refactor(tvix/eval): introduce Depth enum to track variable status

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>
This commit is contained in:
Vincent Ambo 2022-08-27 17:06:49 +03:00 committed by tazjin
parent 33cde1422e
commit 00aeb6dfaf

View file

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