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 {
1717 UnionTag,
1818 EnumTag,
1919 Identifier,
20 AsyncAttribute,
2021 FnProto,
2122 ParamDecl,
2223 Block,
2324 Defer,
2425 Comptime,
25 ErrorPayload,
26 ValuePayload,
27 ValueIndexPayload,
26 Payload,
27 PointerPayload,
28 PointerIndexPayload,
2829 Else,
2930 Switch,
3031 SwitchCase,
......@@ -37,6 +38,7 @@ pub const Node = struct {
3738 SuffixOp,
3839 GroupedExpression,
3940 ControlFlowExpression,
41 Suspend,
4042 FieldInitializer,
4143 IntegerLiteral,
4244 FloatLiteral,
......@@ -67,14 +69,15 @@ pub const Node = struct {
6769 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).iterate(index),
6870 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).iterate(index),
6971 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).iterate(index),
72 Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).iterate(index),
7073 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index),
7174 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index),
7275 Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index),
7376 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).iterate(index),
7477 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).iterate(index),
75 Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).iterate(index),
76 Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).iterate(index),
77 Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).iterate(index),
78 Id.Payload => @fieldParentPtr(NodePayload, "base", base).iterate(index),
79 Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).iterate(index),
80 Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).iterate(index),
7881 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
7982 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
8083 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).iterate(index),
......@@ -87,6 +90,7 @@ pub const Node = struct {
8790 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
8891 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).iterate(index),
8992 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).iterate(index),
93 Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).iterate(index),
9094 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).iterate(index),
9195 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
9296 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
......@@ -118,14 +122,15 @@ pub const Node = struct {
118122 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).firstToken(),
119123 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).firstToken(),
120124 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).firstToken(),
125 Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).firstToken(),
121126 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(),
122127 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(),
123128 Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(),
124129 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).firstToken(),
125130 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).firstToken(),
126 Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).firstToken(),
127 Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).firstToken(),
128 Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).firstToken(),
131 Id.Payload => @fieldParentPtr(NodePayload, "base", base).firstToken(),
132 Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).firstToken(),
133 Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).firstToken(),
129134 Id.Else => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
130135 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
131136 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).firstToken(),
......@@ -138,6 +143,7 @@ pub const Node = struct {
138143 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
139144 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).firstToken(),
140145 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).firstToken(),
146 Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).firstToken(),
141147 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).firstToken(),
142148 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),
143149 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),
......@@ -169,14 +175,15 @@ pub const Node = struct {
169175 Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).lastToken(),
170176 Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).lastToken(),
171177 Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).lastToken(),
178 Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).lastToken(),
172179 Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(),
173180 Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(),
174181 Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(),
175182 Id.Defer => @fieldParentPtr(NodeDefer, "base", base).lastToken(),
176183 Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).lastToken(),
177 Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).lastToken(),
178 Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).lastToken(),
179 Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).lastToken(),
184 Id.Payload => @fieldParentPtr(NodePayload, "base", base).lastToken(),
185 Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).lastToken(),
186 Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).lastToken(),
180187 Id.Else => @fieldParentPtr(NodeElse, "base", base).lastToken(),
181188 Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).lastToken(),
182189 Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).lastToken(),
......@@ -189,6 +196,7 @@ pub const Node = struct {
189196 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
190197 Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).lastToken(),
191198 Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).lastToken(),
199 Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).lastToken(),
192200 Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).lastToken(),
193201 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),
194202 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),
......@@ -456,6 +464,36 @@ pub const NodeIdentifier = struct {
456464 }
457465};
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
459497pub const NodeFnProto = struct {
460498 base: Node,
461499 visib_token: ?Token,
......@@ -467,6 +505,7 @@ pub const NodeFnProto = struct {
467505 extern_token: ?Token,
468506 inline_token: ?Token,
469507 cc_token: ?Token,
508 async_attr: ?&NodeAsyncAttribute,
470509 body_node: ?&Node,
471510 lib_name: ?&Node, // populated if this is an extern declaration
472511 align_expr: ?&Node, // populated if align(A) is present
......@@ -511,6 +550,14 @@ pub const NodeFnProto = struct {
511550 i -= 1;
512551 }
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
514561 return null;
515562 }
516563
......@@ -645,13 +692,13 @@ pub const NodeComptime = struct {
645692 }
646693};
647694
648pub const NodeErrorPayload = struct {
695pub const NodePayload = struct {
649696 base: Node,
650697 lpipe: Token,
651698 error_symbol: &NodeIdentifier,
652699 rpipe: Token,
653700
654 pub fn iterate(self: &NodeErrorPayload, index: usize) ?&Node {
701 pub fn iterate(self: &NodePayload, index: usize) ?&Node {
655702 var i = index;
656703
657704 if (i < 1) return &self.error_symbol.base;
......@@ -660,23 +707,23 @@ pub const NodeErrorPayload = struct {
660707 return null;
661708 }
662709
663 pub fn firstToken(self: &NodeErrorPayload) Token {
710 pub fn firstToken(self: &NodePayload) Token {
664711 return self.lpipe;
665712 }
666713
667 pub fn lastToken(self: &NodeErrorPayload) Token {
714 pub fn lastToken(self: &NodePayload) Token {
668715 return self.rpipe;
669716 }
670717};
671718
672pub const NodeValuePayload = struct {
719pub const NodePointerPayload = struct {
673720 base: Node,
674721 lpipe: Token,
675722 is_ptr: bool,
676723 value_symbol: &NodeIdentifier,
677724 rpipe: Token,
678725
679 pub fn iterate(self: &NodeValuePayload, index: usize) ?&Node {
726 pub fn iterate(self: &NodePointerPayload, index: usize) ?&Node {
680727 var i = index;
681728
682729 if (i < 1) return &self.value_symbol.base;
......@@ -685,16 +732,16 @@ pub const NodeValuePayload = struct {
685732 return null;
686733 }
687734
688 pub fn firstToken(self: &NodeValuePayload) Token {
735 pub fn firstToken(self: &NodePointerPayload) Token {
689736 return self.lpipe;
690737 }
691738
692 pub fn lastToken(self: &NodeValuePayload) Token {
739 pub fn lastToken(self: &NodePointerPayload) Token {
693740 return self.rpipe;
694741 }
695742};
696743
697pub const NodeValueIndexPayload = struct {
744pub const NodePointerIndexPayload = struct {
698745 base: Node,
699746 lpipe: Token,
700747 is_ptr: bool,
......@@ -702,7 +749,7 @@ pub const NodeValueIndexPayload = struct {
702749 index_symbol: ?&NodeIdentifier,
703750 rpipe: Token,
704751
705 pub fn iterate(self: &NodeValueIndexPayload, index: usize) ?&Node {
752 pub fn iterate(self: &NodePointerIndexPayload, index: usize) ?&Node {
706753 var i = index;
707754
708755 if (i < 1) return &self.value_symbol.base;
......@@ -716,11 +763,11 @@ pub const NodeValueIndexPayload = struct {
716763 return null;
717764 }
718765
719 pub fn firstToken(self: &NodeValueIndexPayload) Token {
766 pub fn firstToken(self: &NodePointerIndexPayload) Token {
720767 return self.lpipe;
721768 }
722769
723 pub fn lastToken(self: &NodeValueIndexPayload) Token {
770 pub fn lastToken(self: &NodePointerIndexPayload) Token {
724771 return self.rpipe;
725772 }
726773};
......@@ -728,7 +775,7 @@ pub const NodeValueIndexPayload = struct {
728775pub const NodeElse = struct {
729776 base: Node,
730777 else_token: Token,
731 payload: ?&NodeErrorPayload,
778 payload: ?&NodePayload,
732779 body: &Node,
733780
734781 pub fn iterate(self: &NodeElse, index: usize) ?&Node {
......@@ -785,7 +832,7 @@ pub const NodeSwitch = struct {
785832pub const NodeSwitchCase = struct {
786833 base: Node,
787834 items: ArrayList(&Node),
788 payload: ?&NodeValuePayload,
835 payload: ?&NodePointerPayload,
789836 expr: &Node,
790837
791838 pub fn iterate(self: &NodeSwitchCase, index: usize) ?&Node {
......@@ -837,7 +884,7 @@ pub const NodeWhile = struct {
837884 inline_token: ?Token,
838885 while_token: Token,
839886 condition: &Node,
840 payload: ?&NodeValuePayload,
887 payload: ?&NodePointerPayload,
841888 continue_expr: ?&Node,
842889 body: &Node,
843890 @"else": ?&NodeElse,
......@@ -896,7 +943,7 @@ pub const NodeFor = struct {
896943 inline_token: ?Token,
897944 for_token: Token,
898945 array_expr: &Node,
899 payload: ?&NodeValueIndexPayload,
946 payload: ?&NodePointerIndexPayload,
900947 body: &Node,
901948 @"else": ?&NodeElse,
902949
......@@ -947,7 +994,7 @@ pub const NodeIf = struct {
947994 base: Node,
948995 if_token: Token,
949996 condition: &Node,
950 payload: ?&NodeValuePayload,
997 payload: ?&NodePointerPayload,
951998 body: &Node,
952999 @"else": ?&NodeElse,
9531000
......@@ -1020,7 +1067,7 @@ pub const NodeInfixOp = struct {
10201067 BitXor,
10211068 BoolAnd,
10221069 BoolOr,
1023 Catch: ?&NodeErrorPayload,
1070 Catch: ?&NodePayload,
10241071 Div,
10251072 EqualEqual,
10261073 ErrorUnion,
......@@ -1113,13 +1160,16 @@ pub const NodePrefixOp = struct {
11131160
11141161 const PrefixOp = union(enum) {
11151162 AddrOf: AddrOfInfo,
1163 ArrayType: &Node,
1164 Await,
11161165 BitNot,
11171166 BoolNot,
1167 Cancel,
11181168 Deref,
11191169 MaybeType,
11201170 Negation,
11211171 NegationWrap,
1122 ArrayType: &Node,
1172 Resume,
11231173 SliceType: AddrOfInfo,
11241174 Try,
11251175 UnwrapMaybe,
......@@ -1153,13 +1203,16 @@ pub const NodePrefixOp = struct {
11531203 if (i < 1) return size_expr;
11541204 i -= 1;
11551205 },
1206 PrefixOp.Await,
11561207 PrefixOp.BitNot,
11571208 PrefixOp.BoolNot,
1209 PrefixOp.Cancel,
11581210 PrefixOp.Deref,
11591211 PrefixOp.Negation,
11601212 PrefixOp.NegationWrap,
11611213 PrefixOp.Return,
11621214 PrefixOp.Try,
1215 PrefixOp.Resume,
11631216 PrefixOp.UnwrapMaybe => {},
11641217 }
11651218
......@@ -1218,8 +1271,7 @@ pub const NodeSuffixOp = struct {
12181271
12191272 const CallInfo = struct {
12201273 params: ArrayList(&Node),
1221 is_async: bool,
1222 allocator: ?&Node,
1274 async_attr: ?&NodeAsyncAttribute,
12231275 };
12241276
12251277 const SliceRange = struct {
......@@ -1347,6 +1399,45 @@ pub const NodeControlFlowExpression = struct {
13471399 }
13481400};
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
13501441pub const NodeIntegerLiteral = struct {
13511442 base: Node,
13521443 token: Token,
std/zig/parser.zig+221-56
......@@ -134,6 +134,11 @@ pub const Parser = struct {
134134 dest_ptr: DestPtr,
135135 };
136136
137 const AsyncEndCtx = struct {
138 dest_ptr: DestPtr,
139 attribute: &ast.NodeAsyncAttribute,
140 };
141
137142 const State = union(enum) {
138143 TopLevel,
139144 TopLevelExtern: TopLevelDeclCtx,
......@@ -173,9 +178,11 @@ pub const Parser = struct {
173178 FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),
174179 FieldListCommaOrEnd: &ast.NodeContainerDecl,
175180 SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),
176 ErrorPayload: &?&ast.NodeErrorPayload,
177 ValuePayload: &?&ast.NodeValuePayload,
178 ValueIndexPayload: &?&ast.NodeValueIndexPayload,
181 SuspendBody: &ast.NodeSuspend,
182 AsyncEnd: AsyncEndCtx,
183 Payload: &?&ast.NodePayload,
184 PointerPayload: &?&ast.NodePointerPayload,
185 PointerIndexPayload: &?&ast.NodePointerIndexPayload,
179186 SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase),
180187 SwitchCaseItem: &ArrayList(&ast.Node),
181188 SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node),
......@@ -399,6 +406,45 @@ pub const Parser = struct {
399406 });
400407 continue;
401408 },
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 },
402448 else => {
403449 try self.parseError(&stack, token, "expected variable declaration or function, found {}", @tagName(token.id));
404450 continue;
......@@ -711,13 +757,14 @@ pub const Parser = struct {
711757 continue;
712758 },
713759 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;
715763 },
716764 Token.Id.Keyword_resume => {
717 @panic("TODO: resume");
718 },
719 Token.Id.Keyword_await => {
720 @panic("TODO: await");
765 const resume_node = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp.Resume);
766 dest_ptr.store(&resume_node.base);
767 stack.append(State { .Expression = DestPtr { .Field = &resume_node.rhs } }) catch unreachable;
721768 },
722769 else => {
723770 self.putBackToken(token);
......@@ -786,7 +833,7 @@ pub const Parser = struct {
786833
787834 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
788835 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 });
790837 continue;
791838 },
792839 Token.Id.QuestionMarkQuestionMark => {
......@@ -1113,6 +1160,9 @@ pub const Parser = struct {
11131160 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
11141161 }
11151162 continue;
1163 //Token.Id.Keyword_await => {
1164 // @panic("TODO: await");
1165 //},
11161166 } else {
11171167 self.putBackToken(token);
11181168 stack.append(State { .SuffixOpExpressionBegin = dest_ptr }) catch unreachable;
......@@ -1124,7 +1174,38 @@ pub const Parser = struct {
11241174 const token = self.getNextToken();
11251175 switch (token.id) {
11261176 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;
11281209 },
11291210 else => {
11301211 self.putBackToken(token);
......@@ -1142,8 +1223,7 @@ pub const Parser = struct {
11421223 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
11431224 .Call = ast.NodeSuffixOp.CallInfo {
11441225 .params = ArrayList(&ast.Node).init(arena),
1145 .is_async = false, // TODO: ASYNC
1146 .allocator = null,
1226 .async_attr = null,
11471227 }
11481228 });
11491229 node.lhs = dest_ptr.get();
......@@ -1257,6 +1337,19 @@ pub const Parser = struct {
12571337 dest_ptr.store(&node.base);
12581338 continue;
12591339 },
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 },
12601353 Token.Id.MultilineStringLiteralLine => {
12611354 const node = try arena.create(ast.NodeMultilineStringLiteral);
12621355 *node = ast.NodeMultilineStringLiteral {
......@@ -1477,17 +1570,12 @@ pub const Parser = struct {
14771570 continue;
14781571 },
14791572 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
1573 const fn_token = (try self.eatToken(&stack, Token.Id.Keyword_fn)) ?? continue;
14801574 // 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,
14821576 (?Token)(null), (?&ast.Node)(null), (?Token)(token), (?Token)(null), (?Token)(null));
14831577 dest_ptr.store(&fn_proto.base);
14841578 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 });
14911579 continue;
14921580 },
14931581 Token.Id.Keyword_asm => {
......@@ -1544,7 +1632,7 @@ pub const Parser = struct {
15441632
15451633 stack.append(State { .Else = &node.@"else" }) catch unreachable;
15461634 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 });
15481636 try stack.append(State { .ExpectToken = Token.Id.RParen });
15491637 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
15501638 try stack.append(State { .ExpectToken = Token.Id.LParen });
......@@ -1816,7 +1904,7 @@ pub const Parser = struct {
18161904 try list_state.list.append(node);
18171905 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;
18181906 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
18211909 const maybe_else = self.getNextToken();
18221910 if (maybe_else.id == Token.Id.Keyword_else) {
......@@ -1883,7 +1971,7 @@ pub const Parser = struct {
18831971 *dest = node;
18841972
18851973 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 });
18871975 },
18881976
18891977 State.WhileContinueExpr => |dest| {
......@@ -1898,7 +1986,41 @@ pub const Parser = struct {
18981986 try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = dest } });
18991987 },
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| {
19022024 const lpipe = self.getNextToken();
19032025 if (lpipe.id != Token.Id.Pipe) {
19042026 self.putBackToken(lpipe);
......@@ -1907,9 +2029,9 @@ pub const Parser = struct {
19072029
19082030 const error_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
19092031 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
1910 const node = try arena.create(ast.NodeErrorPayload);
1911 *node = ast.NodeErrorPayload {
1912 .base = self.initNode(ast.Node.Id.ErrorPayload),
2032 const node = try arena.create(ast.NodePayload);
2033 *node = ast.NodePayload {
2034 .base = self.initNode(ast.Node.Id.Payload),
19132035 .lpipe = lpipe,
19142036 .error_symbol = try self.createIdentifier(arena, error_symbol),
19152037 .rpipe = rpipe
......@@ -1917,7 +2039,7 @@ pub const Parser = struct {
19172039 *dest = node;
19182040 },
19192041
1920 State.ValuePayload => |dest| {
2042 State.PointerPayload => |dest| {
19212043 const lpipe = self.getNextToken();
19222044 if (lpipe.id != Token.Id.Pipe) {
19232045 self.putBackToken(lpipe);
......@@ -1936,9 +2058,9 @@ pub const Parser = struct {
19362058
19372059 const value_symbol = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
19382060 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
1939 const node = try arena.create(ast.NodeValuePayload);
1940 *node = ast.NodeValuePayload {
1941 .base = self.initNode(ast.Node.Id.ValuePayload),
2061 const node = try arena.create(ast.NodePointerPayload);
2062 *node = ast.NodePointerPayload {
2063 .base = self.initNode(ast.Node.Id.PointerPayload),
19422064 .lpipe = lpipe,
19432065 .is_ptr = is_ptr,
19442066 .value_symbol = try self.createIdentifier(arena, value_symbol),
......@@ -1947,7 +2069,7 @@ pub const Parser = struct {
19472069 *dest = node;
19482070 },
19492071
1950 State.ValueIndexPayload => |dest| {
2072 State.PointerIndexPayload => |dest| {
19512073 const lpipe = self.getNextToken();
19522074 if (lpipe.id != Token.Id.Pipe) {
19532075 self.putBackToken(lpipe);
......@@ -1977,9 +2099,9 @@ pub const Parser = struct {
19772099 };
19782100
19792101 const rpipe = (try self.eatToken(&stack, Token.Id.Pipe)) ?? continue;
1980 const node = try arena.create(ast.NodeValueIndexPayload);
1981 *node = ast.NodeValueIndexPayload {
1982 .base = self.initNode(ast.Node.Id.ValueIndexPayload),
2102 const node = try arena.create(ast.NodePointerIndexPayload);
2103 *node = ast.NodePointerIndexPayload {
2104 .base = self.initNode(ast.Node.Id.PointerIndexPayload),
19832105 .lpipe = lpipe,
19842106 .is_ptr = is_ptr,
19852107 .value_symbol = try self.createIdentifier(arena, value_symbol),
......@@ -2249,7 +2371,7 @@ pub const Parser = struct {
22492371 stack.append(State { .Else = &node.@"else" }) catch unreachable;
22502372 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
22512373 try stack.append(State { .WhileContinueExpr = &node.continue_expr });
2252 try stack.append(State { .ValuePayload = &node.payload });
2374 try stack.append(State { .PointerPayload = &node.payload });
22532375 try stack.append(State { .ExpectToken = Token.Id.RParen });
22542376 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
22552377 try stack.append(State { .ExpectToken = Token.Id.LParen });
......@@ -2271,7 +2393,7 @@ pub const Parser = struct {
22712393
22722394 stack.append(State { .Else = &node.@"else" }) catch unreachable;
22732395 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 });
22752397 try stack.append(State { .ExpectToken = Token.Id.RParen });
22762398 try stack.append(State { .Expression = DestPtr { .Field = &node.array_expr } });
22772399 try stack.append(State { .ExpectToken = Token.Id.LParen });
......@@ -2374,9 +2496,9 @@ pub const Parser = struct {
23742496 ast.Node.Id.EnumTag,
23752497 ast.Node.Id.ParamDecl,
23762498 ast.Node.Id.Block,
2377 ast.Node.Id.ErrorPayload,
2378 ast.Node.Id.ValuePayload,
2379 ast.Node.Id.ValueIndexPayload,
2499 ast.Node.Id.Payload,
2500 ast.Node.Id.PointerPayload,
2501 ast.Node.Id.PointerIndexPayload,
23802502 ast.Node.Id.Switch,
23812503 ast.Node.Id.SwitchCase,
23822504 ast.Node.Id.SwitchElse,
......@@ -2422,6 +2544,15 @@ pub const Parser = struct {
24222544 const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", n);
24232545 n = comptime_node.expr;
24242546 },
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 },
24252556 else => return true,
24262557 }
24272558 }
......@@ -2540,6 +2671,7 @@ pub const Parser = struct {
25402671 },
25412672 Token.Id.QuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.MaybeType),
25422673 Token.Id.QuestionMarkQuestionMark => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.UnwrapMaybe),
2674 Token.Id.Keyword_await => (ast.NodePrefixOp.PrefixOp)(ast.NodePrefixOp.PrefixOp.Await),
25432675 else => null,
25442676 };
25452677 }
......@@ -2628,6 +2760,7 @@ pub const Parser = struct {
26282760 .extern_token = *extern_token,
26292761 .inline_token = *inline_token,
26302762 .cc_token = *cc_token,
2763 .async_attr = null,
26312764 .body_node = null,
26322765 .lib_name = lib_name,
26332766 .align_expr = null,
......@@ -3105,6 +3238,30 @@ pub const Parser = struct {
31053238 try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_node.comptime_token));
31063239 try stack.append(RenderState { .Expression = comptime_node.expr });
31073240 },
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 },
31083265 ast.Node.Id.InfixOp => {
31093266 const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base);
31103267 try stack.append(RenderState { .Expression = prefix_op_node.rhs });
......@@ -3211,6 +3368,9 @@ pub const Parser = struct {
32113368 ast.NodePrefixOp.PrefixOp.Try => try stream.write("try "),
32123369 ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"),
32133370 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 "),
32143374 }
32153375 },
32163376 ast.Node.Id.SuffixOp => {
......@@ -3229,11 +3389,18 @@ pub const Parser = struct {
32293389 }
32303390 }
32313391 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 }
32323398 },
32333399 ast.NodeSuffixOp.SuffixOp.ArrayAccess => |index_expr| {
32343400 try stack.append(RenderState { .Text = "]"});
32353401 try stack.append(RenderState { .Expression = index_expr});
32363402 try stack.append(RenderState { .Text = "["});
3403 try stack.append(RenderState { .Expression = suffix_op.lhs });
32373404 },
32383405 ast.NodeSuffixOp.SuffixOp.Slice => |range| {
32393406 try stack.append(RenderState { .Text = "]"});
......@@ -3243,6 +3410,7 @@ pub const Parser = struct {
32433410 try stack.append(RenderState { .Text = ".."});
32443411 try stack.append(RenderState { .Expression = range.start});
32453412 try stack.append(RenderState { .Text = "["});
3413 try stack.append(RenderState { .Expression = suffix_op.lhs });
32463414 },
32473415 ast.NodeSuffixOp.SuffixOp.StructInitializer => |field_inits| {
32483416 try stack.append(RenderState { .Text = " }"});
......@@ -3257,6 +3425,7 @@ pub const Parser = struct {
32573425 }
32583426 }
32593427 try stack.append(RenderState { .Text = "{"});
3428 try stack.append(RenderState { .Expression = suffix_op.lhs });
32603429 },
32613430 ast.NodeSuffixOp.SuffixOp.ArrayInitializer => |exprs| {
32623431 try stack.append(RenderState { .Text = " }"});
......@@ -3271,10 +3440,9 @@ pub const Parser = struct {
32713440 }
32723441 }
32733442 try stack.append(RenderState { .Text = "{"});
3443 try stack.append(RenderState { .Expression = suffix_op.lhs });
32743444 },
32753445 }
3276
3277 try stack.append(RenderState { .Expression = suffix_op.lhs });
32783446 },
32793447 ast.Node.Id.ControlFlowExpression => {
32803448 const flow_expr = @fieldParentPtr(ast.NodeControlFlowExpression, "base", base);
......@@ -3302,14 +3470,14 @@ pub const Parser = struct {
33023470 try stack.append(RenderState { .Expression = rhs });
33033471 }
33043472 },
3305 ast.Node.Id.ErrorPayload => {
3306 const payload = @fieldParentPtr(ast.NodeErrorPayload, "base", base);
3473 ast.Node.Id.Payload => {
3474 const payload = @fieldParentPtr(ast.NodePayload, "base", base);
33073475 try stack.append(RenderState { .Text = "|"});
33083476 try stack.append(RenderState { .Expression = &payload.error_symbol.base });
33093477 try stack.append(RenderState { .Text = "|"});
33103478 },
3311 ast.Node.Id.ValuePayload => {
3312 const payload = @fieldParentPtr(ast.NodeValuePayload, "base", base);
3479 ast.Node.Id.PointerPayload => {
3480 const payload = @fieldParentPtr(ast.NodePointerPayload, "base", base);
33133481 try stack.append(RenderState { .Text = "|"});
33143482 try stack.append(RenderState { .Expression = &payload.value_symbol.base });
33153483
......@@ -3319,8 +3487,8 @@ pub const Parser = struct {
33193487
33203488 try stack.append(RenderState { .Text = "|"});
33213489 },
3322 ast.Node.Id.ValueIndexPayload => {
3323 const payload = @fieldParentPtr(ast.NodeValueIndexPayload, "base", base);
3490 ast.Node.Id.PointerIndexPayload => {
3491 const payload = @fieldParentPtr(ast.NodePointerIndexPayload, "base", base);
33243492 try stack.append(RenderState { .Text = "|"});
33253493
33263494 if (payload.index_symbol) |index_symbol| {
......@@ -3553,6 +3721,11 @@ pub const Parser = struct {
35533721
35543722 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
35563729 if (fn_proto.cc_token) |cc_token| {
35573730 try stack.append(RenderState { .Text = " " });
35583731 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(cc_token) });
......@@ -4789,8 +4962,7 @@ test "zig fmt: coroutines" {
47894962 \\ x += 1;
47904963 \\ suspend;
47914964 \\ x += 1;
4792 \\ suspend |p| {
4793 \\ }
4965 \\ suspend |p| {}
47944966 \\ const p = async simpleAsyncFn() catch unreachable;
47954967 \\ await p;
47964968 \\}
......@@ -4803,10 +4975,3 @@ test "zig fmt: coroutines" {
48034975 \\
48044976 );
48054977}
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}