# 类型系统

Gonidium 的类型系统目前只覆盖数值与布尔，并遵循"显式标注 + 隐式提升"的思路：

- **参数类型**：在函数头 `|x: f32, y: i32|` 中显式标注。
- **字面量类型**：默认类型由 parser 直接给出；也可以用 `@dtype` 显式标注（如 `255@u8`、`1.5@bf16`），等价于对该字面量做一次显式 cast。
- **表达式类型**：由 lowering 期间的"类型提升（promotion）"决定。

## 支持的 dtype

- **bool**：`bool`
- **整数**：`u8/u16/u32/u64`，`i8/i16/i32/i64`
- **浮点**：
  - IEEE：`f16/f32/f64`
  - Brain：`bf16`
- **复数**：`c64/c128`（仅 IEEE 复数族，分别对应 `f32/f64` 的复数表示）

## 默认字面量类型

不写 `@dtype` 时：

- **`true/false`** → `bool`
- **整数** → 推导为**能完全容纳该值的最小 bit 宽有符号整数类型**
  - `0` → `i8`，`127` → `i8`，`128` → `i16`，以此类推
  - 例如：`-1` → `i8`，`-129` → `i16` ...
- **浮点** → 推导为**能精确表示该值的最小 IEEE 浮点类型**
  - 依次尝试 `f16 → f32 → f64`，选择第一个能精确表示的，表示不了报警告；`bf16` 仅在显式写 `@bf16` 时使用
- **纯虚数**（`2.0j`）→ 推导为**能精确表示其最小复数类型**
  - 规则与浮点一致，但是类型为Complex

特殊常量与显式 cast：

- **`e` / `pi`** 在 lowering 时直接生成 `f64` 常量节点。
- **`expr @ dtype`** 统一视为 `cast<dtype>(expr)` 的语法糖：
  - 例如：`(3//2)@f8` 与 `cast<f8>(3//2)` 语义相同；
  - 字面量场景下（如 `8@i8`），仍保留当前的字面量范围检查与默认 dtype 推导，只是从用户心智上可以把它看成"先按默认规则得到一个字面量，再显式 cast 到目标 dtype"。

## 类型提升（promotion）

类型提升用于二元运算（如 `+ - * / // % **`、比较运算、`if` 两分支合并）。其目标是为两个操作数找一个**共同 dtype**，使计算在该 dtype 下语义明确。
`/` 具有特殊性质，需要单独处理；`//` 仅定义在整数族上，语义为对提升后的整数类型做**地板除（floor division）**。这两个运算在做 dtype 提升前，都会**先检查参与运算的 kind**：

- `/`：仅在 **非整数 kind** 上定义（`Float` 或 `Complex`），若任一操作数是整数（`UInt`/`SInt`）则报 `Incompatible`。
- `//`：仅在 **整数 kind** 上定义（`UInt`/`SInt`），若有 `Float`/`Complex` 参与则报 `Incompatible`。



### 规则列表

`Bool -> UInt -> SInt -> Float -> Complex`，只向上提升。
Float 主干优先原则，IEEE 被视为主干，其他变种进行提升前都会转成 IEEE。


- **RULE 0**：`T + T → T`, `Bool + T → T`
- **RULE 1**：`T(m) + T(n) → T(max(m,n))`
- **RULE 2**：`UInt(m) + SInt(n) → SInt(max(2m, n))`，2m大于64时报警告。
- **RULE 3**：`Int(m) + Float(n) → Float(max(2m, n))`；非 IEEE float 与 Int 不兼容，报错。
- **RULE 4**：`Float<X>(m) + Float<Y>(n)`。
  - `Float<IEEE>(m) + Float<Brain>(n) → Float<IEEE>(max(m, 2n))`
  - else: TODO
- **RULE 5**：`Float(m) + Complex(n) → Complex(max(m*2, n))`；非 IEEE float 与 Complex 不兼容，报错。


## 诊断行为（实现约定）

- lowering 会记录 **info**：每次隐式提升（`Promotion`）。
- lowering 会记录 **warning**：`u64` 参与 `UInt + SInt` 的提升（可能溢出 `i64`）。
- 常量折叠（optimization）对纯整数常量的 `+ - *`：
  - 若结果超出"当前期望 dtype"可表示范围，会自动把 dtype **加宽**（如 `u8 → u16`），并发出 warning；
  - 若超出 `i64`，则抛出error并给出修改提示。
