diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-28T12·41+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-06T07·45+0000 |
commit | 900a92935d458fff6c4117ba29558ac8aeb529f9 (patch) | |
tree | bee489898d2abd4f117228e0990ec38775bab1b3 /tvix | |
parent | 47b356286751bff8f41930761a402564d54d1898 (diff) |
refactor(tvix/eval): declare all locals before compiling them r/4662
This actually makes things full-circle, as this tree already had this implementation once before all the other required components were in place. With this commit, the compiler can resolve recursive upvalues within the same scope (though they will not yet work at runtime). Change-Id: I6267e477d08f367257c3a6dde054b880d7b47211 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6326 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix')
-rw-r--r-- | tvix/eval/src/compiler/mod.rs | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index ca1098af64dd..fb08662da84b 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -654,6 +654,9 @@ impl Compiler { self.compile_let_inherit(node.inherits()); + // First pass to ensure that all identifiers are known; + // required for resolving recursion. + let mut entries: Vec<(String, rnix::ast::Expr)> = vec![]; for entry in node.attrpath_values() { let mut path = match normalise_ident_path(entry.attrpath().unwrap().attrs()) { Ok(p) => p, @@ -669,7 +672,15 @@ impl Compiler { let name = path.pop().unwrap(); self.declare_local(entry.attrpath().unwrap().syntax().clone(), &name); - self.compile(entry.value().unwrap()); + entries.push((name, entry.value().unwrap())); + } + + // Second pass to place the values in the correct stack slots. + for (name, value) in entries.into_iter() { + self.compile(value); + + // Any code after this point will observe the value in the + // right stack slot, so mark it as initialised. self.mark_initialised(&name); } |