diff options
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 395 |
1 files changed, 251 insertions, 144 deletions
diff --git a/src/parser.c b/src/parser.c index 90adaf3..5253841 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -9,6 +9,7 @@ | |||
9 | // | 9 | // |
10 | 10 | ||
11 | typedef enum NodeKind { | 11 | typedef enum NodeKind { |
12 | NODE_ERR, | ||
12 | // Arithmetic. | 13 | // Arithmetic. |
13 | NODE_ADD, | 14 | NODE_ADD, |
14 | NODE_SUB, | 15 | NODE_SUB, |
@@ -29,6 +30,7 @@ typedef enum NodeKind { | |||
29 | NODE_BITNOT, | 30 | NODE_BITNOT, |
30 | NODE_BITAND, | 31 | NODE_BITAND, |
31 | NODE_BITOR, | 32 | NODE_BITOR, |
33 | NODE_BITXOR, | ||
32 | NODE_BITLSHIFT, | 34 | NODE_BITLSHIFT, |
33 | NODE_BITRSHIFT, | 35 | NODE_BITRSHIFT, |
34 | // Literals. | 36 | // Literals. |
@@ -69,6 +71,7 @@ typedef enum NodeKind { | |||
69 | } NodeKind; | 71 | } NodeKind; |
70 | 72 | ||
71 | Str node_str[] = { | 73 | Str node_str[] = { |
74 | [NODE_ERR] = cstr("ERR"), | ||
72 | // Arithmetic. | 75 | // Arithmetic. |
73 | [NODE_ADD] = cstr("ADD"), | 76 | [NODE_ADD] = cstr("ADD"), |
74 | [NODE_SUB] = cstr("SUB"), | 77 | [NODE_SUB] = cstr("SUB"), |
@@ -89,6 +92,7 @@ Str node_str[] = { | |||
89 | [NODE_BITNOT] = cstr("BITNOT"), | 92 | [NODE_BITNOT] = cstr("BITNOT"), |
90 | [NODE_BITAND] = cstr("BITAND"), | 93 | [NODE_BITAND] = cstr("BITAND"), |
91 | [NODE_BITOR] = cstr("BITOR"), | 94 | [NODE_BITOR] = cstr("BITOR"), |
95 | [NODE_BITXOR] = cstr("BITXOR"), | ||
92 | [NODE_BITLSHIFT] = cstr("BITLSHIFT"), | 96 | [NODE_BITLSHIFT] = cstr("BITLSHIFT"), |
93 | [NODE_BITRSHIFT] = cstr("BITRSHIFT"), | 97 | [NODE_BITRSHIFT] = cstr("BITRSHIFT"), |
94 | // Literals. | 98 | // Literals. |
@@ -128,75 +132,102 @@ Str node_str[] = { | |||
128 | [NODE_BLOCK] = cstr("BLOCK"), | 132 | [NODE_BLOCK] = cstr("BLOCK"), |
129 | }; | 133 | }; |
130 | 134 | ||
135 | typedef union NodeLit { | ||
136 | f64 d; | ||
137 | sz i; | ||
138 | u64 u; | ||
139 | Str str; | ||
140 | Str sym; | ||
141 | } NodeLit; | ||
142 | |||
143 | typedef struct NodeBinary { | ||
144 | struct Node *left; | ||
145 | struct Node *right; | ||
146 | } NodeBinary; | ||
147 | |||
148 | typedef struct NodeUnary { | ||
149 | struct Node *left; | ||
150 | } NodeUnary; | ||
151 | |||
152 | typedef struct NodeVariable { | ||
153 | struct Node *name; | ||
154 | struct Node *type; | ||
155 | struct Node *val; | ||
156 | } NodeVariable; | ||
157 | |||
158 | typedef struct NodeLoop { | ||
159 | struct Node *cond; | ||
160 | struct Node *expr; | ||
161 | } NodeLoop; | ||
162 | |||
163 | typedef struct NodeIf { | ||
164 | struct Node *cond; | ||
165 | struct Node *expr_true; | ||
166 | struct Node *expr_else; | ||
167 | } NodeIf; | ||
168 | |||
169 | typedef struct NodeField { | ||
170 | struct Node *type; | ||
171 | struct Node *val; | ||
172 | } NodeField; | ||
173 | |||
174 | typedef struct NodeParam { | ||
175 | struct Node *name; | ||
176 | struct Node *type; | ||
177 | } NodeParam; | ||
178 | |||
179 | typedef struct NodeMatch { | ||
180 | struct Node *expr; | ||
181 | struct Node **cases; | ||
182 | } NodeMatch; | ||
183 | |||
184 | typedef struct NodeCase { | ||
185 | struct Node *cond; | ||
186 | struct Node *expr; | ||
187 | } NodeCase; | ||
188 | |||
189 | typedef struct NodeFunction { | ||
190 | struct Node *name; | ||
191 | struct Node **params; | ||
192 | struct Node **ret; | ||
193 | struct Node *body; | ||
194 | } NodeFunction; | ||
195 | |||
196 | typedef struct NodeSymbol { | ||
197 | struct Node *next; | ||
198 | struct Node *arr_size; | ||
199 | } NodeSymbol; | ||
200 | |||
131 | typedef struct Node { | 201 | typedef struct Node { |
132 | sz id; | 202 | sz id; |
133 | sz line; | 203 | sz line; |
134 | sz col; | 204 | sz col; |
205 | struct Node *parent; | ||
135 | 206 | ||
136 | NodeKind kind; | 207 | NodeKind kind; |
208 | NodeLit value; | ||
137 | union { | 209 | union { |
138 | f64 d; | 210 | NodeBinary binary; |
139 | sz i; | 211 | NodeUnary unary; |
140 | u64 u; | 212 | NodeVariable var; |
141 | Str str; | 213 | NodeSymbol sym; |
142 | Str sym; | 214 | NodeLoop loop; |
143 | } value; | 215 | NodeIf ifelse; |
144 | union { | 216 | NodeField field; |
145 | struct { | 217 | NodeParam param; |
146 | struct Node *left; | 218 | NodeMatch match; |
147 | struct Node *right; | 219 | NodeCase case_entry; |
148 | }; | 220 | NodeFunction func; |
149 | struct { | ||
150 | struct Node *next; | ||
151 | struct Node *arr_size; | ||
152 | }; | ||
153 | struct { | ||
154 | struct Node *var_name; | ||
155 | struct Node *var_type; | ||
156 | struct Node *var_val; | ||
157 | }; | ||
158 | struct { | ||
159 | struct Node *while_cond; | ||
160 | struct Node *while_expr; | ||
161 | }; | ||
162 | struct { | ||
163 | struct Node *cond_if; | ||
164 | struct Node *cond_expr; | ||
165 | struct Node *cond_else; | ||
166 | }; | ||
167 | struct { | ||
168 | struct Node *field_type; | ||
169 | struct Node *field_val; | ||
170 | }; | ||
171 | struct { | ||
172 | struct Node *param_name; | ||
173 | struct Node *param_type; | ||
174 | }; | ||
175 | struct { | ||
176 | struct Node *match_expr; | ||
177 | struct Node **match_cases; | ||
178 | }; | ||
179 | struct { | ||
180 | struct Node *case_value; | ||
181 | struct Node *case_expr; | ||
182 | }; | ||
183 | struct Node **struct_field; | 221 | struct Node **struct_field; |
184 | struct Node **elements; | 222 | struct Node **elements; |
185 | struct Node **statements; | 223 | struct Node **statements; |
186 | struct Node **expressions; | 224 | struct Node **expressions; |
187 | struct Node **arguments; | 225 | struct Node **arguments; |
188 | struct { | ||
189 | struct Node *func_name; | ||
190 | struct Node **func_params; | ||
191 | struct Node **func_ret; | ||
192 | struct Node *func_body; | ||
193 | }; | ||
194 | }; | 226 | }; |
195 | bool is_ptr; | 227 | bool is_ptr; |
196 | struct Scope *scope; | ||
197 | Str type; | 228 | Str type; |
198 | Str fun_params; | 229 | Str type_params; |
199 | Str fun_return; | 230 | Str type_returns; |
200 | Str unique_name; | 231 | Str unique_name; |
201 | } Node; | 232 | } Node; |
202 | 233 | ||
@@ -286,6 +317,7 @@ ParseRule parse_rules[] = { | |||
286 | [TOK_BITNOT] = {parse_unary, NULL, PREC_NONE}, | 317 | [TOK_BITNOT] = {parse_unary, NULL, PREC_NONE}, |
287 | [TOK_BITAND] = {NULL, parse_binary, PREC_BITLOGIC}, | 318 | [TOK_BITAND] = {NULL, parse_binary, PREC_BITLOGIC}, |
288 | [TOK_BITOR] = {NULL, parse_binary, PREC_BITLOGIC}, | 319 | [TOK_BITOR] = {NULL, parse_binary, PREC_BITLOGIC}, |
320 | [TOK_BITXOR] = {NULL, parse_binary, PREC_BITLOGIC}, | ||
289 | [TOK_BITLSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, | 321 | [TOK_BITLSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, |
290 | [TOK_BITRSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, | 322 | [TOK_BITRSHIFT] = {NULL, parse_binary, PREC_BITSHIFT}, |
291 | 323 | ||
@@ -308,6 +340,7 @@ ParseRule parse_rules[] = { | |||
308 | [TOK_MATCH] = {parse_keyword, NULL, PREC_NONE}, | 340 | [TOK_MATCH] = {parse_keyword, NULL, PREC_NONE}, |
309 | [TOK_COND] = {parse_keyword, NULL, PREC_NONE}, | 341 | [TOK_COND] = {parse_keyword, NULL, PREC_NONE}, |
310 | [TOK_WHILE] = {parse_keyword, NULL, PREC_NONE}, | 342 | [TOK_WHILE] = {parse_keyword, NULL, PREC_NONE}, |
343 | [TOK_FOR] = {parse_keyword, NULL, PREC_NONE}, | ||
311 | [TOK_CONTINUE] = {parse_keyword, NULL, PREC_NONE}, | 344 | [TOK_CONTINUE] = {parse_keyword, NULL, PREC_NONE}, |
312 | [TOK_BREAK] = {parse_keyword, NULL, PREC_NONE}, | 345 | [TOK_BREAK] = {parse_keyword, NULL, PREC_NONE}, |
313 | [TOK_FUN] = {parse_keyword, NULL, PREC_NONE}, | 346 | [TOK_FUN] = {parse_keyword, NULL, PREC_NONE}, |
@@ -437,7 +470,7 @@ parse_unary(Parser *parser) { | |||
437 | default: break; // Unreachable. | 470 | default: break; // Unreachable. |
438 | } | 471 | } |
439 | if (!node) return; | 472 | if (!node) return; |
440 | node->left = array_pop(parser->nodes); | 473 | node->unary.left = array_pop(parser->nodes); |
441 | array_push(parser->nodes, node, parser->storage); | 474 | array_push(parser->nodes, node, parser->storage); |
442 | } | 475 | } |
443 | 476 | ||
@@ -482,7 +515,7 @@ parse_type(Parser *parser) { | |||
482 | node->kind = NODE_ARR_TYPE, | 515 | node->kind = NODE_ARR_TYPE, |
483 | parse_consume(parser, TOK_NUM_INT, cstr("no array size given")); | 516 | parse_consume(parser, TOK_NUM_INT, cstr("no array size given")); |
484 | parse_number(parser); | 517 | parse_number(parser); |
485 | node->arr_size = array_pop(parser->nodes); | 518 | node->sym.arr_size = array_pop(parser->nodes); |
486 | parse_consume(parser, TOK_RSQUARE, | 519 | parse_consume(parser, TOK_RSQUARE, |
487 | cstr("unmatched brackets ']' in array type")); | 520 | cstr("unmatched brackets ']' in array type")); |
488 | } | 521 | } |
@@ -510,16 +543,16 @@ parse_struct_field(Parser *parser) { | |||
510 | Node *subfield = array_pop(parser->nodes); | 543 | Node *subfield = array_pop(parser->nodes); |
511 | array_push(type->elements, subfield, parser->storage); | 544 | array_push(type->elements, subfield, parser->storage); |
512 | } | 545 | } |
513 | field->field_type = type; | 546 | field->field.type = type; |
514 | } else { | 547 | } else { |
515 | parse_type(parser); | 548 | parse_type(parser); |
516 | field->field_type = array_pop(parser->nodes); | 549 | field->field.type = array_pop(parser->nodes); |
517 | } | 550 | } |
518 | 551 | ||
519 | // Optional assignment. | 552 | // Optional assignment. |
520 | if (parse_match(parser, TOK_ASSIGN)) { | 553 | if (parse_match(parser, TOK_ASSIGN)) { |
521 | parse_expr(parser, PREC_LOW); | 554 | parse_expr(parser, PREC_LOW); |
522 | field->field_val = array_pop(parser->nodes); | 555 | field->field.val = array_pop(parser->nodes); |
523 | } | 556 | } |
524 | array_push(parser->nodes, field, parser->storage); | 557 | array_push(parser->nodes, field, parser->storage); |
525 | } | 558 | } |
@@ -546,10 +579,10 @@ parse_struct_lit_field(Parser *parser) { | |||
546 | Node *subfield = array_pop(parser->nodes); | 579 | Node *subfield = array_pop(parser->nodes); |
547 | array_push(type->elements, subfield, parser->storage); | 580 | array_push(type->elements, subfield, parser->storage); |
548 | } | 581 | } |
549 | field->field_val = type; | 582 | field->field.val = type; |
550 | } else { | 583 | } else { |
551 | parse_expr(parser, PREC_LOW); | 584 | parse_expr(parser, PREC_LOW); |
552 | field->field_val = array_pop(parser->nodes); | 585 | field->field.val = array_pop(parser->nodes); |
553 | } | 586 | } |
554 | array_push(parser->nodes, field, parser->storage); | 587 | array_push(parser->nodes, field, parser->storage); |
555 | } | 588 | } |
@@ -570,8 +603,8 @@ parse_keyword(Parser *parser) { | |||
570 | parse_consume(parser, TOK_SYMBOL, | 603 | parse_consume(parser, TOK_SYMBOL, |
571 | cstr("expected symbol name on let expression")); | 604 | cstr("expected symbol name on let expression")); |
572 | parse_symbol(parser); | 605 | parse_symbol(parser); |
573 | node->var_name = array_pop(parser->nodes); | 606 | node->var.name = array_pop(parser->nodes); |
574 | if (node->var_name->next) { | 607 | if (node->var.name->sym.next) { |
575 | parse_emit_err(parser, prev, | 608 | parse_emit_err(parser, prev, |
576 | cstr("invalid symbol name in let expression")); | 609 | cstr("invalid symbol name in let expression")); |
577 | return; | 610 | return; |
@@ -580,16 +613,16 @@ parse_keyword(Parser *parser) { | |||
580 | // Optional type declaration. | 613 | // Optional type declaration. |
581 | if (parse_match(parser, TOK_COLON)) { | 614 | if (parse_match(parser, TOK_COLON)) { |
582 | parse_type(parser); | 615 | parse_type(parser); |
583 | node->var_type = array_pop(parser->nodes); | 616 | node->var.type = array_pop(parser->nodes); |
584 | } | 617 | } |
585 | 618 | ||
586 | // Optional assignment. | 619 | // Optional assignment. |
587 | if (parse_match(parser, TOK_ASSIGN)) { | 620 | if (parse_match(parser, TOK_ASSIGN)) { |
588 | parse_expr(parser, PREC_LOW); | 621 | parse_expr(parser, PREC_LOW); |
589 | node->var_val = array_pop(parser->nodes); | 622 | node->var.val = array_pop(parser->nodes); |
590 | } | 623 | } |
591 | 624 | ||
592 | if (node->var_type == NULL && node->var_val == NULL) { | 625 | if (node->var.type == NULL && node->var.val == NULL) { |
593 | parse_emit_err(parser, prev, | 626 | parse_emit_err(parser, prev, |
594 | cstr("variable declaration must include type or " | 627 | cstr("variable declaration must include type or " |
595 | "value information")); | 628 | "value information")); |
@@ -599,13 +632,50 @@ parse_keyword(Parser *parser) { | |||
599 | node = node_alloc(parser, NODE_SET, prev); | 632 | node = node_alloc(parser, NODE_SET, prev); |
600 | if (!node) return; | 633 | if (!node) return; |
601 | parse_consume(parser, TOK_SYMBOL, | 634 | parse_consume(parser, TOK_SYMBOL, |
602 | cstr("expected symbol name on let expression")); | 635 | cstr("expected symbol name on set expression")); |
603 | parse_symbol(parser); | 636 | parse_symbol(parser); |
604 | node->var_name = array_pop(parser->nodes); | 637 | node->var.name = array_pop(parser->nodes); |
605 | parse_consume(parser, TOK_ASSIGN, | 638 | |
606 | cstr("expected assignment on set expression")); | 639 | if (parse_match(parser, TOK_ADD_ASSIGN) || |
607 | parse_expr(parser, PREC_LOW); | 640 | parse_match(parser, TOK_ADD_ASSIGN) || |
608 | node->var_val = array_pop(parser->nodes); | 641 | parse_match(parser, TOK_SUB_ASSIGN) || |
642 | parse_match(parser, TOK_MUL_ASSIGN) || | ||
643 | parse_match(parser, TOK_DIV_ASSIGN) || | ||
644 | parse_match(parser, TOK_MOD_ASSIGN) || | ||
645 | parse_match(parser, TOK_BITAND_ASSIGN) || | ||
646 | parse_match(parser, TOK_BITOR_ASSIGN) || | ||
647 | parse_match(parser, TOK_BITXOR_ASSIGN) || | ||
648 | parse_match(parser, TOK_BITLSHIFT_ASSIGN) || | ||
649 | parse_match(parser, TOK_BITRSHIFT_ASSIGN)) { | ||
650 | NodeKind kind = NODE_ERR; | ||
651 | switch (parser->previous.kind) { | ||
652 | case TOK_ADD_ASSIGN: kind = NODE_ADD; break; | ||
653 | case TOK_SUB_ASSIGN: kind = NODE_SUB; break; | ||
654 | case TOK_MUL_ASSIGN: kind = NODE_MUL; break; | ||
655 | case TOK_DIV_ASSIGN: kind = NODE_DIV; break; | ||
656 | case TOK_MOD_ASSIGN: kind = NODE_MOD; break; | ||
657 | case TOK_BITAND_ASSIGN: kind = NODE_BITAND; break; | ||
658 | case TOK_BITOR_ASSIGN: kind = NODE_BITOR; break; | ||
659 | case TOK_BITXOR_ASSIGN: kind = NODE_BITXOR; break; | ||
660 | case TOK_BITLSHIFT_ASSIGN: kind = NODE_BITLSHIFT; break; | ||
661 | case TOK_BITRSHIFT_ASSIGN: kind = NODE_BITRSHIFT; break; | ||
662 | default: break; | ||
663 | } | ||
664 | parse_expr(parser, PREC_LOW); | ||
665 | Node *value = array_pop(parser->nodes); | ||
666 | Node *sym = node_alloc(parser, NODE_SYMBOL, prev); | ||
667 | Node *op = node_alloc(parser, kind, prev); | ||
668 | op->binary.left = sym; | ||
669 | op->binary.right = value; | ||
670 | node->var.val = op; | ||
671 | sym->value = node->var.name->value; | ||
672 | sym->kind = node->var.name->kind; | ||
673 | } else { | ||
674 | parse_consume(parser, TOK_ASSIGN, | ||
675 | cstr("expected assignment on set expression")); | ||
676 | parse_expr(parser, PREC_LOW); | ||
677 | node->var.val = array_pop(parser->nodes); | ||
678 | } | ||
609 | } break; | 679 | } break; |
610 | case TOK_STRUCT: { | 680 | case TOK_STRUCT: { |
611 | node = node_alloc(parser, NODE_STRUCT, prev); | 681 | node = node_alloc(parser, NODE_STRUCT, prev); |
@@ -629,19 +699,19 @@ parse_keyword(Parser *parser) { | |||
629 | node = node_alloc(parser, NODE_IF, prev); | 699 | node = node_alloc(parser, NODE_IF, prev); |
630 | if (!node) return; | 700 | if (!node) return; |
631 | parse_expr(parser, PREC_LOW); | 701 | parse_expr(parser, PREC_LOW); |
632 | node->cond_if = array_pop(parser->nodes); | 702 | node->ifelse.cond = array_pop(parser->nodes); |
633 | parse_expr(parser, PREC_LOW); | 703 | parse_expr(parser, PREC_LOW); |
634 | node->cond_expr = array_pop(parser->nodes); | 704 | node->ifelse.expr_true = array_pop(parser->nodes); |
635 | if (parse_match(parser, TOK_ELSE)) { | 705 | if (parse_match(parser, TOK_ELSE)) { |
636 | parse_expr(parser, PREC_LOW); | 706 | parse_expr(parser, PREC_LOW); |
637 | node->cond_else = array_pop(parser->nodes); | 707 | node->ifelse.expr_else = array_pop(parser->nodes); |
638 | } | 708 | } |
639 | } break; | 709 | } break; |
640 | case TOK_MATCH: { | 710 | case TOK_MATCH: { |
641 | node = node_alloc(parser, NODE_MATCH, prev); | 711 | node = node_alloc(parser, NODE_MATCH, prev); |
642 | if (!node) return; | 712 | if (!node) return; |
643 | parse_expr(parser, PREC_LOW); | 713 | parse_expr(parser, PREC_LOW); |
644 | node->match_expr = array_pop(parser->nodes); | 714 | node->match.expr = array_pop(parser->nodes); |
645 | parse_consume(parser, TOK_LCURLY, | 715 | parse_consume(parser, TOK_LCURLY, |
646 | cstr("expected block of match cases")); | 716 | cstr("expected block of match cases")); |
647 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | 717 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { |
@@ -653,13 +723,13 @@ parse_keyword(Parser *parser) { | |||
653 | parse_consume(parser, TOK_CASE, | 723 | parse_consume(parser, TOK_CASE, |
654 | cstr("expected case statement")); | 724 | cstr("expected case statement")); |
655 | parse_expr(parser, PREC_LOW); | 725 | parse_expr(parser, PREC_LOW); |
656 | tmp->case_value = array_pop(parser->nodes); | 726 | tmp->case_entry.cond = array_pop(parser->nodes); |
657 | } | 727 | } |
658 | parse_consume(parser, TOK_ASSIGN, | 728 | parse_consume(parser, TOK_ASSIGN, |
659 | cstr("malformed case statement")); | 729 | cstr("malformed case statement")); |
660 | parse_expr(parser, PREC_LOW); | 730 | parse_expr(parser, PREC_LOW); |
661 | tmp->case_expr = array_pop(parser->nodes); | 731 | tmp->case_entry.expr = array_pop(parser->nodes); |
662 | array_push(node->match_cases, tmp, parser->storage); | 732 | array_push(node->match.cases, tmp, parser->storage); |
663 | } | 733 | } |
664 | // TODO: Check that we only have literals on the match case, | 734 | // TODO: Check that we only have literals on the match case, |
665 | // this could be done on the analysis step, but also here... | 735 | // this could be done on the analysis step, but also here... |
@@ -683,7 +753,7 @@ parse_keyword(Parser *parser) { | |||
683 | field->value.sym = parser->previous.val; | 753 | field->value.sym = parser->previous.val; |
684 | if (parse_match(parser, TOK_ASSIGN)) { | 754 | if (parse_match(parser, TOK_ASSIGN)) { |
685 | parse_expr(parser, PREC_LOW); | 755 | parse_expr(parser, PREC_LOW); |
686 | field->field_val = array_pop(parser->nodes); | 756 | field->field.val = array_pop(parser->nodes); |
687 | } | 757 | } |
688 | array_push(node->struct_field, field, parser->storage); | 758 | array_push(node->struct_field, field, parser->storage); |
689 | } | 759 | } |
@@ -703,13 +773,13 @@ parse_keyword(Parser *parser) { | |||
703 | // Are we on the default case. | 773 | // Are we on the default case. |
704 | if (!parse_match(parser, TOK_ELSE)) { | 774 | if (!parse_match(parser, TOK_ELSE)) { |
705 | parse_expr(parser, PREC_LOW); | 775 | parse_expr(parser, PREC_LOW); |
706 | tmp->case_value = array_pop(parser->nodes); | 776 | tmp->case_entry.cond = array_pop(parser->nodes); |
707 | } | 777 | } |
708 | parse_consume(parser, TOK_ASSIGN, | 778 | parse_consume(parser, TOK_ASSIGN, |
709 | cstr("malformed case statement")); | 779 | cstr("malformed case statement")); |
710 | parse_expr(parser, PREC_LOW); | 780 | parse_expr(parser, PREC_LOW); |
711 | tmp->case_expr = array_pop(parser->nodes); | 781 | tmp->case_entry.expr = array_pop(parser->nodes); |
712 | array_push(node->match_cases, tmp, parser->storage); | 782 | array_push(node->match.cases, tmp, parser->storage); |
713 | } | 783 | } |
714 | } break; | 784 | } break; |
715 | case TOK_BREAK: { | 785 | case TOK_BREAK: { |
@@ -720,13 +790,47 @@ parse_keyword(Parser *parser) { | |||
720 | node = node_alloc(parser, NODE_CONTINUE, prev); | 790 | node = node_alloc(parser, NODE_CONTINUE, prev); |
721 | if (!node) return; | 791 | if (!node) return; |
722 | } break; | 792 | } break; |
793 | case TOK_FOR: { | ||
794 | node = node_alloc(parser, NODE_BLOCK, prev); | ||
795 | if (!node) return; | ||
796 | |||
797 | Node *node_while = node_alloc(parser, NODE_WHILE, prev); | ||
798 | if (!node_while) return; | ||
799 | Node *block = node_alloc(parser, NODE_BLOCK, prev); | ||
800 | if (!block) return; | ||
801 | |||
802 | parse_expr(parser, PREC_LOW); | ||
803 | Node *pre = array_pop(parser->nodes); | ||
804 | |||
805 | parse_expr(parser, PREC_LOW); | ||
806 | Node *cond = array_pop(parser->nodes); | ||
807 | |||
808 | parse_expr(parser, PREC_LOW); | ||
809 | Node *post = array_pop(parser->nodes); | ||
810 | |||
811 | // Body. | ||
812 | parse_consume(parser, TOK_LCURLY, | ||
813 | cstr("expected '{' on for loop statement")); | ||
814 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | ||
815 | parse_expr(parser, PREC_LOW); | ||
816 | Node *next = array_pop(parser->nodes); | ||
817 | array_push(block->statements, next, parser->storage); | ||
818 | } | ||
819 | array_push(block->statements, post, parser->storage); | ||
820 | |||
821 | // Put everything together | ||
822 | node_while->loop.cond = cond; | ||
823 | node_while->loop.expr = block; | ||
824 | array_push(node->statements, pre, parser->storage); | ||
825 | array_push(node->statements, node_while, parser->storage); | ||
826 | } break; | ||
723 | case TOK_WHILE: { | 827 | case TOK_WHILE: { |
724 | node = node_alloc(parser, NODE_WHILE, prev); | 828 | node = node_alloc(parser, NODE_WHILE, prev); |
725 | if (!node) return; | 829 | if (!node) return; |
726 | parse_expr(parser, PREC_LOW); | 830 | parse_expr(parser, PREC_LOW); |
727 | node->while_cond = array_pop(parser->nodes); | 831 | node->loop.cond = array_pop(parser->nodes); |
728 | parse_expr(parser, PREC_LOW); | 832 | parse_expr(parser, PREC_LOW); |
729 | node->while_expr = array_pop(parser->nodes); | 833 | node->loop.expr = array_pop(parser->nodes); |
730 | } break; | 834 | } break; |
731 | case TOK_FUN: { | 835 | case TOK_FUN: { |
732 | node = node_alloc(parser, NODE_FUN, prev); | 836 | node = node_alloc(parser, NODE_FUN, prev); |
@@ -735,7 +839,7 @@ parse_keyword(Parser *parser) { | |||
735 | Node *name = node_alloc(parser, NODE_SYMBOL, prev); | 839 | Node *name = node_alloc(parser, NODE_SYMBOL, prev); |
736 | if (!name) return; | 840 | if (!name) return; |
737 | name->value.sym = parser->previous.val; | 841 | name->value.sym = parser->previous.val; |
738 | node->func_name = name; | 842 | node->func.name = name; |
739 | parse_consume(parser, TOK_LPAREN, | 843 | parse_consume(parser, TOK_LPAREN, |
740 | cstr("expected '(' on function definition")); | 844 | cstr("expected '(' on function definition")); |
741 | // Parameters. | 845 | // Parameters. |
@@ -747,7 +851,7 @@ parse_keyword(Parser *parser) { | |||
747 | if (!name) return; | 851 | if (!name) return; |
748 | parse_consume(parser, TOK_SYMBOL, cstr("expected symbol name")); | 852 | parse_consume(parser, TOK_SYMBOL, cstr("expected symbol name")); |
749 | name->value.sym = parser->previous.val; | 853 | name->value.sym = parser->previous.val; |
750 | param->param_name = name; | 854 | param->param.name = name; |
751 | 855 | ||
752 | Node *type = node_alloc(parser, NODE_TYPE, prev); | 856 | Node *type = node_alloc(parser, NODE_TYPE, prev); |
753 | if (!type) return; | 857 | if (!type) return; |
@@ -757,17 +861,17 @@ parse_keyword(Parser *parser) { | |||
757 | } | 861 | } |
758 | parse_consume(parser, TOK_SYMBOL, cstr("expected param type")); | 862 | parse_consume(parser, TOK_SYMBOL, cstr("expected param type")); |
759 | type->value.sym = parser->previous.val; | 863 | type->value.sym = parser->previous.val; |
760 | param->param_type = type; | 864 | param->param.type = type; |
761 | if (parse_match(parser, TOK_LSQUARE)) { | 865 | if (parse_match(parser, TOK_LSQUARE)) { |
762 | type->kind = NODE_ARR_TYPE, | 866 | type->kind = NODE_ARR_TYPE, |
763 | parse_consume(parser, TOK_NUM_INT, | 867 | parse_consume(parser, TOK_NUM_INT, |
764 | cstr("no array size given")); | 868 | cstr("no array size given")); |
765 | parse_number(parser); | 869 | parse_number(parser); |
766 | type->arr_size = array_pop(parser->nodes); | 870 | type->sym.arr_size = array_pop(parser->nodes); |
767 | parse_consume(parser, TOK_RSQUARE, | 871 | parse_consume(parser, TOK_RSQUARE, |
768 | cstr("unmatched brackets ']' in array type")); | 872 | cstr("unmatched brackets ']' in array type")); |
769 | } | 873 | } |
770 | array_push(node->func_params, param, parser->storage); | 874 | array_push(node->func.params, param, parser->storage); |
771 | } | 875 | } |
772 | parse_consume(parser, TOK_COLON, cstr("expected param type")); | 876 | parse_consume(parser, TOK_COLON, cstr("expected param type")); |
773 | 877 | ||
@@ -788,12 +892,12 @@ parse_keyword(Parser *parser) { | |||
788 | parse_consume(parser, TOK_NUM_INT, | 892 | parse_consume(parser, TOK_NUM_INT, |
789 | cstr("no array size given")); | 893 | cstr("no array size given")); |
790 | parse_number(parser); | 894 | parse_number(parser); |
791 | ret->arr_size = array_pop(parser->nodes); | 895 | ret->sym.arr_size = array_pop(parser->nodes); |
792 | parse_consume(parser, TOK_RSQUARE, | 896 | parse_consume(parser, TOK_RSQUARE, |
793 | cstr("unmatched brackets ']' in " | 897 | cstr("unmatched brackets ']' in " |
794 | "array type")); | 898 | "array type")); |
795 | } | 899 | } |
796 | array_push(node->func_ret, ret, parser->storage); | 900 | array_push(node->func.ret, ret, parser->storage); |
797 | } | 901 | } |
798 | } else { | 902 | } else { |
799 | Node *ret = node_alloc(parser, NODE_TYPE, prev); | 903 | Node *ret = node_alloc(parser, NODE_TYPE, prev); |
@@ -809,18 +913,18 @@ parse_keyword(Parser *parser) { | |||
809 | parse_consume(parser, TOK_NUM_INT, | 913 | parse_consume(parser, TOK_NUM_INT, |
810 | cstr("no array size given")); | 914 | cstr("no array size given")); |
811 | parse_number(parser); | 915 | parse_number(parser); |
812 | ret->arr_size = array_pop(parser->nodes); | 916 | ret->sym.arr_size = array_pop(parser->nodes); |
813 | parse_consume( | 917 | parse_consume( |
814 | parser, TOK_RSQUARE, | 918 | parser, TOK_RSQUARE, |
815 | cstr("unmatched brackets ']' in array type")); | 919 | cstr("unmatched brackets ']' in array type")); |
816 | } | 920 | } |
817 | array_push(node->func_ret, ret, parser->storage); | 921 | array_push(node->func.ret, ret, parser->storage); |
818 | } | 922 | } |
819 | } | 923 | } |
820 | 924 | ||
821 | // Body. | 925 | // Body. |
822 | parse_expr(parser, PREC_LOW); | 926 | parse_expr(parser, PREC_LOW); |
823 | node->func_body = array_pop(parser->nodes); | 927 | node->func.body = array_pop(parser->nodes); |
824 | } break; | 928 | } break; |
825 | case TOK_RETURN: { | 929 | case TOK_RETURN: { |
826 | node = node_alloc(parser, NODE_RETURN, prev); | 930 | node = node_alloc(parser, NODE_RETURN, prev); |
@@ -870,6 +974,9 @@ parse_binary(Parser *parser) { | |||
870 | case TOK_BITOR: { | 974 | case TOK_BITOR: { |
871 | node = node_alloc(parser, NODE_BITOR, prev); | 975 | node = node_alloc(parser, NODE_BITOR, prev); |
872 | } break; | 976 | } break; |
977 | case TOK_BITXOR: { | ||
978 | node = node_alloc(parser, NODE_BITXOR, prev); | ||
979 | } break; | ||
873 | case TOK_BITLSHIFT: { | 980 | case TOK_BITLSHIFT: { |
874 | node = node_alloc(parser, NODE_BITLSHIFT, prev); | 981 | node = node_alloc(parser, NODE_BITLSHIFT, prev); |
875 | } break; | 982 | } break; |
@@ -882,8 +989,8 @@ parse_binary(Parser *parser) { | |||
882 | } | 989 | } |
883 | } | 990 | } |
884 | if (!node) return; | 991 | if (!node) return; |
885 | node->right = array_pop(parser->nodes); | 992 | node->binary.right = array_pop(parser->nodes); |
886 | node->left = array_pop(parser->nodes); | 993 | node->binary.left = array_pop(parser->nodes); |
887 | array_push(parser->nodes, node, parser->storage); | 994 | array_push(parser->nodes, node, parser->storage); |
888 | } | 995 | } |
889 | 996 | ||
@@ -965,7 +1072,7 @@ parse_symbol(Parser *parser) { | |||
965 | parse_consume(parser, TOK_SYMBOL, | 1072 | parse_consume(parser, TOK_SYMBOL, |
966 | cstr("expected symbol after '.' operator")); | 1073 | cstr("expected symbol after '.' operator")); |
967 | parse_symbol(parser); | 1074 | parse_symbol(parser); |
968 | node->next = array_pop(parser->nodes); | 1075 | node->sym.next = array_pop(parser->nodes); |
969 | } else if (parser->current.kind == TOK_COLON && | 1076 | } else if (parser->current.kind == TOK_COLON && |
970 | parse_peek(parser) == TOK_LCURLY) { | 1077 | parse_peek(parser) == TOK_LCURLY) { |
971 | parse_advance(parser); | 1078 | parse_advance(parser); |
@@ -981,7 +1088,7 @@ parse_symbol(Parser *parser) { | |||
981 | } else if (parse_match(parser, TOK_LSQUARE)) { | 1088 | } else if (parse_match(parser, TOK_LSQUARE)) { |
982 | node->kind = NODE_SYMBOL_IDX; | 1089 | node->kind = NODE_SYMBOL_IDX; |
983 | parse_expr(parser, PREC_LOW); | 1090 | parse_expr(parser, PREC_LOW); |
984 | node->arr_size = array_pop(parser->nodes); | 1091 | node->sym.arr_size = array_pop(parser->nodes); |
985 | parse_consume(parser, TOK_RSQUARE, | 1092 | parse_consume(parser, TOK_RSQUARE, |
986 | cstr("unmatched brackets ']' in array type")); | 1093 | cstr("unmatched brackets ']' in array type")); |
987 | if (parse_match(parser, TOK_DOT)) { | 1094 | if (parse_match(parser, TOK_DOT)) { |
@@ -989,7 +1096,7 @@ parse_symbol(Parser *parser) { | |||
989 | parse_consume(parser, TOK_SYMBOL, | 1096 | parse_consume(parser, TOK_SYMBOL, |
990 | cstr("expected symbol after '.' operator")); | 1097 | cstr("expected symbol after '.' operator")); |
991 | parse_symbol(parser); | 1098 | parse_symbol(parser); |
992 | node->next = array_pop(parser->nodes); | 1099 | node->sym.next = array_pop(parser->nodes); |
993 | } | 1100 | } |
994 | } else if (parse_match(parser, TOK_LPAREN)) { | 1101 | } else if (parse_match(parser, TOK_LPAREN)) { |
995 | node->kind = NODE_FUNCALL; | 1102 | node->kind = NODE_FUNCALL; |
@@ -1003,7 +1110,7 @@ parse_symbol(Parser *parser) { | |||
1003 | parse_consume(parser, TOK_SYMBOL, | 1110 | parse_consume(parser, TOK_SYMBOL, |
1004 | cstr("expected symbol after '.' operator")); | 1111 | cstr("expected symbol after '.' operator")); |
1005 | parse_symbol(parser); | 1112 | parse_symbol(parser); |
1006 | node->next = array_pop(parser->nodes); | 1113 | node->sym.next = array_pop(parser->nodes); |
1007 | } | 1114 | } |
1008 | } | 1115 | } |
1009 | node->value.sym = prev.val; | 1116 | node->value.sym = prev.val; |
@@ -1051,43 +1158,43 @@ graph_node(Node *node) { | |||
1051 | if (node->type.size > 0) { | 1158 | if (node->type.size > 0) { |
1052 | print("| Type: %s", node->type); | 1159 | print("| Type: %s", node->type); |
1053 | } | 1160 | } |
1054 | if (node->fun_params.size > 0) { | 1161 | if (node->type_params.size > 0) { |
1055 | print("| Params: %s", node->fun_params); | 1162 | print("| Params: %s", node->type_params); |
1056 | } | 1163 | } |
1057 | if (node->fun_return.size > 0) { | 1164 | if (node->type_returns.size > 0) { |
1058 | print("| Return: %s", node->fun_return); | 1165 | print("| Return: %s", node->type_returns); |
1059 | } | 1166 | } |
1060 | println("\"];"); | 1167 | println("\"];"); |
1061 | 1168 | ||
1062 | switch (node->kind) { | 1169 | switch (node->kind) { |
1063 | case NODE_FUN: { | 1170 | case NODE_FUN: { |
1064 | for (sz i = 0; i < array_size(node->func_params); i++) { | 1171 | for (sz i = 0; i < array_size(node->func.params); i++) { |
1065 | Node *next = node->func_params[i]; | 1172 | Node *next = node->func.params[i]; |
1066 | println("%d:e->%d:w;", node->id, next->id); | 1173 | println("%d:e->%d:w;", node->id, next->id); |
1067 | graph_node(next); | 1174 | graph_node(next); |
1068 | } | 1175 | } |
1069 | for (sz i = 0; i < array_size(node->func_ret); i++) { | 1176 | for (sz i = 0; i < array_size(node->func.ret); i++) { |
1070 | Node *next = node->func_ret[i]; | 1177 | Node *next = node->func.ret[i]; |
1071 | println("%d:e->%d:w;", node->id, next->id); | 1178 | println("%d:e->%d:w;", node->id, next->id); |
1072 | graph_node(next); | 1179 | graph_node(next); |
1073 | } | 1180 | } |
1074 | if (node->func_name) { | 1181 | if (node->func.name) { |
1075 | println("%d:e->%d:w;", node->id, node->func_name->id); | 1182 | println("%d:e->%d:w;", node->id, node->func.name->id); |
1076 | graph_node(node->func_name); | 1183 | graph_node(node->func.name); |
1077 | } | 1184 | } |
1078 | if (node->func_body) { | 1185 | if (node->func.body) { |
1079 | println("%d:e->%d:w;", node->id, node->func_body->id); | 1186 | println("%d:e->%d:w;", node->id, node->func.body->id); |
1080 | graph_node(node->func_body); | 1187 | graph_node(node->func.body); |
1081 | } | 1188 | } |
1082 | } break; | 1189 | } break; |
1083 | case NODE_COND: | 1190 | case NODE_COND: |
1084 | case NODE_MATCH: { | 1191 | case NODE_MATCH: { |
1085 | if (node->match_expr) { | 1192 | if (node->match.expr) { |
1086 | println("%d:e->%d:w;", node->id, node->match_expr->id); | 1193 | println("%d:e->%d:w;", node->id, node->match.expr->id); |
1087 | graph_node(node->match_expr); | 1194 | graph_node(node->match.expr); |
1088 | } | 1195 | } |
1089 | for (sz i = 0; i < array_size(node->match_cases); i++) { | 1196 | for (sz i = 0; i < array_size(node->match.cases); i++) { |
1090 | Node *next = node->match_cases[i]; | 1197 | Node *next = node->match.cases[i]; |
1091 | println("%d:e->%d:w;", node->id, next->id); | 1198 | println("%d:e->%d:w;", node->id, next->id); |
1092 | graph_node(next); | 1199 | graph_node(next); |
1093 | } | 1200 | } |
@@ -1112,43 +1219,43 @@ graph_node(Node *node) { | |||
1112 | } | 1219 | } |
1113 | } break; | 1220 | } break; |
1114 | case NODE_IF: { | 1221 | case NODE_IF: { |
1115 | if (node->cond_if) { | 1222 | if (node->ifelse.cond) { |
1116 | println("%d:e->%d:w;", node->id, node->cond_if->id); | 1223 | println("%d:e->%d:w;", node->id, node->ifelse.cond->id); |
1117 | graph_node(node->cond_if); | 1224 | graph_node(node->ifelse.cond); |
1118 | } | 1225 | } |
1119 | if (node->cond_expr) { | 1226 | if (node->ifelse.expr_true) { |
1120 | println("%d:e->%d:w;", node->id, node->cond_expr->id); | 1227 | println("%d:e->%d:w;", node->id, node->ifelse.expr_true->id); |
1121 | graph_node(node->cond_expr); | 1228 | graph_node(node->ifelse.expr_true); |
1122 | } | 1229 | } |
1123 | if (node->cond_else) { | 1230 | if (node->ifelse.expr_else) { |
1124 | println("%d:e->%d:w;", node->id, node->cond_else->id); | 1231 | println("%d:e->%d:w;", node->id, node->ifelse.expr_else->id); |
1125 | graph_node(node->cond_else); | 1232 | graph_node(node->ifelse.expr_else); |
1126 | } | 1233 | } |
1127 | } break; | 1234 | } break; |
1128 | case NODE_FIELD: | 1235 | case NODE_FIELD: |
1129 | case NODE_SET: | 1236 | case NODE_SET: |
1130 | case NODE_LET: { | 1237 | case NODE_LET: { |
1131 | if (node->var_name) { | 1238 | if (node->var.name) { |
1132 | println("%d:e->%d:w;", node->id, node->var_name->id); | 1239 | println("%d:e->%d:w;", node->id, node->var.name->id); |
1133 | graph_node(node->var_name); | 1240 | graph_node(node->var.name); |
1134 | } | 1241 | } |
1135 | if (node->var_type) { | 1242 | if (node->var.type) { |
1136 | println("%d:e->%d:w;", node->id, node->var_type->id); | 1243 | println("%d:e->%d:w;", node->id, node->var.type->id); |
1137 | graph_node(node->var_type); | 1244 | graph_node(node->var.type); |
1138 | } | 1245 | } |
1139 | if (node->var_val) { | 1246 | if (node->var.val) { |
1140 | println("%d:e->%d:w;", node->id, node->var_val->id); | 1247 | println("%d:e->%d:w;", node->id, node->var.val->id); |
1141 | graph_node(node->var_val); | 1248 | graph_node(node->var.val); |
1142 | } | 1249 | } |
1143 | } break; | 1250 | } break; |
1144 | default: { | 1251 | default: { |
1145 | if (node->left) { | 1252 | if (node->binary.left) { |
1146 | println("%d:e->%d:w;", node->id, node->left->id); | 1253 | println("%d:e->%d:w;", node->id, node->binary.left->id); |
1147 | graph_node(node->left); | 1254 | graph_node(node->binary.left); |
1148 | } | 1255 | } |
1149 | if (node->right) { | 1256 | if (node->binary.right) { |
1150 | println("%d:e->%d:w;", node->id, node->right->id); | 1257 | println("%d:e->%d:w;", node->id, node->binary.right->id); |
1151 | graph_node(node->right); | 1258 | graph_node(node->binary.right); |
1152 | } | 1259 | } |
1153 | } break; | 1260 | } break; |
1154 | } | 1261 | } |