Files
Admin 9cd4997a3a 实现 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
2026-08-21 11:26:55 +08:00

79 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 类型检查(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` + 文档