| author | |
| committer | |
| log | 7dd55a8007c540415d3e704e490609dd86bea924 |
| tree | b3d45596525808eafbbff203bb54a8f5eb2516ac |
| parent | e24409ebe0f50be9e01810a5f61bb4c09db57d28 |
2 files changed, 318 insertions(+), 32 deletions(-)
std/zig/ast.zig+134-14| ... | @@ -20,12 +20,15 @@ pub const Node = struct { | ... | @@ -20,12 +20,15 @@ pub const Node = struct { |
| 20 | FnProto, | 20 | FnProto, |
| 21 | ParamDecl, | 21 | ParamDecl, |
| 22 | Block, | 22 | Block, |
| 23 | Payload, | 23 | ErrorPayload, |
| 24 | ValuePayload, | ||
| 25 | ValueIndexPayload, | ||
| 24 | Else, | 26 | Else, |
| 25 | Switch, | 27 | Switch, |
| 26 | SwitchCase, | 28 | SwitchCase, |
| 27 | SwitchElse, | 29 | SwitchElse, |
| 28 | While, | 30 | While, |
| 31 | For, | ||
| 29 | InfixOp, | 32 | InfixOp, |
| 30 | PrefixOp, | 33 | PrefixOp, |
| 31 | SuffixOp, | 34 | SuffixOp, |
| ... | @@ -61,12 +64,15 @@ pub const Node = struct { | ... | @@ -61,12 +64,15 @@ pub const Node = struct { |
| 61 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index), | 64 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index), |
| 62 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index), | 65 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index), |
| 63 | Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index), | 66 | Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index), |
| 64 | Id.Payload => @fieldParentPtr(NodePayload, "base", base).iterate(index), | 67 | Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).iterate(index), |
| 68 | Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).iterate(index), | ||
| 69 | Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).iterate(index), | ||
| 65 | Id.Else => @fieldParentPtr(NodeSwitch, "base", base).iterate(index), | 70 | Id.Else => @fieldParentPtr(NodeSwitch, "base", base).iterate(index), |
| 66 | Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).iterate(index), | 71 | Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).iterate(index), |
| 67 | Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).iterate(index), | 72 | Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).iterate(index), |
| 68 | Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).iterate(index), | 73 | Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).iterate(index), |
| 69 | Id.While => @fieldParentPtr(NodeWhile, "base", base).iterate(index), | 74 | Id.While => @fieldParentPtr(NodeWhile, "base", base).iterate(index), |
| 75 | Id.For => @fieldParentPtr(NodeFor, "base", base).iterate(index), | ||
| 70 | Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index), | 76 | Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index), |
| 71 | Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index), | 77 | Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index), |
| 72 | Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index), | 78 | Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index), |
| ... | @@ -103,12 +109,15 @@ pub const Node = struct { | ... | @@ -103,12 +109,15 @@ pub const Node = struct { |
| 103 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(), | 109 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(), |
| 104 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(), | 110 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(), |
| 105 | Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(), | 111 | Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(), |
| 106 | Id.Payload => @fieldParentPtr(NodePayload, "base", base).firstToken(), | 112 | Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).firstToken(), |
| 113 | Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).firstToken(), | ||
| 114 | Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).firstToken(), | ||
| 107 | Id.Else => @fieldParentPtr(NodeSwitch, "base", base).firstToken(), | 115 | Id.Else => @fieldParentPtr(NodeSwitch, "base", base).firstToken(), |
| 108 | Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).firstToken(), | 116 | Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).firstToken(), |
| 109 | Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).firstToken(), | 117 | Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).firstToken(), |
| 110 | Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).firstToken(), | 118 | Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).firstToken(), |
| 111 | Id.While => @fieldParentPtr(NodeWhile, "base", base).firstToken(), | 119 | Id.While => @fieldParentPtr(NodeWhile, "base", base).firstToken(), |
| 120 | Id.For => @fieldParentPtr(NodeFor, "base", base).firstToken(), | ||
| 112 | Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(), | 121 | Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(), |
| 113 | Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(), | 122 | Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(), |
| 114 | Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(), | 123 | Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(), |
| ... | @@ -145,12 +154,15 @@ pub const Node = struct { | ... | @@ -145,12 +154,15 @@ pub const Node = struct { |
| 145 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(), | 154 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(), |
| 146 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(), | 155 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(), |
| 147 | Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(), | 156 | Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(), |
| 148 | Id.Payload => @fieldParentPtr(NodePayload, "base", base).lastToken(), | 157 | Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).lastToken(), |
| 158 | Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).lastToken(), | ||
| 159 | Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).lastToken(), | ||
| 149 | Id.Else => @fieldParentPtr(NodeElse, "base", base).lastToken(), | 160 | Id.Else => @fieldParentPtr(NodeElse, "base", base).lastToken(), |
| 150 | Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).lastToken(), | 161 | Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).lastToken(), |
| 151 | Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).lastToken(), | 162 | Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).lastToken(), |
| 152 | Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).lastToken(), | 163 | Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).lastToken(), |
| 153 | Id.While => @fieldParentPtr(NodeWhile, "base", base).lastToken(), | 164 | Id.While => @fieldParentPtr(NodeWhile, "base", base).lastToken(), |
| 165 | Id.For => @fieldParentPtr(NodeFor, "base", base).lastToken(), | ||
| 154 | Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(), | 166 | Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(), |
| 155 | Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(), | 167 | Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(), |
| 156 | Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(), | 168 | Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(), |
| ... | @@ -557,27 +569,82 @@ pub const NodeBlock = struct { | ... | @@ -557,27 +569,82 @@ pub const NodeBlock = struct { |
| 557 | } | 569 | } |
| 558 | }; | 570 | }; |
| 559 | 571 | ||
| 560 | pub const NodePayload = struct { | 572 | pub const NodeErrorPayload = struct { |
| 573 | base: Node, | ||
| 574 | lpipe: Token, | ||
| 575 | error_symbol: &NodeIdentifier, | ||
| 576 | rpipe: Token, | ||
| 577 | |||
| 578 | pub fn iterate(self: &NodeErrorPayload, index: usize) ?&Node { | ||
| 579 | var i = index; | ||
| 580 | |||
| 581 | if (i < 1) return &self.error_symbol.base; | ||
| 582 | i -= 1; | ||
| 583 | |||
| 584 | return null; | ||
| 585 | } | ||
| 586 | |||
| 587 | pub fn firstToken(self: &NodeErrorPayload) Token { | ||
| 588 | return self.lpipe; | ||
| 589 | } | ||
| 590 | |||
| 591 | pub fn lastToken(self: &NodeErrorPayload) Token { | ||
| 592 | return self.rpipe; | ||
| 593 | } | ||
| 594 | }; | ||
| 595 | |||
| 596 | pub const NodeValuePayload = struct { | ||
| 597 | base: Node, | ||
| 598 | lpipe: Token, | ||
| 599 | is_ptr: bool, | ||
| 600 | value_symbol: &NodeIdentifier, | ||
| 601 | rpipe: Token, | ||
| 602 | |||
| 603 | pub fn iterate(self: &NodeValuePayload, index: usize) ?&Node { | ||
| 604 | var i = index; | ||
| 605 | |||
| 606 | if (i < 1) return &self.value_symbol.base; | ||
| 607 | i -= 1; | ||
| 608 | |||
| 609 | return null; | ||
| 610 | } | ||
| 611 | |||
| 612 | pub fn firstToken(self: &NodeValuePayload) Token { | ||
| 613 | return self.lpipe; | ||
| 614 | } | ||
| 615 | |||
| 616 | pub fn lastToken(self: &NodeValuePayload) Token { | ||
| 617 | return self.rpipe; | ||
| 618 | } | ||
| 619 | }; | ||
| 620 | |||
| 621 | pub const NodeValueIndexPayload = struct { | ||
| 561 | base: Node, | 622 | base: Node, |
| 562 | lpipe: Token, | 623 | lpipe: Token, |
| 563 | is_ptr: bool, | 624 | is_ptr: bool, |
| 564 | symbol: &NodeIdentifier, | 625 | value_symbol: &NodeIdentifier, |
| 626 | index_symbol: ?&NodeIdentifier, | ||
| 565 | rpipe: Token, | 627 | rpipe: Token, |
| 566 | 628 | ||
| 567 | pub fn iterate(self: &NodePayload, index: usize) ?&Node { | 629 | pub fn iterate(self: &NodeValueIndexPayload, index: usize) ?&Node { |
| 568 | var i = index; | 630 | var i = index; |
| 569 | 631 | ||
| 570 | if (i < 1) return &self.symbol.base; | 632 | if (i < 1) return &self.value_symbol.base; |
| 571 | i -= 1; | 633 | i -= 1; |
| 572 | 634 | ||
| 635 | if (self.index_symbol) |index_symbol| { | ||
| 636 | if (i < 1) return &index_symbol.base; | ||
| 637 | i -= 1; | ||
| 638 | } | ||
| 639 | |||
| 573 | return null; | 640 | return null; |
| 574 | } | 641 | } |
| 575 | 642 | ||
| 576 | pub fn firstToken(self: &NodePayload) Token { | 643 | pub fn firstToken(self: &NodeValueIndexPayload) Token { |
| 577 | return self.lpipe; | 644 | return self.lpipe; |
| 578 | } | 645 | } |
| 579 | 646 | ||
| 580 | pub fn lastToken(self: &NodePayload) Token { | 647 | pub fn lastToken(self: &NodeValueIndexPayload) Token { |
| 581 | return self.rpipe; | 648 | return self.rpipe; |
| 582 | } | 649 | } |
| 583 | }; | 650 | }; |
| ... | @@ -585,7 +652,7 @@ pub const NodePayload = struct { | ... | @@ -585,7 +652,7 @@ pub const NodePayload = struct { |
| 585 | pub const NodeElse = struct { | 652 | pub const NodeElse = struct { |
| 586 | base: Node, | 653 | base: Node, |
| 587 | else_token: Token, | 654 | else_token: Token, |
| 588 | payload: ?&NodePayload, | 655 | payload: ?&NodeErrorPayload, |
| 589 | body: &Node, | 656 | body: &Node, |
| 590 | 657 | ||
| 591 | pub fn iterate(self: &NodeElse, index: usize) ?&Node { | 658 | pub fn iterate(self: &NodeElse, index: usize) ?&Node { |
| ... | @@ -642,7 +709,7 @@ pub const NodeSwitch = struct { | ... | @@ -642,7 +709,7 @@ pub const NodeSwitch = struct { |
| 642 | pub const NodeSwitchCase = struct { | 709 | pub const NodeSwitchCase = struct { |
| 643 | base: Node, | 710 | base: Node, |
| 644 | items: ArrayList(&Node), | 711 | items: ArrayList(&Node), |
| 645 | payload: ?&NodePayload, | 712 | payload: ?&NodeValuePayload, |
| 646 | expr: &Node, | 713 | expr: &Node, |
| 647 | 714 | ||
| 648 | pub fn iterate(self: &NodeSwitchCase, index: usize) ?&Node { | 715 | pub fn iterate(self: &NodeSwitchCase, index: usize) ?&Node { |
| ... | @@ -694,7 +761,7 @@ pub const NodeWhile = struct { | ... | @@ -694,7 +761,7 @@ pub const NodeWhile = struct { |
| 694 | inline_token: ?Token, | 761 | inline_token: ?Token, |
| 695 | while_token: Token, | 762 | while_token: Token, |
| 696 | condition: &Node, | 763 | condition: &Node, |
| 697 | payload: ?&NodePayload, | 764 | payload: ?&NodeValuePayload, |
| 698 | continue_expr: ?&Node, | 765 | continue_expr: ?&Node, |
| 699 | body: &Node, | 766 | body: &Node, |
| 700 | @"else": ?&NodeElse, | 767 | @"else": ?&NodeElse, |
| ... | @@ -747,6 +814,59 @@ pub const NodeWhile = struct { | ... | @@ -747,6 +814,59 @@ pub const NodeWhile = struct { |
| 747 | } | 814 | } |
| 748 | }; | 815 | }; |
| 749 | 816 | ||
| 817 | pub const NodeFor = struct { | ||
| 818 | base: Node, | ||
| 819 | label: ?Token, | ||
| 820 | inline_token: ?Token, | ||
| 821 | for_token: Token, | ||
| 822 | array_expr: &Node, | ||
| 823 | payload: ?&NodeValueIndexPayload, | ||
| 824 | body: &Node, | ||
| 825 | @"else": ?&NodeElse, | ||
| 826 | |||
| 827 | pub fn iterate(self: &NodeFor, index: usize) ?&Node { | ||
| 828 | var i = index; | ||
| 829 | |||
| 830 | if (i < 1) return self.array_expr; | ||
| 831 | i -= 1; | ||
| 832 | |||
| 833 | if (self.payload) |payload| { | ||
| 834 | if (i < 1) return &payload.base; | ||
| 835 | i -= 1; | ||
| 836 | } | ||
| 837 | |||
| 838 | if (i < 1) return self.body; | ||
| 839 | i -= 1; | ||
| 840 | |||
| 841 | if (self.@"else") |@"else"| { | ||
| 842 | if (i < 1) return &@"else".base; | ||
| 843 | i -= 1; | ||
| 844 | } | ||
| 845 | |||
| 846 | return null; | ||
| 847 | } | ||
| 848 | |||
| 849 | pub fn firstToken(self: &NodeFor) Token { | ||
| 850 | if (self.label) |label| { | ||
| 851 | return label; | ||
| 852 | } | ||
| 853 | |||
| 854 | if (self.inline_token) |inline_token| { | ||
| 855 | return inline_token; | ||
| 856 | } | ||
| 857 | |||
| 858 | return self.for_token; | ||
| 859 | } | ||
| 860 | |||
| 861 | pub fn lastToken(self: &NodeFor) Token { | ||
| 862 | if (self.@"else") |@"else"| { | ||
| 863 | return @"else".body.lastToken(); | ||
| 864 | } | ||
| 865 | |||
| 866 | return self.body.lastToken(); | ||
| 867 | } | ||
| 868 | }; | ||
| 869 | |||
| 750 | pub const NodeInfixOp = struct { | 870 | pub const NodeInfixOp = struct { |
| 751 | base: Node, | 871 | base: Node, |
| 752 | op_token: Token, | 872 | op_token: Token, |
| ... | @@ -781,7 +901,7 @@ pub const NodeInfixOp = struct { | ... | @@ -781,7 +901,7 @@ pub const NodeInfixOp = struct { |
| 781 | BitXor, | 901 | BitXor, |
| 782 | BoolAnd, | 902 | BoolAnd, |
| 783 | BoolOr, | 903 | BoolOr, |
| 784 | Catch: ?&NodePayload, | 904 | Catch: ?&NodeErrorPayload, |
| 785 | Div, | 905 | Div, |
| 786 | EqualEqual, | 906 | EqualEqual, |
| 787 | ErrorUnion, | 907 | ErrorUnion, |
std/zig/parser.zig+184-18| ... | @@ -170,7 +170,9 @@ pub const Parser = struct { | ... | @@ -170,7 +170,9 @@ pub const Parser = struct { |
| 170 | FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer), | 170 | FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer), |
| 171 | FieldListCommaOrEnd: &ast.NodeContainerDecl, | 171 | FieldListCommaOrEnd: &ast.NodeContainerDecl, |
| 172 | SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase), | 172 | SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase), |
| 173 | Payload: &?&ast.NodePayload, | 173 | ErrorPayload: &?&ast.NodeErrorPayload, |
| 174 | ValuePayload: &?&ast.NodeValuePayload, | ||
| 175 | ValueIndexPayload: &?&ast.NodeValueIndexPayload, | ||
| 174 | SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase), | 176 | SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase), |
| 175 | SwitchCaseItem: &ArrayList(&ast.Node), | 177 | SwitchCaseItem: &ArrayList(&ast.Node), |
| 176 | SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node), | 178 | SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node), |
| ... | @@ -769,7 +771,7 @@ pub const Parser = struct { | ... | @@ -769,7 +771,7 @@ pub const Parser = struct { |
| 769 | 771 | ||
| 770 | stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable; | 772 | stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable; |
| 771 | try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }); | 773 | try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }); |
| 772 | try stack.append(State { .Payload = &node.op.Catch }); | 774 | try stack.append(State { .ErrorPayload = &node.op.Catch }); |
| 773 | continue; | 775 | continue; |
| 774 | }, | 776 | }, |
| 775 | Token.Id.QuestionMarkQuestionMark => { | 777 | Token.Id.QuestionMarkQuestionMark => { |
| ... | @@ -1471,7 +1473,15 @@ pub const Parser = struct { | ... | @@ -1471,7 +1473,15 @@ pub const Parser = struct { |
| 1471 | continue; | 1473 | continue; |
| 1472 | }, | 1474 | }, |
| 1473 | Token.Id.Keyword_for => { | 1475 | Token.Id.Keyword_for => { |
| 1474 | @panic("TODO: inline for"); | 1476 | stack.append(State { |
| 1477 | .For = LoopCtx { | ||
| 1478 | .label = null, | ||
| 1479 | .inline_token = null, | ||
| 1480 | .loop_token = token, | ||
| 1481 | .dest_ptr = dest_ptr, | ||
| 1482 | } | ||
| 1483 | }) catch unreachable; | ||
| 1484 | continue; | ||
| 1475 | }, | 1485 | }, |
| 1476 | Token.Id.Keyword_switch => { | 1486 | Token.Id.Keyword_switch => { |
| 1477 | const node = try arena.create(ast.NodeSwitch); | 1487 | const node = try arena.create(ast.NodeSwitch); |
| ... | @@ -1614,7 +1624,7 @@ pub const Parser = struct { | ... | @@ -1614,7 +1624,7 @@ pub const Parser = struct { |
| 1614 | try list_state.list.append(node); | 1624 | try list_state.list.append(node); |
| 1615 | stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable; | 1625 | stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable; |
| 1616 | try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } }); | 1626 | try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } }); |
| 1617 | try stack.append(State { .Payload = &node.payload }); | 1627 | try stack.append(State { .ValuePayload = &node.payload }); |
| 1618 | 1628 | ||
| 1619 | const maybe_else = self.getNextToken(); | 1629 | const maybe_else = self.getNextToken(); |
| 1620 | if (maybe_else.id == Token.Id.Keyword_else) { | 1630 | if (maybe_else.id == Token.Id.Keyword_else) { |
| ... | @@ -1681,7 +1691,7 @@ pub const Parser = struct { | ... | @@ -1681,7 +1691,7 @@ pub const Parser = struct { |
| 1681 | *dest = node; | 1691 | *dest = node; |
| 1682 | 1692 | ||
| 1683 | stack.append(State { .Expression = DestPtr { .Field = &node.body } }) catch unreachable; | 1693 | stack.append(State { .Expression = DestPtr { .Field = &node.body } }) catch unreachable; |
| 1684 | try stack.append(State { .Payload = &node.payload }); | 1694 | try stack.append(State { .ErrorPayload = &node.payload }); |
| 1685 | }, | 1695 | }, |
| 1686 | 1696 | ||
| 1687 | State.WhileContinueExpr => |dest| { | 1697 | State.WhileContinueExpr => |dest| { |
| ... | @@ -1696,7 +1706,26 @@ pub const Parser = struct { | ... | @@ -1696,7 +1706,26 @@ pub const Parser = struct { |
| 1696 | try stack.append(State { .Expression = DestPtr { .NullableField = dest } }); | 1706 | try stack.append(State { .Expression = DestPtr { .NullableField = dest } }); |
| 1697 | }, | 1707 | }, |
| 1698 | 1708 | ||
| 1699 | State.Payload => |dest| { | 1709 | State.ErrorPayload => |dest| { |
| 1710 | const lpipe = self.getNextToken(); | ||
| 1711 | if (lpipe.id != Token.Id.Pipe) { | ||
| 1712 | self.putBackToken(lpipe); | ||
| 1713 | continue; | ||
| 1714 | } | ||
| 1715 | |||
| 1716 | const error_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; | ||
| 1717 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; | ||
| 1718 | const node = try arena.create(ast.NodeErrorPayload); | ||
| 1719 | *node = ast.NodeErrorPayload { | ||
| 1720 | .base = self.initNode(ast.Node.Id.ErrorPayload), | ||
| 1721 | .lpipe = lpipe, | ||
| 1722 | .error_symbol = try self.createIdentifier(arena, error_symbol), | ||
| 1723 | .rpipe = rpipe | ||
| 1724 | }; | ||
| 1725 | *dest = node; | ||
| 1726 | }, | ||
| 1727 | |||
| 1728 | State.ValuePayload => |dest| { | ||
| 1700 | const lpipe = self.getNextToken(); | 1729 | const lpipe = self.getNextToken(); |
| 1701 | if (lpipe.id != Token.Id.Pipe) { | 1730 | if (lpipe.id != Token.Id.Pipe) { |
| 1702 | self.putBackToken(lpipe); | 1731 | self.putBackToken(lpipe); |
| ... | @@ -1713,14 +1742,56 @@ pub const Parser = struct { | ... | @@ -1713,14 +1742,56 @@ pub const Parser = struct { |
| 1713 | } | 1742 | } |
| 1714 | }; | 1743 | }; |
| 1715 | 1744 | ||
| 1716 | const ident = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; | 1745 | const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; |
| 1717 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; | 1746 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; |
| 1718 | const node = try arena.create(ast.NodePayload); | 1747 | const node = try arena.create(ast.NodeValuePayload); |
| 1719 | *node = ast.NodePayload { | 1748 | *node = ast.NodeValuePayload { |
| 1720 | .base = self.initNode(ast.Node.Id.Payload), | 1749 | .base = self.initNode(ast.Node.Id.ValuePayload), |
| 1721 | .lpipe = lpipe, | 1750 | .lpipe = lpipe, |
| 1722 | .is_ptr = is_ptr, | 1751 | .is_ptr = is_ptr, |
| 1723 | .symbol = try self.createIdentifier(arena, ident), | 1752 | .value_symbol = try self.createIdentifier(arena, value_symbol), |
| 1753 | .rpipe = rpipe | ||
| 1754 | }; | ||
| 1755 | *dest = node; | ||
| 1756 | }, | ||
| 1757 | |||
| 1758 | State.ValueIndexPayload => |dest| { | ||
| 1759 | const lpipe = self.getNextToken(); | ||
| 1760 | if (lpipe.id != Token.Id.Pipe) { | ||
| 1761 | self.putBackToken(lpipe); | ||
| 1762 | continue; | ||
| 1763 | } | ||
| 1764 | |||
| 1765 | const is_ptr = blk: { | ||
| 1766 | const asterik = self.getNextToken(); | ||
| 1767 | if (asterik.id == Token.Id.Asterisk) { | ||
| 1768 | break :blk true; | ||
| 1769 | } else { | ||
| 1770 | self.putBackToken(asterik); | ||
| 1771 | break :blk false; | ||
| 1772 | } | ||
| 1773 | }; | ||
| 1774 | |||
| 1775 | const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; | ||
| 1776 | const index_symbol = blk: { | ||
| 1777 | const comma = self.getNextToken(); | ||
| 1778 | if (comma.id != Token.Id.Comma) { | ||
| 1779 | self.putBackToken(comma); | ||
| 1780 | break :blk null; | ||
| 1781 | } | ||
| 1782 | |||
| 1783 | const symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue; | ||
| 1784 | break :blk try self.createIdentifier(arena, symbol); | ||
| 1785 | }; | ||
| 1786 | |||
| 1787 | const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue; | ||
| 1788 | const node = try arena.create(ast.NodeValueIndexPayload); | ||
| 1789 | *node = ast.NodeValueIndexPayload { | ||
| 1790 | .base = self.initNode(ast.Node.Id.ValueIndexPayload), | ||
| 1791 | .lpipe = lpipe, | ||
| 1792 | .is_ptr = is_ptr, | ||
| 1793 | .value_symbol = try self.createIdentifier(arena, value_symbol), | ||
| 1794 | .index_symbol = index_symbol, | ||
| 1724 | .rpipe = rpipe | 1795 | .rpipe = rpipe |
| 1725 | }; | 1796 | }; |
| 1726 | *dest = node; | 1797 | *dest = node; |
| ... | @@ -1986,13 +2057,32 @@ pub const Parser = struct { | ... | @@ -1986,13 +2057,32 @@ pub const Parser = struct { |
| 1986 | stack.append(State { .Else = &node.@"else" }) catch unreachable; | 2057 | stack.append(State { .Else = &node.@"else" }) catch unreachable; |
| 1987 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); | 2058 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); |
| 1988 | try stack.append(State { .WhileContinueExpr = &node.continue_expr }); | 2059 | try stack.append(State { .WhileContinueExpr = &node.continue_expr }); |
| 1989 | try stack.append(State { .Payload = &node.payload }); | 2060 | try stack.append(State { .ValuePayload = &node.payload }); |
| 1990 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | 2061 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1991 | try stack.append(State { .Expression = DestPtr { .Field = &node.condition } }); | 2062 | try stack.append(State { .Expression = DestPtr { .Field = &node.condition } }); |
| 1992 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | 2063 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 1993 | }, | 2064 | }, |
| 1994 | 2065 | ||
| 1995 | State.For => |ctx| { | 2066 | State.For => |ctx| { |
| 2067 | const node = try arena.create(ast.NodeFor); | ||
| 2068 | *node = ast.NodeFor { | ||
| 2069 | .base = self.initNode(ast.Node.Id.For), | ||
| 2070 | .label = ctx.label, | ||
| 2071 | .inline_token = ctx.inline_token, | ||
| 2072 | .for_token = ctx.loop_token, | ||
| 2073 | .array_expr = undefined, | ||
| 2074 | .payload = null, | ||
| 2075 | .body = undefined, | ||
| 2076 | .@"else" = null, | ||
| 2077 | }; | ||
| 2078 | ctx.dest_ptr.store(&node.base); | ||
| 2079 | |||
| 2080 | stack.append(State { .Else = &node.@"else" }) catch unreachable; | ||
| 2081 | try stack.append(State { .Expression = DestPtr { .Field = &node.body } }); | ||
| 2082 | try stack.append(State { .ValueIndexPayload = &node.payload }); | ||
| 2083 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | ||
| 2084 | try stack.append(State { .Expression = DestPtr { .Field = &node.array_expr } }); | ||
| 2085 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | ||
| 1996 | }, | 2086 | }, |
| 1997 | 2087 | ||
| 1998 | State.Block => |block| { | 2088 | State.Block => |block| { |
| ... | @@ -2071,7 +2161,9 @@ pub const Parser = struct { | ... | @@ -2071,7 +2161,9 @@ pub const Parser = struct { |
| 2071 | ast.Node.Id.EnumTag, | 2161 | ast.Node.Id.EnumTag, |
| 2072 | ast.Node.Id.ParamDecl, | 2162 | ast.Node.Id.ParamDecl, |
| 2073 | ast.Node.Id.Block, | 2163 | ast.Node.Id.Block, |
| 2074 | ast.Node.Id.Payload, | 2164 | ast.Node.Id.ErrorPayload, |
| 2165 | ast.Node.Id.ValuePayload, | ||
| 2166 | ast.Node.Id.ValueIndexPayload, | ||
| 2075 | ast.Node.Id.Switch, | 2167 | ast.Node.Id.Switch, |
| 2076 | ast.Node.Id.SwitchCase, | 2168 | ast.Node.Id.SwitchCase, |
| 2077 | ast.Node.Id.SwitchElse, | 2169 | ast.Node.Id.SwitchElse, |
| ... | @@ -2087,6 +2179,15 @@ pub const Parser = struct { | ... | @@ -2087,6 +2179,15 @@ pub const Parser = struct { |
| 2087 | 2179 | ||
| 2088 | n = while_node.body; | 2180 | n = while_node.body; |
| 2089 | }, | 2181 | }, |
| 2182 | ast.Node.Id.For => { | ||
| 2183 | const for_node = @fieldParentPtr(ast.NodeFor, "base", n); | ||
| 2184 | if (for_node.@"else") |@"else"| { | ||
| 2185 | n = @"else".base; | ||
| 2186 | continue; | ||
| 2187 | } | ||
| 2188 | |||
| 2189 | n = for_node.body; | ||
| 2190 | }, | ||
| 2090 | ast.Node.Id.Else => { | 2191 | ast.Node.Id.Else => { |
| 2091 | const else_node = @fieldParentPtr(ast.NodeElse, "base", n); | 2192 | const else_node = @fieldParentPtr(ast.NodeElse, "base", n); |
| 2092 | n = else_node.body; | 2193 | n = else_node.body; |
| ... | @@ -2982,10 +3083,33 @@ pub const Parser = struct { | ... | @@ -2982,10 +3083,33 @@ pub const Parser = struct { |
| 2982 | try stack.append(RenderState { .Expression = rhs }); | 3083 | try stack.append(RenderState { .Expression = rhs }); |
| 2983 | } | 3084 | } |
| 2984 | }, | 3085 | }, |
| 2985 | ast.Node.Id.Payload => { | 3086 | ast.Node.Id.ErrorPayload => { |
| 2986 | const payload = @fieldParentPtr(ast.NodePayload, "base", base); | 3087 | const payload = @fieldParentPtr(ast.NodeErrorPayload, "base", base); |
| 3088 | try stack.append(RenderState { .Text = "|"}); | ||
| 3089 | try stack.append(RenderState { .Expression = &payload.error_symbol.base }); | ||
| 3090 | try stack.append(RenderState { .Text = "|"}); | ||
| 3091 | }, | ||
| 3092 | ast.Node.Id.ValuePayload => { | ||
| 3093 | const payload = @fieldParentPtr(ast.NodeValuePayload, "base", base); | ||
| 3094 | try stack.append(RenderState { .Text = "|"}); | ||
| 3095 | try stack.append(RenderState { .Expression = &payload.value_symbol.base }); | ||
| 3096 | |||
| 3097 | if (payload.is_ptr) { | ||
| 3098 | try stack.append(RenderState { .Text = "*"}); | ||
| 3099 | } | ||
| 3100 | |||
| 3101 | try stack.append(RenderState { .Text = "|"}); | ||
| 3102 | }, | ||
| 3103 | ast.Node.Id.ValueIndexPayload => { | ||
| 3104 | const payload = @fieldParentPtr(ast.NodeValueIndexPayload, "base", base); | ||
| 2987 | try stack.append(RenderState { .Text = "|"}); | 3105 | try stack.append(RenderState { .Text = "|"}); |
| 2988 | try stack.append(RenderState { .Expression = &payload.symbol.base }); | 3106 | |
| 3107 | if (payload.index_symbol) |index_symbol| { | ||
| 3108 | try stack.append(RenderState { .Expression = &index_symbol.base }); | ||
| 3109 | try stack.append(RenderState { .Text = ", "}); | ||
| 3110 | } | ||
| 3111 | |||
| 3112 | try stack.append(RenderState { .Expression = &payload.value_symbol.base }); | ||
| 2989 | 3113 | ||
| 2990 | if (payload.is_ptr) { | 3114 | if (payload.is_ptr) { |
| 2991 | try stack.append(RenderState { .Text = "*"}); | 3115 | try stack.append(RenderState { .Text = "*"}); |
| ... | @@ -3303,6 +3427,48 @@ pub const Parser = struct { | ... | @@ -3303,6 +3427,48 @@ pub const Parser = struct { |
| 3303 | try stack.append(RenderState { .Expression = while_node.condition }); | 3427 | try stack.append(RenderState { .Expression = while_node.condition }); |
| 3304 | try stack.append(RenderState { .Text = "(" }); | 3428 | try stack.append(RenderState { .Text = "(" }); |
| 3305 | }, | 3429 | }, |
| 3430 | ast.Node.Id.For => { | ||
| 3431 | const for_node = @fieldParentPtr(ast.NodeFor, "base", base); | ||
| 3432 | if (for_node.label) |label| { | ||
| 3433 | try stream.print("{}: ", self.tokenizer.getTokenSlice(label)); | ||
| 3434 | } | ||
| 3435 | |||
| 3436 | if (for_node.inline_token) |inline_token| { | ||
| 3437 | try stream.print("{} ", self.tokenizer.getTokenSlice(inline_token)); | ||
| 3438 | } | ||
| 3439 | |||
| 3440 | try stream.print("{} ", self.tokenizer.getTokenSlice(for_node.for_token)); | ||
| 3441 | |||
| 3442 | if (for_node.@"else") |@"else"| { | ||
| 3443 | try stack.append(RenderState { .Expression = &@"else".base }); | ||
| 3444 | |||
| 3445 | if (for_node.body.id == ast.Node.Id.Block) { | ||
| 3446 | try stack.append(RenderState { .Text = " " }); | ||
| 3447 | } else { | ||
| 3448 | try stack.append(RenderState { .Text = "\n" }); | ||
| 3449 | } | ||
| 3450 | } | ||
| 3451 | |||
| 3452 | if (for_node.body.id == ast.Node.Id.Block) { | ||
| 3453 | try stack.append(RenderState { .Expression = for_node.body }); | ||
| 3454 | try stack.append(RenderState { .Text = " " }); | ||
| 3455 | } else { | ||
| 3456 | try stack.append(RenderState { .Indent = indent }); | ||
| 3457 | try stack.append(RenderState { .Expression = for_node.body }); | ||
| 3458 | try stack.append(RenderState.PrintIndent); | ||
| 3459 | try stack.append(RenderState { .Indent = indent + indent_delta }); | ||
| 3460 | try stack.append(RenderState { .Text = "\n" }); | ||
| 3461 | } | ||
| 3462 | |||
| 3463 | if (for_node.payload) |payload| { | ||
| 3464 | try stack.append(RenderState { .Expression = &payload.base }); | ||
| 3465 | try stack.append(RenderState { .Text = " " }); | ||
| 3466 | } | ||
| 3467 | |||
| 3468 | try stack.append(RenderState { .Text = ")" }); | ||
| 3469 | try stack.append(RenderState { .Expression = for_node.array_expr }); | ||
| 3470 | try stack.append(RenderState { .Text = "(" }); | ||
| 3471 | }, | ||
| 3306 | 3472 | ||
| 3307 | ast.Node.Id.StructField, | 3473 | ast.Node.Id.StructField, |
| 3308 | ast.Node.Id.UnionTag, | 3474 | ast.Node.Id.UnionTag, |
| ... | @@ -4022,10 +4188,10 @@ test "zig fmt: for" { | ... | @@ -4022,10 +4188,10 @@ test "zig fmt: for" { |
| 4022 | \\ continue; | 4188 | \\ continue; |
| 4023 | \\ | 4189 | \\ |
| 4024 | \\ const res = for (a) |v, i| { | 4190 | \\ const res = for (a) |v, i| { |
| 4025 | \\ breal v; | 4191 | \\ break v; |
| 4026 | \\ } else { | 4192 | \\ } else { |
| 4027 | \\ unreachable; | 4193 | \\ unreachable; |
| 4028 | \\ } | 4194 | \\ }; |
| 4029 | \\ | 4195 | \\ |
| 4030 | \\ var num: usize = 0; | 4196 | \\ var num: usize = 0; |
| 4031 | \\ inline for (a) |v, i| { | 4197 | \\ inline for (a) |v, i| { |