diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-16 22:03:13 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-16 22:03:13 +0200 |
commit | 3922b262aef17be3fcee90db969aca5b0edc617e (patch) | |
tree | c297ec5200e0c9002dfa3ea522c41cb48d6e1110 /src/main.c | |
parent | bf4aa41a445986658f4ee931305d9caf496e9072 (diff) | |
download | bdl-3922b262aef17be3fcee90db969aca5b0edc617e.tar.gz bdl-3922b262aef17be3fcee90db969aca5b0edc617e.zip |
Add bitwise parsing operations
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 45 |
1 files changed, 39 insertions, 6 deletions
@@ -50,11 +50,17 @@ typedef enum NodeKind { | |||
50 | NODE_AND, | 50 | NODE_AND, |
51 | NODE_OR, | 51 | NODE_OR, |
52 | NODE_EQ, | 52 | NODE_EQ, |
53 | NODE_NOTEQ, | 53 | NODE_NEQ, |
54 | NODE_LT, | 54 | NODE_LT, |
55 | NODE_GT, | 55 | NODE_GT, |
56 | NODE_LE, | 56 | NODE_LE, |
57 | NODE_GE, | 57 | NODE_GE, |
58 | // Bitwise ops. | ||
59 | NODE_BITNOT, | ||
60 | NODE_BITAND, | ||
61 | NODE_BITOR, | ||
62 | NODE_BITLSHIFT, | ||
63 | NODE_BITRSHIFT, | ||
58 | // Literals. | 64 | // Literals. |
59 | NODE_NUM_INT, | 65 | NODE_NUM_INT, |
60 | NODE_NUM_FLOAT, | 66 | NODE_NUM_FLOAT, |
@@ -75,11 +81,17 @@ Str node_str[] = { | |||
75 | [NODE_AND] = cstr("AND"), | 81 | [NODE_AND] = cstr("AND"), |
76 | [NODE_OR] = cstr("OR"), | 82 | [NODE_OR] = cstr("OR"), |
77 | [NODE_EQ] = cstr("EQ"), | 83 | [NODE_EQ] = cstr("EQ"), |
78 | [NODE_NOTEQ] = cstr("NOTEQ"), | 84 | [NODE_NEQ] = cstr("NEQ"), |
79 | [NODE_LT] = cstr("LT"), | 85 | [NODE_LT] = cstr("LT"), |
80 | [NODE_GT] = cstr("GT"), | 86 | [NODE_GT] = cstr("GT"), |
81 | [NODE_LE] = cstr("LE"), | 87 | [NODE_LE] = cstr("LE"), |
82 | [NODE_GE] = cstr("GE"), | 88 | [NODE_GE] = cstr("GE"), |
89 | // Bitwise ops. | ||
90 | [NODE_BITNOT] = cstr("BITNOT"), | ||
91 | [NODE_BITAND] = cstr("BITAND"), | ||
92 | [NODE_BITOR] = cstr("BITOR"), | ||
93 | [NODE_BITLSHIFT] = cstr("BITLSHIFT"), | ||
94 | [NODE_BITRSHIFT] = cstr("BITRSHIFT"), | ||
83 | // Literals. | 95 | // Literals. |
84 | [NODE_NUM_INT] = cstr("INT"), | 96 | [NODE_NUM_INT] = cstr("INT"), |
85 | [NODE_NUM_FLOAT] = cstr("FLOAT"), | 97 | [NODE_NUM_FLOAT] = cstr("FLOAT"), |
@@ -135,6 +147,8 @@ typedef struct Parser { | |||
135 | typedef enum { | 147 | typedef enum { |
136 | PREC_NONE = 0, | 148 | PREC_NONE = 0, |
137 | PREC_LOW, // lowest precedence | 149 | PREC_LOW, // lowest precedence |
150 | PREC_BITLOGIC, // & | | ||
151 | PREC_BITSHIFT, // << >> | ||
138 | PREC_OR, // || | 152 | PREC_OR, // || |
139 | PREC_AND, // && | 153 | PREC_AND, // && |
140 | PREC_EQUALITY, // == != | 154 | PREC_EQUALITY, // == != |
@@ -176,11 +190,17 @@ ParseRule parse_rules[] = { | |||
176 | [TOK_AND] = {NULL, parse_binary, PREC_AND}, | 190 | [TOK_AND] = {NULL, parse_binary, PREC_AND}, |
177 | [TOK_OR] = {NULL, parse_binary, PREC_OR}, | 191 | [TOK_OR] = {NULL, parse_binary, PREC_OR}, |
178 | [TOK_EQ] = {NULL, parse_binary, PREC_EQUALITY}, | 192 | [TOK_EQ] = {NULL, parse_binary, PREC_EQUALITY}, |
179 | [TOK_NOTEQ] = {NULL, parse_binary, PREC_EQUALITY}, | 193 | [TOK_NEQ] = {NULL, parse_binary, PREC_EQUALITY}, |
180 | [TOK_LT] = {NULL, parse_binary, PREC_COMPARISON}, | 194 | [TOK_LT] = {NULL, parse_binary, PREC_COMPARISON}, |
181 | [TOK_GT] = {NULL, parse_binary, PREC_COMPARISON}, | 195 | [TOK_GT] = {NULL, parse_binary, PREC_COMPARISON}, |
182 | [TOK_LE] = {NULL, parse_binary, PREC_COMPARISON}, | 196 | [TOK_LE] = {NULL, parse_binary, PREC_COMPARISON}, |
183 | [TOK_GE] = {NULL, parse_binary, PREC_COMPARISON}, | 197 | [TOK_GE] = {NULL, parse_binary, PREC_COMPARISON}, |
198 | // Bitwise ops. | ||
199 | [TOK_BITNOT] = {parse_unary, NULL, PREC_NONE}, | ||
200 | [TOK_BITAND] = {NULL, parse_binary, PREC_BITLOGIC}, | ||
201 | [TOK_BITOR] = {NULL, parse_binary, PREC_BITLOGIC}, | ||
202 | [TOK_BITLSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, | ||
203 | [TOK_BITRSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, | ||
184 | // Literals. | 204 | // Literals. |
185 | [TOK_NUM_INT] = {parse_number, NULL, PREC_NONE}, | 205 | [TOK_NUM_INT] = {parse_number, NULL, PREC_NONE}, |
186 | [TOK_NUM_FLOAT] = {parse_number, NULL, PREC_NONE}, | 206 | [TOK_NUM_FLOAT] = {parse_number, NULL, PREC_NONE}, |
@@ -255,6 +275,9 @@ parse_unary(Parser *parser) { | |||
255 | Node *node = NULL; | 275 | Node *node = NULL; |
256 | switch (prev.kind) { | 276 | switch (prev.kind) { |
257 | case TOK_NOT: node = node_alloc(NODE_NOT, prev, parser->storage); break; | 277 | case TOK_NOT: node = node_alloc(NODE_NOT, prev, parser->storage); break; |
278 | case TOK_BITNOT: { | ||
279 | node = node_alloc(NODE_BITNOT, prev, parser->storage); | ||
280 | } break; | ||
258 | default: break; // Unreachable. | 281 | default: break; // Unreachable. |
259 | } | 282 | } |
260 | node->left = array_pop(parser->nodes); | 283 | node->left = array_pop(parser->nodes); |
@@ -304,13 +327,23 @@ parse_binary(Parser *parser) { | |||
304 | case TOK_AND: node = node_alloc(NODE_AND, prev, parser->storage); break; | 327 | 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; | 328 | 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; | 329 | case TOK_EQ: node = node_alloc(NODE_EQ, prev, parser->storage); break; |
307 | case TOK_NOTEQ: | 330 | case TOK_NEQ: node = node_alloc(NODE_NEQ, prev, parser->storage); break; |
308 | node = node_alloc(NODE_NOTEQ, prev, parser->storage); | ||
309 | break; | ||
310 | case TOK_LT: node = node_alloc(NODE_LT, prev, parser->storage); break; | 331 | 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; | 332 | 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; | 333 | 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; | 334 | case TOK_GE: node = node_alloc(NODE_GE, prev, parser->storage); break; |
335 | case TOK_BITAND: { | ||
336 | node = node_alloc(NODE_BITAND, prev, parser->storage); | ||
337 | } break; | ||
338 | case TOK_BITOR: { | ||
339 | node = node_alloc(NODE_BITOR, prev, parser->storage); | ||
340 | } break; | ||
341 | case TOK_BITLSHIFT: { | ||
342 | node = node_alloc(NODE_BITLSHIFT, prev, parser->storage); | ||
343 | } break; | ||
344 | case TOK_BITRSHIFT: { | ||
345 | node = node_alloc(NODE_BITRSHIFT, prev, parser->storage); | ||
346 | } break; | ||
314 | default: { | 347 | default: { |
315 | parse_emit_err(parser, prev, cstr("unreachable")); | 348 | parse_emit_err(parser, prev, cstr("unreachable")); |
316 | return; | 349 | return; |