diff options
author | Vincent Ambo <mail@tazj.in> | 2021-01-17T20·03+0300 |
---|---|---|
committer | tazjin <mail@tazj.in> | 2021-01-17T21·17+0000 |
commit | 7fb93fb49008491184a7d55ccd43db846452dce0 (patch) | |
tree | e07383f72d95ee2cfc150811a99af7caef87bb55 /users/tazjin/rlox/src/bytecode/vm.rs | |
parent | b1d0e22b1f5fe907ba3d48931e5a38b9a75b0dcf (diff) |
feat(tazjin/rlox): Bootstrap VM for Lox bytecode r/2127
Change-Id: I479e20bf2087e5c4aa20e31b364c57ed0d961bcf Reviewed-on: https://cl.tvl.fyi/c/depot/+/2416 Tested-by: BuildkiteCI Reviewed-by: tazjin <mail@tazj.in>
Diffstat (limited to 'users/tazjin/rlox/src/bytecode/vm.rs')
-rw-r--r-- | users/tazjin/rlox/src/bytecode/vm.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/users/tazjin/rlox/src/bytecode/vm.rs b/users/tazjin/rlox/src/bytecode/vm.rs new file mode 100644 index 000000000000..1b9c4a235940 --- /dev/null +++ b/users/tazjin/rlox/src/bytecode/vm.rs @@ -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() +} |