/* splc0.c — Stage 1 SPL compiler (bootstrap) * Usage: * splc0 — compile * splc0 --dump-tokens — dump tokens * splc0 --help — help */ #include "../stage0/spl_ir.h" #include "spl_comp.h" #include #include #include static char *read_file(const char *path, long *out_len) { FILE *f = fopen(path, "rb"); if (!f) { perror("fopen"); return NULL; } fseek(f, 0, SEEK_END); long len = ftell(f); fseek(f, 0, SEEK_SET); char *buf = malloc((size_t)len + 1); if (!buf) { fclose(f); return NULL; } fread(buf, 1, (size_t)len, f); fclose(f); buf[len] = '\0'; *out_len = len; return buf; } static int cmd_dump_tokens(int argc, char **argv) { if (argc < 1) { fprintf(stderr, "Usage: splc0 --dump-tokens \n"); return 1; } long len; char *src = read_file(argv[0], &len); if (!src) return 1; spl_tok_vec_t toks = spl_lex(src, argv[0]); spl_tok_vec_dump(&toks); spl_tok_vec_drop(&toks); free(src); return 0; } static int cmd_compile(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "Usage: splc0 \n"); return 1; } const char *inpath = argv[0]; const char *outpath = argv[1]; long len; char *src = read_file(inpath, &len); if (!src) return 1; spl_comp_t ctx; spl_comp_init(&ctx); int ret = 0; if (spl_compile(&ctx, src, inpath) != 0) { fprintf(stderr, "compilation failed: %s\n", ctx.error_msg); ret = 1; goto cleanup; } if (spl_prog_store_to_file(outpath, &ctx.prog) != 0) { fprintf(stderr, "failed to write '%s'\n", outpath); ret = 1; goto cleanup; } printf("compiled %s -> %s\n", inpath, outpath); cleanup: spl_comp_drop(&ctx); free(src); return ret; } int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "Usage: splc0 [--dump-tokens|--help] [output.sir]\n"); return 1; } if (strcmp(argv[1], "--dump-tokens") == 0) { return cmd_dump_tokens(argc - 2, argv + 2); } if (strcmp(argv[1], "--help") == 0) { printf("SPL Compiler (stage1 bootstrap)\n"); printf(" splc0 - compile\n"); printf(" splc0 --dump-tokens - dump token stream\n"); return 0; } return cmd_compile(argc - 1, argv + 1); }