diff --git a/compiler/src/main.cpp b/compiler/src/main.cpp index a45da05..e7bccc1 100644 --- a/compiler/src/main.cpp +++ b/compiler/src/main.cpp @@ -10,12 +10,18 @@ #include #include +#include "compiler/Codegen.h" +#include "compiler/Linker.h" #include "compiler/Project.h" +#include "compiler/Typecheck.h" +#include "isa/Image.h" namespace { void usage() { - std::printf("usage: STCompiler \n" - " 解析工程并打印文件集合与工程哈希(12.3 阶段)\n" + std::printf("usage: STCompiler [-o .stb]\n" + " 解析工程并编译(词法 → 语法 → 链接 → 类型 → 寄存器码)\n" + " -o .stb 编译并写出映像文件\n" + " 无 -o 只打印文件集合与工程哈希(12.3 阶段)\n" " --help 打印本帮助\n"); } } @@ -31,24 +37,68 @@ int main(int argc, char** argv) { return 0; } + const std::string toml_path = argv[1]; + std::string out_path; + for (int i = 2; i + 1 < argc; ++i) { + if (std::strcmp(argv[i], "-o") == 0) { + out_path = argv[i + 1]; + } + } + compiler::Project proj; std::string err; - if (!compiler::parse_project(argv[1], &proj, &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); - uint64_t hash = 0; - if (!compiler::compute_project_hash(proj, &hash, &err)) { + + 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; + } + + // 完整管线:读 .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, &image, &err)) { + std::fprintf(stderr, "error: %s\n", err.c_str()); + return 1; + } + if (!isa::write_stb_file(out_path.c_str(), image, &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)); + const isa::ImageView v = isa::ImageView::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); return 0; }