diff --git a/tests/README.md b/tests/README.md index 8246209..630b834 100644 --- a/tests/README.md +++ b/tests/README.md @@ -4,6 +4,16 @@ 可以 `add_test` 调 `STCompiler` / `BytecodeExecutor`(编译→执行管线),或直接链接 `compiler` + `vm` 做单元断言。样例工程数据按「一份 toml + 若干 `.st`」分子目录存放,不要做成 library。 +## 用例目录(`cases/`) + +每个用例一个子目录:`project.toml` + `.st` + `EXPECTED.md`(期望:通过 / 报哪类错)。清单与编号见 [`Doc/初步计划.md`](../Doc/初步计划.md) 12.2 节,共 20 个: + +- 正例:01 空 MAIN、02 BOOL、03 短路、04 IF、05 WHILE、07 算术、08 TIME、09 GVL+EXTERNAL、13 FUNCTION、15 FB、17 TON、18 TOF/CTU、20 line1 +- 负例(编译错误/链接失败):10 非 GVL 写全局、11 同名全局、12 io.var 未声明、14 FUNCTION 写全局、16 未声明实例、19 循环调用 +- 运行时故障:06 cycle_limit 打满 + +12.2 完成标准:目录和期望表齐,此时大部分还编不过,属正常。实现阶段逐个点亮。 + ## 第一版要冻的 - 关键字表与约 20 个样例程序 diff --git a/tests/cases/01_empty_main/EXPECTED.md b/tests/cases/01_empty_main/EXPECTED.md new file mode 100644 index 0000000..f89b6a0 --- /dev/null +++ b/tests/cases/01_empty_main/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过 + +- 映像:MAIN(fn_id=0)字节码为一条 `RET`,`nregs=0` +- 运行任意周期数无故障 diff --git a/tests/cases/01_empty_main/main.st b/tests/cases/01_empty_main/main.st new file mode 100644 index 0000000..abb17ed --- /dev/null +++ b/tests/cases/01_empty_main/main.st @@ -0,0 +1,2 @@ +PROGRAM MAIN +END_PROGRAM diff --git a/tests/cases/01_empty_main/project.toml b/tests/cases/01_empty_main/project.toml new file mode 100644 index 0000000..46b4e3b --- /dev/null +++ b/tests/cases/01_empty_main/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case01" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/02_bool_assign/EXPECTED.md b/tests/cases/02_bool_assign/EXPECTED.md new file mode 100644 index 0000000..775f938 --- /dev/null +++ b/tests/cases/02_bool_assign/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过 + +- 执行后 `a` = TRUE、`b` = FALSE +- `TRUE` / `FALSE` 是关键字,不是标识符 diff --git a/tests/cases/02_bool_assign/main.st b/tests/cases/02_bool_assign/main.st new file mode 100644 index 0000000..570f321 --- /dev/null +++ b/tests/cases/02_bool_assign/main.st @@ -0,0 +1,8 @@ +PROGRAM MAIN +VAR + a : BOOL; + b : BOOL; +END_VAR + a := TRUE; + b := FALSE; +END_PROGRAM diff --git a/tests/cases/02_bool_assign/project.toml b/tests/cases/02_bool_assign/project.toml new file mode 100644 index 0000000..96dbd78 --- /dev/null +++ b/tests/cases/02_bool_assign/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case02" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/03_short_circuit/EXPECTED.md b/tests/cases/03_short_circuit/EXPECTED.md new file mode 100644 index 0000000..553b8e5 --- /dev/null +++ b/tests/cases/03_short_circuit/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过 + +- 反汇编中 `AND` / `OR` 必须编成条件跳转(`JT` / `JF`),不得先算两侧再组合 +- v1 表达式无调用、无副作用;「右侧有副作用时不执行」以编译产物含条件跳转为验收标准 diff --git a/tests/cases/03_short_circuit/main.st b/tests/cases/03_short_circuit/main.st new file mode 100644 index 0000000..7af35e7 --- /dev/null +++ b/tests/cases/03_short_circuit/main.st @@ -0,0 +1,9 @@ +PROGRAM MAIN +VAR + a : BOOL; + b : BOOL; + x : BOOL; +END_VAR + x := a AND b; + x := a OR b; +END_PROGRAM diff --git a/tests/cases/03_short_circuit/project.toml b/tests/cases/03_short_circuit/project.toml new file mode 100644 index 0000000..6c28ffc --- /dev/null +++ b/tests/cases/03_short_circuit/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case03" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/04_if_elsif_else/EXPECTED.md b/tests/cases/04_if_elsif_else/EXPECTED.md new file mode 100644 index 0000000..d7abe9d --- /dev/null +++ b/tests/cases/04_if_elsif_else/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过 + +- `sel` = 0 → `out` = 10;`sel` = 1 → `out` = 20;其他 → `out` = 30 +- 必须编成比较 + 条件跳转,不逐分支执行 diff --git a/tests/cases/04_if_elsif_else/main.st b/tests/cases/04_if_elsif_else/main.st new file mode 100644 index 0000000..ddf2cd3 --- /dev/null +++ b/tests/cases/04_if_elsif_else/main.st @@ -0,0 +1,13 @@ +PROGRAM MAIN +VAR + sel : INT; + out : INT; +END_VAR + IF sel = 0 THEN + out := 10; + ELSIF sel = 1 THEN + out := 20; + ELSE + out := 30; + END_IF +END_PROGRAM diff --git a/tests/cases/04_if_elsif_else/project.toml b/tests/cases/04_if_elsif_else/project.toml new file mode 100644 index 0000000..39d6878 --- /dev/null +++ b/tests/cases/04_if_elsif_else/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case04" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/05_while_normal/EXPECTED.md b/tests/cases/05_while_normal/EXPECTED.md new file mode 100644 index 0000000..a73f4f9 --- /dev/null +++ b/tests/cases/05_while_normal/EXPECTED.md @@ -0,0 +1,3 @@ +# 期望:编译通过 + +- 循环结束后 `n` = 10(正常终止,不触发 cycle_limit) diff --git a/tests/cases/05_while_normal/main.st b/tests/cases/05_while_normal/main.st new file mode 100644 index 0000000..90ea81c --- /dev/null +++ b/tests/cases/05_while_normal/main.st @@ -0,0 +1,9 @@ +PROGRAM MAIN +VAR + n : INT; +END_VAR + n := 0; + WHILE n < 10 DO + n := n + 1; + END_WHILE +END_PROGRAM diff --git a/tests/cases/05_while_normal/project.toml b/tests/cases/05_while_normal/project.toml new file mode 100644 index 0000000..2af69b3 --- /dev/null +++ b/tests/cases/05_while_normal/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case05" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/06_while_cycle_limit/EXPECTED.md b/tests/cases/06_while_cycle_limit/EXPECTED.md new file mode 100644 index 0000000..e73793a --- /dev/null +++ b/tests/cases/06_while_cycle_limit/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:运行时故障 + +- 单周期指令数超 `cycle_limit = 10`,VM 报故障并停止 +- 编译本身通过;WHILE 不做终止证明 diff --git a/tests/cases/06_while_cycle_limit/main.st b/tests/cases/06_while_cycle_limit/main.st new file mode 100644 index 0000000..7c3f716 --- /dev/null +++ b/tests/cases/06_while_cycle_limit/main.st @@ -0,0 +1,4 @@ +PROGRAM MAIN + WHILE TRUE DO + END_WHILE +END_PROGRAM diff --git a/tests/cases/06_while_cycle_limit/project.toml b/tests/cases/06_while_cycle_limit/project.toml new file mode 100644 index 0000000..6e5d23a --- /dev/null +++ b/tests/cases/06_while_cycle_limit/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case06" +entry = "program MAIN" +cycle_limit = 10 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/07_int_arith/EXPECTED.md b/tests/cases/07_int_arith/EXPECTED.md new file mode 100644 index 0000000..8f832e9 --- /dev/null +++ b/tests/cases/07_int_arith/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过 + +- `a` = 42、`b` = 10、`c` = 32、`eq` = TRUE +- 溢出饱和:`30000 + 30000` = 32767、`-30000 - 30000` = -32768(由 isa 饱和函数保证) diff --git a/tests/cases/07_int_arith/main.st b/tests/cases/07_int_arith/main.st new file mode 100644 index 0000000..0b140c9 --- /dev/null +++ b/tests/cases/07_int_arith/main.st @@ -0,0 +1,10 @@ +PROGRAM MAIN +VAR + a, b, c : INT; + eq : BOOL; +END_VAR + a := 7 * 6; + b := a / 4; + c := a - b; + eq := c > 30; +END_PROGRAM diff --git a/tests/cases/07_int_arith/project.toml b/tests/cases/07_int_arith/project.toml new file mode 100644 index 0000000..c3a2005 --- /dev/null +++ b/tests/cases/07_int_arith/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case07" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/08_time_literal/EXPECTED.md b/tests/cases/08_time_literal/EXPECTED.md new file mode 100644 index 0000000..3316c3d --- /dev/null +++ b/tests/cases/08_time_literal/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过 + +- `t1` = 10 毫秒、`t2` = 1250 毫秒(内部一律毫秒) +- `TIME` 与 `INT` 不混用;不支持 `T#` 以外的 TIME 语法 diff --git a/tests/cases/08_time_literal/main.st b/tests/cases/08_time_literal/main.st new file mode 100644 index 0000000..48f1d9e --- /dev/null +++ b/tests/cases/08_time_literal/main.st @@ -0,0 +1,7 @@ +PROGRAM MAIN +VAR + t1, t2 : TIME; +END_VAR + t1 := T#10ms; + t2 := T#1s250ms; +END_PROGRAM diff --git a/tests/cases/08_time_literal/project.toml b/tests/cases/08_time_literal/project.toml new file mode 100644 index 0000000..85aff37 --- /dev/null +++ b/tests/cases/08_time_literal/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case08" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/09_gvl_external/EXPECTED.md b/tests/cases/09_gvl_external/EXPECTED.md new file mode 100644 index 0000000..540026d --- /dev/null +++ b/tests/cases/09_gvl_external/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过 + +- 符号表里 `G1` 的 global 与 external 指向**同一槽**,不是新变量 +- 执行后 `x` = 5(初值来自 GVL) diff --git a/tests/cases/09_gvl_external/globals.st b/tests/cases/09_gvl_external/globals.st new file mode 100644 index 0000000..8b63cbf --- /dev/null +++ b/tests/cases/09_gvl_external/globals.st @@ -0,0 +1,3 @@ +VAR_GLOBAL + G1 : INT := 5; +END_VAR diff --git a/tests/cases/09_gvl_external/main.st b/tests/cases/09_gvl_external/main.st new file mode 100644 index 0000000..e16974d --- /dev/null +++ b/tests/cases/09_gvl_external/main.st @@ -0,0 +1,9 @@ +PROGRAM MAIN +VAR_EXTERNAL + G1 : INT; +END_VAR +VAR + x : INT; +END_VAR + x := G1; +END_PROGRAM diff --git a/tests/cases/09_gvl_external/project.toml b/tests/cases/09_gvl_external/project.toml new file mode 100644 index 0000000..f7d30d1 --- /dev/null +++ b/tests/cases/09_gvl_external/project.toml @@ -0,0 +1,11 @@ +[project] +name = "case09" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["globals.st", "main.st"] + +[gvl] +file = "globals.st" diff --git a/tests/cases/10_gvl_wrong_file/EXPECTED.md b/tests/cases/10_gvl_wrong_file/EXPECTED.md new file mode 100644 index 0000000..e778bd8 --- /dev/null +++ b/tests/cases/10_gvl_wrong_file/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译错误 + +- `other.st` 出现 `VAR_GLOBAL`,但 `gvl.file = globals.st` +- 报错类别:VAR_GLOBAL 只允许出现在 gvl.file diff --git a/tests/cases/10_gvl_wrong_file/globals.st b/tests/cases/10_gvl_wrong_file/globals.st new file mode 100644 index 0000000..0fd7899 --- /dev/null +++ b/tests/cases/10_gvl_wrong_file/globals.st @@ -0,0 +1,3 @@ +VAR_GLOBAL + G1 : BOOL; +END_VAR diff --git a/tests/cases/10_gvl_wrong_file/other.st b/tests/cases/10_gvl_wrong_file/other.st new file mode 100644 index 0000000..8ed700a --- /dev/null +++ b/tests/cases/10_gvl_wrong_file/other.st @@ -0,0 +1,5 @@ +PROGRAM MAIN +VAR_GLOBAL + G2 : BOOL; +END_VAR +END_PROGRAM diff --git a/tests/cases/10_gvl_wrong_file/project.toml b/tests/cases/10_gvl_wrong_file/project.toml new file mode 100644 index 0000000..8a0108f --- /dev/null +++ b/tests/cases/10_gvl_wrong_file/project.toml @@ -0,0 +1,11 @@ +[project] +name = "case10" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["globals.st", "other.st"] + +[gvl] +file = "globals.st" diff --git a/tests/cases/11_duplicate_global/EXPECTED.md b/tests/cases/11_duplicate_global/EXPECTED.md new file mode 100644 index 0000000..c87a3b0 --- /dev/null +++ b/tests/cases/11_duplicate_global/EXPECTED.md @@ -0,0 +1,3 @@ +# 期望:链接失败 + +- 同名 `VAR_GLOBAL`(G1)出现两次,禁止覆盖 diff --git a/tests/cases/11_duplicate_global/globals.st b/tests/cases/11_duplicate_global/globals.st new file mode 100644 index 0000000..f89fdf4 --- /dev/null +++ b/tests/cases/11_duplicate_global/globals.st @@ -0,0 +1,7 @@ +VAR_GLOBAL + G1 : INT; +END_VAR + +VAR_GLOBAL + G1 : INT; +END_VAR diff --git a/tests/cases/11_duplicate_global/main.st b/tests/cases/11_duplicate_global/main.st new file mode 100644 index 0000000..abb17ed --- /dev/null +++ b/tests/cases/11_duplicate_global/main.st @@ -0,0 +1,2 @@ +PROGRAM MAIN +END_PROGRAM diff --git a/tests/cases/11_duplicate_global/project.toml b/tests/cases/11_duplicate_global/project.toml new file mode 100644 index 0000000..ed7fcbb --- /dev/null +++ b/tests/cases/11_duplicate_global/project.toml @@ -0,0 +1,11 @@ +[project] +name = "case11" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["globals.st", "main.st"] + +[gvl] +file = "globals.st" diff --git a/tests/cases/12_io_unknown_var/EXPECTED.md b/tests/cases/12_io_unknown_var/EXPECTED.md new file mode 100644 index 0000000..6553fcb --- /dev/null +++ b/tests/cases/12_io_unknown_var/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译错误 + +- `[[io.input]]` 的 `var = "Nope"` 未在 GVL 声明 +- 报错类别:io.var 未在 GVL(io 不创造变量) diff --git a/tests/cases/12_io_unknown_var/globals.st b/tests/cases/12_io_unknown_var/globals.st new file mode 100644 index 0000000..0fd7899 --- /dev/null +++ b/tests/cases/12_io_unknown_var/globals.st @@ -0,0 +1,3 @@ +VAR_GLOBAL + G1 : BOOL; +END_VAR diff --git a/tests/cases/12_io_unknown_var/main.st b/tests/cases/12_io_unknown_var/main.st new file mode 100644 index 0000000..abb17ed --- /dev/null +++ b/tests/cases/12_io_unknown_var/main.st @@ -0,0 +1,2 @@ +PROGRAM MAIN +END_PROGRAM diff --git a/tests/cases/12_io_unknown_var/project.toml b/tests/cases/12_io_unknown_var/project.toml new file mode 100644 index 0000000..87db796 --- /dev/null +++ b/tests/cases/12_io_unknown_var/project.toml @@ -0,0 +1,16 @@ +[project] +name = "case12" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["globals.st", "main.st"] + +[gvl] +file = "globals.st" + +[[io.input]] +var = "Nope" +channel = 0 +bit = 0 diff --git a/tests/cases/13_function_call/EXPECTED.md b/tests/cases/13_function_call/EXPECTED.md new file mode 100644 index 0000000..0525049 --- /dev/null +++ b/tests/cases/13_function_call/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过 + +- `CALL fn_id` + 有界调用帧;函数无内部状态 +- 执行后 `x` = 7;结果值 = 函数名赋值(`Add := ...`) diff --git a/tests/cases/13_function_call/main.st b/tests/cases/13_function_call/main.st new file mode 100644 index 0000000..32597f9 --- /dev/null +++ b/tests/cases/13_function_call/main.st @@ -0,0 +1,13 @@ +FUNCTION Add : INT +VAR_INPUT + a, b : INT; +END_VAR + Add := a + b; +END_FUNCTION + +PROGRAM MAIN +VAR + x : INT; +END_VAR + x := Add(3, 4); +END_PROGRAM diff --git a/tests/cases/13_function_call/project.toml b/tests/cases/13_function_call/project.toml new file mode 100644 index 0000000..a3a31a3 --- /dev/null +++ b/tests/cases/13_function_call/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case13" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/14_function_write_global/EXPECTED.md b/tests/cases/14_function_write_global/EXPECTED.md new file mode 100644 index 0000000..c7b5913 --- /dev/null +++ b/tests/cases/14_function_write_global/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译错误 + +- `FUNCTION` 内写全局(此处经 `VAR_EXTERNAL` 写 `G1`) +- 报错类别:FUNCTION 禁止写全局 diff --git a/tests/cases/14_function_write_global/globals.st b/tests/cases/14_function_write_global/globals.st new file mode 100644 index 0000000..ab85e9b --- /dev/null +++ b/tests/cases/14_function_write_global/globals.st @@ -0,0 +1,3 @@ +VAR_GLOBAL + G1 : INT; +END_VAR diff --git a/tests/cases/14_function_write_global/main.st b/tests/cases/14_function_write_global/main.st new file mode 100644 index 0000000..3612310 --- /dev/null +++ b/tests/cases/14_function_write_global/main.st @@ -0,0 +1,9 @@ +FUNCTION Bad : INT +VAR_EXTERNAL + G1 : INT; +END_VAR + G1 := 1; +END_FUNCTION + +PROGRAM MAIN +END_PROGRAM diff --git a/tests/cases/14_function_write_global/project.toml b/tests/cases/14_function_write_global/project.toml new file mode 100644 index 0000000..6089ead --- /dev/null +++ b/tests/cases/14_function_write_global/project.toml @@ -0,0 +1,11 @@ +[project] +name = "case14" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["globals.st", "main.st"] + +[gvl] +file = "globals.st" diff --git a/tests/cases/15_fb_instance/EXPECTED.md b/tests/cases/15_fb_instance/EXPECTED.md new file mode 100644 index 0000000..5478127 --- /dev/null +++ b/tests/cases/15_fb_instance/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过 + +- FB 实例固定布局,`starter.Q` 字段偏移编译期算死 +- 命名输入绑定 `start` / `stop`;执行后 `q` = TRUE diff --git a/tests/cases/15_fb_instance/main.st b/tests/cases/15_fb_instance/main.st new file mode 100644 index 0000000..087c1b1 --- /dev/null +++ b/tests/cases/15_fb_instance/main.st @@ -0,0 +1,8 @@ +PROGRAM MAIN +VAR + starter : MotorStarter; + q : BOOL; +END_VAR + starter(start := TRUE, stop := FALSE); + q := starter.Q; +END_PROGRAM diff --git a/tests/cases/15_fb_instance/motor.st b/tests/cases/15_fb_instance/motor.st new file mode 100644 index 0000000..db037f9 --- /dev/null +++ b/tests/cases/15_fb_instance/motor.st @@ -0,0 +1,9 @@ +FUNCTION_BLOCK MotorStarter +VAR_INPUT + start, stop : BOOL; +END_VAR +VAR_OUTPUT + Q : BOOL; +END_VAR + Q := start AND NOT stop; +END_FUNCTION_BLOCK diff --git a/tests/cases/15_fb_instance/project.toml b/tests/cases/15_fb_instance/project.toml new file mode 100644 index 0000000..e33b8b6 --- /dev/null +++ b/tests/cases/15_fb_instance/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case15" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["motor.st", "main.st"] diff --git a/tests/cases/16_fb_undeclared/EXPECTED.md b/tests/cases/16_fb_undeclared/EXPECTED.md new file mode 100644 index 0000000..76a94bc --- /dev/null +++ b/tests/cases/16_fb_undeclared/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译错误 + +- 调用 `starter(...)` 但未声明实例 +- 报错类别:FB 必须先声明实例才能调用 diff --git a/tests/cases/16_fb_undeclared/main.st b/tests/cases/16_fb_undeclared/main.st new file mode 100644 index 0000000..f42d0cb --- /dev/null +++ b/tests/cases/16_fb_undeclared/main.st @@ -0,0 +1,7 @@ +PROGRAM MAIN +VAR + q : BOOL; +END_VAR + starter(start := TRUE, stop := FALSE); + q := starter.Q; +END_PROGRAM diff --git a/tests/cases/16_fb_undeclared/motor.st b/tests/cases/16_fb_undeclared/motor.st new file mode 100644 index 0000000..db037f9 --- /dev/null +++ b/tests/cases/16_fb_undeclared/motor.st @@ -0,0 +1,9 @@ +FUNCTION_BLOCK MotorStarter +VAR_INPUT + start, stop : BOOL; +END_VAR +VAR_OUTPUT + Q : BOOL; +END_VAR + Q := start AND NOT stop; +END_FUNCTION_BLOCK diff --git a/tests/cases/16_fb_undeclared/project.toml b/tests/cases/16_fb_undeclared/project.toml new file mode 100644 index 0000000..19123fd --- /dev/null +++ b/tests/cases/16_fb_undeclared/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case16" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["motor.st", "main.st"] diff --git a/tests/cases/17_ton/EXPECTED.md b/tests/cases/17_ton/EXPECTED.md new file mode 100644 index 0000000..b05ed8a --- /dev/null +++ b/tests/cases/17_ton/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译通过;运行行为与 Δt 一致 + +- `dt_ms = 10`、`PT = 30ms`:前 2 周期 `Q` = FALSE,第 3 周期起 `Q` = TRUE +- 累计用映像里的 Δt,不用 wall clock diff --git a/tests/cases/17_ton/main.st b/tests/cases/17_ton/main.st new file mode 100644 index 0000000..4d7447b --- /dev/null +++ b/tests/cases/17_ton/main.st @@ -0,0 +1,8 @@ +PROGRAM MAIN +VAR + t : TON; + q : BOOL; +END_VAR + t(in := TRUE, pt := T#30ms); + q := t.Q; +END_PROGRAM diff --git a/tests/cases/17_ton/project.toml b/tests/cases/17_ton/project.toml new file mode 100644 index 0000000..2726f46 --- /dev/null +++ b/tests/cases/17_ton/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case17" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/18_tof_ctu/EXPECTED.md b/tests/cases/18_tof_ctu/EXPECTED.md new file mode 100644 index 0000000..486bcb0 --- /dev/null +++ b/tests/cases/18_tof_ctu/EXPECTED.md @@ -0,0 +1,5 @@ +# 期望:编译通过;运行行为与 Δt 一致 + +- TOF:`in` 掉电后 `Q` 保持 `PT` 时长(20ms)再复位 +- CTU:`cu` 上升沿计数 +1;`r` 复位;`CV` 到 `PV`(3)时 `Q` = TRUE +- 内部累计用映像 Δt,不用 wall clock diff --git a/tests/cases/18_tof_ctu/main.st b/tests/cases/18_tof_ctu/main.st new file mode 100644 index 0000000..b3ab44a --- /dev/null +++ b/tests/cases/18_tof_ctu/main.st @@ -0,0 +1,13 @@ +PROGRAM MAIN +VAR + tf : TOF; + c : CTU; + q1, q2 : BOOL; + cnt : INT; +END_VAR + tf(in := FALSE, pt := T#20ms); + q1 := tf.Q; + c(cu := TRUE, r := FALSE, pv := 3); + q2 := c.Q; + cnt := c.CV; +END_PROGRAM diff --git a/tests/cases/18_tof_ctu/project.toml b/tests/cases/18_tof_ctu/project.toml new file mode 100644 index 0000000..37b21e6 --- /dev/null +++ b/tests/cases/18_tof_ctu/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case18" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/19_recursive_call/EXPECTED.md b/tests/cases/19_recursive_call/EXPECTED.md new file mode 100644 index 0000000..608fa62 --- /dev/null +++ b/tests/cases/19_recursive_call/EXPECTED.md @@ -0,0 +1,4 @@ +# 期望:编译错误 + +- `A` ↔ `B` 函数体循环调用(无界递归) +- 报错类别:有界 CALL 检查拒绝循环调用 diff --git a/tests/cases/19_recursive_call/main.st b/tests/cases/19_recursive_call/main.st new file mode 100644 index 0000000..8cf5455 --- /dev/null +++ b/tests/cases/19_recursive_call/main.st @@ -0,0 +1,14 @@ +FUNCTION A : INT + A := B(); +END_FUNCTION + +FUNCTION B : INT + B := A(); +END_FUNCTION + +PROGRAM MAIN +VAR + x : INT; +END_VAR + x := A(); +END_PROGRAM diff --git a/tests/cases/19_recursive_call/project.toml b/tests/cases/19_recursive_call/project.toml new file mode 100644 index 0000000..36e8e6c --- /dev/null +++ b/tests/cases/19_recursive_call/project.toml @@ -0,0 +1,8 @@ +[project] +name = "case19" +entry = "program MAIN" +cycle_limit = 1000 +dt_ms = 10 + +[files] +st = ["main.st"] diff --git a/tests/cases/20_line1/EXPECTED.md b/tests/cases/20_line1/EXPECTED.md new file mode 100644 index 0000000..dee5181 --- /dev/null +++ b/tests/cases/20_line1/EXPECTED.md @@ -0,0 +1,11 @@ +# 期望:编译通过;I 组合 → `Q0_0` 与急停语义一致 + +| I0_0 | I0_1 | EmergencyStop | Q0_0 | +|---|---|---|---| +| TRUE | FALSE | FALSE | TRUE | +| TRUE | TRUE | FALSE | FALSE | +| FALSE | FALSE | FALSE | FALSE | +| TRUE | FALSE | TRUE | FALSE | + +- `Q0_0 = I0_0 AND NOT I0_1 AND NOT EmergencyStop` +- 固定 I 序列跑两遍,槽位与工程哈希一致(回放确定性) diff --git a/tests/cases/20_line1/globals.st b/tests/cases/20_line1/globals.st new file mode 100644 index 0000000..6baeaa6 --- /dev/null +++ b/tests/cases/20_line1/globals.st @@ -0,0 +1,7 @@ +(* globals.st *) +VAR_GLOBAL + EmergencyStop : BOOL := FALSE; + I0_0 : BOOL; + I0_1 : BOOL; + Q0_0 : BOOL; +END_VAR diff --git a/tests/cases/20_line1/main.st b/tests/cases/20_line1/main.st new file mode 100644 index 0000000..fef1b92 --- /dev/null +++ b/tests/cases/20_line1/main.st @@ -0,0 +1,8 @@ +(* main.st *) +PROGRAM MAIN +VAR + starter : MotorStarter; +END_VAR + starter(start := I0_0, stop := I0_1); + Q0_0 := starter.Q; +END_PROGRAM diff --git a/tests/cases/20_line1/motor.st b/tests/cases/20_line1/motor.st new file mode 100644 index 0000000..69de7df --- /dev/null +++ b/tests/cases/20_line1/motor.st @@ -0,0 +1,13 @@ +(* motor.st *) +FUNCTION_BLOCK MotorStarter +VAR_EXTERNAL + EmergencyStop : BOOL; +END_VAR +VAR_INPUT + start, stop : BOOL; +END_VAR +VAR_OUTPUT + Q : BOOL; +END_VAR + Q := start AND NOT stop AND NOT EmergencyStop; +END_FUNCTION_BLOCK diff --git a/tests/cases/20_line1/project.toml b/tests/cases/20_line1/project.toml new file mode 100644 index 0000000..3f6658f --- /dev/null +++ b/tests/cases/20_line1/project.toml @@ -0,0 +1,28 @@ +[project] +name = "line1" +entry = "program MAIN" +cycle_limit = 100000 +dt_ms = 10 + +[files] +st = ["globals.st", "motor.st", "main.st"] + +# 全工程只允许这一处出现 VAR_GLOBAL(第一版:单个文件) +[gvl] +file = "globals.st" + +# 可选:I/O 绑定。不创造变量,var 必须已在 GVL 里声明 +[[io.input]] +var = "EmergencyStop" +channel = 0 +bit = 2 + +[[io.input]] +var = "I0_0" +channel = 0 +bit = 0 + +[[io.output]] +var = "Q0_0" +channel = 0 +bit = 0