From 900a92935d458fff6c4117ba29558ac8aeb529f9 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sun, 28 Aug 2022 15:41:57 +0300 Subject: refactor(tvix/eval): declare all locals before compiling them 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 --- tvix/eval/src/compiler/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'tvix') 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); } -- cgit 1.4.1