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:
parent
b1d0e22b1f
commit
7fb93fb490
7 changed files with 89 additions and 25 deletions
59
users/tazjin/rlox/src/bytecode/vm.rs
Normal file
59
users/tazjin/rlox/src/bytecode/vm.rs
Normal 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()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue