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 { fn get_upvalue(&self, name: &'static str) -> Upvalue {
let local = self.bindings.iter().find(|b| b.name == name); let local = self.bindings.iter().find(|b| b.name == name);
match local { match local {
Some(binding) => Upvalue { Some(binding) => {
name, let upvalue = Upvalue {
stack_pos: binding.stack_pos, name,
}, stack_pos: binding.stack_pos,
};
println!("found upvalue {name} in {}", self.name);
upvalue
}
None => { None => {
println!("Getting upvalue {name}"); 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 => { None => {
let mut compiler = Compiler::new( let mut compiler = Compiler::new(
clause, clause,
self.name, name,
self.src, self.src,
Some(self), Some(self),
self.chunk.env.clone(), self.chunk.env.clone(),

View File

@ -99,7 +99,8 @@ pub fn run(src: &'static str) {
// in any event, the AST should live forever // in any event, the AST should live forever
let parsed: &'static Spanned<Ast> = Box::leak(Box::new(parse_result.unwrap())); 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()); let mut validator = Validator::new(&parsed.0, &parsed.1, "user input", src, prelude.clone());
validator.validate(); validator.validate();
@ -145,10 +146,10 @@ pub fn main() {
env::set_var("RUST_BACKTRACE", "1"); env::set_var("RUST_BACKTRACE", "1");
let src = r#" let src = r#"
let foo = { let foo = {
let bar = :bar
let baz = :baz
fn quux () -> { 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 => { SetUpvalue => {
let idx = self.chunk().bytecode[self.ip + 1]; let idx = self.chunk().bytecode[self.ip + 1];
self.ip += 2; 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() { if let Value::Fn(lfn) = self.peek() {
lfn.close(closed_over); lfn.close(closed_over);
} }