// compile_seed.ce — compile a .cm module to native .dylib via QBE (seed mode) // Usage: ./cell --dev --seed compile_seed var fd = use("fd") var os = use("os") var tokenize = use("tokenize") var parse = use("parse") var fold = use("fold") var mcode = use("mcode") var streamline = use("streamline") var qbe_macros = use("qbe") var qbe_emit = use("qbe_emit") if (length(args) < 1) { print("usage: cell --dev --seed compile_seed ") disrupt } var file = args[0] var base = file if (ends_with(base, ".cm")) { base = text(base, 0, length(base) - 3) } else if (ends_with(base, ".ce")) { base = text(base, 0, length(base) - 3) } var safe = replace(replace(replace(base, "/", "_"), "-", "_"), ".", "_") var symbol = "js_" + safe + "_use" var tmp = "/tmp/qbe_" + safe var ssa_path = tmp + ".ssa" var s_path = tmp + ".s" var o_path = tmp + ".o" var rt_o_path = "/tmp/qbe_rt.o" var dylib_path = file + ".dylib" var rc = 0 // Step 1: compile to QBE IL print("compiling " + file + " to QBE IL...") var src = text(fd.slurp(file)) var result = tokenize(src, file) var ast = parse(result.tokens, src, file, tokenize) var folded = fold(ast) var compiled = mcode(folded) var optimized = streamline(compiled) var il = qbe_emit(optimized, qbe_macros) // Step 2: append wrapper function var wrapper = ` export function l $${symbol}(l %ctx) { @entry %result =l call $cell_rt_module_entry(l %ctx) ret %result } ` il = il + wrapper // Write IL to file — remove old file first to avoid leftover content if (fd.is_file(ssa_path)) fd.unlink(ssa_path) var out_fd = fd.open(ssa_path, 1537, 420) fd.write(out_fd, il) fd.close(out_fd) print("wrote " + ssa_path + " (" + text(length(il)) + " bytes)") // Step 3: compile QBE IL to assembly print("qbe compile...") rc = os.system("qbe -o " + s_path + " " + ssa_path) if (rc != 0) { print("qbe compilation failed") disrupt } // Step 4: assemble print("assemble...") rc = os.system("cc -c " + s_path + " -o " + o_path) if (rc != 0) { print("assembly failed") disrupt } // Step 5: compile runtime stubs if (!fd.is_file(rt_o_path)) { print("compile runtime stubs...") rc = os.system("cc -c source/qbe_helpers.c -o " + rt_o_path + " -fPIC -Isource") if (rc != 0) { print("runtime stubs compilation failed") disrupt } } // Step 6: link dylib print("link...") rc = os.system("cc -shared -fPIC -undefined dynamic_lookup " + o_path + " " + rt_o_path + " -o " + dylib_path) if (rc != 0) { print("linking failed") disrupt } print("built: " + dylib_path)