diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-27T14·06+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-04T17·40+0000 |
commit | 00aeb6dfaf97c515b155387fc7de27429cf86f74 (patch) | |
tree | 790b098be59f3b1694a6209ede916f6bd7dd66e2 /tvix/eval/src | |
parent | 33cde1422e473770ab0ca30759ece618cb4c3680 (diff) |
refactor(tvix/eval): introduce Depth enum to track variable status r/4636
This does not yet change anything semantically, but will be useful for resolving simple cases of self-recursion etc. Change-Id: I139ecb7e4a8a81193774392a96e73e0ea6b9f85d Reviewed-on: https://cl.tvl.fyi/c/depot/+/6300 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix/eval/src')
-rw-r--r-- | tvix/eval/src/compiler/mod.rs | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index f8b9ccc460ef..38eaddddc16b 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -36,6 +36,26 @@ pub struct CompilationOutput { pub errors: Vec<Error>, } +/// Represents the initialisation status of a variable, tracking +/// whether it is only known or also already defined. +enum Depth { + /// Variable is defined and located at the given depth. + At(usize), + + /// Variable is known but not yet defined. + Unitialised, +} + +impl Depth { + /// Does this variable live above the other given depth? + fn above(&self, theirs: usize) -> bool { + match self { + Depth::Unitialised => false, + Depth::At(ours) => *ours > theirs, + } + } +} + /// Represents a single local already known to the compiler. struct Local { // Definition name, which can be different kinds of tokens (plain @@ -47,7 +67,7 @@ struct Local { node: Option<rnix::SyntaxNode>, // Scope depth of this local. - depth: usize, + depth: Depth, // Phantom locals are not actually accessible by users (e.g. // intermediate values used for `with`). @@ -948,7 +968,9 @@ impl Compiler { // TL;DR - iterate from the back while things belonging to the // ended scope still exist. while !self.scope().locals.is_empty() - && self.scope().locals[self.scope().locals.len() - 1].depth > self.scope().scope_depth + && self.scope().locals[self.scope().locals.len() - 1] + .depth + .above(self.scope().scope_depth) { pops += 1; @@ -992,8 +1014,8 @@ impl Compiler { } self.scope_mut().locals.push(Local { - depth, name, + depth: Depth::At(depth), node: Some(node), phantom: false, used: false, @@ -1003,7 +1025,7 @@ impl Compiler { fn declare_phantom(&mut self) { let depth = self.scope().scope_depth; self.scope_mut().locals.push(Local { - depth, + depth: Depth::At(depth), name: "".into(), node: None, phantom: true, |