authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-09 11:48:25+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-09 11:48:25+02:00
log7dd55a8007c540415d3e704e490609dd86bea924
treeb3d45596525808eafbbff203bb54a8f5eb2516ac
parente24409ebe0f50be9e01810a5f61bb4c09db57d28

std.zig.parser now parses for loops


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};
559571
560pub const NodePayload = struct {572pub 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
596pub 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
621pub 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,
566628
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;
569631
570 if (i < 1) return &self.symbol.base;632 if (i < 1) return &self.value_symbol.base;
571 i -= 1;633 i -= 1;
572634
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 }
575642
576 pub fn firstToken(self: &NodePayload) Token {643 pub fn firstToken(self: &NodeValueIndexPayload) Token {
577 return self.lpipe;644 return self.lpipe;
578 }645 }
579646
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 {
585pub const NodeElse = struct {652pub 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,
590657
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 {
642pub const NodeSwitchCase = struct {709pub 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,
647714
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};
749816
817pub 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
750pub const NodeInfixOp = struct {870pub 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 {
769771
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 });
16181628
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;
16821692
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 },
16861696
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 },
16981708
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 };
17151744
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 = rpipe1795 .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 },
19942065
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 },
19972087
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 {
20872179
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 });
29893113
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 },
33063472
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| {