about summary refs log tree commit diff
path: root/users/tazjin/rlox/src/bytecode/vm.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-01-17T20·03+0300
committertazjin <mail@tazj.in>2021-01-17T21·17+0000
commit7fb93fb49008491184a7d55ccd43db846452dce0 (patch)
treee07383f72d95ee2cfc150811a99af7caef87bb55 /users/tazjin/rlox/src/bytecode/vm.rs
parentb1d0e22b1f5fe907ba3d48931e5a38b9a75b0dcf (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 '')
-rw-r--r--users/tazjin/rlox/src/bytecode/vm.rs59
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 0000000000..1b9c4a2359
--- /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()
+}