# StScan 子集 ST + 扫描周期虚拟机。IEC 风格的子集 ST:用 `project.toml` 组织多个 `.st`,编译成单一映像,由寄存器虚拟机按扫描周期执行。 方案见 [`Doc/初步计划.md`](Doc/初步计划.md),模块文档见 [`Doc/索引.md`](Doc/索引.md)。 ```text 多个 .st + machine.toml(指令/类型/FB 布局) ↑ project.toml 列出源文件;machine.toml 唯一事实来源 ↓ STCompiler(compiler 库:词法 / 语法 → 符号表 → 类型检查 → 寄存器码 → 链接;编码查 machine.toml) ↓ .stb 映像(头 104 含型号标识 + 段 + SHA-256 文件尾)+ .runtime.toml sidecar ↓ BytecodeExecutor(vm 库按扫描周期执行;型号/SHA 校验;喂 I、收 Q、给 Δt、回放) ``` ## 目录 ```text . ├── CMakeLists.txt # 顶层工程:加入各目标,并启用测试 ├── cmake/ # CMake 辅助(警告、C++ 标准等),不是业务模块 ├── isa/ # 共享契约:指令、映像、定宽类型 ├── compiler/ # ST / toml 编译器(库)+ STCompiler 可执行入口 ├── vm/ # 寄存器虚拟机(库) ├── executor/ # BytecodeExecutor:加载 .stb + sidecar 并执行 ├── examples/ # 样例工程(给人看、跑通最小闭环) │ └── line1/ # MAIN + Motor FB + I/O │ ├── project.toml │ ├── globals.st │ ├── motor.st │ └── main.st ├── tests/ # 自动化用例(语法、链接、指令、回放) ├── third_party/ # 第三方(如 toml 解析),compiler 私有链接 └── Doc/ # 设计文档 ``` 样例和测试是数据,不做成 CMake 库。每个用例是一份 toml + 若干 `.st`,按工程子目录存放。 ## 模块与 CMake 目标 三个静态库与两个可执行,与目录一一对应。`compiler` 与 `vm` 不互相链接。指令/类型/FB 布局的**唯一事实来源是 `compiler/machine.toml`**(编译器运行时加载);`isa` 归执行器侧(`vm` 依赖),只管指令定义。依赖方向:`STCompiler → compiler`、`BytecodeExecutor → vm → isa`。 | 目录 | 目标 | 类型 | 依赖 | 职责 | |---|---|---|---|---| | `isa/` | `isa` | `STATIC` | 无 | 指令定义(Op/Instr/Encode/Types/饱和/disasm),**归执行器侧** | | `compiler/` | `compiler` | `STATIC` | toml++(私有) | 读 toml、收齐 `.st`、解析、链接、定址、类型检查、编寄存器码、写 `.stb`(指令 opcode/类型/FB 布局全部来自 `machine.toml`) | | `vm/` | `vm` | `STATIC` | `isa` | 一台 VM、一个入口、一份映像;扫描周期、寄存器、FB、有界 `CALL` / `RET`;自带 `.stb` 读实现 + 型号/SHA-256 校验 | | `compiler/` | `STCompiler` | `EXECUTABLE` | `compiler` | `STCompiler -o .stb --machine `:编译并写映像 + sidecar;`--disasm` 可反汇编 | | `executor/` | `BytecodeExecutor` | `EXECUTABLE` | `vm`、`isa` | `BytecodeExecutor .stb`:加载映像 + sidecar,采样 I、执行 `PROGRAM MAIN`、写回 Q、用 Δt 推进定时器 / 计数器、回放 | 词法、语法、符号表、检查、codegen、链接都留在 `compiler` 一个库里,不再拆 CMake 子库。 ### `isa` 归执行器侧(`vm` 依赖),**只管指令定义**:Op 枚举 / Instr 打包 / Encode(编解码·disasm)/ Types(饱和)。执行器执行 switch 在 `vm`。 ### `compiler` toml **不声明变量**,只列出源文件、指定唯一 GVL、可选地把已有全局接到硬件。`VAR_GLOBAL` 第一版只允许出现在 `gvl.file`(如 `globals.st`)。指令 opcode / 类型元数据 / FB 布局**全部来自 `compiler/machine.toml`**(`STCompiler --machine` 加载,强校验后编译)。 ### `vm` 每个扫描周期:采样 I → 从 `PROGRAM MAIN` 的 `pc=0` 执行到 `RET` → 写回 Q → 用本周期 Δt 推进内置 FB。无 GC、无堆、无线程;变量编译期分配。读取 `.stb` 时**校验型号标识与 SHA-256**(不匹配/篡改 → 拒绝)。 ### `executor`(BytecodeExecutor) `STCompiler` 编译出 `.stb`(含型号标识 + SHA-256)+ `.runtime.toml`(sidecar:I/O 绑定);`BytecodeExecutor` 加载后按扫描周期跑。`dt_ms` / `cycle_limit` 从映像头取。 ### `examples/` 与 `tests/` | 目录 | 用途 | |---|---| | `examples/line1/` | 计划中的最小样例:全局、`MotorStarter` FB、`PROGRAM MAIN` | | `tests/` | 冻关键字、指令、符号表、链接错误(重复 `VAR_GLOBAL`、`io.var` 未声明等) | `tests/` 通过 `add_test` 调 `STCompiler` / `BytecodeExecutor`,或直接链接 `compiler` + `vm`。样例工程数据按「一份 toml + 若干 `.st`」分子目录存放,不做成 library。