Files
l-language/docs/analysis/architecture-analysis-report-2026-06-05-0303.md
T
Serendipity 8144f1bfd7 feat: for 循环 + range (for i in start..end)
- lexer: TOK_FOR, TOK_IN, TOK_DOT_DOT + 修复数字中 .. 解析
- parser: for-in-range → desugar to {let mut, while, assign}
- 零 sema/codegen 改动,复用现有机制
- 新增 2 个集成测试 (10_for_range.l, 11_for_step2.l)
- mem2reg: LLVM 22 C API 不导出,标注已知限制

基于 Codex 分析报告 §6 P0 #3。
2026-06-05 04:42:44 +08:00

12 KiB

L Language 架构分析报告 (v0.2)

日期: 2026-06-05 03:03 | 自动生成 | 自上次报告后有 3 个提交 上次报告: architecture-analysis-report-2026-06-05-0100.md (基线 9ff2990)


变更摘要 (自上次报告)

上次报告提出的 P0 #1 (复合赋值) 和 P0 #2 (修复 str+str 拼接) 已全部落地。另新增 codegen 层单元测试,覆盖了技术债 #4。

Commit 功能 变更量
9e41b09 fix: str+str 运行时拼接 — malloc + strlen + memcpy codegen.c +62
d5a94d4 feat: 复合赋值 += -= *= /= + CHANGELOG 更新 lexer/parser/token +41
72a971e test: codegen 层单元测试 (3 函数, 7 断言) test_codegen.c +96, CMakeLists +10

11 个文件变更, +516/−4 行代码。


1. 当前架构全景

1.1 编译流水线 (无变化)

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

整条流水线手写实现,零生成器依赖。Codegen 与 Target 通过 target.h/c 解耦。

1.2 模块清单与指标

模块 文件 行数 关键职责 新增项
include/ l_lang.h 34 TypeKind 枚举, 向前声明, arena_alloc_impl
util/ arena.c(39) + .h(13) 52 8MB bump allocator
lexer/ lexer.c(135) token.c(45) + .h(40) 220 手写状态机, 40 Token 类型 TOK_PLUS_EQ TOK_MINUS_EQ TOK_STAR_EQ TOK_SLASH_EQ
ast/ ast.c(107) ast.h(93) 200 15 种节点类型 (含 AST_ASSIGN_STMT)
parser/ parser.c(341) parser.h(10) 351 Pratt 解析 + 递归下降语句/函数 复合赋值 desugar (ident += expr -> ident = ident + expr)
sema/ sema.c(294) symbol.c(46) + .h(32) 372 类型推断, 作用域链, 可变性检查 复合赋值的 mut 检查 (通过 desugar 后路径)
codegen/ codegen.c(420) target.c(30) + .h(15) 465 LLVM IR 生成, 4 个运行时函数 malloc/strlen/memcpy 声明, str+str concat 实现
driver/ main.c(133) error.c(46) + .h(18) 197 流水线串联, 错误报告

总计: 22 源文件, ~2,163 行代码 (1,636 实现 .c + 285 头文件 .h + 242 测试)

1.3 技术选型评估

选择 评价 最新状态
C17 + CMake + MinGW 轻量, 学习友好 稳定
Arena bump allocator (8MB) 极简, 零 GC 开销 已统一, 全流水线 arena
LLVM-C API 19.x 成熟, 版本差异已适配 声明 4 个 C 运行时函数 (printf, malloc, strlen, memcpy)
手写 Lexer/Parser 0 外部依赖 稳定, 40 种 Token (新增 4 种复合赋值)
Pratt 表达式解析 优雅优先级处理 无变化
GCC 链接 (system()) 简单但平台绑定 待改进
target.h/c 解耦 关注点分离 无变化

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.1+ 新增功能 (前两次迭代)

  • let mut 可变变量 + 赋值语句 x = expr;
  • 可变性检查 — 不可变变量赋值报编译错误
  • 字符串类型 str + 双引号字面量
  • print_str 内置函数
  • LLVM 目标初始化解耦 (target.h/c)
  • codegen malloc -> arena 统一
  • 6 个集成测试 (01-06)

2.3 本次迭代新增 (v0.2 完成项)

  • str+str 运行时拼接 — codegen 中调用 malloc+strlen+memcpy 实现 (此前语义层通过但运行时返回左操作数)
  • 复合赋值 += -= *= /= — 4 个新 Token, parser 去糖为 x = x op expr, sema 通过去糖路径自动获得可变性检查
  • codegen 层单元测试 — 3 个测试函数 (简单函数 / if-else / 二元运算), 7 个断言, 均含 LLVMVerifyModule 验证
  • 2 个新集成测试: 08_str_concat.l (str+str 拼接), 09_compound_assign.l (四种复合赋值)
  • CHANGELOG 更新为 v0.2.0

2.4 实现细节: 复合赋值去糖路径

x += expr;  (源码)
    v lexer
TOK_IDENT("x") TOK_PLUS_EQ TOK_INT_LIT(5) TOK_SEMICOLON
    v parser (desugar)
AST_ASSIGN_STMT { name="x", value=AST_BINARY_EXPR { OP_ADD, AST_IDENT("x"), AST_LITERAL(5) } }
    v sema (分析 assign_stmt)
检查 x 的可变性, 分析 value 表达式 (x + 5), 检查类型匹配
    v codegen (生成 assign_stmt -> LLVMBuildStore)

3. 与 Rust 对标: 缺失功能清单及状态

按优先级排序。本次迭代完成项标注

P0: 短期 (1-2 天/项)

