| author | |
| committer | |
| log | 0cce115476628ad1bb266309225efa5714d56321 |
| tree | 47b49a58d1ff23ed74ea599961b5f9bc92e6fadc |
| parent | d5346d7a8045549819abeb331d775aa2a10ca53b |
closes #28518 files changed, 208 insertions(+), 284 deletions(-)
doc/langref.md+4-6| ... | @@ -69,7 +69,7 @@ AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | Un | ... | @@ -69,7 +69,7 @@ AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | Un |
| 69 | 69 | ||
| 70 | AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" | "*%=" | "+%=" | "-%=" | "<<%=" | 70 | AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" | "*%=" | "+%=" | "-%=" | "<<%=" |
| 71 | 71 | ||
| 72 | BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) | 72 | BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) |
| 73 | 73 | ||
| 74 | CompTimeExpression(body) = "comptime" body | 74 | CompTimeExpression(body) = "comptime" body |
| 75 | 75 | ||
| ... | @@ -89,13 +89,11 @@ ReturnExpression = option("%") "return" option(Expression) | ... | @@ -89,13 +89,11 @@ ReturnExpression = option("%") "return" option(Expression) |
| 89 | 89 | ||
| 90 | Defer(body) = option("%") "defer" body | 90 | Defer(body) = option("%") "defer" body |
| 91 | 91 | ||
| 92 | IfExpression(body) = IfVarExpression(body) | IfBoolExpression(body) | 92 | IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body)) |
| 93 | 93 | ||
| 94 | IfBoolExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body)) | 94 | TryExpression(body) = "try" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" option("|" Symbol "|") BlockExpression(body)) |
| 95 | 95 | ||
| 96 | TryExpression(body) = "try" "(" option(("const" | "var") option("*") Symbol "=") Expression ")" body option("else" option("|" Symbol "|") BlockExpression(body)) | 96 | TestExpression(body) = "test" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" option("|" Symbol "|") BlockExpression(body)) |
| 97 | |||
| 98 | IfVarExpression(body) = "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" body Option("else" BlockExpression(body)) | ||
| 99 | 97 | ||
| 100 | BoolAndExpression = ComparisonExpression "and" BoolAndExpression | ComparisonExpression | 98 | BoolAndExpression = ComparisonExpression "and" BoolAndExpression | ComparisonExpression |
| 101 | 99 |
src/all_types.hpp+7-7| ... | @@ -344,7 +344,6 @@ enum NodeType { | ... | @@ -344,7 +344,6 @@ enum NodeType { |
| 344 | NodeTypeThisLiteral, | 344 | NodeTypeThisLiteral, |
| 345 | NodeTypeUnreachable, | 345 | NodeTypeUnreachable, |
| 346 | NodeTypeIfBoolExpr, | 346 | NodeTypeIfBoolExpr, |
| 347 | NodeTypeIfVarExpr, | ||
| 348 | NodeTypeWhileExpr, | 347 | NodeTypeWhileExpr, |
| 349 | NodeTypeForExpr, | 348 | NodeTypeForExpr, |
| 350 | NodeTypeSwitchExpr, | 349 | NodeTypeSwitchExpr, |
| ... | @@ -364,6 +363,7 @@ enum NodeType { | ... | @@ -364,6 +363,7 @@ enum NodeType { |
| 364 | NodeTypeErrorType, | 363 | NodeTypeErrorType, |
| 365 | NodeTypeVarLiteral, | 364 | NodeTypeVarLiteral, |
| 366 | NodeTypeTryExpr, | 365 | NodeTypeTryExpr, |
| 366 | NodeTypeTestExpr, | ||
| 367 | NodeTypeInlineExpr, | 367 | NodeTypeInlineExpr, |
| 368 | }; | 368 | }; |
| 369 | 369 | ||
| ... | @@ -577,7 +577,6 @@ struct AstNodeIfBoolExpr { | ... | @@ -577,7 +577,6 @@ struct AstNodeIfBoolExpr { |
| 577 | }; | 577 | }; |
| 578 | 578 | ||
| 579 | struct AstNodeTryExpr { | 579 | struct AstNodeTryExpr { |
| 580 | bool var_is_const; | ||
| 581 | Buf *var_symbol; | 580 | Buf *var_symbol; |
| 582 | bool var_is_ptr; | 581 | bool var_is_ptr; |
| 583 | AstNode *target_node; | 582 | AstNode *target_node; |
| ... | @@ -586,11 +585,12 @@ struct AstNodeTryExpr { | ... | @@ -586,11 +585,12 @@ struct AstNodeTryExpr { |
| 586 | Buf *err_symbol; | 585 | Buf *err_symbol; |
| 587 | }; | 586 | }; |
| 588 | 587 | ||
| 589 | struct AstNodeIfVarExpr { | 588 | struct AstNodeTestExpr { |
| 590 | AstNodeVariableDeclaration var_decl; | 589 | Buf *var_symbol; |
| 591 | AstNode *then_block; | ||
| 592 | AstNode *else_node; // null, block node, or other if expr node | ||
| 593 | bool var_is_ptr; | 590 | bool var_is_ptr; |
| 591 | AstNode *target_node; | ||
| 592 | AstNode *then_node; | ||
| 593 | AstNode *else_node; // null, block node, or other if expr node | ||
| 594 | }; | 594 | }; |
| 595 | 595 | ||
| 596 | struct AstNodeWhileExpr { | 596 | struct AstNodeWhileExpr { |
| ... | @@ -807,8 +807,8 @@ struct AstNode { | ... | @@ -807,8 +807,8 @@ struct AstNode { |
| 807 | AstNodeSliceExpr slice_expr; | 807 | AstNodeSliceExpr slice_expr; |
| 808 | AstNodeUse use; | 808 | AstNodeUse use; |
| 809 | AstNodeIfBoolExpr if_bool_expr; | 809 | AstNodeIfBoolExpr if_bool_expr; |
| 810 | AstNodeIfVarExpr if_var_expr; | ||
| 811 | AstNodeTryExpr try_expr; | 810 | AstNodeTryExpr try_expr; |
| 811 | AstNodeTestExpr test_expr; | ||
| 812 | AstNodeWhileExpr while_expr; | 812 | AstNodeWhileExpr while_expr; |
| 813 | AstNodeForExpr for_expr; | 813 | AstNodeForExpr for_expr; |
| 814 | AstNodeSwitchExpr switch_expr; | 814 | AstNodeSwitchExpr switch_expr; |
src/analyze.cpp+1-1| ... | @@ -2099,7 +2099,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { | ... | @@ -2099,7 +2099,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 2099 | case NodeTypeSymbol: | 2099 | case NodeTypeSymbol: |
| 2100 | case NodeTypePrefixOpExpr: | 2100 | case NodeTypePrefixOpExpr: |
| 2101 | case NodeTypeIfBoolExpr: | 2101 | case NodeTypeIfBoolExpr: |
| 2102 | case NodeTypeIfVarExpr: | ||
| 2103 | case NodeTypeWhileExpr: | 2102 | case NodeTypeWhileExpr: |
| 2104 | case NodeTypeForExpr: | 2103 | case NodeTypeForExpr: |
| 2105 | case NodeTypeSwitchExpr: | 2104 | case NodeTypeSwitchExpr: |
| ... | @@ -2119,6 +2118,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { | ... | @@ -2119,6 +2118,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 2119 | case NodeTypeErrorType: | 2118 | case NodeTypeErrorType: |
| 2120 | case NodeTypeVarLiteral: | 2119 | case NodeTypeVarLiteral: |
| 2121 | case NodeTypeTryExpr: | 2120 | case NodeTypeTryExpr: |
| 2121 | case NodeTypeTestExpr: | ||
| 2122 | case NodeTypeInlineExpr: | 2122 | case NodeTypeInlineExpr: |
| 2123 | zig_unreachable(); | 2123 | zig_unreachable(); |
| 2124 | } | 2124 | } |
src/ast_render.cpp+23-28| ... | @@ -192,8 +192,6 @@ static const char *node_type_str(NodeType node_type) { | ... | @@ -192,8 +192,6 @@ static const char *node_type_str(NodeType node_type) { |
| 192 | return "ThisLiteral"; | 192 | return "ThisLiteral"; |
| 193 | case NodeTypeIfBoolExpr: | 193 | case NodeTypeIfBoolExpr: |
| 194 | return "IfBoolExpr"; | 194 | return "IfBoolExpr"; |
| 195 | case NodeTypeIfVarExpr: | ||
| 196 | return "IfVarExpr"; | ||
| 197 | case NodeTypeWhileExpr: | 195 | case NodeTypeWhileExpr: |
| 198 | return "WhileExpr"; | 196 | return "WhileExpr"; |
| 199 | case NodeTypeForExpr: | 197 | case NodeTypeForExpr: |
| ... | @@ -236,6 +234,8 @@ static const char *node_type_str(NodeType node_type) { | ... | @@ -236,6 +234,8 @@ static const char *node_type_str(NodeType node_type) { |
| 236 | return "VarLiteral"; | 234 | return "VarLiteral"; |
| 237 | case NodeTypeTryExpr: | 235 | case NodeTypeTryExpr: |
| 238 | return "TryExpr"; | 236 | return "TryExpr"; |
| 237 | case NodeTypeTestExpr: | ||
| 238 | return "TestExpr"; | ||
| 239 | case NodeTypeInlineExpr: | 239 | case NodeTypeInlineExpr: |
| 240 | return "InlineExpr"; | 240 | return "InlineExpr"; |
| 241 | } | 241 | } |
| ... | @@ -760,38 +760,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { | ... | @@ -760,38 +760,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 760 | fprintf(ar->f, "null"); | 760 | fprintf(ar->f, "null"); |
| 761 | break; | 761 | break; |
| 762 | } | 762 | } |
| 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 | } | ||
| 784 | case NodeTypeTryExpr: | 763 | case NodeTypeTryExpr: |
| 785 | { | 764 | { |
| 786 | fprintf(ar->f, "try ("); | 765 | fprintf(ar->f, "try ("); |
| 766 | render_node_grouped(ar, node->data.try_expr.target_node); | ||
| 767 | fprintf(ar->f, ") "); | ||
| 787 | if (node->data.try_expr.var_symbol) { | 768 | 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); | ||
| 790 | const char *ptr_str = node->data.try_expr.var_is_ptr ? "*" : ""; | 769 | 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); | ||
| 792 | } | 772 | } |
| 793 | render_node_grouped(ar, node->data.try_expr.target_node); | ||
| 794 | fprintf(ar->f, ") "); | ||
| 795 | render_node_grouped(ar, node->data.try_expr.then_node); | 773 | render_node_grouped(ar, node->data.try_expr.then_node); |
| 796 | if (node->data.try_expr.else_node) { | 774 | if (node->data.try_expr.else_node) { |
| 797 | fprintf(ar->f, " else "); | 775 | fprintf(ar->f, " else "); |
| ... | @@ -802,6 +780,23 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { | ... | @@ -802,6 +780,23 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 802 | } | 780 | } |
| 803 | break; | 781 | break; |
| 804 | } | 782 | } |
| 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 | } | ||
| 805 | case NodeTypeSwitchExpr: | 800 | case NodeTypeSwitchExpr: |
| 806 | { | 801 | { |
| 807 | AstNodeSwitchExpr *switch_expr = &node->data.switch_expr; | 802 | 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 | ... | @@ -4941,14 +4941,14 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod |
| 4941 | return ir_build_asm(irb, scope, node, input_list, output_types, output_vars, return_count, is_volatile); | 4941 | return ir_build_asm(irb, scope, node, input_list, output_types, output_vars, return_count, is_volatile); |
| 4942 | } | 4942 | } |
| 4943 | 4943 | ||
| 4944 | static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 4944 | static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 4945 | assert(node->type == NodeTypeIfVarExpr); | 4945 | assert(node->type == NodeTypeTestExpr); |
| 4946 | 4946 | ||
| 4947 | AstNodeVariableDeclaration *var_decl = &node->data.if_var_expr.var_decl; | 4947 | Buf *var_symbol = node->data.test_expr.var_symbol; |
| 4948 | AstNode *expr_node = var_decl->expr; | 4948 | AstNode *expr_node = node->data.test_expr.target_node; |
| 4949 | AstNode *then_node = node->data.if_var_expr.then_block; | 4949 | AstNode *then_node = node->data.test_expr.then_node; |
| 4950 | AstNode *else_node = node->data.if_var_expr.else_node; | 4950 | AstNode *else_node = node->data.test_expr.else_node; |
| 4951 | bool var_is_ptr = node->data.if_var_expr.var_is_ptr; | 4951 | bool var_is_ptr = node->data.test_expr.var_is_ptr; |
| 4952 | 4952 | ||
| 4953 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR); | 4953 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR); |
| 4954 | if (maybe_val_ptr == irb->codegen->invalid_instruction) | 4954 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| ... | @@ -4970,21 +4970,23 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -4970,21 +4970,23 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 4970 | ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); | 4970 | ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); |
| 4971 | 4971 | ||
| 4972 | ir_set_cursor_at_end(irb, then_block); | 4972 | ir_set_cursor_at_end(irb, then_block); |
| 4973 | IrInstruction *var_type = nullptr; | 4973 | |
| 4974 | if (var_decl->type) { | 4974 | Scope *var_scope; |
| 4975 | var_type = ir_gen_node(irb, var_decl->type, scope); | 4975 | if (var_symbol) { |
| 4976 | if (var_type == irb->codegen->invalid_instruction) | 4976 | IrInstruction *var_type = nullptr; |
| 4977 | return irb->codegen->invalid_instruction; | 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; | ||
| 4978 | } | 4988 | } |
| 4979 | bool is_shadowable = false; | 4989 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); |
| 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); | ||
| 4988 | if (then_expr_result == irb->codegen->invalid_instruction) | 4990 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 4989 | return then_expr_result; | 4991 | return then_expr_result; |
| 4990 | IrBasicBlock *after_then_block = irb->current_basic_block; | 4992 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -5022,7 +5024,7 @@ static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5022,7 +5024,7 @@ static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5022 | AstNode *then_node = node->data.try_expr.then_node; | 5024 | AstNode *then_node = node->data.try_expr.then_node; |
| 5023 | AstNode *else_node = node->data.try_expr.else_node; | 5025 | AstNode *else_node = node->data.try_expr.else_node; |
| 5024 | bool var_is_ptr = node->data.try_expr.var_is_ptr; | 5026 | 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; |
| 5026 | Buf *var_symbol = node->data.try_expr.var_symbol; | 5028 | Buf *var_symbol = node->data.try_expr.var_symbol; |
| 5027 | Buf *err_symbol = node->data.try_expr.err_symbol; | 5029 | Buf *err_symbol = node->data.try_expr.err_symbol; |
| 5028 | 5030 | ||
| ... | @@ -5659,10 +5661,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -5659,10 +5661,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 5659 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); | 5661 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); |
| 5660 | case NodeTypeVarLiteral: | 5662 | case NodeTypeVarLiteral: |
| 5661 | return ir_lval_wrap(irb, scope, ir_gen_var_literal(irb, scope, node), lval); | 5663 | 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); | ||
| 5664 | case NodeTypeTryExpr: | 5664 | case NodeTypeTryExpr: |
| 5665 | return ir_lval_wrap(irb, scope, ir_gen_try_expr(irb, scope, node), lval); | 5665 | 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); | ||
| 5666 | case NodeTypeSwitchExpr: | 5668 | case NodeTypeSwitchExpr: |
| 5667 | return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval); | 5669 | return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval); |
| 5668 | case NodeTypeGoto: | 5670 | case NodeTypeGoto: |
src/parser.cpp+81-91| ... | @@ -640,7 +640,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b | ... | @@ -640,7 +640,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b |
| 640 | } | 640 | } |
| 641 | 641 | ||
| 642 | /* | 642 | /* |
| 643 | TryExpression(body) = "try" "(" option(("const" | "var") option("*") Symbol "=") Expression ")" body option("else" option("|" Symbol "|") body) | 643 | TryExpression(body) = "try" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" option("|" Symbol "|") BlockExpression(body)) |
| 644 | */ | 644 | */ |
| 645 | static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool mandatory) { | 645 | static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 646 | Token *try_token = &pc->tokens->at(*token_index); | 646 | 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 | ... | @@ -656,38 +656,25 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool m |
| 656 | AstNode *node = ast_create_node(pc, NodeTypeTryExpr, try_token); | 656 | AstNode *node = ast_create_node(pc, NodeTypeTryExpr, try_token); |
| 657 | 657 | ||
| 658 | ast_eat_token(pc, token_index, TokenIdLParen); | 658 | 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); | ||
| 659 | 661 | ||
| 660 | Token *var_token = &pc->tokens->at(*token_index); | 662 | Token *open_bar_tok = &pc->tokens->at(*token_index); |
| 661 | bool have_vars; | 663 | if (open_bar_tok->id == TokenIdBinOr) { |
| 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; | ||
| 668 | *token_index += 1; | 664 | *token_index += 1; |
| 669 | have_vars = true; | ||
| 670 | } else { | ||
| 671 | have_vars = false; | ||
| 672 | } | ||
| 673 | 665 | ||
| 674 | if (have_vars) { | 666 | Token *star_tok = &pc->tokens->at(*token_index); |
| 675 | Token *star_token = &pc->tokens->at(*token_index); | 667 | if (star_tok->id == TokenIdStar) { |
| 676 | if (star_token->id == TokenIdStar) { | ||
| 677 | node->data.try_expr.var_is_ptr = true; | ||
| 678 | *token_index += 1; | 668 | *token_index += 1; |
| 669 | node->data.try_expr.var_is_ptr = true; | ||
| 679 | } | 670 | } |
| 680 | 671 | ||
| 681 | Token *var_name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); | 672 | Token *var_name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); |
| 682 | node->data.try_expr.var_symbol = token_buf(var_name_tok); | 673 | node->data.try_expr.var_symbol = token_buf(var_name_tok); |
| 683 | 674 | ||
| 684 | ast_eat_token(pc, token_index, TokenIdEq); | 675 | ast_eat_token(pc, token_index, TokenIdBinOr); |
| 685 | } | 676 | } |
| 686 | 677 | ||
| 687 | node->data.try_expr.target_node = ast_parse_expression(pc, token_index, true); | ||
| 688 | |||
| 689 | ast_eat_token(pc, token_index, TokenIdRParen); | ||
| 690 | |||
| 691 | node->data.try_expr.then_node = ast_parse_block_or_expression(pc, token_index, true); | 678 | node->data.try_expr.then_node = ast_parse_block_or_expression(pc, token_index, true); |
| 692 | 679 | ||
| 693 | Token *else_token = &pc->tokens->at(*token_index); | 680 | 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 | ... | @@ -709,6 +696,53 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool m |
| 709 | return node; | 696 | return node; |
| 710 | } | 697 | } |
| 711 | 698 | ||
| 699 | /* | ||
| 700 | TestExpression(body) = "test" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body)) | ||
| 701 | */ | ||
| 702 | static 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 | |||
| 712 | /* | 746 | /* |
| 713 | PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl | 747 | PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl |
| 714 | KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "this" | "unreachable" | 748 | KeywordLiteral = "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 | ... | @@ -1405,9 +1439,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc, size_t *token_index, b |
| 1405 | } | 1439 | } |
| 1406 | 1440 | ||
| 1407 | /* | 1441 | /* |
| 1408 | IfExpression(body) = IfVarExpression(body) | IfBoolExpression(body) | 1442 | IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body)) |
| 1409 | IfBoolExpression(body) = "if" "(" Expression ")" body option("else" body) | ||
| 1410 | IfVarExpression(body) = "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" body Option("else" body) | ||
| 1411 | */ | 1443 | */ |
| 1412 | static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool mandatory) { | 1444 | static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 1413 | Token *if_token = &pc->tokens->at(*token_index); | 1445 | 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 | ... | @@ -1423,63 +1455,18 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma |
| 1423 | 1455 | ||
| 1424 | ast_eat_token(pc, token_index, TokenIdLParen); | 1456 | ast_eat_token(pc, token_index, TokenIdLParen); |
| 1425 | 1457 | ||
| 1426 | Token *token = &pc->tokens->at(*token_index); | 1458 | AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_token); |
| 1427 | if (token->id == TokenIdKeywordConst || token->id == TokenIdKeywordVar) { | 1459 | node->data.if_bool_expr.condition = ast_parse_expression(pc, token_index, true); |
| 1428 | AstNode *node = ast_create_node(pc, NodeTypeIfVarExpr, if_token); | 1460 | ast_eat_token(pc, token_index, TokenIdRParen); |
| 1429 | node->data.if_var_expr.var_decl.is_const = (token->id == TokenIdKeywordConst); | 1461 | node->data.if_bool_expr.then_block = ast_parse_block_or_expression(pc, token_index, true); |
| 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 | } | ||
| 1480 | 1462 | ||
| 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); | ||
| 1482 | } | 1467 | } |
| 1468 | |||
| 1469 | return node; | ||
| 1483 | } | 1470 | } |
| 1484 | 1471 | ||
| 1485 | /* | 1472 | /* |
| ... | @@ -1862,7 +1849,7 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, size_t *token_index, boo | ... | @@ -1862,7 +1849,7 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, size_t *token_index, boo |
| 1862 | } | 1849 | } |
| 1863 | 1850 | ||
| 1864 | /* | 1851 | /* |
| 1865 | BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) | 1852 | BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) |
| 1866 | */ | 1853 | */ |
| 1867 | static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool mandatory) { | 1854 | static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 1868 | Token *token = &pc->tokens->at(*token_index); | 1855 | Token *token = &pc->tokens->at(*token_index); |
| ... | @@ -1895,6 +1882,10 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool | ... | @@ -1895,6 +1882,10 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool |
| 1895 | if (try_node) | 1882 | if (try_node) |
| 1896 | return try_node; | 1883 | return try_node; |
| 1897 | 1884 | ||
| 1885 | AstNode *test_node = ast_parse_test_expr(pc, token_index, false); | ||
| 1886 | if (test_node) | ||
| 1887 | return test_node; | ||
| 1888 | |||
| 1898 | if (mandatory) | 1889 | if (mandatory) |
| 1899 | ast_invalid_token_error(pc, token); | 1890 | ast_invalid_token_error(pc, token); |
| 1900 | 1891 | ||
| ... | @@ -2079,14 +2070,14 @@ static bool statement_terminates_without_semicolon(AstNode *node) { | ... | @@ -2079,14 +2070,14 @@ static bool statement_terminates_without_semicolon(AstNode *node) { |
| 2079 | if (node->data.if_bool_expr.else_node) | 2070 | if (node->data.if_bool_expr.else_node) |
| 2080 | return statement_terminates_without_semicolon(node->data.if_bool_expr.else_node); | 2071 | return statement_terminates_without_semicolon(node->data.if_bool_expr.else_node); |
| 2081 | return node->data.if_bool_expr.then_block->type == NodeTypeBlock; | 2072 | 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; | ||
| 2086 | case NodeTypeTryExpr: | 2073 | case NodeTypeTryExpr: |
| 2087 | if (node->data.try_expr.else_node) | 2074 | if (node->data.try_expr.else_node) |
| 2088 | return statement_terminates_without_semicolon(node->data.try_expr.else_node); | 2075 | return statement_terminates_without_semicolon(node->data.try_expr.else_node); |
| 2089 | return node->data.try_expr.then_node->type == NodeTypeBlock; | 2076 | 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; | ||
| 2090 | case NodeTypeWhileExpr: | 2081 | case NodeTypeWhileExpr: |
| 2091 | return node->data.while_expr.body->type == NodeTypeBlock; | 2082 | return node->data.while_expr.body->type == NodeTypeBlock; |
| 2092 | case NodeTypeForExpr: | 2083 | case NodeTypeForExpr: |
| ... | @@ -2667,17 +2658,16 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont | ... | @@ -2667,17 +2658,16 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2667 | visit_field(&node->data.if_bool_expr.then_block, visit, context); | 2658 | visit_field(&node->data.if_bool_expr.then_block, visit, context); |
| 2668 | visit_field(&node->data.if_bool_expr.else_node, visit, context); | 2659 | visit_field(&node->data.if_bool_expr.else_node, visit, context); |
| 2669 | break; | 2660 | 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; | ||
| 2676 | case NodeTypeTryExpr: | 2661 | case NodeTypeTryExpr: |
| 2677 | visit_field(&node->data.try_expr.target_node, visit, context); | 2662 | visit_field(&node->data.try_expr.target_node, visit, context); |
| 2678 | visit_field(&node->data.try_expr.then_node, visit, context); | 2663 | visit_field(&node->data.try_expr.then_node, visit, context); |
| 2679 | visit_field(&node->data.try_expr.else_node, visit, context); | 2664 | visit_field(&node->data.try_expr.else_node, visit, context); |
| 2680 | break; | 2665 | 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; | ||
| 2681 | case NodeTypeWhileExpr: | 2671 | case NodeTypeWhileExpr: |
| 2682 | visit_field(&node->data.while_expr.condition, visit, context); | 2672 | visit_field(&node->data.while_expr.condition, visit, context); |
| 2683 | visit_field(&node->data.while_expr.body, visit, context); | 2673 | visit_field(&node->data.while_expr.body, visit, context); |
std/buf_map.zig+1-1| ... | @@ -28,7 +28,7 @@ pub const BufMap = struct { | ... | @@ -28,7 +28,7 @@ pub const BufMap = struct { |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | pub fn set(self: &BufMap, key: []const u8, value: []const u8) -> %void { | 30 | 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| { |
| 32 | const value_copy = %return self.copy(value); | 32 | const value_copy = %return self.copy(value); |
| 33 | %defer self.free(value_copy); | 33 | %defer self.free(value_copy); |
| 34 | %return self.hash_map.put(key, value_copy); | 34 | %return self.hash_map.put(key, value_copy); |
std/build.zig+12-12| ... | @@ -309,7 +309,7 @@ pub const Builder = struct { | ... | @@ -309,7 +309,7 @@ pub const Builder = struct { |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | fn processNixOSEnvVars(self: &Builder) { | 311 | 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| { |
| 313 | var it = mem.split(nix_cflags_compile, ' '); | 313 | var it = mem.split(nix_cflags_compile, ' '); |
| 314 | while (true) { | 314 | while (true) { |
| 315 | const word = it.next() ?? break; | 315 | const word = it.next() ?? break; |
| ... | @@ -325,7 +325,7 @@ pub const Builder = struct { | ... | @@ -325,7 +325,7 @@ pub const Builder = struct { |
| 325 | } | 325 | } |
| 326 | } | 326 | } |
| 327 | } | 327 | } |
| 328 | if (const nix_ldflags ?= os.getEnv("NIX_LDFLAGS")) { | 328 | test (os.getEnv("NIX_LDFLAGS")) |nix_ldflags| { |
| 329 | var it = mem.split(nix_ldflags, ' '); | 329 | var it = mem.split(nix_ldflags, ' '); |
| 330 | while (true) { | 330 | while (true) { |
| 331 | const word = it.next() ?? break; | 331 | const word = it.next() ?? break; |
| ... | @@ -353,7 +353,7 @@ pub const Builder = struct { | ... | @@ -353,7 +353,7 @@ pub const Builder = struct { |
| 353 | .type_id = type_id, | 353 | .type_id = type_id, |
| 354 | .description = description, | 354 | .description = description, |
| 355 | }; | 355 | }; |
| 356 | if (const _ ?= %%self.available_options_map.put(name, available_option)) { | 356 | test (%%self.available_options_map.put(name, available_option)) { |
| 357 | debug.panic("Option '{}' declared twice", name); | 357 | debug.panic("Option '{}' declared twice", name); |
| 358 | } | 358 | } |
| 359 | %%self.available_options_list.append(available_option); | 359 | %%self.available_options_list.append(available_option); |
| ... | @@ -410,11 +410,11 @@ pub const Builder = struct { | ... | @@ -410,11 +410,11 @@ pub const Builder = struct { |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) -> bool { | 412 | 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 { |
| 414 | .name = name, | 414 | .name = name, |
| 415 | .value = UserValue.Scalar { value }, | 415 | .value = UserValue.Scalar { value }, |
| 416 | .used = false, | 416 | .used = false, |
| 417 | })) { | 417 | })) |*prev_value| { |
| 418 | switch (prev_value.value) { | 418 | switch (prev_value.value) { |
| 419 | UserValue.Scalar => |s| { | 419 | UserValue.Scalar => |s| { |
| 420 | var list = List([]const u8).init(self.allocator); | 420 | var list = List([]const u8).init(self.allocator); |
| ... | @@ -444,11 +444,11 @@ pub const Builder = struct { | ... | @@ -444,11 +444,11 @@ pub const Builder = struct { |
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | pub fn addUserInputFlag(self: &Builder, name: []const u8) -> bool { | 446 | 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 { |
| 448 | .name = name, | 448 | .name = name, |
| 449 | .value = UserValue.Flag, | 449 | .value = UserValue.Flag, |
| 450 | .used = false, | 450 | .used = false, |
| 451 | })) { | 451 | })) |*prev_value| { |
| 452 | switch (prev_value.value) { | 452 | switch (prev_value.value) { |
| 453 | UserValue.Scalar => |s| { | 453 | UserValue.Scalar => |s| { |
| 454 | %%io.stderr.printf("Flag '-D{}' conflicts with option '-D{}={}'.\n", name, name, s); | 454 | %%io.stderr.printf("Flag '-D{}' conflicts with option '-D{}={}'.\n", name, name, s); |
| ... | @@ -766,7 +766,7 @@ pub const LibOrExeStep = struct { | ... | @@ -766,7 +766,7 @@ pub const LibOrExeStep = struct { |
| 766 | %%zig_args.append("--release"); | 766 | %%zig_args.append("--release"); |
| 767 | } | 767 | } |
| 768 | 768 | ||
| 769 | if (const output_path ?= self.output_path) { | 769 | test (self.output_path) |output_path| { |
| 770 | %%zig_args.append("--output"); | 770 | %%zig_args.append("--output"); |
| 771 | %%zig_args.append(builder.pathFromRoot(output_path)); | 771 | %%zig_args.append(builder.pathFromRoot(output_path)); |
| 772 | } | 772 | } |
| ... | @@ -912,7 +912,7 @@ pub const ObjectStep = struct { | ... | @@ -912,7 +912,7 @@ pub const ObjectStep = struct { |
| 912 | %%zig_args.append("--release"); | 912 | %%zig_args.append("--release"); |
| 913 | } | 913 | } |
| 914 | 914 | ||
| 915 | if (const output_path ?= self.output_path) { | 915 | test (self.output_path) |output_path| { |
| 916 | %%zig_args.append("--output"); | 916 | %%zig_args.append("--output"); |
| 917 | %%zig_args.append(builder.pathFromRoot(output_path)); | 917 | %%zig_args.append(builder.pathFromRoot(output_path)); |
| 918 | } | 918 | } |
| ... | @@ -1017,7 +1017,7 @@ pub const AsmStep = struct { | ... | @@ -1017,7 +1017,7 @@ pub const AsmStep = struct { |
| 1017 | %%zig_args.append("--release"); | 1017 | %%zig_args.append("--release"); |
| 1018 | } | 1018 | } |
| 1019 | 1019 | ||
| 1020 | if (const output_path ?= self.output_path) { | 1020 | test (self.output_path) |output_path| { |
| 1021 | %%zig_args.append("--output"); | 1021 | %%zig_args.append("--output"); |
| 1022 | %%zig_args.append(builder.pathFromRoot(output_path)); | 1022 | %%zig_args.append(builder.pathFromRoot(output_path)); |
| 1023 | } | 1023 | } |
| ... | @@ -1194,7 +1194,7 @@ pub const LinkStep = struct { | ... | @@ -1194,7 +1194,7 @@ pub const LinkStep = struct { |
| 1194 | %%zig_args.append("--static"); | 1194 | %%zig_args.append("--static"); |
| 1195 | } | 1195 | } |
| 1196 | 1196 | ||
| 1197 | if (const output_path ?= self.output_path) { | 1197 | test (self.output_path) |output_path| { |
| 1198 | %%zig_args.append("--output"); | 1198 | %%zig_args.append("--output"); |
| 1199 | %%zig_args.append(builder.pathFromRoot(output_path)); | 1199 | %%zig_args.append(builder.pathFromRoot(output_path)); |
| 1200 | } | 1200 | } |
| ... | @@ -1316,7 +1316,7 @@ pub const TestStep = struct { | ... | @@ -1316,7 +1316,7 @@ pub const TestStep = struct { |
| 1316 | %%zig_args.append("--release"); | 1316 | %%zig_args.append("--release"); |
| 1317 | } | 1317 | } |
| 1318 | 1318 | ||
| 1319 | if (const filter ?= self.filter) { | 1319 | test (self.filter) |filter| { |
| 1320 | %%zig_args.append("--test-filter"); | 1320 | %%zig_args.append("--test-filter"); |
| 1321 | %%zig_args.append(filter); | 1321 | %%zig_args.append(filter); |
| 1322 | } | 1322 | } |
std/hash_map.zig+1-1| ... | @@ -246,7 +246,7 @@ test "basicHashMapTest" { | ... | @@ -246,7 +246,7 @@ test "basicHashMapTest" { |
| 246 | assert((??map.get(2)).value == 22); | 246 | assert((??map.get(2)).value == 22); |
| 247 | _ = map.remove(2); | 247 | _ = map.remove(2); |
| 248 | assert(map.remove(2) == null); | 248 | 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); |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | fn hash_i32(x: i32) -> u32 { | 252 | fn hash_i32(x: i32) -> u32 { |
std/os/child_process.zig+7-6| ... | @@ -56,9 +56,9 @@ pub const ChildProcess = struct { | ... | @@ -56,9 +56,9 @@ pub const ChildProcess = struct { |
| 56 | errno.EINVAL, errno.ECHILD => unreachable, | 56 | errno.EINVAL, errno.ECHILD => unreachable, |
| 57 | errno.EINTR => continue, | 57 | errno.EINTR => continue, |
| 58 | else => { | 58 | else => { |
| 59 | if (const *stdin ?= self.stdin) { stdin.close(); } | 59 | test (self.stdin) |*stdin| { stdin.close(); } |
| 60 | if (const *stdout ?= self.stdin) { stdout.close(); } | 60 | test (self.stdout) |*stdout| { stdout.close(); } |
| 61 | if (const *stderr ?= self.stdin) { stderr.close(); } | 61 | test (self.stderr) |*stderr| { stderr.close(); } |
| 62 | return error.Unexpected; | 62 | return error.Unexpected; |
| 63 | }, | 63 | }, |
| 64 | } | 64 | } |
| ... | @@ -66,9 +66,10 @@ pub const ChildProcess = struct { | ... | @@ -66,9 +66,10 @@ pub const ChildProcess = struct { |
| 66 | break; | 66 | break; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | if (const *stdin ?= self.stdin) { stdin.close(); } | 69 | // TODO oops! |
| 70 | if (const *stdout ?= self.stdin) { stdout.close(); } | 70 | test (self.stdin) |*stdin| { stdin.close(); } |
| 71 | if (const *stderr ?= self.stdin) { stderr.close(); } | 71 | test (self.stdin) |*stdout| { stdout.close(); } |
| 72 | test (self.stdin) |*stderr| { stderr.close(); } | ||
| 72 | 73 | ||
| 73 | // Write @maxValue(ErrInt) to the write end of the err_pipe. This is after | 74 | // Write @maxValue(ErrInt) to the write end of the err_pipe. This is after |
| 74 | // waitpid, so this write is guaranteed to be after the child | 75 | // 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: ?& | ... | @@ -162,7 +162,7 @@ pub fn posixOpen(file_path: []const u8, flags: usize, perm: usize, allocator: ?& |
| 162 | 162 | ||
| 163 | if (file_path.len < stack_buf.len) { | 163 | if (file_path.len < stack_buf.len) { |
| 164 | path0 = stack_buf[0...file_path.len + 1]; | 164 | path0 = stack_buf[0...file_path.len + 1]; |
| 165 | } else if (const a ?= allocator) { | 165 | } else test (allocator) |a| { |
| 166 | path0 = %return a.alloc(u8, file_path.len + 1); | 166 | path0 = %return a.alloc(u8, file_path.len + 1); |
| 167 | need_free = true; | 167 | need_free = true; |
| 168 | } else { | 168 | } else { |
| ... | @@ -230,7 +230,7 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con | ... | @@ -230,7 +230,7 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con |
| 230 | mem.set(?&u8, argv_buf, null); | 230 | mem.set(?&u8, argv_buf, null); |
| 231 | defer { | 231 | defer { |
| 232 | for (argv_buf) |arg| { | 232 | 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; |
| 234 | allocator.free(arg_buf); | 234 | allocator.free(arg_buf); |
| 235 | } | 235 | } |
| 236 | allocator.free(argv_buf); | 236 | allocator.free(argv_buf); |
| ... | @@ -257,7 +257,7 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con | ... | @@ -257,7 +257,7 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con |
| 257 | mem.set(?&u8, envp_buf, null); | 257 | mem.set(?&u8, envp_buf, null); |
| 258 | defer { | 258 | defer { |
| 259 | for (envp_buf) |env| { | 259 | 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; |
| 261 | allocator.free(env_buf); | 261 | allocator.free(env_buf); |
| 262 | } | 262 | } |
| 263 | allocator.free(envp_buf); | 263 | allocator.free(envp_buf); |
std/special/build_runner.zig+1-1| ... | @@ -53,7 +53,7 @@ pub fn main() -> %void { | ... | @@ -53,7 +53,7 @@ pub fn main() -> %void { |
| 53 | %%io.stderr.printf("Expected option name after '-D'\n\n"); | 53 | %%io.stderr.printf("Expected option name after '-D'\n\n"); |
| 54 | return usage(&builder, false, &io.stderr); | 54 | return usage(&builder, false, &io.stderr); |
| 55 | } | 55 | } |
| 56 | if (const name_end ?= mem.indexOfScalar(u8, option_contents, '=')) { | 56 | test (mem.indexOfScalar(u8, option_contents, '=')) |name_end| { |
| 57 | const option_name = option_contents[0...name_end]; | 57 | const option_name = option_contents[0...name_end]; |
| 58 | const option_value = option_contents[name_end + 1...]; | 58 | const option_value = option_contents[name_end + 1...]; |
| 59 | if (builder.addUserInputOption(option_name, option_value)) | 59 | 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 { | ... | @@ -34,7 +34,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 34 | // 0 X | 34 | // 0 X |
| 35 | // --- | 35 | // --- |
| 36 | // 0 X | 36 | // 0 X |
| 37 | if (const rem ?= maybe_rem) { | 37 | test (maybe_rem) |rem| { |
| 38 | *rem = n[low] % d[low]; | 38 | *rem = n[low] % d[low]; |
| 39 | } | 39 | } |
| 40 | return n[low] / d[low]; | 40 | return n[low] / d[low]; |
| ... | @@ -42,7 +42,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -42,7 +42,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 42 | // 0 X | 42 | // 0 X |
| 43 | // --- | 43 | // --- |
| 44 | // K X | 44 | // K X |
| 45 | if (const rem ?= maybe_rem) { | 45 | test (maybe_rem) |rem| { |
| 46 | *rem = n[low]; | 46 | *rem = n[low]; |
| 47 | } | 47 | } |
| 48 | return 0; | 48 | return 0; |
| ... | @@ -53,7 +53,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -53,7 +53,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 53 | // K X | 53 | // K X |
| 54 | // --- | 54 | // --- |
| 55 | // 0 0 | 55 | // 0 0 |
| 56 | if (var rem ?= maybe_rem) { | 56 | test (maybe_rem) |rem| { |
| 57 | *rem = n[high] % d[low]; | 57 | *rem = n[high] % d[low]; |
| 58 | } | 58 | } |
| 59 | return n[high] / d[low]; | 59 | return n[high] / d[low]; |
| ... | @@ -63,7 +63,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -63,7 +63,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 63 | // K 0 | 63 | // K 0 |
| 64 | // --- | 64 | // --- |
| 65 | // K 0 | 65 | // K 0 |
| 66 | if (var rem ?= maybe_rem) { | 66 | test (maybe_rem) |rem| { |
| 67 | r[high] = n[high] % d[high]; | 67 | r[high] = n[high] % d[high]; |
| 68 | r[low] = 0; | 68 | r[low] = 0; |
| 69 | *rem = *@ptrCast(&du_int, &r[0]); | 69 | *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 { | ... | @@ -75,7 +75,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 75 | // K 0 | 75 | // K 0 |
| 76 | // if d is a power of 2 | 76 | // if d is a power of 2 |
| 77 | if ((d[high] & (d[high] - 1)) == 0) { | 77 | if ((d[high] & (d[high] - 1)) == 0) { |
| 78 | if (var rem ?= maybe_rem) { | 78 | test (maybe_rem) |rem| { |
| 79 | r[low] = n[low]; | 79 | r[low] = n[low]; |
| 80 | r[high] = n[high] & (d[high] - 1); | 80 | r[high] = n[high] & (d[high] - 1); |
| 81 | *rem = *@ptrCast(&du_int, &r[0]); | 81 | *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 { | ... | @@ -88,7 +88,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 88 | sr = @clz(su_int(d[high])) - @clz(su_int(n[high])); | 88 | sr = @clz(su_int(d[high])) - @clz(su_int(n[high])); |
| 89 | // 0 <= sr <= n_uword_bits - 2 or sr large | 89 | // 0 <= sr <= n_uword_bits - 2 or sr large |
| 90 | if (sr > n_uword_bits - 2) { | 90 | if (sr > n_uword_bits - 2) { |
| 91 | if (var rem ?= maybe_rem) { | 91 | test (maybe_rem) |rem| { |
| 92 | *rem = *@ptrCast(&du_int, &n[0]); | 92 | *rem = *@ptrCast(&du_int, &n[0]); |
| 93 | } | 93 | } |
| 94 | return 0; | 94 | return 0; |
| ... | @@ -109,7 +109,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -109,7 +109,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 109 | // 0 K | 109 | // 0 K |
| 110 | // if d is a power of 2 | 110 | // if d is a power of 2 |
| 111 | if ((d[low] & (d[low] - 1)) == 0) { | 111 | if ((d[low] & (d[low] - 1)) == 0) { |
| 112 | if (var rem ?= maybe_rem) { | 112 | test (maybe_rem) |rem| { |
| 113 | *rem = n[low] & (d[low] - 1); | 113 | *rem = n[low] & (d[low] - 1); |
| 114 | } | 114 | } |
| 115 | if (d[low] == 1) { | 115 | if (d[low] == 1) { |
| ... | @@ -153,7 +153,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -153,7 +153,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 153 | sr = @clz(su_int(d[high])) - @clz(su_int(n[high])); | 153 | sr = @clz(su_int(d[high])) - @clz(su_int(n[high])); |
| 154 | // 0 <= sr <= n_uword_bits - 1 or sr large | 154 | // 0 <= sr <= n_uword_bits - 1 or sr large |
| 155 | if (sr > n_uword_bits - 1) { | 155 | if (sr > n_uword_bits - 1) { |
| 156 | if (var rem ?= maybe_rem) { | 156 | test (maybe_rem) |rem| { |
| 157 | *rem = *@ptrCast(&du_int, &n[0]); | 157 | *rem = *@ptrCast(&du_int, &n[0]); |
| 158 | } | 158 | } |
| 159 | return 0; | 159 | return 0; |
| ... | @@ -198,7 +198,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -198,7 +198,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 198 | sr -= 1; | 198 | sr -= 1; |
| 199 | } | 199 | } |
| 200 | *@ptrCast(&du_int, &q[0]) = (*@ptrCast(&du_int, &q[0]) << 1) | u64(carry); | 200 | *@ptrCast(&du_int, &q[0]) = (*@ptrCast(&du_int, &q[0]) << 1) | u64(carry); |
| 201 | if (var rem ?= maybe_rem) { | 201 | test (maybe_rem) |rem| { |
| 202 | *rem = *@ptrCast(&du_int, &r[0]); | 202 | *rem = *@ptrCast(&du_int, &r[0]); |
| 203 | } | 203 | } |
| 204 | return *@ptrCast(&du_int, &q[0]); | 204 | return *@ptrCast(&du_int, &q[0]); |
test/cases/misc.zig-10| ... | @@ -128,16 +128,6 @@ fn testTruncate(x: u32) -> u8 { | ... | @@ -128,16 +128,6 @@ fn testTruncate(x: u32) -> u8 { |
| 128 | @truncate(u8, x) | 128 | @truncate(u8, x) |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | test "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 | |||
| 141 | fn first4KeysOfHomeRow() -> []const u8 { | 131 | fn first4KeysOfHomeRow() -> []const u8 { |
| 142 | "aoeu" | 132 | "aoeu" |
| 143 | } | 133 | } |
test/cases/null.zig+9-7| ... | @@ -3,7 +3,7 @@ const assert = @import("std").debug.assert; | ... | @@ -3,7 +3,7 @@ const assert = @import("std").debug.assert; |
| 3 | test "nullableType" { | 3 | test "nullableType" { |
| 4 | const x : ?bool = @generatedCode(true); | 4 | const x : ?bool = @generatedCode(true); |
| 5 | 5 | ||
| 6 | if (const y ?= x) { | 6 | test (x) |y| { |
| 7 | if (y) { | 7 | if (y) { |
| 8 | // OK | 8 | // OK |
| 9 | } else { | 9 | } else { |
| ... | @@ -26,16 +26,17 @@ test "nullableType" { | ... | @@ -26,16 +26,17 @@ test "nullableType" { |
| 26 | assert(num == 13); | 26 | assert(num == 13); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | test "assignToIfVarPtr" { | 29 | test "test maybe object and get a pointer to the inner value" { |
| 30 | var maybe_bool: ?bool = true; | 30 | var maybe_bool: ?bool = true; |
| 31 | 31 | ||
| 32 | if (const *b ?= maybe_bool) { | 32 | test (maybe_bool) |*b| { |
| 33 | *b = false; | 33 | *b = false; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | assert(??maybe_bool == false); | 36 | assert(??maybe_bool == false); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | |||
| 39 | test "rhsMaybeUnwrapReturn" { | 40 | test "rhsMaybeUnwrapReturn" { |
| 40 | const x: ?bool = @generatedCode(true); | 41 | const x: ?bool = @generatedCode(true); |
| 41 | const y = x ?? return; | 42 | const y = x ?? return; |
| ... | @@ -49,7 +50,8 @@ test "maybe return" { | ... | @@ -49,7 +50,8 @@ test "maybe return" { |
| 49 | 50 | ||
| 50 | fn maybeReturnImpl() { | 51 | fn maybeReturnImpl() { |
| 51 | assert(??foo(1235)); | 52 | assert(??foo(1235)); |
| 52 | assert(if (const _ ?= foo(null)) false else true); | 53 | test (foo(null)) |
| 54 | unreachable; | ||
| 53 | assert(!??foo(1234)); | 55 | assert(!??foo(1234)); |
| 54 | } | 56 | } |
| 55 | 57 | ||
| ... | @@ -64,10 +66,10 @@ test "ifVarMaybePointer" { | ... | @@ -64,10 +66,10 @@ test "ifVarMaybePointer" { |
| 64 | } | 66 | } |
| 65 | fn shouldBeAPlus1(p: &const Particle) -> u64 { | 67 | fn shouldBeAPlus1(p: &const Particle) -> u64 { |
| 66 | var maybe_particle: ?Particle = *p; | 68 | var maybe_particle: ?Particle = *p; |
| 67 | if (const *particle ?= maybe_particle) { | 69 | test (maybe_particle) |*particle| { |
| 68 | particle.a += 1; | 70 | particle.a += 1; |
| 69 | } | 71 | } |
| 70 | if (const particle ?= maybe_particle) { | 72 | test (maybe_particle) |particle| { |
| 71 | return particle.a; | 73 | return particle.a; |
| 72 | } | 74 | } |
| 73 | return 0; | 75 | return 0; |
| ... | @@ -114,7 +116,7 @@ fn nullableVoidImpl() { | ... | @@ -114,7 +116,7 @@ fn nullableVoidImpl() { |
| 114 | } | 116 | } |
| 115 | 117 | ||
| 116 | fn bar(x: ?void) -> ?void { | 118 | fn bar(x: ?void) -> ?void { |
| 117 | if (const _ ?= x) { | 119 | test (x) { |
| 118 | return {}; | 120 | return {}; |
| 119 | } else { | 121 | } else { |
| 120 | return null; | 122 | return null; |
test/cases/try.zig+2-2| ... | @@ -7,7 +7,7 @@ test "tryOnErrorUnion" { | ... | @@ -7,7 +7,7 @@ test "tryOnErrorUnion" { |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | fn tryOnErrorUnionImpl() { | 9 | fn tryOnErrorUnionImpl() { |
| 10 | const x = try (const val = returnsTen()) { | 10 | const x = try (returnsTen()) |val| { |
| 11 | val + 1 | 11 | val + 1 |
| 12 | } else |err| switch (err) { | 12 | } else |err| switch (err) { |
| 13 | error.ItBroke, error.NoMem => 1, | 13 | error.ItBroke, error.NoMem => 1, |
| ... | @@ -51,7 +51,7 @@ fn failIfTrue(ok: bool) -> %void { | ... | @@ -51,7 +51,7 @@ fn failIfTrue(ok: bool) -> %void { |
| 51 | //fn tryThenNotExecutedWithAssignment() { | 51 | //fn tryThenNotExecutedWithAssignment() { |
| 52 | // @setFnTest(this); | 52 | // @setFnTest(this); |
| 53 | // | 53 | // |
| 54 | // try (_ = failIfTrue(true)) { | 54 | // try (failIfTrue(true)) { |
| 55 | // unreachable; | 55 | // unreachable; |
| 56 | // } else |err| { | 56 | // } else |err| { |
| 57 | // assert(err == error.ItBroke); | 57 | // assert(err == error.ItBroke); |
test/compile_errors.zig+14-68| ... | @@ -118,92 +118,38 @@ pub fn addCases(cases: &tests.CompileErrorContext) { | ... | @@ -118,92 +118,38 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 118 | \\} | 118 | \\} |
| 119 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); | 119 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 120 | 120 | ||
| 121 | cases.add("implicit semicolon - if(var) statement", | 121 | cases.add("implicit semicolon - try 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", | ||
| 176 | \\export fn entry() { | 122 | \\export fn entry() { |
| 177 | \\ if(_=foo()) {} else if(_=foo()) {} else {} | 123 | \\ try (foo()) {} |
| 178 | \\ var good = {}; | 124 | \\ var good = {}; |
| 179 | \\ if(_=foo()) ({}) else if(_=foo()) ({}) else ({}) | 125 | \\ try (foo()) ({}) |
| 180 | \\ var bad = {}; | 126 | \\ var bad = {}; |
| 181 | \\} | 127 | \\} |
| 182 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); | 128 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 183 | 129 | ||
| 184 | cases.add("implicit semicolon - if(var)-else-if(var)-else expression", | 130 | cases.add("implicit semicolon - try expression", |
| 185 | \\export fn entry() { | 131 | \\export fn entry() { |
| 186 | \\ _ = if(_=foo()) {} else if(_=foo()) {} else {}; | 132 | \\ _ = try (foo()) {}; |
| 187 | \\ var good = {}; | 133 | \\ var good = {}; |
| 188 | \\ _ = if(_=foo()) {} else if(_=foo()) {} else {} | 134 | \\ _ = try (foo()) {} |
| 189 | \\ var bad = {}; | 135 | \\ var bad = {}; |
| 190 | \\} | 136 | \\} |
| 191 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); | 137 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 192 | 138 | ||
| 193 | cases.add("implicit semicolon - try statement", | 139 | cases.add("implicit semicolon - test statement", |
| 194 | \\export fn entry() { | 140 | \\export fn entry() { |
| 195 | \\ try (_ = foo()) {} | 141 | \\ test (foo()) {} |
| 196 | \\ var good = {}; | 142 | \\ var good = {}; |
| 197 | \\ try (_ = foo()) ({}) | 143 | \\ test (foo()) ({}) |
| 198 | \\ var bad = {}; | 144 | \\ var bad = {}; |
| 199 | \\} | 145 | \\} |
| 200 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); | 146 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 201 | 147 | ||
| 202 | cases.add("implicit semicolon - try expression", | 148 | cases.add("implicit semicolon - test expression", |
| 203 | \\export fn entry() { | 149 | \\export fn entry() { |
| 204 | \\ _ = try (_ = foo()) {}; | 150 | \\ _ = test (foo()) {}; |
| 205 | \\ var good = {}; | 151 | \\ var good = {}; |
| 206 | \\ _ = try (_ = foo()) {} | 152 | \\ _ = test (foo()) {} |
| 207 | \\ var bad = {}; | 153 | \\ var bad = {}; |
| 208 | \\} | 154 | \\} |
| 209 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); | 155 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| ... | @@ -554,9 +500,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) { | ... | @@ -554,9 +500,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 554 | 500 | ||
| 555 | cases.add("invalid maybe type", | 501 | cases.add("invalid maybe type", |
| 556 | \\export fn f() { | 502 | \\export fn f() { |
| 557 | \\ if (const x ?= true) { } | 503 | \\ test (true) |x| { } |
| 558 | \\} | 504 | \\} |
| 559 | , ".tmp_source.zig:2:20: error: expected nullable type, found 'bool'"); | 505 | , ".tmp_source.zig:2:11: error: expected nullable type, found 'bool'"); |
| 560 | 506 | ||
| 561 | cases.add("cast unreachable", | 507 | cases.add("cast unreachable", |
| 562 | \\fn f() -> i32 { | 508 | \\fn f() -> i32 { |
test/tests.zig+7-7| ... | @@ -350,7 +350,7 @@ pub const CompareOutputContext = struct { | ... | @@ -350,7 +350,7 @@ pub const CompareOutputContext = struct { |
| 350 | Special.Asm => { | 350 | Special.Asm => { |
| 351 | const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o"); | 351 | const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o"); |
| 352 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "assemble-and-link {}", case.name); | 352 | 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| { |
| 354 | if (mem.indexOf(u8, annotated_case_name, filter) == null) | 354 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 355 | return; | 355 | return; |
| 356 | } | 356 | } |
| ... | @@ -379,7 +379,7 @@ pub const CompareOutputContext = struct { | ... | @@ -379,7 +379,7 @@ pub const CompareOutputContext = struct { |
| 379 | for ([]bool{false, true}) |release| { | 379 | for ([]bool{false, true}) |release| { |
| 380 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "{} {} ({})", | 380 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "{} {} ({})", |
| 381 | "compare-output", case.name, if (release) "release" else "debug"); | 381 | "compare-output", case.name, if (release) "release" else "debug"); |
| 382 | if (const filter ?= self.test_filter) { | 382 | test (self.test_filter) |filter| { |
| 383 | if (mem.indexOf(u8, annotated_case_name, filter) == null) | 383 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 384 | continue; | 384 | continue; |
| 385 | } | 385 | } |
| ... | @@ -407,7 +407,7 @@ pub const CompareOutputContext = struct { | ... | @@ -407,7 +407,7 @@ pub const CompareOutputContext = struct { |
| 407 | Special.DebugSafety => { | 407 | Special.DebugSafety => { |
| 408 | const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o"); | 408 | const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o"); |
| 409 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "debug-safety {}", case.name); | 409 | 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| { |
| 411 | if (mem.indexOf(u8, annotated_case_name, filter) == null) | 411 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 412 | return; | 412 | return; |
| 413 | } | 413 | } |
| ... | @@ -626,7 +626,7 @@ pub const CompileErrorContext = struct { | ... | @@ -626,7 +626,7 @@ pub const CompileErrorContext = struct { |
| 626 | for ([]bool{false, true}) |release| { | 626 | for ([]bool{false, true}) |release| { |
| 627 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "compile-error {} ({})", | 627 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "compile-error {} ({})", |
| 628 | case.name, if (release) "release" else "debug"); | 628 | case.name, if (release) "release" else "debug"); |
| 629 | if (const filter ?= self.test_filter) { | 629 | test (self.test_filter) |filter| { |
| 630 | if (mem.indexOf(u8, annotated_case_name, filter) == null) | 630 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 631 | continue; | 631 | continue; |
| 632 | } | 632 | } |
| ... | @@ -661,7 +661,7 @@ pub const BuildExamplesContext = struct { | ... | @@ -661,7 +661,7 @@ pub const BuildExamplesContext = struct { |
| 661 | const b = self.b; | 661 | const b = self.b; |
| 662 | 662 | ||
| 663 | const annotated_case_name = b.fmt("build {}", build_file); | 663 | const annotated_case_name = b.fmt("build {}", build_file); |
| 664 | if (const filter ?= self.test_filter) { | 664 | test (self.test_filter) |filter| { |
| 665 | if (mem.indexOf(u8, annotated_case_name, filter) == null) | 665 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 666 | return; | 666 | return; |
| 667 | } | 667 | } |
| ... | @@ -692,7 +692,7 @@ pub const BuildExamplesContext = struct { | ... | @@ -692,7 +692,7 @@ pub const BuildExamplesContext = struct { |
| 692 | for ([]bool{false, true}) |release| { | 692 | for ([]bool{false, true}) |release| { |
| 693 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "build {} ({})", | 693 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "build {} ({})", |
| 694 | root_src, if (release) "release" else "debug"); | 694 | root_src, if (release) "release" else "debug"); |
| 695 | if (const filter ?= self.test_filter) { | 695 | test (self.test_filter) |filter| { |
| 696 | if (mem.indexOf(u8, annotated_case_name, filter) == null) | 696 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 697 | continue; | 697 | continue; |
| 698 | } | 698 | } |
| ... | @@ -880,7 +880,7 @@ pub const ParseHContext = struct { | ... | @@ -880,7 +880,7 @@ pub const ParseHContext = struct { |
| 880 | const b = self.b; | 880 | const b = self.b; |
| 881 | 881 | ||
| 882 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "parseh {}", case.name); | 882 | 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| { |
| 884 | if (mem.indexOf(u8, annotated_case_name, filter) == null) | 884 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 885 | return; | 885 | return; |
| 886 | } | 886 | } |