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
+2 -1
View File
@@ -73,7 +73,8 @@ struct AstNode {
TypeKind return_type; const char* return_struct_type_name;
struct AstNode* body; bool is_pub;
const char** type_params; size_t type_param_count;
TypeKind* multi_ret_types; const char** multi_ret_snames; size_t multi_ret_count; } function;
TypeKind* multi_ret_types; const char** multi_ret_snames; size_t multi_ret_count;
const char** captured; TypeKind* cap_types; size_t cap_count; } function;
// AST_PARAMETER (也用作结构体字段: name + type)
struct { const char* name; TypeKind type; const char* struct_type_name; bool is_out; } parameter;
// AST_BLOCK