authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-21 16:46:33-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-21 16:46:33-04:00
log0cce115476628ad1bb266309225efa5714d56321
tree47b49a58d1ff23ed74ea599961b5f9bc92e6fadc
parentd5346d7a8045549819abeb331d775aa2a10ca53b

update syntax for try and nullable unwrapping

closes #285

18 files changed, 208 insertions(+), 284 deletions(-)

doc/langref.md+4-6
......@@ -69,7 +69,7 @@ AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | Un
6969
7070AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" | "*%=" | "+%=" | "-%=" | "<<%="
7171
72BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body)
72BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body)
7373
7474CompTimeExpression(body) = "comptime" body
7575
......@@ -89,13 +89,11 @@ ReturnExpression = option("%") "return" option(Expression)
8989
9090Defer(body) = option("%") "defer" body
9191
92IfExpression(body) = IfVarExpression(body) | IfBoolExpression(body)
92IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
9393
94IfBoolExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
94TryExpression(body) = "try" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" option("|" Symbol "|") BlockExpression(body))
9595
96TryExpression(body) = "try" "(" option(("const" | "var") option("*") Symbol "=") Expression ")" body option("else" option("|" Symbol "|") BlockExpression(body))
97
98IfVarExpression(body) = "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" body Option("else" BlockExpression(body))
96TestExpression(body) = "test" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" option("|" Symbol "|") BlockExpression(body))
9997
10098BoolAndExpression = ComparisonExpression "and" BoolAndExpression | ComparisonExpression
10199
src/all_types.hpp+7-7
......@@ -344,7 +344,6 @@ enum NodeType {
344344 NodeTypeThisLiteral,
345345 NodeTypeUnreachable,
346346 NodeTypeIfBoolExpr,
347 NodeTypeIfVarExpr,
348347 NodeTypeWhileExpr,
349348 NodeTypeForExpr,
350349 NodeTypeSwitchExpr,
......@@ -364,6 +363,7 @@ enum NodeType {
364363 NodeTypeErrorType,
365364 NodeTypeVarLiteral,
366365 NodeTypeTryExpr,
366 NodeTypeTestExpr,
367367 NodeTypeInlineExpr,
368368};
369369
......@@ -577,7 +577,6 @@ struct AstNodeIfBoolExpr {
577577};
578578
579579struct AstNodeTryExpr {
580 bool var_is_const;
581580 Buf *var_symbol;
582581 bool var_is_ptr;
583582 AstNode *target_node;
......@@ -586,11 +585,12 @@ struct AstNodeTryExpr {
586585 Buf *err_symbol;
587586};
588587
589struct AstNodeIfVarExpr {
590 AstNodeVariableDeclaration var_decl;
591 AstNode *then_block;
592 AstNode *else_node; // null, block node, or other if expr node
588struct AstNodeTestExpr {
589 Buf *var_symbol;
593590 bool var_is_ptr;
591 AstNode *target_node;
592 AstNode *then_node;
593 AstNode *else_node; // null, block node, or other if expr node
594594};
595595
596596struct AstNodeWhileExpr {
......@@ -807,8 +807,8 @@ struct AstNode {
807807 AstNodeSliceExpr slice_expr;
808808 AstNodeUse use;
809809 AstNodeIfBoolExpr if_bool_expr;
810 AstNodeIfVarExpr if_var_expr;
811810 AstNodeTryExpr try_expr;
811 AstNodeTestExpr test_expr;
812812 AstNodeWhileExpr while_expr;
813813 AstNodeForExpr for_expr;
814814 AstNodeSwitchExpr switch_expr;
src/analyze.cpp+1-1
......@@ -2099,7 +2099,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
20992099 case NodeTypeSymbol:
21002100 case NodeTypePrefixOpExpr:
21012101 case NodeTypeIfBoolExpr:
2102 case NodeTypeIfVarExpr:
21032102 case NodeTypeWhileExpr:
21042103 case NodeTypeForExpr:
21052104 case NodeTypeSwitchExpr:
......@@ -2119,6 +2118,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
21192118 case NodeTypeErrorType:
21202119 case NodeTypeVarLiteral:
21212120 case NodeTypeTryExpr:
2121 case NodeTypeTestExpr:
21222122 case NodeTypeInlineExpr:
21232123 zig_unreachable();
21242124 }
src/ast_render.cpp+23-28
......@@ -192,8 +192,6 @@ static const char *node_type_str(NodeType node_type) {
192192 return "ThisLiteral";
193193 case NodeTypeIfBoolExpr:
194194 return "IfBoolExpr";
195 case NodeTypeIfVarExpr:
196 return "IfVarExpr";
197195 case NodeTypeWhileExpr:
198196 return "WhileExpr";
199197 case NodeTypeForExpr:
......@@ -236,6 +234,8 @@ static const char *node_type_str(NodeType node_type) {
236234 return "VarLiteral";
237235 case NodeTypeTryExpr:
238236 return "TryExpr";
237 case NodeTypeTestExpr:
238 return "TestExpr";
239239 case NodeTypeInlineExpr:
240240 return "InlineExpr";
241241 }
......@@ -760,38 +760,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
760760 fprintf(ar->f, "null");
761761 break;
762762 }
763 case NodeTypeIfVarExpr:
764 {
765 AstNodeVariableDeclaration *var_decl = &node->data.if_var_expr.var_decl;
766 const char *var_str = var_decl->is_const ? "const" : "var";
767 const char *var_name = buf_ptr(var_decl->symbol);
768 const char *ptr_str = node->data.if_var_expr.var_is_ptr ? "*" : "";
769 fprintf(ar->f, "if (%s %s%s", var_str, ptr_str, var_name);
770 if (var_decl->type) {
771 fprintf(ar->f, ": ");
772 render_node_ungrouped(ar, var_decl->type);
773 }
774 fprintf(ar->f, " ?= ");
775 render_node_grouped(ar, var_decl->expr);
776 fprintf(ar->f, ") ");
777 render_node_grouped(ar, node->data.if_var_expr.then_block);
778 if (node->data.if_var_expr.else_node) {
779 fprintf(ar->f, " else ");
780 render_node_grouped(ar, node->data.if_var_expr.else_node);
781 }
782 break;
783 }
784763 case NodeTypeTryExpr:
785764 {
786765 fprintf(ar->f, "try (");
766 render_node_grouped(ar, node->data.try_expr.target_node);
767 fprintf(ar->f, ") ");
787768 if (node->data.try_expr.var_symbol) {
788 const char *var_str = node->data.try_expr.var_is_const ? "const" : "var";
789 const char *var_name = buf_ptr(node->data.try_expr.var_symbol);
790769 const char *ptr_str = node->data.try_expr.var_is_ptr ? "*" : "";
791 fprintf(ar->f, "%s %s%s = ", var_str, ptr_str, var_name);
770 const char *var_name = buf_ptr(node->data.try_expr.var_symbol);
771 fprintf(ar->f, "|%s%s| ", ptr_str, var_name);
792772 }
793 render_node_grouped(ar, node->data.try_expr.target_node);
794 fprintf(ar->f, ") ");
795773 render_node_grouped(ar, node->data.try_expr.then_node);
796774 if (node->data.try_expr.else_node) {
797775 fprintf(ar->f, " else ");
......@@ -802,6 +780,23 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
802780 }
803781 break;
804782 }
783 case NodeTypeTestExpr:
784 {
785 fprintf(ar->f, "test (");
786 render_node_grouped(ar, node->data.test_expr.target_node);
787 fprintf(ar->f, ") ");
788 if (node->data.test_expr.var_symbol) {
789 const char *ptr_str = node->data.test_expr.var_is_ptr ? "*" : "";
790 const char *var_name = buf_ptr(node->data.test_expr.var_symbol);
791 fprintf(ar->f, "|%s%s| ", ptr_str, var_name);
792 }
793 render_node_grouped(ar, node->data.test_expr.then_node);
794 if (node->data.test_expr.else_node) {
795 fprintf(ar->f, " else ");
796 render_node_grouped(ar, node->data.test_expr.else_node);
797 }
798 break;
799 }
805800 case NodeTypeSwitchExpr:
806801 {
807802 AstNodeSwitchExpr *switch_expr = &node->data.switch_expr;
src/ir.cpp+26-24
......@@ -4941,14 +4941,14 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod
49414941 return ir_build_asm(irb, scope, node, input_list, output_types, output_vars, return_count, is_volatile);
49424942}
49434943
4944static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
4945 assert(node->type == NodeTypeIfVarExpr);
4944static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
4945 assert(node->type == NodeTypeTestExpr);
49464946
4947 AstNodeVariableDeclaration *var_decl = &node->data.if_var_expr.var_decl;
4948 AstNode *expr_node = var_decl->expr;
4949 AstNode *then_node = node->data.if_var_expr.then_block;
4950 AstNode *else_node = node->data.if_var_expr.else_node;
4951 bool var_is_ptr = node->data.if_var_expr.var_is_ptr;
4947 Buf *var_symbol = node->data.test_expr.var_symbol;
4948 AstNode *expr_node = node->data.test_expr.target_node;
4949 AstNode *then_node = node->data.test_expr.then_node;
4950 AstNode *else_node = node->data.test_expr.else_node;
4951 bool var_is_ptr = node->data.test_expr.var_is_ptr;
49524952
49534953 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR);
49544954 if (maybe_val_ptr == irb->codegen->invalid_instruction)
......@@ -4970,21 +4970,23 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, Scope *scope, AstNode *
49704970 ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime);
49714971
49724972 ir_set_cursor_at_end(irb, then_block);
4973 IrInstruction *var_type = nullptr;
4974 if (var_decl->type) {
4975 var_type = ir_gen_node(irb, var_decl->type, scope);
4976 if (var_type == irb->codegen->invalid_instruction)
4977 return irb->codegen->invalid_instruction;
4973
4974 Scope *var_scope;
4975 if (var_symbol) {
4976 IrInstruction *var_type = nullptr;
4977 bool is_shadowable = false;
4978 bool is_const = true;
4979 VariableTableEntry *var = ir_create_var(irb, node, scope,
4980 var_symbol, is_const, is_const, is_shadowable, is_comptime);
4981
4982 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, scope, node, maybe_val_ptr, false);
4983 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value);
4984 ir_build_var_decl(irb, scope, node, var, var_type, var_value);
4985 var_scope = var->child_scope;
4986 } else {
4987 var_scope = scope;
49784988 }
4979 bool is_shadowable = false;
4980 bool is_const = var_decl->is_const;
4981 VariableTableEntry *var = ir_create_var(irb, node, scope,
4982 var_decl->symbol, is_const, is_const, is_shadowable, is_comptime);
4983
4984 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, scope, node, maybe_val_ptr, false);
4985 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value);
4986 ir_build_var_decl(irb, scope, node, var, var_type, var_value);
4987 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var->child_scope);
4989 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope);
49884990 if (then_expr_result == irb->codegen->invalid_instruction)
49894991 return then_expr_result;
49904992 IrBasicBlock *after_then_block = irb->current_basic_block;
......@@ -5022,7 +5024,7 @@ static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *nod
50225024 AstNode *then_node = node->data.try_expr.then_node;
50235025 AstNode *else_node = node->data.try_expr.else_node;
50245026 bool var_is_ptr = node->data.try_expr.var_is_ptr;
5025 bool var_is_const = node->data.try_expr.var_is_const;
5027 bool var_is_const = true;
50265028 Buf *var_symbol = node->data.try_expr.var_symbol;
50275029 Buf *err_symbol = node->data.try_expr.err_symbol;
50285030
......@@ -5659,10 +5661,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
56595661 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval);
56605662 case NodeTypeVarLiteral:
56615663 return ir_lval_wrap(irb, scope, ir_gen_var_literal(irb, scope, node), lval);
5662 case NodeTypeIfVarExpr:
5663 return ir_lval_wrap(irb, scope, ir_gen_if_var_expr(irb, scope, node), lval);
56645664 case NodeTypeTryExpr:
56655665 return ir_lval_wrap(irb, scope, ir_gen_try_expr(irb, scope, node), lval);
5666 case NodeTypeTestExpr:
5667 return ir_lval_wrap(irb, scope, ir_gen_test_expr(irb, scope, node), lval);
56665668 case NodeTypeSwitchExpr:
56675669 return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval);
56685670 case NodeTypeGoto:
src/parser.cpp+81-91
......@@ -640,7 +640,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b
640640}
641641
642642/*
643TryExpression(body) = "try" "(" option(("const" | "var") option("*") Symbol "=") Expression ")" body option("else" option("|" Symbol "|") body)
643TryExpression(body) = "try" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" option("|" Symbol "|") BlockExpression(body))
644644*/
645645static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
646646 Token *try_token = &pc->tokens->at(*token_index);
......@@ -656,38 +656,25 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool m
656656 AstNode *node = ast_create_node(pc, NodeTypeTryExpr, try_token);
657657
658658 ast_eat_token(pc, token_index, TokenIdLParen);
659 node->data.try_expr.target_node = ast_parse_expression(pc, token_index, true);
660 ast_eat_token(pc, token_index, TokenIdRParen);
659661
660 Token *var_token = &pc->tokens->at(*token_index);
661 bool have_vars;
662 if (var_token->id == TokenIdKeywordVar) {
663 node->data.try_expr.var_is_const = false;
664 *token_index += 1;
665 have_vars = true;
666 } else if (var_token->id == TokenIdKeywordConst) {
667 node->data.try_expr.var_is_const = true;
662 Token *open_bar_tok = &pc->tokens->at(*token_index);
663 if (open_bar_tok->id == TokenIdBinOr) {
668664 *token_index += 1;
669 have_vars = true;
670 } else {
671 have_vars = false;
672 }
673665
674 if (have_vars) {
675 Token *star_token = &pc->tokens->at(*token_index);
676 if (star_token->id == TokenIdStar) {
677 node->data.try_expr.var_is_ptr = true;
666 Token *star_tok = &pc->tokens->at(*token_index);
667 if (star_tok->id == TokenIdStar) {
678668 *token_index += 1;
669 node->data.try_expr.var_is_ptr = true;
679670 }
680671
681672 Token *var_name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
682673 node->data.try_expr.var_symbol = token_buf(var_name_tok);
683674
684 ast_eat_token(pc, token_index, TokenIdEq);
675 ast_eat_token(pc, token_index, TokenIdBinOr);
685676 }
686677
687 node->data.try_expr.target_node = ast_parse_expression(pc, token_index, true);
688
689 ast_eat_token(pc, token_index, TokenIdRParen);
690
691678 node->data.try_expr.then_node = ast_parse_block_or_expression(pc, token_index, true);
692679
693680 Token *else_token = &pc->tokens->at(*token_index);
......@@ -709,6 +696,53 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool m
709696 return node;
710697}
711698
699/*
700TestExpression(body) = "test" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body))
701*/
702static AstNode *ast_parse_test_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
703 Token *test_token = &pc->tokens->at(*token_index);
704 if (test_token->id == TokenIdKeywordTest) {
705 *token_index += 1;
706 } else if (mandatory) {
707 ast_expect_token(pc, test_token, TokenIdKeywordTest);
708 zig_unreachable();
709 } else {
710 return nullptr;
711 }
712
713 AstNode *node = ast_create_node(pc, NodeTypeTestExpr, test_token);
714
715 ast_eat_token(pc, token_index, TokenIdLParen);
716 node->data.test_expr.target_node = ast_parse_expression(pc, token_index, true);
717 ast_eat_token(pc, token_index, TokenIdRParen);
718
719 Token *open_bar_tok = &pc->tokens->at(*token_index);
720 if (open_bar_tok->id == TokenIdBinOr) {
721 *token_index += 1;
722
723 Token *star_tok = &pc->tokens->at(*token_index);
724 if (star_tok->id == TokenIdStar) {
725 *token_index += 1;
726 node->data.test_expr.var_is_ptr = true;
727 }
728
729 Token *var_name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
730 node->data.test_expr.var_symbol = token_buf(var_name_tok);
731
732 ast_eat_token(pc, token_index, TokenIdBinOr);
733 }
734
735 node->data.test_expr.then_node = ast_parse_block_or_expression(pc, token_index, true);
736
737 Token *else_token = &pc->tokens->at(*token_index);
738 if (else_token->id == TokenIdKeywordElse) {
739 *token_index += 1;
740 node->data.test_expr.else_node = ast_parse_block_expr_or_expression(pc, token_index, true);
741 }
742
743 return node;
744}
745
712746/*
713747PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
714748KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "this" | "unreachable"
......@@ -1405,9 +1439,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc, size_t *token_index, b
14051439}
14061440
14071441/*
1408IfExpression(body) = IfVarExpression(body) | IfBoolExpression(body)
1409IfBoolExpression(body) = "if" "(" Expression ")" body option("else" body)
1410IfVarExpression(body) = "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" body Option("else" body)
1442IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
14111443*/
14121444static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
14131445 Token *if_token = &pc->tokens->at(*token_index);
......@@ -1423,63 +1455,18 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma
14231455
14241456 ast_eat_token(pc, token_index, TokenIdLParen);
14251457
1426 Token *token = &pc->tokens->at(*token_index);
1427 if (token->id == TokenIdKeywordConst || token->id == TokenIdKeywordVar) {
1428 AstNode *node = ast_create_node(pc, NodeTypeIfVarExpr, if_token);
1429 node->data.if_var_expr.var_decl.is_const = (token->id == TokenIdKeywordConst);
1430 *token_index += 1;
1431
1432 Token *star_or_symbol = &pc->tokens->at(*token_index);
1433 if (star_or_symbol->id == TokenIdStar) {
1434 *token_index += 1;
1435 node->data.if_var_expr.var_is_ptr = true;
1436 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
1437 node->data.if_var_expr.var_decl.symbol = token_buf(name_token);
1438 } else if (star_or_symbol->id == TokenIdSymbol) {
1439 *token_index += 1;
1440 node->data.if_var_expr.var_decl.symbol = token_buf(star_or_symbol);
1441 } else {
1442 ast_invalid_token_error(pc, star_or_symbol);
1443 }
1444
1445
1446 Token *eq_or_colon = &pc->tokens->at(*token_index);
1447 if (eq_or_colon->id == TokenIdMaybeAssign) {
1448 *token_index += 1;
1449 node->data.if_var_expr.var_decl.expr = ast_parse_expression(pc, token_index, true);
1450 } else if (eq_or_colon->id == TokenIdColon) {
1451 *token_index += 1;
1452 node->data.if_var_expr.var_decl.type = ast_parse_type_expr(pc, token_index, true);
1453
1454 ast_eat_token(pc, token_index, TokenIdMaybeAssign);
1455 node->data.if_var_expr.var_decl.expr = ast_parse_expression(pc, token_index, true);
1456 } else {
1457 ast_invalid_token_error(pc, eq_or_colon);
1458 }
1459 ast_eat_token(pc, token_index, TokenIdRParen);
1460 node->data.if_var_expr.then_block = ast_parse_block_or_expression(pc, token_index, true);
1461
1462 Token *else_token = &pc->tokens->at(*token_index);
1463 if (else_token->id == TokenIdKeywordElse) {
1464 *token_index += 1;
1465 node->data.if_var_expr.else_node = ast_parse_block_expr_or_expression(pc, token_index, true);
1466 }
1467
1468 return node;
1469 } else {
1470 AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_token);
1471 node->data.if_bool_expr.condition = ast_parse_expression(pc, token_index, true);
1472 ast_eat_token(pc, token_index, TokenIdRParen);
1473 node->data.if_bool_expr.then_block = ast_parse_block_or_expression(pc, token_index, true);
1474
1475 Token *else_token = &pc->tokens->at(*token_index);
1476 if (else_token->id == TokenIdKeywordElse) {
1477 *token_index += 1;
1478 node->data.if_bool_expr.else_node = ast_parse_block_expr_or_expression(pc, token_index, true);
1479 }
1458 AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_token);
1459 node->data.if_bool_expr.condition = ast_parse_expression(pc, token_index, true);
1460 ast_eat_token(pc, token_index, TokenIdRParen);
1461 node->data.if_bool_expr.then_block = ast_parse_block_or_expression(pc, token_index, true);
14801462
1481 return node;
1463 Token *else_token = &pc->tokens->at(*token_index);
1464 if (else_token->id == TokenIdKeywordElse) {
1465 *token_index += 1;
1466 node->data.if_bool_expr.else_node = ast_parse_block_expr_or_expression(pc, token_index, true);
14821467 }
1468
1469 return node;
14831470}
14841471
14851472/*
......@@ -1862,7 +1849,7 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, size_t *token_index, boo
18621849}
18631850
18641851/*
1865BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body)
1852BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body)
18661853*/
18671854static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
18681855 Token *token = &pc->tokens->at(*token_index);
......@@ -1895,6 +1882,10 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool
18951882 if (try_node)
18961883 return try_node;
18971884
1885 AstNode *test_node = ast_parse_test_expr(pc, token_index, false);
1886 if (test_node)
1887 return test_node;
1888
18981889 if (mandatory)
18991890 ast_invalid_token_error(pc, token);
19001891
......@@ -2079,14 +2070,14 @@ static bool statement_terminates_without_semicolon(AstNode *node) {
20792070 if (node->data.if_bool_expr.else_node)
20802071 return statement_terminates_without_semicolon(node->data.if_bool_expr.else_node);
20812072 return node->data.if_bool_expr.then_block->type == NodeTypeBlock;
2082 case NodeTypeIfVarExpr:
2083 if (node->data.if_var_expr.else_node)
2084 return statement_terminates_without_semicolon(node->data.if_var_expr.else_node);
2085 return node->data.if_var_expr.then_block->type == NodeTypeBlock;
20862073 case NodeTypeTryExpr:
20872074 if (node->data.try_expr.else_node)
20882075 return statement_terminates_without_semicolon(node->data.try_expr.else_node);
20892076 return node->data.try_expr.then_node->type == NodeTypeBlock;
2077 case NodeTypeTestExpr:
2078 if (node->data.test_expr.else_node)
2079 return statement_terminates_without_semicolon(node->data.test_expr.else_node);
2080 return node->data.test_expr.then_node->type == NodeTypeBlock;
20902081 case NodeTypeWhileExpr:
20912082 return node->data.while_expr.body->type == NodeTypeBlock;
20922083 case NodeTypeForExpr:
......@@ -2667,17 +2658,16 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
26672658 visit_field(&node->data.if_bool_expr.then_block, visit, context);
26682659 visit_field(&node->data.if_bool_expr.else_node, visit, context);
26692660 break;
2670 case NodeTypeIfVarExpr:
2671 visit_field(&node->data.if_var_expr.var_decl.type, visit, context);
2672 visit_field(&node->data.if_var_expr.var_decl.expr, visit, context);
2673 visit_field(&node->data.if_var_expr.then_block, visit, context);
2674 visit_field(&node->data.if_var_expr.else_node, visit, context);
2675 break;
26762661 case NodeTypeTryExpr:
26772662 visit_field(&node->data.try_expr.target_node, visit, context);
26782663 visit_field(&node->data.try_expr.then_node, visit, context);
26792664 visit_field(&node->data.try_expr.else_node, visit, context);
26802665 break;
2666 case NodeTypeTestExpr:
2667 visit_field(&node->data.test_expr.target_node, visit, context);
2668 visit_field(&node->data.test_expr.then_node, visit, context);
2669 visit_field(&node->data.test_expr.else_node, visit, context);
2670 break;
26812671 case NodeTypeWhileExpr:
26822672 visit_field(&node->data.while_expr.condition, visit, context);
26832673 visit_field(&node->data.while_expr.body, visit, context);
std/buf_map.zig+1-1
......@@ -28,7 +28,7 @@ pub const BufMap = struct {
2828 }
2929
3030 pub fn set(self: &BufMap, key: []const u8, value: []const u8) -> %void {
31 if (const entry ?= self.hash_map.get(key)) {
31 test (self.hash_map.get(key)) |entry| {
3232 const value_copy = %return self.copy(value);
3333 %defer self.free(value_copy);
3434 %return self.hash_map.put(key, value_copy);
std/build.zig+12-12
......@@ -309,7 +309,7 @@ pub const Builder = struct {
309309 }
310310
311311 fn processNixOSEnvVars(self: &Builder) {
312 if (const nix_cflags_compile ?= os.getEnv("NIX_CFLAGS_COMPILE")) {
312 test (os.getEnv("NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
313313 var it = mem.split(nix_cflags_compile, ' ');
314314 while (true) {
315315 const word = it.next() ?? break;
......@@ -325,7 +325,7 @@ pub const Builder = struct {
325325 }
326326 }
327327 }
328 if (const nix_ldflags ?= os.getEnv("NIX_LDFLAGS")) {
328 test (os.getEnv("NIX_LDFLAGS")) |nix_ldflags| {
329329 var it = mem.split(nix_ldflags, ' ');
330330 while (true) {
331331 const word = it.next() ?? break;
......@@ -353,7 +353,7 @@ pub const Builder = struct {
353353 .type_id = type_id,
354354 .description = description,
355355 };
356 if (const _ ?= %%self.available_options_map.put(name, available_option)) {
356 test (%%self.available_options_map.put(name, available_option)) {
357357 debug.panic("Option '{}' declared twice", name);
358358 }
359359 %%self.available_options_list.append(available_option);
......@@ -410,11 +410,11 @@ pub const Builder = struct {
410410 }
411411
412412 pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) -> bool {
413 if (var prev_value ?= %%self.user_input_options.put(name, UserInputOption {
413 test (%%self.user_input_options.put(name, UserInputOption {
414414 .name = name,
415415 .value = UserValue.Scalar { value },
416416 .used = false,
417 })) {
417 })) |*prev_value| {
418418 switch (prev_value.value) {
419419 UserValue.Scalar => |s| {
420420 var list = List([]const u8).init(self.allocator);
......@@ -444,11 +444,11 @@ pub const Builder = struct {
444444 }
445445
446446 pub fn addUserInputFlag(self: &Builder, name: []const u8) -> bool {
447 if (const prev_value ?= %%self.user_input_options.put(name, UserInputOption {
447 test (%%self.user_input_options.put(name, UserInputOption {
448448 .name = name,
449449 .value = UserValue.Flag,
450450 .used = false,
451 })) {
451 })) |*prev_value| {
452452 switch (prev_value.value) {
453453 UserValue.Scalar => |s| {
454454 %%io.stderr.printf("Flag '-D{}' conflicts with option '-D{}={}'.\n", name, name, s);
......@@ -766,7 +766,7 @@ pub const LibOrExeStep = struct {
766766 %%zig_args.append("--release");
767767 }
768768
769 if (const output_path ?= self.output_path) {
769 test (self.output_path) |output_path| {
770770 %%zig_args.append("--output");
771771 %%zig_args.append(builder.pathFromRoot(output_path));
772772 }
......@@ -912,7 +912,7 @@ pub const ObjectStep = struct {
912912 %%zig_args.append("--release");
913913 }
914914
915 if (const output_path ?= self.output_path) {
915 test (self.output_path) |output_path| {
916916 %%zig_args.append("--output");
917917 %%zig_args.append(builder.pathFromRoot(output_path));
918918 }
......@@ -1017,7 +1017,7 @@ pub const AsmStep = struct {
10171017 %%zig_args.append("--release");
10181018 }
10191019
1020 if (const output_path ?= self.output_path) {
1020 test (self.output_path) |output_path| {
10211021 %%zig_args.append("--output");
10221022 %%zig_args.append(builder.pathFromRoot(output_path));
10231023 }
......@@ -1194,7 +1194,7 @@ pub const LinkStep = struct {
11941194 %%zig_args.append("--static");
11951195 }
11961196
1197 if (const output_path ?= self.output_path) {
1197 test (self.output_path) |output_path| {
11981198 %%zig_args.append("--output");
11991199 %%zig_args.append(builder.pathFromRoot(output_path));
12001200 }
......@@ -1316,7 +1316,7 @@ pub const TestStep = struct {
13161316 %%zig_args.append("--release");
13171317 }
13181318
1319 if (const filter ?= self.filter) {
1319 test (self.filter) |filter| {
13201320 %%zig_args.append("--test-filter");
13211321 %%zig_args.append(filter);
13221322 }
std/hash_map.zig+1-1
......@@ -246,7 +246,7 @@ test "basicHashMapTest" {
246246 assert((??map.get(2)).value == 22);
247247 _ = map.remove(2);
248248 assert(map.remove(2) == null);
249 assert(if (const entry ?= map.get(2)) false else true);
249 assert(test (map.get(2)) false else true);
250250}
251251
252252fn hash_i32(x: i32) -> u32 {
std/os/child_process.zig+7-6
......@@ -56,9 +56,9 @@ pub const ChildProcess = struct {
5656 errno.EINVAL, errno.ECHILD => unreachable,
5757 errno.EINTR => continue,
5858 else => {
59 if (const *stdin ?= self.stdin) { stdin.close(); }
60 if (const *stdout ?= self.stdin) { stdout.close(); }
61 if (const *stderr ?= self.stdin) { stderr.close(); }
59 test (self.stdin) |*stdin| { stdin.close(); }
60 test (self.stdout) |*stdout| { stdout.close(); }
61 test (self.stderr) |*stderr| { stderr.close(); }
6262 return error.Unexpected;
6363 },
6464 }
......@@ -66,9 +66,10 @@ pub const ChildProcess = struct {
6666 break;
6767 }
6868
69 if (const *stdin ?= self.stdin) { stdin.close(); }
70 if (const *stdout ?= self.stdin) { stdout.close(); }
71 if (const *stderr ?= self.stdin) { stderr.close(); }
69 // TODO oops!
70 test (self.stdin) |*stdin| { stdin.close(); }
71 test (self.stdin) |*stdout| { stdout.close(); }
72 test (self.stdin) |*stderr| { stderr.close(); }
7273
7374 // Write @maxValue(ErrInt) to the write end of the err_pipe. This is after
7475 // waitpid, so this write is guaranteed to be after the child
std/os/index.zig+3-3
......@@ -162,7 +162,7 @@ pub fn posixOpen(file_path: []const u8, flags: usize, perm: usize, allocator: ?&
162162
163163 if (file_path.len < stack_buf.len) {
164164 path0 = stack_buf[0...file_path.len + 1];
165 } else if (const a ?= allocator) {
165 } else test (allocator) |a| {
166166 path0 = %return a.alloc(u8, file_path.len + 1);
167167 need_free = true;
168168 } else {
......@@ -230,7 +230,7 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con
230230 mem.set(?&u8, argv_buf, null);
231231 defer {
232232 for (argv_buf) |arg| {
233 const arg_buf = if (const ptr ?= arg) cstr.toSlice(ptr) else break;
233 const arg_buf = test (arg) |ptr| cstr.toSlice(ptr) else break;
234234 allocator.free(arg_buf);
235235 }
236236 allocator.free(argv_buf);
......@@ -257,7 +257,7 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con
257257 mem.set(?&u8, envp_buf, null);
258258 defer {
259259 for (envp_buf) |env| {
260 const env_buf = if (const ptr ?= env) cstr.toSlice(ptr) else break;
260 const env_buf = test (env) |ptr| cstr.toSlice(ptr) else break;
261261 allocator.free(env_buf);
262262 }
263263 allocator.free(envp_buf);
std/special/build_runner.zig+1-1
......@@ -53,7 +53,7 @@ pub fn main() -> %void {
5353 %%io.stderr.printf("Expected option name after '-D'\n\n");
5454 return usage(&builder, false, &io.stderr);
5555 }
56 if (const name_end ?= mem.indexOfScalar(u8, option_contents, '=')) {
56 test (mem.indexOfScalar(u8, option_contents, '=')) |name_end| {
5757 const option_name = option_contents[0...name_end];
5858 const option_value = option_contents[name_end + 1...];
5959 if (builder.addUserInputOption(option_name, option_value))
std/special/compiler_rt.zig+9-9
......@@ -34,7 +34,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
3434 // 0 X
3535 // ---
3636 // 0 X
37 if (const rem ?= maybe_rem) {
37 test (maybe_rem) |rem| {
3838 *rem = n[low] % d[low];
3939 }
4040 return n[low] / d[low];
......@@ -42,7 +42,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
4242 // 0 X
4343 // ---
4444 // K X
45 if (const rem ?= maybe_rem) {
45 test (maybe_rem) |rem| {
4646 *rem = n[low];
4747 }
4848 return 0;
......@@ -53,7 +53,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
5353 // K X
5454 // ---
5555 // 0 0
56 if (var rem ?= maybe_rem) {
56 test (maybe_rem) |rem| {
5757 *rem = n[high] % d[low];
5858 }
5959 return n[high] / d[low];
......@@ -63,7 +63,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
6363 // K 0
6464 // ---
6565 // K 0
66 if (var rem ?= maybe_rem) {
66 test (maybe_rem) |rem| {
6767 r[high] = n[high] % d[high];
6868 r[low] = 0;
6969 *rem = *@ptrCast(&du_int, &r[0]);
......@@ -75,7 +75,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
7575 // K 0
7676 // if d is a power of 2
7777 if ((d[high] & (d[high] - 1)) == 0) {
78 if (var rem ?= maybe_rem) {
78 test (maybe_rem) |rem| {
7979 r[low] = n[low];
8080 r[high] = n[high] & (d[high] - 1);
8181 *rem = *@ptrCast(&du_int, &r[0]);
......@@ -88,7 +88,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
8888 sr = @clz(su_int(d[high])) - @clz(su_int(n[high]));
8989 // 0 <= sr <= n_uword_bits - 2 or sr large
9090 if (sr > n_uword_bits - 2) {
91 if (var rem ?= maybe_rem) {
91 test (maybe_rem) |rem| {
9292 *rem = *@ptrCast(&du_int, &n[0]);
9393 }
9494 return 0;
......@@ -109,7 +109,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
109109 // 0 K
110110 // if d is a power of 2
111111 if ((d[low] & (d[low] - 1)) == 0) {
112 if (var rem ?= maybe_rem) {
112 test (maybe_rem) |rem| {
113113 *rem = n[low] & (d[low] - 1);
114114 }
115115 if (d[low] == 1) {
......@@ -153,7 +153,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
153153 sr = @clz(su_int(d[high])) - @clz(su_int(n[high]));
154154 // 0 <= sr <= n_uword_bits - 1 or sr large
155155 if (sr > n_uword_bits - 1) {
156 if (var rem ?= maybe_rem) {
156 test (maybe_rem) |rem| {
157157 *rem = *@ptrCast(&du_int, &n[0]);
158158 }
159159 return 0;
......@@ -198,7 +198,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
198198 sr -= 1;
199199 }
200200 *@ptrCast(&du_int, &q[0]) = (*@ptrCast(&du_int, &q[0]) << 1) | u64(carry);
201 if (var rem ?= maybe_rem) {
201 test (maybe_rem) |rem| {
202202 *rem = *@ptrCast(&du_int, &r[0]);
203203 }
204204 return *@ptrCast(&du_int, &q[0]);
test/cases/misc.zig-10
......@@ -128,16 +128,6 @@ fn testTruncate(x: u32) -> u8 {
128128 @truncate(u8, x)
129129}
130130
131test "assignToIfVarPtr" {
132 var maybe_bool: ?bool = true;
133
134 if (const *b ?= maybe_bool) {
135 *b = false;
136 }
137
138 assert(??maybe_bool == false);
139}
140
141131fn first4KeysOfHomeRow() -> []const u8 {
142132 "aoeu"
143133}
test/cases/null.zig+9-7
......@@ -3,7 +3,7 @@ const assert = @import("std").debug.assert;
33test "nullableType" {
44 const x : ?bool = @generatedCode(true);
55
6 if (const y ?= x) {
6 test (x) |y| {
77 if (y) {
88 // OK
99 } else {
......@@ -26,16 +26,17 @@ test "nullableType" {
2626 assert(num == 13);
2727}
2828
29test "assignToIfVarPtr" {
29test "test maybe object and get a pointer to the inner value" {
3030 var maybe_bool: ?bool = true;
3131
32 if (const *b ?= maybe_bool) {
32 test (maybe_bool) |*b| {
3333 *b = false;
3434 }
3535
3636 assert(??maybe_bool == false);
3737}
3838
39
3940test "rhsMaybeUnwrapReturn" {
4041 const x: ?bool = @generatedCode(true);
4142 const y = x ?? return;
......@@ -49,7 +50,8 @@ test "maybe return" {
4950
5051fn maybeReturnImpl() {
5152 assert(??foo(1235));
52 assert(if (const _ ?= foo(null)) false else true);
53 test (foo(null))
54 unreachable;
5355 assert(!??foo(1234));
5456}
5557
......@@ -64,10 +66,10 @@ test "ifVarMaybePointer" {
6466}
6567fn shouldBeAPlus1(p: &const Particle) -> u64 {
6668 var maybe_particle: ?Particle = *p;
67 if (const *particle ?= maybe_particle) {
69 test (maybe_particle) |*particle| {
6870 particle.a += 1;
6971 }
70 if (const particle ?= maybe_particle) {
72 test (maybe_particle) |particle| {
7173 return particle.a;
7274 }
7375 return 0;
......@@ -114,7 +116,7 @@ fn nullableVoidImpl() {
114116}
115117
116118fn bar(x: ?void) -> ?void {
117 if (const _ ?= x) {
119 test (x) {
118120 return {};
119121 } else {
120122 return null;
test/cases/try.zig+2-2
......@@ -7,7 +7,7 @@ test "tryOnErrorUnion" {
77}
88
99fn tryOnErrorUnionImpl() {
10 const x = try (const val = returnsTen()) {
10 const x = try (returnsTen()) |val| {
1111 val + 1
1212 } else |err| switch (err) {
1313 error.ItBroke, error.NoMem => 1,
......@@ -51,7 +51,7 @@ fn failIfTrue(ok: bool) -> %void {
5151//fn tryThenNotExecutedWithAssignment() {
5252// @setFnTest(this);
5353//
54// try (_ = failIfTrue(true)) {
54// try (failIfTrue(true)) {
5555// unreachable;
5656// } else |err| {
5757// assert(err == error.ItBroke);
test/compile_errors.zig+14-68
......@@ -118,92 +118,38 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
118118 \\}
119119 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
120120
121 cases.add("implicit semicolon - if(var) statement",
122 \\export fn entry() {
123 \\ if(_=foo()) {}
124 \\ var good = {};
125 \\ if(_=foo()) ({})
126 \\ var bad = {};
127 \\}
128 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
129
130 cases.add("implicit semicolon - if(var) expression",
131 \\export fn entry() {
132 \\ _ = if(_=foo()) {};
133 \\ var good = {};
134 \\ _ = if(_=foo()) {}
135 \\ var bad = {};
136 \\}
137 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
138
139 cases.add("implicit semicolon - if(var)-else statement",
140 \\export fn entry() {
141 \\ if(_=foo()) {} else {}
142 \\ var good = {};
143 \\ if(_=foo()) ({}) else ({})
144 \\ var bad = {};
145 \\}
146 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
147
148 cases.add("implicit semicolon - if(var)-else expression",
149 \\export fn entry() {
150 \\ _ = if(_=foo()) {} else {};
151 \\ var good = {};
152 \\ _ = if(_=foo()) {} else {}
153 \\ var bad = {};
154 \\}
155 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
156
157 cases.add("implicit semicolon - if(var)-else-if(var) statement",
158 \\export fn entry() {
159 \\ if(_=foo()) {} else if(_=foo()) {}
160 \\ var good = {};
161 \\ if(_=foo()) ({}) else if(_=foo()) ({})
162 \\ var bad = {};
163 \\}
164 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
165
166 cases.add("implicit semicolon - if(var)-else-if(var) expression",
167 \\export fn entry() {
168 \\ _ = if(_=foo()) {} else if(_=foo()) {};
169 \\ var good = {};
170 \\ _ = if(_=foo()) {} else if(_=foo()) {}
171 \\ var bad = {};
172 \\}
173 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
174
175 cases.add("implicit semicolon - if(var)-else-if(var)-else statement",
121 cases.add("implicit semicolon - try statement",
176122 \\export fn entry() {
177 \\ if(_=foo()) {} else if(_=foo()) {} else {}
123 \\ try (foo()) {}
178124 \\ var good = {};
179 \\ if(_=foo()) ({}) else if(_=foo()) ({}) else ({})
125 \\ try (foo()) ({})
180126 \\ var bad = {};
181127 \\}
182128 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
183129
184 cases.add("implicit semicolon - if(var)-else-if(var)-else expression",
130 cases.add("implicit semicolon - try expression",
185131 \\export fn entry() {
186 \\ _ = if(_=foo()) {} else if(_=foo()) {} else {};
132 \\ _ = try (foo()) {};
187133 \\ var good = {};
188 \\ _ = if(_=foo()) {} else if(_=foo()) {} else {}
134 \\ _ = try (foo()) {}
189135 \\ var bad = {};
190136 \\}
191137 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
192138
193 cases.add("implicit semicolon - try statement",
139 cases.add("implicit semicolon - test statement",
194140 \\export fn entry() {
195 \\ try (_ = foo()) {}
141 \\ test (foo()) {}
196142 \\ var good = {};
197 \\ try (_ = foo()) ({})
143 \\ test (foo()) ({})
198144 \\ var bad = {};
199145 \\}
200146 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
201147
202 cases.add("implicit semicolon - try expression",
148 cases.add("implicit semicolon - test expression",
203149 \\export fn entry() {
204 \\ _ = try (_ = foo()) {};
150 \\ _ = test (foo()) {};
205151 \\ var good = {};
206 \\ _ = try (_ = foo()) {}
152 \\ _ = test (foo()) {}
207153 \\ var bad = {};
208154 \\}
209155 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
......@@ -554,9 +500,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
554500
555501 cases.add("invalid maybe type",
556502 \\export fn f() {
557 \\ if (const x ?= true) { }
503 \\ test (true) |x| { }
558504 \\}
559 , ".tmp_source.zig:2:20: error: expected nullable type, found 'bool'");
505 , ".tmp_source.zig:2:11: error: expected nullable type, found 'bool'");
560506
561507 cases.add("cast unreachable",
562508 \\fn f() -> i32 {
test/tests.zig+7-7
......@@ -350,7 +350,7 @@ pub const CompareOutputContext = struct {
350350 Special.Asm => {
351351 const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o");
352352 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "assemble-and-link {}", case.name);
353 if (const filter ?= self.test_filter) {
353 test (self.test_filter) |filter| {
354354 if (mem.indexOf(u8, annotated_case_name, filter) == null)
355355 return;
356356 }
......@@ -379,7 +379,7 @@ pub const CompareOutputContext = struct {
379379 for ([]bool{false, true}) |release| {
380380 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "{} {} ({})",
381381 "compare-output", case.name, if (release) "release" else "debug");
382 if (const filter ?= self.test_filter) {
382 test (self.test_filter) |filter| {
383383 if (mem.indexOf(u8, annotated_case_name, filter) == null)
384384 continue;
385385 }
......@@ -407,7 +407,7 @@ pub const CompareOutputContext = struct {
407407 Special.DebugSafety => {
408408 const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o");
409409 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "debug-safety {}", case.name);
410 if (const filter ?= self.test_filter) {
410 test (self.test_filter) |filter| {
411411 if (mem.indexOf(u8, annotated_case_name, filter) == null)
412412 return;
413413 }
......@@ -626,7 +626,7 @@ pub const CompileErrorContext = struct {
626626 for ([]bool{false, true}) |release| {
627627 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "compile-error {} ({})",
628628 case.name, if (release) "release" else "debug");
629 if (const filter ?= self.test_filter) {
629 test (self.test_filter) |filter| {
630630 if (mem.indexOf(u8, annotated_case_name, filter) == null)
631631 continue;
632632 }
......@@ -661,7 +661,7 @@ pub const BuildExamplesContext = struct {
661661 const b = self.b;
662662
663663 const annotated_case_name = b.fmt("build {}", build_file);
664 if (const filter ?= self.test_filter) {
664 test (self.test_filter) |filter| {
665665 if (mem.indexOf(u8, annotated_case_name, filter) == null)
666666 return;
667667 }
......@@ -692,7 +692,7 @@ pub const BuildExamplesContext = struct {
692692 for ([]bool{false, true}) |release| {
693693 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "build {} ({})",
694694 root_src, if (release) "release" else "debug");
695 if (const filter ?= self.test_filter) {
695 test (self.test_filter) |filter| {
696696 if (mem.indexOf(u8, annotated_case_name, filter) == null)
697697 continue;
698698 }
......@@ -880,7 +880,7 @@ pub const ParseHContext = struct {
880880 const b = self.b;
881881
882882 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "parseh {}", case.name);
883 if (const filter ?= self.test_filter) {
883 test (self.test_filter) |filter| {
884884 if (mem.indexOf(u8, annotated_case_name, filter) == null)
885885 return;
886886 }