docs: L Language 语言参考手册 (language-reference.md)
- 14 章完整教程: 类型/变量/运算符/控制流/函数/struct/enum/数组/impl/match - 3 个完整示例: 斐波那契/学生成绩/数组操作 - 快速参考卡片 - README 添加手册链接
This commit is contained in:
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
L Language 是一门学习型编译语言,手写词法分析、递归下降 + Pratt 解析、语义分析和 LLVM IR 代码生成,最终生成原生可执行文件。语法借鉴 Rust,类型系统支持类型推断。
|
L Language 是一门学习型编译语言,手写词法分析、递归下降 + Pratt 解析、语义分析和 LLVM IR 代码生成,最终生成原生可执行文件。语法借鉴 Rust,类型系统支持类型推断。
|
||||||
|
|
||||||
|
📖 **[语言参考手册](docs/language-reference.md)** — 完整的语法、类型、示例教程
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn fib(n: i64) -> i64 {
|
fn fib(n: i64) -> i64 {
|
||||||
if n < 2 { return n; }
|
if n < 2 { return n; }
|
||||||
|
|||||||
@@ -0,0 +1,575 @@
|
|||||||
|
# L Language 语言参考手册
|
||||||
|
|
||||||
|
> 版本 v0.5 | 145 测试全部通过 | LLVM 后端编译型语言
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
1. [快速开始](#1-快速开始)
|
||||||
|
2. [基本类型](#2-基本类型)
|
||||||
|
3. [变量](#3-变量)
|
||||||
|
4. [运算符](#4-运算符)
|
||||||
|
5. [控制流](#5-控制流)
|
||||||
|
6. [函数](#6-函数)
|
||||||
|
7. [结构体](#7-结构体)
|
||||||
|
8. [枚举](#8-枚举)
|
||||||
|
9. [数组](#9-数组)
|
||||||
|
10. [类型别名](#10-类型别名)
|
||||||
|
11. [内置函数](#11-内置函数)
|
||||||
|
12. [注释](#12-注释)
|
||||||
|
13. [完整示例](#13-完整示例)
|
||||||
|
14. [编译与运行](#14-编译与运行)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 快速开始
|
||||||
|
|
||||||
|
### Hello, World
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn main() -> i64 {
|
||||||
|
print_i64(42);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
编译运行:
|
||||||
|
```bash
|
||||||
|
l_lang.exe hello.l -o hello.exe
|
||||||
|
./hello.exe
|
||||||
|
# 输出: 42
|
||||||
|
```
|
||||||
|
|
||||||
|
### 程序结构
|
||||||
|
|
||||||
|
- 文件扩展名 `.l`
|
||||||
|
- 一个 `.l` 文件包含若干函数和类型声明
|
||||||
|
- 必须有 `main` 函数作为入口点
|
||||||
|
- 所有声明在顶层,不支持嵌套函数
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 基本类型
|
||||||
|
|
||||||
|
| 类型 | 关键字 | 范围/说明 | 示例 |
|
||||||
|
|------|--------|----------|------|
|
||||||
|
| 整数 | `i64` | 64位有符号,`-2^63 ~ 2^63-1` | `42`, `-7`, `0` |
|
||||||
|
| 浮点 | `f64` | 64位双精度 | `3.14`, `-0.5`, `1.0` |
|
||||||
|
| 布尔 | `bool` | `true` 或 `false` | `true`, `false` |
|
||||||
|
| 字符串 | `str` | UTF-8 文本 | `"Hello"`, `"你好"` |
|
||||||
|
| 空类型 | `void` | 无返回值 | 用于函数返回类型 |
|
||||||
|
|
||||||
|
### 类型转换
|
||||||
|
|
||||||
|
- `i64` 和 `f64` 混合运算时,`i64` 自动提升为 `f64`
|
||||||
|
- `bool` 和数值之间**不能**隐式转换
|
||||||
|
- `str` 不能隐式转换为其他类型
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 变量
|
||||||
|
|
||||||
|
### 声明
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let x = 42; // 不可变,类型推断为 i64
|
||||||
|
let y: i64 = 100; // 不可变,显式类型标注
|
||||||
|
let z = 3.14; // 类型推断为 f64
|
||||||
|
let msg = "hello"; // 类型推断为 str
|
||||||
|
let flag = true; // 类型推断为 bool
|
||||||
|
```
|
||||||
|
|
||||||
|
### 可变变量
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let mut count: i64 = 0; // 可变变量
|
||||||
|
count = count + 1; // 赋值
|
||||||
|
count += 1; // 复合赋值 (等价于 count = count + 1)
|
||||||
|
```
|
||||||
|
|
||||||
|
> **规则**: 对 `let` 声明的不可变变量赋值会在编译时报错。
|
||||||
|
|
||||||
|
### 类型标注语法
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let name: Type = value; // 完整写法
|
||||||
|
let name = value; // 类型推断
|
||||||
|
let mut name: Type = value; // 可变变量
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 运算符
|
||||||
|
|
||||||
|
### 算术
|
||||||
|
|
||||||
|
| 运算符 | 说明 | 示例 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `+` | 加法 | `1 + 2` → `3` |
|
||||||
|
| `-` | 减法 | `5 - 3` → `2` |
|
||||||
|
| `*` | 乘法 | `3 * 4` → `12` |
|
||||||
|
| `/` | 除法 | `10 / 3` → `3` (整数) |
|
||||||
|
| `%` | 取模 | `10 % 3` → `1` |
|
||||||
|
|
||||||
|
### 比较(返回 bool)
|
||||||
|
|
||||||
|
| 运算符 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| `==` | 等于 |
|
||||||
|
| `!=` | 不等于 |
|
||||||
|
| `<` | 小于 |
|
||||||
|
| `>` | 大于 |
|
||||||
|
| `<=` | 小于等于 |
|
||||||
|
| `>=` | 大于等于 |
|
||||||
|
|
||||||
|
### 逻辑
|
||||||
|
|
||||||
|
| 运算符 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| `&&` | 逻辑与 |
|
||||||
|
| `\|\|` | 逻辑或 |
|
||||||
|
| `!` | 逻辑非 |
|
||||||
|
|
||||||
|
### 复合赋值
|
||||||
|
|
||||||
|
| 运算符 | 等价于 |
|
||||||
|
|--------|--------|
|
||||||
|
| `x += y` | `x = x + y` |
|
||||||
|
| `x -= y` | `x = x - y` |
|
||||||
|
| `x *= y` | `x = x * y` |
|
||||||
|
| `x /= y` | `x = x / y` |
|
||||||
|
|
||||||
|
### 字符串拼接
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let greeting = "Hello, " + "World!";
|
||||||
|
// greeting = "Hello, World!"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 优先级(从高到低)
|
||||||
|
|
||||||
|
```
|
||||||
|
! -(一元负)
|
||||||
|
* / %
|
||||||
|
+ -
|
||||||
|
== != < > <= >=
|
||||||
|
&&
|
||||||
|
||
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 控制流
|
||||||
|
|
||||||
|
### if / else
|
||||||
|
|
||||||
|
```rust
|
||||||
|
if x > 0 {
|
||||||
|
print_i64(1);
|
||||||
|
} else if x == 0 {
|
||||||
|
print_i64(0);
|
||||||
|
} else {
|
||||||
|
print_i64(-1);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### while 循环
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let mut i: i64 = 0;
|
||||||
|
while i < 5 {
|
||||||
|
print_i64(i);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
// 输出: 0 1 2 3 4
|
||||||
|
```
|
||||||
|
|
||||||
|
### for 循环
|
||||||
|
|
||||||
|
```rust
|
||||||
|
for i in 0..5 {
|
||||||
|
print_i64(i);
|
||||||
|
}
|
||||||
|
// 输出: 0 1 2 3 4
|
||||||
|
```
|
||||||
|
|
||||||
|
`for i in start..end` 等价于 `let mut i = start; while i < end { ...; i += 1; }`
|
||||||
|
|
||||||
|
### match
|
||||||
|
|
||||||
|
```rust
|
||||||
|
enum Color { Red, Green, Blue }
|
||||||
|
|
||||||
|
let c = Color::Green;
|
||||||
|
match c {
|
||||||
|
Color::Red => { print_i64(10); }
|
||||||
|
Color::Green => { print_i64(20); }
|
||||||
|
_ => { print_i64(0); } // 通配符
|
||||||
|
}
|
||||||
|
// 输出: 20
|
||||||
|
```
|
||||||
|
|
||||||
|
- 每个分支用 `=>` 分隔,花括号包围
|
||||||
|
- `_` 表示通配符(匹配所有未列出的情况)
|
||||||
|
- `match` 是语句,不是表达式
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 函数
|
||||||
|
|
||||||
|
### 定义
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn add(a: i64, b: i64) -> i64 {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn greet() -> void {
|
||||||
|
print_str("Hello");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `fn` 关键字定义函数
|
||||||
|
- 参数格式: `name: Type`
|
||||||
|
- 返回类型: `-> Type`,可省略(默认 `void`)
|
||||||
|
- 支持递归调用
|
||||||
|
|
||||||
|
### 调用
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let result = add(3, 5);
|
||||||
|
greet();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 结构体
|
||||||
|
|
||||||
|
### 声明
|
||||||
|
|
||||||
|
```rust
|
||||||
|
struct Point {
|
||||||
|
x: i64,
|
||||||
|
y: i64,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 初始化
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let p = Point { x: 10, y: 20 };
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字段访问
|
||||||
|
|
||||||
|
```rust
|
||||||
|
print_i64(p.x); // 10
|
||||||
|
print_i64(p.y); // 20
|
||||||
|
```
|
||||||
|
|
||||||
|
### 嵌套结构体
|
||||||
|
|
||||||
|
```rust
|
||||||
|
struct Rect {
|
||||||
|
tl: Point, // 左上角
|
||||||
|
br: Point, // 右下角
|
||||||
|
}
|
||||||
|
|
||||||
|
let r = Rect {
|
||||||
|
tl: Point { x: 0, y: 10 },
|
||||||
|
br: Point { x: 5, y: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
print_i64(r.tl.x); // 0 (链式访问)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 函数参数和返回值
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn make_point(x: i64, y: i64) -> Point {
|
||||||
|
return Point { x: x, y: y };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_point(p: Point) -> void {
|
||||||
|
print_i64(p.x);
|
||||||
|
print_i64(p.y);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### impl — 方法
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl Point {
|
||||||
|
fn new(x: i64, y: i64) -> Point {
|
||||||
|
return Point { x: x, y: y };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_x(self: Point) -> i64 {
|
||||||
|
return self.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = Point.new(10, 20); // 方法调用
|
||||||
|
print_i64(p.get_x()); // 10
|
||||||
|
```
|
||||||
|
|
||||||
|
- `impl StructName { fn ... }` 定义方法
|
||||||
|
- 第一个参数必须是 `self: StructName`
|
||||||
|
- 调用: `instance.method(args)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 枚举
|
||||||
|
|
||||||
|
### 声明
|
||||||
|
|
||||||
|
```rust
|
||||||
|
enum Color {
|
||||||
|
Red,
|
||||||
|
Green,
|
||||||
|
Blue,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 访问变体
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let c = Color::Green;
|
||||||
|
print_i64(c); // 1 (索引值: Red=0, Green=1, Blue=2)
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let is_red = (c == Color::Red); // false
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 数组
|
||||||
|
|
||||||
|
### 声明类型
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let arr: [i64; 5] = arr; // 未初始化的 5 个 i64 数组
|
||||||
|
```
|
||||||
|
|
||||||
|
数组类型语法: `[元素类型; 大小]`
|
||||||
|
|
||||||
|
- 大小必须是整数常量
|
||||||
|
- 元素类型支持: `i64`, `f64`, `bool`
|
||||||
|
|
||||||
|
### 索引
|
||||||
|
|
||||||
|
```rust
|
||||||
|
arr[0] = 100; // 给第一个元素赋值
|
||||||
|
arr[1] = 200;
|
||||||
|
|
||||||
|
print_i64(arr[0]); // 100
|
||||||
|
print_i64(arr[1]); // 200
|
||||||
|
```
|
||||||
|
|
||||||
|
### 循环遍历
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let mut arr: [i64; 5] = arr;
|
||||||
|
let mut i: i64 = 0;
|
||||||
|
while i < 5 {
|
||||||
|
arr[i] = i * 10;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 类型别名
|
||||||
|
|
||||||
|
```rust
|
||||||
|
type Meters = i64;
|
||||||
|
type Kilometers = i64;
|
||||||
|
|
||||||
|
fn run(distance: Meters) -> void {
|
||||||
|
print_i64(distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
let d: Meters = 5000;
|
||||||
|
run(d); // 输出: 5000
|
||||||
|
```
|
||||||
|
|
||||||
|
支持别名指向 struct:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
type P = Point;
|
||||||
|
let p: P = Point { x: 1, y: 2 };
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 内置函数
|
||||||
|
|
||||||
|
| 函数 | 参数 | 输出 |
|
||||||
|
|------|------|------|
|
||||||
|
| `print_i64(x)` | `i64` | 整数 + 换行 |
|
||||||
|
| `print_f64(x)` | `f64` | 浮点 + 换行 |
|
||||||
|
| `print_bool(x)` | `bool` | `true`/`false` + 换行 |
|
||||||
|
| `print_str(s)` | `str` | 字符串 + 换行 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. 注释
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// 这是单行注释
|
||||||
|
|
||||||
|
/*
|
||||||
|
这是
|
||||||
|
多行注释
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. 完整示例
|
||||||
|
|
||||||
|
### 斐波那契
|
||||||
|
|
||||||
|
```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;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 学生成绩统计
|
||||||
|
|
||||||
|
```rust
|
||||||
|
struct Student {
|
||||||
|
name_id: i64,
|
||||||
|
score: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Student {
|
||||||
|
fn new(id: i64, score: i64) -> Student {
|
||||||
|
return Student { name_id: id, score: score };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_pass(self: Student) -> bool {
|
||||||
|
return self.score >= 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Grade { A, B, C, D, F }
|
||||||
|
|
||||||
|
fn get_grade(score: i64) -> i64 {
|
||||||
|
match score {
|
||||||
|
90 => { return 0; }
|
||||||
|
80 => { return 1; }
|
||||||
|
70 => { return 2; }
|
||||||
|
60 => { return 3; }
|
||||||
|
_ => { return 4; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> i64 {
|
||||||
|
let s = Student.new(1001, 85);
|
||||||
|
print_i64(s.name_id);
|
||||||
|
print_i64(s.score);
|
||||||
|
|
||||||
|
if s.is_pass() {
|
||||||
|
print_str("PASS");
|
||||||
|
} else {
|
||||||
|
print_str("FAIL");
|
||||||
|
}
|
||||||
|
|
||||||
|
print_i64(get_grade(85)); // 1 (Grade::B)
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 数组操作
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn main() -> i64 {
|
||||||
|
let mut arr: [i64; 5] = arr;
|
||||||
|
|
||||||
|
// 填充数组
|
||||||
|
let mut i: i64 = 0;
|
||||||
|
while i < 5 {
|
||||||
|
arr[i] = i * i;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印数组
|
||||||
|
i = 0;
|
||||||
|
while i < 5 {
|
||||||
|
print_i64(arr[i]);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// 输出: 0 1 4 9 16
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14. 编译与运行
|
||||||
|
|
||||||
|
### 安装编译器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 从源码构建
|
||||||
|
git clone git@lhy-git.liuhangyv.top:Serendipity/l-language.git
|
||||||
|
cd l-language
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH="D:/settings/Language/LLVM"
|
||||||
|
mingw32-make -j4
|
||||||
|
```
|
||||||
|
|
||||||
|
依赖: GCC 15.x (MinGW-w64), CMake 3.20+, LLVM 22.x
|
||||||
|
|
||||||
|
### 使用
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 编译
|
||||||
|
l_lang.exe source.l -o program.exe
|
||||||
|
|
||||||
|
# 运行
|
||||||
|
./program.exe
|
||||||
|
|
||||||
|
# 查看生成的 LLVM IR
|
||||||
|
l_lang.exe source.l --emit-ir
|
||||||
|
```
|
||||||
|
|
||||||
|
### 错误信息格式
|
||||||
|
|
||||||
|
```
|
||||||
|
错误: 文件名:行号:列号: 错误描述
|
||||||
|
```
|
||||||
|
|
||||||
|
- 词法/语法错误: 立即终止
|
||||||
|
- 类型错误: 收集所有错误后统一输出
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 快速参考卡片
|
||||||
|
|
||||||
|
```
|
||||||
|
类型: i64 f64 bool str void struct enum [T;N]
|
||||||
|
声明: let x = val let mut x = val
|
||||||
|
let x: Type = val type Alias = Type
|
||||||
|
控制流: if/else while for i in 0..N match
|
||||||
|
函数: fn name(p: T) -> Ret { return expr; }
|
||||||
|
结构体: struct Name { f: Type } Name { f: val }
|
||||||
|
枚举: enum Name { A, B, C } Name::B
|
||||||
|
方法: impl T { fn m(self: T) } obj.m()
|
||||||
|
内建: print_i64 print_f64 print_bool print_str
|
||||||
|
运算符: + - * / % == != < > <= >= && || ! += -= *= /=
|
||||||
|
注释: // 行注释 /* 块注释 */
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user