Files
l-language/docs/analysis/architecture-analysis-report-2026-06-05-1308.md
T
Serendipity 4046ab1875 refactor: tok_is_type 统一 + 架构改进文档
- parser.c: 删除重复的is_type_token, 统一使用token.c的tok_is_type
- docs/architecture-improvements.md: TypeKind解耦/Visitor/SourceLoc/去糖方案
2026-06-05 13:13:51 +08:00

428 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.1v0.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: 中期 (35 天/项)
| # | 功能 | 改动范围 | 学习价值 | 状态 |
|---|------|---------|---------|------|
| 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: 中后期 (12 周/项)
| # | 功能 | 学习价值 | 状态 |
|---|------|---------|------|
| 11 | 模块系统 `mod` + `use` | 单文件→多文件编译 | 待实施 |
| 12 | 自定义 IR 层 (三地址码/SSA) | 编译器核心抽象 | 待实施 |
| 13 | 泛型 (单态化) | Rust 零成本抽象基石 | 待实施 |
| 14 | 解释器模式 (walk AST) | 快速验证语义 | 待实施 |
### P3: 长期 (24 周/项)
| # | 功能 | 备注 | 状态 |
|---|------|------|------|
| 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 目标 (下一迭代, 23 天)
| 优先级 | 功能 | 预计工时 | 依赖/备注 |
|--------|------|---------|----------|
| **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 表达式 | 23 天 |
| P1 | 类型别名 | 0.5 天 |
| P2 | 自定义 IR 层 | 35 天 |
| P2 | 模块系统 | 35 天 |
| P3 | 泛型 (单态化) | 57 天 |
| P3 | trait / 接口 | 57 天 |
---
## 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 单元测试覆盖。*