about summary refs log tree commit diff
path: root/tvix
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-23T23·54+0300
committertazjin <tazjin@tvl.su>2022-09-02T12·31+0000
commit64746388e2c81c3dac7f520c40a4c4aacb3dc376 (patch)
treed34d19c84741f5f8e026c03913b2bfa18a68f2fd /tvix
parent1239a85e237f0ce24cd53effbdbc23c455e02364 (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.rs12
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.exp1
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-lambda-identity.nix2
3 files changed, 14 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index bb751e4f92..4043f268bf 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 0000000000..d81cc0710e
--- /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 0000000000..f2ee49df80
--- /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