| author | |
| committer | |
| log | 2151f84d59f8af6e28570cb01a3a134c7b068fa2 |
| tree | 8ad09e707b33b7f53ed7964aa24bd4fd426ba6a7 |
| parent | 1e3b6816a8929bb141fb2157197077d74656e7ca |
8 files changed, 41 insertions(+), 145 deletions(-)
doc/langref.html.in+2-4| ... | @@ -9987,7 +9987,7 @@ TypeExpr <- PrefixTypeOp* ErrorUnionExpr | ... | @@ -9987,7 +9987,7 @@ TypeExpr <- PrefixTypeOp* ErrorUnionExpr |
| 9987 | ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)? | 9987 | ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)? |
| 9988 | 9988 | ||
| 9989 | SuffixExpr | 9989 | SuffixExpr |
| 9990 | <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArguments | 9990 | <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments |
| 9991 | / PrimaryTypeExpr (SuffixOp / FnCallArguments)* | 9991 | / PrimaryTypeExpr (SuffixOp / FnCallArguments)* |
| 9992 | 9992 | ||
| 9993 | PrimaryTypeExpr | 9993 | PrimaryTypeExpr |
| ... | @@ -10063,7 +10063,7 @@ FnCC | ... | @@ -10063,7 +10063,7 @@ FnCC |
| 10063 | <- KEYWORD_nakedcc | 10063 | <- KEYWORD_nakedcc |
| 10064 | / KEYWORD_stdcallcc | 10064 | / KEYWORD_stdcallcc |
| 10065 | / KEYWORD_extern | 10065 | / KEYWORD_extern |
| 10066 | / KEYWORD_async (LARROW TypeExpr RARROW)? | 10066 | / KEYWORD_async |
| 10067 | 10067 | ||
| 10068 | ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType | 10068 | ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType |
| 10069 | 10069 | ||
| ... | @@ -10168,8 +10168,6 @@ SuffixOp | ... | @@ -10168,8 +10168,6 @@ SuffixOp |
| 10168 | / DOTASTERISK | 10168 | / DOTASTERISK |
| 10169 | / DOTQUESTIONMARK | 10169 | / DOTQUESTIONMARK |
| 10170 | 10170 | ||
| 10171 | AsyncPrefix <- KEYWORD_async (LARROW PrefixExpr RARROW)? | ||
| 10172 | |||
| 10173 | FnCallArguments <- LPAREN ExprList RPAREN | 10171 | FnCallArguments <- LPAREN ExprList RPAREN |
| 10174 | 10172 | ||
| 10175 | # Ptr specific | 10173 | # Ptr specific |
src-self-hosted/ir.zig-1| ... | @@ -1181,7 +1181,6 @@ pub const Builder = struct { | ... | @@ -1181,7 +1181,6 @@ pub const Builder = struct { |
| 1181 | ast.Node.Id.ErrorTag => return error.Unimplemented, | 1181 | ast.Node.Id.ErrorTag => return error.Unimplemented, |
| 1182 | ast.Node.Id.AsmInput => return error.Unimplemented, | 1182 | ast.Node.Id.AsmInput => return error.Unimplemented, |
| 1183 | ast.Node.Id.AsmOutput => return error.Unimplemented, | 1183 | ast.Node.Id.AsmOutput => return error.Unimplemented, |
| 1184 | ast.Node.Id.AsyncAttribute => return error.Unimplemented, | ||
| 1185 | ast.Node.Id.ParamDecl => return error.Unimplemented, | 1184 | ast.Node.Id.ParamDecl => return error.Unimplemented, |
| 1186 | ast.Node.Id.FieldInitializer => return error.Unimplemented, | 1185 | ast.Node.Id.FieldInitializer => return error.Unimplemented, |
| 1187 | ast.Node.Id.EnumLiteral => return error.Unimplemented, | 1186 | ast.Node.Id.EnumLiteral => return error.Unimplemented, |
src-self-hosted/translate_c.zig+1-2| ... | @@ -1037,7 +1037,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp { | ... | @@ -1037,7 +1037,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp { |
| 1037 | .op = ast.Node.SuffixOp.Op{ | 1037 | .op = ast.Node.SuffixOp.Op{ |
| 1038 | .Call = ast.Node.SuffixOp.Op.Call{ | 1038 | .Call = ast.Node.SuffixOp.Op.Call{ |
| 1039 | .params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()), | 1039 | .params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()), |
| 1040 | .async_attr = null, | 1040 | .async_token = null, |
| 1041 | }, | 1041 | }, |
| 1042 | }, | 1042 | }, |
| 1043 | .rtoken = undefined, // set after appending args | 1043 | .rtoken = undefined, // set after appending args |
| ... | @@ -1355,7 +1355,6 @@ fn finishTransFnProto( | ... | @@ -1355,7 +1355,6 @@ fn finishTransFnProto( |
| 1355 | .var_args_token = null, // TODO this field is broken in the AST data model | 1355 | .var_args_token = null, // TODO this field is broken in the AST data model |
| 1356 | .extern_export_inline_token = extern_export_inline_tok, | 1356 | .extern_export_inline_token = extern_export_inline_tok, |
| 1357 | .cc_token = cc_tok, | 1357 | .cc_token = cc_tok, |
| 1358 | .async_attr = null, | ||
| 1359 | .body_node = null, | 1358 | .body_node = null, |
| 1360 | .lib_name = null, | 1359 | .lib_name = null, |
| 1361 | .align_expr = null, | 1360 | .align_expr = null, |
src/parser.cpp+15-29| ... | @@ -113,7 +113,6 @@ static AstNode *ast_parse_multiply_op(ParseContext *pc); | ... | @@ -113,7 +113,6 @@ static AstNode *ast_parse_multiply_op(ParseContext *pc); |
| 113 | static AstNode *ast_parse_prefix_op(ParseContext *pc); | 113 | static AstNode *ast_parse_prefix_op(ParseContext *pc); |
| 114 | static AstNode *ast_parse_prefix_type_op(ParseContext *pc); | 114 | static AstNode *ast_parse_prefix_type_op(ParseContext *pc); |
| 115 | static AstNode *ast_parse_suffix_op(ParseContext *pc); | 115 | static AstNode *ast_parse_suffix_op(ParseContext *pc); |
| 116 | static AstNode *ast_parse_async_prefix(ParseContext *pc); | ||
| 117 | static AstNode *ast_parse_fn_call_argumnets(ParseContext *pc); | 116 | static AstNode *ast_parse_fn_call_argumnets(ParseContext *pc); |
| 118 | static AstNode *ast_parse_array_type_start(ParseContext *pc); | 117 | static AstNode *ast_parse_array_type_start(ParseContext *pc); |
| 119 | static AstNode *ast_parse_ptr_type_start(ParseContext *pc); | 118 | static AstNode *ast_parse_ptr_type_start(ParseContext *pc); |
| ... | @@ -1389,22 +1388,18 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) { | ... | @@ -1389,22 +1388,18 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) { |
| 1389 | } | 1388 | } |
| 1390 | 1389 | ||
| 1391 | // SuffixExpr | 1390 | // SuffixExpr |
| 1392 | // <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArguments | 1391 | // <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments |
| 1393 | // / PrimaryTypeExpr (SuffixOp / FnCallArguments)* | 1392 | // / PrimaryTypeExpr (SuffixOp / FnCallArguments)* |
| 1394 | static AstNode *ast_parse_suffix_expr(ParseContext *pc) { | 1393 | static AstNode *ast_parse_suffix_expr(ParseContext *pc) { |
| 1395 | AstNode *async_call = ast_parse_async_prefix(pc); | 1394 | Token *async_token = eat_token_if(pc, TokenIdKeywordAsync); |
| 1396 | if (async_call != nullptr) { | 1395 | if (async_token != nullptr) { |
| 1397 | if (eat_token_if(pc, TokenIdKeywordFn) != nullptr) { | 1396 | if (eat_token_if(pc, TokenIdKeywordFn) != nullptr) { |
| 1398 | // HACK: If we see the keyword `fn`, then we assume that | 1397 | // HACK: If we see the keyword `fn`, then we assume that |
| 1399 | // we are parsing an async fn proto, and not a call. | 1398 | // we are parsing an async fn proto, and not a call. |
| 1400 | // We therefore put back all tokens consumed by the async | 1399 | // We therefore put back all tokens consumed by the async |
| 1401 | // prefix... | 1400 | // prefix... |
| 1402 | // HACK: This loop is not actually enough to put back all the | 1401 | put_back_token(pc); |
| 1403 | // tokens. Let's hope this is fine for most code right now | 1402 | put_back_token(pc); |
| 1404 | // and wait till we get the async rework for a syntax update. | ||
| 1405 | do { | ||
| 1406 | put_back_token(pc); | ||
| 1407 | } while (peek_token(pc)->id != TokenIdKeywordAsync); | ||
| 1408 | 1403 | ||
| 1409 | return ast_parse_primary_type_expr(pc); | 1404 | return ast_parse_primary_type_expr(pc); |
| 1410 | } | 1405 | } |
| ... | @@ -1446,10 +1441,14 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) { | ... | @@ -1446,10 +1441,14 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) { |
| 1446 | ast_invalid_token_error(pc, peek_token(pc)); | 1441 | ast_invalid_token_error(pc, peek_token(pc)); |
| 1447 | 1442 | ||
| 1448 | assert(args->type == NodeTypeFnCallExpr); | 1443 | assert(args->type == NodeTypeFnCallExpr); |
| 1449 | async_call->data.fn_call_expr.fn_ref_expr = child; | 1444 | |
| 1450 | async_call->data.fn_call_expr.params = args->data.fn_call_expr.params; | 1445 | AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async_token); |
| 1451 | async_call->data.fn_call_expr.is_builtin = false; | 1446 | res->data.fn_call_expr.is_async = true; |
| 1452 | return async_call; | 1447 | res->data.fn_call_expr.seen = false; |
| 1448 | res->data.fn_call_expr.fn_ref_expr = child; | ||
| 1449 | res->data.fn_call_expr.params = args->data.fn_call_expr.params; | ||
| 1450 | res->data.fn_call_expr.is_builtin = false; | ||
| 1451 | return res; | ||
| 1453 | } | 1452 | } |
| 1454 | 1453 | ||
| 1455 | AstNode *res = ast_parse_primary_type_expr(pc); | 1454 | AstNode *res = ast_parse_primary_type_expr(pc); |
| ... | @@ -1501,7 +1500,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) { | ... | @@ -1501,7 +1500,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) { |
| 1501 | // <- BUILTINIDENTIFIER FnCallArguments | 1500 | // <- BUILTINIDENTIFIER FnCallArguments |
| 1502 | // / CHAR_LITERAL | 1501 | // / CHAR_LITERAL |
| 1503 | // / ContainerDecl | 1502 | // / ContainerDecl |
| 1504 | // / DOT IDENTIFIER | 1503 | // / DOT IDENTIFIER |
| 1505 | // / ErrorSetDecl | 1504 | // / ErrorSetDecl |
| 1506 | // / FLOAT | 1505 | // / FLOAT |
| 1507 | // / FnProto | 1506 | // / FnProto |
| ... | @@ -2016,7 +2015,7 @@ static AstNode *ast_parse_link_section(ParseContext *pc) { | ... | @@ -2016,7 +2015,7 @@ static AstNode *ast_parse_link_section(ParseContext *pc) { |
| 2016 | // <- KEYWORD_nakedcc | 2015 | // <- KEYWORD_nakedcc |
| 2017 | // / KEYWORD_stdcallcc | 2016 | // / KEYWORD_stdcallcc |
| 2018 | // / KEYWORD_extern | 2017 | // / KEYWORD_extern |
| 2019 | // / KEYWORD_async (LARROW TypeExpr RARROW)? | 2018 | // / KEYWORD_async |
| 2020 | static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) { | 2019 | static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) { |
| 2021 | AstNodeFnProto res = {}; | 2020 | AstNodeFnProto res = {}; |
| 2022 | if (eat_token_if(pc, TokenIdKeywordNakedCC) != nullptr) { | 2021 | if (eat_token_if(pc, TokenIdKeywordNakedCC) != nullptr) { |
| ... | @@ -2657,19 +2656,6 @@ static AstNode *ast_parse_suffix_op(ParseContext *pc) { | ... | @@ -2657,19 +2656,6 @@ static AstNode *ast_parse_suffix_op(ParseContext *pc) { |
| 2657 | return nullptr; | 2656 | return nullptr; |
| 2658 | } | 2657 | } |
| 2659 | 2658 | ||
| 2660 | // AsyncPrefix <- KEYWORD_async (LARROW PrefixExpr RARROW)? | ||
| 2661 | static AstNode *ast_parse_async_prefix(ParseContext *pc) { | ||
| 2662 | Token *async = eat_token_if(pc, TokenIdKeywordAsync); | ||
| 2663 | if (async == nullptr) | ||
| 2664 | return nullptr; | ||
| 2665 | |||
| 2666 | AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async); | ||
| 2667 | res->data.fn_call_expr.is_async = true; | ||
| 2668 | res->data.fn_call_expr.seen = false; | ||
| 2669 | |||
| 2670 | return res; | ||
| 2671 | } | ||
| 2672 | |||
| 2673 | // FnCallArguments <- LPAREN ExprList RPAREN | 2659 | // FnCallArguments <- LPAREN ExprList RPAREN |
| 2674 | static AstNode *ast_parse_fn_call_argumnets(ParseContext *pc) { | 2660 | static AstNode *ast_parse_fn_call_argumnets(ParseContext *pc) { |
| 2675 | Token *paren = eat_token_if(pc, TokenIdLParen); | 2661 | Token *paren = eat_token_if(pc, TokenIdLParen); |
std/zig/ast.zig+2-35| ... | @@ -434,7 +434,6 @@ pub const Node = struct { | ... | @@ -434,7 +434,6 @@ pub const Node = struct { |
| 434 | ErrorTag, | 434 | ErrorTag, |
| 435 | AsmInput, | 435 | AsmInput, |
| 436 | AsmOutput, | 436 | AsmOutput, |
| 437 | AsyncAttribute, | ||
| 438 | ParamDecl, | 437 | ParamDecl, |
| 439 | FieldInitializer, | 438 | FieldInitializer, |
| 440 | }; | 439 | }; |
| ... | @@ -838,36 +837,6 @@ pub const Node = struct { | ... | @@ -838,36 +837,6 @@ pub const Node = struct { |
| 838 | } | 837 | } |
| 839 | }; | 838 | }; |
| 840 | 839 | ||
| 841 | pub const AsyncAttribute = struct { | ||
| 842 | base: Node, | ||
| 843 | async_token: TokenIndex, | ||
| 844 | allocator_type: ?*Node, | ||
| 845 | rangle_bracket: ?TokenIndex, | ||
| 846 | |||
| 847 | pub fn iterate(self: *AsyncAttribute, index: usize) ?*Node { | ||
| 848 | var i = index; | ||
| 849 | |||
| 850 | if (self.allocator_type) |allocator_type| { | ||
| 851 | if (i < 1) return allocator_type; | ||
| 852 | i -= 1; | ||
| 853 | } | ||
| 854 | |||
| 855 | return null; | ||
| 856 | } | ||
| 857 | |||
| 858 | pub fn firstToken(self: *const AsyncAttribute) TokenIndex { | ||
| 859 | return self.async_token; | ||
| 860 | } | ||
| 861 | |||
| 862 | pub fn lastToken(self: *const AsyncAttribute) TokenIndex { | ||
| 863 | if (self.rangle_bracket) |rangle_bracket| { | ||
| 864 | return rangle_bracket; | ||
| 865 | } | ||
| 866 | |||
| 867 | return self.async_token; | ||
| 868 | } | ||
| 869 | }; | ||
| 870 | |||
| 871 | pub const FnProto = struct { | 840 | pub const FnProto = struct { |
| 872 | base: Node, | 841 | base: Node, |
| 873 | doc_comments: ?*DocComment, | 842 | doc_comments: ?*DocComment, |
| ... | @@ -879,7 +848,6 @@ pub const Node = struct { | ... | @@ -879,7 +848,6 @@ pub const Node = struct { |
| 879 | var_args_token: ?TokenIndex, | 848 | var_args_token: ?TokenIndex, |
| 880 | extern_export_inline_token: ?TokenIndex, | 849 | extern_export_inline_token: ?TokenIndex, |
| 881 | cc_token: ?TokenIndex, | 850 | cc_token: ?TokenIndex, |
| 882 | async_attr: ?*AsyncAttribute, | ||
| 883 | body_node: ?*Node, | 851 | body_node: ?*Node, |
| 884 | lib_name: ?*Node, // populated if this is an extern declaration | 852 | lib_name: ?*Node, // populated if this is an extern declaration |
| 885 | align_expr: ?*Node, // populated if align(A) is present | 853 | align_expr: ?*Node, // populated if align(A) is present |
| ... | @@ -935,7 +903,6 @@ pub const Node = struct { | ... | @@ -935,7 +903,6 @@ pub const Node = struct { |
| 935 | 903 | ||
| 936 | pub fn firstToken(self: *const FnProto) TokenIndex { | 904 | pub fn firstToken(self: *const FnProto) TokenIndex { |
| 937 | if (self.visib_token) |visib_token| return visib_token; | 905 | if (self.visib_token) |visib_token| return visib_token; |
| 938 | if (self.async_attr) |async_attr| return async_attr.firstToken(); | ||
| 939 | if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token; | 906 | if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token; |
| 940 | assert(self.lib_name == null); | 907 | assert(self.lib_name == null); |
| 941 | if (self.cc_token) |cc_token| return cc_token; | 908 | if (self.cc_token) |cc_token| return cc_token; |
| ... | @@ -1699,7 +1666,7 @@ pub const Node = struct { | ... | @@ -1699,7 +1666,7 @@ pub const Node = struct { |
| 1699 | 1666 | ||
| 1700 | pub const Call = struct { | 1667 | pub const Call = struct { |
| 1701 | params: ParamList, | 1668 | params: ParamList, |
| 1702 | async_attr: ?*AsyncAttribute, | 1669 | async_token: ?TokenIndex, |
| 1703 | 1670 | ||
| 1704 | pub const ParamList = SegmentedList(*Node, 2); | 1671 | pub const ParamList = SegmentedList(*Node, 2); |
| 1705 | }; | 1672 | }; |
| ... | @@ -1752,7 +1719,7 @@ pub const Node = struct { | ... | @@ -1752,7 +1719,7 @@ pub const Node = struct { |
| 1752 | 1719 | ||
| 1753 | pub fn firstToken(self: *const SuffixOp) TokenIndex { | 1720 | pub fn firstToken(self: *const SuffixOp) TokenIndex { |
| 1754 | switch (self.op) { | 1721 | switch (self.op) { |
| 1755 | .Call => |*call_info| if (call_info.async_attr) |async_attr| return async_attr.firstToken(), | 1722 | .Call => |*call_info| if (call_info.async_token) |async_token| return async_token, |
| 1756 | else => {}, | 1723 | else => {}, |
| 1757 | } | 1724 | } |
| 1758 | return self.lhs.firstToken(); | 1725 | return self.lhs.firstToken(); |
std/zig/parse.zig+17-52| ... | @@ -277,7 +277,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node | ... | @@ -277,7 +277,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node |
| 277 | 277 | ||
| 278 | /// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr) | 278 | /// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr) |
| 279 | fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | 279 | fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 280 | const cc = try parseFnCC(arena, it, tree); | 280 | const cc = parseFnCC(arena, it, tree); |
| 281 | const fn_token = eatToken(it, .Keyword_fn) orelse { | 281 | const fn_token = eatToken(it, .Keyword_fn) orelse { |
| 282 | if (cc == null) return null else return error.ParseError; | 282 | if (cc == null) return null else return error.ParseError; |
| 283 | }; | 283 | }; |
| ... | @@ -320,7 +320,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -320,7 +320,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 320 | .var_args_token = var_args_token, | 320 | .var_args_token = var_args_token, |
| 321 | .extern_export_inline_token = null, | 321 | .extern_export_inline_token = null, |
| 322 | .cc_token = null, | 322 | .cc_token = null, |
| 323 | .async_attr = null, | ||
| 324 | .body_node = null, | 323 | .body_node = null, |
| 325 | .lib_name = null, | 324 | .lib_name = null, |
| 326 | .align_expr = align_expr, | 325 | .align_expr = align_expr, |
| ... | @@ -331,7 +330,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -331,7 +330,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 331 | switch (kind) { | 330 | switch (kind) { |
| 332 | .CC => |token| fn_proto_node.cc_token = token, | 331 | .CC => |token| fn_proto_node.cc_token = token, |
| 333 | .Extern => |token| fn_proto_node.extern_export_inline_token = token, | 332 | .Extern => |token| fn_proto_node.extern_export_inline_token = token, |
| 334 | .Async => |node| fn_proto_node.async_attr = node, | ||
| 335 | } | 333 | } |
| 336 | } | 334 | } |
| 337 | 335 | ||
| ... | @@ -1092,10 +1090,19 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No | ... | @@ -1092,10 +1090,19 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No |
| 1092 | } | 1090 | } |
| 1093 | 1091 | ||
| 1094 | /// SuffixExpr | 1092 | /// SuffixExpr |
| 1095 | /// <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArguments | 1093 | /// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments |
| 1096 | /// / PrimaryTypeExpr (SuffixOp / FnCallArguments)* | 1094 | /// / PrimaryTypeExpr (SuffixOp / FnCallArguments)* |
| 1097 | fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | 1095 | fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1098 | if (try parseAsyncPrefix(arena, it, tree)) |async_node| { | 1096 | if (eatToken(it, .Keyword_async)) |async_token| { |
| 1097 | if (eatToken(it, .Keyword_fn)) |token_fn| { | ||
| 1098 | // HACK: If we see the keyword `fn`, then we assume that | ||
| 1099 | // we are parsing an async fn proto, and not a call. | ||
| 1100 | // We therefore put back all tokens consumed by the async | ||
| 1101 | // prefix... | ||
| 1102 | putBackToken(it, token_fn); | ||
| 1103 | putBackToken(it, async_token); | ||
| 1104 | return parsePrimaryTypeExpr(arena, it, tree); | ||
| 1105 | } | ||
| 1099 | // TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr | 1106 | // TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr |
| 1100 | var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, AstError{ | 1107 | var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, AstError{ |
| 1101 | .ExpectedPrimaryTypeExpr = AstError.ExpectedPrimaryTypeExpr{ .token = it.index }, | 1108 | .ExpectedPrimaryTypeExpr = AstError.ExpectedPrimaryTypeExpr{ .token = it.index }, |
| ... | @@ -1116,7 +1123,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -1116,7 +1123,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1116 | }); | 1123 | }); |
| 1117 | return null; | 1124 | return null; |
| 1118 | }; | 1125 | }; |
| 1119 | |||
| 1120 | const node = try arena.create(Node.SuffixOp); | 1126 | const node = try arena.create(Node.SuffixOp); |
| 1121 | node.* = Node.SuffixOp{ | 1127 | node.* = Node.SuffixOp{ |
| 1122 | .base = Node{ .id = .SuffixOp }, | 1128 | .base = Node{ .id = .SuffixOp }, |
| ... | @@ -1124,14 +1130,13 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -1124,14 +1130,13 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1124 | .op = Node.SuffixOp.Op{ | 1130 | .op = Node.SuffixOp.Op{ |
| 1125 | .Call = Node.SuffixOp.Op.Call{ | 1131 | .Call = Node.SuffixOp.Op.Call{ |
| 1126 | .params = params.list, | 1132 | .params = params.list, |
| 1127 | .async_attr = async_node.cast(Node.AsyncAttribute).?, | 1133 | .async_token = async_token, |
| 1128 | }, | 1134 | }, |
| 1129 | }, | 1135 | }, |
| 1130 | .rtoken = params.rparen, | 1136 | .rtoken = params.rparen, |
| 1131 | }; | 1137 | }; |
| 1132 | return &node.base; | 1138 | return &node.base; |
| 1133 | } | 1139 | } |
| 1134 | |||
| 1135 | if (try parsePrimaryTypeExpr(arena, it, tree)) |expr| { | 1140 | if (try parsePrimaryTypeExpr(arena, it, tree)) |expr| { |
| 1136 | var res = expr; | 1141 | var res = expr; |
| 1137 | 1142 | ||
| ... | @@ -1153,7 +1158,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -1153,7 +1158,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1153 | .op = Node.SuffixOp.Op{ | 1158 | .op = Node.SuffixOp.Op{ |
| 1154 | .Call = Node.SuffixOp.Op.Call{ | 1159 | .Call = Node.SuffixOp.Op.Call{ |
| 1155 | .params = params.list, | 1160 | .params = params.list, |
| 1156 | .async_attr = null, | 1161 | .async_token = null, |
| 1157 | }, | 1162 | }, |
| 1158 | }, | 1163 | }, |
| 1159 | .rtoken = params.rparen, | 1164 | .rtoken = params.rparen, |
| ... | @@ -1653,36 +1658,18 @@ fn parseLinkSection(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node | ... | @@ -1653,36 +1658,18 @@ fn parseLinkSection(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node |
| 1653 | /// <- KEYWORD_nakedcc | 1658 | /// <- KEYWORD_nakedcc |
| 1654 | /// / KEYWORD_stdcallcc | 1659 | /// / KEYWORD_stdcallcc |
| 1655 | /// / KEYWORD_extern | 1660 | /// / KEYWORD_extern |
| 1656 | /// / KEYWORD_async (LARROW TypeExpr RARROW)? | 1661 | /// / KEYWORD_async |
| 1657 | fn parseFnCC(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?FnCC { | 1662 | fn parseFnCC(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?FnCC { |
| 1658 | if (eatToken(it, .Keyword_nakedcc)) |token| return FnCC{ .CC = token }; | 1663 | if (eatToken(it, .Keyword_nakedcc)) |token| return FnCC{ .CC = token }; |
| 1659 | if (eatToken(it, .Keyword_stdcallcc)) |token| return FnCC{ .CC = token }; | 1664 | if (eatToken(it, .Keyword_stdcallcc)) |token| return FnCC{ .CC = token }; |
| 1660 | if (eatToken(it, .Keyword_extern)) |token| return FnCC{ .Extern = token }; | 1665 | if (eatToken(it, .Keyword_extern)) |token| return FnCC{ .Extern = token }; |
| 1661 | if (eatToken(it, .Keyword_async)) |token| { | 1666 | if (eatToken(it, .Keyword_async)) |token| return FnCC{ .CC = token }; |
| 1662 | const node = try arena.create(Node.AsyncAttribute); | ||
| 1663 | node.* = Node.AsyncAttribute{ | ||
| 1664 | .base = Node{ .id = .AsyncAttribute }, | ||
| 1665 | .async_token = token, | ||
| 1666 | .allocator_type = null, | ||
| 1667 | .rangle_bracket = null, | ||
| 1668 | }; | ||
| 1669 | if (eatToken(it, .AngleBracketLeft)) |_| { | ||
| 1670 | const type_expr = try expectNode(arena, it, tree, parseTypeExpr, AstError{ | ||
| 1671 | .ExpectedTypeExpr = AstError.ExpectedTypeExpr{ .token = it.index }, | ||
| 1672 | }); | ||
| 1673 | const rarrow = try expectToken(it, tree, .AngleBracketRight); | ||
| 1674 | node.allocator_type = type_expr; | ||
| 1675 | node.rangle_bracket = rarrow; | ||
| 1676 | } | ||
| 1677 | return FnCC{ .Async = node }; | ||
| 1678 | } | ||
| 1679 | return null; | 1667 | return null; |
| 1680 | } | 1668 | } |
| 1681 | 1669 | ||
| 1682 | const FnCC = union(enum) { | 1670 | const FnCC = union(enum) { |
| 1683 | CC: TokenIndex, | 1671 | CC: TokenIndex, |
| 1684 | Extern: TokenIndex, | 1672 | Extern: TokenIndex, |
| 1685 | Async: *Node.AsyncAttribute, | ||
| 1686 | }; | 1673 | }; |
| 1687 | 1674 | ||
| 1688 | /// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType | 1675 | /// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType |
| ... | @@ -2409,28 +2396,6 @@ fn parseSuffixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -2409,28 +2396,6 @@ fn parseSuffixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 2409 | return &node.base; | 2396 | return &node.base; |
| 2410 | } | 2397 | } |
| 2411 | 2398 | ||
| 2412 | /// AsyncPrefix <- KEYWORD_async (LARROW PrefixExpr RARROW)? | ||
| 2413 | fn parseAsyncPrefix(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ||
| 2414 | const async_token = eatToken(it, .Keyword_async) orelse return null; | ||
| 2415 | var rangle_bracket: ?TokenIndex = null; | ||
| 2416 | const expr_node = if (eatToken(it, .AngleBracketLeft)) |_| blk: { | ||
| 2417 | const prefix_expr = try expectNode(arena, it, tree, parsePrefixExpr, AstError{ | ||
| 2418 | .ExpectedPrefixExpr = AstError.ExpectedPrefixExpr{ .token = it.index }, | ||
| 2419 | }); | ||
| 2420 | rangle_bracket = try expectToken(it, tree, .AngleBracketRight); | ||
| 2421 | break :blk prefix_expr; | ||
| 2422 | } else null; | ||
| 2423 | |||
| 2424 | const node = try arena.create(Node.AsyncAttribute); | ||
| 2425 | node.* = Node.AsyncAttribute{ | ||
| 2426 | .base = Node{ .id = .AsyncAttribute }, | ||
| 2427 | .async_token = async_token, | ||
| 2428 | .allocator_type = expr_node, | ||
| 2429 | .rangle_bracket = rangle_bracket, | ||
| 2430 | }; | ||
| 2431 | return &node.base; | ||
| 2432 | } | ||
| 2433 | |||
| 2434 | /// FnCallArguments <- LPAREN ExprList RPAREN | 2399 | /// FnCallArguments <- LPAREN ExprList RPAREN |
| 2435 | /// ExprList <- (Expr COMMA)* Expr? | 2400 | /// ExprList <- (Expr COMMA)* Expr? |
| 2436 | fn parseFnCallArguments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?AnnotatedParamList { | 2401 | fn parseFnCallArguments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?AnnotatedParamList { |
std/zig/parser_test.zig+2-2| ... | @@ -210,7 +210,7 @@ test "zig fmt: spaces around slice operator" { | ... | @@ -210,7 +210,7 @@ test "zig fmt: spaces around slice operator" { |
| 210 | test "zig fmt: async call in if condition" { | 210 | test "zig fmt: async call in if condition" { |
| 211 | try testCanonical( | 211 | try testCanonical( |
| 212 | \\comptime { | 212 | \\comptime { |
| 213 | \\ if (async<a> b()) { | 213 | \\ if (async b()) { |
| 214 | \\ a(); | 214 | \\ a(); |
| 215 | \\ } | 215 | \\ } |
| 216 | \\} | 216 | \\} |
| ... | @@ -1118,7 +1118,7 @@ test "zig fmt: first line comment in struct initializer" { | ... | @@ -1118,7 +1118,7 @@ test "zig fmt: first line comment in struct initializer" { |
| 1118 | \\pub async fn acquire(self: *Self) HeldLock { | 1118 | \\pub async fn acquire(self: *Self) HeldLock { |
| 1119 | \\ return HeldLock{ | 1119 | \\ return HeldLock{ |
| 1120 | \\ // guaranteed allocation elision | 1120 | \\ // guaranteed allocation elision |
| 1121 | \\ .held = await (async self.lock.acquire() catch unreachable), | 1121 | \\ .held = self.lock.acquire(), |
| 1122 | \\ .value = &self.private_data, | 1122 | \\ .value = &self.private_data, |
| 1123 | \\ }; | 1123 | \\ }; |
| 1124 | \\} | 1124 | \\} |
std/zig/render.zig+2-20| ... | @@ -284,20 +284,6 @@ fn renderExpression( | ... | @@ -284,20 +284,6 @@ fn renderExpression( |
| 284 | return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space); | 284 | return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space); |
| 285 | }, | 285 | }, |
| 286 | 286 | ||
| 287 | ast.Node.Id.AsyncAttribute => { | ||
| 288 | const async_attr = @fieldParentPtr(ast.Node.AsyncAttribute, "base", base); | ||
| 289 | |||
| 290 | if (async_attr.allocator_type) |allocator_type| { | ||
| 291 | try renderToken(tree, stream, async_attr.async_token, indent, start_col, Space.None); // async | ||
| 292 | |||
| 293 | try renderToken(tree, stream, tree.nextToken(async_attr.async_token), indent, start_col, Space.None); // < | ||
| 294 | try renderExpression(allocator, stream, tree, indent, start_col, allocator_type, Space.None); // allocator | ||
| 295 | return renderToken(tree, stream, tree.nextToken(allocator_type.lastToken()), indent, start_col, space); // > | ||
| 296 | } else { | ||
| 297 | return renderToken(tree, stream, async_attr.async_token, indent, start_col, space); // async | ||
| 298 | } | ||
| 299 | }, | ||
| 300 | |||
| 301 | ast.Node.Id.Suspend => { | 287 | ast.Node.Id.Suspend => { |
| 302 | const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base); | 288 | const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base); |
| 303 | 289 | ||
| ... | @@ -459,8 +445,8 @@ fn renderExpression( | ... | @@ -459,8 +445,8 @@ fn renderExpression( |
| 459 | 445 | ||
| 460 | switch (suffix_op.op) { | 446 | switch (suffix_op.op) { |
| 461 | @TagType(ast.Node.SuffixOp.Op).Call => |*call_info| { | 447 | @TagType(ast.Node.SuffixOp.Op).Call => |*call_info| { |
| 462 | if (call_info.async_attr) |async_attr| { | 448 | if (call_info.async_token) |async_token| { |
| 463 | try renderExpression(allocator, stream, tree, indent, start_col, &async_attr.base, Space.Space); | 449 | try renderToken(tree, stream, async_token, indent, start_col, Space.Space); |
| 464 | } | 450 | } |
| 465 | 451 | ||
| 466 | try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None); | 452 | try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None); |
| ... | @@ -1121,10 +1107,6 @@ fn renderExpression( | ... | @@ -1121,10 +1107,6 @@ fn renderExpression( |
| 1121 | try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc | 1107 | try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc |
| 1122 | } | 1108 | } |
| 1123 | 1109 | ||
| 1124 | if (fn_proto.async_attr) |async_attr| { | ||
| 1125 | try renderExpression(allocator, stream, tree, indent, start_col, &async_attr.base, Space.Space); | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | const lparen = if (fn_proto.name_token) |name_token| blk: { | 1110 | const lparen = if (fn_proto.name_token) |name_token| blk: { |
| 1129 | try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn | 1111 | try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn |
| 1130 | try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name | 1112 | try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name |