authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-04 12:59:06-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-04 12:59:06-07:00
log25e74cb385dc353bcf0e56b35a6f1c7c8b13267e
tree09c18cff4b8e63c040db933fe9d321c2e0b09eca
parent32642ac9cb00b59fef97c1888e0424b0eb4db784

ability to explicitly cast bool to int


4 files changed, 34 insertions(+), 0 deletions(-)

src/all_types.hpp+1
...@@ -346,6 +346,7 @@ enum CastOp {...@@ -346,6 +346,7 @@ enum CastOp {
346 CastOpErrToInt,346 CastOpErrToInt,
347 CastOpIntToFloat,347 CastOpIntToFloat,
348 CastOpFloatToInt,348 CastOpFloatToInt,
349 CastOpBoolToInt,
349};350};
350351
351struct AstNodeFnCallExpr {352struct AstNodeFnCallExpr {
src/analyze.cpp+13
...@@ -3610,6 +3610,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex...@@ -3610,6 +3610,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
3610 bignum_cast_to_int(&const_val->data.x_bignum, &other_val->data.x_bignum);3610 bignum_cast_to_int(&const_val->data.x_bignum, &other_val->data.x_bignum);
3611 const_val->ok = true;3611 const_val->ok = true;
3612 break;3612 break;
3613 case CastOpBoolToInt:
3614 bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_bool ? 1 : 0);
3615 const_val->ok = true;
3616 break;
3613 }3617 }
3614}3618}
36153619
...@@ -3643,6 +3647,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -3643,6 +3647,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
3643 return wanted_type;3647 return wanted_type;
3644 }3648 }
36453649
3650 // explicit cast from bool to int
3651 if (wanted_type->id == TypeTableEntryIdInt &&
3652 actual_type->id == TypeTableEntryIdBool)
3653 {
3654 node->data.fn_call_expr.cast_op = CastOpBoolToInt;
3655 eval_const_expr_implicit_cast(g, node, expr_node);
3656 return wanted_type;
3657 }
3658
3646 // explicit cast from pointer to isize or usize3659 // explicit cast from pointer to isize or usize
3647 if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) &&3660 if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) &&
3648 actual_type->id == TypeTableEntryIdPointer)3661 actual_type->id == TypeTableEntryIdPointer)
src/codegen.cpp+5
...@@ -530,6 +530,11 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -530,6 +530,11 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
530 return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, "");530 return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, "");
531 }531 }
532532
533 case CastOpBoolToInt:
534 assert(wanted_type->id == TypeTableEntryIdInt);
535 assert(actual_type->id == TypeTableEntryIdBool);
536 return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
537
533 }538 }
534 zig_unreachable();539 zig_unreachable();
535}540}
test/self_hosted.zig+15
...@@ -82,3 +82,18 @@ fn continue_in_for_loop() {...@@ -82,3 +82,18 @@ fn continue_in_for_loop() {
82 }82 }
83 if (sum != 6) unreachable{}83 if (sum != 6) unreachable{}
84}84}
85
86
87#attribute("test")
88fn cast_bool_to_int() {
89 const t = true;
90 const f = false;
91 if (i32(t) != i32(1)) unreachable{}
92 if (i32(f) != i32(0)) unreachable{}
93 non_const_cast_bool_to_int(t, f);
94}
95
96fn non_const_cast_bool_to_int(t: bool, f: bool) {
97 if (i32(t) != i32(1)) unreachable{}
98 if (i32(f) != i32(0)) unreachable{}
99}