authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-26 00:04:11-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-26 00:04:11-05:00
logc60496a297a0d4c53ad0e22850ad62b0b4a2d841
tree821fd1f0399d8d013acba645a9f54df6914adad7
parent6fef7406c80d6db26513a6ae53f9c44444bef1f2

parse await and suspend syntax

See #727

6 files changed, 139 insertions(+), 6 deletions(-)

doc/langref.html.in+7-3
...@@ -5687,7 +5687,7 @@ AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | Un...@@ -5687,7 +5687,7 @@ AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | Un
56875687
5688AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "&lt;&lt;=" | "&gt;&gt;=" | "&amp;=" | "^=" | "|=" | "*%=" | "+%=" | "-%="5688AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "&lt;&lt;=" | "&gt;&gt;=" | "&amp;=" | "^=" | "|=" | "*%=" | "+%=" | "-%="
56895689
5690BlockExpression(body) = Block | IfExpression(body) | IfErrorExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body)5690BlockExpression(body) = Block | IfExpression(body) | IfErrorExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) | SuspendExpression(body)
56915691
5692CompTimeExpression(body) = "comptime" body5692CompTimeExpression(body) = "comptime" body
56935693
...@@ -5705,6 +5705,8 @@ ReturnExpression = "return" option(Expression)...@@ -5705,6 +5705,8 @@ ReturnExpression = "return" option(Expression)
57055705
5706TryExpression = "try" Expression5706TryExpression = "try" Expression
57075707
5708AwaitExpression = "await" Expression
5709
5708BreakExpression = "break" option(":" Symbol) option(Expression)5710BreakExpression = "break" option(":" Symbol) option(Expression)
57095711
5710CancelExpression = "cancel" Expression;5712CancelExpression = "cancel" Expression;
...@@ -5713,6 +5715,8 @@ Defer(body) = ("defer" | "deferror") body...@@ -5713,6 +5715,8 @@ Defer(body) = ("defer" | "deferror") body
57135715
5714IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))5716IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
57155717
5718SuspendExpression(body) = "suspend" option(("|" Symbol "|" body))
5719
5716IfErrorExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body)5720IfErrorExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body)
57175721
5718TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body))5722TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body))
...@@ -5763,7 +5767,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")...@@ -5763,7 +5767,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")
57635767
5764StructLiteralField = "." Symbol "=" Expression5768StructLiteralField = "." Symbol "=" Expression
57655769
5766PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try"5770PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"
57675771
5768PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl5772PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl
57695773
...@@ -5771,7 +5775,7 @@ ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":"...@@ -5771,7 +5775,7 @@ ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":"
57715775
5772GroupedExpression = "(" Expression ")"5776GroupedExpression = "(" Expression ")"
57735777
5774KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable"5778KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable" | "suspend"
57755779
5776ErrorSetDecl = "error" "{" list(Symbol, ",") "}"5780ErrorSetDecl = "error" "{" list(Symbol, ",") "}"
57775781
src/all_types.hpp+13
...@@ -401,6 +401,8 @@ enum NodeType {...@@ -401,6 +401,8 @@ enum NodeType {
401 NodeTypeTestExpr,401 NodeTypeTestExpr,
402 NodeTypeErrorSetDecl,402 NodeTypeErrorSetDecl,
403 NodeTypeCancel,403 NodeTypeCancel,
404 NodeTypeAwaitExpr,
405 NodeTypeSuspend,
404};406};
405407
406struct AstNodeRoot {408struct AstNodeRoot {
...@@ -859,6 +861,15 @@ struct AstNodeErrorType {...@@ -859,6 +861,15 @@ struct AstNodeErrorType {
859struct AstNodeVarLiteral {861struct AstNodeVarLiteral {
860};862};
861863
864struct AstNodeAwaitExpr {
865 AstNode *expr;
866};
867
868struct AstNodeSuspend {
869 AstNode *block;
870 AstNode *promise_symbol;
871};
872
862struct AstNode {873struct AstNode {
863 enum NodeType type;874 enum NodeType type;
864 size_t line;875 size_t line;
...@@ -917,6 +928,8 @@ struct AstNode {...@@ -917,6 +928,8 @@ struct AstNode {
917 AstNodeVarLiteral var_literal;928 AstNodeVarLiteral var_literal;
918 AstNodeErrorSetDecl err_set_decl;929 AstNodeErrorSetDecl err_set_decl;
919 AstNodeCancelExpr cancel_expr;930 AstNodeCancelExpr cancel_expr;
931 AstNodeAwaitExpr await_expr;
932 AstNodeSuspend suspend;
920 } data;933 } data;
921};934};
922935
src/analyze.cpp+2
...@@ -3214,6 +3214,8 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -3214,6 +3214,8 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
3214 case NodeTypeTestExpr:3214 case NodeTypeTestExpr:
3215 case NodeTypeErrorSetDecl:3215 case NodeTypeErrorSetDecl:
3216 case NodeTypeCancel:3216 case NodeTypeCancel:
3217 case NodeTypeAwaitExpr:
3218 case NodeTypeSuspend:
3217 zig_unreachable();3219 zig_unreachable();
3218 }3220 }
3219}3221}
src/ast_render.cpp+21
...@@ -246,6 +246,10 @@ static const char *node_type_str(NodeType node_type) {...@@ -246,6 +246,10 @@ static const char *node_type_str(NodeType node_type) {
246 return "ErrorSetDecl";246 return "ErrorSetDecl";
247 case NodeTypeCancel:247 case NodeTypeCancel:
248 return "Cancel";248 return "Cancel";
249 case NodeTypeAwaitExpr:
250 return "AwaitExpr";
251 case NodeTypeSuspend:
252 return "Suspend";
249 }253 }
250 zig_unreachable();254 zig_unreachable();
251}255}
...@@ -1045,6 +1049,23 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -1045,6 +1049,23 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
1045 render_node_grouped(ar, node->data.cancel_expr.expr);1049 render_node_grouped(ar, node->data.cancel_expr.expr);
1046 break;1050 break;
1047 }1051 }
1052 case NodeTypeAwaitExpr:
1053 {
1054 fprintf(ar->f, "await ");
1055 render_node_grouped(ar, node->data.await_expr.expr);
1056 break;
1057 }
1058 case NodeTypeSuspend:
1059 {
1060 fprintf(ar->f, "suspend");
1061 if (node->data.suspend.block != nullptr) {
1062 fprintf(ar->f, " |");
1063 render_node_grouped(ar, node->data.suspend.promise_symbol);
1064 fprintf(ar->f, "| ");
1065 render_node_grouped(ar, node->data.suspend.block);
1066 }
1067 break;
1068 }
1048 case NodeTypeFnDecl:1069 case NodeTypeFnDecl:
1049 case NodeTypeParamDecl:1070 case NodeTypeParamDecl:
1050 case NodeTypeTestDecl:1071 case NodeTypeTestDecl:
src/ir.cpp+20
...@@ -5834,6 +5834,22 @@ static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -5834,6 +5834,22 @@ static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *parent_scope, AstNode
5834 return ir_build_cancel(irb, parent_scope, node, target_inst);5834 return ir_build_cancel(irb, parent_scope, node, target_inst);
5835}5835}
58365836
5837static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
5838 assert(node->type == NodeTypeAwaitExpr);
5839
5840 IrInstruction *target_inst = ir_gen_node(irb, node->data.await_expr.expr, parent_scope);
5841 if (target_inst == irb->codegen->invalid_instruction)
5842 return irb->codegen->invalid_instruction;
5843
5844 zig_panic("TODO: generate await expr");
5845}
5846
5847static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
5848 assert(node->type == NodeTypeSuspend);
5849
5850 zig_panic("TODO: generate suspend");
5851}
5852
5837static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,5853static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
5838 LVal lval)5854 LVal lval)
5839{5855{
...@@ -5932,6 +5948,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -5932,6 +5948,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
5932 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval);5948 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval);
5933 case NodeTypeCancel:5949 case NodeTypeCancel:
5934 return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval);5950 return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval);
5951 case NodeTypeAwaitExpr:
5952 return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval);
5953 case NodeTypeSuspend:
5954 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval);
5935 }5955 }
5936 zig_unreachable();5956 zig_unreachable();
5937}5957}
src/parser.cpp+76-3
...@@ -221,6 +221,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bo...@@ -221,6 +221,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bo
221static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory);221static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory);
222static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory);222static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory);
223static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index);223static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index);
224static AstNode *ast_parse_await_expr(ParseContext *pc, size_t *token_index);
224static AstNode *ast_parse_symbol(ParseContext *pc, size_t *token_index);225static AstNode *ast_parse_symbol(ParseContext *pc, size_t *token_index);
225226
226static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) {227static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) {
...@@ -650,6 +651,41 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m...@@ -650,6 +651,41 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m
650 return node;651 return node;
651}652}
652653
654/*
655SuspendExpression(body) = "suspend" "|" Symbol "|" body
656*/
657static AstNode *ast_parse_suspend_block(ParseContext *pc, size_t *token_index, bool mandatory) {
658 size_t orig_token_index = *token_index;
659
660 Token *suspend_token = &pc->tokens->at(*token_index);
661 if (suspend_token->id == TokenIdKeywordSuspend) {
662 *token_index += 1;
663 } else if (mandatory) {
664 ast_expect_token(pc, suspend_token, TokenIdKeywordSuspend);
665 zig_unreachable();
666 } else {
667 return nullptr;
668 }
669
670 Token *bar_token = &pc->tokens->at(*token_index);
671 if (bar_token->id == TokenIdBinOr) {
672 *token_index += 1;
673 } else if (mandatory) {
674 ast_expect_token(pc, suspend_token, TokenIdBinOr);
675 zig_unreachable();
676 } else {
677 *token_index = orig_token_index;
678 return nullptr;
679 }
680
681 AstNode *node = ast_create_node(pc, NodeTypeSuspend, suspend_token);
682 node->data.suspend.promise_symbol = ast_parse_symbol(pc, token_index);
683 ast_eat_token(pc, token_index, TokenIdBinOr);
684 node->data.suspend.block = ast_parse_block(pc, token_index, true);
685
686 return node;
687}
688
653/*689/*
654CompTimeExpression(body) = "comptime" body690CompTimeExpression(body) = "comptime" body
655*/691*/
...@@ -674,7 +710,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b...@@ -674,7 +710,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b
674710
675/*711/*
676PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl712PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl
677KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable"713KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable" | "suspend"
678ErrorSetDecl = "error" "{" list(Symbol, ",") "}"714ErrorSetDecl = "error" "{" list(Symbol, ",") "}"
679*/715*/
680static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {716static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
...@@ -738,6 +774,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo...@@ -738,6 +774,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
738 AstNode *node = ast_create_node(pc, NodeTypeUnreachable, token);774 AstNode *node = ast_create_node(pc, NodeTypeUnreachable, token);
739 *token_index += 1;775 *token_index += 1;
740 return node;776 return node;
777 } else if (token->id == TokenIdKeywordSuspend) {
778 AstNode *node = ast_create_node(pc, NodeTypeSuspend, token);
779 *token_index += 1;
780 return node;
741 } else if (token->id == TokenIdKeywordError) {781 } else if (token->id == TokenIdKeywordError) {
742 Token *next_token = &pc->tokens->at(*token_index + 1);782 Token *next_token = &pc->tokens->at(*token_index + 1);
743 if (next_token->id == TokenIdLBrace) {783 if (next_token->id == TokenIdLBrace) {
...@@ -1067,7 +1107,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {...@@ -1067,7 +1107,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
10671107
1068/*1108/*
1069PrefixOpExpression = PrefixOp ErrorSetExpr | SuffixOpExpression1109PrefixOpExpression = PrefixOp ErrorSetExpr | SuffixOpExpression
1070PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try"1110PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"
1071*/1111*/
1072static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {1112static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
1073 Token *token = &pc->tokens->at(*token_index);1113 Token *token = &pc->tokens->at(*token_index);
...@@ -1077,6 +1117,9 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,...@@ -1077,6 +1117,9 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,
1077 if (token->id == TokenIdKeywordTry) {1117 if (token->id == TokenIdKeywordTry) {
1078 return ast_parse_try_expr(pc, token_index);1118 return ast_parse_try_expr(pc, token_index);
1079 }1119 }
1120 if (token->id == TokenIdKeywordAwait) {
1121 return ast_parse_await_expr(pc, token_index);
1122 }
1080 PrefixOp prefix_op = tok_to_prefix_op(token);1123 PrefixOp prefix_op = tok_to_prefix_op(token);
1081 if (prefix_op == PrefixOpInvalid) {1124 if (prefix_op == PrefixOpInvalid) {
1082 return ast_parse_suffix_op_expr(pc, token_index, mandatory);1125 return ast_parse_suffix_op_expr(pc, token_index, mandatory);
...@@ -1535,6 +1578,23 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index) {...@@ -1535,6 +1578,23 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index) {
1535 return node;1578 return node;
1536}1579}
15371580
1581/*
1582AwaitExpression : "await" Expression
1583*/
1584static AstNode *ast_parse_await_expr(ParseContext *pc, size_t *token_index) {
1585 Token *token = &pc->tokens->at(*token_index);
1586
1587 if (token->id != TokenIdKeywordAwait) {
1588 return nullptr;
1589 }
1590 *token_index += 1;
1591
1592 AstNode *node = ast_create_node(pc, NodeTypeAwaitExpr, token);
1593 node->data.await_expr.expr = ast_parse_expression(pc, token_index, true);
1594
1595 return node;
1596}
1597
1538/*1598/*
1539BreakExpression = "break" option(":" Symbol) option(Expression)1599BreakExpression = "break" option(":" Symbol) option(Expression)
1540*/1600*/
...@@ -2044,7 +2104,7 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, size_t *token_index, boo...@@ -2044,7 +2104,7 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, size_t *token_index, boo
2044}2104}
20452105
2046/*2106/*
2047BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body)2107BlockExpression(body) = Block | IfExpression(body) | IfErrorExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) | SuspendExpression(body)
2048*/2108*/
2049static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool mandatory) {2109static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
2050 Token *token = &pc->tokens->at(*token_index);2110 Token *token = &pc->tokens->at(*token_index);
...@@ -2073,6 +2133,10 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool...@@ -2073,6 +2133,10 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool
2073 if (comptime_node)2133 if (comptime_node)
2074 return comptime_node;2134 return comptime_node;
20752135
2136 AstNode *suspend_node = ast_parse_suspend_block(pc, token_index, false);
2137 if (suspend_node)
2138 return suspend_node;
2139
2076 if (mandatory)2140 if (mandatory)
2077 ast_invalid_token_error(pc, token);2141 ast_invalid_token_error(pc, token);
20782142
...@@ -2255,6 +2319,8 @@ static bool statement_terminates_without_semicolon(AstNode *node) {...@@ -2255,6 +2319,8 @@ static bool statement_terminates_without_semicolon(AstNode *node) {
2255 return node->data.comptime_expr.expr->type == NodeTypeBlock;2319 return node->data.comptime_expr.expr->type == NodeTypeBlock;
2256 case NodeTypeDefer:2320 case NodeTypeDefer:
2257 return node->data.defer.expr->type == NodeTypeBlock;2321 return node->data.defer.expr->type == NodeTypeBlock;
2322 case NodeTypeSuspend:
2323 return node->data.suspend.block != nullptr && node->data.suspend.block->type == NodeTypeBlock;
2258 case NodeTypeSwitchExpr:2324 case NodeTypeSwitchExpr:
2259 case NodeTypeBlock:2325 case NodeTypeBlock:
2260 return true;2326 return true;
...@@ -2994,5 +3060,12 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2994,5 +3060,12 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2994 case NodeTypeCancel:3060 case NodeTypeCancel:
2995 visit_field(&node->data.cancel_expr.expr, visit, context);3061 visit_field(&node->data.cancel_expr.expr, visit, context);
2996 break;3062 break;
3063 case NodeTypeAwaitExpr:
3064 visit_field(&node->data.await_expr.expr, visit, context);
3065 break;
3066 case NodeTypeSuspend:
3067 visit_field(&node->data.suspend.promise_symbol, visit, context);
3068 visit_field(&node->data.suspend.block, visit, context);
3069 break;
2997 }3070 }
2998}3071}