fix one-up closure resolution

This commit is contained in:
Scott Richmond 2025-06-21 18:33:14 -04:00
parent ce11f1cd0f
commit 583262f9e8
3 changed files with 19 additions and 11 deletions

View File

@ -541,13 +541,19 @@ impl<'a> Compiler<'a> {
fn get_upvalue(&self, name: &'static str) -> Upvalue {
let local = self.bindings.iter().find(|b| b.name == name);
match local {
Some(binding) => Upvalue {
name,
stack_pos: binding.stack_pos,
},
Some(binding) => {
let upvalue = Upvalue {
name,
stack_pos: binding.stack_pos,
};
println!("found upvalue {name} in {}", self.name);
upvalue
}
None => {
println!("Getting upvalue {name}");
self.enclosing.unwrap().get_upvalue(name)
let upvalue = self.enclosing.unwrap().get_upvalue(name);
println!("upvalue: {:?}", upvalue);
upvalue
}
}
}
@ -1309,7 +1315,7 @@ impl<'a> Compiler<'a> {
None => {
let mut compiler = Compiler::new(
clause,
self.name,
name,
self.src,
Some(self),
self.chunk.env.clone(),

View File

@ -99,7 +99,8 @@ pub fn run(src: &'static str) {
// in any event, the AST should live forever
let parsed: &'static Spanned<Ast> = Box::leak(Box::new(parse_result.unwrap()));
let prelude = prelude();
// let prelude = prelude();
let prelude = imbl::HashMap::new();
let mut validator = Validator::new(&parsed.0, &parsed.1, "user input", src, prelude.clone());
validator.validate();
@ -145,10 +146,10 @@ pub fn main() {
env::set_var("RUST_BACKTRACE", "1");
let src = r#"
let foo = {
let bar = :bar
let baz = :baz
fn quux () -> {
fn frobulate () -> (bar, baz)
let bar = :bar
let baz = :baz
fn frobulate () -> (bar, baz, baz)
}
}

View File

@ -1097,7 +1097,8 @@ impl Vm {
SetUpvalue => {
let idx = self.chunk().bytecode[self.ip + 1];
self.ip += 2;
let closed_over = self.stack[idx as usize].clone();
let closed_idx = idx as usize + self.frame.stack_base;
let closed_over = self.stack[closed_idx].clone();
if let Value::Fn(lfn) = self.peek() {
lfn.close(closed_over);
}