| author | |
| committer | |
| log | 6f8d732599461aa816f545b658a068eceb6ac9bc |
| tree | 5fda80a4507cf0676c1eb9a2d4badfd17d5ee599 |
| parent | e2fd289a33bb35cf4b86daa4d80adb7cc0c2c2b0 |
| signature | Commit is signed but in an unrecognized format. |
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, |
| 435 | 436 | ||
| 436 | // Misc | 437 | // Misc |
| ... | @@ -1078,6 +1079,30 @@ pub const Node = struct { | ... | @@ -1078,6 +1079,30 @@ pub const Node = struct { |
| 1078 | } | 1079 | } |
| 1079 | }; | 1080 | }; |
| 1080 | 1081 | ||
| 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 | /// / IfExpr | 856 | /// / IfExpr |
| 857 | /// / KEYWORD_break BreakLabel? Expr? | 857 | /// / KEYWORD_break BreakLabel? Expr? |
| 858 | /// / KEYWORD_comptime Expr | 858 | /// / KEYWORD_comptime Expr |
| 859 | /// / KEYWORD_noasync Expr | ||
| 859 | /// / KEYWORD_continue BreakLabel? | 860 | /// / KEYWORD_continue BreakLabel? |
| 860 | /// / KEYWORD_resume Expr | 861 | /// / 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 | } |
| 893 | 894 | ||
| 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 |
| 1126 | 1140 | ||
| 1127 | /// SuffixExpr | 1141 | /// SuffixExpr |
| 1128 | /// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments | 1142 | /// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments |
| 1129 | /// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments | ||
| 1130 | /// / PrimaryTypeExpr (SuffixOp / FnCallArguments)* | 1143 | /// / PrimaryTypeExpr (SuffixOp / FnCallArguments)* |
| 1131 | fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | 1144 | fn 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 that | 1149 | // 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 async | 1151 | // 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_expr | 1157 | // 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 | /// / IfTypeExpr | 1237 | /// / IfTypeExpr |
| 1225 | /// / INTEGER | 1238 | /// / INTEGER |
| 1226 | /// / KEYWORD_comptime TypeExpr | 1239 | /// / KEYWORD_comptime TypeExpr |
| 1240 | /// / KEYWORD_noasync TypeExpr | ||
| 1227 | /// / KEYWORD_error DOT IDENTIFIER | 1241 | /// / KEYWORD_error DOT IDENTIFIER |
| 1228 | /// / KEYWORD_false | 1242 | /// / KEYWORD_false |
| 1229 | /// / KEYWORD_null | 1243 | /// / 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 | }, | ||
| 393 | 399 | ||
| 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 | }, |
| 591 | 597 | ||
| 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 | }; |
| 993 | 994 | ||
| 995 | struct AstNodeNoAsync { | ||
| 996 | AstNode *expr; | ||
| 997 | }; | ||
| 998 | |||
| 994 | struct AsmOutput { | 999 | struct 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 | }; |
| 1149 | 1154 | ||
| 1150 | struct AstNodeAwaitExpr { | 1155 | struct AstNodeAwaitExpr { |
| 1151 | Token *noasync_token; | ||
| 1152 | AstNode *expr; | 1156 | AstNode *expr; |
| 1153 | }; | 1157 | }; |
| 1154 | 1158 | ||
| ... | @@ -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 | // / IfExpr | 1237 | // / IfExpr |
| 1238 | // / KEYWORD_break BreakLabel? Expr? | 1238 | // / KEYWORD_break BreakLabel? Expr? |
| 1239 | // / KEYWORD_comptime Expr | 1239 | // / KEYWORD_comptime Expr |
| 1240 | // / KEYWORD_noasync Expr | ||
| 1240 | // / KEYWORD_continue BreakLabel? | 1241 | // / KEYWORD_continue BreakLabel? |
| 1241 | // / KEYWORD_resume Expr | 1242 | // / 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 | } |
| 1273 | 1274 | ||
| 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) { |
| 1459 | 1468 | ||
| 1460 | // SuffixExpr | 1469 | // SuffixExpr |
| 1461 | // <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments | 1470 | // <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments |
| 1462 | // / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments | ||
| 1463 | // / PrimaryTypeExpr (SuffixOp / FnCallArguments)* | 1471 | // / PrimaryTypeExpr (SuffixOp / FnCallArguments)* |
| 1464 | static AstNode *ast_parse_suffix_expr(ParseContext *pc) { | 1472 | static 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 that | 1476 | // 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 async | 1478 | // 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); |
| 1516 | 1523 | ||
| 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); | ||
| 1525 | 1531 | ||
| 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 | // / IfTypeExpr | 1588 | // / IfTypeExpr |
| 1583 | // / INTEGER | 1589 | // / INTEGER |
| 1584 | // / KEYWORD_comptime TypeExpr | 1590 | // / KEYWORD_comptime TypeExpr |
| 1591 | // / KEYWORD_noasync TypeExpr | ||
| 1585 | // / KEYWORD_error DOT IDENTIFIER | 1592 | // / KEYWORD_error DOT IDENTIFIER |
| 1586 | // / KEYWORD_false | 1593 | // / KEYWORD_false |
| 1587 | // / KEYWORD_null | 1594 | // / 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 | } |
| 1685 | 1692 | ||
| 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 | } |
| 2601 | 2616 | ||
| 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 | } |
| 2611 | 2622 | ||
| 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 | // none | 3143 | // none |
| 3130 | break; | 3144 | break; |