aboutsummaryrefslogtreecommitdiff
path: root/nextlang.c
diff options
context:
space:
mode:
Diffstat (limited to 'nextlang.c')
-rw-r--r--nextlang.c79
1 files changed, 75 insertions, 4 deletions
diff --git a/nextlang.c b/nextlang.c
index 617adc98..333c4515 100644
--- a/nextlang.c
+++ b/nextlang.c
@@ -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;
}