Files
Serendipity 06d80f441a 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>
2026-06-07 15:07:03 +08:00

67 lines
1.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef L_LANG_H
#define L_LANG_H
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
// === 类型系统 ===
typedef enum {
TYPE_I32,
TYPE_I64,
TYPE_U64,
TYPE_F64,
TYPE_BOOL,
TYPE_CHAR,
TYPE_STR,
TYPE_VOID,
TYPE_STRUCT, // 结构体类型
TYPE_ENUM, // 枚举类型
TYPE_ARRAY, // 固定大小数组类型
TYPE_CLOSURE, // 闭包类型 (函数指针 + 环境指针)
TYPE_GENERIC, // 泛型类型参数(单态化前)
TYPE_UNKNOWN, // 尚未推断
TYPE_ERROR, // 类型错误
} TypeKind;
static inline const char* type_name(TypeKind kind) {
switch (kind) {
case TYPE_I32: return "i32";
case TYPE_I64: return "i64";
case TYPE_U64: return "u64";
case TYPE_F64: return "f64";
case TYPE_BOOL: return "bool";
case TYPE_CHAR: return "char";
case TYPE_STR: return "str";
case TYPE_VOID: return "void";
case TYPE_STRUCT: return "struct";
case TYPE_ENUM: return "enum";
case TYPE_ARRAY: return "array";
case TYPE_CLOSURE: return "closure";
default: return "<unknown>";
}
}
// === 源码位置(替代分散的 line/col 参数)===
typedef struct {
int line;
int col;
} SourceLoc;
// 手动创建 SourceLoc
static inline SourceLoc loc_at(int line, int col) {
return (SourceLoc){ .line = line, .col = col };
}
// === 向前声明 ===
typedef struct Token Token;
typedef struct AstNode AstNode;
typedef struct Scope Scope;
typedef struct Arena Arena;
// === 跨模块分配器接口(避免循环依赖,各模块通过 void* 使用 arena===
void* arena_alloc_impl(void* alloc, size_t size);
char* arena_strdup_impl(void* alloc, const char* src, size_t len);
#endif