diff --git a/docs/analysis/architecture-analysis-report-2026-06-05-0100.md b/docs/analysis/architecture-analysis-report-2026-06-05-0100.md deleted file mode 100644 index 00bcb9c..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-05-0100.md +++ /dev/null @@ -1,268 +0,0 @@ -# L Language 架构分析报告 (v0.1+) - -> 日期: 2026-06-05 01:00 | 自动生成 | 自上次报告后有 4 个提交 -> 上次报告: [docs/architecture-analysis-report-2026-06-05.md](/D:\Code\doing_exercises\programs\L Language\docs\architecture-analysis-report-2026-06-05.md) (v0.1 基线 3b7bab1) - ---- - -## 变更摘要 (自上次报告) - -- [x] P0: `let mut` + 赋值语句 -- [x] P0: 字符串类型 + 字面量 + `print_str` -- [x] 架构: LLVM 目标初始化解耦 -> `target.h/c` -- [x] 技术债: codegen `malloc` -> arena -- [x] 技术债: 添加 `.codegraphignore` - -上次报告提出的 4 项 P0 建议已全部落地。本次报告反映 v0.1 + 4 commits 后的当前快照,新增 588 行代码(net),2 个集成测试程序(06_mut_while.l, 07_hello_str.l)。 - -| Commit | 功能 | -|--------|------| -| `f8c5e18` | 技术债修复:codegen malloc->arena + .codegraphignore | -| `bd02a49` | `let mut` + 赋值语句 -- while 循环可修改变量 | -| `9a53d97` | 字符串类型 + 字面量 + `print_str` | -| `9ff2990` | LLVM 目标初始化解耦 -- 抽取 target.h/c | - ---- - -## 1. 当前架构全景 - -### 1.1 编译流水线 - -``` -源码(.l) -> Lexer(词法) -> Parser(语法) -> Sema(语义) -> Codegen(LLVM IR) -> Target(obj) -> 链接(.exe) - Token[] AstNode* 类型标注 LLVMModuleRef .o 文件 GCC/ld -``` - -一条完整的手写单趟编译器流水线,无依赖生成器。Codegen 层与 Target 层已通过 `target.h/c` 解耦。 - -### 1.2 模块清单与指标 - -| 模块 | 文件 | 行数 | 关键数据结构 | 新增功能 | -|------|------|------|-------------|---------| -| lexer/ | lexer.c(131) token.c(44) + .h(49) | 224 | Token {kind, start, length, line, col} | TOK_MUT, TOK_STR, TOK_STR_LIT, TOK_ASSIGN | -| ast/ | ast.c(107) ast.h(93) | 200 | AstNode {kind, type, as{union}} | AST_ASSIGN_STMT, is_mut, str_val | -| parser/ | parser.c(314) parser.h(10) | 324 | Parser {tokens, pos, filename, arena} | let mut 解析, 赋值语句, 字符串字面量 | -| sema/ | sema.c(294) symbol.c(46) + .h(41) | 381 | Scope {head, parent}, Symbol {is_mut} | 可变性检查, TYPE_STR, print_str, 赋值检查 | -| codegen/ | codegen.c(365) target.c(30) + .h(26) | 421 | CgCtx {builder, var_table, fn_table} | Store(赋值), GlobalStringPtr(str) | -| driver/ | main.c(133) error.c(46) + .h(18) | 197 | 流水线串联 | 调用 target_* 接口 | -| util/ | arena.c(39) arena.h(13) | 52 | Arena {memory, offset, capacity} | 8MB bump allocator | -| include/ | l_lang.h | 34 | TypeKind, 公共声明 | TYPE_STR 新增 | - -**总计: 22 源文件, ~1,833 行实现代码** - -### 1.3 技术选型评估 - -| 选择 | 评价 | 最新状态 | -|------|------|---------| -| C17 + CMake + MinGW | 轻量,学习友好 | 稳定 | -| Arena bump allocator | 极简内存管理,无 GC 开销 | 已统一(codegen 原先混用 malloc) | -| LLVM-C API (19.x) | 成熟但版本差异需处理 | 已适配 LLVMContext API | -| 手写 Lexer/Parser | 0 外部依赖,完整控制 | 稳定,30 种 Token 类型 | -| Pratt 表达式解析 | 优雅处理优先级,易扩展 | 无变化 | -| GCC 链接 (`system()`) | 简单但平台绑定 | 待改进 | -| 分离 target.h/c | 关注点分离,可测试 | **新建模块** | - ---- - -## 2. 功能清单与成熟度 - -### 2.1 v0.1 基线功能 - -- [x] 基本类型: i64, f64, bool, void -- [x] 算术运算: + - * / % -- [x] 比较运算: == != < > <= >= -- [x] 逻辑运算: && || ! -- [x] 变量声明: let 不可变,类型标注 + 类型推断 -- [x] 控制流: if/else, while -- [x] 函数定义与调用: 参数、返回类型、递归 -- [x] 内置函数: print_i64, print_f64, print_bool -- [x] 注释: // 行注释, /* */ 块注释 -- [x] 错误报告: 词法/语法即时终止, 语义错误批量输出 -- [x] 测试: 65 单元测试 + 5 集成测试 - -### 2.2 v0.1+ 新增功能 - -- [x] **let mut 可变变量** -- `let mut x: i64 = 0;` 声明可变变量 -- [x] **赋值语句** -- `x = x + 1;` 对可变变量赋值(LLVMBuildStore) -- [x] **可变性检查** -- 对不可变变量赋值报 "不能对不可变变量赋值(需用 let mut 声明)" -- [x] **字符串类型 str** -- 类型系统新增 TYPE_STR -- [x] **字符串字面量** -- `"Hello, L Language!"` 双引号字面量,LLVMBuildGlobalStringPtr -- [x] **字符串拼接 (语义)** -- `"a" + "b"` 类型检查为 str + str -> str -- [x] **print_str 内置函数** -- 委托 printf("%%s\n", str) -- [x] **target.h/c 独立模块** -- LLVM 目标初始化与 Codegen 解耦 -- [x] **集成测试**: 06_mut_while.l (可变 while 循环), 07_hello_str.l (字符串输出) - -### 2.3 实现细节 - -**let mut + 赋值** 贯穿全流水线: -- Lexer: `TOK_MUT` (关键字), `TOK_ASSIGN` (分隔符) -- AST: `AST_ASSIGN_STMT` 节点, `let_stmt.is_mut` 标志 -- Parser: `let mut IDENT = expr;` 完整解析; `IDENT = expr;` 赋值语句(标识符后紧跟 `=` 时触发) -- Sema: `Symbol.is_mut` 标记; 赋值时检查可变性 + 类型一致性 -- Codegen: `LLVMBuildStore` 向现有 alloca 写入新值 - -**字符串类型** 实现: -- Lexer: `TOK_STR` (类型关键字), `TOK_STR_LIT` (双引号字面量) -- AST: `literal.str_val` (arena 拷贝), `AST_LITERAL_EXPR` 支持 TYPE_STR -- Parser: `TOK_STR_LIT` 创建 `ast_make_literal_str()` -- Sema: TYPE_STR 加入类型系统; `+` 对 str+str 做类型检查 -- Codegen: `LLVMBuildGlobalStringPtr` 生成全局常量; `print_str` 委派 printf -- **限制**: 运行时字符串拼接(str + str)在 codegen 中直接返回左操作数,语义层验证通过但**运行时行为不正确** - ---- - -## 3. 与 Rust 对标:缺失功能清单 - -按 "学习价值 + 实现难度" 排序。已完成项标注 ✓。 - -### P0: 短期(1-2 天/项) - -| # | 功能 | Rust 启发 | 改动范围 | 学习价值 | -|---|------|----------|---------|---------| -| ✓ | let mut + 赋值 | 默认不可变 | lexer/parser/sema/codegen | 不可变性贯穿全流水线 | -| ✓ | 字符串类型 + 字面量 | &str/String | lexer/parser/sema/codegen | LLVM 全局常量和指针 | -| 1 | **复合赋值** += -= *= /= | 复合赋值运算符 | lexer(4 Token) + parser(desugar) + sema(mut check) | 语法糖去糖 | -| 2 | **修复 str+str 运行时拼接** | -- | codegen(strcat/memcpy) | 运行时内存操作 | -| 3 | **for 循环 + Range** | for i in 0..10 {} | lexer(for/in/..) + parser + sema + codegen->while | 去糖为 while 循环 | -| 4 | **结构体 struct** | struct 具名域 | lexer(struct/.) + parser + sema + codegen(GEP) | GEP 指针计算 | - -### P1: 中期(3-5 天/项) - -| # | 功能 | 改动范围 | 学习价值 | -|---|------|---------|---------| -| 5 | **数组 + 索引** [i64; N], arr[i] | lexer/parser/sema/codegen(GEP) | GEP 多维指针计算 | -| 6 | **枚举 (C 风格)** | lexer(enum) + parser + sema + codegen(i64) | 为代数类型铺路 | -| 7 | **match 表达式** | lexer/parser/sema(穷举检查) + codegen | 模式匹配是 PL 核心 | -| 8 | **类型别名** type Meters = i64 | lexer/parser/sema(展开) | 名称等价 vs 结构等价 | - -### P2: 中后期(1-2 周/项) - -| # | 功能 | 学习价值 | -|---|------|---------| -| 9 | 模块系统 mod + use | 从单文件到多文件跳跃 | -| 10 | 自定义 IR 层 (三地址码/SSA) | "IR 是编译器的核心抽象" | -| 11 | 泛型 (单态化) | Rust 零成本抽象的基石 | -| 12 | 解释器模式 (walk AST) | 快速验证语义,无需 LLVM | - -### P3: 长期(2-4 周/项) - -| # | 功能 | 备注 | -|---|------|------| -| 13 | trait / 接口 | 需泛型 + 虚表 | -| 14 | Option/Result 错误处理 | 需泛型 + enum | -| 15 | 所有权 / 借用检查 | 借用检查器,极度复杂 | -| 16 | 自举 (L 编译 L) | 终极考验 | - -### Rust 设计哲学吸收建议 - -| Rust 特性 | 决策 | 理由 | -|-----------|------|------| -| 默认不可变 (let vs let mut) | **已加** | 编译期检查,零实现成本 | -| 表达式 vs 语句 | 建议加 | if/match/block 作为表达式 | -| 模式匹配 | 建议加 | 最优雅的控制流之一 | -| 代数数据类型 | 有条件 | 需要泛型支持 | -| Option/Result | 有条件 | 依赖泛型 + enum | -| 所有权 / 借用 | 暂不加 | 借用检查器,远超当前阶段 | -| 生命周期标注 | 暂不加 | 所有权系统的伴生 | -| trait 系统 | 暂不加 | 需泛型 + 虚表 | -| 宏系统 | 暂不加 | 自举后才考虑 | - ---- - -## 4. 架构改进:已完成 vs 待实施 - -### 4.1 已完成 ✓ - -1. **代码生成与链接解耦** (来自上次报告 4.1-1) - - `src/codegen/target.h/c` 新增 (30+15 行) - - 接口: target_init(), target_get_default_triple(), target_create_machine(), target_emit_obj() - - main.c 减少 25 行 inline LLVM Target API 调用 - -2. **内存管理统一** (来自上次报告 7-1) - - codegen.c 所有 malloc 替换为 arena_alloc() - - 消除内存泄漏风险 - -3. **索引排除** (来自上次报告 7-5) - - .codegraphignore 排除 build/ - -### 4.2 待实施 - -4. **错误类型统一** (上次报告 4.1-2) - - 当前: ErrorInfo 和 ErrorList 分散多个模块 - - 建议: 统一为 CompilerError 结构体 - -5. **测试框架扩展** (上次报告 4.1-3) - - 当前: 无 codegen 层测试 - - 建议: test_codegen.c + LLVMVerifyModule - -6. **调用约定抽象** (上次报告 4.2-6) - - 建议: 抽 abi.h 封装参数传递和返回值处理 - ---- - -## 5. 技术债务与风险 - -| # | 问题 | 状态 | 影响 | 建议 | -|---|------|------|------|------| -| 1 | codegen malloc 混用 arena | **已修复** | -- | -- | -| 2 | 无 .codegraphignore | **已修复** | -- | -- | -| 3 | system("gcc ...") 链接 | **仍存在** | 平台不兼容 | 封装 Linker 接口,支持 ld/lld | -| 4 | 无 codegen 层测试 | **仍存在** | IR 正确性无形式验证 | test_codegen.c | -| 5 | 无优化 pass (mem2reg) | **仍存在** | alloca 效率低 | LLVMRunPassManager | -| 6 | 字符串运行时拼接不工作 | **新增** | "a"+"b" 语义通过但运行时错误 | codegen 中实现 strcat/memcpy | -| 7 | CHANGELOG 未更新 | **新增** | 4 个新 commit 未记录 | 添加 v0.2.0 条目 | - ---- - -## 6. 推荐开发路线图 - -### v0.2 目标 - -| 优先级 | 功能 | 预计工时 | 备注 | -|--------|------|---------|------| -| P0 | 修复 str+str 运行时拼接 | 0.5 天 | 阻塞后续 | -| P0 | 复合赋值 += -= *= /= | 0.5 天 | 语法糖,改动面小 | -| P0 | 结构体 struct | 2-3 天 | 解锁 GEP 和复合类型 | -| P0 | for 循环 + range | 1 天 | 去糖为 while | -| P1 | test_codegen.c | 1 天 | 技术债补偿 | - -### v0.3 目标 - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| P1 | 数组 + 索引 | 2 天 | -| P1 | 枚举 (C 风格) | 1 天 | -| P2 | match 表达式 | 2-3 天 | -| P1 | 类型别名 | 0.5 天 | -| P2 | 解释器模式 | 2 天 | - -### 长期 - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| P2 | 自定义 IR 层 | 3-5 天 | -| P2 | 模块系统 | 3-5 天 | -| P3 | 泛型 (单态化) | 5-7 天 | -| P3 | trait / 接口 | 5-7 天 | -| P3 | 自举尝试 | 数周 | - ---- - -## 7. 度量汇总 - -| 指标 | v0.1 基线 | 当前 (v0.1+) | 变化 | -|------|----------|-------------|------| -| 源文件数 | 19 | 22 | +3 | -| 实现代码行 | ~1,300 | ~1,833 | +~530 | -| Token 类型 | 25 | 30 | +5 | -| AST 节点类型 | 13 | 15 | +2 | -| 类型系统 | 4 种 | 5 种 (+str) | +1 | -| 内置函数 | 3 | 4 (+print_str) | +1 | -| 集成测试 | 5 程序 | 7 程序 | +2 | -| 单元测试 | 65 | 65 | 无变化 | -| LLVM 模块 | 单体 codegen.c | codegen.c + target.c | 解耦 | -| 报告 P0 完成度 | -- | 4/4 | 100% | - ---- - -*本报告由 Codex 自动生成。自上次报告后代码有显著变化 (4 commits, +588/-53 行),上次报告的 4 项 P0 建议全部实现。* diff --git a/docs/analysis/architecture-analysis-report-2026-06-05-0303.md b/docs/analysis/architecture-analysis-report-2026-06-05-0303.md deleted file mode 100644 index 7b38a61..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-05-0303.md +++ /dev/null @@ -1,262 +0,0 @@ -# L Language 架构分析报告 (v0.2) - -> 日期: 2026-06-05 03:03 | 自动生成 | 自上次报告后有 3 个提交 -> 上次报告: [architecture-analysis-report-2026-06-05-0100.md](/D:/Code/doing_exercises/programs/L%20Language/docs/analysis/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 基线功能 (全部保持) - -- [x] 基本类型: i64, f64, bool, void -- [x] 算术: + - * / % -- [x] 比较: == != < > <= >= -- [x] 逻辑: && || ! -- [x] let 不可变变量, 类型标注 + 类型推断 -- [x] 控制流: if/else (含 else if), while, return -- [x] 函数定义与调用, 递归 -- [x] 内置函数: print_i64, print_f64, print_bool -- [x] 注释: // 行注释, /* */ 块注释 -- [x] 错误报告: 词法/语法即时终止, 语义错误批量输出 - -### 2.2 v0.1+ 新增功能 (前两次迭代) - -- [x] let mut 可变变量 + 赋值语句 x = expr; -- [x] 可变性检查 — 不可变变量赋值报编译错误 -- [x] 字符串类型 str + 双引号字面量 -- [x] print_str 内置函数 -- [x] LLVM 目标初始化解耦 (target.h/c) -- [x] codegen malloc -> arena 统一 -- [x] 6 个集成测试 (01-06) - -### 2.3 本次迭代新增 (v0.2 完成项) - -- [x] **str+str 运行时拼接** — codegen 中调用 malloc+strlen+memcpy 实现 (此前语义层通过但运行时返回左操作数) -- [x] **复合赋值** += -= *= /= — 4 个新 Token, parser 去糖为 x = x op expr, sema 通过去糖路径自动获得可变性检查 -- [x] **codegen 层单元测试** — 3 个测试函数 (简单函数 / if-else / 二元运算), 7 个断言, 均含 LLVMVerifyModule 验证 -- [x] **2 个新集成测试**: 08_str_concat.l (str+str 拼接), 09_compound_assign.l (四种复合赋值) -- [x] 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) 为下一迭代目标。* diff --git a/docs/analysis/architecture-analysis-report-2026-06-05-0703.md b/docs/analysis/architecture-analysis-report-2026-06-05-0703.md deleted file mode 100644 index f68f554..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-05-0703.md +++ /dev/null @@ -1,288 +0,0 @@ -# L Language 架构分析报告 (v0.3) - -> 日期: 2026-06-05 07:03 | 自动生成 | 自上次报告后有 2 个提交 -> 上次报告: [architecture-analysis-report-2026-06-05-0303.md](/D:/Code/doing_exercises/programs/L%20Language/docs/analysis/architecture-analysis-report-2026-06-05-0303.md) (基线 72a971e) - ---- - -## 变更摘要 (自上次报告) - -上次报告的 P0 #3 (for 循环 + range) 已落地。P0 #4 (struct) 仍待实施。测试大幅补强。 - -| Commit | 功能 | 变更量 | -|--------|------|--------| -| `8144f1b` | feat: for 循环 + range (for i in start..end) | lexer +4 Token, parser +64 | -| `382cd08` | test: sema + codegen 测试补全 | test_sema.c +5 函数, test_codegen.c +1 函数 | - -10 个文件变更, +443/-6 行代码。 - -**核心变化**: -- 新增 3 个 Token: `TOK_FOR`, `TOK_IN`, `TOK_DOT_DOT`,Token 总数 34→37 -- 浮点数字面量解析修复: `peek_next` 检查 `.` 不是 `..` 时才消耗小数点 -- for 循环完全通过 parser 去糖实现,无需新增 AST 节点类型或 codegen 路径 -- 单元测试: 14→19 函数 (+5), 45→59 断言 (+14) -- 集成测试: 9→11 程序 (+2: `10_for_range.l`, `11_for_step2.l`) - ---- - -## 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 枚举, 向前声明, arena_alloc_impl | — | -| util/ | arena.c(39) + .h(13) | 52 | 8MB bump allocator | — | -| lexer/ | lexer.c(141) token.c(46) + .h(40) | 227 | 手写状态机, **37** Token 类型 | +TOK_FOR/TOK_IN/TOK_DOT_DOT, peek_next 修复 | -| ast/ | ast.c(107) ast.h(93) | 200 | **15** 种节点类型 | — | -| parser/ | parser.c(405) parser.h(10) | 415 | Pratt + 递归下降 + **for 去糖** | +64 行 for 解析与去糖 | -| sema/ | sema.c(294) symbol.c(46) + .h(32) | 372 | 类型推断, 作用域链, 可变性检查 | — | -| codegen/ | codegen.c(421) target.c(30) + .h(15) | 466 | LLVM IR, 4 运行时函数 | +1 行 LLVM 22 mem2reg 注释 | -| driver/ | main.c(133) error.c(46) + .h(18) | 197 | 流水线串联, 错误报告 | — | -| test/ | test_*.c(4 文件) | 330 | 19 测试函数, 59 断言 | +6 测试函数, +14 断言 | - -**总计: 23 源文件, ~1,689 行实现代码 + 251 头文件 + 330 测试 = ~2,270 行** - -### 1.3 for 循环去糖路径 (新增) - -这是本迭代的核心架构决策 — for 循环完全在 parser 层去糖,无下游变更: - -``` -for i in 0..5 { body; } (源码) - v lexer -TOK_FOR TOK_IDENT("i") TOK_IN TOK_INT_LIT(0) TOK_DOT_DOT TOK_INT_LIT(5) TOK_LBRACE ... TOK_RBRACE - v parser (desugar) -{ - let mut i = 0; - while i < 5 { - body; - i = i + 1; - } -} - v sema (无变更,分析 while + let mut + assign 即可) -类型检查: i < 5 确保两边类型兼容, i = i + 1 检查可变性 - v codegen (无变更,生成 while + alloca + store + load) -``` - -**设计评价**: 去糖策略正确。for 降级为已有原语,零 codegen/sema 入侵,零新 AST 节点。代价是步长固定为 1 — 如需自定义步长需扩展语法或使用 `for i in start..end step n`。 - -### 1.4 技术选型评估 (更新) - -| 选择 | 评价 | 最新状态 | -|------|------|---------| -| C17 + CMake + MinGW | 轻量, 学习友好 | 稳定 | -| Arena bump allocator | 零 GC 开销 | 稳定 | -| LLVM-C API 19.x | 成熟 | **LLVM 22 移除 mem2reg C API** (已记录注释) | -| 手写 Lexer/Parser | 0 外部依赖 | 37 种 Token | -| Pratt 表达式解析 | 优雅优先级 | 无变化 | -| GCC 链接 (system()) | 简单但平台绑定 | 待改进 | -| 去糖策略 (复合赋值/for) | AST 节点数不膨胀 | 已验证有效 | - ---- - -## 2. 功能清单与成熟度 - -### 2.1 v0.1 基线功能 - -- [x] 基本类型: i64, f64, bool, void -- [x] 算术: + - * / % -- [x] 比较: == != < > <= >= -- [x] 逻辑: && || ! -- [x] let 不可变变量, 类型标注 + 类型推断 -- [x] 控制流: if/else (含 else if), while, return -- [x] 函数定义与调用, 递归 -- [x] 内置函数: print_i64, print_f64, print_bool -- [x] 注释: // 行注释, /* */ 块注释 -- [x] 错误报告: 词法/语法即时终止, 语义错误批量输出 - -### 2.2 v0.1+ 功能 (前两次迭代) - -- [x] let mut 可变变量 + 赋值语句 -- [x] 可变性检查 — 不可变变量赋值报编译错误 -- [x] 字符串类型 str + 双引号字面量 -- [x] print_str 内置函数 -- [x] str+str 运行时拼接 -- [x] 复合赋值 += -= *= /= (去糖) -- [x] LLVM 目标初始化解耦 (target.h/c) -- [x] codegen malloc -> arena 统一 - -### 2.3 本次迭代新增 (v0.3) - -- [x] **for 循环 + range** — `for i in start..end { ... }`,parser 去糖为 `let mut i = start; while i < end { ...; i = i + 1; }` -- [x] **浮点数 lexer 修复** — `peek_next` 防 `..` 与 `.` 冲突 -- [x] **sema 测试补全** — +5 测试: let mut assign OK, immutable assign error, str type, str concat -- [x] **codegen 测试补全** — +1 测试: while 循环 -- [x] **2 个新集成测试**: `10_for_range.l`, `11_for_step2.l` -- [x] LLVM 22 mem2reg 不可用注释 (防止后续困惑) - ---- - -## 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 作为表达式 | -| 模式匹配 | ❌ | P1 优先级 | -| 代数数据类型 | ❌ | 需泛型 | -| 所有权 / 借用 | ❌ | 远期 | - ---- - -## 4. 测试覆盖分析 - -### 4.1 单元测试 - -| 测试文件 | 函数数 | 断言数 | 覆盖范围 | 本次变化 | -|---------|--------|--------|---------|---------| -| test_lexer.c | 3 | 14 | token 识别, 关键字, 操作符, 注释 | — | -| test_parser.c | 5 | 15 | 算术, let, if, while, 函数 | — | -| test_sema.c | 7 | 21 | 类型错误, 未定义变量, let mut, immutable assign error, str, str concat | **+5 函数, +12 断言** | -| test_codegen.c | 4 | 9 | 简单函数, if/else, 二元运算, while | **+1 函数, +2 断言** | -| **合计** | **19** | **59** | | **+6 函数, +14 断言** | - -### 4.2 集成测试 (11 程序) - -| 文件 | 功能 | 状态 | -|------|------|------| -| 01_arithmetic.l | 算术运算 | ✅ | -| 02_if_else.l | if/else 控制流 | ✅ | -| 03_recurse.l | 递归函数 | ✅ | -| 04_fib_recursive.l | 斐波那契 | ✅ | -| 05_float.l | 浮点数 | ✅ | -| 06_mut_while.l | let mut + while | ✅ | -| 07_hello_str.l | 字符串输出 | ✅ | -| 08_str_concat.l | 字符串拼接 | ✅ | -| 09_compound_assign.l | 复合赋值 | ✅ | -| 10_for_range.l | for range 循环 | ✅ 新增 | -| 11_for_step2.l | for range (变量边界) | ✅ 新增 | - -### 4.3 测试缺口 - -| 缺口 | 严重度 | 说明 | -|------|--------|------| -| 复合赋值无独立 desugar 测试 | 低 | 仅通过集成测试间接覆盖 | -| for 循环无独立 desugar 测试 | 低 | 同上,集成测试覆盖 | -| codegen 缺 call/str/compound/for 路径 | 中 | 4 测试仅覆盖基础路径 | -| parser 缺 for 错误恢复测试 | 低 | 缺少 for/in/.. 错误提示验证 | - ---- - -## 5. 技术债务与风险 - -| # | 问题 | 状态 | 严重度 | 说明 | -|---|------|------|--------|------| -| 1 | str concat malloc 内存泄漏 | **存留** | 中 | x + y 每次 malloc 无 free,长运行程序会泄漏 | -| 2 | 复合赋值无独立 desugar 测试 | **存留** | 低 | 集成测试间接覆盖 | -| 3 | sema 层缺 str/let mut/assign 测试 | **✅ 已解决** | — | 本次新增 5 个 sema 测试 | -| 4 | codegen 测试覆盖率低 | **部分缓解** | 中 | 新增 while 测试,但 call/str/compound/for 仍无覆盖 | -| 5 | system("gcc ...") 平台绑定 | **存留** | 低 | Windows/MinGW 正常工作 | -| 6 | LLVM 22 无 mem2reg C API | **已记录** | 低 | codegen.c 注释说明需用 opt 工具 | -| 7 | 错误类型分散 (ErrorInfo + ErrorList) | **存留** | 低 | 不影响功能 | -| 8 | CHANGELOG 未更新 v0.3 | **新增** | 低 | 仍标 v0.2.0 | - ---- - -## 6. 推荐开发路线图 - -### v0.4 目标 (下一迭代) - -| 优先级 | 功能 | 预计工时 | 依赖/备注 | -|--------|------|---------|----------| -| **P0** | **结构体 struct** | 2-3 天 | 解锁 GEP 和复合类型,全流水线 | -| P1 | parser 测试补全 (for 错误恢复) | 0.5 天 | 回归保护 | -| P1 | codegen 测试扩展 (for/call/str) | 0.5 天 | 覆盖率补偿 | -| P1 | 更新 CHANGELOG v0.3 | 0.1 天 | 记录 for 循环 | -| P1 | str concat arena 化 (修复技术债 #1) | 0.5 天 | 替换 malloc 为 arena 分配 | - -### v0.5 目标 - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| 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.2, 72a971e) | 本次 (v0.3, 382cd08) | 变化 | -|------|--------------------------|---------------------|------| -| 源文件数 | 22 | 23 | — | -| 实现代码 (.c) | 1,636 | 1,688 | +52 | -| 头文件 (.h) | 285 | 251 | -34 | -| 测试代码 | 242 | 330 | +88 | -| Token 类型 | 34 | 37 | +3 (FOR/IN/DOT_DOT) | -| AST 节点类型 | 15 | 15 | 无变化 | -| 类型系统 | 5 种 | 5 种 | 无变化 | -| 内置函数 | 4 (print_*) | 4 | 无变化 | -| C 运行时依赖 | printf, malloc, strlen, memcpy | 无变化 | — | -| 集成测试 | 9 程序 | 11 程序 | +2 | -| 单元测试函数 | 14 | 19 | +5 | -| 单元测试断言 | 45 | 59 | +14 | -| 上次 P0 完成度 | 2/4 | 3/4 (+for) | 75% | -| 上次 P0 遗留 | for, struct | struct | — | - ---- - -*本报告由 Codex 自动生成。自上次报告 (2026-06-05 03:03) 后代码有显著变化 (2 commits, +443/-6)。P0 #3 (for 循环 + range) 完成, P0 #4 (struct) 为下一迭代唯一 P0 目标。测试覆盖从 14 函数/45 断言升至 19 函数/59 断言。* diff --git a/docs/analysis/architecture-analysis-report-2026-06-05-0829.md b/docs/analysis/architecture-analysis-report-2026-06-05-0829.md deleted file mode 100644 index 8af7b24..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-05-0829.md +++ /dev/null @@ -1,288 +0,0 @@ -# L Language 架构分析报告 (v0.3 — 无变更增量) - -> 日期: 2026-06-05 08:29 | 自动生成 | 自上次报告后无代码变更 -> 上次报告: [architecture-analysis-report-2026-06-05-0703.md](D:/Code/doing_exercises/programs/L%20Language/docs/analysis/architecture-analysis-report-2026-06-05-0703.md) (基线 382cd08) - ---- - -## 变更摘要 (自上次报告) - -上次报告的 P0 #3 (for 循环 + range) 已落地。P0 #4 (struct) 仍待实施。测试大幅补强。 - -| Commit | 功能 | 变更量 | -|--------|------|--------| -| `8144f1b` | feat: for 循环 + range (for i in start..end) | lexer +4 Token, parser +64 | -| `382cd08` | test: sema + codegen 测试补全 | test_sema.c +5 函数, test_codegen.c +1 函数 | - -10 个文件变更, +443/-6 行代码。 - -**核心变化**: -- 新增 3 个 Token: `TOK_FOR`, `TOK_IN`, `TOK_DOT_DOT`,Token 总数 34→37 -- 浮点数字面量解析修复: `peek_next` 检查 `.` 不是 `..` 时才消耗小数点 -- for 循环完全通过 parser 去糖实现,无需新增 AST 节点类型或 codegen 路径 -- 单元测试: 14→19 函数 (+5), 45→59 断言 (+14) -- 集成测试: 9→11 程序 (+2: `10_for_range.l`, `11_for_step2.l`) - ---- - -## 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 枚举, 向前声明, arena_alloc_impl | — | -| util/ | arena.c(39) + .h(13) | 52 | 8MB bump allocator | — | -| lexer/ | lexer.c(141) token.c(46) + .h(40) | 227 | 手写状态机, **37** Token 类型 | +TOK_FOR/TOK_IN/TOK_DOT_DOT, peek_next 修复 | -| ast/ | ast.c(107) ast.h(93) | 200 | **15** 种节点类型 | — | -| parser/ | parser.c(405) parser.h(10) | 415 | Pratt + 递归下降 + **for 去糖** | +64 行 for 解析与去糖 | -| sema/ | sema.c(294) symbol.c(46) + .h(32) | 372 | 类型推断, 作用域链, 可变性检查 | — | -| codegen/ | codegen.c(421) target.c(30) + .h(15) | 466 | LLVM IR, 4 运行时函数 | +1 行 LLVM 22 mem2reg 注释 | -| driver/ | main.c(133) error.c(46) + .h(18) | 197 | 流水线串联, 错误报告 | — | -| test/ | test_*.c(4 文件) | 330 | 19 测试函数, 59 断言 | +6 测试函数, +14 断言 | - -**总计: 23 源文件, ~1,689 行实现代码 + 251 头文件 + 330 测试 = ~2,270 行** - -### 1.3 for 循环去糖路径 (新增) - -这是本迭代的核心架构决策 — for 循环完全在 parser 层去糖,无下游变更: - -``` -for i in 0..5 { body; } (源码) - v lexer -TOK_FOR TOK_IDENT("i") TOK_IN TOK_INT_LIT(0) TOK_DOT_DOT TOK_INT_LIT(5) TOK_LBRACE ... TOK_RBRACE - v parser (desugar) -{ - let mut i = 0; - while i < 5 { - body; - i = i + 1; - } -} - v sema (无变更,分析 while + let mut + assign 即可) -类型检查: i < 5 确保两边类型兼容, i = i + 1 检查可变性 - v codegen (无变更,生成 while + alloca + store + load) -``` - -**设计评价**: 去糖策略正确。for 降级为已有原语,零 codegen/sema 入侵,零新 AST 节点。代价是步长固定为 1 — 如需自定义步长需扩展语法或使用 `for i in start..end step n`。 - -### 1.4 技术选型评估 (更新) - -| 选择 | 评价 | 最新状态 | -|------|------|---------| -| C17 + CMake + MinGW | 轻量, 学习友好 | 稳定 | -| Arena bump allocator | 零 GC 开销 | 稳定 | -| LLVM-C API 19.x | 成熟 | **LLVM 22 移除 mem2reg C API** (已记录注释) | -| 手写 Lexer/Parser | 0 外部依赖 | 37 种 Token | -| Pratt 表达式解析 | 优雅优先级 | 无变化 | -| GCC 链接 (system()) | 简单但平台绑定 | 待改进 | -| 去糖策略 (复合赋值/for) | AST 节点数不膨胀 | 已验证有效 | - ---- - -## 2. 功能清单与成熟度 - -### 2.1 v0.1 基线功能 - -- [x] 基本类型: i64, f64, bool, void -- [x] 算术: + - * / % -- [x] 比较: == != < > <= >= -- [x] 逻辑: && || ! -- [x] let 不可变变量, 类型标注 + 类型推断 -- [x] 控制流: if/else (含 else if), while, return -- [x] 函数定义与调用, 递归 -- [x] 内置函数: print_i64, print_f64, print_bool -- [x] 注释: // 行注释, /* */ 块注释 -- [x] 错误报告: 词法/语法即时终止, 语义错误批量输出 - -### 2.2 v0.1+ 功能 (前两次迭代) - -- [x] let mut 可变变量 + 赋值语句 -- [x] 可变性检查 — 不可变变量赋值报编译错误 -- [x] 字符串类型 str + 双引号字面量 -- [x] print_str 内置函数 -- [x] str+str 运行时拼接 -- [x] 复合赋值 += -= *= /= (去糖) -- [x] LLVM 目标初始化解耦 (target.h/c) -- [x] codegen malloc -> arena 统一 - -### 2.3 本次迭代新增 (v0.3 — 无变更增量) - -- [x] **for 循环 + range** — `for i in start..end { ... }`,parser 去糖为 `let mut i = start; while i < end { ...; i = i + 1; }` -- [x] **浮点数 lexer 修复** — `peek_next` 防 `..` 与 `.` 冲突 -- [x] **sema 测试补全** — +5 测试: let mut assign OK, immutable assign error, str type, str concat -- [x] **codegen 测试补全** — +1 测试: while 循环 -- [x] **2 个新集成测试**: `10_for_range.l`, `11_for_step2.l` -- [x] LLVM 22 mem2reg 不可用注释 (防止后续困惑) - ---- - -## 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 作为表达式 | -| 模式匹配 | ❌ | P1 优先级 | -| 代数数据类型 | ❌ | 需泛型 | -| 所有权 / 借用 | ❌ | 远期 | - ---- - -## 4. 测试覆盖分析 - -### 4.1 单元测试 - -| 测试文件 | 函数数 | 断言数 | 覆盖范围 | 本次变化 | -|---------|--------|--------|---------|---------| -| test_lexer.c | 3 | 14 | token 识别, 关键字, 操作符, 注释 | — | -| test_parser.c | 5 | 15 | 算术, let, if, while, 函数 | — | -| test_sema.c | 7 | 21 | 类型错误, 未定义变量, let mut, immutable assign error, str, str concat | **+5 函数, +12 断言** | -| test_codegen.c | 4 | 9 | 简单函数, if/else, 二元运算, while | **+1 函数, +2 断言** | -| **合计** | **19** | **59** | | **+6 函数, +14 断言** | - -### 4.2 集成测试 (11 程序) - -| 文件 | 功能 | 状态 | -|------|------|------| -| 01_arithmetic.l | 算术运算 | ✅ | -| 02_if_else.l | if/else 控制流 | ✅ | -| 03_recurse.l | 递归函数 | ✅ | -| 04_fib_recursive.l | 斐波那契 | ✅ | -| 05_float.l | 浮点数 | ✅ | -| 06_mut_while.l | let mut + while | ✅ | -| 07_hello_str.l | 字符串输出 | ✅ | -| 08_str_concat.l | 字符串拼接 | ✅ | -| 09_compound_assign.l | 复合赋值 | ✅ | -| 10_for_range.l | for range 循环 | ✅ 新增 | -| 11_for_step2.l | for range (变量边界) | ✅ 新增 | - -### 4.3 测试缺口 - -| 缺口 | 严重度 | 说明 | -|------|--------|------| -| 复合赋值无独立 desugar 测试 | 低 | 仅通过集成测试间接覆盖 | -| for 循环无独立 desugar 测试 | 低 | 同上,集成测试覆盖 | -| codegen 缺 call/str/compound/for 路径 | 中 | 4 测试仅覆盖基础路径 | -| parser 缺 for 错误恢复测试 | 低 | 缺少 for/in/.. 错误提示验证 | - ---- - -## 5. 技术债务与风险 - -| # | 问题 | 状态 | 严重度 | 说明 | -|---|------|------|--------|------| -| 1 | str concat malloc 内存泄漏 | **存留** | 中 | x + y 每次 malloc 无 free,长运行程序会泄漏 | -| 2 | 复合赋值无独立 desugar 测试 | **存留** | 低 | 集成测试间接覆盖 | -| 3 | sema 层缺 str/let mut/assign 测试 | **✅ 已解决** | — | 本次新增 5 个 sema 测试 | -| 4 | codegen 测试覆盖率低 | **部分缓解** | 中 | 新增 while 测试,但 call/str/compound/for 仍无覆盖 | -| 5 | system("gcc ...") 平台绑定 | **存留** | 低 | Windows/MinGW 正常工作 | -| 6 | LLVM 22 无 mem2reg C API | **已记录** | 低 | codegen.c 注释说明需用 opt 工具 | -| 7 | 错误类型分散 (ErrorInfo + ErrorList) | **存留** | 低 | 不影响功能 | -| 8 | CHANGELOG 未更新 v0.3 | **新增** | 低 | 仍标 v0.2.0 | - ---- - -## 6. 推荐开发路线图 - -### v0.4 目标 (下一迭代) - -| 优先级 | 功能 | 预计工时 | 依赖/备注 | -|--------|------|---------|----------| -| **P0** | **结构体 struct** | 2-3 天 | 解锁 GEP 和复合类型,全流水线 | -| P1 | parser 测试补全 (for 错误恢复) | 0.5 天 | 回归保护 | -| P1 | codegen 测试扩展 (for/call/str) | 0.5 天 | 覆盖率补偿 | -| P1 | 更新 CHANGELOG v0.3 | 0.1 天 | 记录 for 循环 | -| P1 | str concat arena 化 (修复技术债 #1) | 0.5 天 | 替换 malloc 为 arena 分配 | - -### v0.5 目标 - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| 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.2, 72a971e) | 本次 (v0.3, 382cd08) | 变化 | -|------|--------------------------|---------------------|------| -| 源文件数 | 22 | 23 | — | -| 实现代码 (.c) | 1,636 | 1,688 | +52 | -| 头文件 (.h) | 285 | 251 | -34 | -| 测试代码 | 242 | 330 | +88 | -| Token 类型 | 34 | 37 | +3 (FOR/IN/DOT_DOT) | -| AST 节点类型 | 15 | 15 | 无变化 | -| 类型系统 | 5 种 | 5 种 | 无变化 | -| 内置函数 | 4 (print_*) | 4 | 无变化 | -| C 运行时依赖 | printf, malloc, strlen, memcpy | 无变化 | — | -| 集成测试 | 9 程序 | 11 程序 | +2 | -| 单元测试函数 | 14 | 19 | +5 | -| 单元测试断言 | 45 | 59 | +14 | -| 上次 P0 完成度 | 2/4 | 3/4 (+for) | 75% | -| 上次 P0 遗留 | for, struct | struct | — | - ---- - -*本报告由 Codex 自动生成。自上次报告 (2026-06-05 07:03) 后 HEAD 保持不变 (382cd08),无代码变更。自上次报告 (2026-06-05 03:03) 后代码有显著变化 (2 commits, +443/-6)。P0 #3 (for 循环 + range) 完成, P0 #4 (struct) 为下一迭代唯一 P0 目标。测试覆盖从 14 函数/45 断言升至 19 函数/59 断言。* diff --git a/docs/analysis/architecture-analysis-report-2026-06-05-1150.md b/docs/analysis/architecture-analysis-report-2026-06-05-1150.md deleted file mode 100644 index 44666de..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-05-1150.md +++ /dev/null @@ -1,306 +0,0 @@ -# L Language 架构分析报告 (v0.3 — 增量分析, 无代码变更) - -> 日期: 2026-06-05 11:50 | 自动生成 | **自上次报告后无代码变更** -> 基线: [architecture-analysis-report-2026-06-05-0829.md](D:/Code/doing_exercises/programs/L%20Language/docs/analysis/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](/D:/Code/doing_exercises/programs/L%20Language/src/lexer/token.h:7) | 关键字/类型/字面量/标识符/运算符/分隔符/EOF/ERROR | -| `Token` | [token.h](/D:/Code/doing_exercises/programs/L%20Language/src/lexer/token.h:30) | kind, start, length, line, col | -| `AstKind` (15 枚举值) | [ast.h](/D:/Code/doing_exercises/programs/L%20Language/src/ast/ast.h:8) | PROGRAM → IDENT_EXPR | -| `AstNode` (union 实现) | [ast.h](/D:/Code/doing_exercises/programs/L%20Language/src/ast/ast.h:38) | kind, type, line, col, as.{12 sub-structs} | -| `TypeKind` (7 枚举值) | [l_lang.h](/D:/Code/doing_exercises/programs/L%20Language/include/l_lang.h:10) | I64, F64, BOOL, STR, VOID, UNKNOWN, ERROR | -| `Scope` (作用域链) | [symbol.h](/D:/Code/doing_exercises/programs/L%20Language/src/sema/symbol.h:1) | symbols[], count, parent | -| `Symbol` (符号条目) | [symbol.h](/D:/Code/doing_exercises/programs/L%20Language/src/sema/symbol.h:1) | 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 基线功能 (全部完成) - -- [x] 基本类型: `i64`, `f64`, `bool`, `void` -- [x] 算术: `+` `-` `*` `/` `%` -- [x] 比较: `==` `!=` `<` `>` `<=` `>=` -- [x] 逻辑: `&&` `||` `!` -- [x] `let` 不可变变量 + 类型推断 -- [x] 控制流: `if`/`else` (含 `else if`), `while`, `return` -- [x] 函数定义与调用, 递归 (含斐波那契) -- [x] 内置函数: `print_i64`, `print_f64`, `print_bool` -- [x] 注释: `//` 行注释, `/* */` 块注释 -- [x] 错误报告: 词法/语法即时终止, 语义错误批量输出 - -### 2.2 v0.2 新增 (全部完成) - -- [x] `let mut` 可变变量 + 赋值语句 (`x = expr`) -- [x] 可变性检查 — 不可变变量赋值报编译错误 -- [x] 字符串类型 `str` + 双引号字面量 -- [x] `print_str` 内置函数 -- [x] `str + str` 运行时拼接 (malloc + strlen + memcpy) -- [x] 复合赋值 `+=` `-=` `*=` `/=` (parser 去糖) -- [x] LLVM 目标初始化解耦 → `target.h/c` 独立模块 -- [x] codegen malloc → arena 统一分配 - -### 2.3 v0.3 新增 (全部完成) - -- [x] `for` 循环 + range — `for i in start..end { ... }` (parser 去糖为 `let mut i = start; while i < end { ...; i = i + 1; }`) -- [x] `..` range 运算符 (TOK_DOT_DOT) -- [x] 浮点数 lexer 修复 — `peek_next` 防 `..` 与 `.` 冲突 -- [x] sema 测试补全: +5 测试 (let mut assign OK, immutable assign error, str type, str concat) -- [x] codegen 测试补全: +1 测试 (while 循环) -- [x] 集成测试: `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 文档。* \ No newline at end of file diff --git a/docs/analysis/architecture-analysis-report-2026-06-05-1152.md b/docs/analysis/architecture-analysis-report-2026-06-05-1152.md deleted file mode 100644 index 4bc363f..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-05-1152.md +++ /dev/null @@ -1,348 +0,0 @@ -# L Language 架构分析报告 (v0.3 — 无代码变更) - -> 日期: 2026-06-05 11:52 | 自动生成 | 自上次源代码基线无变更 -> 上次代码分析基线: `382cd08` (2026-06-05 08:29 报告) -> 当前 HEAD: `620cec4` (CHANGELOG 更新 v0.3.0) - ---- - -## 变更摘要 (自上次代码基线) - -**源代码无变更。** 自 `382cd08` 以来,仅有 2 个纯文档提交 (`620cec4`): - -| 文件 | 变更 | 行数 | -|------|------|------| -| CHANGELOG.md | 新增 v0.3.0 条目 (for 循环 + 测试补全 + Known Issues) | +14 | -| docs/analysis/architecture-analysis-report-2026-06-05-0703.md | 上一轮自动化分析报告提交 | +288 | - -**结论**: 编译器源代码、测试代码、构建系统均无变化。本次运行与 08:29 报告相比,唯一差异是 CHANGELOG v0.3.0 已正式提交(上次报告列为技术债 #8「CHANGELOG 未更新 v0.3」)。 - ---- - -## 1. 当前架构全景 - -### 1.1 编译流水线 - -``` -源码(.l) → Lexer(词法) → Parser(语法) → Sema(语义) → Codegen(LLVM IR) → Target(obj) → GCC 链接(.exe) - Token[] AstNode* 类型标注 LLVMModuleRef .o 文件 -``` - -全流水线 6 个阶段,**无架构变化**。 - -### 1.2 模块清单与指标 - -| 模块 | 文件 | 行数 | 关键职责 | -|------|------|------|---------| -| include/ | l_lang.h | 34 | TypeKind 枚举 (7 种), 向前声明, arena_alloc_impl | -| util/ | arena.c(39) + .h(13) | 52 | 8MB bump allocator, strdup | -| lexer/ | lexer.c(137) token.c(45) + .h(40) | 222 | 手写状态机, **37** Token 类型, peek_next | -| ast/ | ast.c(107) ast.h(93) | 200 | **15** 种节点类型, 工厂函数 | -| parser/ | parser.c(390) parser.h(10) | 400 | Pratt 表达式解析 + 递归下降 + for/复合赋值去糖 | -| sema/ | sema.c(294) symbol.c(46) + .h(32) | 372 | 类型推断, 作用域链 (Scope), 可变性检查 | -| codegen/ | codegen.c(421) target.c(30) + .h(15) | 466 | LLVM IR 生成, 4 内置函数, 目标平台初始化 | -| driver/ | main.c(133) error.c(46) + .h(18) | 197 | 流水线串联, CLI (`l_lang [-o ] [--emit-ir]`), 错误报告 | -| test/ | test_*.c(4 文件) + test_utils.h(23) | 353 | 19 测试函数, 59 断言, 11 集成程序 | - -**总计: 23 源文件, 1,688 行实现代码 + 308 行头文件 + 330 行测试 = 2,326 行** - -### 1.3 关键架构决策 (v0.2–v0.3 沉淀) - -| 决策 | 描述 | 技术理由 | -|------|------|---------| -| **去糖策略** | 复合赋值 (`+=` 等) 和 for 循环在 parser 层降级为已有原语 | 零 codegen/sema 入侵, 零新 AST 节点, 降低维护成本 | -| **for 去糖路径** | `for i in 0..5 {body}` → `let mut i=0; while i<5 {body; i=i+1;}` | 步长固定为 1, 如需自定义步长需扩展语法 | -| **Arena 统一分配** | 编译器内部所有动态内存走 arena bump allocator (8MB) | 零 free 调用, 编译器结束时一次性释放 | -| **LLVM-C API 19.x** | 绑定 LLVM 19.x 的 C API | LLVM 22 移除 mem2reg C API (已记录注释) | -| **GCC 链接** | `system("gcc ...")` 链接目标文件 | 简单但平台绑定 (Windows/MinGW) | -| **Pratt 表达式解析** | 9 级优先级, 零左递归问题 | 比纯递归下降更优雅处理表达式 | - -### 1.4 核心数据结构 - -**Token (37 种)** - -``` -关键字: fn let mut if else while for in return -类型: i64 f64 bool str void -字面量: 整数 浮点数 true false 字符串 -运算符: + - * / % == != < > <= >= && || ! -> .. += -= *= /= -分隔符: ( ) { } , : ; = -特殊: EOF ERROR -``` - -**AST 节点 (15 种)** - -``` -Program Function Parameter Block LetStmt AssignStmt IfStmt WhileStmt -ReturnStmt ExprStmt BinaryExpr UnaryExpr CallExpr LiteralExpr IdentExpr -``` - -**类型系统 (7 种)** - -``` -TypeKind: I64 F64 BOOL STR VOID UNKNOWN ERROR - -转换规则: - 隐式: i64 → f64 (算术混合) - 显式: 函数参数/返回值必须标注 - 不可转换: str ↔ 数值, bool ↔ 数值 -``` - -**符号表** - -``` -Scope (链表栈): 全局 → 函数 → 块 - - SymbolKind: VARIABLE | PARAMETER | FUNCTION - - 变量属性: is_mut (可变性) - - 函数属性: return_type + param_types[] + param_count - - 作用域退出时释放 (arena 生命周期管理) -``` - ---- - -## 2. 功能清单与成熟度 - -### 2.1 v0.1 基线功能 (全部完成) - -- [x] 基本类型: i64, f64, bool, void -- [x] 算术: + - * / % -- [x] 比较: == != < > <= >= -- [x] 逻辑: && || ! -- [x] let 不可变变量, 类型标注 + 类型推断 -- [x] 控制流: if/else (含 else if), while, return -- [x] 函数定义与调用, 递归 -- [x] 内置函数: print_i64, print_f64, print_bool -- [x] 注释: // 行注释, /* */ 块注释 -- [x] 错误报告: 词法/语法即时终止, 语义错误批量输出 - -### 2.2 v0.2 新增功能 (全部完成) - -- [x] let mut 可变变量 + 赋值语句 -- [x] 可变性检查 — 不可变变量赋值报编译错误 -- [x] 字符串类型 str + 双引号字面量 -- [x] print_str 内置函数 -- [x] str+str 运行时拼接 (malloc + strlen + memcpy) -- [x] 复合赋值 += -= *= /= (parser 去糖) -- [x] LLVM 目标初始化解耦 (target.h/c) -- [x] codegen malloc → arena 统一 - -### 2.3 v0.3 新增功能 (全部完成) - -- [x] **for 循环 + range** — `for i in start..end { ... }`,parser 去糖 -- [x] **浮点数 lexer 修复** — `peek_next` 防 `..` 与 `.` 冲突 -- [x] **sema 测试补全** — +5 测试 (let mut assign, immutable error, str type, str concat) -- [x] **codegen 测试补全** — +1 测试 (while 循环) -- [x] **2 个新集成测试**: `10_for_range.l` (0..5), `11_for_step2.l` (变量边界) -- [x] LLVM 22 mem2reg 不可用注释 -- [x] CHANGELOG v0.3.0 提交 (本次运行时已就绪) - ---- - -## 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 | **待实施** | - -**P0 完成度: 3/4 (75%)**。struct 是解锁复合类型的最后一块 P0 拼图。 - -### 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) | ✅ 已实现 | 编译期检查, 可变性追踪 | -| 复合赋值 | ✅ 已实现 | parser desugar 模式 | -| for + range | ✅ 已实现 | desugar 为 while | -| str 拼接 | ✅ 已实现 | 运行时 malloc | -| 表达式 vs 语句 | ❌ | if/match/block 作为表达式 (目前只支持语句) | -| 模式匹配 | ❌ | P1 优先级 | -| 代数数据类型 | ❌ | 需泛型 | -| 所有权 / 借用 | ❌ | 远期 | - ---- - -## 4. 测试覆盖分析 - -### 4.1 单元测试 - -| 测试文件 | 测试函数 | 断言数 | 覆盖范围 | -|---------|----------|--------|---------| -| test_lexer.c | 3 | 14 | token 识别, 关键字, 操作符, 注释 | -| test_parser.c | 5 | 15 | 算术, let, if, while, 函数 | -| test_sema.c | 7 | 21 | 类型错误, 未定义变量, let mut, immutable error, str type, str concat | -| test_codegen.c | 4 | 9 | 简单函数, if/else, 二元运算, while | -| **合计** | **19** | **59** | | - -### 4.2 集成测试 (11 程序) - -| 文件 | 功能 | 版本 | -|------|------|------| -| 01_arithmetic.l | 算术运算 | v0.1 | -| 02_if_else.l | if/else 控制流 | v0.1 | -| 03_recurse.l | 递归函数 | v0.1 | -| 04_fib_recursive.l | 斐波那契 (递归) | v0.1 | -| 05_float.l | 浮点数 | v0.1 | -| 06_mut_while.l | let mut + while | v0.2 | -| 07_hello_str.l | 字符串输出 | v0.2 | -| 08_str_concat.l | 字符串拼接 | v0.2 | -| 09_compound_assign.l | 复合赋值 | v0.2 | -| 10_for_range.l | for range 循环 | v0.3 | -| 11_for_step2.l | for range (变量边界) | v0.3 | - -### 4.3 测试缺口 - -| 缺口 | 严重度 | 说明 | -|------|--------|------| -| 复合赋值无独立 desugar 测试 | 低 | 仅通过 `09_compound_assign.l` 间接覆盖 | -| for 循环无独立 desugar 测试 | 低 | 仅通过 `10_for_range.l` / `11_for_step2.l` 间接覆盖 | -| codegen 缺 call/str/compound/for 路径 | 中 | 4 测试仅覆盖基础路径: simple, if/else, binary, while | -| parser 缺 for 错误恢复测试 | 低 | 缺少 for/in/.. 错误提示验证 | -| 无 LLVM IR 输出一致性测试 | 低 | 无法检测 LLVM IR 生成回归 | - ---- - -## 5. 技术债务与风险 - -| # | 问题 | 状态 | 严重度 | 说明 | -|---|------|------|--------|------| -| 1 | str concat malloc 内存泄漏 | **存留** | 中 | x + y 每次 malloc 无 free,编译后程序运行会泄漏 (编译器自身不受影响) | -| 2 | 复合赋值无独立 desugar 测试 | **存留** | 低 | 集成测试间接覆盖 | -| 3 | codegen 测试覆盖率低 (4/9 路径) | **存留** | 中 | call/str/compound/for/return 路径无单元测试 | -| 4 | `system("gcc ...")` 平台绑定 | **存留** | 低 | Windows/MinGW 正常,Linux/Unix 需 `gcc`/`cc` 替换 | -| 5 | LLVM 22 无 mem2reg C API | **已记录** | 低 | codegen.c 注释说明需用 `opt` 工具 | -| 6 | 错误类型分散 (ErrorInfo + ErrorList) | **存留** | 低 | 不影响功能,但 API 不统一 | -| 7 | CHANGELOG 未更新 v0.3 | **✅ 已解决** | — | `620cec4` 提交了 v0.3.0 条目 | -| 8 | parser.c 函数 `parse_function` 过长 | **存留** | 低 | 约 60 行,可拆分为多个子函数 | -| 9 | 无 fuzzing / 边界输入测试 | **新增** | 低 | 超大源文件、超长标识符、深层嵌套等未覆盖 | - -### 风险矩阵 - -| 风险 | 概率 | 影响 | 缓解 | -|------|------|------|------| -| LLVM API 版本升级 break | 中 | 高 | 当前锁定 19.x,文档记录不兼容点 | -| GCC 链接在非 MinGW 环境失败 | 中 | 中 | 可接受链接器参数或使用 LLVM lld | -| Arena 内存耗尽 (8MB) | 极低 | 中 | 巨型程序才触发,编译器中止即可 | -| str 泄漏导致大程序 OOM | 低 | 中 | 短期替代方案: arena 化 str 拼接 | - ---- - -## 6. 推荐开发路线图 - -### v0.4 目标 (下一迭代) - -| 优先级 | 功能 | 预计工时 | 依赖/备注 | -|--------|------|---------|----------| -| **P0** | **结构体 struct** | 2–3 天 | 解锁 GEP 和复合类型,全流水线 | -| P1 | str concat arena 化 (修复技术债 #1) | 0.5 天 | 替换 malloc 为 arena 分配 | -| P1 | codegen 测试扩展 (call/str/for) | 0.5 天 | 覆盖率补偿 | -| P1 | parser 测试补全 (for 错误恢复) | 0.5 天 | 回归保护 | - -### v0.5 目标 - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| 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.2 (72a971e) | 较 v0.3 基线 (382cd08) | -|------|-----|-------------------|----------------------| -| 源文件数 (.c) | 12 | — | 无变化 | -| 头文件数 (.h) | 12 | — | 无变化 | -| 实现代码 | 1,688 行 | +52 | 无变化 | -| 头文件 | 308 行 | +23 | 无变化 | -| 测试代码 | 330 行 | +88 | 无变化 | -| 总代码量 | 2,326 行 | +163 | 无变化 | -| Token 类型 | 37 | +3 (FOR/IN/DOT_DOT) | 无变化 | -| AST 节点类型 | 15 | +1 (ASSIGN_STMT) | 无变化 | -| TypeKind | 7 | +2 (STR, ERROR) | 无变化 | -| 内置函数 | 4 (print_i64/f64/bool/str) | +1 (print_str) | 无变化 | -| C 运行时依赖 | printf, malloc, strlen, memcpy | +malloc/strlen/memcpy | 无变化 | -| 单元测试函数 | 19 | +5 | 无变化 | -| 单元测试断言 | 59 | +14 | 无变化 | -| 集成测试程序 | 11 | +2 (for_range, for_step2) | 无变化 | -| P0 完成度 | 3/4 (75%) | +for | 无变化 | -| P0 遗留 | struct | — | 无变化 | -| 编译产物 | 6 个 .exe | — | 无变化 | -| Git 提交数 | 11 | +2 | +1 (CHANGELOG) | - ---- - -## 8. 代码质量评估 - -### 8.1 模块内聚度 - -| 模块 | 内聚度 | 评价 | -|------|--------|------| -| lexer | 高 | 纯函数接口,状态机集中在单文件,token 定义与值提取分离 | -| parser | 高 | 递归下降 + Pratt 组合清晰,去糖逻辑局部化 | -| ast | 高 | 工厂函数模式统一,union 节点设计节省内存 | -| sema | 高 | 遍历器模式,analyze_node/analyze_expr 双入口,职责明确 | -| codegen | 中高 | `codegen_stmt` 单一大函数处理所有节点,可拆分但暂不紧急 | -| driver | 中 | main.c 串联流水线,error.c 独立,接口清晰 | -| util | 高 | 单一职责 (arena 分配器),零外部依赖 | - -### 8.2 代码风格一致性 - -- 蛇形命名 (snake_case) 贯穿全部源文件 -- 头文件守卫 (`#ifndef X_H` / `#define X_H` / `#endif`) 统一 -- 工厂函数模式 (`ast_make_*`) 跨 AST 模块一致 -- 错误处理模式: `ErrorInfo*` (即时错误) + `ErrorList*` (批量错误) 两类 - -### 8.3 编译警告 - -未在本次运行中编译,但从代码结构推断: -- 全局变量 `_tests_run` / `_tests_failed` 在 `test_utils.h` 中 `static` 声明 (每个翻译单元独立副本, 跨文件统计不准确) -- `Arena*` 通过 `void*` 跨模块传递 (`arena_alloc_impl(void* alloc, ...)`),丢失类型安全, 但避免了模块间循环依赖 - ---- - -*本报告由 Codex 自动生成于 2026-06-05 11:52。自上次代码基线 `382cd08` 后无源代码变更。当前 HEAD `620cec4` 仅增加 CHANGELOG.md v0.3.0 条目 (14 行) + 上一轮分析报告 (288 行)。编译器源码、测试、构建系统均不变。P0 struct 仍为唯一待实施的 P0 功能。* \ No newline at end of file diff --git a/docs/analysis/architecture-analysis-report-2026-06-05-1308.md b/docs/analysis/architecture-analysis-report-2026-06-05-1308.md deleted file mode 100644 index 0b5478f..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-05-1308.md +++ /dev/null @@ -1,427 +0,0 @@ -# L Language 架构分析报告 — 结构体 + 自动内存管理 (v0.4) - -> 日期: 2026-06-05 13:08 | 自动生成 | **有源代码变更** -> 上次代码分析基线: `382cd08` (2026-06-05 11:52 报告) -> 当前 HEAD: `1d4fb27` feat: 自动内存管理 — 作用域级 RAII for str -> -> 新增提交 (自上次源代码基线 `382cd08`): -> - `b390d39` feat: 结构体 struct — 最后一项 P0 功能 -> - `1d4fb27` feat: 自动内存管理 — 作用域级 RAII for str - ---- - -## 变更摘要 (自上次代码基线) - -**19 个文件变更, +1882 / -54 行。** 两项重大功能落地: - -| 变更类别 | 详情 | 影响范围 | -|---------|------|---------| -| **struct 结构体** | 全流水线: lexer → parser → sema → codegen | 12 源文件, 2 集成测试 | -| **RAII 自动内存管理** | 作用域级 str free: `cleanup_list` + `malloc`/`free` 配对 | codegen.c (+~120 行) | -| **基础设施扩展** | 3 新 AST 节点, 2 新 Token, 1 新 SymbolKind, 1 新 TypeKind | ast/token/symbol/l_lang.h | -| **测试更新** | 2 新集成程序 + test_codegen.c API 兼容修复 | test/ | - ---- - -## 1. 当前架构全景 - -### 1.1 编译流水线 - -``` -源码(.l) → Lexer(词法) → Parser(语法) → Sema(语义) → Codegen(LLVM IR) → Target(obj) → GCC 链接(.exe) - 39 Token 18 AST 节点 类型标注 LLVMModuleRef .o 文件 - (含 struct) -``` - -**无架构变化。** 流水线仍为 6 阶段, struct 和 RAII 均在现有模块内实现。 - -### 1.2 模块清单与指标 - -| 模块 | 文件 | 行数 | Δ | 关键职责 | -|------|------|------|---|---------| -| include/ | l_lang.h | 36 | +2 | TypeKind 枚举 (8 种), 新增 TYPE_STRUCT | -| util/ | arena.c(39) + .h(13) | 52 | 0 | 8MB bump allocator, strdup | -| lexer/ | lexer.c(139) token.c(47) + .h(52) | 238 | +4 | 手写状态机, **39** Token 类型 (+2: TOK_STRUCT, TOK_DOT) | -| ast/ | ast.c(143) ast.h(111) | 254 | +54 | **18** 种节点类型 (+3: STRUCT_DECL, STRUCT_INIT, FIELD_ACCESS) | -| parser/ | parser.c(514) parser.h(10) | 524 | +124 | 递归下降 + Pratt, 新增 struct 声明/初始化/字段访问解析 | -| sema/ | sema.c(442) symbol.c(92) + .h(56) | 590 | +218 | 类型推断, 4 种 SymbolKind (+SYM_STRUCT), 结构体字段类型检查 | -| codegen/ | codegen.c(588) target.c(30) + .h(27) | 645 | +179 | LLVM 命名结构体, GEP/extractvalue, RAII cleanup 机制 | -| driver/ | main.c(141) error.c(46) + .h(18) | 205 | 0 | 流水线串联, 结构体解析结果自动流入 codegen | -| test/ | test_*.c(4 文件) + test_utils.h(23) | 361 | +31 | 19 测试函数, **61 断言**, **13** 集成程序 (+2) | - -| 汇总指标 | 上次 (382cd08) | 当前 (1d4fb27) | Δ | -|---------|---------------|---------------|----| -| 实现代码 (.c) | 1,688 行 | 2,221 行 | +533 | -| 头文件 (.h) | 308 行 | 323 行 | +15 | -| 测试代码 | 330 行 | 361 行 | +31 | -| **总代码量** | **2,326 行** | **2,905 行** | **+579** | -| Token 类型 | 37 | **39** | +2 | -| AST 节点类型 | 15 | **18** | +3 | -| TypeKind | 7 | **8** | +1 | -| SymbolKind | 3 | **4** | +1 | -| 内置函数 | 4 | 4 | 0 | -| 单元测试函数 | 19 | 19 | 0 | -| 单元测试断言 | 59 | **61** | +2 | -| 集成测试程序 | 11 | **13** | +2 | -| P0 完成度 | 3/4 (75%) | **4/4 (100%)** | ✅ | -| Git 提交数 | 11 | 13 | +2 | - -### 1.3 关键架构决策 (v0.4 新增) - -| 决策 | 描述 | 技术理由 | -|------|------|---------| -| **LLVM 命名结构体** | 先用 `LLVMStructCreateNamed` 创建占位符, 遍历完所有 struct 后再 `LLVMStructSetBody` | 支持结构体间互相引用 (如 `Rect` 含 `Point`) | -| **结构体值语义** | 字段访问通过 `extractvalue`(寄存器内) 而非 `GEP`(指针), init 用 alloca+store+load | 接近 Rust 的 move 语义雏形, 避免指针间接 | -| **RAII cleanup_list** | `CgCtx` 内维护固定大小 64 槽数组, `cleanup_add`/`cleanup_emit` 配对使用 | 零 malloc overhead, 作用域退出时 FIFO 释放 | -| **cleanup 触发范围** | BINARY_EXPR(拼接)、STRUCT_INIT、CALL_EXPR 产生的 str; struct 变量整体追踪 | 保守策略: 宁可泄漏简单 str 字面量也不误 free 栈数据 | -| **struct init 前瞻消歧义** | `Name { IDENT : ...` 模式判断 struct init vs block: 用 2-token lookahead | 避免 `{` 的 block/struct-init 二义性 | - ---- - -## 2. struct 结构体功能详解 - -### 2.1 全流水线实现 - -``` -源码: struct Point { x: i64, y: i64 } - │ - ▼ Lexer: TOK_STRUCT TOK_IDENT("Point") TOK_LBRACE TOK_IDENT("x") TOK_COLON TOK_I64 ... - │ - ▼ Parser: parse_struct_decl() → AST_STRUCT_DECL { name="Point", fields=[x:i64, y:i64] } - │ parse_struct_init() → Point { x: 10, y: 20 } - │ parse_expr_prec() → p.x (PREC_POSTFIX, TOK_DOT) - │ - ▼ Sema: scope_insert_struct() → SYM_STRUCT, 字段名校验, 类型匹配 - │ AST_FIELD_ACCESS → field_index 解析 + struct_name 传播 - │ - ▼ Codegen: - Phase 0: LLVMStructCreateNamed("Point") → forward decl - LLVMStructSetBody([i64, i64]) → body definition - Init: alloca(Point) + GEP(0,i) + store + load → struct value - Access: extractvalue(struct_val, field_idx) → 字段值 -``` - -### 2.2 新增 AST 节点 - -| AST 节点 | 用途 | 关键字段 | -|----------|------|---------| -| `AST_STRUCT_DECL` | 结构体声明 | `name`, `fields[]` (AST_PARAMETER 复用), `field_count` | -| `AST_STRUCT_INIT` | 结构体初始化表达式 | `type_name`, `field_names[]`, `field_values[]`, `field_count` | -| `AST_FIELD_ACCESS` | 点号字段访问 (p.x) | `object`, `field`, `field_index` (sema 填充) | - -### 2.3 类型传播链 - -`TypeInfo.struct_name` 字段在整个类型系统中传播: -- lexer: 将 `TOK_IDENT` 在类型位置识别为 struct 类型名 -- parser: `let p: Point = ...` 中 `Point` 解析为 `TYPE_STRUCT` + struct_type_name -- sema: 赋值/表达式推断时传播 `struct_name`; 字段访问时从 `struct_field_struct_names` 获取嵌套 struct 名 -- codegen: 通过 `find_struct_type()` 获取 `LLVMTypeRef` - -### 2.4 集成测试覆盖 - -| 程序 | 覆盖场景 | -|------|---------| -| `12_struct.l` | 基础 struct: 声明 Point, init, 字段访问 p.x/p.y, print_i64 | -| `13_struct_nested.l` | 嵌套 struct: Rect { top_left: Point, bot_right: Point }, 链式访问 r.top_left.x | - ---- - -## 3. RAII 自动内存管理详解 - -### 3.1 问题背景 - -v0.2 引入 str+str 拼接时使用 `malloc`, 导致编译后程序产生内存泄漏 (技术债 #1)。本次实现作用域级的自动 `free`, 不引入 GC, 不依赖 LLVM 优化 pass。 - -### 3.2 实现机制 - -``` -CgCtx { - cleanup_list[64]; // str 变量的 alloca 指针 - cleanup_count; // 当前追踪数量 - free_fn; // 声明的 C 标准库 free() -} - -cleanup_add(ctx, alloca): - cleanup_list[count++] = alloca - -cleanup_emit(ctx, from_mark): - for j in from_mark..count: - val = load(cleanup_list[j]) // 加载 str 指针 - call free(val) - count = from_mark // 收缩 -``` - -### 3.3 触发点 - -| 位置 | 触发逻辑 | -|------|---------| -| `LET_STMT` | 当 init 表达式类型为 `TYPE_STR` 且节点为 BINARY_EXPR/STRUCT_INIT/CALL_EXPR, 或类型为 `TYPE_STRUCT` (可能含 str 字段) → `cleanup_add` | -| `BLOCK` 出口 | `cleanup_emit(block_mark)` — 块作用域内所有 str 变量 | -| `RETURN_STMT` | `cleanup_emit(0)` *先于* `LLVMBuildRet` — 函数退出前释放所有 | -| 隐式函数结尾 | `cleanup_emit(0)` — 无 return 的函数自动尾部释放 | - -### 3.4 设计权衡 - -| 方面 | 决策 | 理由 | -|------|------|------| -| 槽位上限 | 固定 64 | 正常函数内不会声明超过 64 个 str/struct; 溢出静默忽略 | -| 未追踪字面量 | str 字面量 (如 `"hello"`) 不追踪 | 字面量存储在 .rodata, free 会导致段错误 | -| struct 整体追踪 | struct 一律追踪 (非仅 str 字段) | 简单安全; 未来可按字段粒度优化 | -| `free` 而非 `GC_free` | 直接调用 libc free() | 无 GC 依赖, 链接到 C 运行时 | - ---- - -## 4. 功能清单与成熟度 - -### 4.1 v0.1–v0.3 基线功能 (全部完成) - -- [x] 基本类型: i64, f64, bool, void, str -- [x] 算术/比较/逻辑运算 -- [x] let/let mut 变量, 类型推断 + 可变性检查 -- [x] 控制流: if/else, while, for+range, return -- [x] 函数定义与调用, 递归 -- [x] 内置函数: print_i64/f64/bool/str -- [x] 复合赋值 += -= *= /= (parser 去糖) -- [x] str+str 运行时拼接 -- [x] 注释: // 行注释, /* */ 块注释 - -### 4.2 v0.4 新增功能 (本次实现) - -- [x] **struct 结构体声明** — `struct Name { field: Type, ... }`, 支持嵌套 struct 字段 -- [x] **struct 初始化** — `Point { x: 10, y: 20 }`, 字段名+类型校验, 2-token lookahead 消歧义 -- [x] **字段访问** — `p.x` / `r.top_left.x` 链式访问, PREC_POSTFIX 优先级 -- [x] **struct 类型标注** — `let p: Point = ...`, 类型名传播全流水线 -- [x] **RAII 自动内存管理** — 作用域级 str/struct free, 3 个释放点 (block/return/隐式结尾) -- [x] **LLVM 命名结构体互相引用** — forward decl → body 二阶段创建 - -### 4.3 当前已知限制 (struct 相关) - -| 限制 | 说明 | 严重度 | -|------|------|--------| -| struct 不能作为函数参数 | parser 函数参数解析未处理 struct 类型名 (`token_to_type` 无 Ident 分支) | 中 | -| struct 不能作为函数返回值 | 同上, 返回类型标注仅支持 `i64`/`f64`/`bool`/`void`/`str` | 中 | -| 无 struct 方法 (impl) | struct 只有数据, 无关联函数 | 低 | -| 空 struct (零字段) 未测试 | 边界情况 | 低 | -| struct 字段无默认值 | 不支持 `Point { x: 10, ..Default::default() }` | 低 | - ---- - -## 5. 与 Rust 对标: 缺失功能清单及优先级 - -### P0: 短期 (4/4 完成 ✅) - -| # | 功能 | Rust 启发 | 状态 | -|---|------|----------|------| -| 1 | 复合赋值 += -= *= /= | 复合赋值运算符 | ✅ v0.2 | -| 2 | str+str 运行时拼接 | — | ✅ v0.2 | -| 3 | for 循环 + range | `for i in 0..10 {}` | ✅ v0.3 | -| 4 | **结构体 struct** | struct 具名域 | ✅ v0.4 | - -### P1: 中期 (3–5 天/项) - -| # | 功能 | 改动范围 | 学习价值 | 状态 | -|---|------|---------|---------|------| -| 5 | struct 作为函数参数/返回值 | parser (param/return 类型标注) + sema + codegen | 值传递 vs 引用传递语义 | 待实施 | -| 6 | 数组 + 索引 `[T; N]`, `arr[i]` | lexer/parser/sema/codegen(GEP) | GEP 指针计算 | 待实施 | -| 7 | 枚举 (C 风格) | lexer/parser/sema/codegen(i64) | 为代数类型铺路 | 待实施 | -| 8 | match 表达式 | lexer/parser/sema(穷举) + codegen | 模式匹配核心 | 待实施 | -| 9 | struct 方法 (impl) | parser + sema (self 参数) + codegen | Rust 方法语法糖 | 待实施 | -| 10 | 类型别名 `type Meters = i64` | lexer/parser/sema(展开) | 名称等价 vs 结构等价 | 待实施 | - -### P2: 中后期 (1–2 周/项) - -| # | 功能 | 学习价值 | 状态 | -|---|------|---------|------| -| 11 | 模块系统 `mod` + `use` | 单文件→多文件编译 | 待实施 | -| 12 | 自定义 IR 层 (三地址码/SSA) | 编译器核心抽象 | 待实施 | -| 13 | 泛型 (单态化) | Rust 零成本抽象基石 | 待实施 | -| 14 | 解释器模式 (walk AST) | 快速验证语义 | 待实施 | - -### P3: 长期 (2–4 周/项) - -| # | 功能 | 备注 | 状态 | -|---|------|------|------| -| 15 | trait / 接口 | 需泛型 + 虚表 | 待实施 | -| 16 | Option/Result | 需泛型 + enum | 待实施 | -| 17 | 所有权 / 借用检查 | 极度复杂 | 待实施 | -| 18 | 自举 (L 编译 L) | 终极考验 | 待实施 | - -### Rust 设计哲学吸收进度 - -| Rust 特性 | 状态 | 备注 | -|-----------|------|------| -| 默认不可变 (let vs let mut) | ✅ | 编译期检查, 可变性追踪 | -| 复合赋值 | ✅ | parser desugar 模式 | -| for + range | ✅ | desugar 为 while | -| str 基本支持 | ✅ | 字面量 + 拼接 + RAII 释放 | -| struct 具名域 + 字段访问 | ✅ | LLVM 命名结构体 + extractvalue | -| 表达式 vs 语句 | ❌ | if/match/block 作为表达式 (目前只支持语句) | -| struct 方法 (impl) | ❌ | P1 优先级 | -| 模式匹配 | ❌ | P1 优先级 | -| 代数数据类型 | ❌ | 需泛型 | -| 所有权 / 借用 | ❌ | RAII 雏形已就位, 但无借用检查 | - ---- - -## 6. 测试覆盖分析 - -### 6.1 单元测试 - -| 测试文件 | 测试函数 | 断言数 | 覆盖范围 | -|---------|----------|--------|---------| -| test_lexer.c | 3 | 14 | token 识别, 关键字, 操作符, 注释 | -| test_parser.c | 5 | 15 | 算术, let, if, while, 函数 | -| test_sema.c | 7 | 23 | 类型错误, 未定义变量, let mut, immutable error, str type, str concat | -| test_codegen.c | 4 | 9 | 简单函数, if/else, 二元运算, while | -| **合计** | **19** | **61** | (+2 断言) | - -### 6.2 集成测试 (13 程序, +2) - -| 文件 | 功能 | 版本 | -|------|------|------| -| 01_arithmetic.l | 算术运算 | v0.1 | -| 02_if_else.l | if/else 控制流 | v0.1 | -| 03_recurse.l | 递归函数 | v0.1 | -| 04_fib_recursive.l | 斐波那契 (递归) | v0.1 | -| 05_float.l | 浮点数 | v0.1 | -| 06_mut_while.l | let mut + while | v0.2 | -| 07_hello_str.l | 字符串输出 | v0.2 | -| 08_str_concat.l | 字符串拼接 | v0.2 | -| 09_compound_assign.l | 复合赋值 | v0.2 | -| 10_for_range.l | for range 循环 | v0.3 | -| 11_for_step2.l | for range (变量边界) | v0.3 | -| **12_struct.l** | **结构体声明+初始化+字段访问** | **v0.4** | -| **13_struct_nested.l** | **嵌套结构体+链式访问** | **v0.4** | - -### 6.3 测试缺口 (更新) - -| 缺口 | 严重度 | 说明 | -|------|--------|------| -| struct/sema 无独立单元测试 | **高** | struct 仅在集成测试间接覆盖; 缺 struct 字段类型错误/字段数不匹配/未定义 struct 等测试 | -| codegen struct 路径无单元测试 | **高** | LLVM struct 创建/GEP/extractvalue 无单元级验证 | -| RAII cleanup 无验证 | **高** | cleanup_add/cleanup_emit 逻辑仅在集成测试间接运行, 无法检测内存泄漏 | -| parser struct 错误恢复无测试 | 中 | 缺 `struct {` 不闭合、字段缺类型等错误提示验证 | -| 复合赋值/for 无独立 desugar 测试 | 低 | 仅集成测试间接覆盖 | -| codegen 缺 call/str/compound/for 路径 | 中 | 4 测试仅覆盖基础路径 | - ---- - -## 7. 技术债务与风险 - -| # | 问题 | 状态 | 严重度 | 说明 | -|---|------|------|--------|------| -| 1 | str concat malloc 内存泄漏 | **✅ 已解决** | — | v0.4 RAII 自动 free, cleanup_list 在作用域退出时调用 free() | -| 2 | struct 不可作函数参数/返回 | **新增** | 中 | parser 参数类型解析未扩展 struct 类型名 | -| 3 | struct/sema/codegen 单元测试缺失 | **新增** | 高 | struct 全流水线无单元级测试, 回归风险高 | -| 4 | RAII cleanup 无验证手段 | **新增** | 中 | 无法自动化检测 str 泄漏是否真正修复 | -| 5 | 复合赋值无独立 desugar 测试 | 存留 | 低 | 集成测试间接覆盖 | -| 6 | codegen 测试覆盖率低 (4/12 路径) | 存留 | 中 | call/str/compound/for/return/struct 路径无单元测试 | -| 7 | `system("gcc ...")` 平台绑定 | 存留 | 低 | Windows/MinGW 正常 | -| 8 | LLVM 22 无 mem2reg C API | 已记录 | 低 | codegen.c 注释说明需用 `opt` 工具 | -| 9 | 错误类型分散 (ErrorInfo + ErrorList) | 存留 | 低 | API 不统一 | -| 10 | parser.c `parse_function` 过长 | 存留 | 低 | 约 60 行 | -| 11 | **CHANGELOG 未更新 v0.4** | **新增** | 低 | struct + RAII 无 CHANGELOG 条目 | -| 12 | struct 空字段/边界测试缺失 | **新增** | 低 | 零字段 struct、仅含 struct 字段等 | - -### 风险矩阵 - -| 风险 | 概率 | 影响 | 缓解 | -|------|------|------|------| -| LLVM API 版本升级 break | 中 | 高 | 当前锁定 19.x, 文档记录不兼容点 | -| struct 全流水线无单元测试 → 回归 | 中 | 高 | struct 是核心抽象, 后续改动可能破坏 | -| GCC 链接在非 MinGW 环境失败 | 中 | 中 | 可接受链接器参数或使用 LLVM lld | -| RAII cleanup_list 溢出 (64 槽) | 低 | 低 | 正常函数不会声明 64+ struct/str | -| Arena 内存耗尽 (8MB) | 极低 | 中 | 巨型程序才触发 | - ---- - -## 8. 推荐开发路线图 - -### v0.5 目标 (下一迭代, 2–3 天) - -| 优先级 | 功能 | 预计工时 | 依赖/备注 | -|--------|------|---------|----------| -| **P1** | **struct 作为函数参数/返回值** | 1 天 | 补完 struct 可用性, parser param/return 类型标注扩展 | -| **P1** | **struct/sema 单元测试** | 0.5 天 | 覆盖: 字段类型错误, 字段数不匹配, 未定义 struct, 嵌套 struct | -| **P1** | **codegen struct 单元测试** | 0.5 天 | LLVM struct 创建, GEP, extractvalue | -| P2 | CHANGELOG 更新 v0.4 | 0.5 天 | struct + RAII 条目 | - -### v0.6 目标 - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| P1 | 数组 + 索引 `[T; N]` | 2 天 | -| P1 | struct 方法 (impl) | 2 天 | -| P1 | 枚举 (C 风格) | 1 天 | - -### 长期方向 - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| P1 | match 表达式 | 2–3 天 | -| P1 | 类型别名 | 0.5 天 | -| P2 | 自定义 IR 层 | 3–5 天 | -| P2 | 模块系统 | 3–5 天 | -| P3 | 泛型 (单态化) | 5–7 天 | -| P3 | trait / 接口 | 5–7 天 | - ---- - -## 9. 代码质量评估 - -### 9.1 模块内聚度 - -| 模块 | 内聚度 | 评价 | -|------|--------|------| -| lexer | 高 | 纯函数接口, 新增 TOK_STRUCT/TOK_DOT 一字插入 | -| parser | 高 | struct 解析逻辑独立为 `parse_struct_decl`/`parse_struct_init`, 未侵入现有流程; 2-token lookahead 消歧义清晰 | -| ast | 高 | 3 新节点遵循工厂函数模式, TypeInfo.struct_name 向后兼容 (NULL for 非 struct) | -| sema | 中高 | struct 检查独立分支, struct_name 传播链完整; 但 analyze_expr/analyze_node switch 需关注增长 | -| codegen | 中 | cleanup_list 机制与现有 `codegen_stmt` 耦合; struct 类型映射独立为 `struct_table` 查找 | -| driver | 中 | 无变更 | -| util | 高 | 无变更 | - -### 9.2 新增代码风格 - -- cleanup_list 64 槽硬编码合理 (以现有代码规模) -- struct_name 传播链使用 `const char*` (arena 分配), 零拷贝负担 -- `extractvalue` 而非 `GEP+load` 的选择与 AST 值语义一致 -- 2-token lookahead 是 parser 中唯一的非 LL(1) 点, 注释说明了消歧义逻辑 - -### 9.3 架构债务 (新增) - -| 债务 | 说明 | -|------|------| -| analyze_expr 持续膨胀 | 当前 200+ 行 switch, 新增 FIELD_ACCESS/STRUCT_INIT 两个 case; 考虑拆分为子函数 | -| codegen_stmt 单一大函数 | 当前 ~280 行, cleanup 逻辑嵌入 let/block/return 三个 case | -| struct_name 空指针传播 | 多处 `if (xxx && xxx->struct_name)` 检查, 若遗漏则静默 fallback | - ---- - -## 10. 度量汇总 (对比) - -| 指标 | v0.3 基线 (382cd08) | **v0.4 (1d4fb27)** | Δ | -|------|---------------------|---------------------|----| -| 源文件数 (.c) | 12 | 12 | 0 | -| 头文件数 (.h) | 12 | 12 | 0 | -| 实现代码 | 1,688 行 | **2,221 行** | +533 | -| 头文件 | 308 行 | **323 行** | +15 | -| 测试代码 | 330 行 | **361 行** | +31 | -| 总代码量 | 2,326 行 | **2,905 行** | +579 | -| Token 类型 | 37 | **39** | +2 | -| AST 节点类型 | 15 | **18** | +3 | -| TypeKind | 7 | **8** | +1 | -| SymbolKind | 3 | **4** | +1 | -| 内置函数 | 4 | 4 | 0 | -| C 运行时依赖 | printf, malloc, strlen, memcpy | **+free** | +1 | -| 单元测试函数 | 19 | 19 | 0 | -| 单元测试断言 | 59 | **61** | +2 | -| 集成测试程序 | 11 | **13** | +2 | -| P0 完成度 | 3/4 (75%) | **4/4 (100%)** | ✅ | -| P0 遗留 | struct | **无** | — | -| 编译产物 | 6 个 .exe | 6 个 .exe | 0 | -| Git 提交数 | 11 | **13** | +2 | - ---- - -*本报告由 Codex 自动生成于 2026-06-05 13:08。自上次代码基线 `382cd08` 后有 2 个源代码提交 (+1882/-54 行): struct 结构体 (P0 收官) 和 RAII 自动内存管理 (作用域级 free)。P0 全线完成, struct 集成度已完成但缺函数参数/返回值支持。下一优先级: struct 参数/返回值 + struct 单元测试覆盖。* diff --git a/docs/analysis/architecture-analysis-report-2026-06-05-1509.md b/docs/analysis/architecture-analysis-report-2026-06-05-1509.md deleted file mode 100644 index 2addd88..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-05-1509.md +++ /dev/null @@ -1,417 +0,0 @@ -# L Language 架构分析报告 — P1 全线收官 + match 表达式 (v0.5) - -> 日期: 2026-06-05 15:09 | 自动生成 | **有源代码变更** -> 上次代码分析基线: `1d4fb27` (2026-06-05 13:08 报告, v0.4) -> 当前 HEAD: `a15cd9d` feat: match 表达式 (P1 #8 收官) -> -> 新增提交 (自上次源代码基线 `1d4fb27`): -> - `af0725c` fix: 全面代码审查 — 修复 3 CRITICAL + 4 HIGH 问题 -> - `a7fca59` fix: 5项立即修复 + 2项尽快修复 -> - `4046ab1` refactor: tok_is_type 统一 + 架构改进文档 -> - `da9a706` feat: struct参数/返回值 + SourceLoc + 测试补全 (**P1 #5 完成**) -> - `ab88ea2` feat: 类型别名 type alias (**P1 #10 完成**) -> - `5237398` feat: 枚举 enum (**P1 #7 完成**) -> - `2923e75` feat: 数组+索引 [T;N], arr[i] (**P1 #6 完成**) -> - `9f6e695` feat: struct方法 impl (**P1 #9 完成**) -> - `a15cd9d` feat: match 表达式 (**P1 #8 收官**) - -**本次是自 v0.4 以来最大规模的变更: 9 个提交, P1 全部 6 项需求一次性落地。** - ---- - -## 变更摘要 (自上次代码基线) - -**27 个文件变更, +2596 / -284 行。** P1 路线图全覆盖: - -| 变更类别 | 详情 | 影响范围 | -|---------|------|---------| -| **P1 #5: struct 参数/返回值** | parser 扩展 param/return type 解析; SourceLoc 抽象落地 | parser/sema/codegen/driver | -| **P1 #10: 类型别名** | `type Meters = i64;` / `type P = Point;` 全流水线 | parser/sema(alias 展开链) | -| **P1 #7: 枚举 enum** | `enum Color { Red, Green, Blue }`, `Color::Green` 变体 | lexer/parser/sema/codegen | -| **P1 #6: 数组+索引** | `let arr: [i64; 3]`, `arr[i]`, `arr[i] = expr` | lexer/parser/sema/codegen(GEP) | -| **P1 #9: struct 方法 impl** | `impl Point { fn get_x(self: Point) ... }`, `p.method()` 调用 | parser/sema(改名 mangle)/codegen | -| **P1 #8: match 表达式** | `match x { pat => { body } _ => { body } }`, parser 脱糖 | parser(desugar 为 let+if-else) | -| **基础设施重构** | SourceLoc 抽象, tok_is_type 统一, 架构改进文档, CRITICAL bug 修复 | 全项目 | -| **测试扩展** | sema: 9→21 tests; codegen: 4→9 tests; 集成: 13→23 programs | test/ | - ---- - -## 1. 当前架构全景 - -### 1.1 编译流水线 - -``` -源码(.l) → Lexer(词法) → Parser(语法) → Sema(语义) → Codegen(LLVM IR) → Target(obj) → GCC 链接(.exe) - 50 Token 25 AST 节点 类型标注 LLVMModuleRef .o 文件 -``` - -**流水线结构无变化**,但数据流丰富度大幅提升: AST 节点从 18 增至 25, Token 从 39 增至 50, TypeKind 从 8 增至 10。 - -### 1.2 模块清单与指标 - -| 模块 | 关键职责 | 本次变更 | -|------|---------|---------| -| include/ | TypeKind 枚举 (10 种: +TYPE_ENUM, +TYPE_ARRAY), SourceLoc 抽象 | +15 行 | -| lexer/ | 手写状态机, **50** Token 类型 | +38 行 | -| ast/ | **25** 种节点类型 (+7: TYPE_ALIAS, ENUM_DECL, ENUM_VARIANT, INDEX_EXPR, ARRAY_ASSIGN, IMPL_BLOCK, METHOD_CALL) | +218 行 | -| parser/ | 递归下降 + Pratt, 新增 enum/impl/type/match 解析, `parse_type_expr()` 统一类型表达式 | +425 行 | -| sema/ | 类型推断, 5 种 SymbolKind (+SYM_ENUM), impl 方法改名 mangle, alias 展开链 | +542 行 | -| codegen/ | LLVM struct/array/enum/match, GEP, method call, 清理表动态扩容 | +269 行 | -| driver/ | 流水线串联, SourceLoc 适配 | +11 行 | -| test/ | **30** 单元测试函数 (+11), 10 集成程序新增 | +636 行 | - -| 汇总指标 | 上次 (v0.4, 1d4fb27) | **当前 (v0.5, a15cd9d)** | Δ | -|---------|----------------------|-------------------|----| -| 实现代码 (.c) | 2,221 行 | **~3,480 行** | +~1,259 | -| 头文件 (.h) | 323 行 | **~450 行** | +~127 | -| 测试代码 | 361 行 | **~997 行** | +636 | -| **总代码量** | **2,905 行** | **~4,927 行** | **+2,022** | -| Token 类型 | 39 | **50** | +11 | -| AST 节点类型 | 18 | **25** | +7 | -| TypeKind | 8 | **10** | +2 | -| SymbolKind | 4 | **5** | +1 | -| 单元测试函数 | 19 | **30** | +11 | -| 集成测试程序 | 13 | **23** | +10 | -| P0 完成度 | 4/4 (100%) | 4/4 (100%) | — | -| P1 完成度 | 0/6 (0%) | **6/6 (100%)** | ✅ | -| Git 提交数 | 13 | **22** | +9 | - -### 1.3 关键架构决策 (v0.5 新增) - -| 决策 | 描述 | 技术理由 | -|------|------|---------| -| **impl 改名 mangle** | `impl Point { fn get_x }` 在 sema 阶段将函数名改为 `Point$get_x`, 自动插入 self 参数 | 零入侵 codegen: 方法调用退化为普通函数调用 | -| **match 脱糖为 let+if-else** | parser 阶段将 match 转为 `{ let __match_val=expr; if ... else ... }` | 复用现有 if-else codegen, 零新增 LLVM IR 路径 | -| **数组类型自引用声明** | `let arr: [i64; 3] = arr;` 以自身标识符为初始化占位符 | ArrayType 固定大小, sema/codegen 识别 TYPE_ARRAY 标注后跳过 init 分析 | -| **parse_type_expr 统一入口** | 所有类型标注解析通过同一函数 | 消除分散类型解析, 支持 `[T; N]` 嵌套 | -| **cleanup_list 动态扩容** | 从固定 64 槽改为 realloc 式动态扩容 (16→x2) | 消除溢出风险 | -| **SourceLoc 聚合** | `typedef struct { int line; int col; }` 替代所有 `int line, int col` 参数对 | 减少参数数量, 为后续添加 `file` 做准备 | - ---- - -## 2. P1 全线功能详解 - -### 2.1 struct 作为函数参数/返回值 (P1 #5) - -parser 的 `parse_function` 参数类型解析从 `token_to_type()` 改为 `parse_type_expr()`, 支持 `fn f(p: Point) -> Point`。Codegen 中 struct 参数通过 alloca+store 转为栈变量, struct 返回值通过直接值传递 (LLVM struct 类型)。 - -**测试**: `14_struct_fn.l` — Point 作为参数和返回值。 - -### 2.2 类型别名 type alias (P1 #10) - -`parse_type_expr()` 识别 `TOK_IDENT` 时查找已注册别名; sema Pass 0 提前注册所有别名。 - -``` -语法: type Meters = i64; - type P = Point; - -别名展开链: - parser: 解析 `let x: P` → annot struct_type_name="P" - sema: scope_lookup("P") → 别名符号 → 获取真实 type=STRUCT/struct_type_name="Point" -``` - -**测试**: `15_type_alias.l`, `16_type_alias_struct.l` - -### 2.3 枚举 enum (P1 #7) - -新增 TOK_ENUM/TOK_COLON_COLON Token; `AST_ENUM_DECL`/`AST_ENUM_VARIANT` AST 节点; SYM_ENUM SymbolKind。枚举变体映射为 i64 常量 (0, 1, 2...)。 - -``` -语法: enum Color { Red, Green, Blue } - let c = Color::Green; // codegen: LLVMConstInt(LLVMInt64Type, 1) -``` - -**测试**: `17_enum.l`, sema: test_enum_ok/test_enum_bad_variant - -### 2.4 数组 + 索引 (P1 #6) - -新增 `[i64; N]` 语法 (`parse_type_expr` 中解析), `AST_INDEX_EXPR` (读取), `AST_ARRAY_ASSIGN_STMT` (写入)。 - -``` -语法: let arr: [i64; 3] = arr; - arr[0] = 10; - print_i64(arr[0]); - -Codegen: LLVMArrayType(elem_ty, N) → alloca → GEP(0, i) → load/store - 索引值 i64 → i32 截断 (LLVM GEP 要求 i32) -``` - -**测试**: `18_array.l`, sema 4 测试, codegen: test_codegen_array - -### 2.5 struct 方法 impl (P1 #9) - -`parse` 处理 `impl StructName { ... }` 块; sema 将方法函数名改为 `StructName$methodName` 并追加 self 参数。 - -``` -语法: impl Point { - fn get_x(self: Point) -> i64 { return self.x; } - } - p.get_x(); // AST_METHOD_CALL - -Mangle 流程: - parser: impl → AST_IMPL_BLOCK { struct_name, methods } - sema: 遍历 impl → 改名 "Point$get_x", 插入前导 self 参数, 追加到 functions 数组 - codegen: find_fn("Point$get_x") + call(receiver, args...) — 退化为普通函数调用 -``` - -**测试**: `19_struct_method.l`, sema 2 测试, codegen: test_codegen_method_call - -### 2.6 match 表达式 (P1 #8) - -新增 TOK_MATCH/TOK_MATCH_ARROW/TOK_UNDERSCORE Token; parser 内 `parse_match_stmt()` 将 match 脱糖为 let+if-else 链。 - -``` -语法: match expr { - pat1 => { body1; } - _ => { default_body; } - } - -脱糖逻辑 (parser 阶段): - match c { Color::Green => { print_i64(20); } _ => { print_i64(0); } } - → { - let __match_val = c; - if __match_val == Color::Green { print_i64(20); } - else { print_i64(0); } - } - -臂数 64 上限, 从最后一个臂往前构建 if-else 链 -``` - -**关键设计**: match 不产生新 AST 节点 — 直接生成 AST_BLOCK + AST_LET_STMT + AST_IF_STMT 链; codegen/sema 零改动。 - -**测试**: 4 个集成测试 (`20_match.l`~`23_match_wildcard.l`) - ---- - -## 3. 架构重构与基础设施 - -### 3.1 SourceLoc 抽象 - -```c -// include/l_lang.h -typedef struct { int line; int col; } SourceLoc; -``` - -所有 AST 工厂函数从 `int line, int col` 参数对改为 `SourceLoc loc` 单参数。全模块已适配。 - -### 3.2 tok_is_type 统一 - -删除 parser.c 中重复的 `is_type_token()` 函数, 统一使用 `token.c:tok_is_type()` (已补 TOK_STR)。 - -### 3.3 CRITICAL Bug 修复清单 - -| 严重度 | 问题 | 修复 | -|--------|------|------| -| CRITICAL | parser `parse_struct_init` 字段名数组栈变量悬垂 | arena 分配 + memcpy | -| CRITICAL | codegen 隐式尾部 return 缺 struct 类型处理 | 添加 `LLVMConstNull(st_ty)` | -| CRITICAL | str 字面量 tok 未 NUL 终止 | arena_strdup + `\0` | -| HIGH | codegen return 前 cleanup 可能 free 返回值 | 从 cleanup_list 移除 | -| HIGH | match 通配符 if-else 链条件 | `if (true) { body }` | -| HIGH | sema impl 处理 `new_fns` 数组大小计算时机 | 预先统计 extra_fn | - ---- - -## 4. 功能清单与成熟度 - -### 4.1 已实现功能 (全版本) - -- [x] v0.1: 基本类型/算术/控制流/函数/内置函数/类型推断 -- [x] v0.2: let mut/赋值/str/字符串拼接/复合赋值 -- [x] v0.3: for + range -- [x] v0.4: struct 声明+初始化+字段访问/嵌套结构体/RAII 自动内存管理 -- [x] **v0.5: P1 全线 — struct 参数/返回值/类型别名/枚举/数组+索引/impl 方法/match 表达式** - -### 4.2 当前已知限制 - -| 限制 | 严重度 | 说明 | -|------|--------|------| -| 数组不支持 struct 元素类型 `[Point; N]` | 中 | parse_type_expr TYPE_ARRAY 路径未传 element_struct_name | -| enum 无关联数据 (代数数据类型) | 中 | 仅 C 风格枚举 | -| 无表达式作为值 (expression-oriented) | 中 | if/match/block 不能出现在表达式位置 | -| match 仅单值匹配 | 低 | 不支持 range pattern / guard | -| 数组声明自引用语法 `let arr: [i64; 3] = arr;` | 低 | 必须写两遍 arr | -| 无字符串方法 (len/slice) | 低 | str 仅拼接+打印 | - ---- - -## 5. 与 Rust 对标: 缺失功能清单及优先级 - -### 已完成 (P0 + P1 全通过) - -| # | 功能 | Rust 启发 | 版本 | -|---|------|----------|------| -| P0-1~4 | 复合赋值/str拼接/for+range/struct | — | v0.2–v0.4 | -| P1-5 | struct 参数/返回值 | 值语义 | v0.5 | -| P1-6 | 数组+索引 | `[T; N]`, `arr[i]` | v0.5 | -| P1-7 | 枚举 | enum | v0.5 | -| P1-8 | match 表达式 | 模式匹配 (简化) | v0.5 | -| P1-9 | struct 方法 | impl block | v0.5 | -| P1-10 | 类型别名 | type alias | v0.5 | - -### P2: 中后期 - -| # | 功能 | 预计工时 | 状态 | -|---|------|---------|------| -| 11 | 表达式作为值 (expression-oriented) | 2–3 天 | 待实施 | -| 12 | 模块系统 `mod` + `use` | 3–5 天 | 待实施 | -| 13 | 泛型 (单态化) | 5–7 天 | 待实施 | -| 14 | 枚举关联数据 (代数数据类型) | 2 天 | 待实施 | -| 15 | trait / 接口 | 5–7 天 | 待实施 | - -### P3: 长期 - -| # | 功能 | 预计工时 | -|---|------|---------| -| 16 | 所有权 / 借用检查 | 2–4 周 | -| 17 | 自举 (L 编译 L) | 4–6 周 | -| 18 | 标准库 (prelude) | 4–6 周 | - -### Rust 设计哲学吸收进度 - -| Rust 特性 | 状态 | 备注 | -|-----------|------|------| -| 默认不可变 (let vs let mut) | ✅ | 编译期检查 | -| 复合赋值 | ✅ | parser desugar | -| for + range | ✅ | desugar 为 while | -| struct 具名域 | ✅ | LLVM 命名结构体 | -| impl 方法 | ✅ | sema mangle | -| enum + match (简化) | ✅ | C 风格枚举 + 单值 match | -| 类型别名 | ✅ | alias 展开链 | -| 数组固定大小 | ✅ | GEP | -| RAII 自动释放 | ✅ | cleanup_list | -| 表达式 vs 语句 | ❌ | P2 优先 | -| 代数数据类型 | ❌ | P2 优先 | -| 泛型 (单态化) | ❌ | P2 优先 | -| trait / 接口 | ❌ | P2 优先 | -| 所有权 / 借用 | ❌ | P3 | -| 模块系统 | ❌ | P2 优先 | - ---- - -## 6. 测试覆盖分析 - -### 6.1 单元测试 - -| 测试文件 | 测试函数 | 覆盖范围 | -|---------|----------|---------| -| test_lexer.c | 3 | token 识别, 关键字, 操作符, 注释 | -| test_parser.c | 5 | 算术, let, if, while, 函数 | -| test_sema.c | **21** (+12) | 类型错误, let mut, str, struct 字段, 类型别名, enum, 数组, 方法调用 | -| test_codegen.c | **9** (+5) | 基础路径, struct decl/field, enum, array, method call | -| **合计** | **38** (+11) | | - -### 6.2 集成测试 (23 程序) - -- 01–11: v0.1–v0.3 基线 -- 12–13: struct + 嵌套 struct (v0.4) -- **14–23**: v0.5 新增 10 程序 (struct_fn/type_alias/enum/array/struct_method/4×match) - -### 6.3 测试缺口 - -| 缺口 | 严重度 | -|------|--------| -| match/sema 无独立单元测试 | 高 | -| 数组 struct 元素类型无测试 | 中 | -| RAII + 新功能交互无验证 | 中 | -| parser 错误恢复无测试 | 低 | - ---- - -## 7. 技术债务与风险 - -| # | 问题 | 严重度 | 说明 | -|---|------|--------|------| -| 1 | analyze_expr 持续膨胀 (200+→350+ 行) | 高 | ENUM_VARIANT/INDEX_EXPR/METHOD_CALL 等 | -| 2 | parser.c 单文件 939 行 | 中 | +415 行: enum/impl/type/match/match 脱糖 | -| 3 | codegen.c 单文件 854 行 | 中 | 3 个 switch 持续增长 | -| 4 | match 脱糖在 parser, 非独立 pass | 中 | arch-improvements #4 建议未实施 | -| 5 | 数组 struct 元素类型未实现 | 中 | `[Point; N]` | -| 6 | TypeKind 耦合 (arch-improvements #1) | 低 | 加新类型需改 7+ 文件 | -| 7 | AST Visitor 缺失 (arch-improvements #2) | 低 | 加新节点需改 4 个 switch | -| 8 | CHANGELOG 未更新 v0.4/v0.5 | 低 | 仅到 v0.3 | -| 9 | LLVM 22 无 mem2reg C API | 低 | 已记录 | -| 10 | `system("gcc ...")` 平台绑定 | 低 | Windows/MinGW | - ---- - -## 8. 推荐开发路线图 - -### v0.6 目标 (下一迭代, 2–3 天) - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| P1 | parser 独立 desugar pass (for/match/compound assign) | 0.5 天 | -| P1 | 数组 struct 元素类型 `[Point; N]` | 0.5 天 | -| P1 | match/sema 单元测试 | 0.5 天 | -| P2 | CHANGELOG 更新 v0.4/v0.5 | 0.5 天 | - -### v0.7 目标 - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| P2 | 表达式作为值 (expression-oriented) | 2–3 天 | -| P2 | 枚举关联数据 | 2 天 | -| P2 | AST Visitor 宏驱动 | 2 天 | - -### 长期方向 - -| 优先级 | 功能 | 预计工时 | -|--------|------|---------| -| P2 | 模块系统 / 泛型 / trait | 各 3–7 天 | -| P3 | 所有权 / 自举 / 标准库 | 2–6 周 | - ---- - -## 9. 代码质量评估 - -### 9.1 模块内聚度 - -| 模块 | 评价 | -|------|------| -| lexer | 高 — 11 新 Token 一字插入 | -| parser | **中** — +415 行, parse_match_stmt(80行) + parse_type_expr(40行) + impl/enum/type 内联 | -| ast | 高 — 7 新节点遵循工厂函数模式 | -| sema | **中高** — +542 行: impl mangle/alias 展开/enum/array/method 语义; analyze_expr switch 350+ 行 | -| codegen | **中** — +269 行: enum/array/index/method/match; 3 个 switch 持续增长 | -| driver | 高 — 仅 SourceLoc 适配 | -| util | 高 — 无变更 | - -### 9.2 代码风格亮点 - -- **impl mangle 设计**: sema 阶段转换, codegen 零修改 — 干净解耦 -- **match 脱糖**: 转为 AST 原语链, sema/codegen 完全复用 (但耦合在 parser 中) -- **parse_type_expr 统一**: 消除分散类型解析, 天然支持 `[T; N]` -- **cleanup_list 动态扩容**: arena 分配保持 zero-overhead - -### 9.3 架构债务 - -| 债务 | 说明 | -|------|------| -| parser.c 939 行 | 含 enum/impl/type/match + 脱糖, 建议 P2 模块化 | -| sema analyze_expr 350+ 行 | CASE 从 5 增至 10 | -| codegen 3 个 switch 增长 | 新增 3 case (ENUM_VARIANT/METHOD_CALL/INDEX_EXPR) | -| impl mangle 隐式命名约定 | codegen 通过 `$` 识别方法, 非结构化标记 | - ---- - -## 10. 度量汇总 (对比) - -| 指标 | v0.4 (1d4fb27) | **v0.5 (a15cd9d)** | Δ | -|------|----------------|-------------------|----| -| 实现代码 | 2,221 行 | **~3,480 行** | +~1,259 | -| 头文件 | 323 行 | **~450 行** | +~127 | -| 测试代码 | 361 行 | **~997 行** | +636 | -| **总代码量** | **2,905 行** | **~4,927 行** | **+2,022** | -| Token 类型 | 39 | **50** | +11 | -| AST 节点类型 | 18 | **25** | +7 | -| TypeKind | 8 | **10** | +2 | -| SymbolKind | 4 | **5** | +1 | -| 单元测试函数 | 19 | **30** | +11 | -| 集成测试程序 | 13 | **23** | +10 | -| P0 完成度 | 4/4 (100%) | 4/4 (100%) | — | -| P1 完成度 | 0/6 (0%) | **6/6 (100%)** | ✅ | -| Git 提交数 | 13 | **22** | +9 | - ---- - -*本报告由 Codex 自动生成于 2026-06-05 15:09。自上次代码基线 `1d4fb27` (v0.4) 后有 9 个源代码提交 (+2596/-284 行): P1 路线图全线收官 — struct 参数/返回值、类型别名、枚举、数组+索引、struct 方法 impl、match 表达式全部落地。v0.5 实现了 Rust 启发语言的完整单片编译器能力; 下一迭代应关注 parser 独立 desugar pass、数组 struct 元素类型补全、表达式作为值。* diff --git a/docs/analysis/architecture-analysis-report-2026-06-05-1708.md b/docs/analysis/architecture-analysis-report-2026-06-05-1708.md deleted file mode 100644 index 83df10d..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-05-1708.md +++ /dev/null @@ -1,185 +0,0 @@ -# L Language 架构分析报告 — 无代码变更 (快照复查) - -> 日期: 2026-06-05 17:08 | 自动生成 | **无源代码变更** -> 上次代码基线: `a15cd9d` (2026-06-05 15:09 报告, v0.5) -> 当前 HEAD: `a15cd9d` feat: match 表达式 (P1 #8 收官) -> -> **结论: 自上次架构分析报告以来无新提交。以下为当前架构快照及健全性复查。** - ---- - -## 代码变更检查 - -``` -git log a15cd9d..HEAD → (空) -``` - -`a15cd9d` 仍是 HEAD。与上次报告 (2026-06-05 15:09) 完全一致。**零文件变更,零行差异。** - ---- - -## 1. 当前架构快照 (v0.5) - -### 1.1 编译流水线 - -``` -源码(.l) → Lexer(词法) → Parser(语法) → Sema(语义) → Codegen(LLVM IR) → Target(obj) → GCC 链接(.exe) - 50 Token 25 AST 节点 类型标注 LLVMModuleRef .o 文件 -``` - -### 1.2 模块清单与行数 - -| 模块 | 文件 | 行数 | 职责 | -|------|------|------|------| -| include/ | l_lang.h | 57 | TypeKind (10), SourceLoc, 公共类型 | -| lexer/ | lexer.c + token.c (+ .h) | 163 + 54 | 手写状态机, 50 Token 类型 | -| ast/ | ast.c + ast.h | 245 + 159 | 25 种 AST 节点, 工厂函数 | -| parser/ | parser.c + parser.h | 825 + 13 | 递归下降 + Pratt, parse_type_expr 统一 | -| sema/ | sema.c + symbol.c (+ .h) | 809 + 155 | 类型推断, alias 展开, impl mangle | -| codegen/ | codegen.c + target.c (+ .h) | 824 + 35 | LLVM IR 生成, GEP, enum/array/match | -| driver/ | main.c + error.c (+ .h) | 160 + 49 | 流水线串联, 错误报告 | -| util/ | arena.c + arena.h | 45 + 17 | Bump allocator (8MB) | -| **实现总计** | | **~3,336 行** | | -| test/ | test_*.c × 4 | 944 | 30 单元测试函数 | -| test/ | programs/*.l × 23 | — | 23 集成测试程序 | -| **测试总计** | | **~944 行** | | - -### 1.3 核心类型系统 - -| 枚举 | 成员数 | 位置 | -|------|--------|------| -| TypeKind | 10 (+2 vs v0.4) | include/l_lang.h:9, TYPE_ENUM + TYPE_ARRAY | -| TokenKind | 50 (+11 vs v0.4) | src/lexer/token.h | -| AstNodeKind | 25 (+7 vs v0.4) | src/ast/ast.h | -| SymbolKind | 5 (+1 vs v0.4) | src/sema/symbol.h:7, SYM_ENUM | - -**TypeKind 成员**: TYPE_I64, TYPE_F64, TYPE_BOOL, TYPE_STR, TYPE_VOID, TYPE_STRUCT, TYPE_ENUM, TYPE_ARRAY, TYPE_UNKNOWN, TYPE_ERROR - -**SymbolKind 成员**: SYM_VARIABLE, SYM_PARAMETER, SYM_FUNCTION, SYM_STRUCT, SYM_ENUM - -### 1.4 关键架构决策 - -| 决策 | 说明 | -|------|------| -| impl 改名 mangle | sema 阶段将 `impl S { fn f }` 转为 `S$f`, 追加 self 参数; codegen 零修改 | -| match 脱糖为 let+if-else | parser 阶段直接生成 AST_BLOCK + AST_LET_STMT + AST_IF_STMT 链; sema/codegen 完全复用 | -| parse_type_expr 统一入口 | 所有类型标注解析通过同一函数, 天然支持 `[T; N]` 嵌套 | -| SourceLoc 聚合 | `{ int line; int col; }` 替代所有松散参数对 | -| cleanup_list 动态扩容 | arena realloc, 消除固定 64 槽溢出风险 | - ---- - -## 2. 功能完成度总览 - -### 2.1 P0 (v0.1-v0.4) — 100% - -- [x] 词法/语法/语义三阶段解析 -- [x] i64/f64/bool/void/str 类型 -- [x] 算术/比较/逻辑运算 -- [x] if/else/while/return 控制流 -- [x] 函数定义+调用+递归 -- [x] let/let mut 变量+赋值 -- [x] 字符串拼接 str+str -- [x] 复合赋值 += -= *= /= -- [x] for + range (去糖为 let mut + while + assign) -- [x] struct 声明/初始化/字段访问/嵌套 -- [x] RAII 自动内存管理 (cleanup_list) -- [x] 3 内置函数: print_i64, print_f64, print_str - -### 2.2 P1 (v0.5) — 100% - -| # | 功能 | Rust 启发 | 实现方式 | -|---|------|----------|---------| -| P1-5 | struct 参数/返回值 | 值语义 | parse_type_expr 扩展 + codegen struct type | -| P1-6 | 数组+索引 | `[T; N]`, `arr[i]` | parse_type_expr 嵌套 + GEP | -| P1-7 | 枚举 | enum | i64 常量映射 + SYM_ENUM | -| P1-8 | match 表达式 | 模式匹配 (简化) | parser 脱糖为 let+if-else | -| P1-9 | struct 方法 impl | impl block | sema mangle + 普通函数调用 | -| P1-10 | 类型别名 | type alias | alias 展开链 (sema Pass 0) | - ---- - -## 3. 测试覆盖 - -| 测试文件 | 测试函数 | 行数 | 覆盖范围 | -|---------|----------|------|---------| -| test_lexer.c | 3 | 53 | token 识别, 关键字, 操作符, 注释 | -| test_parser.c | 5 | 68 | 算术, let, if, while, 函数 | -| test_sema.c | 21 | 391 | 类型检查, let mut, str, struct, enum, array, method, type alias | -| test_codegen.c | 9 | 432 | struct, enum, array, method call, LLVMVerifyModule | -| **合计** | **38 (+11 vs v0.4)** | **944** | | -| 集成 .l 程序 | **23** | — | 算术→if→for→struct→enum→array→method→match | - ---- - -## 4. Rust 对标缺失清单 (现状) - -### 已完成 - -| 特性 | 状态 | -|------|------| -| 默认不可变 (let vs let mut) | ✅ | -| 复合赋值 | ✅ | -| for + range | ✅ | -| struct 具名域 | ✅ | -| impl 方法 | ✅ | -| enum + match (简化) | ✅ | -| 类型别名 | ✅ | -| 数组固定大小 | ✅ | -| RAII 自动释放 | ✅ | - -### 缺失 (P2 — 中期) - -| # | 功能 | 预计工时 | 优先级 | -|---|------|---------|--------| -| 11 | 表达式作为值 (expression-oriented) | 2–3 天 | 高 | -| 12 | 模块系统 `mod` + `use` | 3–5 天 | 高 | -| 13 | 泛型 (单态化) | 5–7 天 | 中 | -| 14 | 枚举关联数据 (代数数据类型) | 2 天 | 高 | -| 15 | trait / 接口 | 5–7 天 | 中 | - -### 缺失 (P3 — 长期) - -| # | 功能 | 预计工时 | -|---|------|---------| -| 16 | 所有权 / 借用检查 | 2–4 周 | -| 17 | 自举 (L 编译 L) | 4–6 周 | -| 18 | 标准库 (prelude) | 4–6 周 | - ---- - -## 5. 技术债务 (不变) - -| # | 问题 | 严重度 | 状态 | -|---|------|--------|------| -| 1 | analyze_expr 膨胀 (350+ 行) | 高 | 未修复 | -| 2 | parser.c 单文件 825 行 | 中 | 未修复 | -| 3 | codegen.c 单文件 824 行 | 中 | 未修复 | -| 4 | match 脱糖在 parser, 非独立 pass | 中 | 未修复 | -| 5 | 数组 struct 元素类型 `[Point; N]` 未实现 | 中 | 未修复 | -| 6 | match/sema 无独立单元测试 | 高 | 未修复 | -| 7 | TypeKind 耦合 (加新类型需改 7+ 文件) | 低 | 未修复 | -| 8 | AST Visitor 缺失 (加节点需改 4 个 switch) | 低 | 未修复 | -| 9 | CHANGELOG 未更新 v0.4/v0.5 | 低 | 未修复 | -| 10 | LLVM 22 无 mem2reg C API | 低 | 平台限制 | - ---- - -## 6. 推荐开发路线图 (重述) - -### v0.6 优先 (2–3 天) - -1. parser 独立 desugar pass (for/match/compound assign) -2. 数组 struct 元素类型 `[Point; N]` -3. match/sema 单元测试 -4. CHANGELOG 更新 - -### v0.7 优先 - -1. 表达式作为值 (expression-oriented) -2. 枚举关联数据 (代数数据类型) -3. AST Visitor 宏驱动 - ---- - -*本报告由 Codex 自动生成于 2026-06-05 17:08。自上次代码基线 `a15cd9d` (v0.5) 以来无新提交 — 代码库处于稳定状态。P1 路线图全线完成, 下一迭代应聚焦 parser 重构、数组 struct 元素类型、match/sema 测试、表达式作为值。* diff --git a/docs/analysis/architecture-analysis-report-2026-06-06-0050.md b/docs/analysis/architecture-analysis-report-2026-06-06-0050.md deleted file mode 100644 index a5668c8..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-06-0050.md +++ /dev/null @@ -1,307 +0,0 @@ -# L Language 架构分析报告 v0.6 - -> 日期: 2026-06-06 00:50 | 自动生成 | **重大代码变更** -> 上次代码基线: `a15cd9d` (2026-06-05 17:08 报告, v0.5) -> 当前 HEAD: `de91886` fix: CreateProcess 替代 system() 调 ld.lld,消除 shell 转义问题 -> **版本: v0.6** - ---- - -## 代码变更检查 - -``` -git log a15cd9d..HEAD → 20 新提交, 36 文件变更, +2483/-163 行 -``` - -自 v0.5 以来累计 20 个提交,涵盖 6 个新语言特性、语法差异化调整、链接器重构、安装包系统。 - -详细提交链: - -| # | 提交 | 类别 | -|---|------|------| -| 1-2 | CHANGELOG/语言参考文档 | 文档 | -| 3-4 | CLAUDE.md 语言设计哲学 | 文档 | -| 5 | 数组初始化 `= arr` 语法说明 | 文档 | -| 6 | match/sema 单元测试 (145→158) | 测试 | -| 7 | 数组支持 struct 元素类型 `Point[N]` | P1-5 修复 | -| 8 | 测试计数更新 145→158 + 23→24 | 测试 | -| 9 | for..in 范围语法 `..` → `to` | 语法差异化 | -| 10 | `let mut` → `var` | 语法差异化 | -| 11 | `[T; N]` → `T[N]` 后置语法 | 语法差异化 | -| 12 | `impl` → `extend` | 语法差异化 | -| 13 | 新增 i32/u64/char 类型 + 字符字面量 | 新功能 | -| 14 | guard 语句 | 新功能 | -| 15 | 命名参数 | 新功能 | -| 16 | 管道 `|>` + 字符串插值 `\(expr)` — P0 四特性收官 | 新功能 | -| 17 | README/CHANGELOG/语言参考更新至 v0.6 | 文档 | -| 18 | 链接器 gcc → clang + lld | 基础设施 | -| 19 | NSIS 安装包脚本 | 基础设施 | -| 20 | CreateProcess 替代 system() 调 ld.lld | 基础设施 | - ---- - -## 1. 当前架构快照 (v0.6) - -### 1.1 编译流水线 - -``` -源码(.l) → Lexer(词法) → Parser(语法) → Sema(语义) → Codegen(LLVM IR) → Target(obj) → clang+lld 链接(.exe) - 58 Token 25 AST 节点 类型标注 LLVMModuleRef .o 文件 优先 clang→fallback gcc -``` - -v0.5 的 GCC 链接器已被 clang + lld 替代(自动 fallback)。`system()` 调用被 `CreateProcess` 替代,消除 shell 转义问题。 - -### 1.2 模块清单与行数 - -| 模块 | 文件 | 行数 | vs v0.5 | 职责 | -|------|------|------|---------|------| -| include/ | l_lang.h | 55 | -2 | TypeKind (13), SourceLoc, 公共类型 | -| lexer/ | lexer.c + token.c (+ .h) | 168+53+47 = 268 | +11 | 手写状态机, 58 Token 类型 | -| ast/ | ast.c + ast.h | 221+152 = 373 | -31 | 25 种 AST 节点, 工厂函数 (arg_names 扩展) | -| parser/ | parser.c + parser.h | 851+10 = 861 | +23 | 递归下降+Pratt, guard/pipe/插值去糖 | -| sema/ | sema.c + symbol.c (+ .h) | 871+148+63 = 1082 | +77 | 类型推断, can_implicit_convert, 命名参数重排 | -| codegen/ | codegen.c + target.c (+ .h) | 764+30+15 = 809 | -55 | LLVM IR 生成, coerce_int 隐式转换 | -| driver/ | main.c + error.c (+ .h) | 205+46+18 = 269 | +58 | 流水线串联, CreateProcess 链接 | -| util/ | arena.c + arena.h | 39+13 = 52 | 不变 | Bump allocator (8MB) | -| **实现总计** | | **~3,769 行** | **+434 vs v0.5** | | - -> 注意: codegen.c 从 824 行收缩到 764 行(-7.3%),说明新加入的 pipe/guard/插值等功能去糖后不需要 codegen 层改动。 - -### 1.3 核心类型系统变化 - -| 枚举 | v0.5 | v0.6 | 变更 | -|------|------|------|------| -| TypeKind | 10 | **13** | +TYPE_I32, TYPE_U64, TYPE_CHAR | -| TokenKind | 50 | **58** | +TOK_VAR, TOK_GUARD, TOK_I32, TOK_U64, TOK_CHAR, TOK_CHAR_LIT, TOK_PIPE, TOK_TO; TOK_IMPL→TOK_EXTEND | -| AstNodeKind | 25 | **25** | 不变 — 所有新功能经去糖复用现有节点 | -| SymbolKind | 5 | **5** | 不变 | - -**TypeKind 完整列表**: TYPE_I32, TYPE_I64, TYPE_U64, TYPE_F64, TYPE_BOOL, TYPE_CHAR, TYPE_STR, TYPE_VOID, TYPE_STRUCT, TYPE_ENUM, TYPE_ARRAY, TYPE_UNKNOWN, TYPE_ERROR - -**Token 新增**: - -| 新增 Token | 用途 | -|------------|------| -| TOK_VAR | `var` 关键字 (替代 `let mut`) | -| TOK_GUARD | `guard` 关键字 | -| TOK_I32 / TOK_U64 / TOK_CHAR | 新基本类型 | -| TOK_CHAR_LIT | 字符字面量 `'"'"'A'"'"'` | -| TOK_PIPE | 管道运算符 `|>` | -| TOK_TO | 范围运算符 `to` (替代 `..`) | -| TOK_EXTEND | `extend` 关键字 (替代 `impl`) | - -**AST 结构体扩展**: -- `AST_CALL_EXPR.call` 新增 `arg_names` 字段 — 支持命名参数 -- `AST_METHOD_CALL.method_call` 新增 `arg_names` 字段 — 支持命名参数 -- `AST_LITERAL_EXPR.literal` 新增 `lit_type` + union 扩展 — 支持 char 字面量 - -**Symbol 扩展**: -- `Symbol.param_names` 新增 — 支持命名参数匹配 - ---- - -## 2. 功能完成度总览 - -### 2.1 P0 (v0.1-v0.4) — 100% - -全 12 项保持完成状态。 - -### 2.2 P1 (v0.5) — 100% - -全 6 项保持完成,P1-5 (数组 struct 元素类型) 在本轮修复。 - -### 2.3 P0-扩展 (v0.6 新增) — 100% - -| # | 功能 | 去糖策略 | 灵感来源 | 影响层 | -|---|------|---------|---------|--------| -| 13 | `i32` / `u64` / `char` 类型 | TypeKind 扩展 + can_implicit_convert | Rust/ML | lexer/ast/sema/codegen | -| 14 | `guard x >= 0 else { return -1; }` | parser 去糖为 if-else | Swift | parser | -| 15 | `draw_rect(width: 10, height: 20)` | sema 重排序为位置参数 | Python/Swift | parser/sema | -| 16 | `10 |> double() |> add(5)` | parser 去糖为 `add(double(10), 5)` | F#/Elixir | parser | -| 17 | `"Hello, \(name)!"` | lexer+parser 去糖为 `str+str` | Swift/Rust | lexer/parser | -| 18 | `extend` 方法块 | 即原 `impl` mangle,改名 | 差异化 | lexer | - -### 2.4 语法差异化 (L 语言独有) - -| L 语法 | Rust 对应 | 理由 | -|--------|----------|------| -| `var` | `let mut` | 更简洁,2 字符 vs 6 字符 | -| `T[N]` | `[T; N]` | C 风格直觉,减少括号 | -| `to` | `..` | 明确语义 (省略终值 `to` vs 闭区间 `..=`) | -| `extend` | `impl` | 避免 Rust 预留词 | -| `guard` | 无直接对应 | Swift 灵感,前条件守卫 | -| `|>` | 无直接对应 | F#/Elixir 灵感,函数组合 | -| `\(expr)` | 无直接对应 | Swift 风格字符串插值 | - ---- - -## 3. Rust 对标缺失清单 - -### 3.1 已完成 - -| 特性 | 状态 | 版本 | -|------|------|------| -| 默认不可变 (let) / 可变 (var) | ✅ | v0.1-v0.6 | -| 复合赋值 | ✅ | v0.2 | -| for + range | ✅ | v0.3 | -| struct 具名域 | ✅ | v0.4 | -| impl/extend 方法 | ✅ | v0.5 | -| enum + match | ✅ | v0.5 | -| 类型别名 | ✅ | v0.5 | -| 数组固定大小 | ✅ | v0.5 | -| 数组 struct 元素类型 | ✅ | v0.6 | -| RAII 自动释放 | ✅ | v0.4 | -| 命名参数 | ✅ | v0.6 | -| 管道运算符 | ✅ | v0.6 | -| 字符串插值 | ✅ | v0.6 | -| guard 守卫语句 | ✅ | v0.6 | -| i32/u64/char 多种整数类型 | ✅ | v0.6 | - -### 3.2 缺失 (P2 — 中期, 按难度排序) - -| # | 功能 | 预计工时 | 优先级 | Rust 对应 | 说明 | -|---|------|---------|--------|----------|------| -| 19 | 表达式作为值 (块返回最后表达式) | 2-3 天 | **高** | 块是表达式 | sema/codegen 需处理块类型推断, 当前 block→void | -| 20 | 枚举关联数据 (ADT) | 2-3 天 | **高** | `enum Option` | 当前仅简单常量枚举, 需 payload + 模式匹配扩展 | -| 21 | `if let` / `while let` | 1 天 | 中 | `if let Some(x) = opt` | 基于枚举关联数据 | -| 22 | 模块系统 `mod` + `use` | 3-5 天 | **高** | `mod`, `use`, `pub` | 多文件编译, 符号可见性 | -| 23 | 泛型 (单态化) | 5-7 天 | 中 | `fn(x: T)` | sema 类型参数收集, codegen 复制 | -| 24 | trait / 接口 | 5-7 天 | 中 | `trait`, `impl Trait` | vtable 或单态化分派 | -| 25 | 引用/切片 | 7-10 天 | 中 | `&T`, `&[T]` | 需指针层次, 生命周期标注 | - -### 3.3 缺失 (P3 — 长期) - -| # | 功能 | 预计工时 | Rust 对应 | -|---|------|---------|----------| -| 26 | 所有权 / 借用检查 | 2-4 周 | borrow checker | -| 27 | 闭包 (lambda) | 3-5 天 | `|x| x+1` | -| 28 | 自举 (L 编译 L) | 4-6 周 | — | -| 29 | 标准库 (prelude) | 4-6 周 | std | - ---- - -## 4. 测试覆盖 - -| 测试文件 | 测试函数 | vs v0.5 | 覆盖范围 | -|---------|----------|---------|---------| -| test_lexer.c | 3 | 不变 | token 识别 | -| test_parser.c | 5 | 不变 | 语法解析基本路径 | -| test_sema.c | 24 | +3 | i32/u64/char 转换, named args, guard, 管道, 插值 | -| test_codegen.c | 10 | +1 | 隐式转换, 命名参数, i32/u64/char codegen | -| **单元合计** | **42** | **+4** | | -| 集成 .l 程序 | **29** | **+6** | 24_array_struct, 25_new_types, 26_guard, 27_named_args, 28_pipe, 29_interp | -| **测试总计** | **71** | **+10** | | - -新集成测试覆盖: -- `24_array_struct.l` — struct 数组 (P1-5 修复验证) -- `25_new_types.l` — i32/u64/char 类型 + 隐式转换 -- `26_guard.l` — guard 守卫语句 -- `27_named_args.l` — 命名参数任意顺序 -- `28_pipe.l` — 管道 |> 函数组合 -- `29_interp.l` — 字符串插值 - ---- - -## 5. 代码审查 — 风险区域 - -### 5.1 去糖策略的评价 - -v0.6 延续了 v0.5 的去糖哲学: pipe/guard/插值/named_args 全在 parser 层去糖为现有 AST 节点。优势是 sema/codegen 改动极小(codegen 甚至缩水 60 行),但代价是: - -1. **parser.c 进一步膨胀**: 825→851 行,去糖逻辑散落在 `parse_expr` 和 `parse_statement` 之间 -2. **错误消息质量下降**: 去糖后生成的 AST 丢失原始语法信息,错误报告指向去糖后的 if-else 而非原始 `guard` 语句 -3. **调试/IR 可读性**: 用户写 `10 |> double()` 但 IR 中看到的是 `double(10)`,不利于学习 - -**建议**: v0.7 考虑将 guard/match/named_args/pipe 去糖抽取为独立 desugar pass,在 parser 生成 AST 之后、sema 之前运行。这既能保持"去糖"优势,又能改善错误消息质量。 - -### 5.2 sema.c 持续膨胀 - -sema.c 从 809→871 行 (v0.5→v0.6),analyze_expr 仍然是单函数怪兽 (~380 行)。新增的 `can_implicit_convert()` 是好的模块化进步,但类型检查逻辑仍需拆分。 - -### 5.3 TypeKind 耦合未改善 - -TypeKind 从 10 增加到 13,修改范围涉及 7+ 文件。加新类型仍是全局搜索替换作业。 - -### 5.4 链接器变更风险 - -gcc→clang+lld 变更是正确方向,但 fallback 链 (clang→gcc) 增加了 CI 配置复杂度。自包含安装包 (39MB) 和 NSIS 安装包 (62MB) 是两个并行方案,后续需统一。 - ---- - -## 6. 技术债务更新 - -### 6.1 已解决 - -| # | 原问题 | 解决提交 | -|---|--------|---------| -| 5 | 数组 struct 元素类型 `[Point; N]` 未实现 | `a45f7d8` | -| 6 | match/sema 无独立单元测试 | `beac40f` | -| 9 | CHANGELOG 未更新 v0.4/v0.5 | `5a0bf60` + `2baf762` | - -### 6.2 当前债务 (优先级排序) - -| # | 问题 | 严重度 | 现状 | 备注 | -|---|------|--------|------|------| -| 1 | analyze_expr 膨胀 (~380 行) | **高** | 未修复, 反而增加 | sema.c 871 行, +62 vs v0.5 | -| 2 | parser.c 单文件 851 行 | **高** | 未修复, +26 行 | 去糖逻辑散落 | -| 3 | 去糖无独立 pass, 错误消息受损 | **中** | 需求显现 | v0.6 新暴露 | -| 4 | codegen.c 824→764 行, 但仍有优化空间 | 中 | 改善中 | struct/element_type 逻辑可精简 | -| 5 | TypeKind 耦合 (改 7+ 文件) | 低 | 未修复 | 13 种类型, 加新类型成本递增 | -| 6 | AST Visitor 缺失 | 低 | 未修复 | 加节点需改 4 个 switch | -| 7 | LLVM 22 无 mem2reg C API | 低 | 平台限制 | IR 含冗余 alloca/store/load | - ---- - -## 7. 基础设施变更 - -| 组件 | v0.5 | v0.6 | 影响 | -|------|------|------|------| -| 链接器 | GCC (外部依赖) | clang + lld (优先), fallback gcc | 用户需安装 LLVM 或将 ld.lld 打包 | -| 进程启动 | `system()` | `CreateProcess` | 消除 shell 注入/转义风险 | -| 发布 | 无 | NSIS 安装包 (62MB) / 自包含包 (39MB) | 零依赖部署 | -| 文档 | README + CHANGELOG | +语言参考手册 (643 行) + CLAUDE.md | 开发者友好 | - ---- - -## 8. 与 PRD 对照 - -PRD v0.1 设定了"学习编译器全流程"的短期目标。对照 PRD 中的非目标列表: - -| PRD 非目标 (v0.1 不做) | 当前状态 | -|------------------------|---------| -| 字符串类型 | ✅ v0.2 实现 `str` | -| 数组/切片/结构体 | ✅ v0.4-v0.5 实现 struct/array | -| 模块系统 | ❌ 仍缺失 | -| 泛型/trait | ❌ 仍缺失 | -| 模式匹配 | ✅ v0.5 match (简化) | -| 标准库 | ❌ 仍缺失 | -| 垃圾回收 | ❌ 不做 (采用 RAII) | - -v0.6 已大幅超出 v0.1 PRD 范围。建议更新 PRD 到 v0.6 以反映当前功能边界。 - ---- - -## 9. 推荐开发路线图 - -### v0.7 (短期, 2-3 天) - -1. **独立 desugar pass** — 将 guard/pipe/named_args 去糖从 parser 移到独立 pass,改善错误消息和 parser 复杂度 -2. **analyze_expr 拆分** — 按节点类型拆分为 4-6 个辅助函数 -3. **枚举关联数据 (ADT)** — `enum Option { Some(i64), None }`,打开类型安全编程新范式 -4. **表达式作为值** — `let x = if a { 1 } else { 2 }`,函数体最后表达式即返回值 - -### v0.8 (中期, 1 周) - -1. **模块系统** — `mod` + `use` + `pub`,多文件编译 -2. `if let` / `while let` — 简化 ADT 匹配 -3. 标准库起步: `io`, `convert`, `vec` - -### v0.9 (中期, 1-2 周) - -1. 泛型 (单态化) -2. trait / 接口 -3. AST Visitor 宏驱动 - ---- - -*本报告由 Codex 自动生成于 2026-06-06 00:50。自上次代码基线 `a15cd9d` (v0.5) 以来共 20 个提交, +2483/-163 行。P0 扩展 6 个新特性全部实现, 语法完成差异化定型, 链接器/进程启动基础设施升级。v0.7 应聚焦 parser 结构优化和枚举 ADT。* diff --git a/docs/analysis/architecture-analysis-report-2026-06-06-0653.md b/docs/analysis/architecture-analysis-report-2026-06-06-0653.md deleted file mode 100644 index e8a12af..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-06-0653.md +++ /dev/null @@ -1,267 +0,0 @@ -# L Language 架构分析报告 v0.6.1 - -> 日期: 2026-06-06 06:53 | 自动生成 | **小幅变更** -> 上次代码基线: `de91886` (2026-06-06 00:50 报告, v0.6) -> 当前 HEAD: `031dedf` refactor: 拆分 sema analyze_expr 为 9 个辅助函数 + 调度器 -> **版本: v0.6.1** (增量重构, 无功能变更) - ---- - -## 代码变更检查 - -``` -git log de91886..HEAD → 1 新提交, 2 文件变更, +635/-393 行 -``` - -自 v0.6 以来仅 1 个提交, 聚焦 sema 内部重构。**无新语言特性, 无新增 Token/AST 类型**。 - -| # | 提交 | 类别 | -|---|------|------| -| 21 | `031dedf` refactor: 拆分 sema analyze_expr | 重构 | - -**变更范围**: 仅 [sema.c](D:\Code\doing_exercises\programs\L Language\src\sema\sema.c) + 本报告。 - ---- - -## 1. 当前架构快照 (v0.6.1) - -### 1.1 编译流水线 - -``` -源码(.l) → Lexer(词法) → Parser(语法) → Sema(语义) → Codegen(LLVM IR) → Target(obj) → clang+lld 链接(.exe) - 58 Token 25 AST 节点 类型标注 LLVMModuleRef .o 文件 优先 clang→fallback gcc -``` - -流水线拓扑未变。与 v0.6 相同。 - -### 1.2 模块清单与行数 - -| 模块 | 文件 | 行数 | vs v0.6 | 职责 | -|------|------|------|---------|------| -| include/ | l_lang.h | 55 | 0 | TypeKind (13), SourceLoc, 公共类型 | -| lexer/ | lexer.c + token.c (+ .h) | 168+53+47 = 268 | 0 | 手写状态机, 58 Token 类型 | -| ast/ | ast.c + ast.h | 221+152 = 373 | 0 | 25 种 AST 节点, 工厂函数 | -| parser/ | parser.c + parser.h | 851+10 = 861 | 0 | 递归下降+Pratt, 去糖逻辑 | -| sema/ | sema.c + symbol.c (+ .h) | **806**+148+63 = 1017 | **-65** | 类型推断, 9 个辅助函数+调度器 | -| codegen/ | codegen.c + target.c (+ .h) | 764+30+15 = 809 | 0 | LLVM IR 生成 | -| driver/ | main.c + error.c (+ .h) | 205+46+18 = 269 | 0 | 流水线串联 | -| util/ | arena.c + arena.h | 39+13 = 52 | 0 | Bump allocator (8MB) | -| **实现总计** | | **~3,735 行** | **-34 vs v0.6** | | - -> sema.c: 871→806 行 (-7.5%), analyze_expr 从 ~380 行单体缩减为 15 行调度器 + 9 个独立辅助函数。 - -### 1.3 核心类型系统 - -| 枚举 | v0.6 | v0.6.1 | 变更 | -|------|------|--------|------| -| TypeKind | 13 | 13 | 0 | -| TokenKind | 58 | 58 | 0 | -| AstNodeKind | 25 | 25 | 0 | -| SymbolKind | 5 | 5 | 0 | - -无新增类型。重构不涉及枚举变更。 - ---- - -## 2. 本轮重构详解: sema analyze_expr 拆分 - -### 2.1 问题背景 - -v0.6 报告中标记为技术债务 #1: - -> analyze_expr 膨胀 (~380 行) | **高** | 未修复, 反而增加 | sema.c 871 行 - -### 2.2 拆分方案 - -原 `analyze_expr` 是一个 380+ 行的 `switch` 语句, 每种 AST 节点类型的检查逻辑直接内联。本轮重构将其拆分为: - -| # | 新函数 | 行号 | 职责 | -|---|--------|------|------| -| 1 | `analyze_ident_expr` | 58 | 标识符引用类型检查 | -| 2 | `analyze_unary_expr` | 85 | 一元运算 (`-`, `!`) 类型推导 | -| 3 | `analyze_binary_expr` | 107 | 二元运算类型检查 + promote | -| 4 | `analyze_call_expr` | 220 | 函数调用参数/返回值检查 | -| 5 | `analyze_field_access` | 253 | 结构体字段访问 | -| 6 | `analyze_struct_init` | 287 | 结构体字面量初始化 | -| 7 | `analyze_enum_variant` | 333 | 枚举变体初始化 | -| 8 | `analyze_index_expr` | 352 | 数组索引 | -| 9 | `analyze_method_call` | 373 | 方法调用 (extend mangle) | - -`analyze_expr` 现为 15 行调度器: - -```c -static void analyze_expr(AstNode* node, Scope* scope, ErrorList* errors, Arena* a) { - switch (node->kind) { - case AST_LITERAL_EXPR: break; - case AST_IDENT_EXPR: analyze_ident_expr(node, scope, errors, a); break; - case AST_UNARY_EXPR: analyze_unary_expr(node, scope, errors, a); break; - case AST_BINARY_EXPR: analyze_binary_expr(node, scope, errors, a); break; - case AST_CALL_EXPR: analyze_call_expr(node, scope, errors, a); break; - case AST_FIELD_ACCESS: analyze_field_access(node, scope, errors, a); break; - case AST_STRUCT_INIT: analyze_struct_init(node, scope, errors, a); break; - case AST_ENUM_VARIANT: analyze_enum_variant(node, scope, errors, a); break; - case AST_INDEX_EXPR: analyze_index_expr(node, scope, errors, a); break; - case AST_METHOD_CALL: analyze_method_call(node, scope, errors, a); break; - default: break; - } -} -``` - -### 2.3 效果评估 - -| 维度 | 重构前 | 重构后 | -|------|--------|--------| -| analyze_expr 行数 | ~380 | 15 (+ 9×30-60 行辅助函数) | -| 最大函数深度 | 4 层嵌套 switch | 1 层 switch 调度 | -| 每个 AST 类型可独立修改 | 否 | 是 | -| 新增 AST 类型成本 | 改动函数中部 | 新增辅助函数 + 添加 case | - ---- - -## 3. 功能完成度总览 (无变化) - -### 3.1 P0 (v0.1-v0.4) — 100% - -全 12 项保持完成状态。 - -### 3.2 P1 (v0.5) — 100% - -全 6 项保持完成。 - -### 3.3 P0-扩展 (v0.6) — 100% - -| # | 功能 | 状态 | -|---|------|------| -| 13 | i32 / u64 / char 类型 | ✅ | -| 14 | guard 守卫语句 | ✅ | -| 15 | 命名参数 | ✅ | -| 16 | 管道 `|>` | ✅ | -| 17 | 字符串插值 `\(expr)` | ✅ | -| 18 | extend 方法块 | ✅ | - -### 3.4 语法差异化 (无变化) - -| L 语法 | Rust 对应 | -|--------|----------| -| `var` | `let mut` | -| `T[N]` | `[T; N]` | -| `to` | `..` | -| `extend` | `impl` | -| `guard` | 无 (Swift 灵感) | -| `|>` | 无 (F#/Elixir 灵感) | -| `\(expr)` | 无 (Swift 灵感) | - ---- - -## 4. Rust 对标缺失清单 (无变化) - -### 4.1 已完成 - -共 15 项, 与 v0.6 报告相同。 - -### 4.2 缺失 (P2 — 中期) - -| # | 功能 | 预计工时 | 优先级 | Rust 对应 | -|---|------|---------|--------|----------| -| 19 | 表达式作为值 (块返回最后表达式) | 2-3 天 | **高** | 块是表达式 | -| 20 | 枚举关联数据 (ADT) | 2-3 天 | **高** | `enum Option` | -| 21 | `if let` / `while let` | 1 天 | 中 | 模式匹配简化 | -| 22 | 模块系统 `mod` + `use` | 3-5 天 | **高** | 多文件编译 | -| 23 | 泛型 (单态化) | 5-7 天 | 中 | `fn(x: T)` | -| 24 | trait / 接口 | 5-7 天 | 中 | `trait`, `impl Trait` | -| 25 | 引用/切片 | 7-10 天 | 中 | `&T`, `&[T]` | - -### 4.3 缺失 (P3 — 长期) - -| # | 功能 | 预计工时 | Rust 对应 | -|---|------|---------|----------| -| 26 | 所有权 / 借用检查 | 2-4 周 | borrow checker | -| 27 | 闭包 (lambda) | 3-5 天 | `|x| x+1` | -| 28 | 自举 | 4-6 周 | — | -| 29 | 标准库 | 4-6 周 | std | - ---- - -## 5. 测试覆盖 (无变化) - -| 测试文件 | 测试函数 | 覆盖范围 | -|---------|----------|---------| -| test_lexer.c | 3 | token 识别 | -| test_parser.c | 5 | 语法解析基本路径 | -| test_sema.c | 24 | 类型检查 + i32/u64/char + named args + guard + pipe + 插值 | -| test_codegen.c | 10 | 代码生成 + 隐式转换 | -| **单元合计** | **42** | | -| 集成 .l 程序 | **29** | | -| **测试总计** | **71** | | - ---- - -## 6. 代码审查 - -### 6.1 本轮重构评价 - -**正面**: -- analyze_expr 从 380+ 行缩减到 15 行调度器, 可维护性显著提升 -- sema.c 总行数下降 65 行 (871→806), 净减少 -- 每个 AST 类型的类型检查逻辑可独立修改/测试 -- 新增 AST 类型时只需新增辅助函数 + 添加 case, 改动范围可控 - -**保留问题**: -- 辅助函数间仍有重复模式 (如错误格式化), 但规模不大暂不构成负担 -- 辅助函数的参数签名统一 (`node, scope, errors, a`), 风格一致 - -### 6.2 其他无变化区域 - -- parser.c 仍是 851 行单文件, 去糖逻辑散落 (技术债务 #2) -- codegen.c 764 行, 未变化 -- TypeKind 耦合未改善 (技术债务 #4) -- AST Visitor 缺失 (技术债务 #5) - ---- - -## 7. 技术债务更新 - -### 7.1 已解决 - -| # | 原问题 | 解决提交 | -|---|--------|---------| -| 1 | **analyze_expr 膨胀 (~380 行)** | `031dedf` | - -### 7.2 当前债务 (优先级排序) - -| # | 问题 | 严重度 | 现状 | -|---|------|--------|------| -| 1 | parser.c 单文件 851 行 | **高** | 未修复 | -| 2 | 去糖无独立 pass, 错误消息受损 | **中** | 需求显现 | -| 3 | codegen.c 764 行, 仍有优化空间 | 中 | 未变化 | -| 4 | TypeKind 耦合 (改 7+ 文件) | 低 | 未修复 | -| 5 | AST Visitor 缺失 | 低 | 未修复 | -| 6 | LLVM 22 无 mem2reg C API | 低 | 平台限制 | - -> 从 v0.6 报告的 7 项债务 → 6 项, analyze_expr 膨胀已解决。 - ---- - -## 8. 推荐开发路线图 (与 v0.6 一致) - -### v0.7 (短期, 2-3 天) - -1. **独立 desugar pass** — 将 guard/pipe/named_args 去糖从 parser 移到独立 pass -2. **枚举关联数据 (ADT)** — `enum Option { Some(i64), None }` -3. **表达式作为值** — `let x = if a { 1 } else { 2 }` - -### v0.8 (中期, 1 周) - -1. 模块系统 — `mod` + `use` + `pub` -2. `if let` / `while let` -3. 标准库起步: `io`, `convert`, `vec` - -### v0.9 (中期, 1-2 周) - -1. 泛型 (单态化) -2. trait / 接口 -3. AST Visitor 宏驱动 - ---- - -*本报告由 Codex 自动生成于 2026-06-06 06:53。自上次代码基线 `de91886` (v0.6) 以来仅 1 个重构提交, 无功能变更。sema analyze_expr 拆分为 9+1 函数结构, 技术债务从 7 项降至 6 项。* diff --git a/docs/analysis/architecture-analysis-report-2026-06-06-1133.md b/docs/analysis/architecture-analysis-report-2026-06-06-1133.md deleted file mode 100644 index 1e6920f..0000000 --- a/docs/analysis/architecture-analysis-report-2026-06-06-1133.md +++ /dev/null @@ -1,266 +0,0 @@ -# L Language 架构分析报告 v0.6.1 (复查) - -> 日期: 2026-06-06 11:33 UTC | 自动生成 | **无代码变更** -> 上次报告基线: `031dedf` (2026-06-06 06:53 UTC, v0.6.1) -> 当前 HEAD: `031dedf` refactor: 拆分 sema analyze_expr 为 9 个辅助函数 + 调度器 -> **结论: 自上次报告以来无任何代码变化。** - ---- - -## 0. 代码变更检查 - -``` -git diff 031dedf..HEAD → (空) -``` - -**零提交, 零文件变更, 零行变化。** 上次报告距今约 4.5 小时,HEAD 未移动。 - -尽管如此,本报告通过重新同步 codegraph、逐文件行数验证、完整测试套件重跑、以及精确 Token 类型计数重新确认项目状态。发现一处数据修正: Token 类型实际为 67 种(上次报告误记为 58)。 - ---- - -## 1. 当前架构快照 - -### 1.1 编译流水线 - -``` -源码(.l) → Lexer(词法) → Parser(语法+去糖) → Sema(语义) → Codegen(LLVM IR) → Target(obj) → clang+lld 链接(.exe) - 67 Token 25 AST 节点 类型标注 LLVMModuleRef .o 文件 优先clang→fallback gcc -``` - -### 1.2 模块清单与精确行数 - -| 模块 | 文件 | 行数 | 职责 | -|------|------|------|------| -| include/ | l_lang.h | 55 | TypeKind (13), SourceLoc | -| lexer/ | lexer.c (168) + token.c (53) + .h (47+10) | 278 | 手写状态机, 67 Token | -| ast/ | ast.c (221) + ast.h (152) | 373 | 25 种 AST + 工厂函数 | -| parser/ | parser.c (851) + parser.h (10) | 861 | 递归下降+Pratt, 去糖逻辑 | -| sema/ | sema.c (806) + symbol.c (148) + .h (9+63) | 1,026 | 类型推断, 9+1 函数结构 | -| codegen/ | codegen.c (764) + target.c (30) + .h (12+15) | 821 | LLVM IR 生成 + 目标输出 | -| driver/ | main.c (205) + error.c (46) + .h (18) | 269 | 流水线串联 + 错误报告 | -| util/ | arena.c (39) + arena.h (13) | 52 | Bump allocator (8MB) | -| **合计** | | **~3,735** | | - -### 1.3 核心类型枚举(数据修正) - -| 枚举 | 数量 | 来源文件 | 备注 | -|------|------|----------|------| -| **TokenKind** | **67** | token.h:5 | **上次报告误记为 58,已修正** | -| TypeKind | 13 | l_lang.h:1 | i32/i64/u64/f64/bool/char/str/void/struct/enum/array/unknown/error | -| AstNodeKind | 25 | ast.h:1 | 含 impl/method_call/array_assign/match 脱糖节点 | -| SymbolKind | 5 | symbol.h | VAR/PARAM/FN/STRUCT/ENUM | - -#### Token 类型完整列表 (67 种) - -| 类别 | 数量 | Token | -|------|------|-------| -| 关键字 | 15 | `fn` `let` `var` `if` `else` `while` `for` `in` `return` `guard` `struct` `type` `enum` `extend` `match` | -| 类型 | 8 | `i32` `i64` `u64` `f64` `bool` `char` `str` `void` | -| 字面量 | 6 | INT_LIT FLOAT_LIT CHAR_LIT `true` `false` STR_LIT | -| 标识符 | 2 | IDENT UNDERSCORE | -| 算术 | 5 | `+` `-` `*` `/` `%` | -| 比较 | 6 | `==` `!=` `<` `>` `<=` `>=` | -| 逻辑 | 4 | `&&` `\|\|` `\|`(pipe) `!` | -| 箭头 | 3 | `->` `to` `=>` | -| 复合赋值 | 4 | `+=` `-=` `*=` `/=` | -| 括号 | 4 | `(` `)` `{` `}` | -| 方括号 | 2 | `[` `]` | -| 其他分隔 | 4 | `,` `:` `;` `=` | -| 特殊 | 4 | `.` `::` EOF ERROR | - -**关键增长点** (vs v0.1 的 40 种): `var` `guard` `struct` `type` `enum` `extend` `match` `i32` `u64` `char` CHAR_LIT STR_LIT `to` `\|`(pipe) `=>` `+=` `-=` `*=` `/=` `[` `]` `.` `::` — 共 27 种新增。 - ---- - -## 2. 已实现功能总览(无变化) - -### 2.1 版本演进路线 - -| 版本 | 日期 | 核心功能 | Token | AST | 测试 | -|------|------|----------|-------|-----|------| -| v0.1 | 06-05 | 基础类型+控制流+函数 | 40 | 14 | 65 | -| v0.2 | 06-05 | let mut + str + 复合赋值 | +4 | +1 | +? | -| v0.3 | 06-05 | for..in range (去糖) | +2 | +1 | +2 集成 | -| v0.4 | 06-05 | struct + 字段访问 + RAII | +5 | +4 | +3 集成 | -| v0.5 | 06-05 | type/impl/enum/array/match | +7 | +5 | +6 集成 | -| v0.6 | 06-05 | i32/u64/char + guard + named args + pipe + 插值 | +9 | 0 | +4 集成 | -| v0.6.1 | 06-06 | sema analyze_expr 拆分重构 | 0 | 0 | 0 | - -### 2.2 P0 基础功能 (v0.1→v0.4) — 100% - -| # | 功能 | 版本 | 实现方式 | -|---|------|------|----------| -| 1 | 词法分析 + 注释跳过 | v0.1 | 手写状态机 | -| 2 | Pratt 表达式解析 (9 级优先级) | v0.1 | 递归下降+Pratt | -| 3 | i64/f64/bool/void 基本类型 | v0.1 | 直接 LLVM 类型映射 | -| 4 | let 不可变变量 + 类型推断 | v0.1 | sema 从初始值推断 | -| 5 | if/else 控制流 | v0.1 | LLVM cond_br | -| 6 | while 循环 | v0.1 | LLVM 三 BB 循环 | -| 7 | 函数定义+调用+递归 | v0.1 | LLVM function/call | -| 8 | 斐波那契程序通过 | v0.1 | 递归版 fib(10) = 55 | -| 9 | let mut + 赋值 | v0.2 | alloca+store/load | -| 10 | str 类型 + 拼接 | v0.2 | LLVM i8* + concat helper | -| 11 | for..in range (去糖为 while) | v0.3 | parser 去糖 | -| 12 | 结构体声明+初始化+字段访问 | v0.4 | LLVM struct GEP | - -### 2.3 P1 类型与抽象 (v0.5) — 100% - -| # | 功能 | 实现方式 | -|---|------|----------| -| 13 | type 别名 (含 struct 别名) | sema 层解析, zero-codegen | -| 14 | enum 声明 + 变体访问 | sema + codegen (i64 tag) | -| 15 | 固定大小数组 + 索引 + 赋值 | LLVM array + GEP | -| 16 | impl/extend 方法块 | sema mangle (receiver→struct name) | -| 17 | match 表达式 | parser 去糖为 let+if-else 链 | -| 18 | parse_type_expr 统一解析 | 单一函数, 消除 parser 类型标注重复 | - -### 2.4 P0-扩展 (v0.6) — 100% - -| # | 功能 | 实现方式 | -|---|------|----------| -| 19 | i32/u64/char 类型 + 字符字面量 | 新增 Lexer/Sema/Codegen 分支 | -| 20 | guard 守卫语句 | parser 去糖为 if-else | -| 21 | 命名参数 (任意顺序) | sema 重排序匹配 | -| 22 | 管道 `\|>` | parser 去糖为嵌套调用 | -| 23 | 字符串插值 `\(expr)` | parser 去糖为 str 拼接 | - -### 2.5 语法差异化 (L vs Rust) - -| L 语法 | Rust 对应 | 设计意图 | -|--------|----------|----------| -| `var` | `let mut` | 更短, 2 tokens→1 | -| `T[N]` | `[T; N]` | C 风格数组直觉 | -| `to` | `..` | 避免与浮点 `.` 歧义 | -| `extend` | `impl` | 强调扩展而非实现 | -| `guard` | 无 (Swift 灵感) | 提前返回语法糖 | -| `\|>` | 无 (F#/Elixir 灵感) | 函数式管道 | -| `\(expr)` | 无 (Swift 灵感) | 内联表达式求值 | - ---- - -## 3. Rust 对标缺失清单 - -### 3.1 已完成 (19 项) - -全部 P0 + P1 + P0-扩展功能已实现,覆盖 Rust 的基础/中级语法元素。 - -### 3.2 P2 缺失(中期 — 预计 2-4 周) - -| # | 功能 | 预计工时 | 优先级 | Rust 对应 | -|---|------|---------|--------|----------| -| F1 | **枚举关联数据 (ADT)** | 2-3 天 | ⭐⭐⭐ | `enum Option { Some(T), None }` | -| F2 | **表达式作为值** | 2-3 天 | ⭐⭐⭐ | 块返回最后表达式 | -| F3 | **模块系统** `mod` + `use` | 3-5 天 | ⭐⭐ | 多文件编译 + 可见性 | -| F4 | **`if let` / `while let`** | 1-2 天 | ⭐⭐ | 模式匹配简化语法糖 | -| F5 | **泛型 (单态化)** | 5-7 天 | ⭐⭐ | `fn(x: T) → T` | -| F6 | **trait / 接口** | 5-7 天 | ⭐⭐ | 抽象行为定义 | -| F7 | **引用 / 切片** | 7-10 天 | ⭐ | `&T`, `&[T]` (不含 borrow check) | -| F8 | **闭包 (lambda)** | 3-5 天 | ⭐ | `\|x\| x + 1` | - -### 3.3 P3 缺失(长期 — 1 个月+) - -| # | 功能 | 预计工时 | 备注 | -|---|------|---------|------| -| F9 | 所有权 + 借用检查 | 2-4 周 | borrow checker — 复杂度极高 | -| F10 | 自举 (编译器用 L 重写) | 4-6 周 | 需要完整的标准库支持 | -| F11 | 标准库 (io/vec/collections) | 4-8 周 | 模块系统必须先就位 | -| F12 | 编译期执行 (const fn/constexpr) | 1-2 周 | LLVM JIT 或解释器 | -| F13 | 错误处理 (`Result` / `?` 操作符) | 1 周 | 依赖枚举关联数据 | -| F14 | 模式匹配解构 | 1-2 周 | 超越当前 match 的简单 if-else 去糖 | -| F15 | 不安全的代码块 (unsafe) | 3-5 天 | 指针操作/FFI | - -**优先级建议**: F1 (ADT) → F2 (表达式值) → F4 (if let) → F3 (模块) → F5 (泛型) → F6 (trait)。ADT 和表达式值是最具语言表现力增益的下一步。 - ---- - -## 4. 代码审查(无变化, 与前次一致) - -### 4.1 sema analyze_expr 拆分(v0.6.1 重构) - -**状态**: 已完成且经验证稳定。`analyze_expr` 从 380+ 行缩减为 15 行调度器 + 9 个辅助函数。 - -| 辅助函数 | 职责 | -|----------|------| -| `analyze_ident_expr` | 标识符引用类型检查 | -| `analyze_unary_expr` | `-` `!` 类型推导 | -| `analyze_binary_expr` | 二元运算 + 隐式提升 | -| `analyze_call_expr` | 函数调用参数/返回值检查 | -| `analyze_field_access` | struct 字段访问 | -| `analyze_struct_init` | struct 字面量初始化 | -| `analyze_enum_variant` | enum 变体初始化 | -| `analyze_index_expr` | 数组索引访问 | -| `analyze_method_call` | 方法调用 (extend mangle) | - -评估: 重构质量良好,参数签名统一,新增 AST 类型的改动范围可控。74 个 sema 测试断言全部通过。 - -### 4.2 持续关注问题 - -| 问题 | 位置 | 风险 | -|------|------|------| -| parser.c 单文件 851 行 | parser.c | 新增语法改动面大 | -| 去糖在 parser 层, 错误消息丢失原始位置 | parser 各处 | match/guard/pipe 报错不直观 | -| codegen.c 764 行 | codegen.c | 结构体+枚举+方法生成耦合 | - ---- - -## 5. 测试覆盖(全部通过) - -| 测试文件 | 测试函数 | 断言 | 覆盖范围 | -|---------|----------|------|---------| -| test_lexer.c | 3 | 41 | 基础 token、关键字、运算符 | -| test_parser.c | 5 | 15 | 函数解析、表达式、if/while | -| test_sema.c | 24 | 74 | 类型错误、struct/enum/array/match/method/new_types | -| test_codegen.c | 10 | 28 | 函数/if/while/binary/struct/enum/array/method/match | -| **单元断言** | **42** | **158** | | -| 集成 .l 程序 | **29** | — | 全特性端到端, 01~29 | -| **总计** | **71** | **158+** | | - -**验证结果**: 全部 158 断言通过,零失败。构建零警告(`-Wall -Wextra`)。 - ---- - -## 6. 技术债务 - -| # | 问题 | 严重度 | 现状 | 建议 | -|---|------|--------|------|------| -| 1 | parser.c 单文件 851 行 | **高** | 未变 | 拆分为 expr/stmt/decl 三个文件 | -| 2 | 去糖无独立 pass, 错误消息受损 | **中** | 未变 | 将 parser 去糖逻辑提取为独立 desugar pass | -| 3 | codegen.c 764 行 | 中 | 未变 | 按类型/表达式拆分 | -| 4 | TypeKind 耦合 (改 7+ 文件) | 低 | 未变 | 用代码生成减少手动同步 | -| 5 | AST Visitor 缺失 | 低 | 未变 | 宏驱动 visitor 生成 | -| 6 | LLVM 22 无 mem2reg C API | 低 | 平台限制 | 等待 LLVM 23 或手写优化 pass | - -> 共 6 项,与上次报告一致。analyze_expr 膨胀已在 v0.6.1 解决。 - ---- - -## 7. 推荐开发路线图 - -### v0.7 (短期, 2-3 天) — 语言表现力 - -1. **枚举关联数据 (ADT)** — `enum Option { Some(i64), None }` — 解锁 Result/Option 模式 -2. **表达式作为值** — `let x = if cond { 1 } else { 2 }` — 一致性提升 -3. **`if let` 语法糖** — `if let Some(v) = opt { ... }` — 在 ADT 之后自然跟进 - -### v0.8 (中期, 1 周) — 工程化 - -1. **独立 desugar pass** — 解决技术债务 #2,改善 match/guard/pipe 错误消息 -2. **模块系统** — `mod` + `use` + `pub` — 多文件编译 -3. 标准库起步: `io`, `convert`, `collections/vec` - -### v0.9 (中期, 1-2 周) — 类型系统 - -1. 泛型 (单态化) -2. trait / 接口 -3. AST Visitor 宏驱动 - ---- - -## 8. 修正说明 - -- **TokenKind 计数**: 上次报告 (v0.6.1) 记 58 种,实际为 **67 种**。本次通过逐行读取 token.h 精确计数修正。58 是 v0.1 报告的近似值延续。AGENTS.md 中的 "50 Token 类型" 也已过期。 - ---- - -*本报告由 Codex 自动生成于 2026-06-06 11:33 UTC。自上次代码基线 `031dedf` (v0.6.1) 以来零变更。构建和完整测试套件重新验证通过 (158 断言, 0 失败)。*