diff --git a/executor/src/main.cpp b/executor/src/main.cpp index a1ca3a5..22157cd 100644 --- a/executor/src/main.cpp +++ b/executor/src/main.cpp @@ -5,7 +5,7 @@ * @date 2026-08-21 * * @details 12.10:加载 .stb + sidecar,按扫描周期执行。 - * - `BytecodeExecutor .stb [--cycles N] [--replay ]` + * - `BytecodeExecutor .stb [--cycles N] [--replay ] [--step]` * - 只链 vm + isa,不链 compiler;dt_ms / cycle_limit 从映像头取 * - I 采样 / Q 写回按 sidecar(var → 槽号 → channel/bit),不创造变量 * - --replay:读录制文本(每行空格分隔的 0/1,按 io.input 绑定顺序), @@ -26,6 +26,7 @@ namespace { + /// 打印命令行用法。 void usage() { std::printf("usage: BytecodeExecutor .stb [--cycles N] [--replay ] [--step]\n" " 加载 .stb + .runtime.toml,按扫描周期执行\n" @@ -35,16 +36,28 @@ namespace { " --help 打印本帮助\n"); } - // sidecar 绑定(TOML 子集,格式冻结于 Doc/isa/指令与映像.md) + /** + * @brief sidecar 中的一条 I/O 绑定。 + * @details TOML 子集 `var`/`slot`/`channel`/`bit`,格式冻结于 + * Doc/isa/指令与映像.md;不创造变量,只把外部通道映射到数据区槽。 + */ struct Binding { - bool is_input = true; - std::string var; - uint32_t slot = 0; - uint32_t channel = 0; - uint32_t bit = 0; + bool is_input = true; ///< true = [[io.input]],false = [[io.output]] + std::string var; ///< 绑定的全局变量名 + uint32_t slot = 0; ///< 数据区槽号(槽 × 8 = 字节偏移) + uint32_t channel = 0; ///< 通道号(展示用) + uint32_t bit = 0; ///< 位号(展示用) }; - // 解析 .runtime.toml(逐行手写解析,仅冻结子集) + /** + * @brief 解析 .runtime.toml(逐行手写解析,仅冻结子集)。 + * @param path sidecar 路径 + * @param out 输出绑定列表(按文件中 [[io.input]] / [[io.output]] 出现顺序) + * @param err 错误输出 + * @return true 成功;false(文件打不开,err 已写) + * @details 识别行:`[[io.input]]` / `[[io.output]]` 分段,`key = "value"` 或 + * `key = 数字` 字段(var/slot/channel/bit);空行与 `#` 注释跳过。 + */ bool parse_sidecar(const std::string& path, std::vector* out, std::string* err) { std::ifstream in(path); @@ -109,16 +122,36 @@ namespace { return true; } - // 读一个槽的 BOOL 值(低字节) + /** + * @brief 读一个槽的 BOOL 值。 + * @param m 机器实例 + * @param slot 槽号 + * @return 低字节非零 → 1,否则 0 + */ int slot_bool(vm::Machine& m, uint32_t slot) { return m.data()[static_cast(slot) * 8] ? 1 : 0; } + /** + * @brief 写一个槽的 BOOL 值。 + * @param m 机器实例 + * @param slot 槽号 + * @param v 0/1(非零归一化为 1) + */ void put_bool(vm::Machine& m, uint32_t slot, int v) { m.data()[static_cast(slot) * 8] = v ? 1 : 0; } - // 采样:回放行按 io.input 顺序填,无回放则全 0;文件读尽后保持最后一行 + /** + * @brief 本周期 I 采样:喂入数据区。 + * @param m 机器实例 + * @param bindings sidecar 绑定列表 + * @param replay_in 回放文件流(未打开则无回放) + * @param replay_line 当前回放行(0/1 按 io.input 绑定顺序) + * @details 有回放:读一行,按 io.input 顺序填槽,缺位补 0; + * 文件读尽后保持最后一行(replay_line 不清空)。 + * 无回放:所有 input 槽填 0。 + */ void sample_inputs(vm::Machine& m, const std::vector& bindings, std::ifstream& replay_in, std::vector& replay_line) { if (replay_in.is_open()) { @@ -155,7 +188,14 @@ namespace { } } - // 按 sidecar 绑定顺序打印 I/Q + /** + * @brief 按 sidecar 绑定顺序生成 I / Q 文本。 + * @param m 机器实例 + * @param bindings sidecar 绑定列表 + * @param is 输出:input 槽值(空格分隔) + * @param qs 输出:output 槽值(空格分隔) + * @return is(与参数 3 同对象) + */ std::string iq_string(vm::Machine& m, const std::vector& bindings, std::string* is, std::string* qs) { for (const Binding& b : bindings) { @@ -172,6 +212,16 @@ namespace { } // namespace +/** + * @brief 程序入口。 + * @param argc 参数个数 + * @param argv 参数表 + * @return 0 成功;1 失败 + * @details 流程:解析参数(--cycles/--replay/--step)→ 读 .stb → Image 解析 + * → Machine::create(型号/SHA 校验)→ 解析 sidecar → 按周期循环: + * 采样 I → run_cycle → 打印 I/Q。--step 模式跑 1 个周期并逐指令 + * 打印 pc/fn/反汇编/非零寄存器。所有错误打印 `error: ...` 到 stderr。 + */ int main(int argc, char** argv) { if (argc < 2) { std::printf("BytecodeExecutor 0.1\n");