aboutsummaryrefslogtreecommitdiff
path: root/nextlang.c
blob: 62a3feec20311f4a2664909b420d23500fcb1c36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <stdio.h>
#include <stdlib.h>
#include <gc.h>
#include <gc/cord.h>
#include <printf.h>

#include "ast.h"
#include "builtins/string.h"
#include "compile.h"
#include "parse.h"
#include "typecheck.h"
#include "types.h"

int main(int argc, char *argv[])
{
    if (argc < 2) return 1;

    // 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");

    const char *autofmt = getenv("AUTOFMT");
    if (!autofmt) autofmt = "indent -kr -l100 -nbbo -nut -sob";

    file_t *f = load_file(argv[1]);

    ast_t *ast = parse_file(f, NULL);

    if (!ast)
        errx(1, "Could not compile!");

    bool verbose = (getenv("VERBOSE") && strcmp(getenv("VERBOSE"), "1") == 0);
    if (verbose) {
        FILE *out = popen(heap_strf("bat -P --file-name='%s'", argv[1]), "w");
        fputs(f->text, out);
        fclose(out);
    }

    if (verbose) {
        FILE *out = popen("bat -P --file-name=AST", "w");
        fputs(ast_to_str(ast), out);
        fclose(out);
    }

    module_code_t module = compile_file(ast);

    CORD program = CORD_all(
        "// File: ", f->filename, ".h\n",
        module.header,
        "\n",
        "// File: ", f->filename, ".c\n",
        module.c_file,
        "\n",
        "int main(int argc, const char *argv[]) {\n"
        "(void)argc;\n"
        "(void)argv;\n"
        "GC_INIT();\n"
        "detect_color();\n"
        "$load();\n"
        "return 0;\n"
        "}\n"
    );
    
    if (verbose) {
        FILE *out = popen(heap_strf("%s | bat -P --file-name=program.c", autofmt), "w");
        CORD_put(program, out);
        fclose(out);
    }

    const char *cflags = getenv("CFLAGS");
    if (!cflags)
        cflags = "-std=c11 -fdollars-in-identifiers -fsanitize=signed-integer-overflow -fno-sanitize-recover";

    const char *ldlibs = "-lgc -lcord -lm -L. -lnext";
    if (getenv("LDLIBS"))
        ldlibs = heap_strf("%s %s", ldlibs, getenv("LDLIBS"));

    const char *ldflags = "-Wl,-rpath '-Wl,$ORIGIN'";

    // 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);
    FILE *cc = popen(run, "w");
    CORD_put(program, cc);
    fclose(cc);

    return 0;
}

// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0