aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-12 10:53:20 +0200
committerBad Diode <bd@badd10de.dev>2021-10-12 10:53:20 +0200
commit3444b5b58a78c12a79365bb35e54cfa029fccd99 (patch)
treea9d86a93666b317d60183b9f7f8b2680628b6fe6
parent2627e81de26667b7bc9d88304473e2a234fee7fe (diff)
downloadbdl-3444b5b58a78c12a79365bb35e54cfa029fccd99.tar.gz
bdl-3444b5b58a78c12a79365bb35e54cfa029fccd99.zip
Add error dispatch procedurev0.2
-rw-r--r--src/bootstrap/errors.c33
-rw-r--r--src/bootstrap/lexer.c52
-rwxr-xr-xsrc/bootstrap/main.c55
3 files changed, 116 insertions, 24 deletions
diff --git a/src/bootstrap/errors.c b/src/bootstrap/errors.c
new file mode 100644
index 0000000..fcb629a
--- /dev/null
+++ b/src/bootstrap/errors.c
@@ -0,0 +1,33 @@
1typedef enum ErrorType {
2 ERR_TYPE_LEXER,
3 ERR_TYPE_PARSER,
4 ERR_TYPE_RUNTIME,
5} ErrorType;
6
7typedef enum ErrorValue {
8 ERR_UNKNOWN = 0,
9 ERR_UNMATCHED_STRING,
10} ErrorValue;
11
12typedef struct Error {
13 ErrorType type;
14 ErrorValue value;
15 size_t line;
16 size_t col;
17} Error;
18
19static const char* error_msgs[] = {
20 [ERR_UNKNOWN] = "error: something unexpected happened",
21 [ERR_UNMATCHED_STRING] = "error: unmatched string delimiter",
22};
23
24#define ERR_MAX_NUMBER 16
25static Error errors[ERR_MAX_NUMBER];
26static size_t errors_n = 0;
27
28void
29error_push(Error error) {
30 if (errors_n < ERR_MAX_NUMBER) {
31 errors[errors_n++] = error;
32 }
33}
diff --git a/src/bootstrap/lexer.c b/src/bootstrap/lexer.c
index 1add4dc..49431d0 100644
--- a/src/bootstrap/lexer.c
+++ b/src/bootstrap/lexer.c
@@ -134,6 +134,28 @@ skip_whitespace(Scanner *scanner) {
134 } 134 }
135} 135}
136 136
137bool
138is_delimiter(char c) {
139 switch (c) {
140 case EOF:
141 case '\0':
142 case ';':
143 case '"':
144 case '\'':
145 case '(':
146 case ')':
147 case ' ':
148 case '\f':
149 case '\n':
150 case '\r':
151 case '\t':
152 case '\v': {
153 return true;
154 } break;
155 }
156 return false;
157}
158
137TokenType 159TokenType
138find_primitive_type(StringView value) { 160find_primitive_type(StringView value) {
139 bool is_fixnum = true; 161 bool is_fixnum = true;
@@ -159,28 +181,6 @@ find_primitive_type(StringView value) {
159 return TOKEN_SYMBOL; 181 return TOKEN_SYMBOL;
160} 182}
161 183
162bool
163is_delimiter(char c) {
164 switch (c) {
165 case EOF:
166 case '\0':
167 case ';':
168 case '"':
169 case '\'':
170 case '(':
171 case ')':
172 case ' ':
173 case '\f':
174 case '\n':
175 case '\r':
176 case '\t':
177 case '\v': {
178 return true;
179 } break;
180 }
181 return false;
182}
183
184Tokens 184Tokens
185tokenize(const StringView *sv) { 185tokenize(const StringView *sv) {
186 Tokens tokens = (Tokens){0}; 186 Tokens tokens = (Tokens){0};
@@ -214,7 +214,13 @@ tokenize(const StringView *sv) {
214 n++; 214 n++;
215 } 215 }
216 if (!found) { 216 if (!found) {
217 // TODO: Report error: couldn't find the closing quotes. 217 error_push((Error){
218 .type = ERR_TYPE_LEXER,
219 .value = ERR_UNMATCHED_STRING,
220 .line = line,
221 .col = col,
222 });
223 return tokens;
218 } 224 }
219 Token token = (Token){ 225 Token token = (Token){
220 .value = (StringView){ 226 .value = (StringView){
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c
index 113ee48..dadc887 100755
--- a/src/bootstrap/main.c
+++ b/src/bootstrap/main.c
@@ -5,11 +5,18 @@
5 5
6#include "string_view.c" 6#include "string_view.c"
7#include "read_line.c" 7#include "read_line.c"
8#include "errors.c"
8#include "lexer.c" 9#include "lexer.c"
9 10
10void 11void
11process_source(const StringView *source) { 12process_source(const StringView *source) {
12 Tokens tokens = tokenize(source); 13 Tokens tokens = tokenize(source);
14 if (errors_n != 0) {
15 if (tokens.buf != NULL) {
16 free(tokens.buf);
17 }
18 return;
19 }
13 20
14 // Print tokens. 21 // Print tokens.
15 for (size_t i = 0; i < tokens.size; i++) { 22 for (size_t i = 0; i < tokens.size; i++) {
@@ -17,7 +24,9 @@ process_source(const StringView *source) {
17 print_token(tok); 24 print_token(tok);
18 } 25 }
19 26
20 free(tokens.buf); 27 if (tokens.buf != NULL) {
28 free(tokens.buf);
29 }
21} 30}
22 31
23#define REPL_PROMPT "bdl> " 32#define REPL_PROMPT "bdl> "
@@ -32,6 +41,24 @@ run_repl(void) {
32 return; 41 return;
33 } 42 }
34 process_source(&sv); 43 process_source(&sv);
44
45 // Check if there were any errors.
46 if (errors_n != 0) {
47 for (size_t i = 0; i < errors_n; i++) {
48 Error err = errors[i];
49 for (size_t j = 0; j < err.col + sizeof(REPL_PROMPT) - 2; j++) {
50 putchar(' ');
51 }
52 printf("|\n");
53 for (size_t j = 0; j < err.col + sizeof(REPL_PROMPT) - 2; j++) {
54 putchar(' ');
55 }
56 printf("%s\n", error_msgs[err.value]);
57 }
58 errors_n = 0;
59 continue;
60 }
61
35 if (sv.n != 0) { 62 if (sv.n != 0) {
36 printf("\n"); 63 printf("\n");
37 } 64 }
@@ -62,6 +89,19 @@ run_file(char *file_name) {
62 89
63 process_source(&sv); 90 process_source(&sv);
64 91
92 // Check if there were any errors.
93 if (errors_n != 0) {
94 for (size_t i = 0; i < errors_n; i++) {
95 Error err = errors[i];
96 printf("%s", file_name);
97 if (err.line != 0) {
98 printf(":%ld:%ld", err.line, err.col);
99 }
100 printf("%s\n", error_msgs[err.value]);
101 }
102 errors_n = 0;
103 }
104
65 free(source); 105 free(source);
66 fclose(file); 106 fclose(file);
67} 107}
@@ -91,6 +131,19 @@ run_stdin(void) {
91 131
92 process_source(&sv); 132 process_source(&sv);
93 133
134 // Check if there were any errors.
135 if (errors_n != 0) {
136 for (size_t i = 0; i < errors_n; i++) {
137 Error err = errors[i];
138 printf("stdin");
139 if (err.line != 0) {
140 printf(":%ld:%ld: ", err.line, err.col);
141 }
142 printf("%s\n", error_msgs[err.value]);
143 }
144 errors_n = 0;
145 }
146
94 free(source); 147 free(source);
95} 148}
96 149