阶段 B 步骤 4:compiler 配置驱动化,去除 isa 依赖。
- Project.h 自带 IoBinding;Stb.h/cpp:compiler 侧 .stb 规范(常量/ConstEntry/FNV/StbView/读写/sidecar) - Codec.h/cpp:指令字 pack/字段/配置驱动 disasm(format 表驱动) - Codegen:opcode 全查 MachineConfig(E_* 发射器)、常量 tag 查配置类型、初值按基元宽度写、 映像拼装用 Stb 常量;codegen_project 增加 cfg 参数 - main.cpp:--machine <path>(编译/反汇编必填),--disasm 用 StbView+Codec - CMake:compiler 不再链接 isa(仅 toml++ 私有);测试补链 isa(自身断言用) - 验证:20 用例字节不变(hash 0xc3fe4ae74ad45900 相同)、ctest 12/12、缺 --machine 报错退出
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file Codec.h
|
||||
* @brief 指令字编解码 + 配置驱动反汇编(编译器侧)
|
||||
* @author
|
||||
* @date 2026-08-21
|
||||
*
|
||||
* @details 编译器不依赖 isa:指令字布局([op:8|rd:8|a:8|b:8] 小端)与
|
||||
* 反汇编输出(按 machine.toml 的 format/参数名)全部由本模块 + MachineConfig 提供,
|
||||
* 保证与执行器(isa)产生的字节一致。
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "compiler/MachineConfig.h"
|
||||
|
||||
namespace compiler {
|
||||
|
||||
// 指令字:[op:8 | rd:8 | a:8 | b:8],小端 u32
|
||||
typedef uint32_t Instr;
|
||||
|
||||
Instr pack(uint8_t opcode, uint8_t rd, uint8_t a, uint8_t b);
|
||||
|
||||
uint8_t op_of(Instr w);
|
||||
uint8_t rd_of(Instr w);
|
||||
uint8_t a_of(Instr w);
|
||||
uint8_t b_of(Instr w);
|
||||
uint16_t imm16_of(Instr w); // a|b 拼 u16(const_id / slot / fn_id)
|
||||
int16_t off16_of(Instr w); // a|b 有符号偏移(相对下一条)
|
||||
|
||||
// 配置驱动反汇编:按 machine.toml 的 format 输出一行文本。
|
||||
// 未知操作码 → "??? 0x<hex>"。输出格式与 Doc/isa/指令与映像.md 一致。
|
||||
void disasm(const MachineConfig& cfg, Instr w, char* out, size_t cap);
|
||||
}
|
||||
@@ -12,14 +12,16 @@
|
||||
#include <vector>
|
||||
|
||||
#include "compiler/Linker.h"
|
||||
#include "compiler/MachineConfig.h"
|
||||
#include "compiler/Parser.h"
|
||||
#include "compiler/Project.h"
|
||||
|
||||
namespace compiler {
|
||||
|
||||
// 编译工程为 .stb 映像字节(在链接 + 类型检查成功后调用)。
|
||||
// 指令 opcode / 类型 tag / FB 布局全部来自 machine.toml(cfg)。
|
||||
// 失败返回 false,err 前缀 "codegen error"。
|
||||
bool codegen_project(const Project& proj, const std::vector<SourceUnit>& units,
|
||||
const LinkResult& link, std::vector<uint8_t>* image,
|
||||
std::string* err);
|
||||
const LinkResult& link, const MachineConfig& cfg,
|
||||
std::vector<uint8_t>* image, std::string* err);
|
||||
}
|
||||
|
||||
@@ -11,10 +11,17 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "isa/Image.h"
|
||||
|
||||
namespace compiler {
|
||||
|
||||
// I/O 绑定(project.toml [[io.*]];不创造变量,slot 由链接结果解析)
|
||||
struct IoBinding {
|
||||
std::string var;
|
||||
uint32_t slot = 0;
|
||||
uint32_t channel = 0;
|
||||
uint32_t bit = 0;
|
||||
bool is_input = false; // true = [[io.input]],false = [[io.output]]
|
||||
};
|
||||
|
||||
// 与 Doc/初步计划.md 12.1 的 toml 字段表一一对应。
|
||||
// 字段白名单 / 必填 / io 完整性在 parse_project 内校验。
|
||||
struct Project {
|
||||
@@ -24,7 +31,7 @@ namespace compiler {
|
||||
uint32_t dt_ms = 0; // 必填 > 0
|
||||
std::vector<std::string> files_st; // [files] 必填非空
|
||||
std::string gvl_file; // [gvl] 可选;无则空串
|
||||
std::vector<isa::IoBinding> io; // [[io.*]] 可选;slot 12.6 才解析,此处填 0
|
||||
std::vector<IoBinding> io; // [[io.*]] 可选;slot 12.6 才解析,此处填 0
|
||||
std::string base_dir; // toml 所在目录(解析相对路径用)
|
||||
};
|
||||
|
||||
@@ -37,6 +44,6 @@ namespace compiler {
|
||||
std::vector<std::string> compile_files(const Project& p);
|
||||
|
||||
// 校验全部文件存在并计算工程哈希:集合按路径排序,对内容做 FNV-1a 64 增量;
|
||||
// 空集合 = basis(isa::kFnvBasis)。缺文件报错前缀 "file missing"。
|
||||
// 空集合 = basis(Stb::kFnvBasis)。缺文件报错前缀 "file missing"。
|
||||
bool compute_project_hash(const Project& p, uint64_t* hash, std::string* err);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @file Stb.h
|
||||
* @brief 编译器自带的 .stb 映像规范(写侧)+ 只读视图 + FNV-1a
|
||||
* @author
|
||||
* @date 2026-08-21
|
||||
*
|
||||
* @details 执行器(vm)各有自己的读写实现;格式契约见 Doc/isa/指令与映像.md。
|
||||
* 12.13 修订(型号标识[32] 头 104 字节 + SHA-256 文件尾)在后续步骤落地。
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "compiler/Project.h"
|
||||
|
||||
namespace compiler {
|
||||
|
||||
// ---- .stb 格式常量(契约)----
|
||||
static const uint32_t kMagic = 0x43545353u; // "STSC" 小端
|
||||
static const uint32_t kVersion = 1;
|
||||
static const size_t kHeaderSize = 72;
|
||||
static const size_t kConstEntrySize = 12;
|
||||
static const size_t kFuncRowSize = 12;
|
||||
static const uint64_t kFnvBasis = 0xcbf29ce484222325ull;
|
||||
static const uint64_t kFnvPrime = 0x100000001b3ull;
|
||||
|
||||
// 常量表一行(tag:0=BOOL、1=INT、2=TIME,契约)
|
||||
struct ConstEntry {
|
||||
uint32_t tag = 0;
|
||||
uint64_t value = 0;
|
||||
};
|
||||
|
||||
// FNV-1a 64(工程哈希,非密码学)
|
||||
uint64_t fnv1a64_update(uint64_t h, const uint8_t* data, size_t len);
|
||||
uint64_t fnv1a64(const uint8_t* data, size_t len);
|
||||
|
||||
// 只读视图(--disasm 用;校验魔数/版本/段边界)
|
||||
class StbView {
|
||||
public:
|
||||
struct FuncRow {
|
||||
uint32_t nregs = 0;
|
||||
uint32_t code_offset = 0;
|
||||
uint32_t code_len = 0;
|
||||
};
|
||||
|
||||
static StbView from(const uint8_t* buf, size_t len);
|
||||
static StbView from(const std::vector<uint8_t>& buf);
|
||||
|
||||
bool ok() const { return ok_; }
|
||||
const std::string& error() const { return err_; }
|
||||
|
||||
uint32_t cycle_limit() const { return cycle_limit_; }
|
||||
uint32_t dt_ms() const { return dt_ms_; }
|
||||
uint64_t project_hash() const { return project_hash_; }
|
||||
uint32_t entry_fn_id() const { return entry_fn_id_; }
|
||||
uint32_t n_globals() const { return n_globals_; }
|
||||
uint32_t n_consts() const { return n_consts_; }
|
||||
uint32_t n_funcs() const { return n_funcs_; }
|
||||
uint32_t offset_code() const { return offset_code_; }
|
||||
uint32_t offset_fb() const { return offset_fb_; }
|
||||
uint32_t offset_data() const { return offset_data_; }
|
||||
|
||||
ConstEntry const_entry(size_t i) const;
|
||||
FuncRow func_row(size_t i) const;
|
||||
const uint8_t* code_bytes() const;
|
||||
size_t code_len() const;
|
||||
const uint8_t* data_bytes() const;
|
||||
size_t data_len() const;
|
||||
|
||||
private:
|
||||
StbView() : buf_(0), len_(0) {}
|
||||
|
||||
uint32_t offs_of_const() const; // offset_const(from 已校验段起点)
|
||||
|
||||
const uint8_t* buf_;
|
||||
size_t len_;
|
||||
bool ok_ = false;
|
||||
std::string err_;
|
||||
uint32_t cycle_limit_ = 0;
|
||||
uint32_t dt_ms_ = 0;
|
||||
uint64_t project_hash_ = 0;
|
||||
uint32_t entry_fn_id_ = 0;
|
||||
uint32_t n_globals_ = 0;
|
||||
uint32_t n_consts_ = 0;
|
||||
uint32_t n_funcs_ = 0;
|
||||
uint32_t offset_code_ = 0;
|
||||
uint32_t offset_fb_ = 0;
|
||||
uint32_t offset_data_ = 0;
|
||||
};
|
||||
|
||||
// 文件读写(纯字节;校验交给 StbView)
|
||||
bool read_stb_file(const char* path, std::vector<uint8_t>* out, std::string* err);
|
||||
bool write_stb_file(const char* path, const std::vector<uint8_t>& img, std::string* err);
|
||||
|
||||
// sidecar 生成与写文件(I/O 绑定 var → 槽号 → channel/bit)
|
||||
std::string make_sidecar(const std::vector<IoBinding>& bindings);
|
||||
bool write_sidecar_file(const char* path, const std::vector<IoBinding>& bindings,
|
||||
std::string* err);
|
||||
}
|
||||
Reference in New Issue
Block a user