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 {
2020 FnProto,
2121 ParamDecl,
2222 Block,
23 Payload,
23 ErrorPayload,
24 ValuePayload,
25 ValueIndexPayload,
2426 Else,
2527 Switch,
2628 SwitchCase,
2729 SwitchElse,
2830 While,
31 For,
2932 InfixOp,
3033 PrefixOp,
3134 SuffixOp,
......@@ -61,12 +64,15 @@ pub const Node = struct {
6164 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index),
6265 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index),
6366 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),
6570 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
6671 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
6772 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).iterate(index),
6873 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).iterate(index),
6974 Id.While => @fieldParentPtr(NodeWhile, "base", base).iterate(index),
75 Id.For => @fieldParentPtr(NodeFor, "base", base).iterate(index),
7076 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index),
7177 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
7278 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
......@@ -103,12 +109,15 @@ pub const Node = struct {
103109 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(),
104110 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(),
105111 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(),
107115 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
108116 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
109117 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).firstToken(),
110118 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).firstToken(),
111119 Id.While => @fieldParentPtr(NodeWhile, "base", base).firstToken(),
120 Id.For => @fieldParentPtr(NodeFor, "base", base).firstToken(),
112121 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),
113122 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
114123 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
......@@ -145,12 +154,15 @@ pub const Node = struct {
145154 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(),
146155 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(),
147156 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(),
149160 Id.Else => @fieldParentPtr(NodeElse, "base", base).lastToken(),
150161 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).lastToken(),
151162 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).lastToken(),
152163 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).lastToken(),
153164 Id.While => @fieldParentPtr(NodeWhile, "base", base).lastToken(),
165 Id.For => @fieldParentPtr(NodeFor, "base", base).lastToken(),
154166 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),
155167 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
156168 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
......@@ -557,27 +569,82 @@ pub const NodeBlock = struct {
557569 }
558570};
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 {
561622 base: Node,
562623 lpipe: Token,
563624 is_ptr: bool,
564 symbol: &NodeIdentifier,
625 value_symbol: &NodeIdentifier,
626 index_symbol: ?&NodeIdentifier,
565627 rpipe: Token,
566628
567 pub fn iterate(self: &NodePayload, index: usize) ?&Node {
629 pub fn iterate(self: &NodeValueIndexPayload, index: usize) ?&Node {
568630 var i = index;
569631
570 if (i < 1) return &self.symbol.base;
632 if (i < 1) return &self.value_symbol.base;
571633 i -= 1;
572634
635 if (self.index_symbol) |index_symbol| {
636 if (i < 1) return &index_symbol.base;
637 i -= 1;
638 }
639
573640 return null;
574641 }
575642
576 pub fn firstToken(self: &NodePayload) Token {
643 pub fn firstToken(self: &NodeValueIndexPayload) Token {
577644 return self.lpipe;
578645 }
579646
580 pub fn lastToken(self: &NodePayload) Token {
647 pub fn lastToken(self: &NodeValueIndexPayload) Token {
581648 return self.rpipe;
582649 }
583650};
......@@ -585,7 +652,7 @@ pub const NodePayload = struct {
585652pub const NodeElse = struct {
586653 base: Node,
587654 else_token: Token,
588 payload: ?&NodePayload,
655 payload: ?&NodeErrorPayload,
589656 body: &Node,
590657
591658 pub fn iterate(self: &NodeElse, index: usize) ?&Node {
......@@ -642,7 +709,7 @@ pub const NodeSwitch = struct {
642709pub const NodeSwitchCase = struct {
643710 base: Node,
644711 items: ArrayList(&Node),
645 payload: ?&NodePayload,
712 payload: ?&NodeValuePayload,
646713 expr: &Node,
647714
648715 pub fn iterate(self: &NodeSwitchCase, index: usize) ?&Node {
......@@ -694,7 +761,7 @@ pub const NodeWhile = struct {
694761 inline_token: ?Token,
695762 while_token: Token,
696763 condition: &Node,
697 payload: ?&NodePayload,
764 payload: ?&NodeValuePayload,
698765 continue_expr: ?&Node,
699766 body: &Node,
700767 @"else": ?&NodeElse,
......@@ -747,6 +814,59 @@ pub const NodeWhile = struct {
747814 }
748815};
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
750870pub const NodeInfixOp = struct {
751871 base: Node,
752872 op_token: Token,
......@@ -781,7 +901,7 @@ pub const NodeInfixOp = struct {
781901 BitXor,
782902 BoolAnd,
783903 BoolOr,
784 Catch: ?&NodePayload,
904 Catch: ?&NodeErrorPayload,
785905 Div,
786906 EqualEqual,
787907 ErrorUnion,
std/zig/parser.zig+184-18
......@@ -170,7 +170,9 @@ pub const Parser = struct {
170170 FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),
171171 FieldListCommaOrEnd: &ast.NodeContainerDecl,
172172 SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),
173 Payload: &?&ast.NodePayload,
173 ErrorPayload: &?&ast.NodeErrorPayload,
174 ValuePayload: &?&ast.NodeValuePayload,
175 ValueIndexPayload: &?&ast.NodeValueIndexPayload,
174176 SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase),
175177 SwitchCaseItem: &ArrayList(&ast.Node),
176178 SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node),
......@@ -769,7 +771,7 @@ pub const Parser = struct {
769771
770772 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
771773 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 });
773775 continue;
774776 },
775777 Token.Id.QuestionMarkQuestionMark => {
......@@ -1471,7 +1473,15 @@ pub const Parser = struct {
14711473 continue;
14721474 },
14731475 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;
14751485 },
14761486 Token.Id.Keyword_switch => {
14771487 const node = try arena.create(ast.NodeSwitch);
......@@ -1614,7 +1624,7 @@ pub const Parser = struct {
16141624 try list_state.list.append(node);
16151625 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;
16161626 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
16191629 const maybe_else = self.getNextToken();
16201630 if (maybe_else.id == Token.Id.Keyword_else) {
......@@ -1681,7 +1691,7 @@ pub const Parser = struct {
16811691 *dest = node;
16821692
16831693 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 });
16851695 },
16861696
16871697 State.WhileContinueExpr => |dest| {
......@@ -1696,7 +1706,26 @@ pub const Parser = struct {
16961706 try stack.append(State { .Expression = DestPtr { .NullableField = dest } });
16971707 },
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| {
17001729 const lpipe = self.getNextToken();
17011730 if (lpipe.id != Token.Id.Pipe) {
17021731 self.putBackToken(lpipe);
......@@ -1713,14 +1742,56 @@ pub const Parser = struct {
17131742 }
17141743 };
17151744
1716 const ident = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
1745 const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
17171746 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
1718 const node = try arena.create(ast.NodePayload);
1719 *node = ast.NodePayload {
1720 .base = self.initNode(ast.Node.Id.Payload),
1747 const node = try arena.create(ast.NodeValuePayload);
1748 *node = ast.NodeValuePayload {
1749 .base = self.initNode(ast.Node.Id.ValuePayload),
17211750 .lpipe = lpipe,
17221751 .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,
17241795 .rpipe = rpipe
17251796 };
17261797 *dest = node;
......@@ -1986,13 +2057,32 @@ pub const Parser = struct {
19862057 stack.append(State { .Else = &node.@"else" }) catch unreachable;
19872058 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
19882059 try stack.append(State { .WhileContinueExpr = &node.continue_expr });
1989 try stack.append(State { .Payload = &node.payload });
2060 try stack.append(State { .ValuePayload = &node.payload });
19902061 try stack.append(State { .ExpectToken = Token.Id.RParen });
19912062 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
19922063 try stack.append(State { .ExpectToken = Token.Id.LParen });
19932064 },
19942065
19952066 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 });
19962086 },
19972087
19982088 State.Block => |block| {
......@@ -2071,7 +2161,9 @@ pub const Parser = struct {
20712161 ast.Node.Id.EnumTag,
20722162 ast.Node.Id.ParamDecl,
20732163 ast.Node.Id.Block,
2074 ast.Node.Id.Payload,
2164 ast.Node.Id.ErrorPayload,
2165 ast.Node.Id.ValuePayload,
2166 ast.Node.Id.ValueIndexPayload,
20752167 ast.Node.Id.Switch,
20762168 ast.Node.Id.SwitchCase,
20772169 ast.Node.Id.SwitchElse,
......@@ -2087,6 +2179,15 @@ pub const Parser = struct {
20872179
20882180 n = while_node.body;
20892181 },
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 },
20902191 ast.Node.Id.Else => {
20912192 const else_node = @fieldParentPtr(ast.NodeElse, "base", n);
20922193 n = else_node.body;
......@@ -2982,10 +3083,33 @@ pub const Parser = struct {
29823083 try stack.append(RenderState { .Expression = rhs });
29833084 }
29843085 },
2985 ast.Node.Id.Payload => {
2986 const payload = @fieldParentPtr(ast.NodePayload, "base", base);
3086 ast.Node.Id.ErrorPayload => {
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);
29873105 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
29903114 if (payload.is_ptr) {
29913115 try stack.append(RenderState { .Text = "*"});
......@@ -3303,6 +3427,48 @@ pub const Parser = struct {
33033427 try stack.append(RenderState { .Expression = while_node.condition });
33043428 try stack.append(RenderState { .Text = "(" });
33053429 },
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
33073473 ast.Node.Id.StructField,
33083474 ast.Node.Id.UnionTag,
......@@ -4022,10 +4188,10 @@ test "zig fmt: for" {
40224188 \\ continue;
40234189 \\
40244190 \\ const res = for (a) |v, i| {
4025 \\ breal v;
4191 \\ break v;
40264192 \\ } else {
40274193 \\ unreachable;
4028 \\ }
4194 \\ };
40294195 \\
40304196 \\ var num: usize = 0;
40314197 \\ inline for (a) |v, i| {