阶段5-2:文档收尾——vm 指令执行/扫描周期、compiler 寄存器码/符号表/STCompiler说明、executor 入口全部更新为 V2
This commit is contained in:
@@ -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`)
|
||||
|
||||
+41
-48
@@ -1,33 +1,33 @@
|
||||
# 寄存器码(12.8)
|
||||
# 寄存器码(V2)
|
||||
|
||||
compiler 模块的代码生成。输入:`Project` + `Unit`(AST)+ `LinkResult`;输出:`.stb` 映像字节(`std::vector<uint8_t>`)。全工程定案见 [`初步计划.md`](../初步计划.md) 12.8,指令/映像布局见 [`指令与映像.md`](../isa/指令与映像.md)。
|
||||
compiler 模块的代码生成。输入:`Project` + `Unit`(AST)+ `LinkResult`;输出:`.stb` 映像字节(`std::vector<uint8_t>`)。全工程定案见 [`初步计划.md`](../初步计划.md) 12.8,指令/映像布局见 [`指令与映像.md`](../isa/指令与映像.md),槽表/值段格式见 [`stb文件格式.md`](../isa/stb文件格式.md)。
|
||||
|
||||
## 做 / 不做
|
||||
|
||||
**做**
|
||||
|
||||
- 寄存器分配:局部/变量固定寄存器,表达式临时值往后编号,`nregs` 写进函数头
|
||||
- 跳转先留洞、后回填;`AND` / `OR` **必须编成跳转**(短路),禁止两边都算
|
||||
- 常量表(`LOADK`)、全局/实例槽(`LOAD_GLOBAL` / `STORE_GLOBAL` 等)
|
||||
- `CALL fn_id` 有界帧;用户 FB 调用**内联展开**;内建 `CAL_TON` / `CAL_TOF` / `CAL_CTU`
|
||||
- 拼装映像:函数表 / 常量表 / 数据段 / 头(`cycle_limit`、`dt_ms`、工程哈希、入口)
|
||||
- 跳转先留洞、后回填(字节单位,相对下一条);`AND` / `OR` **必须编成跳转**(短路),禁止两边都算
|
||||
- 常量表(`LOADK`,8B 原始值无 tag,按 func 解释)、全局/实例槽(`LOAD` / `STORE` / `LOAD_OFF` / `STORE_OFF`)
|
||||
- `CALL fn_id` 有界帧;用户 FB 调用**内联展开**;内建 `CAL fb_id, 实例槽`
|
||||
- 拼装映像:V2 头 128B / 函数表 / 常量表 / 字节码 / 槽表 / 值段 + SHA-256 尾部
|
||||
- `max_stack`:MAIN + FUNCTION 调用图 DAG 最坏路径 Σ(12 + nregs×8);递归 = 编译期报错
|
||||
|
||||
**不做(第一版)**
|
||||
|
||||
- 图染色、SSA、生命周期分析、优化、异常表、闭包
|
||||
- 函数指针、间接跳转、`REAL`
|
||||
- 函数指针、间接跳转、动态实例
|
||||
|
||||
## 存储布局(v1 定案)
|
||||
## 存储布局(V2 定案)
|
||||
|
||||
| 数据 | 放哪 | 说明 |
|
||||
|---|---|---|
|
||||
| PROGRAM / FUNCTION 标量变量与临时 | **寄存器**(函数帧) | 每周期帧保留由 VM 负责(12.9) |
|
||||
| FB 实例(任意 POU 内声明) | **数据区实例块**(绝对地址) | 状态跨周期持久 |
|
||||
| 全局(含 I/Q/M) | 数据区(声明序) | 12.6 已定槽号 |
|
||||
| 全局(含 I/Q/M)与 FB 实例 | **值区**(紧凑变宽,1/2/4/8 对齐) | 槽表条目(8B:addr:u32 + 预留)指到值区偏移;状态跨周期持久 |
|
||||
|
||||
- **数据区** = 全局块(声明序,**每槽 8 字节定宽**,见 [`指令与映像.md`](../isa/指令与映像.md))→ FB 实例块(按实例声明序,每字段一槽)
|
||||
- **指令 slot = 槽号**(u16,0..65535);数据偏移 = 槽号 × 8;符号表 `address` 即指令 slot,无映射
|
||||
- 字段访问 `fb.Q`:`LOAD_GLOBAL rd, <实例基槽+字段序号>`(编译期算死);I/Q/M 用 `LOAD_I` / `STORE_Q` / `LOAD_M` / `STORE_M` 同槽号
|
||||
- **槽表两级**:指令操作数 = **槽号**(u32)→ 槽表条目 → 值区字节偏移;`slot_addr(slot)` 由 VM/Image 提供
|
||||
- 全局按 GVL 声明序编槽;**FB 实例 = 1 个槽表条目**,字段在实例基址上按偏移访问(字段偏移编译期按 1/2/4/8 对齐计算,字段类型 = machine.toml `[[fb]]` 表)
|
||||
- 字段访问 `fb.Q`:`LOAD_OFF rd, <实例槽>, <偏移>` / `STORE_OFF <实例槽>, <偏移>, rs`(16B SLOT+off 指令);I/Q/M 同普通槽(`LOAD` / `STORE`)
|
||||
- 函数帧寄存器:`FUNCTION` 结果固定 **r0**,`VAR_INPUT` 从 r1 起按声明序,`VAR` 续后;PROGRAM / FB 变量从 r0 起按声明序
|
||||
|
||||
### 调用约定(v1 冻结,VM 12.9 按此实现)
|
||||
@@ -37,7 +37,7 @@ compiler 模块的代码生成。输入:`Project` + `Unit`(AST)+ `LinkResu
|
||||
| 结果寄存器 | **r0**(FUNCTION 结果写入处) |
|
||||
| 参数寄存器 | **r1..r7**(最多 7 个输入,按声明序) |
|
||||
| 变量 / 临时 | **全部从 r8 起**(调用约定区不受覆盖) |
|
||||
| `CALL` | VM 复制当前帧 **r0..r7 → 新帧 r0..r7** |
|
||||
| `CALL` | VM 复制当前帧 **r0..r7 → 新帧 r0..r7**(全宽) |
|
||||
| `RET` | VM 复制当前帧 **r0..r7 → 调用方帧 r0..r7**(r0=结果,r1..r7 原样返回) |
|
||||
| 函数输入 | 函数体内**只读**(写输入 → codegen error) |
|
||||
|
||||
@@ -53,9 +53,9 @@ compiler 模块的代码生成。输入:`Project` + `Unit`(AST)+ `LinkResu
|
||||
## 表达式与语句的指令模式
|
||||
|
||||
```text
|
||||
字面量 LOADK rd, const_id
|
||||
变量读 LOAD_GLOBAL/LOAD_I/LOAD_M rd, slot (或帧内 MOVE)
|
||||
字段读 LOAD_GLOBAL rd, <基址+偏移>
|
||||
字面量 LOADK rd, const_id (func = 语言类型;REAL/LREAL 位模式按目标类型装载)
|
||||
变量读 LOAD rd, slot (帧内直接 MOVE)
|
||||
字段读 LOAD_OFF rd, <实例槽>, <偏移>
|
||||
函数调用 <实参求值 → 参数寄存器> CALL fn_id MOVE rd, r0
|
||||
|
||||
NOT <operand → t> NOT rd, t
|
||||
@@ -65,7 +65,7 @@ AND/OR 短路(必须跳转):
|
||||
L_end:
|
||||
比较 <l→t1> <r→t2> CMP_xx rd, t1, t2
|
||||
算术 <l→t1> <r→t2> ADD/SUB/MUL/DIV rd, t1, t2
|
||||
负号 <operand → t> SUB rd, r0, t (0 - t,r0 恒 0)
|
||||
负号 <operand → t> NEG rd, t
|
||||
|
||||
IF <cond → t> JF t, L_else
|
||||
<then body> JMP L_end
|
||||
@@ -74,13 +74,13 @@ IF <cond → t> JF t, L_else
|
||||
WHILE L_loop: <cond → t> JF t, L_end <body> JMP L_loop L_end:
|
||||
|
||||
FB 调用(用户,内联展开):
|
||||
<每个实参求值 → 临时> STORE_GLOBAL <实例基址+字段偏移>, 临时
|
||||
<内联体:读输入字段、算输出、写输出字段>
|
||||
内建 实参同左 → CAL_TON/CAL_TOF/CAL_CTU <实例偏移>
|
||||
<每个实参求值 → 临时> STORE_OFF <实例槽>, <字段偏移>, 临时
|
||||
<内联体:LOAD_OFF 读输入字段、算输出、STORE_OFF 写输出字段>
|
||||
内建 实参同左 → CAL <fb_id>, <实例槽>
|
||||
```
|
||||
|
||||
- 常量统一进常量表(BOOL / INT / TIME),`const_id` = 首次出现序
|
||||
- 空条件寄存器约定:`r0` 恒 0(`enc_jmp` 用),`SUB rd, r0, t` 实现取负
|
||||
- 常量统一进常量表(8B 原始值,位模式去重;BOOL / 整数 / 时间 / 浮点 / 日期),`const_id` = 首次出现序;`LOADK` 按 func 解释位模式
|
||||
- 指令 func 位段 = 语言类型对应(`func_of_name`:宽度 × 符号 + F32/F64)
|
||||
|
||||
## 用户 FB 调用内联(v1 定案)
|
||||
|
||||
@@ -90,17 +90,23 @@ FB 体共享会与「绝对字段地址」冲突(不同实例基址不同)
|
||||
- 代价:字节码随调用点数膨胀;v1 规模可接受;以后可升级为「基址寄存器寻址」指令
|
||||
- FB 无递归、无动态实例,内联安全
|
||||
|
||||
## 映像拼装
|
||||
## 映像拼装(V2)
|
||||
|
||||
```text
|
||||
头 128B:magic / version=2 / model=STATOR2 / cycle_limit / dt_ms / 工程哈希 /
|
||||
entry_fn_id / n_globals / n_consts / n_funcs / 各段偏移 /
|
||||
n_slots / values_size / meta / max_stack
|
||||
函数表:收集序 fn_id → { nregs, code_offset(相对字节码段), code_len }
|
||||
常量表:const_id → { tag, value }
|
||||
数据段:全局 + 实例块(见上)
|
||||
头:cycle_limit / dt_ms / 工程哈希(12.3)/ entry=MAIN fn_id / n_globals / n_i=n_q=n_m=0
|
||||
常量表:const_id → { value:u64 }(无 tag)
|
||||
字节码:各函数指令连续
|
||||
槽表:每条目 8B(addr:u32 + 预留:u32)
|
||||
值段:全局 + FB 实例紧凑变宽
|
||||
尾部:SHA-256(覆盖头部到值段末尾)
|
||||
```
|
||||
|
||||
- 用 `isa` 的 `enc_*` 编码指令、`ImageView` 校验回读
|
||||
- 工程哈希用 12.3 的 `compute_project_hash`
|
||||
- 用 `isa` 的 `enc_*` 编码指令(变长 4/8/16/32B,前缀分区)
|
||||
- 工程哈希用 12.3 的 `compute_project_hash`(FNV-1a 64)
|
||||
- `--dump-map` 可打印变量/槽映射(对照源码 ↔ 反汇编)
|
||||
|
||||
## 错误
|
||||
|
||||
@@ -109,27 +115,14 @@ FB 体共享会与「绝对字段地址」冲突(不同实例基址不同)
|
||||
```text
|
||||
codegen error: register overflow (>256) in function 'f'
|
||||
codegen error: constant table overflow
|
||||
codegen error: slot out of range
|
||||
codegen error: no storage for 'x'
|
||||
codegen error: no instance 't' in 'MAIN'
|
||||
codegen error: recursive CALL/FB nesting too deep
|
||||
```
|
||||
|
||||
## 完成标准
|
||||
|
||||
1. `line1` 能写出映像(函数字节码 + 全局/FB 槽 + 工程哈希),`ImageView` 校验通过
|
||||
2. 跳转回填无悬空(disasm 抽查)
|
||||
1. `line1` 能写出映像(函数字节码 + 槽表/值段 + 工程哈希 + SHA-256),`StbView` 校验通过
|
||||
2. 跳转回填无悬空(`--disasm` 抽查)
|
||||
3. 用例 1~9、13、15、17、18、20 编译出映像;负例(10/11/12/14/16/19)仍在前层被拒
|
||||
4. 全部构建 + `ctest` 无回归
|
||||
|
||||
---
|
||||
|
||||
## 执行计划(8 片,每片验证编译产物)
|
||||
|
||||
1. **`Codegen.h`(新建)+ `Codegen.cpp` 骨架**:帧/槽/常量表/指令缓冲/回填基础设施;`MOVE` `LOADK` `RET` → 用例 1、2 出映像
|
||||
2. **全局与 I/Q/M**:`LOAD_I` / `STORE_Q` / `LOAD_M` / `STORE_M` / `LOAD_GLOBAL` / `STORE_GLOBAL`(用例 9)
|
||||
3. **`NOT` + 短路 `AND` / `OR`**(用例 3,断言产物含跳转)
|
||||
4. **`CMP_*` + `JMP` / `JT` / `JF` → `IF`**(用例 4)
|
||||
5. **`WHILE`**(用例 5;`cycle_limit` 进映像头)
|
||||
6. **`ADD/SUB/MUL/DIV` + TIME 常量**(用例 7、8)
|
||||
7. **`CALL fn_id` + 有界帧**(用例 13)
|
||||
8. **FB 实例块 + 字段偏移;内联用户 FB;`CAL_TON` / `CAL_TOF` / `CAL_CTU`**(用例 15、17、18、20 line1 全链路)
|
||||
|
||||
每片配 `codegen_test` 断言(nregs / 指令序列 disasm / 回填 / 常量表 / 数据区);最终 `ctest` 9/9。
|
||||
4. 全部构建 + `ctest` 无回归(14/14)
|
||||
|
||||
+25
-17
@@ -12,18 +12,19 @@ compiler 模块的符号收集与链接。输入:`Project`(toml)+ 各 `.st
|
||||
- `FUNCTION` 标无状态;`FUNCTION_BLOCK` 必须先有实例才能调用
|
||||
- `CALL` 目标解析成 `fn_id`(立即数),无函数指针
|
||||
- 校验:同名全局、未声明 `io.var`、重复 POU 名、未声明 FB 实例、函数循环调用 → 失败
|
||||
- FB 实例布局:按类型算字段清单(输入/输出/内部/内建 8 个 FB 固定字段(12.11 扩充))
|
||||
- FB 实例布局:按类型算字段清单(输入/输出/内部;内建 FB 15 条字段来自 machine.toml `[[fb]]` 表,编译期按 1/2/4/8 对齐计算偏移)
|
||||
|
||||
**不做(第一版)**
|
||||
|
||||
- 寄存器分配(12.8)、类型检查(12.7)
|
||||
- 多 GVL 文件、I/Q/M 与全局分槽(v1 **单一数据区**,见下)
|
||||
|
||||
## 数据区定址(v1 定案)
|
||||
## 数据区定址(V2 定案)
|
||||
|
||||
- **单一数据区**:全部全局(含 I/Q/M)按 `globals.st` 声明顺序编槽号 0..n-1
|
||||
- 映像头 `n_globals` = 声明总数;`n_i` / `n_q` / `n_m` = 0(第一版不拆,见 [`初步计划.md`](../初步计划.md) 5.1)
|
||||
- `LOAD_I` / `STORE_Q` / `LOAD_GLOBAL` / `STORE_GLOBAL` 操作码不同,槽号指向同一数据区
|
||||
- **槽表两级**:全部全局(含 I/Q/M)与 FB 实例统一编槽号(0..n-1);槽表条目(8B:addr:u32 + 预留)指向**值区**字节偏移;值区按变量类型紧凑变宽(1/2/4/8 对齐)
|
||||
- 全局按 `globals.st` 声明顺序编槽;**FB 实例 = 1 个槽表条目**,字段走 `LOAD_OFF` / `STORE_OFF` 实例槽 + 编译期算死的字段偏移
|
||||
- 映像头 `n_globals` = 全局声明总数;`n_i` / `n_q` / `n_m` = 0(第一版不拆,见 [`初步计划.md`](../初步计划.md) 5.1)
|
||||
- 访问统一 `LOAD` / `STORE`(+ `LOAD_OFF` / `STORE_OFF`),无 I/Q/M 专用操作码
|
||||
- io 绑定(toml)只负责 channel/bit → 槽号映射(sidecar),不创造变量
|
||||
|
||||
## 符号表一行
|
||||
@@ -70,20 +71,27 @@ struct Symbol {
|
||||
## FB 实例布局
|
||||
|
||||
- 用户 FB:字段 = 全部 `VAR_INPUT` + `VAR_OUTPUT` + `VAR`(内部),按声明段序排
|
||||
- 内建(冻结,isa 规格;12.11 扩为 8 个):
|
||||
- 内建 FB 15 条(`compiler/machine.toml` `[[fb]]` 表驱动,fb_id 0..14):
|
||||
|
||||
| FB | 字段(名 → 类型) |
|
||||
|---|---|
|
||||
| TON | in BOOL, pt TIME, q BOOL, et TIME |
|
||||
| TOF | in BOOL, pt TIME, q BOOL, et TIME |
|
||||
| TP | in BOOL, pt TIME, q BOOL, et TIME |
|
||||
| CTU | cu BOOL, r BOOL, pv INT, q BOOL, cv INT |
|
||||
| CTD | cd BOOL, ld BOOL, pv INT, q BOOL, cv INT |
|
||||
| CTUD | cu BOOL, cd BOOL, r BOOL, lu BOOL, pv INT, qu BOOL, qd BOOL, cv INT |
|
||||
| R_TRIG | clk BOOL, q BOOL |
|
||||
| F_TRIG | clk BOOL, q BOOL |
|
||||
| fb_id | FB | 字段(名 → 类型) |
|
||||
|---|---|---|
|
||||
| 0 | TON | in BOOL, pt TIME, q BOOL, et TIME |
|
||||
| 1 | TOF | 同 TON |
|
||||
| 2 | TP | 同 TON |
|
||||
| 3 | CTU | cu BOOL, r BOOL, pv INT, q BOOL, cv INT |
|
||||
| 4 | DCTU | cu BOOL, r BOOL, pv DINT, q BOOL, cv DINT |
|
||||
| 5 | CTD | cd BOOL, ld BOOL, pv INT, q BOOL, cv INT |
|
||||
| 6 | DCTD | cd BOOL, ld BOOL, pv DINT, q BOOL, cv DINT |
|
||||
| 7 | CTUD | cu BOOL, cd BOOL, r BOOL, lu BOOL, pv INT, qu BOOL, qd BOOL, cv INT |
|
||||
| 8 | DCTUD | cu BOOL, cd BOOL, r BOOL, lu BOOL, pv DINT, qu BOOL, qd BOOL, cv DINT |
|
||||
| 9 | R_TRIG | clk BOOL, q BOOL |
|
||||
| 10 | F_TRIG | clk BOOL, q BOOL |
|
||||
| 11 | SR | S1 BOOL, R BOOL, Q1 BOOL |
|
||||
| 12 | RS | SET BOOL, RESET1 BOOL, Q1 BOOL |
|
||||
| 13 | PWM | in BOOL, pt TIME, duty REAL, q BOOL, et TIME |
|
||||
| 14 | RTC | enable BOOL, date DATE, tod TOD |
|
||||
|
||||
- 实例布局 = 类型字段表的一份拷贝;字段偏移 = 字段序号 × 8(8 字节定宽槽)
|
||||
- 实例布局 = 类型字段表的一份拷贝;字段偏移编译期按 1/2/4/8 对齐计算(字段类型决定宽度),实例 = 槽表 1 条
|
||||
|
||||
## 错误
|
||||
|
||||
|
||||
Reference in New Issue
Block a user