aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
blob: 30eab2b6b0596f1231b96fe7b8e7cf75165f9b21 (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>

#include "common.h"
#include "darray.h"
#include "string_view.c"
#include "errors.c"
#include "lexer.c"
#include "parser.c"
#include "ir.h"
// #include "compiler.h"

void
init(void) {
    // STUB
}

void
halt(void) {
    // STUB
}

void
process_source(const StringView *source, const char *file_name) {
    Errors errors = {0};

    // Read tokens.
    Token *tokens = tokenize(source, &errors);
    if (errors.n != 0) {
        report_errors(&errors, file_name);
        array_free(tokens);
        exit(EXIT_FAILURE);
    }

    // Parser.
    Program program = parse(tokens, &errors);
    if (errors.n != 0) {
        report_errors(&errors, file_name);
        free_objects();
        array_free(tokens);
        exit(EXIT_FAILURE);
    }
    array_free(tokens);

    // TODO: Optimization.

    // Compilation.
    ProgramIr program_ir = compile(program);
    (void)program_ir;

    // Free resources.
    free_objects();
}

void
run_file(char *file_name) {
    FILE *file = fopen(file_name, "r");
    if (!file) {
        fprintf(stderr, "error: couldn't open input file: %s\n", file_name);
        exit(EXIT_FAILURE);
    }

    // Read entire file into memory.
    fseek(file, 0, SEEK_END);
    size_t file_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    char *source = malloc(file_size + 1);
    fread(source, 1, file_size, file);
    source[file_size] = 0;

    StringView sv = (StringView){
        .start = source,
        .n = file_size,
    };

    process_source(&sv, file_name);

    free(source);
    fclose(file);
}

#define STDIN_BUF_CAP 16

void
run_stdin(void) {
    size_t buf_size = 0;
    char *source = NULL;
    array_init(source, STDIN_BUF_CAP);

    char c;
    while ((c = getchar()) != EOF) {
        array_push(source, c);
        buf_size++;
    }

    StringView sv = (StringView){
        .start = source,
        .n = buf_size,
    };

    process_source(&sv, "stdin");

    array_free(source);
}

#ifndef BIN_NAME
#define BIN_NAME "bdl"
#endif

void
print_usage(void) {
    printf("Usage: %s [options] <filename filename ...>\n", BIN_NAME);
    printf("\n");
    printf("\t-h \tShow usage.\n");
    printf("\n");
}

int
main(int argc, char *argv[]) {
    init();

    int option;
    while ((option = getopt(argc, argv, "h")) != -1) {
        switch (option) {
            case 'h': {
                print_usage();
                goto exit_success;
            } break;
            default: {
                print_usage();
                return EXIT_FAILURE;
            } break;
        }
    }

    // Run from stdin.
    if (optind == argc) {
        run_stdin();
        goto exit_success;
    }

    // Run from file.
    while (optind < argc) {
        char *file_name = argv[optind];
        run_file(file_name);
        optind++;
    }

exit_success:
    halt();
    return EXIT_SUCCESS;
}