阶段5-2:文档收尾——vm 指令执行/扫描周期、compiler 寄存器码/符号表/STCompiler说明、executor 入口全部更新为 V2

This commit is contained in:
2026-08-26 10:40:20 +08:00
parent 98d2e86dca
commit 84de006665
6 changed files with 242 additions and 275 deletions
+31 -21
View File
@@ -1,13 +1,13 @@
# STCompiler 使用说明
把 ST 工程(`project.toml` + 若干 `.st`)编译成单一映像 `.stb`。执行由 `BytecodeExecutor`12.9/12.10 实现)负责。
把 ST 工程(`project.toml` + 若干 `.st`)编译成单一映像 `.stb`。执行由 `BytecodeExecutor` 负责。
## 构建
```bash
cmake --preset gcc-debug # 配置
cmake --build --preset gcc-debug # 编译
ctest --test-dir build/gcc-debug # 测试(当前 9 个用例
ctest --test-dir build/gcc-debug # 测试(14/14 全绿
```
可执行文件:`build/gcc-debug/compiler/STCompiler`
@@ -35,29 +35,39 @@ STCompiler <name>.stb --disasm --machine <machine.toml>
```bash
$ STCompiler line1.stb --disasm --machine machine.toml
image: line1.stb (288 bytes, 2 functions, 4 globals, entry fn 1)
dt_ms=10 cycle_limit=100000 hash=0xc3fe4ae74ad45900 model=STATOR1 sha=ok
image: line1.stb (399 bytes)
header:
magic = 0x43545353 # 魔数 "STSC"
version = 2 # 格式版本(V2
model = STATOR2 # 型号标识
...
n_slots = 5 # 槽表条目数
values_size = 7 # 值段字节数
max_stack = 116 # 栈区字节数(编译期算)
sha = ok # 文件尾 SHA-256 完整性
functions:
fn 0: nregs=8, offset=0, len=1
0x0080 RET
fn 1: nregs=13, offset=4, len=17
0x0084 LOAD_I r8, 1
0x0088 STORE_GLOBAL r8, 4
fn 0: nregs=8, offset=0, len=4
0x0098 RET
fn 1: nregs=13, offset=4, len=164
0x009c LOAD.U8 r8, s1
0x00a4 STORE_OFF.U8 r8, s4, 0
...
data (56 bytes):
slots:
[0] addr=0
data (7 bytes):
0x0000: ...
```
说明:
- 指令偏移是**文件绝对字节偏移**,可直接对照 `xxd line1.stb`
- 映像里**没有符号名**(函数表只有 fn_id,数据段无名字映射),因此按 `fn 0` / `fn 1`、槽号显示
- 指令偏移是**文件绝对字节偏移**,可直接对照 `xxd line1.stb`V2 指令变长 4/8/16/32B
- 映像里**没有符号名**(函数表只有 fn_id,槽表/值段无名字映射),因此按 `fn 0` / `fn 1`、槽号显示`--dump-map` 可打印变量/槽映射
- `model=` 显示型号标识(`machine.toml [meta]` 生成);`sha=ok|BAD` 显示文件尾 SHA-256 校验结果
- 文件损坏或打不开 → `error: ...` 退出码 1
## 编译产物(.stb 加固)
- **型号标识[32]**`[meta] name + version` 拼成(如 `"STATOR1"`),写进头偏移 72
- **型号标识[32]**`[meta] name + version` 拼成(如 `"STATOR2"`),写进头V2 头 128B`kOffModelId`=32
- **SHA-256 文件尾[32]**:对文件尾之前全部内容计算;compiler 写侧与 vm 读侧各实现一份
- 执行器读取时型号不匹配 / SHA 不符 → 直接拒绝(详见 `Doc/isa/指令与映像.md` 12.13 修订)
@@ -73,10 +83,10 @@ files:
hash: 0xc3fe4ae74ad45900
$ STCompiler examples/line1/project.toml -o line1.stb --machine compiler/machine.toml
compiled: line1.stb (288 bytes, 2 functions, 4 globals)
compiled: line1.stb (399 bytes, 2 functions, 4 globals)
```
产物:`line1.stb`288 字节:头 104 含型号标识 + 各段 + SHA-256 文件尾)+ `line1.runtime.toml`sidecar)。指令见 `Doc/isa/指令与映像.md`,结构拆解见 `Doc/isa/stb文件格式.md`
产物:`line1.stb`399 字节:头 128B 含型号标识 + 各段 + SHA-256 文件尾)+ `line1.runtime.toml`sidecar)。指令见 `Doc/isa/指令与映像.md`,结构拆解见 `Doc/isa/stb文件格式.md`
## 工程文件(project.toml
@@ -117,15 +127,15 @@ bit = 2
**变量段**`VAR` / `VAR_INPUT` / `VAR_OUTPUT` / `VAR_GLOBAL`(仅 `gvl.file` 顶层)/ `VAR_EXTERNAL`
**类型**`BOOL` / `INT` / `TIME`;内建 FB 类型 `TON` / `TOF` / `TP` / `CTU` / `CTD` / `CTUD` / `R_TRIG` / `F_TRIG`(关键字,不可作变量名)。
**类型**19 种(`BOOL`/`SINT`/`INT`/`DINT`/`LINT`/`BYTE`/`WORD`/`DWORD`/`LWORD`/`USINT`/`UINT`/`UDINT`/`ULINT`/`REAL`/`LREAL`/`TIME`/`DATE`/`TOD`/`DT`;内建 FB 15 条(`TON`/`TOF`/`TP`/`CTU`/`DCTU`/`CTD`/`DCTD`/`CTUD`/`DCTUD`/`R_TRIG`/`F_TRIG`/`SR`/`RS`/`PWM`/`RTC`,关键字,不可作变量名;FB 名三层判定:toml fb 表 → 用户 FB → 类型名)。
**语句**:赋值 `:=``IF / ELSIF / ELSE / END_IF``WHILE / END_WHILE`、FB 调用 `fb(in := ..., ...);`、字段读 `fb.Q`
**表达式**:字面量(`TRUE`/`FALSE`、整数、`T#10ms` 式 TIME)、`NOT``AND`/`OR`**短路**)、比较 `= <> < <= > >=`(不连锁)、算术 `+ - * /`、一元负号、函数调用 `Add(3, 4)`
**表达式**:字面量(`TRUE`/`FALSE`、整数、`T#10ms` 式 TIME`R#`/`D#`/`TOD#`/`DT#` 浮点与日期)、`NOT``AND`/`OR`**短路**)、比较 `= <> < <= > >=`(不连锁)、算术 `+ - * /`、一元负号、函数调用 `Add(3, 4)`
**函数**:结果 = 函数名赋值(`Add := a + b;`);返回类型 `FUNCTION Add : INT`;调用约定:结果 r0、参数 r1..r7(最多 7 个输入,函数内只读)、变量与临时从 r8 起(见 `Doc/compiler/寄存器码.md`)。
**限制(v1 明确不做)**:指针 / `REF` / `CLASS` / `ANY` / `VAR_IN_OUT`(语法层直接拒绝)、链式比较、FB 字段赋值、`REAL`字符串、用户类型套娃、隐式类型转换、函数循环调用(链接层拒绝)、`FUNCTION` 写全局(类型检查层拒绝,含经 `VAR_EXTERNAL`)。
**限制(v1 明确不做)**:指针 / `REF` / `CLASS` / `ANY` / `VAR_IN_OUT`(语法层直接拒绝)、链式比较、FB 字段赋值、字符串、用户类型套娃、**隐式类型转换**(类型检查层拒绝,字面量按目标类型适配)、函数循环调用(链接层拒绝)、`FUNCTION` 写全局(类型检查层拒绝,含经 `VAR_EXTERNAL`)。
## 编译管线与错误类别
@@ -149,10 +159,10 @@ project.toml + .st
- `examples/line1/`:最小闭环(MAIN + MotorStarter FB + I/O + 全局),给人看
- `tests/cases/01~20/`20 个用例(每份 `project.toml` + `.st` + `EXPECTED.md`),编译结果按表
- `tests/`CTest`compiler_toml` / `lexer_tokens` / `parser_syntax` / `linker_links` / `typecheck_types` / `codegen_slice1` / `machine_config` / `vm_cycles` / `cases_all` / `cli_*`
- `tests/`CTest 14 项`compiler_toml` / `lexer_tokens` / `parser_syntax` / `linker_links` / `typecheck_types` / `codegen_slice1` / `isa_roundtrip` / `machine_config` / `vm_test` / `vm_cycles` / `cases_all` / `cli_*`
## 当前状态
- ✅ 可编译:14 个正例用例全部产出 `.stb`型号标识 + SHA-256);6 个负例按期望拒绝
- ✅ 执行:`BytecodeExecutor` 加载 `.stb` 跑扫描周期(型号/SHA 校验、回放、单步)
- ✅ 可编译:14 个正例用例全部产出 `.stb`V2 头 128B + 型号标识 + SHA-256);6 个负例按期望拒绝
- ✅ 执行:`BytecodeExecutor` 加载 `.stb` 跑扫描周期(型号/SHA 校验、回放、单步)V2 槽表两级采样
- ✅ 配置驱动:指令 opcode / 类型元数据 / FB 布局来自 `compiler/machine.toml``--machine`