#include #include #include #include #include #include #include "types.h" #include "token.h" #include "lex.h" #define assert(c) while (!(c)) __builtin_unreachable() static void usage(void) { printf("lc [--lex|---parse|--validate|--codegen] [-c] \n"); } /* The different stages */ enum stage { Snone, Slex, Sparse, Svalidate, Scodegen, Semit, }; static char *stagename[Semit+1] = { [Slex] = "lex", [Sparse] = "parse", [Svalidate] = "validate", [Scodegen] = "codegen", [Semit] = "emit", }; /* options */ static char *infname = 0; static enum stage stage = Snone; static bool obj = false; static bool parseargs(usize argc, char *argv[]) { char *arg; usize len; for (usize i = 0; i < argc; i++) { arg = argv[i]; len = strlen(arg); if (arg[0] == '-') { if (len < 2) { fprintf(stderr, "error: not an option: -\n"); return false; } if (len == 2 && arg[1] == 'c') { obj = true; continue; } if (arg[1] != '-') { fprintf(stderr, "error: unrecognised option: %s\n", arg); return false; } /* we've seen --, check for options */ enum stage newstage = Snone; if (!strncmp(&arg[2], "lex", len-2)) { newstage = Slex; } else if (!strncmp(&arg[2], "parse", len-2)) { newstage = Sparse; } else if (!strncmp(&arg[2], "validate", len-2)) { newstage = Svalidate; } else if (!strncmp(&arg[2], "codegen", len-2)) { newstage = Svalidate; } else if (!strncmp(&arg[2], "emit", len-2)) { newstage = Svalidate; } if (newstage) { if (stage) { fprintf(stderr, "error: conflicting options: --%s and --%s cannot be specified at the same time\n", stagename[stage], stagename[newstage]); return false; } stage = newstage; continue; } fprintf(stderr, "error: unrecognised option: %s\n", arg); return false; } if (infname) { fprintf(stderr, "warning: multiple input files are not yet implemented. Ignoring %s\n", arg); continue; } infname = arg; } if (!infname) { fprintf(stderr, "error: no input file provided\n"); return false; } if (stage == Snone) stage = Semit; return true; } int main(int argc, char *argv[]) { /* parse arguments */ if (argc < 2) { usage(); exit(EXIT_SUCCESS); } argc--; argv++; if (!parseargs((usize)argc, argv)) { usage(); exit(EXIT_FAILURE); } printf("stage = %s\n", stagename[stage]); printf("input = %s\n", infname); struct lexstate lexer; lexreset(&lexer); u8 code[] = " \n\n int\nmain(void)\n{\n\treturn 2;\n}\n"; lexfeed(&lexer, sizeof(code)-1, code); lex(&lexer); /* call preprocessor */ /* call main compiler */ /* call assembler */ }