Files
l-language/docs/language-reference.md
T

644 lines
11 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.
# L Language 语言参考手册
> 版本 v0.6 | 158 单元 + 29 集成测试全部通过 | 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. 基本类型
| 类型 | 关键字 | 范围/说明 | 示例 |
|------|--------|----------|------|
| 32位整数 | `i32` | 32位有符号,`-2^31 ~ 2^31-1` | `100` |
| 64位整数 | `i64` | 64位有符号,`-2^63 ~ 2^63-1` | `42`, `-7`, `0` |
| 无符号整数 | `u64` | 64位无符号,`0 ~ 2^64-1` | `999` |
| 浮点 | `f64` | 64位双精度 | `3.14`, `-0.5`, `1.0` |
| 布尔 | `bool` | `true``false` | `true`, `false` |
| 字符 | `char` | 单字符,ASCII | `'A'`, `'\n'` |
| 字符串 | `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
var count: i64 = 0; // 可变变量
count = count + 1; // 赋值
count += 1; // 复合赋值 (等价于 count = count + 1)
```
> **规则**: 对 `let` 声明的不可变变量赋值会在编译时报错。可变变量用 `var` 声明。
### 类型标注语法
```rust
let name: Type = value; // 完整写法(不可变)
let name = value; // 类型推断(不可变)
var 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
var i: i64 = 0;
while i < 5 {
print_i64(i);
i += 1;
}
// 输出: 0 1 2 3 4
```
### for 循环
```rust
for i in 0 to 5 {
print_i64(i);
}
// 输出: 0 1 2 3 4
```
`for i in start to end` 等价于 `var 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();
```
### 命名参数
调用函数时可以标注参数名,命名参数可任意顺序,但必须放在位置参数之后:
```rust
fn draw_rect(x: i64, y: i64, w: i64, h: i64) -> void {
// ...
}
draw_rect(0, 0, 100, 200); // 全位置
draw_rect(x: 1, y: 2, w: 10, h: 20); // 全命名
draw_rect(0, 0, w: 10, h: 20); // 混用
draw_rect(w: 10, h: 20, x: 1, y: 2); // 命名任意顺序
```
`:` 分隔参数名和值(与类型标注 `name: Type` 视觉统一)。
### guard 语句
guard 是提前返回的语法糖,用于提前处理异常条件:
```rust
fn abs(x: i64) -> i64 {
guard x >= 0 else { return -x; }
return x;
}
// guard x >= 0 else { ... } 去糖为:
// if !(x >= 0) { ... }
```
- `else` 块必须用花括号,通常包含 `return`/`continue` 等跳转
- guard 让正常路径的代码保持在左侧,提高可读性
### 管道 `|>`
管道将数据从左到右流经函数,LHS 作为 RHS 函数调用的第一个参数(F#/Elixir 风格):
```rust
fn double(x: i64) -> i64 { return x * 2; }
fn add(a: i64, b: i64) -> i64 { return a + b; }
let result = 10 |> double() |> add(5);
// 去糖为: add(double(10), 5) → 25
```
- 管道右侧必须是函数调用(带括号)
- 管道优先级低于所有算术运算符
### 字符串插值
`\(expr)` 在字符串中嵌入表达式(Swift 风格,`\` 与 C 转义字符视觉一致):
```rust
let name = "World";
let msg = "Hello, \(name)!";
print_str(msg); // Hello, World!
```
- 去糖为字符串拼接: `"Hello, " + name + "!"`
- 字面量 `\(` 写作 `\\(`,反斜杠写作 `\\`
---
## 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);
}
```
### extend — 方法
```rust
extend 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
```
- `extend 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 数组
```
数组类型语法: `元素类型[大小]`(后置维度)
- `= arr` 是固定写法,表示声明未初始化的数组(`arr` 是变量名自身)
- 大小必须是整数常量
- 元素类型支持: `i64`, `f64`, `bool`
- 数组元素默认值为零值(`0` / `0.0` / `false`
### 索引
```rust
arr[0] = 100; // 给第一个元素赋值
arr[1] = 200;
print_i64(arr[0]); // 100
print_i64(arr[1]); // 200
```
### 循环遍历
```rust
var arr: i64[5] = arr;
var 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,
}
extend 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 {
var arr: i64[5] = arr;
// 填充数组
var 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
```
### 错误信息格式
```
错误: 文件名:行号:列号: 错误描述
```
- 词法/语法错误: 立即终止
- 类型错误: 收集所有错误后统一输出
---
## 快速参考卡片
```
类型: i32 i64 u64 f64 bool char str void struct enum T[N]
声明: let x = val var x = val
let x: Type = val type Alias = Type
控制流: if/else while for i in 0 to N match guard
函数: fn name(p: T) -> Ret { return expr; }
func(name: val) 命名参数 expr |> func() 管道
结构体: struct Name { f: Type } Name { f: val }
枚举: enum Name { A, B, C } Name::B
方法: extend T { fn m(self: T) } obj.m()
内建: print_i64 print_f64 print_bool print_str
运算符: + - * / % == != < > <= >= && || ! += -= *= /= |>
插值: "Hello, \(name)!"
注释: // 行注释 /* 块注释 */
```