feat: 搭建闭包捕获基础设施

This commit is contained in:
2026-06-30 19:58:58 +08:00
parent 930b14b3f0
commit c58aae4862
17 changed files with 660 additions and 12 deletions
@@ -32,13 +32,21 @@ impl Compiler {
self.count_expression(&assign.right, ctx);
ctx.count_load_const(); // private id
ctx.count_instr(); // SET_PRIVATE
} else if let oxide_parser::AssignmentTarget::AssignmentTargetIdentifier(_) = &assign.left {
} else if let oxide_parser::AssignmentTarget::AssignmentTargetIdentifier(ati) = &assign.left {
let name = ati.name.as_str();
// Check if target is an upvalue or captured cell
let is_upvalue = ctx.current_upvalue_captures.iter().any(|u| u.name == name);
let is_captured = ctx.scopes.symbols.lookup_is_captured(name);
if let Some(logical_op) = assign.operator.to_logical_operator() {
self.count_identifier_logical_assignment(logical_op, &assign.right, ctx);
} else {
self.count_expression(&assign.right, ctx);
if assign.operator != AssignmentOperator::Assign {
ctx.projected_pc += 1; // COMPOUND_* on var
} else if is_upvalue {
ctx.count_instr(); // STORE_UPVALUE
} else if is_captured {
ctx.count_instr(); // CELL_SET
} else {
ctx.alloc_reg();
ctx.projected_pc += 1; // STORE_VAR
@@ -21,8 +21,26 @@ impl Compiler {
let Expression::Identifier(ident) = expr else {
return;
};
if CompileCtx::is_known_builtin(ident.name.as_str()) {
let _ = ctx.lookup_or_builtin(ident.name.as_str());
let name = ident.name.as_str();
// Check if this is an upvalue reference (nested closure)
for up in &ctx.current_upvalue_captures {
if up.name == name {
ctx.alloc_reg();
ctx.count_instr(); // LOAD_UPVALUE
return;
}
}
// Check if the owner's binding is captured (cell access)
if ctx.scopes.symbols.lookup_is_captured(name) {
ctx.alloc_reg();
ctx.count_instr(); // CELL_GET
return;
}
if CompileCtx::is_known_builtin(name) {
let _ = ctx.lookup_or_builtin(name);
}
ctx.alloc_reg();
ctx.projected_pc += 1; // LOAD_VAR