L Language 架构分析报告 (v0.3 — 增量分析, 无代码变更)
日期: 2026-06-05 11:50 | 自动生成 | 自上次报告后无代码变更
基线: architecture-analysis-report-2026-06-05-0829.md (HEAD 382cd08)
当前 HEAD: 620cec4 (docs-only commit: CHANGELOG v0.3 + analysis report)
变更摘要
无代码变更。 自上次分析 (2026-06-05 08:29) 以来,唯一的新 commit 620cec4 仅包含文档更新:
| Commit |
内容 |
类型 |
620cec4 |
docs: CHANGELOG 更新 v0.3 — for循环 + 测试补全 |
docs-only |
382cd08 |
test: sema + codegen 测试补全 — 86 单元测试 |
代码基线 (上次分析) |
git diff 382cd08..620cec4 结果: 仅 CHANGELOG.md (+14) 和 architecture-analysis-report-2026-06-05-0703.md (+288) 两个非代码文件变更。所有 .c / .h / CMakeLists.txt / 测试程序全未变动。
1. 当前架构全景
1.1 编译流水线 (无变化)
1.2 模块清单与指标
| 模块 |
文件 |
实现行数 |
头文件行数 |
关键职责 |
| include/ |
l_lang.h |
— |
34 |
TypeKind 枚举 (7种), 向前声明, arena_alloc_impl |
| util/ |
arena.c (39) + .h (13) |
39 |
13 |
8MB bump allocator |
| lexer/ |
lexer.c (137) + token.c (45) |
182 |
50 |
手写状态机, 37 种 Token |
| ast/ |
ast.c (107) + .h (93) |
107 |
93 |
15 种 AST 节点 + 工厂函数 |
| parser/ |
parser.c (390) + .h (10) |
390 |
10 |
Pratt 表达式 + 递归下降 + for/复合赋值去糖 |
| sema/ |
sema.c (294) + symbol.c (46) |
340 |
41 |
类型推断, 作用域链, 可变性检查 |
| codegen/ |
codegen.c (421) + target.c (30) |
451 |
26 |
LLVM IR 生成, 4 运行时内置函数, 目标初始化 |
| driver/ |
main.c (133) + error.c (46) |
179 |
18 |
流水线串联, 命令行参数, 错误报告 |
总计: 11 .c 源文件 (1,688 行) + 10 .h 头文件 (251 行) + 1 公共头 (34 行) = ~1,973 行实现代码 + ~330 行测试代码 = ~2,303 行
1.3 核心数据结构
| 数据结构 |
定义位置 |
关键字段 |
TokenKind (37 枚举值) |
token.h |
关键字/类型/字面量/标识符/运算符/分隔符/EOF/ERROR |
Token |
token.h |
kind, start, length, line, col |
AstKind (15 枚举值) |
ast.h |
PROGRAM → IDENT_EXPR |
AstNode (union 实现) |
ast.h |
kind, type, line, col, as.{12 sub-structs} |
TypeKind (7 枚举值) |
l_lang.h |
I64, F64, BOOL, STR, VOID, UNKNOWN, ERROR |
Scope (作用域链) |
symbol.h |
symbols[], count, parent |
Symbol (符号条目) |
symbol.h |
name, type, kind, return_type, param_types, is_mut |
1.4 AST 节点覆盖矩阵
| AST 节点 |
Lexer |
Parser |
Sema |
Codegen |
| AST_PROGRAM |
— |
✅ |
✅ |
✅ |
| AST_FUNCTION |
— |
✅ |
✅ |
✅ |
| AST_PARAMETER |
— |
✅ |
— |
— |
| AST_BLOCK |
— |
✅ |
✅ |
✅ |
| AST_LET_STMT |
— |
✅ |
✅ |
✅ |
| AST_ASSIGN_STMT |
— |
✅ |
✅ |
✅ |
| AST_IF_STMT |
— |
✅ |
✅ |
✅ |
| AST_WHILE_STMT |
— |
✅ |
✅ |
✅ |
| AST_FOR_STMT |
去糖 (lexer 标记) |
去糖为 while |
— |
— |
| AST_RETURN_STMT |
— |
✅ |
✅ |
✅ |
| AST_EXPR_STMT |
— |
✅ |
✅ |
✅ |
| AST_BINARY_EXPR |
— |
✅ |
✅ |
✅ |
| AST_UNARY_EXPR |
— |
✅ |
✅ |
✅ |
| AST_CALL_EXPR |
— |
✅ |
✅ |
✅ |
| AST_LITERAL_EXPR |
— |
✅ |
✅ |
✅ |
| AST_IDENT_EXPR |
— |
✅ |
✅ |
✅ |
- 完整覆盖率: 15 个 AST 节点在 sema 和 codegen 中全部覆盖 (100%)。AST_PARAMETER 无需独立 sema/codegen 路径 (函数签名处理时展开)。for 循环和复合赋值在 parser 层去糖,无 AST 节点增量。
- 去糖策略: for 循环 (TOK_FOR + TOK_IN + TOK_DOT_DOT) 和复合赋值 (TOK_PLUS_EQ 等) 在 parser 层去糖为 while + let mut + assign,零下游模块变更。
1.5 技术选型评估
| 选择 |
评价 |
状态 |
| C17 + CMake + MinGW (GCC 14.x) |
轻量, 学习友好, 交叉编译受限 |
稳定 |
| Arena bump allocator (8MB) |
零 GC 开销, 无 free, 编译时内存线性 |
稳定 |
| LLVM-C API 19.x |
成熟, 表达式级映射 |
LLVM 22 mem2reg C API 已移除 (有注释) |
| 手写 Lexer/Parser (Pratt) |
0 外部依赖, 37 Token |
稳定 |
| 去糖策略 (for / 复合赋值) |
AST 节点数不膨胀, 零下游侵入 |
验证有效 |
| GCC system() 链接 |
简单但平台绑定 (MinGW) |
待改进 |
| 错误报告 (即时终止 + 批量输出) |
分阶段差异处理 |
稳定 |
2. 功能清单与成熟度
2.1 v0.1 基线功能 (全部完成)
- 基本类型:
i64, f64, bool, void
- 算术:
+ - * / %
- 比较:
== != < > <= >=
- 逻辑:
&& || !
let 不可变变量 + 类型推断
- 控制流:
if/else (含 else if), while, return
- 函数定义与调用, 递归 (含斐波那契)
- 内置函数:
print_i64, print_f64, print_bool
- 注释:
// 行注释, /* */ 块注释
- 错误报告: 词法/语法即时终止, 语义错误批量输出
2.2 v0.2 新增 (全部完成)
2.3 v0.3 新增 (全部完成)
3. 与 Rust 对标: 缺失功能及优先级
P0: 短期 (1-2 天/项)
| # |
功能 |
Rust 启发 |
改动范围 |
状态 |
| 1 |
复合赋值 += -= *= /= |
复合赋值运算符 |
lexer + parser (desugar) |
✅ v0.2 |
| 2 |
str+str 运行时拼接 |
— |
codegen (malloc/strlen/memcpy) |
✅ v0.2 |
| 3 |
for 循环 + range |
for i in 0..10 {} |
lexer + parser (desugar) |
✅ v0.3 |
| 4 |
结构体 struct |
struct 具名域 + GEP |
lexer/parser/sema/codegen (全流水线) |
❌ 待实施 |
P1: 中期 (3-5 天/项)
| # |
功能 |
改动范围 |
学习价值 |
状态 |
| 5 |
数组 + 索引: [i64; N], arr[i] |
lexer/parser/sema/codegen (GEP) |
GEP 指针计算 |
待实施 |
| 6 |
枚举 (C 风格) |
lexer/parser/sema/codegen (i64) |
为代数类型铺路 |
待实施 |
| 7 |
match 表达式 |
lexer/parser/sema (穷举) + codegen |
模式匹配核心 |
待实施 |
| 8 |
类型别名 type Meters = i64 |
lexer/parser/sema (展开) |
名称等价 vs 结构等价 |
待实施 |
P2: 中后期 (1-2 周/项)
| # |
功能 |
学习价值 |
状态 |
| 9 |
模块系统 mod + use |
单文件→多文件 |
待实施 |
| 10 |
自定义 IR 层 (三地址码/SSA) |
编译器的核心抽象 |
待实施 |
| 11 |
泛型 (单态化) |
Rust 零成本抽象基石 |
待实施 |
| 12 |
解释器模式 (walk AST) |
快速验证语义 |
待实施 |
P3: 长期 (2-4 周/项)
| # |
功能 |
备注 |
状态 |
| 13 |
trait / 接口 |
需泛型 + 虚表 |
待实施 |
| 14 |
Option / Result |
需泛型 + enum |
待实施 |
| 15 |
所有权 / 借用检查 |
极度复杂 |
待实施 |
| 16 |
自举 (L 编译 L) |
终极考验 |
待实施 |
Rust 设计哲学吸收进度
| Rust 特性 |
状态 |
备注 |
| 默认不可变 (let vs let mut) |
✅ |
编译期检查 |
| 复合赋值 |
✅ |
desugar 模式 |
| for + range |
✅ |
desugar 为 while |
| 表达式 vs 语句 |
❌ |
if/match/block 作为表达式 |
| 模式匹配 (match) |
❌ |
P1 |
| 代数数据类型 (enum) |
❌ |
需泛型 |
| 结构体 (struct) |
❌ |
P0 #4 |
| 所有权 / 借用 |
❌ |
P3 远期 |
4. 测试覆盖分析
4.1 单元测试 (19 函数, 59 断言)
| 测试文件 |
函数数 |
覆盖范围 |
| test_lexer.c |
3 |
token 识别, 关键字, 操作符, 注释 |
| test_parser.c |
5 |
算术, let, if, while, 函数 |
| test_sema.c |
7 |
类型错误, 未定义变量, let mut, immutable assign, str, str concat |
| test_codegen.c |
4 |
简单函数, if/else, 二元运算, while |
4.2 集成测试 (11 程序)
| # |
文件 |
测试功能 |
状态 |
| 1 |
01_arithmetic.l |
算术运算 |
✅ |
| 2 |
02_if_else.l |
if/else 控制流 |
✅ |
| 3 |
03_recurse.l |
递归函数 |
✅ |
| 4 |
04_fib_recursive.l |
斐波那契 |
✅ |
| 5 |
05_float.l |
浮点数 |
✅ |
| 6 |
06_mut_while.l |
let mut + while |
✅ |
| 7 |
07_hello_str.l |
字符串输出 |
✅ |
| 8 |
08_str_concat.l |
字符串拼接 |
✅ |
| 9 |
09_compound_assign.l |
复合赋值 |
✅ |
| 10 |
10_for_range.l |
for range 循环 |
✅ |
| 11 |
11_for_step2.l |
for range (变量边界) |
✅ |
4.3 测试缺口
| # |
缺口 |
严重度 |
说明 |
| 1 |
codegen 缺 call/str/compound/for 路径 |
中 |
4 测试函数仅覆盖基础路径 |
| 2 |
parser 缺 for 错误恢复测试 |
低 |
无 for/in/.. 错误提示验证 |
| 3 |
复合赋值无独立 desugar 测试 |
低 |
仅集成测试间接覆盖 |
| 4 |
for 循环无独立 desugar 测试 |
低 |
同上 |
5. 技术债务
| # |
问题 |
严重度 |
说明 |
趋势 |
| 1 |
str concat malloc 内存泄漏 |
中 |
x + y 每次 malloc, 无 free; 编译后程序泄漏, 不影响编译器 |
存留 |
| 2 |
codegen 测试覆盖率低 (4/15 AST 路径) |
中 |
call/str/compound/for 路径无单元测试 |
存留 |
| 3 |
system("gcc ...") 平台绑定 |
低 |
Windows/MinGW 正常工作, 其他 OS 需手动链接 |
存留 |
| 4 |
LLVM 22 移除 mem2reg C API |
低 |
已记录注释; 需用 opt 工具替代 |
存留 |
| 5 |
错误类型分散 (ErrorInfo + ErrorList) |
低 |
token/parse 用 ErrorInfo, sema 用 ErrorList; 不影响功能 |
存留 |
| 6 |
复合赋值无独立 desugar 测试 |
低 |
集成测试间接覆盖 |
存留 |
| 7 |
for 循环无独立 desugar 测试 |
低 |
集成测试间接覆盖 |
存留 |
| 8 |
for 循环步长固定为 1 |
低 |
需扩展语法支持 step n |
存留 |
6. 推荐开发路线图
v0.4 目标 (下一迭代 — 无变更建议)
| 优先级 |
功能 |
预计工时 |
依赖/备注 |
| P0 |
结构体 struct |
2-3 天 |
解锁 GEP 和复合类型, 全流水线改动 |
| P1 |
codegen 测试扩展 (for/call/str/compound) |
0.5 天 |
覆盖率补偿 |
| P1 |
parser 测试补全 (for 错误恢复) |
0.5 天 |
回归保护 |
| P1 |
str concat arena 化 (修复技术债 #1) |
0.5 天 |
替换 malloc 为 arena 分配 |
v0.5 目标
| 优先级 |
功能 |
预计工时 |
| P1 |
数组 + 索引 [i64; N], arr[i] |
2 天 |
| P1 |
枚举 (C 风格) |
1 天 |
| P1 |
match 表达式 |
2-3 天 |
| P1 |
类型别名 type X = T |
0.5 天 |
长期目标
| 优先级 |
功能 |
预计工时 |
| P2 |
自定义 IR 层 (三地址码/SSA) |
3-5 天 |
| P2 |
模块系统 mod + use |
3-5 天 |
| P2 |
解释器模式 |
2 天 |
| P3 |
泛型 (单态化) |
5-7 天 |
| P3 |
trait / 接口 |
5-7 天 |
| P3 |
自举尝试 |
数周 |
7. 度量汇总
| 指标 |
值 |
变化 (vs 0829 报告) |
| Git HEAD |
620cec4 |
+1 commit (docs-only) |
| 代码基线 |
382cd08 |
无变化 |
| 源文件 (.c) |
11 文件, 1,688 行 |
— |
| 头文件 (.h) |
11 文件, 285 行 |
— |
| Token 类型 |
37 |
— |
| AST 节点类型 |
15 |
— |
| 类型系统 |
5 种 (i64, f64, bool, str, void) |
— |
| 内置函数 |
4 (print_i64/f64/bool/str) |
— |
| 集成测试 |
11 程序 |
— |
| 单元测试函数 |
19 |
— |
| 单元测试断言 |
59 |
— |
| P0 完成度 |
3/4 (75%) |
— (struct 待实施) |
| P1-P3 完成度 |
0/12 |
— |
| AST 节点覆盖率 (sema) |
15/15 (100%) |
— |
| AST 节点覆盖率 (codegen) |
15/15 (100%) |
— |
8. 结论
本次分析确认: 自 2026-06-05 08:29 报告以来无代码变更。 基线代码状态 382cd08 保持不变, 唯一新增的 commit 620cec4 是 CHANGELOG 文档更新。
当前状态: v0.3 阶段已完成。语言支持 37 种 Token, 15 种 AST 节点, 5 种类型, 4 个内置函数。所有 AST 节点在 sema 和 codegen 中均有覆盖。19 个单元测试 + 11 个集成测试提供回归保护。去糖策略 (for 循环/复合赋值) 被验证为有效的架构决策, 实现了零下游侵入的新语法特性扩展。
最大优先级: P0 #4 结构体 struct 是唯一尚未完成的短期高优先功能, 也是解锁数组、枚举等复合类型的关键前置。
技术债务: 8 项债务中, 2 项为中危 (str concat 内存泄漏, codegen 测试覆盖率), 其余均为低危或已缓解。
本报告由 Codex 自动生成。自上次报告 (2026-06-05 08:29) 后无代码变更。代码基线 382cd08, 唯一新增 commit 620cec4 为 CHANGELOG 文档。