Files
Interpreter/Doc/compiler/STCompiler使用说明.md
T
Admin 26256a36b9 扩充内置功能块为 8 个:TON/TOF/TP/CTU/CTD/CTUD/R_TRIG/F_TRIG。
- isa:CAL_* 操作码连续占 24..31(CALL/RET 后移为 32/33,kOpCount=34);disasm 支持 5 个新操作码
- 词法/语法/链接:新 8 个关键字与冻结布局(TP=in/pt/q/et、CTD=cd/ld/pv/q/cv、
  CTUD=cu/cd/r/lu/pv/qu/qd/cv、R_TRIG/F_TRIG=clk/q)
- VM:do_cal 全 8 个语义(TP 脉冲、CTD 递减、CTUD 双向+装载、R_TRIG 上升沿、F_TRIG 下降沿);
  edge_prev_ 每槽 2 字节存边沿上次输入;exec_one 分发补 5 个新操作码
- 验证:TP 30ms 脉冲 2 周期、CTD 装载+递减到 q=1、CTUD cu/cd 双向、R/F_TRIG 交替;
  ctest 11/11 全绿
- 文档:指令与映像/词法/初步计划/符号表与链接/指令执行/扫描周期/使用说明 同步
2026-08-21 20:38:27 +08:00

5.8 KiB
Raw Blame History

STCompiler 使用说明

把 ST 工程(project.toml + 若干 .st)编译成单一映像 .stb。执行由 BytecodeExecutor12.9/12.10 实现)负责。

构建

cmake --preset gcc-debug          # 配置
cmake --build --preset gcc-debug  # 编译
ctest --test-dir build/gcc-debug  # 测试(当前 9 个用例)

可执行文件:build/gcc-debug/compiler/STCompiler

用法

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。

$ 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

$ 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),给内置 FB 定时器
files.st 源文件列表(非空数组)
gvl.file 唯一允许 VAR_GLOBAL 的文件;已在 files.st 则不重复收录
[[io.input]] / [[io.output]] var + channel + bitvar 必须已在 GVL 声明
[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 子集(第一版)

POUPROGRAM / FUNCTION / FUNCTION_BLOCK(含对应 END_*)。

变量段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(关键字,不可作变量名)。

语句:赋值 :=IF / ELSIF / ELSE / END_IFWHILE / END_WHILE、FB 调用 fb(in := ..., ...);、字段读 fb.Q

表达式:字面量(TRUE/FALSE、整数、T#10ms 式 TIME)、NOTAND/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/CTestisa_roundtrip / compiler_toml / lexer_tokens / parser_syntax / linker_links / typecheck_types / codegen_slice1

当前状态

  • 可编译:14 个正例用例全部产出 .stb6 个负例按期望拒绝
  • 执行:BytecodeExecutor(加载 .stb 跑扫描周期)在 12.9/12.10
  • sidecar<name>.runtime.toml,I/O 绑定)在 12.10 随执行器一起接线