| author | |
| committer | |
| log | 5a8d87f5042b5ab86de7c72df4ce84a314878e40 |
| tree | d9a8e14011994c5ebdf4525ea5c5b647aae91a6e |
| parent | 38658a597bc22697c2038c21bdec9f04c9973eb8 |
| parent | 598170756cd91b6f300921d256baa72141ec3098 |
64 files changed, 1564 insertions(+), 1165 deletions(-)
CMakeLists.txt+1| ... | @@ -440,6 +440,7 @@ set(ZIG_STD_FILES | ... | @@ -440,6 +440,7 @@ set(ZIG_STD_FILES |
| 440 | "os/windows/error.zig" | 440 | "os/windows/error.zig" |
| 441 | "os/windows/index.zig" | 441 | "os/windows/index.zig" |
| 442 | "os/windows/util.zig" | 442 | "os/windows/util.zig" |
| 443 | "os/zen.zig" | ||
| 443 | "rand.zig" | 444 | "rand.zig" |
| 444 | "sort.zig" | 445 | "sort.zig" |
| 445 | "special/bootstrap.zig" | 446 | "special/bootstrap.zig" |
doc/docgen.zig+1-1| ... | @@ -45,7 +45,7 @@ const State = enum { | ... | @@ -45,7 +45,7 @@ const State = enum { |
| 45 | fn gen(in: &io.InStream, out: &io.OutStream) { | 45 | fn gen(in: &io.InStream, out: &io.OutStream) { |
| 46 | var state = State.Start; | 46 | var state = State.Start; |
| 47 | while (true) { | 47 | while (true) { |
| 48 | const byte = in.readByte() %% |err| { | 48 | const byte = in.readByte() catch |err| { |
| 49 | if (err == error.EndOfStream) { | 49 | if (err == error.EndOfStream) { |
| 50 | return; | 50 | return; |
| 51 | } | 51 | } |
doc/home.html.in+18-18| ... | @@ -75,10 +75,10 @@ | ... | @@ -75,10 +75,10 @@ |
| 75 | 75 | ||
| 76 | pub fn main() -> %void { | 76 | pub fn main() -> %void { |
| 77 | // If this program is run without stdout attached, exit with an error. | 77 | // If this program is run without stdout attached, exit with an error. |
| 78 | var stdout_file = %return std.io.getStdOut(); | 78 | var stdout_file = try std.io.getStdOut(); |
| 79 | // If this program encounters pipe failure when printing to stdout, exit | 79 | // If this program encounters pipe failure when printing to stdout, exit |
| 80 | // with an error. | 80 | // with an error. |
| 81 | %return stdout_file.write("Hello, world!\n"); | 81 | try stdout_file.write("Hello, world!\n"); |
| 82 | }</code></pre> | 82 | }</code></pre> |
| 83 | <p>Build this with:</p> | 83 | <p>Build this with:</p> |
| 84 | <pre>zig build-exe hello.zig</pre> | 84 | <pre>zig build-exe hello.zig</pre> |
| ... | @@ -105,9 +105,9 @@ export fn main(argc: c_int, argv: &amp;&amp;u8) -&gt; c_int { | ... | @@ -105,9 +105,9 @@ export fn main(argc: c_int, argv: &amp;&amp;u8) -&gt; c_int { |
| 105 | var x: T = 0; | 105 | var x: T = 0; |
| 106 | 106 | ||
| 107 | for (buf) |c| { | 107 | for (buf) |c| { |
| 108 | const digit = %return charToDigit(c, radix); | 108 | const digit = try charToDigit(c, radix); |
| 109 | x = %return mulOverflow(T, x, radix); | 109 | x = try mulOverflow(T, x, radix); |
| 110 | x = %return addOverflow(T, x, digit); | 110 | x = try addOverflow(T, x, digit); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | return x; | 113 | return x; |
| ... | @@ -142,7 +142,7 @@ pub fn addOverflow(comptime T: type, a: T, b: T) -&gt; %T { | ... | @@ -142,7 +142,7 @@ pub fn addOverflow(comptime T: type, a: T, b: T) -&gt; %T { |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | fn getNumberWithDefault(s: []u8) -&gt; u32 { | 144 | fn getNumberWithDefault(s: []u8) -&gt; u32 { |
| 145 | parseUnsigned(u32, s, 10) %% 42 | 145 | parseUnsigned(u32, s, 10) catch 42 |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | fn getNumberOrCrash(s: []u8) -&gt; u32 { | 148 | fn getNumberOrCrash(s: []u8) -&gt; u32 { |
| ... | @@ -150,8 +150,8 @@ fn getNumberOrCrash(s: []u8) -&gt; u32 { | ... | @@ -150,8 +150,8 @@ fn getNumberOrCrash(s: []u8) -&gt; u32 { |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | fn addTwoTogetherOrReturnErr(a_str: []u8, b_str: []u8) -&gt; %u32 { | 152 | fn addTwoTogetherOrReturnErr(a_str: []u8, b_str: []u8) -&gt; %u32 { |
| 153 | const a = parseUnsigned(u32, a_str, 10) %% |err| return err; | 153 | const a = parseUnsigned(u32, a_str, 10) catch |err| return err; |
| 154 | const b = parseUnsigned(u32, b_str, 10) %% |err| return err; | 154 | const b = parseUnsigned(u32, b_str, 10) catch |err| return err; |
| 155 | return a + b; | 155 | return a + b; |
| 156 | }</code></pre> | 156 | }</code></pre> |
| 157 | <h3 id="hashmap">HashMap with Custom Allocator</h3> | 157 | <h3 id="hashmap">HashMap with Custom Allocator</h3> |
| ... | @@ -234,14 +234,14 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)-&gt | ... | @@ -234,14 +234,14 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)-&gt |
| 234 | 234 | ||
| 235 | pub fn put(hm: &amp;Self, key: K, value: V) -&gt; %void { | 235 | pub fn put(hm: &amp;Self, key: K, value: V) -&gt; %void { |
| 236 | if (hm.entries.len == 0) { | 236 | if (hm.entries.len == 0) { |
| 237 | %return hm.initCapacity(16); | 237 | try hm.initCapacity(16); |
| 238 | } | 238 | } |
| 239 | hm.incrementModificationCount(); | 239 | hm.incrementModificationCount(); |
| 240 | 240 | ||
| 241 | // if we get too full (60%), double the capacity | 241 | // if we get too full (60%), double the capacity |
| 242 | if (hm.size * 5 &gt;= hm.entries.len * 3) { | 242 | if (hm.size * 5 &gt;= hm.entries.len * 3) { |
| 243 | const old_entries = hm.entries; | 243 | const old_entries = hm.entries; |
| 244 | %return hm.initCapacity(hm.entries.len * 2); | 244 | try hm.initCapacity(hm.entries.len * 2); |
| 245 | // dump all of the old elements into the new table | 245 | // dump all of the old elements into the new table |
| 246 | for (old_entries) |*old_entry| { | 246 | for (old_entries) |*old_entry| { |
| 247 | if (old_entry.used) { | 247 | if (old_entry.used) { |
| ... | @@ -296,7 +296,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)-&gt | ... | @@ -296,7 +296,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)-&gt |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | fn initCapacity(hm: &amp;Self, capacity: usize) -&gt; %void { | 298 | fn initCapacity(hm: &amp;Self, capacity: usize) -&gt; %void { |
| 299 | hm.entries = %return hm.allocator.alloc(Entry, capacity); | 299 | hm.entries = try hm.allocator.alloc(Entry, capacity); |
| 300 | hm.size = 0; | 300 | hm.size = 0; |
| 301 | hm.max_distance_from_start_index = 0; | 301 | hm.max_distance_from_start_index = 0; |
| 302 | for (hm.entries) |*entry| { | 302 | for (hm.entries) |*entry| { |
| ... | @@ -420,24 +420,24 @@ pub fn main() -&gt; %void { | ... | @@ -420,24 +420,24 @@ pub fn main() -&gt; %void { |
| 420 | const arg = os.args.at(arg_i); | 420 | const arg = os.args.at(arg_i); |
| 421 | if (mem.eql(u8, arg, "-")) { | 421 | if (mem.eql(u8, arg, "-")) { |
| 422 | catted_anything = true; | 422 | catted_anything = true; |
| 423 | %return cat_stream(&amp;io.stdin); | 423 | try cat_stream(&amp;io.stdin); |
| 424 | } else if (arg[0] == '-') { | 424 | } else if (arg[0] == '-') { |
| 425 | return usage(exe); | 425 | return usage(exe); |
| 426 | } else { | 426 | } else { |
| 427 | var is = io.InStream.open(arg, null) %% |err| { | 427 | var is = io.InStream.open(arg, null) catch |err| { |
| 428 | %%io.stderr.printf("Unable to open file: {}\n", @errorName(err)); | 428 | %%io.stderr.printf("Unable to open file: {}\n", @errorName(err)); |
| 429 | return err; | 429 | return err; |
| 430 | }; | 430 | }; |
| 431 | defer is.close(); | 431 | defer is.close(); |
| 432 | 432 | ||
| 433 | catted_anything = true; | 433 | catted_anything = true; |
| 434 | %return cat_stream(&amp;is); | 434 | try cat_stream(&amp;is); |
| 435 | } | 435 | } |
| 436 | } | 436 | } |
| 437 | if (!catted_anything) { | 437 | if (!catted_anything) { |
| 438 | %return cat_stream(&amp;io.stdin); | 438 | try cat_stream(&amp;io.stdin); |
| 439 | } | 439 | } |
| 440 | %return io.stdout.flush(); | 440 | try io.stdout.flush(); |
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | fn usage(exe: []const u8) -&gt; %void { | 443 | fn usage(exe: []const u8) -&gt; %void { |
| ... | @@ -449,7 +449,7 @@ fn cat_stream(is: &amp;io.InStream) -&gt; %void { | ... | @@ -449,7 +449,7 @@ fn cat_stream(is: &amp;io.InStream) -&gt; %void { |
| 449 | var buf: [1024 * 4]u8 = undefined; | 449 | var buf: [1024 * 4]u8 = undefined; |
| 450 | 450 | ||
| 451 | while (true) { | 451 | while (true) { |
| 452 | const bytes_read = is.read(buf[0..]) %% |err| { | 452 | const bytes_read = is.read(buf[0..]) catch |err| { |
| 453 | %%io.stderr.printf("Unable to read from stream: {}\n", @errorName(err)); | 453 | %%io.stderr.printf("Unable to read from stream: {}\n", @errorName(err)); |
| 454 | return err; | 454 | return err; |
| 455 | }; | 455 | }; |
| ... | @@ -458,7 +458,7 @@ fn cat_stream(is: &amp;io.InStream) -&gt; %void { | ... | @@ -458,7 +458,7 @@ fn cat_stream(is: &amp;io.InStream) -&gt; %void { |
| 458 | break; | 458 | break; |
| 459 | } | 459 | } |
| 460 | 460 | ||
| 461 | io.stdout.write(buf[0..bytes_read]) %% |err| { | 461 | io.stdout.write(buf[0..bytes_read]) catch |err| { |
| 462 | %%io.stderr.printf("Unable to write to stdout: {}\n", @errorName(err)); | 462 | %%io.stderr.printf("Unable to write to stdout: {}\n", @errorName(err)); |
| 463 | return err; | 463 | return err; |
| 464 | }; | 464 | }; |
doc/langref.html.in+40-39| ... | @@ -264,15 +264,14 @@ | ... | @@ -264,15 +264,14 @@ |
| 264 | please <a href="https://github.com/zig-lang/www.ziglang.org/issues/new?title=I%20searched%20for%20___%20in%20the%20docs%20and%20didn%27t%20find%20it">file an issue</a> or <a href="https://webchat.freenode.net/?channels=%23zig">say something on IRC</a>. | 264 | please <a href="https://github.com/zig-lang/www.ziglang.org/issues/new?title=I%20searched%20for%20___%20in%20the%20docs%20and%20didn%27t%20find%20it">file an issue</a> or <a href="https://webchat.freenode.net/?channels=%23zig">say something on IRC</a>. |
| 265 | </p> | 265 | </p> |
| 266 | <h2 id="hello-world">Hello World</h2> | 266 | <h2 id="hello-world">Hello World</h2> |
| 267 | <pre><code class="zig">const io = @import("std").io; | 267 | <pre><code class="zig">const std = @import("std"); |
| 268 | 268 | ||
| 269 | pub fn main() -&gt; %void { | 269 | pub fn main() -&gt; %void { |
| 270 | // If this program is run without stdout attached, exit with an error. | 270 | // If this program is run without stdout attached, exit with an error. |
| 271 | var stdout_file = %return io.getStdOut(); | 271 | var stdout_file = try std.io.getStdOut(); |
| 272 | const stdout = &amp;stdout_file.out_stream; | ||
| 273 | // If this program encounters pipe failure when printing to stdout, exit | 272 | // If this program encounters pipe failure when printing to stdout, exit |
| 274 | // with an error. | 273 | // with an error. |
| 275 | %return stdout.print("Hello, world!\n"); | 274 | try stdout_file.write("Hello, world!\n"); |
| 276 | }</code></pre> | 275 | }</code></pre> |
| 277 | <pre><code class="sh">$ zig build-exe hello.zig | 276 | <pre><code class="sh">$ zig build-exe hello.zig |
| 278 | $ ./hello | 277 | $ ./hello |
| ... | @@ -1212,8 +1211,8 @@ unwrapped == 1234</code></pre> | ... | @@ -1212,8 +1211,8 @@ unwrapped == 1234</code></pre> |
| 1212 | </td> | 1211 | </td> |
| 1213 | </tr> | 1212 | </tr> |
| 1214 | <tr> | 1213 | <tr> |
| 1215 | <td><pre><code class="zig">a %% b | 1214 | <td><pre><code class="zig">a catch b |
| 1216 | a %% |err| b</code></pre></td> | 1215 | a catch |err| b</code></pre></td> |
| 1217 | <td> | 1216 | <td> |
| 1218 | <ul> | 1217 | <ul> |
| 1219 | <li><a href="#errors">Error Unions</a></li> | 1218 | <li><a href="#errors">Error Unions</a></li> |
| ... | @@ -1227,7 +1226,7 @@ a %% |err| b</code></pre></td> | ... | @@ -1227,7 +1226,7 @@ a %% |err| b</code></pre></td> |
| 1227 | </td> | 1226 | </td> |
| 1228 | <td> | 1227 | <td> |
| 1229 | <pre><code class="zig">const value: %u32 = null; | 1228 | <pre><code class="zig">const value: %u32 = null; |
| 1230 | const unwrapped = value %% 1234; | 1229 | const unwrapped = value catch 1234; |
| 1231 | unwrapped == 1234</code></pre> | 1230 | unwrapped == 1234</code></pre> |
| 1232 | </td> | 1231 | </td> |
| 1233 | </tr> | 1232 | </tr> |
| ... | @@ -1239,7 +1238,7 @@ unwrapped == 1234</code></pre> | ... | @@ -1239,7 +1238,7 @@ unwrapped == 1234</code></pre> |
| 1239 | </ul> | 1238 | </ul> |
| 1240 | </td> | 1239 | </td> |
| 1241 | <td>Equivalent to: | 1240 | <td>Equivalent to: |
| 1242 | <pre><code class="zig">a %% unreachable</code></pre> | 1241 | <pre><code class="zig">a catch unreachable</code></pre> |
| 1243 | </td> | 1242 | </td> |
| 1244 | <td> | 1243 | <td> |
| 1245 | <pre><code class="zig">const value: %u32 = 5678; | 1244 | <pre><code class="zig">const value: %u32 = 5678; |
| ... | @@ -1483,7 +1482,7 @@ x{} | ... | @@ -1483,7 +1482,7 @@ x{} |
| 1483 | == != &lt; &gt; &lt;= &gt;= | 1482 | == != &lt; &gt; &lt;= &gt;= |
| 1484 | and | 1483 | and |
| 1485 | or | 1484 | or |
| 1486 | ?? %% | 1485 | ?? catch |
| 1487 | = *= /= %= += -= &lt;&lt;= &gt;&gt;= &amp;= ^= |=</code></pre> | 1486 | = *= /= %= += -= &lt;&lt;= &gt;&gt;= &amp;= ^= |=</code></pre> |
| 1488 | <h2 id="arrays">Arrays</h2> | 1487 | <h2 id="arrays">Arrays</h2> |
| 1489 | <pre><code class="zig">const assert = @import("std").debug.assert; | 1488 | <pre><code class="zig">const assert = @import("std").debug.assert; |
| ... | @@ -1830,7 +1829,7 @@ Test 1/1 pointer alignment safety...incorrect alignment | ... | @@ -1830,7 +1829,7 @@ Test 1/1 pointer alignment safety...incorrect alignment |
| 1830 | return root.main(); | 1829 | return root.main(); |
| 1831 | ^ | 1830 | ^ |
| 1832 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000216050 in ??? (test) | 1831 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000216050 in ??? (test) |
| 1833 | callMain(argc, argv, envp) %% std.os.posix.exit(1); | 1832 | callMain(argc, argv, envp) catch std.os.posix.exit(1); |
| 1834 | ^ | 1833 | ^ |
| 1835 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000215fa0 in ??? (test) | 1834 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000215fa0 in ??? (test) |
| 1836 | posixCallMainAndExit() | 1835 | posixCallMainAndExit() |
| ... | @@ -1886,7 +1885,7 @@ lib/zig/std/special/bootstrap.zig:60:21: 0x00000000002149e7 in ??? (test) | ... | @@ -1886,7 +1885,7 @@ lib/zig/std/special/bootstrap.zig:60:21: 0x00000000002149e7 in ??? (test) |
| 1886 | return root.main(); | 1885 | return root.main(); |
| 1887 | ^ | 1886 | ^ |
| 1888 | lib/zig/std/special/bootstrap.zig:47:13: 0x00000000002148a0 in ??? (test) | 1887 | lib/zig/std/special/bootstrap.zig:47:13: 0x00000000002148a0 in ??? (test) |
| 1889 | callMain(argc, argv, envp) %% std.os.posix.exit(1); | 1888 | callMain(argc, argv, envp) catch std.os.posix.exit(1); |
| 1890 | ^ | 1889 | ^ |
| 1891 | lib/zig/std/special/bootstrap.zig:34:25: 0x00000000002147f0 in ??? (test) | 1890 | lib/zig/std/special/bootstrap.zig:34:25: 0x00000000002147f0 in ??? (test) |
| 1892 | posixCallMainAndExit() | 1891 | posixCallMainAndExit() |
| ... | @@ -2966,7 +2965,7 @@ lib/zig/std/special/bootstrap.zig:60:21: 0x0000000000214947 in ??? (test) | ... | @@ -2966,7 +2965,7 @@ lib/zig/std/special/bootstrap.zig:60:21: 0x0000000000214947 in ??? (test) |
| 2966 | return root.main(); | 2965 | return root.main(); |
| 2967 | ^ | 2966 | ^ |
| 2968 | lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000214800 in ??? (test) | 2967 | lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000214800 in ??? (test) |
| 2969 | callMain(argc, argv, envp) %% std.os.posix.exit(1); | 2968 | callMain(argc, argv, envp) catch std.os.posix.exit(1); |
| 2970 | ^ | 2969 | ^ |
| 2971 | lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000214750 in ??? (test) | 2970 | lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000214750 in ??? (test) |
| 2972 | posixCallMainAndExit() | 2971 | posixCallMainAndExit() |
| ... | @@ -3020,7 +3019,7 @@ extern fn bar(value: u32);</code></pre> | ... | @@ -3020,7 +3019,7 @@ extern fn bar(value: u32);</code></pre> |
| 3020 | <pre><code class="zig">pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: c_uint) -&gt; noreturn; | 3019 | <pre><code class="zig">pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: c_uint) -&gt; noreturn; |
| 3021 | 3020 | ||
| 3022 | fn foo() { | 3021 | fn foo() { |
| 3023 | const value = bar() %% ExitProcess(1); | 3022 | const value = bar() catch ExitProcess(1); |
| 3024 | assert(value == 1234); | 3023 | assert(value == 1234); |
| 3025 | } | 3024 | } |
| 3026 | 3025 | ||
| ... | @@ -3210,7 +3209,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { | ... | @@ -3210,7 +3209,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3210 | </ul> | 3209 | </ul> |
| 3211 | <p>If you want to provide a default value, you can use the <code>%%</code> binary operator:</p> | 3210 | <p>If you want to provide a default value, you can use the <code>%%</code> binary operator:</p> |
| 3212 | <pre><code class="zig">fn doAThing(str: []u8) { | 3211 | <pre><code class="zig">fn doAThing(str: []u8) { |
| 3213 | const number = parseU64(str, 10) %% 13; | 3212 | const number = parseU64(str, 10) catch 13; |
| 3214 | // ... | 3213 | // ... |
| 3215 | }</code></pre> | 3214 | }</code></pre> |
| 3216 | <p> | 3215 | <p> |
| ... | @@ -3221,18 +3220,18 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { | ... | @@ -3221,18 +3220,18 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3221 | <p>Let's say you wanted to return the error if you got one, otherwise continue with the | 3220 | <p>Let's say you wanted to return the error if you got one, otherwise continue with the |
| 3222 | function logic:</p> | 3221 | function logic:</p> |
| 3223 | <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void { | 3222 | <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void { |
| 3224 | const number = parseU64(str, 10) %% |err| return err; | 3223 | const number = parseU64(str, 10) catch |err| return err; |
| 3225 | // ... | 3224 | // ... |
| 3226 | }</code></pre> | 3225 | }</code></pre> |
| 3227 | <p> | 3226 | <p> |
| 3228 | There is a shortcut for this. The <code>%return</code> expression: | 3227 | There is a shortcut for this. The <code>try</code> expression: |
| 3229 | </p> | 3228 | </p> |
| 3230 | <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void { | 3229 | <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void { |
| 3231 | const number = %return parseU64(str, 10); | 3230 | const number = try parseU64(str, 10); |
| 3232 | // ... | 3231 | // ... |
| 3233 | }</code></pre> | 3232 | }</code></pre> |
| 3234 | <p> | 3233 | <p> |
| 3235 | <code>%return</code> evaluates an error union expression. If it is an error, it returns | 3234 | <code>try</code> evaluates an error union expression. If it is an error, it returns |
| 3236 | from the current function with the same error. Otherwise, the expression results in | 3235 | from the current function with the same error. Otherwise, the expression results in |
| 3237 | the unwrapped value. | 3236 | the unwrapped value. |
| 3238 | </p> | 3237 | </p> |
| ... | @@ -3240,7 +3239,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { | ... | @@ -3240,7 +3239,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3240 | Maybe you know with complete certainty that an expression will never be an error. | 3239 | Maybe you know with complete certainty that an expression will never be an error. |
| 3241 | In this case you can do this: | 3240 | In this case you can do this: |
| 3242 | </p> | 3241 | </p> |
| 3243 | <pre><code class="zig">const number = parseU64("1234", 10) %% unreachable;</code></pre> | 3242 | <pre><code class="zig">const number = parseU64("1234", 10) catch unreachable;</code></pre> |
| 3244 | <p> | 3243 | <p> |
| 3245 | Here we know for sure that "1234" will parse successfully. So we put the | 3244 | Here we know for sure that "1234" will parse successfully. So we put the |
| 3246 | <code>unreachable</code> value on the right hand side. <code>unreachable</code> generates | 3245 | <code>unreachable</code> value on the right hand side. <code>unreachable</code> generates |
| ... | @@ -3251,7 +3250,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { | ... | @@ -3251,7 +3250,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3251 | <p>Again there is a syntactic shortcut for this:</p> | 3250 | <p>Again there is a syntactic shortcut for this:</p> |
| 3252 | <pre><code class="zig">const number = %%parseU64("1234", 10);</code></pre> | 3251 | <pre><code class="zig">const number = %%parseU64("1234", 10);</code></pre> |
| 3253 | <p> | 3252 | <p> |
| 3254 | The <code>%%</code> <em>prefix</em> operator is equivalent to <code class="zig">expression %% unreachable</code>. It unwraps an error union type, | 3253 | The <code>%%</code> <em>prefix</em> operator is equivalent to <code class="zig">expression catch unreachable</code>. It unwraps an error union type, |
| 3255 | and panics in debug mode if the value was an error. | 3254 | and panics in debug mode if the value was an error. |
| 3256 | </p> | 3255 | </p> |
| 3257 | <p> | 3256 | <p> |
| ... | @@ -3279,7 +3278,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { | ... | @@ -3279,7 +3278,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3279 | Example: | 3278 | Example: |
| 3280 | </p> | 3279 | </p> |
| 3281 | <pre><code class="zig">fn createFoo(param: i32) -&gt; %Foo { | 3280 | <pre><code class="zig">fn createFoo(param: i32) -&gt; %Foo { |
| 3282 | const foo = %return tryToAllocateFoo(); | 3281 | const foo = try tryToAllocateFoo(); |
| 3283 | // now we have allocated foo. we need to free it if the function fails. | 3282 | // now we have allocated foo. we need to free it if the function fails. |
| 3284 | // but we want to return it if the function succeeds. | 3283 | // but we want to return it if the function succeeds. |
| 3285 | %defer deallocateFoo(foo); | 3284 | %defer deallocateFoo(foo); |
| ... | @@ -3929,11 +3928,11 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt | ... | @@ -3929,11 +3928,11 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt |
| 3929 | switch (state) { | 3928 | switch (state) { |
| 3930 | State.Start =&gt; switch (c) { | 3929 | State.Start =&gt; switch (c) { |
| 3931 | '{' =&gt; { | 3930 | '{' =&gt; { |
| 3932 | if (start_index &lt; i) %return self.write(format[start_index...i]); | 3931 | if (start_index &lt; i) try self.write(format[start_index...i]); |
| 3933 | state = State.OpenBrace; | 3932 | state = State.OpenBrace; |
| 3934 | }, | 3933 | }, |
| 3935 | '}' =&gt; { | 3934 | '}' =&gt; { |
| 3936 | if (start_index &lt; i) %return self.write(format[start_index...i]); | 3935 | if (start_index &lt; i) try self.write(format[start_index...i]); |
| 3937 | state = State.CloseBrace; | 3936 | state = State.CloseBrace; |
| 3938 | }, | 3937 | }, |
| 3939 | else =&gt; {}, | 3938 | else =&gt; {}, |
| ... | @@ -3944,7 +3943,7 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt | ... | @@ -3944,7 +3943,7 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt |
| 3944 | start_index = i; | 3943 | start_index = i; |
| 3945 | }, | 3944 | }, |
| 3946 | '}' =&gt; { | 3945 | '}' =&gt; { |
| 3947 | %return self.printValue(args[next_arg]); | 3946 | try self.printValue(args[next_arg]); |
| 3948 | next_arg += 1; | 3947 | next_arg += 1; |
| 3949 | state = State.Start; | 3948 | state = State.Start; |
| 3950 | start_index = i + 1; | 3949 | start_index = i + 1; |
| ... | @@ -3969,9 +3968,9 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt | ... | @@ -3969,9 +3968,9 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt |
| 3969 | } | 3968 | } |
| 3970 | } | 3969 | } |
| 3971 | if (start_index &lt; format.len) { | 3970 | if (start_index &lt; format.len) { |
| 3972 | %return self.write(format[start_index...format.len]); | 3971 | try self.write(format[start_index...format.len]); |
| 3973 | } | 3972 | } |
| 3974 | %return self.flush(); | 3973 | try self.flush(); |
| 3975 | }</code></pre> | 3974 | }</code></pre> |
| 3976 | <p> | 3975 | <p> |
| 3977 | This is a proof of concept implementation; the actual function in the standard library has more | 3976 | This is a proof of concept implementation; the actual function in the standard library has more |
| ... | @@ -3985,12 +3984,12 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt | ... | @@ -3985,12 +3984,12 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt |
| 3985 | and emits a function that actually looks like this: | 3984 | and emits a function that actually looks like this: |
| 3986 | </p> | 3985 | </p> |
| 3987 | <pre><code class="zig">pub fn printf(self: &amp;OutStream, arg0: i32, arg1: []const u8) -&gt; %void { | 3986 | <pre><code class="zig">pub fn printf(self: &amp;OutStream, arg0: i32, arg1: []const u8) -&gt; %void { |
| 3988 | %return self.write("here is a string: '"); | 3987 | try self.write("here is a string: '"); |
| 3989 | %return self.printValue(arg0); | 3988 | try self.printValue(arg0); |
| 3990 | %return self.write("' here is a number: "); | 3989 | try self.write("' here is a number: "); |
| 3991 | %return self.printValue(arg1); | 3990 | try self.printValue(arg1); |
| 3992 | %return self.write("\n"); | 3991 | try self.write("\n"); |
| 3993 | %return self.flush(); | 3992 | try self.flush(); |
| 3994 | }</code></pre> | 3993 | }</code></pre> |
| 3995 | <p> | 3994 | <p> |
| 3996 | <code>printValue</code> is a function that takes a parameter of any type, and does different things depending | 3995 | <code>printValue</code> is a function that takes a parameter of any type, and does different things depending |
| ... | @@ -4985,7 +4984,7 @@ Test 1/1 safety check...reached unreachable code | ... | @@ -4985,7 +4984,7 @@ Test 1/1 safety check...reached unreachable code |
| 4985 | return root.main(); | 4984 | return root.main(); |
| 4986 | ^ | 4985 | ^ |
| 4987 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:37:13: 0x00000000002148d0 in ??? (test) | 4986 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:37:13: 0x00000000002148d0 in ??? (test) |
| 4988 | callMain(argc, argv, envp) %% exit(1); | 4987 | callMain(argc, argv, envp) catch exit(1); |
| 4989 | ^ | 4988 | ^ |
| 4990 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:30:20: 0x0000000000214820 in ??? (test) | 4989 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:30:20: 0x0000000000214820 in ??? (test) |
| 4991 | callMainAndExit() | 4990 | callMainAndExit() |
| ... | @@ -5892,7 +5891,7 @@ TypeExpr = PrefixOpExpression | "var" | ... | @@ -5892,7 +5891,7 @@ TypeExpr = PrefixOpExpression | "var" |
| 5892 | 5891 | ||
| 5893 | BlockOrExpression = Block | Expression | 5892 | BlockOrExpression = Block | Expression |
| 5894 | 5893 | ||
| 5895 | Expression = ReturnExpression | BreakExpression | AssignmentExpression | 5894 | Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression |
| 5896 | 5895 | ||
| 5897 | AsmExpression = "asm" option("volatile") "(" String option(AsmOutput) ")" | 5896 | AsmExpression = "asm" option("volatile") "(" String option(AsmOutput) ")" |
| 5898 | 5897 | ||
| ... | @@ -5910,13 +5909,13 @@ UnwrapExpression = BoolOrExpression (UnwrapNullable | UnwrapError) | BoolOrExpre | ... | @@ -5910,13 +5909,13 @@ UnwrapExpression = BoolOrExpression (UnwrapNullable | UnwrapError) | BoolOrExpre |
| 5910 | 5909 | ||
| 5911 | UnwrapNullable = "??" Expression | 5910 | UnwrapNullable = "??" Expression |
| 5912 | 5911 | ||
| 5913 | UnwrapError = "%%" option("|" Symbol "|") Expression | 5912 | UnwrapError = "catch" option("|" Symbol "|") Expression |
| 5914 | 5913 | ||
| 5915 | AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | UnwrapExpression | 5914 | AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | UnwrapExpression |
| 5916 | 5915 | ||
| 5917 | AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "&lt;&lt;=" | "&gt;&gt;=" | "&amp;=" | "^=" | "|=" | "*%=" | "+%=" | "-%=" | 5916 | AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "&lt;&lt;=" | "&gt;&gt;=" | "&amp;=" | "^=" | "|=" | "*%=" | "+%=" | "-%=" |
| 5918 | 5917 | ||
| 5919 | BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) | 5918 | BlockExpression(body) = Block | IfExpression(body) | IfErrorExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) |
| 5920 | 5919 | ||
| 5921 | CompTimeExpression(body) = "comptime" body | 5920 | CompTimeExpression(body) = "comptime" body |
| 5922 | 5921 | ||
| ... | @@ -5930,7 +5929,9 @@ ForExpression(body) = option(Symbol ":") option("inline") "for" "(" Expression " | ... | @@ -5930,7 +5929,9 @@ ForExpression(body) = option(Symbol ":") option("inline") "for" "(" Expression " |
| 5930 | 5929 | ||
| 5931 | BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression | 5930 | BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression |
| 5932 | 5931 | ||
| 5933 | ReturnExpression = option("%") "return" option(Expression) | 5932 | ReturnExpression = "return" option(Expression) |
| 5933 | |||
| 5934 | TryExpression = "try" Expression | ||
| 5934 | 5935 | ||
| 5935 | BreakExpression = "break" option(":" Symbol) option(Expression) | 5936 | BreakExpression = "break" option(":" Symbol) option(Expression) |
| 5936 | 5937 | ||
| ... | @@ -5938,7 +5939,7 @@ Defer(body) = option("%") "defer" body | ... | @@ -5938,7 +5939,7 @@ Defer(body) = option("%") "defer" body |
| 5938 | 5939 | ||
| 5939 | IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body)) | 5940 | IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body)) |
| 5940 | 5941 | ||
| 5941 | TryExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body) | 5942 | IfErrorExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body) |
| 5942 | 5943 | ||
| 5943 | TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body)) | 5944 | TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body)) |
| 5944 | 5945 | ||
| ... | @@ -5988,7 +5989,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",") | ... | @@ -5988,7 +5989,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",") |
| 5988 | 5989 | ||
| 5989 | StructLiteralField = "." Symbol "=" Expression | 5990 | StructLiteralField = "." Symbol "=" Expression |
| 5990 | 5991 | ||
| 5991 | PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | 5992 | PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | "try" |
| 5992 | 5993 | ||
| 5993 | PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl | ("continue" option(":" Symbol)) | 5994 | PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl | ("continue" option(":" Symbol)) |
| 5994 | 5995 |
example/cat/main.zig+12-12| ... | @@ -7,32 +7,32 @@ const allocator = std.debug.global_allocator; | ... | @@ -7,32 +7,32 @@ const allocator = std.debug.global_allocator; |
| 7 | 7 | ||
| 8 | pub fn main() -> %void { | 8 | pub fn main() -> %void { |
| 9 | var args_it = os.args(); | 9 | var args_it = os.args(); |
| 10 | const exe = %return unwrapArg(??args_it.next(allocator)); | 10 | const exe = try unwrapArg(??args_it.next(allocator)); |
| 11 | var catted_anything = false; | 11 | var catted_anything = false; |
| 12 | var stdout_file = %return io.getStdOut(); | 12 | var stdout_file = try io.getStdOut(); |
| 13 | 13 | ||
| 14 | while (args_it.next(allocator)) |arg_or_err| { | 14 | while (args_it.next(allocator)) |arg_or_err| { |
| 15 | const arg = %return unwrapArg(arg_or_err); | 15 | const arg = try unwrapArg(arg_or_err); |
| 16 | if (mem.eql(u8, arg, "-")) { | 16 | if (mem.eql(u8, arg, "-")) { |
| 17 | catted_anything = true; | 17 | catted_anything = true; |
| 18 | var stdin_file = %return io.getStdIn(); | 18 | var stdin_file = try io.getStdIn(); |
| 19 | %return cat_file(&stdout_file, &stdin_file); | 19 | try cat_file(&stdout_file, &stdin_file); |
| 20 | } else if (arg[0] == '-') { | 20 | } else if (arg[0] == '-') { |
| 21 | return usage(exe); | 21 | return usage(exe); |
| 22 | } else { | 22 | } else { |
| 23 | var file = io.File.openRead(arg, null) %% |err| { | 23 | var file = io.File.openRead(arg, null) catch |err| { |
| 24 | warn("Unable to open file: {}\n", @errorName(err)); | 24 | warn("Unable to open file: {}\n", @errorName(err)); |
| 25 | return err; | 25 | return err; |
| 26 | }; | 26 | }; |
| 27 | defer file.close(); | 27 | defer file.close(); |
| 28 | 28 | ||
| 29 | catted_anything = true; | 29 | catted_anything = true; |
| 30 | %return cat_file(&stdout_file, &file); | 30 | try cat_file(&stdout_file, &file); |
| 31 | } | 31 | } |
| 32 | } | 32 | } |
| 33 | if (!catted_anything) { | 33 | if (!catted_anything) { |
| 34 | var stdin_file = %return io.getStdIn(); | 34 | var stdin_file = try io.getStdIn(); |
| 35 | %return cat_file(&stdout_file, &stdin_file); | 35 | try cat_file(&stdout_file, &stdin_file); |
| 36 | } | 36 | } |
| 37 | } | 37 | } |
| 38 | 38 | ||
| ... | @@ -45,7 +45,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void { | ... | @@ -45,7 +45,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void { |
| 45 | var buf: [1024 * 4]u8 = undefined; | 45 | var buf: [1024 * 4]u8 = undefined; |
| 46 | 46 | ||
| 47 | while (true) { | 47 | while (true) { |
| 48 | const bytes_read = file.read(buf[0..]) %% |err| { | 48 | const bytes_read = file.read(buf[0..]) catch |err| { |
| 49 | warn("Unable to read from stream: {}\n", @errorName(err)); | 49 | warn("Unable to read from stream: {}\n", @errorName(err)); |
| 50 | return err; | 50 | return err; |
| 51 | }; | 51 | }; |
| ... | @@ -54,7 +54,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void { | ... | @@ -54,7 +54,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void { |
| 54 | break; | 54 | break; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | stdout.write(buf[0..bytes_read]) %% |err| { | 57 | stdout.write(buf[0..bytes_read]) catch |err| { |
| 58 | warn("Unable to write to stdout: {}\n", @errorName(err)); | 58 | warn("Unable to write to stdout: {}\n", @errorName(err)); |
| 59 | return err; | 59 | return err; |
| 60 | }; | 60 | }; |
| ... | @@ -62,7 +62,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void { | ... | @@ -62,7 +62,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void { |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | fn unwrapArg(arg: %[]u8) -> %[]u8 { | 64 | fn unwrapArg(arg: %[]u8) -> %[]u8 { |
| 65 | return arg %% |err| { | 65 | return arg catch |err| { |
| 66 | warn("Unable to parse command line: {}\n", err); | 66 | warn("Unable to parse command line: {}\n", err); |
| 67 | return err; | 67 | return err; |
| 68 | }; | 68 | }; |
example/guess_number/main.zig+11-11| ... | @@ -6,13 +6,13 @@ const Rand = std.rand.Rand; | ... | @@ -6,13 +6,13 @@ const Rand = std.rand.Rand; |
| 6 | const os = std.os; | 6 | const os = std.os; |
| 7 | 7 | ||
| 8 | pub fn main() -> %void { | 8 | pub fn main() -> %void { |
| 9 | var stdout_file = %return io.getStdOut(); | 9 | var stdout_file = try io.getStdOut(); |
| 10 | var stdout_file_stream = io.FileOutStream.init(&stdout_file); | 10 | var stdout_file_stream = io.FileOutStream.init(&stdout_file); |
| 11 | const stdout = &stdout_file_stream.stream; | 11 | const stdout = &stdout_file_stream.stream; |
| 12 | 12 | ||
| 13 | var stdin_file = %return io.getStdIn(); | 13 | var stdin_file = try io.getStdIn(); |
| 14 | 14 | ||
| 15 | %return stdout.print("Welcome to the Guess Number Game in Zig.\n"); | 15 | try stdout.print("Welcome to the Guess Number Game in Zig.\n"); |
| 16 | 16 | ||
| 17 | var seed_bytes: [@sizeOf(usize)]u8 = undefined; | 17 | var seed_bytes: [@sizeOf(usize)]u8 = undefined; |
| 18 | %%os.getRandomBytes(seed_bytes[0..]); | 18 | %%os.getRandomBytes(seed_bytes[0..]); |
| ... | @@ -22,24 +22,24 @@ pub fn main() -> %void { | ... | @@ -22,24 +22,24 @@ pub fn main() -> %void { |
| 22 | const answer = rand.range(u8, 0, 100) + 1; | 22 | const answer = rand.range(u8, 0, 100) + 1; |
| 23 | 23 | ||
| 24 | while (true) { | 24 | while (true) { |
| 25 | %return stdout.print("\nGuess a number between 1 and 100: "); | 25 | try stdout.print("\nGuess a number between 1 and 100: "); |
| 26 | var line_buf : [20]u8 = undefined; | 26 | var line_buf : [20]u8 = undefined; |
| 27 | 27 | ||
| 28 | const line_len = stdin_file.read(line_buf[0..]) %% |err| { | 28 | const line_len = stdin_file.read(line_buf[0..]) catch |err| { |
| 29 | %return stdout.print("Unable to read from stdin: {}\n", @errorName(err)); | 29 | try stdout.print("Unable to read from stdin: {}\n", @errorName(err)); |
| 30 | return err; | 30 | return err; |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | const guess = fmt.parseUnsigned(u8, line_buf[0..line_len - 1], 10) %% { | 33 | const guess = fmt.parseUnsigned(u8, line_buf[0..line_len - 1], 10) catch { |
| 34 | %return stdout.print("Invalid number.\n"); | 34 | try stdout.print("Invalid number.\n"); |
| 35 | continue; | 35 | continue; |
| 36 | }; | 36 | }; |
| 37 | if (guess > answer) { | 37 | if (guess > answer) { |
| 38 | %return stdout.print("Guess lower.\n"); | 38 | try stdout.print("Guess lower.\n"); |
| 39 | } else if (guess < answer) { | 39 | } else if (guess < answer) { |
| 40 | %return stdout.print("Guess higher.\n"); | 40 | try stdout.print("Guess higher.\n"); |
| 41 | } else { | 41 | } else { |
| 42 | %return stdout.print("You win!\n"); | 42 | try stdout.print("You win!\n"); |
| 43 | return; | 43 | return; |
| 44 | } | 44 | } |
| 45 | } | 45 | } |
example/hello_world/hello.zig+2-2| ... | @@ -2,8 +2,8 @@ const std = @import("std"); | ... | @@ -2,8 +2,8 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn main() -> %void { | 3 | pub fn main() -> %void { |
| 4 | // If this program is run without stdout attached, exit with an error. | 4 | // If this program is run without stdout attached, exit with an error. |
| 5 | var stdout_file = %return std.io.getStdOut(); | 5 | var stdout_file = try std.io.getStdOut(); |
| 6 | // If this program encounters pipe failure when printing to stdout, exit | 6 | // If this program encounters pipe failure when printing to stdout, exit |
| 7 | // with an error. | 7 | // with an error. |
| 8 | %return stdout_file.write("Hello, world!\n"); | 8 | try stdout_file.write("Hello, world!\n"); |
| 9 | } | 9 | } |
src-self-hosted/main.zig+42-42| ... | @@ -21,7 +21,7 @@ error ZigInstallationNotFound; | ... | @@ -21,7 +21,7 @@ error ZigInstallationNotFound; |
| 21 | const default_zig_cache_name = "zig-cache"; | 21 | const default_zig_cache_name = "zig-cache"; |
| 22 | 22 | ||
| 23 | pub fn main() -> %void { | 23 | pub fn main() -> %void { |
| 24 | main2() %% |err| { | 24 | main2() catch |err| { |
| 25 | if (err != error.InvalidCommandLineArguments) { | 25 | if (err != error.InvalidCommandLineArguments) { |
| 26 | warn("{}\n", @errorName(err)); | 26 | warn("{}\n", @errorName(err)); |
| 27 | } | 27 | } |
| ... | @@ -40,18 +40,18 @@ const Cmd = enum { | ... | @@ -40,18 +40,18 @@ const Cmd = enum { |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | fn badArgs(comptime format: []const u8, args: ...) -> error { | 42 | fn badArgs(comptime format: []const u8, args: ...) -> error { |
| 43 | var stderr = %return io.getStdErr(); | 43 | var stderr = try io.getStdErr(); |
| 44 | var stderr_stream_adapter = io.FileOutStream.init(&stderr); | 44 | var stderr_stream_adapter = io.FileOutStream.init(&stderr); |
| 45 | const stderr_stream = &stderr_stream_adapter.stream; | 45 | const stderr_stream = &stderr_stream_adapter.stream; |
| 46 | %return stderr_stream.print(format ++ "\n\n", args); | 46 | try stderr_stream.print(format ++ "\n\n", args); |
| 47 | %return printUsage(&stderr_stream_adapter.stream); | 47 | try printUsage(&stderr_stream_adapter.stream); |
| 48 | return error.InvalidCommandLineArguments; | 48 | return error.InvalidCommandLineArguments; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | pub fn main2() -> %void { | 51 | pub fn main2() -> %void { |
| 52 | const allocator = std.heap.c_allocator; | 52 | const allocator = std.heap.c_allocator; |
| 53 | 53 | ||
| 54 | const args = %return os.argsAlloc(allocator); | 54 | const args = try os.argsAlloc(allocator); |
| 55 | defer os.argsFree(allocator, args); | 55 | defer os.argsFree(allocator, args); |
| 56 | 56 | ||
| 57 | var cmd = Cmd.None; | 57 | var cmd = Cmd.None; |
| ... | @@ -167,7 +167,7 @@ pub fn main2() -> %void { | ... | @@ -167,7 +167,7 @@ pub fn main2() -> %void { |
| 167 | @panic("TODO --test-cmd-bin"); | 167 | @panic("TODO --test-cmd-bin"); |
| 168 | } else if (arg[1] == 'L' and arg.len > 2) { | 168 | } else if (arg[1] == 'L' and arg.len > 2) { |
| 169 | // alias for --library-path | 169 | // alias for --library-path |
| 170 | %return lib_dirs.append(arg[1..]); | 170 | try lib_dirs.append(arg[1..]); |
| 171 | } else if (mem.eql(u8, arg, "--pkg-begin")) { | 171 | } else if (mem.eql(u8, arg, "--pkg-begin")) { |
| 172 | @panic("TODO --pkg-begin"); | 172 | @panic("TODO --pkg-begin"); |
| 173 | } else if (mem.eql(u8, arg, "--pkg-end")) { | 173 | } else if (mem.eql(u8, arg, "--pkg-end")) { |
| ... | @@ -217,24 +217,24 @@ pub fn main2() -> %void { | ... | @@ -217,24 +217,24 @@ pub fn main2() -> %void { |
| 217 | } else if (mem.eql(u8, arg, "--dynamic-linker")) { | 217 | } else if (mem.eql(u8, arg, "--dynamic-linker")) { |
| 218 | dynamic_linker_arg = args[arg_i]; | 218 | dynamic_linker_arg = args[arg_i]; |
| 219 | } else if (mem.eql(u8, arg, "-isystem")) { | 219 | } else if (mem.eql(u8, arg, "-isystem")) { |
| 220 | %return clang_argv.append("-isystem"); | 220 | try clang_argv.append("-isystem"); |
| 221 | %return clang_argv.append(args[arg_i]); | 221 | try clang_argv.append(args[arg_i]); |
| 222 | } else if (mem.eql(u8, arg, "-dirafter")) { | 222 | } else if (mem.eql(u8, arg, "-dirafter")) { |
| 223 | %return clang_argv.append("-dirafter"); | 223 | try clang_argv.append("-dirafter"); |
| 224 | %return clang_argv.append(args[arg_i]); | 224 | try clang_argv.append(args[arg_i]); |
| 225 | } else if (mem.eql(u8, arg, "-mllvm")) { | 225 | } else if (mem.eql(u8, arg, "-mllvm")) { |
| 226 | %return clang_argv.append("-mllvm"); | 226 | try clang_argv.append("-mllvm"); |
| 227 | %return clang_argv.append(args[arg_i]); | 227 | try clang_argv.append(args[arg_i]); |
| 228 | 228 | ||
| 229 | %return llvm_argv.append(args[arg_i]); | 229 | try llvm_argv.append(args[arg_i]); |
| 230 | } else if (mem.eql(u8, arg, "--library-path") or mem.eql(u8, arg, "-L")) { | 230 | } else if (mem.eql(u8, arg, "--library-path") or mem.eql(u8, arg, "-L")) { |
| 231 | %return lib_dirs.append(args[arg_i]); | 231 | try lib_dirs.append(args[arg_i]); |
| 232 | } else if (mem.eql(u8, arg, "--library")) { | 232 | } else if (mem.eql(u8, arg, "--library")) { |
| 233 | %return link_libs.append(args[arg_i]); | 233 | try link_libs.append(args[arg_i]); |
| 234 | } else if (mem.eql(u8, arg, "--object")) { | 234 | } else if (mem.eql(u8, arg, "--object")) { |
| 235 | %return objects.append(args[arg_i]); | 235 | try objects.append(args[arg_i]); |
| 236 | } else if (mem.eql(u8, arg, "--assembly")) { | 236 | } else if (mem.eql(u8, arg, "--assembly")) { |
| 237 | %return asm_files.append(args[arg_i]); | 237 | try asm_files.append(args[arg_i]); |
| 238 | } else if (mem.eql(u8, arg, "--cache-dir")) { | 238 | } else if (mem.eql(u8, arg, "--cache-dir")) { |
| 239 | cache_dir_arg = args[arg_i]; | 239 | cache_dir_arg = args[arg_i]; |
| 240 | } else if (mem.eql(u8, arg, "--target-arch")) { | 240 | } else if (mem.eql(u8, arg, "--target-arch")) { |
| ... | @@ -248,21 +248,21 @@ pub fn main2() -> %void { | ... | @@ -248,21 +248,21 @@ pub fn main2() -> %void { |
| 248 | } else if (mem.eql(u8, arg, "-mios-version-min")) { | 248 | } else if (mem.eql(u8, arg, "-mios-version-min")) { |
| 249 | mios_version_min = args[arg_i]; | 249 | mios_version_min = args[arg_i]; |
| 250 | } else if (mem.eql(u8, arg, "-framework")) { | 250 | } else if (mem.eql(u8, arg, "-framework")) { |
| 251 | %return frameworks.append(args[arg_i]); | 251 | try frameworks.append(args[arg_i]); |
| 252 | } else if (mem.eql(u8, arg, "--linker-script")) { | 252 | } else if (mem.eql(u8, arg, "--linker-script")) { |
| 253 | linker_script_arg = args[arg_i]; | 253 | linker_script_arg = args[arg_i]; |
| 254 | } else if (mem.eql(u8, arg, "-rpath")) { | 254 | } else if (mem.eql(u8, arg, "-rpath")) { |
| 255 | %return rpath_list.append(args[arg_i]); | 255 | try rpath_list.append(args[arg_i]); |
| 256 | } else if (mem.eql(u8, arg, "--test-filter")) { | 256 | } else if (mem.eql(u8, arg, "--test-filter")) { |
| 257 | %return test_filters.append(args[arg_i]); | 257 | try test_filters.append(args[arg_i]); |
| 258 | } else if (mem.eql(u8, arg, "--test-name-prefix")) { | 258 | } else if (mem.eql(u8, arg, "--test-name-prefix")) { |
| 259 | test_name_prefix_arg = args[arg_i]; | 259 | test_name_prefix_arg = args[arg_i]; |
| 260 | } else if (mem.eql(u8, arg, "--ver-major")) { | 260 | } else if (mem.eql(u8, arg, "--ver-major")) { |
| 261 | ver_major = %return std.fmt.parseUnsigned(u32, args[arg_i], 10); | 261 | ver_major = try std.fmt.parseUnsigned(u32, args[arg_i], 10); |
| 262 | } else if (mem.eql(u8, arg, "--ver-minor")) { | 262 | } else if (mem.eql(u8, arg, "--ver-minor")) { |
| 263 | ver_minor = %return std.fmt.parseUnsigned(u32, args[arg_i], 10); | 263 | ver_minor = try std.fmt.parseUnsigned(u32, args[arg_i], 10); |
| 264 | } else if (mem.eql(u8, arg, "--ver-patch")) { | 264 | } else if (mem.eql(u8, arg, "--ver-patch")) { |
| 265 | ver_patch = %return std.fmt.parseUnsigned(u32, args[arg_i], 10); | 265 | ver_patch = try std.fmt.parseUnsigned(u32, args[arg_i], 10); |
| 266 | } else if (mem.eql(u8, arg, "--test-cmd")) { | 266 | } else if (mem.eql(u8, arg, "--test-cmd")) { |
| 267 | @panic("TODO --test-cmd"); | 267 | @panic("TODO --test-cmd"); |
| 268 | } else { | 268 | } else { |
| ... | @@ -367,13 +367,13 @@ pub fn main2() -> %void { | ... | @@ -367,13 +367,13 @@ pub fn main2() -> %void { |
| 367 | const zig_root_source_file = if (cmd == Cmd.TranslateC) null else in_file_arg; | 367 | const zig_root_source_file = if (cmd == Cmd.TranslateC) null else in_file_arg; |
| 368 | 368 | ||
| 369 | const chosen_cache_dir = cache_dir_arg ?? default_zig_cache_name; | 369 | const chosen_cache_dir = cache_dir_arg ?? default_zig_cache_name; |
| 370 | const full_cache_dir = %return os.path.resolve(allocator, ".", chosen_cache_dir); | 370 | const full_cache_dir = try os.path.resolve(allocator, ".", chosen_cache_dir); |
| 371 | defer allocator.free(full_cache_dir); | 371 | defer allocator.free(full_cache_dir); |
| 372 | 372 | ||
| 373 | const zig_lib_dir = %return resolveZigLibDir(allocator, zig_install_prefix); | 373 | const zig_lib_dir = try resolveZigLibDir(allocator, zig_install_prefix); |
| 374 | %defer allocator.free(zig_lib_dir); | 374 | %defer allocator.free(zig_lib_dir); |
| 375 | 375 | ||
| 376 | const module = %return Module.create(allocator, root_name, zig_root_source_file, | 376 | const module = try Module.create(allocator, root_name, zig_root_source_file, |
| 377 | Target.Native, build_kind, build_mode, zig_lib_dir, full_cache_dir); | 377 | Target.Native, build_kind, build_mode, zig_lib_dir, full_cache_dir); |
| 378 | defer module.destroy(); | 378 | defer module.destroy(); |
| 379 | 379 | ||
| ... | @@ -424,7 +424,7 @@ pub fn main2() -> %void { | ... | @@ -424,7 +424,7 @@ pub fn main2() -> %void { |
| 424 | module.rpath_list = rpath_list.toSliceConst(); | 424 | module.rpath_list = rpath_list.toSliceConst(); |
| 425 | 425 | ||
| 426 | for (link_libs.toSliceConst()) |name| { | 426 | for (link_libs.toSliceConst()) |name| { |
| 427 | _ = %return module.addLinkLib(name, true); | 427 | _ = try module.addLinkLib(name, true); |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | module.windows_subsystem_windows = mwindows; | 430 | module.windows_subsystem_windows = mwindows; |
| ... | @@ -455,8 +455,8 @@ pub fn main2() -> %void { | ... | @@ -455,8 +455,8 @@ pub fn main2() -> %void { |
| 455 | module.link_objects = objects.toSliceConst(); | 455 | module.link_objects = objects.toSliceConst(); |
| 456 | module.assembly_files = asm_files.toSliceConst(); | 456 | module.assembly_files = asm_files.toSliceConst(); |
| 457 | 457 | ||
| 458 | %return module.build(); | 458 | try module.build(); |
| 459 | %return module.link(out_file); | 459 | try module.link(out_file); |
| 460 | }, | 460 | }, |
| 461 | Cmd.TranslateC => @panic("TODO translate-c"), | 461 | Cmd.TranslateC => @panic("TODO translate-c"), |
| 462 | Cmd.Test => @panic("TODO test cmd"), | 462 | Cmd.Test => @panic("TODO test cmd"), |
| ... | @@ -464,16 +464,16 @@ pub fn main2() -> %void { | ... | @@ -464,16 +464,16 @@ pub fn main2() -> %void { |
| 464 | } | 464 | } |
| 465 | }, | 465 | }, |
| 466 | Cmd.Version => { | 466 | Cmd.Version => { |
| 467 | var stdout_file = %return io.getStdErr(); | 467 | var stdout_file = try io.getStdErr(); |
| 468 | %return stdout_file.write(std.cstr.toSliceConst(c.ZIG_VERSION_STRING)); | 468 | try stdout_file.write(std.cstr.toSliceConst(c.ZIG_VERSION_STRING)); |
| 469 | %return stdout_file.write("\n"); | 469 | try stdout_file.write("\n"); |
| 470 | }, | 470 | }, |
| 471 | Cmd.Targets => @panic("TODO zig targets"), | 471 | Cmd.Targets => @panic("TODO zig targets"), |
| 472 | } | 472 | } |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | fn printUsage(stream: &io.OutStream) -> %void { | 475 | fn printUsage(stream: &io.OutStream) -> %void { |
| 476 | %return stream.write( | 476 | try stream.write( |
| 477 | \\Usage: zig [command] [options] | 477 | \\Usage: zig [command] [options] |
| 478 | \\ | 478 | \\ |
| 479 | \\Commands: | 479 | \\Commands: |
| ... | @@ -549,8 +549,8 @@ fn printUsage(stream: &io.OutStream) -> %void { | ... | @@ -549,8 +549,8 @@ fn printUsage(stream: &io.OutStream) -> %void { |
| 549 | } | 549 | } |
| 550 | 550 | ||
| 551 | fn printZen() -> %void { | 551 | fn printZen() -> %void { |
| 552 | var stdout_file = %return io.getStdErr(); | 552 | var stdout_file = try io.getStdErr(); |
| 553 | %return stdout_file.write( | 553 | try stdout_file.write( |
| 554 | \\ | 554 | \\ |
| 555 | \\ * Communicate intent precisely. | 555 | \\ * Communicate intent precisely. |
| 556 | \\ * Edge cases matter. | 556 | \\ * Edge cases matter. |
| ... | @@ -571,12 +571,12 @@ fn printZen() -> %void { | ... | @@ -571,12 +571,12 @@ fn printZen() -> %void { |
| 571 | /// Caller must free result | 571 | /// Caller must free result |
| 572 | fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) -> %[]u8 { | 572 | fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) -> %[]u8 { |
| 573 | if (zig_install_prefix_arg) |zig_install_prefix| { | 573 | if (zig_install_prefix_arg) |zig_install_prefix| { |
| 574 | return testZigInstallPrefix(allocator, zig_install_prefix) %% |err| { | 574 | return testZigInstallPrefix(allocator, zig_install_prefix) catch |err| { |
| 575 | warn("No Zig installation found at prefix {}: {}\n", zig_install_prefix_arg, @errorName(err)); | 575 | warn("No Zig installation found at prefix {}: {}\n", zig_install_prefix_arg, @errorName(err)); |
| 576 | return error.ZigInstallationNotFound; | 576 | return error.ZigInstallationNotFound; |
| 577 | }; | 577 | }; |
| 578 | } else { | 578 | } else { |
| 579 | return findZigLibDir(allocator) %% |err| { | 579 | return findZigLibDir(allocator) catch |err| { |
| 580 | warn("Unable to find zig lib directory: {}.\nReinstall Zig or use --zig-install-prefix.\n", | 580 | warn("Unable to find zig lib directory: {}.\nReinstall Zig or use --zig-install-prefix.\n", |
| 581 | @errorName(err)); | 581 | @errorName(err)); |
| 582 | return error.ZigLibDirNotFound; | 582 | return error.ZigLibDirNotFound; |
| ... | @@ -586,13 +586,13 @@ fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const | ... | @@ -586,13 +586,13 @@ fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const |
| 586 | 586 | ||
| 587 | /// Caller must free result | 587 | /// Caller must free result |
| 588 | fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]u8 { | 588 | fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]u8 { |
| 589 | const test_zig_dir = %return os.path.join(allocator, test_path, "lib", "zig"); | 589 | const test_zig_dir = try os.path.join(allocator, test_path, "lib", "zig"); |
| 590 | %defer allocator.free(test_zig_dir); | 590 | %defer allocator.free(test_zig_dir); |
| 591 | 591 | ||
| 592 | const test_index_file = %return os.path.join(allocator, test_zig_dir, "std", "index.zig"); | 592 | const test_index_file = try os.path.join(allocator, test_zig_dir, "std", "index.zig"); |
| 593 | defer allocator.free(test_index_file); | 593 | defer allocator.free(test_index_file); |
| 594 | 594 | ||
| 595 | var file = %return io.File.openRead(test_index_file, allocator); | 595 | var file = try io.File.openRead(test_index_file, allocator); |
| 596 | file.close(); | 596 | file.close(); |
| 597 | 597 | ||
| 598 | return test_zig_dir; | 598 | return test_zig_dir; |
| ... | @@ -600,7 +600,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[] | ... | @@ -600,7 +600,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[] |
| 600 | 600 | ||
| 601 | /// Caller must free result | 601 | /// Caller must free result |
| 602 | fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 { | 602 | fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 { |
| 603 | const self_exe_path = %return os.selfExeDirPath(allocator); | 603 | const self_exe_path = try os.selfExeDirPath(allocator); |
| 604 | defer allocator.free(self_exe_path); | 604 | defer allocator.free(self_exe_path); |
| 605 | 605 | ||
| 606 | var cur_path: []const u8 = self_exe_path; | 606 | var cur_path: []const u8 = self_exe_path; |
| ... | @@ -611,7 +611,7 @@ fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 { | ... | @@ -611,7 +611,7 @@ fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 { |
| 611 | break; | 611 | break; |
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | return testZigInstallPrefix(allocator, test_dir) %% |err| { | 614 | return testZigInstallPrefix(allocator, test_dir) catch |err| { |
| 615 | cur_path = test_dir; | 615 | cur_path = test_dir; |
| 616 | continue; | 616 | continue; |
| 617 | }; | 617 | }; |
src-self-hosted/module.zig+15-15| ... | @@ -112,7 +112,7 @@ pub const Module = struct { | ... | @@ -112,7 +112,7 @@ pub const Module = struct { |
| 112 | pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target, | 112 | pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target, |
| 113 | kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) -> %&Module | 113 | kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) -> %&Module |
| 114 | { | 114 | { |
| 115 | var name_buffer = %return Buffer.init(allocator, name); | 115 | var name_buffer = try Buffer.init(allocator, name); |
| 116 | %defer name_buffer.deinit(); | 116 | %defer name_buffer.deinit(); |
| 117 | 117 | ||
| 118 | const context = c.LLVMContextCreate() ?? return error.OutOfMemory; | 118 | const context = c.LLVMContextCreate() ?? return error.OutOfMemory; |
| ... | @@ -124,7 +124,7 @@ pub const Module = struct { | ... | @@ -124,7 +124,7 @@ pub const Module = struct { |
| 124 | const builder = c.LLVMCreateBuilderInContext(context) ?? return error.OutOfMemory; | 124 | const builder = c.LLVMCreateBuilderInContext(context) ?? return error.OutOfMemory; |
| 125 | %defer c.LLVMDisposeBuilder(builder); | 125 | %defer c.LLVMDisposeBuilder(builder); |
| 126 | 126 | ||
| 127 | const module_ptr = %return allocator.create(Module); | 127 | const module_ptr = try allocator.create(Module); |
| 128 | %defer allocator.destroy(module_ptr); | 128 | %defer allocator.destroy(module_ptr); |
| 129 | 129 | ||
| 130 | *module_ptr = Module { | 130 | *module_ptr = Module { |
| ... | @@ -200,21 +200,21 @@ pub const Module = struct { | ... | @@ -200,21 +200,21 @@ pub const Module = struct { |
| 200 | 200 | ||
| 201 | pub fn build(self: &Module) -> %void { | 201 | pub fn build(self: &Module) -> %void { |
| 202 | if (self.llvm_argv.len != 0) { | 202 | if (self.llvm_argv.len != 0) { |
| 203 | var c_compatible_args = %return std.cstr.NullTerminated2DArray.fromSlices(self.allocator, | 203 | var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator, |
| 204 | [][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, }); | 204 | [][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, }); |
| 205 | defer c_compatible_args.deinit(); | 205 | defer c_compatible_args.deinit(); |
| 206 | c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr); | 206 | c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr); |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | const root_src_path = self.root_src_path ?? @panic("TODO handle null root src path"); | 209 | const root_src_path = self.root_src_path ?? @panic("TODO handle null root src path"); |
| 210 | const root_src_real_path = os.path.real(self.allocator, root_src_path) %% |err| { | 210 | const root_src_real_path = os.path.real(self.allocator, root_src_path) catch |err| { |
| 211 | %return printError("unable to get real path '{}': {}", root_src_path, err); | 211 | try printError("unable to get real path '{}': {}", root_src_path, err); |
| 212 | return err; | 212 | return err; |
| 213 | }; | 213 | }; |
| 214 | %defer self.allocator.free(root_src_real_path); | 214 | %defer self.allocator.free(root_src_real_path); |
| 215 | 215 | ||
| 216 | const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) %% |err| { | 216 | const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) catch |err| { |
| 217 | %return printError("unable to open '{}': {}", root_src_real_path, err); | 217 | try printError("unable to open '{}': {}", root_src_real_path, err); |
| 218 | return err; | 218 | return err; |
| 219 | }; | 219 | }; |
| 220 | %defer self.allocator.free(source_code); | 220 | %defer self.allocator.free(source_code); |
| ... | @@ -244,16 +244,16 @@ pub const Module = struct { | ... | @@ -244,16 +244,16 @@ pub const Module = struct { |
| 244 | var parser = Parser.init(&tokenizer, self.allocator, root_src_real_path); | 244 | var parser = Parser.init(&tokenizer, self.allocator, root_src_real_path); |
| 245 | defer parser.deinit(); | 245 | defer parser.deinit(); |
| 246 | 246 | ||
| 247 | const root_node = %return parser.parse(); | 247 | const root_node = try parser.parse(); |
| 248 | defer parser.freeAst(root_node); | 248 | defer parser.freeAst(root_node); |
| 249 | 249 | ||
| 250 | var stderr_file = %return std.io.getStdErr(); | 250 | var stderr_file = try std.io.getStdErr(); |
| 251 | var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file); | 251 | var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file); |
| 252 | const out_stream = &stderr_file_out_stream.stream; | 252 | const out_stream = &stderr_file_out_stream.stream; |
| 253 | %return parser.renderAst(out_stream, root_node); | 253 | try parser.renderAst(out_stream, root_node); |
| 254 | 254 | ||
| 255 | warn("====fmt:====\n"); | 255 | warn("====fmt:====\n"); |
| 256 | %return parser.renderSource(out_stream, root_node); | 256 | try parser.renderSource(out_stream, root_node); |
| 257 | 257 | ||
| 258 | warn("====ir:====\n"); | 258 | warn("====ir:====\n"); |
| 259 | warn("TODO\n\n"); | 259 | warn("TODO\n\n"); |
| ... | @@ -282,14 +282,14 @@ pub const Module = struct { | ... | @@ -282,14 +282,14 @@ pub const Module = struct { |
| 282 | } | 282 | } |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | const link_lib = %return self.allocator.create(LinkLib); | 285 | const link_lib = try self.allocator.create(LinkLib); |
| 286 | *link_lib = LinkLib { | 286 | *link_lib = LinkLib { |
| 287 | .name = name, | 287 | .name = name, |
| 288 | .path = null, | 288 | .path = null, |
| 289 | .provided_explicitly = provided_explicitly, | 289 | .provided_explicitly = provided_explicitly, |
| 290 | .symbols = ArrayList([]u8).init(self.allocator), | 290 | .symbols = ArrayList([]u8).init(self.allocator), |
| 291 | }; | 291 | }; |
| 292 | %return self.link_libs_list.append(link_lib); | 292 | try self.link_libs_list.append(link_lib); |
| 293 | if (is_libc) { | 293 | if (is_libc) { |
| 294 | self.libc_link_lib = link_lib; | 294 | self.libc_link_lib = link_lib; |
| 295 | } | 295 | } |
| ... | @@ -298,8 +298,8 @@ pub const Module = struct { | ... | @@ -298,8 +298,8 @@ pub const Module = struct { |
| 298 | }; | 298 | }; |
| 299 | 299 | ||
| 300 | fn printError(comptime format: []const u8, args: ...) -> %void { | 300 | fn printError(comptime format: []const u8, args: ...) -> %void { |
| 301 | var stderr_file = %return std.io.getStdErr(); | 301 | var stderr_file = try std.io.getStdErr(); |
| 302 | var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file); | 302 | var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file); |
| 303 | const out_stream = &stderr_file_out_stream.stream; | 303 | const out_stream = &stderr_file_out_stream.stream; |
| 304 | %return out_stream.print(format, args); | 304 | try out_stream.print(format, args); |
| 305 | } | 305 | } |
src-self-hosted/parser.zig+175-175| ... | @@ -58,7 +58,7 @@ pub const Parser = struct { | ... | @@ -58,7 +58,7 @@ pub const Parser = struct { |
| 58 | switch (*self) { | 58 | switch (*self) { |
| 59 | DestPtr.Field => |ptr| *ptr = value, | 59 | DestPtr.Field => |ptr| *ptr = value, |
| 60 | DestPtr.NullableField => |ptr| *ptr = value, | 60 | DestPtr.NullableField => |ptr| *ptr = value, |
| 61 | DestPtr.List => |list| %return list.append(value), | 61 | DestPtr.List => |list| try list.append(value), |
| 62 | } | 62 | } |
| 63 | } | 63 | } |
| 64 | }; | 64 | }; |
| ... | @@ -96,12 +96,12 @@ pub const Parser = struct { | ... | @@ -96,12 +96,12 @@ pub const Parser = struct { |
| 96 | var stack = self.initUtilityArrayList(&ast.Node); | 96 | var stack = self.initUtilityArrayList(&ast.Node); |
| 97 | defer self.deinitUtilityArrayList(stack); | 97 | defer self.deinitUtilityArrayList(stack); |
| 98 | 98 | ||
| 99 | stack.append(&root_node.base) %% unreachable; | 99 | stack.append(&root_node.base) catch unreachable; |
| 100 | while (stack.popOrNull()) |node| { | 100 | while (stack.popOrNull()) |node| { |
| 101 | var i: usize = 0; | 101 | var i: usize = 0; |
| 102 | while (node.iterate(i)) |child| : (i += 1) { | 102 | while (node.iterate(i)) |child| : (i += 1) { |
| 103 | if (child.iterate(0) != null) { | 103 | if (child.iterate(0) != null) { |
| 104 | stack.append(child) %% unreachable; | 104 | stack.append(child) catch unreachable; |
| 105 | } else { | 105 | } else { |
| 106 | child.destroy(self.allocator); | 106 | child.destroy(self.allocator); |
| 107 | } | 107 | } |
| ... | @@ -111,7 +111,7 @@ pub const Parser = struct { | ... | @@ -111,7 +111,7 @@ pub const Parser = struct { |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | pub fn parse(self: &Parser) -> %&ast.NodeRoot { | 113 | pub fn parse(self: &Parser) -> %&ast.NodeRoot { |
| 114 | const result = self.parseInner() %% |err| x: { | 114 | const result = self.parseInner() catch |err| x: { |
| 115 | if (self.cleanup_root_node) |root_node| { | 115 | if (self.cleanup_root_node) |root_node| { |
| 116 | self.freeAst(root_node); | 116 | self.freeAst(root_node); |
| 117 | } | 117 | } |
| ... | @@ -126,10 +126,10 @@ pub const Parser = struct { | ... | @@ -126,10 +126,10 @@ pub const Parser = struct { |
| 126 | defer self.deinitUtilityArrayList(stack); | 126 | defer self.deinitUtilityArrayList(stack); |
| 127 | 127 | ||
| 128 | const root_node = x: { | 128 | const root_node = x: { |
| 129 | const root_node = %return self.createRoot(); | 129 | const root_node = try self.createRoot(); |
| 130 | %defer self.allocator.destroy(root_node); | 130 | %defer self.allocator.destroy(root_node); |
| 131 | // This stack append has to succeed for freeAst to work | 131 | // This stack append has to succeed for freeAst to work |
| 132 | %return stack.append(State.TopLevel); | 132 | try stack.append(State.TopLevel); |
| 133 | break :x root_node; | 133 | break :x root_node; |
| 134 | }; | 134 | }; |
| 135 | assert(self.cleanup_root_node == null); | 135 | assert(self.cleanup_root_node == null); |
| ... | @@ -156,14 +156,14 @@ pub const Parser = struct { | ... | @@ -156,14 +156,14 @@ pub const Parser = struct { |
| 156 | const token = self.getNextToken(); | 156 | const token = self.getNextToken(); |
| 157 | switch (token.id) { | 157 | switch (token.id) { |
| 158 | Token.Id.Keyword_pub, Token.Id.Keyword_export => { | 158 | Token.Id.Keyword_pub, Token.Id.Keyword_export => { |
| 159 | stack.append(State { .TopLevelExtern = token }) %% unreachable; | 159 | stack.append(State { .TopLevelExtern = token }) catch unreachable; |
| 160 | continue; | 160 | continue; |
| 161 | }, | 161 | }, |
| 162 | Token.Id.Eof => return root_node, | 162 | Token.Id.Eof => return root_node, |
| 163 | else => { | 163 | else => { |
| 164 | self.putBackToken(token); | 164 | self.putBackToken(token); |
| 165 | // TODO shouldn't need this cast | 165 | // TODO shouldn't need this cast |
| 166 | stack.append(State { .TopLevelExtern = null }) %% unreachable; | 166 | stack.append(State { .TopLevelExtern = null }) catch unreachable; |
| 167 | continue; | 167 | continue; |
| 168 | }, | 168 | }, |
| 169 | } | 169 | } |
| ... | @@ -176,7 +176,7 @@ pub const Parser = struct { | ... | @@ -176,7 +176,7 @@ pub const Parser = struct { |
| 176 | .visib_token = visib_token, | 176 | .visib_token = visib_token, |
| 177 | .extern_token = token, | 177 | .extern_token = token, |
| 178 | }, | 178 | }, |
| 179 | }) %% unreachable; | 179 | }) catch unreachable; |
| 180 | continue; | 180 | continue; |
| 181 | } | 181 | } |
| 182 | self.putBackToken(token); | 182 | self.putBackToken(token); |
| ... | @@ -185,52 +185,52 @@ pub const Parser = struct { | ... | @@ -185,52 +185,52 @@ pub const Parser = struct { |
| 185 | .visib_token = visib_token, | 185 | .visib_token = visib_token, |
| 186 | .extern_token = null, | 186 | .extern_token = null, |
| 187 | }, | 187 | }, |
| 188 | }) %% unreachable; | 188 | }) catch unreachable; |
| 189 | continue; | 189 | continue; |
| 190 | }, | 190 | }, |
| 191 | State.TopLevelDecl => |ctx| { | 191 | State.TopLevelDecl => |ctx| { |
| 192 | const token = self.getNextToken(); | 192 | const token = self.getNextToken(); |
| 193 | switch (token.id) { | 193 | switch (token.id) { |
| 194 | Token.Id.Keyword_var, Token.Id.Keyword_const => { | 194 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 195 | stack.append(State.TopLevel) %% unreachable; | 195 | stack.append(State.TopLevel) catch unreachable; |
| 196 | // TODO shouldn't need these casts | 196 | // TODO shouldn't need these casts |
| 197 | const var_decl_node = %return self.createAttachVarDecl(&root_node.decls, ctx.visib_token, | 197 | const var_decl_node = try self.createAttachVarDecl(&root_node.decls, ctx.visib_token, |
| 198 | token, (?Token)(null), ctx.extern_token); | 198 | token, (?Token)(null), ctx.extern_token); |
| 199 | %return stack.append(State { .VarDecl = var_decl_node }); | 199 | try stack.append(State { .VarDecl = var_decl_node }); |
| 200 | continue; | 200 | continue; |
| 201 | }, | 201 | }, |
| 202 | Token.Id.Keyword_fn => { | 202 | Token.Id.Keyword_fn => { |
| 203 | stack.append(State.TopLevel) %% unreachable; | 203 | stack.append(State.TopLevel) catch unreachable; |
| 204 | // TODO shouldn't need these casts | 204 | // TODO shouldn't need these casts |
| 205 | const fn_proto = %return self.createAttachFnProto(&root_node.decls, token, | 205 | const fn_proto = try self.createAttachFnProto(&root_node.decls, token, |
| 206 | ctx.extern_token, (?Token)(null), (?Token)(null), (?Token)(null)); | 206 | ctx.extern_token, (?Token)(null), (?Token)(null), (?Token)(null)); |
| 207 | %return stack.append(State { .FnDef = fn_proto }); | 207 | try stack.append(State { .FnDef = fn_proto }); |
| 208 | %return stack.append(State { .FnProto = fn_proto }); | 208 | try stack.append(State { .FnProto = fn_proto }); |
| 209 | continue; | 209 | continue; |
| 210 | }, | 210 | }, |
| 211 | Token.Id.StringLiteral => { | 211 | Token.Id.StringLiteral => { |
| 212 | @panic("TODO extern with string literal"); | 212 | @panic("TODO extern with string literal"); |
| 213 | }, | 213 | }, |
| 214 | Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => { | 214 | Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => { |
| 215 | stack.append(State.TopLevel) %% unreachable; | 215 | stack.append(State.TopLevel) catch unreachable; |
| 216 | const fn_token = %return self.eatToken(Token.Id.Keyword_fn); | 216 | const fn_token = try self.eatToken(Token.Id.Keyword_fn); |
| 217 | // TODO shouldn't need this cast | 217 | // TODO shouldn't need this cast |
| 218 | const fn_proto = %return self.createAttachFnProto(&root_node.decls, fn_token, | 218 | const fn_proto = try self.createAttachFnProto(&root_node.decls, fn_token, |
| 219 | ctx.extern_token, (?Token)(token), (?Token)(null), (?Token)(null)); | 219 | ctx.extern_token, (?Token)(token), (?Token)(null), (?Token)(null)); |
| 220 | %return stack.append(State { .FnDef = fn_proto }); | 220 | try stack.append(State { .FnDef = fn_proto }); |
| 221 | %return stack.append(State { .FnProto = fn_proto }); | 221 | try stack.append(State { .FnProto = fn_proto }); |
| 222 | continue; | 222 | continue; |
| 223 | }, | 223 | }, |
| 224 | else => return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)), | 224 | else => return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)), |
| 225 | } | 225 | } |
| 226 | }, | 226 | }, |
| 227 | State.VarDecl => |var_decl| { | 227 | State.VarDecl => |var_decl| { |
| 228 | var_decl.name_token = %return self.eatToken(Token.Id.Identifier); | 228 | var_decl.name_token = try self.eatToken(Token.Id.Identifier); |
| 229 | stack.append(State { .VarDeclAlign = var_decl }) %% unreachable; | 229 | stack.append(State { .VarDeclAlign = var_decl }) catch unreachable; |
| 230 | 230 | ||
| 231 | const next_token = self.getNextToken(); | 231 | const next_token = self.getNextToken(); |
| 232 | if (next_token.id == Token.Id.Colon) { | 232 | if (next_token.id == Token.Id.Colon) { |
| 233 | %return stack.append(State { .TypeExpr = DestPtr {.NullableField = &var_decl.type_node} }); | 233 | try stack.append(State { .TypeExpr = DestPtr {.NullableField = &var_decl.type_node} }); |
| 234 | continue; | 234 | continue; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| ... | @@ -238,13 +238,13 @@ pub const Parser = struct { | ... | @@ -238,13 +238,13 @@ pub const Parser = struct { |
| 238 | continue; | 238 | continue; |
| 239 | }, | 239 | }, |
| 240 | State.VarDeclAlign => |var_decl| { | 240 | State.VarDeclAlign => |var_decl| { |
| 241 | stack.append(State { .VarDeclEq = var_decl }) %% unreachable; | 241 | stack.append(State { .VarDeclEq = var_decl }) catch unreachable; |
| 242 | 242 | ||
| 243 | const next_token = self.getNextToken(); | 243 | const next_token = self.getNextToken(); |
| 244 | if (next_token.id == Token.Id.Keyword_align) { | 244 | if (next_token.id == Token.Id.Keyword_align) { |
| 245 | _ = %return self.eatToken(Token.Id.LParen); | 245 | _ = try self.eatToken(Token.Id.LParen); |
| 246 | %return stack.append(State { .ExpectToken = Token.Id.RParen }); | 246 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 247 | %return stack.append(State { .Expression = DestPtr{.NullableField = &var_decl.align_node} }); | 247 | try stack.append(State { .Expression = DestPtr{.NullableField = &var_decl.align_node} }); |
| 248 | continue; | 248 | continue; |
| 249 | } | 249 | } |
| 250 | 250 | ||
| ... | @@ -255,8 +255,8 @@ pub const Parser = struct { | ... | @@ -255,8 +255,8 @@ pub const Parser = struct { |
| 255 | const token = self.getNextToken(); | 255 | const token = self.getNextToken(); |
| 256 | if (token.id == Token.Id.Equal) { | 256 | if (token.id == Token.Id.Equal) { |
| 257 | var_decl.eq_token = token; | 257 | var_decl.eq_token = token; |
| 258 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable; | 258 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; |
| 259 | %return stack.append(State { | 259 | try stack.append(State { |
| 260 | .Expression = DestPtr {.NullableField = &var_decl.init_node}, | 260 | .Expression = DestPtr {.NullableField = &var_decl.init_node}, |
| 261 | }); | 261 | }); |
| 262 | continue; | 262 | continue; |
| ... | @@ -267,14 +267,14 @@ pub const Parser = struct { | ... | @@ -267,14 +267,14 @@ pub const Parser = struct { |
| 267 | return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id)); | 267 | return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id)); |
| 268 | }, | 268 | }, |
| 269 | State.ExpectToken => |token_id| { | 269 | State.ExpectToken => |token_id| { |
| 270 | _ = %return self.eatToken(token_id); | 270 | _ = try self.eatToken(token_id); |
| 271 | continue; | 271 | continue; |
| 272 | }, | 272 | }, |
| 273 | 273 | ||
| 274 | State.Expression => |dest_ptr| { | 274 | State.Expression => |dest_ptr| { |
| 275 | // save the dest_ptr for later | 275 | // save the dest_ptr for later |
| 276 | stack.append(state) %% unreachable; | 276 | stack.append(state) catch unreachable; |
| 277 | %return stack.append(State.ExpectOperand); | 277 | try stack.append(State.ExpectOperand); |
| 278 | continue; | 278 | continue; |
| 279 | }, | 279 | }, |
| 280 | State.ExpectOperand => { | 280 | State.ExpectOperand => { |
| ... | @@ -283,13 +283,13 @@ pub const Parser = struct { | ... | @@ -283,13 +283,13 @@ pub const Parser = struct { |
| 283 | const token = self.getNextToken(); | 283 | const token = self.getNextToken(); |
| 284 | switch (token.id) { | 284 | switch (token.id) { |
| 285 | Token.Id.Keyword_return => { | 285 | Token.Id.Keyword_return => { |
| 286 | %return stack.append(State { .PrefixOp = %return self.createPrefixOp(token, | 286 | try stack.append(State { .PrefixOp = try self.createPrefixOp(token, |
| 287 | ast.NodePrefixOp.PrefixOp.Return) }); | 287 | ast.NodePrefixOp.PrefixOp.Return) }); |
| 288 | %return stack.append(State.ExpectOperand); | 288 | try stack.append(State.ExpectOperand); |
| 289 | continue; | 289 | continue; |
| 290 | }, | 290 | }, |
| 291 | Token.Id.Ampersand => { | 291 | Token.Id.Ampersand => { |
| 292 | const prefix_op = %return self.createPrefixOp(token, ast.NodePrefixOp.PrefixOp{ | 292 | const prefix_op = try self.createPrefixOp(token, ast.NodePrefixOp.PrefixOp{ |
| 293 | .AddrOf = ast.NodePrefixOp.AddrOfInfo { | 293 | .AddrOf = ast.NodePrefixOp.AddrOfInfo { |
| 294 | .align_expr = null, | 294 | .align_expr = null, |
| 295 | .bit_offset_start_token = null, | 295 | .bit_offset_start_token = null, |
| ... | @@ -298,30 +298,30 @@ pub const Parser = struct { | ... | @@ -298,30 +298,30 @@ pub const Parser = struct { |
| 298 | .volatile_token = null, | 298 | .volatile_token = null, |
| 299 | } | 299 | } |
| 300 | }); | 300 | }); |
| 301 | %return stack.append(State { .PrefixOp = prefix_op }); | 301 | try stack.append(State { .PrefixOp = prefix_op }); |
| 302 | %return stack.append(State.ExpectOperand); | 302 | try stack.append(State.ExpectOperand); |
| 303 | %return stack.append(State { .AddrOfModifiers = &prefix_op.op.AddrOf }); | 303 | try stack.append(State { .AddrOfModifiers = &prefix_op.op.AddrOf }); |
| 304 | continue; | 304 | continue; |
| 305 | }, | 305 | }, |
| 306 | Token.Id.Identifier => { | 306 | Token.Id.Identifier => { |
| 307 | %return stack.append(State { | 307 | try stack.append(State { |
| 308 | .Operand = &(%return self.createIdentifier(token)).base | 308 | .Operand = &(try self.createIdentifier(token)).base |
| 309 | }); | 309 | }); |
| 310 | %return stack.append(State.AfterOperand); | 310 | try stack.append(State.AfterOperand); |
| 311 | continue; | 311 | continue; |
| 312 | }, | 312 | }, |
| 313 | Token.Id.IntegerLiteral => { | 313 | Token.Id.IntegerLiteral => { |
| 314 | %return stack.append(State { | 314 | try stack.append(State { |
| 315 | .Operand = &(%return self.createIntegerLiteral(token)).base | 315 | .Operand = &(try self.createIntegerLiteral(token)).base |
| 316 | }); | 316 | }); |
| 317 | %return stack.append(State.AfterOperand); | 317 | try stack.append(State.AfterOperand); |
| 318 | continue; | 318 | continue; |
| 319 | }, | 319 | }, |
| 320 | Token.Id.FloatLiteral => { | 320 | Token.Id.FloatLiteral => { |
| 321 | %return stack.append(State { | 321 | try stack.append(State { |
| 322 | .Operand = &(%return self.createFloatLiteral(token)).base | 322 | .Operand = &(try self.createFloatLiteral(token)).base |
| 323 | }); | 323 | }); |
| 324 | %return stack.append(State.AfterOperand); | 324 | try stack.append(State.AfterOperand); |
| 325 | continue; | 325 | continue; |
| 326 | }, | 326 | }, |
| 327 | else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)), | 327 | else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)), |
| ... | @@ -335,17 +335,17 @@ pub const Parser = struct { | ... | @@ -335,17 +335,17 @@ pub const Parser = struct { |
| 335 | var token = self.getNextToken(); | 335 | var token = self.getNextToken(); |
| 336 | switch (token.id) { | 336 | switch (token.id) { |
| 337 | Token.Id.EqualEqual => { | 337 | Token.Id.EqualEqual => { |
| 338 | %return stack.append(State { | 338 | try stack.append(State { |
| 339 | .InfixOp = %return self.createInfixOp(token, ast.NodeInfixOp.InfixOp.EqualEqual) | 339 | .InfixOp = try self.createInfixOp(token, ast.NodeInfixOp.InfixOp.EqualEqual) |
| 340 | }); | 340 | }); |
| 341 | %return stack.append(State.ExpectOperand); | 341 | try stack.append(State.ExpectOperand); |
| 342 | continue; | 342 | continue; |
| 343 | }, | 343 | }, |
| 344 | Token.Id.BangEqual => { | 344 | Token.Id.BangEqual => { |
| 345 | %return stack.append(State { | 345 | try stack.append(State { |
| 346 | .InfixOp = %return self.createInfixOp(token, ast.NodeInfixOp.InfixOp.BangEqual) | 346 | .InfixOp = try self.createInfixOp(token, ast.NodeInfixOp.InfixOp.BangEqual) |
| 347 | }); | 347 | }); |
| 348 | %return stack.append(State.ExpectOperand); | 348 | try stack.append(State.ExpectOperand); |
| 349 | continue; | 349 | continue; |
| 350 | }, | 350 | }, |
| 351 | else => { | 351 | else => { |
| ... | @@ -357,7 +357,7 @@ pub const Parser = struct { | ... | @@ -357,7 +357,7 @@ pub const Parser = struct { |
| 357 | switch (stack.pop()) { | 357 | switch (stack.pop()) { |
| 358 | State.Expression => |dest_ptr| { | 358 | State.Expression => |dest_ptr| { |
| 359 | // we're done | 359 | // we're done |
| 360 | %return dest_ptr.store(expression); | 360 | try dest_ptr.store(expression); |
| 361 | break; | 361 | break; |
| 362 | }, | 362 | }, |
| 363 | State.InfixOp => |infix_op| { | 363 | State.InfixOp => |infix_op| { |
| ... | @@ -383,21 +383,21 @@ pub const Parser = struct { | ... | @@ -383,21 +383,21 @@ pub const Parser = struct { |
| 383 | var token = self.getNextToken(); | 383 | var token = self.getNextToken(); |
| 384 | switch (token.id) { | 384 | switch (token.id) { |
| 385 | Token.Id.Keyword_align => { | 385 | Token.Id.Keyword_align => { |
| 386 | stack.append(state) %% unreachable; | 386 | stack.append(state) catch unreachable; |
| 387 | if (addr_of_info.align_expr != null) return self.parseError(token, "multiple align qualifiers"); | 387 | if (addr_of_info.align_expr != null) return self.parseError(token, "multiple align qualifiers"); |
| 388 | _ = %return self.eatToken(Token.Id.LParen); | 388 | _ = try self.eatToken(Token.Id.LParen); |
| 389 | %return stack.append(State { .ExpectToken = Token.Id.RParen }); | 389 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 390 | %return stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_info.align_expr} }); | 390 | try stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_info.align_expr} }); |
| 391 | continue; | 391 | continue; |
| 392 | }, | 392 | }, |
| 393 | Token.Id.Keyword_const => { | 393 | Token.Id.Keyword_const => { |
| 394 | stack.append(state) %% unreachable; | 394 | stack.append(state) catch unreachable; |
| 395 | if (addr_of_info.const_token != null) return self.parseError(token, "duplicate qualifier: const"); | 395 | if (addr_of_info.const_token != null) return self.parseError(token, "duplicate qualifier: const"); |
| 396 | addr_of_info.const_token = token; | 396 | addr_of_info.const_token = token; |
| 397 | continue; | 397 | continue; |
| 398 | }, | 398 | }, |
| 399 | Token.Id.Keyword_volatile => { | 399 | Token.Id.Keyword_volatile => { |
| 400 | stack.append(state) %% unreachable; | 400 | stack.append(state) catch unreachable; |
| 401 | if (addr_of_info.volatile_token != null) return self.parseError(token, "duplicate qualifier: volatile"); | 401 | if (addr_of_info.volatile_token != null) return self.parseError(token, "duplicate qualifier: volatile"); |
| 402 | addr_of_info.volatile_token = token; | 402 | addr_of_info.volatile_token = token; |
| 403 | continue; | 403 | continue; |
| ... | @@ -416,14 +416,14 @@ pub const Parser = struct { | ... | @@ -416,14 +416,14 @@ pub const Parser = struct { |
| 416 | } | 416 | } |
| 417 | self.putBackToken(token); | 417 | self.putBackToken(token); |
| 418 | 418 | ||
| 419 | stack.append(State { .Expression = dest_ptr }) %% unreachable; | 419 | stack.append(State { .Expression = dest_ptr }) catch unreachable; |
| 420 | continue; | 420 | continue; |
| 421 | }, | 421 | }, |
| 422 | 422 | ||
| 423 | State.FnProto => |fn_proto| { | 423 | State.FnProto => |fn_proto| { |
| 424 | stack.append(State { .FnProtoAlign = fn_proto }) %% unreachable; | 424 | stack.append(State { .FnProtoAlign = fn_proto }) catch unreachable; |
| 425 | %return stack.append(State { .ParamDecl = fn_proto }); | 425 | try stack.append(State { .ParamDecl = fn_proto }); |
| 426 | %return stack.append(State { .ExpectToken = Token.Id.LParen }); | 426 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 427 | 427 | ||
| 428 | const next_token = self.getNextToken(); | 428 | const next_token = self.getNextToken(); |
| 429 | if (next_token.id == Token.Id.Identifier) { | 429 | if (next_token.id == Token.Id.Identifier) { |
| ... | @@ -442,7 +442,7 @@ pub const Parser = struct { | ... | @@ -442,7 +442,7 @@ pub const Parser = struct { |
| 442 | if (token.id == Token.Id.Arrow) { | 442 | if (token.id == Token.Id.Arrow) { |
| 443 | stack.append(State { | 443 | stack.append(State { |
| 444 | .TypeExpr = DestPtr {.NullableField = &fn_proto.return_type}, | 444 | .TypeExpr = DestPtr {.NullableField = &fn_proto.return_type}, |
| 445 | }) %% unreachable; | 445 | }) catch unreachable; |
| 446 | continue; | 446 | continue; |
| 447 | } else { | 447 | } else { |
| 448 | self.putBackToken(token); | 448 | self.putBackToken(token); |
| ... | @@ -455,7 +455,7 @@ pub const Parser = struct { | ... | @@ -455,7 +455,7 @@ pub const Parser = struct { |
| 455 | if (token.id == Token.Id.RParen) { | 455 | if (token.id == Token.Id.RParen) { |
| 456 | continue; | 456 | continue; |
| 457 | } | 457 | } |
| 458 | const param_decl = %return self.createAttachParamDecl(&fn_proto.params); | 458 | const param_decl = try self.createAttachParamDecl(&fn_proto.params); |
| 459 | if (token.id == Token.Id.Keyword_comptime) { | 459 | if (token.id == Token.Id.Keyword_comptime) { |
| 460 | param_decl.comptime_token = token; | 460 | param_decl.comptime_token = token; |
| 461 | token = self.getNextToken(); | 461 | token = self.getNextToken(); |
| ... | @@ -474,15 +474,15 @@ pub const Parser = struct { | ... | @@ -474,15 +474,15 @@ pub const Parser = struct { |
| 474 | } | 474 | } |
| 475 | if (token.id == Token.Id.Ellipsis3) { | 475 | if (token.id == Token.Id.Ellipsis3) { |
| 476 | param_decl.var_args_token = token; | 476 | param_decl.var_args_token = token; |
| 477 | stack.append(State { .ExpectToken = Token.Id.RParen }) %% unreachable; | 477 | stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable; |
| 478 | continue; | 478 | continue; |
| 479 | } else { | 479 | } else { |
| 480 | self.putBackToken(token); | 480 | self.putBackToken(token); |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | stack.append(State { .ParamDecl = fn_proto }) %% unreachable; | 483 | stack.append(State { .ParamDecl = fn_proto }) catch unreachable; |
| 484 | %return stack.append(State.ParamDeclComma); | 484 | try stack.append(State.ParamDeclComma); |
| 485 | %return stack.append(State { | 485 | try stack.append(State { |
| 486 | .TypeExpr = DestPtr {.Field = &param_decl.type_node} | 486 | .TypeExpr = DestPtr {.Field = &param_decl.type_node} |
| 487 | }); | 487 | }); |
| 488 | continue; | 488 | continue; |
| ... | @@ -504,9 +504,9 @@ pub const Parser = struct { | ... | @@ -504,9 +504,9 @@ pub const Parser = struct { |
| 504 | const token = self.getNextToken(); | 504 | const token = self.getNextToken(); |
| 505 | switch(token.id) { | 505 | switch(token.id) { |
| 506 | Token.Id.LBrace => { | 506 | Token.Id.LBrace => { |
| 507 | const block = %return self.createBlock(token); | 507 | const block = try self.createBlock(token); |
| 508 | fn_proto.body_node = &block.base; | 508 | fn_proto.body_node = &block.base; |
| 509 | stack.append(State { .Block = block }) %% unreachable; | 509 | stack.append(State { .Block = block }) catch unreachable; |
| 510 | continue; | 510 | continue; |
| 511 | }, | 511 | }, |
| 512 | Token.Id.Semicolon => continue, | 512 | Token.Id.Semicolon => continue, |
| ... | @@ -523,8 +523,8 @@ pub const Parser = struct { | ... | @@ -523,8 +523,8 @@ pub const Parser = struct { |
| 523 | }, | 523 | }, |
| 524 | else => { | 524 | else => { |
| 525 | self.putBackToken(token); | 525 | self.putBackToken(token); |
| 526 | stack.append(State { .Block = block }) %% unreachable; | 526 | stack.append(State { .Block = block }) catch unreachable; |
| 527 | %return stack.append(State { .Statement = block }); | 527 | try stack.append(State { .Statement = block }); |
| 528 | continue; | 528 | continue; |
| 529 | }, | 529 | }, |
| 530 | } | 530 | } |
| ... | @@ -538,9 +538,9 @@ pub const Parser = struct { | ... | @@ -538,9 +538,9 @@ pub const Parser = struct { |
| 538 | const mut_token = self.getNextToken(); | 538 | const mut_token = self.getNextToken(); |
| 539 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { | 539 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { |
| 540 | // TODO shouldn't need these casts | 540 | // TODO shouldn't need these casts |
| 541 | const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null), | 541 | const var_decl = try self.createAttachVarDecl(&block.statements, (?Token)(null), |
| 542 | mut_token, (?Token)(comptime_token), (?Token)(null)); | 542 | mut_token, (?Token)(comptime_token), (?Token)(null)); |
| 543 | %return stack.append(State { .VarDecl = var_decl }); | 543 | try stack.append(State { .VarDecl = var_decl }); |
| 544 | continue; | 544 | continue; |
| 545 | } | 545 | } |
| 546 | self.putBackToken(mut_token); | 546 | self.putBackToken(mut_token); |
| ... | @@ -552,16 +552,16 @@ pub const Parser = struct { | ... | @@ -552,16 +552,16 @@ pub const Parser = struct { |
| 552 | const mut_token = self.getNextToken(); | 552 | const mut_token = self.getNextToken(); |
| 553 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { | 553 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { |
| 554 | // TODO shouldn't need these casts | 554 | // TODO shouldn't need these casts |
| 555 | const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null), | 555 | const var_decl = try self.createAttachVarDecl(&block.statements, (?Token)(null), |
| 556 | mut_token, (?Token)(null), (?Token)(null)); | 556 | mut_token, (?Token)(null), (?Token)(null)); |
| 557 | %return stack.append(State { .VarDecl = var_decl }); | 557 | try stack.append(State { .VarDecl = var_decl }); |
| 558 | continue; | 558 | continue; |
| 559 | } | 559 | } |
| 560 | self.putBackToken(mut_token); | 560 | self.putBackToken(mut_token); |
| 561 | } | 561 | } |
| 562 | 562 | ||
| 563 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable; | 563 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; |
| 564 | %return stack.append(State { .Expression = DestPtr{.List = &block.statements} }); | 564 | try stack.append(State { .Expression = DestPtr{.List = &block.statements} }); |
| 565 | continue; | 565 | continue; |
| 566 | }, | 566 | }, |
| 567 | 567 | ||
| ... | @@ -576,7 +576,7 @@ pub const Parser = struct { | ... | @@ -576,7 +576,7 @@ pub const Parser = struct { |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | fn createRoot(self: &Parser) -> %&ast.NodeRoot { | 578 | fn createRoot(self: &Parser) -> %&ast.NodeRoot { |
| 579 | const node = %return self.allocator.create(ast.NodeRoot); | 579 | const node = try self.allocator.create(ast.NodeRoot); |
| 580 | %defer self.allocator.destroy(node); | 580 | %defer self.allocator.destroy(node); |
| 581 | 581 | ||
| 582 | *node = ast.NodeRoot { | 582 | *node = ast.NodeRoot { |
| ... | @@ -589,7 +589,7 @@ pub const Parser = struct { | ... | @@ -589,7 +589,7 @@ pub const Parser = struct { |
| 589 | fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token, | 589 | fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token, |
| 590 | extern_token: &const ?Token) -> %&ast.NodeVarDecl | 590 | extern_token: &const ?Token) -> %&ast.NodeVarDecl |
| 591 | { | 591 | { |
| 592 | const node = %return self.allocator.create(ast.NodeVarDecl); | 592 | const node = try self.allocator.create(ast.NodeVarDecl); |
| 593 | %defer self.allocator.destroy(node); | 593 | %defer self.allocator.destroy(node); |
| 594 | 594 | ||
| 595 | *node = ast.NodeVarDecl { | 595 | *node = ast.NodeVarDecl { |
| ... | @@ -612,7 +612,7 @@ pub const Parser = struct { | ... | @@ -612,7 +612,7 @@ pub const Parser = struct { |
| 612 | fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token, | 612 | fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token, |
| 613 | cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) -> %&ast.NodeFnProto | 613 | cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) -> %&ast.NodeFnProto |
| 614 | { | 614 | { |
| 615 | const node = %return self.allocator.create(ast.NodeFnProto); | 615 | const node = try self.allocator.create(ast.NodeFnProto); |
| 616 | %defer self.allocator.destroy(node); | 616 | %defer self.allocator.destroy(node); |
| 617 | 617 | ||
| 618 | *node = ast.NodeFnProto { | 618 | *node = ast.NodeFnProto { |
| ... | @@ -634,7 +634,7 @@ pub const Parser = struct { | ... | @@ -634,7 +634,7 @@ pub const Parser = struct { |
| 634 | } | 634 | } |
| 635 | 635 | ||
| 636 | fn createParamDecl(self: &Parser) -> %&ast.NodeParamDecl { | 636 | fn createParamDecl(self: &Parser) -> %&ast.NodeParamDecl { |
| 637 | const node = %return self.allocator.create(ast.NodeParamDecl); | 637 | const node = try self.allocator.create(ast.NodeParamDecl); |
| 638 | %defer self.allocator.destroy(node); | 638 | %defer self.allocator.destroy(node); |
| 639 | 639 | ||
| 640 | *node = ast.NodeParamDecl { | 640 | *node = ast.NodeParamDecl { |
| ... | @@ -649,7 +649,7 @@ pub const Parser = struct { | ... | @@ -649,7 +649,7 @@ pub const Parser = struct { |
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | fn createBlock(self: &Parser, begin_token: &const Token) -> %&ast.NodeBlock { | 651 | fn createBlock(self: &Parser, begin_token: &const Token) -> %&ast.NodeBlock { |
| 652 | const node = %return self.allocator.create(ast.NodeBlock); | 652 | const node = try self.allocator.create(ast.NodeBlock); |
| 653 | %defer self.allocator.destroy(node); | 653 | %defer self.allocator.destroy(node); |
| 654 | 654 | ||
| 655 | *node = ast.NodeBlock { | 655 | *node = ast.NodeBlock { |
| ... | @@ -662,7 +662,7 @@ pub const Parser = struct { | ... | @@ -662,7 +662,7 @@ pub const Parser = struct { |
| 662 | } | 662 | } |
| 663 | 663 | ||
| 664 | fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) -> %&ast.NodeInfixOp { | 664 | fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) -> %&ast.NodeInfixOp { |
| 665 | const node = %return self.allocator.create(ast.NodeInfixOp); | 665 | const node = try self.allocator.create(ast.NodeInfixOp); |
| 666 | %defer self.allocator.destroy(node); | 666 | %defer self.allocator.destroy(node); |
| 667 | 667 | ||
| 668 | *node = ast.NodeInfixOp { | 668 | *node = ast.NodeInfixOp { |
| ... | @@ -676,7 +676,7 @@ pub const Parser = struct { | ... | @@ -676,7 +676,7 @@ pub const Parser = struct { |
| 676 | } | 676 | } |
| 677 | 677 | ||
| 678 | fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) -> %&ast.NodePrefixOp { | 678 | fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) -> %&ast.NodePrefixOp { |
| 679 | const node = %return self.allocator.create(ast.NodePrefixOp); | 679 | const node = try self.allocator.create(ast.NodePrefixOp); |
| 680 | %defer self.allocator.destroy(node); | 680 | %defer self.allocator.destroy(node); |
| 681 | 681 | ||
| 682 | *node = ast.NodePrefixOp { | 682 | *node = ast.NodePrefixOp { |
| ... | @@ -689,7 +689,7 @@ pub const Parser = struct { | ... | @@ -689,7 +689,7 @@ pub const Parser = struct { |
| 689 | } | 689 | } |
| 690 | 690 | ||
| 691 | fn createIdentifier(self: &Parser, name_token: &const Token) -> %&ast.NodeIdentifier { | 691 | fn createIdentifier(self: &Parser, name_token: &const Token) -> %&ast.NodeIdentifier { |
| 692 | const node = %return self.allocator.create(ast.NodeIdentifier); | 692 | const node = try self.allocator.create(ast.NodeIdentifier); |
| 693 | %defer self.allocator.destroy(node); | 693 | %defer self.allocator.destroy(node); |
| 694 | 694 | ||
| 695 | *node = ast.NodeIdentifier { | 695 | *node = ast.NodeIdentifier { |
| ... | @@ -700,7 +700,7 @@ pub const Parser = struct { | ... | @@ -700,7 +700,7 @@ pub const Parser = struct { |
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | fn createIntegerLiteral(self: &Parser, token: &const Token) -> %&ast.NodeIntegerLiteral { | 702 | fn createIntegerLiteral(self: &Parser, token: &const Token) -> %&ast.NodeIntegerLiteral { |
| 703 | const node = %return self.allocator.create(ast.NodeIntegerLiteral); | 703 | const node = try self.allocator.create(ast.NodeIntegerLiteral); |
| 704 | %defer self.allocator.destroy(node); | 704 | %defer self.allocator.destroy(node); |
| 705 | 705 | ||
| 706 | *node = ast.NodeIntegerLiteral { | 706 | *node = ast.NodeIntegerLiteral { |
| ... | @@ -711,7 +711,7 @@ pub const Parser = struct { | ... | @@ -711,7 +711,7 @@ pub const Parser = struct { |
| 711 | } | 711 | } |
| 712 | 712 | ||
| 713 | fn createFloatLiteral(self: &Parser, token: &const Token) -> %&ast.NodeFloatLiteral { | 713 | fn createFloatLiteral(self: &Parser, token: &const Token) -> %&ast.NodeFloatLiteral { |
| 714 | const node = %return self.allocator.create(ast.NodeFloatLiteral); | 714 | const node = try self.allocator.create(ast.NodeFloatLiteral); |
| 715 | %defer self.allocator.destroy(node); | 715 | %defer self.allocator.destroy(node); |
| 716 | 716 | ||
| 717 | *node = ast.NodeFloatLiteral { | 717 | *node = ast.NodeFloatLiteral { |
| ... | @@ -722,16 +722,16 @@ pub const Parser = struct { | ... | @@ -722,16 +722,16 @@ pub const Parser = struct { |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) -> %&ast.NodeIdentifier { | 724 | fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) -> %&ast.NodeIdentifier { |
| 725 | const node = %return self.createIdentifier(name_token); | 725 | const node = try self.createIdentifier(name_token); |
| 726 | %defer self.allocator.destroy(node); | 726 | %defer self.allocator.destroy(node); |
| 727 | %return dest_ptr.store(&node.base); | 727 | try dest_ptr.store(&node.base); |
| 728 | return node; | 728 | return node; |
| 729 | } | 729 | } |
| 730 | 730 | ||
| 731 | fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) -> %&ast.NodeParamDecl { | 731 | fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) -> %&ast.NodeParamDecl { |
| 732 | const node = %return self.createParamDecl(); | 732 | const node = try self.createParamDecl(); |
| 733 | %defer self.allocator.destroy(node); | 733 | %defer self.allocator.destroy(node); |
| 734 | %return list.append(&node.base); | 734 | try list.append(&node.base); |
| 735 | return node; | 735 | return node; |
| 736 | } | 736 | } |
| 737 | 737 | ||
| ... | @@ -739,18 +739,18 @@ pub const Parser = struct { | ... | @@ -739,18 +739,18 @@ pub const Parser = struct { |
| 739 | extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token, | 739 | extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token, |
| 740 | inline_token: &const ?Token) -> %&ast.NodeFnProto | 740 | inline_token: &const ?Token) -> %&ast.NodeFnProto |
| 741 | { | 741 | { |
| 742 | const node = %return self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token); | 742 | const node = try self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token); |
| 743 | %defer self.allocator.destroy(node); | 743 | %defer self.allocator.destroy(node); |
| 744 | %return list.append(&node.base); | 744 | try list.append(&node.base); |
| 745 | return node; | 745 | return node; |
| 746 | } | 746 | } |
| 747 | 747 | ||
| 748 | fn createAttachVarDecl(self: &Parser, list: &ArrayList(&ast.Node), visib_token: &const ?Token, | 748 | fn createAttachVarDecl(self: &Parser, list: &ArrayList(&ast.Node), visib_token: &const ?Token, |
| 749 | mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) -> %&ast.NodeVarDecl | 749 | mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) -> %&ast.NodeVarDecl |
| 750 | { | 750 | { |
| 751 | const node = %return self.createVarDecl(visib_token, mut_token, comptime_token, extern_token); | 751 | const node = try self.createVarDecl(visib_token, mut_token, comptime_token, extern_token); |
| 752 | %defer self.allocator.destroy(node); | 752 | %defer self.allocator.destroy(node); |
| 753 | %return list.append(&node.base); | 753 | try list.append(&node.base); |
| 754 | return node; | 754 | return node; |
| 755 | } | 755 | } |
| 756 | 756 | ||
| ... | @@ -783,7 +783,7 @@ pub const Parser = struct { | ... | @@ -783,7 +783,7 @@ pub const Parser = struct { |
| 783 | 783 | ||
| 784 | fn eatToken(self: &Parser, id: @TagType(Token.Id)) -> %Token { | 784 | fn eatToken(self: &Parser, id: @TagType(Token.Id)) -> %Token { |
| 785 | const token = self.getNextToken(); | 785 | const token = self.getNextToken(); |
| 786 | %return self.expectToken(token, id); | 786 | try self.expectToken(token, id); |
| 787 | return token; | 787 | return token; |
| 788 | } | 788 | } |
| 789 | 789 | ||
| ... | @@ -812,7 +812,7 @@ pub const Parser = struct { | ... | @@ -812,7 +812,7 @@ pub const Parser = struct { |
| 812 | var stack = self.initUtilityArrayList(RenderAstFrame); | 812 | var stack = self.initUtilityArrayList(RenderAstFrame); |
| 813 | defer self.deinitUtilityArrayList(stack); | 813 | defer self.deinitUtilityArrayList(stack); |
| 814 | 814 | ||
| 815 | %return stack.append(RenderAstFrame { | 815 | try stack.append(RenderAstFrame { |
| 816 | .node = &root_node.base, | 816 | .node = &root_node.base, |
| 817 | .indent = 0, | 817 | .indent = 0, |
| 818 | }); | 818 | }); |
| ... | @@ -821,13 +821,13 @@ pub const Parser = struct { | ... | @@ -821,13 +821,13 @@ pub const Parser = struct { |
| 821 | { | 821 | { |
| 822 | var i: usize = 0; | 822 | var i: usize = 0; |
| 823 | while (i < frame.indent) : (i += 1) { | 823 | while (i < frame.indent) : (i += 1) { |
| 824 | %return stream.print(" "); | 824 | try stream.print(" "); |
| 825 | } | 825 | } |
| 826 | } | 826 | } |
| 827 | %return stream.print("{}\n", @tagName(frame.node.id)); | 827 | try stream.print("{}\n", @tagName(frame.node.id)); |
| 828 | var child_i: usize = 0; | 828 | var child_i: usize = 0; |
| 829 | while (frame.node.iterate(child_i)) |child| : (child_i += 1) { | 829 | while (frame.node.iterate(child_i)) |child| : (child_i += 1) { |
| 830 | %return stack.append(RenderAstFrame { | 830 | try stack.append(RenderAstFrame { |
| 831 | .node = child, | 831 | .node = child, |
| 832 | .indent = frame.indent + 2, | 832 | .indent = frame.indent + 2, |
| 833 | }); | 833 | }); |
| ... | @@ -856,7 +856,7 @@ pub const Parser = struct { | ... | @@ -856,7 +856,7 @@ pub const Parser = struct { |
| 856 | while (i != 0) { | 856 | while (i != 0) { |
| 857 | i -= 1; | 857 | i -= 1; |
| 858 | const decl = root_node.decls.items[i]; | 858 | const decl = root_node.decls.items[i]; |
| 859 | %return stack.append(RenderState {.TopLevelDecl = decl}); | 859 | try stack.append(RenderState {.TopLevelDecl = decl}); |
| 860 | } | 860 | } |
| 861 | } | 861 | } |
| 862 | 862 | ||
| ... | @@ -870,42 +870,42 @@ pub const Parser = struct { | ... | @@ -870,42 +870,42 @@ pub const Parser = struct { |
| 870 | const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", decl); | 870 | const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", decl); |
| 871 | if (fn_proto.visib_token) |visib_token| { | 871 | if (fn_proto.visib_token) |visib_token| { |
| 872 | switch (visib_token.id) { | 872 | switch (visib_token.id) { |
| 873 | Token.Id.Keyword_pub => %return stream.print("pub "), | 873 | Token.Id.Keyword_pub => try stream.print("pub "), |
| 874 | Token.Id.Keyword_export => %return stream.print("export "), | 874 | Token.Id.Keyword_export => try stream.print("export "), |
| 875 | else => unreachable, | 875 | else => unreachable, |
| 876 | } | 876 | } |
| 877 | } | 877 | } |
| 878 | if (fn_proto.extern_token) |extern_token| { | 878 | if (fn_proto.extern_token) |extern_token| { |
| 879 | %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); | 879 | try stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); |
| 880 | } | 880 | } |
| 881 | %return stream.print("fn"); | 881 | try stream.print("fn"); |
| 882 | 882 | ||
| 883 | if (fn_proto.name_token) |name_token| { | 883 | if (fn_proto.name_token) |name_token| { |
| 884 | %return stream.print(" {}", self.tokenizer.getTokenSlice(name_token)); | 884 | try stream.print(" {}", self.tokenizer.getTokenSlice(name_token)); |
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | %return stream.print("("); | 887 | try stream.print("("); |
| 888 | 888 | ||
| 889 | %return stack.append(RenderState { .Text = "\n" }); | 889 | try stack.append(RenderState { .Text = "\n" }); |
| 890 | if (fn_proto.body_node == null) { | 890 | if (fn_proto.body_node == null) { |
| 891 | %return stack.append(RenderState { .Text = ";" }); | 891 | try stack.append(RenderState { .Text = ";" }); |
| 892 | } | 892 | } |
| 893 | 893 | ||
| 894 | %return stack.append(RenderState { .FnProtoRParen = fn_proto}); | 894 | try stack.append(RenderState { .FnProtoRParen = fn_proto}); |
| 895 | var i = fn_proto.params.len; | 895 | var i = fn_proto.params.len; |
| 896 | while (i != 0) { | 896 | while (i != 0) { |
| 897 | i -= 1; | 897 | i -= 1; |
| 898 | const param_decl_node = fn_proto.params.items[i]; | 898 | const param_decl_node = fn_proto.params.items[i]; |
| 899 | %return stack.append(RenderState { .ParamDecl = param_decl_node}); | 899 | try stack.append(RenderState { .ParamDecl = param_decl_node}); |
| 900 | if (i != 0) { | 900 | if (i != 0) { |
| 901 | %return stack.append(RenderState { .Text = ", " }); | 901 | try stack.append(RenderState { .Text = ", " }); |
| 902 | } | 902 | } |
| 903 | } | 903 | } |
| 904 | }, | 904 | }, |
| 905 | ast.Node.Id.VarDecl => { | 905 | ast.Node.Id.VarDecl => { |
| 906 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl); | 906 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl); |
| 907 | %return stack.append(RenderState { .Text = "\n"}); | 907 | try stack.append(RenderState { .Text = "\n"}); |
| 908 | %return stack.append(RenderState { .VarDecl = var_decl}); | 908 | try stack.append(RenderState { .VarDecl = var_decl}); |
| 909 | 909 | ||
| 910 | }, | 910 | }, |
| 911 | else => unreachable, | 911 | else => unreachable, |
| ... | @@ -914,111 +914,111 @@ pub const Parser = struct { | ... | @@ -914,111 +914,111 @@ pub const Parser = struct { |
| 914 | 914 | ||
| 915 | RenderState.VarDecl => |var_decl| { | 915 | RenderState.VarDecl => |var_decl| { |
| 916 | if (var_decl.visib_token) |visib_token| { | 916 | if (var_decl.visib_token) |visib_token| { |
| 917 | %return stream.print("{} ", self.tokenizer.getTokenSlice(visib_token)); | 917 | try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token)); |
| 918 | } | 918 | } |
| 919 | if (var_decl.extern_token) |extern_token| { | 919 | if (var_decl.extern_token) |extern_token| { |
| 920 | %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); | 920 | try stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); |
| 921 | if (var_decl.lib_name != null) { | 921 | if (var_decl.lib_name != null) { |
| 922 | @panic("TODO"); | 922 | @panic("TODO"); |
| 923 | } | 923 | } |
| 924 | } | 924 | } |
| 925 | if (var_decl.comptime_token) |comptime_token| { | 925 | if (var_decl.comptime_token) |comptime_token| { |
| 926 | %return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); | 926 | try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); |
| 927 | } | 927 | } |
| 928 | %return stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token)); | 928 | try stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token)); |
| 929 | %return stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token)); | 929 | try stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token)); |
| 930 | 930 | ||
| 931 | %return stack.append(RenderState { .Text = ";" }); | 931 | try stack.append(RenderState { .Text = ";" }); |
| 932 | if (var_decl.init_node) |init_node| { | 932 | if (var_decl.init_node) |init_node| { |
| 933 | %return stack.append(RenderState { .Expression = init_node }); | 933 | try stack.append(RenderState { .Expression = init_node }); |
| 934 | %return stack.append(RenderState { .Text = " = " }); | 934 | try stack.append(RenderState { .Text = " = " }); |
| 935 | } | 935 | } |
| 936 | if (var_decl.align_node) |align_node| { | 936 | if (var_decl.align_node) |align_node| { |
| 937 | %return stack.append(RenderState { .Text = ")" }); | 937 | try stack.append(RenderState { .Text = ")" }); |
| 938 | %return stack.append(RenderState { .Expression = align_node }); | 938 | try stack.append(RenderState { .Expression = align_node }); |
| 939 | %return stack.append(RenderState { .Text = " align(" }); | 939 | try stack.append(RenderState { .Text = " align(" }); |
| 940 | } | 940 | } |
| 941 | if (var_decl.type_node) |type_node| { | 941 | if (var_decl.type_node) |type_node| { |
| 942 | %return stream.print(": "); | 942 | try stream.print(": "); |
| 943 | %return stack.append(RenderState { .Expression = type_node }); | 943 | try stack.append(RenderState { .Expression = type_node }); |
| 944 | } | 944 | } |
| 945 | }, | 945 | }, |
| 946 | 946 | ||
| 947 | RenderState.ParamDecl => |base| { | 947 | RenderState.ParamDecl => |base| { |
| 948 | const param_decl = @fieldParentPtr(ast.NodeParamDecl, "base", base); | 948 | const param_decl = @fieldParentPtr(ast.NodeParamDecl, "base", base); |
| 949 | if (param_decl.comptime_token) |comptime_token| { | 949 | if (param_decl.comptime_token) |comptime_token| { |
| 950 | %return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); | 950 | try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); |
| 951 | } | 951 | } |
| 952 | if (param_decl.noalias_token) |noalias_token| { | 952 | if (param_decl.noalias_token) |noalias_token| { |
| 953 | %return stream.print("{} ", self.tokenizer.getTokenSlice(noalias_token)); | 953 | try stream.print("{} ", self.tokenizer.getTokenSlice(noalias_token)); |
| 954 | } | 954 | } |
| 955 | if (param_decl.name_token) |name_token| { | 955 | if (param_decl.name_token) |name_token| { |
| 956 | %return stream.print("{}: ", self.tokenizer.getTokenSlice(name_token)); | 956 | try stream.print("{}: ", self.tokenizer.getTokenSlice(name_token)); |
| 957 | } | 957 | } |
| 958 | if (param_decl.var_args_token) |var_args_token| { | 958 | if (param_decl.var_args_token) |var_args_token| { |
| 959 | %return stream.print("{}", self.tokenizer.getTokenSlice(var_args_token)); | 959 | try stream.print("{}", self.tokenizer.getTokenSlice(var_args_token)); |
| 960 | } else { | 960 | } else { |
| 961 | %return stack.append(RenderState { .Expression = param_decl.type_node}); | 961 | try stack.append(RenderState { .Expression = param_decl.type_node}); |
| 962 | } | 962 | } |
| 963 | }, | 963 | }, |
| 964 | RenderState.Text => |bytes| { | 964 | RenderState.Text => |bytes| { |
| 965 | %return stream.write(bytes); | 965 | try stream.write(bytes); |
| 966 | }, | 966 | }, |
| 967 | RenderState.Expression => |base| switch (base.id) { | 967 | RenderState.Expression => |base| switch (base.id) { |
| 968 | ast.Node.Id.Identifier => { | 968 | ast.Node.Id.Identifier => { |
| 969 | const identifier = @fieldParentPtr(ast.NodeIdentifier, "base", base); | 969 | const identifier = @fieldParentPtr(ast.NodeIdentifier, "base", base); |
| 970 | %return stream.print("{}", self.tokenizer.getTokenSlice(identifier.name_token)); | 970 | try stream.print("{}", self.tokenizer.getTokenSlice(identifier.name_token)); |
| 971 | }, | 971 | }, |
| 972 | ast.Node.Id.Block => { | 972 | ast.Node.Id.Block => { |
| 973 | const block = @fieldParentPtr(ast.NodeBlock, "base", base); | 973 | const block = @fieldParentPtr(ast.NodeBlock, "base", base); |
| 974 | %return stream.write("{"); | 974 | try stream.write("{"); |
| 975 | %return stack.append(RenderState { .Text = "}"}); | 975 | try stack.append(RenderState { .Text = "}"}); |
| 976 | %return stack.append(RenderState.PrintIndent); | 976 | try stack.append(RenderState.PrintIndent); |
| 977 | %return stack.append(RenderState { .Indent = indent}); | 977 | try stack.append(RenderState { .Indent = indent}); |
| 978 | %return stack.append(RenderState { .Text = "\n"}); | 978 | try stack.append(RenderState { .Text = "\n"}); |
| 979 | var i = block.statements.len; | 979 | var i = block.statements.len; |
| 980 | while (i != 0) { | 980 | while (i != 0) { |
| 981 | i -= 1; | 981 | i -= 1; |
| 982 | const statement_node = block.statements.items[i]; | 982 | const statement_node = block.statements.items[i]; |
| 983 | %return stack.append(RenderState { .Statement = statement_node}); | 983 | try stack.append(RenderState { .Statement = statement_node}); |
| 984 | %return stack.append(RenderState.PrintIndent); | 984 | try stack.append(RenderState.PrintIndent); |
| 985 | %return stack.append(RenderState { .Indent = indent + indent_delta}); | 985 | try stack.append(RenderState { .Indent = indent + indent_delta}); |
| 986 | %return stack.append(RenderState { .Text = "\n" }); | 986 | try stack.append(RenderState { .Text = "\n" }); |
| 987 | } | 987 | } |
| 988 | }, | 988 | }, |
| 989 | ast.Node.Id.InfixOp => { | 989 | ast.Node.Id.InfixOp => { |
| 990 | const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base); | 990 | const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base); |
| 991 | %return stack.append(RenderState { .Expression = prefix_op_node.rhs }); | 991 | try stack.append(RenderState { .Expression = prefix_op_node.rhs }); |
| 992 | switch (prefix_op_node.op) { | 992 | switch (prefix_op_node.op) { |
| 993 | ast.NodeInfixOp.InfixOp.EqualEqual => { | 993 | ast.NodeInfixOp.InfixOp.EqualEqual => { |
| 994 | %return stack.append(RenderState { .Text = " == "}); | 994 | try stack.append(RenderState { .Text = " == "}); |
| 995 | }, | 995 | }, |
| 996 | ast.NodeInfixOp.InfixOp.BangEqual => { | 996 | ast.NodeInfixOp.InfixOp.BangEqual => { |
| 997 | %return stack.append(RenderState { .Text = " != "}); | 997 | try stack.append(RenderState { .Text = " != "}); |
| 998 | }, | 998 | }, |
| 999 | else => unreachable, | 999 | else => unreachable, |
| 1000 | } | 1000 | } |
| 1001 | %return stack.append(RenderState { .Expression = prefix_op_node.lhs }); | 1001 | try stack.append(RenderState { .Expression = prefix_op_node.lhs }); |
| 1002 | }, | 1002 | }, |
| 1003 | ast.Node.Id.PrefixOp => { | 1003 | ast.Node.Id.PrefixOp => { |
| 1004 | const prefix_op_node = @fieldParentPtr(ast.NodePrefixOp, "base", base); | 1004 | const prefix_op_node = @fieldParentPtr(ast.NodePrefixOp, "base", base); |
| 1005 | %return stack.append(RenderState { .Expression = prefix_op_node.rhs }); | 1005 | try stack.append(RenderState { .Expression = prefix_op_node.rhs }); |
| 1006 | switch (prefix_op_node.op) { | 1006 | switch (prefix_op_node.op) { |
| 1007 | ast.NodePrefixOp.PrefixOp.Return => { | 1007 | ast.NodePrefixOp.PrefixOp.Return => { |
| 1008 | %return stream.write("return "); | 1008 | try stream.write("return "); |
| 1009 | }, | 1009 | }, |
| 1010 | ast.NodePrefixOp.PrefixOp.AddrOf => |addr_of_info| { | 1010 | ast.NodePrefixOp.PrefixOp.AddrOf => |addr_of_info| { |
| 1011 | %return stream.write("&"); | 1011 | try stream.write("&"); |
| 1012 | if (addr_of_info.volatile_token != null) { | 1012 | if (addr_of_info.volatile_token != null) { |
| 1013 | %return stack.append(RenderState { .Text = "volatile "}); | 1013 | try stack.append(RenderState { .Text = "volatile "}); |
| 1014 | } | 1014 | } |
| 1015 | if (addr_of_info.const_token != null) { | 1015 | if (addr_of_info.const_token != null) { |
| 1016 | %return stack.append(RenderState { .Text = "const "}); | 1016 | try stack.append(RenderState { .Text = "const "}); |
| 1017 | } | 1017 | } |
| 1018 | if (addr_of_info.align_expr) |align_expr| { | 1018 | if (addr_of_info.align_expr) |align_expr| { |
| 1019 | %return stream.print("align("); | 1019 | try stream.print("align("); |
| 1020 | %return stack.append(RenderState { .Text = ") "}); | 1020 | try stack.append(RenderState { .Text = ") "}); |
| 1021 | %return stack.append(RenderState { .Expression = align_expr}); | 1021 | try stack.append(RenderState { .Expression = align_expr}); |
| 1022 | } | 1022 | } |
| 1023 | }, | 1023 | }, |
| 1024 | else => unreachable, | 1024 | else => unreachable, |
| ... | @@ -1026,42 +1026,42 @@ pub const Parser = struct { | ... | @@ -1026,42 +1026,42 @@ pub const Parser = struct { |
| 1026 | }, | 1026 | }, |
| 1027 | ast.Node.Id.IntegerLiteral => { | 1027 | ast.Node.Id.IntegerLiteral => { |
| 1028 | const integer_literal = @fieldParentPtr(ast.NodeIntegerLiteral, "base", base); | 1028 | const integer_literal = @fieldParentPtr(ast.NodeIntegerLiteral, "base", base); |
| 1029 | %return stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token)); | 1029 | try stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token)); |
| 1030 | }, | 1030 | }, |
| 1031 | ast.Node.Id.FloatLiteral => { | 1031 | ast.Node.Id.FloatLiteral => { |
| 1032 | const float_literal = @fieldParentPtr(ast.NodeFloatLiteral, "base", base); | 1032 | const float_literal = @fieldParentPtr(ast.NodeFloatLiteral, "base", base); |
| 1033 | %return stream.print("{}", self.tokenizer.getTokenSlice(float_literal.token)); | 1033 | try stream.print("{}", self.tokenizer.getTokenSlice(float_literal.token)); |
| 1034 | }, | 1034 | }, |
| 1035 | else => unreachable, | 1035 | else => unreachable, |
| 1036 | }, | 1036 | }, |
| 1037 | RenderState.FnProtoRParen => |fn_proto| { | 1037 | RenderState.FnProtoRParen => |fn_proto| { |
| 1038 | %return stream.print(")"); | 1038 | try stream.print(")"); |
| 1039 | if (fn_proto.align_expr != null) { | 1039 | if (fn_proto.align_expr != null) { |
| 1040 | @panic("TODO"); | 1040 | @panic("TODO"); |
| 1041 | } | 1041 | } |
| 1042 | if (fn_proto.return_type) |return_type| { | 1042 | if (fn_proto.return_type) |return_type| { |
| 1043 | %return stream.print(" -> "); | 1043 | try stream.print(" -> "); |
| 1044 | if (fn_proto.body_node) |body_node| { | 1044 | if (fn_proto.body_node) |body_node| { |
| 1045 | %return stack.append(RenderState { .Expression = body_node}); | 1045 | try stack.append(RenderState { .Expression = body_node}); |
| 1046 | %return stack.append(RenderState { .Text = " "}); | 1046 | try stack.append(RenderState { .Text = " "}); |
| 1047 | } | 1047 | } |
| 1048 | %return stack.append(RenderState { .Expression = return_type}); | 1048 | try stack.append(RenderState { .Expression = return_type}); |
| 1049 | } | 1049 | } |
| 1050 | }, | 1050 | }, |
| 1051 | RenderState.Statement => |base| { | 1051 | RenderState.Statement => |base| { |
| 1052 | switch (base.id) { | 1052 | switch (base.id) { |
| 1053 | ast.Node.Id.VarDecl => { | 1053 | ast.Node.Id.VarDecl => { |
| 1054 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base); | 1054 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base); |
| 1055 | %return stack.append(RenderState { .VarDecl = var_decl}); | 1055 | try stack.append(RenderState { .VarDecl = var_decl}); |
| 1056 | }, | 1056 | }, |
| 1057 | else => { | 1057 | else => { |
| 1058 | %return stack.append(RenderState { .Text = ";"}); | 1058 | try stack.append(RenderState { .Text = ";"}); |
| 1059 | %return stack.append(RenderState { .Expression = base}); | 1059 | try stack.append(RenderState { .Expression = base}); |
| 1060 | }, | 1060 | }, |
| 1061 | } | 1061 | } |
| 1062 | }, | 1062 | }, |
| 1063 | RenderState.Indent => |new_indent| indent = new_indent, | 1063 | RenderState.Indent => |new_indent| indent = new_indent, |
| 1064 | RenderState.PrintIndent => %return stream.writeByteNTimes(' ', indent), | 1064 | RenderState.PrintIndent => try stream.writeByteNTimes(' ', indent), |
| 1065 | } | 1065 | } |
| 1066 | } | 1066 | } |
| 1067 | } | 1067 | } |
| ... | @@ -1096,12 +1096,12 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 { | ... | @@ -1096,12 +1096,12 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 { |
| 1096 | var parser = Parser.init(&tokenizer, allocator, "(memory buffer)"); | 1096 | var parser = Parser.init(&tokenizer, allocator, "(memory buffer)"); |
| 1097 | defer parser.deinit(); | 1097 | defer parser.deinit(); |
| 1098 | 1098 | ||
| 1099 | const root_node = %return parser.parse(); | 1099 | const root_node = try parser.parse(); |
| 1100 | defer parser.freeAst(root_node); | 1100 | defer parser.freeAst(root_node); |
| 1101 | 1101 | ||
| 1102 | var buffer = %return std.Buffer.initSize(allocator, 0); | 1102 | var buffer = try std.Buffer.initSize(allocator, 0); |
| 1103 | var buffer_out_stream = io.BufferOutStream.init(&buffer); | 1103 | var buffer_out_stream = io.BufferOutStream.init(&buffer); |
| 1104 | %return parser.renderSource(&buffer_out_stream.stream, root_node); | 1104 | try parser.renderSource(&buffer_out_stream.stream, root_node); |
| 1105 | return buffer.toOwnedSlice(); | 1105 | return buffer.toOwnedSlice(); |
| 1106 | } | 1106 | } |
| 1107 | 1107 | ||
| ... | @@ -1112,7 +1112,7 @@ fn testCanonical(source: []const u8) { | ... | @@ -1112,7 +1112,7 @@ fn testCanonical(source: []const u8) { |
| 1112 | // Try it once with unlimited memory, make sure it works | 1112 | // Try it once with unlimited memory, make sure it works |
| 1113 | var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); | 1113 | var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); |
| 1114 | var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize)); | 1114 | var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize)); |
| 1115 | const result_source = testParse(source, &failing_allocator.allocator) %% @panic("test failed"); | 1115 | const result_source = testParse(source, &failing_allocator.allocator) catch @panic("test failed"); |
| 1116 | if (!mem.eql(u8, result_source, source)) { | 1116 | if (!mem.eql(u8, result_source, source)) { |
| 1117 | warn("\n====== expected this output: =========\n"); | 1117 | warn("\n====== expected this output: =========\n"); |
| 1118 | warn("{}", source); | 1118 | warn("{}", source); |
src-self-hosted/target.zig+1-1| ... | @@ -38,7 +38,7 @@ pub const Target = union(enum) { | ... | @@ -38,7 +38,7 @@ pub const Target = union(enum) { |
| 38 | 38 | ||
| 39 | pub fn isDarwin(self: &const Target) -> bool { | 39 | pub fn isDarwin(self: &const Target) -> bool { |
| 40 | return switch (self.getOs()) { | 40 | return switch (self.getOs()) { |
| 41 | builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => true, | 41 | builtin.Os.ios, builtin.Os.macosx => true, |
| 42 | else => false, | 42 | else => false, |
| 43 | }; | 43 | }; |
| 44 | } | 44 | } |
src-self-hosted/tokenizer.zig+4-4| ... | @@ -557,22 +557,22 @@ pub const Tokenizer = struct { | ... | @@ -557,22 +557,22 @@ pub const Tokenizer = struct { |
| 557 | return 0; | 557 | return 0; |
| 558 | } else { | 558 | } else { |
| 559 | // check utf8-encoded character. | 559 | // check utf8-encoded character. |
| 560 | const length = std.unicode.utf8ByteSequenceLength(c0) %% return 1; | 560 | const length = std.unicode.utf8ByteSequenceLength(c0) catch return 1; |
| 561 | // the last 3 bytes in the buffer are guaranteed to be '\n', | 561 | // the last 3 bytes in the buffer are guaranteed to be '\n', |
| 562 | // which means we don't need to do any bounds checking here. | 562 | // which means we don't need to do any bounds checking here. |
| 563 | const bytes = self.buffer[self.index..self.index + length]; | 563 | const bytes = self.buffer[self.index..self.index + length]; |
| 564 | switch (length) { | 564 | switch (length) { |
| 565 | 2 => { | 565 | 2 => { |
| 566 | const value = std.unicode.utf8Decode2(bytes) %% return length; | 566 | const value = std.unicode.utf8Decode2(bytes) catch return length; |
| 567 | if (value == 0x85) return length; // U+0085 (NEL) | 567 | if (value == 0x85) return length; // U+0085 (NEL) |
| 568 | }, | 568 | }, |
| 569 | 3 => { | 569 | 3 => { |
| 570 | const value = std.unicode.utf8Decode3(bytes) %% return length; | 570 | const value = std.unicode.utf8Decode3(bytes) catch return length; |
| 571 | if (value == 0x2028) return length; // U+2028 (LS) | 571 | if (value == 0x2028) return length; // U+2028 (LS) |
| 572 | if (value == 0x2029) return length; // U+2029 (PS) | 572 | if (value == 0x2029) return length; // U+2029 (PS) |
| 573 | }, | 573 | }, |
| 574 | 4 => { | 574 | 4 => { |
| 575 | _ = std.unicode.utf8Decode4(bytes) %% return length; | 575 | _ = std.unicode.utf8Decode4(bytes) catch return length; |
| 576 | }, | 576 | }, |
| 577 | else => unreachable, | 577 | else => unreachable, |
| 578 | } | 578 | } |
src/all_types.hpp+7-12| ... | @@ -37,13 +37,7 @@ struct ScopeDecls; | ... | @@ -37,13 +37,7 @@ struct ScopeDecls; |
| 37 | struct ZigWindowsSDK; | 37 | struct ZigWindowsSDK; |
| 38 | struct Tld; | 38 | struct Tld; |
| 39 | struct TldExport; | 39 | struct TldExport; |
| 40 | 40 | struct IrAnalyze; | |
| 41 | struct IrGotoItem { | ||
| 42 | AstNode *source_node; | ||
| 43 | IrBasicBlock *bb; | ||
| 44 | size_t instruction_index; | ||
| 45 | Scope *scope; | ||
| 46 | }; | ||
| 47 | 41 | ||
| 48 | struct IrExecutable { | 42 | struct IrExecutable { |
| 49 | ZigList<IrBasicBlock *> basic_block_list; | 43 | ZigList<IrBasicBlock *> basic_block_list; |
| ... | @@ -53,13 +47,13 @@ struct IrExecutable { | ... | @@ -53,13 +47,13 @@ struct IrExecutable { |
| 53 | size_t *backward_branch_count; | 47 | size_t *backward_branch_count; |
| 54 | size_t backward_branch_quota; | 48 | size_t backward_branch_quota; |
| 55 | bool invalid; | 49 | bool invalid; |
| 56 | ZigList<IrGotoItem> goto_list; | ||
| 57 | bool is_inline; | 50 | bool is_inline; |
| 58 | FnTableEntry *fn_entry; | 51 | FnTableEntry *fn_entry; |
| 59 | Buf *c_import_buf; | 52 | Buf *c_import_buf; |
| 60 | AstNode *source_node; | 53 | AstNode *source_node; |
| 61 | IrExecutable *parent_exec; | 54 | IrExecutable *parent_exec; |
| 62 | IrExecutable *source_exec; | 55 | IrExecutable *source_exec; |
| 56 | IrAnalyze *analysis; | ||
| 63 | Scope *begin_scope; | 57 | Scope *begin_scope; |
| 64 | ZigList<Tld *> tld_list; | 58 | ZigList<Tld *> tld_list; |
| 65 | }; | 59 | }; |
| ... | @@ -395,7 +389,7 @@ enum NodeType { | ... | @@ -395,7 +389,7 @@ enum NodeType { |
| 395 | NodeTypeArrayType, | 389 | NodeTypeArrayType, |
| 396 | NodeTypeErrorType, | 390 | NodeTypeErrorType, |
| 397 | NodeTypeVarLiteral, | 391 | NodeTypeVarLiteral, |
| 398 | NodeTypeTryExpr, | 392 | NodeTypeIfErrorExpr, |
| 399 | NodeTypeTestExpr, | 393 | NodeTypeTestExpr, |
| 400 | }; | 394 | }; |
| 401 | 395 | ||
| ... | @@ -552,7 +546,7 @@ struct AstNodeBinOpExpr { | ... | @@ -552,7 +546,7 @@ struct AstNodeBinOpExpr { |
| 552 | AstNode *op2; | 546 | AstNode *op2; |
| 553 | }; | 547 | }; |
| 554 | 548 | ||
| 555 | struct AstNodeUnwrapErrorExpr { | 549 | struct AstNodeCatchExpr { |
| 556 | AstNode *op1; | 550 | AstNode *op1; |
| 557 | AstNode *symbol; // can be null | 551 | AstNode *symbol; // can be null |
| 558 | AstNode *op2; | 552 | AstNode *op2; |
| ... | @@ -866,7 +860,7 @@ struct AstNode { | ... | @@ -866,7 +860,7 @@ struct AstNode { |
| 866 | AstNodeErrorValueDecl error_value_decl; | 860 | AstNodeErrorValueDecl error_value_decl; |
| 867 | AstNodeTestDecl test_decl; | 861 | AstNodeTestDecl test_decl; |
| 868 | AstNodeBinOpExpr bin_op_expr; | 862 | AstNodeBinOpExpr bin_op_expr; |
| 869 | AstNodeUnwrapErrorExpr unwrap_err_expr; | 863 | AstNodeCatchExpr unwrap_err_expr; |
| 870 | AstNodePrefixOpExpr prefix_op_expr; | 864 | AstNodePrefixOpExpr prefix_op_expr; |
| 871 | AstNodeAddrOfExpr addr_of_expr; | 865 | AstNodeAddrOfExpr addr_of_expr; |
| 872 | AstNodeFnCallExpr fn_call_expr; | 866 | AstNodeFnCallExpr fn_call_expr; |
| ... | @@ -874,7 +868,7 @@ struct AstNode { | ... | @@ -874,7 +868,7 @@ struct AstNode { |
| 874 | AstNodeSliceExpr slice_expr; | 868 | AstNodeSliceExpr slice_expr; |
| 875 | AstNodeUse use; | 869 | AstNodeUse use; |
| 876 | AstNodeIfBoolExpr if_bool_expr; | 870 | AstNodeIfBoolExpr if_bool_expr; |
| 877 | AstNodeTryExpr try_expr; | 871 | AstNodeTryExpr if_err_expr; |
| 878 | AstNodeTestExpr test_expr; | 872 | AstNodeTestExpr test_expr; |
| 879 | AstNodeWhileExpr while_expr; | 873 | AstNodeWhileExpr while_expr; |
| 880 | AstNodeForExpr for_expr; | 874 | AstNodeForExpr for_expr; |
| ... | @@ -1626,6 +1620,7 @@ struct VariableTableEntry { | ... | @@ -1626,6 +1620,7 @@ struct VariableTableEntry { |
| 1626 | LLVMValueRef param_value_ref; | 1620 | LLVMValueRef param_value_ref; |
| 1627 | bool shadowable; | 1621 | bool shadowable; |
| 1628 | size_t mem_slot_index; | 1622 | size_t mem_slot_index; |
| 1623 | IrExecutable *owner_exec; | ||
| 1629 | size_t ref_count; | 1624 | size_t ref_count; |
| 1630 | VarLinkage linkage; | 1625 | VarLinkage linkage; |
| 1631 | IrInstruction *decl_instruction; | 1626 | IrInstruction *decl_instruction; |
src/analyze.cpp+10-10| ... | @@ -32,7 +32,7 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) { | ... | @@ -32,7 +32,7 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) { |
| 32 | // failed semantic analysis, which isn't supposed to happen | 32 | // failed semantic analysis, which isn't supposed to happen |
| 33 | ErrorMsg *err = add_node_error(g, node->owner->c_import_node, | 33 | ErrorMsg *err = add_node_error(g, node->owner->c_import_node, |
| 34 | buf_sprintf("compiler bug: @cImport generated invalid zig code")); | 34 | buf_sprintf("compiler bug: @cImport generated invalid zig code")); |
| 35 | 35 | ||
| 36 | add_error_note(g, err, node, msg); | 36 | add_error_note(g, err, node, msg); |
| 37 | 37 | ||
| 38 | g->errors.append(err); | 38 | g->errors.append(err); |
| ... | @@ -2425,7 +2425,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { | ... | @@ -2425,7 +2425,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { |
| 2425 | qual_str = "extern"; | 2425 | qual_str = "extern"; |
| 2426 | break; | 2426 | break; |
| 2427 | } | 2427 | } |
| 2428 | AstNode *source_node = (decl_node->data.container_decl.init_arg_expr != nullptr) ? | 2428 | AstNode *source_node = (decl_node->data.container_decl.init_arg_expr != nullptr) ? |
| 2429 | decl_node->data.container_decl.init_arg_expr : decl_node; | 2429 | decl_node->data.container_decl.init_arg_expr : decl_node; |
| 2430 | add_node_error(g, source_node, | 2430 | add_node_error(g, source_node, |
| 2431 | buf_sprintf("%s union does not support enum tag type", qual_str)); | 2431 | buf_sprintf("%s union does not support enum tag type", qual_str)); |
| ... | @@ -2599,17 +2599,17 @@ void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, G | ... | @@ -2599,17 +2599,17 @@ void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, G |
| 2599 | g->windows_subsystem_windows = false; | 2599 | g->windows_subsystem_windows = false; |
| 2600 | g->windows_subsystem_console = true; | 2600 | g->windows_subsystem_console = true; |
| 2601 | } else if (buf_eql_str(symbol_name, "WinMain") && | 2601 | } else if (buf_eql_str(symbol_name, "WinMain") && |
| 2602 | g->zig_target.os == ZigLLVM_Win32) | 2602 | g->zig_target.os == OsWindows) |
| 2603 | { | 2603 | { |
| 2604 | g->have_winmain = true; | 2604 | g->have_winmain = true; |
| 2605 | g->windows_subsystem_windows = true; | 2605 | g->windows_subsystem_windows = true; |
| 2606 | g->windows_subsystem_console = false; | 2606 | g->windows_subsystem_console = false; |
| 2607 | } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && | 2607 | } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && |
| 2608 | g->zig_target.os == ZigLLVM_Win32) | 2608 | g->zig_target.os == OsWindows) |
| 2609 | { | 2609 | { |
| 2610 | g->have_winmain_crt_startup = true; | 2610 | g->have_winmain_crt_startup = true; |
| 2611 | } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") && | 2611 | } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") && |
| 2612 | g->zig_target.os == ZigLLVM_Win32) | 2612 | g->zig_target.os == OsWindows) |
| 2613 | { | 2613 | { |
| 2614 | g->have_dllmain_crt_startup = true; | 2614 | g->have_dllmain_crt_startup = true; |
| 2615 | } | 2615 | } |
| ... | @@ -2933,7 +2933,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { | ... | @@ -2933,7 +2933,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 2933 | case NodeTypeArrayType: | 2933 | case NodeTypeArrayType: |
| 2934 | case NodeTypeErrorType: | 2934 | case NodeTypeErrorType: |
| 2935 | case NodeTypeVarLiteral: | 2935 | case NodeTypeVarLiteral: |
| 2936 | case NodeTypeTryExpr: | 2936 | case NodeTypeIfErrorExpr: |
| 2937 | case NodeTypeTestExpr: | 2937 | case NodeTypeTestExpr: |
| 2938 | zig_unreachable(); | 2938 | zig_unreachable(); |
| 2939 | } | 2939 | } |
| ... | @@ -3994,7 +3994,7 @@ void find_libc_include_path(CodeGen *g) { | ... | @@ -3994,7 +3994,7 @@ void find_libc_include_path(CodeGen *g) { |
| 3994 | if (!g->libc_include_dir || buf_len(g->libc_include_dir) == 0) { | 3994 | if (!g->libc_include_dir || buf_len(g->libc_include_dir) == 0) { |
| 3995 | ZigWindowsSDK *sdk = get_windows_sdk(g); | 3995 | ZigWindowsSDK *sdk = get_windows_sdk(g); |
| 3996 | 3996 | ||
| 3997 | if (g->zig_target.os == ZigLLVM_Win32) { | 3997 | if (g->zig_target.os == OsWindows) { |
| 3998 | if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) { | 3998 | if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) { |
| 3999 | zig_panic("Unable to determine libc include path."); | 3999 | zig_panic("Unable to determine libc include path."); |
| 4000 | } | 4000 | } |
| ... | @@ -4010,9 +4010,9 @@ void find_libc_include_path(CodeGen *g) { | ... | @@ -4010,9 +4010,9 @@ void find_libc_include_path(CodeGen *g) { |
| 4010 | void find_libc_lib_path(CodeGen *g) { | 4010 | void find_libc_lib_path(CodeGen *g) { |
| 4011 | // later we can handle this better by reporting an error via the normal mechanism | 4011 | // later we can handle this better by reporting an error via the normal mechanism |
| 4012 | if (!g->libc_lib_dir || buf_len(g->libc_lib_dir) == 0 || | 4012 | if (!g->libc_lib_dir || buf_len(g->libc_lib_dir) == 0 || |
| 4013 | (g->zig_target.os == ZigLLVM_Win32 && (g->msvc_lib_dir == nullptr || g->kernel32_lib_dir == nullptr))) | 4013 | (g->zig_target.os == OsWindows && (g->msvc_lib_dir == nullptr || g->kernel32_lib_dir == nullptr))) |
| 4014 | { | 4014 | { |
| 4015 | if (g->zig_target.os == ZigLLVM_Win32) { | 4015 | if (g->zig_target.os == OsWindows) { |
| 4016 | ZigWindowsSDK *sdk = get_windows_sdk(g); | 4016 | ZigWindowsSDK *sdk = get_windows_sdk(g); |
| 4017 | 4017 | ||
| 4018 | Buf* vc_lib_dir = buf_alloc(); | 4018 | Buf* vc_lib_dir = buf_alloc(); |
| ... | @@ -4039,7 +4039,7 @@ void find_libc_lib_path(CodeGen *g) { | ... | @@ -4039,7 +4039,7 @@ void find_libc_lib_path(CodeGen *g) { |
| 4039 | } | 4039 | } |
| 4040 | 4040 | ||
| 4041 | if (!g->libc_static_lib_dir || buf_len(g->libc_static_lib_dir) == 0) { | 4041 | if (!g->libc_static_lib_dir || buf_len(g->libc_static_lib_dir) == 0) { |
| 4042 | if ((g->zig_target.os == ZigLLVM_Win32) && (g->msvc_lib_dir != NULL)) { | 4042 | if ((g->zig_target.os == OsWindows) && (g->msvc_lib_dir != NULL)) { |
| 4043 | return; | 4043 | return; |
| 4044 | } | 4044 | } |
| 4045 | else { | 4045 | else { |
src/ast_render.cpp+14-14| ... | @@ -68,7 +68,7 @@ static const char *prefix_op_str(PrefixOp prefix_op) { | ... | @@ -68,7 +68,7 @@ static const char *prefix_op_str(PrefixOp prefix_op) { |
| 68 | case PrefixOpDereference: return "*"; | 68 | case PrefixOpDereference: return "*"; |
| 69 | case PrefixOpMaybe: return "?"; | 69 | case PrefixOpMaybe: return "?"; |
| 70 | case PrefixOpError: return "%"; | 70 | case PrefixOpError: return "%"; |
| 71 | case PrefixOpUnwrapError: return "%%"; | 71 | case PrefixOpUnwrapError: return "catch"; |
| 72 | case PrefixOpUnwrapMaybe: return "??"; | 72 | case PrefixOpUnwrapMaybe: return "??"; |
| 73 | } | 73 | } |
| 74 | zig_unreachable(); | 74 | zig_unreachable(); |
| ... | @@ -85,7 +85,7 @@ static const char *visib_mod_string(VisibMod mod) { | ... | @@ -85,7 +85,7 @@ static const char *visib_mod_string(VisibMod mod) { |
| 85 | static const char *return_string(ReturnKind kind) { | 85 | static const char *return_string(ReturnKind kind) { |
| 86 | switch (kind) { | 86 | switch (kind) { |
| 87 | case ReturnKindUnconditional: return "return"; | 87 | case ReturnKindUnconditional: return "return"; |
| 88 | case ReturnKindError: return "%return"; | 88 | case ReturnKindError: return "try"; |
| 89 | } | 89 | } |
| 90 | zig_unreachable(); | 90 | zig_unreachable(); |
| 91 | } | 91 | } |
| ... | @@ -241,8 +241,8 @@ static const char *node_type_str(NodeType node_type) { | ... | @@ -241,8 +241,8 @@ static const char *node_type_str(NodeType node_type) { |
| 241 | return "ErrorType"; | 241 | return "ErrorType"; |
| 242 | case NodeTypeVarLiteral: | 242 | case NodeTypeVarLiteral: |
| 243 | return "VarLiteral"; | 243 | return "VarLiteral"; |
| 244 | case NodeTypeTryExpr: | 244 | case NodeTypeIfErrorExpr: |
| 245 | return "TryExpr"; | 245 | return "IfErrorExpr"; |
| 246 | case NodeTypeTestExpr: | 246 | case NodeTypeTestExpr: |
| 247 | return "TestExpr"; | 247 | return "TestExpr"; |
| 248 | } | 248 | } |
| ... | @@ -872,23 +872,23 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { | ... | @@ -872,23 +872,23 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 872 | fprintf(ar->f, "null"); | 872 | fprintf(ar->f, "null"); |
| 873 | break; | 873 | break; |
| 874 | } | 874 | } |
| 875 | case NodeTypeTryExpr: | 875 | case NodeTypeIfErrorExpr: |
| 876 | { | 876 | { |
| 877 | fprintf(ar->f, "if ("); | 877 | fprintf(ar->f, "if ("); |
| 878 | render_node_grouped(ar, node->data.try_expr.target_node); | 878 | render_node_grouped(ar, node->data.if_err_expr.target_node); |
| 879 | fprintf(ar->f, ") "); | 879 | fprintf(ar->f, ") "); |
| 880 | if (node->data.try_expr.var_symbol) { | 880 | if (node->data.if_err_expr.var_symbol) { |
| 881 | const char *ptr_str = node->data.try_expr.var_is_ptr ? "*" : ""; | 881 | const char *ptr_str = node->data.if_err_expr.var_is_ptr ? "*" : ""; |
| 882 | const char *var_name = buf_ptr(node->data.try_expr.var_symbol); | 882 | const char *var_name = buf_ptr(node->data.if_err_expr.var_symbol); |
| 883 | fprintf(ar->f, "|%s%s| ", ptr_str, var_name); | 883 | fprintf(ar->f, "|%s%s| ", ptr_str, var_name); |
| 884 | } | 884 | } |
| 885 | render_node_grouped(ar, node->data.try_expr.then_node); | 885 | render_node_grouped(ar, node->data.if_err_expr.then_node); |
| 886 | if (node->data.try_expr.else_node) { | 886 | if (node->data.if_err_expr.else_node) { |
| 887 | fprintf(ar->f, " else "); | 887 | fprintf(ar->f, " else "); |
| 888 | if (node->data.try_expr.err_symbol) { | 888 | if (node->data.if_err_expr.err_symbol) { |
| 889 | fprintf(ar->f, "|%s| ", buf_ptr(node->data.try_expr.err_symbol)); | 889 | fprintf(ar->f, "|%s| ", buf_ptr(node->data.if_err_expr.err_symbol)); |
| 890 | } | 890 | } |
| 891 | render_node_grouped(ar, node->data.try_expr.else_node); | 891 | render_node_grouped(ar, node->data.if_err_expr.else_node); |
| 892 | } | 892 | } |
| 893 | break; | 893 | break; |
| 894 | } | 894 | } |
src/codegen.cpp+13-15| ... | @@ -42,7 +42,7 @@ static void init_darwin_native(CodeGen *g) { | ... | @@ -42,7 +42,7 @@ static void init_darwin_native(CodeGen *g) { |
| 42 | g->mmacosx_version_min = buf_create_from_str(osx_target); | 42 | g->mmacosx_version_min = buf_create_from_str(osx_target); |
| 43 | } else if (ios_target) { | 43 | } else if (ios_target) { |
| 44 | g->mios_version_min = buf_create_from_str(ios_target); | 44 | g->mios_version_min = buf_create_from_str(ios_target); |
| 45 | } else if (g->zig_target.os != ZigLLVM_IOS) { | 45 | } else if (g->zig_target.os != OsIOS) { |
| 46 | g->mmacosx_version_min = buf_create_from_str("10.10"); | 46 | g->mmacosx_version_min = buf_create_from_str("10.10"); |
| 47 | } | 47 | } |
| 48 | } | 48 | } |
| ... | @@ -136,9 +136,8 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out | ... | @@ -136,9 +136,8 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out |
| 136 | g->each_lib_rpath = true; | 136 | g->each_lib_rpath = true; |
| 137 | #endif | 137 | #endif |
| 138 | 138 | ||
| 139 | if (g->zig_target.os == ZigLLVM_Darwin || | 139 | if (g->zig_target.os == OsMacOSX || |
| 140 | g->zig_target.os == ZigLLVM_MacOSX || | 140 | g->zig_target.os == OsIOS) |
| 141 | g->zig_target.os == ZigLLVM_IOS) | ||
| 142 | { | 141 | { |
| 143 | init_darwin_native(g); | 142 | init_darwin_native(g); |
| 144 | } | 143 | } |
| ... | @@ -146,9 +145,8 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out | ... | @@ -146,9 +145,8 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out |
| 146 | } | 145 | } |
| 147 | 146 | ||
| 148 | // On Darwin/MacOS/iOS, we always link libSystem which contains libc. | 147 | // On Darwin/MacOS/iOS, we always link libSystem which contains libc. |
| 149 | if (g->zig_target.os == ZigLLVM_Darwin || | 148 | if (g->zig_target.os == OsMacOSX || |
| 150 | g->zig_target.os == ZigLLVM_MacOSX || | 149 | g->zig_target.os == OsIOS) |
| 151 | g->zig_target.os == ZigLLVM_IOS) | ||
| 152 | { | 150 | { |
| 153 | g->libc_link_lib = create_link_lib(buf_create_from_str("c")); | 151 | g->libc_link_lib = create_link_lib(buf_create_from_str("c")); |
| 154 | g->link_libs_list.append(g->libc_link_lib); | 152 | g->link_libs_list.append(g->libc_link_lib); |
| ... | @@ -363,7 +361,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { | ... | @@ -363,7 +361,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { |
| 363 | g->zig_target.arch.arch == ZigLLVM_x86_64) | 361 | g->zig_target.arch.arch == ZigLLVM_x86_64) |
| 364 | { | 362 | { |
| 365 | // cold calling convention is not supported on windows | 363 | // cold calling convention is not supported on windows |
| 366 | if (g->zig_target.os == ZigLLVM_Win32) { | 364 | if (g->zig_target.os == OsWindows) { |
| 367 | return LLVMCCallConv; | 365 | return LLVMCCallConv; |
| 368 | } else { | 366 | } else { |
| 369 | return LLVMColdCallConv; | 367 | return LLVMColdCallConv; |
| ... | @@ -386,7 +384,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { | ... | @@ -386,7 +384,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { |
| 386 | } | 384 | } |
| 387 | 385 | ||
| 388 | static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { | 386 | static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { |
| 389 | if (g->zig_target.os == ZigLLVM_Win32) { | 387 | if (g->zig_target.os == OsWindows) { |
| 390 | addLLVMFnAttr(fn_val, "uwtable"); | 388 | addLLVMFnAttr(fn_val, "uwtable"); |
| 391 | } | 389 | } |
| 392 | } | 390 | } |
| ... | @@ -559,7 +557,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { | ... | @@ -559,7 +557,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 559 | } | 557 | } |
| 560 | // Note: byval is disabled on windows due to an LLVM bug: | 558 | // Note: byval is disabled on windows due to an LLVM bug: |
| 561 | // https://github.com/zig-lang/zig/issues/536 | 559 | // https://github.com/zig-lang/zig/issues/536 |
| 562 | if (is_byval && g->zig_target.os != ZigLLVM_Win32) { | 560 | if (is_byval && g->zig_target.os != OsWindows) { |
| 563 | addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval"); | 561 | addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval"); |
| 564 | } | 562 | } |
| 565 | } | 563 | } |
| ... | @@ -2371,7 +2369,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -2371,7 +2369,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 2371 | FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; | 2369 | FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; |
| 2372 | // Note: byval is disabled on windows due to an LLVM bug: | 2370 | // Note: byval is disabled on windows due to an LLVM bug: |
| 2373 | // https://github.com/zig-lang/zig/issues/536 | 2371 | // https://github.com/zig-lang/zig/issues/536 |
| 2374 | if (gen_info->is_byval && g->zig_target.os != ZigLLVM_Win32) { | 2372 | if (gen_info->is_byval && g->zig_target.os != OsWindows) { |
| 2375 | addLLVMCallsiteAttr(result, (unsigned)gen_info->gen_index, "byval"); | 2373 | addLLVMCallsiteAttr(result, (unsigned)gen_info->gen_index, "byval"); |
| 2376 | } | 2374 | } |
| 2377 | } | 2375 | } |
| ... | @@ -5094,7 +5092,7 @@ static void define_builtin_compile_vars(CodeGen *g) { | ... | @@ -5094,7 +5092,7 @@ static void define_builtin_compile_vars(CodeGen *g) { |
| 5094 | buf_appendf(contents, "pub const Os = enum {\n"); | 5092 | buf_appendf(contents, "pub const Os = enum {\n"); |
| 5095 | uint32_t field_count = (uint32_t)target_os_count(); | 5093 | uint32_t field_count = (uint32_t)target_os_count(); |
| 5096 | for (uint32_t i = 0; i < field_count; i += 1) { | 5094 | for (uint32_t i = 0; i < field_count; i += 1) { |
| 5097 | ZigLLVM_OSType os_type = get_target_os(i); | 5095 | Os os_type = get_target_os(i); |
| 5098 | const char *name = get_target_os_name(os_type); | 5096 | const char *name = get_target_os_name(os_type); |
| 5099 | buf_appendf(contents, " %s,\n", name); | 5097 | buf_appendf(contents, " %s,\n", name); |
| 5100 | 5098 | ||
| ... | @@ -5304,7 +5302,7 @@ static void init(CodeGen *g) { | ... | @@ -5304,7 +5302,7 @@ static void init(CodeGen *g) { |
| 5304 | // LLVM creates invalid binaries on Windows sometimes. | 5302 | // LLVM creates invalid binaries on Windows sometimes. |
| 5305 | // See https://github.com/zig-lang/zig/issues/508 | 5303 | // See https://github.com/zig-lang/zig/issues/508 |
| 5306 | // As a workaround we do not use target native features on Windows. | 5304 | // As a workaround we do not use target native features on Windows. |
| 5307 | if (g->zig_target.os == ZigLLVM_Win32) { | 5305 | if (g->zig_target.os == OsWindows) { |
| 5308 | target_specific_cpu_args = ""; | 5306 | target_specific_cpu_args = ""; |
| 5309 | target_specific_features = ""; | 5307 | target_specific_features = ""; |
| 5310 | } else { | 5308 | } else { |
| ... | @@ -5524,13 +5522,13 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -5524,13 +5522,13 @@ static void gen_root_source(CodeGen *g) { |
| 5524 | } | 5522 | } |
| 5525 | report_errors_and_maybe_exit(g); | 5523 | report_errors_and_maybe_exit(g); |
| 5526 | 5524 | ||
| 5527 | if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && | 5525 | if (!g->is_test_build && g->zig_target.os != OsFreestanding && |
| 5528 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && | 5526 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && |
| 5529 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) | 5527 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) |
| 5530 | { | 5528 | { |
| 5531 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig"); | 5529 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig"); |
| 5532 | } | 5530 | } |
| 5533 | if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) { | 5531 | if (g->zig_target.os == OsWindows && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) { |
| 5534 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig"); | 5532 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig"); |
| 5535 | } | 5533 | } |
| 5536 | 5534 |
src/ir.cpp+75-53| ... | @@ -2530,8 +2530,10 @@ static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *s | ... | @@ -2530,8 +2530,10 @@ static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *s |
| 2530 | bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) | 2530 | bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) |
| 2531 | { | 2531 | { |
| 2532 | VariableTableEntry *var = create_local_var(irb->codegen, node, scope, name, src_is_const, gen_is_const, is_shadowable, is_comptime); | 2532 | VariableTableEntry *var = create_local_var(irb->codegen, node, scope, name, src_is_const, gen_is_const, is_shadowable, is_comptime); |
| 2533 | if (is_comptime != nullptr || gen_is_const) | 2533 | if (is_comptime != nullptr || gen_is_const) { |
| 2534 | var->mem_slot_index = exec_next_mem_slot(irb->exec); | 2534 | var->mem_slot_index = exec_next_mem_slot(irb->exec); |
| 2535 | var->owner_exec = irb->exec; | ||
| 2536 | } | ||
| 2535 | assert(var->child_scope); | 2537 | assert(var->child_scope); |
| 2536 | return var; | 2538 | return var; |
| 2537 | } | 2539 | } |
| ... | @@ -3896,22 +3898,21 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -3896,22 +3898,21 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n |
| 3896 | align_value, bit_offset_start, bit_offset_end); | 3898 | align_value, bit_offset_start, bit_offset_end); |
| 3897 | } | 3899 | } |
| 3898 | 3900 | ||
| 3899 | static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | 3901 | static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, |
| 3900 | assert(node->type == NodeTypePrefixOpExpr); | 3902 | LVal lval) |
| 3901 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; | 3903 | { |
| 3902 | |||
| 3903 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR); | 3904 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR); |
| 3904 | if (err_union_ptr == irb->codegen->invalid_instruction) | 3905 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 3905 | return irb->codegen->invalid_instruction; | 3906 | return irb->codegen->invalid_instruction; |
| 3906 | 3907 | ||
| 3907 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, true); | 3908 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true); |
| 3908 | if (payload_ptr == irb->codegen->invalid_instruction) | 3909 | if (payload_ptr == irb->codegen->invalid_instruction) |
| 3909 | return irb->codegen->invalid_instruction; | 3910 | return irb->codegen->invalid_instruction; |
| 3910 | 3911 | ||
| 3911 | if (lval.is_ptr) | 3912 | if (lval.is_ptr) |
| 3912 | return payload_ptr; | 3913 | return payload_ptr; |
| 3913 | 3914 | ||
| 3914 | return ir_build_load_ptr(irb, scope, node, payload_ptr); | 3915 | return ir_build_load_ptr(irb, scope, source_node, payload_ptr); |
| 3915 | } | 3916 | } |
| 3916 | 3917 | ||
| 3917 | static IrInstruction *ir_gen_maybe_assert_ok(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | 3918 | static IrInstruction *ir_gen_maybe_assert_ok(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| ... | @@ -3963,7 +3964,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod | ... | @@ -3963,7 +3964,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod |
| 3963 | case PrefixOpError: | 3964 | case PrefixOpError: |
| 3964 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpError), lval); | 3965 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpError), lval); |
| 3965 | case PrefixOpUnwrapError: | 3966 | case PrefixOpUnwrapError: |
| 3966 | return ir_gen_err_assert_ok(irb, scope, node, lval); | 3967 | return ir_gen_err_assert_ok(irb, scope, node, node->data.prefix_op_expr.primary_expr, lval); |
| 3967 | case PrefixOpUnwrapMaybe: | 3968 | case PrefixOpUnwrapMaybe: |
| 3968 | return ir_gen_maybe_assert_ok(irb, scope, node, lval); | 3969 | return ir_gen_maybe_assert_ok(irb, scope, node, lval); |
| 3969 | } | 3970 | } |
| ... | @@ -4663,16 +4664,16 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no | ... | @@ -4663,16 +4664,16 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no |
| 4663 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 4664 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 4664 | } | 4665 | } |
| 4665 | 4666 | ||
| 4666 | static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 4667 | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 4667 | assert(node->type == NodeTypeTryExpr); | 4668 | assert(node->type == NodeTypeIfErrorExpr); |
| 4668 | 4669 | ||
| 4669 | AstNode *target_node = node->data.try_expr.target_node; | 4670 | AstNode *target_node = node->data.if_err_expr.target_node; |
| 4670 | AstNode *then_node = node->data.try_expr.then_node; | 4671 | AstNode *then_node = node->data.if_err_expr.then_node; |
| 4671 | AstNode *else_node = node->data.try_expr.else_node; | 4672 | AstNode *else_node = node->data.if_err_expr.else_node; |
| 4672 | bool var_is_ptr = node->data.try_expr.var_is_ptr; | 4673 | bool var_is_ptr = node->data.if_err_expr.var_is_ptr; |
| 4673 | bool var_is_const = true; | 4674 | bool var_is_const = true; |
| 4674 | Buf *var_symbol = node->data.try_expr.var_symbol; | 4675 | Buf *var_symbol = node->data.if_err_expr.var_symbol; |
| 4675 | Buf *err_symbol = node->data.try_expr.err_symbol; | 4676 | Buf *err_symbol = node->data.if_err_expr.err_symbol; |
| 4676 | 4677 | ||
| 4677 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LVAL_PTR); | 4678 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LVAL_PTR); |
| 4678 | if (err_val_ptr == irb->codegen->invalid_instruction) | 4679 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| ... | @@ -5179,6 +5180,17 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN | ... | @@ -5179,6 +5180,17 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN |
| 5179 | AstNode *op2_node = node->data.unwrap_err_expr.op2; | 5180 | AstNode *op2_node = node->data.unwrap_err_expr.op2; |
| 5180 | AstNode *var_node = node->data.unwrap_err_expr.symbol; | 5181 | AstNode *var_node = node->data.unwrap_err_expr.symbol; |
| 5181 | 5182 | ||
| 5183 | if (op2_node->type == NodeTypeUnreachable) { | ||
| 5184 | if (var_node != nullptr) { | ||
| 5185 | assert(var_node->type == NodeTypeSymbol); | ||
| 5186 | Buf *var_name = var_node->data.symbol_expr.symbol; | ||
| 5187 | add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); | ||
| 5188 | return irb->codegen->invalid_instruction; | ||
| 5189 | } | ||
| 5190 | return ir_gen_err_assert_ok(irb, parent_scope, node, op1_node, LVAL_NONE); | ||
| 5191 | } | ||
| 5192 | |||
| 5193 | |||
| 5182 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LVAL_PTR); | 5194 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LVAL_PTR); |
| 5183 | if (err_union_ptr == irb->codegen->invalid_instruction) | 5195 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 5184 | return irb->codegen->invalid_instruction; | 5196 | return irb->codegen->invalid_instruction; |
| ... | @@ -5409,8 +5421,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -5409,8 +5421,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 5409 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); | 5421 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); |
| 5410 | case NodeTypeVarLiteral: | 5422 | case NodeTypeVarLiteral: |
| 5411 | return ir_lval_wrap(irb, scope, ir_gen_var_literal(irb, scope, node), lval); | 5423 | return ir_lval_wrap(irb, scope, ir_gen_var_literal(irb, scope, node), lval); |
| 5412 | case NodeTypeTryExpr: | 5424 | case NodeTypeIfErrorExpr: |
| 5413 | return ir_lval_wrap(irb, scope, ir_gen_try_expr(irb, scope, node), lval); | 5425 | return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval); |
| 5414 | case NodeTypeTestExpr: | 5426 | case NodeTypeTestExpr: |
| 5415 | return ir_lval_wrap(irb, scope, ir_gen_test_expr(irb, scope, node), lval); | 5427 | return ir_lval_wrap(irb, scope, ir_gen_test_expr(irb, scope, node), lval); |
| 5416 | case NodeTypeSwitchExpr: | 5428 | case NodeTypeSwitchExpr: |
| ... | @@ -7037,48 +7049,48 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node | ... | @@ -7037,48 +7049,48 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node |
| 7037 | if (expected_type != nullptr && type_is_invalid(expected_type)) | 7049 | if (expected_type != nullptr && type_is_invalid(expected_type)) |
| 7038 | return codegen->invalid_instruction; | 7050 | return codegen->invalid_instruction; |
| 7039 | 7051 | ||
| 7040 | IrExecutable ir_executable = {0}; | 7052 | IrExecutable *ir_executable = allocate<IrExecutable>(1); |
| 7041 | ir_executable.source_node = source_node; | 7053 | ir_executable->source_node = source_node; |
| 7042 | ir_executable.parent_exec = parent_exec; | 7054 | ir_executable->parent_exec = parent_exec; |
| 7043 | ir_executable.name = exec_name; | 7055 | ir_executable->name = exec_name; |
| 7044 | ir_executable.is_inline = true; | 7056 | ir_executable->is_inline = true; |
| 7045 | ir_executable.fn_entry = fn_entry; | 7057 | ir_executable->fn_entry = fn_entry; |
| 7046 | ir_executable.c_import_buf = c_import_buf; | 7058 | ir_executable->c_import_buf = c_import_buf; |
| 7047 | ir_executable.begin_scope = scope; | 7059 | ir_executable->begin_scope = scope; |
| 7048 | ir_gen(codegen, node, scope, &ir_executable); | 7060 | ir_gen(codegen, node, scope, ir_executable); |
| 7049 | 7061 | ||
| 7050 | if (ir_executable.invalid) | 7062 | if (ir_executable->invalid) |
| 7051 | return codegen->invalid_instruction; | 7063 | return codegen->invalid_instruction; |
| 7052 | 7064 | ||
| 7053 | if (codegen->verbose_ir) { | 7065 | if (codegen->verbose_ir) { |
| 7054 | fprintf(stderr, "\nSource: "); | 7066 | fprintf(stderr, "\nSource: "); |
| 7055 | ast_render(codegen, stderr, node, 4); | 7067 | ast_render(codegen, stderr, node, 4); |
| 7056 | fprintf(stderr, "\n{ // (IR)\n"); | 7068 | fprintf(stderr, "\n{ // (IR)\n"); |
| 7057 | ir_print(codegen, stderr, &ir_executable, 4); | 7069 | ir_print(codegen, stderr, ir_executable, 4); |
| 7058 | fprintf(stderr, "}\n"); | 7070 | fprintf(stderr, "}\n"); |
| 7059 | } | 7071 | } |
| 7060 | IrExecutable analyzed_executable = {0}; | 7072 | IrExecutable *analyzed_executable = allocate<IrExecutable>(1); |
| 7061 | analyzed_executable.source_node = source_node; | 7073 | analyzed_executable->source_node = source_node; |
| 7062 | analyzed_executable.parent_exec = parent_exec; | 7074 | analyzed_executable->parent_exec = parent_exec; |
| 7063 | analyzed_executable.source_exec = &ir_executable; | 7075 | analyzed_executable->source_exec = ir_executable; |
| 7064 | analyzed_executable.name = exec_name; | 7076 | analyzed_executable->name = exec_name; |
| 7065 | analyzed_executable.is_inline = true; | 7077 | analyzed_executable->is_inline = true; |
| 7066 | analyzed_executable.fn_entry = fn_entry; | 7078 | analyzed_executable->fn_entry = fn_entry; |
| 7067 | analyzed_executable.c_import_buf = c_import_buf; | 7079 | analyzed_executable->c_import_buf = c_import_buf; |
| 7068 | analyzed_executable.backward_branch_count = backward_branch_count; | 7080 | analyzed_executable->backward_branch_count = backward_branch_count; |
| 7069 | analyzed_executable.backward_branch_quota = backward_branch_quota; | 7081 | analyzed_executable->backward_branch_quota = backward_branch_quota; |
| 7070 | analyzed_executable.begin_scope = scope; | 7082 | analyzed_executable->begin_scope = scope; |
| 7071 | TypeTableEntry *result_type = ir_analyze(codegen, &ir_executable, &analyzed_executable, expected_type, node); | 7083 | TypeTableEntry *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, node); |
| 7072 | if (type_is_invalid(result_type)) | 7084 | if (type_is_invalid(result_type)) |
| 7073 | return codegen->invalid_instruction; | 7085 | return codegen->invalid_instruction; |
| 7074 | 7086 | ||
| 7075 | if (codegen->verbose_ir) { | 7087 | if (codegen->verbose_ir) { |
| 7076 | fprintf(stderr, "{ // (analyzed)\n"); | 7088 | fprintf(stderr, "{ // (analyzed)\n"); |
| 7077 | ir_print(codegen, stderr, &analyzed_executable, 4); | 7089 | ir_print(codegen, stderr, analyzed_executable, 4); |
| 7078 | fprintf(stderr, "}\n"); | 7090 | fprintf(stderr, "}\n"); |
| 7079 | } | 7091 | } |
| 7080 | 7092 | ||
| 7081 | return ir_exec_const_result(codegen, &analyzed_executable); | 7093 | return ir_exec_const_result(codegen, analyzed_executable); |
| 7082 | } | 7094 | } |
| 7083 | 7095 | ||
| 7084 | static TypeTableEntry *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { | 7096 | static TypeTableEntry *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| ... | @@ -9334,6 +9346,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -9334,6 +9346,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9334 | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); | 9346 | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); |
| 9335 | bool is_comptime_var = ir_get_var_is_comptime(var); | 9347 | bool is_comptime_var = ir_get_var_is_comptime(var); |
| 9336 | 9348 | ||
| 9349 | bool var_class_requires_const = false; | ||
| 9350 | |||
| 9337 | TypeTableEntry *result_type = casted_init_value->value.type; | 9351 | TypeTableEntry *result_type = casted_init_value->value.type; |
| 9338 | if (type_is_invalid(result_type)) { | 9352 | if (type_is_invalid(result_type)) { |
| 9339 | result_type = ira->codegen->builtin_types.entry_invalid; | 9353 | result_type = ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -9345,6 +9359,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -9345,6 +9359,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9345 | result_type = ira->codegen->builtin_types.entry_invalid; | 9359 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 9346 | break; | 9360 | break; |
| 9347 | case VarClassRequiredConst: | 9361 | case VarClassRequiredConst: |
| 9362 | var_class_requires_const = true; | ||
| 9348 | if (!var->src_is_const && !is_comptime_var) { | 9363 | if (!var->src_is_const && !is_comptime_var) { |
| 9349 | ir_add_error_node(ira, source_node, | 9364 | ir_add_error_node(ira, source_node, |
| 9350 | buf_sprintf("variable of type '%s' must be const or comptime", | 9365 | buf_sprintf("variable of type '%s' must be const or comptime", |
| ... | @@ -9366,8 +9381,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -9366,8 +9381,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9366 | return ira->codegen->builtin_types.entry_void; | 9381 | return ira->codegen->builtin_types.entry_void; |
| 9367 | } | 9382 | } |
| 9368 | 9383 | ||
| 9369 | bool is_comptime = ir_get_var_is_comptime(var); | ||
| 9370 | |||
| 9371 | if (decl_var_instruction->align_value == nullptr) { | 9384 | if (decl_var_instruction->align_value == nullptr) { |
| 9372 | var->align_bytes = get_abi_alignment(ira->codegen, result_type); | 9385 | var->align_bytes = get_abi_alignment(ira->codegen, result_type); |
| 9373 | } else { | 9386 | } else { |
| ... | @@ -9382,12 +9395,12 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -9382,12 +9395,12 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9382 | ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; | 9395 | ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; |
| 9383 | *mem_slot = casted_init_value->value; | 9396 | *mem_slot = casted_init_value->value; |
| 9384 | 9397 | ||
| 9385 | if (is_comptime) { | 9398 | if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { |
| 9386 | ir_build_const_from(ira, &decl_var_instruction->base); | 9399 | ir_build_const_from(ira, &decl_var_instruction->base); |
| 9387 | return ira->codegen->builtin_types.entry_void; | 9400 | return ira->codegen->builtin_types.entry_void; |
| 9388 | } | 9401 | } |
| 9389 | } | 9402 | } |
| 9390 | } else if (is_comptime) { | 9403 | } else if (is_comptime_var) { |
| 9391 | ir_add_error(ira, &decl_var_instruction->base, | 9404 | ir_add_error(ira, &decl_var_instruction->base, |
| 9392 | buf_sprintf("cannot store runtime value in compile time variable")); | 9405 | buf_sprintf("cannot store runtime value in compile time variable")); |
| 9393 | var->value->type = ira->codegen->builtin_types.entry_invalid; | 9406 | var->value->type = ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -9690,6 +9703,10 @@ static VariableTableEntry *get_fn_var_by_index(FnTableEntry *fn_entry, size_t in | ... | @@ -9690,6 +9703,10 @@ static VariableTableEntry *get_fn_var_by_index(FnTableEntry *fn_entry, size_t in |
| 9690 | static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | 9703 | static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 9691 | VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr) | 9704 | VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr) |
| 9692 | { | 9705 | { |
| 9706 | if (var->mem_slot_index != SIZE_MAX && var->owner_exec->analysis == nullptr) { | ||
| 9707 | assert(ira->codegen->errors.length != 0); | ||
| 9708 | return ira->codegen->invalid_instruction; | ||
| 9709 | } | ||
| 9693 | assert(var->value->type); | 9710 | assert(var->value->type); |
| 9694 | if (type_is_invalid(var->value->type)) | 9711 | if (type_is_invalid(var->value->type)) |
| 9695 | return ira->codegen->invalid_instruction; | 9712 | return ira->codegen->invalid_instruction; |
| ... | @@ -9700,9 +9717,14 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -9700,9 +9717,14 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 9700 | if (var->value->special == ConstValSpecialStatic) { | 9717 | if (var->value->special == ConstValSpecialStatic) { |
| 9701 | mem_slot = var->value; | 9718 | mem_slot = var->value; |
| 9702 | } else { | 9719 | } else { |
| 9703 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. | 9720 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { |
| 9704 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) | 9721 | // find the relevant exec_context |
| 9705 | mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; | 9722 | assert(var->owner_exec != nullptr); |
| 9723 | assert(var->owner_exec->analysis != nullptr); | ||
| 9724 | IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; | ||
| 9725 | assert(var->mem_slot_index < exec_context->mem_slot_count); | ||
| 9726 | mem_slot = &exec_context->mem_slot_list[var->mem_slot_index]; | ||
| 9727 | } | ||
| 9706 | } | 9728 | } |
| 9707 | 9729 | ||
| 9708 | bool is_const = (var->value->type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; | 9730 | bool is_const = (var->value->type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; |
| ... | @@ -15328,8 +15350,8 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl | ... | @@ -15328,8 +15350,8 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl |
| 15328 | assert(!old_exec->invalid); | 15350 | assert(!old_exec->invalid); |
| 15329 | assert(expected_type == nullptr || !type_is_invalid(expected_type)); | 15351 | assert(expected_type == nullptr || !type_is_invalid(expected_type)); |
| 15330 | 15352 | ||
| 15331 | IrAnalyze ir_analyze_data = {}; | 15353 | IrAnalyze *ira = allocate<IrAnalyze>(1); |
| 15332 | IrAnalyze *ira = &ir_analyze_data; | 15354 | old_exec->analysis = ira; |
| 15333 | ira->codegen = codegen; | 15355 | ira->codegen = codegen; |
| 15334 | ira->explicit_return_type = expected_type; | 15356 | ira->explicit_return_type = expected_type; |
| 15335 | 15357 |
src/link.cpp+8-1| ... | @@ -334,6 +334,13 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -334,6 +334,13 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 334 | if (!g->is_native_target) { | 334 | if (!g->is_native_target) { |
| 335 | lj->args.append("--allow-shlib-undefined"); | 335 | lj->args.append("--allow-shlib-undefined"); |
| 336 | } | 336 | } |
| 337 | |||
| 338 | if (g->zig_target.os == OsZen) { | ||
| 339 | lj->args.append("-e"); | ||
| 340 | lj->args.append("main"); | ||
| 341 | |||
| 342 | lj->args.append("--image-base=0x10000000"); | ||
| 343 | } | ||
| 337 | } | 344 | } |
| 338 | 345 | ||
| 339 | //static bool is_target_cyg_mingw(const ZigTarget *target) { | 346 | //static bool is_target_cyg_mingw(const ZigTarget *target) { |
| ... | @@ -644,7 +651,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { | ... | @@ -644,7 +651,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { |
| 644 | platform->kind = MacOS; | 651 | platform->kind = MacOS; |
| 645 | } else if (g->mios_version_min) { | 652 | } else if (g->mios_version_min) { |
| 646 | platform->kind = IPhoneOS; | 653 | platform->kind = IPhoneOS; |
| 647 | } else if (g->zig_target.os == ZigLLVM_MacOSX || g->zig_target.os == ZigLLVM_Darwin) { | 654 | } else if (g->zig_target.os == OsMacOSX) { |
| 648 | platform->kind = MacOS; | 655 | platform->kind = MacOS; |
| 649 | g->mmacosx_version_min = buf_create_from_str("10.10"); | 656 | g->mmacosx_version_min = buf_create_from_str("10.10"); |
| 650 | } else { | 657 | } else { |
src/main.cpp+1-1| ... | @@ -120,7 +120,7 @@ static int print_target_list(FILE *f) { | ... | @@ -120,7 +120,7 @@ static int print_target_list(FILE *f) { |
| 120 | fprintf(f, "\nOperating Systems:\n"); | 120 | fprintf(f, "\nOperating Systems:\n"); |
| 121 | size_t os_count = target_os_count(); | 121 | size_t os_count = target_os_count(); |
| 122 | for (size_t i = 0; i < os_count; i += 1) { | 122 | for (size_t i = 0; i < os_count; i += 1) { |
| 123 | ZigLLVM_OSType os_type = get_target_os(i); | 123 | Os os_type = get_target_os(i); |
| 124 | const char *native_str = (native.os == os_type) ? " (native)" : ""; | 124 | const char *native_str = (native.os == os_type) ? " (native)" : ""; |
| 125 | fprintf(f, " %s%s\n", get_target_os_name(os_type), native_str); | 125 | fprintf(f, " %s%s\n", get_target_os_name(os_type), native_str); |
| 126 | } | 126 | } |
src/parser.cpp+50-46| ... | @@ -225,6 +225,7 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index); | ... | @@ -225,6 +225,7 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index); |
| 225 | static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory); | 225 | static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory); |
| 226 | static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory); | 226 | static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory); |
| 227 | static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory); | 227 | static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory); |
| 228 | static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index); | ||
| 228 | 229 | ||
| 229 | static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) { | 230 | static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) { |
| 230 | if (token->id == token_id) { | 231 | if (token->id == token_id) { |
| ... | @@ -1003,25 +1004,21 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) { | ... | @@ -1003,25 +1004,21 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) { |
| 1003 | 1004 | ||
| 1004 | /* | 1005 | /* |
| 1005 | PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression | 1006 | PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression |
| 1006 | PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | 1007 | PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | "try" |
| 1007 | */ | 1008 | */ |
| 1008 | static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) { | 1009 | static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 1009 | Token *token = &pc->tokens->at(*token_index); | 1010 | Token *token = &pc->tokens->at(*token_index); |
| 1010 | if (token->id == TokenIdAmpersand) { | 1011 | if (token->id == TokenIdAmpersand) { |
| 1011 | return ast_parse_addr_of(pc, token_index); | 1012 | return ast_parse_addr_of(pc, token_index); |
| 1012 | } | 1013 | } |
| 1014 | if (token->id == TokenIdKeywordTry) { | ||
| 1015 | return ast_parse_try_expr(pc, token_index); | ||
| 1016 | } | ||
| 1013 | PrefixOp prefix_op = tok_to_prefix_op(token); | 1017 | PrefixOp prefix_op = tok_to_prefix_op(token); |
| 1014 | if (prefix_op == PrefixOpInvalid) { | 1018 | if (prefix_op == PrefixOpInvalid) { |
| 1015 | return ast_parse_suffix_op_expr(pc, token_index, mandatory); | 1019 | return ast_parse_suffix_op_expr(pc, token_index, mandatory); |
| 1016 | } | 1020 | } |
| 1017 | 1021 | ||
| 1018 | if (prefix_op == PrefixOpError || prefix_op == PrefixOpMaybe) { | ||
| 1019 | Token *maybe_return = &pc->tokens->at(*token_index + 1); | ||
| 1020 | if (maybe_return->id == TokenIdKeywordReturn) { | ||
| 1021 | return ast_parse_return_expr(pc, token_index); | ||
| 1022 | } | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | *token_index += 1; | 1022 | *token_index += 1; |
| 1026 | 1023 | ||
| 1027 | 1024 | ||
| ... | @@ -1410,15 +1407,15 @@ static AstNode *ast_parse_if_try_test_expr(ParseContext *pc, size_t *token_index | ... | @@ -1410,15 +1407,15 @@ static AstNode *ast_parse_if_try_test_expr(ParseContext *pc, size_t *token_index |
| 1410 | } | 1407 | } |
| 1411 | 1408 | ||
| 1412 | if (err_name_tok != nullptr) { | 1409 | if (err_name_tok != nullptr) { |
| 1413 | AstNode *node = ast_create_node(pc, NodeTypeTryExpr, if_token); | 1410 | AstNode *node = ast_create_node(pc, NodeTypeIfErrorExpr, if_token); |
| 1414 | node->data.try_expr.target_node = condition; | 1411 | node->data.if_err_expr.target_node = condition; |
| 1415 | node->data.try_expr.var_is_ptr = var_is_ptr; | 1412 | node->data.if_err_expr.var_is_ptr = var_is_ptr; |
| 1416 | if (var_name_tok != nullptr) { | 1413 | if (var_name_tok != nullptr) { |
| 1417 | node->data.try_expr.var_symbol = token_buf(var_name_tok); | 1414 | node->data.if_err_expr.var_symbol = token_buf(var_name_tok); |
| 1418 | } | 1415 | } |
| 1419 | node->data.try_expr.then_node = body_node; | 1416 | node->data.if_err_expr.then_node = body_node; |
| 1420 | node->data.try_expr.err_symbol = token_buf(err_name_tok); | 1417 | node->data.if_err_expr.err_symbol = token_buf(err_name_tok); |
| 1421 | node->data.try_expr.else_node = else_node; | 1418 | node->data.if_err_expr.else_node = else_node; |
| 1422 | return node; | 1419 | return node; |
| 1423 | } else if (var_name_tok != nullptr) { | 1420 | } else if (var_name_tok != nullptr) { |
| 1424 | AstNode *node = ast_create_node(pc, NodeTypeTestExpr, if_token); | 1421 | AstNode *node = ast_create_node(pc, NodeTypeTestExpr, if_token); |
| ... | @@ -1438,38 +1435,41 @@ static AstNode *ast_parse_if_try_test_expr(ParseContext *pc, size_t *token_index | ... | @@ -1438,38 +1435,41 @@ static AstNode *ast_parse_if_try_test_expr(ParseContext *pc, size_t *token_index |
| 1438 | } | 1435 | } |
| 1439 | 1436 | ||
| 1440 | /* | 1437 | /* |
| 1441 | ReturnExpression : option("%") "return" option(Expression) | 1438 | ReturnExpression : "return" option(Expression) |
| 1442 | */ | 1439 | */ |
| 1443 | static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index) { | 1440 | static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index) { |
| 1444 | Token *token = &pc->tokens->at(*token_index); | 1441 | Token *token = &pc->tokens->at(*token_index); |
| 1445 | 1442 | ||
| 1446 | NodeType node_type; | 1443 | if (token->id != TokenIdKeywordReturn) { |
| 1447 | ReturnKind kind; | ||
| 1448 | |||
| 1449 | if (token->id == TokenIdPercent) { | ||
| 1450 | Token *next_token = &pc->tokens->at(*token_index + 1); | ||
| 1451 | if (next_token->id == TokenIdKeywordReturn) { | ||
| 1452 | kind = ReturnKindError; | ||
| 1453 | node_type = NodeTypeReturnExpr; | ||
| 1454 | *token_index += 2; | ||
| 1455 | } else { | ||
| 1456 | return nullptr; | ||
| 1457 | } | ||
| 1458 | } else if (token->id == TokenIdKeywordReturn) { | ||
| 1459 | kind = ReturnKindUnconditional; | ||
| 1460 | node_type = NodeTypeReturnExpr; | ||
| 1461 | *token_index += 1; | ||
| 1462 | } else { | ||
| 1463 | return nullptr; | 1444 | return nullptr; |
| 1464 | } | 1445 | } |
| 1446 | *token_index += 1; | ||
| 1465 | 1447 | ||
| 1466 | AstNode *node = ast_create_node(pc, node_type, token); | 1448 | AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token); |
| 1467 | node->data.return_expr.kind = kind; | 1449 | node->data.return_expr.kind = ReturnKindUnconditional; |
| 1468 | node->data.return_expr.expr = ast_parse_expression(pc, token_index, false); | 1450 | node->data.return_expr.expr = ast_parse_expression(pc, token_index, false); |
| 1469 | 1451 | ||
| 1470 | return node; | 1452 | return node; |
| 1471 | } | 1453 | } |
| 1472 | 1454 | ||
| 1455 | /* | ||
| 1456 | TryExpression : "try" Expression | ||
| 1457 | */ | ||
| 1458 | static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index) { | ||
| 1459 | Token *token = &pc->tokens->at(*token_index); | ||
| 1460 | |||
| 1461 | if (token->id != TokenIdKeywordTry) { | ||
| 1462 | return nullptr; | ||
| 1463 | } | ||
| 1464 | *token_index += 1; | ||
| 1465 | |||
| 1466 | AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token); | ||
| 1467 | node->data.return_expr.kind = ReturnKindError; | ||
| 1468 | node->data.return_expr.expr = ast_parse_expression(pc, token_index, true); | ||
| 1469 | |||
| 1470 | return node; | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | /* | 1473 | /* |
| 1474 | BreakExpression = "break" option(":" Symbol) option(Expression) | 1474 | BreakExpression = "break" option(":" Symbol) option(Expression) |
| 1475 | */ | 1475 | */ |
| ... | @@ -2041,7 +2041,7 @@ static BinOpType ast_parse_ass_op(ParseContext *pc, size_t *token_index, bool ma | ... | @@ -2041,7 +2041,7 @@ static BinOpType ast_parse_ass_op(ParseContext *pc, size_t *token_index, bool ma |
| 2041 | /* | 2041 | /* |
| 2042 | UnwrapExpression : BoolOrExpression (UnwrapMaybe | UnwrapError) | BoolOrExpression | 2042 | UnwrapExpression : BoolOrExpression (UnwrapMaybe | UnwrapError) | BoolOrExpression |
| 2043 | UnwrapMaybe : "??" BoolOrExpression | 2043 | UnwrapMaybe : "??" BoolOrExpression |
| 2044 | UnwrapError : "%%" option("|" "Symbol" "|") BoolOrExpression | 2044 | UnwrapError = "catch" option("|" Symbol "|") Expression |
| 2045 | */ | 2045 | */ |
| 2046 | static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, bool mandatory) { | 2046 | static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 2047 | AstNode *lhs = ast_parse_bool_or_expr(pc, token_index, mandatory); | 2047 | AstNode *lhs = ast_parse_bool_or_expr(pc, token_index, mandatory); |
| ... | @@ -2061,7 +2061,7 @@ static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, boo | ... | @@ -2061,7 +2061,7 @@ static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, boo |
| 2061 | node->data.bin_op_expr.op2 = rhs; | 2061 | node->data.bin_op_expr.op2 = rhs; |
| 2062 | 2062 | ||
| 2063 | return node; | 2063 | return node; |
| 2064 | } else if (token->id == TokenIdPercentPercent) { | 2064 | } else if (token->id == TokenIdKeywordCatch) { |
| 2065 | *token_index += 1; | 2065 | *token_index += 1; |
| 2066 | 2066 | ||
| 2067 | AstNode *node = ast_create_node(pc, NodeTypeUnwrapErrorExpr, token); | 2067 | AstNode *node = ast_create_node(pc, NodeTypeUnwrapErrorExpr, token); |
| ... | @@ -2124,7 +2124,7 @@ static AstNode *ast_parse_block_or_expression(ParseContext *pc, size_t *token_in | ... | @@ -2124,7 +2124,7 @@ static AstNode *ast_parse_block_or_expression(ParseContext *pc, size_t *token_in |
| 2124 | } | 2124 | } |
| 2125 | 2125 | ||
| 2126 | /* | 2126 | /* |
| 2127 | Expression = ReturnExpression | BreakExpression | AssignmentExpression | 2127 | Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression |
| 2128 | */ | 2128 | */ |
| 2129 | static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool mandatory) { | 2129 | static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 2130 | Token *token = &pc->tokens->at(*token_index); | 2130 | Token *token = &pc->tokens->at(*token_index); |
| ... | @@ -2133,6 +2133,10 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool | ... | @@ -2133,6 +2133,10 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool |
| 2133 | if (return_expr) | 2133 | if (return_expr) |
| 2134 | return return_expr; | 2134 | return return_expr; |
| 2135 | 2135 | ||
| 2136 | AstNode *try_expr = ast_parse_try_expr(pc, token_index); | ||
| 2137 | if (try_expr) | ||
| 2138 | return try_expr; | ||
| 2139 | |||
| 2136 | AstNode *break_expr = ast_parse_break_expr(pc, token_index); | 2140 | AstNode *break_expr = ast_parse_break_expr(pc, token_index); |
| 2137 | if (break_expr) | 2141 | if (break_expr) |
| 2138 | return break_expr; | 2142 | return break_expr; |
| ... | @@ -2153,10 +2157,10 @@ static bool statement_terminates_without_semicolon(AstNode *node) { | ... | @@ -2153,10 +2157,10 @@ static bool statement_terminates_without_semicolon(AstNode *node) { |
| 2153 | if (node->data.if_bool_expr.else_node) | 2157 | if (node->data.if_bool_expr.else_node) |
| 2154 | return statement_terminates_without_semicolon(node->data.if_bool_expr.else_node); | 2158 | return statement_terminates_without_semicolon(node->data.if_bool_expr.else_node); |
| 2155 | return node->data.if_bool_expr.then_block->type == NodeTypeBlock; | 2159 | return node->data.if_bool_expr.then_block->type == NodeTypeBlock; |
| 2156 | case NodeTypeTryExpr: | 2160 | case NodeTypeIfErrorExpr: |
| 2157 | if (node->data.try_expr.else_node) | 2161 | if (node->data.if_err_expr.else_node) |
| 2158 | return statement_terminates_without_semicolon(node->data.try_expr.else_node); | 2162 | return statement_terminates_without_semicolon(node->data.if_err_expr.else_node); |
| 2159 | return node->data.try_expr.then_node->type == NodeTypeBlock; | 2163 | return node->data.if_err_expr.then_node->type == NodeTypeBlock; |
| 2160 | case NodeTypeTestExpr: | 2164 | case NodeTypeTestExpr: |
| 2161 | if (node->data.test_expr.else_node) | 2165 | if (node->data.test_expr.else_node) |
| 2162 | return statement_terminates_without_semicolon(node->data.test_expr.else_node); | 2166 | return statement_terminates_without_semicolon(node->data.test_expr.else_node); |
| ... | @@ -2829,10 +2833,10 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont | ... | @@ -2829,10 +2833,10 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2829 | visit_field(&node->data.if_bool_expr.then_block, visit, context); | 2833 | visit_field(&node->data.if_bool_expr.then_block, visit, context); |
| 2830 | visit_field(&node->data.if_bool_expr.else_node, visit, context); | 2834 | visit_field(&node->data.if_bool_expr.else_node, visit, context); |
| 2831 | break; | 2835 | break; |
| 2832 | case NodeTypeTryExpr: | 2836 | case NodeTypeIfErrorExpr: |
| 2833 | visit_field(&node->data.try_expr.target_node, visit, context); | 2837 | visit_field(&node->data.if_err_expr.target_node, visit, context); |
| 2834 | visit_field(&node->data.try_expr.then_node, visit, context); | 2838 | visit_field(&node->data.if_err_expr.then_node, visit, context); |
| 2835 | visit_field(&node->data.try_expr.else_node, visit, context); | 2839 | visit_field(&node->data.if_err_expr.else_node, visit, context); |
| 2836 | break; | 2840 | break; |
| 2837 | case NodeTypeTestExpr: | 2841 | case NodeTypeTestExpr: |
| 2838 | visit_field(&node->data.test_expr.target_node, visit, context); | 2842 | visit_field(&node->data.test_expr.target_node, visit, context); |
src/target.cpp+257-81| ... | @@ -127,39 +127,39 @@ static const ZigLLVM_VendorType vendor_list[] = { | ... | @@ -127,39 +127,39 @@ static const ZigLLVM_VendorType vendor_list[] = { |
| 127 | ZigLLVM_SUSE, | 127 | ZigLLVM_SUSE, |
| 128 | }; | 128 | }; |
| 129 | 129 | ||
| 130 | static const ZigLLVM_OSType os_list[] = { | 130 | static const Os os_list[] = { |
| 131 | ZigLLVM_UnknownOS, | 131 | OsFreestanding, |
| 132 | ZigLLVM_Ananas, | 132 | OsAnanas, |
| 133 | ZigLLVM_CloudABI, | 133 | OsCloudABI, |
| 134 | ZigLLVM_Darwin, | 134 | OsDragonFly, |
| 135 | ZigLLVM_DragonFly, | 135 | OsFreeBSD, |
| 136 | ZigLLVM_FreeBSD, | 136 | OsFuchsia, |
| 137 | ZigLLVM_Fuchsia, | 137 | OsIOS, |
| 138 | ZigLLVM_IOS, | 138 | OsKFreeBSD, |
| 139 | ZigLLVM_KFreeBSD, | 139 | OsLinux, |
| 140 | ZigLLVM_Linux, | 140 | OsLv2, // PS3 |
| 141 | ZigLLVM_Lv2, | 141 | OsMacOSX, |
| 142 | ZigLLVM_MacOSX, | 142 | OsNetBSD, |
| 143 | ZigLLVM_NetBSD, | 143 | OsOpenBSD, |
| 144 | ZigLLVM_OpenBSD, | 144 | OsSolaris, |
| 145 | ZigLLVM_Solaris, | 145 | OsWindows, |
| 146 | ZigLLVM_Win32, | 146 | OsHaiku, |
| 147 | ZigLLVM_Haiku, | 147 | OsMinix, |
| 148 | ZigLLVM_Minix, | 148 | OsRTEMS, |
| 149 | ZigLLVM_RTEMS, | 149 | OsNaCl, // Native Client |
| 150 | ZigLLVM_NaCl, | 150 | OsCNK, // BG/P Compute-Node Kernel |
| 151 | ZigLLVM_CNK, | 151 | OsBitrig, |
| 152 | ZigLLVM_Bitrig, | 152 | OsAIX, |
| 153 | ZigLLVM_AIX, | 153 | OsCUDA, // NVIDIA CUDA |
| 154 | ZigLLVM_CUDA, | 154 | OsNVCL, // NVIDIA OpenCL |
| 155 | ZigLLVM_NVCL, | 155 | OsAMDHSA, // AMD HSA Runtime |
| 156 | ZigLLVM_AMDHSA, | 156 | OsPS4, |
| 157 | ZigLLVM_PS4, | 157 | OsELFIAMCU, |
| 158 | ZigLLVM_ELFIAMCU, | 158 | OsTvOS, // Apple tvOS |
| 159 | ZigLLVM_TvOS, | 159 | OsWatchOS, // Apple watchOS |
| 160 | ZigLLVM_WatchOS, | 160 | OsMesa3D, |
| 161 | ZigLLVM_Mesa3D, | 161 | OsContiki, |
| 162 | ZigLLVM_Contiki, | 162 | OsZen, |
| 163 | }; | 163 | }; |
| 164 | 164 | ||
| 165 | static const ZigLLVM_EnvironmentType environ_list[] = { | 165 | static const ZigLLVM_EnvironmentType environ_list[] = { |
| ... | @@ -233,12 +233,187 @@ ZigLLVM_VendorType get_target_vendor(size_t index) { | ... | @@ -233,12 +233,187 @@ ZigLLVM_VendorType get_target_vendor(size_t index) { |
| 233 | size_t target_os_count(void) { | 233 | size_t target_os_count(void) { |
| 234 | return array_length(os_list); | 234 | return array_length(os_list); |
| 235 | } | 235 | } |
| 236 | ZigLLVM_OSType get_target_os(size_t index) { | 236 | Os get_target_os(size_t index) { |
| 237 | return os_list[index]; | 237 | return os_list[index]; |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | const char *get_target_os_name(ZigLLVM_OSType os_type) { | 240 | static ZigLLVM_OSType get_llvm_os_type(Os os_type) { |
| 241 | return (os_type == ZigLLVM_UnknownOS) ? "freestanding" : ZigLLVMGetOSTypeName(os_type); | 241 | switch (os_type) { |
| 242 | case OsFreestanding: | ||
| 243 | case OsZen: | ||
| 244 | return ZigLLVM_UnknownOS; | ||
| 245 | case OsAnanas: | ||
| 246 | return ZigLLVM_Ananas; | ||
| 247 | case OsCloudABI: | ||
| 248 | return ZigLLVM_CloudABI; | ||
| 249 | case OsDragonFly: | ||
| 250 | return ZigLLVM_DragonFly; | ||
| 251 | case OsFreeBSD: | ||
| 252 | return ZigLLVM_FreeBSD; | ||
| 253 | case OsFuchsia: | ||
| 254 | return ZigLLVM_Fuchsia; | ||
| 255 | case OsIOS: | ||
| 256 | return ZigLLVM_IOS; | ||
| 257 | case OsKFreeBSD: | ||
| 258 | return ZigLLVM_KFreeBSD; | ||
| 259 | case OsLinux: | ||
| 260 | return ZigLLVM_Linux; | ||
| 261 | case OsLv2: | ||
| 262 | return ZigLLVM_Lv2; | ||
| 263 | case OsMacOSX: | ||
| 264 | return ZigLLVM_MacOSX; | ||
| 265 | case OsNetBSD: | ||
| 266 | return ZigLLVM_NetBSD; | ||
| 267 | case OsOpenBSD: | ||
| 268 | return ZigLLVM_OpenBSD; | ||
| 269 | case OsSolaris: | ||
| 270 | return ZigLLVM_Solaris; | ||
| 271 | case OsWindows: | ||
| 272 | return ZigLLVM_Win32; | ||
| 273 | case OsHaiku: | ||
| 274 | return ZigLLVM_Haiku; | ||
| 275 | case OsMinix: | ||
| 276 | return ZigLLVM_Minix; | ||
| 277 | case OsRTEMS: | ||
| 278 | return ZigLLVM_RTEMS; | ||
| 279 | case OsNaCl: | ||
| 280 | return ZigLLVM_NaCl; | ||
| 281 | case OsCNK: | ||
| 282 | return ZigLLVM_CNK; | ||
| 283 | case OsBitrig: | ||
| 284 | return ZigLLVM_Bitrig; | ||
| 285 | case OsAIX: | ||
| 286 | return ZigLLVM_AIX; | ||
| 287 | case OsCUDA: | ||
| 288 | return ZigLLVM_CUDA; | ||
| 289 | case OsNVCL: | ||
| 290 | return ZigLLVM_NVCL; | ||
| 291 | case OsAMDHSA: | ||
| 292 | return ZigLLVM_AMDHSA; | ||
| 293 | case OsPS4: | ||
| 294 | return ZigLLVM_PS4; | ||
| 295 | case OsELFIAMCU: | ||
| 296 | return ZigLLVM_ELFIAMCU; | ||
| 297 | case OsTvOS: | ||
| 298 | return ZigLLVM_TvOS; | ||
| 299 | case OsWatchOS: | ||
| 300 | return ZigLLVM_WatchOS; | ||
| 301 | case OsMesa3D: | ||
| 302 | return ZigLLVM_Mesa3D; | ||
| 303 | case OsContiki: | ||
| 304 | return ZigLLVM_Contiki; | ||
| 305 | } | ||
| 306 | zig_unreachable(); | ||
| 307 | } | ||
| 308 | |||
| 309 | static Os get_zig_os_type(ZigLLVM_OSType os_type) { | ||
| 310 | switch (os_type) { | ||
| 311 | case ZigLLVM_UnknownOS: | ||
| 312 | return OsFreestanding; | ||
| 313 | case ZigLLVM_Ananas: | ||
| 314 | return OsAnanas; | ||
| 315 | case ZigLLVM_CloudABI: | ||
| 316 | return OsCloudABI; | ||
| 317 | case ZigLLVM_DragonFly: | ||
| 318 | return OsDragonFly; | ||
| 319 | case ZigLLVM_FreeBSD: | ||
| 320 | return OsFreeBSD; | ||
| 321 | case ZigLLVM_Fuchsia: | ||
| 322 | return OsFuchsia; | ||
| 323 | case ZigLLVM_IOS: | ||
| 324 | return OsIOS; | ||
| 325 | case ZigLLVM_KFreeBSD: | ||
| 326 | return OsKFreeBSD; | ||
| 327 | case ZigLLVM_Linux: | ||
| 328 | return OsLinux; | ||
| 329 | case ZigLLVM_Lv2: | ||
| 330 | return OsLv2; | ||
| 331 | case ZigLLVM_Darwin: | ||
| 332 | case ZigLLVM_MacOSX: | ||
| 333 | return OsMacOSX; | ||
| 334 | case ZigLLVM_NetBSD: | ||
| 335 | return OsNetBSD; | ||
| 336 | case ZigLLVM_OpenBSD: | ||
| 337 | return OsOpenBSD; | ||
| 338 | case ZigLLVM_Solaris: | ||
| 339 | return OsSolaris; | ||
| 340 | case ZigLLVM_Win32: | ||
| 341 | return OsWindows; | ||
| 342 | case ZigLLVM_Haiku: | ||
| 343 | return OsHaiku; | ||
| 344 | case ZigLLVM_Minix: | ||
| 345 | return OsMinix; | ||
| 346 | case ZigLLVM_RTEMS: | ||
| 347 | return OsRTEMS; | ||
| 348 | case ZigLLVM_NaCl: | ||
| 349 | return OsNaCl; | ||
| 350 | case ZigLLVM_CNK: | ||
| 351 | return OsCNK; | ||
| 352 | case ZigLLVM_Bitrig: | ||
| 353 | return OsBitrig; | ||
| 354 | case ZigLLVM_AIX: | ||
| 355 | return OsAIX; | ||
| 356 | case ZigLLVM_CUDA: | ||
| 357 | return OsCUDA; | ||
| 358 | case ZigLLVM_NVCL: | ||
| 359 | return OsNVCL; | ||
| 360 | case ZigLLVM_AMDHSA: | ||
| 361 | return OsAMDHSA; | ||
| 362 | case ZigLLVM_PS4: | ||
| 363 | return OsPS4; | ||
| 364 | case ZigLLVM_ELFIAMCU: | ||
| 365 | return OsELFIAMCU; | ||
| 366 | case ZigLLVM_TvOS: | ||
| 367 | return OsTvOS; | ||
| 368 | case ZigLLVM_WatchOS: | ||
| 369 | return OsWatchOS; | ||
| 370 | case ZigLLVM_Mesa3D: | ||
| 371 | return OsMesa3D; | ||
| 372 | case ZigLLVM_Contiki: | ||
| 373 | return OsContiki; | ||
| 374 | } | ||
| 375 | zig_unreachable(); | ||
| 376 | } | ||
| 377 | |||
| 378 | const char *get_target_os_name(Os os_type) { | ||
| 379 | switch (os_type) { | ||
| 380 | case OsFreestanding: | ||
| 381 | return "freestanding"; | ||
| 382 | case OsZen: | ||
| 383 | return "zen"; | ||
| 384 | case OsAnanas: | ||
| 385 | case OsCloudABI: | ||
| 386 | case OsDragonFly: | ||
| 387 | case OsFreeBSD: | ||
| 388 | case OsFuchsia: | ||
| 389 | case OsIOS: | ||
| 390 | case OsKFreeBSD: | ||
| 391 | case OsLinux: | ||
| 392 | case OsLv2: // PS3 | ||
| 393 | case OsMacOSX: | ||
| 394 | case OsNetBSD: | ||
| 395 | case OsOpenBSD: | ||
| 396 | case OsSolaris: | ||
| 397 | case OsWindows: | ||
| 398 | case OsHaiku: | ||
| 399 | case OsMinix: | ||
| 400 | case OsRTEMS: | ||
| 401 | case OsNaCl: // Native Client | ||
| 402 | case OsCNK: // BG/P Compute-Node Kernel | ||
| 403 | case OsBitrig: | ||
| 404 | case OsAIX: | ||
| 405 | case OsCUDA: // NVIDIA CUDA | ||
| 406 | case OsNVCL: // NVIDIA OpenCL | ||
| 407 | case OsAMDHSA: // AMD HSA Runtime | ||
| 408 | case OsPS4: | ||
| 409 | case OsELFIAMCU: | ||
| 410 | case OsTvOS: // Apple tvOS | ||
| 411 | case OsWatchOS: // Apple watchOS | ||
| 412 | case OsMesa3D: | ||
| 413 | case OsContiki: | ||
| 414 | return ZigLLVMGetOSTypeName(get_llvm_os_type(os_type)); | ||
| 415 | } | ||
| 416 | zig_unreachable(); | ||
| 242 | } | 417 | } |
| 243 | 418 | ||
| 244 | size_t target_environ_count(void) { | 419 | size_t target_environ_count(void) { |
| ... | @@ -249,20 +424,22 @@ ZigLLVM_EnvironmentType get_target_environ(size_t index) { | ... | @@ -249,20 +424,22 @@ ZigLLVM_EnvironmentType get_target_environ(size_t index) { |
| 249 | } | 424 | } |
| 250 | 425 | ||
| 251 | void get_native_target(ZigTarget *target) { | 426 | void get_native_target(ZigTarget *target) { |
| 427 | ZigLLVM_OSType os_type; | ||
| 252 | ZigLLVMGetNativeTarget( | 428 | ZigLLVMGetNativeTarget( |
| 253 | &target->arch.arch, | 429 | &target->arch.arch, |
| 254 | &target->arch.sub_arch, | 430 | &target->arch.sub_arch, |
| 255 | &target->vendor, | 431 | &target->vendor, |
| 256 | &target->os, | 432 | &os_type, |
| 257 | &target->env_type, | 433 | &target->env_type, |
| 258 | &target->oformat); | 434 | &target->oformat); |
| 435 | target->os = get_zig_os_type(os_type); | ||
| 259 | } | 436 | } |
| 260 | 437 | ||
| 261 | void get_unknown_target(ZigTarget *target) { | 438 | void get_unknown_target(ZigTarget *target) { |
| 262 | target->arch.arch = ZigLLVM_UnknownArch; | 439 | target->arch.arch = ZigLLVM_UnknownArch; |
| 263 | target->arch.sub_arch = ZigLLVM_NoSubArch; | 440 | target->arch.sub_arch = ZigLLVM_NoSubArch; |
| 264 | target->vendor = ZigLLVM_UnknownVendor; | 441 | target->vendor = ZigLLVM_UnknownVendor; |
| 265 | target->os = ZigLLVM_UnknownOS; | 442 | target->os = OsFreestanding; |
| 266 | target->env_type = ZigLLVM_UnknownEnvironment; | 443 | target->env_type = ZigLLVM_UnknownEnvironment; |
| 267 | target->oformat = ZigLLVM_UnknownObjectFormat; | 444 | target->oformat = ZigLLVM_UnknownObjectFormat; |
| 268 | } | 445 | } |
| ... | @@ -289,9 +466,9 @@ int parse_target_arch(const char *str, ArchType *out_arch) { | ... | @@ -289,9 +466,9 @@ int parse_target_arch(const char *str, ArchType *out_arch) { |
| 289 | return ErrorFileNotFound; | 466 | return ErrorFileNotFound; |
| 290 | } | 467 | } |
| 291 | 468 | ||
| 292 | int parse_target_os(const char *str, ZigLLVM_OSType *out_os) { | 469 | int parse_target_os(const char *str, Os *out_os) { |
| 293 | for (size_t i = 0; i < array_length(os_list); i += 1) { | 470 | for (size_t i = 0; i < array_length(os_list); i += 1) { |
| 294 | ZigLLVM_OSType os = os_list[i]; | 471 | Os os = os_list[i]; |
| 295 | const char *os_name = get_target_os_name(os); | 472 | const char *os_name = get_target_os_name(os); |
| 296 | if (strcmp(os_name, str) == 0) { | 473 | if (strcmp(os_name, str) == 0) { |
| 297 | *out_os = os; | 474 | *out_os = os; |
| ... | @@ -328,15 +505,14 @@ void get_target_triple(Buf *triple, const ZigTarget *target) { | ... | @@ -328,15 +505,14 @@ void get_target_triple(Buf *triple, const ZigTarget *target) { |
| 328 | buf_resize(triple, 0); | 505 | buf_resize(triple, 0); |
| 329 | buf_appendf(triple, "%s-%s-%s-%s", arch_name, | 506 | buf_appendf(triple, "%s-%s-%s-%s", arch_name, |
| 330 | ZigLLVMGetVendorTypeName(target->vendor), | 507 | ZigLLVMGetVendorTypeName(target->vendor), |
| 331 | ZigLLVMGetOSTypeName(target->os), | 508 | ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)), |
| 332 | ZigLLVMGetEnvironmentTypeName(target->env_type)); | 509 | ZigLLVMGetEnvironmentTypeName(target->env_type)); |
| 333 | } | 510 | } |
| 334 | 511 | ||
| 335 | static bool is_os_darwin(ZigTarget *target) { | 512 | static bool is_os_darwin(ZigTarget *target) { |
| 336 | switch (target->os) { | 513 | switch (target->os) { |
| 337 | case ZigLLVM_Darwin: | 514 | case OsMacOSX: |
| 338 | case ZigLLVM_IOS: | 515 | case OsIOS: |
| 339 | case ZigLLVM_MacOSX: | ||
| 340 | return true; | 516 | return true; |
| 341 | default: | 517 | default: |
| 342 | return false; | 518 | return false; |
| ... | @@ -357,7 +533,7 @@ void resolve_target_object_format(ZigTarget *target) { | ... | @@ -357,7 +533,7 @@ void resolve_target_object_format(ZigTarget *target) { |
| 357 | case ZigLLVM_x86_64: | 533 | case ZigLLVM_x86_64: |
| 358 | if (is_os_darwin(target)) { | 534 | if (is_os_darwin(target)) { |
| 359 | target->oformat = ZigLLVM_MachO; | 535 | target->oformat = ZigLLVM_MachO; |
| 360 | } else if (target->os == ZigLLVM_Win32) { | 536 | } else if (target->os == OsWindows) { |
| 361 | target->oformat = ZigLLVM_COFF; | 537 | target->oformat = ZigLLVM_COFF; |
| 362 | } else { | 538 | } else { |
| 363 | target->oformat = ZigLLVM_ELF; | 539 | target->oformat = ZigLLVM_ELF; |
| ... | @@ -489,7 +665,7 @@ static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) { | ... | @@ -489,7 +665,7 @@ static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) { |
| 489 | 665 | ||
| 490 | uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | 666 | uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 491 | switch (target->os) { | 667 | switch (target->os) { |
| 492 | case ZigLLVM_UnknownOS: | 668 | case OsFreestanding: |
| 493 | switch (id) { | 669 | switch (id) { |
| 494 | case CIntTypeShort: | 670 | case CIntTypeShort: |
| 495 | case CIntTypeUShort: | 671 | case CIntTypeUShort: |
| ... | @@ -506,9 +682,9 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | ... | @@ -506,9 +682,9 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 506 | case CIntTypeCount: | 682 | case CIntTypeCount: |
| 507 | zig_unreachable(); | 683 | zig_unreachable(); |
| 508 | } | 684 | } |
| 509 | case ZigLLVM_Linux: | 685 | case OsLinux: |
| 510 | case ZigLLVM_Darwin: | 686 | case OsMacOSX: |
| 511 | case ZigLLVM_MacOSX: | 687 | case OsZen: |
| 512 | switch (id) { | 688 | switch (id) { |
| 513 | case CIntTypeShort: | 689 | case CIntTypeShort: |
| 514 | case CIntTypeUShort: | 690 | case CIntTypeUShort: |
| ... | @@ -525,7 +701,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | ... | @@ -525,7 +701,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 525 | case CIntTypeCount: | 701 | case CIntTypeCount: |
| 526 | zig_unreachable(); | 702 | zig_unreachable(); |
| 527 | } | 703 | } |
| 528 | case ZigLLVM_Win32: | 704 | case OsWindows: |
| 529 | switch (id) { | 705 | switch (id) { |
| 530 | case CIntTypeShort: | 706 | case CIntTypeShort: |
| 531 | case CIntTypeUShort: | 707 | case CIntTypeUShort: |
| ... | @@ -541,40 +717,40 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | ... | @@ -541,40 +717,40 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 541 | case CIntTypeCount: | 717 | case CIntTypeCount: |
| 542 | zig_unreachable(); | 718 | zig_unreachable(); |
| 543 | } | 719 | } |
| 544 | case ZigLLVM_Ananas: | 720 | case OsAnanas: |
| 545 | case ZigLLVM_CloudABI: | 721 | case OsCloudABI: |
| 546 | case ZigLLVM_DragonFly: | 722 | case OsDragonFly: |
| 547 | case ZigLLVM_FreeBSD: | 723 | case OsFreeBSD: |
| 548 | case ZigLLVM_IOS: | 724 | case OsIOS: |
| 549 | case ZigLLVM_KFreeBSD: | 725 | case OsKFreeBSD: |
| 550 | case ZigLLVM_Lv2: | 726 | case OsLv2: |
| 551 | case ZigLLVM_NetBSD: | 727 | case OsNetBSD: |
| 552 | case ZigLLVM_OpenBSD: | 728 | case OsOpenBSD: |
| 553 | case ZigLLVM_Solaris: | 729 | case OsSolaris: |
| 554 | case ZigLLVM_Haiku: | 730 | case OsHaiku: |
| 555 | case ZigLLVM_Minix: | 731 | case OsMinix: |
| 556 | case ZigLLVM_RTEMS: | 732 | case OsRTEMS: |
| 557 | case ZigLLVM_NaCl: | 733 | case OsNaCl: |
| 558 | case ZigLLVM_CNK: | 734 | case OsCNK: |
| 559 | case ZigLLVM_Bitrig: | 735 | case OsBitrig: |
| 560 | case ZigLLVM_AIX: | 736 | case OsAIX: |
| 561 | case ZigLLVM_CUDA: | 737 | case OsCUDA: |
| 562 | case ZigLLVM_NVCL: | 738 | case OsNVCL: |
| 563 | case ZigLLVM_AMDHSA: | 739 | case OsAMDHSA: |
| 564 | case ZigLLVM_PS4: | 740 | case OsPS4: |
| 565 | case ZigLLVM_ELFIAMCU: | 741 | case OsELFIAMCU: |
| 566 | case ZigLLVM_TvOS: | 742 | case OsTvOS: |
| 567 | case ZigLLVM_WatchOS: | 743 | case OsWatchOS: |
| 568 | case ZigLLVM_Mesa3D: | 744 | case OsMesa3D: |
| 569 | case ZigLLVM_Fuchsia: | 745 | case OsFuchsia: |
| 570 | case ZigLLVM_Contiki: | 746 | case OsContiki: |
| 571 | zig_panic("TODO c type size in bits for this target"); | 747 | zig_panic("TODO c type size in bits for this target"); |
| 572 | } | 748 | } |
| 573 | zig_unreachable(); | 749 | zig_unreachable(); |
| 574 | } | 750 | } |
| 575 | 751 | ||
| 576 | const char *target_o_file_ext(ZigTarget *target) { | 752 | const char *target_o_file_ext(ZigTarget *target) { |
| 577 | if (target->env_type == ZigLLVM_MSVC || target->os == ZigLLVM_Win32) { | 753 | if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows) { |
| 578 | return ".obj"; | 754 | return ".obj"; |
| 579 | } else { | 755 | } else { |
| 580 | return ".o"; | 756 | return ".o"; |
| ... | @@ -590,7 +766,7 @@ const char *target_llvm_ir_file_ext(ZigTarget *target) { | ... | @@ -590,7 +766,7 @@ const char *target_llvm_ir_file_ext(ZigTarget *target) { |
| 590 | } | 766 | } |
| 591 | 767 | ||
| 592 | const char *target_exe_file_ext(ZigTarget *target) { | 768 | const char *target_exe_file_ext(ZigTarget *target) { |
| 593 | if (target->os == ZigLLVM_Win32) { | 769 | if (target->os == OsWindows) { |
| 594 | return ".exe"; | 770 | return ".exe"; |
| 595 | } else { | 771 | } else { |
| 596 | return ""; | 772 | return ""; |
| ... | @@ -690,12 +866,12 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target | ... | @@ -690,12 +866,12 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target |
| 690 | return true; | 866 | return true; |
| 691 | } | 867 | } |
| 692 | 868 | ||
| 693 | if (guest_target->os == ZigLLVM_Win32 && host_target->os == ZigLLVM_Win32 && | 869 | if (guest_target->os == OsWindows && host_target->os == OsWindows && |
| 694 | host_target->arch.arch == ZigLLVM_x86_64 && guest_target->arch.arch == ZigLLVM_x86) | 870 | host_target->arch.arch == ZigLLVM_x86_64 && guest_target->arch.arch == ZigLLVM_x86) |
| 695 | { | 871 | { |
| 696 | // 64-bit windows can run 32-bit programs | 872 | // 64-bit windows can run 32-bit programs |
| 697 | return true; | 873 | return true; |
| 698 | } | 874 | } |
| 699 | 875 | ||
| 700 | return false; | 876 | return false; |
| 701 | } | 877 | } |
src/target.hpp+39-4| ... | @@ -17,10 +17,45 @@ struct ArchType { | ... | @@ -17,10 +17,45 @@ struct ArchType { |
| 17 | ZigLLVM_SubArchType sub_arch; | 17 | ZigLLVM_SubArchType sub_arch; |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | enum Os { | ||
| 21 | OsFreestanding, | ||
| 22 | OsAnanas, | ||
| 23 | OsCloudABI, | ||
| 24 | OsDragonFly, | ||
| 25 | OsFreeBSD, | ||
| 26 | OsFuchsia, | ||
| 27 | OsIOS, | ||
| 28 | OsKFreeBSD, | ||
| 29 | OsLinux, | ||
| 30 | OsLv2, // PS3 | ||
| 31 | OsMacOSX, | ||
| 32 | OsNetBSD, | ||
| 33 | OsOpenBSD, | ||
| 34 | OsSolaris, | ||
| 35 | OsWindows, | ||
| 36 | OsHaiku, | ||
| 37 | OsMinix, | ||
| 38 | OsRTEMS, | ||
| 39 | OsNaCl, // Native Client | ||
| 40 | OsCNK, // BG/P Compute-Node Kernel | ||
| 41 | OsBitrig, | ||
| 42 | OsAIX, | ||
| 43 | OsCUDA, // NVIDIA CUDA | ||
| 44 | OsNVCL, // NVIDIA OpenCL | ||
| 45 | OsAMDHSA, // AMD HSA Runtime | ||
| 46 | OsPS4, | ||
| 47 | OsELFIAMCU, | ||
| 48 | OsTvOS, // Apple tvOS | ||
| 49 | OsWatchOS, // Apple watchOS | ||
| 50 | OsMesa3D, | ||
| 51 | OsContiki, | ||
| 52 | OsZen, | ||
| 53 | }; | ||
| 54 | |||
| 20 | struct ZigTarget { | 55 | struct ZigTarget { |
| 21 | ArchType arch; | 56 | ArchType arch; |
| 22 | ZigLLVM_VendorType vendor; | 57 | ZigLLVM_VendorType vendor; |
| 23 | ZigLLVM_OSType os; | 58 | Os os; |
| 24 | ZigLLVM_EnvironmentType env_type; | 59 | ZigLLVM_EnvironmentType env_type; |
| 25 | ZigLLVM_ObjectFormatType oformat; | 60 | ZigLLVM_ObjectFormatType oformat; |
| 26 | }; | 61 | }; |
| ... | @@ -46,8 +81,8 @@ size_t target_vendor_count(void); | ... | @@ -46,8 +81,8 @@ size_t target_vendor_count(void); |
| 46 | ZigLLVM_VendorType get_target_vendor(size_t index); | 81 | ZigLLVM_VendorType get_target_vendor(size_t index); |
| 47 | 82 | ||
| 48 | size_t target_os_count(void); | 83 | size_t target_os_count(void); |
| 49 | ZigLLVM_OSType get_target_os(size_t index); | 84 | Os get_target_os(size_t index); |
| 50 | const char *get_target_os_name(ZigLLVM_OSType os_type); | 85 | const char *get_target_os_name(Os os_type); |
| 51 | 86 | ||
| 52 | size_t target_environ_count(void); | 87 | size_t target_environ_count(void); |
| 53 | ZigLLVM_EnvironmentType get_target_environ(size_t index); | 88 | ZigLLVM_EnvironmentType get_target_environ(size_t index); |
| ... | @@ -61,7 +96,7 @@ void get_native_target(ZigTarget *target); | ... | @@ -61,7 +96,7 @@ void get_native_target(ZigTarget *target); |
| 61 | void get_unknown_target(ZigTarget *target); | 96 | void get_unknown_target(ZigTarget *target); |
| 62 | 97 | ||
| 63 | int parse_target_arch(const char *str, ArchType *arch); | 98 | int parse_target_arch(const char *str, ArchType *arch); |
| 64 | int parse_target_os(const char *str, ZigLLVM_OSType *os); | 99 | int parse_target_os(const char *str, Os *os); |
| 65 | int parse_target_environ(const char *str, ZigLLVM_EnvironmentType *env_type); | 100 | int parse_target_environ(const char *str, ZigLLVM_EnvironmentType *env_type); |
| 66 | 101 | ||
| 67 | void init_all_targets(void); | 102 | void init_all_targets(void); |
src/tokenizer.cpp+4| ... | @@ -111,6 +111,7 @@ static const struct ZigKeyword zig_keywords[] = { | ... | @@ -111,6 +111,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 111 | {"and", TokenIdKeywordAnd}, | 111 | {"and", TokenIdKeywordAnd}, |
| 112 | {"asm", TokenIdKeywordAsm}, | 112 | {"asm", TokenIdKeywordAsm}, |
| 113 | {"break", TokenIdKeywordBreak}, | 113 | {"break", TokenIdKeywordBreak}, |
| 114 | {"catch", TokenIdKeywordCatch}, | ||
| 114 | {"coldcc", TokenIdKeywordColdCC}, | 115 | {"coldcc", TokenIdKeywordColdCC}, |
| 115 | {"comptime", TokenIdKeywordCompTime}, | 116 | {"comptime", TokenIdKeywordCompTime}, |
| 116 | {"const", TokenIdKeywordConst}, | 117 | {"const", TokenIdKeywordConst}, |
| ... | @@ -141,6 +142,7 @@ static const struct ZigKeyword zig_keywords[] = { | ... | @@ -141,6 +142,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 141 | {"test", TokenIdKeywordTest}, | 142 | {"test", TokenIdKeywordTest}, |
| 142 | {"this", TokenIdKeywordThis}, | 143 | {"this", TokenIdKeywordThis}, |
| 143 | {"true", TokenIdKeywordTrue}, | 144 | {"true", TokenIdKeywordTrue}, |
| 145 | {"try", TokenIdKeywordTry}, | ||
| 144 | {"undefined", TokenIdKeywordUndefined}, | 146 | {"undefined", TokenIdKeywordUndefined}, |
| 145 | {"union", TokenIdKeywordUnion}, | 147 | {"union", TokenIdKeywordUnion}, |
| 146 | {"unreachable", TokenIdKeywordUnreachable}, | 148 | {"unreachable", TokenIdKeywordUnreachable}, |
| ... | @@ -1511,6 +1513,7 @@ const char * token_name(TokenId id) { | ... | @@ -1511,6 +1513,7 @@ const char * token_name(TokenId id) { |
| 1511 | case TokenIdKeywordAnd: return "and"; | 1513 | case TokenIdKeywordAnd: return "and"; |
| 1512 | case TokenIdKeywordAsm: return "asm"; | 1514 | case TokenIdKeywordAsm: return "asm"; |
| 1513 | case TokenIdKeywordBreak: return "break"; | 1515 | case TokenIdKeywordBreak: return "break"; |
| 1516 | case TokenIdKeywordCatch: return "catch"; | ||
| 1514 | case TokenIdKeywordColdCC: return "coldcc"; | 1517 | case TokenIdKeywordColdCC: return "coldcc"; |
| 1515 | case TokenIdKeywordCompTime: return "comptime"; | 1518 | case TokenIdKeywordCompTime: return "comptime"; |
| 1516 | case TokenIdKeywordConst: return "const"; | 1519 | case TokenIdKeywordConst: return "const"; |
| ... | @@ -1541,6 +1544,7 @@ const char * token_name(TokenId id) { | ... | @@ -1541,6 +1544,7 @@ const char * token_name(TokenId id) { |
| 1541 | case TokenIdKeywordTest: return "test"; | 1544 | case TokenIdKeywordTest: return "test"; |
| 1542 | case TokenIdKeywordThis: return "this"; | 1545 | case TokenIdKeywordThis: return "this"; |
| 1543 | case TokenIdKeywordTrue: return "true"; | 1546 | case TokenIdKeywordTrue: return "true"; |
| 1547 | case TokenIdKeywordTry: return "try"; | ||
| 1544 | case TokenIdKeywordUndefined: return "undefined"; | 1548 | case TokenIdKeywordUndefined: return "undefined"; |
| 1545 | case TokenIdKeywordUnion: return "union"; | 1549 | case TokenIdKeywordUnion: return "union"; |
| 1546 | case TokenIdKeywordUnreachable: return "unreachable"; | 1550 | case TokenIdKeywordUnreachable: return "unreachable"; |
src/tokenizer.hpp+3-1| ... | @@ -47,10 +47,10 @@ enum TokenId { | ... | @@ -47,10 +47,10 @@ enum TokenId { |
| 47 | TokenIdFloatLiteral, | 47 | TokenIdFloatLiteral, |
| 48 | TokenIdIntLiteral, | 48 | TokenIdIntLiteral, |
| 49 | TokenIdKeywordAlign, | 49 | TokenIdKeywordAlign, |
| 50 | TokenIdKeywordSection, | ||
| 51 | TokenIdKeywordAnd, | 50 | TokenIdKeywordAnd, |
| 52 | TokenIdKeywordAsm, | 51 | TokenIdKeywordAsm, |
| 53 | TokenIdKeywordBreak, | 52 | TokenIdKeywordBreak, |
| 53 | TokenIdKeywordCatch, | ||
| 54 | TokenIdKeywordColdCC, | 54 | TokenIdKeywordColdCC, |
| 55 | TokenIdKeywordCompTime, | 55 | TokenIdKeywordCompTime, |
| 56 | TokenIdKeywordConst, | 56 | TokenIdKeywordConst, |
| ... | @@ -74,12 +74,14 @@ enum TokenId { | ... | @@ -74,12 +74,14 @@ enum TokenId { |
| 74 | TokenIdKeywordPacked, | 74 | TokenIdKeywordPacked, |
| 75 | TokenIdKeywordPub, | 75 | TokenIdKeywordPub, |
| 76 | TokenIdKeywordReturn, | 76 | TokenIdKeywordReturn, |
| 77 | TokenIdKeywordSection, | ||
| 77 | TokenIdKeywordStdcallCC, | 78 | TokenIdKeywordStdcallCC, |
| 78 | TokenIdKeywordStruct, | 79 | TokenIdKeywordStruct, |
| 79 | TokenIdKeywordSwitch, | 80 | TokenIdKeywordSwitch, |
| 80 | TokenIdKeywordTest, | 81 | TokenIdKeywordTest, |
| 81 | TokenIdKeywordThis, | 82 | TokenIdKeywordThis, |
| 82 | TokenIdKeywordTrue, | 83 | TokenIdKeywordTrue, |
| 84 | TokenIdKeywordTry, | ||
| 83 | TokenIdKeywordUndefined, | 85 | TokenIdKeywordUndefined, |
| 84 | TokenIdKeywordUnion, | 86 | TokenIdKeywordUnion, |
| 85 | TokenIdKeywordUnreachable, | 87 | TokenIdKeywordUnreachable, |
std/array_list.zig+5-5| ... | @@ -60,18 +60,18 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{ | ... | @@ -60,18 +60,18 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{ |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | pub fn append(l: &Self, item: &const T) -> %void { | 62 | pub fn append(l: &Self, item: &const T) -> %void { |
| 63 | const new_item_ptr = %return l.addOne(); | 63 | const new_item_ptr = try l.addOne(); |
| 64 | *new_item_ptr = *item; | 64 | *new_item_ptr = *item; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | pub fn appendSlice(l: &Self, items: []align(A) const T) -> %void { | 67 | pub fn appendSlice(l: &Self, items: []align(A) const T) -> %void { |
| 68 | %return l.ensureCapacity(l.len + items.len); | 68 | try l.ensureCapacity(l.len + items.len); |
| 69 | mem.copy(T, l.items[l.len..], items); | 69 | mem.copy(T, l.items[l.len..], items); |
| 70 | l.len += items.len; | 70 | l.len += items.len; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | pub fn resize(l: &Self, new_len: usize) -> %void { | 73 | pub fn resize(l: &Self, new_len: usize) -> %void { |
| 74 | %return l.ensureCapacity(new_len); | 74 | try l.ensureCapacity(new_len); |
| 75 | l.len = new_len; | 75 | l.len = new_len; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| ... | @@ -87,12 +87,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{ | ... | @@ -87,12 +87,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{ |
| 87 | better_capacity += better_capacity / 2 + 8; | 87 | better_capacity += better_capacity / 2 + 8; |
| 88 | if (better_capacity >= new_capacity) break; | 88 | if (better_capacity >= new_capacity) break; |
| 89 | } | 89 | } |
| 90 | l.items = %return l.allocator.alignedRealloc(T, A, l.items, better_capacity); | 90 | l.items = try l.allocator.alignedRealloc(T, A, l.items, better_capacity); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | pub fn addOne(l: &Self) -> %&T { | 93 | pub fn addOne(l: &Self) -> %&T { |
| 94 | const new_length = l.len + 1; | 94 | const new_length = l.len + 1; |
| 95 | %return l.ensureCapacity(new_length); | 95 | try l.ensureCapacity(new_length); |
| 96 | const result = &l.items[l.len]; | 96 | const result = &l.items[l.len]; |
| 97 | l.len = new_length; | 97 | l.len = new_length; |
| 98 | return result; | 98 | return result; |
std/base64.zig+35-35| ... | @@ -379,37 +379,37 @@ test "base64" { | ... | @@ -379,37 +379,37 @@ test "base64" { |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | fn testBase64() -> %void { | 381 | fn testBase64() -> %void { |
| 382 | %return testAllApis("", ""); | 382 | try testAllApis("", ""); |
| 383 | %return testAllApis("f", "Zg=="); | 383 | try testAllApis("f", "Zg=="); |
| 384 | %return testAllApis("fo", "Zm8="); | 384 | try testAllApis("fo", "Zm8="); |
| 385 | %return testAllApis("foo", "Zm9v"); | 385 | try testAllApis("foo", "Zm9v"); |
| 386 | %return testAllApis("foob", "Zm9vYg=="); | 386 | try testAllApis("foob", "Zm9vYg=="); |
| 387 | %return testAllApis("fooba", "Zm9vYmE="); | 387 | try testAllApis("fooba", "Zm9vYmE="); |
| 388 | %return testAllApis("foobar", "Zm9vYmFy"); | 388 | try testAllApis("foobar", "Zm9vYmFy"); |
| 389 | 389 | ||
| 390 | %return testDecodeIgnoreSpace("", " "); | 390 | try testDecodeIgnoreSpace("", " "); |
| 391 | %return testDecodeIgnoreSpace("f", "Z g= ="); | 391 | try testDecodeIgnoreSpace("f", "Z g= ="); |
| 392 | %return testDecodeIgnoreSpace("fo", " Zm8="); | 392 | try testDecodeIgnoreSpace("fo", " Zm8="); |
| 393 | %return testDecodeIgnoreSpace("foo", "Zm9v "); | 393 | try testDecodeIgnoreSpace("foo", "Zm9v "); |
| 394 | %return testDecodeIgnoreSpace("foob", "Zm9vYg = = "); | 394 | try testDecodeIgnoreSpace("foob", "Zm9vYg = = "); |
| 395 | %return testDecodeIgnoreSpace("fooba", "Zm9v YmE="); | 395 | try testDecodeIgnoreSpace("fooba", "Zm9v YmE="); |
| 396 | %return testDecodeIgnoreSpace("foobar", " Z m 9 v Y m F y "); | 396 | try testDecodeIgnoreSpace("foobar", " Z m 9 v Y m F y "); |
| 397 | 397 | ||
| 398 | // test getting some api errors | 398 | // test getting some api errors |
| 399 | %return testError("A", error.InvalidPadding); | 399 | try testError("A", error.InvalidPadding); |
| 400 | %return testError("AA", error.InvalidPadding); | 400 | try testError("AA", error.InvalidPadding); |
| 401 | %return testError("AAA", error.InvalidPadding); | 401 | try testError("AAA", error.InvalidPadding); |
| 402 | %return testError("A..A", error.InvalidCharacter); | 402 | try testError("A..A", error.InvalidCharacter); |
| 403 | %return testError("AA=A", error.InvalidCharacter); | 403 | try testError("AA=A", error.InvalidCharacter); |
| 404 | %return testError("AA/=", error.InvalidPadding); | 404 | try testError("AA/=", error.InvalidPadding); |
| 405 | %return testError("A/==", error.InvalidPadding); | 405 | try testError("A/==", error.InvalidPadding); |
| 406 | %return testError("A===", error.InvalidCharacter); | 406 | try testError("A===", error.InvalidCharacter); |
| 407 | %return testError("====", error.InvalidCharacter); | 407 | try testError("====", error.InvalidCharacter); |
| 408 | 408 | ||
| 409 | %return testOutputTooSmallError("AA=="); | 409 | try testOutputTooSmallError("AA=="); |
| 410 | %return testOutputTooSmallError("AAA="); | 410 | try testOutputTooSmallError("AAA="); |
| 411 | %return testOutputTooSmallError("AAAA"); | 411 | try testOutputTooSmallError("AAAA"); |
| 412 | %return testOutputTooSmallError("AAAAAA=="); | 412 | try testOutputTooSmallError("AAAAAA=="); |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %void { | 415 | fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %void { |
| ... | @@ -424,8 +424,8 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v | ... | @@ -424,8 +424,8 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v |
| 424 | // Base64Decoder | 424 | // Base64Decoder |
| 425 | { | 425 | { |
| 426 | var buffer: [0x100]u8 = undefined; | 426 | var buffer: [0x100]u8 = undefined; |
| 427 | var decoded = buffer[0..%return standard_decoder.calcSize(expected_encoded)]; | 427 | var decoded = buffer[0..try standard_decoder.calcSize(expected_encoded)]; |
| 428 | %return standard_decoder.decode(decoded, expected_encoded); | 428 | try standard_decoder.decode(decoded, expected_encoded); |
| 429 | assert(mem.eql(u8, decoded, expected_decoded)); | 429 | assert(mem.eql(u8, decoded, expected_decoded)); |
| 430 | } | 430 | } |
| 431 | 431 | ||
| ... | @@ -434,8 +434,8 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v | ... | @@ -434,8 +434,8 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v |
| 434 | const standard_decoder_ignore_nothing = Base64DecoderWithIgnore.init( | 434 | const standard_decoder_ignore_nothing = Base64DecoderWithIgnore.init( |
| 435 | standard_alphabet_chars, standard_pad_char, ""); | 435 | standard_alphabet_chars, standard_pad_char, ""); |
| 436 | var buffer: [0x100]u8 = undefined; | 436 | var buffer: [0x100]u8 = undefined; |
| 437 | var decoded = buffer[0..%return Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)]; | 437 | var decoded = buffer[0..try Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)]; |
| 438 | var written = %return standard_decoder_ignore_nothing.decode(decoded, expected_encoded); | 438 | var written = try standard_decoder_ignore_nothing.decode(decoded, expected_encoded); |
| 439 | assert(written <= decoded.len); | 439 | assert(written <= decoded.len); |
| 440 | assert(mem.eql(u8, decoded[0..written], expected_decoded)); | 440 | assert(mem.eql(u8, decoded[0..written], expected_decoded)); |
| 441 | } | 441 | } |
| ... | @@ -453,8 +453,8 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> % | ... | @@ -453,8 +453,8 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> % |
| 453 | const standard_decoder_ignore_space = Base64DecoderWithIgnore.init( | 453 | const standard_decoder_ignore_space = Base64DecoderWithIgnore.init( |
| 454 | standard_alphabet_chars, standard_pad_char, " "); | 454 | standard_alphabet_chars, standard_pad_char, " "); |
| 455 | var buffer: [0x100]u8 = undefined; | 455 | var buffer: [0x100]u8 = undefined; |
| 456 | var decoded = buffer[0..%return Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)]; | 456 | var decoded = buffer[0..try Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)]; |
| 457 | var written = %return standard_decoder_ignore_space.decode(decoded, encoded); | 457 | var written = try standard_decoder_ignore_space.decode(decoded, encoded); |
| 458 | assert(mem.eql(u8, decoded[0..written], expected_decoded)); | 458 | assert(mem.eql(u8, decoded[0..written], expected_decoded)); |
| 459 | } | 459 | } |
| 460 | 460 |
std/buf_map.zig+6-6| ... | @@ -29,16 +29,16 @@ pub const BufMap = struct { | ... | @@ -29,16 +29,16 @@ pub const BufMap = struct { |
| 29 | 29 | ||
| 30 | pub fn set(self: &BufMap, key: []const u8, value: []const u8) -> %void { | 30 | pub fn set(self: &BufMap, key: []const u8, value: []const u8) -> %void { |
| 31 | if (self.hash_map.get(key)) |entry| { | 31 | if (self.hash_map.get(key)) |entry| { |
| 32 | const value_copy = %return self.copy(value); | 32 | const value_copy = try self.copy(value); |
| 33 | %defer self.free(value_copy); | 33 | %defer self.free(value_copy); |
| 34 | _ = %return self.hash_map.put(key, value_copy); | 34 | _ = try self.hash_map.put(key, value_copy); |
| 35 | self.free(entry.value); | 35 | self.free(entry.value); |
| 36 | } else { | 36 | } else { |
| 37 | const key_copy = %return self.copy(key); | 37 | const key_copy = try self.copy(key); |
| 38 | %defer self.free(key_copy); | 38 | %defer self.free(key_copy); |
| 39 | const value_copy = %return self.copy(value); | 39 | const value_copy = try self.copy(value); |
| 40 | %defer self.free(value_copy); | 40 | %defer self.free(value_copy); |
| 41 | _ = %return self.hash_map.put(key_copy, value_copy); | 41 | _ = try self.hash_map.put(key_copy, value_copy); |
| 42 | } | 42 | } |
| 43 | } | 43 | } |
| 44 | 44 | ||
| ... | @@ -68,7 +68,7 @@ pub const BufMap = struct { | ... | @@ -68,7 +68,7 @@ pub const BufMap = struct { |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | fn copy(self: &BufMap, value: []const u8) -> %[]const u8 { | 70 | fn copy(self: &BufMap, value: []const u8) -> %[]const u8 { |
| 71 | const result = %return self.hash_map.allocator.alloc(u8, value.len); | 71 | const result = try self.hash_map.allocator.alloc(u8, value.len); |
| 72 | mem.copy(u8, result, value); | 72 | mem.copy(u8, result, value); |
| 73 | return result; | 73 | return result; |
| 74 | } | 74 | } |
std/buf_set.zig+3-3| ... | @@ -26,9 +26,9 @@ pub const BufSet = struct { | ... | @@ -26,9 +26,9 @@ pub const BufSet = struct { |
| 26 | 26 | ||
| 27 | pub fn put(self: &BufSet, key: []const u8) -> %void { | 27 | pub fn put(self: &BufSet, key: []const u8) -> %void { |
| 28 | if (self.hash_map.get(key) == null) { | 28 | if (self.hash_map.get(key) == null) { |
| 29 | const key_copy = %return self.copy(key); | 29 | const key_copy = try self.copy(key); |
| 30 | %defer self.free(key_copy); | 30 | %defer self.free(key_copy); |
| 31 | _ = %return self.hash_map.put(key_copy, {}); | 31 | _ = try self.hash_map.put(key_copy, {}); |
| 32 | } | 32 | } |
| 33 | } | 33 | } |
| 34 | 34 | ||
| ... | @@ -56,7 +56,7 @@ pub const BufSet = struct { | ... | @@ -56,7 +56,7 @@ pub const BufSet = struct { |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | fn copy(self: &BufSet, value: []const u8) -> %[]const u8 { | 58 | fn copy(self: &BufSet, value: []const u8) -> %[]const u8 { |
| 59 | const result = %return self.hash_map.allocator.alloc(u8, value.len); | 59 | const result = try self.hash_map.allocator.alloc(u8, value.len); |
| 60 | mem.copy(u8, result, value); | 60 | mem.copy(u8, result, value); |
| 61 | return result; | 61 | return result; |
| 62 | } | 62 | } |
std/buffer.zig+6-6| ... | @@ -13,7 +13,7 @@ pub const Buffer = struct { | ... | @@ -13,7 +13,7 @@ pub const Buffer = struct { |
| 13 | 13 | ||
| 14 | /// Must deinitialize with deinit. | 14 | /// Must deinitialize with deinit. |
| 15 | pub fn init(allocator: &Allocator, m: []const u8) -> %Buffer { | 15 | pub fn init(allocator: &Allocator, m: []const u8) -> %Buffer { |
| 16 | var self = %return initSize(allocator, m.len); | 16 | var self = try initSize(allocator, m.len); |
| 17 | mem.copy(u8, self.list.items, m); | 17 | mem.copy(u8, self.list.items, m); |
| 18 | return self; | 18 | return self; |
| 19 | } | 19 | } |
| ... | @@ -21,7 +21,7 @@ pub const Buffer = struct { | ... | @@ -21,7 +21,7 @@ pub const Buffer = struct { |
| 21 | /// Must deinitialize with deinit. | 21 | /// Must deinitialize with deinit. |
| 22 | pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer { | 22 | pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer { |
| 23 | var self = initNull(allocator); | 23 | var self = initNull(allocator); |
| 24 | %return self.resize(size); | 24 | try self.resize(size); |
| 25 | return self; | 25 | return self; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| ... | @@ -81,7 +81,7 @@ pub const Buffer = struct { | ... | @@ -81,7 +81,7 @@ pub const Buffer = struct { |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | pub fn resize(self: &Buffer, new_len: usize) -> %void { | 83 | pub fn resize(self: &Buffer, new_len: usize) -> %void { |
| 84 | %return self.list.resize(new_len + 1); | 84 | try self.list.resize(new_len + 1); |
| 85 | self.list.items[self.len()] = 0; | 85 | self.list.items[self.len()] = 0; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| ... | @@ -95,7 +95,7 @@ pub const Buffer = struct { | ... | @@ -95,7 +95,7 @@ pub const Buffer = struct { |
| 95 | 95 | ||
| 96 | pub fn append(self: &Buffer, m: []const u8) -> %void { | 96 | pub fn append(self: &Buffer, m: []const u8) -> %void { |
| 97 | const old_len = self.len(); | 97 | const old_len = self.len(); |
| 98 | %return self.resize(old_len + m.len); | 98 | try self.resize(old_len + m.len); |
| 99 | mem.copy(u8, self.list.toSlice()[old_len..], m); | 99 | mem.copy(u8, self.list.toSlice()[old_len..], m); |
| 100 | } | 100 | } |
| 101 | 101 | ||
| ... | @@ -113,7 +113,7 @@ pub const Buffer = struct { | ... | @@ -113,7 +113,7 @@ pub const Buffer = struct { |
| 113 | pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) -> %void { | 113 | pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) -> %void { |
| 114 | var prev_size: usize = self.len(); | 114 | var prev_size: usize = self.len(); |
| 115 | const new_size = prev_size + count; | 115 | const new_size = prev_size + count; |
| 116 | %return self.resize(new_size); | 116 | try self.resize(new_size); |
| 117 | 117 | ||
| 118 | var i: usize = prev_size; | 118 | var i: usize = prev_size; |
| 119 | while (i < new_size) : (i += 1) { | 119 | while (i < new_size) : (i += 1) { |
| ... | @@ -138,7 +138,7 @@ pub const Buffer = struct { | ... | @@ -138,7 +138,7 @@ pub const Buffer = struct { |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | pub fn replaceContents(self: &const Buffer, m: []const u8) -> %void { | 140 | pub fn replaceContents(self: &const Buffer, m: []const u8) -> %void { |
| 141 | %return self.resize(m.len); | 141 | try self.resize(m.len); |
| 142 | mem.copy(u8, self.list.toSlice(), m); | 142 | mem.copy(u8, self.list.toSlice(), m); |
| 143 | } | 143 | } |
| 144 | 144 |
std/build.zig+37-37| ... | @@ -250,13 +250,13 @@ pub const Builder = struct { | ... | @@ -250,13 +250,13 @@ pub const Builder = struct { |
| 250 | %%wanted_steps.append(&self.default_step); | 250 | %%wanted_steps.append(&self.default_step); |
| 251 | } else { | 251 | } else { |
| 252 | for (step_names) |step_name| { | 252 | for (step_names) |step_name| { |
| 253 | const s = %return self.getTopLevelStepByName(step_name); | 253 | const s = try self.getTopLevelStepByName(step_name); |
| 254 | %%wanted_steps.append(s); | 254 | %%wanted_steps.append(s); |
| 255 | } | 255 | } |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | for (wanted_steps.toSliceConst()) |s| { | 258 | for (wanted_steps.toSliceConst()) |s| { |
| 259 | %return self.makeOneStep(s); | 259 | try self.makeOneStep(s); |
| 260 | } | 260 | } |
| 261 | } | 261 | } |
| 262 | 262 | ||
| ... | @@ -300,7 +300,7 @@ pub const Builder = struct { | ... | @@ -300,7 +300,7 @@ pub const Builder = struct { |
| 300 | s.loop_flag = true; | 300 | s.loop_flag = true; |
| 301 | 301 | ||
| 302 | for (s.dependencies.toSlice()) |dep| { | 302 | for (s.dependencies.toSlice()) |dep| { |
| 303 | self.makeOneStep(dep) %% |err| { | 303 | self.makeOneStep(dep) catch |err| { |
| 304 | if (err == error.DependencyLoopDetected) { | 304 | if (err == error.DependencyLoopDetected) { |
| 305 | warn(" {}\n", s.name); | 305 | warn(" {}\n", s.name); |
| 306 | } | 306 | } |
| ... | @@ -310,7 +310,7 @@ pub const Builder = struct { | ... | @@ -310,7 +310,7 @@ pub const Builder = struct { |
| 310 | 310 | ||
| 311 | s.loop_flag = false; | 311 | s.loop_flag = false; |
| 312 | 312 | ||
| 313 | %return s.make(); | 313 | try s.make(); |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | fn getTopLevelStepByName(self: &Builder, name: []const u8) -> %&Step { | 316 | fn getTopLevelStepByName(self: &Builder, name: []const u8) -> %&Step { |
| ... | @@ -573,7 +573,7 @@ pub const Builder = struct { | ... | @@ -573,7 +573,7 @@ pub const Builder = struct { |
| 573 | child.cwd = cwd; | 573 | child.cwd = cwd; |
| 574 | child.env_map = env_map; | 574 | child.env_map = env_map; |
| 575 | 575 | ||
| 576 | const term = child.spawnAndWait() %% |err| { | 576 | const term = child.spawnAndWait() catch |err| { |
| 577 | warn("Unable to spawn {}: {}\n", argv[0], @errorName(err)); | 577 | warn("Unable to spawn {}: {}\n", argv[0], @errorName(err)); |
| 578 | return err; | 578 | return err; |
| 579 | }; | 579 | }; |
| ... | @@ -596,7 +596,7 @@ pub const Builder = struct { | ... | @@ -596,7 +596,7 @@ pub const Builder = struct { |
| 596 | } | 596 | } |
| 597 | 597 | ||
| 598 | pub fn makePath(self: &Builder, path: []const u8) -> %void { | 598 | pub fn makePath(self: &Builder, path: []const u8) -> %void { |
| 599 | os.makePath(self.allocator, self.pathFromRoot(path)) %% |err| { | 599 | os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| { |
| 600 | warn("Unable to create path {}: {}\n", path, @errorName(err)); | 600 | warn("Unable to create path {}: {}\n", path, @errorName(err)); |
| 601 | return err; | 601 | return err; |
| 602 | }; | 602 | }; |
| ... | @@ -641,11 +641,11 @@ pub const Builder = struct { | ... | @@ -641,11 +641,11 @@ pub const Builder = struct { |
| 641 | 641 | ||
| 642 | const dirname = os.path.dirname(dest_path); | 642 | const dirname = os.path.dirname(dest_path); |
| 643 | const abs_source_path = self.pathFromRoot(source_path); | 643 | const abs_source_path = self.pathFromRoot(source_path); |
| 644 | os.makePath(self.allocator, dirname) %% |err| { | 644 | os.makePath(self.allocator, dirname) catch |err| { |
| 645 | warn("Unable to create path {}: {}\n", dirname, @errorName(err)); | 645 | warn("Unable to create path {}: {}\n", dirname, @errorName(err)); |
| 646 | return err; | 646 | return err; |
| 647 | }; | 647 | }; |
| 648 | os.copyFileMode(self.allocator, abs_source_path, dest_path, mode) %% |err| { | 648 | os.copyFileMode(self.allocator, abs_source_path, dest_path, mode) catch |err| { |
| 649 | warn("Unable to copy {} to {}: {}\n", abs_source_path, dest_path, @errorName(err)); | 649 | warn("Unable to copy {} to {}: {}\n", abs_source_path, dest_path, @errorName(err)); |
| 650 | return err; | 650 | return err; |
| 651 | }; | 651 | }; |
| ... | @@ -663,7 +663,7 @@ pub const Builder = struct { | ... | @@ -663,7 +663,7 @@ pub const Builder = struct { |
| 663 | if (builtin.environ == builtin.Environ.msvc) { | 663 | if (builtin.environ == builtin.Environ.msvc) { |
| 664 | return "cl.exe"; | 664 | return "cl.exe"; |
| 665 | } else { | 665 | } else { |
| 666 | return os.getEnvVarOwned(self.allocator, "CC") %% |err| | 666 | return os.getEnvVarOwned(self.allocator, "CC") catch |err| |
| 667 | if (err == error.EnvironmentVariableNotFound) | 667 | if (err == error.EnvironmentVariableNotFound) |
| 668 | ([]const u8)("cc") | 668 | ([]const u8)("cc") |
| 669 | else | 669 | else |
| ... | @@ -680,7 +680,7 @@ pub const Builder = struct { | ... | @@ -680,7 +680,7 @@ pub const Builder = struct { |
| 680 | if (os.path.isAbsolute(name)) { | 680 | if (os.path.isAbsolute(name)) { |
| 681 | return name; | 681 | return name; |
| 682 | } | 682 | } |
| 683 | const full_path = %return os.path.join(self.allocator, search_prefix, "bin", | 683 | const full_path = try os.path.join(self.allocator, search_prefix, "bin", |
| 684 | self.fmt("{}{}", name, exe_extension)); | 684 | self.fmt("{}{}", name, exe_extension)); |
| 685 | if (os.path.real(self.allocator, full_path)) |real_path| { | 685 | if (os.path.real(self.allocator, full_path)) |real_path| { |
| 686 | return real_path; | 686 | return real_path; |
| ... | @@ -696,7 +696,7 @@ pub const Builder = struct { | ... | @@ -696,7 +696,7 @@ pub const Builder = struct { |
| 696 | } | 696 | } |
| 697 | var it = mem.split(PATH, []u8{os.path.delimiter}); | 697 | var it = mem.split(PATH, []u8{os.path.delimiter}); |
| 698 | while (it.next()) |path| { | 698 | while (it.next()) |path| { |
| 699 | const full_path = %return os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension)); | 699 | const full_path = try os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension)); |
| 700 | if (os.path.real(self.allocator, full_path)) |real_path| { | 700 | if (os.path.real(self.allocator, full_path)) |real_path| { |
| 701 | return real_path; | 701 | return real_path; |
| 702 | } else |_| { | 702 | } else |_| { |
| ... | @@ -710,7 +710,7 @@ pub const Builder = struct { | ... | @@ -710,7 +710,7 @@ pub const Builder = struct { |
| 710 | return name; | 710 | return name; |
| 711 | } | 711 | } |
| 712 | for (paths) |path| { | 712 | for (paths) |path| { |
| 713 | const full_path = %return os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension)); | 713 | const full_path = try os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension)); |
| 714 | if (os.path.real(self.allocator, full_path)) |real_path| { | 714 | if (os.path.real(self.allocator, full_path)) |real_path| { |
| 715 | return real_path; | 715 | return real_path; |
| 716 | } else |_| { | 716 | } else |_| { |
| ... | @@ -723,7 +723,7 @@ pub const Builder = struct { | ... | @@ -723,7 +723,7 @@ pub const Builder = struct { |
| 723 | 723 | ||
| 724 | pub fn exec(self: &Builder, argv: []const []const u8) -> []u8 { | 724 | pub fn exec(self: &Builder, argv: []const []const u8) -> []u8 { |
| 725 | const max_output_size = 100 * 1024; | 725 | const max_output_size = 100 * 1024; |
| 726 | const result = os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size) %% |err| { | 726 | const result = os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size) catch |err| { |
| 727 | std.debug.panic("Unable to spawn {}: {}", argv[0], @errorName(err)); | 727 | std.debug.panic("Unable to spawn {}: {}", argv[0], @errorName(err)); |
| 728 | }; | 728 | }; |
| 729 | switch (result.term) { | 729 | switch (result.term) { |
| ... | @@ -800,7 +800,7 @@ const Target = union(enum) { | ... | @@ -800,7 +800,7 @@ const Target = union(enum) { |
| 800 | 800 | ||
| 801 | pub fn isDarwin(self: &const Target) -> bool { | 801 | pub fn isDarwin(self: &const Target) -> bool { |
| 802 | return switch (self.getOs()) { | 802 | return switch (self.getOs()) { |
| 803 | builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => true, | 803 | builtin.Os.ios, builtin.Os.macosx => true, |
| 804 | else => false, | 804 | else => false, |
| 805 | }; | 805 | }; |
| 806 | } | 806 | } |
| ... | @@ -1011,7 +1011,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1011,7 +1011,7 @@ pub const LibExeObjStep = struct { |
| 1011 | self.out_filename = self.builder.fmt("lib{}.a", self.name); | 1011 | self.out_filename = self.builder.fmt("lib{}.a", self.name); |
| 1012 | } else { | 1012 | } else { |
| 1013 | switch (self.target.getOs()) { | 1013 | switch (self.target.getOs()) { |
| 1014 | builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => { | 1014 | builtin.Os.ios, builtin.Os.macosx => { |
| 1015 | self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", | 1015 | self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", |
| 1016 | self.name, self.version.major, self.version.minor, self.version.patch); | 1016 | self.name, self.version.major, self.version.minor, self.version.patch); |
| 1017 | self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major); | 1017 | self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major); |
| ... | @@ -1345,10 +1345,10 @@ pub const LibExeObjStep = struct { | ... | @@ -1345,10 +1345,10 @@ pub const LibExeObjStep = struct { |
| 1345 | } | 1345 | } |
| 1346 | } | 1346 | } |
| 1347 | 1347 | ||
| 1348 | %return builder.spawnChild(zig_args.toSliceConst()); | 1348 | try builder.spawnChild(zig_args.toSliceConst()); |
| 1349 | 1349 | ||
| 1350 | if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) { | 1350 | if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) { |
| 1351 | %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, | 1351 | try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, |
| 1352 | self.name_only_filename); | 1352 | self.name_only_filename); |
| 1353 | } | 1353 | } |
| 1354 | } | 1354 | } |
| ... | @@ -1423,7 +1423,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1423,7 +1423,7 @@ pub const LibExeObjStep = struct { |
| 1423 | 1423 | ||
| 1424 | self.appendCompileFlags(&cc_args); | 1424 | self.appendCompileFlags(&cc_args); |
| 1425 | 1425 | ||
| 1426 | %return builder.spawnChild(cc_args.toSliceConst()); | 1426 | try builder.spawnChild(cc_args.toSliceConst()); |
| 1427 | }, | 1427 | }, |
| 1428 | Kind.Lib => { | 1428 | Kind.Lib => { |
| 1429 | for (self.source_files.toSliceConst()) |source_file| { | 1429 | for (self.source_files.toSliceConst()) |source_file| { |
| ... | @@ -1440,14 +1440,14 @@ pub const LibExeObjStep = struct { | ... | @@ -1440,14 +1440,14 @@ pub const LibExeObjStep = struct { |
| 1440 | 1440 | ||
| 1441 | const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, source_file); | 1441 | const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, source_file); |
| 1442 | const cache_o_dir = os.path.dirname(cache_o_src); | 1442 | const cache_o_dir = os.path.dirname(cache_o_src); |
| 1443 | %return builder.makePath(cache_o_dir); | 1443 | try builder.makePath(cache_o_dir); |
| 1444 | const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); | 1444 | const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); |
| 1445 | %%cc_args.append("-o"); | 1445 | %%cc_args.append("-o"); |
| 1446 | %%cc_args.append(builder.pathFromRoot(cache_o_file)); | 1446 | %%cc_args.append(builder.pathFromRoot(cache_o_file)); |
| 1447 | 1447 | ||
| 1448 | self.appendCompileFlags(&cc_args); | 1448 | self.appendCompileFlags(&cc_args); |
| 1449 | 1449 | ||
| 1450 | %return builder.spawnChild(cc_args.toSliceConst()); | 1450 | try builder.spawnChild(cc_args.toSliceConst()); |
| 1451 | 1451 | ||
| 1452 | %%self.object_files.append(cache_o_file); | 1452 | %%self.object_files.append(cache_o_file); |
| 1453 | } | 1453 | } |
| ... | @@ -1466,14 +1466,14 @@ pub const LibExeObjStep = struct { | ... | @@ -1466,14 +1466,14 @@ pub const LibExeObjStep = struct { |
| 1466 | %%cc_args.append(builder.pathFromRoot(object_file)); | 1466 | %%cc_args.append(builder.pathFromRoot(object_file)); |
| 1467 | } | 1467 | } |
| 1468 | 1468 | ||
| 1469 | %return builder.spawnChild(cc_args.toSliceConst()); | 1469 | try builder.spawnChild(cc_args.toSliceConst()); |
| 1470 | 1470 | ||
| 1471 | // ranlib | 1471 | // ranlib |
| 1472 | %%cc_args.resize(0); | 1472 | %%cc_args.resize(0); |
| 1473 | %%cc_args.append("ranlib"); | 1473 | %%cc_args.append("ranlib"); |
| 1474 | %%cc_args.append(output_path); | 1474 | %%cc_args.append(output_path); |
| 1475 | 1475 | ||
| 1476 | %return builder.spawnChild(cc_args.toSliceConst()); | 1476 | try builder.spawnChild(cc_args.toSliceConst()); |
| 1477 | } else { | 1477 | } else { |
| 1478 | %%cc_args.resize(0); | 1478 | %%cc_args.resize(0); |
| 1479 | %%cc_args.append(cc); | 1479 | %%cc_args.append(cc); |
| ... | @@ -1537,10 +1537,10 @@ pub const LibExeObjStep = struct { | ... | @@ -1537,10 +1537,10 @@ pub const LibExeObjStep = struct { |
| 1537 | } | 1537 | } |
| 1538 | } | 1538 | } |
| 1539 | 1539 | ||
| 1540 | %return builder.spawnChild(cc_args.toSliceConst()); | 1540 | try builder.spawnChild(cc_args.toSliceConst()); |
| 1541 | 1541 | ||
| 1542 | if (self.target.wantSharedLibSymLinks()) { | 1542 | if (self.target.wantSharedLibSymLinks()) { |
| 1543 | %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, | 1543 | try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, |
| 1544 | self.name_only_filename); | 1544 | self.name_only_filename); |
| 1545 | } | 1545 | } |
| 1546 | } | 1546 | } |
| ... | @@ -1556,7 +1556,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1556,7 +1556,7 @@ pub const LibExeObjStep = struct { |
| 1556 | 1556 | ||
| 1557 | const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, source_file); | 1557 | const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, source_file); |
| 1558 | const cache_o_dir = os.path.dirname(cache_o_src); | 1558 | const cache_o_dir = os.path.dirname(cache_o_src); |
| 1559 | %return builder.makePath(cache_o_dir); | 1559 | try builder.makePath(cache_o_dir); |
| 1560 | const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); | 1560 | const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); |
| 1561 | %%cc_args.append("-o"); | 1561 | %%cc_args.append("-o"); |
| 1562 | %%cc_args.append(builder.pathFromRoot(cache_o_file)); | 1562 | %%cc_args.append(builder.pathFromRoot(cache_o_file)); |
| ... | @@ -1570,7 +1570,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1570,7 +1570,7 @@ pub const LibExeObjStep = struct { |
| 1570 | %%cc_args.append(builder.pathFromRoot(dir)); | 1570 | %%cc_args.append(builder.pathFromRoot(dir)); |
| 1571 | } | 1571 | } |
| 1572 | 1572 | ||
| 1573 | %return builder.spawnChild(cc_args.toSliceConst()); | 1573 | try builder.spawnChild(cc_args.toSliceConst()); |
| 1574 | 1574 | ||
| 1575 | %%self.object_files.append(cache_o_file); | 1575 | %%self.object_files.append(cache_o_file); |
| 1576 | } | 1576 | } |
| ... | @@ -1619,7 +1619,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1619,7 +1619,7 @@ pub const LibExeObjStep = struct { |
| 1619 | } | 1619 | } |
| 1620 | } | 1620 | } |
| 1621 | 1621 | ||
| 1622 | %return builder.spawnChild(cc_args.toSliceConst()); | 1622 | try builder.spawnChild(cc_args.toSliceConst()); |
| 1623 | }, | 1623 | }, |
| 1624 | } | 1624 | } |
| 1625 | } | 1625 | } |
| ... | @@ -1770,7 +1770,7 @@ pub const TestStep = struct { | ... | @@ -1770,7 +1770,7 @@ pub const TestStep = struct { |
| 1770 | %%zig_args.append(lib_path); | 1770 | %%zig_args.append(lib_path); |
| 1771 | } | 1771 | } |
| 1772 | 1772 | ||
| 1773 | %return builder.spawnChild(zig_args.toSliceConst()); | 1773 | try builder.spawnChild(zig_args.toSliceConst()); |
| 1774 | } | 1774 | } |
| 1775 | }; | 1775 | }; |
| 1776 | 1776 | ||
| ... | @@ -1847,9 +1847,9 @@ const InstallArtifactStep = struct { | ... | @@ -1847,9 +1847,9 @@ const InstallArtifactStep = struct { |
| 1847 | LibExeObjStep.Kind.Exe => usize(0o755), | 1847 | LibExeObjStep.Kind.Exe => usize(0o755), |
| 1848 | LibExeObjStep.Kind.Lib => if (self.artifact.static) usize(0o666) else usize(0o755), | 1848 | LibExeObjStep.Kind.Lib => if (self.artifact.static) usize(0o666) else usize(0o755), |
| 1849 | }; | 1849 | }; |
| 1850 | %return builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode); | 1850 | try builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode); |
| 1851 | if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) { | 1851 | if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) { |
| 1852 | %return doAtomicSymLinks(builder.allocator, self.dest_file, | 1852 | try doAtomicSymLinks(builder.allocator, self.dest_file, |
| 1853 | self.artifact.major_only_filename, self.artifact.name_only_filename); | 1853 | self.artifact.major_only_filename, self.artifact.name_only_filename); |
| 1854 | } | 1854 | } |
| 1855 | } | 1855 | } |
| ... | @@ -1872,7 +1872,7 @@ pub const InstallFileStep = struct { | ... | @@ -1872,7 +1872,7 @@ pub const InstallFileStep = struct { |
| 1872 | 1872 | ||
| 1873 | fn make(step: &Step) -> %void { | 1873 | fn make(step: &Step) -> %void { |
| 1874 | const self = @fieldParentPtr(InstallFileStep, "step", step); | 1874 | const self = @fieldParentPtr(InstallFileStep, "step", step); |
| 1875 | %return self.builder.copyFile(self.src_path, self.dest_path); | 1875 | try self.builder.copyFile(self.src_path, self.dest_path); |
| 1876 | } | 1876 | } |
| 1877 | }; | 1877 | }; |
| 1878 | 1878 | ||
| ... | @@ -1895,11 +1895,11 @@ pub const WriteFileStep = struct { | ... | @@ -1895,11 +1895,11 @@ pub const WriteFileStep = struct { |
| 1895 | const self = @fieldParentPtr(WriteFileStep, "step", step); | 1895 | const self = @fieldParentPtr(WriteFileStep, "step", step); |
| 1896 | const full_path = self.builder.pathFromRoot(self.file_path); | 1896 | const full_path = self.builder.pathFromRoot(self.file_path); |
| 1897 | const full_path_dir = os.path.dirname(full_path); | 1897 | const full_path_dir = os.path.dirname(full_path); |
| 1898 | os.makePath(self.builder.allocator, full_path_dir) %% |err| { | 1898 | os.makePath(self.builder.allocator, full_path_dir) catch |err| { |
| 1899 | warn("unable to make path {}: {}\n", full_path_dir, @errorName(err)); | 1899 | warn("unable to make path {}: {}\n", full_path_dir, @errorName(err)); |
| 1900 | return err; | 1900 | return err; |
| 1901 | }; | 1901 | }; |
| 1902 | io.writeFile(full_path, self.data, self.builder.allocator) %% |err| { | 1902 | io.writeFile(full_path, self.data, self.builder.allocator) catch |err| { |
| 1903 | warn("unable to write {}: {}\n", full_path, @errorName(err)); | 1903 | warn("unable to write {}: {}\n", full_path, @errorName(err)); |
| 1904 | return err; | 1904 | return err; |
| 1905 | }; | 1905 | }; |
| ... | @@ -1942,7 +1942,7 @@ pub const RemoveDirStep = struct { | ... | @@ -1942,7 +1942,7 @@ pub const RemoveDirStep = struct { |
| 1942 | const self = @fieldParentPtr(RemoveDirStep, "step", step); | 1942 | const self = @fieldParentPtr(RemoveDirStep, "step", step); |
| 1943 | 1943 | ||
| 1944 | const full_path = self.builder.pathFromRoot(self.dir_path); | 1944 | const full_path = self.builder.pathFromRoot(self.dir_path); |
| 1945 | os.deleteTree(self.builder.allocator, full_path) %% |err| { | 1945 | os.deleteTree(self.builder.allocator, full_path) catch |err| { |
| 1946 | warn("Unable to remove {}: {}\n", full_path, @errorName(err)); | 1946 | warn("Unable to remove {}: {}\n", full_path, @errorName(err)); |
| 1947 | return err; | 1947 | return err; |
| 1948 | }; | 1948 | }; |
| ... | @@ -1973,7 +1973,7 @@ pub const Step = struct { | ... | @@ -1973,7 +1973,7 @@ pub const Step = struct { |
| 1973 | if (self.done_flag) | 1973 | if (self.done_flag) |
| 1974 | return; | 1974 | return; |
| 1975 | 1975 | ||
| 1976 | %return self.makeFn(self); | 1976 | try self.makeFn(self); |
| 1977 | self.done_flag = true; | 1977 | self.done_flag = true; |
| 1978 | } | 1978 | } |
| 1979 | 1979 | ||
| ... | @@ -1991,13 +1991,13 @@ fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_maj | ... | @@ -1991,13 +1991,13 @@ fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_maj |
| 1991 | const out_basename = os.path.basename(output_path); | 1991 | const out_basename = os.path.basename(output_path); |
| 1992 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | 1992 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 |
| 1993 | const major_only_path = %%os.path.join(allocator, out_dir, filename_major_only); | 1993 | const major_only_path = %%os.path.join(allocator, out_dir, filename_major_only); |
| 1994 | os.atomicSymLink(allocator, out_basename, major_only_path) %% |err| { | 1994 | os.atomicSymLink(allocator, out_basename, major_only_path) catch |err| { |
| 1995 | warn("Unable to symlink {} -> {}\n", major_only_path, out_basename); | 1995 | warn("Unable to symlink {} -> {}\n", major_only_path, out_basename); |
| 1996 | return err; | 1996 | return err; |
| 1997 | }; | 1997 | }; |
| 1998 | // sym link for libfoo.so to libfoo.so.1 | 1998 | // sym link for libfoo.so to libfoo.so.1 |
| 1999 | const name_only_path = %%os.path.join(allocator, out_dir, filename_name_only); | 1999 | const name_only_path = %%os.path.join(allocator, out_dir, filename_name_only); |
| 2000 | os.atomicSymLink(allocator, filename_major_only, name_only_path) %% |err| { | 2000 | os.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| { |
| 2001 | warn("Unable to symlink {} -> {}\n", name_only_path, filename_major_only); | 2001 | warn("Unable to symlink {} -> {}\n", name_only_path, filename_major_only); |
| 2002 | return err; | 2002 | return err; |
| 2003 | }; | 2003 | }; |
std/c/index.zig+1-1| ... | @@ -4,7 +4,7 @@ const Os = builtin.Os; | ... | @@ -4,7 +4,7 @@ const Os = builtin.Os; |
| 4 | pub use switch(builtin.os) { | 4 | pub use switch(builtin.os) { |
| 5 | Os.linux => @import("linux.zig"), | 5 | Os.linux => @import("linux.zig"), |
| 6 | Os.windows => @import("windows.zig"), | 6 | Os.windows => @import("windows.zig"), |
| 7 | Os.darwin, Os.macosx, Os.ios => @import("darwin.zig"), | 7 | Os.macosx, Os.ios => @import("darwin.zig"), |
| 8 | else => empty_import, | 8 | else => empty_import, |
| 9 | }; | 9 | }; |
| 10 | const empty_import = @import("../empty.zig"); | 10 | const empty_import = @import("../empty.zig"); |
std/cstr.zig+2-2| ... | @@ -43,7 +43,7 @@ fn testCStrFnsImpl() { | ... | @@ -43,7 +43,7 @@ fn testCStrFnsImpl() { |
| 43 | /// have a null byte after it. | 43 | /// have a null byte after it. |
| 44 | /// Caller owns the returned memory. | 44 | /// Caller owns the returned memory. |
| 45 | pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 { | 45 | pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 { |
| 46 | const result = %return allocator.alloc(u8, slice.len + 1); | 46 | const result = try allocator.alloc(u8, slice.len + 1); |
| 47 | mem.copy(u8, result, slice); | 47 | mem.copy(u8, result, slice); |
| 48 | result[slice.len] = 0; | 48 | result[slice.len] = 0; |
| 49 | return result; | 49 | return result; |
| ... | @@ -70,7 +70,7 @@ pub const NullTerminated2DArray = struct { | ... | @@ -70,7 +70,7 @@ pub const NullTerminated2DArray = struct { |
| 70 | const index_size = @sizeOf(usize) * new_len; // size of the ptrs | 70 | const index_size = @sizeOf(usize) * new_len; // size of the ptrs |
| 71 | byte_count += index_size; | 71 | byte_count += index_size; |
| 72 | 72 | ||
| 73 | const buf = %return allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count); | 73 | const buf = try allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count); |
| 74 | %defer allocator.free(buf); | 74 | %defer allocator.free(buf); |
| 75 | 75 | ||
| 76 | var write_index = index_size; | 76 | var write_index = index_size; |
std/debug/failing_allocator.zig+2-2| ... | @@ -33,7 +33,7 @@ pub const FailingAllocator = struct { | ... | @@ -33,7 +33,7 @@ pub const FailingAllocator = struct { |
| 33 | if (self.index == self.fail_index) { | 33 | if (self.index == self.fail_index) { |
| 34 | return error.OutOfMemory; | 34 | return error.OutOfMemory; |
| 35 | } | 35 | } |
| 36 | const result = %return self.internal_allocator.allocFn(self.internal_allocator, n, alignment); | 36 | const result = try self.internal_allocator.allocFn(self.internal_allocator, n, alignment); |
| 37 | self.allocated_bytes += result.len; | 37 | self.allocated_bytes += result.len; |
| 38 | self.index += 1; | 38 | self.index += 1; |
| 39 | return result; | 39 | return result; |
| ... | @@ -48,7 +48,7 @@ pub const FailingAllocator = struct { | ... | @@ -48,7 +48,7 @@ pub const FailingAllocator = struct { |
| 48 | if (self.index == self.fail_index) { | 48 | if (self.index == self.fail_index) { |
| 49 | return error.OutOfMemory; | 49 | return error.OutOfMemory; |
| 50 | } | 50 | } |
| 51 | const result = %return self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment); | 51 | const result = try self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment); |
| 52 | self.allocated_bytes += new_size - old_mem.len; | 52 | self.allocated_bytes += new_size - old_mem.len; |
| 53 | self.deallocations += 1; | 53 | self.deallocations += 1; |
| 54 | self.index += 1; | 54 | self.index += 1; |
std/debug/index.zig+133-133| ... | @@ -22,14 +22,14 @@ var stderr_file: io.File = undefined; | ... | @@ -22,14 +22,14 @@ var stderr_file: io.File = undefined; |
| 22 | var stderr_file_out_stream: io.FileOutStream = undefined; | 22 | var stderr_file_out_stream: io.FileOutStream = undefined; |
| 23 | var stderr_stream: ?&io.OutStream = null; | 23 | var stderr_stream: ?&io.OutStream = null; |
| 24 | pub fn warn(comptime fmt: []const u8, args: ...) { | 24 | pub fn warn(comptime fmt: []const u8, args: ...) { |
| 25 | const stderr = getStderrStream() %% return; | 25 | const stderr = getStderrStream() catch return; |
| 26 | stderr.print(fmt, args) %% return; | 26 | stderr.print(fmt, args) catch return; |
| 27 | } | 27 | } |
| 28 | fn getStderrStream() -> %&io.OutStream { | 28 | fn getStderrStream() -> %&io.OutStream { |
| 29 | if (stderr_stream) |st| { | 29 | if (stderr_stream) |st| { |
| 30 | return st; | 30 | return st; |
| 31 | } else { | 31 | } else { |
| 32 | stderr_file = %return io.getStdErr(); | 32 | stderr_file = try io.getStdErr(); |
| 33 | stderr_file_out_stream = io.FileOutStream.init(&stderr_file); | 33 | stderr_file_out_stream = io.FileOutStream.init(&stderr_file); |
| 34 | const st = &stderr_file_out_stream.stream; | 34 | const st = &stderr_file_out_stream.stream; |
| 35 | stderr_stream = st; | 35 | stderr_stream = st; |
| ... | @@ -39,8 +39,8 @@ fn getStderrStream() -> %&io.OutStream { | ... | @@ -39,8 +39,8 @@ fn getStderrStream() -> %&io.OutStream { |
| 39 | 39 | ||
| 40 | /// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned. | 40 | /// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned. |
| 41 | pub fn dumpStackTrace() { | 41 | pub fn dumpStackTrace() { |
| 42 | const stderr = getStderrStream() %% return; | 42 | const stderr = getStderrStream() catch return; |
| 43 | writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) %% return; | 43 | writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) catch return; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | /// This function invokes undefined behavior when `ok` is `false`. | 46 | /// This function invokes undefined behavior when `ok` is `false`. |
| ... | @@ -86,9 +86,9 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn { | ... | @@ -86,9 +86,9 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn { |
| 86 | panicking = true; | 86 | panicking = true; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | const stderr = getStderrStream() %% os.abort(); | 89 | const stderr = getStderrStream() catch os.abort(); |
| 90 | stderr.print(format ++ "\n", args) %% os.abort(); | 90 | stderr.print(format ++ "\n", args) catch os.abort(); |
| 91 | writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) %% os.abort(); | 91 | writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) catch os.abort(); |
| 92 | 92 | ||
| 93 | os.abort(); | 93 | os.abort(); |
| 94 | } | 94 | } |
| ... | @@ -118,18 +118,18 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty | ... | @@ -118,18 +118,18 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty |
| 118 | .compile_unit_list = ArrayList(CompileUnit).init(allocator), | 118 | .compile_unit_list = ArrayList(CompileUnit).init(allocator), |
| 119 | }; | 119 | }; |
| 120 | const st = &stack_trace; | 120 | const st = &stack_trace; |
| 121 | st.self_exe_file = %return os.openSelfExe(); | 121 | st.self_exe_file = try os.openSelfExe(); |
| 122 | defer st.self_exe_file.close(); | 122 | defer st.self_exe_file.close(); |
| 123 | 123 | ||
| 124 | %return st.elf.openFile(allocator, &st.self_exe_file); | 124 | try st.elf.openFile(allocator, &st.self_exe_file); |
| 125 | defer st.elf.close(); | 125 | defer st.elf.close(); |
| 126 | 126 | ||
| 127 | st.debug_info = (%return st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo; | 127 | st.debug_info = (try st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo; |
| 128 | st.debug_abbrev = (%return st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo; | 128 | st.debug_abbrev = (try st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo; |
| 129 | st.debug_str = (%return st.elf.findSection(".debug_str")) ?? return error.MissingDebugInfo; | 129 | st.debug_str = (try st.elf.findSection(".debug_str")) ?? return error.MissingDebugInfo; |
| 130 | st.debug_line = (%return st.elf.findSection(".debug_line")) ?? return error.MissingDebugInfo; | 130 | st.debug_line = (try st.elf.findSection(".debug_line")) ?? return error.MissingDebugInfo; |
| 131 | st.debug_ranges = (%return st.elf.findSection(".debug_ranges")); | 131 | st.debug_ranges = (try st.elf.findSection(".debug_ranges")); |
| 132 | %return scanAllCompileUnits(st); | 132 | try scanAllCompileUnits(st); |
| 133 | 133 | ||
| 134 | var ignored_count: usize = 0; | 134 | var ignored_count: usize = 0; |
| 135 | 135 | ||
| ... | @@ -146,26 +146,26 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty | ... | @@ -146,26 +146,26 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty |
| 146 | // at compile time. I'll call it issue #313 | 146 | // at compile time. I'll call it issue #313 |
| 147 | const ptr_hex = if (@sizeOf(usize) == 4) "0x{x8}" else "0x{x16}"; | 147 | const ptr_hex = if (@sizeOf(usize) == 4) "0x{x8}" else "0x{x16}"; |
| 148 | 148 | ||
| 149 | const compile_unit = findCompileUnit(st, return_address) %% { | 149 | const compile_unit = findCompileUnit(st, return_address) catch { |
| 150 | %return out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", | 150 | try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", |
| 151 | return_address); | 151 | return_address); |
| 152 | continue; | 152 | continue; |
| 153 | }; | 153 | }; |
| 154 | const compile_unit_name = %return compile_unit.die.getAttrString(st, DW.AT_name); | 154 | const compile_unit_name = try compile_unit.die.getAttrString(st, DW.AT_name); |
| 155 | if (getLineNumberInfo(st, compile_unit, usize(return_address) - 1)) |line_info| { | 155 | if (getLineNumberInfo(st, compile_unit, usize(return_address) - 1)) |line_info| { |
| 156 | defer line_info.deinit(); | 156 | defer line_info.deinit(); |
| 157 | %return out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ | 157 | try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ |
| 158 | DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", | 158 | DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", |
| 159 | line_info.file_name, line_info.line, line_info.column, | 159 | line_info.file_name, line_info.line, line_info.column, |
| 160 | return_address, compile_unit_name); | 160 | return_address, compile_unit_name); |
| 161 | if (printLineFromFile(st.allocator(), out_stream, line_info)) { | 161 | if (printLineFromFile(st.allocator(), out_stream, line_info)) { |
| 162 | if (line_info.column == 0) { | 162 | if (line_info.column == 0) { |
| 163 | %return out_stream.write("\n"); | 163 | try out_stream.write("\n"); |
| 164 | } else { | 164 | } else { |
| 165 | {var col_i: usize = 1; while (col_i < line_info.column) : (col_i += 1) { | 165 | {var col_i: usize = 1; while (col_i < line_info.column) : (col_i += 1) { |
| 166 | %return out_stream.writeByte(' '); | 166 | try out_stream.writeByte(' '); |
| 167 | }} | 167 | }} |
| 168 | %return out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); | 168 | try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); |
| 169 | } | 169 | } |
| 170 | } else |err| switch (err) { | 170 | } else |err| switch (err) { |
| 171 | error.EndOfFile, error.PathNotFound => {}, | 171 | error.EndOfFile, error.PathNotFound => {}, |
| ... | @@ -173,7 +173,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty | ... | @@ -173,7 +173,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty |
| 173 | } | 173 | } |
| 174 | } else |err| switch (err) { | 174 | } else |err| switch (err) { |
| 175 | error.MissingDebugInfo, error.InvalidDebugInfo => { | 175 | error.MissingDebugInfo, error.InvalidDebugInfo => { |
| 176 | %return out_stream.print(ptr_hex ++ " in ??? ({})\n", | 176 | try out_stream.print(ptr_hex ++ " in ??? ({})\n", |
| 177 | return_address, compile_unit_name); | 177 | return_address, compile_unit_name); |
| 178 | }, | 178 | }, |
| 179 | else => return err, | 179 | else => return err, |
| ... | @@ -181,22 +181,22 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty | ... | @@ -181,22 +181,22 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty |
| 181 | } | 181 | } |
| 182 | }, | 182 | }, |
| 183 | builtin.ObjectFormat.coff => { | 183 | builtin.ObjectFormat.coff => { |
| 184 | %return out_stream.write("(stack trace unavailable for COFF object format)\n"); | 184 | try out_stream.write("(stack trace unavailable for COFF object format)\n"); |
| 185 | }, | 185 | }, |
| 186 | builtin.ObjectFormat.macho => { | 186 | builtin.ObjectFormat.macho => { |
| 187 | %return out_stream.write("(stack trace unavailable for Mach-O object format)\n"); | 187 | try out_stream.write("(stack trace unavailable for Mach-O object format)\n"); |
| 188 | }, | 188 | }, |
| 189 | builtin.ObjectFormat.wasm => { | 189 | builtin.ObjectFormat.wasm => { |
| 190 | %return out_stream.write("(stack trace unavailable for WASM object format)\n"); | 190 | try out_stream.write("(stack trace unavailable for WASM object format)\n"); |
| 191 | }, | 191 | }, |
| 192 | builtin.ObjectFormat.unknown => { | 192 | builtin.ObjectFormat.unknown => { |
| 193 | %return out_stream.write("(stack trace unavailable for unknown object format)\n"); | 193 | try out_stream.write("(stack trace unavailable for unknown object format)\n"); |
| 194 | }, | 194 | }, |
| 195 | } | 195 | } |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) -> %void { | 198 | fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) -> %void { |
| 199 | var f = %return io.File.openRead(line_info.file_name, allocator); | 199 | var f = try io.File.openRead(line_info.file_name, allocator); |
| 200 | defer f.close(); | 200 | defer f.close(); |
| 201 | // TODO fstat and make sure that the file has the correct size | 201 | // TODO fstat and make sure that the file has the correct size |
| 202 | 202 | ||
| ... | @@ -205,12 +205,12 @@ fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_ | ... | @@ -205,12 +205,12 @@ fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_ |
| 205 | var column: usize = 1; | 205 | var column: usize = 1; |
| 206 | var abs_index: usize = 0; | 206 | var abs_index: usize = 0; |
| 207 | while (true) { | 207 | while (true) { |
| 208 | const amt_read = %return f.read(buf[0..]); | 208 | const amt_read = try f.read(buf[0..]); |
| 209 | const slice = buf[0..amt_read]; | 209 | const slice = buf[0..amt_read]; |
| 210 | 210 | ||
| 211 | for (slice) |byte| { | 211 | for (slice) |byte| { |
| 212 | if (line == line_info.line) { | 212 | if (line == line_info.line) { |
| 213 | %return out_stream.writeByte(byte); | 213 | try out_stream.writeByte(byte); |
| 214 | if (byte == '\n') { | 214 | if (byte == '\n') { |
| 215 | return; | 215 | return; |
| 216 | } | 216 | } |
| ... | @@ -437,7 +437,7 @@ const LineNumberProgram = struct { | ... | @@ -437,7 +437,7 @@ const LineNumberProgram = struct { |
| 437 | const dir_name = if (file_entry.dir_index >= self.include_dirs.len) { | 437 | const dir_name = if (file_entry.dir_index >= self.include_dirs.len) { |
| 438 | return error.InvalidDebugInfo; | 438 | return error.InvalidDebugInfo; |
| 439 | } else self.include_dirs[file_entry.dir_index]; | 439 | } else self.include_dirs[file_entry.dir_index]; |
| 440 | const file_name = %return os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name); | 440 | const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name); |
| 441 | %defer self.file_entries.allocator.free(file_name); | 441 | %defer self.file_entries.allocator.free(file_name); |
| 442 | return LineInfo { | 442 | return LineInfo { |
| 443 | .line = if (self.prev_line >= 0) usize(self.prev_line) else 0, | 443 | .line = if (self.prev_line >= 0) usize(self.prev_line) else 0, |
| ... | @@ -461,73 +461,73 @@ const LineNumberProgram = struct { | ... | @@ -461,73 +461,73 @@ const LineNumberProgram = struct { |
| 461 | fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 { | 461 | fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 { |
| 462 | var buf = ArrayList(u8).init(allocator); | 462 | var buf = ArrayList(u8).init(allocator); |
| 463 | while (true) { | 463 | while (true) { |
| 464 | const byte = %return in_stream.readByte(); | 464 | const byte = try in_stream.readByte(); |
| 465 | if (byte == 0) | 465 | if (byte == 0) |
| 466 | break; | 466 | break; |
| 467 | %return buf.append(byte); | 467 | try buf.append(byte); |
| 468 | } | 468 | } |
| 469 | return buf.toSlice(); | 469 | return buf.toSlice(); |
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | fn getString(st: &ElfStackTrace, offset: u64) -> %[]u8 { | 472 | fn getString(st: &ElfStackTrace, offset: u64) -> %[]u8 { |
| 473 | const pos = st.debug_str.offset + offset; | 473 | const pos = st.debug_str.offset + offset; |
| 474 | %return st.self_exe_file.seekTo(pos); | 474 | try st.self_exe_file.seekTo(pos); |
| 475 | return st.readString(); | 475 | return st.readString(); |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %[]u8 { | 478 | fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %[]u8 { |
| 479 | const buf = %return global_allocator.alloc(u8, size); | 479 | const buf = try global_allocator.alloc(u8, size); |
| 480 | %defer global_allocator.free(buf); | 480 | %defer global_allocator.free(buf); |
| 481 | if ((%return in_stream.read(buf)) < size) return error.EndOfFile; | 481 | if ((try in_stream.read(buf)) < size) return error.EndOfFile; |
| 482 | return buf; | 482 | return buf; |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue { | 485 | fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue { |
| 486 | const buf = %return readAllocBytes(allocator, in_stream, size); | 486 | const buf = try readAllocBytes(allocator, in_stream, size); |
| 487 | return FormValue { .Block = buf }; | 487 | return FormValue { .Block = buf }; |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue { | 490 | fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue { |
| 491 | const block_len = %return in_stream.readVarInt(builtin.Endian.Little, usize, size); | 491 | const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size); |
| 492 | return parseFormValueBlockLen(allocator, in_stream, block_len); | 492 | return parseFormValueBlockLen(allocator, in_stream, block_len); |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) -> %FormValue { | 495 | fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) -> %FormValue { |
| 496 | return FormValue { .Const = Constant { | 496 | return FormValue { .Const = Constant { |
| 497 | .signed = signed, | 497 | .signed = signed, |
| 498 | .payload = %return readAllocBytes(allocator, in_stream, size), | 498 | .payload = try readAllocBytes(allocator, in_stream, size), |
| 499 | }}; | 499 | }}; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) -> %u64 { | 502 | fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) -> %u64 { |
| 503 | return if (is_64) %return in_stream.readIntLe(u64) | 503 | return if (is_64) try in_stream.readIntLe(u64) |
| 504 | else u64(%return in_stream.readIntLe(u32)) ; | 504 | else u64(try in_stream.readIntLe(u32)) ; |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 { | 507 | fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 { |
| 508 | return if (@sizeOf(usize) == 4) u64(%return in_stream.readIntLe(u32)) | 508 | return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32)) |
| 509 | else if (@sizeOf(usize) == 8) %return in_stream.readIntLe(u64) | 509 | else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64) |
| 510 | else unreachable; | 510 | else unreachable; |
| 511 | } | 511 | } |
| 512 | 512 | ||
| 513 | fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue { | 513 | fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue { |
| 514 | const buf = %return readAllocBytes(allocator, in_stream, size); | 514 | const buf = try readAllocBytes(allocator, in_stream, size); |
| 515 | return FormValue { .Ref = buf }; | 515 | return FormValue { .Ref = buf }; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) -> %FormValue { | 518 | fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) -> %FormValue { |
| 519 | const block_len = %return in_stream.readIntLe(T); | 519 | const block_len = try in_stream.readIntLe(T); |
| 520 | return parseFormValueRefLen(allocator, in_stream, block_len); | 520 | return parseFormValueRefLen(allocator, in_stream, block_len); |
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) -> %FormValue { | 523 | fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) -> %FormValue { |
| 524 | return switch (form_id) { | 524 | return switch (form_id) { |
| 525 | DW.FORM_addr => FormValue { .Address = %return parseFormValueTargetAddrSize(in_stream) }, | 525 | DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) }, |
| 526 | DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1), | 526 | DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1), |
| 527 | DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2), | 527 | DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2), |
| 528 | DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4), | 528 | DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4), |
| 529 | DW.FORM_block => x: { | 529 | DW.FORM_block => x: { |
| 530 | const block_len = %return readULeb128(in_stream); | 530 | const block_len = try readULeb128(in_stream); |
| 531 | return parseFormValueBlockLen(allocator, in_stream, block_len); | 531 | return parseFormValueBlockLen(allocator, in_stream, block_len); |
| 532 | }, | 532 | }, |
| 533 | DW.FORM_data1 => parseFormValueConstant(allocator, in_stream, false, 1), | 533 | DW.FORM_data1 => parseFormValueConstant(allocator, in_stream, false, 1), |
| ... | @@ -535,35 +535,35 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u | ... | @@ -535,35 +535,35 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u |
| 535 | DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4), | 535 | DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4), |
| 536 | DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8), | 536 | DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8), |
| 537 | DW.FORM_udata, DW.FORM_sdata => { | 537 | DW.FORM_udata, DW.FORM_sdata => { |
| 538 | const block_len = %return readULeb128(in_stream); | 538 | const block_len = try readULeb128(in_stream); |
| 539 | const signed = form_id == DW.FORM_sdata; | 539 | const signed = form_id == DW.FORM_sdata; |
| 540 | return parseFormValueConstant(allocator, in_stream, signed, block_len); | 540 | return parseFormValueConstant(allocator, in_stream, signed, block_len); |
| 541 | }, | 541 | }, |
| 542 | DW.FORM_exprloc => { | 542 | DW.FORM_exprloc => { |
| 543 | const size = %return readULeb128(in_stream); | 543 | const size = try readULeb128(in_stream); |
| 544 | const buf = %return readAllocBytes(allocator, in_stream, size); | 544 | const buf = try readAllocBytes(allocator, in_stream, size); |
| 545 | return FormValue { .ExprLoc = buf }; | 545 | return FormValue { .ExprLoc = buf }; |
| 546 | }, | 546 | }, |
| 547 | DW.FORM_flag => FormValue { .Flag = (%return in_stream.readByte()) != 0 }, | 547 | DW.FORM_flag => FormValue { .Flag = (try in_stream.readByte()) != 0 }, |
| 548 | DW.FORM_flag_present => FormValue { .Flag = true }, | 548 | DW.FORM_flag_present => FormValue { .Flag = true }, |
| 549 | DW.FORM_sec_offset => FormValue { .SecOffset = %return parseFormValueDwarfOffsetSize(in_stream, is_64) }, | 549 | DW.FORM_sec_offset => FormValue { .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, |
| 550 | 550 | ||
| 551 | DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8), | 551 | DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8), |
| 552 | DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16), | 552 | DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16), |
| 553 | DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, u32), | 553 | DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, u32), |
| 554 | DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, u64), | 554 | DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, u64), |
| 555 | DW.FORM_ref_udata => { | 555 | DW.FORM_ref_udata => { |
| 556 | const ref_len = %return readULeb128(in_stream); | 556 | const ref_len = try readULeb128(in_stream); |
| 557 | return parseFormValueRefLen(allocator, in_stream, ref_len); | 557 | return parseFormValueRefLen(allocator, in_stream, ref_len); |
| 558 | }, | 558 | }, |
| 559 | 559 | ||
| 560 | DW.FORM_ref_addr => FormValue { .RefAddr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) }, | 560 | DW.FORM_ref_addr => FormValue { .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, |
| 561 | DW.FORM_ref_sig8 => FormValue { .RefSig8 = %return in_stream.readIntLe(u64) }, | 561 | DW.FORM_ref_sig8 => FormValue { .RefSig8 = try in_stream.readIntLe(u64) }, |
| 562 | 562 | ||
| 563 | DW.FORM_string => FormValue { .String = %return readStringRaw(allocator, in_stream) }, | 563 | DW.FORM_string => FormValue { .String = try readStringRaw(allocator, in_stream) }, |
| 564 | DW.FORM_strp => FormValue { .StrPtr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) }, | 564 | DW.FORM_strp => FormValue { .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, |
| 565 | DW.FORM_indirect => { | 565 | DW.FORM_indirect => { |
| 566 | const child_form_id = %return readULeb128(in_stream); | 566 | const child_form_id = try readULeb128(in_stream); |
| 567 | return parseFormValue(allocator, in_stream, child_form_id, is_64); | 567 | return parseFormValue(allocator, in_stream, child_form_id, is_64); |
| 568 | }, | 568 | }, |
| 569 | else => error.InvalidDebugInfo, | 569 | else => error.InvalidDebugInfo, |
| ... | @@ -576,23 +576,23 @@ fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable { | ... | @@ -576,23 +576,23 @@ fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable { |
| 576 | const in_stream = &in_file_stream.stream; | 576 | const in_stream = &in_file_stream.stream; |
| 577 | var result = AbbrevTable.init(st.allocator()); | 577 | var result = AbbrevTable.init(st.allocator()); |
| 578 | while (true) { | 578 | while (true) { |
| 579 | const abbrev_code = %return readULeb128(in_stream); | 579 | const abbrev_code = try readULeb128(in_stream); |
| 580 | if (abbrev_code == 0) | 580 | if (abbrev_code == 0) |
| 581 | return result; | 581 | return result; |
| 582 | %return result.append(AbbrevTableEntry { | 582 | try result.append(AbbrevTableEntry { |
| 583 | .abbrev_code = abbrev_code, | 583 | .abbrev_code = abbrev_code, |
| 584 | .tag_id = %return readULeb128(in_stream), | 584 | .tag_id = try readULeb128(in_stream), |
| 585 | .has_children = (%return in_stream.readByte()) == DW.CHILDREN_yes, | 585 | .has_children = (try in_stream.readByte()) == DW.CHILDREN_yes, |
| 586 | .attrs = ArrayList(AbbrevAttr).init(st.allocator()), | 586 | .attrs = ArrayList(AbbrevAttr).init(st.allocator()), |
| 587 | }); | 587 | }); |
| 588 | const attrs = &result.items[result.len - 1].attrs; | 588 | const attrs = &result.items[result.len - 1].attrs; |
| 589 | 589 | ||
| 590 | while (true) { | 590 | while (true) { |
| 591 | const attr_id = %return readULeb128(in_stream); | 591 | const attr_id = try readULeb128(in_stream); |
| 592 | const form_id = %return readULeb128(in_stream); | 592 | const form_id = try readULeb128(in_stream); |
| 593 | if (attr_id == 0 and form_id == 0) | 593 | if (attr_id == 0 and form_id == 0) |
| 594 | break; | 594 | break; |
| 595 | %return attrs.append(AbbrevAttr { | 595 | try attrs.append(AbbrevAttr { |
| 596 | .attr_id = attr_id, | 596 | .attr_id = attr_id, |
| 597 | .form_id = form_id, | 597 | .form_id = form_id, |
| 598 | }); | 598 | }); |
| ... | @@ -608,10 +608,10 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable | ... | @@ -608,10 +608,10 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable |
| 608 | return &header.table; | 608 | return &header.table; |
| 609 | } | 609 | } |
| 610 | } | 610 | } |
| 611 | %return st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset); | 611 | try st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset); |
| 612 | %return st.abbrev_table_list.append(AbbrevTableHeader { | 612 | try st.abbrev_table_list.append(AbbrevTableHeader { |
| 613 | .offset = abbrev_offset, | 613 | .offset = abbrev_offset, |
| 614 | .table = %return parseAbbrevTable(st), | 614 | .table = try parseAbbrevTable(st), |
| 615 | }); | 615 | }); |
| 616 | return &st.abbrev_table_list.items[st.abbrev_table_list.len - 1].table; | 616 | return &st.abbrev_table_list.items[st.abbrev_table_list.len - 1].table; |
| 617 | } | 617 | } |
| ... | @@ -628,7 +628,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) - | ... | @@ -628,7 +628,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) - |
| 628 | const in_file = &st.self_exe_file; | 628 | const in_file = &st.self_exe_file; |
| 629 | var in_file_stream = io.FileInStream.init(in_file); | 629 | var in_file_stream = io.FileInStream.init(in_file); |
| 630 | const in_stream = &in_file_stream.stream; | 630 | const in_stream = &in_file_stream.stream; |
| 631 | const abbrev_code = %return readULeb128(in_stream); | 631 | const abbrev_code = try readULeb128(in_stream); |
| 632 | const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) ?? return error.InvalidDebugInfo; | 632 | const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) ?? return error.InvalidDebugInfo; |
| 633 | 633 | ||
| 634 | var result = Die { | 634 | var result = Die { |
| ... | @@ -636,18 +636,18 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) - | ... | @@ -636,18 +636,18 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) - |
| 636 | .has_children = table_entry.has_children, | 636 | .has_children = table_entry.has_children, |
| 637 | .attrs = ArrayList(Die.Attr).init(st.allocator()), | 637 | .attrs = ArrayList(Die.Attr).init(st.allocator()), |
| 638 | }; | 638 | }; |
| 639 | %return result.attrs.resize(table_entry.attrs.len); | 639 | try result.attrs.resize(table_entry.attrs.len); |
| 640 | for (table_entry.attrs.toSliceConst()) |attr, i| { | 640 | for (table_entry.attrs.toSliceConst()) |attr, i| { |
| 641 | result.attrs.items[i] = Die.Attr { | 641 | result.attrs.items[i] = Die.Attr { |
| 642 | .id = attr.attr_id, | 642 | .id = attr.attr_id, |
| 643 | .value = %return parseFormValue(st.allocator(), in_stream, attr.form_id, is_64), | 643 | .value = try parseFormValue(st.allocator(), in_stream, attr.form_id, is_64), |
| 644 | }; | 644 | }; |
| 645 | } | 645 | } |
| 646 | return result; | 646 | return result; |
| 647 | } | 647 | } |
| 648 | 648 | ||
| 649 | fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) -> %LineInfo { | 649 | fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) -> %LineInfo { |
| 650 | const compile_unit_cwd = %return compile_unit.die.getAttrString(st, DW.AT_comp_dir); | 650 | const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir); |
| 651 | 651 | ||
| 652 | const in_file = &st.self_exe_file; | 652 | const in_file = &st.self_exe_file; |
| 653 | const debug_line_end = st.debug_line.offset + st.debug_line.size; | 653 | const debug_line_end = st.debug_line.offset + st.debug_line.size; |
| ... | @@ -658,10 +658,10 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe | ... | @@ -658,10 +658,10 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 658 | const in_stream = &in_file_stream.stream; | 658 | const in_stream = &in_file_stream.stream; |
| 659 | 659 | ||
| 660 | while (this_offset < debug_line_end) : (this_index += 1) { | 660 | while (this_offset < debug_line_end) : (this_index += 1) { |
| 661 | %return in_file.seekTo(this_offset); | 661 | try in_file.seekTo(this_offset); |
| 662 | 662 | ||
| 663 | var is_64: bool = undefined; | 663 | var is_64: bool = undefined; |
| 664 | const unit_length = %return readInitialLength(in_stream, &is_64); | 664 | const unit_length = try readInitialLength(in_stream, &is_64); |
| 665 | if (unit_length == 0) | 665 | if (unit_length == 0) |
| 666 | return error.MissingDebugInfo; | 666 | return error.MissingDebugInfo; |
| 667 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); | 667 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); |
| ... | @@ -671,37 +671,37 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe | ... | @@ -671,37 +671,37 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 671 | continue; | 671 | continue; |
| 672 | } | 672 | } |
| 673 | 673 | ||
| 674 | const version = %return in_stream.readInt(st.elf.endian, u16); | 674 | const version = try in_stream.readInt(st.elf.endian, u16); |
| 675 | if (version != 2) return error.InvalidDebugInfo; | 675 | if (version != 2) return error.InvalidDebugInfo; |
| 676 | 676 | ||
| 677 | const prologue_length = %return in_stream.readInt(st.elf.endian, u32); | 677 | const prologue_length = try in_stream.readInt(st.elf.endian, u32); |
| 678 | const prog_start_offset = (%return in_file.getPos()) + prologue_length; | 678 | const prog_start_offset = (try in_file.getPos()) + prologue_length; |
| 679 | 679 | ||
| 680 | const minimum_instruction_length = %return in_stream.readByte(); | 680 | const minimum_instruction_length = try in_stream.readByte(); |
| 681 | if (minimum_instruction_length == 0) return error.InvalidDebugInfo; | 681 | if (minimum_instruction_length == 0) return error.InvalidDebugInfo; |
| 682 | 682 | ||
| 683 | const default_is_stmt = (%return in_stream.readByte()) != 0; | 683 | const default_is_stmt = (try in_stream.readByte()) != 0; |
| 684 | const line_base = %return in_stream.readByteSigned(); | 684 | const line_base = try in_stream.readByteSigned(); |
| 685 | 685 | ||
| 686 | const line_range = %return in_stream.readByte(); | 686 | const line_range = try in_stream.readByte(); |
| 687 | if (line_range == 0) | 687 | if (line_range == 0) |
| 688 | return error.InvalidDebugInfo; | 688 | return error.InvalidDebugInfo; |
| 689 | 689 | ||
| 690 | const opcode_base = %return in_stream.readByte(); | 690 | const opcode_base = try in_stream.readByte(); |
| 691 | 691 | ||
| 692 | const standard_opcode_lengths = %return st.allocator().alloc(u8, opcode_base - 1); | 692 | const standard_opcode_lengths = try st.allocator().alloc(u8, opcode_base - 1); |
| 693 | 693 | ||
| 694 | {var i: usize = 0; while (i < opcode_base - 1) : (i += 1) { | 694 | {var i: usize = 0; while (i < opcode_base - 1) : (i += 1) { |
| 695 | standard_opcode_lengths[i] = %return in_stream.readByte(); | 695 | standard_opcode_lengths[i] = try in_stream.readByte(); |
| 696 | }} | 696 | }} |
| 697 | 697 | ||
| 698 | var include_directories = ArrayList([]u8).init(st.allocator()); | 698 | var include_directories = ArrayList([]u8).init(st.allocator()); |
| 699 | %return include_directories.append(compile_unit_cwd); | 699 | try include_directories.append(compile_unit_cwd); |
| 700 | while (true) { | 700 | while (true) { |
| 701 | const dir = %return st.readString(); | 701 | const dir = try st.readString(); |
| 702 | if (dir.len == 0) | 702 | if (dir.len == 0) |
| 703 | break; | 703 | break; |
| 704 | %return include_directories.append(dir); | 704 | try include_directories.append(dir); |
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | var file_entries = ArrayList(FileEntry).init(st.allocator()); | 707 | var file_entries = ArrayList(FileEntry).init(st.allocator()); |
| ... | @@ -709,13 +709,13 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe | ... | @@ -709,13 +709,13 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 709 | &file_entries, target_address); | 709 | &file_entries, target_address); |
| 710 | 710 | ||
| 711 | while (true) { | 711 | while (true) { |
| 712 | const file_name = %return st.readString(); | 712 | const file_name = try st.readString(); |
| 713 | if (file_name.len == 0) | 713 | if (file_name.len == 0) |
| 714 | break; | 714 | break; |
| 715 | const dir_index = %return readULeb128(in_stream); | 715 | const dir_index = try readULeb128(in_stream); |
| 716 | const mtime = %return readULeb128(in_stream); | 716 | const mtime = try readULeb128(in_stream); |
| 717 | const len_bytes = %return readULeb128(in_stream); | 717 | const len_bytes = try readULeb128(in_stream); |
| 718 | %return file_entries.append(FileEntry { | 718 | try file_entries.append(FileEntry { |
| 719 | .file_name = file_name, | 719 | .file_name = file_name, |
| 720 | .dir_index = dir_index, | 720 | .dir_index = dir_index, |
| 721 | .mtime = mtime, | 721 | .mtime = mtime, |
| ... | @@ -723,33 +723,33 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe | ... | @@ -723,33 +723,33 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 723 | }); | 723 | }); |
| 724 | } | 724 | } |
| 725 | 725 | ||
| 726 | %return in_file.seekTo(prog_start_offset); | 726 | try in_file.seekTo(prog_start_offset); |
| 727 | 727 | ||
| 728 | while (true) { | 728 | while (true) { |
| 729 | const opcode = %return in_stream.readByte(); | 729 | const opcode = try in_stream.readByte(); |
| 730 | 730 | ||
| 731 | var sub_op: u8 = undefined; // TODO move this to the correct scope and fix the compiler crash | 731 | var sub_op: u8 = undefined; // TODO move this to the correct scope and fix the compiler crash |
| 732 | if (opcode == DW.LNS_extended_op) { | 732 | if (opcode == DW.LNS_extended_op) { |
| 733 | const op_size = %return readULeb128(in_stream); | 733 | const op_size = try readULeb128(in_stream); |
| 734 | if (op_size < 1) | 734 | if (op_size < 1) |
| 735 | return error.InvalidDebugInfo; | 735 | return error.InvalidDebugInfo; |
| 736 | sub_op = %return in_stream.readByte(); | 736 | sub_op = try in_stream.readByte(); |
| 737 | switch (sub_op) { | 737 | switch (sub_op) { |
| 738 | DW.LNE_end_sequence => { | 738 | DW.LNE_end_sequence => { |
| 739 | prog.end_sequence = true; | 739 | prog.end_sequence = true; |
| 740 | if (%return prog.checkLineMatch()) |info| return info; | 740 | if (try prog.checkLineMatch()) |info| return info; |
| 741 | return error.MissingDebugInfo; | 741 | return error.MissingDebugInfo; |
| 742 | }, | 742 | }, |
| 743 | DW.LNE_set_address => { | 743 | DW.LNE_set_address => { |
| 744 | const addr = %return in_stream.readInt(st.elf.endian, usize); | 744 | const addr = try in_stream.readInt(st.elf.endian, usize); |
| 745 | prog.address = addr; | 745 | prog.address = addr; |
| 746 | }, | 746 | }, |
| 747 | DW.LNE_define_file => { | 747 | DW.LNE_define_file => { |
| 748 | const file_name = %return st.readString(); | 748 | const file_name = try st.readString(); |
| 749 | const dir_index = %return readULeb128(in_stream); | 749 | const dir_index = try readULeb128(in_stream); |
| 750 | const mtime = %return readULeb128(in_stream); | 750 | const mtime = try readULeb128(in_stream); |
| 751 | const len_bytes = %return readULeb128(in_stream); | 751 | const len_bytes = try readULeb128(in_stream); |
| 752 | %return file_entries.append(FileEntry { | 752 | try file_entries.append(FileEntry { |
| 753 | .file_name = file_name, | 753 | .file_name = file_name, |
| 754 | .dir_index = dir_index, | 754 | .dir_index = dir_index, |
| 755 | .mtime = mtime, | 755 | .mtime = mtime, |
| ... | @@ -757,8 +757,8 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe | ... | @@ -757,8 +757,8 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 757 | }); | 757 | }); |
| 758 | }, | 758 | }, |
| 759 | else => { | 759 | else => { |
| 760 | const fwd_amt = math.cast(isize, op_size - 1) %% return error.InvalidDebugInfo; | 760 | const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo; |
| 761 | %return in_file.seekForward(fwd_amt); | 761 | try in_file.seekForward(fwd_amt); |
| 762 | }, | 762 | }, |
| 763 | } | 763 | } |
| 764 | } else if (opcode >= opcode_base) { | 764 | } else if (opcode >= opcode_base) { |
| ... | @@ -768,28 +768,28 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe | ... | @@ -768,28 +768,28 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 768 | const inc_line = i32(line_base) + i32(adjusted_opcode % line_range); | 768 | const inc_line = i32(line_base) + i32(adjusted_opcode % line_range); |
| 769 | prog.line += inc_line; | 769 | prog.line += inc_line; |
| 770 | prog.address += inc_addr; | 770 | prog.address += inc_addr; |
| 771 | if (%return prog.checkLineMatch()) |info| return info; | 771 | if (try prog.checkLineMatch()) |info| return info; |
| 772 | prog.basic_block = false; | 772 | prog.basic_block = false; |
| 773 | } else { | 773 | } else { |
| 774 | switch (opcode) { | 774 | switch (opcode) { |
| 775 | DW.LNS_copy => { | 775 | DW.LNS_copy => { |
| 776 | if (%return prog.checkLineMatch()) |info| return info; | 776 | if (try prog.checkLineMatch()) |info| return info; |
| 777 | prog.basic_block = false; | 777 | prog.basic_block = false; |
| 778 | }, | 778 | }, |
| 779 | DW.LNS_advance_pc => { | 779 | DW.LNS_advance_pc => { |
| 780 | const arg = %return readULeb128(in_stream); | 780 | const arg = try readULeb128(in_stream); |
| 781 | prog.address += arg * minimum_instruction_length; | 781 | prog.address += arg * minimum_instruction_length; |
| 782 | }, | 782 | }, |
| 783 | DW.LNS_advance_line => { | 783 | DW.LNS_advance_line => { |
| 784 | const arg = %return readILeb128(in_stream); | 784 | const arg = try readILeb128(in_stream); |
| 785 | prog.line += arg; | 785 | prog.line += arg; |
| 786 | }, | 786 | }, |
| 787 | DW.LNS_set_file => { | 787 | DW.LNS_set_file => { |
| 788 | const arg = %return readULeb128(in_stream); | 788 | const arg = try readULeb128(in_stream); |
| 789 | prog.file = arg; | 789 | prog.file = arg; |
| 790 | }, | 790 | }, |
| 791 | DW.LNS_set_column => { | 791 | DW.LNS_set_column => { |
| 792 | const arg = %return readULeb128(in_stream); | 792 | const arg = try readULeb128(in_stream); |
| 793 | prog.column = arg; | 793 | prog.column = arg; |
| 794 | }, | 794 | }, |
| 795 | DW.LNS_negate_stmt => { | 795 | DW.LNS_negate_stmt => { |
| ... | @@ -803,7 +803,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe | ... | @@ -803,7 +803,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 803 | prog.address += inc_addr; | 803 | prog.address += inc_addr; |
| 804 | }, | 804 | }, |
| 805 | DW.LNS_fixed_advance_pc => { | 805 | DW.LNS_fixed_advance_pc => { |
| 806 | const arg = %return in_stream.readInt(st.elf.endian, u16); | 806 | const arg = try in_stream.readInt(st.elf.endian, u16); |
| 807 | prog.address += arg; | 807 | prog.address += arg; |
| 808 | }, | 808 | }, |
| 809 | DW.LNS_set_prologue_end => { | 809 | DW.LNS_set_prologue_end => { |
| ... | @@ -812,7 +812,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe | ... | @@ -812,7 +812,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 812 | if (opcode - 1 >= standard_opcode_lengths.len) | 812 | if (opcode - 1 >= standard_opcode_lengths.len) |
| 813 | return error.InvalidDebugInfo; | 813 | return error.InvalidDebugInfo; |
| 814 | const len_bytes = standard_opcode_lengths[opcode - 1]; | 814 | const len_bytes = standard_opcode_lengths[opcode - 1]; |
| 815 | %return in_file.seekForward(len_bytes); | 815 | try in_file.seekForward(len_bytes); |
| 816 | }, | 816 | }, |
| 817 | } | 817 | } |
| 818 | } | 818 | } |
| ... | @@ -833,31 +833,31 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { | ... | @@ -833,31 +833,31 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { |
| 833 | const in_stream = &in_file_stream.stream; | 833 | const in_stream = &in_file_stream.stream; |
| 834 | 834 | ||
| 835 | while (this_unit_offset < debug_info_end) { | 835 | while (this_unit_offset < debug_info_end) { |
| 836 | %return st.self_exe_file.seekTo(this_unit_offset); | 836 | try st.self_exe_file.seekTo(this_unit_offset); |
| 837 | 837 | ||
| 838 | var is_64: bool = undefined; | 838 | var is_64: bool = undefined; |
| 839 | const unit_length = %return readInitialLength(in_stream, &is_64); | 839 | const unit_length = try readInitialLength(in_stream, &is_64); |
| 840 | if (unit_length == 0) | 840 | if (unit_length == 0) |
| 841 | return; | 841 | return; |
| 842 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); | 842 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); |
| 843 | 843 | ||
| 844 | const version = %return in_stream.readInt(st.elf.endian, u16); | 844 | const version = try in_stream.readInt(st.elf.endian, u16); |
| 845 | if (version < 2 or version > 5) return error.InvalidDebugInfo; | 845 | if (version < 2 or version > 5) return error.InvalidDebugInfo; |
| 846 | 846 | ||
| 847 | const debug_abbrev_offset = | 847 | const debug_abbrev_offset = |
| 848 | if (is_64) %return in_stream.readInt(st.elf.endian, u64) | 848 | if (is_64) try in_stream.readInt(st.elf.endian, u64) |
| 849 | else %return in_stream.readInt(st.elf.endian, u32); | 849 | else try in_stream.readInt(st.elf.endian, u32); |
| 850 | 850 | ||
| 851 | const address_size = %return in_stream.readByte(); | 851 | const address_size = try in_stream.readByte(); |
| 852 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; | 852 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; |
| 853 | 853 | ||
| 854 | const compile_unit_pos = %return st.self_exe_file.getPos(); | 854 | const compile_unit_pos = try st.self_exe_file.getPos(); |
| 855 | const abbrev_table = %return getAbbrevTable(st, debug_abbrev_offset); | 855 | const abbrev_table = try getAbbrevTable(st, debug_abbrev_offset); |
| 856 | 856 | ||
| 857 | %return st.self_exe_file.seekTo(compile_unit_pos); | 857 | try st.self_exe_file.seekTo(compile_unit_pos); |
| 858 | 858 | ||
| 859 | const compile_unit_die = %return st.allocator().create(Die); | 859 | const compile_unit_die = try st.allocator().create(Die); |
| 860 | *compile_unit_die = %return parseDie(st, abbrev_table, is_64); | 860 | *compile_unit_die = try parseDie(st, abbrev_table, is_64); |
| 861 | 861 | ||
| 862 | if (compile_unit_die.tag_id != DW.TAG_compile_unit) | 862 | if (compile_unit_die.tag_id != DW.TAG_compile_unit) |
| 863 | return error.InvalidDebugInfo; | 863 | return error.InvalidDebugInfo; |
| ... | @@ -868,7 +868,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { | ... | @@ -868,7 +868,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { |
| 868 | const pc_end = switch (*high_pc_value) { | 868 | const pc_end = switch (*high_pc_value) { |
| 869 | FormValue.Address => |value| value, | 869 | FormValue.Address => |value| value, |
| 870 | FormValue.Const => |value| b: { | 870 | FormValue.Const => |value| b: { |
| 871 | const offset = %return value.asUnsignedLe(); | 871 | const offset = try value.asUnsignedLe(); |
| 872 | break :b (low_pc + offset); | 872 | break :b (low_pc + offset); |
| 873 | }, | 873 | }, |
| 874 | else => return error.InvalidDebugInfo, | 874 | else => return error.InvalidDebugInfo, |
| ... | @@ -887,7 +887,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { | ... | @@ -887,7 +887,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { |
| 887 | } | 887 | } |
| 888 | }; | 888 | }; |
| 889 | 889 | ||
| 890 | %return st.compile_unit_list.append(CompileUnit { | 890 | try st.compile_unit_list.append(CompileUnit { |
| 891 | .version = version, | 891 | .version = version, |
| 892 | .is_64 = is_64, | 892 | .is_64 = is_64, |
| 893 | .pc_range = pc_range, | 893 | .pc_range = pc_range, |
| ... | @@ -911,10 +911,10 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn | ... | @@ -911,10 +911,10 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn |
| 911 | if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| { | 911 | if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| { |
| 912 | var base_address: usize = 0; | 912 | var base_address: usize = 0; |
| 913 | if (st.debug_ranges) |debug_ranges| { | 913 | if (st.debug_ranges) |debug_ranges| { |
| 914 | %return st.self_exe_file.seekTo(debug_ranges.offset + ranges_offset); | 914 | try st.self_exe_file.seekTo(debug_ranges.offset + ranges_offset); |
| 915 | while (true) { | 915 | while (true) { |
| 916 | const begin_addr = %return in_stream.readIntLe(usize); | 916 | const begin_addr = try in_stream.readIntLe(usize); |
| 917 | const end_addr = %return in_stream.readIntLe(usize); | 917 | const end_addr = try in_stream.readIntLe(usize); |
| 918 | if (begin_addr == 0 and end_addr == 0) { | 918 | if (begin_addr == 0 and end_addr == 0) { |
| 919 | break; | 919 | break; |
| 920 | } | 920 | } |
| ... | @@ -937,7 +937,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn | ... | @@ -937,7 +937,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn |
| 937 | } | 937 | } |
| 938 | 938 | ||
| 939 | fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 { | 939 | fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 { |
| 940 | const first_32_bits = %return in_stream.readIntLe(u32); | 940 | const first_32_bits = try in_stream.readIntLe(u32); |
| 941 | *is_64 = (first_32_bits == 0xffffffff); | 941 | *is_64 = (first_32_bits == 0xffffffff); |
| 942 | if (*is_64) { | 942 | if (*is_64) { |
| 943 | return in_stream.readIntLe(u64); | 943 | return in_stream.readIntLe(u64); |
| ... | @@ -952,7 +952,7 @@ fn readULeb128(in_stream: &io.InStream) -> %u64 { | ... | @@ -952,7 +952,7 @@ fn readULeb128(in_stream: &io.InStream) -> %u64 { |
| 952 | var shift: usize = 0; | 952 | var shift: usize = 0; |
| 953 | 953 | ||
| 954 | while (true) { | 954 | while (true) { |
| 955 | const byte = %return in_stream.readByte(); | 955 | const byte = try in_stream.readByte(); |
| 956 | 956 | ||
| 957 | var operand: u64 = undefined; | 957 | var operand: u64 = undefined; |
| 958 | 958 | ||
| ... | @@ -973,7 +973,7 @@ fn readILeb128(in_stream: &io.InStream) -> %i64 { | ... | @@ -973,7 +973,7 @@ fn readILeb128(in_stream: &io.InStream) -> %i64 { |
| 973 | var shift: usize = 0; | 973 | var shift: usize = 0; |
| 974 | 974 | ||
| 975 | while (true) { | 975 | while (true) { |
| 976 | const byte = %return in_stream.readByte(); | 976 | const byte = try in_stream.readByte(); |
| 977 | 977 | ||
| 978 | var operand: i64 = undefined; | 978 | var operand: i64 = undefined; |
| 979 | 979 |
std/elf.zig+53-53| ... | @@ -82,8 +82,8 @@ pub const Elf = struct { | ... | @@ -82,8 +82,8 @@ pub const Elf = struct { |
| 82 | 82 | ||
| 83 | /// Call close when done. | 83 | /// Call close when done. |
| 84 | pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) -> %void { | 84 | pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) -> %void { |
| 85 | %return elf.prealloc_file.open(path); | 85 | try elf.prealloc_file.open(path); |
| 86 | %return elf.openFile(allocator, &elf.prealloc_file); | 86 | try elf.openFile(allocator, &elf.prealloc_file); |
| 87 | elf.auto_close_stream = true; | 87 | elf.auto_close_stream = true; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| ... | @@ -97,28 +97,28 @@ pub const Elf = struct { | ... | @@ -97,28 +97,28 @@ pub const Elf = struct { |
| 97 | const in = &file_stream.stream; | 97 | const in = &file_stream.stream; |
| 98 | 98 | ||
| 99 | var magic: [4]u8 = undefined; | 99 | var magic: [4]u8 = undefined; |
| 100 | %return in.readNoEof(magic[0..]); | 100 | try in.readNoEof(magic[0..]); |
| 101 | if (!mem.eql(u8, magic, "\x7fELF")) return error.InvalidFormat; | 101 | if (!mem.eql(u8, magic, "\x7fELF")) return error.InvalidFormat; |
| 102 | 102 | ||
| 103 | elf.is_64 = switch (%return in.readByte()) { | 103 | elf.is_64 = switch (try in.readByte()) { |
| 104 | 1 => false, | 104 | 1 => false, |
| 105 | 2 => true, | 105 | 2 => true, |
| 106 | else => return error.InvalidFormat, | 106 | else => return error.InvalidFormat, |
| 107 | }; | 107 | }; |
| 108 | 108 | ||
| 109 | elf.endian = switch (%return in.readByte()) { | 109 | elf.endian = switch (try in.readByte()) { |
| 110 | 1 => builtin.Endian.Little, | 110 | 1 => builtin.Endian.Little, |
| 111 | 2 => builtin.Endian.Big, | 111 | 2 => builtin.Endian.Big, |
| 112 | else => return error.InvalidFormat, | 112 | else => return error.InvalidFormat, |
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | const version_byte = %return in.readByte(); | 115 | const version_byte = try in.readByte(); |
| 116 | if (version_byte != 1) return error.InvalidFormat; | 116 | if (version_byte != 1) return error.InvalidFormat; |
| 117 | 117 | ||
| 118 | // skip over padding | 118 | // skip over padding |
| 119 | %return elf.in_file.seekForward(9); | 119 | try elf.in_file.seekForward(9); |
| 120 | 120 | ||
| 121 | elf.file_type = switch (%return in.readInt(elf.endian, u16)) { | 121 | elf.file_type = switch (try in.readInt(elf.endian, u16)) { |
| 122 | 1 => FileType.Relocatable, | 122 | 1 => FileType.Relocatable, |
| 123 | 2 => FileType.Executable, | 123 | 2 => FileType.Executable, |
| 124 | 3 => FileType.Shared, | 124 | 3 => FileType.Shared, |
| ... | @@ -126,7 +126,7 @@ pub const Elf = struct { | ... | @@ -126,7 +126,7 @@ pub const Elf = struct { |
| 126 | else => return error.InvalidFormat, | 126 | else => return error.InvalidFormat, |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | elf.arch = switch (%return in.readInt(elf.endian, u16)) { | 129 | elf.arch = switch (try in.readInt(elf.endian, u16)) { |
| 130 | 0x02 => Arch.Sparc, | 130 | 0x02 => Arch.Sparc, |
| 131 | 0x03 => Arch.x86, | 131 | 0x03 => Arch.x86, |
| 132 | 0x08 => Arch.Mips, | 132 | 0x08 => Arch.Mips, |
| ... | @@ -139,88 +139,88 @@ pub const Elf = struct { | ... | @@ -139,88 +139,88 @@ pub const Elf = struct { |
| 139 | else => return error.InvalidFormat, | 139 | else => return error.InvalidFormat, |
| 140 | }; | 140 | }; |
| 141 | 141 | ||
| 142 | const elf_version = %return in.readInt(elf.endian, u32); | 142 | const elf_version = try in.readInt(elf.endian, u32); |
| 143 | if (elf_version != 1) return error.InvalidFormat; | 143 | if (elf_version != 1) return error.InvalidFormat; |
| 144 | 144 | ||
| 145 | if (elf.is_64) { | 145 | if (elf.is_64) { |
| 146 | elf.entry_addr = %return in.readInt(elf.endian, u64); | 146 | elf.entry_addr = try in.readInt(elf.endian, u64); |
| 147 | elf.program_header_offset = %return in.readInt(elf.endian, u64); | 147 | elf.program_header_offset = try in.readInt(elf.endian, u64); |
| 148 | elf.section_header_offset = %return in.readInt(elf.endian, u64); | 148 | elf.section_header_offset = try in.readInt(elf.endian, u64); |
| 149 | } else { | 149 | } else { |
| 150 | elf.entry_addr = u64(%return in.readInt(elf.endian, u32)); | 150 | elf.entry_addr = u64(try in.readInt(elf.endian, u32)); |
| 151 | elf.program_header_offset = u64(%return in.readInt(elf.endian, u32)); | 151 | elf.program_header_offset = u64(try in.readInt(elf.endian, u32)); |
| 152 | elf.section_header_offset = u64(%return in.readInt(elf.endian, u32)); | 152 | elf.section_header_offset = u64(try in.readInt(elf.endian, u32)); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | // skip over flags | 155 | // skip over flags |
| 156 | %return elf.in_file.seekForward(4); | 156 | try elf.in_file.seekForward(4); |
| 157 | 157 | ||
| 158 | const header_size = %return in.readInt(elf.endian, u16); | 158 | const header_size = try in.readInt(elf.endian, u16); |
| 159 | if ((elf.is_64 and header_size != 64) or | 159 | if ((elf.is_64 and header_size != 64) or |
| 160 | (!elf.is_64 and header_size != 52)) | 160 | (!elf.is_64 and header_size != 52)) |
| 161 | { | 161 | { |
| 162 | return error.InvalidFormat; | 162 | return error.InvalidFormat; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | const ph_entry_size = %return in.readInt(elf.endian, u16); | 165 | const ph_entry_size = try in.readInt(elf.endian, u16); |
| 166 | const ph_entry_count = %return in.readInt(elf.endian, u16); | 166 | const ph_entry_count = try in.readInt(elf.endian, u16); |
| 167 | const sh_entry_size = %return in.readInt(elf.endian, u16); | 167 | const sh_entry_size = try in.readInt(elf.endian, u16); |
| 168 | const sh_entry_count = %return in.readInt(elf.endian, u16); | 168 | const sh_entry_count = try in.readInt(elf.endian, u16); |
| 169 | elf.string_section_index = u64(%return in.readInt(elf.endian, u16)); | 169 | elf.string_section_index = u64(try in.readInt(elf.endian, u16)); |
| 170 | 170 | ||
| 171 | if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat; | 171 | if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat; |
| 172 | 172 | ||
| 173 | const sh_byte_count = u64(sh_entry_size) * u64(sh_entry_count); | 173 | const sh_byte_count = u64(sh_entry_size) * u64(sh_entry_count); |
| 174 | const end_sh = %return math.add(u64, elf.section_header_offset, sh_byte_count); | 174 | const end_sh = try math.add(u64, elf.section_header_offset, sh_byte_count); |
| 175 | const ph_byte_count = u64(ph_entry_size) * u64(ph_entry_count); | 175 | const ph_byte_count = u64(ph_entry_size) * u64(ph_entry_count); |
| 176 | const end_ph = %return math.add(u64, elf.program_header_offset, ph_byte_count); | 176 | const end_ph = try math.add(u64, elf.program_header_offset, ph_byte_count); |
| 177 | 177 | ||
| 178 | const stream_end = %return elf.in_file.getEndPos(); | 178 | const stream_end = try elf.in_file.getEndPos(); |
| 179 | if (stream_end < end_sh or stream_end < end_ph) { | 179 | if (stream_end < end_sh or stream_end < end_ph) { |
| 180 | return error.InvalidFormat; | 180 | return error.InvalidFormat; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | %return elf.in_file.seekTo(elf.section_header_offset); | 183 | try elf.in_file.seekTo(elf.section_header_offset); |
| 184 | 184 | ||
| 185 | elf.section_headers = %return elf.allocator.alloc(SectionHeader, sh_entry_count); | 185 | elf.section_headers = try elf.allocator.alloc(SectionHeader, sh_entry_count); |
| 186 | %defer elf.allocator.free(elf.section_headers); | 186 | %defer elf.allocator.free(elf.section_headers); |
| 187 | 187 | ||
| 188 | if (elf.is_64) { | 188 | if (elf.is_64) { |
| 189 | if (sh_entry_size != 64) return error.InvalidFormat; | 189 | if (sh_entry_size != 64) return error.InvalidFormat; |
| 190 | 190 | ||
| 191 | for (elf.section_headers) |*elf_section| { | 191 | for (elf.section_headers) |*elf_section| { |
| 192 | elf_section.name = %return in.readInt(elf.endian, u32); | 192 | elf_section.name = try in.readInt(elf.endian, u32); |
| 193 | elf_section.sh_type = %return in.readInt(elf.endian, u32); | 193 | elf_section.sh_type = try in.readInt(elf.endian, u32); |
| 194 | elf_section.flags = %return in.readInt(elf.endian, u64); | 194 | elf_section.flags = try in.readInt(elf.endian, u64); |
| 195 | elf_section.addr = %return in.readInt(elf.endian, u64); | 195 | elf_section.addr = try in.readInt(elf.endian, u64); |
| 196 | elf_section.offset = %return in.readInt(elf.endian, u64); | 196 | elf_section.offset = try in.readInt(elf.endian, u64); |
| 197 | elf_section.size = %return in.readInt(elf.endian, u64); | 197 | elf_section.size = try in.readInt(elf.endian, u64); |
| 198 | elf_section.link = %return in.readInt(elf.endian, u32); | 198 | elf_section.link = try in.readInt(elf.endian, u32); |
| 199 | elf_section.info = %return in.readInt(elf.endian, u32); | 199 | elf_section.info = try in.readInt(elf.endian, u32); |
| 200 | elf_section.addr_align = %return in.readInt(elf.endian, u64); | 200 | elf_section.addr_align = try in.readInt(elf.endian, u64); |
| 201 | elf_section.ent_size = %return in.readInt(elf.endian, u64); | 201 | elf_section.ent_size = try in.readInt(elf.endian, u64); |
| 202 | } | 202 | } |
| 203 | } else { | 203 | } else { |
| 204 | if (sh_entry_size != 40) return error.InvalidFormat; | 204 | if (sh_entry_size != 40) return error.InvalidFormat; |
| 205 | 205 | ||
| 206 | for (elf.section_headers) |*elf_section| { | 206 | for (elf.section_headers) |*elf_section| { |
| 207 | // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ? | 207 | // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ? |
| 208 | elf_section.name = %return in.readInt(elf.endian, u32); | 208 | elf_section.name = try in.readInt(elf.endian, u32); |
| 209 | elf_section.sh_type = %return in.readInt(elf.endian, u32); | 209 | elf_section.sh_type = try in.readInt(elf.endian, u32); |
| 210 | elf_section.flags = u64(%return in.readInt(elf.endian, u32)); | 210 | elf_section.flags = u64(try in.readInt(elf.endian, u32)); |
| 211 | elf_section.addr = u64(%return in.readInt(elf.endian, u32)); | 211 | elf_section.addr = u64(try in.readInt(elf.endian, u32)); |
| 212 | elf_section.offset = u64(%return in.readInt(elf.endian, u32)); | 212 | elf_section.offset = u64(try in.readInt(elf.endian, u32)); |
| 213 | elf_section.size = u64(%return in.readInt(elf.endian, u32)); | 213 | elf_section.size = u64(try in.readInt(elf.endian, u32)); |
| 214 | elf_section.link = %return in.readInt(elf.endian, u32); | 214 | elf_section.link = try in.readInt(elf.endian, u32); |
| 215 | elf_section.info = %return in.readInt(elf.endian, u32); | 215 | elf_section.info = try in.readInt(elf.endian, u32); |
| 216 | elf_section.addr_align = u64(%return in.readInt(elf.endian, u32)); | 216 | elf_section.addr_align = u64(try in.readInt(elf.endian, u32)); |
| 217 | elf_section.ent_size = u64(%return in.readInt(elf.endian, u32)); | 217 | elf_section.ent_size = u64(try in.readInt(elf.endian, u32)); |
| 218 | } | 218 | } |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | for (elf.section_headers) |*elf_section| { | 221 | for (elf.section_headers) |*elf_section| { |
| 222 | if (elf_section.sh_type != SHT_NOBITS) { | 222 | if (elf_section.sh_type != SHT_NOBITS) { |
| 223 | const file_end_offset = %return math.add(u64, elf_section.offset, elf_section.size); | 223 | const file_end_offset = try math.add(u64, elf_section.offset, elf_section.size); |
| 224 | if (stream_end < file_end_offset) return error.InvalidFormat; | 224 | if (stream_end < file_end_offset) return error.InvalidFormat; |
| 225 | } | 225 | } |
| 226 | } | 226 | } |
| ... | @@ -247,15 +247,15 @@ pub const Elf = struct { | ... | @@ -247,15 +247,15 @@ pub const Elf = struct { |
| 247 | if (elf_section.sh_type == SHT_NULL) continue; | 247 | if (elf_section.sh_type == SHT_NULL) continue; |
| 248 | 248 | ||
| 249 | const name_offset = elf.string_section.offset + elf_section.name; | 249 | const name_offset = elf.string_section.offset + elf_section.name; |
| 250 | %return elf.in_file.seekTo(name_offset); | 250 | try elf.in_file.seekTo(name_offset); |
| 251 | 251 | ||
| 252 | for (name) |expected_c| { | 252 | for (name) |expected_c| { |
| 253 | const target_c = %return in.readByte(); | 253 | const target_c = try in.readByte(); |
| 254 | if (target_c == 0 or expected_c != target_c) continue :section_loop; | 254 | if (target_c == 0 or expected_c != target_c) continue :section_loop; |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | { | 257 | { |
| 258 | const null_byte = %return in.readByte(); | 258 | const null_byte = try in.readByte(); |
| 259 | if (null_byte == 0) return elf_section; | 259 | if (null_byte == 0) return elf_section; |
| 260 | } | 260 | } |
| 261 | } | 261 | } |
| ... | @@ -264,6 +264,6 @@ pub const Elf = struct { | ... | @@ -264,6 +264,6 @@ pub const Elf = struct { |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void { | 266 | pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void { |
| 267 | %return elf.in_file.seekTo(elf_section.offset); | 267 | try elf.in_file.seekTo(elf_section.offset); |
| 268 | } | 268 | } |
| 269 | }; | 269 | }; |
std/endian.zig+1-1| ... | @@ -16,5 +16,5 @@ pub fn swapIf(endian: builtin.Endian, comptime T: type, x: T) -> T { | ... | @@ -16,5 +16,5 @@ pub fn swapIf(endian: builtin.Endian, comptime T: type, x: T) -> T { |
| 16 | pub fn swap(comptime T: type, x: T) -> T { | 16 | pub fn swap(comptime T: type, x: T) -> T { |
| 17 | var buf: [@sizeOf(T)]u8 = undefined; | 17 | var buf: [@sizeOf(T)]u8 = undefined; |
| 18 | mem.writeInt(buf[0..], x, false); | 18 | mem.writeInt(buf[0..], x, false); |
| 19 | return mem.readInt(buf, T, true); | 19 | return mem.readInt(buf, T, builtin.Endian.Big); |
| 20 | } | 20 | } |
std/fmt/index.zig+35-35| ... | @@ -40,13 +40,13 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, | ... | @@ -40,13 +40,13 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 40 | State.Start => switch (c) { | 40 | State.Start => switch (c) { |
| 41 | '{' => { | 41 | '{' => { |
| 42 | if (start_index < i) { | 42 | if (start_index < i) { |
| 43 | %return output(context, fmt[start_index..i]); | 43 | try output(context, fmt[start_index..i]); |
| 44 | } | 44 | } |
| 45 | state = State.OpenBrace; | 45 | state = State.OpenBrace; |
| 46 | }, | 46 | }, |
| 47 | '}' => { | 47 | '}' => { |
| 48 | if (start_index < i) { | 48 | if (start_index < i) { |
| 49 | %return output(context, fmt[start_index..i]); | 49 | try output(context, fmt[start_index..i]); |
| 50 | } | 50 | } |
| 51 | state = State.CloseBrace; | 51 | state = State.CloseBrace; |
| 52 | }, | 52 | }, |
| ... | @@ -58,7 +58,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, | ... | @@ -58,7 +58,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 58 | start_index = i; | 58 | start_index = i; |
| 59 | }, | 59 | }, |
| 60 | '}' => { | 60 | '}' => { |
| 61 | %return formatValue(args[next_arg], context, output); | 61 | try formatValue(args[next_arg], context, output); |
| 62 | next_arg += 1; | 62 | next_arg += 1; |
| 63 | state = State.Start; | 63 | state = State.Start; |
| 64 | start_index = i + 1; | 64 | start_index = i + 1; |
| ... | @@ -110,7 +110,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, | ... | @@ -110,7 +110,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 110 | }, | 110 | }, |
| 111 | State.Integer => switch (c) { | 111 | State.Integer => switch (c) { |
| 112 | '}' => { | 112 | '}' => { |
| 113 | %return formatInt(args[next_arg], radix, uppercase, width, context, output); | 113 | try formatInt(args[next_arg], radix, uppercase, width, context, output); |
| 114 | next_arg += 1; | 114 | next_arg += 1; |
| 115 | state = State.Start; | 115 | state = State.Start; |
| 116 | start_index = i + 1; | 116 | start_index = i + 1; |
| ... | @@ -124,7 +124,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, | ... | @@ -124,7 +124,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 124 | State.IntegerWidth => switch (c) { | 124 | State.IntegerWidth => switch (c) { |
| 125 | '}' => { | 125 | '}' => { |
| 126 | width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10); | 126 | width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10); |
| 127 | %return formatInt(args[next_arg], radix, uppercase, width, context, output); | 127 | try formatInt(args[next_arg], radix, uppercase, width, context, output); |
| 128 | next_arg += 1; | 128 | next_arg += 1; |
| 129 | state = State.Start; | 129 | state = State.Start; |
| 130 | start_index = i + 1; | 130 | start_index = i + 1; |
| ... | @@ -134,7 +134,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, | ... | @@ -134,7 +134,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 134 | }, | 134 | }, |
| 135 | State.Float => switch (c) { | 135 | State.Float => switch (c) { |
| 136 | '}' => { | 136 | '}' => { |
| 137 | %return formatFloatDecimal(args[next_arg], 0, context, output); | 137 | try formatFloatDecimal(args[next_arg], 0, context, output); |
| 138 | next_arg += 1; | 138 | next_arg += 1; |
| 139 | state = State.Start; | 139 | state = State.Start; |
| 140 | start_index = i + 1; | 140 | start_index = i + 1; |
| ... | @@ -148,7 +148,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, | ... | @@ -148,7 +148,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 148 | State.FloatWidth => switch (c) { | 148 | State.FloatWidth => switch (c) { |
| 149 | '}' => { | 149 | '}' => { |
| 150 | width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10); | 150 | width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10); |
| 151 | %return formatFloatDecimal(args[next_arg], width, context, output); | 151 | try formatFloatDecimal(args[next_arg], width, context, output); |
| 152 | next_arg += 1; | 152 | next_arg += 1; |
| 153 | state = State.Start; | 153 | state = State.Start; |
| 154 | start_index = i + 1; | 154 | start_index = i + 1; |
| ... | @@ -159,7 +159,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, | ... | @@ -159,7 +159,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 159 | State.BufWidth => switch (c) { | 159 | State.BufWidth => switch (c) { |
| 160 | '}' => { | 160 | '}' => { |
| 161 | width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10); | 161 | width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10); |
| 162 | %return formatBuf(args[next_arg], width, context, output); | 162 | try formatBuf(args[next_arg], width, context, output); |
| 163 | next_arg += 1; | 163 | next_arg += 1; |
| 164 | state = State.Start; | 164 | state = State.Start; |
| 165 | start_index = i + 1; | 165 | start_index = i + 1; |
| ... | @@ -169,7 +169,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, | ... | @@ -169,7 +169,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 169 | }, | 169 | }, |
| 170 | State.Character => switch (c) { | 170 | State.Character => switch (c) { |
| 171 | '}' => { | 171 | '}' => { |
| 172 | %return formatAsciiChar(args[next_arg], context, output); | 172 | try formatAsciiChar(args[next_arg], context, output); |
| 173 | next_arg += 1; | 173 | next_arg += 1; |
| 174 | state = State.Start; | 174 | state = State.Start; |
| 175 | start_index = i + 1; | 175 | start_index = i + 1; |
| ... | @@ -187,7 +187,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, | ... | @@ -187,7 +187,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 187 | } | 187 | } |
| 188 | } | 188 | } |
| 189 | if (start_index < fmt.len) { | 189 | if (start_index < fmt.len) { |
| 190 | %return output(context, fmt[start_index..]); | 190 | try output(context, fmt[start_index..]); |
| 191 | } | 191 | } |
| 192 | } | 192 | } |
| 193 | 193 | ||
| ... | @@ -221,7 +221,7 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons | ... | @@ -221,7 +221,7 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons |
| 221 | } | 221 | } |
| 222 | }, | 222 | }, |
| 223 | builtin.TypeId.Error => { | 223 | builtin.TypeId.Error => { |
| 224 | %return output(context, "error."); | 224 | try output(context, "error."); |
| 225 | return output(context, @errorName(value)); | 225 | return output(context, @errorName(value)); |
| 226 | }, | 226 | }, |
| 227 | builtin.TypeId.Pointer => { | 227 | builtin.TypeId.Pointer => { |
| ... | @@ -247,12 +247,12 @@ pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const | ... | @@ -247,12 +247,12 @@ pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const |
| 247 | pub fn formatBuf(buf: []const u8, width: usize, | 247 | pub fn formatBuf(buf: []const u8, width: usize, |
| 248 | context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void | 248 | context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void |
| 249 | { | 249 | { |
| 250 | %return output(context, buf); | 250 | try output(context, buf); |
| 251 | 251 | ||
| 252 | var leftover_padding = if (width > buf.len) (width - buf.len) else return; | 252 | var leftover_padding = if (width > buf.len) (width - buf.len) else return; |
| 253 | const pad_byte: u8 = ' '; | 253 | const pad_byte: u8 = ' '; |
| 254 | while (leftover_padding > 0) : (leftover_padding -= 1) { | 254 | while (leftover_padding > 0) : (leftover_padding -= 1) { |
| 255 | %return output(context, (&pad_byte)[0..1]); | 255 | try output(context, (&pad_byte)[0..1]); |
| 256 | } | 256 | } |
| 257 | } | 257 | } |
| 258 | 258 | ||
| ... | @@ -264,7 +264,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons | ... | @@ -264,7 +264,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons |
| 264 | return output(context, "NaN"); | 264 | return output(context, "NaN"); |
| 265 | } | 265 | } |
| 266 | if (math.signbit(x)) { | 266 | if (math.signbit(x)) { |
| 267 | %return output(context, "-"); | 267 | try output(context, "-"); |
| 268 | x = -x; | 268 | x = -x; |
| 269 | } | 269 | } |
| 270 | if (math.isPositiveInf(x)) { | 270 | if (math.isPositiveInf(x)) { |
| ... | @@ -276,21 +276,21 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons | ... | @@ -276,21 +276,21 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons |
| 276 | 276 | ||
| 277 | var buffer: [32]u8 = undefined; | 277 | var buffer: [32]u8 = undefined; |
| 278 | const float_decimal = errol3(x, buffer[0..]); | 278 | const float_decimal = errol3(x, buffer[0..]); |
| 279 | %return output(context, float_decimal.digits[0..1]); | 279 | try output(context, float_decimal.digits[0..1]); |
| 280 | %return output(context, "."); | 280 | try output(context, "."); |
| 281 | if (float_decimal.digits.len > 1) { | 281 | if (float_decimal.digits.len > 1) { |
| 282 | const num_digits = if (@typeOf(value) == f32) | 282 | const num_digits = if (@typeOf(value) == f32) |
| 283 | math.min(usize(9), float_decimal.digits.len) | 283 | math.min(usize(9), float_decimal.digits.len) |
| 284 | else | 284 | else |
| 285 | float_decimal.digits.len; | 285 | float_decimal.digits.len; |
| 286 | %return output(context, float_decimal.digits[1 .. num_digits]); | 286 | try output(context, float_decimal.digits[1 .. num_digits]); |
| 287 | } else { | 287 | } else { |
| 288 | %return output(context, "0"); | 288 | try output(context, "0"); |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | if (float_decimal.exp != 1) { | 291 | if (float_decimal.exp != 1) { |
| 292 | %return output(context, "e"); | 292 | try output(context, "e"); |
| 293 | %return formatInt(float_decimal.exp - 1, 10, false, 0, context, output); | 293 | try formatInt(float_decimal.exp - 1, 10, false, 0, context, output); |
| 294 | } | 294 | } |
| 295 | } | 295 | } |
| 296 | 296 | ||
| ... | @@ -302,7 +302,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn | ... | @@ -302,7 +302,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn |
| 302 | return output(context, "NaN"); | 302 | return output(context, "NaN"); |
| 303 | } | 303 | } |
| 304 | if (math.signbit(x)) { | 304 | if (math.signbit(x)) { |
| 305 | %return output(context, "-"); | 305 | try output(context, "-"); |
| 306 | x = -x; | 306 | x = -x; |
| 307 | } | 307 | } |
| 308 | if (math.isPositiveInf(x)) { | 308 | if (math.isPositiveInf(x)) { |
| ... | @@ -317,8 +317,8 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn | ... | @@ -317,8 +317,8 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn |
| 317 | 317 | ||
| 318 | const num_left_digits = if (float_decimal.exp > 0) usize(float_decimal.exp) else 1; | 318 | const num_left_digits = if (float_decimal.exp > 0) usize(float_decimal.exp) else 1; |
| 319 | 319 | ||
| 320 | %return output(context, float_decimal.digits[0 .. num_left_digits]); | 320 | try output(context, float_decimal.digits[0 .. num_left_digits]); |
| 321 | %return output(context, "."); | 321 | try output(context, "."); |
| 322 | if (float_decimal.digits.len > 1) { | 322 | if (float_decimal.digits.len > 1) { |
| 323 | const num_valid_digtis = if (@typeOf(value) == f32) math.min(usize(7), float_decimal.digits.len) | 323 | const num_valid_digtis = if (@typeOf(value) == f32) math.min(usize(7), float_decimal.digits.len) |
| 324 | else | 324 | else |
| ... | @@ -328,9 +328,9 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn | ... | @@ -328,9 +328,9 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn |
| 328 | math.min(precision, (num_valid_digtis-num_left_digits)) | 328 | math.min(precision, (num_valid_digtis-num_left_digits)) |
| 329 | else | 329 | else |
| 330 | num_valid_digtis - num_left_digits; | 330 | num_valid_digtis - num_left_digits; |
| 331 | %return output(context, float_decimal.digits[num_left_digits .. (num_left_digits + num_right_digits)]); | 331 | try output(context, float_decimal.digits[num_left_digits .. (num_left_digits + num_right_digits)]); |
| 332 | } else { | 332 | } else { |
| 333 | %return output(context, "0"); | 333 | try output(context, "0"); |
| 334 | } | 334 | } |
| 335 | } | 335 | } |
| 336 | 336 | ||
| ... | @@ -351,7 +351,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, | ... | @@ -351,7 +351,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, |
| 351 | const uint = @IntType(false, @typeOf(value).bit_count); | 351 | const uint = @IntType(false, @typeOf(value).bit_count); |
| 352 | if (value < 0) { | 352 | if (value < 0) { |
| 353 | const minus_sign: u8 = '-'; | 353 | const minus_sign: u8 = '-'; |
| 354 | %return output(context, (&minus_sign)[0..1]); | 354 | try output(context, (&minus_sign)[0..1]); |
| 355 | const new_value = uint(-(value + 1)) + 1; | 355 | const new_value = uint(-(value + 1)) + 1; |
| 356 | const new_width = if (width == 0) 0 else (width - 1); | 356 | const new_width = if (width == 0) 0 else (width - 1); |
| 357 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, output); | 357 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, output); |
| ... | @@ -359,7 +359,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, | ... | @@ -359,7 +359,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, |
| 359 | return formatIntUnsigned(uint(value), base, uppercase, width, context, output); | 359 | return formatIntUnsigned(uint(value), base, uppercase, width, context, output); |
| 360 | } else { | 360 | } else { |
| 361 | const plus_sign: u8 = '+'; | 361 | const plus_sign: u8 = '+'; |
| 362 | %return output(context, (&plus_sign)[0..1]); | 362 | try output(context, (&plus_sign)[0..1]); |
| 363 | const new_value = uint(value); | 363 | const new_value = uint(value); |
| 364 | const new_width = if (width == 0) 0 else (width - 1); | 364 | const new_width = if (width == 0) 0 else (width - 1); |
| 365 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, output); | 365 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, output); |
| ... | @@ -391,7 +391,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize, | ... | @@ -391,7 +391,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize, |
| 391 | const zero_byte: u8 = '0'; | 391 | const zero_byte: u8 = '0'; |
| 392 | var leftover_padding = padding - index; | 392 | var leftover_padding = padding - index; |
| 393 | while (true) { | 393 | while (true) { |
| 394 | %return output(context, (&zero_byte)[0..1]); | 394 | try output(context, (&zero_byte)[0..1]); |
| 395 | leftover_padding -= 1; | 395 | leftover_padding -= 1; |
| 396 | if (leftover_padding == 0) | 396 | if (leftover_padding == 0) |
| 397 | break; | 397 | break; |
| ... | @@ -428,7 +428,7 @@ pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) -> %T { | ... | @@ -428,7 +428,7 @@ pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) -> %T { |
| 428 | if (buf.len == 0) | 428 | if (buf.len == 0) |
| 429 | return T(0); | 429 | return T(0); |
| 430 | if (buf[0] == '-') { | 430 | if (buf[0] == '-') { |
| 431 | return math.negate(%return parseUnsigned(T, buf[1..], radix)); | 431 | return math.negate(try parseUnsigned(T, buf[1..], radix)); |
| 432 | } else if (buf[0] == '+') { | 432 | } else if (buf[0] == '+') { |
| 433 | return parseUnsigned(T, buf[1..], radix); | 433 | return parseUnsigned(T, buf[1..], radix); |
| 434 | } else { | 434 | } else { |
| ... | @@ -450,9 +450,9 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T { | ... | @@ -450,9 +450,9 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T { |
| 450 | var x: T = 0; | 450 | var x: T = 0; |
| 451 | 451 | ||
| 452 | for (buf) |c| { | 452 | for (buf) |c| { |
| 453 | const digit = %return charToDigit(c, radix); | 453 | const digit = try charToDigit(c, radix); |
| 454 | x = %return math.mul(T, x, radix); | 454 | x = try math.mul(T, x, radix); |
| 455 | x = %return math.add(T, x, digit); | 455 | x = try math.add(T, x, digit); |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | return x; | 458 | return x; |
| ... | @@ -494,7 +494,7 @@ fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> %void { | ... | @@ -494,7 +494,7 @@ fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> %void { |
| 494 | 494 | ||
| 495 | pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> %[]u8 { | 495 | pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> %[]u8 { |
| 496 | var context = BufPrintContext { .remaining = buf, }; | 496 | var context = BufPrintContext { .remaining = buf, }; |
| 497 | %return format(&context, bufPrintWrite, fmt, args); | 497 | try format(&context, bufPrintWrite, fmt, args); |
| 498 | return buf[0..buf.len - context.remaining.len]; | 498 | return buf[0..buf.len - context.remaining.len]; |
| 499 | } | 499 | } |
| 500 | 500 | ||
| ... | @@ -502,7 +502,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ... | ... | @@ -502,7 +502,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ... |
| 502 | var size: usize = 0; | 502 | var size: usize = 0; |
| 503 | // Cannot fail because `countSize` cannot fail. | 503 | // Cannot fail because `countSize` cannot fail. |
| 504 | %%format(&size, countSize, fmt, args); | 504 | %%format(&size, countSize, fmt, args); |
| 505 | const buf = %return allocator.alloc(u8, size); | 505 | const buf = try allocator.alloc(u8, size); |
| 506 | return bufPrint(buf, fmt, args); | 506 | return bufPrint(buf, fmt, args); |
| 507 | } | 507 | } |
| 508 | 508 | ||
| ... | @@ -533,7 +533,7 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: u | ... | @@ -533,7 +533,7 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: u |
| 533 | } | 533 | } |
| 534 | 534 | ||
| 535 | test "parse u64 digit too big" { | 535 | test "parse u64 digit too big" { |
| 536 | _ = parseUnsigned(u64, "123a", 10) %% |err| { | 536 | _ = parseUnsigned(u64, "123a", 10) catch |err| { |
| 537 | if (err == error.InvalidChar) return; | 537 | if (err == error.InvalidChar) return; |
| 538 | unreachable; | 538 | unreachable; |
| 539 | }; | 539 | }; |
std/hash_map.zig+3-3| ... | @@ -83,14 +83,14 @@ pub fn HashMap(comptime K: type, comptime V: type, | ... | @@ -83,14 +83,14 @@ pub fn HashMap(comptime K: type, comptime V: type, |
| 83 | /// Returns the value that was already there. | 83 | /// Returns the value that was already there. |
| 84 | pub fn put(hm: &Self, key: K, value: &const V) -> %?V { | 84 | pub fn put(hm: &Self, key: K, value: &const V) -> %?V { |
| 85 | if (hm.entries.len == 0) { | 85 | if (hm.entries.len == 0) { |
| 86 | %return hm.initCapacity(16); | 86 | try hm.initCapacity(16); |
| 87 | } | 87 | } |
| 88 | hm.incrementModificationCount(); | 88 | hm.incrementModificationCount(); |
| 89 | 89 | ||
| 90 | // if we get too full (60%), double the capacity | 90 | // if we get too full (60%), double the capacity |
| 91 | if (hm.size * 5 >= hm.entries.len * 3) { | 91 | if (hm.size * 5 >= hm.entries.len * 3) { |
| 92 | const old_entries = hm.entries; | 92 | const old_entries = hm.entries; |
| 93 | %return hm.initCapacity(hm.entries.len * 2); | 93 | try hm.initCapacity(hm.entries.len * 2); |
| 94 | // dump all of the old elements into the new table | 94 | // dump all of the old elements into the new table |
| 95 | for (old_entries) |*old_entry| { | 95 | for (old_entries) |*old_entry| { |
| 96 | if (old_entry.used) { | 96 | if (old_entry.used) { |
| ... | @@ -149,7 +149,7 @@ pub fn HashMap(comptime K: type, comptime V: type, | ... | @@ -149,7 +149,7 @@ pub fn HashMap(comptime K: type, comptime V: type, |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | fn initCapacity(hm: &Self, capacity: usize) -> %void { | 151 | fn initCapacity(hm: &Self, capacity: usize) -> %void { |
| 152 | hm.entries = %return hm.allocator.alloc(Entry, capacity); | 152 | hm.entries = try hm.allocator.alloc(Entry, capacity); |
| 153 | hm.size = 0; | 153 | hm.size = 0; |
| 154 | hm.max_distance_from_start_index = 0; | 154 | hm.max_distance_from_start_index = 0; |
| 155 | for (hm.entries) |*entry| { | 155 | for (hm.entries) |*entry| { |
std/heap.zig+5-5| ... | @@ -49,7 +49,7 @@ pub const IncrementingAllocator = struct { | ... | @@ -49,7 +49,7 @@ pub const IncrementingAllocator = struct { |
| 49 | 49 | ||
| 50 | fn init(capacity: usize) -> %IncrementingAllocator { | 50 | fn init(capacity: usize) -> %IncrementingAllocator { |
| 51 | switch (builtin.os) { | 51 | switch (builtin.os) { |
| 52 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | 52 | Os.linux, Os.macosx, Os.ios => { |
| 53 | const p = os.posix; | 53 | const p = os.posix; |
| 54 | const addr = p.mmap(null, capacity, p.PROT_READ|p.PROT_WRITE, | 54 | const addr = p.mmap(null, capacity, p.PROT_READ|p.PROT_WRITE, |
| 55 | p.MAP_PRIVATE|p.MAP_ANONYMOUS|p.MAP_NORESERVE, -1, 0); | 55 | p.MAP_PRIVATE|p.MAP_ANONYMOUS|p.MAP_NORESERVE, -1, 0); |
| ... | @@ -87,7 +87,7 @@ pub const IncrementingAllocator = struct { | ... | @@ -87,7 +87,7 @@ pub const IncrementingAllocator = struct { |
| 87 | 87 | ||
| 88 | fn deinit(self: &IncrementingAllocator) { | 88 | fn deinit(self: &IncrementingAllocator) { |
| 89 | switch (builtin.os) { | 89 | switch (builtin.os) { |
| 90 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | 90 | Os.linux, Os.macosx, Os.ios => { |
| 91 | _ = os.posix.munmap(self.bytes.ptr, self.bytes.len); | 91 | _ = os.posix.munmap(self.bytes.ptr, self.bytes.len); |
| 92 | }, | 92 | }, |
| 93 | Os.windows => { | 93 | Os.windows => { |
| ... | @@ -124,7 +124,7 @@ pub const IncrementingAllocator = struct { | ... | @@ -124,7 +124,7 @@ pub const IncrementingAllocator = struct { |
| 124 | if (new_size <= old_mem.len) { | 124 | if (new_size <= old_mem.len) { |
| 125 | return old_mem[0..new_size]; | 125 | return old_mem[0..new_size]; |
| 126 | } else { | 126 | } else { |
| 127 | const result = %return alloc(allocator, new_size, alignment); | 127 | const result = try alloc(allocator, new_size, alignment); |
| 128 | mem.copy(u8, result, old_mem); | 128 | mem.copy(u8, result, old_mem); |
| 129 | return result; | 129 | return result; |
| 130 | } | 130 | } |
| ... | @@ -137,9 +137,9 @@ pub const IncrementingAllocator = struct { | ... | @@ -137,9 +137,9 @@ pub const IncrementingAllocator = struct { |
| 137 | 137 | ||
| 138 | test "c_allocator" { | 138 | test "c_allocator" { |
| 139 | if (builtin.link_libc) { | 139 | if (builtin.link_libc) { |
| 140 | var slice = c_allocator.alloc(u8, 50) %% return; | 140 | var slice = c_allocator.alloc(u8, 50) catch return; |
| 141 | defer c_allocator.free(slice); | 141 | defer c_allocator.free(slice); |
| 142 | slice = c_allocator.realloc(u8, slice, 100) %% return; | 142 | slice = c_allocator.realloc(u8, slice, 100) catch return; |
| 143 | } | 143 | } |
| 144 | } | 144 | } |
| 145 | 145 |
std/io.zig+38-38| ... | @@ -3,7 +3,7 @@ const builtin = @import("builtin"); | ... | @@ -3,7 +3,7 @@ const builtin = @import("builtin"); |
| 3 | const Os = builtin.Os; | 3 | const Os = builtin.Os; |
| 4 | const system = switch(builtin.os) { | 4 | const system = switch(builtin.os) { |
| 5 | Os.linux => @import("os/linux.zig"), | 5 | Os.linux => @import("os/linux.zig"), |
| 6 | Os.darwin, Os.macosx, Os.ios => @import("os/darwin.zig"), | 6 | Os.macosx, Os.ios => @import("os/darwin.zig"), |
| 7 | Os.windows => @import("os/windows/index.zig"), | 7 | Os.windows => @import("os/windows/index.zig"), |
| 8 | else => @compileError("Unsupported OS"), | 8 | else => @compileError("Unsupported OS"), |
| 9 | }; | 9 | }; |
| ... | @@ -51,7 +51,7 @@ error EndOfFile; | ... | @@ -51,7 +51,7 @@ error EndOfFile; |
| 51 | 51 | ||
| 52 | pub fn getStdErr() -> %File { | 52 | pub fn getStdErr() -> %File { |
| 53 | const handle = if (is_windows) | 53 | const handle = if (is_windows) |
| 54 | %return os.windowsGetStdHandle(system.STD_ERROR_HANDLE) | 54 | try os.windowsGetStdHandle(system.STD_ERROR_HANDLE) |
| 55 | else if (is_posix) | 55 | else if (is_posix) |
| 56 | system.STDERR_FILENO | 56 | system.STDERR_FILENO |
| 57 | else | 57 | else |
| ... | @@ -61,7 +61,7 @@ pub fn getStdErr() -> %File { | ... | @@ -61,7 +61,7 @@ pub fn getStdErr() -> %File { |
| 61 | 61 | ||
| 62 | pub fn getStdOut() -> %File { | 62 | pub fn getStdOut() -> %File { |
| 63 | const handle = if (is_windows) | 63 | const handle = if (is_windows) |
| 64 | %return os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE) | 64 | try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE) |
| 65 | else if (is_posix) | 65 | else if (is_posix) |
| 66 | system.STDOUT_FILENO | 66 | system.STDOUT_FILENO |
| 67 | else | 67 | else |
| ... | @@ -71,7 +71,7 @@ pub fn getStdOut() -> %File { | ... | @@ -71,7 +71,7 @@ pub fn getStdOut() -> %File { |
| 71 | 71 | ||
| 72 | pub fn getStdIn() -> %File { | 72 | pub fn getStdIn() -> %File { |
| 73 | const handle = if (is_windows) | 73 | const handle = if (is_windows) |
| 74 | %return os.windowsGetStdHandle(system.STD_INPUT_HANDLE) | 74 | try os.windowsGetStdHandle(system.STD_INPUT_HANDLE) |
| 75 | else if (is_posix) | 75 | else if (is_posix) |
| 76 | system.STDIN_FILENO | 76 | system.STDIN_FILENO |
| 77 | else | 77 | else |
| ... | @@ -131,10 +131,10 @@ pub const File = struct { | ... | @@ -131,10 +131,10 @@ pub const File = struct { |
| 131 | pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) -> %File { | 131 | pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) -> %File { |
| 132 | if (is_posix) { | 132 | if (is_posix) { |
| 133 | const flags = system.O_LARGEFILE|system.O_RDONLY; | 133 | const flags = system.O_LARGEFILE|system.O_RDONLY; |
| 134 | const fd = %return os.posixOpen(path, flags, 0, allocator); | 134 | const fd = try os.posixOpen(path, flags, 0, allocator); |
| 135 | return openHandle(fd); | 135 | return openHandle(fd); |
| 136 | } else if (is_windows) { | 136 | } else if (is_windows) { |
| 137 | const handle = %return os.windowsOpen(path, system.GENERIC_READ, system.FILE_SHARE_READ, | 137 | const handle = try os.windowsOpen(path, system.GENERIC_READ, system.FILE_SHARE_READ, |
| 138 | system.OPEN_EXISTING, system.FILE_ATTRIBUTE_NORMAL, allocator); | 138 | system.OPEN_EXISTING, system.FILE_ATTRIBUTE_NORMAL, allocator); |
| 139 | return openHandle(handle); | 139 | return openHandle(handle); |
| 140 | } else { | 140 | } else { |
| ... | @@ -156,10 +156,10 @@ pub const File = struct { | ... | @@ -156,10 +156,10 @@ pub const File = struct { |
| 156 | pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) -> %File { | 156 | pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) -> %File { |
| 157 | if (is_posix) { | 157 | if (is_posix) { |
| 158 | const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC; | 158 | const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC; |
| 159 | const fd = %return os.posixOpen(path, flags, mode, allocator); | 159 | const fd = try os.posixOpen(path, flags, mode, allocator); |
| 160 | return openHandle(fd); | 160 | return openHandle(fd); |
| 161 | } else if (is_windows) { | 161 | } else if (is_windows) { |
| 162 | const handle = %return os.windowsOpen(path, system.GENERIC_WRITE, | 162 | const handle = try os.windowsOpen(path, system.GENERIC_WRITE, |
| 163 | system.FILE_SHARE_WRITE|system.FILE_SHARE_READ|system.FILE_SHARE_DELETE, | 163 | system.FILE_SHARE_WRITE|system.FILE_SHARE_READ|system.FILE_SHARE_DELETE, |
| 164 | system.CREATE_ALWAYS, system.FILE_ATTRIBUTE_NORMAL, allocator); | 164 | system.CREATE_ALWAYS, system.FILE_ATTRIBUTE_NORMAL, allocator); |
| 165 | return openHandle(handle); | 165 | return openHandle(handle); |
| ... | @@ -190,7 +190,7 @@ pub const File = struct { | ... | @@ -190,7 +190,7 @@ pub const File = struct { |
| 190 | 190 | ||
| 191 | pub fn seekForward(self: &File, amount: isize) -> %void { | 191 | pub fn seekForward(self: &File, amount: isize) -> %void { |
| 192 | switch (builtin.os) { | 192 | switch (builtin.os) { |
| 193 | Os.linux, Os.darwin => { | 193 | Os.linux, Os.macosx, Os.ios => { |
| 194 | const result = system.lseek(self.handle, amount, system.SEEK_CUR); | 194 | const result = system.lseek(self.handle, amount, system.SEEK_CUR); |
| 195 | const err = system.getErrno(result); | 195 | const err = system.getErrno(result); |
| 196 | if (err > 0) { | 196 | if (err > 0) { |
| ... | @@ -210,7 +210,7 @@ pub const File = struct { | ... | @@ -210,7 +210,7 @@ pub const File = struct { |
| 210 | 210 | ||
| 211 | pub fn seekTo(self: &File, pos: usize) -> %void { | 211 | pub fn seekTo(self: &File, pos: usize) -> %void { |
| 212 | switch (builtin.os) { | 212 | switch (builtin.os) { |
| 213 | Os.linux, Os.darwin => { | 213 | Os.linux, Os.macosx, Os.ios => { |
| 214 | const result = system.lseek(self.handle, @bitCast(isize, pos), system.SEEK_SET); | 214 | const result = system.lseek(self.handle, @bitCast(isize, pos), system.SEEK_SET); |
| 215 | const err = system.getErrno(result); | 215 | const err = system.getErrno(result); |
| 216 | if (err > 0) { | 216 | if (err > 0) { |
| ... | @@ -230,7 +230,7 @@ pub const File = struct { | ... | @@ -230,7 +230,7 @@ pub const File = struct { |
| 230 | 230 | ||
| 231 | pub fn getPos(self: &File) -> %usize { | 231 | pub fn getPos(self: &File) -> %usize { |
| 232 | switch (builtin.os) { | 232 | switch (builtin.os) { |
| 233 | Os.linux, Os.darwin => { | 233 | Os.linux, Os.macosx, Os.ios => { |
| 234 | const result = system.lseek(self.handle, 0, system.SEEK_CUR); | 234 | const result = system.lseek(self.handle, 0, system.SEEK_CUR); |
| 235 | const err = system.getErrno(result); | 235 | const err = system.getErrno(result); |
| 236 | if (err > 0) { | 236 | if (err > 0) { |
| ... | @@ -322,9 +322,9 @@ pub const File = struct { | ... | @@ -322,9 +322,9 @@ pub const File = struct { |
| 322 | 322 | ||
| 323 | fn write(self: &File, bytes: []const u8) -> %void { | 323 | fn write(self: &File, bytes: []const u8) -> %void { |
| 324 | if (is_posix) { | 324 | if (is_posix) { |
| 325 | %return os.posixWrite(self.handle, bytes); | 325 | try os.posixWrite(self.handle, bytes); |
| 326 | } else if (is_windows) { | 326 | } else if (is_windows) { |
| 327 | %return os.windowsWrite(self.handle, bytes); | 327 | try os.windowsWrite(self.handle, bytes); |
| 328 | } else { | 328 | } else { |
| 329 | @compileError("Unsupported OS"); | 329 | @compileError("Unsupported OS"); |
| 330 | } | 330 | } |
| ... | @@ -344,12 +344,12 @@ pub const InStream = struct { | ... | @@ -344,12 +344,12 @@ pub const InStream = struct { |
| 344 | /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and | 344 | /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and |
| 345 | /// the contents read from the stream are lost. | 345 | /// the contents read from the stream are lost. |
| 346 | pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) -> %void { | 346 | pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) -> %void { |
| 347 | %return buffer.resize(0); | 347 | try buffer.resize(0); |
| 348 | 348 | ||
| 349 | var actual_buf_len: usize = 0; | 349 | var actual_buf_len: usize = 0; |
| 350 | while (true) { | 350 | while (true) { |
| 351 | const dest_slice = buffer.toSlice()[actual_buf_len..]; | 351 | const dest_slice = buffer.toSlice()[actual_buf_len..]; |
| 352 | const bytes_read = %return self.readFn(self, dest_slice); | 352 | const bytes_read = try self.readFn(self, dest_slice); |
| 353 | actual_buf_len += bytes_read; | 353 | actual_buf_len += bytes_read; |
| 354 | 354 | ||
| 355 | if (bytes_read != dest_slice.len) { | 355 | if (bytes_read != dest_slice.len) { |
| ... | @@ -360,7 +360,7 @@ pub const InStream = struct { | ... | @@ -360,7 +360,7 @@ pub const InStream = struct { |
| 360 | const new_buf_size = math.min(max_size, actual_buf_len + os.page_size); | 360 | const new_buf_size = math.min(max_size, actual_buf_len + os.page_size); |
| 361 | if (new_buf_size == actual_buf_len) | 361 | if (new_buf_size == actual_buf_len) |
| 362 | return error.StreamTooLong; | 362 | return error.StreamTooLong; |
| 363 | %return buffer.resize(new_buf_size); | 363 | try buffer.resize(new_buf_size); |
| 364 | } | 364 | } |
| 365 | } | 365 | } |
| 366 | 366 | ||
| ... | @@ -372,7 +372,7 @@ pub const InStream = struct { | ... | @@ -372,7 +372,7 @@ pub const InStream = struct { |
| 372 | var buf = Buffer.initNull(allocator); | 372 | var buf = Buffer.initNull(allocator); |
| 373 | defer buf.deinit(); | 373 | defer buf.deinit(); |
| 374 | 374 | ||
| 375 | %return self.readAllBuffer(&buf, max_size); | 375 | try self.readAllBuffer(&buf, max_size); |
| 376 | return buf.toOwnedSlice(); | 376 | return buf.toOwnedSlice(); |
| 377 | } | 377 | } |
| 378 | 378 | ||
| ... | @@ -381,10 +381,10 @@ pub const InStream = struct { | ... | @@ -381,10 +381,10 @@ pub const InStream = struct { |
| 381 | /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents | 381 | /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents |
| 382 | /// read from the stream so far are lost. | 382 | /// read from the stream so far are lost. |
| 383 | pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) -> %void { | 383 | pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) -> %void { |
| 384 | %return buf.resize(0); | 384 | try buf.resize(0); |
| 385 | 385 | ||
| 386 | while (true) { | 386 | while (true) { |
| 387 | var byte: u8 = %return self.readByte(); | 387 | var byte: u8 = try self.readByte(); |
| 388 | 388 | ||
| 389 | if (byte == delimiter) { | 389 | if (byte == delimiter) { |
| 390 | return; | 390 | return; |
| ... | @@ -394,7 +394,7 @@ pub const InStream = struct { | ... | @@ -394,7 +394,7 @@ pub const InStream = struct { |
| 394 | return error.StreamTooLong; | 394 | return error.StreamTooLong; |
| 395 | } | 395 | } |
| 396 | 396 | ||
| 397 | %return buf.appendByte(byte); | 397 | try buf.appendByte(byte); |
| 398 | } | 398 | } |
| 399 | } | 399 | } |
| 400 | 400 | ||
| ... | @@ -408,7 +408,7 @@ pub const InStream = struct { | ... | @@ -408,7 +408,7 @@ pub const InStream = struct { |
| 408 | var buf = Buffer.initNull(allocator); | 408 | var buf = Buffer.initNull(allocator); |
| 409 | defer buf.deinit(); | 409 | defer buf.deinit(); |
| 410 | 410 | ||
| 411 | %return self.readUntilDelimiterBuffer(self, &buf, delimiter, max_size); | 411 | try self.readUntilDelimiterBuffer(self, &buf, delimiter, max_size); |
| 412 | return buf.toOwnedSlice(); | 412 | return buf.toOwnedSlice(); |
| 413 | } | 413 | } |
| 414 | 414 | ||
| ... | @@ -421,20 +421,20 @@ pub const InStream = struct { | ... | @@ -421,20 +421,20 @@ pub const InStream = struct { |
| 421 | 421 | ||
| 422 | /// Same as `read` but end of stream returns `error.EndOfStream`. | 422 | /// Same as `read` but end of stream returns `error.EndOfStream`. |
| 423 | pub fn readNoEof(self: &InStream, buf: []u8) -> %void { | 423 | pub fn readNoEof(self: &InStream, buf: []u8) -> %void { |
| 424 | const amt_read = %return self.read(buf); | 424 | const amt_read = try self.read(buf); |
| 425 | if (amt_read < buf.len) return error.EndOfStream; | 425 | if (amt_read < buf.len) return error.EndOfStream; |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | /// Reads 1 byte from the stream or returns `error.EndOfStream`. | 428 | /// Reads 1 byte from the stream or returns `error.EndOfStream`. |
| 429 | pub fn readByte(self: &InStream) -> %u8 { | 429 | pub fn readByte(self: &InStream) -> %u8 { |
| 430 | var result: [1]u8 = undefined; | 430 | var result: [1]u8 = undefined; |
| 431 | %return self.readNoEof(result[0..]); | 431 | try self.readNoEof(result[0..]); |
| 432 | return result[0]; | 432 | return result[0]; |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | /// Same as `readByte` except the returned byte is signed. | 435 | /// Same as `readByte` except the returned byte is signed. |
| 436 | pub fn readByteSigned(self: &InStream) -> %i8 { | 436 | pub fn readByteSigned(self: &InStream) -> %i8 { |
| 437 | return @bitCast(i8, %return self.readByte()); | 437 | return @bitCast(i8, try self.readByte()); |
| 438 | } | 438 | } |
| 439 | 439 | ||
| 440 | pub fn readIntLe(self: &InStream, comptime T: type) -> %T { | 440 | pub fn readIntLe(self: &InStream, comptime T: type) -> %T { |
| ... | @@ -447,7 +447,7 @@ pub const InStream = struct { | ... | @@ -447,7 +447,7 @@ pub const InStream = struct { |
| 447 | 447 | ||
| 448 | pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) -> %T { | 448 | pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) -> %T { |
| 449 | var bytes: [@sizeOf(T)]u8 = undefined; | 449 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 450 | %return self.readNoEof(bytes[0..]); | 450 | try self.readNoEof(bytes[0..]); |
| 451 | return mem.readInt(bytes, T, endian); | 451 | return mem.readInt(bytes, T, endian); |
| 452 | } | 452 | } |
| 453 | 453 | ||
| ... | @@ -456,7 +456,7 @@ pub const InStream = struct { | ... | @@ -456,7 +456,7 @@ pub const InStream = struct { |
| 456 | assert(size <= 8); | 456 | assert(size <= 8); |
| 457 | var input_buf: [8]u8 = undefined; | 457 | var input_buf: [8]u8 = undefined; |
| 458 | const input_slice = input_buf[0..size]; | 458 | const input_slice = input_buf[0..size]; |
| 459 | %return self.readNoEof(input_slice); | 459 | try self.readNoEof(input_slice); |
| 460 | return mem.readInt(input_slice, T, endian); | 460 | return mem.readInt(input_slice, T, endian); |
| 461 | } | 461 | } |
| 462 | 462 | ||
| ... | @@ -483,7 +483,7 @@ pub const OutStream = struct { | ... | @@ -483,7 +483,7 @@ pub const OutStream = struct { |
| 483 | const slice = (&byte)[0..1]; | 483 | const slice = (&byte)[0..1]; |
| 484 | var i: usize = 0; | 484 | var i: usize = 0; |
| 485 | while (i < n) : (i += 1) { | 485 | while (i < n) : (i += 1) { |
| 486 | %return self.writeFn(self, slice); | 486 | try self.writeFn(self, slice); |
| 487 | } | 487 | } |
| 488 | } | 488 | } |
| 489 | }; | 489 | }; |
| ... | @@ -493,9 +493,9 @@ pub const OutStream = struct { | ... | @@ -493,9 +493,9 @@ pub const OutStream = struct { |
| 493 | /// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned. | 493 | /// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned. |
| 494 | /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. | 494 | /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. |
| 495 | pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) -> %void { | 495 | pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) -> %void { |
| 496 | var file = %return File.openWrite(path, allocator); | 496 | var file = try File.openWrite(path, allocator); |
| 497 | defer file.close(); | 497 | defer file.close(); |
| 498 | %return file.write(data); | 498 | try file.write(data); |
| 499 | } | 499 | } |
| 500 | 500 | ||
| 501 | /// On success, caller owns returned buffer. | 501 | /// On success, caller owns returned buffer. |
| ... | @@ -505,15 +505,15 @@ pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) -> %[]u8 { | ... | @@ -505,15 +505,15 @@ pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) -> %[]u8 { |
| 505 | /// On success, caller owns returned buffer. | 505 | /// On success, caller owns returned buffer. |
| 506 | /// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized. | 506 | /// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized. |
| 507 | pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) -> %[]u8 { | 507 | pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) -> %[]u8 { |
| 508 | var file = %return File.openRead(path, allocator); | 508 | var file = try File.openRead(path, allocator); |
| 509 | defer file.close(); | 509 | defer file.close(); |
| 510 | 510 | ||
| 511 | const size = %return file.getEndPos(); | 511 | const size = try file.getEndPos(); |
| 512 | const buf = %return allocator.alloc(u8, size + extra_len); | 512 | const buf = try allocator.alloc(u8, size + extra_len); |
| 513 | %defer allocator.free(buf); | 513 | %defer allocator.free(buf); |
| 514 | 514 | ||
| 515 | var adapter = FileInStream.init(&file); | 515 | var adapter = FileInStream.init(&file); |
| 516 | %return adapter.stream.readNoEof(buf[0..size]); | 516 | try adapter.stream.readNoEof(buf[0..size]); |
| 517 | return buf; | 517 | return buf; |
| 518 | } | 518 | } |
| 519 | 519 | ||
| ... | @@ -565,11 +565,11 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type { | ... | @@ -565,11 +565,11 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type { |
| 565 | // we can read more data from the unbuffered stream | 565 | // we can read more data from the unbuffered stream |
| 566 | if (dest_space < buffer_size) { | 566 | if (dest_space < buffer_size) { |
| 567 | self.start_index = 0; | 567 | self.start_index = 0; |
| 568 | self.end_index = %return self.unbuffered_in_stream.read(self.buffer[0..]); | 568 | self.end_index = try self.unbuffered_in_stream.read(self.buffer[0..]); |
| 569 | } else { | 569 | } else { |
| 570 | // asking for so much data that buffering is actually less efficient. | 570 | // asking for so much data that buffering is actually less efficient. |
| 571 | // forward the request directly to the unbuffered stream | 571 | // forward the request directly to the unbuffered stream |
| 572 | const amt_read = %return self.unbuffered_in_stream.read(dest[dest_index..]); | 572 | const amt_read = try self.unbuffered_in_stream.read(dest[dest_index..]); |
| 573 | return dest_index + amt_read; | 573 | return dest_index + amt_read; |
| 574 | } | 574 | } |
| 575 | } else { | 575 | } else { |
| ... | @@ -616,7 +616,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { | ... | @@ -616,7 +616,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { |
| 616 | if (self.index == 0) | 616 | if (self.index == 0) |
| 617 | return; | 617 | return; |
| 618 | 618 | ||
| 619 | %return self.unbuffered_out_stream.write(self.buffer[0..self.index]); | 619 | try self.unbuffered_out_stream.write(self.buffer[0..self.index]); |
| 620 | self.index = 0; | 620 | self.index = 0; |
| 621 | } | 621 | } |
| 622 | 622 | ||
| ... | @@ -624,7 +624,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { | ... | @@ -624,7 +624,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { |
| 624 | const self = @fieldParentPtr(Self, "stream", out_stream); | 624 | const self = @fieldParentPtr(Self, "stream", out_stream); |
| 625 | 625 | ||
| 626 | if (bytes.len >= self.buffer.len) { | 626 | if (bytes.len >= self.buffer.len) { |
| 627 | %return self.flush(); | 627 | try self.flush(); |
| 628 | return self.unbuffered_out_stream.write(bytes); | 628 | return self.unbuffered_out_stream.write(bytes); |
| 629 | } | 629 | } |
| 630 | var src_index: usize = 0; | 630 | var src_index: usize = 0; |
| ... | @@ -636,7 +636,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { | ... | @@ -636,7 +636,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { |
| 636 | self.index += copy_amt; | 636 | self.index += copy_amt; |
| 637 | assert(self.index <= self.buffer.len); | 637 | assert(self.index <= self.buffer.len); |
| 638 | if (self.index == self.buffer.len) { | 638 | if (self.index == self.buffer.len) { |
| 639 | %return self.flush(); | 639 | try self.flush(); |
| 640 | } | 640 | } |
| 641 | src_index += copy_amt; | 641 | src_index += copy_amt; |
| 642 | } | 642 | } |
std/linked_list.zig+1-1| ... | @@ -188,7 +188,7 @@ pub fn LinkedList(comptime T: type) -> type { | ... | @@ -188,7 +188,7 @@ pub fn LinkedList(comptime T: type) -> type { |
| 188 | /// Returns: | 188 | /// Returns: |
| 189 | /// A pointer to the new node. | 189 | /// A pointer to the new node. |
| 190 | pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) -> %&Node { | 190 | pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) -> %&Node { |
| 191 | var node = %return list.allocateNode(allocator); | 191 | var node = try list.allocateNode(allocator); |
| 192 | *node = Node.init(data); | 192 | *node = Node.init(data); |
| 193 | return node; | 193 | return node; |
| 194 | } | 194 | } |
std/mem.zig+8-8| ... | @@ -27,7 +27,7 @@ pub const Allocator = struct { | ... | @@ -27,7 +27,7 @@ pub const Allocator = struct { |
| 27 | freeFn: fn (self: &Allocator, old_mem: []u8), | 27 | freeFn: fn (self: &Allocator, old_mem: []u8), |
| 28 | 28 | ||
| 29 | fn create(self: &Allocator, comptime T: type) -> %&T { | 29 | fn create(self: &Allocator, comptime T: type) -> %&T { |
| 30 | const slice = %return self.alloc(T, 1); | 30 | const slice = try self.alloc(T, 1); |
| 31 | return &slice[0]; | 31 | return &slice[0]; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| ... | @@ -42,8 +42,8 @@ pub const Allocator = struct { | ... | @@ -42,8 +42,8 @@ pub const Allocator = struct { |
| 42 | fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29, | 42 | fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29, |
| 43 | n: usize) -> %[]align(alignment) T | 43 | n: usize) -> %[]align(alignment) T |
| 44 | { | 44 | { |
| 45 | const byte_count = %return math.mul(usize, @sizeOf(T), n); | 45 | const byte_count = try math.mul(usize, @sizeOf(T), n); |
| 46 | const byte_slice = %return self.allocFn(self, byte_count, alignment); | 46 | const byte_slice = try self.allocFn(self, byte_count, alignment); |
| 47 | // This loop should get optimized out in ReleaseFast mode | 47 | // This loop should get optimized out in ReleaseFast mode |
| 48 | for (byte_slice) |*byte| { | 48 | for (byte_slice) |*byte| { |
| 49 | *byte = undefined; | 49 | *byte = undefined; |
| ... | @@ -63,8 +63,8 @@ pub const Allocator = struct { | ... | @@ -63,8 +63,8 @@ pub const Allocator = struct { |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | const old_byte_slice = ([]u8)(old_mem); | 65 | const old_byte_slice = ([]u8)(old_mem); |
| 66 | const byte_count = %return math.mul(usize, @sizeOf(T), n); | 66 | const byte_count = try math.mul(usize, @sizeOf(T), n); |
| 67 | const byte_slice = %return self.reallocFn(self, old_byte_slice, byte_count, alignment); | 67 | const byte_slice = try self.reallocFn(self, old_byte_slice, byte_count, alignment); |
| 68 | // This loop should get optimized out in ReleaseFast mode | 68 | // This loop should get optimized out in ReleaseFast mode |
| 69 | for (byte_slice[old_byte_slice.len..]) |*byte| { | 69 | for (byte_slice[old_byte_slice.len..]) |*byte| { |
| 70 | *byte = undefined; | 70 | *byte = undefined; |
| ... | @@ -142,7 +142,7 @@ pub const FixedBufferAllocator = struct { | ... | @@ -142,7 +142,7 @@ pub const FixedBufferAllocator = struct { |
| 142 | if (new_size <= old_mem.len) { | 142 | if (new_size <= old_mem.len) { |
| 143 | return old_mem[0..new_size]; | 143 | return old_mem[0..new_size]; |
| 144 | } else { | 144 | } else { |
| 145 | const result = %return alloc(allocator, new_size, alignment); | 145 | const result = try alloc(allocator, new_size, alignment); |
| 146 | copy(u8, result, old_mem); | 146 | copy(u8, result, old_mem); |
| 147 | return result; | 147 | return result; |
| 148 | } | 148 | } |
| ... | @@ -198,7 +198,7 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) -> bool { | ... | @@ -198,7 +198,7 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) -> bool { |
| 198 | 198 | ||
| 199 | /// Copies ::m to newly allocated memory. Caller is responsible to free it. | 199 | /// Copies ::m to newly allocated memory. Caller is responsible to free it. |
| 200 | pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) -> %[]T { | 200 | pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) -> %[]T { |
| 201 | const new_buf = %return allocator.alloc(T, m.len); | 201 | const new_buf = try allocator.alloc(T, m.len); |
| 202 | copy(T, new_buf, m); | 202 | copy(T, new_buf, m); |
| 203 | return new_buf; | 203 | return new_buf; |
| 204 | } | 204 | } |
| ... | @@ -425,7 +425,7 @@ pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 { | ... | @@ -425,7 +425,7 @@ pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 { |
| 425 | } | 425 | } |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | const buf = %return allocator.alloc(u8, total_strings_len); | 428 | const buf = try allocator.alloc(u8, total_strings_len); |
| 429 | %defer allocator.free(buf); | 429 | %defer allocator.free(buf); |
| 430 | 430 | ||
| 431 | var buf_index: usize = 0; | 431 | var buf_index: usize = 0; |
std/net.zig+1-1| ... | @@ -133,7 +133,7 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection { | ... | @@ -133,7 +133,7 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection { |
| 133 | 133 | ||
| 134 | pub fn connect(hostname: []const u8, port: u16) -> %Connection { | 134 | pub fn connect(hostname: []const u8, port: u16) -> %Connection { |
| 135 | var addrs_buf: [1]Address = undefined; | 135 | var addrs_buf: [1]Address = undefined; |
| 136 | const addrs_slice = %return lookup(hostname, addrs_buf[0..]); | 136 | const addrs_slice = try lookup(hostname, addrs_buf[0..]); |
| 137 | const main_addr = &addrs_slice[0]; | 137 | const main_addr = &addrs_slice[0]; |
| 138 | 138 | ||
| 139 | return connectAddr(main_addr, port); | 139 | return connectAddr(main_addr, port); |
std/os/child_process.zig+55-55| ... | @@ -75,7 +75,7 @@ pub const ChildProcess = struct { | ... | @@ -75,7 +75,7 @@ pub const ChildProcess = struct { |
| 75 | /// First argument in argv is the executable. | 75 | /// First argument in argv is the executable. |
| 76 | /// On success must call deinit. | 76 | /// On success must call deinit. |
| 77 | pub fn init(argv: []const []const u8, allocator: &mem.Allocator) -> %&ChildProcess { | 77 | pub fn init(argv: []const []const u8, allocator: &mem.Allocator) -> %&ChildProcess { |
| 78 | const child = %return allocator.create(ChildProcess); | 78 | const child = try allocator.create(ChildProcess); |
| 79 | %defer allocator.destroy(child); | 79 | %defer allocator.destroy(child); |
| 80 | 80 | ||
| 81 | *child = ChildProcess { | 81 | *child = ChildProcess { |
| ... | @@ -104,7 +104,7 @@ pub const ChildProcess = struct { | ... | @@ -104,7 +104,7 @@ pub const ChildProcess = struct { |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | pub fn setUserName(self: &ChildProcess, name: []const u8) -> %void { | 106 | pub fn setUserName(self: &ChildProcess, name: []const u8) -> %void { |
| 107 | const user_info = %return os.getUserInfo(name); | 107 | const user_info = try os.getUserInfo(name); |
| 108 | self.uid = user_info.uid; | 108 | self.uid = user_info.uid; |
| 109 | self.gid = user_info.gid; | 109 | self.gid = user_info.gid; |
| 110 | } | 110 | } |
| ... | @@ -120,7 +120,7 @@ pub const ChildProcess = struct { | ... | @@ -120,7 +120,7 @@ pub const ChildProcess = struct { |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | pub fn spawnAndWait(self: &ChildProcess) -> %Term { | 122 | pub fn spawnAndWait(self: &ChildProcess) -> %Term { |
| 123 | %return self.spawn(); | 123 | try self.spawn(); |
| 124 | return self.wait(); | 124 | return self.wait(); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| ... | @@ -200,7 +200,7 @@ pub const ChildProcess = struct { | ... | @@ -200,7 +200,7 @@ pub const ChildProcess = struct { |
| 200 | child.cwd = cwd; | 200 | child.cwd = cwd; |
| 201 | child.env_map = env_map; | 201 | child.env_map = env_map; |
| 202 | 202 | ||
| 203 | %return child.spawn(); | 203 | try child.spawn(); |
| 204 | 204 | ||
| 205 | var stdout = Buffer.initNull(allocator); | 205 | var stdout = Buffer.initNull(allocator); |
| 206 | var stderr = Buffer.initNull(allocator); | 206 | var stderr = Buffer.initNull(allocator); |
| ... | @@ -210,11 +210,11 @@ pub const ChildProcess = struct { | ... | @@ -210,11 +210,11 @@ pub const ChildProcess = struct { |
| 210 | var stdout_file_in_stream = io.FileInStream.init(&??child.stdout); | 210 | var stdout_file_in_stream = io.FileInStream.init(&??child.stdout); |
| 211 | var stderr_file_in_stream = io.FileInStream.init(&??child.stderr); | 211 | var stderr_file_in_stream = io.FileInStream.init(&??child.stderr); |
| 212 | 212 | ||
| 213 | %return stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size); | 213 | try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size); |
| 214 | %return stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size); | 214 | try stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size); |
| 215 | 215 | ||
| 216 | return ExecResult { | 216 | return ExecResult { |
| 217 | .term = %return child.wait(), | 217 | .term = try child.wait(), |
| 218 | .stdout = stdout.toOwnedSlice(), | 218 | .stdout = stdout.toOwnedSlice(), |
| 219 | .stderr = stderr.toOwnedSlice(), | 219 | .stderr = stderr.toOwnedSlice(), |
| 220 | }; | 220 | }; |
| ... | @@ -226,7 +226,7 @@ pub const ChildProcess = struct { | ... | @@ -226,7 +226,7 @@ pub const ChildProcess = struct { |
| 226 | return term; | 226 | return term; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | %return self.waitUnwrappedWindows(); | 229 | try self.waitUnwrappedWindows(); |
| 230 | return ??self.term; | 230 | return ??self.term; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| ... | @@ -308,8 +308,8 @@ pub const ChildProcess = struct { | ... | @@ -308,8 +308,8 @@ pub const ChildProcess = struct { |
| 308 | // pid potentially wrote an error. This way we can do a blocking | 308 | // pid potentially wrote an error. This way we can do a blocking |
| 309 | // read on the error pipe and either get @maxValue(ErrInt) (no error) or | 309 | // read on the error pipe and either get @maxValue(ErrInt) (no error) or |
| 310 | // an error code. | 310 | // an error code. |
| 311 | %return writeIntFd(self.err_pipe[1], @maxValue(ErrInt)); | 311 | try writeIntFd(self.err_pipe[1], @maxValue(ErrInt)); |
| 312 | const err_int = %return readIntFd(self.err_pipe[0]); | 312 | const err_int = try readIntFd(self.err_pipe[0]); |
| 313 | // Here we potentially return the fork child's error | 313 | // Here we potentially return the fork child's error |
| 314 | // from the parent pid. | 314 | // from the parent pid. |
| 315 | if (err_int != @maxValue(ErrInt)) { | 315 | if (err_int != @maxValue(ErrInt)) { |
| ... | @@ -335,18 +335,18 @@ pub const ChildProcess = struct { | ... | @@ -335,18 +335,18 @@ pub const ChildProcess = struct { |
| 335 | // TODO atomically set a flag saying that we already did this | 335 | // TODO atomically set a flag saying that we already did this |
| 336 | install_SIGCHLD_handler(); | 336 | install_SIGCHLD_handler(); |
| 337 | 337 | ||
| 338 | const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) %return makePipe() else undefined; | 338 | const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined; |
| 339 | %defer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); }; | 339 | %defer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); }; |
| 340 | 340 | ||
| 341 | const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) %return makePipe() else undefined; | 341 | const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try makePipe() else undefined; |
| 342 | %defer if (self.stdout_behavior == StdIo.Pipe) { destroyPipe(stdout_pipe); }; | 342 | %defer if (self.stdout_behavior == StdIo.Pipe) { destroyPipe(stdout_pipe); }; |
| 343 | 343 | ||
| 344 | const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) %return makePipe() else undefined; | 344 | const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try makePipe() else undefined; |
| 345 | %defer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); }; | 345 | %defer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); }; |
| 346 | 346 | ||
| 347 | const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); | 347 | const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); |
| 348 | const dev_null_fd = if (any_ignore) | 348 | const dev_null_fd = if (any_ignore) |
| 349 | %return os.posixOpen("/dev/null", posix.O_RDWR, 0, null) | 349 | try os.posixOpen("/dev/null", posix.O_RDWR, 0, null) |
| 350 | else | 350 | else |
| 351 | undefined | 351 | undefined |
| 352 | ; | 352 | ; |
| ... | @@ -359,14 +359,14 @@ pub const ChildProcess = struct { | ... | @@ -359,14 +359,14 @@ pub const ChildProcess = struct { |
| 359 | break :x env_map; | 359 | break :x env_map; |
| 360 | } else x: { | 360 | } else x: { |
| 361 | we_own_env_map = true; | 361 | we_own_env_map = true; |
| 362 | env_map_owned = %return os.getEnvMap(self.allocator); | 362 | env_map_owned = try os.getEnvMap(self.allocator); |
| 363 | break :x &env_map_owned; | 363 | break :x &env_map_owned; |
| 364 | }; | 364 | }; |
| 365 | defer { if (we_own_env_map) env_map_owned.deinit(); } | 365 | defer { if (we_own_env_map) env_map_owned.deinit(); } |
| 366 | 366 | ||
| 367 | // This pipe is used to communicate errors between the time of fork | 367 | // This pipe is used to communicate errors between the time of fork |
| 368 | // and execve from the child process to the parent process. | 368 | // and execve from the child process to the parent process. |
| 369 | const err_pipe = %return makePipe(); | 369 | const err_pipe = try makePipe(); |
| 370 | %defer destroyPipe(err_pipe); | 370 | %defer destroyPipe(err_pipe); |
| 371 | 371 | ||
| 372 | block_SIGCHLD(); | 372 | block_SIGCHLD(); |
| ... | @@ -383,27 +383,27 @@ pub const ChildProcess = struct { | ... | @@ -383,27 +383,27 @@ pub const ChildProcess = struct { |
| 383 | // we are the child | 383 | // we are the child |
| 384 | restore_SIGCHLD(); | 384 | restore_SIGCHLD(); |
| 385 | 385 | ||
| 386 | setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) %% | 386 | setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |
| 387 | |err| forkChildErrReport(err_pipe[1], err); | 387 | |err| forkChildErrReport(err_pipe[1], err); |
| 388 | setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) %% | 388 | setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |
| 389 | |err| forkChildErrReport(err_pipe[1], err); | 389 | |err| forkChildErrReport(err_pipe[1], err); |
| 390 | setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) %% | 390 | setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |
| 391 | |err| forkChildErrReport(err_pipe[1], err); | 391 | |err| forkChildErrReport(err_pipe[1], err); |
| 392 | 392 | ||
| 393 | if (self.cwd) |cwd| { | 393 | if (self.cwd) |cwd| { |
| 394 | os.changeCurDir(self.allocator, cwd) %% | 394 | os.changeCurDir(self.allocator, cwd) catch |
| 395 | |err| forkChildErrReport(err_pipe[1], err); | 395 | |err| forkChildErrReport(err_pipe[1], err); |
| 396 | } | 396 | } |
| 397 | 397 | ||
| 398 | if (self.gid) |gid| { | 398 | if (self.gid) |gid| { |
| 399 | os.posix_setregid(gid, gid) %% |err| forkChildErrReport(err_pipe[1], err); | 399 | os.posix_setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err); |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | if (self.uid) |uid| { | 402 | if (self.uid) |uid| { |
| 403 | os.posix_setreuid(uid, uid) %% |err| forkChildErrReport(err_pipe[1], err); | 403 | os.posix_setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err); |
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | os.posixExecve(self.argv, env_map, self.allocator) %% | 406 | os.posixExecve(self.argv, env_map, self.allocator) catch |
| 407 | |err| forkChildErrReport(err_pipe[1], err); | 407 | |err| forkChildErrReport(err_pipe[1], err); |
| 408 | } | 408 | } |
| 409 | 409 | ||
| ... | @@ -452,14 +452,14 @@ pub const ChildProcess = struct { | ... | @@ -452,14 +452,14 @@ pub const ChildProcess = struct { |
| 452 | self.stderr_behavior == StdIo.Ignore); | 452 | self.stderr_behavior == StdIo.Ignore); |
| 453 | 453 | ||
| 454 | const nul_handle = if (any_ignore) | 454 | const nul_handle = if (any_ignore) |
| 455 | %return os.windowsOpen("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, | 455 | try os.windowsOpen("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, |
| 456 | windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null) | 456 | windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null) |
| 457 | else | 457 | else |
| 458 | undefined | 458 | undefined |
| 459 | ; | 459 | ; |
| 460 | defer { if (any_ignore) os.close(nul_handle); } | 460 | defer { if (any_ignore) os.close(nul_handle); } |
| 461 | if (any_ignore) { | 461 | if (any_ignore) { |
| 462 | %return windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0); | 462 | try windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0); |
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | 465 | ||
| ... | @@ -467,7 +467,7 @@ pub const ChildProcess = struct { | ... | @@ -467,7 +467,7 @@ pub const ChildProcess = struct { |
| 467 | var g_hChildStd_IN_Wr: ?windows.HANDLE = null; | 467 | var g_hChildStd_IN_Wr: ?windows.HANDLE = null; |
| 468 | switch (self.stdin_behavior) { | 468 | switch (self.stdin_behavior) { |
| 469 | StdIo.Pipe => { | 469 | StdIo.Pipe => { |
| 470 | %return windowsMakePipeIn(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, saAttr); | 470 | try windowsMakePipeIn(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, saAttr); |
| 471 | }, | 471 | }, |
| 472 | StdIo.Ignore => { | 472 | StdIo.Ignore => { |
| 473 | g_hChildStd_IN_Rd = nul_handle; | 473 | g_hChildStd_IN_Rd = nul_handle; |
| ... | @@ -485,7 +485,7 @@ pub const ChildProcess = struct { | ... | @@ -485,7 +485,7 @@ pub const ChildProcess = struct { |
| 485 | var g_hChildStd_OUT_Wr: ?windows.HANDLE = null; | 485 | var g_hChildStd_OUT_Wr: ?windows.HANDLE = null; |
| 486 | switch (self.stdout_behavior) { | 486 | switch (self.stdout_behavior) { |
| 487 | StdIo.Pipe => { | 487 | StdIo.Pipe => { |
| 488 | %return windowsMakePipeOut(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, saAttr); | 488 | try windowsMakePipeOut(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, saAttr); |
| 489 | }, | 489 | }, |
| 490 | StdIo.Ignore => { | 490 | StdIo.Ignore => { |
| 491 | g_hChildStd_OUT_Wr = nul_handle; | 491 | g_hChildStd_OUT_Wr = nul_handle; |
| ... | @@ -503,7 +503,7 @@ pub const ChildProcess = struct { | ... | @@ -503,7 +503,7 @@ pub const ChildProcess = struct { |
| 503 | var g_hChildStd_ERR_Wr: ?windows.HANDLE = null; | 503 | var g_hChildStd_ERR_Wr: ?windows.HANDLE = null; |
| 504 | switch (self.stderr_behavior) { | 504 | switch (self.stderr_behavior) { |
| 505 | StdIo.Pipe => { | 505 | StdIo.Pipe => { |
| 506 | %return windowsMakePipeOut(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, saAttr); | 506 | try windowsMakePipeOut(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, saAttr); |
| 507 | }, | 507 | }, |
| 508 | StdIo.Ignore => { | 508 | StdIo.Ignore => { |
| 509 | g_hChildStd_ERR_Wr = nul_handle; | 509 | g_hChildStd_ERR_Wr = nul_handle; |
| ... | @@ -517,7 +517,7 @@ pub const ChildProcess = struct { | ... | @@ -517,7 +517,7 @@ pub const ChildProcess = struct { |
| 517 | } | 517 | } |
| 518 | %defer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr); }; | 518 | %defer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr); }; |
| 519 | 519 | ||
| 520 | const cmd_line = %return windowsCreateCommandLine(self.allocator, self.argv); | 520 | const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv); |
| 521 | defer self.allocator.free(cmd_line); | 521 | defer self.allocator.free(cmd_line); |
| 522 | 522 | ||
| 523 | var siStartInfo = windows.STARTUPINFOA { | 523 | var siStartInfo = windows.STARTUPINFOA { |
| ... | @@ -544,7 +544,7 @@ pub const ChildProcess = struct { | ... | @@ -544,7 +544,7 @@ pub const ChildProcess = struct { |
| 544 | var piProcInfo: windows.PROCESS_INFORMATION = undefined; | 544 | var piProcInfo: windows.PROCESS_INFORMATION = undefined; |
| 545 | 545 | ||
| 546 | const cwd_slice = if (self.cwd) |cwd| | 546 | const cwd_slice = if (self.cwd) |cwd| |
| 547 | %return cstr.addNullByte(self.allocator, cwd) | 547 | try cstr.addNullByte(self.allocator, cwd) |
| 548 | else | 548 | else |
| 549 | null | 549 | null |
| 550 | ; | 550 | ; |
| ... | @@ -552,7 +552,7 @@ pub const ChildProcess = struct { | ... | @@ -552,7 +552,7 @@ pub const ChildProcess = struct { |
| 552 | const cwd_ptr = if (cwd_slice) |cwd| cwd.ptr else null; | 552 | const cwd_ptr = if (cwd_slice) |cwd| cwd.ptr else null; |
| 553 | 553 | ||
| 554 | const maybe_envp_buf = if (self.env_map) |env_map| | 554 | const maybe_envp_buf = if (self.env_map) |env_map| |
| 555 | %return os.createWindowsEnvBlock(self.allocator, env_map) | 555 | try os.createWindowsEnvBlock(self.allocator, env_map) |
| 556 | else | 556 | else |
| 557 | null | 557 | null |
| 558 | ; | 558 | ; |
| ... | @@ -563,27 +563,27 @@ pub const ChildProcess = struct { | ... | @@ -563,27 +563,27 @@ pub const ChildProcess = struct { |
| 563 | // to match posix semantics | 563 | // to match posix semantics |
| 564 | const app_name = x: { | 564 | const app_name = x: { |
| 565 | if (self.cwd) |cwd| { | 565 | if (self.cwd) |cwd| { |
| 566 | const resolved = %return os.path.resolve(self.allocator, cwd, self.argv[0]); | 566 | const resolved = try os.path.resolve(self.allocator, cwd, self.argv[0]); |
| 567 | defer self.allocator.free(resolved); | 567 | defer self.allocator.free(resolved); |
| 568 | break :x %return cstr.addNullByte(self.allocator, resolved); | 568 | break :x try cstr.addNullByte(self.allocator, resolved); |
| 569 | } else { | 569 | } else { |
| 570 | break :x %return cstr.addNullByte(self.allocator, self.argv[0]); | 570 | break :x try cstr.addNullByte(self.allocator, self.argv[0]); |
| 571 | } | 571 | } |
| 572 | }; | 572 | }; |
| 573 | defer self.allocator.free(app_name); | 573 | defer self.allocator.free(app_name); |
| 574 | 574 | ||
| 575 | windowsCreateProcess(app_name.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, | 575 | windowsCreateProcess(app_name.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, |
| 576 | &siStartInfo, &piProcInfo) %% |no_path_err| | 576 | &siStartInfo, &piProcInfo) catch |no_path_err| |
| 577 | { | 577 | { |
| 578 | if (no_path_err != error.FileNotFound) | 578 | if (no_path_err != error.FileNotFound) |
| 579 | return no_path_err; | 579 | return no_path_err; |
| 580 | 580 | ||
| 581 | const PATH = %return os.getEnvVarOwned(self.allocator, "PATH"); | 581 | const PATH = try os.getEnvVarOwned(self.allocator, "PATH"); |
| 582 | defer self.allocator.free(PATH); | 582 | defer self.allocator.free(PATH); |
| 583 | 583 | ||
| 584 | var it = mem.split(PATH, ";"); | 584 | var it = mem.split(PATH, ";"); |
| 585 | while (it.next()) |search_path| { | 585 | while (it.next()) |search_path| { |
| 586 | const joined_path = %return os.path.join(self.allocator, search_path, app_name); | 586 | const joined_path = try os.path.join(self.allocator, search_path, app_name); |
| 587 | defer self.allocator.free(joined_path); | 587 | defer self.allocator.free(joined_path); |
| 588 | 588 | ||
| 589 | if (windowsCreateProcess(joined_path.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, | 589 | if (windowsCreateProcess(joined_path.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, |
| ... | @@ -625,10 +625,10 @@ pub const ChildProcess = struct { | ... | @@ -625,10 +625,10 @@ pub const ChildProcess = struct { |
| 625 | 625 | ||
| 626 | fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) -> %void { | 626 | fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) -> %void { |
| 627 | switch (stdio) { | 627 | switch (stdio) { |
| 628 | StdIo.Pipe => %return os.posixDup2(pipe_fd, std_fileno), | 628 | StdIo.Pipe => try os.posixDup2(pipe_fd, std_fileno), |
| 629 | StdIo.Close => os.close(std_fileno), | 629 | StdIo.Close => os.close(std_fileno), |
| 630 | StdIo.Inherit => {}, | 630 | StdIo.Inherit => {}, |
| 631 | StdIo.Ignore => %return os.posixDup2(dev_null_fd, std_fileno), | 631 | StdIo.Ignore => try os.posixDup2(dev_null_fd, std_fileno), |
| 632 | } | 632 | } |
| 633 | } | 633 | } |
| 634 | 634 | ||
| ... | @@ -656,35 +656,35 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ? | ... | @@ -656,35 +656,35 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ? |
| 656 | /// Caller must dealloc. | 656 | /// Caller must dealloc. |
| 657 | /// Guarantees a null byte at result[result.len]. | 657 | /// Guarantees a null byte at result[result.len]. |
| 658 | fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) -> %[]u8 { | 658 | fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) -> %[]u8 { |
| 659 | var buf = %return Buffer.initSize(allocator, 0); | 659 | var buf = try Buffer.initSize(allocator, 0); |
| 660 | defer buf.deinit(); | 660 | defer buf.deinit(); |
| 661 | 661 | ||
| 662 | for (argv) |arg, arg_i| { | 662 | for (argv) |arg, arg_i| { |
| 663 | if (arg_i != 0) | 663 | if (arg_i != 0) |
| 664 | %return buf.appendByte(' '); | 664 | try buf.appendByte(' '); |
| 665 | if (mem.indexOfAny(u8, arg, " \t\n\"") == null) { | 665 | if (mem.indexOfAny(u8, arg, " \t\n\"") == null) { |
| 666 | %return buf.append(arg); | 666 | try buf.append(arg); |
| 667 | continue; | 667 | continue; |
| 668 | } | 668 | } |
| 669 | %return buf.appendByte('"'); | 669 | try buf.appendByte('"'); |
| 670 | var backslash_count: usize = 0; | 670 | var backslash_count: usize = 0; |
| 671 | for (arg) |byte| { | 671 | for (arg) |byte| { |
| 672 | switch (byte) { | 672 | switch (byte) { |
| 673 | '\\' => backslash_count += 1, | 673 | '\\' => backslash_count += 1, |
| 674 | '"' => { | 674 | '"' => { |
| 675 | %return buf.appendByteNTimes('\\', backslash_count * 2 + 1); | 675 | try buf.appendByteNTimes('\\', backslash_count * 2 + 1); |
| 676 | %return buf.appendByte('"'); | 676 | try buf.appendByte('"'); |
| 677 | backslash_count = 0; | 677 | backslash_count = 0; |
| 678 | }, | 678 | }, |
| 679 | else => { | 679 | else => { |
| 680 | %return buf.appendByteNTimes('\\', backslash_count); | 680 | try buf.appendByteNTimes('\\', backslash_count); |
| 681 | %return buf.appendByte(byte); | 681 | try buf.appendByte(byte); |
| 682 | backslash_count = 0; | 682 | backslash_count = 0; |
| 683 | }, | 683 | }, |
| 684 | } | 684 | } |
| 685 | } | 685 | } |
| 686 | %return buf.appendByteNTimes('\\', backslash_count * 2); | 686 | try buf.appendByteNTimes('\\', backslash_count * 2); |
| 687 | %return buf.appendByte('"'); | 687 | try buf.appendByte('"'); |
| 688 | } | 688 | } |
| 689 | 689 | ||
| 690 | return buf.toOwnedSlice(); | 690 | return buf.toOwnedSlice(); |
| ... | @@ -721,9 +721,9 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D | ... | @@ -721,9 +721,9 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D |
| 721 | fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void { | 721 | fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void { |
| 722 | var rd_h: windows.HANDLE = undefined; | 722 | var rd_h: windows.HANDLE = undefined; |
| 723 | var wr_h: windows.HANDLE = undefined; | 723 | var wr_h: windows.HANDLE = undefined; |
| 724 | %return windowsMakePipe(&rd_h, &wr_h, sattr); | 724 | try windowsMakePipe(&rd_h, &wr_h, sattr); |
| 725 | %defer windowsDestroyPipe(rd_h, wr_h); | 725 | %defer windowsDestroyPipe(rd_h, wr_h); |
| 726 | %return windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0); | 726 | try windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0); |
| 727 | *rd = rd_h; | 727 | *rd = rd_h; |
| 728 | *wr = wr_h; | 728 | *wr = wr_h; |
| 729 | } | 729 | } |
| ... | @@ -731,9 +731,9 @@ fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const S | ... | @@ -731,9 +731,9 @@ fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const S |
| 731 | fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void { | 731 | fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void { |
| 732 | var rd_h: windows.HANDLE = undefined; | 732 | var rd_h: windows.HANDLE = undefined; |
| 733 | var wr_h: windows.HANDLE = undefined; | 733 | var wr_h: windows.HANDLE = undefined; |
| 734 | %return windowsMakePipe(&rd_h, &wr_h, sattr); | 734 | try windowsMakePipe(&rd_h, &wr_h, sattr); |
| 735 | %defer windowsDestroyPipe(rd_h, wr_h); | 735 | %defer windowsDestroyPipe(rd_h, wr_h); |
| 736 | %return windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0); | 736 | try windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0); |
| 737 | *rd = rd_h; | 737 | *rd = rd_h; |
| 738 | *wr = wr_h; | 738 | *wr = wr_h; |
| 739 | } | 739 | } |
| ... | @@ -767,12 +767,12 @@ const ErrInt = @IntType(false, @sizeOf(error) * 8); | ... | @@ -767,12 +767,12 @@ const ErrInt = @IntType(false, @sizeOf(error) * 8); |
| 767 | fn writeIntFd(fd: i32, value: ErrInt) -> %void { | 767 | fn writeIntFd(fd: i32, value: ErrInt) -> %void { |
| 768 | var bytes: [@sizeOf(ErrInt)]u8 = undefined; | 768 | var bytes: [@sizeOf(ErrInt)]u8 = undefined; |
| 769 | mem.writeInt(bytes[0..], value, builtin.endian); | 769 | mem.writeInt(bytes[0..], value, builtin.endian); |
| 770 | os.posixWrite(fd, bytes[0..]) %% return error.SystemResources; | 770 | os.posixWrite(fd, bytes[0..]) catch return error.SystemResources; |
| 771 | } | 771 | } |
| 772 | 772 | ||
| 773 | fn readIntFd(fd: i32) -> %ErrInt { | 773 | fn readIntFd(fd: i32) -> %ErrInt { |
| 774 | var bytes: [@sizeOf(ErrInt)]u8 = undefined; | 774 | var bytes: [@sizeOf(ErrInt)]u8 = undefined; |
| 775 | os.posixRead(fd, bytes[0..]) %% return error.SystemResources; | 775 | os.posixRead(fd, bytes[0..]) catch return error.SystemResources; |
| 776 | return mem.readInt(bytes[0..], ErrInt, builtin.endian); | 776 | return mem.readInt(bytes[0..], ErrInt, builtin.endian); |
| 777 | } | 777 | } |
| 778 | 778 |
std/os/get_user_id.zig+3-3| ... | @@ -11,7 +11,7 @@ pub const UserInfo = struct { | ... | @@ -11,7 +11,7 @@ pub const UserInfo = struct { |
| 11 | /// POSIX function which gets a uid from username. | 11 | /// POSIX function which gets a uid from username. |
| 12 | pub fn getUserInfo(name: []const u8) -> %UserInfo { | 12 | pub fn getUserInfo(name: []const u8) -> %UserInfo { |
| 13 | return switch (builtin.os) { | 13 | return switch (builtin.os) { |
| 14 | Os.linux, Os.darwin, Os.macosx, Os.ios => posixGetUserInfo(name), | 14 | Os.linux, Os.macosx, Os.ios => posixGetUserInfo(name), |
| 15 | else => @compileError("Unsupported OS"), | 15 | else => @compileError("Unsupported OS"), |
| 16 | }; | 16 | }; |
| 17 | } | 17 | } |
| ... | @@ -31,7 +31,7 @@ error CorruptPasswordFile; | ... | @@ -31,7 +31,7 @@ error CorruptPasswordFile; |
| 31 | // like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`. | 31 | // like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`. |
| 32 | 32 | ||
| 33 | pub fn posixGetUserInfo(name: []const u8) -> %UserInfo { | 33 | pub fn posixGetUserInfo(name: []const u8) -> %UserInfo { |
| 34 | var in_stream = %return io.InStream.open("/etc/passwd", null); | 34 | var in_stream = try io.InStream.open("/etc/passwd", null); |
| 35 | defer in_stream.close(); | 35 | defer in_stream.close(); |
| 36 | 36 | ||
| 37 | var buf: [os.page_size]u8 = undefined; | 37 | var buf: [os.page_size]u8 = undefined; |
| ... | @@ -41,7 +41,7 @@ pub fn posixGetUserInfo(name: []const u8) -> %UserInfo { | ... | @@ -41,7 +41,7 @@ pub fn posixGetUserInfo(name: []const u8) -> %UserInfo { |
| 41 | var gid: u32 = 0; | 41 | var gid: u32 = 0; |
| 42 | 42 | ||
| 43 | while (true) { | 43 | while (true) { |
| 44 | const amt_read = %return in_stream.read(buf[0..]); | 44 | const amt_read = try in_stream.read(buf[0..]); |
| 45 | for (buf[0..amt_read]) |byte| { | 45 | for (buf[0..amt_read]) |byte| { |
| 46 | switch (state) { | 46 | switch (state) { |
| 47 | State.Start => switch (byte) { | 47 | State.Start => switch (byte) { |
std/os/index.zig+81-79| ... | @@ -7,9 +7,11 @@ const os = this; | ... | @@ -7,9 +7,11 @@ const os = this; |
| 7 | pub const windows = @import("windows/index.zig"); | 7 | pub const windows = @import("windows/index.zig"); |
| 8 | pub const darwin = @import("darwin.zig"); | 8 | pub const darwin = @import("darwin.zig"); |
| 9 | pub const linux = @import("linux.zig"); | 9 | pub const linux = @import("linux.zig"); |
| 10 | pub const zen = @import("zen.zig"); | ||
| 10 | pub const posix = switch(builtin.os) { | 11 | pub const posix = switch(builtin.os) { |
| 11 | Os.linux => linux, | 12 | Os.linux => linux, |
| 12 | Os.darwin, Os.macosx, Os.ios => darwin, | 13 | Os.macosx, Os.ios => darwin, |
| 14 | Os.zen => zen, | ||
| 13 | else => @compileError("Unsupported OS"), | 15 | else => @compileError("Unsupported OS"), |
| 14 | }; | 16 | }; |
| 15 | 17 | ||
| ... | @@ -89,12 +91,12 @@ pub fn getRandomBytes(buf: []u8) -> %void { | ... | @@ -89,12 +91,12 @@ pub fn getRandomBytes(buf: []u8) -> %void { |
| 89 | } | 91 | } |
| 90 | return; | 92 | return; |
| 91 | }, | 93 | }, |
| 92 | Os.darwin, Os.macosx, Os.ios => { | 94 | Os.macosx, Os.ios => { |
| 93 | const fd = %return posixOpen("/dev/urandom", posix.O_RDONLY|posix.O_CLOEXEC, | 95 | const fd = try posixOpen("/dev/urandom", posix.O_RDONLY|posix.O_CLOEXEC, |
| 94 | 0, null); | 96 | 0, null); |
| 95 | defer close(fd); | 97 | defer close(fd); |
| 96 | 98 | ||
| 97 | %return posixRead(fd, buf); | 99 | try posixRead(fd, buf); |
| 98 | }, | 100 | }, |
| 99 | Os.windows => { | 101 | Os.windows => { |
| 100 | var hCryptProv: windows.HCRYPTPROV = undefined; | 102 | var hCryptProv: windows.HCRYPTPROV = undefined; |
| ... | @@ -130,7 +132,7 @@ pub coldcc fn abort() -> noreturn { | ... | @@ -130,7 +132,7 @@ pub coldcc fn abort() -> noreturn { |
| 130 | c.abort(); | 132 | c.abort(); |
| 131 | } | 133 | } |
| 132 | switch (builtin.os) { | 134 | switch (builtin.os) { |
| 133 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | 135 | Os.linux, Os.macosx, Os.ios => { |
| 134 | _ = posix.raise(posix.SIGABRT); | 136 | _ = posix.raise(posix.SIGABRT); |
| 135 | _ = posix.raise(posix.SIGKILL); | 137 | _ = posix.raise(posix.SIGKILL); |
| 136 | while (true) {} | 138 | while (true) {} |
| ... | @@ -151,7 +153,7 @@ pub coldcc fn exit(status: i32) -> noreturn { | ... | @@ -151,7 +153,7 @@ pub coldcc fn exit(status: i32) -> noreturn { |
| 151 | c.exit(status); | 153 | c.exit(status); |
| 152 | } | 154 | } |
| 153 | switch (builtin.os) { | 155 | switch (builtin.os) { |
| 154 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | 156 | Os.linux, Os.macosx, Os.ios => { |
| 155 | posix.exit(status); | 157 | posix.exit(status); |
| 156 | }, | 158 | }, |
| 157 | Os.windows => { | 159 | Os.windows => { |
| ... | @@ -254,7 +256,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al | ... | @@ -254,7 +256,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al |
| 254 | if (file_path.len < stack_buf.len) { | 256 | if (file_path.len < stack_buf.len) { |
| 255 | path0 = stack_buf[0..file_path.len + 1]; | 257 | path0 = stack_buf[0..file_path.len + 1]; |
| 256 | } else if (allocator) |a| { | 258 | } else if (allocator) |a| { |
| 257 | path0 = %return a.alloc(u8, file_path.len + 1); | 259 | path0 = try a.alloc(u8, file_path.len + 1); |
| 258 | need_free = true; | 260 | need_free = true; |
| 259 | } else { | 261 | } else { |
| 260 | return error.NameTooLong; | 262 | return error.NameTooLong; |
| ... | @@ -312,14 +314,14 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void { | ... | @@ -312,14 +314,14 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void { |
| 312 | 314 | ||
| 313 | pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) -> %[]?&u8 { | 315 | pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) -> %[]?&u8 { |
| 314 | const envp_count = env_map.count(); | 316 | const envp_count = env_map.count(); |
| 315 | const envp_buf = %return allocator.alloc(?&u8, envp_count + 1); | 317 | const envp_buf = try allocator.alloc(?&u8, envp_count + 1); |
| 316 | mem.set(?&u8, envp_buf, null); | 318 | mem.set(?&u8, envp_buf, null); |
| 317 | %defer freeNullDelimitedEnvMap(allocator, envp_buf); | 319 | %defer freeNullDelimitedEnvMap(allocator, envp_buf); |
| 318 | { | 320 | { |
| 319 | var it = env_map.iterator(); | 321 | var it = env_map.iterator(); |
| 320 | var i: usize = 0; | 322 | var i: usize = 0; |
| 321 | while (it.next()) |pair| : (i += 1) { | 323 | while (it.next()) |pair| : (i += 1) { |
| 322 | const env_buf = %return allocator.alloc(u8, pair.key.len + pair.value.len + 2); | 324 | const env_buf = try allocator.alloc(u8, pair.key.len + pair.value.len + 2); |
| 323 | @memcpy(&env_buf[0], pair.key.ptr, pair.key.len); | 325 | @memcpy(&env_buf[0], pair.key.ptr, pair.key.len); |
| 324 | env_buf[pair.key.len] = '='; | 326 | env_buf[pair.key.len] = '='; |
| 325 | @memcpy(&env_buf[pair.key.len + 1], pair.value.ptr, pair.value.len); | 327 | @memcpy(&env_buf[pair.key.len + 1], pair.value.ptr, pair.value.len); |
| ... | @@ -349,7 +351,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) { | ... | @@ -349,7 +351,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) { |
| 349 | pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, | 351 | pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, |
| 350 | allocator: &Allocator) -> %void | 352 | allocator: &Allocator) -> %void |
| 351 | { | 353 | { |
| 352 | const argv_buf = %return allocator.alloc(?&u8, argv.len + 1); | 354 | const argv_buf = try allocator.alloc(?&u8, argv.len + 1); |
| 353 | mem.set(?&u8, argv_buf, null); | 355 | mem.set(?&u8, argv_buf, null); |
| 354 | defer { | 356 | defer { |
| 355 | for (argv_buf) |arg| { | 357 | for (argv_buf) |arg| { |
| ... | @@ -359,7 +361,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, | ... | @@ -359,7 +361,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, |
| 359 | allocator.free(argv_buf); | 361 | allocator.free(argv_buf); |
| 360 | } | 362 | } |
| 361 | for (argv) |arg, i| { | 363 | for (argv) |arg, i| { |
| 362 | const arg_buf = %return allocator.alloc(u8, arg.len + 1); | 364 | const arg_buf = try allocator.alloc(u8, arg.len + 1); |
| 363 | @memcpy(&arg_buf[0], arg.ptr, arg.len); | 365 | @memcpy(&arg_buf[0], arg.ptr, arg.len); |
| 364 | arg_buf[arg.len] = 0; | 366 | arg_buf[arg.len] = 0; |
| 365 | 367 | ||
| ... | @@ -367,7 +369,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, | ... | @@ -367,7 +369,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, |
| 367 | } | 369 | } |
| 368 | argv_buf[argv.len] = null; | 370 | argv_buf[argv.len] = null; |
| 369 | 371 | ||
| 370 | const envp_buf = %return createNullDelimitedEnvMap(allocator, env_map); | 372 | const envp_buf = try createNullDelimitedEnvMap(allocator, env_map); |
| 371 | defer freeNullDelimitedEnvMap(allocator, envp_buf); | 373 | defer freeNullDelimitedEnvMap(allocator, envp_buf); |
| 372 | 374 | ||
| 373 | const exe_path = argv[0]; | 375 | const exe_path = argv[0]; |
| ... | @@ -379,7 +381,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, | ... | @@ -379,7 +381,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, |
| 379 | // PATH.len because it is >= the largest search_path | 381 | // PATH.len because it is >= the largest search_path |
| 380 | // +1 for the / to join the search path and exe_path | 382 | // +1 for the / to join the search path and exe_path |
| 381 | // +1 for the null terminating byte | 383 | // +1 for the null terminating byte |
| 382 | const path_buf = %return allocator.alloc(u8, PATH.len + exe_path.len + 2); | 384 | const path_buf = try allocator.alloc(u8, PATH.len + exe_path.len + 2); |
| 383 | defer allocator.free(path_buf); | 385 | defer allocator.free(path_buf); |
| 384 | var it = mem.split(PATH, ":"); | 386 | var it = mem.split(PATH, ":"); |
| 385 | var seen_eacces = false; | 387 | var seen_eacces = false; |
| ... | @@ -448,7 +450,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap { | ... | @@ -448,7 +450,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap { |
| 448 | 450 | ||
| 449 | i += 1; // skip over null byte | 451 | i += 1; // skip over null byte |
| 450 | 452 | ||
| 451 | %return result.set(key, value); | 453 | try result.set(key, value); |
| 452 | } | 454 | } |
| 453 | } else { | 455 | } else { |
| 454 | for (posix_environ_raw) |ptr| { | 456 | for (posix_environ_raw) |ptr| { |
| ... | @@ -460,7 +462,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap { | ... | @@ -460,7 +462,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap { |
| 460 | while (ptr[end_i] != 0) : (end_i += 1) {} | 462 | while (ptr[end_i] != 0) : (end_i += 1) {} |
| 461 | const value = ptr[line_i + 1..end_i]; | 463 | const value = ptr[line_i + 1..end_i]; |
| 462 | 464 | ||
| 463 | %return result.set(key, value); | 465 | try result.set(key, value); |
| 464 | } | 466 | } |
| 465 | return result; | 467 | return result; |
| 466 | } | 468 | } |
| ... | @@ -488,14 +490,14 @@ error EnvironmentVariableNotFound; | ... | @@ -488,14 +490,14 @@ error EnvironmentVariableNotFound; |
| 488 | /// Caller must free returned memory. | 490 | /// Caller must free returned memory. |
| 489 | pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { | 491 | pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { |
| 490 | if (is_windows) { | 492 | if (is_windows) { |
| 491 | const key_with_null = %return cstr.addNullByte(allocator, key); | 493 | const key_with_null = try cstr.addNullByte(allocator, key); |
| 492 | defer allocator.free(key_with_null); | 494 | defer allocator.free(key_with_null); |
| 493 | 495 | ||
| 494 | var buf = %return allocator.alloc(u8, 256); | 496 | var buf = try allocator.alloc(u8, 256); |
| 495 | %defer allocator.free(buf); | 497 | %defer allocator.free(buf); |
| 496 | 498 | ||
| 497 | while (true) { | 499 | while (true) { |
| 498 | const windows_buf_len = %return math.cast(windows.DWORD, buf.len); | 500 | const windows_buf_len = try math.cast(windows.DWORD, buf.len); |
| 499 | const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len); | 501 | const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len); |
| 500 | 502 | ||
| 501 | if (result == 0) { | 503 | if (result == 0) { |
| ... | @@ -507,7 +509,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { | ... | @@ -507,7 +509,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { |
| 507 | } | 509 | } |
| 508 | 510 | ||
| 509 | if (result > buf.len) { | 511 | if (result > buf.len) { |
| 510 | buf = %return allocator.realloc(u8, buf, result); | 512 | buf = try allocator.realloc(u8, buf, result); |
| 511 | continue; | 513 | continue; |
| 512 | } | 514 | } |
| 513 | 515 | ||
| ... | @@ -523,7 +525,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { | ... | @@ -523,7 +525,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { |
| 523 | pub fn getCwd(allocator: &Allocator) -> %[]u8 { | 525 | pub fn getCwd(allocator: &Allocator) -> %[]u8 { |
| 524 | switch (builtin.os) { | 526 | switch (builtin.os) { |
| 525 | Os.windows => { | 527 | Os.windows => { |
| 526 | var buf = %return allocator.alloc(u8, 256); | 528 | var buf = try allocator.alloc(u8, 256); |
| 527 | %defer allocator.free(buf); | 529 | %defer allocator.free(buf); |
| 528 | 530 | ||
| 529 | while (true) { | 531 | while (true) { |
| ... | @@ -537,7 +539,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 { | ... | @@ -537,7 +539,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 { |
| 537 | } | 539 | } |
| 538 | 540 | ||
| 539 | if (result > buf.len) { | 541 | if (result > buf.len) { |
| 540 | buf = %return allocator.realloc(u8, buf, result); | 542 | buf = try allocator.realloc(u8, buf, result); |
| 541 | continue; | 543 | continue; |
| 542 | } | 544 | } |
| 543 | 545 | ||
| ... | @@ -545,12 +547,12 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 { | ... | @@ -545,12 +547,12 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 { |
| 545 | } | 547 | } |
| 546 | }, | 548 | }, |
| 547 | else => { | 549 | else => { |
| 548 | var buf = %return allocator.alloc(u8, 1024); | 550 | var buf = try allocator.alloc(u8, 1024); |
| 549 | %defer allocator.free(buf); | 551 | %defer allocator.free(buf); |
| 550 | while (true) { | 552 | while (true) { |
| 551 | const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len)); | 553 | const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len)); |
| 552 | if (err == posix.ERANGE) { | 554 | if (err == posix.ERANGE) { |
| 553 | buf = %return allocator.realloc(u8, buf, buf.len * 2); | 555 | buf = try allocator.realloc(u8, buf, buf.len * 2); |
| 554 | continue; | 556 | continue; |
| 555 | } else if (err > 0) { | 557 | } else if (err > 0) { |
| 556 | return unexpectedErrorPosix(err); | 558 | return unexpectedErrorPosix(err); |
| ... | @@ -576,9 +578,9 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con | ... | @@ -576,9 +578,9 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con |
| 576 | } | 578 | } |
| 577 | 579 | ||
| 578 | pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void { | 580 | pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void { |
| 579 | const existing_with_null = %return cstr.addNullByte(allocator, existing_path); | 581 | const existing_with_null = try cstr.addNullByte(allocator, existing_path); |
| 580 | defer allocator.free(existing_with_null); | 582 | defer allocator.free(existing_with_null); |
| 581 | const new_with_null = %return cstr.addNullByte(allocator, new_path); | 583 | const new_with_null = try cstr.addNullByte(allocator, new_path); |
| 582 | defer allocator.free(new_with_null); | 584 | defer allocator.free(new_with_null); |
| 583 | 585 | ||
| 584 | if (windows.CreateSymbolicLinkA(existing_with_null.ptr, new_with_null.ptr, 0) == 0) { | 586 | if (windows.CreateSymbolicLinkA(existing_with_null.ptr, new_with_null.ptr, 0) == 0) { |
| ... | @@ -590,7 +592,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path | ... | @@ -590,7 +592,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path |
| 590 | } | 592 | } |
| 591 | 593 | ||
| 592 | pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void { | 594 | pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void { |
| 593 | const full_buf = %return allocator.alloc(u8, existing_path.len + new_path.len + 2); | 595 | const full_buf = try allocator.alloc(u8, existing_path.len + new_path.len + 2); |
| 594 | defer allocator.free(full_buf); | 596 | defer allocator.free(full_buf); |
| 595 | 597 | ||
| 596 | const existing_buf = full_buf; | 598 | const existing_buf = full_buf; |
| ... | @@ -636,11 +638,11 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: | ... | @@ -636,11 +638,11 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: |
| 636 | } | 638 | } |
| 637 | 639 | ||
| 638 | var rand_buf: [12]u8 = undefined; | 640 | var rand_buf: [12]u8 = undefined; |
| 639 | const tmp_path = %return allocator.alloc(u8, new_path.len + base64.Base64Encoder.calcSize(rand_buf.len)); | 641 | const tmp_path = try allocator.alloc(u8, new_path.len + base64.Base64Encoder.calcSize(rand_buf.len)); |
| 640 | defer allocator.free(tmp_path); | 642 | defer allocator.free(tmp_path); |
| 641 | mem.copy(u8, tmp_path[0..], new_path); | 643 | mem.copy(u8, tmp_path[0..], new_path); |
| 642 | while (true) { | 644 | while (true) { |
| 643 | %return getRandomBytes(rand_buf[0..]); | 645 | try getRandomBytes(rand_buf[0..]); |
| 644 | b64_fs_encoder.encode(tmp_path[new_path.len..], rand_buf); | 646 | b64_fs_encoder.encode(tmp_path[new_path.len..], rand_buf); |
| 645 | if (symLink(allocator, existing_path, tmp_path)) { | 647 | if (symLink(allocator, existing_path, tmp_path)) { |
| 646 | return rename(allocator, tmp_path, new_path); | 648 | return rename(allocator, tmp_path, new_path); |
| ... | @@ -667,7 +669,7 @@ error FileNotFound; | ... | @@ -667,7 +669,7 @@ error FileNotFound; |
| 667 | error AccessDenied; | 669 | error AccessDenied; |
| 668 | 670 | ||
| 669 | pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void { | 671 | pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void { |
| 670 | const buf = %return allocator.alloc(u8, file_path.len + 1); | 672 | const buf = try allocator.alloc(u8, file_path.len + 1); |
| 671 | defer allocator.free(buf); | 673 | defer allocator.free(buf); |
| 672 | 674 | ||
| 673 | mem.copy(u8, buf, file_path); | 675 | mem.copy(u8, buf, file_path); |
| ... | @@ -685,7 +687,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void | ... | @@ -685,7 +687,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void |
| 685 | } | 687 | } |
| 686 | 688 | ||
| 687 | pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void { | 689 | pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void { |
| 688 | const buf = %return allocator.alloc(u8, file_path.len + 1); | 690 | const buf = try allocator.alloc(u8, file_path.len + 1); |
| 689 | defer allocator.free(buf); | 691 | defer allocator.free(buf); |
| 690 | 692 | ||
| 691 | mem.copy(u8, buf, file_path); | 693 | mem.copy(u8, buf, file_path); |
| ... | @@ -719,30 +721,30 @@ pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []con | ... | @@ -719,30 +721,30 @@ pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []con |
| 719 | /// Guaranteed to be atomic. | 721 | /// Guaranteed to be atomic. |
| 720 | pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) -> %void { | 722 | pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) -> %void { |
| 721 | var rand_buf: [12]u8 = undefined; | 723 | var rand_buf: [12]u8 = undefined; |
| 722 | const tmp_path = %return allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len)); | 724 | const tmp_path = try allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len)); |
| 723 | defer allocator.free(tmp_path); | 725 | defer allocator.free(tmp_path); |
| 724 | mem.copy(u8, tmp_path[0..], dest_path); | 726 | mem.copy(u8, tmp_path[0..], dest_path); |
| 725 | %return getRandomBytes(rand_buf[0..]); | 727 | try getRandomBytes(rand_buf[0..]); |
| 726 | b64_fs_encoder.encode(tmp_path[dest_path.len..], rand_buf); | 728 | b64_fs_encoder.encode(tmp_path[dest_path.len..], rand_buf); |
| 727 | 729 | ||
| 728 | var out_file = %return io.File.openWriteMode(tmp_path, mode, allocator); | 730 | var out_file = try io.File.openWriteMode(tmp_path, mode, allocator); |
| 729 | defer out_file.close(); | 731 | defer out_file.close(); |
| 730 | %defer _ = deleteFile(allocator, tmp_path); | 732 | %defer _ = deleteFile(allocator, tmp_path); |
| 731 | 733 | ||
| 732 | var in_file = %return io.File.openRead(source_path, allocator); | 734 | var in_file = try io.File.openRead(source_path, allocator); |
| 733 | defer in_file.close(); | 735 | defer in_file.close(); |
| 734 | 736 | ||
| 735 | var buf: [page_size]u8 = undefined; | 737 | var buf: [page_size]u8 = undefined; |
| 736 | while (true) { | 738 | while (true) { |
| 737 | const amt = %return in_file.read(buf[0..]); | 739 | const amt = try in_file.read(buf[0..]); |
| 738 | %return out_file.write(buf[0..amt]); | 740 | try out_file.write(buf[0..amt]); |
| 739 | if (amt != buf.len) | 741 | if (amt != buf.len) |
| 740 | return rename(allocator, tmp_path, dest_path); | 742 | return rename(allocator, tmp_path, dest_path); |
| 741 | } | 743 | } |
| 742 | } | 744 | } |
| 743 | 745 | ||
| 744 | pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) -> %void { | 746 | pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) -> %void { |
| 745 | const full_buf = %return allocator.alloc(u8, old_path.len + new_path.len + 2); | 747 | const full_buf = try allocator.alloc(u8, old_path.len + new_path.len + 2); |
| 746 | defer allocator.free(full_buf); | 748 | defer allocator.free(full_buf); |
| 747 | 749 | ||
| 748 | const old_buf = full_buf; | 750 | const old_buf = full_buf; |
| ... | @@ -795,7 +797,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void { | ... | @@ -795,7 +797,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 795 | } | 797 | } |
| 796 | 798 | ||
| 797 | pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void { | 799 | pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 798 | const path_buf = %return cstr.addNullByte(allocator, dir_path); | 800 | const path_buf = try cstr.addNullByte(allocator, dir_path); |
| 799 | defer allocator.free(path_buf); | 801 | defer allocator.free(path_buf); |
| 800 | 802 | ||
| 801 | if (windows.CreateDirectoryA(path_buf.ptr, null) == 0) { | 803 | if (windows.CreateDirectoryA(path_buf.ptr, null) == 0) { |
| ... | @@ -809,7 +811,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void { | ... | @@ -809,7 +811,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 809 | } | 811 | } |
| 810 | 812 | ||
| 811 | pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void { | 813 | pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 812 | const path_buf = %return cstr.addNullByte(allocator, dir_path); | 814 | const path_buf = try cstr.addNullByte(allocator, dir_path); |
| 813 | defer allocator.free(path_buf); | 815 | defer allocator.free(path_buf); |
| 814 | 816 | ||
| 815 | const err = posix.getErrno(posix.mkdir(path_buf.ptr, 0o755)); | 817 | const err = posix.getErrno(posix.mkdir(path_buf.ptr, 0o755)); |
| ... | @@ -835,12 +837,12 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void { | ... | @@ -835,12 +837,12 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 835 | /// Calls makeDir recursively to make an entire path. Returns success if the path | 837 | /// Calls makeDir recursively to make an entire path. Returns success if the path |
| 836 | /// already exists and is a directory. | 838 | /// already exists and is a directory. |
| 837 | pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void { | 839 | pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void { |
| 838 | const resolved_path = %return path.resolve(allocator, full_path); | 840 | const resolved_path = try path.resolve(allocator, full_path); |
| 839 | defer allocator.free(resolved_path); | 841 | defer allocator.free(resolved_path); |
| 840 | 842 | ||
| 841 | var end_index: usize = resolved_path.len; | 843 | var end_index: usize = resolved_path.len; |
| 842 | while (true) { | 844 | while (true) { |
| 843 | makeDir(allocator, resolved_path[0..end_index]) %% |err| { | 845 | makeDir(allocator, resolved_path[0..end_index]) catch |err| { |
| 844 | if (err == error.PathAlreadyExists) { | 846 | if (err == error.PathAlreadyExists) { |
| 845 | // TODO stat the file and return an error if it's not a directory | 847 | // TODO stat the file and return an error if it's not a directory |
| 846 | // this is important because otherwise a dangling symlink | 848 | // this is important because otherwise a dangling symlink |
| ... | @@ -873,7 +875,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void { | ... | @@ -873,7 +875,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void { |
| 873 | /// Returns ::error.DirNotEmpty if the directory is not empty. | 875 | /// Returns ::error.DirNotEmpty if the directory is not empty. |
| 874 | /// To delete a directory recursively, see ::deleteTree | 876 | /// To delete a directory recursively, see ::deleteTree |
| 875 | pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void { | 877 | pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 876 | const path_buf = %return allocator.alloc(u8, dir_path.len + 1); | 878 | const path_buf = try allocator.alloc(u8, dir_path.len + 1); |
| 877 | defer allocator.free(path_buf); | 879 | defer allocator.free(path_buf); |
| 878 | 880 | ||
| 879 | mem.copy(u8, path_buf, dir_path); | 881 | mem.copy(u8, path_buf, dir_path); |
| ... | @@ -913,7 +915,7 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void { | ... | @@ -913,7 +915,7 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void { |
| 913 | return err; | 915 | return err; |
| 914 | } | 916 | } |
| 915 | { | 917 | { |
| 916 | var dir = Dir.open(allocator, full_path) %% |err| { | 918 | var dir = Dir.open(allocator, full_path) catch |err| { |
| 917 | if (err == error.FileNotFound) | 919 | if (err == error.FileNotFound) |
| 918 | return; | 920 | return; |
| 919 | if (err == error.NotDir) | 921 | if (err == error.NotDir) |
| ... | @@ -925,14 +927,14 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void { | ... | @@ -925,14 +927,14 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void { |
| 925 | var full_entry_buf = ArrayList(u8).init(allocator); | 927 | var full_entry_buf = ArrayList(u8).init(allocator); |
| 926 | defer full_entry_buf.deinit(); | 928 | defer full_entry_buf.deinit(); |
| 927 | 929 | ||
| 928 | while (%return dir.next()) |entry| { | 930 | while (try dir.next()) |entry| { |
| 929 | %return full_entry_buf.resize(full_path.len + entry.name.len + 1); | 931 | try full_entry_buf.resize(full_path.len + entry.name.len + 1); |
| 930 | const full_entry_path = full_entry_buf.toSlice(); | 932 | const full_entry_path = full_entry_buf.toSlice(); |
| 931 | mem.copy(u8, full_entry_path, full_path); | 933 | mem.copy(u8, full_entry_path, full_path); |
| 932 | full_entry_path[full_path.len] = '/'; | 934 | full_entry_path[full_path.len] = '/'; |
| 933 | mem.copy(u8, full_entry_path[full_path.len + 1..], entry.name); | 935 | mem.copy(u8, full_entry_path[full_path.len + 1..], entry.name); |
| 934 | 936 | ||
| 935 | %return deleteTree(allocator, full_entry_path); | 937 | try deleteTree(allocator, full_entry_path); |
| 936 | } | 938 | } |
| 937 | } | 939 | } |
| 938 | return deleteDir(allocator, full_path); | 940 | return deleteDir(allocator, full_path); |
| ... | @@ -971,7 +973,7 @@ pub const Dir = struct { | ... | @@ -971,7 +973,7 @@ pub const Dir = struct { |
| 971 | }; | 973 | }; |
| 972 | 974 | ||
| 973 | pub fn open(allocator: &Allocator, dir_path: []const u8) -> %Dir { | 975 | pub fn open(allocator: &Allocator, dir_path: []const u8) -> %Dir { |
| 974 | const fd = %return posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator); | 976 | const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator); |
| 975 | return Dir { | 977 | return Dir { |
| 976 | .allocator = allocator, | 978 | .allocator = allocator, |
| 977 | .fd = fd, | 979 | .fd = fd, |
| ... | @@ -992,7 +994,7 @@ pub const Dir = struct { | ... | @@ -992,7 +994,7 @@ pub const Dir = struct { |
| 992 | start_over: while (true) { | 994 | start_over: while (true) { |
| 993 | if (self.index >= self.end_index) { | 995 | if (self.index >= self.end_index) { |
| 994 | if (self.buf.len == 0) { | 996 | if (self.buf.len == 0) { |
| 995 | self.buf = %return self.allocator.alloc(u8, page_size); | 997 | self.buf = try self.allocator.alloc(u8, page_size); |
| 996 | } | 998 | } |
| 997 | 999 | ||
| 998 | while (true) { | 1000 | while (true) { |
| ... | @@ -1002,7 +1004,7 @@ pub const Dir = struct { | ... | @@ -1002,7 +1004,7 @@ pub const Dir = struct { |
| 1002 | switch (err) { | 1004 | switch (err) { |
| 1003 | posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable, | 1005 | posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable, |
| 1004 | posix.EINVAL => { | 1006 | posix.EINVAL => { |
| 1005 | self.buf = %return self.allocator.realloc(u8, self.buf, self.buf.len * 2); | 1007 | self.buf = try self.allocator.realloc(u8, self.buf, self.buf.len * 2); |
| 1006 | continue; | 1008 | continue; |
| 1007 | }, | 1009 | }, |
| 1008 | else => return unexpectedErrorPosix(err), | 1010 | else => return unexpectedErrorPosix(err), |
| ... | @@ -1046,7 +1048,7 @@ pub const Dir = struct { | ... | @@ -1046,7 +1048,7 @@ pub const Dir = struct { |
| 1046 | }; | 1048 | }; |
| 1047 | 1049 | ||
| 1048 | pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void { | 1050 | pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 1049 | const path_buf = %return allocator.alloc(u8, dir_path.len + 1); | 1051 | const path_buf = try allocator.alloc(u8, dir_path.len + 1); |
| 1050 | defer allocator.free(path_buf); | 1052 | defer allocator.free(path_buf); |
| 1051 | 1053 | ||
| 1052 | mem.copy(u8, path_buf, dir_path); | 1054 | mem.copy(u8, path_buf, dir_path); |
| ... | @@ -1070,13 +1072,13 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void { | ... | @@ -1070,13 +1072,13 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 1070 | 1072 | ||
| 1071 | /// Read value of a symbolic link. | 1073 | /// Read value of a symbolic link. |
| 1072 | pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | 1074 | pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1073 | const path_buf = %return allocator.alloc(u8, pathname.len + 1); | 1075 | const path_buf = try allocator.alloc(u8, pathname.len + 1); |
| 1074 | defer allocator.free(path_buf); | 1076 | defer allocator.free(path_buf); |
| 1075 | 1077 | ||
| 1076 | mem.copy(u8, path_buf, pathname); | 1078 | mem.copy(u8, path_buf, pathname); |
| 1077 | path_buf[pathname.len] = 0; | 1079 | path_buf[pathname.len] = 0; |
| 1078 | 1080 | ||
| 1079 | var result_buf = %return allocator.alloc(u8, 1024); | 1081 | var result_buf = try allocator.alloc(u8, 1024); |
| 1080 | %defer allocator.free(result_buf); | 1082 | %defer allocator.free(result_buf); |
| 1081 | while (true) { | 1083 | while (true) { |
| 1082 | const ret_val = posix.readlink(path_buf.ptr, result_buf.ptr, result_buf.len); | 1084 | const ret_val = posix.readlink(path_buf.ptr, result_buf.ptr, result_buf.len); |
| ... | @@ -1095,7 +1097,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | ... | @@ -1095,7 +1097,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1095 | }; | 1097 | }; |
| 1096 | } | 1098 | } |
| 1097 | if (ret_val == result_buf.len) { | 1099 | if (ret_val == result_buf.len) { |
| 1098 | result_buf = %return allocator.realloc(u8, result_buf, result_buf.len * 2); | 1100 | result_buf = try allocator.realloc(u8, result_buf, result_buf.len * 2); |
| 1099 | continue; | 1101 | continue; |
| 1100 | } | 1102 | } |
| 1101 | return allocator.shrink(u8, result_buf, ret_val); | 1103 | return allocator.shrink(u8, result_buf, ret_val); |
| ... | @@ -1104,7 +1106,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | ... | @@ -1104,7 +1106,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1104 | 1106 | ||
| 1105 | pub fn sleep(seconds: usize, nanoseconds: usize) { | 1107 | pub fn sleep(seconds: usize, nanoseconds: usize) { |
| 1106 | switch(builtin.os) { | 1108 | switch(builtin.os) { |
| 1107 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | 1109 | Os.linux, Os.macosx, Os.ios => { |
| 1108 | posixSleep(u63(seconds), u63(nanoseconds)); | 1110 | posixSleep(u63(seconds), u63(nanoseconds)); |
| 1109 | }, | 1111 | }, |
| 1110 | Os.windows => { | 1112 | Os.windows => { |
| ... | @@ -1318,7 +1320,7 @@ pub const ArgIteratorWindows = struct { | ... | @@ -1318,7 +1320,7 @@ pub const ArgIteratorWindows = struct { |
| 1318 | } | 1320 | } |
| 1319 | 1321 | ||
| 1320 | fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) -> %[]u8 { | 1322 | fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) -> %[]u8 { |
| 1321 | var buf = %return Buffer.initSize(allocator, 0); | 1323 | var buf = try Buffer.initSize(allocator, 0); |
| 1322 | defer buf.deinit(); | 1324 | defer buf.deinit(); |
| 1323 | 1325 | ||
| 1324 | var backslash_count: usize = 0; | 1326 | var backslash_count: usize = 0; |
| ... | @@ -1328,34 +1330,34 @@ pub const ArgIteratorWindows = struct { | ... | @@ -1328,34 +1330,34 @@ pub const ArgIteratorWindows = struct { |
| 1328 | 0 => return buf.toOwnedSlice(), | 1330 | 0 => return buf.toOwnedSlice(), |
| 1329 | '"' => { | 1331 | '"' => { |
| 1330 | const quote_is_real = backslash_count % 2 == 0; | 1332 | const quote_is_real = backslash_count % 2 == 0; |
| 1331 | %return self.emitBackslashes(&buf, backslash_count / 2); | 1333 | try self.emitBackslashes(&buf, backslash_count / 2); |
| 1332 | backslash_count = 0; | 1334 | backslash_count = 0; |
| 1333 | 1335 | ||
| 1334 | if (quote_is_real) { | 1336 | if (quote_is_real) { |
| 1335 | self.seen_quote_count += 1; | 1337 | self.seen_quote_count += 1; |
| 1336 | if (self.seen_quote_count == self.quote_count and self.seen_quote_count % 2 == 1) { | 1338 | if (self.seen_quote_count == self.quote_count and self.seen_quote_count % 2 == 1) { |
| 1337 | %return buf.appendByte('"'); | 1339 | try buf.appendByte('"'); |
| 1338 | } | 1340 | } |
| 1339 | } else { | 1341 | } else { |
| 1340 | %return buf.appendByte('"'); | 1342 | try buf.appendByte('"'); |
| 1341 | } | 1343 | } |
| 1342 | }, | 1344 | }, |
| 1343 | '\\' => { | 1345 | '\\' => { |
| 1344 | backslash_count += 1; | 1346 | backslash_count += 1; |
| 1345 | }, | 1347 | }, |
| 1346 | ' ', '\t' => { | 1348 | ' ', '\t' => { |
| 1347 | %return self.emitBackslashes(&buf, backslash_count); | 1349 | try self.emitBackslashes(&buf, backslash_count); |
| 1348 | backslash_count = 0; | 1350 | backslash_count = 0; |
| 1349 | if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) { | 1351 | if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) { |
| 1350 | %return buf.appendByte(byte); | 1352 | try buf.appendByte(byte); |
| 1351 | } else { | 1353 | } else { |
| 1352 | return buf.toOwnedSlice(); | 1354 | return buf.toOwnedSlice(); |
| 1353 | } | 1355 | } |
| 1354 | }, | 1356 | }, |
| 1355 | else => { | 1357 | else => { |
| 1356 | %return self.emitBackslashes(&buf, backslash_count); | 1358 | try self.emitBackslashes(&buf, backslash_count); |
| 1357 | backslash_count = 0; | 1359 | backslash_count = 0; |
| 1358 | %return buf.appendByte(byte); | 1360 | try buf.appendByte(byte); |
| 1359 | }, | 1361 | }, |
| 1360 | } | 1362 | } |
| 1361 | } | 1363 | } |
| ... | @@ -1364,7 +1366,7 @@ pub const ArgIteratorWindows = struct { | ... | @@ -1364,7 +1366,7 @@ pub const ArgIteratorWindows = struct { |
| 1364 | fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void { | 1366 | fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void { |
| 1365 | var i: usize = 0; | 1367 | var i: usize = 0; |
| 1366 | while (i < emit_count) : (i += 1) { | 1368 | while (i < emit_count) : (i += 1) { |
| 1367 | %return buf.appendByte('\\'); | 1369 | try buf.appendByte('\\'); |
| 1368 | } | 1370 | } |
| 1369 | } | 1371 | } |
| 1370 | 1372 | ||
| ... | @@ -1428,24 +1430,24 @@ pub fn args() -> ArgIterator { | ... | @@ -1428,24 +1430,24 @@ pub fn args() -> ArgIterator { |
| 1428 | pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 { | 1430 | pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 { |
| 1429 | // TODO refactor to only make 1 allocation. | 1431 | // TODO refactor to only make 1 allocation. |
| 1430 | var it = args(); | 1432 | var it = args(); |
| 1431 | var contents = %return Buffer.initSize(allocator, 0); | 1433 | var contents = try Buffer.initSize(allocator, 0); |
| 1432 | defer contents.deinit(); | 1434 | defer contents.deinit(); |
| 1433 | 1435 | ||
| 1434 | var slice_list = ArrayList(usize).init(allocator); | 1436 | var slice_list = ArrayList(usize).init(allocator); |
| 1435 | defer slice_list.deinit(); | 1437 | defer slice_list.deinit(); |
| 1436 | 1438 | ||
| 1437 | while (it.next(allocator)) |arg_or_err| { | 1439 | while (it.next(allocator)) |arg_or_err| { |
| 1438 | const arg = %return arg_or_err; | 1440 | const arg = try arg_or_err; |
| 1439 | defer allocator.free(arg); | 1441 | defer allocator.free(arg); |
| 1440 | %return contents.append(arg); | 1442 | try contents.append(arg); |
| 1441 | %return slice_list.append(arg.len); | 1443 | try slice_list.append(arg.len); |
| 1442 | } | 1444 | } |
| 1443 | 1445 | ||
| 1444 | const contents_slice = contents.toSliceConst(); | 1446 | const contents_slice = contents.toSliceConst(); |
| 1445 | const slice_sizes = slice_list.toSliceConst(); | 1447 | const slice_sizes = slice_list.toSliceConst(); |
| 1446 | const slice_list_bytes = %return math.mul(usize, @sizeOf([]u8), slice_sizes.len); | 1448 | const slice_list_bytes = try math.mul(usize, @sizeOf([]u8), slice_sizes.len); |
| 1447 | const total_bytes = %return math.add(usize, slice_list_bytes, contents_slice.len); | 1449 | const total_bytes = try math.add(usize, slice_list_bytes, contents_slice.len); |
| 1448 | const buf = %return allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes); | 1450 | const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes); |
| 1449 | %defer allocator.free(buf); | 1451 | %defer allocator.free(buf); |
| 1450 | 1452 | ||
| 1451 | const result_slice_list = ([][]u8)(buf[0..slice_list_bytes]); | 1453 | const result_slice_list = ([][]u8)(buf[0..slice_list_bytes]); |
| ... | @@ -1537,7 +1539,7 @@ pub fn openSelfExe() -> %io.File { | ... | @@ -1537,7 +1539,7 @@ pub fn openSelfExe() -> %io.File { |
| 1537 | Os.linux => { | 1539 | Os.linux => { |
| 1538 | return io.File.openRead("/proc/self/exe", null); | 1540 | return io.File.openRead("/proc/self/exe", null); |
| 1539 | }, | 1541 | }, |
| 1540 | Os.darwin => { | 1542 | Os.macosx, Os.ios => { |
| 1541 | @panic("TODO: openSelfExe on Darwin"); | 1543 | @panic("TODO: openSelfExe on Darwin"); |
| 1542 | }, | 1544 | }, |
| 1543 | else => @compileError("Unsupported OS"), | 1545 | else => @compileError("Unsupported OS"), |
| ... | @@ -1558,10 +1560,10 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 { | ... | @@ -1558,10 +1560,10 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 { |
| 1558 | return readLink(allocator, "/proc/self/exe"); | 1560 | return readLink(allocator, "/proc/self/exe"); |
| 1559 | }, | 1561 | }, |
| 1560 | Os.windows => { | 1562 | Os.windows => { |
| 1561 | var out_path = %return Buffer.initSize(allocator, 0xff); | 1563 | var out_path = try Buffer.initSize(allocator, 0xff); |
| 1562 | %defer out_path.deinit(); | 1564 | %defer out_path.deinit(); |
| 1563 | while (true) { | 1565 | while (true) { |
| 1564 | const dword_len = %return math.cast(windows.DWORD, out_path.len()); | 1566 | const dword_len = try math.cast(windows.DWORD, out_path.len()); |
| 1565 | const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len); | 1567 | const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len); |
| 1566 | if (copied_amt <= 0) { | 1568 | if (copied_amt <= 0) { |
| 1567 | const err = windows.GetLastError(); | 1569 | const err = windows.GetLastError(); |
| ... | @@ -1574,14 +1576,14 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 { | ... | @@ -1574,14 +1576,14 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 { |
| 1574 | return out_path.toOwnedSlice(); | 1576 | return out_path.toOwnedSlice(); |
| 1575 | } | 1577 | } |
| 1576 | const new_len = (out_path.len() << 1) | 0b1; | 1578 | const new_len = (out_path.len() << 1) | 0b1; |
| 1577 | %return out_path.resize(new_len); | 1579 | try out_path.resize(new_len); |
| 1578 | } | 1580 | } |
| 1579 | }, | 1581 | }, |
| 1580 | Os.darwin, Os.macosx, Os.ios => { | 1582 | Os.macosx, Os.ios => { |
| 1581 | var u32_len: u32 = 0; | 1583 | var u32_len: u32 = 0; |
| 1582 | const ret1 = c._NSGetExecutablePath(undefined, &u32_len); | 1584 | const ret1 = c._NSGetExecutablePath(undefined, &u32_len); |
| 1583 | assert(ret1 != 0); | 1585 | assert(ret1 != 0); |
| 1584 | const bytes = %return allocator.alloc(u8, u32_len); | 1586 | const bytes = try allocator.alloc(u8, u32_len); |
| 1585 | %defer allocator.free(bytes); | 1587 | %defer allocator.free(bytes); |
| 1586 | const ret2 = c._NSGetExecutablePath(bytes.ptr, &u32_len); | 1588 | const ret2 = c._NSGetExecutablePath(bytes.ptr, &u32_len); |
| 1587 | assert(ret2 == 0); | 1589 | assert(ret2 == 0); |
| ... | @@ -1600,13 +1602,13 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 { | ... | @@ -1600,13 +1602,13 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 { |
| 1600 | // the file path looks something like `/a/b/c/exe (deleted)` | 1602 | // the file path looks something like `/a/b/c/exe (deleted)` |
| 1601 | // This path cannot be opened, but it's valid for determining the directory | 1603 | // This path cannot be opened, but it's valid for determining the directory |
| 1602 | // the executable was in when it was run. | 1604 | // the executable was in when it was run. |
| 1603 | const full_exe_path = %return readLink(allocator, "/proc/self/exe"); | 1605 | const full_exe_path = try readLink(allocator, "/proc/self/exe"); |
| 1604 | %defer allocator.free(full_exe_path); | 1606 | %defer allocator.free(full_exe_path); |
| 1605 | const dir = path.dirname(full_exe_path); | 1607 | const dir = path.dirname(full_exe_path); |
| 1606 | return allocator.shrink(u8, full_exe_path, dir.len); | 1608 | return allocator.shrink(u8, full_exe_path, dir.len); |
| 1607 | }, | 1609 | }, |
| 1608 | Os.windows, Os.darwin, Os.macosx, Os.ios => { | 1610 | Os.windows, Os.macosx, Os.ios => { |
| 1609 | const self_exe_path = %return selfExePath(allocator); | 1611 | const self_exe_path = try selfExePath(allocator); |
| 1610 | %defer allocator.free(self_exe_path); | 1612 | %defer allocator.free(self_exe_path); |
| 1611 | const dirname = os.path.dirname(self_exe_path); | 1613 | const dirname = os.path.dirname(self_exe_path); |
| 1612 | return allocator.shrink(u8, self_exe_path, dirname.len); | 1614 | return allocator.shrink(u8, self_exe_path, dirname.len); |
std/os/path.zig+23-23| ... | @@ -412,13 +412,13 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 | ... | @@ -412,13 +412,13 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 |
| 412 | if (have_abs_path) { | 412 | if (have_abs_path) { |
| 413 | switch (have_drive_kind) { | 413 | switch (have_drive_kind) { |
| 414 | WindowsPath.Kind.Drive => { | 414 | WindowsPath.Kind.Drive => { |
| 415 | result = %return allocator.alloc(u8, max_size); | 415 | result = try allocator.alloc(u8, max_size); |
| 416 | 416 | ||
| 417 | mem.copy(u8, result, result_disk_designator); | 417 | mem.copy(u8, result, result_disk_designator); |
| 418 | result_index += result_disk_designator.len; | 418 | result_index += result_disk_designator.len; |
| 419 | }, | 419 | }, |
| 420 | WindowsPath.Kind.NetworkShare => { | 420 | WindowsPath.Kind.NetworkShare => { |
| 421 | result = %return allocator.alloc(u8, max_size); | 421 | result = try allocator.alloc(u8, max_size); |
| 422 | var it = mem.split(paths[first_index], "/\\"); | 422 | var it = mem.split(paths[first_index], "/\\"); |
| 423 | const server_name = ??it.next(); | 423 | const server_name = ??it.next(); |
| 424 | const other_name = ??it.next(); | 424 | const other_name = ??it.next(); |
| ... | @@ -438,10 +438,10 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 | ... | @@ -438,10 +438,10 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 |
| 438 | }, | 438 | }, |
| 439 | WindowsPath.Kind.None => { | 439 | WindowsPath.Kind.None => { |
| 440 | assert(is_windows); // resolveWindows called on non windows can't use getCwd | 440 | assert(is_windows); // resolveWindows called on non windows can't use getCwd |
| 441 | const cwd = %return os.getCwd(allocator); | 441 | const cwd = try os.getCwd(allocator); |
| 442 | defer allocator.free(cwd); | 442 | defer allocator.free(cwd); |
| 443 | const parsed_cwd = windowsParsePath(cwd); | 443 | const parsed_cwd = windowsParsePath(cwd); |
| 444 | result = %return allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1); | 444 | result = try allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1); |
| 445 | mem.copy(u8, result, parsed_cwd.disk_designator); | 445 | mem.copy(u8, result, parsed_cwd.disk_designator); |
| 446 | result_index += parsed_cwd.disk_designator.len; | 446 | result_index += parsed_cwd.disk_designator.len; |
| 447 | result_disk_designator = result[0..parsed_cwd.disk_designator.len]; | 447 | result_disk_designator = result[0..parsed_cwd.disk_designator.len]; |
| ... | @@ -454,10 +454,10 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 | ... | @@ -454,10 +454,10 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 |
| 454 | } else { | 454 | } else { |
| 455 | assert(is_windows); // resolveWindows called on non windows can't use getCwd | 455 | assert(is_windows); // resolveWindows called on non windows can't use getCwd |
| 456 | // TODO call get cwd for the result_disk_designator instead of the global one | 456 | // TODO call get cwd for the result_disk_designator instead of the global one |
| 457 | const cwd = %return os.getCwd(allocator); | 457 | const cwd = try os.getCwd(allocator); |
| 458 | defer allocator.free(cwd); | 458 | defer allocator.free(cwd); |
| 459 | 459 | ||
| 460 | result = %return allocator.alloc(u8, max_size + cwd.len + 1); | 460 | result = try allocator.alloc(u8, max_size + cwd.len + 1); |
| 461 | 461 | ||
| 462 | mem.copy(u8, result, cwd); | 462 | mem.copy(u8, result, cwd); |
| 463 | result_index += cwd.len; | 463 | result_index += cwd.len; |
| ... | @@ -542,12 +542,12 @@ pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) -> %[]u8 { | ... | @@ -542,12 +542,12 @@ pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) -> %[]u8 { |
| 542 | var result_index: usize = 0; | 542 | var result_index: usize = 0; |
| 543 | 543 | ||
| 544 | if (have_abs) { | 544 | if (have_abs) { |
| 545 | result = %return allocator.alloc(u8, max_size); | 545 | result = try allocator.alloc(u8, max_size); |
| 546 | } else { | 546 | } else { |
| 547 | assert(!is_windows); // resolvePosix called on windows can't use getCwd | 547 | assert(!is_windows); // resolvePosix called on windows can't use getCwd |
| 548 | const cwd = %return os.getCwd(allocator); | 548 | const cwd = try os.getCwd(allocator); |
| 549 | defer allocator.free(cwd); | 549 | defer allocator.free(cwd); |
| 550 | result = %return allocator.alloc(u8, max_size + cwd.len + 1); | 550 | result = try allocator.alloc(u8, max_size + cwd.len + 1); |
| 551 | mem.copy(u8, result, cwd); | 551 | mem.copy(u8, result, cwd); |
| 552 | result_index += cwd.len; | 552 | result_index += cwd.len; |
| 553 | } | 553 | } |
| ... | @@ -899,11 +899,11 @@ pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u | ... | @@ -899,11 +899,11 @@ pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u |
| 899 | } | 899 | } |
| 900 | 900 | ||
| 901 | pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 { | 901 | pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 { |
| 902 | const resolved_from = %return resolveWindows(allocator, [][]const u8{from}); | 902 | const resolved_from = try resolveWindows(allocator, [][]const u8{from}); |
| 903 | defer allocator.free(resolved_from); | 903 | defer allocator.free(resolved_from); |
| 904 | 904 | ||
| 905 | var clean_up_resolved_to = true; | 905 | var clean_up_resolved_to = true; |
| 906 | const resolved_to = %return resolveWindows(allocator, [][]const u8{to}); | 906 | const resolved_to = try resolveWindows(allocator, [][]const u8{to}); |
| 907 | defer if (clean_up_resolved_to) allocator.free(resolved_to); | 907 | defer if (clean_up_resolved_to) allocator.free(resolved_to); |
| 908 | 908 | ||
| 909 | const parsed_from = windowsParsePath(resolved_from); | 909 | const parsed_from = windowsParsePath(resolved_from); |
| ... | @@ -942,7 +942,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) | ... | @@ -942,7 +942,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) |
| 942 | up_count += 1; | 942 | up_count += 1; |
| 943 | } | 943 | } |
| 944 | const up_index_end = up_count * "..\\".len; | 944 | const up_index_end = up_count * "..\\".len; |
| 945 | const result = %return allocator.alloc(u8, up_index_end + to_rest.len); | 945 | const result = try allocator.alloc(u8, up_index_end + to_rest.len); |
| 946 | %defer allocator.free(result); | 946 | %defer allocator.free(result); |
| 947 | 947 | ||
| 948 | var result_index: usize = 0; | 948 | var result_index: usize = 0; |
| ... | @@ -972,10 +972,10 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) | ... | @@ -972,10 +972,10 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) |
| 972 | } | 972 | } |
| 973 | 973 | ||
| 974 | pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 { | 974 | pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 { |
| 975 | const resolved_from = %return resolvePosix(allocator, [][]const u8{from}); | 975 | const resolved_from = try resolvePosix(allocator, [][]const u8{from}); |
| 976 | defer allocator.free(resolved_from); | 976 | defer allocator.free(resolved_from); |
| 977 | 977 | ||
| 978 | const resolved_to = %return resolvePosix(allocator, [][]const u8{to}); | 978 | const resolved_to = try resolvePosix(allocator, [][]const u8{to}); |
| 979 | defer allocator.free(resolved_to); | 979 | defer allocator.free(resolved_to); |
| 980 | 980 | ||
| 981 | var from_it = mem.split(resolved_from, "/"); | 981 | var from_it = mem.split(resolved_from, "/"); |
| ... | @@ -992,7 +992,7 @@ pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) -> | ... | @@ -992,7 +992,7 @@ pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) -> |
| 992 | up_count += 1; | 992 | up_count += 1; |
| 993 | } | 993 | } |
| 994 | const up_index_end = up_count * "../".len; | 994 | const up_index_end = up_count * "../".len; |
| 995 | const result = %return allocator.alloc(u8, up_index_end + to_rest.len); | 995 | const result = try allocator.alloc(u8, up_index_end + to_rest.len); |
| 996 | %defer allocator.free(result); | 996 | %defer allocator.free(result); |
| 997 | 997 | ||
| 998 | var result_index: usize = 0; | 998 | var result_index: usize = 0; |
| ... | @@ -1080,7 +1080,7 @@ error InputOutput; | ... | @@ -1080,7 +1080,7 @@ error InputOutput; |
| 1080 | pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | 1080 | pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1081 | switch (builtin.os) { | 1081 | switch (builtin.os) { |
| 1082 | Os.windows => { | 1082 | Os.windows => { |
| 1083 | const pathname_buf = %return allocator.alloc(u8, pathname.len + 1); | 1083 | const pathname_buf = try allocator.alloc(u8, pathname.len + 1); |
| 1084 | defer allocator.free(pathname_buf); | 1084 | defer allocator.free(pathname_buf); |
| 1085 | 1085 | ||
| 1086 | mem.copy(u8, pathname_buf, pathname); | 1086 | mem.copy(u8, pathname_buf, pathname); |
| ... | @@ -1099,10 +1099,10 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | ... | @@ -1099,10 +1099,10 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1099 | }; | 1099 | }; |
| 1100 | } | 1100 | } |
| 1101 | defer os.close(h_file); | 1101 | defer os.close(h_file); |
| 1102 | var buf = %return allocator.alloc(u8, 256); | 1102 | var buf = try allocator.alloc(u8, 256); |
| 1103 | %defer allocator.free(buf); | 1103 | %defer allocator.free(buf); |
| 1104 | while (true) { | 1104 | while (true) { |
| 1105 | const buf_len = math.cast(windows.DWORD, buf.len) %% return error.NameTooLong; | 1105 | const buf_len = math.cast(windows.DWORD, buf.len) catch return error.NameTooLong; |
| 1106 | const result = windows.GetFinalPathNameByHandleA(h_file, buf.ptr, buf_len, windows.VOLUME_NAME_DOS); | 1106 | const result = windows.GetFinalPathNameByHandleA(h_file, buf.ptr, buf_len, windows.VOLUME_NAME_DOS); |
| 1107 | 1107 | ||
| 1108 | if (result == 0) { | 1108 | if (result == 0) { |
| ... | @@ -1116,7 +1116,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | ... | @@ -1116,7 +1116,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1116 | } | 1116 | } |
| 1117 | 1117 | ||
| 1118 | if (result > buf.len) { | 1118 | if (result > buf.len) { |
| 1119 | buf = %return allocator.realloc(u8, buf, result); | 1119 | buf = try allocator.realloc(u8, buf, result); |
| 1120 | continue; | 1120 | continue; |
| 1121 | } | 1121 | } |
| 1122 | 1122 | ||
| ... | @@ -1137,13 +1137,13 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | ... | @@ -1137,13 +1137,13 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1137 | return allocator.shrink(u8, buf, final_len); | 1137 | return allocator.shrink(u8, buf, final_len); |
| 1138 | } | 1138 | } |
| 1139 | }, | 1139 | }, |
| 1140 | Os.darwin, Os.macosx, Os.ios => { | 1140 | Os.macosx, Os.ios => { |
| 1141 | // TODO instead of calling the libc function here, port the implementation | 1141 | // TODO instead of calling the libc function here, port the implementation |
| 1142 | // to Zig, and then remove the NameTooLong error possibility. | 1142 | // to Zig, and then remove the NameTooLong error possibility. |
| 1143 | const pathname_buf = %return allocator.alloc(u8, pathname.len + 1); | 1143 | const pathname_buf = try allocator.alloc(u8, pathname.len + 1); |
| 1144 | defer allocator.free(pathname_buf); | 1144 | defer allocator.free(pathname_buf); |
| 1145 | 1145 | ||
| 1146 | const result_buf = %return allocator.alloc(u8, posix.PATH_MAX); | 1146 | const result_buf = try allocator.alloc(u8, posix.PATH_MAX); |
| 1147 | %defer allocator.free(result_buf); | 1147 | %defer allocator.free(result_buf); |
| 1148 | 1148 | ||
| 1149 | mem.copy(u8, pathname_buf, pathname); | 1149 | mem.copy(u8, pathname_buf, pathname); |
| ... | @@ -1168,7 +1168,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | ... | @@ -1168,7 +1168,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1168 | return allocator.shrink(u8, result_buf, cstr.len(result_buf.ptr)); | 1168 | return allocator.shrink(u8, result_buf, cstr.len(result_buf.ptr)); |
| 1169 | }, | 1169 | }, |
| 1170 | Os.linux => { | 1170 | Os.linux => { |
| 1171 | const fd = %return os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator); | 1171 | const fd = try os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator); |
| 1172 | defer os.close(fd); | 1172 | defer os.close(fd); |
| 1173 | 1173 | ||
| 1174 | var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined; | 1174 | var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined; |
std/os/windows/util.zig+4-4| ... | @@ -93,7 +93,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m | ... | @@ -93,7 +93,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m |
| 93 | if (file_path.len < stack_buf.len) { | 93 | if (file_path.len < stack_buf.len) { |
| 94 | path0 = stack_buf[0..file_path.len + 1]; | 94 | path0 = stack_buf[0..file_path.len + 1]; |
| 95 | } else if (allocator) |a| { | 95 | } else if (allocator) |a| { |
| 96 | path0 = %return a.alloc(u8, file_path.len + 1); | 96 | path0 = try a.alloc(u8, file_path.len + 1); |
| 97 | need_free = true; | 97 | need_free = true; |
| 98 | } else { | 98 | } else { |
| 99 | return error.NameTooLong; | 99 | return error.NameTooLong; |
| ... | @@ -132,7 +132,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) | ... | @@ -132,7 +132,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) |
| 132 | } | 132 | } |
| 133 | break :x bytes_needed; | 133 | break :x bytes_needed; |
| 134 | }; | 134 | }; |
| 135 | const result = %return allocator.alloc(u8, bytes_needed); | 135 | const result = try allocator.alloc(u8, bytes_needed); |
| 136 | %defer allocator.free(result); | 136 | %defer allocator.free(result); |
| 137 | 137 | ||
| 138 | var it = env_map.iterator(); | 138 | var it = env_map.iterator(); |
| ... | @@ -153,7 +153,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) | ... | @@ -153,7 +153,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) |
| 153 | 153 | ||
| 154 | error DllNotFound; | 154 | error DllNotFound; |
| 155 | pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) -> %windows.HMODULE { | 155 | pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) -> %windows.HMODULE { |
| 156 | const padded_buff = %return cstr.addNullByte(allocator, dll_path); | 156 | const padded_buff = try cstr.addNullByte(allocator, dll_path); |
| 157 | defer allocator.free(padded_buff); | 157 | defer allocator.free(padded_buff); |
| 158 | return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound; | 158 | return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound; |
| 159 | } | 159 | } |
| ... | @@ -166,7 +166,7 @@ pub fn windowsUnloadDll(hModule: windows.HMODULE) { | ... | @@ -166,7 +166,7 @@ pub fn windowsUnloadDll(hModule: windows.HMODULE) { |
| 166 | test "InvalidDll" { | 166 | test "InvalidDll" { |
| 167 | const DllName = "asdf.dll"; | 167 | const DllName = "asdf.dll"; |
| 168 | const allocator = std.debug.global_allocator; | 168 | const allocator = std.debug.global_allocator; |
| 169 | const handle = os.windowsLoadDll(allocator, DllName) %% |err| { | 169 | const handle = os.windowsLoadDll(allocator, DllName) catch |err| { |
| 170 | assert(err == error.DllNotFound); | 170 | assert(err == error.DllNotFound); |
| 171 | return; | 171 | return; |
| 172 | }; | 172 | }; |
std/os/zen.zig created+94| ... | @@ -0,0 +1,94 @@ | ||
| 1 | ////////////////////////////// | ||
| 2 | //// Reserved mailboxes //// | ||
| 3 | ////////////////////////////// | ||
| 4 | |||
| 5 | pub const MBOX_TERMINAL = 1; | ||
| 6 | |||
| 7 | |||
| 8 | /////////////////////////// | ||
| 9 | //// Syscall numbers //// | ||
| 10 | /////////////////////////// | ||
| 11 | |||
| 12 | pub const SYS_createMailbox = 0; | ||
| 13 | pub const SYS_send = 1; | ||
| 14 | pub const SYS_receive = 2; | ||
| 15 | pub const SYS_map = 3; | ||
| 16 | |||
| 17 | |||
| 18 | //////////////////// | ||
| 19 | //// Syscalls //// | ||
| 20 | //////////////////// | ||
| 21 | |||
| 22 | pub fn createMailbox(id: u16) { | ||
| 23 | _ = syscall1(SYS_createMailbox, id); | ||
| 24 | } | ||
| 25 | |||
| 26 | pub fn send(mailbox_id: u16, data: usize) { | ||
| 27 | _ = syscall2(SYS_send, mailbox_id, data); | ||
| 28 | } | ||
| 29 | |||
| 30 | pub fn receive(mailbox_id: u16) -> usize { | ||
| 31 | return syscall1(SYS_receive, mailbox_id); | ||
| 32 | } | ||
| 33 | |||
| 34 | pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) -> bool { | ||
| 35 | return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0; | ||
| 36 | } | ||
| 37 | |||
| 38 | |||
| 39 | ///////////////////////// | ||
| 40 | //// Syscall stubs //// | ||
| 41 | ///////////////////////// | ||
| 42 | |||
| 43 | pub inline fn syscall0(number: usize) -> usize { | ||
| 44 | return asm volatile ("int $0x80" | ||
| 45 | : [ret] "={eax}" (-> usize) | ||
| 46 | : [number] "{eax}" (number)); | ||
| 47 | } | ||
| 48 | |||
| 49 | pub inline fn syscall1(number: usize, arg1: usize) -> usize { | ||
| 50 | return asm volatile ("int $0x80" | ||
| 51 | : [ret] "={eax}" (-> usize) | ||
| 52 | : [number] "{eax}" (number), | ||
| 53 | [arg1] "{ecx}" (arg1)); | ||
| 54 | } | ||
| 55 | |||
| 56 | pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize { | ||
| 57 | return asm volatile ("int $0x80" | ||
| 58 | : [ret] "={eax}" (-> usize) | ||
| 59 | : [number] "{eax}" (number), | ||
| 60 | [arg1] "{ecx}" (arg1), | ||
| 61 | [arg2] "{edx}" (arg2)); | ||
| 62 | } | ||
| 63 | |||
| 64 | pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize { | ||
| 65 | return asm volatile ("int $0x80" | ||
| 66 | : [ret] "={eax}" (-> usize) | ||
| 67 | : [number] "{eax}" (number), | ||
| 68 | [arg1] "{ecx}" (arg1), | ||
| 69 | [arg2] "{edx}" (arg2), | ||
| 70 | [arg3] "{ebx}" (arg3)); | ||
| 71 | } | ||
| 72 | |||
| 73 | pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize { | ||
| 74 | return asm volatile ("int $0x80" | ||
| 75 | : [ret] "={eax}" (-> usize) | ||
| 76 | : [number] "{eax}" (number), | ||
| 77 | [arg1] "{ecx}" (arg1), | ||
| 78 | [arg2] "{edx}" (arg2), | ||
| 79 | [arg3] "{ebx}" (arg3), | ||
| 80 | [arg4] "{esi}" (arg4)); | ||
| 81 | } | ||
| 82 | |||
| 83 | pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, | ||
| 84 | arg4: usize, arg5: usize) -> usize | ||
| 85 | { | ||
| 86 | return asm volatile ("int $0x80" | ||
| 87 | : [ret] "={eax}" (-> usize) | ||
| 88 | : [number] "{eax}" (number), | ||
| 89 | [arg1] "{ecx}" (arg1), | ||
| 90 | [arg2] "{edx}" (arg2), | ||
| 91 | [arg3] "{ebx}" (arg3), | ||
| 92 | [arg4] "{esi}" (arg4), | ||
| 93 | [arg5] "{edi}" (arg5)); | ||
| 94 | } | ||
std/rand.zig+1-1| ... | @@ -43,7 +43,7 @@ pub const Rand = struct { | ... | @@ -43,7 +43,7 @@ pub const Rand = struct { |
| 43 | } else { | 43 | } else { |
| 44 | var result: [@sizeOf(T)]u8 = undefined; | 44 | var result: [@sizeOf(T)]u8 = undefined; |
| 45 | r.fillBytes(result[0..]); | 45 | r.fillBytes(result[0..]); |
| 46 | return mem.readInt(result, T, false); | 46 | return mem.readInt(result, T, builtin.Endian.Little); |
| 47 | } | 47 | } |
| 48 | } | 48 | } |
| 49 | 49 |
std/special/bootstrap.zig+11-3| ... | @@ -11,6 +11,8 @@ comptime { | ... | @@ -11,6 +11,8 @@ comptime { |
| 11 | const strong_linkage = builtin.GlobalLinkage.Strong; | 11 | const strong_linkage = builtin.GlobalLinkage.Strong; |
| 12 | if (builtin.link_libc) { | 12 | if (builtin.link_libc) { |
| 13 | @export("main", main, strong_linkage); | 13 | @export("main", main, strong_linkage); |
| 14 | } else if (builtin.os == builtin.Os.zen) { | ||
| 15 | @export("main", zenMain, strong_linkage); | ||
| 14 | } else if (builtin.os == builtin.Os.windows) { | 16 | } else if (builtin.os == builtin.Os.windows) { |
| 15 | @export("WinMainCRTStartup", WinMainCRTStartup, strong_linkage); | 17 | @export("WinMainCRTStartup", WinMainCRTStartup, strong_linkage); |
| 16 | } else { | 18 | } else { |
| ... | @@ -18,6 +20,12 @@ comptime { | ... | @@ -18,6 +20,12 @@ comptime { |
| 18 | } | 20 | } |
| 19 | } | 21 | } |
| 20 | 22 | ||
| 23 | extern fn zenMain() -> noreturn { | ||
| 24 | // TODO: call exit. | ||
| 25 | root.main() catch {}; | ||
| 26 | while (true) {} | ||
| 27 | } | ||
| 28 | |||
| 21 | nakedcc fn _start() -> noreturn { | 29 | nakedcc fn _start() -> noreturn { |
| 22 | switch (builtin.arch) { | 30 | switch (builtin.arch) { |
| 23 | builtin.Arch.x86_64 => { | 31 | builtin.Arch.x86_64 => { |
| ... | @@ -36,7 +44,7 @@ nakedcc fn _start() -> noreturn { | ... | @@ -36,7 +44,7 @@ nakedcc fn _start() -> noreturn { |
| 36 | extern fn WinMainCRTStartup() -> noreturn { | 44 | extern fn WinMainCRTStartup() -> noreturn { |
| 37 | @setAlignStack(16); | 45 | @setAlignStack(16); |
| 38 | 46 | ||
| 39 | root.main() %% std.os.windows.ExitProcess(1); | 47 | root.main() catch std.os.windows.ExitProcess(1); |
| 40 | std.os.windows.ExitProcess(0); | 48 | std.os.windows.ExitProcess(0); |
| 41 | } | 49 | } |
| 42 | 50 | ||
| ... | @@ -44,7 +52,7 @@ fn posixCallMainAndExit() -> noreturn { | ... | @@ -44,7 +52,7 @@ fn posixCallMainAndExit() -> noreturn { |
| 44 | const argc = *argc_ptr; | 52 | const argc = *argc_ptr; |
| 45 | const argv = @ptrCast(&&u8, &argc_ptr[1]); | 53 | const argv = @ptrCast(&&u8, &argc_ptr[1]); |
| 46 | const envp = @ptrCast(&?&u8, &argv[argc + 1]); | 54 | const envp = @ptrCast(&?&u8, &argv[argc + 1]); |
| 47 | callMain(argc, argv, envp) %% std.os.posix.exit(1); | 55 | callMain(argc, argv, envp) catch std.os.posix.exit(1); |
| 48 | std.os.posix.exit(0); | 56 | std.os.posix.exit(0); |
| 49 | } | 57 | } |
| 50 | 58 | ||
| ... | @@ -59,6 +67,6 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void { | ... | @@ -59,6 +67,6 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void { |
| 59 | } | 67 | } |
| 60 | 68 | ||
| 61 | extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { | 69 | extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { |
| 62 | callMain(usize(c_argc), c_argv, c_envp) %% return 1; | 70 | callMain(usize(c_argc), c_argv, c_envp) catch return 1; |
| 63 | return 0; | 71 | return 0; |
| 64 | } | 72 | } |
std/special/build_runner.zig+25-25| ... | @@ -23,15 +23,15 @@ pub fn main() -> %void { | ... | @@ -23,15 +23,15 @@ pub fn main() -> %void { |
| 23 | // skip my own exe name | 23 | // skip my own exe name |
| 24 | _ = arg_it.skip(); | 24 | _ = arg_it.skip(); |
| 25 | 25 | ||
| 26 | const zig_exe = %return unwrapArg(arg_it.next(allocator) ?? { | 26 | const zig_exe = try unwrapArg(arg_it.next(allocator) ?? { |
| 27 | warn("Expected first argument to be path to zig compiler\n"); | 27 | warn("Expected first argument to be path to zig compiler\n"); |
| 28 | return error.InvalidArgs; | 28 | return error.InvalidArgs; |
| 29 | }); | 29 | }); |
| 30 | const build_root = %return unwrapArg(arg_it.next(allocator) ?? { | 30 | const build_root = try unwrapArg(arg_it.next(allocator) ?? { |
| 31 | warn("Expected second argument to be build root directory path\n"); | 31 | warn("Expected second argument to be build root directory path\n"); |
| 32 | return error.InvalidArgs; | 32 | return error.InvalidArgs; |
| 33 | }); | 33 | }); |
| 34 | const cache_root = %return unwrapArg(arg_it.next(allocator) ?? { | 34 | const cache_root = try unwrapArg(arg_it.next(allocator) ?? { |
| 35 | warn("Expected third argument to be cache root directory path\n"); | 35 | warn("Expected third argument to be cache root directory path\n"); |
| 36 | return error.InvalidArgs; | 36 | return error.InvalidArgs; |
| 37 | }); | 37 | }); |
| ... | @@ -58,36 +58,36 @@ pub fn main() -> %void { | ... | @@ -58,36 +58,36 @@ pub fn main() -> %void { |
| 58 | } else |err| err; | 58 | } else |err| err; |
| 59 | 59 | ||
| 60 | while (arg_it.next(allocator)) |err_or_arg| { | 60 | while (arg_it.next(allocator)) |err_or_arg| { |
| 61 | const arg = %return unwrapArg(err_or_arg); | 61 | const arg = try unwrapArg(err_or_arg); |
| 62 | if (mem.startsWith(u8, arg, "-D")) { | 62 | if (mem.startsWith(u8, arg, "-D")) { |
| 63 | const option_contents = arg[2..]; | 63 | const option_contents = arg[2..]; |
| 64 | if (option_contents.len == 0) { | 64 | if (option_contents.len == 0) { |
| 65 | warn("Expected option name after '-D'\n\n"); | 65 | warn("Expected option name after '-D'\n\n"); |
| 66 | return usageAndErr(&builder, false, %return stderr_stream); | 66 | return usageAndErr(&builder, false, try stderr_stream); |
| 67 | } | 67 | } |
| 68 | if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| { | 68 | if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| { |
| 69 | const option_name = option_contents[0..name_end]; | 69 | const option_name = option_contents[0..name_end]; |
| 70 | const option_value = option_contents[name_end + 1..]; | 70 | const option_value = option_contents[name_end + 1..]; |
| 71 | if (builder.addUserInputOption(option_name, option_value)) | 71 | if (builder.addUserInputOption(option_name, option_value)) |
| 72 | return usageAndErr(&builder, false, %return stderr_stream); | 72 | return usageAndErr(&builder, false, try stderr_stream); |
| 73 | } else { | 73 | } else { |
| 74 | if (builder.addUserInputFlag(option_contents)) | 74 | if (builder.addUserInputFlag(option_contents)) |
| 75 | return usageAndErr(&builder, false, %return stderr_stream); | 75 | return usageAndErr(&builder, false, try stderr_stream); |
| 76 | } | 76 | } |
| 77 | } else if (mem.startsWith(u8, arg, "-")) { | 77 | } else if (mem.startsWith(u8, arg, "-")) { |
| 78 | if (mem.eql(u8, arg, "--verbose")) { | 78 | if (mem.eql(u8, arg, "--verbose")) { |
| 79 | builder.verbose = true; | 79 | builder.verbose = true; |
| 80 | } else if (mem.eql(u8, arg, "--help")) { | 80 | } else if (mem.eql(u8, arg, "--help")) { |
| 81 | return usage(&builder, false, %return stdout_stream); | 81 | return usage(&builder, false, try stdout_stream); |
| 82 | } else if (mem.eql(u8, arg, "--prefix")) { | 82 | } else if (mem.eql(u8, arg, "--prefix")) { |
| 83 | prefix = %return unwrapArg(arg_it.next(allocator) ?? { | 83 | prefix = try unwrapArg(arg_it.next(allocator) ?? { |
| 84 | warn("Expected argument after --prefix\n\n"); | 84 | warn("Expected argument after --prefix\n\n"); |
| 85 | return usageAndErr(&builder, false, %return stderr_stream); | 85 | return usageAndErr(&builder, false, try stderr_stream); |
| 86 | }); | 86 | }); |
| 87 | } else if (mem.eql(u8, arg, "--search-prefix")) { | 87 | } else if (mem.eql(u8, arg, "--search-prefix")) { |
| 88 | const search_prefix = %return unwrapArg(arg_it.next(allocator) ?? { | 88 | const search_prefix = try unwrapArg(arg_it.next(allocator) ?? { |
| 89 | warn("Expected argument after --search-prefix\n\n"); | 89 | warn("Expected argument after --search-prefix\n\n"); |
| 90 | return usageAndErr(&builder, false, %return stderr_stream); | 90 | return usageAndErr(&builder, false, try stderr_stream); |
| 91 | }); | 91 | }); |
| 92 | builder.addSearchPrefix(search_prefix); | 92 | builder.addSearchPrefix(search_prefix); |
| 93 | } else if (mem.eql(u8, arg, "--verbose-tokenize")) { | 93 | } else if (mem.eql(u8, arg, "--verbose-tokenize")) { |
| ... | @@ -104,7 +104,7 @@ pub fn main() -> %void { | ... | @@ -104,7 +104,7 @@ pub fn main() -> %void { |
| 104 | builder.verbose_cimport = true; | 104 | builder.verbose_cimport = true; |
| 105 | } else { | 105 | } else { |
| 106 | warn("Unrecognized argument: {}\n\n", arg); | 106 | warn("Unrecognized argument: {}\n\n", arg); |
| 107 | return usageAndErr(&builder, false, %return stderr_stream); | 107 | return usageAndErr(&builder, false, try stderr_stream); |
| 108 | } | 108 | } |
| 109 | } else { | 109 | } else { |
| 110 | %%targets.append(arg); | 110 | %%targets.append(arg); |
| ... | @@ -115,11 +115,11 @@ pub fn main() -> %void { | ... | @@ -115,11 +115,11 @@ pub fn main() -> %void { |
| 115 | root.build(&builder); | 115 | root.build(&builder); |
| 116 | 116 | ||
| 117 | if (builder.validateUserInputDidItFail()) | 117 | if (builder.validateUserInputDidItFail()) |
| 118 | return usageAndErr(&builder, true, %return stderr_stream); | 118 | return usageAndErr(&builder, true, try stderr_stream); |
| 119 | 119 | ||
| 120 | builder.make(targets.toSliceConst()) %% |err| { | 120 | builder.make(targets.toSliceConst()) catch |err| { |
| 121 | if (err == error.InvalidStepName) { | 121 | if (err == error.InvalidStepName) { |
| 122 | return usageAndErr(&builder, true, %return stderr_stream); | 122 | return usageAndErr(&builder, true, try stderr_stream); |
| 123 | } | 123 | } |
| 124 | return err; | 124 | return err; |
| 125 | }; | 125 | }; |
| ... | @@ -133,7 +133,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) | ... | @@ -133,7 +133,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | // This usage text has to be synchronized with src/main.cpp | 135 | // This usage text has to be synchronized with src/main.cpp |
| 136 | %return out_stream.print( | 136 | try out_stream.print( |
| 137 | \\Usage: {} build [steps] [options] | 137 | \\Usage: {} build [steps] [options] |
| 138 | \\ | 138 | \\ |
| 139 | \\Steps: | 139 | \\Steps: |
| ... | @@ -142,10 +142,10 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) | ... | @@ -142,10 +142,10 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 142 | 142 | ||
| 143 | const allocator = builder.allocator; | 143 | const allocator = builder.allocator; |
| 144 | for (builder.top_level_steps.toSliceConst()) |top_level_step| { | 144 | for (builder.top_level_steps.toSliceConst()) |top_level_step| { |
| 145 | %return out_stream.print(" {s22} {}\n", top_level_step.step.name, top_level_step.description); | 145 | try out_stream.print(" {s22} {}\n", top_level_step.step.name, top_level_step.description); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | %return out_stream.write( | 148 | try out_stream.write( |
| 149 | \\ | 149 | \\ |
| 150 | \\General Options: | 150 | \\General Options: |
| 151 | \\ --help Print this help and exit | 151 | \\ --help Print this help and exit |
| ... | @@ -158,17 +158,17 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) | ... | @@ -158,17 +158,17 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 158 | ); | 158 | ); |
| 159 | 159 | ||
| 160 | if (builder.available_options_list.len == 0) { | 160 | if (builder.available_options_list.len == 0) { |
| 161 | %return out_stream.print(" (none)\n"); | 161 | try out_stream.print(" (none)\n"); |
| 162 | } else { | 162 | } else { |
| 163 | for (builder.available_options_list.toSliceConst()) |option| { | 163 | for (builder.available_options_list.toSliceConst()) |option| { |
| 164 | const name = %return fmt.allocPrint(allocator, | 164 | const name = try fmt.allocPrint(allocator, |
| 165 | " -D{}=[{}]", option.name, Builder.typeIdName(option.type_id)); | 165 | " -D{}=[{}]", option.name, Builder.typeIdName(option.type_id)); |
| 166 | defer allocator.free(name); | 166 | defer allocator.free(name); |
| 167 | %return out_stream.print("{s24} {}\n", name, option.description); | 167 | try out_stream.print("{s24} {}\n", name, option.description); |
| 168 | } | 168 | } |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | %return out_stream.write( | 171 | try out_stream.write( |
| 172 | \\ | 172 | \\ |
| 173 | \\Advanced Options: | 173 | \\Advanced Options: |
| 174 | \\ --build-file [file] Override path to build.zig | 174 | \\ --build-file [file] Override path to build.zig |
| ... | @@ -184,12 +184,12 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) | ... | @@ -184,12 +184,12 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) -> error { | 186 | fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) -> error { |
| 187 | usage(builder, already_ran_build, out_stream) %% {}; | 187 | usage(builder, already_ran_build, out_stream) catch {}; |
| 188 | return error.InvalidArgs; | 188 | return error.InvalidArgs; |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | fn unwrapArg(arg: %[]u8) -> %[]u8 { | 191 | fn unwrapArg(arg: %[]u8) -> %[]u8 { |
| 192 | return arg %% |err| { | 192 | return arg catch |err| { |
| 193 | warn("Unable to parse command line: {}\n", err); | 193 | warn("Unable to parse command line: {}\n", err); |
| 194 | return err; | 194 | return err; |
| 195 | }; | 195 | }; |
std/special/panic.zig+8-4| ... | @@ -6,9 +6,13 @@ | ... | @@ -6,9 +6,13 @@ |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | 7 | ||
| 8 | pub coldcc fn panic(msg: []const u8) -> noreturn { | 8 | pub coldcc fn panic(msg: []const u8) -> noreturn { |
| 9 | if (builtin.os == builtin.Os.freestanding) { | 9 | switch (builtin.os) { |
| 10 | while (true) {} | 10 | // TODO: fix panic in zen. |
| 11 | } else { | 11 | builtin.Os.freestanding, builtin.Os.zen => { |
| 12 | @import("std").debug.panic("{}", msg); | 12 | while (true) {} |
| 13 | }, | ||
| 14 | else => { | ||
| 15 | @import("std").debug.panic("{}", msg); | ||
| 16 | }, | ||
| 13 | } | 17 | } |
| 14 | } | 18 | } |
std/unicode.zig+1-1| ... | @@ -162,7 +162,7 @@ fn testValid(bytes: []const u8, expected_codepoint: u32) { | ... | @@ -162,7 +162,7 @@ fn testValid(bytes: []const u8, expected_codepoint: u32) { |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | fn testDecode(bytes: []const u8) -> %u32 { | 164 | fn testDecode(bytes: []const u8) -> %u32 { |
| 165 | const length = %return utf8ByteSequenceLength(bytes[0]); | 165 | const length = try utf8ByteSequenceLength(bytes[0]); |
| 166 | if (bytes.len < length) return error.UnexpectedEof; | 166 | if (bytes.len < length) return error.UnexpectedEof; |
| 167 | std.debug.assert(bytes.len == length); | 167 | std.debug.assert(bytes.len == length); |
| 168 | return utf8Decode(bytes); | 168 | return utf8Decode(bytes); |
test/cases/defer.zig+1-1| ... | @@ -18,7 +18,7 @@ test "mixing normal and error defers" { | ... | @@ -18,7 +18,7 @@ test "mixing normal and error defers" { |
| 18 | assert(result[0] == 'c'); | 18 | assert(result[0] == 'c'); |
| 19 | assert(result[1] == 'a'); | 19 | assert(result[1] == 'a'); |
| 20 | 20 | ||
| 21 | const ok = runSomeErrorDefers(false) %% |err| x: { | 21 | const ok = runSomeErrorDefers(false) catch |err| x: { |
| 22 | assert(err == error.FalseNotAllowed); | 22 | assert(err == error.FalseNotAllowed); |
| 23 | break :x true; | 23 | break :x true; |
| 24 | }; | 24 | }; |
test/cases/error.zig+5-5| ... | @@ -2,7 +2,7 @@ const assert = @import("std").debug.assert; | ... | @@ -2,7 +2,7 @@ const assert = @import("std").debug.assert; |
| 2 | const mem = @import("std").mem; | 2 | const mem = @import("std").mem; |
| 3 | 3 | ||
| 4 | pub fn foo() -> %i32 { | 4 | pub fn foo() -> %i32 { |
| 5 | const x = %return bar(); | 5 | const x = try bar(); |
| 6 | return x + 1; | 6 | return x + 1; |
| 7 | } | 7 | } |
| 8 | 8 | ||
| ... | @@ -11,7 +11,7 @@ pub fn bar() -> %i32 { | ... | @@ -11,7 +11,7 @@ pub fn bar() -> %i32 { |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | pub fn baz() -> %i32 { | 13 | pub fn baz() -> %i32 { |
| 14 | const y = foo() %% 1234; | 14 | const y = foo() catch 1234; |
| 15 | return y + 1; | 15 | return y + 1; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| ... | @@ -53,8 +53,8 @@ fn shouldBeNotEqual(a: error, b: error) { | ... | @@ -53,8 +53,8 @@ fn shouldBeNotEqual(a: error, b: error) { |
| 53 | 53 | ||
| 54 | 54 | ||
| 55 | test "error binary operator" { | 55 | test "error binary operator" { |
| 56 | const a = errBinaryOperatorG(true) %% 3; | 56 | const a = errBinaryOperatorG(true) catch 3; |
| 57 | const b = errBinaryOperatorG(false) %% 3; | 57 | const b = errBinaryOperatorG(false) catch 3; |
| 58 | assert(a == 3); | 58 | assert(a == 3); |
| 59 | assert(b == 10); | 59 | assert(b == 10); |
| 60 | } | 60 | } |
| ... | @@ -77,7 +77,7 @@ test "error return in assignment" { | ... | @@ -77,7 +77,7 @@ test "error return in assignment" { |
| 77 | 77 | ||
| 78 | fn doErrReturnInAssignment() -> %void { | 78 | fn doErrReturnInAssignment() -> %void { |
| 79 | var x : i32 = undefined; | 79 | var x : i32 = undefined; |
| 80 | x = %return makeANonErr(); | 80 | x = try makeANonErr(); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | fn makeANonErr() -> %i32 { | 83 | fn makeANonErr() -> %i32 { |
test/cases/ir_block_deps.zig+2-2| ... | @@ -4,8 +4,8 @@ fn foo(id: u64) -> %i32 { | ... | @@ -4,8 +4,8 @@ fn foo(id: u64) -> %i32 { |
| 4 | return switch (id) { | 4 | return switch (id) { |
| 5 | 1 => getErrInt(), | 5 | 1 => getErrInt(), |
| 6 | 2 => { | 6 | 2 => { |
| 7 | const size = %return getErrInt(); | 7 | const size = try getErrInt(); |
| 8 | return %return getErrInt(); | 8 | return try getErrInt(); |
| 9 | }, | 9 | }, |
| 10 | else => error.ItBroke, | 10 | else => error.ItBroke, |
| 11 | }; | 11 | }; |
test/cases/misc.zig+31| ... | @@ -577,3 +577,34 @@ test "implicit comptime while" { | ... | @@ -577,3 +577,34 @@ test "implicit comptime while" { |
| 577 | @compileError("bad"); | 577 | @compileError("bad"); |
| 578 | } | 578 | } |
| 579 | } | 579 | } |
| 580 | |||
| 581 | test "struct inside function" { | ||
| 582 | testStructInFn(); | ||
| 583 | comptime testStructInFn(); | ||
| 584 | } | ||
| 585 | |||
| 586 | fn testStructInFn() { | ||
| 587 | const BlockKind = u32; | ||
| 588 | |||
| 589 | const Block = struct { | ||
| 590 | kind: BlockKind, | ||
| 591 | }; | ||
| 592 | |||
| 593 | var block = Block { .kind = 1234 }; | ||
| 594 | |||
| 595 | block.kind += 1; | ||
| 596 | |||
| 597 | assert(block.kind == 1235); | ||
| 598 | } | ||
| 599 | |||
| 600 | fn fnThatClosesOverLocalConst() -> type { | ||
| 601 | const c = 1; | ||
| 602 | return struct { | ||
| 603 | fn g() -> i32 { return c; } | ||
| 604 | }; | ||
| 605 | } | ||
| 606 | |||
| 607 | test "function closes over local const" { | ||
| 608 | const x = fnThatClosesOverLocalConst().g(); | ||
| 609 | assert(x == 1); | ||
| 610 | } |
test/cases/switch.zig+1-1| ... | @@ -230,7 +230,7 @@ fn return_a_number() -> %i32 { | ... | @@ -230,7 +230,7 @@ fn return_a_number() -> %i32 { |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | test "capture value of switch with all unreachable prongs" { | 232 | test "capture value of switch with all unreachable prongs" { |
| 233 | const x = return_a_number() %% |err| switch (err) { | 233 | const x = return_a_number() catch |err| switch (err) { |
| 234 | else => unreachable, | 234 | else => unreachable, |
| 235 | }; | 235 | }; |
| 236 | assert(x == 1); | 236 | assert(x == 1); |
test/cases/switch_prong_err_enum.zig+1-1| ... | @@ -16,7 +16,7 @@ const FormValue = union(enum) { | ... | @@ -16,7 +16,7 @@ const FormValue = union(enum) { |
| 16 | 16 | ||
| 17 | fn doThing(form_id: u64) -> %FormValue { | 17 | fn doThing(form_id: u64) -> %FormValue { |
| 18 | return switch (form_id) { | 18 | return switch (form_id) { |
| 19 | 17 => FormValue { .Address = %return readOnce() }, | 19 | 17 => FormValue { .Address = try readOnce() }, |
| 20 | else => error.InvalidDebugInfo, | 20 | else => error.InvalidDebugInfo, |
| 21 | }; | 21 | }; |
| 22 | } | 22 | } |
test/compare_output.zig+10-10| ... | @@ -395,14 +395,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { | ... | @@ -395,14 +395,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 395 | cases.add("%defer and it fails", | 395 | cases.add("%defer and it fails", |
| 396 | \\const io = @import("std").io; | 396 | \\const io = @import("std").io; |
| 397 | \\pub fn main() -> %void { | 397 | \\pub fn main() -> %void { |
| 398 | \\ do_test() %% return; | 398 | \\ do_test() catch return; |
| 399 | \\} | 399 | \\} |
| 400 | \\fn do_test() -> %void { | 400 | \\fn do_test() -> %void { |
| 401 | \\ const stdout = &(io.FileOutStream.init(&%%io.getStdOut()).stream); | 401 | \\ const stdout = &(io.FileOutStream.init(&%%io.getStdOut()).stream); |
| 402 | \\ %%stdout.print("before\n"); | 402 | \\ %%stdout.print("before\n"); |
| 403 | \\ defer %%stdout.print("defer1\n"); | 403 | \\ defer %%stdout.print("defer1\n"); |
| 404 | \\ %defer %%stdout.print("deferErr\n"); | 404 | \\ %defer %%stdout.print("deferErr\n"); |
| 405 | \\ %return its_gonna_fail(); | 405 | \\ try its_gonna_fail(); |
| 406 | \\ defer %%stdout.print("defer3\n"); | 406 | \\ defer %%stdout.print("defer3\n"); |
| 407 | \\ %%stdout.print("after\n"); | 407 | \\ %%stdout.print("after\n"); |
| 408 | \\} | 408 | \\} |
| ... | @@ -415,14 +415,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { | ... | @@ -415,14 +415,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 415 | cases.add("%defer and it passes", | 415 | cases.add("%defer and it passes", |
| 416 | \\const io = @import("std").io; | 416 | \\const io = @import("std").io; |
| 417 | \\pub fn main() -> %void { | 417 | \\pub fn main() -> %void { |
| 418 | \\ do_test() %% return; | 418 | \\ do_test() catch return; |
| 419 | \\} | 419 | \\} |
| 420 | \\fn do_test() -> %void { | 420 | \\fn do_test() -> %void { |
| 421 | \\ const stdout = &(io.FileOutStream.init(&%%io.getStdOut()).stream); | 421 | \\ const stdout = &(io.FileOutStream.init(&%%io.getStdOut()).stream); |
| 422 | \\ %%stdout.print("before\n"); | 422 | \\ %%stdout.print("before\n"); |
| 423 | \\ defer %%stdout.print("defer1\n"); | 423 | \\ defer %%stdout.print("defer1\n"); |
| 424 | \\ %defer %%stdout.print("deferErr\n"); | 424 | \\ %defer %%stdout.print("deferErr\n"); |
| 425 | \\ %return its_gonna_pass(); | 425 | \\ try its_gonna_pass(); |
| 426 | \\ defer %%stdout.print("defer3\n"); | 426 | \\ defer %%stdout.print("defer3\n"); |
| 427 | \\ %%stdout.print("after\n"); | 427 | \\ %%stdout.print("after\n"); |
| 428 | \\} | 428 | \\} |
| ... | @@ -454,14 +454,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { | ... | @@ -454,14 +454,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 454 | \\ | 454 | \\ |
| 455 | \\pub fn main() -> %void { | 455 | \\pub fn main() -> %void { |
| 456 | \\ var args_it = os.args(); | 456 | \\ var args_it = os.args(); |
| 457 | \\ var stdout_file = %return io.getStdOut(); | 457 | \\ var stdout_file = try io.getStdOut(); |
| 458 | \\ var stdout_adapter = io.FileOutStream.init(&stdout_file); | 458 | \\ var stdout_adapter = io.FileOutStream.init(&stdout_file); |
| 459 | \\ const stdout = &stdout_adapter.stream; | 459 | \\ const stdout = &stdout_adapter.stream; |
| 460 | \\ var index: usize = 0; | 460 | \\ var index: usize = 0; |
| 461 | \\ _ = args_it.skip(); | 461 | \\ _ = args_it.skip(); |
| 462 | \\ while (args_it.next(allocator)) |arg_or_err| : (index += 1) { | 462 | \\ while (args_it.next(allocator)) |arg_or_err| : (index += 1) { |
| 463 | \\ const arg = %return arg_or_err; | 463 | \\ const arg = try arg_or_err; |
| 464 | \\ %return stdout.print("{}: {}\n", index, arg); | 464 | \\ try stdout.print("{}: {}\n", index, arg); |
| 465 | \\ } | 465 | \\ } |
| 466 | \\} | 466 | \\} |
| 467 | , | 467 | , |
| ... | @@ -495,14 +495,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { | ... | @@ -495,14 +495,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 495 | \\ | 495 | \\ |
| 496 | \\pub fn main() -> %void { | 496 | \\pub fn main() -> %void { |
| 497 | \\ var args_it = os.args(); | 497 | \\ var args_it = os.args(); |
| 498 | \\ var stdout_file = %return io.getStdOut(); | 498 | \\ var stdout_file = try io.getStdOut(); |
| 499 | \\ var stdout_adapter = io.FileOutStream.init(&stdout_file); | 499 | \\ var stdout_adapter = io.FileOutStream.init(&stdout_file); |
| 500 | \\ const stdout = &stdout_adapter.stream; | 500 | \\ const stdout = &stdout_adapter.stream; |
| 501 | \\ var index: usize = 0; | 501 | \\ var index: usize = 0; |
| 502 | \\ _ = args_it.skip(); | 502 | \\ _ = args_it.skip(); |
| 503 | \\ while (args_it.next(allocator)) |arg_or_err| : (index += 1) { | 503 | \\ while (args_it.next(allocator)) |arg_or_err| : (index += 1) { |
| 504 | \\ const arg = %return arg_or_err; | 504 | \\ const arg = try arg_or_err; |
| 505 | \\ %return stdout.print("{}: {}\n", index, arg); | 505 | \\ try stdout.print("{}: {}\n", index, arg); |
| 506 | \\ } | 506 | \\ } |
| 507 | \\} | 507 | \\} |
| 508 | , | 508 | , |
test/compile_errors.zig+16-4| ... | @@ -1,6 +1,18 @@ | ... | @@ -1,6 +1,18 @@ |
| 1 | const tests = @import("tests.zig"); | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | ||
| 3 | pub fn addCases(cases: &tests.CompileErrorContext) { | 3 | pub fn addCases(cases: &tests.CompileErrorContext) { |
| 4 | cases.add("bad identifier in function with struct defined inside function which references local const", | ||
| 5 | \\export fn entry() { | ||
| 6 | \\ const BlockKind = u32; | ||
| 7 | \\ | ||
| 8 | \\ const Block = struct { | ||
| 9 | \\ kind: BlockKind, | ||
| 10 | \\ }; | ||
| 11 | \\ | ||
| 12 | \\ bogus; | ||
| 13 | \\} | ||
| 14 | , ".tmp_source.zig:8:5: error: use of undeclared identifier 'bogus'"); | ||
| 15 | |||
| 4 | cases.add("labeled break not found", | 16 | cases.add("labeled break not found", |
| 5 | \\export fn entry() { | 17 | \\export fn entry() { |
| 6 | \\ blah: while (true) { | 18 | \\ blah: while (true) { |
| ... | @@ -1039,9 +1051,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) { | ... | @@ -1039,9 +1051,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1039 | \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); } | 1051 | \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); } |
| 1040 | , ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'"); | 1052 | , ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'"); |
| 1041 | 1053 | ||
| 1042 | cases.add("%return in function with non error return type", | 1054 | cases.add("try in function with non error return type", |
| 1043 | \\export fn f() { | 1055 | \\export fn f() { |
| 1044 | \\ %return something(); | 1056 | \\ try something(); |
| 1045 | \\} | 1057 | \\} |
| 1046 | \\fn something() -> %void { } | 1058 | \\fn something() -> %void { } |
| 1047 | , | 1059 | , |
| ... | @@ -1276,9 +1288,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) { | ... | @@ -1276,9 +1288,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1276 | 1288 | ||
| 1277 | cases.add("return from defer expression", | 1289 | cases.add("return from defer expression", |
| 1278 | \\pub fn testTrickyDefer() -> %void { | 1290 | \\pub fn testTrickyDefer() -> %void { |
| 1279 | \\ defer canFail() %% {}; | 1291 | \\ defer canFail() catch {}; |
| 1280 | \\ | 1292 | \\ |
| 1281 | \\ defer %return canFail(); | 1293 | \\ defer try canFail(); |
| 1282 | \\ | 1294 | \\ |
| 1283 | \\ const a = maybeInt() ?? return; | 1295 | \\ const a = maybeInt() ?? return; |
| 1284 | \\} | 1296 | \\} |
test/debug_safety.zig+5-2| ... | @@ -221,11 +221,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { | ... | @@ -221,11 +221,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 221 | 221 | ||
| 222 | cases.addDebugSafety("unwrap error", | 222 | cases.addDebugSafety("unwrap error", |
| 223 | \\pub fn panic(message: []const u8) -> noreturn { | 223 | \\pub fn panic(message: []const u8) -> noreturn { |
| 224 | \\ @import("std").os.exit(126); | 224 | \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) { |
| 225 | \\ @import("std").os.exit(126); // good | ||
| 226 | \\ } | ||
| 227 | \\ @import("std").os.exit(0); // test failed | ||
| 225 | \\} | 228 | \\} |
| 226 | \\error Whatever; | 229 | \\error Whatever; |
| 227 | \\pub fn main() -> %void { | 230 | \\pub fn main() -> %void { |
| 228 | \\ %%bar(); | 231 | \\ bar() catch unreachable; |
| 229 | \\} | 232 | \\} |
| 230 | \\fn bar() -> %void { | 233 | \\fn bar() -> %void { |
| 231 | \\ return error.Whatever; | 234 | \\ return error.Whatever; |
test/tests.zig+8-8| ... | @@ -33,7 +33,7 @@ const test_targets = []TestTarget { | ... | @@ -33,7 +33,7 @@ const test_targets = []TestTarget { |
| 33 | .environ = builtin.Environ.gnu, | 33 | .environ = builtin.Environ.gnu, |
| 34 | }, | 34 | }, |
| 35 | TestTarget { | 35 | TestTarget { |
| 36 | .os = builtin.Os.darwin, | 36 | .os = builtin.Os.macosx, |
| 37 | .arch = builtin.Arch.x86_64, | 37 | .arch = builtin.Arch.x86_64, |
| 38 | .environ = builtin.Environ.unknown, | 38 | .environ = builtin.Environ.unknown, |
| 39 | }, | 39 | }, |
| ... | @@ -259,7 +259,7 @@ pub const CompareOutputContext = struct { | ... | @@ -259,7 +259,7 @@ pub const CompareOutputContext = struct { |
| 259 | child.stderr_behavior = StdIo.Pipe; | 259 | child.stderr_behavior = StdIo.Pipe; |
| 260 | child.env_map = &b.env_map; | 260 | child.env_map = &b.env_map; |
| 261 | 261 | ||
| 262 | child.spawn() %% |err| debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); | 262 | child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); |
| 263 | 263 | ||
| 264 | var stdout = Buffer.initNull(b.allocator); | 264 | var stdout = Buffer.initNull(b.allocator); |
| 265 | var stderr = Buffer.initNull(b.allocator); | 265 | var stderr = Buffer.initNull(b.allocator); |
| ... | @@ -270,7 +270,7 @@ pub const CompareOutputContext = struct { | ... | @@ -270,7 +270,7 @@ pub const CompareOutputContext = struct { |
| 270 | %%stdout_file_in_stream.stream.readAllBuffer(&stdout, max_stdout_size); | 270 | %%stdout_file_in_stream.stream.readAllBuffer(&stdout, max_stdout_size); |
| 271 | %%stderr_file_in_stream.stream.readAllBuffer(&stderr, max_stdout_size); | 271 | %%stderr_file_in_stream.stream.readAllBuffer(&stderr, max_stdout_size); |
| 272 | 272 | ||
| 273 | const term = child.wait() %% |err| { | 273 | const term = child.wait() catch |err| { |
| 274 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); | 274 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); |
| 275 | }; | 275 | }; |
| 276 | switch (term) { | 276 | switch (term) { |
| ... | @@ -341,7 +341,7 @@ pub const CompareOutputContext = struct { | ... | @@ -341,7 +341,7 @@ pub const CompareOutputContext = struct { |
| 341 | child.stdout_behavior = StdIo.Ignore; | 341 | child.stdout_behavior = StdIo.Ignore; |
| 342 | child.stderr_behavior = StdIo.Ignore; | 342 | child.stderr_behavior = StdIo.Ignore; |
| 343 | 343 | ||
| 344 | const term = child.spawnAndWait() %% |err| { | 344 | const term = child.spawnAndWait() catch |err| { |
| 345 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); | 345 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); |
| 346 | }; | 346 | }; |
| 347 | 347 | ||
| ... | @@ -590,7 +590,7 @@ pub const CompileErrorContext = struct { | ... | @@ -590,7 +590,7 @@ pub const CompileErrorContext = struct { |
| 590 | child.stdout_behavior = StdIo.Pipe; | 590 | child.stdout_behavior = StdIo.Pipe; |
| 591 | child.stderr_behavior = StdIo.Pipe; | 591 | child.stderr_behavior = StdIo.Pipe; |
| 592 | 592 | ||
| 593 | child.spawn() %% |err| debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err)); | 593 | child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err)); |
| 594 | 594 | ||
| 595 | var stdout_buf = Buffer.initNull(b.allocator); | 595 | var stdout_buf = Buffer.initNull(b.allocator); |
| 596 | var stderr_buf = Buffer.initNull(b.allocator); | 596 | var stderr_buf = Buffer.initNull(b.allocator); |
| ... | @@ -601,7 +601,7 @@ pub const CompileErrorContext = struct { | ... | @@ -601,7 +601,7 @@ pub const CompileErrorContext = struct { |
| 601 | %%stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size); | 601 | %%stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size); |
| 602 | %%stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size); | 602 | %%stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size); |
| 603 | 603 | ||
| 604 | const term = child.wait() %% |err| { | 604 | const term = child.wait() catch |err| { |
| 605 | debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err)); | 605 | debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err)); |
| 606 | }; | 606 | }; |
| 607 | switch (term) { | 607 | switch (term) { |
| ... | @@ -862,7 +862,7 @@ pub const TranslateCContext = struct { | ... | @@ -862,7 +862,7 @@ pub const TranslateCContext = struct { |
| 862 | child.stdout_behavior = StdIo.Pipe; | 862 | child.stdout_behavior = StdIo.Pipe; |
| 863 | child.stderr_behavior = StdIo.Pipe; | 863 | child.stderr_behavior = StdIo.Pipe; |
| 864 | 864 | ||
| 865 | child.spawn() %% |err| debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err)); | 865 | child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err)); |
| 866 | 866 | ||
| 867 | var stdout_buf = Buffer.initNull(b.allocator); | 867 | var stdout_buf = Buffer.initNull(b.allocator); |
| 868 | var stderr_buf = Buffer.initNull(b.allocator); | 868 | var stderr_buf = Buffer.initNull(b.allocator); |
| ... | @@ -873,7 +873,7 @@ pub const TranslateCContext = struct { | ... | @@ -873,7 +873,7 @@ pub const TranslateCContext = struct { |
| 873 | %%stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size); | 873 | %%stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size); |
| 874 | %%stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size); | 874 | %%stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size); |
| 875 | 875 | ||
| 876 | const term = child.wait() %% |err| { | 876 | const term = child.wait() catch |err| { |
| 877 | debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err)); | 877 | debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err)); |
| 878 | }; | 878 | }; |
| 879 | switch (term) { | 879 | switch (term) { |