/** * @file main.cpp * @brief STCompiler 可执行入口 * @author * @date 2026-08-21 */ #include #include #include #include #include #include #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" namespace { void usage() { std::printf("usage: STCompiler [-o .stb] --machine \n" " STCompiler .stb --disasm --machine \n" " 解析工程并编译(词法 → 语法 → 链接 → 类型 → 寄存器码)\n" " -o .stb 编译并写出映像文件\n" " --machine 机器定义(machine.toml,编译路径必填)\n" " --disasm 反汇编一个已编译的 .stb 映像(需要 --machine)\n" " --help 打印本帮助\n"); } // 反汇编一个已编译映像(函数表逐条 + 常量表 + 数据段摘要)。 // 指令偏移为文件绝对字节偏移;反汇编按 machine.toml 的 format 输出。 int dump_image(const char* path, const compiler::MachineConfig& cfg) { std::vector bytes; std::string err; if (!compiler::read_stb_file(path, &bytes, &err)) { std::fprintf(stderr, "error: %s\n", err.c_str()); return 1; } const compiler::StbView v = compiler::StbView::from(bytes); if (!v.ok()) { std::fprintf(stderr, "error: %s\n", v.error().c_str()); return 1; } std::printf("image: %s (%zu bytes, %u functions, %u globals, entry fn %u)\n", path, bytes.size(), v.n_funcs(), v.n_globals(), v.entry_fn_id()); std::printf(" dt_ms=%u cycle_limit=%u hash=0x%016llx model=%s sha=%s\n", v.dt_ms(), v.cycle_limit(), static_cast(v.project_hash()), v.model_id().c_str(), v.sha_ok() ? "ok" : "BAD"); if (v.n_consts()) { std::printf("constants:\n"); 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(c.value)); } } std::printf("functions:\n"); 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]; compiler::disasm(cfg, reinterpret_cast(base)[j], buf, sizeof buf); std::printf(" 0x%04x %s\n", v.offset_code() + r.code_offset + j * 4, buf); } } if (v.data_len()) { std::printf("data (%zu bytes):\n", v.data_len()); const uint8_t* d = v.data_bytes(); for (size_t i = 0; i < v.data_len(); i += 16) { std::printf(" 0x%04x:", static_cast(i)); for (size_t j = 0; j < 16 && i + j < v.data_len(); ++j) { std::printf(" %02x", d[i + j]); } std::printf("\n"); } } return 0; } } int main(int argc, char** argv) { if (argc < 2) { std::printf("STCompiler 0.1\n"); usage(); return 0; } if (std::strcmp(argv[1], "--help") == 0) { usage(); return 0; } // 参数收集 std::string machine_path; std::string out_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]; } else if (std::strcmp(argv[i], "-o") == 0) { out_path = argv[i + 1]; } } for (int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "--disasm") == 0) { disasm_mode = true; } } // --disasm:需要机器定义(反汇编按 machine.toml 的 format 输出) if (disasm_mode) { if (machine_path.empty()) { std::fprintf(stderr, "error: missing --machine \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; } return dump_image(argv[1], cfg); } const std::string toml_path = argv[1]; 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; } const std::vector files = compiler::compile_files(proj); // 打印模式(无 -o):不需要机器定义 if (out_path.empty()) { uint64_t hash = 0; if (!compiler::compute_project_hash(proj, &hash, &err)) { std::fprintf(stderr, "error: %s\n", err.c_str()); return 1; } std::printf("project: %s\n", proj.name.c_str()); std::printf("files:\n"); for (const std::string& f : files) { std::printf(" %s\n", f.c_str()); } std::printf("hash: 0x%016llx\n", static_cast(hash)); return 0; } // 编译路径:机器定义必填(编码/类型/FB 布局来自 machine.toml) if (machine_path.empty()) { std::fprintf(stderr, "error: missing --machine \n"); usage(); return 1; } compiler::MachineConfig cfg; if (!cfg.load(machine_path, &err)) { std::fprintf(stderr, "error: %s\n", err.c_str()); return 1; } // 完整管线:读 .st → 链接 → 类型检查 → 寄存器码 std::vector units; for (const std::string& f : files) { compiler::SourceUnit u; if (!compiler::load_unit(proj.base_dir + "/" + f, &u, &err)) { std::fprintf(stderr, "error: %s\n", err.c_str()); return 1; } units.push_back(std::move(u)); } compiler::LinkResult link; if (!compiler::link_project(proj, units, &link, &err)) { std::fprintf(stderr, "error: %s\n", err.c_str()); return 1; } if (!compiler::check_project(proj, units, link, &err)) { std::fprintf(stderr, "error: %s\n", err.c_str()); return 1; } std::vector image; if (!compiler::codegen_project(proj, units, link, cfg, &image, &err)) { std::fprintf(stderr, "error: %s\n", err.c_str()); return 1; } if (!compiler::write_stb_file(out_path.c_str(), image, &err)) { std::fprintf(stderr, "error: %s\n", err.c_str()); return 1; } // 写后自检:型号标识与 SHA-256 const compiler::StbView self = compiler::StbView::from(image); if (!self.ok() || !self.sha_ok()) { std::fprintf(stderr, "error: self-check failed: %s\n", self.error().c_str()); return 1; } if (!self.model_matches(cfg.model_name(), cfg.version())) { std::fprintf(stderr, "error: self-check model mismatch\n"); return 1; } // sidecar:I/O 绑定 var → 槽号 → channel/bit(不进映像,执行器采样用) std::vector 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(std::tolower(static_cast(ch))); } const auto it = link.global_index.find(key); if (it != link.global_index.end()) { out_b.slot = it->second; // 12.6 已校验存在 } bindings.push_back(out_b); } std::filesystem::path sidecar = std::filesystem::path(out_path); sidecar.replace_extension(".runtime.toml"); if (!compiler::write_sidecar_file(sidecar.string().c_str(), bindings, &err)) { std::fprintf(stderr, "error: %s\n", err.c_str()); return 1; } 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.n_funcs(), v.n_globals()); return 0; }