about summary refs log tree commit diff
path: root/tvix/eval/src/compiler.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-13T17·17+0300
committertazjin <tazjin@tvl.su>2022-08-28T17·50+0000
commit342b233a0a626aaad4ea32b1e5bf4f873afe7206 (patch)
treec316b9a25c683156b9107bca4fc7a2454998562c /tvix/eval/src/compiler.rs
parent2d401a32e5cef36b44fd35b12c58489cd2595f72 (diff)
feat(tvix/eval): add local identifier access r/4524
This makes basic `let ... in ...` statements work correctly. It does
not yet account for the call frames pushed into the VM during function
application.

Change-Id: I67155171daf1a43011b96716dd9d1ab04b27db33
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6190
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
Diffstat (limited to 'tvix/eval/src/compiler.rs')
-rw-r--r--tvix/eval/src/compiler.rs21
1 files changed, 20 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index c0e895b7be5b..ac630360d403 100644
--- a/tvix/eval/src/compiler.rs
+++ b/tvix/eval/src/compiler.rs
@@ -331,7 +331,14 @@ impl Compiler {
             "false" => self.chunk.push_op(OpCode::OpFalse),
             "null" => self.chunk.push_op(OpCode::OpNull),
 
-            _ => todo!("identifier access"),
+            name => {
+                // Note: `with` and some other special scoping
+                // 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)),
+                }
+            }
         };
 
         Ok(())
@@ -727,6 +734,18 @@ impl Compiler {
             self.chunk.push_op(OpCode::OpCloseScope(pops));
         }
     }
+
+    fn resolve_local(&mut self, name: &str) -> Option<usize> {
+        let scope = &self.locals;
+
+        for (idx, local) in scope.locals.iter().enumerate().rev() {
+            if local.name == name {
+                return Some(idx);
+            }
+        }
+
+        None
+    }
 }
 
 /// Convert a single identifier path fragment to a string if possible,