# 机器定义文件(machine.toml) 指令集与类型的**唯一事实来源**,**只给编译器**(STCompiler/compiler)使用。执行器(vm)不读本文件——它是下位机程序,内建全部指令。 ## 架构(最终定案) ```text machine.toml(只给编译器:meta + type 别名表 + op 表 + fb 表) │ 运行时加载(toml++)+ 强校验 ▼ STCompiler → compiler(编码 opcode / 类型元数据 / FB 布局 全部来自配置) │ 写 .stb(compiler 自带写实现:型号标识[32] + SHA-256 文件尾) ▼ .stb ──→ BytecodeExecutor → vm(执行 switch 在 vm;读 .stb 自实现) │ + 型号匹配校验 + SHA-256 校验 ▼ isa(归执行器侧,只管指令定义) ``` | 模块 | 职责 | |---|---| | `compiler` | 配置驱动编译;自带 `.stb` 写实现;`--disasm` 用配置参数名/format 自格式化 | | `vm` | 内建全指令集(执行 switch 在 vm);自带 `.stb` 读实现 + 型号/SHA-256 校验;无屏蔽、不读配置 | | `isa` | **归执行器侧**(vm 依赖),**只管指令定义**:Op 枚举/Instr/Encode/OpFormat/OpClass/类型/饱和/disasm。指令的具体执行实现在 vm | | `machine.toml` | 编译器唯一知识来源 | ## 决策清单(定案) 1. 指令两大分类:**PLAIN**(无实例,26 条)/ **INSTANCE**(有实例,8 条 `CAL_*`) 2. 三层分类:`class`(操作对象)→ `format`(操作数形态)→ `参数名`(语义) 3. isa 归执行器侧、只管指令定义;执行 switch 留在 vm 4. 配置改 TOML、改名 machine.toml,只给编译器;vm 不需要配置 5. 一致性靠 `.stb`:**型号标识[32]**(定长字符串含版本)+ **SHA-256 文件尾**(compiler/vm 各实现一份)+ 强校验 6. 类型:**基元内置**(编译器内建 bit/int8..uint64/float32/float64,元数据在代码);配置类型行 = `name + base + range? + tag`(别名);**值域约束进配置**(如 BOOL range=[0,1]) 7. 字符串:**方案 A**(v1 不做;"组合类型"(含定长字符串 STRING(n))为未来扩展,需时再扩 .stb 格式) 8. `.stb` 读写:compiler 写、vm 读,**各自实现**(无共享 image 模块) 9. 冻结哈希测试更新(接受) ## 指令三层分类 ```text class(操作对象) → format(操作数形态) → 参数名(操作数语义) PLAIN/INSTANCE RR/RRR/IMM/SLOT/ rd/rs/const_id/ JMP/JC/CALL/CAL/NONE slot/off/fn_id/instance ``` | 大类 | 操作对象 | 现有指令 | |---|---|---| | **PLAIN**(无实例) | 寄存器 / 立即数 / 槽号 / 分支 / 调用 | MOVE/LOADK/NOT/AND/OR/算术/CMP_* / JMP/JT/JF / LOAD_*/STORE_* / CALL/RET(26 条) | | **INSTANCE**(有实例) | 数据区实例块(内建 FB) | CAL_TON/TOF/TP/CTU/CTD/CTUD/R_TRIG/F_TRIG(8 条) | format 不可省:同是"第二个操作数是数字",`LOADK`/`LOAD_I`/`CALL` 渲染相同但语义不同(常量 id / 槽号 / fn_id,由参数名表达);"数字 vs 寄存器 vs 偏移"的渲染差异(`r%d` / `%u` / `%+d`)只有 format 能表达。 ## 配置文件格式(TOML) **全属性必填,不可省略**: ```toml [meta] name = "STATOR" # 型号名(参与 .stb 型号标识) version = 1 # 指令集版本(参与 .stb 型号标识) # ---- 类型:编译器内建基元(bit/int8/int16/int32/int64/uint8/uint16/uint32/uint64/float32/float64) # 配置类型 = 基元别名(+ 值域约束 + .stb 契约 tag) [[type]] name = "BOOL" base = "uint8" range = [0, 1] # 值域约束(语言语义数据化;缺省 = 基元全范围) tag = 0 # 常量表契约(强校验) [[type]] name = "INT" base = "int16" tag = 1 [[type]] name = "TIME" base = "int64" tag = 2 # ---- 指令(全属性必填) [[op]] name = "MOVE" opcode = 0 class = "plain" # plain / instance format = "RR" params = ["rd", "rs"] enabled = true [[op]] name = "CAL_TON" opcode = 24 class = "instance" format = "CAL" params = ["instance"] enabled = true [[op]] name = "RET" opcode = 33 class = "plain" format = "NONE" params = [] enabled = true # ---- 内建 FB(布局登记;cal_opcode 与 op 行强校验一致) [[fb]] name = "ton" opcode = 24 fields = [["in", "BOOL"], ["pt", "TIME"], ["q", "BOOL"], ["et", "TIME"]] [[fb]] name = "ctud" opcode = 29 fields = [["cu", "BOOL"], ["cd", "BOOL"], ["r", "BOOL"], ["lu", "BOOL"], ["pv", "INT"], ["qu", "BOOL"], ["qd", "BOOL"], ["cv", "INT"]] ``` ## 类型系统 - **基元内置**:编译器内建 `bit/int8/int16/int32/int64/uint8/uint16/uint32/uint64/float32/float64`(宽度/有无符号/是否浮点元数据在代码,C 语义) - **别名**:配置类型行只写 `name + base + range? + tag`——宽度/符号/浮点从 base 继承 - **值域约束**:`range`(如 BOOL [0,1])供编译器做常量/赋值检查;缺省 = 基元全范围 - **tag 契约**:`tag`(0/1/2)与 `.stb` 常量表格式强校验(防 type 表改序破坏旧 .stb) - **字符串**:v1 不做(方案 A);组合类型(含 `STRING(n)`)为未来扩展,文档预留,需时再扩 `.stb` 格式 - 半数据化边界:**类型定义数据化**(配置),**运算/类型检查语义代码化**(如 AND 只吃 BOOL 是语言规则,在 compiler 代码;饱和算术在 vm/isa) ## .stb 加固(格式冻结更新) 见 [`指令与映像.md`](指令与映像.md):头新增 **型号标识[32]**(定长 ASCII 字符串,含版本,不足补 `'\0'`);文件尾新增 **SHA-256[32]**(对前面全部内容计算,compiler 写侧 / vm 读侧各自实现)。执行器读取时: ```text 型号标识与自身支持型号不匹配 → 直接报错 SHA-256 不匹配 → 报错(文件损坏/篡改) ``` ## 强校验清单(加载/读取时,任一不符 → 报错退出) 1. TOML 语法与字段完整性(全属性必填) 2. `type.base` 命中内建基元;`range` 合法(min ≤ max、类型相符) 3. `tag` 与 `.stb` 常量表契约一致(0/1/2) 4. `op.opcode` 唯一、0..255;`class` 合法;`format` 合法;**类别-格式互锁**(INSTANCE ↔ CAL) 5. `fb.opcode` 与 op 行的 CAL_* 一致;fb 字段类型命中配置类型表 6. 型号标识(.stb 侧) ## 加东西的流程 ```text 加普通指令:machine.toml 加 [[op]] 一行 + vm 一个语义 case → 重建 vm 加内建 FB :machine.toml 加 [[fb]] 一行 + vm 一个语义 case → 重建 vm(compiler 免重建) 加语言类型:machine.toml 加 [[type]] 一行(别名+tag)+ 类型检查/VM 语义代码 → 重建 改型号版本:machine.toml [meta] version +1 → 旧 .stb 被旧/新执行器按型号校验决定是否接受 ``` ## 执行计划(分支 dev_ops_config) ``` 0. 文档定案(本文 + 指令与映像.md 格式冻结更新 + stb文件格式.md 修订注记) ← 当前 1. ✅ OpFormat/OpClass 显式化 + disasm 表驱动(已完成,35dabf4) 2. machine.toml 落地:meta + type 表 + op 34 条 + fb 8 条 3. compiler 配置驱动改造:toml++ 加载 + 强校验;编码 opcode / 类型元数据 / FB 布局来自配置(compiler 不再依赖 isa) 4. .stb 写侧:compiler 实现 型号标识[32] + SHA-256 文件尾 5. .stb 读侧:vm 自实现读 + 型号匹配 + SHA-256 校验(isa 的 Image 拆出) 6. CLI:STCompiler --machine (编译路径必填) 7. 测试:machine 解析/校验负例、型号不匹配报错、SHA-256 篡改检测、 冻结哈希更新、全量回归 8. 文档 + 提交 ``` ## 实现前确认项(4 项,未定案) 1. 配置文件名与位置:建议 `compiler/machine.toml`(只归编译器用) 2. 型号标识生成规则:建议 `[meta] name + version` 拼成 32 字节(如 `"STATOR" + "1"` → 补 `'\0'`);vm 内建"支持型号列表"比对 3. compiler 内部 `TypeKind`(Bool/Int/Time):保留为语言语义枚举(类型检查规则),元数据从配置 base 查 4. 依赖方向确认:`compiler` 不再依赖 `isa`(`compiler → toml++` 自有;`STCompiler → compiler`;`vm → isa`)