Files
l-language/README.md
T

260 lines
7.5 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.5.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-158%20passed-brightgreen" alt="tests">
<img src="https://img.shields.io/badge/license-MIT-green" alt="license">
</p>
---
## 简介
L Language 是一门学习型编译语言,手写词法分析、递归下降 + Pratt 解析、语义分析和 LLVM IR 代码生成,最终生成原生可执行文件。语法借鉴 Rust,类型系统支持类型推断。
📖 **[语言参考手册](docs/language-reference.md)** — 完整的语法、类型、示例教程
```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.5)
### 类型系统
| 类型 | 语法 | 示例 |
|------|------|------|
| 64 位有符号整数 | `i64` | `42`, `-7` |
| 64 位浮点数 | `f64` | `3.14` |
| 布尔值 | `bool` | `true`, `false` |
| 字符串 | `str` | `"hello"` |
| 结构体 | `struct` | `Point { x: i64, y: i64 }` |
| 枚举 | `enum` | `Color { Red, Green, Blue }` |
| 数组 | `T[N]` | `i64[10]` |
| 无返回值 | `void` | 函数默认 |
| 类型别名 | `type` | `type Meters = i64;` |
- `let` 不可变 + `var` 可变,类型推断
- `i64``f64` 自动提升
### 控制流
- `if` / `else` / `else if`
- `while` 循环
- `for i in 0 to 10` (去糖为 while)
- `match expr { pat => { ... } _ => { ... } }` (去糖为 if-else)
- `return`
### 函数 & 方法
- 多参数、递归、struct 参数/返回值
- 返回类型校验
- `impl StructName { fn method(self: Type) -> Ret { ... } }`
- `instance.method(args)` 调用
- 内建函数:`print_i64`, `print_f64`, `print_bool`, `print_str`
### 运算符
`+ - * / %` `== != < > <= >=` `&& || !` `+= -= *= /=` `str + str`
### 内存管理
- str 拼接 malloc → 作用域退出自动 free (RAII)
- struct/array 栈上值类型
## 安装
### 依赖
- **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
# 运行全部测试 (158 单元 + 24 集成)
./l_lang_lexer_test.exe # 词法分析 (41 tests)
./l_lang_test.exe # 语法分析 (15 tests)
./l_lang_sema_test.exe # 语义分析 (74 tests)
./l_lang_codegen_test.exe # 代码生成 (28 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) — 河南理工大学人工智能协会