diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-07T20·41+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-12T13·05+0000 |
commit | 34df2c8473e681335351f95d5e07d56d24262a81 (patch) | |
tree | 8d1527a00fc28d7ef9c06111793ea3bf4ef6ecfe | |
parent | 3aaefc3000dd80b88d30aefd9e58ceee5a1eddee (diff) |
feat(tvix/eval): add initial barebones compiler r/4406
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 <grfn@gws.fyi>
-rw-r--r-- | tvix/eval/src/compiler.rs | 65 | ||||
-rw-r--r-- | tvix/eval/src/main.rs | 1 |
2 files changed, 66 insertions, 0 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs new file mode 100644 index 000000000000..4a23db3dcb2b --- /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<Chunk> { + 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 c55f48a5432e..bdb5818a3c2a 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; |