文档同步双可执行架构:STCompiler + BytecodeExecutor。

- 12.10 重写为两条命令:STCompiler 编译出 .stb + sidecar,BytecodeExecutor 加载执行
- 12.0 删独立 stc.exe,12.13 依赖方向改为 STCompiler/BytecodeExecutor
- 指令与映像.md 新增「映像文件(.stb)与 sidecar」节,I/O 绑定不进映像
- host/ 改名 executor/,宿主入口.md 重写为执行器入口.md
- README / tests / examples / isa README 同步
This commit is contained in:
2026-08-19 13:59:50 +08:00
parent 94accd52c3
commit 7c855b1618
11 changed files with 111 additions and 87 deletions
+3 -2
View File
@@ -1,8 +1,8 @@
# 编译管线
compiler 模块:ST / toml 编译器。CMake 目标:`compiler``STATIC`),依赖 [`指令与映像.md`](../isa/指令与映像.md)。
compiler 模块:ST / toml 编译器。CMake 目标:`compiler``STATIC`),依赖 [`指令与映像.md`](../isa/指令与映像.md)。可执行入口 `STCompiler`(本模块 `src/main.cpp`,链 `compiler` + `isa`)。
读齐工程后走直通 pass,产出单一映像,不上 LLVM。词法、语法、符号表、检查、codegen、链接都留在本库,不再拆 CMake 子库。
读齐工程后走直通 pass,产出单一映像文件,不上 LLVM。词法、语法、符号表、检查、codegen、链接都留在本库,不再拆 CMake 子库。
语言规则、toml 字段、链接与第 12 节阶段见 [`初步计划.md`](../初步计划.md)。指令和映像只认 [`指令与映像.md`](../isa/指令与映像.md)。
@@ -16,6 +16,7 @@ compiler 模块:ST / toml 编译器。CMake 目标:`compiler``STATIC`
→ 类型检查
→ 按 PROGRAM / FUNCTION / FB 编寄存器码
→ 回填跳转、写映像头与工程哈希
→ 写 <name>.stb(映像)与 <name>.runtime.tomlsidecario 绑定)
```
## 边界
+18
View File
@@ -0,0 +1,18 @@
# 执行器入口
BytecodeExecutor 模块:可执行入口。CMake 目标:`BytecodeExecutor``EXECUTABLE`),链接 `vm``isa`**不链 `compiler`**。源码目录 `executor/`
第一版两个可执行:`STCompiler` 编译出 `<name>.stb``<name>.runtime.toml``BytecodeExecutor` 加载映像按扫描周期跑。总顺序见 [`初步计划.md`](../初步计划.md) 第 12.10 节。
## 职责
- 加载 `.stb` 映像与 `<name>.runtime.toml` sidecarI/O 绑定 var → 槽号 → channel/bit
- 按 sidecar 采样 I、写回 Q(不创造变量)
- `dt_ms` / `cycle_limit` 从映像头取,推进 `TON` / `TOF` / `CTU`
- 单步、看寄存器和映像、按录制的 `I` 回放
## 边界
- 指令与映像编码见 [`指令与映像.md`](../isa/指令与映像.md)
- ST 解析与链接见 [`编译管线.md`](../compiler/编译管线.md),本模块不碰 `.st`
- 寄存器执行循环见 [`扫描周期.md`](../vm/扫描周期.md)
-18
View File
@@ -1,18 +0,0 @@
# 宿主入口
host 模块:可执行入口。CMake 目标:`host``EXECUTABLE`),链接 `compiler``vm`
第一版一条命令:读工程 → 编译映像 → 按扫描周期跑。不拆独立的编译器可执行文件。总顺序见 [`初步计划.md`](../初步计划.md) 第 12.10 节。
## 职责
-`project.toml` 和其中的 `.st`,交给 `compiler`
-`[[io.input]]` / `[[io.output]]` 采样 I、写回 Q(不创造变量)
-`dt_ms` 交给 VM,推进 `TON` / `TOF` / `CTU`
- 单步、看寄存器和映像、按录制的 `I` 回放
## 边界
- 指令编码见 [`指令与映像.md`](../isa/指令与映像.md)
- ST 解析与链接见 [`编译管线.md`](../compiler/编译管线.md)
- 寄存器执行循环见 [`扫描周期.md`](../vm/扫描周期.md)
+30 -15
View File
@@ -7,8 +7,8 @@ isa 模块规范:指令集 + 映像 + 定宽类型。不是编译器,不把
全工程定案见 [`初步计划.md`](../初步计划.md)。**类型、指令编码、映像布局以本文为准**,不要另写一份互相打架的表。头文件实现本文,不另当规范。
```text
host → compiler → isa
host → vm → isa
STCompiler → compiler → isa
BytecodeExecutor → vm → isa
```
CMake 目标:`isa``STATIC`),无依赖。公开头:`isa/include/isa/`
@@ -22,7 +22,7 @@ CMake 目标:`isa``STATIC`),无依赖。公开头:`isa/include/isa/`
- 操作码与 32 位指令布局
- 映像头与段(函数字节码、全局 / FB 槽、工程哈希)
- `BOOL` / `INT` / `TIME` 宽度与溢出规则
- 编解码、工程哈希、一条指令的文本转储(给 host 打印)
- 编解码、工程哈希、一条指令的文本转储(反汇编,给 STCompiler `--disasm` 与测试打印)
**不做**
@@ -40,7 +40,7 @@ CMake 目标:`isa``STATIC`),无依赖。公开头:`isa/include/isa/`
|---|---|
| `BOOL` | `uint8_t`,只允许 0/1 |
| `INT` | `int16_t`IEC `INT` |
| `TIME` | `int32_t` 毫秒;与 `INT` 不混用 |
| `TIME` | `int64_t` 毫秒(有符号);与 `INT` 不混用 |
| 整数溢出 | **饱和**(夹到 `INT` 最小/最大) |
| 字节序 | 小端 |
| 指令宽度 | 32 bit,一种主布局 |
@@ -49,8 +49,8 @@ CMake 目标:`isa``STATIC`),无依赖。公开头:`isa/include/isa/`
| `CALL` | 立即数 `fn_id`u16),无函数指针 |
| 映像魔数 | `STSC`,版本 `1` |
| 工程哈希 | 源文件路径排序后对内容做 FNV-1a 64(非密码学) |
| I/O 绑定 | **不进映像**;编译期把 `var` 收成槽号,channel/bit 留在 host 读 toml |
| 不做 | `REAL`、隐式宽化、独立 `stc.exe` |
| I/O 绑定 | **不进映像**;编译期把 `var` 收成槽号,channel/bit 由 STCompiler 写进 sidecar`.runtime.toml`),BytecodeExecutor 读 sidecar 采样 |
| 不做 | `REAL`、隐式宽化 |
---
@@ -60,10 +60,16 @@ C++11 定宽:
- `BOOL``uint8_t`0/1
- `INT``int16_t`;加减乘除溢出饱和
- `TIME``int32_t` 毫秒
- `TIME``int64_t` 毫秒,有符号
`compiler``vm` 都按同一规则,不再另选溢出策略。
`TIME``int64_t` 的理由(冻结,不再反复问):
- 有符号:`TOF` 剩余时间、两个时间点相减会出负值,免去无符号边界处理
- 64 位:为将来 `DATE_AND_TIME`(毫秒时间戳)与 `TON` / `TOF` / `TP` 的 64 位定时器预留;毫秒量程约 2.9 亿年,扫描周期场景永不溢出
- 代价:槽位 8 字节对齐。**槽位对齐规则**:`BOOL` 1 字节、`INT` 2 字节、`TIME` 8 字节;连续排列按类型对齐,需要时插 padding,偏移以本规则为准。
---
## 指令
@@ -123,6 +129,15 @@ FB 实例固定布局,字段偏移编译期算死。
---
## 映像文件(`.stb`)与 sidecar
编译产物是单文件 `<name>.stb`:映像头 + 各段按本文布局连续排,魔数 `STSC`、版本 `1`、小端。`STCompiler` 写,`BytecodeExecutor` 读。
- `dt_ms` / `cycle_limit` 在映像头,执行器只认映像,不重复配置。
- I/O 绑定不进映像:`STCompiler` 另写 sidecar `<name>.runtime.toml`,内容是 `var`(已解析槽号)→ `channel` / `bit``BytecodeExecutor` 读 sidecar 做采样与写回,不创造变量。
---
## 目录与 CMake
```text
@@ -130,11 +145,11 @@ isa/
CMakeLists.txt
README.md # 代码目录入口,指向本文
include/isa/
Types.hpp # 宽度、饱和、槽值表示
Op.hpp # 操作码枚举 + 助记符
Instr.hpp # 32-bit 打包/拆字段(inline
Image.hpp # 头、段、函数表/常量表/FB 布局
Encode.hpp # 编解码、哈希、反汇编一行
Types.h # 宽度、饱和、槽值表示
Op.h # 操作码枚举 + 助记符
Instr.h # 32-bit 打包/拆字段(inline
Image.h # 头、段、函数表/常量表/FB 布局
Encode.h # 编解码、哈希、反汇编一行
src/
Encode.cpp
Image.cpp
@@ -151,10 +166,10 @@ target_include_directories(isa PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
## 实现顺序(对齐初步计划 12.0~12.1)
1. `Types.hpp`:三类型 + `sat_add` 等饱和函数(inline 即可)
2. `Op.hpp` + `Instr.hpp`:枚举与 32-bit 编解码
1. `Types.h`:三类型 + `sat_add` 等饱和函数(inline 即可)
2. `Op.h` + `Instr.h`:枚举与 32-bit 编解码
3. `Encode.cpp``encode` / `decode` / `disasm` 一条指令
4. `Image.hpp` + `Image.cpp`:头布局、FNV-1a、读写缓冲(先能写空映像 + 一条 `RET`
4. `Image.h` + `Image.cpp`:头布局、FNV-1a、读写缓冲(先能写空映像 + 一条 `RET`
5. 测试随后在 `tests/` 加编解码往返;本阶段以头文件和库能链为准
不在本模块做:VM `switch`、toml、关键字、符号表。
+2 -2
View File
@@ -7,7 +7,7 @@ vm 模块:寄存器虚拟机。CMake 目标:`vm``STATIC`),只依赖 [
## 扫描周期
```text
1. 按 toml 的 io 绑定,采样 → I / 输入全局
1. 按 sidecar 的 io 绑定,采样 → I / 输入全局
2. 从 PROGRAM MAIN 的 pc=0 执行到 RET
3. 写回 Q / 输出全局
4. 用本周期 Δt 推进 TON / TOF / CTU(不用 wall clock
@@ -19,4 +19,4 @@ vm 模块:寄存器虚拟机。CMake 目标:`vm``STATIC`),只依赖 [
- 局部 / `VAR` = 固定寄存器;`nregs` 在函数头
- `CALL` 目标是立即数 `fn_id`,有界调用栈
- 无 GC、无堆、无线程;每周期受 `cycle_limit` 限制
- I/O 从哪来、Δt 谁给、回放怎么喂,属于 `host`
- I/O 从哪来、Δt 谁给、回放怎么喂,属于 `BytecodeExecutor`(读 `.stb` + sidecar
+21 -15
View File
@@ -271,13 +271,13 @@ RET
## 10. 目录
仓库布局见根目录 `README.md`。实现时按四个 CMake 目标,样例不放仓库根:
仓库布局见根目录 `README.md`。实现时按模块拆 CMake 目标(三个库 + 两个可执行),样例不放仓库根:
```text
isa/ # 指令编码、映像头、定宽类型(compiler 与 vm 的合同)
compiler/ # lexer parser symbols checker codegen linker
vm/ # 扫描周期、寄存器、映像、FB
host/ # 喂 I、收 Q、Δt、回放
compiler/ # lexer parser symbols checker codegen linkerSTCompiler 入口在 src/main.cpp
vm/ # 扫描周期、寄存器、映像、FB(库)
executor/ # BytecodeExecutor:加载 .stb + sidecar喂 I、收 Q、Δt、回放
examples/line1/ # 第 11 节最小样例(给人看)
tests/ # 冻规则用的正例 / 负例
```
@@ -327,13 +327,13 @@ END_PROGRAM
原则:**先冻合同,再解析,再链接,最后写 VM**。`compiler``vm` 不互链,合同只进 `isa`。每一阶段先有可运行的测试,再进入下一阶段。一人约 4~8 周做到第 11 节 `line1`
第一版不做:图染色、SSA、WHILE 有界证明、异常表、闭包、优化、`REAL`、独立 `stc.exe`
第一版不做:图染色、SSA、WHILE 有界证明、异常表、闭包、优化、`REAL`
---
### 12.0 骨架(约 1 天)
CMake 四个目标能空编译:`isa``compiler``vm``host``host` 先打印版本即可。
CMake 三个库能空编译:`isa``compiler``vm`;两个可执行 `STCompiler``BytecodeExecutor` 先打印版本即可。
- 落下 `examples/line1/`:第 3 节 toml + 第 11 节三个 `.st`
- `tests/` 接上 CTest,先放一个必过的空测试。
@@ -524,16 +524,22 @@ CMake 四个目标能空编译:`isa`、`compiler`、`vm`、`host`。`host` 先
---
### 12.10 host(约 23 天)
### 12.10 双可执行:STCompiler 与 BytecodeExecutor(约 23 天)
一条命令:读 toml → `compiler``vm` 跑 N 个周期。不拆第二个可执行文件。
编译与执行拆成两个可执行,映像 `.stb` 是中间产物:
-`[[io.*]]` 从宿主缓冲采样 / 写回,不创造变量。
-`dt_ms` 每周期传给 VM。
- 最小可观测:打印本周期 I/Q,或把寄存器/映像 dump 出来。
```text
STCompiler <project.toml> -o <name>.stb # 编译:读 toml + .st → 映像 + sidecar
BytecodeExecutor <name>.stb [--cycles N] # 执行:加载 .stb + sidecar,跑 N 周期
```
- `STCompiler``compiler` + `isa``BytecodeExecutor``vm` + `isa`**不链 `compiler`**。
- 产物两个文件:`<name>.stb`(映像,魔数 `STSC`+ `<name>.runtime.toml`sidecarI/O 绑定 var → 槽号 → channel/bit)。`[[io.*]]` 不进映像,sidecar 由 STCompiler 生成,不创造变量。
- `dt_ms` / `cycle_limit` 从映像头取,sidecar 不重复配置。
- 最小可观测:BytecodeExecutor 打印本周期 I/Q,或把寄存器/映像 dump 出来。
- 回放:读预先录制的 I 序列(文本即可),不接真实硬件。
完成:`host examples/line1/project.toml`编译并跑若干周期。
完成:`STCompiler examples/line1/project.toml -o line1.stb` 产出两个文件;`BytecodeExecutor line1.stb` 能跑若干周期。
---
@@ -556,7 +562,7 @@ CMake 四个目标能空编译:`isa`、`compiler`、`vm`、`host`。`host` 先
| 2 | 12.5AST,能 parse `line1`,拒绝多余特性 |
| 3 | 12.6~12.7:链接、定址、类型、io 校验 |
| 4 | 12.8 前半 + 12.9 前半:赋值/短路/IF 出映像,VM 能跑 |
| 5 | 12.8 后半 + 12.10CALL、FB、host 跑起来 |
| 5 | 12.8 后半 + 12.10CALL、FB、两个可执行跑起来 |
| 6 | 定时器/计数器、io、Δt、`line1` 语义 |
| 7~8 | 20 用例、回放、单步、补漏 |
@@ -567,8 +573,8 @@ CMake 四个目标能空编译:`isa`、`compiler`、`vm`、`host`。`host` 先
### 12.13 依赖方向(全程遵守)
```text
host → compiler → isa
host → vm → isa
STCompiler → compiler → isa
BytecodeExecutor → vm → isa
```
- 指令或映像布局有变:先改 `isa` 和编解码测试,再改两端。
+2 -2
View File
@@ -9,7 +9,7 @@ doc/
isa/指令与映像.md
compiler/编译管线.md
vm/扫描周期.md
host/宿主入口.md
executor/执行器入口.md
```
| 路径 | 内容 |
@@ -18,6 +18,6 @@ doc/
| [`isa/指令与映像.md`](isa/指令与映像.md) | 指令、映像、定宽类型、饱和;**规范以此为准** |
| [`compiler/编译管线.md`](compiler/编译管线.md) | 编译器边界与管线 |
| [`vm/扫描周期.md`](vm/扫描周期.md) | 扫描周期与 VM 边界 |
| [`host/宿主入口.md`](host/宿主入口.md) | 可执行入口:编译 + 跑周期 |
| [`executor/执行器入口.md`](executor/执行器入口.md) | 可执行入口:加载 `.stb` + sidecar,跑扫描周期 |
代码目录里的 README 只作入口;类型、指令、映像以 `isa/指令与映像.md` 为准。