authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-10 11:25:58+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-10 11:25:58+02:00
logf85b9f2bf3ac0c5af7804921d2003c2992558cb7
treef3cb7897b44e3634c90be907f14192f4d2d66d9f
parent5cd69ee6a4b7d02dbc48d93e8f8f95bd608d9d7c

std.zig.parser now parses coroutine code


2 files changed, 345 insertions(+), 89 deletions(-)

std/zig/ast.zig+124-33
...@@ -17,14 +17,15 @@ pub const Node = struct {...@@ -17,14 +17,15 @@ pub const Node = struct {
17 UnionTag,17 UnionTag,
18 EnumTag,18 EnumTag,
19 Identifier,19 Identifier,
20 AsyncAttribute,
20 FnProto,21 FnProto,
21 ParamDecl,22 ParamDecl,
22 Block,23 Block,
23 Defer,24 Defer,
24 Comptime,25 Comptime,
25 ErrorPayload,26 Payload,
26 ValuePayload,27 PointerPayload,
27 ValueIndexPayload,28 PointerIndexPayload,
28 Else,29 Else,
29 Switch,30 Switch,
30 SwitchCase,31 SwitchCase,
...@@ -37,6 +38,7 @@ pub const Node = struct {...@@ -37,6 +38,7 @@ pub const Node = struct {
37 SuffixOp,38 SuffixOp,
38 GroupedExpression,39 GroupedExpression,
39 ControlFlowExpression,40 ControlFlowExpression,
41 Suspend,
40 FieldInitializer,42 FieldInitializer,
41 IntegerLiteral,43 IntegerLiteral,
42 FloatLiteral,44 FloatLiteral,
...@@ -67,14 +69,15 @@ pub const Node = struct {...@@ -67,14 +69,15 @@ pub const Node = struct {
67 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).iterate(index),69 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).iterate(index),
68 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).iterate(index),70 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).iterate(index),
69 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).iterate(index),71 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).iterate(index),
72 Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).iterate(index),
70 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index),73 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index),
71 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index),74 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index),
72 Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index),75 Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index),
73 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).iterate(index),76 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).iterate(index),
74 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).iterate(index),77 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).iterate(index),
75 Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).iterate(index),78 Id.Payload => @fieldParentPtr(NodePayload, "base", base).iterate(index),
76 Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).iterate(index),79 Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).iterate(index),
77 Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).iterate(index),80 Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).iterate(index),
78 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),81 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
79 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),82 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
80 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).iterate(index),83 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).iterate(index),
...@@ -87,6 +90,7 @@ pub const Node = struct {...@@ -87,6 +90,7 @@ pub const Node = struct {
87 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),90 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
88 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).iterate(index),91 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).iterate(index),
89 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).iterate(index),92 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).iterate(index),
93 Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).iterate(index),
90 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).iterate(index),94 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).iterate(index),
91 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),95 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
92 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),96 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
...@@ -118,14 +122,15 @@ pub const Node = struct {...@@ -118,14 +122,15 @@ pub const Node = struct {
118 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).firstToken(),122 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).firstToken(),
119 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).firstToken(),123 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).firstToken(),
120 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).firstToken(),124 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).firstToken(),
125 Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).firstToken(),
121 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(),126 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(),
122 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(),127 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(),
123 Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(),128 Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(),
124 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).firstToken(),129 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).firstToken(),
125 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).firstToken(),130 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).firstToken(),
126 Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).firstToken(),131 Id.Payload => @fieldParentPtr(NodePayload, "base", base).firstToken(),
127 Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).firstToken(),132 Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).firstToken(),
128 Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).firstToken(),133 Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).firstToken(),
129 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),134 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
130 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),135 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
131 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).firstToken(),136 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).firstToken(),
...@@ -138,6 +143,7 @@ pub const Node = struct {...@@ -138,6 +143,7 @@ pub const Node = struct {
138 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),143 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
139 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).firstToken(),144 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).firstToken(),
140 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).firstToken(),145 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).firstToken(),
146 Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).firstToken(),
141 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).firstToken(),147 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).firstToken(),
142 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),148 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),
143 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),149 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),
...@@ -169,14 +175,15 @@ pub const Node = struct {...@@ -169,14 +175,15 @@ pub const Node = struct {
169 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).lastToken(),175 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).lastToken(),
170 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).lastToken(),176 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).lastToken(),
171 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).lastToken(),177 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).lastToken(),
178 Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).lastToken(),
172 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(),179 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(),
173 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(),180 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(),
174 Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(),181 Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(),
175 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).lastToken(),182 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).lastToken(),
176 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).lastToken(),183 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).lastToken(),
177 Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).lastToken(),184 Id.Payload => @fieldParentPtr(NodePayload, "base", base).lastToken(),
178 Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).lastToken(),185 Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).lastToken(),
179 Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).lastToken(),186 Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).lastToken(),
180 Id.Else => @fieldParentPtr(NodeElse, "base", base).lastToken(),187 Id.Else => @fieldParentPtr(NodeElse, "base", base).lastToken(),
181 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).lastToken(),188 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).lastToken(),
182 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).lastToken(),189 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).lastToken(),
...@@ -189,6 +196,7 @@ pub const Node = struct {...@@ -189,6 +196,7 @@ pub const Node = struct {
189 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),196 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
190 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).lastToken(),197 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).lastToken(),
191 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).lastToken(),198 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).lastToken(),
199 Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).lastToken(),
192 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).lastToken(),200 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).lastToken(),
193 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),201 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),
194 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),202 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),
...@@ -456,6 +464,36 @@ pub const NodeIdentifier = struct {...@@ -456,6 +464,36 @@ pub const NodeIdentifier = struct {
456 }464 }
457};465};
458466
467pub const NodeAsyncAttribute = struct {
468 base: Node,
469 async_token: Token,
470 allocator_type: ?&Node,
471 rangle_bracket: ?Token,
472
473 pub fn iterate(self: &NodeAsyncAttribute, index: usize) ?&Node {
474 var i = index;
475
476 if (self.allocator_type) |allocator_type| {
477 if (i < 1) return allocator_type;
478 i -= 1;
479 }
480
481 return null;
482 }
483
484 pub fn firstToken(self: &NodeAsyncAttribute) Token {
485 return self.async_token;
486 }
487
488 pub fn lastToken(self: &NodeAsyncAttribute) Token {
489 if (self.rangle_bracket) |rangle_bracket| {
490 return rangle_bracket;
491 }
492
493 return self.async_token;
494 }
495};
496
459pub const NodeFnProto = struct {497pub const NodeFnProto = struct {
460 base: Node,498 base: Node,
461 visib_token: ?Token,499 visib_token: ?Token,
...@@ -467,6 +505,7 @@ pub const NodeFnProto = struct {...@@ -467,6 +505,7 @@ pub const NodeFnProto = struct {
467 extern_token: ?Token,505 extern_token: ?Token,
468 inline_token: ?Token,506 inline_token: ?Token,
469 cc_token: ?Token,507 cc_token: ?Token,
508 async_attr: ?&NodeAsyncAttribute,
470 body_node: ?&Node,509 body_node: ?&Node,
471 lib_name: ?&Node, // populated if this is an extern declaration510 lib_name: ?&Node, // populated if this is an extern declaration
472 align_expr: ?&Node, // populated if align(A) is present511 align_expr: ?&Node, // populated if align(A) is present
...@@ -511,6 +550,14 @@ pub const NodeFnProto = struct {...@@ -511,6 +550,14 @@ pub const NodeFnProto = struct {
511 i -= 1;550 i -= 1;
512 }551 }
513552
553 switch (self.call_convetion) {
554 CallConvetion.Async => |attr| {
555 if (i < 1) return &attr.base;
556 i -= 1;
557 },
558 else => {},
559 }
560
514 return null;561 return null;
515 }562 }
516563
...@@ -645,13 +692,13 @@ pub const NodeComptime = struct {...@@ -645,13 +692,13 @@ pub const NodeComptime = struct {
645 }692 }
646};693};
647694
648pub const NodeErrorPayload = struct {695pub const NodePayload = struct {
649 base: Node,696 base: Node,
650 lpipe: Token,697 lpipe: Token,
651 error_symbol: &NodeIdentifier,698 error_symbol: &NodeIdentifier,
652 rpipe: Token,699 rpipe: Token,
653700
654 pub fn iterate(self: &NodeErrorPayload, index: usize) ?&Node {701 pub fn iterate(self: &NodePayload, index: usize) ?&Node {
655 var i = index;702 var i = index;
656703
657 if (i < 1) return &self.error_symbol.base;704 if (i < 1) return &self.error_symbol.base;
...@@ -660,23 +707,23 @@ pub const NodeErrorPayload = struct {...@@ -660,23 +707,23 @@ pub const NodeErrorPayload = struct {
660 return null;707 return null;
661 }708 }
662709
663 pub fn firstToken(self: &NodeErrorPayload) Token {710 pub fn firstToken(self: &NodePayload) Token {
664 return self.lpipe;711 return self.lpipe;
665 }712 }
666713
667 pub fn lastToken(self: &NodeErrorPayload) Token {714 pub fn lastToken(self: &NodePayload) Token {
668 return self.rpipe;715 return self.rpipe;
669 }716 }
670};717};
671718
672pub const NodeValuePayload = struct {719pub const NodePointerPayload = struct {
673 base: Node,720 base: Node,
674 lpipe: Token,721 lpipe: Token,
675 is_ptr: bool,722 is_ptr: bool,
676 value_symbol: &NodeIdentifier,723 value_symbol: &NodeIdentifier,
677 rpipe: Token,724 rpipe: Token,
678725
679 pub fn iterate(self: &NodeValuePayload, index: usize) ?&Node {726 pub fn iterate(self: &NodePointerPayload, index: usize) ?&Node {
680 var i = index;727 var i = index;
681728
682 if (i < 1) return &self.value_symbol.base;729 if (i < 1) return &self.value_symbol.base;
...@@ -685,16 +732,16 @@ pub const NodeValuePayload = struct {...@@ -685,16 +732,16 @@ pub const NodeValuePayload = struct {
685 return null;732 return null;
686 }733 }
687734
688 pub fn firstToken(self: &NodeValuePayload) Token {735 pub fn firstToken(self: &NodePointerPayload) Token {
689 return self.lpipe;736 return self.lpipe;
690 }737 }
691738
692 pub fn lastToken(self: &NodeValuePayload) Token {739 pub fn lastToken(self: &NodePointerPayload) Token {
693 return self.rpipe;740 return self.rpipe;
694 }741 }
695};742};
696743
697pub const NodeValueIndexPayload = struct {744pub const NodePointerIndexPayload = struct {
698 base: Node,745 base: Node,
699 lpipe: Token,746 lpipe: Token,
700 is_ptr: bool,747 is_ptr: bool,
...@@ -702,7 +749,7 @@ pub const NodeValueIndexPayload = struct {...@@ -702,7 +749,7 @@ pub const NodeValueIndexPayload = struct {
702 index_symbol: ?&NodeIdentifier,749 index_symbol: ?&NodeIdentifier,
703 rpipe: Token,750 rpipe: Token,
704751
705 pub fn iterate(self: &NodeValueIndexPayload, index: usize) ?&Node {752 pub fn iterate(self: &NodePointerIndexPayload, index: usize) ?&Node {
706 var i = index;753 var i = index;
707754
708 if (i < 1) return &self.value_symbol.base;755 if (i < 1) return &self.value_symbol.base;
...@@ -716,11 +763,11 @@ pub const NodeValueIndexPayload = struct {...@@ -716,11 +763,11 @@ pub const NodeValueIndexPayload = struct {
716 return null;763 return null;
717 }764 }
718765
719 pub fn firstToken(self: &NodeValueIndexPayload) Token {766 pub fn firstToken(self: &NodePointerIndexPayload) Token {
720 return self.lpipe;767 return self.lpipe;
721 }768 }
722769
723 pub fn lastToken(self: &NodeValueIndexPayload) Token {770 pub fn lastToken(self: &NodePointerIndexPayload) Token {
724 return self.rpipe;771 return self.rpipe;
725 }772 }
726};773};
...@@ -728,7 +775,7 @@ pub const NodeValueIndexPayload = struct {...@@ -728,7 +775,7 @@ pub const NodeValueIndexPayload = struct {
728pub const NodeElse = struct {775pub const NodeElse = struct {
729 base: Node,776 base: Node,
730 else_token: Token,777 else_token: Token,
731 payload: ?&NodeErrorPayload,778 payload: ?&NodePayload,
732 body: &Node,779 body: &Node,
733780
734 pub fn iterate(self: &NodeElse, index: usize) ?&Node {781 pub fn iterate(self: &NodeElse, index: usize) ?&Node {
...@@ -785,7 +832,7 @@ pub const NodeSwitch = struct {...@@ -785,7 +832,7 @@ pub const NodeSwitch = struct {
785pub const NodeSwitchCase = struct {832pub const NodeSwitchCase = struct {
786 base: Node,833 base: Node,
787 items: ArrayList(&Node),834 items: ArrayList(&Node),
788 payload: ?&NodeValuePayload,835 payload: ?&NodePointerPayload,
789 expr: &Node,836 expr: &Node,
790837
791 pub fn iterate(self: &NodeSwitchCase, index: usize) ?&Node {838 pub fn iterate(self: &NodeSwitchCase, index: usize) ?&Node {
...@@ -837,7 +884,7 @@ pub const NodeWhile = struct {...@@ -837,7 +884,7 @@ pub const NodeWhile = struct {
837 inline_token: ?Token,884 inline_token: ?Token,
838 while_token: Token,885 while_token: Token,
839 condition: &Node,886 condition: &Node,
840 payload: ?&NodeValuePayload,887 payload: ?&NodePointerPayload,
841 continue_expr: ?&Node,888 continue_expr: ?&Node,
842 body: &Node,889 body: &Node,
843 @"else": ?&NodeElse,890 @"else": ?&NodeElse,
...@@ -896,7 +943,7 @@ pub const NodeFor = struct {...@@ -896,7 +943,7 @@ pub const NodeFor = struct {
896 inline_token: ?Token,943 inline_token: ?Token,
897 for_token: Token,944 for_token: Token,
898 array_expr: &Node,945 array_expr: &Node,
899 payload: ?&NodeValueIndexPayload,946 payload: ?&NodePointerIndexPayload,
900 body: &Node,947 body: &Node,
901 @"else": ?&NodeElse,948 @"else": ?&NodeElse,
902949
...@@ -947,7 +994,7 @@ pub const NodeIf = struct {...@@ -947,7 +994,7 @@ pub const NodeIf = struct {
947 base: Node,994 base: Node,
948 if_token: Token,995 if_token: Token,
949 condition: &Node,996 condition: &Node,
950 payload: ?&NodeValuePayload,997 payload: ?&NodePointerPayload,
951 body: &Node,998 body: &Node,
952 @"else": ?&NodeElse,999 @"else": ?&NodeElse,
9531000
...@@ -1020,7 +1067,7 @@ pub const NodeInfixOp = struct {...@@ -1020,7 +1067,7 @@ pub const NodeInfixOp = struct {
1020 BitXor,1067 BitXor,
1021 BoolAnd,1068 BoolAnd,
1022 BoolOr,1069 BoolOr,
1023 Catch: ?&NodeErrorPayload,1070 Catch: ?&NodePayload,
1024 Div,1071 Div,
1025 EqualEqual,1072 EqualEqual,
1026 ErrorUnion,1073 ErrorUnion,
...@@ -1113,13 +1160,16 @@ pub const NodePrefixOp = struct {...@@ -1113,13 +1160,16 @@ pub const NodePrefixOp = struct {
11131160
1114 const PrefixOp = union(enum) {1161 const PrefixOp = union(enum) {
1115 AddrOf: AddrOfInfo,1162 AddrOf: AddrOfInfo,
1163 ArrayType: &Node,
1164 Await,
1116 BitNot,1165 BitNot,
1117 BoolNot,1166 BoolNot,
1167 Cancel,
1118 Deref,1168 Deref,
1119 MaybeType,1169 MaybeType,
1120 Negation,1170 Negation,
1121 NegationWrap,1171 NegationWrap,
1122 ArrayType: &Node,1172 Resume,
1123 SliceType: AddrOfInfo,1173 SliceType: AddrOfInfo,
1124 Try,1174 Try,
1125 UnwrapMaybe,1175 UnwrapMaybe,
...@@ -1153,13 +1203,16 @@ pub const NodePrefixOp = struct {...@@ -1153,13 +1203,16 @@ pub const NodePrefixOp = struct {
1153 if (i < 1) return size_expr;1203 if (i < 1) return size_expr;
1154 i -= 1;1204 i -= 1;
1155 },1205 },
1206 PrefixOp.Await,
1156 PrefixOp.BitNot,1207 PrefixOp.BitNot,
1157 PrefixOp.BoolNot,1208 PrefixOp.BoolNot,
1209 PrefixOp.Cancel,
1158 PrefixOp.Deref,1210 PrefixOp.Deref,
1159 PrefixOp.Negation,1211 PrefixOp.Negation,
1160 PrefixOp.NegationWrap,1212 PrefixOp.NegationWrap,
1161 PrefixOp.Return,1213 PrefixOp.Return,
1162 PrefixOp.Try,1214 PrefixOp.Try,
1215 PrefixOp.Resume,
1163 PrefixOp.UnwrapMaybe => {},1216 PrefixOp.UnwrapMaybe => {},
1164 }1217 }
11651218
...@@ -1218,8 +1271,7 @@ pub const NodeSuffixOp = struct {...@@ -1218,8 +1271,7 @@ pub const NodeSuffixOp = struct {
12181271
1219 const CallInfo = struct {1272 const CallInfo = struct {
1220 params: ArrayList(&Node),1273 params: ArrayList(&Node),
1221 is_async: bool,1274 async_attr: ?&NodeAsyncAttribute,
1222 allocator: ?&Node,
1223 };1275 };
12241276
1225 const SliceRange = struct {1277 const SliceRange = struct {
...@@ -1347,6 +1399,45 @@ pub const NodeControlFlowExpression = struct {...@@ -1347,6 +1399,45 @@ pub const NodeControlFlowExpression = struct {
1347 }1399 }
1348};1400};
13491401
1402pub const NodeSuspend = struct {
1403 base: Node,
1404 suspend_token: Token,
1405 payload: ?&NodePayload,
1406 body: ?&Node,
1407
1408 pub fn iterate(self: &NodeSuspend, index: usize) ?&Node {
1409 var i = index;
1410
1411 if (self.payload) |payload| {
1412 if (i < 1) return &payload.base;
1413 i -= 1;
1414 }
1415
1416 if (self.body) |body| {
1417 if (i < 1) return body;
1418 i -= 1;
1419 }
1420
1421 return null;
1422 }
1423
1424 pub fn firstToken(self: &NodeSuspend) Token {
1425 return self.suspend_token;
1426 }
1427
1428 pub fn lastToken(self: &NodeSuspend) Token {
1429 if (self.body) |body| {
1430 return body.lastToken();
1431 }
1432
1433 if (self.payload) |payload| {
1434 return payload.lastToken();
1435 }
1436
1437 return self.suspend_token;
1438 }
1439};
1440
1350pub const NodeIntegerLiteral = struct {1441pub const NodeIntegerLiteral = struct {
1351 base: Node,1442 base: Node,
1352 token: Token,1443 token: Token,
std/zig/parser.zig+221-56
...@@ -134,6 +134,11 @@ pub const Parser = struct {...@@ -134,6 +134,11 @@ pub const Parser = struct {
134 dest_ptr: DestPtr,134 dest_ptr: DestPtr,
135 };135 };
136136
137 const AsyncEndCtx = struct {
138 dest_ptr: DestPtr,
139 attribute: &ast.NodeAsyncAttribute,
140 };
141
137 const State = union(enum) {142 const State = union(enum) {
138 TopLevel,143 TopLevel,
139 TopLevelExtern: TopLevelDeclCtx,144 TopLevelExtern: TopLevelDeclCtx,
...@@ -173,9 +178,11 @@ pub const Parser = struct {...@@ -173,9 +178,11 @@ pub const Parser = struct {
173 FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),178 FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),
174 FieldListCommaOrEnd: &ast.NodeContainerDecl,179 FieldListCommaOrEnd: &ast.NodeContainerDecl,
175 SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),180 SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),
176 ErrorPayload: &?&ast.NodeErrorPayload,181 SuspendBody: &ast.NodeSuspend,
177 ValuePayload: &?&ast.NodeValuePayload,182 AsyncEnd: AsyncEndCtx,
178 ValueIndexPayload: &?&ast.NodeValueIndexPayload,183 Payload: &?&ast.NodePayload,
184 PointerPayload: &?&ast.NodePointerPayload,
185 PointerIndexPayload: &?&ast.NodePointerIndexPayload,
179 SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase),186 SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase),
180 SwitchCaseItem: &ArrayList(&ast.Node),187 SwitchCaseItem: &ArrayList(&ast.Node),
181 SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node),188 SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node),
...@@ -399,6 +406,45 @@ pub const Parser = struct {...@@ -399,6 +406,45 @@ pub const Parser = struct {
399 });406 });
400 continue;407 continue;
401 },408 },
409 Token.Id.Keyword_async => {
410 // TODO shouldn't need this cast
411 const fn_proto = try self.createAttachFnProto(arena, ctx.decls, undefined,
412 ctx.extern_token, ctx.lib_name, (?Token)(null), (?Token)(null), (?Token)(null));
413
414 const async_node = try arena.create(ast.NodeAsyncAttribute);
415 *async_node = ast.NodeAsyncAttribute {
416 .base = self.initNode(ast.Node.Id.AsyncAttribute),
417 .async_token = token,
418 .allocator_type = null,
419 .rangle_bracket = null,
420 };
421
422 fn_proto.async_attr = async_node;
423 stack.append(State { .FnDef = fn_proto }) catch unreachable;
424 try stack.append(State { .FnProto = fn_proto });
425 try stack.append(State {
426 .ExpectTokenSave = ExpectTokenSave {
427 .id = Token.Id.Keyword_fn,
428 .ptr = &fn_proto.fn_token,
429 }
430 });
431
432 const langle_bracket = self.getNextToken();
433 if (langle_bracket.id != Token.Id.AngleBracketLeft) {
434 self.putBackToken(langle_bracket);
435 continue;
436 }
437
438 async_node.rangle_bracket = Token(undefined);
439 try stack.append(State {
440 .ExpectTokenSave = ExpectTokenSave {
441 .id = Token.Id.AngleBracketRight,
442 .ptr = &??async_node.rangle_bracket,
443 }
444 });
445 try stack.append(State { .TypeExprBegin = DestPtr { .NullableField = &async_node.allocator_type } });
446 continue;
447 },
402 else => {448 else => {
403 try self.parseError(&stack, token, "expected variable declaration or function, found {}", @tagName(token.id));449 try self.parseError(&stack, token, "expected variable declaration or function, found {}", @tagName(token.id));
404 continue;450 continue;
...@@ -711,13 +757,14 @@ pub const Parser = struct {...@@ -711,13 +757,14 @@ pub const Parser = struct {
711 continue;757 continue;
712 },758 },
713 Token.Id.Keyword_cancel => {759 Token.Id.Keyword_cancel => {
714 @panic("TODO: cancel");760 const cancel_node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp.Cancel);
761 dest_ptr.store(&cancel_node.base);
762 stack.append(State { .Expression = DestPtr { .Field = &cancel_node.rhs } }) catch unreachable;
715 },763 },
716 Token.Id.Keyword_resume => {764 Token.Id.Keyword_resume => {
717 @panic("TODO: resume");765 const resume_node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp.Resume);
718 },766 dest_ptr.store(&resume_node.base);
719 Token.Id.Keyword_await => {767 stack.append(State { .Expression = DestPtr { .Field = &resume_node.rhs } }) catch unreachable;
720 @panic("TODO: await");
721 },768 },
722 else => {769 else => {
723 self.putBackToken(token);770 self.putBackToken(token);
...@@ -786,7 +833,7 @@ pub const Parser = struct {...@@ -786,7 +833,7 @@ pub const Parser = struct {
786833
787 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;834 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
788 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });835 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });
789 try stack.append(State { .ErrorPayload = &node.op.Catch });836 try stack.append(State { .Payload = &node.op.Catch });
790 continue;837 continue;
791 },838 },
792 Token.Id.QuestionMarkQuestionMark => {839 Token.Id.QuestionMarkQuestionMark => {
...@@ -1113,6 +1160,9 @@ pub const Parser = struct {...@@ -1113,6 +1160,9 @@ pub const Parser = struct {
1113 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });1160 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
1114 }1161 }
1115 continue;1162 continue;
1163 //Token.Id.Keyword_await => {
1164 // @panic("TODO: await");
1165 //},
1116 } else {1166 } else {
1117 self.putBackToken(token);1167 self.putBackToken(token);
1118 stack.append(State { .SuffixOpExpressionBegin = dest_ptr }) catch unreachable;1168 stack.append(State { .SuffixOpExpressionBegin = dest_ptr }) catch unreachable;
...@@ -1124,7 +1174,38 @@ pub const Parser = struct {...@@ -1124,7 +1174,38 @@ pub const Parser = struct {
1124 const token = self.getNextToken();1174 const token = self.getNextToken();
1125 switch (token.id) {1175 switch (token.id) {
1126 Token.Id.Keyword_async => {1176 Token.Id.Keyword_async => {
1127 @panic("TODO: Parse async");1177 const async_node = try arena.create(ast.NodeAsyncAttribute);
1178 *async_node = ast.NodeAsyncAttribute {
1179 .base = self.initNode(ast.Node.Id.AsyncAttribute),
1180 .async_token = token,
1181 .allocator_type = null,
1182 .rangle_bracket = null,
1183 };
1184
1185 stack.append(State {
1186 .AsyncEnd = AsyncEndCtx {
1187 .dest_ptr = dest_ptr,
1188 .attribute = async_node,
1189 }
1190 }) catch unreachable;
1191 try stack.append(State { .SuffixOpExpressionEnd = dest_ptr });
1192 try stack.append(State { .PrimaryExpression = dest_ptr });
1193
1194 const langle_bracket = self.getNextToken();
1195 if (langle_bracket.id != Token.Id.AngleBracketLeft) {
1196 self.putBackToken(langle_bracket);
1197 continue;
1198 }
1199
1200 async_node.rangle_bracket = Token(undefined);
1201 try stack.append(State {
1202 .ExpectTokenSave = ExpectTokenSave {
1203 .id = Token.Id.AngleBracketRight,
1204 .ptr = &??async_node.rangle_bracket,
1205 }
1206 });
1207 try stack.append(State { .TypeExprBegin = DestPtr { .NullableField = &async_node.allocator_type } });
1208 continue;
1128 },1209 },
1129 else => {1210 else => {
1130 self.putBackToken(token);1211 self.putBackToken(token);
...@@ -1142,8 +1223,7 @@ pub const Parser = struct {...@@ -1142,8 +1223,7 @@ pub const Parser = struct {
1142 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {1223 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
1143 .Call = ast.NodeSuffixOp.CallInfo {1224 .Call = ast.NodeSuffixOp.CallInfo {
1144 .params = ArrayList(&ast.Node).init(arena),1225 .params = ArrayList(&ast.Node).init(arena),
1145 .is_async = false, // TODO: ASYNC1226 .async_attr = null,
1146 .allocator = null,
1147 }1227 }
1148 });1228 });
1149 node.lhs = dest_ptr.get();1229 node.lhs = dest_ptr.get();
...@@ -1257,6 +1337,19 @@ pub const Parser = struct {...@@ -1257,6 +1337,19 @@ pub const Parser = struct {
1257 dest_ptr.store(&node.base);1337 dest_ptr.store(&node.base);
1258 continue;1338 continue;
1259 },1339 },
1340 Token.Id.Keyword_suspend => {
1341 const node = try arena.create(ast.NodeSuspend);
1342 *node = ast.NodeSuspend {
1343 .base = self.initNode(ast.Node.Id.Suspend),
1344 .suspend_token = token,
1345 .payload = null,
1346 .body = null,
1347 };
1348 dest_ptr.store(&node.base);
1349 stack.append(State { .SuspendBody = node }) catch unreachable;
1350 try stack.append(State { .Payload = &node.payload });
1351 continue;
1352 },
1260 Token.Id.MultilineStringLiteralLine => {1353 Token.Id.MultilineStringLiteralLine => {
1261 const node = try arena.create(ast.NodeMultilineStringLiteral);1354 const node = try arena.create(ast.NodeMultilineStringLiteral);
1262 *node = ast.NodeMultilineStringLiteral {1355 *node = ast.NodeMultilineStringLiteral {
...@@ -1477,17 +1570,12 @@ pub const Parser = struct {...@@ -1477,17 +1570,12 @@ pub const Parser = struct {
1477 continue;1570 continue;
1478 },1571 },
1479 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {1572 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
1573 const fn_token = (try self.eatToken(&stack, Token.Id.Keyword_fn)) ?? continue;
1480 // TODO shouldn't need this cast1574 // TODO shouldn't need this cast
1481 const fn_proto = try self.createFnProto(arena, undefined,1575 const fn_proto = try self.createFnProto(arena, fn_token,
1482 (?Token)(null), (?&ast.Node)(null), (?Token)(token), (?Token)(null), (?Token)(null));1576 (?Token)(null), (?&ast.Node)(null), (?Token)(token), (?Token)(null), (?Token)(null));
1483 dest_ptr.store(&fn_proto.base);1577 dest_ptr.store(&fn_proto.base);
1484 stack.append(State { .FnProto = fn_proto }) catch unreachable;1578 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1485 try stack.append(State {
1486 .ExpectTokenSave = ExpectTokenSave {
1487 .id = Token.Id.Keyword_fn,
1488 .ptr = &fn_proto.fn_token,
1489 }
1490 });
1491 continue;1579 continue;
1492 },1580 },
1493 Token.Id.Keyword_asm => {1581 Token.Id.Keyword_asm => {
...@@ -1544,7 +1632,7 @@ pub const Parser = struct {...@@ -1544,7 +1632,7 @@ pub const Parser = struct {
15441632
1545 stack.append(State { .Else = &node.@"else" }) catch unreachable;1633 stack.append(State { .Else = &node.@"else" }) catch unreachable;
1546 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });1634 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
1547 try stack.append(State { .ValuePayload = &node.payload });1635 try stack.append(State { .PointerPayload = &node.payload });
1548 try stack.append(State { .ExpectToken = Token.Id.RParen });1636 try stack.append(State { .ExpectToken = Token.Id.RParen });
1549 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });1637 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
1550 try stack.append(State { .ExpectToken = Token.Id.LParen });1638 try stack.append(State { .ExpectToken = Token.Id.LParen });
...@@ -1816,7 +1904,7 @@ pub const Parser = struct {...@@ -1816,7 +1904,7 @@ pub const Parser = struct {
1816 try list_state.list.append(node);1904 try list_state.list.append(node);
1817 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;1905 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;
1818 try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } });1906 try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } });
1819 try stack.append(State { .ValuePayload = &node.payload });1907 try stack.append(State { .PointerPayload = &node.payload });
18201908
1821 const maybe_else = self.getNextToken();1909 const maybe_else = self.getNextToken();
1822 if (maybe_else.id == Token.Id.Keyword_else) {1910 if (maybe_else.id == Token.Id.Keyword_else) {
...@@ -1883,7 +1971,7 @@ pub const Parser = struct {...@@ -1883,7 +1971,7 @@ pub const Parser = struct {
1883 *dest = node;1971 *dest = node;
18841972
1885 stack.append(State { .Expression = DestPtr { .Field = &node.body } }) catch unreachable;1973 stack.append(State { .Expression = DestPtr { .Field = &node.body } }) catch unreachable;
1886 try stack.append(State { .ErrorPayload = &node.payload });1974 try stack.append(State { .Payload = &node.payload });
1887 },1975 },
18881976
1889 State.WhileContinueExpr => |dest| {1977 State.WhileContinueExpr => |dest| {
...@@ -1898,7 +1986,41 @@ pub const Parser = struct {...@@ -1898,7 +1986,41 @@ pub const Parser = struct {
1898 try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = dest } });1986 try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = dest } });
1899 },1987 },
19001988
1901 State.ErrorPayload => |dest| {1989 State.SuspendBody => |suspend_node| {
1990 if (suspend_node.payload != null) {
1991 try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = &suspend_node.body } });
1992 }
1993 continue;
1994 },
1995
1996 State.AsyncEnd => |ctx| {
1997 const node = ctx.dest_ptr.get();
1998
1999 switch (node.id) {
2000 ast.Node.Id.FnProto => {
2001 const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node);
2002 fn_proto.async_attr = ctx.attribute;
2003 },
2004 ast.Node.Id.SuffixOp => {
2005 const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node);
2006 if (suffix_op.op == ast.NodeSuffixOp.SuffixOp.Call) {
2007 suffix_op.op.Call.async_attr = ctx.attribute;
2008 continue;
2009 }
2010
2011 try self.parseError(&stack, node.firstToken(), "expected call or fn proto, found {}.",
2012 @tagName(suffix_op.op));
2013 continue;
2014 },
2015 else => {
2016 try self.parseError(&stack, node.firstToken(), "expected call or fn proto, found {}.",
2017 @tagName(node.id));
2018 continue;
2019 }
2020 }
2021 },
2022
2023 State.Payload => |dest| {
1902 const lpipe = self.getNextToken();2024 const lpipe = self.getNextToken();
1903 if (lpipe.id != Token.Id.Pipe) {2025 if (lpipe.id != Token.Id.Pipe) {
1904 self.putBackToken(lpipe);2026 self.putBackToken(lpipe);
...@@ -1907,9 +2029,9 @@ pub const Parser = struct {...@@ -1907,9 +2029,9 @@ pub const Parser = struct {
19072029
1908 const error_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;2030 const error_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
1909 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;2031 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
1910 const node = try arena.create(ast.NodeErrorPayload);2032 const node = try arena.create(ast.NodePayload);
1911 *node = ast.NodeErrorPayload {2033 *node = ast.NodePayload {
1912 .base = self.initNode(ast.Node.Id.ErrorPayload),2034 .base = self.initNode(ast.Node.Id.Payload),
1913 .lpipe = lpipe,2035 .lpipe = lpipe,
1914 .error_symbol = try self.createIdentifier(arena, error_symbol),2036 .error_symbol = try self.createIdentifier(arena, error_symbol),
1915 .rpipe = rpipe2037 .rpipe = rpipe
...@@ -1917,7 +2039,7 @@ pub const Parser = struct {...@@ -1917,7 +2039,7 @@ pub const Parser = struct {
1917 *dest = node;2039 *dest = node;
1918 },2040 },
19192041
1920 State.ValuePayload => |dest| {2042 State.PointerPayload => |dest| {
1921 const lpipe = self.getNextToken();2043 const lpipe = self.getNextToken();
1922 if (lpipe.id != Token.Id.Pipe) {2044 if (lpipe.id != Token.Id.Pipe) {
1923 self.putBackToken(lpipe);2045 self.putBackToken(lpipe);
...@@ -1936,9 +2058,9 @@ pub const Parser = struct {...@@ -1936,9 +2058,9 @@ pub const Parser = struct {
19362058
1937 const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;2059 const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
1938 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;2060 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
1939 const node = try arena.create(ast.NodeValuePayload);2061 const node = try arena.create(ast.NodePointerPayload);
1940 *node = ast.NodeValuePayload {2062 *node = ast.NodePointerPayload {
1941 .base = self.initNode(ast.Node.Id.ValuePayload),2063 .base = self.initNode(ast.Node.Id.PointerPayload),
1942 .lpipe = lpipe,2064 .lpipe = lpipe,
1943 .is_ptr = is_ptr,2065 .is_ptr = is_ptr,
1944 .value_symbol = try self.createIdentifier(arena, value_symbol),2066 .value_symbol = try self.createIdentifier(arena, value_symbol),
...@@ -1947,7 +2069,7 @@ pub const Parser = struct {...@@ -1947,7 +2069,7 @@ pub const Parser = struct {
1947 *dest = node;2069 *dest = node;
1948 },2070 },
19492071
1950 State.ValueIndexPayload => |dest| {2072 State.PointerIndexPayload => |dest| {
1951 const lpipe = self.getNextToken();2073 const lpipe = self.getNextToken();
1952 if (lpipe.id != Token.Id.Pipe) {2074 if (lpipe.id != Token.Id.Pipe) {
1953 self.putBackToken(lpipe);2075 self.putBackToken(lpipe);
...@@ -1977,9 +2099,9 @@ pub const Parser = struct {...@@ -1977,9 +2099,9 @@ pub const Parser = struct {
1977 };2099 };
19782100
1979 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;2101 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
1980 const node = try arena.create(ast.NodeValueIndexPayload);2102 const node = try arena.create(ast.NodePointerIndexPayload);
1981 *node = ast.NodeValueIndexPayload {2103 *node = ast.NodePointerIndexPayload {
1982 .base = self.initNode(ast.Node.Id.ValueIndexPayload),2104 .base = self.initNode(ast.Node.Id.PointerIndexPayload),
1983 .lpipe = lpipe,2105 .lpipe = lpipe,
1984 .is_ptr = is_ptr,2106 .is_ptr = is_ptr,
1985 .value_symbol = try self.createIdentifier(arena, value_symbol),2107 .value_symbol = try self.createIdentifier(arena, value_symbol),
...@@ -2249,7 +2371,7 @@ pub const Parser = struct {...@@ -2249,7 +2371,7 @@ pub const Parser = struct {
2249 stack.append(State { .Else = &node.@"else" }) catch unreachable;2371 stack.append(State { .Else = &node.@"else" }) catch unreachable;
2250 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });2372 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
2251 try stack.append(State { .WhileContinueExpr = &node.continue_expr });2373 try stack.append(State { .WhileContinueExpr = &node.continue_expr });
2252 try stack.append(State { .ValuePayload = &node.payload });2374 try stack.append(State { .PointerPayload = &node.payload });
2253 try stack.append(State { .ExpectToken = Token.Id.RParen });2375 try stack.append(State { .ExpectToken = Token.Id.RParen });
2254 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });2376 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
2255 try stack.append(State { .ExpectToken = Token.Id.LParen });2377 try stack.append(State { .ExpectToken = Token.Id.LParen });
...@@ -2271,7 +2393,7 @@ pub const Parser = struct {...@@ -2271,7 +2393,7 @@ pub const Parser = struct {
22712393
2272 stack.append(State { .Else = &node.@"else" }) catch unreachable;2394 stack.append(State { .Else = &node.@"else" }) catch unreachable;
2273 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });2395 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
2274 try stack.append(State { .ValueIndexPayload = &node.payload });2396 try stack.append(State { .PointerIndexPayload = &node.payload });
2275 try stack.append(State { .ExpectToken = Token.Id.RParen });2397 try stack.append(State { .ExpectToken = Token.Id.RParen });
2276 try stack.append(State { .Expression = DestPtr { .Field = &node.array_expr } });2398 try stack.append(State { .Expression = DestPtr { .Field = &node.array_expr } });
2277 try stack.append(State { .ExpectToken = Token.Id.LParen });2399 try stack.append(State { .ExpectToken = Token.Id.LParen });
...@@ -2374,9 +2496,9 @@ pub const Parser = struct {...@@ -2374,9 +2496,9 @@ pub const Parser = struct {
2374 ast.Node.Id.EnumTag,2496 ast.Node.Id.EnumTag,
2375 ast.Node.Id.ParamDecl,2497 ast.Node.Id.ParamDecl,
2376 ast.Node.Id.Block,2498 ast.Node.Id.Block,
2377 ast.Node.Id.ErrorPayload,2499 ast.Node.Id.Payload,
2378 ast.Node.Id.ValuePayload,2500 ast.Node.Id.PointerPayload,
2379 ast.Node.Id.ValueIndexPayload,2501 ast.Node.Id.PointerIndexPayload,
2380 ast.Node.Id.Switch,2502 ast.Node.Id.Switch,
2381 ast.Node.Id.SwitchCase,2503 ast.Node.Id.SwitchCase,
2382 ast.Node.Id.SwitchElse,2504 ast.Node.Id.SwitchElse,
...@@ -2422,6 +2544,15 @@ pub const Parser = struct {...@@ -2422,6 +2544,15 @@ pub const Parser = struct {
2422 const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", n);2544 const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", n);
2423 n = comptime_node.expr;2545 n = comptime_node.expr;
2424 },2546 },
2547 ast.Node.Id.Suspend => {
2548 const suspend_node = @fieldParentPtr(ast.NodeSuspend, "base", n);
2549 if (suspend_node.body) |body| {
2550 n = body;
2551 continue;
2552 }
2553
2554 return true;
2555 },
2425 else => return true,2556 else => return true,
2426 }2557 }
2427 }2558 }
...@@ -2540,6 +2671,7 @@ pub const Parser = struct {...@@ -2540,6 +2671,7 @@ pub const Parser = struct {
2540 },2671 },
2541 Token.Id.QuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.MaybeType),2672 Token.Id.QuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.MaybeType),
2542 Token.Id.QuestionMarkQuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.UnwrapMaybe),2673 Token.Id.QuestionMarkQuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.UnwrapMaybe),
2674 Token.Id.Keyword_await => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.Await),
2543 else => null,2675 else => null,
2544 };2676 };
2545 }2677 }
...@@ -2628,6 +2760,7 @@ pub const Parser = struct {...@@ -2628,6 +2760,7 @@ pub const Parser = struct {
2628 .extern_token = *extern_token,2760 .extern_token = *extern_token,
2629 .inline_token = *inline_token,2761 .inline_token = *inline_token,
2630 .cc_token = *cc_token,2762 .cc_token = *cc_token,
2763 .async_attr = null,
2631 .body_node = null,2764 .body_node = null,
2632 .lib_name = lib_name,2765 .lib_name = lib_name,
2633 .align_expr = null,2766 .align_expr = null,
...@@ -3105,6 +3238,30 @@ pub const Parser = struct {...@@ -3105,6 +3238,30 @@ pub const Parser = struct {
3105 try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_node.comptime_token));3238 try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_node.comptime_token));
3106 try stack.append(RenderState { .Expression = comptime_node.expr });3239 try stack.append(RenderState { .Expression = comptime_node.expr });
3107 },3240 },
3241 ast.Node.Id.AsyncAttribute => {
3242 const async_attr = @fieldParentPtr(ast.NodeAsyncAttribute, "base", base);
3243 try stream.print("{}", self.tokenizer.getTokenSlice(async_attr.async_token));
3244
3245 if (async_attr.allocator_type) |allocator_type| {
3246 try stack.append(RenderState { .Text = ">" });
3247 try stack.append(RenderState { .Expression = allocator_type });
3248 try stack.append(RenderState { .Text = "<" });
3249 }
3250 },
3251 ast.Node.Id.Suspend => {
3252 const suspend_node = @fieldParentPtr(ast.NodeSuspend, "base", base);
3253 try stream.print("{}", self.tokenizer.getTokenSlice(suspend_node.suspend_token));
3254
3255 if (suspend_node.body) |body| {
3256 try stack.append(RenderState { .Expression = body });
3257 try stack.append(RenderState { .Text = " " });
3258 }
3259
3260 if (suspend_node.payload) |payload| {
3261 try stack.append(RenderState { .Expression = &payload.base });
3262 try stack.append(RenderState { .Text = " " });
3263 }
3264 },
3108 ast.Node.Id.InfixOp => {3265 ast.Node.Id.InfixOp => {
3109 const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base);3266 const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base);
3110 try stack.append(RenderState { .Expression = prefix_op_node.rhs });3267 try stack.append(RenderState { .Expression = prefix_op_node.rhs });
...@@ -3211,6 +3368,9 @@ pub const Parser = struct {...@@ -3211,6 +3368,9 @@ pub const Parser = struct {
3211 ast.NodePrefixOp.PrefixOp.Try => try stream.write("try "),3368 ast.NodePrefixOp.PrefixOp.Try => try stream.write("try "),
3212 ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"),3369 ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"),
3213 ast.NodePrefixOp.PrefixOp.MaybeType => try stream.write("?"),3370 ast.NodePrefixOp.PrefixOp.MaybeType => try stream.write("?"),
3371 ast.NodePrefixOp.PrefixOp.Await => try stream.write("await "),
3372 ast.NodePrefixOp.PrefixOp.Cancel => try stream.write("cancel "),
3373 ast.NodePrefixOp.PrefixOp.Resume => try stream.write("resume "),
3214 }3374 }
3215 },3375 },
3216 ast.Node.Id.SuffixOp => {3376 ast.Node.Id.SuffixOp => {
...@@ -3229,11 +3389,18 @@ pub const Parser = struct {...@@ -3229,11 +3389,18 @@ pub const Parser = struct {
3229 }3389 }
3230 }3390 }
3231 try stack.append(RenderState { .Text = "("});3391 try stack.append(RenderState { .Text = "("});
3392 try stack.append(RenderState { .Expression = suffix_op.lhs });
3393
3394 if (call_info.async_attr) |async_attr| {
3395 try stack.append(RenderState { .Text = " "});
3396 try stack.append(RenderState { .Expression = &async_attr.base });
3397 }
3232 },3398 },
3233 ast.NodeSuffixOp.SuffixOp.ArrayAccess => |index_expr| {3399 ast.NodeSuffixOp.SuffixOp.ArrayAccess => |index_expr| {
3234 try stack.append(RenderState { .Text = "]"});3400 try stack.append(RenderState { .Text = "]"});
3235 try stack.append(RenderState { .Expression = index_expr});3401 try stack.append(RenderState { .Expression = index_expr});
3236 try stack.append(RenderState { .Text = "["});3402 try stack.append(RenderState { .Text = "["});
3403 try stack.append(RenderState { .Expression = suffix_op.lhs });
3237 },3404 },
3238 ast.NodeSuffixOp.SuffixOp.Slice => |range| {3405 ast.NodeSuffixOp.SuffixOp.Slice => |range| {
3239 try stack.append(RenderState { .Text = "]"});3406 try stack.append(RenderState { .Text = "]"});
...@@ -3243,6 +3410,7 @@ pub const Parser = struct {...@@ -3243,6 +3410,7 @@ pub const Parser = struct {
3243 try stack.append(RenderState { .Text = ".."});3410 try stack.append(RenderState { .Text = ".."});
3244 try stack.append(RenderState { .Expression = range.start});3411 try stack.append(RenderState { .Expression = range.start});
3245 try stack.append(RenderState { .Text = "["});3412 try stack.append(RenderState { .Text = "["});
3413 try stack.append(RenderState { .Expression = suffix_op.lhs });
3246 },3414 },
3247 ast.NodeSuffixOp.SuffixOp.StructInitializer => |field_inits| {3415 ast.NodeSuffixOp.SuffixOp.StructInitializer => |field_inits| {
3248 try stack.append(RenderState { .Text = " }"});3416 try stack.append(RenderState { .Text = " }"});
...@@ -3257,6 +3425,7 @@ pub const Parser = struct {...@@ -3257,6 +3425,7 @@ pub const Parser = struct {
3257 }3425 }
3258 }3426 }
3259 try stack.append(RenderState { .Text = "{"});3427 try stack.append(RenderState { .Text = "{"});
3428 try stack.append(RenderState { .Expression = suffix_op.lhs });
3260 },3429 },
3261 ast.NodeSuffixOp.SuffixOp.ArrayInitializer => |exprs| {3430 ast.NodeSuffixOp.SuffixOp.ArrayInitializer => |exprs| {
3262 try stack.append(RenderState { .Text = " }"});3431 try stack.append(RenderState { .Text = " }"});
...@@ -3271,10 +3440,9 @@ pub const Parser = struct {...@@ -3271,10 +3440,9 @@ pub const Parser = struct {
3271 }3440 }
3272 }3441 }
3273 try stack.append(RenderState { .Text = "{"});3442 try stack.append(RenderState { .Text = "{"});
3443 try stack.append(RenderState { .Expression = suffix_op.lhs });
3274 },3444 },
3275 }3445 }
3276
3277 try stack.append(RenderState { .Expression = suffix_op.lhs });
3278 },3446 },
3279 ast.Node.Id.ControlFlowExpression => {3447 ast.Node.Id.ControlFlowExpression => {
3280 const flow_expr = @fieldParentPtr(ast.NodeControlFlowExpression, "base", base);3448 const flow_expr = @fieldParentPtr(ast.NodeControlFlowExpression, "base", base);
...@@ -3302,14 +3470,14 @@ pub const Parser = struct {...@@ -3302,14 +3470,14 @@ pub const Parser = struct {
3302 try stack.append(RenderState { .Expression = rhs });3470 try stack.append(RenderState { .Expression = rhs });
3303 }3471 }
3304 },3472 },
3305 ast.Node.Id.ErrorPayload => {3473 ast.Node.Id.Payload => {
3306 const payload = @fieldParentPtr(ast.NodeErrorPayload, "base", base);3474 const payload = @fieldParentPtr(ast.NodePayload, "base", base);
3307 try stack.append(RenderState { .Text = "|"});3475 try stack.append(RenderState { .Text = "|"});
3308 try stack.append(RenderState { .Expression = &payload.error_symbol.base });3476 try stack.append(RenderState { .Expression = &payload.error_symbol.base });
3309 try stack.append(RenderState { .Text = "|"});3477 try stack.append(RenderState { .Text = "|"});
3310 },3478 },
3311 ast.Node.Id.ValuePayload => {3479 ast.Node.Id.PointerPayload => {
3312 const payload = @fieldParentPtr(ast.NodeValuePayload, "base", base);3480 const payload = @fieldParentPtr(ast.NodePointerPayload, "base", base);
3313 try stack.append(RenderState { .Text = "|"});3481 try stack.append(RenderState { .Text = "|"});
3314 try stack.append(RenderState { .Expression = &payload.value_symbol.base });3482 try stack.append(RenderState { .Expression = &payload.value_symbol.base });
33153483
...@@ -3319,8 +3487,8 @@ pub const Parser = struct {...@@ -3319,8 +3487,8 @@ pub const Parser = struct {
33193487
3320 try stack.append(RenderState { .Text = "|"});3488 try stack.append(RenderState { .Text = "|"});
3321 },3489 },
3322 ast.Node.Id.ValueIndexPayload => {3490 ast.Node.Id.PointerIndexPayload => {
3323 const payload = @fieldParentPtr(ast.NodeValueIndexPayload, "base", base);3491 const payload = @fieldParentPtr(ast.NodePointerIndexPayload, "base", base);
3324 try stack.append(RenderState { .Text = "|"});3492 try stack.append(RenderState { .Text = "|"});
33253493
3326 if (payload.index_symbol) |index_symbol| {3494 if (payload.index_symbol) |index_symbol| {
...@@ -3553,6 +3721,11 @@ pub const Parser = struct {...@@ -3553,6 +3721,11 @@ pub const Parser = struct {
35533721
3554 try stack.append(RenderState { .Text = "fn" });3722 try stack.append(RenderState { .Text = "fn" });
35553723
3724 if (fn_proto.async_attr) |async_attr| {
3725 try stack.append(RenderState { .Text = " " });
3726 try stack.append(RenderState { .Expression = &async_attr.base });
3727 }
3728
3556 if (fn_proto.cc_token) |cc_token| {3729 if (fn_proto.cc_token) |cc_token| {
3557 try stack.append(RenderState { .Text = " " });3730 try stack.append(RenderState { .Text = " " });
3558 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(cc_token) });3731 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(cc_token) });
...@@ -4789,8 +4962,7 @@ test "zig fmt: coroutines" {...@@ -4789,8 +4962,7 @@ test "zig fmt: coroutines" {
4789 \\ x += 1;4962 \\ x += 1;
4790 \\ suspend;4963 \\ suspend;
4791 \\ x += 1;4964 \\ x += 1;
4792 \\ suspend |p| {4965 \\ suspend |p| {}
4793 \\ }
4794 \\ const p = async simpleAsyncFn() catch unreachable;4966 \\ const p = async simpleAsyncFn() catch unreachable;
4795 \\ await p;4967 \\ await p;
4796 \\}4968 \\}
...@@ -4803,10 +4975,3 @@ test "zig fmt: coroutines" {...@@ -4803,10 +4975,3 @@ test "zig fmt: coroutines" {
4803 \\4975 \\
4804 );4976 );
4805}4977}
4806
4807test "zig fmt: zig fmt" {
4808 try testCanonical(@embedFile("ast.zig"));
4809 try testCanonical(@embedFile("index.zig"));
4810 try testCanonical(@embedFile("parser.zig"));
4811 try testCanonical(@embedFile("tokenizer.zig"));
4812}