Files
l-language/docs/analysis/architecture-analysis-report-2026-06-05-1150.md
T
Serendipity b390d390f3 feat: 结构体 struct — 最后一项 P0 功能
- lexer: TOK_STRUCT, TOK_DOT 关键字和运算符
- ast: AST_STRUCT_DECL/STRUCT_INIT/FIELD_ACCESS 3 种新节点
- parser: struct 声明 + .field 访问 + Name{field:val} 初始化
- sema: struct 类型符号表,字段类型解析,初始化字段检查
- codegen: LLVMStructType + extractvalue/insertvalue 字段操作
- 新增集成测试: 12_struct.l, 13_struct_nested.l
- 基于 Codex 分析报告 P0 #4

所有 P0 功能已全部完成。
2026-06-05 12:21:22 +08:00

14 KiB

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 编译流水线 (无变化)

源码(.l) -> Lexer(词法) -> Parser(语法) -> Sema(语义) -> Codegen(LLVM IR) -> Target(obj) -> GCC链接(.exe)
              Token[]        AstNode*        类型标注         LLVMModuleRef       .o 文件

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 新增 (全部完成)

  • let mut 可变变量 + 赋值语句 (x = expr)
  • 可变性检查 — 不可变变量赋值报编译错误
  • 字符串类型 str + 双引号字面量
  • print_str 内置函数
  • str + str 运行时拼接 (malloc + strlen + memcpy)
  • 复合赋值 += -= *= /= (parser 去糖)
  • LLVM 目标初始化解耦 → target.h/c 独立模块
  • codegen malloc → arena 统一分配

2.3 v0.3 新增 (全部完成)

  • for 循环 + range — for i in start..end { ... } (parser 去糖为 let mut i = start; while i < end { ...; i = i + 1; })
  • .. range 运算符 (TOK_DOT_DOT)
  • 浮点数 lexer 修复 — peek_next... 冲突
  • sema 测试补全: +5 测试 (let mut assign OK, immutable assign error, str type, str concat)
  • codegen 测试补全: +1 测试 (while 循环)
  • 集成测试: 10_for_range.l, 11_for_step2.l

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 文档。