Files
l-language/README.md
T
Serendipity 3b7bab1e1b feat: L Language v0.1 编译器完整实现
5 阶段编译流水线: 词法分析 → 语法分析(Pratt) → 语义分析(类型推断) → LLVM IR → .exe

模块:
- lexer: 手写状态机, 40 种 Token, // 和 /* */ 注释
- parser: Pratt 表达式解析(9 级优先级) + 递归下降语句/函数
- ast: 14 种节点类型 + 工厂函数
- sema: 作用域链符号表 + 类型推断 + 类型检查
- codegen: AST → LLVM-C API, print_i64/f64/bool 内建
- driver: 命令行 + 流水线串联 + 错误报告
- util: Arena bump allocator (8MB)

测试: 65 单元测试(词法41+语法15+语义9) + 5 集成测试 全部通过

语言特性: i64/f64/bool/void, let不可变变量, if/else, while, 递归函数
2026-06-05 00:26:59 +08:00

239 lines
6.9 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.
<p align="center">
<h1>L Language</h1>
<p>用 C17 实现的静态类型编译型编程语言</p>
</p>
<p align="center">
<img src="https://img.shields.io/badge/version-0.1.0-blue" alt="version">
<img src="https://img.shields.io/badge/C-17-555555" alt="C">
<img src="https://img.shields.io/badge/LLVM-22.1.7-4B8BBE" alt="LLVM">
<img src="https://img.shields.io/badge/GCC-15.x-darkgreen" alt="GCC">
<img src="https://img.shields.io/badge/tests-70%20passed-brightgreen" alt="tests">
<img src="https://img.shields.io/badge/license-MIT-green" alt="license">
</p>
---
## 简介
L Language 是一门学习型编译语言,手写词法分析、递归下降 + Pratt 解析、语义分析和 LLVM IR 代码生成,最终生成原生可执行文件。语法借鉴 Rust,类型系统支持类型推断。
```rust
fn fib(n: i64) -> i64 {
if n < 2 { return n; }
return fib(n - 1) + fib(n - 2);
}
fn main() -> i64 {
print_i64(fib(10)); // 输出 55
return 0;
}
```
## 架构
```
源码(.l) → 词法分析(Token) → 语法分析(AST) → 语义分析(类型标注) → LLVM IR → 可执行文件
```
```mermaid
graph TB
subgraph 前端["编译器前端"]
Lexer[词法分析器<br/>手写状态机<br/>40 种 Token]
Parser[语法分析器<br/>递归下降 + Pratt<br/>14 种 AST 节点]
Sema[语义分析器<br/>作用域链 + 类型推断<br/>类型检查 + 错误收集]
end
subgraph 后端["编译器后端"]
Codegen[LLVM IR 生成<br/>AST → LLVM-C API<br/>内建 print 函数]
Link[链接器<br/>clang/lld<br/>生成 .exe]
end
subgraph 运行时["运行时支持"]
Builtins[内建函数<br/>print_i64 / print_f64<br/>print_bool → printf]
end
Source[源码 .l] --> Lexer
Lexer --> Parser
Parser --> Sema
Sema --> Codegen
Codegen --> Link
Link --> Exe[可执行文件 .exe]
Builtins -.-> Codegen
```
### 模块职责
| 模块 | 输入 | 输出 | 核心结构 |
|------|------|------|----------|
| `lexer/` | `char*` 源码 | `Token[]` | `Token` {kind, start, length, line, col} |
| `parser/` | `Token[]` | `AstNode*` | 14 种节点 (Program..IdentExpr) |
| `ast/` | — | 工厂函数 | `AstNode` {kind, type, as{union}} |
| `sema/` | `AstNode*` | 类型标注 | `Scope` 作用域链 + `Symbol` 符号表 |
| `codegen/` | `AstNode*` | `LLVMModuleRef` | `CgCtx` {module, builder, var_table} |
| `driver/` | 命令行参数 | exit code | 流水线串联 + 错误报告 |
## 功能 (v0.1)
### 类型系统
| 类型 | 关键字 | 说明 |
|------|--------|------|
| 64 位有符号整数 | `i64` | `42`, `-7` |
| 64 位浮点数 | `f64` | `3.14`, `-0.5` |
| 布尔值 | `bool` | `true`, `false` |
| 无返回值 | `void` | 函数不返回值时使用 |
- `let` 不可变变量,支持可选类型标注和类型推断
- 类型在编译时完全确定,无隐式转换(除 `i64``f64` 自动提升)
### 控制流
- `if` / `else` 条件分支(支持 `else if` 链)
- `while` 循环
- `return` 提前返回(可选带表达式)
### 函数
- 多参数,显式返回类型(可省略,默认 `void`
- 递归调用
- 内建函数:`print_i64`, `print_f64`, `print_bool`
## 安装
### 依赖
- **GCC** 15.x (MinGW-w64)
- **CMake** ≥ 3.20
- **LLVM** 22.xC API 库 + 头文件)
### 从源码构建
```bash
git clone <repo-url>
cd "L Language"
mkdir build && cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH="D:/settings/Language/LLVM"
mingw32-make -j4
```
生成 `l_lang.exe`
## 使用
```bash
# 编译并运行
./l_lang.exe example.l -o example.exe
./example.exe
# 查看生成的 LLVM IR
./l_lang.exe example.l --emit-ir
```
## 开发
```bash
# 构建
cd build && mingw32-make -j4
# 运行全部测试 (65 单元 + 5 集成)
./l_lang_lexer_test.exe # 词法分析 (41 tests)
./l_lang_test.exe # 语法分析 (15 tests)
./l_lang_sema_test.exe # 语义分析 (9 tests)
# 集成测试
for f in ../test/programs/*.l; do
./l_lang.exe "$f" -o out.exe && ./out.exe
done
```
### 技术栈
| 层 | 技术 |
|----|------|
| 实现语言 | C17 (GCC 15.x) |
| 构建系统 | CMake 3.20+ |
| IR 后端 | LLVM 22.1.7 C API |
| 链接器 | clang / lld |
| 内存管理 | Arena bump allocator |
| 测试框架 | 手写断言宏 (ASSERT / TEST_RUN / test_summary) |
### 项目结构
```
include/l_lang.h # 公共类型定义 (TypeKind, 向前声明)
src/
├── lexer/ # 词法分析器
│ ├── token.h/c # Token 类型 + 工具函数
│ └── lexer.h/c # 状态机 lex()
├── parser/
│ └── parser.h/c # Pratt 表达式 + 递归下降 parse()
├── ast/
│ └── ast.h/c # 14 种节点定义 + 创建函数
├── sema/
│ ├── symbol.h/c # 作用域链 (查/插)
│ └── sema.h/c # 类型推断 + 检查 sema_analyze()
├── codegen/
│ └── codegen.h/c # AST → LLVM IR codegen_module()
├── driver/
│ ├── main.c # 入口 + 命令行 + 流水线串联
│ └── error.h/c # 错误报告 (ErrorInfo / ErrorList)
└── util/
└── arena.h/c # Bump allocator (8MB)
test/
├── test_utils.h # 断言宏
├── test_lexer.c # 词法测试 (41 tests)
├── test_parser.c # 语法测试 (15 tests)
├── test_sema.c # 语义测试 (9 tests)
└── programs/ # 集成测试 (.l 源文件)
docs/
├── PRD.md # 产品需求文档
└── superpowers/plans/ # 实现计划
```
## 错误处理
| 阶段 | 策略 |
|------|------|
| 词法分析 | 首个非法字符即终止,报告 文件名:行:列: 错误信息 |
| 语法分析 | 首个语法错误即终止,报告期望 vs 实际 |
| 语义分析 | 收集所有类型错误后批量输出,红色 ANSI 高亮 |
| IR 生成 | LLVMVerifyModule 验证失败 → 输出 LLVM 诊断 |
| 链接 | system() 返回值检查,失败时打印 exit code |
## 贡献
欢迎提交 Issue 和 Pull Request。
### 本地开发环境
- GCC 14.x+ (MinGW-w64)
- CMake 3.20+
- LLVM 22.x(需要 C API 库和头文件)
### 代码规范
- C17 标准,`-Wall -Wextra -g` 零警告
- 注释用中文
- Arena 内存池贯穿全流水线,不在局部函数内 malloc
- 错误信息格式:`文件名:行:列: 描述`
- 提交格式:`<类型>: <描述>`feat/fix/refactor/docs/test/chore
## 版本号升级清单
版本号需在 **3 个地方** 手动修改:
| 文件 | 字段 | 说明 |
|------|------|------|
| `CMakeLists.txt` | `VERSION` 变量 | CMake `project()` |
| `README.md` | badges | 文档徽章 |
| `CHANGELOG.md` | 版本标题 | 变更日志 |
## 许可证
MIT License
## 作者
[刘航宇](https://github.com/LHY0125) — 河南理工大学人工智能协会