aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytecode/main.c')
-rw-r--r--src/bytecode/main.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/src/bytecode/main.c b/src/bytecode/main.c
new file mode 100644
index 0000000..78fdfd3
--- /dev/null
+++ b/src/bytecode/main.c
@@ -0,0 +1,197 @@
1#include <assert.h>
2#include <getopt.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#include "types.h"
8#include "darray.h"
9#include "ops.h"
10#include "debug.h"
11#include "errors.c"
12#include "lexer.c"
13#include "read_line.c"
14#include "string_view.c"
15
16void
17init(void) {
18 // STUB
19}
20
21void
22process_source(const StringView *source) {
23 Token *tokens = tokenize(source);
24 if (errors_n != 0) {
25 array_free(tokens);
26 return;
27 }
28
29 // Test chunks and debugging utilities.
30 u8 *chunk = NULL;
31 array_init(chunk, 0);
32 array_push(chunk, OP_RETURN);
33 array_push(chunk, OP_RETURN);
34 array_push(chunk, OP_RETURN);
35 array_push(chunk, OP_RETURN);
36 disassemble_chunk(chunk, "test chunk");
37
38 array_free(chunk);
39 array_free(tokens);
40}
41
42#define REPL_PROMPT "bdl> "
43
44void
45run_repl(void) {
46 printf("BDL REPL (Press Ctrl-D or Ctrl-C to exit)\n");
47 while (true) {
48 printf(REPL_PROMPT);
49 StringView sv = read_line();
50 if (sv.start == NULL) {
51 return;
52 }
53 process_source(&sv);
54
55 // Check if there were any errors.
56 if (errors_n != 0 && !supress_errors) {
57 for (size_t i = 0; i < errors_n; i++) {
58 Error err = errors[i];
59 for (size_t j = 0; j < err.col + sizeof(REPL_PROMPT) - 2; j++) {
60 putchar(' ');
61 }
62 printf("|\n");
63 for (size_t j = 0; j < err.col + sizeof(REPL_PROMPT) - 2; j++) {
64 putchar(' ');
65 }
66 printf("%s\n", error_msgs[err.value]);
67 }
68 errors_n = 0;
69 continue;
70 }
71 }
72}
73
74void
75run_file(char *file_name) {
76 FILE *file = fopen(file_name, "r");
77 if (!file) {
78 fprintf(stderr, "error: couldn't open input file: %s\n", file_name);
79 exit(EXIT_FAILURE);
80 }
81
82 // Read entire file into memory.
83 fseek(file, 0, SEEK_END);
84 size_t file_size = ftell(file);
85 fseek(file, 0, SEEK_SET);
86
87 char *source = malloc(file_size + 1);
88 fread(source, 1, file_size, file);
89 source[file_size] = 0;
90
91 StringView sv = (StringView){
92 .start = source,
93 .n = file_size,
94 };
95
96 process_source(&sv);
97
98 // Check if there were any errors.
99 if (errors_n != 0 && !supress_errors) {
100 for (size_t i = 0; i < errors_n; i++) {
101 Error err = errors[i];
102 fprintf(stderr, "%s", file_name);
103 if (err.line != 0) {
104 fprintf(stderr, ":%ld:%ld", err.line, err.col);
105 }
106 fprintf(stderr, ": %s\n", error_msgs[err.value]);
107 }
108 errors_n = 0;
109 }
110
111 free(source);
112 fclose(file);
113}
114
115#define STDIN_BUF_CAP 16
116
117void
118run_stdin(void) {
119 size_t buf_size = 0;
120 char *source = NULL;
121 array_init(source, STDIN_BUF_CAP);
122
123 char c;
124 while ((c = getchar()) != EOF) {
125 array_push(source, c);
126 buf_size++;
127 }
128
129 StringView sv = (StringView){
130 .start = source,
131 .n = buf_size,
132 };
133
134 process_source(&sv);
135
136 // Check if there were any errors.
137 if (errors_n != 0 && !supress_errors) {
138 for (size_t i = 0; i < errors_n; i++) {
139 Error err = errors[i];
140 fprintf(stderr, "stdin");
141 if (err.line != 0) {
142 fprintf(stderr, ":%ld:%ld", err.line, err.col);
143 }
144 fprintf(stderr, ": %s\n", error_msgs[err.value]);
145 }
146 errors_n = 0;
147 }
148
149 array_free(source);
150}
151
152#ifndef BIN_NAME
153#define BIN_NAME "bdl"
154#endif
155
156void
157print_usage(void) {
158 printf("Usage: %s [options] <filename filename ...>\n", BIN_NAME);
159 printf("\n");
160 printf("\t-i\tInteractive mode (REPL).\n");
161 printf("\n");
162}
163
164int
165main(int argc, char *argv[]) {
166 init();
167
168 int option;
169 while ((option = getopt(argc, argv, "i")) != -1) {
170 switch (option) {
171 case 'i': {
172 // Interactive mode.
173 run_repl();
174 return EXIT_SUCCESS;
175 } break;
176 default: {
177 print_usage();
178 return EXIT_FAILURE;
179 } break;
180 }
181 }
182
183 // Run from stdin.
184 if (optind == argc) {
185 run_stdin();
186 return EXIT_SUCCESS;
187 }
188
189 // Run from file.
190 while (optind < argc) {
191 char *file_name = argv[optind];
192 run_file(file_name);
193 optind++;
194 }
195
196 return EXIT_SUCCESS;
197}