diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-02-04 18:04:41 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-02-04 18:04:41 -0500 |
| commit | b08a0d3e2bf45bae11c982dd24d0292d6436b993 (patch) | |
| tree | 05c6a455f1cf159109fdd17520f9d772a0bbfe7a /nextlang.c | |
| parent | 98f0c51119f9d42d733f44cb516b1c2bcd9061af (diff) | |
Updates and functionality
Diffstat (limited to 'nextlang.c')
| -rw-r--r-- | nextlang.c | 79 |
1 files changed, 75 insertions, 4 deletions
@@ -11,12 +11,83 @@ int main(int argc, char *argv[]) { if (argc < 2) return 1; + const char *autofmt = getenv("AUTOFMT"); + if (!autofmt) autofmt = "indent -kr -nut | bat --file-name=out.c"; + + setenv("SSSPATH", ".", 0); + sss_file_t *f = sss_load_file(argv[1]); + ast_t *ast = parse_file(f, NULL); - const char *s = ast_to_str(ast); - puts(s); - CORD c = compile(ast); - CORD_put(c, stdout); + + if (!ast) + errx(1, "Could not compile!"); + + if (getenv("VERBOSE")) { + FILE *out = popen("bat --file-name=AST", "w"); + fputs(ast_to_str(ast), out); + fclose(out); + } + + // Predeclare funcs: + CORD code = "#include \"nextlang.h\"\n\n"; + for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { + switch (stmt->ast->tag) { + case FunctionDef: { + auto fndef = Match(stmt->ast, FunctionDef); + CORD_sprintf(&code, "%rstatic %r %r(", code, fndef->ret_type ? compile_type(fndef->ret_type) : "void", compile(fndef->name)); + for (arg_list_t *arg = fndef->args; arg; arg = arg->next) { + CORD_sprintf(&code, "%r%r %s", code, compile_type(arg->type), arg->var.name); + if (arg->next) code = CORD_cat(code, ", "); + } + code = CORD_cat(code, ");\n"); + break; + } + default: break; + } + } + + // Declare funcs: + for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { + switch (stmt->ast->tag) { + case FunctionDef: { + CORD_sprintf(&code, "%r\n\n%r", code, compile(stmt->ast)); + break; + } + default: break; + } + } + + // Main body: + code = CORD_cat(code, "\n\nint main(int argc, const char *argv[]) {\n" + "(void)argc;\n" + "(void)argv;\n" + "GC_INIT();\n\n"); + for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { + switch (stmt->ast->tag) { + case FunctionDef: break; + default: { + code = CORD_cat(code, compile(stmt->ast)); + code = CORD_cat(code, ";\n"); + break; + } + } + } + code = CORD_cat(code, "\nreturn 0;\n}\n"); + + if (getenv("VERBOSE")) { + FILE *out = popen(autofmt, "w"); + CORD_put(code, out); + fclose(out); + } + + const char *flags = getenv("CFLAGS"); + if (!flags) flags = "-std=c11 -lm -lgc -lcord"; + const char *run = heap_strf(getenv("VERBOSE") ? "tcc %s -run - | bat --file-name=output.txt" : "tcc %s -run -", flags); + FILE *cc = popen(run, "w"); + CORD_put(code, cc); + fclose(cc); + return 0; } |
