diff options
Diffstat (limited to 'tvix/eval/src/compiler.rs')
-rw-r--r-- | tvix/eval/src/compiler.rs | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index 4a23db3dcb2b..65b97cd56ccc 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -6,17 +6,18 @@ use crate::errors::EvalResult; use crate::opcode::OpCode; use crate::value::Value; use rnix; +use rnix::types::TypedNode; struct Compiler { chunk: Chunk, } impl Compiler { - fn compile(&mut self, node: &rnix::SyntaxNode) -> EvalResult<()> { + fn compile(&mut self, node: rnix::SyntaxNode) -> EvalResult<()> { match node.kind() { // Root of a file contains no content, it's just a marker // type. - rnix::SyntaxKind::NODE_ROOT => self.compile(&node.first_child().expect("TODO")), + rnix::SyntaxKind::NODE_ROOT => self.compile(node.first_child().expect("TODO")), // Literals contain a single token comprising of the // literal itself. @@ -25,6 +26,11 @@ impl Compiler { self.compile_literal(token) } + rnix::SyntaxKind::NODE_BIN_OP => { + let op = rnix::types::BinOp::cast(node).expect("TODO (should not be possible)"); + self.compile_binop(op) + } + kind => { println!("visiting unsupported node: {:?}", kind); Ok(()) @@ -52,6 +58,25 @@ impl Compiler { rnix::NixValue::Path(_, _) => todo!(), } } + + fn compile_binop(&mut self, op: rnix::types::BinOp) -> EvalResult<()> { + self.compile(op.lhs().unwrap())?; + self.compile(op.rhs().unwrap())?; + + use rnix::types::BinOpKind; + + let opcode = match op.operator().unwrap() { + BinOpKind::Add => OpCode::OpAdd, + BinOpKind::Sub => OpCode::OpSub, + BinOpKind::Mul => OpCode::OpMul, + BinOpKind::Div => OpCode::OpDiv, + + _ => todo!(), + }; + + self.chunk.add_op(opcode); + Ok(()) + } } pub fn compile(ast: rnix::AST) -> EvalResult<Chunk> { @@ -59,7 +84,7 @@ pub fn compile(ast: rnix::AST) -> EvalResult<Chunk> { chunk: Chunk::default(), }; - c.compile(&ast.node())?; + c.compile(ast.node())?; Ok(c.chunk) } |