about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-14T22·31+0300
committertazjin <tazjin@tvl.su>2022-08-31T22·26+0000
commit89f566ef5782c967e14eee5727dce2740a3c24b4 (patch)
tree6465d25279174dbb2cd8b061ed74eee6a4e8f01e
parent59f50dc81a6afe8d2cd77d96ffb1d92f40c971cc (diff)
feat(tvix/eval): emit instructions for dynamic var resolution r/4557
If an unknown variable is encountered and the with stack is not empty,
emit instructions for resolving the variable at runtime.

Change-Id: I752f4bd0025335744e4747364abd1bd34130374e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6223
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Reviewed-by: grfn <grfn@gws.fyi>
-rw-r--r--tvix/eval/src/compiler.rs12
1 files changed, 11 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index cb568bfc6f..970ad7a1b7 100644
--- a/tvix/eval/src/compiler.rs
+++ b/tvix/eval/src/compiler.rs
@@ -352,7 +352,17 @@ impl Compiler {
                 // features are not yet implemented.
                 match self.resolve_local(name) {
                     Some(idx) => self.chunk.push_op(OpCode::OpGetLocal(idx)),
-                    None => return Err(Error::UnknownStaticVariable(node)),
+                    None => {
+                        if self.scope.with_stack.is_empty() {
+                            return Err(Error::UnknownStaticVariable(node));
+                        }
+
+                        // Variable needs to be dynamically resolved
+                        // at runtime.
+                        let idx = self.chunk.push_constant(Value::String(name.into()));
+                        self.chunk.push_op(OpCode::OpConstant(idx));
+                        self.chunk.push_op(OpCode::OpResolveWith)
+                    }
                 }
             }
         };