# 类型检查(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. 用例 14(FUNCTION 写全局)→ `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` + 文档