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 eval;
|
||||||
mod opcode;
|
mod opcode;
|
||||||
mod value;
|
mod value;
|
||||||
|
mod vm;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut args = env::args();
|
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