# 功能 Rust 启发 改动范围 状态
1 复合赋值 += -= *= /= 复合赋值运算符 lexer(4 Token) + parser(desugar) 已完成 (d5a94d4)
2 修复 str+str 运行时拼接 codegen(malloc/strlen/memcpy) 已完成 (9e41b09)
3 for 循环 + Range for i in 0..10 {} lexer(for/in/..) + parser + sema + codegen->while desugar 待实施
4 结构体 struct struct 具名域 lexer(struct/.) + parser + sema + codegen(GEP) 待实施

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 模式
表达式 vs 语句 if/match/block 作为表达式
模式匹配 P1 优先级
代数数据类型 需泛型
所有权 / 借用 远期

4. 架构改进: 已完成 vs 待实施

4.1 已完成 (本次)

  1. str+str 运行时拼接 (来自上次报告 4.2-6)

    • codegen.c 声明 malloc/strlen/memcpy 三个 C 运行时函数
    • AST_BINARY_EXPR 对 TYPE_STR 使用 LLVMBuildCall2 调用 malloc + memcpy 实现拼接
    • 运行时行为: strlen(l) + strlen(r) + 1 分配, 两次 memcpy
  2. 复合赋值去糖 (来自上次报告 P0 #1)

    • lexer: TOK_PLUS_EQ TOK_MINUS_EQ TOK_STAR_EQ TOK_SLASH_EQ 4 个新 Token
    • parser: x += expr -> ast_make_assign("x", ast_make_binary(OP_ADD, ident("x"), expr))
    • sema: 自然复用 AST_ASSIGN_STMT 的可变性检查逻辑
  3. Codegen 层测试 (来自上次报告 4.2-4, 技术债 #4)

    • test_codegen.c: 3 个测试函数, 每个均调用 LLVMVerifyModule 验证 IR 合法性
    • CMakeLists.txt 新增 l_lang_codegen_test 可执行文件
    • 覆盖: 简单函数、if/else、二元运算 — 缺少 while/call/let mut/str/concat/compound/print

4.2 待实施 (继承自上次报告)

# 改进 优先级 说明
1 错误类型统一 (ErrorInfo + ErrorList -> CompilerError) P1 当前两个错误结构体分散多个模块
2 调用约定抽象 (abi.h) P2 封装参数传递和返回值处理
3 system("gcc ...") -> Linker 接口 P2 平台解耦, 支持 ld/lld
4 优化 pass (mem2reg) P1 当前 alloca 效率低, 加一个 pass 即可显著提升

5. 技术债务与风险

# 问题 状态 严重度 说明
1 str concat malloc 内存泄漏 新增 x + y 每次都 malloc 但无 free, 长运行程序会泄漏
2 复合赋值无独立测试 新增 parser desugar 路径无针对性测试 (sema 的 assign 测试可作为间接覆盖)
3 sema 层无 str/let mut/assign 专用测试 存留 仅 3 个 sema 测试, 新功能无回归保护
4 codegen 测试覆盖率低 部分缓解 新增 3 个测试, 但 while/call/str/print/compound 仍无覆盖
5 system("gcc ...") 平台绑定 存留 Windows/MinGW 正常工作, 但不可移植
6 无优化 pass 存留 功能可用但 alloca 密集, mem2reg 能显著改善
7 错误类型分散 (ErrorInfo + ErrorList) 存留 技术债, 不影响功能

6. 推荐开发路线图

v0.3 目标 (下一个迭代)

优先级 功能 预计工时 依赖/备注
P0 for 循环 + range 1 天 去糖为 while, 改动面集中在 parser
P0 结构体 struct 2-3 天 解锁 GEP 和复合类型, 全流水线
P1 sema 层测试补全 (str/let mut/assign) 0.5 天 回归保护
P1 优化 pass (mem2reg) 0.25 天 一行调用
P1 codegen 测试补全 (while/call/str) 0.5 天 覆盖率补偿

v0.4 目标

优先级 功能 预计工时
P1 数组 + 索引 2 天
P1 枚举 (C 风格) 1 天
P1 match 表达式 2-3 天
P1 类型别名 0.5 天

长期

优先级 功能 预计工时
P2 自定义 IR 层 3-5 天
P2 模块系统 3-5 天
P2 解释器模式 2 天
P3 泛型 (单态化) 5-7 天
P3 trait / 接口 5-7 天
P3 自举尝试 数周

7. 度量汇总

指标 上次报告 (v0.1+, 9ff2990) 本次 (v0.2, 72a971e) 变化
源文件数 22 23 (+test_codegen.c) +1
实现代码 (.c) ~1,530 1,636 +106
头文件 (.h) ~303 285 -18 (token.h 精简)
测试代码 ~146 242 +96
Token 类型 30 34 +4 (复合赋值)
AST 节点类型 15 15 无变化
类型系统 5 种 (i64/f64/bool/str/void) 5 种 无变化
内置函数 4 (print_*) 4 无变化
集成测试 7 程序 9 程序 +2
单元测试函数 11 14 +3 (codegen)
单元测试断言 38 45 +7
C 运行时依赖 printf printf + malloc + strlen + memcpy +3
LLVM 模块 codegen.c + target.c 无变化
报告 P0 完成度 2/2 (本次目标) 100%

本报告由 Codex 自动生成。自上次报告 (2026-06-05 01:00) 后代码有显著变化 (3 commits, +516/-4 行)。上次报告的 P0 #1 #2 和 技术债 #4 全部落地, P0 #3 (for) 和 P0 #4 (struct) 为下一迭代目标。