2024-02-04 12:23:59 -08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <gc.h>
|
|
|
|
#include <gc/cord.h>
|
2024-02-07 21:52:18 -08:00
|
|
|
#include <printf.h>
|
2024-02-04 12:23:59 -08:00
|
|
|
|
|
|
|
#include "ast.h"
|
|
|
|
#include "parse.h"
|
|
|
|
#include "compile.h"
|
2024-02-17 17:07:04 -08:00
|
|
|
#include "typecheck.h"
|
2024-02-07 21:52:18 -08:00
|
|
|
#include "types.h"
|
2024-02-04 12:23:59 -08:00
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
if (argc < 2) return 1;
|
|
|
|
|
2024-02-07 21:52:18 -08:00
|
|
|
// register_printf_modifier(L"p");
|
|
|
|
if (register_printf_specifier('T', printf_type, printf_pointer_size))
|
|
|
|
errx(1, "Couldn't set printf specifier");
|
|
|
|
if (register_printf_specifier('W', printf_ast, printf_pointer_size))
|
|
|
|
errx(1, "Couldn't set printf specifier");
|
|
|
|
|
2024-02-04 15:04:41 -08:00
|
|
|
const char *autofmt = getenv("AUTOFMT");
|
2024-02-13 20:03:58 -08:00
|
|
|
if (!autofmt) autofmt = "indent -kr -l100 -nbbo -nut -sob";
|
2024-02-04 15:04:41 -08:00
|
|
|
|
2024-02-11 16:06:42 -08:00
|
|
|
file_t *f = load_file(argv[1]);
|
2024-02-04 15:04:41 -08:00
|
|
|
|
2024-02-04 12:23:59 -08:00
|
|
|
ast_t *ast = parse_file(f, NULL);
|
2024-02-04 15:04:41 -08:00
|
|
|
|
|
|
|
if (!ast)
|
|
|
|
errx(1, "Could not compile!");
|
|
|
|
|
2024-02-11 11:02:00 -08:00
|
|
|
bool verbose = (getenv("VERBOSE") && strcmp(getenv("VERBOSE"), "1") == 0);
|
|
|
|
if (verbose) {
|
2024-02-11 23:10:45 -08:00
|
|
|
FILE *out = popen(heap_strf("bat -P --file-name='%s'", argv[1]), "w");
|
2024-02-10 12:36:35 -08:00
|
|
|
fputs(f->text, out);
|
|
|
|
fclose(out);
|
|
|
|
}
|
|
|
|
|
2024-02-11 11:02:00 -08:00
|
|
|
if (verbose) {
|
2024-02-11 23:10:45 -08:00
|
|
|
FILE *out = popen("bat -P --file-name=AST", "w");
|
2024-02-04 15:04:41 -08:00
|
|
|
fputs(ast_to_str(ast), out);
|
|
|
|
fclose(out);
|
|
|
|
}
|
|
|
|
|
2024-02-17 13:56:19 -08:00
|
|
|
env_t *env = new_compilation_unit();
|
2024-02-04 18:13:50 -08:00
|
|
|
|
2024-02-17 13:56:19 -08:00
|
|
|
CORD_appendf(&env->code->imports, "#include \"nextlang.h\"\n");
|
2024-02-04 15:04:41 -08:00
|
|
|
|
|
|
|
// Main body:
|
2024-02-13 19:58:50 -08:00
|
|
|
for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) {
|
2024-02-15 10:43:46 -08:00
|
|
|
CORD code = compile_statement(env, stmt->ast);
|
2024-02-13 19:58:50 -08:00
|
|
|
if (code)
|
2024-02-17 13:56:19 -08:00
|
|
|
CORD_appendf(&env->code->main, "%r\n", code);
|
2024-02-17 17:07:04 -08:00
|
|
|
bind_statement(env, stmt->ast);
|
2024-02-13 19:58:50 -08:00
|
|
|
}
|
2024-02-13 11:42:33 -08:00
|
|
|
|
2024-02-17 11:53:10 -08:00
|
|
|
CORD fileinfo = CORD_asprintf("#line 0 \"%s\"\n", f->filename);
|
|
|
|
CORD program = CORD_all(
|
|
|
|
fileinfo,
|
|
|
|
"// Generated code:\n",
|
2024-02-17 13:56:19 -08:00
|
|
|
env->code->imports, "\n",
|
|
|
|
env->code->typedefs, "\n",
|
|
|
|
env->code->typecode, "\n",
|
|
|
|
env->code->staticdefs, "\n",
|
2024-02-17 18:04:35 -08:00
|
|
|
env->code->funcs, "\n",
|
|
|
|
env->code->typeinfos, "\n",
|
2024-02-13 11:42:33 -08:00
|
|
|
"\n"
|
2024-02-17 11:53:10 -08:00
|
|
|
"static void $load(void) {\n",
|
2024-02-17 13:56:19 -08:00
|
|
|
env->code->main,
|
2024-02-13 11:42:33 -08:00
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"int main(int argc, const char *argv[]) {\n"
|
|
|
|
"(void)argc;\n"
|
|
|
|
"(void)argv;\n"
|
|
|
|
"GC_INIT();\n"
|
2024-02-17 16:52:37 -08:00
|
|
|
"detect_color();\n"
|
2024-02-14 10:28:28 -08:00
|
|
|
"$load();\n"
|
2024-02-13 11:42:33 -08:00
|
|
|
"return 0;\n"
|
2024-02-17 11:53:10 -08:00
|
|
|
"}\n"
|
|
|
|
);
|
2024-02-04 15:04:41 -08:00
|
|
|
|
2024-02-11 11:02:00 -08:00
|
|
|
if (verbose) {
|
2024-02-11 23:10:45 -08:00
|
|
|
FILE *out = popen(heap_strf("%s | bat -P --file-name=program.c", autofmt), "w");
|
2024-02-11 11:07:49 -08:00
|
|
|
CORD_put(program, out);
|
2024-02-04 15:04:41 -08:00
|
|
|
fclose(out);
|
|
|
|
}
|
|
|
|
|
2024-02-11 19:12:21 -08:00
|
|
|
const char *cflags = getenv("CFLAGS");
|
|
|
|
if (!cflags)
|
2024-02-14 10:28:28 -08:00
|
|
|
cflags = "-std=c11 -fdollars-in-identifiers -fsanitize=signed-integer-overflow -fno-sanitize-recover";
|
2024-02-11 19:12:21 -08:00
|
|
|
|
2024-02-11 21:18:55 -08:00
|
|
|
const char *ldlibs = "-lgc -lcord -lm -L. -lnext";
|
2024-02-11 19:12:21 -08:00
|
|
|
if (getenv("LDLIBS"))
|
|
|
|
ldlibs = heap_strf("%s %s", ldlibs, getenv("LDLIBS"));
|
|
|
|
|
2024-02-13 22:24:04 -08:00
|
|
|
const char *ldflags = "-Wl,-rpath '-Wl,$ORIGIN'";
|
|
|
|
|
2024-02-17 16:32:30 -08:00
|
|
|
// const char *run = heap_strf("tcc -run %s %s %s -", cflags, ldflags, ldlibs);
|
|
|
|
const char *run = heap_strf("gcc -x c %s %s %s - -o program && ./program", cflags, ldflags, ldlibs);
|
2024-02-04 15:04:41 -08:00
|
|
|
FILE *cc = popen(run, "w");
|
2024-02-11 11:07:49 -08:00
|
|
|
CORD_put(program, cc);
|
2024-02-04 15:04:41 -08:00
|
|
|
fclose(cc);
|
|
|
|
|
2024-02-04 12:23:59 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|