authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-09 11:02:16+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-09 12:23:30+02:00
log6f8d732599461aa816f545b658a068eceb6ac9bc
tree5fda80a4507cf0676c1eb9a2d4badfd17d5ee599
parente2fd289a33bb35cf4b86daa4d80adb7cc0c2c2b0
signaturelock-open Commit is signed but in an unrecognized format.

update parsers to new noasync syntax


6 files changed, 108 insertions(+), 43 deletions(-)

lib/std/zig/ast.zig+26-3
...@@ -431,6 +431,7 @@ pub const Node = struct {...@@ -431,6 +431,7 @@ pub const Node = struct {
431 ContainerDecl,431 ContainerDecl,
432 Asm,432 Asm,
433 Comptime,433 Comptime,
434 Noasync,
434 Block,435 Block,
435436
436 // Misc437 // Misc
...@@ -1078,6 +1079,30 @@ pub const Node = struct {...@@ -1078,6 +1079,30 @@ pub const Node = struct {
1078 }1079 }
1079 };1080 };
10801081
1082 pub const Noasync = struct {
1083 base: Node = Node{ .id = .Noasync },
1084 doc_comments: ?*DocComment,
1085 noasync_token: TokenIndex,
1086 expr: *Node,
1087
1088 pub fn iterate(self: *Noasync, index: usize) ?*Node {
1089 var i = index;
1090
1091 if (i < 1) return self.expr;
1092 i -= 1;
1093
1094 return null;
1095 }
1096
1097 pub fn firstToken(self: *const Noasync) TokenIndex {
1098 return self.noasync_token;
1099 }
1100
1101 pub fn lastToken(self: *const Noasync) TokenIndex {
1102 return self.expr.lastToken();
1103 }
1104 };
1105
1081 pub const Payload = struct {1106 pub const Payload = struct {
1082 base: Node = Node{ .id = .Payload },1107 base: Node = Node{ .id = .Payload },
1083 lpipe: TokenIndex,1108 lpipe: TokenIndex,
...@@ -1560,9 +1585,7 @@ pub const Node = struct {...@@ -1560,9 +1585,7 @@ pub const Node = struct {
1560 pub const Op = union(enum) {1585 pub const Op = union(enum) {
1561 AddressOf,1586 AddressOf,
1562 ArrayType: ArrayInfo,1587 ArrayType: ArrayInfo,
1563 Await: struct {1588 Await,
1564 noasync_token: ?TokenIndex = null,
1565 },
1566 BitNot,1589 BitNot,
1567 BoolNot,1590 BoolNot,
1568 Cancel,1591 Cancel,
lib/std/zig/parse.zig+37-25
...@@ -856,6 +856,7 @@ fn parsePrefixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -856,6 +856,7 @@ fn parsePrefixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
856/// / IfExpr856/// / IfExpr
857/// / KEYWORD_break BreakLabel? Expr?857/// / KEYWORD_break BreakLabel? Expr?
858/// / KEYWORD_comptime Expr858/// / KEYWORD_comptime Expr
859/// / KEYWORD_noasync Expr
859/// / KEYWORD_continue BreakLabel?860/// / KEYWORD_continue BreakLabel?
860/// / KEYWORD_resume Expr861/// / KEYWORD_resume Expr
861/// / KEYWORD_return Expr?862/// / KEYWORD_return Expr?
...@@ -870,7 +871,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -870,7 +871,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
870 const label = try parseBreakLabel(arena, it, tree);871 const label = try parseBreakLabel(arena, it, tree);
871 const expr_node = try parseExpr(arena, it, tree);872 const expr_node = try parseExpr(arena, it, tree);
872 const node = try arena.create(Node.ControlFlowExpression);873 const node = try arena.create(Node.ControlFlowExpression);
873 node.* = Node.ControlFlowExpression{874 node.* = .{
874 .ltoken = token,875 .ltoken = token,
875 .kind = Node.ControlFlowExpression.Kind{ .Break = label },876 .kind = Node.ControlFlowExpression.Kind{ .Break = label },
876 .rhs = expr_node,877 .rhs = expr_node,
...@@ -883,7 +884,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -883,7 +884,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
883 .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index },884 .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index },
884 });885 });
885 const node = try arena.create(Node.Comptime);886 const node = try arena.create(Node.Comptime);
886 node.* = Node.Comptime{887 node.* = .{
887 .doc_comments = null,888 .doc_comments = null,
888 .comptime_token = token,889 .comptime_token = token,
889 .expr = expr_node,890 .expr = expr_node,
...@@ -891,10 +892,23 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -891,10 +892,23 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
891 return &node.base;892 return &node.base;
892 }893 }
893894
895 if (eatToken(it, .Keyword_noasync)) |token| {
896 const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{
897 .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index },
898 });
899 const node = try arena.create(Node.Noasync);
900 node.* = .{
901 .doc_comments = null,
902 .noasync_token = token,
903 .expr = expr_node,
904 };
905 return &node.base;
906 }
907
894 if (eatToken(it, .Keyword_continue)) |token| {908 if (eatToken(it, .Keyword_continue)) |token| {
895 const label = try parseBreakLabel(arena, it, tree);909 const label = try parseBreakLabel(arena, it, tree);
896 const node = try arena.create(Node.ControlFlowExpression);910 const node = try arena.create(Node.ControlFlowExpression);
897 node.* = Node.ControlFlowExpression{911 node.* = .{
898 .ltoken = token,912 .ltoken = token,
899 .kind = Node.ControlFlowExpression.Kind{ .Continue = label },913 .kind = Node.ControlFlowExpression.Kind{ .Continue = label },
900 .rhs = null,914 .rhs = null,
...@@ -907,7 +921,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -907,7 +921,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
907 .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index },921 .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index },
908 });922 });
909 const node = try arena.create(Node.PrefixOp);923 const node = try arena.create(Node.PrefixOp);
910 node.* = Node.PrefixOp{924 node.* = .{
911 .op_token = token,925 .op_token = token,
912 .op = Node.PrefixOp.Op.Resume,926 .op = Node.PrefixOp.Op.Resume,
913 .rhs = expr_node,927 .rhs = expr_node,
...@@ -918,7 +932,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -918,7 +932,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
918 if (eatToken(it, .Keyword_return)) |token| {932 if (eatToken(it, .Keyword_return)) |token| {
919 const expr_node = try parseExpr(arena, it, tree);933 const expr_node = try parseExpr(arena, it, tree);
920 const node = try arena.create(Node.ControlFlowExpression);934 const node = try arena.create(Node.ControlFlowExpression);
921 node.* = Node.ControlFlowExpression{935 node.* = .{
922 .ltoken = token,936 .ltoken = token,
923 .kind = Node.ControlFlowExpression.Kind.Return,937 .kind = Node.ControlFlowExpression.Kind.Return,
924 .rhs = expr_node,938 .rhs = expr_node,
...@@ -1126,19 +1140,18 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No...@@ -1126,19 +1140,18 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
11261140
1127/// SuffixExpr1141/// SuffixExpr
1128/// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments1142/// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
1129/// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments
1130/// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*1143/// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
1131fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {1144fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1132 const maybe_async = eatAnnotatedToken(it, .Keyword_async) orelse eatAnnotatedToken(it, .Keyword_noasync);1145 const maybe_async = eatToken(it, .Keyword_async);
1133 if (maybe_async) |async_token| {1146 if (maybe_async) |async_token| {
1134 const token_fn = eatToken(it, .Keyword_fn);1147 const token_fn = eatToken(it, .Keyword_fn);
1135 if (async_token.ptr.id == .Keyword_async and token_fn != null) {1148 if (token_fn != null) {
1136 // HACK: If we see the keyword `fn`, then we assume that1149 // HACK: If we see the keyword `fn`, then we assume that
1137 // we are parsing an async fn proto, and not a call.1150 // we are parsing an async fn proto, and not a call.
1138 // We therefore put back all tokens consumed by the async1151 // We therefore put back all tokens consumed by the async
1139 // prefix...1152 // prefix...
1140 putBackToken(it, token_fn.?);1153 putBackToken(it, token_fn.?);
1141 putBackToken(it, async_token.index);1154 putBackToken(it, async_token);
1142 return parsePrimaryTypeExpr(arena, it, tree);1155 return parsePrimaryTypeExpr(arena, it, tree);
1143 }1156 }
1144 // TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr1157 // TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr
...@@ -1167,7 +1180,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1167,7 +1180,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1167 .op = Node.SuffixOp.Op{1180 .op = Node.SuffixOp.Op{
1168 .Call = Node.SuffixOp.Op.Call{1181 .Call = Node.SuffixOp.Op.Call{
1169 .params = params.list,1182 .params = params.list,
1170 .async_token = async_token.index,1183 .async_token = async_token,
1171 },1184 },
1172 },1185 },
1173 .rtoken = params.rparen,1186 .rtoken = params.rparen,
...@@ -1224,6 +1237,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1224,6 +1237,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1224/// / IfTypeExpr1237/// / IfTypeExpr
1225/// / INTEGER1238/// / INTEGER
1226/// / KEYWORD_comptime TypeExpr1239/// / KEYWORD_comptime TypeExpr
1240/// / KEYWORD_noasync TypeExpr
1227/// / KEYWORD_error DOT IDENTIFIER1241/// / KEYWORD_error DOT IDENTIFIER
1228/// / KEYWORD_false1242/// / KEYWORD_false
1229/// / KEYWORD_null1243/// / KEYWORD_null
...@@ -1255,13 +1269,23 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N...@@ -1255,13 +1269,23 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
1255 if (eatToken(it, .Keyword_comptime)) |token| {1269 if (eatToken(it, .Keyword_comptime)) |token| {
1256 const expr = (try parseTypeExpr(arena, it, tree)) orelse return null;1270 const expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
1257 const node = try arena.create(Node.Comptime);1271 const node = try arena.create(Node.Comptime);
1258 node.* = Node.Comptime{1272 node.* = .{
1259 .doc_comments = null,1273 .doc_comments = null,
1260 .comptime_token = token,1274 .comptime_token = token,
1261 .expr = expr,1275 .expr = expr,
1262 };1276 };
1263 return &node.base;1277 return &node.base;
1264 }1278 }
1279 if (eatToken(it, .Keyword_noasync)) |token| {
1280 const expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
1281 const node = try arena.create(Node.Noasync);
1282 node.* = .{
1283 .doc_comments = null,
1284 .noasync_token = token,
1285 .expr = expr,
1286 };
1287 return &node.base;
1288 }
1265 if (eatToken(it, .Keyword_error)) |token| {1289 if (eatToken(it, .Keyword_error)) |token| {
1266 const period = try expectToken(it, tree, .Period);1290 const period = try expectToken(it, tree, .Period);
1267 const identifier = try expectNode(arena, it, tree, parseIdentifier, AstError{1291 const identifier = try expectNode(arena, it, tree, parseIdentifier, AstError{
...@@ -1269,7 +1293,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N...@@ -1269,7 +1293,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
1269 });1293 });
1270 const global_error_set = try createLiteral(arena, Node.ErrorType, token);1294 const global_error_set = try createLiteral(arena, Node.ErrorType, token);
1271 const node = try arena.create(Node.InfixOp);1295 const node = try arena.create(Node.InfixOp);
1272 node.* = Node.InfixOp{1296 node.* = .{
1273 .op_token = period,1297 .op_token = period,
1274 .lhs = global_error_set,1298 .lhs = global_error_set,
1275 .op = Node.InfixOp.Op.Period,1299 .op = Node.InfixOp.Op.Period,
...@@ -1281,7 +1305,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N...@@ -1281,7 +1305,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
1281 if (eatToken(it, .Keyword_null)) |token| return createLiteral(arena, Node.NullLiteral, token);1305 if (eatToken(it, .Keyword_null)) |token| return createLiteral(arena, Node.NullLiteral, token);
1282 if (eatToken(it, .Keyword_anyframe)) |token| {1306 if (eatToken(it, .Keyword_anyframe)) |token| {
1283 const node = try arena.create(Node.AnyFrameType);1307 const node = try arena.create(Node.AnyFrameType);
1284 node.* = Node.AnyFrameType{1308 node.* = .{
1285 .anyframe_token = token,1309 .anyframe_token = token,
1286 .result = null,1310 .result = null,
1287 };1311 };
...@@ -2180,18 +2204,6 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -2180,18 +2204,6 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
2180 .Ampersand => ops{ .AddressOf = {} },2204 .Ampersand => ops{ .AddressOf = {} },
2181 .Keyword_try => ops{ .Try = {} },2205 .Keyword_try => ops{ .Try = {} },
2182 .Keyword_await => ops{ .Await = .{} },2206 .Keyword_await => ops{ .Await = .{} },
2183 .Keyword_noasync => if (eatToken(it, .Keyword_await)) |await_tok| {
2184 const node = try arena.create(Node.PrefixOp);
2185 node.* = Node.PrefixOp{
2186 .op_token = await_tok,
2187 .op = .{ .Await = .{ .noasync_token = token.index } },
2188 .rhs = undefined, // set by caller
2189 };
2190 return &node.base;
2191 } else {
2192 putBackToken(it, token.index);
2193 return null;
2194 },
2195 else => {2207 else => {
2196 putBackToken(it, token.index);2208 putBackToken(it, token.index);
2197 return null;2209 return null;
lib/std/zig/render.zig+6-3
...@@ -390,6 +390,12 @@ fn renderExpression(...@@ -390,6 +390,12 @@ fn renderExpression(
390 try renderToken(tree, stream, comptime_node.comptime_token, indent, start_col, Space.Space);390 try renderToken(tree, stream, comptime_node.comptime_token, indent, start_col, Space.Space);
391 return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);391 return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);
392 },392 },
393 .Noasync => {
394 const noasync_node = @fieldParentPtr(ast.Node.Noasync, "base", base);
395
396 try renderToken(tree, stream, noasync_node.noasync_token, indent, start_col, Space.Space);
397 return renderExpression(allocator, stream, tree, indent, start_col, noasync_node.expr, space);
398 },
393399
394 .Suspend => {400 .Suspend => {
395 const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base);401 const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base);
...@@ -590,9 +596,6 @@ fn renderExpression(...@@ -590,9 +596,6 @@ fn renderExpression(
590 },596 },
591597
592 .Await => |await_info| {598 .Await => |await_info| {
593 if (await_info.noasync_token) |tok| {
594 try renderToken(tree, stream, tok, indent, start_col, Space.Space);
595 }
596 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space);599 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space);
597 },600 },
598 }601 }
src/all_types.hpp+6-1
...@@ -651,6 +651,7 @@ enum NodeType {...@@ -651,6 +651,7 @@ enum NodeType {
651 NodeTypeSwitchProng,651 NodeTypeSwitchProng,
652 NodeTypeSwitchRange,652 NodeTypeSwitchRange,
653 NodeTypeCompTime,653 NodeTypeCompTime,
654 NodeTypeNoAsync,
654 NodeTypeBreak,655 NodeTypeBreak,
655 NodeTypeContinue,656 NodeTypeContinue,
656 NodeTypeAsmExpr,657 NodeTypeAsmExpr,
...@@ -991,6 +992,10 @@ struct AstNodeCompTime {...@@ -991,6 +992,10 @@ struct AstNodeCompTime {
991 AstNode *expr;992 AstNode *expr;
992};993};
993994
995struct AstNodeNoAsync {
996 AstNode *expr;
997};
998
994struct AsmOutput {999struct AsmOutput {
995 Buf *asm_symbolic_name;1000 Buf *asm_symbolic_name;
996 Buf *constraint;1001 Buf *constraint;
...@@ -1148,7 +1153,6 @@ struct AstNodeErrorType {...@@ -1148,7 +1153,6 @@ struct AstNodeErrorType {
1148};1153};
11491154
1150struct AstNodeAwaitExpr {1155struct AstNodeAwaitExpr {
1151 Token *noasync_token;
1152 AstNode *expr;1156 AstNode *expr;
1153};1157};
11541158
...@@ -1199,6 +1203,7 @@ struct AstNode {...@@ -1199,6 +1203,7 @@ struct AstNode {
1199 AstNodeSwitchProng switch_prong;1203 AstNodeSwitchProng switch_prong;
1200 AstNodeSwitchRange switch_range;1204 AstNodeSwitchRange switch_range;
1201 AstNodeCompTime comptime_expr;1205 AstNodeCompTime comptime_expr;
1206 AstNodeNoAsync noasync_expr;
1202 AstNodeAsmExpr asm_expr;1207 AstNodeAsmExpr asm_expr;
1203 AstNodeFieldAccessExpr field_access_expr;1208 AstNodeFieldAccessExpr field_access_expr;
1204 AstNodePtrDerefExpr ptr_deref_expr;1209 AstNodePtrDerefExpr ptr_deref_expr;
src/ast_render.cpp+8
...@@ -220,6 +220,8 @@ static const char *node_type_str(NodeType node_type) {...@@ -220,6 +220,8 @@ static const char *node_type_str(NodeType node_type) {
220 return "SwitchRange";220 return "SwitchRange";
221 case NodeTypeCompTime:221 case NodeTypeCompTime:
222 return "CompTime";222 return "CompTime";
223 case NodeTypeNoAsync:
224 return "NoAsync";
223 case NodeTypeBreak:225 case NodeTypeBreak:
224 return "Break";226 return "Break";
225 case NodeTypeContinue:227 case NodeTypeContinue:
...@@ -1091,6 +1093,12 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -1091,6 +1093,12 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
1091 render_node_grouped(ar, node->data.comptime_expr.expr);1093 render_node_grouped(ar, node->data.comptime_expr.expr);
1092 break;1094 break;
1093 }1095 }
1096 case NodeTypeNoAsync:
1097 {
1098 fprintf(ar->f, "noasync ");
1099 render_node_grouped(ar, node->data.noasync_expr.expr);
1100 break;
1101 }
1094 case NodeTypeForExpr:1102 case NodeTypeForExpr:
1095 {1103 {
1096 if (node->data.for_expr.name != nullptr) {1104 if (node->data.for_expr.name != nullptr) {
src/parser.cpp+25-11
...@@ -1237,6 +1237,7 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {...@@ -1237,6 +1237,7 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {
1237// / IfExpr1237// / IfExpr
1238// / KEYWORD_break BreakLabel? Expr?1238// / KEYWORD_break BreakLabel? Expr?
1239// / KEYWORD_comptime Expr1239// / KEYWORD_comptime Expr
1240// / KEYWORD_noasync Expr
1240// / KEYWORD_continue BreakLabel?1241// / KEYWORD_continue BreakLabel?
1241// / KEYWORD_resume Expr1242// / KEYWORD_resume Expr
1242// / KEYWORD_return Expr?1243// / KEYWORD_return Expr?
...@@ -1271,6 +1272,14 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {...@@ -1271,6 +1272,14 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
1271 return res;1272 return res;
1272 }1273 }
12731274
1275 Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
1276 if (noasync != nullptr) {
1277 AstNode *expr = ast_expect(pc, ast_parse_expr);
1278 AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
1279 res->data.noasync_expr.expr = expr;
1280 return res;
1281 }
1282
1274 Token *continue_token = eat_token_if(pc, TokenIdKeywordContinue);1283 Token *continue_token = eat_token_if(pc, TokenIdKeywordContinue);
1275 if (continue_token != nullptr) {1284 if (continue_token != nullptr) {
1276 Token *label = ast_parse_break_label(pc);1285 Token *label = ast_parse_break_label(pc);
...@@ -1459,13 +1468,11 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {...@@ -1459,13 +1468,11 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
14591468
1460// SuffixExpr1469// SuffixExpr
1461// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments1470// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
1462// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments
1463// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*1471// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
1464static AstNode *ast_parse_suffix_expr(ParseContext *pc) {1472static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
1465 Token *async_token = eat_token(pc);1473 Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);
1466 bool is_async = async_token->id == TokenIdKeywordAsync;1474 if (async_token) {
1467 if (is_async || async_token->id == TokenIdKeywordNoAsync) {1475 if (eat_token_if(pc, TokenIdKeywordFn) != nullptr) {
1468 if (is_async && eat_token_if(pc, TokenIdKeywordFn) != nullptr) {
1469 // HACK: If we see the keyword `fn`, then we assume that1476 // HACK: If we see the keyword `fn`, then we assume that
1470 // we are parsing an async fn proto, and not a call.1477 // we are parsing an async fn proto, and not a call.
1471 // We therefore put back all tokens consumed by the async1478 // We therefore put back all tokens consumed by the async
...@@ -1515,13 +1522,12 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {...@@ -1515,13 +1522,12 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
1515 assert(args->type == NodeTypeFnCallExpr);1522 assert(args->type == NodeTypeFnCallExpr);
15161523
1517 AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async_token);1524 AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async_token);
1518 res->data.fn_call_expr.modifier = is_async ? CallModifierAsync : CallModifierNoAsync;1525 res->data.fn_call_expr.modifier = CallModifierAsync;
1519 res->data.fn_call_expr.seen = false;1526 res->data.fn_call_expr.seen = false;
1520 res->data.fn_call_expr.fn_ref_expr = child;1527 res->data.fn_call_expr.fn_ref_expr = child;
1521 res->data.fn_call_expr.params = args->data.fn_call_expr.params;1528 res->data.fn_call_expr.params = args->data.fn_call_expr.params;
1522 return res;1529 return res;
1523 }1530 }
1524 put_back_token(pc);
15251531
1526 AstNode *res = ast_parse_primary_type_expr(pc);1532 AstNode *res = ast_parse_primary_type_expr(pc);
1527 if (res == nullptr)1533 if (res == nullptr)
...@@ -1582,6 +1588,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {...@@ -1582,6 +1588,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
1582// / IfTypeExpr1588// / IfTypeExpr
1583// / INTEGER1589// / INTEGER
1584// / KEYWORD_comptime TypeExpr1590// / KEYWORD_comptime TypeExpr
1591// / KEYWORD_noasync TypeExpr
1585// / KEYWORD_error DOT IDENTIFIER1592// / KEYWORD_error DOT IDENTIFIER
1586// / KEYWORD_false1593// / KEYWORD_false
1587// / KEYWORD_null1594// / KEYWORD_null
...@@ -1683,6 +1690,14 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {...@@ -1683,6 +1690,14 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
1683 return res;1690 return res;
1684 }1691 }
16851692
1693 Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
1694 if (noasync != nullptr) {
1695 AstNode *expr = ast_expect(pc, ast_parse_type_expr);
1696 AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
1697 res->data.noasync_expr.expr = expr;
1698 return res;
1699 }
1700
1686 Token *error = eat_token_if(pc, TokenIdKeywordError);1701 Token *error = eat_token_if(pc, TokenIdKeywordError);
1687 if (error != nullptr) {1702 if (error != nullptr) {
1688 Token *dot = expect_token(pc, TokenIdDot);1703 Token *dot = expect_token(pc, TokenIdDot);
...@@ -2599,14 +2614,10 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {...@@ -2599,14 +2614,10 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
2599 return res;2614 return res;
2600 }2615 }
26012616
2602 Token *noasync_token = eat_token_if(pc, TokenIdKeywordNoAsync);
2603 Token *await = eat_token_if(pc, TokenIdKeywordAwait);2617 Token *await = eat_token_if(pc, TokenIdKeywordAwait);
2604 if (await != nullptr) {2618 if (await != nullptr) {
2605 AstNode *res = ast_create_node(pc, NodeTypeAwaitExpr, await);2619 AstNode *res = ast_create_node(pc, NodeTypeAwaitExpr, await);
2606 res->data.await_expr.noasync_token = noasync_token;
2607 return res;2620 return res;
2608 } else if (noasync_token != nullptr) {
2609 put_back_token(pc);
2610 }2621 }
26112622
2612 return nullptr;2623 return nullptr;
...@@ -3125,6 +3136,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -3125,6 +3136,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
3125 case NodeTypeCompTime:3136 case NodeTypeCompTime:
3126 visit_field(&node->data.comptime_expr.expr, visit, context);3137 visit_field(&node->data.comptime_expr.expr, visit, context);
3127 break;3138 break;
3139 case NodeTypeNoAsync:
3140 visit_field(&node->data.comptime_expr.expr, visit, context);
3141 break;
3128 case NodeTypeBreak:3142 case NodeTypeBreak:
3129 // none3143 // none
3130 break;3144 break;