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;
}
|