feat: 闭包变量捕获 — 环境结构体 + 堆分配

lambda 可捕获外层变量, 自动构建环境结构体:

let base = 100;
let f = fn(x: i64) -> i64 { return x + base; };  // 捕获 base
f(50);  // → 150

全流水线实现:
- Sema: collect_free_vars 遍历 AST 收集自由变量
- AST function: captured/cap_types/cap_count 字段存储捕获信息
- Codegen: 闭包类型改为 struct {fn_ptr: i64, env_ptr: ptr}
- Codegen: lambda 表达式 malloc 环境结构体 + 存储捕获值
- Codegen: 生成函数签名添加 env_ptr 首个参数 (capturing only)
- Codegen: 函数体内通过 GEP 注册捕获变量到 var_table
- Codegen: 闭包调用自动提取 fn_ptr/env_ptr, 条件传递 env

非捕获 lambda 兼容: env_ptr=NULL, 不额外传参
嵌套 lambda 正确处理: 内层不穿透捕获外层变量

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 15:24:35 +08:00
parent 06d80f441a
commit f5c0650a97
7 changed files with 285 additions and 46 deletions
+18 -18
View File
@@ -1,26 +1,26 @@
// 闭包测试 — lambda 表达式 + 调用
fn apply_op(x: i64, op: i64) -> i64 {
// 闭包作为参数暂不支持直接调用,返回 x * 2
return x * 2;
// 闭包测试 — 非捕获 lambda + 变量捕获
fn make_adder(base: i64) -> i64 {
let adder = fn(x: i64) -> i64 { return x + base; };
return adder(50);
}
fn main() -> void {
// 测试1: 基本 lambda
// 测试1: 非捕获 lambda
let double = fn(x: i64) -> i64 { return x * 2; };
let r1 = double(21);
print_i64(r1); // 42
print_i64(double(21)); // 42
// 测试2: lambda with multiple params
let add = fn(a: i64, b: i64) -> i64 { return a + b; };
let r2 = add(30, 12);
print_i64(r2); // 42
// 测试2: 捕获单个变量
let base = 100;
let add = fn(x: i64) -> i64 { return x + base; };
print_i64(add(50)); // 150
// 测试3: nested lambda call
let r3 = double(add(10, 11));
print_i64(r3); // 42
// 测试3: 捕获多个变量
let a = 10;
let b = 20;
let sum3 = fn(x: i64) -> i64 { return x + a + b; };
print_i64(sum3(5)); // 35
// 测试4: lambda in sequence
let triple = fn(x: i64) -> i64 { return x * 3; };
let r4 = triple(14);
print_i64(r4); // 42
// 测试4: 函数内创建闭包
let r = make_adder(200);
print_i64(r); // 250
}