diff options
Diffstat (limited to 'tvix/eval')
-rw-r--r-- | tvix/eval/src/main.rs | 1 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 55 |
2 files changed, 56 insertions, 0 deletions
diff --git a/tvix/eval/src/main.rs b/tvix/eval/src/main.rs index bdb5818a3c2a..55365efabd1b 100644 --- a/tvix/eval/src/main.rs +++ b/tvix/eval/src/main.rs @@ -10,6 +10,7 @@ mod errors; mod eval; mod opcode; mod value; +mod vm; fn main() { let mut args = env::args(); diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs new file mode 100644 index 000000000000..e35cd99b1e3d --- /dev/null +++ b/tvix/eval/src/vm.rs @@ -0,0 +1,55 @@ +//! This module implements the virtual (or abstract) machine that runs +//! Tvix bytecode. + +use crate::{chunk::Chunk, errors::EvalResult, opcode::OpCode, value::Value}; + +pub struct VM { + ip: usize, + chunk: Chunk, + stack: Vec<Value>, +} + +impl VM { + fn push(&mut self, value: Value) { + self.stack.push(value) + } + + fn pop(&mut self) -> Value { + self.stack.pop().expect("TODO") + } + + fn inc_ip(&mut self) -> OpCode { + let op = self.chunk.code[self.ip]; + self.ip += 1; + op + } + + fn run(&mut self) -> EvalResult<Value> { + loop { + match self.inc_ip() { + OpCode::OpConstant(idx) => { + let c = self.chunk.constant(idx).clone(); + self.push(c); + } + + OpCode::OpNull => todo!(), + OpCode::OpTrue => todo!(), + OpCode::OpFalse => todo!(), + } + + if self.ip == self.chunk.code.len() { + return Ok(self.pop()); + } + } + } +} + +pub fn run_chunk(chunk: Chunk) -> EvalResult<Value> { + let mut vm = VM { + chunk, + ip: 0, + stack: vec![], + }; + + vm.run() +} |