stage2 提供c后端 提交stage1的测试

This commit is contained in:
zzy committed 2026-09-20 17:56:11 +08:00
1 parent 846f441e3a
commit 51d408d524
82 files changed
+6872 -65

No files matched your search

+35 -2
View File
@@ -13,7 +13,8 @@ type Ast = @import("./ast.spl");
type Parser = @import("./parser.spl");
type Sema = @import("./sema.spl");
type .{ .append_usize } = @import("./utils/fmt.spl");
type .{ .read_all, .print, .eprint } = @import("./utils/io.spl");
type .{ .read_all, .print, .eprint, .open_cstr, .write_all } = @import("./utils/io.spl");
type File = @import("./sys/file.spl");
type .{ .Sources, .Source, .set_new, .set_add, .set_at, .set_drop } = @import("./utils/source.spl");
type .{ .Diag, .Code, .span_none } = @import("./diag.spl");
type Logger = @import("./utils/log.spl");
@@ -25,6 +26,7 @@ type LayoutM = @import("./layout.spl");
type .{ .Layout } = @import("./layout.spl");
type Ir2VmM = @import("./ir2vm.spl");
type .{ .Ir2Vm } = @import("./ir2vm.spl");
type Ir2CM = @import("./ir2c.spl");
type .{ .alloc, .free } = @import("./sys/mem.spl");
fn token_at(tokens: *Vec, index: usize): Token {
@@ -566,6 +568,7 @@ type PipeMode = enum {
Vm, // 继续 layout + ir2vm,dump VM
Compile, // 继续 layout + ir2vm,写 outpath
State, // 只逐步打日志(诊断“卡在哪一步”)
C, // 继续 layout + ir2c,dump C
}
fn step(mode: PipeMode, s: []u8) {
@@ -723,6 +726,31 @@ fn run_pipeline(log: *Logger, path: ByteView, mode: PipeMode, outpath: ByteView)
LayoutM.resolve(&layout, &sema.types.ir);
step(mode, "state: layout ok\n");
if @enum2int(mode) == @enum2int(PipeMode.C) {
var cout = ByteBuffer.new();
defer { ByteBuffer.drop(&cout); }
var ok = Ir2CM.compile(&builder.ir, &sema.types.ir, &layout, &sema.attr, &cout);
if outpath.len != 0 {
var f = open_cstr(outpath, ByteView.from_slice("wb"));
if !File.valid(&f) {
Logger.error(log, "cannot open C output file");
ret 1;
}
match write_all(&f, ByteBuffer.as_slice(cout)) { .Ok => {}, .Err(error) => {} }
ignore_i32(File.close(&f));
} else {
match print(ByteBuffer.as_slice(cout)) {
.Ok => {},
.Err(error) => { ret 1; },
}
}
if !ok {
Logger.error(log, "ir2c failed (see generated C for unsupported markers)");
ret 1;
}
ret 0;
}
var ir2vm: Ir2Vm = undefined;
Ir2VmM.init(&ir2vm, &builder.ir, &sema.types.ir, &layout, &sema.attr);
defer { Ir2VmM.drop(&ir2vm); }
@@ -776,11 +804,13 @@ fn main(argc: i32, argv: **u8): i32 {
}
if argc < 4 {
Logger.fatal(&log, "usage: splc1 --dump <lex|ast|sema|ir|vm> <file> [out]");
Logger.fatal(&log, "usage: splc1 --dump <lex|ast|sema|ir|vm|c> <file> [out]");
ret 1;
}
var mode = ByteView.from_cstr(argv[2]);
var path = ByteView.from_cstr(argv[3]);
var dout = ByteView.empty();
if argc >= 5 { dout = ByteView.from_cstr(argv[4]); }
if ByteView.eq(mode, ByteView.from_slice("lex")) {
ret dump_lex(&log, path);
@@ -800,6 +830,9 @@ fn main(argc: i32, argv: **u8): i32 {
if ByteView.eq(mode, ByteView.from_slice("state")) {
ret run_pipeline(&log, path, .State, ByteView.empty());
}
if ByteView.eq(mode, ByteView.from_slice("c")) {
ret run_pipeline(&log, path, .C, dout);
}
Logger.fatal(&log, "dump mode not implemented");
ret 1;
}