feat(tvix/eval): add local identifier access

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>
This commit is contained in:
Vincent Ambo 2022-08-13 20:17:25 +03:00 committed by tazjin
parent 2d401a32e5
commit 342b233a0a
4 changed files with 31 additions and 1 deletions

View file

@ -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,