authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-20 00:05:38-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-20 00:05:38-05:00
log3d58d7232ab6d1fd54523182beb99c31512bc4b9
tree23303c1ac09a121c59fb075747e74fffcb838f83
parentaf10b0fec213172b0403abfd8ff6e53c88f8c3c6

parse async fn calls and cancel expressions


9 files changed, 171 insertions(+), 7 deletions(-)

doc/langref.html.in+4-2
...@@ -5663,7 +5663,7 @@ ErrorSetExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression...@@ -5663,7 +5663,7 @@ ErrorSetExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression
56635663
5664BlockOrExpression = Block | Expression5664BlockOrExpression = Block | Expression
56655665
5666Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression5666Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression | CancelExpression
56675667
5668AsmExpression = "asm" option("volatile") "(" String option(AsmOutput) ")"5668AsmExpression = "asm" option("volatile") "(" String option(AsmOutput) ")"
56695669
...@@ -5707,6 +5707,8 @@ TryExpression = "try" Expression...@@ -5707,6 +5707,8 @@ TryExpression = "try" Expression
57075707
5708BreakExpression = "break" option(":" Symbol) option(Expression)5708BreakExpression = "break" option(":" Symbol) option(Expression)
57095709
5710CancelExpression = "cancel" Expression;
5711
5710Defer(body) = ("defer" | "deferror") body5712Defer(body) = ("defer" | "deferror") body
57115713
5712IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))5714IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
...@@ -5745,7 +5747,7 @@ MultiplyOperator = "||" | "*" | "/" | "%" | "**" | "*%"...@@ -5745,7 +5747,7 @@ MultiplyOperator = "||" | "*" | "/" | "%" | "**" | "*%"
57455747
5746PrefixOpExpression = PrefixOp ErrorSetExpr | SuffixOpExpression5748PrefixOpExpression = PrefixOp ErrorSetExpr | SuffixOpExpression
57475749
5748SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)5750SuffixOpExpression = ("async" option("(" Expression ")") PrimaryExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
57495751
5750FieldAccessExpression = "." Symbol5752FieldAccessExpression = "." Symbol
57515753
src/all_types.hpp+16
...@@ -393,6 +393,7 @@ enum NodeType {...@@ -393,6 +393,7 @@ enum NodeType {
393 NodeTypeIfErrorExpr,393 NodeTypeIfErrorExpr,
394 NodeTypeTestExpr,394 NodeTypeTestExpr,
395 NodeTypeErrorSetDecl,395 NodeTypeErrorSetDecl,
396 NodeTypeCancel,
396};397};
397398
398struct AstNodeRoot {399struct AstNodeRoot {
...@@ -567,6 +568,8 @@ struct AstNodeFnCallExpr {...@@ -567,6 +568,8 @@ struct AstNodeFnCallExpr {
567 AstNode *fn_ref_expr;568 AstNode *fn_ref_expr;
568 ZigList<AstNode *> params;569 ZigList<AstNode *> params;
569 bool is_builtin;570 bool is_builtin;
571 bool is_async;
572 AstNode *async_allocator;
570};573};
571574
572struct AstNodeArrayAccessExpr {575struct AstNodeArrayAccessExpr {
...@@ -829,6 +832,10 @@ struct AstNodeBreakExpr {...@@ -829,6 +832,10 @@ struct AstNodeBreakExpr {
829 AstNode *expr; // may be null832 AstNode *expr; // may be null
830};833};
831834
835struct AstNodeCancelExpr {
836 AstNode *expr;
837};
838
832struct AstNodeContinueExpr {839struct AstNodeContinueExpr {
833 Buf *name;840 Buf *name;
834};841};
...@@ -900,6 +907,7 @@ struct AstNode {...@@ -900,6 +907,7 @@ struct AstNode {
900 AstNodeErrorType error_type;907 AstNodeErrorType error_type;
901 AstNodeVarLiteral var_literal;908 AstNodeVarLiteral var_literal;
902 AstNodeErrorSetDecl err_set_decl;909 AstNodeErrorSetDecl err_set_decl;
910 AstNodeCancelExpr cancel_expr;
903 } data;911 } data;
904};912};
905913
...@@ -1495,6 +1503,7 @@ struct CodeGen {...@@ -1495,6 +1503,7 @@ struct CodeGen {
1495 TypeTableEntry *entry_var;1503 TypeTableEntry *entry_var;
1496 TypeTableEntry *entry_global_error_set;1504 TypeTableEntry *entry_global_error_set;
1497 TypeTableEntry *entry_arg_tuple;1505 TypeTableEntry *entry_arg_tuple;
1506 TypeTableEntry *entry_promise;
1498 } builtin_types;1507 } builtin_types;
14991508
1500 EmitFileType emit_file_type;1509 EmitFileType emit_file_type;
...@@ -1939,6 +1948,7 @@ enum IrInstructionId {...@@ -1939,6 +1948,7 @@ enum IrInstructionId {
1939 IrInstructionIdExport,1948 IrInstructionIdExport,
1940 IrInstructionIdErrorReturnTrace,1949 IrInstructionIdErrorReturnTrace,
1941 IrInstructionIdErrorUnion,1950 IrInstructionIdErrorUnion,
1951 IrInstructionIdCancel,
1942};1952};
19431953
1944struct IrInstruction {1954struct IrInstruction {
...@@ -2776,6 +2786,12 @@ struct IrInstructionErrorUnion {...@@ -2776,6 +2786,12 @@ struct IrInstructionErrorUnion {
2776 IrInstruction *payload;2786 IrInstruction *payload;
2777};2787};
27782788
2789struct IrInstructionCancel {
2790 IrInstruction base;
2791
2792 IrInstruction *target;
2793};
2794
2779static const size_t slice_ptr_index = 0;2795static const size_t slice_ptr_index = 0;
2780static const size_t slice_len_index = 1;2796static const size_t slice_len_index = 1;
27812797
src/analyze.cpp+1
...@@ -3117,6 +3117,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -3117,6 +3117,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
3117 case NodeTypeIfErrorExpr:3117 case NodeTypeIfErrorExpr:
3118 case NodeTypeTestExpr:3118 case NodeTypeTestExpr:
3119 case NodeTypeErrorSetDecl:3119 case NodeTypeErrorSetDecl:
3120 case NodeTypeCancel:
3120 zig_unreachable();3121 zig_unreachable();
3121 }3122 }
3122}3123}
src/ast_render.cpp+8
...@@ -244,6 +244,8 @@ static const char *node_type_str(NodeType node_type) {...@@ -244,6 +244,8 @@ static const char *node_type_str(NodeType node_type) {
244 return "TestExpr";244 return "TestExpr";
245 case NodeTypeErrorSetDecl:245 case NodeTypeErrorSetDecl:
246 return "ErrorSetDecl";246 return "ErrorSetDecl";
247 case NodeTypeCancel:
248 return "Cancel";
247 }249 }
248 zig_unreachable();250 zig_unreachable();
249}251}
...@@ -1037,6 +1039,12 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -1037,6 +1039,12 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
1037 fprintf(ar->f, "}");1039 fprintf(ar->f, "}");
1038 break;1040 break;
1039 }1041 }
1042 case NodeTypeCancel:
1043 {
1044 fprintf(ar->f, "cancel ");
1045 render_node_grouped(ar, node->data.cancel_expr.expr);
1046 break;
1047 }
1040 case NodeTypeFnDecl:1048 case NodeTypeFnDecl:
1041 case NodeTypeParamDecl:1049 case NodeTypeParamDecl:
1042 case NodeTypeTestDecl:1050 case NodeTypeTestDecl:
src/codegen.cpp+16
...@@ -3088,6 +3088,10 @@ static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutable *execu...@@ -3088,6 +3088,10 @@ static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutable *execu
3088 return g->cur_err_ret_trace_val;3088 return g->cur_err_ret_trace_val;
3089}3089}
30903090
3091static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrInstructionCancel *instruction) {
3092 zig_panic("TODO ir_render_cancel");
3093}
3094
3091static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {3095static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {
3092 switch (atomic_order) {3096 switch (atomic_order) {
3093 case AtomicOrderUnordered: return LLVMAtomicOrderingUnordered;3097 case AtomicOrderUnordered: return LLVMAtomicOrderingUnordered;
...@@ -3862,6 +3866,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -3862,6 +3866,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
3862 return ir_render_align_cast(g, executable, (IrInstructionAlignCast *)instruction);3866 return ir_render_align_cast(g, executable, (IrInstructionAlignCast *)instruction);
3863 case IrInstructionIdErrorReturnTrace:3867 case IrInstructionIdErrorReturnTrace:
3864 return ir_render_error_return_trace(g, executable, (IrInstructionErrorReturnTrace *)instruction);3868 return ir_render_error_return_trace(g, executable, (IrInstructionErrorReturnTrace *)instruction);
3869 case IrInstructionIdCancel:
3870 return ir_render_cancel(g, executable, (IrInstructionCancel *)instruction);
3865 }3871 }
3866 zig_unreachable();3872 zig_unreachable();
3867}3873}
...@@ -5271,6 +5277,16 @@ static void define_builtin_types(CodeGen *g) {...@@ -5271,6 +5277,16 @@ static void define_builtin_types(CodeGen *g) {
52715277
5272 g->primitive_type_table.put(&entry->name, entry);5278 g->primitive_type_table.put(&entry->name, entry);
5273 }5279 }
5280 {
5281 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);
5282 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
5283 entry->type_ref = u8_ptr_type->type_ref;
5284 entry->zero_bits = false;
5285 buf_init_from_str(&entry->name, "promise");
5286 entry->di_type = u8_ptr_type->di_type;
5287 g->builtin_types.entry_promise = entry;
5288 g->primitive_type_table.put(&entry->name, entry);
5289 }
52745290
5275}5291}
52765292
src/ir.cpp+46
...@@ -637,6 +637,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) {...@@ -637,6 +637,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) {
637 return IrInstructionIdErrorUnion;637 return IrInstructionIdErrorUnion;
638}638}
639639
640static constexpr IrInstructionId ir_instruction_id(IrInstructionCancel *) {
641 return IrInstructionIdCancel;
642}
643
640template<typename T>644template<typename T>
641static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {645static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
642 T *special_instruction = allocate<T>(1);646 T *special_instruction = allocate<T>(1);
...@@ -2396,6 +2400,17 @@ static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode...@@ -2396,6 +2400,17 @@ static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode
2396 return &instruction->base;2400 return &instruction->base;
2397}2401}
23982402
2403static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *source_node,
2404 IrInstruction *target)
2405{
2406 IrInstructionCancel *instruction = ir_build_instruction<IrInstructionCancel>(irb, scope, source_node);
2407 instruction->target = target;
2408
2409 ir_ref_instruction(target, irb->current_basic_block);
2410
2411 return &instruction->base;
2412}
2413
2399static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {2414static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
2400 results[ReturnKindUnconditional] = 0;2415 results[ReturnKindUnconditional] = 0;
2401 results[ReturnKindError] = 0;2416 results[ReturnKindError] = 0;
...@@ -3873,6 +3888,10 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node...@@ -3873,6 +3888,10 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
3873 return args[i];3888 return args[i];
3874 }3889 }
38753890
3891 if (node->data.fn_call_expr.is_async) {
3892 zig_panic("TODO ir_gen_fn_call for async fn calls");
3893 }
3894
3876 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto);3895 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto);
3877}3896}
38783897
...@@ -5598,6 +5617,16 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -5598,6 +5617,16 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
5598 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);5617 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);
5599}5618}
56005619
5620static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
5621 assert(node->type == NodeTypeCancel);
5622
5623 IrInstruction *target_inst = ir_gen_node(irb, node->data.cancel_expr.expr, parent_scope);
5624 if (target_inst == irb->codegen->invalid_instruction)
5625 return irb->codegen->invalid_instruction;
5626
5627 return ir_build_cancel(irb, parent_scope, node, target_inst);
5628}
5629
5601static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,5630static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
5602 LVal lval)5631 LVal lval)
5603{5632{
...@@ -5694,6 +5723,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -5694,6 +5723,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
5694 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval);5723 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval);
5695 case NodeTypeErrorSetDecl:5724 case NodeTypeErrorSetDecl:
5696 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval);5725 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval);
5726 case NodeTypeCancel:
5727 return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval);
5697 }5728 }
5698 zig_unreachable();5729 zig_unreachable();
5699}5730}
...@@ -16459,6 +16490,17 @@ static TypeTableEntry *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstruc...@@ -16459,6 +16490,17 @@ static TypeTableEntry *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstruc
16459 }16490 }
16460}16491}
1646116492
16493static TypeTableEntry *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) {
16494 IrInstruction *casted_target = ir_implicit_cast(ira, instruction->target->other, ira->codegen->builtin_types.entry_promise);
16495 if (type_is_invalid(casted_target->value.type))
16496 return ira->codegen->builtin_types.entry_invalid;
16497
16498 IrInstruction *result = ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_target);
16499 result->value.type = casted_target->value.type;
16500 ir_link_new_instruction(result, &instruction->base);
16501 return result->value.type;
16502}
16503
16462static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {16504static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
16463 switch (instruction->id) {16505 switch (instruction->id) {
16464 case IrInstructionIdInvalid:16506 case IrInstructionIdInvalid:
...@@ -16661,6 +16703,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -16661,6 +16703,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
16661 return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction);16703 return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction);
16662 case IrInstructionIdErrorUnion:16704 case IrInstructionIdErrorUnion:
16663 return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction);16705 return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction);
16706 case IrInstructionIdCancel:
16707 return ir_analyze_instruction_cancel(ira, (IrInstructionCancel *)instruction);
16664 }16708 }
16665 zig_unreachable();16709 zig_unreachable();
16666}16710}
...@@ -16774,7 +16818,9 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -16774,7 +16818,9 @@ bool ir_has_side_effects(IrInstruction *instruction) {
16774 case IrInstructionIdPtrTypeOf:16818 case IrInstructionIdPtrTypeOf:
16775 case IrInstructionIdSetAlignStack:16819 case IrInstructionIdSetAlignStack:
16776 case IrInstructionIdExport:16820 case IrInstructionIdExport:
16821 case IrInstructionIdCancel:
16777 return true;16822 return true;
16823
16778 case IrInstructionIdPhi:16824 case IrInstructionIdPhi:
16779 case IrInstructionIdUnOp:16825 case IrInstructionIdUnOp:
16780 case IrInstructionIdBinOp:16826 case IrInstructionIdBinOp:
src/ir_print.cpp+8
...@@ -1010,6 +1010,11 @@ static void ir_print_error_union(IrPrint *irp, IrInstructionErrorUnion *instruct...@@ -1010,6 +1010,11 @@ static void ir_print_error_union(IrPrint *irp, IrInstructionErrorUnion *instruct
1010 ir_print_other_instruction(irp, instruction->payload);1010 ir_print_other_instruction(irp, instruction->payload);
1011}1011}
10121012
1013static void ir_print_cancel(IrPrint *irp, IrInstructionCancel *instruction) {
1014 fprintf(irp->f, "cancel ");
1015 ir_print_other_instruction(irp, instruction->target);
1016}
1017
1013static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1018static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1014 ir_print_prefix(irp, instruction);1019 ir_print_prefix(irp, instruction);
1015 switch (instruction->id) {1020 switch (instruction->id) {
...@@ -1330,6 +1335,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1330,6 +1335,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1330 case IrInstructionIdErrorUnion:1335 case IrInstructionIdErrorUnion:
1331 ir_print_error_union(irp, (IrInstructionErrorUnion *)instruction);1336 ir_print_error_union(irp, (IrInstructionErrorUnion *)instruction);
1332 break;1337 break;
1338 case IrInstructionIdCancel:
1339 ir_print_cancel(irp, (IrInstructionCancel *)instruction);
1340 break;
1333 }1341 }
1334 fprintf(irp->f, "\n");1342 fprintf(irp->f, "\n");
1335}1343}
src/parser.cpp+56-5
...@@ -920,7 +920,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, size_t *token_inde...@@ -920,7 +920,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, size_t *token_inde
920}920}
921921
922/*922/*
923SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)923SuffixOpExpression = ("async" option("(" Expression ")") PrimaryExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
924FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)924FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)
925ArrayAccessExpression : token(LBracket) Expression token(RBracket)925ArrayAccessExpression : token(LBracket) Expression token(RBracket)
926SliceExpression = "[" Expression ".." option(Expression) "]"926SliceExpression = "[" Expression ".." option(Expression) "]"
...@@ -928,9 +928,34 @@ FieldAccessExpression : token(Dot) token(Symbol)...@@ -928,9 +928,34 @@ FieldAccessExpression : token(Dot) token(Symbol)
928StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression928StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression
929*/929*/
930static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {930static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
931 AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory);931 AstNode *primary_expr;
932 if (!primary_expr)932
933 return nullptr;933 Token *async_token = &pc->tokens->at(*token_index);
934 if (async_token->id == TokenIdKeywordAsync) {
935 *token_index += 1;
936
937 AstNode *allocator_expr_node = nullptr;
938 Token *async_lparen_tok = &pc->tokens->at(*token_index);
939 if (async_lparen_tok->id == TokenIdLParen) {
940 *token_index += 1;
941 allocator_expr_node = ast_parse_expression(pc, token_index, true);
942 ast_eat_token(pc, token_index, TokenIdRParen);
943 }
944
945 AstNode *fn_ref_expr_node = ast_parse_primary_expr(pc, token_index, true);
946 Token *lparen_tok = ast_eat_token(pc, token_index, TokenIdLParen);
947 AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, lparen_tok);
948 node->data.fn_call_expr.is_async = true;
949 node->data.fn_call_expr.async_allocator = allocator_expr_node;
950 node->data.fn_call_expr.fn_ref_expr = fn_ref_expr_node;
951 ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);
952
953 primary_expr = node;
954 } else {
955 primary_expr = ast_parse_primary_expr(pc, token_index, mandatory);
956 if (!primary_expr)
957 return nullptr;
958 }
934959
935 while (true) {960 while (true) {
936 Token *first_token = &pc->tokens->at(*token_index);961 Token *first_token = &pc->tokens->at(*token_index);
...@@ -1535,6 +1560,24 @@ static AstNode *ast_parse_break_expr(ParseContext *pc, size_t *token_index) {...@@ -1535,6 +1560,24 @@ static AstNode *ast_parse_break_expr(ParseContext *pc, size_t *token_index) {
1535 return node;1560 return node;
1536}1561}
15371562
1563/*
1564CancelExpression = "cancel" Expression;
1565*/
1566static AstNode *ast_parse_cancel_expr(ParseContext *pc, size_t *token_index) {
1567 Token *token = &pc->tokens->at(*token_index);
1568
1569 if (token->id != TokenIdKeywordCancel) {
1570 return nullptr;
1571 }
1572 *token_index += 1;
1573
1574 AstNode *node = ast_create_node(pc, NodeTypeCancel, token);
1575
1576 node->data.cancel_expr.expr = ast_parse_expression(pc, token_index, false);
1577
1578 return node;
1579}
1580
1538/*1581/*
1539Defer(body) = ("defer" | "errdefer") body1582Defer(body) = ("defer" | "errdefer") body
1540*/1583*/
...@@ -2159,7 +2202,7 @@ static AstNode *ast_parse_block_or_expression(ParseContext *pc, size_t *token_in...@@ -2159,7 +2202,7 @@ static AstNode *ast_parse_block_or_expression(ParseContext *pc, size_t *token_in
2159}2202}
21602203
2161/*2204/*
2162Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression2205Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression | CancelExpression
2163*/2206*/
2164static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool mandatory) {2207static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool mandatory) {
2165 Token *token = &pc->tokens->at(*token_index);2208 Token *token = &pc->tokens->at(*token_index);
...@@ -2176,6 +2219,10 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool...@@ -2176,6 +2219,10 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool
2176 if (break_expr)2219 if (break_expr)
2177 return break_expr;2220 return break_expr;
21782221
2222 AstNode *cancel_expr = ast_parse_cancel_expr(pc, token_index);
2223 if (cancel_expr)
2224 return cancel_expr;
2225
2179 AstNode *ass_expr = ast_parse_ass_expr(pc, token_index, false);2226 AstNode *ass_expr = ast_parse_ass_expr(pc, token_index, false);
2180 if (ass_expr)2227 if (ass_expr)
2181 return ass_expr;2228 return ass_expr;
...@@ -2809,6 +2856,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2809,6 +2856,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2809 case NodeTypeFnCallExpr:2856 case NodeTypeFnCallExpr:
2810 visit_field(&node->data.fn_call_expr.fn_ref_expr, visit, context);2857 visit_field(&node->data.fn_call_expr.fn_ref_expr, visit, context);
2811 visit_node_list(&node->data.fn_call_expr.params, visit, context);2858 visit_node_list(&node->data.fn_call_expr.params, visit, context);
2859 visit_field(&node->data.fn_call_expr.async_allocator, visit, context);
2812 break;2860 break;
2813 case NodeTypeArrayAccessExpr:2861 case NodeTypeArrayAccessExpr:
2814 visit_field(&node->data.array_access_expr.array_ref_expr, visit, context);2862 visit_field(&node->data.array_access_expr.array_ref_expr, visit, context);
...@@ -2931,5 +2979,8 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2931,5 +2979,8 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2931 case NodeTypeErrorSetDecl:2979 case NodeTypeErrorSetDecl:
2932 visit_node_list(&node->data.err_set_decl.decls, visit, context);2980 visit_node_list(&node->data.err_set_decl.decls, visit, context);
2933 break;2981 break;
2982 case NodeTypeCancel:
2983 visit_field(&node->data.cancel_expr.expr, visit, context);
2984 break;
2934 }2985 }
2935}2986}
std/mem.zig+16
...@@ -116,6 +116,22 @@ pub const Allocator = struct {...@@ -116,6 +116,22 @@ pub const Allocator = struct {
116 const non_const_ptr = @intToPtr(&u8, @ptrToInt(bytes.ptr));116 const non_const_ptr = @intToPtr(&u8, @ptrToInt(bytes.ptr));
117 self.freeFn(self, non_const_ptr[0..bytes.len]);117 self.freeFn(self, non_const_ptr[0..bytes.len]);
118 }118 }
119
120 pub const AsyncAllocator = struct {
121 allocator: &Allocator,
122
123 fn alloc(self: &const AsyncAllocator, byte_count: usize, alignment: u29) Error![]u8 {
124 return self.allocator.allocFn(self.allocator, byte_count, alignment);
125 }
126
127 fn free(self: &const AsyncAllocator, old_mem: []u8) {
128 return self.allocator.freeFn(self.allocator, old_mem);
129 }
130 };
131
132 fn toAsync(self: &Allocator) AsyncAllocator {
133 return AsyncAllocator { .allocator = self };
134 }
119};135};
120136
121/// Copy all of source into dest at position 0.137/// Copy all of source into dest at position 0.