diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-23T22·54+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-01T21·56+0000 |
commit | 269788086ec7cfabe70734b9be840efa87bd3f28 (patch) | |
tree | d8739de84b6a2c792d0b0693074f9096df197897 /tvix/eval/src/compiler.rs | |
parent | fc865eb157380fa5d2c779bd0cc207b73a514572 (diff) |
feat(tvix/eval): compile lambda definitions r/4581
Compiles lambda definitions of the simple form (i.e. without formals arguments) and emits them as constants like any other value. This does not yet implement actually invoking these functions in the VM. Change-Id: Ie1e0a13220b68c1728be229b875f0992e685c5ef Reviewed-on: https://cl.tvl.fyi/c/depot/+/6247 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
Diffstat (limited to 'tvix/eval/src/compiler.rs')
-rw-r--r-- | tvix/eval/src/compiler.rs | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index bbf97ccaedf0..bb751e4f92a1 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -160,13 +160,13 @@ impl Compiler { ast::Expr::LetIn(let_in) => self.compile_let_in(let_in), ast::Expr::Ident(ident) => self.compile_ident(ident), ast::Expr::With(with) => self.compile_with(with), + ast::Expr::Lambda(lambda) => self.compile_lambda(lambda), // Parenthesized expressions are simply unwrapped, leaving // their value on the stack. ast::Expr::Paren(paren) => self.compile(paren.expr().unwrap()), ast::Expr::LegacyLet(_) => todo!("legacy let"), - ast::Expr::Lambda(_) => todo!("function definition"), ast::Expr::Apply(_) => todo!("function application"), ast::Expr::Root(_) => unreachable!("there cannot be more than one root"), @@ -735,6 +735,45 @@ impl Compiler { self.compile(node.body().unwrap()); } + fn compile_lambda(&mut self, node: ast::Lambda) { + // Open new lambda context in compiler, which has its own + // scope etc. + self.contexts.push(LambdaCtx::new()); + self.begin_scope(); + + // Compile the function itself + match node.param().unwrap() { + ast::Param::Pattern(_) => todo!("formals function definitions"), + ast::Param::IdentParam(param) => { + let name = param + .ident() + .unwrap() + .ident_token() + .unwrap() + .text() + .to_string(); + + self.declare_local(param.syntax().clone(), name); + } + } + + self.compile(node.body().unwrap()); + self.end_scope(); + + // TODO: determine and insert enclosing name, if available. + + // Pop the lambda context back off, and emit the finished + // lambda as a constant. + let compiled = self.contexts.pop().unwrap(); + + #[cfg(feature = "disassembler")] + { + crate::disassembler::disassemble_chunk(&compiled.lambda.chunk); + } + + self.emit_constant(Value::Lambda(compiled.lambda)); + } + /// Emit the literal string value of an identifier. Required for /// several operations related to attribute sets, where /// identifiers are used as string keys. |