From 376738d7fcc365562ed160093239eefedc10b97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Sun, 7 Jun 2026 12:40:43 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=85=A8=E9=9D=A2=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E4=B8=8E=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=20(2026-06-07)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/architecture-review-2026-06-07.md | 181 +++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 docs/architecture-review-2026-06-07.md diff --git a/docs/architecture-review-2026-06-07.md b/docs/architecture-review-2026-06-07.md new file mode 100644 index 0000000..a6ccb99 --- /dev/null +++ b/docs/architecture-review-2026-06-07.md @@ -0,0 +1,181 @@ +# L Language 架构与代码审查报告 + +> 日期: 2026-06-07 | 全面手动审查 | HEAD: `35e2691` + +## 1. 项目概览 + +| 指标 | 数值 | +|------|------| +| 版本 | v0.6 | +| 语言 | C17 (`-Wall -Wextra -g`) | +| 后端 | LLVM 22.x C API | +| 链接器 | clang+lld (fallback gcc) | +| 平台 | Windows 11 + MinGW-w64 | +| 总源码行数 | 5,039 (32 .c + 20 .h) | +| 单元测试 | 197 断言 (4 文件, 42 测试函数) | +| 集成测试 | 36 程序 | +| 构建警告 | **0** | + +## 2. 编译流水线 + +``` +源码(.l) → Lexer → Parser(+Desugar) → Sema → Codegen → Target → clang+lld → .exe + 72 Token 27 AST 节点 类型标注 LLVM IR .o 文件 可执行文件 +``` + +### 2.1 各阶段文件清单 + +| 阶段 | 文件 | 行数 | 职责 | +|------|------|------|------| +| **include/** | l_lang.h | 55 | TypeKind 枚举 (14), TypeInfo, SourceLoc | +| **lexer/** | lexer.c (180) + token.c (60) + .h (55+13) | 308 | 手写状态机, 72 Token 类型 | +| **parser/** | parser.c (564) + expr.c (484) + desugar.c (109) + parse_internal.h (71) + .h (13+30) | 1,271 | 递归下降+Pratt, 5 种去糖独立化 | +| **ast/** | ast.c (284) + ast.h (183) + visit.c (17) + visit.h (25) | 509 | 27 AST 节点 + 工厂函数 + Visitor dispatch | +| **sema/** | typeck.c (652) + sema.c (500) + symbol.c (172) + type_table.c (36) + .h (57+84+22) | 1,535 | 类型推断+检查, 泛型单态化, 数据驱动类型表 | +| **codegen/** | codegen.c (453) + cg_expr.c (440) + target.c (35) + .h (83+15+21) | 1,047 | LLVM IR 生成, 目标输出, 符号表 | +| **driver/** | main.c (232) + error.c (49) + .h (26) | 307 | 流水线串联, 错误报告 | +| **util/** | arena.c (45) + arena.h (17) | 62 | Bump allocator (8MB) | + +### 2.2 文件大小分布 + +所有核心 .c 文件均 ≤ 652 行(限制 800): + +``` +typeck.c 652 ████████████████████ +parser.c 564 █████████████████ +sema.c 500 ████████████████ +expr.c 484 ███████████████ +codegen.c 453 ██████████████ +cg_expr.c 440 ██████████████ +``` + +## 3. 类型系统 + +### 3.1 Token 类型: 72 种 + +| 类别 | 数量 | 示例 | +|------|------|------| +| 关键字 | 20 | fn, let, var, if, else, while, for, in, return, guard, struct, type, enum, extend, match, pub, mod, use, trait, Self | +| 类型 | 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 | && \|\| \|> ! | +| 箭头 | 3 | -> to => | +| 复合赋值 | 4 | += -= *= /= | +| 括号 | 4 | ( ) { } | +| 方括号 | 2 | [ ] | +| 分隔符 | 4 | , : ; = | +| 特殊 | 4 | . :: EOF ERROR | + +### 3.2 TypeKind: 14 种 + +- 内置: i32, i64, u64, f64, bool, char, str, void +- 复合: struct, enum, array +- 内部: GENERIC (泛型参数), UNKNOWN (未推断), ERROR (类型错误) + +### 3.3 TypeTable 数据驱动 + +`type_table.c` 统一管理类型元数据(promote_rank, bit_width, is_signed, is_numeric),promote/can_implicit_convert/is_numeric/is_comparable 全部查表。新增类型只需在 TABLE[] 加一行。 + +## 4. AST 节点: 27 种 + +| 类别 | 节点 | +|------|------| +| 程序结构 | PROGRAM, FUNCTION, PARAMETER, BLOCK, MOD_DECL, USE_DECL | +| 语句 | LET_STMT, ASSIGN_STMT, IF_STMT, WHILE_STMT, RETURN_STMT, EXPR_STMT, ARRAY_ASSIGN_STMT | +| 表达式 | BINARY_EXPR, UNARY_EXPR, CALL_EXPR, LITERAL_EXPR, IDENT_EXPR, FIELD_ACCESS, INDEX_EXPR, METHOD_CALL | +| 类型/声明 | STRUCT_DECL, STRUCT_INIT, TYPE_ALIAS, ENUM_DECL, ENUM_VARIANT, IMPL_BLOCK, TRAIT_DECL | + +新增节点流程:ast.h 加枚举 → ast.c 加工厂 → typeck.c 的 analyze_expr_init() 加一行 handler → 编译器检查未初始化的函数指针。 + +## 5. 已实现功能 + +### 5.1 P0 基础 (10 项) +基础类型 (i64/f64/bool/void), 控制流 (if/else/while/return), let/var 变量, str 类型+拼接, for..in 去糖, struct 声明+初始化+字段访问 + +### 5.2 P1 类型与抽象 (5 项) +type 别名, enum 声明+变体, 固定数组+索引, impl/extend 方法块, match 去糖 + +### 5.3 P0 扩展 (5 项) +i32/u64/char, guard 守卫, 命名参数, 管道 |>, 字符串插值 + +### 5.4 P2 (6 项) — 全部完成 +ADT 枚举关联数据, 表达式作为值 (if-expr), if let, 模块系统 (mod), 泛型单态化, trait 接口 + +## 6. 测试覆盖 + +| 测试文件 | 函数 | 断言 | 覆盖范围 | +|----------|------|------|----------| +| test_lexer.c | 3 | 41 | 基础 token, 关键字, 运算符 | +| test_parser.c | 20 | 54 | 全语法特性 | +| test_sema.c | 24 | 74 | 类型检查, 错误检测 | +| test_codegen.c | 10 | 28 | LLVM IR 生成验证 | +| **单元合计** | **57** | **197** | | +| programs/*.l | — | 36 | 端到端集成 | + +全部通过,零失败,零构建警告。 + +## 7. 近期重构成果 + +| 重构 | 效果 | +|------|------| +| parser.c 1211→564+484+109 | 表达式/语句/去糖分离 | +| sema.c 1129→500+652 | 入口/表达式检查分离 | +| codegen.c 947→453+440 | 语句/表达式生成分离 | +| desugar.c 独立化 | match/guard/for/if-let/复合赋值 5 种去糖提取 | +| TypeTable 数据驱动 | promote/convert/numeric 查表,新增类型 7→3-4 文件 | +| AST Visitor dispatch | analyze_expr switch→vtable,新增节点加一行 | +| error.c arena 化 | 消除项目唯一 malloc/realloc/strdup | +| test_parser.c 5→20 函数 | 15→54 断言,覆盖全语法特性 | + +## 8. 代码质量 + +### 8.1 优点 + +- **零编译警告**: `-Wall -Wextra` 干净 +- **全测试通过**: 197 单元 + 36 集成 +- **内存管理统一**: 全部通过 Arena bump allocator,无散落 malloc/free(除 driver 文件读取) +- **文件大小受控**: 所有核心 .c ≤ 652 行 +- **模块边界清晰**: 5 阶段流水线,内部头文件隔离实现细节 +- **新增类型/节点低摩擦**: TypeTable 一行注册,Visitor 一行注册 +- **去糖独立化**: 5 种语法糖从 parser 内联提取为纯函数,可独立测试 +- **LLVM 22 适配**: 显式 Context 管理,CreateProcess 替代 system() + +### 8.2 待改进 + +| # | 严重度 | 位置 | 问题 | 建议 | +|---|--------|------|------|------| +| 1 | **中** | parser/expr.c:195, parser/parser.c:497,520 | 3 处 `sprintf` 未使用 `snprintf` | 替换为 snprintf,防止标识符过长溢出 | +| 2 | **中** | parser/parser.c:535 | `use` 语句跳过解析,符号导入未实现 | 实现 use 语句的符号导入语义 | +| 3 | **低** | main.c:192 | `strcpy(p, ld_args[i])` | 用 memcpy+长度检查替代 | +| 4 | **低** | codegen/cg_expr.c | 表达式生成仍用 switch (440 行) | 后续可转为 Visitor dispatch | +| 5 | **低** | sema/typeck.c:652 | typeck.c 略超 650 行 | 泛型单态化可提取为 mono.c | +| 6 | **信息** | 全局 | 固定数组 [64]/[256] 带边界检查 | 当前均有 if (n>=N) 保护,长期可换动态分配 | + +## 9. 安全审计 + +| 检查项 | 状态 | +|--------|------| +| 缓冲区溢出 | ✅ 全部使用 snprintf(sizeof) 或有边界检查 | +| 格式化字符串 | ✅ 无用户输入直接作为格式串 | +| 空指针解引用 | ✅ 所有 arena_alloc 返回值有 NULL 检查 | +| 内存泄漏 | ✅ Arena bump allocator 统一释放 | +| 栈溢出 | ✅ MAX_PARSE_DEPTH/MAX_CODEGEN_DEPTH 限制递归 | +| LLVM 验证 | ✅ codegen_module 调用 LLVMVerifyModule | + +## 10. 架构评估 + +**评分: 8.5/10** + +- 流水线设计清晰,每阶段独立可测试 +- 近期重构显著改善模块化(文件拆分、去糖独立、数据驱动类型表) +- AST 节点新增流程标准化(枚举→工厂→handler 注册) +- 测试覆盖充足(197 单元 + 36 集成) +- 剩余问题均为中低优先级,无阻塞性缺陷 +- 主要不足:codegen 表达式层仍为巨型 switch、use 语句未实现 + +--- + +*本报告手动审查生成于 2026-06-07。*