From 34df2c8473e681335351f95d5e07d56d24262a81 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sun, 7 Aug 2022 23:41:42 +0300 Subject: feat(tvix/eval): add initial barebones compiler This compiler can only take care of very trivial literals so far. Change-Id: I9dfac75a801b7235f868061a979ae24159fe1425 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6070 Tested-by: BuildkiteCI Reviewed-by: grfn --- tvix/eval/src/compiler.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++++ tvix/eval/src/main.rs | 1 + 2 files changed, 66 insertions(+) create mode 100644 tvix/eval/src/compiler.rs diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs new file mode 100644 index 0000000000..4a23db3dcb --- /dev/null +++ b/tvix/eval/src/compiler.rs @@ -0,0 +1,65 @@ +//! This module implements a compiler for compiling the rnix AST +//! representation to Tvix bytecode. + +use crate::chunk::Chunk; +use crate::errors::EvalResult; +use crate::opcode::OpCode; +use crate::value::Value; +use rnix; + +struct Compiler { + chunk: Chunk, +} + +impl Compiler { + 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")), + + // Literals contain a single token comprising of the + // literal itself. + rnix::SyntaxKind::NODE_LITERAL => { + let token = node.first_token().expect("TODO"); + self.compile_literal(token) + } + + kind => { + println!("visiting unsupported node: {:?}", kind); + Ok(()) + } + } + } + + fn compile_literal(&mut self, token: rnix::SyntaxToken) -> EvalResult<()> { + let value = rnix::value::Value::from_token(token.kind(), token.text()).expect("TODO"); + + match value { + rnix::NixValue::Float(f) => { + let idx = self.chunk.add_constant(Value::Float(f)); + self.chunk.add_op(OpCode::OpConstant(idx)); + Ok(()) + } + + rnix::NixValue::Integer(i) => { + let idx = self.chunk.add_constant(Value::Integer(i)); + self.chunk.add_op(OpCode::OpConstant(idx)); + Ok(()) + } + + rnix::NixValue::String(_) => todo!(), + rnix::NixValue::Path(_, _) => todo!(), + } + } +} + +pub fn compile(ast: rnix::AST) -> EvalResult { + let mut c = Compiler { + chunk: Chunk::default(), + }; + + c.compile(&ast.node())?; + + Ok(c.chunk) +} diff --git a/tvix/eval/src/main.rs b/tvix/eval/src/main.rs index c55f48a543..bdb5818a3c 100644 --- a/tvix/eval/src/main.rs +++ b/tvix/eval/src/main.rs @@ -5,6 +5,7 @@ use std::{ }; mod chunk; +mod compiler; mod errors; mod eval; mod opcode; -- cgit 1.4.1