diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-17 18:38:50 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-17 18:38:50 +0200 |
commit | c581804c6ffa5824a9b762097a990425007e49cf (patch) | |
tree | 516e314a60d537d8e1617f945afc8a12b3e0d61f /src | |
parent | 7fee0fc28809042a2ecbc03f2e1b5b569073982b (diff) | |
download | bdl-c581804c6ffa5824a9b762097a990425007e49cf.tar.gz bdl-c581804c6ffa5824a9b762097a990425007e49cf.zip |
Add let/set/struct parsing
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 336 |
1 files changed, 288 insertions, 48 deletions
@@ -70,6 +70,13 @@ typedef enum NodeKind { | |||
70 | NODE_TRUE, | 70 | NODE_TRUE, |
71 | NODE_FALSE, | 71 | NODE_FALSE, |
72 | NODE_NIL, | 72 | NODE_NIL, |
73 | // Keywords. | ||
74 | NODE_LET, | ||
75 | NODE_SET, | ||
76 | NODE_STRUCT, | ||
77 | // Helpers. | ||
78 | NODE_NODE_LIST, | ||
79 | NODE_NODE_TYPE, | ||
73 | } NodeKind; | 80 | } NodeKind; |
74 | 81 | ||
75 | Str node_str[] = { | 82 | Str node_str[] = { |
@@ -104,6 +111,12 @@ Str node_str[] = { | |||
104 | [NODE_TRUE] = cstr("TRUE"), | 111 | [NODE_TRUE] = cstr("TRUE"), |
105 | [NODE_FALSE] = cstr("FALSE"), | 112 | [NODE_FALSE] = cstr("FALSE"), |
106 | [NODE_NIL] = cstr("NIL"), | 113 | [NODE_NIL] = cstr("NIL"), |
114 | [NODE_LET] = cstr("LET"), | ||
115 | [NODE_SET] = cstr("SET"), | ||
116 | [NODE_STRUCT] = cstr("STRUCT"), | ||
117 | // Helpers. | ||
118 | [NODE_NODE_LIST] = cstr("..."), | ||
119 | [NODE_NODE_TYPE] = cstr("TYPE"), | ||
107 | }; | 120 | }; |
108 | 121 | ||
109 | typedef struct Node { | 122 | typedef struct Node { |
@@ -119,21 +132,17 @@ typedef struct Node { | |||
119 | Str str; | 132 | Str str; |
120 | Str sym; | 133 | Str sym; |
121 | } value; | 134 | } value; |
122 | struct Node *left; | 135 | union { |
123 | struct Node *right; | 136 | struct Node *left; |
137 | struct Node *varname; | ||
138 | }; | ||
139 | union { | ||
140 | struct Node *right; | ||
141 | struct Node *vartype; | ||
142 | struct Node *varvalue; | ||
143 | }; | ||
124 | } Node; | 144 | } Node; |
125 | 145 | ||
126 | Node * | ||
127 | node_alloc(NodeKind kind, Token tok, Arena *a) { | ||
128 | static sz id = 0; | ||
129 | Node *node = arena_calloc((sz)sizeof(Node), a); | ||
130 | node->id = id++; | ||
131 | node->kind = kind; | ||
132 | node->line = tok.line; | ||
133 | node->col = tok.col; | ||
134 | return node; | ||
135 | } | ||
136 | |||
137 | // | 146 | // |
138 | // Parsing. | 147 | // Parsing. |
139 | // | 148 | // |
@@ -179,6 +188,7 @@ typedef struct { | |||
179 | 188 | ||
180 | void parse_expr(Parser *parser, ParsePrecedence precedence); | 189 | void parse_expr(Parser *parser, ParsePrecedence precedence); |
181 | void parse_advance(Parser *parser); | 190 | void parse_advance(Parser *parser); |
191 | bool parse_match(Parser *parser, TokenKind kind); | ||
182 | 192 | ||
183 | void parse_grouping(Parser *parser); | 193 | void parse_grouping(Parser *parser); |
184 | void parse_unary(Parser *parser); | 194 | void parse_unary(Parser *parser); |
@@ -187,6 +197,11 @@ void parse_number(Parser *parser); | |||
187 | void parse_literal(Parser *parser); | 197 | void parse_literal(Parser *parser); |
188 | void parse_string(Parser *parser); | 198 | void parse_string(Parser *parser); |
189 | void parse_symbol(Parser *parser); | 199 | void parse_symbol(Parser *parser); |
200 | void parse_symbol_chain(Parser *parser); | ||
201 | void parse_keyword(Parser *parser); | ||
202 | void parse_struct(Parser *parser); | ||
203 | Node *parse_struct_field(Parser *parser); | ||
204 | Node *parse_type(Parser *parser); | ||
190 | 205 | ||
191 | ParseRule parse_rules[] = { | 206 | ParseRule parse_rules[] = { |
192 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, | 207 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, |
@@ -196,6 +211,7 @@ ParseRule parse_rules[] = { | |||
196 | [TOK_DIV] = {NULL, parse_binary, PREC_FACTOR}, | 211 | [TOK_DIV] = {NULL, parse_binary, PREC_FACTOR}, |
197 | [TOK_MUL] = {NULL, parse_binary, PREC_FACTOR}, | 212 | [TOK_MUL] = {NULL, parse_binary, PREC_FACTOR}, |
198 | [TOK_MOD] = {NULL, parse_binary, PREC_FACTOR}, | 213 | [TOK_MOD] = {NULL, parse_binary, PREC_FACTOR}, |
214 | |||
199 | // Logical. | 215 | // Logical. |
200 | [TOK_NOT] = {parse_unary, NULL, PREC_NONE}, | 216 | [TOK_NOT] = {parse_unary, NULL, PREC_NONE}, |
201 | [TOK_AND] = {NULL, parse_binary, PREC_AND}, | 217 | [TOK_AND] = {NULL, parse_binary, PREC_AND}, |
@@ -206,23 +222,53 @@ ParseRule parse_rules[] = { | |||
206 | [TOK_GT] = {NULL, parse_binary, PREC_COMPARISON}, | 222 | [TOK_GT] = {NULL, parse_binary, PREC_COMPARISON}, |
207 | [TOK_LE] = {NULL, parse_binary, PREC_COMPARISON}, | 223 | [TOK_LE] = {NULL, parse_binary, PREC_COMPARISON}, |
208 | [TOK_GE] = {NULL, parse_binary, PREC_COMPARISON}, | 224 | [TOK_GE] = {NULL, parse_binary, PREC_COMPARISON}, |
225 | |||
209 | // Bitwise ops. | 226 | // Bitwise ops. |
210 | [TOK_BITNOT] = {parse_unary, NULL, PREC_NONE}, | 227 | [TOK_BITNOT] = {parse_unary, NULL, PREC_NONE}, |
211 | [TOK_BITAND] = {NULL, parse_binary, PREC_BITLOGIC}, | 228 | [TOK_BITAND] = {NULL, parse_binary, PREC_BITLOGIC}, |
212 | [TOK_BITOR] = {NULL, parse_binary, PREC_BITLOGIC}, | 229 | [TOK_BITOR] = {NULL, parse_binary, PREC_BITLOGIC}, |
213 | [TOK_BITLSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, | 230 | [TOK_BITLSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, |
214 | [TOK_BITRSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, | 231 | [TOK_BITRSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, |
232 | |||
215 | // Literals. | 233 | // Literals. |
216 | [TOK_STRING] = {parse_string, NULL, PREC_NONE}, | 234 | [TOK_STRING] = {parse_string, NULL, PREC_NONE}, |
217 | [TOK_SYMBOL] = {parse_symbol, NULL, PREC_NONE}, | 235 | [TOK_SYMBOL] = {parse_symbol_chain, NULL, PREC_NONE}, |
218 | [TOK_NUM_INT] = {parse_number, NULL, PREC_NONE}, | 236 | [TOK_NUM_INT] = {parse_number, NULL, PREC_NONE}, |
219 | [TOK_NUM_FLOAT] = {parse_number, NULL, PREC_NONE}, | 237 | [TOK_NUM_FLOAT] = {parse_number, NULL, PREC_NONE}, |
220 | [TOK_TRUE] = {parse_literal, NULL, PREC_NONE}, | 238 | [TOK_TRUE] = {parse_literal, NULL, PREC_NONE}, |
221 | [TOK_FALSE] = {parse_literal, NULL, PREC_NONE}, | 239 | [TOK_FALSE] = {parse_literal, NULL, PREC_NONE}, |
222 | [TOK_NIL] = {parse_literal, NULL, PREC_NONE}, | 240 | [TOK_NIL] = {parse_literal, NULL, PREC_NONE}, |
241 | |||
242 | // Statements. | ||
243 | [TOK_LET] = {parse_keyword, NULL, PREC_NONE}, | ||
244 | [TOK_SET] = {parse_keyword, NULL, PREC_NONE}, | ||
245 | [TOK_STRUCT] = {parse_keyword, NULL, PREC_NONE}, | ||
246 | [TOK_IF] = {parse_keyword, NULL, PREC_NONE}, | ||
247 | [TOK_MATCH] = {parse_keyword, NULL, PREC_NONE}, | ||
248 | [TOK_CASE] = {parse_keyword, NULL, PREC_NONE}, | ||
249 | [TOK_WHILE] = {parse_keyword, NULL, PREC_NONE}, | ||
250 | [TOK_CONTINUE] = {parse_keyword, NULL, PREC_NONE}, | ||
251 | [TOK_BREAK] = {parse_keyword, NULL, PREC_NONE}, | ||
252 | [TOK_FUN] = {parse_keyword, NULL, PREC_NONE}, | ||
253 | [TOK_RETURN] = {parse_keyword, NULL, PREC_NONE}, | ||
254 | |||
223 | [TOK_EOF] = {NULL, NULL, PREC_NONE}, | 255 | [TOK_EOF] = {NULL, NULL, PREC_NONE}, |
224 | }; | 256 | }; |
225 | 257 | ||
258 | Node * | ||
259 | node_alloc(NodeKind kind, Token tok, Parser *p) { | ||
260 | if (p->panic) { | ||
261 | return NULL; | ||
262 | } | ||
263 | static sz id = 0; | ||
264 | Node *node = arena_calloc((sz)sizeof(Node), p->storage); | ||
265 | node->id = id++; | ||
266 | node->kind = kind; | ||
267 | node->line = tok.line; | ||
268 | node->col = tok.col; | ||
269 | return node; | ||
270 | } | ||
271 | |||
226 | void | 272 | void |
227 | parse_emit_err(Parser *parser, Token token, Str msg) { | 273 | parse_emit_err(Parser *parser, Token token, Str msg) { |
228 | if (parser->panic) { | 274 | if (parser->panic) { |
@@ -243,9 +289,22 @@ void | |||
243 | parse_advance(Parser *parser) { | 289 | parse_advance(Parser *parser) { |
244 | assert(parser); | 290 | assert(parser); |
245 | parser->previous = parser->current; | 291 | parser->previous = parser->current; |
292 | if (parser->previous.kind == TOK_EOF) { | ||
293 | return; | ||
294 | } | ||
246 | parser->current = parser->tokens[parser->idx++]; | 295 | parser->current = parser->tokens[parser->idx++]; |
247 | } | 296 | } |
248 | 297 | ||
298 | bool | ||
299 | parse_match(Parser *parser, TokenKind kind) { | ||
300 | assert(parser); | ||
301 | if (parser->current.kind != kind) { | ||
302 | return false; | ||
303 | } | ||
304 | parse_advance(parser); | ||
305 | return true; | ||
306 | } | ||
307 | |||
249 | static void | 308 | static void |
250 | parse_consume(Parser *parser, TokenKind kind, Str msg) { | 309 | parse_consume(Parser *parser, TokenKind kind, Str msg) { |
251 | if (parser->current.kind == kind) { | 310 | if (parser->current.kind == kind) { |
@@ -258,6 +317,10 @@ parse_consume(Parser *parser, TokenKind kind, Str msg) { | |||
258 | void | 317 | void |
259 | parse_expr(Parser *parser, ParsePrecedence precedence) { | 318 | parse_expr(Parser *parser, ParsePrecedence precedence) { |
260 | parse_advance(parser); | 319 | parse_advance(parser); |
320 | // TODO: synchronize panic mode on keywords. | ||
321 | if (parser->panic) { | ||
322 | return; | ||
323 | } | ||
261 | ParseFn prefix = parse_rules[parser->previous.kind].prefix; | 324 | ParseFn prefix = parse_rules[parser->previous.kind].prefix; |
262 | if (prefix == NULL) { | 325 | if (prefix == NULL) { |
263 | parse_emit_err(parser, parser->previous, cstr("expected expression")); | 326 | parse_emit_err(parser, parser->previous, cstr("expected expression")); |
@@ -287,12 +350,13 @@ parse_unary(Parser *parser) { | |||
287 | parse_expr(parser, PREC_UNARY); | 350 | parse_expr(parser, PREC_UNARY); |
288 | Node *node = NULL; | 351 | Node *node = NULL; |
289 | switch (prev.kind) { | 352 | switch (prev.kind) { |
290 | case TOK_NOT: node = node_alloc(NODE_NOT, prev, parser->storage); break; | 353 | case TOK_NOT: node = node_alloc(NODE_NOT, prev, parser); break; |
291 | case TOK_BITNOT: { | 354 | case TOK_BITNOT: node = node_alloc(NODE_BITNOT, prev, parser); break; |
292 | node = node_alloc(NODE_BITNOT, prev, parser->storage); | ||
293 | } break; | ||
294 | default: break; // Unreachable. | 355 | default: break; // Unreachable. |
295 | } | 356 | } |
357 | if (!node) { | ||
358 | return; | ||
359 | } | ||
296 | node->left = array_pop(parser->nodes); | 360 | node->left = array_pop(parser->nodes); |
297 | array_push(parser->nodes, node, parser->storage); | 361 | array_push(parser->nodes, node, parser->storage); |
298 | } | 362 | } |
@@ -307,13 +371,142 @@ parse_literal(Parser *parser) { | |||
307 | Node *node = NULL; | 371 | Node *node = NULL; |
308 | switch (prev.kind) { | 372 | switch (prev.kind) { |
309 | case TOK_TRUE: { | 373 | case TOK_TRUE: { |
310 | node = node_alloc(NODE_TRUE, prev, parser->storage); | 374 | node = node_alloc(NODE_TRUE, prev, parser); |
311 | } break; | 375 | } break; |
312 | case TOK_FALSE: { | 376 | case TOK_FALSE: { |
313 | node = node_alloc(NODE_FALSE, prev, parser->storage); | 377 | node = node_alloc(NODE_FALSE, prev, parser); |
314 | } break; | 378 | } break; |
315 | case TOK_NIL: { | 379 | case TOK_NIL: { |
316 | node = node_alloc(NODE_NIL, prev, parser->storage); | 380 | node = node_alloc(NODE_NIL, prev, parser); |
381 | } break; | ||
382 | default: return; // Unreachable. | ||
383 | } | ||
384 | array_push(parser->nodes, node, parser->storage); | ||
385 | } | ||
386 | |||
387 | Node * | ||
388 | parse_type(Parser *parser) { | ||
389 | Token prev = parser->previous; | ||
390 | #if DEBUG == 1 | ||
391 | print("parsing type "); | ||
392 | print_token(prev); | ||
393 | #endif | ||
394 | Node *node = node_alloc(NODE_NODE_TYPE, prev, parser); | ||
395 | if (parse_match(parser, TOK_LCURLY)) { | ||
396 | node->value.sym = cstr("..."); | ||
397 | Node *l = parse_struct_field(parser); | ||
398 | if (!l) { | ||
399 | return NULL; | ||
400 | } | ||
401 | node->vartype = l; | ||
402 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | ||
403 | Node *tmp = parse_struct_field(parser); | ||
404 | if (!tmp) { | ||
405 | return NULL; | ||
406 | } | ||
407 | l->vartype = tmp; | ||
408 | l = tmp; | ||
409 | } | ||
410 | return node; | ||
411 | } | ||
412 | parse_consume(parser, TOK_SYMBOL, cstr("no type given for struct field")); | ||
413 | node->value.sym = parser->previous.val; | ||
414 | return node; | ||
415 | } | ||
416 | |||
417 | Node * | ||
418 | parse_struct_field(Parser *parser) { | ||
419 | #if DEBUG == 1 | ||
420 | println("parsing struct field "); | ||
421 | print_token(parser->previous); | ||
422 | #endif | ||
423 | parse_consume(parser, TOK_SYMBOL, cstr("expected struct field name")); | ||
424 | parse_symbol(parser); | ||
425 | Node *field = array_pop(parser->nodes); | ||
426 | parse_consume(parser, TOK_COLON, | ||
427 | cstr("invalid type name given for struct field")); | ||
428 | field->vartype = parse_type(parser); | ||
429 | if (parse_match(parser, TOK_ASSIGN)) { | ||
430 | parse_expr(parser, PREC_LOW); | ||
431 | field->varname = array_pop(parser->nodes); | ||
432 | } | ||
433 | |||
434 | Node *list = node_alloc(NODE_NODE_LIST, parser->previous, parser); | ||
435 | list->varname = field; | ||
436 | return list; | ||
437 | } | ||
438 | |||
439 | void | ||
440 | parse_keyword(Parser *parser) { | ||
441 | Token prev = parser->previous; | ||
442 | #if DEBUG == 1 | ||
443 | print("parsing keyword "); | ||
444 | print_token(prev); | ||
445 | #endif | ||
446 | Node *node = NULL; | ||
447 | switch (prev.kind) { | ||
448 | case TOK_LET: { | ||
449 | parse_consume(parser, TOK_SYMBOL, | ||
450 | cstr("expected symbol name on let expression")); | ||
451 | parse_symbol(parser); | ||
452 | |||
453 | // Optional type declaration. | ||
454 | Node *type = NULL; | ||
455 | if (parse_match(parser, TOK_COLON)) { | ||
456 | type = parse_type(parser); | ||
457 | } | ||
458 | |||
459 | node = node_alloc(NODE_LET, prev, parser); | ||
460 | if (!node) { | ||
461 | return; | ||
462 | } | ||
463 | |||
464 | // Optional assignment. | ||
465 | if (parse_match(parser, TOK_ASSIGN)) { | ||
466 | parse_expr(parser, PREC_LOW); | ||
467 | node->varvalue = array_pop(parser->nodes); | ||
468 | } | ||
469 | node->varname = array_pop(parser->nodes); | ||
470 | node->varname->vartype = type; | ||
471 | } break; | ||
472 | case TOK_SET: { | ||
473 | parse_consume(parser, TOK_SYMBOL, | ||
474 | cstr("expected symbol name on set expression")); | ||
475 | parse_symbol_chain(parser); | ||
476 | parse_consume(parser, TOK_ASSIGN, | ||
477 | cstr("expected assignment on set expression")); | ||
478 | parse_expr(parser, PREC_LOW); | ||
479 | node = node_alloc(NODE_SET, prev, parser); | ||
480 | if (!node) { | ||
481 | return; | ||
482 | } | ||
483 | node->varvalue = array_pop(parser->nodes); | ||
484 | node->varname = array_pop(parser->nodes); | ||
485 | } break; | ||
486 | case TOK_STRUCT: { | ||
487 | parse_consume(parser, TOK_SYMBOL, | ||
488 | cstr("expected symbol name on struct definition")); | ||
489 | parse_symbol(parser); | ||
490 | parse_consume(parser, TOK_LCURLY, | ||
491 | cstr("expected '{' on struct definition")); | ||
492 | node = node_alloc(NODE_STRUCT, prev, parser); | ||
493 | if (!node) { | ||
494 | return; | ||
495 | } | ||
496 | node->varname = array_pop(parser->nodes); | ||
497 | Node *l = parse_struct_field(parser); | ||
498 | if (!l) { | ||
499 | return; | ||
500 | } | ||
501 | node->vartype = l; | ||
502 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | ||
503 | Node *tmp = parse_struct_field(parser); | ||
504 | if (!tmp) { | ||
505 | return; | ||
506 | } | ||
507 | l->vartype = tmp; | ||
508 | l = tmp; | ||
509 | } | ||
317 | } break; | 510 | } break; |
318 | default: return; // Unreachable. | 511 | default: return; // Unreachable. |
319 | } | 512 | } |
@@ -332,36 +525,39 @@ parse_binary(Parser *parser) { | |||
332 | 525 | ||
333 | Node *node; | 526 | Node *node; |
334 | switch (prev.kind) { | 527 | switch (prev.kind) { |
335 | case TOK_ADD: node = node_alloc(NODE_ADD, prev, parser->storage); break; | 528 | case TOK_ADD: node = node_alloc(NODE_ADD, prev, parser); break; |
336 | case TOK_SUB: node = node_alloc(NODE_SUB, prev, parser->storage); break; | 529 | case TOK_SUB: node = node_alloc(NODE_SUB, prev, parser); break; |
337 | case TOK_MUL: node = node_alloc(NODE_MUL, prev, parser->storage); break; | 530 | case TOK_MUL: node = node_alloc(NODE_MUL, prev, parser); break; |
338 | case TOK_DIV: node = node_alloc(NODE_DIV, prev, parser->storage); break; | 531 | case TOK_DIV: node = node_alloc(NODE_DIV, prev, parser); break; |
339 | case TOK_MOD: node = node_alloc(NODE_MOD, prev, parser->storage); break; | 532 | case TOK_MOD: node = node_alloc(NODE_MOD, prev, parser); break; |
340 | case TOK_AND: node = node_alloc(NODE_AND, prev, parser->storage); break; | 533 | case TOK_AND: node = node_alloc(NODE_AND, prev, parser); break; |
341 | case TOK_OR: node = node_alloc(NODE_OR, prev, parser->storage); break; | 534 | case TOK_OR: node = node_alloc(NODE_OR, prev, parser); break; |
342 | case TOK_EQ: node = node_alloc(NODE_EQ, prev, parser->storage); break; | 535 | case TOK_EQ: node = node_alloc(NODE_EQ, prev, parser); break; |
343 | case TOK_NEQ: node = node_alloc(NODE_NEQ, prev, parser->storage); break; | 536 | case TOK_NEQ: node = node_alloc(NODE_NEQ, prev, parser); break; |
344 | case TOK_LT: node = node_alloc(NODE_LT, prev, parser->storage); break; | 537 | case TOK_LT: node = node_alloc(NODE_LT, prev, parser); break; |
345 | case TOK_GT: node = node_alloc(NODE_GT, prev, parser->storage); break; | 538 | case TOK_GT: node = node_alloc(NODE_GT, prev, parser); break; |
346 | case TOK_LE: node = node_alloc(NODE_LE, prev, parser->storage); break; | 539 | case TOK_LE: node = node_alloc(NODE_LE, prev, parser); break; |
347 | case TOK_GE: node = node_alloc(NODE_GE, prev, parser->storage); break; | 540 | case TOK_GE: node = node_alloc(NODE_GE, prev, parser); break; |
348 | case TOK_BITAND: { | 541 | case TOK_BITAND: { |
349 | node = node_alloc(NODE_BITAND, prev, parser->storage); | 542 | node = node_alloc(NODE_BITAND, prev, parser); |
350 | } break; | 543 | } break; |
351 | case TOK_BITOR: { | 544 | case TOK_BITOR: { |
352 | node = node_alloc(NODE_BITOR, prev, parser->storage); | 545 | node = node_alloc(NODE_BITOR, prev, parser); |
353 | } break; | 546 | } break; |
354 | case TOK_BITLSHIFT: { | 547 | case TOK_BITLSHIFT: { |
355 | node = node_alloc(NODE_BITLSHIFT, prev, parser->storage); | 548 | node = node_alloc(NODE_BITLSHIFT, prev, parser); |
356 | } break; | 549 | } break; |
357 | case TOK_BITRSHIFT: { | 550 | case TOK_BITRSHIFT: { |
358 | node = node_alloc(NODE_BITRSHIFT, prev, parser->storage); | 551 | node = node_alloc(NODE_BITRSHIFT, prev, parser); |
359 | } break; | 552 | } break; |
360 | default: { | 553 | default: { |
361 | parse_emit_err(parser, prev, cstr("unreachable")); | 554 | parse_emit_err(parser, prev, cstr("unreachable")); |
362 | return; | 555 | return; |
363 | } | 556 | } |
364 | } | 557 | } |
558 | if (!node) { | ||
559 | return; | ||
560 | } | ||
365 | node->right = array_pop(parser->nodes); | 561 | node->right = array_pop(parser->nodes); |
366 | node->left = array_pop(parser->nodes); | 562 | node->left = array_pop(parser->nodes); |
367 | array_push(parser->nodes, node, parser->storage); | 563 | array_push(parser->nodes, node, parser->storage); |
@@ -379,15 +575,24 @@ parse_number(Parser *parser) { | |||
379 | case TOK_NUM_INT: { | 575 | case TOK_NUM_INT: { |
380 | if (str_has_prefix(prev.val, cstr("0x")) || | 576 | if (str_has_prefix(prev.val, cstr("0x")) || |
381 | str_has_prefix(prev.val, cstr("0b"))) { | 577 | str_has_prefix(prev.val, cstr("0b"))) { |
382 | node = node_alloc(NODE_NUM_UINT, prev, parser->storage); | 578 | node = node_alloc(NODE_NUM_UINT, prev, parser); |
579 | if (!node) { | ||
580 | return; | ||
581 | } | ||
383 | node->value.u = str_to_uint(prev.val); | 582 | node->value.u = str_to_uint(prev.val); |
384 | } else { | 583 | } else { |
385 | node = node_alloc(NODE_NUM_INT, prev, parser->storage); | 584 | node = node_alloc(NODE_NUM_INT, prev, parser); |
585 | if (!node) { | ||
586 | return; | ||
587 | } | ||
386 | node->value.i = str_to_int(prev.val); | 588 | node->value.i = str_to_int(prev.val); |
387 | } | 589 | } |
388 | } break; | 590 | } break; |
389 | case TOK_NUM_FLOAT: { | 591 | case TOK_NUM_FLOAT: { |
390 | node = node_alloc(NODE_NUM_FLOAT, prev, parser->storage); | 592 | node = node_alloc(NODE_NUM_FLOAT, prev, parser); |
593 | if (!node) { | ||
594 | return; | ||
595 | } | ||
391 | node->value.d = str_to_float(prev.val); | 596 | node->value.d = str_to_float(prev.val); |
392 | } break; | 597 | } break; |
393 | default: break; | 598 | default: break; |
@@ -402,7 +607,10 @@ parse_string(Parser *parser) { | |||
402 | print("parsing string "); | 607 | print("parsing string "); |
403 | print_token(prev); | 608 | print_token(prev); |
404 | #endif | 609 | #endif |
405 | Node *node = node_alloc(NODE_STRING, prev, parser->storage); | 610 | Node *node = node_alloc(NODE_STRING, prev, parser); |
611 | if (!node) { | ||
612 | return; | ||
613 | } | ||
406 | node->value.str = str_remove_prefix(prev.val, cstr("\"")); | 614 | node->value.str = str_remove_prefix(prev.val, cstr("\"")); |
407 | node->value.str = str_remove_suffix(node->value.str, cstr("\"")); | 615 | node->value.str = str_remove_suffix(node->value.str, cstr("\"")); |
408 | array_push(parser->nodes, node, parser->storage); | 616 | array_push(parser->nodes, node, parser->storage); |
@@ -412,15 +620,39 @@ void | |||
412 | parse_symbol(Parser *parser) { | 620 | parse_symbol(Parser *parser) { |
413 | Token prev = parser->previous; | 621 | Token prev = parser->previous; |
414 | #if DEBUG == 1 | 622 | #if DEBUG == 1 |
415 | print("parsing string "); | 623 | print("parsing symbol "); |
416 | print_token(prev); | 624 | print_token(prev); |
417 | #endif | 625 | #endif |
418 | Node *node = node_alloc(NODE_STRING, prev, parser->storage); | 626 | Node *node = node_alloc(NODE_SYMBOL, prev, parser); |
627 | if (!node) { | ||
628 | return; | ||
629 | } | ||
419 | node->value.sym = prev.val; | 630 | node->value.sym = prev.val; |
420 | array_push(parser->nodes, node, parser->storage); | 631 | array_push(parser->nodes, node, parser->storage); |
421 | } | 632 | } |
422 | 633 | ||
423 | void | 634 | void |
635 | parse_symbol_chain(Parser *parser) { | ||
636 | Token prev = parser->previous; | ||
637 | #if DEBUG == 1 | ||
638 | print("parsing symbol "); | ||
639 | print_token(prev); | ||
640 | #endif | ||
641 | Node *node = node_alloc(NODE_SYMBOL, prev, parser); | ||
642 | if (!node) { | ||
643 | return; | ||
644 | } | ||
645 | node->value.sym = prev.val; | ||
646 | if (parse_match(parser, TOK_DOT)) { | ||
647 | parse_consume(parser, TOK_SYMBOL, | ||
648 | cstr("expected symbol after '.' operator")); | ||
649 | parse_symbol_chain(parser); | ||
650 | node->varname = array_pop(parser->nodes); | ||
651 | } | ||
652 | array_push(parser->nodes, node, parser->storage); | ||
653 | } | ||
654 | |||
655 | void | ||
424 | parse_grouping(Parser *parser) { | 656 | parse_grouping(Parser *parser) { |
425 | #if DEBUG == 1 | 657 | #if DEBUG == 1 |
426 | print("parsing group "); | 658 | print("parsing group "); |
@@ -436,23 +668,24 @@ graph_node(Node *node) { | |||
436 | return; | 668 | return; |
437 | } | 669 | } |
438 | print("%d [width=2.5,shape=Mrecord,label=\"", node->id); | 670 | print("%d [width=2.5,shape=Mrecord,label=\"", node->id); |
439 | print("<top> %s ", node_str[node->kind]); | 671 | print("{ %s | { L: %d | C: %d } } ", node_str[node->kind], node->line, |
672 | node->col); | ||
440 | switch (node->kind) { | 673 | switch (node->kind) { |
441 | case NODE_NUM_INT: print("| Value: %d", node->value.i); break; | 674 | case NODE_NUM_INT: print("| Value: %d", node->value.i); break; |
442 | case NODE_NUM_UINT: print("| Value: %x", node->value.u); break; | 675 | case NODE_NUM_UINT: print("| Value: %x", node->value.u); break; |
443 | case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; | 676 | case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; |
444 | case NODE_STRING: print("| Value: %s", node->value.str); break; | 677 | case NODE_STRING: print("| Value: %s", node->value.str); break; |
445 | case NODE_SYMBOL: print("| Value: %s", node->value.sym); break; | 678 | case NODE_SYMBOL: print("| Value: %s", node->value.sym); break; |
679 | case NODE_NODE_TYPE: print("| Value: %s", node->value.sym); break; | ||
446 | default: break; | 680 | default: break; |
447 | } | 681 | } |
448 | print("| Line: %d | Col: %d ", node->line, node->col); | ||
449 | println("\"];"); | 682 | println("\"];"); |
450 | if (node->left) { | 683 | if (node->left) { |
451 | println("%d:top:e->%d:top:w;", node->id, node->left->id); | 684 | println("%d:e->%d:w;", node->id, node->left->id); |
452 | graph_node(node->left); | 685 | graph_node(node->left); |
453 | } | 686 | } |
454 | if (node->right) { | 687 | if (node->right) { |
455 | println("%d:top:e->%d:top:w;", node->id, node->right->id); | 688 | println("%d:e->%d:w;", node->id, node->right->id); |
456 | graph_node(node->right); | 689 | graph_node(node->right); |
457 | } | 690 | } |
458 | } | 691 | } |
@@ -516,7 +749,14 @@ process_file(Str path) { | |||
516 | array_init(parser.nodes, 256, parser.storage); | 749 | array_init(parser.nodes, 256, parser.storage); |
517 | parse_advance(&parser); | 750 | parse_advance(&parser); |
518 | while (parser.current.kind != TOK_EOF) { | 751 | while (parser.current.kind != TOK_EOF) { |
752 | #if DEBUG == 1 | ||
753 | static sz ctr = 0; | ||
754 | println("parsing root: %d", ctr++); | ||
755 | #endif | ||
519 | parse_expr(&parser, PREC_LOW); | 756 | parse_expr(&parser, PREC_LOW); |
757 | if (parser.panic) { | ||
758 | break; | ||
759 | } | ||
520 | } | 760 | } |
521 | if (parser.err) { | 761 | if (parser.err) { |
522 | goto stop; | 762 | goto stop; |