#include "gc.h" #include #include #include static int slurp(const char *path, char **outbuf, u64 *outlen) { FILE *f = fopen(path, "rb"); if (f == NULL) return -1; fseek(f, 0, SEEK_END); long n = ftell(f); fseek(f, 0, SEEK_SET); if (n < 0) { fclose(f); return -1; } char *b = malloc((size_t)n + 1); if (b == NULL) { fclose(f); return -1; } if (fread(b, 1, (size_t)n, f) != (size_t)n) { free(b); fclose(f); return -1; } b[n] = '\0'; fclose(f); *outbuf = b; *outlen = (u64)n; return 0; } int main(int argc, char **argv) { const char *src = NULL; const char *out = NULL; const char *wwiout = NULL; /* -I : M2 export-data producer */ int testmode = 0; int sepmode = 0; /* -c: #22 M3 separate-compile / primary- * only codegen (emit imported==0 decls * only; treat `.wwi` deps as external) */ for (int i = 1; i < argc; i++) { const char *a = argv[i]; if (strcmp(a, "-o") == 0 && i + 1 < argc) { out = argv[++i]; } else if (strcmp(a, "-I") == 0 && i + 1 < argc) { wwiout = argv[++i]; } else if (strcmp(a, "-T") == 0) { testmode = 1; } else if (strcmp(a, "-c") == 0) { sepmode = 1; } else if (a[0] == '-') { fprintf(stderr, "w6c: unknown flag %s\n", a); return 2; } else if (src == NULL) { src = a; } else { fprintf(stderr, "w6c: only one input supported\n"); return 2; } } if (src == NULL) { fputs("usage: w6c [-T] [-c] [-I out.wwi] [-o out.s] file.ww\n", stderr); return 2; } char *buf; u64 len; if (slurp(src, &buf, &len) < 0) { fprintf(stderr, "w6c: %s: cannot read\n", src); return 1; } Arena *a = newarena(); Lex l; Parser p; Checker c; Cg cg; lexinit(&l, a, src, buf, len); parserinit(&p, a, &l); Node *file = parsefile(&p); if (l.errs || p.errs) return 1; check_init(&c, a); c.is_test = testmode; c.sep_mode = sepmode; check_file(&c, file); if (c.errs) return 1; /* M2 export-data: write the `.wwi` after a clean check, before cgen. * Dead on the live path (no existing invocation passes -I); the * producer's check_exported_type may reject a dangling export. */ if (wwiout) { FILE *wf = fopen(wwiout, "wb"); if (wf == NULL) { fprintf(stderr, "w6c: cannot open %s\n", wwiout); return 1; } if (wwi_emit(&c, wf, file) != 0) { fclose(wf); return 1; } fclose(wf); } FILE *of = stdout; if (out) { of = fopen(out, "wb"); if (of == NULL) { fprintf(stderr, "w6c: cannot open %s\n", out); return 1; } } cg_init(&cg, a); cg.sep_mode = sepmode; /* #99: wwiout != NULL <=> this is a sep DEP unit (the producer passes * -I to deps only; the root's .wwi is stripped per #69). Gates the * bare-`main` carve-out so only the root/link-entry main stays bare. */ cg.sep_isdep = (wwiout != NULL); cg_file(&cg, of, file); if (of != stdout) fclose(of); freearena(a); free(buf); return 0; }