# 玄铁模块系统

模块系统允许你将代码拆分到多个文件中,通过 `引` 关键字引入其他模块,通过 `予` 关键字为引入的模块指定别名。

---

### 基本语法

#### 引入模块

```xuantie
引 "./库/数学.xt"              // 引入数学库
引 "./组件/按钮.xt"             // 引入自定义组件
```

#### 带别名的引入

引入的模块默认使用文件名作为命名空间前缀。如果需要更短的名字,使用 `予` 指定别名:

```xuantie
引 "./库/文件.xt" 予 文件     // 用 文件 作为别名
引 "./组件/按钮.xt" 予 btn   // 用 btn 作为别名
```

#### 访问引入模块的成员

引入后,通过 `模块名.成员名` 访问模块中的函数、类型和变量:

```xuantie
// math.xt 中定义了 函 平方(x) { 返 x * x }
引 "./库/数学.xt" 予 数学
设 平方值 = 数学.平方(5)     // 调用模块中的函数
```

---

### 路径解析

`引` 后面的路径是**相对于当前源文件**的路径:

```xuantie
// 假设文件结构:
// project/
//   main.xt
//   lib/
//     math.xt
//     utils.xt
//   ui/
//     button.xt

// 在 main.xt 中:
引 "./lib/math.xt"   予 数学    // 相对路径
引 "./ui/button.xt"                 // 没有别名

// 在 button.xt 中:
引 "../lib/utils.xt" 予 工具     // 上级目录
```

---

### 模块的命名空间隔离

每个被引入的模块有独立的命名空间。同名函数在不同模块中不会冲突:

```xuantie
引 "./lib/math.xt"  予 数学
引 "./lib/geo.xt"   予 几何

设 a = 数学.距离(1, 2)    // 调用 math.xt 中的 距离
设 b = 几何.距离(3, 4)    // 调用 geo.xt 中的 距离——不冲突
```

#### 模块内部的函数互调

模块**内部**的函数可以直接用裸名互相调用,无需也不应加别名前缀——模块自己并不知道调用方给它起了什么别名:

```xuantie
// ui.xt 内部:
公 函 四边(上, 右, 下, 左) { ... }
公 函 全边(值) {
    返 四边(值, 值, 值, 值)    // 直接裸名调用同模块函数,正确写法
}
```

即使调用方以 `引 "ui.xt" 予 UI` 引入,编译器也会把模块内的裸名解析自动回退到当前模块命名空间(`四边` → `UI.四边`)。模块内引用本模块的全局变量(`设`/`常` 声明)同样适用,且允许前向引用(函数体可以先于全局声明语句引用它)。

#### 引入的两条硬性限制

1. **同一模块在一次编译中只能使用一个别名**(或都不用别名)。同一个文件先 `予 R` 后又 `予 渲染`,编译器会明确报错——因为模块内部的裸名互调只能映射到一个命名空间。
2. **菱形引入是安全的**:应用引 UI 和渲染、UI 内部又引渲染——只要别名一致,同一物理文件只预扫描、编译一次(路径最终规范化为绝对路径后去重),不会产生重复定义。

---

### 编译机制

玄铁编译器在编译时对模块的处理分两个阶段:

1. **预扫描**:递归读取所有 `引` 的目标文件,收集符号(函数名、类型名、全局变量)
2. **合并编译**:将所有模块的代码合并到同一个 LLVM 模块中,生成单一可执行文件

这意味着:
- 所有模块共享同一个全局作用域
- 循环引用会被检测并报错
- 不支持动态加载(编译时确定)

---

### 完整示例

**math.xt(被引入的模块):**
```xuantie
// 数学工具模块
函 平方(x) { 返 x * x }
函 立方(x) { 返 x * x * x }
设 PI = 3.14159
```

**main.xt(主程序):**
```xuantie
引 "./math.xt" 予 数学

示("5 的平方: #{ 数学.平方(5)}")
示("5 的立方: #{ 数学.立方(5)}")
示("PI: #{ 数学.PI}")
```

**编译与运行:**
```xuantie
玄铁.exe tie main.xt
./main.exe
// 输出:
// 5 的平方: 25
// 5 的立方: 125
// PI: 3.14159
```

---

### 当前局限

| 局限 | 说明 |
|------|------|
| 单别名 | 同一模块一次编译只能用一个别名,多别名会明确报错 |
| 无导出控制 | 模块中所有顶层符号默认全部导出 |
| 无循环依赖 | 循环引用被编译器检测并报错 |
| 单文件输出 | 所有模块合并为一个可执行文件 |

包管理与版本依赖等功能由铁铺(TiePM)提供,详见 [07_铁铺使用指南.md](./07_铁铺使用指南.md)。

---

*上一篇:[04_弱引用编程指南.md](./04_弱引用编程指南.md)*