feat: 闭包/lambda — 匿名函数表达式
fn(x: T) -> R { body } 作为表达式, 可赋值给变量并间接调用。
全流水线实现:
- Parser: TOK_FN 前缀 → AST_LAMBDA 节点
- Sema: 自动生成 __lambda_N 顶层函数 + 符号注册
- Sema: analyze_call_expr 支持 TYPE_CLOSURE 变量调用
- Codegen: lambda 表达式返回函数指针(i64), 调用点载入+IntToPtr+间接call
- VarEntry.closure_fn 追踪闭包变量对应的生成函数
限制(MVP v0.1): 非捕获 lambda, 返回类型固定 i64
+6 sema 测试 + 1 集成测试, 209 测试全部通过
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -452,6 +452,38 @@ void test_in_param_assign_error() {
|
||||
arena_destroy(&a);
|
||||
}
|
||||
|
||||
void test_lambda_ok() {
|
||||
Arena a = arena_create(1);
|
||||
size_t tc; ErrorInfo lex_err = {0};
|
||||
Token* toks = lex(&a,
|
||||
"fn main() -> void { let f = fn(x: i64) -> i64 { return x * 2; }; return; }",
|
||||
"test", &tc, &lex_err);
|
||||
ASSERT(toks != NULL);
|
||||
ErrorInfo parse_err = {0};
|
||||
AstNode* ast = parse(&a, toks, tc, "test", &parse_err);
|
||||
ASSERT(ast != NULL);
|
||||
ErrorList errors; error_init(&errors, &a);
|
||||
sema_analyze(ast, &errors, &a);
|
||||
ASSERT(errors.count == 0); // lambda 定义应通过
|
||||
arena_destroy(&a);
|
||||
}
|
||||
|
||||
void test_lambda_call_ok() {
|
||||
Arena a = arena_create(1);
|
||||
size_t tc; ErrorInfo lex_err = {0};
|
||||
Token* toks = lex(&a,
|
||||
"fn main() -> void { let f = fn(x: i64) -> i64 { return x + 1; }; let r = f(41); return; }",
|
||||
"test", &tc, &lex_err);
|
||||
ASSERT(toks != NULL);
|
||||
ErrorInfo parse_err = {0};
|
||||
AstNode* ast = parse(&a, toks, tc, "test", &parse_err);
|
||||
ASSERT(ast != NULL);
|
||||
ErrorList errors; error_init(&errors, &a);
|
||||
sema_analyze(ast, &errors, &a);
|
||||
ASSERT(errors.count == 0); // 闭包调用应通过
|
||||
arena_destroy(&a);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
TEST_RUN(test_type_error);
|
||||
TEST_RUN(test_undefined_var);
|
||||
@@ -479,5 +511,7 @@ int main(void) {
|
||||
TEST_RUN(test_match_wildcard_only_sema_ok);
|
||||
TEST_RUN(test_out_param_assign_ok);
|
||||
TEST_RUN(test_in_param_assign_error);
|
||||
TEST_RUN(test_lambda_ok);
|
||||
TEST_RUN(test_lambda_call_ok);
|
||||
return test_summary();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user