refactor(tvix/eval): move resolve_local to Scope struct
This is a more sensible place for this function to live and makes upvalue resolution easier down the line. Change-Id: I48ee39bdcdb4f96a16a327f7015aff60db5b15fb Reviewed-on: https://cl.tvl.fyi/c/depot/+/6270 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
This commit is contained in:
parent
6ce2c666c3
commit
265393301e
1 changed files with 18 additions and 15 deletions
|
@ -114,6 +114,18 @@ impl Scope {
|
||||||
self.poisoned_tokens
|
self.poisoned_tokens
|
||||||
.retain(|_, poisoned_at| *poisoned_at != depth);
|
.retain(|_, poisoned_at| *poisoned_at != depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve the stack index of a statically known local.
|
||||||
|
fn resolve_local(&mut self, name: &str) -> Option<usize> {
|
||||||
|
for (idx, local) in self.locals.iter_mut().enumerate().rev() {
|
||||||
|
if !local.phantom && local.name == name {
|
||||||
|
local.used = true;
|
||||||
|
return Some(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the lambda currently being compiled.
|
/// Represents the lambda currently being compiled.
|
||||||
|
@ -500,7 +512,10 @@ impl Compiler {
|
||||||
count += 1;
|
count += 1;
|
||||||
self.emit_literal_ident(&ident);
|
self.emit_literal_ident(&ident);
|
||||||
|
|
||||||
match self.resolve_local(ident.ident_token().unwrap().text()) {
|
match self
|
||||||
|
.scope_mut()
|
||||||
|
.resolve_local(ident.ident_token().unwrap().text())
|
||||||
|
{
|
||||||
Some(idx) => self.chunk().push_op(OpCode::OpGetLocal(idx)),
|
Some(idx) => self.chunk().push_op(OpCode::OpGetLocal(idx)),
|
||||||
None => {
|
None => {
|
||||||
self.emit_error(
|
self.emit_error(
|
||||||
|
@ -674,6 +689,7 @@ impl Compiler {
|
||||||
// has precedence over dynamic bindings, and
|
// has precedence over dynamic bindings, and
|
||||||
// the inherit is useless.
|
// the inherit is useless.
|
||||||
if self
|
if self
|
||||||
|
.scope_mut()
|
||||||
.resolve_local(ident.ident_token().unwrap().text())
|
.resolve_local(ident.ident_token().unwrap().text())
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
|
@ -751,7 +767,7 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.resolve_local(ident.text()) {
|
match self.scope_mut().resolve_local(ident.text()) {
|
||||||
Some(idx) => self.chunk().push_op(OpCode::OpGetLocal(idx)),
|
Some(idx) => self.chunk().push_op(OpCode::OpGetLocal(idx)),
|
||||||
None => {
|
None => {
|
||||||
if self.scope().with_stack.is_empty() {
|
if self.scope().with_stack.is_empty() {
|
||||||
|
@ -952,19 +968,6 @@ impl Compiler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_local(&mut self, name: &str) -> Option<usize> {
|
|
||||||
let scope = self.scope_mut();
|
|
||||||
|
|
||||||
for (idx, local) in scope.locals.iter_mut().enumerate().rev() {
|
|
||||||
if !local.phantom && local.name == name {
|
|
||||||
local.used = true;
|
|
||||||
return Some(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn emit_warning(&mut self, node: rnix::SyntaxNode, kind: WarningKind) {
|
fn emit_warning(&mut self, node: rnix::SyntaxNode, kind: WarningKind) {
|
||||||
self.warnings.push(EvalWarning { node, kind })
|
self.warnings.push(EvalWarning { node, kind })
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue