diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-07T20·42+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-12T13·05+0000 |
commit | d59968649e843371db7d83ac1e2b327c08e70093 (patch) | |
tree | d49f4547db6e1ffd349fb8bbcace6f1d5f7ddf45 /tvix | |
parent | 34df2c8473e681335351f95d5e07d56d24262a81 (diff) |
feat(tvix/eval): add initial stack-based VM r/4407
This can't do anything other than compute a single literal, for now Change-Id: Ia28f9da51c906b590a198e77a4ca5d45a871106b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6071 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
Diffstat (limited to 'tvix')
-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() +} |