Files
l-language/docs/language-reference.md
T
Serendipity e60021b684 docs: language-reference.md v0.7 全面重写
新增章节: 泛型、Trait、模块系统(mod+use+pub)、ADT枚举、if let、if-expr
更新: 类型表(14种)、测试数据(197+37)、版本号、快速参考卡片
2026-06-07 13:38:47 +08:00

10 KiB
Raw Blame History

L Language 语言参考手册

版本 v0.7 | 197 单元 + 37 集成测试全部通过 | LLVM 22.x 编译型语言

目录

  1. 快速开始
  2. 基本类型
  3. 变量
  4. 运算符
  5. 控制流
  6. 函数
  7. 结构体
  8. 枚举与 ADT
  9. 数组
  10. 类型别名
  11. 泛型
  12. Trait 接口
  13. 模块系统
  14. 内置函数
  15. 注释
  16. 完整示例
  17. 编译与运行

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 查表驱动):

  • chari32(字符参与算术时提升)
  • enumi64(枚举在算术中视为 i64
  • 加宽链:i32i64f64
  • u64i64 双向(同 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$showdot-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.exe39.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