authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 03:07:16-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 03:07:16-04:00
log4210f1f6a0f55fb7c7b287ac691582752340f79d
tree5627170646c8e6abab85756a1ad318834d0aca12
parentd52ef95f77478582e5c479cc2bd0a4ecb5591933

remove bool to int syntax. add @boolToInt

add missing docs See #1061

9 files changed, 158 insertions(+), 43 deletions(-)

doc/langref.html.in+70-20
......@@ -4560,6 +4560,19 @@ comptime {
45604560 </p>
45614561 {#see_also|Alignment#}
45624562 {#header_close#}
4563
4564 {#header_open|@boolToInt#}
4565 <pre><code class="zig">@boolToInt(value: bool) u1</code></pre>
4566 <p>
4567 Converts <code>true</code> to <code>u1(1)</code> and <code>false</code> to
4568 <code>u1(0)</code>.
4569 </p>
4570 <p>
4571 If the value is known at compile-time, the return type is <code>comptime_int</code>
4572 instead of <code>u1</code>.
4573 </p>
4574 {#header_close#}
4575
45634576 {#header_open|@cDefine#}
45644577 <pre><code class="zig">@cDefine(comptime name: []u8, value)</code></pre>
45654578 <p>
......@@ -4834,21 +4847,6 @@ test "main" {
48344847 Creates a symbol in the output object file.
48354848 </p>
48364849 {#header_close#}
4837 {#header_open|@tagName#}
4838 <pre><code class="zig">@tagName(value: var) []const u8</code></pre>
4839 <p>
4840 Converts an enum value or union value to a slice of bytes representing the name.
4841 </p>
4842 {#header_close#}
4843 {#header_open|@TagType#}
4844 <pre><code class="zig">@TagType(T: type) type</code></pre>
4845 <p>
4846 For an enum, returns the integer type that is used to store the enumeration value.
4847 </p>
4848 <p>
4849 For a union, returns the enum type that is used to store the tag value.
4850 </p>
4851 {#header_close#}
48524850 {#header_open|@errorName#}
48534851 <pre><code class="zig">@errorName(err: error) []u8</code></pre>
48544852 <p>
......@@ -4883,6 +4881,12 @@ test "main" {
48834881 </p>
48844882 {#see_also|Compile Variables#}
48854883 {#header_close#}
4884
4885 {#header_open|@field#}
4886 <pre><code class="zig">@field(lhs: var, comptime field_name: []const u8) (field)</code></pre>
4887 <p>Preforms field access equivalent to <code>lhs.-&gtfield_name-&lt</code>.</p>
4888 {#header_close#}
4889
48864890 {#header_open|@fieldParentPtr#}
48874891 <pre><code class="zig">@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8,
48884892 field_ptr: *T) *ParentType</code></pre>
......@@ -4890,6 +4894,23 @@ test "main" {
48904894 Given a pointer to a field, returns the base pointer of a struct.
48914895 </p>
48924896 {#header_close#}
4897
4898 {#header_open|@floatCast#}
4899 <pre><code class="zig">@floatCast(comptime DestType: type, value: var) DestType</code></pre>
4900 <p>
4901 Convert from one float type to another. This cast is safe, but may cause the
4902 numeric value to lose precision.
4903 </p>
4904 {#header_close#}
4905
4906 {#header_open|@floatToInt#}
4907 <pre><code class="zig">@floatToInt(comptime DestType: type, float: var) DestType</code></pre>
4908 <p>
4909 Converts the integer part of a floating point number to the destination type.
4910 To convert the other way, use {#link|@intToFloat#}. This cast is always safe.
4911 </p>
4912 {#header_close#}
4913
48934914 {#header_open|@frameAddress#}
48944915 <pre><code class="zig">@frameAddress()</code></pre>
48954916 <p>
......@@ -4944,12 +4965,30 @@ fn add(a: i32, b: i32) i32 { return a + b; }
49444965 </p>
49454966 {#see_also|@noInlineCall#}
49464967 {#header_close#}
4968
4969 {#header_open|@intCast#}
4970 <pre><code class="zig">@intCast(comptime DestType: type, int: var) DestType</code></pre>
4971 <p>
4972 Converts an integer to another integer while keeping the same numerical value.
4973 Attempting to convert a number which is out of range of the destination type results in
4974 {#link|Undefined Behavior#}.
4975 </p>
4976 {#header_close#}
4977
4978 {#header_open|@intToFloat#}
4979 <pre><code class="zig">@intToFloat(comptime DestType: type, int: var) DestType</code></pre>
4980 <p>
4981 Converts an integer to the closest floating point representation. To convert the other way, use {#link|@floatToInt#}. This cast is always safe.
4982 </p>
4983 {#header_close#}
4984
49474985 {#header_open|@intToPtr#}
49484986 <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) DestType</code></pre>
49494987 <p>
49504988 Converts an integer to a pointer. To convert the other way, use {#link|@ptrToInt#}.
49514989 </p>
49524990 {#header_close#}
4991
49534992 {#header_open|@IntType#}
49544993 <pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u8) type</code></pre>
49554994 <p>
......@@ -4987,10 +5026,6 @@ fn add(a: i32, b: i32) i32 { return a + b; }
49875026 It does not include functions, variables, or constants.
49885027 </p>
49895028 {#header_close#}
4990 {#header_open|@field#}
4991 <pre><code class="zig">@field(lhs: var, comptime field_name: []const u8) (field)</code></pre>
4992 <p>Preforms field access equivalent to <code>lhs.-&gtfield_name-&lt</code>.</p>
4993 {#header_close#}
49945029 {#header_open|@memberType#}
49955030 <pre><code class="zig">@memberType(comptime T: type, comptime index: usize) type</code></pre>
49965031 <p>Returns the field type of a struct or union.</p>
......@@ -5370,6 +5405,21 @@ pub const FloatMode = enum {
53705405 If no overflow or underflow occurs, returns <code>false</code>.
53715406 </p>
53725407 {#header_close#}
5408 {#header_open|@tagName#}
5409 <pre><code class="zig">@tagName(value: var) []const u8</code></pre>
5410 <p>
5411 Converts an enum value or union value to a slice of bytes representing the name.
5412 </p>
5413 {#header_close#}
5414 {#header_open|@TagType#}
5415 <pre><code class="zig">@TagType(T: type) type</code></pre>
5416 <p>
5417 For an enum, returns the integer type that is used to store the enumeration value.
5418 </p>
5419 <p>
5420 For a union, returns the enum type that is used to store the tag value.
5421 </p>
5422 {#header_close#}
53735423 {#header_open|@truncate#}
53745424 <pre><code class="zig">@truncate(comptime T: type, integer) T</code></pre>
53755425 <p>
......@@ -6665,7 +6715,7 @@ hljs.registerLanguage("zig", function(t) {
66656715 a = t.IR + "\\s*\\(",
66666716 c = {
66676717 keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong resume cancel await async orelse",
6668 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall",
6718 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast intCast floatCast intToFloat floatToInt boolToInt bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall",
66696719 literal: "true false null undefined"
66706720 },
66716721 n = [e, t.CLCM, t.CBCM, s, r];
src/all_types.hpp+8
......@@ -1361,6 +1361,7 @@ enum BuiltinFnId {
13611361 BuiltinFnIdFloatCast,
13621362 BuiltinFnIdIntToFloat,
13631363 BuiltinFnIdFloatToInt,
1364 BuiltinFnIdBoolToInt,
13641365 BuiltinFnIdIntType,
13651366 BuiltinFnIdSetCold,
13661367 BuiltinFnIdSetRuntimeSafety,
......@@ -2048,6 +2049,7 @@ enum IrInstructionId {
20482049 IrInstructionIdFloatCast,
20492050 IrInstructionIdIntToFloat,
20502051 IrInstructionIdFloatToInt,
2052 IrInstructionIdBoolToInt,
20512053 IrInstructionIdIntType,
20522054 IrInstructionIdBoolNot,
20532055 IrInstructionIdMemset,
......@@ -2668,6 +2670,12 @@ struct IrInstructionFloatToInt {
26682670 IrInstruction *target;
26692671};
26702672
2673struct IrInstructionBoolToInt {
2674 IrInstruction base;
2675
2676 IrInstruction *target;
2677};
2678
26712679struct IrInstructionIntType {
26722680 IrInstruction base;
26732681
src/codegen.cpp+2
......@@ -4726,6 +4726,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
47264726 case IrInstructionIdFloatCast:
47274727 case IrInstructionIdIntToFloat:
47284728 case IrInstructionIdFloatToInt:
4729 case IrInstructionIdBoolToInt:
47294730 zig_unreachable();
47304731
47314732 case IrInstructionIdReturn:
......@@ -6318,6 +6319,7 @@ static void define_builtin_fns(CodeGen *g) {
63186319 create_builtin_fn(g, BuiltinFnIdFloatCast, "floatCast", 2);
63196320 create_builtin_fn(g, BuiltinFnIdIntToFloat, "intToFloat", 2);
63206321 create_builtin_fn(g, BuiltinFnIdFloatToInt, "floatToInt", 2);
6322 create_builtin_fn(g, BuiltinFnIdBoolToInt, "boolToInt", 1);
63216323 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
63226324 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
63236325 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
src/ir.cpp+53-7
......@@ -476,6 +476,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) {
476476 return IrInstructionIdFloatToInt;
477477}
478478
479static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) {
480 return IrInstructionIdBoolToInt;
481}
482
479483static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) {
480484 return IrInstructionIdIntType;
481485}
......@@ -1959,6 +1963,15 @@ static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNod
19591963 return &instruction->base;
19601964}
19611965
1966static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) {
1967 IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node);
1968 instruction->target = target;
1969
1970 ir_ref_instruction(target, irb->current_basic_block);
1971
1972 return &instruction->base;
1973}
1974
19621975static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) {
19631976 IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node);
19641977 instruction->is_signed = is_signed;
......@@ -4071,6 +4084,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40714084 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value);
40724085 return ir_lval_wrap(irb, scope, result, lval);
40734086 }
4087 case BuiltinFnIdBoolToInt:
4088 {
4089 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4090 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4091 if (arg0_value == irb->codegen->invalid_instruction)
4092 return arg0_value;
4093
4094 IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value);
4095 return ir_lval_wrap(irb, scope, result, lval);
4096 }
40744097 case BuiltinFnIdIntType:
40754098 {
40764099 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -10055,13 +10078,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1005510078 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
1005610079 }
1005710080
10058 // explicit cast from bool to int
10059 if (wanted_type->id == TypeTableEntryIdInt &&
10060 actual_type->id == TypeTableEntryIdBool)
10061 {
10062 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBoolToInt, false);
10063 }
10064
1006510081 // explicit widening conversion
1006610082 if (wanted_type->id == TypeTableEntryIdInt &&
1006710083 actual_type->id == TypeTableEntryIdInt &&
......@@ -17605,6 +17621,33 @@ static TypeTableEntry *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrIns
1760517621 return dest_type;
1760617622}
1760717623
17624static TypeTableEntry *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) {
17625 IrInstruction *target = instruction->target->other;
17626 if (type_is_invalid(target->value.type))
17627 return ira->codegen->builtin_types.entry_invalid;
17628
17629 if (target->value.type->id != TypeTableEntryIdBool) {
17630 ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'",
17631 buf_ptr(&target->value.type->name)));
17632 return ira->codegen->builtin_types.entry_invalid;
17633 }
17634
17635 if (instr_is_comptime(target)) {
17636 bool is_true;
17637 if (!ir_resolve_bool(ira, target, &is_true))
17638 return ira->codegen->builtin_types.entry_invalid;
17639
17640 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
17641 bigint_init_unsigned(&out_val->data.x_bigint, is_true ? 1 : 0);
17642 return ira->codegen->builtin_types.entry_num_lit_int;
17643 }
17644
17645 TypeTableEntry *u1_type = get_int_type(ira->codegen, false, 1);
17646 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false);
17647 ir_link_new_instruction(result, &instruction->base);
17648 return u1_type;
17649}
17650
1760817651static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) {
1760917652 IrInstruction *is_signed_value = instruction->is_signed->other;
1761017653 bool is_signed;
......@@ -20143,6 +20186,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
2014320186 return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction);
2014420187 case IrInstructionIdFloatToInt:
2014520188 return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction);
20189 case IrInstructionIdBoolToInt:
20190 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction);
2014620191 case IrInstructionIdIntType:
2014720192 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction);
2014820193 case IrInstructionIdBoolNot:
......@@ -20490,6 +20535,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2049020535 case IrInstructionIdFloatCast:
2049120536 case IrInstructionIdIntToFloat:
2049220537 case IrInstructionIdFloatToInt:
20538 case IrInstructionIdBoolToInt:
2049320539 return false;
2049420540
2049520541 case IrInstructionIdAsm:
src/ir_print.cpp+9
......@@ -680,6 +680,12 @@ static void ir_print_float_to_int(IrPrint *irp, IrInstructionFloatToInt *instruc
680680 fprintf(irp->f, ")");
681681}
682682
683static void ir_print_bool_to_int(IrPrint *irp, IrInstructionBoolToInt *instruction) {
684 fprintf(irp->f, "@boolToInt(");
685 ir_print_other_instruction(irp, instruction->target);
686 fprintf(irp->f, ")");
687}
688
683689static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) {
684690 fprintf(irp->f, "@IntType(");
685691 ir_print_other_instruction(irp, instruction->is_signed);
......@@ -1461,6 +1467,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
14611467 case IrInstructionIdFloatToInt:
14621468 ir_print_float_to_int(irp, (IrInstructionFloatToInt *)instruction);
14631469 break;
1470 case IrInstructionIdBoolToInt:
1471 ir_print_bool_to_int(irp, (IrInstructionBoolToInt *)instruction);
1472 break;
14641473 case IrInstructionIdIntType:
14651474 ir_print_int_type(irp, (IrInstructionIntType *)instruction);
14661475 break;
std/fmt/errol/index.zig+2-2
......@@ -329,7 +329,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
329329 var mi: i32 = mismatch10(l64, h64);
330330 var x: u64 = 1;
331331 {
332 var i = i32(lf == hf);
332 var i: i32 = @boolToInt(lf == hf);
333333 while (i < mi) : (i += 1) {
334334 x *= 10;
335335 }
......@@ -341,7 +341,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
341341 var buf_index = u64toa(m64, buffer) - 1;
342342
343343 if (mi != 0) {
344 buffer[buf_index - 1] += u8(buffer[buf_index] >= '5');
344 buffer[buf_index - 1] += @boolToInt(buffer[buf_index] >= '5');
345345 } else {
346346 buf_index += 1;
347347 }
std/math/big/int.zig+9-9
......@@ -117,7 +117,7 @@ pub const Int = struct {
117117
118118 fn bitcount(self: Int) usize {
119119 const u_bit_count = (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1]));
120 return usize(!self.positive) + u_bit_count;
120 return usize(@boolToInt(!self.positive)) + u_bit_count;
121121 }
122122
123123 pub fn sizeInBase(self: Int, base: usize) usize {
......@@ -499,13 +499,13 @@ pub const Int = struct {
499499
500500 while (i < b.len) : (i += 1) {
501501 var c: Limb = 0;
502 c += Limb(@addWithOverflow(Limb, a[i], b[i], &r[i]));
503 c += Limb(@addWithOverflow(Limb, r[i], carry, &r[i]));
502 c += @boolToInt(@addWithOverflow(Limb, a[i], b[i], &r[i]));
503 c += @boolToInt(@addWithOverflow(Limb, r[i], carry, &r[i]));
504504 carry = c;
505505 }
506506
507507 while (i < a.len) : (i += 1) {
508 carry = Limb(@addWithOverflow(Limb, a[i], carry, &r[i]));
508 carry = @boolToInt(@addWithOverflow(Limb, a[i], carry, &r[i]));
509509 }
510510
511511 r[i] = carry;
......@@ -577,13 +577,13 @@ pub const Int = struct {
577577
578578 while (i < b.len) : (i += 1) {
579579 var c: Limb = 0;
580 c += Limb(@subWithOverflow(Limb, a[i], b[i], &r[i]));
581 c += Limb(@subWithOverflow(Limb, r[i], borrow, &r[i]));
580 c += @boolToInt(@subWithOverflow(Limb, a[i], b[i], &r[i]));
581 c += @boolToInt(@subWithOverflow(Limb, r[i], borrow, &r[i]));
582582 borrow = c;
583583 }
584584
585585 while (i < a.len) : (i += 1) {
586 borrow = Limb(@subWithOverflow(Limb, a[i], borrow, &r[i]));
586 borrow = @boolToInt(@subWithOverflow(Limb, a[i], borrow, &r[i]));
587587 }
588588
589589 debug.assert(borrow == 0);
......@@ -624,7 +624,7 @@ pub const Int = struct {
624624 var r1: Limb = undefined;
625625
626626 // r1 = a + *carry
627 const c1 = Limb(@addWithOverflow(Limb, a, carry.*, &r1));
627 const c1: Limb = @boolToInt(@addWithOverflow(Limb, a, carry.*, &r1));
628628
629629 // r2 = b * c
630630 //
......@@ -639,7 +639,7 @@ pub const Int = struct {
639639 const c2 = @truncate(Limb, bc >> Limb.bit_count);
640640
641641 // r1 = r1 + r2
642 const c3 = Limb(@addWithOverflow(Limb, r1, r2, &r1));
642 const c3: Limb = @boolToInt(@addWithOverflow(Limb, r1, r2, &r1));
643643
644644 // This never overflows, c1, c3 are either 0 or 1 and if both are 1 then
645645 // c2 is at least <= @maxValue(Limb) - 2.
std/special/compiler_rt/comparetf2.zig+1-1
......@@ -91,5 +91,5 @@ pub extern fn __unordtf2(a: f128, b: f128) c_int {
9191
9292 const aAbs = @bitCast(rep_t, a) & absMask;
9393 const bAbs = @bitCast(rep_t, b) & absMask;
94 return c_int(aAbs > infRep or bAbs > infRep);
94 return @boolToInt(aAbs > infRep or bAbs > infRep);
9595}
test/cases/bool.zig+4-4
......@@ -8,14 +8,14 @@ test "bool literals" {
88test "cast bool to int" {
99 const t = true;
1010 const f = false;
11 assert(i32(t) == i32(1));
12 assert(i32(f) == i32(0));
11 assert(@boolToInt(t) == u32(1));
12 assert(@boolToInt(f) == u32(0));
1313 nonConstCastBoolToInt(t, f);
1414}
1515
1616fn nonConstCastBoolToInt(t: bool, f: bool) void {
17 assert(i32(t) == i32(1));
18 assert(i32(f) == i32(0));
17 assert(@boolToInt(t) == u32(1));
18 assert(@boolToInt(f) == u32(0));
1919}
2020
2121test "bool cmp" {