4.8 KiB
4.8 KiB
AGENTS.md
本文件为 L Language 项目的 Codex 上下文文件,定义项目架构、构建命令、核心 API 和开发约定。
项目概述
L Language v0.5 — C17 实现的静态类型编译型语言,Rust 风格语法,LLVM 22.x 后端。5 阶段流水线:词法 → 语法 → 语义 → IR → 可执行文件。38 单元测试 + 23 集成程序。
目录结构
├── include/l_lang.h TypeKind(10), SourceLoc 公共头文件
├── src/
│ ├── lexer/ {token,lexer} 手写状态机, 50 Token 类型
│ ├── parser/ parser.c 递归下降 + Pratt, 825 行
│ ├── ast/ ast.{c,h} 25 种 AST 节点 + 工厂函数
│ ├── sema/ {symbol,sema} 作用域链 + 类型推断 + impl mangle
│ ├── codegen/{codegen,target} LLVM-C API → 目标代码, 824 行
│ ├── driver/ {main,error} 入口 + 命令行解析 + 错误报告
│ └── util/ arena.c Bump allocator (8MB)
├── test/
│ ├── test_{lexer,parser,sema,codegen}.c 单元测试 (38)
│ └── programs/*.l 集成测试 (23)
└── docs/
├── PRD.md 产品需求文档 (v0.1)
├── analysis/ 架构分析报告
└── architecture-improvements.md
构建命令
cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH="D:/settings/Language/LLVM"
mingw32-make -j4
mingw32-make l_lang # 仅编译器
编译流水线
源码(.l) → Lexer → Parser → Sema → Codegen → Target(obj) → GCC 链接(.exe)
50 Tok 25 AST 类型标注 LLVM IR .o 可执行文件
核心 API
// lexer.h — 词法分析
Token* lex(Arena* a, const char* source, const char* filename,
size_t* count, ErrorInfo* error);
// parser.h — 语法分析
AstNode* parse(Arena* a, const Token* tokens, size_t count,
const char* filename, ErrorInfo* error);
// sema.h — 语义分析
void sema_analyze(AstNode* ast, ErrorList* errors, Arena* arena);
// codegen.h — IR 生成
LLVMModuleRef codegen_module(AstNode* ast, const char* module_name,
const char** error_msg);
类型系统
| L 类型 | LLVM 类型 | TypeKind |
|---|---|---|
| i64 | LLVMInt64Type() | TYPE_I64 |
| f64 | LLVMDoubleType() | TYPE_F64 |
| bool | LLVMInt1Type() | TYPE_BOOL |
| str | LLVMInt8PtrType() | TYPE_STR |
| void | LLVMVoidType() | TYPE_VOID |
| struct | LLVMStructType() | TYPE_STRUCT |
| enum | (i64 常量) | TYPE_ENUM |
| [T; N] | LLVMArrayType() | TYPE_ARRAY |
运算符优先级 (Pratt)
| 优先级 | 运算符 |
|---|---|
| 70 (最高) | -(一元负) ! |
| 60 | * / % |
| 50 | + - |
| 40 | == != < > <= >= |
| 30 | && |
| 20 | || |
关键架构决策
| 决策 | 说明 |
|---|---|
| impl mangle | sema 将 impl S { fn f } 改名为 S$f,codegen 零修改 |
| match 脱糖 | parser 将 match 转为 let+if-else 链,sema/codegen 完全复用 |
| for 脱糖 | for 转为 let mut+while+assign |
| 复合赋值脱糖 | x += 1 → x = x + 1 |
| parse_type_expr 统一 | 所有类型标注经同一函数解析 |
| RAII cleanup_list | 作用域级自动 free,dynamic resize |
版本状态
| 指标 | v0.5 |
|---|---|
| 实现代码 | ~3,336 行 |
| Token 类型 | 50 |
| AST 节点 | 25 |
| TypeKind | 10 |
| SymbolKind | 5 (VAR/PARAM/FN/STRUCT/ENUM) |
| P0 完成度 | 4/4 (100%) |
| P1 完成度 | 6/6 (100%) |
| 已知技术债务 | 10 项 |
开发约定
- 语言标准: C17,
-Wall -Wextra -g,零警告 - 内存管理: Token/AST/符号表均在 arena 分配,禁止 malloc/free 散落
- 错误消息: 中文,格式
文件名:行号:列号: 描述 - 平台: Windows 11 + MinGW-w64,链接器用 gcc(非 clang)
- LLVM 路径:
D:\settings\Language\LLVM(v22.1.7,C API) - 去糖优先: 复杂语法优先在 parser 层去糖为简单原语,减少 sema/codegen 改动
- 新增功能流程: lexer token → ast 节点 → parser 解析 → sema 检查 → codegen 生成 → 测试
测试
./l_lang_lexer_test.exe # 3 测试
./l_lang_test.exe # 5 测试
./l_lang_sema_test.exe # 21 测试
./l_lang_codegen_test.exe # 9 测试
# 集成测试
Get-ChildItem test/programs/*.l | ForEach-Object {
./l_lang.exe $_.FullName -o test.exe
./test.exe
}
当前技术债务 (优先级排序)
- 高: analyze_expr 膨胀 (350+ 行),match/sema 无单元测试
- 中: parser.c 825 行单文件,codegen.c 824 行单文件,match 脱糖在 parser 非独立 pass,
[Point; N]未实现 - 低: TypeKind 耦合 (改 7+ 文件),AST Visitor 缺失,CHANGELOG 未更新 v0.4/v0.5,LLVM 22 无 mem2reg C API