feat(tazjin/rlox): Bootstrap VM for Lox bytecode

Change-Id: I479e20bf2087e5c4aa20e31b364c57ed0d961bcf
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2416
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
This commit is contained in:
Vincent Ambo 2021-01-17 23:03:41 +03:00 committed by tazjin
parent b1d0e22b1f
commit 7fb93fb490
7 changed files with 89 additions and 25 deletions

View file

@ -0,0 +1,59 @@
use super::chunk;
use super::errors::*;
use super::opcode::OpCode;
use super::value::Value;
pub struct VM {
chunk: chunk::Chunk,
// TODO(tazjin): Accessing array elements constantly is not ideal,
// lets see if something clever can be done with iterators.
ip: usize,
stack: Vec<Value>,
}
impl VM {
fn push(&mut self, value: Value) {
self.stack.push(value)
}
fn pop(&mut self) -> Value {
self.stack.pop().expect("fatal error: stack empty!")
}
}
impl VM {
fn run(&mut self) -> LoxResult<()> {
loop {
let op = &self.chunk.code[self.ip];
#[cfg(feature = "disassemble")]
chunk::disassemble_instruction(&self.chunk, self.ip);
self.ip += 1;
match op {
OpCode::OpReturn => {
println!("{:?}", self.pop());
return Ok(());
}
OpCode::OpConstant(idx) => {
let c = *self.chunk.constant(*idx);
self.push(c);
}
}
}
}
}
pub fn interpret(chunk: chunk::Chunk) -> LoxResult<()> {
let mut vm = VM {
chunk,
ip: 0,
stack: vec![],
};
vm.run()
}