commit 25e74cb385dc353bcf0e56b35a6f1c7c8b13267e (tree)
parent 32642ac9cb00b59fef97c1888e0424b0eb4db784
Author: Andrew Kelley <superjoe30@gmail.com>
Date: Thu, 4 Feb 2016 12:59:06 -0700
ability to explicitly cast bool to int
Diffstat:
4 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
@@ -346,6 +346,7 @@ enum CastOp {
CastOpErrToInt,
CastOpIntToFloat,
CastOpFloatToInt,
+ CastOpBoolToInt,
};
struct AstNodeFnCallExpr {
diff --git a/src/analyze.cpp b/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)
diff --git a/src/codegen.cpp b/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();
}
diff --git a/test/self_hosted.zig b/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{}
+}