阶段 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:
+57
-35
@@ -12,67 +12,66 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "compiler/Codec.h"
|
||||
#include "compiler/Codegen.h"
|
||||
#include "compiler/Linker.h"
|
||||
#include "compiler/MachineConfig.h"
|
||||
#include "compiler/Project.h"
|
||||
#include "compiler/Stb.h"
|
||||
#include "compiler/Typecheck.h"
|
||||
#include "isa/Encode.h"
|
||||
#include "isa/Image.h"
|
||||
|
||||
namespace {
|
||||
void usage() {
|
||||
std::printf("usage: STCompiler <project.toml> [-o <name>.stb]\n"
|
||||
" STCompiler <name>.stb --disasm\n"
|
||||
std::printf("usage: STCompiler <project.toml> [-o <name>.stb] --machine <machine.toml>\n"
|
||||
" STCompiler <name>.stb --disasm --machine <machine.toml>\n"
|
||||
" 解析工程并编译(词法 → 语法 → 链接 → 类型 → 寄存器码)\n"
|
||||
" -o <name>.stb 编译并写出映像文件\n"
|
||||
" 无 -o 只打印文件集合与工程哈希(12.3 阶段)\n"
|
||||
" --disasm 反汇编一个已编译的 .stb 映像\n"
|
||||
" --machine <path> 机器定义(machine.toml,编译路径必填)\n"
|
||||
" --disasm 反汇编一个已编译的 .stb 映像(需要 --machine)\n"
|
||||
" --help 打印本帮助\n");
|
||||
}
|
||||
|
||||
// 反汇编一个已编译映像(函数表逐条 + 常量表 + 数据段摘要)。
|
||||
// 映像无符号表,按 fn_id / 槽号显示;指令偏移为文件绝对字节偏移。
|
||||
int dump_image(const char* path) {
|
||||
// 指令偏移为文件绝对字节偏移;反汇编按 machine.toml 的 format 输出。
|
||||
int dump_image(const char* path, const compiler::MachineConfig& cfg) {
|
||||
std::vector<uint8_t> bytes;
|
||||
std::string err;
|
||||
if (!isa::read_stb_file(path, &bytes, &err)) {
|
||||
if (!compiler::read_stb_file(path, &bytes, &err)) {
|
||||
std::fprintf(stderr, "error: %s\n", err.c_str());
|
||||
return 1;
|
||||
}
|
||||
const isa::ImageView v = isa::ImageView::from(bytes);
|
||||
const compiler::StbView v = compiler::StbView::from(bytes);
|
||||
if (!v.ok()) {
|
||||
std::fprintf(stderr, "error: %s\n", v.error().c_str());
|
||||
return 1;
|
||||
}
|
||||
const isa::ImageHeader& h = v.header();
|
||||
std::printf("image: %s (%zu bytes, %u functions, %u globals, entry fn %u)\n",
|
||||
path, bytes.size(), h.n_funcs, h.n_globals, h.entry_fn_id);
|
||||
std::printf(" dt_ms=%u cycle_limit=%u hash=0x%016llx\n", h.dt_ms,
|
||||
h.cycle_limit, static_cast<unsigned long long>(h.project_hash));
|
||||
path, bytes.size(), v.n_funcs(), v.n_globals(), v.entry_fn_id());
|
||||
std::printf(" dt_ms=%u cycle_limit=%u hash=0x%016llx\n", v.dt_ms(),
|
||||
v.cycle_limit(), static_cast<unsigned long long>(v.project_hash()));
|
||||
|
||||
if (h.n_consts) {
|
||||
if (v.n_consts()) {
|
||||
std::printf("constants:\n");
|
||||
for (uint32_t i = 0; i < h.n_consts; ++i) {
|
||||
const isa::ConstEntry c = v.const_entry(i);
|
||||
const char* tag = c.tag == isa::types::Bool ? "BOOL"
|
||||
: c.tag == isa::types::Int ? "INT"
|
||||
: "TIME";
|
||||
for (uint32_t i = 0; i < v.n_consts(); ++i) {
|
||||
const compiler::ConstEntry c = v.const_entry(i);
|
||||
const char* tag = c.tag == 0 ? "BOOL" : c.tag == 1 ? "INT" : "TIME";
|
||||
std::printf(" [%u] %s %llu\n", i, tag,
|
||||
static_cast<unsigned long long>(c.value));
|
||||
}
|
||||
}
|
||||
|
||||
std::printf("functions:\n");
|
||||
for (uint32_t i = 0; i < h.n_funcs; ++i) {
|
||||
const isa::FuncRow r = v.func_row(i);
|
||||
for (uint32_t i = 0; i < v.n_funcs(); ++i) {
|
||||
const compiler::StbView::FuncRow r = v.func_row(i);
|
||||
std::printf(" fn %u: nregs=%u, offset=%u, len=%u\n", i, r.nregs,
|
||||
r.code_offset, r.code_len);
|
||||
const uint8_t* base = v.code_bytes() + r.code_offset;
|
||||
for (uint32_t j = 0; j < r.code_len; ++j) {
|
||||
char buf[64];
|
||||
isa::disasm(reinterpret_cast<const uint32_t*>(base)[j], buf, sizeof buf);
|
||||
compiler::disasm(cfg, reinterpret_cast<const uint32_t*>(base)[j], buf,
|
||||
sizeof buf);
|
||||
std::printf(" 0x%04x %s\n",
|
||||
h.offset_code + r.code_offset + j * 4, buf);
|
||||
v.offset_code() + r.code_offset + j * 4, buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,13 +101,37 @@ int main(int argc, char** argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --disasm:第一参数是 .stb 路径,不重新编译
|
||||
// 参数收集
|
||||
std::string machine_path;
|
||||
bool disasm_mode = false;
|
||||
for (int i = 2; i + 1 < argc; ++i) {
|
||||
if (std::strcmp(argv[i], "--machine") == 0) {
|
||||
machine_path = argv[i + 1];
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (std::strcmp(argv[i], "--disasm") == 0) {
|
||||
return dump_image(argv[1]);
|
||||
disasm_mode = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 机器定义(编译与反汇编都需要;加载/校验失败报错退出)
|
||||
if (machine_path.empty()) {
|
||||
std::fprintf(stderr, "error: missing --machine <machine.toml>\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
compiler::MachineConfig cfg;
|
||||
std::string err;
|
||||
if (!cfg.load(machine_path, &err)) {
|
||||
std::fprintf(stderr, "error: %s\n", err.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (disasm_mode) {
|
||||
return dump_image(argv[1], cfg);
|
||||
}
|
||||
|
||||
const std::string toml_path = argv[1];
|
||||
std::string out_path;
|
||||
for (int i = 2; i + 1 < argc; ++i) {
|
||||
@@ -118,7 +141,6 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
compiler::Project proj;
|
||||
std::string err;
|
||||
if (!compiler::parse_project(toml_path, &proj, &err)) {
|
||||
std::fprintf(stderr, "error: %s\n", err.c_str());
|
||||
return 1;
|
||||
@@ -160,19 +182,19 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
std::vector<uint8_t> image;
|
||||
if (!compiler::codegen_project(proj, units, link, &image, &err)) {
|
||||
if (!compiler::codegen_project(proj, units, link, cfg, &image, &err)) {
|
||||
std::fprintf(stderr, "error: %s\n", err.c_str());
|
||||
return 1;
|
||||
}
|
||||
if (!isa::write_stb_file(out_path.c_str(), image, &err)) {
|
||||
if (!compiler::write_stb_file(out_path.c_str(), image, &err)) {
|
||||
std::fprintf(stderr, "error: %s\n", err.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// sidecar:I/O 绑定 var → 槽号 → channel/bit(不进映像,执行器采样用)
|
||||
std::vector<isa::IoBinding> bindings;
|
||||
for (const isa::IoBinding& b : proj.io) {
|
||||
isa::IoBinding out_b = b;
|
||||
std::vector<compiler::IoBinding> bindings;
|
||||
for (const compiler::IoBinding& b : proj.io) {
|
||||
compiler::IoBinding out_b = b;
|
||||
std::string key = b.var;
|
||||
for (char& ch : key) {
|
||||
ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
|
||||
@@ -185,13 +207,13 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
std::filesystem::path sidecar = std::filesystem::path(out_path);
|
||||
sidecar.replace_extension(".runtime.toml");
|
||||
if (!isa::write_sidecar_file(sidecar.string().c_str(), bindings, &err)) {
|
||||
if (!compiler::write_sidecar_file(sidecar.string().c_str(), bindings, &err)) {
|
||||
std::fprintf(stderr, "error: %s\n", err.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
const isa::ImageView v = isa::ImageView::from(image);
|
||||
const compiler::StbView v = compiler::StbView::from(image);
|
||||
std::printf("compiled: %s (%zu bytes, %u functions, %u globals)\n",
|
||||
out_path.c_str(), image.size(), v.header().n_funcs, v.header().n_globals);
|
||||
out_path.c_str(), image.size(), v.n_funcs(), v.n_globals());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user