Files
Interpreter/Doc/compiler/STCompiler使用说明.md
T

152 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# STCompiler 使用说明
把 ST 工程(`project.toml` + 若干 `.st`)编译成单一映像 `.stb`。执行由 `BytecodeExecutor`12.9/12.10 实现)负责。
## 构建
```bash
cmake --preset gcc-debug # 配置
cmake --build --preset gcc-debug # 编译
ctest --test-dir build/gcc-debug # 测试(当前 9 个用例)
```
可执行文件:`build/gcc-debug/compiler/STCompiler`
## 用法
```text
STCompiler <project.toml> [-o <name>.stb]
STCompiler <name>.stb --disasm
```
| 参数 | 作用 |
|---|---|
| `<project.toml>` | 工程文件(必填) |
| `-o <name>.stb` | 编译并写出映像文件;**缺省时只打印文件集合与工程哈希**(12.3 阶段行为) |
| `<name>.stb --disasm` | **反汇编一个已编译的映像**(不重新编译,见下) |
| `--help` | 打印帮助 |
退出码:`0` 成功;`1` 编译失败(错误信息打到 stderr)。
## 反汇编(--disasm
对已编译的 `.stb` 逐段查看:段摘要、函数表逐条指令(文件绝对偏移)、常量表、数据段 hex。
```bash
$ STCompiler line1.stb --disasm
image: line1.stb (184 bytes, 2 functions, 4 globals, entry fn 1)
dt_ms=10 cycle_limit=100000 hash=0xc3fe4ae74ad45900
functions:
fn 0: nregs=8, offset=0, len=1
0x0060 RET
fn 1: nregs=13, offset=4, len=17
0x0064 LOAD_I r8, 1
0x0068 STORE_GLOBAL r8, 8
0x006c LOAD_GLOBAL r9, 2
...
data (16 bytes):
0x0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
```
说明:
- 指令偏移是**文件绝对字节偏移**,可直接对照 `xxd line1.stb`
- 映像里**没有符号名**(函数表只有 fn_id,数据段无名字映射),因此按 `fn 0` / `fn 1`、槽号显示
- 文件损坏或打不开 → `error: ...` 退出码 1
## 示例(line1
```bash
$ STCompiler examples/line1/project.toml
project: line1
files:
globals.st
motor.st
main.st
hash: 0xc3fe4ae74ad45900
$ STCompiler examples/line1/project.toml -o line1.stb
compiled: line1.stb (184 bytes, 2 functions, 4 globals)
```
产物 `line1.stb`:魔数 `STSC` + 版本 1 的单一映像(指令见 `Doc/isa/指令与映像.md`)。
## 工程文件(project.toml
只做三件事:**列出源文件、指定唯一 GVL、可选地把已声明全局接到硬件**。不声明变量。
| 字段 | 必填 | 说明 |
|---|---|---|
| `project.name` | 是 | 工程名 |
| `project.entry` | 是 | 第一版必须 `"program MAIN"` |
| `project.cycle_limit` | 是 | 每周期指令上限(>0) |
| `project.dt_ms` | 是 | 本周期 Δt 毫秒(>0),给 TON/TOF/CTU |
| `files.st` | 是 | 源文件列表(非空数组) |
| `gvl.file` | 否 | 唯一允许 `VAR_GLOBAL` 的文件;已在 `files.st` 则不重复收录 |
| `[[io.input]]` / `[[io.output]]` | 否 | `var` + `channel` + `bit``var` 必须已在 GVL 声明 |
```toml
[project]
name = "line1"
entry = "program MAIN"
cycle_limit = 100000
dt_ms = 10
[files]
st = ["globals.st", "motor.st", "main.st"]
[gvl]
file = "globals.st"
[[io.input]]
var = "EmergencyStop"
channel = 0
bit = 2
```
## ST 子集(第一版)
**POU**`PROGRAM` / `FUNCTION` / `FUNCTION_BLOCK`(含对应 `END_*`)。
**变量段**`VAR` / `VAR_INPUT` / `VAR_OUTPUT` / `VAR_GLOBAL`(仅 `gvl.file` 顶层)/ `VAR_EXTERNAL`
**类型**`BOOL` / `INT` / `TIME`;内建 FB 类型 `TON` / `TOF` / `CTU`(关键字,不可作变量名)。
**语句**:赋值 `:=``IF / ELSIF / ELSE / END_IF``WHILE / END_WHILE`、FB 调用 `fb(in := ..., ...);`、字段读 `fb.Q`
**表达式**:字面量(`TRUE`/`FALSE`、整数、`T#10ms` 式 TIME)、`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`)。
## 编译管线与错误类别
```
project.toml + .st
→ 词法(lex error)→ 语法(syntax error)→ 链接(link error
→ 类型检查(type error)→ 寄存器码(codegen error)→ .stb
```
错误消息前缀即阶段:`lex error` / `syntax error` / `link error` / `type error` / `codegen error`,均带文件与行列(`type error` 仅带文件)。
| 类别 | 示例 |
|---|---|
| `lex error` | 非法字符、未闭合注释、坏 `T#` 字面量 |
| `syntax error` | 缺 `END_*``VAR_IN_OUT` 等保留名、链式比较 |
| `link error` | 非 GVL 文件写 `VAR_GLOBAL`、同名全局、io.var 未在 GVL、未声明实例、循环调用 |
| `type error` | `FUNCTION` 写全局、AND 吃 INT、赋值类型不匹配、FB 输入类型不匹配 |
| `codegen error` | 寄存器溢出、写 io.input、写函数输入 |
## 样例与测试
- `examples/line1/`:最小闭环(MAIN + MotorStarter FB + I/O + 全局),给人看
- `tests/cases/01~20/`20 个用例(每份 `project.toml` + `.st` + `EXPECTED.md`),编译结果按表
- `tests/`CTest`isa_roundtrip` / `compiler_toml` / `lexer_tokens` / `parser_syntax` / `linker_links` / `typecheck_types` / `codegen_slice1`
## 当前状态
- ✅ 可编译:14 个正例用例全部产出 `.stb`6 个负例按期望拒绝
- ⏳ 执行:`BytecodeExecutor`(加载 `.stb` 跑扫描周期)在 12.9/12.10
- ⏳ sidecar`<name>.runtime.toml`,I/O 绑定)在 12.10 随执行器一起接线