diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-16 21:36:49 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-16 21:36:49 +0200 |
commit | bf4aa41a445986658f4ee931305d9caf496e9072 (patch) | |
tree | 3fbc53824ac50e24050420ef6aa541cc7ea84af3 /src/main.c | |
parent | b86d262b9fe27131d8163a6ba49957736691b1d0 (diff) | |
download | bdl-bf4aa41a445986658f4ee931305d9caf496e9072.tar.gz bdl-bf4aa41a445986658f4ee931305d9caf496e9072.zip |
Add parsing for logical operators
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 99 |
1 files changed, 87 insertions, 12 deletions
@@ -39,14 +39,28 @@ print_tokens(Str path, Token *tokens) { | |||
39 | // | 39 | // |
40 | 40 | ||
41 | typedef enum NodeKind { | 41 | typedef enum NodeKind { |
42 | NODE_NUM_INT, | 42 | // Arithmetic. |
43 | NODE_NUM_FLOAT, | ||
44 | // TODO: probably want to handle ints/unsigneds/floats separately. | ||
45 | NODE_ADD, | 43 | NODE_ADD, |
46 | NODE_SUB, | 44 | NODE_SUB, |
47 | NODE_DIV, | 45 | NODE_DIV, |
48 | NODE_MUL, | 46 | NODE_MUL, |
49 | NODE_MOD, | 47 | NODE_MOD, |
48 | // Logical. | ||
49 | NODE_NOT, | ||
50 | NODE_AND, | ||
51 | NODE_OR, | ||
52 | NODE_EQ, | ||
53 | NODE_NOTEQ, | ||
54 | NODE_LT, | ||
55 | NODE_GT, | ||
56 | NODE_LE, | ||
57 | NODE_GE, | ||
58 | // Literals. | ||
59 | NODE_NUM_INT, | ||
60 | NODE_NUM_FLOAT, | ||
61 | NODE_TRUE, | ||
62 | NODE_FALSE, | ||
63 | NODE_NIL, | ||
50 | } NodeKind; | 64 | } NodeKind; |
51 | 65 | ||
52 | Str node_str[] = { | 66 | Str node_str[] = { |
@@ -56,10 +70,22 @@ Str node_str[] = { | |||
56 | [NODE_DIV] = cstr("DIV"), | 70 | [NODE_DIV] = cstr("DIV"), |
57 | [NODE_MUL] = cstr("MUL"), | 71 | [NODE_MUL] = cstr("MUL"), |
58 | [NODE_MOD] = cstr("MOD"), | 72 | [NODE_MOD] = cstr("MOD"), |
59 | 73 | // Logical. | |
74 | [NODE_NOT] = cstr("NOT"), | ||
75 | [NODE_AND] = cstr("AND"), | ||
76 | [NODE_OR] = cstr("OR"), | ||
77 | [NODE_EQ] = cstr("EQ"), | ||
78 | [NODE_NOTEQ] = cstr("NOTEQ"), | ||
79 | [NODE_LT] = cstr("LT"), | ||
80 | [NODE_GT] = cstr("GT"), | ||
81 | [NODE_LE] = cstr("LE"), | ||
82 | [NODE_GE] = cstr("GE"), | ||
60 | // Literals. | 83 | // Literals. |
61 | [NODE_NUM_INT] = cstr("INT"), | 84 | [NODE_NUM_INT] = cstr("INT"), |
62 | [NODE_NUM_FLOAT] = cstr("FLOAT"), | 85 | [NODE_NUM_FLOAT] = cstr("FLOAT"), |
86 | [NODE_TRUE] = cstr("TRUE"), | ||
87 | [NODE_FALSE] = cstr("FALSE"), | ||
88 | [NODE_NIL] = cstr("NIL"), | ||
63 | }; | 89 | }; |
64 | 90 | ||
65 | typedef struct Node { | 91 | typedef struct Node { |
@@ -135,16 +161,32 @@ void parse_grouping(Parser *parser); | |||
135 | void parse_unary(Parser *parser); | 161 | void parse_unary(Parser *parser); |
136 | void parse_binary(Parser *parser); | 162 | void parse_binary(Parser *parser); |
137 | void parse_number(Parser *parser); | 163 | void parse_number(Parser *parser); |
164 | void parse_literal(Parser *parser); | ||
138 | 165 | ||
139 | ParseRule parse_rules[] = { | 166 | ParseRule parse_rules[] = { |
140 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, | 167 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, |
168 | // Arithmetic. | ||
141 | [TOK_SUB] = {parse_unary, parse_binary, PREC_TERM}, | 169 | [TOK_SUB] = {parse_unary, parse_binary, PREC_TERM}, |
142 | [TOK_ADD] = {NULL, parse_binary, PREC_TERM}, | 170 | [TOK_ADD] = {NULL, parse_binary, PREC_TERM}, |
143 | [TOK_DIV] = {NULL, parse_binary, PREC_FACTOR}, | 171 | [TOK_DIV] = {NULL, parse_binary, PREC_FACTOR}, |
144 | [TOK_MUL] = {NULL, parse_binary, PREC_FACTOR}, | 172 | [TOK_MUL] = {NULL, parse_binary, PREC_FACTOR}, |
145 | [TOK_MOD] = {NULL, parse_binary, PREC_FACTOR}, | 173 | [TOK_MOD] = {NULL, parse_binary, PREC_FACTOR}, |
174 | // Logical. | ||
175 | [TOK_NOT] = {parse_unary, NULL, PREC_NONE}, | ||
176 | [TOK_AND] = {NULL, parse_binary, PREC_AND}, | ||
177 | [TOK_OR] = {NULL, parse_binary, PREC_OR}, | ||
178 | [TOK_EQ] = {NULL, parse_binary, PREC_EQUALITY}, | ||
179 | [TOK_NOTEQ] = {NULL, parse_binary, PREC_EQUALITY}, | ||
180 | [TOK_LT] = {NULL, parse_binary, PREC_COMPARISON}, | ||
181 | [TOK_GT] = {NULL, parse_binary, PREC_COMPARISON}, | ||
182 | [TOK_LE] = {NULL, parse_binary, PREC_COMPARISON}, | ||
183 | [TOK_GE] = {NULL, parse_binary, PREC_COMPARISON}, | ||
184 | // Literals. | ||
146 | [TOK_NUM_INT] = {parse_number, NULL, PREC_NONE}, | 185 | [TOK_NUM_INT] = {parse_number, NULL, PREC_NONE}, |
147 | [TOK_NUM_FLOAT] = {parse_number, NULL, PREC_NONE}, | 186 | [TOK_NUM_FLOAT] = {parse_number, NULL, PREC_NONE}, |
187 | [TOK_TRUE] = {parse_literal, NULL, PREC_NONE}, | ||
188 | [TOK_FALSE] = {parse_literal, NULL, PREC_NONE}, | ||
189 | [TOK_NIL] = {parse_literal, NULL, PREC_NONE}, | ||
148 | [TOK_EOF] = {NULL, NULL, PREC_NONE}, | 190 | [TOK_EOF] = {NULL, NULL, PREC_NONE}, |
149 | }; | 191 | }; |
150 | 192 | ||
@@ -209,13 +251,37 @@ parse_unary(Parser *parser) { | |||
209 | print("parsing unary "); | 251 | print("parsing unary "); |
210 | print_token(prev); | 252 | print_token(prev); |
211 | #endif | 253 | #endif |
212 | TokenKind kind = prev.kind; | 254 | parse_expr(parser, PREC_UNARY); |
213 | parse_expr(parser, PREC_LOW); | 255 | Node *node = NULL; |
214 | // TODO: ... | 256 | switch (prev.kind) { |
215 | switch (kind) { | 257 | case TOK_NOT: node = node_alloc(NODE_NOT, prev, parser->storage); break; |
216 | // case TOKEN_MINUS: emitByte(OP_NEGATE); break; | 258 | default: break; // Unreachable. |
259 | } | ||
260 | node->left = array_pop(parser->nodes); | ||
261 | array_push(parser->nodes, node, parser->storage); | ||
262 | } | ||
263 | |||
264 | void | ||
265 | parse_literal(Parser *parser) { | ||
266 | Token prev = parser->previous; | ||
267 | #if DEBUG == 1 | ||
268 | print("parsing literal "); | ||
269 | print_token(prev); | ||
270 | #endif | ||
271 | Node *node = NULL; | ||
272 | switch (prev.kind) { | ||
273 | case TOK_TRUE: { | ||
274 | node = node_alloc(NODE_TRUE, prev, parser->storage); | ||
275 | } break; | ||
276 | case TOK_FALSE: { | ||
277 | node = node_alloc(NODE_FALSE, prev, parser->storage); | ||
278 | } break; | ||
279 | case TOK_NIL: { | ||
280 | node = node_alloc(NODE_NIL, prev, parser->storage); | ||
281 | } break; | ||
217 | default: return; // Unreachable. | 282 | default: return; // Unreachable. |
218 | } | 283 | } |
284 | array_push(parser->nodes, node, parser->storage); | ||
219 | } | 285 | } |
220 | 286 | ||
221 | void | 287 | void |
@@ -225,17 +291,26 @@ parse_binary(Parser *parser) { | |||
225 | print("parsing binary "); | 291 | print("parsing binary "); |
226 | print_token(prev); | 292 | print_token(prev); |
227 | #endif | 293 | #endif |
228 | TokenKind kind = prev.kind; | 294 | ParseRule rule = parse_rules[prev.kind]; |
229 | ParseRule rule = parse_rules[kind]; | ||
230 | parse_expr(parser, rule.precedence + 1); | 295 | parse_expr(parser, rule.precedence + 1); |
231 | 296 | ||
232 | Node *node; | 297 | Node *node; |
233 | switch (kind) { | 298 | switch (prev.kind) { |
234 | case TOK_ADD: node = node_alloc(NODE_ADD, prev, parser->storage); break; | 299 | case TOK_ADD: node = node_alloc(NODE_ADD, prev, parser->storage); break; |
235 | case TOK_SUB: node = node_alloc(NODE_SUB, prev, parser->storage); break; | 300 | case TOK_SUB: node = node_alloc(NODE_SUB, prev, parser->storage); break; |
236 | case TOK_MUL: node = node_alloc(NODE_MUL, prev, parser->storage); break; | 301 | case TOK_MUL: node = node_alloc(NODE_MUL, prev, parser->storage); break; |
237 | case TOK_DIV: node = node_alloc(NODE_DIV, prev, parser->storage); break; | 302 | case TOK_DIV: node = node_alloc(NODE_DIV, prev, parser->storage); break; |
238 | case TOK_MOD: node = node_alloc(NODE_MOD, prev, parser->storage); break; | 303 | case TOK_MOD: node = node_alloc(NODE_MOD, prev, parser->storage); break; |
304 | case TOK_AND: node = node_alloc(NODE_AND, prev, parser->storage); break; | ||
305 | case TOK_OR: node = node_alloc(NODE_OR, prev, parser->storage); break; | ||
306 | case TOK_EQ: node = node_alloc(NODE_EQ, prev, parser->storage); break; | ||
307 | case TOK_NOTEQ: | ||
308 | node = node_alloc(NODE_NOTEQ, prev, parser->storage); | ||
309 | break; | ||
310 | case TOK_LT: node = node_alloc(NODE_LT, prev, parser->storage); break; | ||
311 | case TOK_GT: node = node_alloc(NODE_GT, prev, parser->storage); break; | ||
312 | case TOK_LE: node = node_alloc(NODE_LE, prev, parser->storage); break; | ||
313 | case TOK_GE: node = node_alloc(NODE_GE, prev, parser->storage); break; | ||
239 | default: { | 314 | default: { |
240 | parse_emit_err(parser, prev, cstr("unreachable")); | 315 | parse_emit_err(parser, prev, cstr("unreachable")); |
241 | return; | 316 | return; |