From 2eb24681191cfdd084b224fec514cc5d6e19fcad Mon Sep 17 00:00:00 2001 From: chentianya Date: Tue, 18 Aug 2026 16:32:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=92=E5=AE=9A=20CMake=20=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E5=B9=B6=E8=A1=A5=E5=85=85=E5=90=84=E5=B1=82?= =?UTF-8?q?=20README=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 固定 isa/compiler/vm/host 的职责边界,样例与测试单独成目录。 Co-authored-by: Cursor --- CMakeLists.txt | 0 Doc/README.md | 9 +++++ README.md | 77 +++++++++++++++++++++++++++++++++++++++++++ cmake/README.md | 7 ++++ compiler/README.md | 28 ++++++++++++++++ examples/README.md | 18 ++++++++++ host/README.md | 16 +++++++++ isa/README.md | 17 ++++++++++ tests/README.md | 14 ++++++++ third_party/README.md | 7 ++++ vm/README.md | 24 ++++++++++++++ 11 files changed, 217 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 Doc/README.md create mode 100644 cmake/README.md create mode 100644 compiler/README.md create mode 100644 examples/README.md create mode 100644 host/README.md create mode 100644 isa/README.md create mode 100644 tests/README.md create mode 100644 third_party/README.md create mode 100644 vm/README.md diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/Doc/README.md b/Doc/README.md new file mode 100644 index 0000000..3ce586c --- /dev/null +++ b/Doc/README.md @@ -0,0 +1,9 @@ +# Doc + +设计文档,不是编译目标。 + +| 文件 | 内容 | +|---|---| +| [`初步计划.md`](初步计划.md) | 定案:子集 ST、toml 工程、寄存器 VM、执行模型、ST 子集、实现顺序 | + +仓库根目录 [`README.md`](../README.md) 只说明目录和模块边界;语言规则、映像与扫描周期的细节以本目录为准。 diff --git a/README.md b/README.md index e69de29..ce3f380 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,77 @@ +# 子集 ST + 寄存器 VM + +IEC 风格的子集 ST:用 `project.toml` 组织多个 `.st`,编译成单一映像,由寄存器虚拟机按扫描周期执行。 + +方案见 [`Doc/初步计划.md`](Doc/初步计划.md)。 + +```text +多个 .st + ↑ project.toml 列出 + ↓ +compiler(词法 / 语法 → 符号表 → 类型检查 → 寄存器码 → 链接) + ↓ +单一映像(函数字节码 + 全局 / FB 数据槽 + 工程哈希) + ↓ +vm 按扫描周期执行;host 喂 I、收 Q、给 Δt、回放 +``` + +## 目录 + +```text +. +├── CMakeLists.txt # 顶层工程:加入四个目标,并启用测试 +├── cmake/ # CMake 辅助(警告、C++ 标准等),不是业务模块 +├── isa/ # 共享契约:指令、映像、定宽类型 +├── compiler/ # ST / toml 编译器 +├── vm/ # 寄存器虚拟机 +├── host/ # 可执行入口:编译并跑扫描周期 +├── examples/ # 样例工程(给人看、跑通最小闭环) +│ └── line1/ # MAIN + Motor FB + I/O +│ ├── project.toml +│ ├── globals.st +│ ├── motor.st +│ └── main.st +├── tests/ # 自动化用例(语法、链接、指令、回放) +├── third_party/ # 第三方(如 toml 解析),compiler 私有链接 +└── Doc/ # 设计文档 +``` + +样例和测试是数据,不做成 CMake 库。每个用例是一份 toml + 若干 `.st`,按工程子目录存放。 + +## 模块与 CMake 目标 + +四个链接目标,与目录一一对应。`compiler` 与 `vm` 不互相链接,合同放在 `isa`。 + +| 目录 | 目标 | 类型 | 依赖 | 职责 | +|---|---|---|---|---| +| `isa/` | `isa` | `STATIC` 或 `INTERFACE` | 无 | 约 20 条指令编码、映像头、工程哈希、`BOOL` / `INT` / `TIME` 宽度 | +| `compiler/` | `compiler` | `STATIC` | `isa` | 读 toml、收齐 `.st`、解析、链接、定址、类型检查、编寄存器码、写映像 | +| `vm/` | `vm` | `STATIC` | `isa` | 一台 VM、一个入口、一份映像;扫描周期、寄存器、FB、有界 `CALL` / `RET` | +| `host/` | `host` | `EXECUTABLE` | `compiler`、`vm` | 读工程、编译、按 toml 的 io 采样 I、执行 `PROGRAM MAIN`、写回 Q、用 Δt 推进定时器 / 计数器、回放 | + +词法、语法、符号表、检查、codegen、链接都留在 `compiler` 一个库里,不再拆 CMake 子库。 + +### `isa` + +编译器写映像、虚拟机读映像,两边共用同一套编码。放这里避免循环依赖。 + +### `compiler` + +toml **不声明变量**,只列出源文件、指定唯一 GVL、可选地把已有全局接到硬件。`VAR_GLOBAL` 第一版只允许出现在 `gvl.file`(如 `globals.st`)。 + +### `vm` + +每个扫描周期:采样 I → 从 `PROGRAM MAIN` 的 `pc=0` 执行到 `RET` → 写回 Q → 用本周期 Δt 推进 `TON` / `TOF` / `CTU`。无 GC、无堆、无线程;变量编译期分配。 + +### `host` + +第一版做成一条命令:编译 + 跑周期。不必再拆独立的编译器可执行文件。 + +### `examples/` 与 `tests/` + +| 目录 | 用途 | +|---|---| +| `examples/line1/` | 计划中的最小样例:全局、`MotorStarter` FB、`PROGRAM MAIN` | +| `tests/` | 冻关键字、指令、符号表、链接错误(重复 `VAR_GLOBAL`、`io.var` 未声明等) | + +`tests/` 通过 `add_test` 调用 `host` 或直接链接 `compiler` + `vm`。 diff --git a/cmake/README.md b/cmake/README.md new file mode 100644 index 0000000..4606336 --- /dev/null +++ b/cmake/README.md @@ -0,0 +1,7 @@ +# cmake + +顶层 CMake 的辅助脚本,**不是**业务模块。 + +放警告选项、C++ 标准、输出目录等共用片段,由根目录 `CMakeLists.txt` `include()`。不要按词法、VM、host 再拆成业务 CMake module。 + +第一版尽量少文件;没有共用逻辑时本目录可以为空。 diff --git a/compiler/README.md b/compiler/README.md new file mode 100644 index 0000000..239d95a --- /dev/null +++ b/compiler/README.md @@ -0,0 +1,28 @@ +# compiler + +ST / toml 编译器。CMake 目标:`compiler`(`STATIC`),依赖 `isa`。 + +读齐工程后走直通 pass,产出单一映像,不上 LLVM。词法、语法、符号表、检查、codegen、链接都留在本库,不再拆 CMake 子库。 + +## 管线 + +```text +读 toml、收齐 .st + → 词法 / 递归下降语法 + → 收集导出符号 + → 解析 VAR_EXTERNAL、链接、定地址 + → 类型检查 + → 按 PROGRAM / FUNCTION / FB 编寄存器码 + → 回填跳转、写映像头与工程哈希 +``` + +## 工程文件 + +toml **不声明变量**,只做三件事:列出源文件、指定唯一 GVL、(可选)把已声明的全局接到硬件。 + +- 字段:`files` / `entry` / `cycle_limit` / `dt_ms` / `gvl.file` / 可选 `io.*` +- 第一版只有 `gvl.file` 允许出现 `VAR_GLOBAL` +- `[[io.*]]` 的 `var` 必须已在 GVL 中声明,否则编译错误 +- 同名 `VAR_GLOBAL` 链接失败,禁止覆盖 + +第三方 toml 解析放在 `third_party/`,本库私有链接。 diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..1568291 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,18 @@ +# examples + +给人看的样例工程,**不是** CMake 库。每个子目录是一份完整工程:`project.toml` + 若干 `.st`。 + +供 `host` 直接打开,用来跑通最小闭环。自动化断言放 `tests/`。 + +## line1 + +计划中的最小样例:`MAIN` + `MotorStarter` FB + I/O。 + +| 文件 | 内容 | +|---|---| +| `project.toml` | `files` / `entry` / `gvl.file` / 可选 `io.*` | +| `globals.st` | 第一版唯一 GVL:`VAR_GLOBAL`、I/Q | +| `motor.st` | `FUNCTION_BLOCK MotorStarter`,用 `VAR_EXTERNAL` 引用急停 | +| `main.st` | `PROGRAM MAIN`,实例化 FB,写 `Q0_0` | + +不要在仓库根目录散放这些文件。 diff --git a/host/README.md b/host/README.md new file mode 100644 index 0000000..17e7c9c --- /dev/null +++ b/host/README.md @@ -0,0 +1,16 @@ +# host + +可执行入口。CMake 目标:`host`(`EXECUTABLE`),链接 `compiler` 和 `vm`。 + +第一版一条命令:读工程 → 编译映像 → 按扫描周期跑。不拆独立的编译器可执行文件。 + +## 职责 + +- 读 `project.toml` 和其中的 `.st`,交给 `compiler` +- 按 `[[io.input]]` / `[[io.output]]` 采样 I、写回 Q +- 把 `dt_ms` 交给 VM,推进 `TON` / `TOF` / `CTU` +- 单步、看寄存器和映像、按录制的 `I` 回放 + +## 不放什么 + +指令编码(`isa`)、ST 解析与链接(`compiler`)、寄存器执行循环(`vm`)。 diff --git a/isa/README.md b/isa/README.md new file mode 100644 index 0000000..f0166a5 --- /dev/null +++ b/isa/README.md @@ -0,0 +1,17 @@ +# isa + +共享契约库。CMake 目标:`isa`(`STATIC` 或 `INTERFACE`),无依赖。 + +`compiler` 写映像、`vm` 读映像,两边只依赖本目录,彼此不链接。 + +## 职责 + +- 约 20 条寄存器指令的编码(`MOVE`、`LOADK`、跳转、`LOAD_I` / `STORE_Q`、`CALL` / `RET`、`CAL_TON` 等) +- 映像头:函数字节码、全局 / FB 数据槽、工程哈希 +- 定宽类型:第一版 `BOOL`、`INT`、`TIME` + +## 不放什么 + +解析器、符号表、扫描周期循环、I/O 采样。那些分别属于 `compiler`、`vm`、`host`。 + +指令表可作为内部 IR 的文本形态,不必当主语言。 diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..8c563d4 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,14 @@ +# tests + +自动化用例,由顶层 `enable_testing()` 接入 CTest。 + +可以 `add_test` 调用 `host`,或直接链接 `compiler` + `vm`。样例工程数据按「一份 toml + 若干 `.st`」分子目录存放,不要做成 library。 + +## 第一版要冻的 + +- 关键字表与约 20 个样例程序 +- 约 20 条指令编码 +- 符号表字段:名字、种类、类型、地址、源文件 +- 链接错误:重复 `VAR_GLOBAL`、非 GVL 文件写全局、`io.var` 未声明 + +给人看的最小闭环放 `examples/line1/`,本目录放断言和负例。 diff --git a/third_party/README.md b/third_party/README.md new file mode 100644 index 0000000..120fdd8 --- /dev/null +++ b/third_party/README.md @@ -0,0 +1,7 @@ +# third_party + +第三方源码或单头库,本仓库不把它们做成业务 CMake 目标。 + +预期由 `compiler` **私有链接**(例如 toml 解析)。不要从 `isa`、`vm`、`host` 直接依赖本目录。 + +新增依赖时在此注明来源、许可和所用版本。第一版不上 LLVM、不做 CPython / JIT。 diff --git a/vm/README.md b/vm/README.md new file mode 100644 index 0000000..feba254 --- /dev/null +++ b/vm/README.md @@ -0,0 +1,24 @@ +# vm + +寄存器虚拟机。CMake 目标:`vm`(`STATIC`),只依赖 `isa`。 + +运行时是 **一台 VM、一个入口、一份映像**。不链接 `compiler`。 + +## 扫描周期 + +```text +1. 按 toml 的 io 绑定,采样 → I / 输入全局 +2. 从 PROGRAM MAIN 的 pc=0 执行到 RET +3. 写回 Q / 输出全局 +4. 用本周期 Δt 推进 TON / TOF / CTU(不用 wall clock) +``` + +## 约束 + +- 局部 / `VAR` = 固定寄存器;`nregs` 写在函数头 +- `I` / `Q` / `M` 走映像指令,不是通用寄存器 +- FB 实例固定布局,字段偏移编译期算死 +- `CALL` 目标是立即数 `fn_id`,有界调用栈 +- 无 GC、无堆、无线程;每周期受 `cycle_limit` 限制 + +I/O 从哪来、Δt 谁给、回放怎么喂,属于 `host`。