diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lexer.c | 22 | ||||
-rw-r--r-- | src/main.c | 45 |
2 files changed, 50 insertions, 17 deletions
diff --git a/src/lexer.c b/src/lexer.c index 997a9f3..0aa26c1 100644 --- a/src/lexer.c +++ b/src/lexer.c | |||
@@ -43,15 +43,15 @@ typedef enum TokenKind { | |||
43 | TOK_MOD, // % | 43 | TOK_MOD, // % |
44 | 44 | ||
45 | // Logical ops. | 45 | // Logical ops. |
46 | TOK_NOT, // ! | 46 | TOK_NOT, // ! |
47 | TOK_AND, // && | 47 | TOK_AND, // && |
48 | TOK_OR, // || | 48 | TOK_OR, // || |
49 | TOK_EQ, // == | 49 | TOK_EQ, // == |
50 | TOK_NOTEQ, // != | 50 | TOK_NEQ, // != |
51 | TOK_LT, // < | 51 | TOK_LT, // < |
52 | TOK_GT, // > | 52 | TOK_GT, // > |
53 | TOK_LE, // <= | 53 | TOK_LE, // <= |
54 | TOK_GE, // >= | 54 | TOK_GE, // >= |
55 | 55 | ||
56 | // Bitwise ops. | 56 | // Bitwise ops. |
57 | TOK_BITNOT, // ~ | 57 | TOK_BITNOT, // ~ |
@@ -115,7 +115,7 @@ Str token_str[] = { | |||
115 | [TOK_AND] = cstr("AND"), | 115 | [TOK_AND] = cstr("AND"), |
116 | [TOK_OR] = cstr("OR"), | 116 | [TOK_OR] = cstr("OR"), |
117 | [TOK_EQ] = cstr("EQ"), | 117 | [TOK_EQ] = cstr("EQ"), |
118 | [TOK_NOTEQ] = cstr("NOTEQ"), | 118 | [TOK_NEQ] = cstr("NEQ"), |
119 | [TOK_LT] = cstr("LT"), | 119 | [TOK_LT] = cstr("LT"), |
120 | [TOK_GT] = cstr("GT"), | 120 | [TOK_GT] = cstr("GT"), |
121 | [TOK_LE] = cstr("LE"), | 121 | [TOK_LE] = cstr("LE"), |
@@ -436,7 +436,7 @@ scan_token(Scanner *scanner) { | |||
436 | case '!': { | 436 | case '!': { |
437 | if (scan_peek(scanner) == '=') { | 437 | if (scan_peek(scanner) == '=') { |
438 | scan_next(scanner); | 438 | scan_next(scanner); |
439 | return emit_token(current, scanner, TOK_NOTEQ); | 439 | return emit_token(current, scanner, TOK_NEQ); |
440 | } | 440 | } |
441 | return emit_token(current, scanner, TOK_NOT); | 441 | return emit_token(current, scanner, TOK_NOT); |
442 | }; | 442 | }; |
@@ -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; |