/* * w6c — amd64 compiler driver. Reads a .ww source file, runs the * libwcc frontend (lex → parse → check), then walks the typed AST * via cgen.c and writes Plan 9-flavoured amd64 asm to stdout (or * the file given by -o). */ #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; 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 (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 [-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); check_file(&c, file); if (c.errs) return 1; 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_file(&cg, of, file); if (of != stdout) fclose(of); freearena(a); free(buf); return 0; }