From 64746388e2c81c3dac7f520c40a4c4aacb3dc376 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 24 Aug 2022 02:54:19 +0300 Subject: feat(tvix/eval): compile function applications Change-Id: I1b9230601895a1f09ef1a8037201147020b85f36 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6250 Reviewed-by: sterni Reviewed-by: grfn Tested-by: BuildkiteCI --- tvix/eval/src/compiler.rs | 12 +++++++++++- tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.exp | 1 + tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.nix | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.exp create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.nix (limited to 'tvix/eval/src') diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index bb751e4f92a1..4043f268bff4 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -161,13 +161,13 @@ impl Compiler { ast::Expr::Ident(ident) => self.compile_ident(ident), ast::Expr::With(with) => self.compile_with(with), ast::Expr::Lambda(lambda) => self.compile_lambda(lambda), + ast::Expr::Apply(apply) => self.compile_apply(apply), // 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::Apply(_) => todo!("function application"), ast::Expr::Root(_) => unreachable!("there cannot be more than one root"), ast::Expr::Error(_) => unreachable!("compile is only called on validated trees"), @@ -774,6 +774,16 @@ impl Compiler { self.emit_constant(Value::Lambda(compiled.lambda)); } + fn compile_apply(&mut self, node: ast::Apply) { + // To call a function, we leave its arguments on the stack, + // followed by the function expression itself, and then emit a + // call instruction. This way, the stack is perfectly laid out + // to enter the function call straight away. + self.compile(node.argument().unwrap()); + self.compile(node.lambda().unwrap()); + self.chunk().push_op(OpCode::OpCall); + } + /// Emit the literal string value of an identifier. Required for /// several operations related to attribute sets, where /// identifiers are used as string keys. diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.exp new file mode 100644 index 000000000000..d81cc0710eb6 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.exp @@ -0,0 +1 @@ +42 diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.nix new file mode 100644 index 000000000000..f2ee49df8092 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.nix @@ -0,0 +1,2 @@ +# Identity function is the simplest possible function. +(x: x) 42 -- cgit 1.4.1