implement WithLookup

This commit is contained in:
2026-04-04 09:51:57 +08:00
parent 88dc8539b5
commit ee54ab8895
+54 -2
View File
@@ -891,8 +891,60 @@ impl Runtime {
root.with_scope = scope.prev;
}),
WithLookup => {
let _name = self.read_string_id();
todo!("implement WithLookup (force with_scope)");
let name = self.read_string_id();
let mut depth = 0;
loop {
let found_scope = self.arena.mutate_root(|_, root| {
let mut cur = root.with_scope;
for _ in 0..depth {
if let Some(s) = cur {
cur = s.prev;
} else {
break;
}
}
if let Some(scope) = cur {
root.push_stack(scope.env);
true
} else {
false
}
});
if !found_scope {
let name_str = self.strings.resolve(name.0).unwrap_or("«unknown»");
return Runtime::handle_vm_error(
self,
vm_err(format!("undefined variable '{name_str}'")),
);
}
if let err @ Action::Done(Err(_)) = self.force_tos() {
return err;
}
let lookup_result = self.arena.mutate_root(|_, root| {
let val = root.pop_stack();
let Some(attrs) = val.as_gc::<AttrSet<'_>>() else {
return Err(vm_err("value in 'with' scope must be a set"));
};
if let Some(v) = attrs.lookup(name) {
root.push_stack(v);
Ok(true) // Found it
} else {
Ok(false) // Not in this scope, try the next one
}
});
match lookup_result {
Ok(true) => break, // Successfully resolved and pushed to stack
Ok(false) => depth += 1, // Move to the parent 'with' scope
Err(e) => return Runtime::handle_vm_error(self, e),
}
}
}
LoadBuiltins => {