- 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
3.6 KiB
3.6 KiB
类型检查(12.7)
compiler 模块的类型规则检查。输入:Project + 各 .st 的 Unit(AST)+ LinkResult(符号已解析);输出:通过或 type error。全工程定案见 初步计划.md 12.7。
做 / 不做
做
:=、比较、算术的类型规则;AND/OR/NOT只吃BOOLFUNCTION禁止写全局(含经VAR_EXTERNAL)——用例 14- FB 调用:命名输入类型匹配;
fb.Q字段存在且类型对 - 表达式求值类型:
BOOL/INT/TIME三型 - 无隐式宽化;
INT与TIME不混用
不做(第一版)
- 常量折叠、溢出区间检查(INT 字面量范围,饱和在 VM 层)
FUNCTION实参与形参的个数/类型核对(12.7 未要求,只核对 FB 命名输入)- 变量初始化表达式的类型核对(语法层已限字面量)
表达式求值类型
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,带文件与行列(尽量带):
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)
完成标准
- 用例 14(FUNCTION 写全局)→
type error(12.6 已放行,本阶段点亮) - line1 / 用例 07 / 13 / 15 / 17 等合法工程类型检查通过
- 负例:AND 吃 INT、赋值类型不匹配、INT+TIME、NOT INT、FB 输入类型不匹配、比较异型 →
type error - 全部构建 +
ctest无回归
执行计划(单步确认)
Typecheck.h(新建compiler/include/compiler/Typecheck.h):TType+check_project声明Typecheck.cpp前半:符号类型解析(VarRef/Field/Call/字面量)+ 表达式递归定类型Typecheck.cpp后半:语句规则(Assign 含函数名/FUNCTION 禁写全局、FbCall 实参、IF/WHILE 条件)typecheck_test(tests/src/typecheck_test.cpp+ CMake):用例 14 + 负例 + 正例- 验证:
cmake --build+ctest(新增typecheck_types后 8/8 全绿) - 提交:
Typecheck.h/cpp+typecheck_test+ 文档