diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-13T17·17+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-28T17·50+0000 |
commit | 342b233a0a626aaad4ea32b1e5bf4f873afe7206 (patch) | |
tree | c316b9a25c683156b9107bca4fc7a2454998562c /tvix/eval/src/compiler.rs | |
parent | 2d401a32e5cef36b44fd35b12c58489cd2595f72 (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.rs | 21 |
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, |