Commit 25e74cb385

Andrew Kelley <superjoe30@gmail.com>
2016-02-04 20:59:06
ability to explicitly cast bool to int
1 parent 32642ac
src/all_types.hpp
@@ -346,6 +346,7 @@ enum CastOp {
     CastOpErrToInt,
     CastOpIntToFloat,
     CastOpFloatToInt,
+    CastOpBoolToInt,
 };
 
 struct AstNodeFnCallExpr {
src/analyze.cpp
@@ -3610,6 +3610,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
             bignum_cast_to_int(&const_val->data.x_bignum, &other_val->data.x_bignum);
             const_val->ok = true;
             break;
+        case CastOpBoolToInt:
+            bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_bool ? 1 : 0);
+            const_val->ok = true;
+            break;
     }
 }
 
@@ -3643,6 +3647,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
         return wanted_type;
     }
 
+    // explicit cast from bool to int
+    if (wanted_type->id == TypeTableEntryIdInt &&
+        actual_type->id == TypeTableEntryIdBool)
+    {
+        node->data.fn_call_expr.cast_op = CastOpBoolToInt;
+        eval_const_expr_implicit_cast(g, node, expr_node);
+        return wanted_type;
+    }
+
     // explicit cast from pointer to isize or usize
     if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) &&
         actual_type->id == TypeTableEntryIdPointer)
src/codegen.cpp
@@ -530,6 +530,11 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
                 return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, "");
             }
 
+        case CastOpBoolToInt:
+            assert(wanted_type->id == TypeTableEntryIdInt);
+            assert(actual_type->id == TypeTableEntryIdBool);
+            return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
+
     }
     zig_unreachable();
 }
test/self_hosted.zig
@@ -82,3 +82,18 @@ fn continue_in_for_loop() {
     }
     if (sum != 6) unreachable{}
 }
+
+
+#attribute("test")
+fn cast_bool_to_int() {
+    const t = true;
+    const f = false;
+    if (i32(t) != i32(1)) unreachable{}
+    if (i32(f) != i32(0)) unreachable{}
+    non_const_cast_bool_to_int(t, f);
+}
+
+fn non_const_cast_bool_to_int(t: bool, f: bool) {
+    if (i32(t) != i32(1)) unreachable{}
+    if (i32(f) != i32(0)) unreachable{}
+}