aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
blob: 9848b8bf23c20dab9d1ddbdb3386a9a9a15893ea (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
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>

#include "badlib.h"
#include "lexer.c"

typedef enum ExecMode {
    RUN_NORMAL,
    PRINT_LEX,
    PRINT_PARSE,
    PRINT_SEMANTIC,
    PRINT_SYMTABLES,
} ExecMode;

static ExecMode mode = RUN_NORMAL;

void
init(void) {
    log_init_default();
}

void
process_file(Str path) {
    Arena lexer_arena = arena_create(LEXER_MEM, os_allocator);

    FileContents file = platform_read_file(path, &lexer_arena);
    if (file.err) {
        printf("file.err: %d\n", file.err);
        eprintln("%s: error: %s", path, cstr("WOT"));
        return;
    }

    Scanner scanner = {
        .str = file.data,
    };
    Token tok = {0};
    sz errors = 0;
    while (tok.type != TOK_EOF) {
        tok = scan_token(&scanner);
        if (tok.type == TOK_UNKNOWN) {
            eprintln("%s:%d:%d:%s %s", path, tok.line, tok.col,
                     token_str[tok.type], tok.val);
            errors++;
        }
    }

    // Only proceed if there are no errors.
    if (errors) {
        goto stop;
    }

stop:
    // Free up resources.
    arena_destroy(&lexer_arena, os_allocator);
}

#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 \t\tShow usage.\n");
    printf(
        "\t-p [l|p|s|t]\tPrint mode for [l]exing, [p]arsing, [s]emantic "
        "analysis, symbol [t]ables\n");
    printf("\n");
}

int
main(int argc, char *argv[]) {
    int option;
    while ((option = getopt(argc, argv, "hp:")) != -1) {
        switch (option) {
            case 'h': {
                print_usage();
                goto exit_success;
            } break;
            case 'p': {
                if (optarg[0] == 'l' && optarg[1] == '\0') {
                    mode = PRINT_LEX;
                } else if (optarg[0] == 'p' && optarg[1] == '\0') {
                    mode = PRINT_PARSE;
                } else if (optarg[0] == 's' && optarg[1] == '\0') {
                    mode = PRINT_SEMANTIC;
                } else if (optarg[0] == 't' && optarg[1] == '\0') {
                    mode = PRINT_SYMTABLES;
                } else {
                    print_usage();
                    return EXIT_FAILURE;
                }
            } break;
            default: {
                print_usage();
                return EXIT_FAILURE;
            } break;
        }
    }

    init();

    // Run from stdin.
    if (optind == argc) {
        // TODO: REPL
        // repl();
        goto exit_success;
    }

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

exit_success:
    return EXIT_SUCCESS;
}