authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 14:51:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 14:51:23-04:00
logc757984879687e465c6470fc1347cf0f14e46dcc
tree9827a65bfcc0041a279d8a75b567cba83f9c5b16
parent84a700f97240eb2d4c65554d9be43bae9fa6d4ae
parent1ca90b585692c9611c64412844d2f3a7b3e11340

Merge remote-tracking branch 'origin/master' into llvm7


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()
35endif()35endif()
36message("Configuring zig version ${ZIG_VERSION}")36message("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#}
647const floating_point = 123.0E+77;668const floating_point = 123.0E+77;
648const another_float = 123.0;669const another_float = 123.0;
...@@ -1334,7 +1355,7 @@ var some_integers: [100]i32 = undefined;...@@ -1334,7 +1355,7 @@ var some_integers: [100]i32 = undefined;
13341355
1335test "modify an array" {1356test "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 value2821 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#}
2804const Foo = struct {2824const Point = struct {
2805 x: i32,2825 x: i32,
2826 y: i32,
2806};2827};
28072828
2808fn bar(foo: Foo) void {}2829fn foo(point: Point) i32 {
28092830 return point.x + point.y;
2810test "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#}
2819const Foo = struct {
2820 x: i32,
2821};
28222832
2823fn bar(foo: *const Foo) void {}2833const assert = @import("std").debug.assert;
28242834
2825test "implicitly cast to const pointer" {2835test "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 which2841 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#}
3561export 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#}
3582const std = @import("std");
3583const assert = std.debug.assert;
3584
3585test "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
3599fn hash_i32(x: i32) u32 {
3600 return @bitCast(u32, x);
3601}
3602
3603fn 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#}
3621test "ignoring expression value" {
3622 foo();
3623}
3624
3625fn 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#}
3631test "ignoring expression value" {
3632 foo();
3633}
3634
3635fn 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#}
5719comptime {5859comptime {
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#}
5733comptime {5873comptime {
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({
8const msg = c"Hello, world!\n";8const msg = c"Hello, world!\n";
99
10export fn main(argc: c_int, argv: **u8) c_int {10export 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;
1212
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};
702702
703const 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
703fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {733fn 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 };
730760
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();
735776
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);
742789
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 }
761808
...@@ -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 }
771818
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};
26322642
2643struct IrInstructionIntCast {
2644 IrInstruction base;
2645
2646 IrInstruction *dest_type;
2647 IrInstruction *target;
2648};
2649
2650struct IrInstructionFloatCast {
2651 IrInstruction base;
2652
2653 IrInstruction *dest_type;
2654 IrInstruction *target;
2655};
2656
2657struct IrInstructionIntToFloat {
2658 IrInstruction base;
2659
2660 IrInstruction *dest_type;
2661 IrInstruction *target;
2662};
2663
2664struct IrInstructionFloatToInt {
2665 IrInstruction base;
2666
2667 IrInstruction *dest_type;
2668 IrInstruction *target;
2669};
2670
2671struct IrInstructionBoolToInt {
2672 IrInstruction base;
2673
2674 IrInstruction *target;
2675};
2676
2633struct IrInstructionIntType {2677struct IrInstructionIntType {
2634 IrInstruction base;2678 IrInstruction base;
26352679
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;
11371138
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}
328328
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
333static 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
340static bool is_symbol_available(CodeGen *g, Buf *name) {329static 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 }
594578
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 }
30543038
30553039
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();
46624642
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 Int6236 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 }
66896674
...@@ -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 }
68606845
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 }
69456930
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 }
69516936
...@@ -7289,7 +7274,7 @@ static void gen_h_file(CodeGen *g) {...@@ -7289,7 +7274,7 @@ static void gen_h_file(CodeGen *g) {
72897274
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));
72937278
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}
462462
463static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) {
464 return IrInstructionIdIntCast;
465}
466
467static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) {
468 return IrInstructionIdFloatCast;
469}
470
471static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) {
472 return IrInstructionIdIntToFloat;
473}
474
475static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) {
476 return IrInstructionIdFloatToInt;
477}
478
479static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) {
480 return IrInstructionIdBoolToInt;
481}
482
463static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) {483static 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}
19011921
1902static IrInstruction *ir_build_truncate_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *dest_type, IrInstruction *target) {1922static 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
1933static 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
1944static 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
1955static 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
1966static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) {
1967 IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node);
1968 instruction->target = target;
1969
1970 ir_ref_instruction(target, irb->current_basic_block);
1971
1972 return &instruction->base;
1906}1973}
19071974
1908static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) {1975static 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 }
994310080
9944 // explicit cast from bool to int10081 // 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 }
995910089
9960 // explicit error set cast10090 // 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 }
996610097
9967 // explicit cast from int to float10098 // 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 }
997310105
9974 // explicit cast from float to int10106
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 }
998010113
9981 // explicit cast from [N]T to []const T10114 // 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}
1046510598
10466static 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
10473static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {10599static 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 }
1230212428
...@@ -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
1251512641
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;
1266812803
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 }
1287813026
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 }
1735617500
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}
1736017506
17507static 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
17548static 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
17596static 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
17616static 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
17630static 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
17361static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) {17657static 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 }
1838318684
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;
2023520551
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}
650650
651static 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
659static 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
667static 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
675static 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
683static void ir_print_bool_to_int(IrPrint *irp, IrInstructionBoolToInt *instruction) {
684 fprintf(irp->f, "@boolToInt(");
685 ir_print_other_instruction(irp, instruction->target);
686 fprintf(irp->f, ")");
687}
688
651static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) {689static 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) {
208static void construct_linker_job_elf(LinkJob *lj) {208static void construct_linker_job_elf(LinkJob *lj) {
209 CodeGen *g = lj->codegen;209 CodeGen *g = lj->codegen;
210210
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 }
214214
...@@ -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
432static void construct_linker_job_coff(LinkJob *lj) {432static void construct_linker_job_coff(LinkJob *lj) {
433 CodeGen *g = lj->codegen;433 CodeGen *g = lj->codegen;
434434
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 }
438438
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 }
990990
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) {
685uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {685uint32_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 }
3131
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 }
3535
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 }
3939
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 }
4343
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 }
4747
48 /// Sets the value at index `i`, or returns `error.OutOfBounds` if48 /// 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 }
5454
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 }
6060
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 }
6464
...@@ -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 }
8383
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;
8787
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 }
9191
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 }
9999
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 }
104104
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 }
191191
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 }
198198
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 }
202202
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 }
206206
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);
101101
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 }
105105
...@@ -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();
235235
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..]);
8080
81 // No key plus default parameters81 // 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 {
110110
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 }
115115
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 }
145145
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];
149149
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 {
345345
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 }
350350
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 }
378378
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];
382382
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 {
7878
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);
8282
83 // Md5 uses the bottom 64-bits for length padding83 // 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 }
111111
std/crypto/sha1.zig+3-3
...@@ -78,7 +78,7 @@ pub const Sha1 = struct {...@@ -78,7 +78,7 @@ pub const Sha1 = struct {
7878
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);
8282
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 }
110110
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 {
131131
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);
135135
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 }
163163
...@@ -472,7 +472,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {...@@ -472,7 +472,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
472472
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);
476476
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 }
504504
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};
644645
...@@ -1069,7 +1070,7 @@ fn readULeb128(in_stream: var) !u64 {...@@ -1069,7 +1070,7 @@ fn readULeb128(in_stream: var) !u64 {
10691070
1070 var operand: u64 = undefined;1071 var operand: u64 = undefined;
10711072
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;
10731074
1074 result |= operand;1075 result |= operand;
10751076
...@@ -1088,13 +1089,13 @@ fn readILeb128(in_stream: var) !i64 {...@@ -1088,13 +1089,13 @@ fn readILeb128(in_stream: var) !i64 {
10881089
1089 var operand: i64 = undefined;1090 var operand: i64 = undefined;
10901091
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;
10921093
1093 result |= operand;1094 result |= operand;
1094 shift += 7;1095 shift += 7;
10951096
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 @@
1const std = @import("index.zig");
2const mem = std.mem;
3const elf = std.elf;
4const cstr = std.cstr;
5const linux = std.os.linux;
6
7pub 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
53pub 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
144fn 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;
305pub const VER_FLG_BASE = 0x1;305pub const VER_FLG_BASE = 0x1;
306pub const VER_FLG_WEAK = 0x2;306pub const VER_FLG_WEAK = 0x2;
307307
308/// An unknown type.
309pub const ET_NONE = 0;
310
311/// A relocatable file.
312pub const ET_REL = 1;
313
314/// An executable file.
315pub const ET_EXEC = 2;
316
317/// A shared object.
318pub const ET_DYN = 3;
319
320/// A core file.
321pub const ET_CORE = 4;
322
308pub const FileType = enum {323pub 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 number34 // 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 midpoint107 // normalize the midpoint
108108
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 }
116116
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;
120120
121 exp -= 307;121 exp -= 307;
122122
...@@ -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;
173173
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;
176176
177 if (ldig != hdig) break;177 if (ldig != hdig) break;
178178
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 }
186186
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;
190190
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 {
304304
305 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));305 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
306306
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);
310310
...@@ -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 }
316316
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);
319319
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);
322322
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;
342342
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 }
348348
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}
354354
...@@ -359,33 +359,33 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {...@@ -359,33 +359,33 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
359fn errolFixed(val: f64, buffer: []u8) FloatDecimal {359fn errolFixed(val: f64, buffer: []u8) FloatDecimal {
360 assert((val >= 16.0) and (val < 9.007199254740992e15));360 assert((val >= 16.0) and (val < 9.007199254740992e15));
361361
362 const u = u64(val);362 const u = @floatToInt(u64, val);
363 const n = f64(u);363 const n = @intToFloat(f64, u);
364364
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;
368368
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;
373373
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);
379379
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);
383383
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);
387387
388 buffer[j] = u8(mdig + '0');388 buffer[j] = @intCast(u8, mdig + '0');
389 j += 1;389 j += 1;
390390
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;
453453
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);
512512
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 1844581 const a = @intCast(u32, value / kTen16); // 1 to 1844
582 value %= kTen16;582 value %= kTen16;
583583
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;
596596
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 }
614614
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);
617617
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;
5const mem = std.mem;5const mem = std.mem;
6const builtin = @import("builtin");6const builtin = @import("builtin");
7const errol = @import("errol/index.zig");7const errol = @import("errol/index.zig");
8const lossyCast = std.math.lossyCast;
89
9const max_int_digits = 65;10const max_int_digits = 65;
1011
...@@ -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);
460465
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;
463468
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(
488493
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);
493498
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;
521526
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(
543548
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);
547552
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;
2727
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;
123123
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)
8181
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 }
8787
...@@ -233,7 +233,7 @@ test "siphash64-2-4 sanity" {...@@ -233,7 +233,7 @@ test "siphash64-2-4 sanity" {
233233
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);
237237
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" {
312312
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);
316316
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 {
408408
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 }
413413
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;
8pub const LinkedList = @import("linked_list.zig").LinkedList;8pub const LinkedList = @import("linked_list.zig").LinkedList;
9pub const IntrusiveLinkedList = @import("linked_list.zig").IntrusiveLinkedList;9pub const IntrusiveLinkedList = @import("linked_list.zig").IntrusiveLinkedList;
10pub const SegmentedList = @import("segmented_list.zig").SegmentedList;10pub const SegmentedList = @import("segmented_list.zig").SegmentedList;
11pub const DynLib = @import("dynamic_library.zig").DynLib;
1112
12pub const atomic = @import("atomic/index.zig");13pub const atomic = @import("atomic/index.zig");
13pub const base64 = @import("base64.zig");14pub 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)
242242
243/// On success, caller owns returned buffer.243/// On success, caller owns returned buffer.
244pub fn readFileAlloc(allocator: *mem.Allocator, path: []const u8) ![]u8 {244pub 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.
249pub 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();
247252
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);
251256
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 };
186186
...@@ -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;
9696
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;
100100
101 // |x| >= 1 or nan101 // |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);
104104
105 // acos(1) = 0, acos(-1) = pi105 // 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;
8888
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;
9292
93 // |x| >= 1 or nan93 // |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);
9696
97 // asin(1) = +-pi/2 with inexact97 // 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 {
138138
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;
144144
...@@ -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 }
125125
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);
129129
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);
133133
134 // x = 1.0134 // 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 // underflow63 // 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.568 // |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}
2020
21const 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.
26fn 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
54pub const Int = struct {21pub 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 }
9562
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 }
9966
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 }
11279
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 }
11784
...@@ -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 }
12794
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 }
142109
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 }
146113
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 }
150117
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 }
155122
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 }
159126
...@@ -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;
170137
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);
172139
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 };
221188
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;
232199
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 }
288255
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 }
297276
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);
346325
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);
349328
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 {
361340
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 }
379358
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 }
409383
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 }
423393
424 // if a == 0394 // 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 }
428398
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 }
433403
434 // if a == b404 // 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 }
438408
...@@ -473,12 +443,7 @@ pub const Int = struct {...@@ -473,12 +443,7 @@ pub const Int = struct {
473 }443 }
474444
475 // r = a + b445 // 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 {
534499
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 }
541506
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 }
545510
546 r[i] = carry;511 r[i] = carry;
547 }512 }
548513
549 // r = a - b514 // 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 + b518 // (a) - (-b) => a + b
...@@ -617,13 +577,13 @@ pub const Int = struct {...@@ -617,13 +577,13 @@ pub const Int = struct {
617577
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 }
624584
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 }
628588
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 * b592 // 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;
643598
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;
670625
671 // r1 = a + *carry626 // r1 = a + *carry
672 const c1 = Limb(@addWithOverflow(Limb, a, carry.*, &r1));627 const c1: Limb = @boolToInt(@addWithOverflow(Limb, a, carry.*, &r1));
673628
674 // r2 = b * c629 // 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);
685640
686 // r1 = r1 + r2641 // r1 = r1 + r2
687 const c3 = Limb(@addWithOverflow(Limb, r1, r2, &r1));642 const c3: Limb = @boolToInt(@addWithOverflow(Limb, r1, r2, &r1));
688643
689 // This never overflows, c1, c3 are either 0 or 1 and if both are 1 then644 // 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 }
716671
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);
719674
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 }
727687
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 }
732692
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 {
821776
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);
826781
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);
833788
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 }
840795
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 }
852807
...@@ -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);
866821
867 if (r.cmpAbs(&tmp) <= 0) {822 if (r.cmpAbs(tmp) <= 0) {
868 break;823 break;
869 }824 }
870825
...@@ -873,13 +828,13 @@ pub const Int = struct {...@@ -873,13 +828,13 @@ pub const Int = struct {
873828
874 // 3.3829 // 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);
879834
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 // Denormalize842 // Denormalize
888 q.normN(q.len);843 q.normN(q.len);
889844
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 }
893848
894 // r = a << shift, in other words, r = a * 2^shift849 // 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);
910861
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);
913864
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;
919870
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 }
924875
...@@ -927,11 +878,7 @@ pub const Int = struct {...@@ -927,11 +878,7 @@ pub const Int = struct {
927 }878 }
928879
929 // r = a >> shift880 // 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));
952899
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);
955902
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 {
961908
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 }
967914
968 // r = a | b915 // 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 }
999941
1000 // r = a & b942 // 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 }
1028965
1029 // r = a ^ b966 // 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.
1066998
1067const u256 = @IntType(false, 256);999const u256 = @IntType(false, 256);
1068var al = debug.global_allocator;1000const al = debug.global_allocator;
10691001
1070test "big.int comptime_int set" {1002test "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);
12001132
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);
13221254
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}
13261258
1327test "big.int compare similar" {1259test "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);
13301262
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}
13341266
1335test "big.int compare different limb size" {1267test "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);
13381270
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}
13421274
1343test "big.int compare multi-limb" {1275test "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);
13461278
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}
13501282
1351test "big.int equality" {1283test "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);
13541286
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}
13581290
1359test "big.int abs" {1291test "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);
13821314
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);
13851317
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" {
13921324
1393 var c = try Int.init(al);1325 var c = try Int.init(al);
13941326
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);
13971329
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}
14011333
...@@ -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);
14071339
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);
14101342
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);
14171349
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);
14201352
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);
14281360
1429 try a.add(&a, &b);1361 try a.add(a, b);
14301362
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" {
1434test "big.int add sign" {1366test "big.int add sign" {
1435 var a = try Int.init(al);1367 var a = try Int.init(al);
14361368
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);
14391376
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);
14421379
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);
14451382
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}
14491386
...@@ -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);
14531390
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);
14561393
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);
14631400
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);
14661403
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);
14761413
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);
14791416
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);
14861423
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);
14891426
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" {
1493test "big.int sub sign" {1430test "big.int sub sign" {
1494 var a = try Int.init(al);1431 var a = try Int.init(al);
14951432
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);
14981440
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);
15011443
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);
15041446
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);
15071449
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}
15111453
...@@ -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);
15151457
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);
15181460
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);
15251467
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);
15281470
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);
15371479
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);
15401482
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);
15471489
1548 try a.mul(&a, &b);1490 try a.mul(a, b);
15491491
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);
15561498
1557 try a.mul(&b, &a);1499 try a.mul(b, a);
15581500
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" {
1562test "big.int mul alias r with a and b" {1504test "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));
15641506
1565 try a.mul(&a, &a);1507 try a.mul(a, a);
15661508
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);
15731515
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);
15761518
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);
15831525
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);
15861528
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" {
15931535
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);
15971539
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" {
16051547
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);
16091551
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" {
16201562
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);
16241566
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" {
16351577
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);
16391581
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" {
16501592
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);
16541596
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" {
16621604
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);
16661608
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" {
16741616
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);
16781620
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);
16861628
1687 try Int.divTrunc(&a, &b, &a, &b);1629 try Int.divTrunc(&a, &b, a, b);
16881630
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" {
16981640
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);
17021644
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 +/+" {
17131655
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);
17171659
1718 // n = q * d + r1660 // n = q * d + r
1719 // 5 = 1 * 3 + 21661 // 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 -/+" {
17331675
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);
17371679
1738 // n = q * d + r1680 // n = q * d + r
1739 // -5 = 1 * -3 - 21681 // -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 +/-" {
17531695
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);
17571699
1758 // n = q * d + r1700 // n = q * d + r
1759 // 5 = -1 * -3 + 21701 // 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 -/-" {
17731715
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);
17771719
1778 // n = q * d + r1720 // n = q * d + r
1779 // -5 = 1 * -3 - 21721 // -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 +/+" {
17931735
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);
17971739
1798 // n = q * d + r1740 // n = q * d + r
1799 // 5 = 1 * 3 + 21741 // 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 -/+" {
18131755
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);
18171759
1818 // n = q * d + r1760 // n = q * d + r
1819 // -5 = -2 * 3 + 11761 // -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 +/-" {
18331775
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);
18371779
1838 // n = q * d + r1780 // n = q * d + r
1839 // 5 = -2 * -3 - 11781 // 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 -/-" {
18531795
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);
18571799
1858 // n = q * d + r1800 // n = q * d + r
1859 // -5 = 2 * -3 + 11801 // -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" {
18701812
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);
18741816
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" {
18821824
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);
18861828
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)" {
18941836
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);
18981840
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)" {
19061848
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);
19101852
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" {
1943test "big.int shift-right negative" {1885test "big.int shift-right negative" {
1944 var a = try Int.init(al);1886 var a = try Int.init(al);
19451887
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);
19481890
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}
19521894
1953test "big.int shift-left negative" {1895test "big.int shift-left negative" {
1954 var a = try Int.init(al);1896 var a = try Int.init(al);
19551897
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}
19591901
...@@ -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);
19631905
1964 try a.bitAnd(&a, &b);1906 try a.bitAnd(a, b);
19651907
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));
19721914
1973 try a.bitAnd(&a, &b);1915 try a.bitAnd(a, b);
19741916
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);
19811923
1982 try a.bitXor(&a, &b);1924 try a.bitXor(a, b);
19831925
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));
19901932
1991 try a.bitXor(&a, &b);1933 try a.bitXor(a, b);
19921934
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);
19991941
2000 try a.bitOr(&a, &b);1942 try a.bitOr(a, b);
20011943
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));
20081950
2009 try a.bitOr(&a, &b);1951 try a.bitOr(a, b);
20101952
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" {
2015test "big.int var args" {1957test "big.int var args" {
2016 var a = try Int.initSet(al, 5);1958 var a = try Int.initSet(al, 5);
20171959
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);
20201962
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);
5656
57 return f32(t);57 return @floatCast(f32, t);
58}58}
5959
60fn cbrt64(x: f64) f64 {60fn 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;
7070
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;
7373
74 // cbrt(nan, inf) = itself74 // 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 ~5bits79 // 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;
8383
84 // cbrt(0) is itself84 // 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) {
2020
21fn ceil32(x: f32) f32 {21fn 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;
2525
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;
4const cmath = math.complex;4const cmath = math.complex;
5const Complex = cmath.Complex;5const Complex = cmath.Complex;
66
7pub fn atan(z: var) Complex(@typeOf(z.re)) {7pub 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 }
2727
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}
3131
32fn atan32(z: *const Complex(f32)) Complex(f32) {32fn atan32(z: Complex(f32)) Complex(f32) {
33 const maxnum = 1.0e38;33 const maxnum = 1.0e38;
3434
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 }
7676
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}
8080
81fn atan64(z: *const Complex(f64)) Complex(f64) {81fn atan64(z: Complex(f64)) Complex(f64) {
82 const maxnum = 1.0e308;82 const maxnum = 1.0e308;
8383
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;
8484
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;
8989
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;
9494
std/math/complex/exp.zig+3-3
...@@ -6,7 +6,7 @@ const Complex = cmath.Complex;...@@ -6,7 +6,7 @@ const Complex = cmath.Complex;
66
7const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;7const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
88
9pub fn exp(z: var) Complex(@typeOf(z.re)) {9pub fn exp(z: var) @typeOf(z) {
10 const T = @typeOf(z.re);10 const T = @typeOf(z.re);
1111
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}
1818
19fn exp32(z: *const Complex(f32)) Complex(f32) {19fn exp32(z: Complex(f32)) Complex(f32) {
20 @setFloatMode(this, @import("builtin").FloatMode.Strict);20 @setFloatMode(this, @import("builtin").FloatMode.Strict);
2121
22 const exp_overflow = 0x42b17218; // max_exp * ln2 ~= 88.7228395522 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}
6565
66fn exp64(z: *const Complex(f64)) Complex(f64) {66fn exp64(z: Complex(f64)) Complex(f64) {
67 const exp_overflow = 0x40862e42; // high bits of max_exp * ln2 ~= 71067 const exp_overflow = 0x40862e42; // high bits of max_exp * ln2 ~= 710
68 const cexp_overflow = 0x4096b8e4; // (max_exp - min_denorm_exp) * ln268 const cexp_overflow = 0x4096b8e4; // (max_exp - min_denorm_exp) * ln2
6969
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 }
3939
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 }
4646
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 }
5353
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 }
6060
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 }
7171
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 }
7878
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 }
8686
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;
4const cmath = math.complex;4const cmath = math.complex;
5const Complex = cmath.Complex;5const Complex = cmath.Complex;
66
7pub fn ldexp_cexp(z: var, expt: i32) Complex(@typeOf(z.re)) {7pub fn ldexp_cexp(z: var, expt: i32) @typeOf(z) {
8 const T = @typeOf(z.re);8 const T = @typeOf(z.re);
99
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 {
2020
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}
2627
27fn ldexp_cexp32(z: *const Complex(f32), expt: i32) Complex(f32) {28fn 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);
4647
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);
5051
51 expt.* = i32(hx >> 20) - (0x3ff + 1023) + k;52 expt.* = @intCast(i32, hx >> 20) - (0x3ff + 1023) + k;
5253
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}
5657
57fn ldexp_cexp64(z: *const Complex(f64), expt: i32) Complex(f64) {58fn 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;
66
7const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;7const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
88
9pub fn sinh(z: var) Complex(@typeOf(z.re)) {9pub 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}
1717
18fn sinh32(z: *const Complex(f32)) Complex(f32) {18fn 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;
2121
...@@ -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}
8080
81fn sinh64(z: *const Complex(f64)) Complex(f64) {81fn 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;
8484
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;
8989
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;
9494
std/math/complex/sqrt.zig+12-7
...@@ -4,18 +4,17 @@ const math = std.math;...@@ -4,18 +4,17 @@ const math = std.math;
4const cmath = math.complex;4const cmath = math.complex;
5const Complex = cmath.Complex;5const Complex = cmath.Complex;
66
7// TODO when #733 is solved this can be @typeOf(z) instead of Complex(@typeOf(z.re))7pub fn sqrt(z: var) @typeOf(z) {
8pub fn sqrt(z: var) Complex(@typeOf(z.re)) {
9 const T = @typeOf(z.re);8 const T = @typeOf(z.re);
109
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}
1716
18fn sqrt32(z: *const Complex(f32)) Complex(f32) {17fn 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;
2120
...@@ -50,14 +49,20 @@ fn sqrt32(z: *const Complex(f32)) Complex(f32) {...@@ -50,14 +49,20 @@ fn sqrt32(z: *const Complex(f32)) Complex(f32) {
5049
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}
5964
60fn sqrt64(z: *const Complex(f64)) Complex(f64) {65fn 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;
6368
std/math/complex/tanh.zig+6-4
...@@ -4,7 +4,7 @@ const math = std.math;...@@ -4,7 +4,7 @@ const math = std.math;
4const cmath = math.complex;4const cmath = math.complex;
5const Complex = cmath.Complex;5const Complex = cmath.Complex;
66
7pub fn tanh(z: var) Complex(@typeOf(z.re)) {7pub 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}
1515
16fn tanh32(z: *const Complex(f32)) Complex(f32) {16fn 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;
1919
...@@ -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}
5353
54fn tanh64(z: *const Complex(f64)) Complex(f64) {54fn 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;
5757
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;
6264
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 }
5656
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);
5959
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 }
107107
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);
110110
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 {
4949
50fn cosh64(x: f64) f64 {50fn 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));
5454
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 {
2929
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;
3434
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 * ln264 // |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 }
7070
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;
115115
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 * ln2149 // |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 }
155155
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{
38fn exp2_32(x: f32) f32 {38fn exp2_32(x: f32) f32 {
39 @setFloatMode(this, @import("builtin").FloatMode.Strict);39 @setFloatMode(this, @import("builtin").FloatMode.Strict);
4040
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}
9494
95const exp2dt = []f64{95const exp2dt = []f64{
...@@ -355,8 +355,8 @@ const exp2dt = []f64{...@@ -355,8 +355,8 @@ const exp2dt = []f64{
355fn exp2_64(x: f64) f64 {355fn exp2_64(x: f64) f64 {
356 @setFloatMode(this, @import("builtin").FloatMode.Strict);356 @setFloatMode(this, @import("builtin").FloatMode.Strict);
357357
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;
365365
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;
368368
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 // underflow387 // 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 }
8080
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 }
125125
126 const twopk = @bitCast(f32, u32((0x7F +% k) << 23));126 const twopk = @bitCast(f32, @intCast(u32, (0x7F +% k) << 23));
127127
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 }
138138
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 {
158158
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;
163163
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 }
209209
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 }
254254
255 const twopk = @bitCast(f64, u64(0x3FF +% k) << 52);255 const twopk = @bitCast(f64, @intCast(u64, 0x3FF +% k) << 52);
256256
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 }
267267
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) {
2020
21fn floor32(x: f32) f32 {21fn 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;
2525
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 }
3434
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;
1818
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-rounding22 // TODO: Handle inexact case with double-rounding
23 return f32(xy_z);23 return @floatCast(f32, xy_z);
24 }24 }
25}25}
2626
...@@ -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;
3131
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;
3434
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;
6868
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;
7171
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 }
5151
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}
5454
55fn sq(hi: *f64, lo: *f64, x: f64) void {55fn 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;
2323
24fn ilogb32(x: f32) i32 {24fn 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);
2727
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 {
5959
60fn ilogb64(x: f64) i32 {60fn 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);
6363
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.
228pub fn shl(comptime T: type, a: T, shift_amt: var) T {228pub 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);
231231
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.
252pub fn shr(comptime T: type, a: T, shift_amt: var) T {252pub 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);
255255
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.
474pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) {474pub 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);
477477
478 return uint(-(x + 1)) + 1;478 return @intCast(uint, -(x + 1)) + 1;
479}479}
480480
481test "math.absCast" {481test "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) {
499499
500 if (x == -@minValue(int)) return @minValue(int);500 if (x == -@minValue(int)) return @minValue(int);
501501
502 return -int(x);502 return -@intCast(int, x);
503}503}
504504
505test "math.negateCast" {505test "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}
528528
...@@ -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}
538538
539pub const AlignCastError = error{UnalignedMemory};
540
541/// Align cast a pointer but return an error if it's the wrong alignment
542pub 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
539pub fn floorPowerOfTwo(comptime T: type, value: T) T {550pub fn floorPowerOfTwo(comptime T: type, value: T) T {
540 var x = value;551 var x = value;
541552
...@@ -554,7 +565,7 @@ test "math.floorPowerOfTwo" {...@@ -554,7 +565,7 @@ test "math.floorPowerOfTwo" {
554565
555pub fn log2_int(comptime T: type, x: T) Log2Int(T) {566pub 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}
559570
560pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) {571pub 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
601pub 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 {
7171
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);
7777
...@@ -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);
8787
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 {
103103
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;
108108
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 x119 // 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 {
128128
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);
145145
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 }
1515
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 math25 // 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 },
2728
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 {
7171
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);
7777
...@@ -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);
9393
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 {
109109
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;
114114
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 x125 // 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 {
134134
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 {
157157
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;
163163
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;
7575
76 // correction to avoid underflow in c / u76 // 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);
9797
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;
113113
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;
156156
157 // correction to avoid underflow in c / u157 // 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);
179179
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 {
7575
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);
8181
...@@ -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}
9898
99pub fn log2_64(x_: f64) f64 {99pub 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 {
109109
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;
114114
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 x125 // 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 {
134134
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;
160160
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;
3030
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;
3434
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 }
5959
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;
7575
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);
7979
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 }
103103
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;
148148
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 {
171171
172fn isOddInteger(x: f64) bool {172fn 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}
176176
177test "math.pow" {177test "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 }
3939
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}
4343
...@@ -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 }
6969
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}
7373
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 }
6161
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);
6464
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 }
113113
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);
116116
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);
5858
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));
6262
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 }
100100
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}
104104
105test "math.sqrt_int" {105test "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 }
5454
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);
5757
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 }
103103
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);
106106
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 {
6868
69fn tanh64(x: f64) f64 {69fn 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));
7373
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 subnormal101 // |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 }
106106
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) {
1919
20fn trunc32(x: f32) f32 {20fn 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;
2424
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 }
3131
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 {
4040
41fn trunc64(x: f64) f64 {41fn 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;
4545
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 }
5252
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 {
4040
41 /// Call destroy with the result41 /// Call destroy with the result
42 /// TODO once #733 is solved, this will replace create42 /// 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 T44 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 }
5551
...@@ -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 }
414414
415 // we are the parent415 // 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.
291pub fn getErrno(r: usize) usize {291pub 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}
295295
296pub fn close(fd: i32) usize {296pub 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}
340340
341pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {341pub 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 {
265265
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 }
322313
323 pub const ReadError = error{};314 pub const ReadError = error{
315 BadFd,
316 Io,
317 IsDir,
318
319 Unexpected,
320 };
324321
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);
128128
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}
349349
...@@ -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);
587587
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);
590590
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),
21892189
...@@ -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),
22312231
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
22962296
2297pub fn linuxEpollWait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize {2297pub 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 correctly2667 // 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
2701pub 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}
644pub fn WIFSTOPPED(s: i32) bool {644pub 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}
647pub fn WIFSIGNALED(s: i32) bool {647pub 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.
659pub fn getErrno(r: usize) usize {659pub 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}
663663
664pub fn dup2(old: i32, new: i32) usize {664pub 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}
667667
668// TODO https://github.com/ziglang/zig/issues/265668// 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}
694694
695pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize {695pub 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}
698698
699pub fn isatty(fd: i32) bool {699pub 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}
703703
704// TODO https://github.com/ziglang/zig/issues/265704// 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}
728728
729pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {729pub 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}
732732
733pub fn munmap(address: usize, length: usize) usize {733pub 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}
736736
737pub fn read(fd: i32, buf: [*]u8, count: usize) usize {737pub 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}
740740
741// TODO https://github.com/ziglang/zig/issues/265741// 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}
750750
751pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {751pub 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}
754754
755// TODO https://github.com/ziglang/zig/issues/265755// 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}
767767
768pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {768pub 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}
771771
772pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {772pub 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}
775775
776// TODO https://github.com/ziglang/zig/issues/265776// 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 {
790790
791// TODO https://github.com/ziglang/zig/issues/265791// TODO https://github.com/ziglang/zig/issues/265
792pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize {792pub 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}
795795
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}
805805
806pub fn close(fd: i32) usize {806pub fn close(fd: i32) usize {
807 return syscall1(SYS_close, usize(fd));807 return syscall1(SYS_close, @intCast(usize, fd));
808}808}
809809
810pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize {810pub 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}
813813
814pub fn exit(status: i32) noreturn {814pub 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}
818818
819pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {819pub 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}
822822
823pub fn kill(pid: i32, sig: i32) usize {823pub 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}
826826
827// TODO https://github.com/ziglang/zig/issues/265827// 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;
999pub fn raise(sig: i32) usize {999pub 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 {
10191019
1020pub fn sigaddset(set: *sigset_t, sig: u6) void {1020pub 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}
10241024
1025pub fn sigismember(set: *const sigset_t, sig: u6) bool {1025pub 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}
10291029
1030pub const in_port_t = u16;1030pub 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};
10581058
1059pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {1059pub 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}
10621062
1063pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {1063pub 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}
10661066
1067pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {1067pub 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}
10701070
1071pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {1071pub 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}
10741074
1075pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {1075pub 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}
10781078
1079pub fn sendmsg(fd: i32, msg: *const msghdr, flags: u32) usize {1079pub 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}
10821082
1083pub fn connect(fd: i32, addr: *const sockaddr, len: socklen_t) usize {1083pub 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}
10861086
1087pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {1087pub 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}
10901090
1091pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {1091pub 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}
10941094
1095pub fn shutdown(fd: i32, how: i32) usize {1095pub 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}
10981098
1099pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {1099pub 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}
11021102
1103pub fn listen(fd: i32, backlog: u32) usize {1103pub 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}
11061106
1107pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {1107pub 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}
11101110
1111pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {1111pub 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}
11141114
1115pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {1115pub 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}
11181118
1119pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize {1119pub 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}
11221122
1123pub fn fstat(fd: i32, stat_buf: *Stat) usize {1123pub 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}
11261126
1127// TODO https://github.com/ziglang/zig/issues/2651127// 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}
12151215
1216pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize {1216pub 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}
12191219
1220pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {1220pub 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}
12231223
1224pub fn timerfd_create(clockid: i32, flags: u32) usize {1224pub 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}
12271227
1228pub const itimerspec = extern struct {1228pub const itimerspec = extern struct {
...@@ -1231,11 +1231,11 @@ pub const itimerspec = extern struct {...@@ -1231,11 +1231,11 @@ pub const itimerspec = extern struct {
1231};1231};
12321232
1233pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize {1233pub 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}
12361236
1237pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize {1237pub 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}
12401240
1241pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;1241pub 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};
13461346
1347pub fn unshare(flags: usize) usize {1347pub fn unshare(flags: usize) usize {
1348 return syscall1(SYS_unshare, usize(flags));1348 return syscall1(SYS_unshare, @intCast(usize, flags));
1349}1349}
13501350
1351pub fn capget(hdrp: *cap_user_header_t, datap: *cap_user_data_t) usize {1351pub 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 };
2323
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);
2626
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 };
3131
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);
3434
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;
3737
38 // TODO implicit cast from *[N]T to [*]T38 // 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 {
6262
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");
14pub fn sleep(seconds: usize, nanoseconds: usize) void {14pub 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}
9090
...@@ -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}
102102
...@@ -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);
167167
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 call174 //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);
188188
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 }
241241
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};
253253
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};
4343
44pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) WriteError!void {44pub 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);
7070
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 }
7479
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 ints60 // 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);
214214
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);
217217
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 }
220220
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}
668668
669fn testRange(r: *Random, start: i32, end: i32) void {669fn 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 }
105105
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 capacity158 /// 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 capacity175 /// 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 }
184184
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 }
352352
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}
8585
86fn callMain() u8 {86fn 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;
142142
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);
231231
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);
234234
235 // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = nan235 // 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 }
248248
249 // normalize x249 // normalize x
250 var m = i32(ix0 >> 20);250 var m = @intCast(i32, ix0 >> 20);
251 if (m == 0) {251 if (m == 0) {
252 // subnormal252 // 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 }
268268
269 // unbias exponent269 // unbias exponent
...@@ -347,10 +347,10 @@ export fn sqrt(x: f64) f64 {...@@ -347,10 +347,10 @@ export fn sqrt(x: f64) f64 {
347347
348 // NOTE: musl here appears to rely on signed twos-complement wraparound. +% has the same348 // 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);
352352
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}
356356
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 {
9191
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 {
1313
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}
1818
19pub extern fn __divti3_windows_x86_64(a: *const i128, b: *const i128) void {19pub 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;
3333
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;
3737
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;
4040
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);
4343
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 line48 // 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 line53 // 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);
293293
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}
298298
...@@ -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 - 1317 // 1 <= sr <= n_uword_bits - 1
318 // Not a special case318 // 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) | carry323 // 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 #42172 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 K76 // 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 - 188 // 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] != 096 // 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 #421112 return @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421
113 }113 }
114 // K X114 // 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 - 1127 // 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 - 1133 // 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 X140 // 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 #421186 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 #421190 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 time35 // - Increasing the initial shift by 6 each time
36 // - Each time after the first shorten the shifted36 // - 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 range38 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" {
8test "cast bool to int" {8test "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}
1515
16fn nonConstCastBoolToInt(t: bool, f: bool) void {16fn 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}
2020
21test "bool cmp" {21test "bool cmp" {
test/cases/byval_arg_var.zig created+27
...@@ -0,0 +1,27 @@
1const std = @import("std");
2
3var result: []const u8 = "wrong";
4
5test "aoeu" {
6 start();
7 blowUpStack(10);
8
9 std.debug.assert(std.mem.eql(u8, result, "string literal"));
10}
11
12fn start() void {
13 foo("string literal");
14}
15
16fn foo(x: var) void {
17 bar(x);
18}
19
20fn bar(x: var) void {
21 result = x;
22}
23
24fn 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}
320320
321test "var args implicitly casts by value arg to const ref" {
322 foo("hello");
323}
324
325fn foo(args: ...) void {
326 assert(@typeOf(args[0]) == *const [5]u8);
327}
328
329test "peer type resolution: error and [N]T" {321test "peer type resolution: error and [N]T" {
330 // TODO: implicit error!T to error!U where T can implicitly cast to U322 // 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 {
351test "explicit cast float number literal to integer if no fraction component" {343test "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}
357349
...@@ -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
402test "@intCast comptime_int" {
403 const result = @intCast(i32, 1234);
404 assert(@typeOf(result) == i32);
405 assert(result == 1234);
406}
407
408test "@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
418test "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}
101fn testIntToEnumEval(x: i32) void {101fn testIntToEnumEval(x: i32) void {
102 assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three);102 assert(IntToEnumNumber(@intCast(u3, x)) == IntToEnumNumber.Three);
103}103}
104const IntToEnumNumber = enum {104const 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");
5test "compile time recursion" {5test "compile time recursion" {
6 assert(some_data.len == 21);6 assert(some_data.len == 21);
7}7}
8var some_data: [usize(fibonacci(7))]u8 = undefined;8var some_data: [@intCast(usize, fibonacci(7))]u8 = undefined;
9fn fibonacci(x: i32) i32 {9fn 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: {
356test "compile-time downcast when the bits fit" {356test "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;
441441
442 for (b) |*r, i|442 for (b) |*r, i|
443 r.* = u8(i + 1);443 r.* = @intCast(u8, i + 1);
444444
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}
86fn fn1() u32 {86fn 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}
120120
121inline fn inlineFn() void {}121inline fn inlineFn() void {}
122
123test "pass by non-copying value" {
124 assert(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);
125}
126
127const Point = struct {
128 x: i32,
129 y: i32,
130};
131
132fn addPointCoords(pt: Point) i32 {
133 return pt.x + pt.y;
134}
135
136test "pass by non-copying value through var arg" {
137 assert(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3);
138}
139
140fn addPointCoordsVar(pt: var) i32 {
141 comptime assert(@typeOf(pt) == Point);
142 return pt.x + pt.y;
143}
144
145test "pass by non-copying value as method" {
146 var pt = Point2{ .x = 1, .y = 2 };
147 assert(pt.addPointCoords() == 3);
148}
149
150const Point2 = struct {
151 x: i32,
152 y: i32,
153
154 fn addPointCoords(self: Point2) i32 {
155 return self.x + self.y;
156 }
157};
158
159test "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
164const 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
173test "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 }
6161
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 };
371371
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}
377377
378var x1 = u4(1);378var 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}
7777
78test "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
84fn assertSlicePtrsEql(args: ...) void {
85 const s1 = ([]const u8)(args[0]);
86 const s2 = args[1];
87 assert(s1.ptr == s2.ptr);
88}
89
90test "pass zero length array to var args param" {78test "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 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub 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 );
22202238
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 });
25752593
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 );
29482957
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 );
29802989
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 );
40684077
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 );
194194
...@@ -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 );
207207
test/standalone/load_dynamic_library/add.zig created+3
...@@ -0,0 +1,3 @@
1export 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 @@
1const Builder = @import("std").build.Builder;
2
3pub 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 @@
1const std = @import("std");
2
3pub 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}