新增章节: 泛型、Trait、模块系统(mod+use+pub)、ADT枚举、if let、if-expr 更新: 类型表(14种)、测试数据(197+37)、版本号、快速参考卡片
10 KiB
L Language 语言参考手册
版本 v0.7 | 197 单元 + 37 集成测试全部通过 | LLVM 22.x 编译型语言
目录
1. 快速开始
Hello, World
fn main() {
print_str("Hello, World!");
}
编译运行:
l_lang hello.l -o hello.exe && ./hello.exe
程序结构
type Age = i64; // 类型别名
struct Point { x: i64, y: i64 } // 结构体
enum Color { Red, Green, Blue } // 枚举
fn main() -> i64 {
let p = Point { x: 10, y: 20 };
print_i64(p.x);
return 0;
}
2. 基本类型
| 类型 | 说明 | 字面量示例 |
|---|---|---|
i32 |
有符号 32 位 | let a: i32 = 100; |
i64 |
有符号 64 位(默认整数) | let a = 42; |
u64 |
无符号 64 位 | let a: u64 = 999; |
f64 |
双精度浮点 | let a = 3.14; |
bool |
布尔 | let a = true; |
char |
字符 | let a = 'A'; |
str |
字符串 | let a = "hello"; |
void |
无返回值 | 函数返回类型 |
复合类型:struct(结构体)、enum(枚举/tagged union)、T[N](固定数组)
类型转换
算术运算自动提升(TypeTable 查表驱动):
char→i32(字符参与算术时提升)enum→i64(枚举在算术中视为 i64)- 加宽链:
i32→i64→f64 u64↔i64双向(同 64-bit 位宽,LLVM 同为 i64)
3. 变量
不可变变量
let x = 42; // 类型推断为 i64
let y: i64 = 42; // 显式类型标注
可变变量
var x = 0; // var 声明可变变量
x = 42; // 允许重新赋值
x += 1; // 复合赋值
let 声明的变量不可重新赋值(编译错误)。
类型标注语法
let a: i64; // 基本类型
let b: str; // 字符串
let c: f64; // 浮点
let d: Point; // 结构体类型
let e: i64[10]; // 数组类型(后置语法 T[N])
4. 运算符
算术
+ - * / %
+ 用于字符串拼接时调用 malloc+memcpy,自动 free。
比较(返回 bool)
== != < > <= >=
逻辑
&& || !
复合赋值
var x = 10;
x += 1; // x = x + 1
x -= 1; // x = x - 1
x *= 2; // x = x * 2
x /= 2; // x = x / 2
去糖为
x = x <op> expr
优先级(从高到低)
| 优先级 | 运算符 |
|---|---|
| 70 (最高) | - (一元负), ! |
| 60 | * / % |
| 50 | + - |
| 40 | == != < > <= >= |
| 30 | && |
| 20 | ` |
| 10 | |> (管道) |
5. 控制流
if / else
if x > 0 {
print_str("正数");
} else if x < 0 {
print_str("负数");
} else {
print_str("零");
}
if 作为表达式(if-expr):
let a = if x > 0 { 10; } else { 20; };
// a = 10 或 a = 20
块的最后一条表达式语句的值即为块的值。
while 循环
var i = 0;
while i < 5 {
print_i64(i);
i = i + 1;
}
for 循环
for i in 0 to 5 {
print_i64(i); // 0, 1, 2, 3, 4
}
去糖为
var i = 0; while i < 5 { ... ; i = i + 1; }
match
match x {
1 => { print_str("one"); },
2 => { print_str("two"); },
_ => { print_str("other"); },
}
去糖为
let __match_val = x; if __match_val == 1 { ... } else if ...
guard
guard x >= 0 else { return -1; }
// 去糖: if !(x >= 0) { return -1; }
提前返回的语法糖,让正常路径保持左对齐。
if let
enum Option { Some(i64), None }
let val = Option::Some(42);
if let Option::Some(v) = val {
print_i64(v); // 42
} else {
print_str("none");
}
6. 函数
定义
fn add(a: i64, b: i64) -> i64 {
return a + b;
}
fn greet() {
print_str("Hello!");
}
泛型定义
fn id<T>(x: T) -> T {
return x;
}
fn swap<A, B>(a: A, b: B) -> B {
return b;
}
单态化:每次泛型调用生成一份具象化副本。最多 8 个类型参数。
调用
let result = add(1, 2);
let x = id(42); // T = i64
let y = id("hello"); // T = str
greet();
命名参数
fn draw_rect(width: i64, height: i64) { ... }
draw_rect(width: 10, height: 20); // 命名调用
draw_rect(10, 20); // 位置调用(等价)
命名参数必须在位置参数之后。
管道
let result = 10 |> add(5); // add(10, 5)
let x = 1 |> add(2) |> mul(3); // mul(add(1, 2), 3)
去糖为嵌套调用,RHS 必须是函数调用形式(带括号)。
字符串插值
let name = "World";
let msg = "Hello, \(name)!"; // "Hello, World!"
去糖为
"Hello, " + name + "!"
7. 结构体
声明
struct Point { x: i64, y: i64 }
初始化
let p = Point { x: 10, y: 20 };
let q = Point { y: 30, x: 5 }; // 命名顺序任意
字段访问
let px = p.x;
函数参数和返回值
fn distance(p1: Point, p2: Point) -> f64 { ... }
fn create_point(x: i64, y: i64) -> Point {
return Point { x: x, y: y };
}
方法(extend)
extend Point {
fn get_x(self: Point) -> i64 {
return self.x;
}
}
let p = Point { x: 10, y: 20 };
p.get_x(); // 10
方法名内部 mangled 为
StructName$methodName
8. 枚举与 ADT
简单枚举
enum Color { Red, Green, Blue }
let c = Color::Red;
print_i64(c); // 0 (变体索引)
带数据的枚举 (ADT)
enum Option {
Some(i64),
None,
}
let x = Option::Some(100);
内部表示为 { tag: i64, payload: i64 } tagged union。
match 枚举 + 解构
match color {
Color::Red => { print_str("red"); },
_ => { print_str("other"); },
}
9. 数组
let arr: i64[3] = arr;
var nums: i64[10];
nums[0] = 42;
let x = nums[0];
后置语法
T[N],大小仅支持整数字面量。元素类型支持 i64/f64/bool/struct。
10. 类型别名
type Meters = i64;
type Point3D = Point;
let distance: Meters = 100;
别名在 sema 层完全解析为零 codegen 开销。
11. 泛型
fn id<T>(x: T) -> T { return x; }
fn main() -> i64 {
let a = id(42); // T = i64,生成 id_i64
let b = id("hello"); // T = str,生成 id_str
return 0;
}
- 函数级类型参数:
fn name<A, B, ...>(...) - 最多 8 个类型参数
- 单态化:调用时生成具象化副本,替换 AST 中所有 T 引用
- 类型参数可用在参数和返回值位置
12. Trait 接口
定义
trait Show {
fn show(self: Self) -> void;
}
Self 关键字在 trait 签名中代表实现者的类型。
实现
extend Show Point {
fn show(self: Point) -> void {
print_i64(self.x);
print_i64(self.y);
}
}
调用
let p = Point { x: 10, y: 20 };
p.show(); // 通过 trait 方法 dispatch
内部 mangled 为
Point$Show$show,dot-call 自动搜索$show后缀。
13. 模块系统
声明子模块
// main.l
mod math; // 加载同目录下 math_mod.l
fn main() -> i64 {
return math_mod::add(3, 4);
}
子模块中 pub 标记对外可见:
// math_mod.l
pub fn add(a: i64, b: i64) -> i64 {
return a + b;
}
use 导入
use math_mod::add;
fn main() -> i64 {
return add(3, 4); // 零前缀直接调用
}
14. 内置函数
| 函数 | 输出格式 |
|---|---|
print_i64(x: i64) |
%lld\n |
print_f64(x: f64) |
%f\n |
print_bool(x: bool) |
true\n / false\n |
print_str(x: str) |
%s\n |
内置函数委托给 C
printf,无需导入。
15. 注释
// 单行注释
/*
多行注释
*/
不支持嵌套多行注释。
16. 完整示例
斐波那契
fn fib(n: i64) -> i64 {
if n <= 1 { return n; }
return fib(n - 1) + fib(n - 2);
}
fn main() -> i64 {
return fib(10); // 55
}
Trait + 泛型
trait Show {
fn show(self: Self) -> void;
}
struct Point { x: i64, y: i64 }
extend Show Point {
fn show(self: Point) -> void {
print_i64(self.x);
print_i64(self.y);
}
}
fn main() -> i64 {
let p = Point { x: 10, y: 20 };
p.show();
return 0;
}
学生成绩统计
struct Student { name: str, score: i64 }
extend Student {
fn is_pass(self: Student) -> bool {
return self.score >= 60;
}
}
enum Grade { A, B, C, D, F }
fn get_grade(score: i64) -> i64 {
if score >= 90 { return 0; }
if score >= 80 { return 1; }
if score >= 70 { return 2; }
if score >= 60 { return 3; }
return 4;
}
fn main() -> i64 {
let s = Student { name: "Tom", score: 85 };
if s.is_pass() { print_str("pass"); }
return get_grade(s.score);
}
模块化
// math_mod.l
pub fn add(a: i64, b: i64) -> i64 { return a + b; }
// main.l
use math_mod::add;
fn main() -> i64 {
print_i64(add(3, 4)); // 7
return 0;
}
17. 编译与运行
安装
下载 L-Language-0.7.0-setup.exe(39.2MB,自包含 LLVM + MinGW)。
使用
l_lang source.l # 编译并自动运行
l_lang source.l -o output.exe # 指定输出路径
错误格式
错误: 文件名:行号:列号: 描述
快速参考
类型: i32 i64 u64 f64 bool char str void struct enum T[N]
变量: let x = 42 var x = 0 let x: i64 = 0
控制流: if/else while for i in 0 to N match guard if let
函数: fn f(a: T) -> R { return expr; } 泛型: fn id<T>(x: T) -> T
结构体: struct S { x: i64 } Point { x: 1 } . extend + method
枚举: enum E { A, B } Option::Some(v) if let Option::Some(v) = x
Traits: trait Show { fn show(self: Self); } extend Trait Struct { ... }
模块: mod math; use math::add; pub fn
管道: expr |> func() 插值: "Hello, \(name)!"
v0.7 — 最后更新 2026-06-07