feat(tvix/eval): add initial stack-based VM
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>
This commit is contained in:
parent
34df2c8473
commit
d59968649e
2 changed files with 56 additions and 0 deletions
|
@ -10,6 +10,7 @@ mod errors;
|
|||
mod eval;
|
||||
mod opcode;
|
||||
mod value;
|
||||
mod vm;
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
|
|
55
tvix/eval/src/vm.rs
Normal file
55
tvix/eval/src/vm.rs
Normal file
|
@ -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()
|
||||
}
|
Loading…
Reference in a new issue