实现 12.7 类型检查:表达式类型、语句规则、FUNCTION 禁写全局。

- Typecheck.h/cpp:三型(BOOL/INT/TIME)求值,AND/OR/NOT 只吃 BOOL、算术只吃 INT(TIME 无算术)、比较同型、IF/WHILE 条件必须 BOOL
- FUNCTION 禁写全局(含经 VAR_EXTERNAL)——用例 14 点亮;函数名赋值=返回类型
- FB 命名实参匹配字段类型;FB 实例不能当值
- typecheck_test:23 断言(用例 14 + 8 类负例 + 13 个正例),ctest 8/8
This commit is contained in:
2026-08-21 11:26:55 +08:00
parent 93a4662d6a
commit 9cd4997a3a
7 changed files with 826 additions and 1 deletions
+78
View File
@@ -0,0 +1,78 @@
# 类型检查(12.7
compiler 模块的类型规则检查。输入:`Project` + 各 `.st``Unit`AST+ `LinkResult`(符号已解析);输出:通过或 `type error`。全工程定案见 [`初步计划.md`](../初步计划.md) 12.7。
## 做 / 不做
**做**
- `:=`、比较、算术的类型规则;`AND` / `OR` / `NOT` 只吃 `BOOL`
- `FUNCTION` 禁止写全局(含经 `VAR_EXTERNAL`)——用例 14
- FB 调用:命名输入类型匹配;`fb.Q` 字段存在且类型对
- 表达式求值类型:`BOOL` / `INT` / `TIME` 三型
- 无隐式宽化;`INT``TIME` 不混用
**不做(第一版)**
- 常量折叠、溢出区间检查(INT 字面量范围,饱和在 VM 层)
- `FUNCTION` 实参与形参的个数/类型核对(12.7 未要求,只核对 FB 命名输入)
- 变量初始化表达式的类型核对(语法层已限字面量)
## 表达式求值类型
```cpp
enum class TType { Bool, Int, Time };
```
| 节点 | 规则 | 结果 |
|---|---|---|
| `LitBool` / `LitInt` / `LitTime` | — | Bool / Int / Time |
| `VarRef` | 查符号(局部/输入/输出/外部/全局)类型 | 符号类型 |
| `Field` | 实例字段类型(布局已由 12.6 提供) | 字段类型 |
| `Not` | 操作数必须 Bool | Bool |
| `And` / `Or` | 两侧必须 Bool(短路已由语法层保留) | Bool |
| `Cmp` | 两侧同型(Bool/Int/Time 均可比较) | Bool |
| `Add/Sub/Mul/Div` | 两侧必须 Int**TIME 无算术**INT 与 TIME 不混用) | Int |
| `Neg` | 操作数必须 Int | Int |
| `Call` | 函数存在(12.6 已验);结果 = 函数返回类型 | 返回类型 |
| `VarRef` 指向 FB 实例 | 实例不能当值 | type error |
## 语句规则
| 语句 | 规则 |
|---|---|
| `Assign`(普通) | 左值类型 == 表达式类型;左值可为局部/输入/输出/外部/全局 |
| `Assign`(函数名,FUNCTION 内) | 表达式类型 == 函数返回类型(用例 13 约定) |
| **`FUNCTION` 内左值是全局/外部** | **拒绝:`function cannot write global`(用例 14,含经 VAR_EXTERNAL** |
| `FbCall` | 每个命名实参表达式类型 == 实例对应字段类型(布局 12.6 已校验存在性) |
| `If` / `While` | 条件表达式必须 Bool |
## 错误
稳定前缀 `type error`,带文件与行列(尽量带):
```text
type error: AND operands must be BOOL (main.st, line 5, col 9)
type error: type mismatch in assignment to 'q0_0' (INT vs BOOL) (main.st, line 6, col 13)
type error: function cannot write global 'g1' (main.st, line 3, col 5)
type error: TIME has no arithmetic (main.st, line 4, col 12)
type error: FB input 'pt' expects TIME (main.st, line 5, col 16)
```
## 完成标准
1. 用例 14FUNCTION 写全局)→ `type error`12.6 已放行,本阶段点亮)
2. line1 / 用例 07 / 13 / 15 / 17 等合法工程类型检查通过
3. 负例:AND 吃 INT、赋值类型不匹配、INT+TIME、NOT INT、FB 输入类型不匹配、比较异型 → `type error`
4. 全部构建 + `ctest` 无回归
---
## 执行计划(单步确认)
1. **`Typecheck.h`(新建 `compiler/include/compiler/Typecheck.h`**`TType` + `check_project` 声明
2. **`Typecheck.cpp` 前半**:符号类型解析(VarRef/Field/Call/字面量)+ 表达式递归定类型
3. **`Typecheck.cpp` 后半**:语句规则(Assign 含函数名/FUNCTION 禁写全局、FbCall 实参、IF/WHILE 条件)
4. **`typecheck_test``tests/src/typecheck_test.cpp` + CMake**:用例 14 + 负例 + 正例
5. **验证**`cmake --build` + `ctest`(新增 `typecheck_types` 后 8/8 全绿)
6. **提交**`Typecheck.h/cpp` + `typecheck_test` + 文档