| author | |
| committer | |
| log | 7151d72532ebc11fe72fda91d156082bd8c1761b |
| tree | 5627170646c8e6abab85756a1ad318834d0aca12 |
| parent | d52ef95f77478582e5c479cc2bd0a4ecb5591933 |
| parent | 4210f1f6a0f55fb7c7b287ac691582752340f79d |
| signature |
remove bool to int syntax. add @boolToInt9 files changed, 158 insertions(+), 43 deletions(-)
doc/langref.html.in+70-20| ... | @@ -4560,6 +4560,19 @@ comptime { | ... | @@ -4560,6 +4560,19 @@ comptime { |
| 4560 | </p> | 4560 | </p> |
| 4561 | {#see_also|Alignment#} | 4561 | {#see_also|Alignment#} |
| 4562 | {#header_close#} | 4562 | {#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 | |||
| 4563 | {#header_open|@cDefine#} | 4576 | {#header_open|@cDefine#} |
| 4564 | <pre><code class="zig">@cDefine(comptime name: []u8, value)</code></pre> | 4577 | <pre><code class="zig">@cDefine(comptime name: []u8, value)</code></pre> |
| 4565 | <p> | 4578 | <p> |
| ... | @@ -4834,21 +4847,6 @@ test "main" { | ... | @@ -4834,21 +4847,6 @@ test "main" { |
| 4834 | Creates a symbol in the output object file. | 4847 | Creates a symbol in the output object file. |
| 4835 | </p> | 4848 | </p> |
| 4836 | {#header_close#} | 4849 | {#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#} | ||
| 4852 | {#header_open|@errorName#} | 4850 | {#header_open|@errorName#} |
| 4853 | <pre><code class="zig">@errorName(err: error) []u8</code></pre> | 4851 | <pre><code class="zig">@errorName(err: error) []u8</code></pre> |
| 4854 | <p> | 4852 | <p> |
| ... | @@ -4883,6 +4881,12 @@ test "main" { | ... | @@ -4883,6 +4881,12 @@ test "main" { |
| 4883 | </p> | 4881 | </p> |
| 4884 | {#see_also|Compile Variables#} | 4882 | {#see_also|Compile Variables#} |
| 4885 | {#header_close#} | 4883 | {#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 | |||
| 4886 | {#header_open|@fieldParentPtr#} | 4890 | {#header_open|@fieldParentPtr#} |
| 4887 | <pre><code class="zig">@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, | 4891 | <pre><code class="zig">@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, |
| 4888 | field_ptr: *T) *ParentType</code></pre> | 4892 | field_ptr: *T) *ParentType</code></pre> |
| ... | @@ -4890,6 +4894,23 @@ test "main" { | ... | @@ -4890,6 +4894,23 @@ test "main" { |
| 4890 | Given a pointer to a field, returns the base pointer of a struct. | 4894 | Given a pointer to a field, returns the base pointer of a struct. |
| 4891 | </p> | 4895 | </p> |
| 4892 | {#header_close#} | 4896 | {#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 | |||
| 4893 | {#header_open|@frameAddress#} | 4914 | {#header_open|@frameAddress#} |
| 4894 | <pre><code class="zig">@frameAddress()</code></pre> | 4915 | <pre><code class="zig">@frameAddress()</code></pre> |
| 4895 | <p> | 4916 | <p> |
| ... | @@ -4944,12 +4965,30 @@ fn add(a: i32, b: i32) i32 { return a + b; } | ... | @@ -4944,12 +4965,30 @@ fn add(a: i32, b: i32) i32 { return a + b; } |
| 4944 | </p> | 4965 | </p> |
| 4945 | {#see_also|@noInlineCall#} | 4966 | {#see_also|@noInlineCall#} |
| 4946 | {#header_close#} | 4967 | {#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 | |||
| 4947 | {#header_open|@intToPtr#} | 4985 | {#header_open|@intToPtr#} |
| 4948 | <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) DestType</code></pre> | 4986 | <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) DestType</code></pre> |
| 4949 | <p> | 4987 | <p> |
| 4950 | Converts an integer to a pointer. To convert the other way, use {#link|@ptrToInt#}. | 4988 | Converts an integer to a pointer. To convert the other way, use {#link|@ptrToInt#}. |
| 4951 | </p> | 4989 | </p> |
| 4952 | {#header_close#} | 4990 | {#header_close#} |
| 4991 | |||
| 4953 | {#header_open|@IntType#} | 4992 | {#header_open|@IntType#} |
| 4954 | <pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u8) type</code></pre> | 4993 | <pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u8) type</code></pre> |
| 4955 | <p> | 4994 | <p> |
| ... | @@ -4987,10 +5026,6 @@ fn add(a: i32, b: i32) i32 { return a + b; } | ... | @@ -4987,10 +5026,6 @@ fn add(a: i32, b: i32) i32 { return a + b; } |
| 4987 | It does not include functions, variables, or constants. | 5026 | It does not include functions, variables, or constants. |
| 4988 | </p> | 5027 | </p> |
| 4989 | {#header_close#} | 5028 | {#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#} | ||
| 4994 | {#header_open|@memberType#} | 5029 | {#header_open|@memberType#} |
| 4995 | <pre><code class="zig">@memberType(comptime T: type, comptime index: usize) type</code></pre> | 5030 | <pre><code class="zig">@memberType(comptime T: type, comptime index: usize) type</code></pre> |
| 4996 | <p>Returns the field type of a struct or union.</p> | 5031 | <p>Returns the field type of a struct or union.</p> |
| ... | @@ -5370,6 +5405,21 @@ pub const FloatMode = enum { | ... | @@ -5370,6 +5405,21 @@ pub const FloatMode = enum { |
| 5370 | If no overflow or underflow occurs, returns <code>false</code>. | 5405 | If no overflow or underflow occurs, returns <code>false</code>. |
| 5371 | </p> | 5406 | </p> |
| 5372 | {#header_close#} | 5407 | {#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#} | ||
| 5373 | {#header_open|@truncate#} | 5423 | {#header_open|@truncate#} |
| 5374 | <pre><code class="zig">@truncate(comptime T: type, integer) T</code></pre> | 5424 | <pre><code class="zig">@truncate(comptime T: type, integer) T</code></pre> |
| 5375 | <p> | 5425 | <p> |
| ... | @@ -6665,7 +6715,7 @@ hljs.registerLanguage("zig", function(t) { | ... | @@ -6665,7 +6715,7 @@ hljs.registerLanguage("zig", function(t) { |
| 6665 | a = t.IR + "\\s*\\(", | 6715 | a = t.IR + "\\s*\\(", |
| 6666 | c = { | 6716 | c = { |
| 6667 | 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", | 6717 | 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", |
| 6669 | literal: "true false null undefined" | 6719 | literal: "true false null undefined" |
| 6670 | }, | 6720 | }, |
| 6671 | n = [e, t.CLCM, t.CBCM, s, r]; | 6721 | n = [e, t.CLCM, t.CBCM, s, r]; |
src/all_types.hpp+8| ... | @@ -1361,6 +1361,7 @@ enum BuiltinFnId { | ... | @@ -1361,6 +1361,7 @@ enum BuiltinFnId { |
| 1361 | BuiltinFnIdFloatCast, | 1361 | BuiltinFnIdFloatCast, |
| 1362 | BuiltinFnIdIntToFloat, | 1362 | BuiltinFnIdIntToFloat, |
| 1363 | BuiltinFnIdFloatToInt, | 1363 | BuiltinFnIdFloatToInt, |
| 1364 | BuiltinFnIdBoolToInt, | ||
| 1364 | BuiltinFnIdIntType, | 1365 | BuiltinFnIdIntType, |
| 1365 | BuiltinFnIdSetCold, | 1366 | BuiltinFnIdSetCold, |
| 1366 | BuiltinFnIdSetRuntimeSafety, | 1367 | BuiltinFnIdSetRuntimeSafety, |
| ... | @@ -2048,6 +2049,7 @@ enum IrInstructionId { | ... | @@ -2048,6 +2049,7 @@ enum IrInstructionId { |
| 2048 | IrInstructionIdFloatCast, | 2049 | IrInstructionIdFloatCast, |
| 2049 | IrInstructionIdIntToFloat, | 2050 | IrInstructionIdIntToFloat, |
| 2050 | IrInstructionIdFloatToInt, | 2051 | IrInstructionIdFloatToInt, |
| 2052 | IrInstructionIdBoolToInt, | ||
| 2051 | IrInstructionIdIntType, | 2053 | IrInstructionIdIntType, |
| 2052 | IrInstructionIdBoolNot, | 2054 | IrInstructionIdBoolNot, |
| 2053 | IrInstructionIdMemset, | 2055 | IrInstructionIdMemset, |
| ... | @@ -2668,6 +2670,12 @@ struct IrInstructionFloatToInt { | ... | @@ -2668,6 +2670,12 @@ struct IrInstructionFloatToInt { |
| 2668 | IrInstruction *target; | 2670 | IrInstruction *target; |
| 2669 | }; | 2671 | }; |
| 2670 | 2672 | ||
| 2673 | struct IrInstructionBoolToInt { | ||
| 2674 | IrInstruction base; | ||
| 2675 | |||
| 2676 | IrInstruction *target; | ||
| 2677 | }; | ||
| 2678 | |||
| 2671 | struct IrInstructionIntType { | 2679 | struct IrInstructionIntType { |
| 2672 | IrInstruction base; | 2680 | IrInstruction base; |
| 2673 | 2681 |
src/codegen.cpp+2| ... | @@ -4726,6 +4726,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -4726,6 +4726,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 4726 | case IrInstructionIdFloatCast: | 4726 | case IrInstructionIdFloatCast: |
| 4727 | case IrInstructionIdIntToFloat: | 4727 | case IrInstructionIdIntToFloat: |
| 4728 | case IrInstructionIdFloatToInt: | 4728 | case IrInstructionIdFloatToInt: |
| 4729 | case IrInstructionIdBoolToInt: | ||
| 4729 | zig_unreachable(); | 4730 | zig_unreachable(); |
| 4730 | 4731 | ||
| 4731 | case IrInstructionIdReturn: | 4732 | case IrInstructionIdReturn: |
| ... | @@ -6318,6 +6319,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -6318,6 +6319,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 6318 | create_builtin_fn(g, BuiltinFnIdFloatCast, "floatCast", 2); | 6319 | create_builtin_fn(g, BuiltinFnIdFloatCast, "floatCast", 2); |
| 6319 | create_builtin_fn(g, BuiltinFnIdIntToFloat, "intToFloat", 2); | 6320 | create_builtin_fn(g, BuiltinFnIdIntToFloat, "intToFloat", 2); |
| 6320 | create_builtin_fn(g, BuiltinFnIdFloatToInt, "floatToInt", 2); | 6321 | create_builtin_fn(g, BuiltinFnIdFloatToInt, "floatToInt", 2); |
| 6322 | create_builtin_fn(g, BuiltinFnIdBoolToInt, "boolToInt", 1); | ||
| 6321 | create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); | 6323 | create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); |
| 6322 | create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); | 6324 | create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); |
| 6323 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int | 6325 | 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 *) { | ... | @@ -476,6 +476,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) { |
| 476 | return IrInstructionIdFloatToInt; | 476 | return IrInstructionIdFloatToInt; |
| 477 | } | 477 | } |
| 478 | 478 | ||
| 479 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) { | ||
| 480 | return IrInstructionIdBoolToInt; | ||
| 481 | } | ||
| 482 | |||
| 479 | static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { | 483 | static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { |
| 480 | return IrInstructionIdIntType; | 484 | return IrInstructionIdIntType; |
| 481 | } | 485 | } |
| ... | @@ -1959,6 +1963,15 @@ static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNod | ... | @@ -1959,6 +1963,15 @@ static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNod |
| 1959 | return &instruction->base; | 1963 | return &instruction->base; |
| 1960 | } | 1964 | } |
| 1961 | 1965 | ||
| 1966 | static 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 | |||
| 1962 | static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) { | 1975 | static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) { |
| 1963 | IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node); | 1976 | IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node); |
| 1964 | instruction->is_signed = is_signed; | 1977 | instruction->is_signed = is_signed; |
| ... | @@ -4071,6 +4084,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4071,6 +4084,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4071 | IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); | 4084 | IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); |
| 4072 | return ir_lval_wrap(irb, scope, result, lval); | 4085 | return ir_lval_wrap(irb, scope, result, lval); |
| 4073 | } | 4086 | } |
| 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 | } | ||
| 4074 | case BuiltinFnIdIntType: | 4097 | case BuiltinFnIdIntType: |
| 4075 | { | 4098 | { |
| 4076 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4099 | 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 | ... | @@ -10055,13 +10078,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10055 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); | 10078 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); |
| 10056 | } | 10079 | } |
| 10057 | 10080 | ||
| 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 | |||
| 10065 | // explicit widening conversion | 10081 | // explicit widening conversion |
| 10066 | if (wanted_type->id == TypeTableEntryIdInt && | 10082 | if (wanted_type->id == TypeTableEntryIdInt && |
| 10067 | actual_type->id == TypeTableEntryIdInt && | 10083 | actual_type->id == TypeTableEntryIdInt && |
| ... | @@ -17605,6 +17621,33 @@ static TypeTableEntry *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrIns | ... | @@ -17605,6 +17621,33 @@ static TypeTableEntry *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrIns |
| 17605 | return dest_type; | 17621 | return dest_type; |
| 17606 | } | 17622 | } |
| 17607 | 17623 | ||
| 17624 | static 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 | |||
| 17608 | static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { | 17651 | static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { |
| 17609 | IrInstruction *is_signed_value = instruction->is_signed->other; | 17652 | IrInstruction *is_signed_value = instruction->is_signed->other; |
| 17610 | bool is_signed; | 17653 | bool is_signed; |
| ... | @@ -20143,6 +20186,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -20143,6 +20186,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 20143 | return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); | 20186 | return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); |
| 20144 | case IrInstructionIdFloatToInt: | 20187 | case IrInstructionIdFloatToInt: |
| 20145 | return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); | 20188 | return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); |
| 20189 | case IrInstructionIdBoolToInt: | ||
| 20190 | return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); | ||
| 20146 | case IrInstructionIdIntType: | 20191 | case IrInstructionIdIntType: |
| 20147 | return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); | 20192 | return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); |
| 20148 | case IrInstructionIdBoolNot: | 20193 | case IrInstructionIdBoolNot: |
| ... | @@ -20490,6 +20535,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -20490,6 +20535,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 20490 | case IrInstructionIdFloatCast: | 20535 | case IrInstructionIdFloatCast: |
| 20491 | case IrInstructionIdIntToFloat: | 20536 | case IrInstructionIdIntToFloat: |
| 20492 | case IrInstructionIdFloatToInt: | 20537 | case IrInstructionIdFloatToInt: |
| 20538 | case IrInstructionIdBoolToInt: | ||
| 20493 | return false; | 20539 | return false; |
| 20494 | 20540 | ||
| 20495 | case IrInstructionIdAsm: | 20541 | case IrInstructionIdAsm: |
src/ir_print.cpp+9| ... | @@ -680,6 +680,12 @@ static void ir_print_float_to_int(IrPrint *irp, IrInstructionFloatToInt *instruc | ... | @@ -680,6 +680,12 @@ static void ir_print_float_to_int(IrPrint *irp, IrInstructionFloatToInt *instruc |
| 680 | fprintf(irp->f, ")"); | 680 | fprintf(irp->f, ")"); |
| 681 | } | 681 | } |
| 682 | 682 | ||
| 683 | static 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 | |||
| 683 | static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) { | 689 | static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) { |
| 684 | fprintf(irp->f, "@IntType("); | 690 | fprintf(irp->f, "@IntType("); |
| 685 | ir_print_other_instruction(irp, instruction->is_signed); | 691 | ir_print_other_instruction(irp, instruction->is_signed); |
| ... | @@ -1461,6 +1467,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1461,6 +1467,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1461 | case IrInstructionIdFloatToInt: | 1467 | case IrInstructionIdFloatToInt: |
| 1462 | ir_print_float_to_int(irp, (IrInstructionFloatToInt *)instruction); | 1468 | ir_print_float_to_int(irp, (IrInstructionFloatToInt *)instruction); |
| 1463 | break; | 1469 | break; |
| 1470 | case IrInstructionIdBoolToInt: | ||
| 1471 | ir_print_bool_to_int(irp, (IrInstructionBoolToInt *)instruction); | ||
| 1472 | break; | ||
| 1464 | case IrInstructionIdIntType: | 1473 | case IrInstructionIdIntType: |
| 1465 | ir_print_int_type(irp, (IrInstructionIntType *)instruction); | 1474 | ir_print_int_type(irp, (IrInstructionIntType *)instruction); |
| 1466 | break; | 1475 | break; |
std/fmt/errol/index.zig+2-2| ... | @@ -329,7 +329,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { | ... | @@ -329,7 +329,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { |
| 329 | var mi: i32 = mismatch10(l64, h64); | 329 | var mi: i32 = mismatch10(l64, h64); |
| 330 | var x: u64 = 1; | 330 | var x: u64 = 1; |
| 331 | { | 331 | { |
| 332 | var i = i32(lf == hf); | 332 | var i: i32 = @boolToInt(lf == hf); |
| 333 | while (i < mi) : (i += 1) { | 333 | while (i < mi) : (i += 1) { |
| 334 | x *= 10; | 334 | x *= 10; |
| 335 | } | 335 | } |
| ... | @@ -341,7 +341,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { | ... | @@ -341,7 +341,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { |
| 341 | var buf_index = u64toa(m64, buffer) - 1; | 341 | var buf_index = u64toa(m64, buffer) - 1; |
| 342 | 342 | ||
| 343 | if (mi != 0) { | 343 | if (mi != 0) { |
| 344 | buffer[buf_index - 1] += u8(buffer[buf_index] >= '5'); | 344 | buffer[buf_index - 1] += @boolToInt(buffer[buf_index] >= '5'); |
| 345 | } else { | 345 | } else { |
| 346 | buf_index += 1; | 346 | buf_index += 1; |
| 347 | } | 347 | } |
std/math/big/int.zig+9-9| ... | @@ -117,7 +117,7 @@ pub const Int = struct { | ... | @@ -117,7 +117,7 @@ pub const Int = struct { |
| 117 | 117 | ||
| 118 | fn bitcount(self: Int) usize { | 118 | fn bitcount(self: Int) usize { |
| 119 | const u_bit_count = (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1])); | 119 | 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; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | pub fn sizeInBase(self: Int, base: usize) usize { | 123 | pub fn sizeInBase(self: Int, base: usize) usize { |
| ... | @@ -499,13 +499,13 @@ pub const Int = struct { | ... | @@ -499,13 +499,13 @@ pub const Int = struct { |
| 499 | 499 | ||
| 500 | while (i < b.len) : (i += 1) { | 500 | while (i < b.len) : (i += 1) { |
| 501 | var c: Limb = 0; | 501 | var c: Limb = 0; |
| 502 | c += Limb(@addWithOverflow(Limb, a[i], b[i], &r[i])); | 502 | c += @boolToInt(@addWithOverflow(Limb, a[i], b[i], &r[i])); |
| 503 | c += Limb(@addWithOverflow(Limb, r[i], carry, &r[i])); | 503 | c += @boolToInt(@addWithOverflow(Limb, r[i], carry, &r[i])); |
| 504 | carry = c; | 504 | carry = c; |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | while (i < a.len) : (i += 1) { | 507 | 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])); |
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | r[i] = carry; | 511 | r[i] = carry; |
| ... | @@ -577,13 +577,13 @@ pub const Int = struct { | ... | @@ -577,13 +577,13 @@ pub const Int = struct { |
| 577 | 577 | ||
| 578 | while (i < b.len) : (i += 1) { | 578 | while (i < b.len) : (i += 1) { |
| 579 | var c: Limb = 0; | 579 | var c: Limb = 0; |
| 580 | c += Limb(@subWithOverflow(Limb, a[i], b[i], &r[i])); | 580 | c += @boolToInt(@subWithOverflow(Limb, a[i], b[i], &r[i])); |
| 581 | c += Limb(@subWithOverflow(Limb, r[i], borrow, &r[i])); | 581 | c += @boolToInt(@subWithOverflow(Limb, r[i], borrow, &r[i])); |
| 582 | borrow = c; | 582 | borrow = c; |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | while (i < a.len) : (i += 1) { | 585 | 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])); |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | debug.assert(borrow == 0); | 589 | debug.assert(borrow == 0); |
| ... | @@ -624,7 +624,7 @@ pub const Int = struct { | ... | @@ -624,7 +624,7 @@ pub const Int = struct { |
| 624 | var r1: Limb = undefined; | 624 | var r1: Limb = undefined; |
| 625 | 625 | ||
| 626 | // r1 = a + *carry | 626 | // r1 = a + *carry |
| 627 | const c1 = Limb(@addWithOverflow(Limb, a, carry.*, &r1)); | 627 | const c1: Limb = @boolToInt(@addWithOverflow(Limb, a, carry.*, &r1)); |
| 628 | 628 | ||
| 629 | // r2 = b * c | 629 | // r2 = b * c |
| 630 | // | 630 | // |
| ... | @@ -639,7 +639,7 @@ pub const Int = struct { | ... | @@ -639,7 +639,7 @@ pub const Int = struct { |
| 639 | const c2 = @truncate(Limb, bc >> Limb.bit_count); | 639 | const c2 = @truncate(Limb, bc >> Limb.bit_count); |
| 640 | 640 | ||
| 641 | // r1 = r1 + r2 | 641 | // r1 = r1 + r2 |
| 642 | const c3 = Limb(@addWithOverflow(Limb, r1, r2, &r1)); | 642 | const c3: Limb = @boolToInt(@addWithOverflow(Limb, r1, r2, &r1)); |
| 643 | 643 | ||
| 644 | // This never overflows, c1, c3 are either 0 or 1 and if both are 1 then | 644 | // This never overflows, c1, c3 are either 0 or 1 and if both are 1 then |
| 645 | // c2 is at least <= @maxValue(Limb) - 2. | 645 | // 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 { | ... | @@ -91,5 +91,5 @@ pub extern fn __unordtf2(a: f128, b: f128) c_int { |
| 91 | 91 | ||
| 92 | const aAbs = @bitCast(rep_t, a) & absMask; | 92 | const aAbs = @bitCast(rep_t, a) & absMask; |
| 93 | const bAbs = @bitCast(rep_t, b) & absMask; | 93 | const bAbs = @bitCast(rep_t, b) & absMask; |
| 94 | return c_int(aAbs > infRep or bAbs > infRep); | 94 | return @boolToInt(aAbs > infRep or bAbs > infRep); |
| 95 | } | 95 | } |
test/cases/bool.zig+4-4| ... | @@ -8,14 +8,14 @@ test "bool literals" { | ... | @@ -8,14 +8,14 @@ test "bool literals" { |
| 8 | test "cast bool to int" { | 8 | test "cast bool to int" { |
| 9 | const t = true; | 9 | const t = true; |
| 10 | const f = false; | 10 | const f = false; |
| 11 | assert(i32(t) == i32(1)); | 11 | assert(@boolToInt(t) == u32(1)); |
| 12 | assert(i32(f) == i32(0)); | 12 | assert(@boolToInt(f) == u32(0)); |
| 13 | nonConstCastBoolToInt(t, f); | 13 | nonConstCastBoolToInt(t, f); |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | fn nonConstCastBoolToInt(t: bool, f: bool) void { | 16 | fn nonConstCastBoolToInt(t: bool, f: bool) void { |
| 17 | assert(i32(t) == i32(1)); | 17 | assert(@boolToInt(t) == u32(1)); |
| 18 | assert(i32(f) == i32(0)); | 18 | assert(@boolToInt(f) == u32(0)); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | test "bool cmp" { | 21 | test "bool cmp" { |