diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-23T23·54+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-02T12·31+0000 |
commit | 64746388e2c81c3dac7f520c40a4c4aacb3dc376 (patch) | |
tree | d34d19c84741f5f8e026c03913b2bfa18a68f2fd /tvix | |
parent | 1239a85e237f0ce24cd53effbdbc23c455e02364 (diff) |
feat(tvix/eval): compile function applications r/4584
Change-Id: I1b9230601895a1f09ef1a8037201147020b85f36 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6250 Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
Diffstat (limited to 'tvix')
-rw-r--r-- | tvix/eval/src/compiler.rs | 12 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.exp | 1 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.nix | 2 |
3 files changed, 14 insertions, 1 deletions
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 |