| author | |
| committer | |
| log | c757984879687e465c6470fc1347cf0f14e46dcc |
| tree | 9827a65bfcc0041a279d8a75b567cba83f9c5b16 |
| parent | 84a700f97240eb2d4c65554d9be43bae9fa6d4ae |
| parent | 1ca90b585692c9611c64412844d2f3a7b3e11340 |
110 files changed, 1812 insertions(+), 882 deletions(-)
CMakeLists.txt+2-1| ... | @@ -30,7 +30,7 @@ if(GIT_EXE) | ... | @@ -30,7 +30,7 @@ if(GIT_EXE) |
| 30 | message("WARNING: Tag does not match configured Zig version") | 30 | message("WARNING: Tag does not match configured Zig version") |
| 31 | endif() | 31 | endif() |
| 32 | else() | 32 | else() |
| 33 | set(ZIG_VERSION "${ZIG_VERSION_MAJOR}.${ZIG_VERSION_MINOR}.${ZIG_VERSION_PATCH}.${ZIG_GIT_REV}") | 33 | set(ZIG_VERSION "${ZIG_VERSION}+${ZIG_GIT_REV}") |
| 34 | endif() | 34 | endif() |
| 35 | endif() | 35 | endif() |
| 36 | message("Configuring zig version ${ZIG_VERSION}") | 36 | message("Configuring zig version ${ZIG_VERSION}") |
| ... | @@ -438,6 +438,7 @@ set(ZIG_STD_FILES | ... | @@ -438,6 +438,7 @@ set(ZIG_STD_FILES |
| 438 | "debug/failing_allocator.zig" | 438 | "debug/failing_allocator.zig" |
| 439 | "debug/index.zig" | 439 | "debug/index.zig" |
| 440 | "dwarf.zig" | 440 | "dwarf.zig" |
| 441 | "dynamic_library.zig" | ||
| 441 | "elf.zig" | 442 | "elf.zig" |
| 442 | "empty.zig" | 443 | "empty.zig" |
| 443 | "event.zig" | 444 | "event.zig" |
doc/langref.html.in+198-58| ... | @@ -370,17 +370,17 @@ pub fn main() void { | ... | @@ -370,17 +370,17 @@ pub fn main() void { |
| 370 | <tr> | 370 | <tr> |
| 371 | <td><code>f32</code></td> | 371 | <td><code>f32</code></td> |
| 372 | <td><code>float</code></td> | 372 | <td><code>float</code></td> |
| 373 | <td>32-bit floating point (23-bit mantissa)</td> | 373 | <td>32-bit floating point (23-bit mantissa) IEEE-754-2008 binary32</td> |
| 374 | </tr> | 374 | </tr> |
| 375 | <tr> | 375 | <tr> |
| 376 | <td><code>f64</code></td> | 376 | <td><code>f64</code></td> |
| 377 | <td><code>double</code></td> | 377 | <td><code>double</code></td> |
| 378 | <td>64-bit floating point (52-bit mantissa)</td> | 378 | <td>64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64</td> |
| 379 | </tr> | 379 | </tr> |
| 380 | <tr> | 380 | <tr> |
| 381 | <td><code>f128</code></td> | 381 | <td><code>f128</code></td> |
| 382 | <td>(none)</td> | 382 | <td>(none)</td> |
| 383 | <td>128-bit floating point (112-bit mantissa)</td> | 383 | <td>128-bit floating point (112-bit mantissa) IEEE-754-2008 binary128</td> |
| 384 | </tr> | 384 | </tr> |
| 385 | <tr> | 385 | <tr> |
| 386 | <td><code>bool</code></td> | 386 | <td><code>bool</code></td> |
| ... | @@ -407,6 +407,16 @@ pub fn main() void { | ... | @@ -407,6 +407,16 @@ pub fn main() void { |
| 407 | <td>(none)</td> | 407 | <td>(none)</td> |
| 408 | <td>an error code</td> | 408 | <td>an error code</td> |
| 409 | </tr> | 409 | </tr> |
| 410 | <tr> | ||
| 411 | <td><code>comptime_int</code></td> | ||
| 412 | <td>(none)</td> | ||
| 413 | <td>Only allowed for {#link|comptime#}-known values. The type of integer literals.</td> | ||
| 414 | </tr> | ||
| 415 | <tr> | ||
| 416 | <td><code>comptime_float</code></td> | ||
| 417 | <td>(none)</td> | ||
| 418 | <td>Only allowed for {#link|comptime#}-known values. The type of float literals.</td> | ||
| 419 | </tr> | ||
| 410 | </table> | 420 | </table> |
| 411 | </div> | 421 | </div> |
| 412 | {#see_also|Integers|Floats|void|Errors#} | 422 | {#see_also|Integers|Floats|void|Errors#} |
| ... | @@ -642,7 +652,18 @@ fn divide(a: i32, b: i32) i32 { | ... | @@ -642,7 +652,18 @@ fn divide(a: i32, b: i32) i32 { |
| 642 | {#header_close#} | 652 | {#header_close#} |
| 643 | {#header_close#} | 653 | {#header_close#} |
| 644 | {#header_open|Floats#} | 654 | {#header_open|Floats#} |
| 655 | <p>Zig has the following floating point types:</p> | ||
| 656 | <ul> | ||
| 657 | <li><code>f32</code> - IEEE-754-2008 binary32</li> | ||
| 658 | <li><code>f64</code> - IEEE-754-2008 binary64</li> | ||
| 659 | <li><code>f128</code> - IEEE-754-2008 binary128</li> | ||
| 660 | <li><code>c_longdouble</code> - matches <code>long double</code> for the target C ABI</li> | ||
| 661 | </ul> | ||
| 645 | {#header_open|Float Literals#} | 662 | {#header_open|Float Literals#} |
| 663 | <p> | ||
| 664 | Float literals have type <code>comptime_float</code> which is guaranteed to hold at least all possible values | ||
| 665 | that the largest other floating point type can hold. Float literals implicitly cast to any other type. | ||
| 666 | </p> | ||
| 646 | {#code_begin|syntax#} | 667 | {#code_begin|syntax#} |
| 647 | const floating_point = 123.0E+77; | 668 | const floating_point = 123.0E+77; |
| 648 | const another_float = 123.0; | 669 | const another_float = 123.0; |
| ... | @@ -1334,7 +1355,7 @@ var some_integers: [100]i32 = undefined; | ... | @@ -1334,7 +1355,7 @@ var some_integers: [100]i32 = undefined; |
| 1334 | 1355 | ||
| 1335 | test "modify an array" { | 1356 | test "modify an array" { |
| 1336 | for (some_integers) |*item, i| { | 1357 | for (some_integers) |*item, i| { |
| 1337 | item.* = i32(i); | 1358 | item.* = @intCast(i32, i); |
| 1338 | } | 1359 | } |
| 1339 | assert(some_integers[10] == 10); | 1360 | assert(some_integers[10] == 10); |
| 1340 | assert(some_integers[99] == 99); | 1361 | assert(some_integers[99] == 99); |
| ... | @@ -1376,8 +1397,8 @@ var fancy_array = init: { | ... | @@ -1376,8 +1397,8 @@ var fancy_array = init: { |
| 1376 | var initial_value: [10]Point = undefined; | 1397 | var initial_value: [10]Point = undefined; |
| 1377 | for (initial_value) |*pt, i| { | 1398 | for (initial_value) |*pt, i| { |
| 1378 | pt.* = Point{ | 1399 | pt.* = Point{ |
| 1379 | .x = i32(i), | 1400 | .x = @intCast(i32, i), |
| 1380 | .y = i32(i) * 2, | 1401 | .y = @intCast(i32, i) * 2, |
| 1381 | }; | 1402 | }; |
| 1382 | } | 1403 | } |
| 1383 | break :init initial_value; | 1404 | break :init initial_value; |
| ... | @@ -1630,7 +1651,7 @@ fn foo(bytes: []u8) u32 { | ... | @@ -1630,7 +1651,7 @@ fn foo(bytes: []u8) u32 { |
| 1630 | <pre><code class="zig">@ptrCast(*u32, f32(12.34)).*</code></pre> | 1651 | <pre><code class="zig">@ptrCast(*u32, f32(12.34)).*</code></pre> |
| 1631 | <p>Instead, use {#link|@bitCast#}: | 1652 | <p>Instead, use {#link|@bitCast#}: |
| 1632 | <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre> | 1653 | <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre> |
| 1633 | <p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p> | 1654 | <p>As an added benefit, the <code>@bitCast</code> version works at compile-time.</p> |
| 1634 | {#see_also|Slices|Memory#} | 1655 | {#see_also|Slices|Memory#} |
| 1635 | {#header_close#} | 1656 | {#header_close#} |
| 1636 | {#header_close#} | 1657 | {#header_close#} |
| ... | @@ -2389,7 +2410,7 @@ test "for basics" { | ... | @@ -2389,7 +2410,7 @@ test "for basics" { |
| 2389 | var sum2: i32 = 0; | 2410 | var sum2: i32 = 0; |
| 2390 | for (items) |value, i| { | 2411 | for (items) |value, i| { |
| 2391 | assert(@typeOf(i) == usize); | 2412 | assert(@typeOf(i) == usize); |
| 2392 | sum2 += i32(i); | 2413 | sum2 += @intCast(i32, i); |
| 2393 | } | 2414 | } |
| 2394 | assert(sum2 == 10); | 2415 | assert(sum2 == 10); |
| 2395 | } | 2416 | } |
| ... | @@ -2797,39 +2818,30 @@ fn foo() void { } | ... | @@ -2797,39 +2818,30 @@ fn foo() void { } |
| 2797 | {#code_end#} | 2818 | {#code_end#} |
| 2798 | {#header_open|Pass-by-value Parameters#} | 2819 | {#header_open|Pass-by-value Parameters#} |
| 2799 | <p> | 2820 | <p> |
| 2800 | In Zig, structs, unions, and enums with payloads cannot be passed by value | 2821 | In Zig, structs, unions, and enums with payloads can be passed directly to a function: |
| 2801 | to a function. | ||
| 2802 | </p> | 2822 | </p> |
| 2803 | {#code_begin|test_err|not copyable; cannot pass by value#} | 2823 | {#code_begin|test#} |
| 2804 | const Foo = struct { | 2824 | const Point = struct { |
| 2805 | x: i32, | 2825 | x: i32, |
| 2826 | y: i32, | ||
| 2806 | }; | 2827 | }; |
| 2807 | 2828 | ||
| 2808 | fn bar(foo: Foo) void {} | 2829 | fn foo(point: Point) i32 { |
| 2809 | 2830 | return point.x + point.y; | |
| 2810 | test "pass aggregate type by value to function" { | ||
| 2811 | bar(Foo {.x = 12,}); | ||
| 2812 | } | 2831 | } |
| 2813 | {#code_end#} | ||
| 2814 | <p> | ||
| 2815 | Instead, one must use <code>*const</code>. Zig allows implicitly casting something | ||
| 2816 | to a const pointer to it: | ||
| 2817 | </p> | ||
| 2818 | {#code_begin|test#} | ||
| 2819 | const Foo = struct { | ||
| 2820 | x: i32, | ||
| 2821 | }; | ||
| 2822 | 2832 | ||
| 2823 | fn bar(foo: *const Foo) void {} | 2833 | const assert = @import("std").debug.assert; |
| 2824 | 2834 | ||
| 2825 | test "implicitly cast to const pointer" { | 2835 | test "pass aggregate type by non-copy value to function" { |
| 2826 | bar(Foo {.x = 12,}); | 2836 | assert(foo(Point{ .x = 1, .y = 2 }) == 3); |
| 2827 | } | 2837 | } |
| 2828 | {#code_end#} | 2838 | {#code_end#} |
| 2829 | <p> | 2839 | <p> |
| 2830 | However, | 2840 | In this case, the value may be passed by reference, or by value, whichever way |
| 2831 | the C ABI does allow passing structs and unions by value. So functions which | 2841 | Zig decides will be faster. |
| 2832 | use the C calling convention may pass structs and unions by value. | 2842 | </p> |
| 2843 | <p> | ||
| 2844 | For extern functions, Zig follows the C ABI for passing structs and unions by value. | ||
| 2833 | </p> | 2845 | </p> |
| 2834 | {#header_close#} | 2846 | {#header_close#} |
| 2835 | {#header_open|Function Reflection#} | 2847 | {#header_open|Function Reflection#} |
| ... | @@ -3539,13 +3551,91 @@ const optional_value: ?i32 = null; | ... | @@ -3539,13 +3551,91 @@ const optional_value: ?i32 = null; |
| 3539 | <p>TODO: ptrcast builtin</p> | 3551 | <p>TODO: ptrcast builtin</p> |
| 3540 | <p>TODO: explain number literals vs concrete types</p> | 3552 | <p>TODO: explain number literals vs concrete types</p> |
| 3541 | {#header_close#} | 3553 | {#header_close#} |
| 3554 | |||
| 3542 | {#header_open|void#} | 3555 | {#header_open|void#} |
| 3543 | <p>TODO: assigning void has no codegen</p> | 3556 | <p> |
| 3544 | <p>TODO: hashmap with void becomes a set</p> | 3557 | <code>void</code> represents a type that has no value. Code that makes use of void values is |
| 3545 | <p>TODO: difference between c_void and void</p> | 3558 | not included in the final generated code: |
| 3546 | <p>TODO: void is the default return value of functions</p> | 3559 | </p> |
| 3547 | <p>TODO: functions require assigning the return value</p> | 3560 | {#code_begin|syntax#} |
| 3561 | export fn entry() void { | ||
| 3562 | var x: void = {}; | ||
| 3563 | var y: void = {}; | ||
| 3564 | x = y; | ||
| 3565 | } | ||
| 3566 | {#code_end#} | ||
| 3567 | <p>When this turns into LLVM IR, there is no code generated in the body of <code>entry</code>, | ||
| 3568 | even in debug mode. For example, on x86_64:</p> | ||
| 3569 | <pre><code>0000000000000010 &lt;entry&gt;: | ||
| 3570 | 10:	55 	push %rbp | ||
| 3571 | 11:	48 89 e5 	mov %rsp,%rbp | ||
| 3572 | 14:	5d 	pop %rbp | ||
| 3573 | 15:	c3 	retq </code></pre> | ||
| 3574 | <p>These assembly instructions do not have any code associated with the void values - | ||
| 3575 | they only perform the function call prologue and epilog.</p> | ||
| 3576 | <p> | ||
| 3577 | <code>void</code> can be useful for instantiating generic types. For example, given a | ||
| 3578 | <code>Map(Key, Value)</code>, one can pass <code>void</code> for the <code>Value</code> | ||
| 3579 | type to make it into a <code>Set</code>: | ||
| 3580 | </p> | ||
| 3581 | {#code_begin|test#} | ||
| 3582 | const std = @import("std"); | ||
| 3583 | const assert = std.debug.assert; | ||
| 3584 | |||
| 3585 | test "turn HashMap into a set with void" { | ||
| 3586 | var map = std.HashMap(i32, void, hash_i32, eql_i32).init(std.debug.global_allocator); | ||
| 3587 | defer map.deinit(); | ||
| 3588 | |||
| 3589 | _ = try map.put(1, {}); | ||
| 3590 | _ = try map.put(2, {}); | ||
| 3591 | |||
| 3592 | assert(map.contains(2)); | ||
| 3593 | assert(!map.contains(3)); | ||
| 3594 | |||
| 3595 | _ = map.remove(2); | ||
| 3596 | assert(!map.contains(2)); | ||
| 3597 | } | ||
| 3598 | |||
| 3599 | fn hash_i32(x: i32) u32 { | ||
| 3600 | return @bitCast(u32, x); | ||
| 3601 | } | ||
| 3602 | |||
| 3603 | fn eql_i32(a: i32, b: i32) bool { | ||
| 3604 | return a == b; | ||
| 3605 | } | ||
| 3606 | {#code_end#} | ||
| 3607 | <p>Note that this is different than using a dummy value for the hash map value. | ||
| 3608 | By using <code>void</code> as the type of the value, the hash map entry type has no value field, and | ||
| 3609 | thus the hash map takes up less space. Further, all the code that deals with storing and loading the | ||
| 3610 | value is deleted, as seen above. | ||
| 3611 | </p> | ||
| 3612 | <p> | ||
| 3613 | <code>void</code> is distinct from <code>c_void</code>, which is defined like this: | ||
| 3614 | <code>pub const c_void = @OpaqueType();</code>. | ||
| 3615 | <code>void</code> has a known size of 0 bytes, and <code>c_void</code> has an unknown, but non-zero, size. | ||
| 3616 | </p> | ||
| 3617 | <p> | ||
| 3618 | Expressions of type <code>void</code> are the only ones whose value can be ignored. For example: | ||
| 3619 | </p> | ||
| 3620 | {#code_begin|test_err|expression value is ignored#} | ||
| 3621 | test "ignoring expression value" { | ||
| 3622 | foo(); | ||
| 3623 | } | ||
| 3624 | |||
| 3625 | fn foo() i32 { | ||
| 3626 | return 1234; | ||
| 3627 | } | ||
| 3628 | {#code_end#} | ||
| 3629 | <p>However, if the expression has type <code>void</code>:</p> | ||
| 3630 | {#code_begin|test#} | ||
| 3631 | test "ignoring expression value" { | ||
| 3632 | foo(); | ||
| 3633 | } | ||
| 3634 | |||
| 3635 | fn foo() void {} | ||
| 3636 | {#code_end#} | ||
| 3548 | {#header_close#} | 3637 | {#header_close#} |
| 3638 | |||
| 3549 | {#header_open|this#} | 3639 | {#header_open|this#} |
| 3550 | <p>TODO: example of this referring to Self struct</p> | 3640 | <p>TODO: example of this referring to Self struct</p> |
| 3551 | <p>TODO: example of this referring to recursion function</p> | 3641 | <p>TODO: example of this referring to recursion function</p> |
| ... | @@ -4548,6 +4638,19 @@ comptime { | ... | @@ -4548,6 +4638,19 @@ comptime { |
| 4548 | </p> | 4638 | </p> |
| 4549 | {#see_also|Alignment#} | 4639 | {#see_also|Alignment#} |
| 4550 | {#header_close#} | 4640 | {#header_close#} |
| 4641 | |||
| 4642 | {#header_open|@boolToInt#} | ||
| 4643 | <pre><code class="zig">@boolToInt(value: bool) u1</code></pre> | ||
| 4644 | <p> | ||
| 4645 | Converts <code>true</code> to <code>u1(1)</code> and <code>false</code> to | ||
| 4646 | <code>u1(0)</code>. | ||
| 4647 | </p> | ||
| 4648 | <p> | ||
| 4649 | If the value is known at compile-time, the return type is <code>comptime_int</code> | ||
| 4650 | instead of <code>u1</code>. | ||
| 4651 | </p> | ||
| 4652 | {#header_close#} | ||
| 4653 | |||
| 4551 | {#header_open|@cDefine#} | 4654 | {#header_open|@cDefine#} |
| 4552 | <pre><code class="zig">@cDefine(comptime name: []u8, value)</code></pre> | 4655 | <pre><code class="zig">@cDefine(comptime name: []u8, value)</code></pre> |
| 4553 | <p> | 4656 | <p> |
| ... | @@ -4822,21 +4925,6 @@ test "main" { | ... | @@ -4822,21 +4925,6 @@ test "main" { |
| 4822 | Creates a symbol in the output object file. | 4925 | Creates a symbol in the output object file. |
| 4823 | </p> | 4926 | </p> |
| 4824 | {#header_close#} | 4927 | {#header_close#} |
| 4825 | {#header_open|@tagName#} | ||
| 4826 | <pre><code class="zig">@tagName(value: var) []const u8</code></pre> | ||
| 4827 | <p> | ||
| 4828 | Converts an enum value or union value to a slice of bytes representing the name. | ||
| 4829 | </p> | ||
| 4830 | {#header_close#} | ||
| 4831 | {#header_open|@TagType#} | ||
| 4832 | <pre><code class="zig">@TagType(T: type) type</code></pre> | ||
| 4833 | <p> | ||
| 4834 | For an enum, returns the integer type that is used to store the enumeration value. | ||
| 4835 | </p> | ||
| 4836 | <p> | ||
| 4837 | For a union, returns the enum type that is used to store the tag value. | ||
| 4838 | </p> | ||
| 4839 | {#header_close#} | ||
| 4840 | {#header_open|@errorName#} | 4928 | {#header_open|@errorName#} |
| 4841 | <pre><code class="zig">@errorName(err: error) []u8</code></pre> | 4929 | <pre><code class="zig">@errorName(err: error) []u8</code></pre> |
| 4842 | <p> | 4930 | <p> |
| ... | @@ -4871,6 +4959,12 @@ test "main" { | ... | @@ -4871,6 +4959,12 @@ test "main" { |
| 4871 | </p> | 4959 | </p> |
| 4872 | {#see_also|Compile Variables#} | 4960 | {#see_also|Compile Variables#} |
| 4873 | {#header_close#} | 4961 | {#header_close#} |
| 4962 | |||
| 4963 | {#header_open|@field#} | ||
| 4964 | <pre><code class="zig">@field(lhs: var, comptime field_name: []const u8) (field)</code></pre> | ||
| 4965 | <p>Preforms field access equivalent to <code>lhs.-&gtfield_name-&lt</code>.</p> | ||
| 4966 | {#header_close#} | ||
| 4967 | |||
| 4874 | {#header_open|@fieldParentPtr#} | 4968 | {#header_open|@fieldParentPtr#} |
| 4875 | <pre><code class="zig">@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, | 4969 | <pre><code class="zig">@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, |
| 4876 | field_ptr: *T) *ParentType</code></pre> | 4970 | field_ptr: *T) *ParentType</code></pre> |
| ... | @@ -4878,6 +4972,23 @@ test "main" { | ... | @@ -4878,6 +4972,23 @@ test "main" { |
| 4878 | Given a pointer to a field, returns the base pointer of a struct. | 4972 | Given a pointer to a field, returns the base pointer of a struct. |
| 4879 | </p> | 4973 | </p> |
| 4880 | {#header_close#} | 4974 | {#header_close#} |
| 4975 | |||
| 4976 | {#header_open|@floatCast#} | ||
| 4977 | <pre><code class="zig">@floatCast(comptime DestType: type, value: var) DestType</code></pre> | ||
| 4978 | <p> | ||
| 4979 | Convert from one float type to another. This cast is safe, but may cause the | ||
| 4980 | numeric value to lose precision. | ||
| 4981 | </p> | ||
| 4982 | {#header_close#} | ||
| 4983 | |||
| 4984 | {#header_open|@floatToInt#} | ||
| 4985 | <pre><code class="zig">@floatToInt(comptime DestType: type, float: var) DestType</code></pre> | ||
| 4986 | <p> | ||
| 4987 | Converts the integer part of a floating point number to the destination type. | ||
| 4988 | To convert the other way, use {#link|@intToFloat#}. This cast is always safe. | ||
| 4989 | </p> | ||
| 4990 | {#header_close#} | ||
| 4991 | |||
| 4881 | {#header_open|@frameAddress#} | 4992 | {#header_open|@frameAddress#} |
| 4882 | <pre><code class="zig">@frameAddress()</code></pre> | 4993 | <pre><code class="zig">@frameAddress()</code></pre> |
| 4883 | <p> | 4994 | <p> |
| ... | @@ -4932,12 +5043,30 @@ fn add(a: i32, b: i32) i32 { return a + b; } | ... | @@ -4932,12 +5043,30 @@ fn add(a: i32, b: i32) i32 { return a + b; } |
| 4932 | </p> | 5043 | </p> |
| 4933 | {#see_also|@noInlineCall#} | 5044 | {#see_also|@noInlineCall#} |
| 4934 | {#header_close#} | 5045 | {#header_close#} |
| 5046 | |||
| 5047 | {#header_open|@intCast#} | ||
| 5048 | <pre><code class="zig">@intCast(comptime DestType: type, int: var) DestType</code></pre> | ||
| 5049 | <p> | ||
| 5050 | Converts an integer to another integer while keeping the same numerical value. | ||
| 5051 | Attempting to convert a number which is out of range of the destination type results in | ||
| 5052 | {#link|Undefined Behavior#}. | ||
| 5053 | </p> | ||
| 5054 | {#header_close#} | ||
| 5055 | |||
| 5056 | {#header_open|@intToFloat#} | ||
| 5057 | <pre><code class="zig">@intToFloat(comptime DestType: type, int: var) DestType</code></pre> | ||
| 5058 | <p> | ||
| 5059 | Converts an integer to the closest floating point representation. To convert the other way, use {#link|@floatToInt#}. This cast is always safe. | ||
| 5060 | </p> | ||
| 5061 | {#header_close#} | ||
| 5062 | |||
| 4935 | {#header_open|@intToPtr#} | 5063 | {#header_open|@intToPtr#} |
| 4936 | <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) DestType</code></pre> | 5064 | <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) DestType</code></pre> |
| 4937 | <p> | 5065 | <p> |
| 4938 | Converts an integer to a pointer. To convert the other way, use {#link|@ptrToInt#}. | 5066 | Converts an integer to a pointer. To convert the other way, use {#link|@ptrToInt#}. |
| 4939 | </p> | 5067 | </p> |
| 4940 | {#header_close#} | 5068 | {#header_close#} |
| 5069 | |||
| 4941 | {#header_open|@IntType#} | 5070 | {#header_open|@IntType#} |
| 4942 | <pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u8) type</code></pre> | 5071 | <pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u8) type</code></pre> |
| 4943 | <p> | 5072 | <p> |
| ... | @@ -4975,10 +5104,6 @@ fn add(a: i32, b: i32) i32 { return a + b; } | ... | @@ -4975,10 +5104,6 @@ fn add(a: i32, b: i32) i32 { return a + b; } |
| 4975 | It does not include functions, variables, or constants. | 5104 | It does not include functions, variables, or constants. |
| 4976 | </p> | 5105 | </p> |
| 4977 | {#header_close#} | 5106 | {#header_close#} |
| 4978 | {#header_open|@field#} | ||
| 4979 | <pre><code class="zig">@field(lhs: var, comptime field_name: []const u8) (field)</code></pre> | ||
| 4980 | <p>Preforms field access equivalent to <code>lhs.-&gtfield_name-&lt</code>.</p> | ||
| 4981 | {#header_close#} | ||
| 4982 | {#header_open|@memberType#} | 5107 | {#header_open|@memberType#} |
| 4983 | <pre><code class="zig">@memberType(comptime T: type, comptime index: usize) type</code></pre> | 5108 | <pre><code class="zig">@memberType(comptime T: type, comptime index: usize) type</code></pre> |
| 4984 | <p>Returns the field type of a struct or union.</p> | 5109 | <p>Returns the field type of a struct or union.</p> |
| ... | @@ -5358,6 +5483,21 @@ pub const FloatMode = enum { | ... | @@ -5358,6 +5483,21 @@ pub const FloatMode = enum { |
| 5358 | If no overflow or underflow occurs, returns <code>false</code>. | 5483 | If no overflow or underflow occurs, returns <code>false</code>. |
| 5359 | </p> | 5484 | </p> |
| 5360 | {#header_close#} | 5485 | {#header_close#} |
| 5486 | {#header_open|@tagName#} | ||
| 5487 | <pre><code class="zig">@tagName(value: var) []const u8</code></pre> | ||
| 5488 | <p> | ||
| 5489 | Converts an enum value or union value to a slice of bytes representing the name. | ||
| 5490 | </p> | ||
| 5491 | {#header_close#} | ||
| 5492 | {#header_open|@TagType#} | ||
| 5493 | <pre><code class="zig">@TagType(T: type) type</code></pre> | ||
| 5494 | <p> | ||
| 5495 | For an enum, returns the integer type that is used to store the enumeration value. | ||
| 5496 | </p> | ||
| 5497 | <p> | ||
| 5498 | For a union, returns the enum type that is used to store the tag value. | ||
| 5499 | </p> | ||
| 5500 | {#header_close#} | ||
| 5361 | {#header_open|@truncate#} | 5501 | {#header_open|@truncate#} |
| 5362 | <pre><code class="zig">@truncate(comptime T: type, integer) T</code></pre> | 5502 | <pre><code class="zig">@truncate(comptime T: type, integer) T</code></pre> |
| 5363 | <p> | 5503 | <p> |
| ... | @@ -5718,7 +5858,7 @@ comptime { | ... | @@ -5718,7 +5858,7 @@ comptime { |
| 5718 | {#code_begin|test_err|attempt to cast negative value to unsigned integer#} | 5858 | {#code_begin|test_err|attempt to cast negative value to unsigned integer#} |
| 5719 | comptime { | 5859 | comptime { |
| 5720 | const value: i32 = -1; | 5860 | const value: i32 = -1; |
| 5721 | const unsigned = u32(value); | 5861 | const unsigned = @intCast(u32, value); |
| 5722 | } | 5862 | } |
| 5723 | {#code_end#} | 5863 | {#code_end#} |
| 5724 | <p>At runtime crashes with the message <code>attempt to cast negative value to unsigned integer</code> and a stack trace.</p> | 5864 | <p>At runtime crashes with the message <code>attempt to cast negative value to unsigned integer</code> and a stack trace.</p> |
| ... | @@ -5732,7 +5872,7 @@ comptime { | ... | @@ -5732,7 +5872,7 @@ comptime { |
| 5732 | {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#} | 5872 | {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#} |
| 5733 | comptime { | 5873 | comptime { |
| 5734 | const spartan_count: u16 = 300; | 5874 | const spartan_count: u16 = 300; |
| 5735 | const byte = u8(spartan_count); | 5875 | const byte = @intCast(u8, spartan_count); |
| 5736 | } | 5876 | } |
| 5737 | {#code_end#} | 5877 | {#code_end#} |
| 5738 | <p>At runtime crashes with the message <code>integer cast truncated bits</code> and a stack trace.</p> | 5878 | <p>At runtime crashes with the message <code>integer cast truncated bits</code> and a stack trace.</p> |
| ... | @@ -6653,7 +6793,7 @@ hljs.registerLanguage("zig", function(t) { | ... | @@ -6653,7 +6793,7 @@ hljs.registerLanguage("zig", function(t) { |
| 6653 | a = t.IR + "\\s*\\(", | 6793 | a = t.IR + "\\s*\\(", |
| 6654 | c = { | 6794 | c = { |
| 6655 | 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", | 6795 | 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", |
| 6656 | 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", | 6796 | 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", |
| 6657 | literal: "true false null undefined" | 6797 | literal: "true false null undefined" |
| 6658 | }, | 6798 | }, |
| 6659 | n = [e, t.CLCM, t.CBCM, s, r]; | 6799 | n = [e, t.CLCM, t.CBCM, s, r]; |
example/hello_world/hello_libc.zig+1-1| ... | @@ -8,7 +8,7 @@ const c = @cImport({ | ... | @@ -8,7 +8,7 @@ const c = @cImport({ |
| 8 | const msg = c"Hello, world!\n"; | 8 | const msg = c"Hello, world!\n"; |
| 9 | 9 | ||
| 10 | export fn main(argc: c_int, argv: **u8) c_int { | 10 | export fn main(argc: c_int, argv: **u8) c_int { |
| 11 | if (c.printf(msg) != c_int(c.strlen(msg))) return -1; | 11 | if (c.printf(msg) != @intCast(c_int, c.strlen(msg))) return -1; |
| 12 | 12 | ||
| 13 | return 0; | 13 | return 0; |
| 14 | } | 14 | } |
src-self-hosted/main.zig+55-8| ... | @@ -700,6 +700,36 @@ const args_fmt_spec = []Flag{ | ... | @@ -700,6 +700,36 @@ const args_fmt_spec = []Flag{ |
| 700 | }), | 700 | }), |
| 701 | }; | 701 | }; |
| 702 | 702 | ||
| 703 | const Fmt = struct { | ||
| 704 | seen: std.HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8), | ||
| 705 | queue: std.LinkedList([]const u8), | ||
| 706 | any_error: bool, | ||
| 707 | |||
| 708 | // file_path must outlive Fmt | ||
| 709 | fn addToQueue(self: *Fmt, file_path: []const u8) !void { | ||
| 710 | const new_node = try self.seen.allocator.construct(std.LinkedList([]const u8).Node{ | ||
| 711 | .prev = undefined, | ||
| 712 | .next = undefined, | ||
| 713 | .data = file_path, | ||
| 714 | }); | ||
| 715 | |||
| 716 | if (try self.seen.put(file_path, {})) |_| return; | ||
| 717 | |||
| 718 | self.queue.append(new_node); | ||
| 719 | } | ||
| 720 | |||
| 721 | fn addDirToQueue(self: *Fmt, file_path: []const u8) !void { | ||
| 722 | var dir = try std.os.Dir.open(self.seen.allocator, file_path); | ||
| 723 | defer dir.close(); | ||
| 724 | while (try dir.next()) |entry| { | ||
| 725 | if (entry.kind == std.os.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) { | ||
| 726 | const full_path = try os.path.join(self.seen.allocator, file_path, entry.name); | ||
| 727 | try self.addToQueue(full_path); | ||
| 728 | } | ||
| 729 | } | ||
| 730 | } | ||
| 731 | }; | ||
| 732 | |||
| 703 | fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { | 733 | fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { |
| 704 | var flags = try Args.parse(allocator, args_fmt_spec, args); | 734 | var flags = try Args.parse(allocator, args_fmt_spec, args); |
| 705 | defer flags.deinit(); | 735 | defer flags.deinit(); |
| ... | @@ -728,21 +758,38 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { | ... | @@ -728,21 +758,38 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { |
| 728 | } | 758 | } |
| 729 | }; | 759 | }; |
| 730 | 760 | ||
| 731 | var fmt_errors = false; | 761 | var fmt = Fmt{ |
| 762 | .seen = std.HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8).init(allocator), | ||
| 763 | .queue = std.LinkedList([]const u8).init(), | ||
| 764 | .any_error = false, | ||
| 765 | }; | ||
| 766 | |||
| 732 | for (flags.positionals.toSliceConst()) |file_path| { | 767 | for (flags.positionals.toSliceConst()) |file_path| { |
| 768 | try fmt.addToQueue(file_path); | ||
| 769 | } | ||
| 770 | |||
| 771 | while (fmt.queue.popFirst()) |node| { | ||
| 772 | const file_path = node.data; | ||
| 773 | |||
| 733 | var file = try os.File.openRead(allocator, file_path); | 774 | var file = try os.File.openRead(allocator, file_path); |
| 734 | defer file.close(); | 775 | defer file.close(); |
| 735 | 776 | ||
| 736 | const source_code = io.readFileAlloc(allocator, file_path) catch |err| { | 777 | const source_code = io.readFileAlloc(allocator, file_path) catch |err| switch (err) { |
| 737 | try stderr.print("unable to open '{}': {}\n", file_path, err); | 778 | error.IsDir => { |
| 738 | fmt_errors = true; | 779 | try fmt.addDirToQueue(file_path); |
| 739 | continue; | 780 | continue; |
| 781 | }, | ||
| 782 | else => { | ||
| 783 | try stderr.print("unable to open '{}': {}\n", file_path, err); | ||
| 784 | fmt.any_error = true; | ||
| 785 | continue; | ||
| 786 | }, | ||
| 740 | }; | 787 | }; |
| 741 | defer allocator.free(source_code); | 788 | defer allocator.free(source_code); |
| 742 | 789 | ||
| 743 | var tree = std.zig.parse(allocator, source_code) catch |err| { | 790 | var tree = std.zig.parse(allocator, source_code) catch |err| { |
| 744 | try stderr.print("error parsing file '{}': {}\n", file_path, err); | 791 | try stderr.print("error parsing file '{}': {}\n", file_path, err); |
| 745 | fmt_errors = true; | 792 | fmt.any_error = true; |
| 746 | continue; | 793 | continue; |
| 747 | }; | 794 | }; |
| 748 | defer tree.deinit(); | 795 | defer tree.deinit(); |
| ... | @@ -755,7 +802,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { | ... | @@ -755,7 +802,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { |
| 755 | try errmsg.printToFile(&stderr_file, msg, color); | 802 | try errmsg.printToFile(&stderr_file, msg, color); |
| 756 | } | 803 | } |
| 757 | if (tree.errors.len != 0) { | 804 | if (tree.errors.len != 0) { |
| 758 | fmt_errors = true; | 805 | fmt.any_error = true; |
| 759 | continue; | 806 | continue; |
| 760 | } | 807 | } |
| 761 | 808 | ||
| ... | @@ -769,7 +816,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { | ... | @@ -769,7 +816,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { |
| 769 | } | 816 | } |
| 770 | } | 817 | } |
| 771 | 818 | ||
| 772 | if (fmt_errors) { | 819 | if (fmt.any_error) { |
| 773 | os.exit(1); | 820 | os.exit(1); |
| 774 | } | 821 | } |
| 775 | } | 822 | } |
src/all_types.hpp+44| ... | @@ -1357,6 +1357,11 @@ enum BuiltinFnId { | ... | @@ -1357,6 +1357,11 @@ enum BuiltinFnId { |
| 1357 | BuiltinFnIdMod, | 1357 | BuiltinFnIdMod, |
| 1358 | BuiltinFnIdSqrt, | 1358 | BuiltinFnIdSqrt, |
| 1359 | BuiltinFnIdTruncate, | 1359 | BuiltinFnIdTruncate, |
| 1360 | BuiltinFnIdIntCast, | ||
| 1361 | BuiltinFnIdFloatCast, | ||
| 1362 | BuiltinFnIdIntToFloat, | ||
| 1363 | BuiltinFnIdFloatToInt, | ||
| 1364 | BuiltinFnIdBoolToInt, | ||
| 1360 | BuiltinFnIdIntType, | 1365 | BuiltinFnIdIntType, |
| 1361 | BuiltinFnIdSetCold, | 1366 | BuiltinFnIdSetCold, |
| 1362 | BuiltinFnIdSetRuntimeSafety, | 1367 | BuiltinFnIdSetRuntimeSafety, |
| ... | @@ -2038,6 +2043,11 @@ enum IrInstructionId { | ... | @@ -2038,6 +2043,11 @@ enum IrInstructionId { |
| 2038 | IrInstructionIdCmpxchg, | 2043 | IrInstructionIdCmpxchg, |
| 2039 | IrInstructionIdFence, | 2044 | IrInstructionIdFence, |
| 2040 | IrInstructionIdTruncate, | 2045 | IrInstructionIdTruncate, |
| 2046 | IrInstructionIdIntCast, | ||
| 2047 | IrInstructionIdFloatCast, | ||
| 2048 | IrInstructionIdIntToFloat, | ||
| 2049 | IrInstructionIdFloatToInt, | ||
| 2050 | IrInstructionIdBoolToInt, | ||
| 2041 | IrInstructionIdIntType, | 2051 | IrInstructionIdIntType, |
| 2042 | IrInstructionIdBoolNot, | 2052 | IrInstructionIdBoolNot, |
| 2043 | IrInstructionIdMemset, | 2053 | IrInstructionIdMemset, |
| ... | @@ -2630,6 +2640,40 @@ struct IrInstructionTruncate { | ... | @@ -2630,6 +2640,40 @@ struct IrInstructionTruncate { |
| 2630 | IrInstruction *target; | 2640 | IrInstruction *target; |
| 2631 | }; | 2641 | }; |
| 2632 | 2642 | ||
| 2643 | struct IrInstructionIntCast { | ||
| 2644 | IrInstruction base; | ||
| 2645 | |||
| 2646 | IrInstruction *dest_type; | ||
| 2647 | IrInstruction *target; | ||
| 2648 | }; | ||
| 2649 | |||
| 2650 | struct IrInstructionFloatCast { | ||
| 2651 | IrInstruction base; | ||
| 2652 | |||
| 2653 | IrInstruction *dest_type; | ||
| 2654 | IrInstruction *target; | ||
| 2655 | }; | ||
| 2656 | |||
| 2657 | struct IrInstructionIntToFloat { | ||
| 2658 | IrInstruction base; | ||
| 2659 | |||
| 2660 | IrInstruction *dest_type; | ||
| 2661 | IrInstruction *target; | ||
| 2662 | }; | ||
| 2663 | |||
| 2664 | struct IrInstructionFloatToInt { | ||
| 2665 | IrInstruction base; | ||
| 2666 | |||
| 2667 | IrInstruction *dest_type; | ||
| 2668 | IrInstruction *target; | ||
| 2669 | }; | ||
| 2670 | |||
| 2671 | struct IrInstructionBoolToInt { | ||
| 2672 | IrInstruction base; | ||
| 2673 | |||
| 2674 | IrInstruction *target; | ||
| 2675 | }; | ||
| 2676 | |||
| 2633 | struct IrInstructionIntType { | 2677 | struct IrInstructionIntType { |
| 2634 | IrInstruction base; | 2678 | IrInstruction base; |
| 2635 | 2679 |
src/analyze.cpp+5-7| ... | @@ -1022,6 +1022,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { | ... | @@ -1022,6 +1022,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 1022 | ensure_complete_type(g, fn_type_id->return_type); | 1022 | ensure_complete_type(g, fn_type_id->return_type); |
| 1023 | if (type_is_invalid(fn_type_id->return_type)) | 1023 | if (type_is_invalid(fn_type_id->return_type)) |
| 1024 | return g->builtin_types.entry_invalid; | 1024 | return g->builtin_types.entry_invalid; |
| 1025 | assert(fn_type_id->return_type->id != TypeTableEntryIdOpaque); | ||
| 1025 | } else { | 1026 | } else { |
| 1026 | zig_panic("TODO implement inferred return types https://github.com/ziglang/zig/issues/447"); | 1027 | zig_panic("TODO implement inferred return types https://github.com/ziglang/zig/issues/447"); |
| 1027 | } | 1028 | } |
| ... | @@ -1135,7 +1136,10 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { | ... | @@ -1135,7 +1136,10 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 1135 | gen_param_info->src_index = i; | 1136 | gen_param_info->src_index = i; |
| 1136 | gen_param_info->gen_index = SIZE_MAX; | 1137 | gen_param_info->gen_index = SIZE_MAX; |
| 1137 | 1138 | ||
| 1138 | type_ensure_zero_bits_known(g, type_entry); | 1139 | ensure_complete_type(g, type_entry); |
| 1140 | if (type_is_invalid(type_entry)) | ||
| 1141 | return g->builtin_types.entry_invalid; | ||
| 1142 | |||
| 1139 | if (type_has_bits(type_entry)) { | 1143 | if (type_has_bits(type_entry)) { |
| 1140 | TypeTableEntry *gen_type; | 1144 | TypeTableEntry *gen_type; |
| 1141 | if (handle_is_ptr(type_entry)) { | 1145 | if (handle_is_ptr(type_entry)) { |
| ... | @@ -1546,12 +1550,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c | ... | @@ -1546,12 +1550,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c |
| 1546 | case TypeTableEntryIdUnion: | 1550 | case TypeTableEntryIdUnion: |
| 1547 | case TypeTableEntryIdFn: | 1551 | case TypeTableEntryIdFn: |
| 1548 | case TypeTableEntryIdPromise: | 1552 | case TypeTableEntryIdPromise: |
| 1549 | ensure_complete_type(g, type_entry); | ||
| 1550 | if (calling_convention_allows_zig_types(fn_type_id.cc) && !type_is_copyable(g, type_entry)) { | ||
| 1551 | add_node_error(g, param_node->data.param_decl.type, | ||
| 1552 | buf_sprintf("type '%s' is not copyable; cannot pass by value", buf_ptr(&type_entry->name))); | ||
| 1553 | return g->builtin_types.entry_invalid; | ||
| 1554 | } | ||
| 1555 | break; | 1553 | break; |
| 1556 | } | 1554 | } |
| 1557 | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; | 1555 | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; |
src/codegen.cpp+16-31| ... | @@ -326,17 +326,6 @@ static void addLLVMArgAttr(LLVMValueRef fn_val, unsigned param_index, const char | ... | @@ -326,17 +326,6 @@ static void addLLVMArgAttr(LLVMValueRef fn_val, unsigned param_index, const char |
| 326 | return addLLVMAttr(fn_val, param_index + 1, attr_name); | 326 | return addLLVMAttr(fn_val, param_index + 1, attr_name); |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | //static void addLLVMArgAttrInt(LLVMValueRef fn_val, unsigned param_index, const char *attr_name, uint64_t attr_val) { | ||
| 330 | // return addLLVMAttrInt(fn_val, param_index + 1, attr_name, attr_val); | ||
| 331 | //} | ||
| 332 | |||
| 333 | static void addLLVMCallsiteAttr(LLVMValueRef call_instr, unsigned param_index, const char *attr_name) { | ||
| 334 | unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); | ||
| 335 | assert(kind_id != 0); | ||
| 336 | LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), kind_id, 0); | ||
| 337 | LLVMAddCallSiteAttribute(call_instr, param_index + 1, llvm_attr); | ||
| 338 | } | ||
| 339 | |||
| 340 | static bool is_symbol_available(CodeGen *g, Buf *name) { | 329 | static bool is_symbol_available(CodeGen *g, Buf *name) { |
| 341 | return g->exported_symbol_names.maybe_get(name) == nullptr && g->external_prototypes.maybe_get(name) == nullptr; | 330 | return g->exported_symbol_names.maybe_get(name) == nullptr && g->external_prototypes.maybe_get(name) == nullptr; |
| 342 | } | 331 | } |
| ... | @@ -585,11 +574,6 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { | ... | @@ -585,11 +574,6 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 585 | if (param_type->id == TypeTableEntryIdPointer) { | 574 | if (param_type->id == TypeTableEntryIdPointer) { |
| 586 | addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull"); | 575 | addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull"); |
| 587 | } | 576 | } |
| 588 | // Note: byval is disabled on windows due to an LLVM bug: | ||
| 589 | // https://github.com/ziglang/zig/issues/536 | ||
| 590 | if (is_byval && g->zig_target.os != OsWindows) { | ||
| 591 | addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval"); | ||
| 592 | } | ||
| 593 | } | 577 | } |
| 594 | 578 | ||
| 595 | uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry); | 579 | uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry); |
| ... | @@ -3053,15 +3037,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -3053,15 +3037,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3053 | } | 3037 | } |
| 3054 | 3038 | ||
| 3055 | 3039 | ||
| 3056 | for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) { | ||
| 3057 | FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; | ||
| 3058 | // Note: byval is disabled on windows due to an LLVM bug: | ||
| 3059 | // https://github.com/ziglang/zig/issues/536 | ||
| 3060 | if (gen_info->is_byval && g->zig_target.os != OsWindows) { | ||
| 3061 | addLLVMCallsiteAttr(result, (unsigned)gen_info->gen_index, "byval"); | ||
| 3062 | } | ||
| 3063 | } | ||
| 3064 | |||
| 3065 | if (instruction->is_async) { | 3040 | if (instruction->is_async) { |
| 3066 | LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, ""); | 3041 | LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, ""); |
| 3067 | LLVMBuildStore(g->builder, result, payload_ptr); | 3042 | LLVMBuildStore(g->builder, result, payload_ptr); |
| ... | @@ -4658,6 +4633,11 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -4658,6 +4633,11 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 4658 | case IrInstructionIdPromiseResultType: | 4633 | case IrInstructionIdPromiseResultType: |
| 4659 | case IrInstructionIdAwaitBookkeeping: | 4634 | case IrInstructionIdAwaitBookkeeping: |
| 4660 | case IrInstructionIdAddImplicitReturnType: | 4635 | case IrInstructionIdAddImplicitReturnType: |
| 4636 | case IrInstructionIdIntCast: | ||
| 4637 | case IrInstructionIdFloatCast: | ||
| 4638 | case IrInstructionIdIntToFloat: | ||
| 4639 | case IrInstructionIdFloatToInt: | ||
| 4640 | case IrInstructionIdBoolToInt: | ||
| 4661 | zig_unreachable(); | 4641 | zig_unreachable(); |
| 4662 | 4642 | ||
| 4663 | case IrInstructionIdReturn: | 4643 | case IrInstructionIdReturn: |
| ... | @@ -6246,6 +6226,11 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -6246,6 +6226,11 @@ static void define_builtin_fns(CodeGen *g) { |
| 6246 | create_builtin_fn(g, BuiltinFnIdCmpxchgStrong, "cmpxchgStrong", 6); | 6226 | create_builtin_fn(g, BuiltinFnIdCmpxchgStrong, "cmpxchgStrong", 6); |
| 6247 | create_builtin_fn(g, BuiltinFnIdFence, "fence", 1); | 6227 | create_builtin_fn(g, BuiltinFnIdFence, "fence", 1); |
| 6248 | create_builtin_fn(g, BuiltinFnIdTruncate, "truncate", 2); | 6228 | create_builtin_fn(g, BuiltinFnIdTruncate, "truncate", 2); |
| 6229 | create_builtin_fn(g, BuiltinFnIdIntCast, "intCast", 2); | ||
| 6230 | create_builtin_fn(g, BuiltinFnIdFloatCast, "floatCast", 2); | ||
| 6231 | create_builtin_fn(g, BuiltinFnIdIntToFloat, "intToFloat", 2); | ||
| 6232 | create_builtin_fn(g, BuiltinFnIdFloatToInt, "floatToInt", 2); | ||
| 6233 | create_builtin_fn(g, BuiltinFnIdBoolToInt, "boolToInt", 1); | ||
| 6249 | create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); | 6234 | create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); |
| 6250 | create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); | 6235 | create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); |
| 6251 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int | 6236 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int |
| ... | @@ -6683,7 +6668,7 @@ static void define_builtin_compile_vars(CodeGen *g) { | ... | @@ -6683,7 +6668,7 @@ static void define_builtin_compile_vars(CodeGen *g) { |
| 6683 | int err; | 6668 | int err; |
| 6684 | Buf *abs_full_path = buf_alloc(); | 6669 | Buf *abs_full_path = buf_alloc(); |
| 6685 | if ((err = os_path_real(builtin_zig_path, abs_full_path))) { | 6670 | if ((err = os_path_real(builtin_zig_path, abs_full_path))) { |
| 6686 | fprintf(stderr, "unable to open '%s': %s", buf_ptr(builtin_zig_path), err_str(err)); | 6671 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err)); |
| 6687 | exit(1); | 6672 | exit(1); |
| 6688 | } | 6673 | } |
| 6689 | 6674 | ||
| ... | @@ -6851,11 +6836,11 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package | ... | @@ -6851,11 +6836,11 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package |
| 6851 | Buf *abs_full_path = buf_alloc(); | 6836 | Buf *abs_full_path = buf_alloc(); |
| 6852 | int err; | 6837 | int err; |
| 6853 | if ((err = os_path_real(&path_to_code_src, abs_full_path))) { | 6838 | if ((err = os_path_real(&path_to_code_src, abs_full_path))) { |
| 6854 | zig_panic("unable to open '%s': %s", buf_ptr(&path_to_code_src), err_str(err)); | 6839 | zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err)); |
| 6855 | } | 6840 | } |
| 6856 | Buf *import_code = buf_alloc(); | 6841 | Buf *import_code = buf_alloc(); |
| 6857 | if ((err = os_fetch_file_path(abs_full_path, import_code, false))) { | 6842 | if ((err = os_fetch_file_path(abs_full_path, import_code, false))) { |
| 6858 | zig_panic("unable to open '%s': %s", buf_ptr(&path_to_code_src), err_str(err)); | 6843 | zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err)); |
| 6859 | } | 6844 | } |
| 6860 | 6845 | ||
| 6861 | return add_source_file(g, package, abs_full_path, import_code); | 6846 | return add_source_file(g, package, abs_full_path, import_code); |
| ... | @@ -6939,13 +6924,13 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -6939,13 +6924,13 @@ static void gen_root_source(CodeGen *g) { |
| 6939 | Buf *abs_full_path = buf_alloc(); | 6924 | Buf *abs_full_path = buf_alloc(); |
| 6940 | int err; | 6925 | int err; |
| 6941 | if ((err = os_path_real(rel_full_path, abs_full_path))) { | 6926 | if ((err = os_path_real(rel_full_path, abs_full_path))) { |
| 6942 | fprintf(stderr, "unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err)); | 6927 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(rel_full_path), err_str(err)); |
| 6943 | exit(1); | 6928 | exit(1); |
| 6944 | } | 6929 | } |
| 6945 | 6930 | ||
| 6946 | Buf *source_code = buf_alloc(); | 6931 | Buf *source_code = buf_alloc(); |
| 6947 | if ((err = os_fetch_file_path(rel_full_path, source_code, true))) { | 6932 | if ((err = os_fetch_file_path(rel_full_path, source_code, true))) { |
| 6948 | fprintf(stderr, "unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err)); | 6933 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(rel_full_path), err_str(err)); |
| 6949 | exit(1); | 6934 | exit(1); |
| 6950 | } | 6935 | } |
| 6951 | 6936 | ||
| ... | @@ -7289,7 +7274,7 @@ static void gen_h_file(CodeGen *g) { | ... | @@ -7289,7 +7274,7 @@ static void gen_h_file(CodeGen *g) { |
| 7289 | 7274 | ||
| 7290 | FILE *out_h = fopen(buf_ptr(g->out_h_path), "wb"); | 7275 | FILE *out_h = fopen(buf_ptr(g->out_h_path), "wb"); |
| 7291 | if (!out_h) | 7276 | if (!out_h) |
| 7292 | zig_panic("unable to open %s: %s", buf_ptr(g->out_h_path), strerror(errno)); | 7277 | zig_panic("unable to open %s: %s\n", buf_ptr(g->out_h_path), strerror(errno)); |
| 7293 | 7278 | ||
| 7294 | Buf *export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name))); | 7279 | Buf *export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name))); |
| 7295 | buf_upcase(export_macro); | 7280 | buf_upcase(export_macro); |
src/ir.cpp+366-50| ... | @@ -460,6 +460,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) { | ... | @@ -460,6 +460,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) { |
| 460 | return IrInstructionIdTruncate; | 460 | return IrInstructionIdTruncate; |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) { | ||
| 464 | return IrInstructionIdIntCast; | ||
| 465 | } | ||
| 466 | |||
| 467 | static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { | ||
| 468 | return IrInstructionIdFloatCast; | ||
| 469 | } | ||
| 470 | |||
| 471 | static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { | ||
| 472 | return IrInstructionIdIntToFloat; | ||
| 473 | } | ||
| 474 | |||
| 475 | static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) { | ||
| 476 | return IrInstructionIdFloatToInt; | ||
| 477 | } | ||
| 478 | |||
| 479 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) { | ||
| 480 | return IrInstructionIdBoolToInt; | ||
| 481 | } | ||
| 482 | |||
| 463 | static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { | 483 | static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { |
| 464 | return IrInstructionIdIntType; | 484 | return IrInstructionIdIntType; |
| 465 | } | 485 | } |
| ... | @@ -1899,10 +1919,57 @@ static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *s | ... | @@ -1899,10 +1919,57 @@ static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *s |
| 1899 | return &instruction->base; | 1919 | return &instruction->base; |
| 1900 | } | 1920 | } |
| 1901 | 1921 | ||
| 1902 | static IrInstruction *ir_build_truncate_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *dest_type, IrInstruction *target) { | 1922 | static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { |
| 1903 | IrInstruction *new_instruction = ir_build_truncate(irb, old_instruction->scope, old_instruction->source_node, dest_type, target); | 1923 | IrInstructionIntCast *instruction = ir_build_instruction<IrInstructionIntCast>(irb, scope, source_node); |
| 1904 | ir_link_new_instruction(new_instruction, old_instruction); | 1924 | instruction->dest_type = dest_type; |
| 1905 | return new_instruction; | 1925 | instruction->target = target; |
| 1926 | |||
| 1927 | ir_ref_instruction(dest_type, irb->current_basic_block); | ||
| 1928 | ir_ref_instruction(target, irb->current_basic_block); | ||
| 1929 | |||
| 1930 | return &instruction->base; | ||
| 1931 | } | ||
| 1932 | |||
| 1933 | static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { | ||
| 1934 | IrInstructionFloatCast *instruction = ir_build_instruction<IrInstructionFloatCast>(irb, scope, source_node); | ||
| 1935 | instruction->dest_type = dest_type; | ||
| 1936 | instruction->target = target; | ||
| 1937 | |||
| 1938 | ir_ref_instruction(dest_type, irb->current_basic_block); | ||
| 1939 | ir_ref_instruction(target, irb->current_basic_block); | ||
| 1940 | |||
| 1941 | return &instruction->base; | ||
| 1942 | } | ||
| 1943 | |||
| 1944 | static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { | ||
| 1945 | IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node); | ||
| 1946 | instruction->dest_type = dest_type; | ||
| 1947 | instruction->target = target; | ||
| 1948 | |||
| 1949 | ir_ref_instruction(dest_type, irb->current_basic_block); | ||
| 1950 | ir_ref_instruction(target, irb->current_basic_block); | ||
| 1951 | |||
| 1952 | return &instruction->base; | ||
| 1953 | } | ||
| 1954 | |||
| 1955 | static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { | ||
| 1956 | IrInstructionFloatToInt *instruction = ir_build_instruction<IrInstructionFloatToInt>(irb, scope, source_node); | ||
| 1957 | instruction->dest_type = dest_type; | ||
| 1958 | instruction->target = target; | ||
| 1959 | |||
| 1960 | ir_ref_instruction(dest_type, irb->current_basic_block); | ||
| 1961 | ir_ref_instruction(target, irb->current_basic_block); | ||
| 1962 | |||
| 1963 | return &instruction->base; | ||
| 1964 | } | ||
| 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; | ||
| 1906 | } | 1973 | } |
| 1907 | 1974 | ||
| 1908 | 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) { |
| ... | @@ -3957,6 +4024,76 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -3957,6 +4024,76 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 3957 | IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); | 4024 | IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); |
| 3958 | return ir_lval_wrap(irb, scope, truncate, lval); | 4025 | return ir_lval_wrap(irb, scope, truncate, lval); |
| 3959 | } | 4026 | } |
| 4027 | case BuiltinFnIdIntCast: | ||
| 4028 | { | ||
| 4029 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4030 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4031 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4032 | return arg0_value; | ||
| 4033 | |||
| 4034 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 4035 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 4036 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 4037 | return arg1_value; | ||
| 4038 | |||
| 4039 | IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); | ||
| 4040 | return ir_lval_wrap(irb, scope, result, lval); | ||
| 4041 | } | ||
| 4042 | case BuiltinFnIdFloatCast: | ||
| 4043 | { | ||
| 4044 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4045 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4046 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4047 | return arg0_value; | ||
| 4048 | |||
| 4049 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 4050 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 4051 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 4052 | return arg1_value; | ||
| 4053 | |||
| 4054 | IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); | ||
| 4055 | return ir_lval_wrap(irb, scope, result, lval); | ||
| 4056 | } | ||
| 4057 | case BuiltinFnIdIntToFloat: | ||
| 4058 | { | ||
| 4059 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4060 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4061 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4062 | return arg0_value; | ||
| 4063 | |||
| 4064 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 4065 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 4066 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 4067 | return arg1_value; | ||
| 4068 | |||
| 4069 | IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); | ||
| 4070 | return ir_lval_wrap(irb, scope, result, lval); | ||
| 4071 | } | ||
| 4072 | case BuiltinFnIdFloatToInt: | ||
| 4073 | { | ||
| 4074 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4075 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4076 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4077 | return arg0_value; | ||
| 4078 | |||
| 4079 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 4080 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 4081 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 4082 | return arg1_value; | ||
| 4083 | |||
| 4084 | IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); | ||
| 4085 | return ir_lval_wrap(irb, scope, result, lval); | ||
| 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 | } | ||
| 3960 | case BuiltinFnIdIntType: | 4097 | case BuiltinFnIdIntType: |
| 3961 | { | 4098 | { |
| 3962 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4099 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -9941,41 +10078,37 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -9941,41 +10078,37 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 9941 | 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); |
| 9942 | } | 10079 | } |
| 9943 | 10080 | ||
| 9944 | // explicit cast from bool to int | 10081 | // explicit widening conversion |
| 9945 | if (wanted_type->id == TypeTableEntryIdInt && | 10082 | if (wanted_type->id == TypeTableEntryIdInt && |
| 9946 | actual_type->id == TypeTableEntryIdBool) | 10083 | actual_type->id == TypeTableEntryIdInt && |
| 9947 | { | 10084 | wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && |
| 9948 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBoolToInt, false); | 10085 | wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) |
| 9949 | } | ||
| 9950 | |||
| 9951 | // explicit widening or shortening cast | ||
| 9952 | if ((wanted_type->id == TypeTableEntryIdInt && | ||
| 9953 | actual_type->id == TypeTableEntryIdInt) || | ||
| 9954 | (wanted_type->id == TypeTableEntryIdFloat && | ||
| 9955 | actual_type->id == TypeTableEntryIdFloat)) | ||
| 9956 | { | 10086 | { |
| 9957 | return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); | 10087 | return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); |
| 9958 | } | 10088 | } |
| 9959 | 10089 | ||
| 9960 | // explicit error set cast | 10090 | // small enough unsigned ints can get casted to large enough signed ints |
| 9961 | if (wanted_type->id == TypeTableEntryIdErrorSet && | 10091 | if (wanted_type->id == TypeTableEntryIdInt && wanted_type->data.integral.is_signed && |
| 9962 | actual_type->id == TypeTableEntryIdErrorSet) | 10092 | actual_type->id == TypeTableEntryIdInt && !actual_type->data.integral.is_signed && |
| 10093 | wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) | ||
| 9963 | { | 10094 | { |
| 9964 | return ir_analyze_err_set_cast(ira, source_instr, value, wanted_type); | 10095 | return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); |
| 9965 | } | 10096 | } |
| 9966 | 10097 | ||
| 9967 | // explicit cast from int to float | 10098 | // explicit float widening conversion |
| 9968 | if (wanted_type->id == TypeTableEntryIdFloat && | 10099 | if (wanted_type->id == TypeTableEntryIdFloat && |
| 9969 | actual_type->id == TypeTableEntryIdInt) | 10100 | actual_type->id == TypeTableEntryIdFloat && |
| 10101 | wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) | ||
| 9970 | { | 10102 | { |
| 9971 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToFloat, false); | 10103 | return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); |
| 9972 | } | 10104 | } |
| 9973 | 10105 | ||
| 9974 | // explicit cast from float to int | 10106 | |
| 9975 | if (wanted_type->id == TypeTableEntryIdInt && | 10107 | // explicit error set cast |
| 9976 | actual_type->id == TypeTableEntryIdFloat) | 10108 | if (wanted_type->id == TypeTableEntryIdErrorSet && |
| 10109 | actual_type->id == TypeTableEntryIdErrorSet) | ||
| 9977 | { | 10110 | { |
| 9978 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpFloatToInt, false); | 10111 | return ir_analyze_err_set_cast(ira, source_instr, value, wanted_type); |
| 9979 | } | 10112 | } |
| 9980 | 10113 | ||
| 9981 | // explicit cast from [N]T to []const T | 10114 | // explicit cast from [N]T to []const T |
| ... | @@ -10463,13 +10596,6 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ | ... | @@ -10463,13 +10596,6 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ |
| 10463 | zig_unreachable(); | 10596 | zig_unreachable(); |
| 10464 | } | 10597 | } |
| 10465 | 10598 | ||
| 10466 | static IrInstruction *ir_implicit_byval_const_ref_cast(IrAnalyze *ira, IrInstruction *inst) { | ||
| 10467 | if (type_is_copyable(ira->codegen, inst->value.type)) | ||
| 10468 | return inst; | ||
| 10469 | TypeTableEntry *const_ref_type = get_pointer_to_type(ira->codegen, inst->value.type, true); | ||
| 10470 | return ir_implicit_cast(ira, inst, const_ref_type); | ||
| 10471 | } | ||
| 10472 | |||
| 10473 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { | 10599 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { |
| 10474 | TypeTableEntry *type_entry = ptr->value.type; | 10600 | TypeTableEntry *type_entry = ptr->value.type; |
| 10475 | if (type_is_invalid(type_entry)) { | 10601 | if (type_is_invalid(type_entry)) { |
| ... | @@ -12283,7 +12409,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod | ... | @@ -12283,7 +12409,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 12283 | IrInstruction *casted_arg; | 12409 | IrInstruction *casted_arg; |
| 12284 | if (is_var_args) { | 12410 | if (is_var_args) { |
| 12285 | arg_part_of_generic_id = true; | 12411 | arg_part_of_generic_id = true; |
| 12286 | casted_arg = ir_implicit_byval_const_ref_cast(ira, arg); | 12412 | casted_arg = arg; |
| 12287 | } else { | 12413 | } else { |
| 12288 | if (param_decl_node->data.param_decl.var_token == nullptr) { | 12414 | if (param_decl_node->data.param_decl.var_token == nullptr) { |
| 12289 | AstNode *param_type_node = param_decl_node->data.param_decl.type; | 12415 | AstNode *param_type_node = param_decl_node->data.param_decl.type; |
| ... | @@ -12296,7 +12422,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod | ... | @@ -12296,7 +12422,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 12296 | return false; | 12422 | return false; |
| 12297 | } else { | 12423 | } else { |
| 12298 | arg_part_of_generic_id = true; | 12424 | arg_part_of_generic_id = true; |
| 12299 | casted_arg = ir_implicit_byval_const_ref_cast(ira, arg); | 12425 | casted_arg = arg; |
| 12300 | } | 12426 | } |
| 12301 | } | 12427 | } |
| 12302 | 12428 | ||
| ... | @@ -12515,9 +12641,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -12515,9 +12641,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 12515 | 12641 | ||
| 12516 | size_t next_proto_i = 0; | 12642 | size_t next_proto_i = 0; |
| 12517 | if (first_arg_ptr) { | 12643 | if (first_arg_ptr) { |
| 12518 | IrInstruction *first_arg; | ||
| 12519 | assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer); | 12644 | assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer); |
| 12520 | if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { | 12645 | |
| 12646 | bool first_arg_known_bare = false; | ||
| 12647 | if (fn_type_id->next_param_index >= 1) { | ||
| 12648 | TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type; | ||
| 12649 | if (type_is_invalid(param_type)) | ||
| 12650 | return ira->codegen->builtin_types.entry_invalid; | ||
| 12651 | first_arg_known_bare = param_type->id != TypeTableEntryIdPointer; | ||
| 12652 | } | ||
| 12653 | |||
| 12654 | IrInstruction *first_arg; | ||
| 12655 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { | ||
| 12521 | first_arg = first_arg_ptr; | 12656 | first_arg = first_arg_ptr; |
| 12522 | } else { | 12657 | } else { |
| 12523 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); | 12658 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| ... | @@ -12667,9 +12802,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -12667,9 +12802,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 12667 | size_t next_proto_i = 0; | 12802 | size_t next_proto_i = 0; |
| 12668 | 12803 | ||
| 12669 | if (first_arg_ptr) { | 12804 | if (first_arg_ptr) { |
| 12670 | IrInstruction *first_arg; | ||
| 12671 | assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer); | 12805 | assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer); |
| 12672 | if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { | 12806 | |
| 12807 | bool first_arg_known_bare = false; | ||
| 12808 | if (fn_type_id->next_param_index >= 1) { | ||
| 12809 | TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type; | ||
| 12810 | if (type_is_invalid(param_type)) | ||
| 12811 | return ira->codegen->builtin_types.entry_invalid; | ||
| 12812 | first_arg_known_bare = param_type->id != TypeTableEntryIdPointer; | ||
| 12813 | } | ||
| 12814 | |||
| 12815 | IrInstruction *first_arg; | ||
| 12816 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { | ||
| 12673 | first_arg = first_arg_ptr; | 12817 | first_arg = first_arg_ptr; |
| 12674 | } else { | 12818 | } else { |
| 12675 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); | 12819 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| ... | @@ -12802,10 +12946,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -12802,10 +12946,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 12802 | return ira->codegen->builtin_types.entry_invalid; | 12946 | return ira->codegen->builtin_types.entry_invalid; |
| 12803 | } | 12947 | } |
| 12804 | if (inst_fn_type_id.async_allocator_type == nullptr) { | 12948 | if (inst_fn_type_id.async_allocator_type == nullptr) { |
| 12805 | IrInstruction *casted_inst = ir_implicit_byval_const_ref_cast(ira, uncasted_async_allocator_inst); | 12949 | inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type; |
| 12806 | if (type_is_invalid(casted_inst->value.type)) | ||
| 12807 | return ira->codegen->builtin_types.entry_invalid; | ||
| 12808 | inst_fn_type_id.async_allocator_type = casted_inst->value.type; | ||
| 12809 | } | 12950 | } |
| 12810 | async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type); | 12951 | async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type); |
| 12811 | if (type_is_invalid(async_allocator_inst->value.type)) | 12952 | if (type_is_invalid(async_allocator_inst->value.type)) |
| ... | @@ -12866,9 +13007,16 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -12866,9 +13007,16 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 12866 | IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); | 13007 | IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); |
| 12867 | size_t next_arg_index = 0; | 13008 | size_t next_arg_index = 0; |
| 12868 | if (first_arg_ptr) { | 13009 | if (first_arg_ptr) { |
| 12869 | IrInstruction *first_arg; | ||
| 12870 | assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer); | 13010 | assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer); |
| 12871 | if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { | 13011 | |
| 13012 | TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type; | ||
| 13013 | if (type_is_invalid(param_type)) | ||
| 13014 | return ira->codegen->builtin_types.entry_invalid; | ||
| 13015 | |||
| 13016 | IrInstruction *first_arg; | ||
| 13017 | if (param_type->id == TypeTableEntryIdPointer && | ||
| 13018 | handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) | ||
| 13019 | { | ||
| 12872 | first_arg = first_arg_ptr; | 13020 | first_arg = first_arg_ptr; |
| 12873 | } else { | 13021 | } else { |
| 12874 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); | 13022 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| ... | @@ -12876,10 +13024,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -12876,10 +13024,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 12876 | return ira->codegen->builtin_types.entry_invalid; | 13024 | return ira->codegen->builtin_types.entry_invalid; |
| 12877 | } | 13025 | } |
| 12878 | 13026 | ||
| 12879 | TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type; | ||
| 12880 | if (type_is_invalid(param_type)) | ||
| 12881 | return ira->codegen->builtin_types.entry_invalid; | ||
| 12882 | |||
| 12883 | IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type); | 13027 | IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type); |
| 12884 | if (type_is_invalid(casted_arg->value.type)) | 13028 | if (type_is_invalid(casted_arg->value.type)) |
| 12885 | return ira->codegen->builtin_types.entry_invalid; | 13029 | return ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -17354,10 +17498,162 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc | ... | @@ -17354,10 +17498,162 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc |
| 17354 | return dest_type; | 17498 | return dest_type; |
| 17355 | } | 17499 | } |
| 17356 | 17500 | ||
| 17357 | ir_build_truncate_from(&ira->new_irb, &instruction->base, dest_type_value, target); | 17501 | IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope, |
| 17502 | instruction->base.source_node, dest_type_value, target); | ||
| 17503 | ir_link_new_instruction(new_instruction, &instruction->base); | ||
| 17358 | return dest_type; | 17504 | return dest_type; |
| 17359 | } | 17505 | } |
| 17360 | 17506 | ||
| 17507 | static TypeTableEntry *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstructionIntCast *instruction) { | ||
| 17508 | TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); | ||
| 17509 | if (type_is_invalid(dest_type)) | ||
| 17510 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17511 | |||
| 17512 | if (dest_type->id != TypeTableEntryIdInt) { | ||
| 17513 | ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); | ||
| 17514 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17515 | } | ||
| 17516 | |||
| 17517 | IrInstruction *target = instruction->target->other; | ||
| 17518 | if (type_is_invalid(target->value.type)) | ||
| 17519 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17520 | |||
| 17521 | if (target->value.type->id == TypeTableEntryIdComptimeInt) { | ||
| 17522 | if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { | ||
| 17523 | IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, | ||
| 17524 | CastOpNumLitToConcrete, false); | ||
| 17525 | if (type_is_invalid(result->value.type)) | ||
| 17526 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17527 | ir_link_new_instruction(result, &instruction->base); | ||
| 17528 | return dest_type; | ||
| 17529 | } else { | ||
| 17530 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17531 | } | ||
| 17532 | } | ||
| 17533 | |||
| 17534 | if (target->value.type->id != TypeTableEntryIdInt) { | ||
| 17535 | ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", | ||
| 17536 | buf_ptr(&target->value.type->name))); | ||
| 17537 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17538 | } | ||
| 17539 | |||
| 17540 | IrInstruction *result = ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); | ||
| 17541 | if (type_is_invalid(result->value.type)) | ||
| 17542 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17543 | |||
| 17544 | ir_link_new_instruction(result, &instruction->base); | ||
| 17545 | return dest_type; | ||
| 17546 | } | ||
| 17547 | |||
| 17548 | static TypeTableEntry *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstructionFloatCast *instruction) { | ||
| 17549 | TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); | ||
| 17550 | if (type_is_invalid(dest_type)) | ||
| 17551 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17552 | |||
| 17553 | if (dest_type->id != TypeTableEntryIdFloat) { | ||
| 17554 | ir_add_error(ira, instruction->dest_type, | ||
| 17555 | buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); | ||
| 17556 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17557 | } | ||
| 17558 | |||
| 17559 | IrInstruction *target = instruction->target->other; | ||
| 17560 | if (type_is_invalid(target->value.type)) | ||
| 17561 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17562 | |||
| 17563 | if (target->value.type->id == TypeTableEntryIdComptimeInt || | ||
| 17564 | target->value.type->id == TypeTableEntryIdComptimeFloat) | ||
| 17565 | { | ||
| 17566 | if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { | ||
| 17567 | CastOp op; | ||
| 17568 | if (target->value.type->id == TypeTableEntryIdComptimeInt) { | ||
| 17569 | op = CastOpIntToFloat; | ||
| 17570 | } else { | ||
| 17571 | op = CastOpNumLitToConcrete; | ||
| 17572 | } | ||
| 17573 | IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false); | ||
| 17574 | if (type_is_invalid(result->value.type)) | ||
| 17575 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17576 | ir_link_new_instruction(result, &instruction->base); | ||
| 17577 | return dest_type; | ||
| 17578 | } else { | ||
| 17579 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17580 | } | ||
| 17581 | } | ||
| 17582 | |||
| 17583 | if (target->value.type->id != TypeTableEntryIdFloat) { | ||
| 17584 | ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", | ||
| 17585 | buf_ptr(&target->value.type->name))); | ||
| 17586 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17587 | } | ||
| 17588 | |||
| 17589 | IrInstruction *result = ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); | ||
| 17590 | if (type_is_invalid(result->value.type)) | ||
| 17591 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17592 | ir_link_new_instruction(result, &instruction->base); | ||
| 17593 | return dest_type; | ||
| 17594 | } | ||
| 17595 | |||
| 17596 | static TypeTableEntry *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { | ||
| 17597 | TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); | ||
| 17598 | if (type_is_invalid(dest_type)) | ||
| 17599 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17600 | |||
| 17601 | IrInstruction *target = instruction->target->other; | ||
| 17602 | if (type_is_invalid(target->value.type)) | ||
| 17603 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17604 | |||
| 17605 | if (target->value.type->id != TypeTableEntryIdInt && target->value.type->id != TypeTableEntryIdComptimeInt) { | ||
| 17606 | ir_add_error(ira, instruction->target, buf_sprintf("expected int type, found '%s'", | ||
| 17607 | buf_ptr(&target->value.type->name))); | ||
| 17608 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17609 | } | ||
| 17610 | |||
| 17611 | IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false); | ||
| 17612 | ir_link_new_instruction(result, &instruction->base); | ||
| 17613 | return dest_type; | ||
| 17614 | } | ||
| 17615 | |||
| 17616 | static TypeTableEntry *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { | ||
| 17617 | TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); | ||
| 17618 | if (type_is_invalid(dest_type)) | ||
| 17619 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17620 | |||
| 17621 | IrInstruction *target = instruction->target->other; | ||
| 17622 | if (type_is_invalid(target->value.type)) | ||
| 17623 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17624 | |||
| 17625 | IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); | ||
| 17626 | ir_link_new_instruction(result, &instruction->base); | ||
| 17627 | return dest_type; | ||
| 17628 | } | ||
| 17629 | |||
| 17630 | static TypeTableEntry *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) { | ||
| 17631 | IrInstruction *target = instruction->target->other; | ||
| 17632 | if (type_is_invalid(target->value.type)) | ||
| 17633 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17634 | |||
| 17635 | if (target->value.type->id != TypeTableEntryIdBool) { | ||
| 17636 | ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'", | ||
| 17637 | buf_ptr(&target->value.type->name))); | ||
| 17638 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17639 | } | ||
| 17640 | |||
| 17641 | if (instr_is_comptime(target)) { | ||
| 17642 | bool is_true; | ||
| 17643 | if (!ir_resolve_bool(ira, target, &is_true)) | ||
| 17644 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17645 | |||
| 17646 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | ||
| 17647 | bigint_init_unsigned(&out_val->data.x_bigint, is_true ? 1 : 0); | ||
| 17648 | return ira->codegen->builtin_types.entry_num_lit_int; | ||
| 17649 | } | ||
| 17650 | |||
| 17651 | TypeTableEntry *u1_type = get_int_type(ira->codegen, false, 1); | ||
| 17652 | IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false); | ||
| 17653 | ir_link_new_instruction(result, &instruction->base); | ||
| 17654 | return u1_type; | ||
| 17655 | } | ||
| 17656 | |||
| 17361 | static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { | 17657 | static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { |
| 17362 | IrInstruction *is_signed_value = instruction->is_signed->other; | 17658 | IrInstruction *is_signed_value = instruction->is_signed->other; |
| 17363 | bool is_signed; | 17659 | bool is_signed; |
| ... | @@ -18380,6 +18676,11 @@ static TypeTableEntry *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruc | ... | @@ -18380,6 +18676,11 @@ static TypeTableEntry *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruc |
| 18380 | fn_type_id.return_type = ir_resolve_type(ira, return_type_value); | 18676 | fn_type_id.return_type = ir_resolve_type(ira, return_type_value); |
| 18381 | if (type_is_invalid(fn_type_id.return_type)) | 18677 | if (type_is_invalid(fn_type_id.return_type)) |
| 18382 | return ira->codegen->builtin_types.entry_invalid; | 18678 | return ira->codegen->builtin_types.entry_invalid; |
| 18679 | if (fn_type_id.return_type->id == TypeTableEntryIdOpaque) { | ||
| 18680 | ir_add_error(ira, instruction->return_type, | ||
| 18681 | buf_sprintf("return type cannot be opaque")); | ||
| 18682 | return ira->codegen->builtin_types.entry_invalid; | ||
| 18683 | } | ||
| 18383 | 18684 | ||
| 18384 | if (fn_type_id.cc == CallingConventionAsync) { | 18685 | if (fn_type_id.cc == CallingConventionAsync) { |
| 18385 | if (instruction->async_allocator_type_value == nullptr) { | 18686 | if (instruction->async_allocator_type_value == nullptr) { |
| ... | @@ -19888,6 +20189,16 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -19888,6 +20189,16 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 19888 | return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); | 20189 | return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); |
| 19889 | case IrInstructionIdTruncate: | 20190 | case IrInstructionIdTruncate: |
| 19890 | return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction); | 20191 | return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction); |
| 20192 | case IrInstructionIdIntCast: | ||
| 20193 | return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); | ||
| 20194 | case IrInstructionIdFloatCast: | ||
| 20195 | return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); | ||
| 20196 | case IrInstructionIdIntToFloat: | ||
| 20197 | return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); | ||
| 20198 | case IrInstructionIdFloatToInt: | ||
| 20199 | return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); | ||
| 20200 | case IrInstructionIdBoolToInt: | ||
| 20201 | return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); | ||
| 19891 | case IrInstructionIdIntType: | 20202 | case IrInstructionIdIntType: |
| 19892 | return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); | 20203 | return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); |
| 19893 | case IrInstructionIdBoolNot: | 20204 | case IrInstructionIdBoolNot: |
| ... | @@ -20231,6 +20542,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -20231,6 +20542,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 20231 | case IrInstructionIdPromiseResultType: | 20542 | case IrInstructionIdPromiseResultType: |
| 20232 | case IrInstructionIdSqrt: | 20543 | case IrInstructionIdSqrt: |
| 20233 | case IrInstructionIdAtomicLoad: | 20544 | case IrInstructionIdAtomicLoad: |
| 20545 | case IrInstructionIdIntCast: | ||
| 20546 | case IrInstructionIdFloatCast: | ||
| 20547 | case IrInstructionIdIntToFloat: | ||
| 20548 | case IrInstructionIdFloatToInt: | ||
| 20549 | case IrInstructionIdBoolToInt: | ||
| 20234 | return false; | 20550 | return false; |
| 20235 | 20551 | ||
| 20236 | case IrInstructionIdAsm: | 20552 | case IrInstructionIdAsm: |
src/ir_print.cpp+53| ... | @@ -648,6 +648,44 @@ static void ir_print_truncate(IrPrint *irp, IrInstructionTruncate *instruction) | ... | @@ -648,6 +648,44 @@ static void ir_print_truncate(IrPrint *irp, IrInstructionTruncate *instruction) |
| 648 | fprintf(irp->f, ")"); | 648 | fprintf(irp->f, ")"); |
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | static void ir_print_int_cast(IrPrint *irp, IrInstructionIntCast *instruction) { | ||
| 652 | fprintf(irp->f, "@intCast("); | ||
| 653 | ir_print_other_instruction(irp, instruction->dest_type); | ||
| 654 | fprintf(irp->f, ", "); | ||
| 655 | ir_print_other_instruction(irp, instruction->target); | ||
| 656 | fprintf(irp->f, ")"); | ||
| 657 | } | ||
| 658 | |||
| 659 | static void ir_print_float_cast(IrPrint *irp, IrInstructionFloatCast *instruction) { | ||
| 660 | fprintf(irp->f, "@floatCast("); | ||
| 661 | ir_print_other_instruction(irp, instruction->dest_type); | ||
| 662 | fprintf(irp->f, ", "); | ||
| 663 | ir_print_other_instruction(irp, instruction->target); | ||
| 664 | fprintf(irp->f, ")"); | ||
| 665 | } | ||
| 666 | |||
| 667 | static void ir_print_int_to_float(IrPrint *irp, IrInstructionIntToFloat *instruction) { | ||
| 668 | fprintf(irp->f, "@intToFloat("); | ||
| 669 | ir_print_other_instruction(irp, instruction->dest_type); | ||
| 670 | fprintf(irp->f, ", "); | ||
| 671 | ir_print_other_instruction(irp, instruction->target); | ||
| 672 | fprintf(irp->f, ")"); | ||
| 673 | } | ||
| 674 | |||
| 675 | static void ir_print_float_to_int(IrPrint *irp, IrInstructionFloatToInt *instruction) { | ||
| 676 | fprintf(irp->f, "@floatToInt("); | ||
| 677 | ir_print_other_instruction(irp, instruction->dest_type); | ||
| 678 | fprintf(irp->f, ", "); | ||
| 679 | ir_print_other_instruction(irp, instruction->target); | ||
| 680 | fprintf(irp->f, ")"); | ||
| 681 | } | ||
| 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 | |||
| 651 | static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) { | 689 | static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) { |
| 652 | fprintf(irp->f, "@IntType("); | 690 | fprintf(irp->f, "@IntType("); |
| 653 | ir_print_other_instruction(irp, instruction->is_signed); | 691 | ir_print_other_instruction(irp, instruction->is_signed); |
| ... | @@ -1417,6 +1455,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1417,6 +1455,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1417 | case IrInstructionIdTruncate: | 1455 | case IrInstructionIdTruncate: |
| 1418 | ir_print_truncate(irp, (IrInstructionTruncate *)instruction); | 1456 | ir_print_truncate(irp, (IrInstructionTruncate *)instruction); |
| 1419 | break; | 1457 | break; |
| 1458 | case IrInstructionIdIntCast: | ||
| 1459 | ir_print_int_cast(irp, (IrInstructionIntCast *)instruction); | ||
| 1460 | break; | ||
| 1461 | case IrInstructionIdFloatCast: | ||
| 1462 | ir_print_float_cast(irp, (IrInstructionFloatCast *)instruction); | ||
| 1463 | break; | ||
| 1464 | case IrInstructionIdIntToFloat: | ||
| 1465 | ir_print_int_to_float(irp, (IrInstructionIntToFloat *)instruction); | ||
| 1466 | break; | ||
| 1467 | case IrInstructionIdFloatToInt: | ||
| 1468 | ir_print_float_to_int(irp, (IrInstructionFloatToInt *)instruction); | ||
| 1469 | break; | ||
| 1470 | case IrInstructionIdBoolToInt: | ||
| 1471 | ir_print_bool_to_int(irp, (IrInstructionBoolToInt *)instruction); | ||
| 1472 | break; | ||
| 1420 | case IrInstructionIdIntType: | 1473 | case IrInstructionIdIntType: |
| 1421 | ir_print_int_type(irp, (IrInstructionIntType *)instruction); | 1474 | ir_print_int_type(irp, (IrInstructionIntType *)instruction); |
| 1422 | break; | 1475 | break; |
src/link.cpp+2-2| ... | @@ -208,7 +208,7 @@ static Buf *get_dynamic_linker_path(CodeGen *g) { | ... | @@ -208,7 +208,7 @@ static Buf *get_dynamic_linker_path(CodeGen *g) { |
| 208 | static void construct_linker_job_elf(LinkJob *lj) { | 208 | static void construct_linker_job_elf(LinkJob *lj) { |
| 209 | CodeGen *g = lj->codegen; | 209 | CodeGen *g = lj->codegen; |
| 210 | 210 | ||
| 211 | if (lj->link_in_crt) { | 211 | if (g->libc_link_lib != nullptr) { |
| 212 | find_libc_lib_path(g); | 212 | find_libc_lib_path(g); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| ... | @@ -432,7 +432,7 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si | ... | @@ -432,7 +432,7 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si |
| 432 | static void construct_linker_job_coff(LinkJob *lj) { | 432 | static void construct_linker_job_coff(LinkJob *lj) { |
| 433 | CodeGen *g = lj->codegen; | 433 | CodeGen *g = lj->codegen; |
| 434 | 434 | ||
| 435 | if (lj->link_in_crt) { | 435 | if (g->libc_link_lib != nullptr) { |
| 436 | find_libc_lib_path(g); | 436 | find_libc_lib_path(g); |
| 437 | } | 437 | } |
| 438 | 438 |
src/main.cpp+1-1| ... | @@ -34,7 +34,7 @@ static int usage(const char *arg0) { | ... | @@ -34,7 +34,7 @@ static int usage(const char *arg0) { |
| 34 | " --assembly [source] add assembly file to build\n" | 34 | " --assembly [source] add assembly file to build\n" |
| 35 | " --cache-dir [path] override the cache directory\n" | 35 | " --cache-dir [path] override the cache directory\n" |
| 36 | " --color [auto|off|on] enable or disable colored error messages\n" | 36 | " --color [auto|off|on] enable or disable colored error messages\n" |
| 37 | " --emit [filetype] emit a specific file format as compilation output\n" | 37 | " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" |
| 38 | " --enable-timing-info print timing diagnostics\n" | 38 | " --enable-timing-info print timing diagnostics\n" |
| 39 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" | 39 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" |
| 40 | " --name [name] override output name\n" | 40 | " --name [name] override output name\n" |
src/os.cpp+19-2| ... | @@ -989,12 +989,29 @@ int os_self_exe_path(Buf *out_path) { | ... | @@ -989,12 +989,29 @@ int os_self_exe_path(Buf *out_path) { |
| 989 | } | 989 | } |
| 990 | 990 | ||
| 991 | #elif defined(ZIG_OS_DARWIN) | 991 | #elif defined(ZIG_OS_DARWIN) |
| 992 | // How long is the executable's path? | ||
| 992 | uint32_t u32_len = 0; | 993 | uint32_t u32_len = 0; |
| 993 | int ret1 = _NSGetExecutablePath(nullptr, &u32_len); | 994 | int ret1 = _NSGetExecutablePath(nullptr, &u32_len); |
| 994 | assert(ret1 != 0); | 995 | assert(ret1 != 0); |
| 995 | buf_resize(out_path, u32_len); | 996 | |
| 996 | int ret2 = _NSGetExecutablePath(buf_ptr(out_path), &u32_len); | 997 | Buf *tmp = buf_alloc_fixed(u32_len); |
| 998 | |||
| 999 | // Fill the executable path. | ||
| 1000 | int ret2 = _NSGetExecutablePath(buf_ptr(tmp), &u32_len); | ||
| 997 | assert(ret2 == 0); | 1001 | assert(ret2 == 0); |
| 1002 | |||
| 1003 | // According to libuv project, PATH_MAX*2 works around a libc bug where | ||
| 1004 | // the resolved path is sometimes bigger than PATH_MAX. | ||
| 1005 | buf_resize(out_path, PATH_MAX*2); | ||
| 1006 | char *real_path = realpath(buf_ptr(tmp), buf_ptr(out_path)); | ||
| 1007 | if (!real_path) { | ||
| 1008 | buf_init_from_buf(out_path, tmp); | ||
| 1009 | return 0; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | // Resize out_path for the correct length. | ||
| 1013 | buf_resize(out_path, strlen(buf_ptr(out_path))); | ||
| 1014 | |||
| 998 | return 0; | 1015 | return 0; |
| 999 | #elif defined(ZIG_OS_LINUX) | 1016 | #elif defined(ZIG_OS_LINUX) |
| 1000 | buf_resize(out_path, 256); | 1017 | buf_resize(out_path, 256); |
src/target.cpp+35-15| ... | @@ -685,21 +685,41 @@ static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) { | ... | @@ -685,21 +685,41 @@ static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) { |
| 685 | uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | 685 | uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 686 | switch (target->os) { | 686 | switch (target->os) { |
| 687 | case OsFreestanding: | 687 | case OsFreestanding: |
| 688 | switch (id) { | 688 | switch (target->arch.arch) { |
| 689 | case CIntTypeShort: | 689 | case ZigLLVM_msp430: |
| 690 | case CIntTypeUShort: | 690 | switch (id) { |
| 691 | return 16; | 691 | case CIntTypeShort: |
| 692 | case CIntTypeInt: | 692 | case CIntTypeUShort: |
| 693 | case CIntTypeUInt: | 693 | return 16; |
| 694 | return 32; | 694 | case CIntTypeInt: |
| 695 | case CIntTypeLong: | 695 | case CIntTypeUInt: |
| 696 | case CIntTypeULong: | 696 | return 16; |
| 697 | return get_arch_pointer_bit_width(target->arch.arch); | 697 | case CIntTypeLong: |
| 698 | case CIntTypeLongLong: | 698 | case CIntTypeULong: |
| 699 | case CIntTypeULongLong: | 699 | return 32; |
| 700 | return 64; | 700 | case CIntTypeLongLong: |
| 701 | case CIntTypeCount: | 701 | case CIntTypeULongLong: |
| 702 | zig_unreachable(); | 702 | return 64; |
| 703 | case CIntTypeCount: | ||
| 704 | zig_unreachable(); | ||
| 705 | } | ||
| 706 | default: | ||
| 707 | switch (id) { | ||
| 708 | case CIntTypeShort: | ||
| 709 | case CIntTypeUShort: | ||
| 710 | return 16; | ||
| 711 | case CIntTypeInt: | ||
| 712 | case CIntTypeUInt: | ||
| 713 | return 32; | ||
| 714 | case CIntTypeLong: | ||
| 715 | case CIntTypeULong: | ||
| 716 | return get_arch_pointer_bit_width(target->arch.arch); | ||
| 717 | case CIntTypeLongLong: | ||
| 718 | case CIntTypeULongLong: | ||
| 719 | return 64; | ||
| 720 | case CIntTypeCount: | ||
| 721 | zig_unreachable(); | ||
| 722 | } | ||
| 703 | } | 723 | } |
| 704 | case OsLinux: | 724 | case OsLinux: |
| 705 | case OsMacOSX: | 725 | case OsMacOSX: |
std/array_list.zig+17-17| ... | @@ -29,36 +29,36 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { | ... | @@ -29,36 +29,36 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { |
| 29 | }; | 29 | }; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | pub fn deinit(self: *const Self) void { | 32 | pub fn deinit(self: Self) void { |
| 33 | self.allocator.free(self.items); | 33 | self.allocator.free(self.items); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | pub fn toSlice(self: *const Self) []align(A) T { | 36 | pub fn toSlice(self: Self) []align(A) T { |
| 37 | return self.items[0..self.len]; | 37 | return self.items[0..self.len]; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | pub fn toSliceConst(self: *const Self) []align(A) const T { | 40 | pub fn toSliceConst(self: Self) []align(A) const T { |
| 41 | return self.items[0..self.len]; | 41 | return self.items[0..self.len]; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | pub fn at(self: *const Self, n: usize) T { | 44 | pub fn at(self: Self, n: usize) T { |
| 45 | return self.toSliceConst()[n]; | 45 | return self.toSliceConst()[n]; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | /// Sets the value at index `i`, or returns `error.OutOfBounds` if | 48 | /// Sets the value at index `i`, or returns `error.OutOfBounds` if |
| 49 | /// the index is not in range. | 49 | /// the index is not in range. |
| 50 | pub fn setOrError(self: *const Self, i: usize, item: *const T) !void { | 50 | pub fn setOrError(self: Self, i: usize, item: T) !void { |
| 51 | if (i >= self.len) return error.OutOfBounds; | 51 | if (i >= self.len) return error.OutOfBounds; |
| 52 | self.items[i] = item.*; | 52 | self.items[i] = item; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | /// Sets the value at index `i`, asserting that the value is in range. | 55 | /// Sets the value at index `i`, asserting that the value is in range. |
| 56 | pub fn set(self: *const Self, i: usize, item: *const T) void { | 56 | pub fn set(self: *Self, i: usize, item: T) void { |
| 57 | assert(i < self.len); | 57 | assert(i < self.len); |
| 58 | self.items[i] = item.*; | 58 | self.items[i] = item; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | pub fn count(self: *const Self) usize { | 61 | pub fn count(self: Self) usize { |
| 62 | return self.len; | 62 | return self.len; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| ... | @@ -81,12 +81,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { | ... | @@ -81,12 +81,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { |
| 81 | return result; | 81 | return result; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | pub fn insert(self: *Self, n: usize, item: *const T) !void { | 84 | pub fn insert(self: *Self, n: usize, item: T) !void { |
| 85 | try self.ensureCapacity(self.len + 1); | 85 | try self.ensureCapacity(self.len + 1); |
| 86 | self.len += 1; | 86 | self.len += 1; |
| 87 | 87 | ||
| 88 | mem.copy(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]); | 88 | mem.copy(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]); |
| 89 | self.items[n] = item.*; | 89 | self.items[n] = item; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | pub fn insertSlice(self: *Self, n: usize, items: []align(A) const T) !void { | 92 | pub fn insertSlice(self: *Self, n: usize, items: []align(A) const T) !void { |
| ... | @@ -97,9 +97,9 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { | ... | @@ -97,9 +97,9 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { |
| 97 | mem.copy(T, self.items[n .. n + items.len], items); | 97 | mem.copy(T, self.items[n .. n + items.len], items); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | pub fn append(self: *Self, item: *const T) !void { | 100 | pub fn append(self: *Self, item: T) !void { |
| 101 | const new_item_ptr = try self.addOne(); | 101 | const new_item_ptr = try self.addOne(); |
| 102 | new_item_ptr.* = item.*; | 102 | new_item_ptr.* = item; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | pub fn appendSlice(self: *Self, items: []align(A) const T) !void { | 105 | pub fn appendSlice(self: *Self, items: []align(A) const T) !void { |
| ... | @@ -185,23 +185,23 @@ test "basic ArrayList test" { | ... | @@ -185,23 +185,23 @@ test "basic ArrayList test" { |
| 185 | { | 185 | { |
| 186 | var i: usize = 0; | 186 | var i: usize = 0; |
| 187 | while (i < 10) : (i += 1) { | 187 | while (i < 10) : (i += 1) { |
| 188 | list.append(i32(i + 1)) catch unreachable; | 188 | list.append(@intCast(i32, i + 1)) catch unreachable; |
| 189 | } | 189 | } |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | { | 192 | { |
| 193 | var i: usize = 0; | 193 | var i: usize = 0; |
| 194 | while (i < 10) : (i += 1) { | 194 | while (i < 10) : (i += 1) { |
| 195 | assert(list.items[i] == i32(i + 1)); | 195 | assert(list.items[i] == @intCast(i32, i + 1)); |
| 196 | } | 196 | } |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | for (list.toSlice()) |v, i| { | 199 | for (list.toSlice()) |v, i| { |
| 200 | assert(v == i32(i + 1)); | 200 | assert(v == @intCast(i32, i + 1)); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | for (list.toSliceConst()) |v, i| { | 203 | for (list.toSliceConst()) |v, i| { |
| 204 | assert(v == i32(i + 1)); | 204 | assert(v == @intCast(i32, i + 1)); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | assert(list.pop() == 10); | 207 | assert(list.pop() == 10); |
std/base64.zig+2-2| ... | @@ -99,7 +99,7 @@ pub const Base64Decoder = struct { | ... | @@ -99,7 +99,7 @@ pub const Base64Decoder = struct { |
| 99 | assert(!result.char_in_alphabet[c]); | 99 | assert(!result.char_in_alphabet[c]); |
| 100 | assert(c != pad_char); | 100 | assert(c != pad_char); |
| 101 | 101 | ||
| 102 | result.char_to_index[c] = u8(i); | 102 | result.char_to_index[c] = @intCast(u8, i); |
| 103 | result.char_in_alphabet[c] = true; | 103 | result.char_in_alphabet[c] = true; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| ... | @@ -284,7 +284,7 @@ pub const Base64DecoderUnsafe = struct { | ... | @@ -284,7 +284,7 @@ pub const Base64DecoderUnsafe = struct { |
| 284 | }; | 284 | }; |
| 285 | for (alphabet_chars) |c, i| { | 285 | for (alphabet_chars) |c, i| { |
| 286 | assert(c != pad_char); | 286 | assert(c != pad_char); |
| 287 | result.char_to_index[c] = u8(i); | 287 | result.char_to_index[c] = @intCast(u8, i); |
| 288 | } | 288 | } |
| 289 | return result; | 289 | return result; |
| 290 | } | 290 | } |
std/build.zig+1-1| ... | @@ -234,7 +234,7 @@ pub const Builder = struct { | ... | @@ -234,7 +234,7 @@ pub const Builder = struct { |
| 234 | defer wanted_steps.deinit(); | 234 | defer wanted_steps.deinit(); |
| 235 | 235 | ||
| 236 | if (step_names.len == 0) { | 236 | if (step_names.len == 0) { |
| 237 | try wanted_steps.append(&self.default_step); | 237 | try wanted_steps.append(self.default_step); |
| 238 | } else { | 238 | } else { |
| 239 | for (step_names) |step_name| { | 239 | for (step_names) |step_name| { |
| 240 | const s = try self.getTopLevelStepByName(step_name); | 240 | const s = try self.getTopLevelStepByName(step_name); |
std/crypto/blake2.zig+5-5| ... | @@ -79,7 +79,7 @@ fn Blake2s(comptime out_len: usize) type { | ... | @@ -79,7 +79,7 @@ fn Blake2s(comptime out_len: usize) type { |
| 79 | mem.copy(u32, d.h[0..], iv[0..]); | 79 | mem.copy(u32, d.h[0..], iv[0..]); |
| 80 | 80 | ||
| 81 | // No key plus default parameters | 81 | // No key plus default parameters |
| 82 | d.h[0] ^= 0x01010000 ^ u32(out_len >> 3); | 82 | d.h[0] ^= 0x01010000 ^ @intCast(u32, out_len >> 3); |
| 83 | d.t = 0; | 83 | d.t = 0; |
| 84 | d.buf_len = 0; | 84 | d.buf_len = 0; |
| 85 | } | 85 | } |
| ... | @@ -110,7 +110,7 @@ fn Blake2s(comptime out_len: usize) type { | ... | @@ -110,7 +110,7 @@ fn Blake2s(comptime out_len: usize) type { |
| 110 | 110 | ||
| 111 | // Copy any remainder for next pass. | 111 | // Copy any remainder for next pass. |
| 112 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); | 112 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); |
| 113 | d.buf_len += u8(b[off..].len); | 113 | d.buf_len += @intCast(u8, b[off..].len); |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | pub fn final(d: *Self, out: []u8) void { | 116 | pub fn final(d: *Self, out: []u8) void { |
| ... | @@ -144,7 +144,7 @@ fn Blake2s(comptime out_len: usize) type { | ... | @@ -144,7 +144,7 @@ fn Blake2s(comptime out_len: usize) type { |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | v[12] ^= @truncate(u32, d.t); | 146 | v[12] ^= @truncate(u32, d.t); |
| 147 | v[13] ^= u32(d.t >> 32); | 147 | v[13] ^= @intCast(u32, d.t >> 32); |
| 148 | if (last) v[14] = ~v[14]; | 148 | if (last) v[14] = ~v[14]; |
| 149 | 149 | ||
| 150 | const rounds = comptime []RoundParam{ | 150 | const rounds = comptime []RoundParam{ |
| ... | @@ -345,7 +345,7 @@ fn Blake2b(comptime out_len: usize) type { | ... | @@ -345,7 +345,7 @@ fn Blake2b(comptime out_len: usize) type { |
| 345 | 345 | ||
| 346 | // Copy any remainder for next pass. | 346 | // Copy any remainder for next pass. |
| 347 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); | 347 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); |
| 348 | d.buf_len += u8(b[off..].len); | 348 | d.buf_len += @intCast(u8, b[off..].len); |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | pub fn final(d: *Self, out: []u8) void { | 351 | pub fn final(d: *Self, out: []u8) void { |
| ... | @@ -377,7 +377,7 @@ fn Blake2b(comptime out_len: usize) type { | ... | @@ -377,7 +377,7 @@ fn Blake2b(comptime out_len: usize) type { |
| 377 | } | 377 | } |
| 378 | 378 | ||
| 379 | v[12] ^= @truncate(u64, d.t); | 379 | v[12] ^= @truncate(u64, d.t); |
| 380 | v[13] ^= u64(d.t >> 64); | 380 | v[13] ^= @intCast(u64, d.t >> 64); |
| 381 | if (last) v[14] = ~v[14]; | 381 | if (last) v[14] = ~v[14]; |
| 382 | 382 | ||
| 383 | const rounds = comptime []RoundParam{ | 383 | const rounds = comptime []RoundParam{ |
std/crypto/md5.zig+3-3| ... | @@ -78,7 +78,7 @@ pub const Md5 = struct { | ... | @@ -78,7 +78,7 @@ pub const Md5 = struct { |
| 78 | 78 | ||
| 79 | // Copy any remainder for next pass. | 79 | // Copy any remainder for next pass. |
| 80 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); | 80 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); |
| 81 | d.buf_len += u8(b[off..].len); | 81 | d.buf_len += @intCast(u8, b[off..].len); |
| 82 | 82 | ||
| 83 | // Md5 uses the bottom 64-bits for length padding | 83 | // Md5 uses the bottom 64-bits for length padding |
| 84 | d.total_len +%= b.len; | 84 | d.total_len +%= b.len; |
| ... | @@ -103,9 +103,9 @@ pub const Md5 = struct { | ... | @@ -103,9 +103,9 @@ pub const Md5 = struct { |
| 103 | // Append message length. | 103 | // Append message length. |
| 104 | var i: usize = 1; | 104 | var i: usize = 1; |
| 105 | var len = d.total_len >> 5; | 105 | var len = d.total_len >> 5; |
| 106 | d.buf[56] = u8(d.total_len & 0x1f) << 3; | 106 | d.buf[56] = @intCast(u8, d.total_len & 0x1f) << 3; |
| 107 | while (i < 8) : (i += 1) { | 107 | while (i < 8) : (i += 1) { |
| 108 | d.buf[56 + i] = u8(len & 0xff); | 108 | d.buf[56 + i] = @intCast(u8, len & 0xff); |
| 109 | len >>= 8; | 109 | len >>= 8; |
| 110 | } | 110 | } |
| 111 | 111 |
std/crypto/sha1.zig+3-3| ... | @@ -78,7 +78,7 @@ pub const Sha1 = struct { | ... | @@ -78,7 +78,7 @@ pub const Sha1 = struct { |
| 78 | 78 | ||
| 79 | // Copy any remainder for next pass. | 79 | // Copy any remainder for next pass. |
| 80 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); | 80 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); |
| 81 | d.buf_len += u8(b[off..].len); | 81 | d.buf_len += @intCast(u8, b[off..].len); |
| 82 | 82 | ||
| 83 | d.total_len += b.len; | 83 | d.total_len += b.len; |
| 84 | } | 84 | } |
| ... | @@ -102,9 +102,9 @@ pub const Sha1 = struct { | ... | @@ -102,9 +102,9 @@ pub const Sha1 = struct { |
| 102 | // Append message length. | 102 | // Append message length. |
| 103 | var i: usize = 1; | 103 | var i: usize = 1; |
| 104 | var len = d.total_len >> 5; | 104 | var len = d.total_len >> 5; |
| 105 | d.buf[63] = u8(d.total_len & 0x1f) << 3; | 105 | d.buf[63] = @intCast(u8, d.total_len & 0x1f) << 3; |
| 106 | while (i < 8) : (i += 1) { | 106 | while (i < 8) : (i += 1) { |
| 107 | d.buf[63 - i] = u8(len & 0xff); | 107 | d.buf[63 - i] = @intCast(u8, len & 0xff); |
| 108 | len >>= 8; | 108 | len >>= 8; |
| 109 | } | 109 | } |
| 110 | 110 |
std/crypto/sha2.zig+6-6| ... | @@ -131,7 +131,7 @@ fn Sha2_32(comptime params: Sha2Params32) type { | ... | @@ -131,7 +131,7 @@ fn Sha2_32(comptime params: Sha2Params32) type { |
| 131 | 131 | ||
| 132 | // Copy any remainder for next pass. | 132 | // Copy any remainder for next pass. |
| 133 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); | 133 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); |
| 134 | d.buf_len += u8(b[off..].len); | 134 | d.buf_len += @intCast(u8, b[off..].len); |
| 135 | 135 | ||
| 136 | d.total_len += b.len; | 136 | d.total_len += b.len; |
| 137 | } | 137 | } |
| ... | @@ -155,9 +155,9 @@ fn Sha2_32(comptime params: Sha2Params32) type { | ... | @@ -155,9 +155,9 @@ fn Sha2_32(comptime params: Sha2Params32) type { |
| 155 | // Append message length. | 155 | // Append message length. |
| 156 | var i: usize = 1; | 156 | var i: usize = 1; |
| 157 | var len = d.total_len >> 5; | 157 | var len = d.total_len >> 5; |
| 158 | d.buf[63] = u8(d.total_len & 0x1f) << 3; | 158 | d.buf[63] = @intCast(u8, d.total_len & 0x1f) << 3; |
| 159 | while (i < 8) : (i += 1) { | 159 | while (i < 8) : (i += 1) { |
| 160 | d.buf[63 - i] = u8(len & 0xff); | 160 | d.buf[63 - i] = @intCast(u8, len & 0xff); |
| 161 | len >>= 8; | 161 | len >>= 8; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| ... | @@ -472,7 +472,7 @@ fn Sha2_64(comptime params: Sha2Params64) type { | ... | @@ -472,7 +472,7 @@ fn Sha2_64(comptime params: Sha2Params64) type { |
| 472 | 472 | ||
| 473 | // Copy any remainder for next pass. | 473 | // Copy any remainder for next pass. |
| 474 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); | 474 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); |
| 475 | d.buf_len += u8(b[off..].len); | 475 | d.buf_len += @intCast(u8, b[off..].len); |
| 476 | 476 | ||
| 477 | d.total_len += b.len; | 477 | d.total_len += b.len; |
| 478 | } | 478 | } |
| ... | @@ -496,9 +496,9 @@ fn Sha2_64(comptime params: Sha2Params64) type { | ... | @@ -496,9 +496,9 @@ fn Sha2_64(comptime params: Sha2Params64) type { |
| 496 | // Append message length. | 496 | // Append message length. |
| 497 | var i: usize = 1; | 497 | var i: usize = 1; |
| 498 | var len = d.total_len >> 5; | 498 | var len = d.total_len >> 5; |
| 499 | d.buf[127] = u8(d.total_len & 0x1f) << 3; | 499 | d.buf[127] = @intCast(u8, d.total_len & 0x1f) << 3; |
| 500 | while (i < 16) : (i += 1) { | 500 | while (i < 16) : (i += 1) { |
| 501 | d.buf[127 - i] = u8(len & 0xff); | 501 | d.buf[127 - i] = @intCast(u8, len & 0xff); |
| 502 | len >>= 8; | 502 | len >>= 8; |
| 503 | } | 503 | } |
| 504 | 504 |
std/debug/index.zig+5-4| ... | @@ -554,7 +554,7 @@ const LineNumberProgram = struct { | ... | @@ -554,7 +554,7 @@ const LineNumberProgram = struct { |
| 554 | const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name); | 554 | const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name); |
| 555 | errdefer self.file_entries.allocator.free(file_name); | 555 | errdefer self.file_entries.allocator.free(file_name); |
| 556 | return LineInfo{ | 556 | return LineInfo{ |
| 557 | .line = if (self.prev_line >= 0) usize(self.prev_line) else 0, | 557 | .line = if (self.prev_line >= 0) @intCast(usize, self.prev_line) else 0, |
| 558 | .column = self.prev_column, | 558 | .column = self.prev_column, |
| 559 | .file_name = file_name, | 559 | .file_name = file_name, |
| 560 | .allocator = self.file_entries.allocator, | 560 | .allocator = self.file_entries.allocator, |
| ... | @@ -639,6 +639,7 @@ const ParseFormValueError = error{ | ... | @@ -639,6 +639,7 @@ const ParseFormValueError = error{ |
| 639 | Unexpected, | 639 | Unexpected, |
| 640 | InvalidDebugInfo, | 640 | InvalidDebugInfo, |
| 641 | EndOfFile, | 641 | EndOfFile, |
| 642 | IsDir, | ||
| 642 | OutOfMemory, | 643 | OutOfMemory, |
| 643 | }; | 644 | }; |
| 644 | 645 | ||
| ... | @@ -1069,7 +1070,7 @@ fn readULeb128(in_stream: var) !u64 { | ... | @@ -1069,7 +1070,7 @@ fn readULeb128(in_stream: var) !u64 { |
| 1069 | 1070 | ||
| 1070 | var operand: u64 = undefined; | 1071 | var operand: u64 = undefined; |
| 1071 | 1072 | ||
| 1072 | if (@shlWithOverflow(u64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo; | 1073 | if (@shlWithOverflow(u64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo; |
| 1073 | 1074 | ||
| 1074 | result |= operand; | 1075 | result |= operand; |
| 1075 | 1076 | ||
| ... | @@ -1088,13 +1089,13 @@ fn readILeb128(in_stream: var) !i64 { | ... | @@ -1088,13 +1089,13 @@ fn readILeb128(in_stream: var) !i64 { |
| 1088 | 1089 | ||
| 1089 | var operand: i64 = undefined; | 1090 | var operand: i64 = undefined; |
| 1090 | 1091 | ||
| 1091 | if (@shlWithOverflow(i64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo; | 1092 | if (@shlWithOverflow(i64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo; |
| 1092 | 1093 | ||
| 1093 | result |= operand; | 1094 | result |= operand; |
| 1094 | shift += 7; | 1095 | shift += 7; |
| 1095 | 1096 | ||
| 1096 | if ((byte & 0b10000000) == 0) { | 1097 | if ((byte & 0b10000000) == 0) { |
| 1097 | if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << u6(shift)); | 1098 | if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << @intCast(u6, shift)); |
| 1098 | return result; | 1099 | return result; |
| 1099 | } | 1100 | } |
| 1100 | } | 1101 | } |
std/dynamic_library.zig created+156| ... | @@ -0,0 +1,156 @@ | ||
| 1 | const std = @import("index.zig"); | ||
| 2 | const mem = std.mem; | ||
| 3 | const elf = std.elf; | ||
| 4 | const cstr = std.cstr; | ||
| 5 | const linux = std.os.linux; | ||
| 6 | |||
| 7 | pub const DynLib = struct { | ||
| 8 | allocator: *mem.Allocator, | ||
| 9 | elf_lib: ElfLib, | ||
| 10 | fd: i32, | ||
| 11 | map_addr: usize, | ||
| 12 | map_size: usize, | ||
| 13 | |||
| 14 | /// Trusts the file | ||
| 15 | pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib { | ||
| 16 | const fd = try std.os.posixOpen(allocator, path, 0, linux.O_RDONLY | linux.O_CLOEXEC); | ||
| 17 | errdefer std.os.close(fd); | ||
| 18 | |||
| 19 | const size = @intCast(usize, (try std.os.posixFStat(fd)).size); | ||
| 20 | |||
| 21 | const addr = linux.mmap( | ||
| 22 | null, | ||
| 23 | size, | ||
| 24 | linux.PROT_READ | linux.PROT_EXEC, | ||
| 25 | linux.MAP_PRIVATE | linux.MAP_LOCKED, | ||
| 26 | fd, | ||
| 27 | 0, | ||
| 28 | ); | ||
| 29 | errdefer _ = linux.munmap(addr, size); | ||
| 30 | |||
| 31 | const bytes = @intToPtr([*]align(std.os.page_size) u8, addr)[0..size]; | ||
| 32 | |||
| 33 | return DynLib{ | ||
| 34 | .allocator = allocator, | ||
| 35 | .elf_lib = try ElfLib.init(bytes), | ||
| 36 | .fd = fd, | ||
| 37 | .map_addr = addr, | ||
| 38 | .map_size = size, | ||
| 39 | }; | ||
| 40 | } | ||
| 41 | |||
| 42 | pub fn close(self: *DynLib) void { | ||
| 43 | _ = linux.munmap(self.map_addr, self.map_size); | ||
| 44 | std.os.close(self.fd); | ||
| 45 | self.* = undefined; | ||
| 46 | } | ||
| 47 | |||
| 48 | pub fn lookup(self: *DynLib, name: []const u8) ?usize { | ||
| 49 | return self.elf_lib.lookup("", name); | ||
| 50 | } | ||
| 51 | }; | ||
| 52 | |||
| 53 | pub const ElfLib = struct { | ||
| 54 | strings: [*]u8, | ||
| 55 | syms: [*]elf.Sym, | ||
| 56 | hashtab: [*]linux.Elf_Symndx, | ||
| 57 | versym: ?[*]u16, | ||
| 58 | verdef: ?*elf.Verdef, | ||
| 59 | base: usize, | ||
| 60 | |||
| 61 | // Trusts the memory | ||
| 62 | pub fn init(bytes: []align(@alignOf(elf.Ehdr)) u8) !ElfLib { | ||
| 63 | const eh = @ptrCast(*elf.Ehdr, bytes.ptr); | ||
| 64 | if (!mem.eql(u8, eh.e_ident[0..4], "\x7fELF")) return error.NotElfFile; | ||
| 65 | if (eh.e_type != elf.ET_DYN) return error.NotDynamicLibrary; | ||
| 66 | |||
| 67 | const elf_addr = @ptrToInt(bytes.ptr); | ||
| 68 | var ph_addr: usize = elf_addr + eh.e_phoff; | ||
| 69 | |||
| 70 | var base: usize = @maxValue(usize); | ||
| 71 | var maybe_dynv: ?[*]usize = null; | ||
| 72 | { | ||
| 73 | var i: usize = 0; | ||
| 74 | while (i < eh.e_phnum) : ({ | ||
| 75 | i += 1; | ||
| 76 | ph_addr += eh.e_phentsize; | ||
| 77 | }) { | ||
| 78 | const ph = @intToPtr(*elf.Phdr, ph_addr); | ||
| 79 | switch (ph.p_type) { | ||
| 80 | elf.PT_LOAD => base = elf_addr + ph.p_offset - ph.p_vaddr, | ||
| 81 | elf.PT_DYNAMIC => maybe_dynv = @intToPtr([*]usize, elf_addr + ph.p_offset), | ||
| 82 | else => {}, | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | ||
| 86 | const dynv = maybe_dynv orelse return error.MissingDynamicLinkingInformation; | ||
| 87 | if (base == @maxValue(usize)) return error.BaseNotFound; | ||
| 88 | |||
| 89 | var maybe_strings: ?[*]u8 = null; | ||
| 90 | var maybe_syms: ?[*]elf.Sym = null; | ||
| 91 | var maybe_hashtab: ?[*]linux.Elf_Symndx = null; | ||
| 92 | var maybe_versym: ?[*]u16 = null; | ||
| 93 | var maybe_verdef: ?*elf.Verdef = null; | ||
| 94 | |||
| 95 | { | ||
| 96 | var i: usize = 0; | ||
| 97 | while (dynv[i] != 0) : (i += 2) { | ||
| 98 | const p = base + dynv[i + 1]; | ||
| 99 | switch (dynv[i]) { | ||
| 100 | elf.DT_STRTAB => maybe_strings = @intToPtr([*]u8, p), | ||
| 101 | elf.DT_SYMTAB => maybe_syms = @intToPtr([*]elf.Sym, p), | ||
| 102 | elf.DT_HASH => maybe_hashtab = @intToPtr([*]linux.Elf_Symndx, p), | ||
| 103 | elf.DT_VERSYM => maybe_versym = @intToPtr([*]u16, p), | ||
| 104 | elf.DT_VERDEF => maybe_verdef = @intToPtr(*elf.Verdef, p), | ||
| 105 | else => {}, | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | return ElfLib{ | ||
| 111 | .base = base, | ||
| 112 | .strings = maybe_strings orelse return error.ElfStringSectionNotFound, | ||
| 113 | .syms = maybe_syms orelse return error.ElfSymSectionNotFound, | ||
| 114 | .hashtab = maybe_hashtab orelse return error.ElfHashTableNotFound, | ||
| 115 | .versym = maybe_versym, | ||
| 116 | .verdef = maybe_verdef, | ||
| 117 | }; | ||
| 118 | } | ||
| 119 | |||
| 120 | /// Returns the address of the symbol | ||
| 121 | pub fn lookup(self: *const ElfLib, vername: []const u8, name: []const u8) ?usize { | ||
| 122 | const maybe_versym = if (self.verdef == null) null else self.versym; | ||
| 123 | |||
| 124 | const OK_TYPES = (1 << elf.STT_NOTYPE | 1 << elf.STT_OBJECT | 1 << elf.STT_FUNC | 1 << elf.STT_COMMON); | ||
| 125 | const OK_BINDS = (1 << elf.STB_GLOBAL | 1 << elf.STB_WEAK | 1 << elf.STB_GNU_UNIQUE); | ||
| 126 | |||
| 127 | var i: usize = 0; | ||
| 128 | while (i < self.hashtab[1]) : (i += 1) { | ||
| 129 | if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info & 0xf) & OK_TYPES)) continue; | ||
| 130 | if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info >> 4) & OK_BINDS)) continue; | ||
| 131 | if (0 == self.syms[i].st_shndx) continue; | ||
| 132 | if (!mem.eql(u8, name, cstr.toSliceConst(self.strings + self.syms[i].st_name))) continue; | ||
| 133 | if (maybe_versym) |versym| { | ||
| 134 | if (!checkver(self.verdef.?, versym[i], vername, self.strings)) | ||
| 135 | continue; | ||
| 136 | } | ||
| 137 | return self.base + self.syms[i].st_value; | ||
| 138 | } | ||
| 139 | |||
| 140 | return null; | ||
| 141 | } | ||
| 142 | }; | ||
| 143 | |||
| 144 | fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [*]u8) bool { | ||
| 145 | var def = def_arg; | ||
| 146 | const vsym = @bitCast(u32, vsym_arg) & 0x7fff; | ||
| 147 | while (true) { | ||
| 148 | if (0 == (def.vd_flags & elf.VER_FLG_BASE) and (def.vd_ndx & 0x7fff) == vsym) | ||
| 149 | break; | ||
| 150 | if (def.vd_next == 0) | ||
| 151 | return false; | ||
| 152 | def = @intToPtr(*elf.Verdef, @ptrToInt(def) + def.vd_next); | ||
| 153 | } | ||
| 154 | const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux); | ||
| 155 | return mem.eql(u8, vername, cstr.toSliceConst(strings + aux.vda_name)); | ||
| 156 | } | ||
std/elf.zig+15| ... | @@ -305,6 +305,21 @@ pub const STT_ARM_16BIT = STT_HIPROC; | ... | @@ -305,6 +305,21 @@ pub const STT_ARM_16BIT = STT_HIPROC; |
| 305 | pub const VER_FLG_BASE = 0x1; | 305 | pub const VER_FLG_BASE = 0x1; |
| 306 | pub const VER_FLG_WEAK = 0x2; | 306 | pub const VER_FLG_WEAK = 0x2; |
| 307 | 307 | ||
| 308 | /// An unknown type. | ||
| 309 | pub const ET_NONE = 0; | ||
| 310 | |||
| 311 | /// A relocatable file. | ||
| 312 | pub const ET_REL = 1; | ||
| 313 | |||
| 314 | /// An executable file. | ||
| 315 | pub const ET_EXEC = 2; | ||
| 316 | |||
| 317 | /// A shared object. | ||
| 318 | pub const ET_DYN = 3; | ||
| 319 | |||
| 320 | /// A core file. | ||
| 321 | pub const ET_CORE = 4; | ||
| 322 | |||
| 308 | pub const FileType = enum { | 323 | pub const FileType = enum { |
| 309 | Relocatable, | 324 | Relocatable, |
| 310 | Executable, | 325 | Executable, |
std/fmt/errol/index.zig+41-41| ... | @@ -29,11 +29,11 @@ pub fn roundToPrecision(float_decimal: *FloatDecimal, precision: usize, mode: Ro | ... | @@ -29,11 +29,11 @@ pub fn roundToPrecision(float_decimal: *FloatDecimal, precision: usize, mode: Ro |
| 29 | switch (mode) { | 29 | switch (mode) { |
| 30 | RoundMode.Decimal => { | 30 | RoundMode.Decimal => { |
| 31 | if (float_decimal.exp >= 0) { | 31 | if (float_decimal.exp >= 0) { |
| 32 | round_digit = precision + usize(float_decimal.exp); | 32 | round_digit = precision + @intCast(usize, float_decimal.exp); |
| 33 | } else { | 33 | } else { |
| 34 | // if a small negative exp, then adjust we need to offset by the number | 34 | // if a small negative exp, then adjust we need to offset by the number |
| 35 | // of leading zeros that will occur. | 35 | // of leading zeros that will occur. |
| 36 | const min_exp_required = usize(-float_decimal.exp); | 36 | const min_exp_required = @intCast(usize, -float_decimal.exp); |
| 37 | if (precision > min_exp_required) { | 37 | if (precision > min_exp_required) { |
| 38 | round_digit = precision - min_exp_required; | 38 | round_digit = precision - min_exp_required; |
| 39 | } | 39 | } |
| ... | @@ -107,16 +107,16 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal { | ... | @@ -107,16 +107,16 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal { |
| 107 | // normalize the midpoint | 107 | // normalize the midpoint |
| 108 | 108 | ||
| 109 | const e = math.frexp(val).exponent; | 109 | const e = math.frexp(val).exponent; |
| 110 | var exp = i16(math.floor(307 + f64(e) * 0.30103)); | 110 | var exp = @floatToInt(i16, math.floor(307 + @intToFloat(f64, e) * 0.30103)); |
| 111 | if (exp < 20) { | 111 | if (exp < 20) { |
| 112 | exp = 20; | 112 | exp = 20; |
| 113 | } else if (usize(exp) >= lookup_table.len) { | 113 | } else if (@intCast(usize, exp) >= lookup_table.len) { |
| 114 | exp = i16(lookup_table.len - 1); | 114 | exp = @intCast(i16, lookup_table.len - 1); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | var mid = lookup_table[usize(exp)]; | 117 | var mid = lookup_table[@intCast(usize, exp)]; |
| 118 | mid = hpProd(mid, val); | 118 | mid = hpProd(mid, val); |
| 119 | const lten = lookup_table[usize(exp)].val; | 119 | const lten = lookup_table[@intCast(usize, exp)].val; |
| 120 | 120 | ||
| 121 | exp -= 307; | 121 | exp -= 307; |
| 122 | 122 | ||
| ... | @@ -168,25 +168,25 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal { | ... | @@ -168,25 +168,25 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal { |
| 168 | // the 0-index for this extra digit. | 168 | // the 0-index for this extra digit. |
| 169 | var buf_index: usize = 1; | 169 | var buf_index: usize = 1; |
| 170 | while (true) { | 170 | while (true) { |
| 171 | var hdig = u8(math.floor(high.val)); | 171 | var hdig = @floatToInt(u8, math.floor(high.val)); |
| 172 | if ((high.val == f64(hdig)) and (high.off < 0)) hdig -= 1; | 172 | if ((high.val == @intToFloat(f64, hdig)) and (high.off < 0)) hdig -= 1; |
| 173 | 173 | ||
| 174 | var ldig = u8(math.floor(low.val)); | 174 | var ldig = @floatToInt(u8, math.floor(low.val)); |
| 175 | if ((low.val == f64(ldig)) and (low.off < 0)) ldig -= 1; | 175 | if ((low.val == @intToFloat(f64, ldig)) and (low.off < 0)) ldig -= 1; |
| 176 | 176 | ||
| 177 | if (ldig != hdig) break; | 177 | if (ldig != hdig) break; |
| 178 | 178 | ||
| 179 | buffer[buf_index] = hdig + '0'; | 179 | buffer[buf_index] = hdig + '0'; |
| 180 | buf_index += 1; | 180 | buf_index += 1; |
| 181 | high.val -= f64(hdig); | 181 | high.val -= @intToFloat(f64, hdig); |
| 182 | low.val -= f64(ldig); | 182 | low.val -= @intToFloat(f64, ldig); |
| 183 | hpMul10(&high); | 183 | hpMul10(&high); |
| 184 | hpMul10(&low); | 184 | hpMul10(&low); |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | const tmp = (high.val + low.val) / 2.0; | 187 | const tmp = (high.val + low.val) / 2.0; |
| 188 | var mdig = u8(math.floor(tmp + 0.5)); | 188 | var mdig = @floatToInt(u8, math.floor(tmp + 0.5)); |
| 189 | if ((f64(mdig) - tmp) == 0.5 and (mdig & 0x1) != 0) mdig -= 1; | 189 | if ((@intToFloat(f64, mdig) - tmp) == 0.5 and (mdig & 0x1) != 0) mdig -= 1; |
| 190 | 190 | ||
| 191 | buffer[buf_index] = mdig + '0'; | 191 | buffer[buf_index] = mdig + '0'; |
| 192 | buf_index += 1; | 192 | buf_index += 1; |
| ... | @@ -304,7 +304,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { | ... | @@ -304,7 +304,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { |
| 304 | 304 | ||
| 305 | assert((val > 9.007199254740992e15) and val < (3.40282366920938e38)); | 305 | assert((val > 9.007199254740992e15) and val < (3.40282366920938e38)); |
| 306 | 306 | ||
| 307 | var mid = u128(val); | 307 | var mid = @floatToInt(u128, val); |
| 308 | var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0); | 308 | var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0); |
| 309 | var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0); | 309 | var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0); |
| 310 | 310 | ||
| ... | @@ -314,11 +314,11 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { | ... | @@ -314,11 +314,11 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { |
| 314 | low -= 1; | 314 | low -= 1; |
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | var l64 = u64(low % pow19); | 317 | var l64 = @intCast(u64, low % pow19); |
| 318 | const lf = u64((low / pow19) % pow19); | 318 | const lf = @intCast(u64, (low / pow19) % pow19); |
| 319 | 319 | ||
| 320 | var h64 = u64(high % pow19); | 320 | var h64 = @intCast(u64, high % pow19); |
| 321 | const hf = u64((high / pow19) % pow19); | 321 | const hf = @intCast(u64, (high / pow19) % pow19); |
| 322 | 322 | ||
| 323 | if (lf != hf) { | 323 | if (lf != hf) { |
| 324 | l64 = lf; | 324 | l64 = lf; |
| ... | @@ -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,14 +341,14 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { | ... | @@ -341,14 +341,14 @@ 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 | } |
| 348 | 348 | ||
| 349 | return FloatDecimal{ | 349 | return FloatDecimal{ |
| 350 | .digits = buffer[0..buf_index], | 350 | .digits = buffer[0..buf_index], |
| 351 | .exp = i32(buf_index) + mi, | 351 | .exp = @intCast(i32, buf_index) + mi, |
| 352 | }; | 352 | }; |
| 353 | } | 353 | } |
| 354 | 354 | ||
| ... | @@ -359,33 +359,33 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { | ... | @@ -359,33 +359,33 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { |
| 359 | fn errolFixed(val: f64, buffer: []u8) FloatDecimal { | 359 | fn errolFixed(val: f64, buffer: []u8) FloatDecimal { |
| 360 | assert((val >= 16.0) and (val < 9.007199254740992e15)); | 360 | assert((val >= 16.0) and (val < 9.007199254740992e15)); |
| 361 | 361 | ||
| 362 | const u = u64(val); | 362 | const u = @floatToInt(u64, val); |
| 363 | const n = f64(u); | 363 | const n = @intToFloat(f64, u); |
| 364 | 364 | ||
| 365 | var mid = val - n; | 365 | var mid = val - n; |
| 366 | var lo = ((fpprev(val) - n) + mid) / 2.0; | 366 | var lo = ((fpprev(val) - n) + mid) / 2.0; |
| 367 | var hi = ((fpnext(val) - n) + mid) / 2.0; | 367 | var hi = ((fpnext(val) - n) + mid) / 2.0; |
| 368 | 368 | ||
| 369 | var buf_index = u64toa(u, buffer); | 369 | var buf_index = u64toa(u, buffer); |
| 370 | var exp = i32(buf_index); | 370 | var exp = @intCast(i32, buf_index); |
| 371 | var j = buf_index; | 371 | var j = buf_index; |
| 372 | buffer[j] = 0; | 372 | buffer[j] = 0; |
| 373 | 373 | ||
| 374 | if (mid != 0.0) { | 374 | if (mid != 0.0) { |
| 375 | while (mid != 0.0) { | 375 | while (mid != 0.0) { |
| 376 | lo *= 10.0; | 376 | lo *= 10.0; |
| 377 | const ldig = i32(lo); | 377 | const ldig = @floatToInt(i32, lo); |
| 378 | lo -= f64(ldig); | 378 | lo -= @intToFloat(f64, ldig); |
| 379 | 379 | ||
| 380 | mid *= 10.0; | 380 | mid *= 10.0; |
| 381 | const mdig = i32(mid); | 381 | const mdig = @floatToInt(i32, mid); |
| 382 | mid -= f64(mdig); | 382 | mid -= @intToFloat(f64, mdig); |
| 383 | 383 | ||
| 384 | hi *= 10.0; | 384 | hi *= 10.0; |
| 385 | const hdig = i32(hi); | 385 | const hdig = @floatToInt(i32, hi); |
| 386 | hi -= f64(hdig); | 386 | hi -= @intToFloat(f64, hdig); |
| 387 | 387 | ||
| 388 | buffer[j] = u8(mdig + '0'); | 388 | buffer[j] = @intCast(u8, mdig + '0'); |
| 389 | j += 1; | 389 | j += 1; |
| 390 | 390 | ||
| 391 | if (hdig != ldig or j > 50) break; | 391 | if (hdig != ldig or j > 50) break; |
| ... | @@ -452,7 +452,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize { | ... | @@ -452,7 +452,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize { |
| 452 | var buf_index: usize = 0; | 452 | var buf_index: usize = 0; |
| 453 | 453 | ||
| 454 | if (value < kTen8) { | 454 | if (value < kTen8) { |
| 455 | const v = u32(value); | 455 | const v = @intCast(u32, value); |
| 456 | if (v < 10000) { | 456 | if (v < 10000) { |
| 457 | const d1: u32 = (v / 100) << 1; | 457 | const d1: u32 = (v / 100) << 1; |
| 458 | const d2: u32 = (v % 100) << 1; | 458 | const d2: u32 = (v % 100) << 1; |
| ... | @@ -507,8 +507,8 @@ fn u64toa(value_param: u64, buffer: []u8) usize { | ... | @@ -507,8 +507,8 @@ fn u64toa(value_param: u64, buffer: []u8) usize { |
| 507 | buf_index += 1; | 507 | buf_index += 1; |
| 508 | } | 508 | } |
| 509 | } else if (value < kTen16) { | 509 | } else if (value < kTen16) { |
| 510 | const v0: u32 = u32(value / kTen8); | 510 | const v0: u32 = @intCast(u32, value / kTen8); |
| 511 | const v1: u32 = u32(value % kTen8); | 511 | const v1: u32 = @intCast(u32, value % kTen8); |
| 512 | 512 | ||
| 513 | const b0: u32 = v0 / 10000; | 513 | const b0: u32 = v0 / 10000; |
| 514 | const c0: u32 = v0 % 10000; | 514 | const c0: u32 = v0 % 10000; |
| ... | @@ -578,11 +578,11 @@ fn u64toa(value_param: u64, buffer: []u8) usize { | ... | @@ -578,11 +578,11 @@ fn u64toa(value_param: u64, buffer: []u8) usize { |
| 578 | buffer[buf_index] = c_digits_lut[d8 + 1]; | 578 | buffer[buf_index] = c_digits_lut[d8 + 1]; |
| 579 | buf_index += 1; | 579 | buf_index += 1; |
| 580 | } else { | 580 | } else { |
| 581 | const a = u32(value / kTen16); // 1 to 1844 | 581 | const a = @intCast(u32, value / kTen16); // 1 to 1844 |
| 582 | value %= kTen16; | 582 | value %= kTen16; |
| 583 | 583 | ||
| 584 | if (a < 10) { | 584 | if (a < 10) { |
| 585 | buffer[buf_index] = '0' + u8(a); | 585 | buffer[buf_index] = '0' + @intCast(u8, a); |
| 586 | buf_index += 1; | 586 | buf_index += 1; |
| 587 | } else if (a < 100) { | 587 | } else if (a < 100) { |
| 588 | const i: u32 = a << 1; | 588 | const i: u32 = a << 1; |
| ... | @@ -591,7 +591,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize { | ... | @@ -591,7 +591,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize { |
| 591 | buffer[buf_index] = c_digits_lut[i + 1]; | 591 | buffer[buf_index] = c_digits_lut[i + 1]; |
| 592 | buf_index += 1; | 592 | buf_index += 1; |
| 593 | } else if (a < 1000) { | 593 | } else if (a < 1000) { |
| 594 | buffer[buf_index] = '0' + u8(a / 100); | 594 | buffer[buf_index] = '0' + @intCast(u8, a / 100); |
| 595 | buf_index += 1; | 595 | buf_index += 1; |
| 596 | 596 | ||
| 597 | const i: u32 = (a % 100) << 1; | 597 | const i: u32 = (a % 100) << 1; |
| ... | @@ -612,8 +612,8 @@ fn u64toa(value_param: u64, buffer: []u8) usize { | ... | @@ -612,8 +612,8 @@ fn u64toa(value_param: u64, buffer: []u8) usize { |
| 612 | buf_index += 1; | 612 | buf_index += 1; |
| 613 | } | 613 | } |
| 614 | 614 | ||
| 615 | const v0 = u32(value / kTen8); | 615 | const v0 = @intCast(u32, value / kTen8); |
| 616 | const v1 = u32(value % kTen8); | 616 | const v1 = @intCast(u32, value % kTen8); |
| 617 | 617 | ||
| 618 | const b0: u32 = v0 / 10000; | 618 | const b0: u32 = v0 / 10000; |
| 619 | const c0: u32 = v0 % 10000; | 619 | const c0: u32 = v0 % 10000; |
std/fmt/index.zig+16-11| ... | @@ -5,6 +5,7 @@ const assert = debug.assert; | ... | @@ -5,6 +5,7 @@ const assert = debug.assert; |
| 5 | const mem = std.mem; | 5 | const mem = std.mem; |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | const errol = @import("errol/index.zig"); | 7 | const errol = @import("errol/index.zig"); |
| 8 | const lossyCast = std.math.lossyCast; | ||
| 8 | 9 | ||
| 9 | const max_int_digits = 65; | 10 | const max_int_digits = 65; |
| 10 | 11 | ||
| ... | @@ -162,8 +163,6 @@ pub fn formatType( | ... | @@ -162,8 +163,6 @@ pub fn formatType( |
| 162 | }, | 163 | }, |
| 163 | builtin.TypeInfo.Pointer.Size.Many => { | 164 | builtin.TypeInfo.Pointer.Size.Many => { |
| 164 | if (ptr_info.child == u8) { | 165 | if (ptr_info.child == u8) { |
| 165 | //This is a bit of a hack, but it made more sense to | ||
| 166 | // do this check here than have formatText do it | ||
| 167 | if (fmt[0] == 's') { | 166 | if (fmt[0] == 's') { |
| 168 | const len = std.cstr.len(value); | 167 | const len = std.cstr.len(value); |
| 169 | return formatText(value[0..len], fmt, context, Errors, output); | 168 | return formatText(value[0..len], fmt, context, Errors, output); |
| ... | @@ -176,6 +175,12 @@ pub fn formatType( | ... | @@ -176,6 +175,12 @@ pub fn formatType( |
| 176 | return output(context, casted_value); | 175 | return output(context, casted_value); |
| 177 | }, | 176 | }, |
| 178 | }, | 177 | }, |
| 178 | builtin.TypeId.Array => |info| { | ||
| 179 | if (info.child == u8) { | ||
| 180 | return formatText(value, fmt, context, Errors, output); | ||
| 181 | } | ||
| 182 | return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value)); | ||
| 183 | }, | ||
| 179 | else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"), | 184 | else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"), |
| 180 | } | 185 | } |
| 181 | } | 186 | } |
| ... | @@ -459,7 +464,7 @@ pub fn formatFloatDecimal( | ... | @@ -459,7 +464,7 @@ pub fn formatFloatDecimal( |
| 459 | errol.roundToPrecision(&float_decimal, precision, errol.RoundMode.Decimal); | 464 | errol.roundToPrecision(&float_decimal, precision, errol.RoundMode.Decimal); |
| 460 | 465 | ||
| 461 | // exp < 0 means the leading is always 0 as errol result is normalized. | 466 | // exp < 0 means the leading is always 0 as errol result is normalized. |
| 462 | var num_digits_whole = if (float_decimal.exp > 0) usize(float_decimal.exp) else 0; | 467 | var num_digits_whole = if (float_decimal.exp > 0) @intCast(usize, float_decimal.exp) else 0; |
| 463 | 468 | ||
| 464 | // the actual slice into the buffer, we may need to zero-pad between num_digits_whole and this. | 469 | // the actual slice into the buffer, we may need to zero-pad between num_digits_whole and this. |
| 465 | var num_digits_whole_no_pad = math.min(num_digits_whole, float_decimal.digits.len); | 470 | var num_digits_whole_no_pad = math.min(num_digits_whole, float_decimal.digits.len); |
| ... | @@ -488,7 +493,7 @@ pub fn formatFloatDecimal( | ... | @@ -488,7 +493,7 @@ pub fn formatFloatDecimal( |
| 488 | 493 | ||
| 489 | // Zero-fill until we reach significant digits or run out of precision. | 494 | // Zero-fill until we reach significant digits or run out of precision. |
| 490 | if (float_decimal.exp <= 0) { | 495 | if (float_decimal.exp <= 0) { |
| 491 | const zero_digit_count = usize(-float_decimal.exp); | 496 | const zero_digit_count = @intCast(usize, -float_decimal.exp); |
| 492 | const zeros_to_print = math.min(zero_digit_count, precision); | 497 | const zeros_to_print = math.min(zero_digit_count, precision); |
| 493 | 498 | ||
| 494 | var i: usize = 0; | 499 | var i: usize = 0; |
| ... | @@ -517,7 +522,7 @@ pub fn formatFloatDecimal( | ... | @@ -517,7 +522,7 @@ pub fn formatFloatDecimal( |
| 517 | } | 522 | } |
| 518 | } else { | 523 | } else { |
| 519 | // exp < 0 means the leading is always 0 as errol result is normalized. | 524 | // exp < 0 means the leading is always 0 as errol result is normalized. |
| 520 | var num_digits_whole = if (float_decimal.exp > 0) usize(float_decimal.exp) else 0; | 525 | var num_digits_whole = if (float_decimal.exp > 0) @intCast(usize, float_decimal.exp) else 0; |
| 521 | 526 | ||
| 522 | // the actual slice into the buffer, we may need to zero-pad between num_digits_whole and this. | 527 | // the actual slice into the buffer, we may need to zero-pad between num_digits_whole and this. |
| 523 | var num_digits_whole_no_pad = math.min(num_digits_whole, float_decimal.digits.len); | 528 | var num_digits_whole_no_pad = math.min(num_digits_whole, float_decimal.digits.len); |
| ... | @@ -543,7 +548,7 @@ pub fn formatFloatDecimal( | ... | @@ -543,7 +548,7 @@ pub fn formatFloatDecimal( |
| 543 | 548 | ||
| 544 | // Zero-fill until we reach significant digits or run out of precision. | 549 | // Zero-fill until we reach significant digits or run out of precision. |
| 545 | if (float_decimal.exp < 0) { | 550 | if (float_decimal.exp < 0) { |
| 546 | const zero_digit_count = usize(-float_decimal.exp); | 551 | const zero_digit_count = @intCast(usize, -float_decimal.exp); |
| 547 | 552 | ||
| 548 | var i: usize = 0; | 553 | var i: usize = 0; |
| 549 | while (i < zero_digit_count) : (i += 1) { | 554 | while (i < zero_digit_count) : (i += 1) { |
| ... | @@ -574,7 +579,7 @@ pub fn formatBytes( | ... | @@ -574,7 +579,7 @@ pub fn formatBytes( |
| 574 | 1024 => math.min(math.log2(value) / 10, mags_iec.len - 1), | 579 | 1024 => math.min(math.log2(value) / 10, mags_iec.len - 1), |
| 575 | else => unreachable, | 580 | else => unreachable, |
| 576 | }; | 581 | }; |
| 577 | const new_value = f64(value) / math.pow(f64, f64(radix), f64(magnitude)); | 582 | const new_value = lossyCast(f64, value) / math.pow(f64, lossyCast(f64, radix), lossyCast(f64, magnitude)); |
| 578 | const suffix = switch (radix) { | 583 | const suffix = switch (radix) { |
| 579 | 1000 => mags_si[magnitude], | 584 | 1000 => mags_si[magnitude], |
| 580 | 1024 => mags_iec[magnitude], | 585 | 1024 => mags_iec[magnitude], |
| ... | @@ -624,15 +629,15 @@ fn formatIntSigned( | ... | @@ -624,15 +629,15 @@ fn formatIntSigned( |
| 624 | if (value < 0) { | 629 | if (value < 0) { |
| 625 | const minus_sign: u8 = '-'; | 630 | const minus_sign: u8 = '-'; |
| 626 | try output(context, (*[1]u8)(&minus_sign)[0..]); | 631 | try output(context, (*[1]u8)(&minus_sign)[0..]); |
| 627 | const new_value = uint(-(value + 1)) + 1; | 632 | const new_value = @intCast(uint, -(value + 1)) + 1; |
| 628 | const new_width = if (width == 0) 0 else (width - 1); | 633 | const new_width = if (width == 0) 0 else (width - 1); |
| 629 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output); | 634 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output); |
| 630 | } else if (width == 0) { | 635 | } else if (width == 0) { |
| 631 | return formatIntUnsigned(uint(value), base, uppercase, width, context, Errors, output); | 636 | return formatIntUnsigned(@intCast(uint, value), base, uppercase, width, context, Errors, output); |
| 632 | } else { | 637 | } else { |
| 633 | const plus_sign: u8 = '+'; | 638 | const plus_sign: u8 = '+'; |
| 634 | try output(context, (*[1]u8)(&plus_sign)[0..]); | 639 | try output(context, (*[1]u8)(&plus_sign)[0..]); |
| 635 | const new_value = uint(value); | 640 | const new_value = @intCast(uint, value); |
| 636 | const new_width = if (width == 0) 0 else (width - 1); | 641 | const new_width = if (width == 0) 0 else (width - 1); |
| 637 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output); | 642 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output); |
| 638 | } | 643 | } |
| ... | @@ -656,7 +661,7 @@ fn formatIntUnsigned( | ... | @@ -656,7 +661,7 @@ fn formatIntUnsigned( |
| 656 | while (true) { | 661 | while (true) { |
| 657 | const digit = a % base; | 662 | const digit = a % base; |
| 658 | index -= 1; | 663 | index -= 1; |
| 659 | buf[index] = digitToChar(u8(digit), uppercase); | 664 | buf[index] = digitToChar(@intCast(u8, digit), uppercase); |
| 660 | a /= base; | 665 | a /= base; |
| 661 | if (a == 0) break; | 666 | if (a == 0) break; |
| 662 | } | 667 | } |
std/hash/crc.zig+2-2| ... | @@ -26,7 +26,7 @@ pub fn Crc32WithPoly(comptime poly: u32) type { | ... | @@ -26,7 +26,7 @@ pub fn Crc32WithPoly(comptime poly: u32) type { |
| 26 | var tables: [8][256]u32 = undefined; | 26 | var tables: [8][256]u32 = undefined; |
| 27 | 27 | ||
| 28 | for (tables[0]) |*e, i| { | 28 | for (tables[0]) |*e, i| { |
| 29 | var crc = u32(i); | 29 | var crc = @intCast(u32, i); |
| 30 | var j: usize = 0; | 30 | var j: usize = 0; |
| 31 | while (j < 8) : (j += 1) { | 31 | while (j < 8) : (j += 1) { |
| 32 | if (crc & 1 == 1) { | 32 | if (crc & 1 == 1) { |
| ... | @@ -122,7 +122,7 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type { | ... | @@ -122,7 +122,7 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type { |
| 122 | var table: [16]u32 = undefined; | 122 | var table: [16]u32 = undefined; |
| 123 | 123 | ||
| 124 | for (table) |*e, i| { | 124 | for (table) |*e, i| { |
| 125 | var crc = u32(i * 16); | 125 | var crc = @intCast(u32, i * 16); |
| 126 | var j: usize = 0; | 126 | var j: usize = 0; |
| 127 | while (j < 8) : (j += 1) { | 127 | while (j < 8) : (j += 1) { |
| 128 | if (crc & 1 == 1) { | 128 | if (crc & 1 == 1) { |
std/hash/siphash.zig+3-3| ... | @@ -81,7 +81,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) | ... | @@ -81,7 +81,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) |
| 81 | 81 | ||
| 82 | // Remainder for next pass. | 82 | // Remainder for next pass. |
| 83 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); | 83 | mem.copy(u8, d.buf[d.buf_len..], b[off..]); |
| 84 | d.buf_len += u8(b[off..].len); | 84 | d.buf_len += @intCast(u8, b[off..].len); |
| 85 | d.msg_len +%= @truncate(u8, b.len); | 85 | d.msg_len +%= @truncate(u8, b.len); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| ... | @@ -233,7 +233,7 @@ test "siphash64-2-4 sanity" { | ... | @@ -233,7 +233,7 @@ test "siphash64-2-4 sanity" { |
| 233 | 233 | ||
| 234 | var buffer: [64]u8 = undefined; | 234 | var buffer: [64]u8 = undefined; |
| 235 | for (vectors) |vector, i| { | 235 | for (vectors) |vector, i| { |
| 236 | buffer[i] = u8(i); | 236 | buffer[i] = @intCast(u8, i); |
| 237 | 237 | ||
| 238 | const expected = mem.readInt(vector, u64, Endian.Little); | 238 | const expected = mem.readInt(vector, u64, Endian.Little); |
| 239 | debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); | 239 | debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); |
| ... | @@ -312,7 +312,7 @@ test "siphash128-2-4 sanity" { | ... | @@ -312,7 +312,7 @@ test "siphash128-2-4 sanity" { |
| 312 | 312 | ||
| 313 | var buffer: [64]u8 = undefined; | 313 | var buffer: [64]u8 = undefined; |
| 314 | for (vectors) |vector, i| { | 314 | for (vectors) |vector, i| { |
| 315 | buffer[i] = u8(i); | 315 | buffer[i] = @intCast(u8, i); |
| 316 | 316 | ||
| 317 | const expected = mem.readInt(vector, u128, Endian.Little); | 317 | const expected = mem.readInt(vector, u128, Endian.Little); |
| 318 | debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); | 318 | debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); |
std/heap.zig+1-1| ... | @@ -408,7 +408,7 @@ fn testAllocator(allocator: *mem.Allocator) !void { | ... | @@ -408,7 +408,7 @@ fn testAllocator(allocator: *mem.Allocator) !void { |
| 408 | 408 | ||
| 409 | for (slice) |*item, i| { | 409 | for (slice) |*item, i| { |
| 410 | item.* = try allocator.create(i32); | 410 | item.* = try allocator.create(i32); |
| 411 | item.*.* = i32(i); | 411 | item.*.* = @intCast(i32, i); |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | for (slice) |item, i| { | 414 | for (slice) |item, i| { |
std/index.zig+1| ... | @@ -8,6 +8,7 @@ pub const HashMap = @import("hash_map.zig").HashMap; | ... | @@ -8,6 +8,7 @@ pub const HashMap = @import("hash_map.zig").HashMap; |
| 8 | pub const LinkedList = @import("linked_list.zig").LinkedList; | 8 | pub const LinkedList = @import("linked_list.zig").LinkedList; |
| 9 | pub const IntrusiveLinkedList = @import("linked_list.zig").IntrusiveLinkedList; | 9 | pub const IntrusiveLinkedList = @import("linked_list.zig").IntrusiveLinkedList; |
| 10 | pub const SegmentedList = @import("segmented_list.zig").SegmentedList; | 10 | pub const SegmentedList = @import("segmented_list.zig").SegmentedList; |
| 11 | pub const DynLib = @import("dynamic_library.zig").DynLib; | ||
| 11 | 12 | ||
| 12 | pub const atomic = @import("atomic/index.zig"); | 13 | pub const atomic = @import("atomic/index.zig"); |
| 13 | pub const base64 = @import("base64.zig"); | 14 | pub const base64 = @import("base64.zig"); |
std/io.zig+6-1| ... | @@ -242,11 +242,16 @@ pub fn writeFile(allocator: *mem.Allocator, path: []const u8, data: []const u8) | ... | @@ -242,11 +242,16 @@ pub fn writeFile(allocator: *mem.Allocator, path: []const u8, data: []const u8) |
| 242 | 242 | ||
| 243 | /// On success, caller owns returned buffer. | 243 | /// On success, caller owns returned buffer. |
| 244 | pub fn readFileAlloc(allocator: *mem.Allocator, path: []const u8) ![]u8 { | 244 | pub fn readFileAlloc(allocator: *mem.Allocator, path: []const u8) ![]u8 { |
| 245 | return readFileAllocAligned(allocator, path, @alignOf(u8)); | ||
| 246 | } | ||
| 247 | |||
| 248 | /// On success, caller owns returned buffer. | ||
| 249 | pub fn readFileAllocAligned(allocator: *mem.Allocator, path: []const u8, comptime A: u29) ![]align(A) u8 { | ||
| 245 | var file = try File.openRead(allocator, path); | 250 | var file = try File.openRead(allocator, path); |
| 246 | defer file.close(); | 251 | defer file.close(); |
| 247 | 252 | ||
| 248 | const size = try file.getEndPos(); | 253 | const size = try file.getEndPos(); |
| 249 | const buf = try allocator.alloc(u8, size); | 254 | const buf = try allocator.alignedAlloc(u8, A, size); |
| 250 | errdefer allocator.free(buf); | 255 | errdefer allocator.free(buf); |
| 251 | 256 | ||
| 252 | var adapter = FileInStream.init(&file); | 257 | var adapter = FileInStream.init(&file); |
std/json.zig+2-2| ... | @@ -180,7 +180,7 @@ pub const StreamingParser = struct { | ... | @@ -180,7 +180,7 @@ pub const StreamingParser = struct { |
| 180 | pub fn fromInt(x: var) State { | 180 | pub fn fromInt(x: var) State { |
| 181 | debug.assert(x == 0 or x == 1); | 181 | debug.assert(x == 0 or x == 1); |
| 182 | const T = @TagType(State); | 182 | const T = @TagType(State); |
| 183 | return State(T(x)); | 183 | return State(@intCast(T, x)); |
| 184 | } | 184 | } |
| 185 | }; | 185 | }; |
| 186 | 186 | ||
| ... | @@ -1326,7 +1326,7 @@ pub const Parser = struct { | ... | @@ -1326,7 +1326,7 @@ pub const Parser = struct { |
| 1326 | }, | 1326 | }, |
| 1327 | // Array Parent -> [ ..., <array>, value ] | 1327 | // Array Parent -> [ ..., <array>, value ] |
| 1328 | Value.Array => |*array| { | 1328 | Value.Array => |*array| { |
| 1329 | try array.append(value); | 1329 | try array.append(value.*); |
| 1330 | p.state = State.ArrayValue; | 1330 | p.state = State.ArrayValue; |
| 1331 | }, | 1331 | }, |
| 1332 | else => { | 1332 | else => { |
std/math/acos.zig+2-2| ... | @@ -95,12 +95,12 @@ fn acos64(x: f64) f64 { | ... | @@ -95,12 +95,12 @@ fn acos64(x: f64) f64 { |
| 95 | const pio2_lo: f64 = 6.12323399573676603587e-17; | 95 | const pio2_lo: f64 = 6.12323399573676603587e-17; |
| 96 | 96 | ||
| 97 | const ux = @bitCast(u64, x); | 97 | const ux = @bitCast(u64, x); |
| 98 | const hx = u32(ux >> 32); | 98 | const hx = @intCast(u32, ux >> 32); |
| 99 | const ix = hx & 0x7FFFFFFF; | 99 | const ix = hx & 0x7FFFFFFF; |
| 100 | 100 | ||
| 101 | // |x| >= 1 or nan | 101 | // |x| >= 1 or nan |
| 102 | if (ix >= 0x3FF00000) { | 102 | if (ix >= 0x3FF00000) { |
| 103 | const lx = u32(ux & 0xFFFFFFFF); | 103 | const lx = @intCast(u32, ux & 0xFFFFFFFF); |
| 104 | 104 | ||
| 105 | // acos(1) = 0, acos(-1) = pi | 105 | // acos(1) = 0, acos(-1) = pi |
| 106 | if ((ix - 0x3FF00000) | lx == 0) { | 106 | if ((ix - 0x3FF00000) | lx == 0) { |
std/math/asin.zig+2-2| ... | @@ -87,12 +87,12 @@ fn asin64(x: f64) f64 { | ... | @@ -87,12 +87,12 @@ fn asin64(x: f64) f64 { |
| 87 | const pio2_lo: f64 = 6.12323399573676603587e-17; | 87 | const pio2_lo: f64 = 6.12323399573676603587e-17; |
| 88 | 88 | ||
| 89 | const ux = @bitCast(u64, x); | 89 | const ux = @bitCast(u64, x); |
| 90 | const hx = u32(ux >> 32); | 90 | const hx = @intCast(u32, ux >> 32); |
| 91 | const ix = hx & 0x7FFFFFFF; | 91 | const ix = hx & 0x7FFFFFFF; |
| 92 | 92 | ||
| 93 | // |x| >= 1 or nan | 93 | // |x| >= 1 or nan |
| 94 | if (ix >= 0x3FF00000) { | 94 | if (ix >= 0x3FF00000) { |
| 95 | const lx = u32(ux & 0xFFFFFFFF); | 95 | const lx = @intCast(u32, ux & 0xFFFFFFFF); |
| 96 | 96 | ||
| 97 | // asin(1) = +-pi/2 with inexact | 97 | // asin(1) = +-pi/2 with inexact |
| 98 | if ((ix - 0x3FF00000) | lx == 0) { | 98 | if ((ix - 0x3FF00000) | lx == 0) { |
std/math/atan.zig+2-2| ... | @@ -138,7 +138,7 @@ fn atan64(x_: f64) f64 { | ... | @@ -138,7 +138,7 @@ fn atan64(x_: f64) f64 { |
| 138 | 138 | ||
| 139 | var x = x_; | 139 | var x = x_; |
| 140 | var ux = @bitCast(u64, x); | 140 | var ux = @bitCast(u64, x); |
| 141 | var ix = u32(ux >> 32); | 141 | var ix = @intCast(u32, ux >> 32); |
| 142 | const sign = ix >> 31; | 142 | const sign = ix >> 31; |
| 143 | ix &= 0x7FFFFFFF; | 143 | ix &= 0x7FFFFFFF; |
| 144 | 144 | ||
| ... | @@ -159,7 +159,7 @@ fn atan64(x_: f64) f64 { | ... | @@ -159,7 +159,7 @@ fn atan64(x_: f64) f64 { |
| 159 | // |x| < 2^(-27) | 159 | // |x| < 2^(-27) |
| 160 | if (ix < 0x3E400000) { | 160 | if (ix < 0x3E400000) { |
| 161 | if (ix < 0x00100000) { | 161 | if (ix < 0x00100000) { |
| 162 | math.forceEval(f32(x)); | 162 | math.forceEval(@floatCast(f32, x)); |
| 163 | } | 163 | } |
| 164 | return x; | 164 | return x; |
| 165 | } | 165 | } |
std/math/atan2.zig+4-4| ... | @@ -124,12 +124,12 @@ fn atan2_64(y: f64, x: f64) f64 { | ... | @@ -124,12 +124,12 @@ fn atan2_64(y: f64, x: f64) f64 { |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | var ux = @bitCast(u64, x); | 126 | var ux = @bitCast(u64, x); |
| 127 | var ix = u32(ux >> 32); | 127 | var ix = @intCast(u32, ux >> 32); |
| 128 | var lx = u32(ux & 0xFFFFFFFF); | 128 | var lx = @intCast(u32, ux & 0xFFFFFFFF); |
| 129 | 129 | ||
| 130 | var uy = @bitCast(u64, y); | 130 | var uy = @bitCast(u64, y); |
| 131 | var iy = u32(uy >> 32); | 131 | var iy = @intCast(u32, uy >> 32); |
| 132 | var ly = u32(uy & 0xFFFFFFFF); | 132 | var ly = @intCast(u32, uy & 0xFFFFFFFF); |
| 133 | 133 | ||
| 134 | // x = 1.0 | 134 | // x = 1.0 |
| 135 | if ((ix -% 0x3FF00000) | lx == 0) { | 135 | if ((ix -% 0x3FF00000) | lx == 0) { |
std/math/atanh.zig+1-1| ... | @@ -62,7 +62,7 @@ fn atanh_64(x: f64) f64 { | ... | @@ -62,7 +62,7 @@ fn atanh_64(x: f64) f64 { |
| 62 | if (e < 0x3FF - 32) { | 62 | if (e < 0x3FF - 32) { |
| 63 | // underflow | 63 | // underflow |
| 64 | if (e == 0) { | 64 | if (e == 0) { |
| 65 | math.forceEval(f32(y)); | 65 | math.forceEval(@floatCast(f32, y)); |
| 66 | } | 66 | } |
| 67 | } | 67 | } |
| 68 | // |x| < 0.5 | 68 | // |x| < 0.5 |
std/math/big/int.zig+164-222| ... | @@ -18,39 +18,6 @@ comptime { | ... | @@ -18,39 +18,6 @@ comptime { |
| 18 | debug.assert(Limb.is_signed == false); | 18 | debug.assert(Limb.is_signed == false); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | const wrapped_buffer_size = 512; | ||
| 22 | |||
| 23 | // Converts primitive integer values onto a stack-based big integer, or passes through existing | ||
| 24 | // Int types with no modifications. This can fail at runtime if using a very large dynamic | ||
| 25 | // integer but it is very unlikely and is considered a user error. | ||
| 26 | fn wrapInt(allocator: *Allocator, bn: var) *const Int { | ||
| 27 | const T = @typeOf(bn); | ||
| 28 | switch (@typeInfo(T)) { | ||
| 29 | TypeId.Pointer => |info| { | ||
| 30 | if (info.child == Int) { | ||
| 31 | return bn; | ||
| 32 | } else { | ||
| 33 | @compileError("cannot set Int using type " ++ @typeName(T)); | ||
| 34 | } | ||
| 35 | }, | ||
| 36 | else => { | ||
| 37 | var s = allocator.create(Int) catch unreachable; | ||
| 38 | s.* = Int{ | ||
| 39 | .allocator = allocator, | ||
| 40 | .positive = false, | ||
| 41 | .limbs = block: { | ||
| 42 | var limbs = allocator.alloc(Limb, Int.default_capacity) catch unreachable; | ||
| 43 | limbs[0] = 0; | ||
| 44 | break :block limbs; | ||
| 45 | }, | ||
| 46 | .len = 1, | ||
| 47 | }; | ||
| 48 | s.set(bn) catch unreachable; | ||
| 49 | return s; | ||
| 50 | }, | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | pub const Int = struct { | 21 | pub const Int = struct { |
| 55 | allocator: *Allocator, | 22 | allocator: *Allocator, |
| 56 | positive: bool, | 23 | positive: bool, |
| ... | @@ -93,11 +60,11 @@ pub const Int = struct { | ... | @@ -93,11 +60,11 @@ pub const Int = struct { |
| 93 | self.limbs = try self.allocator.realloc(Limb, self.limbs, capacity); | 60 | self.limbs = try self.allocator.realloc(Limb, self.limbs, capacity); |
| 94 | } | 61 | } |
| 95 | 62 | ||
| 96 | pub fn deinit(self: *const Int) void { | 63 | pub fn deinit(self: Int) void { |
| 97 | self.allocator.free(self.limbs); | 64 | self.allocator.free(self.limbs); |
| 98 | } | 65 | } |
| 99 | 66 | ||
| 100 | pub fn clone(other: *const Int) !Int { | 67 | pub fn clone(other: Int) !Int { |
| 101 | return Int{ | 68 | return Int{ |
| 102 | .allocator = other.allocator, | 69 | .allocator = other.allocator, |
| 103 | .positive = other.positive, | 70 | .positive = other.positive, |
| ... | @@ -110,8 +77,8 @@ pub const Int = struct { | ... | @@ -110,8 +77,8 @@ pub const Int = struct { |
| 110 | }; | 77 | }; |
| 111 | } | 78 | } |
| 112 | 79 | ||
| 113 | pub fn copy(self: *Int, other: *const Int) !void { | 80 | pub fn copy(self: *Int, other: Int) !void { |
| 114 | if (self == other) { | 81 | if (self == &other) { |
| 115 | return; | 82 | return; |
| 116 | } | 83 | } |
| 117 | 84 | ||
| ... | @@ -125,7 +92,7 @@ pub const Int = struct { | ... | @@ -125,7 +92,7 @@ pub const Int = struct { |
| 125 | mem.swap(Int, self, other); | 92 | mem.swap(Int, self, other); |
| 126 | } | 93 | } |
| 127 | 94 | ||
| 128 | pub fn dump(self: *const Int) void { | 95 | pub fn dump(self: Int) void { |
| 129 | for (self.limbs) |limb| { | 96 | for (self.limbs) |limb| { |
| 130 | debug.warn("{x} ", limb); | 97 | debug.warn("{x} ", limb); |
| 131 | } | 98 | } |
| ... | @@ -140,20 +107,20 @@ pub const Int = struct { | ... | @@ -140,20 +107,20 @@ pub const Int = struct { |
| 140 | r.positive = true; | 107 | r.positive = true; |
| 141 | } | 108 | } |
| 142 | 109 | ||
| 143 | pub fn isOdd(r: *const Int) bool { | 110 | pub fn isOdd(r: Int) bool { |
| 144 | return r.limbs[0] & 1 != 0; | 111 | return r.limbs[0] & 1 != 0; |
| 145 | } | 112 | } |
| 146 | 113 | ||
| 147 | pub fn isEven(r: *const Int) bool { | 114 | pub fn isEven(r: Int) bool { |
| 148 | return !r.isOdd(); | 115 | return !r.isOdd(); |
| 149 | } | 116 | } |
| 150 | 117 | ||
| 151 | fn bitcount(self: *const Int) usize { | 118 | fn bitcount(self: Int) usize { |
| 152 | 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])); |
| 153 | return usize(!self.positive) + u_bit_count; | 120 | return usize(@boolToInt(!self.positive)) + u_bit_count; |
| 154 | } | 121 | } |
| 155 | 122 | ||
| 156 | pub fn sizeInBase(self: *const Int, base: usize) usize { | 123 | pub fn sizeInBase(self: Int, base: usize) usize { |
| 157 | return (self.bitcount() / math.log2(base)) + 1; | 124 | return (self.bitcount() / math.log2(base)) + 1; |
| 158 | } | 125 | } |
| 159 | 126 | ||
| ... | @@ -168,7 +135,7 @@ pub const Int = struct { | ... | @@ -168,7 +135,7 @@ pub const Int = struct { |
| 168 | self.positive = value >= 0; | 135 | self.positive = value >= 0; |
| 169 | self.len = 0; | 136 | self.len = 0; |
| 170 | 137 | ||
| 171 | var w_value: UT = if (value < 0) UT(-value) else UT(value); | 138 | var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value); |
| 172 | 139 | ||
| 173 | if (info.bits <= Limb.bit_count) { | 140 | if (info.bits <= Limb.bit_count) { |
| 174 | self.limbs[0] = Limb(w_value); | 141 | self.limbs[0] = Limb(w_value); |
| ... | @@ -219,7 +186,7 @@ pub const Int = struct { | ... | @@ -219,7 +186,7 @@ pub const Int = struct { |
| 219 | TargetTooSmall, | 186 | TargetTooSmall, |
| 220 | }; | 187 | }; |
| 221 | 188 | ||
| 222 | pub fn to(self: *const Int, comptime T: type) ConvertError!T { | 189 | pub fn to(self: Int, comptime T: type) ConvertError!T { |
| 223 | switch (@typeId(T)) { | 190 | switch (@typeId(T)) { |
| 224 | TypeId.Int => { | 191 | TypeId.Int => { |
| 225 | const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T; | 192 | const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T; |
| ... | @@ -231,7 +198,7 @@ pub const Int = struct { | ... | @@ -231,7 +198,7 @@ pub const Int = struct { |
| 231 | var r: UT = 0; | 198 | var r: UT = 0; |
| 232 | 199 | ||
| 233 | if (@sizeOf(UT) <= @sizeOf(Limb)) { | 200 | if (@sizeOf(UT) <= @sizeOf(Limb)) { |
| 234 | r = UT(self.limbs[0]); | 201 | r = @intCast(UT, self.limbs[0]); |
| 235 | } else { | 202 | } else { |
| 236 | for (self.limbs[0..self.len]) |_, ri| { | 203 | for (self.limbs[0..self.len]) |_, ri| { |
| 237 | const limb = self.limbs[self.len - ri - 1]; | 204 | const limb = self.limbs[self.len - ri - 1]; |
| ... | @@ -243,7 +210,7 @@ pub const Int = struct { | ... | @@ -243,7 +210,7 @@ pub const Int = struct { |
| 243 | if (!T.is_signed) { | 210 | if (!T.is_signed) { |
| 244 | return if (self.positive) r else error.NegativeIntoUnsigned; | 211 | return if (self.positive) r else error.NegativeIntoUnsigned; |
| 245 | } else { | 212 | } else { |
| 246 | return if (self.positive) T(r) else -T(r); | 213 | return if (self.positive) @intCast(T, r) else -@intCast(T, r); |
| 247 | } | 214 | } |
| 248 | }, | 215 | }, |
| 249 | else => { | 216 | else => { |
| ... | @@ -286,16 +253,28 @@ pub const Int = struct { | ... | @@ -286,16 +253,28 @@ pub const Int = struct { |
| 286 | i += 1; | 253 | i += 1; |
| 287 | } | 254 | } |
| 288 | 255 | ||
| 256 | // TODO values less than limb size should guarantee non allocating | ||
| 257 | var base_buffer: [512]u8 = undefined; | ||
| 258 | const base_al = &std.heap.FixedBufferAllocator.init(base_buffer[0..]).allocator; | ||
| 259 | const base_ap = try Int.initSet(base_al, base); | ||
| 260 | |||
| 261 | var d_buffer: [512]u8 = undefined; | ||
| 262 | var d_fba = std.heap.FixedBufferAllocator.init(d_buffer[0..]); | ||
| 263 | const d_al = &d_fba.allocator; | ||
| 264 | |||
| 289 | try self.set(0); | 265 | try self.set(0); |
| 290 | for (value[i..]) |ch| { | 266 | for (value[i..]) |ch| { |
| 291 | const d = try charToDigit(ch, base); | 267 | const d = try charToDigit(ch, base); |
| 292 | try self.mul(self, base); | 268 | d_fba.end_index = 0; |
| 293 | try self.add(self, d); | 269 | const d_ap = try Int.initSet(d_al, d); |
| 270 | |||
| 271 | try self.mul(self.*, base_ap); | ||
| 272 | try self.add(self.*, d_ap); | ||
| 294 | } | 273 | } |
| 295 | self.positive = positive; | 274 | self.positive = positive; |
| 296 | } | 275 | } |
| 297 | 276 | ||
| 298 | pub fn toString(self: *const Int, allocator: *Allocator, base: u8) ![]const u8 { | 277 | pub fn toString(self: Int, allocator: *Allocator, base: u8) ![]const u8 { |
| 299 | if (base < 2 or base > 16) { | 278 | if (base < 2 or base > 16) { |
| 300 | return error.InvalidBase; | 279 | return error.InvalidBase; |
| 301 | } | 280 | } |
| ... | @@ -316,7 +295,7 @@ pub const Int = struct { | ... | @@ -316,7 +295,7 @@ pub const Int = struct { |
| 316 | for (self.limbs[0..self.len]) |limb| { | 295 | for (self.limbs[0..self.len]) |limb| { |
| 317 | var shift: usize = 0; | 296 | var shift: usize = 0; |
| 318 | while (shift < Limb.bit_count) : (shift += base_shift) { | 297 | while (shift < Limb.bit_count) : (shift += base_shift) { |
| 319 | const r = u8((limb >> Log2Limb(shift)) & Limb(base - 1)); | 298 | const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & Limb(base - 1)); |
| 320 | const ch = try digitToChar(r, base); | 299 | const ch = try digitToChar(r, base); |
| 321 | try digits.append(ch); | 300 | try digits.append(ch); |
| 322 | } | 301 | } |
| ... | @@ -345,12 +324,12 @@ pub const Int = struct { | ... | @@ -345,12 +324,12 @@ pub const Int = struct { |
| 345 | var b = try Int.initSet(allocator, limb_base); | 324 | var b = try Int.initSet(allocator, limb_base); |
| 346 | 325 | ||
| 347 | while (q.len >= 2) { | 326 | while (q.len >= 2) { |
| 348 | try Int.divTrunc(&q, &r, &q, &b); | 327 | try Int.divTrunc(&q, &r, q, b); |
| 349 | 328 | ||
| 350 | var r_word = r.limbs[0]; | 329 | var r_word = r.limbs[0]; |
| 351 | var i: usize = 0; | 330 | var i: usize = 0; |
| 352 | while (i < digits_per_limb) : (i += 1) { | 331 | while (i < digits_per_limb) : (i += 1) { |
| 353 | const ch = try digitToChar(u8(r_word % base), base); | 332 | const ch = try digitToChar(@intCast(u8, r_word % base), base); |
| 354 | r_word /= base; | 333 | r_word /= base; |
| 355 | try digits.append(ch); | 334 | try digits.append(ch); |
| 356 | } | 335 | } |
| ... | @@ -361,7 +340,7 @@ pub const Int = struct { | ... | @@ -361,7 +340,7 @@ pub const Int = struct { |
| 361 | 340 | ||
| 362 | var r_word = q.limbs[0]; | 341 | var r_word = q.limbs[0]; |
| 363 | while (r_word != 0) { | 342 | while (r_word != 0) { |
| 364 | const ch = try digitToChar(u8(r_word % base), base); | 343 | const ch = try digitToChar(@intCast(u8, r_word % base), base); |
| 365 | r_word /= base; | 344 | r_word /= base; |
| 366 | try digits.append(ch); | 345 | try digits.append(ch); |
| 367 | } | 346 | } |
| ... | @@ -378,12 +357,7 @@ pub const Int = struct { | ... | @@ -378,12 +357,7 @@ pub const Int = struct { |
| 378 | } | 357 | } |
| 379 | 358 | ||
| 380 | // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively. | 359 | // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively. |
| 381 | pub fn cmpAbs(a: *const Int, bv: var) i8 { | 360 | pub fn cmpAbs(a: Int, b: Int) i8 { |
| 382 | // TODO: Thread-local buffer. | ||
| 383 | var buffer: [wrapped_buffer_size]u8 = undefined; | ||
| 384 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 385 | var b = wrapInt(&stack.allocator, bv); | ||
| 386 | |||
| 387 | if (a.len < b.len) { | 361 | if (a.len < b.len) { |
| 388 | return -1; | 362 | return -1; |
| 389 | } | 363 | } |
| ... | @@ -408,11 +382,7 @@ pub const Int = struct { | ... | @@ -408,11 +382,7 @@ pub const Int = struct { |
| 408 | } | 382 | } |
| 409 | 383 | ||
| 410 | // returns -1, 0, 1 if a < b, a == b or a > b respectively. | 384 | // returns -1, 0, 1 if a < b, a == b or a > b respectively. |
| 411 | pub fn cmp(a: *const Int, bv: var) i8 { | 385 | pub fn cmp(a: Int, b: Int) i8 { |
| 412 | var buffer: [wrapped_buffer_size]u8 = undefined; | ||
| 413 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 414 | var b = wrapInt(&stack.allocator, bv); | ||
| 415 | |||
| 416 | if (a.positive != b.positive) { | 386 | if (a.positive != b.positive) { |
| 417 | return if (a.positive) i8(1) else -1; | 387 | return if (a.positive) i8(1) else -1; |
| 418 | } else { | 388 | } else { |
| ... | @@ -422,17 +392,17 @@ pub const Int = struct { | ... | @@ -422,17 +392,17 @@ pub const Int = struct { |
| 422 | } | 392 | } |
| 423 | 393 | ||
| 424 | // if a == 0 | 394 | // if a == 0 |
| 425 | pub fn eqZero(a: *const Int) bool { | 395 | pub fn eqZero(a: Int) bool { |
| 426 | return a.len == 1 and a.limbs[0] == 0; | 396 | return a.len == 1 and a.limbs[0] == 0; |
| 427 | } | 397 | } |
| 428 | 398 | ||
| 429 | // if |a| == |b| | 399 | // if |a| == |b| |
| 430 | pub fn eqAbs(a: *const Int, b: var) bool { | 400 | pub fn eqAbs(a: Int, b: Int) bool { |
| 431 | return cmpAbs(a, b) == 0; | 401 | return cmpAbs(a, b) == 0; |
| 432 | } | 402 | } |
| 433 | 403 | ||
| 434 | // if a == b | 404 | // if a == b |
| 435 | pub fn eq(a: *const Int, b: var) bool { | 405 | pub fn eq(a: Int, b: Int) bool { |
| 436 | return cmp(a, b) == 0; | 406 | return cmp(a, b) == 0; |
| 437 | } | 407 | } |
| 438 | 408 | ||
| ... | @@ -473,12 +443,7 @@ pub const Int = struct { | ... | @@ -473,12 +443,7 @@ pub const Int = struct { |
| 473 | } | 443 | } |
| 474 | 444 | ||
| 475 | // r = a + b | 445 | // r = a + b |
| 476 | pub fn add(r: *Int, av: var, bv: var) Allocator.Error!void { | 446 | pub fn add(r: *Int, a: Int, b: Int) Allocator.Error!void { |
| 477 | var buffer: [2 * wrapped_buffer_size]u8 = undefined; | ||
| 478 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 479 | var a = wrapInt(&stack.allocator, av); | ||
| 480 | var b = wrapInt(&stack.allocator, bv); | ||
| 481 | |||
| 482 | if (a.eqZero()) { | 447 | if (a.eqZero()) { |
| 483 | try r.copy(b); | 448 | try r.copy(b); |
| 484 | return; | 449 | return; |
| ... | @@ -534,25 +499,20 @@ pub const Int = struct { | ... | @@ -534,25 +499,20 @@ pub const Int = struct { |
| 534 | 499 | ||
| 535 | while (i < b.len) : (i += 1) { | 500 | while (i < b.len) : (i += 1) { |
| 536 | var c: Limb = 0; | 501 | var c: Limb = 0; |
| 537 | c += Limb(@addWithOverflow(Limb, a[i], b[i], &r[i])); | 502 | c += @boolToInt(@addWithOverflow(Limb, a[i], b[i], &r[i])); |
| 538 | c += Limb(@addWithOverflow(Limb, r[i], carry, &r[i])); | 503 | c += @boolToInt(@addWithOverflow(Limb, r[i], carry, &r[i])); |
| 539 | carry = c; | 504 | carry = c; |
| 540 | } | 505 | } |
| 541 | 506 | ||
| 542 | while (i < a.len) : (i += 1) { | 507 | while (i < a.len) : (i += 1) { |
| 543 | carry = Limb(@addWithOverflow(Limb, a[i], carry, &r[i])); | 508 | carry = @boolToInt(@addWithOverflow(Limb, a[i], carry, &r[i])); |
| 544 | } | 509 | } |
| 545 | 510 | ||
| 546 | r[i] = carry; | 511 | r[i] = carry; |
| 547 | } | 512 | } |
| 548 | 513 | ||
| 549 | // r = a - b | 514 | // r = a - b |
| 550 | pub fn sub(r: *Int, av: var, bv: var) !void { | 515 | pub fn sub(r: *Int, a: Int, b: Int) !void { |
| 551 | var buffer: [wrapped_buffer_size]u8 = undefined; | ||
| 552 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 553 | var a = wrapInt(&stack.allocator, av); | ||
| 554 | var b = wrapInt(&stack.allocator, bv); | ||
| 555 | |||
| 556 | if (a.positive != b.positive) { | 516 | if (a.positive != b.positive) { |
| 557 | if (a.positive) { | 517 | if (a.positive) { |
| 558 | // (a) - (-b) => a + b | 518 | // (a) - (-b) => a + b |
| ... | @@ -617,13 +577,13 @@ pub const Int = struct { | ... | @@ -617,13 +577,13 @@ pub const Int = struct { |
| 617 | 577 | ||
| 618 | while (i < b.len) : (i += 1) { | 578 | while (i < b.len) : (i += 1) { |
| 619 | var c: Limb = 0; | 579 | var c: Limb = 0; |
| 620 | c += Limb(@subWithOverflow(Limb, a[i], b[i], &r[i])); | 580 | c += @boolToInt(@subWithOverflow(Limb, a[i], b[i], &r[i])); |
| 621 | c += Limb(@subWithOverflow(Limb, r[i], borrow, &r[i])); | 581 | c += @boolToInt(@subWithOverflow(Limb, r[i], borrow, &r[i])); |
| 622 | borrow = c; | 582 | borrow = c; |
| 623 | } | 583 | } |
| 624 | 584 | ||
| 625 | while (i < a.len) : (i += 1) { | 585 | while (i < a.len) : (i += 1) { |
| 626 | borrow = Limb(@subWithOverflow(Limb, a[i], borrow, &r[i])); | 586 | borrow = @boolToInt(@subWithOverflow(Limb, a[i], borrow, &r[i])); |
| 627 | } | 587 | } |
| 628 | 588 | ||
| 629 | debug.assert(borrow == 0); | 589 | debug.assert(borrow == 0); |
| ... | @@ -632,14 +592,9 @@ pub const Int = struct { | ... | @@ -632,14 +592,9 @@ pub const Int = struct { |
| 632 | // rma = a * b | 592 | // rma = a * b |
| 633 | // | 593 | // |
| 634 | // For greatest efficiency, ensure rma does not alias a or b. | 594 | // For greatest efficiency, ensure rma does not alias a or b. |
| 635 | pub fn mul(rma: *Int, av: var, bv: var) !void { | 595 | pub fn mul(rma: *Int, a: Int, b: Int) !void { |
| 636 | var buffer: [2 * wrapped_buffer_size]u8 = undefined; | ||
| 637 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 638 | var a = wrapInt(&stack.allocator, av); | ||
| 639 | var b = wrapInt(&stack.allocator, bv); | ||
| 640 | |||
| 641 | var r = rma; | 596 | var r = rma; |
| 642 | var aliased = rma == a or rma == b; | 597 | var aliased = rma.limbs.ptr == a.limbs.ptr or rma.limbs.ptr == b.limbs.ptr; |
| 643 | 598 | ||
| 644 | var sr: Int = undefined; | 599 | var sr: Int = undefined; |
| 645 | if (aliased) { | 600 | if (aliased) { |
| ... | @@ -669,7 +624,7 @@ pub const Int = struct { | ... | @@ -669,7 +624,7 @@ pub const Int = struct { |
| 669 | var r1: Limb = undefined; | 624 | var r1: Limb = undefined; |
| 670 | 625 | ||
| 671 | // r1 = a + *carry | 626 | // r1 = a + *carry |
| 672 | const c1 = Limb(@addWithOverflow(Limb, a, carry.*, &r1)); | 627 | const c1: Limb = @boolToInt(@addWithOverflow(Limb, a, carry.*, &r1)); |
| 673 | 628 | ||
| 674 | // r2 = b * c | 629 | // r2 = b * c |
| 675 | // | 630 | // |
| ... | @@ -684,7 +639,7 @@ pub const Int = struct { | ... | @@ -684,7 +639,7 @@ pub const Int = struct { |
| 684 | const c2 = @truncate(Limb, bc >> Limb.bit_count); | 639 | const c2 = @truncate(Limb, bc >> Limb.bit_count); |
| 685 | 640 | ||
| 686 | // r1 = r1 + r2 | 641 | // r1 = r1 + r2 |
| 687 | const c3 = Limb(@addWithOverflow(Limb, r1, r2, &r1)); | 642 | const c3: Limb = @boolToInt(@addWithOverflow(Limb, r1, r2, &r1)); |
| 688 | 643 | ||
| 689 | // 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 |
| 690 | // c2 is at least <= @maxValue(Limb) - 2. | 645 | // c2 is at least <= @maxValue(Limb) - 2. |
| ... | @@ -714,29 +669,29 @@ pub const Int = struct { | ... | @@ -714,29 +669,29 @@ pub const Int = struct { |
| 714 | } | 669 | } |
| 715 | } | 670 | } |
| 716 | 671 | ||
| 717 | pub fn divFloor(q: *Int, r: *Int, a: var, b: var) !void { | 672 | pub fn divFloor(q: *Int, r: *Int, a: Int, b: Int) !void { |
| 718 | try div(q, r, a, b); | 673 | try div(q, r, a, b); |
| 719 | 674 | ||
| 720 | // Trunc -> Floor. | 675 | // Trunc -> Floor. |
| 721 | if (!q.positive) { | 676 | if (!q.positive) { |
| 722 | try q.sub(q, 1); | 677 | // TODO values less than limb size should guarantee non allocating |
| 723 | try r.add(q, 1); | 678 | var one_buffer: [512]u8 = undefined; |
| 679 | const one_al = &std.heap.FixedBufferAllocator.init(one_buffer[0..]).allocator; | ||
| 680 | const one_ap = try Int.initSet(one_al, 1); | ||
| 681 | |||
| 682 | try q.sub(q.*, one_ap); | ||
| 683 | try r.add(q.*, one_ap); | ||
| 724 | } | 684 | } |
| 725 | r.positive = b.positive; | 685 | r.positive = b.positive; |
| 726 | } | 686 | } |
| 727 | 687 | ||
| 728 | pub fn divTrunc(q: *Int, r: *Int, a: var, b: var) !void { | 688 | pub fn divTrunc(q: *Int, r: *Int, a: Int, b: Int) !void { |
| 729 | try div(q, r, a, b); | 689 | try div(q, r, a, b); |
| 730 | r.positive = a.positive; | 690 | r.positive = a.positive; |
| 731 | } | 691 | } |
| 732 | 692 | ||
| 733 | // Truncates by default. | 693 | // Truncates by default. |
| 734 | fn div(quo: *Int, rem: *Int, av: var, bv: var) !void { | 694 | fn div(quo: *Int, rem: *Int, a: Int, b: Int) !void { |
| 735 | var buffer: [2 * wrapped_buffer_size]u8 = undefined; | ||
| 736 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 737 | var a = wrapInt(&stack.allocator, av); | ||
| 738 | var b = wrapInt(&stack.allocator, bv); | ||
| 739 | |||
| 740 | if (b.eqZero()) { | 695 | if (b.eqZero()) { |
| 741 | @panic("division by zero"); | 696 | @panic("division by zero"); |
| 742 | } | 697 | } |
| ... | @@ -821,8 +776,8 @@ pub const Int = struct { | ... | @@ -821,8 +776,8 @@ pub const Int = struct { |
| 821 | 776 | ||
| 822 | // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) | 777 | // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) |
| 823 | const norm_shift = @clz(y.limbs[y.len - 1]); | 778 | const norm_shift = @clz(y.limbs[y.len - 1]); |
| 824 | try x.shiftLeft(x, norm_shift); | 779 | try x.shiftLeft(x.*, norm_shift); |
| 825 | try y.shiftLeft(y, norm_shift); | 780 | try y.shiftLeft(y.*, norm_shift); |
| 826 | 781 | ||
| 827 | const n = x.len - 1; | 782 | const n = x.len - 1; |
| 828 | const t = y.len - 1; | 783 | const t = y.len - 1; |
| ... | @@ -832,10 +787,10 @@ pub const Int = struct { | ... | @@ -832,10 +787,10 @@ pub const Int = struct { |
| 832 | mem.set(Limb, q.limbs[0..q.len], 0); | 787 | mem.set(Limb, q.limbs[0..q.len], 0); |
| 833 | 788 | ||
| 834 | // 2. | 789 | // 2. |
| 835 | try tmp.shiftLeft(y, Limb.bit_count * (n - t)); | 790 | try tmp.shiftLeft(y.*, Limb.bit_count * (n - t)); |
| 836 | while (x.cmp(&tmp) >= 0) { | 791 | while (x.cmp(tmp) >= 0) { |
| 837 | q.limbs[n - t] += 1; | 792 | q.limbs[n - t] += 1; |
| 838 | try x.sub(x, tmp); | 793 | try x.sub(x.*, tmp); |
| 839 | } | 794 | } |
| 840 | 795 | ||
| 841 | // 3. | 796 | // 3. |
| ... | @@ -846,7 +801,7 @@ pub const Int = struct { | ... | @@ -846,7 +801,7 @@ pub const Int = struct { |
| 846 | q.limbs[i - t - 1] = @maxValue(Limb); | 801 | q.limbs[i - t - 1] = @maxValue(Limb); |
| 847 | } else { | 802 | } else { |
| 848 | const num = (DoubleLimb(x.limbs[i]) << Limb.bit_count) | DoubleLimb(x.limbs[i - 1]); | 803 | const num = (DoubleLimb(x.limbs[i]) << Limb.bit_count) | DoubleLimb(x.limbs[i - 1]); |
| 849 | const z = Limb(num / DoubleLimb(y.limbs[t])); | 804 | const z = @intCast(Limb, num / DoubleLimb(y.limbs[t])); |
| 850 | q.limbs[i - t - 1] = if (z > @maxValue(Limb)) @maxValue(Limb) else Limb(z); | 805 | q.limbs[i - t - 1] = if (z > @maxValue(Limb)) @maxValue(Limb) else Limb(z); |
| 851 | } | 806 | } |
| 852 | 807 | ||
| ... | @@ -864,7 +819,7 @@ pub const Int = struct { | ... | @@ -864,7 +819,7 @@ pub const Int = struct { |
| 864 | r.limbs[2] = carry; | 819 | r.limbs[2] = carry; |
| 865 | r.normN(3); | 820 | r.normN(3); |
| 866 | 821 | ||
| 867 | if (r.cmpAbs(&tmp) <= 0) { | 822 | if (r.cmpAbs(tmp) <= 0) { |
| 868 | break; | 823 | break; |
| 869 | } | 824 | } |
| 870 | 825 | ||
| ... | @@ -873,13 +828,13 @@ pub const Int = struct { | ... | @@ -873,13 +828,13 @@ pub const Int = struct { |
| 873 | 828 | ||
| 874 | // 3.3 | 829 | // 3.3 |
| 875 | try tmp.set(q.limbs[i - t - 1]); | 830 | try tmp.set(q.limbs[i - t - 1]); |
| 876 | try tmp.mul(&tmp, y); | 831 | try tmp.mul(tmp, y.*); |
| 877 | try tmp.shiftLeft(&tmp, Limb.bit_count * (i - t - 1)); | 832 | try tmp.shiftLeft(tmp, Limb.bit_count * (i - t - 1)); |
| 878 | try x.sub(x, &tmp); | 833 | try x.sub(x.*, tmp); |
| 879 | 834 | ||
| 880 | if (!x.positive) { | 835 | if (!x.positive) { |
| 881 | try tmp.shiftLeft(y, Limb.bit_count * (i - t - 1)); | 836 | try tmp.shiftLeft(y.*, Limb.bit_count * (i - t - 1)); |
| 882 | try x.add(x, &tmp); | 837 | try x.add(x.*, tmp); |
| 883 | q.limbs[i - t - 1] -= 1; | 838 | q.limbs[i - t - 1] -= 1; |
| 884 | } | 839 | } |
| 885 | } | 840 | } |
| ... | @@ -887,16 +842,12 @@ pub const Int = struct { | ... | @@ -887,16 +842,12 @@ pub const Int = struct { |
| 887 | // Denormalize | 842 | // Denormalize |
| 888 | q.normN(q.len); | 843 | q.normN(q.len); |
| 889 | 844 | ||
| 890 | try r.shiftRight(x, norm_shift); | 845 | try r.shiftRight(x.*, norm_shift); |
| 891 | r.normN(r.len); | 846 | r.normN(r.len); |
| 892 | } | 847 | } |
| 893 | 848 | ||
| 894 | // r = a << shift, in other words, r = a * 2^shift | 849 | // r = a << shift, in other words, r = a * 2^shift |
| 895 | pub fn shiftLeft(r: *Int, av: var, shift: usize) !void { | 850 | pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void { |
| 896 | var buffer: [wrapped_buffer_size]u8 = undefined; | ||
| 897 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 898 | var a = wrapInt(&stack.allocator, av); | ||
| 899 | |||
| 900 | try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1); | 851 | try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1); |
| 901 | llshl(r.limbs[0..], a.limbs[0..a.len], shift); | 852 | llshl(r.limbs[0..], a.limbs[0..a.len], shift); |
| 902 | r.norm1(a.len + (shift / Limb.bit_count) + 1); | 853 | r.norm1(a.len + (shift / Limb.bit_count) + 1); |
| ... | @@ -909,7 +860,7 @@ pub const Int = struct { | ... | @@ -909,7 +860,7 @@ pub const Int = struct { |
| 909 | debug.assert(r.len >= a.len + (shift / Limb.bit_count) + 1); | 860 | debug.assert(r.len >= a.len + (shift / Limb.bit_count) + 1); |
| 910 | 861 | ||
| 911 | const limb_shift = shift / Limb.bit_count + 1; | 862 | const limb_shift = shift / Limb.bit_count + 1; |
| 912 | const interior_limb_shift = Log2Limb(shift % Limb.bit_count); | 863 | const interior_limb_shift = @intCast(Log2Limb, shift % Limb.bit_count); |
| 913 | 864 | ||
| 914 | var carry: Limb = 0; | 865 | var carry: Limb = 0; |
| 915 | var i: usize = 0; | 866 | var i: usize = 0; |
| ... | @@ -918,7 +869,7 @@ pub const Int = struct { | ... | @@ -918,7 +869,7 @@ pub const Int = struct { |
| 918 | const dst_i = src_i + limb_shift; | 869 | const dst_i = src_i + limb_shift; |
| 919 | 870 | ||
| 920 | const src_digit = a[src_i]; | 871 | const src_digit = a[src_i]; |
| 921 | r[dst_i] = carry | @inlineCall(math.shr, Limb, src_digit, Limb.bit_count - Limb(interior_limb_shift)); | 872 | r[dst_i] = carry | @inlineCall(math.shr, Limb, src_digit, Limb.bit_count - @intCast(Limb, interior_limb_shift)); |
| 922 | carry = (src_digit << interior_limb_shift); | 873 | carry = (src_digit << interior_limb_shift); |
| 923 | } | 874 | } |
| 924 | 875 | ||
| ... | @@ -927,11 +878,7 @@ pub const Int = struct { | ... | @@ -927,11 +878,7 @@ pub const Int = struct { |
| 927 | } | 878 | } |
| 928 | 879 | ||
| 929 | // r = a >> shift | 880 | // r = a >> shift |
| 930 | pub fn shiftRight(r: *Int, av: var, shift: usize) !void { | 881 | pub fn shiftRight(r: *Int, a: Int, shift: usize) !void { |
| 931 | var buffer: [wrapped_buffer_size]u8 = undefined; | ||
| 932 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 933 | var a = wrapInt(&stack.allocator, av); | ||
| 934 | |||
| 935 | if (a.len <= shift / Limb.bit_count) { | 882 | if (a.len <= shift / Limb.bit_count) { |
| 936 | r.len = 1; | 883 | r.len = 1; |
| 937 | r.limbs[0] = 0; | 884 | r.limbs[0] = 0; |
| ... | @@ -951,7 +898,7 @@ pub const Int = struct { | ... | @@ -951,7 +898,7 @@ pub const Int = struct { |
| 951 | debug.assert(r.len >= a.len - (shift / Limb.bit_count)); | 898 | debug.assert(r.len >= a.len - (shift / Limb.bit_count)); |
| 952 | 899 | ||
| 953 | const limb_shift = shift / Limb.bit_count; | 900 | const limb_shift = shift / Limb.bit_count; |
| 954 | const interior_limb_shift = Log2Limb(shift % Limb.bit_count); | 901 | const interior_limb_shift = @intCast(Log2Limb, shift % Limb.bit_count); |
| 955 | 902 | ||
| 956 | var carry: Limb = 0; | 903 | var carry: Limb = 0; |
| 957 | var i: usize = 0; | 904 | var i: usize = 0; |
| ... | @@ -961,17 +908,12 @@ pub const Int = struct { | ... | @@ -961,17 +908,12 @@ pub const Int = struct { |
| 961 | 908 | ||
| 962 | const src_digit = a[src_i]; | 909 | const src_digit = a[src_i]; |
| 963 | r[dst_i] = carry | (src_digit >> interior_limb_shift); | 910 | r[dst_i] = carry | (src_digit >> interior_limb_shift); |
| 964 | carry = @inlineCall(math.shl, Limb, src_digit, Limb.bit_count - Limb(interior_limb_shift)); | 911 | carry = @inlineCall(math.shl, Limb, src_digit, Limb.bit_count - @intCast(Limb, interior_limb_shift)); |
| 965 | } | 912 | } |
| 966 | } | 913 | } |
| 967 | 914 | ||
| 968 | // r = a | b | 915 | // r = a | b |
| 969 | pub fn bitOr(r: *Int, av: var, bv: var) !void { | 916 | pub fn bitOr(r: *Int, a: Int, b: Int) !void { |
| 970 | var buffer: [2 * wrapped_buffer_size]u8 = undefined; | ||
| 971 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 972 | var a = wrapInt(&stack.allocator, av); | ||
| 973 | var b = wrapInt(&stack.allocator, bv); | ||
| 974 | |||
| 975 | if (a.len > b.len) { | 917 | if (a.len > b.len) { |
| 976 | try r.ensureCapacity(a.len); | 918 | try r.ensureCapacity(a.len); |
| 977 | llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); | 919 | llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); |
| ... | @@ -998,12 +940,7 @@ pub const Int = struct { | ... | @@ -998,12 +940,7 @@ pub const Int = struct { |
| 998 | } | 940 | } |
| 999 | 941 | ||
| 1000 | // r = a & b | 942 | // r = a & b |
| 1001 | pub fn bitAnd(r: *Int, av: var, bv: var) !void { | 943 | pub fn bitAnd(r: *Int, a: Int, b: Int) !void { |
| 1002 | var buffer: [2 * wrapped_buffer_size]u8 = undefined; | ||
| 1003 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 1004 | var a = wrapInt(&stack.allocator, av); | ||
| 1005 | var b = wrapInt(&stack.allocator, bv); | ||
| 1006 | |||
| 1007 | if (a.len > b.len) { | 944 | if (a.len > b.len) { |
| 1008 | try r.ensureCapacity(b.len); | 945 | try r.ensureCapacity(b.len); |
| 1009 | lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); | 946 | lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); |
| ... | @@ -1027,12 +964,7 @@ pub const Int = struct { | ... | @@ -1027,12 +964,7 @@ pub const Int = struct { |
| 1027 | } | 964 | } |
| 1028 | 965 | ||
| 1029 | // r = a ^ b | 966 | // r = a ^ b |
| 1030 | pub fn bitXor(r: *Int, av: var, bv: var) !void { | 967 | pub fn bitXor(r: *Int, a: Int, b: Int) !void { |
| 1031 | var buffer: [2 * wrapped_buffer_size]u8 = undefined; | ||
| 1032 | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); | ||
| 1033 | var a = wrapInt(&stack.allocator, av); | ||
| 1034 | var b = wrapInt(&stack.allocator, bv); | ||
| 1035 | |||
| 1036 | if (a.len > b.len) { | 968 | if (a.len > b.len) { |
| 1037 | try r.ensureCapacity(a.len); | 969 | try r.ensureCapacity(a.len); |
| 1038 | llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); | 970 | llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); |
| ... | @@ -1065,7 +997,7 @@ pub const Int = struct { | ... | @@ -1065,7 +997,7 @@ pub const Int = struct { |
| 1065 | // may be untested in some cases. | 997 | // may be untested in some cases. |
| 1066 | 998 | ||
| 1067 | const u256 = @IntType(false, 256); | 999 | const u256 = @IntType(false, 256); |
| 1068 | var al = debug.global_allocator; | 1000 | const al = debug.global_allocator; |
| 1069 | 1001 | ||
| 1070 | test "big.int comptime_int set" { | 1002 | test "big.int comptime_int set" { |
| 1071 | comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab; | 1003 | comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab; |
| ... | @@ -1198,7 +1130,7 @@ test "big.int bitcount + sizeInBase" { | ... | @@ -1198,7 +1130,7 @@ test "big.int bitcount + sizeInBase" { |
| 1198 | debug.assert(a.sizeInBase(2) >= 32); | 1130 | debug.assert(a.sizeInBase(2) >= 32); |
| 1199 | debug.assert(a.sizeInBase(10) >= 10); | 1131 | debug.assert(a.sizeInBase(10) >= 10); |
| 1200 | 1132 | ||
| 1201 | try a.shiftLeft(&a, 5000); | 1133 | try a.shiftLeft(a, 5000); |
| 1202 | debug.assert(a.bitcount() == 5032); | 1134 | debug.assert(a.bitcount() == 5032); |
| 1203 | debug.assert(a.sizeInBase(2) >= 5032); | 1135 | debug.assert(a.sizeInBase(2) >= 5032); |
| 1204 | a.positive = false; | 1136 | a.positive = false; |
| ... | @@ -1320,40 +1252,40 @@ test "big.int compare" { | ... | @@ -1320,40 +1252,40 @@ test "big.int compare" { |
| 1320 | var a = try Int.initSet(al, -11); | 1252 | var a = try Int.initSet(al, -11); |
| 1321 | var b = try Int.initSet(al, 10); | 1253 | var b = try Int.initSet(al, 10); |
| 1322 | 1254 | ||
| 1323 | debug.assert(a.cmpAbs(&b) == 1); | 1255 | debug.assert(a.cmpAbs(b) == 1); |
| 1324 | debug.assert(a.cmp(&b) == -1); | 1256 | debug.assert(a.cmp(b) == -1); |
| 1325 | } | 1257 | } |
| 1326 | 1258 | ||
| 1327 | test "big.int compare similar" { | 1259 | test "big.int compare similar" { |
| 1328 | var a = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeee); | 1260 | var a = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeee); |
| 1329 | var b = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeef); | 1261 | var b = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeef); |
| 1330 | 1262 | ||
| 1331 | debug.assert(a.cmpAbs(&b) == -1); | 1263 | debug.assert(a.cmpAbs(b) == -1); |
| 1332 | debug.assert(b.cmpAbs(&a) == 1); | 1264 | debug.assert(b.cmpAbs(a) == 1); |
| 1333 | } | 1265 | } |
| 1334 | 1266 | ||
| 1335 | test "big.int compare different limb size" { | 1267 | test "big.int compare different limb size" { |
| 1336 | var a = try Int.initSet(al, @maxValue(Limb) + 1); | 1268 | var a = try Int.initSet(al, @maxValue(Limb) + 1); |
| 1337 | var b = try Int.initSet(al, 1); | 1269 | var b = try Int.initSet(al, 1); |
| 1338 | 1270 | ||
| 1339 | debug.assert(a.cmpAbs(&b) == 1); | 1271 | debug.assert(a.cmpAbs(b) == 1); |
| 1340 | debug.assert(b.cmpAbs(&a) == -1); | 1272 | debug.assert(b.cmpAbs(a) == -1); |
| 1341 | } | 1273 | } |
| 1342 | 1274 | ||
| 1343 | test "big.int compare multi-limb" { | 1275 | test "big.int compare multi-limb" { |
| 1344 | var a = try Int.initSet(al, -0x7777777799999999ffffeeeeffffeeeeffffeeeef); | 1276 | var a = try Int.initSet(al, -0x7777777799999999ffffeeeeffffeeeeffffeeeef); |
| 1345 | var b = try Int.initSet(al, 0x7777777799999999ffffeeeeffffeeeeffffeeeee); | 1277 | var b = try Int.initSet(al, 0x7777777799999999ffffeeeeffffeeeeffffeeeee); |
| 1346 | 1278 | ||
| 1347 | debug.assert(a.cmpAbs(&b) == 1); | 1279 | debug.assert(a.cmpAbs(b) == 1); |
| 1348 | debug.assert(a.cmp(&b) == -1); | 1280 | debug.assert(a.cmp(b) == -1); |
| 1349 | } | 1281 | } |
| 1350 | 1282 | ||
| 1351 | test "big.int equality" { | 1283 | test "big.int equality" { |
| 1352 | var a = try Int.initSet(al, 0xffffffff1); | 1284 | var a = try Int.initSet(al, 0xffffffff1); |
| 1353 | var b = try Int.initSet(al, -0xffffffff1); | 1285 | var b = try Int.initSet(al, -0xffffffff1); |
| 1354 | 1286 | ||
| 1355 | debug.assert(a.eqAbs(&b)); | 1287 | debug.assert(a.eqAbs(b)); |
| 1356 | debug.assert(!a.eq(&b)); | 1288 | debug.assert(!a.eq(b)); |
| 1357 | } | 1289 | } |
| 1358 | 1290 | ||
| 1359 | test "big.int abs" { | 1291 | test "big.int abs" { |
| ... | @@ -1381,7 +1313,7 @@ test "big.int add single-single" { | ... | @@ -1381,7 +1313,7 @@ test "big.int add single-single" { |
| 1381 | var b = try Int.initSet(al, 5); | 1313 | var b = try Int.initSet(al, 5); |
| 1382 | 1314 | ||
| 1383 | var c = try Int.init(al); | 1315 | var c = try Int.init(al); |
| 1384 | try c.add(&a, &b); | 1316 | try c.add(a, b); |
| 1385 | 1317 | ||
| 1386 | debug.assert((try c.to(u32)) == 55); | 1318 | debug.assert((try c.to(u32)) == 55); |
| 1387 | } | 1319 | } |
| ... | @@ -1392,10 +1324,10 @@ test "big.int add multi-single" { | ... | @@ -1392,10 +1324,10 @@ test "big.int add multi-single" { |
| 1392 | 1324 | ||
| 1393 | var c = try Int.init(al); | 1325 | var c = try Int.init(al); |
| 1394 | 1326 | ||
| 1395 | try c.add(&a, &b); | 1327 | try c.add(a, b); |
| 1396 | debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2); | 1328 | debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2); |
| 1397 | 1329 | ||
| 1398 | try c.add(&b, &a); | 1330 | try c.add(b, a); |
| 1399 | debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2); | 1331 | debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2); |
| 1400 | } | 1332 | } |
| 1401 | 1333 | ||
| ... | @@ -1406,7 +1338,7 @@ test "big.int add multi-multi" { | ... | @@ -1406,7 +1338,7 @@ test "big.int add multi-multi" { |
| 1406 | var b = try Int.initSet(al, op2); | 1338 | var b = try Int.initSet(al, op2); |
| 1407 | 1339 | ||
| 1408 | var c = try Int.init(al); | 1340 | var c = try Int.init(al); |
| 1409 | try c.add(&a, &b); | 1341 | try c.add(a, b); |
| 1410 | 1342 | ||
| 1411 | debug.assert((try c.to(u128)) == op1 + op2); | 1343 | debug.assert((try c.to(u128)) == op1 + op2); |
| 1412 | } | 1344 | } |
| ... | @@ -1416,7 +1348,7 @@ test "big.int add zero-zero" { | ... | @@ -1416,7 +1348,7 @@ test "big.int add zero-zero" { |
| 1416 | var b = try Int.initSet(al, 0); | 1348 | var b = try Int.initSet(al, 0); |
| 1417 | 1349 | ||
| 1418 | var c = try Int.init(al); | 1350 | var c = try Int.init(al); |
| 1419 | try c.add(&a, &b); | 1351 | try c.add(a, b); |
| 1420 | 1352 | ||
| 1421 | debug.assert((try c.to(u32)) == 0); | 1353 | debug.assert((try c.to(u32)) == 0); |
| 1422 | } | 1354 | } |
| ... | @@ -1426,7 +1358,7 @@ test "big.int add alias multi-limb nonzero-zero" { | ... | @@ -1426,7 +1358,7 @@ test "big.int add alias multi-limb nonzero-zero" { |
| 1426 | var a = try Int.initSet(al, op1); | 1358 | var a = try Int.initSet(al, op1); |
| 1427 | var b = try Int.initSet(al, 0); | 1359 | var b = try Int.initSet(al, 0); |
| 1428 | 1360 | ||
| 1429 | try a.add(&a, &b); | 1361 | try a.add(a, b); |
| 1430 | 1362 | ||
| 1431 | debug.assert((try a.to(u128)) == op1); | 1363 | debug.assert((try a.to(u128)) == op1); |
| 1432 | } | 1364 | } |
| ... | @@ -1434,16 +1366,21 @@ test "big.int add alias multi-limb nonzero-zero" { | ... | @@ -1434,16 +1366,21 @@ test "big.int add alias multi-limb nonzero-zero" { |
| 1434 | test "big.int add sign" { | 1366 | test "big.int add sign" { |
| 1435 | var a = try Int.init(al); | 1367 | var a = try Int.init(al); |
| 1436 | 1368 | ||
| 1437 | try a.add(1, 2); | 1369 | const one = try Int.initSet(al, 1); |
| 1370 | const two = try Int.initSet(al, 2); | ||
| 1371 | const neg_one = try Int.initSet(al, -1); | ||
| 1372 | const neg_two = try Int.initSet(al, -2); | ||
| 1373 | |||
| 1374 | try a.add(one, two); | ||
| 1438 | debug.assert((try a.to(i32)) == 3); | 1375 | debug.assert((try a.to(i32)) == 3); |
| 1439 | 1376 | ||
| 1440 | try a.add(-1, 2); | 1377 | try a.add(neg_one, two); |
| 1441 | debug.assert((try a.to(i32)) == 1); | 1378 | debug.assert((try a.to(i32)) == 1); |
| 1442 | 1379 | ||
| 1443 | try a.add(1, -2); | 1380 | try a.add(one, neg_two); |
| 1444 | debug.assert((try a.to(i32)) == -1); | 1381 | debug.assert((try a.to(i32)) == -1); |
| 1445 | 1382 | ||
| 1446 | try a.add(-1, -2); | 1383 | try a.add(neg_one, neg_two); |
| 1447 | debug.assert((try a.to(i32)) == -3); | 1384 | debug.assert((try a.to(i32)) == -3); |
| 1448 | } | 1385 | } |
| 1449 | 1386 | ||
| ... | @@ -1452,7 +1389,7 @@ test "big.int sub single-single" { | ... | @@ -1452,7 +1389,7 @@ test "big.int sub single-single" { |
| 1452 | var b = try Int.initSet(al, 5); | 1389 | var b = try Int.initSet(al, 5); |
| 1453 | 1390 | ||
| 1454 | var c = try Int.init(al); | 1391 | var c = try Int.init(al); |
| 1455 | try c.sub(&a, &b); | 1392 | try c.sub(a, b); |
| 1456 | 1393 | ||
| 1457 | debug.assert((try c.to(u32)) == 45); | 1394 | debug.assert((try c.to(u32)) == 45); |
| 1458 | } | 1395 | } |
| ... | @@ -1462,7 +1399,7 @@ test "big.int sub multi-single" { | ... | @@ -1462,7 +1399,7 @@ test "big.int sub multi-single" { |
| 1462 | var b = try Int.initSet(al, 1); | 1399 | var b = try Int.initSet(al, 1); |
| 1463 | 1400 | ||
| 1464 | var c = try Int.init(al); | 1401 | var c = try Int.init(al); |
| 1465 | try c.sub(&a, &b); | 1402 | try c.sub(a, b); |
| 1466 | 1403 | ||
| 1467 | debug.assert((try c.to(Limb)) == @maxValue(Limb)); | 1404 | debug.assert((try c.to(Limb)) == @maxValue(Limb)); |
| 1468 | } | 1405 | } |
| ... | @@ -1475,7 +1412,7 @@ test "big.int sub multi-multi" { | ... | @@ -1475,7 +1412,7 @@ test "big.int sub multi-multi" { |
| 1475 | var b = try Int.initSet(al, op2); | 1412 | var b = try Int.initSet(al, op2); |
| 1476 | 1413 | ||
| 1477 | var c = try Int.init(al); | 1414 | var c = try Int.init(al); |
| 1478 | try c.sub(&a, &b); | 1415 | try c.sub(a, b); |
| 1479 | 1416 | ||
| 1480 | debug.assert((try c.to(u128)) == op1 - op2); | 1417 | debug.assert((try c.to(u128)) == op1 - op2); |
| 1481 | } | 1418 | } |
| ... | @@ -1485,7 +1422,7 @@ test "big.int sub equal" { | ... | @@ -1485,7 +1422,7 @@ test "big.int sub equal" { |
| 1485 | var b = try Int.initSet(al, 0x11efefefefefefefefefefefef); | 1422 | var b = try Int.initSet(al, 0x11efefefefefefefefefefefef); |
| 1486 | 1423 | ||
| 1487 | var c = try Int.init(al); | 1424 | var c = try Int.init(al); |
| 1488 | try c.sub(&a, &b); | 1425 | try c.sub(a, b); |
| 1489 | 1426 | ||
| 1490 | debug.assert((try c.to(u32)) == 0); | 1427 | debug.assert((try c.to(u32)) == 0); |
| 1491 | } | 1428 | } |
| ... | @@ -1493,19 +1430,24 @@ test "big.int sub equal" { | ... | @@ -1493,19 +1430,24 @@ test "big.int sub equal" { |
| 1493 | test "big.int sub sign" { | 1430 | test "big.int sub sign" { |
| 1494 | var a = try Int.init(al); | 1431 | var a = try Int.init(al); |
| 1495 | 1432 | ||
| 1496 | try a.sub(1, 2); | 1433 | const one = try Int.initSet(al, 1); |
| 1434 | const two = try Int.initSet(al, 2); | ||
| 1435 | const neg_one = try Int.initSet(al, -1); | ||
| 1436 | const neg_two = try Int.initSet(al, -2); | ||
| 1437 | |||
| 1438 | try a.sub(one, two); | ||
| 1497 | debug.assert((try a.to(i32)) == -1); | 1439 | debug.assert((try a.to(i32)) == -1); |
| 1498 | 1440 | ||
| 1499 | try a.sub(-1, 2); | 1441 | try a.sub(neg_one, two); |
| 1500 | debug.assert((try a.to(i32)) == -3); | 1442 | debug.assert((try a.to(i32)) == -3); |
| 1501 | 1443 | ||
| 1502 | try a.sub(1, -2); | 1444 | try a.sub(one, neg_two); |
| 1503 | debug.assert((try a.to(i32)) == 3); | 1445 | debug.assert((try a.to(i32)) == 3); |
| 1504 | 1446 | ||
| 1505 | try a.sub(-1, -2); | 1447 | try a.sub(neg_one, neg_two); |
| 1506 | debug.assert((try a.to(i32)) == 1); | 1448 | debug.assert((try a.to(i32)) == 1); |
| 1507 | 1449 | ||
| 1508 | try a.sub(-2, -1); | 1450 | try a.sub(neg_two, neg_one); |
| 1509 | debug.assert((try a.to(i32)) == -1); | 1451 | debug.assert((try a.to(i32)) == -1); |
| 1510 | } | 1452 | } |
| 1511 | 1453 | ||
| ... | @@ -1514,7 +1456,7 @@ test "big.int mul single-single" { | ... | @@ -1514,7 +1456,7 @@ test "big.int mul single-single" { |
| 1514 | var b = try Int.initSet(al, 5); | 1456 | var b = try Int.initSet(al, 5); |
| 1515 | 1457 | ||
| 1516 | var c = try Int.init(al); | 1458 | var c = try Int.init(al); |
| 1517 | try c.mul(&a, &b); | 1459 | try c.mul(a, b); |
| 1518 | 1460 | ||
| 1519 | debug.assert((try c.to(u64)) == 250); | 1461 | debug.assert((try c.to(u64)) == 250); |
| 1520 | } | 1462 | } |
| ... | @@ -1524,7 +1466,7 @@ test "big.int mul multi-single" { | ... | @@ -1524,7 +1466,7 @@ test "big.int mul multi-single" { |
| 1524 | var b = try Int.initSet(al, 2); | 1466 | var b = try Int.initSet(al, 2); |
| 1525 | 1467 | ||
| 1526 | var c = try Int.init(al); | 1468 | var c = try Int.init(al); |
| 1527 | try c.mul(&a, &b); | 1469 | try c.mul(a, b); |
| 1528 | 1470 | ||
| 1529 | debug.assert((try c.to(DoubleLimb)) == 2 * @maxValue(Limb)); | 1471 | debug.assert((try c.to(DoubleLimb)) == 2 * @maxValue(Limb)); |
| 1530 | } | 1472 | } |
| ... | @@ -1536,7 +1478,7 @@ test "big.int mul multi-multi" { | ... | @@ -1536,7 +1478,7 @@ test "big.int mul multi-multi" { |
| 1536 | var b = try Int.initSet(al, op2); | 1478 | var b = try Int.initSet(al, op2); |
| 1537 | 1479 | ||
| 1538 | var c = try Int.init(al); | 1480 | var c = try Int.init(al); |
| 1539 | try c.mul(&a, &b); | 1481 | try c.mul(a, b); |
| 1540 | 1482 | ||
| 1541 | debug.assert((try c.to(u256)) == op1 * op2); | 1483 | debug.assert((try c.to(u256)) == op1 * op2); |
| 1542 | } | 1484 | } |
| ... | @@ -1545,7 +1487,7 @@ test "big.int mul alias r with a" { | ... | @@ -1545,7 +1487,7 @@ test "big.int mul alias r with a" { |
| 1545 | var a = try Int.initSet(al, @maxValue(Limb)); | 1487 | var a = try Int.initSet(al, @maxValue(Limb)); |
| 1546 | var b = try Int.initSet(al, 2); | 1488 | var b = try Int.initSet(al, 2); |
| 1547 | 1489 | ||
| 1548 | try a.mul(&a, &b); | 1490 | try a.mul(a, b); |
| 1549 | 1491 | ||
| 1550 | debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb)); | 1492 | debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb)); |
| 1551 | } | 1493 | } |
| ... | @@ -1554,7 +1496,7 @@ test "big.int mul alias r with b" { | ... | @@ -1554,7 +1496,7 @@ test "big.int mul alias r with b" { |
| 1554 | var a = try Int.initSet(al, @maxValue(Limb)); | 1496 | var a = try Int.initSet(al, @maxValue(Limb)); |
| 1555 | var b = try Int.initSet(al, 2); | 1497 | var b = try Int.initSet(al, 2); |
| 1556 | 1498 | ||
| 1557 | try a.mul(&b, &a); | 1499 | try a.mul(b, a); |
| 1558 | 1500 | ||
| 1559 | debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb)); | 1501 | debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb)); |
| 1560 | } | 1502 | } |
| ... | @@ -1562,7 +1504,7 @@ test "big.int mul alias r with b" { | ... | @@ -1562,7 +1504,7 @@ test "big.int mul alias r with b" { |
| 1562 | test "big.int mul alias r with a and b" { | 1504 | test "big.int mul alias r with a and b" { |
| 1563 | var a = try Int.initSet(al, @maxValue(Limb)); | 1505 | var a = try Int.initSet(al, @maxValue(Limb)); |
| 1564 | 1506 | ||
| 1565 | try a.mul(&a, &a); | 1507 | try a.mul(a, a); |
| 1566 | 1508 | ||
| 1567 | debug.assert((try a.to(DoubleLimb)) == @maxValue(Limb) * @maxValue(Limb)); | 1509 | debug.assert((try a.to(DoubleLimb)) == @maxValue(Limb) * @maxValue(Limb)); |
| 1568 | } | 1510 | } |
| ... | @@ -1572,7 +1514,7 @@ test "big.int mul a*0" { | ... | @@ -1572,7 +1514,7 @@ test "big.int mul a*0" { |
| 1572 | var b = try Int.initSet(al, 0); | 1514 | var b = try Int.initSet(al, 0); |
| 1573 | 1515 | ||
| 1574 | var c = try Int.init(al); | 1516 | var c = try Int.init(al); |
| 1575 | try c.mul(&a, &b); | 1517 | try c.mul(a, b); |
| 1576 | 1518 | ||
| 1577 | debug.assert((try c.to(u32)) == 0); | 1519 | debug.assert((try c.to(u32)) == 0); |
| 1578 | } | 1520 | } |
| ... | @@ -1582,7 +1524,7 @@ test "big.int mul 0*0" { | ... | @@ -1582,7 +1524,7 @@ test "big.int mul 0*0" { |
| 1582 | var b = try Int.initSet(al, 0); | 1524 | var b = try Int.initSet(al, 0); |
| 1583 | 1525 | ||
| 1584 | var c = try Int.init(al); | 1526 | var c = try Int.init(al); |
| 1585 | try c.mul(&a, &b); | 1527 | try c.mul(a, b); |
| 1586 | 1528 | ||
| 1587 | debug.assert((try c.to(u32)) == 0); | 1529 | debug.assert((try c.to(u32)) == 0); |
| 1588 | } | 1530 | } |
| ... | @@ -1593,7 +1535,7 @@ test "big.int div single-single no rem" { | ... | @@ -1593,7 +1535,7 @@ test "big.int div single-single no rem" { |
| 1593 | 1535 | ||
| 1594 | var q = try Int.init(al); | 1536 | var q = try Int.init(al); |
| 1595 | var r = try Int.init(al); | 1537 | var r = try Int.init(al); |
| 1596 | try Int.divTrunc(&q, &r, &a, &b); | 1538 | try Int.divTrunc(&q, &r, a, b); |
| 1597 | 1539 | ||
| 1598 | debug.assert((try q.to(u32)) == 10); | 1540 | debug.assert((try q.to(u32)) == 10); |
| 1599 | debug.assert((try r.to(u32)) == 0); | 1541 | debug.assert((try r.to(u32)) == 0); |
| ... | @@ -1605,7 +1547,7 @@ test "big.int div single-single with rem" { | ... | @@ -1605,7 +1547,7 @@ test "big.int div single-single with rem" { |
| 1605 | 1547 | ||
| 1606 | var q = try Int.init(al); | 1548 | var q = try Int.init(al); |
| 1607 | var r = try Int.init(al); | 1549 | var r = try Int.init(al); |
| 1608 | try Int.divTrunc(&q, &r, &a, &b); | 1550 | try Int.divTrunc(&q, &r, a, b); |
| 1609 | 1551 | ||
| 1610 | debug.assert((try q.to(u32)) == 9); | 1552 | debug.assert((try q.to(u32)) == 9); |
| 1611 | debug.assert((try r.to(u32)) == 4); | 1553 | debug.assert((try r.to(u32)) == 4); |
| ... | @@ -1620,7 +1562,7 @@ test "big.int div multi-single no rem" { | ... | @@ -1620,7 +1562,7 @@ test "big.int div multi-single no rem" { |
| 1620 | 1562 | ||
| 1621 | var q = try Int.init(al); | 1563 | var q = try Int.init(al); |
| 1622 | var r = try Int.init(al); | 1564 | var r = try Int.init(al); |
| 1623 | try Int.divTrunc(&q, &r, &a, &b); | 1565 | try Int.divTrunc(&q, &r, a, b); |
| 1624 | 1566 | ||
| 1625 | debug.assert((try q.to(u64)) == op1 / op2); | 1567 | debug.assert((try q.to(u64)) == op1 / op2); |
| 1626 | debug.assert((try r.to(u64)) == 0); | 1568 | debug.assert((try r.to(u64)) == 0); |
| ... | @@ -1635,7 +1577,7 @@ test "big.int div multi-single with rem" { | ... | @@ -1635,7 +1577,7 @@ test "big.int div multi-single with rem" { |
| 1635 | 1577 | ||
| 1636 | var q = try Int.init(al); | 1578 | var q = try Int.init(al); |
| 1637 | var r = try Int.init(al); | 1579 | var r = try Int.init(al); |
| 1638 | try Int.divTrunc(&q, &r, &a, &b); | 1580 | try Int.divTrunc(&q, &r, a, b); |
| 1639 | 1581 | ||
| 1640 | debug.assert((try q.to(u64)) == op1 / op2); | 1582 | debug.assert((try q.to(u64)) == op1 / op2); |
| 1641 | debug.assert((try r.to(u64)) == 3); | 1583 | debug.assert((try r.to(u64)) == 3); |
| ... | @@ -1650,7 +1592,7 @@ test "big.int div multi>2-single" { | ... | @@ -1650,7 +1592,7 @@ test "big.int div multi>2-single" { |
| 1650 | 1592 | ||
| 1651 | var q = try Int.init(al); | 1593 | var q = try Int.init(al); |
| 1652 | var r = try Int.init(al); | 1594 | var r = try Int.init(al); |
| 1653 | try Int.divTrunc(&q, &r, &a, &b); | 1595 | try Int.divTrunc(&q, &r, a, b); |
| 1654 | 1596 | ||
| 1655 | debug.assert((try q.to(u128)) == op1 / op2); | 1597 | debug.assert((try q.to(u128)) == op1 / op2); |
| 1656 | debug.assert((try r.to(u32)) == 0x3e4e); | 1598 | debug.assert((try r.to(u32)) == 0x3e4e); |
| ... | @@ -1662,7 +1604,7 @@ test "big.int div single-single q < r" { | ... | @@ -1662,7 +1604,7 @@ test "big.int div single-single q < r" { |
| 1662 | 1604 | ||
| 1663 | var q = try Int.init(al); | 1605 | var q = try Int.init(al); |
| 1664 | var r = try Int.init(al); | 1606 | var r = try Int.init(al); |
| 1665 | try Int.divTrunc(&q, &r, &a, &b); | 1607 | try Int.divTrunc(&q, &r, a, b); |
| 1666 | 1608 | ||
| 1667 | debug.assert((try q.to(u64)) == 0); | 1609 | debug.assert((try q.to(u64)) == 0); |
| 1668 | debug.assert((try r.to(u64)) == 0x0078f432); | 1610 | debug.assert((try r.to(u64)) == 0x0078f432); |
| ... | @@ -1674,7 +1616,7 @@ test "big.int div single-single q == r" { | ... | @@ -1674,7 +1616,7 @@ test "big.int div single-single q == r" { |
| 1674 | 1616 | ||
| 1675 | var q = try Int.init(al); | 1617 | var q = try Int.init(al); |
| 1676 | var r = try Int.init(al); | 1618 | var r = try Int.init(al); |
| 1677 | try Int.divTrunc(&q, &r, &a, &b); | 1619 | try Int.divTrunc(&q, &r, a, b); |
| 1678 | 1620 | ||
| 1679 | debug.assert((try q.to(u64)) == 1); | 1621 | debug.assert((try q.to(u64)) == 1); |
| 1680 | debug.assert((try r.to(u64)) == 0); | 1622 | debug.assert((try r.to(u64)) == 0); |
| ... | @@ -1684,7 +1626,7 @@ test "big.int div q=0 alias" { | ... | @@ -1684,7 +1626,7 @@ test "big.int div q=0 alias" { |
| 1684 | var a = try Int.initSet(al, 3); | 1626 | var a = try Int.initSet(al, 3); |
| 1685 | var b = try Int.initSet(al, 10); | 1627 | var b = try Int.initSet(al, 10); |
| 1686 | 1628 | ||
| 1687 | try Int.divTrunc(&a, &b, &a, &b); | 1629 | try Int.divTrunc(&a, &b, a, b); |
| 1688 | 1630 | ||
| 1689 | debug.assert((try a.to(u64)) == 0); | 1631 | debug.assert((try a.to(u64)) == 0); |
| 1690 | debug.assert((try b.to(u64)) == 3); | 1632 | debug.assert((try b.to(u64)) == 3); |
| ... | @@ -1698,7 +1640,7 @@ test "big.int div multi-multi q < r" { | ... | @@ -1698,7 +1640,7 @@ test "big.int div multi-multi q < r" { |
| 1698 | 1640 | ||
| 1699 | var q = try Int.init(al); | 1641 | var q = try Int.init(al); |
| 1700 | var r = try Int.init(al); | 1642 | var r = try Int.init(al); |
| 1701 | try Int.divTrunc(&q, &r, &a, &b); | 1643 | try Int.divTrunc(&q, &r, a, b); |
| 1702 | 1644 | ||
| 1703 | debug.assert((try q.to(u128)) == 0); | 1645 | debug.assert((try q.to(u128)) == 0); |
| 1704 | debug.assert((try r.to(u128)) == op1); | 1646 | debug.assert((try r.to(u128)) == op1); |
| ... | @@ -1713,7 +1655,7 @@ test "big.int div trunc single-single +/+" { | ... | @@ -1713,7 +1655,7 @@ test "big.int div trunc single-single +/+" { |
| 1713 | 1655 | ||
| 1714 | var q = try Int.init(al); | 1656 | var q = try Int.init(al); |
| 1715 | var r = try Int.init(al); | 1657 | var r = try Int.init(al); |
| 1716 | try Int.divTrunc(&q, &r, &a, &b); | 1658 | try Int.divTrunc(&q, &r, a, b); |
| 1717 | 1659 | ||
| 1718 | // n = q * d + r | 1660 | // n = q * d + r |
| 1719 | // 5 = 1 * 3 + 2 | 1661 | // 5 = 1 * 3 + 2 |
| ... | @@ -1733,7 +1675,7 @@ test "big.int div trunc single-single -/+" { | ... | @@ -1733,7 +1675,7 @@ test "big.int div trunc single-single -/+" { |
| 1733 | 1675 | ||
| 1734 | var q = try Int.init(al); | 1676 | var q = try Int.init(al); |
| 1735 | var r = try Int.init(al); | 1677 | var r = try Int.init(al); |
| 1736 | try Int.divTrunc(&q, &r, &a, &b); | 1678 | try Int.divTrunc(&q, &r, a, b); |
| 1737 | 1679 | ||
| 1738 | // n = q * d + r | 1680 | // n = q * d + r |
| 1739 | // -5 = 1 * -3 - 2 | 1681 | // -5 = 1 * -3 - 2 |
| ... | @@ -1753,7 +1695,7 @@ test "big.int div trunc single-single +/-" { | ... | @@ -1753,7 +1695,7 @@ test "big.int div trunc single-single +/-" { |
| 1753 | 1695 | ||
| 1754 | var q = try Int.init(al); | 1696 | var q = try Int.init(al); |
| 1755 | var r = try Int.init(al); | 1697 | var r = try Int.init(al); |
| 1756 | try Int.divTrunc(&q, &r, &a, &b); | 1698 | try Int.divTrunc(&q, &r, a, b); |
| 1757 | 1699 | ||
| 1758 | // n = q * d + r | 1700 | // n = q * d + r |
| 1759 | // 5 = -1 * -3 + 2 | 1701 | // 5 = -1 * -3 + 2 |
| ... | @@ -1773,7 +1715,7 @@ test "big.int div trunc single-single -/-" { | ... | @@ -1773,7 +1715,7 @@ test "big.int div trunc single-single -/-" { |
| 1773 | 1715 | ||
| 1774 | var q = try Int.init(al); | 1716 | var q = try Int.init(al); |
| 1775 | var r = try Int.init(al); | 1717 | var r = try Int.init(al); |
| 1776 | try Int.divTrunc(&q, &r, &a, &b); | 1718 | try Int.divTrunc(&q, &r, a, b); |
| 1777 | 1719 | ||
| 1778 | // n = q * d + r | 1720 | // n = q * d + r |
| 1779 | // -5 = 1 * -3 - 2 | 1721 | // -5 = 1 * -3 - 2 |
| ... | @@ -1793,7 +1735,7 @@ test "big.int div floor single-single +/+" { | ... | @@ -1793,7 +1735,7 @@ test "big.int div floor single-single +/+" { |
| 1793 | 1735 | ||
| 1794 | var q = try Int.init(al); | 1736 | var q = try Int.init(al); |
| 1795 | var r = try Int.init(al); | 1737 | var r = try Int.init(al); |
| 1796 | try Int.divFloor(&q, &r, &a, &b); | 1738 | try Int.divFloor(&q, &r, a, b); |
| 1797 | 1739 | ||
| 1798 | // n = q * d + r | 1740 | // n = q * d + r |
| 1799 | // 5 = 1 * 3 + 2 | 1741 | // 5 = 1 * 3 + 2 |
| ... | @@ -1813,7 +1755,7 @@ test "big.int div floor single-single -/+" { | ... | @@ -1813,7 +1755,7 @@ test "big.int div floor single-single -/+" { |
| 1813 | 1755 | ||
| 1814 | var q = try Int.init(al); | 1756 | var q = try Int.init(al); |
| 1815 | var r = try Int.init(al); | 1757 | var r = try Int.init(al); |
| 1816 | try Int.divFloor(&q, &r, &a, &b); | 1758 | try Int.divFloor(&q, &r, a, b); |
| 1817 | 1759 | ||
| 1818 | // n = q * d + r | 1760 | // n = q * d + r |
| 1819 | // -5 = -2 * 3 + 1 | 1761 | // -5 = -2 * 3 + 1 |
| ... | @@ -1833,7 +1775,7 @@ test "big.int div floor single-single +/-" { | ... | @@ -1833,7 +1775,7 @@ test "big.int div floor single-single +/-" { |
| 1833 | 1775 | ||
| 1834 | var q = try Int.init(al); | 1776 | var q = try Int.init(al); |
| 1835 | var r = try Int.init(al); | 1777 | var r = try Int.init(al); |
| 1836 | try Int.divFloor(&q, &r, &a, &b); | 1778 | try Int.divFloor(&q, &r, a, b); |
| 1837 | 1779 | ||
| 1838 | // n = q * d + r | 1780 | // n = q * d + r |
| 1839 | // 5 = -2 * -3 - 1 | 1781 | // 5 = -2 * -3 - 1 |
| ... | @@ -1853,7 +1795,7 @@ test "big.int div floor single-single -/-" { | ... | @@ -1853,7 +1795,7 @@ test "big.int div floor single-single -/-" { |
| 1853 | 1795 | ||
| 1854 | var q = try Int.init(al); | 1796 | var q = try Int.init(al); |
| 1855 | var r = try Int.init(al); | 1797 | var r = try Int.init(al); |
| 1856 | try Int.divFloor(&q, &r, &a, &b); | 1798 | try Int.divFloor(&q, &r, a, b); |
| 1857 | 1799 | ||
| 1858 | // n = q * d + r | 1800 | // n = q * d + r |
| 1859 | // -5 = 2 * -3 + 1 | 1801 | // -5 = 2 * -3 + 1 |
| ... | @@ -1870,7 +1812,7 @@ test "big.int div multi-multi with rem" { | ... | @@ -1870,7 +1812,7 @@ test "big.int div multi-multi with rem" { |
| 1870 | 1812 | ||
| 1871 | var q = try Int.init(al); | 1813 | var q = try Int.init(al); |
| 1872 | var r = try Int.init(al); | 1814 | var r = try Int.init(al); |
| 1873 | try Int.divTrunc(&q, &r, &a, &b); | 1815 | try Int.divTrunc(&q, &r, a, b); |
| 1874 | 1816 | ||
| 1875 | debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b); | 1817 | debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b); |
| 1876 | debug.assert((try r.to(u128)) == 0x28de0acacd806823638); | 1818 | debug.assert((try r.to(u128)) == 0x28de0acacd806823638); |
| ... | @@ -1882,7 +1824,7 @@ test "big.int div multi-multi no rem" { | ... | @@ -1882,7 +1824,7 @@ test "big.int div multi-multi no rem" { |
| 1882 | 1824 | ||
| 1883 | var q = try Int.init(al); | 1825 | var q = try Int.init(al); |
| 1884 | var r = try Int.init(al); | 1826 | var r = try Int.init(al); |
| 1885 | try Int.divTrunc(&q, &r, &a, &b); | 1827 | try Int.divTrunc(&q, &r, a, b); |
| 1886 | 1828 | ||
| 1887 | debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b); | 1829 | debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b); |
| 1888 | debug.assert((try r.to(u128)) == 0); | 1830 | debug.assert((try r.to(u128)) == 0); |
| ... | @@ -1894,7 +1836,7 @@ test "big.int div multi-multi (2 branch)" { | ... | @@ -1894,7 +1836,7 @@ test "big.int div multi-multi (2 branch)" { |
| 1894 | 1836 | ||
| 1895 | var q = try Int.init(al); | 1837 | var q = try Int.init(al); |
| 1896 | var r = try Int.init(al); | 1838 | var r = try Int.init(al); |
| 1897 | try Int.divTrunc(&q, &r, &a, &b); | 1839 | try Int.divTrunc(&q, &r, a, b); |
| 1898 | 1840 | ||
| 1899 | debug.assert((try q.to(u128)) == 0x10000000000000000); | 1841 | debug.assert((try q.to(u128)) == 0x10000000000000000); |
| 1900 | debug.assert((try r.to(u128)) == 0x44444443444444431111111111111111); | 1842 | debug.assert((try r.to(u128)) == 0x44444443444444431111111111111111); |
| ... | @@ -1906,7 +1848,7 @@ test "big.int div multi-multi (3.1/3.3 branch)" { | ... | @@ -1906,7 +1848,7 @@ test "big.int div multi-multi (3.1/3.3 branch)" { |
| 1906 | 1848 | ||
| 1907 | var q = try Int.init(al); | 1849 | var q = try Int.init(al); |
| 1908 | var r = try Int.init(al); | 1850 | var r = try Int.init(al); |
| 1909 | try Int.divTrunc(&q, &r, &a, &b); | 1851 | try Int.divTrunc(&q, &r, a, b); |
| 1910 | 1852 | ||
| 1911 | debug.assert((try q.to(u128)) == 0xfffffffffffffffffff); | 1853 | debug.assert((try q.to(u128)) == 0xfffffffffffffffffff); |
| 1912 | debug.assert((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282); | 1854 | debug.assert((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282); |
| ... | @@ -1943,17 +1885,17 @@ test "big.int shift-left multi" { | ... | @@ -1943,17 +1885,17 @@ test "big.int shift-left multi" { |
| 1943 | test "big.int shift-right negative" { | 1885 | test "big.int shift-right negative" { |
| 1944 | var a = try Int.init(al); | 1886 | var a = try Int.init(al); |
| 1945 | 1887 | ||
| 1946 | try a.shiftRight(-20, 2); | 1888 | try a.shiftRight(try Int.initSet(al, -20), 2); |
| 1947 | debug.assert((try a.to(i32)) == -20 >> 2); | 1889 | debug.assert((try a.to(i32)) == -20 >> 2); |
| 1948 | 1890 | ||
| 1949 | try a.shiftRight(-5, 10); | 1891 | try a.shiftRight(try Int.initSet(al, -5), 10); |
| 1950 | debug.assert((try a.to(i32)) == -5 >> 10); | 1892 | debug.assert((try a.to(i32)) == -5 >> 10); |
| 1951 | } | 1893 | } |
| 1952 | 1894 | ||
| 1953 | test "big.int shift-left negative" { | 1895 | test "big.int shift-left negative" { |
| 1954 | var a = try Int.init(al); | 1896 | var a = try Int.init(al); |
| 1955 | 1897 | ||
| 1956 | try a.shiftRight(-10, 1232); | 1898 | try a.shiftRight(try Int.initSet(al, -10), 1232); |
| 1957 | debug.assert((try a.to(i32)) == -10 >> 1232); | 1899 | debug.assert((try a.to(i32)) == -10 >> 1232); |
| 1958 | } | 1900 | } |
| 1959 | 1901 | ||
| ... | @@ -1961,7 +1903,7 @@ test "big.int bitwise and simple" { | ... | @@ -1961,7 +1903,7 @@ test "big.int bitwise and simple" { |
| 1961 | var a = try Int.initSet(al, 0xffffffff11111111); | 1903 | var a = try Int.initSet(al, 0xffffffff11111111); |
| 1962 | var b = try Int.initSet(al, 0xeeeeeeee22222222); | 1904 | var b = try Int.initSet(al, 0xeeeeeeee22222222); |
| 1963 | 1905 | ||
| 1964 | try a.bitAnd(&a, &b); | 1906 | try a.bitAnd(a, b); |
| 1965 | 1907 | ||
| 1966 | debug.assert((try a.to(u64)) == 0xeeeeeeee00000000); | 1908 | debug.assert((try a.to(u64)) == 0xeeeeeeee00000000); |
| 1967 | } | 1909 | } |
| ... | @@ -1970,7 +1912,7 @@ test "big.int bitwise and multi-limb" { | ... | @@ -1970,7 +1912,7 @@ test "big.int bitwise and multi-limb" { |
| 1970 | var a = try Int.initSet(al, @maxValue(Limb) + 1); | 1912 | var a = try Int.initSet(al, @maxValue(Limb) + 1); |
| 1971 | var b = try Int.initSet(al, @maxValue(Limb)); | 1913 | var b = try Int.initSet(al, @maxValue(Limb)); |
| 1972 | 1914 | ||
| 1973 | try a.bitAnd(&a, &b); | 1915 | try a.bitAnd(a, b); |
| 1974 | 1916 | ||
| 1975 | debug.assert((try a.to(u128)) == 0); | 1917 | debug.assert((try a.to(u128)) == 0); |
| 1976 | } | 1918 | } |
| ... | @@ -1979,7 +1921,7 @@ test "big.int bitwise xor simple" { | ... | @@ -1979,7 +1921,7 @@ test "big.int bitwise xor simple" { |
| 1979 | var a = try Int.initSet(al, 0xffffffff11111111); | 1921 | var a = try Int.initSet(al, 0xffffffff11111111); |
| 1980 | var b = try Int.initSet(al, 0xeeeeeeee22222222); | 1922 | var b = try Int.initSet(al, 0xeeeeeeee22222222); |
| 1981 | 1923 | ||
| 1982 | try a.bitXor(&a, &b); | 1924 | try a.bitXor(a, b); |
| 1983 | 1925 | ||
| 1984 | debug.assert((try a.to(u64)) == 0x1111111133333333); | 1926 | debug.assert((try a.to(u64)) == 0x1111111133333333); |
| 1985 | } | 1927 | } |
| ... | @@ -1988,7 +1930,7 @@ test "big.int bitwise xor multi-limb" { | ... | @@ -1988,7 +1930,7 @@ test "big.int bitwise xor multi-limb" { |
| 1988 | var a = try Int.initSet(al, @maxValue(Limb) + 1); | 1930 | var a = try Int.initSet(al, @maxValue(Limb) + 1); |
| 1989 | var b = try Int.initSet(al, @maxValue(Limb)); | 1931 | var b = try Int.initSet(al, @maxValue(Limb)); |
| 1990 | 1932 | ||
| 1991 | try a.bitXor(&a, &b); | 1933 | try a.bitXor(a, b); |
| 1992 | 1934 | ||
| 1993 | debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) ^ @maxValue(Limb)); | 1935 | debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) ^ @maxValue(Limb)); |
| 1994 | } | 1936 | } |
| ... | @@ -1997,7 +1939,7 @@ test "big.int bitwise or simple" { | ... | @@ -1997,7 +1939,7 @@ test "big.int bitwise or simple" { |
| 1997 | var a = try Int.initSet(al, 0xffffffff11111111); | 1939 | var a = try Int.initSet(al, 0xffffffff11111111); |
| 1998 | var b = try Int.initSet(al, 0xeeeeeeee22222222); | 1940 | var b = try Int.initSet(al, 0xeeeeeeee22222222); |
| 1999 | 1941 | ||
| 2000 | try a.bitOr(&a, &b); | 1942 | try a.bitOr(a, b); |
| 2001 | 1943 | ||
| 2002 | debug.assert((try a.to(u64)) == 0xffffffff33333333); | 1944 | debug.assert((try a.to(u64)) == 0xffffffff33333333); |
| 2003 | } | 1945 | } |
| ... | @@ -2006,7 +1948,7 @@ test "big.int bitwise or multi-limb" { | ... | @@ -2006,7 +1948,7 @@ test "big.int bitwise or multi-limb" { |
| 2006 | var a = try Int.initSet(al, @maxValue(Limb) + 1); | 1948 | var a = try Int.initSet(al, @maxValue(Limb) + 1); |
| 2007 | var b = try Int.initSet(al, @maxValue(Limb)); | 1949 | var b = try Int.initSet(al, @maxValue(Limb)); |
| 2008 | 1950 | ||
| 2009 | try a.bitOr(&a, &b); | 1951 | try a.bitOr(a, b); |
| 2010 | 1952 | ||
| 2011 | // TODO: big.int.cpp or is wrong on multi-limb. | 1953 | // TODO: big.int.cpp or is wrong on multi-limb. |
| 2012 | debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) + @maxValue(Limb)); | 1954 | debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) + @maxValue(Limb)); |
| ... | @@ -2015,9 +1957,9 @@ test "big.int bitwise or multi-limb" { | ... | @@ -2015,9 +1957,9 @@ test "big.int bitwise or multi-limb" { |
| 2015 | test "big.int var args" { | 1957 | test "big.int var args" { |
| 2016 | var a = try Int.initSet(al, 5); | 1958 | var a = try Int.initSet(al, 5); |
| 2017 | 1959 | ||
| 2018 | try a.add(&a, 6); | 1960 | try a.add(a, try Int.initSet(al, 6)); |
| 2019 | debug.assert((try a.to(u64)) == 11); | 1961 | debug.assert((try a.to(u64)) == 11); |
| 2020 | 1962 | ||
| 2021 | debug.assert(a.cmp(11) == 0); | 1963 | debug.assert(a.cmp(try Int.initSet(al, 11)) == 0); |
| 2022 | debug.assert(a.cmp(14) <= 0); | 1964 | debug.assert(a.cmp(try Int.initSet(al, 14)) <= 0); |
| 2023 | } | 1965 | } |
std/math/cbrt.zig+3-3| ... | @@ -54,7 +54,7 @@ fn cbrt32(x: f32) f32 { | ... | @@ -54,7 +54,7 @@ fn cbrt32(x: f32) f32 { |
| 54 | r = t * t * t; | 54 | r = t * t * t; |
| 55 | t = t * (f64(x) + x + r) / (x + r + r); | 55 | t = t * (f64(x) + x + r) / (x + r + r); |
| 56 | 56 | ||
| 57 | return f32(t); | 57 | return @floatCast(f32, t); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | fn cbrt64(x: f64) f64 { | 60 | fn cbrt64(x: f64) f64 { |
| ... | @@ -69,7 +69,7 @@ fn cbrt64(x: f64) f64 { | ... | @@ -69,7 +69,7 @@ fn cbrt64(x: f64) f64 { |
| 69 | const P4: f64 = 0.145996192886612446982; | 69 | const P4: f64 = 0.145996192886612446982; |
| 70 | 70 | ||
| 71 | var u = @bitCast(u64, x); | 71 | var u = @bitCast(u64, x); |
| 72 | var hx = u32(u >> 32) & 0x7FFFFFFF; | 72 | var hx = @intCast(u32, u >> 32) & 0x7FFFFFFF; |
| 73 | 73 | ||
| 74 | // cbrt(nan, inf) = itself | 74 | // cbrt(nan, inf) = itself |
| 75 | if (hx >= 0x7FF00000) { | 75 | if (hx >= 0x7FF00000) { |
| ... | @@ -79,7 +79,7 @@ fn cbrt64(x: f64) f64 { | ... | @@ -79,7 +79,7 @@ fn cbrt64(x: f64) f64 { |
| 79 | // cbrt to ~5bits | 79 | // cbrt to ~5bits |
| 80 | if (hx < 0x00100000) { | 80 | if (hx < 0x00100000) { |
| 81 | u = @bitCast(u64, x * 0x1.0p54); | 81 | u = @bitCast(u64, x * 0x1.0p54); |
| 82 | hx = u32(u >> 32) & 0x7FFFFFFF; | 82 | hx = @intCast(u32, u >> 32) & 0x7FFFFFFF; |
| 83 | 83 | ||
| 84 | // cbrt(0) is itself | 84 | // cbrt(0) is itself |
| 85 | if (hx == 0) { | 85 | if (hx == 0) { |
std/math/ceil.zig+2-2| ... | @@ -20,7 +20,7 @@ pub fn ceil(x: var) @typeOf(x) { | ... | @@ -20,7 +20,7 @@ pub fn ceil(x: var) @typeOf(x) { |
| 20 | 20 | ||
| 21 | fn ceil32(x: f32) f32 { | 21 | fn ceil32(x: f32) f32 { |
| 22 | var u = @bitCast(u32, x); | 22 | var u = @bitCast(u32, x); |
| 23 | var e = i32((u >> 23) & 0xFF) - 0x7F; | 23 | var e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F; |
| 24 | var m: u32 = undefined; | 24 | var m: u32 = undefined; |
| 25 | 25 | ||
| 26 | // TODO: Shouldn't need this explicit check. | 26 | // TODO: Shouldn't need this explicit check. |
| ... | @@ -31,7 +31,7 @@ fn ceil32(x: f32) f32 { | ... | @@ -31,7 +31,7 @@ fn ceil32(x: f32) f32 { |
| 31 | if (e >= 23) { | 31 | if (e >= 23) { |
| 32 | return x; | 32 | return x; |
| 33 | } else if (e >= 0) { | 33 | } else if (e >= 0) { |
| 34 | m = u32(0x007FFFFF) >> u5(e); | 34 | m = u32(0x007FFFFF) >> @intCast(u5, e); |
| 35 | if (u & m == 0) { | 35 | if (u & m == 0) { |
| 36 | return x; | 36 | return x; |
| 37 | } | 37 | } |
std/math/complex/atan.zig+5-5| ... | @@ -4,7 +4,7 @@ const math = std.math; | ... | @@ -4,7 +4,7 @@ const math = std.math; |
| 4 | const cmath = math.complex; | 4 | const cmath = math.complex; |
| 5 | const Complex = cmath.Complex; | 5 | const Complex = cmath.Complex; |
| 6 | 6 | ||
| 7 | pub fn atan(z: var) Complex(@typeOf(z.re)) { | 7 | pub fn atan(z: var) @typeOf(z) { |
| 8 | const T = @typeOf(z.re); | 8 | const T = @typeOf(z.re); |
| 9 | return switch (T) { | 9 | return switch (T) { |
| 10 | f32 => atan32(z), | 10 | f32 => atan32(z), |
| ... | @@ -25,11 +25,11 @@ fn redupif32(x: f32) f32 { | ... | @@ -25,11 +25,11 @@ fn redupif32(x: f32) f32 { |
| 25 | t -= 0.5; | 25 | t -= 0.5; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | const u = f32(i32(t)); | 28 | const u = @intToFloat(f32, @floatToInt(i32, t)); |
| 29 | return ((x - u * DP1) - u * DP2) - t * DP3; | 29 | return ((x - u * DP1) - u * DP2) - t * DP3; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | fn atan32(z: *const Complex(f32)) Complex(f32) { | 32 | fn atan32(z: Complex(f32)) Complex(f32) { |
| 33 | const maxnum = 1.0e38; | 33 | const maxnum = 1.0e38; |
| 34 | 34 | ||
| 35 | const x = z.re; | 35 | const x = z.re; |
| ... | @@ -74,11 +74,11 @@ fn redupif64(x: f64) f64 { | ... | @@ -74,11 +74,11 @@ fn redupif64(x: f64) f64 { |
| 74 | t -= 0.5; | 74 | t -= 0.5; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | const u = f64(i64(t)); | 77 | const u = @intToFloat(f64, @floatToInt(i64, t)); |
| 78 | return ((x - u * DP1) - u * DP2) - t * DP3; | 78 | return ((x - u * DP1) - u * DP2) - t * DP3; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | fn atan64(z: *const Complex(f64)) Complex(f64) { | 81 | fn atan64(z: Complex(f64)) Complex(f64) { |
| 82 | const maxnum = 1.0e308; | 82 | const maxnum = 1.0e308; |
| 83 | 83 | ||
| 84 | const x = z.re; | 84 | const x = z.re; |
std/math/complex/cosh.zig+2-2| ... | @@ -83,12 +83,12 @@ fn cosh64(z: *const Complex(f64)) Complex(f64) { | ... | @@ -83,12 +83,12 @@ fn cosh64(z: *const Complex(f64)) Complex(f64) { |
| 83 | const y = z.im; | 83 | const y = z.im; |
| 84 | 84 | ||
| 85 | const fx = @bitCast(u64, x); | 85 | const fx = @bitCast(u64, x); |
| 86 | const hx = u32(fx >> 32); | 86 | const hx = @intCast(u32, fx >> 32); |
| 87 | const lx = @truncate(u32, fx); | 87 | const lx = @truncate(u32, fx); |
| 88 | const ix = hx & 0x7fffffff; | 88 | const ix = hx & 0x7fffffff; |
| 89 | 89 | ||
| 90 | const fy = @bitCast(u64, y); | 90 | const fy = @bitCast(u64, y); |
| 91 | const hy = u32(fy >> 32); | 91 | const hy = @intCast(u32, fy >> 32); |
| 92 | const ly = @truncate(u32, fy); | 92 | const ly = @truncate(u32, fy); |
| 93 | const iy = hy & 0x7fffffff; | 93 | const iy = hy & 0x7fffffff; |
| 94 | 94 |
std/math/complex/exp.zig+3-3| ... | @@ -6,7 +6,7 @@ const Complex = cmath.Complex; | ... | @@ -6,7 +6,7 @@ const Complex = cmath.Complex; |
| 6 | 6 | ||
| 7 | const ldexp_cexp = @import("ldexp.zig").ldexp_cexp; | 7 | const ldexp_cexp = @import("ldexp.zig").ldexp_cexp; |
| 8 | 8 | ||
| 9 | pub fn exp(z: var) Complex(@typeOf(z.re)) { | 9 | pub fn exp(z: var) @typeOf(z) { |
| 10 | const T = @typeOf(z.re); | 10 | const T = @typeOf(z.re); |
| 11 | 11 | ||
| 12 | return switch (T) { | 12 | return switch (T) { |
| ... | @@ -16,7 +16,7 @@ pub fn exp(z: var) Complex(@typeOf(z.re)) { | ... | @@ -16,7 +16,7 @@ pub fn exp(z: var) Complex(@typeOf(z.re)) { |
| 16 | }; | 16 | }; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | fn exp32(z: *const Complex(f32)) Complex(f32) { | 19 | fn exp32(z: Complex(f32)) Complex(f32) { |
| 20 | @setFloatMode(this, @import("builtin").FloatMode.Strict); | 20 | @setFloatMode(this, @import("builtin").FloatMode.Strict); |
| 21 | 21 | ||
| 22 | const exp_overflow = 0x42b17218; // max_exp * ln2 ~= 88.72283955 | 22 | const exp_overflow = 0x42b17218; // max_exp * ln2 ~= 88.72283955 |
| ... | @@ -63,7 +63,7 @@ fn exp32(z: *const Complex(f32)) Complex(f32) { | ... | @@ -63,7 +63,7 @@ fn exp32(z: *const Complex(f32)) Complex(f32) { |
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | fn exp64(z: *const Complex(f64)) Complex(f64) { | 66 | fn exp64(z: Complex(f64)) Complex(f64) { |
| 67 | const exp_overflow = 0x40862e42; // high bits of max_exp * ln2 ~= 710 | 67 | const exp_overflow = 0x40862e42; // high bits of max_exp * ln2 ~= 710 |
| 68 | const cexp_overflow = 0x4096b8e4; // (max_exp - min_denorm_exp) * ln2 | 68 | const cexp_overflow = 0x4096b8e4; // (max_exp - min_denorm_exp) * ln2 |
| 69 | 69 |
std/math/complex/index.zig+7-7| ... | @@ -37,28 +37,28 @@ pub fn Complex(comptime T: type) type { | ... | @@ -37,28 +37,28 @@ pub fn Complex(comptime T: type) type { |
| 37 | }; | 37 | }; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | pub fn add(self: *const Self, other: *const Self) Self { | 40 | pub fn add(self: Self, other: Self) Self { |
| 41 | return Self{ | 41 | return Self{ |
| 42 | .re = self.re + other.re, | 42 | .re = self.re + other.re, |
| 43 | .im = self.im + other.im, | 43 | .im = self.im + other.im, |
| 44 | }; | 44 | }; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | pub fn sub(self: *const Self, other: *const Self) Self { | 47 | pub fn sub(self: Self, other: Self) Self { |
| 48 | return Self{ | 48 | return Self{ |
| 49 | .re = self.re - other.re, | 49 | .re = self.re - other.re, |
| 50 | .im = self.im - other.im, | 50 | .im = self.im - other.im, |
| 51 | }; | 51 | }; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | pub fn mul(self: *const Self, other: *const Self) Self { | 54 | pub fn mul(self: Self, other: Self) Self { |
| 55 | return Self{ | 55 | return Self{ |
| 56 | .re = self.re * other.re - self.im * other.im, | 56 | .re = self.re * other.re - self.im * other.im, |
| 57 | .im = self.im * other.re + self.re * other.im, | 57 | .im = self.im * other.re + self.re * other.im, |
| 58 | }; | 58 | }; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | pub fn div(self: *const Self, other: *const Self) Self { | 61 | pub fn div(self: Self, other: Self) Self { |
| 62 | const re_num = self.re * other.re + self.im * other.im; | 62 | const re_num = self.re * other.re + self.im * other.im; |
| 63 | const im_num = self.im * other.re - self.re * other.im; | 63 | const im_num = self.im * other.re - self.re * other.im; |
| 64 | const den = other.re * other.re + other.im * other.im; | 64 | const den = other.re * other.re + other.im * other.im; |
| ... | @@ -69,14 +69,14 @@ pub fn Complex(comptime T: type) type { | ... | @@ -69,14 +69,14 @@ pub fn Complex(comptime T: type) type { |
| 69 | }; | 69 | }; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | pub fn conjugate(self: *const Self) Self { | 72 | pub fn conjugate(self: Self) Self { |
| 73 | return Self{ | 73 | return Self{ |
| 74 | .re = self.re, | 74 | .re = self.re, |
| 75 | .im = -self.im, | 75 | .im = -self.im, |
| 76 | }; | 76 | }; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | pub fn reciprocal(self: *const Self) Self { | 79 | pub fn reciprocal(self: Self) Self { |
| 80 | const m = self.re * self.re + self.im * self.im; | 80 | const m = self.re * self.re + self.im * self.im; |
| 81 | return Self{ | 81 | return Self{ |
| 82 | .re = self.re / m, | 82 | .re = self.re / m, |
| ... | @@ -84,7 +84,7 @@ pub fn Complex(comptime T: type) type { | ... | @@ -84,7 +84,7 @@ pub fn Complex(comptime T: type) type { |
| 84 | }; | 84 | }; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | pub fn magnitude(self: *const Self) T { | 87 | pub fn magnitude(self: Self) T { |
| 88 | return math.sqrt(self.re * self.re + self.im * self.im); | 88 | return math.sqrt(self.re * self.re + self.im * self.im); |
| 89 | } | 89 | } |
| 90 | }; | 90 | }; |
std/math/complex/ldexp.zig+7-6| ... | @@ -4,7 +4,7 @@ const math = std.math; | ... | @@ -4,7 +4,7 @@ const math = std.math; |
| 4 | const cmath = math.complex; | 4 | const cmath = math.complex; |
| 5 | const Complex = cmath.Complex; | 5 | const Complex = cmath.Complex; |
| 6 | 6 | ||
| 7 | pub fn ldexp_cexp(z: var, expt: i32) Complex(@typeOf(z.re)) { | 7 | pub fn ldexp_cexp(z: var, expt: i32) @typeOf(z) { |
| 8 | const T = @typeOf(z.re); | 8 | const T = @typeOf(z.re); |
| 9 | 9 | ||
| 10 | return switch (T) { | 10 | return switch (T) { |
| ... | @@ -20,11 +20,12 @@ fn frexp_exp32(x: f32, expt: *i32) f32 { | ... | @@ -20,11 +20,12 @@ fn frexp_exp32(x: f32, expt: *i32) f32 { |
| 20 | 20 | ||
| 21 | const exp_x = math.exp(x - kln2); | 21 | const exp_x = math.exp(x - kln2); |
| 22 | const hx = @bitCast(u32, exp_x); | 22 | const hx = @bitCast(u32, exp_x); |
| 23 | expt.* = i32(hx >> 23) - (0x7f + 127) + k; | 23 | // TODO zig should allow this cast implicitly because it should know the value is in range |
| 24 | expt.* = @intCast(i32, hx >> 23) - (0x7f + 127) + k; | ||
| 24 | return @bitCast(f32, (hx & 0x7fffff) | ((0x7f + 127) << 23)); | 25 | return @bitCast(f32, (hx & 0x7fffff) | ((0x7f + 127) << 23)); |
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | fn ldexp_cexp32(z: *const Complex(f32), expt: i32) Complex(f32) { | 28 | fn ldexp_cexp32(z: Complex(f32), expt: i32) Complex(f32) { |
| 28 | var ex_expt: i32 = undefined; | 29 | var ex_expt: i32 = undefined; |
| 29 | const exp_x = frexp_exp32(z.re, &ex_expt); | 30 | const exp_x = frexp_exp32(z.re, &ex_expt); |
| 30 | const exptf = expt + ex_expt; | 31 | const exptf = expt + ex_expt; |
| ... | @@ -45,16 +46,16 @@ fn frexp_exp64(x: f64, expt: *i32) f64 { | ... | @@ -45,16 +46,16 @@ fn frexp_exp64(x: f64, expt: *i32) f64 { |
| 45 | const exp_x = math.exp(x - kln2); | 46 | const exp_x = math.exp(x - kln2); |
| 46 | 47 | ||
| 47 | const fx = @bitCast(u64, x); | 48 | const fx = @bitCast(u64, x); |
| 48 | const hx = u32(fx >> 32); | 49 | const hx = @intCast(u32, fx >> 32); |
| 49 | const lx = @truncate(u32, fx); | 50 | const lx = @truncate(u32, fx); |
| 50 | 51 | ||
| 51 | expt.* = i32(hx >> 20) - (0x3ff + 1023) + k; | 52 | expt.* = @intCast(i32, hx >> 20) - (0x3ff + 1023) + k; |
| 52 | 53 | ||
| 53 | const high_word = (hx & 0xfffff) | ((0x3ff + 1023) << 20); | 54 | const high_word = (hx & 0xfffff) | ((0x3ff + 1023) << 20); |
| 54 | return @bitCast(f64, (u64(high_word) << 32) | lx); | 55 | return @bitCast(f64, (u64(high_word) << 32) | lx); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | fn ldexp_cexp64(z: *const Complex(f64), expt: i32) Complex(f64) { | 58 | fn ldexp_cexp64(z: Complex(f64), expt: i32) Complex(f64) { |
| 58 | var ex_expt: i32 = undefined; | 59 | var ex_expt: i32 = undefined; |
| 59 | const exp_x = frexp_exp64(z.re, &ex_expt); | 60 | const exp_x = frexp_exp64(z.re, &ex_expt); |
| 60 | const exptf = i64(expt + ex_expt); | 61 | const exptf = i64(expt + ex_expt); |
std/math/complex/sinh.zig+5-5| ... | @@ -6,7 +6,7 @@ const Complex = cmath.Complex; | ... | @@ -6,7 +6,7 @@ const Complex = cmath.Complex; |
| 6 | 6 | ||
| 7 | const ldexp_cexp = @import("ldexp.zig").ldexp_cexp; | 7 | const ldexp_cexp = @import("ldexp.zig").ldexp_cexp; |
| 8 | 8 | ||
| 9 | pub fn sinh(z: var) Complex(@typeOf(z.re)) { | 9 | pub fn sinh(z: var) @typeOf(z) { |
| 10 | const T = @typeOf(z.re); | 10 | const T = @typeOf(z.re); |
| 11 | return switch (T) { | 11 | return switch (T) { |
| 12 | f32 => sinh32(z), | 12 | f32 => sinh32(z), |
| ... | @@ -15,7 +15,7 @@ pub fn sinh(z: var) Complex(@typeOf(z.re)) { | ... | @@ -15,7 +15,7 @@ pub fn sinh(z: var) Complex(@typeOf(z.re)) { |
| 15 | }; | 15 | }; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | fn sinh32(z: *const Complex(f32)) Complex(f32) { | 18 | fn sinh32(z: Complex(f32)) Complex(f32) { |
| 19 | const x = z.re; | 19 | const x = z.re; |
| 20 | const y = z.im; | 20 | const y = z.im; |
| 21 | 21 | ||
| ... | @@ -78,17 +78,17 @@ fn sinh32(z: *const Complex(f32)) Complex(f32) { | ... | @@ -78,17 +78,17 @@ fn sinh32(z: *const Complex(f32)) Complex(f32) { |
| 78 | return Complex(f32).new((x * x) * (y - y), (x + x) * (y - y)); | 78 | return Complex(f32).new((x * x) * (y - y), (x + x) * (y - y)); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | fn sinh64(z: *const Complex(f64)) Complex(f64) { | 81 | fn sinh64(z: Complex(f64)) Complex(f64) { |
| 82 | const x = z.re; | 82 | const x = z.re; |
| 83 | const y = z.im; | 83 | const y = z.im; |
| 84 | 84 | ||
| 85 | const fx = @bitCast(u64, x); | 85 | const fx = @bitCast(u64, x); |
| 86 | const hx = u32(fx >> 32); | 86 | const hx = @intCast(u32, fx >> 32); |
| 87 | const lx = @truncate(u32, fx); | 87 | const lx = @truncate(u32, fx); |
| 88 | const ix = hx & 0x7fffffff; | 88 | const ix = hx & 0x7fffffff; |
| 89 | 89 | ||
| 90 | const fy = @bitCast(u64, y); | 90 | const fy = @bitCast(u64, y); |
| 91 | const hy = u32(fy >> 32); | 91 | const hy = @intCast(u32, fy >> 32); |
| 92 | const ly = @truncate(u32, fy); | 92 | const ly = @truncate(u32, fy); |
| 93 | const iy = hy & 0x7fffffff; | 93 | const iy = hy & 0x7fffffff; |
| 94 | 94 |
std/math/complex/sqrt.zig+12-7| ... | @@ -4,18 +4,17 @@ const math = std.math; | ... | @@ -4,18 +4,17 @@ const math = std.math; |
| 4 | const cmath = math.complex; | 4 | const cmath = math.complex; |
| 5 | const Complex = cmath.Complex; | 5 | const Complex = cmath.Complex; |
| 6 | 6 | ||
| 7 | // TODO when #733 is solved this can be @typeOf(z) instead of Complex(@typeOf(z.re)) | 7 | pub fn sqrt(z: var) @typeOf(z) { |
| 8 | pub fn sqrt(z: var) Complex(@typeOf(z.re)) { | ||
| 9 | const T = @typeOf(z.re); | 8 | const T = @typeOf(z.re); |
| 10 | 9 | ||
| 11 | return switch (T) { | 10 | return switch (T) { |
| 12 | f32 => sqrt32(z), | 11 | f32 => sqrt32(z), |
| 13 | f64 => sqrt64(z), | 12 | f64 => sqrt64(z), |
| 14 | else => @compileError("sqrt not implemented for " ++ @typeName(z)), | 13 | else => @compileError("sqrt not implemented for " ++ @typeName(T)), |
| 15 | }; | 14 | }; |
| 16 | } | 15 | } |
| 17 | 16 | ||
| 18 | fn sqrt32(z: *const Complex(f32)) Complex(f32) { | 17 | fn sqrt32(z: Complex(f32)) Complex(f32) { |
| 19 | const x = z.re; | 18 | const x = z.re; |
| 20 | const y = z.im; | 19 | const y = z.im; |
| 21 | 20 | ||
| ... | @@ -50,14 +49,20 @@ fn sqrt32(z: *const Complex(f32)) Complex(f32) { | ... | @@ -50,14 +49,20 @@ fn sqrt32(z: *const Complex(f32)) Complex(f32) { |
| 50 | 49 | ||
| 51 | if (dx >= 0) { | 50 | if (dx >= 0) { |
| 52 | const t = math.sqrt((dx + math.hypot(f64, dx, dy)) * 0.5); | 51 | const t = math.sqrt((dx + math.hypot(f64, dx, dy)) * 0.5); |
| 53 | return Complex(f32).new(f32(t), f32(dy / (2.0 * t))); | 52 | return Complex(f32).new( |
| 53 | @floatCast(f32, t), | ||
| 54 | @floatCast(f32, dy / (2.0 * t)), | ||
| 55 | ); | ||
| 54 | } else { | 56 | } else { |
| 55 | const t = math.sqrt((-dx + math.hypot(f64, dx, dy)) * 0.5); | 57 | const t = math.sqrt((-dx + math.hypot(f64, dx, dy)) * 0.5); |
| 56 | return Complex(f32).new(f32(math.fabs(y) / (2.0 * t)), f32(math.copysign(f64, t, y))); | 58 | return Complex(f32).new( |
| 59 | @floatCast(f32, math.fabs(y) / (2.0 * t)), | ||
| 60 | @floatCast(f32, math.copysign(f64, t, y)), | ||
| 61 | ); | ||
| 57 | } | 62 | } |
| 58 | } | 63 | } |
| 59 | 64 | ||
| 60 | fn sqrt64(z: *const Complex(f64)) Complex(f64) { | 65 | fn sqrt64(z: Complex(f64)) Complex(f64) { |
| 61 | // may encounter overflow for im,re >= DBL_MAX / (1 + sqrt(2)) | 66 | // may encounter overflow for im,re >= DBL_MAX / (1 + sqrt(2)) |
| 62 | const threshold = 0x1.a827999fcef32p+1022; | 67 | const threshold = 0x1.a827999fcef32p+1022; |
| 63 | 68 |
std/math/complex/tanh.zig+6-4| ... | @@ -4,7 +4,7 @@ const math = std.math; | ... | @@ -4,7 +4,7 @@ const math = std.math; |
| 4 | const cmath = math.complex; | 4 | const cmath = math.complex; |
| 5 | const Complex = cmath.Complex; | 5 | const Complex = cmath.Complex; |
| 6 | 6 | ||
| 7 | pub fn tanh(z: var) Complex(@typeOf(z.re)) { | 7 | pub fn tanh(z: var) @typeOf(z) { |
| 8 | const T = @typeOf(z.re); | 8 | const T = @typeOf(z.re); |
| 9 | return switch (T) { | 9 | return switch (T) { |
| 10 | f32 => tanh32(z), | 10 | f32 => tanh32(z), |
| ... | @@ -13,7 +13,7 @@ pub fn tanh(z: var) Complex(@typeOf(z.re)) { | ... | @@ -13,7 +13,7 @@ pub fn tanh(z: var) Complex(@typeOf(z.re)) { |
| 13 | }; | 13 | }; |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | fn tanh32(z: *const Complex(f32)) Complex(f32) { | 16 | fn tanh32(z: Complex(f32)) Complex(f32) { |
| 17 | const x = z.re; | 17 | const x = z.re; |
| 18 | const y = z.im; | 18 | const y = z.im; |
| 19 | 19 | ||
| ... | @@ -51,12 +51,14 @@ fn tanh32(z: *const Complex(f32)) Complex(f32) { | ... | @@ -51,12 +51,14 @@ fn tanh32(z: *const Complex(f32)) Complex(f32) { |
| 51 | return Complex(f32).new((beta * rho * s) / den, t / den); | 51 | return Complex(f32).new((beta * rho * s) / den, t / den); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | fn tanh64(z: *const Complex(f64)) Complex(f64) { | 54 | fn tanh64(z: Complex(f64)) Complex(f64) { |
| 55 | const x = z.re; | 55 | const x = z.re; |
| 56 | const y = z.im; | 56 | const y = z.im; |
| 57 | 57 | ||
| 58 | const fx = @bitCast(u64, x); | 58 | const fx = @bitCast(u64, x); |
| 59 | const hx = u32(fx >> 32); | 59 | // TODO: zig should allow this conversion implicitly because it can notice that the value necessarily |
| 60 | // fits in range. | ||
| 61 | const hx = @intCast(u32, fx >> 32); | ||
| 60 | const lx = @truncate(u32, fx); | 62 | const lx = @truncate(u32, fx); |
| 61 | const ix = hx & 0x7fffffff; | 63 | const ix = hx & 0x7fffffff; |
| 62 | 64 |
std/math/cos.zig+2-2| ... | @@ -55,7 +55,7 @@ fn cos32(x_: f32) f32 { | ... | @@ -55,7 +55,7 @@ fn cos32(x_: f32) f32 { |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | var y = math.floor(x * m4pi); | 57 | var y = math.floor(x * m4pi); |
| 58 | var j = i64(y); | 58 | var j = @floatToInt(i64, y); |
| 59 | 59 | ||
| 60 | if (j & 1 == 1) { | 60 | if (j & 1 == 1) { |
| 61 | j += 1; | 61 | j += 1; |
| ... | @@ -106,7 +106,7 @@ fn cos64(x_: f64) f64 { | ... | @@ -106,7 +106,7 @@ fn cos64(x_: f64) f64 { |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | var y = math.floor(x * m4pi); | 108 | var y = math.floor(x * m4pi); |
| 109 | var j = i64(y); | 109 | var j = @floatToInt(i64, y); |
| 110 | 110 | ||
| 111 | if (j & 1 == 1) { | 111 | if (j & 1 == 1) { |
| 112 | j += 1; | 112 | j += 1; |
std/math/cosh.zig+1-1| ... | @@ -49,7 +49,7 @@ fn cosh32(x: f32) f32 { | ... | @@ -49,7 +49,7 @@ fn cosh32(x: f32) f32 { |
| 49 | 49 | ||
| 50 | fn cosh64(x: f64) f64 { | 50 | fn cosh64(x: f64) f64 { |
| 51 | const u = @bitCast(u64, x); | 51 | const u = @bitCast(u64, x); |
| 52 | const w = u32(u >> 32); | 52 | const w = @intCast(u32, u >> 32); |
| 53 | const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); | 53 | const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); |
| 54 | 54 | ||
| 55 | // TODO: Shouldn't need this explicit check. | 55 | // TODO: Shouldn't need this explicit check. |
std/math/exp.zig+6-6| ... | @@ -29,7 +29,7 @@ fn exp32(x_: f32) f32 { | ... | @@ -29,7 +29,7 @@ fn exp32(x_: f32) f32 { |
| 29 | 29 | ||
| 30 | var x = x_; | 30 | var x = x_; |
| 31 | var hx = @bitCast(u32, x); | 31 | var hx = @bitCast(u32, x); |
| 32 | const sign = i32(hx >> 31); | 32 | const sign = @intCast(i32, hx >> 31); |
| 33 | hx &= 0x7FFFFFFF; | 33 | hx &= 0x7FFFFFFF; |
| 34 | 34 | ||
| 35 | if (math.isNan(x)) { | 35 | if (math.isNan(x)) { |
| ... | @@ -63,12 +63,12 @@ fn exp32(x_: f32) f32 { | ... | @@ -63,12 +63,12 @@ fn exp32(x_: f32) f32 { |
| 63 | if (hx > 0x3EB17218) { | 63 | if (hx > 0x3EB17218) { |
| 64 | // |x| > 1.5 * ln2 | 64 | // |x| > 1.5 * ln2 |
| 65 | if (hx > 0x3F851592) { | 65 | if (hx > 0x3F851592) { |
| 66 | k = i32(invln2 * x + half[usize(sign)]); | 66 | k = @floatToInt(i32, invln2 * x + half[@intCast(usize, sign)]); |
| 67 | } else { | 67 | } else { |
| 68 | k = 1 - sign - sign; | 68 | k = 1 - sign - sign; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | const fk = f32(k); | 71 | const fk = @intToFloat(f32, k); |
| 72 | hi = x - fk * ln2hi; | 72 | hi = x - fk * ln2hi; |
| 73 | lo = fk * ln2lo; | 73 | lo = fk * ln2lo; |
| 74 | x = hi - lo; | 74 | x = hi - lo; |
| ... | @@ -110,7 +110,7 @@ fn exp64(x_: f64) f64 { | ... | @@ -110,7 +110,7 @@ fn exp64(x_: f64) f64 { |
| 110 | var x = x_; | 110 | var x = x_; |
| 111 | var ux = @bitCast(u64, x); | 111 | var ux = @bitCast(u64, x); |
| 112 | var hx = ux >> 32; | 112 | var hx = ux >> 32; |
| 113 | const sign = i32(hx >> 31); | 113 | const sign = @intCast(i32, hx >> 31); |
| 114 | hx &= 0x7FFFFFFF; | 114 | hx &= 0x7FFFFFFF; |
| 115 | 115 | ||
| 116 | if (math.isNan(x)) { | 116 | if (math.isNan(x)) { |
| ... | @@ -148,12 +148,12 @@ fn exp64(x_: f64) f64 { | ... | @@ -148,12 +148,12 @@ fn exp64(x_: f64) f64 { |
| 148 | if (hx > 0x3EB17218) { | 148 | if (hx > 0x3EB17218) { |
| 149 | // |x| >= 1.5 * ln2 | 149 | // |x| >= 1.5 * ln2 |
| 150 | if (hx > 0x3FF0A2B2) { | 150 | if (hx > 0x3FF0A2B2) { |
| 151 | k = i32(invln2 * x + half[usize(sign)]); | 151 | k = @floatToInt(i32, invln2 * x + half[@intCast(usize, sign)]); |
| 152 | } else { | 152 | } else { |
| 153 | k = 1 - sign - sign; | 153 | k = 1 - sign - sign; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | const dk = f64(k); | 156 | const dk = @intToFloat(f64, k); |
| 157 | hi = x - dk * ln2hi; | 157 | hi = x - dk * ln2hi; |
| 158 | lo = dk * ln2lo; | 158 | lo = dk * ln2lo; |
| 159 | x = hi - lo; | 159 | x = hi - lo; |
std/math/exp2.zig+7-7| ... | @@ -38,8 +38,8 @@ const exp2ft = []const f64{ | ... | @@ -38,8 +38,8 @@ const exp2ft = []const f64{ |
| 38 | fn exp2_32(x: f32) f32 { | 38 | fn exp2_32(x: f32) f32 { |
| 39 | @setFloatMode(this, @import("builtin").FloatMode.Strict); | 39 | @setFloatMode(this, @import("builtin").FloatMode.Strict); |
| 40 | 40 | ||
| 41 | const tblsiz = u32(exp2ft.len); | 41 | const tblsiz = @intCast(u32, exp2ft.len); |
| 42 | const redux: f32 = 0x1.8p23 / f32(tblsiz); | 42 | const redux: f32 = 0x1.8p23 / @intToFloat(f32, tblsiz); |
| 43 | const P1: f32 = 0x1.62e430p-1; | 43 | const P1: f32 = 0x1.62e430p-1; |
| 44 | const P2: f32 = 0x1.ebfbe0p-3; | 44 | const P2: f32 = 0x1.ebfbe0p-3; |
| 45 | const P3: f32 = 0x1.c6b348p-5; | 45 | const P3: f32 = 0x1.c6b348p-5; |
| ... | @@ -89,7 +89,7 @@ fn exp2_32(x: f32) f32 { | ... | @@ -89,7 +89,7 @@ fn exp2_32(x: f32) f32 { |
| 89 | var r: f64 = exp2ft[i0]; | 89 | var r: f64 = exp2ft[i0]; |
| 90 | const t: f64 = r * z; | 90 | const t: f64 = r * z; |
| 91 | r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4); | 91 | r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4); |
| 92 | return f32(r * uk); | 92 | return @floatCast(f32, r * uk); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | const exp2dt = []f64{ | 95 | const exp2dt = []f64{ |
| ... | @@ -355,8 +355,8 @@ const exp2dt = []f64{ | ... | @@ -355,8 +355,8 @@ const exp2dt = []f64{ |
| 355 | fn exp2_64(x: f64) f64 { | 355 | fn exp2_64(x: f64) f64 { |
| 356 | @setFloatMode(this, @import("builtin").FloatMode.Strict); | 356 | @setFloatMode(this, @import("builtin").FloatMode.Strict); |
| 357 | 357 | ||
| 358 | const tblsiz = u32(exp2dt.len / 2); | 358 | const tblsiz = @intCast(u32, exp2dt.len / 2); |
| 359 | const redux: f64 = 0x1.8p52 / f64(tblsiz); | 359 | const redux: f64 = 0x1.8p52 / @intToFloat(f64, tblsiz); |
| 360 | const P1: f64 = 0x1.62e42fefa39efp-1; | 360 | const P1: f64 = 0x1.62e42fefa39efp-1; |
| 361 | const P2: f64 = 0x1.ebfbdff82c575p-3; | 361 | const P2: f64 = 0x1.ebfbdff82c575p-3; |
| 362 | const P3: f64 = 0x1.c6b08d704a0a6p-5; | 362 | const P3: f64 = 0x1.c6b08d704a0a6p-5; |
| ... | @@ -364,7 +364,7 @@ fn exp2_64(x: f64) f64 { | ... | @@ -364,7 +364,7 @@ fn exp2_64(x: f64) f64 { |
| 364 | const P5: f64 = 0x1.5d88003875c74p-10; | 364 | const P5: f64 = 0x1.5d88003875c74p-10; |
| 365 | 365 | ||
| 366 | const ux = @bitCast(u64, x); | 366 | const ux = @bitCast(u64, x); |
| 367 | const ix = u32(ux >> 32) & 0x7FFFFFFF; | 367 | const ix = @intCast(u32, ux >> 32) & 0x7FFFFFFF; |
| 368 | 368 | ||
| 369 | // TODO: This should be handled beneath. | 369 | // TODO: This should be handled beneath. |
| 370 | if (math.isNan(x)) { | 370 | if (math.isNan(x)) { |
| ... | @@ -386,7 +386,7 @@ fn exp2_64(x: f64) f64 { | ... | @@ -386,7 +386,7 @@ fn exp2_64(x: f64) f64 { |
| 386 | if (ux >> 63 != 0) { | 386 | if (ux >> 63 != 0) { |
| 387 | // underflow | 387 | // underflow |
| 388 | if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) { | 388 | if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) { |
| 389 | math.forceEval(f32(-0x1.0p-149 / x)); | 389 | math.forceEval(@floatCast(f32, -0x1.0p-149 / x)); |
| 390 | } | 390 | } |
| 391 | if (x <= -1075) { | 391 | if (x <= -1075) { |
| 392 | return 0; | 392 | return 0; |
std/math/expm1.zig+10-10| ... | @@ -78,8 +78,8 @@ fn expm1_32(x_: f32) f32 { | ... | @@ -78,8 +78,8 @@ fn expm1_32(x_: f32) f32 { |
| 78 | kf += 0.5; | 78 | kf += 0.5; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | k = i32(kf); | 81 | k = @floatToInt(i32, kf); |
| 82 | const t = f32(k); | 82 | const t = @intToFloat(f32, k); |
| 83 | hi = x - t * ln2_hi; | 83 | hi = x - t * ln2_hi; |
| 84 | lo = t * ln2_lo; | 84 | lo = t * ln2_lo; |
| 85 | } | 85 | } |
| ... | @@ -123,7 +123,7 @@ fn expm1_32(x_: f32) f32 { | ... | @@ -123,7 +123,7 @@ fn expm1_32(x_: f32) f32 { |
| 123 | } | 123 | } |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | const twopk = @bitCast(f32, u32((0x7F +% k) << 23)); | 126 | const twopk = @bitCast(f32, @intCast(u32, (0x7F +% k) << 23)); |
| 127 | 127 | ||
| 128 | if (k < 0 or k > 56) { | 128 | if (k < 0 or k > 56) { |
| 129 | var y = x - e + 1.0; | 129 | var y = x - e + 1.0; |
| ... | @@ -136,7 +136,7 @@ fn expm1_32(x_: f32) f32 { | ... | @@ -136,7 +136,7 @@ fn expm1_32(x_: f32) f32 { |
| 136 | return y - 1.0; | 136 | return y - 1.0; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | const uf = @bitCast(f32, u32(0x7F -% k) << 23); | 139 | const uf = @bitCast(f32, @intCast(u32, 0x7F -% k) << 23); |
| 140 | if (k < 23) { | 140 | if (k < 23) { |
| 141 | return (x - e + (1 - uf)) * twopk; | 141 | return (x - e + (1 - uf)) * twopk; |
| 142 | } else { | 142 | } else { |
| ... | @@ -158,7 +158,7 @@ fn expm1_64(x_: f64) f64 { | ... | @@ -158,7 +158,7 @@ fn expm1_64(x_: f64) f64 { |
| 158 | 158 | ||
| 159 | var x = x_; | 159 | var x = x_; |
| 160 | const ux = @bitCast(u64, x); | 160 | const ux = @bitCast(u64, x); |
| 161 | const hx = u32(ux >> 32) & 0x7FFFFFFF; | 161 | const hx = @intCast(u32, ux >> 32) & 0x7FFFFFFF; |
| 162 | const sign = ux >> 63; | 162 | const sign = ux >> 63; |
| 163 | 163 | ||
| 164 | if (math.isNegativeInf(x)) { | 164 | if (math.isNegativeInf(x)) { |
| ... | @@ -207,8 +207,8 @@ fn expm1_64(x_: f64) f64 { | ... | @@ -207,8 +207,8 @@ fn expm1_64(x_: f64) f64 { |
| 207 | kf += 0.5; | 207 | kf += 0.5; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | k = i32(kf); | 210 | k = @floatToInt(i32, kf); |
| 211 | const t = f64(k); | 211 | const t = @intToFloat(f64, k); |
| 212 | hi = x - t * ln2_hi; | 212 | hi = x - t * ln2_hi; |
| 213 | lo = t * ln2_lo; | 213 | lo = t * ln2_lo; |
| 214 | } | 214 | } |
| ... | @@ -219,7 +219,7 @@ fn expm1_64(x_: f64) f64 { | ... | @@ -219,7 +219,7 @@ fn expm1_64(x_: f64) f64 { |
| 219 | // |x| < 2^(-54) | 219 | // |x| < 2^(-54) |
| 220 | else if (hx < 0x3C900000) { | 220 | else if (hx < 0x3C900000) { |
| 221 | if (hx < 0x00100000) { | 221 | if (hx < 0x00100000) { |
| 222 | math.forceEval(f32(x)); | 222 | math.forceEval(@floatCast(f32, x)); |
| 223 | } | 223 | } |
| 224 | return x; | 224 | return x; |
| 225 | } else { | 225 | } else { |
| ... | @@ -252,7 +252,7 @@ fn expm1_64(x_: f64) f64 { | ... | @@ -252,7 +252,7 @@ fn expm1_64(x_: f64) f64 { |
| 252 | } | 252 | } |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | const twopk = @bitCast(f64, u64(0x3FF +% k) << 52); | 255 | const twopk = @bitCast(f64, @intCast(u64, 0x3FF +% k) << 52); |
| 256 | 256 | ||
| 257 | if (k < 0 or k > 56) { | 257 | if (k < 0 or k > 56) { |
| 258 | var y = x - e + 1.0; | 258 | var y = x - e + 1.0; |
| ... | @@ -265,7 +265,7 @@ fn expm1_64(x_: f64) f64 { | ... | @@ -265,7 +265,7 @@ fn expm1_64(x_: f64) f64 { |
| 265 | return y - 1.0; | 265 | return y - 1.0; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | const uf = @bitCast(f64, u64(0x3FF -% k) << 52); | 268 | const uf = @bitCast(f64, @intCast(u64, 0x3FF -% k) << 52); |
| 269 | if (k < 20) { | 269 | if (k < 20) { |
| 270 | return (x - e + (1 - uf)) * twopk; | 270 | return (x - e + (1 - uf)) * twopk; |
| 271 | } else { | 271 | } else { |
std/math/floor.zig+2-2| ... | @@ -20,7 +20,7 @@ pub fn floor(x: var) @typeOf(x) { | ... | @@ -20,7 +20,7 @@ pub fn floor(x: var) @typeOf(x) { |
| 20 | 20 | ||
| 21 | fn floor32(x: f32) f32 { | 21 | fn floor32(x: f32) f32 { |
| 22 | var u = @bitCast(u32, x); | 22 | var u = @bitCast(u32, x); |
| 23 | const e = i32((u >> 23) & 0xFF) - 0x7F; | 23 | const e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F; |
| 24 | var m: u32 = undefined; | 24 | var m: u32 = undefined; |
| 25 | 25 | ||
| 26 | // TODO: Shouldn't need this explicit check. | 26 | // TODO: Shouldn't need this explicit check. |
| ... | @@ -33,7 +33,7 @@ fn floor32(x: f32) f32 { | ... | @@ -33,7 +33,7 @@ fn floor32(x: f32) f32 { |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | if (e >= 0) { | 35 | if (e >= 0) { |
| 36 | m = u32(0x007FFFFF) >> u5(e); | 36 | m = u32(0x007FFFFF) >> @intCast(u5, e); |
| 37 | if (u & m == 0) { | 37 | if (u & m == 0) { |
| 38 | return x; | 38 | return x; |
| 39 | } | 39 | } |
std/math/fma.zig+3-3| ... | @@ -17,10 +17,10 @@ fn fma32(x: f32, y: f32, z: f32) f32 { | ... | @@ -17,10 +17,10 @@ fn fma32(x: f32, y: f32, z: f32) f32 { |
| 17 | const e = (u >> 52) & 0x7FF; | 17 | const e = (u >> 52) & 0x7FF; |
| 18 | 18 | ||
| 19 | if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or xy_z - xy == z) { | 19 | if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or xy_z - xy == z) { |
| 20 | return f32(xy_z); | 20 | return @floatCast(f32, xy_z); |
| 21 | } else { | 21 | } else { |
| 22 | // TODO: Handle inexact case with double-rounding | 22 | // TODO: Handle inexact case with double-rounding |
| 23 | return f32(xy_z); | 23 | return @floatCast(f32, xy_z); |
| 24 | } | 24 | } |
| 25 | } | 25 | } |
| 26 | 26 | ||
| ... | @@ -124,7 +124,7 @@ fn add_and_denorm(a: f64, b: f64, scale: i32) f64 { | ... | @@ -124,7 +124,7 @@ fn add_and_denorm(a: f64, b: f64, scale: i32) f64 { |
| 124 | var sum = dd_add(a, b); | 124 | var sum = dd_add(a, b); |
| 125 | if (sum.lo != 0) { | 125 | if (sum.lo != 0) { |
| 126 | var uhii = @bitCast(u64, sum.hi); | 126 | var uhii = @bitCast(u64, sum.hi); |
| 127 | const bits_lost = -i32((uhii >> 52) & 0x7FF) - scale + 1; | 127 | const bits_lost = -@intCast(i32, (uhii >> 52) & 0x7FF) - scale + 1; |
| 128 | if ((bits_lost != 1) == (uhii & 1 != 0)) { | 128 | if ((bits_lost != 1) == (uhii & 1 != 0)) { |
| 129 | const uloi = @bitCast(u64, sum.lo); | 129 | const uloi = @bitCast(u64, sum.lo); |
| 130 | uhii += 1 - (((uhii ^ uloi) >> 62) & 2); | 130 | uhii += 1 - (((uhii ^ uloi) >> 62) & 2); |
std/math/frexp.zig+2-2| ... | @@ -30,7 +30,7 @@ fn frexp32(x: f32) frexp32_result { | ... | @@ -30,7 +30,7 @@ fn frexp32(x: f32) frexp32_result { |
| 30 | var result: frexp32_result = undefined; | 30 | var result: frexp32_result = undefined; |
| 31 | 31 | ||
| 32 | var y = @bitCast(u32, x); | 32 | var y = @bitCast(u32, x); |
| 33 | const e = i32(y >> 23) & 0xFF; | 33 | const e = @intCast(i32, y >> 23) & 0xFF; |
| 34 | 34 | ||
| 35 | if (e == 0) { | 35 | if (e == 0) { |
| 36 | if (x != 0) { | 36 | if (x != 0) { |
| ... | @@ -67,7 +67,7 @@ fn frexp64(x: f64) frexp64_result { | ... | @@ -67,7 +67,7 @@ fn frexp64(x: f64) frexp64_result { |
| 67 | var result: frexp64_result = undefined; | 67 | var result: frexp64_result = undefined; |
| 68 | 68 | ||
| 69 | var y = @bitCast(u64, x); | 69 | var y = @bitCast(u64, x); |
| 70 | const e = i32(y >> 52) & 0x7FF; | 70 | const e = @intCast(i32, y >> 52) & 0x7FF; |
| 71 | 71 | ||
| 72 | if (e == 0) { | 72 | if (e == 0) { |
| 73 | if (x != 0) { | 73 | if (x != 0) { |
std/math/hypot.zig+1-1| ... | @@ -49,7 +49,7 @@ fn hypot32(x: f32, y: f32) f32 { | ... | @@ -49,7 +49,7 @@ fn hypot32(x: f32, y: f32) f32 { |
| 49 | yy *= 0x1.0p-90; | 49 | yy *= 0x1.0p-90; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | return z * math.sqrt(f32(f64(x) * x + f64(y) * y)); | 52 | return z * math.sqrt(@floatCast(f32, f64(x) * x + f64(y) * y)); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | fn sq(hi: *f64, lo: *f64, x: f64) void { | 55 | fn sq(hi: *f64, lo: *f64, x: f64) void { |
std/math/ilogb.zig+2-2| ... | @@ -23,7 +23,7 @@ const fp_ilogb0 = fp_ilogbnan; | ... | @@ -23,7 +23,7 @@ const fp_ilogb0 = fp_ilogbnan; |
| 23 | 23 | ||
| 24 | fn ilogb32(x: f32) i32 { | 24 | fn ilogb32(x: f32) i32 { |
| 25 | var u = @bitCast(u32, x); | 25 | var u = @bitCast(u32, x); |
| 26 | var e = i32((u >> 23) & 0xFF); | 26 | var e = @intCast(i32, (u >> 23) & 0xFF); |
| 27 | 27 | ||
| 28 | // TODO: We should be able to merge this with the lower check. | 28 | // TODO: We should be able to merge this with the lower check. |
| 29 | if (math.isNan(x)) { | 29 | if (math.isNan(x)) { |
| ... | @@ -59,7 +59,7 @@ fn ilogb32(x: f32) i32 { | ... | @@ -59,7 +59,7 @@ fn ilogb32(x: f32) i32 { |
| 59 | 59 | ||
| 60 | fn ilogb64(x: f64) i32 { | 60 | fn ilogb64(x: f64) i32 { |
| 61 | var u = @bitCast(u64, x); | 61 | var u = @bitCast(u64, x); |
| 62 | var e = i32((u >> 52) & 0x7FF); | 62 | var e = @intCast(i32, (u >> 52) & 0x7FF); |
| 63 | 63 | ||
| 64 | if (math.isNan(x)) { | 64 | if (math.isNan(x)) { |
| 65 | return @maxValue(i32); | 65 | return @maxValue(i32); |
std/math/index.zig+29-7| ... | @@ -227,7 +227,7 @@ pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) !T { | ... | @@ -227,7 +227,7 @@ pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) !T { |
| 227 | /// A negative shift amount results in a right shift. | 227 | /// A negative shift amount results in a right shift. |
| 228 | pub fn shl(comptime T: type, a: T, shift_amt: var) T { | 228 | pub fn shl(comptime T: type, a: T, shift_amt: var) T { |
| 229 | const abs_shift_amt = absCast(shift_amt); | 229 | const abs_shift_amt = absCast(shift_amt); |
| 230 | const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt); | 230 | const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else @intCast(Log2Int(T), abs_shift_amt); |
| 231 | 231 | ||
| 232 | if (@typeOf(shift_amt).is_signed) { | 232 | if (@typeOf(shift_amt).is_signed) { |
| 233 | if (shift_amt >= 0) { | 233 | if (shift_amt >= 0) { |
| ... | @@ -251,7 +251,7 @@ test "math.shl" { | ... | @@ -251,7 +251,7 @@ test "math.shl" { |
| 251 | /// A negative shift amount results in a lefft shift. | 251 | /// A negative shift amount results in a lefft shift. |
| 252 | pub fn shr(comptime T: type, a: T, shift_amt: var) T { | 252 | pub fn shr(comptime T: type, a: T, shift_amt: var) T { |
| 253 | const abs_shift_amt = absCast(shift_amt); | 253 | const abs_shift_amt = absCast(shift_amt); |
| 254 | const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt); | 254 | const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else @intCast(Log2Int(T), abs_shift_amt); |
| 255 | 255 | ||
| 256 | if (@typeOf(shift_amt).is_signed) { | 256 | if (@typeOf(shift_amt).is_signed) { |
| 257 | if (shift_amt >= 0) { | 257 | if (shift_amt >= 0) { |
| ... | @@ -473,9 +473,9 @@ fn testRem() void { | ... | @@ -473,9 +473,9 @@ fn testRem() void { |
| 473 | /// Result is an unsigned integer. | 473 | /// Result is an unsigned integer. |
| 474 | pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) { | 474 | pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) { |
| 475 | const uint = @IntType(false, @typeOf(x).bit_count); | 475 | const uint = @IntType(false, @typeOf(x).bit_count); |
| 476 | if (x >= 0) return uint(x); | 476 | if (x >= 0) return @intCast(uint, x); |
| 477 | 477 | ||
| 478 | return uint(-(x + 1)) + 1; | 478 | return @intCast(uint, -(x + 1)) + 1; |
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | test "math.absCast" { | 481 | test "math.absCast" { |
| ... | @@ -499,7 +499,7 @@ pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) { | ... | @@ -499,7 +499,7 @@ pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) { |
| 499 | 499 | ||
| 500 | if (x == -@minValue(int)) return @minValue(int); | 500 | if (x == -@minValue(int)) return @minValue(int); |
| 501 | 501 | ||
| 502 | return -int(x); | 502 | return -@intCast(int, x); |
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | test "math.negateCast" { | 505 | test "math.negateCast" { |
| ... | @@ -522,7 +522,7 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) { | ... | @@ -522,7 +522,7 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) { |
| 522 | } else if (@minValue(@typeOf(x)) < @minValue(T) and x < @minValue(T)) { | 522 | } else if (@minValue(@typeOf(x)) < @minValue(T) and x < @minValue(T)) { |
| 523 | return error.Overflow; | 523 | return error.Overflow; |
| 524 | } else { | 524 | } else { |
| 525 | return T(x); | 525 | return @intCast(T, x); |
| 526 | } | 526 | } |
| 527 | } | 527 | } |
| 528 | 528 | ||
| ... | @@ -536,6 +536,17 @@ test "math.cast" { | ... | @@ -536,6 +536,17 @@ test "math.cast" { |
| 536 | assert(@typeOf(try cast(u8, u32(255))) == u8); | 536 | assert(@typeOf(try cast(u8, u32(255))) == u8); |
| 537 | } | 537 | } |
| 538 | 538 | ||
| 539 | pub const AlignCastError = error{UnalignedMemory}; | ||
| 540 | |||
| 541 | /// Align cast a pointer but return an error if it's the wrong alignment | ||
| 542 | pub fn alignCast(comptime alignment: u29, ptr: var) AlignCastError!@typeOf(@alignCast(alignment, ptr)) { | ||
| 543 | const addr = @ptrToInt(ptr); | ||
| 544 | if (addr % alignment != 0) { | ||
| 545 | return error.UnalignedMemory; | ||
| 546 | } | ||
| 547 | return @alignCast(alignment, ptr); | ||
| 548 | } | ||
| 549 | |||
| 539 | pub fn floorPowerOfTwo(comptime T: type, value: T) T { | 550 | pub fn floorPowerOfTwo(comptime T: type, value: T) T { |
| 540 | var x = value; | 551 | var x = value; |
| 541 | 552 | ||
| ... | @@ -554,7 +565,7 @@ test "math.floorPowerOfTwo" { | ... | @@ -554,7 +565,7 @@ test "math.floorPowerOfTwo" { |
| 554 | 565 | ||
| 555 | pub fn log2_int(comptime T: type, x: T) Log2Int(T) { | 566 | pub fn log2_int(comptime T: type, x: T) Log2Int(T) { |
| 556 | assert(x != 0); | 567 | assert(x != 0); |
| 557 | return Log2Int(T)(T.bit_count - 1 - @clz(x)); | 568 | return @intCast(Log2Int(T), T.bit_count - 1 - @clz(x)); |
| 558 | } | 569 | } |
| 559 | 570 | ||
| 560 | pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) { | 571 | pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) { |
| ... | @@ -586,3 +597,14 @@ fn testFloorPowerOfTwo() void { | ... | @@ -586,3 +597,14 @@ fn testFloorPowerOfTwo() void { |
| 586 | assert(floorPowerOfTwo(u4, 8) == 8); | 597 | assert(floorPowerOfTwo(u4, 8) == 8); |
| 587 | assert(floorPowerOfTwo(u4, 9) == 8); | 598 | assert(floorPowerOfTwo(u4, 9) == 8); |
| 588 | } | 599 | } |
| 600 | |||
| 601 | pub fn lossyCast(comptime T: type, value: var) T { | ||
| 602 | switch (@typeInfo(@typeOf(value))) { | ||
| 603 | builtin.TypeId.Int => return @intToFloat(T, value), | ||
| 604 | builtin.TypeId.Float => return @floatCast(T, value), | ||
| 605 | builtin.TypeId.ComptimeInt => return T(value), | ||
| 606 | builtin.TypeId.ComptimeFloat => return T(value), | ||
| 607 | else => @compileError("bad type"), | ||
| 608 | } | ||
| 609 | } | ||
| 610 |
std/math/ln.zig+6-6| ... | @@ -71,7 +71,7 @@ pub fn ln_32(x_: f32) f32 { | ... | @@ -71,7 +71,7 @@ pub fn ln_32(x_: f32) f32 { |
| 71 | 71 | ||
| 72 | // x into [sqrt(2) / 2, sqrt(2)] | 72 | // x into [sqrt(2) / 2, sqrt(2)] |
| 73 | ix += 0x3F800000 - 0x3F3504F3; | 73 | ix += 0x3F800000 - 0x3F3504F3; |
| 74 | k += i32(ix >> 23) - 0x7F; | 74 | k += @intCast(i32, ix >> 23) - 0x7F; |
| 75 | ix = (ix & 0x007FFFFF) + 0x3F3504F3; | 75 | ix = (ix & 0x007FFFFF) + 0x3F3504F3; |
| 76 | x = @bitCast(f32, ix); | 76 | x = @bitCast(f32, ix); |
| 77 | 77 | ||
| ... | @@ -83,7 +83,7 @@ pub fn ln_32(x_: f32) f32 { | ... | @@ -83,7 +83,7 @@ pub fn ln_32(x_: f32) f32 { |
| 83 | const t2 = z * (Lg1 + w * Lg3); | 83 | const t2 = z * (Lg1 + w * Lg3); |
| 84 | const R = t2 + t1; | 84 | const R = t2 + t1; |
| 85 | const hfsq = 0.5 * f * f; | 85 | const hfsq = 0.5 * f * f; |
| 86 | const dk = f32(k); | 86 | const dk = @intToFloat(f32, k); |
| 87 | 87 | ||
| 88 | return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; | 88 | return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; |
| 89 | } | 89 | } |
| ... | @@ -103,7 +103,7 @@ pub fn ln_64(x_: f64) f64 { | ... | @@ -103,7 +103,7 @@ pub fn ln_64(x_: f64) f64 { |
| 103 | 103 | ||
| 104 | var x = x_; | 104 | var x = x_; |
| 105 | var ix = @bitCast(u64, x); | 105 | var ix = @bitCast(u64, x); |
| 106 | var hx = u32(ix >> 32); | 106 | var hx = @intCast(u32, ix >> 32); |
| 107 | var k: i32 = 0; | 107 | var k: i32 = 0; |
| 108 | 108 | ||
| 109 | if (hx < 0x00100000 or hx >> 31 != 0) { | 109 | if (hx < 0x00100000 or hx >> 31 != 0) { |
| ... | @@ -119,7 +119,7 @@ pub fn ln_64(x_: f64) f64 { | ... | @@ -119,7 +119,7 @@ pub fn ln_64(x_: f64) f64 { |
| 119 | // subnormal, scale x | 119 | // subnormal, scale x |
| 120 | k -= 54; | 120 | k -= 54; |
| 121 | x *= 0x1.0p54; | 121 | x *= 0x1.0p54; |
| 122 | hx = u32(@bitCast(u64, ix) >> 32); | 122 | hx = @intCast(u32, @bitCast(u64, ix) >> 32); |
| 123 | } else if (hx >= 0x7FF00000) { | 123 | } else if (hx >= 0x7FF00000) { |
| 124 | return x; | 124 | return x; |
| 125 | } else if (hx == 0x3FF00000 and ix << 32 == 0) { | 125 | } else if (hx == 0x3FF00000 and ix << 32 == 0) { |
| ... | @@ -128,7 +128,7 @@ pub fn ln_64(x_: f64) f64 { | ... | @@ -128,7 +128,7 @@ pub fn ln_64(x_: f64) f64 { |
| 128 | 128 | ||
| 129 | // x into [sqrt(2) / 2, sqrt(2)] | 129 | // x into [sqrt(2) / 2, sqrt(2)] |
| 130 | hx += 0x3FF00000 - 0x3FE6A09E; | 130 | hx += 0x3FF00000 - 0x3FE6A09E; |
| 131 | k += i32(hx >> 20) - 0x3FF; | 131 | k += @intCast(i32, hx >> 20) - 0x3FF; |
| 132 | hx = (hx & 0x000FFFFF) + 0x3FE6A09E; | 132 | hx = (hx & 0x000FFFFF) + 0x3FE6A09E; |
| 133 | ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF); | 133 | ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF); |
| 134 | x = @bitCast(f64, ix); | 134 | x = @bitCast(f64, ix); |
| ... | @@ -141,7 +141,7 @@ pub fn ln_64(x_: f64) f64 { | ... | @@ -141,7 +141,7 @@ pub fn ln_64(x_: f64) f64 { |
| 141 | const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); | 141 | const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); |
| 142 | const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); | 142 | const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); |
| 143 | const R = t2 + t1; | 143 | const R = t2 + t1; |
| 144 | const dk = f64(k); | 144 | const dk = @intToFloat(f64, k); |
| 145 | 145 | ||
| 146 | return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; | 146 | return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; |
| 147 | } | 147 | } |
std/math/log.zig+6-5| ... | @@ -13,22 +13,23 @@ pub fn log(comptime T: type, base: T, x: T) T { | ... | @@ -13,22 +13,23 @@ pub fn log(comptime T: type, base: T, x: T) T { |
| 13 | return math.ln(x); | 13 | return math.ln(x); |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | const float_base = math.lossyCast(f64, base); | ||
| 16 | switch (@typeId(T)) { | 17 | switch (@typeId(T)) { |
| 17 | TypeId.ComptimeFloat => { | 18 | TypeId.ComptimeFloat => { |
| 18 | return @typeOf(1.0)(math.ln(f64(x)) / math.ln(f64(base))); | 19 | return @typeOf(1.0)(math.ln(f64(x)) / math.ln(float_base)); |
| 19 | }, | 20 | }, |
| 20 | TypeId.ComptimeInt => { | 21 | TypeId.ComptimeInt => { |
| 21 | return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(f64(base)))); | 22 | return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(float_base))); |
| 22 | }, | 23 | }, |
| 23 | builtin.TypeId.Int => { | 24 | builtin.TypeId.Int => { |
| 24 | // TODO implement integer log without using float math | 25 | // TODO implement integer log without using float math |
| 25 | return T(math.floor(math.ln(f64(x)) / math.ln(f64(base)))); | 26 | return @floatToInt(T, math.floor(math.ln(@intToFloat(f64, x)) / math.ln(float_base))); |
| 26 | }, | 27 | }, |
| 27 | 28 | ||
| 28 | builtin.TypeId.Float => { | 29 | builtin.TypeId.Float => { |
| 29 | switch (T) { | 30 | switch (T) { |
| 30 | f32 => return f32(math.ln(f64(x)) / math.ln(f64(base))), | 31 | f32 => return @floatCast(f32, math.ln(f64(x)) / math.ln(float_base)), |
| 31 | f64 => return math.ln(x) / math.ln(f64(base)), | 32 | f64 => return math.ln(x) / math.ln(float_base), |
| 32 | else => @compileError("log not implemented for " ++ @typeName(T)), | 33 | else => @compileError("log not implemented for " ++ @typeName(T)), |
| 33 | } | 34 | } |
| 34 | }, | 35 | }, |
std/math/log10.zig+7-7| ... | @@ -28,7 +28,7 @@ pub fn log10(x: var) @typeOf(x) { | ... | @@ -28,7 +28,7 @@ pub fn log10(x: var) @typeOf(x) { |
| 28 | return @typeOf(1)(math.floor(log10_64(f64(x)))); | 28 | return @typeOf(1)(math.floor(log10_64(f64(x)))); |
| 29 | }, | 29 | }, |
| 30 | TypeId.Int => { | 30 | TypeId.Int => { |
| 31 | return T(math.floor(log10_64(f64(x)))); | 31 | return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x)))); |
| 32 | }, | 32 | }, |
| 33 | else => @compileError("log10 not implemented for " ++ @typeName(T)), | 33 | else => @compileError("log10 not implemented for " ++ @typeName(T)), |
| 34 | } | 34 | } |
| ... | @@ -71,7 +71,7 @@ pub fn log10_32(x_: f32) f32 { | ... | @@ -71,7 +71,7 @@ pub fn log10_32(x_: f32) f32 { |
| 71 | 71 | ||
| 72 | // x into [sqrt(2) / 2, sqrt(2)] | 72 | // x into [sqrt(2) / 2, sqrt(2)] |
| 73 | ix += 0x3F800000 - 0x3F3504F3; | 73 | ix += 0x3F800000 - 0x3F3504F3; |
| 74 | k += i32(ix >> 23) - 0x7F; | 74 | k += @intCast(i32, ix >> 23) - 0x7F; |
| 75 | ix = (ix & 0x007FFFFF) + 0x3F3504F3; | 75 | ix = (ix & 0x007FFFFF) + 0x3F3504F3; |
| 76 | x = @bitCast(f32, ix); | 76 | x = @bitCast(f32, ix); |
| 77 | 77 | ||
| ... | @@ -89,7 +89,7 @@ pub fn log10_32(x_: f32) f32 { | ... | @@ -89,7 +89,7 @@ pub fn log10_32(x_: f32) f32 { |
| 89 | u &= 0xFFFFF000; | 89 | u &= 0xFFFFF000; |
| 90 | hi = @bitCast(f32, u); | 90 | hi = @bitCast(f32, u); |
| 91 | const lo = f - hi - hfsq + s * (hfsq + R); | 91 | const lo = f - hi - hfsq + s * (hfsq + R); |
| 92 | const dk = f32(k); | 92 | const dk = @intToFloat(f32, k); |
| 93 | 93 | ||
| 94 | return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi; | 94 | return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi; |
| 95 | } | 95 | } |
| ... | @@ -109,7 +109,7 @@ pub fn log10_64(x_: f64) f64 { | ... | @@ -109,7 +109,7 @@ pub fn log10_64(x_: f64) f64 { |
| 109 | 109 | ||
| 110 | var x = x_; | 110 | var x = x_; |
| 111 | var ix = @bitCast(u64, x); | 111 | var ix = @bitCast(u64, x); |
| 112 | var hx = u32(ix >> 32); | 112 | var hx = @intCast(u32, ix >> 32); |
| 113 | var k: i32 = 0; | 113 | var k: i32 = 0; |
| 114 | 114 | ||
| 115 | if (hx < 0x00100000 or hx >> 31 != 0) { | 115 | if (hx < 0x00100000 or hx >> 31 != 0) { |
| ... | @@ -125,7 +125,7 @@ pub fn log10_64(x_: f64) f64 { | ... | @@ -125,7 +125,7 @@ pub fn log10_64(x_: f64) f64 { |
| 125 | // subnormal, scale x | 125 | // subnormal, scale x |
| 126 | k -= 54; | 126 | k -= 54; |
| 127 | x *= 0x1.0p54; | 127 | x *= 0x1.0p54; |
| 128 | hx = u32(@bitCast(u64, x) >> 32); | 128 | hx = @intCast(u32, @bitCast(u64, x) >> 32); |
| 129 | } else if (hx >= 0x7FF00000) { | 129 | } else if (hx >= 0x7FF00000) { |
| 130 | return x; | 130 | return x; |
| 131 | } else if (hx == 0x3FF00000 and ix << 32 == 0) { | 131 | } else if (hx == 0x3FF00000 and ix << 32 == 0) { |
| ... | @@ -134,7 +134,7 @@ pub fn log10_64(x_: f64) f64 { | ... | @@ -134,7 +134,7 @@ pub fn log10_64(x_: f64) f64 { |
| 134 | 134 | ||
| 135 | // x into [sqrt(2) / 2, sqrt(2)] | 135 | // x into [sqrt(2) / 2, sqrt(2)] |
| 136 | hx += 0x3FF00000 - 0x3FE6A09E; | 136 | hx += 0x3FF00000 - 0x3FE6A09E; |
| 137 | k += i32(hx >> 20) - 0x3FF; | 137 | k += @intCast(i32, hx >> 20) - 0x3FF; |
| 138 | hx = (hx & 0x000FFFFF) + 0x3FE6A09E; | 138 | hx = (hx & 0x000FFFFF) + 0x3FE6A09E; |
| 139 | ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF); | 139 | ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF); |
| 140 | x = @bitCast(f64, ix); | 140 | x = @bitCast(f64, ix); |
| ... | @@ -157,7 +157,7 @@ pub fn log10_64(x_: f64) f64 { | ... | @@ -157,7 +157,7 @@ pub fn log10_64(x_: f64) f64 { |
| 157 | 157 | ||
| 158 | // val_hi + val_lo ~ log10(1 + f) + k * log10(2) | 158 | // val_hi + val_lo ~ log10(1 + f) + k * log10(2) |
| 159 | var val_hi = hi * ivln10hi; | 159 | var val_hi = hi * ivln10hi; |
| 160 | const dk = f64(k); | 160 | const dk = @intToFloat(f64, k); |
| 161 | const y = dk * log10_2hi; | 161 | const y = dk * log10_2hi; |
| 162 | var val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi; | 162 | var val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi; |
| 163 | 163 |
std/math/log1p.zig+6-6| ... | @@ -71,7 +71,7 @@ fn log1p_32(x: f32) f32 { | ... | @@ -71,7 +71,7 @@ fn log1p_32(x: f32) f32 { |
| 71 | const uf = 1 + x; | 71 | const uf = 1 + x; |
| 72 | var iu = @bitCast(u32, uf); | 72 | var iu = @bitCast(u32, uf); |
| 73 | iu += 0x3F800000 - 0x3F3504F3; | 73 | iu += 0x3F800000 - 0x3F3504F3; |
| 74 | k = i32(iu >> 23) - 0x7F; | 74 | k = @intCast(i32, iu >> 23) - 0x7F; |
| 75 | 75 | ||
| 76 | // correction to avoid underflow in c / u | 76 | // correction to avoid underflow in c / u |
| 77 | if (k < 25) { | 77 | if (k < 25) { |
| ... | @@ -93,7 +93,7 @@ fn log1p_32(x: f32) f32 { | ... | @@ -93,7 +93,7 @@ fn log1p_32(x: f32) f32 { |
| 93 | const t2 = z * (Lg1 + w * Lg3); | 93 | const t2 = z * (Lg1 + w * Lg3); |
| 94 | const R = t2 + t1; | 94 | const R = t2 + t1; |
| 95 | const hfsq = 0.5 * f * f; | 95 | const hfsq = 0.5 * f * f; |
| 96 | const dk = f32(k); | 96 | const dk = @intToFloat(f32, k); |
| 97 | 97 | ||
| 98 | return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi; | 98 | return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi; |
| 99 | } | 99 | } |
| ... | @@ -112,7 +112,7 @@ fn log1p_64(x: f64) f64 { | ... | @@ -112,7 +112,7 @@ fn log1p_64(x: f64) f64 { |
| 112 | const Lg7: f64 = 1.479819860511658591e-01; | 112 | const Lg7: f64 = 1.479819860511658591e-01; |
| 113 | 113 | ||
| 114 | var ix = @bitCast(u64, x); | 114 | var ix = @bitCast(u64, x); |
| 115 | var hx = u32(ix >> 32); | 115 | var hx = @intCast(u32, ix >> 32); |
| 116 | var k: i32 = 1; | 116 | var k: i32 = 1; |
| 117 | var c: f64 = undefined; | 117 | var c: f64 = undefined; |
| 118 | var f: f64 = undefined; | 118 | var f: f64 = undefined; |
| ... | @@ -150,9 +150,9 @@ fn log1p_64(x: f64) f64 { | ... | @@ -150,9 +150,9 @@ fn log1p_64(x: f64) f64 { |
| 150 | if (k != 0) { | 150 | if (k != 0) { |
| 151 | const uf = 1 + x; | 151 | const uf = 1 + x; |
| 152 | const hu = @bitCast(u64, uf); | 152 | const hu = @bitCast(u64, uf); |
| 153 | var iu = u32(hu >> 32); | 153 | var iu = @intCast(u32, hu >> 32); |
| 154 | iu += 0x3FF00000 - 0x3FE6A09E; | 154 | iu += 0x3FF00000 - 0x3FE6A09E; |
| 155 | k = i32(iu >> 20) - 0x3FF; | 155 | k = @intCast(i32, iu >> 20) - 0x3FF; |
| 156 | 156 | ||
| 157 | // correction to avoid underflow in c / u | 157 | // correction to avoid underflow in c / u |
| 158 | if (k < 54) { | 158 | if (k < 54) { |
| ... | @@ -175,7 +175,7 @@ fn log1p_64(x: f64) f64 { | ... | @@ -175,7 +175,7 @@ fn log1p_64(x: f64) f64 { |
| 175 | const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); | 175 | const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); |
| 176 | const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); | 176 | const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); |
| 177 | const R = t2 + t1; | 177 | const R = t2 + t1; |
| 178 | const dk = f64(k); | 178 | const dk = @intToFloat(f64, k); |
| 179 | 179 | ||
| 180 | return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi; | 180 | return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi; |
| 181 | } | 181 | } |
std/math/log2.zig+6-6| ... | @@ -75,7 +75,7 @@ pub fn log2_32(x_: f32) f32 { | ... | @@ -75,7 +75,7 @@ pub fn log2_32(x_: f32) f32 { |
| 75 | 75 | ||
| 76 | // x into [sqrt(2) / 2, sqrt(2)] | 76 | // x into [sqrt(2) / 2, sqrt(2)] |
| 77 | ix += 0x3F800000 - 0x3F3504F3; | 77 | ix += 0x3F800000 - 0x3F3504F3; |
| 78 | k += i32(ix >> 23) - 0x7F; | 78 | k += @intCast(i32, ix >> 23) - 0x7F; |
| 79 | ix = (ix & 0x007FFFFF) + 0x3F3504F3; | 79 | ix = (ix & 0x007FFFFF) + 0x3F3504F3; |
| 80 | x = @bitCast(f32, ix); | 80 | x = @bitCast(f32, ix); |
| 81 | 81 | ||
| ... | @@ -93,7 +93,7 @@ pub fn log2_32(x_: f32) f32 { | ... | @@ -93,7 +93,7 @@ pub fn log2_32(x_: f32) f32 { |
| 93 | u &= 0xFFFFF000; | 93 | u &= 0xFFFFF000; |
| 94 | hi = @bitCast(f32, u); | 94 | hi = @bitCast(f32, u); |
| 95 | const lo = f - hi - hfsq + s * (hfsq + R); | 95 | const lo = f - hi - hfsq + s * (hfsq + R); |
| 96 | return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + f32(k); | 96 | return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @intToFloat(f32, k); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | pub fn log2_64(x_: f64) f64 { | 99 | pub fn log2_64(x_: f64) f64 { |
| ... | @@ -109,7 +109,7 @@ pub fn log2_64(x_: f64) f64 { | ... | @@ -109,7 +109,7 @@ pub fn log2_64(x_: f64) f64 { |
| 109 | 109 | ||
| 110 | var x = x_; | 110 | var x = x_; |
| 111 | var ix = @bitCast(u64, x); | 111 | var ix = @bitCast(u64, x); |
| 112 | var hx = u32(ix >> 32); | 112 | var hx = @intCast(u32, ix >> 32); |
| 113 | var k: i32 = 0; | 113 | var k: i32 = 0; |
| 114 | 114 | ||
| 115 | if (hx < 0x00100000 or hx >> 31 != 0) { | 115 | if (hx < 0x00100000 or hx >> 31 != 0) { |
| ... | @@ -125,7 +125,7 @@ pub fn log2_64(x_: f64) f64 { | ... | @@ -125,7 +125,7 @@ pub fn log2_64(x_: f64) f64 { |
| 125 | // subnormal, scale x | 125 | // subnormal, scale x |
| 126 | k -= 54; | 126 | k -= 54; |
| 127 | x *= 0x1.0p54; | 127 | x *= 0x1.0p54; |
| 128 | hx = u32(@bitCast(u64, x) >> 32); | 128 | hx = @intCast(u32, @bitCast(u64, x) >> 32); |
| 129 | } else if (hx >= 0x7FF00000) { | 129 | } else if (hx >= 0x7FF00000) { |
| 130 | return x; | 130 | return x; |
| 131 | } else if (hx == 0x3FF00000 and ix << 32 == 0) { | 131 | } else if (hx == 0x3FF00000 and ix << 32 == 0) { |
| ... | @@ -134,7 +134,7 @@ pub fn log2_64(x_: f64) f64 { | ... | @@ -134,7 +134,7 @@ pub fn log2_64(x_: f64) f64 { |
| 134 | 134 | ||
| 135 | // x into [sqrt(2) / 2, sqrt(2)] | 135 | // x into [sqrt(2) / 2, sqrt(2)] |
| 136 | hx += 0x3FF00000 - 0x3FE6A09E; | 136 | hx += 0x3FF00000 - 0x3FE6A09E; |
| 137 | k += i32(hx >> 20) - 0x3FF; | 137 | k += @intCast(i32, hx >> 20) - 0x3FF; |
| 138 | hx = (hx & 0x000FFFFF) + 0x3FE6A09E; | 138 | hx = (hx & 0x000FFFFF) + 0x3FE6A09E; |
| 139 | ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF); | 139 | ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF); |
| 140 | x = @bitCast(f64, ix); | 140 | x = @bitCast(f64, ix); |
| ... | @@ -159,7 +159,7 @@ pub fn log2_64(x_: f64) f64 { | ... | @@ -159,7 +159,7 @@ pub fn log2_64(x_: f64) f64 { |
| 159 | var val_lo = (lo + hi) * ivln2lo + lo * ivln2hi; | 159 | var val_lo = (lo + hi) * ivln2lo + lo * ivln2hi; |
| 160 | 160 | ||
| 161 | // spadd(val_hi, val_lo, y) | 161 | // spadd(val_hi, val_lo, y) |
| 162 | const y = f64(k); | 162 | const y = @intToFloat(f64, k); |
| 163 | const ww = y + val_hi; | 163 | const ww = y + val_hi; |
| 164 | val_lo += (y - ww) + val_hi; | 164 | val_lo += (y - ww) + val_hi; |
| 165 | val_hi = ww; | 165 | val_hi = ww; |
std/math/modf.zig+4-4| ... | @@ -29,7 +29,7 @@ fn modf32(x: f32) modf32_result { | ... | @@ -29,7 +29,7 @@ fn modf32(x: f32) modf32_result { |
| 29 | var result: modf32_result = undefined; | 29 | var result: modf32_result = undefined; |
| 30 | 30 | ||
| 31 | const u = @bitCast(u32, x); | 31 | const u = @bitCast(u32, x); |
| 32 | const e = i32((u >> 23) & 0xFF) - 0x7F; | 32 | const e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F; |
| 33 | const us = u & 0x80000000; | 33 | const us = u & 0x80000000; |
| 34 | 34 | ||
| 35 | // TODO: Shouldn't need this. | 35 | // TODO: Shouldn't need this. |
| ... | @@ -57,7 +57,7 @@ fn modf32(x: f32) modf32_result { | ... | @@ -57,7 +57,7 @@ fn modf32(x: f32) modf32_result { |
| 57 | return result; | 57 | return result; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | const mask = u32(0x007FFFFF) >> u5(e); | 60 | const mask = u32(0x007FFFFF) >> @intCast(u5, e); |
| 61 | if (u & mask == 0) { | 61 | if (u & mask == 0) { |
| 62 | result.ipart = x; | 62 | result.ipart = x; |
| 63 | result.fpart = @bitCast(f32, us); | 63 | result.fpart = @bitCast(f32, us); |
| ... | @@ -74,7 +74,7 @@ fn modf64(x: f64) modf64_result { | ... | @@ -74,7 +74,7 @@ fn modf64(x: f64) modf64_result { |
| 74 | var result: modf64_result = undefined; | 74 | var result: modf64_result = undefined; |
| 75 | 75 | ||
| 76 | const u = @bitCast(u64, x); | 76 | const u = @bitCast(u64, x); |
| 77 | const e = i32((u >> 52) & 0x7FF) - 0x3FF; | 77 | const e = @intCast(i32, (u >> 52) & 0x7FF) - 0x3FF; |
| 78 | const us = u & (1 << 63); | 78 | const us = u & (1 << 63); |
| 79 | 79 | ||
| 80 | if (math.isInf(x)) { | 80 | if (math.isInf(x)) { |
| ... | @@ -101,7 +101,7 @@ fn modf64(x: f64) modf64_result { | ... | @@ -101,7 +101,7 @@ fn modf64(x: f64) modf64_result { |
| 101 | return result; | 101 | return result; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | const mask = u64(@maxValue(u64) >> 12) >> u6(e); | 104 | const mask = u64(@maxValue(u64) >> 12) >> @intCast(u6, e); |
| 105 | if (u & mask == 0) { | 105 | if (u & mask == 0) { |
| 106 | result.ipart = x; | 106 | result.ipart = x; |
| 107 | result.fpart = @bitCast(f64, us); | 107 | result.fpart = @bitCast(f64, us); |
std/math/pow.zig+2-2| ... | @@ -146,7 +146,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { | ... | @@ -146,7 +146,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { |
| 146 | var xe = r2.exponent; | 146 | var xe = r2.exponent; |
| 147 | var x1 = r2.significand; | 147 | var x1 = r2.significand; |
| 148 | 148 | ||
| 149 | var i = i32(yi); | 149 | var i = @floatToInt(i32, yi); |
| 150 | while (i != 0) : (i >>= 1) { | 150 | while (i != 0) : (i >>= 1) { |
| 151 | if (i & 1 == 1) { | 151 | if (i & 1 == 1) { |
| 152 | a1 *= x1; | 152 | a1 *= x1; |
| ... | @@ -171,7 +171,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { | ... | @@ -171,7 +171,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { |
| 171 | 171 | ||
| 172 | fn isOddInteger(x: f64) bool { | 172 | fn isOddInteger(x: f64) bool { |
| 173 | const r = math.modf(x); | 173 | const r = math.modf(x); |
| 174 | return r.fpart == 0.0 and i64(r.ipart) & 1 == 1; | 174 | return r.fpart == 0.0 and @floatToInt(i64, r.ipart) & 1 == 1; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | test "math.pow" { | 177 | test "math.pow" { |
std/math/scalbn.zig+2-2| ... | @@ -37,7 +37,7 @@ fn scalbn32(x: f32, n_: i32) f32 { | ... | @@ -37,7 +37,7 @@ fn scalbn32(x: f32, n_: i32) f32 { |
| 37 | } | 37 | } |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | const u = u32(n +% 0x7F) << 23; | 40 | const u = @intCast(u32, n +% 0x7F) << 23; |
| 41 | return y * @bitCast(f32, u); | 41 | return y * @bitCast(f32, u); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| ... | @@ -67,7 +67,7 @@ fn scalbn64(x: f64, n_: i32) f64 { | ... | @@ -67,7 +67,7 @@ fn scalbn64(x: f64, n_: i32) f64 { |
| 67 | } | 67 | } |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | const u = u64(n +% 0x3FF) << 52; | 70 | const u = @intCast(u64, n +% 0x3FF) << 52; |
| 71 | return y * @bitCast(f64, u); | 71 | return y * @bitCast(f64, u); |
| 72 | } | 72 | } |
| 73 | 73 |
std/math/sin.zig+2-2| ... | @@ -60,7 +60,7 @@ fn sin32(x_: f32) f32 { | ... | @@ -60,7 +60,7 @@ fn sin32(x_: f32) f32 { |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | var y = math.floor(x * m4pi); | 62 | var y = math.floor(x * m4pi); |
| 63 | var j = i64(y); | 63 | var j = @floatToInt(i64, y); |
| 64 | 64 | ||
| 65 | if (j & 1 == 1) { | 65 | if (j & 1 == 1) { |
| 66 | j += 1; | 66 | j += 1; |
| ... | @@ -112,7 +112,7 @@ fn sin64(x_: f64) f64 { | ... | @@ -112,7 +112,7 @@ fn sin64(x_: f64) f64 { |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | var y = math.floor(x * m4pi); | 114 | var y = math.floor(x * m4pi); |
| 115 | var j = i64(y); | 115 | var j = @floatToInt(i64, y); |
| 116 | 116 | ||
| 117 | if (j & 1 == 1) { | 117 | if (j & 1 == 1) { |
| 118 | j += 1; | 118 | j += 1; |
std/math/sinh.zig+1-1| ... | @@ -57,7 +57,7 @@ fn sinh64(x: f64) f64 { | ... | @@ -57,7 +57,7 @@ fn sinh64(x: f64) f64 { |
| 57 | @setFloatMode(this, @import("builtin").FloatMode.Strict); | 57 | @setFloatMode(this, @import("builtin").FloatMode.Strict); |
| 58 | 58 | ||
| 59 | const u = @bitCast(u64, x); | 59 | const u = @bitCast(u64, x); |
| 60 | const w = u32(u >> 32); | 60 | const w = @intCast(u32, u >> 32); |
| 61 | const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); | 61 | const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); |
| 62 | 62 | ||
| 63 | if (x == 0.0 or math.isNan(x)) { | 63 | if (x == 0.0 or math.isNan(x)) { |
std/math/sqrt.zig+1-1| ... | @@ -99,7 +99,7 @@ fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) { | ... | @@ -99,7 +99,7 @@ fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) { |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | const ResultType = @IntType(false, T.bit_count / 2); | 101 | const ResultType = @IntType(false, T.bit_count / 2); |
| 102 | return ResultType(res); | 102 | return @intCast(ResultType, res); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | test "math.sqrt_int" { | 105 | test "math.sqrt_int" { |
std/math/tan.zig+2-2| ... | @@ -53,7 +53,7 @@ fn tan32(x_: f32) f32 { | ... | @@ -53,7 +53,7 @@ fn tan32(x_: f32) f32 { |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | var y = math.floor(x * m4pi); | 55 | var y = math.floor(x * m4pi); |
| 56 | var j = i64(y); | 56 | var j = @floatToInt(i64, y); |
| 57 | 57 | ||
| 58 | if (j & 1 == 1) { | 58 | if (j & 1 == 1) { |
| 59 | j += 1; | 59 | j += 1; |
| ... | @@ -102,7 +102,7 @@ fn tan64(x_: f64) f64 { | ... | @@ -102,7 +102,7 @@ fn tan64(x_: f64) f64 { |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | var y = math.floor(x * m4pi); | 104 | var y = math.floor(x * m4pi); |
| 105 | var j = i64(y); | 105 | var j = @floatToInt(i64, y); |
| 106 | 106 | ||
| 107 | if (j & 1 == 1) { | 107 | if (j & 1 == 1) { |
| 108 | j += 1; | 108 | j += 1; |
std/math/tanh.zig+2-2| ... | @@ -68,7 +68,7 @@ fn tanh32(x: f32) f32 { | ... | @@ -68,7 +68,7 @@ fn tanh32(x: f32) f32 { |
| 68 | 68 | ||
| 69 | fn tanh64(x: f64) f64 { | 69 | fn tanh64(x: f64) f64 { |
| 70 | const u = @bitCast(u64, x); | 70 | const u = @bitCast(u64, x); |
| 71 | const w = u32(u >> 32); | 71 | const w = @intCast(u32, u >> 32); |
| 72 | const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); | 72 | const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); |
| 73 | 73 | ||
| 74 | var t: f64 = undefined; | 74 | var t: f64 = undefined; |
| ... | @@ -100,7 +100,7 @@ fn tanh64(x: f64) f64 { | ... | @@ -100,7 +100,7 @@ fn tanh64(x: f64) f64 { |
| 100 | } | 100 | } |
| 101 | // |x| is subnormal | 101 | // |x| is subnormal |
| 102 | else { | 102 | else { |
| 103 | math.forceEval(f32(x)); | 103 | math.forceEval(@floatCast(f32, x)); |
| 104 | t = x; | 104 | t = x; |
| 105 | } | 105 | } |
| 106 | 106 |
std/math/trunc.zig+4-4| ... | @@ -19,7 +19,7 @@ pub fn trunc(x: var) @typeOf(x) { | ... | @@ -19,7 +19,7 @@ pub fn trunc(x: var) @typeOf(x) { |
| 19 | 19 | ||
| 20 | fn trunc32(x: f32) f32 { | 20 | fn trunc32(x: f32) f32 { |
| 21 | const u = @bitCast(u32, x); | 21 | const u = @bitCast(u32, x); |
| 22 | var e = i32(((u >> 23) & 0xFF)) - 0x7F + 9; | 22 | var e = @intCast(i32, ((u >> 23) & 0xFF)) - 0x7F + 9; |
| 23 | var m: u32 = undefined; | 23 | var m: u32 = undefined; |
| 24 | 24 | ||
| 25 | if (e >= 23 + 9) { | 25 | if (e >= 23 + 9) { |
| ... | @@ -29,7 +29,7 @@ fn trunc32(x: f32) f32 { | ... | @@ -29,7 +29,7 @@ fn trunc32(x: f32) f32 { |
| 29 | e = 1; | 29 | e = 1; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | m = u32(@maxValue(u32)) >> u5(e); | 32 | m = u32(@maxValue(u32)) >> @intCast(u5, e); |
| 33 | if (u & m == 0) { | 33 | if (u & m == 0) { |
| 34 | return x; | 34 | return x; |
| 35 | } else { | 35 | } else { |
| ... | @@ -40,7 +40,7 @@ fn trunc32(x: f32) f32 { | ... | @@ -40,7 +40,7 @@ fn trunc32(x: f32) f32 { |
| 40 | 40 | ||
| 41 | fn trunc64(x: f64) f64 { | 41 | fn trunc64(x: f64) f64 { |
| 42 | const u = @bitCast(u64, x); | 42 | const u = @bitCast(u64, x); |
| 43 | var e = i32(((u >> 52) & 0x7FF)) - 0x3FF + 12; | 43 | var e = @intCast(i32, ((u >> 52) & 0x7FF)) - 0x3FF + 12; |
| 44 | var m: u64 = undefined; | 44 | var m: u64 = undefined; |
| 45 | 45 | ||
| 46 | if (e >= 52 + 12) { | 46 | if (e >= 52 + 12) { |
| ... | @@ -50,7 +50,7 @@ fn trunc64(x: f64) f64 { | ... | @@ -50,7 +50,7 @@ fn trunc64(x: f64) f64 { |
| 50 | e = 1; | 50 | e = 1; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | m = u64(@maxValue(u64)) >> u6(e); | 53 | m = u64(@maxValue(u64)) >> @intCast(u6, e); |
| 54 | if (u & m == 0) { | 54 | if (u & m == 0) { |
| 55 | return x; | 55 | return x; |
| 56 | } else { | 56 | } else { |
std/mem.zig+4-8| ... | @@ -40,16 +40,12 @@ pub const Allocator = struct { | ... | @@ -40,16 +40,12 @@ pub const Allocator = struct { |
| 40 | 40 | ||
| 41 | /// Call destroy with the result | 41 | /// Call destroy with the result |
| 42 | /// TODO once #733 is solved, this will replace create | 42 | /// TODO once #733 is solved, this will replace create |
| 43 | pub fn construct(self: *Allocator, init: var) t: { | 43 | pub fn construct(self: *Allocator, init: var) Error!*@typeOf(init) { |
| 44 | // TODO this is a workaround for type getting parsed as Error!&const T | 44 | const T = @typeOf(init); |
| 45 | const T = @typeOf(init).Child; | ||
| 46 | break :t Error!*T; | ||
| 47 | } { | ||
| 48 | const T = @typeOf(init).Child; | ||
| 49 | if (@sizeOf(T) == 0) return &{}; | 45 | if (@sizeOf(T) == 0) return &{}; |
| 50 | const slice = try self.alloc(T, 1); | 46 | const slice = try self.alloc(T, 1); |
| 51 | const ptr = &slice[0]; | 47 | const ptr = &slice[0]; |
| 52 | ptr.* = init.*; | 48 | ptr.* = init; |
| 53 | return ptr; | 49 | return ptr; |
| 54 | } | 50 | } |
| 55 | 51 | ||
| ... | @@ -338,7 +334,7 @@ pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) T { | ... | @@ -338,7 +334,7 @@ pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) T { |
| 338 | builtin.Endian.Little => { | 334 | builtin.Endian.Little => { |
| 339 | const ShiftType = math.Log2Int(T); | 335 | const ShiftType = math.Log2Int(T); |
| 340 | for (bytes) |b, index| { | 336 | for (bytes) |b, index| { |
| 341 | result = result | (T(b) << ShiftType(index * 8)); | 337 | result = result | (T(b) << @intCast(ShiftType, index * 8)); |
| 342 | } | 338 | } |
| 343 | }, | 339 | }, |
| 344 | } | 340 | } |
std/os/child_process.zig+1-1| ... | @@ -413,7 +413,7 @@ pub const ChildProcess = struct { | ... | @@ -413,7 +413,7 @@ pub const ChildProcess = struct { |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | // we are the parent | 415 | // we are the parent |
| 416 | const pid = i32(pid_result); | 416 | const pid = @intCast(i32, pid_result); |
| 417 | if (self.stdin_behavior == StdIo.Pipe) { | 417 | if (self.stdin_behavior == StdIo.Pipe) { |
| 418 | self.stdin = os.File.openHandle(stdin_pipe[1]); | 418 | self.stdin = os.File.openHandle(stdin_pipe[1]); |
| 419 | } else { | 419 | } else { |
std/os/darwin.zig+9-2| ... | @@ -290,7 +290,7 @@ pub fn WIFSIGNALED(x: i32) bool { | ... | @@ -290,7 +290,7 @@ pub fn WIFSIGNALED(x: i32) bool { |
| 290 | /// Get the errno from a syscall return value, or 0 for no error. | 290 | /// Get the errno from a syscall return value, or 0 for no error. |
| 291 | pub fn getErrno(r: usize) usize { | 291 | pub fn getErrno(r: usize) usize { |
| 292 | const signed_r = @bitCast(isize, r); | 292 | const signed_r = @bitCast(isize, r); |
| 293 | return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0; | 293 | return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | pub fn close(fd: i32) usize { | 296 | pub fn close(fd: i32) usize { |
| ... | @@ -339,7 +339,14 @@ pub fn write(fd: i32, buf: [*]const u8, nbyte: usize) usize { | ... | @@ -339,7 +339,14 @@ pub fn write(fd: i32, buf: [*]const u8, nbyte: usize) usize { |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize { | 341 | pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize { |
| 342 | const ptr_result = c.mmap(@ptrCast(*c_void, address), length, @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset); | 342 | const ptr_result = c.mmap( |
| 343 | @ptrCast(*c_void, address), | ||
| 344 | length, | ||
| 345 | @bitCast(c_int, @intCast(c_uint, prot)), | ||
| 346 | @bitCast(c_int, c_uint(flags)), | ||
| 347 | fd, | ||
| 348 | offset, | ||
| 349 | ); | ||
| 343 | const isize_result = @bitCast(isize, @ptrToInt(ptr_result)); | 350 | const isize_result = @bitCast(isize, @ptrToInt(ptr_result)); |
| 344 | return errnoWrap(isize_result); | 351 | return errnoWrap(isize_result); |
| 345 | } | 352 | } |
std/os/file.zig+13-15| ... | @@ -265,17 +265,8 @@ pub const File = struct { | ... | @@ -265,17 +265,8 @@ pub const File = struct { |
| 265 | 265 | ||
| 266 | pub fn getEndPos(self: *File) !usize { | 266 | pub fn getEndPos(self: *File) !usize { |
| 267 | if (is_posix) { | 267 | if (is_posix) { |
| 268 | var stat: posix.Stat = undefined; | 268 | const stat = try os.posixFStat(self.handle); |
| 269 | const err = posix.getErrno(posix.fstat(self.handle, &stat)); | 269 | return @intCast(usize, stat.size); |
| 270 | if (err > 0) { | ||
| 271 | return switch (err) { | ||
| 272 | posix.EBADF => error.BadFd, | ||
| 273 | posix.ENOMEM => error.SystemResources, | ||
| 274 | else => os.unexpectedErrorPosix(err), | ||
| 275 | }; | ||
| 276 | } | ||
| 277 | |||
| 278 | return usize(stat.size); | ||
| 279 | } else if (is_windows) { | 270 | } else if (is_windows) { |
| 280 | var file_size: windows.LARGE_INTEGER = undefined; | 271 | var file_size: windows.LARGE_INTEGER = undefined; |
| 281 | if (windows.GetFileSizeEx(self.handle, &file_size) == 0) { | 272 | if (windows.GetFileSizeEx(self.handle, &file_size) == 0) { |
| ... | @@ -286,7 +277,7 @@ pub const File = struct { | ... | @@ -286,7 +277,7 @@ pub const File = struct { |
| 286 | } | 277 | } |
| 287 | if (file_size < 0) | 278 | if (file_size < 0) |
| 288 | return error.Overflow; | 279 | return error.Overflow; |
| 289 | return math.cast(usize, u64(file_size)); | 280 | return math.cast(usize, @intCast(u64, file_size)); |
| 290 | } else { | 281 | } else { |
| 291 | @compileError("TODO support getEndPos on this OS"); | 282 | @compileError("TODO support getEndPos on this OS"); |
| 292 | } | 283 | } |
| ... | @@ -320,9 +311,15 @@ pub const File = struct { | ... | @@ -320,9 +311,15 @@ pub const File = struct { |
| 320 | } | 311 | } |
| 321 | } | 312 | } |
| 322 | 313 | ||
| 323 | pub const ReadError = error{}; | 314 | pub const ReadError = error{ |
| 315 | BadFd, | ||
| 316 | Io, | ||
| 317 | IsDir, | ||
| 318 | |||
| 319 | Unexpected, | ||
| 320 | }; | ||
| 324 | 321 | ||
| 325 | pub fn read(self: *File, buffer: []u8) !usize { | 322 | pub fn read(self: *File, buffer: []u8) ReadError!usize { |
| 326 | if (is_posix) { | 323 | if (is_posix) { |
| 327 | var index: usize = 0; | 324 | var index: usize = 0; |
| 328 | while (index < buffer.len) { | 325 | while (index < buffer.len) { |
| ... | @@ -335,6 +332,7 @@ pub const File = struct { | ... | @@ -335,6 +332,7 @@ pub const File = struct { |
| 335 | posix.EFAULT => unreachable, | 332 | posix.EFAULT => unreachable, |
| 336 | posix.EBADF => return error.BadFd, | 333 | posix.EBADF => return error.BadFd, |
| 337 | posix.EIO => return error.Io, | 334 | posix.EIO => return error.Io, |
| 335 | posix.EISDIR => return error.IsDir, | ||
| 338 | else => return os.unexpectedErrorPosix(read_err), | 336 | else => return os.unexpectedErrorPosix(read_err), |
| 339 | } | 337 | } |
| 340 | } | 338 | } |
| ... | @@ -345,7 +343,7 @@ pub const File = struct { | ... | @@ -345,7 +343,7 @@ pub const File = struct { |
| 345 | } else if (is_windows) { | 343 | } else if (is_windows) { |
| 346 | var index: usize = 0; | 344 | var index: usize = 0; |
| 347 | while (index < buffer.len) { | 345 | while (index < buffer.len) { |
| 348 | const want_read_count = windows.DWORD(math.min(windows.DWORD(@maxValue(windows.DWORD)), buffer.len - index)); | 346 | const want_read_count = @intCast(windows.DWORD, math.min(windows.DWORD(@maxValue(windows.DWORD)), buffer.len - index)); |
| 349 | var amt_read: windows.DWORD = undefined; | 347 | var amt_read: windows.DWORD = undefined; |
| 350 | if (windows.ReadFile(self.handle, @ptrCast(*c_void, buffer.ptr + index), want_read_count, &amt_read, null) == 0) { | 348 | if (windows.ReadFile(self.handle, @ptrCast(*c_void, buffer.ptr + index), want_read_count, &amt_read, null) == 0) { |
| 351 | const err = windows.GetLastError(); | 349 | const err = windows.GetLastError(); |
std/os/index.zig+22-8| ... | @@ -126,7 +126,7 @@ pub fn getRandomBytes(buf: []u8) !void { | ... | @@ -126,7 +126,7 @@ pub fn getRandomBytes(buf: []u8) !void { |
| 126 | } | 126 | } |
| 127 | defer _ = windows.CryptReleaseContext(hCryptProv, 0); | 127 | defer _ = windows.CryptReleaseContext(hCryptProv, 0); |
| 128 | 128 | ||
| 129 | if (windows.CryptGenRandom(hCryptProv, windows.DWORD(buf.len), buf.ptr) == 0) { | 129 | if (windows.CryptGenRandom(hCryptProv, @intCast(windows.DWORD, buf.len), buf.ptr) == 0) { |
| 130 | const err = windows.GetLastError(); | 130 | const err = windows.GetLastError(); |
| 131 | return switch (err) { | 131 | return switch (err) { |
| 132 | else => unexpectedErrorWindows(err), | 132 | else => unexpectedErrorWindows(err), |
| ... | @@ -343,7 +343,7 @@ pub fn posixOpenC(file_path: [*]const u8, flags: u32, perm: usize) !i32 { | ... | @@ -343,7 +343,7 @@ pub fn posixOpenC(file_path: [*]const u8, flags: u32, perm: usize) !i32 { |
| 343 | else => return unexpectedErrorPosix(err), | 343 | else => return unexpectedErrorPosix(err), |
| 344 | } | 344 | } |
| 345 | } | 345 | } |
| 346 | return i32(result); | 346 | return @intCast(i32, result); |
| 347 | } | 347 | } |
| 348 | } | 348 | } |
| 349 | 349 | ||
| ... | @@ -586,7 +586,7 @@ pub fn getCwd(allocator: *Allocator) ![]u8 { | ... | @@ -586,7 +586,7 @@ pub fn getCwd(allocator: *Allocator) ![]u8 { |
| 586 | errdefer allocator.free(buf); | 586 | errdefer allocator.free(buf); |
| 587 | 587 | ||
| 588 | while (true) { | 588 | while (true) { |
| 589 | const result = windows.GetCurrentDirectoryA(windows.WORD(buf.len), buf.ptr); | 589 | const result = windows.GetCurrentDirectoryA(@intCast(windows.WORD, buf.len), buf.ptr); |
| 590 | 590 | ||
| 591 | if (result == 0) { | 591 | if (result == 0) { |
| 592 | const err = windows.GetLastError(); | 592 | const err = windows.GetLastError(); |
| ... | @@ -2019,7 +2019,7 @@ pub fn posixSocket(domain: u32, socket_type: u32, protocol: u32) !i32 { | ... | @@ -2019,7 +2019,7 @@ pub fn posixSocket(domain: u32, socket_type: u32, protocol: u32) !i32 { |
| 2019 | const rc = posix.socket(domain, socket_type, protocol); | 2019 | const rc = posix.socket(domain, socket_type, protocol); |
| 2020 | const err = posix.getErrno(rc); | 2020 | const err = posix.getErrno(rc); |
| 2021 | switch (err) { | 2021 | switch (err) { |
| 2022 | 0 => return i32(rc), | 2022 | 0 => return @intCast(i32, rc), |
| 2023 | posix.EACCES => return PosixSocketError.PermissionDenied, | 2023 | posix.EACCES => return PosixSocketError.PermissionDenied, |
| 2024 | posix.EAFNOSUPPORT => return PosixSocketError.AddressFamilyNotSupported, | 2024 | posix.EAFNOSUPPORT => return PosixSocketError.AddressFamilyNotSupported, |
| 2025 | posix.EINVAL => return PosixSocketError.ProtocolFamilyNotAvailable, | 2025 | posix.EINVAL => return PosixSocketError.ProtocolFamilyNotAvailable, |
| ... | @@ -2183,7 +2183,7 @@ pub fn posixAccept(fd: i32, addr: *posix.sockaddr, flags: u32) PosixAcceptError! | ... | @@ -2183,7 +2183,7 @@ pub fn posixAccept(fd: i32, addr: *posix.sockaddr, flags: u32) PosixAcceptError! |
| 2183 | const rc = posix.accept4(fd, addr, &sockaddr_size, flags); | 2183 | const rc = posix.accept4(fd, addr, &sockaddr_size, flags); |
| 2184 | const err = posix.getErrno(rc); | 2184 | const err = posix.getErrno(rc); |
| 2185 | switch (err) { | 2185 | switch (err) { |
| 2186 | 0 => return i32(rc), | 2186 | 0 => return @intCast(i32, rc), |
| 2187 | posix.EINTR => continue, | 2187 | posix.EINTR => continue, |
| 2188 | else => return unexpectedErrorPosix(err), | 2188 | else => return unexpectedErrorPosix(err), |
| 2189 | 2189 | ||
| ... | @@ -2226,7 +2226,7 @@ pub fn linuxEpollCreate(flags: u32) LinuxEpollCreateError!i32 { | ... | @@ -2226,7 +2226,7 @@ pub fn linuxEpollCreate(flags: u32) LinuxEpollCreateError!i32 { |
| 2226 | const rc = posix.epoll_create1(flags); | 2226 | const rc = posix.epoll_create1(flags); |
| 2227 | const err = posix.getErrno(rc); | 2227 | const err = posix.getErrno(rc); |
| 2228 | switch (err) { | 2228 | switch (err) { |
| 2229 | 0 => return i32(rc), | 2229 | 0 => return @intCast(i32, rc), |
| 2230 | else => return unexpectedErrorPosix(err), | 2230 | else => return unexpectedErrorPosix(err), |
| 2231 | 2231 | ||
| 2232 | posix.EINVAL => return LinuxEpollCreateError.InvalidSyscall, | 2232 | posix.EINVAL => return LinuxEpollCreateError.InvalidSyscall, |
| ... | @@ -2296,7 +2296,7 @@ pub fn linuxEpollCtl(epfd: i32, op: u32, fd: i32, event: *linux.epoll_event) Lin | ... | @@ -2296,7 +2296,7 @@ pub fn linuxEpollCtl(epfd: i32, op: u32, fd: i32, event: *linux.epoll_event) Lin |
| 2296 | 2296 | ||
| 2297 | pub fn linuxEpollWait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize { | 2297 | pub fn linuxEpollWait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize { |
| 2298 | while (true) { | 2298 | while (true) { |
| 2299 | const rc = posix.epoll_wait(epfd, events.ptr, u32(events.len), timeout); | 2299 | const rc = posix.epoll_wait(epfd, events.ptr, @intCast(u32, events.len), timeout); |
| 2300 | const err = posix.getErrno(rc); | 2300 | const err = posix.getErrno(rc); |
| 2301 | switch (err) { | 2301 | switch (err) { |
| 2302 | 0 => return rc, | 2302 | 0 => return rc, |
| ... | @@ -2661,7 +2661,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread | ... | @@ -2661,7 +2661,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread |
| 2661 | posix.EAGAIN => return SpawnThreadError.SystemResources, | 2661 | posix.EAGAIN => return SpawnThreadError.SystemResources, |
| 2662 | posix.EPERM => unreachable, | 2662 | posix.EPERM => unreachable, |
| 2663 | posix.EINVAL => unreachable, | 2663 | posix.EINVAL => unreachable, |
| 2664 | else => return unexpectedErrorPosix(usize(err)), | 2664 | else => return unexpectedErrorPosix(@intCast(usize, err)), |
| 2665 | } | 2665 | } |
| 2666 | } else if (builtin.os == builtin.Os.linux) { | 2666 | } else if (builtin.os == builtin.Os.linux) { |
| 2667 | // use linux API directly. TODO use posix.CLONE_SETTLS and initialize thread local storage correctly | 2667 | // use linux API directly. TODO use posix.CLONE_SETTLS and initialize thread local storage correctly |
| ... | @@ -2697,3 +2697,17 @@ pub fn posixWait(pid: i32) i32 { | ... | @@ -2697,3 +2697,17 @@ pub fn posixWait(pid: i32) i32 { |
| 2697 | } | 2697 | } |
| 2698 | } | 2698 | } |
| 2699 | } | 2699 | } |
| 2700 | |||
| 2701 | pub fn posixFStat(fd: i32) !posix.Stat { | ||
| 2702 | var stat: posix.Stat = undefined; | ||
| 2703 | const err = posix.getErrno(posix.fstat(fd, &stat)); | ||
| 2704 | if (err > 0) { | ||
| 2705 | return switch (err) { | ||
| 2706 | posix.EBADF => error.BadFd, | ||
| 2707 | posix.ENOMEM => error.SystemResources, | ||
| 2708 | else => os.unexpectedErrorPosix(err), | ||
| 2709 | }; | ||
| 2710 | } | ||
| 2711 | |||
| 2712 | return stat; | ||
| 2713 | } |
std/os/linux/index.zig+40-40| ... | @@ -642,7 +642,7 @@ pub fn WIFEXITED(s: i32) bool { | ... | @@ -642,7 +642,7 @@ pub fn WIFEXITED(s: i32) bool { |
| 642 | return WTERMSIG(s) == 0; | 642 | return WTERMSIG(s) == 0; |
| 643 | } | 643 | } |
| 644 | pub fn WIFSTOPPED(s: i32) bool { | 644 | pub fn WIFSTOPPED(s: i32) bool { |
| 645 | return (u16)(((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00; | 645 | return @intCast(u16, ((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00; |
| 646 | } | 646 | } |
| 647 | pub fn WIFSIGNALED(s: i32) bool { | 647 | pub fn WIFSIGNALED(s: i32) bool { |
| 648 | return (unsigned(s) & 0xffff) -% 1 < 0xff; | 648 | return (unsigned(s) & 0xffff) -% 1 < 0xff; |
| ... | @@ -658,11 +658,11 @@ pub const winsize = extern struct { | ... | @@ -658,11 +658,11 @@ pub const winsize = extern struct { |
| 658 | /// Get the errno from a syscall return value, or 0 for no error. | 658 | /// Get the errno from a syscall return value, or 0 for no error. |
| 659 | pub fn getErrno(r: usize) usize { | 659 | pub fn getErrno(r: usize) usize { |
| 660 | const signed_r = @bitCast(isize, r); | 660 | const signed_r = @bitCast(isize, r); |
| 661 | return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0; | 661 | return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0; |
| 662 | } | 662 | } |
| 663 | 663 | ||
| 664 | pub fn dup2(old: i32, new: i32) usize { | 664 | pub fn dup2(old: i32, new: i32) usize { |
| 665 | return syscall2(SYS_dup2, usize(old), usize(new)); | 665 | return syscall2(SYS_dup2, @intCast(usize, old), @intCast(usize, new)); |
| 666 | } | 666 | } |
| 667 | 667 | ||
| 668 | // TODO https://github.com/ziglang/zig/issues/265 | 668 | // TODO https://github.com/ziglang/zig/issues/265 |
| ... | @@ -693,12 +693,12 @@ pub fn getcwd(buf: [*]u8, size: usize) usize { | ... | @@ -693,12 +693,12 @@ pub fn getcwd(buf: [*]u8, size: usize) usize { |
| 693 | } | 693 | } |
| 694 | 694 | ||
| 695 | pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize { | 695 | pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize { |
| 696 | return syscall3(SYS_getdents, usize(fd), @ptrToInt(dirp), count); | 696 | return syscall3(SYS_getdents, @intCast(usize, fd), @ptrToInt(dirp), count); |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | pub fn isatty(fd: i32) bool { | 699 | pub fn isatty(fd: i32) bool { |
| 700 | var wsz: winsize = undefined; | 700 | var wsz: winsize = undefined; |
| 701 | return syscall3(SYS_ioctl, usize(fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; | 701 | return syscall3(SYS_ioctl, @intCast(usize, fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; |
| 702 | } | 702 | } |
| 703 | 703 | ||
| 704 | // TODO https://github.com/ziglang/zig/issues/265 | 704 | // TODO https://github.com/ziglang/zig/issues/265 |
| ... | @@ -727,7 +727,7 @@ pub fn umount2(special: [*]const u8, flags: u32) usize { | ... | @@ -727,7 +727,7 @@ pub fn umount2(special: [*]const u8, flags: u32) usize { |
| 727 | } | 727 | } |
| 728 | 728 | ||
| 729 | pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize { | 729 | pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize { |
| 730 | return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd), @bitCast(usize, offset)); | 730 | return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @intCast(usize, fd), @bitCast(usize, offset)); |
| 731 | } | 731 | } |
| 732 | 732 | ||
| 733 | pub fn munmap(address: usize, length: usize) usize { | 733 | pub fn munmap(address: usize, length: usize) usize { |
| ... | @@ -735,7 +735,7 @@ pub fn munmap(address: usize, length: usize) usize { | ... | @@ -735,7 +735,7 @@ pub fn munmap(address: usize, length: usize) usize { |
| 735 | } | 735 | } |
| 736 | 736 | ||
| 737 | pub fn read(fd: i32, buf: [*]u8, count: usize) usize { | 737 | pub fn read(fd: i32, buf: [*]u8, count: usize) usize { |
| 738 | return syscall3(SYS_read, usize(fd), @ptrToInt(buf), count); | 738 | return syscall3(SYS_read, @intCast(usize, fd), @ptrToInt(buf), count); |
| 739 | } | 739 | } |
| 740 | 740 | ||
| 741 | // TODO https://github.com/ziglang/zig/issues/265 | 741 | // TODO https://github.com/ziglang/zig/issues/265 |
| ... | @@ -749,7 +749,7 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { | ... | @@ -749,7 +749,7 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { |
| 749 | } | 749 | } |
| 750 | 750 | ||
| 751 | pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize { | 751 | pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize { |
| 752 | return syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset); | 752 | return syscall4(SYS_pread, @intCast(usize, fd), @ptrToInt(buf), count, offset); |
| 753 | } | 753 | } |
| 754 | 754 | ||
| 755 | // TODO https://github.com/ziglang/zig/issues/265 | 755 | // TODO https://github.com/ziglang/zig/issues/265 |
| ... | @@ -766,11 +766,11 @@ pub fn pipe2(fd: *[2]i32, flags: usize) usize { | ... | @@ -766,11 +766,11 @@ pub fn pipe2(fd: *[2]i32, flags: usize) usize { |
| 766 | } | 766 | } |
| 767 | 767 | ||
| 768 | pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { | 768 | pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { |
| 769 | return syscall3(SYS_write, usize(fd), @ptrToInt(buf), count); | 769 | return syscall3(SYS_write, @intCast(usize, fd), @ptrToInt(buf), count); |
| 770 | } | 770 | } |
| 771 | 771 | ||
| 772 | pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize { | 772 | pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize { |
| 773 | return syscall4(SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset); | 773 | return syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset); |
| 774 | } | 774 | } |
| 775 | 775 | ||
| 776 | // TODO https://github.com/ziglang/zig/issues/265 | 776 | // TODO https://github.com/ziglang/zig/issues/265 |
| ... | @@ -790,7 +790,7 @@ pub fn create(path: [*]const u8, perm: usize) usize { | ... | @@ -790,7 +790,7 @@ pub fn create(path: [*]const u8, perm: usize) usize { |
| 790 | 790 | ||
| 791 | // TODO https://github.com/ziglang/zig/issues/265 | 791 | // TODO https://github.com/ziglang/zig/issues/265 |
| 792 | pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize { | 792 | pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize { |
| 793 | return syscall4(SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode); | 793 | return syscall4(SYS_openat, @intCast(usize, dirfd), @ptrToInt(path), flags, mode); |
| 794 | } | 794 | } |
| 795 | 795 | ||
| 796 | /// See also `clone` (from the arch-specific include) | 796 | /// See also `clone` (from the arch-specific include) |
| ... | @@ -804,11 +804,11 @@ pub fn clone2(flags: usize, child_stack_ptr: usize) usize { | ... | @@ -804,11 +804,11 @@ pub fn clone2(flags: usize, child_stack_ptr: usize) usize { |
| 804 | } | 804 | } |
| 805 | 805 | ||
| 806 | pub fn close(fd: i32) usize { | 806 | pub fn close(fd: i32) usize { |
| 807 | return syscall1(SYS_close, usize(fd)); | 807 | return syscall1(SYS_close, @intCast(usize, fd)); |
| 808 | } | 808 | } |
| 809 | 809 | ||
| 810 | pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize { | 810 | pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize { |
| 811 | return syscall3(SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos); | 811 | return syscall3(SYS_lseek, @intCast(usize, fd), @bitCast(usize, offset), ref_pos); |
| 812 | } | 812 | } |
| 813 | 813 | ||
| 814 | pub fn exit(status: i32) noreturn { | 814 | pub fn exit(status: i32) noreturn { |
| ... | @@ -817,11 +817,11 @@ pub fn exit(status: i32) noreturn { | ... | @@ -817,11 +817,11 @@ pub fn exit(status: i32) noreturn { |
| 817 | } | 817 | } |
| 818 | 818 | ||
| 819 | pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize { | 819 | pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize { |
| 820 | return syscall3(SYS_getrandom, @ptrToInt(buf), count, usize(flags)); | 820 | return syscall3(SYS_getrandom, @ptrToInt(buf), count, @intCast(usize, flags)); |
| 821 | } | 821 | } |
| 822 | 822 | ||
| 823 | pub fn kill(pid: i32, sig: i32) usize { | 823 | pub fn kill(pid: i32, sig: i32) usize { |
| 824 | return syscall2(SYS_kill, @bitCast(usize, isize(pid)), usize(sig)); | 824 | return syscall2(SYS_kill, @bitCast(usize, isize(pid)), @intCast(usize, sig)); |
| 825 | } | 825 | } |
| 826 | 826 | ||
| 827 | // TODO https://github.com/ziglang/zig/issues/265 | 827 | // TODO https://github.com/ziglang/zig/issues/265 |
| ... | @@ -999,8 +999,8 @@ pub const empty_sigset = []usize{0} ** sigset_t.len; | ... | @@ -999,8 +999,8 @@ pub const empty_sigset = []usize{0} ** sigset_t.len; |
| 999 | pub fn raise(sig: i32) usize { | 999 | pub fn raise(sig: i32) usize { |
| 1000 | var set: sigset_t = undefined; | 1000 | var set: sigset_t = undefined; |
| 1001 | blockAppSignals(&set); | 1001 | blockAppSignals(&set); |
| 1002 | const tid = i32(syscall0(SYS_gettid)); | 1002 | const tid = @intCast(i32, syscall0(SYS_gettid)); |
| 1003 | const ret = syscall2(SYS_tkill, usize(tid), usize(sig)); | 1003 | const ret = syscall2(SYS_tkill, @intCast(usize, tid), @intCast(usize, sig)); |
| 1004 | restoreSignals(&set); | 1004 | restoreSignals(&set); |
| 1005 | return ret; | 1005 | return ret; |
| 1006 | } | 1006 | } |
| ... | @@ -1019,12 +1019,12 @@ fn restoreSignals(set: *sigset_t) void { | ... | @@ -1019,12 +1019,12 @@ fn restoreSignals(set: *sigset_t) void { |
| 1019 | 1019 | ||
| 1020 | pub fn sigaddset(set: *sigset_t, sig: u6) void { | 1020 | pub fn sigaddset(set: *sigset_t, sig: u6) void { |
| 1021 | const s = sig - 1; | 1021 | const s = sig - 1; |
| 1022 | (set.*)[usize(s) / usize.bit_count] |= usize(1) << (s & (usize.bit_count - 1)); | 1022 | (set.*)[@intCast(usize, s) / usize.bit_count] |= @intCast(usize, 1) << (s & (usize.bit_count - 1)); |
| 1023 | } | 1023 | } |
| 1024 | 1024 | ||
| 1025 | pub fn sigismember(set: *const sigset_t, sig: u6) bool { | 1025 | pub fn sigismember(set: *const sigset_t, sig: u6) bool { |
| 1026 | const s = sig - 1; | 1026 | const s = sig - 1; |
| 1027 | return ((set.*)[usize(s) / usize.bit_count] & (usize(1) << (s & (usize.bit_count - 1)))) != 0; | 1027 | return ((set.*)[@intCast(usize, s) / usize.bit_count] & (@intCast(usize, 1) << (s & (usize.bit_count - 1)))) != 0; |
| 1028 | } | 1028 | } |
| 1029 | 1029 | ||
| 1030 | pub const in_port_t = u16; | 1030 | pub const in_port_t = u16; |
| ... | @@ -1057,11 +1057,11 @@ pub const iovec = extern struct { | ... | @@ -1057,11 +1057,11 @@ pub const iovec = extern struct { |
| 1057 | }; | 1057 | }; |
| 1058 | 1058 | ||
| 1059 | pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { | 1059 | pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { |
| 1060 | return syscall3(SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len)); | 1060 | return syscall3(SYS_getsockname, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len)); |
| 1061 | } | 1061 | } |
| 1062 | 1062 | ||
| 1063 | pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { | 1063 | pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { |
| 1064 | return syscall3(SYS_getpeername, usize(fd), @ptrToInt(addr), @ptrToInt(len)); | 1064 | return syscall3(SYS_getpeername, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len)); |
| 1065 | } | 1065 | } |
| 1066 | 1066 | ||
| 1067 | pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize { | 1067 | pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize { |
| ... | @@ -1069,47 +1069,47 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize { | ... | @@ -1069,47 +1069,47 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize { |
| 1069 | } | 1069 | } |
| 1070 | 1070 | ||
| 1071 | pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize { | 1071 | pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize { |
| 1072 | return syscall5(SYS_setsockopt, usize(fd), level, optname, usize(optval), @ptrToInt(optlen)); | 1072 | return syscall5(SYS_setsockopt, @intCast(usize, fd), level, optname, @intCast(usize, optval), @ptrToInt(optlen)); |
| 1073 | } | 1073 | } |
| 1074 | 1074 | ||
| 1075 | pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize { | 1075 | pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize { |
| 1076 | return syscall5(SYS_getsockopt, usize(fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen)); | 1076 | return syscall5(SYS_getsockopt, @intCast(usize, fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen)); |
| 1077 | } | 1077 | } |
| 1078 | 1078 | ||
| 1079 | pub fn sendmsg(fd: i32, msg: *const msghdr, flags: u32) usize { | 1079 | pub fn sendmsg(fd: i32, msg: *const msghdr, flags: u32) usize { |
| 1080 | return syscall3(SYS_sendmsg, usize(fd), @ptrToInt(msg), flags); | 1080 | return syscall3(SYS_sendmsg, @intCast(usize, fd), @ptrToInt(msg), flags); |
| 1081 | } | 1081 | } |
| 1082 | 1082 | ||
| 1083 | pub fn connect(fd: i32, addr: *const sockaddr, len: socklen_t) usize { | 1083 | pub fn connect(fd: i32, addr: *const sockaddr, len: socklen_t) usize { |
| 1084 | return syscall3(SYS_connect, usize(fd), @ptrToInt(addr), usize(len)); | 1084 | return syscall3(SYS_connect, @intCast(usize, fd), @ptrToInt(addr), @intCast(usize, len)); |
| 1085 | } | 1085 | } |
| 1086 | 1086 | ||
| 1087 | pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize { | 1087 | pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize { |
| 1088 | return syscall3(SYS_recvmsg, usize(fd), @ptrToInt(msg), flags); | 1088 | return syscall3(SYS_recvmsg, @intCast(usize, fd), @ptrToInt(msg), flags); |
| 1089 | } | 1089 | } |
| 1090 | 1090 | ||
| 1091 | pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize { | 1091 | pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize { |
| 1092 | return syscall6(SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen)); | 1092 | return syscall6(SYS_recvfrom, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen)); |
| 1093 | } | 1093 | } |
| 1094 | 1094 | ||
| 1095 | pub fn shutdown(fd: i32, how: i32) usize { | 1095 | pub fn shutdown(fd: i32, how: i32) usize { |
| 1096 | return syscall2(SYS_shutdown, usize(fd), usize(how)); | 1096 | return syscall2(SYS_shutdown, @intCast(usize, fd), @intCast(usize, how)); |
| 1097 | } | 1097 | } |
| 1098 | 1098 | ||
| 1099 | pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize { | 1099 | pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize { |
| 1100 | return syscall3(SYS_bind, usize(fd), @ptrToInt(addr), usize(len)); | 1100 | return syscall3(SYS_bind, @intCast(usize, fd), @ptrToInt(addr), @intCast(usize, len)); |
| 1101 | } | 1101 | } |
| 1102 | 1102 | ||
| 1103 | pub fn listen(fd: i32, backlog: u32) usize { | 1103 | pub fn listen(fd: i32, backlog: u32) usize { |
| 1104 | return syscall2(SYS_listen, usize(fd), backlog); | 1104 | return syscall2(SYS_listen, @intCast(usize, fd), backlog); |
| 1105 | } | 1105 | } |
| 1106 | 1106 | ||
| 1107 | pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize { | 1107 | pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize { |
| 1108 | return syscall6(SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen)); | 1108 | return syscall6(SYS_sendto, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen)); |
| 1109 | } | 1109 | } |
| 1110 | 1110 | ||
| 1111 | pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize { | 1111 | pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize { |
| 1112 | return syscall4(SYS_socketpair, usize(domain), usize(socket_type), usize(protocol), @ptrToInt(*fd[0])); | 1112 | return syscall4(SYS_socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(*fd[0])); |
| 1113 | } | 1113 | } |
| 1114 | 1114 | ||
| 1115 | pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { | 1115 | pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { |
| ... | @@ -1117,11 +1117,11 @@ pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { | ... | @@ -1117,11 +1117,11 @@ pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { |
| 1117 | } | 1117 | } |
| 1118 | 1118 | ||
| 1119 | pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize { | 1119 | pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize { |
| 1120 | return syscall4(SYS_accept4, usize(fd), @ptrToInt(addr), @ptrToInt(len), flags); | 1120 | return syscall4(SYS_accept4, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len), flags); |
| 1121 | } | 1121 | } |
| 1122 | 1122 | ||
| 1123 | pub fn fstat(fd: i32, stat_buf: *Stat) usize { | 1123 | pub fn fstat(fd: i32, stat_buf: *Stat) usize { |
| 1124 | return syscall2(SYS_fstat, usize(fd), @ptrToInt(stat_buf)); | 1124 | return syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf)); |
| 1125 | } | 1125 | } |
| 1126 | 1126 | ||
| 1127 | // TODO https://github.com/ziglang/zig/issues/265 | 1127 | // TODO https://github.com/ziglang/zig/issues/265 |
| ... | @@ -1214,15 +1214,15 @@ pub fn epoll_create1(flags: usize) usize { | ... | @@ -1214,15 +1214,15 @@ pub fn epoll_create1(flags: usize) usize { |
| 1214 | } | 1214 | } |
| 1215 | 1215 | ||
| 1216 | pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize { | 1216 | pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize { |
| 1217 | return syscall4(SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev)); | 1217 | return syscall4(SYS_epoll_ctl, @intCast(usize, epoll_fd), @intCast(usize, op), @intCast(usize, fd), @ptrToInt(ev)); |
| 1218 | } | 1218 | } |
| 1219 | 1219 | ||
| 1220 | pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize { | 1220 | pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize { |
| 1221 | return syscall4(SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout)); | 1221 | return syscall4(SYS_epoll_wait, @intCast(usize, epoll_fd), @ptrToInt(events), @intCast(usize, maxevents), @intCast(usize, timeout)); |
| 1222 | } | 1222 | } |
| 1223 | 1223 | ||
| 1224 | pub fn timerfd_create(clockid: i32, flags: u32) usize { | 1224 | pub fn timerfd_create(clockid: i32, flags: u32) usize { |
| 1225 | return syscall2(SYS_timerfd_create, usize(clockid), usize(flags)); | 1225 | return syscall2(SYS_timerfd_create, @intCast(usize, clockid), @intCast(usize, flags)); |
| 1226 | } | 1226 | } |
| 1227 | 1227 | ||
| 1228 | pub const itimerspec = extern struct { | 1228 | pub const itimerspec = extern struct { |
| ... | @@ -1231,11 +1231,11 @@ pub const itimerspec = extern struct { | ... | @@ -1231,11 +1231,11 @@ pub const itimerspec = extern struct { |
| 1231 | }; | 1231 | }; |
| 1232 | 1232 | ||
| 1233 | pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize { | 1233 | pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize { |
| 1234 | return syscall2(SYS_timerfd_gettime, usize(fd), @ptrToInt(curr_value)); | 1234 | return syscall2(SYS_timerfd_gettime, @intCast(usize, fd), @ptrToInt(curr_value)); |
| 1235 | } | 1235 | } |
| 1236 | 1236 | ||
| 1237 | pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize { | 1237 | pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize { |
| 1238 | return syscall4(SYS_timerfd_settime, usize(fd), usize(flags), @ptrToInt(new_value), @ptrToInt(old_value)); | 1238 | return syscall4(SYS_timerfd_settime, @intCast(usize, fd), @intCast(usize, flags), @ptrToInt(new_value), @ptrToInt(old_value)); |
| 1239 | } | 1239 | } |
| 1240 | 1240 | ||
| 1241 | pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330; | 1241 | pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330; |
| ... | @@ -1345,7 +1345,7 @@ pub const cap_user_data_t = extern struct { | ... | @@ -1345,7 +1345,7 @@ pub const cap_user_data_t = extern struct { |
| 1345 | }; | 1345 | }; |
| 1346 | 1346 | ||
| 1347 | pub fn unshare(flags: usize) usize { | 1347 | pub fn unshare(flags: usize) usize { |
| 1348 | return syscall1(SYS_unshare, usize(flags)); | 1348 | return syscall1(SYS_unshare, @intCast(usize, flags)); |
| 1349 | } | 1349 | } |
| 1350 | 1350 | ||
| 1351 | pub fn capget(hdrp: *cap_user_header_t, datap: *cap_user_data_t) usize { | 1351 | pub fn capget(hdrp: *cap_user_header_t, datap: *cap_user_data_t) usize { |
std/os/linux/test.zig+3-3| ... | @@ -21,7 +21,7 @@ test "timer" { | ... | @@ -21,7 +21,7 @@ test "timer" { |
| 21 | .it_value = time_interval, | 21 | .it_value = time_interval, |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | err = linux.timerfd_settime(i32(timer_fd), 0, &new_time, null); | 24 | err = linux.timerfd_settime(@intCast(i32, timer_fd), 0, &new_time, null); |
| 25 | assert(err == 0); | 25 | assert(err == 0); |
| 26 | 26 | ||
| 27 | var event = linux.epoll_event{ | 27 | var event = linux.epoll_event{ |
| ... | @@ -29,12 +29,12 @@ test "timer" { | ... | @@ -29,12 +29,12 @@ test "timer" { |
| 29 | .data = linux.epoll_data{ .ptr = 0 }, | 29 | .data = linux.epoll_data{ .ptr = 0 }, |
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | err = linux.epoll_ctl(i32(epoll_fd), linux.EPOLL_CTL_ADD, i32(timer_fd), &event); | 32 | err = linux.epoll_ctl(@intCast(i32, epoll_fd), linux.EPOLL_CTL_ADD, @intCast(i32, timer_fd), &event); |
| 33 | assert(err == 0); | 33 | assert(err == 0); |
| 34 | 34 | ||
| 35 | const events_one: linux.epoll_event = undefined; | 35 | const events_one: linux.epoll_event = undefined; |
| 36 | var events = []linux.epoll_event{events_one} ** 8; | 36 | var events = []linux.epoll_event{events_one} ** 8; |
| 37 | 37 | ||
| 38 | // TODO implicit cast from *[N]T to [*]T | 38 | // TODO implicit cast from *[N]T to [*]T |
| 39 | err = linux.epoll_wait(i32(epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1); | 39 | err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1); |
| 40 | } | 40 | } |
std/os/linux/vdso.zig+2-2| ... | @@ -62,8 +62,8 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { | ... | @@ -62,8 +62,8 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { |
| 62 | 62 | ||
| 63 | var i: usize = 0; | 63 | var i: usize = 0; |
| 64 | while (i < hashtab[1]) : (i += 1) { | 64 | while (i < hashtab[1]) : (i += 1) { |
| 65 | if (0 == (u32(1) << u5(syms[i].st_info & 0xf) & OK_TYPES)) continue; | 65 | if (0 == (u32(1) << @intCast(u5, syms[i].st_info & 0xf) & OK_TYPES)) continue; |
| 66 | if (0 == (u32(1) << u5(syms[i].st_info >> 4) & OK_BINDS)) continue; | 66 | if (0 == (u32(1) << @intCast(u5, syms[i].st_info >> 4) & OK_BINDS)) continue; |
| 67 | if (0 == syms[i].st_shndx) continue; | 67 | if (0 == syms[i].st_shndx) continue; |
| 68 | if (!mem.eql(u8, name, cstr.toSliceConst(strings + syms[i].st_name))) continue; | 68 | if (!mem.eql(u8, name, cstr.toSliceConst(strings + syms[i].st_name))) continue; |
| 69 | if (maybe_versym) |versym| { | 69 | if (maybe_versym) |versym| { |
std/os/time.zig+12-12| ... | @@ -14,12 +14,12 @@ pub const epoch = @import("epoch.zig"); | ... | @@ -14,12 +14,12 @@ pub const epoch = @import("epoch.zig"); |
| 14 | pub fn sleep(seconds: usize, nanoseconds: usize) void { | 14 | pub fn sleep(seconds: usize, nanoseconds: usize) void { |
| 15 | switch (builtin.os) { | 15 | switch (builtin.os) { |
| 16 | Os.linux, Os.macosx, Os.ios => { | 16 | Os.linux, Os.macosx, Os.ios => { |
| 17 | posixSleep(u63(seconds), u63(nanoseconds)); | 17 | posixSleep(@intCast(u63, seconds), @intCast(u63, nanoseconds)); |
| 18 | }, | 18 | }, |
| 19 | Os.windows => { | 19 | Os.windows => { |
| 20 | const ns_per_ms = ns_per_s / ms_per_s; | 20 | const ns_per_ms = ns_per_s / ms_per_s; |
| 21 | const milliseconds = seconds * ms_per_s + nanoseconds / ns_per_ms; | 21 | const milliseconds = seconds * ms_per_s + nanoseconds / ns_per_ms; |
| 22 | windows.Sleep(windows.DWORD(milliseconds)); | 22 | windows.Sleep(@intCast(windows.DWORD, milliseconds)); |
| 23 | }, | 23 | }, |
| 24 | else => @compileError("Unsupported OS"), | 24 | else => @compileError("Unsupported OS"), |
| 25 | } | 25 | } |
| ... | @@ -83,8 +83,8 @@ fn milliTimestampDarwin() u64 { | ... | @@ -83,8 +83,8 @@ fn milliTimestampDarwin() u64 { |
| 83 | var tv: darwin.timeval = undefined; | 83 | var tv: darwin.timeval = undefined; |
| 84 | var err = darwin.gettimeofday(&tv, null); | 84 | var err = darwin.gettimeofday(&tv, null); |
| 85 | debug.assert(err == 0); | 85 | debug.assert(err == 0); |
| 86 | const sec_ms = u64(tv.tv_sec) * ms_per_s; | 86 | const sec_ms = @intCast(u64, tv.tv_sec) * ms_per_s; |
| 87 | const usec_ms = @divFloor(u64(tv.tv_usec), us_per_s / ms_per_s); | 87 | const usec_ms = @divFloor(@intCast(u64, tv.tv_usec), us_per_s / ms_per_s); |
| 88 | return u64(sec_ms) + u64(usec_ms); | 88 | return u64(sec_ms) + u64(usec_ms); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| ... | @@ -95,8 +95,8 @@ fn milliTimestampPosix() u64 { | ... | @@ -95,8 +95,8 @@ fn milliTimestampPosix() u64 { |
| 95 | var ts: posix.timespec = undefined; | 95 | var ts: posix.timespec = undefined; |
| 96 | const err = posix.clock_gettime(posix.CLOCK_REALTIME, &ts); | 96 | const err = posix.clock_gettime(posix.CLOCK_REALTIME, &ts); |
| 97 | debug.assert(err == 0); | 97 | debug.assert(err == 0); |
| 98 | const sec_ms = u64(ts.tv_sec) * ms_per_s; | 98 | const sec_ms = @intCast(u64, ts.tv_sec) * ms_per_s; |
| 99 | const nsec_ms = @divFloor(u64(ts.tv_nsec), ns_per_s / ms_per_s); | 99 | const nsec_ms = @divFloor(@intCast(u64, ts.tv_nsec), ns_per_s / ms_per_s); |
| 100 | return sec_ms + nsec_ms; | 100 | return sec_ms + nsec_ms; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| ... | @@ -162,13 +162,13 @@ pub const Timer = struct { | ... | @@ -162,13 +162,13 @@ pub const Timer = struct { |
| 162 | var freq: i64 = undefined; | 162 | var freq: i64 = undefined; |
| 163 | var err = windows.QueryPerformanceFrequency(&freq); | 163 | var err = windows.QueryPerformanceFrequency(&freq); |
| 164 | if (err == windows.FALSE) return error.TimerUnsupported; | 164 | if (err == windows.FALSE) return error.TimerUnsupported; |
| 165 | self.frequency = u64(freq); | 165 | self.frequency = @intCast(u64, freq); |
| 166 | self.resolution = @divFloor(ns_per_s, self.frequency); | 166 | self.resolution = @divFloor(ns_per_s, self.frequency); |
| 167 | 167 | ||
| 168 | var start_time: i64 = undefined; | 168 | var start_time: i64 = undefined; |
| 169 | err = windows.QueryPerformanceCounter(&start_time); | 169 | err = windows.QueryPerformanceCounter(&start_time); |
| 170 | debug.assert(err != windows.FALSE); | 170 | debug.assert(err != windows.FALSE); |
| 171 | self.start_time = u64(start_time); | 171 | self.start_time = @intCast(u64, start_time); |
| 172 | }, | 172 | }, |
| 173 | Os.linux => { | 173 | Os.linux => { |
| 174 | //On Linux, seccomp can do arbitrary things to our ability to call | 174 | //On Linux, seccomp can do arbitrary things to our ability to call |
| ... | @@ -184,12 +184,12 @@ pub const Timer = struct { | ... | @@ -184,12 +184,12 @@ pub const Timer = struct { |
| 184 | posix.EINVAL => return error.TimerUnsupported, | 184 | posix.EINVAL => return error.TimerUnsupported, |
| 185 | else => return std.os.unexpectedErrorPosix(errno), | 185 | else => return std.os.unexpectedErrorPosix(errno), |
| 186 | } | 186 | } |
| 187 | self.resolution = u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec); | 187 | self.resolution = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); |
| 188 | 188 | ||
| 189 | result = posix.clock_gettime(monotonic_clock_id, &ts); | 189 | result = posix.clock_gettime(monotonic_clock_id, &ts); |
| 190 | errno = posix.getErrno(result); | 190 | errno = posix.getErrno(result); |
| 191 | if (errno != 0) return std.os.unexpectedErrorPosix(errno); | 191 | if (errno != 0) return std.os.unexpectedErrorPosix(errno); |
| 192 | self.start_time = u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec); | 192 | self.start_time = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); |
| 193 | }, | 193 | }, |
| 194 | Os.macosx, Os.ios => { | 194 | Os.macosx, Os.ios => { |
| 195 | darwin.mach_timebase_info(&self.frequency); | 195 | darwin.mach_timebase_info(&self.frequency); |
| ... | @@ -236,7 +236,7 @@ pub const Timer = struct { | ... | @@ -236,7 +236,7 @@ pub const Timer = struct { |
| 236 | var result: i64 = undefined; | 236 | var result: i64 = undefined; |
| 237 | var err = windows.QueryPerformanceCounter(&result); | 237 | var err = windows.QueryPerformanceCounter(&result); |
| 238 | debug.assert(err != windows.FALSE); | 238 | debug.assert(err != windows.FALSE); |
| 239 | return u64(result); | 239 | return @intCast(u64, result); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | fn clockDarwin() u64 { | 242 | fn clockDarwin() u64 { |
| ... | @@ -247,7 +247,7 @@ pub const Timer = struct { | ... | @@ -247,7 +247,7 @@ pub const Timer = struct { |
| 247 | var ts: posix.timespec = undefined; | 247 | var ts: posix.timespec = undefined; |
| 248 | var result = posix.clock_gettime(monotonic_clock_id, &ts); | 248 | var result = posix.clock_gettime(monotonic_clock_id, &ts); |
| 249 | debug.assert(posix.getErrno(result) == 0); | 249 | debug.assert(posix.getErrno(result) == 0); |
| 250 | return u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec); | 250 | return @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); |
| 251 | } | 251 | } |
| 252 | }; | 252 | }; |
| 253 | 253 |
std/os/windows/util.zig+7-2| ... | @@ -42,7 +42,7 @@ pub const WriteError = error{ | ... | @@ -42,7 +42,7 @@ pub const WriteError = error{ |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) WriteError!void { | 44 | pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) WriteError!void { |
| 45 | if (windows.WriteFile(handle, @ptrCast(*const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) { | 45 | if (windows.WriteFile(handle, @ptrCast(*const c_void, bytes.ptr), @intCast(u32, bytes.len), null, null) == 0) { |
| 46 | const err = windows.GetLastError(); | 46 | const err = windows.GetLastError(); |
| 47 | return switch (err) { | 47 | return switch (err) { |
| 48 | windows.ERROR.INVALID_USER_BUFFER => WriteError.SystemResources, | 48 | windows.ERROR.INVALID_USER_BUFFER => WriteError.SystemResources, |
| ... | @@ -68,7 +68,12 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool { | ... | @@ -68,7 +68,12 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool { |
| 68 | const size = @sizeOf(windows.FILE_NAME_INFO); | 68 | const size = @sizeOf(windows.FILE_NAME_INFO); |
| 69 | var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH); | 69 | var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH); |
| 70 | 70 | ||
| 71 | if (windows.GetFileInformationByHandleEx(handle, windows.FileNameInfo, @ptrCast(*c_void, &name_info_bytes[0]), u32(name_info_bytes.len)) == 0) { | 71 | if (windows.GetFileInformationByHandleEx( |
| 72 | handle, | ||
| 73 | windows.FileNameInfo, | ||
| 74 | @ptrCast(*c_void, &name_info_bytes[0]), | ||
| 75 | @intCast(u32, name_info_bytes.len), | ||
| 76 | ) == 0) { | ||
| 72 | return true; | 77 | return true; |
| 73 | } | 78 | } |
| 74 | 79 |
std/rand/index.zig+8-8| ... | @@ -55,16 +55,16 @@ pub const Random = struct { | ... | @@ -55,16 +55,16 @@ pub const Random = struct { |
| 55 | if (T.is_signed) { | 55 | if (T.is_signed) { |
| 56 | const uint = @IntType(false, T.bit_count); | 56 | const uint = @IntType(false, T.bit_count); |
| 57 | if (start >= 0 and end >= 0) { | 57 | if (start >= 0 and end >= 0) { |
| 58 | return T(r.range(uint, uint(start), uint(end))); | 58 | return @intCast(T, r.range(uint, @intCast(uint, start), @intCast(uint, end))); |
| 59 | } else if (start < 0 and end < 0) { | 59 | } else if (start < 0 and end < 0) { |
| 60 | // Can't overflow because the range is over signed ints | 60 | // Can't overflow because the range is over signed ints |
| 61 | return math.negateCast(r.range(uint, math.absCast(end), math.absCast(start)) + 1) catch unreachable; | 61 | return math.negateCast(r.range(uint, math.absCast(end), math.absCast(start)) + 1) catch unreachable; |
| 62 | } else if (start < 0 and end >= 0) { | 62 | } else if (start < 0 and end >= 0) { |
| 63 | const end_uint = uint(end); | 63 | const end_uint = @intCast(uint, end); |
| 64 | const total_range = math.absCast(start) + end_uint; | 64 | const total_range = math.absCast(start) + end_uint; |
| 65 | const value = r.range(uint, 0, total_range); | 65 | const value = r.range(uint, 0, total_range); |
| 66 | const result = if (value < end_uint) x: { | 66 | const result = if (value < end_uint) x: { |
| 67 | break :x T(value); | 67 | break :x @intCast(T, value); |
| 68 | } else if (value == end_uint) x: { | 68 | } else if (value == end_uint) x: { |
| 69 | break :x start; | 69 | break :x start; |
| 70 | } else x: { | 70 | } else x: { |
| ... | @@ -213,9 +213,9 @@ pub const Pcg = struct { | ... | @@ -213,9 +213,9 @@ pub const Pcg = struct { |
| 213 | self.s = l *% default_multiplier +% (self.i | 1); | 213 | self.s = l *% default_multiplier +% (self.i | 1); |
| 214 | 214 | ||
| 215 | const xor_s = @truncate(u32, ((l >> 18) ^ l) >> 27); | 215 | const xor_s = @truncate(u32, ((l >> 18) ^ l) >> 27); |
| 216 | const rot = u32(l >> 59); | 216 | const rot = @intCast(u32, l >> 59); |
| 217 | 217 | ||
| 218 | return (xor_s >> u5(rot)) | (xor_s << u5((0 -% rot) & 31)); | 218 | return (xor_s >> @intCast(u5, rot)) | (xor_s << @intCast(u5, (0 -% rot) & 31)); |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | fn seed(self: *Pcg, init_s: u64) void { | 221 | fn seed(self: *Pcg, init_s: u64) void { |
| ... | @@ -322,7 +322,7 @@ pub const Xoroshiro128 = struct { | ... | @@ -322,7 +322,7 @@ pub const Xoroshiro128 = struct { |
| 322 | inline for (table) |entry| { | 322 | inline for (table) |entry| { |
| 323 | var b: usize = 0; | 323 | var b: usize = 0; |
| 324 | while (b < 64) : (b += 1) { | 324 | while (b < 64) : (b += 1) { |
| 325 | if ((entry & (u64(1) << u6(b))) != 0) { | 325 | if ((entry & (u64(1) << @intCast(u6, b))) != 0) { |
| 326 | s0 ^= self.s[0]; | 326 | s0 ^= self.s[0]; |
| 327 | s1 ^= self.s[1]; | 327 | s1 ^= self.s[1]; |
| 328 | } | 328 | } |
| ... | @@ -667,13 +667,13 @@ test "Random range" { | ... | @@ -667,13 +667,13 @@ test "Random range" { |
| 667 | } | 667 | } |
| 668 | 668 | ||
| 669 | fn testRange(r: *Random, start: i32, end: i32) void { | 669 | fn testRange(r: *Random, start: i32, end: i32) void { |
| 670 | const count = usize(end - start); | 670 | const count = @intCast(usize, end - start); |
| 671 | var values_buffer = []bool{false} ** 20; | 671 | var values_buffer = []bool{false} ** 20; |
| 672 | const values = values_buffer[0..count]; | 672 | const values = values_buffer[0..count]; |
| 673 | var i: usize = 0; | 673 | var i: usize = 0; |
| 674 | while (i < count) { | 674 | while (i < count) { |
| 675 | const value = r.range(i32, start, end); | 675 | const value = r.range(i32, start, end); |
| 676 | const index = usize(value - start); | 676 | const index = @intCast(usize, value - start); |
| 677 | if (!values[index]) { | 677 | if (!values[index]) { |
| 678 | i += 1; | 678 | i += 1; |
| 679 | values[index] = true; | 679 | values[index] = true; |
std/segmented_list.zig+6-6| ... | @@ -104,7 +104,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type | ... | @@ -104,7 +104,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | pub fn deinit(self: *Self) void { | 106 | pub fn deinit(self: *Self) void { |
| 107 | self.freeShelves(ShelfIndex(self.dynamic_segments.len), 0); | 107 | self.freeShelves(@intCast(ShelfIndex, self.dynamic_segments.len), 0); |
| 108 | self.allocator.free(self.dynamic_segments); | 108 | self.allocator.free(self.dynamic_segments); |
| 109 | self.* = undefined; | 109 | self.* = undefined; |
| 110 | } | 110 | } |
| ... | @@ -158,7 +158,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type | ... | @@ -158,7 +158,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 158 | /// Only grows capacity, or retains current capacity | 158 | /// Only grows capacity, or retains current capacity |
| 159 | pub fn growCapacity(self: *Self, new_capacity: usize) !void { | 159 | pub fn growCapacity(self: *Self, new_capacity: usize) !void { |
| 160 | const new_cap_shelf_count = shelfCount(new_capacity); | 160 | const new_cap_shelf_count = shelfCount(new_capacity); |
| 161 | const old_shelf_count = ShelfIndex(self.dynamic_segments.len); | 161 | const old_shelf_count = @intCast(ShelfIndex, self.dynamic_segments.len); |
| 162 | if (new_cap_shelf_count > old_shelf_count) { | 162 | if (new_cap_shelf_count > old_shelf_count) { |
| 163 | self.dynamic_segments = try self.allocator.realloc([*]T, self.dynamic_segments, new_cap_shelf_count); | 163 | self.dynamic_segments = try self.allocator.realloc([*]T, self.dynamic_segments, new_cap_shelf_count); |
| 164 | var i = old_shelf_count; | 164 | var i = old_shelf_count; |
| ... | @@ -175,7 +175,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type | ... | @@ -175,7 +175,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 175 | /// Only shrinks capacity or retains current capacity | 175 | /// Only shrinks capacity or retains current capacity |
| 176 | pub fn shrinkCapacity(self: *Self, new_capacity: usize) void { | 176 | pub fn shrinkCapacity(self: *Self, new_capacity: usize) void { |
| 177 | if (new_capacity <= prealloc_item_count) { | 177 | if (new_capacity <= prealloc_item_count) { |
| 178 | const len = ShelfIndex(self.dynamic_segments.len); | 178 | const len = @intCast(ShelfIndex, self.dynamic_segments.len); |
| 179 | self.freeShelves(len, 0); | 179 | self.freeShelves(len, 0); |
| 180 | self.allocator.free(self.dynamic_segments); | 180 | self.allocator.free(self.dynamic_segments); |
| 181 | self.dynamic_segments = [][*]T{}; | 181 | self.dynamic_segments = [][*]T{}; |
| ... | @@ -183,7 +183,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type | ... | @@ -183,7 +183,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | const new_cap_shelf_count = shelfCount(new_capacity); | 185 | const new_cap_shelf_count = shelfCount(new_capacity); |
| 186 | const old_shelf_count = ShelfIndex(self.dynamic_segments.len); | 186 | const old_shelf_count = @intCast(ShelfIndex, self.dynamic_segments.len); |
| 187 | assert(new_cap_shelf_count <= old_shelf_count); | 187 | assert(new_cap_shelf_count <= old_shelf_count); |
| 188 | if (new_cap_shelf_count == old_shelf_count) { | 188 | if (new_cap_shelf_count == old_shelf_count) { |
| 189 | return; | 189 | return; |
| ... | @@ -338,7 +338,7 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { | ... | @@ -338,7 +338,7 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { |
| 338 | { | 338 | { |
| 339 | var i: usize = 0; | 339 | var i: usize = 0; |
| 340 | while (i < 100) : (i += 1) { | 340 | while (i < 100) : (i += 1) { |
| 341 | try list.push(i32(i + 1)); | 341 | try list.push(@intCast(i32, i + 1)); |
| 342 | assert(list.len == i + 1); | 342 | assert(list.len == i + 1); |
| 343 | } | 343 | } |
| 344 | } | 344 | } |
| ... | @@ -346,7 +346,7 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { | ... | @@ -346,7 +346,7 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { |
| 346 | { | 346 | { |
| 347 | var i: usize = 0; | 347 | var i: usize = 0; |
| 348 | while (i < 100) : (i += 1) { | 348 | while (i < 100) : (i += 1) { |
| 349 | assert(list.at(i).* == i32(i + 1)); | 349 | assert(list.at(i).* == @intCast(i32, i + 1)); |
| 350 | } | 350 | } |
| 351 | } | 351 | } |
| 352 | 352 |
std/special/bootstrap.zig+1-1| ... | @@ -80,7 +80,7 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 { | ... | @@ -80,7 +80,7 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 { |
| 80 | var env_count: usize = 0; | 80 | var env_count: usize = 0; |
| 81 | while (c_envp[env_count] != null) : (env_count += 1) {} | 81 | while (c_envp[env_count] != null) : (env_count += 1) {} |
| 82 | const envp = @ptrCast([*][*]u8, c_envp)[0..env_count]; | 82 | const envp = @ptrCast([*][*]u8, c_envp)[0..env_count]; |
| 83 | return callMainWithArgs(usize(c_argc), c_argv, envp); | 83 | return callMainWithArgs(@intCast(usize, c_argc), c_argv, envp); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | fn callMain() u8 { | 86 | fn callMain() u8 { |
std/special/builtin.zig+15-15| ... | @@ -135,9 +135,9 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { | ... | @@ -135,9 +135,9 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 135 | const mask = if (T == f32) 0xff else 0x7ff; | 135 | const mask = if (T == f32) 0xff else 0x7ff; |
| 136 | var ux = @bitCast(uint, x); | 136 | var ux = @bitCast(uint, x); |
| 137 | var uy = @bitCast(uint, y); | 137 | var uy = @bitCast(uint, y); |
| 138 | var ex = i32((ux >> digits) & mask); | 138 | var ex = @intCast(i32, (ux >> digits) & mask); |
| 139 | var ey = i32((uy >> digits) & mask); | 139 | var ey = @intCast(i32, (uy >> digits) & mask); |
| 140 | const sx = if (T == f32) u32(ux & 0x80000000) else i32(ux >> bits_minus_1); | 140 | const sx = if (T == f32) @intCast(u32, ux & 0x80000000) else @intCast(i32, ux >> bits_minus_1); |
| 141 | var i: uint = undefined; | 141 | var i: uint = undefined; |
| 142 | 142 | ||
| 143 | if (uy << 1 == 0 or isNan(uint, uy) or ex == mask) | 143 | if (uy << 1 == 0 or isNan(uint, uy) or ex == mask) |
| ... | @@ -156,7 +156,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { | ... | @@ -156,7 +156,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 156 | ex -= 1; | 156 | ex -= 1; |
| 157 | i <<= 1; | 157 | i <<= 1; |
| 158 | }) {} | 158 | }) {} |
| 159 | ux <<= log2uint(@bitCast(u32, -ex + 1)); | 159 | ux <<= @intCast(log2uint, @bitCast(u32, -ex + 1)); |
| 160 | } else { | 160 | } else { |
| 161 | ux &= @maxValue(uint) >> exp_bits; | 161 | ux &= @maxValue(uint) >> exp_bits; |
| 162 | ux |= 1 << digits; | 162 | ux |= 1 << digits; |
| ... | @@ -167,7 +167,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { | ... | @@ -167,7 +167,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 167 | ey -= 1; | 167 | ey -= 1; |
| 168 | i <<= 1; | 168 | i <<= 1; |
| 169 | }) {} | 169 | }) {} |
| 170 | uy <<= log2uint(@bitCast(u32, -ey + 1)); | 170 | uy <<= @intCast(log2uint, @bitCast(u32, -ey + 1)); |
| 171 | } else { | 171 | } else { |
| 172 | uy &= @maxValue(uint) >> exp_bits; | 172 | uy &= @maxValue(uint) >> exp_bits; |
| 173 | uy |= 1 << digits; | 173 | uy |= 1 << digits; |
| ... | @@ -199,12 +199,12 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { | ... | @@ -199,12 +199,12 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 199 | ux -%= 1 << digits; | 199 | ux -%= 1 << digits; |
| 200 | ux |= uint(@bitCast(u32, ex)) << digits; | 200 | ux |= uint(@bitCast(u32, ex)) << digits; |
| 201 | } else { | 201 | } else { |
| 202 | ux >>= log2uint(@bitCast(u32, -ex + 1)); | 202 | ux >>= @intCast(log2uint, @bitCast(u32, -ex + 1)); |
| 203 | } | 203 | } |
| 204 | if (T == f32) { | 204 | if (T == f32) { |
| 205 | ux |= sx; | 205 | ux |= sx; |
| 206 | } else { | 206 | } else { |
| 207 | ux |= uint(sx) << bits_minus_1; | 207 | ux |= @intCast(uint, sx) << bits_minus_1; |
| 208 | } | 208 | } |
| 209 | return @bitCast(T, ux); | 209 | return @bitCast(T, ux); |
| 210 | } | 210 | } |
| ... | @@ -229,8 +229,8 @@ export fn sqrt(x: f64) f64 { | ... | @@ -229,8 +229,8 @@ export fn sqrt(x: f64) f64 { |
| 229 | const sign: u32 = 0x80000000; | 229 | const sign: u32 = 0x80000000; |
| 230 | const u = @bitCast(u64, x); | 230 | const u = @bitCast(u64, x); |
| 231 | 231 | ||
| 232 | var ix0 = u32(u >> 32); | 232 | var ix0 = @intCast(u32, u >> 32); |
| 233 | var ix1 = u32(u & 0xFFFFFFFF); | 233 | var ix1 = @intCast(u32, u & 0xFFFFFFFF); |
| 234 | 234 | ||
| 235 | // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = nan | 235 | // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = nan |
| 236 | if (ix0 & 0x7FF00000 == 0x7FF00000) { | 236 | if (ix0 & 0x7FF00000 == 0x7FF00000) { |
| ... | @@ -247,7 +247,7 @@ export fn sqrt(x: f64) f64 { | ... | @@ -247,7 +247,7 @@ export fn sqrt(x: f64) f64 { |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | // normalize x | 249 | // normalize x |
| 250 | var m = i32(ix0 >> 20); | 250 | var m = @intCast(i32, ix0 >> 20); |
| 251 | if (m == 0) { | 251 | if (m == 0) { |
| 252 | // subnormal | 252 | // subnormal |
| 253 | while (ix0 == 0) { | 253 | while (ix0 == 0) { |
| ... | @@ -261,9 +261,9 @@ export fn sqrt(x: f64) f64 { | ... | @@ -261,9 +261,9 @@ export fn sqrt(x: f64) f64 { |
| 261 | while (ix0 & 0x00100000 == 0) : (i += 1) { | 261 | while (ix0 & 0x00100000 == 0) : (i += 1) { |
| 262 | ix0 <<= 1; | 262 | ix0 <<= 1; |
| 263 | } | 263 | } |
| 264 | m -= i32(i) - 1; | 264 | m -= @intCast(i32, i) - 1; |
| 265 | ix0 |= ix1 >> u5(32 - i); | 265 | ix0 |= ix1 >> @intCast(u5, 32 - i); |
| 266 | ix1 <<= u5(i); | 266 | ix1 <<= @intCast(u5, i); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | // unbias exponent | 269 | // unbias exponent |
| ... | @@ -347,10 +347,10 @@ export fn sqrt(x: f64) f64 { | ... | @@ -347,10 +347,10 @@ export fn sqrt(x: f64) f64 { |
| 347 | 347 | ||
| 348 | // NOTE: musl here appears to rely on signed twos-complement wraparound. +% has the same | 348 | // NOTE: musl here appears to rely on signed twos-complement wraparound. +% has the same |
| 349 | // behaviour at least. | 349 | // behaviour at least. |
| 350 | var iix0 = i32(ix0); | 350 | var iix0 = @intCast(i32, ix0); |
| 351 | iix0 = iix0 +% (m << 20); | 351 | iix0 = iix0 +% (m << 20); |
| 352 | 352 | ||
| 353 | const uz = (u64(iix0) << 32) | ix1; | 353 | const uz = (@intCast(u64, iix0) << 32) | ix1; |
| 354 | return @bitCast(f64, uz); | 354 | return @bitCast(f64, uz); |
| 355 | } | 355 | } |
| 356 | 356 |
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 | } |
std/special/compiler_rt/divti3.zig+1-1| ... | @@ -13,7 +13,7 @@ pub extern fn __divti3(a: i128, b: i128) i128 { | ... | @@ -13,7 +13,7 @@ pub extern fn __divti3(a: i128, b: i128) i128 { |
| 13 | 13 | ||
| 14 | const r = udivmod(u128, @bitCast(u128, an), @bitCast(u128, bn), null); | 14 | const r = udivmod(u128, @bitCast(u128, an), @bitCast(u128, bn), null); |
| 15 | const s = s_a ^ s_b; | 15 | const s = s_a ^ s_b; |
| 16 | return (i128(r) ^ s) -% s; | 16 | return (@bitCast(i128, r) ^ s) -% s; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | pub extern fn __divti3_windows_x86_64(a: *const i128, b: *const i128) void { | 19 | pub extern fn __divti3_windows_x86_64(a: *const i128, b: *const i128) void { |
std/special/compiler_rt/fixuint.zig+4-4| ... | @@ -32,14 +32,14 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t | ... | @@ -32,14 +32,14 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t |
| 32 | const aAbs: rep_t = aRep & absMask; | 32 | const aAbs: rep_t = aRep & absMask; |
| 33 | 33 | ||
| 34 | const sign = if ((aRep & signBit) != 0) i32(-1) else i32(1); | 34 | const sign = if ((aRep & signBit) != 0) i32(-1) else i32(1); |
| 35 | const exponent = i32(aAbs >> significandBits) - exponentBias; | 35 | const exponent = @intCast(i32, aAbs >> significandBits) - exponentBias; |
| 36 | const significand: rep_t = (aAbs & significandMask) | implicitBit; | 36 | const significand: rep_t = (aAbs & significandMask) | implicitBit; |
| 37 | 37 | ||
| 38 | // If either the value or the exponent is negative, the result is zero. | 38 | // If either the value or the exponent is negative, the result is zero. |
| 39 | if (sign == -1 or exponent < 0) return 0; | 39 | if (sign == -1 or exponent < 0) return 0; |
| 40 | 40 | ||
| 41 | // If the value is too large for the integer type, saturate. | 41 | // If the value is too large for the integer type, saturate. |
| 42 | if (c_uint(exponent) >= fixuint_t.bit_count) return ~fixuint_t(0); | 42 | if (@intCast(c_uint, exponent) >= fixuint_t.bit_count) return ~fixuint_t(0); |
| 43 | 43 | ||
| 44 | // If 0 <= exponent < significandBits, right shift to get the result. | 44 | // If 0 <= exponent < significandBits, right shift to get the result. |
| 45 | // Otherwise, shift left. | 45 | // Otherwise, shift left. |
| ... | @@ -47,11 +47,11 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t | ... | @@ -47,11 +47,11 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t |
| 47 | // TODO this is a workaround for the mysterious "integer cast truncated bits" | 47 | // TODO this is a workaround for the mysterious "integer cast truncated bits" |
| 48 | // happening on the next line | 48 | // happening on the next line |
| 49 | @setRuntimeSafety(false); | 49 | @setRuntimeSafety(false); |
| 50 | return fixuint_t(significand >> Log2Int(rep_t)(significandBits - exponent)); | 50 | return @intCast(fixuint_t, significand >> @intCast(Log2Int(rep_t), significandBits - exponent)); |
| 51 | } else { | 51 | } else { |
| 52 | // TODO this is a workaround for the mysterious "integer cast truncated bits" | 52 | // TODO this is a workaround for the mysterious "integer cast truncated bits" |
| 53 | // happening on the next line | 53 | // happening on the next line |
| 54 | @setRuntimeSafety(false); | 54 | @setRuntimeSafety(false); |
| 55 | return fixuint_t(significand) << Log2Int(fixuint_t)(exponent - significandBits); | 55 | return @intCast(fixuint_t, significand) << @intCast(Log2Int(fixuint_t), exponent - significandBits); |
| 56 | } | 56 | } |
| 57 | } | 57 | } |
std/special/compiler_rt/index.zig+6-6| ... | @@ -292,7 +292,7 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 { | ... | @@ -292,7 +292,7 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 { |
| 292 | @setRuntimeSafety(is_test); | 292 | @setRuntimeSafety(is_test); |
| 293 | 293 | ||
| 294 | const d = __udivsi3(a, b); | 294 | const d = __udivsi3(a, b); |
| 295 | rem.* = u32(i32(a) -% (i32(d) * i32(b))); | 295 | rem.* = @bitCast(u32, @bitCast(i32, a) -% (@bitCast(i32, d) * @bitCast(i32, b))); |
| 296 | return d; | 296 | return d; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| ... | @@ -316,12 +316,12 @@ extern fn __udivsi3(n: u32, d: u32) u32 { | ... | @@ -316,12 +316,12 @@ extern fn __udivsi3(n: u32, d: u32) u32 { |
| 316 | sr += 1; | 316 | sr += 1; |
| 317 | // 1 <= sr <= n_uword_bits - 1 | 317 | // 1 <= sr <= n_uword_bits - 1 |
| 318 | // Not a special case | 318 | // Not a special case |
| 319 | var q: u32 = n << u5(n_uword_bits - sr); | 319 | var q: u32 = n << @intCast(u5, n_uword_bits - sr); |
| 320 | var r: u32 = n >> u5(sr); | 320 | var r: u32 = n >> @intCast(u5, sr); |
| 321 | var carry: u32 = 0; | 321 | var carry: u32 = 0; |
| 322 | while (sr > 0) : (sr -= 1) { | 322 | while (sr > 0) : (sr -= 1) { |
| 323 | // r:q = ((r:q) << 1) | carry | 323 | // r:q = ((r:q) << 1) | carry |
| 324 | r = (r << 1) | (q >> u5(n_uword_bits - 1)); | 324 | r = (r << 1) | (q >> @intCast(u5, n_uword_bits - 1)); |
| 325 | q = (q << 1) | carry; | 325 | q = (q << 1) | carry; |
| 326 | // carry = 0; | 326 | // carry = 0; |
| 327 | // if (r.all >= d.all) | 327 | // if (r.all >= d.all) |
| ... | @@ -329,8 +329,8 @@ extern fn __udivsi3(n: u32, d: u32) u32 { | ... | @@ -329,8 +329,8 @@ extern fn __udivsi3(n: u32, d: u32) u32 { |
| 329 | // r.all -= d.all; | 329 | // r.all -= d.all; |
| 330 | // carry = 1; | 330 | // carry = 1; |
| 331 | // } | 331 | // } |
| 332 | const s = i32(d -% r -% 1) >> u5(n_uword_bits - 1); | 332 | const s = @intCast(i32, d -% r -% 1) >> @intCast(u5, n_uword_bits - 1); |
| 333 | carry = u32(s & 1); | 333 | carry = @intCast(u32, s & 1); |
| 334 | r -= d & @bitCast(u32, s); | 334 | r -= d & @bitCast(u32, s); |
| 335 | } | 335 | } |
| 336 | q = (q << 1) | carry; | 336 | q = (q << 1) | carry; |
std/special/compiler_rt/udivmod.zig+17-17| ... | @@ -71,7 +71,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: | ... | @@ -71,7 +71,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 71 | r[high] = n[high] & (d[high] - 1); | 71 | r[high] = n[high] & (d[high] - 1); |
| 72 | rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 | 72 | rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 |
| 73 | } | 73 | } |
| 74 | return n[high] >> Log2SingleInt(@ctz(d[high])); | 74 | return n[high] >> @intCast(Log2SingleInt, @ctz(d[high])); |
| 75 | } | 75 | } |
| 76 | // K K | 76 | // K K |
| 77 | // --- | 77 | // --- |
| ... | @@ -88,10 +88,10 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: | ... | @@ -88,10 +88,10 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 88 | // 1 <= sr <= SingleInt.bit_count - 1 | 88 | // 1 <= sr <= SingleInt.bit_count - 1 |
| 89 | // q.all = a << (DoubleInt.bit_count - sr); | 89 | // q.all = a << (DoubleInt.bit_count - sr); |
| 90 | q[low] = 0; | 90 | q[low] = 0; |
| 91 | q[high] = n[low] << Log2SingleInt(SingleInt.bit_count - sr); | 91 | q[high] = n[low] << @intCast(Log2SingleInt, SingleInt.bit_count - sr); |
| 92 | // r.all = a >> sr; | 92 | // r.all = a >> sr; |
| 93 | r[high] = n[high] >> Log2SingleInt(sr); | 93 | r[high] = n[high] >> @intCast(Log2SingleInt, sr); |
| 94 | r[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr)); | 94 | r[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); |
| 95 | } else { | 95 | } else { |
| 96 | // d[low] != 0 | 96 | // d[low] != 0 |
| 97 | if (d[high] == 0) { | 97 | if (d[high] == 0) { |
| ... | @@ -107,8 +107,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: | ... | @@ -107,8 +107,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 107 | return a; | 107 | return a; |
| 108 | } | 108 | } |
| 109 | sr = @ctz(d[low]); | 109 | sr = @ctz(d[low]); |
| 110 | q[high] = n[high] >> Log2SingleInt(sr); | 110 | q[high] = n[high] >> @intCast(Log2SingleInt, sr); |
| 111 | q[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr)); | 111 | q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); |
| 112 | return @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421 | 112 | return @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421 |
| 113 | } | 113 | } |
| 114 | // K X | 114 | // K X |
| ... | @@ -126,15 +126,15 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: | ... | @@ -126,15 +126,15 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 126 | } else if (sr < SingleInt.bit_count) { | 126 | } else if (sr < SingleInt.bit_count) { |
| 127 | // 2 <= sr <= SingleInt.bit_count - 1 | 127 | // 2 <= sr <= SingleInt.bit_count - 1 |
| 128 | q[low] = 0; | 128 | q[low] = 0; |
| 129 | q[high] = n[low] << Log2SingleInt(SingleInt.bit_count - sr); | 129 | q[high] = n[low] << @intCast(Log2SingleInt, SingleInt.bit_count - sr); |
| 130 | r[high] = n[high] >> Log2SingleInt(sr); | 130 | r[high] = n[high] >> @intCast(Log2SingleInt, sr); |
| 131 | r[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr)); | 131 | r[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); |
| 132 | } else { | 132 | } else { |
| 133 | // SingleInt.bit_count + 1 <= sr <= DoubleInt.bit_count - 1 | 133 | // SingleInt.bit_count + 1 <= sr <= DoubleInt.bit_count - 1 |
| 134 | q[low] = n[low] << Log2SingleInt(DoubleInt.bit_count - sr); | 134 | q[low] = n[low] << @intCast(Log2SingleInt, DoubleInt.bit_count - sr); |
| 135 | q[high] = (n[high] << Log2SingleInt(DoubleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr - SingleInt.bit_count)); | 135 | q[high] = (n[high] << @intCast(Log2SingleInt, DoubleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr - SingleInt.bit_count)); |
| 136 | r[high] = 0; | 136 | r[high] = 0; |
| 137 | r[low] = n[high] >> Log2SingleInt(sr - SingleInt.bit_count); | 137 | r[low] = n[high] >> @intCast(Log2SingleInt, sr - SingleInt.bit_count); |
| 138 | } | 138 | } |
| 139 | } else { | 139 | } else { |
| 140 | // K X | 140 | // K X |
| ... | @@ -158,9 +158,9 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: | ... | @@ -158,9 +158,9 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 158 | r[high] = 0; | 158 | r[high] = 0; |
| 159 | r[low] = n[high]; | 159 | r[low] = n[high]; |
| 160 | } else { | 160 | } else { |
| 161 | r[high] = n[high] >> Log2SingleInt(sr); | 161 | r[high] = n[high] >> @intCast(Log2SingleInt, sr); |
| 162 | r[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr)); | 162 | r[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); |
| 163 | q[high] = n[low] << Log2SingleInt(SingleInt.bit_count - sr); | 163 | q[high] = n[low] << @intCast(Log2SingleInt, SingleInt.bit_count - sr); |
| 164 | } | 164 | } |
| 165 | } | 165 | } |
| 166 | } | 166 | } |
| ... | @@ -184,8 +184,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: | ... | @@ -184,8 +184,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 184 | // carry = 1; | 184 | // carry = 1; |
| 185 | // } | 185 | // } |
| 186 | r_all = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 | 186 | r_all = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 |
| 187 | const s: SignedDoubleInt = SignedDoubleInt(b -% r_all -% 1) >> (DoubleInt.bit_count - 1); | 187 | const s: SignedDoubleInt = @intCast(SignedDoubleInt, b -% r_all -% 1) >> (DoubleInt.bit_count - 1); |
| 188 | carry = u32(s & 1); | 188 | carry = @intCast(u32, s & 1); |
| 189 | r_all -= b & @bitCast(DoubleInt, s); | 189 | r_all -= b & @bitCast(DoubleInt, s); |
| 190 | r = @ptrCast(*[2]SingleInt, &r_all).*; // TODO issue #421 | 190 | r = @ptrCast(*[2]SingleInt, &r_all).*; // TODO issue #421 |
| 191 | } | 191 | } |
std/unicode.zig+10-10| ... | @@ -35,22 +35,22 @@ pub fn utf8Encode(c: u32, out: []u8) !u3 { | ... | @@ -35,22 +35,22 @@ pub fn utf8Encode(c: u32, out: []u8) !u3 { |
| 35 | // - Increasing the initial shift by 6 each time | 35 | // - Increasing the initial shift by 6 each time |
| 36 | // - Each time after the first shorten the shifted | 36 | // - Each time after the first shorten the shifted |
| 37 | // value to a max of 0b111111 (63) | 37 | // value to a max of 0b111111 (63) |
| 38 | 1 => out[0] = u8(c), // Can just do 0 + codepoint for initial range | 38 | 1 => out[0] = @intCast(u8, c), // Can just do 0 + codepoint for initial range |
| 39 | 2 => { | 39 | 2 => { |
| 40 | out[0] = u8(0b11000000 | (c >> 6)); | 40 | out[0] = @intCast(u8, 0b11000000 | (c >> 6)); |
| 41 | out[1] = u8(0b10000000 | (c & 0b111111)); | 41 | out[1] = @intCast(u8, 0b10000000 | (c & 0b111111)); |
| 42 | }, | 42 | }, |
| 43 | 3 => { | 43 | 3 => { |
| 44 | if (0xd800 <= c and c <= 0xdfff) return error.Utf8CannotEncodeSurrogateHalf; | 44 | if (0xd800 <= c and c <= 0xdfff) return error.Utf8CannotEncodeSurrogateHalf; |
| 45 | out[0] = u8(0b11100000 | (c >> 12)); | 45 | out[0] = @intCast(u8, 0b11100000 | (c >> 12)); |
| 46 | out[1] = u8(0b10000000 | ((c >> 6) & 0b111111)); | 46 | out[1] = @intCast(u8, 0b10000000 | ((c >> 6) & 0b111111)); |
| 47 | out[2] = u8(0b10000000 | (c & 0b111111)); | 47 | out[2] = @intCast(u8, 0b10000000 | (c & 0b111111)); |
| 48 | }, | 48 | }, |
| 49 | 4 => { | 49 | 4 => { |
| 50 | out[0] = u8(0b11110000 | (c >> 18)); | 50 | out[0] = @intCast(u8, 0b11110000 | (c >> 18)); |
| 51 | out[1] = u8(0b10000000 | ((c >> 12) & 0b111111)); | 51 | out[1] = @intCast(u8, 0b10000000 | ((c >> 12) & 0b111111)); |
| 52 | out[2] = u8(0b10000000 | ((c >> 6) & 0b111111)); | 52 | out[2] = @intCast(u8, 0b10000000 | ((c >> 6) & 0b111111)); |
| 53 | out[3] = u8(0b10000000 | (c & 0b111111)); | 53 | out[3] = @intCast(u8, 0b10000000 | (c & 0b111111)); |
| 54 | }, | 54 | }, |
| 55 | else => unreachable, | 55 | else => unreachable, |
| 56 | } | 56 | } |
std/zig/tokenizer.zig+1-1| ... | @@ -1128,7 +1128,7 @@ pub const Tokenizer = struct { | ... | @@ -1128,7 +1128,7 @@ pub const Tokenizer = struct { |
| 1128 | // check utf8-encoded character. | 1128 | // check utf8-encoded character. |
| 1129 | const length = std.unicode.utf8ByteSequenceLength(c0) catch return 1; | 1129 | const length = std.unicode.utf8ByteSequenceLength(c0) catch return 1; |
| 1130 | if (self.index + length > self.buffer.len) { | 1130 | if (self.index + length > self.buffer.len) { |
| 1131 | return u3(self.buffer.len - self.index); | 1131 | return @intCast(u3, self.buffer.len - self.index); |
| 1132 | } | 1132 | } |
| 1133 | const bytes = self.buffer[self.index .. self.index + length]; | 1133 | const bytes = self.buffer[self.index .. self.index + length]; |
| 1134 | switch (length) { | 1134 | switch (length) { |
test/behavior.zig+1| ... | @@ -13,6 +13,7 @@ comptime { | ... | @@ -13,6 +13,7 @@ comptime { |
| 13 | _ = @import("cases/bugs/656.zig"); | 13 | _ = @import("cases/bugs/656.zig"); |
| 14 | _ = @import("cases/bugs/828.zig"); | 14 | _ = @import("cases/bugs/828.zig"); |
| 15 | _ = @import("cases/bugs/920.zig"); | 15 | _ = @import("cases/bugs/920.zig"); |
| 16 | _ = @import("cases/byval_arg_var.zig"); | ||
| 16 | _ = @import("cases/cast.zig"); | 17 | _ = @import("cases/cast.zig"); |
| 17 | _ = @import("cases/const_slice_child.zig"); | 18 | _ = @import("cases/const_slice_child.zig"); |
| 18 | _ = @import("cases/coroutines.zig"); | 19 | _ = @import("cases/coroutines.zig"); |
test/build_examples.zig+11-1| ... | @@ -13,9 +13,19 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void { | ... | @@ -13,9 +13,19 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void { |
| 13 | cases.addBuildFile("example/shared_library/build.zig"); | 13 | cases.addBuildFile("example/shared_library/build.zig"); |
| 14 | cases.addBuildFile("example/mix_o_files/build.zig"); | 14 | cases.addBuildFile("example/mix_o_files/build.zig"); |
| 15 | } | 15 | } |
| 16 | cases.addBuildFile("test/standalone/issue_339/build.zig"); | 16 | if (builtin.os != builtin.Os.macosx) { |
| 17 | // TODO https://github.com/ziglang/zig/issues/1126 | ||
| 18 | cases.addBuildFile("test/standalone/issue_339/build.zig"); | ||
| 19 | } | ||
| 17 | cases.addBuildFile("test/standalone/issue_794/build.zig"); | 20 | cases.addBuildFile("test/standalone/issue_794/build.zig"); |
| 18 | cases.addBuildFile("test/standalone/pkg_import/build.zig"); | 21 | cases.addBuildFile("test/standalone/pkg_import/build.zig"); |
| 19 | cases.addBuildFile("test/standalone/use_alias/build.zig"); | 22 | cases.addBuildFile("test/standalone/use_alias/build.zig"); |
| 20 | cases.addBuildFile("test/standalone/brace_expansion/build.zig"); | 23 | cases.addBuildFile("test/standalone/brace_expansion/build.zig"); |
| 24 | if (false) { | ||
| 25 | // TODO this test is disabled because it is failing on the CI server's linux. when this is fixed | ||
| 26 | // enable it for at least linux | ||
| 27 | // TODO hook up the DynLib API for windows using LoadLibraryA | ||
| 28 | // TODO figure out how to make this work on darwin - probably libSystem has dlopen/dlsym in it | ||
| 29 | cases.addBuildFile("test/standalone/load_dynamic_library/build.zig"); | ||
| 30 | } | ||
| 21 | } | 31 | } |
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" { |
test/cases/byval_arg_var.zig created+27| ... | @@ -0,0 +1,27 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | var result: []const u8 = "wrong"; | ||
| 4 | |||
| 5 | test "aoeu" { | ||
| 6 | start(); | ||
| 7 | blowUpStack(10); | ||
| 8 | |||
| 9 | std.debug.assert(std.mem.eql(u8, result, "string literal")); | ||
| 10 | } | ||
| 11 | |||
| 12 | fn start() void { | ||
| 13 | foo("string literal"); | ||
| 14 | } | ||
| 15 | |||
| 16 | fn foo(x: var) void { | ||
| 17 | bar(x); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn bar(x: var) void { | ||
| 21 | result = x; | ||
| 22 | } | ||
| 23 | |||
| 24 | fn blowUpStack(x: u32) void { | ||
| 25 | if (x == 0) return; | ||
| 26 | blowUpStack(x - 1); | ||
| 27 | } | ||
test/cases/cast.zig+23-9| ... | @@ -318,14 +318,6 @@ fn testCastConstArrayRefToConstSlice() void { | ... | @@ -318,14 +318,6 @@ fn testCastConstArrayRefToConstSlice() void { |
| 318 | assert(mem.eql(u8, slice, "aoeu")); | 318 | assert(mem.eql(u8, slice, "aoeu")); |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | test "var args implicitly casts by value arg to const ref" { | ||
| 322 | foo("hello"); | ||
| 323 | } | ||
| 324 | |||
| 325 | fn foo(args: ...) void { | ||
| 326 | assert(@typeOf(args[0]) == *const [5]u8); | ||
| 327 | } | ||
| 328 | |||
| 329 | test "peer type resolution: error and [N]T" { | 321 | test "peer type resolution: error and [N]T" { |
| 330 | // TODO: implicit error!T to error!U where T can implicitly cast to U | 322 | // TODO: implicit error!T to error!U where T can implicitly cast to U |
| 331 | //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); | 323 | //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); |
| ... | @@ -351,7 +343,7 @@ fn testPeerErrorAndArray2(x: u8) error![]const u8 { | ... | @@ -351,7 +343,7 @@ fn testPeerErrorAndArray2(x: u8) error![]const u8 { |
| 351 | test "explicit cast float number literal to integer if no fraction component" { | 343 | test "explicit cast float number literal to integer if no fraction component" { |
| 352 | const x = i32(1e4); | 344 | const x = i32(1e4); |
| 353 | assert(x == 10000); | 345 | assert(x == 10000); |
| 354 | const y = i32(f32(1e4)); | 346 | const y = @floatToInt(i32, f32(1e4)); |
| 355 | assert(y == 10000); | 347 | assert(y == 10000); |
| 356 | } | 348 | } |
| 357 | 349 | ||
| ... | @@ -406,3 +398,25 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" { | ... | @@ -406,3 +398,25 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" { |
| 406 | const x: [*]const ?[*]const u8 = &window_name; | 398 | const x: [*]const ?[*]const u8 = &window_name; |
| 407 | assert(mem.eql(u8, std.cstr.toSliceConst(x[0].?), "window name")); | 399 | assert(mem.eql(u8, std.cstr.toSliceConst(x[0].?), "window name")); |
| 408 | } | 400 | } |
| 401 | |||
| 402 | test "@intCast comptime_int" { | ||
| 403 | const result = @intCast(i32, 1234); | ||
| 404 | assert(@typeOf(result) == i32); | ||
| 405 | assert(result == 1234); | ||
| 406 | } | ||
| 407 | |||
| 408 | test "@floatCast comptime_int and comptime_float" { | ||
| 409 | const result = @floatCast(f32, 1234); | ||
| 410 | assert(@typeOf(result) == f32); | ||
| 411 | assert(result == 1234.0); | ||
| 412 | |||
| 413 | const result2 = @floatCast(f32, 1234.0); | ||
| 414 | assert(@typeOf(result) == f32); | ||
| 415 | assert(result == 1234.0); | ||
| 416 | } | ||
| 417 | |||
| 418 | test "comptime_int @intToFloat" { | ||
| 419 | const result = @intToFloat(f32, 1234); | ||
| 420 | assert(@typeOf(result) == f32); | ||
| 421 | assert(result == 1234.0); | ||
| 422 | } |
test/cases/enum.zig+1-1| ... | @@ -99,7 +99,7 @@ test "int to enum" { | ... | @@ -99,7 +99,7 @@ test "int to enum" { |
| 99 | testIntToEnumEval(3); | 99 | testIntToEnumEval(3); |
| 100 | } | 100 | } |
| 101 | fn testIntToEnumEval(x: i32) void { | 101 | fn testIntToEnumEval(x: i32) void { |
| 102 | assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three); | 102 | assert(IntToEnumNumber(@intCast(u3, x)) == IntToEnumNumber.Three); |
| 103 | } | 103 | } |
| 104 | const IntToEnumNumber = enum { | 104 | const IntToEnumNumber = enum { |
| 105 | Zero, | 105 | Zero, |
test/cases/eval.zig+4-4| ... | @@ -5,7 +5,7 @@ const builtin = @import("builtin"); | ... | @@ -5,7 +5,7 @@ const builtin = @import("builtin"); |
| 5 | test "compile time recursion" { | 5 | test "compile time recursion" { |
| 6 | assert(some_data.len == 21); | 6 | assert(some_data.len == 21); |
| 7 | } | 7 | } |
| 8 | var some_data: [usize(fibonacci(7))]u8 = undefined; | 8 | var some_data: [@intCast(usize, fibonacci(7))]u8 = undefined; |
| 9 | fn fibonacci(x: i32) i32 { | 9 | fn fibonacci(x: i32) i32 { |
| 10 | if (x <= 1) return 1; | 10 | if (x <= 1) return 1; |
| 11 | return fibonacci(x - 1) + fibonacci(x - 2); | 11 | return fibonacci(x - 1) + fibonacci(x - 2); |
| ... | @@ -356,7 +356,7 @@ const global_array = x: { | ... | @@ -356,7 +356,7 @@ const global_array = x: { |
| 356 | test "compile-time downcast when the bits fit" { | 356 | test "compile-time downcast when the bits fit" { |
| 357 | comptime { | 357 | comptime { |
| 358 | const spartan_count: u16 = 255; | 358 | const spartan_count: u16 = 255; |
| 359 | const byte = u8(spartan_count); | 359 | const byte = @intCast(u8, spartan_count); |
| 360 | assert(byte == 255); | 360 | assert(byte == 255); |
| 361 | } | 361 | } |
| 362 | } | 362 | } |
| ... | @@ -440,7 +440,7 @@ test "binary math operator in partially inlined function" { | ... | @@ -440,7 +440,7 @@ test "binary math operator in partially inlined function" { |
| 440 | var b: [16]u8 = undefined; | 440 | var b: [16]u8 = undefined; |
| 441 | 441 | ||
| 442 | for (b) |*r, i| | 442 | for (b) |*r, i| |
| 443 | r.* = u8(i + 1); | 443 | r.* = @intCast(u8, i + 1); |
| 444 | 444 | ||
| 445 | copyWithPartialInline(s[0..], b[0..]); | 445 | copyWithPartialInline(s[0..], b[0..]); |
| 446 | assert(s[0] == 0x1020304); | 446 | assert(s[0] == 0x1020304); |
| ... | @@ -480,7 +480,7 @@ fn generateTable(comptime T: type) [1010]T { | ... | @@ -480,7 +480,7 @@ fn generateTable(comptime T: type) [1010]T { |
| 480 | var res: [1010]T = undefined; | 480 | var res: [1010]T = undefined; |
| 481 | var i: usize = 0; | 481 | var i: usize = 0; |
| 482 | while (i < 1010) : (i += 1) { | 482 | while (i < 1010) : (i += 1) { |
| 483 | res[i] = T(i); | 483 | res[i] = @intCast(T, i); |
| 484 | } | 484 | } |
| 485 | return res; | 485 | return res; |
| 486 | } | 486 | } |
test/cases/fn.zig+58-1| ... | @@ -80,7 +80,7 @@ test "function pointers" { | ... | @@ -80,7 +80,7 @@ test "function pointers" { |
| 80 | fn4, | 80 | fn4, |
| 81 | }; | 81 | }; |
| 82 | for (fns) |f, i| { | 82 | for (fns) |f, i| { |
| 83 | assert(f() == u32(i) + 5); | 83 | assert(f() == @intCast(u32, i) + 5); |
| 84 | } | 84 | } |
| 85 | } | 85 | } |
| 86 | fn fn1() u32 { | 86 | fn fn1() u32 { |
| ... | @@ -119,3 +119,60 @@ test "assign inline fn to const variable" { | ... | @@ -119,3 +119,60 @@ test "assign inline fn to const variable" { |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | inline fn inlineFn() void {} | 121 | inline fn inlineFn() void {} |
| 122 | |||
| 123 | test "pass by non-copying value" { | ||
| 124 | assert(addPointCoords(Point{ .x = 1, .y = 2 }) == 3); | ||
| 125 | } | ||
| 126 | |||
| 127 | const Point = struct { | ||
| 128 | x: i32, | ||
| 129 | y: i32, | ||
| 130 | }; | ||
| 131 | |||
| 132 | fn addPointCoords(pt: Point) i32 { | ||
| 133 | return pt.x + pt.y; | ||
| 134 | } | ||
| 135 | |||
| 136 | test "pass by non-copying value through var arg" { | ||
| 137 | assert(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3); | ||
| 138 | } | ||
| 139 | |||
| 140 | fn addPointCoordsVar(pt: var) i32 { | ||
| 141 | comptime assert(@typeOf(pt) == Point); | ||
| 142 | return pt.x + pt.y; | ||
| 143 | } | ||
| 144 | |||
| 145 | test "pass by non-copying value as method" { | ||
| 146 | var pt = Point2{ .x = 1, .y = 2 }; | ||
| 147 | assert(pt.addPointCoords() == 3); | ||
| 148 | } | ||
| 149 | |||
| 150 | const Point2 = struct { | ||
| 151 | x: i32, | ||
| 152 | y: i32, | ||
| 153 | |||
| 154 | fn addPointCoords(self: Point2) i32 { | ||
| 155 | return self.x + self.y; | ||
| 156 | } | ||
| 157 | }; | ||
| 158 | |||
| 159 | test "pass by non-copying value as method, which is generic" { | ||
| 160 | var pt = Point3{ .x = 1, .y = 2 }; | ||
| 161 | assert(pt.addPointCoords(i32) == 3); | ||
| 162 | } | ||
| 163 | |||
| 164 | const Point3 = struct { | ||
| 165 | x: i32, | ||
| 166 | y: i32, | ||
| 167 | |||
| 168 | fn addPointCoords(self: Point3, comptime T: type) i32 { | ||
| 169 | return self.x + self.y; | ||
| 170 | } | ||
| 171 | }; | ||
| 172 | |||
| 173 | test "pass by non-copying value as method, at comptime" { | ||
| 174 | comptime { | ||
| 175 | var pt = Point2{ .x = 1, .y = 2 }; | ||
| 176 | assert(pt.addPointCoords() == 3); | ||
| 177 | } | ||
| 178 | } |
test/cases/for.zig+2-2| ... | @@ -46,7 +46,7 @@ test "basic for loop" { | ... | @@ -46,7 +46,7 @@ test "basic for loop" { |
| 46 | buf_index += 1; | 46 | buf_index += 1; |
| 47 | } | 47 | } |
| 48 | for (array) |item, index| { | 48 | for (array) |item, index| { |
| 49 | buffer[buf_index] = u8(index); | 49 | buffer[buf_index] = @intCast(u8, index); |
| 50 | buf_index += 1; | 50 | buf_index += 1; |
| 51 | } | 51 | } |
| 52 | const unknown_size: []const u8 = array; | 52 | const unknown_size: []const u8 = array; |
| ... | @@ -55,7 +55,7 @@ test "basic for loop" { | ... | @@ -55,7 +55,7 @@ test "basic for loop" { |
| 55 | buf_index += 1; | 55 | buf_index += 1; |
| 56 | } | 56 | } |
| 57 | for (unknown_size) |item, index| { | 57 | for (unknown_size) |item, index| { |
| 58 | buffer[buf_index] = u8(index); | 58 | buffer[buf_index] = @intCast(u8, index); |
| 59 | buf_index += 1; | 59 | buf_index += 1; |
| 60 | } | 60 | } |
| 61 | 61 |
test/cases/struct.zig+4-4| ... | @@ -365,14 +365,14 @@ test "runtime struct initialization of bitfield" { | ... | @@ -365,14 +365,14 @@ test "runtime struct initialization of bitfield" { |
| 365 | .y = x1, | 365 | .y = x1, |
| 366 | }; | 366 | }; |
| 367 | const s2 = Nibbles{ | 367 | const s2 = Nibbles{ |
| 368 | .x = u4(x2), | 368 | .x = @intCast(u4, x2), |
| 369 | .y = u4(x2), | 369 | .y = @intCast(u4, x2), |
| 370 | }; | 370 | }; |
| 371 | 371 | ||
| 372 | assert(s1.x == x1); | 372 | assert(s1.x == x1); |
| 373 | assert(s1.y == x1); | 373 | assert(s1.y == x1); |
| 374 | assert(s2.x == u4(x2)); | 374 | assert(s2.x == @intCast(u4, x2)); |
| 375 | assert(s2.y == u4(x2)); | 375 | assert(s2.y == @intCast(u4, x2)); |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | var x1 = u4(1); | 378 | var x1 = u4(1); |
test/cases/var_args.zig-12| ... | @@ -75,18 +75,6 @@ test "array of var args functions" { | ... | @@ -75,18 +75,6 @@ test "array of var args functions" { |
| 75 | assert(!foos[1]()); | 75 | assert(!foos[1]()); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | test "pass array and slice of same array to var args should have same pointers" { | ||
| 79 | const array = "hi"; | ||
| 80 | const slice: []const u8 = array; | ||
| 81 | return assertSlicePtrsEql(array, slice); | ||
| 82 | } | ||
| 83 | |||
| 84 | fn assertSlicePtrsEql(args: ...) void { | ||
| 85 | const s1 = ([]const u8)(args[0]); | ||
| 86 | const s2 = args[1]; | ||
| 87 | assert(s1.ptr == s2.ptr); | ||
| 88 | } | ||
| 89 | |||
| 90 | test "pass zero length array to var args param" { | 78 | test "pass zero length array to var args param" { |
| 91 | doNothingWithFirstArg(""); | 79 | doNothingWithFirstArg(""); |
| 92 | } | 80 | } |
test/compare_output.zig+3-3| ... | @@ -299,7 +299,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { | ... | @@ -299,7 +299,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 299 | \\export fn main() c_int { | 299 | \\export fn main() c_int { |
| 300 | \\ var array = []u32{ 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 }; | 300 | \\ var array = []u32{ 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 }; |
| 301 | \\ | 301 | \\ |
| 302 | \\ c.qsort(@ptrCast(?*c_void, array[0..].ptr), c_ulong(array.len), @sizeOf(i32), compare_fn); | 302 | \\ c.qsort(@ptrCast(?*c_void, array[0..].ptr), @intCast(c_ulong, array.len), @sizeOf(i32), compare_fn); |
| 303 | \\ | 303 | \\ |
| 304 | \\ for (array) |item, i| { | 304 | \\ for (array) |item, i| { |
| 305 | \\ if (item != i) { | 305 | \\ if (item != i) { |
| ... | @@ -331,8 +331,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { | ... | @@ -331,8 +331,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 331 | \\ } | 331 | \\ } |
| 332 | \\ const small: f32 = 3.25; | 332 | \\ const small: f32 = 3.25; |
| 333 | \\ const x: f64 = small; | 333 | \\ const x: f64 = small; |
| 334 | \\ const y = i32(x); | 334 | \\ const y = @floatToInt(i32, x); |
| 335 | \\ const z = f64(y); | 335 | \\ const z = @intToFloat(f64, y); |
| 336 | \\ _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, f64(-0.4)); | 336 | \\ _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, f64(-0.4)); |
| 337 | \\ return 0; | 337 | \\ return 0; |
| 338 | \\} | 338 | \\} |
test/compile_errors.zig+23-28| ... | @@ -1,6 +1,24 @@ | ... | @@ -1,6 +1,24 @@ |
| 1 | const tests = @import("tests.zig"); | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | ||
| 3 | pub fn addCases(cases: *tests.CompileErrorContext) void { | 3 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4 | cases.add( | ||
| 5 | "use c_void as return type of fn ptr", | ||
| 6 | \\export fn entry() void { | ||
| 7 | \\ const a: fn () c_void = undefined; | ||
| 8 | \\} | ||
| 9 | , | ||
| 10 | ".tmp_source.zig:2:20: error: return type cannot be opaque", | ||
| 11 | ); | ||
| 12 | |||
| 13 | cases.add( | ||
| 14 | "non int passed to @intToFloat", | ||
| 15 | \\export fn entry() void { | ||
| 16 | \\ const x = @intToFloat(f32, 1.1); | ||
| 17 | \\} | ||
| 18 | , | ||
| 19 | ".tmp_source.zig:2:32: error: expected int type, found 'comptime_float'", | ||
| 20 | ); | ||
| 21 | |||
| 4 | cases.add( | 22 | cases.add( |
| 5 | "use implicit casts to assign null to non-nullable pointer", | 23 | "use implicit casts to assign null to non-nullable pointer", |
| 6 | \\export fn entry() void { | 24 | \\export fn entry() void { |
| ... | @@ -2215,7 +2233,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -2215,7 +2233,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2215 | \\ derp.init(); | 2233 | \\ derp.init(); |
| 2216 | \\} | 2234 | \\} |
| 2217 | , | 2235 | , |
| 2218 | ".tmp_source.zig:14:5: error: expected type 'i32', found '*const Foo'", | 2236 | ".tmp_source.zig:14:5: error: expected type 'i32', found 'Foo'", |
| 2219 | ); | 2237 | ); |
| 2220 | 2238 | ||
| 2221 | cases.add( | 2239 | cases.add( |
| ... | @@ -2573,15 +2591,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -2573,15 +2591,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2573 | break :x tc; | 2591 | break :x tc; |
| 2574 | }); | 2592 | }); |
| 2575 | 2593 | ||
| 2576 | cases.add( | ||
| 2577 | "pass non-copyable type by value to function", | ||
| 2578 | \\const Point = struct { x: i32, y: i32, }; | ||
| 2579 | \\fn foo(p: Point) void { } | ||
| 2580 | \\export fn entry() usize { return @sizeOf(@typeOf(foo)); } | ||
| 2581 | , | ||
| 2582 | ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value", | ||
| 2583 | ); | ||
| 2584 | |||
| 2585 | cases.add( | 2594 | cases.add( |
| 2586 | "implicit cast from array to mutable slice", | 2595 | "implicit cast from array to mutable slice", |
| 2587 | \\var global_array: [10]i32 = undefined; | 2596 | \\var global_array: [10]i32 = undefined; |
| ... | @@ -2940,10 +2949,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -2940,10 +2949,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2940 | "cast negative value to unsigned integer", | 2949 | "cast negative value to unsigned integer", |
| 2941 | \\comptime { | 2950 | \\comptime { |
| 2942 | \\ const value: i32 = -1; | 2951 | \\ const value: i32 = -1; |
| 2943 | \\ const unsigned = u32(value); | 2952 | \\ const unsigned = @intCast(u32, value); |
| 2944 | \\} | 2953 | \\} |
| 2945 | , | 2954 | , |
| 2946 | ".tmp_source.zig:3:25: error: attempt to cast negative value to unsigned integer", | 2955 | ".tmp_source.zig:3:22: error: attempt to cast negative value to unsigned integer", |
| 2947 | ); | 2956 | ); |
| 2948 | 2957 | ||
| 2949 | cases.add( | 2958 | cases.add( |
| ... | @@ -2972,10 +2981,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -2972,10 +2981,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2972 | "compile-time integer cast truncates bits", | 2981 | "compile-time integer cast truncates bits", |
| 2973 | \\comptime { | 2982 | \\comptime { |
| 2974 | \\ const spartan_count: u16 = 300; | 2983 | \\ const spartan_count: u16 = 300; |
| 2975 | \\ const byte = u8(spartan_count); | 2984 | \\ const byte = @intCast(u8, spartan_count); |
| 2976 | \\} | 2985 | \\} |
| 2977 | , | 2986 | , |
| 2978 | ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits", | 2987 | ".tmp_source.zig:3:18: error: cast from 'u16' to 'u8' truncates bits", |
| 2979 | ); | 2988 | ); |
| 2980 | 2989 | ||
| 2981 | cases.add( | 2990 | cases.add( |
| ... | @@ -4066,20 +4075,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -4066,20 +4075,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4066 | ".tmp_source.zig:3:5: note: field 'A' has type 'i32'", | 4075 | ".tmp_source.zig:3:5: note: field 'A' has type 'i32'", |
| 4067 | ); | 4076 | ); |
| 4068 | 4077 | ||
| 4069 | cases.add( | ||
| 4070 | "self-referencing function pointer field", | ||
| 4071 | \\const S = struct { | ||
| 4072 | \\ f: fn(_: S) void, | ||
| 4073 | \\}; | ||
| 4074 | \\fn f(_: S) void { | ||
| 4075 | \\} | ||
| 4076 | \\export fn entry() void { | ||
| 4077 | \\ var _ = S { .f = f }; | ||
| 4078 | \\} | ||
| 4079 | , | ||
| 4080 | ".tmp_source.zig:4:9: error: type 'S' is not copyable; cannot pass by value", | ||
| 4081 | ); | ||
| 4082 | |||
| 4083 | cases.add( | 4078 | cases.add( |
| 4084 | "taking offset of void field in struct", | 4079 | "taking offset of void field in struct", |
| 4085 | \\const Empty = struct { | 4080 | \\const Empty = struct { |
test/runtime_safety.zig+2-2| ... | @@ -188,7 +188,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { | ... | @@ -188,7 +188,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 188 | \\ if (x == 0) return error.Whatever; | 188 | \\ if (x == 0) return error.Whatever; |
| 189 | \\} | 189 | \\} |
| 190 | \\fn shorten_cast(x: i32) i8 { | 190 | \\fn shorten_cast(x: i32) i8 { |
| 191 | \\ return i8(x); | 191 | \\ return @intCast(i8, x); |
| 192 | \\} | 192 | \\} |
| 193 | ); | 193 | ); |
| 194 | 194 | ||
| ... | @@ -201,7 +201,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { | ... | @@ -201,7 +201,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 201 | \\ if (x == 0) return error.Whatever; | 201 | \\ if (x == 0) return error.Whatever; |
| 202 | \\} | 202 | \\} |
| 203 | \\fn unsigned_cast(x: i32) u32 { | 203 | \\fn unsigned_cast(x: i32) u32 { |
| 204 | \\ return u32(x); | 204 | \\ return @intCast(u32, x); |
| 205 | \\} | 205 | \\} |
| 206 | ); | 206 | ); |
| 207 | 207 |
test/standalone/load_dynamic_library/add.zig created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | export fn add(a: i32, b: i32) i32 { | ||
| 2 | return a + b; | ||
| 3 | } | ||
test/standalone/load_dynamic_library/build.zig created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | const Builder = @import("std").build.Builder; | ||
| 2 | |||
| 3 | pub fn build(b: *Builder) void { | ||
| 4 | const opts = b.standardReleaseOptions(); | ||
| 5 | |||
| 6 | const lib = b.addSharedLibrary("add", "add.zig", b.version(1, 0, 0)); | ||
| 7 | lib.setBuildMode(opts); | ||
| 8 | |||
| 9 | const main = b.addExecutable("main", "main.zig"); | ||
| 10 | main.setBuildMode(opts); | ||
| 11 | |||
| 12 | const run = b.addCommand(".", b.env_map, [][]const u8{ | ||
| 13 | main.getOutputPath(), | ||
| 14 | lib.getOutputPath(), | ||
| 15 | }); | ||
| 16 | run.step.dependOn(&lib.step); | ||
| 17 | run.step.dependOn(&main.step); | ||
| 18 | |||
| 19 | const test_step = b.step("test", "Test the program"); | ||
| 20 | test_step.dependOn(&run.step); | ||
| 21 | } | ||
test/standalone/load_dynamic_library/main.zig created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn main() !void { | ||
| 4 | const args = try std.os.argsAlloc(std.debug.global_allocator); | ||
| 5 | defer std.os.argsFree(std.debug.global_allocator, args); | ||
| 6 | |||
| 7 | const dynlib_name = args[1]; | ||
| 8 | |||
| 9 | var lib = try std.DynLib.open(std.debug.global_allocator, dynlib_name); | ||
| 10 | defer lib.close(); | ||
| 11 | |||
| 12 | const addr = lib.lookup("add") orelse return error.SymbolNotFound; | ||
| 13 | const addFn = @intToPtr(extern fn (i32, i32) i32, addr); | ||
| 14 | |||
| 15 | const result = addFn(12, 34); | ||
| 16 | std.debug.assert(result == 46); | ||
| 17 | } | ||