authorgravatar for tgschultz@gmail.comtgschultz <tgschultz@gmail.com> 2018-05-30 08:26:13-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2018-05-30 08:26:13-05:00
log8174f972a779384b287528e46ea086c714ce5553
tree02e919ffd9a783abb5b984aaefd9c4b03f608e8b
parent8c1872543c8cf76215cc4bf3ced4637bb1065a4e
parent15302e84a45a04cfe94a8842318f02a608055962
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #2 from ziglang/master

sync with ziglang

198 files changed, 15364 insertions(+), 9347 deletions(-)

CMakeLists.txt+1-1
...@@ -196,7 +196,7 @@ else()...@@ -196,7 +196,7 @@ else()
196 if(MSVC)196 if(MSVC)
197 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -D_CRT_SECURE_NO_WARNINGS /w")197 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -D_CRT_SECURE_NO_WARNINGS /w")
198 else()198 else()
199 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment")199 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment -Wno-class-memaccess -Wno-unknown-warning-option")
200 endif()200 endif()
201 set_target_properties(embedded_lld_lib PROPERTIES201 set_target_properties(embedded_lld_lib PROPERTIES
202 COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS}202 COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS}
README.md+7-4
...@@ -1,9 +1,9 @@...@@ -1,9 +1,9 @@
1![ZIG](http://ziglang.org/zig-logo.svg)1![ZIG](https://ziglang.org/zig-logo.svg)
22
3A programming language designed for robustness, optimality, and3A programming language designed for robustness, optimality, and
4clarity.4clarity.
55
6[ziglang.org](http://ziglang.org)6[ziglang.org](https://ziglang.org)
77
8## Feature Highlights8## Feature Highlights
99
...@@ -114,7 +114,7 @@ libc. Create demo games using Zig....@@ -114,7 +114,7 @@ libc. Create demo games using Zig.
114114
115## Building115## Building
116116
117[![Build Status](https://travis-ci.org/zig-lang/zig.svg?branch=master)](https://travis-ci.org/zig-lang/zig)117[![Build Status](https://travis-ci.org/ziglang/zig.svg?branch=master)](https://travis-ci.org/ziglang/zig)
118[![Build status](https://ci.appveyor.com/api/projects/status/4t80mk2dmucrc38i/branch/master?svg=true)](https://ci.appveyor.com/project/andrewrk/zig-d3l86/branch/master)118[![Build status](https://ci.appveyor.com/api/projects/status/4t80mk2dmucrc38i/branch/master?svg=true)](https://ci.appveyor.com/project/andrewrk/zig-d3l86/branch/master)
119119
120### Stage 1: Build Zig from C++ Source Code120### Stage 1: Build Zig from C++ Source Code
...@@ -161,7 +161,7 @@ bin/zig build --build-file ../build.zig test...@@ -161,7 +161,7 @@ bin/zig build --build-file ../build.zig test
161161
162##### Windows162##### Windows
163163
164See https://github.com/zig-lang/zig/wiki/Building-Zig-on-Windows164See https://github.com/ziglang/zig/wiki/Building-Zig-on-Windows
165165
166### Stage 2: Build Self-Hosted Zig from Zig Source Code166### Stage 2: Build Self-Hosted Zig from Zig Source Code
167167
...@@ -182,6 +182,9 @@ binary....@@ -182,6 +182,9 @@ binary.
182182
183This is the actual compiler binary that we will install to the system.183This is the actual compiler binary that we will install to the system.
184184
185*Note: Stage 2 compiler is not yet able to build Stage 3. Building Stage 3 is
186not yet supported.*
187
185#### Debug / Development Build188#### Debug / Development Build
186189
187```190```
build.zig+34-25
...@@ -16,7 +16,7 @@ pub fn build(b: &Builder) !void {...@@ -16,7 +16,7 @@ pub fn build(b: &Builder) !void {
16 var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");16 var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
1717
18 const rel_zig_exe = try os.path.relative(b.allocator, b.build_root, b.zig_exe);18 const rel_zig_exe = try os.path.relative(b.allocator, b.build_root, b.zig_exe);
19 var docgen_cmd = b.addCommand(null, b.env_map, [][]const u8 {19 var docgen_cmd = b.addCommand(null, b.env_map, [][]const u8{
20 docgen_exe.getOutputPath(),20 docgen_exe.getOutputPath(),
21 rel_zig_exe,21 rel_zig_exe,
22 "doc/langref.html.in",22 "doc/langref.html.in",
...@@ -30,7 +30,10 @@ pub fn build(b: &Builder) !void {...@@ -30,7 +30,10 @@ pub fn build(b: &Builder) !void {
30 const test_step = b.step("test", "Run all the tests");30 const test_step = b.step("test", "Run all the tests");
3131
32 // find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library32 // find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library
33 const build_info = try b.exec([][]const u8{b.zig_exe, "BUILD_INFO"});33 const build_info = try b.exec([][]const u8{
34 b.zig_exe,
35 "BUILD_INFO",
36 });
34 var index: usize = 0;37 var index: usize = 0;
35 const cmake_binary_dir = nextValue(&index, build_info);38 const cmake_binary_dir = nextValue(&index, build_info);
36 const cxx_compiler = nextValue(&index, build_info);39 const cxx_compiler = nextValue(&index, build_info);
...@@ -67,7 +70,10 @@ pub fn build(b: &Builder) !void {...@@ -67,7 +70,10 @@ pub fn build(b: &Builder) !void {
67 dependOnLib(exe, llvm);70 dependOnLib(exe, llvm);
6871
69 if (exe.target.getOs() == builtin.Os.linux) {72 if (exe.target.getOs() == builtin.Os.linux) {
70 const libstdcxx_path_padded = try b.exec([][]const u8{cxx_compiler, "-print-file-name=libstdc++.a"});73 const libstdcxx_path_padded = try b.exec([][]const u8{
74 cxx_compiler,
75 "-print-file-name=libstdc++.a",
76 });
71 const libstdcxx_path = ??mem.split(libstdcxx_path_padded, "\r\n").next();77 const libstdcxx_path = ??mem.split(libstdcxx_path_padded, "\r\n").next();
72 if (mem.eql(u8, libstdcxx_path, "libstdc++.a")) {78 if (mem.eql(u8, libstdcxx_path, "libstdc++.a")) {
73 warn(79 warn(
...@@ -111,17 +117,11 @@ pub fn build(b: &Builder) !void {...@@ -111,17 +117,11 @@ pub fn build(b: &Builder) !void {
111117
112 test_step.dependOn(docs_step);118 test_step.dependOn(docs_step);
113119
114 test_step.dependOn(tests.addPkgTests(b, test_filter,120 test_step.dependOn(tests.addPkgTests(b, test_filter, "test/behavior.zig", "behavior", "Run the behavior tests", with_lldb));
115 "test/behavior.zig", "behavior", "Run the behavior tests",
116 with_lldb));
117121
118 test_step.dependOn(tests.addPkgTests(b, test_filter,122 test_step.dependOn(tests.addPkgTests(b, test_filter, "std/index.zig", "std", "Run the standard library tests", with_lldb));
119 "std/index.zig", "std", "Run the standard library tests",
120 with_lldb));
121123
122 test_step.dependOn(tests.addPkgTests(b, test_filter,124 test_step.dependOn(tests.addPkgTests(b, test_filter, "std/special/compiler_rt/index.zig", "compiler-rt", "Run the compiler_rt tests", with_lldb));
123 "std/special/compiler_rt/index.zig", "compiler-rt", "Run the compiler_rt tests",
124 with_lldb));
125125
126 test_step.dependOn(tests.addCompareOutputTests(b, test_filter));126 test_step.dependOn(tests.addCompareOutputTests(b, test_filter));
127 test_step.dependOn(tests.addBuildExampleTests(b, test_filter));127 test_step.dependOn(tests.addBuildExampleTests(b, test_filter));
...@@ -149,8 +149,7 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) vo...@@ -149,8 +149,7 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) vo
149149
150fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) void {150fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) void {
151 const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";151 const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";
152 lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp",152 lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp", b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
153 b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
154}153}
155154
156const LibraryDep = struct {155const LibraryDep = struct {
...@@ -161,11 +160,21 @@ const LibraryDep = struct {...@@ -161,11 +160,21 @@ const LibraryDep = struct {
161};160};
162161
163fn findLLVM(b: &Builder, llvm_config_exe: []const u8) !LibraryDep {162fn findLLVM(b: &Builder, llvm_config_exe: []const u8) !LibraryDep {
164 const libs_output = try b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"});163 const libs_output = try b.exec([][]const u8{
165 const includes_output = try b.exec([][]const u8{llvm_config_exe, "--includedir"});164 llvm_config_exe,
166 const libdir_output = try b.exec([][]const u8{llvm_config_exe, "--libdir"});165 "--libs",
166 "--system-libs",
167 });
168 const includes_output = try b.exec([][]const u8{
169 llvm_config_exe,
170 "--includedir",
171 });
172 const libdir_output = try b.exec([][]const u8{
173 llvm_config_exe,
174 "--libdir",
175 });
167176
168 var result = LibraryDep {177 var result = LibraryDep{
169 .libs = ArrayList([]const u8).init(b.allocator),178 .libs = ArrayList([]const u8).init(b.allocator),
170 .system_libs = ArrayList([]const u8).init(b.allocator),179 .system_libs = ArrayList([]const u8).init(b.allocator),
171 .includes = ArrayList([]const u8).init(b.allocator),180 .includes = ArrayList([]const u8).init(b.allocator),
...@@ -227,17 +236,17 @@ pub fn installCHeaders(b: &Builder, c_header_files: []const u8) void {...@@ -227,17 +236,17 @@ pub fn installCHeaders(b: &Builder, c_header_files: []const u8) void {
227}236}
228237
229fn nextValue(index: &usize, build_info: []const u8) []const u8 {238fn nextValue(index: &usize, build_info: []const u8) []const u8 {
230 const start = *index;239 const start = index.*;
231 while (true) : (*index += 1) {240 while (true) : (index.* += 1) {
232 switch (build_info[*index]) {241 switch (build_info[index.*]) {
233 '\n' => {242 '\n' => {
234 const result = build_info[start..*index];243 const result = build_info[start..index.*];
235 *index += 1;244 index.* += 1;
236 return result;245 return result;
237 },246 },
238 '\r' => {247 '\r' => {
239 const result = build_info[start..*index];248 const result = build_info[start..index.*];
240 *index += 2;249 index.* += 2;
241 return result;250 return result;
242 },251 },
243 else => continue,252 else => continue,
doc/docgen.zig+117-65
...@@ -95,7 +95,7 @@ const Tokenizer = struct {...@@ -95,7 +95,7 @@ const Tokenizer = struct {
95 };95 };
9696
97 fn init(source_file_name: []const u8, buffer: []const u8) Tokenizer {97 fn init(source_file_name: []const u8, buffer: []const u8) Tokenizer {
98 return Tokenizer {98 return Tokenizer{
99 .buffer = buffer,99 .buffer = buffer,
100 .index = 0,100 .index = 0,
101 .state = State.Start,101 .state = State.Start,
...@@ -105,7 +105,7 @@ const Tokenizer = struct {...@@ -105,7 +105,7 @@ const Tokenizer = struct {
105 }105 }
106106
107 fn next(self: &Tokenizer) Token {107 fn next(self: &Tokenizer) Token {
108 var result = Token {108 var result = Token{
109 .id = Token.Id.Eof,109 .id = Token.Id.Eof,
110 .start = self.index,110 .start = self.index,
111 .end = undefined,111 .end = undefined,
...@@ -197,7 +197,7 @@ const Tokenizer = struct {...@@ -197,7 +197,7 @@ const Tokenizer = struct {
197 };197 };
198198
199 fn getTokenLocation(self: &Tokenizer, token: &const Token) Location {199 fn getTokenLocation(self: &Tokenizer, token: &const Token) Location {
200 var loc = Location {200 var loc = Location{
201 .line = 0,201 .line = 0,
202 .column = 0,202 .column = 0,
203 .line_start = 0,203 .line_start = 0,
...@@ -346,7 +346,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {...@@ -346,7 +346,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {
346 break;346 break;
347 },347 },
348 Token.Id.Content => {348 Token.Id.Content => {
349 try nodes.append(Node {.Content = tokenizer.buffer[token.start..token.end] });349 try nodes.append(Node{ .Content = tokenizer.buffer[token.start..token.end] });
350 },350 },
351 Token.Id.BracketOpen => {351 Token.Id.BracketOpen => {
352 const tag_token = try eatToken(tokenizer, Token.Id.TagContent);352 const tag_token = try eatToken(tokenizer, Token.Id.TagContent);
...@@ -365,11 +365,13 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {...@@ -365,11 +365,13 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {
365 header_stack_size += 1;365 header_stack_size += 1;
366366
367 const urlized = try urlize(allocator, content);367 const urlized = try urlize(allocator, content);
368 try nodes.append(Node{.HeaderOpen = HeaderOpen {368 try nodes.append(Node{
369 .name = content,369 .HeaderOpen = HeaderOpen{
370 .url = urlized,370 .name = content,
371 .n = header_stack_size,371 .url = urlized,
372 }});372 .n = header_stack_size,
373 },
374 });
373 if (try urls.put(urlized, tag_token)) |other_tag_token| {375 if (try urls.put(urlized, tag_token)) |other_tag_token| {
374 parseError(tokenizer, tag_token, "duplicate header url: #{}", urlized) catch {};376 parseError(tokenizer, tag_token, "duplicate header url: #{}", urlized) catch {};
375 parseError(tokenizer, other_tag_token, "other tag here") catch {};377 parseError(tokenizer, other_tag_token, "other tag here") catch {};
...@@ -407,14 +409,14 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {...@@ -407,14 +409,14 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {
407 switch (see_also_tok.id) {409 switch (see_also_tok.id) {
408 Token.Id.TagContent => {410 Token.Id.TagContent => {
409 const content = tokenizer.buffer[see_also_tok.start..see_also_tok.end];411 const content = tokenizer.buffer[see_also_tok.start..see_also_tok.end];
410 try list.append(SeeAlsoItem {412 try list.append(SeeAlsoItem{
411 .name = content,413 .name = content,
412 .token = see_also_tok,414 .token = see_also_tok,
413 });415 });
414 },416 },
415 Token.Id.Separator => {},417 Token.Id.Separator => {},
416 Token.Id.BracketClose => {418 Token.Id.BracketClose => {
417 try nodes.append(Node {.SeeAlso = list.toOwnedSlice() } );419 try nodes.append(Node{ .SeeAlso = list.toOwnedSlice() });
418 break;420 break;
419 },421 },
420 else => return parseError(tokenizer, see_also_tok, "invalid see_also token"),422 else => return parseError(tokenizer, see_also_tok, "invalid see_also token"),
...@@ -438,8 +440,8 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {...@@ -438,8 +440,8 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {
438 }440 }
439 };441 };
440442
441 try nodes.append(Node {443 try nodes.append(Node{
442 .Link = Link {444 .Link = Link{
443 .url = try urlize(allocator, url_name),445 .url = try urlize(allocator, url_name),
444 .name = name,446 .name = name,
445 .token = name_tok,447 .token = name_tok,
...@@ -463,24 +465,24 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {...@@ -463,24 +465,24 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {
463 var code_kind_id: Code.Id = undefined;465 var code_kind_id: Code.Id = undefined;
464 var is_inline = false;466 var is_inline = false;
465 if (mem.eql(u8, code_kind_str, "exe")) {467 if (mem.eql(u8, code_kind_str, "exe")) {
466 code_kind_id = Code.Id { .Exe = ExpectedOutcome.Succeed };468 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.Succeed };
467 } else if (mem.eql(u8, code_kind_str, "exe_err")) {469 } else if (mem.eql(u8, code_kind_str, "exe_err")) {
468 code_kind_id = Code.Id { .Exe = ExpectedOutcome.Fail };470 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.Fail };
469 } else if (mem.eql(u8, code_kind_str, "test")) {471 } else if (mem.eql(u8, code_kind_str, "test")) {
470 code_kind_id = Code.Id.Test;472 code_kind_id = Code.Id.Test;
471 } else if (mem.eql(u8, code_kind_str, "test_err")) {473 } else if (mem.eql(u8, code_kind_str, "test_err")) {
472 code_kind_id = Code.Id { .TestError = name};474 code_kind_id = Code.Id{ .TestError = name };
473 name = "test";475 name = "test";
474 } else if (mem.eql(u8, code_kind_str, "test_safety")) {476 } else if (mem.eql(u8, code_kind_str, "test_safety")) {
475 code_kind_id = Code.Id { .TestSafety = name};477 code_kind_id = Code.Id{ .TestSafety = name };
476 name = "test";478 name = "test";
477 } else if (mem.eql(u8, code_kind_str, "obj")) {479 } else if (mem.eql(u8, code_kind_str, "obj")) {
478 code_kind_id = Code.Id { .Obj = null };480 code_kind_id = Code.Id{ .Obj = null };
479 } else if (mem.eql(u8, code_kind_str, "obj_err")) {481 } else if (mem.eql(u8, code_kind_str, "obj_err")) {
480 code_kind_id = Code.Id { .Obj = name };482 code_kind_id = Code.Id{ .Obj = name };
481 name = "test";483 name = "test";
482 } else if (mem.eql(u8, code_kind_str, "syntax")) {484 } else if (mem.eql(u8, code_kind_str, "syntax")) {
483 code_kind_id = Code.Id { .Obj = null };485 code_kind_id = Code.Id{ .Obj = null };
484 is_inline = true;486 is_inline = true;
485 } else {487 } else {
486 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", code_kind_str);488 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", code_kind_str);
...@@ -514,17 +516,20 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {...@@ -514,17 +516,20 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {
514 return parseError(tokenizer, end_code_tag, "invalid token inside code_begin: {}", end_tag_name);516 return parseError(tokenizer, end_code_tag, "invalid token inside code_begin: {}", end_tag_name);
515 }517 }
516 _ = try eatToken(tokenizer, Token.Id.BracketClose);518 _ = try eatToken(tokenizer, Token.Id.BracketClose);
517 } else unreachable; // TODO issue #707519 } else
518 try nodes.append(Node {.Code = Code {520 unreachable; // TODO issue #707
519 .id = code_kind_id,521 try nodes.append(Node{
520 .name = name,522 .Code = Code{
521 .source_token = source_token,523 .id = code_kind_id,
522 .is_inline = is_inline,524 .name = name,
523 .mode = mode,525 .source_token = source_token,
524 .link_objects = link_objects.toOwnedSlice(),526 .is_inline = is_inline,
525 .target_windows = target_windows,527 .mode = mode,
526 .link_libc = link_libc,528 .link_objects = link_objects.toOwnedSlice(),
527 }});529 .target_windows = target_windows,
530 .link_libc = link_libc,
531 },
532 });
528 tokenizer.code_node_count += 1;533 tokenizer.code_node_count += 1;
529 } else {534 } else {
530 return parseError(tokenizer, tag_token, "unrecognized tag name: {}", tag_name);535 return parseError(tokenizer, tag_token, "unrecognized tag name: {}", tag_name);
...@@ -534,7 +539,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {...@@ -534,7 +539,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {
534 }539 }
535 }540 }
536541
537 return Toc {542 return Toc{
538 .nodes = nodes.toOwnedSlice(),543 .nodes = nodes.toOwnedSlice(),
539 .toc = toc_buf.toOwnedSlice(),544 .toc = toc_buf.toOwnedSlice(),
540 .urls = urls,545 .urls = urls,
...@@ -727,16 +732,19 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -727,16 +732,19 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
727 const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name);732 const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name);
728 const tmp_source_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_ext);733 const tmp_source_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_ext);
729 try io.writeFile(allocator, tmp_source_file_name, trimmed_raw_source);734 try io.writeFile(allocator, tmp_source_file_name, trimmed_raw_source);
730 735
731 switch (code.id) {736 switch (code.id) {
732 Code.Id.Exe => |expected_outcome| {737 Code.Id.Exe => |expected_outcome| {
733 const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);738 const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
734 const tmp_bin_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_bin_ext);739 const tmp_bin_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_bin_ext);
735 var build_args = std.ArrayList([]const u8).init(allocator);740 var build_args = std.ArrayList([]const u8).init(allocator);
736 defer build_args.deinit();741 defer build_args.deinit();
737 try build_args.appendSlice([][]const u8 {zig_exe,742 try build_args.appendSlice([][]const u8{
738 "build-exe", tmp_source_file_name,743 zig_exe,
739 "--output", tmp_bin_file_name,744 "build-exe",
745 tmp_source_file_name,
746 "--output",
747 tmp_bin_file_name,
740 });748 });
741 try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", code.name);749 try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", code.name);
742 switch (code.mode) {750 switch (code.mode) {
...@@ -766,10 +774,9 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -766,10 +774,9 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
766 try build_args.append("c");774 try build_args.append("c");
767 try out.print(" --library c");775 try out.print(" --library c");
768 }776 }
769 _ = exec(allocator, build_args.toSliceConst()) catch return parseError(777 _ = exec(allocator, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
770 tokenizer, code.source_token, "example failed to compile");
771778
772 const run_args = [][]const u8 {tmp_bin_file_name};779 const run_args = [][]const u8{tmp_bin_file_name};
773780
774 const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {781 const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {
775 const result = try os.ChildProcess.exec(allocator, run_args, null, null, max_doc_file_size);782 const result = try os.ChildProcess.exec(allocator, run_args, null, null, max_doc_file_size);
...@@ -777,7 +784,10 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -777,7 +784,10 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
777 os.ChildProcess.Term.Exited => |exit_code| {784 os.ChildProcess.Term.Exited => |exit_code| {
778 if (exit_code == 0) {785 if (exit_code == 0) {
779 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);786 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
780 for (run_args) |arg| warn("{} ", arg) else warn("\n");787 for (run_args) |arg|
788 warn("{} ", arg)
789 else
790 warn("\n");
781 return parseError(tokenizer, code.source_token, "example incorrectly compiled");791 return parseError(tokenizer, code.source_token, "example incorrectly compiled");
782 }792 }
783 },793 },
...@@ -785,11 +795,9 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -785,11 +795,9 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
785 }795 }
786 break :blk result;796 break :blk result;
787 } else blk: {797 } else blk: {
788 break :blk exec(allocator, run_args) catch return parseError(798 break :blk exec(allocator, run_args) catch return parseError(tokenizer, code.source_token, "example crashed");
789 tokenizer, code.source_token, "example crashed");
790 };799 };
791800
792
793 const escaped_stderr = try escapeHtml(allocator, result.stderr);801 const escaped_stderr = try escapeHtml(allocator, result.stderr);
794 const escaped_stdout = try escapeHtml(allocator, result.stdout);802 const escaped_stdout = try escapeHtml(allocator, result.stdout);
795803
...@@ -802,7 +810,11 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -802,7 +810,11 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
802 var test_args = std.ArrayList([]const u8).init(allocator);810 var test_args = std.ArrayList([]const u8).init(allocator);
803 defer test_args.deinit();811 defer test_args.deinit();
804812
805 try test_args.appendSlice([][]const u8 {zig_exe, "test", tmp_source_file_name});813 try test_args.appendSlice([][]const u8{
814 zig_exe,
815 "test",
816 tmp_source_file_name,
817 });
806 try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);818 try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);
807 switch (code.mode) {819 switch (code.mode) {
808 builtin.Mode.Debug => {},820 builtin.Mode.Debug => {},
...@@ -821,13 +833,15 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -821,13 +833,15 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
821 }833 }
822 if (code.target_windows) {834 if (code.target_windows) {
823 try test_args.appendSlice([][]const u8{835 try test_args.appendSlice([][]const u8{
824 "--target-os", "windows",836 "--target-os",
825 "--target-arch", "x86_64",837 "windows",
826 "--target-environ", "msvc",838 "--target-arch",
839 "x86_64",
840 "--target-environ",
841 "msvc",
827 });842 });
828 }843 }
829 const result = exec(allocator, test_args.toSliceConst()) catch return parseError(844 const result = exec(allocator, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed");
830 tokenizer, code.source_token, "test failed");
831 const escaped_stderr = try escapeHtml(allocator, result.stderr);845 const escaped_stderr = try escapeHtml(allocator, result.stderr);
832 const escaped_stdout = try escapeHtml(allocator, result.stdout);846 const escaped_stdout = try escapeHtml(allocator, result.stdout);
833 try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);847 try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);
...@@ -836,7 +850,13 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -836,7 +850,13 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
836 var test_args = std.ArrayList([]const u8).init(allocator);850 var test_args = std.ArrayList([]const u8).init(allocator);
837 defer test_args.deinit();851 defer test_args.deinit();
838852
839 try test_args.appendSlice([][]const u8 {zig_exe, "test", "--color", "on", tmp_source_file_name});853 try test_args.appendSlice([][]const u8{
854 zig_exe,
855 "test",
856 "--color",
857 "on",
858 tmp_source_file_name,
859 });
840 try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);860 try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);
841 switch (code.mode) {861 switch (code.mode) {
842 builtin.Mode.Debug => {},862 builtin.Mode.Debug => {},
...@@ -858,13 +878,19 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -858,13 +878,19 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
858 os.ChildProcess.Term.Exited => |exit_code| {878 os.ChildProcess.Term.Exited => |exit_code| {
859 if (exit_code == 0) {879 if (exit_code == 0) {
860 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);880 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
861 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");881 for (test_args.toSliceConst()) |arg|
882 warn("{} ", arg)
883 else
884 warn("\n");
862 return parseError(tokenizer, code.source_token, "example incorrectly compiled");885 return parseError(tokenizer, code.source_token, "example incorrectly compiled");
863 }886 }
864 },887 },
865 else => {888 else => {
866 warn("{}\nThe following command crashed:\n", result.stderr);889 warn("{}\nThe following command crashed:\n", result.stderr);
867 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");890 for (test_args.toSliceConst()) |arg|
891 warn("{} ", arg)
892 else
893 warn("\n");
868 return parseError(tokenizer, code.source_token, "example compile crashed");894 return parseError(tokenizer, code.source_token, "example compile crashed");
869 },895 },
870 }896 }
...@@ -881,7 +907,11 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -881,7 +907,11 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
881 var test_args = std.ArrayList([]const u8).init(allocator);907 var test_args = std.ArrayList([]const u8).init(allocator);
882 defer test_args.deinit();908 defer test_args.deinit();
883909
884 try test_args.appendSlice([][]const u8 {zig_exe, "test", tmp_source_file_name});910 try test_args.appendSlice([][]const u8{
911 zig_exe,
912 "test",
913 tmp_source_file_name,
914 });
885 switch (code.mode) {915 switch (code.mode) {
886 builtin.Mode.Debug => {},916 builtin.Mode.Debug => {},
887 builtin.Mode.ReleaseSafe => try test_args.append("--release-safe"),917 builtin.Mode.ReleaseSafe => try test_args.append("--release-safe"),
...@@ -894,13 +924,19 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -894,13 +924,19 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
894 os.ChildProcess.Term.Exited => |exit_code| {924 os.ChildProcess.Term.Exited => |exit_code| {
895 if (exit_code == 0) {925 if (exit_code == 0) {
896 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);926 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
897 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");927 for (test_args.toSliceConst()) |arg|
928 warn("{} ", arg)
929 else
930 warn("\n");
898 return parseError(tokenizer, code.source_token, "example test incorrectly succeeded");931 return parseError(tokenizer, code.source_token, "example test incorrectly succeeded");
899 }932 }
900 },933 },
901 else => {934 else => {
902 warn("{}\nThe following command crashed:\n", result.stderr);935 warn("{}\nThe following command crashed:\n", result.stderr);
903 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");936 for (test_args.toSliceConst()) |arg|
937 warn("{} ", arg)
938 else
939 warn("\n");
904 return parseError(tokenizer, code.source_token, "example compile crashed");940 return parseError(tokenizer, code.source_token, "example compile crashed");
905 },941 },
906 }942 }
...@@ -918,9 +954,15 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -918,9 +954,15 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
918 var build_args = std.ArrayList([]const u8).init(allocator);954 var build_args = std.ArrayList([]const u8).init(allocator);
919 defer build_args.deinit();955 defer build_args.deinit();
920956
921 try build_args.appendSlice([][]const u8 {zig_exe, "build-obj", tmp_source_file_name,957 try build_args.appendSlice([][]const u8{
922 "--color", "on",958 zig_exe,
923 "--output", tmp_obj_file_name});959 "build-obj",
960 tmp_source_file_name,
961 "--color",
962 "on",
963 "--output",
964 tmp_obj_file_name,
965 });
924966
925 if (!code.is_inline) {967 if (!code.is_inline) {
926 try out.print("<pre><code class=\"shell\">$ zig build-obj {}.zig", code.name);968 try out.print("<pre><code class=\"shell\">$ zig build-obj {}.zig", code.name);
...@@ -954,13 +996,19 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -954,13 +996,19 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
954 os.ChildProcess.Term.Exited => |exit_code| {996 os.ChildProcess.Term.Exited => |exit_code| {
955 if (exit_code == 0) {997 if (exit_code == 0) {
956 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);998 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
957 for (build_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");999 for (build_args.toSliceConst()) |arg|
1000 warn("{} ", arg)
1001 else
1002 warn("\n");
958 return parseError(tokenizer, code.source_token, "example build incorrectly succeeded");1003 return parseError(tokenizer, code.source_token, "example build incorrectly succeeded");
959 }1004 }
960 },1005 },
961 else => {1006 else => {
962 warn("{}\nThe following command crashed:\n", result.stderr);1007 warn("{}\nThe following command crashed:\n", result.stderr);
963 for (build_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");1008 for (build_args.toSliceConst()) |arg|
1009 warn("{} ", arg)
1010 else
1011 warn("\n");
964 return parseError(tokenizer, code.source_token, "example compile crashed");1012 return parseError(tokenizer, code.source_token, "example compile crashed");
965 },1013 },
966 }1014 }
...@@ -975,8 +1023,7 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -975,8 +1023,7 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
975 try out.print("</code></pre>\n");1023 try out.print("</code></pre>\n");
976 }1024 }
977 } else {1025 } else {
978 _ = exec(allocator, build_args.toSliceConst()) catch return parseError(1026 _ = exec(allocator, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
979 tokenizer, code.source_token, "example failed to compile");
980 }1027 }
981 if (!code.is_inline) {1028 if (!code.is_inline) {
982 try out.print("</code></pre>\n");1029 try out.print("</code></pre>\n");
...@@ -987,7 +1034,6 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var...@@ -987,7 +1034,6 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var
987 },1034 },
988 }1035 }
989 }1036 }
990
991}1037}
9921038
993fn exec(allocator: &mem.Allocator, args: []const []const u8) !os.ChildProcess.ExecResult {1039fn exec(allocator: &mem.Allocator, args: []const []const u8) !os.ChildProcess.ExecResult {
...@@ -996,13 +1042,19 @@ fn exec(allocator: &mem.Allocator, args: []const []const u8) !os.ChildProcess.Ex...@@ -996,13 +1042,19 @@ fn exec(allocator: &mem.Allocator, args: []const []const u8) !os.ChildProcess.Ex
996 os.ChildProcess.Term.Exited => |exit_code| {1042 os.ChildProcess.Term.Exited => |exit_code| {
997 if (exit_code != 0) {1043 if (exit_code != 0) {
998 warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);1044 warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);
999 for (args) |arg| warn("{} ", arg) else warn("\n");1045 for (args) |arg|
1046 warn("{} ", arg)
1047 else
1048 warn("\n");
1000 return error.ChildExitError;1049 return error.ChildExitError;
1001 }1050 }
1002 },1051 },
1003 else => {1052 else => {
1004 warn("{}\nThe following command crashed:\n", result.stderr);1053 warn("{}\nThe following command crashed:\n", result.stderr);
1005 for (args) |arg| warn("{} ", arg) else warn("\n");1054 for (args) |arg|
1055 warn("{} ", arg)
1056 else
1057 warn("\n");
1006 return error.ChildCrashed;1058 return error.ChildCrashed;
1007 },1059 },
1008 }1060 }
doc/langref.html.in+133-40
...@@ -96,7 +96,7 @@...@@ -96,7 +96,7 @@
96 </p>96 </p>
97 <p>97 <p>
98 If you search for something specific in this documentation and do not find it,98 If you search for something specific in this documentation and do not find it,
99 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>.99 please <a href="https://github.com/ziglang/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>.
100 </p>100 </p>
101 <p>101 <p>
102 The code samples in this document are compiled and tested as part of the main test suite of Zig.102 The code samples in this document are compiled and tested as part of the main test suite of Zig.
...@@ -1232,7 +1232,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>...@@ -1232,7 +1232,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>
1232 </td>1232 </td>
1233 </tr>1233 </tr>
1234 <tr>1234 <tr>
1235 <td><pre><code class="zig">*a<code></pre></td>1235 <td><pre><code class="zig">a.*<code></pre></td>
1236 <td>1236 <td>
1237 <ul>1237 <ul>
1238 <li>{#link|Pointers#}</li>1238 <li>{#link|Pointers#}</li>
...@@ -1244,7 +1244,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>...@@ -1244,7 +1244,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>
1244 <td>1244 <td>
1245 <pre><code class="zig">const x: u32 = 1234;1245 <pre><code class="zig">const x: u32 = 1234;
1246const ptr = &amp;x;1246const ptr = &amp;x;
1247*x == 1234</code></pre>1247x.* == 1234</code></pre>
1248 </td>1248 </td>
1249 </tr>1249 </tr>
1250 <tr>1250 <tr>
...@@ -1258,7 +1258,7 @@ const ptr = &amp;x;...@@ -1258,7 +1258,7 @@ const ptr = &amp;x;
1258 <td>1258 <td>
1259 <pre><code class="zig">const x: u32 = 1234;1259 <pre><code class="zig">const x: u32 = 1234;
1260const ptr = &amp;x;1260const ptr = &amp;x;
1261*x == 1234</code></pre>1261x.* == 1234</code></pre>
1262 </td>1262 </td>
1263 </tr>1263 </tr>
1264 </table>1264 </table>
...@@ -1267,8 +1267,8 @@ const ptr = &amp;x;...@@ -1267,8 +1267,8 @@ const ptr = &amp;x;
1267 {#header_open|Precedence#}1267 {#header_open|Precedence#}
1268 <pre><code>x() x[] x.y1268 <pre><code>x() x[] x.y
1269a!b1269a!b
1270!x -x -%x ~x *x &amp;x ?x ??x1270!x -x -%x ~x &amp;x ?x ??x
1271x{}1271x{} x.*
1272! * / % ** *%1272! * / % ** *%
1273+ - ++ +% -%1273+ - ++ +% -%
1274&lt;&lt; &gt;&gt;1274&lt;&lt; &gt;&gt;
...@@ -1316,7 +1316,7 @@ var some_integers: [100]i32 = undefined;...@@ -1316,7 +1316,7 @@ var some_integers: [100]i32 = undefined;
13161316
1317test "modify an array" {1317test "modify an array" {
1318 for (some_integers) |*item, i| {1318 for (some_integers) |*item, i| {
1319 *item = i32(i);1319 item.* = i32(i);
1320 }1320 }
1321 assert(some_integers[10] == 10);1321 assert(some_integers[10] == 10);
1322 assert(some_integers[99] == 99);1322 assert(some_integers[99] == 99);
...@@ -1357,7 +1357,7 @@ comptime {...@@ -1357,7 +1357,7 @@ comptime {
1357var fancy_array = init: {1357var fancy_array = init: {
1358 var initial_value: [10]Point = undefined;1358 var initial_value: [10]Point = undefined;
1359 for (initial_value) |*pt, i| {1359 for (initial_value) |*pt, i| {
1360 *pt = Point {1360 pt.* = Point {
1361 .x = i32(i),1361 .x = i32(i),
1362 .y = i32(i) * 2,1362 .y = i32(i) * 2,
1363 };1363 };
...@@ -1400,7 +1400,7 @@ test "address of syntax" {...@@ -1400,7 +1400,7 @@ test "address of syntax" {
1400 const x_ptr = &x;1400 const x_ptr = &x;
14011401
1402 // Deference a pointer:1402 // Deference a pointer:
1403 assert(*x_ptr == 1234);1403 assert(x_ptr.* == 1234);
14041404
1405 // When you get the address of a const variable, you get a const pointer.1405 // When you get the address of a const variable, you get a const pointer.
1406 assert(@typeOf(x_ptr) == &const i32);1406 assert(@typeOf(x_ptr) == &const i32);
...@@ -1409,8 +1409,8 @@ test "address of syntax" {...@@ -1409,8 +1409,8 @@ test "address of syntax" {
1409 var y: i32 = 5678;1409 var y: i32 = 5678;
1410 const y_ptr = &y;1410 const y_ptr = &y;
1411 assert(@typeOf(y_ptr) == &i32);1411 assert(@typeOf(y_ptr) == &i32);
1412 *y_ptr += 1;1412 y_ptr.* += 1;
1413 assert(*y_ptr == 5679);1413 assert(y_ptr.* == 5679);
1414}1414}
14151415
1416test "pointer array access" {1416test "pointer array access" {
...@@ -1448,9 +1448,9 @@ comptime {...@@ -1448,9 +1448,9 @@ comptime {
1448 // @ptrCast.1448 // @ptrCast.
1449 var x: i32 = 1;1449 var x: i32 = 1;
1450 const ptr = &x;1450 const ptr = &x;
1451 *ptr += 1;1451 ptr.* += 1;
1452 x += 1;1452 x += 1;
1453 assert(*ptr == 3);1453 assert(ptr.* == 3);
1454}1454}
14551455
1456test "@ptrToInt and @intToPtr" {1456test "@ptrToInt and @intToPtr" {
...@@ -1492,7 +1492,7 @@ test "nullable pointers" {...@@ -1492,7 +1492,7 @@ test "nullable pointers" {
1492 var x: i32 = 1;1492 var x: i32 = 1;
1493 ptr = &x;1493 ptr = &x;
14941494
1495 assert(*??ptr == 1);1495 assert((??ptr).* == 1);
14961496
1497 // Nullable pointers are the same size as normal pointers, because pointer1497 // Nullable pointers are the same size as normal pointers, because pointer
1498 // value 0 is used as the null value.1498 // value 0 is used as the null value.
...@@ -1505,7 +1505,7 @@ test "pointer casting" {...@@ -1505,7 +1505,7 @@ test "pointer casting" {
1505 // conversions are not possible.1505 // conversions are not possible.
1506 const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12};1506 const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12};
1507 const u32_ptr = @ptrCast(&const u32, &bytes[0]);1507 const u32_ptr = @ptrCast(&const u32, &bytes[0]);
1508 assert(*u32_ptr == 0x12121212);1508 assert(u32_ptr.* == 0x12121212);
15091509
1510 // Even this example is contrived - there are better ways to do the above than1510 // Even this example is contrived - there are better ways to do the above than
1511 // pointer casting. For example, using a slice narrowing cast:1511 // pointer casting. For example, using a slice narrowing cast:
...@@ -1610,7 +1610,7 @@ fn foo(bytes: []u8) u32 {...@@ -1610,7 +1610,7 @@ fn foo(bytes: []u8) u32 {
1610 <code>u8</code> can alias any memory.1610 <code>u8</code> can alias any memory.
1611 </p>1611 </p>
1612 <p>As an example, this code produces undefined behavior:</p>1612 <p>As an example, this code produces undefined behavior:</p>
1613 <pre><code class="zig">*@ptrCast(&amp;u32, f32(12.34))</code></pre>1613 <pre><code class="zig">@ptrCast(&amp;u32, f32(12.34)).*</code></pre>
1614 <p>Instead, use {#link|@bitCast#}:1614 <p>Instead, use {#link|@bitCast#}:
1615 <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>1615 <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>
1616 <p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p>1616 <p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p>
...@@ -2040,7 +2040,7 @@ const Variant = union(enum) {...@@ -2040,7 +2040,7 @@ const Variant = union(enum) {
2040 Bool: bool,2040 Bool: bool,
20412041
2042 fn truthy(self: &const Variant) bool {2042 fn truthy(self: &const Variant) bool {
2043 return switch (*self) {2043 return switch (self.*) {
2044 Variant.Int => |x_int| x_int != 0,2044 Variant.Int => |x_int| x_int != 0,
2045 Variant.Bool => |x_bool| x_bool,2045 Variant.Bool => |x_bool| x_bool,
2046 };2046 };
...@@ -2151,7 +2151,7 @@ test "switch enum" {...@@ -2151,7 +2151,7 @@ test "switch enum" {
21512151
2152 // A reference to the matched value can be obtained using `*` syntax.2152 // A reference to the matched value can be obtained using `*` syntax.
2153 Item.C => |*item| blk: {2153 Item.C => |*item| blk: {
2154 (*item).x += 1;2154 item.*.x += 1;
2155 break :blk 6;2155 break :blk 6;
2156 },2156 },
21572157
...@@ -2374,7 +2374,7 @@ test "for reference" {...@@ -2374,7 +2374,7 @@ test "for reference" {
2374 // Iterate over the slice by reference by2374 // Iterate over the slice by reference by
2375 // specifying that the capture value is a pointer.2375 // specifying that the capture value is a pointer.
2376 for (items) |*value| {2376 for (items) |*value| {
2377 *value += 1;2377 value.* += 1;
2378 }2378 }
23792379
2380 assert(items[0] == 4);2380 assert(items[0] == 4);
...@@ -2483,7 +2483,7 @@ test "if nullable" {...@@ -2483,7 +2483,7 @@ test "if nullable" {
2483 // Access the value by reference using a pointer capture.2483 // Access the value by reference using a pointer capture.
2484 var c: ?u32 = 3;2484 var c: ?u32 = 3;
2485 if (c) |*value| {2485 if (c) |*value| {
2486 *value = 2;2486 value.* = 2;
2487 }2487 }
24882488
2489 if (c) |value| {2489 if (c) |value| {
...@@ -2524,7 +2524,7 @@ test "if error union" {...@@ -2524,7 +2524,7 @@ test "if error union" {
2524 // Access the value by reference using a pointer capture.2524 // Access the value by reference using a pointer capture.
2525 var c: error!u32 = 3;2525 var c: error!u32 = 3;
2526 if (c) |*value| {2526 if (c) |*value| {
2527 *value = 9;2527 value.* = 9;
2528 } else |err| {2528 } else |err| {
2529 unreachable;2529 unreachable;
2530 }2530 }
...@@ -2827,7 +2827,7 @@ test "fn reflection" {...@@ -2827,7 +2827,7 @@ test "fn reflection" {
2827 </p>2827 </p>
2828 <p>2828 <p>
2829 The number of unique error values across the entire compilation should determine the size of the error set type.2829 The number of unique error values across the entire compilation should determine the size of the error set type.
2830 However right now it is hard coded to be a <code>u16</code>. See <a href="https://github.com/zig-lang/zig/issues/786">#768</a>.2830 However right now it is hard coded to be a <code>u16</code>. See <a href="https://github.com/ziglang/zig/issues/786">#768</a>.
2831 </p>2831 </p>
2832 <p>2832 <p>
2833 You can implicitly cast an error from a subset to its superset:2833 You can implicitly cast an error from a subset to its superset:
...@@ -3111,7 +3111,48 @@ test "error union" {...@@ -3111,7 +3111,48 @@ test "error union" {
3111 {#code_end#}3111 {#code_end#}
3112 <p>TODO the <code>||</code> operator for error sets</p>3112 <p>TODO the <code>||</code> operator for error sets</p>
3113 {#header_open|Inferred Error Sets#}3113 {#header_open|Inferred Error Sets#}
3114 <p>TODO</p>3114 <p>
3115 Because many functions in Zig return a possible error, Zig supports inferring the error set.
3116 To infer the error set for a function, use this syntax:
3117 </p>
3118{#code_begin|test#}
3119// With an inferred error set
3120pub fn add_inferred(comptime T: type, a: T, b: T) !T {
3121 var answer: T = undefined;
3122 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
3123}
3124
3125// With an explicit error set
3126pub fn add_explicit(comptime T: type, a: T, b: T) Error!T {
3127 var answer: T = undefined;
3128 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
3129}
3130
3131const Error = error {
3132 Overflow,
3133};
3134
3135const std = @import("std");
3136
3137test "inferred error set" {
3138 if (add_inferred(u8, 255, 1)) |_| unreachable else |err| switch (err) {
3139 error.Overflow => {}, // ok
3140 }
3141}
3142{#code_end#}
3143 <p>
3144 When a function has an inferred error set, that function becomes generic and thus it becomes
3145 trickier to do certain things with it, such as obtain a function pointer, or have an error
3146 set that is consistent across different build targets. Additionally, inferred error sets
3147 are incompatible with recursion.
3148 </p>
3149 <p>
3150 In these situations, it is recommended to use an explicit error set. You can generally start
3151 with an empty error set and let compile errors guide you toward completing the set.
3152 </p>
3153 <p>
3154 These limitations may be overcome in a future version of Zig.
3155 </p>
3115 {#header_close#}3156 {#header_close#}
3116 {#header_close#}3157 {#header_close#}
3117 {#header_open|Error Return Traces#}3158 {#header_open|Error Return Traces#}
...@@ -3872,13 +3913,22 @@ pub fn main() void {...@@ -3872,13 +3913,22 @@ pub fn main() void {
3872 {#header_open|@addWithOverflow#}3913 {#header_open|@addWithOverflow#}
3873 <pre><code class="zig">@addWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>3914 <pre><code class="zig">@addWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
3874 <p>3915 <p>
3875 Performs <code>*result = a + b</code>. If overflow or underflow occurs,3916 Performs <code>result.* = a + b</code>. If overflow or underflow occurs,
3876 stores the overflowed bits in <code>result</code> and returns <code>true</code>.3917 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
3877 If no overflow or underflow occurs, returns <code>false</code>.3918 If no overflow or underflow occurs, returns <code>false</code>.
3878 </p>3919 </p>
3879 {#header_close#}3920 {#header_close#}
3880 {#header_open|@ArgType#}3921 {#header_open|@ArgType#}
3881 <p>TODO</p>3922 <pre><code class="zig">@ArgType(comptime T: type, comptime n: usize) -&gt; type</code></pre>
3923 <p>
3924 This builtin function takes a function type and returns the type of the parameter at index <code>n</code>.
3925 </p>
3926 <p>
3927 <code>T</code> must be a function type.
3928 </p>
3929 <p>
3930 Note: This function is deprecated. Use {#link|@typeInfo#} instead.
3931 </p>
3882 {#header_close#}3932 {#header_close#}
3883 {#header_open|@atomicLoad#}3933 {#header_open|@atomicLoad#}
3884 <pre><code class="zig">@atomicLoad(comptime T: type, ptr: &amp;const T, comptime ordering: builtin.AtomicOrder) -&gt; T</code></pre>3934 <pre><code class="zig">@atomicLoad(comptime T: type, ptr: &amp;const T, comptime ordering: builtin.AtomicOrder) -&gt; T</code></pre>
...@@ -4073,9 +4123,9 @@ comptime {...@@ -4073,9 +4123,9 @@ comptime {
4073 </p>4123 </p>
4074 {#code_begin|syntax#}4124 {#code_begin|syntax#}
4075fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T {4125fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T {
4076 const old_value = *ptr;4126 const old_value = ptr.*;
4077 if (old_value == expected_value) {4127 if (old_value == expected_value) {
4078 *ptr = new_value;4128 ptr.* = new_value;
4079 return null;4129 return null;
4080 } else {4130 } else {
4081 return old_value;4131 return old_value;
...@@ -4100,9 +4150,9 @@ fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_v...@@ -4100,9 +4150,9 @@ fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_v
4100 </p>4150 </p>
4101 {#code_begin|syntax#}4151 {#code_begin|syntax#}
4102fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T {4152fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T {
4103 const old_value = *ptr;4153 const old_value = ptr.*;
4104 if (old_value == expected_value and usuallyTrueButSometimesFalse()) {4154 if (old_value == expected_value and usuallyTrueButSometimesFalse()) {
4105 *ptr = new_value;4155 ptr.* = new_value;
4106 return null;4156 return null;
4107 } else {4157 } else {
4108 return old_value;4158 return old_value;
...@@ -4447,7 +4497,7 @@ mem.copy(u8, dest[0...byte_count], source[0...byte_count]);</code></pre>...@@ -4447,7 +4497,7 @@ mem.copy(u8, dest[0...byte_count], source[0...byte_count]);</code></pre>
4447 This function is a low level intrinsic with no safety mechanisms. Most4497 This function is a low level intrinsic with no safety mechanisms. Most
4448 code should not use this function, instead using something like this:4498 code should not use this function, instead using something like this:
4449 </p>4499 </p>
4450 <pre><code class="zig">for (dest[0...byte_count]) |*b| *b = c;</code></pre>4500 <pre><code class="zig">for (dest[0...byte_count]) |*b| b.* = c;</code></pre>
4451 <p>4501 <p>
4452 The optimizer is intelligent enough to turn the above snippet into a memset.4502 The optimizer is intelligent enough to turn the above snippet into a memset.
4453 </p>4503 </p>
...@@ -4480,22 +4530,63 @@ mem.set(u8, dest, c);</code></pre>...@@ -4480,22 +4530,63 @@ mem.set(u8, dest, c);</code></pre>
4480 {#header_open|@mulWithOverflow#}4530 {#header_open|@mulWithOverflow#}
4481 <pre><code class="zig">@mulWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>4531 <pre><code class="zig">@mulWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
4482 <p>4532 <p>
4483 Performs <code>*result = a * b</code>. If overflow or underflow occurs,4533 Performs <code>result.* = a * b</code>. If overflow or underflow occurs,
4484 stores the overflowed bits in <code>result</code> and returns <code>true</code>.4534 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
4485 If no overflow or underflow occurs, returns <code>false</code>.4535 If no overflow or underflow occurs, returns <code>false</code>.
4486 </p>4536 </p>
4487 {#header_close#}4537 {#header_close#}
4538 {#header_open|@newStackCall#}
4539 <pre><code class="zig">@newStackCall(new_stack: []u8, function: var, args: ...) -&gt; var</code></pre>
4540 <p>
4541 This calls a function, in the same way that invoking an expression with parentheses does. However,
4542 instead of using the same stack as the caller, the function uses the stack provided in the <code>new_stack</code>
4543 parameter.
4544 </p>
4545 {#code_begin|test#}
4546const std = @import("std");
4547const assert = std.debug.assert;
4548
4549var new_stack_bytes: [1024]u8 = undefined;
4550
4551test "calling a function with a new stack" {
4552 const arg = 1234;
4553
4554 const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg);
4555 const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
4556 _ = targetFunction(arg);
4557
4558 assert(arg == 1234);
4559 assert(a < b);
4560}
4561
4562fn targetFunction(x: i32) usize {
4563 assert(x == 1234);
4564
4565 var local_variable: i32 = 42;
4566 const ptr = &local_variable;
4567 ptr.* += 1;
4568
4569 assert(local_variable == 43);
4570 return @ptrToInt(ptr);
4571}
4572 {#code_end#}
4573 {#header_close#}
4488 {#header_open|@noInlineCall#}4574 {#header_open|@noInlineCall#}
4489 <pre><code class="zig">@noInlineCall(function: var, args: ...) -&gt; var</code></pre>4575 <pre><code class="zig">@noInlineCall(function: var, args: ...) -&gt; var</code></pre>
4490 <p>4576 <p>
4491 This calls a function, in the same way that invoking an expression with parentheses does:4577 This calls a function, in the same way that invoking an expression with parentheses does:
4492 </p>4578 </p>
4493 <pre><code class="zig">const assert = @import("std").debug.assert;4579 {#code_begin|test#}
4580const assert = @import("std").debug.assert;
4581
4494test "noinline function call" {4582test "noinline function call" {
4495 assert(@noInlineCall(add, 3, 9) == 12);4583 assert(@noInlineCall(add, 3, 9) == 12);
4496}4584}
44974585
4498fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>4586fn add(a: i32, b: i32) i32 {
4587 return a + b;
4588}
4589 {#code_end#}
4499 <p>4590 <p>
4500 Unlike a normal function call, however, <code>@noInlineCall</code> guarantees that the call4591 Unlike a normal function call, however, <code>@noInlineCall</code> guarantees that the call
4501 will not be inlined. If the call must be inlined, a compile error is emitted.4592 will not be inlined. If the call must be inlined, a compile error is emitted.
...@@ -4705,7 +4796,7 @@ pub const FloatMode = enum {...@@ -4705,7 +4796,7 @@ pub const FloatMode = enum {
4705 {#header_open|@shlWithOverflow#}4796 {#header_open|@shlWithOverflow#}
4706 <pre><code class="zig">@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: &T) -&gt; bool</code></pre>4797 <pre><code class="zig">@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: &T) -&gt; bool</code></pre>
4707 <p>4798 <p>
4708 Performs <code>*result = a &lt;&lt; b</code>. If overflow or underflow occurs,4799 Performs <code>result.* = a &lt;&lt; b</code>. If overflow or underflow occurs,
4709 stores the overflowed bits in <code>result</code> and returns <code>true</code>.4800 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
4710 If no overflow or underflow occurs, returns <code>false</code>.4801 If no overflow or underflow occurs, returns <code>false</code>.
4711 </p>4802 </p>
...@@ -4749,7 +4840,7 @@ pub const FloatMode = enum {...@@ -4749,7 +4840,7 @@ pub const FloatMode = enum {
4749 {#header_open|@subWithOverflow#}4840 {#header_open|@subWithOverflow#}
4750 <pre><code class="zig">@subWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>4841 <pre><code class="zig">@subWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
4751 <p>4842 <p>
4752 Performs <code>*result = a - b</code>. If overflow or underflow occurs,4843 Performs <code>result.* = a - b</code>. If overflow or underflow occurs,
4753 stores the overflowed bits in <code>result</code> and returns <code>true</code>.4844 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
4754 If no overflow or underflow occurs, returns <code>false</code>.4845 If no overflow or underflow occurs, returns <code>false</code>.
4755 </p>4846 </p>
...@@ -5867,7 +5958,7 @@ pub fn main() void {...@@ -5867,7 +5958,7 @@ pub fn main() void {
5867 {#code_begin|exe#}5958 {#code_begin|exe#}
5868 {#link_libc#}5959 {#link_libc#}
5869const c = @cImport({5960const c = @cImport({
5870 // See https://github.com/zig-lang/zig/issues/5155961 // See https://github.com/ziglang/zig/issues/515
5871 @cDefine("_NO_CRT_STDIO_INLINE", "1");5962 @cDefine("_NO_CRT_STDIO_INLINE", "1");
5872 @cInclude("stdio.h");5963 @cInclude("stdio.h");
5873});5964});
...@@ -6210,7 +6301,7 @@ fn readU32Be() u32 {}...@@ -6210,7 +6301,7 @@ fn readU32Be() u32 {}
6210 <li>Non-Ascii Unicode line endings: U+0085 (NEL), U+2028 (LS), U+2029 (PS).</li>6301 <li>Non-Ascii Unicode line endings: U+0085 (NEL), U+2028 (LS), U+2029 (PS).</li>
6211 </ul>6302 </ul>
6212 <p>The codepoint U+000a (LF) (which is encoded as the single-byte value 0x0a) is the line terminator character. This character always terminates a line of zig source code (except possbly the last line of the file).</p>6303 <p>The codepoint U+000a (LF) (which is encoded as the single-byte value 0x0a) is the line terminator character. This character always terminates a line of zig source code (except possbly the last line of the file).</p>
6213 <p>For some discussion on the rationale behind these design decisions, see <a href="https://github.com/zig-lang/zig/issues/663">issue #663</a></p>6304 <p>For some discussion on the rationale behind these design decisions, see <a href="https://github.com/ziglang/zig/issues/663">issue #663</a></p>
6214 {#header_close#}6305 {#header_close#}
6215 {#header_open|Grammar#}6306 {#header_open|Grammar#}
6216 <pre><code class="nohighlight">Root = many(TopLevelItem) EOF6307 <pre><code class="nohighlight">Root = many(TopLevelItem) EOF
...@@ -6341,10 +6432,12 @@ MultiplyOperator = "||" | "*" | "/" | "%" | "**" | "*%"...@@ -6341,10 +6432,12 @@ MultiplyOperator = "||" | "*" | "/" | "%" | "**" | "*%"
63416432
6342PrefixOpExpression = PrefixOp TypeExpr | SuffixOpExpression6433PrefixOpExpression = PrefixOp TypeExpr | SuffixOpExpression
63436434
6344SuffixOpExpression = ("async" option("&lt;" SuffixOpExpression "&gt;") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)6435SuffixOpExpression = ("async" option("&lt;" SuffixOpExpression "&gt;") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression | PtrDerefExpression)
63456436
6346FieldAccessExpression = "." Symbol6437FieldAccessExpression = "." Symbol
63476438
6439PtrDerefExpression = ".*"
6440
6348FnCallExpression = "(" list(Expression, ",") ")"6441FnCallExpression = "(" list(Expression, ",") ")"
63496442
6350ArrayAccessExpression = "[" Expression "]"6443ArrayAccessExpression = "[" Expression "]"
...@@ -6357,7 +6450,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")...@@ -6357,7 +6450,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")
63576450
6358StructLiteralField = "." Symbol "=" Expression6451StructLiteralField = "." Symbol "=" Expression
63596452
6360PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"6453PrefixOp = "!" | "-" | "~" | ("*" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"
63616454
6362PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl | PromiseType6455PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl | PromiseType
63636456
...@@ -6451,7 +6544,7 @@ hljs.registerLanguage("zig", function(t) {...@@ -6451,7 +6544,7 @@ hljs.registerLanguage("zig", function(t) {
6451 a = t.IR + "\\s*\\(",6544 a = t.IR + "\\s*\\(",
6452 c = {6545 c = {
6453 keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong",6546 keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong",
6454 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic canImplicitCast ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo",6547 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic canImplicitCast ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo newStackCall",
6455 literal: "true false null undefined"6548 literal: "true false null undefined"
6456 },6549 },
6457 n = [e, t.CLCM, t.CBCM, s, r];6550 n = [e, t.CLCM, t.CBCM, s, r];
example/guess_number/main.zig+1-1
...@@ -23,7 +23,7 @@ pub fn main() !void {...@@ -23,7 +23,7 @@ pub fn main() !void {
2323
24 while (true) {24 while (true) {
25 try 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;
2727
28 const line_len = io.readLine(line_buf[0..]) catch |err| switch (err) {28 const line_len = io.readLine(line_buf[0..]) catch |err| switch (err) {
29 error.InputTooLong => {29 error.InputTooLong => {
example/hello_world/hello_libc.zig+2-3
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1const c = @cImport({1const c = @cImport({
2 // See https://github.com/zig-lang/zig/issues/5152 // See https://github.com/ziglang/zig/issues/515
3 @cDefine("_NO_CRT_STDIO_INLINE", "1");3 @cDefine("_NO_CRT_STDIO_INLINE", "1");
4 @cInclude("stdio.h");4 @cInclude("stdio.h");
5 @cInclude("string.h");5 @cInclude("string.h");
...@@ -8,8 +8,7 @@ const c = @cImport({...@@ -8,8 +8,7 @@ const c = @cImport({
8const msg = c"Hello, world!\n";8const msg = c"Hello, world!\n";
99
10export fn main(argc: c_int, argv: &&u8) c_int {10export fn main(argc: c_int, argv: &&u8) c_int {
11 if (c.printf(msg) != c_int(c.strlen(msg)))11 if (c.printf(msg) != c_int(c.strlen(msg))) return -1;
12 return -1;
1312
14 return 0;13 return 0;
15}14}
example/mix_o_files/build.zig+1-3
...@@ -4,9 +4,7 @@ pub fn build(b: &Builder) void {...@@ -4,9 +4,7 @@ pub fn build(b: &Builder) void {
4 const obj = b.addObject("base64", "base64.zig");4 const obj = b.addObject("base64", "base64.zig");
55
6 const exe = b.addCExecutable("test");6 const exe = b.addCExecutable("test");
7 exe.addCompileFlags([][]const u8 {7 exe.addCompileFlags([][]const u8{"-std=c99"});
8 "-std=c99",
9 });
10 exe.addSourceFile("test.c");8 exe.addSourceFile("test.c");
11 exe.addObject(obj);9 exe.addObject(obj);
1210
example/shared_library/build.zig+1-3
...@@ -4,9 +4,7 @@ pub fn build(b: &Builder) void {...@@ -4,9 +4,7 @@ pub fn build(b: &Builder) void {
4 const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));4 const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
55
6 const exe = b.addCExecutable("test");6 const exe = b.addCExecutable("test");
7 exe.addCompileFlags([][]const u8 {7 exe.addCompileFlags([][]const u8{"-std=c99"});
8 "-std=c99",
9 });
10 exe.addSourceFile("test.c");8 exe.addSourceFile("test.c");
11 exe.linkLibrary(lib);9 exe.linkLibrary(lib);
1210
src-self-hosted/arg.zig+41-33
...@@ -30,24 +30,22 @@ fn argInAllowedSet(maybe_set: ?[]const []const u8, arg: []const u8) bool {...@@ -30,24 +30,22 @@ fn argInAllowedSet(maybe_set: ?[]const []const u8, arg: []const u8) bool {
30}30}
3131
32// Modifies the current argument index during iteration32// Modifies the current argument index during iteration
33fn readFlagArguments(allocator: &Allocator, args: []const []const u8, required: usize,33fn readFlagArguments(allocator: &Allocator, args: []const []const u8, required: usize, allowed_set: ?[]const []const u8, index: &usize) !FlagArg {
34 allowed_set: ?[]const []const u8, index: &usize) !FlagArg {
35
36 switch (required) {34 switch (required) {
37 0 => return FlagArg { .None = undefined }, // TODO: Required to force non-tag but value?35 0 => return FlagArg{ .None = undefined }, // TODO: Required to force non-tag but value?
38 1 => {36 1 => {
39 if (*index + 1 >= args.len) {37 if (index.* + 1 >= args.len) {
40 return error.MissingFlagArguments;38 return error.MissingFlagArguments;
41 }39 }
4240
43 *index += 1;41 index.* += 1;
44 const arg = args[*index];42 const arg = args[index.*];
4543
46 if (!argInAllowedSet(allowed_set, arg)) {44 if (!argInAllowedSet(allowed_set, arg)) {
47 return error.ArgumentNotInAllowedSet;45 return error.ArgumentNotInAllowedSet;
48 }46 }
4947
50 return FlagArg { .Single = arg };48 return FlagArg{ .Single = arg };
51 },49 },
52 else => |needed| {50 else => |needed| {
53 var extra = ArrayList([]const u8).init(allocator);51 var extra = ArrayList([]const u8).init(allocator);
...@@ -55,12 +53,12 @@ fn readFlagArguments(allocator: &Allocator, args: []const []const u8, required:...@@ -55,12 +53,12 @@ fn readFlagArguments(allocator: &Allocator, args: []const []const u8, required:
5553
56 var j: usize = 0;54 var j: usize = 0;
57 while (j < needed) : (j += 1) {55 while (j < needed) : (j += 1) {
58 if (*index + 1 >= args.len) {56 if (index.* + 1 >= args.len) {
59 return error.MissingFlagArguments;57 return error.MissingFlagArguments;
60 }58 }
6159
62 *index += 1;60 index.* += 1;
63 const arg = args[*index];61 const arg = args[index.*];
6462
65 if (!argInAllowedSet(allowed_set, arg)) {63 if (!argInAllowedSet(allowed_set, arg)) {
66 return error.ArgumentNotInAllowedSet;64 return error.ArgumentNotInAllowedSet;
...@@ -69,7 +67,7 @@ fn readFlagArguments(allocator: &Allocator, args: []const []const u8, required:...@@ -69,7 +67,7 @@ fn readFlagArguments(allocator: &Allocator, args: []const []const u8, required:
69 try extra.append(arg);67 try extra.append(arg);
70 }68 }
7169
72 return FlagArg { .Many = extra };70 return FlagArg{ .Many = extra };
73 },71 },
74 }72 }
75}73}
...@@ -82,7 +80,7 @@ pub const Args = struct {...@@ -82,7 +80,7 @@ pub const Args = struct {
82 positionals: ArrayList([]const u8),80 positionals: ArrayList([]const u8),
8381
84 pub fn parse(allocator: &Allocator, comptime spec: []const Flag, args: []const []const u8) !Args {82 pub fn parse(allocator: &Allocator, comptime spec: []const Flag, args: []const []const u8) !Args {
85 var parsed = Args {83 var parsed = Args{
86 .flags = HashMapFlags.init(allocator),84 .flags = HashMapFlags.init(allocator),
87 .positionals = ArrayList([]const u8).init(allocator),85 .positionals = ArrayList([]const u8).init(allocator),
88 };86 };
...@@ -116,11 +114,7 @@ pub const Args = struct {...@@ -116,11 +114,7 @@ pub const Args = struct {
116 };114 };
117115
118 if (flag.mergable) {116 if (flag.mergable) {
119 var prev =117 var prev = if (parsed.flags.get(flag_name_trimmed)) |entry| entry.value.Many else ArrayList([]const u8).init(allocator);
120 if (parsed.flags.get(flag_name_trimmed)) |entry|
121 entry.value.Many
122 else
123 ArrayList([]const u8).init(allocator);
124118
125 // MergeN creation disallows 0 length flag entry (doesn't make sense)119 // MergeN creation disallows 0 length flag entry (doesn't make sense)
126 switch (flag_args) {120 switch (flag_args) {
...@@ -129,7 +123,7 @@ pub const Args = struct {...@@ -129,7 +123,7 @@ pub const Args = struct {
129 FlagArg.Many => |inner| try prev.appendSlice(inner.toSliceConst()),123 FlagArg.Many => |inner| try prev.appendSlice(inner.toSliceConst()),
130 }124 }
131125
132 _ = try parsed.flags.put(flag_name_trimmed, FlagArg { .Many = prev });126 _ = try parsed.flags.put(flag_name_trimmed, FlagArg{ .Many = prev });
133 } else {127 } else {
134 _ = try parsed.flags.put(flag_name_trimmed, flag_args);128 _ = try parsed.flags.put(flag_name_trimmed, flag_args);
135 }129 }
...@@ -163,7 +157,9 @@ pub const Args = struct {...@@ -163,7 +157,9 @@ pub const Args = struct {
163 pub fn single(self: &Args, name: []const u8) ?[]const u8 {157 pub fn single(self: &Args, name: []const u8) ?[]const u8 {
164 if (self.flags.get(name)) |entry| {158 if (self.flags.get(name)) |entry| {
165 switch (entry.value) {159 switch (entry.value) {
166 FlagArg.Single => |inner| { return inner; },160 FlagArg.Single => |inner| {
161 return inner;
162 },
167 else => @panic("attempted to retrieve flag with wrong type"),163 else => @panic("attempted to retrieve flag with wrong type"),
168 }164 }
169 } else {165 } else {
...@@ -175,7 +171,9 @@ pub const Args = struct {...@@ -175,7 +171,9 @@ pub const Args = struct {
175 pub fn many(self: &Args, name: []const u8) ?[]const []const u8 {171 pub fn many(self: &Args, name: []const u8) ?[]const []const u8 {
176 if (self.flags.get(name)) |entry| {172 if (self.flags.get(name)) |entry| {
177 switch (entry.value) {173 switch (entry.value) {
178 FlagArg.Many => |inner| { return inner.toSliceConst(); },174 FlagArg.Many => |inner| {
175 return inner.toSliceConst();
176 },
179 else => @panic("attempted to retrieve flag with wrong type"),177 else => @panic("attempted to retrieve flag with wrong type"),
180 }178 }
181 } else {179 } else {
...@@ -207,7 +205,7 @@ pub const Flag = struct {...@@ -207,7 +205,7 @@ pub const Flag = struct {
207 }205 }
208206
209 pub fn ArgN(comptime name: []const u8, comptime n: usize) Flag {207 pub fn ArgN(comptime name: []const u8, comptime n: usize) Flag {
210 return Flag {208 return Flag{
211 .name = name,209 .name = name,
212 .required = n,210 .required = n,
213 .mergable = false,211 .mergable = false,
...@@ -220,7 +218,7 @@ pub const Flag = struct {...@@ -220,7 +218,7 @@ pub const Flag = struct {
220 @compileError("n must be greater than 0");218 @compileError("n must be greater than 0");
221 }219 }
222220
223 return Flag {221 return Flag{
224 .name = name,222 .name = name,
225 .required = n,223 .required = n,
226 .mergable = true,224 .mergable = true,
...@@ -229,7 +227,7 @@ pub const Flag = struct {...@@ -229,7 +227,7 @@ pub const Flag = struct {
229 }227 }
230228
231 pub fn Option(comptime name: []const u8, comptime set: []const []const u8) Flag {229 pub fn Option(comptime name: []const u8, comptime set: []const []const u8) Flag {
232 return Flag {230 return Flag{
233 .name = name,231 .name = name,
234 .required = 1,232 .required = 1,
235 .mergable = false,233 .mergable = false,
...@@ -239,26 +237,36 @@ pub const Flag = struct {...@@ -239,26 +237,36 @@ pub const Flag = struct {
239};237};
240238
241test "parse arguments" {239test "parse arguments" {
242 const spec1 = comptime []const Flag {240 const spec1 = comptime []const Flag{
243 Flag.Bool("--help"),241 Flag.Bool("--help"),
244 Flag.Bool("--init"),242 Flag.Bool("--init"),
245 Flag.Arg1("--build-file"),243 Flag.Arg1("--build-file"),
246 Flag.Option("--color", []const []const u8 { "on", "off", "auto" }),244 Flag.Option("--color", []const []const u8{
245 "on",
246 "off",
247 "auto",
248 }),
247 Flag.ArgN("--pkg-begin", 2),249 Flag.ArgN("--pkg-begin", 2),
248 Flag.ArgMergeN("--object", 1),250 Flag.ArgMergeN("--object", 1),
249 Flag.ArgN("--library", 1),251 Flag.ArgN("--library", 1),
250 };252 };
251253
252 const cliargs = []const []const u8 {254 const cliargs = []const []const u8{
253 "build",255 "build",
254 "--help",256 "--help",
255 "pos1",257 "pos1",
256 "--build-file", "build.zig",258 "--build-file",
257 "--object", "obj1",259 "build.zig",
258 "--object", "obj2",260 "--object",
259 "--library", "lib1",261 "obj1",
260 "--library", "lib2",262 "--object",
261 "--color", "on",263 "obj2",
264 "--library",
265 "lib1",
266 "--library",
267 "lib2",
268 "--color",
269 "on",
262 "pos2",270 "pos2",
263 };271 };
264272
src-self-hosted/introspect.zig+1-3
...@@ -48,9 +48,7 @@ pub fn resolveZigLibDir(allocator: &mem.Allocator) ![]u8 {...@@ -48,9 +48,7 @@ pub fn resolveZigLibDir(allocator: &mem.Allocator) ![]u8 {
48 \\Unable to find zig lib directory: {}.48 \\Unable to find zig lib directory: {}.
49 \\Reinstall Zig or use --zig-install-prefix.49 \\Reinstall Zig or use --zig-install-prefix.
50 \\50 \\
51 ,51 , @errorName(err));
52 @errorName(err)
53 );
5452
55 return error.ZigLibDirNotFound;53 return error.ZigLibDirNotFound;
56 };54 };
src-self-hosted/ir.zig-1
...@@ -108,5 +108,4 @@ pub const Instruction = struct {...@@ -108,5 +108,4 @@ pub const Instruction = struct {
108 ArgType,108 ArgType,
109 Export,109 Export,
110 };110 };
111
112};111};
src-self-hosted/main.zig+102-69
...@@ -37,7 +37,7 @@ const usage =...@@ -37,7 +37,7 @@ const usage =
37 \\ zen Print zen of zig and exit37 \\ zen Print zen of zig and exit
38 \\38 \\
39 \\39 \\
40 ;40;
4141
42const Command = struct {42const Command = struct {
43 name: []const u8,43 name: []const u8,
...@@ -63,22 +63,61 @@ pub fn main() !void {...@@ -63,22 +63,61 @@ pub fn main() !void {
63 os.exit(1);63 os.exit(1);
64 }64 }
6565
66 const commands = []Command {66 const commands = []Command{
67 Command { .name = "build", .exec = cmdBuild },67 Command{
68 Command { .name = "build-exe", .exec = cmdBuildExe },68 .name = "build",
69 Command { .name = "build-lib", .exec = cmdBuildLib },69 .exec = cmdBuild,
70 Command { .name = "build-obj", .exec = cmdBuildObj },70 },
71 Command { .name = "fmt", .exec = cmdFmt },71 Command{
72 Command { .name = "run", .exec = cmdRun },72 .name = "build-exe",
73 Command { .name = "targets", .exec = cmdTargets },73 .exec = cmdBuildExe,
74 Command { .name = "test", .exec = cmdTest },74 },
75 Command { .name = "translate-c", .exec = cmdTranslateC },75 Command{
76 Command { .name = "version", .exec = cmdVersion },76 .name = "build-lib",
77 Command { .name = "zen", .exec = cmdZen },77 .exec = cmdBuildLib,
78 },
79 Command{
80 .name = "build-obj",
81 .exec = cmdBuildObj,
82 },
83 Command{
84 .name = "fmt",
85 .exec = cmdFmt,
86 },
87 Command{
88 .name = "run",
89 .exec = cmdRun,
90 },
91 Command{
92 .name = "targets",
93 .exec = cmdTargets,
94 },
95 Command{
96 .name = "test",
97 .exec = cmdTest,
98 },
99 Command{
100 .name = "translate-c",
101 .exec = cmdTranslateC,
102 },
103 Command{
104 .name = "version",
105 .exec = cmdVersion,
106 },
107 Command{
108 .name = "zen",
109 .exec = cmdZen,
110 },
78111
79 // undocumented commands112 // undocumented commands
80 Command { .name = "help", .exec = cmdHelp },113 Command{
81 Command { .name = "internal", .exec = cmdInternal },114 .name = "help",
115 .exec = cmdHelp,
116 },
117 Command{
118 .name = "internal",
119 .exec = cmdInternal,
120 },
82 };121 };
83122
84 for (commands) |command| {123 for (commands) |command| {
...@@ -120,9 +159,9 @@ const usage_build =...@@ -120,9 +159,9 @@ const usage_build =
120 \\ --verbose-cimport Enable compiler debug output for C imports159 \\ --verbose-cimport Enable compiler debug output for C imports
121 \\160 \\
122 \\161 \\
123 ;162;
124163
125const args_build_spec = []Flag {164const args_build_spec = []Flag{
126 Flag.Bool("--help"),165 Flag.Bool("--help"),
127 Flag.Bool("--init"),166 Flag.Bool("--init"),
128 Flag.Arg1("--build-file"),167 Flag.Arg1("--build-file"),
...@@ -148,7 +187,7 @@ const missing_build_file =...@@ -148,7 +187,7 @@ const missing_build_file =
148 \\187 \\
149 \\See: `zig build --help` or `zig help` for more options.188 \\See: `zig build --help` or `zig help` for more options.
150 \\189 \\
151 ;190;
152191
153fn cmdBuild(allocator: &Allocator, args: []const []const u8) !void {192fn cmdBuild(allocator: &Allocator, args: []const []const u8) !void {
154 var flags = try Args.parse(allocator, args_build_spec, args);193 var flags = try Args.parse(allocator, args_build_spec, args);
...@@ -317,15 +356,23 @@ const usage_build_generic =...@@ -317,15 +356,23 @@ const usage_build_generic =
317 \\ --ver-patch [ver] Dynamic library semver patch version356 \\ --ver-patch [ver] Dynamic library semver patch version
318 \\357 \\
319 \\358 \\
320 ;359;
321360
322const args_build_generic = []Flag {361const args_build_generic = []Flag{
323 Flag.Bool("--help"),362 Flag.Bool("--help"),
324 Flag.Option("--color", []const []const u8 { "auto", "off", "on" }),363 Flag.Option("--color", []const []const u8{
364 "auto",
365 "off",
366 "on",
367 }),
325368
326 Flag.ArgMergeN("--assembly", 1),369 Flag.ArgMergeN("--assembly", 1),
327 Flag.Arg1("--cache-dir"),370 Flag.Arg1("--cache-dir"),
328 Flag.Option("--emit", []const []const u8 { "asm", "bin", "llvm-ir" }),371 Flag.Option("--emit", []const []const u8{
372 "asm",
373 "bin",
374 "llvm-ir",
375 }),
329 Flag.Bool("--enable-timing-info"),376 Flag.Bool("--enable-timing-info"),
330 Flag.Arg1("--libc-include-dir"),377 Flag.Arg1("--libc-include-dir"),
331 Flag.Arg1("--name"),378 Flag.Arg1("--name"),
...@@ -471,7 +518,7 @@ fn buildOutputType(allocator: &Allocator, args: []const []const u8, out_type: Mo...@@ -471,7 +518,7 @@ fn buildOutputType(allocator: &Allocator, args: []const []const u8, out_type: Mo
471 os.exit(1);518 os.exit(1);
472 };519 };
473520
474 const asm_a= flags.many("assembly");521 const asm_a = flags.many("assembly");
475 const obj_a = flags.many("object");522 const obj_a = flags.many("object");
476 if (in_file == null and (obj_a == null or (??obj_a).len == 0) and (asm_a == null or (??asm_a).len == 0)) {523 if (in_file == null and (obj_a == null or (??obj_a).len == 0) and (asm_a == null or (??asm_a).len == 0)) {
477 try stderr.write("Expected source file argument or at least one --object or --assembly argument\n");524 try stderr.write("Expected source file argument or at least one --object or --assembly argument\n");
...@@ -493,17 +540,16 @@ fn buildOutputType(allocator: &Allocator, args: []const []const u8, out_type: Mo...@@ -493,17 +540,16 @@ fn buildOutputType(allocator: &Allocator, args: []const []const u8, out_type: Mo
493 const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch os.exit(1);540 const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch os.exit(1);
494 defer allocator.free(zig_lib_dir);541 defer allocator.free(zig_lib_dir);
495542
496 var module =543 var module = try Module.create(
497 try Module.create(544 allocator,
498 allocator,545 root_name,
499 root_name,546 zig_root_source_file,
500 zig_root_source_file,547 Target.Native,
501 Target.Native,548 out_type,
502 out_type,549 build_mode,
503 build_mode,550 zig_lib_dir,
504 zig_lib_dir,551 full_cache_dir,
505 full_cache_dir552 );
506 );
507 defer module.destroy();553 defer module.destroy();
508554
509 module.version_major = try std.fmt.parseUnsigned(u32, flags.single("ver-major") ?? "0", 10);555 module.version_major = try std.fmt.parseUnsigned(u32, flags.single("ver-major") ?? "0", 10);
...@@ -588,10 +634,10 @@ fn buildOutputType(allocator: &Allocator, args: []const []const u8, out_type: Mo...@@ -588,10 +634,10 @@ fn buildOutputType(allocator: &Allocator, args: []const []const u8, out_type: Mo
588 }634 }
589635
590 if (flags.single("mmacosx-version-min")) |ver| {636 if (flags.single("mmacosx-version-min")) |ver| {
591 module.darwin_version_min = Module.DarwinVersionMin { .MacOS = ver };637 module.darwin_version_min = Module.DarwinVersionMin{ .MacOS = ver };
592 }638 }
593 if (flags.single("mios-version-min")) |ver| {639 if (flags.single("mios-version-min")) |ver| {
594 module.darwin_version_min = Module.DarwinVersionMin { .Ios = ver };640 module.darwin_version_min = Module.DarwinVersionMin{ .Ios = ver };
595 }641 }
596642
597 module.emit_file_type = emit_type;643 module.emit_file_type = emit_type;
...@@ -637,15 +683,11 @@ const usage_fmt =...@@ -637,15 +683,11 @@ const usage_fmt =
637 \\683 \\
638 \\Options:684 \\Options:
639 \\ --help Print this help and exit685 \\ --help Print this help and exit
640 \\ --keep-backups Retain backup entries for every file
641 \\686 \\
642 \\687 \\
643 ;688;
644689
645const args_fmt_spec = []Flag {690const args_fmt_spec = []Flag{Flag.Bool("--help")};
646 Flag.Bool("--help"),
647 Flag.Bool("--keep-backups"),
648};
649691
650fn cmdFmt(allocator: &Allocator, args: []const []const u8) !void {692fn cmdFmt(allocator: &Allocator, args: []const []const u8) !void {
651 var flags = try Args.parse(allocator, args_fmt_spec, args);693 var flags = try Args.parse(allocator, args_fmt_spec, args);
...@@ -677,7 +719,6 @@ fn cmdFmt(allocator: &Allocator, args: []const []const u8) !void {...@@ -677,7 +719,6 @@ fn cmdFmt(allocator: &Allocator, args: []const []const u8) !void {
677 };719 };
678 defer tree.deinit();720 defer tree.deinit();
679721
680
681 var error_it = tree.errors.iterator(0);722 var error_it = tree.errors.iterator(0);
682 while (error_it.next()) |parse_error| {723 while (error_it.next()) |parse_error| {
683 const token = tree.tokens.at(parse_error.loc());724 const token = tree.tokens.at(parse_error.loc());
...@@ -723,8 +764,7 @@ fn cmdTargets(allocator: &Allocator, args: []const []const u8) !void {...@@ -723,8 +764,7 @@ fn cmdTargets(allocator: &Allocator, args: []const []const u8) !void {
723 inline while (i < @memberCount(builtin.Arch)) : (i += 1) {764 inline while (i < @memberCount(builtin.Arch)) : (i += 1) {
724 comptime const arch_tag = @memberName(builtin.Arch, i);765 comptime const arch_tag = @memberName(builtin.Arch, i);
725 // NOTE: Cannot use empty string, see #918.766 // NOTE: Cannot use empty string, see #918.
726 comptime const native_str =767 comptime const native_str = if (comptime mem.eql(u8, arch_tag, @tagName(builtin.arch))) " (native)\n" else "\n";
727 if (comptime mem.eql(u8, arch_tag, @tagName(builtin.arch))) " (native)\n" else "\n";
728768
729 try stdout.print(" {}{}", arch_tag, native_str);769 try stdout.print(" {}{}", arch_tag, native_str);
730 }770 }
...@@ -737,8 +777,7 @@ fn cmdTargets(allocator: &Allocator, args: []const []const u8) !void {...@@ -737,8 +777,7 @@ fn cmdTargets(allocator: &Allocator, args: []const []const u8) !void {
737 inline while (i < @memberCount(builtin.Os)) : (i += 1) {777 inline while (i < @memberCount(builtin.Os)) : (i += 1) {
738 comptime const os_tag = @memberName(builtin.Os, i);778 comptime const os_tag = @memberName(builtin.Os, i);
739 // NOTE: Cannot use empty string, see #918.779 // NOTE: Cannot use empty string, see #918.
740 comptime const native_str =780 comptime const native_str = if (comptime mem.eql(u8, os_tag, @tagName(builtin.os))) " (native)\n" else "\n";
741 if (comptime mem.eql(u8, os_tag, @tagName(builtin.os))) " (native)\n" else "\n";
742781
743 try stdout.print(" {}{}", os_tag, native_str);782 try stdout.print(" {}{}", os_tag, native_str);
744 }783 }
...@@ -751,8 +790,7 @@ fn cmdTargets(allocator: &Allocator, args: []const []const u8) !void {...@@ -751,8 +790,7 @@ fn cmdTargets(allocator: &Allocator, args: []const []const u8) !void {
751 inline while (i < @memberCount(builtin.Environ)) : (i += 1) {790 inline while (i < @memberCount(builtin.Environ)) : (i += 1) {
752 comptime const environ_tag = @memberName(builtin.Environ, i);791 comptime const environ_tag = @memberName(builtin.Environ, i);
753 // NOTE: Cannot use empty string, see #918.792 // NOTE: Cannot use empty string, see #918.
754 comptime const native_str =793 comptime const native_str = if (comptime mem.eql(u8, environ_tag, @tagName(builtin.environ))) " (native)\n" else "\n";
755 if (comptime mem.eql(u8, environ_tag, @tagName(builtin.environ))) " (native)\n" else "\n";
756794
757 try stdout.print(" {}{}", environ_tag, native_str);795 try stdout.print(" {}{}", environ_tag, native_str);
758 }796 }
...@@ -774,12 +812,9 @@ const usage_test =...@@ -774,12 +812,9 @@ const usage_test =
774 \\ --help Print this help and exit812 \\ --help Print this help and exit
775 \\813 \\
776 \\814 \\
777 ;815;
778
779const args_test_spec = []Flag {
780 Flag.Bool("--help"),
781};
782816
817const args_test_spec = []Flag{Flag.Bool("--help")};
783818
784fn cmdTest(allocator: &Allocator, args: []const []const u8) !void {819fn cmdTest(allocator: &Allocator, args: []const []const u8) !void {
785 var flags = try Args.parse(allocator, args_build_spec, args);820 var flags = try Args.parse(allocator, args_build_spec, args);
...@@ -812,21 +847,18 @@ const usage_run =...@@ -812,21 +847,18 @@ const usage_run =
812 \\ --help Print this help and exit847 \\ --help Print this help and exit
813 \\848 \\
814 \\849 \\
815 ;850;
816
817const args_run_spec = []Flag {
818 Flag.Bool("--help"),
819};
820851
852const args_run_spec = []Flag{Flag.Bool("--help")};
821853
822fn cmdRun(allocator: &Allocator, args: []const []const u8) !void {854fn cmdRun(allocator: &Allocator, args: []const []const u8) !void {
823 var compile_args = args;855 var compile_args = args;
824 var runtime_args: []const []const u8 = []const []const u8 {};856 var runtime_args: []const []const u8 = []const []const u8{};
825857
826 for (args) |argv, i| {858 for (args) |argv, i| {
827 if (mem.eql(u8, argv, "--")) {859 if (mem.eql(u8, argv, "--")) {
828 compile_args = args[0..i];860 compile_args = args[0..i];
829 runtime_args = args[i+1..];861 runtime_args = args[i + 1..];
830 break;862 break;
831 }863 }
832 }864 }
...@@ -860,9 +892,9 @@ const usage_translate_c =...@@ -860,9 +892,9 @@ const usage_translate_c =
860 \\ --output [path] Output file to write generated zig file (default: stdout)892 \\ --output [path] Output file to write generated zig file (default: stdout)
861 \\893 \\
862 \\894 \\
863 ;895;
864896
865const args_translate_c_spec = []Flag {897const args_translate_c_spec = []Flag{
866 Flag.Bool("--help"),898 Flag.Bool("--help"),
867 Flag.Bool("--enable-timing-info"),899 Flag.Bool("--enable-timing-info"),
868 Flag.Arg1("--libc-include-dir"),900 Flag.Arg1("--libc-include-dir"),
...@@ -936,7 +968,7 @@ const info_zen =...@@ -936,7 +968,7 @@ const info_zen =
936 \\ * Together we serve end users.968 \\ * Together we serve end users.
937 \\969 \\
938 \\970 \\
939 ;971;
940972
941fn cmdZen(allocator: &Allocator, args: []const []const u8) !void {973fn cmdZen(allocator: &Allocator, args: []const []const u8) !void {
942 try stdout.write(info_zen);974 try stdout.write(info_zen);
...@@ -951,7 +983,7 @@ const usage_internal =...@@ -951,7 +983,7 @@ const usage_internal =
951 \\ build-info Print static compiler build-info983 \\ build-info Print static compiler build-info
952 \\984 \\
953 \\985 \\
954 ;986;
955987
956fn cmdInternal(allocator: &Allocator, args: []const []const u8) !void {988fn cmdInternal(allocator: &Allocator, args: []const []const u8) !void {
957 if (args.len == 0) {989 if (args.len == 0) {
...@@ -959,9 +991,10 @@ fn cmdInternal(allocator: &Allocator, args: []const []const u8) !void {...@@ -959,9 +991,10 @@ fn cmdInternal(allocator: &Allocator, args: []const []const u8) !void {
959 os.exit(1);991 os.exit(1);
960 }992 }
961993
962 const sub_commands = []Command {994 const sub_commands = []Command{Command{
963 Command { .name = "build-info", .exec = cmdInternalBuildInfo },995 .name = "build-info",
964 };996 .exec = cmdInternalBuildInfo,
997 }};
965998
966 for (sub_commands) |sub_command| {999 for (sub_commands) |sub_command| {
967 if (mem.eql(u8, sub_command.name, args[0])) {1000 if (mem.eql(u8, sub_command.name, args[0])) {
...@@ -985,7 +1018,7 @@ fn cmdInternalBuildInfo(allocator: &Allocator, args: []const []const u8) !void {...@@ -985,7 +1018,7 @@ fn cmdInternalBuildInfo(allocator: &Allocator, args: []const []const u8) !void {
985 \\ZIG_C_HEADER_FILES {}1018 \\ZIG_C_HEADER_FILES {}
986 \\ZIG_DIA_GUIDS_LIB {}1019 \\ZIG_DIA_GUIDS_LIB {}
987 \\1020 \\
988 ,1021 ,
989 std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR),1022 std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR),
990 std.cstr.toSliceConst(c.ZIG_CXX_COMPILER),1023 std.cstr.toSliceConst(c.ZIG_CXX_COMPILER),
991 std.cstr.toSliceConst(c.ZIG_LLVM_CONFIG_EXE),1024 std.cstr.toSliceConst(c.ZIG_LLVM_CONFIG_EXE),
src-self-hosted/module.zig+9-9
...@@ -96,6 +96,7 @@ pub const Module = struct {...@@ -96,6 +96,7 @@ pub const Module = struct {
96 pub const LinkLib = struct {96 pub const LinkLib = struct {
97 name: []const u8,97 name: []const u8,
98 path: ?[]const u8,98 path: ?[]const u8,
99
99 /// the list of symbols we depend on from this lib100 /// the list of symbols we depend on from this lib
100 symbols: ArrayList([]u8),101 symbols: ArrayList([]u8),
101 provided_explicitly: bool,102 provided_explicitly: bool,
...@@ -130,9 +131,7 @@ pub const Module = struct {...@@ -130,9 +131,7 @@ pub const Module = struct {
130 }131 }
131 };132 };
132133
133 pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target,134 pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target, kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) !&Module {
134 kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) !&Module
135 {
136 var name_buffer = try Buffer.init(allocator, name);135 var name_buffer = try Buffer.init(allocator, name);
137 errdefer name_buffer.deinit();136 errdefer name_buffer.deinit();
138137
...@@ -148,14 +147,14 @@ pub const Module = struct {...@@ -148,14 +147,14 @@ pub const Module = struct {
148 const module_ptr = try allocator.create(Module);147 const module_ptr = try allocator.create(Module);
149 errdefer allocator.destroy(module_ptr);148 errdefer allocator.destroy(module_ptr);
150149
151 *module_ptr = Module {150 module_ptr.* = Module{
152 .allocator = allocator,151 .allocator = allocator,
153 .name = name_buffer,152 .name = name_buffer,
154 .root_src_path = root_src_path,153 .root_src_path = root_src_path,
155 .module = module,154 .module = module,
156 .context = context,155 .context = context,
157 .builder = builder,156 .builder = builder,
158 .target = *target,157 .target = target.*,
159 .kind = kind,158 .kind = kind,
160 .build_mode = build_mode,159 .build_mode = build_mode,
161 .zig_lib_dir = zig_lib_dir,160 .zig_lib_dir = zig_lib_dir,
...@@ -221,8 +220,10 @@ pub const Module = struct {...@@ -221,8 +220,10 @@ pub const Module = struct {
221220
222 pub fn build(self: &Module) !void {221 pub fn build(self: &Module) !void {
223 if (self.llvm_argv.len != 0) {222 if (self.llvm_argv.len != 0) {
224 var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator,223 var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator, [][]const []const u8{
225 [][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });224 [][]const u8{"zig (LLVM option parsing)"},
225 self.llvm_argv,
226 });
226 defer c_compatible_args.deinit();227 defer c_compatible_args.deinit();
227 c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr);228 c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr);
228 }229 }
...@@ -261,7 +262,6 @@ pub const Module = struct {...@@ -261,7 +262,6 @@ pub const Module = struct {
261262
262 warn("====llvm ir:====\n");263 warn("====llvm ir:====\n");
263 self.dump();264 self.dump();
264
265 }265 }
266266
267 pub fn link(self: &Module, out_file: ?[]const u8) !void {267 pub fn link(self: &Module, out_file: ?[]const u8) !void {
...@@ -285,7 +285,7 @@ pub const Module = struct {...@@ -285,7 +285,7 @@ pub const Module = struct {
285 }285 }
286286
287 const link_lib = try self.allocator.create(LinkLib);287 const link_lib = try self.allocator.create(LinkLib);
288 *link_lib = LinkLib {288 link_lib.* = LinkLib{
289 .name = name,289 .name = name,
290 .path = null,290 .path = null,
291 .provided_explicitly = provided_explicitly,291 .provided_explicitly = provided_explicitly,
src-self-hosted/target.zig+2-2
...@@ -12,7 +12,7 @@ pub const Target = union(enum) {...@@ -12,7 +12,7 @@ pub const Target = union(enum) {
12 Cross: CrossTarget,12 Cross: CrossTarget,
1313
14 pub fn oFileExt(self: &const Target) []const u8 {14 pub fn oFileExt(self: &const Target) []const u8 {
15 const environ = switch (*self) {15 const environ = switch (self.*) {
16 Target.Native => builtin.environ,16 Target.Native => builtin.environ,
17 Target.Cross => |t| t.environ,17 Target.Cross => |t| t.environ,
18 };18 };
...@@ -30,7 +30,7 @@ pub const Target = union(enum) {...@@ -30,7 +30,7 @@ pub const Target = union(enum) {
30 }30 }
3131
32 pub fn getOs(self: &const Target) builtin.Os {32 pub fn getOs(self: &const Target) builtin.Os {
33 return switch (*self) {33 return switch (self.*) {
34 Target.Native => builtin.os,34 Target.Native => builtin.os,
35 Target.Cross => |t| t.os,35 Target.Cross => |t| t.os,
36 };36 };
src/all_types.hpp+13-1
...@@ -379,6 +379,7 @@ enum NodeType {...@@ -379,6 +379,7 @@ enum NodeType {
379 NodeTypeArrayAccessExpr,379 NodeTypeArrayAccessExpr,
380 NodeTypeSliceExpr,380 NodeTypeSliceExpr,
381 NodeTypeFieldAccessExpr,381 NodeTypeFieldAccessExpr,
382 NodeTypePtrDeref,
382 NodeTypeUse,383 NodeTypeUse,
383 NodeTypeBoolLiteral,384 NodeTypeBoolLiteral,
384 NodeTypeNullLiteral,385 NodeTypeNullLiteral,
...@@ -603,13 +604,16 @@ struct AstNodeFieldAccessExpr {...@@ -603,13 +604,16 @@ struct AstNodeFieldAccessExpr {
603 Buf *field_name;604 Buf *field_name;
604};605};
605606
607struct AstNodePtrDerefExpr {
608 AstNode *target;
609};
610
606enum PrefixOp {611enum PrefixOp {
607 PrefixOpInvalid,612 PrefixOpInvalid,
608 PrefixOpBoolNot,613 PrefixOpBoolNot,
609 PrefixOpBinNot,614 PrefixOpBinNot,
610 PrefixOpNegation,615 PrefixOpNegation,
611 PrefixOpNegationWrap,616 PrefixOpNegationWrap,
612 PrefixOpDereference,
613 PrefixOpMaybe,617 PrefixOpMaybe,
614 PrefixOpUnwrapMaybe,618 PrefixOpUnwrapMaybe,
615};619};
...@@ -911,6 +915,7 @@ struct AstNode {...@@ -911,6 +915,7 @@ struct AstNode {
911 AstNodeCompTime comptime_expr;915 AstNodeCompTime comptime_expr;
912 AstNodeAsmExpr asm_expr;916 AstNodeAsmExpr asm_expr;
913 AstNodeFieldAccessExpr field_access_expr;917 AstNodeFieldAccessExpr field_access_expr;
918 AstNodePtrDerefExpr ptr_deref_expr;
914 AstNodeContainerDecl container_decl;919 AstNodeContainerDecl container_decl;
915 AstNodeStructField struct_field;920 AstNodeStructField struct_field;
916 AstNodeStringLiteral string_literal;921 AstNodeStringLiteral string_literal;
...@@ -1340,6 +1345,7 @@ enum BuiltinFnId {...@@ -1340,6 +1345,7 @@ enum BuiltinFnId {
1340 BuiltinFnIdOffsetOf,1345 BuiltinFnIdOffsetOf,
1341 BuiltinFnIdInlineCall,1346 BuiltinFnIdInlineCall,
1342 BuiltinFnIdNoInlineCall,1347 BuiltinFnIdNoInlineCall,
1348 BuiltinFnIdNewStackCall,
1343 BuiltinFnIdTypeId,1349 BuiltinFnIdTypeId,
1344 BuiltinFnIdShlExact,1350 BuiltinFnIdShlExact,
1345 BuiltinFnIdShrExact,1351 BuiltinFnIdShrExact,
...@@ -1656,8 +1662,13 @@ struct CodeGen {...@@ -1656,8 +1662,13 @@ struct CodeGen {
1656 LLVMValueRef coro_alloc_helper_fn_val;1662 LLVMValueRef coro_alloc_helper_fn_val;
1657 LLVMValueRef merge_err_ret_traces_fn_val;1663 LLVMValueRef merge_err_ret_traces_fn_val;
1658 LLVMValueRef add_error_return_trace_addr_fn_val;1664 LLVMValueRef add_error_return_trace_addr_fn_val;
1665 LLVMValueRef stacksave_fn_val;
1666 LLVMValueRef stackrestore_fn_val;
1667 LLVMValueRef write_register_fn_val;
1659 bool error_during_imports;1668 bool error_during_imports;
16601669
1670 LLVMValueRef sp_md_node;
1671
1661 const char **clang_argv;1672 const char **clang_argv;
1662 size_t clang_argv_len;1673 size_t clang_argv_len;
1663 ZigList<const char *> lib_dirs;1674 ZigList<const char *> lib_dirs;
...@@ -2280,6 +2291,7 @@ struct IrInstructionCall {...@@ -2280,6 +2291,7 @@ struct IrInstructionCall {
2280 bool is_async;2291 bool is_async;
22812292
2282 IrInstruction *async_allocator;2293 IrInstruction *async_allocator;
2294 IrInstruction *new_stack;
2283};2295};
22842296
2285struct IrInstructionConst {2297struct IrInstructionConst {
src/analyze.cpp+7-5
...@@ -25,6 +25,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type);...@@ -25,6 +25,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type);
25static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type);25static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type);
26static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type);26static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type);
27static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type);27static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type);
28static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry);
2829
29ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {30ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
30 if (node->owner->c_import_node != nullptr) {31 if (node->owner->c_import_node != nullptr) {
...@@ -1007,7 +1008,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1007,7 +1008,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1007 if (fn_type_id->return_type != nullptr) {1008 if (fn_type_id->return_type != nullptr) {
1008 ensure_complete_type(g, fn_type_id->return_type);1009 ensure_complete_type(g, fn_type_id->return_type);
1009 } else {1010 } else {
1010 zig_panic("TODO implement inferred return types https://github.com/zig-lang/zig/issues/447");1011 zig_panic("TODO implement inferred return types https://github.com/ziglang/zig/issues/447");
1011 }1012 }
10121013
1013 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);1014 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);
...@@ -1556,7 +1557,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1556,7 +1557,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1556 return g->builtin_types.entry_invalid;1557 return g->builtin_types.entry_invalid;
1557 }1558 }
1558 add_node_error(g, proto_node,1559 add_node_error(g, proto_node,
1559 buf_sprintf("TODO implement inferred return types https://github.com/zig-lang/zig/issues/447"));1560 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447"));
1560 return g->builtin_types.entry_invalid;1561 return g->builtin_types.entry_invalid;
1561 //return get_generic_fn_type(g, &fn_type_id);1562 //return get_generic_fn_type(g, &fn_type_id);
1562 }1563 }
...@@ -3281,6 +3282,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -3281,6 +3282,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
3281 case NodeTypeUnreachable:3282 case NodeTypeUnreachable:
3282 case NodeTypeAsmExpr:3283 case NodeTypeAsmExpr:
3283 case NodeTypeFieldAccessExpr:3284 case NodeTypeFieldAccessExpr:
3285 case NodeTypePtrDeref:
3284 case NodeTypeStructField:3286 case NodeTypeStructField:
3285 case NodeTypeContainerInitExpr:3287 case NodeTypeContainerInitExpr:
3286 case NodeTypeStructValueField:3288 case NodeTypeStructValueField:
...@@ -3879,7 +3881,7 @@ static void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entr...@@ -3879,7 +3881,7 @@ static void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entr
3879 }3881 }
3880}3882}
38813883
3882static bool analyze_resolve_inferred_error_set(CodeGen *g, TypeTableEntry *err_set_type, AstNode *source_node) {3884bool resolve_inferred_error_set(CodeGen *g, TypeTableEntry *err_set_type, AstNode *source_node) {
3883 FnTableEntry *infer_fn = err_set_type->data.error_set.infer_fn;3885 FnTableEntry *infer_fn = err_set_type->data.error_set.infer_fn;
3884 if (infer_fn != nullptr) {3886 if (infer_fn != nullptr) {
3885 if (infer_fn->anal_state == FnAnalStateInvalid) {3887 if (infer_fn->anal_state == FnAnalStateInvalid) {
...@@ -3931,7 +3933,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ...@@ -3931,7 +3933,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
3931 }3933 }
39323934
3933 if (inferred_err_set_type->data.error_set.infer_fn != nullptr) {3935 if (inferred_err_set_type->data.error_set.infer_fn != nullptr) {
3934 if (!analyze_resolve_inferred_error_set(g, inferred_err_set_type, return_type_node)) {3936 if (!resolve_inferred_error_set(g, inferred_err_set_type, return_type_node)) {
3935 fn_table_entry->anal_state = FnAnalStateInvalid;3937 fn_table_entry->anal_state = FnAnalStateInvalid;
3936 return;3938 return;
3937 }3939 }
...@@ -3961,7 +3963,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ...@@ -3961,7 +3963,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
3961 fn_table_entry->anal_state = FnAnalStateComplete;3963 fn_table_entry->anal_state = FnAnalStateComplete;
3962}3964}
39633965
3964void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {3966static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
3965 assert(fn_table_entry->anal_state != FnAnalStateProbing);3967 assert(fn_table_entry->anal_state != FnAnalStateProbing);
3966 if (fn_table_entry->anal_state != FnAnalStateReady)3968 if (fn_table_entry->anal_state != FnAnalStateReady)
3967 return;3969 return;
src/analyze.hpp+1-1
...@@ -191,7 +191,7 @@ void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, G...@@ -191,7 +191,7 @@ void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, G
191191
192ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);192ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);
193TypeTableEntry *get_ptr_to_stack_trace_type(CodeGen *g);193TypeTableEntry *get_ptr_to_stack_trace_type(CodeGen *g);
194void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry);194bool resolve_inferred_error_set(CodeGen *g, TypeTableEntry *err_set_type, AstNode *source_node);
195195
196TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry);196TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry);
197197
src/ast_render.cpp+9-1
...@@ -66,7 +66,6 @@ static const char *prefix_op_str(PrefixOp prefix_op) {...@@ -66,7 +66,6 @@ static const char *prefix_op_str(PrefixOp prefix_op) {
66 case PrefixOpNegationWrap: return "-%";66 case PrefixOpNegationWrap: return "-%";
67 case PrefixOpBoolNot: return "!";67 case PrefixOpBoolNot: return "!";
68 case PrefixOpBinNot: return "~";68 case PrefixOpBinNot: return "~";
69 case PrefixOpDereference: return "*";
70 case PrefixOpMaybe: return "?";69 case PrefixOpMaybe: return "?";
71 case PrefixOpUnwrapMaybe: return "??";70 case PrefixOpUnwrapMaybe: return "??";
72 }71 }
...@@ -222,6 +221,8 @@ static const char *node_type_str(NodeType node_type) {...@@ -222,6 +221,8 @@ static const char *node_type_str(NodeType node_type) {
222 return "AsmExpr";221 return "AsmExpr";
223 case NodeTypeFieldAccessExpr:222 case NodeTypeFieldAccessExpr:
224 return "FieldAccessExpr";223 return "FieldAccessExpr";
224 case NodeTypePtrDeref:
225 return "PtrDerefExpr";
225 case NodeTypeContainerDecl:226 case NodeTypeContainerDecl:
226 return "ContainerDecl";227 return "ContainerDecl";
227 case NodeTypeStructField:228 case NodeTypeStructField:
...@@ -696,6 +697,13 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -696,6 +697,13 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
696 print_symbol(ar, rhs);697 print_symbol(ar, rhs);
697 break;698 break;
698 }699 }
700 case NodeTypePtrDeref:
701 {
702 AstNode *lhs = node->data.ptr_deref_expr.target;
703 render_node_ungrouped(ar, lhs);
704 fprintf(ar->f, ".*");
705 break;
706 }
699 case NodeTypeUndefinedLiteral:707 case NodeTypeUndefinedLiteral:
700 fprintf(ar->f, "undefined");708 fprintf(ar->f, "undefined");
701 break;709 break;
src/codegen.cpp+100-5
...@@ -582,7 +582,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -582,7 +582,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
582 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull");582 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull");
583 }583 }
584 // Note: byval is disabled on windows due to an LLVM bug:584 // Note: byval is disabled on windows due to an LLVM bug:
585 // https://github.com/zig-lang/zig/issues/536585 // https://github.com/ziglang/zig/issues/536
586 if (is_byval && g->zig_target.os != OsWindows) {586 if (is_byval && g->zig_target.os != OsWindows) {
587 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval");587 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval");
588 }588 }
...@@ -938,6 +938,53 @@ static LLVMValueRef get_memcpy_fn_val(CodeGen *g) {...@@ -938,6 +938,53 @@ static LLVMValueRef get_memcpy_fn_val(CodeGen *g) {
938 return g->memcpy_fn_val;938 return g->memcpy_fn_val;
939}939}
940940
941static LLVMValueRef get_stacksave_fn_val(CodeGen *g) {
942 if (g->stacksave_fn_val)
943 return g->stacksave_fn_val;
944
945 // declare i8* @llvm.stacksave()
946
947 LLVMTypeRef fn_type = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), nullptr, 0, false);
948 g->stacksave_fn_val = LLVMAddFunction(g->module, "llvm.stacksave", fn_type);
949 assert(LLVMGetIntrinsicID(g->stacksave_fn_val));
950
951 return g->stacksave_fn_val;
952}
953
954static LLVMValueRef get_stackrestore_fn_val(CodeGen *g) {
955 if (g->stackrestore_fn_val)
956 return g->stackrestore_fn_val;
957
958 // declare void @llvm.stackrestore(i8* %ptr)
959
960 LLVMTypeRef param_type = LLVMPointerType(LLVMInt8Type(), 0);
961 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), &param_type, 1, false);
962 g->stackrestore_fn_val = LLVMAddFunction(g->module, "llvm.stackrestore", fn_type);
963 assert(LLVMGetIntrinsicID(g->stackrestore_fn_val));
964
965 return g->stackrestore_fn_val;
966}
967
968static LLVMValueRef get_write_register_fn_val(CodeGen *g) {
969 if (g->write_register_fn_val)
970 return g->write_register_fn_val;
971
972 // declare void @llvm.write_register.i64(metadata, i64 @value)
973 // !0 = !{!"sp\00"}
974
975 LLVMTypeRef param_types[] = {
976 LLVMMetadataTypeInContext(LLVMGetGlobalContext()),
977 LLVMIntType(g->pointer_size_bytes * 8),
978 };
979
980 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 2, false);
981 Buf *name = buf_sprintf("llvm.write_register.i%d", g->pointer_size_bytes * 8);
982 g->write_register_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
983 assert(LLVMGetIntrinsicID(g->write_register_fn_val));
984
985 return g->write_register_fn_val;
986}
987
941static LLVMValueRef get_coro_destroy_fn_val(CodeGen *g) {988static LLVMValueRef get_coro_destroy_fn_val(CodeGen *g) {
942 if (g->coro_destroy_fn_val)989 if (g->coro_destroy_fn_val)
943 return g->coro_destroy_fn_val;990 return g->coro_destroy_fn_val;
...@@ -2901,6 +2948,38 @@ static size_t get_async_err_code_arg_index(CodeGen *g, FnTypeId *fn_type_id) {...@@ -2901,6 +2948,38 @@ static size_t get_async_err_code_arg_index(CodeGen *g, FnTypeId *fn_type_id) {
2901 return 1 + get_async_allocator_arg_index(g, fn_type_id);2948 return 1 + get_async_allocator_arg_index(g, fn_type_id);
2902}2949}
29032950
2951
2952static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) {
2953 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_ptr_index, "");
2954 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_len_index, "");
2955
2956 LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, "");
2957 LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, "");
2958
2959 LLVMValueRef ptr_addr = LLVMBuildPtrToInt(g->builder, ptr_value, LLVMTypeOf(len_value), "");
2960 LLVMValueRef end_addr = LLVMBuildNUWAdd(g->builder, ptr_addr, len_value, "");
2961 LLVMValueRef align_amt = LLVMConstInt(LLVMTypeOf(end_addr), get_abi_alignment(g, g->builtin_types.entry_usize), false);
2962 LLVMValueRef align_adj = LLVMBuildURem(g->builder, end_addr, align_amt, "");
2963 return LLVMBuildNUWSub(g->builder, end_addr, align_adj, "");
2964}
2965
2966static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) {
2967 LLVMValueRef write_register_fn_val = get_write_register_fn_val(g);
2968
2969 if (g->sp_md_node == nullptr) {
2970 Buf *sp_reg_name = buf_create_from_str(arch_stack_pointer_register_name(&g->zig_target.arch));
2971 LLVMValueRef str_node = LLVMMDString(buf_ptr(sp_reg_name), buf_len(sp_reg_name) + 1);
2972 g->sp_md_node = LLVMMDNode(&str_node, 1);
2973 }
2974
2975 LLVMValueRef params[] = {
2976 g->sp_md_node,
2977 aligned_end_addr,
2978 };
2979
2980 LLVMBuildCall(g->builder, write_register_fn_val, params, 2, "");
2981}
2982
2904static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {2983static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
2905 LLVMValueRef fn_val;2984 LLVMValueRef fn_val;
2906 TypeTableEntry *fn_type;2985 TypeTableEntry *fn_type;
...@@ -2967,13 +3046,28 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -2967,13 +3046,28 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
2967 }3046 }
29683047
2969 LLVMCallConv llvm_cc = get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc);3048 LLVMCallConv llvm_cc = get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc);
2970 LLVMValueRef result = ZigLLVMBuildCall(g->builder, fn_val,3049 LLVMValueRef result;
2971 gen_param_values, (unsigned)gen_param_index, llvm_cc, fn_inline, "");3050
3051 if (instruction->new_stack == nullptr) {
3052 result = ZigLLVMBuildCall(g->builder, fn_val,
3053 gen_param_values, (unsigned)gen_param_index, llvm_cc, fn_inline, "");
3054 } else {
3055 LLVMValueRef stacksave_fn_val = get_stacksave_fn_val(g);
3056 LLVMValueRef stackrestore_fn_val = get_stackrestore_fn_val(g);
3057
3058 LLVMValueRef new_stack_addr = get_new_stack_addr(g, ir_llvm_value(g, instruction->new_stack));
3059 LLVMValueRef old_stack_ref = LLVMBuildCall(g->builder, stacksave_fn_val, nullptr, 0, "");
3060 gen_set_stack_pointer(g, new_stack_addr);
3061 result = ZigLLVMBuildCall(g->builder, fn_val,
3062 gen_param_values, (unsigned)gen_param_index, llvm_cc, fn_inline, "");
3063 LLVMBuildCall(g->builder, stackrestore_fn_val, &old_stack_ref, 1, "");
3064 }
3065
29723066
2973 for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) {3067 for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) {
2974 FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i];3068 FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i];
2975 // Note: byval is disabled on windows due to an LLVM bug:3069 // Note: byval is disabled on windows due to an LLVM bug:
2976 // https://github.com/zig-lang/zig/issues/5363070 // https://github.com/ziglang/zig/issues/536
2977 if (gen_info->is_byval && g->zig_target.os != OsWindows) {3071 if (gen_info->is_byval && g->zig_target.os != OsWindows) {
2978 addLLVMCallsiteAttr(result, (unsigned)gen_info->gen_index, "byval");3072 addLLVMCallsiteAttr(result, (unsigned)gen_info->gen_index, "byval");
2979 }3073 }
...@@ -6171,6 +6265,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -6171,6 +6265,7 @@ static void define_builtin_fns(CodeGen *g) {
6171 create_builtin_fn(g, BuiltinFnIdSqrt, "sqrt", 2);6265 create_builtin_fn(g, BuiltinFnIdSqrt, "sqrt", 2);
6172 create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX);6266 create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX);
6173 create_builtin_fn(g, BuiltinFnIdNoInlineCall, "noInlineCall", SIZE_MAX);6267 create_builtin_fn(g, BuiltinFnIdNoInlineCall, "noInlineCall", SIZE_MAX);
6268 create_builtin_fn(g, BuiltinFnIdNewStackCall, "newStackCall", SIZE_MAX);
6174 create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1);6269 create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1);
6175 create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2);6270 create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2);
6176 create_builtin_fn(g, BuiltinFnIdShrExact, "shrExact", 2);6271 create_builtin_fn(g, BuiltinFnIdShrExact, "shrExact", 2);
...@@ -6635,7 +6730,7 @@ static void init(CodeGen *g) {...@@ -6635,7 +6730,7 @@ static void init(CodeGen *g) {
6635 const char *target_specific_features;6730 const char *target_specific_features;
6636 if (g->is_native_target) {6731 if (g->is_native_target) {
6637 // LLVM creates invalid binaries on Windows sometimes.6732 // LLVM creates invalid binaries on Windows sometimes.
6638 // See https://github.com/zig-lang/zig/issues/5086733 // See https://github.com/ziglang/zig/issues/508
6639 // As a workaround we do not use target native features on Windows.6734 // As a workaround we do not use target native features on Windows.
6640 if (g->zig_target.os == OsWindows) {6735 if (g->zig_target.os == OsWindows) {
6641 target_specific_cpu_args = "";6736 target_specific_cpu_args = "";
src/ir.cpp+112-65
...@@ -1102,7 +1102,8 @@ static IrInstruction *ir_build_union_field_ptr_from(IrBuilder *irb, IrInstructio...@@ -1102,7 +1102,8 @@ static IrInstruction *ir_build_union_field_ptr_from(IrBuilder *irb, IrInstructio
11021102
1103static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,1103static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,
1104 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,1104 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
1105 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator)1105 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator,
1106 IrInstruction *new_stack)
1106{1107{
1107 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);1108 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);
1108 call_instruction->fn_entry = fn_entry;1109 call_instruction->fn_entry = fn_entry;
...@@ -1113,6 +1114,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc...@@ -1113,6 +1114,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
1113 call_instruction->arg_count = arg_count;1114 call_instruction->arg_count = arg_count;
1114 call_instruction->is_async = is_async;1115 call_instruction->is_async = is_async;
1115 call_instruction->async_allocator = async_allocator;1116 call_instruction->async_allocator = async_allocator;
1117 call_instruction->new_stack = new_stack;
11161118
1117 if (fn_ref)1119 if (fn_ref)
1118 ir_ref_instruction(fn_ref, irb->current_basic_block);1120 ir_ref_instruction(fn_ref, irb->current_basic_block);
...@@ -1120,16 +1122,19 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc...@@ -1120,16 +1122,19 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
1120 ir_ref_instruction(args[i], irb->current_basic_block);1122 ir_ref_instruction(args[i], irb->current_basic_block);
1121 if (async_allocator)1123 if (async_allocator)
1122 ir_ref_instruction(async_allocator, irb->current_basic_block);1124 ir_ref_instruction(async_allocator, irb->current_basic_block);
1125 if (new_stack != nullptr)
1126 ir_ref_instruction(new_stack, irb->current_basic_block);
11231127
1124 return &call_instruction->base;1128 return &call_instruction->base;
1125}1129}
11261130
1127static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,1131static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,
1128 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,1132 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
1129 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator)1133 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator,
1134 IrInstruction *new_stack)
1130{1135{
1131 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->scope,1136 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->scope,
1132 old_instruction->source_node, fn_entry, fn_ref, arg_count, args, is_comptime, fn_inline, is_async, async_allocator);1137 old_instruction->source_node, fn_entry, fn_ref, arg_count, args, is_comptime, fn_inline, is_async, async_allocator, new_stack);
1133 ir_link_new_instruction(new_instruction, old_instruction);1138 ir_link_new_instruction(new_instruction, old_instruction);
1134 return new_instruction;1139 return new_instruction;
1135}1140}
...@@ -4303,7 +4308,37 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4303,7 +4308,37 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4303 }4308 }
4304 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;4309 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
43054310
4306 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr);4311 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr);
4312 return ir_lval_wrap(irb, scope, call, lval);
4313 }
4314 case BuiltinFnIdNewStackCall:
4315 {
4316 if (node->data.fn_call_expr.params.length == 0) {
4317 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0"));
4318 return irb->codegen->invalid_instruction;
4319 }
4320
4321 AstNode *new_stack_node = node->data.fn_call_expr.params.at(0);
4322 IrInstruction *new_stack = ir_gen_node(irb, new_stack_node, scope);
4323 if (new_stack == irb->codegen->invalid_instruction)
4324 return new_stack;
4325
4326 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1);
4327 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
4328 if (fn_ref == irb->codegen->invalid_instruction)
4329 return fn_ref;
4330
4331 size_t arg_count = node->data.fn_call_expr.params.length - 2;
4332
4333 IrInstruction **args = allocate<IrInstruction*>(arg_count);
4334 for (size_t i = 0; i < arg_count; i += 1) {
4335 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 2);
4336 args[i] = ir_gen_node(irb, arg_node, scope);
4337 if (args[i] == irb->codegen->invalid_instruction)
4338 return args[i];
4339 }
4340
4341 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack);
4307 return ir_lval_wrap(irb, scope, call, lval);4342 return ir_lval_wrap(irb, scope, call, lval);
4308 }4343 }
4309 case BuiltinFnIdTypeId:4344 case BuiltinFnIdTypeId:
...@@ -4513,7 +4548,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node...@@ -4513,7 +4548,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
4513 }4548 }
4514 }4549 }
45154550
4516 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator);4551 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator, nullptr);
4517 return ir_lval_wrap(irb, scope, fn_call, lval);4552 return ir_lval_wrap(irb, scope, fn_call, lval);
4518}4553}
45194554
...@@ -4574,8 +4609,14 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode...@@ -4574,8 +4609,14 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
4574}4609}
45754610
4576static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {4611static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {
4577 assert(node->type == NodeTypePrefixOpExpr);4612 AstNode *expr_node;
4578 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;4613 if (node->type == NodeTypePrefixOpExpr) {
4614 expr_node = node->data.prefix_op_expr.primary_expr;
4615 } else if (node->type == NodeTypePtrDeref) {
4616 expr_node = node->data.ptr_deref_expr.target;
4617 } else {
4618 zig_unreachable();
4619 }
45794620
4580 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);4621 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
4581 if (value == irb->codegen->invalid_instruction)4622 if (value == irb->codegen->invalid_instruction)
...@@ -4716,8 +4757,6 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod...@@ -4716,8 +4757,6 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
4716 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval);4757 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval);
4717 case PrefixOpNegationWrap:4758 case PrefixOpNegationWrap:
4718 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval);4759 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval);
4719 case PrefixOpDereference:
4720 return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval);
4721 case PrefixOpMaybe:4760 case PrefixOpMaybe:
4722 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe), lval);4761 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe), lval);
4723 case PrefixOpUnwrapMaybe:4762 case PrefixOpUnwrapMaybe:
...@@ -6553,6 +6592,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -6553,6 +6592,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
65536592
6554 return ir_build_load_ptr(irb, scope, node, ptr_instruction);6593 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
6555 }6594 }
6595 case NodeTypePtrDeref:
6596 return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval);
6556 case NodeTypeThisLiteral:6597 case NodeTypeThisLiteral:
6557 return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval);6598 return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval);
6558 case NodeTypeBoolLiteral:6599 case NodeTypeBoolLiteral:
...@@ -6825,7 +6866,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6825,7 +6866,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6825 IrInstruction **args = allocate<IrInstruction *>(arg_count);6866 IrInstruction **args = allocate<IrInstruction *>(arg_count);
6826 args[0] = implicit_allocator_ptr; // self6867 args[0] = implicit_allocator_ptr; // self
6827 args[1] = mem_slice; // old_mem6868 args[1] = mem_slice; // old_mem
6828 ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr);6869 ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr);
68296870
6830 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");6871 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
6831 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);6872 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
...@@ -7592,38 +7633,16 @@ static bool slice_is_const(TypeTableEntry *type) {...@@ -7592,38 +7633,16 @@ static bool slice_is_const(TypeTableEntry *type) {
7592 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const;7633 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const;
7593}7634}
75947635
7595static bool resolve_inferred_error_set(IrAnalyze *ira, TypeTableEntry *err_set_type, AstNode *source_node) {
7596 assert(err_set_type->id == TypeTableEntryIdErrorSet);
7597 FnTableEntry *infer_fn = err_set_type->data.error_set.infer_fn;
7598 if (infer_fn != nullptr) {
7599 if (infer_fn->anal_state == FnAnalStateInvalid) {
7600 return false;
7601 } else if (infer_fn->anal_state == FnAnalStateReady) {
7602 analyze_fn_body(ira->codegen, infer_fn);
7603 if (err_set_type->data.error_set.infer_fn != nullptr) {
7604 assert(ira->codegen->errors.length != 0);
7605 return false;
7606 }
7607 } else {
7608 ir_add_error_node(ira, source_node,
7609 buf_sprintf("cannot resolve inferred error set '%s': function '%s' not fully analyzed yet",
7610 buf_ptr(&err_set_type->name), buf_ptr(&err_set_type->data.error_set.infer_fn->symbol_name)));
7611 return false;
7612 }
7613 }
7614 return true;
7615}
7616
7617static TypeTableEntry *get_error_set_intersection(IrAnalyze *ira, TypeTableEntry *set1, TypeTableEntry *set2,7636static TypeTableEntry *get_error_set_intersection(IrAnalyze *ira, TypeTableEntry *set1, TypeTableEntry *set2,
7618 AstNode *source_node)7637 AstNode *source_node)
7619{7638{
7620 assert(set1->id == TypeTableEntryIdErrorSet);7639 assert(set1->id == TypeTableEntryIdErrorSet);
7621 assert(set2->id == TypeTableEntryIdErrorSet);7640 assert(set2->id == TypeTableEntryIdErrorSet);
76227641
7623 if (!resolve_inferred_error_set(ira, set1, source_node)) {7642 if (!resolve_inferred_error_set(ira->codegen, set1, source_node)) {
7624 return ira->codegen->builtin_types.entry_invalid;7643 return ira->codegen->builtin_types.entry_invalid;
7625 }7644 }
7626 if (!resolve_inferred_error_set(ira, set2, source_node)) {7645 if (!resolve_inferred_error_set(ira->codegen, set2, source_node)) {
7627 return ira->codegen->builtin_types.entry_invalid;7646 return ira->codegen->builtin_types.entry_invalid;
7628 }7647 }
7629 if (type_is_global_error_set(set1)) {7648 if (type_is_global_error_set(set1)) {
...@@ -7762,7 +7781,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7762,7 +7781,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7762 return result;7781 return result;
7763 }7782 }
77647783
7765 if (!resolve_inferred_error_set(ira, contained_set, source_node)) {7784 if (!resolve_inferred_error_set(ira->codegen, contained_set, source_node)) {
7766 result.id = ConstCastResultIdUnresolvedInferredErrSet;7785 result.id = ConstCastResultIdUnresolvedInferredErrSet;
7767 return result;7786 return result;
7768 }7787 }
...@@ -8151,7 +8170,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8151,7 +8170,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8151 err_set_type = ira->codegen->builtin_types.entry_global_error_set;8170 err_set_type = ira->codegen->builtin_types.entry_global_error_set;
8152 } else {8171 } else {
8153 err_set_type = prev_inst->value.type;8172 err_set_type = prev_inst->value.type;
8154 if (!resolve_inferred_error_set(ira, err_set_type, prev_inst->source_node)) {8173 if (!resolve_inferred_error_set(ira->codegen, err_set_type, prev_inst->source_node)) {
8155 return ira->codegen->builtin_types.entry_invalid;8174 return ira->codegen->builtin_types.entry_invalid;
8156 }8175 }
8157 update_errors_helper(ira->codegen, &errors, &errors_count);8176 update_errors_helper(ira->codegen, &errors, &errors_count);
...@@ -8190,7 +8209,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8190,7 +8209,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8190 if (type_is_global_error_set(err_set_type)) {8209 if (type_is_global_error_set(err_set_type)) {
8191 continue;8210 continue;
8192 }8211 }
8193 if (!resolve_inferred_error_set(ira, cur_type, cur_inst->source_node)) {8212 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
8194 return ira->codegen->builtin_types.entry_invalid;8213 return ira->codegen->builtin_types.entry_invalid;
8195 }8214 }
8196 if (type_is_global_error_set(cur_type)) {8215 if (type_is_global_error_set(cur_type)) {
...@@ -8256,7 +8275,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8256,7 +8275,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8256 continue;8275 continue;
8257 }8276 }
8258 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;8277 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;
8259 if (!resolve_inferred_error_set(ira, cur_err_set_type, cur_inst->source_node)) {8278 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
8260 return ira->codegen->builtin_types.entry_invalid;8279 return ira->codegen->builtin_types.entry_invalid;
8261 }8280 }
8262 if (type_is_global_error_set(cur_err_set_type)) {8281 if (type_is_global_error_set(cur_err_set_type)) {
...@@ -8319,7 +8338,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8319,7 +8338,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8319 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) {8338 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) {
8320 continue;8339 continue;
8321 }8340 }
8322 if (!resolve_inferred_error_set(ira, cur_type, cur_inst->source_node)) {8341 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
8323 return ira->codegen->builtin_types.entry_invalid;8342 return ira->codegen->builtin_types.entry_invalid;
8324 }8343 }
83258344
...@@ -8376,11 +8395,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8376,11 +8395,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8376 TypeTableEntry *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type;8395 TypeTableEntry *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type;
8377 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;8396 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;
83788397
8379 if (!resolve_inferred_error_set(ira, prev_err_set_type, cur_inst->source_node)) {8398 if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) {
8380 return ira->codegen->builtin_types.entry_invalid;8399 return ira->codegen->builtin_types.entry_invalid;
8381 }8400 }
83828401
8383 if (!resolve_inferred_error_set(ira, cur_err_set_type, cur_inst->source_node)) {8402 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
8384 return ira->codegen->builtin_types.entry_invalid;8403 return ira->codegen->builtin_types.entry_invalid;
8385 }8404 }
83868405
...@@ -8490,7 +8509,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8490,7 +8509,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8490 {8509 {
8491 if (err_set_type != nullptr) {8510 if (err_set_type != nullptr) {
8492 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;8511 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;
8493 if (!resolve_inferred_error_set(ira, cur_err_set_type, cur_inst->source_node)) {8512 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
8494 return ira->codegen->builtin_types.entry_invalid;8513 return ira->codegen->builtin_types.entry_invalid;
8495 }8514 }
8496 if (type_is_global_error_set(cur_err_set_type) || type_is_global_error_set(err_set_type)) {8515 if (type_is_global_error_set(cur_err_set_type) || type_is_global_error_set(err_set_type)) {
...@@ -8686,6 +8705,10 @@ static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_...@@ -8686,6 +8705,10 @@ static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_
8686 *dest = *src;8705 *dest = *src;
8687 if (!same_global_refs) {8706 if (!same_global_refs) {
8688 dest->global_refs = global_refs;8707 dest->global_refs = global_refs;
8708 if (dest->type->id == TypeTableEntryIdStruct) {
8709 dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count);
8710 memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count);
8711 }
8689 }8712 }
8690}8713}
86918714
...@@ -9168,7 +9191,7 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou...@@ -9168,7 +9191,7 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou
9168 if (!val)9191 if (!val)
9169 return ira->codegen->invalid_instruction;9192 return ira->codegen->invalid_instruction;
91709193
9171 if (!resolve_inferred_error_set(ira, wanted_type, source_instr->source_node)) {9194 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) {
9172 return ira->codegen->invalid_instruction;9195 return ira->codegen->invalid_instruction;
9173 }9196 }
9174 if (!type_is_global_error_set(wanted_type)) {9197 if (!type_is_global_error_set(wanted_type)) {
...@@ -9609,7 +9632,7 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc...@@ -9609,7 +9632,7 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc
9609 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,9632 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
9610 source_instr->source_node, wanted_type);9633 source_instr->source_node, wanted_type);
96119634
9612 if (!resolve_inferred_error_set(ira, wanted_type, source_instr->source_node)) {9635 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) {
9613 return ira->codegen->invalid_instruction;9636 return ira->codegen->invalid_instruction;
9614 }9637 }
96159638
...@@ -9707,7 +9730,7 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc...@@ -9707,7 +9730,7 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc
9707 zig_unreachable();9730 zig_unreachable();
9708 }9731 }
9709 if (!type_is_global_error_set(err_set_type)) {9732 if (!type_is_global_error_set(err_set_type)) {
9710 if (!resolve_inferred_error_set(ira, err_set_type, source_instr->source_node)) {9733 if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) {
9711 return ira->codegen->invalid_instruction;9734 return ira->codegen->invalid_instruction;
9712 }9735 }
9713 if (err_set_type->data.error_set.err_count == 0) {9736 if (err_set_type->data.error_set.err_count == 0) {
...@@ -10602,7 +10625,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -10602,7 +10625,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
10602 return ira->codegen->builtin_types.entry_invalid;10625 return ira->codegen->builtin_types.entry_invalid;
10603 }10626 }
1060410627
10605 if (!resolve_inferred_error_set(ira, intersect_type, source_node)) {10628 if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) {
10606 return ira->codegen->builtin_types.entry_invalid;10629 return ira->codegen->builtin_types.entry_invalid;
10607 }10630 }
1060810631
...@@ -11458,11 +11481,11 @@ static TypeTableEntry *ir_analyze_merge_error_sets(IrAnalyze *ira, IrInstruction...@@ -11458,11 +11481,11 @@ static TypeTableEntry *ir_analyze_merge_error_sets(IrAnalyze *ira, IrInstruction
11458 return ira->codegen->builtin_types.entry_type;11481 return ira->codegen->builtin_types.entry_type;
11459 }11482 }
1146011483
11461 if (!resolve_inferred_error_set(ira, op1_type, instruction->op1->other->source_node)) {11484 if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->other->source_node)) {
11462 return ira->codegen->builtin_types.entry_invalid;11485 return ira->codegen->builtin_types.entry_invalid;
11463 }11486 }
1146411487
11465 if (!resolve_inferred_error_set(ira, op2_type, instruction->op2->other->source_node)) {11488 if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->other->source_node)) {
11466 return ira->codegen->builtin_types.entry_invalid;11489 return ira->codegen->builtin_types.entry_invalid;
11467 }11490 }
1146811491
...@@ -11670,7 +11693,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -11670,7 +11693,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
11670 if (var->mem_slot_index != SIZE_MAX) {11693 if (var->mem_slot_index != SIZE_MAX) {
11671 assert(var->mem_slot_index < ira->exec_context.mem_slot_count);11694 assert(var->mem_slot_index < ira->exec_context.mem_slot_count);
11672 ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];11695 ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
11673 *mem_slot = casted_init_value->value;11696 copy_const_val(mem_slot, &casted_init_value->value,
11697 !is_comptime_var || var->gen_is_const);
1167411698
11675 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) {11699 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) {
11676 ir_build_const_from(ira, &decl_var_instruction->base);11700 ir_build_const_from(ira, &decl_var_instruction->base);
...@@ -11987,7 +12011,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c...@@ -11987,7 +12011,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c
11987 TypeTableEntry *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);12011 TypeTableEntry *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
1198812012
11989 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node,12013 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node,
11990 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst);12014 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr);
11991 result->value.type = async_return_type;12015 result->value.type = async_return_type;
11992 return result;12016 return result;
11993}12017}
...@@ -12084,7 +12108,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -12084,7 +12108,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
12084 casted_arg->value.type->id == TypeTableEntryIdNumLitFloat)12108 casted_arg->value.type->id == TypeTableEntryIdNumLitFloat)
12085 {12109 {
12086 ir_add_error(ira, casted_arg,12110 ir_add_error(ira, casted_arg,
12087 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/zig-lang/zig/issues/557"));12111 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557"));
12088 return false;12112 return false;
12089 }12113 }
1209012114
...@@ -12285,7 +12309,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12285,7 +12309,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1228512309
12286 if (fn_proto_node->data.fn_proto.is_var_args) {12310 if (fn_proto_node->data.fn_proto.is_var_args) {
12287 ir_add_error(ira, &call_instruction->base,12311 ir_add_error(ira, &call_instruction->base,
12288 buf_sprintf("compiler bug: unable to call var args function at compile time. https://github.com/zig-lang/zig/issues/313"));12312 buf_sprintf("compiler bug: unable to call var args function at compile time. https://github.com/ziglang/zig/issues/313"));
12289 return ira->codegen->builtin_types.entry_invalid;12313 return ira->codegen->builtin_types.entry_invalid;
12290 }12314 }
1229112315
...@@ -12357,6 +12381,19 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12357,6 +12381,19 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
12357 return ir_finish_anal(ira, return_type);12381 return ir_finish_anal(ira, return_type);
12358 }12382 }
1235912383
12384 IrInstruction *casted_new_stack = nullptr;
12385 if (call_instruction->new_stack != nullptr) {
12386 TypeTableEntry *u8_ptr = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false);
12387 TypeTableEntry *u8_slice = get_slice_type(ira->codegen, u8_ptr);
12388 IrInstruction *new_stack = call_instruction->new_stack->other;
12389 if (type_is_invalid(new_stack->value.type))
12390 return ira->codegen->builtin_types.entry_invalid;
12391
12392 casted_new_stack = ir_implicit_cast(ira, new_stack, u8_slice);
12393 if (type_is_invalid(casted_new_stack->value.type))
12394 return ira->codegen->builtin_types.entry_invalid;
12395 }
12396
12360 if (fn_type->data.fn.is_generic) {12397 if (fn_type->data.fn.is_generic) {
12361 if (!fn_entry) {12398 if (!fn_entry) {
12362 ir_add_error(ira, call_instruction->fn_ref,12399 ir_add_error(ira, call_instruction->fn_ref,
...@@ -12365,7 +12402,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12365,7 +12402,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
12365 }12402 }
12366 if (call_instruction->is_async && fn_type_id->is_var_args) {12403 if (call_instruction->is_async && fn_type_id->is_var_args) {
12367 ir_add_error(ira, call_instruction->fn_ref,12404 ir_add_error(ira, call_instruction->fn_ref,
12368 buf_sprintf("compiler bug: TODO: implement var args async functions. https://github.com/zig-lang/zig/issues/557"));12405 buf_sprintf("compiler bug: TODO: implement var args async functions. https://github.com/ziglang/zig/issues/557"));
12369 return ira->codegen->builtin_types.entry_invalid;12406 return ira->codegen->builtin_types.entry_invalid;
12370 }12407 }
1237112408
...@@ -12448,7 +12485,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12448,7 +12485,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
12448 VariableTableEntry *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i);12485 VariableTableEntry *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i);
12449 if (arg_var == nullptr) {12486 if (arg_var == nullptr) {
12450 ir_add_error(ira, arg,12487 ir_add_error(ira, arg,
12451 buf_sprintf("compiler bug: var args can't handle void. https://github.com/zig-lang/zig/issues/557"));12488 buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557"));
12452 return ira->codegen->builtin_types.entry_invalid;12489 return ira->codegen->builtin_types.entry_invalid;
12453 }12490 }
12454 IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var, true, false);12491 IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var, true, false);
...@@ -12583,7 +12620,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12583,7 +12620,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
12583 assert(async_allocator_inst == nullptr);12620 assert(async_allocator_inst == nullptr);
12584 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,12621 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,
12585 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline,12622 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline,
12586 call_instruction->is_async, nullptr);12623 call_instruction->is_async, nullptr, casted_new_stack);
1258712624
12588 ir_add_alloca(ira, new_call_instruction, return_type);12625 ir_add_alloca(ira, new_call_instruction, return_type);
1258912626
...@@ -12674,7 +12711,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12674,7 +12711,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1267412711
1267512712
12676 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,12713 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,
12677 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr);12714 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack);
1267812715
12679 ir_add_alloca(ira, new_call_instruction, return_type);12716 ir_add_alloca(ira, new_call_instruction, return_type);
12680 return ir_finish_anal(ira, return_type);12717 return ir_finish_anal(ira, return_type);
...@@ -13792,7 +13829,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -13792,7 +13829,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
13792 }13829 }
13793 err_set_type = err_entry->set_with_only_this_in_it;13830 err_set_type = err_entry->set_with_only_this_in_it;
13794 } else {13831 } else {
13795 if (!resolve_inferred_error_set(ira, child_type, field_ptr_instruction->base.source_node)) {13832 if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.source_node)) {
13796 return ira->codegen->builtin_types.entry_invalid;13833 return ira->codegen->builtin_types.entry_invalid;
13797 }13834 }
13798 err_entry = find_err_table_entry(child_type, field_name);13835 err_entry = find_err_table_entry(child_type, field_name);
...@@ -15923,10 +15960,6 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop...@@ -15923,10 +15960,6 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop
15923 FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;15960 FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
15924 assert(!fn_entry->is_test);15961 assert(!fn_entry->is_test);
1592515962
15926 analyze_fn_body(ira->codegen, fn_entry);
15927 if (fn_entry->anal_state == FnAnalStateInvalid)
15928 return;
15929
15930 AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node);15963 AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node);
1593115964
15932 ConstExprValue *fn_def_val = create_const_vals(1);15965 ConstExprValue *fn_def_val = create_const_vals(1);
...@@ -16496,6 +16529,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -16496,6 +16529,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
16496 {16529 {
16497 size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index);16530 size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index);
16498 inner_fields[1].data.x_maybe = create_const_vals(1);16531 inner_fields[1].data.x_maybe = create_const_vals(1);
16532 inner_fields[1].data.x_maybe->special = ConstValSpecialStatic;
16499 inner_fields[1].data.x_maybe->type = ira->codegen->builtin_types.entry_usize;16533 inner_fields[1].data.x_maybe->type = ira->codegen->builtin_types.entry_usize;
16500 bigint_init_unsigned(&inner_fields[1].data.x_maybe->data.x_bigint, byte_offset);16534 bigint_init_unsigned(&inner_fields[1].data.x_maybe->data.x_bigint, byte_offset);
16501 }16535 }
...@@ -17503,7 +17537,7 @@ static TypeTableEntry *ir_analyze_instruction_member_count(IrAnalyze *ira, IrIns...@@ -17503,7 +17537,7 @@ static TypeTableEntry *ir_analyze_instruction_member_count(IrAnalyze *ira, IrIns
17503 } else if (container_type->id == TypeTableEntryIdUnion) {17537 } else if (container_type->id == TypeTableEntryIdUnion) {
17504 result = container_type->data.unionation.src_field_count;17538 result = container_type->data.unionation.src_field_count;
17505 } else if (container_type->id == TypeTableEntryIdErrorSet) {17539 } else if (container_type->id == TypeTableEntryIdErrorSet) {
17506 if (!resolve_inferred_error_set(ira, container_type, instruction->base.source_node)) {17540 if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.source_node)) {
17507 return ira->codegen->builtin_types.entry_invalid;17541 return ira->codegen->builtin_types.entry_invalid;
17508 }17542 }
17509 if (type_is_global_error_set(container_type)) {17543 if (type_is_global_error_set(container_type)) {
...@@ -17807,7 +17841,7 @@ static TypeTableEntry *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruc...@@ -17807,7 +17841,7 @@ static TypeTableEntry *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruc
17807 }17841 }
1780817842
17809 TypeTableEntry *err_set_type = type_entry->data.error_union.err_set_type;17843 TypeTableEntry *err_set_type = type_entry->data.error_union.err_set_type;
17810 if (!resolve_inferred_error_set(ira, err_set_type, instruction->base.source_node)) {17844 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) {
17811 return ira->codegen->builtin_types.entry_invalid;17845 return ira->codegen->builtin_types.entry_invalid;
17812 }17846 }
17813 if (!type_is_global_error_set(err_set_type) &&17847 if (!type_is_global_error_set(err_set_type) &&
...@@ -17880,6 +17914,15 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,...@@ -17880,6 +17914,15 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
17880 return ira->codegen->builtin_types.entry_invalid;17914 return ira->codegen->builtin_types.entry_invalid;
17881 TypeTableEntry *ptr_type = value->value.type;17915 TypeTableEntry *ptr_type = value->value.type;
1788217916
17917 // Because we don't have Pointer Reform yet, we can't have a pointer to a 'type'.
17918 // Therefor, we have to check for type 'type' here, so we can output a correct error
17919 // without asserting the assert below.
17920 if (ptr_type->id == TypeTableEntryIdMetaType) {
17921 ir_add_error(ira, value,
17922 buf_sprintf("expected error union type, found '%s'", buf_ptr(&ptr_type->name)));
17923 return ira->codegen->builtin_types.entry_invalid;
17924 }
17925
17883 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing.17926 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing.
17884 assert(ptr_type->id == TypeTableEntryIdPointer);17927 assert(ptr_type->id == TypeTableEntryIdPointer);
1788517928
...@@ -18030,7 +18073,11 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira...@@ -18030,7 +18073,11 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira
18030 if (type_is_invalid(end_value->value.type))18073 if (type_is_invalid(end_value->value.type))
18031 return ira->codegen->builtin_types.entry_invalid;18074 return ira->codegen->builtin_types.entry_invalid;
1803218075
18033 assert(start_value->value.type->id == TypeTableEntryIdEnum);18076 if (start_value->value.type->id != TypeTableEntryIdEnum) {
18077 ir_add_error(ira, range->start, buf_sprintf("not an enum type"));
18078 return ira->codegen->builtin_types.entry_invalid;
18079 }
18080
18034 BigInt start_index;18081 BigInt start_index;
18035 bigint_init_bigint(&start_index, &start_value->value.data.x_enum_tag);18082 bigint_init_bigint(&start_index, &start_value->value.data.x_enum_tag);
1803618083
...@@ -18071,7 +18118,7 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira...@@ -18071,7 +18118,7 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira
18071 }18118 }
18072 }18119 }
18073 } else if (switch_type->id == TypeTableEntryIdErrorSet) {18120 } else if (switch_type->id == TypeTableEntryIdErrorSet) {
18074 if (!resolve_inferred_error_set(ira, switch_type, target_value->source_node)) {18121 if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->source_node)) {
18075 return ira->codegen->builtin_types.entry_invalid;18122 return ira->codegen->builtin_types.entry_invalid;
18076 }18123 }
1807718124
src/parser.cpp+25-18
...@@ -1046,11 +1046,12 @@ static AstNode *ast_parse_fn_proto_partial(ParseContext *pc, size_t *token_index...@@ -1046,11 +1046,12 @@ static AstNode *ast_parse_fn_proto_partial(ParseContext *pc, size_t *token_index
1046}1046}
10471047
1048/*1048/*
1049SuffixOpExpression = ("async" option("<" SuffixOpExpression ">") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)1049SuffixOpExpression = ("async" option("<" SuffixOpExpression ">") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | PtrDerefExpression | SliceExpression)
1050FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)1050FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)
1051ArrayAccessExpression : token(LBracket) Expression token(RBracket)1051ArrayAccessExpression : token(LBracket) Expression token(RBracket)
1052SliceExpression = "[" Expression ".." option(Expression) "]"1052SliceExpression = "[" Expression ".." option(Expression) "]"
1053FieldAccessExpression : token(Dot) token(Symbol)1053FieldAccessExpression : token(Dot) token(Symbol)
1054PtrDerefExpression = ".*"
1054StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression1055StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression
1055*/1056*/
1056static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {1057static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
...@@ -1131,13 +1132,27 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,...@@ -1131,13 +1132,27 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,
1131 } else if (first_token->id == TokenIdDot) {1132 } else if (first_token->id == TokenIdDot) {
1132 *token_index += 1;1133 *token_index += 1;
11331134
1134 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);1135 Token *token = &pc->tokens->at(*token_index);
1136
1137 if (token->id == TokenIdSymbol) {
1138 *token_index += 1;
11351139
1136 AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token);1140 AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token);
1137 node->data.field_access_expr.struct_expr = primary_expr;1141 node->data.field_access_expr.struct_expr = primary_expr;
1138 node->data.field_access_expr.field_name = token_buf(name_token);1142 node->data.field_access_expr.field_name = token_buf(token);
1143
1144 primary_expr = node;
1145 } else if (token->id == TokenIdStar) {
1146 *token_index += 1;
1147
1148 AstNode *node = ast_create_node(pc, NodeTypePtrDeref, first_token);
1149 node->data.ptr_deref_expr.target = primary_expr;
1150
1151 primary_expr = node;
1152 } else {
1153 ast_invalid_token_error(pc, token);
1154 }
11391155
1140 primary_expr = node;
1141 } else {1156 } else {
1142 return primary_expr;1157 return primary_expr;
1143 }1158 }
...@@ -1150,10 +1165,8 @@ static PrefixOp tok_to_prefix_op(Token *token) {...@@ -1150,10 +1165,8 @@ static PrefixOp tok_to_prefix_op(Token *token) {
1150 case TokenIdDash: return PrefixOpNegation;1165 case TokenIdDash: return PrefixOpNegation;
1151 case TokenIdMinusPercent: return PrefixOpNegationWrap;1166 case TokenIdMinusPercent: return PrefixOpNegationWrap;
1152 case TokenIdTilde: return PrefixOpBinNot;1167 case TokenIdTilde: return PrefixOpBinNot;
1153 case TokenIdStar: return PrefixOpDereference;
1154 case TokenIdMaybe: return PrefixOpMaybe;1168 case TokenIdMaybe: return PrefixOpMaybe;
1155 case TokenIdDoubleQuestion: return PrefixOpUnwrapMaybe;1169 case TokenIdDoubleQuestion: return PrefixOpUnwrapMaybe;
1156 case TokenIdStarStar: return PrefixOpDereference;
1157 default: return PrefixOpInvalid;1170 default: return PrefixOpInvalid;
1158 }1171 }
1159}1172}
...@@ -1199,7 +1212,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {...@@ -1199,7 +1212,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
11991212
1200/*1213/*
1201PrefixOpExpression = PrefixOp ErrorSetExpr | SuffixOpExpression1214PrefixOpExpression = PrefixOp ErrorSetExpr | SuffixOpExpression
1202PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"1215PrefixOp = "!" | "-" | "~" | ("*" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"
1203*/1216*/
1204static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {1217static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
1205 Token *token = &pc->tokens->at(*token_index);1218 Token *token = &pc->tokens->at(*token_index);
...@@ -1222,15 +1235,6 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,...@@ -1222,15 +1235,6 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,
12221235
1223 AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token);1236 AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token);
1224 AstNode *parent_node = node;1237 AstNode *parent_node = node;
1225 if (token->id == TokenIdStarStar) {
1226 // pretend that we got 2 star tokens
1227
1228 parent_node = ast_create_node(pc, NodeTypePrefixOpExpr, token);
1229 parent_node->data.prefix_op_expr.primary_expr = node;
1230 parent_node->data.prefix_op_expr.prefix_op = PrefixOpDereference;
1231
1232 node->column += 1;
1233 }
12341238
1235 AstNode *prefix_op_expr = ast_parse_error_set_expr(pc, token_index, true);1239 AstNode *prefix_op_expr = ast_parse_error_set_expr(pc, token_index, true);
1236 node->data.prefix_op_expr.primary_expr = prefix_op_expr;1240 node->data.prefix_op_expr.primary_expr = prefix_op_expr;
...@@ -3012,6 +3016,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -3012,6 +3016,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
3012 case NodeTypeFieldAccessExpr:3016 case NodeTypeFieldAccessExpr:
3013 visit_field(&node->data.field_access_expr.struct_expr, visit, context);3017 visit_field(&node->data.field_access_expr.struct_expr, visit, context);
3014 break;3018 break;
3019 case NodeTypePtrDeref:
3020 visit_field(&node->data.ptr_deref_expr.target, visit, context);
3021 break;
3015 case NodeTypeUse:3022 case NodeTypeUse:
3016 visit_field(&node->data.use.expr, visit, context);3023 visit_field(&node->data.use.expr, visit, context);
3017 break;3024 break;
src/target.cpp+63-1
...@@ -702,6 +702,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {...@@ -702,6 +702,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
702 case OsLinux:702 case OsLinux:
703 case OsMacOSX:703 case OsMacOSX:
704 case OsZen:704 case OsZen:
705 case OsOpenBSD:
705 switch (id) {706 switch (id) {
706 case CIntTypeShort:707 case CIntTypeShort:
707 case CIntTypeUShort:708 case CIntTypeUShort:
...@@ -742,7 +743,6 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {...@@ -742,7 +743,6 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
742 case OsKFreeBSD:743 case OsKFreeBSD:
743 case OsLv2:744 case OsLv2:
744 case OsNetBSD:745 case OsNetBSD:
745 case OsOpenBSD:
746 case OsSolaris:746 case OsSolaris:
747 case OsHaiku:747 case OsHaiku:
748 case OsMinix:748 case OsMinix:
...@@ -896,3 +896,65 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target...@@ -896,3 +896,65 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target
896896
897 return false;897 return false;
898}898}
899
900const char *arch_stack_pointer_register_name(const ArchType *arch) {
901 switch (arch->arch) {
902 case ZigLLVM_UnknownArch:
903 zig_unreachable();
904 case ZigLLVM_x86:
905 return "sp";
906 case ZigLLVM_x86_64:
907 return "rsp";
908
909 case ZigLLVM_aarch64:
910 case ZigLLVM_arm:
911 case ZigLLVM_thumb:
912 case ZigLLVM_aarch64_be:
913 case ZigLLVM_amdgcn:
914 case ZigLLVM_amdil:
915 case ZigLLVM_amdil64:
916 case ZigLLVM_armeb:
917 case ZigLLVM_arc:
918 case ZigLLVM_avr:
919 case ZigLLVM_bpfeb:
920 case ZigLLVM_bpfel:
921 case ZigLLVM_hexagon:
922 case ZigLLVM_lanai:
923 case ZigLLVM_hsail:
924 case ZigLLVM_hsail64:
925 case ZigLLVM_kalimba:
926 case ZigLLVM_le32:
927 case ZigLLVM_le64:
928 case ZigLLVM_mips:
929 case ZigLLVM_mips64:
930 case ZigLLVM_mips64el:
931 case ZigLLVM_mipsel:
932 case ZigLLVM_msp430:
933 case ZigLLVM_nios2:
934 case ZigLLVM_nvptx:
935 case ZigLLVM_nvptx64:
936 case ZigLLVM_ppc64le:
937 case ZigLLVM_r600:
938 case ZigLLVM_renderscript32:
939 case ZigLLVM_renderscript64:
940 case ZigLLVM_riscv32:
941 case ZigLLVM_riscv64:
942 case ZigLLVM_shave:
943 case ZigLLVM_sparc:
944 case ZigLLVM_sparcel:
945 case ZigLLVM_sparcv9:
946 case ZigLLVM_spir:
947 case ZigLLVM_spir64:
948 case ZigLLVM_systemz:
949 case ZigLLVM_tce:
950 case ZigLLVM_tcele:
951 case ZigLLVM_thumbeb:
952 case ZigLLVM_wasm32:
953 case ZigLLVM_wasm64:
954 case ZigLLVM_xcore:
955 case ZigLLVM_ppc:
956 case ZigLLVM_ppc64:
957 zig_panic("TODO populate this table with stack pointer register name for this CPU architecture");
958 }
959 zig_unreachable();
960}
src/target.hpp+2
...@@ -77,6 +77,8 @@ size_t target_arch_count(void);...@@ -77,6 +77,8 @@ size_t target_arch_count(void);
77const ArchType *get_target_arch(size_t index);77const ArchType *get_target_arch(size_t index);
78void get_arch_name(char *out_str, const ArchType *arch);78void get_arch_name(char *out_str, const ArchType *arch);
7979
80const char *arch_stack_pointer_register_name(const ArchType *arch);
81
80size_t target_vendor_count(void);82size_t target_vendor_count(void);
81ZigLLVM_VendorType get_target_vendor(size_t index);83ZigLLVM_VendorType get_target_vendor(size_t index);
8284
src/translate_c.cpp+53-30
...@@ -247,6 +247,12 @@ static AstNode *trans_create_node_field_access_str(Context *c, AstNode *containe...@@ -247,6 +247,12 @@ static AstNode *trans_create_node_field_access_str(Context *c, AstNode *containe
247 return trans_create_node_field_access(c, container, buf_create_from_str(field_name));247 return trans_create_node_field_access(c, container, buf_create_from_str(field_name));
248}248}
249249
250static AstNode *trans_create_node_ptr_deref(Context *c, AstNode *child_node) {
251 AstNode *node = trans_create_node(c, NodeTypePtrDeref);
252 node->data.ptr_deref_expr.target = child_node;
253 return node;
254}
255
250static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {256static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
251 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);257 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
252 node->data.prefix_op_expr.prefix_op = op;258 node->data.prefix_op_expr.prefix_op = op;
...@@ -1412,8 +1418,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1412,8 +1418,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
1412 AstNode *operation_type_cast = trans_c_cast(c, rhs_location,1418 AstNode *operation_type_cast = trans_c_cast(c, rhs_location,
1413 stmt->getComputationLHSType(),1419 stmt->getComputationLHSType(),
1414 stmt->getLHS()->getType(),1420 stmt->getLHS()->getType(),
1415 trans_create_node_prefix_op(c, PrefixOpDereference,1421 trans_create_node_ptr_deref(c, trans_create_node_symbol(c, tmp_var_name)));
1416 trans_create_node_symbol(c, tmp_var_name)));
14171422
1418 // result_type(... >> u5(rhs))1423 // result_type(... >> u5(rhs))
1419 AstNode *result_type_cast = trans_c_cast(c, rhs_location,1424 AstNode *result_type_cast = trans_c_cast(c, rhs_location,
...@@ -1426,7 +1431,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1426,7 +1431,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
14261431
1427 // *_ref = ...1432 // *_ref = ...
1428 AstNode *assign_statement = trans_create_node_bin_op(c,1433 AstNode *assign_statement = trans_create_node_bin_op(c,
1429 trans_create_node_prefix_op(c, PrefixOpDereference,1434 trans_create_node_ptr_deref(c,
1430 trans_create_node_symbol(c, tmp_var_name)),1435 trans_create_node_symbol(c, tmp_var_name)),
1431 BinOpTypeAssign, result_type_cast);1436 BinOpTypeAssign, result_type_cast);
14321437
...@@ -1436,7 +1441,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1436,7 +1441,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
1436 // break :x *_ref1441 // break :x *_ref
1437 child_scope->node->data.block.statements.append(1442 child_scope->node->data.block.statements.append(
1438 trans_create_node_break(c, label_name,1443 trans_create_node_break(c, label_name,
1439 trans_create_node_prefix_op(c, PrefixOpDereference,1444 trans_create_node_ptr_deref(c,
1440 trans_create_node_symbol(c, tmp_var_name))));1445 trans_create_node_symbol(c, tmp_var_name))));
1441 }1446 }
14421447
...@@ -1483,11 +1488,11 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,...@@ -1483,11 +1488,11 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
1483 if (rhs == nullptr) return nullptr;1488 if (rhs == nullptr) return nullptr;
14841489
1485 AstNode *assign_statement = trans_create_node_bin_op(c,1490 AstNode *assign_statement = trans_create_node_bin_op(c,
1486 trans_create_node_prefix_op(c, PrefixOpDereference,1491 trans_create_node_ptr_deref(c,
1487 trans_create_node_symbol(c, tmp_var_name)),1492 trans_create_node_symbol(c, tmp_var_name)),
1488 BinOpTypeAssign,1493 BinOpTypeAssign,
1489 trans_create_node_bin_op(c,1494 trans_create_node_bin_op(c,
1490 trans_create_node_prefix_op(c, PrefixOpDereference,1495 trans_create_node_ptr_deref(c,
1491 trans_create_node_symbol(c, tmp_var_name)),1496 trans_create_node_symbol(c, tmp_var_name)),
1492 bin_op,1497 bin_op,
1493 rhs));1498 rhs));
...@@ -1496,7 +1501,7 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,...@@ -1496,7 +1501,7 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
1496 // break :x *_ref1501 // break :x *_ref
1497 child_scope->node->data.block.statements.append(1502 child_scope->node->data.block.statements.append(
1498 trans_create_node_break(c, label_name,1503 trans_create_node_break(c, label_name,
1499 trans_create_node_prefix_op(c, PrefixOpDereference,1504 trans_create_node_ptr_deref(c,
1500 trans_create_node_symbol(c, tmp_var_name))));1505 trans_create_node_symbol(c, tmp_var_name))));
15011506
1502 return child_scope->node;1507 return child_scope->node;
...@@ -1817,13 +1822,13 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr...@@ -1817,13 +1822,13 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr
1817 // const _tmp = *_ref;1822 // const _tmp = *_ref;
1818 Buf* tmp_var_name = buf_create_from_str("_tmp");1823 Buf* tmp_var_name = buf_create_from_str("_tmp");
1819 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr,1824 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr,
1820 trans_create_node_prefix_op(c, PrefixOpDereference,1825 trans_create_node_ptr_deref(c,
1821 trans_create_node_symbol(c, ref_var_name)));1826 trans_create_node_symbol(c, ref_var_name)));
1822 child_scope->node->data.block.statements.append(tmp_var_decl);1827 child_scope->node->data.block.statements.append(tmp_var_decl);
18231828
1824 // *_ref += 1;1829 // *_ref += 1;
1825 AstNode *assign_statement = trans_create_node_bin_op(c,1830 AstNode *assign_statement = trans_create_node_bin_op(c,
1826 trans_create_node_prefix_op(c, PrefixOpDereference,1831 trans_create_node_ptr_deref(c,
1827 trans_create_node_symbol(c, ref_var_name)),1832 trans_create_node_symbol(c, ref_var_name)),
1828 assign_op,1833 assign_op,
1829 trans_create_node_unsigned(c, 1));1834 trans_create_node_unsigned(c, 1));
...@@ -1871,14 +1876,14 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra...@@ -1871,14 +1876,14 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra
18711876
1872 // *_ref += 1;1877 // *_ref += 1;
1873 AstNode *assign_statement = trans_create_node_bin_op(c,1878 AstNode *assign_statement = trans_create_node_bin_op(c,
1874 trans_create_node_prefix_op(c, PrefixOpDereference,1879 trans_create_node_ptr_deref(c,
1875 trans_create_node_symbol(c, ref_var_name)),1880 trans_create_node_symbol(c, ref_var_name)),
1876 assign_op,1881 assign_op,
1877 trans_create_node_unsigned(c, 1));1882 trans_create_node_unsigned(c, 1));
1878 child_scope->node->data.block.statements.append(assign_statement);1883 child_scope->node->data.block.statements.append(assign_statement);
18791884
1880 // break :x *_ref1885 // break :x *_ref
1881 AstNode *deref_expr = trans_create_node_prefix_op(c, PrefixOpDereference,1886 AstNode *deref_expr = trans_create_node_ptr_deref(c,
1882 trans_create_node_symbol(c, ref_var_name));1887 trans_create_node_symbol(c, ref_var_name));
1883 child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, deref_expr));1888 child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, deref_expr));
18841889
...@@ -1923,7 +1928,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc...@@ -1923,7 +1928,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
1923 if (is_fn_ptr)1928 if (is_fn_ptr)
1924 return value_node;1929 return value_node;
1925 AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);1930 AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);
1926 return trans_create_node_prefix_op(c, PrefixOpDereference, unwrapped);1931 return trans_create_node_ptr_deref(c, unwrapped);
1927 }1932 }
1928 case UO_Plus:1933 case UO_Plus:
1929 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus");1934 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus");
...@@ -4443,27 +4448,45 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t...@@ -4443,27 +4448,45 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t
4443 }4448 }
4444}4449}
44454450
4446static PrefixOp ctok_to_prefix_op(CTok *token) {
4447 switch (token->id) {
4448 case CTokIdBang: return PrefixOpBoolNot;
4449 case CTokIdMinus: return PrefixOpNegation;
4450 case CTokIdTilde: return PrefixOpBinNot;
4451 case CTokIdAsterisk: return PrefixOpDereference;
4452 default: return PrefixOpInvalid;
4453 }
4454}
4455static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {4451static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4456 CTok *op_tok = &ctok->tokens.at(*tok_i);4452 CTok *op_tok = &ctok->tokens.at(*tok_i);
4457 PrefixOp prefix_op = ctok_to_prefix_op(op_tok);
4458 if (prefix_op == PrefixOpInvalid) {
4459 return parse_ctok_suffix_op_expr(c, ctok, tok_i);
4460 }
4461 *tok_i += 1;
44624453
4463 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);4454 switch (op_tok->id) {
4464 if (prefix_op_expr == nullptr)4455 case CTokIdBang:
4465 return nullptr;4456 {
4466 return trans_create_node_prefix_op(c, prefix_op, prefix_op_expr);4457 *tok_i += 1;
4458 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4459 if (prefix_op_expr == nullptr)
4460 return nullptr;
4461 return trans_create_node_prefix_op(c, PrefixOpBoolNot, prefix_op_expr);
4462 }
4463 case CTokIdMinus:
4464 {
4465 *tok_i += 1;
4466 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4467 if (prefix_op_expr == nullptr)
4468 return nullptr;
4469 return trans_create_node_prefix_op(c, PrefixOpNegation, prefix_op_expr);
4470 }
4471 case CTokIdTilde:
4472 {
4473 *tok_i += 1;
4474 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4475 if (prefix_op_expr == nullptr)
4476 return nullptr;
4477 return trans_create_node_prefix_op(c, PrefixOpBinNot, prefix_op_expr);
4478 }
4479 case CTokIdAsterisk:
4480 {
4481 *tok_i += 1;
4482 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4483 if (prefix_op_expr == nullptr)
4484 return nullptr;
4485 return trans_create_node_ptr_deref(c, prefix_op_expr);
4486 }
4487 default:
4488 return parse_ctok_suffix_op_expr(c, ctok, tok_i);
4489 }
4467}4490}
44684491
4469static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {4492static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
std/array_list.zig+39-24
...@@ -8,7 +8,7 @@ pub fn ArrayList(comptime T: type) type {...@@ -8,7 +8,7 @@ pub fn ArrayList(comptime T: type) type {
8 return AlignedArrayList(T, @alignOf(T));8 return AlignedArrayList(T, @alignOf(T));
9}9}
1010
11pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{11pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
12 return struct {12 return struct {
13 const Self = this;13 const Self = this;
1414
...@@ -21,7 +21,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{...@@ -21,7 +21,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
2121
22 /// Deinitialize with `deinit` or use `toOwnedSlice`.22 /// Deinitialize with `deinit` or use `toOwnedSlice`.
23 pub fn init(allocator: &Allocator) Self {23 pub fn init(allocator: &Allocator) Self {
24 return Self {24 return Self{
25 .items = []align(A) T{},25 .items = []align(A) T{},
26 .len = 0,26 .len = 0,
27 .allocator = allocator,27 .allocator = allocator,
...@@ -52,7 +52,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{...@@ -52,7 +52,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
52 /// allocated with `allocator`.52 /// allocated with `allocator`.
53 /// Deinitialize with `deinit` or use `toOwnedSlice`.53 /// Deinitialize with `deinit` or use `toOwnedSlice`.
54 pub fn fromOwnedSlice(allocator: &Allocator, slice: []align(A) T) Self {54 pub fn fromOwnedSlice(allocator: &Allocator, slice: []align(A) T) Self {
55 return Self {55 return Self{
56 .items = slice,56 .items = slice,
57 .len = slice.len,57 .len = slice.len,
58 .allocator = allocator,58 .allocator = allocator,
...@@ -63,7 +63,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{...@@ -63,7 +63,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
63 pub fn toOwnedSlice(self: &Self) []align(A) T {63 pub fn toOwnedSlice(self: &Self) []align(A) T {
64 const allocator = self.allocator;64 const allocator = self.allocator;
65 const result = allocator.alignedShrink(T, A, self.items, self.len);65 const result = allocator.alignedShrink(T, A, self.items, self.len);
66 *self = init(allocator);66 self.* = init(allocator);
67 return result;67 return result;
68 }68 }
6969
...@@ -71,21 +71,21 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{...@@ -71,21 +71,21 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
71 try l.ensureCapacity(l.len + 1);71 try l.ensureCapacity(l.len + 1);
72 l.len += 1;72 l.len += 1;
7373
74 mem.copy(T, l.items[n+1..l.len], l.items[n..l.len-1]);74 mem.copy(T, l.items[n + 1..l.len], l.items[n..l.len - 1]);
75 l.items[n] = *item;75 l.items[n] = item.*;
76 }76 }
7777
78 pub fn insertSlice(l: &Self, n: usize, items: []align(A) const T) !void {78 pub fn insertSlice(l: &Self, n: usize, items: []align(A) const T) !void {
79 try l.ensureCapacity(l.len + items.len);79 try l.ensureCapacity(l.len + items.len);
80 l.len += items.len;80 l.len += items.len;
8181
82 mem.copy(T, l.items[n+items.len..l.len], l.items[n..l.len-items.len]);82 mem.copy(T, l.items[n + items.len..l.len], l.items[n..l.len - items.len]);
83 mem.copy(T, l.items[n..n+items.len], items);83 mem.copy(T, l.items[n..n + items.len], items);
84 }84 }
8585
86 pub fn append(l: &Self, item: &const T) !void {86 pub fn append(l: &Self, item: &const T) !void {
87 const new_item_ptr = try l.addOne();87 const new_item_ptr = try l.addOne();
88 *new_item_ptr = *item;88 new_item_ptr.* = item.*;
89 }89 }
9090
91 pub fn appendSlice(l: &Self, items: []align(A) const T) !void {91 pub fn appendSlice(l: &Self, items: []align(A) const T) !void {
...@@ -128,8 +128,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{...@@ -128,8 +128,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
128 }128 }
129129
130 pub fn popOrNull(self: &Self) ?T {130 pub fn popOrNull(self: &Self) ?T {
131 if (self.len == 0)131 if (self.len == 0) return null;
132 return null;
133 return self.pop();132 return self.pop();
134 }133 }
135134
...@@ -151,7 +150,10 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{...@@ -151,7 +150,10 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
151 };150 };
152151
153 pub fn iterator(self: &const Self) Iterator {152 pub fn iterator(self: &const Self) Iterator {
154 return Iterator { .list = self, .count = 0 };153 return Iterator{
154 .list = self,
155 .count = 0,
156 };
155 }157 }
156 };158 };
157}159}
...@@ -160,13 +162,19 @@ test "basic ArrayList test" {...@@ -160,13 +162,19 @@ test "basic ArrayList test" {
160 var list = ArrayList(i32).init(debug.global_allocator);162 var list = ArrayList(i32).init(debug.global_allocator);
161 defer list.deinit();163 defer list.deinit();
162164
163 {var i: usize = 0; while (i < 10) : (i += 1) {165 {
164 list.append(i32(i + 1)) catch unreachable;166 var i: usize = 0;
165 }}167 while (i < 10) : (i += 1) {
168 list.append(i32(i + 1)) catch unreachable;
169 }
170 }
166171
167 {var i: usize = 0; while (i < 10) : (i += 1) {172 {
168 assert(list.items[i] == i32(i + 1));173 var i: usize = 0;
169 }}174 while (i < 10) : (i += 1) {
175 assert(list.items[i] == i32(i + 1));
176 }
177 }
170178
171 for (list.toSlice()) |v, i| {179 for (list.toSlice()) |v, i| {
172 assert(v == i32(i + 1));180 assert(v == i32(i + 1));
...@@ -179,14 +187,18 @@ test "basic ArrayList test" {...@@ -179,14 +187,18 @@ test "basic ArrayList test" {
179 assert(list.pop() == 10);187 assert(list.pop() == 10);
180 assert(list.len == 9);188 assert(list.len == 9);
181189
182 list.appendSlice([]const i32 { 1, 2, 3 }) catch unreachable;190 list.appendSlice([]const i32{
191 1,
192 2,
193 3,
194 }) catch unreachable;
183 assert(list.len == 12);195 assert(list.len == 12);
184 assert(list.pop() == 3);196 assert(list.pop() == 3);
185 assert(list.pop() == 2);197 assert(list.pop() == 2);
186 assert(list.pop() == 1);198 assert(list.pop() == 1);
187 assert(list.len == 9);199 assert(list.len == 9);
188200
189 list.appendSlice([]const i32 {}) catch unreachable;201 list.appendSlice([]const i32{}) catch unreachable;
190 assert(list.len == 9);202 assert(list.len == 9);
191}203}
192204
...@@ -198,7 +210,7 @@ test "iterator ArrayList test" {...@@ -198,7 +210,7 @@ test "iterator ArrayList test" {
198 try list.append(2);210 try list.append(2);
199 try list.append(3);211 try list.append(3);
200212
201 var count : i32 = 0;213 var count: i32 = 0;
202 var it = list.iterator();214 var it = list.iterator();
203 while (it.next()) |next| {215 while (it.next()) |next| {
204 assert(next == count + 1);216 assert(next == count + 1);
...@@ -216,7 +228,7 @@ test "iterator ArrayList test" {...@@ -216,7 +228,7 @@ test "iterator ArrayList test" {
216 }228 }
217229
218 it.reset();230 it.reset();
219 assert(?? it.next() == 1);231 assert(??it.next() == 1);
220}232}
221233
222test "insert ArrayList test" {234test "insert ArrayList test" {
...@@ -228,12 +240,15 @@ test "insert ArrayList test" {...@@ -228,12 +240,15 @@ test "insert ArrayList test" {
228 assert(list.items[0] == 5);240 assert(list.items[0] == 5);
229 assert(list.items[1] == 1);241 assert(list.items[1] == 1);
230242
231 try list.insertSlice(1, []const i32 { 9, 8 });243 try list.insertSlice(1, []const i32{
244 9,
245 8,
246 });
232 assert(list.items[0] == 5);247 assert(list.items[0] == 5);
233 assert(list.items[1] == 9);248 assert(list.items[1] == 9);
234 assert(list.items[2] == 8);249 assert(list.items[2] == 8);
235250
236 const items = []const i32 { 1 };251 const items = []const i32{1};
237 try list.insertSlice(0, items[0..0]);252 try list.insertSlice(0, items[0..0]);
238 assert(list.items[0] == 5);253 assert(list.items[0] == 5);
239}254}
std/atomic/queue.zig+8-6
...@@ -16,7 +16,7 @@ pub fn Queue(comptime T: type) type {...@@ -16,7 +16,7 @@ pub fn Queue(comptime T: type) type {
16 data: T,16 data: T,
17 };17 };
1818
19 // TODO: well defined copy elision: https://github.com/zig-lang/zig/issues/28719 // TODO: well defined copy elision: https://github.com/ziglang/zig/issues/287
20 pub fn init(self: &Self) void {20 pub fn init(self: &Self) void {
21 self.root.next = null;21 self.root.next = null;
22 self.head = &self.root;22 self.head = &self.root;
...@@ -70,7 +70,7 @@ test "std.atomic.queue" {...@@ -70,7 +70,7 @@ test "std.atomic.queue" {
7070
71 var queue: Queue(i32) = undefined;71 var queue: Queue(i32) = undefined;
72 queue.init();72 queue.init();
73 var context = Context {73 var context = Context{
74 .allocator = a,74 .allocator = a,
75 .queue = &queue,75 .queue = &queue,
76 .put_sum = 0,76 .put_sum = 0,
...@@ -81,16 +81,18 @@ test "std.atomic.queue" {...@@ -81,16 +81,18 @@ test "std.atomic.queue" {
8181
82 var putters: [put_thread_count]&std.os.Thread = undefined;82 var putters: [put_thread_count]&std.os.Thread = undefined;
83 for (putters) |*t| {83 for (putters) |*t| {
84 *t = try std.os.spawnThread(&context, startPuts);84 t.* = try std.os.spawnThread(&context, startPuts);
85 }85 }
86 var getters: [put_thread_count]&std.os.Thread = undefined;86 var getters: [put_thread_count]&std.os.Thread = undefined;
87 for (getters) |*t| {87 for (getters) |*t| {
88 *t = try std.os.spawnThread(&context, startGets);88 t.* = try std.os.spawnThread(&context, startGets);
89 }89 }
9090
91 for (putters) |t| t.wait();91 for (putters) |t|
92 t.wait();
92 _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);93 _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
93 for (getters) |t| t.wait();94 for (getters) |t|
95 t.wait();
9496
95 std.debug.assert(context.put_sum == context.get_sum);97 std.debug.assert(context.put_sum == context.get_sum);
96 std.debug.assert(context.get_count == puts_per_thread * put_thread_count);98 std.debug.assert(context.get_count == puts_per_thread * put_thread_count);
std/atomic/stack.zig+8-8
...@@ -14,9 +14,7 @@ pub fn Stack(comptime T: type) type {...@@ -14,9 +14,7 @@ pub fn Stack(comptime T: type) type {
14 };14 };
1515
16 pub fn init() Self {16 pub fn init() Self {
17 return Self {17 return Self{ .root = null };
18 .root = null,
19 };
20 }18 }
2119
22 /// push operation, but only if you are the first item in the stack. if you did not succeed in20 /// push operation, but only if you are the first item in the stack. if you did not succeed in
...@@ -75,7 +73,7 @@ test "std.atomic.stack" {...@@ -75,7 +73,7 @@ test "std.atomic.stack" {
75 var a = &fixed_buffer_allocator.allocator;73 var a = &fixed_buffer_allocator.allocator;
7674
77 var stack = Stack(i32).init();75 var stack = Stack(i32).init();
78 var context = Context {76 var context = Context{
79 .allocator = a,77 .allocator = a,
80 .stack = &stack,78 .stack = &stack,
81 .put_sum = 0,79 .put_sum = 0,
...@@ -86,16 +84,18 @@ test "std.atomic.stack" {...@@ -86,16 +84,18 @@ test "std.atomic.stack" {
8684
87 var putters: [put_thread_count]&std.os.Thread = undefined;85 var putters: [put_thread_count]&std.os.Thread = undefined;
88 for (putters) |*t| {86 for (putters) |*t| {
89 *t = try std.os.spawnThread(&context, startPuts);87 t.* = try std.os.spawnThread(&context, startPuts);
90 }88 }
91 var getters: [put_thread_count]&std.os.Thread = undefined;89 var getters: [put_thread_count]&std.os.Thread = undefined;
92 for (getters) |*t| {90 for (getters) |*t| {
93 *t = try std.os.spawnThread(&context, startGets);91 t.* = try std.os.spawnThread(&context, startGets);
94 }92 }
9593
96 for (putters) |t| t.wait();94 for (putters) |t|
95 t.wait();
97 _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);96 _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
98 for (getters) |t| t.wait();97 for (getters) |t|
98 t.wait();
9999
100 std.debug.assert(context.put_sum == context.get_sum);100 std.debug.assert(context.put_sum == context.get_sum);
101 std.debug.assert(context.get_count == puts_per_thread * put_thread_count);101 std.debug.assert(context.get_count == puts_per_thread * put_thread_count);
std/base64.zig+47-71
...@@ -41,12 +41,10 @@ pub const Base64Encoder = struct {...@@ -41,12 +41,10 @@ pub const Base64Encoder = struct {
41 dest[out_index] = encoder.alphabet_chars[(source[i] >> 2) & 0x3f];41 dest[out_index] = encoder.alphabet_chars[(source[i] >> 2) & 0x3f];
42 out_index += 1;42 out_index += 1;
4343
44 dest[out_index] = encoder.alphabet_chars[((source[i] & 0x3) << 4) |44 dest[out_index] = encoder.alphabet_chars[((source[i] & 0x3) << 4) | ((source[i + 1] & 0xf0) >> 4)];
45 ((source[i + 1] & 0xf0) >> 4)];
46 out_index += 1;45 out_index += 1;
4746
48 dest[out_index] = encoder.alphabet_chars[((source[i + 1] & 0xf) << 2) |47 dest[out_index] = encoder.alphabet_chars[((source[i + 1] & 0xf) << 2) | ((source[i + 2] & 0xc0) >> 6)];
49 ((source[i + 2] & 0xc0) >> 6)];
50 out_index += 1;48 out_index += 1;
5149
52 dest[out_index] = encoder.alphabet_chars[source[i + 2] & 0x3f];50 dest[out_index] = encoder.alphabet_chars[source[i + 2] & 0x3f];
...@@ -64,8 +62,7 @@ pub const Base64Encoder = struct {...@@ -64,8 +62,7 @@ pub const Base64Encoder = struct {
64 dest[out_index] = encoder.pad_char;62 dest[out_index] = encoder.pad_char;
65 out_index += 1;63 out_index += 1;
66 } else {64 } else {
67 dest[out_index] = encoder.alphabet_chars[((source[i] & 0x3) << 4) |65 dest[out_index] = encoder.alphabet_chars[((source[i] & 0x3) << 4) | ((source[i + 1] & 0xf0) >> 4)];
68 ((source[i + 1] & 0xf0) >> 4)];
69 out_index += 1;66 out_index += 1;
7067
71 dest[out_index] = encoder.alphabet_chars[(source[i + 1] & 0xf) << 2];68 dest[out_index] = encoder.alphabet_chars[(source[i + 1] & 0xf) << 2];
...@@ -84,6 +81,7 @@ pub const Base64Decoder = struct {...@@ -84,6 +81,7 @@ pub const Base64Decoder = struct {
84 /// e.g. 'A' => 0.81 /// e.g. 'A' => 0.
85 /// undefined for any value not in the 64 alphabet chars.82 /// undefined for any value not in the 64 alphabet chars.
86 char_to_index: [256]u8,83 char_to_index: [256]u8,
84
87 /// true only for the 64 chars in the alphabet, not the pad char.85 /// true only for the 64 chars in the alphabet, not the pad char.
88 char_in_alphabet: [256]bool,86 char_in_alphabet: [256]bool,
89 pad_char: u8,87 pad_char: u8,
...@@ -131,26 +129,20 @@ pub const Base64Decoder = struct {...@@ -131,26 +129,20 @@ pub const Base64Decoder = struct {
131 // common case129 // common case
132 if (!decoder.char_in_alphabet[source[src_cursor + 2]]) return error.InvalidCharacter;130 if (!decoder.char_in_alphabet[source[src_cursor + 2]]) return error.InvalidCharacter;
133 if (!decoder.char_in_alphabet[source[src_cursor + 3]]) return error.InvalidCharacter;131 if (!decoder.char_in_alphabet[source[src_cursor + 3]]) return error.InvalidCharacter;
134 dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 |132 dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 | decoder.char_to_index[source[src_cursor + 1]] >> 4;
135 decoder.char_to_index[source[src_cursor + 1]] >> 4;133 dest[dest_cursor + 1] = decoder.char_to_index[source[src_cursor + 1]] << 4 | decoder.char_to_index[source[src_cursor + 2]] >> 2;
136 dest[dest_cursor + 1] = decoder.char_to_index[source[src_cursor + 1]] << 4 |134 dest[dest_cursor + 2] = decoder.char_to_index[source[src_cursor + 2]] << 6 | decoder.char_to_index[source[src_cursor + 3]];
137 decoder.char_to_index[source[src_cursor + 2]] >> 2;
138 dest[dest_cursor + 2] = decoder.char_to_index[source[src_cursor + 2]] << 6 |
139 decoder.char_to_index[source[src_cursor + 3]];
140 dest_cursor += 3;135 dest_cursor += 3;
141 } else if (source[src_cursor + 2] != decoder.pad_char) {136 } else if (source[src_cursor + 2] != decoder.pad_char) {
142 // one pad char137 // one pad char
143 if (!decoder.char_in_alphabet[source[src_cursor + 2]]) return error.InvalidCharacter;138 if (!decoder.char_in_alphabet[source[src_cursor + 2]]) return error.InvalidCharacter;
144 dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 |139 dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 | decoder.char_to_index[source[src_cursor + 1]] >> 4;
145 decoder.char_to_index[source[src_cursor + 1]] >> 4;140 dest[dest_cursor + 1] = decoder.char_to_index[source[src_cursor + 1]] << 4 | decoder.char_to_index[source[src_cursor + 2]] >> 2;
146 dest[dest_cursor + 1] = decoder.char_to_index[source[src_cursor + 1]] << 4 |
147 decoder.char_to_index[source[src_cursor + 2]] >> 2;
148 if (decoder.char_to_index[source[src_cursor + 2]] << 6 != 0) return error.InvalidPadding;141 if (decoder.char_to_index[source[src_cursor + 2]] << 6 != 0) return error.InvalidPadding;
149 dest_cursor += 2;142 dest_cursor += 2;
150 } else {143 } else {
151 // two pad chars144 // two pad chars
152 dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 |145 dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 | decoder.char_to_index[source[src_cursor + 1]] >> 4;
153 decoder.char_to_index[source[src_cursor + 1]] >> 4;
154 if (decoder.char_to_index[source[src_cursor + 1]] << 4 != 0) return error.InvalidPadding;146 if (decoder.char_to_index[source[src_cursor + 1]] << 4 != 0) return error.InvalidPadding;
155 dest_cursor += 1;147 dest_cursor += 1;
156 }148 }
...@@ -165,7 +157,7 @@ pub const Base64DecoderWithIgnore = struct {...@@ -165,7 +157,7 @@ pub const Base64DecoderWithIgnore = struct {
165 decoder: Base64Decoder,157 decoder: Base64Decoder,
166 char_is_ignored: [256]bool,158 char_is_ignored: [256]bool,
167 pub fn init(alphabet_chars: []const u8, pad_char: u8, ignore_chars: []const u8) Base64DecoderWithIgnore {159 pub fn init(alphabet_chars: []const u8, pad_char: u8, ignore_chars: []const u8) Base64DecoderWithIgnore {
168 var result = Base64DecoderWithIgnore {160 var result = Base64DecoderWithIgnore{
169 .decoder = Base64Decoder.init(alphabet_chars, pad_char),161 .decoder = Base64Decoder.init(alphabet_chars, pad_char),
170 .char_is_ignored = []bool{false} ** 256,162 .char_is_ignored = []bool{false} ** 256,
171 };163 };
...@@ -223,10 +215,12 @@ pub const Base64DecoderWithIgnore = struct {...@@ -223,10 +215,12 @@ pub const Base64DecoderWithIgnore = struct {
223 } else if (decoder_with_ignore.char_is_ignored[c]) {215 } else if (decoder_with_ignore.char_is_ignored[c]) {
224 // we can even ignore chars during the padding216 // we can even ignore chars during the padding
225 continue;217 continue;
226 } else return error.InvalidCharacter;218 } else
219 return error.InvalidCharacter;
227 }220 }
228 break;221 break;
229 } else return error.InvalidCharacter;222 } else
223 return error.InvalidCharacter;
230 }224 }
231225
232 switch (available_chars) {226 switch (available_chars) {
...@@ -234,22 +228,17 @@ pub const Base64DecoderWithIgnore = struct {...@@ -234,22 +228,17 @@ pub const Base64DecoderWithIgnore = struct {
234 // common case228 // common case
235 if (dest_cursor + 3 > dest.len) return error.OutputTooSmall;229 if (dest_cursor + 3 > dest.len) return error.OutputTooSmall;
236 assert(pad_char_count == 0);230 assert(pad_char_count == 0);
237 dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 |231 dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 | decoder.char_to_index[next_4_chars[1]] >> 4;
238 decoder.char_to_index[next_4_chars[1]] >> 4;232 dest[dest_cursor + 1] = decoder.char_to_index[next_4_chars[1]] << 4 | decoder.char_to_index[next_4_chars[2]] >> 2;
239 dest[dest_cursor + 1] = decoder.char_to_index[next_4_chars[1]] << 4 |233 dest[dest_cursor + 2] = decoder.char_to_index[next_4_chars[2]] << 6 | decoder.char_to_index[next_4_chars[3]];
240 decoder.char_to_index[next_4_chars[2]] >> 2;
241 dest[dest_cursor + 2] = decoder.char_to_index[next_4_chars[2]] << 6 |
242 decoder.char_to_index[next_4_chars[3]];
243 dest_cursor += 3;234 dest_cursor += 3;
244 continue;235 continue;
245 },236 },
246 3 => {237 3 => {
247 if (dest_cursor + 2 > dest.len) return error.OutputTooSmall;238 if (dest_cursor + 2 > dest.len) return error.OutputTooSmall;
248 if (pad_char_count != 1) return error.InvalidPadding;239 if (pad_char_count != 1) return error.InvalidPadding;
249 dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 |240 dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 | decoder.char_to_index[next_4_chars[1]] >> 4;
250 decoder.char_to_index[next_4_chars[1]] >> 4;241 dest[dest_cursor + 1] = decoder.char_to_index[next_4_chars[1]] << 4 | decoder.char_to_index[next_4_chars[2]] >> 2;
251 dest[dest_cursor + 1] = decoder.char_to_index[next_4_chars[1]] << 4 |
252 decoder.char_to_index[next_4_chars[2]] >> 2;
253 if (decoder.char_to_index[next_4_chars[2]] << 6 != 0) return error.InvalidPadding;242 if (decoder.char_to_index[next_4_chars[2]] << 6 != 0) return error.InvalidPadding;
254 dest_cursor += 2;243 dest_cursor += 2;
255 break;244 break;
...@@ -257,8 +246,7 @@ pub const Base64DecoderWithIgnore = struct {...@@ -257,8 +246,7 @@ pub const Base64DecoderWithIgnore = struct {
257 2 => {246 2 => {
258 if (dest_cursor + 1 > dest.len) return error.OutputTooSmall;247 if (dest_cursor + 1 > dest.len) return error.OutputTooSmall;
259 if (pad_char_count != 2) return error.InvalidPadding;248 if (pad_char_count != 2) return error.InvalidPadding;
260 dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 |249 dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 | decoder.char_to_index[next_4_chars[1]] >> 4;
261 decoder.char_to_index[next_4_chars[1]] >> 4;
262 if (decoder.char_to_index[next_4_chars[1]] << 4 != 0) return error.InvalidPadding;250 if (decoder.char_to_index[next_4_chars[1]] << 4 != 0) return error.InvalidPadding;
263 dest_cursor += 1;251 dest_cursor += 1;
264 break;252 break;
...@@ -280,7 +268,6 @@ pub const Base64DecoderWithIgnore = struct {...@@ -280,7 +268,6 @@ pub const Base64DecoderWithIgnore = struct {
280 }268 }
281};269};
282270
283
284pub const standard_decoder_unsafe = Base64DecoderUnsafe.init(standard_alphabet_chars, standard_pad_char);271pub const standard_decoder_unsafe = Base64DecoderUnsafe.init(standard_alphabet_chars, standard_pad_char);
285272
286pub const Base64DecoderUnsafe = struct {273pub const Base64DecoderUnsafe = struct {
...@@ -291,7 +278,7 @@ pub const Base64DecoderUnsafe = struct {...@@ -291,7 +278,7 @@ pub const Base64DecoderUnsafe = struct {
291278
292 pub fn init(alphabet_chars: []const u8, pad_char: u8) Base64DecoderUnsafe {279 pub fn init(alphabet_chars: []const u8, pad_char: u8) Base64DecoderUnsafe {
293 assert(alphabet_chars.len == 64);280 assert(alphabet_chars.len == 64);
294 var result = Base64DecoderUnsafe {281 var result = Base64DecoderUnsafe{
295 .char_to_index = undefined,282 .char_to_index = undefined,
296 .pad_char = pad_char,283 .pad_char = pad_char,
297 };284 };
...@@ -321,16 +308,13 @@ pub const Base64DecoderUnsafe = struct {...@@ -321,16 +308,13 @@ pub const Base64DecoderUnsafe = struct {
321 }308 }
322309
323 while (in_buf_len > 4) {310 while (in_buf_len > 4) {
324 dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 |311 dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 | decoder.char_to_index[source[src_index + 1]] >> 4;
325 decoder.char_to_index[source[src_index + 1]] >> 4;
326 dest_index += 1;312 dest_index += 1;
327313
328 dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 |314 dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 | decoder.char_to_index[source[src_index + 2]] >> 2;
329 decoder.char_to_index[source[src_index + 2]] >> 2;
330 dest_index += 1;315 dest_index += 1;
331316
332 dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 |317 dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 | decoder.char_to_index[source[src_index + 3]];
333 decoder.char_to_index[source[src_index + 3]];
334 dest_index += 1;318 dest_index += 1;
335319
336 src_index += 4;320 src_index += 4;
...@@ -338,18 +322,15 @@ pub const Base64DecoderUnsafe = struct {...@@ -338,18 +322,15 @@ pub const Base64DecoderUnsafe = struct {
338 }322 }
339323
340 if (in_buf_len > 1) {324 if (in_buf_len > 1) {
341 dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 |325 dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 | decoder.char_to_index[source[src_index + 1]] >> 4;
342 decoder.char_to_index[source[src_index + 1]] >> 4;
343 dest_index += 1;326 dest_index += 1;
344 }327 }
345 if (in_buf_len > 2) {328 if (in_buf_len > 2) {
346 dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 |329 dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 | decoder.char_to_index[source[src_index + 2]] >> 2;
347 decoder.char_to_index[source[src_index + 2]] >> 2;
348 dest_index += 1;330 dest_index += 1;
349 }331 }
350 if (in_buf_len > 3) {332 if (in_buf_len > 3) {
351 dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 |333 dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 | decoder.char_to_index[source[src_index + 3]];
352 decoder.char_to_index[source[src_index + 3]];
353 dest_index += 1;334 dest_index += 1;
354 }335 }
355 }336 }
...@@ -367,7 +348,6 @@ fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) usize {...@@ -367,7 +348,6 @@ fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) usize {
367 return result;348 return result;
368}349}
369350
370
371test "base64" {351test "base64" {
372 @setEvalBranchQuota(8000);352 @setEvalBranchQuota(8000);
373 testBase64() catch unreachable;353 testBase64() catch unreachable;
...@@ -375,26 +355,26 @@ test "base64" {...@@ -375,26 +355,26 @@ test "base64" {
375}355}
376356
377fn testBase64() !void {357fn testBase64() !void {
378 try testAllApis("", "");358 try testAllApis("", "");
379 try testAllApis("f", "Zg==");359 try testAllApis("f", "Zg==");
380 try testAllApis("fo", "Zm8=");360 try testAllApis("fo", "Zm8=");
381 try testAllApis("foo", "Zm9v");361 try testAllApis("foo", "Zm9v");
382 try testAllApis("foob", "Zm9vYg==");362 try testAllApis("foob", "Zm9vYg==");
383 try testAllApis("fooba", "Zm9vYmE=");363 try testAllApis("fooba", "Zm9vYmE=");
384 try testAllApis("foobar", "Zm9vYmFy");364 try testAllApis("foobar", "Zm9vYmFy");
385365
386 try testDecodeIgnoreSpace("", " ");366 try testDecodeIgnoreSpace("", " ");
387 try testDecodeIgnoreSpace("f", "Z g= =");367 try testDecodeIgnoreSpace("f", "Z g= =");
388 try testDecodeIgnoreSpace("fo", " Zm8=");368 try testDecodeIgnoreSpace("fo", " Zm8=");
389 try testDecodeIgnoreSpace("foo", "Zm9v ");369 try testDecodeIgnoreSpace("foo", "Zm9v ");
390 try testDecodeIgnoreSpace("foob", "Zm9vYg = = ");370 try testDecodeIgnoreSpace("foob", "Zm9vYg = = ");
391 try testDecodeIgnoreSpace("fooba", "Zm9v YmE=");371 try testDecodeIgnoreSpace("fooba", "Zm9v YmE=");
392 try testDecodeIgnoreSpace("foobar", " Z m 9 v Y m F y ");372 try testDecodeIgnoreSpace("foobar", " Z m 9 v Y m F y ");
393373
394 // test getting some api errors374 // test getting some api errors
395 try testError("A", error.InvalidPadding);375 try testError("A", error.InvalidPadding);
396 try testError("AA", error.InvalidPadding);376 try testError("AA", error.InvalidPadding);
397 try testError("AAA", error.InvalidPadding);377 try testError("AAA", error.InvalidPadding);
398 try testError("A..A", error.InvalidCharacter);378 try testError("A..A", error.InvalidCharacter);
399 try testError("AA=A", error.InvalidCharacter);379 try testError("AA=A", error.InvalidCharacter);
400 try testError("AA/=", error.InvalidPadding);380 try testError("AA/=", error.InvalidPadding);
...@@ -427,8 +407,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void...@@ -427,8 +407,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void
427407
428 // Base64DecoderWithIgnore408 // Base64DecoderWithIgnore
429 {409 {
430 const standard_decoder_ignore_nothing = Base64DecoderWithIgnore.init(410 const standard_decoder_ignore_nothing = Base64DecoderWithIgnore.init(standard_alphabet_chars, standard_pad_char, "");
431 standard_alphabet_chars, standard_pad_char, "");
432 var buffer: [0x100]u8 = undefined;411 var buffer: [0x100]u8 = undefined;
433 var decoded = buffer[0..Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)];412 var decoded = buffer[0..Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)];
434 var written = try standard_decoder_ignore_nothing.decode(decoded, expected_encoded);413 var written = try standard_decoder_ignore_nothing.decode(decoded, expected_encoded);
...@@ -446,8 +425,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void...@@ -446,8 +425,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void
446}425}
447426
448fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) !void {427fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) !void {
449 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(428 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(standard_alphabet_chars, standard_pad_char, " ");
450 standard_alphabet_chars, standard_pad_char, " ");
451 var buffer: [0x100]u8 = undefined;429 var buffer: [0x100]u8 = undefined;
452 var decoded = buffer[0..Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)];430 var decoded = buffer[0..Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)];
453 var written = try standard_decoder_ignore_space.decode(decoded, encoded);431 var written = try standard_decoder_ignore_space.decode(decoded, encoded);
...@@ -455,8 +433,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) !voi...@@ -455,8 +433,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) !voi
455}433}
456434
457fn testError(encoded: []const u8, expected_err: error) !void {435fn testError(encoded: []const u8, expected_err: error) !void {
458 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(436 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(standard_alphabet_chars, standard_pad_char, " ");
459 standard_alphabet_chars, standard_pad_char, " ");
460 var buffer: [0x100]u8 = undefined;437 var buffer: [0x100]u8 = undefined;
461 if (standard_decoder.calcSize(encoded)) |decoded_size| {438 if (standard_decoder.calcSize(encoded)) |decoded_size| {
462 var decoded = buffer[0..decoded_size];439 var decoded = buffer[0..decoded_size];
...@@ -471,8 +448,7 @@ fn testError(encoded: []const u8, expected_err: error) !void {...@@ -471,8 +448,7 @@ fn testError(encoded: []const u8, expected_err: error) !void {
471}448}
472449
473fn testOutputTooSmallError(encoded: []const u8) !void {450fn testOutputTooSmallError(encoded: []const u8) !void {
474 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(451 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(standard_alphabet_chars, standard_pad_char, " ");
475 standard_alphabet_chars, standard_pad_char, " ");
476 var buffer: [0x100]u8 = undefined;452 var buffer: [0x100]u8 = undefined;
477 var decoded = buffer[0..calcDecodedSizeExactUnsafe(encoded, standard_pad_char) - 1];453 var decoded = buffer[0..calcDecodedSizeExactUnsafe(encoded, standard_pad_char) - 1];
478 if (standard_decoder_ignore_space.decode(decoded, encoded)) |_| {454 if (standard_decoder_ignore_space.decode(decoded, encoded)) |_| {
std/buf_map.zig+1-3
...@@ -12,9 +12,7 @@ pub const BufMap = struct {...@@ -12,9 +12,7 @@ pub const BufMap = struct {
12 const BufMapHashMap = HashMap([]const u8, []const u8, mem.hash_slice_u8, mem.eql_slice_u8);12 const BufMapHashMap = HashMap([]const u8, []const u8, mem.hash_slice_u8, mem.eql_slice_u8);
1313
14 pub fn init(allocator: &Allocator) BufMap {14 pub fn init(allocator: &Allocator) BufMap {
15 var self = BufMap {15 var self = BufMap{ .hash_map = BufMapHashMap.init(allocator) };
16 .hash_map = BufMapHashMap.init(allocator),
17 };
18 return self;16 return self;
19 }17 }
2018
std/buf_set.zig+1-3
...@@ -10,9 +10,7 @@ pub const BufSet = struct {...@@ -10,9 +10,7 @@ pub const BufSet = struct {
10 const BufSetHashMap = HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);10 const BufSetHashMap = HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);
1111
12 pub fn init(a: &Allocator) BufSet {12 pub fn init(a: &Allocator) BufSet {
13 var self = BufSet {13 var self = BufSet{ .hash_map = BufSetHashMap.init(a) };
14 .hash_map = BufSetHashMap.init(a),
15 };
16 return self;14 return self;
17 }15 }
1816
std/buffer.zig+3-8
...@@ -31,9 +31,7 @@ pub const Buffer = struct {...@@ -31,9 +31,7 @@ pub const Buffer = struct {
31 /// * ::replaceContentsBuffer31 /// * ::replaceContentsBuffer
32 /// * ::resize32 /// * ::resize
33 pub fn initNull(allocator: &Allocator) Buffer {33 pub fn initNull(allocator: &Allocator) Buffer {
34 return Buffer {34 return Buffer{ .list = ArrayList(u8).init(allocator) };
35 .list = ArrayList(u8).init(allocator),
36 };
37 }35 }
3836
39 /// Must deinitialize with deinit.37 /// Must deinitialize with deinit.
...@@ -45,9 +43,7 @@ pub const Buffer = struct {...@@ -45,9 +43,7 @@ pub const Buffer = struct {
45 /// allocated with `allocator`.43 /// allocated with `allocator`.
46 /// Must deinitialize with deinit.44 /// Must deinitialize with deinit.
47 pub fn fromOwnedSlice(allocator: &Allocator, slice: []u8) Buffer {45 pub fn fromOwnedSlice(allocator: &Allocator, slice: []u8) Buffer {
48 var self = Buffer {46 var self = Buffer{ .list = ArrayList(u8).fromOwnedSlice(allocator, slice) };
49 .list = ArrayList(u8).fromOwnedSlice(allocator, slice),
50 };
51 self.list.append(0);47 self.list.append(0);
52 return self;48 return self;
53 }49 }
...@@ -57,11 +53,10 @@ pub const Buffer = struct {...@@ -57,11 +53,10 @@ pub const Buffer = struct {
57 pub fn toOwnedSlice(self: &Buffer) []u8 {53 pub fn toOwnedSlice(self: &Buffer) []u8 {
58 const allocator = self.list.allocator;54 const allocator = self.list.allocator;
59 const result = allocator.shrink(u8, self.list.items, self.len());55 const result = allocator.shrink(u8, self.list.items, self.len());
60 *self = initNull(allocator);56 self.* = initNull(allocator);
61 return result;57 return result;
62 }58 }
6359
64
65 pub fn deinit(self: &Buffer) void {60 pub fn deinit(self: &Buffer) void {
66 self.list.deinit();61 self.list.deinit();
67 }62 }
std/build.zig+78-130
...@@ -82,10 +82,8 @@ pub const Builder = struct {...@@ -82,10 +82,8 @@ pub const Builder = struct {
82 description: []const u8,82 description: []const u8,
83 };83 };
8484
85 pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8,85 pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8, cache_root: []const u8) Builder {
86 cache_root: []const u8) Builder86 var self = Builder{
87 {
88 var self = Builder {
89 .zig_exe = zig_exe,87 .zig_exe = zig_exe,
90 .build_root = build_root,88 .build_root = build_root,
91 .cache_root = os.path.relative(allocator, build_root, cache_root) catch unreachable,89 .cache_root = os.path.relative(allocator, build_root, cache_root) catch unreachable,
...@@ -112,12 +110,12 @@ pub const Builder = struct {...@@ -112,12 +110,12 @@ pub const Builder = struct {
112 .lib_dir = undefined,110 .lib_dir = undefined,
113 .exe_dir = undefined,111 .exe_dir = undefined,
114 .installed_files = ArrayList([]const u8).init(allocator),112 .installed_files = ArrayList([]const u8).init(allocator),
115 .uninstall_tls = TopLevelStep {113 .uninstall_tls = TopLevelStep{
116 .step = Step.init("uninstall", allocator, makeUninstall),114 .step = Step.init("uninstall", allocator, makeUninstall),
117 .description = "Remove build artifacts from prefix path",115 .description = "Remove build artifacts from prefix path",
118 },116 },
119 .have_uninstall_step = false,117 .have_uninstall_step = false,
120 .install_tls = TopLevelStep {118 .install_tls = TopLevelStep{
121 .step = Step.initNoOp("install", allocator),119 .step = Step.initNoOp("install", allocator),
122 .description = "Copy build artifacts to prefix path",120 .description = "Copy build artifacts to prefix path",
123 },121 },
...@@ -151,9 +149,7 @@ pub const Builder = struct {...@@ -151,9 +149,7 @@ pub const Builder = struct {
151 return LibExeObjStep.createObject(self, name, root_src);149 return LibExeObjStep.createObject(self, name, root_src);
152 }150 }
153151
154 pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8,152 pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8, ver: &const Version) &LibExeObjStep {
155 ver: &const Version) &LibExeObjStep
156 {
157 return LibExeObjStep.createSharedLibrary(self, name, root_src, ver);153 return LibExeObjStep.createSharedLibrary(self, name, root_src, ver);
158 }154 }
159155
...@@ -163,7 +159,7 @@ pub const Builder = struct {...@@ -163,7 +159,7 @@ pub const Builder = struct {
163159
164 pub fn addTest(self: &Builder, root_src: []const u8) &TestStep {160 pub fn addTest(self: &Builder, root_src: []const u8) &TestStep {
165 const test_step = self.allocator.create(TestStep) catch unreachable;161 const test_step = self.allocator.create(TestStep) catch unreachable;
166 *test_step = TestStep.init(self, root_src);162 test_step.* = TestStep.init(self, root_src);
167 return test_step;163 return test_step;
168 }164 }
169165
...@@ -190,33 +186,31 @@ pub const Builder = struct {...@@ -190,33 +186,31 @@ pub const Builder = struct {
190 }186 }
191187
192 /// ::argv is copied.188 /// ::argv is copied.
193 pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,189 pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap, argv: []const []const u8) &CommandStep {
194 argv: []const []const u8) &CommandStep
195 {
196 return CommandStep.create(self, cwd, env_map, argv);190 return CommandStep.create(self, cwd, env_map, argv);
197 }191 }
198192
199 pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) &WriteFileStep {193 pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) &WriteFileStep {
200 const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;194 const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
201 *write_file_step = WriteFileStep.init(self, file_path, data);195 write_file_step.* = WriteFileStep.init(self, file_path, data);
202 return write_file_step;196 return write_file_step;
203 }197 }
204198
205 pub fn addLog(self: &Builder, comptime format: []const u8, args: ...) &LogStep {199 pub fn addLog(self: &Builder, comptime format: []const u8, args: ...) &LogStep {
206 const data = self.fmt(format, args);200 const data = self.fmt(format, args);
207 const log_step = self.allocator.create(LogStep) catch unreachable;201 const log_step = self.allocator.create(LogStep) catch unreachable;
208 *log_step = LogStep.init(self, data);202 log_step.* = LogStep.init(self, data);
209 return log_step;203 return log_step;
210 }204 }
211205
212 pub fn addRemoveDirTree(self: &Builder, dir_path: []const u8) &RemoveDirStep {206 pub fn addRemoveDirTree(self: &Builder, dir_path: []const u8) &RemoveDirStep {
213 const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;207 const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
214 *remove_dir_step = RemoveDirStep.init(self, dir_path);208 remove_dir_step.* = RemoveDirStep.init(self, dir_path);
215 return remove_dir_step;209 return remove_dir_step;
216 }210 }
217211
218 pub fn version(self: &const Builder, major: u32, minor: u32, patch: u32) Version {212 pub fn version(self: &const Builder, major: u32, minor: u32, patch: u32) Version {
219 return Version {213 return Version{
220 .major = major,214 .major = major,
221 .minor = minor,215 .minor = minor,
222 .patch = patch,216 .patch = patch,
...@@ -254,8 +248,7 @@ pub const Builder = struct {...@@ -254,8 +248,7 @@ pub const Builder = struct {
254 }248 }
255249
256 pub fn getInstallStep(self: &Builder) &Step {250 pub fn getInstallStep(self: &Builder) &Step {
257 if (self.have_install_step)251 if (self.have_install_step) return &self.install_tls.step;
258 return &self.install_tls.step;
259252
260 self.top_level_steps.append(&self.install_tls) catch unreachable;253 self.top_level_steps.append(&self.install_tls) catch unreachable;
261 self.have_install_step = true;254 self.have_install_step = true;
...@@ -263,8 +256,7 @@ pub const Builder = struct {...@@ -263,8 +256,7 @@ pub const Builder = struct {
263 }256 }
264257
265 pub fn getUninstallStep(self: &Builder) &Step {258 pub fn getUninstallStep(self: &Builder) &Step {
266 if (self.have_uninstall_step)259 if (self.have_uninstall_step) return &self.uninstall_tls.step;
267 return &self.uninstall_tls.step;
268260
269 self.top_level_steps.append(&self.uninstall_tls) catch unreachable;261 self.top_level_steps.append(&self.uninstall_tls) catch unreachable;
270 self.have_uninstall_step = true;262 self.have_uninstall_step = true;
...@@ -360,7 +352,7 @@ pub const Builder = struct {...@@ -360,7 +352,7 @@ pub const Builder = struct {
360352
361 pub fn option(self: &Builder, comptime T: type, name: []const u8, description: []const u8) ?T {353 pub fn option(self: &Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
362 const type_id = comptime typeToEnum(T);354 const type_id = comptime typeToEnum(T);
363 const available_option = AvailableOption {355 const available_option = AvailableOption{
364 .name = name,356 .name = name,
365 .type_id = type_id,357 .type_id = type_id,
366 .description = description,358 .description = description,
...@@ -413,7 +405,7 @@ pub const Builder = struct {...@@ -413,7 +405,7 @@ pub const Builder = struct {
413405
414 pub fn step(self: &Builder, name: []const u8, description: []const u8) &Step {406 pub fn step(self: &Builder, name: []const u8, description: []const u8) &Step {
415 const step_info = self.allocator.create(TopLevelStep) catch unreachable;407 const step_info = self.allocator.create(TopLevelStep) catch unreachable;
416 *step_info = TopLevelStep {408 step_info.* = TopLevelStep{
417 .step = Step.initNoOp(name, self.allocator),409 .step = Step.initNoOp(name, self.allocator),
418 .description = description,410 .description = description,
419 };411 };
...@@ -428,15 +420,7 @@ pub const Builder = struct {...@@ -428,15 +420,7 @@ pub const Builder = struct {
428 const release_fast = self.option(bool, "release-fast", "optimizations on and safety off") ?? false;420 const release_fast = self.option(bool, "release-fast", "optimizations on and safety off") ?? false;
429 const release_small = self.option(bool, "release-small", "size optimizations on and safety off") ?? false;421 const release_small = self.option(bool, "release-small", "size optimizations on and safety off") ?? false;
430422
431 const mode = if (release_safe and !release_fast and !release_small)423 const mode = if (release_safe and !release_fast and !release_small) builtin.Mode.ReleaseSafe else if (release_fast and !release_safe and !release_small) builtin.Mode.ReleaseFast else if (release_small and !release_fast and !release_safe) builtin.Mode.ReleaseSmall else if (!release_fast and !release_safe and !release_small) builtin.Mode.Debug else x: {
432 builtin.Mode.ReleaseSafe
433 else if (release_fast and !release_safe and !release_small)
434 builtin.Mode.ReleaseFast
435 else if (release_small and !release_fast and !release_safe)
436 builtin.Mode.ReleaseSmall
437 else if (!release_fast and !release_safe and !release_small)
438 builtin.Mode.Debug
439 else x: {
440 warn("Multiple release modes (of -Drelease-safe, -Drelease-fast and -Drelease-small)");424 warn("Multiple release modes (of -Drelease-safe, -Drelease-fast and -Drelease-small)");
441 self.markInvalidUserInput();425 self.markInvalidUserInput();
442 break :x builtin.Mode.Debug;426 break :x builtin.Mode.Debug;
...@@ -446,9 +430,9 @@ pub const Builder = struct {...@@ -446,9 +430,9 @@ pub const Builder = struct {
446 }430 }
447431
448 pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) bool {432 pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) bool {
449 if (self.user_input_options.put(name, UserInputOption {433 if (self.user_input_options.put(name, UserInputOption{
450 .name = name,434 .name = name,
451 .value = UserValue { .Scalar = value },435 .value = UserValue{ .Scalar = value },
452 .used = false,436 .used = false,
453 }) catch unreachable) |*prev_value| {437 }) catch unreachable) |*prev_value| {
454 // option already exists438 // option already exists
...@@ -458,18 +442,18 @@ pub const Builder = struct {...@@ -458,18 +442,18 @@ pub const Builder = struct {
458 var list = ArrayList([]const u8).init(self.allocator);442 var list = ArrayList([]const u8).init(self.allocator);
459 list.append(s) catch unreachable;443 list.append(s) catch unreachable;
460 list.append(value) catch unreachable;444 list.append(value) catch unreachable;
461 _ = self.user_input_options.put(name, UserInputOption {445 _ = self.user_input_options.put(name, UserInputOption{
462 .name = name,446 .name = name,
463 .value = UserValue { .List = list },447 .value = UserValue{ .List = list },
464 .used = false,448 .used = false,
465 }) catch unreachable;449 }) catch unreachable;
466 },450 },
467 UserValue.List => |*list| {451 UserValue.List => |*list| {
468 // append to the list452 // append to the list
469 list.append(value) catch unreachable;453 list.append(value) catch unreachable;
470 _ = self.user_input_options.put(name, UserInputOption {454 _ = self.user_input_options.put(name, UserInputOption{
471 .name = name,455 .name = name,
472 .value = UserValue { .List = *list },456 .value = UserValue{ .List = list.* },
473 .used = false,457 .used = false,
474 }) catch unreachable;458 }) catch unreachable;
475 },459 },
...@@ -483,9 +467,9 @@ pub const Builder = struct {...@@ -483,9 +467,9 @@ pub const Builder = struct {
483 }467 }
484468
485 pub fn addUserInputFlag(self: &Builder, name: []const u8) bool {469 pub fn addUserInputFlag(self: &Builder, name: []const u8) bool {
486 if (self.user_input_options.put(name, UserInputOption {470 if (self.user_input_options.put(name, UserInputOption{
487 .name = name,471 .name = name,
488 .value = UserValue {.Flag = {} },472 .value = UserValue{ .Flag = {} },
489 .used = false,473 .used = false,
490 }) catch unreachable) |*prev_value| {474 }) catch unreachable) |*prev_value| {
491 switch (prev_value.value) {475 switch (prev_value.value) {
...@@ -556,9 +540,7 @@ pub const Builder = struct {...@@ -556,9 +540,7 @@ pub const Builder = struct {
556 warn("\n");540 warn("\n");
557 }541 }
558542
559 fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,543 fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap, argv: []const []const u8) !void {
560 argv: []const []const u8) !void
561 {
562 if (self.verbose) {544 if (self.verbose) {
563 printCmd(cwd, argv);545 printCmd(cwd, argv);
564 }546 }
...@@ -617,7 +599,7 @@ pub const Builder = struct {...@@ -617,7 +599,7 @@ pub const Builder = struct {
617 self.pushInstalledFile(full_dest_path);599 self.pushInstalledFile(full_dest_path);
618600
619 const install_step = self.allocator.create(InstallFileStep) catch unreachable;601 const install_step = self.allocator.create(InstallFileStep) catch unreachable;
620 *install_step = InstallFileStep.init(self, src_path, full_dest_path);602 install_step.* = InstallFileStep.init(self, src_path, full_dest_path);
621 return install_step;603 return install_step;
622 }604 }
623605
...@@ -659,25 +641,19 @@ pub const Builder = struct {...@@ -659,25 +641,19 @@ pub const Builder = struct {
659 if (builtin.environ == builtin.Environ.msvc) {641 if (builtin.environ == builtin.Environ.msvc) {
660 return "cl.exe";642 return "cl.exe";
661 } else {643 } else {
662 return os.getEnvVarOwned(self.allocator, "CC") catch |err| 644 return os.getEnvVarOwned(self.allocator, "CC") catch |err| if (err == error.EnvironmentVariableNotFound) ([]const u8)("cc") else debug.panic("Unable to get environment variable: {}", err);
663 if (err == error.EnvironmentVariableNotFound)
664 ([]const u8)("cc")
665 else
666 debug.panic("Unable to get environment variable: {}", err)
667 ;
668 }645 }
669 }646 }
670647
671 pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 {648 pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 {
672 // TODO report error for ambiguous situations649 // TODO report error for ambiguous situations
673 const exe_extension = (Target { .Native = {}}).exeFileExt();650 const exe_extension = (Target{ .Native = {} }).exeFileExt();
674 for (self.search_prefixes.toSliceConst()) |search_prefix| {651 for (self.search_prefixes.toSliceConst()) |search_prefix| {
675 for (names) |name| {652 for (names) |name| {
676 if (os.path.isAbsolute(name)) {653 if (os.path.isAbsolute(name)) {
677 return name;654 return name;
678 }655 }
679 const full_path = try os.path.join(self.allocator, search_prefix, "bin",656 const full_path = try os.path.join(self.allocator, search_prefix, "bin", self.fmt("{}{}", name, exe_extension));
680 self.fmt("{}{}", name, exe_extension));
681 if (os.path.real(self.allocator, full_path)) |real_path| {657 if (os.path.real(self.allocator, full_path)) |real_path| {
682 return real_path;658 return real_path;
683 } else |_| {659 } else |_| {
...@@ -761,7 +737,7 @@ pub const Target = union(enum) {...@@ -761,7 +737,7 @@ pub const Target = union(enum) {
761 Cross: CrossTarget,737 Cross: CrossTarget,
762738
763 pub fn oFileExt(self: &const Target) []const u8 {739 pub fn oFileExt(self: &const Target) []const u8 {
764 const environ = switch (*self) {740 const environ = switch (self.*) {
765 Target.Native => builtin.environ,741 Target.Native => builtin.environ,
766 Target.Cross => |t| t.environ,742 Target.Cross => |t| t.environ,
767 };743 };
...@@ -786,7 +762,7 @@ pub const Target = union(enum) {...@@ -786,7 +762,7 @@ pub const Target = union(enum) {
786 }762 }
787763
788 pub fn getOs(self: &const Target) builtin.Os {764 pub fn getOs(self: &const Target) builtin.Os {
789 return switch (*self) {765 return switch (self.*) {
790 Target.Native => builtin.os,766 Target.Native => builtin.os,
791 Target.Cross => |t| t.os,767 Target.Cross => |t| t.os,
792 };768 };
...@@ -860,61 +836,57 @@ pub const LibExeObjStep = struct {...@@ -860,61 +836,57 @@ pub const LibExeObjStep = struct {
860 Obj,836 Obj,
861 };837 };
862838
863 pub fn createSharedLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8,839 pub fn createSharedLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8, ver: &const Version) &LibExeObjStep {
864 ver: &const Version) &LibExeObjStep
865 {
866 const self = builder.allocator.create(LibExeObjStep) catch unreachable;840 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
867 *self = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);841 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
868 return self;842 return self;
869 }843 }
870844
871 pub fn createCSharedLibrary(builder: &Builder, name: []const u8, version: &const Version) &LibExeObjStep {845 pub fn createCSharedLibrary(builder: &Builder, name: []const u8, version: &const Version) &LibExeObjStep {
872 const self = builder.allocator.create(LibExeObjStep) catch unreachable;846 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
873 *self = initC(builder, name, Kind.Lib, version, false);847 self.* = initC(builder, name, Kind.Lib, version, false);
874 return self;848 return self;
875 }849 }
876850
877 pub fn createStaticLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {851 pub fn createStaticLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
878 const self = builder.allocator.create(LibExeObjStep) catch unreachable;852 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
879 *self = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));853 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
880 return self;854 return self;
881 }855 }
882856
883 pub fn createCStaticLibrary(builder: &Builder, name: []const u8) &LibExeObjStep {857 pub fn createCStaticLibrary(builder: &Builder, name: []const u8) &LibExeObjStep {
884 const self = builder.allocator.create(LibExeObjStep) catch unreachable;858 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
885 *self = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);859 self.* = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
886 return self;860 return self;
887 }861 }
888862
889 pub fn createObject(builder: &Builder, name: []const u8, root_src: []const u8) &LibExeObjStep {863 pub fn createObject(builder: &Builder, name: []const u8, root_src: []const u8) &LibExeObjStep {
890 const self = builder.allocator.create(LibExeObjStep) catch unreachable;864 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
891 *self = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));865 self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
892 return self;866 return self;
893 }867 }
894868
895 pub fn createCObject(builder: &Builder, name: []const u8, src: []const u8) &LibExeObjStep {869 pub fn createCObject(builder: &Builder, name: []const u8, src: []const u8) &LibExeObjStep {
896 const self = builder.allocator.create(LibExeObjStep) catch unreachable;870 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
897 *self = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);871 self.* = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
898 self.object_src = src;872 self.object_src = src;
899 return self;873 return self;
900 }874 }
901875
902 pub fn createExecutable(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {876 pub fn createExecutable(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
903 const self = builder.allocator.create(LibExeObjStep) catch unreachable;877 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
904 *self = initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0));878 self.* = initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0));
905 return self;879 return self;
906 }880 }
907881
908 pub fn createCExecutable(builder: &Builder, name: []const u8) &LibExeObjStep {882 pub fn createCExecutable(builder: &Builder, name: []const u8) &LibExeObjStep {
909 const self = builder.allocator.create(LibExeObjStep) catch unreachable;883 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
910 *self = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);884 self.* = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
911 return self;885 return self;
912 }886 }
913887
914 fn initExtraArgs(builder: &Builder, name: []const u8, root_src: ?[]const u8, kind: Kind,888 fn initExtraArgs(builder: &Builder, name: []const u8, root_src: ?[]const u8, kind: Kind, static: bool, ver: &const Version) LibExeObjStep {
915 static: bool, ver: &const Version) LibExeObjStep889 var self = LibExeObjStep{
916 {
917 var self = LibExeObjStep {
918 .strip = false,890 .strip = false,
919 .builder = builder,891 .builder = builder,
920 .verbose_link = false,892 .verbose_link = false,
...@@ -930,7 +902,7 @@ pub const LibExeObjStep = struct {...@@ -930,7 +902,7 @@ pub const LibExeObjStep = struct {
930 .step = Step.init(name, builder.allocator, make),902 .step = Step.init(name, builder.allocator, make),
931 .output_path = null,903 .output_path = null,
932 .output_h_path = null,904 .output_h_path = null,
933 .version = *ver,905 .version = ver.*,
934 .out_filename = undefined,906 .out_filename = undefined,
935 .out_h_filename = builder.fmt("{}.h", name),907 .out_h_filename = builder.fmt("{}.h", name),
936 .major_only_filename = undefined,908 .major_only_filename = undefined,
...@@ -953,11 +925,11 @@ pub const LibExeObjStep = struct {...@@ -953,11 +925,11 @@ pub const LibExeObjStep = struct {
953 }925 }
954926
955 fn initC(builder: &Builder, name: []const u8, kind: Kind, version: &const Version, static: bool) LibExeObjStep {927 fn initC(builder: &Builder, name: []const u8, kind: Kind, version: &const Version, static: bool) LibExeObjStep {
956 var self = LibExeObjStep {928 var self = LibExeObjStep{
957 .builder = builder,929 .builder = builder,
958 .name = name,930 .name = name,
959 .kind = kind,931 .kind = kind,
960 .version = *version,932 .version = version.*,
961 .static = static,933 .static = static,
962 .target = Target.Native,934 .target = Target.Native,
963 .cflags = ArrayList([]const u8).init(builder.allocator),935 .cflags = ArrayList([]const u8).init(builder.allocator),
...@@ -1006,8 +978,7 @@ pub const LibExeObjStep = struct {...@@ -1006,8 +978,7 @@ pub const LibExeObjStep = struct {
1006 } else {978 } else {
1007 switch (self.target.getOs()) {979 switch (self.target.getOs()) {
1008 builtin.Os.ios, builtin.Os.macosx => {980 builtin.Os.ios, builtin.Os.macosx => {
1009 self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib",981 self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", self.name, self.version.major, self.version.minor, self.version.patch);
1010 self.name, self.version.major, self.version.minor, self.version.patch);
1011 self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major);982 self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major);
1012 self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);983 self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
1013 },984 },
...@@ -1015,8 +986,7 @@ pub const LibExeObjStep = struct {...@@ -1015,8 +986,7 @@ pub const LibExeObjStep = struct {
1015 self.out_filename = self.builder.fmt("{}.dll", self.name);986 self.out_filename = self.builder.fmt("{}.dll", self.name);
1016 },987 },
1017 else => {988 else => {
1018 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}",989 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", self.name, self.version.major, self.version.minor, self.version.patch);
1019 self.name, self.version.major, self.version.minor, self.version.patch);
1020 self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);990 self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);
1021 self.name_only_filename = self.builder.fmt("lib{}.so", self.name);991 self.name_only_filename = self.builder.fmt("lib{}.so", self.name);
1022 },992 },
...@@ -1026,15 +996,13 @@ pub const LibExeObjStep = struct {...@@ -1026,15 +996,13 @@ pub const LibExeObjStep = struct {
1026 }996 }
1027 }997 }
1028998
1029 pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os,999 pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os, target_environ: builtin.Environ) void {
1030 target_environ: builtin.Environ) void1000 self.target = Target{
1031 {1001 .Cross = CrossTarget{
1032 self.target = Target {
1033 .Cross = CrossTarget {
1034 .arch = target_arch,1002 .arch = target_arch,
1035 .os = target_os,1003 .os = target_os,
1036 .environ = target_environ,1004 .environ = target_environ,
1037 }1005 },
1038 };1006 };
1039 self.computeOutFileNames();1007 self.computeOutFileNames();
1040 }1008 }
...@@ -1099,10 +1067,7 @@ pub const LibExeObjStep = struct {...@@ -1099,10 +1067,7 @@ pub const LibExeObjStep = struct {
1099 }1067 }
11001068
1101 pub fn getOutputPath(self: &LibExeObjStep) []const u8 {1069 pub fn getOutputPath(self: &LibExeObjStep) []const u8 {
1102 return if (self.output_path) |output_path|1070 return if (self.output_path) |output_path| output_path else os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename) catch unreachable;
1103 output_path
1104 else
1105 os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename) catch unreachable;
1106 }1071 }
11071072
1108 pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) void {1073 pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) void {
...@@ -1115,10 +1080,7 @@ pub const LibExeObjStep = struct {...@@ -1115,10 +1080,7 @@ pub const LibExeObjStep = struct {
1115 }1080 }
11161081
1117 pub fn getOutputHPath(self: &LibExeObjStep) []const u8 {1082 pub fn getOutputHPath(self: &LibExeObjStep) []const u8 {
1118 return if (self.output_h_path) |output_h_path|1083 return if (self.output_h_path) |output_h_path| output_h_path else os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename) catch unreachable;
1119 output_h_path
1120 else
1121 os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename) catch unreachable;
1122 }1084 }
11231085
1124 pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) void {1086 pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) void {
...@@ -1159,7 +1121,7 @@ pub const LibExeObjStep = struct {...@@ -1159,7 +1121,7 @@ pub const LibExeObjStep = struct {
1159 pub fn addPackagePath(self: &LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void {1121 pub fn addPackagePath(self: &LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void {
1160 assert(self.is_zig);1122 assert(self.is_zig);
11611123
1162 self.packages.append(Pkg {1124 self.packages.append(Pkg{
1163 .name = name,1125 .name = name,
1164 .path = pkg_index_path,1126 .path = pkg_index_path,
1165 }) catch unreachable;1127 }) catch unreachable;
...@@ -1343,8 +1305,7 @@ pub const LibExeObjStep = struct {...@@ -1343,8 +1305,7 @@ pub const LibExeObjStep = struct {
1343 try builder.spawnChild(zig_args.toSliceConst());1305 try builder.spawnChild(zig_args.toSliceConst());
13441306
1345 if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) {1307 if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) {
1346 try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,1308 try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, self.name_only_filename);
1347 self.name_only_filename);
1348 }1309 }
1349 }1310 }
13501311
...@@ -1505,8 +1466,7 @@ pub const LibExeObjStep = struct {...@@ -1505,8 +1466,7 @@ pub const LibExeObjStep = struct {
1505 }1466 }
15061467
1507 if (!is_darwin) {1468 if (!is_darwin) {
1508 const rpath_arg = builder.fmt("-Wl,-rpath,{}",1469 const rpath_arg = builder.fmt("-Wl,-rpath,{}", os.path.real(builder.allocator, builder.pathFromRoot(builder.cache_root)) catch unreachable);
1509 os.path.real(builder.allocator, builder.pathFromRoot(builder.cache_root)) catch unreachable);
1510 defer builder.allocator.free(rpath_arg);1470 defer builder.allocator.free(rpath_arg);
1511 cc_args.append(rpath_arg) catch unreachable;1471 cc_args.append(rpath_arg) catch unreachable;
15121472
...@@ -1535,8 +1495,7 @@ pub const LibExeObjStep = struct {...@@ -1535,8 +1495,7 @@ pub const LibExeObjStep = struct {
1535 try builder.spawnChild(cc_args.toSliceConst());1495 try builder.spawnChild(cc_args.toSliceConst());
15361496
1537 if (self.target.wantSharedLibSymLinks()) {1497 if (self.target.wantSharedLibSymLinks()) {
1538 try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,1498 try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, self.name_only_filename);
1539 self.name_only_filename);
1540 }1499 }
1541 }1500 }
1542 },1501 },
...@@ -1581,8 +1540,7 @@ pub const LibExeObjStep = struct {...@@ -1581,8 +1540,7 @@ pub const LibExeObjStep = struct {
1581 cc_args.append("-o") catch unreachable;1540 cc_args.append("-o") catch unreachable;
1582 cc_args.append(output_path) catch unreachable;1541 cc_args.append(output_path) catch unreachable;
15831542
1584 const rpath_arg = builder.fmt("-Wl,-rpath,{}",1543 const rpath_arg = builder.fmt("-Wl,-rpath,{}", os.path.real(builder.allocator, builder.pathFromRoot(builder.cache_root)) catch unreachable);
1585 os.path.real(builder.allocator, builder.pathFromRoot(builder.cache_root)) catch unreachable);
1586 defer builder.allocator.free(rpath_arg);1544 defer builder.allocator.free(rpath_arg);
1587 cc_args.append(rpath_arg) catch unreachable;1545 cc_args.append(rpath_arg) catch unreachable;
15881546
...@@ -1635,7 +1593,7 @@ pub const TestStep = struct {...@@ -1635,7 +1593,7 @@ pub const TestStep = struct {
16351593
1636 pub fn init(builder: &Builder, root_src: []const u8) TestStep {1594 pub fn init(builder: &Builder, root_src: []const u8) TestStep {
1637 const step_name = builder.fmt("test {}", root_src);1595 const step_name = builder.fmt("test {}", root_src);
1638 return TestStep {1596 return TestStep{
1639 .step = Step.init(step_name, builder.allocator, make),1597 .step = Step.init(step_name, builder.allocator, make),
1640 .builder = builder,1598 .builder = builder,
1641 .root_src = root_src,1599 .root_src = root_src,
...@@ -1644,7 +1602,7 @@ pub const TestStep = struct {...@@ -1644,7 +1602,7 @@ pub const TestStep = struct {
1644 .name_prefix = "",1602 .name_prefix = "",
1645 .filter = null,1603 .filter = null,
1646 .link_libs = BufSet.init(builder.allocator),1604 .link_libs = BufSet.init(builder.allocator),
1647 .target = Target { .Native = {} },1605 .target = Target{ .Native = {} },
1648 .exec_cmd_args = null,1606 .exec_cmd_args = null,
1649 .include_dirs = ArrayList([]const u8).init(builder.allocator),1607 .include_dirs = ArrayList([]const u8).init(builder.allocator),
1650 };1608 };
...@@ -1674,15 +1632,13 @@ pub const TestStep = struct {...@@ -1674,15 +1632,13 @@ pub const TestStep = struct {
1674 self.filter = text;1632 self.filter = text;
1675 }1633 }
16761634
1677 pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os,1635 pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os, target_environ: builtin.Environ) void {
1678 target_environ: builtin.Environ) void1636 self.target = Target{
1679 {1637 .Cross = CrossTarget{
1680 self.target = Target {
1681 .Cross = CrossTarget {
1682 .arch = target_arch,1638 .arch = target_arch,
1683 .os = target_os,1639 .os = target_os,
1684 .environ = target_environ,1640 .environ = target_environ,
1685 }1641 },
1686 };1642 };
1687 }1643 }
16881644
...@@ -1789,11 +1745,9 @@ pub const CommandStep = struct {...@@ -1789,11 +1745,9 @@ pub const CommandStep = struct {
1789 env_map: &const BufMap,1745 env_map: &const BufMap,
17901746
1791 /// ::argv is copied.1747 /// ::argv is copied.
1792 pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap,1748 pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap, argv: []const []const u8) &CommandStep {
1793 argv: []const []const u8) &CommandStep
1794 {
1795 const self = builder.allocator.create(CommandStep) catch unreachable;1749 const self = builder.allocator.create(CommandStep) catch unreachable;
1796 *self = CommandStep {1750 self.* = CommandStep{
1797 .builder = builder,1751 .builder = builder,
1798 .step = Step.init(argv[0], builder.allocator, make),1752 .step = Step.init(argv[0], builder.allocator, make),
1799 .argv = builder.allocator.alloc([]u8, argv.len) catch unreachable,1753 .argv = builder.allocator.alloc([]u8, argv.len) catch unreachable,
...@@ -1828,7 +1782,7 @@ const InstallArtifactStep = struct {...@@ -1828,7 +1782,7 @@ const InstallArtifactStep = struct {
1828 LibExeObjStep.Kind.Exe => builder.exe_dir,1782 LibExeObjStep.Kind.Exe => builder.exe_dir,
1829 LibExeObjStep.Kind.Lib => builder.lib_dir,1783 LibExeObjStep.Kind.Lib => builder.lib_dir,
1830 };1784 };
1831 *self = Self {1785 self.* = Self{
1832 .builder = builder,1786 .builder = builder,
1833 .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),1787 .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
1834 .artifact = artifact,1788 .artifact = artifact,
...@@ -1837,10 +1791,8 @@ const InstallArtifactStep = struct {...@@ -1837,10 +1791,8 @@ const InstallArtifactStep = struct {
1837 self.step.dependOn(&artifact.step);1791 self.step.dependOn(&artifact.step);
1838 builder.pushInstalledFile(self.dest_file);1792 builder.pushInstalledFile(self.dest_file);
1839 if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {1793 if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {
1840 builder.pushInstalledFile(os.path.join(builder.allocator, builder.lib_dir,1794 builder.pushInstalledFile(os.path.join(builder.allocator, builder.lib_dir, artifact.major_only_filename) catch unreachable);
1841 artifact.major_only_filename) catch unreachable);1795 builder.pushInstalledFile(os.path.join(builder.allocator, builder.lib_dir, artifact.name_only_filename) catch unreachable);
1842 builder.pushInstalledFile(os.path.join(builder.allocator, builder.lib_dir,
1843 artifact.name_only_filename) catch unreachable);
1844 }1796 }
1845 return self;1797 return self;
1846 }1798 }
...@@ -1859,8 +1811,7 @@ const InstallArtifactStep = struct {...@@ -1859,8 +1811,7 @@ const InstallArtifactStep = struct {
1859 };1811 };
1860 try builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode);1812 try builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode);
1861 if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {1813 if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {
1862 try doAtomicSymLinks(builder.allocator, self.dest_file,1814 try doAtomicSymLinks(builder.allocator, self.dest_file, self.artifact.major_only_filename, self.artifact.name_only_filename);
1863 self.artifact.major_only_filename, self.artifact.name_only_filename);
1864 }1815 }
1865 }1816 }
1866};1817};
...@@ -1872,7 +1823,7 @@ pub const InstallFileStep = struct {...@@ -1872,7 +1823,7 @@ pub const InstallFileStep = struct {
1872 dest_path: []const u8,1823 dest_path: []const u8,
18731824
1874 pub fn init(builder: &Builder, src_path: []const u8, dest_path: []const u8) InstallFileStep {1825 pub fn init(builder: &Builder, src_path: []const u8, dest_path: []const u8) InstallFileStep {
1875 return InstallFileStep {1826 return InstallFileStep{
1876 .builder = builder,1827 .builder = builder,
1877 .step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make),1828 .step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make),
1878 .src_path = src_path,1829 .src_path = src_path,
...@@ -1893,7 +1844,7 @@ pub const WriteFileStep = struct {...@@ -1893,7 +1844,7 @@ pub const WriteFileStep = struct {
1893 data: []const u8,1844 data: []const u8,
18941845
1895 pub fn init(builder: &Builder, file_path: []const u8, data: []const u8) WriteFileStep {1846 pub fn init(builder: &Builder, file_path: []const u8, data: []const u8) WriteFileStep {
1896 return WriteFileStep {1847 return WriteFileStep{
1897 .builder = builder,1848 .builder = builder,
1898 .step = Step.init(builder.fmt("writefile {}", file_path), builder.allocator, make),1849 .step = Step.init(builder.fmt("writefile {}", file_path), builder.allocator, make),
1899 .file_path = file_path,1850 .file_path = file_path,
...@@ -1922,7 +1873,7 @@ pub const LogStep = struct {...@@ -1922,7 +1873,7 @@ pub const LogStep = struct {
1922 data: []const u8,1873 data: []const u8,
19231874
1924 pub fn init(builder: &Builder, data: []const u8) LogStep {1875 pub fn init(builder: &Builder, data: []const u8) LogStep {
1925 return LogStep {1876 return LogStep{
1926 .builder = builder,1877 .builder = builder,
1927 .step = Step.init(builder.fmt("log {}", data), builder.allocator, make),1878 .step = Step.init(builder.fmt("log {}", data), builder.allocator, make),
1928 .data = data,1879 .data = data,
...@@ -1941,7 +1892,7 @@ pub const RemoveDirStep = struct {...@@ -1941,7 +1892,7 @@ pub const RemoveDirStep = struct {
1941 dir_path: []const u8,1892 dir_path: []const u8,
19421893
1943 pub fn init(builder: &Builder, dir_path: []const u8) RemoveDirStep {1894 pub fn init(builder: &Builder, dir_path: []const u8) RemoveDirStep {
1944 return RemoveDirStep {1895 return RemoveDirStep{
1945 .builder = builder,1896 .builder = builder,
1946 .step = Step.init(builder.fmt("RemoveDir {}", dir_path), builder.allocator, make),1897 .step = Step.init(builder.fmt("RemoveDir {}", dir_path), builder.allocator, make),
1947 .dir_path = dir_path,1898 .dir_path = dir_path,
...@@ -1966,8 +1917,8 @@ pub const Step = struct {...@@ -1966,8 +1917,8 @@ pub const Step = struct {
1966 loop_flag: bool,1917 loop_flag: bool,
1967 done_flag: bool,1918 done_flag: bool,
19681919
1969 pub fn init(name: []const u8, allocator: &Allocator, makeFn: fn (&Step)error!void) Step {1920 pub fn init(name: []const u8, allocator: &Allocator, makeFn: fn(&Step) error!void) Step {
1970 return Step {1921 return Step{
1971 .name = name,1922 .name = name,
1972 .makeFn = makeFn,1923 .makeFn = makeFn,
1973 .dependencies = ArrayList(&Step).init(allocator),1924 .dependencies = ArrayList(&Step).init(allocator),
...@@ -1980,8 +1931,7 @@ pub const Step = struct {...@@ -1980,8 +1931,7 @@ pub const Step = struct {
1980 }1931 }
19811932
1982 pub fn make(self: &Step) !void {1933 pub fn make(self: &Step) !void {
1983 if (self.done_flag)1934 if (self.done_flag) return;
1984 return;
19851935
1986 try self.makeFn(self);1936 try self.makeFn(self);
1987 self.done_flag = true;1937 self.done_flag = true;
...@@ -1994,9 +1944,7 @@ pub const Step = struct {...@@ -1994,9 +1944,7 @@ pub const Step = struct {
1994 fn makeNoOp(self: &Step) error!void {}1944 fn makeNoOp(self: &Step) error!void {}
1995};1945};
19961946
1997fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8,1947fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8, filename_name_only: []const u8) !void {
1998 filename_name_only: []const u8) !void
1999{
2000 const out_dir = os.path.dirname(output_path);1948 const out_dir = os.path.dirname(output_path);
2001 const out_basename = os.path.basename(output_path);1949 const out_basename = os.path.basename(output_path);
2002 // sym link for libfoo.so.1 to libfoo.so.1.2.31950 // sym link for libfoo.so.1 to libfoo.so.1.2.3
std/c/darwin.zig+1-1
...@@ -60,7 +60,7 @@ pub const sigset_t = u32;...@@ -60,7 +60,7 @@ pub const sigset_t = u32;
6060
61/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.61/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
62pub const Sigaction = extern struct {62pub const Sigaction = extern struct {
63 handler: extern fn(c_int)void,63 handler: extern fn(c_int) void,
64 sa_mask: sigset_t,64 sa_mask: sigset_t,
65 sa_flags: c_int,65 sa_flags: c_int,
66};66};
std/c/index.zig+4-8
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const Os = builtin.Os;2const Os = builtin.Os;
33
4pub use switch(builtin.os) {4pub 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.macosx, Os.ios => @import("darwin.zig"),7 Os.macosx, Os.ios => @import("darwin.zig"),
...@@ -21,8 +21,7 @@ pub extern "c" fn raise(sig: c_int) c_int;...@@ -21,8 +21,7 @@ pub extern "c" fn raise(sig: c_int) c_int;
21pub extern "c" fn read(fd: c_int, buf: &c_void, nbyte: usize) isize;21pub extern "c" fn read(fd: c_int, buf: &c_void, nbyte: usize) isize;
22pub extern "c" fn stat(noalias path: &const u8, noalias buf: &Stat) c_int;22pub extern "c" fn stat(noalias path: &const u8, noalias buf: &Stat) c_int;
23pub extern "c" fn write(fd: c_int, buf: &const c_void, nbyte: usize) isize;23pub extern "c" fn write(fd: c_int, buf: &const c_void, nbyte: usize) isize;
24pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int,24pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int, fd: c_int, offset: isize) ?&c_void;
25 fd: c_int, offset: isize) ?&c_void;
26pub extern "c" fn munmap(addr: &c_void, len: usize) c_int;25pub extern "c" fn munmap(addr: &c_void, len: usize) c_int;
27pub extern "c" fn unlink(path: &const u8) c_int;26pub extern "c" fn unlink(path: &const u8) c_int;
28pub extern "c" fn getcwd(buf: &u8, size: usize) ?&u8;27pub extern "c" fn getcwd(buf: &u8, size: usize) ?&u8;
...@@ -34,8 +33,7 @@ pub extern "c" fn mkdir(path: &const u8, mode: c_uint) c_int;...@@ -34,8 +33,7 @@ pub extern "c" fn mkdir(path: &const u8, mode: c_uint) c_int;
34pub extern "c" fn symlink(existing: &const u8, new: &const u8) c_int;33pub extern "c" fn symlink(existing: &const u8, new: &const u8) c_int;
35pub extern "c" fn rename(old: &const u8, new: &const u8) c_int;34pub extern "c" fn rename(old: &const u8, new: &const u8) c_int;
36pub extern "c" fn chdir(path: &const u8) c_int;35pub extern "c" fn chdir(path: &const u8) c_int;
37pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8,36pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) c_int;
38 envp: &const ?&const u8) c_int;
39pub extern "c" fn dup(fd: c_int) c_int;37pub extern "c" fn dup(fd: c_int) c_int;
40pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) c_int;38pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) c_int;
41pub extern "c" fn readlink(noalias path: &const u8, noalias buf: &u8, bufsize: usize) isize;39pub extern "c" fn readlink(noalias path: &const u8, noalias buf: &u8, bufsize: usize) isize;
...@@ -54,9 +52,7 @@ pub extern "c" fn realloc(&c_void, usize) ?&c_void;...@@ -54,9 +52,7 @@ pub extern "c" fn realloc(&c_void, usize) ?&c_void;
54pub extern "c" fn free(&c_void) void;52pub extern "c" fn free(&c_void) void;
55pub extern "c" fn posix_memalign(memptr: &&c_void, alignment: usize, size: usize) c_int;53pub extern "c" fn posix_memalign(memptr: &&c_void, alignment: usize, size: usize) c_int;
5654
57pub extern "pthread" fn pthread_create(noalias newthread: &pthread_t,55pub extern "pthread" fn pthread_create(noalias newthread: &pthread_t, noalias attr: ?&const pthread_attr_t, start_routine: extern fn(?&c_void) ?&c_void, noalias arg: ?&c_void) c_int;
58 noalias attr: ?&const pthread_attr_t, start_routine: extern fn(?&c_void) ?&c_void,
59 noalias arg: ?&c_void) c_int;
60pub extern "pthread" fn pthread_attr_init(attr: &pthread_attr_t) c_int;56pub extern "pthread" fn pthread_attr_init(attr: &pthread_attr_t) c_int;
61pub extern "pthread" fn pthread_attr_setstack(attr: &pthread_attr_t, stackaddr: &c_void, stacksize: usize) c_int;57pub extern "pthread" fn pthread_attr_setstack(attr: &pthread_attr_t, stackaddr: &c_void, stacksize: usize) c_int;
62pub extern "pthread" fn pthread_attr_destroy(attr: &pthread_attr_t) c_int;58pub extern "pthread" fn pthread_attr_destroy(attr: &pthread_attr_t) c_int;
std/crypto/blake2.zig+266-241
...@@ -6,11 +6,23 @@ const builtin = @import("builtin");...@@ -6,11 +6,23 @@ const builtin = @import("builtin");
6const htest = @import("test.zig");6const htest = @import("test.zig");
77
8const RoundParam = struct {8const RoundParam = struct {
9 a: usize, b: usize, c: usize, d: usize, x: usize, y: usize,9 a: usize,
10 b: usize,
11 c: usize,
12 d: usize,
13 x: usize,
14 y: usize,
10};15};
1116
12fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam {17fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam {
13 return RoundParam { .a = a, .b = b, .c = c, .d = d, .x = x, .y = y, };18 return RoundParam{
19 .a = a,
20 .b = b,
21 .c = c,
22 .d = d,
23 .x = x,
24 .y = y,
25 };
14}26}
1527
16/////////////////////28/////////////////////
...@@ -19,145 +31,153 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam {...@@ -19,145 +31,153 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam {
19pub const Blake2s224 = Blake2s(224);31pub const Blake2s224 = Blake2s(224);
20pub const Blake2s256 = Blake2s(256);32pub const Blake2s256 = Blake2s(256);
2133
22fn Blake2s(comptime out_len: usize) type { return struct {34fn Blake2s(comptime out_len: usize) type {
23 const Self = this;35 return struct {
24 const block_size = 64;36 const Self = this;
25 const digest_size = out_len / 8;37 const block_size = 64;
38 const digest_size = out_len / 8;
39
40 const iv = [8]u32{
41 0x6A09E667,
42 0xBB67AE85,
43 0x3C6EF372,
44 0xA54FF53A,
45 0x510E527F,
46 0x9B05688C,
47 0x1F83D9AB,
48 0x5BE0CD19,
49 };
2650
27 const iv = [8]u32 {51 const sigma = [10][16]u8{
28 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,52 []const u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
29 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19,53 []const u8{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
30 };54 []const u8{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
55 []const u8{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
56 []const u8{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
57 []const u8{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
58 []const u8{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
59 []const u8{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
60 []const u8{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
61 []const u8{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
62 };
3163
32 const sigma = [10][16]u8 {64 h: [8]u32,
33 []const u8 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },65 t: u64,
34 []const u8 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },66 // Streaming cache
35 []const u8 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },67 buf: [64]u8,
36 []const u8 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },68 buf_len: u8,
37 []const u8 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
38 []const u8 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
39 []const u8 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
40 []const u8 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
41 []const u8 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
42 []const u8 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
43 };
4469
45 h: [8]u32,70 pub fn init() Self {
46 t: u64,71 debug.assert(8 <= out_len and out_len <= 512);
47 // Streaming cache72
48 buf: [64]u8,73 var s: Self = undefined;
49 buf_len: u8,74 s.reset();
5075 return s;
51 pub fn init() Self {
52 debug.assert(8 <= out_len and out_len <= 512);
53
54 var s: Self = undefined;
55 s.reset();
56 return s;
57 }
58
59 pub fn reset(d: &Self) void {
60 mem.copy(u32, d.h[0..], iv[0..]);
61
62 // No key plus default parameters
63 d.h[0] ^= 0x01010000 ^ u32(out_len >> 3);
64 d.t = 0;
65 d.buf_len = 0;
66 }
67
68 pub fn hash(b: []const u8, out: []u8) void {
69 var d = Self.init();
70 d.update(b);
71 d.final(out);
72 }
73
74 pub fn update(d: &Self, b: []const u8) void {
75 var off: usize = 0;
76
77 // Partial buffer exists from previous update. Copy into buffer then hash.
78 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
79 off += 64 - d.buf_len;
80 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
81 d.t += 64;
82 d.round(d.buf[0..], false);
83 d.buf_len = 0;
84 }76 }
8577
86 // Full middle blocks.78 pub fn reset(d: &Self) void {
87 while (off + 64 <= b.len) : (off += 64) {79 mem.copy(u32, d.h[0..], iv[0..]);
88 d.t += 64;80
89 d.round(b[off..off + 64], false);81 // No key plus default parameters
82 d.h[0] ^= 0x01010000 ^ u32(out_len >> 3);
83 d.t = 0;
84 d.buf_len = 0;
90 }85 }
9186
92 // Copy any remainder for next pass.87 pub fn hash(b: []const u8, out: []u8) void {
93 mem.copy(u8, d.buf[d.buf_len..], b[off..]);88 var d = Self.init();
94 d.buf_len += u8(b[off..].len);89 d.update(b);
95 }90 d.final(out);
91 }
9692
97 pub fn final(d: &Self, out: []u8) void {93 pub fn update(d: &Self, b: []const u8) void {
98 debug.assert(out.len >= out_len / 8);94 var off: usize = 0;
9995
100 mem.set(u8, d.buf[d.buf_len..], 0);96 // Partial buffer exists from previous update. Copy into buffer then hash.
101 d.t += d.buf_len;97 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
102 d.round(d.buf[0..], true);98 off += 64 - d.buf_len;
99 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
100 d.t += 64;
101 d.round(d.buf[0..], false);
102 d.buf_len = 0;
103 }
103104
104 const rr = d.h[0 .. out_len / 32];105 // Full middle blocks.
106 while (off + 64 <= b.len) : (off += 64) {
107 d.t += 64;
108 d.round(b[off..off + 64], false);
109 }
105110
106 for (rr) |s, j| {111 // Copy any remainder for next pass.
107 mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Little);112 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
113 d.buf_len += u8(b[off..].len);
108 }114 }
109 }
110115
111 fn round(d: &Self, b: []const u8, last: bool) void {116 pub fn final(d: &Self, out: []u8) void {
112 debug.assert(b.len == 64);117 debug.assert(out.len >= out_len / 8);
113118
114 var m: [16]u32 = undefined;119 mem.set(u8, d.buf[d.buf_len..], 0);
115 var v: [16]u32 = undefined;120 d.t += d.buf_len;
121 d.round(d.buf[0..], true);
116122
117 for (m) |*r, i| {123 const rr = d.h[0..out_len / 32];
118 *r = mem.readIntLE(u32, b[4*i .. 4*i + 4]);
119 }
120124
121 var k: usize = 0;125 for (rr) |s, j| {
122 while (k < 8) : (k += 1) {126 mem.writeInt(out[4 * j..4 * j + 4], s, builtin.Endian.Little);
123 v[k] = d.h[k];127 }
124 v[k+8] = iv[k];
125 }128 }
126129
127 v[12] ^= @truncate(u32, d.t);130 fn round(d: &Self, b: []const u8, last: bool) void {
128 v[13] ^= u32(d.t >> 32);131 debug.assert(b.len == 64);
129 if (last) v[14] = ~v[14];
130
131 const rounds = comptime []RoundParam {
132 Rp(0, 4, 8, 12, 0, 1),
133 Rp(1, 5, 9, 13, 2, 3),
134 Rp(2, 6, 10, 14, 4, 5),
135 Rp(3, 7, 11, 15, 6, 7),
136 Rp(0, 5, 10, 15, 8, 9),
137 Rp(1, 6, 11, 12, 10, 11),
138 Rp(2, 7, 8, 13, 12, 13),
139 Rp(3, 4, 9, 14, 14, 15),
140 };
141132
142 comptime var j: usize = 0;133 var m: [16]u32 = undefined;
143 inline while (j < 10) : (j += 1) {134 var v: [16]u32 = undefined;
144 inline for (rounds) |r| {135
145 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];136 for (m) |*r, i| {
146 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(16));137 r.* = mem.readIntLE(u32, b[4 * i..4 * i + 4]);
147 v[r.c] = v[r.c] +% v[r.d];
148 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(12));
149 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
150 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(8));
151 v[r.c] = v[r.c] +% v[r.d];
152 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(7));
153 }138 }
154 }
155139
156 for (d.h) |*r, i| {140 var k: usize = 0;
157 *r ^= v[i] ^ v[i + 8];141 while (k < 8) : (k += 1) {
142 v[k] = d.h[k];
143 v[k + 8] = iv[k];
144 }
145
146 v[12] ^= @truncate(u32, d.t);
147 v[13] ^= u32(d.t >> 32);
148 if (last) v[14] = ~v[14];
149
150 const rounds = comptime []RoundParam{
151 Rp(0, 4, 8, 12, 0, 1),
152 Rp(1, 5, 9, 13, 2, 3),
153 Rp(2, 6, 10, 14, 4, 5),
154 Rp(3, 7, 11, 15, 6, 7),
155 Rp(0, 5, 10, 15, 8, 9),
156 Rp(1, 6, 11, 12, 10, 11),
157 Rp(2, 7, 8, 13, 12, 13),
158 Rp(3, 4, 9, 14, 14, 15),
159 };
160
161 comptime var j: usize = 0;
162 inline while (j < 10) : (j += 1) {
163 inline for (rounds) |r| {
164 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
165 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(16));
166 v[r.c] = v[r.c] +% v[r.d];
167 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(12));
168 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
169 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(8));
170 v[r.c] = v[r.c] +% v[r.d];
171 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(7));
172 }
173 }
174
175 for (d.h) |*r, i| {
176 r.* ^= v[i] ^ v[i + 8];
177 }
158 }178 }
159 }179 };
160};}180}
161181
162test "blake2s224 single" {182test "blake2s224 single" {
163 const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4";183 const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4";
...@@ -230,7 +250,7 @@ test "blake2s256 streaming" {...@@ -230,7 +250,7 @@ test "blake2s256 streaming" {
230}250}
231251
232test "blake2s256 aligned final" {252test "blake2s256 aligned final" {
233 var block = []u8 {0} ** Blake2s256.block_size;253 var block = []u8{0} ** Blake2s256.block_size;
234 var out: [Blake2s256.digest_size]u8 = undefined;254 var out: [Blake2s256.digest_size]u8 = undefined;
235255
236 var h = Blake2s256.init();256 var h = Blake2s256.init();
...@@ -238,154 +258,159 @@ test "blake2s256 aligned final" {...@@ -238,154 +258,159 @@ test "blake2s256 aligned final" {
238 h.final(out[0..]);258 h.final(out[0..]);
239}259}
240260
241
242/////////////////////261/////////////////////
243// Blake2b262// Blake2b
244263
245pub const Blake2b384 = Blake2b(384);264pub const Blake2b384 = Blake2b(384);
246pub const Blake2b512 = Blake2b(512);265pub const Blake2b512 = Blake2b(512);
247266
248fn Blake2b(comptime out_len: usize) type { return struct {267fn Blake2b(comptime out_len: usize) type {
249 const Self = this;268 return struct {
250 const block_size = 128;269 const Self = this;
251 const digest_size = out_len / 8;270 const block_size = 128;
271 const digest_size = out_len / 8;
272
273 const iv = [8]u64{
274 0x6a09e667f3bcc908,
275 0xbb67ae8584caa73b,
276 0x3c6ef372fe94f82b,
277 0xa54ff53a5f1d36f1,
278 0x510e527fade682d1,
279 0x9b05688c2b3e6c1f,
280 0x1f83d9abfb41bd6b,
281 0x5be0cd19137e2179,
282 };
252283
253 const iv = [8]u64 {284 const sigma = [12][16]u8{
254 0x6a09e667f3bcc908, 0xbb67ae8584caa73b,285 []const u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
255 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,286 []const u8{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
256 0x510e527fade682d1, 0x9b05688c2b3e6c1f,287 []const u8{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
257 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,288 []const u8{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
258 };289 []const u8{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
290 []const u8{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
291 []const u8{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
292 []const u8{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
293 []const u8{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
294 []const u8{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
295 []const u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
296 []const u8{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
297 };
259298
260 const sigma = [12][16]u8 {299 h: [8]u64,
261 []const u8 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },300 t: u128,
262 []const u8 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },301 // Streaming cache
263 []const u8 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },302 buf: [128]u8,
264 []const u8 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },303 buf_len: u8,
265 []const u8 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
266 []const u8 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
267 []const u8 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
268 []const u8 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
269 []const u8 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
270 []const u8 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
271 []const u8 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
272 []const u8 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
273 };
274304
275 h: [8]u64,305 pub fn init() Self {
276 t: u128,306 debug.assert(8 <= out_len and out_len <= 512);
277 // Streaming cache307
278 buf: [128]u8,308 var s: Self = undefined;
279 buf_len: u8,309 s.reset();
280310 return s;
281 pub fn init() Self {311 }
282 debug.assert(8 <= out_len and out_len <= 512);312
283313 pub fn reset(d: &Self) void {
284 var s: Self = undefined;314 mem.copy(u64, d.h[0..], iv[0..]);
285 s.reset();315
286 return s;316 // No key plus default parameters
287 }317 d.h[0] ^= 0x01010000 ^ (out_len >> 3);
288318 d.t = 0;
289 pub fn reset(d: &Self) void {
290 mem.copy(u64, d.h[0..], iv[0..]);
291
292 // No key plus default parameters
293 d.h[0] ^= 0x01010000 ^ (out_len >> 3);
294 d.t = 0;
295 d.buf_len = 0;
296 }
297
298 pub fn hash(b: []const u8, out: []u8) void {
299 var d = Self.init();
300 d.update(b);
301 d.final(out);
302 }
303
304 pub fn update(d: &Self, b: []const u8) void {
305 var off: usize = 0;
306
307 // Partial buffer exists from previous update. Copy into buffer then hash.
308 if (d.buf_len != 0 and d.buf_len + b.len > 128) {
309 off += 128 - d.buf_len;
310 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
311 d.t += 128;
312 d.round(d.buf[0..], false);
313 d.buf_len = 0;319 d.buf_len = 0;
314 }320 }
315321
316 // Full middle blocks.322 pub fn hash(b: []const u8, out: []u8) void {
317 while (off + 128 <= b.len) : (off += 128) {323 var d = Self.init();
318 d.t += 128;324 d.update(b);
319 d.round(b[off..off + 128], false);325 d.final(out);
320 }326 }
321327
322 // Copy any remainder for next pass.328 pub fn update(d: &Self, b: []const u8) void {
323 mem.copy(u8, d.buf[d.buf_len..], b[off..]);329 var off: usize = 0;
324 d.buf_len += u8(b[off..].len);
325 }
326330
327 pub fn final(d: &Self, out: []u8) void {331 // Partial buffer exists from previous update. Copy into buffer then hash.
328 mem.set(u8, d.buf[d.buf_len..], 0);332 if (d.buf_len != 0 and d.buf_len + b.len > 128) {
329 d.t += d.buf_len;333 off += 128 - d.buf_len;
330 d.round(d.buf[0..], true);334 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
335 d.t += 128;
336 d.round(d.buf[0..], false);
337 d.buf_len = 0;
338 }
331339
332 const rr = d.h[0 .. out_len / 64];340 // Full middle blocks.
341 while (off + 128 <= b.len) : (off += 128) {
342 d.t += 128;
343 d.round(b[off..off + 128], false);
344 }
333345
334 for (rr) |s, j| {346 // Copy any remainder for next pass.
335 mem.writeInt(out[8*j .. 8*j + 8], s, builtin.Endian.Little);347 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
348 d.buf_len += u8(b[off..].len);
336 }349 }
337 }
338350
339 fn round(d: &Self, b: []const u8, last: bool) void {351 pub fn final(d: &Self, out: []u8) void {
340 debug.assert(b.len == 128);352 mem.set(u8, d.buf[d.buf_len..], 0);
353 d.t += d.buf_len;
354 d.round(d.buf[0..], true);
341355
342 var m: [16]u64 = undefined;356 const rr = d.h[0..out_len / 64];
343 var v: [16]u64 = undefined;
344357
345 for (m) |*r, i| {358 for (rr) |s, j| {
346 *r = mem.readIntLE(u64, b[8*i .. 8*i + 8]);359 mem.writeInt(out[8 * j..8 * j + 8], s, builtin.Endian.Little);
360 }
347 }361 }
348362
349 var k: usize = 0;363 fn round(d: &Self, b: []const u8, last: bool) void {
350 while (k < 8) : (k += 1) {364 debug.assert(b.len == 128);
351 v[k] = d.h[k];
352 v[k+8] = iv[k];
353 }
354365
355 v[12] ^= @truncate(u64, d.t);366 var m: [16]u64 = undefined;
356 v[13] ^= u64(d.t >> 64);367 var v: [16]u64 = undefined;
357 if (last) v[14] = ~v[14];
358
359 const rounds = comptime []RoundParam {
360 Rp(0, 4, 8, 12, 0, 1),
361 Rp(1, 5, 9, 13, 2, 3),
362 Rp(2, 6, 10, 14, 4, 5),
363 Rp(3, 7, 11, 15, 6, 7),
364 Rp(0, 5, 10, 15, 8, 9),
365 Rp(1, 6, 11, 12, 10, 11),
366 Rp(2, 7, 8, 13, 12, 13),
367 Rp(3, 4, 9, 14, 14, 15),
368 };
369368
370 comptime var j: usize = 0;369 for (m) |*r, i| {
371 inline while (j < 12) : (j += 1) {370 r.* = mem.readIntLE(u64, b[8 * i..8 * i + 8]);
372 inline for (rounds) |r| {371 }
373 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];372
374 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(32));373 var k: usize = 0;
375 v[r.c] = v[r.c] +% v[r.d];374 while (k < 8) : (k += 1) {
376 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(24));375 v[k] = d.h[k];
377 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];376 v[k + 8] = iv[k];
378 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(16));
379 v[r.c] = v[r.c] +% v[r.d];
380 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(63));
381 }377 }
382 }
383378
384 for (d.h) |*r, i| {379 v[12] ^= @truncate(u64, d.t);
385 *r ^= v[i] ^ v[i + 8];380 v[13] ^= u64(d.t >> 64);
381 if (last) v[14] = ~v[14];
382
383 const rounds = comptime []RoundParam{
384 Rp(0, 4, 8, 12, 0, 1),
385 Rp(1, 5, 9, 13, 2, 3),
386 Rp(2, 6, 10, 14, 4, 5),
387 Rp(3, 7, 11, 15, 6, 7),
388 Rp(0, 5, 10, 15, 8, 9),
389 Rp(1, 6, 11, 12, 10, 11),
390 Rp(2, 7, 8, 13, 12, 13),
391 Rp(3, 4, 9, 14, 14, 15),
392 };
393
394 comptime var j: usize = 0;
395 inline while (j < 12) : (j += 1) {
396 inline for (rounds) |r| {
397 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
398 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(32));
399 v[r.c] = v[r.c] +% v[r.d];
400 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(24));
401 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
402 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(16));
403 v[r.c] = v[r.c] +% v[r.d];
404 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(63));
405 }
406 }
407
408 for (d.h) |*r, i| {
409 r.* ^= v[i] ^ v[i + 8];
410 }
386 }411 }
387 }412 };
388};}413}
389414
390test "blake2b384 single" {415test "blake2b384 single" {
391 const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100";416 const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100";
...@@ -458,7 +483,7 @@ test "blake2b512 streaming" {...@@ -458,7 +483,7 @@ test "blake2b512 streaming" {
458}483}
459484
460test "blake2b512 aligned final" {485test "blake2b512 aligned final" {
461 var block = []u8 {0} ** Blake2b512.block_size;486 var block = []u8{0} ** Blake2b512.block_size;
462 var out: [Blake2b512.digest_size]u8 = undefined;487 var out: [Blake2b512.digest_size]u8 = undefined;
463488
464 var h = Blake2b512.init();489 var h = Blake2b512.init();
std/crypto/hmac.zig+2-2
...@@ -29,12 +29,12 @@ pub fn Hmac(comptime H: type) type {...@@ -29,12 +29,12 @@ pub fn Hmac(comptime H: type) type {
2929
30 var o_key_pad: [H.block_size]u8 = undefined;30 var o_key_pad: [H.block_size]u8 = undefined;
31 for (o_key_pad) |*b, i| {31 for (o_key_pad) |*b, i| {
32 *b = scratch[i] ^ 0x5c;32 b.* = scratch[i] ^ 0x5c;
33 }33 }
3434
35 var i_key_pad: [H.block_size]u8 = undefined;35 var i_key_pad: [H.block_size]u8 = undefined;
36 for (i_key_pad) |*b, i| {36 for (i_key_pad) |*b, i| {
37 *b = scratch[i] ^ 0x36;37 b.* = scratch[i] ^ 0x36;
38 }38 }
3939
40 // HMAC(k, m) = H(o_key_pad | H(i_key_pad | message)) where | is concatenation40 // HMAC(k, m) = H(o_key_pad | H(i_key_pad | message)) where | is concatenation
std/crypto/md5.zig+77-61
...@@ -6,12 +6,25 @@ const debug = @import("../debug/index.zig");...@@ -6,12 +6,25 @@ const debug = @import("../debug/index.zig");
6const fmt = @import("../fmt/index.zig");6const fmt = @import("../fmt/index.zig");
77
8const RoundParam = struct {8const RoundParam = struct {
9 a: usize, b: usize, c: usize, d: usize,9 a: usize,
10 k: usize, s: u32, t: u3210 b: usize,
11 c: usize,
12 d: usize,
13 k: usize,
14 s: u32,
15 t: u32,
11};16};
1217
13fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundParam {18fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundParam {
14 return RoundParam { .a = a, .b = b, .c = c, .d = d, .k = k, .s = s, .t = t };19 return RoundParam{
20 .a = a,
21 .b = b,
22 .c = c,
23 .d = d,
24 .k = k,
25 .s = s,
26 .t = t,
27 };
15}28}
1629
17pub const Md5 = struct {30pub const Md5 = struct {
...@@ -99,7 +112,7 @@ pub const Md5 = struct {...@@ -99,7 +112,7 @@ pub const Md5 = struct {
99 d.round(d.buf[0..]);112 d.round(d.buf[0..]);
100113
101 for (d.s) |s, j| {114 for (d.s) |s, j| {
102 mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Little);115 mem.writeInt(out[4 * j..4 * j + 4], s, builtin.Endian.Little);
103 }116 }
104 }117 }
105118
...@@ -112,30 +125,33 @@ pub const Md5 = struct {...@@ -112,30 +125,33 @@ pub const Md5 = struct {
112 while (i < 16) : (i += 1) {125 while (i < 16) : (i += 1) {
113 // NOTE: Performing or's separately improves perf by ~10%126 // NOTE: Performing or's separately improves perf by ~10%
114 s[i] = 0;127 s[i] = 0;
115 s[i] |= u32(b[i*4+0]);128 s[i] |= u32(b[i * 4 + 0]);
116 s[i] |= u32(b[i*4+1]) << 8;129 s[i] |= u32(b[i * 4 + 1]) << 8;
117 s[i] |= u32(b[i*4+2]) << 16;130 s[i] |= u32(b[i * 4 + 2]) << 16;
118 s[i] |= u32(b[i*4+3]) << 24;131 s[i] |= u32(b[i * 4 + 3]) << 24;
119 }132 }
120133
121 var v: [4]u32 = []u32 {134 var v: [4]u32 = []u32{
122 d.s[0], d.s[1], d.s[2], d.s[3],135 d.s[0],
136 d.s[1],
137 d.s[2],
138 d.s[3],
123 };139 };
124140
125 const round0 = comptime []RoundParam {141 const round0 = comptime []RoundParam{
126 Rp(0, 1, 2, 3, 0, 7, 0xD76AA478),142 Rp(0, 1, 2, 3, 0, 7, 0xD76AA478),
127 Rp(3, 0, 1, 2, 1, 12, 0xE8C7B756),143 Rp(3, 0, 1, 2, 1, 12, 0xE8C7B756),
128 Rp(2, 3, 0, 1, 2, 17, 0x242070DB),144 Rp(2, 3, 0, 1, 2, 17, 0x242070DB),
129 Rp(1, 2, 3, 0, 3, 22, 0xC1BDCEEE),145 Rp(1, 2, 3, 0, 3, 22, 0xC1BDCEEE),
130 Rp(0, 1, 2, 3, 4, 7, 0xF57C0FAF),146 Rp(0, 1, 2, 3, 4, 7, 0xF57C0FAF),
131 Rp(3, 0, 1, 2, 5, 12, 0x4787C62A),147 Rp(3, 0, 1, 2, 5, 12, 0x4787C62A),
132 Rp(2, 3, 0, 1, 6, 17, 0xA8304613),148 Rp(2, 3, 0, 1, 6, 17, 0xA8304613),
133 Rp(1, 2, 3, 0, 7, 22, 0xFD469501),149 Rp(1, 2, 3, 0, 7, 22, 0xFD469501),
134 Rp(0, 1, 2, 3, 8, 7, 0x698098D8),150 Rp(0, 1, 2, 3, 8, 7, 0x698098D8),
135 Rp(3, 0, 1, 2, 9, 12, 0x8B44F7AF),151 Rp(3, 0, 1, 2, 9, 12, 0x8B44F7AF),
136 Rp(2, 3, 0, 1, 10, 17, 0xFFFF5BB1),152 Rp(2, 3, 0, 1, 10, 17, 0xFFFF5BB1),
137 Rp(1, 2, 3, 0, 11, 22, 0x895CD7BE),153 Rp(1, 2, 3, 0, 11, 22, 0x895CD7BE),
138 Rp(0, 1, 2, 3, 12, 7, 0x6B901122),154 Rp(0, 1, 2, 3, 12, 7, 0x6B901122),
139 Rp(3, 0, 1, 2, 13, 12, 0xFD987193),155 Rp(3, 0, 1, 2, 13, 12, 0xFD987193),
140 Rp(2, 3, 0, 1, 14, 17, 0xA679438E),156 Rp(2, 3, 0, 1, 14, 17, 0xA679438E),
141 Rp(1, 2, 3, 0, 15, 22, 0x49B40821),157 Rp(1, 2, 3, 0, 15, 22, 0x49B40821),
...@@ -145,22 +161,22 @@ pub const Md5 = struct {...@@ -145,22 +161,22 @@ pub const Md5 = struct {
145 v[r.a] = v[r.b] +% math.rotl(u32, v[r.a], r.s);161 v[r.a] = v[r.b] +% math.rotl(u32, v[r.a], r.s);
146 }162 }
147163
148 const round1 = comptime []RoundParam {164 const round1 = comptime []RoundParam{
149 Rp(0, 1, 2, 3, 1, 5, 0xF61E2562),165 Rp(0, 1, 2, 3, 1, 5, 0xF61E2562),
150 Rp(3, 0, 1, 2, 6, 9, 0xC040B340),166 Rp(3, 0, 1, 2, 6, 9, 0xC040B340),
151 Rp(2, 3, 0, 1, 11, 14, 0x265E5A51),167 Rp(2, 3, 0, 1, 11, 14, 0x265E5A51),
152 Rp(1, 2, 3, 0, 0, 20, 0xE9B6C7AA),168 Rp(1, 2, 3, 0, 0, 20, 0xE9B6C7AA),
153 Rp(0, 1, 2, 3, 5, 5, 0xD62F105D),169 Rp(0, 1, 2, 3, 5, 5, 0xD62F105D),
154 Rp(3, 0, 1, 2, 10, 9, 0x02441453),170 Rp(3, 0, 1, 2, 10, 9, 0x02441453),
155 Rp(2, 3, 0, 1, 15, 14, 0xD8A1E681),171 Rp(2, 3, 0, 1, 15, 14, 0xD8A1E681),
156 Rp(1, 2, 3, 0, 4, 20, 0xE7D3FBC8),172 Rp(1, 2, 3, 0, 4, 20, 0xE7D3FBC8),
157 Rp(0, 1, 2, 3, 9, 5, 0x21E1CDE6),173 Rp(0, 1, 2, 3, 9, 5, 0x21E1CDE6),
158 Rp(3, 0, 1, 2, 14, 9, 0xC33707D6),174 Rp(3, 0, 1, 2, 14, 9, 0xC33707D6),
159 Rp(2, 3, 0, 1, 3, 14, 0xF4D50D87),175 Rp(2, 3, 0, 1, 3, 14, 0xF4D50D87),
160 Rp(1, 2, 3, 0, 8, 20, 0x455A14ED),176 Rp(1, 2, 3, 0, 8, 20, 0x455A14ED),
161 Rp(0, 1, 2, 3, 13, 5, 0xA9E3E905),177 Rp(0, 1, 2, 3, 13, 5, 0xA9E3E905),
162 Rp(3, 0, 1, 2, 2, 9, 0xFCEFA3F8),178 Rp(3, 0, 1, 2, 2, 9, 0xFCEFA3F8),
163 Rp(2, 3, 0, 1, 7, 14, 0x676F02D9),179 Rp(2, 3, 0, 1, 7, 14, 0x676F02D9),
164 Rp(1, 2, 3, 0, 12, 20, 0x8D2A4C8A),180 Rp(1, 2, 3, 0, 12, 20, 0x8D2A4C8A),
165 };181 };
166 inline for (round1) |r| {182 inline for (round1) |r| {
...@@ -168,46 +184,46 @@ pub const Md5 = struct {...@@ -168,46 +184,46 @@ pub const Md5 = struct {
168 v[r.a] = v[r.b] +% math.rotl(u32, v[r.a], r.s);184 v[r.a] = v[r.b] +% math.rotl(u32, v[r.a], r.s);
169 }185 }
170186
171 const round2 = comptime []RoundParam {187 const round2 = comptime []RoundParam{
172 Rp(0, 1, 2, 3, 5, 4, 0xFFFA3942),188 Rp(0, 1, 2, 3, 5, 4, 0xFFFA3942),
173 Rp(3, 0, 1, 2, 8, 11, 0x8771F681),189 Rp(3, 0, 1, 2, 8, 11, 0x8771F681),
174 Rp(2, 3, 0, 1, 11, 16, 0x6D9D6122),190 Rp(2, 3, 0, 1, 11, 16, 0x6D9D6122),
175 Rp(1, 2, 3, 0, 14, 23, 0xFDE5380C),191 Rp(1, 2, 3, 0, 14, 23, 0xFDE5380C),
176 Rp(0, 1, 2, 3, 1, 4, 0xA4BEEA44),192 Rp(0, 1, 2, 3, 1, 4, 0xA4BEEA44),
177 Rp(3, 0, 1, 2, 4, 11, 0x4BDECFA9),193 Rp(3, 0, 1, 2, 4, 11, 0x4BDECFA9),
178 Rp(2, 3, 0, 1, 7, 16, 0xF6BB4B60),194 Rp(2, 3, 0, 1, 7, 16, 0xF6BB4B60),
179 Rp(1, 2, 3, 0, 10, 23, 0xBEBFBC70),195 Rp(1, 2, 3, 0, 10, 23, 0xBEBFBC70),
180 Rp(0, 1, 2, 3, 13, 4, 0x289B7EC6),196 Rp(0, 1, 2, 3, 13, 4, 0x289B7EC6),
181 Rp(3, 0, 1, 2, 0, 11, 0xEAA127FA),197 Rp(3, 0, 1, 2, 0, 11, 0xEAA127FA),
182 Rp(2, 3, 0, 1, 3, 16, 0xD4EF3085),198 Rp(2, 3, 0, 1, 3, 16, 0xD4EF3085),
183 Rp(1, 2, 3, 0, 6, 23, 0x04881D05),199 Rp(1, 2, 3, 0, 6, 23, 0x04881D05),
184 Rp(0, 1, 2, 3, 9, 4, 0xD9D4D039),200 Rp(0, 1, 2, 3, 9, 4, 0xD9D4D039),
185 Rp(3, 0, 1, 2, 12, 11, 0xE6DB99E5),201 Rp(3, 0, 1, 2, 12, 11, 0xE6DB99E5),
186 Rp(2, 3, 0, 1, 15, 16, 0x1FA27CF8),202 Rp(2, 3, 0, 1, 15, 16, 0x1FA27CF8),
187 Rp(1, 2, 3, 0, 2, 23, 0xC4AC5665),203 Rp(1, 2, 3, 0, 2, 23, 0xC4AC5665),
188 };204 };
189 inline for (round2) |r| {205 inline for (round2) |r| {
190 v[r.a] = v[r.a] +% (v[r.b] ^ v[r.c] ^ v[r.d]) +% r.t +% s[r.k];206 v[r.a] = v[r.a] +% (v[r.b] ^ v[r.c] ^ v[r.d]) +% r.t +% s[r.k];
191 v[r.a] = v[r.b] +% math.rotl(u32, v[r.a], r.s);207 v[r.a] = v[r.b] +% math.rotl(u32, v[r.a], r.s);
192 }208 }
193209
194 const round3 = comptime []RoundParam {210 const round3 = comptime []RoundParam{
195 Rp(0, 1, 2, 3, 0, 6, 0xF4292244),211 Rp(0, 1, 2, 3, 0, 6, 0xF4292244),
196 Rp(3, 0, 1, 2, 7, 10, 0x432AFF97),212 Rp(3, 0, 1, 2, 7, 10, 0x432AFF97),
197 Rp(2, 3, 0, 1, 14, 15, 0xAB9423A7),213 Rp(2, 3, 0, 1, 14, 15, 0xAB9423A7),
198 Rp(1, 2, 3, 0, 5, 21, 0xFC93A039),214 Rp(1, 2, 3, 0, 5, 21, 0xFC93A039),
199 Rp(0, 1, 2, 3, 12, 6, 0x655B59C3),215 Rp(0, 1, 2, 3, 12, 6, 0x655B59C3),
200 Rp(3, 0, 1, 2, 3, 10, 0x8F0CCC92),216 Rp(3, 0, 1, 2, 3, 10, 0x8F0CCC92),
201 Rp(2, 3, 0, 1, 10, 15, 0xFFEFF47D),217 Rp(2, 3, 0, 1, 10, 15, 0xFFEFF47D),
202 Rp(1, 2, 3, 0, 1, 21, 0x85845DD1),218 Rp(1, 2, 3, 0, 1, 21, 0x85845DD1),
203 Rp(0, 1, 2, 3, 8, 6, 0x6FA87E4F),219 Rp(0, 1, 2, 3, 8, 6, 0x6FA87E4F),
204 Rp(3, 0, 1, 2, 15, 10, 0xFE2CE6E0),220 Rp(3, 0, 1, 2, 15, 10, 0xFE2CE6E0),
205 Rp(2, 3, 0, 1, 6, 15, 0xA3014314),221 Rp(2, 3, 0, 1, 6, 15, 0xA3014314),
206 Rp(1, 2, 3, 0, 13, 21, 0x4E0811A1),222 Rp(1, 2, 3, 0, 13, 21, 0x4E0811A1),
207 Rp(0, 1, 2, 3, 4, 6, 0xF7537E82),223 Rp(0, 1, 2, 3, 4, 6, 0xF7537E82),
208 Rp(3, 0, 1, 2, 11, 10, 0xBD3AF235),224 Rp(3, 0, 1, 2, 11, 10, 0xBD3AF235),
209 Rp(2, 3, 0, 1, 2, 15, 0x2AD7D2BB),225 Rp(2, 3, 0, 1, 2, 15, 0x2AD7D2BB),
210 Rp(1, 2, 3, 0, 9, 21, 0xEB86D391),226 Rp(1, 2, 3, 0, 9, 21, 0xEB86D391),
211 };227 };
212 inline for (round3) |r| {228 inline for (round3) |r| {
213 v[r.a] = v[r.a] +% (v[r.c] ^ (v[r.b] | ~v[r.d])) +% r.t +% s[r.k];229 v[r.a] = v[r.a] +% (v[r.c] ^ (v[r.b] | ~v[r.d])) +% r.t +% s[r.k];
...@@ -255,7 +271,7 @@ test "md5 streaming" {...@@ -255,7 +271,7 @@ test "md5 streaming" {
255}271}
256272
257test "md5 aligned final" {273test "md5 aligned final" {
258 var block = []u8 {0} ** Md5.block_size;274 var block = []u8{0} ** Md5.block_size;
259 var out: [Md5.digest_size]u8 = undefined;275 var out: [Md5.digest_size]u8 = undefined;
260276
261 var h = Md5.init();277 var h = Md5.init();
std/crypto/sha1.zig+47-39
...@@ -7,11 +7,23 @@ const builtin = @import("builtin");...@@ -7,11 +7,23 @@ const builtin = @import("builtin");
7pub const u160 = @IntType(false, 160);7pub const u160 = @IntType(false, 160);
88
9const RoundParam = struct {9const RoundParam = struct {
10 a: usize, b: usize, c: usize, d: usize, e: usize, i: u32,10 a: usize,
11 b: usize,
12 c: usize,
13 d: usize,
14 e: usize,
15 i: u32,
11};16};
1217
13fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam {18fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam {
14 return RoundParam { .a = a, .b = b, .c = c, .d = d, .e = e, .i = i };19 return RoundParam{
20 .a = a,
21 .b = b,
22 .c = c,
23 .d = d,
24 .e = e,
25 .i = i,
26 };
15}27}
1628
17pub const Sha1 = struct {29pub const Sha1 = struct {
...@@ -99,7 +111,7 @@ pub const Sha1 = struct {...@@ -99,7 +111,7 @@ pub const Sha1 = struct {
99 d.round(d.buf[0..]);111 d.round(d.buf[0..]);
100112
101 for (d.s) |s, j| {113 for (d.s) |s, j| {
102 mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Big);114 mem.writeInt(out[4 * j..4 * j + 4], s, builtin.Endian.Big);
103 }115 }
104 }116 }
105117
...@@ -108,21 +120,25 @@ pub const Sha1 = struct {...@@ -108,21 +120,25 @@ pub const Sha1 = struct {
108120
109 var s: [16]u32 = undefined;121 var s: [16]u32 = undefined;
110122
111 var v: [5]u32 = []u32 {123 var v: [5]u32 = []u32{
112 d.s[0], d.s[1], d.s[2], d.s[3], d.s[4],124 d.s[0],
125 d.s[1],
126 d.s[2],
127 d.s[3],
128 d.s[4],
113 };129 };
114130
115 const round0a = comptime []RoundParam {131 const round0a = comptime []RoundParam{
116 Rp(0, 1, 2, 3, 4, 0),132 Rp(0, 1, 2, 3, 4, 0),
117 Rp(4, 0, 1, 2, 3, 1),133 Rp(4, 0, 1, 2, 3, 1),
118 Rp(3, 4, 0, 1, 2, 2),134 Rp(3, 4, 0, 1, 2, 2),
119 Rp(2, 3, 4, 0, 1, 3),135 Rp(2, 3, 4, 0, 1, 3),
120 Rp(1, 2, 3, 4, 0, 4),136 Rp(1, 2, 3, 4, 0, 4),
121 Rp(0, 1, 2, 3, 4, 5),137 Rp(0, 1, 2, 3, 4, 5),
122 Rp(4, 0, 1, 2, 3, 6),138 Rp(4, 0, 1, 2, 3, 6),
123 Rp(3, 4, 0, 1, 2, 7),139 Rp(3, 4, 0, 1, 2, 7),
124 Rp(2, 3, 4, 0, 1, 8),140 Rp(2, 3, 4, 0, 1, 8),
125 Rp(1, 2, 3, 4, 0, 9),141 Rp(1, 2, 3, 4, 0, 9),
126 Rp(0, 1, 2, 3, 4, 10),142 Rp(0, 1, 2, 3, 4, 10),
127 Rp(4, 0, 1, 2, 3, 11),143 Rp(4, 0, 1, 2, 3, 11),
128 Rp(3, 4, 0, 1, 2, 12),144 Rp(3, 4, 0, 1, 2, 12),
...@@ -131,32 +147,27 @@ pub const Sha1 = struct {...@@ -131,32 +147,27 @@ pub const Sha1 = struct {
131 Rp(0, 1, 2, 3, 4, 15),147 Rp(0, 1, 2, 3, 4, 15),
132 };148 };
133 inline for (round0a) |r| {149 inline for (round0a) |r| {
134 s[r.i] = (u32(b[r.i * 4 + 0]) << 24) |150 s[r.i] = (u32(b[r.i * 4 + 0]) << 24) | (u32(b[r.i * 4 + 1]) << 16) | (u32(b[r.i * 4 + 2]) << 8) | (u32(b[r.i * 4 + 3]) << 0);
135 (u32(b[r.i * 4 + 1]) << 16) |
136 (u32(b[r.i * 4 + 2]) << 8) |
137 (u32(b[r.i * 4 + 3]) << 0);
138151
139 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x5A827999 +% s[r.i & 0xf]152 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
140 +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
141 v[r.b] = math.rotl(u32, v[r.b], u32(30));153 v[r.b] = math.rotl(u32, v[r.b], u32(30));
142 }154 }
143155
144 const round0b = comptime []RoundParam {156 const round0b = comptime []RoundParam{
145 Rp(4, 0, 1, 2, 3, 16),157 Rp(4, 0, 1, 2, 3, 16),
146 Rp(3, 4, 0, 1, 2, 17),158 Rp(3, 4, 0, 1, 2, 17),
147 Rp(2, 3, 4, 0, 1, 18),159 Rp(2, 3, 4, 0, 1, 18),
148 Rp(1, 2, 3, 4, 0, 19),160 Rp(1, 2, 3, 4, 0, 19),
149 };161 };
150 inline for (round0b) |r| {162 inline for (round0b) |r| {
151 const t = s[(r.i-3) & 0xf] ^ s[(r.i-8) & 0xf] ^ s[(r.i-14) & 0xf] ^ s[(r.i-16) & 0xf];163 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
152 s[r.i & 0xf] = math.rotl(u32, t, u32(1));164 s[r.i & 0xf] = math.rotl(u32, t, u32(1));
153165
154 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x5A827999 +% s[r.i & 0xf]166 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
155 +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
156 v[r.b] = math.rotl(u32, v[r.b], u32(30));167 v[r.b] = math.rotl(u32, v[r.b], u32(30));
157 }168 }
158169
159 const round1 = comptime []RoundParam {170 const round1 = comptime []RoundParam{
160 Rp(0, 1, 2, 3, 4, 20),171 Rp(0, 1, 2, 3, 4, 20),
161 Rp(4, 0, 1, 2, 3, 21),172 Rp(4, 0, 1, 2, 3, 21),
162 Rp(3, 4, 0, 1, 2, 22),173 Rp(3, 4, 0, 1, 2, 22),
...@@ -179,15 +190,14 @@ pub const Sha1 = struct {...@@ -179,15 +190,14 @@ pub const Sha1 = struct {
179 Rp(1, 2, 3, 4, 0, 39),190 Rp(1, 2, 3, 4, 0, 39),
180 };191 };
181 inline for (round1) |r| {192 inline for (round1) |r| {
182 const t = s[(r.i-3) & 0xf] ^ s[(r.i-8) & 0xf] ^ s[(r.i-14) & 0xf] ^ s[(r.i-16) & 0xf];193 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
183 s[r.i & 0xf] = math.rotl(u32, t, u32(1));194 s[r.i & 0xf] = math.rotl(u32, t, u32(1));
184195
185 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x6ED9EBA1 +% s[r.i & 0xf]196 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x6ED9EBA1 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);
186 +% (v[r.b] ^ v[r.c] ^ v[r.d]);
187 v[r.b] = math.rotl(u32, v[r.b], u32(30));197 v[r.b] = math.rotl(u32, v[r.b], u32(30));
188 }198 }
189199
190 const round2 = comptime []RoundParam {200 const round2 = comptime []RoundParam{
191 Rp(0, 1, 2, 3, 4, 40),201 Rp(0, 1, 2, 3, 4, 40),
192 Rp(4, 0, 1, 2, 3, 41),202 Rp(4, 0, 1, 2, 3, 41),
193 Rp(3, 4, 0, 1, 2, 42),203 Rp(3, 4, 0, 1, 2, 42),
...@@ -210,15 +220,14 @@ pub const Sha1 = struct {...@@ -210,15 +220,14 @@ pub const Sha1 = struct {
210 Rp(1, 2, 3, 4, 0, 59),220 Rp(1, 2, 3, 4, 0, 59),
211 };221 };
212 inline for (round2) |r| {222 inline for (round2) |r| {
213 const t = s[(r.i-3) & 0xf] ^ s[(r.i-8) & 0xf] ^ s[(r.i-14) & 0xf] ^ s[(r.i-16) & 0xf];223 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
214 s[r.i & 0xf] = math.rotl(u32, t, u32(1));224 s[r.i & 0xf] = math.rotl(u32, t, u32(1));
215225
216 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x8F1BBCDC +% s[r.i & 0xf]226 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x8F1BBCDC +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) ^ (v[r.b] & v[r.d]) ^ (v[r.c] & v[r.d]));
217 +% ((v[r.b] & v[r.c]) ^ (v[r.b] & v[r.d]) ^ (v[r.c] & v[r.d]));
218 v[r.b] = math.rotl(u32, v[r.b], u32(30));227 v[r.b] = math.rotl(u32, v[r.b], u32(30));
219 }228 }
220229
221 const round3 = comptime []RoundParam {230 const round3 = comptime []RoundParam{
222 Rp(0, 1, 2, 3, 4, 60),231 Rp(0, 1, 2, 3, 4, 60),
223 Rp(4, 0, 1, 2, 3, 61),232 Rp(4, 0, 1, 2, 3, 61),
224 Rp(3, 4, 0, 1, 2, 62),233 Rp(3, 4, 0, 1, 2, 62),
...@@ -241,11 +250,10 @@ pub const Sha1 = struct {...@@ -241,11 +250,10 @@ pub const Sha1 = struct {
241 Rp(1, 2, 3, 4, 0, 79),250 Rp(1, 2, 3, 4, 0, 79),
242 };251 };
243 inline for (round3) |r| {252 inline for (round3) |r| {
244 const t = s[(r.i-3) & 0xf] ^ s[(r.i-8) & 0xf] ^ s[(r.i-14) & 0xf] ^ s[(r.i-16) & 0xf];253 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
245 s[r.i & 0xf] = math.rotl(u32, t, u32(1));254 s[r.i & 0xf] = math.rotl(u32, t, u32(1));
246255
247 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0xCA62C1D6 +% s[r.i & 0xf]256 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0xCA62C1D6 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);
248 +% (v[r.b] ^ v[r.c] ^ v[r.d]);
249 v[r.b] = math.rotl(u32, v[r.b], u32(30));257 v[r.b] = math.rotl(u32, v[r.b], u32(30));
250 }258 }
251259
...@@ -286,7 +294,7 @@ test "sha1 streaming" {...@@ -286,7 +294,7 @@ test "sha1 streaming" {
286}294}
287295
288test "sha1 aligned final" {296test "sha1 aligned final" {
289 var block = []u8 {0} ** Sha1.block_size;297 var block = []u8{0} ** Sha1.block_size;
290 var out: [Sha1.digest_size]u8 = undefined;298 var out: [Sha1.digest_size]u8 = undefined;
291299
292 var h = Sha1.init();300 var h = Sha1.init();
std/crypto/sha2.zig+448-413
...@@ -9,12 +9,31 @@ const htest = @import("test.zig");...@@ -9,12 +9,31 @@ const htest = @import("test.zig");
9// Sha224 + Sha2569// Sha224 + Sha256
1010
11const RoundParam256 = struct {11const RoundParam256 = struct {
12 a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize,12 a: usize,
13 i: usize, k: u32,13 b: usize,
14 c: usize,
15 d: usize,
16 e: usize,
17 f: usize,
18 g: usize,
19 h: usize,
20 i: usize,
21 k: u32,
14};22};
1523
16fn Rp256(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u32) RoundParam256 {24fn Rp256(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u32) RoundParam256 {
17 return RoundParam256 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };25 return RoundParam256{
26 .a = a,
27 .b = b,
28 .c = c,
29 .d = d,
30 .e = e,
31 .f = f,
32 .g = g,
33 .h = h,
34 .i = i,
35 .k = k,
36 };
18}37}
1938
20const Sha2Params32 = struct {39const Sha2Params32 = struct {
...@@ -29,7 +48,7 @@ const Sha2Params32 = struct {...@@ -29,7 +48,7 @@ const Sha2Params32 = struct {
29 out_len: usize,48 out_len: usize,
30};49};
3150
32const Sha224Params = Sha2Params32 {51const Sha224Params = Sha2Params32{
33 .iv0 = 0xC1059ED8,52 .iv0 = 0xC1059ED8,
34 .iv1 = 0x367CD507,53 .iv1 = 0x367CD507,
35 .iv2 = 0x3070DD17,54 .iv2 = 0x3070DD17,
...@@ -41,7 +60,7 @@ const Sha224Params = Sha2Params32 {...@@ -41,7 +60,7 @@ const Sha224Params = Sha2Params32 {
41 .out_len = 224,60 .out_len = 224,
42};61};
4362
44const Sha256Params = Sha2Params32 {63const Sha256Params = Sha2Params32{
45 .iv0 = 0x6A09E667,64 .iv0 = 0x6A09E667,
46 .iv1 = 0xBB67AE85,65 .iv1 = 0xBB67AE85,
47 .iv2 = 0x3C6EF372,66 .iv2 = 0x3C6EF372,
...@@ -56,216 +75,215 @@ const Sha256Params = Sha2Params32 {...@@ -56,216 +75,215 @@ const Sha256Params = Sha2Params32 {
56pub const Sha224 = Sha2_32(Sha224Params);75pub const Sha224 = Sha2_32(Sha224Params);
57pub const Sha256 = Sha2_32(Sha256Params);76pub const Sha256 = Sha2_32(Sha256Params);
5877
59fn Sha2_32(comptime params: Sha2Params32) type { return struct {78fn Sha2_32(comptime params: Sha2Params32) type {
60 const Self = this;79 return struct {
61 const block_size = 64;80 const Self = this;
62 const digest_size = params.out_len / 8;81 const block_size = 64;
6382 const digest_size = params.out_len / 8;
64 s: [8]u32,83
65 // Streaming Cache84 s: [8]u32,
66 buf: [64]u8,85 // Streaming Cache
67 buf_len: u8,86 buf: [64]u8,
68 total_len: u64,87 buf_len: u8,
6988 total_len: u64,
70 pub fn init() Self {89
71 var d: Self = undefined;90 pub fn init() Self {
72 d.reset();91 var d: Self = undefined;
73 return d;92 d.reset();
74 }93 return d;
7594 }
76 pub fn reset(d: &Self) void {
77 d.s[0] = params.iv0;
78 d.s[1] = params.iv1;
79 d.s[2] = params.iv2;
80 d.s[3] = params.iv3;
81 d.s[4] = params.iv4;
82 d.s[5] = params.iv5;
83 d.s[6] = params.iv6;
84 d.s[7] = params.iv7;
85 d.buf_len = 0;
86 d.total_len = 0;
87 }
88
89 pub fn hash(b: []const u8, out: []u8) void {
90 var d = Self.init();
91 d.update(b);
92 d.final(out);
93 }
94
95 pub fn update(d: &Self, b: []const u8) void {
96 var off: usize = 0;
97
98 // Partial buffer exists from previous update. Copy into buffer then hash.
99 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
100 off += 64 - d.buf_len;
101 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
10295
103 d.round(d.buf[0..]);96 pub fn reset(d: &Self) void {
97 d.s[0] = params.iv0;
98 d.s[1] = params.iv1;
99 d.s[2] = params.iv2;
100 d.s[3] = params.iv3;
101 d.s[4] = params.iv4;
102 d.s[5] = params.iv5;
103 d.s[6] = params.iv6;
104 d.s[7] = params.iv7;
104 d.buf_len = 0;105 d.buf_len = 0;
106 d.total_len = 0;
105 }107 }
106108
107 // Full middle blocks.109 pub fn hash(b: []const u8, out: []u8) void {
108 while (off + 64 <= b.len) : (off += 64) {110 var d = Self.init();
109 d.round(b[off..off + 64]);111 d.update(b);
112 d.final(out);
110 }113 }
111114
112 // Copy any remainder for next pass.115 pub fn update(d: &Self, b: []const u8) void {
113 mem.copy(u8, d.buf[d.buf_len..], b[off..]);116 var off: usize = 0;
114 d.buf_len += u8(b[off..].len);
115117
116 d.total_len += b.len;118 // Partial buffer exists from previous update. Copy into buffer then hash.
117 }119 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
120 off += 64 - d.buf_len;
121 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
118122
119 pub fn final(d: &Self, out: []u8) void {123 d.round(d.buf[0..]);
120 debug.assert(out.len >= params.out_len / 8);124 d.buf_len = 0;
125 }
121126
122 // The buffer here will never be completely full.127 // Full middle blocks.
123 mem.set(u8, d.buf[d.buf_len..], 0);128 while (off + 64 <= b.len) : (off += 64) {
129 d.round(b[off..off + 64]);
130 }
124131
125 // Append padding bits.132 // Copy any remainder for next pass.
126 d.buf[d.buf_len] = 0x80;133 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
127 d.buf_len += 1;134 d.buf_len += u8(b[off..].len);
128135
129 // > 448 mod 512 so need to add an extra round to wrap around.136 d.total_len += b.len;
130 if (64 - d.buf_len < 8) {
131 d.round(d.buf[0..]);
132 mem.set(u8, d.buf[0..], 0);
133 }137 }
134138
135 // Append message length.139 pub fn final(d: &Self, out: []u8) void {
136 var i: usize = 1;140 debug.assert(out.len >= params.out_len / 8);
137 var len = d.total_len >> 5;
138 d.buf[63] = u8(d.total_len & 0x1f) << 3;
139 while (i < 8) : (i += 1) {
140 d.buf[63 - i] = u8(len & 0xff);
141 len >>= 8;
142 }
143141
144 d.round(d.buf[0..]);142 // The buffer here will never be completely full.
143 mem.set(u8, d.buf[d.buf_len..], 0);
145144
146 // May truncate for possible 224 output145 // Append padding bits.
147 const rr = d.s[0 .. params.out_len / 32];146 d.buf[d.buf_len] = 0x80;
147 d.buf_len += 1;
148148
149 for (rr) |s, j| {149 // > 448 mod 512 so need to add an extra round to wrap around.
150 mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Big);150 if (64 - d.buf_len < 8) {
151 }151 d.round(d.buf[0..]);
152 }152 mem.set(u8, d.buf[0..], 0);
153 }
154
155 // Append message length.
156 var i: usize = 1;
157 var len = d.total_len >> 5;
158 d.buf[63] = u8(d.total_len & 0x1f) << 3;
159 while (i < 8) : (i += 1) {
160 d.buf[63 - i] = u8(len & 0xff);
161 len >>= 8;
162 }
153163
154 fn round(d: &Self, b: []const u8) void {164 d.round(d.buf[0..]);
155 debug.assert(b.len == 64);
156165
157 var s: [64]u32 = undefined;166 // May truncate for possible 224 output
167 const rr = d.s[0..params.out_len / 32];
158168
159 var i: usize = 0;169 for (rr) |s, j| {
160 while (i < 16) : (i += 1) {170 mem.writeInt(out[4 * j..4 * j + 4], s, builtin.Endian.Big);
161 s[i] = 0;171 }
162 s[i] |= u32(b[i*4+0]) << 24;
163 s[i] |= u32(b[i*4+1]) << 16;
164 s[i] |= u32(b[i*4+2]) << 8;
165 s[i] |= u32(b[i*4+3]) << 0;
166 }
167 while (i < 64) : (i += 1) {
168 s[i] =
169 s[i-16] +% s[i-7] +%
170 (math.rotr(u32, s[i-15], u32(7)) ^ math.rotr(u32, s[i-15], u32(18)) ^ (s[i-15] >> 3)) +%
171 (math.rotr(u32, s[i-2], u32(17)) ^ math.rotr(u32, s[i-2], u32(19)) ^ (s[i-2] >> 10));
172 }172 }
173173
174 var v: [8]u32 = []u32 {174 fn round(d: &Self, b: []const u8) void {
175 d.s[0], d.s[1], d.s[2], d.s[3], d.s[4], d.s[5], d.s[6], d.s[7],175 debug.assert(b.len == 64);
176 };176
177177 var s: [64]u32 = undefined;
178 const round0 = comptime []RoundParam256 {178
179 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98),179 var i: usize = 0;
180 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x71374491),180 while (i < 16) : (i += 1) {
181 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCF),181 s[i] = 0;
182 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA5),182 s[i] |= u32(b[i * 4 + 0]) << 24;
183 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25B),183 s[i] |= u32(b[i * 4 + 1]) << 16;
184 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1),184 s[i] |= u32(b[i * 4 + 2]) << 8;
185 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4),185 s[i] |= u32(b[i * 4 + 3]) << 0;
186 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5),186 }
187 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98),187 while (i < 64) : (i += 1) {
188 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B01),188 s[i] = s[i - 16] +% s[i - 7] +% (math.rotr(u32, s[i - 15], u32(7)) ^ math.rotr(u32, s[i - 15], u32(18)) ^ (s[i - 15] >> 3)) +% (math.rotr(u32, s[i - 2], u32(17)) ^ math.rotr(u32, s[i - 2], u32(19)) ^ (s[i - 2] >> 10));
189 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE),189 }
190 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3),190
191 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74),191 var v: [8]u32 = []u32{
192 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE),192 d.s[0],
193 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A7),193 d.s[1],
194 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174),194 d.s[2],
195 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C1),195 d.s[3],
196 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786),196 d.s[4],
197 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC6),197 d.s[5],
198 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC),198 d.s[6],
199 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F),199 d.s[7],
200 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA),200 };
201 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DC),201
202 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA),202 const round0 = comptime []RoundParam256{
203 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152),203 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98),
204 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D),204 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x71374491),
205 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C8),205 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCF),
206 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7),206 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA5),
207 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF3),207 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25B),
208 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147),208 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1),
209 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351),209 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4),
210 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x14292967),210 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5),
211 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A85),211 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98),
212 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B2138),212 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B01),
213 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC),213 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE),
214 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D13),214 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3),
215 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A7354),215 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74),
216 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB),216 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE),
217 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E),217 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A7),
218 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C85),218 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174),
219 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A1),219 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C1),
220 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664B),220 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786),
221 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70),221 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC6),
222 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A3),222 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC),
223 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819),223 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F),
224 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD6990624),224 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA),
225 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E3585),225 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DC),
226 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA070),226 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA),
227 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116),227 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152),
228 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C08),228 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D),
229 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774C),229 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C8),
230 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5),230 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7),
231 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3),231 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF3),
232 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4A),232 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147),
233 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F),233 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351),
234 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3),234 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x14292967),
235 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE),235 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A85),
236 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F),236 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B2138),
237 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814),237 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC),
238 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC70208),238 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D13),
239 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA),239 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A7354),
240 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEB),240 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB),
241 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7),241 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E),
242 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2),242 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C85),
243 };243 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A1),
244 inline for (round0) |r| {244 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664B),
245 v[r.h] =245 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70),
246 v[r.h] +%246 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A3),
247 (math.rotr(u32, v[r.e], u32(6)) ^ math.rotr(u32, v[r.e], u32(11)) ^ math.rotr(u32, v[r.e], u32(25))) +%247 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819),
248 (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +%248 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD6990624),
249 r.k +% s[r.i];249 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E3585),
250250 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA070),
251 v[r.d] = v[r.d] +% v[r.h];251 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116),
252252 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C08),
253 v[r.h] =253 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774C),
254 v[r.h] +%254 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5),
255 (math.rotr(u32, v[r.a], u32(2)) ^ math.rotr(u32, v[r.a], u32(13)) ^ math.rotr(u32, v[r.a], u32(22))) +%255 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3),
256 ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));256 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4A),
257 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F),
258 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3),
259 Rp256(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE),
260 Rp256(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F),
261 Rp256(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814),
262 Rp256(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC70208),
263 Rp256(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA),
264 Rp256(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEB),
265 Rp256(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7),
266 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2),
267 };
268 inline for (round0) |r| {
269 v[r.h] = v[r.h] +% (math.rotr(u32, v[r.e], u32(6)) ^ math.rotr(u32, v[r.e], u32(11)) ^ math.rotr(u32, v[r.e], u32(25))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];
270
271 v[r.d] = v[r.d] +% v[r.h];
272
273 v[r.h] = v[r.h] +% (math.rotr(u32, v[r.a], u32(2)) ^ math.rotr(u32, v[r.a], u32(13)) ^ math.rotr(u32, v[r.a], u32(22))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));
274 }
275
276 d.s[0] +%= v[0];
277 d.s[1] +%= v[1];
278 d.s[2] +%= v[2];
279 d.s[3] +%= v[3];
280 d.s[4] +%= v[4];
281 d.s[5] +%= v[5];
282 d.s[6] +%= v[6];
283 d.s[7] +%= v[7];
257 }284 }
258285 };
259 d.s[0] +%= v[0];286}
260 d.s[1] +%= v[1];
261 d.s[2] +%= v[2];
262 d.s[3] +%= v[3];
263 d.s[4] +%= v[4];
264 d.s[5] +%= v[5];
265 d.s[6] +%= v[6];
266 d.s[7] +%= v[7];
267 }
268};}
269287
270test "sha224 single" {288test "sha224 single" {
271 htest.assertEqualHash(Sha224, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "");289 htest.assertEqualHash(Sha224, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "");
...@@ -320,7 +338,7 @@ test "sha256 streaming" {...@@ -320,7 +338,7 @@ test "sha256 streaming" {
320}338}
321339
322test "sha256 aligned final" {340test "sha256 aligned final" {
323 var block = []u8 {0} ** Sha256.block_size;341 var block = []u8{0} ** Sha256.block_size;
324 var out: [Sha256.digest_size]u8 = undefined;342 var out: [Sha256.digest_size]u8 = undefined;
325343
326 var h = Sha256.init();344 var h = Sha256.init();
...@@ -328,17 +346,35 @@ test "sha256 aligned final" {...@@ -328,17 +346,35 @@ test "sha256 aligned final" {
328 h.final(out[0..]);346 h.final(out[0..]);
329}347}
330348
331
332/////////////////////349/////////////////////
333// Sha384 + Sha512350// Sha384 + Sha512
334351
335const RoundParam512 = struct {352const RoundParam512 = struct {
336 a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize,353 a: usize,
337 i: usize, k: u64,354 b: usize,
355 c: usize,
356 d: usize,
357 e: usize,
358 f: usize,
359 g: usize,
360 h: usize,
361 i: usize,
362 k: u64,
338};363};
339364
340fn Rp512(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u64) RoundParam512 {365fn Rp512(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u64) RoundParam512 {
341 return RoundParam512 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };366 return RoundParam512{
367 .a = a,
368 .b = b,
369 .c = c,
370 .d = d,
371 .e = e,
372 .f = f,
373 .g = g,
374 .h = h,
375 .i = i,
376 .k = k,
377 };
342}378}
343379
344const Sha2Params64 = struct {380const Sha2Params64 = struct {
...@@ -353,7 +389,7 @@ const Sha2Params64 = struct {...@@ -353,7 +389,7 @@ const Sha2Params64 = struct {
353 out_len: usize,389 out_len: usize,
354};390};
355391
356const Sha384Params = Sha2Params64 {392const Sha384Params = Sha2Params64{
357 .iv0 = 0xCBBB9D5DC1059ED8,393 .iv0 = 0xCBBB9D5DC1059ED8,
358 .iv1 = 0x629A292A367CD507,394 .iv1 = 0x629A292A367CD507,
359 .iv2 = 0x9159015A3070DD17,395 .iv2 = 0x9159015A3070DD17,
...@@ -365,7 +401,7 @@ const Sha384Params = Sha2Params64 {...@@ -365,7 +401,7 @@ const Sha384Params = Sha2Params64 {
365 .out_len = 384,401 .out_len = 384,
366};402};
367403
368const Sha512Params = Sha2Params64 {404const Sha512Params = Sha2Params64{
369 .iv0 = 0x6A09E667F3BCC908,405 .iv0 = 0x6A09E667F3BCC908,
370 .iv1 = 0xBB67AE8584CAA73B,406 .iv1 = 0xBB67AE8584CAA73B,
371 .iv2 = 0x3C6EF372FE94F82B,407 .iv2 = 0x3C6EF372FE94F82B,
...@@ -374,242 +410,241 @@ const Sha512Params = Sha2Params64 {...@@ -374,242 +410,241 @@ const Sha512Params = Sha2Params64 {
374 .iv5 = 0x9B05688C2B3E6C1F,410 .iv5 = 0x9B05688C2B3E6C1F,
375 .iv6 = 0x1F83D9ABFB41BD6B,411 .iv6 = 0x1F83D9ABFB41BD6B,
376 .iv7 = 0x5BE0CD19137E2179,412 .iv7 = 0x5BE0CD19137E2179,
377 .out_len = 512413 .out_len = 512,
378};414};
379415
380pub const Sha384 = Sha2_64(Sha384Params);416pub const Sha384 = Sha2_64(Sha384Params);
381pub const Sha512 = Sha2_64(Sha512Params);417pub const Sha512 = Sha2_64(Sha512Params);
382418
383fn Sha2_64(comptime params: Sha2Params64) type { return struct {419fn Sha2_64(comptime params: Sha2Params64) type {
384 const Self = this;420 return struct {
385 const block_size = 128;421 const Self = this;
386 const digest_size = params.out_len / 8;422 const block_size = 128;
387423 const digest_size = params.out_len / 8;
388 s: [8]u64,424
389 // Streaming Cache425 s: [8]u64,
390 buf: [128]u8,426 // Streaming Cache
391 buf_len: u8,427 buf: [128]u8,
392 total_len: u128,428 buf_len: u8,
393429 total_len: u128,
394 pub fn init() Self {430
395 var d: Self = undefined;431 pub fn init() Self {
396 d.reset();432 var d: Self = undefined;
397 return d;433 d.reset();
398 }434 return d;
399435 }
400 pub fn reset(d: &Self) void {
401 d.s[0] = params.iv0;
402 d.s[1] = params.iv1;
403 d.s[2] = params.iv2;
404 d.s[3] = params.iv3;
405 d.s[4] = params.iv4;
406 d.s[5] = params.iv5;
407 d.s[6] = params.iv6;
408 d.s[7] = params.iv7;
409 d.buf_len = 0;
410 d.total_len = 0;
411 }
412
413 pub fn hash(b: []const u8, out: []u8) void {
414 var d = Self.init();
415 d.update(b);
416 d.final(out);
417 }
418
419 pub fn update(d: &Self, b: []const u8) void {
420 var off: usize = 0;
421
422 // Partial buffer exists from previous update. Copy into buffer then hash.
423 if (d.buf_len != 0 and d.buf_len + b.len > 128) {
424 off += 128 - d.buf_len;
425 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
426436
427 d.round(d.buf[0..]);437 pub fn reset(d: &Self) void {
438 d.s[0] = params.iv0;
439 d.s[1] = params.iv1;
440 d.s[2] = params.iv2;
441 d.s[3] = params.iv3;
442 d.s[4] = params.iv4;
443 d.s[5] = params.iv5;
444 d.s[6] = params.iv6;
445 d.s[7] = params.iv7;
428 d.buf_len = 0;446 d.buf_len = 0;
447 d.total_len = 0;
429 }448 }
430449
431 // Full middle blocks.450 pub fn hash(b: []const u8, out: []u8) void {
432 while (off + 128 <= b.len) : (off += 128) {451 var d = Self.init();
433 d.round(b[off..off + 128]);452 d.update(b);
453 d.final(out);
434 }454 }
435455
436 // Copy any remainder for next pass.456 pub fn update(d: &Self, b: []const u8) void {
437 mem.copy(u8, d.buf[d.buf_len..], b[off..]);457 var off: usize = 0;
438 d.buf_len += u8(b[off..].len);
439458
440 d.total_len += b.len;459 // Partial buffer exists from previous update. Copy into buffer then hash.
441 }460 if (d.buf_len != 0 and d.buf_len + b.len > 128) {
461 off += 128 - d.buf_len;
462 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
442463
443 pub fn final(d: &Self, out: []u8) void {464 d.round(d.buf[0..]);
444 debug.assert(out.len >= params.out_len / 8);465 d.buf_len = 0;
466 }
445467
446 // The buffer here will never be completely full.468 // Full middle blocks.
447 mem.set(u8, d.buf[d.buf_len..], 0);469 while (off + 128 <= b.len) : (off += 128) {
470 d.round(b[off..off + 128]);
471 }
448472
449 // Append padding bits.473 // Copy any remainder for next pass.
450 d.buf[d.buf_len] = 0x80;474 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
451 d.buf_len += 1;475 d.buf_len += u8(b[off..].len);
452476
453 // > 896 mod 1024 so need to add an extra round to wrap around.477 d.total_len += b.len;
454 if (128 - d.buf_len < 16) {
455 d.round(d.buf[0..]);
456 mem.set(u8, d.buf[0..], 0);
457 }478 }
458479
459 // Append message length.480 pub fn final(d: &Self, out: []u8) void {
460 var i: usize = 1;481 debug.assert(out.len >= params.out_len / 8);
461 var len = d.total_len >> 5;
462 d.buf[127] = u8(d.total_len & 0x1f) << 3;
463 while (i < 16) : (i += 1) {
464 d.buf[127 - i] = u8(len & 0xff);
465 len >>= 8;
466 }
467482
468 d.round(d.buf[0..]);483 // The buffer here will never be completely full.
484 mem.set(u8, d.buf[d.buf_len..], 0);
469485
470 // May truncate for possible 384 output486 // Append padding bits.
471 const rr = d.s[0 .. params.out_len / 64];487 d.buf[d.buf_len] = 0x80;
488 d.buf_len += 1;
472489
473 for (rr) |s, j| {490 // > 896 mod 1024 so need to add an extra round to wrap around.
474 mem.writeInt(out[8*j .. 8*j + 8], s, builtin.Endian.Big);491 if (128 - d.buf_len < 16) {
475 }492 d.round(d.buf[0..]);
476 }493 mem.set(u8, d.buf[0..], 0);
477494 }
478 fn round(d: &Self, b: []const u8) void {
479 debug.assert(b.len == 128);
480
481 var s: [80]u64 = undefined;
482
483 var i: usize = 0;
484 while (i < 16) : (i += 1) {
485 s[i] = 0;
486 s[i] |= u64(b[i*8+0]) << 56;
487 s[i] |= u64(b[i*8+1]) << 48;
488 s[i] |= u64(b[i*8+2]) << 40;
489 s[i] |= u64(b[i*8+3]) << 32;
490 s[i] |= u64(b[i*8+4]) << 24;
491 s[i] |= u64(b[i*8+5]) << 16;
492 s[i] |= u64(b[i*8+6]) << 8;
493 s[i] |= u64(b[i*8+7]) << 0;
494 }
495 while (i < 80) : (i += 1) {
496 s[i] =
497 s[i-16] +% s[i-7] +%
498 (math.rotr(u64, s[i-15], u64(1)) ^ math.rotr(u64, s[i-15], u64(8)) ^ (s[i-15] >> 7)) +%
499 (math.rotr(u64, s[i-2], u64(19)) ^ math.rotr(u64, s[i-2], u64(61)) ^ (s[i-2] >> 6));
500 }
501495
502 var v: [8]u64 = []u64 {496 // Append message length.
503 d.s[0], d.s[1], d.s[2], d.s[3], d.s[4], d.s[5], d.s[6], d.s[7],497 var i: usize = 1;
504 };498 var len = d.total_len >> 5;
505499 d.buf[127] = u8(d.total_len & 0x1f) << 3;
506 const round0 = comptime []RoundParam512 {500 while (i < 16) : (i += 1) {
507 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98D728AE22),501 d.buf[127 - i] = u8(len & 0xff);
508 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x7137449123EF65CD),502 len >>= 8;
509 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCFEC4D3B2F),503 }
510 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA58189DBBC),504
511 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25BF348B538),505 d.round(d.buf[0..]);
512 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1B605D019),506
513 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4AF194F9B),507 // May truncate for possible 384 output
514 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5DA6D8118),508 const rr = d.s[0..params.out_len / 64];
515 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98A3030242),509
516 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B0145706FBE),510 for (rr) |s, j| {
517 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE4EE4B28C),511 mem.writeInt(out[8 * j..8 * j + 8], s, builtin.Endian.Big);
518 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3D5FFB4E2),512 }
519 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74F27B896F),
520 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE3B1696B1),
521 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A725C71235),
522 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174CF692694),
523 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C19EF14AD2),
524 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786384F25E3),
525 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC68B8CD5B5),
526 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC77AC9C65),
527 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F592B0275),
528 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA6EA6E483),
529 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DCBD41FBD4),
530 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA831153B5),
531 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152EE66DFAB),
532 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D2DB43210),
533 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C898FB213F),
534 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7BEEF0EE4),
535 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF33DA88FC2),
536 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147930AA725),
537 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351E003826F),
538 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x142929670A0E6E70),
539 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A8546D22FFC),
540 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B21385C26C926),
541 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC5AC42AED),
542 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D139D95B3DF),
543 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A73548BAF63DE),
544 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB3C77B2A8),
545 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E47EDAEE6),
546 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C851482353B),
547 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A14CF10364),
548 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664BBC423001),
549 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70D0F89791),
550 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A30654BE30),
551 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819D6EF5218),
552 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD69906245565A910),
553 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E35855771202A),
554 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA07032BBD1B8),
555 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116B8D2D0C8),
556 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C085141AB53),
557 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774CDF8EEB99),
558 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5E19B48A8),
559 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3C5C95A63),
560 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4AE3418ACB),
561 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F7763E373),
562 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3D6B2B8A3),
563 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE5DEFB2FC),
564 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F43172F60),
565 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814A1F0AB72),
566 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC702081A6439EC),
567 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA23631E28),
568 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEBDE82BDE9),
569 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7B2C67915),
570 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2E372532B),
571 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 64, 0xCA273ECEEA26619C),
572 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 65, 0xD186B8C721C0C207),
573 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 66, 0xEADA7DD6CDE0EB1E),
574 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 67, 0xF57D4F7FEE6ED178),
575 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 68, 0x06F067AA72176FBA),
576 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 69, 0x0A637DC5A2C898A6),
577 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 70, 0x113F9804BEF90DAE),
578 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 71, 0x1B710B35131C471B),
579 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 72, 0x28DB77F523047D84),
580 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 73, 0x32CAAB7B40C72493),
581 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 74, 0x3C9EBE0A15C9BEBC),
582 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 75, 0x431D67C49C100D4C),
583 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 76, 0x4CC5D4BECB3E42B6),
584 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 77, 0x597F299CFC657E2A),
585 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 78, 0x5FCB6FAB3AD6FAEC),
586 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 79, 0x6C44198C4A475817),
587 };
588 inline for (round0) |r| {
589 v[r.h] =
590 v[r.h] +%
591 (math.rotr(u64, v[r.e], u64(14)) ^ math.rotr(u64, v[r.e], u64(18)) ^ math.rotr(u64, v[r.e], u64(41))) +%
592 (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +%
593 r.k +% s[r.i];
594
595 v[r.d] = v[r.d] +% v[r.h];
596
597 v[r.h] =
598 v[r.h] +%
599 (math.rotr(u64, v[r.a], u64(28)) ^ math.rotr(u64, v[r.a], u64(34)) ^ math.rotr(u64, v[r.a], u64(39))) +%
600 ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));
601 }513 }
602514
603 d.s[0] +%= v[0];515 fn round(d: &Self, b: []const u8) void {
604 d.s[1] +%= v[1];516 debug.assert(b.len == 128);
605 d.s[2] +%= v[2];517
606 d.s[3] +%= v[3];518 var s: [80]u64 = undefined;
607 d.s[4] +%= v[4];519
608 d.s[5] +%= v[5];520 var i: usize = 0;
609 d.s[6] +%= v[6];521 while (i < 16) : (i += 1) {
610 d.s[7] +%= v[7];522 s[i] = 0;
611 }523 s[i] |= u64(b[i * 8 + 0]) << 56;
612};}524 s[i] |= u64(b[i * 8 + 1]) << 48;
525 s[i] |= u64(b[i * 8 + 2]) << 40;
526 s[i] |= u64(b[i * 8 + 3]) << 32;
527 s[i] |= u64(b[i * 8 + 4]) << 24;
528 s[i] |= u64(b[i * 8 + 5]) << 16;
529 s[i] |= u64(b[i * 8 + 6]) << 8;
530 s[i] |= u64(b[i * 8 + 7]) << 0;
531 }
532 while (i < 80) : (i += 1) {
533 s[i] = s[i - 16] +% s[i - 7] +% (math.rotr(u64, s[i - 15], u64(1)) ^ math.rotr(u64, s[i - 15], u64(8)) ^ (s[i - 15] >> 7)) +% (math.rotr(u64, s[i - 2], u64(19)) ^ math.rotr(u64, s[i - 2], u64(61)) ^ (s[i - 2] >> 6));
534 }
535
536 var v: [8]u64 = []u64{
537 d.s[0],
538 d.s[1],
539 d.s[2],
540 d.s[3],
541 d.s[4],
542 d.s[5],
543 d.s[6],
544 d.s[7],
545 };
546
547 const round0 = comptime []RoundParam512{
548 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98D728AE22),
549 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x7137449123EF65CD),
550 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCFEC4D3B2F),
551 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA58189DBBC),
552 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25BF348B538),
553 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1B605D019),
554 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4AF194F9B),
555 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5DA6D8118),
556 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98A3030242),
557 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B0145706FBE),
558 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE4EE4B28C),
559 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3D5FFB4E2),
560 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74F27B896F),
561 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE3B1696B1),
562 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A725C71235),
563 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174CF692694),
564 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C19EF14AD2),
565 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786384F25E3),
566 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC68B8CD5B5),
567 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC77AC9C65),
568 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F592B0275),
569 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA6EA6E483),
570 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DCBD41FBD4),
571 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA831153B5),
572 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152EE66DFAB),
573 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D2DB43210),
574 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C898FB213F),
575 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7BEEF0EE4),
576 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF33DA88FC2),
577 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147930AA725),
578 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351E003826F),
579 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x142929670A0E6E70),
580 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A8546D22FFC),
581 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B21385C26C926),
582 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC5AC42AED),
583 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D139D95B3DF),
584 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A73548BAF63DE),
585 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB3C77B2A8),
586 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E47EDAEE6),
587 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C851482353B),
588 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A14CF10364),
589 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664BBC423001),
590 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70D0F89791),
591 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A30654BE30),
592 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819D6EF5218),
593 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD69906245565A910),
594 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E35855771202A),
595 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA07032BBD1B8),
596 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116B8D2D0C8),
597 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C085141AB53),
598 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774CDF8EEB99),
599 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5E19B48A8),
600 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3C5C95A63),
601 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4AE3418ACB),
602 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F7763E373),
603 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3D6B2B8A3),
604 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE5DEFB2FC),
605 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F43172F60),
606 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814A1F0AB72),
607 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC702081A6439EC),
608 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA23631E28),
609 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEBDE82BDE9),
610 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7B2C67915),
611 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2E372532B),
612 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 64, 0xCA273ECEEA26619C),
613 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 65, 0xD186B8C721C0C207),
614 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 66, 0xEADA7DD6CDE0EB1E),
615 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 67, 0xF57D4F7FEE6ED178),
616 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 68, 0x06F067AA72176FBA),
617 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 69, 0x0A637DC5A2C898A6),
618 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 70, 0x113F9804BEF90DAE),
619 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 71, 0x1B710B35131C471B),
620 Rp512(0, 1, 2, 3, 4, 5, 6, 7, 72, 0x28DB77F523047D84),
621 Rp512(7, 0, 1, 2, 3, 4, 5, 6, 73, 0x32CAAB7B40C72493),
622 Rp512(6, 7, 0, 1, 2, 3, 4, 5, 74, 0x3C9EBE0A15C9BEBC),
623 Rp512(5, 6, 7, 0, 1, 2, 3, 4, 75, 0x431D67C49C100D4C),
624 Rp512(4, 5, 6, 7, 0, 1, 2, 3, 76, 0x4CC5D4BECB3E42B6),
625 Rp512(3, 4, 5, 6, 7, 0, 1, 2, 77, 0x597F299CFC657E2A),
626 Rp512(2, 3, 4, 5, 6, 7, 0, 1, 78, 0x5FCB6FAB3AD6FAEC),
627 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 79, 0x6C44198C4A475817),
628 };
629 inline for (round0) |r| {
630 v[r.h] = v[r.h] +% (math.rotr(u64, v[r.e], u64(14)) ^ math.rotr(u64, v[r.e], u64(18)) ^ math.rotr(u64, v[r.e], u64(41))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];
631
632 v[r.d] = v[r.d] +% v[r.h];
633
634 v[r.h] = v[r.h] +% (math.rotr(u64, v[r.a], u64(28)) ^ math.rotr(u64, v[r.a], u64(34)) ^ math.rotr(u64, v[r.a], u64(39))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));
635 }
636
637 d.s[0] +%= v[0];
638 d.s[1] +%= v[1];
639 d.s[2] +%= v[2];
640 d.s[3] +%= v[3];
641 d.s[4] +%= v[4];
642 d.s[5] +%= v[5];
643 d.s[6] +%= v[6];
644 d.s[7] +%= v[7];
645 }
646 };
647}
613648
614test "sha384 single" {649test "sha384 single" {
615 const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";650 const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";
...@@ -680,7 +715,7 @@ test "sha512 streaming" {...@@ -680,7 +715,7 @@ test "sha512 streaming" {
680}715}
681716
682test "sha512 aligned final" {717test "sha512 aligned final" {
683 var block = []u8 {0} ** Sha512.block_size;718 var block = []u8{0} ** Sha512.block_size;
684 var out: [Sha512.digest_size]u8 = undefined;719 var out: [Sha512.digest_size]u8 = undefined;
685720
686 var h = Sha512.init();721 var h = Sha512.init();
std/crypto/sha3.zig+180-101
...@@ -10,148 +10,228 @@ pub const Sha3_256 = Keccak(256, 0x06);...@@ -10,148 +10,228 @@ pub const Sha3_256 = Keccak(256, 0x06);
10pub const Sha3_384 = Keccak(384, 0x06);10pub const Sha3_384 = Keccak(384, 0x06);
11pub const Sha3_512 = Keccak(512, 0x06);11pub const Sha3_512 = Keccak(512, 0x06);
1212
13fn Keccak(comptime bits: usize, comptime delim: u8) type { return struct {13fn Keccak(comptime bits: usize, comptime delim: u8) type {
14 const Self = this;14 return struct {
15 const block_size = 200;15 const Self = this;
16 const digest_size = bits / 8;16 const block_size = 200;
1717 const digest_size = bits / 8;
18 s: [200]u8,18
19 offset: usize,19 s: [200]u8,
20 rate: usize,20 offset: usize,
2121 rate: usize,
22 pub fn init() Self {22
23 var d: Self = undefined;23 pub fn init() Self {
24 d.reset();24 var d: Self = undefined;
25 return d;25 d.reset();
26 }26 return d;
27 }
2728
28 pub fn reset(d: &Self) void {29 pub fn reset(d: &Self) void {
29 mem.set(u8, d.s[0..], 0);30 mem.set(u8, d.s[0..], 0);
30 d.offset = 0;31 d.offset = 0;
31 d.rate = 200 - (bits / 4);32 d.rate = 200 - (bits / 4);
32 }33 }
3334
34 pub fn hash(b: []const u8, out: []u8) void {35 pub fn hash(b: []const u8, out: []u8) void {
35 var d = Self.init();36 var d = Self.init();
36 d.update(b);37 d.update(b);
37 d.final(out);38 d.final(out);
38 }39 }
3940
40 pub fn update(d: &Self, b: []const u8) void {41 pub fn update(d: &Self, b: []const u8) void {
41 var ip: usize = 0;42 var ip: usize = 0;
42 var len = b.len;43 var len = b.len;
43 var rate = d.rate - d.offset;44 var rate = d.rate - d.offset;
44 var offset = d.offset;45 var offset = d.offset;
4546
46 // absorb47 // absorb
47 while (len >= rate) {48 while (len >= rate) {
48 for (d.s[offset .. offset + rate]) |*r, i|49 for (d.s[offset..offset + rate]) |*r, i|
49 *r ^= b[ip..][i];50 r.* ^= b[ip..][i];
5051
51 keccak_f(1600, d.s[0..]);52 keccak_f(1600, d.s[0..]);
5253
53 ip += rate;54 ip += rate;
54 len -= rate;55 len -= rate;
55 rate = d.rate;56 rate = d.rate;
56 offset = 0;57 offset = 0;
57 }58 }
5859
59 for (d.s[offset .. offset + len]) |*r, i|60 for (d.s[offset..offset + len]) |*r, i|
60 *r ^= b[ip..][i];61 r.* ^= b[ip..][i];
6162
62 d.offset = offset + len;63 d.offset = offset + len;
63 }64 }
6465
65 pub fn final(d: &Self, out: []u8) void {66 pub fn final(d: &Self, out: []u8) void {
66 // padding67 // padding
67 d.s[d.offset] ^= delim;68 d.s[d.offset] ^= delim;
68 d.s[d.rate - 1] ^= 0x80;69 d.s[d.rate - 1] ^= 0x80;
6970
70 keccak_f(1600, d.s[0..]);71 keccak_f(1600, d.s[0..]);
7172
72 // squeeze73 // squeeze
73 var op: usize = 0;74 var op: usize = 0;
74 var len: usize = bits / 8;75 var len: usize = bits / 8;
7576
76 while (len >= d.rate) {77 while (len >= d.rate) {
77 mem.copy(u8, out[op..], d.s[0..d.rate]);78 mem.copy(u8, out[op..], d.s[0..d.rate]);
78 keccak_f(1600, d.s[0..]);79 keccak_f(1600, d.s[0..]);
79 op += d.rate;80 op += d.rate;
80 len -= d.rate;81 len -= d.rate;
82 }
83
84 mem.copy(u8, out[op..], d.s[0..len]);
81 }85 }
86 };
87}
8288
83 mem.copy(u8, out[op..], d.s[0..len]);89const RC = []const u64{
84 }90 0x0000000000000001,
85};}91 0x0000000000008082,
8692 0x800000000000808a,
87const RC = []const u64 {93 0x8000000080008000,
88 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,94 0x000000000000808b,
89 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,95 0x0000000080000001,
90 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,96 0x8000000080008081,
91 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,97 0x8000000000008009,
92 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,98 0x000000000000008a,
93 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,99 0x0000000000000088,
100 0x0000000080008009,
101 0x000000008000000a,
102 0x000000008000808b,
103 0x800000000000008b,
104 0x8000000000008089,
105 0x8000000000008003,
106 0x8000000000008002,
107 0x8000000000000080,
108 0x000000000000800a,
109 0x800000008000000a,
110 0x8000000080008081,
111 0x8000000000008080,
112 0x0000000080000001,
113 0x8000000080008008,
94};114};
95115
96const ROTC = []const usize {116const ROTC = []const usize{
97 1, 3, 6, 10, 15, 21, 28, 36,117 1,
98 45, 55, 2, 14, 27, 41, 56, 8,118 3,
99 25, 43, 62, 18, 39, 61, 20, 44119 6,
120 10,
121 15,
122 21,
123 28,
124 36,
125 45,
126 55,
127 2,
128 14,
129 27,
130 41,
131 56,
132 8,
133 25,
134 43,
135 62,
136 18,
137 39,
138 61,
139 20,
140 44,
100};141};
101142
102const PIL = []const usize {143const PIL = []const usize{
103 10, 7, 11, 17, 18, 3, 5, 16,144 10,
104 8, 21, 24, 4, 15, 23, 19, 13,145 7,
105 12, 2, 20, 14, 22, 9, 6, 1146 11,
147 17,
148 18,
149 3,
150 5,
151 16,
152 8,
153 21,
154 24,
155 4,
156 15,
157 23,
158 19,
159 13,
160 12,
161 2,
162 20,
163 14,
164 22,
165 9,
166 6,
167 1,
106};168};
107169
108const M5 = []const usize {170const M5 = []const usize{
109 0, 1, 2, 3, 4, 0, 1, 2, 3, 4171 0,
172 1,
173 2,
174 3,
175 4,
176 0,
177 1,
178 2,
179 3,
180 4,
110};181};
111182
112fn keccak_f(comptime F: usize, d: []u8) void {183fn keccak_f(comptime F: usize, d: []u8) void {
113 debug.assert(d.len == F / 8);184 debug.assert(d.len == F / 8);
114185
115 const B = F / 25;186 const B = F / 25;
116 const no_rounds = comptime x: { break :x 12 + 2 * math.log2(B); };187 const no_rounds = comptime x: {
188 break :x 12 + 2 * math.log2(B);
189 };
117190
118 var s = []const u64 {0} ** 25;191 var s = []const u64{0} ** 25;
119 var t = []const u64 {0} ** 1;192 var t = []const u64{0} ** 1;
120 var c = []const u64 {0} ** 5;193 var c = []const u64{0} ** 5;
121194
122 for (s) |*r, i| {195 for (s) |*r, i| {
123 *r = mem.readIntLE(u64, d[8*i .. 8*i + 8]);196 r.* = mem.readIntLE(u64, d[8 * i..8 * i + 8]);
124 }197 }
125198
126 comptime var x: usize = 0;199 comptime var x: usize = 0;
127 comptime var y: usize = 0;200 comptime var y: usize = 0;
128 for (RC[0..no_rounds]) |round| {201 for (RC[0..no_rounds]) |round| {
129 // theta202 // theta
130 x = 0; inline while (x < 5) : (x += 1) {203 x = 0;
131 c[x] = s[x] ^ s[x+5] ^ s[x+10] ^ s[x+15] ^ s[x+20];204 inline while (x < 5) : (x += 1) {
205 c[x] = s[x] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20];
132 }206 }
133 x = 0; inline while (x < 5) : (x += 1) {207 x = 0;
134 t[0] = c[M5[x+4]] ^ math.rotl(u64, c[M5[x+1]], usize(1));208 inline while (x < 5) : (x += 1) {
135 y = 0; inline while (y < 5) : (y += 1) {209 t[0] = c[M5[x + 4]] ^ math.rotl(u64, c[M5[x + 1]], usize(1));
136 s[x + y*5] ^= t[0];210 y = 0;
211 inline while (y < 5) : (y += 1) {
212 s[x + y * 5] ^= t[0];
137 }213 }
138 }214 }
139215
140 // rho+pi216 // rho+pi
141 t[0] = s[1];217 t[0] = s[1];
142 x = 0; inline while (x < 24) : (x += 1) {218 x = 0;
219 inline while (x < 24) : (x += 1) {
143 c[0] = s[PIL[x]];220 c[0] = s[PIL[x]];
144 s[PIL[x]] = math.rotl(u64, t[0], ROTC[x]);221 s[PIL[x]] = math.rotl(u64, t[0], ROTC[x]);
145 t[0] = c[0];222 t[0] = c[0];
146 }223 }
147224
148 // chi225 // chi
149 y = 0; inline while (y < 5) : (y += 1) {226 y = 0;
150 x = 0; inline while (x < 5) : (x += 1) {227 inline while (y < 5) : (y += 1) {
151 c[x] = s[x + y*5];228 x = 0;
229 inline while (x < 5) : (x += 1) {
230 c[x] = s[x + y * 5];
152 }231 }
153 x = 0; inline while (x < 5) : (x += 1) {232 x = 0;
154 s[x + y*5] = c[x] ^ (~c[M5[x+1]] & c[M5[x+2]]);233 inline while (x < 5) : (x += 1) {
234 s[x + y * 5] = c[x] ^ (~c[M5[x + 1]] & c[M5[x + 2]]);
155 }235 }
156 }236 }
157237
...@@ -160,11 +240,10 @@ fn keccak_f(comptime F: usize, d: []u8) void {...@@ -160,11 +240,10 @@ fn keccak_f(comptime F: usize, d: []u8) void {
160 }240 }
161241
162 for (s) |r, i| {242 for (s) |r, i| {
163 mem.writeInt(d[8*i .. 8*i + 8], r, builtin.Endian.Little);243 mem.writeInt(d[8 * i..8 * i + 8], r, builtin.Endian.Little);
164 }244 }
165}245}
166246
167
168test "sha3-224 single" {247test "sha3-224 single" {
169 htest.assertEqualHash(Sha3_224, "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", "");248 htest.assertEqualHash(Sha3_224, "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", "");
170 htest.assertEqualHash(Sha3_224, "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", "abc");249 htest.assertEqualHash(Sha3_224, "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", "abc");
...@@ -192,7 +271,7 @@ test "sha3-224 streaming" {...@@ -192,7 +271,7 @@ test "sha3-224 streaming" {
192}271}
193272
194test "sha3-256 single" {273test "sha3-256 single" {
195 htest.assertEqualHash(Sha3_256, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a" , "");274 htest.assertEqualHash(Sha3_256, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", "");
196 htest.assertEqualHash(Sha3_256, "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", "abc");275 htest.assertEqualHash(Sha3_256, "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", "abc");
197 htest.assertEqualHash(Sha3_256, "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");276 htest.assertEqualHash(Sha3_256, "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
198}277}
...@@ -218,7 +297,7 @@ test "sha3-256 streaming" {...@@ -218,7 +297,7 @@ test "sha3-256 streaming" {
218}297}
219298
220test "sha3-256 aligned final" {299test "sha3-256 aligned final" {
221 var block = []u8 {0} ** Sha3_256.block_size;300 var block = []u8{0} ** Sha3_256.block_size;
222 var out: [Sha3_256.digest_size]u8 = undefined;301 var out: [Sha3_256.digest_size]u8 = undefined;
223302
224 var h = Sha3_256.init();303 var h = Sha3_256.init();
...@@ -228,7 +307,7 @@ test "sha3-256 aligned final" {...@@ -228,7 +307,7 @@ test "sha3-256 aligned final" {
228307
229test "sha3-384 single" {308test "sha3-384 single" {
230 const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004";309 const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004";
231 htest.assertEqualHash(Sha3_384, h1 , "");310 htest.assertEqualHash(Sha3_384, h1, "");
232 const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25";311 const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25";
233 htest.assertEqualHash(Sha3_384, h2, "abc");312 htest.assertEqualHash(Sha3_384, h2, "abc");
234 const h3 = "79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7";313 const h3 = "79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7";
...@@ -259,7 +338,7 @@ test "sha3-384 streaming" {...@@ -259,7 +338,7 @@ test "sha3-384 streaming" {
259338
260test "sha3-512 single" {339test "sha3-512 single" {
261 const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26";340 const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26";
262 htest.assertEqualHash(Sha3_512, h1 , "");341 htest.assertEqualHash(Sha3_512, h1, "");
263 const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0";342 const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0";
264 htest.assertEqualHash(Sha3_512, h2, "abc");343 htest.assertEqualHash(Sha3_512, h2, "abc");
265 const h3 = "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185";344 const h3 = "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185";
...@@ -289,7 +368,7 @@ test "sha3-512 streaming" {...@@ -289,7 +368,7 @@ test "sha3-512 streaming" {
289}368}
290369
291test "sha3-512 aligned final" {370test "sha3-512 aligned final" {
292 var block = []u8 {0} ** Sha3_512.block_size;371 var block = []u8{0} ** Sha3_512.block_size;
293 var out: [Sha3_512.digest_size]u8 = undefined;372 var out: [Sha3_512.digest_size]u8 = undefined;
294373
295 var h = Sha3_512.init();374 var h = Sha3_512.init();
std/crypto/test.zig+1-2
...@@ -14,9 +14,8 @@ pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, inpu...@@ -14,9 +14,8 @@ pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, inpu
14pub fn assertEqual(comptime expected: []const u8, input: []const u8) void {14pub fn assertEqual(comptime expected: []const u8, input: []const u8) void {
15 var expected_bytes: [expected.len / 2]u8 = undefined;15 var expected_bytes: [expected.len / 2]u8 = undefined;
16 for (expected_bytes) |*r, i| {16 for (expected_bytes) |*r, i| {
17 *r = fmt.parseInt(u8, expected[2*i .. 2*i+2], 16) catch unreachable;17 r.* = fmt.parseInt(u8, expected[2 * i..2 * i + 2], 16) catch unreachable;
18 }18 }
1919
20 debug.assert(mem.eql(u8, expected_bytes, input));20 debug.assert(mem.eql(u8, expected_bytes, input));
21}21}
22
std/crypto/throughput_test.zig+1-1
...@@ -11,7 +11,7 @@ const Timer = time.Timer;...@@ -11,7 +11,7 @@ const Timer = time.Timer;
11const HashFunction = @import("md5.zig").Md5;11const HashFunction = @import("md5.zig").Md5;
1212
13const MiB = 1024 * 1024;13const MiB = 1024 * 1024;
14const BytesToHash = 1024 * MiB;14const BytesToHash = 1024 * MiB;
1515
16pub fn main() !void {16pub fn main() !void {
17 var stdout_file = try std.io.getStdOut();17 var stdout_file = try std.io.getStdOut();
std/cstr.zig+1-3
...@@ -9,7 +9,6 @@ pub const line_sep = switch (builtin.os) {...@@ -9,7 +9,6 @@ pub const line_sep = switch (builtin.os) {
9 else => "\n",9 else => "\n",
10};10};
1111
12
13pub fn len(ptr: &const u8) usize {12pub fn len(ptr: &const u8) usize {
14 var count: usize = 0;13 var count: usize = 0;
15 while (ptr[count] != 0) : (count += 1) {}14 while (ptr[count] != 0) : (count += 1) {}
...@@ -95,7 +94,7 @@ pub const NullTerminated2DArray = struct {...@@ -95,7 +94,7 @@ pub const NullTerminated2DArray = struct {
95 }94 }
96 index_buf[i] = null;95 index_buf[i] = null;
9796
98 return NullTerminated2DArray {97 return NullTerminated2DArray{
99 .allocator = allocator,98 .allocator = allocator,
100 .byte_count = byte_count,99 .byte_count = byte_count,
101 .ptr = @ptrCast(?&?&u8, buf.ptr),100 .ptr = @ptrCast(?&?&u8, buf.ptr),
...@@ -107,4 +106,3 @@ pub const NullTerminated2DArray = struct {...@@ -107,4 +106,3 @@ pub const NullTerminated2DArray = struct {
107 self.allocator.free(buf[0..self.byte_count]);106 self.allocator.free(buf[0..self.byte_count]);
108 }107 }
109};108};
110
std/debug/failing_allocator.zig+2-2
...@@ -13,14 +13,14 @@ pub const FailingAllocator = struct {...@@ -13,14 +13,14 @@ pub const FailingAllocator = struct {
13 deallocations: usize,13 deallocations: usize,
1414
15 pub fn init(allocator: &mem.Allocator, fail_index: usize) FailingAllocator {15 pub fn init(allocator: &mem.Allocator, fail_index: usize) FailingAllocator {
16 return FailingAllocator {16 return FailingAllocator{
17 .internal_allocator = allocator,17 .internal_allocator = allocator,
18 .fail_index = fail_index,18 .fail_index = fail_index,
19 .index = 0,19 .index = 0,
20 .allocated_bytes = 0,20 .allocated_bytes = 0,
21 .freed_bytes = 0,21 .freed_bytes = 0,
22 .deallocations = 0,22 .deallocations = 0,
23 .allocator = mem.Allocator {23 .allocator = mem.Allocator{
24 .allocFn = alloc,24 .allocFn = alloc,
25 .reallocFn = realloc,25 .reallocFn = realloc,
26 .freeFn = free,26 .freeFn = free,
std/debug/index.zig+99-136
...@@ -104,9 +104,7 @@ pub fn panic(comptime format: []const u8, args: ...) noreturn {...@@ -104,9 +104,7 @@ pub fn panic(comptime format: []const u8, args: ...) noreturn {
104104
105var panicking: u8 = 0; // TODO make this a bool105var panicking: u8 = 0; // TODO make this a bool
106106
107pub fn panicExtra(trace: ?&const builtin.StackTrace, first_trace_addr: ?usize,107pub fn panicExtra(trace: ?&const builtin.StackTrace, first_trace_addr: ?usize, comptime format: []const u8, args: ...) noreturn {
108 comptime format: []const u8, args: ...) noreturn
109{
110 @setCold(true);108 @setCold(true);
111109
112 if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) {110 if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) {
...@@ -132,9 +130,7 @@ const WHITE = "\x1b[37;1m";...@@ -132,9 +130,7 @@ const WHITE = "\x1b[37;1m";
132const DIM = "\x1b[2m";130const DIM = "\x1b[2m";
133const RESET = "\x1b[0m";131const RESET = "\x1b[0m";
134132
135pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var, allocator: &mem.Allocator,133pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var, allocator: &mem.Allocator, debug_info: &ElfStackTrace, tty_color: bool) !void {
136 debug_info: &ElfStackTrace, tty_color: bool) !void
137{
138 var frame_index: usize = undefined;134 var frame_index: usize = undefined;
139 var frames_left: usize = undefined;135 var frames_left: usize = undefined;
140 if (stack_trace.index < stack_trace.instruction_addresses.len) {136 if (stack_trace.index < stack_trace.instruction_addresses.len) {
...@@ -154,9 +150,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var,...@@ -154,9 +150,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var,
154 }150 }
155}151}
156152
157pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator,153pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator, debug_info: &ElfStackTrace, tty_color: bool, start_addr: ?usize) !void {
158 debug_info: &ElfStackTrace, tty_color: bool, start_addr: ?usize) !void
159{
160 const AddressState = union(enum) {154 const AddressState = union(enum) {
161 NotLookingForStartAddress,155 NotLookingForStartAddress,
162 LookingForStartAddress: usize,156 LookingForStartAddress: usize,
...@@ -166,14 +160,14 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator,...@@ -166,14 +160,14 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator,
166 // else AddressState.NotLookingForStartAddress;160 // else AddressState.NotLookingForStartAddress;
167 var addr_state: AddressState = undefined;161 var addr_state: AddressState = undefined;
168 if (start_addr) |addr| {162 if (start_addr) |addr| {
169 addr_state = AddressState { .LookingForStartAddress = addr };163 addr_state = AddressState{ .LookingForStartAddress = addr };
170 } else {164 } else {
171 addr_state = AddressState.NotLookingForStartAddress;165 addr_state = AddressState.NotLookingForStartAddress;
172 }166 }
173167
174 var fp = @ptrToInt(@frameAddress());168 var fp = @ptrToInt(@frameAddress());
175 while (fp != 0) : (fp = *@intToPtr(&const usize, fp)) {169 while (fp != 0) : (fp = @intToPtr(&const usize, fp).*) {
176 const return_address = *@intToPtr(&const usize, fp + @sizeOf(usize));170 const return_address = @intToPtr(&const usize, fp + @sizeOf(usize)).*;
177171
178 switch (addr_state) {172 switch (addr_state) {
179 AddressState.NotLookingForStartAddress => {},173 AddressState.NotLookingForStartAddress => {},
...@@ -200,32 +194,32 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: var, address: us...@@ -200,32 +194,32 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: var, address: us
200 // in practice because the compiler dumps everything in a single194 // in practice because the compiler dumps everything in a single
201 // object file. Future improvement: use external dSYM data when195 // object file. Future improvement: use external dSYM data when
202 // available.196 // available.
203 const unknown = macho.Symbol { .name = "???", .address = address };197 const unknown = macho.Symbol{
198 .name = "???",
199 .address = address,
200 };
204 const symbol = debug_info.symbol_table.search(address) ?? &unknown;201 const symbol = debug_info.symbol_table.search(address) ?? &unknown;
205 try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++202 try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n", symbol.name, address);
206 DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n",
207 symbol.name, address);
208 },203 },
209 else => {204 else => {
210 const compile_unit = findCompileUnit(debug_info, address) catch {205 const compile_unit = findCompileUnit(debug_info, address) catch {
211 try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n",206 try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", address);
212 address);
213 return;207 return;
214 };208 };
215 const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name);209 const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name);
216 if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| {210 if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| {
217 defer line_info.deinit();211 defer line_info.deinit();
218 try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++212 try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", line_info.file_name, line_info.line, line_info.column, address, compile_unit_name);
219 DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n",
220 line_info.file_name, line_info.line, line_info.column,
221 address, compile_unit_name);
222 if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) {213 if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) {
223 if (line_info.column == 0) {214 if (line_info.column == 0) {
224 try out_stream.write("\n");215 try out_stream.write("\n");
225 } else {216 } else {
226 {var col_i: usize = 1; while (col_i < line_info.column) : (col_i += 1) {217 {
227 try out_stream.writeByte(' ');218 var col_i: usize = 1;
228 }}219 while (col_i < line_info.column) : (col_i += 1) {
220 try out_stream.writeByte(' ');
221 }
222 }
229 try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");223 try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");
230 }224 }
231 } else |err| switch (err) {225 } else |err| switch (err) {
...@@ -247,7 +241,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace {...@@ -247,7 +241,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace {
247 builtin.ObjectFormat.elf => {241 builtin.ObjectFormat.elf => {
248 const st = try allocator.create(ElfStackTrace);242 const st = try allocator.create(ElfStackTrace);
249 errdefer allocator.destroy(st);243 errdefer allocator.destroy(st);
250 *st = ElfStackTrace {244 st.* = ElfStackTrace{
251 .self_exe_file = undefined,245 .self_exe_file = undefined,
252 .elf = undefined,246 .elf = undefined,
253 .debug_info = undefined,247 .debug_info = undefined,
...@@ -279,9 +273,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace {...@@ -279,9 +273,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace {
279 const st = try allocator.create(ElfStackTrace);273 const st = try allocator.create(ElfStackTrace);
280 errdefer allocator.destroy(st);274 errdefer allocator.destroy(st);
281275
282 *st = ElfStackTrace {276 st.* = ElfStackTrace{ .symbol_table = try macho.loadSymbols(allocator, &io.FileInStream.init(&exe_file)) };
283 .symbol_table = try macho.loadSymbols(allocator, &io.FileInStream.init(&exe_file)),
284 };
285277
286 return st;278 return st;
287 },279 },
...@@ -325,8 +317,7 @@ fn printLineFromFile(allocator: &mem.Allocator, out_stream: var, line_info: &con...@@ -325,8 +317,7 @@ fn printLineFromFile(allocator: &mem.Allocator, out_stream: var, line_info: &con
325 }317 }
326 }318 }
327319
328 if (amt_read < buf.len)320 if (amt_read < buf.len) return error.EndOfFile;
329 return error.EndOfFile;
330 }321 }
331}322}
332323
...@@ -418,10 +409,8 @@ const Constant = struct {...@@ -418,10 +409,8 @@ const Constant = struct {
418 signed: bool,409 signed: bool,
419410
420 fn asUnsignedLe(self: &const Constant) !u64 {411 fn asUnsignedLe(self: &const Constant) !u64 {
421 if (self.payload.len > @sizeOf(u64))412 if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo;
422 return error.InvalidDebugInfo;413 if (self.signed) return error.InvalidDebugInfo;
423 if (self.signed)
424 return error.InvalidDebugInfo;
425 return mem.readInt(self.payload, u64, builtin.Endian.Little);414 return mem.readInt(self.payload, u64, builtin.Endian.Little);
426 }415 }
427};416};
...@@ -438,15 +427,14 @@ const Die = struct {...@@ -438,15 +427,14 @@ const Die = struct {
438427
439 fn getAttr(self: &const Die, id: u64) ?&const FormValue {428 fn getAttr(self: &const Die, id: u64) ?&const FormValue {
440 for (self.attrs.toSliceConst()) |*attr| {429 for (self.attrs.toSliceConst()) |*attr| {
441 if (attr.id == id)430 if (attr.id == id) return &attr.value;
442 return &attr.value;
443 }431 }
444 return null;432 return null;
445 }433 }
446434
447 fn getAttrAddr(self: &const Die, id: u64) !u64 {435 fn getAttrAddr(self: &const Die, id: u64) !u64 {
448 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;436 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
449 return switch (*form_value) {437 return switch (form_value.*) {
450 FormValue.Address => |value| value,438 FormValue.Address => |value| value,
451 else => error.InvalidDebugInfo,439 else => error.InvalidDebugInfo,
452 };440 };
...@@ -454,7 +442,7 @@ const Die = struct {...@@ -454,7 +442,7 @@ const Die = struct {
454442
455 fn getAttrSecOffset(self: &const Die, id: u64) !u64 {443 fn getAttrSecOffset(self: &const Die, id: u64) !u64 {
456 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;444 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
457 return switch (*form_value) {445 return switch (form_value.*) {
458 FormValue.Const => |value| value.asUnsignedLe(),446 FormValue.Const => |value| value.asUnsignedLe(),
459 FormValue.SecOffset => |value| value,447 FormValue.SecOffset => |value| value,
460 else => error.InvalidDebugInfo,448 else => error.InvalidDebugInfo,
...@@ -463,7 +451,7 @@ const Die = struct {...@@ -463,7 +451,7 @@ const Die = struct {
463451
464 fn getAttrUnsignedLe(self: &const Die, id: u64) !u64 {452 fn getAttrUnsignedLe(self: &const Die, id: u64) !u64 {
465 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;453 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
466 return switch (*form_value) {454 return switch (form_value.*) {
467 FormValue.Const => |value| value.asUnsignedLe(),455 FormValue.Const => |value| value.asUnsignedLe(),
468 else => error.InvalidDebugInfo,456 else => error.InvalidDebugInfo,
469 };457 };
...@@ -471,7 +459,7 @@ const Die = struct {...@@ -471,7 +459,7 @@ const Die = struct {
471459
472 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) ![]u8 {460 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) ![]u8 {
473 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;461 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
474 return switch (*form_value) {462 return switch (form_value.*) {
475 FormValue.String => |value| value,463 FormValue.String => |value| value,
476 FormValue.StrPtr => |offset| getString(st, offset),464 FormValue.StrPtr => |offset| getString(st, offset),
477 else => error.InvalidDebugInfo,465 else => error.InvalidDebugInfo,
...@@ -518,10 +506,8 @@ const LineNumberProgram = struct {...@@ -518,10 +506,8 @@ const LineNumberProgram = struct {
518 prev_basic_block: bool,506 prev_basic_block: bool,
519 prev_end_sequence: bool,507 prev_end_sequence: bool,
520508
521 pub fn init(is_stmt: bool, include_dirs: []const []const u8,509 pub fn init(is_stmt: bool, include_dirs: []const []const u8, file_entries: &ArrayList(FileEntry), target_address: usize) LineNumberProgram {
522 file_entries: &ArrayList(FileEntry), target_address: usize) LineNumberProgram510 return LineNumberProgram{
523 {
524 return LineNumberProgram {
525 .address = 0,511 .address = 0,
526 .file = 1,512 .file = 1,
527 .line = 1,513 .line = 1,
...@@ -548,14 +534,16 @@ const LineNumberProgram = struct {...@@ -548,14 +534,16 @@ const LineNumberProgram = struct {
548 return error.MissingDebugInfo;534 return error.MissingDebugInfo;
549 } else if (self.prev_file - 1 >= self.file_entries.len) {535 } else if (self.prev_file - 1 >= self.file_entries.len) {
550 return error.InvalidDebugInfo;536 return error.InvalidDebugInfo;
551 } else &self.file_entries.items[self.prev_file - 1];537 } else
538 &self.file_entries.items[self.prev_file - 1];
552539
553 const dir_name = if (file_entry.dir_index >= self.include_dirs.len) {540 const dir_name = if (file_entry.dir_index >= self.include_dirs.len) {
554 return error.InvalidDebugInfo;541 return error.InvalidDebugInfo;
555 } else self.include_dirs[file_entry.dir_index];542 } else
543 self.include_dirs[file_entry.dir_index];
556 const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);544 const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);
557 errdefer self.file_entries.allocator.free(file_name);545 errdefer self.file_entries.allocator.free(file_name);
558 return LineInfo {546 return LineInfo{
559 .line = if (self.prev_line >= 0) usize(self.prev_line) else 0,547 .line = if (self.prev_line >= 0) usize(self.prev_line) else 0,
560 .column = self.prev_column,548 .column = self.prev_column,
561 .file_name = file_name,549 .file_name = file_name,
...@@ -578,8 +566,7 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: var) ![]u8 {...@@ -578,8 +566,7 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: var) ![]u8 {
578 var buf = ArrayList(u8).init(allocator);566 var buf = ArrayList(u8).init(allocator);
579 while (true) {567 while (true) {
580 const byte = try in_stream.readByte();568 const byte = try in_stream.readByte();
581 if (byte == 0)569 if (byte == 0) break;
582 break;
583 try buf.append(byte);570 try buf.append(byte);
584 }571 }
585 return buf.toSlice();572 return buf.toSlice();
...@@ -600,7 +587,7 @@ fn readAllocBytes(allocator: &mem.Allocator, in_stream: var, size: usize) ![]u8...@@ -600,7 +587,7 @@ fn readAllocBytes(allocator: &mem.Allocator, in_stream: var, size: usize) ![]u8
600587
601fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {588fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {
602 const buf = try readAllocBytes(allocator, in_stream, size);589 const buf = try readAllocBytes(allocator, in_stream, size);
603 return FormValue { .Block = buf };590 return FormValue{ .Block = buf };
604}591}
605592
606fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {593fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {
...@@ -609,26 +596,25 @@ fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: var, size: usize) !...@@ -609,26 +596,25 @@ fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: var, size: usize) !
609}596}
610597
611fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue {598fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue {
612 return FormValue { .Const = Constant {599 return FormValue{
613 .signed = signed,600 .Const = Constant{
614 .payload = try readAllocBytes(allocator, in_stream, size),601 .signed = signed,
615 }};602 .payload = try readAllocBytes(allocator, in_stream, size),
603 },
604 };
616}605}
617606
618fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 {607fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 {
619 return if (is_64) try in_stream.readIntLe(u64)608 return if (is_64) try in_stream.readIntLe(u64) else u64(try in_stream.readIntLe(u32));
620 else u64(try in_stream.readIntLe(u32)) ;
621}609}
622610
623fn parseFormValueTargetAddrSize(in_stream: var) !u64 {611fn parseFormValueTargetAddrSize(in_stream: var) !u64 {
624 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32))612 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64) else unreachable;
625 else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64)
626 else unreachable;
627}613}
628614
629fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {615fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {
630 const buf = try readAllocBytes(allocator, in_stream, size);616 const buf = try readAllocBytes(allocator, in_stream, size);
631 return FormValue { .Ref = buf };617 return FormValue{ .Ref = buf };
632}618}
633619
634fn parseFormValueRef(allocator: &mem.Allocator, in_stream: var, comptime T: type) !FormValue {620fn parseFormValueRef(allocator: &mem.Allocator, in_stream: var, comptime T: type) !FormValue {
...@@ -636,7 +622,7 @@ fn parseFormValueRef(allocator: &mem.Allocator, in_stream: var, comptime T: type...@@ -636,7 +622,7 @@ fn parseFormValueRef(allocator: &mem.Allocator, in_stream: var, comptime T: type
636 return parseFormValueRefLen(allocator, in_stream, block_len);622 return parseFormValueRefLen(allocator, in_stream, block_len);
637}623}
638624
639const ParseFormValueError = error {625const ParseFormValueError = error{
640 EndOfStream,626 EndOfStream,
641 Io,627 Io,
642 BadFd,628 BadFd,
...@@ -646,11 +632,9 @@ const ParseFormValueError = error {...@@ -646,11 +632,9 @@ const ParseFormValueError = error {
646 OutOfMemory,632 OutOfMemory,
647};633};
648634
649fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64: bool)635fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64: bool) ParseFormValueError!FormValue {
650 ParseFormValueError!FormValue
651{
652 return switch (form_id) {636 return switch (form_id) {
653 DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) },637 DW.FORM_addr => FormValue{ .Address = try parseFormValueTargetAddrSize(in_stream) },
654 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),638 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
655 DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2),639 DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2),
656 DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4),640 DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4),
...@@ -670,11 +654,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64...@@ -670,11 +654,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64
670 DW.FORM_exprloc => {654 DW.FORM_exprloc => {
671 const size = try readULeb128(in_stream);655 const size = try readULeb128(in_stream);
672 const buf = try readAllocBytes(allocator, in_stream, size);656 const buf = try readAllocBytes(allocator, in_stream, size);
673 return FormValue { .ExprLoc = buf };657 return FormValue{ .ExprLoc = buf };
674 },658 },
675 DW.FORM_flag => FormValue { .Flag = (try in_stream.readByte()) != 0 },659 DW.FORM_flag => FormValue{ .Flag = (try in_stream.readByte()) != 0 },
676 DW.FORM_flag_present => FormValue { .Flag = true },660 DW.FORM_flag_present => FormValue{ .Flag = true },
677 DW.FORM_sec_offset => FormValue { .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) },661 DW.FORM_sec_offset => FormValue{ .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
678662
679 DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8),663 DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8),
680 DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16),664 DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16),
...@@ -685,11 +669,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64...@@ -685,11 +669,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64
685 return parseFormValueRefLen(allocator, in_stream, ref_len);669 return parseFormValueRefLen(allocator, in_stream, ref_len);
686 },670 },
687671
688 DW.FORM_ref_addr => FormValue { .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },672 DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
689 DW.FORM_ref_sig8 => FormValue { .RefSig8 = try in_stream.readIntLe(u64) },673 DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLe(u64) },
690674
691 DW.FORM_string => FormValue { .String = try readStringRaw(allocator, in_stream) },675 DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) },
692 DW.FORM_strp => FormValue { .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },676 DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
693 DW.FORM_indirect => {677 DW.FORM_indirect => {
694 const child_form_id = try readULeb128(in_stream);678 const child_form_id = try readULeb128(in_stream);
695 return parseFormValue(allocator, in_stream, child_form_id, is_64);679 return parseFormValue(allocator, in_stream, child_form_id, is_64);
...@@ -705,9 +689,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable {...@@ -705,9 +689,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable {
705 var result = AbbrevTable.init(st.allocator());689 var result = AbbrevTable.init(st.allocator());
706 while (true) {690 while (true) {
707 const abbrev_code = try readULeb128(in_stream);691 const abbrev_code = try readULeb128(in_stream);
708 if (abbrev_code == 0)692 if (abbrev_code == 0) return result;
709 return result;693 try result.append(AbbrevTableEntry{
710 try result.append(AbbrevTableEntry {
711 .abbrev_code = abbrev_code,694 .abbrev_code = abbrev_code,
712 .tag_id = try readULeb128(in_stream),695 .tag_id = try readULeb128(in_stream),
713 .has_children = (try in_stream.readByte()) == DW.CHILDREN_yes,696 .has_children = (try in_stream.readByte()) == DW.CHILDREN_yes,
...@@ -718,9 +701,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable {...@@ -718,9 +701,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable {
718 while (true) {701 while (true) {
719 const attr_id = try readULeb128(in_stream);702 const attr_id = try readULeb128(in_stream);
720 const form_id = try readULeb128(in_stream);703 const form_id = try readULeb128(in_stream);
721 if (attr_id == 0 and form_id == 0)704 if (attr_id == 0 and form_id == 0) break;
722 break;705 try attrs.append(AbbrevAttr{
723 try attrs.append(AbbrevAttr {
724 .attr_id = attr_id,706 .attr_id = attr_id,
725 .form_id = form_id,707 .form_id = form_id,
726 });708 });
...@@ -737,7 +719,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable {...@@ -737,7 +719,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable {
737 }719 }
738 }720 }
739 try st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset);721 try st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset);
740 try st.abbrev_table_list.append(AbbrevTableHeader {722 try st.abbrev_table_list.append(AbbrevTableHeader{
741 .offset = abbrev_offset,723 .offset = abbrev_offset,
742 .table = try parseAbbrevTable(st),724 .table = try parseAbbrevTable(st),
743 });725 });
...@@ -746,8 +728,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable {...@@ -746,8 +728,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable {
746728
747fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&const AbbrevTableEntry {729fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&const AbbrevTableEntry {
748 for (abbrev_table.toSliceConst()) |*table_entry| {730 for (abbrev_table.toSliceConst()) |*table_entry| {
749 if (table_entry.abbrev_code == abbrev_code)731 if (table_entry.abbrev_code == abbrev_code) return table_entry;
750 return table_entry;
751 }732 }
752 return null;733 return null;
753}734}
...@@ -759,14 +740,14 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) !...@@ -759,14 +740,14 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) !
759 const abbrev_code = try readULeb128(in_stream);740 const abbrev_code = try readULeb128(in_stream);
760 const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) ?? return error.InvalidDebugInfo;741 const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) ?? return error.InvalidDebugInfo;
761742
762 var result = Die {743 var result = Die{
763 .tag_id = table_entry.tag_id,744 .tag_id = table_entry.tag_id,
764 .has_children = table_entry.has_children,745 .has_children = table_entry.has_children,
765 .attrs = ArrayList(Die.Attr).init(st.allocator()),746 .attrs = ArrayList(Die.Attr).init(st.allocator()),
766 };747 };
767 try result.attrs.resize(table_entry.attrs.len);748 try result.attrs.resize(table_entry.attrs.len);
768 for (table_entry.attrs.toSliceConst()) |attr, i| {749 for (table_entry.attrs.toSliceConst()) |attr, i| {
769 result.attrs.items[i] = Die.Attr {750 result.attrs.items[i] = Die.Attr{
770 .id = attr.attr_id,751 .id = attr.attr_id,
771 .value = try parseFormValue(st.allocator(), in_stream, attr.form_id, is_64),752 .value = try parseFormValue(st.allocator(), in_stream, attr.form_id, is_64),
772 };753 };
...@@ -790,8 +771,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -790,8 +771,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
790771
791 var is_64: bool = undefined;772 var is_64: bool = undefined;
792 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);773 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);
793 if (unit_length == 0)774 if (unit_length == 0) return error.MissingDebugInfo;
794 return error.MissingDebugInfo;
795 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));775 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
796776
797 if (compile_unit.index != this_index) {777 if (compile_unit.index != this_index) {
...@@ -803,8 +783,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -803,8 +783,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
803 // TODO support 3 and 5783 // TODO support 3 and 5
804 if (version != 2 and version != 4) return error.InvalidDebugInfo;784 if (version != 2 and version != 4) return error.InvalidDebugInfo;
805785
806 const prologue_length = if (is_64) try in_stream.readInt(st.elf.endian, u64)786 const prologue_length = if (is_64) try in_stream.readInt(st.elf.endian, u64) else try in_stream.readInt(st.elf.endian, u32);
807 else try in_stream.readInt(st.elf.endian, u32);
808 const prog_start_offset = (try in_file.getPos()) + prologue_length;787 const prog_start_offset = (try in_file.getPos()) + prologue_length;
809788
810 const minimum_instruction_length = try in_stream.readByte();789 const minimum_instruction_length = try in_stream.readByte();
...@@ -819,38 +798,37 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -819,38 +798,37 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
819 const line_base = try in_stream.readByteSigned();798 const line_base = try in_stream.readByteSigned();
820799
821 const line_range = try in_stream.readByte();800 const line_range = try in_stream.readByte();
822 if (line_range == 0)801 if (line_range == 0) return error.InvalidDebugInfo;
823 return error.InvalidDebugInfo;
824802
825 const opcode_base = try in_stream.readByte();803 const opcode_base = try in_stream.readByte();
826804
827 const standard_opcode_lengths = try st.allocator().alloc(u8, opcode_base - 1);805 const standard_opcode_lengths = try st.allocator().alloc(u8, opcode_base - 1);
828806
829 {var i: usize = 0; while (i < opcode_base - 1) : (i += 1) {807 {
830 standard_opcode_lengths[i] = try in_stream.readByte();808 var i: usize = 0;
831 }}809 while (i < opcode_base - 1) : (i += 1) {
810 standard_opcode_lengths[i] = try in_stream.readByte();
811 }
812 }
832813
833 var include_directories = ArrayList([]u8).init(st.allocator());814 var include_directories = ArrayList([]u8).init(st.allocator());
834 try include_directories.append(compile_unit_cwd);815 try include_directories.append(compile_unit_cwd);
835 while (true) {816 while (true) {
836 const dir = try st.readString();817 const dir = try st.readString();
837 if (dir.len == 0)818 if (dir.len == 0) break;
838 break;
839 try include_directories.append(dir);819 try include_directories.append(dir);
840 }820 }
841821
842 var file_entries = ArrayList(FileEntry).init(st.allocator());822 var file_entries = ArrayList(FileEntry).init(st.allocator());
843 var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(),823 var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), &file_entries, target_address);
844 &file_entries, target_address);
845824
846 while (true) {825 while (true) {
847 const file_name = try st.readString();826 const file_name = try st.readString();
848 if (file_name.len == 0)827 if (file_name.len == 0) break;
849 break;
850 const dir_index = try readULeb128(in_stream);828 const dir_index = try readULeb128(in_stream);
851 const mtime = try readULeb128(in_stream);829 const mtime = try readULeb128(in_stream);
852 const len_bytes = try readULeb128(in_stream);830 const len_bytes = try readULeb128(in_stream);
853 try file_entries.append(FileEntry {831 try file_entries.append(FileEntry{
854 .file_name = file_name,832 .file_name = file_name,
855 .dir_index = dir_index,833 .dir_index = dir_index,
856 .mtime = mtime,834 .mtime = mtime,
...@@ -866,8 +844,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -866,8 +844,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
866 var sub_op: u8 = undefined; // TODO move this to the correct scope and fix the compiler crash844 var sub_op: u8 = undefined; // TODO move this to the correct scope and fix the compiler crash
867 if (opcode == DW.LNS_extended_op) {845 if (opcode == DW.LNS_extended_op) {
868 const op_size = try readULeb128(in_stream);846 const op_size = try readULeb128(in_stream);
869 if (op_size < 1)847 if (op_size < 1) return error.InvalidDebugInfo;
870 return error.InvalidDebugInfo;
871 sub_op = try in_stream.readByte();848 sub_op = try in_stream.readByte();
872 switch (sub_op) {849 switch (sub_op) {
873 DW.LNE_end_sequence => {850 DW.LNE_end_sequence => {
...@@ -884,7 +861,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -884,7 +861,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
884 const dir_index = try readULeb128(in_stream);861 const dir_index = try readULeb128(in_stream);
885 const mtime = try readULeb128(in_stream);862 const mtime = try readULeb128(in_stream);
886 const len_bytes = try readULeb128(in_stream);863 const len_bytes = try readULeb128(in_stream);
887 try file_entries.append(FileEntry {864 try file_entries.append(FileEntry{
888 .file_name = file_name,865 .file_name = file_name,
889 .dir_index = dir_index,866 .dir_index = dir_index,
890 .mtime = mtime,867 .mtime = mtime,
...@@ -941,11 +918,9 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -941,11 +918,9 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
941 const arg = try in_stream.readInt(st.elf.endian, u16);918 const arg = try in_stream.readInt(st.elf.endian, u16);
942 prog.address += arg;919 prog.address += arg;
943 },920 },
944 DW.LNS_set_prologue_end => {921 DW.LNS_set_prologue_end => {},
945 },
946 else => {922 else => {
947 if (opcode - 1 >= standard_opcode_lengths.len)923 if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo;
948 return error.InvalidDebugInfo;
949 const len_bytes = standard_opcode_lengths[opcode - 1];924 const len_bytes = standard_opcode_lengths[opcode - 1];
950 try in_file.seekForward(len_bytes);925 try in_file.seekForward(len_bytes);
951 },926 },
...@@ -972,16 +947,13 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {...@@ -972,16 +947,13 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {
972947
973 var is_64: bool = undefined;948 var is_64: bool = undefined;
974 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);949 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);
975 if (unit_length == 0)950 if (unit_length == 0) return;
976 return;
977 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));951 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
978952
979 const version = try in_stream.readInt(st.elf.endian, u16);953 const version = try in_stream.readInt(st.elf.endian, u16);
980 if (version < 2 or version > 5) return error.InvalidDebugInfo;954 if (version < 2 or version > 5) return error.InvalidDebugInfo;
981955
982 const debug_abbrev_offset =956 const debug_abbrev_offset = if (is_64) try in_stream.readInt(st.elf.endian, u64) else try in_stream.readInt(st.elf.endian, u32);
983 if (is_64) try in_stream.readInt(st.elf.endian, u64)
984 else try in_stream.readInt(st.elf.endian, u32);
985957
986 const address_size = try in_stream.readByte();958 const address_size = try in_stream.readByte();
987 if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;959 if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;
...@@ -992,15 +964,14 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {...@@ -992,15 +964,14 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {
992 try st.self_exe_file.seekTo(compile_unit_pos);964 try st.self_exe_file.seekTo(compile_unit_pos);
993965
994 const compile_unit_die = try st.allocator().create(Die);966 const compile_unit_die = try st.allocator().create(Die);
995 *compile_unit_die = try parseDie(st, abbrev_table, is_64);967 compile_unit_die.* = try parseDie(st, abbrev_table, is_64);
996968
997 if (compile_unit_die.tag_id != DW.TAG_compile_unit)969 if (compile_unit_die.tag_id != DW.TAG_compile_unit) return error.InvalidDebugInfo;
998 return error.InvalidDebugInfo;
999970
1000 const pc_range = x: {971 const pc_range = x: {
1001 if (compile_unit_die.getAttrAddr(DW.AT_low_pc)) |low_pc| {972 if (compile_unit_die.getAttrAddr(DW.AT_low_pc)) |low_pc| {
1002 if (compile_unit_die.getAttr(DW.AT_high_pc)) |high_pc_value| {973 if (compile_unit_die.getAttr(DW.AT_high_pc)) |high_pc_value| {
1003 const pc_end = switch (*high_pc_value) {974 const pc_end = switch (high_pc_value.*) {
1004 FormValue.Address => |value| value,975 FormValue.Address => |value| value,
1005 FormValue.Const => |value| b: {976 FormValue.Const => |value| b: {
1006 const offset = try value.asUnsignedLe();977 const offset = try value.asUnsignedLe();
...@@ -1008,7 +979,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {...@@ -1008,7 +979,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {
1008 },979 },
1009 else => return error.InvalidDebugInfo,980 else => return error.InvalidDebugInfo,
1010 };981 };
1011 break :x PcRange {982 break :x PcRange{
1012 .start = low_pc,983 .start = low_pc,
1013 .end = pc_end,984 .end = pc_end,
1014 };985 };
...@@ -1016,13 +987,12 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {...@@ -1016,13 +987,12 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {
1016 break :x null;987 break :x null;
1017 }988 }
1018 } else |err| {989 } else |err| {
1019 if (err != error.MissingDebugInfo)990 if (err != error.MissingDebugInfo) return err;
1020 return err;
1021 break :x null;991 break :x null;
1022 }992 }
1023 };993 };
1024994
1025 try st.compile_unit_list.append(CompileUnit {995 try st.compile_unit_list.append(CompileUnit{
1026 .version = version,996 .version = version,
1027 .is_64 = is_64,997 .is_64 = is_64,
1028 .pc_range = pc_range,998 .pc_range = pc_range,
...@@ -1040,8 +1010,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit...@@ -1040,8 +1010,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit
1040 const in_stream = &in_file_stream.stream;1010 const in_stream = &in_file_stream.stream;
1041 for (st.compile_unit_list.toSlice()) |*compile_unit| {1011 for (st.compile_unit_list.toSlice()) |*compile_unit| {
1042 if (compile_unit.pc_range) |range| {1012 if (compile_unit.pc_range) |range| {
1043 if (target_address >= range.start and target_address < range.end)1013 if (target_address >= range.start and target_address < range.end) return compile_unit;
1044 return compile_unit;
1045 }1014 }
1046 if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {1015 if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {
1047 var base_address: usize = 0;1016 var base_address: usize = 0;
...@@ -1063,8 +1032,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit...@@ -1063,8 +1032,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit
1063 }1032 }
1064 }1033 }
1065 } else |err| {1034 } else |err| {
1066 if (err != error.MissingDebugInfo)1035 if (err != error.MissingDebugInfo) return err;
1067 return err;
1068 continue;1036 continue;
1069 }1037 }
1070 }1038 }
...@@ -1073,8 +1041,8 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit...@@ -1073,8 +1041,8 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit
10731041
1074fn readInitialLength(comptime E: type, in_stream: &io.InStream(E), is_64: &bool) !u64 {1042fn readInitialLength(comptime E: type, in_stream: &io.InStream(E), is_64: &bool) !u64 {
1075 const first_32_bits = try in_stream.readIntLe(u32);1043 const first_32_bits = try in_stream.readIntLe(u32);
1076 *is_64 = (first_32_bits == 0xffffffff);1044 is_64.* = (first_32_bits == 0xffffffff);
1077 if (*is_64) {1045 if (is_64.*) {
1078 return in_stream.readIntLe(u64);1046 return in_stream.readIntLe(u64);
1079 } else {1047 } else {
1080 if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;1048 if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;
...@@ -1091,13 +1059,11 @@ fn readULeb128(in_stream: var) !u64 {...@@ -1091,13 +1059,11 @@ fn readULeb128(in_stream: var) !u64 {
10911059
1092 var operand: u64 = undefined;1060 var operand: u64 = undefined;
10931061
1094 if (@shlWithOverflow(u64, byte & 0b01111111, u6(shift), &operand))1062 if (@shlWithOverflow(u64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo;
1095 return error.InvalidDebugInfo;
10961063
1097 result |= operand;1064 result |= operand;
10981065
1099 if ((byte & 0b10000000) == 0)1066 if ((byte & 0b10000000) == 0) return result;
1100 return result;
11011067
1102 shift += 7;1068 shift += 7;
1103 }1069 }
...@@ -1112,15 +1078,13 @@ fn readILeb128(in_stream: var) !i64 {...@@ -1112,15 +1078,13 @@ fn readILeb128(in_stream: var) !i64 {
11121078
1113 var operand: i64 = undefined;1079 var operand: i64 = undefined;
11141080
1115 if (@shlWithOverflow(i64, byte & 0b01111111, u6(shift), &operand))1081 if (@shlWithOverflow(i64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo;
1116 return error.InvalidDebugInfo;
11171082
1118 result |= operand;1083 result |= operand;
1119 shift += 7;1084 shift += 7;
11201085
1121 if ((byte & 0b10000000) == 0) {1086 if ((byte & 0b10000000) == 0) {
1122 if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0)1087 if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << u6(shift));
1123 result |= -(i64(1) << u6(shift));
1124 return result;1088 return result;
1125 }1089 }
1126 }1090 }
...@@ -1131,7 +1095,6 @@ pub const global_allocator = &global_fixed_allocator.allocator;...@@ -1131,7 +1095,6 @@ pub const global_allocator = &global_fixed_allocator.allocator;
1131var global_fixed_allocator = std.heap.FixedBufferAllocator.init(global_allocator_mem[0..]);1095var global_fixed_allocator = std.heap.FixedBufferAllocator.init(global_allocator_mem[0..]);
1132var global_allocator_mem: [100 * 1024]u8 = undefined;1096var global_allocator_mem: [100 * 1024]u8 = undefined;
11331097
1134
1135// TODO make thread safe1098// TODO make thread safe
1136var debug_info_allocator: ?&mem.Allocator = null;1099var debug_info_allocator: ?&mem.Allocator = null;
1137var debug_info_direct_allocator: std.heap.DirectAllocator = undefined;1100var debug_info_direct_allocator: std.heap.DirectAllocator = undefined;
std/dwarf.zig-2
...@@ -337,7 +337,6 @@ pub const AT_PGI_lbase = 0x3a00;...@@ -337,7 +337,6 @@ pub const AT_PGI_lbase = 0x3a00;
337pub const AT_PGI_soffset = 0x3a01;337pub const AT_PGI_soffset = 0x3a01;
338pub const AT_PGI_lstride = 0x3a02;338pub const AT_PGI_lstride = 0x3a02;
339339
340
341pub const OP_addr = 0x03;340pub const OP_addr = 0x03;
342pub const OP_deref = 0x06;341pub const OP_deref = 0x06;
343pub const OP_const1u = 0x08;342pub const OP_const1u = 0x08;
...@@ -577,7 +576,6 @@ pub const ATE_HP_unsigned_fixed = 0x8e; // Cobol....@@ -577,7 +576,6 @@ pub const ATE_HP_unsigned_fixed = 0x8e; // Cobol.
577pub const ATE_HP_VAX_complex_float = 0x8f; // F or G floating complex.576pub const ATE_HP_VAX_complex_float = 0x8f; // F or G floating complex.
578pub const ATE_HP_VAX_complex_float_d = 0x90; // D floating complex.577pub const ATE_HP_VAX_complex_float_d = 0x90; // D floating complex.
579578
580
581pub const CFA_advance_loc = 0x40;579pub const CFA_advance_loc = 0x40;
582pub const CFA_offset = 0x80;580pub const CFA_offset = 0x80;
583pub const CFA_restore = 0xc0;581pub const CFA_restore = 0xc0;
std/elf.zig+17-25
...@@ -123,13 +123,11 @@ pub const DT_SYMINFO = 0x6ffffeff;...@@ -123,13 +123,11 @@ pub const DT_SYMINFO = 0x6ffffeff;
123pub const DT_ADDRRNGHI = 0x6ffffeff;123pub const DT_ADDRRNGHI = 0x6ffffeff;
124pub const DT_ADDRNUM = 11;124pub const DT_ADDRNUM = 11;
125125
126
127pub const DT_VERSYM = 0x6ffffff0;126pub const DT_VERSYM = 0x6ffffff0;
128127
129pub const DT_RELACOUNT = 0x6ffffff9;128pub const DT_RELACOUNT = 0x6ffffff9;
130pub const DT_RELCOUNT = 0x6ffffffa;129pub const DT_RELCOUNT = 0x6ffffffa;
131130
132
133pub const DT_FLAGS_1 = 0x6ffffffb;131pub const DT_FLAGS_1 = 0x6ffffffb;
134pub const DT_VERDEF = 0x6ffffffc;132pub const DT_VERDEF = 0x6ffffffc;
135133
...@@ -139,13 +137,10 @@ pub const DT_VERNEED = 0x6ffffffe;...@@ -139,13 +137,10 @@ pub const DT_VERNEED = 0x6ffffffe;
139pub const DT_VERNEEDNUM = 0x6fffffff;137pub const DT_VERNEEDNUM = 0x6fffffff;
140pub const DT_VERSIONTAGNUM = 16;138pub const DT_VERSIONTAGNUM = 16;
141139
142
143
144pub const DT_AUXILIARY = 0x7ffffffd;140pub const DT_AUXILIARY = 0x7ffffffd;
145pub const DT_FILTER = 0x7fffffff;141pub const DT_FILTER = 0x7fffffff;
146pub const DT_EXTRANUM = 3;142pub const DT_EXTRANUM = 3;
147143
148
149pub const DT_SPARC_REGISTER = 0x70000001;144pub const DT_SPARC_REGISTER = 0x70000001;
150pub const DT_SPARC_NUM = 2;145pub const DT_SPARC_NUM = 2;
151146
...@@ -434,9 +429,7 @@ pub const Elf = struct {...@@ -434,9 +429,7 @@ pub const Elf = struct {
434 try elf.in_file.seekForward(4);429 try elf.in_file.seekForward(4);
435430
436 const header_size = try in.readInt(elf.endian, u16);431 const header_size = try in.readInt(elf.endian, u16);
437 if ((elf.is_64 and header_size != 64) or432 if ((elf.is_64 and header_size != 64) or (!elf.is_64 and header_size != 52)) {
438 (!elf.is_64 and header_size != 52))
439 {
440 return error.InvalidFormat;433 return error.InvalidFormat;
441 }434 }
442435
...@@ -467,16 +460,16 @@ pub const Elf = struct {...@@ -467,16 +460,16 @@ pub const Elf = struct {
467 if (sh_entry_size != 64) return error.InvalidFormat;460 if (sh_entry_size != 64) return error.InvalidFormat;
468461
469 for (elf.section_headers) |*elf_section| {462 for (elf.section_headers) |*elf_section| {
470 elf_section.name = try in.readInt(elf.endian, u32);463 elf_section.name = try in.readInt(elf.endian, u32);
471 elf_section.sh_type = try in.readInt(elf.endian, u32);464 elf_section.sh_type = try in.readInt(elf.endian, u32);
472 elf_section.flags = try in.readInt(elf.endian, u64);465 elf_section.flags = try in.readInt(elf.endian, u64);
473 elf_section.addr = try in.readInt(elf.endian, u64);466 elf_section.addr = try in.readInt(elf.endian, u64);
474 elf_section.offset = try in.readInt(elf.endian, u64);467 elf_section.offset = try in.readInt(elf.endian, u64);
475 elf_section.size = try in.readInt(elf.endian, u64);468 elf_section.size = try in.readInt(elf.endian, u64);
476 elf_section.link = try in.readInt(elf.endian, u32);469 elf_section.link = try in.readInt(elf.endian, u32);
477 elf_section.info = try in.readInt(elf.endian, u32);470 elf_section.info = try in.readInt(elf.endian, u32);
478 elf_section.addr_align = try in.readInt(elf.endian, u64);471 elf_section.addr_align = try in.readInt(elf.endian, u64);
479 elf_section.ent_size = try in.readInt(elf.endian, u64);472 elf_section.ent_size = try in.readInt(elf.endian, u64);
480 }473 }
481 } else {474 } else {
482 if (sh_entry_size != 40) return error.InvalidFormat;475 if (sh_entry_size != 40) return error.InvalidFormat;
...@@ -513,8 +506,7 @@ pub const Elf = struct {...@@ -513,8 +506,7 @@ pub const Elf = struct {
513 pub fn close(elf: &Elf) void {506 pub fn close(elf: &Elf) void {
514 elf.allocator.free(elf.section_headers);507 elf.allocator.free(elf.section_headers);
515508
516 if (elf.auto_close_stream)509 if (elf.auto_close_stream) elf.in_file.close();
517 elf.in_file.close();
518 }510 }
519511
520 pub fn findSection(elf: &Elf, name: []const u8) !?&SectionHeader {512 pub fn findSection(elf: &Elf, name: []const u8) !?&SectionHeader {
...@@ -852,27 +844,27 @@ pub const Elf_MIPS_ABIFlags_v0 = extern struct {...@@ -852,27 +844,27 @@ pub const Elf_MIPS_ABIFlags_v0 = extern struct {
852 flags2: Elf32_Word,844 flags2: Elf32_Word,
853};845};
854846
855pub const Ehdr = switch(@sizeOf(usize)) {847pub const Ehdr = switch (@sizeOf(usize)) {
856 4 => Elf32_Ehdr,848 4 => Elf32_Ehdr,
857 8 => Elf64_Ehdr,849 8 => Elf64_Ehdr,
858 else => @compileError("expected pointer size of 32 or 64"),850 else => @compileError("expected pointer size of 32 or 64"),
859};851};
860pub const Phdr = switch(@sizeOf(usize)) {852pub const Phdr = switch (@sizeOf(usize)) {
861 4 => Elf32_Phdr,853 4 => Elf32_Phdr,
862 8 => Elf64_Phdr,854 8 => Elf64_Phdr,
863 else => @compileError("expected pointer size of 32 or 64"),855 else => @compileError("expected pointer size of 32 or 64"),
864};856};
865pub const Sym = switch(@sizeOf(usize)) {857pub const Sym = switch (@sizeOf(usize)) {
866 4 => Elf32_Sym,858 4 => Elf32_Sym,
867 8 => Elf64_Sym,859 8 => Elf64_Sym,
868 else => @compileError("expected pointer size of 32 or 64"),860 else => @compileError("expected pointer size of 32 or 64"),
869};861};
870pub const Verdef = switch(@sizeOf(usize)) {862pub const Verdef = switch (@sizeOf(usize)) {
871 4 => Elf32_Verdef,863 4 => Elf32_Verdef,
872 8 => Elf64_Verdef,864 8 => Elf64_Verdef,
873 else => @compileError("expected pointer size of 32 or 64"),865 else => @compileError("expected pointer size of 32 or 64"),
874};866};
875pub const Verdaux = switch(@sizeOf(usize)) {867pub const Verdaux = switch (@sizeOf(usize)) {
876 4 => Elf32_Verdaux,868 4 => Elf32_Verdaux,
877 8 => Elf64_Verdaux,869 8 => Elf64_Verdaux,
878 else => @compileError("expected pointer size of 32 or 64"),870 else => @compileError("expected pointer size of 32 or 64"),
std/event.zig+22-44
...@@ -6,7 +6,7 @@ const mem = std.mem;...@@ -6,7 +6,7 @@ const mem = std.mem;
6const posix = std.os.posix;6const posix = std.os.posix;
77
8pub const TcpServer = struct {8pub const TcpServer = struct {
9 handleRequestFn: async<&mem.Allocator> fn (&TcpServer, &const std.net.Address, &const std.os.File) void,9 handleRequestFn: async<&mem.Allocator> fn(&TcpServer, &const std.net.Address, &const std.os.File) void,
1010
11 loop: &Loop,11 loop: &Loop,
12 sockfd: i32,12 sockfd: i32,
...@@ -18,13 +18,11 @@ pub const TcpServer = struct {...@@ -18,13 +18,11 @@ pub const TcpServer = struct {
18 const PromiseNode = std.LinkedList(promise).Node;18 const PromiseNode = std.LinkedList(promise).Node;
1919
20 pub fn init(loop: &Loop) !TcpServer {20 pub fn init(loop: &Loop) !TcpServer {
21 const sockfd = try std.os.posixSocket(posix.AF_INET,21 const sockfd = try std.os.posixSocket(posix.AF_INET, posix.SOCK_STREAM | posix.SOCK_CLOEXEC | posix.SOCK_NONBLOCK, posix.PROTO_tcp);
22 posix.SOCK_STREAM|posix.SOCK_CLOEXEC|posix.SOCK_NONBLOCK,
23 posix.PROTO_tcp);
24 errdefer std.os.close(sockfd);22 errdefer std.os.close(sockfd);
2523
26 // TODO can't initialize handler coroutine here because we need well defined copy elision24 // TODO can't initialize handler coroutine here because we need well defined copy elision
27 return TcpServer {25 return TcpServer{
28 .loop = loop,26 .loop = loop,
29 .sockfd = sockfd,27 .sockfd = sockfd,
30 .accept_coro = null,28 .accept_coro = null,
...@@ -34,9 +32,7 @@ pub const TcpServer = struct {...@@ -34,9 +32,7 @@ pub const TcpServer = struct {
34 };32 };
35 }33 }
3634
37 pub fn listen(self: &TcpServer, address: &const std.net.Address,35 pub fn listen(self: &TcpServer, address: &const std.net.Address, handleRequestFn: async<&mem.Allocator> fn(&TcpServer, &const std.net.Address, &const std.os.File) void) !void {
38 handleRequestFn: async<&mem.Allocator> fn (&TcpServer, &const std.net.Address, &const std.os.File)void) !void
39 {
40 self.handleRequestFn = handleRequestFn;36 self.handleRequestFn = handleRequestFn;
4137
42 try std.os.posixBind(self.sockfd, &address.os_addr);38 try std.os.posixBind(self.sockfd, &address.os_addr);
...@@ -48,7 +44,6 @@ pub const TcpServer = struct {...@@ -48,7 +44,6 @@ pub const TcpServer = struct {
4844
49 try self.loop.addFd(self.sockfd, ??self.accept_coro);45 try self.loop.addFd(self.sockfd, ??self.accept_coro);
50 errdefer self.loop.removeFd(self.sockfd);46 errdefer self.loop.removeFd(self.sockfd);
51
52 }47 }
5348
54 pub fn deinit(self: &TcpServer) void {49 pub fn deinit(self: &TcpServer) void {
...@@ -60,9 +55,7 @@ pub const TcpServer = struct {...@@ -60,9 +55,7 @@ pub const TcpServer = struct {
60 pub async fn handler(self: &TcpServer) void {55 pub async fn handler(self: &TcpServer) void {
61 while (true) {56 while (true) {
62 var accepted_addr: std.net.Address = undefined;57 var accepted_addr: std.net.Address = undefined;
63 if (std.os.posixAccept(self.sockfd, &accepted_addr.os_addr,58 if (std.os.posixAccept(self.sockfd, &accepted_addr.os_addr, posix.SOCK_NONBLOCK | posix.SOCK_CLOEXEC)) |accepted_fd| {
64 posix.SOCK_NONBLOCK | posix.SOCK_CLOEXEC)) |accepted_fd|
65 {
66 var socket = std.os.File.openHandle(accepted_fd);59 var socket = std.os.File.openHandle(accepted_fd);
67 _ = async<self.loop.allocator> self.handleRequestFn(self, accepted_addr, socket) catch |err| switch (err) {60 _ = async<self.loop.allocator> self.handleRequestFn(self, accepted_addr, socket) catch |err| switch (err) {
68 error.OutOfMemory => {61 error.OutOfMemory => {
...@@ -83,19 +76,14 @@ pub const TcpServer = struct {...@@ -83,19 +76,14 @@ pub const TcpServer = struct {
83 }76 }
84 continue;77 continue;
85 },78 },
86 error.ConnectionAborted,79 error.ConnectionAborted, error.FileDescriptorClosed => continue,
87 error.FileDescriptorClosed => continue,
8880
89 error.PageFault => unreachable,81 error.PageFault => unreachable,
90 error.InvalidSyscall => unreachable,82 error.InvalidSyscall => unreachable,
91 error.FileDescriptorNotASocket => unreachable,83 error.FileDescriptorNotASocket => unreachable,
92 error.OperationNotSupported => unreachable,84 error.OperationNotSupported => unreachable,
9385
94 error.SystemFdQuotaExceeded,86 error.SystemFdQuotaExceeded, error.SystemResources, error.ProtocolFailure, error.BlockedByFirewall, error.Unexpected => {
95 error.SystemResources,
96 error.ProtocolFailure,
97 error.BlockedByFirewall,
98 error.Unexpected => {
99 @panic("TODO handle this error");87 @panic("TODO handle this error");
100 },88 },
101 }89 }
...@@ -110,7 +98,7 @@ pub const Loop = struct {...@@ -110,7 +98,7 @@ pub const Loop = struct {
11098
111 fn init(allocator: &mem.Allocator) !Loop {99 fn init(allocator: &mem.Allocator) !Loop {
112 const epollfd = try std.os.linuxEpollCreate(std.os.linux.EPOLL_CLOEXEC);100 const epollfd = try std.os.linuxEpollCreate(std.os.linux.EPOLL_CLOEXEC);
113 return Loop {101 return Loop{
114 .keep_running = true,102 .keep_running = true,
115 .allocator = allocator,103 .allocator = allocator,
116 .epollfd = epollfd,104 .epollfd = epollfd,
...@@ -118,11 +106,9 @@ pub const Loop = struct {...@@ -118,11 +106,9 @@ pub const Loop = struct {
118 }106 }
119107
120 pub fn addFd(self: &Loop, fd: i32, prom: promise) !void {108 pub fn addFd(self: &Loop, fd: i32, prom: promise) !void {
121 var ev = std.os.linux.epoll_event {109 var ev = std.os.linux.epoll_event{
122 .events = std.os.linux.EPOLLIN|std.os.linux.EPOLLOUT|std.os.linux.EPOLLET,110 .events = std.os.linux.EPOLLIN | std.os.linux.EPOLLOUT | std.os.linux.EPOLLET,
123 .data = std.os.linux.epoll_data {111 .data = std.os.linux.epoll_data{ .ptr = @ptrToInt(prom) },
124 .ptr = @ptrToInt(prom),
125 },
126 };112 };
127 try std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_ADD, fd, &ev);113 try std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_ADD, fd, &ev);
128 }114 }
...@@ -130,7 +116,6 @@ pub const Loop = struct {...@@ -130,7 +116,6 @@ pub const Loop = struct {
130 pub fn removeFd(self: &Loop, fd: i32) void {116 pub fn removeFd(self: &Loop, fd: i32) void {
131 std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};117 std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};
132 }118 }
133
134 async fn waitFd(self: &Loop, fd: i32) !void {119 async fn waitFd(self: &Loop, fd: i32) !void {
135 defer self.removeFd(fd);120 defer self.removeFd(fd);
136 suspend |p| {121 suspend |p| {
...@@ -157,9 +142,9 @@ pub const Loop = struct {...@@ -157,9 +142,9 @@ pub const Loop = struct {
157};142};
158143
159pub async fn connect(loop: &Loop, _address: &const std.net.Address) !std.os.File {144pub async fn connect(loop: &Loop, _address: &const std.net.Address) !std.os.File {
160 var address = *_address; // TODO https://github.com/zig-lang/zig/issues/733145 var address = _address.*; // TODO https://github.com/ziglang/zig/issues/733
161146
162 const sockfd = try std.os.posixSocket(posix.AF_INET, posix.SOCK_STREAM|posix.SOCK_CLOEXEC|posix.SOCK_NONBLOCK, posix.PROTO_tcp);147 const sockfd = try std.os.posixSocket(posix.AF_INET, posix.SOCK_STREAM | posix.SOCK_CLOEXEC | posix.SOCK_NONBLOCK, posix.PROTO_tcp);
163 errdefer std.os.close(sockfd);148 errdefer std.os.close(sockfd);
164149
165 try std.os.posixConnectAsync(sockfd, &address.os_addr);150 try std.os.posixConnectAsync(sockfd, &address.os_addr);
...@@ -178,12 +163,9 @@ test "listen on a port, send bytes, receive bytes" {...@@ -178,12 +163,9 @@ test "listen on a port, send bytes, receive bytes" {
178 tcp_server: TcpServer,163 tcp_server: TcpServer,
179164
180 const Self = this;165 const Self = this;
181166 async<&mem.Allocator> fn handler(tcp_server: &TcpServer, _addr: &const std.net.Address, _socket: &const std.os.File) void {
182 async<&mem.Allocator> fn handler(tcp_server: &TcpServer, _addr: &const std.net.Address,
183 _socket: &const std.os.File) void
184 {
185 const self = @fieldParentPtr(Self, "tcp_server", tcp_server);167 const self = @fieldParentPtr(Self, "tcp_server", tcp_server);
186 var socket = *_socket; // TODO https://github.com/zig-lang/zig/issues/733168 var socket = _socket.*; // TODO https://github.com/ziglang/zig/issues/733
187 defer socket.close();169 defer socket.close();
188 const next_handler = async errorableHandler(self, _addr, socket) catch |err| switch (err) {170 const next_handler = async errorableHandler(self, _addr, socket) catch |err| switch (err) {
189 error.OutOfMemory => @panic("unable to handle connection: out of memory"),171 error.OutOfMemory => @panic("unable to handle connection: out of memory"),
...@@ -191,14 +173,13 @@ test "listen on a port, send bytes, receive bytes" {...@@ -191,14 +173,13 @@ test "listen on a port, send bytes, receive bytes" {
191 (await next_handler) catch |err| {173 (await next_handler) catch |err| {
192 std.debug.panic("unable to handle connection: {}\n", err);174 std.debug.panic("unable to handle connection: {}\n", err);
193 };175 };
194 suspend |p| { cancel p; }176 suspend |p| {
177 cancel p;
178 }
195 }179 }
196180 async fn errorableHandler(self: &Self, _addr: &const std.net.Address, _socket: &const std.os.File) !void {
197 async fn errorableHandler(self: &Self, _addr: &const std.net.Address,181 const addr = _addr.*; // TODO https://github.com/ziglang/zig/issues/733
198 _socket: &const std.os.File) !void182 var socket = _socket.*; // TODO https://github.com/ziglang/zig/issues/733
199 {
200 const addr = *_addr; // TODO https://github.com/zig-lang/zig/issues/733
201 var socket = *_socket; // TODO https://github.com/zig-lang/zig/issues/733
202183
203 var adapter = std.io.FileOutStream.init(&socket);184 var adapter = std.io.FileOutStream.init(&socket);
204 var stream = &adapter.stream;185 var stream = &adapter.stream;
...@@ -210,9 +191,7 @@ test "listen on a port, send bytes, receive bytes" {...@@ -210,9 +191,7 @@ test "listen on a port, send bytes, receive bytes" {
210 const addr = std.net.Address.initIp4(ip4addr, 0);191 const addr = std.net.Address.initIp4(ip4addr, 0);
211192
212 var loop = try Loop.init(std.debug.global_allocator);193 var loop = try Loop.init(std.debug.global_allocator);
213 var server = MyServer {194 var server = MyServer{ .tcp_server = try TcpServer.init(&loop) };
214 .tcp_server = try TcpServer.init(&loop),
215 };
216 defer server.tcp_server.deinit();195 defer server.tcp_server.deinit();
217 try server.tcp_server.listen(addr, MyServer.handler);196 try server.tcp_server.listen(addr, MyServer.handler);
218197
...@@ -220,7 +199,6 @@ test "listen on a port, send bytes, receive bytes" {...@@ -220,7 +199,6 @@ test "listen on a port, send bytes, receive bytes" {
220 defer cancel p;199 defer cancel p;
221 loop.run();200 loop.run();
222}201}
223
224async fn doAsyncTest(loop: &Loop, address: &const std.net.Address) void {202async fn doAsyncTest(loop: &Loop, address: &const std.net.Address) void {
225 errdefer @panic("test failure");203 errdefer @panic("test failure");
226204
std/fmt/errol/enum3.zig+3-4
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1pub const enum3 = []u64 {1pub const enum3 = []u64{
2 0x4e2e2785c3a2a20b,2 0x4e2e2785c3a2a20b,
3 0x240a28877a09a4e1,3 0x240a28877a09a4e1,
4 0x728fca36c06cf106,4 0x728fca36c06cf106,
...@@ -439,13 +439,13 @@ const Slab = struct {...@@ -439,13 +439,13 @@ const Slab = struct {
439};439};
440440
441fn slab(str: []const u8, exp: i32) Slab {441fn slab(str: []const u8, exp: i32) Slab {
442 return Slab {442 return Slab{
443 .str = str,443 .str = str,
444 .exp = exp,444 .exp = exp,
445 };445 };
446}446}
447447
448pub const enum3_data = []Slab {448pub const enum3_data = []Slab{
449 slab("40648030339495312", 69),449 slab("40648030339495312", 69),
450 slab("4498645355592131", -134),450 slab("4498645355592131", -134),
451 slab("678321594594593", 244),451 slab("678321594594593", 244),
...@@ -879,4 +879,3 @@ pub const enum3_data = []Slab {...@@ -879,4 +879,3 @@ pub const enum3_data = []Slab {
879 slab("32216657306260762", 218),879 slab("32216657306260762", 218),
880 slab("30423431424080128", 219),880 slab("30423431424080128", 219),
881};881};
882
std/fmt/errol/index.zig+23-34
...@@ -86,7 +86,7 @@ pub fn errol3(value: f64, buffer: []u8) FloatDecimal {...@@ -86,7 +86,7 @@ pub fn errol3(value: f64, buffer: []u8) FloatDecimal {
86 const data = enum3_data[i];86 const data = enum3_data[i];
87 const digits = buffer[1..data.str.len + 1];87 const digits = buffer[1..data.str.len + 1];
88 mem.copy(u8, digits, data.str);88 mem.copy(u8, digits, data.str);
89 return FloatDecimal {89 return FloatDecimal{
90 .digits = digits,90 .digits = digits,
91 .exp = data.exp,91 .exp = data.exp,
92 };92 };
...@@ -98,14 +98,12 @@ pub fn errol3(value: f64, buffer: []u8) FloatDecimal {...@@ -98,14 +98,12 @@ pub fn errol3(value: f64, buffer: []u8) FloatDecimal {
98/// Uncorrected Errol3 double to ASCII conversion.98/// Uncorrected Errol3 double to ASCII conversion.
99fn errol3u(val: f64, buffer: []u8) FloatDecimal {99fn errol3u(val: f64, buffer: []u8) FloatDecimal {
100 // check if in integer or fixed range100 // check if in integer or fixed range
101
102 if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {101 if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {
103 return errolInt(val, buffer);102 return errolInt(val, buffer);
104 } else if (val >= 16.0 and val < 9.007199254740992e15) {103 } else if (val >= 16.0 and val < 9.007199254740992e15) {
105 return errolFixed(val, buffer);104 return errolFixed(val, buffer);
106 }105 }
107106
108
109 // normalize the midpoint107 // normalize the midpoint
110108
111 const e = math.frexp(val).exponent;109 const e = math.frexp(val).exponent;
...@@ -137,11 +135,11 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {...@@ -137,11 +135,11 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {
137 }135 }
138136
139 // compute boundaries137 // compute boundaries
140 var high = HP {138 var high = HP{
141 .val = mid.val,139 .val = mid.val,
142 .off = mid.off + (fpnext(val) - val) * lten * ten / 2.0,140 .off = mid.off + (fpnext(val) - val) * lten * ten / 2.0,
143 };141 };
144 var low = HP {142 var low = HP{
145 .val = mid.val,143 .val = mid.val,
146 .off = mid.off + (fpprev(val) - val) * lten * ten / 2.0,144 .off = mid.off + (fpprev(val) - val) * lten * ten / 2.0,
147 };145 };
...@@ -171,15 +169,12 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {...@@ -171,15 +169,12 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {
171 var buf_index: usize = 1;169 var buf_index: usize = 1;
172 while (true) {170 while (true) {
173 var hdig = u8(math.floor(high.val));171 var hdig = u8(math.floor(high.val));
174 if ((high.val == f64(hdig)) and (high.off < 0))172 if ((high.val == f64(hdig)) and (high.off < 0)) hdig -= 1;
175 hdig -= 1;
176173
177 var ldig = u8(math.floor(low.val));174 var ldig = u8(math.floor(low.val));
178 if ((low.val == f64(ldig)) and (low.off < 0))175 if ((low.val == f64(ldig)) and (low.off < 0)) ldig -= 1;
179 ldig -= 1;
180176
181 if (ldig != hdig)177 if (ldig != hdig) break;
182 break;
183178
184 buffer[buf_index] = hdig + '0';179 buffer[buf_index] = hdig + '0';
185 buf_index += 1;180 buf_index += 1;
...@@ -191,13 +186,12 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {...@@ -191,13 +186,12 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {
191186
192 const tmp = (high.val + low.val) / 2.0;187 const tmp = (high.val + low.val) / 2.0;
193 var mdig = u8(math.floor(tmp + 0.5));188 var mdig = u8(math.floor(tmp + 0.5));
194 if ((f64(mdig) - tmp) == 0.5 and (mdig & 0x1) != 0)189 if ((f64(mdig) - tmp) == 0.5 and (mdig & 0x1) != 0) mdig -= 1;
195 mdig -= 1;
196190
197 buffer[buf_index] = mdig + '0';191 buffer[buf_index] = mdig + '0';
198 buf_index += 1;192 buf_index += 1;
199193
200 return FloatDecimal {194 return FloatDecimal{
201 .digits = buffer[1..buf_index],195 .digits = buffer[1..buf_index],
202 .exp = exp,196 .exp = exp,
203 };197 };
...@@ -235,7 +229,7 @@ fn hpProd(in: &const HP, val: f64) HP {...@@ -235,7 +229,7 @@ fn hpProd(in: &const HP, val: f64) HP {
235 const p = in.val * val;229 const p = in.val * val;
236 const e = ((hi * hi2 - p) + lo * hi2 + hi * lo2) + lo * lo2;230 const e = ((hi * hi2 - p) + lo * hi2 + hi * lo2) + lo * lo2;
237231
238 return HP {232 return HP{
239 .val = p,233 .val = p,
240 .off = in.off * val + e,234 .off = in.off * val + e,
241 };235 };
...@@ -246,8 +240,8 @@ fn hpProd(in: &const HP, val: f64) HP {...@@ -246,8 +240,8 @@ fn hpProd(in: &const HP, val: f64) HP {
246/// @hi: The high bits.240/// @hi: The high bits.
247/// @lo: The low bits.241/// @lo: The low bits.
248fn split(val: f64, hi: &f64, lo: &f64) void {242fn split(val: f64, hi: &f64, lo: &f64) void {
249 *hi = gethi(val);243 hi.* = gethi(val);
250 *lo = val - *hi;244 lo.* = val - hi.*;
251}245}
252246
253fn gethi(in: f64) f64 {247fn gethi(in: f64) f64 {
...@@ -301,7 +295,6 @@ fn hpMul10(hp: &HP) void {...@@ -301,7 +295,6 @@ fn hpMul10(hp: &HP) void {
301 hpNormalize(hp);295 hpNormalize(hp);
302}296}
303297
304
305/// Integer conversion algorithm, guaranteed correct, optimal, and best.298/// Integer conversion algorithm, guaranteed correct, optimal, and best.
306/// @val: The val.299/// @val: The val.
307/// @buf: The output buffer.300/// @buf: The output buffer.
...@@ -343,8 +336,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {...@@ -343,8 +336,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
343 }336 }
344 const m64 = @truncate(u64, @divTrunc(mid, x));337 const m64 = @truncate(u64, @divTrunc(mid, x));
345338
346 if (lf != hf)339 if (lf != hf) mi += 19;
347 mi += 19;
348340
349 var buf_index = u64toa(m64, buffer) - 1;341 var buf_index = u64toa(m64, buffer) - 1;
350342
...@@ -354,7 +346,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {...@@ -354,7 +346,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
354 buf_index += 1;346 buf_index += 1;
355 }347 }
356348
357 return FloatDecimal {349 return FloatDecimal{
358 .digits = buffer[0..buf_index],350 .digits = buffer[0..buf_index],
359 .exp = i32(buf_index) + mi,351 .exp = i32(buf_index) + mi,
360 };352 };
...@@ -396,25 +388,24 @@ fn errolFixed(val: f64, buffer: []u8) FloatDecimal {...@@ -396,25 +388,24 @@ fn errolFixed(val: f64, buffer: []u8) FloatDecimal {
396 buffer[j] = u8(mdig + '0');388 buffer[j] = u8(mdig + '0');
397 j += 1;389 j += 1;
398390
399 if(hdig != ldig or j > 50)391 if (hdig != ldig or j > 50) break;
400 break;
401 }392 }
402393
403 if (mid > 0.5) {394 if (mid > 0.5) {
404 buffer[j-1] += 1;395 buffer[j - 1] += 1;
405 } else if ((mid == 0.5) and (buffer[j-1] & 0x1) != 0) {396 } else if ((mid == 0.5) and (buffer[j - 1] & 0x1) != 0) {
406 buffer[j-1] += 1;397 buffer[j - 1] += 1;
407 }398 }
408 } else {399 } else {
409 while (buffer[j-1] == '0') {400 while (buffer[j - 1] == '0') {
410 buffer[j-1] = 0;401 buffer[j - 1] = 0;
411 j -= 1;402 j -= 1;
412 }403 }
413 }404 }
414405
415 buffer[j] = 0;406 buffer[j] = 0;
416407
417 return FloatDecimal {408 return FloatDecimal{
418 .digits = buffer[0..j],409 .digits = buffer[0..j],
419 .exp = exp,410 .exp = exp,
420 };411 };
...@@ -428,7 +419,7 @@ fn fpprev(val: f64) f64 {...@@ -428,7 +419,7 @@ fn fpprev(val: f64) f64 {
428 return @bitCast(f64, @bitCast(u64, val) -% 1);419 return @bitCast(f64, @bitCast(u64, val) -% 1);
429}420}
430421
431pub const c_digits_lut = []u8 {422pub const c_digits_lut = []u8{
432 '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6',423 '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6',
433 '0', '7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3',424 '0', '7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3',
434 '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0',425 '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0',
...@@ -587,7 +578,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize {...@@ -587,7 +578,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize {
587 buffer[buf_index] = c_digits_lut[d8 + 1];578 buffer[buf_index] = c_digits_lut[d8 + 1];
588 buf_index += 1;579 buf_index += 1;
589 } else {580 } else {
590 const a = u32(value / kTen16); // 1 to 1844581 const a = u32(value / kTen16); // 1 to 1844
591 value %= kTen16;582 value %= kTen16;
592583
593 if (a < 10) {584 if (a < 10) {
...@@ -686,7 +677,6 @@ fn fpeint(from: f64) u128 {...@@ -686,7 +677,6 @@ fn fpeint(from: f64) u128 {
686 return u128(1) << @truncate(u7, (bits >> 52) -% 1023);677 return u128(1) << @truncate(u7, (bits >> 52) -% 1023);
687}678}
688679
689
690/// Given two different integers with the same length in terms of the number680/// Given two different integers with the same length in terms of the number
691/// of decimal digits, index the digits from the right-most position starting681/// of decimal digits, index the digits from the right-most position starting
692/// from zero, find the first index where the digits in the two integers682/// from zero, find the first index where the digits in the two integers
...@@ -713,7 +703,6 @@ fn mismatch10(a: u64, b: u64) i32 {...@@ -713,7 +703,6 @@ fn mismatch10(a: u64, b: u64) i32 {
713 a_copy /= 10;703 a_copy /= 10;
714 b_copy /= 10;704 b_copy /= 10;
715705
716 if (a_copy == b_copy)706 if (a_copy == b_copy) return i;
717 return i;
718 }707 }
719}708}
std/fmt/errol/lookup.zig+600-600
...@@ -3,604 +3,604 @@ pub const HP = struct {...@@ -3,604 +3,604 @@ pub const HP = struct {
3 off: f64,3 off: f64,
4};4};
5pub const lookup_table = []HP{5pub const lookup_table = []HP{
6 HP{.val=1.000000e+308, .off= -1.097906362944045488e+291 },6 HP{ .val = 1.000000e+308, .off = -1.097906362944045488e+291 },
7 HP{.val=1.000000e+307, .off= 1.396894023974354241e+290 },7 HP{ .val = 1.000000e+307, .off = 1.396894023974354241e+290 },
8 HP{.val=1.000000e+306, .off= -1.721606459673645508e+289 },8 HP{ .val = 1.000000e+306, .off = -1.721606459673645508e+289 },
9 HP{.val=1.000000e+305, .off= 6.074644749446353973e+288 },9 HP{ .val = 1.000000e+305, .off = 6.074644749446353973e+288 },
10 HP{.val=1.000000e+304, .off= 6.074644749446353567e+287 },10 HP{ .val = 1.000000e+304, .off = 6.074644749446353567e+287 },
11 HP{.val=1.000000e+303, .off= -1.617650767864564452e+284 },11 HP{ .val = 1.000000e+303, .off = -1.617650767864564452e+284 },
12 HP{.val=1.000000e+302, .off= -7.629703079084895055e+285 },12 HP{ .val = 1.000000e+302, .off = -7.629703079084895055e+285 },
13 HP{.val=1.000000e+301, .off= -5.250476025520442286e+284 },13 HP{ .val = 1.000000e+301, .off = -5.250476025520442286e+284 },
14 HP{.val=1.000000e+300, .off= -5.250476025520441956e+283 },14 HP{ .val = 1.000000e+300, .off = -5.250476025520441956e+283 },
15 HP{.val=1.000000e+299, .off= -5.250476025520441750e+282 },15 HP{ .val = 1.000000e+299, .off = -5.250476025520441750e+282 },
16 HP{.val=1.000000e+298, .off= 4.043379652465702264e+281 },16 HP{ .val = 1.000000e+298, .off = 4.043379652465702264e+281 },
17 HP{.val=1.000000e+297, .off= -1.765280146275637946e+280 },17 HP{ .val = 1.000000e+297, .off = -1.765280146275637946e+280 },
18 HP{.val=1.000000e+296, .off= 1.865132227937699609e+279 },18 HP{ .val = 1.000000e+296, .off = 1.865132227937699609e+279 },
19 HP{.val=1.000000e+295, .off= 1.865132227937699609e+278 },19 HP{ .val = 1.000000e+295, .off = 1.865132227937699609e+278 },
20 HP{.val=1.000000e+294, .off= -6.643646774124810287e+277 },20 HP{ .val = 1.000000e+294, .off = -6.643646774124810287e+277 },
21 HP{.val=1.000000e+293, .off= 7.537651562646039934e+276 },21 HP{ .val = 1.000000e+293, .off = 7.537651562646039934e+276 },
22 HP{.val=1.000000e+292, .off= -1.325659897835741608e+275 },22 HP{ .val = 1.000000e+292, .off = -1.325659897835741608e+275 },
23 HP{.val=1.000000e+291, .off= 4.213909764965371606e+274 },23 HP{ .val = 1.000000e+291, .off = 4.213909764965371606e+274 },
24 HP{.val=1.000000e+290, .off= -6.172783352786715670e+273 },24 HP{ .val = 1.000000e+290, .off = -6.172783352786715670e+273 },
25 HP{.val=1.000000e+289, .off= -6.172783352786715670e+272 },25 HP{ .val = 1.000000e+289, .off = -6.172783352786715670e+272 },
26 HP{.val=1.000000e+288, .off= -7.630473539575035471e+270 },26 HP{ .val = 1.000000e+288, .off = -7.630473539575035471e+270 },
27 HP{.val=1.000000e+287, .off= -7.525217352494018700e+270 },27 HP{ .val = 1.000000e+287, .off = -7.525217352494018700e+270 },
28 HP{.val=1.000000e+286, .off= -3.298861103408696612e+269 },28 HP{ .val = 1.000000e+286, .off = -3.298861103408696612e+269 },
29 HP{.val=1.000000e+285, .off= 1.984084207947955778e+268 },29 HP{ .val = 1.000000e+285, .off = 1.984084207947955778e+268 },
30 HP{.val=1.000000e+284, .off= -7.921438250845767591e+267 },30 HP{ .val = 1.000000e+284, .off = -7.921438250845767591e+267 },
31 HP{.val=1.000000e+283, .off= 4.460464822646386735e+266 },31 HP{ .val = 1.000000e+283, .off = 4.460464822646386735e+266 },
32 HP{.val=1.000000e+282, .off= -3.278224598286209647e+265 },32 HP{ .val = 1.000000e+282, .off = -3.278224598286209647e+265 },
33 HP{.val=1.000000e+281, .off= -3.278224598286209737e+264 },33 HP{ .val = 1.000000e+281, .off = -3.278224598286209737e+264 },
34 HP{.val=1.000000e+280, .off= -3.278224598286209961e+263 },34 HP{ .val = 1.000000e+280, .off = -3.278224598286209961e+263 },
35 HP{.val=1.000000e+279, .off= -5.797329227496039232e+262 },35 HP{ .val = 1.000000e+279, .off = -5.797329227496039232e+262 },
36 HP{.val=1.000000e+278, .off= 3.649313132040821498e+261 },36 HP{ .val = 1.000000e+278, .off = 3.649313132040821498e+261 },
37 HP{.val=1.000000e+277, .off= -2.867878510995372374e+259 },37 HP{ .val = 1.000000e+277, .off = -2.867878510995372374e+259 },
38 HP{.val=1.000000e+276, .off= -5.206914080024985409e+259 },38 HP{ .val = 1.000000e+276, .off = -5.206914080024985409e+259 },
39 HP{.val=1.000000e+275, .off= 4.018322599210230404e+258 },39 HP{ .val = 1.000000e+275, .off = 4.018322599210230404e+258 },
40 HP{.val=1.000000e+274, .off= 7.862171215558236495e+257 },40 HP{ .val = 1.000000e+274, .off = 7.862171215558236495e+257 },
41 HP{.val=1.000000e+273, .off= 5.459765830340732821e+256 },41 HP{ .val = 1.000000e+273, .off = 5.459765830340732821e+256 },
42 HP{.val=1.000000e+272, .off= -6.552261095746788047e+255 },42 HP{ .val = 1.000000e+272, .off = -6.552261095746788047e+255 },
43 HP{.val=1.000000e+271, .off= 4.709014147460262298e+254 },43 HP{ .val = 1.000000e+271, .off = 4.709014147460262298e+254 },
44 HP{.val=1.000000e+270, .off= -4.675381888545612729e+253 },44 HP{ .val = 1.000000e+270, .off = -4.675381888545612729e+253 },
45 HP{.val=1.000000e+269, .off= -4.675381888545612892e+252 },45 HP{ .val = 1.000000e+269, .off = -4.675381888545612892e+252 },
46 HP{.val=1.000000e+268, .off= 2.656177514583977380e+251 },46 HP{ .val = 1.000000e+268, .off = 2.656177514583977380e+251 },
47 HP{.val=1.000000e+267, .off= 2.656177514583977190e+250 },47 HP{ .val = 1.000000e+267, .off = 2.656177514583977190e+250 },
48 HP{.val=1.000000e+266, .off= -3.071603269111014892e+249 },48 HP{ .val = 1.000000e+266, .off = -3.071603269111014892e+249 },
49 HP{.val=1.000000e+265, .off= -6.651466258920385440e+248 },49 HP{ .val = 1.000000e+265, .off = -6.651466258920385440e+248 },
50 HP{.val=1.000000e+264, .off= -4.414051890289528972e+247 },50 HP{ .val = 1.000000e+264, .off = -4.414051890289528972e+247 },
51 HP{.val=1.000000e+263, .off= -1.617283929500958387e+246 },51 HP{ .val = 1.000000e+263, .off = -1.617283929500958387e+246 },
52 HP{.val=1.000000e+262, .off= -1.617283929500958241e+245 },52 HP{ .val = 1.000000e+262, .off = -1.617283929500958241e+245 },
53 HP{.val=1.000000e+261, .off= 7.122615947963323868e+244 },53 HP{ .val = 1.000000e+261, .off = 7.122615947963323868e+244 },
54 HP{.val=1.000000e+260, .off= -6.533477610574617382e+243 },54 HP{ .val = 1.000000e+260, .off = -6.533477610574617382e+243 },
55 HP{.val=1.000000e+259, .off= 7.122615947963323982e+242 },55 HP{ .val = 1.000000e+259, .off = 7.122615947963323982e+242 },
56 HP{.val=1.000000e+258, .off= -5.679971763165996225e+241 },56 HP{ .val = 1.000000e+258, .off = -5.679971763165996225e+241 },
57 HP{.val=1.000000e+257, .off= -3.012765990014054219e+240 },57 HP{ .val = 1.000000e+257, .off = -3.012765990014054219e+240 },
58 HP{.val=1.000000e+256, .off= -3.012765990014054219e+239 },58 HP{ .val = 1.000000e+256, .off = -3.012765990014054219e+239 },
59 HP{.val=1.000000e+255, .off= 1.154743030535854616e+238 },59 HP{ .val = 1.000000e+255, .off = 1.154743030535854616e+238 },
60 HP{.val=1.000000e+254, .off= 6.364129306223240767e+237 },60 HP{ .val = 1.000000e+254, .off = 6.364129306223240767e+237 },
61 HP{.val=1.000000e+253, .off= 6.364129306223241129e+236 },61 HP{ .val = 1.000000e+253, .off = 6.364129306223241129e+236 },
62 HP{.val=1.000000e+252, .off= -9.915202805299840595e+235 },62 HP{ .val = 1.000000e+252, .off = -9.915202805299840595e+235 },
63 HP{.val=1.000000e+251, .off= -4.827911520448877980e+234 },63 HP{ .val = 1.000000e+251, .off = -4.827911520448877980e+234 },
64 HP{.val=1.000000e+250, .off= 7.890316691678530146e+233 },64 HP{ .val = 1.000000e+250, .off = 7.890316691678530146e+233 },
65 HP{.val=1.000000e+249, .off= 7.890316691678529484e+232 },65 HP{ .val = 1.000000e+249, .off = 7.890316691678529484e+232 },
66 HP{.val=1.000000e+248, .off= -4.529828046727141859e+231 },66 HP{ .val = 1.000000e+248, .off = -4.529828046727141859e+231 },
67 HP{.val=1.000000e+247, .off= 4.785280507077111924e+230 },67 HP{ .val = 1.000000e+247, .off = 4.785280507077111924e+230 },
68 HP{.val=1.000000e+246, .off= -6.858605185178205305e+229 },68 HP{ .val = 1.000000e+246, .off = -6.858605185178205305e+229 },
69 HP{.val=1.000000e+245, .off= -4.432795665958347728e+228 },69 HP{ .val = 1.000000e+245, .off = -4.432795665958347728e+228 },
70 HP{.val=1.000000e+244, .off= -7.465057564983169531e+227 },70 HP{ .val = 1.000000e+244, .off = -7.465057564983169531e+227 },
71 HP{.val=1.000000e+243, .off= -7.465057564983169741e+226 },71 HP{ .val = 1.000000e+243, .off = -7.465057564983169741e+226 },
72 HP{.val=1.000000e+242, .off= -5.096102956370027445e+225 },72 HP{ .val = 1.000000e+242, .off = -5.096102956370027445e+225 },
73 HP{.val=1.000000e+241, .off= -5.096102956370026952e+224 },73 HP{ .val = 1.000000e+241, .off = -5.096102956370026952e+224 },
74 HP{.val=1.000000e+240, .off= -1.394611380411992474e+223 },74 HP{ .val = 1.000000e+240, .off = -1.394611380411992474e+223 },
75 HP{.val=1.000000e+239, .off= 9.188208545617793960e+221 },75 HP{ .val = 1.000000e+239, .off = 9.188208545617793960e+221 },
76 HP{.val=1.000000e+238, .off= -4.864759732872650359e+221 },76 HP{ .val = 1.000000e+238, .off = -4.864759732872650359e+221 },
77 HP{.val=1.000000e+237, .off= 5.979453868566904629e+220 },77 HP{ .val = 1.000000e+237, .off = 5.979453868566904629e+220 },
78 HP{.val=1.000000e+236, .off= -5.316601966265964857e+219 },78 HP{ .val = 1.000000e+236, .off = -5.316601966265964857e+219 },
79 HP{.val=1.000000e+235, .off= -5.316601966265964701e+218 },79 HP{ .val = 1.000000e+235, .off = -5.316601966265964701e+218 },
80 HP{.val=1.000000e+234, .off= -1.786584517880693123e+217 },80 HP{ .val = 1.000000e+234, .off = -1.786584517880693123e+217 },
81 HP{.val=1.000000e+233, .off= 2.625937292600896716e+216 },81 HP{ .val = 1.000000e+233, .off = 2.625937292600896716e+216 },
82 HP{.val=1.000000e+232, .off= -5.647541102052084079e+215 },82 HP{ .val = 1.000000e+232, .off = -5.647541102052084079e+215 },
83 HP{.val=1.000000e+231, .off= -5.647541102052083888e+214 },83 HP{ .val = 1.000000e+231, .off = -5.647541102052083888e+214 },
84 HP{.val=1.000000e+230, .off= -9.956644432600511943e+213 },84 HP{ .val = 1.000000e+230, .off = -9.956644432600511943e+213 },
85 HP{.val=1.000000e+229, .off= 8.161138937705571862e+211 },85 HP{ .val = 1.000000e+229, .off = 8.161138937705571862e+211 },
86 HP{.val=1.000000e+228, .off= 7.549087847752475275e+211 },86 HP{ .val = 1.000000e+228, .off = 7.549087847752475275e+211 },
87 HP{.val=1.000000e+227, .off= -9.283347037202319948e+210 },87 HP{ .val = 1.000000e+227, .off = -9.283347037202319948e+210 },
88 HP{.val=1.000000e+226, .off= 3.866992716668613820e+209 },88 HP{ .val = 1.000000e+226, .off = 3.866992716668613820e+209 },
89 HP{.val=1.000000e+225, .off= 7.154577655136347262e+208 },89 HP{ .val = 1.000000e+225, .off = 7.154577655136347262e+208 },
90 HP{.val=1.000000e+224, .off= 3.045096482051680688e+207 },90 HP{ .val = 1.000000e+224, .off = 3.045096482051680688e+207 },
91 HP{.val=1.000000e+223, .off= -4.660180717482069567e+206 },91 HP{ .val = 1.000000e+223, .off = -4.660180717482069567e+206 },
92 HP{.val=1.000000e+222, .off= -4.660180717482070101e+205 },92 HP{ .val = 1.000000e+222, .off = -4.660180717482070101e+205 },
93 HP{.val=1.000000e+221, .off= -4.660180717482069544e+204 },93 HP{ .val = 1.000000e+221, .off = -4.660180717482069544e+204 },
94 HP{.val=1.000000e+220, .off= 3.562757926310489022e+202 },94 HP{ .val = 1.000000e+220, .off = 3.562757926310489022e+202 },
95 HP{.val=1.000000e+219, .off= 3.491561111451748149e+202 },95 HP{ .val = 1.000000e+219, .off = 3.491561111451748149e+202 },
96 HP{.val=1.000000e+218, .off= -8.265758834125874135e+201 },96 HP{ .val = 1.000000e+218, .off = -8.265758834125874135e+201 },
97 HP{.val=1.000000e+217, .off= 3.981449442517482365e+200 },97 HP{ .val = 1.000000e+217, .off = 3.981449442517482365e+200 },
98 HP{.val=1.000000e+216, .off= -2.142154695804195936e+199 },98 HP{ .val = 1.000000e+216, .off = -2.142154695804195936e+199 },
99 HP{.val=1.000000e+215, .off= 9.339603063548950188e+198 },99 HP{ .val = 1.000000e+215, .off = 9.339603063548950188e+198 },
100 HP{.val=1.000000e+214, .off= 4.555537330485139746e+197 },100 HP{ .val = 1.000000e+214, .off = 4.555537330485139746e+197 },
101 HP{.val=1.000000e+213, .off= 1.565496247320257804e+196 },101 HP{ .val = 1.000000e+213, .off = 1.565496247320257804e+196 },
102 HP{.val=1.000000e+212, .off= 9.040598955232462036e+195 },102 HP{ .val = 1.000000e+212, .off = 9.040598955232462036e+195 },
103 HP{.val=1.000000e+211, .off= 4.368659762787334780e+194 },103 HP{ .val = 1.000000e+211, .off = 4.368659762787334780e+194 },
104 HP{.val=1.000000e+210, .off= 7.288621758065539072e+193 },104 HP{ .val = 1.000000e+210, .off = 7.288621758065539072e+193 },
105 HP{.val=1.000000e+209, .off= -7.311188218325485628e+192 },105 HP{ .val = 1.000000e+209, .off = -7.311188218325485628e+192 },
106 HP{.val=1.000000e+208, .off= 1.813693016918905189e+191 },106 HP{ .val = 1.000000e+208, .off = 1.813693016918905189e+191 },
107 HP{.val=1.000000e+207, .off= -3.889357755108838992e+190 },107 HP{ .val = 1.000000e+207, .off = -3.889357755108838992e+190 },
108 HP{.val=1.000000e+206, .off= -3.889357755108838992e+189 },108 HP{ .val = 1.000000e+206, .off = -3.889357755108838992e+189 },
109 HP{.val=1.000000e+205, .off= -1.661603547285501360e+188 },109 HP{ .val = 1.000000e+205, .off = -1.661603547285501360e+188 },
110 HP{.val=1.000000e+204, .off= 1.123089212493670643e+187 },110 HP{ .val = 1.000000e+204, .off = 1.123089212493670643e+187 },
111 HP{.val=1.000000e+203, .off= 1.123089212493670643e+186 },111 HP{ .val = 1.000000e+203, .off = 1.123089212493670643e+186 },
112 HP{.val=1.000000e+202, .off= 9.825254086803583029e+185 },112 HP{ .val = 1.000000e+202, .off = 9.825254086803583029e+185 },
113 HP{.val=1.000000e+201, .off= -3.771878529305654999e+184 },113 HP{ .val = 1.000000e+201, .off = -3.771878529305654999e+184 },
114 HP{.val=1.000000e+200, .off= 3.026687778748963675e+183 },114 HP{ .val = 1.000000e+200, .off = 3.026687778748963675e+183 },
115 HP{.val=1.000000e+199, .off= -9.720624048853446693e+182 },115 HP{ .val = 1.000000e+199, .off = -9.720624048853446693e+182 },
116 HP{.val=1.000000e+198, .off= -1.753554156601940139e+181 },116 HP{ .val = 1.000000e+198, .off = -1.753554156601940139e+181 },
117 HP{.val=1.000000e+197, .off= 4.885670753607648963e+180 },117 HP{ .val = 1.000000e+197, .off = 4.885670753607648963e+180 },
118 HP{.val=1.000000e+196, .off= 4.885670753607648963e+179 },118 HP{ .val = 1.000000e+196, .off = 4.885670753607648963e+179 },
119 HP{.val=1.000000e+195, .off= 2.292223523057028076e+178 },119 HP{ .val = 1.000000e+195, .off = 2.292223523057028076e+178 },
120 HP{.val=1.000000e+194, .off= 5.534032561245303825e+177 },120 HP{ .val = 1.000000e+194, .off = 5.534032561245303825e+177 },
121 HP{.val=1.000000e+193, .off= -6.622751331960730683e+176 },121 HP{ .val = 1.000000e+193, .off = -6.622751331960730683e+176 },
122 HP{.val=1.000000e+192, .off= -4.090088020876139692e+175 },122 HP{ .val = 1.000000e+192, .off = -4.090088020876139692e+175 },
123 HP{.val=1.000000e+191, .off= -7.255917159731877552e+174 },123 HP{ .val = 1.000000e+191, .off = -7.255917159731877552e+174 },
124 HP{.val=1.000000e+190, .off= -7.255917159731877992e+173 },124 HP{ .val = 1.000000e+190, .off = -7.255917159731877992e+173 },
125 HP{.val=1.000000e+189, .off= -2.309309130269787104e+172 },125 HP{ .val = 1.000000e+189, .off = -2.309309130269787104e+172 },
126 HP{.val=1.000000e+188, .off= -2.309309130269787019e+171 },126 HP{ .val = 1.000000e+188, .off = -2.309309130269787019e+171 },
127 HP{.val=1.000000e+187, .off= 9.284303438781988230e+170 },127 HP{ .val = 1.000000e+187, .off = 9.284303438781988230e+170 },
128 HP{.val=1.000000e+186, .off= 2.038295583124628364e+169 },128 HP{ .val = 1.000000e+186, .off = 2.038295583124628364e+169 },
129 HP{.val=1.000000e+185, .off= 2.038295583124628532e+168 },129 HP{ .val = 1.000000e+185, .off = 2.038295583124628532e+168 },
130 HP{.val=1.000000e+184, .off= -1.735666841696912925e+167 },130 HP{ .val = 1.000000e+184, .off = -1.735666841696912925e+167 },
131 HP{.val=1.000000e+183, .off= 5.340512704843477241e+166 },131 HP{ .val = 1.000000e+183, .off = 5.340512704843477241e+166 },
132 HP{.val=1.000000e+182, .off= -6.453119872723839321e+165 },132 HP{ .val = 1.000000e+182, .off = -6.453119872723839321e+165 },
133 HP{.val=1.000000e+181, .off= 8.288920849235306587e+164 },133 HP{ .val = 1.000000e+181, .off = 8.288920849235306587e+164 },
134 HP{.val=1.000000e+180, .off= -9.248546019891598293e+162 },134 HP{ .val = 1.000000e+180, .off = -9.248546019891598293e+162 },
135 HP{.val=1.000000e+179, .off= 1.954450226518486016e+162 },135 HP{ .val = 1.000000e+179, .off = 1.954450226518486016e+162 },
136 HP{.val=1.000000e+178, .off= -5.243811844750628197e+161 },136 HP{ .val = 1.000000e+178, .off = -5.243811844750628197e+161 },
137 HP{.val=1.000000e+177, .off= -7.448980502074320639e+159 },137 HP{ .val = 1.000000e+177, .off = -7.448980502074320639e+159 },
138 HP{.val=1.000000e+176, .off= -7.448980502074319858e+158 },138 HP{ .val = 1.000000e+176, .off = -7.448980502074319858e+158 },
139 HP{.val=1.000000e+175, .off= 6.284654753766312753e+158 },139 HP{ .val = 1.000000e+175, .off = 6.284654753766312753e+158 },
140 HP{.val=1.000000e+174, .off= -6.895756753684458388e+157 },140 HP{ .val = 1.000000e+174, .off = -6.895756753684458388e+157 },
141 HP{.val=1.000000e+173, .off= -1.403918625579970616e+156 },141 HP{ .val = 1.000000e+173, .off = -1.403918625579970616e+156 },
142 HP{.val=1.000000e+172, .off= -8.268716285710580522e+155 },142 HP{ .val = 1.000000e+172, .off = -8.268716285710580522e+155 },
143 HP{.val=1.000000e+171, .off= 4.602779327034313170e+154 },143 HP{ .val = 1.000000e+171, .off = 4.602779327034313170e+154 },
144 HP{.val=1.000000e+170, .off= -3.441905430931244940e+153 },144 HP{ .val = 1.000000e+170, .off = -3.441905430931244940e+153 },
145 HP{.val=1.000000e+169, .off= 6.613950516525702884e+152 },145 HP{ .val = 1.000000e+169, .off = 6.613950516525702884e+152 },
146 HP{.val=1.000000e+168, .off= 6.613950516525702652e+151 },146 HP{ .val = 1.000000e+168, .off = 6.613950516525702652e+151 },
147 HP{.val=1.000000e+167, .off= -3.860899428741951187e+150 },147 HP{ .val = 1.000000e+167, .off = -3.860899428741951187e+150 },
148 HP{.val=1.000000e+166, .off= 5.959272394946474605e+149 },148 HP{ .val = 1.000000e+166, .off = 5.959272394946474605e+149 },
149 HP{.val=1.000000e+165, .off= 1.005101065481665103e+149 },149 HP{ .val = 1.000000e+165, .off = 1.005101065481665103e+149 },
150 HP{.val=1.000000e+164, .off= -1.783349948587918355e+146 },150 HP{ .val = 1.000000e+164, .off = -1.783349948587918355e+146 },
151 HP{.val=1.000000e+163, .off= 6.215006036188360099e+146 },151 HP{ .val = 1.000000e+163, .off = 6.215006036188360099e+146 },
152 HP{.val=1.000000e+162, .off= 6.215006036188360099e+145 },152 HP{ .val = 1.000000e+162, .off = 6.215006036188360099e+145 },
153 HP{.val=1.000000e+161, .off= -3.774589324822814903e+144 },153 HP{ .val = 1.000000e+161, .off = -3.774589324822814903e+144 },
154 HP{.val=1.000000e+160, .off= -6.528407745068226929e+142 },154 HP{ .val = 1.000000e+160, .off = -6.528407745068226929e+142 },
155 HP{.val=1.000000e+159, .off= 7.151530601283157561e+142 },155 HP{ .val = 1.000000e+159, .off = 7.151530601283157561e+142 },
156 HP{.val=1.000000e+158, .off= 4.712664546348788765e+141 },156 HP{ .val = 1.000000e+158, .off = 4.712664546348788765e+141 },
157 HP{.val=1.000000e+157, .off= 1.664081977680827856e+140 },157 HP{ .val = 1.000000e+157, .off = 1.664081977680827856e+140 },
158 HP{.val=1.000000e+156, .off= 1.664081977680827750e+139 },158 HP{ .val = 1.000000e+156, .off = 1.664081977680827750e+139 },
159 HP{.val=1.000000e+155, .off= -7.176231540910168265e+137 },159 HP{ .val = 1.000000e+155, .off = -7.176231540910168265e+137 },
160 HP{.val=1.000000e+154, .off= -3.694754568805822650e+137 },160 HP{ .val = 1.000000e+154, .off = -3.694754568805822650e+137 },
161 HP{.val=1.000000e+153, .off= 2.665969958768462622e+134 },161 HP{ .val = 1.000000e+153, .off = 2.665969958768462622e+134 },
162 HP{.val=1.000000e+152, .off= -4.625108135904199522e+135 },162 HP{ .val = 1.000000e+152, .off = -4.625108135904199522e+135 },
163 HP{.val=1.000000e+151, .off= -1.717753238721771919e+134 },163 HP{ .val = 1.000000e+151, .off = -1.717753238721771919e+134 },
164 HP{.val=1.000000e+150, .off= 1.916440382756262433e+133 },164 HP{ .val = 1.000000e+150, .off = 1.916440382756262433e+133 },
165 HP{.val=1.000000e+149, .off= -4.897672657515052040e+132 },165 HP{ .val = 1.000000e+149, .off = -4.897672657515052040e+132 },
166 HP{.val=1.000000e+148, .off= -4.897672657515052198e+131 },166 HP{ .val = 1.000000e+148, .off = -4.897672657515052198e+131 },
167 HP{.val=1.000000e+147, .off= 2.200361759434233991e+130 },167 HP{ .val = 1.000000e+147, .off = 2.200361759434233991e+130 },
168 HP{.val=1.000000e+146, .off= 6.636633270027537273e+129 },168 HP{ .val = 1.000000e+146, .off = 6.636633270027537273e+129 },
169 HP{.val=1.000000e+145, .off= 1.091293881785907977e+128 },169 HP{ .val = 1.000000e+145, .off = 1.091293881785907977e+128 },
170 HP{.val=1.000000e+144, .off= -2.374543235865110597e+127 },170 HP{ .val = 1.000000e+144, .off = -2.374543235865110597e+127 },
171 HP{.val=1.000000e+143, .off= -2.374543235865110537e+126 },171 HP{ .val = 1.000000e+143, .off = -2.374543235865110537e+126 },
172 HP{.val=1.000000e+142, .off= -5.082228484029969099e+125 },172 HP{ .val = 1.000000e+142, .off = -5.082228484029969099e+125 },
173 HP{.val=1.000000e+141, .off= -1.697621923823895943e+124 },173 HP{ .val = 1.000000e+141, .off = -1.697621923823895943e+124 },
174 HP{.val=1.000000e+140, .off= -5.928380124081487212e+123 },174 HP{ .val = 1.000000e+140, .off = -5.928380124081487212e+123 },
175 HP{.val=1.000000e+139, .off= -3.284156248920492522e+122 },175 HP{ .val = 1.000000e+139, .off = -3.284156248920492522e+122 },
176 HP{.val=1.000000e+138, .off= -3.284156248920492706e+121 },176 HP{ .val = 1.000000e+138, .off = -3.284156248920492706e+121 },
177 HP{.val=1.000000e+137, .off= -3.284156248920492476e+120 },177 HP{ .val = 1.000000e+137, .off = -3.284156248920492476e+120 },
178 HP{.val=1.000000e+136, .off= -5.866406127007401066e+119 },178 HP{ .val = 1.000000e+136, .off = -5.866406127007401066e+119 },
179 HP{.val=1.000000e+135, .off= 3.817030915818506056e+118 },179 HP{ .val = 1.000000e+135, .off = 3.817030915818506056e+118 },
180 HP{.val=1.000000e+134, .off= 7.851796350329300951e+117 },180 HP{ .val = 1.000000e+134, .off = 7.851796350329300951e+117 },
181 HP{.val=1.000000e+133, .off= -2.235117235947686077e+116 },181 HP{ .val = 1.000000e+133, .off = -2.235117235947686077e+116 },
182 HP{.val=1.000000e+132, .off= 9.170432597638723691e+114 },182 HP{ .val = 1.000000e+132, .off = 9.170432597638723691e+114 },
183 HP{.val=1.000000e+131, .off= 8.797444499042767883e+114 },183 HP{ .val = 1.000000e+131, .off = 8.797444499042767883e+114 },
184 HP{.val=1.000000e+130, .off= -5.978307824605161274e+113 },184 HP{ .val = 1.000000e+130, .off = -5.978307824605161274e+113 },
185 HP{.val=1.000000e+129, .off= 1.782556435814758516e+111 },185 HP{ .val = 1.000000e+129, .off = 1.782556435814758516e+111 },
186 HP{.val=1.000000e+128, .off= -7.517448691651820362e+111 },186 HP{ .val = 1.000000e+128, .off = -7.517448691651820362e+111 },
187 HP{.val=1.000000e+127, .off= 4.507089332150205498e+110 },187 HP{ .val = 1.000000e+127, .off = 4.507089332150205498e+110 },
188 HP{.val=1.000000e+126, .off= 7.513223838100711695e+109 },188 HP{ .val = 1.000000e+126, .off = 7.513223838100711695e+109 },
189 HP{.val=1.000000e+125, .off= 7.513223838100712113e+108 },189 HP{ .val = 1.000000e+125, .off = 7.513223838100712113e+108 },
190 HP{.val=1.000000e+124, .off= 5.164681255326878494e+107 },190 HP{ .val = 1.000000e+124, .off = 5.164681255326878494e+107 },
191 HP{.val=1.000000e+123, .off= 2.229003026859587122e+106 },191 HP{ .val = 1.000000e+123, .off = 2.229003026859587122e+106 },
192 HP{.val=1.000000e+122, .off= -1.440594758724527399e+105 },192 HP{ .val = 1.000000e+122, .off = -1.440594758724527399e+105 },
193 HP{.val=1.000000e+121, .off= -3.734093374714598783e+104 },193 HP{ .val = 1.000000e+121, .off = -3.734093374714598783e+104 },
194 HP{.val=1.000000e+120, .off= 1.999653165260579757e+103 },194 HP{ .val = 1.000000e+120, .off = 1.999653165260579757e+103 },
195 HP{.val=1.000000e+119, .off= 5.583244752745066693e+102 },195 HP{ .val = 1.000000e+119, .off = 5.583244752745066693e+102 },
196 HP{.val=1.000000e+118, .off= 3.343500010567262234e+101 },196 HP{ .val = 1.000000e+118, .off = 3.343500010567262234e+101 },
197 HP{.val=1.000000e+117, .off= -5.055542772599503556e+100 },197 HP{ .val = 1.000000e+117, .off = -5.055542772599503556e+100 },
198 HP{.val=1.000000e+116, .off= -1.555941612946684331e+99 },198 HP{ .val = 1.000000e+116, .off = -1.555941612946684331e+99 },
199 HP{.val=1.000000e+115, .off= -1.555941612946684331e+98 },199 HP{ .val = 1.000000e+115, .off = -1.555941612946684331e+98 },
200 HP{.val=1.000000e+114, .off= -1.555941612946684293e+97 },200 HP{ .val = 1.000000e+114, .off = -1.555941612946684293e+97 },
201 HP{.val=1.000000e+113, .off= -1.555941612946684246e+96 },201 HP{ .val = 1.000000e+113, .off = -1.555941612946684246e+96 },
202 HP{.val=1.000000e+112, .off= 6.988006530736955847e+95 },202 HP{ .val = 1.000000e+112, .off = 6.988006530736955847e+95 },
203 HP{.val=1.000000e+111, .off= 4.318022735835818244e+94 },203 HP{ .val = 1.000000e+111, .off = 4.318022735835818244e+94 },
204 HP{.val=1.000000e+110, .off= -2.356936751417025578e+93 },204 HP{ .val = 1.000000e+110, .off = -2.356936751417025578e+93 },
205 HP{.val=1.000000e+109, .off= 1.814912928116001926e+92 },205 HP{ .val = 1.000000e+109, .off = 1.814912928116001926e+92 },
206 HP{.val=1.000000e+108, .off= -3.399899171300282744e+91 },206 HP{ .val = 1.000000e+108, .off = -3.399899171300282744e+91 },
207 HP{.val=1.000000e+107, .off= 3.118615952970072913e+90 },207 HP{ .val = 1.000000e+107, .off = 3.118615952970072913e+90 },
208 HP{.val=1.000000e+106, .off= -9.103599905036843605e+89 },208 HP{ .val = 1.000000e+106, .off = -9.103599905036843605e+89 },
209 HP{.val=1.000000e+105, .off= 6.174169917471802325e+88 },209 HP{ .val = 1.000000e+105, .off = 6.174169917471802325e+88 },
210 HP{.val=1.000000e+104, .off= -1.915675085734668657e+86 },210 HP{ .val = 1.000000e+104, .off = -1.915675085734668657e+86 },
211 HP{.val=1.000000e+103, .off= -1.915675085734668864e+85 },211 HP{ .val = 1.000000e+103, .off = -1.915675085734668864e+85 },
212 HP{.val=1.000000e+102, .off= 2.295048673475466221e+85 },212 HP{ .val = 1.000000e+102, .off = 2.295048673475466221e+85 },
213 HP{.val=1.000000e+101, .off= 2.295048673475466135e+84 },213 HP{ .val = 1.000000e+101, .off = 2.295048673475466135e+84 },
214 HP{.val=1.000000e+100, .off= -1.590289110975991792e+83 },214 HP{ .val = 1.000000e+100, .off = -1.590289110975991792e+83 },
215 HP{.val=1.000000e+99, .off= 3.266383119588331155e+82 },215 HP{ .val = 1.000000e+99, .off = 3.266383119588331155e+82 },
216 HP{.val=1.000000e+98, .off= 2.309629754856292029e+80 },216 HP{ .val = 1.000000e+98, .off = 2.309629754856292029e+80 },
217 HP{.val=1.000000e+97, .off= -7.357587384771124533e+80 },217 HP{ .val = 1.000000e+97, .off = -7.357587384771124533e+80 },
218 HP{.val=1.000000e+96, .off= -4.986165397190889509e+79 },218 HP{ .val = 1.000000e+96, .off = -4.986165397190889509e+79 },
219 HP{.val=1.000000e+95, .off= -2.021887912715594741e+78 },219 HP{ .val = 1.000000e+95, .off = -2.021887912715594741e+78 },
220 HP{.val=1.000000e+94, .off= -2.021887912715594638e+77 },220 HP{ .val = 1.000000e+94, .off = -2.021887912715594638e+77 },
221 HP{.val=1.000000e+93, .off= -4.337729697461918675e+76 },221 HP{ .val = 1.000000e+93, .off = -4.337729697461918675e+76 },
222 HP{.val=1.000000e+92, .off= -4.337729697461918997e+75 },222 HP{ .val = 1.000000e+92, .off = -4.337729697461918997e+75 },
223 HP{.val=1.000000e+91, .off= -7.956232486128049702e+74 },223 HP{ .val = 1.000000e+91, .off = -7.956232486128049702e+74 },
224 HP{.val=1.000000e+90, .off= 3.351588728453609882e+73 },224 HP{ .val = 1.000000e+90, .off = 3.351588728453609882e+73 },
225 HP{.val=1.000000e+89, .off= 5.246334248081951113e+71 },225 HP{ .val = 1.000000e+89, .off = 5.246334248081951113e+71 },
226 HP{.val=1.000000e+88, .off= 4.058327554364963672e+71 },226 HP{ .val = 1.000000e+88, .off = 4.058327554364963672e+71 },
227 HP{.val=1.000000e+87, .off= 4.058327554364963918e+70 },227 HP{ .val = 1.000000e+87, .off = 4.058327554364963918e+70 },
228 HP{.val=1.000000e+86, .off= -1.463069523067487266e+69 },228 HP{ .val = 1.000000e+86, .off = -1.463069523067487266e+69 },
229 HP{.val=1.000000e+85, .off= -1.463069523067487314e+68 },229 HP{ .val = 1.000000e+85, .off = -1.463069523067487314e+68 },
230 HP{.val=1.000000e+84, .off= -5.776660989811589441e+67 },230 HP{ .val = 1.000000e+84, .off = -5.776660989811589441e+67 },
231 HP{.val=1.000000e+83, .off= -3.080666323096525761e+66 },231 HP{ .val = 1.000000e+83, .off = -3.080666323096525761e+66 },
232 HP{.val=1.000000e+82, .off= 3.659320343691134468e+65 },232 HP{ .val = 1.000000e+82, .off = 3.659320343691134468e+65 },
233 HP{.val=1.000000e+81, .off= 7.871812010433421235e+64 },233 HP{ .val = 1.000000e+81, .off = 7.871812010433421235e+64 },
234 HP{.val=1.000000e+80, .off= -2.660986470836727449e+61 },234 HP{ .val = 1.000000e+80, .off = -2.660986470836727449e+61 },
235 HP{.val=1.000000e+79, .off= 3.264399249934044627e+62 },235 HP{ .val = 1.000000e+79, .off = 3.264399249934044627e+62 },
236 HP{.val=1.000000e+78, .off= -8.493621433689703070e+60 },236 HP{ .val = 1.000000e+78, .off = -8.493621433689703070e+60 },
237 HP{.val=1.000000e+77, .off= 1.721738727445414063e+60 },237 HP{ .val = 1.000000e+77, .off = 1.721738727445414063e+60 },
238 HP{.val=1.000000e+76, .off= -4.706013449590547218e+59 },238 HP{ .val = 1.000000e+76, .off = -4.706013449590547218e+59 },
239 HP{.val=1.000000e+75, .off= 7.346021882351880518e+58 },239 HP{ .val = 1.000000e+75, .off = 7.346021882351880518e+58 },
240 HP{.val=1.000000e+74, .off= 4.835181188197207515e+57 },240 HP{ .val = 1.000000e+74, .off = 4.835181188197207515e+57 },
241 HP{.val=1.000000e+73, .off= 1.696630320503867482e+56 },241 HP{ .val = 1.000000e+73, .off = 1.696630320503867482e+56 },
242 HP{.val=1.000000e+72, .off= 5.619818905120542959e+55 },242 HP{ .val = 1.000000e+72, .off = 5.619818905120542959e+55 },
243 HP{.val=1.000000e+71, .off= -4.188152556421145598e+54 },243 HP{ .val = 1.000000e+71, .off = -4.188152556421145598e+54 },
244 HP{.val=1.000000e+70, .off= -7.253143638152923145e+53 },244 HP{ .val = 1.000000e+70, .off = -7.253143638152923145e+53 },
245 HP{.val=1.000000e+69, .off= -7.253143638152923145e+52 },245 HP{ .val = 1.000000e+69, .off = -7.253143638152923145e+52 },
246 HP{.val=1.000000e+68, .off= 4.719477774861832896e+51 },246 HP{ .val = 1.000000e+68, .off = 4.719477774861832896e+51 },
247 HP{.val=1.000000e+67, .off= 1.726322421608144052e+50 },247 HP{ .val = 1.000000e+67, .off = 1.726322421608144052e+50 },
248 HP{.val=1.000000e+66, .off= 5.467766613175255107e+49 },248 HP{ .val = 1.000000e+66, .off = 5.467766613175255107e+49 },
249 HP{.val=1.000000e+65, .off= 7.909613737163661911e+47 },249 HP{ .val = 1.000000e+65, .off = 7.909613737163661911e+47 },
250 HP{.val=1.000000e+64, .off= -2.132041900945439564e+47 },250 HP{ .val = 1.000000e+64, .off = -2.132041900945439564e+47 },
251 HP{.val=1.000000e+63, .off= -5.785795994272697265e+46 },251 HP{ .val = 1.000000e+63, .off = -5.785795994272697265e+46 },
252 HP{.val=1.000000e+62, .off= -3.502199685943161329e+45 },252 HP{ .val = 1.000000e+62, .off = -3.502199685943161329e+45 },
253 HP{.val=1.000000e+61, .off= 5.061286470292598274e+44 },253 HP{ .val = 1.000000e+61, .off = 5.061286470292598274e+44 },
254 HP{.val=1.000000e+60, .off= 5.061286470292598472e+43 },254 HP{ .val = 1.000000e+60, .off = 5.061286470292598472e+43 },
255 HP{.val=1.000000e+59, .off= 2.831211950439536034e+42 },255 HP{ .val = 1.000000e+59, .off = 2.831211950439536034e+42 },
256 HP{.val=1.000000e+58, .off= 5.618805100255863927e+41 },256 HP{ .val = 1.000000e+58, .off = 5.618805100255863927e+41 },
257 HP{.val=1.000000e+57, .off= -4.834669211555366251e+40 },257 HP{ .val = 1.000000e+57, .off = -4.834669211555366251e+40 },
258 HP{.val=1.000000e+56, .off= -9.190283508143378583e+39 },258 HP{ .val = 1.000000e+56, .off = -9.190283508143378583e+39 },
259 HP{.val=1.000000e+55, .off= -1.023506702040855158e+38 },259 HP{ .val = 1.000000e+55, .off = -1.023506702040855158e+38 },
260 HP{.val=1.000000e+54, .off= -7.829154040459624616e+37 },260 HP{ .val = 1.000000e+54, .off = -7.829154040459624616e+37 },
261 HP{.val=1.000000e+53, .off= 6.779051325638372659e+35 },261 HP{ .val = 1.000000e+53, .off = 6.779051325638372659e+35 },
262 HP{.val=1.000000e+52, .off= 6.779051325638372290e+34 },262 HP{ .val = 1.000000e+52, .off = 6.779051325638372290e+34 },
263 HP{.val=1.000000e+51, .off= 6.779051325638371598e+33 },263 HP{ .val = 1.000000e+51, .off = 6.779051325638371598e+33 },
264 HP{.val=1.000000e+50, .off= -7.629769841091887392e+33 },264 HP{ .val = 1.000000e+50, .off = -7.629769841091887392e+33 },
265 HP{.val=1.000000e+49, .off= 5.350972305245182400e+32 },265 HP{ .val = 1.000000e+49, .off = 5.350972305245182400e+32 },
266 HP{.val=1.000000e+48, .off= -4.384584304507619764e+31 },266 HP{ .val = 1.000000e+48, .off = -4.384584304507619764e+31 },
267 HP{.val=1.000000e+47, .off= -4.384584304507619876e+30 },267 HP{ .val = 1.000000e+47, .off = -4.384584304507619876e+30 },
268 HP{.val=1.000000e+46, .off= 6.860180964052978705e+28 },268 HP{ .val = 1.000000e+46, .off = 6.860180964052978705e+28 },
269 HP{.val=1.000000e+45, .off= 7.024271097546444878e+28 },269 HP{ .val = 1.000000e+45, .off = 7.024271097546444878e+28 },
270 HP{.val=1.000000e+44, .off= -8.821361405306422641e+27 },270 HP{ .val = 1.000000e+44, .off = -8.821361405306422641e+27 },
271 HP{.val=1.000000e+43, .off= -1.393721169594140991e+26 },271 HP{ .val = 1.000000e+43, .off = -1.393721169594140991e+26 },
272 HP{.val=1.000000e+42, .off= -4.488571267807591679e+25 },272 HP{ .val = 1.000000e+42, .off = -4.488571267807591679e+25 },
273 HP{.val=1.000000e+41, .off= -6.200086450407783195e+23 },273 HP{ .val = 1.000000e+41, .off = -6.200086450407783195e+23 },
274 HP{.val=1.000000e+40, .off= -3.037860284270036669e+23 },274 HP{ .val = 1.000000e+40, .off = -3.037860284270036669e+23 },
275 HP{.val=1.000000e+39, .off= 6.029083362839682141e+22 },275 HP{ .val = 1.000000e+39, .off = 6.029083362839682141e+22 },
276 HP{.val=1.000000e+38, .off= 2.251190176543965970e+21 },276 HP{ .val = 1.000000e+38, .off = 2.251190176543965970e+21 },
277 HP{.val=1.000000e+37, .off= 4.612373417978788577e+20 },277 HP{ .val = 1.000000e+37, .off = 4.612373417978788577e+20 },
278 HP{.val=1.000000e+36, .off= -4.242063737401796198e+19 },278 HP{ .val = 1.000000e+36, .off = -4.242063737401796198e+19 },
279 HP{.val=1.000000e+35, .off= 3.136633892082024448e+18 },279 HP{ .val = 1.000000e+35, .off = 3.136633892082024448e+18 },
280 HP{.val=1.000000e+34, .off= 5.442476901295718400e+17 },280 HP{ .val = 1.000000e+34, .off = 5.442476901295718400e+17 },
281 HP{.val=1.000000e+33, .off= 5.442476901295718400e+16 },281 HP{ .val = 1.000000e+33, .off = 5.442476901295718400e+16 },
282 HP{.val=1.000000e+32, .off= -5.366162204393472000e+15 },282 HP{ .val = 1.000000e+32, .off = -5.366162204393472000e+15 },
283 HP{.val=1.000000e+31, .off= 3.641037050347520000e+14 },283 HP{ .val = 1.000000e+31, .off = 3.641037050347520000e+14 },
284 HP{.val=1.000000e+30, .off= -1.988462483865600000e+13 },284 HP{ .val = 1.000000e+30, .off = -1.988462483865600000e+13 },
285 HP{.val=1.000000e+29, .off= 8.566849142784000000e+12 },285 HP{ .val = 1.000000e+29, .off = 8.566849142784000000e+12 },
286 HP{.val=1.000000e+28, .off= 4.168802631680000000e+11 },286 HP{ .val = 1.000000e+28, .off = 4.168802631680000000e+11 },
287 HP{.val=1.000000e+27, .off= -1.328755507200000000e+10 },287 HP{ .val = 1.000000e+27, .off = -1.328755507200000000e+10 },
288 HP{.val=1.000000e+26, .off= -4.764729344000000000e+09 },288 HP{ .val = 1.000000e+26, .off = -4.764729344000000000e+09 },
289 HP{.val=1.000000e+25, .off= -9.059696640000000000e+08 },289 HP{ .val = 1.000000e+25, .off = -9.059696640000000000e+08 },
290 HP{.val=1.000000e+24, .off= 1.677721600000000000e+07 },290 HP{ .val = 1.000000e+24, .off = 1.677721600000000000e+07 },
291 HP{.val=1.000000e+23, .off= 8.388608000000000000e+06 },291 HP{ .val = 1.000000e+23, .off = 8.388608000000000000e+06 },
292 HP{.val=1.000000e+22, .off= 0.000000000000000000e+00 },292 HP{ .val = 1.000000e+22, .off = 0.000000000000000000e+00 },
293 HP{.val=1.000000e+21, .off= 0.000000000000000000e+00 },293 HP{ .val = 1.000000e+21, .off = 0.000000000000000000e+00 },
294 HP{.val=1.000000e+20, .off= 0.000000000000000000e+00 },294 HP{ .val = 1.000000e+20, .off = 0.000000000000000000e+00 },
295 HP{.val=1.000000e+19, .off= 0.000000000000000000e+00 },295 HP{ .val = 1.000000e+19, .off = 0.000000000000000000e+00 },
296 HP{.val=1.000000e+18, .off= 0.000000000000000000e+00 },296 HP{ .val = 1.000000e+18, .off = 0.000000000000000000e+00 },
297 HP{.val=1.000000e+17, .off= 0.000000000000000000e+00 },297 HP{ .val = 1.000000e+17, .off = 0.000000000000000000e+00 },
298 HP{.val=1.000000e+16, .off= 0.000000000000000000e+00 },298 HP{ .val = 1.000000e+16, .off = 0.000000000000000000e+00 },
299 HP{.val=1.000000e+15, .off= 0.000000000000000000e+00 },299 HP{ .val = 1.000000e+15, .off = 0.000000000000000000e+00 },
300 HP{.val=1.000000e+14, .off= 0.000000000000000000e+00 },300 HP{ .val = 1.000000e+14, .off = 0.000000000000000000e+00 },
301 HP{.val=1.000000e+13, .off= 0.000000000000000000e+00 },301 HP{ .val = 1.000000e+13, .off = 0.000000000000000000e+00 },
302 HP{.val=1.000000e+12, .off= 0.000000000000000000e+00 },302 HP{ .val = 1.000000e+12, .off = 0.000000000000000000e+00 },
303 HP{.val=1.000000e+11, .off= 0.000000000000000000e+00 },303 HP{ .val = 1.000000e+11, .off = 0.000000000000000000e+00 },
304 HP{.val=1.000000e+10, .off= 0.000000000000000000e+00 },304 HP{ .val = 1.000000e+10, .off = 0.000000000000000000e+00 },
305 HP{.val=1.000000e+09, .off= 0.000000000000000000e+00 },305 HP{ .val = 1.000000e+09, .off = 0.000000000000000000e+00 },
306 HP{.val=1.000000e+08, .off= 0.000000000000000000e+00 },306 HP{ .val = 1.000000e+08, .off = 0.000000000000000000e+00 },
307 HP{.val=1.000000e+07, .off= 0.000000000000000000e+00 },307 HP{ .val = 1.000000e+07, .off = 0.000000000000000000e+00 },
308 HP{.val=1.000000e+06, .off= 0.000000000000000000e+00 },308 HP{ .val = 1.000000e+06, .off = 0.000000000000000000e+00 },
309 HP{.val=1.000000e+05, .off= 0.000000000000000000e+00 },309 HP{ .val = 1.000000e+05, .off = 0.000000000000000000e+00 },
310 HP{.val=1.000000e+04, .off= 0.000000000000000000e+00 },310 HP{ .val = 1.000000e+04, .off = 0.000000000000000000e+00 },
311 HP{.val=1.000000e+03, .off= 0.000000000000000000e+00 },311 HP{ .val = 1.000000e+03, .off = 0.000000000000000000e+00 },
312 HP{.val=1.000000e+02, .off= 0.000000000000000000e+00 },312 HP{ .val = 1.000000e+02, .off = 0.000000000000000000e+00 },
313 HP{.val=1.000000e+01, .off= 0.000000000000000000e+00 },313 HP{ .val = 1.000000e+01, .off = 0.000000000000000000e+00 },
314 HP{.val=1.000000e+00, .off= 0.000000000000000000e+00 },314 HP{ .val = 1.000000e+00, .off = 0.000000000000000000e+00 },
315 HP{.val=1.000000e-01, .off= -5.551115123125783010e-18 },315 HP{ .val = 1.000000e-01, .off = -5.551115123125783010e-18 },
316 HP{.val=1.000000e-02, .off= -2.081668171172168436e-19 },316 HP{ .val = 1.000000e-02, .off = -2.081668171172168436e-19 },
317 HP{.val=1.000000e-03, .off= -2.081668171172168557e-20 },317 HP{ .val = 1.000000e-03, .off = -2.081668171172168557e-20 },
318 HP{.val=1.000000e-04, .off= -4.792173602385929943e-21 },318 HP{ .val = 1.000000e-04, .off = -4.792173602385929943e-21 },
319 HP{.val=1.000000e-05, .off= -8.180305391403130547e-22 },319 HP{ .val = 1.000000e-05, .off = -8.180305391403130547e-22 },
320 HP{.val=1.000000e-06, .off= 4.525188817411374069e-23 },320 HP{ .val = 1.000000e-06, .off = 4.525188817411374069e-23 },
321 HP{.val=1.000000e-07, .off= 4.525188817411373922e-24 },321 HP{ .val = 1.000000e-07, .off = 4.525188817411373922e-24 },
322 HP{.val=1.000000e-08, .off= -2.092256083012847109e-25 },322 HP{ .val = 1.000000e-08, .off = -2.092256083012847109e-25 },
323 HP{.val=1.000000e-09, .off= -6.228159145777985254e-26 },323 HP{ .val = 1.000000e-09, .off = -6.228159145777985254e-26 },
324 HP{.val=1.000000e-10, .off= -3.643219731549774344e-27 },324 HP{ .val = 1.000000e-10, .off = -3.643219731549774344e-27 },
325 HP{.val=1.000000e-11, .off= 6.050303071806019080e-28 },325 HP{ .val = 1.000000e-11, .off = 6.050303071806019080e-28 },
326 HP{.val=1.000000e-12, .off= 2.011335237074438524e-29 },326 HP{ .val = 1.000000e-12, .off = 2.011335237074438524e-29 },
327 HP{.val=1.000000e-13, .off= -3.037374556340037101e-30 },327 HP{ .val = 1.000000e-13, .off = -3.037374556340037101e-30 },
328 HP{.val=1.000000e-14, .off= 1.180690645440101289e-32 },328 HP{ .val = 1.000000e-14, .off = 1.180690645440101289e-32 },
329 HP{.val=1.000000e-15, .off= -7.770539987666107583e-32 },329 HP{ .val = 1.000000e-15, .off = -7.770539987666107583e-32 },
330 HP{.val=1.000000e-16, .off= 2.090221327596539779e-33 },330 HP{ .val = 1.000000e-16, .off = 2.090221327596539779e-33 },
331 HP{.val=1.000000e-17, .off= -7.154242405462192144e-34 },331 HP{ .val = 1.000000e-17, .off = -7.154242405462192144e-34 },
332 HP{.val=1.000000e-18, .off= -7.154242405462192572e-35 },332 HP{ .val = 1.000000e-18, .off = -7.154242405462192572e-35 },
333 HP{.val=1.000000e-19, .off= 2.475407316473986894e-36 },333 HP{ .val = 1.000000e-19, .off = 2.475407316473986894e-36 },
334 HP{.val=1.000000e-20, .off= 5.484672854579042914e-37 },334 HP{ .val = 1.000000e-20, .off = 5.484672854579042914e-37 },
335 HP{.val=1.000000e-21, .off= 9.246254777210362522e-38 },335 HP{ .val = 1.000000e-21, .off = 9.246254777210362522e-38 },
336 HP{.val=1.000000e-22, .off= -4.859677432657087182e-39 },336 HP{ .val = 1.000000e-22, .off = -4.859677432657087182e-39 },
337 HP{.val=1.000000e-23, .off= 3.956530198510069291e-40 },337 HP{ .val = 1.000000e-23, .off = 3.956530198510069291e-40 },
338 HP{.val=1.000000e-24, .off= 7.629950044829717753e-41 },338 HP{ .val = 1.000000e-24, .off = 7.629950044829717753e-41 },
339 HP{.val=1.000000e-25, .off= -3.849486974919183692e-42 },339 HP{ .val = 1.000000e-25, .off = -3.849486974919183692e-42 },
340 HP{.val=1.000000e-26, .off= -3.849486974919184170e-43 },340 HP{ .val = 1.000000e-26, .off = -3.849486974919184170e-43 },
341 HP{.val=1.000000e-27, .off= -3.849486974919184070e-44 },341 HP{ .val = 1.000000e-27, .off = -3.849486974919184070e-44 },
342 HP{.val=1.000000e-28, .off= 2.876745653839937870e-45 },342 HP{ .val = 1.000000e-28, .off = 2.876745653839937870e-45 },
343 HP{.val=1.000000e-29, .off= 5.679342582489572168e-46 },343 HP{ .val = 1.000000e-29, .off = 5.679342582489572168e-46 },
344 HP{.val=1.000000e-30, .off= -8.333642060758598930e-47 },344 HP{ .val = 1.000000e-30, .off = -8.333642060758598930e-47 },
345 HP{.val=1.000000e-31, .off= -8.333642060758597958e-48 },345 HP{ .val = 1.000000e-31, .off = -8.333642060758597958e-48 },
346 HP{.val=1.000000e-32, .off= -5.596730997624190224e-49 },346 HP{ .val = 1.000000e-32, .off = -5.596730997624190224e-49 },
347 HP{.val=1.000000e-33, .off= -5.596730997624190604e-50 },347 HP{ .val = 1.000000e-33, .off = -5.596730997624190604e-50 },
348 HP{.val=1.000000e-34, .off= 7.232539610818348498e-51 },348 HP{ .val = 1.000000e-34, .off = 7.232539610818348498e-51 },
349 HP{.val=1.000000e-35, .off= -7.857545194582380514e-53 },349 HP{ .val = 1.000000e-35, .off = -7.857545194582380514e-53 },
350 HP{.val=1.000000e-36, .off= 5.896157255772251528e-53 },350 HP{ .val = 1.000000e-36, .off = 5.896157255772251528e-53 },
351 HP{.val=1.000000e-37, .off= -6.632427322784915796e-54 },351 HP{ .val = 1.000000e-37, .off = -6.632427322784915796e-54 },
352 HP{.val=1.000000e-38, .off= 3.808059826012723592e-55 },352 HP{ .val = 1.000000e-38, .off = 3.808059826012723592e-55 },
353 HP{.val=1.000000e-39, .off= 7.070712060011985131e-56 },353 HP{ .val = 1.000000e-39, .off = 7.070712060011985131e-56 },
354 HP{.val=1.000000e-40, .off= 7.070712060011985584e-57 },354 HP{ .val = 1.000000e-40, .off = 7.070712060011985584e-57 },
355 HP{.val=1.000000e-41, .off= -5.761291134237854167e-59 },355 HP{ .val = 1.000000e-41, .off = -5.761291134237854167e-59 },
356 HP{.val=1.000000e-42, .off= -3.762312935688689794e-59 },356 HP{ .val = 1.000000e-42, .off = -3.762312935688689794e-59 },
357 HP{.val=1.000000e-43, .off= -7.745042713519821150e-60 },357 HP{ .val = 1.000000e-43, .off = -7.745042713519821150e-60 },
358 HP{.val=1.000000e-44, .off= 4.700987842202462817e-61 },358 HP{ .val = 1.000000e-44, .off = 4.700987842202462817e-61 },
359 HP{.val=1.000000e-45, .off= 1.589480203271891964e-62 },359 HP{ .val = 1.000000e-45, .off = 1.589480203271891964e-62 },
360 HP{.val=1.000000e-46, .off= -2.299904345391321765e-63 },360 HP{ .val = 1.000000e-46, .off = -2.299904345391321765e-63 },
361 HP{.val=1.000000e-47, .off= 2.561826340437695261e-64 },361 HP{ .val = 1.000000e-47, .off = 2.561826340437695261e-64 },
362 HP{.val=1.000000e-48, .off= 2.561826340437695345e-65 },362 HP{ .val = 1.000000e-48, .off = 2.561826340437695345e-65 },
363 HP{.val=1.000000e-49, .off= 6.360053438741614633e-66 },363 HP{ .val = 1.000000e-49, .off = 6.360053438741614633e-66 },
364 HP{.val=1.000000e-50, .off= -7.616223705782342295e-68 },364 HP{ .val = 1.000000e-50, .off = -7.616223705782342295e-68 },
365 HP{.val=1.000000e-51, .off= -7.616223705782343324e-69 },365 HP{ .val = 1.000000e-51, .off = -7.616223705782343324e-69 },
366 HP{.val=1.000000e-52, .off= -7.616223705782342295e-70 },366 HP{ .val = 1.000000e-52, .off = -7.616223705782342295e-70 },
367 HP{.val=1.000000e-53, .off= -3.079876214757872338e-70 },367 HP{ .val = 1.000000e-53, .off = -3.079876214757872338e-70 },
368 HP{.val=1.000000e-54, .off= -3.079876214757872821e-71 },368 HP{ .val = 1.000000e-54, .off = -3.079876214757872821e-71 },
369 HP{.val=1.000000e-55, .off= 5.423954167728123147e-73 },369 HP{ .val = 1.000000e-55, .off = 5.423954167728123147e-73 },
370 HP{.val=1.000000e-56, .off= -3.985444122640543680e-73 },370 HP{ .val = 1.000000e-56, .off = -3.985444122640543680e-73 },
371 HP{.val=1.000000e-57, .off= 4.504255013759498850e-74 },371 HP{ .val = 1.000000e-57, .off = 4.504255013759498850e-74 },
372 HP{.val=1.000000e-58, .off= -2.570494266573869991e-75 },372 HP{ .val = 1.000000e-58, .off = -2.570494266573869991e-75 },
373 HP{.val=1.000000e-59, .off= -2.570494266573869930e-76 },373 HP{ .val = 1.000000e-59, .off = -2.570494266573869930e-76 },
374 HP{.val=1.000000e-60, .off= 2.956653608686574324e-77 },374 HP{ .val = 1.000000e-60, .off = 2.956653608686574324e-77 },
375 HP{.val=1.000000e-61, .off= -3.952281235388981376e-78 },375 HP{ .val = 1.000000e-61, .off = -3.952281235388981376e-78 },
376 HP{.val=1.000000e-62, .off= -3.952281235388981376e-79 },376 HP{ .val = 1.000000e-62, .off = -3.952281235388981376e-79 },
377 HP{.val=1.000000e-63, .off= -6.651083908855995172e-80 },377 HP{ .val = 1.000000e-63, .off = -6.651083908855995172e-80 },
378 HP{.val=1.000000e-64, .off= 3.469426116645307030e-81 },378 HP{ .val = 1.000000e-64, .off = 3.469426116645307030e-81 },
379 HP{.val=1.000000e-65, .off= 7.686305293937516319e-82 },379 HP{ .val = 1.000000e-65, .off = 7.686305293937516319e-82 },
380 HP{.val=1.000000e-66, .off= 2.415206322322254927e-83 },380 HP{ .val = 1.000000e-66, .off = 2.415206322322254927e-83 },
381 HP{.val=1.000000e-67, .off= 5.709643179581793251e-84 },381 HP{ .val = 1.000000e-67, .off = 5.709643179581793251e-84 },
382 HP{.val=1.000000e-68, .off= -6.644495035141475923e-85 },382 HP{ .val = 1.000000e-68, .off = -6.644495035141475923e-85 },
383 HP{.val=1.000000e-69, .off= 3.650620143794581913e-86 },383 HP{ .val = 1.000000e-69, .off = 3.650620143794581913e-86 },
384 HP{.val=1.000000e-70, .off= 4.333966503770636492e-88 },384 HP{ .val = 1.000000e-70, .off = 4.333966503770636492e-88 },
385 HP{.val=1.000000e-71, .off= 8.476455383920859113e-88 },385 HP{ .val = 1.000000e-71, .off = 8.476455383920859113e-88 },
386 HP{.val=1.000000e-72, .off= 3.449543675455986564e-89 },386 HP{ .val = 1.000000e-72, .off = 3.449543675455986564e-89 },
387 HP{.val=1.000000e-73, .off= 3.077238576654418974e-91 },387 HP{ .val = 1.000000e-73, .off = 3.077238576654418974e-91 },
388 HP{.val=1.000000e-74, .off= 4.234998629903623140e-91 },388 HP{ .val = 1.000000e-74, .off = 4.234998629903623140e-91 },
389 HP{.val=1.000000e-75, .off= 4.234998629903623412e-92 },389 HP{ .val = 1.000000e-75, .off = 4.234998629903623412e-92 },
390 HP{.val=1.000000e-76, .off= 7.303182045714702338e-93 },390 HP{ .val = 1.000000e-76, .off = 7.303182045714702338e-93 },
391 HP{.val=1.000000e-77, .off= 7.303182045714701699e-94 },391 HP{ .val = 1.000000e-77, .off = 7.303182045714701699e-94 },
392 HP{.val=1.000000e-78, .off= 1.121271649074855759e-96 },392 HP{ .val = 1.000000e-78, .off = 1.121271649074855759e-96 },
393 HP{.val=1.000000e-79, .off= 1.121271649074855863e-97 },393 HP{ .val = 1.000000e-79, .off = 1.121271649074855863e-97 },
394 HP{.val=1.000000e-80, .off= 3.857468248661243988e-97 },394 HP{ .val = 1.000000e-80, .off = 3.857468248661243988e-97 },
395 HP{.val=1.000000e-81, .off= 3.857468248661244248e-98 },395 HP{ .val = 1.000000e-81, .off = 3.857468248661244248e-98 },
396 HP{.val=1.000000e-82, .off= 3.857468248661244410e-99 },396 HP{ .val = 1.000000e-82, .off = 3.857468248661244410e-99 },
397 HP{.val=1.000000e-83, .off= -3.457651055545315679e-100 },397 HP{ .val = 1.000000e-83, .off = -3.457651055545315679e-100 },
398 HP{.val=1.000000e-84, .off= -3.457651055545315933e-101 },398 HP{ .val = 1.000000e-84, .off = -3.457651055545315933e-101 },
399 HP{.val=1.000000e-85, .off= 2.257285900866059216e-102 },399 HP{ .val = 1.000000e-85, .off = 2.257285900866059216e-102 },
400 HP{.val=1.000000e-86, .off= -8.458220892405268345e-103 },400 HP{ .val = 1.000000e-86, .off = -8.458220892405268345e-103 },
401 HP{.val=1.000000e-87, .off= -1.761029146610688867e-104 },401 HP{ .val = 1.000000e-87, .off = -1.761029146610688867e-104 },
402 HP{.val=1.000000e-88, .off= 6.610460535632536565e-105 },402 HP{ .val = 1.000000e-88, .off = 6.610460535632536565e-105 },
403 HP{.val=1.000000e-89, .off= -3.853901567171494935e-106 },403 HP{ .val = 1.000000e-89, .off = -3.853901567171494935e-106 },
404 HP{.val=1.000000e-90, .off= 5.062493089968513723e-108 },404 HP{ .val = 1.000000e-90, .off = 5.062493089968513723e-108 },
405 HP{.val=1.000000e-91, .off= -2.218844988608365240e-108 },405 HP{ .val = 1.000000e-91, .off = -2.218844988608365240e-108 },
406 HP{.val=1.000000e-92, .off= 1.187522883398155383e-109 },406 HP{ .val = 1.000000e-92, .off = 1.187522883398155383e-109 },
407 HP{.val=1.000000e-93, .off= 9.703442563414457296e-110 },407 HP{ .val = 1.000000e-93, .off = 9.703442563414457296e-110 },
408 HP{.val=1.000000e-94, .off= 4.380992763404268896e-111 },408 HP{ .val = 1.000000e-94, .off = 4.380992763404268896e-111 },
409 HP{.val=1.000000e-95, .off= 1.054461638397900823e-112 },409 HP{ .val = 1.000000e-95, .off = 1.054461638397900823e-112 },
410 HP{.val=1.000000e-96, .off= 9.370789450913819736e-113 },410 HP{ .val = 1.000000e-96, .off = 9.370789450913819736e-113 },
411 HP{.val=1.000000e-97, .off= -3.623472756142303998e-114 },411 HP{ .val = 1.000000e-97, .off = -3.623472756142303998e-114 },
412 HP{.val=1.000000e-98, .off= 6.122223899149788839e-115 },412 HP{ .val = 1.000000e-98, .off = 6.122223899149788839e-115 },
413 HP{.val=1.000000e-99, .off= -1.999189980260288281e-116 },413 HP{ .val = 1.000000e-99, .off = -1.999189980260288281e-116 },
414 HP{.val=1.000000e-100, .off= -1.999189980260288281e-117 },414 HP{ .val = 1.000000e-100, .off = -1.999189980260288281e-117 },
415 HP{.val=1.000000e-101, .off= -5.171617276904849634e-118 },415 HP{ .val = 1.000000e-101, .off = -5.171617276904849634e-118 },
416 HP{.val=1.000000e-102, .off= 6.724985085512256320e-119 },416 HP{ .val = 1.000000e-102, .off = 6.724985085512256320e-119 },
417 HP{.val=1.000000e-103, .off= 4.246526260008692213e-120 },417 HP{ .val = 1.000000e-103, .off = 4.246526260008692213e-120 },
418 HP{.val=1.000000e-104, .off= 7.344599791888147003e-121 },418 HP{ .val = 1.000000e-104, .off = 7.344599791888147003e-121 },
419 HP{.val=1.000000e-105, .off= 3.472007877038828407e-122 },419 HP{ .val = 1.000000e-105, .off = 3.472007877038828407e-122 },
420 HP{.val=1.000000e-106, .off= 5.892377823819652194e-123 },420 HP{ .val = 1.000000e-106, .off = 5.892377823819652194e-123 },
421 HP{.val=1.000000e-107, .off= -1.585470431324073925e-125 },421 HP{ .val = 1.000000e-107, .off = -1.585470431324073925e-125 },
422 HP{.val=1.000000e-108, .off= -3.940375084977444795e-125 },422 HP{ .val = 1.000000e-108, .off = -3.940375084977444795e-125 },
423 HP{.val=1.000000e-109, .off= 7.869099673288519908e-127 },423 HP{ .val = 1.000000e-109, .off = 7.869099673288519908e-127 },
424 HP{.val=1.000000e-110, .off= -5.122196348054018581e-127 },424 HP{ .val = 1.000000e-110, .off = -5.122196348054018581e-127 },
425 HP{.val=1.000000e-111, .off= -8.815387795168313713e-128 },425 HP{ .val = 1.000000e-111, .off = -8.815387795168313713e-128 },
426 HP{.val=1.000000e-112, .off= 5.034080131510290214e-129 },426 HP{ .val = 1.000000e-112, .off = 5.034080131510290214e-129 },
427 HP{.val=1.000000e-113, .off= 2.148774313452247863e-130 },427 HP{ .val = 1.000000e-113, .off = 2.148774313452247863e-130 },
428 HP{.val=1.000000e-114, .off= -5.064490231692858416e-131 },428 HP{ .val = 1.000000e-114, .off = -5.064490231692858416e-131 },
429 HP{.val=1.000000e-115, .off= -5.064490231692858166e-132 },429 HP{ .val = 1.000000e-115, .off = -5.064490231692858166e-132 },
430 HP{.val=1.000000e-116, .off= 5.708726942017560559e-134 },430 HP{ .val = 1.000000e-116, .off = 5.708726942017560559e-134 },
431 HP{.val=1.000000e-117, .off= -2.951229134482377772e-134 },431 HP{ .val = 1.000000e-117, .off = -2.951229134482377772e-134 },
432 HP{.val=1.000000e-118, .off= 1.451398151372789513e-135 },432 HP{ .val = 1.000000e-118, .off = 1.451398151372789513e-135 },
433 HP{.val=1.000000e-119, .off= -1.300243902286690040e-136 },433 HP{ .val = 1.000000e-119, .off = -1.300243902286690040e-136 },
434 HP{.val=1.000000e-120, .off= 2.139308664787659449e-137 },434 HP{ .val = 1.000000e-120, .off = 2.139308664787659449e-137 },
435 HP{.val=1.000000e-121, .off= 2.139308664787659329e-138 },435 HP{ .val = 1.000000e-121, .off = 2.139308664787659329e-138 },
436 HP{.val=1.000000e-122, .off= -5.922142664292847471e-139 },436 HP{ .val = 1.000000e-122, .off = -5.922142664292847471e-139 },
437 HP{.val=1.000000e-123, .off= -5.922142664292846912e-140 },437 HP{ .val = 1.000000e-123, .off = -5.922142664292846912e-140 },
438 HP{.val=1.000000e-124, .off= 6.673875037395443799e-141 },438 HP{ .val = 1.000000e-124, .off = 6.673875037395443799e-141 },
439 HP{.val=1.000000e-125, .off= -1.198636026159737932e-142 },439 HP{ .val = 1.000000e-125, .off = -1.198636026159737932e-142 },
440 HP{.val=1.000000e-126, .off= 5.361789860136246995e-143 },440 HP{ .val = 1.000000e-126, .off = 5.361789860136246995e-143 },
441 HP{.val=1.000000e-127, .off= -2.838742497733733936e-144 },441 HP{ .val = 1.000000e-127, .off = -2.838742497733733936e-144 },
442 HP{.val=1.000000e-128, .off= -5.401408859568103261e-145 },442 HP{ .val = 1.000000e-128, .off = -5.401408859568103261e-145 },
443 HP{.val=1.000000e-129, .off= 7.411922949603743011e-146 },443 HP{ .val = 1.000000e-129, .off = 7.411922949603743011e-146 },
444 HP{.val=1.000000e-130, .off= -8.604741811861064385e-147 },444 HP{ .val = 1.000000e-130, .off = -8.604741811861064385e-147 },
445 HP{.val=1.000000e-131, .off= 1.405673664054439890e-148 },445 HP{ .val = 1.000000e-131, .off = 1.405673664054439890e-148 },
446 HP{.val=1.000000e-132, .off= 1.405673664054439933e-149 },446 HP{ .val = 1.000000e-132, .off = 1.405673664054439933e-149 },
447 HP{.val=1.000000e-133, .off= -6.414963426504548053e-150 },447 HP{ .val = 1.000000e-133, .off = -6.414963426504548053e-150 },
448 HP{.val=1.000000e-134, .off= -3.971014335704864578e-151 },448 HP{ .val = 1.000000e-134, .off = -3.971014335704864578e-151 },
449 HP{.val=1.000000e-135, .off= -3.971014335704864748e-152 },449 HP{ .val = 1.000000e-135, .off = -3.971014335704864748e-152 },
450 HP{.val=1.000000e-136, .off= -1.523438813303585576e-154 },450 HP{ .val = 1.000000e-136, .off = -1.523438813303585576e-154 },
451 HP{.val=1.000000e-137, .off= 2.234325152653707766e-154 },451 HP{ .val = 1.000000e-137, .off = 2.234325152653707766e-154 },
452 HP{.val=1.000000e-138, .off= -6.715683724786540160e-155 },452 HP{ .val = 1.000000e-138, .off = -6.715683724786540160e-155 },
453 HP{.val=1.000000e-139, .off= -2.986513359186437306e-156 },453 HP{ .val = 1.000000e-139, .off = -2.986513359186437306e-156 },
454 HP{.val=1.000000e-140, .off= 1.674949597813692102e-157 },454 HP{ .val = 1.000000e-140, .off = 1.674949597813692102e-157 },
455 HP{.val=1.000000e-141, .off= -4.151879098436469092e-158 },455 HP{ .val = 1.000000e-141, .off = -4.151879098436469092e-158 },
456 HP{.val=1.000000e-142, .off= -4.151879098436469295e-159 },456 HP{ .val = 1.000000e-142, .off = -4.151879098436469295e-159 },
457 HP{.val=1.000000e-143, .off= 4.952540739454407825e-160 },457 HP{ .val = 1.000000e-143, .off = 4.952540739454407825e-160 },
458 HP{.val=1.000000e-144, .off= 4.952540739454407667e-161 },458 HP{ .val = 1.000000e-144, .off = 4.952540739454407667e-161 },
459 HP{.val=1.000000e-145, .off= 8.508954738630531443e-162 },459 HP{ .val = 1.000000e-145, .off = 8.508954738630531443e-162 },
460 HP{.val=1.000000e-146, .off= -2.604839008794855481e-163 },460 HP{ .val = 1.000000e-146, .off = -2.604839008794855481e-163 },
461 HP{.val=1.000000e-147, .off= 2.952057864917838382e-164 },461 HP{ .val = 1.000000e-147, .off = 2.952057864917838382e-164 },
462 HP{.val=1.000000e-148, .off= 6.425118410988271757e-165 },462 HP{ .val = 1.000000e-148, .off = 6.425118410988271757e-165 },
463 HP{.val=1.000000e-149, .off= 2.083792728400229858e-166 },463 HP{ .val = 1.000000e-149, .off = 2.083792728400229858e-166 },
464 HP{.val=1.000000e-150, .off= -6.295358232172964237e-168 },464 HP{ .val = 1.000000e-150, .off = -6.295358232172964237e-168 },
465 HP{.val=1.000000e-151, .off= 6.153785555826519421e-168 },465 HP{ .val = 1.000000e-151, .off = 6.153785555826519421e-168 },
466 HP{.val=1.000000e-152, .off= -6.564942029880634994e-169 },466 HP{ .val = 1.000000e-152, .off = -6.564942029880634994e-169 },
467 HP{.val=1.000000e-153, .off= -3.915207116191644540e-170 },467 HP{ .val = 1.000000e-153, .off = -3.915207116191644540e-170 },
468 HP{.val=1.000000e-154, .off= 2.709130168030831503e-171 },468 HP{ .val = 1.000000e-154, .off = 2.709130168030831503e-171 },
469 HP{.val=1.000000e-155, .off= -1.431080634608215966e-172 },469 HP{ .val = 1.000000e-155, .off = -1.431080634608215966e-172 },
470 HP{.val=1.000000e-156, .off= -4.018712386257620994e-173 },470 HP{ .val = 1.000000e-156, .off = -4.018712386257620994e-173 },
471 HP{.val=1.000000e-157, .off= 5.684906682427646782e-174 },471 HP{ .val = 1.000000e-157, .off = 5.684906682427646782e-174 },
472 HP{.val=1.000000e-158, .off= -6.444617153428937489e-175 },472 HP{ .val = 1.000000e-158, .off = -6.444617153428937489e-175 },
473 HP{.val=1.000000e-159, .off= 1.136335243981427681e-176 },473 HP{ .val = 1.000000e-159, .off = 1.136335243981427681e-176 },
474 HP{.val=1.000000e-160, .off= 1.136335243981427725e-177 },474 HP{ .val = 1.000000e-160, .off = 1.136335243981427725e-177 },
475 HP{.val=1.000000e-161, .off= -2.812077463003137395e-178 },475 HP{ .val = 1.000000e-161, .off = -2.812077463003137395e-178 },
476 HP{.val=1.000000e-162, .off= 4.591196362592922204e-179 },476 HP{ .val = 1.000000e-162, .off = 4.591196362592922204e-179 },
477 HP{.val=1.000000e-163, .off= 7.675893789924613703e-180 },477 HP{ .val = 1.000000e-163, .off = 7.675893789924613703e-180 },
478 HP{.val=1.000000e-164, .off= 3.820022005759999543e-181 },478 HP{ .val = 1.000000e-164, .off = 3.820022005759999543e-181 },
479 HP{.val=1.000000e-165, .off= -9.998177244457686588e-183 },479 HP{ .val = 1.000000e-165, .off = -9.998177244457686588e-183 },
480 HP{.val=1.000000e-166, .off= -4.012217555824373639e-183 },480 HP{ .val = 1.000000e-166, .off = -4.012217555824373639e-183 },
481 HP{.val=1.000000e-167, .off= -2.467177666011174334e-185 },481 HP{ .val = 1.000000e-167, .off = -2.467177666011174334e-185 },
482 HP{.val=1.000000e-168, .off= -4.953592503130188139e-185 },482 HP{ .val = 1.000000e-168, .off = -4.953592503130188139e-185 },
483 HP{.val=1.000000e-169, .off= -2.011795792799518887e-186 },483 HP{ .val = 1.000000e-169, .off = -2.011795792799518887e-186 },
484 HP{.val=1.000000e-170, .off= 1.665450095113817423e-187 },484 HP{ .val = 1.000000e-170, .off = 1.665450095113817423e-187 },
485 HP{.val=1.000000e-171, .off= 1.665450095113817487e-188 },485 HP{ .val = 1.000000e-171, .off = 1.665450095113817487e-188 },
486 HP{.val=1.000000e-172, .off= -4.080246604750770577e-189 },486 HP{ .val = 1.000000e-172, .off = -4.080246604750770577e-189 },
487 HP{.val=1.000000e-173, .off= -4.080246604750770677e-190 },487 HP{ .val = 1.000000e-173, .off = -4.080246604750770677e-190 },
488 HP{.val=1.000000e-174, .off= 4.085789420184387951e-192 },488 HP{ .val = 1.000000e-174, .off = 4.085789420184387951e-192 },
489 HP{.val=1.000000e-175, .off= 4.085789420184388146e-193 },489 HP{ .val = 1.000000e-175, .off = 4.085789420184388146e-193 },
490 HP{.val=1.000000e-176, .off= 4.085789420184388146e-194 },490 HP{ .val = 1.000000e-176, .off = 4.085789420184388146e-194 },
491 HP{.val=1.000000e-177, .off= 4.792197640035244894e-194 },491 HP{ .val = 1.000000e-177, .off = 4.792197640035244894e-194 },
492 HP{.val=1.000000e-178, .off= 4.792197640035244742e-195 },492 HP{ .val = 1.000000e-178, .off = 4.792197640035244742e-195 },
493 HP{.val=1.000000e-179, .off= -2.057206575616014662e-196 },493 HP{ .val = 1.000000e-179, .off = -2.057206575616014662e-196 },
494 HP{.val=1.000000e-180, .off= -2.057206575616014662e-197 },494 HP{ .val = 1.000000e-180, .off = -2.057206575616014662e-197 },
495 HP{.val=1.000000e-181, .off= -4.732755097354788053e-198 },495 HP{ .val = 1.000000e-181, .off = -4.732755097354788053e-198 },
496 HP{.val=1.000000e-182, .off= -4.732755097354787867e-199 },496 HP{ .val = 1.000000e-182, .off = -4.732755097354787867e-199 },
497 HP{.val=1.000000e-183, .off= -5.522105321379546765e-201 },497 HP{ .val = 1.000000e-183, .off = -5.522105321379546765e-201 },
498 HP{.val=1.000000e-184, .off= -5.777891238658996019e-201 },498 HP{ .val = 1.000000e-184, .off = -5.777891238658996019e-201 },
499 HP{.val=1.000000e-185, .off= 7.542096444923057046e-203 },499 HP{ .val = 1.000000e-185, .off = 7.542096444923057046e-203 },
500 HP{.val=1.000000e-186, .off= 8.919335748431433483e-203 },500 HP{ .val = 1.000000e-186, .off = 8.919335748431433483e-203 },
501 HP{.val=1.000000e-187, .off= -1.287071881492476028e-204 },501 HP{ .val = 1.000000e-187, .off = -1.287071881492476028e-204 },
502 HP{.val=1.000000e-188, .off= 5.091932887209967018e-205 },502 HP{ .val = 1.000000e-188, .off = 5.091932887209967018e-205 },
503 HP{.val=1.000000e-189, .off= -6.868701054107114024e-206 },503 HP{ .val = 1.000000e-189, .off = -6.868701054107114024e-206 },
504 HP{.val=1.000000e-190, .off= -1.885103578558330118e-207 },504 HP{ .val = 1.000000e-190, .off = -1.885103578558330118e-207 },
505 HP{.val=1.000000e-191, .off= -1.885103578558330205e-208 },505 HP{ .val = 1.000000e-191, .off = -1.885103578558330205e-208 },
506 HP{.val=1.000000e-192, .off= -9.671974634103305058e-209 },506 HP{ .val = 1.000000e-192, .off = -9.671974634103305058e-209 },
507 HP{.val=1.000000e-193, .off= -4.805180224387695640e-210 },507 HP{ .val = 1.000000e-193, .off = -4.805180224387695640e-210 },
508 HP{.val=1.000000e-194, .off= -1.763433718315439838e-211 },508 HP{ .val = 1.000000e-194, .off = -1.763433718315439838e-211 },
509 HP{.val=1.000000e-195, .off= -9.367799983496079132e-212 },509 HP{ .val = 1.000000e-195, .off = -9.367799983496079132e-212 },
510 HP{.val=1.000000e-196, .off= -4.615071067758179837e-213 },510 HP{ .val = 1.000000e-196, .off = -4.615071067758179837e-213 },
511 HP{.val=1.000000e-197, .off= 1.325840076914194777e-214 },511 HP{ .val = 1.000000e-197, .off = 1.325840076914194777e-214 },
512 HP{.val=1.000000e-198, .off= 8.751979007754662425e-215 },512 HP{ .val = 1.000000e-198, .off = 8.751979007754662425e-215 },
513 HP{.val=1.000000e-199, .off= 1.789973760091724198e-216 },513 HP{ .val = 1.000000e-199, .off = 1.789973760091724198e-216 },
514 HP{.val=1.000000e-200, .off= 1.789973760091724077e-217 },514 HP{ .val = 1.000000e-200, .off = 1.789973760091724077e-217 },
515 HP{.val=1.000000e-201, .off= 5.416018159916171171e-218 },515 HP{ .val = 1.000000e-201, .off = 5.416018159916171171e-218 },
516 HP{.val=1.000000e-202, .off= -3.649092839644947067e-219 },516 HP{ .val = 1.000000e-202, .off = -3.649092839644947067e-219 },
517 HP{.val=1.000000e-203, .off= -3.649092839644947067e-220 },517 HP{ .val = 1.000000e-203, .off = -3.649092839644947067e-220 },
518 HP{.val=1.000000e-204, .off= -1.080338554413850956e-222 },518 HP{ .val = 1.000000e-204, .off = -1.080338554413850956e-222 },
519 HP{.val=1.000000e-205, .off= -1.080338554413850841e-223 },519 HP{ .val = 1.000000e-205, .off = -1.080338554413850841e-223 },
520 HP{.val=1.000000e-206, .off= -2.874486186850417807e-223 },520 HP{ .val = 1.000000e-206, .off = -2.874486186850417807e-223 },
521 HP{.val=1.000000e-207, .off= 7.499710055933455072e-224 },521 HP{ .val = 1.000000e-207, .off = 7.499710055933455072e-224 },
522 HP{.val=1.000000e-208, .off= -9.790617015372999087e-225 },522 HP{ .val = 1.000000e-208, .off = -9.790617015372999087e-225 },
523 HP{.val=1.000000e-209, .off= -4.387389805589732612e-226 },523 HP{ .val = 1.000000e-209, .off = -4.387389805589732612e-226 },
524 HP{.val=1.000000e-210, .off= -4.387389805589732612e-227 },524 HP{ .val = 1.000000e-210, .off = -4.387389805589732612e-227 },
525 HP{.val=1.000000e-211, .off= -8.608661063232909897e-228 },525 HP{ .val = 1.000000e-211, .off = -8.608661063232909897e-228 },
526 HP{.val=1.000000e-212, .off= 4.582811616902018972e-229 },526 HP{ .val = 1.000000e-212, .off = 4.582811616902018972e-229 },
527 HP{.val=1.000000e-213, .off= 4.582811616902019155e-230 },527 HP{ .val = 1.000000e-213, .off = 4.582811616902019155e-230 },
528 HP{.val=1.000000e-214, .off= 8.705146829444184930e-231 },528 HP{ .val = 1.000000e-214, .off = 8.705146829444184930e-231 },
529 HP{.val=1.000000e-215, .off= -4.177150709750081830e-232 },529 HP{ .val = 1.000000e-215, .off = -4.177150709750081830e-232 },
530 HP{.val=1.000000e-216, .off= -4.177150709750082366e-233 },530 HP{ .val = 1.000000e-216, .off = -4.177150709750082366e-233 },
531 HP{.val=1.000000e-217, .off= -8.202868690748290237e-234 },531 HP{ .val = 1.000000e-217, .off = -8.202868690748290237e-234 },
532 HP{.val=1.000000e-218, .off= -3.170721214500530119e-235 },532 HP{ .val = 1.000000e-218, .off = -3.170721214500530119e-235 },
533 HP{.val=1.000000e-219, .off= -3.170721214500529857e-236 },533 HP{ .val = 1.000000e-219, .off = -3.170721214500529857e-236 },
534 HP{.val=1.000000e-220, .off= 7.606440013180328441e-238 },534 HP{ .val = 1.000000e-220, .off = 7.606440013180328441e-238 },
535 HP{.val=1.000000e-221, .off= -1.696459258568569049e-238 },535 HP{ .val = 1.000000e-221, .off = -1.696459258568569049e-238 },
536 HP{.val=1.000000e-222, .off= -4.767838333426821244e-239 },536 HP{ .val = 1.000000e-222, .off = -4.767838333426821244e-239 },
537 HP{.val=1.000000e-223, .off= 2.910609353718809138e-240 },537 HP{ .val = 1.000000e-223, .off = 2.910609353718809138e-240 },
538 HP{.val=1.000000e-224, .off= -1.888420450747209784e-241 },538 HP{ .val = 1.000000e-224, .off = -1.888420450747209784e-241 },
539 HP{.val=1.000000e-225, .off= 4.110366804835314035e-242 },539 HP{ .val = 1.000000e-225, .off = 4.110366804835314035e-242 },
540 HP{.val=1.000000e-226, .off= 7.859608839574391006e-243 },540 HP{ .val = 1.000000e-226, .off = 7.859608839574391006e-243 },
541 HP{.val=1.000000e-227, .off= 5.516332567862468419e-244 },541 HP{ .val = 1.000000e-227, .off = 5.516332567862468419e-244 },
542 HP{.val=1.000000e-228, .off= -3.270953451057244613e-245 },542 HP{ .val = 1.000000e-228, .off = -3.270953451057244613e-245 },
543 HP{.val=1.000000e-229, .off= -6.932322625607124670e-246 },543 HP{ .val = 1.000000e-229, .off = -6.932322625607124670e-246 },
544 HP{.val=1.000000e-230, .off= -4.643966891513449762e-247 },544 HP{ .val = 1.000000e-230, .off = -4.643966891513449762e-247 },
545 HP{.val=1.000000e-231, .off= 1.076922443720738305e-248 },545 HP{ .val = 1.000000e-231, .off = 1.076922443720738305e-248 },
546 HP{.val=1.000000e-232, .off= -2.498633390800628939e-249 },546 HP{ .val = 1.000000e-232, .off = -2.498633390800628939e-249 },
547 HP{.val=1.000000e-233, .off= 4.205533798926934891e-250 },547 HP{ .val = 1.000000e-233, .off = 4.205533798926934891e-250 },
548 HP{.val=1.000000e-234, .off= 4.205533798926934891e-251 },548 HP{ .val = 1.000000e-234, .off = 4.205533798926934891e-251 },
549 HP{.val=1.000000e-235, .off= 4.205533798926934697e-252 },549 HP{ .val = 1.000000e-235, .off = 4.205533798926934697e-252 },
550 HP{.val=1.000000e-236, .off= -4.523850562697497656e-253 },550 HP{ .val = 1.000000e-236, .off = -4.523850562697497656e-253 },
551 HP{.val=1.000000e-237, .off= 9.320146633177728298e-255 },551 HP{ .val = 1.000000e-237, .off = 9.320146633177728298e-255 },
552 HP{.val=1.000000e-238, .off= 9.320146633177728062e-256 },552 HP{ .val = 1.000000e-238, .off = 9.320146633177728062e-256 },
553 HP{.val=1.000000e-239, .off= -7.592774752331086440e-256 },553 HP{ .val = 1.000000e-239, .off = -7.592774752331086440e-256 },
554 HP{.val=1.000000e-240, .off= 3.063212017229987840e-257 },554 HP{ .val = 1.000000e-240, .off = 3.063212017229987840e-257 },
555 HP{.val=1.000000e-241, .off= 3.063212017229987562e-258 },555 HP{ .val = 1.000000e-241, .off = 3.063212017229987562e-258 },
556 HP{.val=1.000000e-242, .off= 3.063212017229987562e-259 },556 HP{ .val = 1.000000e-242, .off = 3.063212017229987562e-259 },
557 HP{.val=1.000000e-243, .off= 4.616527473176159842e-261 },557 HP{ .val = 1.000000e-243, .off = 4.616527473176159842e-261 },
558 HP{.val=1.000000e-244, .off= 6.965550922098544975e-261 },558 HP{ .val = 1.000000e-244, .off = 6.965550922098544975e-261 },
559 HP{.val=1.000000e-245, .off= 6.965550922098544749e-262 },559 HP{ .val = 1.000000e-245, .off = 6.965550922098544749e-262 },
560 HP{.val=1.000000e-246, .off= 4.424965697574744679e-263 },560 HP{ .val = 1.000000e-246, .off = 4.424965697574744679e-263 },
561 HP{.val=1.000000e-247, .off= -1.926497363734756420e-264 },561 HP{ .val = 1.000000e-247, .off = -1.926497363734756420e-264 },
562 HP{.val=1.000000e-248, .off= 2.043167049583681740e-265 },562 HP{ .val = 1.000000e-248, .off = 2.043167049583681740e-265 },
563 HP{.val=1.000000e-249, .off= -5.399953725388390154e-266 },563 HP{ .val = 1.000000e-249, .off = -5.399953725388390154e-266 },
564 HP{.val=1.000000e-250, .off= -5.399953725388389982e-267 },564 HP{ .val = 1.000000e-250, .off = -5.399953725388389982e-267 },
565 HP{.val=1.000000e-251, .off= -1.523328321757102663e-268 },565 HP{ .val = 1.000000e-251, .off = -1.523328321757102663e-268 },
566 HP{.val=1.000000e-252, .off= 5.745344310051561161e-269 },566 HP{ .val = 1.000000e-252, .off = 5.745344310051561161e-269 },
567 HP{.val=1.000000e-253, .off= -6.369110076296211879e-270 },567 HP{ .val = 1.000000e-253, .off = -6.369110076296211879e-270 },
568 HP{.val=1.000000e-254, .off= 8.773957906638504842e-271 },568 HP{ .val = 1.000000e-254, .off = 8.773957906638504842e-271 },
569 HP{.val=1.000000e-255, .off= -6.904595826956931908e-273 },569 HP{ .val = 1.000000e-255, .off = -6.904595826956931908e-273 },
570 HP{.val=1.000000e-256, .off= 2.267170882721243669e-273 },570 HP{ .val = 1.000000e-256, .off = 2.267170882721243669e-273 },
571 HP{.val=1.000000e-257, .off= 2.267170882721243669e-274 },571 HP{ .val = 1.000000e-257, .off = 2.267170882721243669e-274 },
572 HP{.val=1.000000e-258, .off= 4.577819683828225398e-275 },572 HP{ .val = 1.000000e-258, .off = 4.577819683828225398e-275 },
573 HP{.val=1.000000e-259, .off= -6.975424321706684210e-276 },573 HP{ .val = 1.000000e-259, .off = -6.975424321706684210e-276 },
574 HP{.val=1.000000e-260, .off= 3.855741933482293648e-277 },574 HP{ .val = 1.000000e-260, .off = 3.855741933482293648e-277 },
575 HP{.val=1.000000e-261, .off= 1.599248963651256552e-278 },575 HP{ .val = 1.000000e-261, .off = 1.599248963651256552e-278 },
576 HP{.val=1.000000e-262, .off= -1.221367248637539543e-279 },576 HP{ .val = 1.000000e-262, .off = -1.221367248637539543e-279 },
577 HP{.val=1.000000e-263, .off= -1.221367248637539494e-280 },577 HP{ .val = 1.000000e-263, .off = -1.221367248637539494e-280 },
578 HP{.val=1.000000e-264, .off= -1.221367248637539647e-281 },578 HP{ .val = 1.000000e-264, .off = -1.221367248637539647e-281 },
579 HP{.val=1.000000e-265, .off= 1.533140771175737943e-282 },579 HP{ .val = 1.000000e-265, .off = 1.533140771175737943e-282 },
580 HP{.val=1.000000e-266, .off= 1.533140771175737895e-283 },580 HP{ .val = 1.000000e-266, .off = 1.533140771175737895e-283 },
581 HP{.val=1.000000e-267, .off= 1.533140771175738074e-284 },581 HP{ .val = 1.000000e-267, .off = 1.533140771175738074e-284 },
582 HP{.val=1.000000e-268, .off= 4.223090009274641634e-285 },582 HP{ .val = 1.000000e-268, .off = 4.223090009274641634e-285 },
583 HP{.val=1.000000e-269, .off= 4.223090009274641634e-286 },583 HP{ .val = 1.000000e-269, .off = 4.223090009274641634e-286 },
584 HP{.val=1.000000e-270, .off= -4.183001359784432924e-287 },584 HP{ .val = 1.000000e-270, .off = -4.183001359784432924e-287 },
585 HP{.val=1.000000e-271, .off= 3.697709298708449474e-288 },585 HP{ .val = 1.000000e-271, .off = 3.697709298708449474e-288 },
586 HP{.val=1.000000e-272, .off= 6.981338739747150474e-289 },586 HP{ .val = 1.000000e-272, .off = 6.981338739747150474e-289 },
587 HP{.val=1.000000e-273, .off= -9.436808465446354751e-290 },587 HP{ .val = 1.000000e-273, .off = -9.436808465446354751e-290 },
588 HP{.val=1.000000e-274, .off= 3.389869038611071740e-291 },588 HP{ .val = 1.000000e-274, .off = 3.389869038611071740e-291 },
589 HP{.val=1.000000e-275, .off= 6.596538414625427829e-292 },589 HP{ .val = 1.000000e-275, .off = 6.596538414625427829e-292 },
590 HP{.val=1.000000e-276, .off= -9.436808465446354618e-293 },590 HP{ .val = 1.000000e-276, .off = -9.436808465446354618e-293 },
591 HP{.val=1.000000e-277, .off= 3.089243784609725523e-294 },591 HP{ .val = 1.000000e-277, .off = 3.089243784609725523e-294 },
592 HP{.val=1.000000e-278, .off= 6.220756847123745836e-295 },592 HP{ .val = 1.000000e-278, .off = 6.220756847123745836e-295 },
593 HP{.val=1.000000e-279, .off= -5.522417137303829470e-296 },593 HP{ .val = 1.000000e-279, .off = -5.522417137303829470e-296 },
594 HP{.val=1.000000e-280, .off= 4.263561183052483059e-297 },594 HP{ .val = 1.000000e-280, .off = 4.263561183052483059e-297 },
595 HP{.val=1.000000e-281, .off= -1.852675267170212272e-298 },595 HP{ .val = 1.000000e-281, .off = -1.852675267170212272e-298 },
596 HP{.val=1.000000e-282, .off= -1.852675267170212378e-299 },596 HP{ .val = 1.000000e-282, .off = -1.852675267170212378e-299 },
597 HP{.val=1.000000e-283, .off= 5.314789322934508480e-300 },597 HP{ .val = 1.000000e-283, .off = 5.314789322934508480e-300 },
598 HP{.val=1.000000e-284, .off= -3.644541414696392675e-301 },598 HP{ .val = 1.000000e-284, .off = -3.644541414696392675e-301 },
599 HP{.val=1.000000e-285, .off= -7.377595888709267777e-302 },599 HP{ .val = 1.000000e-285, .off = -7.377595888709267777e-302 },
600 HP{.val=1.000000e-286, .off= -5.044436842451220838e-303 },600 HP{ .val = 1.000000e-286, .off = -5.044436842451220838e-303 },
601 HP{.val=1.000000e-287, .off= -2.127988034628661760e-304 },601 HP{ .val = 1.000000e-287, .off = -2.127988034628661760e-304 },
602 HP{.val=1.000000e-288, .off= -5.773549044406860911e-305 },602 HP{ .val = 1.000000e-288, .off = -5.773549044406860911e-305 },
603 HP{.val=1.000000e-289, .off= -1.216597782184112068e-306 },603 HP{ .val = 1.000000e-289, .off = -1.216597782184112068e-306 },
604 HP{.val=1.000000e-290, .off= -6.912786859962547924e-307 },604 HP{ .val = 1.000000e-290, .off = -6.912786859962547924e-307 },
605 HP{.val=1.000000e-291, .off= 3.767567660872018813e-308 },605 HP{ .val = 1.000000e-291, .off = 3.767567660872018813e-308 },
606};606};
std/fmt/index.zig+157-81
...@@ -11,9 +11,7 @@ const max_int_digits = 65;...@@ -11,9 +11,7 @@ const max_int_digits = 65;
11/// Renders fmt string with args, calling output with slices of bytes.11/// Renders fmt string with args, calling output with slices of bytes.
12/// If `output` returns an error, the error is returned from `format` and12/// If `output` returns an error, the error is returned from `format` and
13/// `output` is not called again.13/// `output` is not called again.
14pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void,14pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void, comptime fmt: []const u8, args: ...) Errors!void {
15 comptime fmt: []const u8, args: ...) Errors!void
16{
17 const State = enum {15 const State = enum {
18 Start,16 Start,
19 OpenBrace,17 OpenBrace,
...@@ -27,6 +25,9 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -27,6 +25,9 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
27 Character,25 Character,
28 Buf,26 Buf,
29 BufWidth,27 BufWidth,
28 Bytes,
29 BytesBase,
30 BytesWidth,
30 };31 };
3132
32 comptime var start_index = 0;33 comptime var start_index = 0;
...@@ -95,13 +96,18 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -95,13 +96,18 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
95 '.' => {96 '.' => {
96 state = State.Float;97 state = State.Float;
97 },98 },
99 'B' => {
100 width = 0;
101 radix = 1000;
102 state = State.Bytes;
103 },
98 else => @compileError("Unknown format character: " ++ []u8{c}),104 else => @compileError("Unknown format character: " ++ []u8{c}),
99 },105 },
100 State.Buf => switch (c) {106 State.Buf => switch (c) {
101 '}' => {107 '}' => {
102 return output(context, args[next_arg]);108 return output(context, args[next_arg]);
103 },109 },
104 '0' ... '9' => {110 '0'...'9' => {
105 width_start = i;111 width_start = i;
106 state = State.BufWidth;112 state = State.BufWidth;
107 },113 },
...@@ -121,7 +127,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -121,7 +127,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
121 state = State.Start;127 state = State.Start;
122 start_index = i + 1;128 start_index = i + 1;
123 },129 },
124 '0' ... '9' => {130 '0'...'9' => {
125 width_start = i;131 width_start = i;
126 state = State.IntegerWidth;132 state = State.IntegerWidth;
127 },133 },
...@@ -135,7 +141,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -135,7 +141,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
135 state = State.Start;141 state = State.Start;
136 start_index = i + 1;142 start_index = i + 1;
137 },143 },
138 '0' ... '9' => {},144 '0'...'9' => {},
139 else => @compileError("Unexpected character in format string: " ++ []u8{c}),145 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
140 },146 },
141 State.FloatScientific => switch (c) {147 State.FloatScientific => switch (c) {
...@@ -145,7 +151,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -145,7 +151,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
145 state = State.Start;151 state = State.Start;
146 start_index = i + 1;152 start_index = i + 1;
147 },153 },
148 '0' ... '9' => {154 '0'...'9' => {
149 width_start = i;155 width_start = i;
150 state = State.FloatScientificWidth;156 state = State.FloatScientificWidth;
151 },157 },
...@@ -159,7 +165,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -159,7 +165,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
159 state = State.Start;165 state = State.Start;
160 start_index = i + 1;166 start_index = i + 1;
161 },167 },
162 '0' ... '9' => {},168 '0'...'9' => {},
163 else => @compileError("Unexpected character in format string: " ++ []u8{c}),169 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
164 },170 },
165 State.Float => switch (c) {171 State.Float => switch (c) {
...@@ -169,7 +175,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -169,7 +175,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
169 state = State.Start;175 state = State.Start;
170 start_index = i + 1;176 start_index = i + 1;
171 },177 },
172 '0' ... '9' => {178 '0'...'9' => {
173 width_start = i;179 width_start = i;
174 state = State.FloatWidth;180 state = State.FloatWidth;
175 },181 },
...@@ -183,7 +189,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -183,7 +189,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
183 state = State.Start;189 state = State.Start;
184 start_index = i + 1;190 start_index = i + 1;
185 },191 },
186 '0' ... '9' => {},192 '0'...'9' => {},
187 else => @compileError("Unexpected character in format string: " ++ []u8{c}),193 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
188 },194 },
189 State.BufWidth => switch (c) {195 State.BufWidth => switch (c) {
...@@ -194,7 +200,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -194,7 +200,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
194 state = State.Start;200 state = State.Start;
195 start_index = i + 1;201 start_index = i + 1;
196 },202 },
197 '0' ... '9' => {},203 '0'...'9' => {},
198 else => @compileError("Unexpected character in format string: " ++ []u8{c}),204 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
199 },205 },
200 State.Character => switch (c) {206 State.Character => switch (c) {
...@@ -206,6 +212,47 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -206,6 +212,47 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
206 },212 },
207 else => @compileError("Unexpected character in format string: " ++ []u8{c}),213 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
208 },214 },
215 State.Bytes => switch (c) {
216 '}' => {
217 try formatBytes(args[next_arg], 0, radix, context, Errors, output);
218 next_arg += 1;
219 state = State.Start;
220 start_index = i + 1;
221 },
222 'i' => {
223 radix = 1024;
224 state = State.BytesBase;
225 },
226 '0'...'9' => {
227 width_start = i;
228 state = State.BytesWidth;
229 },
230 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
231 },
232 State.BytesBase => switch (c) {
233 '}' => {
234 try formatBytes(args[next_arg], 0, radix, context, Errors, output);
235 next_arg += 1;
236 state = State.Start;
237 start_index = i + 1;
238 },
239 '0'...'9' => {
240 width_start = i;
241 state = State.BytesWidth;
242 },
243 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
244 },
245 State.BytesWidth => switch (c) {
246 '}' => {
247 width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
248 try formatBytes(args[next_arg], width, radix, context, Errors, output);
249 next_arg += 1;
250 state = State.Start;
251 start_index = i + 1;
252 },
253 '0'...'9' => {},
254 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
255 },
209 }256 }
210 }257 }
211 comptime {258 comptime {
...@@ -221,7 +268,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -221,7 +268,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
221 }268 }
222}269}
223270
224pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {271pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void) Errors!void {
225 const T = @typeOf(value);272 const T = @typeOf(value);
226 switch (@typeId(T)) {273 switch (@typeId(T)) {
227 builtin.TypeId.Int => {274 builtin.TypeId.Int => {
...@@ -256,7 +303,7 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@...@@ -256,7 +303,7 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@
256 },303 },
257 builtin.TypeId.Pointer => {304 builtin.TypeId.Pointer => {
258 if (@typeId(T.Child) == builtin.TypeId.Array and T.Child.Child == u8) {305 if (@typeId(T.Child) == builtin.TypeId.Array and T.Child.Child == u8) {
259 return output(context, (*value)[0..]);306 return output(context, (value.*)[0..]);
260 } else {307 } else {
261 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));308 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
262 }309 }
...@@ -270,13 +317,11 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@...@@ -270,13 +317,11 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@
270 }317 }
271}318}
272319
273pub fn formatAsciiChar(c: u8, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {320pub fn formatAsciiChar(c: u8, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void) Errors!void {
274 return output(context, (&c)[0..1]);321 return output(context, (&c)[0..1]);
275}322}
276323
277pub fn formatBuf(buf: []const u8, width: usize,324pub fn formatBuf(buf: []const u8, width: usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void) Errors!void {
278 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
279{
280 try output(context, buf);325 try output(context, buf);
281326
282 var leftover_padding = if (width > buf.len) (width - buf.len) else return;327 var leftover_padding = if (width > buf.len) (width - buf.len) else return;
...@@ -289,7 +334,7 @@ pub fn formatBuf(buf: []const u8, width: usize,...@@ -289,7 +334,7 @@ pub fn formatBuf(buf: []const u8, width: usize,
289// Print a float in scientific notation to the specified precision. Null uses full precision.334// Print a float in scientific notation to the specified precision. Null uses full precision.
290// It should be the case that every full precision, printed value can be re-parsed back to the335// It should be the case that every full precision, printed value can be re-parsed back to the
291// same type unambiguously.336// same type unambiguously.
292pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {337pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void) Errors!void {
293 var x = f64(value);338 var x = f64(value);
294339
295 // Errol doesn't handle these special cases.340 // Errol doesn't handle these special cases.
...@@ -338,7 +383,7 @@ pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var,...@@ -338,7 +383,7 @@ pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var,
338 var printed: usize = 0;383 var printed: usize = 0;
339 if (float_decimal.digits.len > 1) {384 if (float_decimal.digits.len > 1) {
340 const num_digits = math.min(float_decimal.digits.len, precision + 1);385 const num_digits = math.min(float_decimal.digits.len, precision + 1);
341 try output(context, float_decimal.digits[1 .. num_digits]);386 try output(context, float_decimal.digits[1..num_digits]);
342 printed += num_digits - 1;387 printed += num_digits - 1;
343 }388 }
344389
...@@ -350,12 +395,9 @@ pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var,...@@ -350,12 +395,9 @@ pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var,
350 try output(context, float_decimal.digits[0..1]);395 try output(context, float_decimal.digits[0..1]);
351 try output(context, ".");396 try output(context, ".");
352 if (float_decimal.digits.len > 1) {397 if (float_decimal.digits.len > 1) {
353 const num_digits = if (@typeOf(value) == f32)398 const num_digits = if (@typeOf(value) == f32) math.min(usize(9), float_decimal.digits.len) else float_decimal.digits.len;
354 math.min(usize(9), float_decimal.digits.len)
355 else
356 float_decimal.digits.len;
357399
358 try output(context, float_decimal.digits[1 .. num_digits]);400 try output(context, float_decimal.digits[1..num_digits]);
359 } else {401 } else {
360 try output(context, "0");402 try output(context, "0");
361 }403 }
...@@ -381,7 +423,7 @@ pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var,...@@ -381,7 +423,7 @@ pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var,
381423
382// Print a float of the format x.yyyyy where the number of y is specified by the precision argument.424// Print a float of the format x.yyyyy where the number of y is specified by the precision argument.
383// By default floats are printed at full precision (no rounding).425// By default floats are printed at full precision (no rounding).
384pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {426pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void) Errors!void {
385 var x = f64(value);427 var x = f64(value);
386428
387 // Errol doesn't handle these special cases.429 // Errol doesn't handle these special cases.
...@@ -431,14 +473,14 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com...@@ -431,14 +473,14 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com
431473
432 if (num_digits_whole > 0) {474 if (num_digits_whole > 0) {
433 // We may have to zero pad, for instance 1e4 requires zero padding.475 // We may have to zero pad, for instance 1e4 requires zero padding.
434 try output(context, float_decimal.digits[0 .. num_digits_whole_no_pad]);476 try output(context, float_decimal.digits[0..num_digits_whole_no_pad]);
435477
436 var i = num_digits_whole_no_pad;478 var i = num_digits_whole_no_pad;
437 while (i < num_digits_whole) : (i += 1) {479 while (i < num_digits_whole) : (i += 1) {
438 try output(context, "0");480 try output(context, "0");
439 }481 }
440 } else {482 } else {
441 try output(context , "0");483 try output(context, "0");
442 }484 }
443485
444 // {.0} special case doesn't want a trailing '.'486 // {.0} special case doesn't want a trailing '.'
...@@ -470,10 +512,10 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com...@@ -470,10 +512,10 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com
470 // Remaining fractional portion, zero-padding if insufficient.512 // Remaining fractional portion, zero-padding if insufficient.
471 debug.assert(precision >= printed);513 debug.assert(precision >= printed);
472 if (num_digits_whole_no_pad + precision - printed < float_decimal.digits.len) {514 if (num_digits_whole_no_pad + precision - printed < float_decimal.digits.len) {
473 try output(context, float_decimal.digits[num_digits_whole_no_pad .. num_digits_whole_no_pad + precision - printed]);515 try output(context, float_decimal.digits[num_digits_whole_no_pad..num_digits_whole_no_pad + precision - printed]);
474 return;516 return;
475 } else {517 } else {
476 try output(context, float_decimal.digits[num_digits_whole_no_pad ..]);518 try output(context, float_decimal.digits[num_digits_whole_no_pad..]);
477 printed += float_decimal.digits.len - num_digits_whole_no_pad;519 printed += float_decimal.digits.len - num_digits_whole_no_pad;
478520
479 while (printed < precision) : (printed += 1) {521 while (printed < precision) : (printed += 1) {
...@@ -489,14 +531,14 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com...@@ -489,14 +531,14 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com
489531
490 if (num_digits_whole > 0) {532 if (num_digits_whole > 0) {
491 // We may have to zero pad, for instance 1e4 requires zero padding.533 // We may have to zero pad, for instance 1e4 requires zero padding.
492 try output(context, float_decimal.digits[0 .. num_digits_whole_no_pad]);534 try output(context, float_decimal.digits[0..num_digits_whole_no_pad]);
493535
494 var i = num_digits_whole_no_pad;536 var i = num_digits_whole_no_pad;
495 while (i < num_digits_whole) : (i += 1) {537 while (i < num_digits_whole) : (i += 1) {
496 try output(context, "0");538 try output(context, "0");
497 }539 }
498 } else {540 } else {
499 try output(context , "0");541 try output(context, "0");
500 }542 }
501543
502 // Omit `.` if no fractional portion544 // Omit `.` if no fractional portion
...@@ -516,14 +558,54 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com...@@ -516,14 +558,54 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com
516 }558 }
517 }559 }
518560
519 try output(context, float_decimal.digits[num_digits_whole_no_pad ..]);561 try output(context, float_decimal.digits[num_digits_whole_no_pad..]);
520 }562 }
521}563}
522564
565pub fn formatBytes(
566 value: var,
567 width: ?usize,
568 comptime radix: usize,
569 context: var,
570 comptime Errors: type,
571 output: fn(@typeOf(context), []const u8) Errors!void,
572) Errors!void {
573 if (value == 0) {
574 return output(context, "0B");
575 }
576
577 const mags = " KMGTPEZY";
578 const magnitude = switch (radix) {
579 1000 => math.min(math.log2(value) / comptime math.log2(1000), mags.len - 1),
580 1024 => math.min(math.log2(value) / 10, mags.len - 1),
581 else => unreachable,
582 };
583 const new_value = f64(value) / math.pow(f64, f64(radix), f64(magnitude));
584 const suffix = mags[magnitude];
585
586 try formatFloatDecimal(new_value, width, context, Errors, output);
587
588 if (suffix == ' ') {
589 return output(context, "B");
590 }
591
592 const buf = switch (radix) {
593 1000 => []u8{ suffix, 'B' },
594 1024 => []u8{ suffix, 'i', 'B' },
595 else => unreachable,
596 };
597 return output(context, buf);
598}
523599
524pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,600pub fn formatInt(
525 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void601 value: var,
526{602 base: u8,
603 uppercase: bool,
604 width: usize,
605 context: var,
606 comptime Errors: type,
607 output: fn(@typeOf(context), []const u8) Errors!void,
608) Errors!void {
527 if (@typeOf(value).is_signed) {609 if (@typeOf(value).is_signed) {
528 return formatIntSigned(value, base, uppercase, width, context, Errors, output);610 return formatIntSigned(value, base, uppercase, width, context, Errors, output);
529 } else {611 } else {
...@@ -531,9 +613,7 @@ pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,...@@ -531,9 +613,7 @@ pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
531 }613 }
532}614}
533615
534fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,616fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void) Errors!void {
535 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
536{
537 const uint = @IntType(false, @typeOf(value).bit_count);617 const uint = @IntType(false, @typeOf(value).bit_count);
538 if (value < 0) {618 if (value < 0) {
539 const minus_sign: u8 = '-';619 const minus_sign: u8 = '-';
...@@ -552,9 +632,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,...@@ -552,9 +632,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
552 }632 }
553}633}
554634
555fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,635fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void) Errors!void {
556 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
557{
558 // max_int_digits accounts for the minus sign. when printing an unsigned636 // max_int_digits accounts for the minus sign. when printing an unsigned
559 // number we don't need to do that.637 // number we don't need to do that.
560 var buf: [max_int_digits - 1]u8 = undefined;638 var buf: [max_int_digits - 1]u8 = undefined;
...@@ -566,8 +644,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,...@@ -566,8 +644,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
566 index -= 1;644 index -= 1;
567 buf[index] = digitToChar(u8(digit), uppercase);645 buf[index] = digitToChar(u8(digit), uppercase);
568 a /= base;646 a /= base;
569 if (a == 0)647 if (a == 0) break;
570 break;
571 }648 }
572649
573 const digits_buf = buf[index..];650 const digits_buf = buf[index..];
...@@ -579,8 +656,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,...@@ -579,8 +656,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
579 while (true) {656 while (true) {
580 try output(context, (&zero_byte)[0..1]);657 try output(context, (&zero_byte)[0..1]);
581 leftover_padding -= 1;658 leftover_padding -= 1;
582 if (leftover_padding == 0)659 if (leftover_padding == 0) break;
583 break;
584 }660 }
585 mem.set(u8, buf[0..index], '0');661 mem.set(u8, buf[0..index], '0');
586 return output(context, buf);662 return output(context, buf);
...@@ -592,7 +668,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,...@@ -592,7 +668,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
592}668}
593669
594pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width: usize) usize {670pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width: usize) usize {
595 var context = FormatIntBuf {671 var context = FormatIntBuf{
596 .out_buf = out_buf,672 .out_buf = out_buf,
597 .index = 0,673 .index = 0,
598 };674 };
...@@ -609,10 +685,8 @@ fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) (error{}!void) {...@@ -609,10 +685,8 @@ fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) (error{}!void) {
609}685}
610686
611pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T {687pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T {
612 if (!T.is_signed)688 if (!T.is_signed) return parseUnsigned(T, buf, radix);
613 return parseUnsigned(T, buf, radix);689 if (buf.len == 0) return T(0);
614 if (buf.len == 0)
615 return T(0);
616 if (buf[0] == '-') {690 if (buf[0] == '-') {
617 return math.negate(try parseUnsigned(T, buf[1..], radix));691 return math.negate(try parseUnsigned(T, buf[1..], radix));
618 } else if (buf[0] == '+') {692 } else if (buf[0] == '+') {
...@@ -632,9 +706,10 @@ test "fmt.parseInt" {...@@ -632,9 +706,10 @@ test "fmt.parseInt" {
632 assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);706 assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
633}707}
634708
635const ParseUnsignedError = error {709const ParseUnsignedError = error{
636 /// The result cannot fit in the type specified710 /// The result cannot fit in the type specified
637 Overflow,711 Overflow,
712
638 /// The input had a byte that was not a digit713 /// The input had a byte that was not a digit
639 InvalidCharacter,714 InvalidCharacter,
640};715};
...@@ -653,22 +728,21 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned...@@ -653,22 +728,21 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned
653728
654pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {729pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
655 const value = switch (c) {730 const value = switch (c) {
656 '0' ... '9' => c - '0',731 '0'...'9' => c - '0',
657 'A' ... 'Z' => c - 'A' + 10,732 'A'...'Z' => c - 'A' + 10,
658 'a' ... 'z' => c - 'a' + 10,733 'a'...'z' => c - 'a' + 10,
659 else => return error.InvalidCharacter,734 else => return error.InvalidCharacter,
660 };735 };
661736
662 if (value >= radix)737 if (value >= radix) return error.InvalidCharacter;
663 return error.InvalidCharacter;
664738
665 return value;739 return value;
666}740}
667741
668fn digitToChar(digit: u8, uppercase: bool) u8 {742fn digitToChar(digit: u8, uppercase: bool) u8 {
669 return switch (digit) {743 return switch (digit) {
670 0 ... 9 => digit + '0',744 0...9 => digit + '0',
671 10 ... 35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),745 10...35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),
672 else => unreachable,746 else => unreachable,
673 };747 };
674}748}
...@@ -684,7 +758,7 @@ fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) !void {...@@ -684,7 +758,7 @@ fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) !void {
684}758}
685759
686pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) ![]u8 {760pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) ![]u8 {
687 var context = BufPrintContext { .remaining = buf, };761 var context = BufPrintContext{ .remaining = buf };
688 try format(&context, error{BufferTooSmall}, bufPrintWrite, fmt, args);762 try format(&context, error{BufferTooSmall}, bufPrintWrite, fmt, args);
689 return buf[0..buf.len - context.remaining.len];763 return buf[0..buf.len - context.remaining.len];
690}764}
...@@ -697,7 +771,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ......@@ -697,7 +771,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...
697}771}
698772
699fn countSize(size: &usize, bytes: []const u8) (error{}!void) {773fn countSize(size: &usize, bytes: []const u8) (error{}!void) {
700 *size += bytes.len;774 size.* += bytes.len;
701}775}
702776
703test "buf print int" {777test "buf print int" {
...@@ -738,44 +812,34 @@ test "parse unsigned comptime" {...@@ -738,44 +812,34 @@ test "parse unsigned comptime" {
738812
739test "fmt.format" {813test "fmt.format" {
740 {814 {
741 var buf1: [32]u8 = undefined;
742 const value: ?i32 = 1234;815 const value: ?i32 = 1234;
743 const result = try bufPrint(buf1[0..], "nullable: {}\n", value);816 try testFmt("nullable: 1234\n", "nullable: {}\n", value);
744 assert(mem.eql(u8, result, "nullable: 1234\n"));
745 }817 }
746 {818 {
747 var buf1: [32]u8 = undefined;
748 const value: ?i32 = null;819 const value: ?i32 = null;
749 const result = try bufPrint(buf1[0..], "nullable: {}\n", value);820 try testFmt("nullable: null\n", "nullable: {}\n", value);
750 assert(mem.eql(u8, result, "nullable: null\n"));
751 }821 }
752 {822 {
753 var buf1: [32]u8 = undefined;
754 const value: error!i32 = 1234;823 const value: error!i32 = 1234;
755 const result = try bufPrint(buf1[0..], "error union: {}\n", value);824 try testFmt("error union: 1234\n", "error union: {}\n", value);
756 assert(mem.eql(u8, result, "error union: 1234\n"));
757 }825 }
758 {826 {
759 var buf1: [32]u8 = undefined;
760 const value: error!i32 = error.InvalidChar;827 const value: error!i32 = error.InvalidChar;
761 const result = try bufPrint(buf1[0..], "error union: {}\n", value);828 try testFmt("error union: error.InvalidChar\n", "error union: {}\n", value);
762 assert(mem.eql(u8, result, "error union: error.InvalidChar\n"));
763 }829 }
764 {830 {
765 var buf1: [32]u8 = undefined;
766 const value: u3 = 0b101;831 const value: u3 = 0b101;
767 const result = try bufPrint(buf1[0..], "u3: {}\n", value);832 try testFmt("u3: 5\n", "u3: {}\n", value);
768 assert(mem.eql(u8, result, "u3: 5\n"));
769 }833 }
834 try testFmt("file size: 63MiB\n", "file size: {Bi}\n", usize(63 * 1024 * 1024));
835 try testFmt("file size: 66.06MB\n", "file size: {B2}\n", usize(63 * 1024 * 1024));
770 {836 {
771 // Dummy field because of https://github.com/zig-lang/zig/issues/557.837 // Dummy field because of https://github.com/ziglang/zig/issues/557.
772 const Struct = struct {838 const Struct = struct {
773 unused: u8,839 unused: u8,
774 };840 };
775 var buf1: [32]u8 = undefined;841 var buf1: [32]u8 = undefined;
776 const value = Struct {842 const value = Struct{ .unused = 42 };
777 .unused = 42,
778 };
779 const result = try bufPrint(buf1[0..], "pointer: {}\n", &value);843 const result = try bufPrint(buf1[0..], "pointer: {}\n", &value);
780 assert(mem.startsWith(u8, result, "pointer: Struct@"));844 assert(mem.startsWith(u8, result, "pointer: Struct@"));
781 }845 }
...@@ -986,9 +1050,22 @@ test "fmt.format" {...@@ -986,9 +1050,22 @@ test "fmt.format" {
986 }1050 }
987}1051}
9881052
1053fn testFmt(expected: []const u8, comptime template: []const u8, args: ...) !void {
1054 var buf: [100]u8 = undefined;
1055 const result = try bufPrint(buf[0..], template, args);
1056 if (mem.eql(u8, result, expected)) return;
1057
1058 std.debug.warn("\n====== expected this output: =========\n");
1059 std.debug.warn("{}", expected);
1060 std.debug.warn("\n======== instead found this: =========\n");
1061 std.debug.warn("{}", result);
1062 std.debug.warn("\n======================================\n");
1063 return error.TestFailed;
1064}
1065
989pub fn trim(buf: []const u8) []const u8 {1066pub fn trim(buf: []const u8) []const u8 {
990 var start: usize = 0;1067 var start: usize = 0;
991 while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) { }1068 while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) {}
9921069
993 var end: usize = buf.len;1070 var end: usize = buf.len;
994 while (true) {1071 while (true) {
...@@ -1000,7 +1077,6 @@ pub fn trim(buf: []const u8) []const u8 {...@@ -1000,7 +1077,6 @@ pub fn trim(buf: []const u8) []const u8 {
1000 }1077 }
1001 }1078 }
1002 break;1079 break;
1003
1004 }1080 }
1005 return buf[start..end];1081 return buf[start..end];
1006}1082}
std/hash/adler.zig+6-11
...@@ -13,9 +13,7 @@ pub const Adler32 = struct {...@@ -13,9 +13,7 @@ pub const Adler32 = struct {
13 adler: u32,13 adler: u32,
1414
15 pub fn init() Adler32 {15 pub fn init() Adler32 {
16 return Adler32 {16 return Adler32{ .adler = 1 };
17 .adler = 1,
18 };
19 }17 }
2018
21 // This fast variant is taken from zlib. It reduces the required modulos and unrolls longer19 // This fast variant is taken from zlib. It reduces the required modulos and unrolls longer
...@@ -33,8 +31,7 @@ pub const Adler32 = struct {...@@ -33,8 +31,7 @@ pub const Adler32 = struct {
33 if (s2 >= base) {31 if (s2 >= base) {
34 s2 -= base;32 s2 -= base;
35 }33 }
36 }34 } else if (input.len < 16) {
37 else if (input.len < 16) {
38 for (input) |b| {35 for (input) |b| {
39 s1 +%= b;36 s1 +%= b;
40 s2 +%= s1;37 s2 +%= s1;
...@@ -44,8 +41,7 @@ pub const Adler32 = struct {...@@ -44,8 +41,7 @@ pub const Adler32 = struct {
44 }41 }
4542
46 s2 %= base;43 s2 %= base;
47 }44 } else {
48 else {
49 var i: usize = 0;45 var i: usize = 0;
50 while (i + nmax <= input.len) : (i += nmax) {46 while (i + nmax <= input.len) : (i += nmax) {
51 const n = nmax / 16; // note: 16 | nmax47 const n = nmax / 16; // note: 16 | nmax
...@@ -98,15 +94,14 @@ test "adler32 sanity" {...@@ -98,15 +94,14 @@ test "adler32 sanity" {
98}94}
9995
100test "adler32 long" {96test "adler32 long" {
101 const long1 = []u8 {1} ** 1024;97 const long1 = []u8{1} ** 1024;
102 debug.assert(Adler32.hash(long1[0..]) == 0x06780401);98 debug.assert(Adler32.hash(long1[0..]) == 0x06780401);
10399
104 const long2 = []u8 {1} ** 1025;100 const long2 = []u8{1} ** 1025;
105 debug.assert(Adler32.hash(long2[0..]) == 0x0a7a0402);101 debug.assert(Adler32.hash(long2[0..]) == 0x0a7a0402);
106}102}
107103
108test "adler32 very long" {104test "adler32 very long" {
109 const long = []u8 {1} ** 5553;105 const long = []u8{1} ** 5553;
110 debug.assert(Adler32.hash(long[0..]) == 0x707f15b2);106 debug.assert(Adler32.hash(long[0..]) == 0x707f15b2);
111}107}
112
std/hash/crc.zig+17-18
...@@ -9,9 +9,9 @@ const std = @import("../index.zig");...@@ -9,9 +9,9 @@ const std = @import("../index.zig");
9const debug = std.debug;9const debug = std.debug;
1010
11pub const Polynomial = struct {11pub const Polynomial = struct {
12 const IEEE = 0xedb88320;12 const IEEE = 0xedb88320;
13 const Castagnoli = 0x82f63b78;13 const Castagnoli = 0x82f63b78;
14 const Koopman = 0xeb31d82e;14 const Koopman = 0xeb31d82e;
15};15};
1616
17// IEEE is by far the most common CRC and so is aliased by default.17// IEEE is by far the most common CRC and so is aliased by default.
...@@ -27,20 +27,22 @@ pub fn Crc32WithPoly(comptime poly: u32) type {...@@ -27,20 +27,22 @@ pub fn Crc32WithPoly(comptime poly: u32) type {
2727
28 for (tables[0]) |*e, i| {28 for (tables[0]) |*e, i| {
29 var crc = u32(i);29 var crc = u32(i);
30 var j: usize = 0; while (j < 8) : (j += 1) {30 var j: usize = 0;
31 while (j < 8) : (j += 1) {
31 if (crc & 1 == 1) {32 if (crc & 1 == 1) {
32 crc = (crc >> 1) ^ poly;33 crc = (crc >> 1) ^ poly;
33 } else {34 } else {
34 crc = (crc >> 1);35 crc = (crc >> 1);
35 }36 }
36 }37 }
37 *e = crc;38 e.* = crc;
38 }39 }
3940
40 var i: usize = 0;41 var i: usize = 0;
41 while (i < 256) : (i += 1) {42 while (i < 256) : (i += 1) {
42 var crc = tables[0][i];43 var crc = tables[0][i];
43 var j: usize = 1; while (j < 8) : (j += 1) {44 var j: usize = 1;
45 while (j < 8) : (j += 1) {
44 const index = @truncate(u8, crc);46 const index = @truncate(u8, crc);
45 crc = tables[0][index] ^ (crc >> 8);47 crc = tables[0][index] ^ (crc >> 8);
46 tables[j][i] = crc;48 tables[j][i] = crc;
...@@ -53,19 +55,17 @@ pub fn Crc32WithPoly(comptime poly: u32) type {...@@ -53,19 +55,17 @@ pub fn Crc32WithPoly(comptime poly: u32) type {
53 crc: u32,55 crc: u32,
5456
55 pub fn init() Self {57 pub fn init() Self {
56 return Self {58 return Self{ .crc = 0xffffffff };
57 .crc = 0xffffffff,
58 };
59 }59 }
6060
61 pub fn update(self: &Self, input: []const u8) void {61 pub fn update(self: &Self, input: []const u8) void {
62 var i: usize = 0;62 var i: usize = 0;
63 while (i + 8 <= input.len) : (i += 8) {63 while (i + 8 <= input.len) : (i += 8) {
64 const p = input[i..i+8];64 const p = input[i..i + 8];
6565
66 // Unrolling this way gives ~50Mb/s increase66 // Unrolling this way gives ~50Mb/s increase
67 self.crc ^= (u32(p[0]) << 0);67 self.crc ^= (u32(p[0]) << 0);
68 self.crc ^= (u32(p[1]) << 8);68 self.crc ^= (u32(p[1]) << 8);
69 self.crc ^= (u32(p[2]) << 16);69 self.crc ^= (u32(p[2]) << 16);
70 self.crc ^= (u32(p[3]) << 24);70 self.crc ^= (u32(p[3]) << 24);
7171
...@@ -76,8 +76,8 @@ pub fn Crc32WithPoly(comptime poly: u32) type {...@@ -76,8 +76,8 @@ pub fn Crc32WithPoly(comptime poly: u32) type {
76 lookup_tables[3][p[4]] ^76 lookup_tables[3][p[4]] ^
77 lookup_tables[4][@truncate(u8, self.crc >> 24)] ^77 lookup_tables[4][@truncate(u8, self.crc >> 24)] ^
78 lookup_tables[5][@truncate(u8, self.crc >> 16)] ^78 lookup_tables[5][@truncate(u8, self.crc >> 16)] ^
79 lookup_tables[6][@truncate(u8, self.crc >> 8)] ^79 lookup_tables[6][@truncate(u8, self.crc >> 8)] ^
80 lookup_tables[7][@truncate(u8, self.crc >> 0)];80 lookup_tables[7][@truncate(u8, self.crc >> 0)];
81 }81 }
8282
83 while (i < input.len) : (i += 1) {83 while (i < input.len) : (i += 1) {
...@@ -123,14 +123,15 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type {...@@ -123,14 +123,15 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type {
123123
124 for (table) |*e, i| {124 for (table) |*e, i| {
125 var crc = u32(i * 16);125 var crc = u32(i * 16);
126 var j: usize = 0; while (j < 8) : (j += 1) {126 var j: usize = 0;
127 while (j < 8) : (j += 1) {
127 if (crc & 1 == 1) {128 if (crc & 1 == 1) {
128 crc = (crc >> 1) ^ poly;129 crc = (crc >> 1) ^ poly;
129 } else {130 } else {
130 crc = (crc >> 1);131 crc = (crc >> 1);
131 }132 }
132 }133 }
133 *e = crc;134 e.* = crc;
134 }135 }
135136
136 break :block table;137 break :block table;
...@@ -139,9 +140,7 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type {...@@ -139,9 +140,7 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type {
139 crc: u32,140 crc: u32,
140141
141 pub fn init() Self {142 pub fn init() Self {
142 return Self {143 return Self{ .crc = 0xffffffff };
143 .crc = 0xffffffff,
144 };
145 }144 }
146145
147 pub fn update(self: &Self, input: []const u8) void {146 pub fn update(self: &Self, input: []const u8) void {
std/hash/fnv.zig+2-4
...@@ -7,7 +7,7 @@...@@ -7,7 +7,7 @@
7const std = @import("../index.zig");7const std = @import("../index.zig");
8const debug = std.debug;8const debug = std.debug;
99
10pub const Fnv1a_32 = Fnv1a(u32, 0x01000193 , 0x811c9dc5);10pub const Fnv1a_32 = Fnv1a(u32, 0x01000193, 0x811c9dc5);
11pub const Fnv1a_64 = Fnv1a(u64, 0x100000001b3, 0xcbf29ce484222325);11pub const Fnv1a_64 = Fnv1a(u64, 0x100000001b3, 0xcbf29ce484222325);
12pub const Fnv1a_128 = Fnv1a(u128, 0x1000000000000000000013b, 0x6c62272e07bb014262b821756295c58d);12pub const Fnv1a_128 = Fnv1a(u128, 0x1000000000000000000013b, 0x6c62272e07bb014262b821756295c58d);
1313
...@@ -18,9 +18,7 @@ fn Fnv1a(comptime T: type, comptime prime: T, comptime offset: T) type {...@@ -18,9 +18,7 @@ fn Fnv1a(comptime T: type, comptime prime: T, comptime offset: T) type {
18 value: T,18 value: T,
1919
20 pub fn init() Self {20 pub fn init() Self {
21 return Self {21 return Self{ .value = offset };
22 .value = offset,
23 };
24 }22 }
2523
26 pub fn update(self: &Self, input: []const u8) void {24 pub fn update(self: &Self, input: []const u8) void {
std/hash/siphash.zig+3-3
...@@ -45,7 +45,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)...@@ -45,7 +45,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
45 const k0 = mem.readInt(key[0..8], u64, Endian.Little);45 const k0 = mem.readInt(key[0..8], u64, Endian.Little);
46 const k1 = mem.readInt(key[8..16], u64, Endian.Little);46 const k1 = mem.readInt(key[8..16], u64, Endian.Little);
4747
48 var d = Self {48 var d = Self{
49 .v0 = k0 ^ 0x736f6d6570736575,49 .v0 = k0 ^ 0x736f6d6570736575,
50 .v1 = k1 ^ 0x646f72616e646f6d,50 .v1 = k1 ^ 0x646f72616e646f6d,
51 .v2 = k0 ^ 0x6c7967656e657261,51 .v2 = k0 ^ 0x6c7967656e657261,
...@@ -162,7 +162,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)...@@ -162,7 +162,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
162const test_key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f";162const test_key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f";
163163
164test "siphash64-2-4 sanity" {164test "siphash64-2-4 sanity" {
165 const vectors = [][]const u8 {165 const vectors = [][]const u8{
166 "\x31\x0e\x0e\xdd\x47\xdb\x6f\x72", // ""166 "\x31\x0e\x0e\xdd\x47\xdb\x6f\x72", // ""
167 "\xfd\x67\xdc\x93\xc5\x39\xf8\x74", // "\x00"167 "\xfd\x67\xdc\x93\xc5\x39\xf8\x74", // "\x00"
168 "\x5a\x4f\xa9\xd9\x09\x80\x6c\x0d", // "\x00\x01" ... etc168 "\x5a\x4f\xa9\xd9\x09\x80\x6c\x0d", // "\x00\x01" ... etc
...@@ -241,7 +241,7 @@ test "siphash64-2-4 sanity" {...@@ -241,7 +241,7 @@ test "siphash64-2-4 sanity" {
241}241}
242242
243test "siphash128-2-4 sanity" {243test "siphash128-2-4 sanity" {
244 const vectors = [][]const u8 {244 const vectors = [][]const u8{
245 "\xa3\x81\x7f\x04\xba\x25\xa8\xe6\x6d\xf6\x72\x14\xc7\x55\x02\x93",245 "\xa3\x81\x7f\x04\xba\x25\xa8\xe6\x6d\xf6\x72\x14\xc7\x55\x02\x93",
246 "\xda\x87\xc1\xd8\x6b\x99\xaf\x44\x34\x76\x59\x11\x9b\x22\xfc\x45",246 "\xda\x87\xc1\xd8\x6b\x99\xaf\x44\x34\x76\x59\x11\x9b\x22\xfc\x45",
247 "\x81\x77\x22\x8d\xa4\xa4\x5d\xc7\xfc\xa3\x8b\xde\xf6\x0a\xff\xe4",247 "\x81\x77\x22\x8d\xa4\xa4\x5d\xc7\xfc\xa3\x8b\xde\xf6\x0a\xff\xe4",
std/hash_map.zig+57-45
...@@ -9,10 +9,7 @@ const builtin = @import("builtin");...@@ -9,10 +9,7 @@ const builtin = @import("builtin");
9const want_modification_safety = builtin.mode != builtin.Mode.ReleaseFast;9const want_modification_safety = builtin.mode != builtin.Mode.ReleaseFast;
10const debug_u32 = if (want_modification_safety) u32 else void;10const debug_u32 = if (want_modification_safety) u32 else void;
1111
12pub fn HashMap(comptime K: type, comptime V: type,12pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K) u32, comptime eql: fn(a: K, b: K) bool) type {
13 comptime hash: fn(key: K)u32,
14 comptime eql: fn(a: K, b: K)bool) type
15{
16 return struct {13 return struct {
17 entries: []Entry,14 entries: []Entry,
18 size: usize,15 size: usize,
...@@ -65,7 +62,7 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -65,7 +62,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
65 };62 };
6663
67 pub fn init(allocator: &Allocator) Self {64 pub fn init(allocator: &Allocator) Self {
68 return Self {65 return Self{
69 .entries = []Entry{},66 .entries = []Entry{},
70 .allocator = allocator,67 .allocator = allocator,
71 .size = 0,68 .size = 0,
...@@ -129,34 +126,36 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -129,34 +126,36 @@ pub fn HashMap(comptime K: type, comptime V: type,
129 if (hm.entries.len == 0) return null;126 if (hm.entries.len == 0) return null;
130 hm.incrementModificationCount();127 hm.incrementModificationCount();
131 const start_index = hm.keyToIndex(key);128 const start_index = hm.keyToIndex(key);
132 {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {129 {
133 const index = (start_index + roll_over) % hm.entries.len;130 var roll_over: usize = 0;
134 var entry = &hm.entries[index];131 while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
135132 const index = (start_index + roll_over) % hm.entries.len;
136 if (!entry.used)133 var entry = &hm.entries[index];
137 return null;134
138135 if (!entry.used) return null;
139 if (!eql(entry.key, key)) continue;136
140137 if (!eql(entry.key, key)) continue;
141 while (roll_over < hm.entries.len) : (roll_over += 1) {138
142 const next_index = (start_index + roll_over + 1) % hm.entries.len;139 while (roll_over < hm.entries.len) : (roll_over += 1) {
143 const next_entry = &hm.entries[next_index];140 const next_index = (start_index + roll_over + 1) % hm.entries.len;
144 if (!next_entry.used or next_entry.distance_from_start_index == 0) {141 const next_entry = &hm.entries[next_index];
145 entry.used = false;142 if (!next_entry.used or next_entry.distance_from_start_index == 0) {
146 hm.size -= 1;143 entry.used = false;
147 return entry;144 hm.size -= 1;
145 return entry;
146 }
147 entry.* = next_entry.*;
148 entry.distance_from_start_index -= 1;
149 entry = next_entry;
148 }150 }
149 *entry = *next_entry;151 unreachable; // shifting everything in the table
150 entry.distance_from_start_index -= 1;
151 entry = next_entry;
152 }152 }
153 unreachable; // shifting everything in the table153 }
154 }}
155 return null;154 return null;
156 }155 }
157156
158 pub fn iterator(hm: &const Self) Iterator {157 pub fn iterator(hm: &const Self) Iterator {
159 return Iterator {158 return Iterator{
160 .hm = hm,159 .hm = hm,
161 .count = 0,160 .count = 0,
162 .index = 0,161 .index = 0,
...@@ -182,21 +181,23 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -182,21 +181,23 @@ pub fn HashMap(comptime K: type, comptime V: type,
182 /// Returns the value that was already there.181 /// Returns the value that was already there.
183 fn internalPut(hm: &Self, orig_key: K, orig_value: &const V) ?V {182 fn internalPut(hm: &Self, orig_key: K, orig_value: &const V) ?V {
184 var key = orig_key;183 var key = orig_key;
185 var value = *orig_value;184 var value = orig_value.*;
186 const start_index = hm.keyToIndex(key);185 const start_index = hm.keyToIndex(key);
187 var roll_over: usize = 0;186 var roll_over: usize = 0;
188 var distance_from_start_index: usize = 0;187 var distance_from_start_index: usize = 0;
189 while (roll_over < hm.entries.len) : ({roll_over += 1; distance_from_start_index += 1;}) {188 while (roll_over < hm.entries.len) : ({
189 roll_over += 1;
190 distance_from_start_index += 1;
191 }) {
190 const index = (start_index + roll_over) % hm.entries.len;192 const index = (start_index + roll_over) % hm.entries.len;
191 const entry = &hm.entries[index];193 const entry = &hm.entries[index];
192194
193 if (entry.used and !eql(entry.key, key)) {195 if (entry.used and !eql(entry.key, key)) {
194 if (entry.distance_from_start_index < distance_from_start_index) {196 if (entry.distance_from_start_index < distance_from_start_index) {
195 // robin hood to the rescue197 // robin hood to the rescue
196 const tmp = *entry;198 const tmp = entry.*;
197 hm.max_distance_from_start_index = math.max(hm.max_distance_from_start_index,199 hm.max_distance_from_start_index = math.max(hm.max_distance_from_start_index, distance_from_start_index);
198 distance_from_start_index);200 entry.* = Entry{
199 *entry = Entry {
200 .used = true,201 .used = true,
201 .distance_from_start_index = distance_from_start_index,202 .distance_from_start_index = distance_from_start_index,
202 .key = key,203 .key = key,
...@@ -219,7 +220,7 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -219,7 +220,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
219 }220 }
220221
221 hm.max_distance_from_start_index = math.max(distance_from_start_index, hm.max_distance_from_start_index);222 hm.max_distance_from_start_index = math.max(distance_from_start_index, hm.max_distance_from_start_index);
222 *entry = Entry {223 entry.* = Entry{
223 .used = true,224 .used = true,
224 .distance_from_start_index = distance_from_start_index,225 .distance_from_start_index = distance_from_start_index,
225 .key = key,226 .key = key,
...@@ -232,13 +233,16 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -232,13 +233,16 @@ pub fn HashMap(comptime K: type, comptime V: type,
232233
233 fn internalGet(hm: &const Self, key: K) ?&Entry {234 fn internalGet(hm: &const Self, key: K) ?&Entry {
234 const start_index = hm.keyToIndex(key);235 const start_index = hm.keyToIndex(key);
235 {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {236 {
236 const index = (start_index + roll_over) % hm.entries.len;237 var roll_over: usize = 0;
237 const entry = &hm.entries[index];238 while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
238239 const index = (start_index + roll_over) % hm.entries.len;
239 if (!entry.used) return null;240 const entry = &hm.entries[index];
240 if (eql(entry.key, key)) return entry;241
241 }}242 if (!entry.used) return null;
243 if (eql(entry.key, key)) return entry;
244 }
245 }
242 return null;246 return null;
243 }247 }
244248
...@@ -282,11 +286,19 @@ test "iterator hash map" {...@@ -282,11 +286,19 @@ test "iterator hash map" {
282 assert((reset_map.put(2, 22) catch unreachable) == null);286 assert((reset_map.put(2, 22) catch unreachable) == null);
283 assert((reset_map.put(3, 33) catch unreachable) == null);287 assert((reset_map.put(3, 33) catch unreachable) == null);
284288
285 var keys = []i32 { 1, 2, 3 };289 var keys = []i32{
286 var values = []i32 { 11, 22, 33 };290 1,
291 2,
292 3,
293 };
294 var values = []i32{
295 11,
296 22,
297 33,
298 };
287299
288 var it = reset_map.iterator();300 var it = reset_map.iterator();
289 var count : usize = 0;301 var count: usize = 0;
290 while (it.next()) |next| {302 while (it.next()) |next| {
291 assert(next.key == keys[count]);303 assert(next.key == keys[count]);
292 assert(next.value == values[count]);304 assert(next.value == values[count]);
...@@ -305,7 +317,7 @@ test "iterator hash map" {...@@ -305,7 +317,7 @@ test "iterator hash map" {
305 }317 }
306318
307 it.reset();319 it.reset();
308 var entry = ?? it.next();320 var entry = ??it.next();
309 assert(entry.key == keys[0]);321 assert(entry.key == keys[0]);
310 assert(entry.value == values[0]);322 assert(entry.value == values[0]);
311}323}
std/heap.zig+44-52
...@@ -10,7 +10,7 @@ const c = std.c;...@@ -10,7 +10,7 @@ const c = std.c;
10const Allocator = mem.Allocator;10const Allocator = mem.Allocator;
1111
12pub const c_allocator = &c_allocator_state;12pub const c_allocator = &c_allocator_state;
13var c_allocator_state = Allocator {13var c_allocator_state = Allocator{
14 .allocFn = cAlloc,14 .allocFn = cAlloc,
15 .reallocFn = cRealloc,15 .reallocFn = cRealloc,
16 .freeFn = cFree,16 .freeFn = cFree,
...@@ -18,10 +18,7 @@ var c_allocator_state = Allocator {...@@ -18,10 +18,7 @@ var c_allocator_state = Allocator {
1818
19fn cAlloc(self: &Allocator, n: usize, alignment: u29) ![]u8 {19fn cAlloc(self: &Allocator, n: usize, alignment: u29) ![]u8 {
20 assert(alignment <= @alignOf(c_longdouble));20 assert(alignment <= @alignOf(c_longdouble));
21 return if (c.malloc(n)) |buf|21 return if (c.malloc(n)) |buf| @ptrCast(&u8, buf)[0..n] else error.OutOfMemory;
22 @ptrCast(&u8, buf)[0..n]
23 else
24 error.OutOfMemory;
25}22}
2623
27fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {24fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
...@@ -48,8 +45,8 @@ pub const DirectAllocator = struct {...@@ -48,8 +45,8 @@ pub const DirectAllocator = struct {
48 const HeapHandle = if (builtin.os == Os.windows) os.windows.HANDLE else void;45 const HeapHandle = if (builtin.os == Os.windows) os.windows.HANDLE else void;
4946
50 pub fn init() DirectAllocator {47 pub fn init() DirectAllocator {
51 return DirectAllocator {48 return DirectAllocator{
52 .allocator = Allocator {49 .allocator = Allocator{
53 .allocFn = alloc,50 .allocFn = alloc,
54 .reallocFn = realloc,51 .reallocFn = realloc,
55 .freeFn = free,52 .freeFn = free,
...@@ -73,37 +70,35 @@ pub const DirectAllocator = struct {...@@ -73,37 +70,35 @@ pub const DirectAllocator = struct {
73 switch (builtin.os) {70 switch (builtin.os) {
74 Os.linux, Os.macosx, Os.ios => {71 Os.linux, Os.macosx, Os.ios => {
75 const p = os.posix;72 const p = os.posix;
76 const alloc_size = if(alignment <= os.page_size) n else n + alignment;73 const alloc_size = if (alignment <= os.page_size) n else n + alignment;
77 const addr = p.mmap(null, alloc_size, p.PROT_READ|p.PROT_WRITE, 74 const addr = p.mmap(null, alloc_size, p.PROT_READ | p.PROT_WRITE, p.MAP_PRIVATE | p.MAP_ANONYMOUS, -1, 0);
78 p.MAP_PRIVATE|p.MAP_ANONYMOUS, -1, 0);75 if (addr == p.MAP_FAILED) return error.OutOfMemory;
79 if(addr == p.MAP_FAILED) return error.OutOfMemory;76
80 77 if (alloc_size == n) return @intToPtr(&u8, addr)[0..n];
81 if(alloc_size == n) return @intToPtr(&u8, addr)[0..n];78
82
83 var aligned_addr = addr & ~usize(alignment - 1);79 var aligned_addr = addr & ~usize(alignment - 1);
84 aligned_addr += alignment;80 aligned_addr += alignment;
85 81
86 //We can unmap the unused portions of our mmap, but we must only82 //We can unmap the unused portions of our mmap, but we must only
87 // pass munmap bytes that exist outside our allocated pages or it83 // pass munmap bytes that exist outside our allocated pages or it
88 // will happily eat us too84 // will happily eat us too
89 85
90 //Since alignment > page_size, we are by definition on a page boundry86 //Since alignment > page_size, we are by definition on a page boundry
91 const unused_start = addr;87 const unused_start = addr;
92 const unused_len = aligned_addr - 1 - unused_start;88 const unused_len = aligned_addr - 1 - unused_start;
9389
94 var err = p.munmap(unused_start, unused_len);90 var err = p.munmap(unused_start, unused_len);
95 debug.assert(p.getErrno(err) == 0);91 debug.assert(p.getErrno(err) == 0);
96 92
97 //It is impossible that there is an unoccupied page at the top of our93 //It is impossible that there is an unoccupied page at the top of our
98 // mmap.94 // mmap.
99 95
100 return @intToPtr(&u8, aligned_addr)[0..n];96 return @intToPtr(&u8, aligned_addr)[0..n];
101 },97 },
102 Os.windows => {98 Os.windows => {
103 const amt = n + alignment + @sizeOf(usize);99 const amt = n + alignment + @sizeOf(usize);
104 const heap_handle = self.heap_handle ?? blk: {100 const heap_handle = self.heap_handle ?? blk: {
105 const hh = os.windows.HeapCreate(os.windows.HEAP_NO_SERIALIZE, amt, 0)101 const hh = os.windows.HeapCreate(os.windows.HEAP_NO_SERIALIZE, amt, 0) ?? return error.OutOfMemory;
106 ?? return error.OutOfMemory;
107 self.heap_handle = hh;102 self.heap_handle = hh;
108 break :blk hh;103 break :blk hh;
109 };104 };
...@@ -113,7 +108,7 @@ pub const DirectAllocator = struct {...@@ -113,7 +108,7 @@ pub const DirectAllocator = struct {
113 const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);108 const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);
114 const adjusted_addr = root_addr + march_forward_bytes;109 const adjusted_addr = root_addr + march_forward_bytes;
115 const record_addr = adjusted_addr + n;110 const record_addr = adjusted_addr + n;
116 *@intToPtr(&align(1) usize, record_addr) = root_addr;111 @intToPtr(&align(1) usize, record_addr).* = root_addr;
117 return @intToPtr(&u8, adjusted_addr)[0..n];112 return @intToPtr(&u8, adjusted_addr)[0..n];
118 },113 },
119 else => @compileError("Unsupported OS"),114 else => @compileError("Unsupported OS"),
...@@ -144,13 +139,13 @@ pub const DirectAllocator = struct {...@@ -144,13 +139,13 @@ pub const DirectAllocator = struct {
144 Os.windows => {139 Os.windows => {
145 const old_adjusted_addr = @ptrToInt(old_mem.ptr);140 const old_adjusted_addr = @ptrToInt(old_mem.ptr);
146 const old_record_addr = old_adjusted_addr + old_mem.len;141 const old_record_addr = old_adjusted_addr + old_mem.len;
147 const root_addr = *@intToPtr(&align(1) usize, old_record_addr);142 const root_addr = @intToPtr(&align(1) usize, old_record_addr).*;
148 const old_ptr = @intToPtr(os.windows.LPVOID, root_addr);143 const old_ptr = @intToPtr(os.windows.LPVOID, root_addr);
149 const amt = new_size + alignment + @sizeOf(usize);144 const amt = new_size + alignment + @sizeOf(usize);
150 const new_ptr = os.windows.HeapReAlloc(??self.heap_handle, 0, old_ptr, amt) ?? blk: {145 const new_ptr = os.windows.HeapReAlloc(??self.heap_handle, 0, old_ptr, amt) ?? blk: {
151 if (new_size > old_mem.len) return error.OutOfMemory;146 if (new_size > old_mem.len) return error.OutOfMemory;
152 const new_record_addr = old_record_addr - new_size + old_mem.len;147 const new_record_addr = old_record_addr - new_size + old_mem.len;
153 *@intToPtr(&align(1) usize, new_record_addr) = root_addr;148 @intToPtr(&align(1) usize, new_record_addr).* = root_addr;
154 return old_mem[0..new_size];149 return old_mem[0..new_size];
155 };150 };
156 const offset = old_adjusted_addr - root_addr;151 const offset = old_adjusted_addr - root_addr;
...@@ -158,7 +153,7 @@ pub const DirectAllocator = struct {...@@ -158,7 +153,7 @@ pub const DirectAllocator = struct {
158 const new_adjusted_addr = new_root_addr + offset;153 const new_adjusted_addr = new_root_addr + offset;
159 assert(new_adjusted_addr % alignment == 0);154 assert(new_adjusted_addr % alignment == 0);
160 const new_record_addr = new_adjusted_addr + new_size;155 const new_record_addr = new_adjusted_addr + new_size;
161 *@intToPtr(&align(1) usize, new_record_addr) = new_root_addr;156 @intToPtr(&align(1) usize, new_record_addr).* = new_root_addr;
162 return @intToPtr(&u8, new_adjusted_addr)[0..new_size];157 return @intToPtr(&u8, new_adjusted_addr)[0..new_size];
163 },158 },
164 else => @compileError("Unsupported OS"),159 else => @compileError("Unsupported OS"),
...@@ -174,7 +169,7 @@ pub const DirectAllocator = struct {...@@ -174,7 +169,7 @@ pub const DirectAllocator = struct {
174 },169 },
175 Os.windows => {170 Os.windows => {
176 const record_addr = @ptrToInt(bytes.ptr) + bytes.len;171 const record_addr = @ptrToInt(bytes.ptr) + bytes.len;
177 const root_addr = *@intToPtr(&align(1) usize, record_addr);172 const root_addr = @intToPtr(&align(1) usize, record_addr).*;
178 const ptr = @intToPtr(os.windows.LPVOID, root_addr);173 const ptr = @intToPtr(os.windows.LPVOID, root_addr);
179 _ = os.windows.HeapFree(??self.heap_handle, 0, ptr);174 _ = os.windows.HeapFree(??self.heap_handle, 0, ptr);
180 },175 },
...@@ -195,8 +190,8 @@ pub const ArenaAllocator = struct {...@@ -195,8 +190,8 @@ pub const ArenaAllocator = struct {
195 const BufNode = std.LinkedList([]u8).Node;190 const BufNode = std.LinkedList([]u8).Node;
196191
197 pub fn init(child_allocator: &Allocator) ArenaAllocator {192 pub fn init(child_allocator: &Allocator) ArenaAllocator {
198 return ArenaAllocator {193 return ArenaAllocator{
199 .allocator = Allocator {194 .allocator = Allocator{
200 .allocFn = alloc,195 .allocFn = alloc,
201 .reallocFn = realloc,196 .reallocFn = realloc,
202 .freeFn = free,197 .freeFn = free,
...@@ -228,7 +223,7 @@ pub const ArenaAllocator = struct {...@@ -228,7 +223,7 @@ pub const ArenaAllocator = struct {
228 const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);223 const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);
229 const buf_node_slice = ([]BufNode)(buf[0..@sizeOf(BufNode)]);224 const buf_node_slice = ([]BufNode)(buf[0..@sizeOf(BufNode)]);
230 const buf_node = &buf_node_slice[0];225 const buf_node = &buf_node_slice[0];
231 *buf_node = BufNode {226 buf_node.* = BufNode{
232 .data = buf,227 .data = buf,
233 .prev = null,228 .prev = null,
234 .next = null,229 .next = null,
...@@ -253,7 +248,7 @@ pub const ArenaAllocator = struct {...@@ -253,7 +248,7 @@ pub const ArenaAllocator = struct {
253 cur_node = try self.createNode(cur_buf.len, n + alignment);248 cur_node = try self.createNode(cur_buf.len, n + alignment);
254 continue;249 continue;
255 }250 }
256 const result = cur_buf[adjusted_index .. new_end_index];251 const result = cur_buf[adjusted_index..new_end_index];
257 self.end_index = new_end_index;252 self.end_index = new_end_index;
258 return result;253 return result;
259 }254 }
...@@ -269,7 +264,7 @@ pub const ArenaAllocator = struct {...@@ -269,7 +264,7 @@ pub const ArenaAllocator = struct {
269 }264 }
270 }265 }
271266
272 fn free(allocator: &Allocator, bytes: []u8) void { }267 fn free(allocator: &Allocator, bytes: []u8) void {}
273};268};
274269
275pub const FixedBufferAllocator = struct {270pub const FixedBufferAllocator = struct {
...@@ -278,8 +273,8 @@ pub const FixedBufferAllocator = struct {...@@ -278,8 +273,8 @@ pub const FixedBufferAllocator = struct {
278 buffer: []u8,273 buffer: []u8,
279274
280 pub fn init(buffer: []u8) FixedBufferAllocator {275 pub fn init(buffer: []u8) FixedBufferAllocator {
281 return FixedBufferAllocator {276 return FixedBufferAllocator{
282 .allocator = Allocator {277 .allocator = Allocator{
283 .allocFn = alloc,278 .allocFn = alloc,
284 .reallocFn = realloc,279 .reallocFn = realloc,
285 .freeFn = free,280 .freeFn = free,
...@@ -299,7 +294,7 @@ pub const FixedBufferAllocator = struct {...@@ -299,7 +294,7 @@ pub const FixedBufferAllocator = struct {
299 if (new_end_index > self.buffer.len) {294 if (new_end_index > self.buffer.len) {
300 return error.OutOfMemory;295 return error.OutOfMemory;
301 }296 }
302 const result = self.buffer[adjusted_index .. new_end_index];297 const result = self.buffer[adjusted_index..new_end_index];
303 self.end_index = new_end_index;298 self.end_index = new_end_index;
304299
305 return result;300 return result;
...@@ -315,7 +310,7 @@ pub const FixedBufferAllocator = struct {...@@ -315,7 +310,7 @@ pub const FixedBufferAllocator = struct {
315 }310 }
316 }311 }
317312
318 fn free(allocator: &Allocator, bytes: []u8) void { }313 fn free(allocator: &Allocator, bytes: []u8) void {}
319};314};
320315
321/// lock free316/// lock free
...@@ -325,8 +320,8 @@ pub const ThreadSafeFixedBufferAllocator = struct {...@@ -325,8 +320,8 @@ pub const ThreadSafeFixedBufferAllocator = struct {
325 buffer: []u8,320 buffer: []u8,
326321
327 pub fn init(buffer: []u8) ThreadSafeFixedBufferAllocator {322 pub fn init(buffer: []u8) ThreadSafeFixedBufferAllocator {
328 return ThreadSafeFixedBufferAllocator {323 return ThreadSafeFixedBufferAllocator{
329 .allocator = Allocator {324 .allocator = Allocator{
330 .allocFn = alloc,325 .allocFn = alloc,
331 .reallocFn = realloc,326 .reallocFn = realloc,
332 .freeFn = free,327 .freeFn = free,
...@@ -348,8 +343,7 @@ pub const ThreadSafeFixedBufferAllocator = struct {...@@ -348,8 +343,7 @@ pub const ThreadSafeFixedBufferAllocator = struct {
348 if (new_end_index > self.buffer.len) {343 if (new_end_index > self.buffer.len) {
349 return error.OutOfMemory;344 return error.OutOfMemory;
350 }345 }
351 end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index,346 end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index, builtin.AtomicOrder.SeqCst, builtin.AtomicOrder.SeqCst) ?? return self.buffer[adjusted_index..new_end_index];
352 builtin.AtomicOrder.SeqCst, builtin.AtomicOrder.SeqCst) ?? return self.buffer[adjusted_index .. new_end_index];
353 }347 }
354 }348 }
355349
...@@ -363,11 +357,9 @@ pub const ThreadSafeFixedBufferAllocator = struct {...@@ -363,11 +357,9 @@ pub const ThreadSafeFixedBufferAllocator = struct {
363 }357 }
364 }358 }
365359
366 fn free(allocator: &Allocator, bytes: []u8) void { }360 fn free(allocator: &Allocator, bytes: []u8) void {}
367};361};
368362
369
370
371test "c_allocator" {363test "c_allocator" {
372 if (builtin.link_libc) {364 if (builtin.link_libc) {
373 var slice = c_allocator.alloc(u8, 50) catch return;365 var slice = c_allocator.alloc(u8, 50) catch return;
...@@ -415,8 +407,8 @@ fn testAllocator(allocator: &mem.Allocator) !void {...@@ -415,8 +407,8 @@ fn testAllocator(allocator: &mem.Allocator) !void {
415 var slice = try allocator.alloc(&i32, 100);407 var slice = try allocator.alloc(&i32, 100);
416408
417 for (slice) |*item, i| {409 for (slice) |*item, i| {
418 *item = try allocator.create(i32);410 item.* = try allocator.create(i32);
419 **item = i32(i);411 item.*.* = i32(i);
420 }412 }
421413
422 for (slice) |item, i| {414 for (slice) |item, i| {
...@@ -432,28 +424,28 @@ fn testAllocator(allocator: &mem.Allocator) !void {...@@ -432,28 +424,28 @@ fn testAllocator(allocator: &mem.Allocator) !void {
432}424}
433425
434fn testAllocatorLargeAlignment(allocator: &mem.Allocator) mem.Allocator.Error!void {426fn testAllocatorLargeAlignment(allocator: &mem.Allocator) mem.Allocator.Error!void {
435 //Maybe a platform's page_size is actually the same as or 427 //Maybe a platform's page_size is actually the same as or
436 // very near usize?428 // very near usize?
437 if(os.page_size << 2 > @maxValue(usize)) return;429 if (os.page_size << 2 > @maxValue(usize)) return;
438 430
439 const USizeShift = @IntType(false, std.math.log2(usize.bit_count));431 const USizeShift = @IntType(false, std.math.log2(usize.bit_count));
440 const large_align = u29(os.page_size << 2);432 const large_align = u29(os.page_size << 2);
441 433
442 var align_mask: usize = undefined;434 var align_mask: usize = undefined;
443 _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(large_align)), &align_mask);435 _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(large_align)), &align_mask);
444 436
445 var slice = try allocator.allocFn(allocator, 500, large_align);437 var slice = try allocator.allocFn(allocator, 500, large_align);
446 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));438 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
447 439
448 slice = try allocator.reallocFn(allocator, slice, 100, large_align);440 slice = try allocator.reallocFn(allocator, slice, 100, large_align);
449 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));441 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
450 442
451 slice = try allocator.reallocFn(allocator, slice, 5000, large_align);443 slice = try allocator.reallocFn(allocator, slice, 5000, large_align);
452 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));444 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
453 445
454 slice = try allocator.reallocFn(allocator, slice, 10, large_align);446 slice = try allocator.reallocFn(allocator, slice, 10, large_align);
455 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));447 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
456 448
457 slice = try allocator.reallocFn(allocator, slice, 20000, large_align);449 slice = try allocator.reallocFn(allocator, slice, 20000, large_align);
458 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));450 debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
459451
std/io.zig+18-47
...@@ -18,32 +18,17 @@ const is_windows = builtin.os == builtin.Os.windows;...@@ -18,32 +18,17 @@ const is_windows = builtin.os == builtin.Os.windows;
18const GetStdIoErrs = os.WindowsGetStdHandleErrs;18const GetStdIoErrs = os.WindowsGetStdHandleErrs;
1919
20pub fn getStdErr() GetStdIoErrs!File {20pub fn getStdErr() GetStdIoErrs!File {
21 const handle = if (is_windows)21 const handle = if (is_windows) try os.windowsGetStdHandle(os.windows.STD_ERROR_HANDLE) else if (is_posix) os.posix.STDERR_FILENO else unreachable;
22 try os.windowsGetStdHandle(os.windows.STD_ERROR_HANDLE)
23 else if (is_posix)
24 os.posix.STDERR_FILENO
25 else
26 unreachable;
27 return File.openHandle(handle);22 return File.openHandle(handle);
28}23}
2924
30pub fn getStdOut() GetStdIoErrs!File {25pub fn getStdOut() GetStdIoErrs!File {
31 const handle = if (is_windows)26 const handle = if (is_windows) try os.windowsGetStdHandle(os.windows.STD_OUTPUT_HANDLE) else if (is_posix) os.posix.STDOUT_FILENO else unreachable;
32 try os.windowsGetStdHandle(os.windows.STD_OUTPUT_HANDLE)
33 else if (is_posix)
34 os.posix.STDOUT_FILENO
35 else
36 unreachable;
37 return File.openHandle(handle);27 return File.openHandle(handle);
38}28}
3929
40pub fn getStdIn() GetStdIoErrs!File {30pub fn getStdIn() GetStdIoErrs!File {
41 const handle = if (is_windows)31 const handle = if (is_windows) try os.windowsGetStdHandle(os.windows.STD_INPUT_HANDLE) else if (is_posix) os.posix.STDIN_FILENO else unreachable;
42 try os.windowsGetStdHandle(os.windows.STD_INPUT_HANDLE)
43 else if (is_posix)
44 os.posix.STDIN_FILENO
45 else
46 unreachable;
47 return File.openHandle(handle);32 return File.openHandle(handle);
48}33}
4934
...@@ -56,11 +41,9 @@ pub const FileInStream = struct {...@@ -56,11 +41,9 @@ pub const FileInStream = struct {
56 pub const Stream = InStream(Error);41 pub const Stream = InStream(Error);
5742
58 pub fn init(file: &File) FileInStream {43 pub fn init(file: &File) FileInStream {
59 return FileInStream {44 return FileInStream{
60 .file = file,45 .file = file,
61 .stream = Stream {46 .stream = Stream{ .readFn = readFn },
62 .readFn = readFn,
63 },
64 };47 };
65 }48 }
6649
...@@ -79,11 +62,9 @@ pub const FileOutStream = struct {...@@ -79,11 +62,9 @@ pub const FileOutStream = struct {
79 pub const Stream = OutStream(Error);62 pub const Stream = OutStream(Error);
8063
81 pub fn init(file: &File) FileOutStream {64 pub fn init(file: &File) FileOutStream {
82 return FileOutStream {65 return FileOutStream{
83 .file = file,66 .file = file,
84 .stream = Stream {67 .stream = Stream{ .writeFn = writeFn },
85 .writeFn = writeFn,
86 },
87 };68 };
88 }69 }
8970
...@@ -121,8 +102,7 @@ pub fn InStream(comptime ReadError: type) type {...@@ -121,8 +102,7 @@ pub fn InStream(comptime ReadError: type) type {
121 }102 }
122103
123 const new_buf_size = math.min(max_size, actual_buf_len + os.page_size);104 const new_buf_size = math.min(max_size, actual_buf_len + os.page_size);
124 if (new_buf_size == actual_buf_len)105 if (new_buf_size == actual_buf_len) return error.StreamTooLong;
125 return error.StreamTooLong;
126 try buffer.resize(new_buf_size);106 try buffer.resize(new_buf_size);
127 }107 }
128 }108 }
...@@ -165,9 +145,7 @@ pub fn InStream(comptime ReadError: type) type {...@@ -165,9 +145,7 @@ pub fn InStream(comptime ReadError: type) type {
165 /// memory would be greater than `max_size`, returns `error.StreamTooLong`.145 /// memory would be greater than `max_size`, returns `error.StreamTooLong`.
166 /// Caller owns returned memory.146 /// Caller owns returned memory.
167 /// If this function returns an error, the contents from the stream read so far are lost.147 /// If this function returns an error, the contents from the stream read so far are lost.
168 pub fn readUntilDelimiterAlloc(self: &Self, allocator: &mem.Allocator,148 pub fn readUntilDelimiterAlloc(self: &Self, allocator: &mem.Allocator, delimiter: u8, max_size: usize) ![]u8 {
169 delimiter: u8, max_size: usize) ![]u8
170 {
171 var buf = Buffer.initNull(allocator);149 var buf = Buffer.initNull(allocator);
172 defer buf.deinit();150 defer buf.deinit();
173151
...@@ -283,7 +261,7 @@ pub fn BufferedInStream(comptime Error: type) type {...@@ -283,7 +261,7 @@ pub fn BufferedInStream(comptime Error: type) type {
283pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type) type {261pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type) type {
284 return struct {262 return struct {
285 const Self = this;263 const Self = this;
286 const Stream = InStream(Error); 264 const Stream = InStream(Error);
287265
288 pub stream: Stream,266 pub stream: Stream,
289267
...@@ -294,7 +272,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)...@@ -294,7 +272,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)
294 end_index: usize,272 end_index: usize,
295273
296 pub fn init(unbuffered_in_stream: &Stream) Self {274 pub fn init(unbuffered_in_stream: &Stream) Self {
297 return Self {275 return Self{
298 .unbuffered_in_stream = unbuffered_in_stream,276 .unbuffered_in_stream = unbuffered_in_stream,
299 .buffer = undefined,277 .buffer = undefined,
300278
...@@ -305,9 +283,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)...@@ -305,9 +283,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)
305 .start_index = buffer_size,283 .start_index = buffer_size,
306 .end_index = buffer_size,284 .end_index = buffer_size,
307285
308 .stream = Stream {286 .stream = Stream{ .readFn = readFn },
309 .readFn = readFn,
310 },
311 };287 };
312 }288 }
313289
...@@ -368,13 +344,11 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamEr...@@ -368,13 +344,11 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamEr
368 index: usize,344 index: usize,
369345
370 pub fn init(unbuffered_out_stream: &Stream) Self {346 pub fn init(unbuffered_out_stream: &Stream) Self {
371 return Self {347 return Self{
372 .unbuffered_out_stream = unbuffered_out_stream,348 .unbuffered_out_stream = unbuffered_out_stream,
373 .buffer = undefined,349 .buffer = undefined,
374 .index = 0,350 .index = 0,
375 .stream = Stream {351 .stream = Stream{ .writeFn = writeFn },
376 .writeFn = writeFn,
377 },
378 };352 };
379 }353 }
380354
...@@ -416,11 +390,9 @@ pub const BufferOutStream = struct {...@@ -416,11 +390,9 @@ pub const BufferOutStream = struct {
416 pub const Stream = OutStream(Error);390 pub const Stream = OutStream(Error);
417391
418 pub fn init(buffer: &Buffer) BufferOutStream {392 pub fn init(buffer: &Buffer) BufferOutStream {
419 return BufferOutStream {393 return BufferOutStream{
420 .buffer = buffer,394 .buffer = buffer,
421 .stream = Stream {395 .stream = Stream{ .writeFn = writeFn },
422 .writeFn = writeFn,
423 },
424 };396 };
425 }397 }
426398
...@@ -430,7 +402,6 @@ pub const BufferOutStream = struct {...@@ -430,7 +402,6 @@ pub const BufferOutStream = struct {
430 }402 }
431};403};
432404
433
434pub const BufferedAtomicFile = struct {405pub const BufferedAtomicFile = struct {
435 atomic_file: os.AtomicFile,406 atomic_file: os.AtomicFile,
436 file_stream: FileOutStream,407 file_stream: FileOutStream,
...@@ -441,7 +412,7 @@ pub const BufferedAtomicFile = struct {...@@ -441,7 +412,7 @@ pub const BufferedAtomicFile = struct {
441 var self = try allocator.create(BufferedAtomicFile);412 var self = try allocator.create(BufferedAtomicFile);
442 errdefer allocator.destroy(self);413 errdefer allocator.destroy(self);
443414
444 *self = BufferedAtomicFile {415 self.* = BufferedAtomicFile{
445 .atomic_file = undefined,416 .atomic_file = undefined,
446 .file_stream = undefined,417 .file_stream = undefined,
447 .buffered_stream = undefined,418 .buffered_stream = undefined,
...@@ -489,7 +460,7 @@ pub fn readLine(buf: []u8) !usize {...@@ -489,7 +460,7 @@ pub fn readLine(buf: []u8) !usize {
489 '\r' => {460 '\r' => {
490 // trash the following \n461 // trash the following \n
491 _ = stream.readByte() catch return error.EndOfFile;462 _ = stream.readByte() catch return error.EndOfFile;
492 return index;463 return index;
493 },464 },
494 '\n' => return index,465 '\n' => return index,
495 else => {466 else => {
std/io_test.zig+1-1
...@@ -42,7 +42,7 @@ test "write a file, read it, then delete it" {...@@ -42,7 +42,7 @@ test "write a file, read it, then delete it" {
4242
43 assert(mem.eql(u8, contents[0.."begin".len], "begin"));43 assert(mem.eql(u8, contents[0.."begin".len], "begin"));
44 assert(mem.eql(u8, contents["begin".len..contents.len - "end".len], data));44 assert(mem.eql(u8, contents["begin".len..contents.len - "end".len], data));
45 assert(mem.eql(u8, contents[contents.len - "end".len ..], "end"));45 assert(mem.eql(u8, contents[contents.len - "end".len..], "end"));
46 }46 }
47 try os.deleteFile(allocator, tmp_file_name);47 try os.deleteFile(allocator, tmp_file_name);
48}48}
std/json.zig+86-87
...@@ -35,7 +35,7 @@ pub const Token = struct {...@@ -35,7 +35,7 @@ pub const Token = struct {
35 };35 };
3636
37 pub fn init(id: Id, count: usize, offset: u1) Token {37 pub fn init(id: Id, count: usize, offset: u1) Token {
38 return Token {38 return Token{
39 .id = id,39 .id = id,
40 .offset = offset,40 .offset = offset,
41 .string_has_escape = false,41 .string_has_escape = false,
...@@ -45,7 +45,7 @@ pub const Token = struct {...@@ -45,7 +45,7 @@ pub const Token = struct {
45 }45 }
4646
47 pub fn initString(count: usize, has_unicode_escape: bool) Token {47 pub fn initString(count: usize, has_unicode_escape: bool) Token {
48 return Token {48 return Token{
49 .id = Id.String,49 .id = Id.String,
50 .offset = 0,50 .offset = 0,
51 .string_has_escape = has_unicode_escape,51 .string_has_escape = has_unicode_escape,
...@@ -55,7 +55,7 @@ pub const Token = struct {...@@ -55,7 +55,7 @@ pub const Token = struct {
55 }55 }
5656
57 pub fn initNumber(count: usize, number_is_integer: bool) Token {57 pub fn initNumber(count: usize, number_is_integer: bool) Token {
58 return Token {58 return Token{
59 .id = Id.Number,59 .id = Id.Number,
60 .offset = 0,60 .offset = 0,
61 .string_has_escape = false,61 .string_has_escape = false,
...@@ -66,7 +66,7 @@ pub const Token = struct {...@@ -66,7 +66,7 @@ pub const Token = struct {
6666
67 // A marker token is a zero-length67 // A marker token is a zero-length
68 pub fn initMarker(id: Id) Token {68 pub fn initMarker(id: Id) Token {
69 return Token {69 return Token{
70 .id = id,70 .id = id,
71 .offset = 0,71 .offset = 0,
72 .string_has_escape = false,72 .string_has_escape = false,
...@@ -77,7 +77,7 @@ pub const Token = struct {...@@ -77,7 +77,7 @@ pub const Token = struct {
7777
78 // Slice into the underlying input string.78 // Slice into the underlying input string.
79 pub fn slice(self: &const Token, input: []const u8, i: usize) []const u8 {79 pub fn slice(self: &const Token, input: []const u8, i: usize) []const u8 {
80 return input[i + self.offset - self.count .. i + self.offset];80 return input[i + self.offset - self.count..i + self.offset];
81 }81 }
82};82};
8383
...@@ -86,7 +86,7 @@ pub const Token = struct {...@@ -86,7 +86,7 @@ pub const Token = struct {
86// parsing state requires ~40-50 bytes of stack space.86// parsing state requires ~40-50 bytes of stack space.
87//87//
88// Conforms strictly to RFC8529.88// Conforms strictly to RFC8529.
89const StreamingJsonParser = struct {89pub const StreamingJsonParser = struct {
90 // Current state90 // Current state
91 state: State,91 state: State,
92 // How many bytes we have counted for the current token92 // How many bytes we have counted for the current token
...@@ -105,8 +105,8 @@ const StreamingJsonParser = struct {...@@ -105,8 +105,8 @@ const StreamingJsonParser = struct {
105 stack: u256,105 stack: u256,
106 stack_used: u8,106 stack_used: u8,
107107
108 const object_bit = 0;108 const object_bit = 0;
109 const array_bit = 1;109 const array_bit = 1;
110 const max_stack_size = @maxValue(u8);110 const max_stack_size = @maxValue(u8);
111111
112 pub fn init() StreamingJsonParser {112 pub fn init() StreamingJsonParser {
...@@ -120,7 +120,7 @@ const StreamingJsonParser = struct {...@@ -120,7 +120,7 @@ const StreamingJsonParser = struct {
120 p.count = 0;120 p.count = 0;
121 // Set before ever read in main transition function121 // Set before ever read in main transition function
122 p.after_string_state = undefined;122 p.after_string_state = undefined;
123 p.after_value_state = State.ValueEnd; // handle end of values normally123 p.after_value_state = State.ValueEnd; // handle end of values normally
124 p.stack = 0;124 p.stack = 0;
125 p.stack_used = 0;125 p.stack_used = 0;
126 p.complete = false;126 p.complete = false;
...@@ -181,7 +181,7 @@ const StreamingJsonParser = struct {...@@ -181,7 +181,7 @@ const StreamingJsonParser = struct {
181 }181 }
182 };182 };
183183
184 pub const Error = error {184 pub const Error = error{
185 InvalidTopLevel,185 InvalidTopLevel,
186 TooManyNestedItems,186 TooManyNestedItems,
187 TooManyClosingItems,187 TooManyClosingItems,
...@@ -206,8 +206,8 @@ const StreamingJsonParser = struct {...@@ -206,8 +206,8 @@ const StreamingJsonParser = struct {
206 //206 //
207 // There is currently no error recovery on a bad stream.207 // There is currently no error recovery on a bad stream.
208 pub fn feed(p: &StreamingJsonParser, c: u8, token1: &?Token, token2: &?Token) Error!void {208 pub fn feed(p: &StreamingJsonParser, c: u8, token1: &?Token, token2: &?Token) Error!void {
209 *token1 = null;209 token1.* = null;
210 *token2 = null;210 token2.* = null;
211 p.count += 1;211 p.count += 1;
212212
213 // unlikely213 // unlikely
...@@ -228,7 +228,7 @@ const StreamingJsonParser = struct {...@@ -228,7 +228,7 @@ const StreamingJsonParser = struct {
228 p.state = State.ValueBegin;228 p.state = State.ValueBegin;
229 p.after_string_state = State.ObjectSeparator;229 p.after_string_state = State.ObjectSeparator;
230230
231 *token = Token.initMarker(Token.Id.ObjectBegin);231 token.* = Token.initMarker(Token.Id.ObjectBegin);
232 },232 },
233 '[' => {233 '[' => {
234 p.stack <<= 1;234 p.stack <<= 1;
...@@ -238,7 +238,7 @@ const StreamingJsonParser = struct {...@@ -238,7 +238,7 @@ const StreamingJsonParser = struct {
238 p.state = State.ValueBegin;238 p.state = State.ValueBegin;
239 p.after_string_state = State.ValueEnd;239 p.after_string_state = State.ValueEnd;
240240
241 *token = Token.initMarker(Token.Id.ArrayBegin);241 token.* = Token.initMarker(Token.Id.ArrayBegin);
242 },242 },
243 '-' => {243 '-' => {
244 p.number_is_integer = true;244 p.number_is_integer = true;
...@@ -252,7 +252,7 @@ const StreamingJsonParser = struct {...@@ -252,7 +252,7 @@ const StreamingJsonParser = struct {
252 p.after_value_state = State.TopLevelEnd;252 p.after_value_state = State.TopLevelEnd;
253 p.count = 0;253 p.count = 0;
254 },254 },
255 '1' ... '9' => {255 '1'...'9' => {
256 p.number_is_integer = true;256 p.number_is_integer = true;
257 p.state = State.NumberMaybeDigitOrDotOrExponent;257 p.state = State.NumberMaybeDigitOrDotOrExponent;
258 p.after_value_state = State.TopLevelEnd;258 p.after_value_state = State.TopLevelEnd;
...@@ -324,7 +324,7 @@ const StreamingJsonParser = struct {...@@ -324,7 +324,7 @@ const StreamingJsonParser = struct {
324 else => {},324 else => {},
325 }325 }
326326
327 *token = Token.initMarker(Token.Id.ObjectEnd);327 token.* = Token.initMarker(Token.Id.ObjectEnd);
328 },328 },
329 ']' => {329 ']' => {
330 if (p.stack & 1 != array_bit) {330 if (p.stack & 1 != array_bit) {
...@@ -348,7 +348,7 @@ const StreamingJsonParser = struct {...@@ -348,7 +348,7 @@ const StreamingJsonParser = struct {
348 else => {},348 else => {},
349 }349 }
350350
351 *token = Token.initMarker(Token.Id.ArrayEnd);351 token.* = Token.initMarker(Token.Id.ArrayEnd);
352 },352 },
353 '{' => {353 '{' => {
354 if (p.stack_used == max_stack_size) {354 if (p.stack_used == max_stack_size) {
...@@ -362,7 +362,7 @@ const StreamingJsonParser = struct {...@@ -362,7 +362,7 @@ const StreamingJsonParser = struct {
362 p.state = State.ValueBegin;362 p.state = State.ValueBegin;
363 p.after_string_state = State.ObjectSeparator;363 p.after_string_state = State.ObjectSeparator;
364364
365 *token = Token.initMarker(Token.Id.ObjectBegin);365 token.* = Token.initMarker(Token.Id.ObjectBegin);
366 },366 },
367 '[' => {367 '[' => {
368 if (p.stack_used == max_stack_size) {368 if (p.stack_used == max_stack_size) {
...@@ -376,7 +376,7 @@ const StreamingJsonParser = struct {...@@ -376,7 +376,7 @@ const StreamingJsonParser = struct {
376 p.state = State.ValueBegin;376 p.state = State.ValueBegin;
377 p.after_string_state = State.ValueEnd;377 p.after_string_state = State.ValueEnd;
378378
379 *token = Token.initMarker(Token.Id.ArrayBegin);379 token.* = Token.initMarker(Token.Id.ArrayBegin);
380 },380 },
381 '-' => {381 '-' => {
382 p.state = State.Number;382 p.state = State.Number;
...@@ -386,7 +386,7 @@ const StreamingJsonParser = struct {...@@ -386,7 +386,7 @@ const StreamingJsonParser = struct {
386 p.state = State.NumberMaybeDotOrExponent;386 p.state = State.NumberMaybeDotOrExponent;
387 p.count = 0;387 p.count = 0;
388 },388 },
389 '1' ... '9' => {389 '1'...'9' => {
390 p.state = State.NumberMaybeDigitOrDotOrExponent;390 p.state = State.NumberMaybeDigitOrDotOrExponent;
391 p.count = 0;391 p.count = 0;
392 },392 },
...@@ -428,7 +428,7 @@ const StreamingJsonParser = struct {...@@ -428,7 +428,7 @@ const StreamingJsonParser = struct {
428 p.state = State.ValueBegin;428 p.state = State.ValueBegin;
429 p.after_string_state = State.ObjectSeparator;429 p.after_string_state = State.ObjectSeparator;
430430
431 *token = Token.initMarker(Token.Id.ObjectBegin);431 token.* = Token.initMarker(Token.Id.ObjectBegin);
432 },432 },
433 '[' => {433 '[' => {
434 if (p.stack_used == max_stack_size) {434 if (p.stack_used == max_stack_size) {
...@@ -442,7 +442,7 @@ const StreamingJsonParser = struct {...@@ -442,7 +442,7 @@ const StreamingJsonParser = struct {
442 p.state = State.ValueBegin;442 p.state = State.ValueBegin;
443 p.after_string_state = State.ValueEnd;443 p.after_string_state = State.ValueEnd;
444444
445 *token = Token.initMarker(Token.Id.ArrayBegin);445 token.* = Token.initMarker(Token.Id.ArrayBegin);
446 },446 },
447 '-' => {447 '-' => {
448 p.state = State.Number;448 p.state = State.Number;
...@@ -452,7 +452,7 @@ const StreamingJsonParser = struct {...@@ -452,7 +452,7 @@ const StreamingJsonParser = struct {
452 p.state = State.NumberMaybeDotOrExponent;452 p.state = State.NumberMaybeDotOrExponent;
453 p.count = 0;453 p.count = 0;
454 },454 },
455 '1' ... '9' => {455 '1'...'9' => {
456 p.state = State.NumberMaybeDigitOrDotOrExponent;456 p.state = State.NumberMaybeDigitOrDotOrExponent;
457 p.count = 0;457 p.count = 0;
458 },458 },
...@@ -501,7 +501,7 @@ const StreamingJsonParser = struct {...@@ -501,7 +501,7 @@ const StreamingJsonParser = struct {
501 p.state = State.TopLevelEnd;501 p.state = State.TopLevelEnd;
502 }502 }
503503
504 *token = Token.initMarker(Token.Id.ArrayEnd);504 token.* = Token.initMarker(Token.Id.ArrayEnd);
505 },505 },
506 '}' => {506 '}' => {
507 if (p.stack_used == 0) {507 if (p.stack_used == 0) {
...@@ -519,7 +519,7 @@ const StreamingJsonParser = struct {...@@ -519,7 +519,7 @@ const StreamingJsonParser = struct {
519 p.state = State.TopLevelEnd;519 p.state = State.TopLevelEnd;
520 }520 }
521521
522 *token = Token.initMarker(Token.Id.ObjectEnd);522 token.* = Token.initMarker(Token.Id.ObjectEnd);
523 },523 },
524 0x09, 0x0A, 0x0D, 0x20 => {524 0x09, 0x0A, 0x0D, 0x20 => {
525 // whitespace525 // whitespace
...@@ -543,7 +543,7 @@ const StreamingJsonParser = struct {...@@ -543,7 +543,7 @@ const StreamingJsonParser = struct {
543 },543 },
544544
545 State.String => switch (c) {545 State.String => switch (c) {
546 0x00 ... 0x1F => {546 0x00...0x1F => {
547 return error.InvalidControlCharacter;547 return error.InvalidControlCharacter;
548 },548 },
549 '"' => {549 '"' => {
...@@ -553,21 +553,21 @@ const StreamingJsonParser = struct {...@@ -553,21 +553,21 @@ const StreamingJsonParser = struct {
553 p.complete = true;553 p.complete = true;
554 }554 }
555555
556 *token = Token.initString(p.count - 1, p.string_has_escape);556 token.* = Token.initString(p.count - 1, p.string_has_escape);
557 },557 },
558 '\\' => {558 '\\' => {
559 p.state = State.StringEscapeCharacter;559 p.state = State.StringEscapeCharacter;
560 },560 },
561 0x20, 0x21, 0x23 ... 0x5B, 0x5D ... 0x7F => {561 0x20, 0x21, 0x23...0x5B, 0x5D...0x7F => {
562 // non-control ascii562 // non-control ascii
563 },563 },
564 0xC0 ... 0xDF => {564 0xC0...0xDF => {
565 p.state = State.StringUtf8Byte1;565 p.state = State.StringUtf8Byte1;
566 },566 },
567 0xE0 ... 0xEF => {567 0xE0...0xEF => {
568 p.state = State.StringUtf8Byte2;568 p.state = State.StringUtf8Byte2;
569 },569 },
570 0xF0 ... 0xFF => {570 0xF0...0xFF => {
571 p.state = State.StringUtf8Byte3;571 p.state = State.StringUtf8Byte3;
572 },572 },
573 else => {573 else => {
...@@ -613,28 +613,28 @@ const StreamingJsonParser = struct {...@@ -613,28 +613,28 @@ const StreamingJsonParser = struct {
613 },613 },
614614
615 State.StringEscapeHexUnicode4 => switch (c) {615 State.StringEscapeHexUnicode4 => switch (c) {
616 '0' ... '9', 'A' ... 'F', 'a' ... 'f' => {616 '0'...'9', 'A'...'F', 'a'...'f' => {
617 p.state = State.StringEscapeHexUnicode3;617 p.state = State.StringEscapeHexUnicode3;
618 },618 },
619 else => return error.InvalidUnicodeHexSymbol,619 else => return error.InvalidUnicodeHexSymbol,
620 },620 },
621621
622 State.StringEscapeHexUnicode3 => switch (c) {622 State.StringEscapeHexUnicode3 => switch (c) {
623 '0' ... '9', 'A' ... 'F', 'a' ... 'f' => {623 '0'...'9', 'A'...'F', 'a'...'f' => {
624 p.state = State.StringEscapeHexUnicode2;624 p.state = State.StringEscapeHexUnicode2;
625 },625 },
626 else => return error.InvalidUnicodeHexSymbol,626 else => return error.InvalidUnicodeHexSymbol,
627 },627 },
628628
629 State.StringEscapeHexUnicode2 => switch (c) {629 State.StringEscapeHexUnicode2 => switch (c) {
630 '0' ... '9', 'A' ... 'F', 'a' ... 'f' => {630 '0'...'9', 'A'...'F', 'a'...'f' => {
631 p.state = State.StringEscapeHexUnicode1;631 p.state = State.StringEscapeHexUnicode1;
632 },632 },
633 else => return error.InvalidUnicodeHexSymbol,633 else => return error.InvalidUnicodeHexSymbol,
634 },634 },
635635
636 State.StringEscapeHexUnicode1 => switch (c) {636 State.StringEscapeHexUnicode1 => switch (c) {
637 '0' ... '9', 'A' ... 'F', 'a' ... 'f' => {637 '0'...'9', 'A'...'F', 'a'...'f' => {
638 p.state = State.String;638 p.state = State.String;
639 },639 },
640 else => return error.InvalidUnicodeHexSymbol,640 else => return error.InvalidUnicodeHexSymbol,
...@@ -646,7 +646,7 @@ const StreamingJsonParser = struct {...@@ -646,7 +646,7 @@ const StreamingJsonParser = struct {
646 '0' => {646 '0' => {
647 p.state = State.NumberMaybeDotOrExponent;647 p.state = State.NumberMaybeDotOrExponent;
648 },648 },
649 '1' ... '9' => {649 '1'...'9' => {
650 p.state = State.NumberMaybeDigitOrDotOrExponent;650 p.state = State.NumberMaybeDigitOrDotOrExponent;
651 },651 },
652 else => {652 else => {
...@@ -668,7 +668,7 @@ const StreamingJsonParser = struct {...@@ -668,7 +668,7 @@ const StreamingJsonParser = struct {
668 },668 },
669 else => {669 else => {
670 p.state = p.after_value_state;670 p.state = p.after_value_state;
671 *token = Token.initNumber(p.count, p.number_is_integer);671 token.* = Token.initNumber(p.count, p.number_is_integer);
672 return true;672 return true;
673 },673 },
674 }674 }
...@@ -685,12 +685,12 @@ const StreamingJsonParser = struct {...@@ -685,12 +685,12 @@ const StreamingJsonParser = struct {
685 p.number_is_integer = false;685 p.number_is_integer = false;
686 p.state = State.NumberExponent;686 p.state = State.NumberExponent;
687 },687 },
688 '0' ... '9' => {688 '0'...'9' => {
689 // another digit689 // another digit
690 },690 },
691 else => {691 else => {
692 p.state = p.after_value_state;692 p.state = p.after_value_state;
693 *token = Token.initNumber(p.count, p.number_is_integer);693 token.* = Token.initNumber(p.count, p.number_is_integer);
694 return true;694 return true;
695 },695 },
696 }696 }
...@@ -699,7 +699,7 @@ const StreamingJsonParser = struct {...@@ -699,7 +699,7 @@ const StreamingJsonParser = struct {
699 State.NumberFractionalRequired => {699 State.NumberFractionalRequired => {
700 p.complete = p.after_value_state == State.TopLevelEnd;700 p.complete = p.after_value_state == State.TopLevelEnd;
701 switch (c) {701 switch (c) {
702 '0' ... '9' => {702 '0'...'9' => {
703 p.state = State.NumberFractional;703 p.state = State.NumberFractional;
704 },704 },
705 else => {705 else => {
...@@ -711,7 +711,7 @@ const StreamingJsonParser = struct {...@@ -711,7 +711,7 @@ const StreamingJsonParser = struct {
711 State.NumberFractional => {711 State.NumberFractional => {
712 p.complete = p.after_value_state == State.TopLevelEnd;712 p.complete = p.after_value_state == State.TopLevelEnd;
713 switch (c) {713 switch (c) {
714 '0' ... '9' => {714 '0'...'9' => {
715 // another digit715 // another digit
716 },716 },
717 'e', 'E' => {717 'e', 'E' => {
...@@ -720,7 +720,7 @@ const StreamingJsonParser = struct {...@@ -720,7 +720,7 @@ const StreamingJsonParser = struct {
720 },720 },
721 else => {721 else => {
722 p.state = p.after_value_state;722 p.state = p.after_value_state;
723 *token = Token.initNumber(p.count, p.number_is_integer);723 token.* = Token.initNumber(p.count, p.number_is_integer);
724 return true;724 return true;
725 },725 },
726 }726 }
...@@ -735,18 +735,18 @@ const StreamingJsonParser = struct {...@@ -735,18 +735,18 @@ const StreamingJsonParser = struct {
735 },735 },
736 else => {736 else => {
737 p.state = p.after_value_state;737 p.state = p.after_value_state;
738 *token = Token.initNumber(p.count, p.number_is_integer);738 token.* = Token.initNumber(p.count, p.number_is_integer);
739 return true;739 return true;
740 },740 },
741 }741 }
742 },742 },
743743
744 State.NumberExponent => switch (c) {744 State.NumberExponent => switch (c) {
745 '-', '+', => {745 '-', '+' => {
746 p.complete = false;746 p.complete = false;
747 p.state = State.NumberExponentDigitsRequired;747 p.state = State.NumberExponentDigitsRequired;
748 },748 },
749 '0' ... '9' => {749 '0'...'9' => {
750 p.complete = p.after_value_state == State.TopLevelEnd;750 p.complete = p.after_value_state == State.TopLevelEnd;
751 p.state = State.NumberExponentDigits;751 p.state = State.NumberExponentDigits;
752 },752 },
...@@ -756,7 +756,7 @@ const StreamingJsonParser = struct {...@@ -756,7 +756,7 @@ const StreamingJsonParser = struct {
756 },756 },
757757
758 State.NumberExponentDigitsRequired => switch (c) {758 State.NumberExponentDigitsRequired => switch (c) {
759 '0' ... '9' => {759 '0'...'9' => {
760 p.complete = p.after_value_state == State.TopLevelEnd;760 p.complete = p.after_value_state == State.TopLevelEnd;
761 p.state = State.NumberExponentDigits;761 p.state = State.NumberExponentDigits;
762 },762 },
...@@ -768,12 +768,12 @@ const StreamingJsonParser = struct {...@@ -768,12 +768,12 @@ const StreamingJsonParser = struct {
768 State.NumberExponentDigits => {768 State.NumberExponentDigits => {
769 p.complete = p.after_value_state == State.TopLevelEnd;769 p.complete = p.after_value_state == State.TopLevelEnd;
770 switch (c) {770 switch (c) {
771 '0' ... '9' => {771 '0'...'9' => {
772 // another digit772 // another digit
773 },773 },
774 else => {774 else => {
775 p.state = p.after_value_state;775 p.state = p.after_value_state;
776 *token = Token.initNumber(p.count, p.number_is_integer);776 token.* = Token.initNumber(p.count, p.number_is_integer);
777 return true;777 return true;
778 },778 },
779 }779 }
...@@ -793,7 +793,7 @@ const StreamingJsonParser = struct {...@@ -793,7 +793,7 @@ const StreamingJsonParser = struct {
793 'e' => {793 'e' => {
794 p.state = p.after_value_state;794 p.state = p.after_value_state;
795 p.complete = p.state == State.TopLevelEnd;795 p.complete = p.state == State.TopLevelEnd;
796 *token = Token.init(Token.Id.True, p.count + 1, 1);796 token.* = Token.init(Token.Id.True, p.count + 1, 1);
797 },797 },
798 else => {798 else => {
799 return error.InvalidLiteral;799 return error.InvalidLiteral;
...@@ -819,7 +819,7 @@ const StreamingJsonParser = struct {...@@ -819,7 +819,7 @@ const StreamingJsonParser = struct {
819 'e' => {819 'e' => {
820 p.state = p.after_value_state;820 p.state = p.after_value_state;
821 p.complete = p.state == State.TopLevelEnd;821 p.complete = p.state == State.TopLevelEnd;
822 *token = Token.init(Token.Id.False, p.count + 1, 1);822 token.* = Token.init(Token.Id.False, p.count + 1, 1);
823 },823 },
824 else => {824 else => {
825 return error.InvalidLiteral;825 return error.InvalidLiteral;
...@@ -840,7 +840,7 @@ const StreamingJsonParser = struct {...@@ -840,7 +840,7 @@ const StreamingJsonParser = struct {
840 'l' => {840 'l' => {
841 p.state = p.after_value_state;841 p.state = p.after_value_state;
842 p.complete = p.state == State.TopLevelEnd;842 p.complete = p.state == State.TopLevelEnd;
843 *token = Token.init(Token.Id.Null, p.count + 1, 1);843 token.* = Token.init(Token.Id.Null, p.count + 1, 1);
844 },844 },
845 else => {845 else => {
846 return error.InvalidLiteral;846 return error.InvalidLiteral;
...@@ -895,7 +895,7 @@ pub const Value = union(enum) {...@@ -895,7 +895,7 @@ pub const Value = union(enum) {
895 Object: ObjectMap,895 Object: ObjectMap,
896896
897 pub fn dump(self: &const Value) void {897 pub fn dump(self: &const Value) void {
898 switch (*self) {898 switch (self.*) {
899 Value.Null => {899 Value.Null => {
900 std.debug.warn("null");900 std.debug.warn("null");
901 },901 },
...@@ -950,7 +950,7 @@ pub const Value = union(enum) {...@@ -950,7 +950,7 @@ pub const Value = union(enum) {
950 }950 }
951951
952 fn dumpIndentLevel(self: &const Value, indent: usize, level: usize) void {952 fn dumpIndentLevel(self: &const Value, indent: usize, level: usize) void {
953 switch (*self) {953 switch (self.*) {
954 Value.Null => {954 Value.Null => {
955 std.debug.warn("null");955 std.debug.warn("null");
956 },956 },
...@@ -1012,7 +1012,7 @@ pub const Value = union(enum) {...@@ -1012,7 +1012,7 @@ pub const Value = union(enum) {
1012};1012};
10131013
1014// A non-stream JSON parser which constructs a tree of Value's.1014// A non-stream JSON parser which constructs a tree of Value's.
1015const JsonParser = struct {1015pub const JsonParser = struct {
1016 allocator: &Allocator,1016 allocator: &Allocator,
1017 state: State,1017 state: State,
1018 copy_strings: bool,1018 copy_strings: bool,
...@@ -1027,7 +1027,7 @@ const JsonParser = struct {...@@ -1027,7 +1027,7 @@ const JsonParser = struct {
1027 };1027 };
10281028
1029 pub fn init(allocator: &Allocator, copy_strings: bool) JsonParser {1029 pub fn init(allocator: &Allocator, copy_strings: bool) JsonParser {
1030 return JsonParser {1030 return JsonParser{
1031 .allocator = allocator,1031 .allocator = allocator,
1032 .state = State.Simple,1032 .state = State.Simple,
1033 .copy_strings = copy_strings,1033 .copy_strings = copy_strings,
...@@ -1082,7 +1082,7 @@ const JsonParser = struct {...@@ -1082,7 +1082,7 @@ const JsonParser = struct {
10821082
1083 std.debug.assert(p.stack.len == 1);1083 std.debug.assert(p.stack.len == 1);
10841084
1085 return ValueTree {1085 return ValueTree{
1086 .arena = arena,1086 .arena = arena,
1087 .root = p.stack.at(0),1087 .root = p.stack.at(0),
1088 };1088 };
...@@ -1115,11 +1115,11 @@ const JsonParser = struct {...@@ -1115,11 +1115,11 @@ const JsonParser = struct {
11151115
1116 switch (token.id) {1116 switch (token.id) {
1117 Token.Id.ObjectBegin => {1117 Token.Id.ObjectBegin => {
1118 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });1118 try p.stack.append(Value{ .Object = ObjectMap.init(allocator) });
1119 p.state = State.ObjectKey;1119 p.state = State.ObjectKey;
1120 },1120 },
1121 Token.Id.ArrayBegin => {1121 Token.Id.ArrayBegin => {
1122 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });1122 try p.stack.append(Value{ .Array = ArrayList(Value).init(allocator) });
1123 p.state = State.ArrayValue;1123 p.state = State.ArrayValue;
1124 },1124 },
1125 Token.Id.String => {1125 Token.Id.String => {
...@@ -1133,12 +1133,12 @@ const JsonParser = struct {...@@ -1133,12 +1133,12 @@ const JsonParser = struct {
1133 p.state = State.ObjectKey;1133 p.state = State.ObjectKey;
1134 },1134 },
1135 Token.Id.True => {1135 Token.Id.True => {
1136 _ = try object.put(key, Value { .Bool = true });1136 _ = try object.put(key, Value{ .Bool = true });
1137 _ = p.stack.pop();1137 _ = p.stack.pop();
1138 p.state = State.ObjectKey;1138 p.state = State.ObjectKey;
1139 },1139 },
1140 Token.Id.False => {1140 Token.Id.False => {
1141 _ = try object.put(key, Value { .Bool = false });1141 _ = try object.put(key, Value{ .Bool = false });
1142 _ = p.stack.pop();1142 _ = p.stack.pop();
1143 p.state = State.ObjectKey;1143 p.state = State.ObjectKey;
1144 },1144 },
...@@ -1165,11 +1165,11 @@ const JsonParser = struct {...@@ -1165,11 +1165,11 @@ const JsonParser = struct {
1165 try p.pushToParent(value);1165 try p.pushToParent(value);
1166 },1166 },
1167 Token.Id.ObjectBegin => {1167 Token.Id.ObjectBegin => {
1168 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });1168 try p.stack.append(Value{ .Object = ObjectMap.init(allocator) });
1169 p.state = State.ObjectKey;1169 p.state = State.ObjectKey;
1170 },1170 },
1171 Token.Id.ArrayBegin => {1171 Token.Id.ArrayBegin => {
1172 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });1172 try p.stack.append(Value{ .Array = ArrayList(Value).init(allocator) });
1173 p.state = State.ArrayValue;1173 p.state = State.ArrayValue;
1174 },1174 },
1175 Token.Id.String => {1175 Token.Id.String => {
...@@ -1179,10 +1179,10 @@ const JsonParser = struct {...@@ -1179,10 +1179,10 @@ const JsonParser = struct {
1179 try array.append(try p.parseNumber(token, input, i));1179 try array.append(try p.parseNumber(token, input, i));
1180 },1180 },
1181 Token.Id.True => {1181 Token.Id.True => {
1182 try array.append(Value { .Bool = true });1182 try array.append(Value{ .Bool = true });
1183 },1183 },
1184 Token.Id.False => {1184 Token.Id.False => {
1185 try array.append(Value { .Bool = false });1185 try array.append(Value{ .Bool = false });
1186 },1186 },
1187 Token.Id.Null => {1187 Token.Id.Null => {
1188 try array.append(Value.Null);1188 try array.append(Value.Null);
...@@ -1194,11 +1194,11 @@ const JsonParser = struct {...@@ -1194,11 +1194,11 @@ const JsonParser = struct {
1194 },1194 },
1195 State.Simple => switch (token.id) {1195 State.Simple => switch (token.id) {
1196 Token.Id.ObjectBegin => {1196 Token.Id.ObjectBegin => {
1197 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });1197 try p.stack.append(Value{ .Object = ObjectMap.init(allocator) });
1198 p.state = State.ObjectKey;1198 p.state = State.ObjectKey;
1199 },1199 },
1200 Token.Id.ArrayBegin => {1200 Token.Id.ArrayBegin => {
1201 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });1201 try p.stack.append(Value{ .Array = ArrayList(Value).init(allocator) });
1202 p.state = State.ArrayValue;1202 p.state = State.ArrayValue;
1203 },1203 },
1204 Token.Id.String => {1204 Token.Id.String => {
...@@ -1208,10 +1208,10 @@ const JsonParser = struct {...@@ -1208,10 +1208,10 @@ const JsonParser = struct {
1208 try p.stack.append(try p.parseNumber(token, input, i));1208 try p.stack.append(try p.parseNumber(token, input, i));
1209 },1209 },
1210 Token.Id.True => {1210 Token.Id.True => {
1211 try p.stack.append(Value { .Bool = true });1211 try p.stack.append(Value{ .Bool = true });
1212 },1212 },
1213 Token.Id.False => {1213 Token.Id.False => {
1214 try p.stack.append(Value { .Bool = false });1214 try p.stack.append(Value{ .Bool = false });
1215 },1215 },
1216 Token.Id.Null => {1216 Token.Id.Null => {
1217 try p.stack.append(Value.Null);1217 try p.stack.append(Value.Null);
...@@ -1248,15 +1248,14 @@ const JsonParser = struct {...@@ -1248,15 +1248,14 @@ const JsonParser = struct {
1248 // TODO: We don't strictly have to copy values which do not contain any escape1248 // TODO: We don't strictly have to copy values which do not contain any escape
1249 // characters if flagged with the option.1249 // characters if flagged with the option.
1250 const slice = token.slice(input, i);1250 const slice = token.slice(input, i);
1251 return Value { .String = try mem.dupe(p.allocator, u8, slice) };1251 return Value{ .String = try mem.dupe(p.allocator, u8, slice) };
1252 }1252 }
12531253
1254 fn parseNumber(p: &JsonParser, token: &const Token, input: []const u8, i: usize) !Value {1254 fn parseNumber(p: &JsonParser, token: &const Token, input: []const u8, i: usize) !Value {
1255 return if (token.number_is_integer)1255 return if (token.number_is_integer)
1256 Value { .Integer = try std.fmt.parseInt(i64, token.slice(input, i), 10) }1256 Value{ .Integer = try std.fmt.parseInt(i64, token.slice(input, i), 10) }
1257 else1257 else
1258 @panic("TODO: fmt.parseFloat not yet implemented")1258 @panic("TODO: fmt.parseFloat not yet implemented");
1259 ;
1260 }1259 }
1261};1260};
12621261
...@@ -1267,21 +1266,21 @@ test "json parser dynamic" {...@@ -1267,21 +1266,21 @@ test "json parser dynamic" {
1267 defer p.deinit();1266 defer p.deinit();
12681267
1269 const s =1268 const s =
1270 \\{1269 \\{
1271 \\ "Image": {1270 \\ "Image": {
1272 \\ "Width": 800,1271 \\ "Width": 800,
1273 \\ "Height": 600,1272 \\ "Height": 600,
1274 \\ "Title": "View from 15th Floor",1273 \\ "Title": "View from 15th Floor",
1275 \\ "Thumbnail": {1274 \\ "Thumbnail": {
1276 \\ "Url": "http://www.example.com/image/481989943",1275 \\ "Url": "http://www.example.com/image/481989943",
1277 \\ "Height": 125,1276 \\ "Height": 125,
1278 \\ "Width": 1001277 \\ "Width": 100
1279 \\ },1278 \\ },
1280 \\ "Animated" : false,1279 \\ "Animated" : false,
1281 \\ "IDs": [116, 943, 234, 38793]1280 \\ "IDs": [116, 943, 234, 38793]
1282 \\ }1281 \\ }
1283 \\}1282 \\}
1284 ;1283 ;
12851284
1286 var tree = try p.parse(s);1285 var tree = try p.parse(s);
1287 defer tree.deinit();1286 defer tree.deinit();
std/json_test.zig+24-72
...@@ -81,9 +81,7 @@ test "y_array_with_several_null" {...@@ -81,9 +81,7 @@ test "y_array_with_several_null" {
81}81}
8282
83test "y_array_with_trailing_space" {83test "y_array_with_trailing_space" {
84 ok(84 ok("[2] ");
85 "[2] "
86 );
87}85}
8886
89test "y_number_0e+1" {87test "y_number_0e+1" {
...@@ -431,15 +429,11 @@ test "y_string_two-byte-utf-8" {...@@ -431,15 +429,11 @@ test "y_string_two-byte-utf-8" {
431}429}
432430
433test "y_string_u+2028_line_sep" {431test "y_string_u+2028_line_sep" {
434 ok(432 ok("[\"\xe2\x80\xa8\"]");
435 \\["
"]
436 );
437}433}
438434
439test "y_string_u+2029_par_sep" {435test "y_string_u+2029_par_sep" {
440 ok(436 ok("[\"\xe2\x80\xa9\"]");
441 \\["
"]
442 );
443}437}
444438
445test "y_string_uescaped_newline" {439test "y_string_uescaped_newline" {
...@@ -455,9 +449,7 @@ test "y_string_uEscape" {...@@ -455,9 +449,7 @@ test "y_string_uEscape" {
455}449}
456450
457test "y_string_unescaped_char_delete" {451test "y_string_unescaped_char_delete" {
458 ok(452 ok("[\"\x7f\"]");
459 \\[""]
460 );
461}453}
462454
463test "y_string_unicode_2" {455test "y_string_unicode_2" {
...@@ -527,9 +519,7 @@ test "y_string_utf8" {...@@ -527,9 +519,7 @@ test "y_string_utf8" {
527}519}
528520
529test "y_string_with_del_character" {521test "y_string_with_del_character" {
530 ok(522 ok("[\"a\x7fa\"]");
531 \\["aa"]
532 );
533}523}
534524
535test "y_structure_lonely_false" {525test "y_structure_lonely_false" {
...@@ -587,9 +577,7 @@ test "y_structure_true_in_array" {...@@ -587,9 +577,7 @@ test "y_structure_true_in_array" {
587}577}
588578
589test "y_structure_whitespace_array" {579test "y_structure_whitespace_array" {
590 ok(580 ok(" [] ");
591 " [] "
592 );
593}581}
594582
595////////////////////////////////////////////////////////////////////////////////////////////////////583////////////////////////////////////////////////////////////////////////////////////////////////////
...@@ -704,7 +692,6 @@ test "n_array_newlines_unclosed" {...@@ -704,7 +692,6 @@ test "n_array_newlines_unclosed" {
704 );692 );
705}693}
706694
707
708test "n_array_number_and_comma" {695test "n_array_number_and_comma" {
709 err(696 err(
710 \\[1,]697 \\[1,]
...@@ -718,9 +705,7 @@ test "n_array_number_and_several_commas" {...@@ -718,9 +705,7 @@ test "n_array_number_and_several_commas" {
718}705}
719706
720test "n_array_spaces_vertical_tab_formfeed" {707test "n_array_spaces_vertical_tab_formfeed" {
721 err(708 err("[\"\x0aa\"\\f]");
722 \\[" a"\f]
723 );
724}709}
725710
726test "n_array_star_inside" {711test "n_array_star_inside" {
...@@ -774,9 +759,7 @@ test "n_incomplete_true" {...@@ -774,9 +759,7 @@ test "n_incomplete_true" {
774}759}
775760
776test "n_multidigit_number_then_00" {761test "n_multidigit_number_then_00" {
777 err(762 err("123\x00");
778 \\123
779 );
780}763}
781764
782test "n_number_0.1.2" {765test "n_number_0.1.2" {
...@@ -983,7 +966,6 @@ test "n_number_invalid-utf-8-in-int" {...@@ -983,7 +966,6 @@ test "n_number_invalid-utf-8-in-int" {
983 );966 );
984}967}
985968
986
987test "n_number_++" {969test "n_number_++" {
988 err(970 err(
989 \\[++1234]971 \\[++1234]
...@@ -1240,7 +1222,7 @@ test "n_object_unterminated-value" {...@@ -1240,7 +1222,7 @@ test "n_object_unterminated-value" {
1240 err(1222 err(
1241 \\{"a":"a1223 \\{"a":"a
1242 );1224 );
1243 }1225}
12441226
1245test "n_object_with_single_string" {1227test "n_object_with_single_string" {
1246 err(1228 err(
...@@ -1255,9 +1237,7 @@ test "n_object_with_trailing_garbage" {...@@ -1255,9 +1237,7 @@ test "n_object_with_trailing_garbage" {
1255}1237}
12561238
1257test "n_single_space" {1239test "n_single_space" {
1258 err(1240 err(" ");
1259 " "
1260 );
1261}1241}
12621242
1263test "n_string_1_surrogate_then_escape" {1243test "n_string_1_surrogate_then_escape" {
...@@ -1291,9 +1271,7 @@ test "n_string_accentuated_char_no_quotes" {...@@ -1291,9 +1271,7 @@ test "n_string_accentuated_char_no_quotes" {
1291}1271}
12921272
1293test "n_string_backslash_00" {1273test "n_string_backslash_00" {
1294 err(1274 err("[\"\x00\"]");
1295 \\["\"]
1296 );
1297}1275}
12981276
1299test "n_string_escaped_backslash_bad" {1277test "n_string_escaped_backslash_bad" {
...@@ -1303,15 +1281,11 @@ test "n_string_escaped_backslash_bad" {...@@ -1303,15 +1281,11 @@ test "n_string_escaped_backslash_bad" {
1303}1281}
13041282
1305test "n_string_escaped_ctrl_char_tab" {1283test "n_string_escaped_ctrl_char_tab" {
1306 err(1284 err("\x5b\x22\x5c\x09\x22\x5d");
1307 \\["\ "]
1308 );
1309}1285}
13101286
1311test "n_string_escaped_emoji" {1287test "n_string_escaped_emoji" {
1312 err(1288 err("[\"\x5c\xc3\xb0\xc2\x9f\xc2\x8c\xc2\x80\"]");
1313 \\["\🌀"]
1314 );
1315}1289}
13161290
1317test "n_string_escape_x" {1291test "n_string_escape_x" {
...@@ -1357,9 +1331,7 @@ test "n_string_invalid_unicode_escape" {...@@ -1357,9 +1331,7 @@ test "n_string_invalid_unicode_escape" {
1357}1331}
13581332
1359test "n_string_invalid_utf8_after_escape" {1333test "n_string_invalid_utf8_after_escape" {
1360 err(1334 err("[\"\\\x75\xc3\xa5\"]");
1361 \\["\å"]
1362 );
1363}1335}
13641336
1365test "n_string_invalid-utf-8-in-escape" {1337test "n_string_invalid-utf-8-in-escape" {
...@@ -1405,9 +1377,7 @@ test "n_string_start_escape_unclosed" {...@@ -1405,9 +1377,7 @@ test "n_string_start_escape_unclosed" {
1405}1377}
14061378
1407test "n_string_unescaped_crtl_char" {1379test "n_string_unescaped_crtl_char" {
1408 err(1380 err("[\"a\x00a\"]");
1409 \\["aa"]
1410 );
1411}1381}
14121382
1413test "n_string_unescaped_newline" {1383test "n_string_unescaped_newline" {
...@@ -1418,9 +1388,7 @@ test "n_string_unescaped_newline" {...@@ -1418,9 +1388,7 @@ test "n_string_unescaped_newline" {
1418}1388}
14191389
1420test "n_string_unescaped_tab" {1390test "n_string_unescaped_tab" {
1421 err(1391 err("[\"\t\"]");
1422 \\[" "]
1423 );
1424}1392}
14251393
1426test "n_string_unicode_CapitalU" {1394test "n_string_unicode_CapitalU" {
...@@ -1436,9 +1404,7 @@ test "n_string_with_trailing_garbage" {...@@ -1436,9 +1404,7 @@ test "n_string_with_trailing_garbage" {
1436}1404}
14371405
1438test "n_structure_100000_opening_arrays" {1406test "n_structure_100000_opening_arrays" {
1439 err(1407 err("[" ** 100000);
1440 "[" ** 100000
1441 );
1442}1408}
14431409
1444test "n_structure_angle_bracket_." {1410test "n_structure_angle_bracket_." {
...@@ -1532,9 +1498,7 @@ test "n_structure_no_data" {...@@ -1532,9 +1498,7 @@ test "n_structure_no_data" {
1532}1498}
15331499
1534test "n_structure_null-byte-outside-string" {1500test "n_structure_null-byte-outside-string" {
1535 err(1501 err("[\x00]");
1536 \\[]
1537 );
1538}1502}
15391503
1540test "n_structure_number_with_trailing_garbage" {1504test "n_structure_number_with_trailing_garbage" {
...@@ -1580,9 +1544,7 @@ test "n_structure_open_array_comma" {...@@ -1580,9 +1544,7 @@ test "n_structure_open_array_comma" {
1580}1544}
15811545
1582test "n_structure_open_array_object" {1546test "n_structure_open_array_object" {
1583 err(1547 err("[{\"\":" ** 50000);
1584 "[{\"\":" ** 50000
1585 );
1586}1548}
15871549
1588test "n_structure_open_array_open_object" {1550test "n_structure_open_array_open_object" {
...@@ -1718,9 +1680,7 @@ test "n_structure_UTF8_BOM_no_data" {...@@ -1718,9 +1680,7 @@ test "n_structure_UTF8_BOM_no_data" {
1718}1680}
17191681
1720test "n_structure_whitespace_formfeed" {1682test "n_structure_whitespace_formfeed" {
1721 err(1683 err("[\x0c]");
1722 \\[ ]
1723 );
1724}1684}
17251685
1726test "n_structure_whitespace_U+2060_word_joiner" {1686test "n_structure_whitespace_U+2060_word_joiner" {
...@@ -1900,21 +1860,15 @@ test "i_string_truncated-utf-8" {...@@ -1900,21 +1860,15 @@ test "i_string_truncated-utf-8" {
1900}1860}
19011861
1902test "i_string_utf16BE_no_BOM" {1862test "i_string_utf16BE_no_BOM" {
1903 any(1863 any("\x00\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d");
1904 \\["é"]
1905 );
1906}1864}
19071865
1908test "i_string_utf16LE_no_BOM" {1866test "i_string_utf16LE_no_BOM" {
1909 any(1867 any("\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d\x00");
1910 \\["é"]
1911 );
1912}1868}
19131869
1914test "i_string_UTF-16LE_with_BOM" {1870test "i_string_UTF-16LE_with_BOM" {
1915 any(1871 any("\xc3\xbf\xc3\xbe\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d\x00");
1916 \\ÿþ["é"]
1917 );
1918}1872}
19191873
1920test "i_string_UTF-8_invalid_sequence" {1874test "i_string_UTF-8_invalid_sequence" {
...@@ -1930,9 +1884,7 @@ test "i_string_UTF8_surrogate_U+D800" {...@@ -1930,9 +1884,7 @@ test "i_string_UTF8_surrogate_U+D800" {
1930}1884}
19311885
1932test "i_structure_500_nested_arrays" {1886test "i_structure_500_nested_arrays" {
1933 any(1887 any(("[" ** 500) ++ ("]" ** 500));
1934 ("[" ** 500) ++ ("]" ** 500)
1935 );
1936}1888}
19371889
1938test "i_structure_UTF-8_BOM_empty_object" {1890test "i_structure_UTF-8_BOM_empty_object" {
std/linked_list.zig+55-40
...@@ -26,10 +26,10 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -26,10 +26,10 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
26 data: T,26 data: T,
2727
28 pub fn init(value: &const T) Node {28 pub fn init(value: &const T) Node {
29 return Node {29 return Node{
30 .prev = null,30 .prev = null,
31 .next = null,31 .next = null,
32 .data = *value,32 .data = value.*,
33 };33 };
34 }34 }
3535
...@@ -45,18 +45,18 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -45,18 +45,18 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
45 };45 };
4646
47 first: ?&Node,47 first: ?&Node,
48 last: ?&Node,48 last: ?&Node,
49 len: usize,49 len: usize,
5050
51 /// Initialize a linked list.51 /// Initialize a linked list.
52 ///52 ///
53 /// Returns:53 /// Returns:
54 /// An empty linked list.54 /// An empty linked list.
55 pub fn init() Self {55 pub fn init() Self {
56 return Self {56 return Self{
57 .first = null,57 .first = null,
58 .last = null,58 .last = null,
59 .len = 0,59 .len = 0,
60 };60 };
61 }61 }
6262
...@@ -131,7 +131,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -131,7 +131,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
131 } else {131 } else {
132 // Empty list.132 // Empty list.
133 list.first = new_node;133 list.first = new_node;
134 list.last = new_node;134 list.last = new_node;
135 new_node.prev = null;135 new_node.prev = null;
136 new_node.next = null;136 new_node.next = null;
137137
...@@ -217,7 +217,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -217,7 +217,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
217 pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) !&Node {217 pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) !&Node {
218 comptime assert(!isIntrusive());218 comptime assert(!isIntrusive());
219 var node = try list.allocateNode(allocator);219 var node = try list.allocateNode(allocator);
220 *node = Node.init(data);220 node.* = Node.init(data);
221 return node;221 return node;
222 }222 }
223 };223 };
...@@ -227,11 +227,11 @@ test "basic linked list test" {...@@ -227,11 +227,11 @@ test "basic linked list test" {
227 const allocator = debug.global_allocator;227 const allocator = debug.global_allocator;
228 var list = LinkedList(u32).init();228 var list = LinkedList(u32).init();
229229
230 var one = try list.createNode(1, allocator);230 var one = try list.createNode(1, allocator);
231 var two = try list.createNode(2, allocator);231 var two = try list.createNode(2, allocator);
232 var three = try list.createNode(3, allocator);232 var three = try list.createNode(3, allocator);
233 var four = try list.createNode(4, allocator);233 var four = try list.createNode(4, allocator);
234 var five = try list.createNode(5, allocator);234 var five = try list.createNode(5, allocator);
235 defer {235 defer {
236 list.destroyNode(one, allocator);236 list.destroyNode(one, allocator);
237 list.destroyNode(two, allocator);237 list.destroyNode(two, allocator);
...@@ -240,11 +240,11 @@ test "basic linked list test" {...@@ -240,11 +240,11 @@ test "basic linked list test" {
240 list.destroyNode(five, allocator);240 list.destroyNode(five, allocator);
241 }241 }
242242
243 list.append(two); // {2}243 list.append(two); // {2}
244 list.append(five); // {2, 5}244 list.append(five); // {2, 5}
245 list.prepend(one); // {1, 2, 5}245 list.prepend(one); // {1, 2, 5}
246 list.insertBefore(five, four); // {1, 2, 4, 5}246 list.insertBefore(five, four); // {1, 2, 4, 5}
247 list.insertAfter(two, three); // {1, 2, 3, 4, 5}247 list.insertAfter(two, three); // {1, 2, 3, 4, 5}
248248
249 // Traverse forwards.249 // Traverse forwards.
250 {250 {
...@@ -266,13 +266,13 @@ test "basic linked list test" {...@@ -266,13 +266,13 @@ test "basic linked list test" {
266 }266 }
267 }267 }
268268
269 var first = list.popFirst(); // {2, 3, 4, 5}269 var first = list.popFirst(); // {2, 3, 4, 5}
270 var last = list.pop(); // {2, 3, 4}270 var last = list.pop(); // {2, 3, 4}
271 list.remove(three); // {2, 4}271 list.remove(three); // {2, 4}
272272
273 assert ((??list.first).data == 2);273 assert((??list.first).data == 2);
274 assert ((??list.last ).data == 4);274 assert((??list.last).data == 4);
275 assert (list.len == 2);275 assert(list.len == 2);
276}276}
277277
278const ElementList = IntrusiveLinkedList(Element, "link");278const ElementList = IntrusiveLinkedList(Element, "link");
...@@ -285,17 +285,32 @@ test "basic intrusive linked list test" {...@@ -285,17 +285,32 @@ test "basic intrusive linked list test" {
285 const allocator = debug.global_allocator;285 const allocator = debug.global_allocator;
286 var list = ElementList.init();286 var list = ElementList.init();
287287
288 var one = Element { .value = 1, .link = ElementList.Node.initIntrusive() };288 var one = Element{
289 var two = Element { .value = 2, .link = ElementList.Node.initIntrusive() };289 .value = 1,
290 var three = Element { .value = 3, .link = ElementList.Node.initIntrusive() };290 .link = ElementList.Node.initIntrusive(),
291 var four = Element { .value = 4, .link = ElementList.Node.initIntrusive() };291 };
292 var five = Element { .value = 5, .link = ElementList.Node.initIntrusive() };292 var two = Element{
293 .value = 2,
294 .link = ElementList.Node.initIntrusive(),
295 };
296 var three = Element{
297 .value = 3,
298 .link = ElementList.Node.initIntrusive(),
299 };
300 var four = Element{
301 .value = 4,
302 .link = ElementList.Node.initIntrusive(),
303 };
304 var five = Element{
305 .value = 5,
306 .link = ElementList.Node.initIntrusive(),
307 };
293308
294 list.append(&two.link); // {2}309 list.append(&two.link); // {2}
295 list.append(&five.link); // {2, 5}310 list.append(&five.link); // {2, 5}
296 list.prepend(&one.link); // {1, 2, 5}311 list.prepend(&one.link); // {1, 2, 5}
297 list.insertBefore(&five.link, &four.link); // {1, 2, 4, 5}312 list.insertBefore(&five.link, &four.link); // {1, 2, 4, 5}
298 list.insertAfter(&two.link, &three.link); // {1, 2, 3, 4, 5}313 list.insertAfter(&two.link, &three.link); // {1, 2, 3, 4, 5}
299314
300 // Traverse forwards.315 // Traverse forwards.
301 {316 {
...@@ -317,11 +332,11 @@ test "basic intrusive linked list test" {...@@ -317,11 +332,11 @@ test "basic intrusive linked list test" {
317 }332 }
318 }333 }
319334
320 var first = list.popFirst(); // {2, 3, 4, 5}335 var first = list.popFirst(); // {2, 3, 4, 5}
321 var last = list.pop(); // {2, 3, 4}336 var last = list.pop(); // {2, 3, 4}
322 list.remove(&three.link); // {2, 4}337 list.remove(&three.link); // {2, 4}
323338
324 assert ((??list.first).toData().value == 2);339 assert((??list.first).toData().value == 2);
325 assert ((??list.last ).toData().value == 4);340 assert((??list.last).toData().value == 4);
326 assert (list.len == 2);341 assert(list.len == 2);
327}342}
std/macho.zig+11-9
...@@ -58,15 +58,15 @@ pub const SymbolTable = struct {...@@ -58,15 +58,15 @@ pub const SymbolTable = struct {
58 // code, its displacement is different.58 // code, its displacement is different.
59 pub fn deinit(self: &SymbolTable) void {59 pub fn deinit(self: &SymbolTable) void {
60 self.allocator.free(self.symbols);60 self.allocator.free(self.symbols);
61 self.symbols = []const Symbol {};61 self.symbols = []const Symbol{};
6262
63 self.allocator.free(self.strings);63 self.allocator.free(self.strings);
64 self.strings = []const u8 {};64 self.strings = []const u8{};
65 }65 }
6666
67 pub fn search(self: &const SymbolTable, address: usize) ?&const Symbol {67 pub fn search(self: &const SymbolTable, address: usize) ?&const Symbol {
68 var min: usize = 0;68 var min: usize = 0;
69 var max: usize = self.symbols.len - 1; // Exclude sentinel.69 var max: usize = self.symbols.len - 1; // Exclude sentinel.
70 while (min < max) {70 while (min < max) {
71 const mid = min + (max - min) / 2;71 const mid = min + (max - min) / 2;
72 const curr = &self.symbols[mid];72 const curr = &self.symbols[mid];
...@@ -118,10 +118,11 @@ pub fn loadSymbols(allocator: &mem.Allocator, in: &io.FileInStream) !SymbolTable...@@ -118,10 +118,11 @@ pub fn loadSymbols(allocator: &mem.Allocator, in: &io.FileInStream) !SymbolTable
118 try in.stream.readNoEof(strings);118 try in.stream.readNoEof(strings);
119119
120 var nsyms: usize = 0;120 var nsyms: usize = 0;
121 for (syms) |sym| if (isSymbol(sym)) nsyms += 1;121 for (syms) |sym|
122 if (isSymbol(sym)) nsyms += 1;
122 if (nsyms == 0) return error.MissingDebugInfo;123 if (nsyms == 0) return error.MissingDebugInfo;
123124
124 var symbols = try allocator.alloc(Symbol, nsyms + 1); // Room for sentinel.125 var symbols = try allocator.alloc(Symbol, nsyms + 1); // Room for sentinel.
125 errdefer allocator.free(symbols);126 errdefer allocator.free(symbols);
126127
127 var pie_slide: usize = 0;128 var pie_slide: usize = 0;
...@@ -132,7 +133,7 @@ pub fn loadSymbols(allocator: &mem.Allocator, in: &io.FileInStream) !SymbolTable...@@ -132,7 +133,7 @@ pub fn loadSymbols(allocator: &mem.Allocator, in: &io.FileInStream) !SymbolTable
132 const end = ??mem.indexOfScalarPos(u8, strings, start, 0);133 const end = ??mem.indexOfScalarPos(u8, strings, start, 0);
133 const name = strings[start..end];134 const name = strings[start..end];
134 const address = sym.n_value;135 const address = sym.n_value;
135 symbols[nsym] = Symbol { .name = name, .address = address };136 symbols[nsym] = Symbol{ .name = name, .address = address };
136 nsym += 1;137 nsym += 1;
137 if (is_pie and mem.eql(u8, name, "_SymbolTable_deinit")) {138 if (is_pie and mem.eql(u8, name, "_SymbolTable_deinit")) {
138 pie_slide = @ptrToInt(SymbolTable.deinit) - address;139 pie_slide = @ptrToInt(SymbolTable.deinit) - address;
...@@ -145,13 +146,14 @@ pub fn loadSymbols(allocator: &mem.Allocator, in: &io.FileInStream) !SymbolTable...@@ -145,13 +146,14 @@ pub fn loadSymbols(allocator: &mem.Allocator, in: &io.FileInStream) !SymbolTable
145 // Insert the sentinel. Since we don't know where the last function ends,146 // Insert the sentinel. Since we don't know where the last function ends,
146 // we arbitrarily limit it to the start address + 4 KB.147 // we arbitrarily limit it to the start address + 4 KB.
147 const top = symbols[nsyms - 1].address + 4096;148 const top = symbols[nsyms - 1].address + 4096;
148 symbols[nsyms] = Symbol { .name = "", .address = top };149 symbols[nsyms] = Symbol{ .name = "", .address = top };
149150
150 if (pie_slide != 0) {151 if (pie_slide != 0) {
151 for (symbols) |*symbol| symbol.address += pie_slide;152 for (symbols) |*symbol|
153 symbol.address += pie_slide;
152 }154 }
153155
154 return SymbolTable {156 return SymbolTable{
155 .allocator = allocator,157 .allocator = allocator,
156 .symbols = symbols,158 .symbols = symbols,
157 .strings = strings,159 .strings = strings,
std/math/acos.zig+7-7
...@@ -16,7 +16,7 @@ pub fn acos(x: var) @typeOf(x) {...@@ -16,7 +16,7 @@ pub fn acos(x: var) @typeOf(x) {
16}16}
1717
18fn r32(z: f32) f32 {18fn r32(z: f32) f32 {
19 const pS0 = 1.6666586697e-01;19 const pS0 = 1.6666586697e-01;
20 const pS1 = -4.2743422091e-02;20 const pS1 = -4.2743422091e-02;
21 const pS2 = -8.6563630030e-03;21 const pS2 = -8.6563630030e-03;
22 const qS1 = -7.0662963390e-01;22 const qS1 = -7.0662963390e-01;
...@@ -74,16 +74,16 @@ fn acos32(x: f32) f32 {...@@ -74,16 +74,16 @@ fn acos32(x: f32) f32 {
74}74}
7575
76fn r64(z: f64) f64 {76fn r64(z: f64) f64 {
77 const pS0: f64 = 1.66666666666666657415e-01;77 const pS0: f64 = 1.66666666666666657415e-01;
78 const pS1: f64 = -3.25565818622400915405e-01;78 const pS1: f64 = -3.25565818622400915405e-01;
79 const pS2: f64 = 2.01212532134862925881e-01;79 const pS2: f64 = 2.01212532134862925881e-01;
80 const pS3: f64 = -4.00555345006794114027e-02;80 const pS3: f64 = -4.00555345006794114027e-02;
81 const pS4: f64 = 7.91534994289814532176e-04;81 const pS4: f64 = 7.91534994289814532176e-04;
82 const pS5: f64 = 3.47933107596021167570e-05;82 const pS5: f64 = 3.47933107596021167570e-05;
83 const qS1: f64 = -2.40339491173441421878e+00;83 const qS1: f64 = -2.40339491173441421878e+00;
84 const qS2: f64 = 2.02094576023350569471e+00;84 const qS2: f64 = 2.02094576023350569471e+00;
85 const qS3: f64 = -6.88283971605453293030e-01;85 const qS3: f64 = -6.88283971605453293030e-01;
86 const qS4: f64 = 7.70381505559019352791e-02;86 const qS4: f64 = 7.70381505559019352791e-02;
8787
88 const p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));88 const p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
89 const q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));89 const q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
std/math/asin.zig+9-9
...@@ -17,7 +17,7 @@ pub fn asin(x: var) @typeOf(x) {...@@ -17,7 +17,7 @@ pub fn asin(x: var) @typeOf(x) {
17}17}
1818
19fn r32(z: f32) f32 {19fn r32(z: f32) f32 {
20 const pS0 = 1.6666586697e-01;20 const pS0 = 1.6666586697e-01;
21 const pS1 = -4.2743422091e-02;21 const pS1 = -4.2743422091e-02;
22 const pS2 = -8.6563630030e-03;22 const pS2 = -8.6563630030e-03;
23 const qS1 = -7.0662963390e-01;23 const qS1 = -7.0662963390e-01;
...@@ -37,9 +37,9 @@ fn asin32(x: f32) f32 {...@@ -37,9 +37,9 @@ fn asin32(x: f32) f32 {
37 if (ix >= 0x3F800000) {37 if (ix >= 0x3F800000) {
38 // |x| >= 138 // |x| >= 1
39 if (ix == 0x3F800000) {39 if (ix == 0x3F800000) {
40 return x * pio2 + 0x1.0p-120; // asin(+-1) = +-pi/2 with inexact40 return x * pio2 + 0x1.0p-120; // asin(+-1) = +-pi/2 with inexact
41 } else {41 } else {
42 return math.nan(f32); // asin(|x| > 1) is nan42 return math.nan(f32); // asin(|x| > 1) is nan
43 }43 }
44 }44 }
4545
...@@ -66,16 +66,16 @@ fn asin32(x: f32) f32 {...@@ -66,16 +66,16 @@ fn asin32(x: f32) f32 {
66}66}
6767
68fn r64(z: f64) f64 {68fn r64(z: f64) f64 {
69 const pS0: f64 = 1.66666666666666657415e-01;69 const pS0: f64 = 1.66666666666666657415e-01;
70 const pS1: f64 = -3.25565818622400915405e-01;70 const pS1: f64 = -3.25565818622400915405e-01;
71 const pS2: f64 = 2.01212532134862925881e-01;71 const pS2: f64 = 2.01212532134862925881e-01;
72 const pS3: f64 = -4.00555345006794114027e-02;72 const pS3: f64 = -4.00555345006794114027e-02;
73 const pS4: f64 = 7.91534994289814532176e-04;73 const pS4: f64 = 7.91534994289814532176e-04;
74 const pS5: f64 = 3.47933107596021167570e-05;74 const pS5: f64 = 3.47933107596021167570e-05;
75 const qS1: f64 = -2.40339491173441421878e+00;75 const qS1: f64 = -2.40339491173441421878e+00;
76 const qS2: f64 = 2.02094576023350569471e+00;76 const qS2: f64 = 2.02094576023350569471e+00;
77 const qS3: f64 = -6.88283971605453293030e-01;77 const qS3: f64 = -6.88283971605453293030e-01;
78 const qS4: f64 = 7.70381505559019352791e-02;78 const qS4: f64 = 7.70381505559019352791e-02;
7979
80 const p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));80 const p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
81 const q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));81 const q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
std/math/atan.zig+15-17
...@@ -17,25 +17,25 @@ pub fn atan(x: var) @typeOf(x) {...@@ -17,25 +17,25 @@ pub fn atan(x: var) @typeOf(x) {
17}17}
1818
19fn atan32(x_: f32) f32 {19fn atan32(x_: f32) f32 {
20 const atanhi = []const f32 {20 const atanhi = []const f32{
21 4.6364760399e-01, // atan(0.5)hi21 4.6364760399e-01, // atan(0.5)hi
22 7.8539812565e-01, // atan(1.0)hi22 7.8539812565e-01, // atan(1.0)hi
23 9.8279368877e-01, // atan(1.5)hi23 9.8279368877e-01, // atan(1.5)hi
24 1.5707962513e+00, // atan(inf)hi24 1.5707962513e+00, // atan(inf)hi
25 };25 };
2626
27 const atanlo = []const f32 {27 const atanlo = []const f32{
28 5.0121582440e-09, // atan(0.5)lo28 5.0121582440e-09, // atan(0.5)lo
29 3.7748947079e-08, // atan(1.0)lo29 3.7748947079e-08, // atan(1.0)lo
30 3.4473217170e-08, // atan(1.5)lo30 3.4473217170e-08, // atan(1.5)lo
31 7.5497894159e-08, // atan(inf)lo31 7.5497894159e-08, // atan(inf)lo
32 };32 };
3333
34 const aT = []const f32 {34 const aT = []const f32{
35 3.3333328366e-01,35 3.3333328366e-01,
36 -1.9999158382e-01,36 -1.9999158382e-01,
37 1.4253635705e-01,37 1.4253635705e-01,
38 -1.0648017377e-01,38 -1.0648017377e-01,
39 6.1687607318e-02,39 6.1687607318e-02,
40 };40 };
4141
...@@ -80,8 +80,7 @@ fn atan32(x_: f32) f32 {...@@ -80,8 +80,7 @@ fn atan32(x_: f32) f32 {
80 id = 1;80 id = 1;
81 x = (x - 1.0) / (x + 1.0);81 x = (x - 1.0) / (x + 1.0);
82 }82 }
83 }83 } else {
84 else {
85 // |x| < 2.437584 // |x| < 2.4375
86 if (ix < 0x401C0000) {85 if (ix < 0x401C0000) {
87 id = 2;86 id = 2;
...@@ -109,31 +108,31 @@ fn atan32(x_: f32) f32 {...@@ -109,31 +108,31 @@ fn atan32(x_: f32) f32 {
109}108}
110109
111fn atan64(x_: f64) f64 {110fn atan64(x_: f64) f64 {
112 const atanhi = []const f64 {111 const atanhi = []const f64{
113 4.63647609000806093515e-01, // atan(0.5)hi112 4.63647609000806093515e-01, // atan(0.5)hi
114 7.85398163397448278999e-01, // atan(1.0)hi113 7.85398163397448278999e-01, // atan(1.0)hi
115 9.82793723247329054082e-01, // atan(1.5)hi114 9.82793723247329054082e-01, // atan(1.5)hi
116 1.57079632679489655800e+00, // atan(inf)hi115 1.57079632679489655800e+00, // atan(inf)hi
117 };116 };
118117
119 const atanlo = []const f64 {118 const atanlo = []const f64{
120 2.26987774529616870924e-17, // atan(0.5)lo119 2.26987774529616870924e-17, // atan(0.5)lo
121 3.06161699786838301793e-17, // atan(1.0)lo120 3.06161699786838301793e-17, // atan(1.0)lo
122 1.39033110312309984516e-17, // atan(1.5)lo121 1.39033110312309984516e-17, // atan(1.5)lo
123 6.12323399573676603587e-17, // atan(inf)lo122 6.12323399573676603587e-17, // atan(inf)lo
124 };123 };
125124
126 const aT = []const f64 {125 const aT = []const f64{
127 3.33333333333329318027e-01,126 3.33333333333329318027e-01,
128 -1.99999999998764832476e-01,127 -1.99999999998764832476e-01,
129 1.42857142725034663711e-01,128 1.42857142725034663711e-01,
130 -1.11111104054623557880e-01,129 -1.11111104054623557880e-01,
131 9.09088713343650656196e-02,130 9.09088713343650656196e-02,
132 -7.69187620504482999495e-02,131 -7.69187620504482999495e-02,
133 6.66107313738753120669e-02,132 6.66107313738753120669e-02,
134 -5.83357013379057348645e-02,133 -5.83357013379057348645e-02,
135 4.97687799461593236017e-02,134 4.97687799461593236017e-02,
136 -3.65315727442169155270e-02,135 -3.65315727442169155270e-02,
137 1.62858201153657823623e-02,136 1.62858201153657823623e-02,
138 };137 };
139138
...@@ -179,8 +178,7 @@ fn atan64(x_: f64) f64 {...@@ -179,8 +178,7 @@ fn atan64(x_: f64) f64 {
179 id = 1;178 id = 1;
180 x = (x - 1.0) / (x + 1.0);179 x = (x - 1.0) / (x + 1.0);
181 }180 }
182 }181 } else {
183 else {
184 // |x| < 2.4375182 // |x| < 2.4375
185 if (ix < 0x40038000) {183 if (ix < 0x40038000) {
186 id = 2;184 id = 2;
std/math/atan2.zig+32-32
...@@ -31,7 +31,7 @@ pub fn atan2(comptime T: type, x: T, y: T) T {...@@ -31,7 +31,7 @@ pub fn atan2(comptime T: type, x: T, y: T) T {
31}31}
3232
33fn atan2_32(y: f32, x: f32) f32 {33fn atan2_32(y: f32, x: f32) f32 {
34 const pi: f32 = 3.1415927410e+00;34 const pi: f32 = 3.1415927410e+00;
35 const pi_lo: f32 = -8.7422776573e-08;35 const pi_lo: f32 = -8.7422776573e-08;
3636
37 if (math.isNan(x) or math.isNan(y)) {37 if (math.isNan(x) or math.isNan(y)) {
...@@ -53,9 +53,9 @@ fn atan2_32(y: f32, x: f32) f32 {...@@ -53,9 +53,9 @@ fn atan2_32(y: f32, x: f32) f32 {
5353
54 if (iy == 0) {54 if (iy == 0) {
55 switch (m) {55 switch (m) {
56 0, 1 => return y, // atan(+-0, +...)56 0, 1 => return y, // atan(+-0, +...)
57 2 => return pi, // atan(+0, -...)57 2 => return pi, // atan(+0, -...)
58 3 => return -pi, // atan(-0, -...)58 3 => return -pi, // atan(-0, -...)
59 else => unreachable,59 else => unreachable,
60 }60 }
61 }61 }
...@@ -71,18 +71,18 @@ fn atan2_32(y: f32, x: f32) f32 {...@@ -71,18 +71,18 @@ fn atan2_32(y: f32, x: f32) f32 {
71 if (ix == 0x7F800000) {71 if (ix == 0x7F800000) {
72 if (iy == 0x7F800000) {72 if (iy == 0x7F800000) {
73 switch (m) {73 switch (m) {
74 0 => return pi / 4, // atan(+inf, +inf)74 0 => return pi / 4, // atan(+inf, +inf)
75 1 => return -pi / 4, // atan(-inf, +inf)75 1 => return -pi / 4, // atan(-inf, +inf)
76 2 => return 3*pi / 4, // atan(+inf, -inf)76 2 => return 3 * pi / 4, // atan(+inf, -inf)
77 3 => return -3*pi / 4, // atan(-inf, -inf)77 3 => return -3 * pi / 4, // atan(-inf, -inf)
78 else => unreachable,78 else => unreachable,
79 }79 }
80 } else {80 } else {
81 switch (m) {81 switch (m) {
82 0 => return 0.0, // atan(+..., +inf)82 0 => return 0.0, // atan(+..., +inf)
83 1 => return -0.0, // atan(-..., +inf)83 1 => return -0.0, // atan(-..., +inf)
84 2 => return pi, // atan(+..., -inf)84 2 => return pi, // atan(+..., -inf)
85 3 => return -pi, // atan(-...f, -inf)85 3 => return -pi, // atan(-...f, -inf)
86 else => unreachable,86 else => unreachable,
87 }87 }
88 }88 }
...@@ -107,16 +107,16 @@ fn atan2_32(y: f32, x: f32) f32 {...@@ -107,16 +107,16 @@ fn atan2_32(y: f32, x: f32) f32 {
107 };107 };
108108
109 switch (m) {109 switch (m) {
110 0 => return z, // atan(+, +)110 0 => return z, // atan(+, +)
111 1 => return -z, // atan(-, +)111 1 => return -z, // atan(-, +)
112 2 => return pi - (z - pi_lo), // atan(+, -)112 2 => return pi - (z - pi_lo), // atan(+, -)
113 3 => return (z - pi_lo) - pi, // atan(-, -)113 3 => return (z - pi_lo) - pi, // atan(-, -)
114 else => unreachable,114 else => unreachable,
115 }115 }
116}116}
117117
118fn atan2_64(y: f64, x: f64) f64 {118fn atan2_64(y: f64, x: f64) f64 {
119 const pi: f64 = 3.1415926535897931160E+00;119 const pi: f64 = 3.1415926535897931160E+00;
120 const pi_lo: f64 = 1.2246467991473531772E-16;120 const pi_lo: f64 = 1.2246467991473531772E-16;
121121
122 if (math.isNan(x) or math.isNan(y)) {122 if (math.isNan(x) or math.isNan(y)) {
...@@ -143,9 +143,9 @@ fn atan2_64(y: f64, x: f64) f64 {...@@ -143,9 +143,9 @@ fn atan2_64(y: f64, x: f64) f64 {
143143
144 if (iy | ly == 0) {144 if (iy | ly == 0) {
145 switch (m) {145 switch (m) {
146 0, 1 => return y, // atan(+-0, +...)146 0, 1 => return y, // atan(+-0, +...)
147 2 => return pi, // atan(+0, -...)147 2 => return pi, // atan(+0, -...)
148 3 => return -pi, // atan(-0, -...)148 3 => return -pi, // atan(-0, -...)
149 else => unreachable,149 else => unreachable,
150 }150 }
151 }151 }
...@@ -161,18 +161,18 @@ fn atan2_64(y: f64, x: f64) f64 {...@@ -161,18 +161,18 @@ fn atan2_64(y: f64, x: f64) f64 {
161 if (ix == 0x7FF00000) {161 if (ix == 0x7FF00000) {
162 if (iy == 0x7FF00000) {162 if (iy == 0x7FF00000) {
163 switch (m) {163 switch (m) {
164 0 => return pi / 4, // atan(+inf, +inf)164 0 => return pi / 4, // atan(+inf, +inf)
165 1 => return -pi / 4, // atan(-inf, +inf)165 1 => return -pi / 4, // atan(-inf, +inf)
166 2 => return 3*pi / 4, // atan(+inf, -inf)166 2 => return 3 * pi / 4, // atan(+inf, -inf)
167 3 => return -3*pi / 4, // atan(-inf, -inf)167 3 => return -3 * pi / 4, // atan(-inf, -inf)
168 else => unreachable,168 else => unreachable,
169 }169 }
170 } else {170 } else {
171 switch (m) {171 switch (m) {
172 0 => return 0.0, // atan(+..., +inf)172 0 => return 0.0, // atan(+..., +inf)
173 1 => return -0.0, // atan(-..., +inf)173 1 => return -0.0, // atan(-..., +inf)
174 2 => return pi, // atan(+..., -inf)174 2 => return pi, // atan(+..., -inf)
175 3 => return -pi, // atan(-...f, -inf)175 3 => return -pi, // atan(-...f, -inf)
176 else => unreachable,176 else => unreachable,
177 }177 }
178 }178 }
...@@ -197,10 +197,10 @@ fn atan2_64(y: f64, x: f64) f64 {...@@ -197,10 +197,10 @@ fn atan2_64(y: f64, x: f64) f64 {
197 };197 };
198198
199 switch (m) {199 switch (m) {
200 0 => return z, // atan(+, +)200 0 => return z, // atan(+, +)
201 1 => return -z, // atan(-, +)201 1 => return -z, // atan(-, +)
202 2 => return pi - (z - pi_lo), // atan(+, -)202 2 => return pi - (z - pi_lo), // atan(+, -)
203 3 => return (z - pi_lo) - pi, // atan(-, -)203 3 => return (z - pi_lo) - pi, // atan(-, -)
204 else => unreachable,204 else => unreachable,
205 }205 }
206}206}
std/math/cbrt.zig+5-5
...@@ -58,15 +58,15 @@ fn cbrt32(x: f32) f32 {...@@ -58,15 +58,15 @@ fn cbrt32(x: f32) f32 {
58}58}
5959
60fn cbrt64(x: f64) f64 {60fn cbrt64(x: f64) f64 {
61 const B1: u32 = 715094163; // (1023 - 1023 / 3 - 0.03306235651 * 2^2061 const B1: u32 = 715094163; // (1023 - 1023 / 3 - 0.03306235651 * 2^20
62 const B2: u32 = 696219795; // (1023 - 1023 / 3 - 54 / 3 - 0.03306235651 * 2^2062 const B2: u32 = 696219795; // (1023 - 1023 / 3 - 54 / 3 - 0.03306235651 * 2^20
6363
64 // |1 / cbrt(x) - p(x)| < 2^(23.5)64 // |1 / cbrt(x) - p(x)| < 2^(23.5)
65 const P0: f64 = 1.87595182427177009643;65 const P0: f64 = 1.87595182427177009643;
66 const P1: f64 = -1.88497979543377169875;66 const P1: f64 = -1.88497979543377169875;
67 const P2: f64 = 1.621429720105354466140;67 const P2: f64 = 1.621429720105354466140;
68 const P3: f64 = -0.758397934778766047437;68 const P3: f64 = -0.758397934778766047437;
69 const P4: f64 = 0.145996192886612446982;69 const P4: f64 = 0.145996192886612446982;
7070
71 var u = @bitCast(u64, x);71 var u = @bitCast(u64, x);
72 var hx = u32(u >> 32) & 0x7FFFFFFF;72 var hx = u32(u >> 32) & 0x7FFFFFFF;
std/math/ceil.zig+2-2
...@@ -56,7 +56,7 @@ fn ceil64(x: f64) f64 {...@@ -56,7 +56,7 @@ fn ceil64(x: f64) f64 {
56 const e = (u >> 52) & 0x7FF;56 const e = (u >> 52) & 0x7FF;
57 var y: f64 = undefined;57 var y: f64 = undefined;
5858
59 if (e >= 0x3FF+52 or x == 0) {59 if (e >= 0x3FF + 52 or x == 0) {
60 return x;60 return x;
61 }61 }
6262
...@@ -68,7 +68,7 @@ fn ceil64(x: f64) f64 {...@@ -68,7 +68,7 @@ fn ceil64(x: f64) f64 {
68 y = x + math.f64_toint - math.f64_toint - x;68 y = x + math.f64_toint - math.f64_toint - x;
69 }69 }
7070
71 if (e <= 0x3FF-1) {71 if (e <= 0x3FF - 1) {
72 math.forceEval(y);72 math.forceEval(y);
73 if (u >> 63 != 0) {73 if (u >> 63 != 0) {
74 return -0.0;74 return -0.0;
std/math/complex/exp.zig+11-17
...@@ -19,8 +19,8 @@ pub fn exp(z: var) Complex(@typeOf(z.re)) {...@@ -19,8 +19,8 @@ pub fn exp(z: var) Complex(@typeOf(z.re)) {
19fn exp32(z: &const Complex(f32)) Complex(f32) {19fn exp32(z: &const Complex(f32)) Complex(f32) {
20 @setFloatMode(this, @import("builtin").FloatMode.Strict);20 @setFloatMode(this, @import("builtin").FloatMode.Strict);
2121
22 const exp_overflow = 0x42b17218; // max_exp * ln2 ~= 88.7228395522 const exp_overflow = 0x42b17218; // max_exp * ln2 ~= 88.72283955
23 const cexp_overflow = 0x43400074; // (max_exp - min_denom_exp) * ln223 const cexp_overflow = 0x43400074; // (max_exp - min_denom_exp) * ln2
2424
25 const x = z.re;25 const x = z.re;
26 const y = z.im;26 const y = z.im;
...@@ -41,12 +41,10 @@ fn exp32(z: &const Complex(f32)) Complex(f32) {...@@ -41,12 +41,10 @@ fn exp32(z: &const Complex(f32)) Complex(f32) {
41 // cexp(finite|nan +- i inf|nan) = nan + i nan41 // cexp(finite|nan +- i inf|nan) = nan + i nan
42 if ((hx & 0x7fffffff) != 0x7f800000) {42 if ((hx & 0x7fffffff) != 0x7f800000) {
43 return Complex(f32).new(y - y, y - y);43 return Complex(f32).new(y - y, y - y);
44 }44 } // cexp(-inf +- i inf|nan) = 0 + i0
45 // cexp(-inf +- i inf|nan) = 0 + i0
46 else if (hx & 0x80000000 != 0) {45 else if (hx & 0x80000000 != 0) {
47 return Complex(f32).new(0, 0);46 return Complex(f32).new(0, 0);
48 }47 } // cexp(+inf +- i inf|nan) = inf + i nan
49 // cexp(+inf +- i inf|nan) = inf + i nan
50 else {48 else {
51 return Complex(f32).new(x, y - y);49 return Complex(f32).new(x, y - y);
52 }50 }
...@@ -55,8 +53,7 @@ fn exp32(z: &const Complex(f32)) Complex(f32) {...@@ -55,8 +53,7 @@ fn exp32(z: &const Complex(f32)) Complex(f32) {
55 // 88.7 <= x <= 192 so must scale53 // 88.7 <= x <= 192 so must scale
56 if (hx >= exp_overflow and hx <= cexp_overflow) {54 if (hx >= exp_overflow and hx <= cexp_overflow) {
57 return ldexp_cexp(z, 0);55 return ldexp_cexp(z, 0);
58 }56 } // - x < exp_overflow => exp(x) won't overflow (common)
59 // - x < exp_overflow => exp(x) won't overflow (common)
60 // - x > cexp_overflow, so exp(x) * s overflows for s > 057 // - x > cexp_overflow, so exp(x) * s overflows for s > 0
61 // - x = +-inf58 // - x = +-inf
62 // - x = nan59 // - x = nan
...@@ -67,8 +64,8 @@ fn exp32(z: &const Complex(f32)) Complex(f32) {...@@ -67,8 +64,8 @@ fn exp32(z: &const Complex(f32)) Complex(f32) {
67}64}
6865
69fn exp64(z: &const Complex(f64)) Complex(f64) {66fn exp64(z: &const Complex(f64)) Complex(f64) {
70 const exp_overflow = 0x40862e42; // high bits of max_exp * ln2 ~= 71067 const exp_overflow = 0x40862e42; // high bits of max_exp * ln2 ~= 710
71 const cexp_overflow = 0x4096b8e4; // (max_exp - min_denorm_exp) * ln268 const cexp_overflow = 0x4096b8e4; // (max_exp - min_denorm_exp) * ln2
7269
73 const x = z.re;70 const x = z.re;
74 const y = z.im;71 const y = z.im;
...@@ -95,12 +92,10 @@ fn exp64(z: &const Complex(f64)) Complex(f64) {...@@ -95,12 +92,10 @@ fn exp64(z: &const Complex(f64)) Complex(f64) {
95 // cexp(finite|nan +- i inf|nan) = nan + i nan92 // cexp(finite|nan +- i inf|nan) = nan + i nan
96 if (lx != 0 or (hx & 0x7fffffff) != 0x7ff00000) {93 if (lx != 0 or (hx & 0x7fffffff) != 0x7ff00000) {
97 return Complex(f64).new(y - y, y - y);94 return Complex(f64).new(y - y, y - y);
98 }95 } // cexp(-inf +- i inf|nan) = 0 + i0
99 // cexp(-inf +- i inf|nan) = 0 + i0
100 else if (hx & 0x80000000 != 0) {96 else if (hx & 0x80000000 != 0) {
101 return Complex(f64).new(0, 0);97 return Complex(f64).new(0, 0);
102 }98 } // cexp(+inf +- i inf|nan) = inf + i nan
103 // cexp(+inf +- i inf|nan) = inf + i nan
104 else {99 else {
105 return Complex(f64).new(x, y - y);100 return Complex(f64).new(x, y - y);
106 }101 }
...@@ -109,9 +104,8 @@ fn exp64(z: &const Complex(f64)) Complex(f64) {...@@ -109,9 +104,8 @@ fn exp64(z: &const Complex(f64)) Complex(f64) {
109 // 709.7 <= x <= 1454.3 so must scale104 // 709.7 <= x <= 1454.3 so must scale
110 if (hx >= exp_overflow and hx <= cexp_overflow) {105 if (hx >= exp_overflow and hx <= cexp_overflow) {
111 const r = ldexp_cexp(z, 0);106 const r = ldexp_cexp(z, 0);
112 return *r;107 return r.*;
113 }108 } // - x < exp_overflow => exp(x) won't overflow (common)
114 // - x < exp_overflow => exp(x) won't overflow (common)
115 // - x > cexp_overflow, so exp(x) * s overflows for s > 0109 // - x > cexp_overflow, so exp(x) * s overflows for s > 0
116 // - x = +-inf110 // - x = +-inf
117 // - x = nan111 // - x = nan
std/math/complex/index.zig+11-11
...@@ -31,28 +31,28 @@ pub fn Complex(comptime T: type) type {...@@ -31,28 +31,28 @@ pub fn Complex(comptime T: type) type {
31 im: T,31 im: T,
3232
33 pub fn new(re: T, im: T) Self {33 pub fn new(re: T, im: T) Self {
34 return Self {34 return Self{
35 .re = re,35 .re = re,
36 .im = im,36 .im = im,
37 };37 };
38 }38 }
3939
40 pub fn add(self: &const Self, other: &const Self) Self {40 pub fn add(self: &const Self, other: &const Self) Self {
41 return Self {41 return Self{
42 .re = self.re + other.re,42 .re = self.re + other.re,
43 .im = self.im + other.im,43 .im = self.im + other.im,
44 };44 };
45 }45 }
4646
47 pub fn sub(self: &const Self, other: &const Self) Self {47 pub fn sub(self: &const Self, other: &const Self) Self {
48 return Self {48 return Self{
49 .re = self.re - other.re,49 .re = self.re - other.re,
50 .im = self.im - other.im,50 .im = self.im - other.im,
51 };51 };
52 }52 }
5353
54 pub fn mul(self: &const Self, other: &const Self) Self {54 pub fn mul(self: &const Self, other: &const Self) Self {
55 return Self {55 return Self{
56 .re = self.re * other.re - self.im * other.im,56 .re = self.re * other.re - self.im * other.im,
57 .im = self.im * other.re + self.re * other.im,57 .im = self.im * other.re + self.re * other.im,
58 };58 };
...@@ -63,14 +63,14 @@ pub fn Complex(comptime T: type) type {...@@ -63,14 +63,14 @@ pub fn Complex(comptime T: type) type {
63 const im_num = self.im * other.re - self.re * other.im;63 const im_num = self.im * other.re - self.re * other.im;
64 const den = other.re * other.re + other.im * other.im;64 const den = other.re * other.re + other.im * other.im;
6565
66 return Self {66 return Self{
67 .re = re_num / den,67 .re = re_num / den,
68 .im = im_num / den,68 .im = im_num / den,
69 };69 };
70 }70 }
7171
72 pub fn conjugate(self: &const Self) Self {72 pub fn conjugate(self: &const Self) Self {
73 return Self {73 return Self{
74 .re = self.re,74 .re = self.re,
75 .im = -self.im,75 .im = -self.im,
76 };76 };
...@@ -78,7 +78,7 @@ pub fn Complex(comptime T: type) type {...@@ -78,7 +78,7 @@ pub fn Complex(comptime T: type) type {
7878
79 pub fn reciprocal(self: &const Self) Self {79 pub fn reciprocal(self: &const Self) Self {
80 const m = self.re * self.re + self.im * self.im;80 const m = self.re * self.re + self.im * self.im;
81 return Self {81 return Self{
82 .re = self.re / m,82 .re = self.re / m,
83 .im = -self.im / m,83 .im = -self.im / m,
84 };84 };
...@@ -121,8 +121,8 @@ test "complex.div" {...@@ -121,8 +121,8 @@ test "complex.div" {
121 const b = Complex(f32).new(2, 7);121 const b = Complex(f32).new(2, 7);
122 const c = a.div(b);122 const c = a.div(b);
123123
124 debug.assert(math.approxEq(f32, c.re, f32(31)/53, epsilon) and124 debug.assert(math.approxEq(f32, c.re, f32(31) / 53, epsilon) and
125 math.approxEq(f32, c.im, f32(-29)/53, epsilon));125 math.approxEq(f32, c.im, f32(-29) / 53, epsilon));
126}126}
127127
128test "complex.conjugate" {128test "complex.conjugate" {
...@@ -136,8 +136,8 @@ test "complex.reciprocal" {...@@ -136,8 +136,8 @@ test "complex.reciprocal" {
136 const a = Complex(f32).new(5, 3);136 const a = Complex(f32).new(5, 3);
137 const c = a.reciprocal();137 const c = a.reciprocal();
138138
139 debug.assert(math.approxEq(f32, c.re, f32(5)/34, epsilon) and139 debug.assert(math.approxEq(f32, c.re, f32(5) / 34, epsilon) and
140 math.approxEq(f32, c.im, f32(-3)/34, epsilon));140 math.approxEq(f32, c.im, f32(-3) / 34, epsilon));
141}141}
142142
143test "complex.magnitude" {143test "complex.magnitude" {
std/math/complex/ldexp.zig+7-10
...@@ -15,12 +15,12 @@ pub fn ldexp_cexp(z: var, expt: i32) Complex(@typeOf(z.re)) {...@@ -15,12 +15,12 @@ pub fn ldexp_cexp(z: var, expt: i32) Complex(@typeOf(z.re)) {
15}15}
1616
17fn frexp_exp32(x: f32, expt: &i32) f32 {17fn frexp_exp32(x: f32, expt: &i32) f32 {
18 const k = 235; // reduction constant18 const k = 235; // reduction constant
19 const kln2 = 162.88958740; // k * ln219 const kln2 = 162.88958740; // k * ln2
2020
21 const exp_x = math.exp(x - kln2);21 const exp_x = math.exp(x - kln2);
22 const hx = @bitCast(u32, exp_x);22 const hx = @bitCast(u32, exp_x);
23 *expt = i32(hx >> 23) - (0x7f + 127) + k;23 expt.* = i32(hx >> 23) - (0x7f + 127) + k;
24 return @bitCast(f32, (hx & 0x7fffff) | ((0x7f + 127) << 23));24 return @bitCast(f32, (hx & 0x7fffff) | ((0x7f + 127) << 23));
25}25}
2626
...@@ -35,15 +35,12 @@ fn ldexp_cexp32(z: &const Complex(f32), expt: i32) Complex(f32) {...@@ -35,15 +35,12 @@ fn ldexp_cexp32(z: &const Complex(f32), expt: i32) Complex(f32) {
35 const half_expt2 = exptf - half_expt1;35 const half_expt2 = exptf - half_expt1;
36 const scale2 = @bitCast(f32, (0x7f + half_expt2) << 23);36 const scale2 = @bitCast(f32, (0x7f + half_expt2) << 23);
3737
38 return Complex(f32).new(38 return Complex(f32).new(math.cos(z.im) * exp_x * scale1 * scale2, math.sin(z.im) * exp_x * scale1 * scale2);
39 math.cos(z.im) * exp_x * scale1 * scale2,
40 math.sin(z.im) * exp_x * scale1 * scale2,
41 );
42}39}
4340
44fn frexp_exp64(x: f64, expt: &i32) f64 {41fn frexp_exp64(x: f64, expt: &i32) f64 {
45 const k = 1799; // reduction constant42 const k = 1799; // reduction constant
46 const kln2 = 1246.97177782734161156; // k * ln243 const kln2 = 1246.97177782734161156; // k * ln2
4744
48 const exp_x = math.exp(x - kln2);45 const exp_x = math.exp(x - kln2);
4946
...@@ -51,7 +48,7 @@ fn frexp_exp64(x: f64, expt: &i32) f64 {...@@ -51,7 +48,7 @@ fn frexp_exp64(x: f64, expt: &i32) f64 {
51 const hx = u32(fx >> 32);48 const hx = u32(fx >> 32);
52 const lx = @truncate(u32, fx);49 const lx = @truncate(u32, fx);
5350
54 *expt = i32(hx >> 20) - (0x3ff + 1023) + k;51 expt.* = i32(hx >> 20) - (0x3ff + 1023) + k;
5552
56 const high_word = (hx & 0xfffff) | ((0x3ff + 1023) << 20);53 const high_word = (hx & 0xfffff) | ((0x3ff + 1023) << 20);
57 return @bitCast(f64, (u64(high_word) << 32) | lx);54 return @bitCast(f64, (u64(high_word) << 32) | lx);
std/math/complex/tanh.zig+2-2
...@@ -98,7 +98,7 @@ test "complex.ctanh32" {...@@ -98,7 +98,7 @@ test "complex.ctanh32" {
98 const a = Complex(f32).new(5, 3);98 const a = Complex(f32).new(5, 3);
99 const c = tanh(a);99 const c = tanh(a);
100100
101 debug.assert(math.approxEq(f32, c.re, 0.999913, epsilon));101 debug.assert(math.approxEq(f32, c.re, 0.999913, epsilon));
102 debug.assert(math.approxEq(f32, c.im, -0.000025, epsilon));102 debug.assert(math.approxEq(f32, c.im, -0.000025, epsilon));
103}103}
104104
...@@ -106,6 +106,6 @@ test "complex.ctanh64" {...@@ -106,6 +106,6 @@ test "complex.ctanh64" {
106 const a = Complex(f64).new(5, 3);106 const a = Complex(f64).new(5, 3);
107 const c = tanh(a);107 const c = tanh(a);
108108
109 debug.assert(math.approxEq(f64, c.re, 0.999913, epsilon));109 debug.assert(math.approxEq(f64, c.re, 0.999913, epsilon));
110 debug.assert(math.approxEq(f64, c.im, -0.000025, epsilon));110 debug.assert(math.approxEq(f64, c.im, -0.000025, epsilon));
111}111}
std/math/cos.zig+6-6
...@@ -18,20 +18,20 @@ pub fn cos(x: var) @typeOf(x) {...@@ -18,20 +18,20 @@ pub fn cos(x: var) @typeOf(x) {
18}18}
1919
20// sin polynomial coefficients20// sin polynomial coefficients
21const S0 = 1.58962301576546568060E-10;21const S0 = 1.58962301576546568060E-10;
22const S1 = -2.50507477628578072866E-8;22const S1 = -2.50507477628578072866E-8;
23const S2 = 2.75573136213857245213E-6;23const S2 = 2.75573136213857245213E-6;
24const S3 = -1.98412698295895385996E-4;24const S3 = -1.98412698295895385996E-4;
25const S4 = 8.33333333332211858878E-3;25const S4 = 8.33333333332211858878E-3;
26const S5 = -1.66666666666666307295E-1;26const S5 = -1.66666666666666307295E-1;
2727
28// cos polynomial coeffiecients28// cos polynomial coeffiecients
29const C0 = -1.13585365213876817300E-11;29const C0 = -1.13585365213876817300E-11;
30const C1 = 2.08757008419747316778E-9;30const C1 = 2.08757008419747316778E-9;
31const C2 = -2.75573141792967388112E-7;31const C2 = -2.75573141792967388112E-7;
32const C3 = 2.48015872888517045348E-5;32const C3 = 2.48015872888517045348E-5;
33const C4 = -1.38888888888730564116E-3;33const C4 = -1.38888888888730564116E-3;
34const C5 = 4.16666666666665929218E-2;34const C5 = 4.16666666666665929218E-2;
3535
36// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.36// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
37//37//
std/math/exp.zig+13-17
...@@ -20,10 +20,10 @@ pub fn exp(x: var) @typeOf(x) {...@@ -20,10 +20,10 @@ pub fn exp(x: var) @typeOf(x) {
20fn exp32(x_: f32) f32 {20fn exp32(x_: f32) f32 {
21 @setFloatMode(this, builtin.FloatMode.Strict);21 @setFloatMode(this, builtin.FloatMode.Strict);
2222
23 const half = []f32 { 0.5, -0.5 };23 const half = []f32{ 0.5, -0.5 };
24 const ln2hi = 6.9314575195e-1;24 const ln2hi = 6.9314575195e-1;
25 const ln2lo = 1.4286067653e-6;25 const ln2lo = 1.4286067653e-6;
26 const invln2 = 1.4426950216e+0;26 const invln2 = 1.4426950216e+0;
27 const P1 = 1.6666625440e-1;27 const P1 = 1.6666625440e-1;
28 const P2 = -2.7667332906e-3;28 const P2 = -2.7667332906e-3;
2929
...@@ -47,7 +47,7 @@ fn exp32(x_: f32) f32 {...@@ -47,7 +47,7 @@ fn exp32(x_: f32) f32 {
47 return x * 0x1.0p127;47 return x * 0x1.0p127;
48 }48 }
49 if (sign != 0) {49 if (sign != 0) {
50 math.forceEval(-0x1.0p-149 / x); // overflow50 math.forceEval(-0x1.0p-149 / x); // overflow
51 // x <= -103.97208451 // x <= -103.972084
52 if (hx >= 0x42CFF1B5) {52 if (hx >= 0x42CFF1B5) {
53 return 0;53 return 0;
...@@ -64,8 +64,7 @@ fn exp32(x_: f32) f32 {...@@ -64,8 +64,7 @@ fn exp32(x_: f32) f32 {
64 // |x| > 1.5 * ln264 // |x| > 1.5 * ln2
65 if (hx > 0x3F851592) {65 if (hx > 0x3F851592) {
66 k = i32(invln2 * x + half[usize(sign)]);66 k = i32(invln2 * x + half[usize(sign)]);
67 }67 } else {
68 else {
69 k = 1 - sign - sign;68 k = 1 - sign - sign;
70 }69 }
7170
...@@ -79,8 +78,7 @@ fn exp32(x_: f32) f32 {...@@ -79,8 +78,7 @@ fn exp32(x_: f32) f32 {
79 k = 0;78 k = 0;
80 hi = x;79 hi = x;
81 lo = 0;80 lo = 0;
82 }81 } else {
83 else {
84 math.forceEval(0x1.0p127 + x); // inexact82 math.forceEval(0x1.0p127 + x); // inexact
85 return 1 + x;83 return 1 + x;
86 }84 }
...@@ -99,15 +97,15 @@ fn exp32(x_: f32) f32 {...@@ -99,15 +97,15 @@ fn exp32(x_: f32) f32 {
99fn exp64(x_: f64) f64 {97fn exp64(x_: f64) f64 {
100 @setFloatMode(this, builtin.FloatMode.Strict);98 @setFloatMode(this, builtin.FloatMode.Strict);
10199
102 const half = []const f64 { 0.5, -0.5 };100 const half = []const f64{ 0.5, -0.5 };
103 const ln2hi: f64 = 6.93147180369123816490e-01;101 const ln2hi: f64 = 6.93147180369123816490e-01;
104 const ln2lo: f64 = 1.90821492927058770002e-10;102 const ln2lo: f64 = 1.90821492927058770002e-10;
105 const invln2: f64 = 1.44269504088896338700e+00;103 const invln2: f64 = 1.44269504088896338700e+00;
106 const P1: f64 = 1.66666666666666019037e-01;104 const P1: f64 = 1.66666666666666019037e-01;
107 const P2: f64 = -2.77777777770155933842e-03;105 const P2: f64 = -2.77777777770155933842e-03;
108 const P3: f64 = 6.61375632143793436117e-05;106 const P3: f64 = 6.61375632143793436117e-05;
109 const P4: f64 = -1.65339022054652515390e-06;107 const P4: f64 = -1.65339022054652515390e-06;
110 const P5: f64 = 4.13813679705723846039e-08;108 const P5: f64 = 4.13813679705723846039e-08;
111109
112 var x = x_;110 var x = x_;
113 var ux = @bitCast(u64, x);111 var ux = @bitCast(u64, x);
...@@ -151,8 +149,7 @@ fn exp64(x_: f64) f64 {...@@ -151,8 +149,7 @@ fn exp64(x_: f64) f64 {
151 // |x| >= 1.5 * ln2149 // |x| >= 1.5 * ln2
152 if (hx > 0x3FF0A2B2) {150 if (hx > 0x3FF0A2B2) {
153 k = i32(invln2 * x + half[usize(sign)]);151 k = i32(invln2 * x + half[usize(sign)]);
154 }152 } else {
155 else {
156 k = 1 - sign - sign;153 k = 1 - sign - sign;
157 }154 }
158155
...@@ -166,8 +163,7 @@ fn exp64(x_: f64) f64 {...@@ -166,8 +163,7 @@ fn exp64(x_: f64) f64 {
166 k = 0;163 k = 0;
167 hi = x;164 hi = x;
168 lo = 0;165 lo = 0;
169 }166 } else {
170 else {
171 // inexact if x != 0167 // inexact if x != 0
172 // math.forceEval(0x1.0p1023 + x);168 // math.forceEval(0x1.0p1023 + x);
173 return 1 + x;169 return 1 + x;
std/math/exp2.zig+140-140
...@@ -16,7 +16,7 @@ pub fn exp2(x: var) @typeOf(x) {...@@ -16,7 +16,7 @@ pub fn exp2(x: var) @typeOf(x) {
16 };16 };
17}17}
1818
19const exp2ft = []const f64 {19const exp2ft = []const f64{
20 0x1.6a09e667f3bcdp-1,20 0x1.6a09e667f3bcdp-1,
21 0x1.7a11473eb0187p-1,21 0x1.7a11473eb0187p-1,
22 0x1.8ace5422aa0dbp-1,22 0x1.8ace5422aa0dbp-1,
...@@ -92,195 +92,195 @@ fn exp2_32(x: f32) f32 {...@@ -92,195 +92,195 @@ fn exp2_32(x: f32) f32 {
92 return f32(r * uk);92 return f32(r * uk);
93}93}
9494
95const exp2dt = []f64 {95const exp2dt = []f64{
96 // exp2(z + eps) eps96 // exp2(z + eps) eps
97 0x1.6a09e667f3d5dp-1, 0x1.9880p-44,97 0x1.6a09e667f3d5dp-1, 0x1.9880p-44,
98 0x1.6b052fa751744p-1, 0x1.8000p-50,98 0x1.6b052fa751744p-1, 0x1.8000p-50,
99 0x1.6c012750bd9fep-1, -0x1.8780p-45,99 0x1.6c012750bd9fep-1, -0x1.8780p-45,
100 0x1.6cfdcddd476bfp-1, 0x1.ec00p-46,100 0x1.6cfdcddd476bfp-1, 0x1.ec00p-46,
101 0x1.6dfb23c651a29p-1, -0x1.8000p-50,101 0x1.6dfb23c651a29p-1, -0x1.8000p-50,
102 0x1.6ef9298593ae3p-1, -0x1.c000p-52,102 0x1.6ef9298593ae3p-1, -0x1.c000p-52,
103 0x1.6ff7df9519386p-1, -0x1.fd80p-45,103 0x1.6ff7df9519386p-1, -0x1.fd80p-45,
104 0x1.70f7466f42da3p-1, -0x1.c880p-45,104 0x1.70f7466f42da3p-1, -0x1.c880p-45,
105 0x1.71f75e8ec5fc3p-1, 0x1.3c00p-46,105 0x1.71f75e8ec5fc3p-1, 0x1.3c00p-46,
106 0x1.72f8286eacf05p-1, -0x1.8300p-44,106 0x1.72f8286eacf05p-1, -0x1.8300p-44,
107 0x1.73f9a48a58152p-1, -0x1.0c00p-47,107 0x1.73f9a48a58152p-1, -0x1.0c00p-47,
108 0x1.74fbd35d7ccfcp-1, 0x1.f880p-45,108 0x1.74fbd35d7ccfcp-1, 0x1.f880p-45,
109 0x1.75feb564267f1p-1, 0x1.3e00p-47,109 0x1.75feb564267f1p-1, 0x1.3e00p-47,
110 0x1.77024b1ab6d48p-1, -0x1.7d00p-45,110 0x1.77024b1ab6d48p-1, -0x1.7d00p-45,
111 0x1.780694fde5d38p-1, -0x1.d000p-50,111 0x1.780694fde5d38p-1, -0x1.d000p-50,
112 0x1.790b938ac1d00p-1, 0x1.3000p-49,112 0x1.790b938ac1d00p-1, 0x1.3000p-49,
113 0x1.7a11473eb0178p-1, -0x1.d000p-49,113 0x1.7a11473eb0178p-1, -0x1.d000p-49,
114 0x1.7b17b0976d060p-1, 0x1.0400p-45,114 0x1.7b17b0976d060p-1, 0x1.0400p-45,
115 0x1.7c1ed0130c133p-1, 0x1.0000p-53,115 0x1.7c1ed0130c133p-1, 0x1.0000p-53,
116 0x1.7d26a62ff8636p-1, -0x1.6900p-45,116 0x1.7d26a62ff8636p-1, -0x1.6900p-45,
117 0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47,117 0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47,
118 0x1.7f3878491c3e8p-1, -0x1.4580p-45,118 0x1.7f3878491c3e8p-1, -0x1.4580p-45,
119 0x1.80427543e1b4ep-1, 0x1.3000p-44,119 0x1.80427543e1b4ep-1, 0x1.3000p-44,
120 0x1.814d2add1071ap-1, 0x1.f000p-47,120 0x1.814d2add1071ap-1, 0x1.f000p-47,
121 0x1.82589994ccd7ep-1, -0x1.1c00p-45,121 0x1.82589994ccd7ep-1, -0x1.1c00p-45,
122 0x1.8364c1eb942d0p-1, 0x1.9d00p-45,122 0x1.8364c1eb942d0p-1, 0x1.9d00p-45,
123 0x1.8471a4623cab5p-1, 0x1.7100p-43,123 0x1.8471a4623cab5p-1, 0x1.7100p-43,
124 0x1.857f4179f5bbcp-1, 0x1.2600p-45,124 0x1.857f4179f5bbcp-1, 0x1.2600p-45,
125 0x1.868d99b4491afp-1, -0x1.2c40p-44,125 0x1.868d99b4491afp-1, -0x1.2c40p-44,
126 0x1.879cad931a395p-1, -0x1.3000p-45,126 0x1.879cad931a395p-1, -0x1.3000p-45,
127 0x1.88ac7d98a65b8p-1, -0x1.a800p-45,127 0x1.88ac7d98a65b8p-1, -0x1.a800p-45,
128 0x1.89bd0a4785800p-1, -0x1.d000p-49,128 0x1.89bd0a4785800p-1, -0x1.d000p-49,
129 0x1.8ace5422aa223p-1, 0x1.3280p-44,129 0x1.8ace5422aa223p-1, 0x1.3280p-44,
130 0x1.8be05bad619fap-1, 0x1.2b40p-43,130 0x1.8be05bad619fap-1, 0x1.2b40p-43,
131 0x1.8cf3216b54383p-1, -0x1.ed00p-45,131 0x1.8cf3216b54383p-1, -0x1.ed00p-45,
132 0x1.8e06a5e08664cp-1, -0x1.0500p-45,132 0x1.8e06a5e08664cp-1, -0x1.0500p-45,
133 0x1.8f1ae99157807p-1, 0x1.8280p-45,133 0x1.8f1ae99157807p-1, 0x1.8280p-45,
134 0x1.902fed0282c0ep-1, -0x1.cb00p-46,134 0x1.902fed0282c0ep-1, -0x1.cb00p-46,
135 0x1.9145b0b91ff96p-1, -0x1.5e00p-47,135 0x1.9145b0b91ff96p-1, -0x1.5e00p-47,
136 0x1.925c353aa2ff9p-1, 0x1.5400p-48,136 0x1.925c353aa2ff9p-1, 0x1.5400p-48,
137 0x1.93737b0cdc64ap-1, 0x1.7200p-46,137 0x1.93737b0cdc64ap-1, 0x1.7200p-46,
138 0x1.948b82b5f98aep-1, -0x1.9000p-47,138 0x1.948b82b5f98aep-1, -0x1.9000p-47,
139 0x1.95a44cbc852cbp-1, 0x1.5680p-45,139 0x1.95a44cbc852cbp-1, 0x1.5680p-45,
140 0x1.96bdd9a766f21p-1, -0x1.6d00p-44,140 0x1.96bdd9a766f21p-1, -0x1.6d00p-44,
141 0x1.97d829fde4e2ap-1, -0x1.1000p-47,141 0x1.97d829fde4e2ap-1, -0x1.1000p-47,
142 0x1.98f33e47a23a3p-1, 0x1.d000p-45,142 0x1.98f33e47a23a3p-1, 0x1.d000p-45,
143 0x1.9a0f170ca0604p-1, -0x1.8a40p-44,143 0x1.9a0f170ca0604p-1, -0x1.8a40p-44,
144 0x1.9b2bb4d53ff89p-1, 0x1.55c0p-44,144 0x1.9b2bb4d53ff89p-1, 0x1.55c0p-44,
145 0x1.9c49182a3f15bp-1, 0x1.6b80p-45,145 0x1.9c49182a3f15bp-1, 0x1.6b80p-45,
146 0x1.9d674194bb8c5p-1, -0x1.c000p-49,146 0x1.9d674194bb8c5p-1, -0x1.c000p-49,
147 0x1.9e86319e3238ep-1, 0x1.7d00p-46,147 0x1.9e86319e3238ep-1, 0x1.7d00p-46,
148 0x1.9fa5e8d07f302p-1, 0x1.6400p-46,148 0x1.9fa5e8d07f302p-1, 0x1.6400p-46,
149 0x1.a0c667b5de54dp-1, -0x1.5000p-48,149 0x1.a0c667b5de54dp-1, -0x1.5000p-48,
150 0x1.a1e7aed8eb8f6p-1, 0x1.9e00p-47,150 0x1.a1e7aed8eb8f6p-1, 0x1.9e00p-47,
151 0x1.a309bec4a2e27p-1, 0x1.ad80p-45,151 0x1.a309bec4a2e27p-1, 0x1.ad80p-45,
152 0x1.a42c980460a5dp-1, -0x1.af00p-46,152 0x1.a42c980460a5dp-1, -0x1.af00p-46,
153 0x1.a5503b23e259bp-1, 0x1.b600p-47,153 0x1.a5503b23e259bp-1, 0x1.b600p-47,
154 0x1.a674a8af46213p-1, 0x1.8880p-44,154 0x1.a674a8af46213p-1, 0x1.8880p-44,
155 0x1.a799e1330b3a7p-1, 0x1.1200p-46,155 0x1.a799e1330b3a7p-1, 0x1.1200p-46,
156 0x1.a8bfe53c12e8dp-1, 0x1.6c00p-47,156 0x1.a8bfe53c12e8dp-1, 0x1.6c00p-47,
157 0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45,157 0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45,
158 0x1.ab0e521356fb8p-1, 0x1.b700p-45,158 0x1.ab0e521356fb8p-1, 0x1.b700p-45,
159 0x1.ac36bbfd3f381p-1, 0x1.9000p-50,159 0x1.ac36bbfd3f381p-1, 0x1.9000p-50,
160 0x1.ad5ff3a3c2780p-1, 0x1.4000p-49,160 0x1.ad5ff3a3c2780p-1, 0x1.4000p-49,
161 0x1.ae89f995ad2a3p-1, -0x1.c900p-45,161 0x1.ae89f995ad2a3p-1, -0x1.c900p-45,
162 0x1.afb4ce622f367p-1, 0x1.6500p-46,162 0x1.afb4ce622f367p-1, 0x1.6500p-46,
163 0x1.b0e07298db790p-1, 0x1.fd40p-45,163 0x1.b0e07298db790p-1, 0x1.fd40p-45,
164 0x1.b20ce6c9a89a9p-1, 0x1.2700p-46,164 0x1.b20ce6c9a89a9p-1, 0x1.2700p-46,
165 0x1.b33a2b84f1a4bp-1, 0x1.d470p-43,165 0x1.b33a2b84f1a4bp-1, 0x1.d470p-43,
166 0x1.b468415b747e7p-1, -0x1.8380p-44,166 0x1.b468415b747e7p-1, -0x1.8380p-44,
167 0x1.b59728de5593ap-1, 0x1.8000p-54,167 0x1.b59728de5593ap-1, 0x1.8000p-54,
168 0x1.b6c6e29f1c56ap-1, 0x1.ad00p-47,168 0x1.b6c6e29f1c56ap-1, 0x1.ad00p-47,
169 0x1.b7f76f2fb5e50p-1, 0x1.e800p-50,169 0x1.b7f76f2fb5e50p-1, 0x1.e800p-50,
170 0x1.b928cf22749b2p-1, -0x1.4c00p-47,170 0x1.b928cf22749b2p-1, -0x1.4c00p-47,
171 0x1.ba5b030a10603p-1, -0x1.d700p-47,171 0x1.ba5b030a10603p-1, -0x1.d700p-47,
172 0x1.bb8e0b79a6f66p-1, 0x1.d900p-47,172 0x1.bb8e0b79a6f66p-1, 0x1.d900p-47,
173 0x1.bcc1e904bc1ffp-1, 0x1.2a00p-47,173 0x1.bcc1e904bc1ffp-1, 0x1.2a00p-47,
174 0x1.bdf69c3f3a16fp-1, -0x1.f780p-46,174 0x1.bdf69c3f3a16fp-1, -0x1.f780p-46,
175 0x1.bf2c25bd71db8p-1, -0x1.0a00p-46,175 0x1.bf2c25bd71db8p-1, -0x1.0a00p-46,
176 0x1.c06286141b2e9p-1, -0x1.1400p-46,176 0x1.c06286141b2e9p-1, -0x1.1400p-46,
177 0x1.c199bdd8552e0p-1, 0x1.be00p-47,177 0x1.c199bdd8552e0p-1, 0x1.be00p-47,
178 0x1.c2d1cd9fa64eep-1, -0x1.9400p-47,178 0x1.c2d1cd9fa64eep-1, -0x1.9400p-47,
179 0x1.c40ab5fffd02fp-1, -0x1.ed00p-47,179 0x1.c40ab5fffd02fp-1, -0x1.ed00p-47,
180 0x1.c544778fafd15p-1, 0x1.9660p-44,180 0x1.c544778fafd15p-1, 0x1.9660p-44,
181 0x1.c67f12e57d0cbp-1, -0x1.a100p-46,181 0x1.c67f12e57d0cbp-1, -0x1.a100p-46,
182 0x1.c7ba88988c1b6p-1, -0x1.8458p-42,182 0x1.c7ba88988c1b6p-1, -0x1.8458p-42,
183 0x1.c8f6d9406e733p-1, -0x1.a480p-46,183 0x1.c8f6d9406e733p-1, -0x1.a480p-46,
184 0x1.ca3405751c4dfp-1, 0x1.b000p-51,184 0x1.ca3405751c4dfp-1, 0x1.b000p-51,
185 0x1.cb720dcef9094p-1, 0x1.1400p-47,185 0x1.cb720dcef9094p-1, 0x1.1400p-47,
186 0x1.ccb0f2e6d1689p-1, 0x1.0200p-48,186 0x1.ccb0f2e6d1689p-1, 0x1.0200p-48,
187 0x1.cdf0b555dc412p-1, 0x1.3600p-48,187 0x1.cdf0b555dc412p-1, 0x1.3600p-48,
188 0x1.cf3155b5bab3bp-1, -0x1.6900p-47,188 0x1.cf3155b5bab3bp-1, -0x1.6900p-47,
189 0x1.d072d4a0789bcp-1, 0x1.9a00p-47,189 0x1.d072d4a0789bcp-1, 0x1.9a00p-47,
190 0x1.d1b532b08c8fap-1, -0x1.5e00p-46,190 0x1.d1b532b08c8fap-1, -0x1.5e00p-46,
191 0x1.d2f87080d8a85p-1, 0x1.d280p-46,191 0x1.d2f87080d8a85p-1, 0x1.d280p-46,
192 0x1.d43c8eacaa203p-1, 0x1.1a00p-47,192 0x1.d43c8eacaa203p-1, 0x1.1a00p-47,
193 0x1.d5818dcfba491p-1, 0x1.f000p-50,193 0x1.d5818dcfba491p-1, 0x1.f000p-50,
194 0x1.d6c76e862e6a1p-1, -0x1.3a00p-47,194 0x1.d6c76e862e6a1p-1, -0x1.3a00p-47,
195 0x1.d80e316c9834ep-1, -0x1.cd80p-47,195 0x1.d80e316c9834ep-1, -0x1.cd80p-47,
196 0x1.d955d71ff6090p-1, 0x1.4c00p-48,196 0x1.d955d71ff6090p-1, 0x1.4c00p-48,
197 0x1.da9e603db32aep-1, 0x1.f900p-48,197 0x1.da9e603db32aep-1, 0x1.f900p-48,
198 0x1.dbe7cd63a8325p-1, 0x1.9800p-49,198 0x1.dbe7cd63a8325p-1, 0x1.9800p-49,
199 0x1.dd321f301b445p-1, -0x1.5200p-48,199 0x1.dd321f301b445p-1, -0x1.5200p-48,
200 0x1.de7d5641c05bfp-1, -0x1.d700p-46,200 0x1.de7d5641c05bfp-1, -0x1.d700p-46,
201 0x1.dfc97337b9aecp-1, -0x1.6140p-46,201 0x1.dfc97337b9aecp-1, -0x1.6140p-46,
202 0x1.e11676b197d5ep-1, 0x1.b480p-47,202 0x1.e11676b197d5ep-1, 0x1.b480p-47,
203 0x1.e264614f5a3e7p-1, 0x1.0ce0p-43,203 0x1.e264614f5a3e7p-1, 0x1.0ce0p-43,
204 0x1.e3b333b16ee5cp-1, 0x1.c680p-47,204 0x1.e3b333b16ee5cp-1, 0x1.c680p-47,
205 0x1.e502ee78b3fb4p-1, -0x1.9300p-47,205 0x1.e502ee78b3fb4p-1, -0x1.9300p-47,
206 0x1.e653924676d68p-1, -0x1.5000p-49,206 0x1.e653924676d68p-1, -0x1.5000p-49,
207 0x1.e7a51fbc74c44p-1, -0x1.7f80p-47,207 0x1.e7a51fbc74c44p-1, -0x1.7f80p-47,
208 0x1.e8f7977cdb726p-1, -0x1.3700p-48,208 0x1.e8f7977cdb726p-1, -0x1.3700p-48,
209 0x1.ea4afa2a490e8p-1, 0x1.5d00p-49,209 0x1.ea4afa2a490e8p-1, 0x1.5d00p-49,
210 0x1.eb9f4867ccae4p-1, 0x1.61a0p-46,210 0x1.eb9f4867ccae4p-1, 0x1.61a0p-46,
211 0x1.ecf482d8e680dp-1, 0x1.5500p-48,211 0x1.ecf482d8e680dp-1, 0x1.5500p-48,
212 0x1.ee4aaa2188514p-1, 0x1.6400p-51,212 0x1.ee4aaa2188514p-1, 0x1.6400p-51,
213 0x1.efa1bee615a13p-1, -0x1.e800p-49,213 0x1.efa1bee615a13p-1, -0x1.e800p-49,
214 0x1.f0f9c1cb64106p-1, -0x1.a880p-48,214 0x1.f0f9c1cb64106p-1, -0x1.a880p-48,
215 0x1.f252b376bb963p-1, -0x1.c900p-45,215 0x1.f252b376bb963p-1, -0x1.c900p-45,
216 0x1.f3ac948dd7275p-1, 0x1.a000p-53,216 0x1.f3ac948dd7275p-1, 0x1.a000p-53,
217 0x1.f50765b6e4524p-1, -0x1.4f00p-48,217 0x1.f50765b6e4524p-1, -0x1.4f00p-48,
218 0x1.f6632798844fdp-1, 0x1.a800p-51,218 0x1.f6632798844fdp-1, 0x1.a800p-51,
219 0x1.f7bfdad9cbe38p-1, 0x1.abc0p-48,219 0x1.f7bfdad9cbe38p-1, 0x1.abc0p-48,
220 0x1.f91d802243c82p-1, -0x1.4600p-50,220 0x1.f91d802243c82p-1, -0x1.4600p-50,
221 0x1.fa7c1819e908ep-1, -0x1.b0c0p-47,221 0x1.fa7c1819e908ep-1, -0x1.b0c0p-47,
222 0x1.fbdba3692d511p-1, -0x1.0e00p-51,222 0x1.fbdba3692d511p-1, -0x1.0e00p-51,
223 0x1.fd3c22b8f7194p-1, -0x1.0de8p-46,223 0x1.fd3c22b8f7194p-1, -0x1.0de8p-46,
224 0x1.fe9d96b2a23eep-1, 0x1.e430p-49,224 0x1.fe9d96b2a23eep-1, 0x1.e430p-49,
225 0x1.0000000000000p+0, 0x0.0000p+0,225 0x1.0000000000000p+0, 0x0.0000p+0,
226 0x1.00b1afa5abcbep+0, -0x1.3400p-52,226 0x1.00b1afa5abcbep+0, -0x1.3400p-52,
227 0x1.0163da9fb3303p+0, -0x1.2170p-46,227 0x1.0163da9fb3303p+0, -0x1.2170p-46,
228 0x1.02168143b0282p+0, 0x1.a400p-52,228 0x1.02168143b0282p+0, 0x1.a400p-52,
229 0x1.02c9a3e77806cp+0, 0x1.f980p-49,229 0x1.02c9a3e77806cp+0, 0x1.f980p-49,
230 0x1.037d42e11bbcap+0, -0x1.7400p-51,230 0x1.037d42e11bbcap+0, -0x1.7400p-51,
231 0x1.04315e86e7f89p+0, 0x1.8300p-50,231 0x1.04315e86e7f89p+0, 0x1.8300p-50,
232 0x1.04e5f72f65467p+0, -0x1.a3f0p-46,232 0x1.04e5f72f65467p+0, -0x1.a3f0p-46,
233 0x1.059b0d315855ap+0, -0x1.2840p-47,233 0x1.059b0d315855ap+0, -0x1.2840p-47,
234 0x1.0650a0e3c1f95p+0, 0x1.1600p-48,234 0x1.0650a0e3c1f95p+0, 0x1.1600p-48,
235 0x1.0706b29ddf71ap+0, 0x1.5240p-46,235 0x1.0706b29ddf71ap+0, 0x1.5240p-46,
236 0x1.07bd42b72a82dp+0, -0x1.9a00p-49,236 0x1.07bd42b72a82dp+0, -0x1.9a00p-49,
237 0x1.0874518759bd0p+0, 0x1.6400p-49,237 0x1.0874518759bd0p+0, 0x1.6400p-49,
238 0x1.092bdf66607c8p+0, -0x1.0780p-47,238 0x1.092bdf66607c8p+0, -0x1.0780p-47,
239 0x1.09e3ecac6f383p+0, -0x1.8000p-54,239 0x1.09e3ecac6f383p+0, -0x1.8000p-54,
240 0x1.0a9c79b1f3930p+0, 0x1.fa00p-48,240 0x1.0a9c79b1f3930p+0, 0x1.fa00p-48,
241 0x1.0b5586cf988fcp+0, -0x1.ac80p-48,241 0x1.0b5586cf988fcp+0, -0x1.ac80p-48,
242 0x1.0c0f145e46c8ap+0, 0x1.9c00p-50,242 0x1.0c0f145e46c8ap+0, 0x1.9c00p-50,
243 0x1.0cc922b724816p+0, 0x1.5200p-47,243 0x1.0cc922b724816p+0, 0x1.5200p-47,
244 0x1.0d83b23395dd8p+0, -0x1.ad00p-48,244 0x1.0d83b23395dd8p+0, -0x1.ad00p-48,
245 0x1.0e3ec32d3d1f3p+0, 0x1.bac0p-46,245 0x1.0e3ec32d3d1f3p+0, 0x1.bac0p-46,
246 0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47,246 0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47,
247 0x1.0fb66affed2f0p+0, -0x1.d300p-47,247 0x1.0fb66affed2f0p+0, -0x1.d300p-47,
248 0x1.1073028d7234bp+0, 0x1.1500p-48,248 0x1.1073028d7234bp+0, 0x1.1500p-48,
249 0x1.11301d0125b5bp+0, 0x1.c000p-49,249 0x1.11301d0125b5bp+0, 0x1.c000p-49,
250 0x1.11edbab5e2af9p+0, 0x1.6bc0p-46,250 0x1.11edbab5e2af9p+0, 0x1.6bc0p-46,
251 0x1.12abdc06c31d5p+0, 0x1.8400p-49,251 0x1.12abdc06c31d5p+0, 0x1.8400p-49,
252 0x1.136a814f2047dp+0, -0x1.ed00p-47,252 0x1.136a814f2047dp+0, -0x1.ed00p-47,
253 0x1.1429aaea92de9p+0, 0x1.8e00p-49,253 0x1.1429aaea92de9p+0, 0x1.8e00p-49,
254 0x1.14e95934f3138p+0, 0x1.b400p-49,254 0x1.14e95934f3138p+0, 0x1.b400p-49,
255 0x1.15a98c8a58e71p+0, 0x1.5300p-47,255 0x1.15a98c8a58e71p+0, 0x1.5300p-47,
256 0x1.166a45471c3dfp+0, 0x1.3380p-47,256 0x1.166a45471c3dfp+0, 0x1.3380p-47,
257 0x1.172b83c7d5211p+0, 0x1.8d40p-45,257 0x1.172b83c7d5211p+0, 0x1.8d40p-45,
258 0x1.17ed48695bb9fp+0, -0x1.5d00p-47,258 0x1.17ed48695bb9fp+0, -0x1.5d00p-47,
259 0x1.18af9388c8d93p+0, -0x1.c880p-46,259 0x1.18af9388c8d93p+0, -0x1.c880p-46,
260 0x1.1972658375d66p+0, 0x1.1f00p-46,260 0x1.1972658375d66p+0, 0x1.1f00p-46,
261 0x1.1a35beb6fcba7p+0, 0x1.0480p-46,261 0x1.1a35beb6fcba7p+0, 0x1.0480p-46,
262 0x1.1af99f81387e3p+0, -0x1.7390p-43,262 0x1.1af99f81387e3p+0, -0x1.7390p-43,
263 0x1.1bbe084045d54p+0, 0x1.4e40p-45,263 0x1.1bbe084045d54p+0, 0x1.4e40p-45,
264 0x1.1c82f95281c43p+0, -0x1.a200p-47,264 0x1.1c82f95281c43p+0, -0x1.a200p-47,
265 0x1.1d4873168b9b2p+0, 0x1.3800p-49,265 0x1.1d4873168b9b2p+0, 0x1.3800p-49,
266 0x1.1e0e75eb44031p+0, 0x1.ac00p-49,266 0x1.1e0e75eb44031p+0, 0x1.ac00p-49,
267 0x1.1ed5022fcd938p+0, 0x1.1900p-47,267 0x1.1ed5022fcd938p+0, 0x1.1900p-47,
268 0x1.1f9c18438cdf7p+0, -0x1.b780p-46,268 0x1.1f9c18438cdf7p+0, -0x1.b780p-46,
269 0x1.2063b88628d8fp+0, 0x1.d940p-45,269 0x1.2063b88628d8fp+0, 0x1.d940p-45,
270 0x1.212be3578a81ep+0, 0x1.8000p-50,270 0x1.212be3578a81ep+0, 0x1.8000p-50,
271 0x1.21f49917ddd41p+0, 0x1.b340p-45,271 0x1.21f49917ddd41p+0, 0x1.b340p-45,
272 0x1.22bdda2791323p+0, 0x1.9f80p-46,272 0x1.22bdda2791323p+0, 0x1.9f80p-46,
273 0x1.2387a6e7561e7p+0, -0x1.9c80p-46,273 0x1.2387a6e7561e7p+0, -0x1.9c80p-46,
274 0x1.2451ffb821427p+0, 0x1.2300p-47,274 0x1.2451ffb821427p+0, 0x1.2300p-47,
275 0x1.251ce4fb2a602p+0, -0x1.3480p-46,275 0x1.251ce4fb2a602p+0, -0x1.3480p-46,
276 0x1.25e85711eceb0p+0, 0x1.2700p-46,276 0x1.25e85711eceb0p+0, 0x1.2700p-46,
277 0x1.26b4565e27d16p+0, 0x1.1d00p-46,277 0x1.26b4565e27d16p+0, 0x1.1d00p-46,
278 0x1.2780e341de00fp+0, 0x1.1ee0p-44,278 0x1.2780e341de00fp+0, 0x1.1ee0p-44,
279 0x1.284dfe1f5633ep+0, -0x1.4c00p-46,279 0x1.284dfe1f5633ep+0, -0x1.4c00p-46,
280 0x1.291ba7591bb30p+0, -0x1.3d80p-46,280 0x1.291ba7591bb30p+0, -0x1.3d80p-46,
281 0x1.29e9df51fdf09p+0, 0x1.8b00p-47,281 0x1.29e9df51fdf09p+0, 0x1.8b00p-47,
282 0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45,282 0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45,
283 0x1.2b87fd0dada3ap+0, 0x1.a340p-45,283 0x1.2b87fd0dada3ap+0, 0x1.a340p-45,
284 0x1.2c57e39771af9p+0, -0x1.0800p-46,284 0x1.2c57e39771af9p+0, -0x1.0800p-46,
285 0x1.2d285a6e402d9p+0, -0x1.ed00p-47,285 0x1.2d285a6e402d9p+0, -0x1.ed00p-47,
286 0x1.2df961f641579p+0, -0x1.4200p-48,286 0x1.2df961f641579p+0, -0x1.4200p-48,
...@@ -290,78 +290,78 @@ const exp2dt = []f64 {...@@ -290,78 +290,78 @@ const exp2dt = []f64 {
290 0x1.31432edeea50bp+0, -0x1.0df8p-40,290 0x1.31432edeea50bp+0, -0x1.0df8p-40,
291 0x1.32170fc4cd7b8p+0, -0x1.2480p-45,291 0x1.32170fc4cd7b8p+0, -0x1.2480p-45,
292 0x1.32eb83ba8e9a2p+0, -0x1.5980p-45,292 0x1.32eb83ba8e9a2p+0, -0x1.5980p-45,
293 0x1.33c08b2641766p+0, 0x1.ed00p-46,293 0x1.33c08b2641766p+0, 0x1.ed00p-46,
294 0x1.3496266e3fa27p+0, -0x1.c000p-50,294 0x1.3496266e3fa27p+0, -0x1.c000p-50,
295 0x1.356c55f929f0fp+0, -0x1.0d80p-44,295 0x1.356c55f929f0fp+0, -0x1.0d80p-44,
296 0x1.36431a2de88b9p+0, 0x1.2c80p-45,296 0x1.36431a2de88b9p+0, 0x1.2c80p-45,
297 0x1.371a7373aaa39p+0, 0x1.0600p-45,297 0x1.371a7373aaa39p+0, 0x1.0600p-45,
298 0x1.37f26231e74fep+0, -0x1.6600p-46,298 0x1.37f26231e74fep+0, -0x1.6600p-46,
299 0x1.38cae6d05d838p+0, -0x1.ae00p-47,299 0x1.38cae6d05d838p+0, -0x1.ae00p-47,
300 0x1.39a401b713ec3p+0, -0x1.4720p-43,300 0x1.39a401b713ec3p+0, -0x1.4720p-43,
301 0x1.3a7db34e5a020p+0, 0x1.8200p-47,301 0x1.3a7db34e5a020p+0, 0x1.8200p-47,
302 0x1.3b57fbfec6e95p+0, 0x1.e800p-44,302 0x1.3b57fbfec6e95p+0, 0x1.e800p-44,
303 0x1.3c32dc313a8f2p+0, 0x1.f800p-49,303 0x1.3c32dc313a8f2p+0, 0x1.f800p-49,
304 0x1.3d0e544ede122p+0, -0x1.7a00p-46,304 0x1.3d0e544ede122p+0, -0x1.7a00p-46,
305 0x1.3dea64c1234bbp+0, 0x1.6300p-45,305 0x1.3dea64c1234bbp+0, 0x1.6300p-45,
306 0x1.3ec70df1c4eccp+0, -0x1.8a60p-43,306 0x1.3ec70df1c4eccp+0, -0x1.8a60p-43,
307 0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44,307 0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44,
308 0x1.40822c367a0bbp+0, 0x1.5b80p-45,308 0x1.40822c367a0bbp+0, 0x1.5b80p-45,
309 0x1.4160a21f72e95p+0, 0x1.ec00p-46,309 0x1.4160a21f72e95p+0, 0x1.ec00p-46,
310 0x1.423fb27094646p+0, -0x1.3600p-46,310 0x1.423fb27094646p+0, -0x1.3600p-46,
311 0x1.431f5d950a920p+0, 0x1.3980p-45,311 0x1.431f5d950a920p+0, 0x1.3980p-45,
312 0x1.43ffa3f84b9ebp+0, 0x1.a000p-48,312 0x1.43ffa3f84b9ebp+0, 0x1.a000p-48,
313 0x1.44e0860618919p+0, -0x1.6c00p-48,313 0x1.44e0860618919p+0, -0x1.6c00p-48,
314 0x1.45c2042a7d201p+0, -0x1.bc00p-47,314 0x1.45c2042a7d201p+0, -0x1.bc00p-47,
315 0x1.46a41ed1d0016p+0, -0x1.2800p-46,315 0x1.46a41ed1d0016p+0, -0x1.2800p-46,
316 0x1.4786d668b3326p+0, 0x1.0e00p-44,316 0x1.4786d668b3326p+0, 0x1.0e00p-44,
317 0x1.486a2b5c13c00p+0, -0x1.d400p-45,317 0x1.486a2b5c13c00p+0, -0x1.d400p-45,
318 0x1.494e1e192af04p+0, 0x1.c200p-47,318 0x1.494e1e192af04p+0, 0x1.c200p-47,
319 0x1.4a32af0d7d372p+0, -0x1.e500p-46,319 0x1.4a32af0d7d372p+0, -0x1.e500p-46,
320 0x1.4b17dea6db801p+0, 0x1.7800p-47,320 0x1.4b17dea6db801p+0, 0x1.7800p-47,
321 0x1.4bfdad53629e1p+0, -0x1.3800p-46,321 0x1.4bfdad53629e1p+0, -0x1.3800p-46,
322 0x1.4ce41b817c132p+0, 0x1.0800p-47,322 0x1.4ce41b817c132p+0, 0x1.0800p-47,
323 0x1.4dcb299fddddbp+0, 0x1.c700p-45,323 0x1.4dcb299fddddbp+0, 0x1.c700p-45,
324 0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46,324 0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46,
325 0x1.4f9b2769d2d02p+0, 0x1.9200p-46,325 0x1.4f9b2769d2d02p+0, 0x1.9200p-46,
326 0x1.508417f4531c1p+0, -0x1.8c00p-47,326 0x1.508417f4531c1p+0, -0x1.8c00p-47,
327 0x1.516daa2cf662ap+0, -0x1.a000p-48,327 0x1.516daa2cf662ap+0, -0x1.a000p-48,
328 0x1.5257de83f51eap+0, 0x1.a080p-43,328 0x1.5257de83f51eap+0, 0x1.a080p-43,
329 0x1.5342b569d4edap+0, -0x1.6d80p-45,329 0x1.5342b569d4edap+0, -0x1.6d80p-45,
330 0x1.542e2f4f6ac1ap+0, -0x1.2440p-44,330 0x1.542e2f4f6ac1ap+0, -0x1.2440p-44,
331 0x1.551a4ca5d94dbp+0, 0x1.83c0p-43,331 0x1.551a4ca5d94dbp+0, 0x1.83c0p-43,
332 0x1.56070dde9116bp+0, 0x1.4b00p-45,332 0x1.56070dde9116bp+0, 0x1.4b00p-45,
333 0x1.56f4736b529dep+0, 0x1.15a0p-43,333 0x1.56f4736b529dep+0, 0x1.15a0p-43,
334 0x1.57e27dbe2c40ep+0, -0x1.9e00p-45,334 0x1.57e27dbe2c40ep+0, -0x1.9e00p-45,
335 0x1.58d12d497c76fp+0, -0x1.3080p-45,335 0x1.58d12d497c76fp+0, -0x1.3080p-45,
336 0x1.59c0827ff0b4cp+0, 0x1.dec0p-43,336 0x1.59c0827ff0b4cp+0, 0x1.dec0p-43,
337 0x1.5ab07dd485427p+0, -0x1.4000p-51,337 0x1.5ab07dd485427p+0, -0x1.4000p-51,
338 0x1.5ba11fba87af4p+0, 0x1.0080p-44,338 0x1.5ba11fba87af4p+0, 0x1.0080p-44,
339 0x1.5c9268a59460bp+0, -0x1.6c80p-45,339 0x1.5c9268a59460bp+0, -0x1.6c80p-45,
340 0x1.5d84590998e3fp+0, 0x1.69a0p-43,340 0x1.5d84590998e3fp+0, 0x1.69a0p-43,
341 0x1.5e76f15ad20e1p+0, -0x1.b400p-46,341 0x1.5e76f15ad20e1p+0, -0x1.b400p-46,
342 0x1.5f6a320dcebcap+0, 0x1.7700p-46,342 0x1.5f6a320dcebcap+0, 0x1.7700p-46,
343 0x1.605e1b976dcb8p+0, 0x1.6f80p-45,343 0x1.605e1b976dcb8p+0, 0x1.6f80p-45,
344 0x1.6152ae6cdf715p+0, 0x1.1000p-47,344 0x1.6152ae6cdf715p+0, 0x1.1000p-47,
345 0x1.6247eb03a5531p+0, -0x1.5d00p-46,345 0x1.6247eb03a5531p+0, -0x1.5d00p-46,
346 0x1.633dd1d1929b5p+0, -0x1.2d00p-46,346 0x1.633dd1d1929b5p+0, -0x1.2d00p-46,
347 0x1.6434634ccc313p+0, -0x1.a800p-49,347 0x1.6434634ccc313p+0, -0x1.a800p-49,
348 0x1.652b9febc8efap+0, -0x1.8600p-45,348 0x1.652b9febc8efap+0, -0x1.8600p-45,
349 0x1.6623882553397p+0, 0x1.1fe0p-40,349 0x1.6623882553397p+0, 0x1.1fe0p-40,
350 0x1.671c1c708328ep+0, -0x1.7200p-44,350 0x1.671c1c708328ep+0, -0x1.7200p-44,
351 0x1.68155d44ca97ep+0, 0x1.6800p-49,351 0x1.68155d44ca97ep+0, 0x1.6800p-49,
352 0x1.690f4b19e9471p+0, -0x1.9780p-45,352 0x1.690f4b19e9471p+0, -0x1.9780p-45,
353};353};
354354
355fn exp2_64(x: f64) f64 {355fn exp2_64(x: f64) f64 {
356 @setFloatMode(this, @import("builtin").FloatMode.Strict);356 @setFloatMode(this, @import("builtin").FloatMode.Strict);
357357
358 const tblsiz = u32(exp2dt.len / 2);358 const tblsiz = u32(exp2dt.len / 2);
359 const redux: f64 = 0x1.8p52 / f64(tblsiz);359 const redux: f64 = 0x1.8p52 / f64(tblsiz);
360 const P1: f64 = 0x1.62e42fefa39efp-1;360 const P1: f64 = 0x1.62e42fefa39efp-1;
361 const P2: f64 = 0x1.ebfbdff82c575p-3;361 const P2: f64 = 0x1.ebfbdff82c575p-3;
362 const P3: f64 = 0x1.c6b08d704a0a6p-5;362 const P3: f64 = 0x1.c6b08d704a0a6p-5;
363 const P4: f64 = 0x1.3b2ab88f70400p-7;363 const P4: f64 = 0x1.3b2ab88f70400p-7;
364 const P5: f64 = 0x1.5d88003875c74p-10;364 const P5: f64 = 0x1.5d88003875c74p-10;
365365
366 const ux = @bitCast(u64, x);366 const ux = @bitCast(u64, x);
367 const ix = u32(ux >> 32) & 0x7FFFFFFF;367 const ix = u32(ux >> 32) & 0x7FFFFFFF;
std/math/expm1.zig+11-13
...@@ -21,11 +21,11 @@ pub fn expm1(x: var) @typeOf(x) {...@@ -21,11 +21,11 @@ pub fn expm1(x: var) @typeOf(x) {
21fn expm1_32(x_: f32) f32 {21fn expm1_32(x_: f32) f32 {
22 @setFloatMode(this, builtin.FloatMode.Strict);22 @setFloatMode(this, builtin.FloatMode.Strict);
23 const o_threshold: f32 = 8.8721679688e+01;23 const o_threshold: f32 = 8.8721679688e+01;
24 const ln2_hi: f32 = 6.9313812256e-01;24 const ln2_hi: f32 = 6.9313812256e-01;
25 const ln2_lo: f32 = 9.0580006145e-06;25 const ln2_lo: f32 = 9.0580006145e-06;
26 const invln2: f32 = 1.4426950216e+00;26 const invln2: f32 = 1.4426950216e+00;
27 const Q1: f32 = -3.3333212137e-2;27 const Q1: f32 = -3.3333212137e-2;
28 const Q2: f32 = 1.5807170421e-3;28 const Q2: f32 = 1.5807170421e-3;
2929
30 var x = x_;30 var x = x_;
31 const ux = @bitCast(u32, x);31 const ux = @bitCast(u32, x);
...@@ -93,8 +93,7 @@ fn expm1_32(x_: f32) f32 {...@@ -93,8 +93,7 @@ fn expm1_32(x_: f32) f32 {
93 math.forceEval(x * x);93 math.forceEval(x * x);
94 }94 }
95 return x;95 return x;
96 }96 } else {
97 else {
98 k = 0;97 k = 0;
99 }98 }
10099
...@@ -148,13 +147,13 @@ fn expm1_32(x_: f32) f32 {...@@ -148,13 +147,13 @@ fn expm1_32(x_: f32) f32 {
148fn expm1_64(x_: f64) f64 {147fn expm1_64(x_: f64) f64 {
149 @setFloatMode(this, builtin.FloatMode.Strict);148 @setFloatMode(this, builtin.FloatMode.Strict);
150 const o_threshold: f64 = 7.09782712893383973096e+02;149 const o_threshold: f64 = 7.09782712893383973096e+02;
151 const ln2_hi: f64 = 6.93147180369123816490e-01;150 const ln2_hi: f64 = 6.93147180369123816490e-01;
152 const ln2_lo: f64 = 1.90821492927058770002e-10;151 const ln2_lo: f64 = 1.90821492927058770002e-10;
153 const invln2: f64 = 1.44269504088896338700e+00;152 const invln2: f64 = 1.44269504088896338700e+00;
154 const Q1: f64 = -3.33333333333331316428e-02;153 const Q1: f64 = -3.33333333333331316428e-02;
155 const Q2: f64 = 1.58730158725481460165e-03;154 const Q2: f64 = 1.58730158725481460165e-03;
156 const Q3: f64 = -7.93650757867487942473e-05;155 const Q3: f64 = -7.93650757867487942473e-05;
157 const Q4: f64 = 4.00821782732936239552e-06;156 const Q4: f64 = 4.00821782732936239552e-06;
158 const Q5: f64 = -2.01099218183624371326e-07;157 const Q5: f64 = -2.01099218183624371326e-07;
159158
160 var x = x_;159 var x = x_;
...@@ -223,8 +222,7 @@ fn expm1_64(x_: f64) f64 {...@@ -223,8 +222,7 @@ fn expm1_64(x_: f64) f64 {
223 math.forceEval(f32(x));222 math.forceEval(f32(x));
224 }223 }
225 return x;224 return x;
226 }225 } else {
227 else {
228 k = 0;226 k = 0;
229 }227 }
230228
std/math/floor.zig+2-2
...@@ -57,7 +57,7 @@ fn floor64(x: f64) f64 {...@@ -57,7 +57,7 @@ fn floor64(x: f64) f64 {
57 const e = (u >> 52) & 0x7FF;57 const e = (u >> 52) & 0x7FF;
58 var y: f64 = undefined;58 var y: f64 = undefined;
5959
60 if (e >= 0x3FF+52 or x == 0) {60 if (e >= 0x3FF + 52 or x == 0) {
61 return x;61 return x;
62 }62 }
6363
...@@ -69,7 +69,7 @@ fn floor64(x: f64) f64 {...@@ -69,7 +69,7 @@ fn floor64(x: f64) f64 {
69 y = x + math.f64_toint - math.f64_toint - x;69 y = x + math.f64_toint - math.f64_toint - x;
70 }70 }
7171
72 if (e <= 0x3FF-1) {72 if (e <= 0x3FF - 1) {
73 math.forceEval(y);73 math.forceEval(y);
74 if (u >> 63 != 0) {74 if (u >> 63 != 0) {
75 return -1.0;75 return -1.0;
std/math/fma.zig+5-2
...@@ -5,7 +5,7 @@ const assert = std.debug.assert;...@@ -5,7 +5,7 @@ const assert = std.debug.assert;
5pub fn fma(comptime T: type, x: T, y: T, z: T) T {5pub fn fma(comptime T: type, x: T, y: T, z: T) T {
6 return switch (T) {6 return switch (T) {
7 f32 => fma32(x, y, z),7 f32 => fma32(x, y, z),
8 f64 => fma64(x, y ,z),8 f64 => fma64(x, y, z),
9 else => @compileError("fma not implemented for " ++ @typeName(T)),9 else => @compileError("fma not implemented for " ++ @typeName(T)),
10 };10 };
11}11}
...@@ -71,7 +71,10 @@ fn fma64(x: f64, y: f64, z: f64) f64 {...@@ -71,7 +71,10 @@ fn fma64(x: f64, y: f64, z: f64) f64 {
71 }71 }
72}72}
7373
74const dd = struct { hi: f64, lo: f64, };74const dd = struct {
75 hi: f64,
76 lo: f64,
77};
7578
76fn dd_add(a: f64, b: f64) dd {79fn dd_add(a: f64, b: f64) dd {
77 var ret: dd = undefined;80 var ret: dd = undefined;
std/math/hypot.zig+4-4
...@@ -39,11 +39,11 @@ fn hypot32(x: f32, y: f32) f32 {...@@ -39,11 +39,11 @@ fn hypot32(x: f32, y: f32) f32 {
39 }39 }
4040
41 var z: f32 = 1.0;41 var z: f32 = 1.0;
42 if (ux >= (0x7F+60) << 23) {42 if (ux >= (0x7F + 60) << 23) {
43 z = 0x1.0p90;43 z = 0x1.0p90;
44 xx *= 0x1.0p-90;44 xx *= 0x1.0p-90;
45 yy *= 0x1.0p-90;45 yy *= 0x1.0p-90;
46 } else if (uy < (0x7F-60) << 23) {46 } else if (uy < (0x7F - 60) << 23) {
47 z = 0x1.0p-90;47 z = 0x1.0p-90;
48 xx *= 0x1.0p-90;48 xx *= 0x1.0p-90;
49 yy *= 0x1.0p-90;49 yy *= 0x1.0p-90;
...@@ -57,8 +57,8 @@ fn sq(hi: &f64, lo: &f64, x: f64) void {...@@ -57,8 +57,8 @@ fn sq(hi: &f64, lo: &f64, x: f64) void {
57 const xc = x * split;57 const xc = x * split;
58 const xh = x - xc + xc;58 const xh = x - xc + xc;
59 const xl = x - xh;59 const xl = x - xh;
60 *hi = x * x;60 hi.* = x * x;
61 *lo = xh * xh - *hi + 2 * xh * xl + xl * xl;61 lo.* = xh * xh - hi.* + 2 * xh * xl + xl * xl;
62}62}
6363
64fn hypot64(x: f64, y: f64) f64 {64fn hypot64(x: f64, y: f64) f64 {
std/math/index.zig+30-47
...@@ -47,12 +47,12 @@ pub fn forceEval(value: var) void {...@@ -47,12 +47,12 @@ pub fn forceEval(value: var) void {
47 f32 => {47 f32 => {
48 var x: f32 = undefined;48 var x: f32 = undefined;
49 const p = @ptrCast(&volatile f32, &x);49 const p = @ptrCast(&volatile f32, &x);
50 *p = x;50 p.* = x;
51 },51 },
52 f64 => {52 f64 => {
53 var x: f64 = undefined;53 var x: f64 = undefined;
54 const p = @ptrCast(&volatile f64, &x);54 const p = @ptrCast(&volatile f64, &x);
55 *p = x;55 p.* = x;
56 },56 },
57 else => {57 else => {
58 @compileError("forceEval not implemented for " ++ @typeName(T));58 @compileError("forceEval not implemented for " ++ @typeName(T));
...@@ -179,7 +179,6 @@ test "math" {...@@ -179,7 +179,6 @@ test "math" {
179 _ = @import("complex/index.zig");179 _ = @import("complex/index.zig");
180}180}
181181
182
183pub fn min(x: var, y: var) @typeOf(x + y) {182pub fn min(x: var, y: var) @typeOf(x + y) {
184 return if (x < y) x else y;183 return if (x < y) x else y;
185}184}
...@@ -280,10 +279,10 @@ pub fn rotr(comptime T: type, x: T, r: var) T {...@@ -280,10 +279,10 @@ pub fn rotr(comptime T: type, x: T, r: var) T {
280}279}
281280
282test "math.rotr" {281test "math.rotr" {
283 assert(rotr(u8, 0b00000001, usize(0)) == 0b00000001);282 assert(rotr(u8, 0b00000001, usize(0)) == 0b00000001);
284 assert(rotr(u8, 0b00000001, usize(9)) == 0b10000000);283 assert(rotr(u8, 0b00000001, usize(9)) == 0b10000000);
285 assert(rotr(u8, 0b00000001, usize(8)) == 0b00000001);284 assert(rotr(u8, 0b00000001, usize(8)) == 0b00000001);
286 assert(rotr(u8, 0b00000001, usize(4)) == 0b00010000);285 assert(rotr(u8, 0b00000001, usize(4)) == 0b00010000);
287 assert(rotr(u8, 0b00000001, isize(-1)) == 0b00000010);286 assert(rotr(u8, 0b00000001, isize(-1)) == 0b00000010);
288}287}
289288
...@@ -299,14 +298,13 @@ pub fn rotl(comptime T: type, x: T, r: var) T {...@@ -299,14 +298,13 @@ pub fn rotl(comptime T: type, x: T, r: var) T {
299}298}
300299
301test "math.rotl" {300test "math.rotl" {
302 assert(rotl(u8, 0b00000001, usize(0)) == 0b00000001);301 assert(rotl(u8, 0b00000001, usize(0)) == 0b00000001);
303 assert(rotl(u8, 0b00000001, usize(9)) == 0b00000010);302 assert(rotl(u8, 0b00000001, usize(9)) == 0b00000010);
304 assert(rotl(u8, 0b00000001, usize(8)) == 0b00000001);303 assert(rotl(u8, 0b00000001, usize(8)) == 0b00000001);
305 assert(rotl(u8, 0b00000001, usize(4)) == 0b00010000);304 assert(rotl(u8, 0b00000001, usize(4)) == 0b00010000);
306 assert(rotl(u8, 0b00000001, isize(-1)) == 0b10000000);305 assert(rotl(u8, 0b00000001, isize(-1)) == 0b10000000);
307}306}
308307
309
310pub fn Log2Int(comptime T: type) type {308pub fn Log2Int(comptime T: type) type {
311 return @IntType(false, log2(T.bit_count));309 return @IntType(false, log2(T.bit_count));
312}310}
...@@ -323,14 +321,14 @@ fn testOverflow() void {...@@ -323,14 +321,14 @@ fn testOverflow() void {
323 assert((shlExact(i32, 0b11, 4) catch unreachable) == 0b110000);321 assert((shlExact(i32, 0b11, 4) catch unreachable) == 0b110000);
324}322}
325323
326
327pub fn absInt(x: var) !@typeOf(x) {324pub fn absInt(x: var) !@typeOf(x) {
328 const T = @typeOf(x);325 const T = @typeOf(x);
329 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt326 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
330 comptime assert(T.is_signed); // must pass a signed integer to absInt327 comptime assert(T.is_signed); // must pass a signed integer to absInt
331 if (x == @minValue(@typeOf(x)))328
329 if (x == @minValue(@typeOf(x))) {
332 return error.Overflow;330 return error.Overflow;
333 {331 } else {
334 @setRuntimeSafety(false);332 @setRuntimeSafety(false);
335 return if (x < 0) -x else x;333 return if (x < 0) -x else x;
336 }334 }
...@@ -349,10 +347,8 @@ pub const absFloat = @import("fabs.zig").fabs;...@@ -349,10 +347,8 @@ pub const absFloat = @import("fabs.zig").fabs;
349347
350pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {348pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {
351 @setRuntimeSafety(false);349 @setRuntimeSafety(false);
352 if (denominator == 0)350 if (denominator == 0) return error.DivisionByZero;
353 return error.DivisionByZero;351 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) return error.Overflow;
354 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
355 return error.Overflow;
356 return @divTrunc(numerator, denominator);352 return @divTrunc(numerator, denominator);
357}353}
358354
...@@ -372,10 +368,8 @@ fn testDivTrunc() void {...@@ -372,10 +368,8 @@ fn testDivTrunc() void {
372368
373pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {369pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {
374 @setRuntimeSafety(false);370 @setRuntimeSafety(false);
375 if (denominator == 0)371 if (denominator == 0) return error.DivisionByZero;
376 return error.DivisionByZero;372 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) return error.Overflow;
377 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
378 return error.Overflow;
379 return @divFloor(numerator, denominator);373 return @divFloor(numerator, denominator);
380}374}
381375
...@@ -395,13 +389,10 @@ fn testDivFloor() void {...@@ -395,13 +389,10 @@ fn testDivFloor() void {
395389
396pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {390pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {
397 @setRuntimeSafety(false);391 @setRuntimeSafety(false);
398 if (denominator == 0)392 if (denominator == 0) return error.DivisionByZero;
399 return error.DivisionByZero;393 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) return error.Overflow;
400 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
401 return error.Overflow;
402 const result = @divTrunc(numerator, denominator);394 const result = @divTrunc(numerator, denominator);
403 if (result * denominator != numerator)395 if (result * denominator != numerator) return error.UnexpectedRemainder;
404 return error.UnexpectedRemainder;
405 return result;396 return result;
406}397}
407398
...@@ -423,10 +414,8 @@ fn testDivExact() void {...@@ -423,10 +414,8 @@ fn testDivExact() void {
423414
424pub fn mod(comptime T: type, numerator: T, denominator: T) !T {415pub fn mod(comptime T: type, numerator: T, denominator: T) !T {
425 @setRuntimeSafety(false);416 @setRuntimeSafety(false);
426 if (denominator == 0)417 if (denominator == 0) return error.DivisionByZero;
427 return error.DivisionByZero;418 if (denominator < 0) return error.NegativeDenominator;
428 if (denominator < 0)
429 return error.NegativeDenominator;
430 return @mod(numerator, denominator);419 return @mod(numerator, denominator);
431}420}
432421
...@@ -448,10 +437,8 @@ fn testMod() void {...@@ -448,10 +437,8 @@ fn testMod() void {
448437
449pub fn rem(comptime T: type, numerator: T, denominator: T) !T {438pub fn rem(comptime T: type, numerator: T, denominator: T) !T {
450 @setRuntimeSafety(false);439 @setRuntimeSafety(false);
451 if (denominator == 0)440 if (denominator == 0) return error.DivisionByZero;
452 return error.DivisionByZero;441 if (denominator < 0) return error.NegativeDenominator;
453 if (denominator < 0)
454 return error.NegativeDenominator;
455 return @rem(numerator, denominator);442 return @rem(numerator, denominator);
456}443}
457444
...@@ -475,8 +462,7 @@ fn testRem() void {...@@ -475,8 +462,7 @@ fn testRem() void {
475/// Result is an unsigned integer.462/// Result is an unsigned integer.
476pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) {463pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) {
477 const uint = @IntType(false, @typeOf(x).bit_count);464 const uint = @IntType(false, @typeOf(x).bit_count);
478 if (x >= 0)465 if (x >= 0) return uint(x);
479 return uint(x);
480466
481 return uint(-(x + 1)) + 1;467 return uint(-(x + 1)) + 1;
482}468}
...@@ -495,15 +481,12 @@ test "math.absCast" {...@@ -495,15 +481,12 @@ test "math.absCast" {
495/// Returns the negation of the integer parameter.481/// Returns the negation of the integer parameter.
496/// Result is a signed integer.482/// Result is a signed integer.
497pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {483pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {
498 if (@typeOf(x).is_signed)484 if (@typeOf(x).is_signed) return negate(x);
499 return negate(x);
500485
501 const int = @IntType(true, @typeOf(x).bit_count);486 const int = @IntType(true, @typeOf(x).bit_count);
502 if (x > -@minValue(int))487 if (x > -@minValue(int)) return error.Overflow;
503 return error.Overflow;
504488
505 if (x == -@minValue(int))489 if (x == -@minValue(int)) return @minValue(int);
506 return @minValue(int);
507490
508 return -int(x);491 return -int(x);
509}492}
...@@ -518,7 +501,7 @@ test "math.negateCast" {...@@ -518,7 +501,7 @@ test "math.negateCast" {
518 if (negateCast(u32(@maxValue(i32) + 10))) |_| unreachable else |err| assert(err == error.Overflow);501 if (negateCast(u32(@maxValue(i32) + 10))) |_| unreachable else |err| assert(err == error.Overflow);
519}502}
520503
521/// Cast an integer to a different integer type. If the value doesn't fit, 504/// Cast an integer to a different integer type. If the value doesn't fit,
522/// return an error.505/// return an error.
523pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {506pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {
524 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer507 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer
...@@ -546,7 +529,7 @@ pub fn floorPowerOfTwo(comptime T: type, value: T) T {...@@ -546,7 +529,7 @@ pub fn floorPowerOfTwo(comptime T: type, value: T) T {
546 var x = value;529 var x = value;
547530
548 comptime var i = 1;531 comptime var i = 1;
549 inline while(T.bit_count > i) : (i *= 2) {532 inline while (T.bit_count > i) : (i *= 2) {
550 x |= (x >> i);533 x |= (x >> i);
551 }534 }
552535
std/math/ln.zig+2-4
...@@ -120,11 +120,9 @@ pub fn ln_64(x_: f64) f64 {...@@ -120,11 +120,9 @@ pub fn ln_64(x_: f64) f64 {
120 k -= 54;120 k -= 54;
121 x *= 0x1.0p54;121 x *= 0x1.0p54;
122 hx = u32(@bitCast(u64, ix) >> 32);122 hx = u32(@bitCast(u64, ix) >> 32);
123 }123 } else if (hx >= 0x7FF00000) {
124 else if (hx >= 0x7FF00000) {
125 return x;124 return x;
126 }125 } else if (hx == 0x3FF00000 and ix << 32 == 0) {
127 else if (hx == 0x3FF00000 and ix << 32 == 0) {
128 return 0;126 return 0;
129 }127 }
130128
std/math/log10.zig+8-10
...@@ -35,10 +35,10 @@ pub fn log10(x: var) @typeOf(x) {...@@ -35,10 +35,10 @@ pub fn log10(x: var) @typeOf(x) {
35}35}
3636
37pub fn log10_32(x_: f32) f32 {37pub fn log10_32(x_: f32) f32 {
38 const ivln10hi: f32 = 4.3432617188e-01;38 const ivln10hi: f32 = 4.3432617188e-01;
39 const ivln10lo: f32 = -3.1689971365e-05;39 const ivln10lo: f32 = -3.1689971365e-05;
40 const log10_2hi: f32 = 3.0102920532e-01;40 const log10_2hi: f32 = 3.0102920532e-01;
41 const log10_2lo: f32 = 7.9034151668e-07;41 const log10_2lo: f32 = 7.9034151668e-07;
42 const Lg1: f32 = 0xaaaaaa.0p-24;42 const Lg1: f32 = 0xaaaaaa.0p-24;
43 const Lg2: f32 = 0xccce13.0p-25;43 const Lg2: f32 = 0xccce13.0p-25;
44 const Lg3: f32 = 0x91e9ee.0p-25;44 const Lg3: f32 = 0x91e9ee.0p-25;
...@@ -95,8 +95,8 @@ pub fn log10_32(x_: f32) f32 {...@@ -95,8 +95,8 @@ pub fn log10_32(x_: f32) f32 {
95}95}
9696
97pub fn log10_64(x_: f64) f64 {97pub fn log10_64(x_: f64) f64 {
98 const ivln10hi: f64 = 4.34294481878168880939e-01;98 const ivln10hi: f64 = 4.34294481878168880939e-01;
99 const ivln10lo: f64 = 2.50829467116452752298e-11;99 const ivln10lo: f64 = 2.50829467116452752298e-11;
100 const log10_2hi: f64 = 3.01029995663611771306e-01;100 const log10_2hi: f64 = 3.01029995663611771306e-01;
101 const log10_2lo: f64 = 3.69423907715893078616e-13;101 const log10_2lo: f64 = 3.69423907715893078616e-13;
102 const Lg1: f64 = 6.666666666666735130e-01;102 const Lg1: f64 = 6.666666666666735130e-01;
...@@ -126,11 +126,9 @@ pub fn log10_64(x_: f64) f64 {...@@ -126,11 +126,9 @@ pub fn log10_64(x_: f64) f64 {
126 k -= 54;126 k -= 54;
127 x *= 0x1.0p54;127 x *= 0x1.0p54;
128 hx = u32(@bitCast(u64, x) >> 32);128 hx = u32(@bitCast(u64, x) >> 32);
129 }129 } else if (hx >= 0x7FF00000) {
130 else if (hx >= 0x7FF00000) {
131 return x;130 return x;
132 }131 } else if (hx == 0x3FF00000 and ix << 32 == 0) {
133 else if (hx == 0x3FF00000 and ix << 32 == 0) {
134 return 0;132 return 0;
135 }133 }
136134
std/math/log1p.zig+1-2
...@@ -138,8 +138,7 @@ fn log1p_64(x: f64) f64 {...@@ -138,8 +138,7 @@ fn log1p_64(x: f64) f64 {
138 c = 0;138 c = 0;
139 f = x;139 f = x;
140 }140 }
141 }141 } else if (hx >= 0x7FF00000) {
142 else if (hx >= 0x7FF00000) {
143 return x;142 return x;
144 }143 }
145144
std/math/log2.zig+5-2
...@@ -27,7 +27,10 @@ pub fn log2(x: var) @typeOf(x) {...@@ -27,7 +27,10 @@ pub fn log2(x: var) @typeOf(x) {
27 TypeId.IntLiteral => comptime {27 TypeId.IntLiteral => comptime {
28 var result = 0;28 var result = 0;
29 var x_shifted = x;29 var x_shifted = x;
30 while (b: {x_shifted >>= 1; break :b x_shifted != 0;}) : (result += 1) {}30 while (b: {
31 x_shifted >>= 1;
32 break :b x_shifted != 0;
33 }) : (result += 1) {}
31 return result;34 return result;
32 },35 },
33 TypeId.Int => {36 TypeId.Int => {
...@@ -38,7 +41,7 @@ pub fn log2(x: var) @typeOf(x) {...@@ -38,7 +41,7 @@ pub fn log2(x: var) @typeOf(x) {
38}41}
3942
40pub fn log2_32(x_: f32) f32 {43pub fn log2_32(x_: f32) f32 {
41 const ivln2hi: f32 = 1.4428710938e+00;44 const ivln2hi: f32 = 1.4428710938e+00;
42 const ivln2lo: f32 = -1.7605285393e-04;45 const ivln2lo: f32 = -1.7605285393e-04;
43 const Lg1: f32 = 0xaaaaaa.0p-24;46 const Lg1: f32 = 0xaaaaaa.0p-24;
44 const Lg2: f32 = 0xccce13.0p-25;47 const Lg2: f32 = 0xccce13.0p-25;
std/math/pow.zig-1
...@@ -28,7 +28,6 @@ const assert = std.debug.assert;...@@ -28,7 +28,6 @@ const assert = std.debug.assert;
2828
29// This implementation is taken from the go stlib, musl is a bit more complex.29// This implementation is taken from the go stlib, musl is a bit more complex.
30pub fn pow(comptime T: type, x: T, y: T) T {30pub fn pow(comptime T: type, x: T, y: T) T {
31
32 @setFloatMode(this, @import("builtin").FloatMode.Strict);31 @setFloatMode(this, @import("builtin").FloatMode.Strict);
3332
34 if (T != f32 and T != f64) {33 if (T != f32 and T != f64) {
std/math/round.zig+4-4
...@@ -24,13 +24,13 @@ fn round32(x_: f32) f32 {...@@ -24,13 +24,13 @@ fn round32(x_: f32) f32 {
24 const e = (u >> 23) & 0xFF;24 const e = (u >> 23) & 0xFF;
25 var y: f32 = undefined;25 var y: f32 = undefined;
2626
27 if (e >= 0x7F+23) {27 if (e >= 0x7F + 23) {
28 return x;28 return x;
29 }29 }
30 if (u >> 31 != 0) {30 if (u >> 31 != 0) {
31 x = -x;31 x = -x;
32 }32 }
33 if (e < 0x7F-1) {33 if (e < 0x7F - 1) {
34 math.forceEval(x + math.f32_toint);34 math.forceEval(x + math.f32_toint);
35 return 0 * @bitCast(f32, u);35 return 0 * @bitCast(f32, u);
36 }36 }
...@@ -61,13 +61,13 @@ fn round64(x_: f64) f64 {...@@ -61,13 +61,13 @@ fn round64(x_: f64) f64 {
61 const e = (u >> 52) & 0x7FF;61 const e = (u >> 52) & 0x7FF;
62 var y: f64 = undefined;62 var y: f64 = undefined;
6363
64 if (e >= 0x3FF+52) {64 if (e >= 0x3FF + 52) {
65 return x;65 return x;
66 }66 }
67 if (u >> 63 != 0) {67 if (u >> 63 != 0) {
68 x = -x;68 x = -x;
69 }69 }
70 if (e < 0x3ff-1) {70 if (e < 0x3ff - 1) {
71 math.forceEval(x + math.f64_toint);71 math.forceEval(x + math.f64_toint);
72 return 0 * @bitCast(f64, u);72 return 0 * @bitCast(f64, u);
73 }73 }
std/math/sin.zig+6-6
...@@ -19,20 +19,20 @@ pub fn sin(x: var) @typeOf(x) {...@@ -19,20 +19,20 @@ pub fn sin(x: var) @typeOf(x) {
19}19}
2020
21// sin polynomial coefficients21// sin polynomial coefficients
22const S0 = 1.58962301576546568060E-10;22const S0 = 1.58962301576546568060E-10;
23const S1 = -2.50507477628578072866E-8;23const S1 = -2.50507477628578072866E-8;
24const S2 = 2.75573136213857245213E-6;24const S2 = 2.75573136213857245213E-6;
25const S3 = -1.98412698295895385996E-4;25const S3 = -1.98412698295895385996E-4;
26const S4 = 8.33333333332211858878E-3;26const S4 = 8.33333333332211858878E-3;
27const S5 = -1.66666666666666307295E-1;27const S5 = -1.66666666666666307295E-1;
2828
29// cos polynomial coeffiecients29// cos polynomial coeffiecients
30const C0 = -1.13585365213876817300E-11;30const C0 = -1.13585365213876817300E-11;
31const C1 = 2.08757008419747316778E-9;31const C1 = 2.08757008419747316778E-9;
32const C2 = -2.75573141792967388112E-7;32const C2 = -2.75573141792967388112E-7;
33const C3 = 2.48015872888517045348E-5;33const C3 = 2.48015872888517045348E-5;
34const C4 = -1.38888888888730564116E-3;34const C4 = -1.38888888888730564116E-3;
35const C5 = 4.16666666666665929218E-2;35const C5 = 4.16666666666665929218E-2;
3636
37// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.37// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
38//38//
std/math/tan.zig+3-3
...@@ -19,12 +19,12 @@ pub fn tan(x: var) @typeOf(x) {...@@ -19,12 +19,12 @@ pub fn tan(x: var) @typeOf(x) {
19}19}
2020
21const Tp0 = -1.30936939181383777646E4;21const Tp0 = -1.30936939181383777646E4;
22const Tp1 = 1.15351664838587416140E6;22const Tp1 = 1.15351664838587416140E6;
23const Tp2 = -1.79565251976484877988E7;23const Tp2 = -1.79565251976484877988E7;
2424
25const Tq1 = 1.36812963470692954678E4;25const Tq1 = 1.36812963470692954678E4;
26const Tq2 = -1.32089234440210967447E6;26const Tq2 = -1.32089234440210967447E6;
27const Tq3 = 2.50083801823357915839E7;27const Tq3 = 2.50083801823357915839E7;
28const Tq4 = -5.38695755929454629881E7;28const Tq4 = -5.38695755929454629881E7;
2929
30// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.30// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
std/mem.zig+133-74
...@@ -6,14 +6,14 @@ const builtin = @import("builtin");...@@ -6,14 +6,14 @@ const builtin = @import("builtin");
6const mem = this;6const mem = this;
77
8pub const Allocator = struct {8pub const Allocator = struct {
9 const Error = error {OutOfMemory};9 const Error = error{OutOfMemory};
1010
11 /// Allocate byte_count bytes and return them in a slice, with the11 /// Allocate byte_count bytes and return them in a slice, with the
12 /// slice's pointer aligned at least to alignment bytes.12 /// slice's pointer aligned at least to alignment bytes.
13 /// The returned newly allocated memory is undefined.13 /// The returned newly allocated memory is undefined.
14 /// `alignment` is guaranteed to be >= 114 /// `alignment` is guaranteed to be >= 1
15 /// `alignment` is guaranteed to be a power of 215 /// `alignment` is guaranteed to be a power of 2
16 allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) Error![]u8,16 allocFn: fn(self: &Allocator, byte_count: usize, alignment: u29) Error![]u8,
1717
18 /// If `new_byte_count > old_mem.len`:18 /// If `new_byte_count > old_mem.len`:
19 /// * `old_mem.len` is the same as what was returned from allocFn or reallocFn.19 /// * `old_mem.len` is the same as what was returned from allocFn or reallocFn.
...@@ -26,10 +26,10 @@ pub const Allocator = struct {...@@ -26,10 +26,10 @@ pub const Allocator = struct {
26 /// The returned newly allocated memory is undefined.26 /// The returned newly allocated memory is undefined.
27 /// `alignment` is guaranteed to be >= 127 /// `alignment` is guaranteed to be >= 1
28 /// `alignment` is guaranteed to be a power of 228 /// `alignment` is guaranteed to be a power of 2
29 reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) Error![]u8,29 reallocFn: fn(self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) Error![]u8,
3030
31 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`31 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
32 freeFn: fn (self: &Allocator, old_mem: []u8) void,32 freeFn: fn(self: &Allocator, old_mem: []u8) void,
3333
34 fn create(self: &Allocator, comptime T: type) !&T {34 fn create(self: &Allocator, comptime T: type) !&T {
35 if (@sizeOf(T) == 0) return &{};35 if (@sizeOf(T) == 0) return &{};
...@@ -47,7 +47,7 @@ pub const Allocator = struct {...@@ -47,7 +47,7 @@ pub const Allocator = struct {
47 if (@sizeOf(T) == 0) return &{};47 if (@sizeOf(T) == 0) return &{};
48 const slice = try self.alloc(T, 1);48 const slice = try self.alloc(T, 1);
49 const ptr = &slice[0];49 const ptr = &slice[0];
50 *ptr = *init;50 ptr.* = init.*;
51 return ptr;51 return ptr;
52 }52 }
5353
...@@ -59,9 +59,7 @@ pub const Allocator = struct {...@@ -59,9 +59,7 @@ pub const Allocator = struct {
59 return self.alignedAlloc(T, @alignOf(T), n);59 return self.alignedAlloc(T, @alignOf(T), n);
60 }60 }
6161
62 fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,62 fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29, n: usize) ![]align(alignment) T {
63 n: usize) ![]align(alignment) T
64 {
65 if (n == 0) {63 if (n == 0) {
66 return (&align(alignment) T)(undefined)[0..0];64 return (&align(alignment) T)(undefined)[0..0];
67 }65 }
...@@ -70,7 +68,7 @@ pub const Allocator = struct {...@@ -70,7 +68,7 @@ pub const Allocator = struct {
70 assert(byte_slice.len == byte_count);68 assert(byte_slice.len == byte_count);
71 // This loop gets optimized out in ReleaseFast mode69 // This loop gets optimized out in ReleaseFast mode
72 for (byte_slice) |*byte| {70 for (byte_slice) |*byte| {
73 *byte = undefined;71 byte.* = undefined;
74 }72 }
75 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));73 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
76 }74 }
...@@ -79,9 +77,7 @@ pub const Allocator = struct {...@@ -79,9 +77,7 @@ pub const Allocator = struct {
79 return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);77 return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
80 }78 }
8179
82 fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29,80 fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) ![]align(alignment) T {
83 old_mem: []align(alignment) T, n: usize) ![]align(alignment) T
84 {
85 if (old_mem.len == 0) {81 if (old_mem.len == 0) {
86 return self.alloc(T, n);82 return self.alloc(T, n);
87 }83 }
...@@ -97,7 +93,7 @@ pub const Allocator = struct {...@@ -97,7 +93,7 @@ pub const Allocator = struct {
97 if (n > old_mem.len) {93 if (n > old_mem.len) {
98 // This loop gets optimized out in ReleaseFast mode94 // This loop gets optimized out in ReleaseFast mode
99 for (byte_slice[old_byte_slice.len..]) |*byte| {95 for (byte_slice[old_byte_slice.len..]) |*byte| {
100 *byte = undefined;96 byte.* = undefined;
101 }97 }
102 }98 }
103 return ([]T)(@alignCast(alignment, byte_slice));99 return ([]T)(@alignCast(alignment, byte_slice));
...@@ -110,9 +106,7 @@ pub const Allocator = struct {...@@ -110,9 +106,7 @@ pub const Allocator = struct {
110 return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);106 return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
111 }107 }
112108
113 fn alignedShrink(self: &Allocator, comptime T: type, comptime alignment: u29,109 fn alignedShrink(self: &Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) []align(alignment) T {
114 old_mem: []align(alignment) T, n: usize) []align(alignment) T
115 {
116 if (n == 0) {110 if (n == 0) {
117 self.free(old_mem);111 self.free(old_mem);
118 return old_mem[0..0];112 return old_mem[0..0];
...@@ -131,8 +125,7 @@ pub const Allocator = struct {...@@ -131,8 +125,7 @@ pub const Allocator = struct {
131125
132 fn free(self: &Allocator, memory: var) void {126 fn free(self: &Allocator, memory: var) void {
133 const bytes = ([]const u8)(memory);127 const bytes = ([]const u8)(memory);
134 if (bytes.len == 0)128 if (bytes.len == 0) return;
135 return;
136 const non_const_ptr = @intToPtr(&u8, @ptrToInt(bytes.ptr));129 const non_const_ptr = @intToPtr(&u8, @ptrToInt(bytes.ptr));
137 self.freeFn(self, non_const_ptr[0..bytes.len]);130 self.freeFn(self, non_const_ptr[0..bytes.len]);
138 }131 }
...@@ -146,11 +139,13 @@ pub fn copy(comptime T: type, dest: []T, source: []const T) void {...@@ -146,11 +139,13 @@ pub fn copy(comptime T: type, dest: []T, source: []const T) void {
146 // this and automatically omit safety checks for loops139 // this and automatically omit safety checks for loops
147 @setRuntimeSafety(false);140 @setRuntimeSafety(false);
148 assert(dest.len >= source.len);141 assert(dest.len >= source.len);
149 for (source) |s, i| dest[i] = s;142 for (source) |s, i|
143 dest[i] = s;
150}144}
151145
152pub fn set(comptime T: type, dest: []T, value: T) void {146pub fn set(comptime T: type, dest: []T, value: T) void {
153 for (dest) |*d| *d = value;147 for (dest) |*d|
148 d.* = value;
154}149}
155150
156/// Returns true if lhs < rhs, false otherwise151/// Returns true if lhs < rhs, false otherwise
...@@ -182,6 +177,14 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool {...@@ -182,6 +177,14 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool {
182 return true;177 return true;
183}178}
184179
180/// Returns true if all elements in a slice are equal to the scalar value provided
181pub fn allEqual(comptime T: type, slice: []const T, scalar: T) bool {
182 for (slice) |item| {
183 if (item != scalar) return false;
184 }
185 return true;
186}
187
185/// Copies ::m to newly allocated memory. Caller is responsible to free it.188/// Copies ::m to newly allocated memory. Caller is responsible to free it.
186pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) ![]T {189pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) ![]T {
187 const new_buf = try allocator.alloc(T, m.len);190 const new_buf = try allocator.alloc(T, m.len);
...@@ -229,8 +232,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {...@@ -229,8 +232,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {
229 var i: usize = slice.len;232 var i: usize = slice.len;
230 while (i != 0) {233 while (i != 0) {
231 i -= 1;234 i -= 1;
232 if (slice[i] == value)235 if (slice[i] == value) return i;
233 return i;
234 }236 }
235 return null;237 return null;
236}238}
...@@ -238,8 +240,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {...@@ -238,8 +240,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {
238pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) ?usize {240pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) ?usize {
239 var i: usize = start_index;241 var i: usize = start_index;
240 while (i < slice.len) : (i += 1) {242 while (i < slice.len) : (i += 1) {
241 if (slice[i] == value)243 if (slice[i] == value) return i;
242 return i;
243 }244 }
244 return null;245 return null;
245}246}
...@@ -253,8 +254,7 @@ pub fn lastIndexOfAny(comptime T: type, slice: []const T, values: []const T) ?us...@@ -253,8 +254,7 @@ pub fn lastIndexOfAny(comptime T: type, slice: []const T, values: []const T) ?us
253 while (i != 0) {254 while (i != 0) {
254 i -= 1;255 i -= 1;
255 for (values) |value| {256 for (values) |value| {
256 if (slice[i] == value)257 if (slice[i] == value) return i;
257 return i;
258 }258 }
259 }259 }
260 return null;260 return null;
...@@ -264,8 +264,7 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val...@@ -264,8 +264,7 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val
264 var i: usize = start_index;264 var i: usize = start_index;
265 while (i < slice.len) : (i += 1) {265 while (i < slice.len) : (i += 1) {
266 for (values) |value| {266 for (values) |value| {
267 if (slice[i] == value)267 if (slice[i] == value) return i;
268 return i;
269 }268 }
270 }269 }
271 return null;270 return null;
...@@ -279,28 +278,23 @@ pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize...@@ -279,28 +278,23 @@ pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize
279/// To start looking at a different index, slice the haystack first.278/// To start looking at a different index, slice the haystack first.
280/// TODO is there even a better algorithm for this?279/// TODO is there even a better algorithm for this?
281pub fn lastIndexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize {280pub fn lastIndexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize {
282 if (needle.len > haystack.len)281 if (needle.len > haystack.len) return null;
283 return null;
284282
285 var i: usize = haystack.len - needle.len;283 var i: usize = haystack.len - needle.len;
286 while (true) : (i -= 1) {284 while (true) : (i -= 1) {
287 if (mem.eql(T, haystack[i..i+needle.len], needle))285 if (mem.eql(T, haystack[i..i + needle.len], needle)) return i;
288 return i;286 if (i == 0) return null;
289 if (i == 0)
290 return null;
291 }287 }
292}288}
293289
294// TODO boyer-moore algorithm290// TODO boyer-moore algorithm
295pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, needle: []const T) ?usize {291pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, needle: []const T) ?usize {
296 if (needle.len > haystack.len)292 if (needle.len > haystack.len) return null;
297 return null;
298293
299 var i: usize = start_index;294 var i: usize = start_index;
300 const end = haystack.len - needle.len;295 const end = haystack.len - needle.len;
301 while (i <= end) : (i += 1) {296 while (i <= end) : (i += 1) {
302 if (eql(T, haystack[i .. i + needle.len], needle))297 if (eql(T, haystack[i..i + needle.len], needle)) return i;
303 return i;
304 }298 }
305 return null;299 return null;
306}300}
...@@ -355,9 +349,12 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) T {...@@ -355,9 +349,12 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) T {
355 }349 }
356 assert(bytes.len == @sizeOf(T));350 assert(bytes.len == @sizeOf(T));
357 var result: T = 0;351 var result: T = 0;
358 {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) {352 {
359 result = (result << 8) | T(bytes[i]);353 comptime var i = 0;
360 }}354 inline while (i < @sizeOf(T)) : (i += 1) {
355 result = (result << 8) | T(bytes[i]);
356 }
357 }
361 return result;358 return result;
362}359}
363360
...@@ -369,9 +366,12 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) T {...@@ -369,9 +366,12 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) T {
369 }366 }
370 assert(bytes.len == @sizeOf(T));367 assert(bytes.len == @sizeOf(T));
371 var result: T = 0;368 var result: T = 0;
372 {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) {369 {
373 result |= T(bytes[i]) << i * 8;370 comptime var i = 0;
374 }}371 inline while (i < @sizeOf(T)) : (i += 1) {
372 result |= T(bytes[i]) << i * 8;
373 }
374 }
375 return result;375 return result;
376}376}
377377
...@@ -393,7 +393,7 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {...@@ -393,7 +393,7 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {
393 },393 },
394 builtin.Endian.Little => {394 builtin.Endian.Little => {
395 for (buf) |*b| {395 for (buf) |*b| {
396 *b = @truncate(u8, bits);396 b.* = @truncate(u8, bits);
397 bits >>= 8;397 bits >>= 8;
398 }398 }
399 },399 },
...@@ -401,7 +401,6 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {...@@ -401,7 +401,6 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {
401 assert(bits == 0);401 assert(bits == 0);
402}402}
403403
404
405pub fn hash_slice_u8(k: []const u8) u32 {404pub fn hash_slice_u8(k: []const u8) u32 {
406 // FNV 32-bit hash405 // FNV 32-bit hash
407 var h: u32 = 2166136261;406 var h: u32 = 2166136261;
...@@ -420,7 +419,7 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) bool {...@@ -420,7 +419,7 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) bool {
420/// split(" abc def ghi ", " ")419/// split(" abc def ghi ", " ")
421/// Will return slices for "abc", "def", "ghi", null, in that order.420/// Will return slices for "abc", "def", "ghi", null, in that order.
422pub fn split(buffer: []const u8, split_bytes: []const u8) SplitIterator {421pub fn split(buffer: []const u8, split_bytes: []const u8) SplitIterator {
423 return SplitIterator {422 return SplitIterator{
424 .index = 0,423 .index = 0,
425 .buffer = buffer,424 .buffer = buffer,
426 .split_bytes = split_bytes,425 .split_bytes = split_bytes,
...@@ -436,7 +435,7 @@ test "mem.split" {...@@ -436,7 +435,7 @@ test "mem.split" {
436}435}
437436
438pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool {437pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool {
439 return if (needle.len > haystack.len) false else eql(T, haystack[0 .. needle.len], needle);438 return if (needle.len > haystack.len) false else eql(T, haystack[0..needle.len], needle);
440}439}
441440
442test "mem.startsWith" {441test "mem.startsWith" {
...@@ -445,10 +444,9 @@ test "mem.startsWith" {...@@ -445,10 +444,9 @@ test "mem.startsWith" {
445}444}
446445
447pub fn endsWith(comptime T: type, haystack: []const T, needle: []const T) bool {446pub fn endsWith(comptime T: type, haystack: []const T, needle: []const T) bool {
448 return if (needle.len > haystack.len) false else eql(T, haystack[haystack.len - needle.len ..], needle);447 return if (needle.len > haystack.len) false else eql(T, haystack[haystack.len - needle.len..], needle);
449}448}
450449
451
452test "mem.endsWith" {450test "mem.endsWith" {
453 assert(endsWith(u8, "Needle in haystack", "haystack"));451 assert(endsWith(u8, "Needle in haystack", "haystack"));
454 assert(!endsWith(u8, "Bob", "Bo"));452 assert(!endsWith(u8, "Bob", "Bo"));
...@@ -542,29 +540,47 @@ test "testReadInt" {...@@ -542,29 +540,47 @@ test "testReadInt" {
542}540}
543fn testReadIntImpl() void {541fn testReadIntImpl() void {
544 {542 {
545 const bytes = []u8{ 0x12, 0x34, 0x56, 0x78 };543 const bytes = []u8{
546 assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678);544 0x12,
547 assert(readIntBE(u32, bytes) == 0x12345678);545 0x34,
548 assert(readIntBE(i32, bytes) == 0x12345678);546 0x56,
547 0x78,
548 };
549 assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678);
550 assert(readIntBE(u32, bytes) == 0x12345678);
551 assert(readIntBE(i32, bytes) == 0x12345678);
549 assert(readInt(bytes, u32, builtin.Endian.Little) == 0x78563412);552 assert(readInt(bytes, u32, builtin.Endian.Little) == 0x78563412);
550 assert(readIntLE(u32, bytes) == 0x78563412);553 assert(readIntLE(u32, bytes) == 0x78563412);
551 assert(readIntLE(i32, bytes) == 0x78563412);554 assert(readIntLE(i32, bytes) == 0x78563412);
552 }555 }
553 {556 {
554 const buf = []u8{0x00, 0x00, 0x12, 0x34};557 const buf = []u8{
558 0x00,
559 0x00,
560 0x12,
561 0x34,
562 };
555 const answer = readInt(buf, u64, builtin.Endian.Big);563 const answer = readInt(buf, u64, builtin.Endian.Big);
556 assert(answer == 0x00001234);564 assert(answer == 0x00001234);
557 }565 }
558 {566 {
559 const buf = []u8{0x12, 0x34, 0x00, 0x00};567 const buf = []u8{
568 0x12,
569 0x34,
570 0x00,
571 0x00,
572 };
560 const answer = readInt(buf, u64, builtin.Endian.Little);573 const answer = readInt(buf, u64, builtin.Endian.Little);
561 assert(answer == 0x00003412);574 assert(answer == 0x00003412);
562 }575 }
563 {576 {
564 const bytes = []u8{0xff, 0xfe};577 const bytes = []u8{
565 assert(readIntBE(u16, bytes) == 0xfffe);578 0xff,
579 0xfe,
580 };
581 assert(readIntBE(u16, bytes) == 0xfffe);
566 assert(readIntBE(i16, bytes) == -0x0002);582 assert(readIntBE(i16, bytes) == -0x0002);
567 assert(readIntLE(u16, bytes) == 0xfeff);583 assert(readIntLE(u16, bytes) == 0xfeff);
568 assert(readIntLE(i16, bytes) == -0x0101);584 assert(readIntLE(i16, bytes) == -0x0101);
569 }585 }
570}586}
...@@ -577,19 +593,38 @@ fn testWriteIntImpl() void {...@@ -577,19 +593,38 @@ fn testWriteIntImpl() void {
577 var bytes: [4]u8 = undefined;593 var bytes: [4]u8 = undefined;
578594
579 writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big);595 writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big);
580 assert(eql(u8, bytes, []u8{ 0x12, 0x34, 0x56, 0x78 }));596 assert(eql(u8, bytes, []u8{
597 0x12,
598 0x34,
599 0x56,
600 0x78,
601 }));
581602
582 writeInt(bytes[0..], u32(0x78563412), builtin.Endian.Little);603 writeInt(bytes[0..], u32(0x78563412), builtin.Endian.Little);
583 assert(eql(u8, bytes, []u8{ 0x12, 0x34, 0x56, 0x78 }));604 assert(eql(u8, bytes, []u8{
605 0x12,
606 0x34,
607 0x56,
608 0x78,
609 }));
584610
585 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Big);611 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Big);
586 assert(eql(u8, bytes, []u8{ 0x00, 0x00, 0x12, 0x34 }));612 assert(eql(u8, bytes, []u8{
613 0x00,
614 0x00,
615 0x12,
616 0x34,
617 }));
587618
588 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Little);619 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Little);
589 assert(eql(u8, bytes, []u8{ 0x34, 0x12, 0x00, 0x00 }));620 assert(eql(u8, bytes, []u8{
621 0x34,
622 0x12,
623 0x00,
624 0x00,
625 }));
590}626}
591627
592
593pub fn min(comptime T: type, slice: []const T) T {628pub fn min(comptime T: type, slice: []const T) T {
594 var best = slice[0];629 var best = slice[0];
595 for (slice[1..]) |item| {630 for (slice[1..]) |item| {
...@@ -615,9 +650,9 @@ test "mem.max" {...@@ -615,9 +650,9 @@ test "mem.max" {
615}650}
616651
617pub fn swap(comptime T: type, a: &T, b: &T) void {652pub fn swap(comptime T: type, a: &T, b: &T) void {
618 const tmp = *a;653 const tmp = a.*;
619 *a = *b;654 a.* = b.*;
620 *b = tmp;655 b.* = tmp;
621}656}
622657
623/// In-place order reversal of a slice658/// In-place order reversal of a slice
...@@ -630,10 +665,22 @@ pub fn reverse(comptime T: type, items: []T) void {...@@ -630,10 +665,22 @@ pub fn reverse(comptime T: type, items: []T) void {
630}665}
631666
632test "std.mem.reverse" {667test "std.mem.reverse" {
633 var arr = []i32{ 5, 3, 1, 2, 4 };668 var arr = []i32{
669 5,
670 3,
671 1,
672 2,
673 4,
674 };
634 reverse(i32, arr[0..]);675 reverse(i32, arr[0..]);
635676
636 assert(eql(i32, arr, []i32{ 4, 2, 1, 3, 5 }));677 assert(eql(i32, arr, []i32{
678 4,
679 2,
680 1,
681 3,
682 5,
683 }));
637}684}
638685
639/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)686/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)
...@@ -645,13 +692,25 @@ pub fn rotate(comptime T: type, items: []T, amount: usize) void {...@@ -645,13 +692,25 @@ pub fn rotate(comptime T: type, items: []T, amount: usize) void {
645}692}
646693
647test "std.mem.rotate" {694test "std.mem.rotate" {
648 var arr = []i32{ 5, 3, 1, 2, 4 };695 var arr = []i32{
696 5,
697 3,
698 1,
699 2,
700 4,
701 };
649 rotate(i32, arr[0..], 2);702 rotate(i32, arr[0..], 2);
650703
651 assert(eql(i32, arr, []i32{ 1, 2, 4, 5, 3 }));704 assert(eql(i32, arr, []i32{
705 1,
706 2,
707 4,
708 5,
709 3,
710 }));
652}711}
653712
654// TODO: When https://github.com/zig-lang/zig/issues/649 is solved these can be done by713// TODO: When https://github.com/ziglang/zig/issues/649 is solved these can be done by
655// endian-casting the pointer and then dereferencing714// endian-casting the pointer and then dereferencing
656715
657pub fn endianSwapIfLe(comptime T: type, x: T) T {716pub fn endianSwapIfLe(comptime T: type, x: T) T {
std/net.zig+8-10
...@@ -19,9 +19,9 @@ pub const Address = struct {...@@ -19,9 +19,9 @@ pub const Address = struct {
19 os_addr: OsAddress,19 os_addr: OsAddress,
2020
21 pub fn initIp4(ip4: u32, port: u16) Address {21 pub fn initIp4(ip4: u32, port: u16) Address {
22 return Address {22 return Address{
23 .os_addr = posix.sockaddr {23 .os_addr = posix.sockaddr{
24 .in = posix.sockaddr_in {24 .in = posix.sockaddr_in{
25 .family = posix.AF_INET,25 .family = posix.AF_INET,
26 .port = std.mem.endianSwapIfLe(u16, port),26 .port = std.mem.endianSwapIfLe(u16, port),
27 .addr = ip4,27 .addr = ip4,
...@@ -32,10 +32,10 @@ pub const Address = struct {...@@ -32,10 +32,10 @@ pub const Address = struct {
32 }32 }
3333
34 pub fn initIp6(ip6: &const Ip6Addr, port: u16) Address {34 pub fn initIp6(ip6: &const Ip6Addr, port: u16) Address {
35 return Address {35 return Address{
36 .family = posix.AF_INET6,36 .family = posix.AF_INET6,
37 .os_addr = posix.sockaddr {37 .os_addr = posix.sockaddr{
38 .in6 = posix.sockaddr_in6 {38 .in6 = posix.sockaddr_in6{
39 .family = posix.AF_INET6,39 .family = posix.AF_INET6,
40 .port = std.mem.endianSwapIfLe(u16, port),40 .port = std.mem.endianSwapIfLe(u16, port),
41 .flowinfo = 0,41 .flowinfo = 0,
...@@ -47,9 +47,7 @@ pub const Address = struct {...@@ -47,9 +47,7 @@ pub const Address = struct {
47 }47 }
4848
49 pub fn initPosix(addr: &const posix.sockaddr) Address {49 pub fn initPosix(addr: &const posix.sockaddr) Address {
50 return Address {50 return Address{ .os_addr = addr.* };
51 .os_addr = *addr,
52 };
53 }51 }
5452
55 pub fn format(self: &const Address, out_stream: var) !void {53 pub fn format(self: &const Address, out_stream: var) !void {
...@@ -98,7 +96,7 @@ pub fn parseIp4(buf: []const u8) !u32 {...@@ -98,7 +96,7 @@ pub fn parseIp4(buf: []const u8) !u32 {
98 }96 }
99 } else {97 } else {
100 return error.InvalidCharacter;98 return error.InvalidCharacter;
101 } 99 }
102 }100 }
103 if (index == 3 and saw_any_digits) {101 if (index == 3 and saw_any_digits) {
104 out_ptr[index] = x;102 out_ptr[index] = x;
std/os/child_process.zig+99-92
...@@ -49,7 +49,7 @@ pub const ChildProcess = struct {...@@ -49,7 +49,7 @@ pub const ChildProcess = struct {
49 err_pipe: if (is_windows) void else [2]i32,49 err_pipe: if (is_windows) void else [2]i32,
50 llnode: if (is_windows) void else LinkedList(&ChildProcess).Node,50 llnode: if (is_windows) void else LinkedList(&ChildProcess).Node,
5151
52 pub const SpawnError = error {52 pub const SpawnError = error{
53 ProcessFdQuotaExceeded,53 ProcessFdQuotaExceeded,
54 Unexpected,54 Unexpected,
55 NotDir,55 NotDir,
...@@ -88,7 +88,7 @@ pub const ChildProcess = struct {...@@ -88,7 +88,7 @@ pub const ChildProcess = struct {
88 const child = try allocator.create(ChildProcess);88 const child = try allocator.create(ChildProcess);
89 errdefer allocator.destroy(child);89 errdefer allocator.destroy(child);
9090
91 *child = ChildProcess {91 child.* = ChildProcess{
92 .allocator = allocator,92 .allocator = allocator,
93 .argv = argv,93 .argv = argv,
94 .pid = undefined,94 .pid = undefined,
...@@ -99,8 +99,10 @@ pub const ChildProcess = struct {...@@ -99,8 +99,10 @@ pub const ChildProcess = struct {
99 .term = null,99 .term = null,
100 .env_map = null,100 .env_map = null,
101 .cwd = null,101 .cwd = null,
102 .uid = if (is_windows) {} else null,102 .uid = if (is_windows) {} else
103 .gid = if (is_windows) {} else null,103 null,
104 .gid = if (is_windows) {} else
105 null,
104 .stdin = null,106 .stdin = null,
105 .stdout = null,107 .stdout = null,
106 .stderr = null,108 .stderr = null,
...@@ -193,9 +195,7 @@ pub const ChildProcess = struct {...@@ -193,9 +195,7 @@ pub const ChildProcess = struct {
193195
194 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.196 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
195 /// If it succeeds, the caller owns result.stdout and result.stderr memory.197 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
196 pub fn exec(allocator: &mem.Allocator, argv: []const []const u8, cwd: ?[]const u8,198 pub fn exec(allocator: &mem.Allocator, argv: []const []const u8, cwd: ?[]const u8, env_map: ?&const BufMap, max_output_size: usize) !ExecResult {
197 env_map: ?&const BufMap, max_output_size: usize) !ExecResult
198 {
199 const child = try ChildProcess.init(argv, allocator);199 const child = try ChildProcess.init(argv, allocator);
200 defer child.deinit();200 defer child.deinit();
201201
...@@ -218,7 +218,7 @@ pub const ChildProcess = struct {...@@ -218,7 +218,7 @@ pub const ChildProcess = struct {
218 try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size);218 try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size);
219 try stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size);219 try stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size);
220220
221 return ExecResult {221 return ExecResult{
222 .term = try child.wait(),222 .term = try child.wait(),
223 .stdout = stdout.toOwnedSlice(),223 .stdout = stdout.toOwnedSlice(),
224 .stderr = stderr.toOwnedSlice(),224 .stderr = stderr.toOwnedSlice(),
...@@ -255,9 +255,9 @@ pub const ChildProcess = struct {...@@ -255,9 +255,9 @@ pub const ChildProcess = struct {
255 self.term = (SpawnError!Term)(x: {255 self.term = (SpawnError!Term)(x: {
256 var exit_code: windows.DWORD = undefined;256 var exit_code: windows.DWORD = undefined;
257 if (windows.GetExitCodeProcess(self.handle, &exit_code) == 0) {257 if (windows.GetExitCodeProcess(self.handle, &exit_code) == 0) {
258 break :x Term { .Unknown = 0 };258 break :x Term{ .Unknown = 0 };
259 } else {259 } else {
260 break :x Term { .Exited = @bitCast(i32, exit_code)};260 break :x Term{ .Exited = @bitCast(i32, exit_code) };
261 }261 }
262 });262 });
263263
...@@ -288,9 +288,18 @@ pub const ChildProcess = struct {...@@ -288,9 +288,18 @@ pub const ChildProcess = struct {
288 }288 }
289289
290 fn cleanupStreams(self: &ChildProcess) void {290 fn cleanupStreams(self: &ChildProcess) void {
291 if (self.stdin) |*stdin| { stdin.close(); self.stdin = null; }291 if (self.stdin) |*stdin| {
292 if (self.stdout) |*stdout| { stdout.close(); self.stdout = null; }292 stdin.close();
293 if (self.stderr) |*stderr| { stderr.close(); self.stderr = null; }293 self.stdin = null;
294 }
295 if (self.stdout) |*stdout| {
296 stdout.close();
297 self.stdout = null;
298 }
299 if (self.stderr) |*stderr| {
300 stderr.close();
301 self.stderr = null;
302 }
294 }303 }
295304
296 fn cleanupAfterWait(self: &ChildProcess, status: i32) !Term {305 fn cleanupAfterWait(self: &ChildProcess, status: i32) !Term {
...@@ -317,25 +326,30 @@ pub const ChildProcess = struct {...@@ -317,25 +326,30 @@ pub const ChildProcess = struct {
317326
318 fn statusToTerm(status: i32) Term {327 fn statusToTerm(status: i32) Term {
319 return if (posix.WIFEXITED(status))328 return if (posix.WIFEXITED(status))
320 Term { .Exited = posix.WEXITSTATUS(status) }329 Term{ .Exited = posix.WEXITSTATUS(status) }
321 else if (posix.WIFSIGNALED(status))330 else if (posix.WIFSIGNALED(status))
322 Term { .Signal = posix.WTERMSIG(status) }331 Term{ .Signal = posix.WTERMSIG(status) }
323 else if (posix.WIFSTOPPED(status))332 else if (posix.WIFSTOPPED(status))
324 Term { .Stopped = posix.WSTOPSIG(status) }333 Term{ .Stopped = posix.WSTOPSIG(status) }
325 else334 else
326 Term { .Unknown = status }335 Term{ .Unknown = status };
327 ;
328 }336 }
329337
330 fn spawnPosix(self: &ChildProcess) !void {338 fn spawnPosix(self: &ChildProcess) !void {
331 const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined;339 const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined;
332 errdefer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); };340 errdefer if (self.stdin_behavior == StdIo.Pipe) {
341 destroyPipe(stdin_pipe);
342 };
333343
334 const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try makePipe() else undefined;344 const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try makePipe() else undefined;
335 errdefer if (self.stdout_behavior == StdIo.Pipe) { destroyPipe(stdout_pipe); };345 errdefer if (self.stdout_behavior == StdIo.Pipe) {
346 destroyPipe(stdout_pipe);
347 };
336348
337 const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try makePipe() else undefined;349 const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try makePipe() else undefined;
338 errdefer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); };350 errdefer if (self.stderr_behavior == StdIo.Pipe) {
351 destroyPipe(stderr_pipe);
352 };
339353
340 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);354 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
341 const dev_null_fd = if (any_ignore) blk: {355 const dev_null_fd = if (any_ignore) blk: {
...@@ -346,7 +360,9 @@ pub const ChildProcess = struct {...@@ -346,7 +360,9 @@ pub const ChildProcess = struct {
346 } else blk: {360 } else blk: {
347 break :blk undefined;361 break :blk undefined;
348 };362 };
349 defer { if (any_ignore) os.close(dev_null_fd); }363 defer {
364 if (any_ignore) os.close(dev_null_fd);
365 }
350366
351 var env_map_owned: BufMap = undefined;367 var env_map_owned: BufMap = undefined;
352 var we_own_env_map: bool = undefined;368 var we_own_env_map: bool = undefined;
...@@ -358,7 +374,9 @@ pub const ChildProcess = struct {...@@ -358,7 +374,9 @@ pub const ChildProcess = struct {
358 env_map_owned = try os.getEnvMap(self.allocator);374 env_map_owned = try os.getEnvMap(self.allocator);
359 break :x &env_map_owned;375 break :x &env_map_owned;
360 };376 };
361 defer { if (we_own_env_map) env_map_owned.deinit(); }377 defer {
378 if (we_own_env_map) env_map_owned.deinit();
379 }
362380
363 // This pipe is used to communicate errors between the time of fork381 // This pipe is used to communicate errors between the time of fork
364 // and execve from the child process to the parent process.382 // and execve from the child process to the parent process.
...@@ -375,17 +393,12 @@ pub const ChildProcess = struct {...@@ -375,17 +393,12 @@ pub const ChildProcess = struct {
375 }393 }
376 if (pid_result == 0) {394 if (pid_result == 0) {
377 // we are the child395 // we are the child
378396 setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
379 setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch397 setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
380 |err| forkChildErrReport(err_pipe[1], err);398 setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
381 setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch
382 |err| forkChildErrReport(err_pipe[1], err);
383 setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch
384 |err| forkChildErrReport(err_pipe[1], err);
385399
386 if (self.cwd) |cwd| {400 if (self.cwd) |cwd| {
387 os.changeCurDir(self.allocator, cwd) catch401 os.changeCurDir(self.allocator, cwd) catch |err| forkChildErrReport(err_pipe[1], err);
388 |err| forkChildErrReport(err_pipe[1], err);
389 }402 }
390403
391 if (self.gid) |gid| {404 if (self.gid) |gid| {
...@@ -396,8 +409,7 @@ pub const ChildProcess = struct {...@@ -396,8 +409,7 @@ pub const ChildProcess = struct {
396 os.posix_setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);409 os.posix_setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
397 }410 }
398411
399 os.posixExecve(self.argv, env_map, self.allocator) catch412 os.posixExecve(self.argv, env_map, self.allocator) catch |err| forkChildErrReport(err_pipe[1], err);
400 |err| forkChildErrReport(err_pipe[1], err);
401 }413 }
402414
403 // we are the parent415 // we are the parent
...@@ -423,37 +435,41 @@ pub const ChildProcess = struct {...@@ -423,37 +435,41 @@ pub const ChildProcess = struct {
423 self.llnode = LinkedList(&ChildProcess).Node.init(self);435 self.llnode = LinkedList(&ChildProcess).Node.init(self);
424 self.term = null;436 self.term = null;
425437
426 if (self.stdin_behavior == StdIo.Pipe) { os.close(stdin_pipe[0]); }438 if (self.stdin_behavior == StdIo.Pipe) {
427 if (self.stdout_behavior == StdIo.Pipe) { os.close(stdout_pipe[1]); }439 os.close(stdin_pipe[0]);
428 if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); }440 }
441 if (self.stdout_behavior == StdIo.Pipe) {
442 os.close(stdout_pipe[1]);
443 }
444 if (self.stderr_behavior == StdIo.Pipe) {
445 os.close(stderr_pipe[1]);
446 }
429 }447 }
430448
431 fn spawnWindows(self: &ChildProcess) !void {449 fn spawnWindows(self: &ChildProcess) !void {
432 const saAttr = windows.SECURITY_ATTRIBUTES {450 const saAttr = windows.SECURITY_ATTRIBUTES{
433 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),451 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
434 .bInheritHandle = windows.TRUE,452 .bInheritHandle = windows.TRUE,
435 .lpSecurityDescriptor = null,453 .lpSecurityDescriptor = null,
436 };454 };
437455
438 const any_ignore = (self.stdin_behavior == StdIo.Ignore or456 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
439 self.stdout_behavior == StdIo.Ignore or
440 self.stderr_behavior == StdIo.Ignore);
441457
442 const nul_handle = if (any_ignore) blk: {458 const nul_handle = if (any_ignore) blk: {
443 const nul_file_path = "NUL";459 const nul_file_path = "NUL";
444 var fixed_buffer_mem: [nul_file_path.len + 1]u8 = undefined;460 var fixed_buffer_mem: [nul_file_path.len + 1]u8 = undefined;
445 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);461 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
446 break :blk try os.windowsOpen(&fixed_allocator.allocator, "NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ,462 break :blk try os.windowsOpen(&fixed_allocator.allocator, "NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL);
447 windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL);
448 } else blk: {463 } else blk: {
449 break :blk undefined;464 break :blk undefined;
450 };465 };
451 defer { if (any_ignore) os.close(nul_handle); }466 defer {
467 if (any_ignore) os.close(nul_handle);
468 }
452 if (any_ignore) {469 if (any_ignore) {
453 try windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0);470 try windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0);
454 }471 }
455472
456
457 var g_hChildStd_IN_Rd: ?windows.HANDLE = null;473 var g_hChildStd_IN_Rd: ?windows.HANDLE = null;
458 var g_hChildStd_IN_Wr: ?windows.HANDLE = null;474 var g_hChildStd_IN_Wr: ?windows.HANDLE = null;
459 switch (self.stdin_behavior) {475 switch (self.stdin_behavior) {
...@@ -470,7 +486,9 @@ pub const ChildProcess = struct {...@@ -470,7 +486,9 @@ pub const ChildProcess = struct {
470 g_hChildStd_IN_Rd = null;486 g_hChildStd_IN_Rd = null;
471 },487 },
472 }488 }
473 errdefer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_IN_Rd, g_hChildStd_IN_Wr); };489 errdefer if (self.stdin_behavior == StdIo.Pipe) {
490 windowsDestroyPipe(g_hChildStd_IN_Rd, g_hChildStd_IN_Wr);
491 };
474492
475 var g_hChildStd_OUT_Rd: ?windows.HANDLE = null;493 var g_hChildStd_OUT_Rd: ?windows.HANDLE = null;
476 var g_hChildStd_OUT_Wr: ?windows.HANDLE = null;494 var g_hChildStd_OUT_Wr: ?windows.HANDLE = null;
...@@ -488,7 +506,9 @@ pub const ChildProcess = struct {...@@ -488,7 +506,9 @@ pub const ChildProcess = struct {
488 g_hChildStd_OUT_Wr = null;506 g_hChildStd_OUT_Wr = null;
489 },507 },
490 }508 }
491 errdefer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_OUT_Rd, g_hChildStd_OUT_Wr); };509 errdefer if (self.stdin_behavior == StdIo.Pipe) {
510 windowsDestroyPipe(g_hChildStd_OUT_Rd, g_hChildStd_OUT_Wr);
511 };
492512
493 var g_hChildStd_ERR_Rd: ?windows.HANDLE = null;513 var g_hChildStd_ERR_Rd: ?windows.HANDLE = null;
494 var g_hChildStd_ERR_Wr: ?windows.HANDLE = null;514 var g_hChildStd_ERR_Wr: ?windows.HANDLE = null;
...@@ -506,12 +526,14 @@ pub const ChildProcess = struct {...@@ -506,12 +526,14 @@ pub const ChildProcess = struct {
506 g_hChildStd_ERR_Wr = null;526 g_hChildStd_ERR_Wr = null;
507 },527 },
508 }528 }
509 errdefer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr); };529 errdefer if (self.stdin_behavior == StdIo.Pipe) {
530 windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr);
531 };
510532
511 const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv);533 const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv);
512 defer self.allocator.free(cmd_line);534 defer self.allocator.free(cmd_line);
513535
514 var siStartInfo = windows.STARTUPINFOA {536 var siStartInfo = windows.STARTUPINFOA{
515 .cb = @sizeOf(windows.STARTUPINFOA),537 .cb = @sizeOf(windows.STARTUPINFOA),
516 .hStdError = g_hChildStd_ERR_Wr,538 .hStdError = g_hChildStd_ERR_Wr,
517 .hStdOutput = g_hChildStd_OUT_Wr,539 .hStdOutput = g_hChildStd_OUT_Wr,
...@@ -534,19 +556,11 @@ pub const ChildProcess = struct {...@@ -534,19 +556,11 @@ pub const ChildProcess = struct {
534 };556 };
535 var piProcInfo: windows.PROCESS_INFORMATION = undefined;557 var piProcInfo: windows.PROCESS_INFORMATION = undefined;
536558
537 const cwd_slice = if (self.cwd) |cwd|559 const cwd_slice = if (self.cwd) |cwd| try cstr.addNullByte(self.allocator, cwd) else null;
538 try cstr.addNullByte(self.allocator, cwd)
539 else
540 null
541 ;
542 defer if (cwd_slice) |cwd| self.allocator.free(cwd);560 defer if (cwd_slice) |cwd| self.allocator.free(cwd);
543 const cwd_ptr = if (cwd_slice) |cwd| cwd.ptr else null;561 const cwd_ptr = if (cwd_slice) |cwd| cwd.ptr else null;
544562
545 const maybe_envp_buf = if (self.env_map) |env_map|563 const maybe_envp_buf = if (self.env_map) |env_map| try os.createWindowsEnvBlock(self.allocator, env_map) else null;
546 try os.createWindowsEnvBlock(self.allocator, env_map)
547 else
548 null
549 ;
550 defer if (maybe_envp_buf) |envp_buf| self.allocator.free(envp_buf);564 defer if (maybe_envp_buf) |envp_buf| self.allocator.free(envp_buf);
551 const envp_ptr = if (maybe_envp_buf) |envp_buf| envp_buf.ptr else null;565 const envp_ptr = if (maybe_envp_buf) |envp_buf| envp_buf.ptr else null;
552566
...@@ -563,11 +577,8 @@ pub const ChildProcess = struct {...@@ -563,11 +577,8 @@ pub const ChildProcess = struct {
563 };577 };
564 defer self.allocator.free(app_name);578 defer self.allocator.free(app_name);
565579
566 windowsCreateProcess(app_name.ptr, cmd_line.ptr, envp_ptr, cwd_ptr,580 windowsCreateProcess(app_name.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, &siStartInfo, &piProcInfo) catch |no_path_err| {
567 &siStartInfo, &piProcInfo) catch |no_path_err|581 if (no_path_err != error.FileNotFound) return no_path_err;
568 {
569 if (no_path_err != error.FileNotFound)
570 return no_path_err;
571582
572 const PATH = try os.getEnvVarOwned(self.allocator, "PATH");583 const PATH = try os.getEnvVarOwned(self.allocator, "PATH");
573 defer self.allocator.free(PATH);584 defer self.allocator.free(PATH);
...@@ -577,9 +588,7 @@ pub const ChildProcess = struct {...@@ -577,9 +588,7 @@ pub const ChildProcess = struct {
577 const joined_path = try os.path.join(self.allocator, search_path, app_name);588 const joined_path = try os.path.join(self.allocator, search_path, app_name);
578 defer self.allocator.free(joined_path);589 defer self.allocator.free(joined_path);
579590
580 if (windowsCreateProcess(joined_path.ptr, cmd_line.ptr, envp_ptr, cwd_ptr,591 if (windowsCreateProcess(joined_path.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, &siStartInfo, &piProcInfo)) |_| {
581 &siStartInfo, &piProcInfo)) |_|
582 {
583 break;592 break;
584 } else |err| if (err == error.FileNotFound) {593 } else |err| if (err == error.FileNotFound) {
585 continue;594 continue;
...@@ -609,9 +618,15 @@ pub const ChildProcess = struct {...@@ -609,9 +618,15 @@ pub const ChildProcess = struct {
609 self.thread_handle = piProcInfo.hThread;618 self.thread_handle = piProcInfo.hThread;
610 self.term = null;619 self.term = null;
611620
612 if (self.stdin_behavior == StdIo.Pipe) { os.close(??g_hChildStd_IN_Rd); }621 if (self.stdin_behavior == StdIo.Pipe) {
613 if (self.stderr_behavior == StdIo.Pipe) { os.close(??g_hChildStd_ERR_Wr); }622 os.close(??g_hChildStd_IN_Rd);
614 if (self.stdout_behavior == StdIo.Pipe) { os.close(??g_hChildStd_OUT_Wr); }623 }
624 if (self.stderr_behavior == StdIo.Pipe) {
625 os.close(??g_hChildStd_ERR_Wr);
626 }
627 if (self.stdout_behavior == StdIo.Pipe) {
628 os.close(??g_hChildStd_OUT_Wr);
629 }
615 }630 }
616631
617 fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void {632 fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void {
...@@ -622,15 +637,10 @@ pub const ChildProcess = struct {...@@ -622,15 +637,10 @@ pub const ChildProcess = struct {
622 StdIo.Ignore => try os.posixDup2(dev_null_fd, std_fileno),637 StdIo.Ignore => try os.posixDup2(dev_null_fd, std_fileno),
623 }638 }
624 }639 }
625
626};640};
627641
628fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?&u8,642fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?&u8, lpStartupInfo: &windows.STARTUPINFOA, lpProcessInformation: &windows.PROCESS_INFORMATION) !void {
629 lpStartupInfo: &windows.STARTUPINFOA, lpProcessInformation: &windows.PROCESS_INFORMATION) !void643 if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0, @ptrCast(?&c_void, envp_ptr), cwd_ptr, lpStartupInfo, lpProcessInformation) == 0) {
630{
631 if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0,
632 @ptrCast(?&c_void, envp_ptr), cwd_ptr, lpStartupInfo, lpProcessInformation) == 0)
633 {
634 const err = windows.GetLastError();644 const err = windows.GetLastError();
635 return switch (err) {645 return switch (err) {
636 windows.ERROR.FILE_NOT_FOUND, windows.ERROR.PATH_NOT_FOUND => error.FileNotFound,646 windows.ERROR.FILE_NOT_FOUND, windows.ERROR.PATH_NOT_FOUND => error.FileNotFound,
...@@ -641,18 +651,16 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?...@@ -641,18 +651,16 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?
641 }651 }
642}652}
643653
644
645
646
647/// Caller must dealloc.654/// Caller must dealloc.
648/// Guarantees a null byte at result[result.len].655/// Guarantees a null byte at result[result.len].
649fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) ![]u8 {656fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) ![]u8 {
650 var buf = try Buffer.initSize(allocator, 0);657 var buf = try Buffer.initSize(allocator, 0);
651 defer buf.deinit();658 defer buf.deinit();
652659
660 var buf_stream = &io.BufferOutStream.init(&buf).stream;
661
653 for (argv) |arg, arg_i| {662 for (argv) |arg, arg_i| {
654 if (arg_i != 0)663 if (arg_i != 0) try buf.appendByte(' ');
655 try buf.appendByte(' ');
656 if (mem.indexOfAny(u8, arg, " \t\n\"") == null) {664 if (mem.indexOfAny(u8, arg, " \t\n\"") == null) {
657 try buf.append(arg);665 try buf.append(arg);
658 continue;666 continue;
...@@ -663,18 +671,18 @@ fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8)...@@ -663,18 +671,18 @@ fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8)
663 switch (byte) {671 switch (byte) {
664 '\\' => backslash_count += 1,672 '\\' => backslash_count += 1,
665 '"' => {673 '"' => {
666 try buf.appendByteNTimes('\\', backslash_count * 2 + 1);674 try buf_stream.writeByteNTimes('\\', backslash_count * 2 + 1);
667 try buf.appendByte('"');675 try buf.appendByte('"');
668 backslash_count = 0;676 backslash_count = 0;
669 },677 },
670 else => {678 else => {
671 try buf.appendByteNTimes('\\', backslash_count);679 try buf_stream.writeByteNTimes('\\', backslash_count);
672 try buf.appendByte(byte);680 try buf.appendByte(byte);
673 backslash_count = 0;681 backslash_count = 0;
674 },682 },
675 }683 }
676 }684 }
677 try buf.appendByteNTimes('\\', backslash_count * 2);685 try buf_stream.writeByteNTimes('\\', backslash_count * 2);
678 try buf.appendByte('"');686 try buf.appendByte('"');
679 }687 }
680688
...@@ -686,7 +694,6 @@ fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) void {...@@ -686,7 +694,6 @@ fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) void {
686 if (wr) |h| os.close(h);694 if (wr) |h| os.close(h);
687}695}
688696
689
690// TODO: workaround for bug where the `const` from `&const` is dropped when the type is697// TODO: workaround for bug where the `const` from `&const` is dropped when the type is
691// a namespace field lookup698// a namespace field lookup
692const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;699const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;
...@@ -715,8 +722,8 @@ fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const S...@@ -715,8 +722,8 @@ fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const S
715 try windowsMakePipe(&rd_h, &wr_h, sattr);722 try windowsMakePipe(&rd_h, &wr_h, sattr);
716 errdefer windowsDestroyPipe(rd_h, wr_h);723 errdefer windowsDestroyPipe(rd_h, wr_h);
717 try windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0);724 try windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0);
718 *rd = rd_h;725 rd.* = rd_h;
719 *wr = wr_h;726 wr.* = wr_h;
720}727}
721728
722fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) !void {729fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) !void {
...@@ -725,8 +732,8 @@ fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const...@@ -725,8 +732,8 @@ fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const
725 try windowsMakePipe(&rd_h, &wr_h, sattr);732 try windowsMakePipe(&rd_h, &wr_h, sattr);
726 errdefer windowsDestroyPipe(rd_h, wr_h);733 errdefer windowsDestroyPipe(rd_h, wr_h);
727 try windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0);734 try windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0);
728 *rd = rd_h;735 rd.* = rd_h;
729 *wr = wr_h;736 wr.* = wr_h;
730}737}
731738
732fn makePipe() ![2]i32 {739fn makePipe() ![2]i32 {
...@@ -742,8 +749,8 @@ fn makePipe() ![2]i32 {...@@ -742,8 +749,8 @@ fn makePipe() ![2]i32 {
742}749}
743750
744fn destroyPipe(pipe: &const [2]i32) void {751fn destroyPipe(pipe: &const [2]i32) void {
745 os.close((*pipe)[0]);752 os.close((pipe.*)[0]);
746 os.close((*pipe)[1]);753 os.close((pipe.*)[1]);
747}754}
748755
749// Child of fork calls this to report an error to the fork parent.756// Child of fork calls this to report an error to the fork parent.
std/os/darwin.zig+247-99
...@@ -10,33 +10,75 @@ pub const STDIN_FILENO = 0;...@@ -10,33 +10,75 @@ pub const STDIN_FILENO = 0;
10pub const STDOUT_FILENO = 1;10pub const STDOUT_FILENO = 1;
11pub const STDERR_FILENO = 2;11pub const STDERR_FILENO = 2;
1212
13pub const PROT_NONE = 0x00; /// [MC2] no permissions13/// [MC2] no permissions
14pub const PROT_READ = 0x01; /// [MC2] pages can be read14pub const PROT_NONE = 0x00;
15pub const PROT_WRITE = 0x02; /// [MC2] pages can be written15
16pub const PROT_EXEC = 0x04; /// [MC2] pages can be executed16/// [MC2] pages can be read
1717pub const PROT_READ = 0x01;
18pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space18
19pub const MAP_FILE = 0x0000; /// map from file (default)19/// [MC2] pages can be written
20pub const MAP_FIXED = 0x0010; /// interpret addr exactly20pub const PROT_WRITE = 0x02;
21pub const MAP_HASSEMAPHORE = 0x0200; /// region may contain semaphores21
22pub const MAP_PRIVATE = 0x0002; /// changes are private22/// [MC2] pages can be executed
23pub const MAP_SHARED = 0x0001; /// share changes23pub const PROT_EXEC = 0x04;
24pub const MAP_NOCACHE = 0x0400; /// don't cache pages for this mapping24
25pub const MAP_NORESERVE = 0x0040; /// don't reserve needed swap area25/// allocated from memory, swap space
26pub const MAP_ANONYMOUS = 0x1000;
27
28/// map from file (default)
29pub const MAP_FILE = 0x0000;
30
31/// interpret addr exactly
32pub const MAP_FIXED = 0x0010;
33
34/// region may contain semaphores
35pub const MAP_HASSEMAPHORE = 0x0200;
36
37/// changes are private
38pub const MAP_PRIVATE = 0x0002;
39
40/// share changes
41pub const MAP_SHARED = 0x0001;
42
43/// don't cache pages for this mapping
44pub const MAP_NOCACHE = 0x0400;
45
46/// don't reserve needed swap area
47pub const MAP_NORESERVE = 0x0040;
26pub const MAP_FAILED = @maxValue(usize);48pub const MAP_FAILED = @maxValue(usize);
2749
28pub const WNOHANG = 0x00000001; /// [XSI] no hang in wait/no child to reap50/// [XSI] no hang in wait/no child to reap
29pub const WUNTRACED = 0x00000002; /// [XSI] notify on stop, untraced child51pub const WNOHANG = 0x00000001;
52
53/// [XSI] notify on stop, untraced child
54pub const WUNTRACED = 0x00000002;
55
56/// take signal on signal stack
57pub const SA_ONSTACK = 0x0001;
58
59/// restart system on signal return
60pub const SA_RESTART = 0x0002;
61
62/// reset to SIG_DFL when taking signal
63pub const SA_RESETHAND = 0x0004;
64
65/// do not generate SIGCHLD on child stop
66pub const SA_NOCLDSTOP = 0x0008;
67
68/// don't mask the signal we're delivering
69pub const SA_NODEFER = 0x0010;
70
71/// don't keep zombies around
72pub const SA_NOCLDWAIT = 0x0020;
73
74/// signal handler with SA_SIGINFO args
75pub const SA_SIGINFO = 0x0040;
76
77/// do not bounce off kernel's sigtramp
78pub const SA_USERTRAMP = 0x0100;
3079
31pub const SA_ONSTACK = 0x0001; /// take signal on signal stack80/// signal handler with SA_SIGINFO args with 64bit regs information
32pub const SA_RESTART = 0x0002; /// restart system on signal return81pub const SA_64REGSET = 0x0200;
33pub const SA_RESETHAND = 0x0004; /// reset to SIG_DFL when taking signal
34pub const SA_NOCLDSTOP = 0x0008; /// do not generate SIGCHLD on child stop
35pub const SA_NODEFER = 0x0010; /// don't mask the signal we're delivering
36pub const SA_NOCLDWAIT = 0x0020; /// don't keep zombies around
37pub const SA_SIGINFO = 0x0040; /// signal handler with SA_SIGINFO args
38pub const SA_USERTRAMP = 0x0100; /// do not bounce off kernel's sigtramp
39pub const SA_64REGSET = 0x0200; /// signal handler with SA_SIGINFO args with 64bit regs information
4082
41pub const O_LARGEFILE = 0x0000;83pub const O_LARGEFILE = 0x0000;
42pub const O_PATH = 0x0000;84pub const O_PATH = 0x0000;
...@@ -46,20 +88,47 @@ pub const X_OK = 1;...@@ -46,20 +88,47 @@ pub const X_OK = 1;
46pub const W_OK = 2;88pub const W_OK = 2;
47pub const R_OK = 4;89pub const R_OK = 4;
4890
49pub const O_RDONLY = 0x0000; /// open for reading only91/// open for reading only
50pub const O_WRONLY = 0x0001; /// open for writing only92pub const O_RDONLY = 0x0000;
51pub const O_RDWR = 0x0002; /// open for reading and writing93
52pub const O_NONBLOCK = 0x0004; /// do not block on open or for data to become available94/// open for writing only
53pub const O_APPEND = 0x0008; /// append on each write95pub const O_WRONLY = 0x0001;
54pub const O_CREAT = 0x0200; /// create file if it does not exist96
55pub const O_TRUNC = 0x0400; /// truncate size to 097/// open for reading and writing
56pub const O_EXCL = 0x0800; /// error if O_CREAT and the file exists98pub const O_RDWR = 0x0002;
57pub const O_SHLOCK = 0x0010; /// atomically obtain a shared lock99
58pub const O_EXLOCK = 0x0020; /// atomically obtain an exclusive lock100/// do not block on open or for data to become available
59pub const O_NOFOLLOW = 0x0100; /// do not follow symlinks101pub const O_NONBLOCK = 0x0004;
60pub const O_SYMLINK = 0x200000; /// allow open of symlinks102
61pub const O_EVTONLY = 0x8000; /// descriptor requested for event notifications only103/// append on each write
62pub const O_CLOEXEC = 0x1000000; /// mark as close-on-exec104pub const O_APPEND = 0x0008;
105
106/// create file if it does not exist
107pub const O_CREAT = 0x0200;
108
109/// truncate size to 0
110pub const O_TRUNC = 0x0400;
111
112/// error if O_CREAT and the file exists
113pub const O_EXCL = 0x0800;
114
115/// atomically obtain a shared lock
116pub const O_SHLOCK = 0x0010;
117
118/// atomically obtain an exclusive lock
119pub const O_EXLOCK = 0x0020;
120
121/// do not follow symlinks
122pub const O_NOFOLLOW = 0x0100;
123
124/// allow open of symlinks
125pub const O_SYMLINK = 0x200000;
126
127/// descriptor requested for event notifications only
128pub const O_EVTONLY = 0x8000;
129
130/// mark as close-on-exec
131pub const O_CLOEXEC = 0x1000000;
63132
64pub const O_ACCMODE = 3;133pub const O_ACCMODE = 3;
65pub const O_ALERT = 536870912;134pub const O_ALERT = 536870912;
...@@ -87,52 +156,136 @@ pub const DT_LNK = 10;...@@ -87,52 +156,136 @@ pub const DT_LNK = 10;
87pub const DT_SOCK = 12;156pub const DT_SOCK = 12;
88pub const DT_WHT = 14;157pub const DT_WHT = 14;
89158
90pub const SIG_BLOCK = 1; /// block specified signal set159/// block specified signal set
91pub const SIG_UNBLOCK = 2; /// unblock specified signal set160pub const SIG_BLOCK = 1;
92pub const SIG_SETMASK = 3; /// set specified signal set161
93162/// unblock specified signal set
94pub const SIGHUP = 1; /// hangup163pub const SIG_UNBLOCK = 2;
95pub const SIGINT = 2; /// interrupt164
96pub const SIGQUIT = 3; /// quit165/// set specified signal set
97pub const SIGILL = 4; /// illegal instruction (not reset when caught)166pub const SIG_SETMASK = 3;
98pub const SIGTRAP = 5; /// trace trap (not reset when caught)167
99pub const SIGABRT = 6; /// abort()168/// hangup
100pub const SIGPOLL = 7; /// pollable event ([XSR] generated, not supported)169pub const SIGHUP = 1;
101pub const SIGIOT = SIGABRT; /// compatibility170
102pub const SIGEMT = 7; /// EMT instruction171/// interrupt
103pub const SIGFPE = 8; /// floating point exception172pub const SIGINT = 2;
104pub const SIGKILL = 9; /// kill (cannot be caught or ignored)173
105pub const SIGBUS = 10; /// bus error174/// quit
106pub const SIGSEGV = 11; /// segmentation violation175pub const SIGQUIT = 3;
107pub const SIGSYS = 12; /// bad argument to system call176
108pub const SIGPIPE = 13; /// write on a pipe with no one to read it177/// illegal instruction (not reset when caught)
109pub const SIGALRM = 14; /// alarm clock178pub const SIGILL = 4;
110pub const SIGTERM = 15; /// software termination signal from kill179
111pub const SIGURG = 16; /// urgent condition on IO channel180/// trace trap (not reset when caught)
112pub const SIGSTOP = 17; /// sendable stop signal not from tty181pub const SIGTRAP = 5;
113pub const SIGTSTP = 18; /// stop signal from tty182
114pub const SIGCONT = 19; /// continue a stopped process183/// abort()
115pub const SIGCHLD = 20; /// to parent on child stop or exit184pub const SIGABRT = 6;
116pub const SIGTTIN = 21; /// to readers pgrp upon background tty read185
117pub const SIGTTOU = 22; /// like TTIN for output if (tp->t_local&LTOSTOP)186/// pollable event ([XSR] generated, not supported)
118pub const SIGIO = 23; /// input/output possible signal187pub const SIGPOLL = 7;
119pub const SIGXCPU = 24; /// exceeded CPU time limit188
120pub const SIGXFSZ = 25; /// exceeded file size limit189/// compatibility
121pub const SIGVTALRM = 26; /// virtual time alarm190pub const SIGIOT = SIGABRT;
122pub const SIGPROF = 27; /// profiling time alarm191
123pub const SIGWINCH = 28; /// window size changes192/// EMT instruction
124pub const SIGINFO = 29; /// information request193pub const SIGEMT = 7;
125pub const SIGUSR1 = 30; /// user defined signal 1194
126pub const SIGUSR2 = 31; /// user defined signal 2195/// floating point exception
127196pub const SIGFPE = 8;
128fn wstatus(x: i32) i32 { return x & 0o177; }197
198/// kill (cannot be caught or ignored)
199pub const SIGKILL = 9;
200
201/// bus error
202pub const SIGBUS = 10;
203
204/// segmentation violation
205pub const SIGSEGV = 11;
206
207/// bad argument to system call
208pub const SIGSYS = 12;
209
210/// write on a pipe with no one to read it
211pub const SIGPIPE = 13;
212
213/// alarm clock
214pub const SIGALRM = 14;
215
216/// software termination signal from kill
217pub const SIGTERM = 15;
218
219/// urgent condition on IO channel
220pub const SIGURG = 16;
221
222/// sendable stop signal not from tty
223pub const SIGSTOP = 17;
224
225/// stop signal from tty
226pub const SIGTSTP = 18;
227
228/// continue a stopped process
229pub const SIGCONT = 19;
230
231/// to parent on child stop or exit
232pub const SIGCHLD = 20;
233
234/// to readers pgrp upon background tty read
235pub const SIGTTIN = 21;
236
237/// like TTIN for output if (tp->t_local&LTOSTOP)
238pub const SIGTTOU = 22;
239
240/// input/output possible signal
241pub const SIGIO = 23;
242
243/// exceeded CPU time limit
244pub const SIGXCPU = 24;
245
246/// exceeded file size limit
247pub const SIGXFSZ = 25;
248
249/// virtual time alarm
250pub const SIGVTALRM = 26;
251
252/// profiling time alarm
253pub const SIGPROF = 27;
254
255/// window size changes
256pub const SIGWINCH = 28;
257
258/// information request
259pub const SIGINFO = 29;
260
261/// user defined signal 1
262pub const SIGUSR1 = 30;
263
264/// user defined signal 2
265pub const SIGUSR2 = 31;
266
267fn wstatus(x: i32) i32 {
268 return x & 0o177;
269}
129const wstopped = 0o177;270const wstopped = 0o177;
130pub fn WEXITSTATUS(x: i32) i32 { return x >> 8; }271pub fn WEXITSTATUS(x: i32) i32 {
131pub fn WTERMSIG(x: i32) i32 { return wstatus(x); }272 return x >> 8;
132pub fn WSTOPSIG(x: i32) i32 { return x >> 8; }273}
133pub fn WIFEXITED(x: i32) bool { return wstatus(x) == 0; }274pub fn WTERMSIG(x: i32) i32 {
134pub fn WIFSTOPPED(x: i32) bool { return wstatus(x) == wstopped and WSTOPSIG(x) != 0x13; }275 return wstatus(x);
135pub fn WIFSIGNALED(x: i32) bool { return wstatus(x) != wstopped and wstatus(x) != 0; }276}
277pub fn WSTOPSIG(x: i32) i32 {
278 return x >> 8;
279}
280pub fn WIFEXITED(x: i32) bool {
281 return wstatus(x) == 0;
282}
283pub fn WIFSTOPPED(x: i32) bool {
284 return wstatus(x) == wstopped and WSTOPSIG(x) != 0x13;
285}
286pub fn WIFSIGNALED(x: i32) bool {
287 return wstatus(x) != wstopped and wstatus(x) != 0;
288}
136289
137/// Get the errno from a syscall return value, or 0 for no error.290/// Get the errno from a syscall return value, or 0 for no error.
138pub fn getErrno(r: usize) usize {291pub fn getErrno(r: usize) usize {
...@@ -184,11 +337,8 @@ pub fn write(fd: i32, buf: &const u8, nbyte: usize) usize {...@@ -184,11 +337,8 @@ pub fn write(fd: i32, buf: &const u8, nbyte: usize) usize {
184 return errnoWrap(c.write(fd, @ptrCast(&const c_void, buf), nbyte));337 return errnoWrap(c.write(fd, @ptrCast(&const c_void, buf), nbyte));
185}338}
186339
187pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: u32, fd: i32,340pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {
188 offset: isize) usize341 const ptr_result = c.mmap(@ptrCast(&c_void, address), length, @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);
189{
190 const ptr_result = c.mmap(@ptrCast(&c_void, address), length,
191 @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);
192 const isize_result = @bitCast(isize, @ptrToInt(ptr_result));342 const isize_result = @bitCast(isize, @ptrToInt(ptr_result));
193 return errnoWrap(isize_result);343 return errnoWrap(isize_result);
194}344}
...@@ -202,7 +352,7 @@ pub fn unlink(path: &const u8) usize {...@@ -202,7 +352,7 @@ pub fn unlink(path: &const u8) usize {
202}352}
203353
204pub fn getcwd(buf: &u8, size: usize) usize {354pub fn getcwd(buf: &u8, size: usize) usize {
205 return if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(*c._errno())) else 0;355 return if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(c._errno().*)) else 0;
206}356}
207357
208pub fn waitpid(pid: i32, status: &i32, options: u32) usize {358pub fn waitpid(pid: i32, status: &i32, options: u32) usize {
...@@ -223,7 +373,6 @@ pub fn pipe(fds: &[2]i32) usize {...@@ -223,7 +373,6 @@ pub fn pipe(fds: &[2]i32) usize {
223 return errnoWrap(c.pipe(@ptrCast(&c_int, fds)));373 return errnoWrap(c.pipe(@ptrCast(&c_int, fds)));
224}374}
225375
226
227pub fn getdirentries64(fd: i32, buf_ptr: &u8, buf_len: usize, basep: &i64) usize {376pub fn getdirentries64(fd: i32, buf_ptr: &u8, buf_len: usize, basep: &i64) usize {
228 return errnoWrap(@bitCast(isize, c.__getdirentries64(fd, buf_ptr, buf_len, basep)));377 return errnoWrap(@bitCast(isize, c.__getdirentries64(fd, buf_ptr, buf_len, basep)));
229}378}
...@@ -269,7 +418,7 @@ pub fn nanosleep(req: &const timespec, rem: ?&timespec) usize {...@@ -269,7 +418,7 @@ pub fn nanosleep(req: &const timespec, rem: ?&timespec) usize {
269}418}
270419
271pub fn realpath(noalias filename: &const u8, noalias resolved_name: &u8) usize {420pub fn realpath(noalias filename: &const u8, noalias resolved_name: &u8) usize {
272 return if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(*c._errno())) else 0;421 return if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(c._errno().*)) else 0;
273}422}
274423
275pub fn setreuid(ruid: u32, euid: u32) usize {424pub fn setreuid(ruid: u32, euid: u32) usize {
...@@ -287,8 +436,8 @@ pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&s...@@ -287,8 +436,8 @@ pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&s
287pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigaction) usize {436pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigaction) usize {
288 assert(sig != SIGKILL);437 assert(sig != SIGKILL);
289 assert(sig != SIGSTOP);438 assert(sig != SIGSTOP);
290 var cact = c.Sigaction {439 var cact = c.Sigaction{
291 .handler = @ptrCast(extern fn(c_int)void, act.handler),440 .handler = @ptrCast(extern fn(c_int) void, act.handler),
292 .sa_flags = @bitCast(c_int, act.flags),441 .sa_flags = @bitCast(c_int, act.flags),
293 .sa_mask = act.mask,442 .sa_mask = act.mask,
294 };443 };
...@@ -298,8 +447,8 @@ pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigacti...@@ -298,8 +447,8 @@ pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigacti
298 return result;447 return result;
299 }448 }
300 if (oact) |old| {449 if (oact) |old| {
301 *old = Sigaction {450 old.* = Sigaction{
302 .handler = @ptrCast(extern fn(i32)void, coact.handler),451 .handler = @ptrCast(extern fn(i32) void, coact.handler),
303 .flags = @bitCast(u32, coact.sa_flags),452 .flags = @bitCast(u32, coact.sa_flags),
304 .mask = coact.sa_mask,453 .mask = coact.sa_mask,
305 };454 };
...@@ -319,23 +468,22 @@ pub const sockaddr = c.sockaddr;...@@ -319,23 +468,22 @@ pub const sockaddr = c.sockaddr;
319468
320/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.469/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
321pub const Sigaction = struct {470pub const Sigaction = struct {
322 handler: extern fn(i32)void,471 handler: extern fn(i32) void,
323 mask: sigset_t,472 mask: sigset_t,
324 flags: u32,473 flags: u32,
325};474};
326475
327pub fn sigaddset(set: &sigset_t, signo: u5) void {476pub fn sigaddset(set: &sigset_t, signo: u5) void {
328 *set |= u32(1) << (signo - 1);477 set.* |= u32(1) << (signo - 1);
329}478}
330479
331/// Takes the return value from a syscall and formats it back in the way480/// Takes the return value from a syscall and formats it back in the way
332/// that the kernel represents it to libc. Errno was a mistake, let's make481/// that the kernel represents it to libc. Errno was a mistake, let's make
333/// it go away forever.482/// it go away forever.
334fn errnoWrap(value: isize) usize {483fn errnoWrap(value: isize) usize {
335 return @bitCast(usize, if (value == -1) -isize(*c._errno()) else value);484 return @bitCast(usize, if (value == -1) -isize(c._errno().*) else value);
336}485}
337486
338
339pub const timezone = c.timezone;487pub const timezone = c.timezone;
340pub const timeval = c.timeval;488pub const timeval = c.timeval;
341pub const mach_timebase_info_data = c.mach_timebase_info_data;489pub const mach_timebase_info_data = c.mach_timebase_info_data;
std/os/darwin_errno.zig+294-108
...@@ -1,142 +1,328 @@...@@ -1,142 +1,328 @@
1/// Operation not permitted
2pub const EPERM = 1;
13
2pub const EPERM = 1; /// Operation not permitted4/// No such file or directory
3pub const ENOENT = 2; /// No such file or directory5pub const ENOENT = 2;
4pub const ESRCH = 3; /// No such process6
5pub const EINTR = 4; /// Interrupted system call7/// No such process
6pub const EIO = 5; /// Input/output error8pub const ESRCH = 3;
7pub const ENXIO = 6; /// Device not configured9
8pub const E2BIG = 7; /// Argument list too long10/// Interrupted system call
9pub const ENOEXEC = 8; /// Exec format error11pub const EINTR = 4;
10pub const EBADF = 9; /// Bad file descriptor12
11pub const ECHILD = 10; /// No child processes13/// Input/output error
12pub const EDEADLK = 11; /// Resource deadlock avoided14pub const EIO = 5;
1315
14pub const ENOMEM = 12; /// Cannot allocate memory16/// Device not configured
15pub const EACCES = 13; /// Permission denied17pub const ENXIO = 6;
16pub const EFAULT = 14; /// Bad address18
17pub const ENOTBLK = 15; /// Block device required19/// Argument list too long
18pub const EBUSY = 16; /// Device / Resource busy20pub const E2BIG = 7;
19pub const EEXIST = 17; /// File exists21
20pub const EXDEV = 18; /// Cross-device link22/// Exec format error
21pub const ENODEV = 19; /// Operation not supported by device23pub const ENOEXEC = 8;
22pub const ENOTDIR = 20; /// Not a directory24
23pub const EISDIR = 21; /// Is a directory25/// Bad file descriptor
24pub const EINVAL = 22; /// Invalid argument26pub const EBADF = 9;
25pub const ENFILE = 23; /// Too many open files in system27
26pub const EMFILE = 24; /// Too many open files28/// No child processes
27pub const ENOTTY = 25; /// Inappropriate ioctl for device29pub const ECHILD = 10;
28pub const ETXTBSY = 26; /// Text file busy30
29pub const EFBIG = 27; /// File too large31/// Resource deadlock avoided
30pub const ENOSPC = 28; /// No space left on device32pub const EDEADLK = 11;
31pub const ESPIPE = 29; /// Illegal seek33
32pub const EROFS = 30; /// Read-only file system34/// Cannot allocate memory
33pub const EMLINK = 31; /// Too many links35pub const ENOMEM = 12;
34pub const EPIPE = 32; /// Broken pipe36
37/// Permission denied
38pub const EACCES = 13;
39
40/// Bad address
41pub const EFAULT = 14;
42
43/// Block device required
44pub const ENOTBLK = 15;
45
46/// Device / Resource busy
47pub const EBUSY = 16;
48
49/// File exists
50pub const EEXIST = 17;
51
52/// Cross-device link
53pub const EXDEV = 18;
54
55/// Operation not supported by device
56pub const ENODEV = 19;
57
58/// Not a directory
59pub const ENOTDIR = 20;
60
61/// Is a directory
62pub const EISDIR = 21;
63
64/// Invalid argument
65pub const EINVAL = 22;
66
67/// Too many open files in system
68pub const ENFILE = 23;
69
70/// Too many open files
71pub const EMFILE = 24;
72
73/// Inappropriate ioctl for device
74pub const ENOTTY = 25;
75
76/// Text file busy
77pub const ETXTBSY = 26;
78
79/// File too large
80pub const EFBIG = 27;
81
82/// No space left on device
83pub const ENOSPC = 28;
84
85/// Illegal seek
86pub const ESPIPE = 29;
87
88/// Read-only file system
89pub const EROFS = 30;
90
91/// Too many links
92pub const EMLINK = 31;
93/// Broken pipe
3594
36// math software95// math software
37pub const EDOM = 33; /// Numerical argument out of domain96pub const EPIPE = 32;
38pub const ERANGE = 34; /// Result too large97
98/// Numerical argument out of domain
99pub const EDOM = 33;
100/// Result too large
39101
40// non-blocking and interrupt i/o102// non-blocking and interrupt i/o
41pub const EAGAIN = 35; /// Resource temporarily unavailable103pub const ERANGE = 34;
42pub const EWOULDBLOCK = EAGAIN; /// Operation would block104
43pub const EINPROGRESS = 36; /// Operation now in progress105/// Resource temporarily unavailable
44pub const EALREADY = 37; /// Operation already in progress106pub const EAGAIN = 35;
107
108/// Operation would block
109pub const EWOULDBLOCK = EAGAIN;
110
111/// Operation now in progress
112pub const EINPROGRESS = 36;
113/// Operation already in progress
45114
46// ipc/network software -- argument errors115// ipc/network software -- argument errors
47pub const ENOTSOCK = 38; /// Socket operation on non-socket116pub const EALREADY = 37;
48pub const EDESTADDRREQ = 39; /// Destination address required117
49pub const EMSGSIZE = 40; /// Message too long118/// Socket operation on non-socket
50pub const EPROTOTYPE = 41; /// Protocol wrong type for socket119pub const ENOTSOCK = 38;
51pub const ENOPROTOOPT = 42; /// Protocol not available120
52pub const EPROTONOSUPPORT = 43; /// Protocol not supported121/// Destination address required
122pub const EDESTADDRREQ = 39;
123
124/// Message too long
125pub const EMSGSIZE = 40;
126
127/// Protocol wrong type for socket
128pub const EPROTOTYPE = 41;
129
130/// Protocol not available
131pub const ENOPROTOOPT = 42;
132
133/// Protocol not supported
134pub const EPROTONOSUPPORT = 43;
135
136/// Socket type not supported
137pub const ESOCKTNOSUPPORT = 44;
53138
54pub const ESOCKTNOSUPPORT = 44; /// Socket type not supported139/// Operation not supported
140pub const ENOTSUP = 45;
55141
56pub const ENOTSUP = 45; /// Operation not supported142/// Protocol family not supported
143pub const EPFNOSUPPORT = 46;
57144
58pub const EPFNOSUPPORT = 46; /// Protocol family not supported145/// Address family not supported by protocol family
59pub const EAFNOSUPPORT = 47; /// Address family not supported by protocol family146pub const EAFNOSUPPORT = 47;
60pub const EADDRINUSE = 48; /// Address already in use147
61pub const EADDRNOTAVAIL = 49; /// Can't assign requested address148/// Address already in use
149pub const EADDRINUSE = 48;
150/// Can't assign requested address
62151
63// ipc/network software -- operational errors152// ipc/network software -- operational errors
64pub const ENETDOWN = 50; /// Network is down153pub const EADDRNOTAVAIL = 49;
65pub const ENETUNREACH = 51; /// Network is unreachable154
66pub const ENETRESET = 52; /// Network dropped connection on reset155/// Network is down
67pub const ECONNABORTED = 53; /// Software caused connection abort156pub const ENETDOWN = 50;
68pub const ECONNRESET = 54; /// Connection reset by peer157
69pub const ENOBUFS = 55; /// No buffer space available158/// Network is unreachable
70pub const EISCONN = 56; /// Socket is already connected159pub const ENETUNREACH = 51;
71pub const ENOTCONN = 57; /// Socket is not connected160
161/// Network dropped connection on reset
162pub const ENETRESET = 52;
163
164/// Software caused connection abort
165pub const ECONNABORTED = 53;
166
167/// Connection reset by peer
168pub const ECONNRESET = 54;
169
170/// No buffer space available
171pub const ENOBUFS = 55;
172
173/// Socket is already connected
174pub const EISCONN = 56;
175
176/// Socket is not connected
177pub const ENOTCONN = 57;
178
179/// Can't send after socket shutdown
180pub const ESHUTDOWN = 58;
72181
73pub const ESHUTDOWN = 58; /// Can't send after socket shutdown182/// Too many references: can't splice
74pub const ETOOMANYREFS = 59; /// Too many references: can't splice183pub const ETOOMANYREFS = 59;
75184
76pub const ETIMEDOUT = 60; /// Operation timed out185/// Operation timed out
77pub const ECONNREFUSED = 61; /// Connection refused186pub const ETIMEDOUT = 60;
78187
79pub const ELOOP = 62; /// Too many levels of symbolic links188/// Connection refused
80pub const ENAMETOOLONG = 63; /// File name too long189pub const ECONNREFUSED = 61;
81190
82pub const EHOSTDOWN = 64; /// Host is down191/// Too many levels of symbolic links
83pub const EHOSTUNREACH = 65; /// No route to host192pub const ELOOP = 62;
84pub const ENOTEMPTY = 66; /// Directory not empty193
194/// File name too long
195pub const ENAMETOOLONG = 63;
196
197/// Host is down
198pub const EHOSTDOWN = 64;
199
200/// No route to host
201pub const EHOSTUNREACH = 65;
202/// Directory not empty
85203
86// quotas & mush204// quotas & mush
87pub const EPROCLIM = 67; /// Too many processes205pub const ENOTEMPTY = 66;
88pub const EUSERS = 68; /// Too many users206
89pub const EDQUOT = 69; /// Disc quota exceeded207/// Too many processes
208pub const EPROCLIM = 67;
209
210/// Too many users
211pub const EUSERS = 68;
212/// Disc quota exceeded
90213
91// Network File System214// Network File System
92pub const ESTALE = 70; /// Stale NFS file handle215pub const EDQUOT = 69;
93pub const EREMOTE = 71; /// Too many levels of remote in path216
94pub const EBADRPC = 72; /// RPC struct is bad217/// Stale NFS file handle
95pub const ERPCMISMATCH = 73; /// RPC version wrong218pub const ESTALE = 70;
96pub const EPROGUNAVAIL = 74; /// RPC prog. not avail219
97pub const EPROGMISMATCH = 75; /// Program version wrong220/// Too many levels of remote in path
98pub const EPROCUNAVAIL = 76; /// Bad procedure for program221pub const EREMOTE = 71;
222
223/// RPC struct is bad
224pub const EBADRPC = 72;
225
226/// RPC version wrong
227pub const ERPCMISMATCH = 73;
228
229/// RPC prog. not avail
230pub const EPROGUNAVAIL = 74;
99231
100pub const ENOLCK = 77; /// No locks available232/// Program version wrong
101pub const ENOSYS = 78; /// Function not implemented233pub const EPROGMISMATCH = 75;
102234
103pub const EFTYPE = 79; /// Inappropriate file type or format235/// Bad procedure for program
104pub const EAUTH = 80; /// Authentication error236pub const EPROCUNAVAIL = 76;
105pub const ENEEDAUTH = 81; /// Need authenticator237
238/// No locks available
239pub const ENOLCK = 77;
240
241/// Function not implemented
242pub const ENOSYS = 78;
243
244/// Inappropriate file type or format
245pub const EFTYPE = 79;
246
247/// Authentication error
248pub const EAUTH = 80;
249/// Need authenticator
106250
107// Intelligent device errors251// Intelligent device errors
108pub const EPWROFF = 82; /// Device power is off252pub const ENEEDAUTH = 81;
109pub const EDEVERR = 83; /// Device error, e.g. paper out253
254/// Device power is off
255pub const EPWROFF = 82;
110256
111pub const EOVERFLOW = 84; /// Value too large to be stored in data type257/// Device error, e.g. paper out
258pub const EDEVERR = 83;
259/// Value too large to be stored in data type
112260
113// Program loading errors261// Program loading errors
114pub const EBADEXEC = 85; /// Bad executable262pub const EOVERFLOW = 84;
115pub const EBADARCH = 86; /// Bad CPU type in executable263
116pub const ESHLIBVERS = 87; /// Shared library version mismatch264/// Bad executable
117pub const EBADMACHO = 88; /// Malformed Macho file265pub const EBADEXEC = 85;
266
267/// Bad CPU type in executable
268pub const EBADARCH = 86;
269
270/// Shared library version mismatch
271pub const ESHLIBVERS = 87;
272
273/// Malformed Macho file
274pub const EBADMACHO = 88;
275
276/// Operation canceled
277pub const ECANCELED = 89;
278
279/// Identifier removed
280pub const EIDRM = 90;
281
282/// No message of desired type
283pub const ENOMSG = 91;
284
285/// Illegal byte sequence
286pub const EILSEQ = 92;
287
288/// Attribute not found
289pub const ENOATTR = 93;
290
291/// Bad message
292pub const EBADMSG = 94;
293
294/// Reserved
295pub const EMULTIHOP = 95;
296
297/// No message available on STREAM
298pub const ENODATA = 96;
299
300/// Reserved
301pub const ENOLINK = 97;
302
303/// No STREAM resources
304pub const ENOSR = 98;
305
306/// Not a STREAM
307pub const ENOSTR = 99;
118308
119pub const ECANCELED = 89; /// Operation canceled309/// Protocol error
310pub const EPROTO = 100;
120311
121pub const EIDRM = 90; /// Identifier removed312/// STREAM ioctl timeout
122pub const ENOMSG = 91; /// No message of desired type313pub const ETIME = 101;
123pub const EILSEQ = 92; /// Illegal byte sequence
124pub const ENOATTR = 93; /// Attribute not found
125314
126pub const EBADMSG = 94; /// Bad message315/// No such policy registered
127pub const EMULTIHOP = 95; /// Reserved316pub const ENOPOLICY = 103;
128pub const ENODATA = 96; /// No message available on STREAM
129pub const ENOLINK = 97; /// Reserved
130pub const ENOSR = 98; /// No STREAM resources
131pub const ENOSTR = 99; /// Not a STREAM
132pub const EPROTO = 100; /// Protocol error
133pub const ETIME = 101; /// STREAM ioctl timeout
134317
135pub const ENOPOLICY = 103; /// No such policy registered318/// State not recoverable
319pub const ENOTRECOVERABLE = 104;
136320
137pub const ENOTRECOVERABLE = 104; /// State not recoverable321/// Previous owner died
138pub const EOWNERDEAD = 105; /// Previous owner died322pub const EOWNERDEAD = 105;
139323
140pub const EQFULL = 106; /// Interface output queue is full324/// Interface output queue is full
141pub const ELAST = 106; /// Must be equal largest errno325pub const EQFULL = 106;
142326
327/// Must be equal largest errno
328pub const ELAST = 106;
std/os/epoch.zig+23-23
...@@ -1,26 +1,26 @@...@@ -1,26 +1,26 @@
1/// Epoch reference times in terms of their difference from1/// Epoch reference times in terms of their difference from
2/// posix epoch in seconds.2/// posix epoch in seconds.
3pub const posix = 0; //Jan 01, 1970 AD3pub const posix = 0; //Jan 01, 1970 AD
4pub const dos = 315532800; //Jan 01, 1980 AD4pub const dos = 315532800; //Jan 01, 1980 AD
5pub const ios = 978307200; //Jan 01, 2001 AD5pub const ios = 978307200; //Jan 01, 2001 AD
6pub const openvms = -3506716800; //Nov 17, 1858 AD6pub const openvms = -3506716800; //Nov 17, 1858 AD
7pub const zos = -2208988800; //Jan 01, 1900 AD7pub const zos = -2208988800; //Jan 01, 1900 AD
8pub const windows = -11644473600; //Jan 01, 1601 AD8pub const windows = -11644473600; //Jan 01, 1601 AD
9pub const amiga = 252460800; //Jan 01, 1978 AD9pub const amiga = 252460800; //Jan 01, 1978 AD
10pub const pickos = -63244800; //Dec 31, 1967 AD10pub const pickos = -63244800; //Dec 31, 1967 AD
11pub const gps = 315964800; //Jan 06, 1980 AD11pub const gps = 315964800; //Jan 06, 1980 AD
12pub const clr = -62135769600; //Jan 01, 0001 AD12pub const clr = -62135769600; //Jan 01, 0001 AD
1313
14pub const unix = posix;
15pub const android = posix;
16pub const os2 = dos;
17pub const bios = dos;
18pub const vfat = dos;
19pub const ntfs = windows;
20pub const ntp = zos;
21pub const jbase = pickos;
22pub const aros = amiga;
23pub const morphos = amiga;
24pub const brew = gps;
25pub const atsc = gps;
26pub const go = clr;
\ No newline at end of file
14pub const unix = posix;
15pub const android = posix;
16pub const os2 = dos;
17pub const bios = dos;
18pub const vfat = dos;
19pub const ntfs = windows;
20pub const ntp = zos;
21pub const jbase = pickos;
22pub const aros = amiga;
23pub const morphos = amiga;
24pub const brew = gps;
25pub const atsc = gps;
26pub const go = clr;
std/os/file.zig+35-24
...@@ -21,12 +21,18 @@ pub const File = struct {...@@ -21,12 +21,18 @@ pub const File = struct {
21 /// Call close to clean up.21 /// Call close to clean up.
22 pub fn openRead(allocator: &mem.Allocator, path: []const u8) OpenError!File {22 pub fn openRead(allocator: &mem.Allocator, path: []const u8) OpenError!File {
23 if (is_posix) {23 if (is_posix) {
24 const flags = posix.O_LARGEFILE|posix.O_RDONLY;24 const flags = posix.O_LARGEFILE | posix.O_RDONLY;
25 const fd = try os.posixOpen(allocator, path, flags, 0);25 const fd = try os.posixOpen(allocator, path, flags, 0);
26 return openHandle(fd);26 return openHandle(fd);
27 } else if (is_windows) {27 } else if (is_windows) {
28 const handle = try os.windowsOpen(allocator, path, windows.GENERIC_READ, windows.FILE_SHARE_READ,28 const handle = try os.windowsOpen(
29 windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL);29 allocator,
30 path,
31 windows.GENERIC_READ,
32 windows.FILE_SHARE_READ,
33 windows.OPEN_EXISTING,
34 windows.FILE_ATTRIBUTE_NORMAL,
35 );
30 return openHandle(handle);36 return openHandle(handle);
31 } else {37 } else {
32 @compileError("TODO implement openRead for this OS");38 @compileError("TODO implement openRead for this OS");
...@@ -36,7 +42,6 @@ pub const File = struct {...@@ -36,7 +42,6 @@ pub const File = struct {
36 /// Calls `openWriteMode` with os.default_file_mode for the mode.42 /// Calls `openWriteMode` with os.default_file_mode for the mode.
37 pub fn openWrite(allocator: &mem.Allocator, path: []const u8) OpenError!File {43 pub fn openWrite(allocator: &mem.Allocator, path: []const u8) OpenError!File {
38 return openWriteMode(allocator, path, os.default_file_mode);44 return openWriteMode(allocator, path, os.default_file_mode);
39
40 }45 }
4146
42 /// If the path does not exist it will be created.47 /// If the path does not exist it will be created.
...@@ -45,18 +50,22 @@ pub const File = struct {...@@ -45,18 +50,22 @@ pub const File = struct {
45 /// Call close to clean up.50 /// Call close to clean up.
46 pub fn openWriteMode(allocator: &mem.Allocator, path: []const u8, file_mode: os.FileMode) OpenError!File {51 pub fn openWriteMode(allocator: &mem.Allocator, path: []const u8, file_mode: os.FileMode) OpenError!File {
47 if (is_posix) {52 if (is_posix) {
48 const flags = posix.O_LARGEFILE|posix.O_WRONLY|posix.O_CREAT|posix.O_CLOEXEC|posix.O_TRUNC;53 const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC;
49 const fd = try os.posixOpen(allocator, path, flags, file_mode);54 const fd = try os.posixOpen(allocator, path, flags, file_mode);
50 return openHandle(fd);55 return openHandle(fd);
51 } else if (is_windows) {56 } else if (is_windows) {
52 const handle = try os.windowsOpen(allocator, path, windows.GENERIC_WRITE,57 const handle = try os.windowsOpen(
53 windows.FILE_SHARE_WRITE|windows.FILE_SHARE_READ|windows.FILE_SHARE_DELETE,58 allocator,
54 windows.CREATE_ALWAYS, windows.FILE_ATTRIBUTE_NORMAL);59 path,
60 windows.GENERIC_WRITE,
61 windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
62 windows.CREATE_ALWAYS,
63 windows.FILE_ATTRIBUTE_NORMAL,
64 );
55 return openHandle(handle);65 return openHandle(handle);
56 } else {66 } else {
57 @compileError("TODO implement openWriteMode for this OS");67 @compileError("TODO implement openWriteMode for this OS");
58 }68 }
59
60 }69 }
6170
62 /// If the path does not exist it will be created.71 /// If the path does not exist it will be created.
...@@ -65,24 +74,26 @@ pub const File = struct {...@@ -65,24 +74,26 @@ pub const File = struct {
65 /// Call close to clean up.74 /// Call close to clean up.
66 pub fn openWriteNoClobber(allocator: &mem.Allocator, path: []const u8, file_mode: os.FileMode) OpenError!File {75 pub fn openWriteNoClobber(allocator: &mem.Allocator, path: []const u8, file_mode: os.FileMode) OpenError!File {
67 if (is_posix) {76 if (is_posix) {
68 const flags = posix.O_LARGEFILE|posix.O_WRONLY|posix.O_CREAT|posix.O_CLOEXEC|posix.O_EXCL;77 const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_EXCL;
69 const fd = try os.posixOpen(allocator, path, flags, file_mode);78 const fd = try os.posixOpen(allocator, path, flags, file_mode);
70 return openHandle(fd);79 return openHandle(fd);
71 } else if (is_windows) {80 } else if (is_windows) {
72 const handle = try os.windowsOpen(allocator, path, windows.GENERIC_WRITE,81 const handle = try os.windowsOpen(
73 windows.FILE_SHARE_WRITE|windows.FILE_SHARE_READ|windows.FILE_SHARE_DELETE,82 allocator,
74 windows.CREATE_NEW, windows.FILE_ATTRIBUTE_NORMAL);83 path,
84 windows.GENERIC_WRITE,
85 windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
86 windows.CREATE_NEW,
87 windows.FILE_ATTRIBUTE_NORMAL,
88 );
75 return openHandle(handle);89 return openHandle(handle);
76 } else {90 } else {
77 @compileError("TODO implement openWriteMode for this OS");91 @compileError("TODO implement openWriteMode for this OS");
78 }92 }
79
80 }93 }
8194
82 pub fn openHandle(handle: os.FileHandle) File {95 pub fn openHandle(handle: os.FileHandle) File {
83 return File {96 return File{ .handle = handle };
84 .handle = handle,
85 };
86 }97 }
8798
88 pub fn access(allocator: &mem.Allocator, path: []const u8, file_mode: os.FileMode) !bool {99 pub fn access(allocator: &mem.Allocator, path: []const u8, file_mode: os.FileMode) !bool {
...@@ -217,7 +228,7 @@ pub const File = struct {...@@ -217,7 +228,7 @@ pub const File = struct {
217 return result;228 return result;
218 },229 },
219 Os.windows => {230 Os.windows => {
220 var pos : windows.LARGE_INTEGER = undefined;231 var pos: windows.LARGE_INTEGER = undefined;
221 if (windows.SetFilePointerEx(self.handle, 0, &pos, windows.FILE_CURRENT) == 0) {232 if (windows.SetFilePointerEx(self.handle, 0, &pos, windows.FILE_CURRENT) == 0) {
222 const err = windows.GetLastError();233 const err = windows.GetLastError();
223 return switch (err) {234 return switch (err) {
...@@ -268,7 +279,7 @@ pub const File = struct {...@@ -268,7 +279,7 @@ pub const File = struct {
268 }279 }
269 }280 }
270281
271 pub const ModeError = error {282 pub const ModeError = error{
272 BadFd,283 BadFd,
273 SystemResources,284 SystemResources,
274 Unexpected,285 Unexpected,
...@@ -296,7 +307,7 @@ pub const File = struct {...@@ -296,7 +307,7 @@ pub const File = struct {
296 }307 }
297 }308 }
298309
299 pub const ReadError = error {};310 pub const ReadError = error{};
300311
301 pub fn read(self: &File, buffer: []u8) !usize {312 pub fn read(self: &File, buffer: []u8) !usize {
302 if (is_posix) {313 if (is_posix) {
...@@ -306,12 +317,12 @@ pub const File = struct {...@@ -306,12 +317,12 @@ pub const File = struct {
306 const read_err = posix.getErrno(amt_read);317 const read_err = posix.getErrno(amt_read);
307 if (read_err > 0) {318 if (read_err > 0) {
308 switch (read_err) {319 switch (read_err) {
309 posix.EINTR => continue,320 posix.EINTR => continue,
310 posix.EINVAL => unreachable,321 posix.EINVAL => unreachable,
311 posix.EFAULT => unreachable,322 posix.EFAULT => unreachable,
312 posix.EBADF => return error.BadFd,323 posix.EBADF => return error.BadFd,
313 posix.EIO => return error.Io,324 posix.EIO => return error.Io,
314 else => return os.unexpectedErrorPosix(read_err),325 else => return os.unexpectedErrorPosix(read_err),
315 }326 }
316 }327 }
317 if (amt_read == 0) return index;328 if (amt_read == 0) return index;
std/os/get_user_id.zig+3-3
...@@ -74,7 +74,7 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo {...@@ -74,7 +74,7 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo {
74 '\n' => return error.CorruptPasswordFile,74 '\n' => return error.CorruptPasswordFile,
75 else => {75 else => {
76 const digit = switch (byte) {76 const digit = switch (byte) {
77 '0' ... '9' => byte - '0',77 '0'...'9' => byte - '0',
78 else => return error.CorruptPasswordFile,78 else => return error.CorruptPasswordFile,
79 };79 };
80 if (@mulWithOverflow(u32, uid, 10, &uid)) return error.CorruptPasswordFile;80 if (@mulWithOverflow(u32, uid, 10, &uid)) return error.CorruptPasswordFile;
...@@ -83,14 +83,14 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo {...@@ -83,14 +83,14 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo {
83 },83 },
84 State.ReadGroupId => switch (byte) {84 State.ReadGroupId => switch (byte) {
85 '\n', ':' => {85 '\n', ':' => {
86 return UserInfo {86 return UserInfo{
87 .uid = uid,87 .uid = uid,
88 .gid = gid,88 .gid = gid,
89 };89 };
90 },90 },
91 else => {91 else => {
92 const digit = switch (byte) {92 const digit = switch (byte) {
93 '0' ... '9' => byte - '0',93 '0'...'9' => byte - '0',
94 else => return error.CorruptPasswordFile,94 else => return error.CorruptPasswordFile,
95 };95 };
96 if (@mulWithOverflow(u32, gid, 10, &gid)) return error.CorruptPasswordFile;96 if (@mulWithOverflow(u32, gid, 10, &gid)) return error.CorruptPasswordFile;
std/os/index.zig+113-155
...@@ -3,8 +3,7 @@ const builtin = @import("builtin");...@@ -3,8 +3,7 @@ const builtin = @import("builtin");
3const Os = builtin.Os;3const Os = builtin.Os;
4const is_windows = builtin.os == Os.windows;4const is_windows = builtin.os == Os.windows;
5const is_posix = switch (builtin.os) {5const is_posix = switch (builtin.os) {
6 builtin.Os.linux,6 builtin.Os.linux, builtin.Os.macosx => true,
7 builtin.Os.macosx => true,
8 else => false,7 else => false,
9};8};
10const os = this;9const os = this;
...@@ -27,8 +26,7 @@ pub const linux = @import("linux/index.zig");...@@ -27,8 +26,7 @@ pub const linux = @import("linux/index.zig");
27pub const zen = @import("zen.zig");26pub const zen = @import("zen.zig");
28pub const posix = switch (builtin.os) {27pub const posix = switch (builtin.os) {
29 Os.linux => linux,28 Os.linux => linux,
30 Os.macosx,29 Os.macosx, Os.ios => darwin,
31 Os.ios => darwin,
32 Os.zen => zen,30 Os.zen => zen,
33 else => @compileError("Unsupported OS"),31 else => @compileError("Unsupported OS"),
34};32};
...@@ -112,8 +110,7 @@ pub fn getRandomBytes(buf: []u8) !void {...@@ -112,8 +110,7 @@ pub fn getRandomBytes(buf: []u8) !void {
112 }110 }
113 return;111 return;
114 },112 },
115 Os.macosx,113 Os.macosx, Os.ios => {
116 Os.ios => {
117 const fd = try posixOpenC(c"/dev/urandom", posix.O_RDONLY | posix.O_CLOEXEC, 0);114 const fd = try posixOpenC(c"/dev/urandom", posix.O_RDONLY | posix.O_CLOEXEC, 0);
118 defer close(fd);115 defer close(fd);
119116
...@@ -137,7 +134,7 @@ pub fn getRandomBytes(buf: []u8) !void {...@@ -137,7 +134,7 @@ pub fn getRandomBytes(buf: []u8) !void {
137 }134 }
138 },135 },
139 Os.zen => {136 Os.zen => {
140 const randomness = []u8 {137 const randomness = []u8{
141 42,138 42,
142 1,139 1,
143 7,140 7,
...@@ -175,9 +172,7 @@ pub fn abort() noreturn {...@@ -175,9 +172,7 @@ pub fn abort() noreturn {
175 c.abort();172 c.abort();
176 }173 }
177 switch (builtin.os) {174 switch (builtin.os) {
178 Os.linux,175 Os.linux, Os.macosx, Os.ios => {
179 Os.macosx,
180 Os.ios => {
181 _ = posix.raise(posix.SIGABRT);176 _ = posix.raise(posix.SIGABRT);
182 _ = posix.raise(posix.SIGKILL);177 _ = posix.raise(posix.SIGKILL);
183 while (true) {}178 while (true) {}
...@@ -199,9 +194,7 @@ pub fn exit(status: u8) noreturn {...@@ -199,9 +194,7 @@ pub fn exit(status: u8) noreturn {
199 c.exit(status);194 c.exit(status);
200 }195 }
201 switch (builtin.os) {196 switch (builtin.os) {
202 Os.linux,197 Os.linux, Os.macosx, Os.ios => {
203 Os.macosx,
204 Os.ios => {
205 posix.exit(status);198 posix.exit(status);
206 },199 },
207 Os.windows => {200 Os.windows => {
...@@ -239,7 +232,7 @@ pub fn close(handle: FileHandle) void {...@@ -239,7 +232,7 @@ pub fn close(handle: FileHandle) void {
239/// Calls POSIX read, and keeps trying if it gets interrupted.232/// Calls POSIX read, and keeps trying if it gets interrupted.
240pub fn posixRead(fd: i32, buf: []u8) !void {233pub fn posixRead(fd: i32, buf: []u8) !void {
241 // Linux can return EINVAL when read amount is > 0x7ffff000234 // Linux can return EINVAL when read amount is > 0x7ffff000
242 // See https://github.com/zig-lang/zig/pull/743#issuecomment-363158274235 // See https://github.com/ziglang/zig/pull/743#issuecomment-363158274
243 const max_buf_len = 0x7ffff000;236 const max_buf_len = 0x7ffff000;
244237
245 var index: usize = 0;238 var index: usize = 0;
...@@ -250,14 +243,12 @@ pub fn posixRead(fd: i32, buf: []u8) !void {...@@ -250,14 +243,12 @@ pub fn posixRead(fd: i32, buf: []u8) !void {
250 if (err > 0) {243 if (err > 0) {
251 return switch (err) {244 return switch (err) {
252 posix.EINTR => continue,245 posix.EINTR => continue,
253 posix.EINVAL,246 posix.EINVAL, posix.EFAULT => unreachable,
254 posix.EFAULT => unreachable,
255 posix.EAGAIN => error.WouldBlock,247 posix.EAGAIN => error.WouldBlock,
256 posix.EBADF => error.FileClosed,248 posix.EBADF => error.FileClosed,
257 posix.EIO => error.InputOutput,249 posix.EIO => error.InputOutput,
258 posix.EISDIR => error.IsDir,250 posix.EISDIR => error.IsDir,
259 posix.ENOBUFS,251 posix.ENOBUFS, posix.ENOMEM => error.SystemResources,
260 posix.ENOMEM => error.SystemResources,
261 else => unexpectedErrorPosix(err),252 else => unexpectedErrorPosix(err),
262 };253 };
263 }254 }
...@@ -265,7 +256,7 @@ pub fn posixRead(fd: i32, buf: []u8) !void {...@@ -265,7 +256,7 @@ pub fn posixRead(fd: i32, buf: []u8) !void {
265 }256 }
266}257}
267258
268pub const PosixWriteError = error {259pub const PosixWriteError = error{
269 WouldBlock,260 WouldBlock,
270 FileClosed,261 FileClosed,
271 DestinationAddressRequired,262 DestinationAddressRequired,
...@@ -281,7 +272,7 @@ pub const PosixWriteError = error {...@@ -281,7 +272,7 @@ pub const PosixWriteError = error {
281/// Calls POSIX write, and keeps trying if it gets interrupted.272/// Calls POSIX write, and keeps trying if it gets interrupted.
282pub fn posixWrite(fd: i32, bytes: []const u8) !void {273pub fn posixWrite(fd: i32, bytes: []const u8) !void {
283 // Linux can return EINVAL when write amount is > 0x7ffff000274 // Linux can return EINVAL when write amount is > 0x7ffff000
284 // See https://github.com/zig-lang/zig/pull/743#issuecomment-363165856275 // See https://github.com/ziglang/zig/pull/743#issuecomment-363165856
285 const max_bytes_len = 0x7ffff000;276 const max_bytes_len = 0x7ffff000;
286277
287 var index: usize = 0;278 var index: usize = 0;
...@@ -292,8 +283,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) !void {...@@ -292,8 +283,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) !void {
292 if (write_err > 0) {283 if (write_err > 0) {
293 return switch (write_err) {284 return switch (write_err) {
294 posix.EINTR => continue,285 posix.EINTR => continue,
295 posix.EINVAL,286 posix.EINVAL, posix.EFAULT => unreachable,
296 posix.EFAULT => unreachable,
297 posix.EAGAIN => PosixWriteError.WouldBlock,287 posix.EAGAIN => PosixWriteError.WouldBlock,
298 posix.EBADF => PosixWriteError.FileClosed,288 posix.EBADF => PosixWriteError.FileClosed,
299 posix.EDESTADDRREQ => PosixWriteError.DestinationAddressRequired,289 posix.EDESTADDRREQ => PosixWriteError.DestinationAddressRequired,
...@@ -310,7 +300,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) !void {...@@ -310,7 +300,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) !void {
310 }300 }
311}301}
312302
313pub const PosixOpenError = error {303pub const PosixOpenError = error{
314 OutOfMemory,304 OutOfMemory,
315 AccessDenied,305 AccessDenied,
316 FileTooBig,306 FileTooBig,
...@@ -349,8 +339,7 @@ pub fn posixOpenC(file_path: &const u8, flags: u32, perm: usize) !i32 {...@@ -349,8 +339,7 @@ pub fn posixOpenC(file_path: &const u8, flags: u32, perm: usize) !i32 {
349 posix.EFAULT => unreachable,339 posix.EFAULT => unreachable,
350 posix.EINVAL => unreachable,340 posix.EINVAL => unreachable,
351 posix.EACCES => return PosixOpenError.AccessDenied,341 posix.EACCES => return PosixOpenError.AccessDenied,
352 posix.EFBIG,342 posix.EFBIG, posix.EOVERFLOW => return PosixOpenError.FileTooBig,
353 posix.EOVERFLOW => return PosixOpenError.FileTooBig,
354 posix.EISDIR => return PosixOpenError.IsDir,343 posix.EISDIR => return PosixOpenError.IsDir,
355 posix.ELOOP => return PosixOpenError.SymLinkLoop,344 posix.ELOOP => return PosixOpenError.SymLinkLoop,
356 posix.EMFILE => return PosixOpenError.ProcessFdQuotaExceeded,345 posix.EMFILE => return PosixOpenError.ProcessFdQuotaExceeded,
...@@ -375,8 +364,7 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) !void {...@@ -375,8 +364,7 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) !void {
375 const err = posix.getErrno(posix.dup2(old_fd, new_fd));364 const err = posix.getErrno(posix.dup2(old_fd, new_fd));
376 if (err > 0) {365 if (err > 0) {
377 return switch (err) {366 return switch (err) {
378 posix.EBUSY,367 posix.EBUSY, posix.EINTR => continue,
379 posix.EINTR => continue,
380 posix.EMFILE => error.ProcessFdQuotaExceeded,368 posix.EMFILE => error.ProcessFdQuotaExceeded,
381 posix.EINVAL => unreachable,369 posix.EINVAL => unreachable,
382 else => unexpectedErrorPosix(err),370 else => unexpectedErrorPosix(err),
...@@ -477,7 +465,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, allocator:...@@ -477,7 +465,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, allocator:
477 return posixExecveErrnoToErr(err);465 return posixExecveErrnoToErr(err);
478}466}
479467
480pub const PosixExecveError = error {468pub const PosixExecveError = error{
481 SystemResources,469 SystemResources,
482 AccessDenied,470 AccessDenied,
483 InvalidExe,471 InvalidExe,
...@@ -493,17 +481,10 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {...@@ -493,17 +481,10 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {
493 assert(err > 0);481 assert(err > 0);
494 return switch (err) {482 return switch (err) {
495 posix.EFAULT => unreachable,483 posix.EFAULT => unreachable,
496 posix.E2BIG,484 posix.E2BIG, posix.EMFILE, posix.ENAMETOOLONG, posix.ENFILE, posix.ENOMEM => error.SystemResources,
497 posix.EMFILE,485 posix.EACCES, posix.EPERM => error.AccessDenied,
498 posix.ENAMETOOLONG,486 posix.EINVAL, posix.ENOEXEC => error.InvalidExe,
499 posix.ENFILE,487 posix.EIO, posix.ELOOP => error.FileSystem,
500 posix.ENOMEM => error.SystemResources,
501 posix.EACCES,
502 posix.EPERM => error.AccessDenied,
503 posix.EINVAL,
504 posix.ENOEXEC => error.InvalidExe,
505 posix.EIO,
506 posix.ELOOP => error.FileSystem,
507 posix.EISDIR => error.IsDir,488 posix.EISDIR => error.IsDir,
508 posix.ENOENT => error.FileNotFound,489 posix.ENOENT => error.FileNotFound,
509 posix.ENOTDIR => error.NotDir,490 posix.ENOTDIR => error.NotDir,
...@@ -512,7 +493,7 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {...@@ -512,7 +493,7 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {
512 };493 };
513}494}
514495
515pub var linux_aux_raw = []usize {0} ** 38;496pub var linux_aux_raw = []usize{0} ** 38;
516pub var posix_environ_raw: []&u8 = undefined;497pub var posix_environ_raw: []&u8 = undefined;
517498
518/// Caller must free result when done.499/// Caller must free result when done.
...@@ -667,7 +648,7 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con...@@ -667,7 +648,7 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con
667 }648 }
668}649}
669650
670pub const WindowsSymLinkError = error {651pub const WindowsSymLinkError = error{
671 OutOfMemory,652 OutOfMemory,
672 Unexpected,653 Unexpected,
673};654};
...@@ -686,7 +667,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path...@@ -686,7 +667,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path
686 }667 }
687}668}
688669
689pub const PosixSymLinkError = error {670pub const PosixSymLinkError = error{
690 OutOfMemory,671 OutOfMemory,
691 AccessDenied,672 AccessDenied,
692 DiskQuota,673 DiskQuota,
...@@ -717,10 +698,8 @@ pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path:...@@ -717,10 +698,8 @@ pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path:
717 const err = posix.getErrno(posix.symlink(existing_buf.ptr, new_buf.ptr));698 const err = posix.getErrno(posix.symlink(existing_buf.ptr, new_buf.ptr));
718 if (err > 0) {699 if (err > 0) {
719 return switch (err) {700 return switch (err) {
720 posix.EFAULT,701 posix.EFAULT, posix.EINVAL => unreachable,
721 posix.EINVAL => unreachable,702 posix.EACCES, posix.EPERM => error.AccessDenied,
722 posix.EACCES,
723 posix.EPERM => error.AccessDenied,
724 posix.EDQUOT => error.DiskQuota,703 posix.EDQUOT => error.DiskQuota,
725 posix.EEXIST => error.PathAlreadyExists,704 posix.EEXIST => error.PathAlreadyExists,
726 posix.EIO => error.FileSystem,705 posix.EIO => error.FileSystem,
...@@ -787,8 +766,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) !void {...@@ -787,8 +766,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) !void {
787 return switch (err) {766 return switch (err) {
788 windows.ERROR.FILE_NOT_FOUND => error.FileNotFound,767 windows.ERROR.FILE_NOT_FOUND => error.FileNotFound,
789 windows.ERROR.ACCESS_DENIED => error.AccessDenied,768 windows.ERROR.ACCESS_DENIED => error.AccessDenied,
790 windows.ERROR.FILENAME_EXCED_RANGE,769 windows.ERROR.FILENAME_EXCED_RANGE, windows.ERROR.INVALID_PARAMETER => error.NameTooLong,
791 windows.ERROR.INVALID_PARAMETER => error.NameTooLong,
792 else => unexpectedErrorWindows(err),770 else => unexpectedErrorWindows(err),
793 };771 };
794 }772 }
...@@ -804,11 +782,9 @@ pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) !void {...@@ -804,11 +782,9 @@ pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) !void {
804 const err = posix.getErrno(posix.unlink(buf.ptr));782 const err = posix.getErrno(posix.unlink(buf.ptr));
805 if (err > 0) {783 if (err > 0) {
806 return switch (err) {784 return switch (err) {
807 posix.EACCES,785 posix.EACCES, posix.EPERM => error.AccessDenied,
808 posix.EPERM => error.AccessDenied,
809 posix.EBUSY => error.FileBusy,786 posix.EBUSY => error.FileBusy,
810 posix.EFAULT,787 posix.EFAULT, posix.EINVAL => unreachable,
811 posix.EINVAL => unreachable,
812 posix.EIO => error.FileSystem,788 posix.EIO => error.FileSystem,
813 posix.EISDIR => error.IsDir,789 posix.EISDIR => error.IsDir,
814 posix.ELOOP => error.SymLinkLoop,790 posix.ELOOP => error.SymLinkLoop,
...@@ -879,14 +855,20 @@ pub const AtomicFile = struct {...@@ -879,14 +855,20 @@ pub const AtomicFile = struct {
879 const dirname = os.path.dirname(dest_path);855 const dirname = os.path.dirname(dest_path);
880856
881 var rand_buf: [12]u8 = undefined;857 var rand_buf: [12]u8 = undefined;
882 const tmp_path = try allocator.alloc(u8, dirname.len + 1 + base64.Base64Encoder.calcSize(rand_buf.len));858
859 const dirname_component_len = if (dirname.len == 0) 0 else dirname.len + 1;
860 const tmp_path = try allocator.alloc(u8, dirname_component_len +
861 base64.Base64Encoder.calcSize(rand_buf.len));
883 errdefer allocator.free(tmp_path);862 errdefer allocator.free(tmp_path);
884 mem.copy(u8, tmp_path[0..], dirname);863
885 tmp_path[dirname.len] = os.path.sep;864 if (dirname.len != 0) {
865 mem.copy(u8, tmp_path[0..], dirname);
866 tmp_path[dirname.len] = os.path.sep;
867 }
886868
887 while (true) {869 while (true) {
888 try getRandomBytes(rand_buf[0..]);870 try getRandomBytes(rand_buf[0..]);
889 b64_fs_encoder.encode(tmp_path[dirname.len + 1..], rand_buf);871 b64_fs_encoder.encode(tmp_path[dirname_component_len..], rand_buf);
890872
891 const file = os.File.openWriteNoClobber(allocator, tmp_path, mode) catch |err| switch (err) {873 const file = os.File.openWriteNoClobber(allocator, tmp_path, mode) catch |err| switch (err) {
892 error.PathAlreadyExists => continue,874 error.PathAlreadyExists => continue,
...@@ -895,7 +877,7 @@ pub const AtomicFile = struct {...@@ -895,7 +877,7 @@ pub const AtomicFile = struct {
895 else => return err,877 else => return err,
896 };878 };
897879
898 return AtomicFile {880 return AtomicFile{
899 .allocator = allocator,881 .allocator = allocator,
900 .file = file,882 .file = file,
901 .tmp_path = tmp_path,883 .tmp_path = tmp_path,
...@@ -948,12 +930,10 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)...@@ -948,12 +930,10 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)
948 const err = posix.getErrno(posix.rename(old_buf.ptr, new_buf.ptr));930 const err = posix.getErrno(posix.rename(old_buf.ptr, new_buf.ptr));
949 if (err > 0) {931 if (err > 0) {
950 return switch (err) {932 return switch (err) {
951 posix.EACCES,933 posix.EACCES, posix.EPERM => error.AccessDenied,
952 posix.EPERM => error.AccessDenied,
953 posix.EBUSY => error.FileBusy,934 posix.EBUSY => error.FileBusy,
954 posix.EDQUOT => error.DiskQuota,935 posix.EDQUOT => error.DiskQuota,
955 posix.EFAULT,936 posix.EFAULT, posix.EINVAL => unreachable,
956 posix.EINVAL => unreachable,
957 posix.EISDIR => error.IsDir,937 posix.EISDIR => error.IsDir,
958 posix.ELOOP => error.SymLinkLoop,938 posix.ELOOP => error.SymLinkLoop,
959 posix.EMLINK => error.LinkQuotaExceeded,939 posix.EMLINK => error.LinkQuotaExceeded,
...@@ -962,8 +942,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)...@@ -962,8 +942,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)
962 posix.ENOTDIR => error.NotDir,942 posix.ENOTDIR => error.NotDir,
963 posix.ENOMEM => error.SystemResources,943 posix.ENOMEM => error.SystemResources,
964 posix.ENOSPC => error.NoSpaceLeft,944 posix.ENOSPC => error.NoSpaceLeft,
965 posix.EEXIST,945 posix.EEXIST, posix.ENOTEMPTY => error.PathAlreadyExists,
966 posix.ENOTEMPTY => error.PathAlreadyExists,
967 posix.EROFS => error.ReadOnlyFileSystem,946 posix.EROFS => error.ReadOnlyFileSystem,
968 posix.EXDEV => error.RenameAcrossMountPoints,947 posix.EXDEV => error.RenameAcrossMountPoints,
969 else => unexpectedErrorPosix(err),948 else => unexpectedErrorPosix(err),
...@@ -1001,8 +980,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) !void {...@@ -1001,8 +980,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) !void {
1001 const err = posix.getErrno(posix.mkdir(path_buf.ptr, 0o755));980 const err = posix.getErrno(posix.mkdir(path_buf.ptr, 0o755));
1002 if (err > 0) {981 if (err > 0) {
1003 return switch (err) {982 return switch (err) {
1004 posix.EACCES,983 posix.EACCES, posix.EPERM => error.AccessDenied,
1005 posix.EPERM => error.AccessDenied,
1006 posix.EDQUOT => error.DiskQuota,984 posix.EDQUOT => error.DiskQuota,
1007 posix.EEXIST => error.PathAlreadyExists,985 posix.EEXIST => error.PathAlreadyExists,
1008 posix.EFAULT => unreachable,986 posix.EFAULT => unreachable,
...@@ -1065,18 +1043,15 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) !void {...@@ -1065,18 +1043,15 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) !void {
1065 const err = posix.getErrno(posix.rmdir(path_buf.ptr));1043 const err = posix.getErrno(posix.rmdir(path_buf.ptr));
1066 if (err > 0) {1044 if (err > 0) {
1067 return switch (err) {1045 return switch (err) {
1068 posix.EACCES,1046 posix.EACCES, posix.EPERM => error.AccessDenied,
1069 posix.EPERM => error.AccessDenied,
1070 posix.EBUSY => error.FileBusy,1047 posix.EBUSY => error.FileBusy,
1071 posix.EFAULT,1048 posix.EFAULT, posix.EINVAL => unreachable,
1072 posix.EINVAL => unreachable,
1073 posix.ELOOP => error.SymLinkLoop,1049 posix.ELOOP => error.SymLinkLoop,
1074 posix.ENAMETOOLONG => error.NameTooLong,1050 posix.ENAMETOOLONG => error.NameTooLong,
1075 posix.ENOENT => error.FileNotFound,1051 posix.ENOENT => error.FileNotFound,
1076 posix.ENOMEM => error.SystemResources,1052 posix.ENOMEM => error.SystemResources,
1077 posix.ENOTDIR => error.NotDir,1053 posix.ENOTDIR => error.NotDir,
1078 posix.EEXIST,1054 posix.EEXIST, posix.ENOTEMPTY => error.DirNotEmpty,
1079 posix.ENOTEMPTY => error.DirNotEmpty,
1080 posix.EROFS => error.ReadOnlyFileSystem,1055 posix.EROFS => error.ReadOnlyFileSystem,
1081 else => unexpectedErrorPosix(err),1056 else => unexpectedErrorPosix(err),
1082 };1057 };
...@@ -1087,7 +1062,7 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) !void {...@@ -1087,7 +1062,7 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) !void {
1087/// removes it. If it cannot be removed because it is a non-empty directory,1062/// removes it. If it cannot be removed because it is a non-empty directory,
1088/// this function recursively removes its entries and then tries again.1063/// this function recursively removes its entries and then tries again.
1089/// TODO non-recursive implementation1064/// TODO non-recursive implementation
1090const DeleteTreeError = error {1065const DeleteTreeError = error{
1091 OutOfMemory,1066 OutOfMemory,
1092 AccessDenied,1067 AccessDenied,
1093 FileTooBig,1068 FileTooBig,
...@@ -1128,7 +1103,8 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) DeleteTreeError!...@@ -1128,7 +1103,8 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) DeleteTreeError!
1128 error.NotDir,1103 error.NotDir,
1129 error.FileSystem,1104 error.FileSystem,
1130 error.FileBusy,1105 error.FileBusy,
1131 error.Unexpected => return err,1106 error.Unexpected,
1107 => return err,
1132 }1108 }
1133 {1109 {
1134 var dir = Dir.open(allocator, full_path) catch |err| switch (err) {1110 var dir = Dir.open(allocator, full_path) catch |err| switch (err) {
...@@ -1152,7 +1128,8 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) DeleteTreeError!...@@ -1152,7 +1128,8 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) DeleteTreeError!
1152 error.SystemResources,1128 error.SystemResources,
1153 error.NoSpaceLeft,1129 error.NoSpaceLeft,
1154 error.PathAlreadyExists,1130 error.PathAlreadyExists,
1155 error.Unexpected => return err,1131 error.Unexpected,
1132 => return err,
1156 };1133 };
1157 defer dir.close();1134 defer dir.close();
11581135
...@@ -1182,8 +1159,7 @@ pub const Dir = struct {...@@ -1182,8 +1159,7 @@ pub const Dir = struct {
1182 end_index: usize,1159 end_index: usize,
11831160
1184 const darwin_seek_t = switch (builtin.os) {1161 const darwin_seek_t = switch (builtin.os) {
1185 Os.macosx,1162 Os.macosx, Os.ios => i64,
1186 Os.ios => i64,
1187 else => void,1163 else => void,
1188 };1164 };
11891165
...@@ -1208,16 +1184,19 @@ pub const Dir = struct {...@@ -1208,16 +1184,19 @@ pub const Dir = struct {
1208 const fd = switch (builtin.os) {1184 const fd = switch (builtin.os) {
1209 Os.windows => @compileError("TODO support Dir.open for windows"),1185 Os.windows => @compileError("TODO support Dir.open for windows"),
1210 Os.linux => try posixOpen(allocator, dir_path, posix.O_RDONLY | posix.O_DIRECTORY | posix.O_CLOEXEC, 0),1186 Os.linux => try posixOpen(allocator, dir_path, posix.O_RDONLY | posix.O_DIRECTORY | posix.O_CLOEXEC, 0),
1211 Os.macosx,1187 Os.macosx, Os.ios => try posixOpen(
1212 Os.ios => try posixOpen(allocator, dir_path, posix.O_RDONLY | posix.O_NONBLOCK | posix.O_DIRECTORY | posix.O_CLOEXEC, 0),1188 allocator,
1189 dir_path,
1190 posix.O_RDONLY | posix.O_NONBLOCK | posix.O_DIRECTORY | posix.O_CLOEXEC,
1191 0,
1192 ),
1213 else => @compileError("Dir.open is not supported for this platform"),1193 else => @compileError("Dir.open is not supported for this platform"),
1214 };1194 };
1215 const darwin_seek_init = switch (builtin.os) {1195 const darwin_seek_init = switch (builtin.os) {
1216 Os.macosx,1196 Os.macosx, Os.ios => 0,
1217 Os.ios => 0,
1218 else => {},1197 else => {},
1219 };1198 };
1220 return Dir {1199 return Dir{
1221 .allocator = allocator,1200 .allocator = allocator,
1222 .fd = fd,1201 .fd = fd,
1223 .darwin_seek = darwin_seek_init,1202 .darwin_seek = darwin_seek_init,
...@@ -1237,8 +1216,7 @@ pub const Dir = struct {...@@ -1237,8 +1216,7 @@ pub const Dir = struct {
1237 pub fn next(self: &Dir) !?Entry {1216 pub fn next(self: &Dir) !?Entry {
1238 switch (builtin.os) {1217 switch (builtin.os) {
1239 Os.linux => return self.nextLinux(),1218 Os.linux => return self.nextLinux(),
1240 Os.macosx,1219 Os.macosx, Os.ios => return self.nextDarwin(),
1241 Os.ios => return self.nextDarwin(),
1242 Os.windows => return self.nextWindows(),1220 Os.windows => return self.nextWindows(),
1243 else => @compileError("Dir.next not supported on " ++ @tagName(builtin.os)),1221 else => @compileError("Dir.next not supported on " ++ @tagName(builtin.os)),
1244 }1222 }
...@@ -1256,9 +1234,7 @@ pub const Dir = struct {...@@ -1256,9 +1234,7 @@ pub const Dir = struct {
1256 const err = posix.getErrno(result);1234 const err = posix.getErrno(result);
1257 if (err > 0) {1235 if (err > 0) {
1258 switch (err) {1236 switch (err) {
1259 posix.EBADF,1237 posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable,
1260 posix.EFAULT,
1261 posix.ENOTDIR => unreachable,
1262 posix.EINVAL => {1238 posix.EINVAL => {
1263 self.buf = try self.allocator.realloc(u8, self.buf, self.buf.len * 2);1239 self.buf = try self.allocator.realloc(u8, self.buf, self.buf.len * 2);
1264 continue;1240 continue;
...@@ -1294,7 +1270,7 @@ pub const Dir = struct {...@@ -1294,7 +1270,7 @@ pub const Dir = struct {
1294 posix.DT_WHT => Entry.Kind.Whiteout,1270 posix.DT_WHT => Entry.Kind.Whiteout,
1295 else => Entry.Kind.Unknown,1271 else => Entry.Kind.Unknown,
1296 };1272 };
1297 return Entry {1273 return Entry{
1298 .name = name,1274 .name = name,
1299 .kind = entry_kind,1275 .kind = entry_kind,
1300 };1276 };
...@@ -1317,9 +1293,7 @@ pub const Dir = struct {...@@ -1317,9 +1293,7 @@ pub const Dir = struct {
1317 const err = posix.getErrno(result);1293 const err = posix.getErrno(result);
1318 if (err > 0) {1294 if (err > 0) {
1319 switch (err) {1295 switch (err) {
1320 posix.EBADF,1296 posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable,
1321 posix.EFAULT,
1322 posix.ENOTDIR => unreachable,
1323 posix.EINVAL => {1297 posix.EINVAL => {
1324 self.buf = try self.allocator.realloc(u8, self.buf, self.buf.len * 2);1298 self.buf = try self.allocator.realloc(u8, self.buf, self.buf.len * 2);
1325 continue;1299 continue;
...@@ -1355,7 +1329,7 @@ pub const Dir = struct {...@@ -1355,7 +1329,7 @@ pub const Dir = struct {
1355 posix.DT_SOCK => Entry.Kind.UnixDomainSocket,1329 posix.DT_SOCK => Entry.Kind.UnixDomainSocket,
1356 else => Entry.Kind.Unknown,1330 else => Entry.Kind.Unknown,
1357 };1331 };
1358 return Entry {1332 return Entry{
1359 .name = name,1333 .name = name,
1360 .kind = entry_kind,1334 .kind = entry_kind,
1361 };1335 };
...@@ -1402,8 +1376,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) ![]u8 {...@@ -1402,8 +1376,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) ![]u8 {
1402 if (err > 0) {1376 if (err > 0) {
1403 return switch (err) {1377 return switch (err) {
1404 posix.EACCES => error.AccessDenied,1378 posix.EACCES => error.AccessDenied,
1405 posix.EFAULT,1379 posix.EFAULT, posix.EINVAL => unreachable,
1406 posix.EINVAL => unreachable,
1407 posix.EIO => error.FileSystem,1380 posix.EIO => error.FileSystem,
1408 posix.ELOOP => error.SymLinkLoop,1381 posix.ELOOP => error.SymLinkLoop,
1409 posix.ENAMETOOLONG => error.NameTooLong,1382 posix.ENAMETOOLONG => error.NameTooLong,
...@@ -1465,7 +1438,7 @@ pub fn posix_setregid(rgid: u32, egid: u32) !void {...@@ -1465,7 +1438,7 @@ pub fn posix_setregid(rgid: u32, egid: u32) !void {
1465 };1438 };
1466}1439}
14671440
1468pub const WindowsGetStdHandleErrs = error {1441pub const WindowsGetStdHandleErrs = error{
1469 NoStdHandles,1442 NoStdHandles,
1470 Unexpected,1443 Unexpected,
1471};1444};
...@@ -1489,7 +1462,7 @@ pub const ArgIteratorPosix = struct {...@@ -1489,7 +1462,7 @@ pub const ArgIteratorPosix = struct {
1489 count: usize,1462 count: usize,
14901463
1491 pub fn init() ArgIteratorPosix {1464 pub fn init() ArgIteratorPosix {
1492 return ArgIteratorPosix {1465 return ArgIteratorPosix{
1493 .index = 0,1466 .index = 0,
1494 .count = raw.len,1467 .count = raw.len,
1495 };1468 };
...@@ -1522,16 +1495,14 @@ pub const ArgIteratorWindows = struct {...@@ -1522,16 +1495,14 @@ pub const ArgIteratorWindows = struct {
1522 quote_count: usize,1495 quote_count: usize,
1523 seen_quote_count: usize,1496 seen_quote_count: usize,
15241497
1525 pub const NextError = error {1498 pub const NextError = error{OutOfMemory};
1526 OutOfMemory,
1527 };
15281499
1529 pub fn init() ArgIteratorWindows {1500 pub fn init() ArgIteratorWindows {
1530 return initWithCmdLine(windows.GetCommandLineA());1501 return initWithCmdLine(windows.GetCommandLineA());
1531 }1502 }
15321503
1533 pub fn initWithCmdLine(cmd_line: &const u8) ArgIteratorWindows {1504 pub fn initWithCmdLine(cmd_line: &const u8) ArgIteratorWindows {
1534 return ArgIteratorWindows {1505 return ArgIteratorWindows{
1535 .index = 0,1506 .index = 0,
1536 .cmd_line = cmd_line,1507 .cmd_line = cmd_line,
1537 .in_quote = false,1508 .in_quote = false,
...@@ -1547,8 +1518,7 @@ pub const ArgIteratorWindows = struct {...@@ -1547,8 +1518,7 @@ pub const ArgIteratorWindows = struct {
1547 const byte = self.cmd_line[self.index];1518 const byte = self.cmd_line[self.index];
1548 switch (byte) {1519 switch (byte) {
1549 0 => return null,1520 0 => return null,
1550 ' ',1521 ' ', '\t' => continue,
1551 '\t' => continue,
1552 else => break,1522 else => break,
1553 }1523 }
1554 }1524 }
...@@ -1562,8 +1532,7 @@ pub const ArgIteratorWindows = struct {...@@ -1562,8 +1532,7 @@ pub const ArgIteratorWindows = struct {
1562 const byte = self.cmd_line[self.index];1532 const byte = self.cmd_line[self.index];
1563 switch (byte) {1533 switch (byte) {
1564 0 => return false,1534 0 => return false,
1565 ' ',1535 ' ', '\t' => continue,
1566 '\t' => continue,
1567 else => break,1536 else => break,
1568 }1537 }
1569 }1538 }
...@@ -1582,8 +1551,7 @@ pub const ArgIteratorWindows = struct {...@@ -1582,8 +1551,7 @@ pub const ArgIteratorWindows = struct {
1582 '\\' => {1551 '\\' => {
1583 backslash_count += 1;1552 backslash_count += 1;
1584 },1553 },
1585 ' ',1554 ' ', '\t' => {
1586 '\t' => {
1587 if (self.seen_quote_count % 2 == 0 or self.seen_quote_count == self.quote_count) {1555 if (self.seen_quote_count % 2 == 0 or self.seen_quote_count == self.quote_count) {
1588 return true;1556 return true;
1589 }1557 }
...@@ -1623,8 +1591,7 @@ pub const ArgIteratorWindows = struct {...@@ -1623,8 +1591,7 @@ pub const ArgIteratorWindows = struct {
1623 '\\' => {1591 '\\' => {
1624 backslash_count += 1;1592 backslash_count += 1;
1625 },1593 },
1626 ' ',1594 ' ', '\t' => {
1627 '\t' => {
1628 try self.emitBackslashes(&buf, backslash_count);1595 try self.emitBackslashes(&buf, backslash_count);
1629 backslash_count = 0;1596 backslash_count = 0;
1630 if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) {1597 if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) {
...@@ -1676,9 +1643,7 @@ pub const ArgIterator = struct {...@@ -1676,9 +1643,7 @@ pub const ArgIterator = struct {
1676 inner: InnerType,1643 inner: InnerType,
16771644
1678 pub fn init() ArgIterator {1645 pub fn init() ArgIterator {
1679 return ArgIterator {1646 return ArgIterator{ .inner = InnerType.init() };
1680 .inner = InnerType.init(),
1681 };
1682 }1647 }
16831648
1684 pub const NextError = ArgIteratorWindows.NextError;1649 pub const NextError = ArgIteratorWindows.NextError;
...@@ -1757,33 +1722,33 @@ pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) void {...@@ -1757,33 +1722,33 @@ pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) void {
1757}1722}
17581723
1759test "windows arg parsing" {1724test "windows arg parsing" {
1760 testWindowsCmdLine(c"a b\tc d", [][]const u8 {1725 testWindowsCmdLine(c"a b\tc d", [][]const u8{
1761 "a",1726 "a",
1762 "b",1727 "b",
1763 "c",1728 "c",
1764 "d",1729 "d",
1765 });1730 });
1766 testWindowsCmdLine(c"\"abc\" d e", [][]const u8 {1731 testWindowsCmdLine(c"\"abc\" d e", [][]const u8{
1767 "abc",1732 "abc",
1768 "d",1733 "d",
1769 "e",1734 "e",
1770 });1735 });
1771 testWindowsCmdLine(c"a\\\\\\b d\"e f\"g h", [][]const u8 {1736 testWindowsCmdLine(c"a\\\\\\b d\"e f\"g h", [][]const u8{
1772 "a\\\\\\b",1737 "a\\\\\\b",
1773 "de fg",1738 "de fg",
1774 "h",1739 "h",
1775 });1740 });
1776 testWindowsCmdLine(c"a\\\\\\\"b c d", [][]const u8 {1741 testWindowsCmdLine(c"a\\\\\\\"b c d", [][]const u8{
1777 "a\\\"b",1742 "a\\\"b",
1778 "c",1743 "c",
1779 "d",1744 "d",
1780 });1745 });
1781 testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [][]const u8 {1746 testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [][]const u8{
1782 "a\\\\b c",1747 "a\\\\b c",
1783 "d",1748 "d",
1784 "e",1749 "e",
1785 });1750 });
1786 testWindowsCmdLine(c"a b\tc \"d f", [][]const u8 {1751 testWindowsCmdLine(c"a b\tc \"d f", [][]const u8{
1787 "a",1752 "a",
1788 "b",1753 "b",
1789 "c",1754 "c",
...@@ -1791,7 +1756,7 @@ test "windows arg parsing" {...@@ -1791,7 +1756,7 @@ test "windows arg parsing" {
1791 "f",1756 "f",
1792 });1757 });
17931758
1794 testWindowsCmdLine(c"\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", [][]const u8 {1759 testWindowsCmdLine(c"\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", [][]const u8{
1795 ".\\..\\zig-cache\\build",1760 ".\\..\\zig-cache\\build",
1796 "bin\\zig.exe",1761 "bin\\zig.exe",
1797 ".\\..",1762 ".\\..",
...@@ -1811,7 +1776,7 @@ fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const...@@ -1811,7 +1776,7 @@ fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const
18111776
1812// TODO make this a build variable that you can set1777// TODO make this a build variable that you can set
1813const unexpected_error_tracing = false;1778const unexpected_error_tracing = false;
1814const UnexpectedError = error {1779const UnexpectedError = error{
1815 /// The Operating System returned an undocumented error code.1780 /// The Operating System returned an undocumented error code.
1816 Unexpected,1781 Unexpected,
1817};1782};
...@@ -1844,8 +1809,7 @@ pub fn openSelfExe() !os.File {...@@ -1844,8 +1809,7 @@ pub fn openSelfExe() !os.File {
1844 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);1809 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1845 return os.File.openRead(&fixed_allocator.allocator, proc_file_path);1810 return os.File.openRead(&fixed_allocator.allocator, proc_file_path);
1846 },1811 },
1847 Os.macosx,1812 Os.macosx, Os.ios => {
1848 Os.ios => {
1849 var fixed_buffer_mem: [darwin.PATH_MAX * 2]u8 = undefined;1813 var fixed_buffer_mem: [darwin.PATH_MAX * 2]u8 = undefined;
1850 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);1814 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1851 const self_exe_path = try selfExePath(&fixed_allocator.allocator);1815 const self_exe_path = try selfExePath(&fixed_allocator.allocator);
...@@ -1857,9 +1821,7 @@ pub fn openSelfExe() !os.File {...@@ -1857,9 +1821,7 @@ pub fn openSelfExe() !os.File {
18571821
1858test "openSelfExe" {1822test "openSelfExe" {
1859 switch (builtin.os) {1823 switch (builtin.os) {
1860 Os.linux,1824 Os.linux, Os.macosx, Os.ios => (try openSelfExe()).close(),
1861 Os.macosx,
1862 Os.ios => (try openSelfExe()).close(),
1863 else => return, // Unsupported OS.1825 else => return, // Unsupported OS.
1864 }1826 }
1865}1827}
...@@ -1897,8 +1859,7 @@ pub fn selfExePath(allocator: &mem.Allocator) ![]u8 {...@@ -1897,8 +1859,7 @@ pub fn selfExePath(allocator: &mem.Allocator) ![]u8 {
1897 try out_path.resize(new_len);1859 try out_path.resize(new_len);
1898 }1860 }
1899 },1861 },
1900 Os.macosx,1862 Os.macosx, Os.ios => {
1901 Os.ios => {
1902 var u32_len: u32 = 0;1863 var u32_len: u32 = 0;
1903 const ret1 = c._NSGetExecutablePath(undefined, &u32_len);1864 const ret1 = c._NSGetExecutablePath(undefined, &u32_len);
1904 assert(ret1 != 0);1865 assert(ret1 != 0);
...@@ -1926,9 +1887,7 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) ![]u8 {...@@ -1926,9 +1887,7 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) ![]u8 {
1926 const dir = path.dirname(full_exe_path);1887 const dir = path.dirname(full_exe_path);
1927 return allocator.shrink(u8, full_exe_path, dir.len);1888 return allocator.shrink(u8, full_exe_path, dir.len);
1928 },1889 },
1929 Os.windows,1890 Os.windows, Os.macosx, Os.ios => {
1930 Os.macosx,
1931 Os.ios => {
1932 const self_exe_path = try selfExePath(allocator);1891 const self_exe_path = try selfExePath(allocator);
1933 errdefer allocator.free(self_exe_path);1892 errdefer allocator.free(self_exe_path);
1934 const dirname = os.path.dirname(self_exe_path);1893 const dirname = os.path.dirname(self_exe_path);
...@@ -1950,7 +1909,7 @@ pub fn isTty(handle: FileHandle) bool {...@@ -1950,7 +1909,7 @@ pub fn isTty(handle: FileHandle) bool {
1950 }1909 }
1951}1910}
19521911
1953pub const PosixSocketError = error {1912pub const PosixSocketError = error{
1954 /// Permission to create a socket of the specified type and/or1913 /// Permission to create a socket of the specified type and/or
1955 /// pro‐tocol is denied.1914 /// pro‐tocol is denied.
1956 PermissionDenied,1915 PermissionDenied,
...@@ -1985,16 +1944,15 @@ pub fn posixSocket(domain: u32, socket_type: u32, protocol: u32) !i32 {...@@ -1985,16 +1944,15 @@ pub fn posixSocket(domain: u32, socket_type: u32, protocol: u32) !i32 {
1985 posix.EINVAL => return PosixSocketError.ProtocolFamilyNotAvailable,1944 posix.EINVAL => return PosixSocketError.ProtocolFamilyNotAvailable,
1986 posix.EMFILE => return PosixSocketError.ProcessFdQuotaExceeded,1945 posix.EMFILE => return PosixSocketError.ProcessFdQuotaExceeded,
1987 posix.ENFILE => return PosixSocketError.SystemFdQuotaExceeded,1946 posix.ENFILE => return PosixSocketError.SystemFdQuotaExceeded,
1988 posix.ENOBUFS,1947 posix.ENOBUFS, posix.ENOMEM => return PosixSocketError.SystemResources,
1989 posix.ENOMEM => return PosixSocketError.SystemResources,
1990 posix.EPROTONOSUPPORT => return PosixSocketError.ProtocolNotSupported,1948 posix.EPROTONOSUPPORT => return PosixSocketError.ProtocolNotSupported,
1991 else => return unexpectedErrorPosix(err),1949 else => return unexpectedErrorPosix(err),
1992 }1950 }
1993}1951}
19941952
1995pub const PosixBindError = error {1953pub const PosixBindError = error{
1996 /// The address is protected, and the user is not the superuser.1954 /// The address is protected, and the user is not the superuser.
1997 /// For UNIX domain sockets: Search permission is denied on a component 1955 /// For UNIX domain sockets: Search permission is denied on a component
1998 /// of the path prefix.1956 /// of the path prefix.
1999 AccessDenied,1957 AccessDenied,
20001958
...@@ -2065,7 +2023,7 @@ pub fn posixBind(fd: i32, addr: &const posix.sockaddr) PosixBindError!void {...@@ -2065,7 +2023,7 @@ pub fn posixBind(fd: i32, addr: &const posix.sockaddr) PosixBindError!void {
2065 }2023 }
2066}2024}
20672025
2068const PosixListenError = error {2026const PosixListenError = error{
2069 /// Another socket is already listening on the same port.2027 /// Another socket is already listening on the same port.
2070 /// For Internet domain sockets, the socket referred to by sockfd had not previously2028 /// For Internet domain sockets, the socket referred to by sockfd had not previously
2071 /// been bound to an address and, upon attempting to bind it to an ephemeral port, it2029 /// been bound to an address and, upon attempting to bind it to an ephemeral port, it
...@@ -2098,7 +2056,7 @@ pub fn posixListen(sockfd: i32, backlog: u32) PosixListenError!void {...@@ -2098,7 +2056,7 @@ pub fn posixListen(sockfd: i32, backlog: u32) PosixListenError!void {
2098 }2056 }
2099}2057}
21002058
2101pub const PosixAcceptError = error {2059pub const PosixAcceptError = error{
2102 /// The socket is marked nonblocking and no connections are present to be accepted.2060 /// The socket is marked nonblocking and no connections are present to be accepted.
2103 WouldBlock,2061 WouldBlock,
21042062
...@@ -2155,8 +2113,7 @@ pub fn posixAccept(fd: i32, addr: &posix.sockaddr, flags: u32) PosixAcceptError!...@@ -2155,8 +2113,7 @@ pub fn posixAccept(fd: i32, addr: &posix.sockaddr, flags: u32) PosixAcceptError!
2155 posix.EINVAL => return PosixAcceptError.InvalidSyscall,2113 posix.EINVAL => return PosixAcceptError.InvalidSyscall,
2156 posix.EMFILE => return PosixAcceptError.ProcessFdQuotaExceeded,2114 posix.EMFILE => return PosixAcceptError.ProcessFdQuotaExceeded,
2157 posix.ENFILE => return PosixAcceptError.SystemFdQuotaExceeded,2115 posix.ENFILE => return PosixAcceptError.SystemFdQuotaExceeded,
2158 posix.ENOBUFS,2116 posix.ENOBUFS, posix.ENOMEM => return PosixAcceptError.SystemResources,
2159 posix.ENOMEM => return PosixAcceptError.SystemResources,
2160 posix.ENOTSOCK => return PosixAcceptError.FileDescriptorNotASocket,2117 posix.ENOTSOCK => return PosixAcceptError.FileDescriptorNotASocket,
2161 posix.EOPNOTSUPP => return PosixAcceptError.OperationNotSupported,2118 posix.EOPNOTSUPP => return PosixAcceptError.OperationNotSupported,
2162 posix.EPROTO => return PosixAcceptError.ProtocolFailure,2119 posix.EPROTO => return PosixAcceptError.ProtocolFailure,
...@@ -2165,7 +2122,7 @@ pub fn posixAccept(fd: i32, addr: &posix.sockaddr, flags: u32) PosixAcceptError!...@@ -2165,7 +2122,7 @@ pub fn posixAccept(fd: i32, addr: &posix.sockaddr, flags: u32) PosixAcceptError!
2165 }2122 }
2166}2123}
21672124
2168pub const LinuxEpollCreateError = error {2125pub const LinuxEpollCreateError = error{
2169 /// Invalid value specified in flags.2126 /// Invalid value specified in flags.
2170 InvalidSyscall,2127 InvalidSyscall,
21712128
...@@ -2198,7 +2155,7 @@ pub fn linuxEpollCreate(flags: u32) LinuxEpollCreateError!i32 {...@@ -2198,7 +2155,7 @@ pub fn linuxEpollCreate(flags: u32) LinuxEpollCreateError!i32 {
2198 }2155 }
2199}2156}
22002157
2201pub const LinuxEpollCtlError = error {2158pub const LinuxEpollCtlError = error{
2202 /// epfd or fd is not a valid file descriptor.2159 /// epfd or fd is not a valid file descriptor.
2203 InvalidFileDescriptor,2160 InvalidFileDescriptor,
22042161
...@@ -2271,7 +2228,7 @@ pub fn linuxEpollWait(epfd: i32, events: []linux.epoll_event, timeout: i32) usiz...@@ -2271,7 +2228,7 @@ pub fn linuxEpollWait(epfd: i32, events: []linux.epoll_event, timeout: i32) usiz
2271 }2228 }
2272}2229}
22732230
2274pub const PosixGetSockNameError = error {2231pub const PosixGetSockNameError = error{
2275 /// Insufficient resources were available in the system to perform the operation.2232 /// Insufficient resources were available in the system to perform the operation.
2276 SystemResources,2233 SystemResources,
22772234
...@@ -2295,7 +2252,7 @@ pub fn posixGetSockName(sockfd: i32) PosixGetSockNameError!posix.sockaddr {...@@ -2295,7 +2252,7 @@ pub fn posixGetSockName(sockfd: i32) PosixGetSockNameError!posix.sockaddr {
2295 }2252 }
2296}2253}
22972254
2298pub const PosixConnectError = error {2255pub const PosixConnectError = error{
2299 /// For UNIX domain sockets, which are identified by pathname: Write permission is denied on the socket2256 /// For UNIX domain sockets, which are identified by pathname: Write permission is denied on the socket
2300 /// file, or search permission is denied for one of the directories in the path prefix.2257 /// file, or search permission is denied for one of the directories in the path prefix.
2301 /// or2258 /// or
...@@ -2367,8 +2324,7 @@ pub fn posixConnectAsync(sockfd: i32, sockaddr: &const posix.sockaddr) PosixConn...@@ -2367,8 +2324,7 @@ pub fn posixConnectAsync(sockfd: i32, sockaddr: &const posix.sockaddr) PosixConn
2367 const rc = posix.connect(sockfd, sockaddr, @sizeOf(posix.sockaddr));2324 const rc = posix.connect(sockfd, sockaddr, @sizeOf(posix.sockaddr));
2368 const err = posix.getErrno(rc);2325 const err = posix.getErrno(rc);
2369 switch (err) {2326 switch (err) {
2370 0,2327 0, posix.EINPROGRESS => return,
2371 posix.EINPROGRESS => return,
2372 else => return unexpectedErrorPosix(err),2328 else => return unexpectedErrorPosix(err),
23732329
2374 posix.EACCES => return PosixConnectError.PermissionDenied,2330 posix.EACCES => return PosixConnectError.PermissionDenied,
...@@ -2420,7 +2376,7 @@ pub fn posixGetSockOptConnectError(sockfd: i32) PosixConnectError!void {...@@ -2420,7 +2376,7 @@ pub fn posixGetSockOptConnectError(sockfd: i32) PosixConnectError!void {
2420 },2376 },
2421 else => return unexpectedErrorPosix(err),2377 else => return unexpectedErrorPosix(err),
2422 posix.EBADF => unreachable, // The argument sockfd is not a valid file descriptor.2378 posix.EBADF => unreachable, // The argument sockfd is not a valid file descriptor.
2423 posix.EFAULT => unreachable, // The address pointed to by optval or optlen is not in a valid part of the process address space. 2379 posix.EFAULT => unreachable, // The address pointed to by optval or optlen is not in a valid part of the process address space.
2424 posix.EINVAL => unreachable,2380 posix.EINVAL => unreachable,
2425 posix.ENOPROTOOPT => unreachable, // The option is unknown at the level indicated.2381 posix.ENOPROTOOPT => unreachable, // The option is unknown at the level indicated.
2426 posix.ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.2382 posix.ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
...@@ -2431,11 +2387,13 @@ pub const Thread = struct {...@@ -2431,11 +2387,13 @@ pub const Thread = struct {
2431 data: Data,2387 data: Data,
24322388
2433 pub const use_pthreads = is_posix and builtin.link_libc;2389 pub const use_pthreads = is_posix and builtin.link_libc;
2434 const Data = if (use_pthreads) struct {2390 const Data = if (use_pthreads)
2435 handle: c.pthread_t,2391 struct {
2436 stack_addr: usize,2392 handle: c.pthread_t,
2437 stack_len: usize,2393 stack_addr: usize,
2438 } else switch (builtin.os) {2394 stack_len: usize,
2395 }
2396 else switch (builtin.os) {
2439 builtin.Os.linux => struct {2397 builtin.Os.linux => struct {
2440 pid: i32,2398 pid: i32,
2441 stack_addr: usize,2399 stack_addr: usize,
...@@ -2485,7 +2443,7 @@ pub const Thread = struct {...@@ -2485,7 +2443,7 @@ pub const Thread = struct {
2485 }2443 }
2486};2444};
24872445
2488pub const SpawnThreadError = error {2446pub const SpawnThreadError = error{
2489 /// A system-imposed limit on the number of threads was encountered.2447 /// A system-imposed limit on the number of threads was encountered.
2490 /// There are a number of limits that may trigger this error:2448 /// There are a number of limits that may trigger this error:
2491 /// * the RLIMIT_NPROC soft resource limit (set via setrlimit(2)),2449 /// * the RLIMIT_NPROC soft resource limit (set via setrlimit(2)),
...@@ -2517,7 +2475,7 @@ pub const SpawnThreadError = error {...@@ -2517,7 +2475,7 @@ pub const SpawnThreadError = error {
2517/// caller must call wait on the returned thread2475/// caller must call wait on the returned thread
2518pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread {2476pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread {
2519 // TODO compile-time call graph analysis to determine stack upper bound2477 // TODO compile-time call graph analysis to determine stack upper bound
2520 // https://github.com/zig-lang/zig/issues/1572478 // https://github.com/ziglang/zig/issues/157
2521 const default_stack_size = 8 * 1024 * 1024;2479 const default_stack_size = 8 * 1024 * 1024;
25222480
2523 const Context = @typeOf(context);2481 const Context = @typeOf(context);
...@@ -2533,7 +2491,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread...@@ -2533,7 +2491,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread
2533 if (@sizeOf(Context) == 0) {2491 if (@sizeOf(Context) == 0) {
2534 return startFn({});2492 return startFn({});
2535 } else {2493 } else {
2536 return startFn(*@ptrCast(&Context, @alignCast(@alignOf(Context), arg)));2494 return startFn(@ptrCast(&Context, @alignCast(@alignOf(Context), arg)).*);
2537 }2495 }
2538 }2496 }
2539 };2497 };
...@@ -2563,7 +2521,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread...@@ -2563,7 +2521,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread
2563 if (@sizeOf(Context) == 0) {2521 if (@sizeOf(Context) == 0) {
2564 return startFn({});2522 return startFn({});
2565 } else {2523 } else {
2566 return startFn(*@intToPtr(&const Context, ctx_addr));2524 return startFn(@intToPtr(&const Context, ctx_addr).*);
2567 }2525 }
2568 }2526 }
2569 extern fn posixThreadMain(ctx: ?&c_void) ?&c_void {2527 extern fn posixThreadMain(ctx: ?&c_void) ?&c_void {
...@@ -2571,7 +2529,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread...@@ -2571,7 +2529,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread
2571 _ = startFn({});2529 _ = startFn({});
2572 return null;2530 return null;
2573 } else {2531 } else {
2574 _ = startFn(*@ptrCast(&const Context, @alignCast(@alignOf(Context), ctx)));2532 _ = startFn(@ptrCast(&const Context, @alignCast(@alignOf(Context), ctx)).*);
2575 return null;2533 return null;
2576 }2534 }
2577 }2535 }
...@@ -2591,7 +2549,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread...@@ -2591,7 +2549,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!&Thread
2591 stack_end -= stack_end % @alignOf(Context);2549 stack_end -= stack_end % @alignOf(Context);
2592 assert(stack_end >= stack_addr);2550 assert(stack_end >= stack_addr);
2593 const context_ptr = @alignCast(@alignOf(Context), @intToPtr(&Context, stack_end));2551 const context_ptr = @alignCast(@alignOf(Context), @intToPtr(&Context, stack_end));
2594 *context_ptr = context;2552 context_ptr.* = context;
2595 arg = stack_end;2553 arg = stack_end;
2596 }2554 }
25972555
std/os/linux/errno.zig+425-144
...@@ -1,146 +1,427 @@...@@ -1,146 +1,427 @@
1pub const EPERM = 1; /// Operation not permitted1/// Operation not permitted
2pub const ENOENT = 2; /// No such file or directory2pub const EPERM = 1;
3pub const ESRCH = 3; /// No such process3
4pub const EINTR = 4; /// Interrupted system call4/// No such file or directory
5pub const EIO = 5; /// I/O error5pub const ENOENT = 2;
6pub const ENXIO = 6; /// No such device or address6
7pub const E2BIG = 7; /// Arg list too long7/// No such process
8pub const ENOEXEC = 8; /// Exec format error8pub const ESRCH = 3;
9pub const EBADF = 9; /// Bad file number9
10pub const ECHILD = 10; /// No child processes10/// Interrupted system call
11pub const EAGAIN = 11; /// Try again11pub const EINTR = 4;
12pub const ENOMEM = 12; /// Out of memory12
13pub const EACCES = 13; /// Permission denied13/// I/O error
14pub const EFAULT = 14; /// Bad address14pub const EIO = 5;
15pub const ENOTBLK = 15; /// Block device required15
16pub const EBUSY = 16; /// Device or resource busy16/// No such device or address
17pub const EEXIST = 17; /// File exists17pub const ENXIO = 6;
18pub const EXDEV = 18; /// Cross-device link18
19pub const ENODEV = 19; /// No such device19/// Arg list too long
20pub const ENOTDIR = 20; /// Not a directory20pub const E2BIG = 7;
21pub const EISDIR = 21; /// Is a directory21
22pub const EINVAL = 22; /// Invalid argument22/// Exec format error
23pub const ENFILE = 23; /// File table overflow23pub const ENOEXEC = 8;
24pub const EMFILE = 24; /// Too many open files24
25pub const ENOTTY = 25; /// Not a typewriter25/// Bad file number
26pub const ETXTBSY = 26; /// Text file busy26pub const EBADF = 9;
27pub const EFBIG = 27; /// File too large27
28pub const ENOSPC = 28; /// No space left on device28/// No child processes
29pub const ESPIPE = 29; /// Illegal seek29pub const ECHILD = 10;
30pub const EROFS = 30; /// Read-only file system30
31pub const EMLINK = 31; /// Too many links31/// Try again
32pub const EPIPE = 32; /// Broken pipe32pub const EAGAIN = 11;
33pub const EDOM = 33; /// Math argument out of domain of func33
34pub const ERANGE = 34; /// Math result not representable34/// Out of memory
35pub const EDEADLK = 35; /// Resource deadlock would occur35pub const ENOMEM = 12;
36pub const ENAMETOOLONG = 36; /// File name too long36
37pub const ENOLCK = 37; /// No record locks available37/// Permission denied
38pub const ENOSYS = 38; /// Function not implemented38pub const EACCES = 13;
39pub const ENOTEMPTY = 39; /// Directory not empty39
40pub const ELOOP = 40; /// Too many symbolic links encountered40/// Bad address
41pub const EWOULDBLOCK = EAGAIN; /// Operation would block41pub const EFAULT = 14;
42pub const ENOMSG = 42; /// No message of desired type42
43pub const EIDRM = 43; /// Identifier removed43/// Block device required
44pub const ECHRNG = 44; /// Channel number out of range44pub const ENOTBLK = 15;
45pub const EL2NSYNC = 45; /// Level 2 not synchronized45
46pub const EL3HLT = 46; /// Level 3 halted46/// Device or resource busy
47pub const EL3RST = 47; /// Level 3 reset47pub const EBUSY = 16;
48pub const ELNRNG = 48; /// Link number out of range48
49pub const EUNATCH = 49; /// Protocol driver not attached49/// File exists
50pub const ENOCSI = 50; /// No CSI structure available50pub const EEXIST = 17;
51pub const EL2HLT = 51; /// Level 2 halted51
52pub const EBADE = 52; /// Invalid exchange52/// Cross-device link
53pub const EBADR = 53; /// Invalid request descriptor53pub const EXDEV = 18;
54pub const EXFULL = 54; /// Exchange full54
55pub const ENOANO = 55; /// No anode55/// No such device
56pub const EBADRQC = 56; /// Invalid request code56pub const ENODEV = 19;
57pub const EBADSLT = 57; /// Invalid slot57
5858/// Not a directory
59pub const EBFONT = 59; /// Bad font file format59pub const ENOTDIR = 20;
60pub const ENOSTR = 60; /// Device not a stream60
61pub const ENODATA = 61; /// No data available61/// Is a directory
62pub const ETIME = 62; /// Timer expired62pub const EISDIR = 21;
63pub const ENOSR = 63; /// Out of streams resources63
64pub const ENONET = 64; /// Machine is not on the network64/// Invalid argument
65pub const ENOPKG = 65; /// Package not installed65pub const EINVAL = 22;
66pub const EREMOTE = 66; /// Object is remote66
67pub const ENOLINK = 67; /// Link has been severed67/// File table overflow
68pub const EADV = 68; /// Advertise error68pub const ENFILE = 23;
69pub const ESRMNT = 69; /// Srmount error69
70pub const ECOMM = 70; /// Communication error on send70/// Too many open files
71pub const EPROTO = 71; /// Protocol error71pub const EMFILE = 24;
72pub const EMULTIHOP = 72; /// Multihop attempted72
73pub const EDOTDOT = 73; /// RFS specific error73/// Not a typewriter
74pub const EBADMSG = 74; /// Not a data message74pub const ENOTTY = 25;
75pub const EOVERFLOW = 75; /// Value too large for defined data type75
76pub const ENOTUNIQ = 76; /// Name not unique on network76/// Text file busy
77pub const EBADFD = 77; /// File descriptor in bad state77pub const ETXTBSY = 26;
78pub const EREMCHG = 78; /// Remote address changed78
79pub const ELIBACC = 79; /// Can not access a needed shared library79/// File too large
80pub const ELIBBAD = 80; /// Accessing a corrupted shared library80pub const EFBIG = 27;
81pub const ELIBSCN = 81; /// .lib section in a.out corrupted81
82pub const ELIBMAX = 82; /// Attempting to link in too many shared libraries82/// No space left on device
83pub const ELIBEXEC = 83; /// Cannot exec a shared library directly83pub const ENOSPC = 28;
84pub const EILSEQ = 84; /// Illegal byte sequence84
85pub const ERESTART = 85; /// Interrupted system call should be restarted85/// Illegal seek
86pub const ESTRPIPE = 86; /// Streams pipe error86pub const ESPIPE = 29;
87pub const EUSERS = 87; /// Too many users87
88pub const ENOTSOCK = 88; /// Socket operation on non-socket88/// Read-only file system
89pub const EDESTADDRREQ = 89; /// Destination address required89pub const EROFS = 30;
90pub const EMSGSIZE = 90; /// Message too long90
91pub const EPROTOTYPE = 91; /// Protocol wrong type for socket91/// Too many links
92pub const ENOPROTOOPT = 92; /// Protocol not available92pub const EMLINK = 31;
93pub const EPROTONOSUPPORT = 93; /// Protocol not supported93
94pub const ESOCKTNOSUPPORT = 94; /// Socket type not supported94/// Broken pipe
95pub const EOPNOTSUPP = 95; /// Operation not supported on transport endpoint95pub const EPIPE = 32;
96pub const EPFNOSUPPORT = 96; /// Protocol family not supported96
97pub const EAFNOSUPPORT = 97; /// Address family not supported by protocol97/// Math argument out of domain of func
98pub const EADDRINUSE = 98; /// Address already in use98pub const EDOM = 33;
99pub const EADDRNOTAVAIL = 99; /// Cannot assign requested address99
100pub const ENETDOWN = 100; /// Network is down100/// Math result not representable
101pub const ENETUNREACH = 101; /// Network is unreachable101pub const ERANGE = 34;
102pub const ENETRESET = 102; /// Network dropped connection because of reset102
103pub const ECONNABORTED = 103; /// Software caused connection abort103/// Resource deadlock would occur
104pub const ECONNRESET = 104; /// Connection reset by peer104pub const EDEADLK = 35;
105pub const ENOBUFS = 105; /// No buffer space available105
106pub const EISCONN = 106; /// Transport endpoint is already connected106/// File name too long
107pub const ENOTCONN = 107; /// Transport endpoint is not connected107pub const ENAMETOOLONG = 36;
108pub const ESHUTDOWN = 108; /// Cannot send after transport endpoint shutdown108
109pub const ETOOMANYREFS = 109; /// Too many references: cannot splice109/// No record locks available
110pub const ETIMEDOUT = 110; /// Connection timed out110pub const ENOLCK = 37;
111pub const ECONNREFUSED = 111; /// Connection refused111
112pub const EHOSTDOWN = 112; /// Host is down112/// Function not implemented
113pub const EHOSTUNREACH = 113; /// No route to host113pub const ENOSYS = 38;
114pub const EALREADY = 114; /// Operation already in progress114
115pub const EINPROGRESS = 115; /// Operation now in progress115/// Directory not empty
116pub const ESTALE = 116; /// Stale NFS file handle116pub const ENOTEMPTY = 39;
117pub const EUCLEAN = 117; /// Structure needs cleaning117
118pub const ENOTNAM = 118; /// Not a XENIX named type file118/// Too many symbolic links encountered
119pub const ENAVAIL = 119; /// No XENIX semaphores available119pub const ELOOP = 40;
120pub const EISNAM = 120; /// Is a named type file120
121pub const EREMOTEIO = 121; /// Remote I/O error121/// Operation would block
122pub const EDQUOT = 122; /// Quota exceeded122pub const EWOULDBLOCK = EAGAIN;
123123
124pub const ENOMEDIUM = 123; /// No medium found124/// No message of desired type
125pub const EMEDIUMTYPE = 124; /// Wrong medium type125pub const ENOMSG = 42;
126
127/// Identifier removed
128pub const EIDRM = 43;
129
130/// Channel number out of range
131pub const ECHRNG = 44;
132
133/// Level 2 not synchronized
134pub const EL2NSYNC = 45;
135
136/// Level 3 halted
137pub const EL3HLT = 46;
138
139/// Level 3 reset
140pub const EL3RST = 47;
141
142/// Link number out of range
143pub const ELNRNG = 48;
144
145/// Protocol driver not attached
146pub const EUNATCH = 49;
147
148/// No CSI structure available
149pub const ENOCSI = 50;
150
151/// Level 2 halted
152pub const EL2HLT = 51;
153
154/// Invalid exchange
155pub const EBADE = 52;
156
157/// Invalid request descriptor
158pub const EBADR = 53;
159
160/// Exchange full
161pub const EXFULL = 54;
162
163/// No anode
164pub const ENOANO = 55;
165
166/// Invalid request code
167pub const EBADRQC = 56;
168
169/// Invalid slot
170pub const EBADSLT = 57;
171
172/// Bad font file format
173pub const EBFONT = 59;
174
175/// Device not a stream
176pub const ENOSTR = 60;
177
178/// No data available
179pub const ENODATA = 61;
180
181/// Timer expired
182pub const ETIME = 62;
183
184/// Out of streams resources
185pub const ENOSR = 63;
186
187/// Machine is not on the network
188pub const ENONET = 64;
189
190/// Package not installed
191pub const ENOPKG = 65;
192
193/// Object is remote
194pub const EREMOTE = 66;
195
196/// Link has been severed
197pub const ENOLINK = 67;
198
199/// Advertise error
200pub const EADV = 68;
201
202/// Srmount error
203pub const ESRMNT = 69;
204
205/// Communication error on send
206pub const ECOMM = 70;
207
208/// Protocol error
209pub const EPROTO = 71;
210
211/// Multihop attempted
212pub const EMULTIHOP = 72;
213
214/// RFS specific error
215pub const EDOTDOT = 73;
216
217/// Not a data message
218pub const EBADMSG = 74;
219
220/// Value too large for defined data type
221pub const EOVERFLOW = 75;
222
223/// Name not unique on network
224pub const ENOTUNIQ = 76;
225
226/// File descriptor in bad state
227pub const EBADFD = 77;
228
229/// Remote address changed
230pub const EREMCHG = 78;
231
232/// Can not access a needed shared library
233pub const ELIBACC = 79;
234
235/// Accessing a corrupted shared library
236pub const ELIBBAD = 80;
237
238/// .lib section in a.out corrupted
239pub const ELIBSCN = 81;
240
241/// Attempting to link in too many shared libraries
242pub const ELIBMAX = 82;
243
244/// Cannot exec a shared library directly
245pub const ELIBEXEC = 83;
246
247/// Illegal byte sequence
248pub const EILSEQ = 84;
249
250/// Interrupted system call should be restarted
251pub const ERESTART = 85;
252
253/// Streams pipe error
254pub const ESTRPIPE = 86;
255
256/// Too many users
257pub const EUSERS = 87;
258
259/// Socket operation on non-socket
260pub const ENOTSOCK = 88;
261
262/// Destination address required
263pub const EDESTADDRREQ = 89;
264
265/// Message too long
266pub const EMSGSIZE = 90;
267
268/// Protocol wrong type for socket
269pub const EPROTOTYPE = 91;
270
271/// Protocol not available
272pub const ENOPROTOOPT = 92;
273
274/// Protocol not supported
275pub const EPROTONOSUPPORT = 93;
276
277/// Socket type not supported
278pub const ESOCKTNOSUPPORT = 94;
279
280/// Operation not supported on transport endpoint
281pub const EOPNOTSUPP = 95;
282
283/// Protocol family not supported
284pub const EPFNOSUPPORT = 96;
285
286/// Address family not supported by protocol
287pub const EAFNOSUPPORT = 97;
288
289/// Address already in use
290pub const EADDRINUSE = 98;
291
292/// Cannot assign requested address
293pub const EADDRNOTAVAIL = 99;
294
295/// Network is down
296pub const ENETDOWN = 100;
297
298/// Network is unreachable
299pub const ENETUNREACH = 101;
300
301/// Network dropped connection because of reset
302pub const ENETRESET = 102;
303
304/// Software caused connection abort
305pub const ECONNABORTED = 103;
306
307/// Connection reset by peer
308pub const ECONNRESET = 104;
309
310/// No buffer space available
311pub const ENOBUFS = 105;
312
313/// Transport endpoint is already connected
314pub const EISCONN = 106;
315
316/// Transport endpoint is not connected
317pub const ENOTCONN = 107;
318
319/// Cannot send after transport endpoint shutdown
320pub const ESHUTDOWN = 108;
321
322/// Too many references: cannot splice
323pub const ETOOMANYREFS = 109;
324
325/// Connection timed out
326pub const ETIMEDOUT = 110;
327
328/// Connection refused
329pub const ECONNREFUSED = 111;
330
331/// Host is down
332pub const EHOSTDOWN = 112;
333
334/// No route to host
335pub const EHOSTUNREACH = 113;
336
337/// Operation already in progress
338pub const EALREADY = 114;
339
340/// Operation now in progress
341pub const EINPROGRESS = 115;
342
343/// Stale NFS file handle
344pub const ESTALE = 116;
345
346/// Structure needs cleaning
347pub const EUCLEAN = 117;
348
349/// Not a XENIX named type file
350pub const ENOTNAM = 118;
351
352/// No XENIX semaphores available
353pub const ENAVAIL = 119;
354
355/// Is a named type file
356pub const EISNAM = 120;
357
358/// Remote I/O error
359pub const EREMOTEIO = 121;
360
361/// Quota exceeded
362pub const EDQUOT = 122;
363
364/// No medium found
365pub const ENOMEDIUM = 123;
366
367/// Wrong medium type
368pub const EMEDIUMTYPE = 124;
126369
127// nameserver query return codes370// nameserver query return codes
128pub const ENSROK = 0; /// DNS server returned answer with no data371
129pub const ENSRNODATA = 160; /// DNS server returned answer with no data372/// DNS server returned answer with no data
130pub const ENSRFORMERR = 161; /// DNS server claims query was misformatted373pub const ENSROK = 0;
131pub const ENSRSERVFAIL = 162; /// DNS server returned general failure374
132pub const ENSRNOTFOUND = 163; /// Domain name not found375/// DNS server returned answer with no data
133pub const ENSRNOTIMP = 164; /// DNS server does not implement requested operation376pub const ENSRNODATA = 160;
134pub const ENSRREFUSED = 165; /// DNS server refused query377
135pub const ENSRBADQUERY = 166; /// Misformatted DNS query378/// DNS server claims query was misformatted
136pub const ENSRBADNAME = 167; /// Misformatted domain name379pub const ENSRFORMERR = 161;
137pub const ENSRBADFAMILY = 168; /// Unsupported address family380
138pub const ENSRBADRESP = 169; /// Misformatted DNS reply381/// DNS server returned general failure
139pub const ENSRCONNREFUSED = 170; /// Could not contact DNS servers382pub const ENSRSERVFAIL = 162;
140pub const ENSRTIMEOUT = 171; /// Timeout while contacting DNS servers383
141pub const ENSROF = 172; /// End of file384/// Domain name not found
142pub const ENSRFILE = 173; /// Error reading file385pub const ENSRNOTFOUND = 163;
143pub const ENSRNOMEM = 174; /// Out of memory386
144pub const ENSRDESTRUCTION = 175; /// Application terminated lookup387/// DNS server does not implement requested operation
145pub const ENSRQUERYDOMAINTOOLONG = 176; /// Domain name is too long388pub const ENSRNOTIMP = 164;
146pub const ENSRCNAMELOOP = 177; /// Domain name is too long389
390/// DNS server refused query
391pub const ENSRREFUSED = 165;
392
393/// Misformatted DNS query
394pub const ENSRBADQUERY = 166;
395
396/// Misformatted domain name
397pub const ENSRBADNAME = 167;
398
399/// Unsupported address family
400pub const ENSRBADFAMILY = 168;
401
402/// Misformatted DNS reply
403pub const ENSRBADRESP = 169;
404
405/// Could not contact DNS servers
406pub const ENSRCONNREFUSED = 170;
407
408/// Timeout while contacting DNS servers
409pub const ENSRTIMEOUT = 171;
410
411/// End of file
412pub const ENSROF = 172;
413
414/// Error reading file
415pub const ENSRFILE = 173;
416
417/// Out of memory
418pub const ENSRNOMEM = 174;
419
420/// Application terminated lookup
421pub const ENSRDESTRUCTION = 175;
422
423/// Domain name is too long
424pub const ENSRQUERYDOMAINTOOLONG = 176;
425
426/// Domain name is too long
427pub const ENSRCNAMELOOP = 177;
std/os/linux/index.zig+187-189
...@@ -30,96 +30,95 @@ pub const FUTEX_PRIVATE_FLAG = 128;...@@ -30,96 +30,95 @@ pub const FUTEX_PRIVATE_FLAG = 128;
3030
31pub const FUTEX_CLOCK_REALTIME = 256;31pub const FUTEX_CLOCK_REALTIME = 256;
3232
3333pub const PROT_NONE = 0;
34pub const PROT_NONE = 0;34pub const PROT_READ = 1;
35pub const PROT_READ = 1;35pub const PROT_WRITE = 2;
36pub const PROT_WRITE = 2;36pub const PROT_EXEC = 4;
37pub const PROT_EXEC = 4;
38pub const PROT_GROWSDOWN = 0x01000000;37pub const PROT_GROWSDOWN = 0x01000000;
39pub const PROT_GROWSUP = 0x02000000;38pub const PROT_GROWSUP = 0x02000000;
4039
41pub const MAP_FAILED = @maxValue(usize);40pub const MAP_FAILED = @maxValue(usize);
42pub const MAP_SHARED = 0x01;41pub const MAP_SHARED = 0x01;
43pub const MAP_PRIVATE = 0x02;42pub const MAP_PRIVATE = 0x02;
44pub const MAP_TYPE = 0x0f;43pub const MAP_TYPE = 0x0f;
45pub const MAP_FIXED = 0x10;44pub const MAP_FIXED = 0x10;
46pub const MAP_ANONYMOUS = 0x20;45pub const MAP_ANONYMOUS = 0x20;
47pub const MAP_NORESERVE = 0x4000;46pub const MAP_NORESERVE = 0x4000;
48pub const MAP_GROWSDOWN = 0x0100;47pub const MAP_GROWSDOWN = 0x0100;
49pub const MAP_DENYWRITE = 0x0800;48pub const MAP_DENYWRITE = 0x0800;
50pub const MAP_EXECUTABLE = 0x1000;49pub const MAP_EXECUTABLE = 0x1000;
51pub const MAP_LOCKED = 0x2000;50pub const MAP_LOCKED = 0x2000;
52pub const MAP_POPULATE = 0x8000;51pub const MAP_POPULATE = 0x8000;
53pub const MAP_NONBLOCK = 0x10000;52pub const MAP_NONBLOCK = 0x10000;
54pub const MAP_STACK = 0x20000;53pub const MAP_STACK = 0x20000;
55pub const MAP_HUGETLB = 0x40000;54pub const MAP_HUGETLB = 0x40000;
56pub const MAP_FILE = 0;55pub const MAP_FILE = 0;
5756
58pub const F_OK = 0;57pub const F_OK = 0;
59pub const X_OK = 1;58pub const X_OK = 1;
60pub const W_OK = 2;59pub const W_OK = 2;
61pub const R_OK = 4;60pub const R_OK = 4;
6261
63pub const WNOHANG = 1;62pub const WNOHANG = 1;
64pub const WUNTRACED = 2;63pub const WUNTRACED = 2;
65pub const WSTOPPED = 2;64pub const WSTOPPED = 2;
66pub const WEXITED = 4;65pub const WEXITED = 4;
67pub const WCONTINUED = 8;66pub const WCONTINUED = 8;
68pub const WNOWAIT = 0x1000000;67pub const WNOWAIT = 0x1000000;
6968
70pub const SA_NOCLDSTOP = 1;69pub const SA_NOCLDSTOP = 1;
71pub const SA_NOCLDWAIT = 2;70pub const SA_NOCLDWAIT = 2;
72pub const SA_SIGINFO = 4;71pub const SA_SIGINFO = 4;
73pub const SA_ONSTACK = 0x08000000;72pub const SA_ONSTACK = 0x08000000;
74pub const SA_RESTART = 0x10000000;73pub const SA_RESTART = 0x10000000;
75pub const SA_NODEFER = 0x40000000;74pub const SA_NODEFER = 0x40000000;
76pub const SA_RESETHAND = 0x80000000;75pub const SA_RESETHAND = 0x80000000;
77pub const SA_RESTORER = 0x04000000;76pub const SA_RESTORER = 0x04000000;
7877
79pub const SIGHUP = 1;78pub const SIGHUP = 1;
80pub const SIGINT = 2;79pub const SIGINT = 2;
81pub const SIGQUIT = 3;80pub const SIGQUIT = 3;
82pub const SIGILL = 4;81pub const SIGILL = 4;
83pub const SIGTRAP = 5;82pub const SIGTRAP = 5;
84pub const SIGABRT = 6;83pub const SIGABRT = 6;
85pub const SIGIOT = SIGABRT;84pub const SIGIOT = SIGABRT;
86pub const SIGBUS = 7;85pub const SIGBUS = 7;
87pub const SIGFPE = 8;86pub const SIGFPE = 8;
88pub const SIGKILL = 9;87pub const SIGKILL = 9;
89pub const SIGUSR1 = 10;88pub const SIGUSR1 = 10;
90pub const SIGSEGV = 11;89pub const SIGSEGV = 11;
91pub const SIGUSR2 = 12;90pub const SIGUSR2 = 12;
92pub const SIGPIPE = 13;91pub const SIGPIPE = 13;
93pub const SIGALRM = 14;92pub const SIGALRM = 14;
94pub const SIGTERM = 15;93pub const SIGTERM = 15;
95pub const SIGSTKFLT = 16;94pub const SIGSTKFLT = 16;
96pub const SIGCHLD = 17;95pub const SIGCHLD = 17;
97pub const SIGCONT = 18;96pub const SIGCONT = 18;
98pub const SIGSTOP = 19;97pub const SIGSTOP = 19;
99pub const SIGTSTP = 20;98pub const SIGTSTP = 20;
100pub const SIGTTIN = 21;99pub const SIGTTIN = 21;
101pub const SIGTTOU = 22;100pub const SIGTTOU = 22;
102pub const SIGURG = 23;101pub const SIGURG = 23;
103pub const SIGXCPU = 24;102pub const SIGXCPU = 24;
104pub const SIGXFSZ = 25;103pub const SIGXFSZ = 25;
105pub const SIGVTALRM = 26;104pub const SIGVTALRM = 26;
106pub const SIGPROF = 27;105pub const SIGPROF = 27;
107pub const SIGWINCH = 28;106pub const SIGWINCH = 28;
108pub const SIGIO = 29;107pub const SIGIO = 29;
109pub const SIGPOLL = 29;108pub const SIGPOLL = 29;
110pub const SIGPWR = 30;109pub const SIGPWR = 30;
111pub const SIGSYS = 31;110pub const SIGSYS = 31;
112pub const SIGUNUSED = SIGSYS;111pub const SIGUNUSED = SIGSYS;
113112
114pub const O_RDONLY = 0o0;113pub const O_RDONLY = 0o0;
115pub const O_WRONLY = 0o1;114pub const O_WRONLY = 0o1;
116pub const O_RDWR = 0o2;115pub const O_RDWR = 0o2;
117116
118pub const SEEK_SET = 0;117pub const SEEK_SET = 0;
119pub const SEEK_CUR = 1;118pub const SEEK_CUR = 1;
120pub const SEEK_END = 2;119pub const SEEK_END = 2;
121120
122pub const SIG_BLOCK = 0;121pub const SIG_BLOCK = 0;
123pub const SIG_UNBLOCK = 1;122pub const SIG_UNBLOCK = 1;
124pub const SIG_SETMASK = 2;123pub const SIG_SETMASK = 2;
125124
...@@ -408,7 +407,6 @@ pub const DT_LNK = 10;...@@ -408,7 +407,6 @@ pub const DT_LNK = 10;
408pub const DT_SOCK = 12;407pub const DT_SOCK = 12;
409pub const DT_WHT = 14;408pub const DT_WHT = 14;
410409
411
412pub const TCGETS = 0x5401;410pub const TCGETS = 0x5401;
413pub const TCSETS = 0x5402;411pub const TCSETS = 0x5402;
414pub const TCSETSW = 0x5403;412pub const TCSETSW = 0x5403;
...@@ -539,23 +537,23 @@ pub const MS_BIND = 4096;...@@ -539,23 +537,23 @@ pub const MS_BIND = 4096;
539pub const MS_MOVE = 8192;537pub const MS_MOVE = 8192;
540pub const MS_REC = 16384;538pub const MS_REC = 16384;
541pub const MS_SILENT = 32768;539pub const MS_SILENT = 32768;
542pub const MS_POSIXACL = (1<<16);540pub const MS_POSIXACL = (1 << 16);
543pub const MS_UNBINDABLE = (1<<17);541pub const MS_UNBINDABLE = (1 << 17);
544pub const MS_PRIVATE = (1<<18);542pub const MS_PRIVATE = (1 << 18);
545pub const MS_SLAVE = (1<<19);543pub const MS_SLAVE = (1 << 19);
546pub const MS_SHARED = (1<<20);544pub const MS_SHARED = (1 << 20);
547pub const MS_RELATIME = (1<<21);545pub const MS_RELATIME = (1 << 21);
548pub const MS_KERNMOUNT = (1<<22);546pub const MS_KERNMOUNT = (1 << 22);
549pub const MS_I_VERSION = (1<<23);547pub const MS_I_VERSION = (1 << 23);
550pub const MS_STRICTATIME = (1<<24);548pub const MS_STRICTATIME = (1 << 24);
551pub const MS_LAZYTIME = (1<<25);549pub const MS_LAZYTIME = (1 << 25);
552pub const MS_NOREMOTELOCK = (1<<27);550pub const MS_NOREMOTELOCK = (1 << 27);
553pub const MS_NOSEC = (1<<28);551pub const MS_NOSEC = (1 << 28);
554pub const MS_BORN = (1<<29);552pub const MS_BORN = (1 << 29);
555pub const MS_ACTIVE = (1<<30);553pub const MS_ACTIVE = (1 << 30);
556pub const MS_NOUSER = (1<<31);554pub const MS_NOUSER = (1 << 31);
557555
558pub const MS_RMT_MASK = (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|MS_LAZYTIME);556pub const MS_RMT_MASK = (MS_RDONLY | MS_SYNCHRONOUS | MS_MANDLOCK | MS_I_VERSION | MS_LAZYTIME);
559557
560pub const MS_MGC_VAL = 0xc0ed0000;558pub const MS_MGC_VAL = 0xc0ed0000;
561pub const MS_MGC_MSK = 0xffff0000;559pub const MS_MGC_MSK = 0xffff0000;
...@@ -565,7 +563,6 @@ pub const MNT_DETACH = 2;...@@ -565,7 +563,6 @@ pub const MNT_DETACH = 2;
565pub const MNT_EXPIRE = 4;563pub const MNT_EXPIRE = 4;
566pub const UMOUNT_NOFOLLOW = 8;564pub const UMOUNT_NOFOLLOW = 8;
567565
568
569pub const S_IFMT = 0o170000;566pub const S_IFMT = 0o170000;
570567
571pub const S_IFDIR = 0o040000;568pub const S_IFDIR = 0o040000;
...@@ -626,15 +623,30 @@ pub const TFD_CLOEXEC = O_CLOEXEC;...@@ -626,15 +623,30 @@ pub const TFD_CLOEXEC = O_CLOEXEC;
626pub const TFD_TIMER_ABSTIME = 1;623pub const TFD_TIMER_ABSTIME = 1;
627pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);624pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);
628625
629fn unsigned(s: i32) u32 { return @bitCast(u32, s); }626fn unsigned(s: i32) u32 {
630fn signed(s: u32) i32 { return @bitCast(i32, s); }627 return @bitCast(u32, s);
631pub fn WEXITSTATUS(s: i32) i32 { return signed((unsigned(s) & 0xff00) >> 8); }628}
632pub fn WTERMSIG(s: i32) i32 { return signed(unsigned(s) & 0x7f); }629fn signed(s: u32) i32 {
633pub fn WSTOPSIG(s: i32) i32 { return WEXITSTATUS(s); }630 return @bitCast(i32, s);
634pub fn WIFEXITED(s: i32) bool { return WTERMSIG(s) == 0; }631}
635pub fn WIFSTOPPED(s: i32) bool { return (u16)(((unsigned(s)&0xffff)*%0x10001)>>8) > 0x7f00; }632pub fn WEXITSTATUS(s: i32) i32 {
636pub fn WIFSIGNALED(s: i32) bool { return (unsigned(s)&0xffff)-%1 < 0xff; }633 return signed((unsigned(s) & 0xff00) >> 8);
637634}
635pub fn WTERMSIG(s: i32) i32 {
636 return signed(unsigned(s) & 0x7f);
637}
638pub fn WSTOPSIG(s: i32) i32 {
639 return WEXITSTATUS(s);
640}
641pub fn WIFEXITED(s: i32) bool {
642 return WTERMSIG(s) == 0;
643}
644pub fn WIFSTOPPED(s: i32) bool {
645 return (u16)(((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00;
646}
647pub fn WIFSIGNALED(s: i32) bool {
648 return (unsigned(s) & 0xffff) -% 1 < 0xff;
649}
638650
639pub const winsize = extern struct {651pub const winsize = extern struct {
640 ws_row: u16,652 ws_row: u16,
...@@ -707,8 +719,7 @@ pub fn umount2(special: &const u8, flags: u32) usize {...@@ -707,8 +719,7 @@ pub fn umount2(special: &const u8, flags: u32) usize {
707}719}
708720
709pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {721pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {
710 return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd),722 return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd), @bitCast(usize, offset));
711 @bitCast(usize, offset));
712}723}
713724
714pub fn munmap(address: usize, length: usize) usize {725pub fn munmap(address: usize, length: usize) usize {
...@@ -823,8 +834,7 @@ var vdso_clock_gettime = init_vdso_clock_gettime;...@@ -823,8 +834,7 @@ var vdso_clock_gettime = init_vdso_clock_gettime;
823extern fn init_vdso_clock_gettime(clk: i32, ts: &timespec) usize {834extern fn init_vdso_clock_gettime(clk: i32, ts: &timespec) usize {
824 const addr = vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM);835 const addr = vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM);
825 var f = @intToPtr(@typeOf(init_vdso_clock_gettime), addr);836 var f = @intToPtr(@typeOf(init_vdso_clock_gettime), addr);
826 _ = @cmpxchgStrong(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, init_vdso_clock_gettime, f,837 _ = @cmpxchgStrong(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, init_vdso_clock_gettime, f, builtin.AtomicOrder.Monotonic, builtin.AtomicOrder.Monotonic);
827 builtin.AtomicOrder.Monotonic, builtin.AtomicOrder.Monotonic);
828 if (@ptrToInt(f) == 0) return @bitCast(usize, isize(-ENOSYS));838 if (@ptrToInt(f) == 0) return @bitCast(usize, isize(-ENOSYS));
829 return f(clk, ts);839 return f(clk, ts);
830}840}
...@@ -918,18 +928,18 @@ pub fn getpid() i32 {...@@ -918,18 +928,18 @@ pub fn getpid() i32 {
918}928}
919929
920pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&sigset_t) usize {930pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&sigset_t) usize {
921 return syscall4(SYS_rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG/8);931 return syscall4(SYS_rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG / 8);
922}932}
923933
924pub fn sigaction(sig: u6, noalias act: &const Sigaction, noalias oact: ?&Sigaction) usize {934pub fn sigaction(sig: u6, noalias act: &const Sigaction, noalias oact: ?&Sigaction) usize {
925 assert(sig >= 1);935 assert(sig >= 1);
926 assert(sig != SIGKILL);936 assert(sig != SIGKILL);
927 assert(sig != SIGSTOP);937 assert(sig != SIGSTOP);
928 var ksa = k_sigaction {938 var ksa = k_sigaction{
929 .handler = act.handler,939 .handler = act.handler,
930 .flags = act.flags | SA_RESTORER,940 .flags = act.flags | SA_RESTORER,
931 .mask = undefined,941 .mask = undefined,
932 .restorer = @ptrCast(extern fn()void, restore_rt),942 .restorer = @ptrCast(extern fn() void, restore_rt),
933 };943 };
934 var ksa_old: k_sigaction = undefined;944 var ksa_old: k_sigaction = undefined;
935 @memcpy(@ptrCast(&u8, &ksa.mask), @ptrCast(&const u8, &act.mask), 8);945 @memcpy(@ptrCast(&u8, &ksa.mask), @ptrCast(&const u8, &act.mask), 8);
...@@ -952,22 +962,22 @@ const all_mask = []usize{@maxValue(usize)};...@@ -952,22 +962,22 @@ const all_mask = []usize{@maxValue(usize)};
952const app_mask = []usize{0xfffffffc7fffffff};962const app_mask = []usize{0xfffffffc7fffffff};
953963
954const k_sigaction = extern struct {964const k_sigaction = extern struct {
955 handler: extern fn(i32)void,965 handler: extern fn(i32) void,
956 flags: usize,966 flags: usize,
957 restorer: extern fn()void,967 restorer: extern fn() void,
958 mask: [2]u32,968 mask: [2]u32,
959};969};
960970
961/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.971/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
962pub const Sigaction = struct {972pub const Sigaction = struct {
963 handler: extern fn(i32)void,973 handler: extern fn(i32) void,
964 mask: sigset_t,974 mask: sigset_t,
965 flags: u32,975 flags: u32,
966};976};
967977
968pub const SIG_ERR = @intToPtr(extern fn(i32)void, @maxValue(usize));978pub const SIG_ERR = @intToPtr(extern fn(i32) void, @maxValue(usize));
969pub const SIG_DFL = @intToPtr(extern fn(i32)void, 0);979pub const SIG_DFL = @intToPtr(extern fn(i32) void, 0);
970pub const SIG_IGN = @intToPtr(extern fn(i32)void, 1);980pub const SIG_IGN = @intToPtr(extern fn(i32) void, 1);
971pub const empty_sigset = []usize{0} ** sigset_t.len;981pub const empty_sigset = []usize{0} ** sigset_t.len;
972982
973pub fn raise(sig: i32) usize {983pub fn raise(sig: i32) usize {
...@@ -980,25 +990,25 @@ pub fn raise(sig: i32) usize {...@@ -980,25 +990,25 @@ pub fn raise(sig: i32) usize {
980}990}
981991
982fn blockAllSignals(set: &sigset_t) void {992fn blockAllSignals(set: &sigset_t) void {
983 _ = syscall4(SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&all_mask), @ptrToInt(set), NSIG/8);993 _ = syscall4(SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&all_mask), @ptrToInt(set), NSIG / 8);
984}994}
985995
986fn blockAppSignals(set: &sigset_t) void {996fn blockAppSignals(set: &sigset_t) void {
987 _ = syscall4(SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&app_mask), @ptrToInt(set), NSIG/8);997 _ = syscall4(SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&app_mask), @ptrToInt(set), NSIG / 8);
988}998}
989999
990fn restoreSignals(set: &sigset_t) void {1000fn restoreSignals(set: &sigset_t) void {
991 _ = syscall4(SYS_rt_sigprocmask, SIG_SETMASK, @ptrToInt(set), 0, NSIG/8);1001 _ = syscall4(SYS_rt_sigprocmask, SIG_SETMASK, @ptrToInt(set), 0, NSIG / 8);
992}1002}
9931003
994pub fn sigaddset(set: &sigset_t, sig: u6) void {1004pub fn sigaddset(set: &sigset_t, sig: u6) void {
995 const s = sig - 1;1005 const s = sig - 1;
996 (*set)[usize(s) / usize.bit_count] |= usize(1) << (s & (usize.bit_count - 1));1006 (set.*)[usize(s) / usize.bit_count] |= usize(1) << (s & (usize.bit_count - 1));
997}1007}
9981008
999pub fn sigismember(set: &const sigset_t, sig: u6) bool {1009pub fn sigismember(set: &const sigset_t, sig: u6) bool {
1000 const s = sig - 1;1010 const s = sig - 1;
1001 return ((*set)[usize(s) / usize.bit_count] & (usize(1) << (s & (usize.bit_count - 1)))) != 0;1011 return ((set.*)[usize(s) / usize.bit_count] & (usize(1) << (s & (usize.bit_count - 1)))) != 0;
1002}1012}
10031013
1004pub const in_port_t = u16;1014pub const in_port_t = u16;
...@@ -1062,9 +1072,7 @@ pub fn recvmsg(fd: i32, msg: &msghdr, flags: u32) usize {...@@ -1062,9 +1072,7 @@ pub fn recvmsg(fd: i32, msg: &msghdr, flags: u32) usize {
1062 return syscall3(SYS_recvmsg, usize(fd), @ptrToInt(msg), flags);1072 return syscall3(SYS_recvmsg, usize(fd), @ptrToInt(msg), flags);
1063}1073}
10641074
1065pub fn recvfrom(fd: i32, noalias buf: &u8, len: usize, flags: u32,1075pub fn recvfrom(fd: i32, noalias buf: &u8, len: usize, flags: u32, noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) usize {
1066 noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) usize
1067{
1068 return syscall6(SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));1076 return syscall6(SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
1069}1077}
10701078
...@@ -1132,25 +1140,16 @@ pub fn fgetxattr(fd: usize, name: &const u8, value: &void, size: usize) usize {...@@ -1132,25 +1140,16 @@ pub fn fgetxattr(fd: usize, name: &const u8, value: &void, size: usize) usize {
1132 return syscall4(SYS_lgetxattr, fd, @ptrToInt(name), @ptrToInt(value), size);1140 return syscall4(SYS_lgetxattr, fd, @ptrToInt(name), @ptrToInt(value), size);
1133}1141}
11341142
1135pub fn setxattr(path: &const u8, name: &const u8, value: &const void,1143pub fn setxattr(path: &const u8, name: &const u8, value: &const void, size: usize, flags: usize) usize {
1136 size: usize, flags: usize) usize {1144 return syscall5(SYS_setxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size, flags);
1137
1138 return syscall5(SYS_setxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value),
1139 size, flags);
1140}1145}
11411146
1142pub fn lsetxattr(path: &const u8, name: &const u8, value: &const void,1147pub fn lsetxattr(path: &const u8, name: &const u8, value: &const void, size: usize, flags: usize) usize {
1143 size: usize, flags: usize) usize {1148 return syscall5(SYS_lsetxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value), size, flags);
1144
1145 return syscall5(SYS_lsetxattr, @ptrToInt(path), @ptrToInt(name), @ptrToInt(value),
1146 size, flags);
1147}1149}
11481150
1149pub fn fsetxattr(fd: usize, name: &const u8, value: &const void,1151pub fn fsetxattr(fd: usize, name: &const u8, value: &const void, size: usize, flags: usize) usize {
1150 size: usize, flags: usize) usize {1152 return syscall5(SYS_fsetxattr, fd, @ptrToInt(name), @ptrToInt(value), size, flags);
1151
1152 return syscall5(SYS_fsetxattr, fd, @ptrToInt(name), @ptrToInt(value),
1153 size, flags);
1154}1153}
11551154
1156pub fn removexattr(path: &const u8, name: &const u8) usize {1155pub fn removexattr(path: &const u8, name: &const u8) usize {
...@@ -1199,7 +1198,7 @@ pub fn timerfd_create(clockid: i32, flags: u32) usize {...@@ -1199,7 +1198,7 @@ pub fn timerfd_create(clockid: i32, flags: u32) usize {
11991198
1200pub const itimerspec = extern struct {1199pub const itimerspec = extern struct {
1201 it_interval: timespec,1200 it_interval: timespec,
1202 it_value: timespec1201 it_value: timespec,
1203};1202};
12041203
1205pub fn timerfd_gettime(fd: i32, curr_value: &itimerspec) usize {1204pub fn timerfd_gettime(fd: i32, curr_value: &itimerspec) usize {
...@@ -1211,30 +1210,30 @@ pub fn timerfd_settime(fd: i32, flags: u32, new_value: &const itimerspec, old_va...@@ -1211,30 +1210,30 @@ pub fn timerfd_settime(fd: i32, flags: u32, new_value: &const itimerspec, old_va
1211}1210}
12121211
1213pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;1212pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;
1214pub const _LINUX_CAPABILITY_U32S_1 = 1;1213pub const _LINUX_CAPABILITY_U32S_1 = 1;
12151214
1216pub const _LINUX_CAPABILITY_VERSION_2 = 0x20071026;1215pub const _LINUX_CAPABILITY_VERSION_2 = 0x20071026;
1217pub const _LINUX_CAPABILITY_U32S_2 = 2;1216pub const _LINUX_CAPABILITY_U32S_2 = 2;
12181217
1219pub const _LINUX_CAPABILITY_VERSION_3 = 0x20080522;1218pub const _LINUX_CAPABILITY_VERSION_3 = 0x20080522;
1220pub const _LINUX_CAPABILITY_U32S_3 = 2;1219pub const _LINUX_CAPABILITY_U32S_3 = 2;
12211220
1222pub const VFS_CAP_REVISION_MASK = 0xFF000000;1221pub const VFS_CAP_REVISION_MASK = 0xFF000000;
1223pub const VFS_CAP_REVISION_SHIFT = 24;1222pub const VFS_CAP_REVISION_SHIFT = 24;
1224pub const VFS_CAP_FLAGS_MASK = ~VFS_CAP_REVISION_MASK;1223pub const VFS_CAP_FLAGS_MASK = ~VFS_CAP_REVISION_MASK;
1225pub const VFS_CAP_FLAGS_EFFECTIVE = 0x000001;1224pub const VFS_CAP_FLAGS_EFFECTIVE = 0x000001;
12261225
1227pub const VFS_CAP_REVISION_1 = 0x01000000;1226pub const VFS_CAP_REVISION_1 = 0x01000000;
1228pub const VFS_CAP_U32_1 = 1;1227pub const VFS_CAP_U32_1 = 1;
1229pub const XATTR_CAPS_SZ_1 = @sizeOf(u32)*(1 + 2*VFS_CAP_U32_1);1228pub const XATTR_CAPS_SZ_1 = @sizeOf(u32) * (1 + 2 * VFS_CAP_U32_1);
12301229
1231pub const VFS_CAP_REVISION_2 = 0x02000000;1230pub const VFS_CAP_REVISION_2 = 0x02000000;
1232pub const VFS_CAP_U32_2 = 2;1231pub const VFS_CAP_U32_2 = 2;
1233pub const XATTR_CAPS_SZ_2 = @sizeOf(u32)*(1 + 2*VFS_CAP_U32_2);1232pub const XATTR_CAPS_SZ_2 = @sizeOf(u32) * (1 + 2 * VFS_CAP_U32_2);
12341233
1235pub const XATTR_CAPS_SZ = XATTR_CAPS_SZ_2;1234pub const XATTR_CAPS_SZ = XATTR_CAPS_SZ_2;
1236pub const VFS_CAP_U32 = VFS_CAP_U32_2;1235pub const VFS_CAP_U32 = VFS_CAP_U32_2;
1237pub const VFS_CAP_REVISION = VFS_CAP_REVISION_2;1236pub const VFS_CAP_REVISION = VFS_CAP_REVISION_2;
12381237
1239pub const vfs_cap_data = extern struct {1238pub const vfs_cap_data = extern struct {
1240 //all of these are mandated as little endian1239 //all of these are mandated as little endian
...@@ -1245,49 +1244,48 @@ pub const vfs_cap_data = extern struct {...@@ -1245,49 +1244,48 @@ pub const vfs_cap_data = extern struct {
1245 };1244 };
12461245
1247 magic_etc: u32,1246 magic_etc: u32,
1248 data: [VFS_CAP_U32]Data,1247 data: [VFS_CAP_U32]Data,
1249};1248};
12501249
12511250pub const CAP_CHOWN = 0;
1252pub const CAP_CHOWN = 0;1251pub const CAP_DAC_OVERRIDE = 1;
1253pub const CAP_DAC_OVERRIDE = 1;1252pub const CAP_DAC_READ_SEARCH = 2;
1254pub const CAP_DAC_READ_SEARCH = 2;1253pub const CAP_FOWNER = 3;
1255pub const CAP_FOWNER = 3;1254pub const CAP_FSETID = 4;
1256pub const CAP_FSETID = 4;1255pub const CAP_KILL = 5;
1257pub const CAP_KILL = 5;1256pub const CAP_SETGID = 6;
1258pub const CAP_SETGID = 6;1257pub const CAP_SETUID = 7;
1259pub const CAP_SETUID = 7;1258pub const CAP_SETPCAP = 8;
1260pub const CAP_SETPCAP = 8;1259pub const CAP_LINUX_IMMUTABLE = 9;
1261pub const CAP_LINUX_IMMUTABLE = 9;1260pub const CAP_NET_BIND_SERVICE = 10;
1262pub const CAP_NET_BIND_SERVICE = 10;1261pub const CAP_NET_BROADCAST = 11;
1263pub const CAP_NET_BROADCAST = 11;1262pub const CAP_NET_ADMIN = 12;
1264pub const CAP_NET_ADMIN = 12;1263pub const CAP_NET_RAW = 13;
1265pub const CAP_NET_RAW = 13;1264pub const CAP_IPC_LOCK = 14;
1266pub const CAP_IPC_LOCK = 14;1265pub const CAP_IPC_OWNER = 15;
1267pub const CAP_IPC_OWNER = 15;1266pub const CAP_SYS_MODULE = 16;
1268pub const CAP_SYS_MODULE = 16;1267pub const CAP_SYS_RAWIO = 17;
1269pub const CAP_SYS_RAWIO = 17;1268pub const CAP_SYS_CHROOT = 18;
1270pub const CAP_SYS_CHROOT = 18;1269pub const CAP_SYS_PTRACE = 19;
1271pub const CAP_SYS_PTRACE = 19;1270pub const CAP_SYS_PACCT = 20;
1272pub const CAP_SYS_PACCT = 20;1271pub const CAP_SYS_ADMIN = 21;
1273pub const CAP_SYS_ADMIN = 21;1272pub const CAP_SYS_BOOT = 22;
1274pub const CAP_SYS_BOOT = 22;1273pub const CAP_SYS_NICE = 23;
1275pub const CAP_SYS_NICE = 23;1274pub const CAP_SYS_RESOURCE = 24;
1276pub const CAP_SYS_RESOURCE = 24;1275pub const CAP_SYS_TIME = 25;
1277pub const CAP_SYS_TIME = 25;1276pub const CAP_SYS_TTY_CONFIG = 26;
1278pub const CAP_SYS_TTY_CONFIG = 26;1277pub const CAP_MKNOD = 27;
1279pub const CAP_MKNOD = 27;1278pub const CAP_LEASE = 28;
1280pub const CAP_LEASE = 28;1279pub const CAP_AUDIT_WRITE = 29;
1281pub const CAP_AUDIT_WRITE = 29;1280pub const CAP_AUDIT_CONTROL = 30;
1282pub const CAP_AUDIT_CONTROL = 30;1281pub const CAP_SETFCAP = 31;
1283pub const CAP_SETFCAP = 31;1282pub const CAP_MAC_OVERRIDE = 32;
1284pub const CAP_MAC_OVERRIDE = 32;1283pub const CAP_MAC_ADMIN = 33;
1285pub const CAP_MAC_ADMIN = 33;1284pub const CAP_SYSLOG = 34;
1286pub const CAP_SYSLOG = 34;1285pub const CAP_WAKE_ALARM = 35;
1287pub const CAP_WAKE_ALARM = 35;1286pub const CAP_BLOCK_SUSPEND = 36;
1288pub const CAP_BLOCK_SUSPEND = 36;1287pub const CAP_AUDIT_READ = 37;
1289pub const CAP_AUDIT_READ = 37;1288pub const CAP_LAST_CAP = CAP_AUDIT_READ;
1290pub const CAP_LAST_CAP = CAP_AUDIT_READ;
12911289
1292pub fn cap_valid(u8: x) bool {1290pub fn cap_valid(u8: x) bool {
1293 return x >= 0 and x <= CAP_LAST_CAP;1291 return x >= 0 and x <= CAP_LAST_CAP;
std/os/linux/test.zig+6-6
...@@ -11,22 +11,22 @@ test "timer" {...@@ -11,22 +11,22 @@ test "timer" {
11 const timer_fd = linux.timerfd_create(linux.CLOCK_MONOTONIC, 0);11 const timer_fd = linux.timerfd_create(linux.CLOCK_MONOTONIC, 0);
12 assert(linux.getErrno(timer_fd) == 0);12 assert(linux.getErrno(timer_fd) == 0);
1313
14 const time_interval = linux.timespec {14 const time_interval = linux.timespec{
15 .tv_sec = 0,15 .tv_sec = 0,
16 .tv_nsec = 200000016 .tv_nsec = 2000000,
17 };17 };
1818
19 const new_time = linux.itimerspec {19 const new_time = linux.itimerspec{
20 .it_interval = time_interval,20 .it_interval = time_interval,
21 .it_value = time_interval21 .it_value = time_interval,
22 };22 };
2323
24 err = linux.timerfd_settime(i32(timer_fd), 0, &new_time, null);24 err = linux.timerfd_settime(i32(timer_fd), 0, &new_time, null);
25 assert(err == 0);25 assert(err == 0);
2626
27 var event = linux.epoll_event {27 var event = linux.epoll_event{
28 .events = linux.EPOLLIN | linux.EPOLLOUT | linux.EPOLLET,28 .events = linux.EPOLLIN | linux.EPOLLOUT | linux.EPOLLET,
29 .data = linux.epoll_data { .ptr = 0 },29 .data = linux.epoll_data{ .ptr = 0 },
30 };30 };
3131
32 err = linux.epoll_ctl(i32(epoll_fd), linux.EPOLL_CTL_ADD, i32(timer_fd), &event);32 err = linux.epoll_ctl(i32(epoll_fd), linux.EPOLL_CTL_ADD, i32(timer_fd), &event);
std/os/linux/vdso.zig+11-9
...@@ -16,7 +16,10 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {...@@ -16,7 +16,10 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
16 var base: usize = @maxValue(usize);16 var base: usize = @maxValue(usize);
17 {17 {
18 var i: usize = 0;18 var i: usize = 0;
19 while (i < eh.e_phnum) : ({i += 1; ph_addr += eh.e_phentsize;}) {19 while (i < eh.e_phnum) : ({
20 i += 1;
21 ph_addr += eh.e_phentsize;
22 }) {
20 const this_ph = @intToPtr(&elf.Phdr, ph_addr);23 const this_ph = @intToPtr(&elf.Phdr, ph_addr);
21 switch (this_ph.p_type) {24 switch (this_ph.p_type) {
22 elf.PT_LOAD => base = vdso_addr + this_ph.p_offset - this_ph.p_vaddr,25 elf.PT_LOAD => base = vdso_addr + this_ph.p_offset - this_ph.p_vaddr,
...@@ -54,15 +57,14 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {...@@ -54,15 +57,14 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
54 const hashtab = maybe_hashtab ?? return 0;57 const hashtab = maybe_hashtab ?? return 0;
55 if (maybe_verdef == null) maybe_versym = null;58 if (maybe_verdef == null) maybe_versym = null;
5659
5760 const OK_TYPES = (1 << elf.STT_NOTYPE | 1 << elf.STT_OBJECT | 1 << elf.STT_FUNC | 1 << elf.STT_COMMON);
58 const OK_TYPES = (1<<elf.STT_NOTYPE | 1<<elf.STT_OBJECT | 1<<elf.STT_FUNC | 1<<elf.STT_COMMON);61 const OK_BINDS = (1 << elf.STB_GLOBAL | 1 << elf.STB_WEAK | 1 << elf.STB_GNU_UNIQUE);
59 const OK_BINDS = (1<<elf.STB_GLOBAL | 1<<elf.STB_WEAK | 1<<elf.STB_GNU_UNIQUE);
6062
61 var i: usize = 0;63 var i: usize = 0;
62 while (i < hashtab[1]) : (i += 1) {64 while (i < hashtab[1]) : (i += 1) {
63 if (0==(u32(1)<<u5(syms[i].st_info&0xf) & OK_TYPES)) continue;65 if (0 == (u32(1) << u5(syms[i].st_info & 0xf) & OK_TYPES)) continue;
64 if (0==(u32(1)<<u5(syms[i].st_info>>4) & OK_BINDS)) continue;66 if (0 == (u32(1) << u5(syms[i].st_info >> 4) & OK_BINDS)) continue;
65 if (0==syms[i].st_shndx) continue;67 if (0 == syms[i].st_shndx) continue;
66 if (!mem.eql(u8, name, cstr.toSliceConst(&strings[syms[i].st_name]))) continue;68 if (!mem.eql(u8, name, cstr.toSliceConst(&strings[syms[i].st_name]))) continue;
67 if (maybe_versym) |versym| {69 if (maybe_versym) |versym| {
68 if (!checkver(??maybe_verdef, versym[i], vername, strings))70 if (!checkver(??maybe_verdef, versym[i], vername, strings))
...@@ -78,12 +80,12 @@ fn checkver(def_arg: &elf.Verdef, vsym_arg: i32, vername: []const u8, strings: &...@@ -78,12 +80,12 @@ fn checkver(def_arg: &elf.Verdef, vsym_arg: i32, vername: []const u8, strings: &
78 var def = def_arg;80 var def = def_arg;
79 const vsym = @bitCast(u32, vsym_arg) & 0x7fff;81 const vsym = @bitCast(u32, vsym_arg) & 0x7fff;
80 while (true) {82 while (true) {
81 if (0==(def.vd_flags & elf.VER_FLG_BASE) and (def.vd_ndx & 0x7fff) == vsym)83 if (0 == (def.vd_flags & elf.VER_FLG_BASE) and (def.vd_ndx & 0x7fff) == vsym)
82 break;84 break;
83 if (def.vd_next == 0)85 if (def.vd_next == 0)
84 return false;86 return false;
85 def = @intToPtr(&elf.Verdef, @ptrToInt(def) + def.vd_next);87 def = @intToPtr(&elf.Verdef, @ptrToInt(def) + def.vd_next);
86 }88 }
87 const aux = @intToPtr(&elf.Verdaux, @ptrToInt(def ) + def.vd_aux);89 const aux = @intToPtr(&elf.Verdaux, @ptrToInt(def) + def.vd_aux);
88 return mem.eql(u8, vername, cstr.toSliceConst(&strings[aux.vda_name]));90 return mem.eql(u8, vername, cstr.toSliceConst(&strings[aux.vda_name]));
89}91}
std/os/linux/x86_64.zig+63-51
...@@ -330,26 +330,26 @@ pub const SYS_userfaultfd = 323;...@@ -330,26 +330,26 @@ pub const SYS_userfaultfd = 323;
330pub const SYS_membarrier = 324;330pub const SYS_membarrier = 324;
331pub const SYS_mlock2 = 325;331pub const SYS_mlock2 = 325;
332332
333pub const O_CREAT = 0o100;333pub const O_CREAT = 0o100;
334pub const O_EXCL = 0o200;334pub const O_EXCL = 0o200;
335pub const O_NOCTTY = 0o400;335pub const O_NOCTTY = 0o400;
336pub const O_TRUNC = 0o1000;336pub const O_TRUNC = 0o1000;
337pub const O_APPEND = 0o2000;337pub const O_APPEND = 0o2000;
338pub const O_NONBLOCK = 0o4000;338pub const O_NONBLOCK = 0o4000;
339pub const O_DSYNC = 0o10000;339pub const O_DSYNC = 0o10000;
340pub const O_SYNC = 0o4010000;340pub const O_SYNC = 0o4010000;
341pub const O_RSYNC = 0o4010000;341pub const O_RSYNC = 0o4010000;
342pub const O_DIRECTORY = 0o200000;342pub const O_DIRECTORY = 0o200000;
343pub const O_NOFOLLOW = 0o400000;343pub const O_NOFOLLOW = 0o400000;
344pub const O_CLOEXEC = 0o2000000;344pub const O_CLOEXEC = 0o2000000;
345345
346pub const O_ASYNC = 0o20000;346pub const O_ASYNC = 0o20000;
347pub const O_DIRECT = 0o40000;347pub const O_DIRECT = 0o40000;
348pub const O_LARGEFILE = 0;348pub const O_LARGEFILE = 0;
349pub const O_NOATIME = 0o1000000;349pub const O_NOATIME = 0o1000000;
350pub const O_PATH = 0o10000000;350pub const O_PATH = 0o10000000;
351pub const O_TMPFILE = 0o20200000;351pub const O_TMPFILE = 0o20200000;
352pub const O_NDELAY = O_NONBLOCK;352pub const O_NDELAY = O_NONBLOCK;
353353
354pub const F_DUPFD = 0;354pub const F_DUPFD = 0;
355pub const F_GETFD = 1;355pub const F_GETFD = 1;
...@@ -371,7 +371,6 @@ pub const F_GETOWN_EX = 16;...@@ -371,7 +371,6 @@ pub const F_GETOWN_EX = 16;
371371
372pub const F_GETOWNER_UIDS = 17;372pub const F_GETOWNER_UIDS = 17;
373373
374
375pub const VDSO_USEFUL = true;374pub const VDSO_USEFUL = true;
376pub const VDSO_CGT_SYM = "__vdso_clock_gettime";375pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
377pub const VDSO_CGT_VER = "LINUX_2.6";376pub const VDSO_CGT_VER = "LINUX_2.6";
...@@ -382,72 +381,85 @@ pub fn syscall0(number: usize) usize {...@@ -382,72 +381,85 @@ pub fn syscall0(number: usize) usize {
382 return asm volatile ("syscall"381 return asm volatile ("syscall"
383 : [ret] "={rax}" (-> usize)382 : [ret] "={rax}" (-> usize)
384 : [number] "{rax}" (number)383 : [number] "{rax}" (number)
385 : "rcx", "r11");384 : "rcx", "r11"
385 );
386}386}
387387
388pub fn syscall1(number: usize, arg1: usize) usize {388pub fn syscall1(number: usize, arg1: usize) usize {
389 return asm volatile ("syscall"389 return asm volatile ("syscall"
390 : [ret] "={rax}" (-> usize)390 : [ret] "={rax}" (-> usize)
391 : [number] "{rax}" (number),391 : [number] "{rax}" (number),
392 [arg1] "{rdi}" (arg1)392 [arg1] "{rdi}" (arg1)
393 : "rcx", "r11");393 : "rcx", "r11"
394 );
394}395}
395396
396pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize {397pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
397 return asm volatile ("syscall"398 return asm volatile ("syscall"
398 : [ret] "={rax}" (-> usize)399 : [ret] "={rax}" (-> usize)
399 : [number] "{rax}" (number),400 : [number] "{rax}" (number),
400 [arg1] "{rdi}" (arg1),401 [arg1] "{rdi}" (arg1),
401 [arg2] "{rsi}" (arg2)402 [arg2] "{rsi}" (arg2)
402 : "rcx", "r11");403 : "rcx", "r11"
404 );
403}405}
404406
405pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {407pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
406 return asm volatile ("syscall"408 return asm volatile ("syscall"
407 : [ret] "={rax}" (-> usize)409 : [ret] "={rax}" (-> usize)
408 : [number] "{rax}" (number),410 : [number] "{rax}" (number),
409 [arg1] "{rdi}" (arg1),411 [arg1] "{rdi}" (arg1),
410 [arg2] "{rsi}" (arg2),412 [arg2] "{rsi}" (arg2),
411 [arg3] "{rdx}" (arg3)413 [arg3] "{rdx}" (arg3)
412 : "rcx", "r11");414 : "rcx", "r11"
415 );
413}416}
414417
415pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {418pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
416 return asm volatile ("syscall"419 return asm volatile ("syscall"
417 : [ret] "={rax}" (-> usize)420 : [ret] "={rax}" (-> usize)
418 : [number] "{rax}" (number),421 : [number] "{rax}" (number),
419 [arg1] "{rdi}" (arg1),422 [arg1] "{rdi}" (arg1),
420 [arg2] "{rsi}" (arg2),423 [arg2] "{rsi}" (arg2),
421 [arg3] "{rdx}" (arg3),424 [arg3] "{rdx}" (arg3),
422 [arg4] "{r10}" (arg4)425 [arg4] "{r10}" (arg4)
423 : "rcx", "r11");426 : "rcx", "r11"
427 );
424}428}
425429
426pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {430pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
427 return asm volatile ("syscall"431 return asm volatile ("syscall"
428 : [ret] "={rax}" (-> usize)432 : [ret] "={rax}" (-> usize)
429 : [number] "{rax}" (number),433 : [number] "{rax}" (number),
430 [arg1] "{rdi}" (arg1),434 [arg1] "{rdi}" (arg1),
431 [arg2] "{rsi}" (arg2),435 [arg2] "{rsi}" (arg2),
432 [arg3] "{rdx}" (arg3),436 [arg3] "{rdx}" (arg3),
433 [arg4] "{r10}" (arg4),437 [arg4] "{r10}" (arg4),
434 [arg5] "{r8}" (arg5)438 [arg5] "{r8}" (arg5)
435 : "rcx", "r11");439 : "rcx", "r11"
440 );
436}441}
437442
438pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize,443pub fn syscall6(
439 arg5: usize, arg6: usize) usize444 number: usize,
440{445 arg1: usize,
446 arg2: usize,
447 arg3: usize,
448 arg4: usize,
449 arg5: usize,
450 arg6: usize,
451) usize {
441 return asm volatile ("syscall"452 return asm volatile ("syscall"
442 : [ret] "={rax}" (-> usize)453 : [ret] "={rax}" (-> usize)
443 : [number] "{rax}" (number),454 : [number] "{rax}" (number),
444 [arg1] "{rdi}" (arg1),455 [arg1] "{rdi}" (arg1),
445 [arg2] "{rsi}" (arg2),456 [arg2] "{rsi}" (arg2),
446 [arg3] "{rdx}" (arg3),457 [arg3] "{rdx}" (arg3),
447 [arg4] "{r10}" (arg4),458 [arg4] "{r10}" (arg4),
448 [arg5] "{r8}" (arg5),459 [arg5] "{r8}" (arg5),
449 [arg6] "{r9}" (arg6)460 [arg6] "{r9}" (arg6)
450 : "rcx", "r11");461 : "rcx", "r11"
462 );
451}463}
452464
453/// This matches the libc clone function.465/// This matches the libc clone function.
...@@ -457,10 +469,10 @@ pub nakedcc fn restore_rt() void {...@@ -457,10 +469,10 @@ pub nakedcc fn restore_rt() void {
457 return asm volatile ("syscall"469 return asm volatile ("syscall"
458 :470 :
459 : [number] "{rax}" (usize(SYS_rt_sigreturn))471 : [number] "{rax}" (usize(SYS_rt_sigreturn))
460 : "rcx", "r11");472 : "rcx", "r11"
473 );
461}474}
462475
463
464pub const msghdr = extern struct {476pub const msghdr = extern struct {
465 msg_name: &u8,477 msg_name: &u8,
466 msg_namelen: socklen_t,478 msg_namelen: socklen_t,
std/os/path.zig+43-52
...@@ -55,9 +55,7 @@ test "os.path.join" {...@@ -55,9 +55,7 @@ test "os.path.join" {
55 assert(mem.eql(u8, try joinWindows(debug.global_allocator, "c:\\", "a", "b\\", "c"), "c:\\a\\b\\c"));55 assert(mem.eql(u8, try joinWindows(debug.global_allocator, "c:\\", "a", "b\\", "c"), "c:\\a\\b\\c"));
56 assert(mem.eql(u8, try joinWindows(debug.global_allocator, "c:\\a\\", "b\\", "c"), "c:\\a\\b\\c"));56 assert(mem.eql(u8, try joinWindows(debug.global_allocator, "c:\\a\\", "b\\", "c"), "c:\\a\\b\\c"));
5757
58 assert(mem.eql(u8, try joinWindows(debug.global_allocator,58 assert(mem.eql(u8, try joinWindows(debug.global_allocator, "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std", "io.zig"), "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std\\io.zig"));
59 "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std", "io.zig"),
60 "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std\\io.zig"));
6159
62 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/a/b", "c"), "/a/b/c"));60 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/a/b", "c"), "/a/b/c"));
63 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/a/b/", "c"), "/a/b/c"));61 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/a/b/", "c"), "/a/b/c"));
...@@ -65,8 +63,7 @@ test "os.path.join" {...@@ -65,8 +63,7 @@ test "os.path.join" {
65 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/", "a", "b/", "c"), "/a/b/c"));63 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/", "a", "b/", "c"), "/a/b/c"));
66 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/a/", "b/", "c"), "/a/b/c"));64 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/a/", "b/", "c"), "/a/b/c"));
6765
68 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/home/andy/dev/zig/build/lib/zig/std", "io.zig"),66 assert(mem.eql(u8, try joinPosix(debug.global_allocator, "/home/andy/dev/zig/build/lib/zig/std", "io.zig"), "/home/andy/dev/zig/build/lib/zig/std/io.zig"));
69 "/home/andy/dev/zig/build/lib/zig/std/io.zig"));
70}67}
7168
72pub fn isAbsolute(path: []const u8) bool {69pub fn isAbsolute(path: []const u8) bool {
...@@ -151,22 +148,22 @@ pub const WindowsPath = struct {...@@ -151,22 +148,22 @@ pub const WindowsPath = struct {
151148
152pub fn windowsParsePath(path: []const u8) WindowsPath {149pub fn windowsParsePath(path: []const u8) WindowsPath {
153 if (path.len >= 2 and path[1] == ':') {150 if (path.len >= 2 and path[1] == ':') {
154 return WindowsPath {151 return WindowsPath{
155 .is_abs = isAbsoluteWindows(path),152 .is_abs = isAbsoluteWindows(path),
156 .kind = WindowsPath.Kind.Drive,153 .kind = WindowsPath.Kind.Drive,
157 .disk_designator = path[0..2],154 .disk_designator = path[0..2],
158 };155 };
159 }156 }
160 if (path.len >= 1 and (path[0] == '/' or path[0] == '\\') and157 if (path.len >= 1 and (path[0] == '/' or path[0] == '\\') and
161 (path.len == 1 or (path[1] != '/' and path[1] != '\\')))158 (path.len == 1 or (path[1] != '/' and path[1] != '\\')))
162 {159 {
163 return WindowsPath {160 return WindowsPath{
164 .is_abs = true,161 .is_abs = true,
165 .kind = WindowsPath.Kind.None,162 .kind = WindowsPath.Kind.None,
166 .disk_designator = path[0..0],163 .disk_designator = path[0..0],
167 };164 };
168 }165 }
169 const relative_path = WindowsPath {166 const relative_path = WindowsPath{
170 .kind = WindowsPath.Kind.None,167 .kind = WindowsPath.Kind.None,
171 .disk_designator = []u8{},168 .disk_designator = []u8{},
172 .is_abs = false,169 .is_abs = false,
...@@ -178,7 +175,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {...@@ -178,7 +175,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {
178 // TODO when I combined these together with `inline for` the compiler crashed175 // TODO when I combined these together with `inline for` the compiler crashed
179 {176 {
180 const this_sep = '/';177 const this_sep = '/';
181 const two_sep = []u8{this_sep, this_sep};178 const two_sep = []u8{ this_sep, this_sep };
182 if (mem.startsWith(u8, path, two_sep)) {179 if (mem.startsWith(u8, path, two_sep)) {
183 if (path[2] == this_sep) {180 if (path[2] == this_sep) {
184 return relative_path;181 return relative_path;
...@@ -187,7 +184,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {...@@ -187,7 +184,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {
187 var it = mem.split(path, []u8{this_sep});184 var it = mem.split(path, []u8{this_sep});
188 _ = (it.next() ?? return relative_path);185 _ = (it.next() ?? return relative_path);
189 _ = (it.next() ?? return relative_path);186 _ = (it.next() ?? return relative_path);
190 return WindowsPath {187 return WindowsPath{
191 .is_abs = isAbsoluteWindows(path),188 .is_abs = isAbsoluteWindows(path),
192 .kind = WindowsPath.Kind.NetworkShare,189 .kind = WindowsPath.Kind.NetworkShare,
193 .disk_designator = path[0..it.index],190 .disk_designator = path[0..it.index],
...@@ -196,7 +193,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {...@@ -196,7 +193,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {
196 }193 }
197 {194 {
198 const this_sep = '\\';195 const this_sep = '\\';
199 const two_sep = []u8{this_sep, this_sep};196 const two_sep = []u8{ this_sep, this_sep };
200 if (mem.startsWith(u8, path, two_sep)) {197 if (mem.startsWith(u8, path, two_sep)) {
201 if (path[2] == this_sep) {198 if (path[2] == this_sep) {
202 return relative_path;199 return relative_path;
...@@ -205,7 +202,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {...@@ -205,7 +202,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {
205 var it = mem.split(path, []u8{this_sep});202 var it = mem.split(path, []u8{this_sep});
206 _ = (it.next() ?? return relative_path);203 _ = (it.next() ?? return relative_path);
207 _ = (it.next() ?? return relative_path);204 _ = (it.next() ?? return relative_path);
208 return WindowsPath {205 return WindowsPath{
209 .is_abs = isAbsoluteWindows(path),206 .is_abs = isAbsoluteWindows(path),
210 .kind = WindowsPath.Kind.NetworkShare,207 .kind = WindowsPath.Kind.NetworkShare,
211 .disk_designator = path[0..it.index],208 .disk_designator = path[0..it.index],
...@@ -296,7 +293,7 @@ fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8...@@ -296,7 +293,7 @@ fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8
296293
297fn asciiUpper(byte: u8) u8 {294fn asciiUpper(byte: u8) u8 {
298 return switch (byte) {295 return switch (byte) {
299 'a' ... 'z' => 'A' + (byte - 'a'),296 'a'...'z' => 'A' + (byte - 'a'),
300 else => byte,297 else => byte,
301 };298 };
302}299}
...@@ -372,7 +369,6 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {...@@ -372,7 +369,6 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {
372 max_size += p.len + 1;369 max_size += p.len + 1;
373 }370 }
374371
375
376 // if we will result with a disk designator, loop again to determine372 // if we will result with a disk designator, loop again to determine
377 // which is the last time the disk designator is absolutely specified, if any373 // which is the last time the disk designator is absolutely specified, if any
378 // and count up the max bytes for paths related to this disk designator374 // and count up the max bytes for paths related to this disk designator
...@@ -386,8 +382,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {...@@ -386,8 +382,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {
386 const parsed = windowsParsePath(p);382 const parsed = windowsParsePath(p);
387 if (parsed.kind != WindowsPath.Kind.None) {383 if (parsed.kind != WindowsPath.Kind.None) {
388 if (parsed.kind == have_drive_kind) {384 if (parsed.kind == have_drive_kind) {
389 correct_disk_designator = compareDiskDesignators(have_drive_kind,385 correct_disk_designator = compareDiskDesignators(have_drive_kind, result_disk_designator, parsed.disk_designator);
390 result_disk_designator, parsed.disk_designator);
391 } else {386 } else {
392 continue;387 continue;
393 }388 }
...@@ -404,7 +399,6 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {...@@ -404,7 +399,6 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {
404 }399 }
405 }400 }
406401
407
408 // Allocate result and fill in the disk designator, calling getCwd if we have to.402 // Allocate result and fill in the disk designator, calling getCwd if we have to.
409 var result: []u8 = undefined;403 var result: []u8 = undefined;
410 var result_index: usize = 0;404 var result_index: usize = 0;
...@@ -433,7 +427,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {...@@ -433,7 +427,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {
433 result_index += 1;427 result_index += 1;
434 mem.copy(u8, result[result_index..], other_name);428 mem.copy(u8, result[result_index..], other_name);
435 result_index += other_name.len;429 result_index += other_name.len;
436 430
437 result_disk_designator = result[0..result_index];431 result_disk_designator = result[0..result_index];
438 },432 },
439 WindowsPath.Kind.None => {433 WindowsPath.Kind.None => {
...@@ -478,8 +472,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {...@@ -478,8 +472,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {
478472
479 if (parsed.kind != WindowsPath.Kind.None) {473 if (parsed.kind != WindowsPath.Kind.None) {
480 if (parsed.kind == have_drive_kind) {474 if (parsed.kind == have_drive_kind) {
481 correct_disk_designator = compareDiskDesignators(have_drive_kind,475 correct_disk_designator = compareDiskDesignators(have_drive_kind, result_disk_designator, parsed.disk_designator);
482 result_disk_designator, parsed.disk_designator);
483 } else {476 } else {
484 continue;477 continue;
485 }478 }
...@@ -591,7 +584,7 @@ test "os.path.resolve" {...@@ -591,7 +584,7 @@ test "os.path.resolve" {
591 }584 }
592 assert(mem.eql(u8, testResolveWindows([][]const u8{"."}), cwd));585 assert(mem.eql(u8, testResolveWindows([][]const u8{"."}), cwd));
593 } else {586 } else {
594 assert(mem.eql(u8, testResolvePosix([][]const u8{"a/b/c/", "../../.."}), cwd));587 assert(mem.eql(u8, testResolvePosix([][]const u8{ "a/b/c/", "../../.." }), cwd));
595 assert(mem.eql(u8, testResolvePosix([][]const u8{"."}), cwd));588 assert(mem.eql(u8, testResolvePosix([][]const u8{"."}), cwd));
596 }589 }
597}590}
...@@ -601,16 +594,15 @@ test "os.path.resolveWindows" {...@@ -601,16 +594,15 @@ test "os.path.resolveWindows" {
601 const cwd = try os.getCwd(debug.global_allocator);594 const cwd = try os.getCwd(debug.global_allocator);
602 const parsed_cwd = windowsParsePath(cwd);595 const parsed_cwd = windowsParsePath(cwd);
603 {596 {
604 const result = testResolveWindows([][]const u8{"/usr/local", "lib\\zig\\std\\array_list.zig"});597 const result = testResolveWindows([][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" });
605 const expected = try join(debug.global_allocator,598 const expected = try join(debug.global_allocator, parsed_cwd.disk_designator, "usr\\local\\lib\\zig\\std\\array_list.zig");
606 parsed_cwd.disk_designator, "usr\\local\\lib\\zig\\std\\array_list.zig");
607 if (parsed_cwd.kind == WindowsPath.Kind.Drive) {599 if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
608 expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);600 expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
609 }601 }
610 assert(mem.eql(u8, result, expected));602 assert(mem.eql(u8, result, expected));
611 }603 }
612 {604 {
613 const result = testResolveWindows([][]const u8{"usr/local", "lib\\zig"});605 const result = testResolveWindows([][]const u8{ "usr/local", "lib\\zig" });
614 const expected = try join(debug.global_allocator, cwd, "usr\\local\\lib\\zig");606 const expected = try join(debug.global_allocator, cwd, "usr\\local\\lib\\zig");
615 if (parsed_cwd.kind == WindowsPath.Kind.Drive) {607 if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
616 expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);608 expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
...@@ -619,33 +611,32 @@ test "os.path.resolveWindows" {...@@ -619,33 +611,32 @@ test "os.path.resolveWindows" {
619 }611 }
620 }612 }
621613
622 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:\\a\\b\\c", "/hi", "ok"}), "C:\\hi\\ok"));614 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }), "C:\\hi\\ok"));
623 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:/blah\\blah", "d:/games", "c:../a"}), "C:\\blah\\a"));615 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }), "C:\\blah\\a"));
624 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:/blah\\blah", "d:/games", "C:../a"}), "C:\\blah\\a"));616 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/blah\\blah", "d:/games", "C:../a" }), "C:\\blah\\a"));
625 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:/ignore", "d:\\a/b\\c/d", "\\e.exe"}), "D:\\e.exe"));617 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/ignore", "d:\\a/b\\c/d", "\\e.exe" }), "D:\\e.exe"));
626 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:/ignore", "c:/some/file"}), "C:\\some\\file"));618 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/ignore", "c:/some/file" }), "C:\\some\\file"));
627 assert(mem.eql(u8, testResolveWindows([][]const u8{"d:/ignore", "d:some/dir//"}), "D:\\ignore\\some\\dir"));619 assert(mem.eql(u8, testResolveWindows([][]const u8{ "d:/ignore", "d:some/dir//" }), "D:\\ignore\\some\\dir"));
628 assert(mem.eql(u8, testResolveWindows([][]const u8{"//server/share", "..", "relative\\"}), "\\\\server\\share\\relative"));620 assert(mem.eql(u8, testResolveWindows([][]const u8{ "//server/share", "..", "relative\\" }), "\\\\server\\share\\relative"));
629 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:/", "//"}), "C:\\"));621 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//" }), "C:\\"));
630 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:/", "//dir"}), "C:\\dir"));622 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//dir" }), "C:\\dir"));
631 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:/", "//server/share"}), "\\\\server\\share\\"));623 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//server/share" }), "\\\\server\\share\\"));
632 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:/", "//server//share"}), "\\\\server\\share\\"));624 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//server//share" }), "\\\\server\\share\\"));
633 assert(mem.eql(u8, testResolveWindows([][]const u8{"c:/", "///some//dir"}), "C:\\some\\dir"));625 assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "///some//dir" }), "C:\\some\\dir"));
634 assert(mem.eql(u8, testResolveWindows([][]const u8{"C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js"}),626 assert(mem.eql(u8, testResolveWindows([][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }), "C:\\foo\\tmp.3\\cycles\\root.js"));
635 "C:\\foo\\tmp.3\\cycles\\root.js"));
636}627}
637628
638test "os.path.resolvePosix" {629test "os.path.resolvePosix" {
639 assert(mem.eql(u8, testResolvePosix([][]const u8{"/a/b", "c"}), "/a/b/c"));630 assert(mem.eql(u8, testResolvePosix([][]const u8{ "/a/b", "c" }), "/a/b/c"));
640 assert(mem.eql(u8, testResolvePosix([][]const u8{"/a/b", "c", "//d", "e///"}), "/d/e"));631 assert(mem.eql(u8, testResolvePosix([][]const u8{ "/a/b", "c", "//d", "e///" }), "/d/e"));
641 assert(mem.eql(u8, testResolvePosix([][]const u8{"/a/b/c", "..", "../"}), "/a"));632 assert(mem.eql(u8, testResolvePosix([][]const u8{ "/a/b/c", "..", "../" }), "/a"));
642 assert(mem.eql(u8, testResolvePosix([][]const u8{"/", "..", ".."}), "/"));633 assert(mem.eql(u8, testResolvePosix([][]const u8{ "/", "..", ".." }), "/"));
643 assert(mem.eql(u8, testResolvePosix([][]const u8{"/a/b/c/"}), "/a/b/c"));634 assert(mem.eql(u8, testResolvePosix([][]const u8{"/a/b/c/"}), "/a/b/c"));
644635
645 assert(mem.eql(u8, testResolvePosix([][]const u8{"/var/lib", "../", "file/"}), "/var/file"));636 assert(mem.eql(u8, testResolvePosix([][]const u8{ "/var/lib", "../", "file/" }), "/var/file"));
646 assert(mem.eql(u8, testResolvePosix([][]const u8{"/var/lib", "/../", "file/"}), "/file"));637 assert(mem.eql(u8, testResolvePosix([][]const u8{ "/var/lib", "/../", "file/" }), "/file"));
647 assert(mem.eql(u8, testResolvePosix([][]const u8{"/some/dir", ".", "/absolute/"}), "/absolute"));638 assert(mem.eql(u8, testResolvePosix([][]const u8{ "/some/dir", ".", "/absolute/" }), "/absolute"));
648 assert(mem.eql(u8, testResolvePosix([][]const u8{"/foo/tmp.3/", "../tmp.3/cycles/root.js"}), "/foo/tmp.3/cycles/root.js"));639 assert(mem.eql(u8, testResolvePosix([][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }), "/foo/tmp.3/cycles/root.js"));
649}640}
650641
651fn testResolveWindows(paths: []const []const u8) []u8 {642fn testResolveWindows(paths: []const []const u8) []u8 {
...@@ -656,6 +647,8 @@ fn testResolvePosix(paths: []const []const u8) []u8 {...@@ -656,6 +647,8 @@ fn testResolvePosix(paths: []const []const u8) []u8 {
656 return resolvePosix(debug.global_allocator, paths) catch unreachable;647 return resolvePosix(debug.global_allocator, paths) catch unreachable;
657}648}
658649
650/// If the path is a file in the current directory (no directory component)
651/// then the returned slice has .len = 0.
659pub fn dirname(path: []const u8) []const u8 {652pub fn dirname(path: []const u8) []const u8 {
660 if (is_windows) {653 if (is_windows) {
661 return dirnameWindows(path);654 return dirnameWindows(path);
...@@ -1079,9 +1072,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) ![]u8 {...@@ -1079,9 +1072,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) ![]u8 {
1079 mem.copy(u8, pathname_buf, pathname);1072 mem.copy(u8, pathname_buf, pathname);
1080 pathname_buf[pathname.len] = 0;1073 pathname_buf[pathname.len] = 0;
10811074
1082 const h_file = windows.CreateFileA(pathname_buf.ptr,1075 const h_file = windows.CreateFileA(pathname_buf.ptr, windows.GENERIC_READ, windows.FILE_SHARE_READ, null, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null);
1083 windows.GENERIC_READ, windows.FILE_SHARE_READ, null, windows.OPEN_EXISTING,
1084 windows.FILE_ATTRIBUTE_NORMAL, null);
1085 if (h_file == windows.INVALID_HANDLE_VALUE) {1076 if (h_file == windows.INVALID_HANDLE_VALUE) {
1086 const err = windows.GetLastError();1077 const err = windows.GetLastError();
1087 return switch (err) {1078 return switch (err) {
...@@ -1161,7 +1152,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) ![]u8 {...@@ -1161,7 +1152,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) ![]u8 {
1161 return allocator.shrink(u8, result_buf, cstr.len(result_buf.ptr));1152 return allocator.shrink(u8, result_buf, cstr.len(result_buf.ptr));
1162 },1153 },
1163 Os.linux => {1154 Os.linux => {
1164 const fd = try os.posixOpen(allocator, pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0);1155 const fd = try os.posixOpen(allocator, pathname, posix.O_PATH | posix.O_NONBLOCK | posix.O_CLOEXEC, 0);
1165 defer os.close(fd);1156 defer os.close(fd);
11661157
1167 var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined;1158 var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined;
std/os/test.zig+1-1
...@@ -12,7 +12,7 @@ const AtomicOrder = builtin.AtomicOrder;...@@ -12,7 +12,7 @@ const AtomicOrder = builtin.AtomicOrder;
12test "makePath, put some files in it, deleteTree" {12test "makePath, put some files in it, deleteTree" {
13 if (builtin.os == builtin.Os.windows) {13 if (builtin.os == builtin.Os.windows) {
14 // TODO implement os.Dir for windows14 // TODO implement os.Dir for windows
15 // https://github.com/zig-lang/zig/issues/70915 // https://github.com/ziglang/zig/issues/709
16 return;16 return;
17 }17 }
18 try os.makePath(a, "os_test_tmp/b/c");18 try os.makePath(a, "os_test_tmp/b/c");
std/os/time.zig+32-39
...@@ -27,7 +27,7 @@ pub fn sleep(seconds: usize, nanoseconds: usize) void {...@@ -27,7 +27,7 @@ pub fn sleep(seconds: usize, nanoseconds: usize) void {
2727
28const u63 = @IntType(false, 63);28const u63 = @IntType(false, 63);
29pub fn posixSleep(seconds: u63, nanoseconds: u63) void {29pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
30 var req = posix.timespec {30 var req = posix.timespec{
31 .tv_sec = seconds,31 .tv_sec = seconds,
32 .tv_nsec = nanoseconds,32 .tv_nsec = nanoseconds,
33 };33 };
...@@ -71,7 +71,7 @@ fn milliTimestampWindows() u64 {...@@ -71,7 +71,7 @@ fn milliTimestampWindows() u64 {
71 var ft: i64 = undefined;71 var ft: i64 = undefined;
72 windows.GetSystemTimeAsFileTime(&ft);72 windows.GetSystemTimeAsFileTime(&ft);
73 const hns_per_ms = (ns_per_s / 100) / ms_per_s;73 const hns_per_ms = (ns_per_s / 100) / ms_per_s;
74 const epoch_adj = epoch.windows * ms_per_s;74 const epoch_adj = epoch.windows * ms_per_s;
75 return u64(@divFloor(ft, hns_per_ms) + epoch_adj);75 return u64(@divFloor(ft, hns_per_ms) + epoch_adj);
76}76}
7777
...@@ -83,7 +83,7 @@ fn milliTimestampDarwin() u64 {...@@ -83,7 +83,7 @@ fn milliTimestampDarwin() u64 {
83 debug.assert(err == 0);83 debug.assert(err == 0);
84 const sec_ms = u64(tv.tv_sec) * ms_per_s;84 const sec_ms = u64(tv.tv_sec) * ms_per_s;
85 const usec_ms = @divFloor(u64(tv.tv_usec), us_per_s / ms_per_s);85 const usec_ms = @divFloor(u64(tv.tv_usec), us_per_s / ms_per_s);
86 return u64(sec_ms) + u64(usec_ms); 86 return u64(sec_ms) + u64(usec_ms);
87}87}
8888
89fn milliTimestampPosix() u64 {89fn milliTimestampPosix() u64 {
...@@ -110,17 +110,16 @@ pub const s_per_hour = s_per_min * 60;...@@ -110,17 +110,16 @@ pub const s_per_hour = s_per_min * 60;
110pub const s_per_day = s_per_hour * 24;110pub const s_per_day = s_per_hour * 24;
111pub const s_per_week = s_per_day * 7;111pub const s_per_week = s_per_day * 7;
112112
113
114/// A monotonic high-performance timer.113/// A monotonic high-performance timer.
115/// Timer.start() must be called to initialize the struct, which captures114/// Timer.start() must be called to initialize the struct, which captures
116/// the counter frequency on windows and darwin, records the resolution,115/// the counter frequency on windows and darwin, records the resolution,
117/// and gives the user an oportunity to check for the existnece of116/// and gives the user an oportunity to check for the existnece of
118/// monotonic clocks without forcing them to check for error on each read.117/// monotonic clocks without forcing them to check for error on each read.
119/// .resolution is in nanoseconds on all platforms but .start_time's meaning 118/// .resolution is in nanoseconds on all platforms but .start_time's meaning
120/// depends on the OS. On Windows and Darwin it is a hardware counter 119/// depends on the OS. On Windows and Darwin it is a hardware counter
121/// value that requires calculation to convert to a meaninful unit.120/// value that requires calculation to convert to a meaninful unit.
122pub const Timer = struct {121pub const Timer = struct {
123 122
124 //if we used resolution's value when performing the123 //if we used resolution's value when performing the
125 // performance counter calc on windows/darwin, it would124 // performance counter calc on windows/darwin, it would
126 // be less precise125 // be less precise
...@@ -131,31 +130,31 @@ pub const Timer = struct {...@@ -131,31 +130,31 @@ pub const Timer = struct {
131 },130 },
132 resolution: u64,131 resolution: u64,
133 start_time: u64,132 start_time: u64,
134 133
135
136 //At some point we may change our minds on RAW, but for now we're134 //At some point we may change our minds on RAW, but for now we're
137 // sticking with posix standard MONOTONIC. For more information, see: 135 // sticking with posix standard MONOTONIC. For more information, see:
138 // https://github.com/zig-lang/zig/pull/933136 // https://github.com/ziglang/zig/pull/933
139 //137 //
140 //const monotonic_clock_id = switch(builtin.os) {138 //const monotonic_clock_id = switch(builtin.os) {
141 // Os.linux => linux.CLOCK_MONOTONIC_RAW,139 // Os.linux => linux.CLOCK_MONOTONIC_RAW,
142 // else => posix.CLOCK_MONOTONIC,140 // else => posix.CLOCK_MONOTONIC,
143 //};141 //};
144 const monotonic_clock_id = posix.CLOCK_MONOTONIC;142 const monotonic_clock_id = posix.CLOCK_MONOTONIC;
145
146
147 /// Initialize the timer structure.143 /// Initialize the timer structure.
148 //This gives us an oportunity to grab the counter frequency in windows.144 //This gives us an oportunity to grab the counter frequency in windows.
149 //On Windows: QueryPerformanceCounter will succeed on anything >= XP/2000.145 //On Windows: QueryPerformanceCounter will succeed on anything >= XP/2000.
150 //On Posix: CLOCK_MONOTONIC will only fail if the monotonic counter is not 146 //On Posix: CLOCK_MONOTONIC will only fail if the monotonic counter is not
151 // supported, or if the timespec pointer is out of bounds, which should be 147 // supported, or if the timespec pointer is out of bounds, which should be
152 // impossible here barring cosmic rays or other such occurances of148 // impossible here barring cosmic rays or other such occurances of
153 // incredibly bad luck.149 // incredibly bad luck.
154 //On Darwin: This cannot fail, as far as I am able to tell.150 //On Darwin: This cannot fail, as far as I am able to tell.
155 const TimerError = error{TimerUnsupported, Unexpected};151 const TimerError = error{
152 TimerUnsupported,
153 Unexpected,
154 };
156 pub fn start() TimerError!Timer {155 pub fn start() TimerError!Timer {
157 var self: Timer = undefined;156 var self: Timer = undefined;
158 157
159 switch (builtin.os) {158 switch (builtin.os) {
160 Os.windows => {159 Os.windows => {
161 var freq: i64 = undefined;160 var freq: i64 = undefined;
...@@ -163,7 +162,7 @@ pub const Timer = struct {...@@ -163,7 +162,7 @@ pub const Timer = struct {
163 if (err == windows.FALSE) return error.TimerUnsupported;162 if (err == windows.FALSE) return error.TimerUnsupported;
164 self.frequency = u64(freq);163 self.frequency = u64(freq);
165 self.resolution = @divFloor(ns_per_s, self.frequency);164 self.resolution = @divFloor(ns_per_s, self.frequency);
166 165
167 var start_time: i64 = undefined;166 var start_time: i64 = undefined;
168 err = windows.QueryPerformanceCounter(&start_time);167 err = windows.QueryPerformanceCounter(&start_time);
169 debug.assert(err != windows.FALSE);168 debug.assert(err != windows.FALSE);
...@@ -171,9 +170,9 @@ pub const Timer = struct {...@@ -171,9 +170,9 @@ pub const Timer = struct {
171 },170 },
172 Os.linux => {171 Os.linux => {
173 //On Linux, seccomp can do arbitrary things to our ability to call172 //On Linux, seccomp can do arbitrary things to our ability to call
174 // syscalls, including return any errno value it wants and 173 // syscalls, including return any errno value it wants and
175 // inconsistently throwing errors. Since we can't account for174 // inconsistently throwing errors. Since we can't account for
176 // abuses of seccomp in a reasonable way, we'll assume that if 175 // abuses of seccomp in a reasonable way, we'll assume that if
177 // seccomp is going to block us it will at least do so consistently176 // seccomp is going to block us it will at least do so consistently
178 var ts: posix.timespec = undefined;177 var ts: posix.timespec = undefined;
179 var result = posix.clock_getres(monotonic_clock_id, &ts);178 var result = posix.clock_getres(monotonic_clock_id, &ts);
...@@ -184,7 +183,7 @@ pub const Timer = struct {...@@ -184,7 +183,7 @@ pub const Timer = struct {
184 else => return std.os.unexpectedErrorPosix(errno),183 else => return std.os.unexpectedErrorPosix(errno),
185 }184 }
186 self.resolution = u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec);185 self.resolution = u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec);
187 186
188 result = posix.clock_gettime(monotonic_clock_id, &ts);187 result = posix.clock_gettime(monotonic_clock_id, &ts);
189 errno = posix.getErrno(result);188 errno = posix.getErrno(result);
190 if (errno != 0) return std.os.unexpectedErrorPosix(errno);189 if (errno != 0) return std.os.unexpectedErrorPosix(errno);
...@@ -199,7 +198,7 @@ pub const Timer = struct {...@@ -199,7 +198,7 @@ pub const Timer = struct {
199 }198 }
200 return self;199 return self;
201 }200 }
202 201
203 /// Reads the timer value since start or the last reset in nanoseconds202 /// Reads the timer value since start or the last reset in nanoseconds
204 pub fn read(self: &Timer) u64 {203 pub fn read(self: &Timer) u64 {
205 var clock = clockNative() - self.start_time;204 var clock = clockNative() - self.start_time;
...@@ -210,13 +209,12 @@ pub const Timer = struct {...@@ -210,13 +209,12 @@ pub const Timer = struct {
210 else => @compileError("Unsupported OS"),209 else => @compileError("Unsupported OS"),
211 };210 };
212 }211 }
213 212
214 /// Resets the timer value to 0/now.213 /// Resets the timer value to 0/now.
215 pub fn reset(self: &Timer) void214 pub fn reset(self: &Timer) void {
216 {
217 self.start_time = clockNative();215 self.start_time = clockNative();
218 }216 }
219 217
220 /// Returns the current value of the timer in nanoseconds, then resets it218 /// Returns the current value of the timer in nanoseconds, then resets it
221 pub fn lap(self: &Timer) u64 {219 pub fn lap(self: &Timer) u64 {
222 var now = clockNative();220 var now = clockNative();
...@@ -224,26 +222,25 @@ pub const Timer = struct {...@@ -224,26 +222,25 @@ pub const Timer = struct {
224 self.start_time = now;222 self.start_time = now;
225 return lap_time;223 return lap_time;
226 }224 }
227 225
228
229 const clockNative = switch (builtin.os) {226 const clockNative = switch (builtin.os) {
230 Os.windows => clockWindows,227 Os.windows => clockWindows,
231 Os.linux => clockLinux,228 Os.linux => clockLinux,
232 Os.macosx, Os.ios => clockDarwin,229 Os.macosx, Os.ios => clockDarwin,
233 else => @compileError("Unsupported OS"),230 else => @compileError("Unsupported OS"),
234 };231 };
235 232
236 fn clockWindows() u64 {233 fn clockWindows() u64 {
237 var result: i64 = undefined;234 var result: i64 = undefined;
238 var err = windows.QueryPerformanceCounter(&result);235 var err = windows.QueryPerformanceCounter(&result);
239 debug.assert(err != windows.FALSE);236 debug.assert(err != windows.FALSE);
240 return u64(result);237 return u64(result);
241 }238 }
242 239
243 fn clockDarwin() u64 {240 fn clockDarwin() u64 {
244 return darwin.mach_absolute_time();241 return darwin.mach_absolute_time();
245 }242 }
246 243
247 fn clockLinux() u64 {244 fn clockLinux() u64 {
248 var ts: posix.timespec = undefined;245 var ts: posix.timespec = undefined;
249 var result = posix.clock_gettime(monotonic_clock_id, &ts);246 var result = posix.clock_gettime(monotonic_clock_id, &ts);
...@@ -252,10 +249,6 @@ pub const Timer = struct {...@@ -252,10 +249,6 @@ pub const Timer = struct {
252 }249 }
253};250};
254251
255
256
257
258
259test "os.time.sleep" {252test "os.time.sleep" {
260 sleep(0, 1);253 sleep(0, 1);
261}254}
...@@ -263,7 +256,7 @@ test "os.time.sleep" {...@@ -263,7 +256,7 @@ test "os.time.sleep" {
263test "os.time.timestamp" {256test "os.time.timestamp" {
264 const ns_per_ms = (ns_per_s / ms_per_s);257 const ns_per_ms = (ns_per_s / ms_per_s);
265 const margin = 50;258 const margin = 50;
266 259
267 const time_0 = milliTimestamp();260 const time_0 = milliTimestamp();
268 sleep(0, ns_per_ms);261 sleep(0, ns_per_ms);
269 const time_1 = milliTimestamp();262 const time_1 = milliTimestamp();
...@@ -274,15 +267,15 @@ test "os.time.timestamp" {...@@ -274,15 +267,15 @@ test "os.time.timestamp" {
274test "os.time.Timer" {267test "os.time.Timer" {
275 const ns_per_ms = (ns_per_s / ms_per_s);268 const ns_per_ms = (ns_per_s / ms_per_s);
276 const margin = ns_per_ms * 50;269 const margin = ns_per_ms * 50;
277 270
278 var timer = try Timer.start();271 var timer = try Timer.start();
279 sleep(0, 10 * ns_per_ms);272 sleep(0, 10 * ns_per_ms);
280 const time_0 = timer.read();273 const time_0 = timer.read();
281 debug.assert(time_0 > 0 and time_0 < margin);274 debug.assert(time_0 > 0 and time_0 < margin);
282 275
283 const time_1 = timer.lap();276 const time_1 = timer.lap();
284 debug.assert(time_1 >= time_0);277 debug.assert(time_1 >= time_0);
285 278
286 timer.reset();279 timer.reset();
287 debug.assert(timer.read() < time_1);280 debug.assert(timer.read() < time_1);
288}281}
std/os/windows/error.zig+1188
...@@ -1,2379 +1,3567 @@...@@ -1,2379 +1,3567 @@
1/// The operation completed successfully.1/// The operation completed successfully.
2pub const SUCCESS = 0;2pub const SUCCESS = 0;
3
3/// Incorrect function.4/// Incorrect function.
4pub const INVALID_FUNCTION = 1;5pub const INVALID_FUNCTION = 1;
6
5/// The system cannot find the file specified.7/// The system cannot find the file specified.
6pub const FILE_NOT_FOUND = 2;8pub const FILE_NOT_FOUND = 2;
9
7/// The system cannot find the path specified.10/// The system cannot find the path specified.
8pub const PATH_NOT_FOUND = 3;11pub const PATH_NOT_FOUND = 3;
12
9/// The system cannot open the file.13/// The system cannot open the file.
10pub const TOO_MANY_OPEN_FILES = 4;14pub const TOO_MANY_OPEN_FILES = 4;
15
11/// Access is denied.16/// Access is denied.
12pub const ACCESS_DENIED = 5;17pub const ACCESS_DENIED = 5;
18
13/// The handle is invalid.19/// The handle is invalid.
14pub const INVALID_HANDLE = 6;20pub const INVALID_HANDLE = 6;
21
15/// The storage control blocks were destroyed.22/// The storage control blocks were destroyed.
16pub const ARENA_TRASHED = 7;23pub const ARENA_TRASHED = 7;
24
17/// Not enough storage is available to process this command.25/// Not enough storage is available to process this command.
18pub const NOT_ENOUGH_MEMORY = 8;26pub const NOT_ENOUGH_MEMORY = 8;
27
19/// The storage control block address is invalid.28/// The storage control block address is invalid.
20pub const INVALID_BLOCK = 9;29pub const INVALID_BLOCK = 9;
30
21/// The environment is incorrect.31/// The environment is incorrect.
22pub const BAD_ENVIRONMENT = 10;32pub const BAD_ENVIRONMENT = 10;
33
23/// An attempt was made to load a program with an incorrect format.34/// An attempt was made to load a program with an incorrect format.
24pub const BAD_FORMAT = 11;35pub const BAD_FORMAT = 11;
36
25/// The access code is invalid.37/// The access code is invalid.
26pub const INVALID_ACCESS = 12;38pub const INVALID_ACCESS = 12;
39
27/// The data is invalid.40/// The data is invalid.
28pub const INVALID_DATA = 13;41pub const INVALID_DATA = 13;
42
29/// Not enough storage is available to complete this operation.43/// Not enough storage is available to complete this operation.
30pub const OUTOFMEMORY = 14;44pub const OUTOFMEMORY = 14;
45
31/// The system cannot find the drive specified.46/// The system cannot find the drive specified.
32pub const INVALID_DRIVE = 15;47pub const INVALID_DRIVE = 15;
48
33/// The directory cannot be removed.49/// The directory cannot be removed.
34pub const CURRENT_DIRECTORY = 16;50pub const CURRENT_DIRECTORY = 16;
51
35/// The system cannot move the file to a different disk drive.52/// The system cannot move the file to a different disk drive.
36pub const NOT_SAME_DEVICE = 17;53pub const NOT_SAME_DEVICE = 17;
54
37/// There are no more files.55/// There are no more files.
38pub const NO_MORE_FILES = 18;56pub const NO_MORE_FILES = 18;
57
39/// The media is write protected.58/// The media is write protected.
40pub const WRITE_PROTECT = 19;59pub const WRITE_PROTECT = 19;
60
41/// The system cannot find the device specified.61/// The system cannot find the device specified.
42pub const BAD_UNIT = 20;62pub const BAD_UNIT = 20;
63
43/// The device is not ready.64/// The device is not ready.
44pub const NOT_READY = 21;65pub const NOT_READY = 21;
66
45/// The device does not recognize the command.67/// The device does not recognize the command.
46pub const BAD_COMMAND = 22;68pub const BAD_COMMAND = 22;
69
47/// Data error (cyclic redundancy check).70/// Data error (cyclic redundancy check).
48pub const CRC = 23;71pub const CRC = 23;
72
49/// The program issued a command but the command length is incorrect.73/// The program issued a command but the command length is incorrect.
50pub const BAD_LENGTH = 24;74pub const BAD_LENGTH = 24;
75
51/// The drive cannot locate a specific area or track on the disk.76/// The drive cannot locate a specific area or track on the disk.
52pub const SEEK = 25;77pub const SEEK = 25;
78
53/// The specified disk or diskette cannot be accessed.79/// The specified disk or diskette cannot be accessed.
54pub const NOT_DOS_DISK = 26;80pub const NOT_DOS_DISK = 26;
81
55/// The drive cannot find the sector requested.82/// The drive cannot find the sector requested.
56pub const SECTOR_NOT_FOUND = 27;83pub const SECTOR_NOT_FOUND = 27;
84
57/// The printer is out of paper.85/// The printer is out of paper.
58pub const OUT_OF_PAPER = 28;86pub const OUT_OF_PAPER = 28;
87
59/// The system cannot write to the specified device.88/// The system cannot write to the specified device.
60pub const WRITE_FAULT = 29;89pub const WRITE_FAULT = 29;
90
61/// The system cannot read from the specified device.91/// The system cannot read from the specified device.
62pub const READ_FAULT = 30;92pub const READ_FAULT = 30;
93
63/// A device attached to the system is not functioning.94/// A device attached to the system is not functioning.
64pub const GEN_FAILURE = 31;95pub const GEN_FAILURE = 31;
96
65/// The process cannot access the file because it is being used by another process.97/// The process cannot access the file because it is being used by another process.
66pub const SHARING_VIOLATION = 32;98pub const SHARING_VIOLATION = 32;
99
67/// The process cannot access the file because another process has locked a portion of the file.100/// The process cannot access the file because another process has locked a portion of the file.
68pub const LOCK_VIOLATION = 33;101pub const LOCK_VIOLATION = 33;
102
69/// The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1.103/// The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1.
70pub const WRONG_DISK = 34;104pub const WRONG_DISK = 34;
105
71/// Too many files opened for sharing.106/// Too many files opened for sharing.
72pub const SHARING_BUFFER_EXCEEDED = 36;107pub const SHARING_BUFFER_EXCEEDED = 36;
108
73/// Reached the end of the file.109/// Reached the end of the file.
74pub const HANDLE_EOF = 38;110pub const HANDLE_EOF = 38;
111
75/// The disk is full.112/// The disk is full.
76pub const HANDLE_DISK_FULL = 39;113pub const HANDLE_DISK_FULL = 39;
114
77/// The request is not supported.115/// The request is not supported.
78pub const NOT_SUPPORTED = 50;116pub const NOT_SUPPORTED = 50;
117
79/// Windows cannot find the network path. Verify that the network path is correct and the destination computer is not busy or turned off. If Windows still cannot find the network path, contact your network administrator.118/// Windows cannot find the network path. Verify that the network path is correct and the destination computer is not busy or turned off. If Windows still cannot find the network path, contact your network administrator.
80pub const REM_NOT_LIST = 51;119pub const REM_NOT_LIST = 51;
120
81/// You were not connected because a duplicate name exists on the network. If joining a domain, go to System in Control Panel to change the computer name and try again. If joining a workgroup, choose another workgroup name.121/// You were not connected because a duplicate name exists on the network. If joining a domain, go to System in Control Panel to change the computer name and try again. If joining a workgroup, choose another workgroup name.
82pub const DUP_NAME = 52;122pub const DUP_NAME = 52;
123
83/// The network path was not found.124/// The network path was not found.
84pub const BAD_NETPATH = 53;125pub const BAD_NETPATH = 53;
126
85/// The network is busy.127/// The network is busy.
86pub const NETWORK_BUSY = 54;128pub const NETWORK_BUSY = 54;
129
87/// The specified network resource or device is no longer available.130/// The specified network resource or device is no longer available.
88pub const DEV_NOT_EXIST = 55;131pub const DEV_NOT_EXIST = 55;
132
89/// The network BIOS command limit has been reached.133/// The network BIOS command limit has been reached.
90pub const TOO_MANY_CMDS = 56;134pub const TOO_MANY_CMDS = 56;
135
91/// A network adapter hardware error occurred.136/// A network adapter hardware error occurred.
92pub const ADAP_HDW_ERR = 57;137pub const ADAP_HDW_ERR = 57;
138
93/// The specified server cannot perform the requested operation.139/// The specified server cannot perform the requested operation.
94pub const BAD_NET_RESP = 58;140pub const BAD_NET_RESP = 58;
141
95/// An unexpected network error occurred.142/// An unexpected network error occurred.
96pub const UNEXP_NET_ERR = 59;143pub const UNEXP_NET_ERR = 59;
144
97/// The remote adapter is not compatible.145/// The remote adapter is not compatible.
98pub const BAD_REM_ADAP = 60;146pub const BAD_REM_ADAP = 60;
147
99/// The printer queue is full.148/// The printer queue is full.
100pub const PRINTQ_FULL = 61;149pub const PRINTQ_FULL = 61;
150
101/// Space to store the file waiting to be printed is not available on the server.151/// Space to store the file waiting to be printed is not available on the server.
102pub const NO_SPOOL_SPACE = 62;152pub const NO_SPOOL_SPACE = 62;
153
103/// Your file waiting to be printed was deleted.154/// Your file waiting to be printed was deleted.
104pub const PRINT_CANCELLED = 63;155pub const PRINT_CANCELLED = 63;
156
105/// The specified network name is no longer available.157/// The specified network name is no longer available.
106pub const NETNAME_DELETED = 64;158pub const NETNAME_DELETED = 64;
159
107/// Network access is denied.160/// Network access is denied.
108pub const NETWORK_ACCESS_DENIED = 65;161pub const NETWORK_ACCESS_DENIED = 65;
162
109/// The network resource type is not correct.163/// The network resource type is not correct.
110pub const BAD_DEV_TYPE = 66;164pub const BAD_DEV_TYPE = 66;
165
111/// The network name cannot be found.166/// The network name cannot be found.
112pub const BAD_NET_NAME = 67;167pub const BAD_NET_NAME = 67;
168
113/// The name limit for the local computer network adapter card was exceeded.169/// The name limit for the local computer network adapter card was exceeded.
114pub const TOO_MANY_NAMES = 68;170pub const TOO_MANY_NAMES = 68;
171
115/// The network BIOS session limit was exceeded.172/// The network BIOS session limit was exceeded.
116pub const TOO_MANY_SESS = 69;173pub const TOO_MANY_SESS = 69;
174
117/// The remote server has been paused or is in the process of being started.175/// The remote server has been paused or is in the process of being started.
118pub const SHARING_PAUSED = 70;176pub const SHARING_PAUSED = 70;
177
119/// No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept.178/// No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept.
120pub const REQ_NOT_ACCEP = 71;179pub const REQ_NOT_ACCEP = 71;
180
121/// The specified printer or disk device has been paused.181/// The specified printer or disk device has been paused.
122pub const REDIR_PAUSED = 72;182pub const REDIR_PAUSED = 72;
183
123/// The file exists.184/// The file exists.
124pub const FILE_EXISTS = 80;185pub const FILE_EXISTS = 80;
186
125/// The directory or file cannot be created.187/// The directory or file cannot be created.
126pub const CANNOT_MAKE = 82;188pub const CANNOT_MAKE = 82;
189
127/// Fail on INT 24.190/// Fail on INT 24.
128pub const FAIL_I24 = 83;191pub const FAIL_I24 = 83;
192
129/// Storage to process this request is not available.193/// Storage to process this request is not available.
130pub const OUT_OF_STRUCTURES = 84;194pub const OUT_OF_STRUCTURES = 84;
195
131/// The local device name is already in use.196/// The local device name is already in use.
132pub const ALREADY_ASSIGNED = 85;197pub const ALREADY_ASSIGNED = 85;
198
133/// The specified network password is not correct.199/// The specified network password is not correct.
134pub const INVALID_PASSWORD = 86;200pub const INVALID_PASSWORD = 86;
201
135/// The parameter is incorrect.202/// The parameter is incorrect.
136pub const INVALID_PARAMETER = 87;203pub const INVALID_PARAMETER = 87;
204
137/// A write fault occurred on the network.205/// A write fault occurred on the network.
138pub const NET_WRITE_FAULT = 88;206pub const NET_WRITE_FAULT = 88;
207
139/// The system cannot start another process at this time.208/// The system cannot start another process at this time.
140pub const NO_PROC_SLOTS = 89;209pub const NO_PROC_SLOTS = 89;
210
141/// Cannot create another system semaphore.211/// Cannot create another system semaphore.
142pub const TOO_MANY_SEMAPHORES = 100;212pub const TOO_MANY_SEMAPHORES = 100;
213
143/// The exclusive semaphore is owned by another process.214/// The exclusive semaphore is owned by another process.
144pub const EXCL_SEM_ALREADY_OWNED = 101;215pub const EXCL_SEM_ALREADY_OWNED = 101;
216
145/// The semaphore is set and cannot be closed.217/// The semaphore is set and cannot be closed.
146pub const SEM_IS_SET = 102;218pub const SEM_IS_SET = 102;
219
147/// The semaphore cannot be set again.220/// The semaphore cannot be set again.
148pub const TOO_MANY_SEM_REQUESTS = 103;221pub const TOO_MANY_SEM_REQUESTS = 103;
222
149/// Cannot request exclusive semaphores at interrupt time.223/// Cannot request exclusive semaphores at interrupt time.
150pub const INVALID_AT_INTERRUPT_TIME = 104;224pub const INVALID_AT_INTERRUPT_TIME = 104;
225
151/// The previous ownership of this semaphore has ended.226/// The previous ownership of this semaphore has ended.
152pub const SEM_OWNER_DIED = 105;227pub const SEM_OWNER_DIED = 105;
228
153/// Insert the diskette for drive %1.229/// Insert the diskette for drive %1.
154pub const SEM_USER_LIMIT = 106;230pub const SEM_USER_LIMIT = 106;
231
155/// The program stopped because an alternate diskette was not inserted.232/// The program stopped because an alternate diskette was not inserted.
156pub const DISK_CHANGE = 107;233pub const DISK_CHANGE = 107;
234
157/// The disk is in use or locked by another process.235/// The disk is in use or locked by another process.
158pub const DRIVE_LOCKED = 108;236pub const DRIVE_LOCKED = 108;
237
159/// The pipe has been ended.238/// The pipe has been ended.
160pub const BROKEN_PIPE = 109;239pub const BROKEN_PIPE = 109;
240
161/// The system cannot open the device or file specified.241/// The system cannot open the device or file specified.
162pub const OPEN_FAILED = 110;242pub const OPEN_FAILED = 110;
243
163/// The file name is too long.244/// The file name is too long.
164pub const BUFFER_OVERFLOW = 111;245pub const BUFFER_OVERFLOW = 111;
246
165/// There is not enough space on the disk.247/// There is not enough space on the disk.
166pub const DISK_FULL = 112;248pub const DISK_FULL = 112;
249
167/// No more internal file identifiers available.250/// No more internal file identifiers available.
168pub const NO_MORE_SEARCH_HANDLES = 113;251pub const NO_MORE_SEARCH_HANDLES = 113;
252
169/// The target internal file identifier is incorrect.253/// The target internal file identifier is incorrect.
170pub const INVALID_TARGET_HANDLE = 114;254pub const INVALID_TARGET_HANDLE = 114;
255
171/// The IOCTL call made by the application program is not correct.256/// The IOCTL call made by the application program is not correct.
172pub const INVALID_CATEGORY = 117;257pub const INVALID_CATEGORY = 117;
258
173/// The verify-on-write switch parameter value is not correct.259/// The verify-on-write switch parameter value is not correct.
174pub const INVALID_VERIFY_SWITCH = 118;260pub const INVALID_VERIFY_SWITCH = 118;
261
175/// The system does not support the command requested.262/// The system does not support the command requested.
176pub const BAD_DRIVER_LEVEL = 119;263pub const BAD_DRIVER_LEVEL = 119;
264
177/// This function is not supported on this system.265/// This function is not supported on this system.
178pub const CALL_NOT_IMPLEMENTED = 120;266pub const CALL_NOT_IMPLEMENTED = 120;
267
179/// The semaphore timeout period has expired.268/// The semaphore timeout period has expired.
180pub const SEM_TIMEOUT = 121;269pub const SEM_TIMEOUT = 121;
270
181/// The data area passed to a system call is too small.271/// The data area passed to a system call is too small.
182pub const INSUFFICIENT_BUFFER = 122;272pub const INSUFFICIENT_BUFFER = 122;
273
183/// The filename, directory name, or volume label syntax is incorrect.274/// The filename, directory name, or volume label syntax is incorrect.
184pub const INVALID_NAME = 123;275pub const INVALID_NAME = 123;
276
185/// The system call level is not correct.277/// The system call level is not correct.
186pub const INVALID_LEVEL = 124;278pub const INVALID_LEVEL = 124;
279
187/// The disk has no volume label.280/// The disk has no volume label.
188pub const NO_VOLUME_LABEL = 125;281pub const NO_VOLUME_LABEL = 125;
282
189/// The specified module could not be found.283/// The specified module could not be found.
190pub const MOD_NOT_FOUND = 126;284pub const MOD_NOT_FOUND = 126;
285
191/// The specified procedure could not be found.286/// The specified procedure could not be found.
192pub const PROC_NOT_FOUND = 127;287pub const PROC_NOT_FOUND = 127;
288
193/// There are no child processes to wait for.289/// There are no child processes to wait for.
194pub const WAIT_NO_CHILDREN = 128;290pub const WAIT_NO_CHILDREN = 128;
291
195/// The %1 application cannot be run in Win32 mode.292/// The %1 application cannot be run in Win32 mode.
196pub const CHILD_NOT_COMPLETE = 129;293pub const CHILD_NOT_COMPLETE = 129;
294
197/// Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O.295/// Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O.
198pub const DIRECT_ACCESS_HANDLE = 130;296pub const DIRECT_ACCESS_HANDLE = 130;
297
199/// An attempt was made to move the file pointer before the beginning of the file.298/// An attempt was made to move the file pointer before the beginning of the file.
200pub const NEGATIVE_SEEK = 131;299pub const NEGATIVE_SEEK = 131;
300
201/// The file pointer cannot be set on the specified device or file.301/// The file pointer cannot be set on the specified device or file.
202pub const SEEK_ON_DEVICE = 132;302pub const SEEK_ON_DEVICE = 132;
303
203/// A JOIN or SUBST command cannot be used for a drive that contains previously joined drives.304/// A JOIN or SUBST command cannot be used for a drive that contains previously joined drives.
204pub const IS_JOIN_TARGET = 133;305pub const IS_JOIN_TARGET = 133;
306
205/// An attempt was made to use a JOIN or SUBST command on a drive that has already been joined.307/// An attempt was made to use a JOIN or SUBST command on a drive that has already been joined.
206pub const IS_JOINED = 134;308pub const IS_JOINED = 134;
309
207/// An attempt was made to use a JOIN or SUBST command on a drive that has already been substituted.310/// An attempt was made to use a JOIN or SUBST command on a drive that has already been substituted.
208pub const IS_SUBSTED = 135;311pub const IS_SUBSTED = 135;
312
209/// The system tried to delete the JOIN of a drive that is not joined.313/// The system tried to delete the JOIN of a drive that is not joined.
210pub const NOT_JOINED = 136;314pub const NOT_JOINED = 136;
315
211/// The system tried to delete the substitution of a drive that is not substituted.316/// The system tried to delete the substitution of a drive that is not substituted.
212pub const NOT_SUBSTED = 137;317pub const NOT_SUBSTED = 137;
318
213/// The system tried to join a drive to a directory on a joined drive.319/// The system tried to join a drive to a directory on a joined drive.
214pub const JOIN_TO_JOIN = 138;320pub const JOIN_TO_JOIN = 138;
321
215/// The system tried to substitute a drive to a directory on a substituted drive.322/// The system tried to substitute a drive to a directory on a substituted drive.
216pub const SUBST_TO_SUBST = 139;323pub const SUBST_TO_SUBST = 139;
324
217/// The system tried to join a drive to a directory on a substituted drive.325/// The system tried to join a drive to a directory on a substituted drive.
218pub const JOIN_TO_SUBST = 140;326pub const JOIN_TO_SUBST = 140;
327
219/// The system tried to SUBST a drive to a directory on a joined drive.328/// The system tried to SUBST a drive to a directory on a joined drive.
220pub const SUBST_TO_JOIN = 141;329pub const SUBST_TO_JOIN = 141;
330
221/// The system cannot perform a JOIN or SUBST at this time.331/// The system cannot perform a JOIN or SUBST at this time.
222pub const BUSY_DRIVE = 142;332pub const BUSY_DRIVE = 142;
333
223/// The system cannot join or substitute a drive to or for a directory on the same drive.334/// The system cannot join or substitute a drive to or for a directory on the same drive.
224pub const SAME_DRIVE = 143;335pub const SAME_DRIVE = 143;
336
225/// The directory is not a subdirectory of the root directory.337/// The directory is not a subdirectory of the root directory.
226pub const DIR_NOT_ROOT = 144;338pub const DIR_NOT_ROOT = 144;
339
227/// The directory is not empty.340/// The directory is not empty.
228pub const DIR_NOT_EMPTY = 145;341pub const DIR_NOT_EMPTY = 145;
342
229/// The path specified is being used in a substitute.343/// The path specified is being used in a substitute.
230pub const IS_SUBST_PATH = 146;344pub const IS_SUBST_PATH = 146;
345
231/// Not enough resources are available to process this command.346/// Not enough resources are available to process this command.
232pub const IS_JOIN_PATH = 147;347pub const IS_JOIN_PATH = 147;
348
233/// The path specified cannot be used at this time.349/// The path specified cannot be used at this time.
234pub const PATH_BUSY = 148;350pub const PATH_BUSY = 148;
351
235/// An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute.352/// An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute.
236pub const IS_SUBST_TARGET = 149;353pub const IS_SUBST_TARGET = 149;
354
237/// System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed.355/// System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed.
238pub const SYSTEM_TRACE = 150;356pub const SYSTEM_TRACE = 150;
357
239/// The number of specified semaphore events for DosMuxSemWait is not correct.358/// The number of specified semaphore events for DosMuxSemWait is not correct.
240pub const INVALID_EVENT_COUNT = 151;359pub const INVALID_EVENT_COUNT = 151;
360
241/// DosMuxSemWait did not execute; too many semaphores are already set.361/// DosMuxSemWait did not execute; too many semaphores are already set.
242pub const TOO_MANY_MUXWAITERS = 152;362pub const TOO_MANY_MUXWAITERS = 152;
363
243/// The DosMuxSemWait list is not correct.364/// The DosMuxSemWait list is not correct.
244pub const INVALID_LIST_FORMAT = 153;365pub const INVALID_LIST_FORMAT = 153;
366
245/// The volume label you entered exceeds the label character limit of the target file system.367/// The volume label you entered exceeds the label character limit of the target file system.
246pub const LABEL_TOO_LONG = 154;368pub const LABEL_TOO_LONG = 154;
369
247/// Cannot create another thread.370/// Cannot create another thread.
248pub const TOO_MANY_TCBS = 155;371pub const TOO_MANY_TCBS = 155;
372
249/// The recipient process has refused the signal.373/// The recipient process has refused the signal.
250pub const SIGNAL_REFUSED = 156;374pub const SIGNAL_REFUSED = 156;
375
251/// The segment is already discarded and cannot be locked.376/// The segment is already discarded and cannot be locked.
252pub const DISCARDED = 157;377pub const DISCARDED = 157;
378
253/// The segment is already unlocked.379/// The segment is already unlocked.
254pub const NOT_LOCKED = 158;380pub const NOT_LOCKED = 158;
381
255/// The address for the thread ID is not correct.382/// The address for the thread ID is not correct.
256pub const BAD_THREADID_ADDR = 159;383pub const BAD_THREADID_ADDR = 159;
384
257/// One or more arguments are not correct.385/// One or more arguments are not correct.
258pub const BAD_ARGUMENTS = 160;386pub const BAD_ARGUMENTS = 160;
387
259/// The specified path is invalid.388/// The specified path is invalid.
260pub const BAD_PATHNAME = 161;389pub const BAD_PATHNAME = 161;
390
261/// A signal is already pending.391/// A signal is already pending.
262pub const SIGNAL_PENDING = 162;392pub const SIGNAL_PENDING = 162;
393
263/// No more threads can be created in the system.394/// No more threads can be created in the system.
264pub const MAX_THRDS_REACHED = 164;395pub const MAX_THRDS_REACHED = 164;
396
265/// Unable to lock a region of a file.397/// Unable to lock a region of a file.
266pub const LOCK_FAILED = 167;398pub const LOCK_FAILED = 167;
399
267/// The requested resource is in use.400/// The requested resource is in use.
268pub const BUSY = 170;401pub const BUSY = 170;
402
269/// Device's command support detection is in progress.403/// Device's command support detection is in progress.
270pub const DEVICE_SUPPORT_IN_PROGRESS = 171;404pub const DEVICE_SUPPORT_IN_PROGRESS = 171;
405
271/// A lock request was not outstanding for the supplied cancel region.406/// A lock request was not outstanding for the supplied cancel region.
272pub const CANCEL_VIOLATION = 173;407pub const CANCEL_VIOLATION = 173;
408
273/// The file system does not support atomic changes to the lock type.409/// The file system does not support atomic changes to the lock type.
274pub const ATOMIC_LOCKS_NOT_SUPPORTED = 174;410pub const ATOMIC_LOCKS_NOT_SUPPORTED = 174;
411
275/// The system detected a segment number that was not correct.412/// The system detected a segment number that was not correct.
276pub const INVALID_SEGMENT_NUMBER = 180;413pub const INVALID_SEGMENT_NUMBER = 180;
414
277/// The operating system cannot run %1.415/// The operating system cannot run %1.
278pub const INVALID_ORDINAL = 182;416pub const INVALID_ORDINAL = 182;
417
279/// Cannot create a file when that file already exists.418/// Cannot create a file when that file already exists.
280pub const ALREADY_EXISTS = 183;419pub const ALREADY_EXISTS = 183;
420
281/// The flag passed is not correct.421/// The flag passed is not correct.
282pub const INVALID_FLAG_NUMBER = 186;422pub const INVALID_FLAG_NUMBER = 186;
423
283/// The specified system semaphore name was not found.424/// The specified system semaphore name was not found.
284pub const SEM_NOT_FOUND = 187;425pub const SEM_NOT_FOUND = 187;
426
285/// The operating system cannot run %1.427/// The operating system cannot run %1.
286pub const INVALID_STARTING_CODESEG = 188;428pub const INVALID_STARTING_CODESEG = 188;
429
287/// The operating system cannot run %1.430/// The operating system cannot run %1.
288pub const INVALID_STACKSEG = 189;431pub const INVALID_STACKSEG = 189;
432
289/// The operating system cannot run %1.433/// The operating system cannot run %1.
290pub const INVALID_MODULETYPE = 190;434pub const INVALID_MODULETYPE = 190;
435
291/// Cannot run %1 in Win32 mode.436/// Cannot run %1 in Win32 mode.
292pub const INVALID_EXE_SIGNATURE = 191;437pub const INVALID_EXE_SIGNATURE = 191;
438
293/// The operating system cannot run %1.439/// The operating system cannot run %1.
294pub const EXE_MARKED_INVALID = 192;440pub const EXE_MARKED_INVALID = 192;
441
295/// %1 is not a valid Win32 application.442/// %1 is not a valid Win32 application.
296pub const BAD_EXE_FORMAT = 193;443pub const BAD_EXE_FORMAT = 193;
444
297/// The operating system cannot run %1.445/// The operating system cannot run %1.
298pub const ITERATED_DATA_EXCEEDS_64k = 194;446pub const ITERATED_DATA_EXCEEDS_64k = 194;
447
299/// The operating system cannot run %1.448/// The operating system cannot run %1.
300pub const INVALID_MINALLOCSIZE = 195;449pub const INVALID_MINALLOCSIZE = 195;
450
301/// The operating system cannot run this application program.451/// The operating system cannot run this application program.
302pub const DYNLINK_FROM_INVALID_RING = 196;452pub const DYNLINK_FROM_INVALID_RING = 196;
453
303/// The operating system is not presently configured to run this application.454/// The operating system is not presently configured to run this application.
304pub const IOPL_NOT_ENABLED = 197;455pub const IOPL_NOT_ENABLED = 197;
456
305/// The operating system cannot run %1.457/// The operating system cannot run %1.
306pub const INVALID_SEGDPL = 198;458pub const INVALID_SEGDPL = 198;
459
307/// The operating system cannot run this application program.460/// The operating system cannot run this application program.
308pub const AUTODATASEG_EXCEEDS_64k = 199;461pub const AUTODATASEG_EXCEEDS_64k = 199;
462
309/// The code segment cannot be greater than or equal to 64K.463/// The code segment cannot be greater than or equal to 64K.
310pub const RING2SEG_MUST_BE_MOVABLE = 200;464pub const RING2SEG_MUST_BE_MOVABLE = 200;
465
311/// The operating system cannot run %1.466/// The operating system cannot run %1.
312pub const RELOC_CHAIN_XEEDS_SEGLIM = 201;467pub const RELOC_CHAIN_XEEDS_SEGLIM = 201;
468
313/// The operating system cannot run %1.469/// The operating system cannot run %1.
314pub const INFLOOP_IN_RELOC_CHAIN = 202;470pub const INFLOOP_IN_RELOC_CHAIN = 202;
471
315/// The system could not find the environment option that was entered.472/// The system could not find the environment option that was entered.
316pub const ENVVAR_NOT_FOUND = 203;473pub const ENVVAR_NOT_FOUND = 203;
474
317/// No process in the command subtree has a signal handler.475/// No process in the command subtree has a signal handler.
318pub const NO_SIGNAL_SENT = 205;476pub const NO_SIGNAL_SENT = 205;
477
319/// The filename or extension is too long.478/// The filename or extension is too long.
320pub const FILENAME_EXCED_RANGE = 206;479pub const FILENAME_EXCED_RANGE = 206;
480
321/// The ring 2 stack is in use.481/// The ring 2 stack is in use.
322pub const RING2_STACK_IN_USE = 207;482pub const RING2_STACK_IN_USE = 207;
483
323/// The global filename characters, * or ?, are entered incorrectly or too many global filename characters are specified.484/// The global filename characters, * or ?, are entered incorrectly or too many global filename characters are specified.
324pub const META_EXPANSION_TOO_LONG = 208;485pub const META_EXPANSION_TOO_LONG = 208;
486
325/// The signal being posted is not correct.487/// The signal being posted is not correct.
326pub const INVALID_SIGNAL_NUMBER = 209;488pub const INVALID_SIGNAL_NUMBER = 209;
489
327/// The signal handler cannot be set.490/// The signal handler cannot be set.
328pub const THREAD_1_INACTIVE = 210;491pub const THREAD_1_INACTIVE = 210;
492
329/// The segment is locked and cannot be reallocated.493/// The segment is locked and cannot be reallocated.
330pub const LOCKED = 212;494pub const LOCKED = 212;
495
331/// Too many dynamic-link modules are attached to this program or dynamic-link module.496/// Too many dynamic-link modules are attached to this program or dynamic-link module.
332pub const TOO_MANY_MODULES = 214;497pub const TOO_MANY_MODULES = 214;
498
333/// Cannot nest calls to LoadModule.499/// Cannot nest calls to LoadModule.
334pub const NESTING_NOT_ALLOWED = 215;500pub const NESTING_NOT_ALLOWED = 215;
501
335/// This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.502/// This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.
336pub const EXE_MACHINE_TYPE_MISMATCH = 216;503pub const EXE_MACHINE_TYPE_MISMATCH = 216;
504
337/// The image file %1 is signed, unable to modify.505/// The image file %1 is signed, unable to modify.
338pub const EXE_CANNOT_MODIFY_SIGNED_BINARY = 217;506pub const EXE_CANNOT_MODIFY_SIGNED_BINARY = 217;
507
339/// The image file %1 is strong signed, unable to modify.508/// The image file %1 is strong signed, unable to modify.
340pub const EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY = 218;509pub const EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY = 218;
510
341/// This file is checked out or locked for editing by another user.511/// This file is checked out or locked for editing by another user.
342pub const FILE_CHECKED_OUT = 220;512pub const FILE_CHECKED_OUT = 220;
513
343/// The file must be checked out before saving changes.514/// The file must be checked out before saving changes.
344pub const CHECKOUT_REQUIRED = 221;515pub const CHECKOUT_REQUIRED = 221;
516
345/// The file type being saved or retrieved has been blocked.517/// The file type being saved or retrieved has been blocked.
346pub const BAD_FILE_TYPE = 222;518pub const BAD_FILE_TYPE = 222;
519
347/// The file size exceeds the limit allowed and cannot be saved.520/// The file size exceeds the limit allowed and cannot be saved.
348pub const FILE_TOO_LARGE = 223;521pub const FILE_TOO_LARGE = 223;
522
349/// Access Denied. Before opening files in this location, you must first add the web site to your trusted sites list, browse to the web site, and select the option to login automatically.523/// Access Denied. Before opening files in this location, you must first add the web site to your trusted sites list, browse to the web site, and select the option to login automatically.
350pub const FORMS_AUTH_REQUIRED = 224;524pub const FORMS_AUTH_REQUIRED = 224;
525
351/// Operation did not complete successfully because the file contains a virus or potentially unwanted software.526/// Operation did not complete successfully because the file contains a virus or potentially unwanted software.
352pub const VIRUS_INFECTED = 225;527pub const VIRUS_INFECTED = 225;
528
353/// This file contains a virus or potentially unwanted software and cannot be opened. Due to the nature of this virus or potentially unwanted software, the file has been removed from this location.529/// This file contains a virus or potentially unwanted software and cannot be opened. Due to the nature of this virus or potentially unwanted software, the file has been removed from this location.
354pub const VIRUS_DELETED = 226;530pub const VIRUS_DELETED = 226;
531
355/// The pipe is local.532/// The pipe is local.
356pub const PIPE_LOCAL = 229;533pub const PIPE_LOCAL = 229;
534
357/// The pipe state is invalid.535/// The pipe state is invalid.
358pub const BAD_PIPE = 230;536pub const BAD_PIPE = 230;
537
359/// All pipe instances are busy.538/// All pipe instances are busy.
360pub const PIPE_BUSY = 231;539pub const PIPE_BUSY = 231;
540
361/// The pipe is being closed.541/// The pipe is being closed.
362pub const NO_DATA = 232;542pub const NO_DATA = 232;
543
363/// No process is on the other end of the pipe.544/// No process is on the other end of the pipe.
364pub const PIPE_NOT_CONNECTED = 233;545pub const PIPE_NOT_CONNECTED = 233;
546
365/// More data is available.547/// More data is available.
366pub const MORE_DATA = 234;548pub const MORE_DATA = 234;
549
367/// The session was canceled.550/// The session was canceled.
368pub const VC_DISCONNECTED = 240;551pub const VC_DISCONNECTED = 240;
552
369/// The specified extended attribute name was invalid.553/// The specified extended attribute name was invalid.
370pub const INVALID_EA_NAME = 254;554pub const INVALID_EA_NAME = 254;
555
371/// The extended attributes are inconsistent.556/// The extended attributes are inconsistent.
372pub const EA_LIST_INCONSISTENT = 255;557pub const EA_LIST_INCONSISTENT = 255;
558
373/// The wait operation timed out.559/// The wait operation timed out.
374pub const IMEOUT = 258;560pub const IMEOUT = 258;
561
375/// No more data is available.562/// No more data is available.
376pub const NO_MORE_ITEMS = 259;563pub const NO_MORE_ITEMS = 259;
564
377/// The copy functions cannot be used.565/// The copy functions cannot be used.
378pub const CANNOT_COPY = 266;566pub const CANNOT_COPY = 266;
567
379/// The directory name is invalid.568/// The directory name is invalid.
380pub const DIRECTORY = 267;569pub const DIRECTORY = 267;
570
381/// The extended attributes did not fit in the buffer.571/// The extended attributes did not fit in the buffer.
382pub const EAS_DIDNT_FIT = 275;572pub const EAS_DIDNT_FIT = 275;
573
383/// The extended attribute file on the mounted file system is corrupt.574/// The extended attribute file on the mounted file system is corrupt.
384pub const EA_FILE_CORRUPT = 276;575pub const EA_FILE_CORRUPT = 276;
576
385/// The extended attribute table file is full.577/// The extended attribute table file is full.
386pub const EA_TABLE_FULL = 277;578pub const EA_TABLE_FULL = 277;
579
387/// The specified extended attribute handle is invalid.580/// The specified extended attribute handle is invalid.
388pub const INVALID_EA_HANDLE = 278;581pub const INVALID_EA_HANDLE = 278;
582
389/// The mounted file system does not support extended attributes.583/// The mounted file system does not support extended attributes.
390pub const EAS_NOT_SUPPORTED = 282;584pub const EAS_NOT_SUPPORTED = 282;
585
391/// Attempt to release mutex not owned by caller.586/// Attempt to release mutex not owned by caller.
392pub const NOT_OWNER = 288;587pub const NOT_OWNER = 288;
588
393/// Too many posts were made to a semaphore.589/// Too many posts were made to a semaphore.
394pub const TOO_MANY_POSTS = 298;590pub const TOO_MANY_POSTS = 298;
591
395/// Only part of a ReadProcessMemory or WriteProcessMemory request was completed.592/// Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
396pub const PARTIAL_COPY = 299;593pub const PARTIAL_COPY = 299;
594
397/// The oplock request is denied.595/// The oplock request is denied.
398pub const OPLOCK_NOT_GRANTED = 300;596pub const OPLOCK_NOT_GRANTED = 300;
597
399/// An invalid oplock acknowledgment was received by the system.598/// An invalid oplock acknowledgment was received by the system.
400pub const INVALID_OPLOCK_PROTOCOL = 301;599pub const INVALID_OPLOCK_PROTOCOL = 301;
600
401/// The volume is too fragmented to complete this operation.601/// The volume is too fragmented to complete this operation.
402pub const DISK_TOO_FRAGMENTED = 302;602pub const DISK_TOO_FRAGMENTED = 302;
603
403/// The file cannot be opened because it is in the process of being deleted.604/// The file cannot be opened because it is in the process of being deleted.
404pub const DELETE_PENDING = 303;605pub const DELETE_PENDING = 303;
606
405/// Short name settings may not be changed on this volume due to the global registry setting.607/// Short name settings may not be changed on this volume due to the global registry setting.
406pub const INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING = 304;608pub const INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING = 304;
609
407/// Short names are not enabled on this volume.610/// Short names are not enabled on this volume.
408pub const SHORT_NAMES_NOT_ENABLED_ON_VOLUME = 305;611pub const SHORT_NAMES_NOT_ENABLED_ON_VOLUME = 305;
612
409/// The security stream for the given volume is in an inconsistent state. Please run CHKDSK on the volume.613/// The security stream for the given volume is in an inconsistent state. Please run CHKDSK on the volume.
410pub const SECURITY_STREAM_IS_INCONSISTENT = 306;614pub const SECURITY_STREAM_IS_INCONSISTENT = 306;
615
411/// A requested file lock operation cannot be processed due to an invalid byte range.616/// A requested file lock operation cannot be processed due to an invalid byte range.
412pub const INVALID_LOCK_RANGE = 307;617pub const INVALID_LOCK_RANGE = 307;
618
413/// The subsystem needed to support the image type is not present.619/// The subsystem needed to support the image type is not present.
414pub const IMAGE_SUBSYSTEM_NOT_PRESENT = 308;620pub const IMAGE_SUBSYSTEM_NOT_PRESENT = 308;
621
415/// The specified file already has a notification GUID associated with it.622/// The specified file already has a notification GUID associated with it.
416pub const NOTIFICATION_GUID_ALREADY_DEFINED = 309;623pub const NOTIFICATION_GUID_ALREADY_DEFINED = 309;
624
417/// An invalid exception handler routine has been detected.625/// An invalid exception handler routine has been detected.
418pub const INVALID_EXCEPTION_HANDLER = 310;626pub const INVALID_EXCEPTION_HANDLER = 310;
627
419/// Duplicate privileges were specified for the token.628/// Duplicate privileges were specified for the token.
420pub const DUPLICATE_PRIVILEGES = 311;629pub const DUPLICATE_PRIVILEGES = 311;
630
421/// No ranges for the specified operation were able to be processed.631/// No ranges for the specified operation were able to be processed.
422pub const NO_RANGES_PROCESSED = 312;632pub const NO_RANGES_PROCESSED = 312;
633
423/// Operation is not allowed on a file system internal file.634/// Operation is not allowed on a file system internal file.
424pub const NOT_ALLOWED_ON_SYSTEM_FILE = 313;635pub const NOT_ALLOWED_ON_SYSTEM_FILE = 313;
636
425/// The physical resources of this disk have been exhausted.637/// The physical resources of this disk have been exhausted.
426pub const DISK_RESOURCES_EXHAUSTED = 314;638pub const DISK_RESOURCES_EXHAUSTED = 314;
639
427/// The token representing the data is invalid.640/// The token representing the data is invalid.
428pub const INVALID_TOKEN = 315;641pub const INVALID_TOKEN = 315;
642
429/// The device does not support the command feature.643/// The device does not support the command feature.
430pub const DEVICE_FEATURE_NOT_SUPPORTED = 316;644pub const DEVICE_FEATURE_NOT_SUPPORTED = 316;
645
431/// The system cannot find message text for message number 0x%1 in the message file for %2.646/// The system cannot find message text for message number 0x%1 in the message file for %2.
432pub const MR_MID_NOT_FOUND = 317;647pub const MR_MID_NOT_FOUND = 317;
648
433/// The scope specified was not found.649/// The scope specified was not found.
434pub const SCOPE_NOT_FOUND = 318;650pub const SCOPE_NOT_FOUND = 318;
651
435/// The Central Access Policy specified is not defined on the target machine.652/// The Central Access Policy specified is not defined on the target machine.
436pub const UNDEFINED_SCOPE = 319;653pub const UNDEFINED_SCOPE = 319;
654
437/// The Central Access Policy obtained from Active Directory is invalid.655/// The Central Access Policy obtained from Active Directory is invalid.
438pub const INVALID_CAP = 320;656pub const INVALID_CAP = 320;
657
439/// The device is unreachable.658/// The device is unreachable.
440pub const DEVICE_UNREACHABLE = 321;659pub const DEVICE_UNREACHABLE = 321;
660
441/// The target device has insufficient resources to complete the operation.661/// The target device has insufficient resources to complete the operation.
442pub const DEVICE_NO_RESOURCES = 322;662pub const DEVICE_NO_RESOURCES = 322;
663
443/// A data integrity checksum error occurred. Data in the file stream is corrupt.664/// A data integrity checksum error occurred. Data in the file stream is corrupt.
444pub const DATA_CHECKSUM_ERROR = 323;665pub const DATA_CHECKSUM_ERROR = 323;
666
445/// An attempt was made to modify both a KERNEL and normal Extended Attribute (EA) in the same operation.667/// An attempt was made to modify both a KERNEL and normal Extended Attribute (EA) in the same operation.
446pub const INTERMIXED_KERNEL_EA_OPERATION = 324;668pub const INTERMIXED_KERNEL_EA_OPERATION = 324;
669
447/// Device does not support file-level TRIM.670/// Device does not support file-level TRIM.
448pub const FILE_LEVEL_TRIM_NOT_SUPPORTED = 326;671pub const FILE_LEVEL_TRIM_NOT_SUPPORTED = 326;
672
449/// The command specified a data offset that does not align to the device's granularity/alignment.673/// The command specified a data offset that does not align to the device's granularity/alignment.
450pub const OFFSET_ALIGNMENT_VIOLATION = 327;674pub const OFFSET_ALIGNMENT_VIOLATION = 327;
675
451/// The command specified an invalid field in its parameter list.676/// The command specified an invalid field in its parameter list.
452pub const INVALID_FIELD_IN_PARAMETER_LIST = 328;677pub const INVALID_FIELD_IN_PARAMETER_LIST = 328;
678
453/// An operation is currently in progress with the device.679/// An operation is currently in progress with the device.
454pub const OPERATION_IN_PROGRESS = 329;680pub const OPERATION_IN_PROGRESS = 329;
681
455/// An attempt was made to send down the command via an invalid path to the target device.682/// An attempt was made to send down the command via an invalid path to the target device.
456pub const BAD_DEVICE_PATH = 330;683pub const BAD_DEVICE_PATH = 330;
684
457/// The command specified a number of descriptors that exceeded the maximum supported by the device.685/// The command specified a number of descriptors that exceeded the maximum supported by the device.
458pub const TOO_MANY_DESCRIPTORS = 331;686pub const TOO_MANY_DESCRIPTORS = 331;
687
459/// Scrub is disabled on the specified file.688/// Scrub is disabled on the specified file.
460pub const SCRUB_DATA_DISABLED = 332;689pub const SCRUB_DATA_DISABLED = 332;
690
461/// The storage device does not provide redundancy.691/// The storage device does not provide redundancy.
462pub const NOT_REDUNDANT_STORAGE = 333;692pub const NOT_REDUNDANT_STORAGE = 333;
693
463/// An operation is not supported on a resident file.694/// An operation is not supported on a resident file.
464pub const RESIDENT_FILE_NOT_SUPPORTED = 334;695pub const RESIDENT_FILE_NOT_SUPPORTED = 334;
696
465/// An operation is not supported on a compressed file.697/// An operation is not supported on a compressed file.
466pub const COMPRESSED_FILE_NOT_SUPPORTED = 335;698pub const COMPRESSED_FILE_NOT_SUPPORTED = 335;
699
467/// An operation is not supported on a directory.700/// An operation is not supported on a directory.
468pub const DIRECTORY_NOT_SUPPORTED = 336;701pub const DIRECTORY_NOT_SUPPORTED = 336;
702
469/// The specified copy of the requested data could not be read.703/// The specified copy of the requested data could not be read.
470pub const NOT_READ_FROM_COPY = 337;704pub const NOT_READ_FROM_COPY = 337;
705
471/// No action was taken as a system reboot is required.706/// No action was taken as a system reboot is required.
472pub const FAIL_NOACTION_REBOOT = 350;707pub const FAIL_NOACTION_REBOOT = 350;
708
473/// The shutdown operation failed.709/// The shutdown operation failed.
474pub const FAIL_SHUTDOWN = 351;710pub const FAIL_SHUTDOWN = 351;
711
475/// The restart operation failed.712/// The restart operation failed.
476pub const FAIL_RESTART = 352;713pub const FAIL_RESTART = 352;
714
477/// The maximum number of sessions has been reached.715/// The maximum number of sessions has been reached.
478pub const MAX_SESSIONS_REACHED = 353;716pub const MAX_SESSIONS_REACHED = 353;
717
479/// The thread is already in background processing mode.718/// The thread is already in background processing mode.
480pub const THREAD_MODE_ALREADY_BACKGROUND = 400;719pub const THREAD_MODE_ALREADY_BACKGROUND = 400;
720
481/// The thread is not in background processing mode.721/// The thread is not in background processing mode.
482pub const THREAD_MODE_NOT_BACKGROUND = 401;722pub const THREAD_MODE_NOT_BACKGROUND = 401;
723
483/// The process is already in background processing mode.724/// The process is already in background processing mode.
484pub const PROCESS_MODE_ALREADY_BACKGROUND = 402;725pub const PROCESS_MODE_ALREADY_BACKGROUND = 402;
726
485/// The process is not in background processing mode.727/// The process is not in background processing mode.
486pub const PROCESS_MODE_NOT_BACKGROUND = 403;728pub const PROCESS_MODE_NOT_BACKGROUND = 403;
729
487/// Attempt to access invalid address.730/// Attempt to access invalid address.
488pub const INVALID_ADDRESS = 487;731pub const INVALID_ADDRESS = 487;
732
489/// User profile cannot be loaded.733/// User profile cannot be loaded.
490pub const USER_PROFILE_LOAD = 500;734pub const USER_PROFILE_LOAD = 500;
735
491/// Arithmetic result exceeded 32 bits.736/// Arithmetic result exceeded 32 bits.
492pub const ARITHMETIC_OVERFLOW = 534;737pub const ARITHMETIC_OVERFLOW = 534;
738
493/// There is a process on other end of the pipe.739/// There is a process on other end of the pipe.
494pub const PIPE_CONNECTED = 535;740pub const PIPE_CONNECTED = 535;
741
495/// Waiting for a process to open the other end of the pipe.742/// Waiting for a process to open the other end of the pipe.
496pub const PIPE_LISTENING = 536;743pub const PIPE_LISTENING = 536;
744
497/// Application verifier has found an error in the current process.745/// Application verifier has found an error in the current process.
498pub const VERIFIER_STOP = 537;746pub const VERIFIER_STOP = 537;
747
499/// An error occurred in the ABIOS subsystem.748/// An error occurred in the ABIOS subsystem.
500pub const ABIOS_ERROR = 538;749pub const ABIOS_ERROR = 538;
750
501/// A warning occurred in the WX86 subsystem.751/// A warning occurred in the WX86 subsystem.
502pub const WX86_WARNING = 539;752pub const WX86_WARNING = 539;
753
503/// An error occurred in the WX86 subsystem.754/// An error occurred in the WX86 subsystem.
504pub const WX86_ERROR = 540;755pub const WX86_ERROR = 540;
756
505/// An attempt was made to cancel or set a timer that has an associated APC and the subject thread is not the thread that originally set the timer with an associated APC routine.757/// An attempt was made to cancel or set a timer that has an associated APC and the subject thread is not the thread that originally set the timer with an associated APC routine.
506pub const TIMER_NOT_CANCELED = 541;758pub const TIMER_NOT_CANCELED = 541;
759
507/// Unwind exception code.760/// Unwind exception code.
508pub const UNWIND = 542;761pub const UNWIND = 542;
762
509/// An invalid or unaligned stack was encountered during an unwind operation.763/// An invalid or unaligned stack was encountered during an unwind operation.
510pub const BAD_STACK = 543;764pub const BAD_STACK = 543;
765
511/// An invalid unwind target was encountered during an unwind operation.766/// An invalid unwind target was encountered during an unwind operation.
512pub const INVALID_UNWIND_TARGET = 544;767pub const INVALID_UNWIND_TARGET = 544;
768
513/// Invalid Object Attributes specified to NtCreatePort or invalid Port Attributes specified to NtConnectPort769/// Invalid Object Attributes specified to NtCreatePort or invalid Port Attributes specified to NtConnectPort
514pub const INVALID_PORT_ATTRIBUTES = 545;770pub const INVALID_PORT_ATTRIBUTES = 545;
771
515/// Length of message passed to NtRequestPort or NtRequestWaitReplyPort was longer than the maximum message allowed by the port.772/// Length of message passed to NtRequestPort or NtRequestWaitReplyPort was longer than the maximum message allowed by the port.
516pub const PORT_MESSAGE_TOO_LONG = 546;773pub const PORT_MESSAGE_TOO_LONG = 546;
774
517/// An attempt was made to lower a quota limit below the current usage.775/// An attempt was made to lower a quota limit below the current usage.
518pub const INVALID_QUOTA_LOWER = 547;776pub const INVALID_QUOTA_LOWER = 547;
777
519/// An attempt was made to attach to a device that was already attached to another device.778/// An attempt was made to attach to a device that was already attached to another device.
520pub const DEVICE_ALREADY_ATTACHED = 548;779pub const DEVICE_ALREADY_ATTACHED = 548;
780
521/// An attempt was made to execute an instruction at an unaligned address and the host system does not support unaligned instruction references.781/// An attempt was made to execute an instruction at an unaligned address and the host system does not support unaligned instruction references.
522pub const INSTRUCTION_MISALIGNMENT = 549;782pub const INSTRUCTION_MISALIGNMENT = 549;
783
523/// Profiling not started.784/// Profiling not started.
524pub const PROFILING_NOT_STARTED = 550;785pub const PROFILING_NOT_STARTED = 550;
786
525/// Profiling not stopped.787/// Profiling not stopped.
526pub const PROFILING_NOT_STOPPED = 551;788pub const PROFILING_NOT_STOPPED = 551;
789
527/// The passed ACL did not contain the minimum required information.790/// The passed ACL did not contain the minimum required information.
528pub const COULD_NOT_INTERPRET = 552;791pub const COULD_NOT_INTERPRET = 552;
792
529/// The number of active profiling objects is at the maximum and no more may be started.793/// The number of active profiling objects is at the maximum and no more may be started.
530pub const PROFILING_AT_LIMIT = 553;794pub const PROFILING_AT_LIMIT = 553;
795
531/// Used to indicate that an operation cannot continue without blocking for I/O.796/// Used to indicate that an operation cannot continue without blocking for I/O.
532pub const CANT_WAIT = 554;797pub const CANT_WAIT = 554;
798
533/// Indicates that a thread attempted to terminate itself by default (called NtTerminateThread with NULL) and it was the last thread in the current process.799/// Indicates that a thread attempted to terminate itself by default (called NtTerminateThread with NULL) and it was the last thread in the current process.
534pub const CANT_TERMINATE_SELF = 555;800pub const CANT_TERMINATE_SELF = 555;
801
535/// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter. In this case information is lost, however, the filter correctly handles the exception.802/// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter. In this case information is lost, however, the filter correctly handles the exception.
536pub const UNEXPECTED_MM_CREATE_ERR = 556;803pub const UNEXPECTED_MM_CREATE_ERR = 556;
804
537/// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter. In this case information is lost, however, the filter correctly handles the exception.805/// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter. In this case information is lost, however, the filter correctly handles the exception.
538pub const UNEXPECTED_MM_MAP_ERROR = 557;806pub const UNEXPECTED_MM_MAP_ERROR = 557;
807
539/// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter. In this case information is lost, however, the filter correctly handles the exception.808/// If an MM error is returned which is not defined in the standard FsRtl filter, it is converted to one of the following errors which is guaranteed to be in the filter. In this case information is lost, however, the filter correctly handles the exception.
540pub const UNEXPECTED_MM_EXTEND_ERR = 558;809pub const UNEXPECTED_MM_EXTEND_ERR = 558;
810
541/// A malformed function table was encountered during an unwind operation.811/// A malformed function table was encountered during an unwind operation.
542pub const BAD_FUNCTION_TABLE = 559;812pub const BAD_FUNCTION_TABLE = 559;
813
543/// Indicates that an attempt was made to assign protection to a file system file or directory and one of the SIDs in the security descriptor could not be translated into a GUID that could be stored by the file system. This causes the protection attempt to fail, which may cause a file creation attempt to fail.814/// Indicates that an attempt was made to assign protection to a file system file or directory and one of the SIDs in the security descriptor could not be translated into a GUID that could be stored by the file system. This causes the protection attempt to fail, which may cause a file creation attempt to fail.
544pub const NO_GUID_TRANSLATION = 560;815pub const NO_GUID_TRANSLATION = 560;
816
545/// Indicates that an attempt was made to grow an LDT by setting its size, or that the size was not an even number of selectors.817/// Indicates that an attempt was made to grow an LDT by setting its size, or that the size was not an even number of selectors.
546pub const INVALID_LDT_SIZE = 561;818pub const INVALID_LDT_SIZE = 561;
819
547/// Indicates that the starting value for the LDT information was not an integral multiple of the selector size.820/// Indicates that the starting value for the LDT information was not an integral multiple of the selector size.
548pub const INVALID_LDT_OFFSET = 563;821pub const INVALID_LDT_OFFSET = 563;
822
549/// Indicates that the user supplied an invalid descriptor when trying to set up Ldt descriptors.823/// Indicates that the user supplied an invalid descriptor when trying to set up Ldt descriptors.
550pub const INVALID_LDT_DESCRIPTOR = 564;824pub const INVALID_LDT_DESCRIPTOR = 564;
825
551/// Indicates a process has too many threads to perform the requested action. For example, assignment of a primary token may only be performed when a process has zero or one threads.826/// Indicates a process has too many threads to perform the requested action. For example, assignment of a primary token may only be performed when a process has zero or one threads.
552pub const TOO_MANY_THREADS = 565;827pub const TOO_MANY_THREADS = 565;
828
553/// An attempt was made to operate on a thread within a specific process, but the thread specified is not in the process specified.829/// An attempt was made to operate on a thread within a specific process, but the thread specified is not in the process specified.
554pub const THREAD_NOT_IN_PROCESS = 566;830pub const THREAD_NOT_IN_PROCESS = 566;
831
555/// Page file quota was exceeded.832/// Page file quota was exceeded.
556pub const PAGEFILE_QUOTA_EXCEEDED = 567;833pub const PAGEFILE_QUOTA_EXCEEDED = 567;
834
557/// The Netlogon service cannot start because another Netlogon service running in the domain conflicts with the specified role.835/// The Netlogon service cannot start because another Netlogon service running in the domain conflicts with the specified role.
558pub const LOGON_SERVER_CONFLICT = 568;836pub const LOGON_SERVER_CONFLICT = 568;
837
559/// The SAM database on a Windows Server is significantly out of synchronization with the copy on the Domain Controller. A complete synchronization is required.838/// The SAM database on a Windows Server is significantly out of synchronization with the copy on the Domain Controller. A complete synchronization is required.
560pub const SYNCHRONIZATION_REQUIRED = 569;839pub const SYNCHRONIZATION_REQUIRED = 569;
840
561/// The NtCreateFile API failed. This error should never be returned to an application, it is a place holder for the Windows Lan Manager Redirector to use in its internal error mapping routines.841/// The NtCreateFile API failed. This error should never be returned to an application, it is a place holder for the Windows Lan Manager Redirector to use in its internal error mapping routines.
562pub const NET_OPEN_FAILED = 570;842pub const NET_OPEN_FAILED = 570;
843
563/// {Privilege Failed} The I/O permissions for the process could not be changed.844/// {Privilege Failed} The I/O permissions for the process could not be changed.
564pub const IO_PRIVILEGE_FAILED = 571;845pub const IO_PRIVILEGE_FAILED = 571;
846
565/// {Application Exit by CTRL+C} The application terminated as a result of a CTRL+C.847/// {Application Exit by CTRL+C} The application terminated as a result of a CTRL+C.
566pub const CONTROL_C_EXIT = 572;848pub const CONTROL_C_EXIT = 572;
849
567/// {Missing System File} The required system file %hs is bad or missing.850/// {Missing System File} The required system file %hs is bad or missing.
568pub const MISSING_SYSTEMFILE = 573;851pub const MISSING_SYSTEMFILE = 573;
852
569/// {Application Error} The exception %s (0x%08lx) occurred in the application at location 0x%08lx.853/// {Application Error} The exception %s (0x%08lx) occurred in the application at location 0x%08lx.
570pub const UNHANDLED_EXCEPTION = 574;854pub const UNHANDLED_EXCEPTION = 574;
855
571/// {Application Error} The application was unable to start correctly (0x%lx). Click OK to close the application.856/// {Application Error} The application was unable to start correctly (0x%lx). Click OK to close the application.
572pub const APP_INIT_FAILURE = 575;857pub const APP_INIT_FAILURE = 575;
858
573/// {Unable to Create Paging File} The creation of the paging file %hs failed (%lx). The requested size was %ld.859/// {Unable to Create Paging File} The creation of the paging file %hs failed (%lx). The requested size was %ld.
574pub const PAGEFILE_CREATE_FAILED = 576;860pub const PAGEFILE_CREATE_FAILED = 576;
861
575/// Windows cannot verify the digital signature for this file. A recent hardware or software change might have installed a file that is signed incorrectly or damaged, or that might be malicious software from an unknown source.862/// Windows cannot verify the digital signature for this file. A recent hardware or software change might have installed a file that is signed incorrectly or damaged, or that might be malicious software from an unknown source.
576pub const INVALID_IMAGE_HASH = 577;863pub const INVALID_IMAGE_HASH = 577;
864
577/// {No Paging File Specified} No paging file was specified in the system configuration.865/// {No Paging File Specified} No paging file was specified in the system configuration.
578pub const NO_PAGEFILE = 578;866pub const NO_PAGEFILE = 578;
867
579/// {EXCEPTION} A real-mode application issued a floating-point instruction and floating-point hardware is not present.868/// {EXCEPTION} A real-mode application issued a floating-point instruction and floating-point hardware is not present.
580pub const ILLEGAL_FLOAT_CONTEXT = 579;869pub const ILLEGAL_FLOAT_CONTEXT = 579;
870
581/// An event pair synchronization operation was performed using the thread specific client/server event pair object, but no event pair object was associated with the thread.871/// An event pair synchronization operation was performed using the thread specific client/server event pair object, but no event pair object was associated with the thread.
582pub const NO_EVENT_PAIR = 580;872pub const NO_EVENT_PAIR = 580;
873
583/// A Windows Server has an incorrect configuration.874/// A Windows Server has an incorrect configuration.
584pub const DOMAIN_CTRLR_CONFIG_ERROR = 581;875pub const DOMAIN_CTRLR_CONFIG_ERROR = 581;
876
585/// An illegal character was encountered. For a multi-byte character set this includes a lead byte without a succeeding trail byte. For the Unicode character set this includes the characters 0xFFFF and 0xFFFE.877/// An illegal character was encountered. For a multi-byte character set this includes a lead byte without a succeeding trail byte. For the Unicode character set this includes the characters 0xFFFF and 0xFFFE.
586pub const ILLEGAL_CHARACTER = 582;878pub const ILLEGAL_CHARACTER = 582;
879
587/// The Unicode character is not defined in the Unicode character set installed on the system.880/// The Unicode character is not defined in the Unicode character set installed on the system.
588pub const UNDEFINED_CHARACTER = 583;881pub const UNDEFINED_CHARACTER = 583;
882
589/// The paging file cannot be created on a floppy diskette.883/// The paging file cannot be created on a floppy diskette.
590pub const FLOPPY_VOLUME = 584;884pub const FLOPPY_VOLUME = 584;
885
591/// The system BIOS failed to connect a system interrupt to the device or bus for which the device is connected.886/// The system BIOS failed to connect a system interrupt to the device or bus for which the device is connected.
592pub const BIOS_FAILED_TO_CONNECT_INTERRUPT = 585;887pub const BIOS_FAILED_TO_CONNECT_INTERRUPT = 585;
888
593/// This operation is only allowed for the Primary Domain Controller of the domain.889/// This operation is only allowed for the Primary Domain Controller of the domain.
594pub const BACKUP_CONTROLLER = 586;890pub const BACKUP_CONTROLLER = 586;
891
595/// An attempt was made to acquire a mutant such that its maximum count would have been exceeded.892/// An attempt was made to acquire a mutant such that its maximum count would have been exceeded.
596pub const MUTANT_LIMIT_EXCEEDED = 587;893pub const MUTANT_LIMIT_EXCEEDED = 587;
894
597/// A volume has been accessed for which a file system driver is required that has not yet been loaded.895/// A volume has been accessed for which a file system driver is required that has not yet been loaded.
598pub const FS_DRIVER_REQUIRED = 588;896pub const FS_DRIVER_REQUIRED = 588;
897
599/// {Registry File Failure} The registry cannot load the hive (file): %hs or its log or alternate. It is corrupt, absent, or not writable.898/// {Registry File Failure} The registry cannot load the hive (file): %hs or its log or alternate. It is corrupt, absent, or not writable.
600pub const CANNOT_LOAD_REGISTRY_FILE = 589;899pub const CANNOT_LOAD_REGISTRY_FILE = 589;
900
601/// {Unexpected Failure in DebugActiveProcess} An unexpected failure occurred while processing a DebugActiveProcess API request. You may choose OK to terminate the process, or Cancel to ignore the error.901/// {Unexpected Failure in DebugActiveProcess} An unexpected failure occurred while processing a DebugActiveProcess API request. You may choose OK to terminate the process, or Cancel to ignore the error.
602pub const DEBUG_ATTACH_FAILED = 590;902pub const DEBUG_ATTACH_FAILED = 590;
903
603/// {Fatal System Error} The %hs system process terminated unexpectedly with a status of 0x%08x (0x%08x 0x%08x). The system has been shut down.904/// {Fatal System Error} The %hs system process terminated unexpectedly with a status of 0x%08x (0x%08x 0x%08x). The system has been shut down.
604pub const SYSTEM_PROCESS_TERMINATED = 591;905pub const SYSTEM_PROCESS_TERMINATED = 591;
906
605/// {Data Not Accepted} The TDI client could not handle the data received during an indication.907/// {Data Not Accepted} The TDI client could not handle the data received during an indication.
606pub const DATA_NOT_ACCEPTED = 592;908pub const DATA_NOT_ACCEPTED = 592;
909
607/// NTVDM encountered a hard error.910/// NTVDM encountered a hard error.
608pub const VDM_HARD_ERROR = 593;911pub const VDM_HARD_ERROR = 593;
912
609/// {Cancel Timeout} The driver %hs failed to complete a cancelled I/O request in the allotted time.913/// {Cancel Timeout} The driver %hs failed to complete a cancelled I/O request in the allotted time.
610pub const DRIVER_CANCEL_TIMEOUT = 594;914pub const DRIVER_CANCEL_TIMEOUT = 594;
915
611/// {Reply Message Mismatch} An attempt was made to reply to an LPC message, but the thread specified by the client ID in the message was not waiting on that message.916/// {Reply Message Mismatch} An attempt was made to reply to an LPC message, but the thread specified by the client ID in the message was not waiting on that message.
612pub const REPLY_MESSAGE_MISMATCH = 595;917pub const REPLY_MESSAGE_MISMATCH = 595;
918
613/// {Delayed Write Failed} Windows was unable to save all the data for the file %hs. The data has been lost. This error may be caused by a failure of your computer hardware or network connection. Please try to save this file elsewhere.919/// {Delayed Write Failed} Windows was unable to save all the data for the file %hs. The data has been lost. This error may be caused by a failure of your computer hardware or network connection. Please try to save this file elsewhere.
614pub const LOST_WRITEBEHIND_DATA = 596;920pub const LOST_WRITEBEHIND_DATA = 596;
921
615/// The parameter(s) passed to the server in the client/server shared memory window were invalid. Too much data may have been put in the shared memory window.922/// The parameter(s) passed to the server in the client/server shared memory window were invalid. Too much data may have been put in the shared memory window.
616pub const CLIENT_SERVER_PARAMETERS_INVALID = 597;923pub const CLIENT_SERVER_PARAMETERS_INVALID = 597;
924
617/// The stream is not a tiny stream.925/// The stream is not a tiny stream.
618pub const NOT_TINY_STREAM = 598;926pub const NOT_TINY_STREAM = 598;
927
619/// The request must be handled by the stack overflow code.928/// The request must be handled by the stack overflow code.
620pub const STACK_OVERFLOW_READ = 599;929pub const STACK_OVERFLOW_READ = 599;
930
621/// Internal OFS status codes indicating how an allocation operation is handled. Either it is retried after the containing onode is moved or the extent stream is converted to a large stream.931/// Internal OFS status codes indicating how an allocation operation is handled. Either it is retried after the containing onode is moved or the extent stream is converted to a large stream.
622pub const CONVERT_TO_LARGE = 600;932pub const CONVERT_TO_LARGE = 600;
933
623/// The attempt to find the object found an object matching by ID on the volume but it is out of the scope of the handle used for the operation.934/// The attempt to find the object found an object matching by ID on the volume but it is out of the scope of the handle used for the operation.
624pub const FOUND_OUT_OF_SCOPE = 601;935pub const FOUND_OUT_OF_SCOPE = 601;
936
625/// The bucket array must be grown. Retry transaction after doing so.937/// The bucket array must be grown. Retry transaction after doing so.
626pub const ALLOCATE_BUCKET = 602;938pub const ALLOCATE_BUCKET = 602;
939
627/// The user/kernel marshalling buffer has overflowed.940/// The user/kernel marshalling buffer has overflowed.
628pub const MARSHALL_OVERFLOW = 603;941pub const MARSHALL_OVERFLOW = 603;
942
629/// The supplied variant structure contains invalid data.943/// The supplied variant structure contains invalid data.
630pub const INVALID_VARIANT = 604;944pub const INVALID_VARIANT = 604;
945
631/// The specified buffer contains ill-formed data.946/// The specified buffer contains ill-formed data.
632pub const BAD_COMPRESSION_BUFFER = 605;947pub const BAD_COMPRESSION_BUFFER = 605;
948
633/// {Audit Failed} An attempt to generate a security audit failed.949/// {Audit Failed} An attempt to generate a security audit failed.
634pub const AUDIT_FAILED = 606;950pub const AUDIT_FAILED = 606;
951
635/// The timer resolution was not previously set by the current process.952/// The timer resolution was not previously set by the current process.
636pub const TIMER_RESOLUTION_NOT_SET = 607;953pub const TIMER_RESOLUTION_NOT_SET = 607;
954
637/// There is insufficient account information to log you on.955/// There is insufficient account information to log you on.
638pub const INSUFFICIENT_LOGON_INFO = 608;956pub const INSUFFICIENT_LOGON_INFO = 608;
957
639/// {Invalid DLL Entrypoint} The dynamic link library %hs is not written correctly. The stack pointer has been left in an inconsistent state. The entrypoint should be declared as WINAPI or STDCALL. Select YES to fail the DLL load. Select NO to continue execution. Selecting NO may cause the application to operate incorrectly.958/// {Invalid DLL Entrypoint} The dynamic link library %hs is not written correctly. The stack pointer has been left in an inconsistent state. The entrypoint should be declared as WINAPI or STDCALL. Select YES to fail the DLL load. Select NO to continue execution. Selecting NO may cause the application to operate incorrectly.
640pub const BAD_DLL_ENTRYPOINT = 609;959pub const BAD_DLL_ENTRYPOINT = 609;
960
641/// {Invalid Service Callback Entrypoint} The %hs service is not written correctly. The stack pointer has been left in an inconsistent state. The callback entrypoint should be declared as WINAPI or STDCALL. Selecting OK will cause the service to continue operation. However, the service process may operate incorrectly.961/// {Invalid Service Callback Entrypoint} The %hs service is not written correctly. The stack pointer has been left in an inconsistent state. The callback entrypoint should be declared as WINAPI or STDCALL. Selecting OK will cause the service to continue operation. However, the service process may operate incorrectly.
642pub const BAD_SERVICE_ENTRYPOINT = 610;962pub const BAD_SERVICE_ENTRYPOINT = 610;
963
643/// There is an IP address conflict with another system on the network.964/// There is an IP address conflict with another system on the network.
644pub const IP_ADDRESS_CONFLICT1 = 611;965pub const IP_ADDRESS_CONFLICT1 = 611;
966
645/// There is an IP address conflict with another system on the network.967/// There is an IP address conflict with another system on the network.
646pub const IP_ADDRESS_CONFLICT2 = 612;968pub const IP_ADDRESS_CONFLICT2 = 612;
969
647/// {Low On Registry Space} The system has reached the maximum size allowed for the system part of the registry. Additional storage requests will be ignored.970/// {Low On Registry Space} The system has reached the maximum size allowed for the system part of the registry. Additional storage requests will be ignored.
648pub const REGISTRY_QUOTA_LIMIT = 613;971pub const REGISTRY_QUOTA_LIMIT = 613;
972
649/// A callback return system service cannot be executed when no callback is active.973/// A callback return system service cannot be executed when no callback is active.
650pub const NO_CALLBACK_ACTIVE = 614;974pub const NO_CALLBACK_ACTIVE = 614;
975
651/// The password provided is too short to meet the policy of your user account. Please choose a longer password.976/// The password provided is too short to meet the policy of your user account. Please choose a longer password.
652pub const PWD_TOO_SHORT = 615;977pub const PWD_TOO_SHORT = 615;
978
653/// The policy of your user account does not allow you to change passwords too frequently. This is done to prevent users from changing back to a familiar, but potentially discovered, password. If you feel your password has been compromised then please contact your administrator immediately to have a new one assigned.979/// The policy of your user account does not allow you to change passwords too frequently. This is done to prevent users from changing back to a familiar, but potentially discovered, password. If you feel your password has been compromised then please contact your administrator immediately to have a new one assigned.
654pub const PWD_TOO_RECENT = 616;980pub const PWD_TOO_RECENT = 616;
981
655/// You have attempted to change your password to one that you have used in the past. The policy of your user account does not allow this. Please select a password that you have not previously used.982/// You have attempted to change your password to one that you have used in the past. The policy of your user account does not allow this. Please select a password that you have not previously used.
656pub const PWD_HISTORY_CONFLICT = 617;983pub const PWD_HISTORY_CONFLICT = 617;
984
657/// The specified compression format is unsupported.985/// The specified compression format is unsupported.
658pub const UNSUPPORTED_COMPRESSION = 618;986pub const UNSUPPORTED_COMPRESSION = 618;
987
659/// The specified hardware profile configuration is invalid.988/// The specified hardware profile configuration is invalid.
660pub const INVALID_HW_PROFILE = 619;989pub const INVALID_HW_PROFILE = 619;
990
661/// The specified Plug and Play registry device path is invalid.991/// The specified Plug and Play registry device path is invalid.
662pub const INVALID_PLUGPLAY_DEVICE_PATH = 620;992pub const INVALID_PLUGPLAY_DEVICE_PATH = 620;
993
663/// The specified quota list is internally inconsistent with its descriptor.994/// The specified quota list is internally inconsistent with its descriptor.
664pub const QUOTA_LIST_INCONSISTENT = 621;995pub const QUOTA_LIST_INCONSISTENT = 621;
996
665/// {Windows Evaluation Notification} The evaluation period for this installation of Windows has expired. This system will shutdown in 1 hour. To restore access to this installation of Windows, please upgrade this installation using a licensed distribution of this product.997/// {Windows Evaluation Notification} The evaluation period for this installation of Windows has expired. This system will shutdown in 1 hour. To restore access to this installation of Windows, please upgrade this installation using a licensed distribution of this product.
666pub const EVALUATION_EXPIRATION = 622;998pub const EVALUATION_EXPIRATION = 622;
999
667/// {Illegal System DLL Relocation} The system DLL %hs was relocated in memory. The application will not run properly. The relocation occurred because the DLL %hs occupied an address range reserved for Windows system DLLs. The vendor supplying the DLL should be contacted for a new DLL.1000/// {Illegal System DLL Relocation} The system DLL %hs was relocated in memory. The application will not run properly. The relocation occurred because the DLL %hs occupied an address range reserved for Windows system DLLs. The vendor supplying the DLL should be contacted for a new DLL.
668pub const ILLEGAL_DLL_RELOCATION = 623;1001pub const ILLEGAL_DLL_RELOCATION = 623;
1002
669/// {DLL Initialization Failed} The application failed to initialize because the window station is shutting down.1003/// {DLL Initialization Failed} The application failed to initialize because the window station is shutting down.
670pub const DLL_INIT_FAILED_LOGOFF = 624;1004pub const DLL_INIT_FAILED_LOGOFF = 624;
1005
671/// The validation process needs to continue on to the next step.1006/// The validation process needs to continue on to the next step.
672pub const VALIDATE_CONTINUE = 625;1007pub const VALIDATE_CONTINUE = 625;
1008
673/// There are no more matches for the current index enumeration.1009/// There are no more matches for the current index enumeration.
674pub const NO_MORE_MATCHES = 626;1010pub const NO_MORE_MATCHES = 626;
1011
675/// The range could not be added to the range list because of a conflict.1012/// The range could not be added to the range list because of a conflict.
676pub const RANGE_LIST_CONFLICT = 627;1013pub const RANGE_LIST_CONFLICT = 627;
1014
677/// The server process is running under a SID different than that required by client.1015/// The server process is running under a SID different than that required by client.
678pub const SERVER_SID_MISMATCH = 628;1016pub const SERVER_SID_MISMATCH = 628;
1017
679/// A group marked use for deny only cannot be enabled.1018/// A group marked use for deny only cannot be enabled.
680pub const CANT_ENABLE_DENY_ONLY = 629;1019pub const CANT_ENABLE_DENY_ONLY = 629;
1020
681/// {EXCEPTION} Multiple floating point faults.1021/// {EXCEPTION} Multiple floating point faults.
682pub const FLOAT_MULTIPLE_FAULTS = 630;1022pub const FLOAT_MULTIPLE_FAULTS = 630;
1023
683/// {EXCEPTION} Multiple floating point traps.1024/// {EXCEPTION} Multiple floating point traps.
684pub const FLOAT_MULTIPLE_TRAPS = 631;1025pub const FLOAT_MULTIPLE_TRAPS = 631;
1026
685/// The requested interface is not supported.1027/// The requested interface is not supported.
686pub const NOINTERFACE = 632;1028pub const NOINTERFACE = 632;
1029
687/// {System Standby Failed} The driver %hs does not support standby mode. Updating this driver may allow the system to go to standby mode.1030/// {System Standby Failed} The driver %hs does not support standby mode. Updating this driver may allow the system to go to standby mode.
688pub const DRIVER_FAILED_SLEEP = 633;1031pub const DRIVER_FAILED_SLEEP = 633;
1032
689/// The system file %1 has become corrupt and has been replaced.1033/// The system file %1 has become corrupt and has been replaced.
690pub const CORRUPT_SYSTEM_FILE = 634;1034pub const CORRUPT_SYSTEM_FILE = 634;
1035
691/// {Virtual Memory Minimum Too Low} Your system is low on virtual memory. Windows is increasing the size of your virtual memory paging file. During this process, memory requests for some applications may be denied. For more information, see Help.1036/// {Virtual Memory Minimum Too Low} Your system is low on virtual memory. Windows is increasing the size of your virtual memory paging file. During this process, memory requests for some applications may be denied. For more information, see Help.
692pub const COMMITMENT_MINIMUM = 635;1037pub const COMMITMENT_MINIMUM = 635;
1038
693/// A device was removed so enumeration must be restarted.1039/// A device was removed so enumeration must be restarted.
694pub const PNP_RESTART_ENUMERATION = 636;1040pub const PNP_RESTART_ENUMERATION = 636;
1041
695/// {Fatal System Error} The system image %s is not properly signed. The file has been replaced with the signed file. The system has been shut down.1042/// {Fatal System Error} The system image %s is not properly signed. The file has been replaced with the signed file. The system has been shut down.
696pub const SYSTEM_IMAGE_BAD_SIGNATURE = 637;1043pub const SYSTEM_IMAGE_BAD_SIGNATURE = 637;
1044
697/// Device will not start without a reboot.1045/// Device will not start without a reboot.
698pub const PNP_REBOOT_REQUIRED = 638;1046pub const PNP_REBOOT_REQUIRED = 638;
1047
699/// There is not enough power to complete the requested operation.1048/// There is not enough power to complete the requested operation.
700pub const INSUFFICIENT_POWER = 639;1049pub const INSUFFICIENT_POWER = 639;
1050
701/// ERROR_MULTIPLE_FAULT_VIOLATION1051/// ERROR_MULTIPLE_FAULT_VIOLATION
702pub const MULTIPLE_FAULT_VIOLATION = 640;1052pub const MULTIPLE_FAULT_VIOLATION = 640;
1053
703/// The system is in the process of shutting down.1054/// The system is in the process of shutting down.
704pub const SYSTEM_SHUTDOWN = 641;1055pub const SYSTEM_SHUTDOWN = 641;
1056
705/// An attempt to remove a processes DebugPort was made, but a port was not already associated with the process.1057/// An attempt to remove a processes DebugPort was made, but a port was not already associated with the process.
706pub const PORT_NOT_SET = 642;1058pub const PORT_NOT_SET = 642;
1059
707/// This version of Windows is not compatible with the behavior version of directory forest, domain or domain controller.1060/// This version of Windows is not compatible with the behavior version of directory forest, domain or domain controller.
708pub const DS_VERSION_CHECK_FAILURE = 643;1061pub const DS_VERSION_CHECK_FAILURE = 643;
1062
709/// The specified range could not be found in the range list.1063/// The specified range could not be found in the range list.
710pub const RANGE_NOT_FOUND = 644;1064pub const RANGE_NOT_FOUND = 644;
1065
711/// The driver was not loaded because the system is booting into safe mode.1066/// The driver was not loaded because the system is booting into safe mode.
712pub const NOT_SAFE_MODE_DRIVER = 646;1067pub const NOT_SAFE_MODE_DRIVER = 646;
1068
713/// The driver was not loaded because it failed its initialization call.1069/// The driver was not loaded because it failed its initialization call.
714pub const FAILED_DRIVER_ENTRY = 647;1070pub const FAILED_DRIVER_ENTRY = 647;
1071
715/// The "%hs" encountered an error while applying power or reading the device configuration. This may be caused by a failure of your hardware or by a poor connection.1072/// The "%hs" encountered an error while applying power or reading the device configuration. This may be caused by a failure of your hardware or by a poor connection.
716pub const DEVICE_ENUMERATION_ERROR = 648;1073pub const DEVICE_ENUMERATION_ERROR = 648;
1074
717/// The create operation failed because the name contained at least one mount point which resolves to a volume to which the specified device object is not attached.1075/// The create operation failed because the name contained at least one mount point which resolves to a volume to which the specified device object is not attached.
718pub const MOUNT_POINT_NOT_RESOLVED = 649;1076pub const MOUNT_POINT_NOT_RESOLVED = 649;
1077
719/// The device object parameter is either not a valid device object or is not attached to the volume specified by the file name.1078/// The device object parameter is either not a valid device object or is not attached to the volume specified by the file name.
720pub const INVALID_DEVICE_OBJECT_PARAMETER = 650;1079pub const INVALID_DEVICE_OBJECT_PARAMETER = 650;
1080
721/// A Machine Check Error has occurred. Please check the system eventlog for additional information.1081/// A Machine Check Error has occurred. Please check the system eventlog for additional information.
722pub const MCA_OCCURED = 651;1082pub const MCA_OCCURED = 651;
1083
723/// There was error [%2] processing the driver database.1084/// There was error [%2] processing the driver database.
724pub const DRIVER_DATABASE_ERROR = 652;1085pub const DRIVER_DATABASE_ERROR = 652;
1086
725/// System hive size has exceeded its limit.1087/// System hive size has exceeded its limit.
726pub const SYSTEM_HIVE_TOO_LARGE = 653;1088pub const SYSTEM_HIVE_TOO_LARGE = 653;
1089
727/// The driver could not be loaded because a previous version of the driver is still in memory.1090/// The driver could not be loaded because a previous version of the driver is still in memory.
728pub const DRIVER_FAILED_PRIOR_UNLOAD = 654;1091pub const DRIVER_FAILED_PRIOR_UNLOAD = 654;
1092
729/// {Volume Shadow Copy Service} Please wait while the Volume Shadow Copy Service prepares volume %hs for hibernation.1093/// {Volume Shadow Copy Service} Please wait while the Volume Shadow Copy Service prepares volume %hs for hibernation.
730pub const VOLSNAP_PREPARE_HIBERNATE = 655;1094pub const VOLSNAP_PREPARE_HIBERNATE = 655;
1095
731/// The system has failed to hibernate (The error code is %hs). Hibernation will be disabled until the system is restarted.1096/// The system has failed to hibernate (The error code is %hs). Hibernation will be disabled until the system is restarted.
732pub const HIBERNATION_FAILURE = 656;1097pub const HIBERNATION_FAILURE = 656;
1098
733/// The password provided is too long to meet the policy of your user account. Please choose a shorter password.1099/// The password provided is too long to meet the policy of your user account. Please choose a shorter password.
734pub const PWD_TOO_LONG = 657;1100pub const PWD_TOO_LONG = 657;
1101
735/// The requested operation could not be completed due to a file system limitation.1102/// The requested operation could not be completed due to a file system limitation.
736pub const FILE_SYSTEM_LIMITATION = 665;1103pub const FILE_SYSTEM_LIMITATION = 665;
1104
737/// An assertion failure has occurred.1105/// An assertion failure has occurred.
738pub const ASSERTION_FAILURE = 668;1106pub const ASSERTION_FAILURE = 668;
1107
739/// An error occurred in the ACPI subsystem.1108/// An error occurred in the ACPI subsystem.
740pub const ACPI_ERROR = 669;1109pub const ACPI_ERROR = 669;
1110
741/// WOW Assertion Error.1111/// WOW Assertion Error.
742pub const WOW_ASSERTION = 670;1112pub const WOW_ASSERTION = 670;
1113
743/// A device is missing in the system BIOS MPS table. This device will not be used. Please contact your system vendor for system BIOS update.1114/// A device is missing in the system BIOS MPS table. This device will not be used. Please contact your system vendor for system BIOS update.
744pub const PNP_BAD_MPS_TABLE = 671;1115pub const PNP_BAD_MPS_TABLE = 671;
1116
745/// A translator failed to translate resources.1117/// A translator failed to translate resources.
746pub const PNP_TRANSLATION_FAILED = 672;1118pub const PNP_TRANSLATION_FAILED = 672;
1119
747/// A IRQ translator failed to translate resources.1120/// A IRQ translator failed to translate resources.
748pub const PNP_IRQ_TRANSLATION_FAILED = 673;1121pub const PNP_IRQ_TRANSLATION_FAILED = 673;
1122
749/// Driver %2 returned invalid ID for a child device (%3).1123/// Driver %2 returned invalid ID for a child device (%3).
750pub const PNP_INVALID_ID = 674;1124pub const PNP_INVALID_ID = 674;
1125
751/// {Kernel Debugger Awakened} the system debugger was awakened by an interrupt.1126/// {Kernel Debugger Awakened} the system debugger was awakened by an interrupt.
752pub const WAKE_SYSTEM_DEBUGGER = 675;1127pub const WAKE_SYSTEM_DEBUGGER = 675;
1128
753/// {Handles Closed} Handles to objects have been automatically closed as a result of the requested operation.1129/// {Handles Closed} Handles to objects have been automatically closed as a result of the requested operation.
754pub const HANDLES_CLOSED = 676;1130pub const HANDLES_CLOSED = 676;
1131
755/// {Too Much Information} The specified access control list (ACL) contained more information than was expected.1132/// {Too Much Information} The specified access control list (ACL) contained more information than was expected.
756pub const EXTRANEOUS_INFORMATION = 677;1133pub const EXTRANEOUS_INFORMATION = 677;
1134
757/// This warning level status indicates that the transaction state already exists for the registry sub-tree, but that a transaction commit was previously aborted. The commit has NOT been completed, but has not been rolled back either (so it may still be committed if desired).1135/// This warning level status indicates that the transaction state already exists for the registry sub-tree, but that a transaction commit was previously aborted. The commit has NOT been completed, but has not been rolled back either (so it may still be committed if desired).
758pub const RXACT_COMMIT_NECESSARY = 678;1136pub const RXACT_COMMIT_NECESSARY = 678;
1137
759/// {Media Changed} The media may have changed.1138/// {Media Changed} The media may have changed.
760pub const MEDIA_CHECK = 679;1139pub const MEDIA_CHECK = 679;
1140
761/// {GUID Substitution} During the translation of a global identifier (GUID) to a Windows security ID (SID), no administratively-defined GUID prefix was found. A substitute prefix was used, which will not compromise system security. However, this may provide a more restrictive access than intended.1141/// {GUID Substitution} During the translation of a global identifier (GUID) to a Windows security ID (SID), no administratively-defined GUID prefix was found. A substitute prefix was used, which will not compromise system security. However, this may provide a more restrictive access than intended.
762pub const GUID_SUBSTITUTION_MADE = 680;1142pub const GUID_SUBSTITUTION_MADE = 680;
1143
763/// The create operation stopped after reaching a symbolic link.1144/// The create operation stopped after reaching a symbolic link.
764pub const STOPPED_ON_SYMLINK = 681;1145pub const STOPPED_ON_SYMLINK = 681;
1146
765/// A long jump has been executed.1147/// A long jump has been executed.
766pub const LONGJUMP = 682;1148pub const LONGJUMP = 682;
1149
767/// The Plug and Play query operation was not successful.1150/// The Plug and Play query operation was not successful.
768pub const PLUGPLAY_QUERY_VETOED = 683;1151pub const PLUGPLAY_QUERY_VETOED = 683;
1152
769/// A frame consolidation has been executed.1153/// A frame consolidation has been executed.
770pub const UNWIND_CONSOLIDATE = 684;1154pub const UNWIND_CONSOLIDATE = 684;
1155
771/// {Registry Hive Recovered} Registry hive (file): %hs was corrupted and it has been recovered. Some data might have been lost.1156/// {Registry Hive Recovered} Registry hive (file): %hs was corrupted and it has been recovered. Some data might have been lost.
772pub const REGISTRY_HIVE_RECOVERED = 685;1157pub const REGISTRY_HIVE_RECOVERED = 685;
1158
773/// The application is attempting to run executable code from the module %hs. This may be insecure. An alternative, %hs, is available. Should the application use the secure module %hs?1159/// The application is attempting to run executable code from the module %hs. This may be insecure. An alternative, %hs, is available. Should the application use the secure module %hs?
774pub const DLL_MIGHT_BE_INSECURE = 686;1160pub const DLL_MIGHT_BE_INSECURE = 686;
1161
775/// The application is loading executable code from the module %hs. This is secure, but may be incompatible with previous releases of the operating system. An alternative, %hs, is available. Should the application use the secure module %hs?1162/// The application is loading executable code from the module %hs. This is secure, but may be incompatible with previous releases of the operating system. An alternative, %hs, is available. Should the application use the secure module %hs?
776pub const DLL_MIGHT_BE_INCOMPATIBLE = 687;1163pub const DLL_MIGHT_BE_INCOMPATIBLE = 687;
1164
777/// Debugger did not handle the exception.1165/// Debugger did not handle the exception.
778pub const DBG_EXCEPTION_NOT_HANDLED = 688;1166pub const DBG_EXCEPTION_NOT_HANDLED = 688;
1167
779/// Debugger will reply later.1168/// Debugger will reply later.
780pub const DBG_REPLY_LATER = 689;1169pub const DBG_REPLY_LATER = 689;
1170
781/// Debugger cannot provide handle.1171/// Debugger cannot provide handle.
782pub const DBG_UNABLE_TO_PROVIDE_HANDLE = 690;1172pub const DBG_UNABLE_TO_PROVIDE_HANDLE = 690;
1173
783/// Debugger terminated thread.1174/// Debugger terminated thread.
784pub const DBG_TERMINATE_THREAD = 691;1175pub const DBG_TERMINATE_THREAD = 691;
1176
785/// Debugger terminated process.1177/// Debugger terminated process.
786pub const DBG_TERMINATE_PROCESS = 692;1178pub const DBG_TERMINATE_PROCESS = 692;
1179
787/// Debugger got control C.1180/// Debugger got control C.
788pub const DBG_CONTROL_C = 693;1181pub const DBG_CONTROL_C = 693;
1182
789/// Debugger printed exception on control C.1183/// Debugger printed exception on control C.
790pub const DBG_PRINTEXCEPTION_C = 694;1184pub const DBG_PRINTEXCEPTION_C = 694;
1185
791/// Debugger received RIP exception.1186/// Debugger received RIP exception.
792pub const DBG_RIPEXCEPTION = 695;1187pub const DBG_RIPEXCEPTION = 695;
1188
793/// Debugger received control break.1189/// Debugger received control break.
794pub const DBG_CONTROL_BREAK = 696;1190pub const DBG_CONTROL_BREAK = 696;
1191
795/// Debugger command communication exception.1192/// Debugger command communication exception.
796pub const DBG_COMMAND_EXCEPTION = 697;1193pub const DBG_COMMAND_EXCEPTION = 697;
1194
797/// {Object Exists} An attempt was made to create an object and the object name already existed.1195/// {Object Exists} An attempt was made to create an object and the object name already existed.
798pub const OBJECT_NAME_EXISTS = 698;1196pub const OBJECT_NAME_EXISTS = 698;
1197
799/// {Thread Suspended} A thread termination occurred while the thread was suspended. The thread was resumed, and termination proceeded.1198/// {Thread Suspended} A thread termination occurred while the thread was suspended. The thread was resumed, and termination proceeded.
800pub const THREAD_WAS_SUSPENDED = 699;1199pub const THREAD_WAS_SUSPENDED = 699;
1200
801/// {Image Relocated} An image file could not be mapped at the address specified in the image file. Local fixups must be performed on this image.1201/// {Image Relocated} An image file could not be mapped at the address specified in the image file. Local fixups must be performed on this image.
802pub const IMAGE_NOT_AT_BASE = 700;1202pub const IMAGE_NOT_AT_BASE = 700;
1203
803/// This informational level status indicates that a specified registry sub-tree transaction state did not yet exist and had to be created.1204/// This informational level status indicates that a specified registry sub-tree transaction state did not yet exist and had to be created.
804pub const RXACT_STATE_CREATED = 701;1205pub const RXACT_STATE_CREATED = 701;
1206
805/// {Segment Load} A virtual DOS machine (VDM) is loading, unloading, or moving an MS-DOS or Win16 program segment image. An exception is raised so a debugger can load, unload or track symbols and breakpoints within these 16-bit segments.1207/// {Segment Load} A virtual DOS machine (VDM) is loading, unloading, or moving an MS-DOS or Win16 program segment image. An exception is raised so a debugger can load, unload or track symbols and breakpoints within these 16-bit segments.
806pub const SEGMENT_NOTIFICATION = 702;1208pub const SEGMENT_NOTIFICATION = 702;
1209
807/// {Invalid Current Directory} The process cannot switch to the startup current directory %hs. Select OK to set current directory to %hs, or select CANCEL to exit.1210/// {Invalid Current Directory} The process cannot switch to the startup current directory %hs. Select OK to set current directory to %hs, or select CANCEL to exit.
808pub const BAD_CURRENT_DIRECTORY = 703;1211pub const BAD_CURRENT_DIRECTORY = 703;
1212
809/// {Redundant Read} To satisfy a read request, the NT fault-tolerant file system successfully read the requested data from a redundant copy. This was done because the file system encountered a failure on a member of the fault-tolerant volume, but was unable to reassign the failing area of the device.1213/// {Redundant Read} To satisfy a read request, the NT fault-tolerant file system successfully read the requested data from a redundant copy. This was done because the file system encountered a failure on a member of the fault-tolerant volume, but was unable to reassign the failing area of the device.
810pub const FT_READ_RECOVERY_FROM_BACKUP = 704;1214pub const FT_READ_RECOVERY_FROM_BACKUP = 704;
1215
811/// {Redundant Write} To satisfy a write request, the NT fault-tolerant file system successfully wrote a redundant copy of the information. This was done because the file system encountered a failure on a member of the fault-tolerant volume, but was not able to reassign the failing area of the device.1216/// {Redundant Write} To satisfy a write request, the NT fault-tolerant file system successfully wrote a redundant copy of the information. This was done because the file system encountered a failure on a member of the fault-tolerant volume, but was not able to reassign the failing area of the device.
812pub const FT_WRITE_RECOVERY = 705;1217pub const FT_WRITE_RECOVERY = 705;
1218
813/// {Machine Type Mismatch} The image file %hs is valid, but is for a machine type other than the current machine. Select OK to continue, or CANCEL to fail the DLL load.1219/// {Machine Type Mismatch} The image file %hs is valid, but is for a machine type other than the current machine. Select OK to continue, or CANCEL to fail the DLL load.
814pub const IMAGE_MACHINE_TYPE_MISMATCH = 706;1220pub const IMAGE_MACHINE_TYPE_MISMATCH = 706;
1221
815/// {Partial Data Received} The network transport returned partial data to its client. The remaining data will be sent later.1222/// {Partial Data Received} The network transport returned partial data to its client. The remaining data will be sent later.
816pub const RECEIVE_PARTIAL = 707;1223pub const RECEIVE_PARTIAL = 707;
1224
817/// {Expedited Data Received} The network transport returned data to its client that was marked as expedited by the remote system.1225/// {Expedited Data Received} The network transport returned data to its client that was marked as expedited by the remote system.
818pub const RECEIVE_EXPEDITED = 708;1226pub const RECEIVE_EXPEDITED = 708;
1227
819/// {Partial Expedited Data Received} The network transport returned partial data to its client and this data was marked as expedited by the remote system. The remaining data will be sent later.1228/// {Partial Expedited Data Received} The network transport returned partial data to its client and this data was marked as expedited by the remote system. The remaining data will be sent later.
820pub const RECEIVE_PARTIAL_EXPEDITED = 709;1229pub const RECEIVE_PARTIAL_EXPEDITED = 709;
1230
821/// {TDI Event Done} The TDI indication has completed successfully.1231/// {TDI Event Done} The TDI indication has completed successfully.
822pub const EVENT_DONE = 710;1232pub const EVENT_DONE = 710;
1233
823/// {TDI Event Pending} The TDI indication has entered the pending state.1234/// {TDI Event Pending} The TDI indication has entered the pending state.
824pub const EVENT_PENDING = 711;1235pub const EVENT_PENDING = 711;
1236
825/// Checking file system on %wZ.1237/// Checking file system on %wZ.
826pub const CHECKING_FILE_SYSTEM = 712;1238pub const CHECKING_FILE_SYSTEM = 712;
1239
827/// {Fatal Application Exit} %hs.1240/// {Fatal Application Exit} %hs.
828pub const FATAL_APP_EXIT = 713;1241pub const FATAL_APP_EXIT = 713;
1242
829/// The specified registry key is referenced by a predefined handle.1243/// The specified registry key is referenced by a predefined handle.
830pub const PREDEFINED_HANDLE = 714;1244pub const PREDEFINED_HANDLE = 714;
1245
831/// {Page Unlocked} The page protection of a locked page was changed to 'No Access' and the page was unlocked from memory and from the process.1246/// {Page Unlocked} The page protection of a locked page was changed to 'No Access' and the page was unlocked from memory and from the process.
832pub const WAS_UNLOCKED = 715;1247pub const WAS_UNLOCKED = 715;
1248
833/// %hs1249/// %hs
834pub const SERVICE_NOTIFICATION = 716;1250pub const SERVICE_NOTIFICATION = 716;
1251
835/// {Page Locked} One of the pages to lock was already locked.1252/// {Page Locked} One of the pages to lock was already locked.
836pub const WAS_LOCKED = 717;1253pub const WAS_LOCKED = 717;
1254
837/// Application popup: %1 : %21255/// Application popup: %1 : %2
838pub const LOG_HARD_ERROR = 718;1256pub const LOG_HARD_ERROR = 718;
1257
839/// ERROR_ALREADY_WIN321258/// ERROR_ALREADY_WIN32
840pub const ALREADY_WIN32 = 719;1259pub const ALREADY_WIN32 = 719;
1260
841/// {Machine Type Mismatch} The image file %hs is valid, but is for a machine type other than the current machine.1261/// {Machine Type Mismatch} The image file %hs is valid, but is for a machine type other than the current machine.
842pub const IMAGE_MACHINE_TYPE_MISMATCH_EXE = 720;1262pub const IMAGE_MACHINE_TYPE_MISMATCH_EXE = 720;
1263
843/// A yield execution was performed and no thread was available to run.1264/// A yield execution was performed and no thread was available to run.
844pub const NO_YIELD_PERFORMED = 721;1265pub const NO_YIELD_PERFORMED = 721;
1266
845/// The resumable flag to a timer API was ignored.1267/// The resumable flag to a timer API was ignored.
846pub const TIMER_RESUME_IGNORED = 722;1268pub const TIMER_RESUME_IGNORED = 722;
1269
847/// The arbiter has deferred arbitration of these resources to its parent.1270/// The arbiter has deferred arbitration of these resources to its parent.
848pub const ARBITRATION_UNHANDLED = 723;1271pub const ARBITRATION_UNHANDLED = 723;
1272
849/// The inserted CardBus device cannot be started because of a configuration error on "%hs".1273/// The inserted CardBus device cannot be started because of a configuration error on "%hs".
850pub const CARDBUS_NOT_SUPPORTED = 724;1274pub const CARDBUS_NOT_SUPPORTED = 724;
1275
851/// The CPUs in this multiprocessor system are not all the same revision level. To use all processors the operating system restricts itself to the features of the least capable processor in the system. Should problems occur with this system, contact the CPU manufacturer to see if this mix of processors is supported.1276/// The CPUs in this multiprocessor system are not all the same revision level. To use all processors the operating system restricts itself to the features of the least capable processor in the system. Should problems occur with this system, contact the CPU manufacturer to see if this mix of processors is supported.
852pub const MP_PROCESSOR_MISMATCH = 725;1277pub const MP_PROCESSOR_MISMATCH = 725;
1278
853/// The system was put into hibernation.1279/// The system was put into hibernation.
854pub const HIBERNATED = 726;1280pub const HIBERNATED = 726;
1281
855/// The system was resumed from hibernation.1282/// The system was resumed from hibernation.
856pub const RESUME_HIBERNATION = 727;1283pub const RESUME_HIBERNATION = 727;
1284
857/// Windows has detected that the system firmware (BIOS) was updated [previous firmware date = %2, current firmware date %3].1285/// Windows has detected that the system firmware (BIOS) was updated [previous firmware date = %2, current firmware date %3].
858pub const FIRMWARE_UPDATED = 728;1286pub const FIRMWARE_UPDATED = 728;
1287
859/// A device driver is leaking locked I/O pages causing system degradation. The system has automatically enabled tracking code in order to try and catch the culprit.1288/// A device driver is leaking locked I/O pages causing system degradation. The system has automatically enabled tracking code in order to try and catch the culprit.
860pub const DRIVERS_LEAKING_LOCKED_PAGES = 729;1289pub const DRIVERS_LEAKING_LOCKED_PAGES = 729;
1290
861/// The system has awoken.1291/// The system has awoken.
862pub const WAKE_SYSTEM = 730;1292pub const WAKE_SYSTEM = 730;
1293
863/// ERROR_WAIT_11294/// ERROR_WAIT_1
864pub const WAIT_1 = 731;1295pub const WAIT_1 = 731;
1296
865/// ERROR_WAIT_21297/// ERROR_WAIT_2
866pub const WAIT_2 = 732;1298pub const WAIT_2 = 732;
1299
867/// ERROR_WAIT_31300/// ERROR_WAIT_3
868pub const WAIT_3 = 733;1301pub const WAIT_3 = 733;
1302
869/// ERROR_WAIT_631303/// ERROR_WAIT_63
870pub const WAIT_63 = 734;1304pub const WAIT_63 = 734;
1305
871/// ERROR_ABANDONED_WAIT_01306/// ERROR_ABANDONED_WAIT_0
872pub const ABANDONED_WAIT_0 = 735;1307pub const ABANDONED_WAIT_0 = 735;
1308
873/// ERROR_ABANDONED_WAIT_631309/// ERROR_ABANDONED_WAIT_63
874pub const ABANDONED_WAIT_63 = 736;1310pub const ABANDONED_WAIT_63 = 736;
1311
875/// ERROR_USER_APC1312/// ERROR_USER_APC
876pub const USER_APC = 737;1313pub const USER_APC = 737;
1314
877/// ERROR_KERNEL_APC1315/// ERROR_KERNEL_APC
878pub const KERNEL_APC = 738;1316pub const KERNEL_APC = 738;
1317
879/// ERROR_ALERTED1318/// ERROR_ALERTED
880pub const ALERTED = 739;1319pub const ALERTED = 739;
1320
881/// The requested operation requires elevation.1321/// The requested operation requires elevation.
882pub const ELEVATION_REQUIRED = 740;1322pub const ELEVATION_REQUIRED = 740;
1323
883/// A reparse should be performed by the Object Manager since the name of the file resulted in a symbolic link.1324/// A reparse should be performed by the Object Manager since the name of the file resulted in a symbolic link.
884pub const REPARSE = 741;1325pub const REPARSE = 741;
1326
885/// An open/create operation completed while an oplock break is underway.1327/// An open/create operation completed while an oplock break is underway.
886pub const OPLOCK_BREAK_IN_PROGRESS = 742;1328pub const OPLOCK_BREAK_IN_PROGRESS = 742;
1329
887/// A new volume has been mounted by a file system.1330/// A new volume has been mounted by a file system.
888pub const VOLUME_MOUNTED = 743;1331pub const VOLUME_MOUNTED = 743;
1332
889/// This success level status indicates that the transaction state already exists for the registry sub-tree, but that a transaction commit was previously aborted. The commit has now been completed.1333/// This success level status indicates that the transaction state already exists for the registry sub-tree, but that a transaction commit was previously aborted. The commit has now been completed.
890pub const RXACT_COMMITTED = 744;1334pub const RXACT_COMMITTED = 744;
1335
891/// This indicates that a notify change request has been completed due to closing the handle which made the notify change request.1336/// This indicates that a notify change request has been completed due to closing the handle which made the notify change request.
892pub const NOTIFY_CLEANUP = 745;1337pub const NOTIFY_CLEANUP = 745;
1338
893/// {Connect Failure on Primary Transport} An attempt was made to connect to the remote server %hs on the primary transport, but the connection failed. The computer WAS able to connect on a secondary transport.1339/// {Connect Failure on Primary Transport} An attempt was made to connect to the remote server %hs on the primary transport, but the connection failed. The computer WAS able to connect on a secondary transport.
894pub const PRIMARY_TRANSPORT_CONNECT_FAILED = 746;1340pub const PRIMARY_TRANSPORT_CONNECT_FAILED = 746;
1341
895/// Page fault was a transition fault.1342/// Page fault was a transition fault.
896pub const PAGE_FAULT_TRANSITION = 747;1343pub const PAGE_FAULT_TRANSITION = 747;
1344
897/// Page fault was a demand zero fault.1345/// Page fault was a demand zero fault.
898pub const PAGE_FAULT_DEMAND_ZERO = 748;1346pub const PAGE_FAULT_DEMAND_ZERO = 748;
1347
899/// Page fault was a demand zero fault.1348/// Page fault was a demand zero fault.
900pub const PAGE_FAULT_COPY_ON_WRITE = 749;1349pub const PAGE_FAULT_COPY_ON_WRITE = 749;
1350
901/// Page fault was a demand zero fault.1351/// Page fault was a demand zero fault.
902pub const PAGE_FAULT_GUARD_PAGE = 750;1352pub const PAGE_FAULT_GUARD_PAGE = 750;
1353
903/// Page fault was satisfied by reading from a secondary storage device.1354/// Page fault was satisfied by reading from a secondary storage device.
904pub const PAGE_FAULT_PAGING_FILE = 751;1355pub const PAGE_FAULT_PAGING_FILE = 751;
1356
905/// Cached page was locked during operation.1357/// Cached page was locked during operation.
906pub const CACHE_PAGE_LOCKED = 752;1358pub const CACHE_PAGE_LOCKED = 752;
1359
907/// Crash dump exists in paging file.1360/// Crash dump exists in paging file.
908pub const CRASH_DUMP = 753;1361pub const CRASH_DUMP = 753;
1362
909/// Specified buffer contains all zeros.1363/// Specified buffer contains all zeros.
910pub const BUFFER_ALL_ZEROS = 754;1364pub const BUFFER_ALL_ZEROS = 754;
1365
911/// A reparse should be performed by the Object Manager since the name of the file resulted in a symbolic link.1366/// A reparse should be performed by the Object Manager since the name of the file resulted in a symbolic link.
912pub const REPARSE_OBJECT = 755;1367pub const REPARSE_OBJECT = 755;
1368
913/// The device has succeeded a query-stop and its resource requirements have changed.1369/// The device has succeeded a query-stop and its resource requirements have changed.
914pub const RESOURCE_REQUIREMENTS_CHANGED = 756;1370pub const RESOURCE_REQUIREMENTS_CHANGED = 756;
1371
915/// The translator has translated these resources into the global space and no further translations should be performed.1372/// The translator has translated these resources into the global space and no further translations should be performed.
916pub const TRANSLATION_COMPLETE = 757;1373pub const TRANSLATION_COMPLETE = 757;
1374
917/// A process being terminated has no threads to terminate.1375/// A process being terminated has no threads to terminate.
918pub const NOTHING_TO_TERMINATE = 758;1376pub const NOTHING_TO_TERMINATE = 758;
1377
919/// The specified process is not part of a job.1378/// The specified process is not part of a job.
920pub const PROCESS_NOT_IN_JOB = 759;1379pub const PROCESS_NOT_IN_JOB = 759;
1380
921/// The specified process is part of a job.1381/// The specified process is part of a job.
922pub const PROCESS_IN_JOB = 760;1382pub const PROCESS_IN_JOB = 760;
1383
923/// {Volume Shadow Copy Service} The system is now ready for hibernation.1384/// {Volume Shadow Copy Service} The system is now ready for hibernation.
924pub const VOLSNAP_HIBERNATE_READY = 761;1385pub const VOLSNAP_HIBERNATE_READY = 761;
1386
925/// A file system or file system filter driver has successfully completed an FsFilter operation.1387/// A file system or file system filter driver has successfully completed an FsFilter operation.
926pub const FSFILTER_OP_COMPLETED_SUCCESSFULLY = 762;1388pub const FSFILTER_OP_COMPLETED_SUCCESSFULLY = 762;
1389
927/// The specified interrupt vector was already connected.1390/// The specified interrupt vector was already connected.
928pub const INTERRUPT_VECTOR_ALREADY_CONNECTED = 763;1391pub const INTERRUPT_VECTOR_ALREADY_CONNECTED = 763;
1392
929/// The specified interrupt vector is still connected.1393/// The specified interrupt vector is still connected.
930pub const INTERRUPT_STILL_CONNECTED = 764;1394pub const INTERRUPT_STILL_CONNECTED = 764;
1395
931/// An operation is blocked waiting for an oplock.1396/// An operation is blocked waiting for an oplock.
932pub const WAIT_FOR_OPLOCK = 765;1397pub const WAIT_FOR_OPLOCK = 765;
1398
933/// Debugger handled exception.1399/// Debugger handled exception.
934pub const DBG_EXCEPTION_HANDLED = 766;1400pub const DBG_EXCEPTION_HANDLED = 766;
1401
935/// Debugger continued.1402/// Debugger continued.
936pub const DBG_CONTINUE = 767;1403pub const DBG_CONTINUE = 767;
1404
937/// An exception occurred in a user mode callback and the kernel callback frame should be removed.1405/// An exception occurred in a user mode callback and the kernel callback frame should be removed.
938pub const CALLBACK_POP_STACK = 768;1406pub const CALLBACK_POP_STACK = 768;
1407
939/// Compression is disabled for this volume.1408/// Compression is disabled for this volume.
940pub const COMPRESSION_DISABLED = 769;1409pub const COMPRESSION_DISABLED = 769;
1410
941/// The data provider cannot fetch backwards through a result set.1411/// The data provider cannot fetch backwards through a result set.
942pub const CANTFETCHBACKWARDS = 770;1412pub const CANTFETCHBACKWARDS = 770;
1413
943/// The data provider cannot scroll backwards through a result set.1414/// The data provider cannot scroll backwards through a result set.
944pub const CANTSCROLLBACKWARDS = 771;1415pub const CANTSCROLLBACKWARDS = 771;
1416
945/// The data provider requires that previously fetched data is released before asking for more data.1417/// The data provider requires that previously fetched data is released before asking for more data.
946pub const ROWSNOTRELEASED = 772;1418pub const ROWSNOTRELEASED = 772;
1419
947/// The data provider was not able to interpret the flags set for a column binding in an accessor.1420/// The data provider was not able to interpret the flags set for a column binding in an accessor.
948pub const BAD_ACCESSOR_FLAGS = 773;1421pub const BAD_ACCESSOR_FLAGS = 773;
1422
949/// One or more errors occurred while processing the request.1423/// One or more errors occurred while processing the request.
950pub const ERRORS_ENCOUNTERED = 774;1424pub const ERRORS_ENCOUNTERED = 774;
1425
951/// The implementation is not capable of performing the request.1426/// The implementation is not capable of performing the request.
952pub const NOT_CAPABLE = 775;1427pub const NOT_CAPABLE = 775;
1428
953/// The client of a component requested an operation which is not valid given the state of the component instance.1429/// The client of a component requested an operation which is not valid given the state of the component instance.
954pub const REQUEST_OUT_OF_SEQUENCE = 776;1430pub const REQUEST_OUT_OF_SEQUENCE = 776;
1431
955/// A version number could not be parsed.1432/// A version number could not be parsed.
956pub const VERSION_PARSE_ERROR = 777;1433pub const VERSION_PARSE_ERROR = 777;
1434
957/// The iterator's start position is invalid.1435/// The iterator's start position is invalid.
958pub const BADSTARTPOSITION = 778;1436pub const BADSTARTPOSITION = 778;
1437
959/// The hardware has reported an uncorrectable memory error.1438/// The hardware has reported an uncorrectable memory error.
960pub const MEMORY_HARDWARE = 779;1439pub const MEMORY_HARDWARE = 779;
1440
961/// The attempted operation required self healing to be enabled.1441/// The attempted operation required self healing to be enabled.
962pub const DISK_REPAIR_DISABLED = 780;1442pub const DISK_REPAIR_DISABLED = 780;
1443
963/// The Desktop heap encountered an error while allocating session memory. There is more information in the system event log.1444/// The Desktop heap encountered an error while allocating session memory. There is more information in the system event log.
964pub const INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE = 781;1445pub const INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE = 781;
1446
965/// The system power state is transitioning from %2 to %3.1447/// The system power state is transitioning from %2 to %3.
966pub const SYSTEM_POWERSTATE_TRANSITION = 782;1448pub const SYSTEM_POWERSTATE_TRANSITION = 782;
1449
967/// The system power state is transitioning from %2 to %3 but could enter %4.1450/// The system power state is transitioning from %2 to %3 but could enter %4.
968pub const SYSTEM_POWERSTATE_COMPLEX_TRANSITION = 783;1451pub const SYSTEM_POWERSTATE_COMPLEX_TRANSITION = 783;
1452
969/// A thread is getting dispatched with MCA EXCEPTION because of MCA.1453/// A thread is getting dispatched with MCA EXCEPTION because of MCA.
970pub const MCA_EXCEPTION = 784;1454pub const MCA_EXCEPTION = 784;
1455
971/// Access to %1 is monitored by policy rule %2.1456/// Access to %1 is monitored by policy rule %2.
972pub const ACCESS_AUDIT_BY_POLICY = 785;1457pub const ACCESS_AUDIT_BY_POLICY = 785;
1458
973/// Access to %1 has been restricted by your Administrator by policy rule %2.1459/// Access to %1 has been restricted by your Administrator by policy rule %2.
974pub const ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY = 786;1460pub const ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY = 786;
1461
975/// A valid hibernation file has been invalidated and should be abandoned.1462/// A valid hibernation file has been invalidated and should be abandoned.
976pub const ABANDON_HIBERFILE = 787;1463pub const ABANDON_HIBERFILE = 787;
1464
977/// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost. This error may be caused by network connectivity issues. Please try to save this file elsewhere.1465/// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost. This error may be caused by network connectivity issues. Please try to save this file elsewhere.
978pub const LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED = 788;1466pub const LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED = 788;
1467
979/// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost. This error was returned by the server on which the file exists. Please try to save this file elsewhere.1468/// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost. This error was returned by the server on which the file exists. Please try to save this file elsewhere.
980pub const LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR = 789;1469pub const LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR = 789;
1470
981/// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost. This error may be caused if the device has been removed or the media is write-protected.1471/// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost. This error may be caused if the device has been removed or the media is write-protected.
982pub const LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR = 790;1472pub const LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR = 790;
1473
983/// The resources required for this device conflict with the MCFG table.1474/// The resources required for this device conflict with the MCFG table.
984pub const BAD_MCFG_TABLE = 791;1475pub const BAD_MCFG_TABLE = 791;
1476
985/// The volume repair could not be performed while it is online. Please schedule to take the volume offline so that it can be repaired.1477/// The volume repair could not be performed while it is online. Please schedule to take the volume offline so that it can be repaired.
986pub const DISK_REPAIR_REDIRECTED = 792;1478pub const DISK_REPAIR_REDIRECTED = 792;
1479
987/// The volume repair was not successful.1480/// The volume repair was not successful.
988pub const DISK_REPAIR_UNSUCCESSFUL = 793;1481pub const DISK_REPAIR_UNSUCCESSFUL = 793;
1482
989/// One of the volume corruption logs is full. Further corruptions that may be detected won't be logged.1483/// One of the volume corruption logs is full. Further corruptions that may be detected won't be logged.
990pub const CORRUPT_LOG_OVERFULL = 794;1484pub const CORRUPT_LOG_OVERFULL = 794;
1485
991/// One of the volume corruption logs is internally corrupted and needs to be recreated. The volume may contain undetected corruptions and must be scanned.1486/// One of the volume corruption logs is internally corrupted and needs to be recreated. The volume may contain undetected corruptions and must be scanned.
992pub const CORRUPT_LOG_CORRUPTED = 795;1487pub const CORRUPT_LOG_CORRUPTED = 795;
1488
993/// One of the volume corruption logs is unavailable for being operated on.1489/// One of the volume corruption logs is unavailable for being operated on.
994pub const CORRUPT_LOG_UNAVAILABLE = 796;1490pub const CORRUPT_LOG_UNAVAILABLE = 796;
1491
995/// One of the volume corruption logs was deleted while still having corruption records in them. The volume contains detected corruptions and must be scanned.1492/// One of the volume corruption logs was deleted while still having corruption records in them. The volume contains detected corruptions and must be scanned.
996pub const CORRUPT_LOG_DELETED_FULL = 797;1493pub const CORRUPT_LOG_DELETED_FULL = 797;
1494
997/// One of the volume corruption logs was cleared by chkdsk and no longer contains real corruptions.1495/// One of the volume corruption logs was cleared by chkdsk and no longer contains real corruptions.
998pub const CORRUPT_LOG_CLEARED = 798;1496pub const CORRUPT_LOG_CLEARED = 798;
1497
999/// Orphaned files exist on the volume but could not be recovered because no more new names could be created in the recovery directory. Files must be moved from the recovery directory.1498/// Orphaned files exist on the volume but could not be recovered because no more new names could be created in the recovery directory. Files must be moved from the recovery directory.
1000pub const ORPHAN_NAME_EXHAUSTED = 799;1499pub const ORPHAN_NAME_EXHAUSTED = 799;
1500
1001/// The oplock that was associated with this handle is now associated with a different handle.1501/// The oplock that was associated with this handle is now associated with a different handle.
1002pub const OPLOCK_SWITCHED_TO_NEW_HANDLE = 800;1502pub const OPLOCK_SWITCHED_TO_NEW_HANDLE = 800;
1503
1003/// An oplock of the requested level cannot be granted. An oplock of a lower level may be available.1504/// An oplock of the requested level cannot be granted. An oplock of a lower level may be available.
1004pub const CANNOT_GRANT_REQUESTED_OPLOCK = 801;1505pub const CANNOT_GRANT_REQUESTED_OPLOCK = 801;
1506
1005/// The operation did not complete successfully because it would cause an oplock to be broken. The caller has requested that existing oplocks not be broken.1507/// The operation did not complete successfully because it would cause an oplock to be broken. The caller has requested that existing oplocks not be broken.
1006pub const CANNOT_BREAK_OPLOCK = 802;1508pub const CANNOT_BREAK_OPLOCK = 802;
1509
1007/// The handle with which this oplock was associated has been closed. The oplock is now broken.1510/// The handle with which this oplock was associated has been closed. The oplock is now broken.
1008pub const OPLOCK_HANDLE_CLOSED = 803;1511pub const OPLOCK_HANDLE_CLOSED = 803;
1512
1009/// The specified access control entry (ACE) does not contain a condition.1513/// The specified access control entry (ACE) does not contain a condition.
1010pub const NO_ACE_CONDITION = 804;1514pub const NO_ACE_CONDITION = 804;
1515
1011/// The specified access control entry (ACE) contains an invalid condition.1516/// The specified access control entry (ACE) contains an invalid condition.
1012pub const INVALID_ACE_CONDITION = 805;1517pub const INVALID_ACE_CONDITION = 805;
1518
1013/// Access to the specified file handle has been revoked.1519/// Access to the specified file handle has been revoked.
1014pub const FILE_HANDLE_REVOKED = 806;1520pub const FILE_HANDLE_REVOKED = 806;
1521
1015/// An image file was mapped at a different address from the one specified in the image file but fixups will still be automatically performed on the image.1522/// An image file was mapped at a different address from the one specified in the image file but fixups will still be automatically performed on the image.
1016pub const IMAGE_AT_DIFFERENT_BASE = 807;1523pub const IMAGE_AT_DIFFERENT_BASE = 807;
1524
1017/// Access to the extended attribute was denied.1525/// Access to the extended attribute was denied.
1018pub const EA_ACCESS_DENIED = 994;1526pub const EA_ACCESS_DENIED = 994;
1527
1019/// The I/O operation has been aborted because of either a thread exit or an application request.1528/// The I/O operation has been aborted because of either a thread exit or an application request.
1020pub const OPERATION_ABORTED = 995;1529pub const OPERATION_ABORTED = 995;
1530
1021/// Overlapped I/O event is not in a signaled state.1531/// Overlapped I/O event is not in a signaled state.
1022pub const IO_INCOMPLETE = 996;1532pub const IO_INCOMPLETE = 996;
1533
1023/// Overlapped I/O operation is in progress.1534/// Overlapped I/O operation is in progress.
1024pub const IO_PENDING = 997;1535pub const IO_PENDING = 997;
1536
1025/// Invalid access to memory location.1537/// Invalid access to memory location.
1026pub const NOACCESS = 998;1538pub const NOACCESS = 998;
1539
1027/// Error performing inpage operation.1540/// Error performing inpage operation.
1028pub const SWAPERROR = 999;1541pub const SWAPERROR = 999;
1542
1029/// Recursion too deep; the stack overflowed.1543/// Recursion too deep; the stack overflowed.
1030pub const STACK_OVERFLOW = 1001;1544pub const STACK_OVERFLOW = 1001;
1545
1031/// The window cannot act on the sent message.1546/// The window cannot act on the sent message.
1032pub const INVALID_MESSAGE = 1002;1547pub const INVALID_MESSAGE = 1002;
1548
1033/// Cannot complete this function.1549/// Cannot complete this function.
1034pub const CAN_NOT_COMPLETE = 1003;1550pub const CAN_NOT_COMPLETE = 1003;
1551
1035/// Invalid flags.1552/// Invalid flags.
1036pub const INVALID_FLAGS = 1004;1553pub const INVALID_FLAGS = 1004;
1554
1037/// The volume does not contain a recognized file system. Please make sure that all required file system drivers are loaded and that the volume is not corrupted.1555/// The volume does not contain a recognized file system. Please make sure that all required file system drivers are loaded and that the volume is not corrupted.
1038pub const UNRECOGNIZED_VOLUME = 1005;1556pub const UNRECOGNIZED_VOLUME = 1005;
1557
1039/// The volume for a file has been externally altered so that the opened file is no longer valid.1558/// The volume for a file has been externally altered so that the opened file is no longer valid.
1040pub const FILE_INVALID = 1006;1559pub const FILE_INVALID = 1006;
1560
1041/// The requested operation cannot be performed in full-screen mode.1561/// The requested operation cannot be performed in full-screen mode.
1042pub const FULLSCREEN_MODE = 1007;1562pub const FULLSCREEN_MODE = 1007;
1563
1043/// An attempt was made to reference a token that does not exist.1564/// An attempt was made to reference a token that does not exist.
1044pub const NO_TOKEN = 1008;1565pub const NO_TOKEN = 1008;
1566
1045/// The configuration registry database is corrupt.1567/// The configuration registry database is corrupt.
1046pub const BADDB = 1009;1568pub const BADDB = 1009;
1569
1047/// The configuration registry key is invalid.1570/// The configuration registry key is invalid.
1048pub const BADKEY = 1010;1571pub const BADKEY = 1010;
1572
1049/// The configuration registry key could not be opened.1573/// The configuration registry key could not be opened.
1050pub const CANTOPEN = 1011;1574pub const CANTOPEN = 1011;
1575
1051/// The configuration registry key could not be read.1576/// The configuration registry key could not be read.
1052pub const CANTREAD = 1012;1577pub const CANTREAD = 1012;
1578
1053/// The configuration registry key could not be written.1579/// The configuration registry key could not be written.
1054pub const CANTWRITE = 1013;1580pub const CANTWRITE = 1013;
1581
1055/// One of the files in the registry database had to be recovered by use of a log or alternate copy. The recovery was successful.1582/// One of the files in the registry database had to be recovered by use of a log or alternate copy. The recovery was successful.
1056pub const REGISTRY_RECOVERED = 1014;1583pub const REGISTRY_RECOVERED = 1014;
1584
1057/// The registry is corrupted. The structure of one of the files containing registry data is corrupted, or the system's memory image of the file is corrupted, or the file could not be recovered because the alternate copy or log was absent or corrupted.1585/// The registry is corrupted. The structure of one of the files containing registry data is corrupted, or the system's memory image of the file is corrupted, or the file could not be recovered because the alternate copy or log was absent or corrupted.
1058pub const REGISTRY_CORRUPT = 1015;1586pub const REGISTRY_CORRUPT = 1015;
1587
1059/// An I/O operation initiated by the registry failed unrecoverably. The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry.1588/// An I/O operation initiated by the registry failed unrecoverably. The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry.
1060pub const REGISTRY_IO_FAILED = 1016;1589pub const REGISTRY_IO_FAILED = 1016;
1590
1061/// The system has attempted to load or restore a file into the registry, but the specified file is not in a registry file format.1591/// The system has attempted to load or restore a file into the registry, but the specified file is not in a registry file format.
1062pub const NOT_REGISTRY_FILE = 1017;1592pub const NOT_REGISTRY_FILE = 1017;
1593
1063/// Illegal operation attempted on a registry key that has been marked for deletion.1594/// Illegal operation attempted on a registry key that has been marked for deletion.
1064pub const KEY_DELETED = 1018;1595pub const KEY_DELETED = 1018;
1596
1065/// System could not allocate the required space in a registry log.1597/// System could not allocate the required space in a registry log.
1066pub const NO_LOG_SPACE = 1019;1598pub const NO_LOG_SPACE = 1019;
1599
1067/// Cannot create a symbolic link in a registry key that already has subkeys or values.1600/// Cannot create a symbolic link in a registry key that already has subkeys or values.
1068pub const KEY_HAS_CHILDREN = 1020;1601pub const KEY_HAS_CHILDREN = 1020;
1602
1069/// Cannot create a stable subkey under a volatile parent key.1603/// Cannot create a stable subkey under a volatile parent key.
1070pub const CHILD_MUST_BE_VOLATILE = 1021;1604pub const CHILD_MUST_BE_VOLATILE = 1021;
1605
1071/// A notify change request is being completed and the information is not being returned in the caller's buffer. The caller now needs to enumerate the files to find the changes.1606/// A notify change request is being completed and the information is not being returned in the caller's buffer. The caller now needs to enumerate the files to find the changes.
1072pub const NOTIFY_ENUM_DIR = 1022;1607pub const NOTIFY_ENUM_DIR = 1022;
1608
1073/// A stop control has been sent to a service that other running services are dependent on.1609/// A stop control has been sent to a service that other running services are dependent on.
1074pub const DEPENDENT_SERVICES_RUNNING = 1051;1610pub const DEPENDENT_SERVICES_RUNNING = 1051;
1611
1075/// The requested control is not valid for this service.1612/// The requested control is not valid for this service.
1076pub const INVALID_SERVICE_CONTROL = 1052;1613pub const INVALID_SERVICE_CONTROL = 1052;
1614
1077/// The service did not respond to the start or control request in a timely fashion.1615/// The service did not respond to the start or control request in a timely fashion.
1078pub const SERVICE_REQUEST_TIMEOUT = 1053;1616pub const SERVICE_REQUEST_TIMEOUT = 1053;
1617
1079/// A thread could not be created for the service.1618/// A thread could not be created for the service.
1080pub const SERVICE_NO_THREAD = 1054;1619pub const SERVICE_NO_THREAD = 1054;
1620
1081/// The service database is locked.1621/// The service database is locked.
1082pub const SERVICE_DATABASE_LOCKED = 1055;1622pub const SERVICE_DATABASE_LOCKED = 1055;
1623
1083/// An instance of the service is already running.1624/// An instance of the service is already running.
1084pub const SERVICE_ALREADY_RUNNING = 1056;1625pub const SERVICE_ALREADY_RUNNING = 1056;
1626
1085/// The account name is invalid or does not exist, or the password is invalid for the account name specified.1627/// The account name is invalid or does not exist, or the password is invalid for the account name specified.
1086pub const INVALID_SERVICE_ACCOUNT = 1057;1628pub const INVALID_SERVICE_ACCOUNT = 1057;
1629
1087/// The service cannot be started, either because it is disabled or because it has no enabled devices associated with it.1630/// The service cannot be started, either because it is disabled or because it has no enabled devices associated with it.
1088pub const SERVICE_DISABLED = 1058;1631pub const SERVICE_DISABLED = 1058;
1632
1089/// Circular service dependency was specified.1633/// Circular service dependency was specified.
1090pub const CIRCULAR_DEPENDENCY = 1059;1634pub const CIRCULAR_DEPENDENCY = 1059;
1635
1091/// The specified service does not exist as an installed service.1636/// The specified service does not exist as an installed service.
1092pub const SERVICE_DOES_NOT_EXIST = 1060;1637pub const SERVICE_DOES_NOT_EXIST = 1060;
1638
1093/// The service cannot accept control messages at this time.1639/// The service cannot accept control messages at this time.
1094pub const SERVICE_CANNOT_ACCEPT_CTRL = 1061;1640pub const SERVICE_CANNOT_ACCEPT_CTRL = 1061;
1641
1095/// The service has not been started.1642/// The service has not been started.
1096pub const SERVICE_NOT_ACTIVE = 1062;1643pub const SERVICE_NOT_ACTIVE = 1062;
1644
1097/// The service process could not connect to the service controller.1645/// The service process could not connect to the service controller.
1098pub const FAILED_SERVICE_CONTROLLER_CONNECT = 1063;1646pub const FAILED_SERVICE_CONTROLLER_CONNECT = 1063;
1647
1099/// An exception occurred in the service when handling the control request.1648/// An exception occurred in the service when handling the control request.
1100pub const EXCEPTION_IN_SERVICE = 1064;1649pub const EXCEPTION_IN_SERVICE = 1064;
1650
1101/// The database specified does not exist.1651/// The database specified does not exist.
1102pub const DATABASE_DOES_NOT_EXIST = 1065;1652pub const DATABASE_DOES_NOT_EXIST = 1065;
1653
1103/// The service has returned a service-specific error code.1654/// The service has returned a service-specific error code.
1104pub const SERVICE_SPECIFIC_ERROR = 1066;1655pub const SERVICE_SPECIFIC_ERROR = 1066;
1656
1105/// The process terminated unexpectedly.1657/// The process terminated unexpectedly.
1106pub const PROCESS_ABORTED = 1067;1658pub const PROCESS_ABORTED = 1067;
1659
1107/// The dependency service or group failed to start.1660/// The dependency service or group failed to start.
1108pub const SERVICE_DEPENDENCY_FAIL = 1068;1661pub const SERVICE_DEPENDENCY_FAIL = 1068;
1662
1109/// The service did not start due to a logon failure.1663/// The service did not start due to a logon failure.
1110pub const SERVICE_LOGON_FAILED = 1069;1664pub const SERVICE_LOGON_FAILED = 1069;
1665
1111/// After starting, the service hung in a start-pending state.1666/// After starting, the service hung in a start-pending state.
1112pub const SERVICE_START_HANG = 1070;1667pub const SERVICE_START_HANG = 1070;
1668
1113/// The specified service database lock is invalid.1669/// The specified service database lock is invalid.
1114pub const INVALID_SERVICE_LOCK = 1071;1670pub const INVALID_SERVICE_LOCK = 1071;
1671
1115/// The specified service has been marked for deletion.1672/// The specified service has been marked for deletion.
1116pub const SERVICE_MARKED_FOR_DELETE = 1072;1673pub const SERVICE_MARKED_FOR_DELETE = 1072;
1674
1117/// The specified service already exists.1675/// The specified service already exists.
1118pub const SERVICE_EXISTS = 1073;1676pub const SERVICE_EXISTS = 1073;
1677
1119/// The system is currently running with the last-known-good configuration.1678/// The system is currently running with the last-known-good configuration.
1120pub const ALREADY_RUNNING_LKG = 1074;1679pub const ALREADY_RUNNING_LKG = 1074;
1680
1121/// The dependency service does not exist or has been marked for deletion.1681/// The dependency service does not exist or has been marked for deletion.
1122pub const SERVICE_DEPENDENCY_DELETED = 1075;1682pub const SERVICE_DEPENDENCY_DELETED = 1075;
1683
1123/// The current boot has already been accepted for use as the last-known-good control set.1684/// The current boot has already been accepted for use as the last-known-good control set.
1124pub const BOOT_ALREADY_ACCEPTED = 1076;1685pub const BOOT_ALREADY_ACCEPTED = 1076;
1686
1125/// No attempts to start the service have been made since the last boot.1687/// No attempts to start the service have been made since the last boot.
1126pub const SERVICE_NEVER_STARTED = 1077;1688pub const SERVICE_NEVER_STARTED = 1077;
1689
1127/// The name is already in use as either a service name or a service display name.1690/// The name is already in use as either a service name or a service display name.
1128pub const DUPLICATE_SERVICE_NAME = 1078;1691pub const DUPLICATE_SERVICE_NAME = 1078;
1692
1129/// The account specified for this service is different from the account specified for other services running in the same process.1693/// The account specified for this service is different from the account specified for other services running in the same process.
1130pub const DIFFERENT_SERVICE_ACCOUNT = 1079;1694pub const DIFFERENT_SERVICE_ACCOUNT = 1079;
1695
1131/// Failure actions can only be set for Win32 services, not for drivers.1696/// Failure actions can only be set for Win32 services, not for drivers.
1132pub const CANNOT_DETECT_DRIVER_FAILURE = 1080;1697pub const CANNOT_DETECT_DRIVER_FAILURE = 1080;
1698
1133/// This service runs in the same process as the service control manager. Therefore, the service control manager cannot take action if this service's process terminates unexpectedly.1699/// This service runs in the same process as the service control manager. Therefore, the service control manager cannot take action if this service's process terminates unexpectedly.
1134pub const CANNOT_DETECT_PROCESS_ABORT = 1081;1700pub const CANNOT_DETECT_PROCESS_ABORT = 1081;
1701
1135/// No recovery program has been configured for this service.1702/// No recovery program has been configured for this service.
1136pub const NO_RECOVERY_PROGRAM = 1082;1703pub const NO_RECOVERY_PROGRAM = 1082;
1704
1137/// The executable program that this service is configured to run in does not implement the service.1705/// The executable program that this service is configured to run in does not implement the service.
1138pub const SERVICE_NOT_IN_EXE = 1083;1706pub const SERVICE_NOT_IN_EXE = 1083;
1707
1139/// This service cannot be started in Safe Mode.1708/// This service cannot be started in Safe Mode.
1140pub const NOT_SAFEBOOT_SERVICE = 1084;1709pub const NOT_SAFEBOOT_SERVICE = 1084;
1710
1141/// The physical end of the tape has been reached.1711/// The physical end of the tape has been reached.
1142pub const END_OF_MEDIA = 1100;1712pub const END_OF_MEDIA = 1100;
1713
1143/// A tape access reached a filemark.1714/// A tape access reached a filemark.
1144pub const FILEMARK_DETECTED = 1101;1715pub const FILEMARK_DETECTED = 1101;
1716
1145/// The beginning of the tape or a partition was encountered.1717/// The beginning of the tape or a partition was encountered.
1146pub const BEGINNING_OF_MEDIA = 1102;1718pub const BEGINNING_OF_MEDIA = 1102;
1719
1147/// A tape access reached the end of a set of files.1720/// A tape access reached the end of a set of files.
1148pub const SETMARK_DETECTED = 1103;1721pub const SETMARK_DETECTED = 1103;
1722
1149/// No more data is on the tape.1723/// No more data is on the tape.
1150pub const NO_DATA_DETECTED = 1104;1724pub const NO_DATA_DETECTED = 1104;
1725
1151/// Tape could not be partitioned.1726/// Tape could not be partitioned.
1152pub const PARTITION_FAILURE = 1105;1727pub const PARTITION_FAILURE = 1105;
1728
1153/// When accessing a new tape of a multivolume partition, the current block size is incorrect.1729/// When accessing a new tape of a multivolume partition, the current block size is incorrect.
1154pub const INVALID_BLOCK_LENGTH = 1106;1730pub const INVALID_BLOCK_LENGTH = 1106;
1731
1155/// Tape partition information could not be found when loading a tape.1732/// Tape partition information could not be found when loading a tape.
1156pub const DEVICE_NOT_PARTITIONED = 1107;1733pub const DEVICE_NOT_PARTITIONED = 1107;
1734
1157/// Unable to lock the media eject mechanism.1735/// Unable to lock the media eject mechanism.
1158pub const UNABLE_TO_LOCK_MEDIA = 1108;1736pub const UNABLE_TO_LOCK_MEDIA = 1108;
1737
1159/// Unable to unload the media.1738/// Unable to unload the media.
1160pub const UNABLE_TO_UNLOAD_MEDIA = 1109;1739pub const UNABLE_TO_UNLOAD_MEDIA = 1109;
1740
1161/// The media in the drive may have changed.1741/// The media in the drive may have changed.
1162pub const MEDIA_CHANGED = 1110;1742pub const MEDIA_CHANGED = 1110;
1743
1163/// The I/O bus was reset.1744/// The I/O bus was reset.
1164pub const BUS_RESET = 1111;1745pub const BUS_RESET = 1111;
1746
1165/// No media in drive.1747/// No media in drive.
1166pub const NO_MEDIA_IN_DRIVE = 1112;1748pub const NO_MEDIA_IN_DRIVE = 1112;
1749
1167/// No mapping for the Unicode character exists in the target multi-byte code page.1750/// No mapping for the Unicode character exists in the target multi-byte code page.
1168pub const NO_UNICODE_TRANSLATION = 1113;1751pub const NO_UNICODE_TRANSLATION = 1113;
1752
1169/// A dynamic link library (DLL) initialization routine failed.1753/// A dynamic link library (DLL) initialization routine failed.
1170pub const DLL_INIT_FAILED = 1114;1754pub const DLL_INIT_FAILED = 1114;
1755
1171/// A system shutdown is in progress.1756/// A system shutdown is in progress.
1172pub const SHUTDOWN_IN_PROGRESS = 1115;1757pub const SHUTDOWN_IN_PROGRESS = 1115;
1758
1173/// Unable to abort the system shutdown because no shutdown was in progress.1759/// Unable to abort the system shutdown because no shutdown was in progress.
1174pub const NO_SHUTDOWN_IN_PROGRESS = 1116;1760pub const NO_SHUTDOWN_IN_PROGRESS = 1116;
1761
1175/// The request could not be performed because of an I/O device error.1762/// The request could not be performed because of an I/O device error.
1176pub const IO_DEVICE = 1117;1763pub const IO_DEVICE = 1117;
1764
1177/// No serial device was successfully initialized. The serial driver will unload.1765/// No serial device was successfully initialized. The serial driver will unload.
1178pub const SERIAL_NO_DEVICE = 1118;1766pub const SERIAL_NO_DEVICE = 1118;
1767
1179/// Unable to open a device that was sharing an interrupt request (IRQ) with other devices. At least one other device that uses that IRQ was already opened.1768/// Unable to open a device that was sharing an interrupt request (IRQ) with other devices. At least one other device that uses that IRQ was already opened.
1180pub const IRQ_BUSY = 1119;1769pub const IRQ_BUSY = 1119;
1770
1181/// A serial I/O operation was completed by another write to the serial port. The IOCTL_SERIAL_XOFF_COUNTER reached zero.)1771/// A serial I/O operation was completed by another write to the serial port. The IOCTL_SERIAL_XOFF_COUNTER reached zero.)
1182pub const MORE_WRITES = 1120;1772pub const MORE_WRITES = 1120;
1773
1183/// A serial I/O operation completed because the timeout period expired. The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.)1774/// A serial I/O operation completed because the timeout period expired. The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.)
1184pub const COUNTER_TIMEOUT = 1121;1775pub const COUNTER_TIMEOUT = 1121;
1776
1185/// No ID address mark was found on the floppy disk.1777/// No ID address mark was found on the floppy disk.
1186pub const FLOPPY_ID_MARK_NOT_FOUND = 1122;1778pub const FLOPPY_ID_MARK_NOT_FOUND = 1122;
1779
1187/// Mismatch between the floppy disk sector ID field and the floppy disk controller track address.1780/// Mismatch between the floppy disk sector ID field and the floppy disk controller track address.
1188pub const FLOPPY_WRONG_CYLINDER = 1123;1781pub const FLOPPY_WRONG_CYLINDER = 1123;
1782
1189/// The floppy disk controller reported an error that is not recognized by the floppy disk driver.1783/// The floppy disk controller reported an error that is not recognized by the floppy disk driver.
1190pub const FLOPPY_UNKNOWN_ERROR = 1124;1784pub const FLOPPY_UNKNOWN_ERROR = 1124;
1785
1191/// The floppy disk controller returned inconsistent results in its registers.1786/// The floppy disk controller returned inconsistent results in its registers.
1192pub const FLOPPY_BAD_REGISTERS = 1125;1787pub const FLOPPY_BAD_REGISTERS = 1125;
1788
1193/// While accessing the hard disk, a recalibrate operation failed, even after retries.1789/// While accessing the hard disk, a recalibrate operation failed, even after retries.
1194pub const DISK_RECALIBRATE_FAILED = 1126;1790pub const DISK_RECALIBRATE_FAILED = 1126;
1791
1195/// While accessing the hard disk, a disk operation failed even after retries.1792/// While accessing the hard disk, a disk operation failed even after retries.
1196pub const DISK_OPERATION_FAILED = 1127;1793pub const DISK_OPERATION_FAILED = 1127;
1794
1197/// While accessing the hard disk, a disk controller reset was needed, but even that failed.1795/// While accessing the hard disk, a disk controller reset was needed, but even that failed.
1198pub const DISK_RESET_FAILED = 1128;1796pub const DISK_RESET_FAILED = 1128;
1797
1199/// Physical end of tape encountered.1798/// Physical end of tape encountered.
1200pub const EOM_OVERFLOW = 1129;1799pub const EOM_OVERFLOW = 1129;
1800
1201/// Not enough server storage is available to process this command.1801/// Not enough server storage is available to process this command.
1202pub const NOT_ENOUGH_SERVER_MEMORY = 1130;1802pub const NOT_ENOUGH_SERVER_MEMORY = 1130;
1803
1203/// A potential deadlock condition has been detected.1804/// A potential deadlock condition has been detected.
1204pub const POSSIBLE_DEADLOCK = 1131;1805pub const POSSIBLE_DEADLOCK = 1131;
1806
1205/// The base address or the file offset specified does not have the proper alignment.1807/// The base address or the file offset specified does not have the proper alignment.
1206pub const MAPPED_ALIGNMENT = 1132;1808pub const MAPPED_ALIGNMENT = 1132;
1809
1207/// An attempt to change the system power state was vetoed by another application or driver.1810/// An attempt to change the system power state was vetoed by another application or driver.
1208pub const SET_POWER_STATE_VETOED = 1140;1811pub const SET_POWER_STATE_VETOED = 1140;
1812
1209/// The system BIOS failed an attempt to change the system power state.1813/// The system BIOS failed an attempt to change the system power state.
1210pub const SET_POWER_STATE_FAILED = 1141;1814pub const SET_POWER_STATE_FAILED = 1141;
1815
1211/// An attempt was made to create more links on a file than the file system supports.1816/// An attempt was made to create more links on a file than the file system supports.
1212pub const TOO_MANY_LINKS = 1142;1817pub const TOO_MANY_LINKS = 1142;
1818
1213/// The specified program requires a newer version of Windows.1819/// The specified program requires a newer version of Windows.
1214pub const OLD_WIN_VERSION = 1150;1820pub const OLD_WIN_VERSION = 1150;
1821
1215/// The specified program is not a Windows or MS-DOS program.1822/// The specified program is not a Windows or MS-DOS program.
1216pub const APP_WRONG_OS = 1151;1823pub const APP_WRONG_OS = 1151;
1824
1217/// Cannot start more than one instance of the specified program.1825/// Cannot start more than one instance of the specified program.
1218pub const SINGLE_INSTANCE_APP = 1152;1826pub const SINGLE_INSTANCE_APP = 1152;
1827
1219/// The specified program was written for an earlier version of Windows.1828/// The specified program was written for an earlier version of Windows.
1220pub const RMODE_APP = 1153;1829pub const RMODE_APP = 1153;
1830
1221/// One of the library files needed to run this application is damaged.1831/// One of the library files needed to run this application is damaged.
1222pub const INVALID_DLL = 1154;1832pub const INVALID_DLL = 1154;
1833
1223/// No application is associated with the specified file for this operation.1834/// No application is associated with the specified file for this operation.
1224pub const NO_ASSOCIATION = 1155;1835pub const NO_ASSOCIATION = 1155;
1836
1225/// An error occurred in sending the command to the application.1837/// An error occurred in sending the command to the application.
1226pub const DDE_FAIL = 1156;1838pub const DDE_FAIL = 1156;
1839
1227/// One of the library files needed to run this application cannot be found.1840/// One of the library files needed to run this application cannot be found.
1228pub const DLL_NOT_FOUND = 1157;1841pub const DLL_NOT_FOUND = 1157;
1842
1229/// The current process has used all of its system allowance of handles for Window Manager objects.1843/// The current process has used all of its system allowance of handles for Window Manager objects.
1230pub const NO_MORE_USER_HANDLES = 1158;1844pub const NO_MORE_USER_HANDLES = 1158;
1845
1231/// The message can be used only with synchronous operations.1846/// The message can be used only with synchronous operations.
1232pub const MESSAGE_SYNC_ONLY = 1159;1847pub const MESSAGE_SYNC_ONLY = 1159;
1848
1233/// The indicated source element has no media.1849/// The indicated source element has no media.
1234pub const SOURCE_ELEMENT_EMPTY = 1160;1850pub const SOURCE_ELEMENT_EMPTY = 1160;
1851
1235/// The indicated destination element already contains media.1852/// The indicated destination element already contains media.
1236pub const DESTINATION_ELEMENT_FULL = 1161;1853pub const DESTINATION_ELEMENT_FULL = 1161;
1854
1237/// The indicated element does not exist.1855/// The indicated element does not exist.
1238pub const ILLEGAL_ELEMENT_ADDRESS = 1162;1856pub const ILLEGAL_ELEMENT_ADDRESS = 1162;
1857
1239/// The indicated element is part of a magazine that is not present.1858/// The indicated element is part of a magazine that is not present.
1240pub const MAGAZINE_NOT_PRESENT = 1163;1859pub const MAGAZINE_NOT_PRESENT = 1163;
1860
1241/// The indicated device requires reinitialization due to hardware errors.1861/// The indicated device requires reinitialization due to hardware errors.
1242pub const DEVICE_REINITIALIZATION_NEEDED = 1164;1862pub const DEVICE_REINITIALIZATION_NEEDED = 1164;
1863
1243/// The device has indicated that cleaning is required before further operations are attempted.1864/// The device has indicated that cleaning is required before further operations are attempted.
1244pub const DEVICE_REQUIRES_CLEANING = 1165;1865pub const DEVICE_REQUIRES_CLEANING = 1165;
1866
1245/// The device has indicated that its door is open.1867/// The device has indicated that its door is open.
1246pub const DEVICE_DOOR_OPEN = 1166;1868pub const DEVICE_DOOR_OPEN = 1166;
1869
1247/// The device is not connected.1870/// The device is not connected.
1248pub const DEVICE_NOT_CONNECTED = 1167;1871pub const DEVICE_NOT_CONNECTED = 1167;
1872
1249/// Element not found.1873/// Element not found.
1250pub const NOT_FOUND = 1168;1874pub const NOT_FOUND = 1168;
1875
1251/// There was no match for the specified key in the index.1876/// There was no match for the specified key in the index.
1252pub const NO_MATCH = 1169;1877pub const NO_MATCH = 1169;
1878
1253/// The property set specified does not exist on the object.1879/// The property set specified does not exist on the object.
1254pub const SET_NOT_FOUND = 1170;1880pub const SET_NOT_FOUND = 1170;
1881
1255/// The point passed to GetMouseMovePoints is not in the buffer.1882/// The point passed to GetMouseMovePoints is not in the buffer.
1256pub const POINT_NOT_FOUND = 1171;1883pub const POINT_NOT_FOUND = 1171;
1884
1257/// The tracking (workstation) service is not running.1885/// The tracking (workstation) service is not running.
1258pub const NO_TRACKING_SERVICE = 1172;1886pub const NO_TRACKING_SERVICE = 1172;
1887
1259/// The Volume ID could not be found.1888/// The Volume ID could not be found.
1260pub const NO_VOLUME_ID = 1173;1889pub const NO_VOLUME_ID = 1173;
1890
1261/// Unable to remove the file to be replaced.1891/// Unable to remove the file to be replaced.
1262pub const UNABLE_TO_REMOVE_REPLACED = 1175;1892pub const UNABLE_TO_REMOVE_REPLACED = 1175;
1893
1263/// Unable to move the replacement file to the file to be replaced. The file to be replaced has retained its original name.1894/// Unable to move the replacement file to the file to be replaced. The file to be replaced has retained its original name.
1264pub const UNABLE_TO_MOVE_REPLACEMENT = 1176;1895pub const UNABLE_TO_MOVE_REPLACEMENT = 1176;
1896
1265/// Unable to move the replacement file to the file to be replaced. The file to be replaced has been renamed using the backup name.1897/// Unable to move the replacement file to the file to be replaced. The file to be replaced has been renamed using the backup name.
1266pub const UNABLE_TO_MOVE_REPLACEMENT_2 = 1177;1898pub const UNABLE_TO_MOVE_REPLACEMENT_2 = 1177;
1899
1267/// The volume change journal is being deleted.1900/// The volume change journal is being deleted.
1268pub const JOURNAL_DELETE_IN_PROGRESS = 1178;1901pub const JOURNAL_DELETE_IN_PROGRESS = 1178;
1902
1269/// The volume change journal is not active.1903/// The volume change journal is not active.
1270pub const JOURNAL_NOT_ACTIVE = 1179;1904pub const JOURNAL_NOT_ACTIVE = 1179;
1905
1271/// A file was found, but it may not be the correct file.1906/// A file was found, but it may not be the correct file.
1272pub const POTENTIAL_FILE_FOUND = 1180;1907pub const POTENTIAL_FILE_FOUND = 1180;
1908
1273/// The journal entry has been deleted from the journal.1909/// The journal entry has been deleted from the journal.
1274pub const JOURNAL_ENTRY_DELETED = 1181;1910pub const JOURNAL_ENTRY_DELETED = 1181;
1911
1275/// A system shutdown has already been scheduled.1912/// A system shutdown has already been scheduled.
1276pub const SHUTDOWN_IS_SCHEDULED = 1190;1913pub const SHUTDOWN_IS_SCHEDULED = 1190;
1914
1277/// The system shutdown cannot be initiated because there are other users logged on to the computer.1915/// The system shutdown cannot be initiated because there are other users logged on to the computer.
1278pub const SHUTDOWN_USERS_LOGGED_ON = 1191;1916pub const SHUTDOWN_USERS_LOGGED_ON = 1191;
1917
1279/// The specified device name is invalid.1918/// The specified device name is invalid.
1280pub const BAD_DEVICE = 1200;1919pub const BAD_DEVICE = 1200;
1920
1281/// The device is not currently connected but it is a remembered connection.1921/// The device is not currently connected but it is a remembered connection.
1282pub const CONNECTION_UNAVAIL = 1201;1922pub const CONNECTION_UNAVAIL = 1201;
1923
1283/// The local device name has a remembered connection to another network resource.1924/// The local device name has a remembered connection to another network resource.
1284pub const DEVICE_ALREADY_REMEMBERED = 1202;1925pub const DEVICE_ALREADY_REMEMBERED = 1202;
1926
1285/// The network path was either typed incorrectly, does not exist, or the network provider is not currently available. Please try retyping the path or contact your network administrator.1927/// The network path was either typed incorrectly, does not exist, or the network provider is not currently available. Please try retyping the path or contact your network administrator.
1286pub const NO_NET_OR_BAD_PATH = 1203;1928pub const NO_NET_OR_BAD_PATH = 1203;
1929
1287/// The specified network provider name is invalid.1930/// The specified network provider name is invalid.
1288pub const BAD_PROVIDER = 1204;1931pub const BAD_PROVIDER = 1204;
1932
1289/// Unable to open the network connection profile.1933/// Unable to open the network connection profile.
1290pub const CANNOT_OPEN_PROFILE = 1205;1934pub const CANNOT_OPEN_PROFILE = 1205;
1935
1291/// The network connection profile is corrupted.1936/// The network connection profile is corrupted.
1292pub const BAD_PROFILE = 1206;1937pub const BAD_PROFILE = 1206;
1938
1293/// Cannot enumerate a noncontainer.1939/// Cannot enumerate a noncontainer.
1294pub const NOT_CONTAINER = 1207;1940pub const NOT_CONTAINER = 1207;
1941
1295/// An extended error has occurred.1942/// An extended error has occurred.
1296pub const EXTENDED_ERROR = 1208;1943pub const EXTENDED_ERROR = 1208;
1944
1297/// The format of the specified group name is invalid.1945/// The format of the specified group name is invalid.
1298pub const INVALID_GROUPNAME = 1209;1946pub const INVALID_GROUPNAME = 1209;
1947
1299/// The format of the specified computer name is invalid.1948/// The format of the specified computer name is invalid.
1300pub const INVALID_COMPUTERNAME = 1210;1949pub const INVALID_COMPUTERNAME = 1210;
1950
1301/// The format of the specified event name is invalid.1951/// The format of the specified event name is invalid.
1302pub const INVALID_EVENTNAME = 1211;1952pub const INVALID_EVENTNAME = 1211;
1953
1303/// The format of the specified domain name is invalid.1954/// The format of the specified domain name is invalid.
1304pub const INVALID_DOMAINNAME = 1212;1955pub const INVALID_DOMAINNAME = 1212;
1956
1305/// The format of the specified service name is invalid.1957/// The format of the specified service name is invalid.
1306pub const INVALID_SERVICENAME = 1213;1958pub const INVALID_SERVICENAME = 1213;
1959
1307/// The format of the specified network name is invalid.1960/// The format of the specified network name is invalid.
1308pub const INVALID_NETNAME = 1214;1961pub const INVALID_NETNAME = 1214;
1962
1309/// The format of the specified share name is invalid.1963/// The format of the specified share name is invalid.
1310pub const INVALID_SHARENAME = 1215;1964pub const INVALID_SHARENAME = 1215;
1965
1311/// The format of the specified password is invalid.1966/// The format of the specified password is invalid.
1312pub const INVALID_PASSWORDNAME = 1216;1967pub const INVALID_PASSWORDNAME = 1216;
1968
1313/// The format of the specified message name is invalid.1969/// The format of the specified message name is invalid.
1314pub const INVALID_MESSAGENAME = 1217;1970pub const INVALID_MESSAGENAME = 1217;
1971
1315/// The format of the specified message destination is invalid.1972/// The format of the specified message destination is invalid.
1316pub const INVALID_MESSAGEDEST = 1218;1973pub const INVALID_MESSAGEDEST = 1218;
1974
1317/// Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.1975/// Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.
1318pub const SESSION_CREDENTIAL_CONFLICT = 1219;1976pub const SESSION_CREDENTIAL_CONFLICT = 1219;
1977
1319/// An attempt was made to establish a session to a network server, but there are already too many sessions established to that server.1978/// An attempt was made to establish a session to a network server, but there are already too many sessions established to that server.
1320pub const REMOTE_SESSION_LIMIT_EXCEEDED = 1220;1979pub const REMOTE_SESSION_LIMIT_EXCEEDED = 1220;
1980
1321/// The workgroup or domain name is already in use by another computer on the network.1981/// The workgroup or domain name is already in use by another computer on the network.
1322pub const DUP_DOMAINNAME = 1221;1982pub const DUP_DOMAINNAME = 1221;
1983
1323/// The network is not present or not started.1984/// The network is not present or not started.
1324pub const NO_NETWORK = 1222;1985pub const NO_NETWORK = 1222;
1986
1325/// The operation was canceled by the user.1987/// The operation was canceled by the user.
1326pub const CANCELLED = 1223;1988pub const CANCELLED = 1223;
1989
1327/// The requested operation cannot be performed on a file with a user-mapped section open.1990/// The requested operation cannot be performed on a file with a user-mapped section open.
1328pub const USER_MAPPED_FILE = 1224;1991pub const USER_MAPPED_FILE = 1224;
1992
1329/// The remote computer refused the network connection.1993/// The remote computer refused the network connection.
1330pub const CONNECTION_REFUSED = 1225;1994pub const CONNECTION_REFUSED = 1225;
1995
1331/// The network connection was gracefully closed.1996/// The network connection was gracefully closed.
1332pub const GRACEFUL_DISCONNECT = 1226;1997pub const GRACEFUL_DISCONNECT = 1226;
1998
1333/// The network transport endpoint already has an address associated with it.1999/// The network transport endpoint already has an address associated with it.
1334pub const ADDRESS_ALREADY_ASSOCIATED = 1227;2000pub const ADDRESS_ALREADY_ASSOCIATED = 1227;
2001
1335/// An address has not yet been associated with the network endpoint.2002/// An address has not yet been associated with the network endpoint.
1336pub const ADDRESS_NOT_ASSOCIATED = 1228;2003pub const ADDRESS_NOT_ASSOCIATED = 1228;
2004
1337/// An operation was attempted on a nonexistent network connection.2005/// An operation was attempted on a nonexistent network connection.
1338pub const CONNECTION_INVALID = 1229;2006pub const CONNECTION_INVALID = 1229;
2007
1339/// An invalid operation was attempted on an active network connection.2008/// An invalid operation was attempted on an active network connection.
1340pub const CONNECTION_ACTIVE = 1230;2009pub const CONNECTION_ACTIVE = 1230;
2010
1341/// The network location cannot be reached. For information about network troubleshooting, see Windows Help.2011/// The network location cannot be reached. For information about network troubleshooting, see Windows Help.
1342pub const NETWORK_UNREACHABLE = 1231;2012pub const NETWORK_UNREACHABLE = 1231;
2013
1343/// The network location cannot be reached. For information about network troubleshooting, see Windows Help.2014/// The network location cannot be reached. For information about network troubleshooting, see Windows Help.
1344pub const HOST_UNREACHABLE = 1232;2015pub const HOST_UNREACHABLE = 1232;
2016
1345/// The network location cannot be reached. For information about network troubleshooting, see Windows Help.2017/// The network location cannot be reached. For information about network troubleshooting, see Windows Help.
1346pub const PROTOCOL_UNREACHABLE = 1233;2018pub const PROTOCOL_UNREACHABLE = 1233;
2019
1347/// No service is operating at the destination network endpoint on the remote system.2020/// No service is operating at the destination network endpoint on the remote system.
1348pub const PORT_UNREACHABLE = 1234;2021pub const PORT_UNREACHABLE = 1234;
2022
1349/// The request was aborted.2023/// The request was aborted.
1350pub const REQUEST_ABORTED = 1235;2024pub const REQUEST_ABORTED = 1235;
2025
1351/// The network connection was aborted by the local system.2026/// The network connection was aborted by the local system.
1352pub const CONNECTION_ABORTED = 1236;2027pub const CONNECTION_ABORTED = 1236;
2028
1353/// The operation could not be completed. A retry should be performed.2029/// The operation could not be completed. A retry should be performed.
1354pub const RETRY = 1237;2030pub const RETRY = 1237;
2031
1355/// A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached.2032/// A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached.
1356pub const CONNECTION_COUNT_LIMIT = 1238;2033pub const CONNECTION_COUNT_LIMIT = 1238;
2034
1357/// Attempting to log in during an unauthorized time of day for this account.2035/// Attempting to log in during an unauthorized time of day for this account.
1358pub const LOGIN_TIME_RESTRICTION = 1239;2036pub const LOGIN_TIME_RESTRICTION = 1239;
2037
1359/// The account is not authorized to log in from this station.2038/// The account is not authorized to log in from this station.
1360pub const LOGIN_WKSTA_RESTRICTION = 1240;2039pub const LOGIN_WKSTA_RESTRICTION = 1240;
2040
1361/// The network address could not be used for the operation requested.2041/// The network address could not be used for the operation requested.
1362pub const INCORRECT_ADDRESS = 1241;2042pub const INCORRECT_ADDRESS = 1241;
2043
1363/// The service is already registered.2044/// The service is already registered.
1364pub const ALREADY_REGISTERED = 1242;2045pub const ALREADY_REGISTERED = 1242;
2046
1365/// The specified service does not exist.2047/// The specified service does not exist.
1366pub const SERVICE_NOT_FOUND = 1243;2048pub const SERVICE_NOT_FOUND = 1243;
2049
1367/// The operation being requested was not performed because the user has not been authenticated.2050/// The operation being requested was not performed because the user has not been authenticated.
1368pub const NOT_AUTHENTICATED = 1244;2051pub const NOT_AUTHENTICATED = 1244;
2052
1369/// The operation being requested was not performed because the user has not logged on to the network. The specified service does not exist.2053/// The operation being requested was not performed because the user has not logged on to the network. The specified service does not exist.
1370pub const NOT_LOGGED_ON = 1245;2054pub const NOT_LOGGED_ON = 1245;
2055
1371/// Continue with work in progress.2056/// Continue with work in progress.
1372pub const CONTINUE = 1246;2057pub const CONTINUE = 1246;
2058
1373/// An attempt was made to perform an initialization operation when initialization has already been completed.2059/// An attempt was made to perform an initialization operation when initialization has already been completed.
1374pub const ALREADY_INITIALIZED = 1247;2060pub const ALREADY_INITIALIZED = 1247;
2061
1375/// No more local devices.2062/// No more local devices.
1376pub const NO_MORE_DEVICES = 1248;2063pub const NO_MORE_DEVICES = 1248;
2064
1377/// The specified site does not exist.2065/// The specified site does not exist.
1378pub const NO_SUCH_SITE = 1249;2066pub const NO_SUCH_SITE = 1249;
2067
1379/// A domain controller with the specified name already exists.2068/// A domain controller with the specified name already exists.
1380pub const DOMAIN_CONTROLLER_EXISTS = 1250;2069pub const DOMAIN_CONTROLLER_EXISTS = 1250;
2070
1381/// This operation is supported only when you are connected to the server.2071/// This operation is supported only when you are connected to the server.
1382pub const ONLY_IF_CONNECTED = 1251;2072pub const ONLY_IF_CONNECTED = 1251;
2073
1383/// The group policy framework should call the extension even if there are no changes.2074/// The group policy framework should call the extension even if there are no changes.
1384pub const OVERRIDE_NOCHANGES = 1252;2075pub const OVERRIDE_NOCHANGES = 1252;
2076
1385/// The specified user does not have a valid profile.2077/// The specified user does not have a valid profile.
1386pub const BAD_USER_PROFILE = 1253;2078pub const BAD_USER_PROFILE = 1253;
2079
1387/// This operation is not supported on a computer running Windows Server 2003 for Small Business Server.2080/// This operation is not supported on a computer running Windows Server 2003 for Small Business Server.
1388pub const NOT_SUPPORTED_ON_SBS = 1254;2081pub const NOT_SUPPORTED_ON_SBS = 1254;
2082
1389/// The server machine is shutting down.2083/// The server machine is shutting down.
1390pub const SERVER_SHUTDOWN_IN_PROGRESS = 1255;2084pub const SERVER_SHUTDOWN_IN_PROGRESS = 1255;
2085
1391/// The remote system is not available. For information about network troubleshooting, see Windows Help.2086/// The remote system is not available. For information about network troubleshooting, see Windows Help.
1392pub const HOST_DOWN = 1256;2087pub const HOST_DOWN = 1256;
2088
1393/// The security identifier provided is not from an account domain.2089/// The security identifier provided is not from an account domain.
1394pub const NON_ACCOUNT_SID = 1257;2090pub const NON_ACCOUNT_SID = 1257;
2091
1395/// The security identifier provided does not have a domain component.2092/// The security identifier provided does not have a domain component.
1396pub const NON_DOMAIN_SID = 1258;2093pub const NON_DOMAIN_SID = 1258;
2094
1397/// AppHelp dialog canceled thus preventing the application from starting.2095/// AppHelp dialog canceled thus preventing the application from starting.
1398pub const APPHELP_BLOCK = 1259;2096pub const APPHELP_BLOCK = 1259;
2097
1399/// This program is blocked by group policy. For more information, contact your system administrator.2098/// This program is blocked by group policy. For more information, contact your system administrator.
1400pub const ACCESS_DISABLED_BY_POLICY = 1260;2099pub const ACCESS_DISABLED_BY_POLICY = 1260;
2100
1401/// A program attempt to use an invalid register value. Normally caused by an uninitialized register. This error is Itanium specific.2101/// A program attempt to use an invalid register value. Normally caused by an uninitialized register. This error is Itanium specific.
1402pub const REG_NAT_CONSUMPTION = 1261;2102pub const REG_NAT_CONSUMPTION = 1261;
2103
1403/// The share is currently offline or does not exist.2104/// The share is currently offline or does not exist.
1404pub const CSCSHARE_OFFLINE = 1262;2105pub const CSCSHARE_OFFLINE = 1262;
2106
1405/// The Kerberos protocol encountered an error while validating the KDC certificate during smartcard logon. There is more information in the system event log.2107/// The Kerberos protocol encountered an error while validating the KDC certificate during smartcard logon. There is more information in the system event log.
1406pub const PKINIT_FAILURE = 1263;2108pub const PKINIT_FAILURE = 1263;
2109
1407/// The Kerberos protocol encountered an error while attempting to utilize the smartcard subsystem.2110/// The Kerberos protocol encountered an error while attempting to utilize the smartcard subsystem.
1408pub const SMARTCARD_SUBSYSTEM_FAILURE = 1264;2111pub const SMARTCARD_SUBSYSTEM_FAILURE = 1264;
2112
1409/// The system cannot contact a domain controller to service the authentication request. Please try again later.2113/// The system cannot contact a domain controller to service the authentication request. Please try again later.
1410pub const DOWNGRADE_DETECTED = 1265;2114pub const DOWNGRADE_DETECTED = 1265;
2115
1411/// The machine is locked and cannot be shut down without the force option.2116/// The machine is locked and cannot be shut down without the force option.
1412pub const MACHINE_LOCKED = 1271;2117pub const MACHINE_LOCKED = 1271;
2118
1413/// An application-defined callback gave invalid data when called.2119/// An application-defined callback gave invalid data when called.
1414pub const CALLBACK_SUPPLIED_INVALID_DATA = 1273;2120pub const CALLBACK_SUPPLIED_INVALID_DATA = 1273;
2121
1415/// The group policy framework should call the extension in the synchronous foreground policy refresh.2122/// The group policy framework should call the extension in the synchronous foreground policy refresh.
1416pub const SYNC_FOREGROUND_REFRESH_REQUIRED = 1274;2123pub const SYNC_FOREGROUND_REFRESH_REQUIRED = 1274;
2124
1417/// This driver has been blocked from loading.2125/// This driver has been blocked from loading.
1418pub const DRIVER_BLOCKED = 1275;2126pub const DRIVER_BLOCKED = 1275;
2127
1419/// A dynamic link library (DLL) referenced a module that was neither a DLL nor the process's executable image.2128/// A dynamic link library (DLL) referenced a module that was neither a DLL nor the process's executable image.
1420pub const INVALID_IMPORT_OF_NON_DLL = 1276;2129pub const INVALID_IMPORT_OF_NON_DLL = 1276;
2130
1421/// Windows cannot open this program since it has been disabled.2131/// Windows cannot open this program since it has been disabled.
1422pub const ACCESS_DISABLED_WEBBLADE = 1277;2132pub const ACCESS_DISABLED_WEBBLADE = 1277;
2133
1423/// Windows cannot open this program because the license enforcement system has been tampered with or become corrupted.2134/// Windows cannot open this program because the license enforcement system has been tampered with or become corrupted.
1424pub const ACCESS_DISABLED_WEBBLADE_TAMPER = 1278;2135pub const ACCESS_DISABLED_WEBBLADE_TAMPER = 1278;
2136
1425/// A transaction recover failed.2137/// A transaction recover failed.
1426pub const RECOVERY_FAILURE = 1279;2138pub const RECOVERY_FAILURE = 1279;
2139
1427/// The current thread has already been converted to a fiber.2140/// The current thread has already been converted to a fiber.
1428pub const ALREADY_FIBER = 1280;2141pub const ALREADY_FIBER = 1280;
2142
1429/// The current thread has already been converted from a fiber.2143/// The current thread has already been converted from a fiber.
1430pub const ALREADY_THREAD = 1281;2144pub const ALREADY_THREAD = 1281;
2145
1431/// The system detected an overrun of a stack-based buffer in this application. This overrun could potentially allow a malicious user to gain control of this application.2146/// The system detected an overrun of a stack-based buffer in this application. This overrun could potentially allow a malicious user to gain control of this application.
1432pub const STACK_BUFFER_OVERRUN = 1282;2147pub const STACK_BUFFER_OVERRUN = 1282;
2148
1433/// Data present in one of the parameters is more than the function can operate on.2149/// Data present in one of the parameters is more than the function can operate on.
1434pub const PARAMETER_QUOTA_EXCEEDED = 1283;2150pub const PARAMETER_QUOTA_EXCEEDED = 1283;
2151
1435/// An attempt to do an operation on a debug object failed because the object is in the process of being deleted.2152/// An attempt to do an operation on a debug object failed because the object is in the process of being deleted.
1436pub const DEBUGGER_INACTIVE = 1284;2153pub const DEBUGGER_INACTIVE = 1284;
2154
1437/// An attempt to delay-load a .dll or get a function address in a delay-loaded .dll failed.2155/// An attempt to delay-load a .dll or get a function address in a delay-loaded .dll failed.
1438pub const DELAY_LOAD_FAILED = 1285;2156pub const DELAY_LOAD_FAILED = 1285;
2157
1439/// %1 is a 16-bit application. You do not have permissions to execute 16-bit applications. Check your permissions with your system administrator.2158/// %1 is a 16-bit application. You do not have permissions to execute 16-bit applications. Check your permissions with your system administrator.
1440pub const VDM_DISALLOWED = 1286;2159pub const VDM_DISALLOWED = 1286;
2160
1441/// Insufficient information exists to identify the cause of failure.2161/// Insufficient information exists to identify the cause of failure.
1442pub const UNIDENTIFIED_ERROR = 1287;2162pub const UNIDENTIFIED_ERROR = 1287;
2163
1443/// The parameter passed to a C runtime function is incorrect.2164/// The parameter passed to a C runtime function is incorrect.
1444pub const INVALID_CRUNTIME_PARAMETER = 1288;2165pub const INVALID_CRUNTIME_PARAMETER = 1288;
2166
1445/// The operation occurred beyond the valid data length of the file.2167/// The operation occurred beyond the valid data length of the file.
1446pub const BEYOND_VDL = 1289;2168pub const BEYOND_VDL = 1289;
2169
1447/// The service start failed since one or more services in the same process have an incompatible service SID type setting. A service with restricted service SID type can only coexist in the same process with other services with a restricted SID type. If the service SID type for this service was just configured, the hosting process must be restarted in order to start this service.2170/// The service start failed since one or more services in the same process have an incompatible service SID type setting. A service with restricted service SID type can only coexist in the same process with other services with a restricted SID type. If the service SID type for this service was just configured, the hosting process must be restarted in order to start this service.
1448/// On Windows Server 2003 and Windows XP, an unrestricted service cannot coexist in the same process with other services. The service with the unrestricted service SID type must be moved to an owned process in order to start this service.2171/// On Windows Server 2003 and Windows XP, an unrestricted service cannot coexist in the same process with other services. The service with the unrestricted service SID type must be moved to an owned process in order to start this service.
1449pub const INCOMPATIBLE_SERVICE_SID_TYPE = 1290;2172pub const INCOMPATIBLE_SERVICE_SID_TYPE = 1290;
2173
1450/// The process hosting the driver for this device has been terminated.2174/// The process hosting the driver for this device has been terminated.
1451pub const DRIVER_PROCESS_TERMINATED = 1291;2175pub const DRIVER_PROCESS_TERMINATED = 1291;
2176
1452/// An operation attempted to exceed an implementation-defined limit.2177/// An operation attempted to exceed an implementation-defined limit.
1453pub const IMPLEMENTATION_LIMIT = 1292;2178pub const IMPLEMENTATION_LIMIT = 1292;
2179
1454/// Either the target process, or the target thread's containing process, is a protected process.2180/// Either the target process, or the target thread's containing process, is a protected process.
1455pub const PROCESS_IS_PROTECTED = 1293;2181pub const PROCESS_IS_PROTECTED = 1293;
2182
1456/// The service notification client is lagging too far behind the current state of services in the machine.2183/// The service notification client is lagging too far behind the current state of services in the machine.
1457pub const SERVICE_NOTIFY_CLIENT_LAGGING = 1294;2184pub const SERVICE_NOTIFY_CLIENT_LAGGING = 1294;
2185
1458/// The requested file operation failed because the storage quota was exceeded. To free up disk space, move files to a different location or delete unnecessary files. For more information, contact your system administrator.2186/// The requested file operation failed because the storage quota was exceeded. To free up disk space, move files to a different location or delete unnecessary files. For more information, contact your system administrator.
1459pub const DISK_QUOTA_EXCEEDED = 1295;2187pub const DISK_QUOTA_EXCEEDED = 1295;
2188
1460/// The requested file operation failed because the storage policy blocks that type of file. For more information, contact your system administrator.2189/// The requested file operation failed because the storage policy blocks that type of file. For more information, contact your system administrator.
1461pub const CONTENT_BLOCKED = 1296;2190pub const CONTENT_BLOCKED = 1296;
2191
1462/// A privilege that the service requires to function properly does not exist in the service account configuration. You may use the Services Microsoft Management Console (MMC) snap-in (services.msc) and the Local Security Settings MMC snap-in (secpol.msc) to view the service configuration and the account configuration.2192/// A privilege that the service requires to function properly does not exist in the service account configuration. You may use the Services Microsoft Management Console (MMC) snap-in (services.msc) and the Local Security Settings MMC snap-in (secpol.msc) to view the service configuration and the account configuration.
1463pub const INCOMPATIBLE_SERVICE_PRIVILEGE = 1297;2193pub const INCOMPATIBLE_SERVICE_PRIVILEGE = 1297;
2194
1464/// A thread involved in this operation appears to be unresponsive.2195/// A thread involved in this operation appears to be unresponsive.
1465pub const APP_HANG = 1298;2196pub const APP_HANG = 1298;
2197
1466/// Indicates a particular Security ID may not be assigned as the label of an object.2198/// Indicates a particular Security ID may not be assigned as the label of an object.
1467pub const INVALID_LABEL = 1299;2199pub const INVALID_LABEL = 1299;
2200
1468/// Not all privileges or groups referenced are assigned to the caller.2201/// Not all privileges or groups referenced are assigned to the caller.
1469pub const NOT_ALL_ASSIGNED = 1300;2202pub const NOT_ALL_ASSIGNED = 1300;
2203
1470/// Some mapping between account names and security IDs was not done.2204/// Some mapping between account names and security IDs was not done.
1471pub const SOME_NOT_MAPPED = 1301;2205pub const SOME_NOT_MAPPED = 1301;
2206
1472/// No system quota limits are specifically set for this account.2207/// No system quota limits are specifically set for this account.
1473pub const NO_QUOTAS_FOR_ACCOUNT = 1302;2208pub const NO_QUOTAS_FOR_ACCOUNT = 1302;
2209
1474/// No encryption key is available. A well-known encryption key was returned.2210/// No encryption key is available. A well-known encryption key was returned.
1475pub const LOCAL_USER_SESSION_KEY = 1303;2211pub const LOCAL_USER_SESSION_KEY = 1303;
2212
1476/// The password is too complex to be converted to a LAN Manager password. The LAN Manager password returned is a NULL string.2213/// The password is too complex to be converted to a LAN Manager password. The LAN Manager password returned is a NULL string.
1477pub const NULL_LM_PASSWORD = 1304;2214pub const NULL_LM_PASSWORD = 1304;
2215
1478/// The revision level is unknown.2216/// The revision level is unknown.
1479pub const UNKNOWN_REVISION = 1305;2217pub const UNKNOWN_REVISION = 1305;
2218
1480/// Indicates two revision levels are incompatible.2219/// Indicates two revision levels are incompatible.
1481pub const REVISION_MISMATCH = 1306;2220pub const REVISION_MISMATCH = 1306;
2221
1482/// This security ID may not be assigned as the owner of this object.2222/// This security ID may not be assigned as the owner of this object.
1483pub const INVALID_OWNER = 1307;2223pub const INVALID_OWNER = 1307;
2224
1484/// This security ID may not be assigned as the primary group of an object.2225/// This security ID may not be assigned as the primary group of an object.
1485pub const INVALID_PRIMARY_GROUP = 1308;2226pub const INVALID_PRIMARY_GROUP = 1308;
2227
1486/// An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client.2228/// An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client.
1487pub const NO_IMPERSONATION_TOKEN = 1309;2229pub const NO_IMPERSONATION_TOKEN = 1309;
2230
1488/// The group may not be disabled.2231/// The group may not be disabled.
1489pub const CANT_DISABLE_MANDATORY = 1310;2232pub const CANT_DISABLE_MANDATORY = 1310;
2233
1490/// There are currently no logon servers available to service the logon request.2234/// There are currently no logon servers available to service the logon request.
1491pub const NO_LOGON_SERVERS = 1311;2235pub const NO_LOGON_SERVERS = 1311;
2236
1492/// A specified logon session does not exist. It may already have been terminated.2237/// A specified logon session does not exist. It may already have been terminated.
1493pub const NO_SUCH_LOGON_SESSION = 1312;2238pub const NO_SUCH_LOGON_SESSION = 1312;
2239
1494/// A specified privilege does not exist.2240/// A specified privilege does not exist.
1495pub const NO_SUCH_PRIVILEGE = 1313;2241pub const NO_SUCH_PRIVILEGE = 1313;
2242
1496/// A required privilege is not held by the client.2243/// A required privilege is not held by the client.
1497pub const PRIVILEGE_NOT_HELD = 1314;2244pub const PRIVILEGE_NOT_HELD = 1314;
2245
1498/// The name provided is not a properly formed account name.2246/// The name provided is not a properly formed account name.
1499pub const INVALID_ACCOUNT_NAME = 1315;2247pub const INVALID_ACCOUNT_NAME = 1315;
2248
1500/// The specified account already exists.2249/// The specified account already exists.
1501pub const USER_EXISTS = 1316;2250pub const USER_EXISTS = 1316;
2251
1502/// The specified account does not exist.2252/// The specified account does not exist.
1503pub const NO_SUCH_USER = 1317;2253pub const NO_SUCH_USER = 1317;
2254
1504/// The specified group already exists.2255/// The specified group already exists.
1505pub const GROUP_EXISTS = 1318;2256pub const GROUP_EXISTS = 1318;
2257
1506/// The specified group does not exist.2258/// The specified group does not exist.
1507pub const NO_SUCH_GROUP = 1319;2259pub const NO_SUCH_GROUP = 1319;
2260
1508/// Either the specified user account is already a member of the specified group, or the specified group cannot be deleted because it contains a member.2261/// Either the specified user account is already a member of the specified group, or the specified group cannot be deleted because it contains a member.
1509pub const MEMBER_IN_GROUP = 1320;2262pub const MEMBER_IN_GROUP = 1320;
2263
1510/// The specified user account is not a member of the specified group account.2264/// The specified user account is not a member of the specified group account.
1511pub const MEMBER_NOT_IN_GROUP = 1321;2265pub const MEMBER_NOT_IN_GROUP = 1321;
2266
1512/// This operation is disallowed as it could result in an administration account being disabled, deleted or unable to log on.2267/// This operation is disallowed as it could result in an administration account being disabled, deleted or unable to log on.
1513pub const LAST_ADMIN = 1322;2268pub const LAST_ADMIN = 1322;
2269
1514/// Unable to update the password. The value provided as the current password is incorrect.2270/// Unable to update the password. The value provided as the current password is incorrect.
1515pub const WRONG_PASSWORD = 1323;2271pub const WRONG_PASSWORD = 1323;
2272
1516/// Unable to update the password. The value provided for the new password contains values that are not allowed in passwords.2273/// Unable to update the password. The value provided for the new password contains values that are not allowed in passwords.
1517pub const ILL_FORMED_PASSWORD = 1324;2274pub const ILL_FORMED_PASSWORD = 1324;
2275
1518/// Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain.2276/// Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain.
1519pub const PASSWORD_RESTRICTION = 1325;2277pub const PASSWORD_RESTRICTION = 1325;
2278
1520/// The user name or password is incorrect.2279/// The user name or password is incorrect.
1521pub const LOGON_FAILURE = 1326;2280pub const LOGON_FAILURE = 1326;
2281
1522/// Account restrictions are preventing this user from signing in. For example: blank passwords aren't allowed, sign-in times are limited, or a policy restriction has been enforced.2282/// Account restrictions are preventing this user from signing in. For example: blank passwords aren't allowed, sign-in times are limited, or a policy restriction has been enforced.
1523pub const ACCOUNT_RESTRICTION = 1327;2283pub const ACCOUNT_RESTRICTION = 1327;
2284
1524/// Your account has time restrictions that keep you from signing in right now.2285/// Your account has time restrictions that keep you from signing in right now.
1525pub const INVALID_LOGON_HOURS = 1328;2286pub const INVALID_LOGON_HOURS = 1328;
2287
1526/// This user isn't allowed to sign in to this computer.2288/// This user isn't allowed to sign in to this computer.
1527pub const INVALID_WORKSTATION = 1329;2289pub const INVALID_WORKSTATION = 1329;
2290
1528/// The password for this account has expired.2291/// The password for this account has expired.
1529pub const PASSWORD_EXPIRED = 1330;2292pub const PASSWORD_EXPIRED = 1330;
2293
1530/// This user can't sign in because this account is currently disabled.2294/// This user can't sign in because this account is currently disabled.
1531pub const ACCOUNT_DISABLED = 1331;2295pub const ACCOUNT_DISABLED = 1331;
2296
1532/// No mapping between account names and security IDs was done.2297/// No mapping between account names and security IDs was done.
1533pub const NONE_MAPPED = 1332;2298pub const NONE_MAPPED = 1332;
2299
1534/// Too many local user identifiers (LUIDs) were requested at one time.2300/// Too many local user identifiers (LUIDs) were requested at one time.
1535pub const TOO_MANY_LUIDS_REQUESTED = 1333;2301pub const TOO_MANY_LUIDS_REQUESTED = 1333;
2302
1536/// No more local user identifiers (LUIDs) are available.2303/// No more local user identifiers (LUIDs) are available.
1537pub const LUIDS_EXHAUSTED = 1334;2304pub const LUIDS_EXHAUSTED = 1334;
2305
1538/// The subauthority part of a security ID is invalid for this particular use.2306/// The subauthority part of a security ID is invalid for this particular use.
1539pub const INVALID_SUB_AUTHORITY = 1335;2307pub const INVALID_SUB_AUTHORITY = 1335;
2308
1540/// The access control list (ACL) structure is invalid.2309/// The access control list (ACL) structure is invalid.
1541pub const INVALID_ACL = 1336;2310pub const INVALID_ACL = 1336;
2311
1542/// The security ID structure is invalid.2312/// The security ID structure is invalid.
1543pub const INVALID_SID = 1337;2313pub const INVALID_SID = 1337;
2314
1544/// The security descriptor structure is invalid.2315/// The security descriptor structure is invalid.
1545pub const INVALID_SECURITY_DESCR = 1338;2316pub const INVALID_SECURITY_DESCR = 1338;
2317
1546/// The inherited access control list (ACL) or access control entry (ACE) could not be built.2318/// The inherited access control list (ACL) or access control entry (ACE) could not be built.
1547pub const BAD_INHERITANCE_ACL = 1340;2319pub const BAD_INHERITANCE_ACL = 1340;
2320
1548/// The server is currently disabled.2321/// The server is currently disabled.
1549pub const SERVER_DISABLED = 1341;2322pub const SERVER_DISABLED = 1341;
2323
1550/// The server is currently enabled.2324/// The server is currently enabled.
1551pub const SERVER_NOT_DISABLED = 1342;2325pub const SERVER_NOT_DISABLED = 1342;
2326
1552/// The value provided was an invalid value for an identifier authority.2327/// The value provided was an invalid value for an identifier authority.
1553pub const INVALID_ID_AUTHORITY = 1343;2328pub const INVALID_ID_AUTHORITY = 1343;
2329
1554/// No more memory is available for security information updates.2330/// No more memory is available for security information updates.
1555pub const ALLOTTED_SPACE_EXCEEDED = 1344;2331pub const ALLOTTED_SPACE_EXCEEDED = 1344;
2332
1556/// The specified attributes are invalid, or incompatible with the attributes for the group as a whole.2333/// The specified attributes are invalid, or incompatible with the attributes for the group as a whole.
1557pub const INVALID_GROUP_ATTRIBUTES = 1345;2334pub const INVALID_GROUP_ATTRIBUTES = 1345;
2335
1558/// Either a required impersonation level was not provided, or the provided impersonation level is invalid.2336/// Either a required impersonation level was not provided, or the provided impersonation level is invalid.
1559pub const BAD_IMPERSONATION_LEVEL = 1346;2337pub const BAD_IMPERSONATION_LEVEL = 1346;
2338
1560/// Cannot open an anonymous level security token.2339/// Cannot open an anonymous level security token.
1561pub const CANT_OPEN_ANONYMOUS = 1347;2340pub const CANT_OPEN_ANONYMOUS = 1347;
2341
1562/// The validation information class requested was invalid.2342/// The validation information class requested was invalid.
1563pub const BAD_VALIDATION_CLASS = 1348;2343pub const BAD_VALIDATION_CLASS = 1348;
2344
1564/// The type of the token is inappropriate for its attempted use.2345/// The type of the token is inappropriate for its attempted use.
1565pub const BAD_TOKEN_TYPE = 1349;2346pub const BAD_TOKEN_TYPE = 1349;
2347
1566/// Unable to perform a security operation on an object that has no associated security.2348/// Unable to perform a security operation on an object that has no associated security.
1567pub const NO_SECURITY_ON_OBJECT = 1350;2349pub const NO_SECURITY_ON_OBJECT = 1350;
2350
1568/// Configuration information could not be read from the domain controller, either because the machine is unavailable, or access has been denied.2351/// Configuration information could not be read from the domain controller, either because the machine is unavailable, or access has been denied.
1569pub const CANT_ACCESS_DOMAIN_INFO = 1351;2352pub const CANT_ACCESS_DOMAIN_INFO = 1351;
2353
1570/// The security account manager (SAM) or local security authority (LSA) server was in the wrong state to perform the security operation.2354/// The security account manager (SAM) or local security authority (LSA) server was in the wrong state to perform the security operation.
1571pub const INVALID_SERVER_STATE = 1352;2355pub const INVALID_SERVER_STATE = 1352;
2356
1572/// The domain was in the wrong state to perform the security operation.2357/// The domain was in the wrong state to perform the security operation.
1573pub const INVALID_DOMAIN_STATE = 1353;2358pub const INVALID_DOMAIN_STATE = 1353;
2359
1574/// This operation is only allowed for the Primary Domain Controller of the domain.2360/// This operation is only allowed for the Primary Domain Controller of the domain.
1575pub const INVALID_DOMAIN_ROLE = 1354;2361pub const INVALID_DOMAIN_ROLE = 1354;
2362
1576/// The specified domain either does not exist or could not be contacted.2363/// The specified domain either does not exist or could not be contacted.
1577pub const NO_SUCH_DOMAIN = 1355;2364pub const NO_SUCH_DOMAIN = 1355;
2365
1578/// The specified domain already exists.2366/// The specified domain already exists.
1579pub const DOMAIN_EXISTS = 1356;2367pub const DOMAIN_EXISTS = 1356;
2368
1580/// An attempt was made to exceed the limit on the number of domains per server.2369/// An attempt was made to exceed the limit on the number of domains per server.
1581pub const DOMAIN_LIMIT_EXCEEDED = 1357;2370pub const DOMAIN_LIMIT_EXCEEDED = 1357;
2371
1582/// Unable to complete the requested operation because of either a catastrophic media failure or a data structure corruption on the disk.2372/// Unable to complete the requested operation because of either a catastrophic media failure or a data structure corruption on the disk.
1583pub const INTERNAL_DB_CORRUPTION = 1358;2373pub const INTERNAL_DB_CORRUPTION = 1358;
2374
1584/// An internal error occurred.2375/// An internal error occurred.
1585pub const INTERNAL_ERROR = 1359;2376pub const INTERNAL_ERROR = 1359;
2377
1586/// Generic access types were contained in an access mask which should already be mapped to nongeneric types.2378/// Generic access types were contained in an access mask which should already be mapped to nongeneric types.
1587pub const GENERIC_NOT_MAPPED = 1360;2379pub const GENERIC_NOT_MAPPED = 1360;
2380
1588/// A security descriptor is not in the right format (absolute or self-relative).2381/// A security descriptor is not in the right format (absolute or self-relative).
1589pub const BAD_DESCRIPTOR_FORMAT = 1361;2382pub const BAD_DESCRIPTOR_FORMAT = 1361;
2383
1590/// The requested action is restricted for use by logon processes only. The calling process has not registered as a logon process.2384/// The requested action is restricted for use by logon processes only. The calling process has not registered as a logon process.
1591pub const NOT_LOGON_PROCESS = 1362;2385pub const NOT_LOGON_PROCESS = 1362;
2386
1592/// Cannot start a new logon session with an ID that is already in use.2387/// Cannot start a new logon session with an ID that is already in use.
1593pub const LOGON_SESSION_EXISTS = 1363;2388pub const LOGON_SESSION_EXISTS = 1363;
2389
1594/// A specified authentication package is unknown.2390/// A specified authentication package is unknown.
1595pub const NO_SUCH_PACKAGE = 1364;2391pub const NO_SUCH_PACKAGE = 1364;
2392
1596/// The logon session is not in a state that is consistent with the requested operation.2393/// The logon session is not in a state that is consistent with the requested operation.
1597pub const BAD_LOGON_SESSION_STATE = 1365;2394pub const BAD_LOGON_SESSION_STATE = 1365;
2395
1598/// The logon session ID is already in use.2396/// The logon session ID is already in use.
1599pub const LOGON_SESSION_COLLISION = 1366;2397pub const LOGON_SESSION_COLLISION = 1366;
2398
1600/// A logon request contained an invalid logon type value.2399/// A logon request contained an invalid logon type value.
1601pub const INVALID_LOGON_TYPE = 1367;2400pub const INVALID_LOGON_TYPE = 1367;
2401
1602/// Unable to impersonate using a named pipe until data has been read from that pipe.2402/// Unable to impersonate using a named pipe until data has been read from that pipe.
1603pub const CANNOT_IMPERSONATE = 1368;2403pub const CANNOT_IMPERSONATE = 1368;
2404
1604/// The transaction state of a registry subtree is incompatible with the requested operation.2405/// The transaction state of a registry subtree is incompatible with the requested operation.
1605pub const RXACT_INVALID_STATE = 1369;2406pub const RXACT_INVALID_STATE = 1369;
2407
1606/// An internal security database corruption has been encountered.2408/// An internal security database corruption has been encountered.
1607pub const RXACT_COMMIT_FAILURE = 1370;2409pub const RXACT_COMMIT_FAILURE = 1370;
2410
1608/// Cannot perform this operation on built-in accounts.2411/// Cannot perform this operation on built-in accounts.
1609pub const SPECIAL_ACCOUNT = 1371;2412pub const SPECIAL_ACCOUNT = 1371;
2413
1610/// Cannot perform this operation on this built-in special group.2414/// Cannot perform this operation on this built-in special group.
1611pub const SPECIAL_GROUP = 1372;2415pub const SPECIAL_GROUP = 1372;
2416
1612/// Cannot perform this operation on this built-in special user.2417/// Cannot perform this operation on this built-in special user.
1613pub const SPECIAL_USER = 1373;2418pub const SPECIAL_USER = 1373;
2419
1614/// The user cannot be removed from a group because the group is currently the user's primary group.2420/// The user cannot be removed from a group because the group is currently the user's primary group.
1615pub const MEMBERS_PRIMARY_GROUP = 1374;2421pub const MEMBERS_PRIMARY_GROUP = 1374;
2422
1616/// The token is already in use as a primary token.2423/// The token is already in use as a primary token.
1617pub const TOKEN_ALREADY_IN_USE = 1375;2424pub const TOKEN_ALREADY_IN_USE = 1375;
2425
1618/// The specified local group does not exist.2426/// The specified local group does not exist.
1619pub const NO_SUCH_ALIAS = 1376;2427pub const NO_SUCH_ALIAS = 1376;
2428
1620/// The specified account name is not a member of the group.2429/// The specified account name is not a member of the group.
1621pub const MEMBER_NOT_IN_ALIAS = 1377;2430pub const MEMBER_NOT_IN_ALIAS = 1377;
2431
1622/// The specified account name is already a member of the group.2432/// The specified account name is already a member of the group.
1623pub const MEMBER_IN_ALIAS = 1378;2433pub const MEMBER_IN_ALIAS = 1378;
2434
1624/// The specified local group already exists.2435/// The specified local group already exists.
1625pub const ALIAS_EXISTS = 1379;2436pub const ALIAS_EXISTS = 1379;
2437
1626/// Logon failure: the user has not been granted the requested logon type at this computer.2438/// Logon failure: the user has not been granted the requested logon type at this computer.
1627pub const LOGON_NOT_GRANTED = 1380;2439pub const LOGON_NOT_GRANTED = 1380;
2440
1628/// The maximum number of secrets that may be stored in a single system has been exceeded.2441/// The maximum number of secrets that may be stored in a single system has been exceeded.
1629pub const TOO_MANY_SECRETS = 1381;2442pub const TOO_MANY_SECRETS = 1381;
2443
1630/// The length of a secret exceeds the maximum length allowed.2444/// The length of a secret exceeds the maximum length allowed.
1631pub const SECRET_TOO_LONG = 1382;2445pub const SECRET_TOO_LONG = 1382;
2446
1632/// The local security authority database contains an internal inconsistency.2447/// The local security authority database contains an internal inconsistency.
1633pub const INTERNAL_DB_ERROR = 1383;2448pub const INTERNAL_DB_ERROR = 1383;
2449
1634/// During a logon attempt, the user's security context accumulated too many security IDs.2450/// During a logon attempt, the user's security context accumulated too many security IDs.
1635pub const TOO_MANY_CONTEXT_IDS = 1384;2451pub const TOO_MANY_CONTEXT_IDS = 1384;
2452
1636/// Logon failure: the user has not been granted the requested logon type at this computer.2453/// Logon failure: the user has not been granted the requested logon type at this computer.
1637pub const LOGON_TYPE_NOT_GRANTED = 1385;2454pub const LOGON_TYPE_NOT_GRANTED = 1385;
2455
1638/// A cross-encrypted password is necessary to change a user password.2456/// A cross-encrypted password is necessary to change a user password.
1639pub const NT_CROSS_ENCRYPTION_REQUIRED = 1386;2457pub const NT_CROSS_ENCRYPTION_REQUIRED = 1386;
2458
1640/// A member could not be added to or removed from the local group because the member does not exist.2459/// A member could not be added to or removed from the local group because the member does not exist.
1641pub const NO_SUCH_MEMBER = 1387;2460pub const NO_SUCH_MEMBER = 1387;
2461
1642/// A new member could not be added to a local group because the member has the wrong account type.2462/// A new member could not be added to a local group because the member has the wrong account type.
1643pub const INVALID_MEMBER = 1388;2463pub const INVALID_MEMBER = 1388;
2464
1644/// Too many security IDs have been specified.2465/// Too many security IDs have been specified.
1645pub const TOO_MANY_SIDS = 1389;2466pub const TOO_MANY_SIDS = 1389;
2467
1646/// A cross-encrypted password is necessary to change this user password.2468/// A cross-encrypted password is necessary to change this user password.
1647pub const LM_CROSS_ENCRYPTION_REQUIRED = 1390;2469pub const LM_CROSS_ENCRYPTION_REQUIRED = 1390;
2470
1648/// Indicates an ACL contains no inheritable components.2471/// Indicates an ACL contains no inheritable components.
1649pub const NO_INHERITANCE = 1391;2472pub const NO_INHERITANCE = 1391;
2473
1650/// The file or directory is corrupted and unreadable.2474/// The file or directory is corrupted and unreadable.
1651pub const FILE_CORRUPT = 1392;2475pub const FILE_CORRUPT = 1392;
2476
1652/// The disk structure is corrupted and unreadable.2477/// The disk structure is corrupted and unreadable.
1653pub const DISK_CORRUPT = 1393;2478pub const DISK_CORRUPT = 1393;
2479
1654/// There is no user session key for the specified logon session.2480/// There is no user session key for the specified logon session.
1655pub const NO_USER_SESSION_KEY = 1394;2481pub const NO_USER_SESSION_KEY = 1394;
2482
1656/// The service being accessed is licensed for a particular number of connections. No more connections can be made to the service at this time because there are already as many connections as the service can accept.2483/// The service being accessed is licensed for a particular number of connections. No more connections can be made to the service at this time because there are already as many connections as the service can accept.
1657pub const LICENSE_QUOTA_EXCEEDED = 1395;2484pub const LICENSE_QUOTA_EXCEEDED = 1395;
2485
1658/// The target account name is incorrect.2486/// The target account name is incorrect.
1659pub const WRONG_TARGET_NAME = 1396;2487pub const WRONG_TARGET_NAME = 1396;
2488
1660/// Mutual Authentication failed. The server's password is out of date at the domain controller.2489/// Mutual Authentication failed. The server's password is out of date at the domain controller.
1661pub const MUTUAL_AUTH_FAILED = 1397;2490pub const MUTUAL_AUTH_FAILED = 1397;
2491
1662/// There is a time and/or date difference between the client and server.2492/// There is a time and/or date difference between the client and server.
1663pub const TIME_SKEW = 1398;2493pub const TIME_SKEW = 1398;
2494
1664/// This operation cannot be performed on the current domain.2495/// This operation cannot be performed on the current domain.
1665pub const CURRENT_DOMAIN_NOT_ALLOWED = 1399;2496pub const CURRENT_DOMAIN_NOT_ALLOWED = 1399;
2497
1666/// Invalid window handle.2498/// Invalid window handle.
1667pub const INVALID_WINDOW_HANDLE = 1400;2499pub const INVALID_WINDOW_HANDLE = 1400;
2500
1668/// Invalid menu handle.2501/// Invalid menu handle.
1669pub const INVALID_MENU_HANDLE = 1401;2502pub const INVALID_MENU_HANDLE = 1401;
2503
1670/// Invalid cursor handle.2504/// Invalid cursor handle.
1671pub const INVALID_CURSOR_HANDLE = 1402;2505pub const INVALID_CURSOR_HANDLE = 1402;
2506
1672/// Invalid accelerator table handle.2507/// Invalid accelerator table handle.
1673pub const INVALID_ACCEL_HANDLE = 1403;2508pub const INVALID_ACCEL_HANDLE = 1403;
2509
1674/// Invalid hook handle.2510/// Invalid hook handle.
1675pub const INVALID_HOOK_HANDLE = 1404;2511pub const INVALID_HOOK_HANDLE = 1404;
2512
1676/// Invalid handle to a multiple-window position structure.2513/// Invalid handle to a multiple-window position structure.
1677pub const INVALID_DWP_HANDLE = 1405;2514pub const INVALID_DWP_HANDLE = 1405;
2515
1678/// Cannot create a top-level child window.2516/// Cannot create a top-level child window.
1679pub const TLW_WITH_WSCHILD = 1406;2517pub const TLW_WITH_WSCHILD = 1406;
2518
1680/// Cannot find window class.2519/// Cannot find window class.
1681pub const CANNOT_FIND_WND_CLASS = 1407;2520pub const CANNOT_FIND_WND_CLASS = 1407;
2521
1682/// Invalid window; it belongs to other thread.2522/// Invalid window; it belongs to other thread.
1683pub const WINDOW_OF_OTHER_THREAD = 1408;2523pub const WINDOW_OF_OTHER_THREAD = 1408;
2524
1684/// Hot key is already registered.2525/// Hot key is already registered.
1685pub const HOTKEY_ALREADY_REGISTERED = 1409;2526pub const HOTKEY_ALREADY_REGISTERED = 1409;
2527
1686/// Class already exists.2528/// Class already exists.
1687pub const CLASS_ALREADY_EXISTS = 1410;2529pub const CLASS_ALREADY_EXISTS = 1410;
2530
1688/// Class does not exist.2531/// Class does not exist.
1689pub const CLASS_DOES_NOT_EXIST = 1411;2532pub const CLASS_DOES_NOT_EXIST = 1411;
2533
1690/// Class still has open windows.2534/// Class still has open windows.
1691pub const CLASS_HAS_WINDOWS = 1412;2535pub const CLASS_HAS_WINDOWS = 1412;
2536
1692/// Invalid index.2537/// Invalid index.
1693pub const INVALID_INDEX = 1413;2538pub const INVALID_INDEX = 1413;
2539
1694/// Invalid icon handle.2540/// Invalid icon handle.
1695pub const INVALID_ICON_HANDLE = 1414;2541pub const INVALID_ICON_HANDLE = 1414;
2542
1696/// Using private DIALOG window words.2543/// Using private DIALOG window words.
1697pub const PRIVATE_DIALOG_INDEX = 1415;2544pub const PRIVATE_DIALOG_INDEX = 1415;
2545
1698/// The list box identifier was not found.2546/// The list box identifier was not found.
1699pub const LISTBOX_ID_NOT_FOUND = 1416;2547pub const LISTBOX_ID_NOT_FOUND = 1416;
2548
1700/// No wildcards were found.2549/// No wildcards were found.
1701pub const NO_WILDCARD_CHARACTERS = 1417;2550pub const NO_WILDCARD_CHARACTERS = 1417;
2551
1702/// Thread does not have a clipboard open.2552/// Thread does not have a clipboard open.
1703pub const CLIPBOARD_NOT_OPEN = 1418;2553pub const CLIPBOARD_NOT_OPEN = 1418;
2554
1704/// Hot key is not registered.2555/// Hot key is not registered.
1705pub const HOTKEY_NOT_REGISTERED = 1419;2556pub const HOTKEY_NOT_REGISTERED = 1419;
2557
1706/// The window is not a valid dialog window.2558/// The window is not a valid dialog window.
1707pub const WINDOW_NOT_DIALOG = 1420;2559pub const WINDOW_NOT_DIALOG = 1420;
2560
1708/// Control ID not found.2561/// Control ID not found.
1709pub const CONTROL_ID_NOT_FOUND = 1421;2562pub const CONTROL_ID_NOT_FOUND = 1421;
2563
1710/// Invalid message for a combo box because it does not have an edit control.2564/// Invalid message for a combo box because it does not have an edit control.
1711pub const INVALID_COMBOBOX_MESSAGE = 1422;2565pub const INVALID_COMBOBOX_MESSAGE = 1422;
2566
1712/// The window is not a combo box.2567/// The window is not a combo box.
1713pub const WINDOW_NOT_COMBOBOX = 1423;2568pub const WINDOW_NOT_COMBOBOX = 1423;
2569
1714/// Height must be less than 256.2570/// Height must be less than 256.
1715pub const INVALID_EDIT_HEIGHT = 1424;2571pub const INVALID_EDIT_HEIGHT = 1424;
2572
1716/// Invalid device context (DC) handle.2573/// Invalid device context (DC) handle.
1717pub const DC_NOT_FOUND = 1425;2574pub const DC_NOT_FOUND = 1425;
2575
1718/// Invalid hook procedure type.2576/// Invalid hook procedure type.
1719pub const INVALID_HOOK_FILTER = 1426;2577pub const INVALID_HOOK_FILTER = 1426;
2578
1720/// Invalid hook procedure.2579/// Invalid hook procedure.
1721pub const INVALID_FILTER_PROC = 1427;2580pub const INVALID_FILTER_PROC = 1427;
2581
1722/// Cannot set nonlocal hook without a module handle.2582/// Cannot set nonlocal hook without a module handle.
1723pub const HOOK_NEEDS_HMOD = 1428;2583pub const HOOK_NEEDS_HMOD = 1428;
2584
1724/// This hook procedure can only be set globally.2585/// This hook procedure can only be set globally.
1725pub const GLOBAL_ONLY_HOOK = 1429;2586pub const GLOBAL_ONLY_HOOK = 1429;
2587
1726/// The journal hook procedure is already installed.2588/// The journal hook procedure is already installed.
1727pub const JOURNAL_HOOK_SET = 1430;2589pub const JOURNAL_HOOK_SET = 1430;
2590
1728/// The hook procedure is not installed.2591/// The hook procedure is not installed.
1729pub const HOOK_NOT_INSTALLED = 1431;2592pub const HOOK_NOT_INSTALLED = 1431;
2593
1730/// Invalid message for single-selection list box.2594/// Invalid message for single-selection list box.
1731pub const INVALID_LB_MESSAGE = 1432;2595pub const INVALID_LB_MESSAGE = 1432;
2596
1732/// LB_SETCOUNT sent to non-lazy list box.2597/// LB_SETCOUNT sent to non-lazy list box.
1733pub const SETCOUNT_ON_BAD_LB = 1433;2598pub const SETCOUNT_ON_BAD_LB = 1433;
2599
1734/// This list box does not support tab stops.2600/// This list box does not support tab stops.
1735pub const LB_WITHOUT_TABSTOPS = 1434;2601pub const LB_WITHOUT_TABSTOPS = 1434;
2602
1736/// Cannot destroy object created by another thread.2603/// Cannot destroy object created by another thread.
1737pub const DESTROY_OBJECT_OF_OTHER_THREAD = 1435;2604pub const DESTROY_OBJECT_OF_OTHER_THREAD = 1435;
2605
1738/// Child windows cannot have menus.2606/// Child windows cannot have menus.
1739pub const CHILD_WINDOW_MENU = 1436;2607pub const CHILD_WINDOW_MENU = 1436;
2608
1740/// The window does not have a system menu.2609/// The window does not have a system menu.
1741pub const NO_SYSTEM_MENU = 1437;2610pub const NO_SYSTEM_MENU = 1437;
2611
1742/// Invalid message box style.2612/// Invalid message box style.
1743pub const INVALID_MSGBOX_STYLE = 1438;2613pub const INVALID_MSGBOX_STYLE = 1438;
2614
1744/// Invalid system-wide (SPI_*) parameter.2615/// Invalid system-wide (SPI_*) parameter.
1745pub const INVALID_SPI_VALUE = 1439;2616pub const INVALID_SPI_VALUE = 1439;
2617
1746/// Screen already locked.2618/// Screen already locked.
1747pub const SCREEN_ALREADY_LOCKED = 1440;2619pub const SCREEN_ALREADY_LOCKED = 1440;
2620
1748/// All handles to windows in a multiple-window position structure must have the same parent.2621/// All handles to windows in a multiple-window position structure must have the same parent.
1749pub const HWNDS_HAVE_DIFF_PARENT = 1441;2622pub const HWNDS_HAVE_DIFF_PARENT = 1441;
2623
1750/// The window is not a child window.2624/// The window is not a child window.
1751pub const NOT_CHILD_WINDOW = 1442;2625pub const NOT_CHILD_WINDOW = 1442;
2626
1752/// Invalid GW_* command.2627/// Invalid GW_* command.
1753pub const INVALID_GW_COMMAND = 1443;2628pub const INVALID_GW_COMMAND = 1443;
2629
1754/// Invalid thread identifier.2630/// Invalid thread identifier.
1755pub const INVALID_THREAD_ID = 1444;2631pub const INVALID_THREAD_ID = 1444;
2632
1756/// Cannot process a message from a window that is not a multiple document interface (MDI) window.2633/// Cannot process a message from a window that is not a multiple document interface (MDI) window.
1757pub const NON_MDICHILD_WINDOW = 1445;2634pub const NON_MDICHILD_WINDOW = 1445;
2635
1758/// Popup menu already active.2636/// Popup menu already active.
1759pub const POPUP_ALREADY_ACTIVE = 1446;2637pub const POPUP_ALREADY_ACTIVE = 1446;
2638
1760/// The window does not have scroll bars.2639/// The window does not have scroll bars.
1761pub const NO_SCROLLBARS = 1447;2640pub const NO_SCROLLBARS = 1447;
2641
1762/// Scroll bar range cannot be greater than MAXLONG.2642/// Scroll bar range cannot be greater than MAXLONG.
1763pub const INVALID_SCROLLBAR_RANGE = 1448;2643pub const INVALID_SCROLLBAR_RANGE = 1448;
2644
1764/// Cannot show or remove the window in the way specified.2645/// Cannot show or remove the window in the way specified.
1765pub const INVALID_SHOWWIN_COMMAND = 1449;2646pub const INVALID_SHOWWIN_COMMAND = 1449;
2647
1766/// Insufficient system resources exist to complete the requested service.2648/// Insufficient system resources exist to complete the requested service.
1767pub const NO_SYSTEM_RESOURCES = 1450;2649pub const NO_SYSTEM_RESOURCES = 1450;
2650
1768/// Insufficient system resources exist to complete the requested service.2651/// Insufficient system resources exist to complete the requested service.
1769pub const NONPAGED_SYSTEM_RESOURCES = 1451;2652pub const NONPAGED_SYSTEM_RESOURCES = 1451;
2653
1770/// Insufficient system resources exist to complete the requested service.2654/// Insufficient system resources exist to complete the requested service.
1771pub const PAGED_SYSTEM_RESOURCES = 1452;2655pub const PAGED_SYSTEM_RESOURCES = 1452;
2656
1772/// Insufficient quota to complete the requested service.2657/// Insufficient quota to complete the requested service.
1773pub const WORKING_SET_QUOTA = 1453;2658pub const WORKING_SET_QUOTA = 1453;
2659
1774/// Insufficient quota to complete the requested service.2660/// Insufficient quota to complete the requested service.
1775pub const PAGEFILE_QUOTA = 1454;2661pub const PAGEFILE_QUOTA = 1454;
2662
1776/// The paging file is too small for this operation to complete.2663/// The paging file is too small for this operation to complete.
1777pub const COMMITMENT_LIMIT = 1455;2664pub const COMMITMENT_LIMIT = 1455;
2665
1778/// A menu item was not found.2666/// A menu item was not found.
1779pub const MENU_ITEM_NOT_FOUND = 1456;2667pub const MENU_ITEM_NOT_FOUND = 1456;
2668
1780/// Invalid keyboard layout handle.2669/// Invalid keyboard layout handle.
1781pub const INVALID_KEYBOARD_HANDLE = 1457;2670pub const INVALID_KEYBOARD_HANDLE = 1457;
2671
1782/// Hook type not allowed.2672/// Hook type not allowed.
1783pub const HOOK_TYPE_NOT_ALLOWED = 1458;2673pub const HOOK_TYPE_NOT_ALLOWED = 1458;
2674
1784/// This operation requires an interactive window station.2675/// This operation requires an interactive window station.
1785pub const REQUIRES_INTERACTIVE_WINDOWSTATION = 1459;2676pub const REQUIRES_INTERACTIVE_WINDOWSTATION = 1459;
2677
1786/// This operation returned because the timeout period expired.2678/// This operation returned because the timeout period expired.
1787pub const TIMEOUT = 1460;2679pub const TIMEOUT = 1460;
2680
1788/// Invalid monitor handle.2681/// Invalid monitor handle.
1789pub const INVALID_MONITOR_HANDLE = 1461;2682pub const INVALID_MONITOR_HANDLE = 1461;
2683
1790/// Incorrect size argument.2684/// Incorrect size argument.
1791pub const INCORRECT_SIZE = 1462;2685pub const INCORRECT_SIZE = 1462;
2686
1792/// The symbolic link cannot be followed because its type is disabled.2687/// The symbolic link cannot be followed because its type is disabled.
1793pub const SYMLINK_CLASS_DISABLED = 1463;2688pub const SYMLINK_CLASS_DISABLED = 1463;
2689
1794/// This application does not support the current operation on symbolic links.2690/// This application does not support the current operation on symbolic links.
1795pub const SYMLINK_NOT_SUPPORTED = 1464;2691pub const SYMLINK_NOT_SUPPORTED = 1464;
2692
1796/// Windows was unable to parse the requested XML data.2693/// Windows was unable to parse the requested XML data.
1797pub const XML_PARSE_ERROR = 1465;2694pub const XML_PARSE_ERROR = 1465;
2695
1798/// An error was encountered while processing an XML digital signature.2696/// An error was encountered while processing an XML digital signature.
1799pub const XMLDSIG_ERROR = 1466;2697pub const XMLDSIG_ERROR = 1466;
2698
1800/// This application must be restarted.2699/// This application must be restarted.
1801pub const RESTART_APPLICATION = 1467;2700pub const RESTART_APPLICATION = 1467;
2701
1802/// The caller made the connection request in the wrong routing compartment.2702/// The caller made the connection request in the wrong routing compartment.
1803pub const WRONG_COMPARTMENT = 1468;2703pub const WRONG_COMPARTMENT = 1468;
2704
1804/// There was an AuthIP failure when attempting to connect to the remote host.2705/// There was an AuthIP failure when attempting to connect to the remote host.
1805pub const AUTHIP_FAILURE = 1469;2706pub const AUTHIP_FAILURE = 1469;
2707
1806/// Insufficient NVRAM resources exist to complete the requested service. A reboot might be required.2708/// Insufficient NVRAM resources exist to complete the requested service. A reboot might be required.
1807pub const NO_NVRAM_RESOURCES = 1470;2709pub const NO_NVRAM_RESOURCES = 1470;
2710
1808/// Unable to finish the requested operation because the specified process is not a GUI process.2711/// Unable to finish the requested operation because the specified process is not a GUI process.
1809pub const NOT_GUI_PROCESS = 1471;2712pub const NOT_GUI_PROCESS = 1471;
2713
1810/// The event log file is corrupted.2714/// The event log file is corrupted.
1811pub const EVENTLOG_FILE_CORRUPT = 1500;2715pub const EVENTLOG_FILE_CORRUPT = 1500;
2716
1812/// No event log file could be opened, so the event logging service did not start.2717/// No event log file could be opened, so the event logging service did not start.
1813pub const EVENTLOG_CANT_START = 1501;2718pub const EVENTLOG_CANT_START = 1501;
2719
1814/// The event log file is full.2720/// The event log file is full.
1815pub const LOG_FILE_FULL = 1502;2721pub const LOG_FILE_FULL = 1502;
2722
1816/// The event log file has changed between read operations.2723/// The event log file has changed between read operations.
1817pub const EVENTLOG_FILE_CHANGED = 1503;2724pub const EVENTLOG_FILE_CHANGED = 1503;
2725
1818/// The specified task name is invalid.2726/// The specified task name is invalid.
1819pub const INVALID_TASK_NAME = 1550;2727pub const INVALID_TASK_NAME = 1550;
2728
1820/// The specified task index is invalid.2729/// The specified task index is invalid.
1821pub const INVALID_TASK_INDEX = 1551;2730pub const INVALID_TASK_INDEX = 1551;
2731
1822/// The specified thread is already joining a task.2732/// The specified thread is already joining a task.
1823pub const THREAD_ALREADY_IN_TASK = 1552;2733pub const THREAD_ALREADY_IN_TASK = 1552;
2734
1824/// The Windows Installer Service could not be accessed. This can occur if the Windows Installer is not correctly installed. Contact your support personnel for assistance.2735/// The Windows Installer Service could not be accessed. This can occur if the Windows Installer is not correctly installed. Contact your support personnel for assistance.
1825pub const INSTALL_SERVICE_FAILURE = 1601;2736pub const INSTALL_SERVICE_FAILURE = 1601;
2737
1826/// User cancelled installation.2738/// User cancelled installation.
1827pub const INSTALL_USEREXIT = 1602;2739pub const INSTALL_USEREXIT = 1602;
2740
1828/// Fatal error during installation.2741/// Fatal error during installation.
1829pub const INSTALL_FAILURE = 1603;2742pub const INSTALL_FAILURE = 1603;
2743
1830/// Installation suspended, incomplete.2744/// Installation suspended, incomplete.
1831pub const INSTALL_SUSPEND = 1604;2745pub const INSTALL_SUSPEND = 1604;
2746
1832/// This action is only valid for products that are currently installed.2747/// This action is only valid for products that are currently installed.
1833pub const UNKNOWN_PRODUCT = 1605;2748pub const UNKNOWN_PRODUCT = 1605;
2749
1834/// Feature ID not registered.2750/// Feature ID not registered.
1835pub const UNKNOWN_FEATURE = 1606;2751pub const UNKNOWN_FEATURE = 1606;
2752
1836/// Component ID not registered.2753/// Component ID not registered.
1837pub const UNKNOWN_COMPONENT = 1607;2754pub const UNKNOWN_COMPONENT = 1607;
2755
1838/// Unknown property.2756/// Unknown property.
1839pub const UNKNOWN_PROPERTY = 1608;2757pub const UNKNOWN_PROPERTY = 1608;
2758
1840/// Handle is in an invalid state.2759/// Handle is in an invalid state.
1841pub const INVALID_HANDLE_STATE = 1609;2760pub const INVALID_HANDLE_STATE = 1609;
2761
1842/// The configuration data for this product is corrupt. Contact your support personnel.2762/// The configuration data for this product is corrupt. Contact your support personnel.
1843pub const BAD_CONFIGURATION = 1610;2763pub const BAD_CONFIGURATION = 1610;
2764
1844/// Component qualifier not present.2765/// Component qualifier not present.
1845pub const INDEX_ABSENT = 1611;2766pub const INDEX_ABSENT = 1611;
2767
1846/// The installation source for this product is not available. Verify that the source exists and that you can access it.2768/// The installation source for this product is not available. Verify that the source exists and that you can access it.
1847pub const INSTALL_SOURCE_ABSENT = 1612;2769pub const INSTALL_SOURCE_ABSENT = 1612;
2770
1848/// This installation package cannot be installed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service.2771/// This installation package cannot be installed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service.
1849pub const INSTALL_PACKAGE_VERSION = 1613;2772pub const INSTALL_PACKAGE_VERSION = 1613;
2773
1850/// Product is uninstalled.2774/// Product is uninstalled.
1851pub const PRODUCT_UNINSTALLED = 1614;2775pub const PRODUCT_UNINSTALLED = 1614;
2776
1852/// SQL query syntax invalid or unsupported.2777/// SQL query syntax invalid or unsupported.
1853pub const BAD_QUERY_SYNTAX = 1615;2778pub const BAD_QUERY_SYNTAX = 1615;
2779
1854/// Record field does not exist.2780/// Record field does not exist.
1855pub const INVALID_FIELD = 1616;2781pub const INVALID_FIELD = 1616;
2782
1856/// The device has been removed.2783/// The device has been removed.
1857pub const DEVICE_REMOVED = 1617;2784pub const DEVICE_REMOVED = 1617;
2785
1858/// Another installation is already in progress. Complete that installation before proceeding with this install.2786/// Another installation is already in progress. Complete that installation before proceeding with this install.
1859pub const INSTALL_ALREADY_RUNNING = 1618;2787pub const INSTALL_ALREADY_RUNNING = 1618;
2788
1860/// This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.2789/// This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.
1861pub const INSTALL_PACKAGE_OPEN_FAILED = 1619;2790pub const INSTALL_PACKAGE_OPEN_FAILED = 1619;
2791
1862/// This installation package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer package.2792/// This installation package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer package.
1863pub const INSTALL_PACKAGE_INVALID = 1620;2793pub const INSTALL_PACKAGE_INVALID = 1620;
2794
1864/// There was an error starting the Windows Installer service user interface. Contact your support personnel.2795/// There was an error starting the Windows Installer service user interface. Contact your support personnel.
1865pub const INSTALL_UI_FAILURE = 1621;2796pub const INSTALL_UI_FAILURE = 1621;
2797
1866/// Error opening installation log file. Verify that the specified log file location exists and that you can write to it.2798/// Error opening installation log file. Verify that the specified log file location exists and that you can write to it.
1867pub const INSTALL_LOG_FAILURE = 1622;2799pub const INSTALL_LOG_FAILURE = 1622;
2800
1868/// The language of this installation package is not supported by your system.2801/// The language of this installation package is not supported by your system.
1869pub const INSTALL_LANGUAGE_UNSUPPORTED = 1623;2802pub const INSTALL_LANGUAGE_UNSUPPORTED = 1623;
2803
1870/// Error applying transforms. Verify that the specified transform paths are valid.2804/// Error applying transforms. Verify that the specified transform paths are valid.
1871pub const INSTALL_TRANSFORM_FAILURE = 1624;2805pub const INSTALL_TRANSFORM_FAILURE = 1624;
2806
1872/// This installation is forbidden by system policy. Contact your system administrator.2807/// This installation is forbidden by system policy. Contact your system administrator.
1873pub const INSTALL_PACKAGE_REJECTED = 1625;2808pub const INSTALL_PACKAGE_REJECTED = 1625;
2809
1874/// Function could not be executed.2810/// Function could not be executed.
1875pub const FUNCTION_NOT_CALLED = 1626;2811pub const FUNCTION_NOT_CALLED = 1626;
2812
1876/// Function failed during execution.2813/// Function failed during execution.
1877pub const FUNCTION_FAILED = 1627;2814pub const FUNCTION_FAILED = 1627;
2815
1878/// Invalid or unknown table specified.2816/// Invalid or unknown table specified.
1879pub const INVALID_TABLE = 1628;2817pub const INVALID_TABLE = 1628;
2818
1880/// Data supplied is of wrong type.2819/// Data supplied is of wrong type.
1881pub const DATATYPE_MISMATCH = 1629;2820pub const DATATYPE_MISMATCH = 1629;
2821
1882/// Data of this type is not supported.2822/// Data of this type is not supported.
1883pub const UNSUPPORTED_TYPE = 1630;2823pub const UNSUPPORTED_TYPE = 1630;
2824
1884/// The Windows Installer service failed to start. Contact your support personnel.2825/// The Windows Installer service failed to start. Contact your support personnel.
1885pub const CREATE_FAILED = 1631;2826pub const CREATE_FAILED = 1631;
2827
1886/// The Temp folder is on a drive that is full or is inaccessible. Free up space on the drive or verify that you have write permission on the Temp folder.2828/// The Temp folder is on a drive that is full or is inaccessible. Free up space on the drive or verify that you have write permission on the Temp folder.
1887pub const INSTALL_TEMP_UNWRITABLE = 1632;2829pub const INSTALL_TEMP_UNWRITABLE = 1632;
2830
1888/// This installation package is not supported by this processor type. Contact your product vendor.2831/// This installation package is not supported by this processor type. Contact your product vendor.
1889pub const INSTALL_PLATFORM_UNSUPPORTED = 1633;2832pub const INSTALL_PLATFORM_UNSUPPORTED = 1633;
2833
1890/// Component not used on this computer.2834/// Component not used on this computer.
1891pub const INSTALL_NOTUSED = 1634;2835pub const INSTALL_NOTUSED = 1634;
2836
1892/// This update package could not be opened. Verify that the update package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer update package.2837/// This update package could not be opened. Verify that the update package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer update package.
1893pub const PATCH_PACKAGE_OPEN_FAILED = 1635;2838pub const PATCH_PACKAGE_OPEN_FAILED = 1635;
2839
1894/// This update package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer update package.2840/// This update package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer update package.
1895pub const PATCH_PACKAGE_INVALID = 1636;2841pub const PATCH_PACKAGE_INVALID = 1636;
2842
1896/// This update package cannot be processed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service.2843/// This update package cannot be processed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service.
1897pub const PATCH_PACKAGE_UNSUPPORTED = 1637;2844pub const PATCH_PACKAGE_UNSUPPORTED = 1637;
2845
1898/// Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel.2846/// Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel.
1899pub const PRODUCT_VERSION = 1638;2847pub const PRODUCT_VERSION = 1638;
2848
1900/// Invalid command line argument. Consult the Windows Installer SDK for detailed command line help.2849/// Invalid command line argument. Consult the Windows Installer SDK for detailed command line help.
1901pub const INVALID_COMMAND_LINE = 1639;2850pub const INVALID_COMMAND_LINE = 1639;
2851
1902/// Only administrators have permission to add, remove, or configure server software during a Terminal services remote session. If you want to install or configure software on the server, contact your network administrator.2852/// Only administrators have permission to add, remove, or configure server software during a Terminal services remote session. If you want to install or configure software on the server, contact your network administrator.
1903pub const INSTALL_REMOTE_DISALLOWED = 1640;2853pub const INSTALL_REMOTE_DISALLOWED = 1640;
2854
1904/// The requested operation completed successfully. The system will be restarted so the changes can take effect.2855/// The requested operation completed successfully. The system will be restarted so the changes can take effect.
1905pub const SUCCESS_REBOOT_INITIATED = 1641;2856pub const SUCCESS_REBOOT_INITIATED = 1641;
2857
1906/// The upgrade cannot be installed by the Windows Installer service because the program to be upgraded may be missing, or the upgrade may update a different version of the program. Verify that the program to be upgraded exists on your computer and that you have the correct upgrade.2858/// The upgrade cannot be installed by the Windows Installer service because the program to be upgraded may be missing, or the upgrade may update a different version of the program. Verify that the program to be upgraded exists on your computer and that you have the correct upgrade.
1907pub const PATCH_TARGET_NOT_FOUND = 1642;2859pub const PATCH_TARGET_NOT_FOUND = 1642;
2860
1908/// The update package is not permitted by software restriction policy.2861/// The update package is not permitted by software restriction policy.
1909pub const PATCH_PACKAGE_REJECTED = 1643;2862pub const PATCH_PACKAGE_REJECTED = 1643;
2863
1910/// One or more customizations are not permitted by software restriction policy.2864/// One or more customizations are not permitted by software restriction policy.
1911pub const INSTALL_TRANSFORM_REJECTED = 1644;2865pub const INSTALL_TRANSFORM_REJECTED = 1644;
2866
1912/// The Windows Installer does not permit installation from a Remote Desktop Connection.2867/// The Windows Installer does not permit installation from a Remote Desktop Connection.
1913pub const INSTALL_REMOTE_PROHIBITED = 1645;2868pub const INSTALL_REMOTE_PROHIBITED = 1645;
2869
1914/// Uninstallation of the update package is not supported.2870/// Uninstallation of the update package is not supported.
1915pub const PATCH_REMOVAL_UNSUPPORTED = 1646;2871pub const PATCH_REMOVAL_UNSUPPORTED = 1646;
2872
1916/// The update is not applied to this product.2873/// The update is not applied to this product.
1917pub const UNKNOWN_PATCH = 1647;2874pub const UNKNOWN_PATCH = 1647;
2875
1918/// No valid sequence could be found for the set of updates.2876/// No valid sequence could be found for the set of updates.
1919pub const PATCH_NO_SEQUENCE = 1648;2877pub const PATCH_NO_SEQUENCE = 1648;
2878
1920/// Update removal was disallowed by policy.2879/// Update removal was disallowed by policy.
1921pub const PATCH_REMOVAL_DISALLOWED = 1649;2880pub const PATCH_REMOVAL_DISALLOWED = 1649;
2881
1922/// The XML update data is invalid.2882/// The XML update data is invalid.
1923pub const INVALID_PATCH_XML = 1650;2883pub const INVALID_PATCH_XML = 1650;
2884
1924/// Windows Installer does not permit updating of managed advertised products. At least one feature of the product must be installed before applying the update.2885/// Windows Installer does not permit updating of managed advertised products. At least one feature of the product must be installed before applying the update.
1925pub const PATCH_MANAGED_ADVERTISED_PRODUCT = 1651;2886pub const PATCH_MANAGED_ADVERTISED_PRODUCT = 1651;
2887
1926/// The Windows Installer service is not accessible in Safe Mode. Please try again when your computer is not in Safe Mode or you can use System Restore to return your machine to a previous good state.2888/// The Windows Installer service is not accessible in Safe Mode. Please try again when your computer is not in Safe Mode or you can use System Restore to return your machine to a previous good state.
1927pub const INSTALL_SERVICE_SAFEBOOT = 1652;2889pub const INSTALL_SERVICE_SAFEBOOT = 1652;
2890
1928/// A fail fast exception occurred. Exception handlers will not be invoked and the process will be terminated immediately.2891/// A fail fast exception occurred. Exception handlers will not be invoked and the process will be terminated immediately.
1929pub const FAIL_FAST_EXCEPTION = 1653;2892pub const FAIL_FAST_EXCEPTION = 1653;
2893
1930/// The app that you are trying to run is not supported on this version of Windows.2894/// The app that you are trying to run is not supported on this version of Windows.
1931pub const INSTALL_REJECTED = 1654;2895pub const INSTALL_REJECTED = 1654;
2896
1932/// The string binding is invalid.2897/// The string binding is invalid.
1933pub const RPC_S_INVALID_STRING_BINDING = 1700;2898pub const RPC_S_INVALID_STRING_BINDING = 1700;
2899
1934/// The binding handle is not the correct type.2900/// The binding handle is not the correct type.
1935pub const RPC_S_WRONG_KIND_OF_BINDING = 1701;2901pub const RPC_S_WRONG_KIND_OF_BINDING = 1701;
2902
1936/// The binding handle is invalid.2903/// The binding handle is invalid.
1937pub const RPC_S_INVALID_BINDING = 1702;2904pub const RPC_S_INVALID_BINDING = 1702;
2905
1938/// The RPC protocol sequence is not supported.2906/// The RPC protocol sequence is not supported.
1939pub const RPC_S_PROTSEQ_NOT_SUPPORTED = 1703;2907pub const RPC_S_PROTSEQ_NOT_SUPPORTED = 1703;
2908
1940/// The RPC protocol sequence is invalid.2909/// The RPC protocol sequence is invalid.
1941pub const RPC_S_INVALID_RPC_PROTSEQ = 1704;2910pub const RPC_S_INVALID_RPC_PROTSEQ = 1704;
2911
1942/// The string universal unique identifier (UUID) is invalid.2912/// The string universal unique identifier (UUID) is invalid.
1943pub const RPC_S_INVALID_STRING_UUID = 1705;2913pub const RPC_S_INVALID_STRING_UUID = 1705;
2914
1944/// The endpoint format is invalid.2915/// The endpoint format is invalid.
1945pub const RPC_S_INVALID_ENDPOINT_FORMAT = 1706;2916pub const RPC_S_INVALID_ENDPOINT_FORMAT = 1706;
2917
1946/// The network address is invalid.2918/// The network address is invalid.
1947pub const RPC_S_INVALID_NET_ADDR = 1707;2919pub const RPC_S_INVALID_NET_ADDR = 1707;
2920
1948/// No endpoint was found.2921/// No endpoint was found.
1949pub const RPC_S_NO_ENDPOINT_FOUND = 1708;2922pub const RPC_S_NO_ENDPOINT_FOUND = 1708;
2923
1950/// The timeout value is invalid.2924/// The timeout value is invalid.
1951pub const RPC_S_INVALID_TIMEOUT = 1709;2925pub const RPC_S_INVALID_TIMEOUT = 1709;
2926
1952/// The object universal unique identifier (UUID) was not found.2927/// The object universal unique identifier (UUID) was not found.
1953pub const RPC_S_OBJECT_NOT_FOUND = 1710;2928pub const RPC_S_OBJECT_NOT_FOUND = 1710;
2929
1954/// The object universal unique identifier (UUID) has already been registered.2930/// The object universal unique identifier (UUID) has already been registered.
1955pub const RPC_S_ALREADY_REGISTERED = 1711;2931pub const RPC_S_ALREADY_REGISTERED = 1711;
2932
1956/// The type universal unique identifier (UUID) has already been registered.2933/// The type universal unique identifier (UUID) has already been registered.
1957pub const RPC_S_TYPE_ALREADY_REGISTERED = 1712;2934pub const RPC_S_TYPE_ALREADY_REGISTERED = 1712;
2935
1958/// The RPC server is already listening.2936/// The RPC server is already listening.
1959pub const RPC_S_ALREADY_LISTENING = 1713;2937pub const RPC_S_ALREADY_LISTENING = 1713;
2938
1960/// No protocol sequences have been registered.2939/// No protocol sequences have been registered.
1961pub const RPC_S_NO_PROTSEQS_REGISTERED = 1714;2940pub const RPC_S_NO_PROTSEQS_REGISTERED = 1714;
2941
1962/// The RPC server is not listening.2942/// The RPC server is not listening.
1963pub const RPC_S_NOT_LISTENING = 1715;2943pub const RPC_S_NOT_LISTENING = 1715;
2944
1964/// The manager type is unknown.2945/// The manager type is unknown.
1965pub const RPC_S_UNKNOWN_MGR_TYPE = 1716;2946pub const RPC_S_UNKNOWN_MGR_TYPE = 1716;
2947
1966/// The interface is unknown.2948/// The interface is unknown.
1967pub const RPC_S_UNKNOWN_IF = 1717;2949pub const RPC_S_UNKNOWN_IF = 1717;
2950
1968/// There are no bindings.2951/// There are no bindings.
1969pub const RPC_S_NO_BINDINGS = 1718;2952pub const RPC_S_NO_BINDINGS = 1718;
2953
1970/// There are no protocol sequences.2954/// There are no protocol sequences.
1971pub const RPC_S_NO_PROTSEQS = 1719;2955pub const RPC_S_NO_PROTSEQS = 1719;
2956
1972/// The endpoint cannot be created.2957/// The endpoint cannot be created.
1973pub const RPC_S_CANT_CREATE_ENDPOINT = 1720;2958pub const RPC_S_CANT_CREATE_ENDPOINT = 1720;
2959
1974/// Not enough resources are available to complete this operation.2960/// Not enough resources are available to complete this operation.
1975pub const RPC_S_OUT_OF_RESOURCES = 1721;2961pub const RPC_S_OUT_OF_RESOURCES = 1721;
2962
1976/// The RPC server is unavailable.2963/// The RPC server is unavailable.
1977pub const RPC_S_SERVER_UNAVAILABLE = 1722;2964pub const RPC_S_SERVER_UNAVAILABLE = 1722;
2965
1978/// The RPC server is too busy to complete this operation.2966/// The RPC server is too busy to complete this operation.
1979pub const RPC_S_SERVER_TOO_BUSY = 1723;2967pub const RPC_S_SERVER_TOO_BUSY = 1723;
2968
1980/// The network options are invalid.2969/// The network options are invalid.
1981pub const RPC_S_INVALID_NETWORK_OPTIONS = 1724;2970pub const RPC_S_INVALID_NETWORK_OPTIONS = 1724;
2971
1982/// There are no remote procedure calls active on this thread.2972/// There are no remote procedure calls active on this thread.
1983pub const RPC_S_NO_CALL_ACTIVE = 1725;2973pub const RPC_S_NO_CALL_ACTIVE = 1725;
2974
1984/// The remote procedure call failed.2975/// The remote procedure call failed.
1985pub const RPC_S_CALL_FAILED = 1726;2976pub const RPC_S_CALL_FAILED = 1726;
2977
1986/// The remote procedure call failed and did not execute.2978/// The remote procedure call failed and did not execute.
1987pub const RPC_S_CALL_FAILED_DNE = 1727;2979pub const RPC_S_CALL_FAILED_DNE = 1727;
2980
1988/// A remote procedure call (RPC) protocol error occurred.2981/// A remote procedure call (RPC) protocol error occurred.
1989pub const RPC_S_PROTOCOL_ERROR = 1728;2982pub const RPC_S_PROTOCOL_ERROR = 1728;
2983
1990/// Access to the HTTP proxy is denied.2984/// Access to the HTTP proxy is denied.
1991pub const RPC_S_PROXY_ACCESS_DENIED = 1729;2985pub const RPC_S_PROXY_ACCESS_DENIED = 1729;
2986
1992/// The transfer syntax is not supported by the RPC server.2987/// The transfer syntax is not supported by the RPC server.
1993pub const RPC_S_UNSUPPORTED_TRANS_SYN = 1730;2988pub const RPC_S_UNSUPPORTED_TRANS_SYN = 1730;
2989
1994/// The universal unique identifier (UUID) type is not supported.2990/// The universal unique identifier (UUID) type is not supported.
1995pub const RPC_S_UNSUPPORTED_TYPE = 1732;2991pub const RPC_S_UNSUPPORTED_TYPE = 1732;
2992
1996/// The tag is invalid.2993/// The tag is invalid.
1997pub const RPC_S_INVALID_TAG = 1733;2994pub const RPC_S_INVALID_TAG = 1733;
2995
1998/// The array bounds are invalid.2996/// The array bounds are invalid.
1999pub const RPC_S_INVALID_BOUND = 1734;2997pub const RPC_S_INVALID_BOUND = 1734;
2998
2000/// The binding does not contain an entry name.2999/// The binding does not contain an entry name.
2001pub const RPC_S_NO_ENTRY_NAME = 1735;3000pub const RPC_S_NO_ENTRY_NAME = 1735;
3001
2002/// The name syntax is invalid.3002/// The name syntax is invalid.
2003pub const RPC_S_INVALID_NAME_SYNTAX = 1736;3003pub const RPC_S_INVALID_NAME_SYNTAX = 1736;
3004
2004/// The name syntax is not supported.3005/// The name syntax is not supported.
2005pub const RPC_S_UNSUPPORTED_NAME_SYNTAX = 1737;3006pub const RPC_S_UNSUPPORTED_NAME_SYNTAX = 1737;
3007
2006/// No network address is available to use to construct a universal unique identifier (UUID).3008/// No network address is available to use to construct a universal unique identifier (UUID).
2007pub const RPC_S_UUID_NO_ADDRESS = 1739;3009pub const RPC_S_UUID_NO_ADDRESS = 1739;
3010
2008/// The endpoint is a duplicate.3011/// The endpoint is a duplicate.
2009pub const RPC_S_DUPLICATE_ENDPOINT = 1740;3012pub const RPC_S_DUPLICATE_ENDPOINT = 1740;
3013
2010/// The authentication type is unknown.3014/// The authentication type is unknown.
2011pub const RPC_S_UNKNOWN_AUTHN_TYPE = 1741;3015pub const RPC_S_UNKNOWN_AUTHN_TYPE = 1741;
3016
2012/// The maximum number of calls is too small.3017/// The maximum number of calls is too small.
2013pub const RPC_S_MAX_CALLS_TOO_SMALL = 1742;3018pub const RPC_S_MAX_CALLS_TOO_SMALL = 1742;
3019
2014/// The string is too long.3020/// The string is too long.
2015pub const RPC_S_STRING_TOO_LONG = 1743;3021pub const RPC_S_STRING_TOO_LONG = 1743;
3022
2016/// The RPC protocol sequence was not found.3023/// The RPC protocol sequence was not found.
2017pub const RPC_S_PROTSEQ_NOT_FOUND = 1744;3024pub const RPC_S_PROTSEQ_NOT_FOUND = 1744;
3025
2018/// The procedure number is out of range.3026/// The procedure number is out of range.
2019pub const RPC_S_PROCNUM_OUT_OF_RANGE = 1745;3027pub const RPC_S_PROCNUM_OUT_OF_RANGE = 1745;
3028
2020/// The binding does not contain any authentication information.3029/// The binding does not contain any authentication information.
2021pub const RPC_S_BINDING_HAS_NO_AUTH = 1746;3030pub const RPC_S_BINDING_HAS_NO_AUTH = 1746;
3031
2022/// The authentication service is unknown.3032/// The authentication service is unknown.
2023pub const RPC_S_UNKNOWN_AUTHN_SERVICE = 1747;3033pub const RPC_S_UNKNOWN_AUTHN_SERVICE = 1747;
3034
2024/// The authentication level is unknown.3035/// The authentication level is unknown.
2025pub const RPC_S_UNKNOWN_AUTHN_LEVEL = 1748;3036pub const RPC_S_UNKNOWN_AUTHN_LEVEL = 1748;
3037
2026/// The security context is invalid.3038/// The security context is invalid.
2027pub const RPC_S_INVALID_AUTH_IDENTITY = 1749;3039pub const RPC_S_INVALID_AUTH_IDENTITY = 1749;
3040
2028/// The authorization service is unknown.3041/// The authorization service is unknown.
2029pub const RPC_S_UNKNOWN_AUTHZ_SERVICE = 1750;3042pub const RPC_S_UNKNOWN_AUTHZ_SERVICE = 1750;
3043
2030/// The entry is invalid.3044/// The entry is invalid.
2031pub const EPT_S_INVALID_ENTRY = 1751;3045pub const EPT_S_INVALID_ENTRY = 1751;
3046
2032/// The server endpoint cannot perform the operation.3047/// The server endpoint cannot perform the operation.
2033pub const EPT_S_CANT_PERFORM_OP = 1752;3048pub const EPT_S_CANT_PERFORM_OP = 1752;
3049
2034/// There are no more endpoints available from the endpoint mapper.3050/// There are no more endpoints available from the endpoint mapper.
2035pub const EPT_S_NOT_REGISTERED = 1753;3051pub const EPT_S_NOT_REGISTERED = 1753;
3052
2036/// No interfaces have been exported.3053/// No interfaces have been exported.
2037pub const RPC_S_NOTHING_TO_EXPORT = 1754;3054pub const RPC_S_NOTHING_TO_EXPORT = 1754;
3055
2038/// The entry name is incomplete.3056/// The entry name is incomplete.
2039pub const RPC_S_INCOMPLETE_NAME = 1755;3057pub const RPC_S_INCOMPLETE_NAME = 1755;
3058
2040/// The version option is invalid.3059/// The version option is invalid.
2041pub const RPC_S_INVALID_VERS_OPTION = 1756;3060pub const RPC_S_INVALID_VERS_OPTION = 1756;
3061
2042/// There are no more members.3062/// There are no more members.
2043pub const RPC_S_NO_MORE_MEMBERS = 1757;3063pub const RPC_S_NO_MORE_MEMBERS = 1757;
3064
2044/// There is nothing to unexport.3065/// There is nothing to unexport.
2045pub const RPC_S_NOT_ALL_OBJS_UNEXPORTED = 1758;3066pub const RPC_S_NOT_ALL_OBJS_UNEXPORTED = 1758;
3067
2046/// The interface was not found.3068/// The interface was not found.
2047pub const RPC_S_INTERFACE_NOT_FOUND = 1759;3069pub const RPC_S_INTERFACE_NOT_FOUND = 1759;
3070
2048/// The entry already exists.3071/// The entry already exists.
2049pub const RPC_S_ENTRY_ALREADY_EXISTS = 1760;3072pub const RPC_S_ENTRY_ALREADY_EXISTS = 1760;
3073
2050/// The entry is not found.3074/// The entry is not found.
2051pub const RPC_S_ENTRY_NOT_FOUND = 1761;3075pub const RPC_S_ENTRY_NOT_FOUND = 1761;
3076
2052/// The name service is unavailable.3077/// The name service is unavailable.
2053pub const RPC_S_NAME_SERVICE_UNAVAILABLE = 1762;3078pub const RPC_S_NAME_SERVICE_UNAVAILABLE = 1762;
3079
2054/// The network address family is invalid.3080/// The network address family is invalid.
2055pub const RPC_S_INVALID_NAF_ID = 1763;3081pub const RPC_S_INVALID_NAF_ID = 1763;
3082
2056/// The requested operation is not supported.3083/// The requested operation is not supported.
2057pub const RPC_S_CANNOT_SUPPORT = 1764;3084pub const RPC_S_CANNOT_SUPPORT = 1764;
3085
2058/// No security context is available to allow impersonation.3086/// No security context is available to allow impersonation.
2059pub const RPC_S_NO_CONTEXT_AVAILABLE = 1765;3087pub const RPC_S_NO_CONTEXT_AVAILABLE = 1765;
3088
2060/// An internal error occurred in a remote procedure call (RPC).3089/// An internal error occurred in a remote procedure call (RPC).
2061pub const RPC_S_INTERNAL_ERROR = 1766;3090pub const RPC_S_INTERNAL_ERROR = 1766;
3091
2062/// The RPC server attempted an integer division by zero.3092/// The RPC server attempted an integer division by zero.
2063pub const RPC_S_ZERO_DIVIDE = 1767;3093pub const RPC_S_ZERO_DIVIDE = 1767;
3094
2064/// An addressing error occurred in the RPC server.3095/// An addressing error occurred in the RPC server.
2065pub const RPC_S_ADDRESS_ERROR = 1768;3096pub const RPC_S_ADDRESS_ERROR = 1768;
3097
2066/// A floating-point operation at the RPC server caused a division by zero.3098/// A floating-point operation at the RPC server caused a division by zero.
2067pub const RPC_S_FP_DIV_ZERO = 1769;3099pub const RPC_S_FP_DIV_ZERO = 1769;
3100
2068/// A floating-point underflow occurred at the RPC server.3101/// A floating-point underflow occurred at the RPC server.
2069pub const RPC_S_FP_UNDERFLOW = 1770;3102pub const RPC_S_FP_UNDERFLOW = 1770;
3103
2070/// A floating-point overflow occurred at the RPC server.3104/// A floating-point overflow occurred at the RPC server.
2071pub const RPC_S_FP_OVERFLOW = 1771;3105pub const RPC_S_FP_OVERFLOW = 1771;
3106
2072/// The list of RPC servers available for the binding of auto handles has been exhausted.3107/// The list of RPC servers available for the binding of auto handles has been exhausted.
2073pub const RPC_X_NO_MORE_ENTRIES = 1772;3108pub const RPC_X_NO_MORE_ENTRIES = 1772;
3109
2074/// Unable to open the character translation table file.3110/// Unable to open the character translation table file.
2075pub const RPC_X_SS_CHAR_TRANS_OPEN_FAIL = 1773;3111pub const RPC_X_SS_CHAR_TRANS_OPEN_FAIL = 1773;
3112
2076/// The file containing the character translation table has fewer than 512 bytes.3113/// The file containing the character translation table has fewer than 512 bytes.
2077pub const RPC_X_SS_CHAR_TRANS_SHORT_FILE = 1774;3114pub const RPC_X_SS_CHAR_TRANS_SHORT_FILE = 1774;
3115
2078/// A null context handle was passed from the client to the host during a remote procedure call.3116/// A null context handle was passed from the client to the host during a remote procedure call.
2079pub const RPC_X_SS_IN_NULL_CONTEXT = 1775;3117pub const RPC_X_SS_IN_NULL_CONTEXT = 1775;
3118
2080/// The context handle changed during a remote procedure call.3119/// The context handle changed during a remote procedure call.
2081pub const RPC_X_SS_CONTEXT_DAMAGED = 1777;3120pub const RPC_X_SS_CONTEXT_DAMAGED = 1777;
3121
2082/// The binding handles passed to a remote procedure call do not match.3122/// The binding handles passed to a remote procedure call do not match.
2083pub const RPC_X_SS_HANDLES_MISMATCH = 1778;3123pub const RPC_X_SS_HANDLES_MISMATCH = 1778;
3124
2084/// The stub is unable to get the remote procedure call handle.3125/// The stub is unable to get the remote procedure call handle.
2085pub const RPC_X_SS_CANNOT_GET_CALL_HANDLE = 1779;3126pub const RPC_X_SS_CANNOT_GET_CALL_HANDLE = 1779;
3127
2086/// A null reference pointer was passed to the stub.3128/// A null reference pointer was passed to the stub.
2087pub const RPC_X_NULL_REF_POINTER = 1780;3129pub const RPC_X_NULL_REF_POINTER = 1780;
3130
2088/// The enumeration value is out of range.3131/// The enumeration value is out of range.
2089pub const RPC_X_ENUM_VALUE_OUT_OF_RANGE = 1781;3132pub const RPC_X_ENUM_VALUE_OUT_OF_RANGE = 1781;
3133
2090/// The byte count is too small.3134/// The byte count is too small.
2091pub const RPC_X_BYTE_COUNT_TOO_SMALL = 1782;3135pub const RPC_X_BYTE_COUNT_TOO_SMALL = 1782;
3136
2092/// The stub received bad data.3137/// The stub received bad data.
2093pub const RPC_X_BAD_STUB_DATA = 1783;3138pub const RPC_X_BAD_STUB_DATA = 1783;
3139
2094/// The supplied user buffer is not valid for the requested operation.3140/// The supplied user buffer is not valid for the requested operation.
2095pub const INVALID_USER_BUFFER = 1784;3141pub const INVALID_USER_BUFFER = 1784;
3142
2096/// The disk media is not recognized. It may not be formatted.3143/// The disk media is not recognized. It may not be formatted.
2097pub const UNRECOGNIZED_MEDIA = 1785;3144pub const UNRECOGNIZED_MEDIA = 1785;
3145
2098/// The workstation does not have a trust secret.3146/// The workstation does not have a trust secret.
2099pub const NO_TRUST_LSA_SECRET = 1786;3147pub const NO_TRUST_LSA_SECRET = 1786;
3148
2100/// The security database on the server does not have a computer account for this workstation trust relationship.3149/// The security database on the server does not have a computer account for this workstation trust relationship.
2101pub const NO_TRUST_SAM_ACCOUNT = 1787;3150pub const NO_TRUST_SAM_ACCOUNT = 1787;
3151
2102/// The trust relationship between the primary domain and the trusted domain failed.3152/// The trust relationship between the primary domain and the trusted domain failed.
2103pub const TRUSTED_DOMAIN_FAILURE = 1788;3153pub const TRUSTED_DOMAIN_FAILURE = 1788;
3154
2104/// The trust relationship between this workstation and the primary domain failed.3155/// The trust relationship between this workstation and the primary domain failed.
2105pub const TRUSTED_RELATIONSHIP_FAILURE = 1789;3156pub const TRUSTED_RELATIONSHIP_FAILURE = 1789;
3157
2106/// The network logon failed.3158/// The network logon failed.
2107pub const TRUST_FAILURE = 1790;3159pub const TRUST_FAILURE = 1790;
3160
2108/// A remote procedure call is already in progress for this thread.3161/// A remote procedure call is already in progress for this thread.
2109pub const RPC_S_CALL_IN_PROGRESS = 1791;3162pub const RPC_S_CALL_IN_PROGRESS = 1791;
3163
2110/// An attempt was made to logon, but the network logon service was not started.3164/// An attempt was made to logon, but the network logon service was not started.
2111pub const NETLOGON_NOT_STARTED = 1792;3165pub const NETLOGON_NOT_STARTED = 1792;
3166
2112/// The user's account has expired.3167/// The user's account has expired.
2113pub const ACCOUNT_EXPIRED = 1793;3168pub const ACCOUNT_EXPIRED = 1793;
3169
2114/// The redirector is in use and cannot be unloaded.3170/// The redirector is in use and cannot be unloaded.
2115pub const REDIRECTOR_HAS_OPEN_HANDLES = 1794;3171pub const REDIRECTOR_HAS_OPEN_HANDLES = 1794;
3172
2116/// The specified printer driver is already installed.3173/// The specified printer driver is already installed.
2117pub const PRINTER_DRIVER_ALREADY_INSTALLED = 1795;3174pub const PRINTER_DRIVER_ALREADY_INSTALLED = 1795;
3175
2118/// The specified port is unknown.3176/// The specified port is unknown.
2119pub const UNKNOWN_PORT = 1796;3177pub const UNKNOWN_PORT = 1796;
3178
2120/// The printer driver is unknown.3179/// The printer driver is unknown.
2121pub const UNKNOWN_PRINTER_DRIVER = 1797;3180pub const UNKNOWN_PRINTER_DRIVER = 1797;
3181
2122/// The print processor is unknown.3182/// The print processor is unknown.
2123pub const UNKNOWN_PRINTPROCESSOR = 1798;3183pub const UNKNOWN_PRINTPROCESSOR = 1798;
3184
2124/// The specified separator file is invalid.3185/// The specified separator file is invalid.
2125pub const INVALID_SEPARATOR_FILE = 1799;3186pub const INVALID_SEPARATOR_FILE = 1799;
3187
2126/// The specified priority is invalid.3188/// The specified priority is invalid.
2127pub const INVALID_PRIORITY = 1800;3189pub const INVALID_PRIORITY = 1800;
3190
2128/// The printer name is invalid.3191/// The printer name is invalid.
2129pub const INVALID_PRINTER_NAME = 1801;3192pub const INVALID_PRINTER_NAME = 1801;
3193
2130/// The printer already exists.3194/// The printer already exists.
2131pub const PRINTER_ALREADY_EXISTS = 1802;3195pub const PRINTER_ALREADY_EXISTS = 1802;
3196
2132/// The printer command is invalid.3197/// The printer command is invalid.
2133pub const INVALID_PRINTER_COMMAND = 1803;3198pub const INVALID_PRINTER_COMMAND = 1803;
3199
2134/// The specified datatype is invalid.3200/// The specified datatype is invalid.
2135pub const INVALID_DATATYPE = 1804;3201pub const INVALID_DATATYPE = 1804;
3202
2136/// The environment specified is invalid.3203/// The environment specified is invalid.
2137pub const INVALID_ENVIRONMENT = 1805;3204pub const INVALID_ENVIRONMENT = 1805;
3205
2138/// There are no more bindings.3206/// There are no more bindings.
2139pub const RPC_S_NO_MORE_BINDINGS = 1806;3207pub const RPC_S_NO_MORE_BINDINGS = 1806;
3208
2140/// The account used is an interdomain trust account. Use your global user account or local user account to access this server.3209/// The account used is an interdomain trust account. Use your global user account or local user account to access this server.
2141pub const NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 1807;3210pub const NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 1807;
3211
2142/// The account used is a computer account. Use your global user account or local user account to access this server.3212/// The account used is a computer account. Use your global user account or local user account to access this server.
2143pub const NOLOGON_WORKSTATION_TRUST_ACCOUNT = 1808;3213pub const NOLOGON_WORKSTATION_TRUST_ACCOUNT = 1808;
3214
2144/// The account used is a server trust account. Use your global user account or local user account to access this server.3215/// The account used is a server trust account. Use your global user account or local user account to access this server.
2145pub const NOLOGON_SERVER_TRUST_ACCOUNT = 1809;3216pub const NOLOGON_SERVER_TRUST_ACCOUNT = 1809;
3217
2146/// The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.3218/// The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.
2147pub const DOMAIN_TRUST_INCONSISTENT = 1810;3219pub const DOMAIN_TRUST_INCONSISTENT = 1810;
3220
2148/// The server is in use and cannot be unloaded.3221/// The server is in use and cannot be unloaded.
2149pub const SERVER_HAS_OPEN_HANDLES = 1811;3222pub const SERVER_HAS_OPEN_HANDLES = 1811;
3223
2150/// The specified image file did not contain a resource section.3224/// The specified image file did not contain a resource section.
2151pub const RESOURCE_DATA_NOT_FOUND = 1812;3225pub const RESOURCE_DATA_NOT_FOUND = 1812;
3226
2152/// The specified resource type cannot be found in the image file.3227/// The specified resource type cannot be found in the image file.
2153pub const RESOURCE_TYPE_NOT_FOUND = 1813;3228pub const RESOURCE_TYPE_NOT_FOUND = 1813;
3229
2154/// The specified resource name cannot be found in the image file.3230/// The specified resource name cannot be found in the image file.
2155pub const RESOURCE_NAME_NOT_FOUND = 1814;3231pub const RESOURCE_NAME_NOT_FOUND = 1814;
3232
2156/// The specified resource language ID cannot be found in the image file.3233/// The specified resource language ID cannot be found in the image file.
2157pub const RESOURCE_LANG_NOT_FOUND = 1815;3234pub const RESOURCE_LANG_NOT_FOUND = 1815;
3235
2158/// Not enough quota is available to process this command.3236/// Not enough quota is available to process this command.
2159pub const NOT_ENOUGH_QUOTA = 1816;3237pub const NOT_ENOUGH_QUOTA = 1816;
3238
2160/// No interfaces have been registered.3239/// No interfaces have been registered.
2161pub const RPC_S_NO_INTERFACES = 1817;3240pub const RPC_S_NO_INTERFACES = 1817;
3241
2162/// The remote procedure call was cancelled.3242/// The remote procedure call was cancelled.
2163pub const RPC_S_CALL_CANCELLED = 1818;3243pub const RPC_S_CALL_CANCELLED = 1818;
3244
2164/// The binding handle does not contain all required information.3245/// The binding handle does not contain all required information.
2165pub const RPC_S_BINDING_INCOMPLETE = 1819;3246pub const RPC_S_BINDING_INCOMPLETE = 1819;
3247
2166/// A communications failure occurred during a remote procedure call.3248/// A communications failure occurred during a remote procedure call.
2167pub const RPC_S_COMM_FAILURE = 1820;3249pub const RPC_S_COMM_FAILURE = 1820;
3250
2168/// The requested authentication level is not supported.3251/// The requested authentication level is not supported.
2169pub const RPC_S_UNSUPPORTED_AUTHN_LEVEL = 1821;3252pub const RPC_S_UNSUPPORTED_AUTHN_LEVEL = 1821;
3253
2170/// No principal name registered.3254/// No principal name registered.
2171pub const RPC_S_NO_PRINC_NAME = 1822;3255pub const RPC_S_NO_PRINC_NAME = 1822;
3256
2172/// The error specified is not a valid Windows RPC error code.3257/// The error specified is not a valid Windows RPC error code.
2173pub const RPC_S_NOT_RPC_ERROR = 1823;3258pub const RPC_S_NOT_RPC_ERROR = 1823;
3259
2174/// A UUID that is valid only on this computer has been allocated.3260/// A UUID that is valid only on this computer has been allocated.
2175pub const RPC_S_UUID_LOCAL_ONLY = 1824;3261pub const RPC_S_UUID_LOCAL_ONLY = 1824;
3262
2176/// A security package specific error occurred.3263/// A security package specific error occurred.
2177pub const RPC_S_SEC_PKG_ERROR = 1825;3264pub const RPC_S_SEC_PKG_ERROR = 1825;
3265
2178/// Thread is not canceled.3266/// Thread is not canceled.
2179pub const RPC_S_NOT_CANCELLED = 1826;3267pub const RPC_S_NOT_CANCELLED = 1826;
3268
2180/// Invalid operation on the encoding/decoding handle.3269/// Invalid operation on the encoding/decoding handle.
2181pub const RPC_X_INVALID_ES_ACTION = 1827;3270pub const RPC_X_INVALID_ES_ACTION = 1827;
3271
2182/// Incompatible version of the serializing package.3272/// Incompatible version of the serializing package.
2183pub const RPC_X_WRONG_ES_VERSION = 1828;3273pub const RPC_X_WRONG_ES_VERSION = 1828;
3274
2184/// Incompatible version of the RPC stub.3275/// Incompatible version of the RPC stub.
2185pub const RPC_X_WRONG_STUB_VERSION = 1829;3276pub const RPC_X_WRONG_STUB_VERSION = 1829;
3277
2186/// The RPC pipe object is invalid or corrupted.3278/// The RPC pipe object is invalid or corrupted.
2187pub const RPC_X_INVALID_PIPE_OBJECT = 1830;3279pub const RPC_X_INVALID_PIPE_OBJECT = 1830;
3280
2188/// An invalid operation was attempted on an RPC pipe object.3281/// An invalid operation was attempted on an RPC pipe object.
2189pub const RPC_X_WRONG_PIPE_ORDER = 1831;3282pub const RPC_X_WRONG_PIPE_ORDER = 1831;
3283
2190/// Unsupported RPC pipe version.3284/// Unsupported RPC pipe version.
2191pub const RPC_X_WRONG_PIPE_VERSION = 1832;3285pub const RPC_X_WRONG_PIPE_VERSION = 1832;
3286
2192/// HTTP proxy server rejected the connection because the cookie authentication failed.3287/// HTTP proxy server rejected the connection because the cookie authentication failed.
2193pub const RPC_S_COOKIE_AUTH_FAILED = 1833;3288pub const RPC_S_COOKIE_AUTH_FAILED = 1833;
3289
2194/// The group member was not found.3290/// The group member was not found.
2195pub const RPC_S_GROUP_MEMBER_NOT_FOUND = 1898;3291pub const RPC_S_GROUP_MEMBER_NOT_FOUND = 1898;
3292
2196/// The endpoint mapper database entry could not be created.3293/// The endpoint mapper database entry could not be created.
2197pub const EPT_S_CANT_CREATE = 1899;3294pub const EPT_S_CANT_CREATE = 1899;
3295
2198/// The object universal unique identifier (UUID) is the nil UUID.3296/// The object universal unique identifier (UUID) is the nil UUID.
2199pub const RPC_S_INVALID_OBJECT = 1900;3297pub const RPC_S_INVALID_OBJECT = 1900;
3298
2200/// The specified time is invalid.3299/// The specified time is invalid.
2201pub const INVALID_TIME = 1901;3300pub const INVALID_TIME = 1901;
3301
2202/// The specified form name is invalid.3302/// The specified form name is invalid.
2203pub const INVALID_FORM_NAME = 1902;3303pub const INVALID_FORM_NAME = 1902;
3304
2204/// The specified form size is invalid.3305/// The specified form size is invalid.
2205pub const INVALID_FORM_SIZE = 1903;3306pub const INVALID_FORM_SIZE = 1903;
3307
2206/// The specified printer handle is already being waited on.3308/// The specified printer handle is already being waited on.
2207pub const ALREADY_WAITING = 1904;3309pub const ALREADY_WAITING = 1904;
3310
2208/// The specified printer has been deleted.3311/// The specified printer has been deleted.
2209pub const PRINTER_DELETED = 1905;3312pub const PRINTER_DELETED = 1905;
3313
2210/// The state of the printer is invalid.3314/// The state of the printer is invalid.
2211pub const INVALID_PRINTER_STATE = 1906;3315pub const INVALID_PRINTER_STATE = 1906;
3316
2212/// The user's password must be changed before signing in.3317/// The user's password must be changed before signing in.
2213pub const PASSWORD_MUST_CHANGE = 1907;3318pub const PASSWORD_MUST_CHANGE = 1907;
3319
2214/// Could not find the domain controller for this domain.3320/// Could not find the domain controller for this domain.
2215pub const DOMAIN_CONTROLLER_NOT_FOUND = 1908;3321pub const DOMAIN_CONTROLLER_NOT_FOUND = 1908;
3322
2216/// The referenced account is currently locked out and may not be logged on to.3323/// The referenced account is currently locked out and may not be logged on to.
2217pub const ACCOUNT_LOCKED_OUT = 1909;3324pub const ACCOUNT_LOCKED_OUT = 1909;
3325
2218/// The object exporter specified was not found.3326/// The object exporter specified was not found.
2219pub const OR_INVALID_OXID = 1910;3327pub const OR_INVALID_OXID = 1910;
3328
2220/// The object specified was not found.3329/// The object specified was not found.
2221pub const OR_INVALID_OID = 1911;3330pub const OR_INVALID_OID = 1911;
3331
2222/// The object resolver set specified was not found.3332/// The object resolver set specified was not found.
2223pub const OR_INVALID_SET = 1912;3333pub const OR_INVALID_SET = 1912;
3334
2224/// Some data remains to be sent in the request buffer.3335/// Some data remains to be sent in the request buffer.
2225pub const RPC_S_SEND_INCOMPLETE = 1913;3336pub const RPC_S_SEND_INCOMPLETE = 1913;
3337
2226/// Invalid asynchronous remote procedure call handle.3338/// Invalid asynchronous remote procedure call handle.
2227pub const RPC_S_INVALID_ASYNC_HANDLE = 1914;3339pub const RPC_S_INVALID_ASYNC_HANDLE = 1914;
3340
2228/// Invalid asynchronous RPC call handle for this operation.3341/// Invalid asynchronous RPC call handle for this operation.
2229pub const RPC_S_INVALID_ASYNC_CALL = 1915;3342pub const RPC_S_INVALID_ASYNC_CALL = 1915;
3343
2230/// The RPC pipe object has already been closed.3344/// The RPC pipe object has already been closed.
2231pub const RPC_X_PIPE_CLOSED = 1916;3345pub const RPC_X_PIPE_CLOSED = 1916;
3346
2232/// The RPC call completed before all pipes were processed.3347/// The RPC call completed before all pipes were processed.
2233pub const RPC_X_PIPE_DISCIPLINE_ERROR = 1917;3348pub const RPC_X_PIPE_DISCIPLINE_ERROR = 1917;
3349
2234/// No more data is available from the RPC pipe.3350/// No more data is available from the RPC pipe.
2235pub const RPC_X_PIPE_EMPTY = 1918;3351pub const RPC_X_PIPE_EMPTY = 1918;
3352
2236/// No site name is available for this machine.3353/// No site name is available for this machine.
2237pub const NO_SITENAME = 1919;3354pub const NO_SITENAME = 1919;
3355
2238/// The file cannot be accessed by the system.3356/// The file cannot be accessed by the system.
2239pub const CANT_ACCESS_FILE = 1920;3357pub const CANT_ACCESS_FILE = 1920;
3358
2240/// The name of the file cannot be resolved by the system.3359/// The name of the file cannot be resolved by the system.
2241pub const CANT_RESOLVE_FILENAME = 1921;3360pub const CANT_RESOLVE_FILENAME = 1921;
3361
2242/// The entry is not of the expected type.3362/// The entry is not of the expected type.
2243pub const RPC_S_ENTRY_TYPE_MISMATCH = 1922;3363pub const RPC_S_ENTRY_TYPE_MISMATCH = 1922;
3364
2244/// Not all object UUIDs could be exported to the specified entry.3365/// Not all object UUIDs could be exported to the specified entry.
2245pub const RPC_S_NOT_ALL_OBJS_EXPORTED = 1923;3366pub const RPC_S_NOT_ALL_OBJS_EXPORTED = 1923;
3367
2246/// Interface could not be exported to the specified entry.3368/// Interface could not be exported to the specified entry.
2247pub const RPC_S_INTERFACE_NOT_EXPORTED = 1924;3369pub const RPC_S_INTERFACE_NOT_EXPORTED = 1924;
3370
2248/// The specified profile entry could not be added.3371/// The specified profile entry could not be added.
2249pub const RPC_S_PROFILE_NOT_ADDED = 1925;3372pub const RPC_S_PROFILE_NOT_ADDED = 1925;
3373
2250/// The specified profile element could not be added.3374/// The specified profile element could not be added.
2251pub const RPC_S_PRF_ELT_NOT_ADDED = 1926;3375pub const RPC_S_PRF_ELT_NOT_ADDED = 1926;
3376
2252/// The specified profile element could not be removed.3377/// The specified profile element could not be removed.
2253pub const RPC_S_PRF_ELT_NOT_REMOVED = 1927;3378pub const RPC_S_PRF_ELT_NOT_REMOVED = 1927;
3379
2254/// The group element could not be added.3380/// The group element could not be added.
2255pub const RPC_S_GRP_ELT_NOT_ADDED = 1928;3381pub const RPC_S_GRP_ELT_NOT_ADDED = 1928;
3382
2256/// The group element could not be removed.3383/// The group element could not be removed.
2257pub const RPC_S_GRP_ELT_NOT_REMOVED = 1929;3384pub const RPC_S_GRP_ELT_NOT_REMOVED = 1929;
3385
2258/// The printer driver is not compatible with a policy enabled on your computer that blocks NT 4.0 drivers.3386/// The printer driver is not compatible with a policy enabled on your computer that blocks NT 4.0 drivers.
2259pub const KM_DRIVER_BLOCKED = 1930;3387pub const KM_DRIVER_BLOCKED = 1930;
3388
2260/// The context has expired and can no longer be used.3389/// The context has expired and can no longer be used.
2261pub const CONTEXT_EXPIRED = 1931;3390pub const CONTEXT_EXPIRED = 1931;
3391
2262/// The current user's delegated trust creation quota has been exceeded.3392/// The current user's delegated trust creation quota has been exceeded.
2263pub const PER_USER_TRUST_QUOTA_EXCEEDED = 1932;3393pub const PER_USER_TRUST_QUOTA_EXCEEDED = 1932;
3394
2264/// The total delegated trust creation quota has been exceeded.3395/// The total delegated trust creation quota has been exceeded.
2265pub const ALL_USER_TRUST_QUOTA_EXCEEDED = 1933;3396pub const ALL_USER_TRUST_QUOTA_EXCEEDED = 1933;
3397
2266/// The current user's delegated trust deletion quota has been exceeded.3398/// The current user's delegated trust deletion quota has been exceeded.
2267pub const USER_DELETE_TRUST_QUOTA_EXCEEDED = 1934;3399pub const USER_DELETE_TRUST_QUOTA_EXCEEDED = 1934;
3400
2268/// The computer you are signing into is protected by an authentication firewall. The specified account is not allowed to authenticate to the computer.3401/// The computer you are signing into is protected by an authentication firewall. The specified account is not allowed to authenticate to the computer.
2269pub const AUTHENTICATION_FIREWALL_FAILED = 1935;3402pub const AUTHENTICATION_FIREWALL_FAILED = 1935;
3403
2270/// Remote connections to the Print Spooler are blocked by a policy set on your machine.3404/// Remote connections to the Print Spooler are blocked by a policy set on your machine.
2271pub const REMOTE_PRINT_CONNECTIONS_BLOCKED = 1936;3405pub const REMOTE_PRINT_CONNECTIONS_BLOCKED = 1936;
3406
2272/// Authentication failed because NTLM authentication has been disabled.3407/// Authentication failed because NTLM authentication has been disabled.
2273pub const NTLM_BLOCKED = 1937;3408pub const NTLM_BLOCKED = 1937;
3409
2274/// Logon Failure: EAS policy requires that the user change their password before this operation can be performed.3410/// Logon Failure: EAS policy requires that the user change their password before this operation can be performed.
2275pub const PASSWORD_CHANGE_REQUIRED = 1938;3411pub const PASSWORD_CHANGE_REQUIRED = 1938;
3412
2276/// The pixel format is invalid.3413/// The pixel format is invalid.
2277pub const INVALID_PIXEL_FORMAT = 2000;3414pub const INVALID_PIXEL_FORMAT = 2000;
3415
2278/// The specified driver is invalid.3416/// The specified driver is invalid.
2279pub const BAD_DRIVER = 2001;3417pub const BAD_DRIVER = 2001;
3418
2280/// The window style or class attribute is invalid for this operation.3419/// The window style or class attribute is invalid for this operation.
2281pub const INVALID_WINDOW_STYLE = 2002;3420pub const INVALID_WINDOW_STYLE = 2002;
3421
2282/// The requested metafile operation is not supported.3422/// The requested metafile operation is not supported.
2283pub const METAFILE_NOT_SUPPORTED = 2003;3423pub const METAFILE_NOT_SUPPORTED = 2003;
3424
2284/// The requested transformation operation is not supported.3425/// The requested transformation operation is not supported.
2285pub const TRANSFORM_NOT_SUPPORTED = 2004;3426pub const TRANSFORM_NOT_SUPPORTED = 2004;
3427
2286/// The requested clipping operation is not supported.3428/// The requested clipping operation is not supported.
2287pub const CLIPPING_NOT_SUPPORTED = 2005;3429pub const CLIPPING_NOT_SUPPORTED = 2005;
3430
2288/// The specified color management module is invalid.3431/// The specified color management module is invalid.
2289pub const INVALID_CMM = 2010;3432pub const INVALID_CMM = 2010;
3433
2290/// The specified color profile is invalid.3434/// The specified color profile is invalid.
2291pub const INVALID_PROFILE = 2011;3435pub const INVALID_PROFILE = 2011;
3436
2292/// The specified tag was not found.3437/// The specified tag was not found.
2293pub const TAG_NOT_FOUND = 2012;3438pub const TAG_NOT_FOUND = 2012;
3439
2294/// A required tag is not present.3440/// A required tag is not present.
2295pub const TAG_NOT_PRESENT = 2013;3441pub const TAG_NOT_PRESENT = 2013;
3442
2296/// The specified tag is already present.3443/// The specified tag is already present.
2297pub const DUPLICATE_TAG = 2014;3444pub const DUPLICATE_TAG = 2014;
3445
2298/// The specified color profile is not associated with the specified device.3446/// The specified color profile is not associated with the specified device.
2299pub const PROFILE_NOT_ASSOCIATED_WITH_DEVICE = 2015;3447pub const PROFILE_NOT_ASSOCIATED_WITH_DEVICE = 2015;
3448
2300/// The specified color profile was not found.3449/// The specified color profile was not found.
2301pub const PROFILE_NOT_FOUND = 2016;3450pub const PROFILE_NOT_FOUND = 2016;
3451
2302/// The specified color space is invalid.3452/// The specified color space is invalid.
2303pub const INVALID_COLORSPACE = 2017;3453pub const INVALID_COLORSPACE = 2017;
3454
2304/// Image Color Management is not enabled.3455/// Image Color Management is not enabled.
2305pub const ICM_NOT_ENABLED = 2018;3456pub const ICM_NOT_ENABLED = 2018;
3457
2306/// There was an error while deleting the color transform.3458/// There was an error while deleting the color transform.
2307pub const DELETING_ICM_XFORM = 2019;3459pub const DELETING_ICM_XFORM = 2019;
3460
2308/// The specified color transform is invalid.3461/// The specified color transform is invalid.
2309pub const INVALID_TRANSFORM = 2020;3462pub const INVALID_TRANSFORM = 2020;
3463
2310/// The specified transform does not match the bitmap's color space.3464/// The specified transform does not match the bitmap's color space.
2311pub const COLORSPACE_MISMATCH = 2021;3465pub const COLORSPACE_MISMATCH = 2021;
3466
2312/// The specified named color index is not present in the profile.3467/// The specified named color index is not present in the profile.
2313pub const INVALID_COLORINDEX = 2022;3468pub const INVALID_COLORINDEX = 2022;
3469
2314/// The specified profile is intended for a device of a different type than the specified device.3470/// The specified profile is intended for a device of a different type than the specified device.
2315pub const PROFILE_DOES_NOT_MATCH_DEVICE = 2023;3471pub const PROFILE_DOES_NOT_MATCH_DEVICE = 2023;
3472
2316/// The network connection was made successfully, but the user had to be prompted for a password other than the one originally specified.3473/// The network connection was made successfully, but the user had to be prompted for a password other than the one originally specified.
2317pub const CONNECTED_OTHER_PASSWORD = 2108;3474pub const CONNECTED_OTHER_PASSWORD = 2108;
3475
2318/// The network connection was made successfully using default credentials.3476/// The network connection was made successfully using default credentials.
2319pub const CONNECTED_OTHER_PASSWORD_DEFAULT = 2109;3477pub const CONNECTED_OTHER_PASSWORD_DEFAULT = 2109;
3478
2320/// The specified username is invalid.3479/// The specified username is invalid.
2321pub const BAD_USERNAME = 2202;3480pub const BAD_USERNAME = 2202;
3481
2322/// This network connection does not exist.3482/// This network connection does not exist.
2323pub const NOT_CONNECTED = 2250;3483pub const NOT_CONNECTED = 2250;
3484
2324/// This network connection has files open or requests pending.3485/// This network connection has files open or requests pending.
2325pub const OPEN_FILES = 2401;3486pub const OPEN_FILES = 2401;
3487
2326/// Active connections still exist.3488/// Active connections still exist.
2327pub const ACTIVE_CONNECTIONS = 2402;3489pub const ACTIVE_CONNECTIONS = 2402;
3490
2328/// The device is in use by an active process and cannot be disconnected.3491/// The device is in use by an active process and cannot be disconnected.
2329pub const DEVICE_IN_USE = 2404;3492pub const DEVICE_IN_USE = 2404;
3493
2330/// The specified print monitor is unknown.3494/// The specified print monitor is unknown.
2331pub const UNKNOWN_PRINT_MONITOR = 3000;3495pub const UNKNOWN_PRINT_MONITOR = 3000;
3496
2332/// The specified printer driver is currently in use.3497/// The specified printer driver is currently in use.
2333pub const PRINTER_DRIVER_IN_USE = 3001;3498pub const PRINTER_DRIVER_IN_USE = 3001;
3499
2334/// The spool file was not found.3500/// The spool file was not found.
2335pub const SPOOL_FILE_NOT_FOUND = 3002;3501pub const SPOOL_FILE_NOT_FOUND = 3002;
3502
2336/// A StartDocPrinter call was not issued.3503/// A StartDocPrinter call was not issued.
2337pub const SPL_NO_STARTDOC = 3003;3504pub const SPL_NO_STARTDOC = 3003;
3505
2338/// An AddJob call was not issued.3506/// An AddJob call was not issued.
2339pub const SPL_NO_ADDJOB = 3004;3507pub const SPL_NO_ADDJOB = 3004;
3508
2340/// The specified print processor has already been installed.3509/// The specified print processor has already been installed.
2341pub const PRINT_PROCESSOR_ALREADY_INSTALLED = 3005;3510pub const PRINT_PROCESSOR_ALREADY_INSTALLED = 3005;
3511
2342/// The specified print monitor has already been installed.3512/// The specified print monitor has already been installed.
2343pub const PRINT_MONITOR_ALREADY_INSTALLED = 3006;3513pub const PRINT_MONITOR_ALREADY_INSTALLED = 3006;
3514
2344/// The specified print monitor does not have the required functions.3515/// The specified print monitor does not have the required functions.
2345pub const INVALID_PRINT_MONITOR = 3007;3516pub const INVALID_PRINT_MONITOR = 3007;
3517
2346/// The specified print monitor is currently in use.3518/// The specified print monitor is currently in use.
2347pub const PRINT_MONITOR_IN_USE = 3008;3519pub const PRINT_MONITOR_IN_USE = 3008;
3520
2348/// The requested operation is not allowed when there are jobs queued to the printer.3521/// The requested operation is not allowed when there are jobs queued to the printer.
2349pub const PRINTER_HAS_JOBS_QUEUED = 3009;3522pub const PRINTER_HAS_JOBS_QUEUED = 3009;
3523
2350/// The requested operation is successful. Changes will not be effective until the system is rebooted.3524/// The requested operation is successful. Changes will not be effective until the system is rebooted.
2351pub const SUCCESS_REBOOT_REQUIRED = 3010;3525pub const SUCCESS_REBOOT_REQUIRED = 3010;
3526
2352/// The requested operation is successful. Changes will not be effective until the service is restarted.3527/// The requested operation is successful. Changes will not be effective until the service is restarted.
2353pub const SUCCESS_RESTART_REQUIRED = 3011;3528pub const SUCCESS_RESTART_REQUIRED = 3011;
3529
2354/// No printers were found.3530/// No printers were found.
2355pub const PRINTER_NOT_FOUND = 3012;3531pub const PRINTER_NOT_FOUND = 3012;
3532
2356/// The printer driver is known to be unreliable.3533/// The printer driver is known to be unreliable.
2357pub const PRINTER_DRIVER_WARNED = 3013;3534pub const PRINTER_DRIVER_WARNED = 3013;
3535
2358/// The printer driver is known to harm the system.3536/// The printer driver is known to harm the system.
2359pub const PRINTER_DRIVER_BLOCKED = 3014;3537pub const PRINTER_DRIVER_BLOCKED = 3014;
3538
2360/// The specified printer driver package is currently in use.3539/// The specified printer driver package is currently in use.
2361pub const PRINTER_DRIVER_PACKAGE_IN_USE = 3015;3540pub const PRINTER_DRIVER_PACKAGE_IN_USE = 3015;
3541
2362/// Unable to find a core driver package that is required by the printer driver package.3542/// Unable to find a core driver package that is required by the printer driver package.
2363pub const CORE_DRIVER_PACKAGE_NOT_FOUND = 3016;3543pub const CORE_DRIVER_PACKAGE_NOT_FOUND = 3016;
3544
2364/// The requested operation failed. A system reboot is required to roll back changes made.3545/// The requested operation failed. A system reboot is required to roll back changes made.
2365pub const FAIL_REBOOT_REQUIRED = 3017;3546pub const FAIL_REBOOT_REQUIRED = 3017;
3547
2366/// The requested operation failed. A system reboot has been initiated to roll back changes made.3548/// The requested operation failed. A system reboot has been initiated to roll back changes made.
2367pub const FAIL_REBOOT_INITIATED = 3018;3549pub const FAIL_REBOOT_INITIATED = 3018;
3550
2368/// The specified printer driver was not found on the system and needs to be downloaded.3551/// The specified printer driver was not found on the system and needs to be downloaded.
2369pub const PRINTER_DRIVER_DOWNLOAD_NEEDED = 3019;3552pub const PRINTER_DRIVER_DOWNLOAD_NEEDED = 3019;
3553
2370/// The requested print job has failed to print. A print system update requires the job to be resubmitted.3554/// The requested print job has failed to print. A print system update requires the job to be resubmitted.
2371pub const PRINT_JOB_RESTART_REQUIRED = 3020;3555pub const PRINT_JOB_RESTART_REQUIRED = 3020;
3556
2372/// The printer driver does not contain a valid manifest, or contains too many manifests.3557/// The printer driver does not contain a valid manifest, or contains too many manifests.
2373pub const INVALID_PRINTER_DRIVER_MANIFEST = 3021;3558pub const INVALID_PRINTER_DRIVER_MANIFEST = 3021;
3559
2374/// The specified printer cannot be shared.3560/// The specified printer cannot be shared.
2375pub const PRINTER_NOT_SHAREABLE = 3022;3561pub const PRINTER_NOT_SHAREABLE = 3022;
3562
2376/// The operation was paused.3563/// The operation was paused.
2377pub const REQUEST_PAUSED = 3050;3564pub const REQUEST_PAUSED = 3050;
3565
2378/// Reissue the given operation as a cached IO operation.3566/// Reissue the given operation as a cached IO operation.
2379pub const IO_REISSUE_AS_CACHED = 3950;3567pub const IO_REISSUE_AS_CACHED = 3950;
std/os/windows/index.zig+113-65
...@@ -1,33 +1,59 @@...@@ -1,33 +1,59 @@
1pub const ERROR = @import("error.zig");1pub const ERROR = @import("error.zig");
22
3pub extern "advapi32" stdcallcc fn CryptAcquireContextA(phProv: &HCRYPTPROV, pszContainer: ?LPCSTR,3pub extern "advapi32" stdcallcc fn CryptAcquireContextA(
4 pszProvider: ?LPCSTR, dwProvType: DWORD, dwFlags: DWORD) BOOL;4 phProv: &HCRYPTPROV,
5 pszContainer: ?LPCSTR,
6 pszProvider: ?LPCSTR,
7 dwProvType: DWORD,
8 dwFlags: DWORD,
9) BOOL;
510
6pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) BOOL;11pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) BOOL;
712
8pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: &BYTE) BOOL;13pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: &BYTE) BOOL;
914
10
11pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;15pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;
1216
13pub extern "kernel32" stdcallcc fn CreateDirectoryA(lpPathName: LPCSTR,17pub extern "kernel32" stdcallcc fn CreateDirectoryA(
14 lpSecurityAttributes: ?&SECURITY_ATTRIBUTES) BOOL;18 lpPathName: LPCSTR,
1519 lpSecurityAttributes: ?&SECURITY_ATTRIBUTES,
16pub extern "kernel32" stdcallcc fn CreateFileA(lpFileName: LPCSTR, dwDesiredAccess: DWORD,20) BOOL;
17 dwShareMode: DWORD, lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD,21
18 dwFlagsAndAttributes: DWORD, hTemplateFile: ?HANDLE) HANDLE;22pub extern "kernel32" stdcallcc fn CreateFileA(
1923 lpFileName: LPCSTR,
20pub extern "kernel32" stdcallcc fn CreatePipe(hReadPipe: &HANDLE, hWritePipe: &HANDLE,24 dwDesiredAccess: DWORD,
21 lpPipeAttributes: &const SECURITY_ATTRIBUTES, nSize: DWORD) BOOL;25 dwShareMode: DWORD,
2226 lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES,
23pub extern "kernel32" stdcallcc fn CreateProcessA(lpApplicationName: ?LPCSTR, lpCommandLine: LPSTR,27 dwCreationDisposition: DWORD,
24 lpProcessAttributes: ?&SECURITY_ATTRIBUTES, lpThreadAttributes: ?&SECURITY_ATTRIBUTES, bInheritHandles: BOOL,28 dwFlagsAndAttributes: DWORD,
25 dwCreationFlags: DWORD, lpEnvironment: ?&c_void, lpCurrentDirectory: ?LPCSTR, lpStartupInfo: &STARTUPINFOA,29 hTemplateFile: ?HANDLE,
26 lpProcessInformation: &PROCESS_INFORMATION) BOOL;30) HANDLE;
2731
28pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA(lpSymlinkFileName: LPCSTR, lpTargetFileName: LPCSTR,32pub extern "kernel32" stdcallcc fn CreatePipe(
29 dwFlags: DWORD) BOOLEAN;33 hReadPipe: &HANDLE,
3034 hWritePipe: &HANDLE,
35 lpPipeAttributes: &const SECURITY_ATTRIBUTES,
36 nSize: DWORD,
37) BOOL;
38
39pub extern "kernel32" stdcallcc fn CreateProcessA(
40 lpApplicationName: ?LPCSTR,
41 lpCommandLine: LPSTR,
42 lpProcessAttributes: ?&SECURITY_ATTRIBUTES,
43 lpThreadAttributes: ?&SECURITY_ATTRIBUTES,
44 bInheritHandles: BOOL,
45 dwCreationFlags: DWORD,
46 lpEnvironment: ?&c_void,
47 lpCurrentDirectory: ?LPCSTR,
48 lpStartupInfo: &STARTUPINFOA,
49 lpProcessInformation: &PROCESS_INFORMATION,
50) BOOL;
51
52pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA(
53 lpSymlinkFileName: LPCSTR,
54 lpTargetFileName: LPCSTR,
55 dwFlags: DWORD,
56) BOOLEAN;
3157
32pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE;58pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE;
3359
...@@ -55,12 +81,19 @@ pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilen...@@ -55,12 +81,19 @@ pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilen
5581
56pub extern "kernel32" stdcallcc fn GetLastError() DWORD;82pub extern "kernel32" stdcallcc fn GetLastError() DWORD;
5783
58pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(in_hFile: HANDLE,84pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(
59 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, out_lpFileInformation: &c_void,85 in_hFile: HANDLE,
60 in_dwBufferSize: DWORD) BOOL;86 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
6187 out_lpFileInformation: &c_void,
62pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA(hFile: HANDLE, lpszFilePath: LPSTR,88 in_dwBufferSize: DWORD,
63 cchFilePath: DWORD, dwFlags: DWORD) DWORD;89) BOOL;
90
91pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA(
92 hFile: HANDLE,
93 lpszFilePath: LPSTR,
94 cchFilePath: DWORD,
95 dwFlags: DWORD,
96) DWORD;
6497
65pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE;98pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE;
6699
...@@ -80,21 +113,32 @@ pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBy...@@ -80,21 +113,32 @@ pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBy
80113
81pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: &c_void) BOOL;114pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: &c_void) BOOL;
82115
83pub extern "kernel32" stdcallcc fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR,116pub extern "kernel32" stdcallcc fn MoveFileExA(
84 dwFlags: DWORD) BOOL;117 lpExistingFileName: LPCSTR,
85 118 lpNewFileName: LPCSTR,
119 dwFlags: DWORD,
120) BOOL;
121
86pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: &LARGE_INTEGER) BOOL;122pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: &LARGE_INTEGER) BOOL;
87123
88pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: &LARGE_INTEGER) BOOL;124pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: &LARGE_INTEGER) BOOL;
89125
90pub extern "kernel32" stdcallcc fn PathFileExists(pszPath: ?LPCTSTR) BOOL;126pub extern "kernel32" stdcallcc fn PathFileExists(pszPath: ?LPCTSTR) BOOL;
91127
92pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: &c_void,128pub extern "kernel32" stdcallcc fn ReadFile(
93 in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD,129 in_hFile: HANDLE,
94 in_out_lpOverlapped: ?&OVERLAPPED) BOOL;130 out_lpBuffer: &c_void,
95131 in_nNumberOfBytesToRead: DWORD,
96pub extern "kernel32" stdcallcc fn SetFilePointerEx(in_fFile: HANDLE, in_liDistanceToMove: LARGE_INTEGER, 132 out_lpNumberOfBytesRead: &DWORD,
97 out_opt_ldNewFilePointer: ?&LARGE_INTEGER, in_dwMoveMethod: DWORD) BOOL;133 in_out_lpOverlapped: ?&OVERLAPPED,
134) BOOL;
135
136pub extern "kernel32" stdcallcc fn SetFilePointerEx(
137 in_fFile: HANDLE,
138 in_liDistanceToMove: LARGE_INTEGER,
139 out_opt_ldNewFilePointer: ?&LARGE_INTEGER,
140 in_dwMoveMethod: DWORD,
141) BOOL;
98142
99pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL;143pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL;
100144
...@@ -104,14 +148,18 @@ pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode:...@@ -104,14 +148,18 @@ pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode:
104148
105pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD;149pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD;
106150
107pub extern "kernel32" stdcallcc fn WriteFile(in_hFile: HANDLE, in_lpBuffer: &const c_void,151pub extern "kernel32" stdcallcc fn WriteFile(
108 in_nNumberOfBytesToWrite: DWORD, out_lpNumberOfBytesWritten: ?&DWORD,152 in_hFile: HANDLE,
109 in_out_lpOverlapped: ?&OVERLAPPED) BOOL;153 in_lpBuffer: &const c_void,
154 in_nNumberOfBytesToWrite: DWORD,
155 out_lpNumberOfBytesWritten: ?&DWORD,
156 in_out_lpOverlapped: ?&OVERLAPPED,
157) BOOL;
110158
111//TODO: call unicode versions instead of relying on ANSI code page159//TODO: call unicode versions instead of relying on ANSI code page
112pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: LPCSTR) ?HMODULE;160pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: LPCSTR) ?HMODULE;
113161
114pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL; 162pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL;
115163
116pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int;164pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int;
117165
...@@ -176,49 +224,51 @@ pub const MAX_PATH = 260;...@@ -176,49 +224,51 @@ pub const MAX_PATH = 260;
176224
177// TODO issue #305225// TODO issue #305
178pub const FILE_INFO_BY_HANDLE_CLASS = u32;226pub const FILE_INFO_BY_HANDLE_CLASS = u32;
179pub const FileBasicInfo = 0;227pub const FileBasicInfo = 0;
180pub const FileStandardInfo = 1;228pub const FileStandardInfo = 1;
181pub const FileNameInfo = 2;229pub const FileNameInfo = 2;
182pub const FileRenameInfo = 3;230pub const FileRenameInfo = 3;
183pub const FileDispositionInfo = 4;231pub const FileDispositionInfo = 4;
184pub const FileAllocationInfo = 5;232pub const FileAllocationInfo = 5;
185pub const FileEndOfFileInfo = 6;233pub const FileEndOfFileInfo = 6;
186pub const FileStreamInfo = 7;234pub const FileStreamInfo = 7;
187pub const FileCompressionInfo = 8;235pub const FileCompressionInfo = 8;
188pub const FileAttributeTagInfo = 9;236pub const FileAttributeTagInfo = 9;
189pub const FileIdBothDirectoryInfo = 10;237pub const FileIdBothDirectoryInfo = 10;
190pub const FileIdBothDirectoryRestartInfo = 11;238pub const FileIdBothDirectoryRestartInfo = 11;
191pub const FileIoPriorityHintInfo = 12;239pub const FileIoPriorityHintInfo = 12;
192pub const FileRemoteProtocolInfo = 13;240pub const FileRemoteProtocolInfo = 13;
193pub const FileFullDirectoryInfo = 14;241pub const FileFullDirectoryInfo = 14;
194pub const FileFullDirectoryRestartInfo = 15;242pub const FileFullDirectoryRestartInfo = 15;
195pub const FileStorageInfo = 16;243pub const FileStorageInfo = 16;
196pub const FileAlignmentInfo = 17;244pub const FileAlignmentInfo = 17;
197pub const FileIdInfo = 18;245pub const FileIdInfo = 18;
198pub const FileIdExtdDirectoryInfo = 19;246pub const FileIdExtdDirectoryInfo = 19;
199pub const FileIdExtdDirectoryRestartInfo = 20;247pub const FileIdExtdDirectoryRestartInfo = 20;
200248
201pub const FILE_NAME_INFO = extern struct {249pub const FILE_NAME_INFO = extern struct {
202 FileNameLength: DWORD,250 FileNameLength: DWORD,
203 FileName: [1]WCHAR,251 FileName: [1]WCHAR,
204};252};
205253
206
207/// Return the normalized drive name. This is the default.254/// Return the normalized drive name. This is the default.
208pub const FILE_NAME_NORMALIZED = 0x0;255pub const FILE_NAME_NORMALIZED = 0x0;
256
209/// Return the opened file name (not normalized).257/// Return the opened file name (not normalized).
210pub const FILE_NAME_OPENED = 0x8;258pub const FILE_NAME_OPENED = 0x8;
211259
212/// Return the path with the drive letter. This is the default.260/// Return the path with the drive letter. This is the default.
213pub const VOLUME_NAME_DOS = 0x0;261pub const VOLUME_NAME_DOS = 0x0;
262
214/// Return the path with a volume GUID path instead of the drive name.263/// Return the path with a volume GUID path instead of the drive name.
215pub const VOLUME_NAME_GUID = 0x1;264pub const VOLUME_NAME_GUID = 0x1;
265
216/// Return the path with no drive information.266/// Return the path with no drive information.
217pub const VOLUME_NAME_NONE = 0x4;267pub const VOLUME_NAME_NONE = 0x4;
268
218/// Return the path with the volume device path.269/// Return the path with the volume device path.
219pub const VOLUME_NAME_NT = 0x2;270pub const VOLUME_NAME_NT = 0x2;
220271
221
222pub const SECURITY_ATTRIBUTES = extern struct {272pub const SECURITY_ATTRIBUTES = extern struct {
223 nLength: DWORD,273 nLength: DWORD,
224 lpSecurityDescriptor: ?&c_void,274 lpSecurityDescriptor: ?&c_void,
...@@ -227,7 +277,6 @@ pub const SECURITY_ATTRIBUTES = extern struct {...@@ -227,7 +277,6 @@ pub const SECURITY_ATTRIBUTES = extern struct {
227pub const PSECURITY_ATTRIBUTES = &SECURITY_ATTRIBUTES;277pub const PSECURITY_ATTRIBUTES = &SECURITY_ATTRIBUTES;
228pub const LPSECURITY_ATTRIBUTES = &SECURITY_ATTRIBUTES;278pub const LPSECURITY_ATTRIBUTES = &SECURITY_ATTRIBUTES;
229279
230
231pub const GENERIC_READ = 0x80000000;280pub const GENERIC_READ = 0x80000000;
232pub const GENERIC_WRITE = 0x40000000;281pub const GENERIC_WRITE = 0x40000000;
233pub const GENERIC_EXECUTE = 0x20000000;282pub const GENERIC_EXECUTE = 0x20000000;
...@@ -243,7 +292,6 @@ pub const OPEN_ALWAYS = 4;...@@ -243,7 +292,6 @@ pub const OPEN_ALWAYS = 4;
243pub const OPEN_EXISTING = 3;292pub const OPEN_EXISTING = 3;
244pub const TRUNCATE_EXISTING = 5;293pub const TRUNCATE_EXISTING = 5;
245294
246
247pub const FILE_ATTRIBUTE_ARCHIVE = 0x20;295pub const FILE_ATTRIBUTE_ARCHIVE = 0x20;
248pub const FILE_ATTRIBUTE_ENCRYPTED = 0x4000;296pub const FILE_ATTRIBUTE_ENCRYPTED = 0x4000;
249pub const FILE_ATTRIBUTE_HIDDEN = 0x2;297pub const FILE_ATTRIBUTE_HIDDEN = 0x2;
std/os/windows/util.zig+18-19
...@@ -7,7 +7,7 @@ const mem = std.mem;...@@ -7,7 +7,7 @@ const mem = std.mem;
7const BufMap = std.BufMap;7const BufMap = std.BufMap;
8const cstr = std.cstr;8const cstr = std.cstr;
99
10pub const WaitError = error {10pub const WaitError = error{
11 WaitAbandoned,11 WaitAbandoned,
12 WaitTimeOut,12 WaitTimeOut,
13 Unexpected,13 Unexpected,
...@@ -33,7 +33,7 @@ pub fn windowsClose(handle: windows.HANDLE) void {...@@ -33,7 +33,7 @@ pub fn windowsClose(handle: windows.HANDLE) void {
33 assert(windows.CloseHandle(handle) != 0);33 assert(windows.CloseHandle(handle) != 0);
34}34}
3535
36pub const WriteError = error {36pub const WriteError = error{
37 SystemResources,37 SystemResources,
38 OperationAborted,38 OperationAborted,
39 IoPending,39 IoPending,
...@@ -68,20 +68,18 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool {...@@ -68,20 +68,18 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool {
68 const size = @sizeOf(windows.FILE_NAME_INFO);68 const size = @sizeOf(windows.FILE_NAME_INFO);
69 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH);69 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH);
7070
71 if (windows.GetFileInformationByHandleEx(handle, windows.FileNameInfo,71 if (windows.GetFileInformationByHandleEx(handle, windows.FileNameInfo, @ptrCast(&c_void, &name_info_bytes[0]), u32(name_info_bytes.len)) == 0) {
72 @ptrCast(&c_void, &name_info_bytes[0]), u32(name_info_bytes.len)) == 0)
73 {
74 return true;72 return true;
75 }73 }
7674
77 const name_info = @ptrCast(&const windows.FILE_NAME_INFO, &name_info_bytes[0]);75 const name_info = @ptrCast(&const windows.FILE_NAME_INFO, &name_info_bytes[0]);
78 const name_bytes = name_info_bytes[size..size + usize(name_info.FileNameLength)];76 const name_bytes = name_info_bytes[size..size + usize(name_info.FileNameLength)];
79 const name_wide = ([]u16)(name_bytes);77 const name_wide = ([]u16)(name_bytes);
80 return mem.indexOf(u16, name_wide, []u16{'m','s','y','s','-'}) != null or78 return mem.indexOf(u16, name_wide, []u16{ 'm', 's', 'y', 's', '-' }) != null or
81 mem.indexOf(u16, name_wide, []u16{'-','p','t','y'}) != null;79 mem.indexOf(u16, name_wide, []u16{ '-', 'p', 't', 'y' }) != null;
82}80}
8381
84pub const OpenError = error {82pub const OpenError = error{
85 SharingViolation,83 SharingViolation,
86 PathAlreadyExists,84 PathAlreadyExists,
87 FileNotFound,85 FileNotFound,
...@@ -92,15 +90,18 @@ pub const OpenError = error {...@@ -92,15 +90,18 @@ pub const OpenError = error {
92};90};
9391
94/// `file_path` needs to be copied in memory to add a null terminating byte, hence the allocator.92/// `file_path` needs to be copied in memory to add a null terminating byte, hence the allocator.
95pub fn windowsOpen(allocator: &mem.Allocator, file_path: []const u8, desired_access: windows.DWORD, share_mode: windows.DWORD,93pub fn windowsOpen(
96 creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD)94 allocator: &mem.Allocator,
97 OpenError!windows.HANDLE95 file_path: []const u8,
98{96 desired_access: windows.DWORD,
97 share_mode: windows.DWORD,
98 creation_disposition: windows.DWORD,
99 flags_and_attrs: windows.DWORD,
100) OpenError!windows.HANDLE {
99 const path_with_null = try cstr.addNullByte(allocator, file_path);101 const path_with_null = try cstr.addNullByte(allocator, file_path);
100 defer allocator.free(path_with_null);102 defer allocator.free(path_with_null);
101103
102 const result = windows.CreateFileA(path_with_null.ptr, desired_access, share_mode, null, creation_disposition,104 const result = windows.CreateFileA(path_with_null.ptr, desired_access, share_mode, null, creation_disposition, flags_and_attrs, null);
103 flags_and_attrs, null);
104105
105 if (result == windows.INVALID_HANDLE_VALUE) {106 if (result == windows.INVALID_HANDLE_VALUE) {
106 const err = windows.GetLastError();107 const err = windows.GetLastError();
...@@ -156,18 +157,16 @@ pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) !windows....@@ -156,18 +157,16 @@ pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) !windows.
156}157}
157158
158pub fn windowsUnloadDll(hModule: windows.HMODULE) void {159pub fn windowsUnloadDll(hModule: windows.HMODULE) void {
159 assert(windows.FreeLibrary(hModule)!= 0);160 assert(windows.FreeLibrary(hModule) != 0);
160}161}
161162
162
163test "InvalidDll" {163test "InvalidDll" {
164 if (builtin.os != builtin.Os.windows) return;164 if (builtin.os != builtin.Os.windows) return;
165165
166 const DllName = "asdf.dll";166 const DllName = "asdf.dll";
167 const allocator = std.debug.global_allocator;167 const allocator = std.debug.global_allocator;
168 const handle = os.windowsLoadDll(allocator, DllName) catch |err| {168 const handle = os.windowsLoadDll(allocator, DllName) catch |err| {
169 assert(err == error.DllNotFound);169 assert(err == error.DllNotFound);
170 return;170 return;
171 };171 };
172}172}
173
std/os/zen.zig+76-62
...@@ -3,35 +3,35 @@...@@ -3,35 +3,35 @@
3//////////////////////////3//////////////////////////
44
5pub const Message = struct {5pub const Message = struct {
6 sender: MailboxId,6 sender: MailboxId,
7 receiver: MailboxId,7 receiver: MailboxId,
8 type: usize,8 type: usize,
9 payload: usize,9 payload: usize,
1010
11 pub fn from(mailbox_id: &const MailboxId) Message {11 pub fn from(mailbox_id: &const MailboxId) Message {
12 return Message {12 return Message{
13 .sender = MailboxId.Undefined,13 .sender = MailboxId.Undefined,
14 .receiver = *mailbox_id,14 .receiver = *mailbox_id,
15 .type = 0,15 .type = 0,
16 .payload = 0,16 .payload = 0,
17 };17 };
18 }18 }
1919
20 pub fn to(mailbox_id: &const MailboxId, msg_type: usize) Message {20 pub fn to(mailbox_id: &const MailboxId, msg_type: usize) Message {
21 return Message {21 return Message{
22 .sender = MailboxId.This,22 .sender = MailboxId.This,
23 .receiver = *mailbox_id,23 .receiver = *mailbox_id,
24 .type = msg_type,24 .type = msg_type,
25 .payload = 0,25 .payload = 0,
26 };26 };
27 }27 }
2828
29 pub fn withData(mailbox_id: &const MailboxId, msg_type: usize, payload: usize) Message {29 pub fn withData(mailbox_id: &const MailboxId, msg_type: usize, payload: usize) Message {
30 return Message {30 return Message{
31 .sender = MailboxId.This,31 .sender = MailboxId.This,
32 .receiver = *mailbox_id,32 .receiver = *mailbox_id,
33 .type = msg_type,33 .type = msg_type,
34 .payload = payload,34 .payload = payload,
35 };35 };
36 }36 }
37};37};
...@@ -40,27 +40,25 @@ pub const MailboxId = union(enum) {...@@ -40,27 +40,25 @@ pub const MailboxId = union(enum) {
40 Undefined,40 Undefined,
41 This,41 This,
42 Kernel,42 Kernel,
43 Port: u16,43 Port: u16,
44 Thread: u16,44 Thread: u16,
45};45};
4646
47
48//////////////////////////////////////47//////////////////////////////////////
49//// Ports reserved for servers ////48//// Ports reserved for servers ////
50//////////////////////////////////////49//////////////////////////////////////
5150
52pub const Server = struct {51pub const Server = struct {
53 pub const Keyboard = MailboxId { .Port = 0 };52 pub const Keyboard = MailboxId{ .Port = 0 };
54 pub const Terminal = MailboxId { .Port = 1 };53 pub const Terminal = MailboxId{ .Port = 1 };
55};54};
5655
57
58////////////////////////56////////////////////////
59//// POSIX things ////57//// POSIX things ////
60////////////////////////58////////////////////////
6159
62// Standard streams.60// Standard streams.
63pub const STDIN_FILENO = 0;61pub const STDIN_FILENO = 0;
64pub const STDOUT_FILENO = 1;62pub const STDOUT_FILENO = 1;
65pub const STDERR_FILENO = 2;63pub const STDERR_FILENO = 2;
6664
...@@ -101,26 +99,24 @@ pub fn write(fd: i32, buf: &const u8, count: usize) usize {...@@ -101,26 +99,24 @@ pub fn write(fd: i32, buf: &const u8, count: usize) usize {
101 return count;99 return count;
102}100}
103101
104
105///////////////////////////102///////////////////////////
106//// Syscall numbers ////103//// Syscall numbers ////
107///////////////////////////104///////////////////////////
108105
109pub const Syscall = enum(usize) {106pub const Syscall = enum(usize) {
110 exit = 0,107 exit = 0,
111 createPort = 1,108 createPort = 1,
112 send = 2,109 send = 2,
113 receive = 3,110 receive = 3,
114 subscribeIRQ = 4,111 subscribeIRQ = 4,
115 inb = 5,112 inb = 5,
116 map = 6,113 map = 6,
117 createThread = 7,114 createThread = 7,
118 createProcess = 8,115 createProcess = 8,
119 wait = 9,116 wait = 9,
120 portReady = 10,117 portReady = 10,
121};118};
122119
123
124////////////////////120////////////////////
125//// Syscalls ////121//// Syscalls ////
126////////////////////122////////////////////
...@@ -157,7 +153,7 @@ pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {...@@ -157,7 +153,7 @@ pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {
157 return syscall4(Syscall.map, v_addr, p_addr, size, usize(writable)) != 0;153 return syscall4(Syscall.map, v_addr, p_addr, size, usize(writable)) != 0;
158}154}
159155
160pub fn createThread(function: fn()void) u16 {156pub fn createThread(function: fn() void) u16 {
161 return u16(syscall1(Syscall.createThread, @ptrToInt(function)));157 return u16(syscall1(Syscall.createThread, @ptrToInt(function)));
162}158}
163159
...@@ -180,66 +176,84 @@ pub fn portReady(port: u16) bool {...@@ -180,66 +176,84 @@ pub fn portReady(port: u16) bool {
180inline fn syscall0(number: Syscall) usize {176inline fn syscall0(number: Syscall) usize {
181 return asm volatile ("int $0x80"177 return asm volatile ("int $0x80"
182 : [ret] "={eax}" (-> usize)178 : [ret] "={eax}" (-> usize)
183 : [number] "{eax}" (number));179 : [number] "{eax}" (number)
180 );
184}181}
185182
186inline fn syscall1(number: Syscall, arg1: usize) usize {183inline fn syscall1(number: Syscall, arg1: usize) usize {
187 return asm volatile ("int $0x80"184 return asm volatile ("int $0x80"
188 : [ret] "={eax}" (-> usize)185 : [ret] "={eax}" (-> usize)
189 : [number] "{eax}" (number),186 : [number] "{eax}" (number),
190 [arg1] "{ecx}" (arg1));187 [arg1] "{ecx}" (arg1)
188 );
191}189}
192190
193inline fn syscall2(number: Syscall, arg1: usize, arg2: usize) usize {191inline fn syscall2(number: Syscall, arg1: usize, arg2: usize) usize {
194 return asm volatile ("int $0x80"192 return asm volatile ("int $0x80"
195 : [ret] "={eax}" (-> usize)193 : [ret] "={eax}" (-> usize)
196 : [number] "{eax}" (number),194 : [number] "{eax}" (number),
197 [arg1] "{ecx}" (arg1),195 [arg1] "{ecx}" (arg1),
198 [arg2] "{edx}" (arg2));196 [arg2] "{edx}" (arg2)
197 );
199}198}
200199
201inline fn syscall3(number: Syscall, arg1: usize, arg2: usize, arg3: usize) usize {200inline fn syscall3(number: Syscall, arg1: usize, arg2: usize, arg3: usize) usize {
202 return asm volatile ("int $0x80"201 return asm volatile ("int $0x80"
203 : [ret] "={eax}" (-> usize)202 : [ret] "={eax}" (-> usize)
204 : [number] "{eax}" (number),203 : [number] "{eax}" (number),
205 [arg1] "{ecx}" (arg1),204 [arg1] "{ecx}" (arg1),
206 [arg2] "{edx}" (arg2),205 [arg2] "{edx}" (arg2),
207 [arg3] "{ebx}" (arg3));206 [arg3] "{ebx}" (arg3)
207 );
208}208}
209209
210inline fn syscall4(number: Syscall, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {210inline fn syscall4(number: Syscall, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
211 return asm volatile ("int $0x80"211 return asm volatile ("int $0x80"
212 : [ret] "={eax}" (-> usize)212 : [ret] "={eax}" (-> usize)
213 : [number] "{eax}" (number),213 : [number] "{eax}" (number),
214 [arg1] "{ecx}" (arg1),214 [arg1] "{ecx}" (arg1),
215 [arg2] "{edx}" (arg2),215 [arg2] "{edx}" (arg2),
216 [arg3] "{ebx}" (arg3),216 [arg3] "{ebx}" (arg3),
217 [arg4] "{esi}" (arg4));217 [arg4] "{esi}" (arg4)
218 );
218}219}
219220
220inline fn syscall5(number: Syscall, arg1: usize, arg2: usize, arg3: usize,221inline fn syscall5(
221 arg4: usize, arg5: usize) usize222 number: Syscall,
222{223 arg1: usize,
224 arg2: usize,
225 arg3: usize,
226 arg4: usize,
227 arg5: usize,
228) usize {
223 return asm volatile ("int $0x80"229 return asm volatile ("int $0x80"
224 : [ret] "={eax}" (-> usize)230 : [ret] "={eax}" (-> usize)
225 : [number] "{eax}" (number),231 : [number] "{eax}" (number),
226 [arg1] "{ecx}" (arg1),232 [arg1] "{ecx}" (arg1),
227 [arg2] "{edx}" (arg2),233 [arg2] "{edx}" (arg2),
228 [arg3] "{ebx}" (arg3),234 [arg3] "{ebx}" (arg3),
229 [arg4] "{esi}" (arg4),235 [arg4] "{esi}" (arg4),
230 [arg5] "{edi}" (arg5));236 [arg5] "{edi}" (arg5)
237 );
231}238}
232239
233inline fn syscall6(number: Syscall, arg1: usize, arg2: usize, arg3: usize,240inline fn syscall6(
234 arg4: usize, arg5: usize, arg6: usize) usize241 number: Syscall,
235{242 arg1: usize,
243 arg2: usize,
244 arg3: usize,
245 arg4: usize,
246 arg5: usize,
247 arg6: usize,
248) usize {
236 return asm volatile ("int $0x80"249 return asm volatile ("int $0x80"
237 : [ret] "={eax}" (-> usize)250 : [ret] "={eax}" (-> usize)
238 : [number] "{eax}" (number),251 : [number] "{eax}" (number),
239 [arg1] "{ecx}" (arg1),252 [arg1] "{ecx}" (arg1),
240 [arg2] "{edx}" (arg2),253 [arg2] "{edx}" (arg2),
241 [arg3] "{ebx}" (arg3),254 [arg3] "{ebx}" (arg3),
242 [arg4] "{esi}" (arg4),255 [arg4] "{esi}" (arg4),
243 [arg5] "{edi}" (arg5),256 [arg5] "{edi}" (arg5),
244 [arg6] "{ebp}" (arg6));257 [arg6] "{ebp}" (arg6)
258 );
245}259}
std/rand/index.zig+54-38
...@@ -69,7 +69,7 @@ pub const Random = struct {...@@ -69,7 +69,7 @@ pub const Random = struct {
69 break :x start;69 break :x start;
70 } else x: {70 } else x: {
71 // Can't overflow because the range is over signed ints71 // Can't overflow because the range is over signed ints
72 break :x math.negateCast(value - end_uint) catch unreachable;72 break :x math.negateCast(value - end_uint) catch unreachable;
73 };73 };
74 return result;74 return result;
75 } else {75 } else {
...@@ -156,7 +156,7 @@ const SplitMix64 = struct {...@@ -156,7 +156,7 @@ const SplitMix64 = struct {
156 s: u64,156 s: u64,
157157
158 pub fn init(seed: u64) SplitMix64 {158 pub fn init(seed: u64) SplitMix64 {
159 return SplitMix64 { .s = seed };159 return SplitMix64{ .s = seed };
160 }160 }
161161
162 pub fn next(self: &SplitMix64) u64 {162 pub fn next(self: &SplitMix64) u64 {
...@@ -172,7 +172,7 @@ const SplitMix64 = struct {...@@ -172,7 +172,7 @@ const SplitMix64 = struct {
172test "splitmix64 sequence" {172test "splitmix64 sequence" {
173 var r = SplitMix64.init(0xaeecf86f7878dd75);173 var r = SplitMix64.init(0xaeecf86f7878dd75);
174174
175 const seq = []const u64 {175 const seq = []const u64{
176 0x5dbd39db0178eb44,176 0x5dbd39db0178eb44,
177 0xa9900fb66b397da3,177 0xa9900fb66b397da3,
178 0x5c1a28b1aeebcf5c,178 0x5c1a28b1aeebcf5c,
...@@ -198,8 +198,8 @@ pub const Pcg = struct {...@@ -198,8 +198,8 @@ pub const Pcg = struct {
198 i: u64,198 i: u64,
199199
200 pub fn init(init_s: u64) Pcg {200 pub fn init(init_s: u64) Pcg {
201 var pcg = Pcg {201 var pcg = Pcg{
202 .random = Random { .fillFn = fill },202 .random = Random{ .fillFn = fill },
203 .s = undefined,203 .s = undefined,
204 .i = undefined,204 .i = undefined,
205 };205 };
...@@ -265,7 +265,7 @@ test "pcg sequence" {...@@ -265,7 +265,7 @@ test "pcg sequence" {
265 const s1: u64 = 0x84e9c579ef59bbf7;265 const s1: u64 = 0x84e9c579ef59bbf7;
266 r.seedTwo(s0, s1);266 r.seedTwo(s0, s1);
267267
268 const seq = []const u32 {268 const seq = []const u32{
269 2881561918,269 2881561918,
270 3063928540,270 3063928540,
271 1199791034,271 1199791034,
...@@ -288,8 +288,8 @@ pub const Xoroshiro128 = struct {...@@ -288,8 +288,8 @@ pub const Xoroshiro128 = struct {
288 s: [2]u64,288 s: [2]u64,
289289
290 pub fn init(init_s: u64) Xoroshiro128 {290 pub fn init(init_s: u64) Xoroshiro128 {
291 var x = Xoroshiro128 {291 var x = Xoroshiro128{
292 .random = Random { .fillFn = fill },292 .random = Random{ .fillFn = fill },
293 .s = undefined,293 .s = undefined,
294 };294 };
295295
...@@ -314,9 +314,9 @@ pub const Xoroshiro128 = struct {...@@ -314,9 +314,9 @@ pub const Xoroshiro128 = struct {
314 var s0: u64 = 0;314 var s0: u64 = 0;
315 var s1: u64 = 0;315 var s1: u64 = 0;
316316
317 const table = []const u64 {317 const table = []const u64{
318 0xbeac0467eba5facb,318 0xbeac0467eba5facb,
319 0xd86b048b86aa9922319 0xd86b048b86aa9922,
320 };320 };
321321
322 inline for (table) |entry| {322 inline for (table) |entry| {
...@@ -374,7 +374,7 @@ test "xoroshiro sequence" {...@@ -374,7 +374,7 @@ test "xoroshiro sequence" {
374 r.s[0] = 0xaeecf86f7878dd75;374 r.s[0] = 0xaeecf86f7878dd75;
375 r.s[1] = 0x01cd153642e72622;375 r.s[1] = 0x01cd153642e72622;
376376
377 const seq1 = []const u64 {377 const seq1 = []const u64{
378 0xb0ba0da5bb600397,378 0xb0ba0da5bb600397,
379 0x18a08afde614dccc,379 0x18a08afde614dccc,
380 0xa2635b956a31b929,380 0xa2635b956a31b929,
...@@ -387,10 +387,9 @@ test "xoroshiro sequence" {...@@ -387,10 +387,9 @@ test "xoroshiro sequence" {
387 std.debug.assert(s == r.next());387 std.debug.assert(s == r.next());
388 }388 }
389389
390
391 r.jump();390 r.jump();
392391
393 const seq2 = []const u64 {392 const seq2 = []const u64{
394 0x95344a13556d3e22,393 0x95344a13556d3e22,
395 0xb4fb32dafa4d00df,394 0xb4fb32dafa4d00df,
396 0xb2011d9ccdcfe2dd,395 0xb2011d9ccdcfe2dd,
...@@ -421,8 +420,8 @@ pub const Isaac64 = struct {...@@ -421,8 +420,8 @@ pub const Isaac64 = struct {
421 i: usize,420 i: usize,
422421
423 pub fn init(init_s: u64) Isaac64 {422 pub fn init(init_s: u64) Isaac64 {
424 var isaac = Isaac64 {423 var isaac = Isaac64{
425 .random = Random { .fillFn = fill },424 .random = Random{ .fillFn = fill },
426 .r = undefined,425 .r = undefined,
427 .m = undefined,426 .m = undefined,
428 .a = undefined,427 .a = undefined,
...@@ -456,20 +455,20 @@ pub const Isaac64 = struct {...@@ -456,20 +455,20 @@ pub const Isaac64 = struct {
456 {455 {
457 var i: usize = 0;456 var i: usize = 0;
458 while (i < midpoint) : (i += 4) {457 while (i < midpoint) : (i += 4) {
459 self.step( ~(self.a ^ (self.a << 21)), i + 0, 0, midpoint);458 self.step(~(self.a ^ (self.a << 21)), i + 0, 0, midpoint);
460 self.step( self.a ^ (self.a >> 5) , i + 1, 0, midpoint);459 self.step(self.a ^ (self.a >> 5), i + 1, 0, midpoint);
461 self.step( self.a ^ (self.a << 12) , i + 2, 0, midpoint);460 self.step(self.a ^ (self.a << 12), i + 2, 0, midpoint);
462 self.step( self.a ^ (self.a >> 33) , i + 3, 0, midpoint);461 self.step(self.a ^ (self.a >> 33), i + 3, 0, midpoint);
463 }462 }
464 }463 }
465464
466 {465 {
467 var i: usize = 0;466 var i: usize = 0;
468 while (i < midpoint) : (i += 4) {467 while (i < midpoint) : (i += 4) {
469 self.step( ~(self.a ^ (self.a << 21)), i + 0, midpoint, 0);468 self.step(~(self.a ^ (self.a << 21)), i + 0, midpoint, 0);
470 self.step( self.a ^ (self.a >> 5) , i + 1, midpoint, 0);469 self.step(self.a ^ (self.a >> 5), i + 1, midpoint, 0);
471 self.step( self.a ^ (self.a << 12) , i + 2, midpoint, 0);470 self.step(self.a ^ (self.a << 12), i + 2, midpoint, 0);
472 self.step( self.a ^ (self.a >> 33) , i + 3, midpoint, 0);471 self.step(self.a ^ (self.a >> 33), i + 3, midpoint, 0);
473 }472 }
474 }473 }
475474
...@@ -493,7 +492,7 @@ pub const Isaac64 = struct {...@@ -493,7 +492,7 @@ pub const Isaac64 = struct {
493 self.m[0] = init_s;492 self.m[0] = init_s;
494493
495 // prescrambled golden ratio constants494 // prescrambled golden ratio constants
496 var a = []const u64 {495 var a = []const u64{
497 0x647c4677a2884b7c,496 0x647c4677a2884b7c,
498 0xb9f8b322c73ac862,497 0xb9f8b322c73ac862,
499 0x8c0ea5053d4712a0,498 0x8c0ea5053d4712a0,
...@@ -513,14 +512,30 @@ pub const Isaac64 = struct {...@@ -513,14 +512,30 @@ pub const Isaac64 = struct {
513 a[x1] +%= self.m[j + x1];512 a[x1] +%= self.m[j + x1];
514 }513 }
515514
516 a[0] -%= a[4]; a[5] ^= a[7] >> 9; a[7] +%= a[0];515 a[0] -%= a[4];
517 a[1] -%= a[5]; a[6] ^= a[0] << 9; a[0] +%= a[1];516 a[5] ^= a[7] >> 9;
518 a[2] -%= a[6]; a[7] ^= a[1] >> 23; a[1] +%= a[2];517 a[7] +%= a[0];
519 a[3] -%= a[7]; a[0] ^= a[2] << 15; a[2] +%= a[3];518 a[1] -%= a[5];
520 a[4] -%= a[0]; a[1] ^= a[3] >> 14; a[3] +%= a[4];519 a[6] ^= a[0] << 9;
521 a[5] -%= a[1]; a[2] ^= a[4] << 20; a[4] +%= a[5];520 a[0] +%= a[1];
522 a[6] -%= a[2]; a[3] ^= a[5] >> 17; a[5] +%= a[6];521 a[2] -%= a[6];
523 a[7] -%= a[3]; a[4] ^= a[6] << 14; a[6] +%= a[7];522 a[7] ^= a[1] >> 23;
523 a[1] +%= a[2];
524 a[3] -%= a[7];
525 a[0] ^= a[2] << 15;
526 a[2] +%= a[3];
527 a[4] -%= a[0];
528 a[1] ^= a[3] >> 14;
529 a[3] +%= a[4];
530 a[5] -%= a[1];
531 a[2] ^= a[4] << 20;
532 a[4] +%= a[5];
533 a[6] -%= a[2];
534 a[3] ^= a[5] >> 17;
535 a[5] +%= a[6];
536 a[7] -%= a[3];
537 a[4] ^= a[6] << 14;
538 a[6] +%= a[7];
524539
525 comptime var x2: usize = 0;540 comptime var x2: usize = 0;
526 inline while (x2 < 8) : (x2 += 1) {541 inline while (x2 < 8) : (x2 += 1) {
...@@ -533,7 +548,7 @@ pub const Isaac64 = struct {...@@ -533,7 +548,7 @@ pub const Isaac64 = struct {
533 self.a = 0;548 self.a = 0;
534 self.b = 0;549 self.b = 0;
535 self.c = 0;550 self.c = 0;
536 self.i = self.r.len; // trigger refill on first value551 self.i = self.r.len; // trigger refill on first value
537 }552 }
538553
539 fn fill(r: &Random, buf: []u8) void {554 fn fill(r: &Random, buf: []u8) void {
...@@ -567,7 +582,7 @@ test "isaac64 sequence" {...@@ -567,7 +582,7 @@ test "isaac64 sequence" {
567 var r = Isaac64.init(0);582 var r = Isaac64.init(0);
568583
569 // from reference implementation584 // from reference implementation
570 const seq = []const u64 {585 const seq = []const u64{
571 0xf67dfba498e4937c,586 0xf67dfba498e4937c,
572 0x84a5066a9204f380,587 0x84a5066a9204f380,
573 0xfee34bd5f5514dbb,588 0xfee34bd5f5514dbb,
...@@ -609,7 +624,7 @@ test "Random float" {...@@ -609,7 +624,7 @@ test "Random float" {
609624
610test "Random scalar" {625test "Random scalar" {
611 var prng = DefaultPrng.init(0);626 var prng = DefaultPrng.init(0);
612 const s = prng .random.scalar(u64);627 const s = prng.random.scalar(u64);
613}628}
614629
615test "Random bytes" {630test "Random bytes" {
...@@ -621,8 +636,8 @@ test "Random bytes" {...@@ -621,8 +636,8 @@ test "Random bytes" {
621test "Random shuffle" {636test "Random shuffle" {
622 var prng = DefaultPrng.init(0);637 var prng = DefaultPrng.init(0);
623638
624 var seq = []const u8 { 0, 1, 2, 3, 4 };639 var seq = []const u8{ 0, 1, 2, 3, 4 };
625 var seen = []bool {false} ** 5;640 var seen = []bool{false} ** 5;
626641
627 var i: usize = 0;642 var i: usize = 0;
628 while (i < 1000) : (i += 1) {643 while (i < 1000) : (i += 1) {
...@@ -639,7 +654,8 @@ test "Random shuffle" {...@@ -639,7 +654,8 @@ test "Random shuffle" {
639654
640fn sumArray(s: []const u8) u32 {655fn sumArray(s: []const u8) u32 {
641 var r: u32 = 0;656 var r: u32 = 0;
642 for (s) |e| r += e;657 for (s) |e|
658 r += e;
643 return r;659 return r;
644}660}
645661
std/rand/ziggurat.zig+23-7
...@@ -64,8 +64,14 @@ pub const ZigTable = struct {...@@ -64,8 +64,14 @@ pub const ZigTable = struct {
64};64};
6565
66// zigNorInit66// zigNorInit
67fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn(f64) f64,67fn ZigTableGen(
68 comptime f_inv: fn(f64) f64, comptime zero_case: fn(&Random, f64) f64) ZigTable {68 comptime is_symmetric: bool,
69 comptime r: f64,
70 comptime v: f64,
71 comptime f: fn(f64) f64,
72 comptime f_inv: fn(f64) f64,
73 comptime zero_case: fn(&Random, f64) f64,
74) ZigTable {
69 var tables: ZigTable = undefined;75 var tables: ZigTable = undefined;
7076
71 tables.is_symmetric = is_symmetric;77 tables.is_symmetric = is_symmetric;
...@@ -98,8 +104,12 @@ pub const NormDist = blk: {...@@ -98,8 +104,12 @@ pub const NormDist = blk: {
98const norm_r = 3.6541528853610088;104const norm_r = 3.6541528853610088;
99const norm_v = 0.00492867323399;105const norm_v = 0.00492867323399;
100106
101fn norm_f(x: f64) f64 { return math.exp(-x * x / 2.0); }107fn norm_f(x: f64) f64 {
102fn norm_f_inv(y: f64) f64 { return math.sqrt(-2.0 * math.ln(y)); }108 return math.exp(-x * x / 2.0);
109}
110fn norm_f_inv(y: f64) f64 {
111 return math.sqrt(-2.0 * math.ln(y));
112}
103fn norm_zero_case(random: &Random, u: f64) f64 {113fn norm_zero_case(random: &Random, u: f64) f64 {
104 var x: f64 = 1;114 var x: f64 = 1;
105 var y: f64 = 0;115 var y: f64 = 0;
...@@ -133,9 +143,15 @@ pub const ExpDist = blk: {...@@ -133,9 +143,15 @@ pub const ExpDist = blk: {
133const exp_r = 7.69711747013104972;143const exp_r = 7.69711747013104972;
134const exp_v = 0.0039496598225815571993;144const exp_v = 0.0039496598225815571993;
135145
136fn exp_f(x: f64) f64 { return math.exp(-x); }146fn exp_f(x: f64) f64 {
137fn exp_f_inv(y: f64) f64 { return -math.ln(y); }147 return math.exp(-x);
138fn exp_zero_case(random: &Random, _: f64) f64 { return exp_r - math.ln(random.float(f64)); }148}
149fn exp_f_inv(y: f64) f64 {
150 return -math.ln(y);
151}
152fn exp_zero_case(random: &Random, _: f64) f64 {
153 return exp_r - math.ln(random.float(f64));
154}
139155
140test "ziggurant exp dist sanity" {156test "ziggurant exp dist sanity" {
141 var prng = std.rand.DefaultPrng.init(0);157 var prng = std.rand.DefaultPrng.init(0);
std/segmented_list.zig+43-33
...@@ -5,7 +5,7 @@ const Allocator = std.mem.Allocator;...@@ -5,7 +5,7 @@ const Allocator = std.mem.Allocator;
5// Imagine that `fn at(self: &Self, index: usize) &T` is a customer asking for a box5// Imagine that `fn at(self: &Self, index: usize) &T` is a customer asking for a box
6// from a warehouse, based on a flat array, boxes ordered from 0 to N - 1.6// from a warehouse, based on a flat array, boxes ordered from 0 to N - 1.
7// But the warehouse actually stores boxes in shelves of increasing powers of 2 sizes.7// But the warehouse actually stores boxes in shelves of increasing powers of 2 sizes.
8// So when the customer requests a box index, we have to translate it to shelf index 8// So when the customer requests a box index, we have to translate it to shelf index
9// and box index within that shelf. Illustration:9// and box index within that shelf. Illustration:
10//10//
11// customer indexes:11// customer indexes:
...@@ -37,14 +37,14 @@ const Allocator = std.mem.Allocator;...@@ -37,14 +37,14 @@ const Allocator = std.mem.Allocator;
37// Now we complicate it a little bit further by adding a preallocated shelf, which must be37// Now we complicate it a little bit further by adding a preallocated shelf, which must be
38// a power of 2:38// a power of 2:
39// prealloc=439// prealloc=4
40// 40//
41// customer indexes:41// customer indexes:
42// prealloc: 0 1 2 342// prealloc: 0 1 2 3
43// shelf 0: 4 5 6 7 8 9 10 1143// shelf 0: 4 5 6 7 8 9 10 11
44// shelf 1: 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2744// shelf 1: 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
45// shelf 2: 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 5945// shelf 2: 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
46// ...46// ...
47// 47//
48// warehouse indexes:48// warehouse indexes:
49// prealloc: 0 1 2 349// prealloc: 0 1 2 3
50// shelf 0: 0 1 2 3 4 5 6 750// shelf 0: 0 1 2 3 4 5 6 7
...@@ -95,7 +95,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -95,7 +95,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
9595
96 /// Deinitialize with `deinit`96 /// Deinitialize with `deinit`
97 pub fn init(allocator: &Allocator) Self {97 pub fn init(allocator: &Allocator) Self {
98 return Self {98 return Self{
99 .allocator = allocator,99 .allocator = allocator,
100 .len = 0,100 .len = 0,
101 .prealloc_segment = undefined,101 .prealloc_segment = undefined,
...@@ -106,7 +106,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -106,7 +106,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
106 pub fn deinit(self: &Self) void {106 pub fn deinit(self: &Self) void {
107 self.freeShelves(ShelfIndex(self.dynamic_segments.len), 0);107 self.freeShelves(ShelfIndex(self.dynamic_segments.len), 0);
108 self.allocator.free(self.dynamic_segments);108 self.allocator.free(self.dynamic_segments);
109 *self = undefined;109 self.* = undefined;
110 }110 }
111111
112 pub fn at(self: &Self, i: usize) &T {112 pub fn at(self: &Self, i: usize) &T {
...@@ -120,7 +120,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -120,7 +120,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
120120
121 pub fn push(self: &Self, item: &const T) !void {121 pub fn push(self: &Self, item: &const T) !void {
122 const new_item_ptr = try self.addOne();122 const new_item_ptr = try self.addOne();
123 *new_item_ptr = *item;123 new_item_ptr.* = item.*;
124 }124 }
125125
126 pub fn pushMany(self: &Self, items: []const T) !void {126 pub fn pushMany(self: &Self, items: []const T) !void {
...@@ -130,11 +130,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -130,11 +130,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
130 }130 }
131131
132 pub fn pop(self: &Self) ?T {132 pub fn pop(self: &Self) ?T {
133 if (self.len == 0)133 if (self.len == 0) return null;
134 return null;
135134
136 const index = self.len - 1;135 const index = self.len - 1;
137 const result = *self.uncheckedAt(index);136 const result = self.uncheckedAt(index).*;
138 self.len = index;137 self.len = index;
139 return result;138 return result;
140 }139 }
...@@ -247,8 +246,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -247,8 +246,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
247 shelf_size: usize,246 shelf_size: usize,
248247
249 pub fn next(it: &Iterator) ?&T {248 pub fn next(it: &Iterator) ?&T {
250 if (it.index >= it.list.len)249 if (it.index >= it.list.len) return null;
251 return null;
252 if (it.index < prealloc_item_count) {250 if (it.index < prealloc_item_count) {
253 const ptr = &it.list.prealloc_segment[it.index];251 const ptr = &it.list.prealloc_segment[it.index];
254 it.index += 1;252 it.index += 1;
...@@ -272,12 +270,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -272,12 +270,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
272 }270 }
273271
274 pub fn prev(it: &Iterator) ?&T {272 pub fn prev(it: &Iterator) ?&T {
275 if (it.index == 0)273 if (it.index == 0) return null;
276 return null;
277274
278 it.index -= 1;275 it.index -= 1;
279 if (it.index < prealloc_item_count)276 if (it.index < prealloc_item_count) return &it.list.prealloc_segment[it.index];
280 return &it.list.prealloc_segment[it.index];
281277
282 if (it.box_index == 0) {278 if (it.box_index == 0) {
283 it.shelf_index -= 1;279 it.shelf_index -= 1;
...@@ -298,21 +294,25 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -298,21 +294,25 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
298294
299 return &it.list.dynamic_segments[it.shelf_index][it.box_index];295 return &it.list.dynamic_segments[it.shelf_index][it.box_index];
300 }296 }
297
298 pub fn set(it: &Iterator, index: usize) void {
299 it.index = index;
300 if (index < prealloc_item_count) return;
301 it.shelf_index = shelfIndex(index);
302 it.box_index = boxIndex(index, it.shelf_index);
303 it.shelf_size = shelfSize(it.shelf_index);
304 }
301 };305 };
302306
303 pub fn iterator(self: &Self, start_index: usize) Iterator {307 pub fn iterator(self: &Self, start_index: usize) Iterator {
304 var it = Iterator {308 var it = Iterator{
305 .list = self,309 .list = self,
306 .index = start_index,310 .index = undefined,
307 .shelf_index = undefined,311 .shelf_index = undefined,
308 .box_index = undefined,312 .box_index = undefined,
309 .shelf_size = undefined,313 .shelf_size = undefined,
310 };314 };
311 if (start_index >= prealloc_item_count) {315 it.set(start_index);
312 it.shelf_index = shelfIndex(start_index);
313 it.box_index = boxIndex(start_index, it.shelf_index);
314 it.shelf_size = shelfSize(it.shelf_index);
315 }
316 return it;316 return it;
317 }317 }
318 };318 };
...@@ -335,25 +335,31 @@ fn testSegmentedList(comptime prealloc: usize, allocator: &Allocator) !void {...@@ -335,25 +335,31 @@ fn testSegmentedList(comptime prealloc: usize, allocator: &Allocator) !void {
335 var list = SegmentedList(i32, prealloc).init(allocator);335 var list = SegmentedList(i32, prealloc).init(allocator);
336 defer list.deinit();336 defer list.deinit();
337337
338 {var i: usize = 0; while (i < 100) : (i += 1) {338 {
339 try list.push(i32(i + 1));339 var i: usize = 0;
340 assert(list.len == i + 1);340 while (i < 100) : (i += 1) {
341 }}341 try list.push(i32(i + 1));
342 assert(list.len == i + 1);
343 }
344 }
342345
343 {var i: usize = 0; while (i < 100) : (i += 1) {346 {
344 assert(*list.at(i) == i32(i + 1));347 var i: usize = 0;
345 }}348 while (i < 100) : (i += 1) {
349 assert(list.at(i).* == i32(i + 1));
350 }
351 }
346352
347 {353 {
348 var it = list.iterator(0);354 var it = list.iterator(0);
349 var x: i32 = 0;355 var x: i32 = 0;
350 while (it.next()) |item| {356 while (it.next()) |item| {
351 x += 1;357 x += 1;
352 assert(*item == x);358 assert(item.* == x);
353 }359 }
354 assert(x == 100);360 assert(x == 100);
355 while (it.prev()) |item| : (x -= 1) {361 while (it.prev()) |item| : (x -= 1) {
356 assert(*item == x);362 assert(item.* == x);
357 }363 }
358 assert(x == 0);364 assert(x == 0);
359 }365 }
...@@ -361,14 +367,18 @@ fn testSegmentedList(comptime prealloc: usize, allocator: &Allocator) !void {...@@ -361,14 +367,18 @@ fn testSegmentedList(comptime prealloc: usize, allocator: &Allocator) !void {
361 assert(??list.pop() == 100);367 assert(??list.pop() == 100);
362 assert(list.len == 99);368 assert(list.len == 99);
363369
364 try list.pushMany([]i32 { 1, 2, 3 });370 try list.pushMany([]i32{
371 1,
372 2,
373 3,
374 });
365 assert(list.len == 102);375 assert(list.len == 102);
366 assert(??list.pop() == 3);376 assert(??list.pop() == 3);
367 assert(??list.pop() == 2);377 assert(??list.pop() == 2);
368 assert(??list.pop() == 1);378 assert(??list.pop() == 1);
369 assert(list.len == 99);379 assert(list.len == 99);
370380
371 try list.pushMany([]const i32 {});381 try list.pushMany([]const i32{});
372 assert(list.len == 99);382 assert(list.len == 99);
373383
374 var i: i32 = 99;384 var i: i32 = 99;
std/sort.zig+398-165
...@@ -5,15 +5,18 @@ const math = std.math;...@@ -5,15 +5,18 @@ const math = std.math;
5const builtin = @import("builtin");5const builtin = @import("builtin");
66
7/// Stable in-place sort. O(n) best case, O(pow(n, 2)) worst case. O(1) memory (no allocator required).7/// Stable in-place sort. O(n) best case, O(pow(n, 2)) worst case. O(1) memory (no allocator required).
8pub fn insertionSort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) void {8pub fn insertionSort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool) void {
9 {var i: usize = 1; while (i < items.len) : (i += 1) {9 {
10 const x = items[i];10 var i: usize = 1;
11 var j: usize = i;11 while (i < items.len) : (i += 1) {
12 while (j > 0 and lessThan(x, items[j - 1])) : (j -= 1) {12 const x = items[i];
13 items[j] = items[j - 1];13 var j: usize = i;
14 while (j > 0 and lessThan(x, items[j - 1])) : (j -= 1) {
15 items[j] = items[j - 1];
16 }
17 items[j] = x;
14 }18 }
15 items[j] = x;19 }
16 }}
17}20}
1821
19const Range = struct {22const Range = struct {
...@@ -21,7 +24,10 @@ const Range = struct {...@@ -21,7 +24,10 @@ const Range = struct {
21 end: usize,24 end: usize,
2225
23 fn init(start: usize, end: usize) Range {26 fn init(start: usize, end: usize) Range {
24 return Range { .start = start, .end = end };27 return Range{
28 .start = start,
29 .end = end,
30 };
25 }31 }
2632
27 fn length(self: &const Range) usize {33 fn length(self: &const Range) usize {
...@@ -29,7 +35,6 @@ const Range = struct {...@@ -29,7 +35,6 @@ const Range = struct {
29 }35 }
30};36};
3137
32
33const Iterator = struct {38const Iterator = struct {
34 size: usize,39 size: usize,
35 power_of_two: usize,40 power_of_two: usize,
...@@ -42,7 +47,7 @@ const Iterator = struct {...@@ -42,7 +47,7 @@ const Iterator = struct {
42 fn init(size2: usize, min_level: usize) Iterator {47 fn init(size2: usize, min_level: usize) Iterator {
43 const power_of_two = math.floorPowerOfTwo(usize, size2);48 const power_of_two = math.floorPowerOfTwo(usize, size2);
44 const denominator = power_of_two / min_level;49 const denominator = power_of_two / min_level;
45 return Iterator {50 return Iterator{
46 .numerator = 0,51 .numerator = 0,
47 .decimal = 0,52 .decimal = 0,
48 .size = size2,53 .size = size2,
...@@ -68,7 +73,10 @@ const Iterator = struct {...@@ -68,7 +73,10 @@ const Iterator = struct {
68 self.decimal += 1;73 self.decimal += 1;
69 }74 }
7075
71 return Range {.start = start, .end = self.decimal};76 return Range{
77 .start = start,
78 .end = self.decimal,
79 };
72 }80 }
7381
74 fn finished(self: &Iterator) bool {82 fn finished(self: &Iterator) bool {
...@@ -100,7 +108,7 @@ const Pull = struct {...@@ -100,7 +108,7 @@ const Pull = struct {
100108
101/// Stable in-place sort. O(n) best case, O(n*log(n)) worst case and average case. O(1) memory (no allocator required).109/// Stable in-place sort. O(n) best case, O(n*log(n)) worst case and average case. O(1) memory (no allocator required).
102/// Currently implemented as block sort.110/// Currently implemented as block sort.
103pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) void {111pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool) void {
104 // Implementation ported from https://github.com/BonzaiThePenguin/WikiSort/blob/master/WikiSort.c112 // Implementation ported from https://github.com/BonzaiThePenguin/WikiSort/blob/master/WikiSort.c
105 var cache: [512]T = undefined;113 var cache: [512]T = undefined;
106114
...@@ -123,7 +131,16 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -123,7 +131,16 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
123 // http://pages.ripco.net/~jgamble/nw.html131 // http://pages.ripco.net/~jgamble/nw.html
124 var iterator = Iterator.init(items.len, 4);132 var iterator = Iterator.init(items.len, 4);
125 while (!iterator.finished()) {133 while (!iterator.finished()) {
126 var order = []u8{0, 1, 2, 3, 4, 5, 6, 7};134 var order = []u8{
135 0,
136 1,
137 2,
138 3,
139 4,
140 5,
141 6,
142 7,
143 };
127 const range = iterator.nextRange();144 const range = iterator.nextRange();
128145
129 const sliced_items = items[range.start..];146 const sliced_items = items[range.start..];
...@@ -149,56 +166,56 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -149,56 +166,56 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
149 swap(T, sliced_items, lessThan, &order, 3, 5);166 swap(T, sliced_items, lessThan, &order, 3, 5);
150 swap(T, sliced_items, lessThan, &order, 3, 4);167 swap(T, sliced_items, lessThan, &order, 3, 4);
151 },168 },
152 7 => {169 7 => {
153 swap(T, sliced_items, lessThan, &order, 1, 2);170 swap(T, sliced_items, lessThan, &order, 1, 2);
154 swap(T, sliced_items, lessThan, &order, 3, 4);171 swap(T, sliced_items, lessThan, &order, 3, 4);
155 swap(T, sliced_items, lessThan, &order, 5, 6);172 swap(T, sliced_items, lessThan, &order, 5, 6);
156 swap(T, sliced_items, lessThan, &order, 0, 2);173 swap(T, sliced_items, lessThan, &order, 0, 2);
157 swap(T, sliced_items, lessThan, &order, 3, 5);174 swap(T, sliced_items, lessThan, &order, 3, 5);
158 swap(T, sliced_items, lessThan, &order, 4, 6);175 swap(T, sliced_items, lessThan, &order, 4, 6);
159 swap(T, sliced_items, lessThan, &order, 0, 1);176 swap(T, sliced_items, lessThan, &order, 0, 1);
160 swap(T, sliced_items, lessThan, &order, 4, 5);177 swap(T, sliced_items, lessThan, &order, 4, 5);
161 swap(T, sliced_items, lessThan, &order, 2, 6);178 swap(T, sliced_items, lessThan, &order, 2, 6);
162 swap(T, sliced_items, lessThan, &order, 0, 4);179 swap(T, sliced_items, lessThan, &order, 0, 4);
163 swap(T, sliced_items, lessThan, &order, 1, 5);180 swap(T, sliced_items, lessThan, &order, 1, 5);
164 swap(T, sliced_items, lessThan, &order, 0, 3);181 swap(T, sliced_items, lessThan, &order, 0, 3);
165 swap(T, sliced_items, lessThan, &order, 2, 5);182 swap(T, sliced_items, lessThan, &order, 2, 5);
166 swap(T, sliced_items, lessThan, &order, 1, 3);183 swap(T, sliced_items, lessThan, &order, 1, 3);
167 swap(T, sliced_items, lessThan, &order, 2, 4);184 swap(T, sliced_items, lessThan, &order, 2, 4);
168 swap(T, sliced_items, lessThan, &order, 2, 3);185 swap(T, sliced_items, lessThan, &order, 2, 3);
169 },186 },
170 6 => {187 6 => {
171 swap(T, sliced_items, lessThan, &order, 1, 2);188 swap(T, sliced_items, lessThan, &order, 1, 2);
172 swap(T, sliced_items, lessThan, &order, 4, 5);189 swap(T, sliced_items, lessThan, &order, 4, 5);
173 swap(T, sliced_items, lessThan, &order, 0, 2);190 swap(T, sliced_items, lessThan, &order, 0, 2);
174 swap(T, sliced_items, lessThan, &order, 3, 5);191 swap(T, sliced_items, lessThan, &order, 3, 5);
175 swap(T, sliced_items, lessThan, &order, 0, 1);192 swap(T, sliced_items, lessThan, &order, 0, 1);
176 swap(T, sliced_items, lessThan, &order, 3, 4);193 swap(T, sliced_items, lessThan, &order, 3, 4);
177 swap(T, sliced_items, lessThan, &order, 2, 5);194 swap(T, sliced_items, lessThan, &order, 2, 5);
178 swap(T, sliced_items, lessThan, &order, 0, 3);195 swap(T, sliced_items, lessThan, &order, 0, 3);
179 swap(T, sliced_items, lessThan, &order, 1, 4);196 swap(T, sliced_items, lessThan, &order, 1, 4);
180 swap(T, sliced_items, lessThan, &order, 2, 4);197 swap(T, sliced_items, lessThan, &order, 2, 4);
181 swap(T, sliced_items, lessThan, &order, 1, 3);198 swap(T, sliced_items, lessThan, &order, 1, 3);
182 swap(T, sliced_items, lessThan, &order, 2, 3);199 swap(T, sliced_items, lessThan, &order, 2, 3);
183 },200 },
184 5 => {201 5 => {
185 swap(T, sliced_items, lessThan, &order, 0, 1);202 swap(T, sliced_items, lessThan, &order, 0, 1);
186 swap(T, sliced_items, lessThan, &order, 3, 4);203 swap(T, sliced_items, lessThan, &order, 3, 4);
187 swap(T, sliced_items, lessThan, &order, 2, 4);204 swap(T, sliced_items, lessThan, &order, 2, 4);
188 swap(T, sliced_items, lessThan, &order, 2, 3);205 swap(T, sliced_items, lessThan, &order, 2, 3);
189 swap(T, sliced_items, lessThan, &order, 1, 4);206 swap(T, sliced_items, lessThan, &order, 1, 4);
190 swap(T, sliced_items, lessThan, &order, 0, 3);207 swap(T, sliced_items, lessThan, &order, 0, 3);
191 swap(T, sliced_items, lessThan, &order, 0, 2);208 swap(T, sliced_items, lessThan, &order, 0, 2);
192 swap(T, sliced_items, lessThan, &order, 1, 3);209 swap(T, sliced_items, lessThan, &order, 1, 3);
193 swap(T, sliced_items, lessThan, &order, 1, 2);210 swap(T, sliced_items, lessThan, &order, 1, 2);
194 },211 },
195 4 => {212 4 => {
196 swap(T, sliced_items, lessThan, &order, 0, 1);213 swap(T, sliced_items, lessThan, &order, 0, 1);
197 swap(T, sliced_items, lessThan, &order, 2, 3);214 swap(T, sliced_items, lessThan, &order, 2, 3);
198 swap(T, sliced_items, lessThan, &order, 0, 2);215 swap(T, sliced_items, lessThan, &order, 0, 2);
199 swap(T, sliced_items, lessThan, &order, 1, 3);216 swap(T, sliced_items, lessThan, &order, 1, 3);
200 swap(T, sliced_items, lessThan, &order, 1, 2);217 swap(T, sliced_items, lessThan, &order, 1, 2);
201 },218 },
202 else => {},219 else => {},
203 }220 }
204 }221 }
...@@ -273,7 +290,6 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -273,7 +290,6 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
273 // we merged two levels at the same time, so we're done with this level already290 // we merged two levels at the same time, so we're done with this level already
274 // (iterator.nextLevel() is called again at the bottom of this outer merge loop)291 // (iterator.nextLevel() is called again at the bottom of this outer merge loop)
275 _ = iterator.nextLevel();292 _ = iterator.nextLevel();
276
277 } else {293 } else {
278 iterator.begin();294 iterator.begin();
279 while (!iterator.finished()) {295 while (!iterator.finished()) {
...@@ -301,9 +317,8 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -301,9 +317,8 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
301 // 6. merge each A block with any B values that follow, using the cache or the second internal buffer317 // 6. merge each A block with any B values that follow, using the cache or the second internal buffer
302 // 7. sort the second internal buffer if it exists318 // 7. sort the second internal buffer if it exists
303 // 8. redistribute the two internal buffers back into the items319 // 8. redistribute the two internal buffers back into the items
304
305 var block_size: usize = math.sqrt(iterator.length());320 var block_size: usize = math.sqrt(iterator.length());
306 var buffer_size = iterator.length()/block_size + 1;321 var buffer_size = iterator.length() / block_size + 1;
307322
308 // as an optimization, we really only need to pull out the internal buffers once for each level of merges323 // as an optimization, we really only need to pull out the internal buffers once for each level of merges
309 // after that we can reuse the same buffers over and over, then redistribute it when we're finished with this level324 // after that we can reuse the same buffers over and over, then redistribute it when we're finished with this level
...@@ -316,8 +331,18 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -316,8 +331,18 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
316 var start: usize = 0;331 var start: usize = 0;
317 var pull_index: usize = 0;332 var pull_index: usize = 0;
318 var pull = []Pull{333 var pull = []Pull{
319 Pull {.from = 0, .to = 0, .count = 0, .range = Range.init(0, 0),},334 Pull{
320 Pull {.from = 0, .to = 0, .count = 0, .range = Range.init(0, 0),},335 .from = 0,
336 .to = 0,
337 .count = 0,
338 .range = Range.init(0, 0),
339 },
340 Pull{
341 .from = 0,
342 .to = 0,
343 .count = 0,
344 .range = Range.init(0, 0),
345 },
321 };346 };
322347
323 var buffer1 = Range.init(0, 0);348 var buffer1 = Range.init(0, 0);
...@@ -355,7 +380,10 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -355,7 +380,10 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
355 // these values will be pulled out to the start of A380 // these values will be pulled out to the start of A
356 last = A.start;381 last = A.start;
357 count = 1;382 count = 1;
358 while (count < find) : ({last = index; count += 1;}) {383 while (count < find) : ({
384 last = index;
385 count += 1;
386 }) {
359 index = findLastForward(T, items, items[last], Range.init(last + 1, A.end), lessThan, find - count);387 index = findLastForward(T, items, items[last], Range.init(last + 1, A.end), lessThan, find - count);
360 if (index == A.end) break;388 if (index == A.end) break;
361 }389 }
...@@ -363,7 +391,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -363,7 +391,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
363391
364 if (count >= buffer_size) {392 if (count >= buffer_size) {
365 // keep track of the range within the items where we'll need to "pull out" these values to create the internal buffer393 // keep track of the range within the items where we'll need to "pull out" these values to create the internal buffer
366 pull[pull_index] = Pull {394 pull[pull_index] = Pull{
367 .range = Range.init(A.start, B.end),395 .range = Range.init(A.start, B.end),
368 .count = count,396 .count = count,
369 .from = index,397 .from = index,
...@@ -398,7 +426,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -398,7 +426,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
398 } else if (pull_index == 0 and count > buffer1.length()) {426 } else if (pull_index == 0 and count > buffer1.length()) {
399 // keep track of the largest buffer we were able to find427 // keep track of the largest buffer we were able to find
400 buffer1 = Range.init(A.start, A.start + count);428 buffer1 = Range.init(A.start, A.start + count);
401 pull[pull_index] = Pull {429 pull[pull_index] = Pull{
402 .range = Range.init(A.start, B.end),430 .range = Range.init(A.start, B.end),
403 .count = count,431 .count = count,
404 .from = index,432 .from = index,
...@@ -410,7 +438,10 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -410,7 +438,10 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
410 // these values will be pulled out to the end of B438 // these values will be pulled out to the end of B
411 last = B.end - 1;439 last = B.end - 1;
412 count = 1;440 count = 1;
413 while (count < find) : ({last = index - 1; count += 1;}) {441 while (count < find) : ({
442 last = index - 1;
443 count += 1;
444 }) {
414 index = findFirstBackward(T, items, items[last], Range.init(B.start, last), lessThan, find - count);445 index = findFirstBackward(T, items, items[last], Range.init(B.start, last), lessThan, find - count);
415 if (index == B.start) break;446 if (index == B.start) break;
416 }447 }
...@@ -418,7 +449,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -418,7 +449,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
418449
419 if (count >= buffer_size) {450 if (count >= buffer_size) {
420 // keep track of the range within the items where we'll need to "pull out" these values to create the internal buffe451 // keep track of the range within the items where we'll need to "pull out" these values to create the internal buffe
421 pull[pull_index] = Pull {452 pull[pull_index] = Pull{
422 .range = Range.init(A.start, B.end),453 .range = Range.init(A.start, B.end),
423 .count = count,454 .count = count,
424 .from = index,455 .from = index,
...@@ -457,7 +488,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -457,7 +488,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
457 } else if (pull_index == 0 and count > buffer1.length()) {488 } else if (pull_index == 0 and count > buffer1.length()) {
458 // keep track of the largest buffer we were able to find489 // keep track of the largest buffer we were able to find
459 buffer1 = Range.init(B.end - count, B.end);490 buffer1 = Range.init(B.end - count, B.end);
460 pull[pull_index] = Pull {491 pull[pull_index] = Pull{
461 .range = Range.init(A.start, B.end),492 .range = Range.init(A.start, B.end),
462 .count = count,493 .count = count,
463 .from = index,494 .from = index,
...@@ -496,7 +527,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -496,7 +527,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
496527
497 // adjust block_size and buffer_size based on the values we were able to pull out528 // adjust block_size and buffer_size based on the values we were able to pull out
498 buffer_size = buffer1.length();529 buffer_size = buffer1.length();
499 block_size = iterator.length()/buffer_size + 1;530 block_size = iterator.length() / buffer_size + 1;
500531
501 // the first buffer NEEDS to be large enough to tag each of the evenly sized A blocks,532 // the first buffer NEEDS to be large enough to tag each of the evenly sized A blocks,
502 // so this was originally here to test the math for adjusting block_size above533 // so this was originally here to test the math for adjusting block_size above
...@@ -547,7 +578,10 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -547,7 +578,10 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
547 // swap the first value of each A block with the value in buffer1578 // swap the first value of each A block with the value in buffer1
548 var indexA = buffer1.start;579 var indexA = buffer1.start;
549 index = firstA.end;580 index = firstA.end;
550 while (index < blockA.end) : ({indexA += 1; index += block_size;}) {581 while (index < blockA.end) : ({
582 indexA += 1;
583 index += block_size;
584 }) {
551 mem.swap(T, &items[indexA], &items[index]);585 mem.swap(T, &items[indexA], &items[index]);
552 }586 }
553587
...@@ -626,9 +660,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -626,9 +660,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
626660
627 // if there are no more A blocks remaining, this step is finished!661 // if there are no more A blocks remaining, this step is finished!
628 blockA.start += block_size;662 blockA.start += block_size;
629 if (blockA.length() == 0)663 if (blockA.length() == 0) break;
630 break;
631
632 } else if (blockB.length() < block_size) {664 } else if (blockB.length() < block_size) {
633 // move the last B block, which is unevenly sized, to before the remaining A blocks, by using a rotation665 // move the last B block, which is unevenly sized, to before the remaining A blocks, by using a rotation
634 // the cache is disabled here since it might contain the contents of the previous A block666 // the cache is disabled here since it might contain the contents of the previous A block
...@@ -709,7 +741,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -709,7 +741,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
709}741}
710742
711// merge operation without a buffer743// merge operation without a buffer
712fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const Range, lessThan: fn(&const T,&const T)bool) void {744fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const Range, lessThan: fn(&const T, &const T) bool) void {
713 if (A_arg.length() == 0 or B_arg.length() == 0) return;745 if (A_arg.length() == 0 or B_arg.length() == 0) return;
714746
715 // this just repeatedly binary searches into B and rotates A into position.747 // this just repeatedly binary searches into B and rotates A into position.
...@@ -730,8 +762,8 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const...@@ -730,8 +762,8 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const
730 // again, this is NOT a general-purpose solution – it only works well in this case!762 // again, this is NOT a general-purpose solution – it only works well in this case!
731 // kind of like how the O(n^2) insertion sort is used in some places763 // kind of like how the O(n^2) insertion sort is used in some places
732764
733 var A = *A_arg;765 var A = A_arg.*;
734 var B = *B_arg;766 var B = B_arg.*;
735767
736 while (true) {768 while (true) {
737 // find the first place in B where the first item in A needs to be inserted769 // find the first place in B where the first item in A needs to be inserted
...@@ -751,7 +783,7 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const...@@ -751,7 +783,7 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const
751}783}
752784
753// merge operation using an internal buffer785// merge operation using an internal buffer
754fn mergeInternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)bool, buffer: &const Range) void {786fn mergeInternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T, &const T) bool, buffer: &const Range) void {
755 // whenever we find a value to add to the final array, swap it with the value that's already in that spot787 // whenever we find a value to add to the final array, swap it with the value that's already in that spot
756 // when this algorithm is finished, 'buffer' will contain its original contents, but in a different order788 // when this algorithm is finished, 'buffer' will contain its original contents, but in a different order
757 var A_count: usize = 0;789 var A_count: usize = 0;
...@@ -787,9 +819,9 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s...@@ -787,9 +819,9 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s
787819
788// combine a linear search with a binary search to reduce the number of comparisons in situations820// combine a linear search with a binary search to reduce the number of comparisons in situations
789// where have some idea as to how many unique values there are and where the next value might be821// where have some idea as to how many unique values there are and where the next value might be
790fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {822fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool, unique: usize) usize {
791 if (range.length() == 0) return range.start;823 if (range.length() == 0) return range.start;
792 const skip = math.max(range.length()/unique, usize(1));824 const skip = math.max(range.length() / unique, usize(1));
793825
794 var index = range.start + skip;826 var index = range.start + skip;
795 while (lessThan(items[index - 1], value)) : (index += skip) {827 while (lessThan(items[index - 1], value)) : (index += skip) {
...@@ -801,9 +833,9 @@ fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const...@@ -801,9 +833,9 @@ fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const
801 return binaryFirst(T, items, value, Range.init(index - skip, index), lessThan);833 return binaryFirst(T, items, value, Range.init(index - skip, index), lessThan);
802}834}
803835
804fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {836fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool, unique: usize) usize {
805 if (range.length() == 0) return range.start;837 if (range.length() == 0) return range.start;
806 const skip = math.max(range.length()/unique, usize(1));838 const skip = math.max(range.length() / unique, usize(1));
807839
808 var index = range.end - skip;840 var index = range.end - skip;
809 while (index > range.start and !lessThan(items[index - 1], value)) : (index -= skip) {841 while (index > range.start and !lessThan(items[index - 1], value)) : (index -= skip) {
...@@ -815,9 +847,9 @@ fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &cons...@@ -815,9 +847,9 @@ fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &cons
815 return binaryFirst(T, items, value, Range.init(index, index + skip), lessThan);847 return binaryFirst(T, items, value, Range.init(index, index + skip), lessThan);
816}848}
817849
818fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {850fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool, unique: usize) usize {
819 if (range.length() == 0) return range.start;851 if (range.length() == 0) return range.start;
820 const skip = math.max(range.length()/unique, usize(1));852 const skip = math.max(range.length() / unique, usize(1));
821853
822 var index = range.start + skip;854 var index = range.start + skip;
823 while (!lessThan(value, items[index - 1])) : (index += skip) {855 while (!lessThan(value, items[index - 1])) : (index += skip) {
...@@ -829,9 +861,9 @@ fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const...@@ -829,9 +861,9 @@ fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const
829 return binaryLast(T, items, value, Range.init(index - skip, index), lessThan);861 return binaryLast(T, items, value, Range.init(index - skip, index), lessThan);
830}862}
831863
832fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {864fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool, unique: usize) usize {
833 if (range.length() == 0) return range.start;865 if (range.length() == 0) return range.start;
834 const skip = math.max(range.length()/unique, usize(1));866 const skip = math.max(range.length() / unique, usize(1));
835867
836 var index = range.end - skip;868 var index = range.end - skip;
837 while (index > range.start and lessThan(value, items[index - 1])) : (index -= skip) {869 while (index > range.start and lessThan(value, items[index - 1])) : (index -= skip) {
...@@ -843,12 +875,12 @@ fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const...@@ -843,12 +875,12 @@ fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const
843 return binaryLast(T, items, value, Range.init(index, index + skip), lessThan);875 return binaryLast(T, items, value, Range.init(index, index + skip), lessThan);
844}876}
845877
846fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool) usize {878fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool) usize {
847 var start = range.start;879 var start = range.start;
848 var end = range.end - 1;880 var end = range.end - 1;
849 if (range.start >= range.end) return range.end;881 if (range.start >= range.end) return range.end;
850 while (start < end) {882 while (start < end) {
851 const mid = start + (end - start)/2;883 const mid = start + (end - start) / 2;
852 if (lessThan(items[mid], value)) {884 if (lessThan(items[mid], value)) {
853 start = mid + 1;885 start = mid + 1;
854 } else {886 } else {
...@@ -861,12 +893,12 @@ fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Rang...@@ -861,12 +893,12 @@ fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Rang
861 return start;893 return start;
862}894}
863895
864fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool) usize {896fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool) usize {
865 var start = range.start;897 var start = range.start;
866 var end = range.end - 1;898 var end = range.end - 1;
867 if (range.start >= range.end) return range.end;899 if (range.start >= range.end) return range.end;
868 while (start < end) {900 while (start < end) {
869 const mid = start + (end - start)/2;901 const mid = start + (end - start) / 2;
870 if (!lessThan(value, items[mid])) {902 if (!lessThan(value, items[mid])) {
871 start = mid + 1;903 start = mid + 1;
872 } else {904 } else {
...@@ -879,7 +911,7 @@ fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range...@@ -879,7 +911,7 @@ fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range
879 return start;911 return start;
880}912}
881913
882fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)bool, into: []T) void {914fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, lessThan: fn(&const T, &const T) bool, into: []T) void {
883 var A_index: usize = A.start;915 var A_index: usize = A.start;
884 var B_index: usize = B.start;916 var B_index: usize = B.start;
885 const A_last = A.end;917 const A_last = A.end;
...@@ -909,7 +941,7 @@ fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, less...@@ -909,7 +941,7 @@ fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, less
909 }941 }
910}942}
911943
912fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)bool, cache: []T) void {944fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T, &const T) bool, cache: []T) void {
913 // A fits into the cache, so use that instead of the internal buffer945 // A fits into the cache, so use that instead of the internal buffer
914 var A_index: usize = 0;946 var A_index: usize = 0;
915 var B_index: usize = B.start;947 var B_index: usize = B.start;
...@@ -937,29 +969,27 @@ fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range,...@@ -937,29 +969,27 @@ fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range,
937 mem.copy(T, items[insert_index..], cache[A_index..A_last]);969 mem.copy(T, items[insert_index..], cache[A_index..A_last]);
938}970}
939971
940fn swap(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool, order: &[8]u8, x: usize, y: usize) void {972fn swap(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool, order: &[8]u8, x: usize, y: usize) void {
941 if (lessThan(items[y], items[x]) or973 if (lessThan(items[y], items[x]) or ((order.*)[x] > (order.*)[y] and !lessThan(items[x], items[y]))) {
942 ((*order)[x] > (*order)[y] and !lessThan(items[x], items[y])))
943 {
944 mem.swap(T, &items[x], &items[y]);974 mem.swap(T, &items[x], &items[y]);
945 mem.swap(u8, &(*order)[x], &(*order)[y]);975 mem.swap(u8, &(order.*)[x], &(order.*)[y]);
946 }976 }
947}977}
948978
949fn i32asc(lhs: &const i32, rhs: &const i32) bool {979fn i32asc(lhs: &const i32, rhs: &const i32) bool {
950 return *lhs < *rhs;980 return lhs.* < rhs.*;
951}981}
952982
953fn i32desc(lhs: &const i32, rhs: &const i32) bool {983fn i32desc(lhs: &const i32, rhs: &const i32) bool {
954 return *rhs < *lhs;984 return rhs.* < lhs.*;
955}985}
956986
957fn u8asc(lhs: &const u8, rhs: &const u8) bool {987fn u8asc(lhs: &const u8, rhs: &const u8) bool {
958 return *lhs < *rhs;988 return lhs.* < rhs.*;
959}989}
960990
961fn u8desc(lhs: &const u8, rhs: &const u8) bool {991fn u8desc(lhs: &const u8, rhs: &const u8) bool {
962 return *rhs < *lhs;992 return rhs.* < lhs.*;
963}993}
964994
965test "stable sort" {995test "stable sort" {
...@@ -967,44 +997,125 @@ test "stable sort" {...@@ -967,44 +997,125 @@ test "stable sort" {
967 comptime testStableSort();997 comptime testStableSort();
968}998}
969fn testStableSort() void {999fn testStableSort() void {
970 var expected = []IdAndValue {1000 var expected = []IdAndValue{
971 IdAndValue{.id = 0, .value = 0},1001 IdAndValue{
972 IdAndValue{.id = 1, .value = 0},1002 .id = 0,
973 IdAndValue{.id = 2, .value = 0},1003 .value = 0,
974 IdAndValue{.id = 0, .value = 1},1004 },
975 IdAndValue{.id = 1, .value = 1},1005 IdAndValue{
976 IdAndValue{.id = 2, .value = 1},1006 .id = 1,
977 IdAndValue{.id = 0, .value = 2},1007 .value = 0,
978 IdAndValue{.id = 1, .value = 2},1008 },
979 IdAndValue{.id = 2, .value = 2},1009 IdAndValue{
1010 .id = 2,
1011 .value = 0,
1012 },
1013 IdAndValue{
1014 .id = 0,
1015 .value = 1,
1016 },
1017 IdAndValue{
1018 .id = 1,
1019 .value = 1,
1020 },
1021 IdAndValue{
1022 .id = 2,
1023 .value = 1,
1024 },
1025 IdAndValue{
1026 .id = 0,
1027 .value = 2,
1028 },
1029 IdAndValue{
1030 .id = 1,
1031 .value = 2,
1032 },
1033 IdAndValue{
1034 .id = 2,
1035 .value = 2,
1036 },
980 };1037 };
981 var cases = [][9]IdAndValue {1038 var cases = [][9]IdAndValue{
982 []IdAndValue {1039 []IdAndValue{
983 IdAndValue{.id = 0, .value = 0},1040 IdAndValue{
984 IdAndValue{.id = 0, .value = 1},1041 .id = 0,
985 IdAndValue{.id = 0, .value = 2},1042 .value = 0,
986 IdAndValue{.id = 1, .value = 0},1043 },
987 IdAndValue{.id = 1, .value = 1},1044 IdAndValue{
988 IdAndValue{.id = 1, .value = 2},1045 .id = 0,
989 IdAndValue{.id = 2, .value = 0},1046 .value = 1,
990 IdAndValue{.id = 2, .value = 1},1047 },
991 IdAndValue{.id = 2, .value = 2},1048 IdAndValue{
1049 .id = 0,
1050 .value = 2,
1051 },
1052 IdAndValue{
1053 .id = 1,
1054 .value = 0,
1055 },
1056 IdAndValue{
1057 .id = 1,
1058 .value = 1,
1059 },
1060 IdAndValue{
1061 .id = 1,
1062 .value = 2,
1063 },
1064 IdAndValue{
1065 .id = 2,
1066 .value = 0,
1067 },
1068 IdAndValue{
1069 .id = 2,
1070 .value = 1,
1071 },
1072 IdAndValue{
1073 .id = 2,
1074 .value = 2,
1075 },
992 },1076 },
993 []IdAndValue {1077 []IdAndValue{
994 IdAndValue{.id = 0, .value = 2},1078 IdAndValue{
995 IdAndValue{.id = 0, .value = 1},1079 .id = 0,
996 IdAndValue{.id = 0, .value = 0},1080 .value = 2,
997 IdAndValue{.id = 1, .value = 2},1081 },
998 IdAndValue{.id = 1, .value = 1},1082 IdAndValue{
999 IdAndValue{.id = 1, .value = 0},1083 .id = 0,
1000 IdAndValue{.id = 2, .value = 2},1084 .value = 1,
1001 IdAndValue{.id = 2, .value = 1},1085 },
1002 IdAndValue{.id = 2, .value = 0},1086 IdAndValue{
1087 .id = 0,
1088 .value = 0,
1089 },
1090 IdAndValue{
1091 .id = 1,
1092 .value = 2,
1093 },
1094 IdAndValue{
1095 .id = 1,
1096 .value = 1,
1097 },
1098 IdAndValue{
1099 .id = 1,
1100 .value = 0,
1101 },
1102 IdAndValue{
1103 .id = 2,
1104 .value = 2,
1105 },
1106 IdAndValue{
1107 .id = 2,
1108 .value = 1,
1109 },
1110 IdAndValue{
1111 .id = 2,
1112 .value = 0,
1113 },
1003 },1114 },
1004 };1115 };
1005 for (cases) |*case| {1116 for (cases) |*case| {
1006 insertionSort(IdAndValue, (*case)[0..], cmpByValue);1117 insertionSort(IdAndValue, (case.*)[0..], cmpByValue);
1007 for (*case) |item, i| {1118 for (case.*) |item, i| {
1008 assert(item.id == expected[i].id);1119 assert(item.id == expected[i].id);
1009 assert(item.value == expected[i].value);1120 assert(item.value == expected[i].value);
1010 }1121 }
...@@ -1019,13 +1130,31 @@ fn cmpByValue(a: &const IdAndValue, b: &const IdAndValue) bool {...@@ -1019,13 +1130,31 @@ fn cmpByValue(a: &const IdAndValue, b: &const IdAndValue) bool {
1019}1130}
10201131
1021test "std.sort" {1132test "std.sort" {
1022 const u8cases = [][]const []const u8 {1133 const u8cases = [][]const []const u8{
1023 [][]const u8{"", ""},1134 [][]const u8{
1024 [][]const u8{"a", "a"},1135 "",
1025 [][]const u8{"az", "az"},1136 "",
1026 [][]const u8{"za", "az"},1137 },
1027 [][]const u8{"asdf", "adfs"},1138 [][]const u8{
1028 [][]const u8{"one", "eno"},1139 "a",
1140 "a",
1141 },
1142 [][]const u8{
1143 "az",
1144 "az",
1145 },
1146 [][]const u8{
1147 "za",
1148 "az",
1149 },
1150 [][]const u8{
1151 "asdf",
1152 "adfs",
1153 },
1154 [][]const u8{
1155 "one",
1156 "eno",
1157 },
1029 };1158 };
10301159
1031 for (u8cases) |case| {1160 for (u8cases) |case| {
...@@ -1036,13 +1165,59 @@ test "std.sort" {...@@ -1036,13 +1165,59 @@ test "std.sort" {
1036 assert(mem.eql(u8, slice, case[1]));1165 assert(mem.eql(u8, slice, case[1]));
1037 }1166 }
10381167
1039 const i32cases = [][]const []const i32 {1168 const i32cases = [][]const []const i32{
1040 [][]const i32{[]i32{}, []i32{}},1169 [][]const i32{
1041 [][]const i32{[]i32{1}, []i32{1}},1170 []i32{},
1042 [][]const i32{[]i32{0, 1}, []i32{0, 1}},1171 []i32{},
1043 [][]const i32{[]i32{1, 0}, []i32{0, 1}},1172 },
1044 [][]const i32{[]i32{1, -1, 0}, []i32{-1, 0, 1}},1173 [][]const i32{
1045 [][]const i32{[]i32{2, 1, 3}, []i32{1, 2, 3}},1174 []i32{1},
1175 []i32{1},
1176 },
1177 [][]const i32{
1178 []i32{
1179 0,
1180 1,
1181 },
1182 []i32{
1183 0,
1184 1,
1185 },
1186 },
1187 [][]const i32{
1188 []i32{
1189 1,
1190 0,
1191 },
1192 []i32{
1193 0,
1194 1,
1195 },
1196 },
1197 [][]const i32{
1198 []i32{
1199 1,
1200 -1,
1201 0,
1202 },
1203 []i32{
1204 -1,
1205 0,
1206 1,
1207 },
1208 },
1209 [][]const i32{
1210 []i32{
1211 2,
1212 1,
1213 3,
1214 },
1215 []i32{
1216 1,
1217 2,
1218 3,
1219 },
1220 },
1046 };1221 };
10471222
1048 for (i32cases) |case| {1223 for (i32cases) |case| {
...@@ -1055,13 +1230,59 @@ test "std.sort" {...@@ -1055,13 +1230,59 @@ test "std.sort" {
1055}1230}
10561231
1057test "std.sort descending" {1232test "std.sort descending" {
1058 const rev_cases = [][]const []const i32 {1233 const rev_cases = [][]const []const i32{
1059 [][]const i32{[]i32{}, []i32{}},1234 [][]const i32{
1060 [][]const i32{[]i32{1}, []i32{1}},1235 []i32{},
1061 [][]const i32{[]i32{0, 1}, []i32{1, 0}},1236 []i32{},
1062 [][]const i32{[]i32{1, 0}, []i32{1, 0}},1237 },
1063 [][]const i32{[]i32{1, -1, 0}, []i32{1, 0, -1}},1238 [][]const i32{
1064 [][]const i32{[]i32{2, 1, 3}, []i32{3, 2, 1}},1239 []i32{1},
1240 []i32{1},
1241 },
1242 [][]const i32{
1243 []i32{
1244 0,
1245 1,
1246 },
1247 []i32{
1248 1,
1249 0,
1250 },
1251 },
1252 [][]const i32{
1253 []i32{
1254 1,
1255 0,
1256 },
1257 []i32{
1258 1,
1259 0,
1260 },
1261 },
1262 [][]const i32{
1263 []i32{
1264 1,
1265 -1,
1266 0,
1267 },
1268 []i32{
1269 1,
1270 0,
1271 -1,
1272 },
1273 },
1274 [][]const i32{
1275 []i32{
1276 2,
1277 1,
1278 3,
1279 },
1280 []i32{
1281 3,
1282 2,
1283 1,
1284 },
1285 },
1065 };1286 };
10661287
1067 for (rev_cases) |case| {1288 for (rev_cases) |case| {
...@@ -1074,10 +1295,22 @@ test "std.sort descending" {...@@ -1074,10 +1295,22 @@ test "std.sort descending" {
1074}1295}
10751296
1076test "another sort case" {1297test "another sort case" {
1077 var arr = []i32{ 5, 3, 1, 2, 4 };1298 var arr = []i32{
1299 5,
1300 3,
1301 1,
1302 2,
1303 4,
1304 };
1078 sort(i32, arr[0..], i32asc);1305 sort(i32, arr[0..], i32asc);
10791306
1080 assert(mem.eql(i32, arr, []i32{ 1, 2, 3, 4, 5 }));1307 assert(mem.eql(i32, arr, []i32{
1308 1,
1309 2,
1310 3,
1311 4,
1312 5,
1313 }));
1081}1314}
10821315
1083test "sort fuzz testing" {1316test "sort fuzz testing" {
...@@ -1112,7 +1345,7 @@ fn fuzzTest(rng: &std.rand.Random) void {...@@ -1112,7 +1345,7 @@ fn fuzzTest(rng: &std.rand.Random) void {
1112 }1345 }
1113}1346}
11141347
1115pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) T {1348pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool) T {
1116 var i: usize = 0;1349 var i: usize = 0;
1117 var smallest = items[0];1350 var smallest = items[0];
1118 for (items[1..]) |item| {1351 for (items[1..]) |item| {
...@@ -1123,7 +1356,7 @@ pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const...@@ -1123,7 +1356,7 @@ pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const
1123 return smallest;1356 return smallest;
1124}1357}
11251358
1126pub fn max(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) T {1359pub fn max(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool) T {
1127 var i: usize = 0;1360 var i: usize = 0;
1128 var biggest = items[0];1361 var biggest = items[0];
1129 for (items[1..]) |item| {1362 for (items[1..]) |item| {
std/special/bootstrap.zig+8-4
...@@ -27,10 +27,14 @@ extern fn zen_start() noreturn {...@@ -27,10 +27,14 @@ extern fn zen_start() noreturn {
27nakedcc fn _start() noreturn {27nakedcc fn _start() noreturn {
28 switch (builtin.arch) {28 switch (builtin.arch) {
29 builtin.Arch.x86_64 => {29 builtin.Arch.x86_64 => {
30 argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize));30 argc_ptr = asm ("lea (%%rsp), %[argc]"
31 : [argc] "=r" (-> &usize)
32 );
31 },33 },
32 builtin.Arch.i386 => {34 builtin.Arch.i386 => {
33 argc_ptr = asm("lea (%%esp), %[argc]": [argc] "=r" (-> &usize));35 argc_ptr = asm ("lea (%%esp), %[argc]"
36 : [argc] "=r" (-> &usize)
37 );
34 },38 },
35 else => @compileError("unsupported arch"),39 else => @compileError("unsupported arch"),
36 }40 }
...@@ -46,7 +50,7 @@ extern fn WinMainCRTStartup() noreturn {...@@ -46,7 +50,7 @@ extern fn WinMainCRTStartup() noreturn {
46}50}
4751
48fn posixCallMainAndExit() noreturn {52fn posixCallMainAndExit() noreturn {
49 const argc = *argc_ptr;53 const argc = argc_ptr.*;
50 const argv = @ptrCast(&&u8, &argc_ptr[1]);54 const argv = @ptrCast(&&u8, &argc_ptr[1]);
51 const envp_nullable = @ptrCast(&?&u8, &argv[argc + 1]);55 const envp_nullable = @ptrCast(&?&u8, &argv[argc + 1]);
52 var envp_count: usize = 0;56 var envp_count: usize = 0;
...@@ -56,7 +60,7 @@ fn posixCallMainAndExit() noreturn {...@@ -56,7 +60,7 @@ fn posixCallMainAndExit() noreturn {
56 const auxv = &@ptrCast(&usize, envp.ptr)[envp_count + 1];60 const auxv = &@ptrCast(&usize, envp.ptr)[envp_count + 1];
57 var i: usize = 0;61 var i: usize = 0;
58 while (auxv[i] != 0) : (i += 2) {62 while (auxv[i] != 0) : (i += 2) {
59 if (auxv[i] < std.os.linux_aux_raw.len) std.os.linux_aux_raw[auxv[i]] = auxv[i+1];63 if (auxv[i] < std.os.linux_aux_raw.len) std.os.linux_aux_raw[auxv[i]] = auxv[i + 1];
60 }64 }
61 std.debug.assert(std.os.linux_aux_raw[std.elf.AT_PAGESZ] == std.os.page_size);65 std.debug.assert(std.os.linux_aux_raw[std.elf.AT_PAGESZ] == std.os.page_size);
62 }66 }
std/special/bootstrap_lib.zig+5-3
...@@ -7,8 +7,10 @@ comptime {...@@ -7,8 +7,10 @@ comptime {
7 @export("_DllMainCRTStartup", _DllMainCRTStartup, builtin.GlobalLinkage.Strong);7 @export("_DllMainCRTStartup", _DllMainCRTStartup, builtin.GlobalLinkage.Strong);
8}8}
99
10stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD,10stdcallcc fn _DllMainCRTStartup(
11 lpReserved: std.os.windows.LPVOID) std.os.windows.BOOL11 hinstDLL: std.os.windows.HINSTANCE,
12{12 fdwReason: std.os.windows.DWORD,
13 lpReserved: std.os.windows.LPVOID,
14) std.os.windows.BOOL {
13 return std.os.windows.TRUE;15 return std.os.windows.TRUE;
14}16}
std/special/build_runner.zig+2-4
...@@ -24,7 +24,6 @@ pub fn main() !void {...@@ -24,7 +24,6 @@ pub fn main() !void {
2424
25 const allocator = &arena.allocator;25 const allocator = &arena.allocator;
2626
27
28 // skip my own exe name27 // skip my own exe name
29 _ = arg_it.skip();28 _ = arg_it.skip();
3029
...@@ -175,8 +174,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: var) !void {...@@ -175,8 +174,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: var) !void {
175 try out_stream.print(" (none)\n");174 try out_stream.print(" (none)\n");
176 } else {175 } else {
177 for (builder.available_options_list.toSliceConst()) |option| {176 for (builder.available_options_list.toSliceConst()) |option| {
178 const name = try fmt.allocPrint(allocator,177 const name = try fmt.allocPrint(allocator, " -D{}=[{}]", option.name, Builder.typeIdName(option.type_id));
179 " -D{}=[{}]", option.name, Builder.typeIdName(option.type_id));
180 defer allocator.free(name);178 defer allocator.free(name);
181 try out_stream.print("{s24} {}\n", name, option.description);179 try out_stream.print("{s24} {}\n", name, option.description);
182 }180 }
...@@ -202,7 +200,7 @@ fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: var) erro...@@ -202,7 +200,7 @@ fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: var) erro
202 return error.InvalidArgs;200 return error.InvalidArgs;
203}201}
204202
205const UnwrapArgError = error {OutOfMemory};203const UnwrapArgError = error{OutOfMemory};
206204
207fn unwrapArg(arg: UnwrapArgError![]u8) UnwrapArgError![]u8 {205fn unwrapArg(arg: UnwrapArgError![]u8) UnwrapArgError![]u8 {
208 return arg catch |err| {206 return arg catch |err| {
std/special/builtin.zig+41-19
...@@ -56,7 +56,8 @@ export fn memmove(dest: ?&u8, src: ?&const u8, n: usize) ?&u8 {...@@ -56,7 +56,8 @@ export fn memmove(dest: ?&u8, src: ?&const u8, n: usize) ?&u8 {
56comptime {56comptime {
57 if (builtin.mode != builtin.Mode.ReleaseFast and57 if (builtin.mode != builtin.Mode.ReleaseFast and
58 builtin.mode != builtin.Mode.ReleaseSmall and58 builtin.mode != builtin.Mode.ReleaseSmall and
59 builtin.os != builtin.Os.windows) {59 builtin.os != builtin.Os.windows)
60 {
60 @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong);61 @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong);
61 }62 }
62 if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) {63 if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) {
...@@ -101,15 +102,27 @@ nakedcc fn clone() void {...@@ -101,15 +102,27 @@ nakedcc fn clone() void {
101102
102const math = @import("../math/index.zig");103const math = @import("../math/index.zig");
103104
104export fn fmodf(x: f32, y: f32) f32 { return generic_fmod(f32, x, y); }105export fn fmodf(x: f32, y: f32) f32 {
105export fn fmod(x: f64, y: f64) f64 { return generic_fmod(f64, x, y); }106 return generic_fmod(f32, x, y);
107}
108export fn fmod(x: f64, y: f64) f64 {
109 return generic_fmod(f64, x, y);
110}
106111
107// TODO add intrinsics for these (and probably the double version too)112// TODO add intrinsics for these (and probably the double version too)
108// and have the math stuff use the intrinsic. same as @mod and @rem113// and have the math stuff use the intrinsic. same as @mod and @rem
109export fn floorf(x: f32) f32 { return math.floor(x); }114export fn floorf(x: f32) f32 {
110export fn ceilf(x: f32) f32 { return math.ceil(x); }115 return math.floor(x);
111export fn floor(x: f64) f64 { return math.floor(x); }116}
112export fn ceil(x: f64) f64 { return math.ceil(x); }117export fn ceilf(x: f32) f32 {
118 return math.ceil(x);
119}
120export fn floor(x: f64) f64 {
121 return math.floor(x);
122}
123export fn ceil(x: f64) f64 {
124 return math.ceil(x);
125}
113126
114fn generic_fmod(comptime T: type, x: T, y: T) T {127fn generic_fmod(comptime T: type, x: T, y: T) T {
115 @setRuntimeSafety(false);128 @setRuntimeSafety(false);
...@@ -139,7 +152,10 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -139,7 +152,10 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
139 // normalize x and y152 // normalize x and y
140 if (ex == 0) {153 if (ex == 0) {
141 i = ux << exp_bits;154 i = ux << exp_bits;
142 while (i >> bits_minus_1 == 0) : (b: {ex -= 1; break :b i <<= 1;}) {}155 while (i >> bits_minus_1 == 0) : (b: {
156 ex -= 1;
157 i <<= 1;
158 }) {}
143 ux <<= log2uint(@bitCast(u32, -ex + 1));159 ux <<= log2uint(@bitCast(u32, -ex + 1));
144 } else {160 } else {
145 ux &= @maxValue(uint) >> exp_bits;161 ux &= @maxValue(uint) >> exp_bits;
...@@ -147,7 +163,10 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -147,7 +163,10 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
147 }163 }
148 if (ey == 0) {164 if (ey == 0) {
149 i = uy << exp_bits;165 i = uy << exp_bits;
150 while (i >> bits_minus_1 == 0) : (b: {ey -= 1; break :b i <<= 1;}) {}166 while (i >> bits_minus_1 == 0) : (b: {
167 ey -= 1;
168 i <<= 1;
169 }) {}
151 uy <<= log2uint(@bitCast(u32, -ey + 1));170 uy <<= log2uint(@bitCast(u32, -ey + 1));
152 } else {171 } else {
153 uy &= @maxValue(uint) >> exp_bits;172 uy &= @maxValue(uint) >> exp_bits;
...@@ -170,7 +189,10 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -170,7 +189,10 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
170 return 0 * x;189 return 0 * x;
171 ux = i;190 ux = i;
172 }191 }
173 while (ux >> digits == 0) : (b: {ux <<= 1; break :b ex -= 1;}) {}192 while (ux >> digits == 0) : (b: {
193 ux <<= 1;
194 ex -= 1;
195 }) {}
174196
175 // scale result up197 // scale result up
176 if (ex > 0) {198 if (ex > 0) {
...@@ -298,7 +320,7 @@ export fn sqrt(x: f64) f64 {...@@ -298,7 +320,7 @@ export fn sqrt(x: f64) f64 {
298320
299 // rounding direction321 // rounding direction
300 if (ix0 | ix1 != 0) {322 if (ix0 | ix1 != 0) {
301 var z = 1.0 - tiny; // raise inexact323 var z = 1.0 - tiny; // raise inexact
302 if (z >= 1.0) {324 if (z >= 1.0) {
303 z = 1.0 + tiny;325 z = 1.0 + tiny;
304 if (q1 == 0xFFFFFFFF) {326 if (q1 == 0xFFFFFFFF) {
...@@ -336,13 +358,13 @@ export fn sqrtf(x: f32) f32 {...@@ -336,13 +358,13 @@ export fn sqrtf(x: f32) f32 {
336 var ix: i32 = @bitCast(i32, x);358 var ix: i32 = @bitCast(i32, x);
337359
338 if ((ix & 0x7F800000) == 0x7F800000) {360 if ((ix & 0x7F800000) == 0x7F800000) {
339 return x * x + x; // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = snan361 return x * x + x; // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = snan
340 }362 }
341363
342 // zero364 // zero
343 if (ix <= 0) {365 if (ix <= 0) {
344 if (ix & ~sign == 0) {366 if (ix & ~sign == 0) {
345 return x; // sqrt (+-0) = +-0367 return x; // sqrt (+-0) = +-0
346 }368 }
347 if (ix < 0) {369 if (ix < 0) {
348 return math.snan(f32);370 return math.snan(f32);
...@@ -360,20 +382,20 @@ export fn sqrtf(x: f32) f32 {...@@ -360,20 +382,20 @@ export fn sqrtf(x: f32) f32 {
360 m -= i - 1;382 m -= i - 1;
361 }383 }
362384
363 m -= 127; // unbias exponent385 m -= 127; // unbias exponent
364 ix = (ix & 0x007FFFFF) | 0x00800000;386 ix = (ix & 0x007FFFFF) | 0x00800000;
365387
366 if (m & 1 != 0) { // odd m, double x to even388 if (m & 1 != 0) { // odd m, double x to even
367 ix += ix;389 ix += ix;
368 }390 }
369391
370 m >>= 1; // m = [m / 2]392 m >>= 1; // m = [m / 2]
371393
372 // sqrt(x) bit by bit394 // sqrt(x) bit by bit
373 ix += ix;395 ix += ix;
374 var q: i32 = 0; // q = sqrt(x)396 var q: i32 = 0; // q = sqrt(x)
375 var s: i32 = 0;397 var s: i32 = 0;
376 var r: i32 = 0x01000000; // r = moving bit right -> left398 var r: i32 = 0x01000000; // r = moving bit right -> left
377399
378 while (r != 0) {400 while (r != 0) {
379 const t = s + r;401 const t = s + r;
...@@ -388,7 +410,7 @@ export fn sqrtf(x: f32) f32 {...@@ -388,7 +410,7 @@ export fn sqrtf(x: f32) f32 {
388410
389 // floating add to find rounding direction411 // floating add to find rounding direction
390 if (ix != 0) {412 if (ix != 0) {
391 var z = 1.0 - tiny; // inexact413 var z = 1.0 - tiny; // inexact
392 if (z >= 1.0) {414 if (z >= 1.0) {
393 z = 1.0 + tiny;415 z = 1.0 + tiny;
394 if (z > 1.0) {416 if (z > 1.0) {
std/special/compiler_rt/comparetf2.zig+27-34
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1// TODO https://github.com/zig-lang/zig/issues/3051// TODO https://github.com/ziglang/zig/issues/305
2// and then make the return types of some of these functions the enum instead of c_int2// and then make the return types of some of these functions the enum instead of c_int
3const LE_LESS = c_int(-1);3const LE_LESS = c_int(-1);
4const LE_EQUAL = c_int(0);4const LE_EQUAL = c_int(0);
...@@ -38,28 +38,25 @@ pub extern fn __letf2(a: f128, b: f128) c_int {...@@ -38,28 +38,25 @@ pub extern fn __letf2(a: f128, b: f128) c_int {
3838
39 // If at least one of a and b is positive, we get the same result comparing39 // If at least one of a and b is positive, we get the same result comparing
40 // a and b as signed integers as we would with a floating-point compare.40 // a and b as signed integers as we would with a floating-point compare.
41 return if ((aInt & bInt) >= 0)41 return if ((aInt & bInt) >= 0) if (aInt < bInt)
42 if (aInt < bInt)42 LE_LESS
43 LE_LESS43 else if (aInt == bInt)
44 else if (aInt == bInt)44 LE_EQUAL
45 LE_EQUAL
46 else
47 LE_GREATER
48 else45 else
49 // Otherwise, both are negative, so we need to flip the sense of the46 LE_GREATER else
50 // comparison to get the correct result. (This assumes a twos- or ones-47 // Otherwise, both are negative, so we need to flip the sense of the
51 // complement integer representation; if integers are represented in a48 // comparison to get the correct result. (This assumes a twos- or ones-
52 // sign-magnitude representation, then this flip is incorrect).49 // complement integer representation; if integers are represented in a
53 if (aInt > bInt)50 // sign-magnitude representation, then this flip is incorrect).
54 LE_LESS51 if (aInt > bInt)
55 else if (aInt == bInt)52 LE_LESS
56 LE_EQUAL53 else if (aInt == bInt)
57 else54 LE_EQUAL
58 LE_GREATER55 else
59 ;56 LE_GREATER;
60}57}
6158
62// TODO https://github.com/zig-lang/zig/issues/30559// TODO https://github.com/ziglang/zig/issues/305
63// and then make the return types of some of these functions the enum instead of c_int60// and then make the return types of some of these functions the enum instead of c_int
64const GE_LESS = c_int(-1);61const GE_LESS = c_int(-1);
65const GE_EQUAL = c_int(0);62const GE_EQUAL = c_int(0);
...@@ -76,21 +73,17 @@ pub extern fn __getf2(a: f128, b: f128) c_int {...@@ -76,21 +73,17 @@ pub extern fn __getf2(a: f128, b: f128) c_int {
7673
77 if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;74 if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;
78 if ((aAbs | bAbs) == 0) return GE_EQUAL;75 if ((aAbs | bAbs) == 0) return GE_EQUAL;
79 return if ((aInt & bInt) >= 0)76 return if ((aInt & bInt) >= 0) if (aInt < bInt)
80 if (aInt < bInt)77 GE_LESS
81 GE_LESS78 else if (aInt == bInt)
82 else if (aInt == bInt)79 GE_EQUAL
83 GE_EQUAL80 else
84 else81 GE_GREATER else if (aInt > bInt)
85 GE_GREATER82 GE_LESS
83 else if (aInt == bInt)
84 GE_EQUAL
86 else85 else
87 if (aInt > bInt)86 GE_GREATER;
88 GE_LESS
89 else if (aInt == bInt)
90 GE_EQUAL
91 else
92 GE_GREATER
93 ;
94}87}
9588
96pub extern fn __unordtf2(a: f128, b: f128) c_int {89pub extern fn __unordtf2(a: f128, b: f128) c_int {
std/special/compiler_rt/fixuint.zig+2-4
...@@ -36,12 +36,10 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t...@@ -36,12 +36,10 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
36 const significand: rep_t = (aAbs & significandMask) | implicitBit;36 const significand: rep_t = (aAbs & significandMask) | implicitBit;
3737
38 // If either the value or the exponent is negative, the result is zero.38 // If either the value or the exponent is negative, the result is zero.
39 if (sign == -1 or exponent < 0)39 if (sign == -1 or exponent < 0) return 0;
40 return 0;
4140
42 // If the value is too large for the integer type, saturate.41 // If the value is too large for the integer type, saturate.
43 if (c_uint(exponent) >= fixuint_t.bit_count)42 if (c_uint(exponent) >= fixuint_t.bit_count) return ~fixuint_t(0);
44 return ~fixuint_t(0);
4543
46 // If 0 <= exponent < significandBits, right shift to get the result.44 // If 0 <= exponent < significandBits, right shift to get the result.
47 // Otherwise, shift left.45 // Otherwise, shift left.
std/special/compiler_rt/fixunsdfdi.zig-1
...@@ -9,4 +9,3 @@ pub extern fn __fixunsdfdi(a: f64) u64 {...@@ -9,4 +9,3 @@ pub extern fn __fixunsdfdi(a: f64) u64 {
9test "import fixunsdfdi" {9test "import fixunsdfdi" {
10 _ = @import("fixunsdfdi_test.zig");10 _ = @import("fixunsdfdi_test.zig");
11}11}
12
std/special/compiler_rt/fixunsdfsi.zig-1
...@@ -9,4 +9,3 @@ pub extern fn __fixunsdfsi(a: f64) u32 {...@@ -9,4 +9,3 @@ pub extern fn __fixunsdfsi(a: f64) u32 {
9test "import fixunsdfsi" {9test "import fixunsdfsi" {
10 _ = @import("fixunsdfsi_test.zig");10 _ = @import("fixunsdfsi_test.zig");
11}11}
12
std/special/compiler_rt/fixunsdfti_test.zig-1
...@@ -44,4 +44,3 @@ test "fixunsdfti" {...@@ -44,4 +44,3 @@ test "fixunsdfti" {
44 test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0);44 test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0);
45 test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0);45 test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0);
46}46}
47
std/special/compiler_rt/fixunssfti.zig-1
...@@ -9,4 +9,3 @@ pub extern fn __fixunssfti(a: f32) u128 {...@@ -9,4 +9,3 @@ pub extern fn __fixunssfti(a: f32) u128 {
9test "import fixunssfti" {9test "import fixunssfti" {
10 _ = @import("fixunssfti_test.zig");10 _ = @import("fixunssfti_test.zig");
11}11}
12
std/special/compiler_rt/fixunstfti.zig-1
...@@ -9,4 +9,3 @@ pub extern fn __fixunstfti(a: f128) u128 {...@@ -9,4 +9,3 @@ pub extern fn __fixunstfti(a: f128) u128 {
9test "import fixunstfti" {9test "import fixunstfti" {
10 _ = @import("fixunstfti_test.zig");10 _ = @import("fixunstfti_test.zig");
11}11}
12
std/special/compiler_rt/index.zig+680-146
...@@ -92,9 +92,10 @@ pub fn setXmm0(comptime T: type, value: T) void {...@@ -92,9 +92,10 @@ pub fn setXmm0(comptime T: type, value: T) void {
92 const aligned_value: T align(16) = value;92 const aligned_value: T align(16) = value;
93 asm volatile (93 asm volatile (
94 \\movaps (%[ptr]), %%xmm094 \\movaps (%[ptr]), %%xmm0
95 :95 :
96 : [ptr] "r" (&aligned_value)96 : [ptr] "r" (&aligned_value)
97 : "xmm0");97 : "xmm0"
98 );
98}99}
99100
100extern fn __udivdi3(a: u64, b: u64) u64 {101extern fn __udivdi3(a: u64, b: u64) u64 {
...@@ -158,7 +159,8 @@ fn isArmArch() bool {...@@ -158,7 +159,8 @@ fn isArmArch() bool {
158 builtin.Arch.armebv6t2,159 builtin.Arch.armebv6t2,
159 builtin.Arch.armebv5,160 builtin.Arch.armebv5,
160 builtin.Arch.armebv5te,161 builtin.Arch.armebv5te,
161 builtin.Arch.armebv4t => true,162 builtin.Arch.armebv4t,
163 => true,
162 else => false,164 else => false,
163 };165 };
164}166}
...@@ -173,7 +175,10 @@ nakedcc fn __aeabi_uidivmod() void {...@@ -173,7 +175,10 @@ nakedcc fn __aeabi_uidivmod() void {
173 \\ ldr r1, [sp]175 \\ ldr r1, [sp]
174 \\ add sp, sp, #4176 \\ add sp, sp, #4
175 \\ pop { pc }177 \\ pop { pc }
176 ::: "r2", "r1");178 :
179 :
180 : "r2", "r1"
181 );
177}182}
178183
179// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,184// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,
...@@ -283,26 +288,27 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) u32 {...@@ -283,26 +288,27 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) u32 {
283 @setRuntimeSafety(is_test);288 @setRuntimeSafety(is_test);
284289
285 const d = __udivsi3(a, b);290 const d = __udivsi3(a, b);
286 *rem = u32(i32(a) -% (i32(d) * i32(b)));291 rem.* = u32(i32(a) -% (i32(d) * i32(b)));
287 return d;292 return d;
288}293}
289294
290
291extern fn __udivsi3(n: u32, d: u32) u32 {295extern fn __udivsi3(n: u32, d: u32) u32 {
292 @setRuntimeSafety(is_test);296 @setRuntimeSafety(is_test);
293297
294 const n_uword_bits: c_uint = u32.bit_count;298 const n_uword_bits: c_uint = u32.bit_count;
295 // special cases299 // special cases
296 if (d == 0)300 if (d == 0) return 0; // ?!
297 return 0; // ?!301 if (n == 0) return 0;
298 if (n == 0)
299 return 0;
300 var sr = @bitCast(c_uint, c_int(@clz(d)) - c_int(@clz(n)));302 var sr = @bitCast(c_uint, c_int(@clz(d)) - c_int(@clz(n)));
301 // 0 <= sr <= n_uword_bits - 1 or sr large303 // 0 <= sr <= n_uword_bits - 1 or sr large
302 if (sr > n_uword_bits - 1) // d > r304 if (sr > n_uword_bits - 1) {
305 // d > r
303 return 0;306 return 0;
304 if (sr == n_uword_bits - 1) // d == 1307 }
308 if (sr == n_uword_bits - 1) {
309 // d == 1
305 return n;310 return n;
311 }
306 sr += 1;312 sr += 1;
307 // 1 <= sr <= n_uword_bits - 1313 // 1 <= sr <= n_uword_bits - 1
308 // Not a special case314 // Not a special case
...@@ -341,139 +347,667 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) void {...@@ -341,139 +347,667 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) void {
341}347}
342348
343test "test_udivsi3" {349test "test_udivsi3" {
344 const cases = [][3]u32 {350 const cases = [][3]u32{
345 []u32{0x00000000, 0x00000001, 0x00000000},351 []u32{
346 []u32{0x00000000, 0x00000002, 0x00000000},352 0x00000000,
347 []u32{0x00000000, 0x00000003, 0x00000000},353 0x00000001,
348 []u32{0x00000000, 0x00000010, 0x00000000},354 0x00000000,
349 []u32{0x00000000, 0x078644FA, 0x00000000},355 },
350 []u32{0x00000000, 0x0747AE14, 0x00000000},356 []u32{
351 []u32{0x00000000, 0x7FFFFFFF, 0x00000000},357 0x00000000,
352 []u32{0x00000000, 0x80000000, 0x00000000},358 0x00000002,
353 []u32{0x00000000, 0xFFFFFFFD, 0x00000000},359 0x00000000,
354 []u32{0x00000000, 0xFFFFFFFE, 0x00000000},360 },
355 []u32{0x00000000, 0xFFFFFFFF, 0x00000000},361 []u32{
356 []u32{0x00000001, 0x00000001, 0x00000001},362 0x00000000,
357 []u32{0x00000001, 0x00000002, 0x00000000},363 0x00000003,
358 []u32{0x00000001, 0x00000003, 0x00000000},364 0x00000000,
359 []u32{0x00000001, 0x00000010, 0x00000000},365 },
360 []u32{0x00000001, 0x078644FA, 0x00000000},366 []u32{
361 []u32{0x00000001, 0x0747AE14, 0x00000000},367 0x00000000,
362 []u32{0x00000001, 0x7FFFFFFF, 0x00000000},368 0x00000010,
363 []u32{0x00000001, 0x80000000, 0x00000000},369 0x00000000,
364 []u32{0x00000001, 0xFFFFFFFD, 0x00000000},370 },
365 []u32{0x00000001, 0xFFFFFFFE, 0x00000000},371 []u32{
366 []u32{0x00000001, 0xFFFFFFFF, 0x00000000},372 0x00000000,
367 []u32{0x00000002, 0x00000001, 0x00000002},373 0x078644FA,
368 []u32{0x00000002, 0x00000002, 0x00000001},374 0x00000000,
369 []u32{0x00000002, 0x00000003, 0x00000000},375 },
370 []u32{0x00000002, 0x00000010, 0x00000000},376 []u32{
371 []u32{0x00000002, 0x078644FA, 0x00000000},377 0x00000000,
372 []u32{0x00000002, 0x0747AE14, 0x00000000},378 0x0747AE14,
373 []u32{0x00000002, 0x7FFFFFFF, 0x00000000},379 0x00000000,
374 []u32{0x00000002, 0x80000000, 0x00000000},380 },
375 []u32{0x00000002, 0xFFFFFFFD, 0x00000000},381 []u32{
376 []u32{0x00000002, 0xFFFFFFFE, 0x00000000},382 0x00000000,
377 []u32{0x00000002, 0xFFFFFFFF, 0x00000000},383 0x7FFFFFFF,
378 []u32{0x00000003, 0x00000001, 0x00000003},384 0x00000000,
379 []u32{0x00000003, 0x00000002, 0x00000001},385 },
380 []u32{0x00000003, 0x00000003, 0x00000001},386 []u32{
381 []u32{0x00000003, 0x00000010, 0x00000000},387 0x00000000,
382 []u32{0x00000003, 0x078644FA, 0x00000000},388 0x80000000,
383 []u32{0x00000003, 0x0747AE14, 0x00000000},389 0x00000000,
384 []u32{0x00000003, 0x7FFFFFFF, 0x00000000},390 },
385 []u32{0x00000003, 0x80000000, 0x00000000},391 []u32{
386 []u32{0x00000003, 0xFFFFFFFD, 0x00000000},392 0x00000000,
387 []u32{0x00000003, 0xFFFFFFFE, 0x00000000},393 0xFFFFFFFD,
388 []u32{0x00000003, 0xFFFFFFFF, 0x00000000},394 0x00000000,
389 []u32{0x00000010, 0x00000001, 0x00000010},395 },
390 []u32{0x00000010, 0x00000002, 0x00000008},396 []u32{
391 []u32{0x00000010, 0x00000003, 0x00000005},397 0x00000000,
392 []u32{0x00000010, 0x00000010, 0x00000001},398 0xFFFFFFFE,
393 []u32{0x00000010, 0x078644FA, 0x00000000},399 0x00000000,
394 []u32{0x00000010, 0x0747AE14, 0x00000000},400 },
395 []u32{0x00000010, 0x7FFFFFFF, 0x00000000},401 []u32{
396 []u32{0x00000010, 0x80000000, 0x00000000},402 0x00000000,
397 []u32{0x00000010, 0xFFFFFFFD, 0x00000000},403 0xFFFFFFFF,
398 []u32{0x00000010, 0xFFFFFFFE, 0x00000000},404 0x00000000,
399 []u32{0x00000010, 0xFFFFFFFF, 0x00000000},405 },
400 []u32{0x078644FA, 0x00000001, 0x078644FA},406 []u32{
401 []u32{0x078644FA, 0x00000002, 0x03C3227D},407 0x00000001,
402 []u32{0x078644FA, 0x00000003, 0x028216FE},408 0x00000001,
403 []u32{0x078644FA, 0x00000010, 0x0078644F},409 0x00000001,
404 []u32{0x078644FA, 0x078644FA, 0x00000001},410 },
405 []u32{0x078644FA, 0x0747AE14, 0x00000001},411 []u32{
406 []u32{0x078644FA, 0x7FFFFFFF, 0x00000000},412 0x00000001,
407 []u32{0x078644FA, 0x80000000, 0x00000000},413 0x00000002,
408 []u32{0x078644FA, 0xFFFFFFFD, 0x00000000},414 0x00000000,
409 []u32{0x078644FA, 0xFFFFFFFE, 0x00000000},415 },
410 []u32{0x078644FA, 0xFFFFFFFF, 0x00000000},416 []u32{
411 []u32{0x0747AE14, 0x00000001, 0x0747AE14},417 0x00000001,
412 []u32{0x0747AE14, 0x00000002, 0x03A3D70A},418 0x00000003,
413 []u32{0x0747AE14, 0x00000003, 0x026D3A06},419 0x00000000,
414 []u32{0x0747AE14, 0x00000010, 0x00747AE1},420 },
415 []u32{0x0747AE14, 0x078644FA, 0x00000000},421 []u32{
416 []u32{0x0747AE14, 0x0747AE14, 0x00000001},422 0x00000001,
417 []u32{0x0747AE14, 0x7FFFFFFF, 0x00000000},423 0x00000010,
418 []u32{0x0747AE14, 0x80000000, 0x00000000},424 0x00000000,
419 []u32{0x0747AE14, 0xFFFFFFFD, 0x00000000},425 },
420 []u32{0x0747AE14, 0xFFFFFFFE, 0x00000000},426 []u32{
421 []u32{0x0747AE14, 0xFFFFFFFF, 0x00000000},427 0x00000001,
422 []u32{0x7FFFFFFF, 0x00000001, 0x7FFFFFFF},428 0x078644FA,
423 []u32{0x7FFFFFFF, 0x00000002, 0x3FFFFFFF},429 0x00000000,
424 []u32{0x7FFFFFFF, 0x00000003, 0x2AAAAAAA},430 },
425 []u32{0x7FFFFFFF, 0x00000010, 0x07FFFFFF},431 []u32{
426 []u32{0x7FFFFFFF, 0x078644FA, 0x00000011},432 0x00000001,
427 []u32{0x7FFFFFFF, 0x0747AE14, 0x00000011},433 0x0747AE14,
428 []u32{0x7FFFFFFF, 0x7FFFFFFF, 0x00000001},434 0x00000000,
429 []u32{0x7FFFFFFF, 0x80000000, 0x00000000},435 },
430 []u32{0x7FFFFFFF, 0xFFFFFFFD, 0x00000000},436 []u32{
431 []u32{0x7FFFFFFF, 0xFFFFFFFE, 0x00000000},437 0x00000001,
432 []u32{0x7FFFFFFF, 0xFFFFFFFF, 0x00000000},438 0x7FFFFFFF,
433 []u32{0x80000000, 0x00000001, 0x80000000},439 0x00000000,
434 []u32{0x80000000, 0x00000002, 0x40000000},440 },
435 []u32{0x80000000, 0x00000003, 0x2AAAAAAA},441 []u32{
436 []u32{0x80000000, 0x00000010, 0x08000000},442 0x00000001,
437 []u32{0x80000000, 0x078644FA, 0x00000011},443 0x80000000,
438 []u32{0x80000000, 0x0747AE14, 0x00000011},444 0x00000000,
439 []u32{0x80000000, 0x7FFFFFFF, 0x00000001},445 },
440 []u32{0x80000000, 0x80000000, 0x00000001},446 []u32{
441 []u32{0x80000000, 0xFFFFFFFD, 0x00000000},447 0x00000001,
442 []u32{0x80000000, 0xFFFFFFFE, 0x00000000},448 0xFFFFFFFD,
443 []u32{0x80000000, 0xFFFFFFFF, 0x00000000},449 0x00000000,
444 []u32{0xFFFFFFFD, 0x00000001, 0xFFFFFFFD},450 },
445 []u32{0xFFFFFFFD, 0x00000002, 0x7FFFFFFE},451 []u32{
446 []u32{0xFFFFFFFD, 0x00000003, 0x55555554},452 0x00000001,
447 []u32{0xFFFFFFFD, 0x00000010, 0x0FFFFFFF},453 0xFFFFFFFE,
448 []u32{0xFFFFFFFD, 0x078644FA, 0x00000022},454 0x00000000,
449 []u32{0xFFFFFFFD, 0x0747AE14, 0x00000023},455 },
450 []u32{0xFFFFFFFD, 0x7FFFFFFF, 0x00000001},456 []u32{
451 []u32{0xFFFFFFFD, 0x80000000, 0x00000001},457 0x00000001,
452 []u32{0xFFFFFFFD, 0xFFFFFFFD, 0x00000001},458 0xFFFFFFFF,
453 []u32{0xFFFFFFFD, 0xFFFFFFFE, 0x00000000},459 0x00000000,
454 []u32{0xFFFFFFFD, 0xFFFFFFFF, 0x00000000},460 },
455 []u32{0xFFFFFFFE, 0x00000001, 0xFFFFFFFE},461 []u32{
456 []u32{0xFFFFFFFE, 0x00000002, 0x7FFFFFFF},462 0x00000002,
457 []u32{0xFFFFFFFE, 0x00000003, 0x55555554},463 0x00000001,
458 []u32{0xFFFFFFFE, 0x00000010, 0x0FFFFFFF},464 0x00000002,
459 []u32{0xFFFFFFFE, 0x078644FA, 0x00000022},465 },
460 []u32{0xFFFFFFFE, 0x0747AE14, 0x00000023},466 []u32{
461 []u32{0xFFFFFFFE, 0x7FFFFFFF, 0x00000002},467 0x00000002,
462 []u32{0xFFFFFFFE, 0x80000000, 0x00000001},468 0x00000002,
463 []u32{0xFFFFFFFE, 0xFFFFFFFD, 0x00000001},469 0x00000001,
464 []u32{0xFFFFFFFE, 0xFFFFFFFE, 0x00000001},470 },
465 []u32{0xFFFFFFFE, 0xFFFFFFFF, 0x00000000},471 []u32{
466 []u32{0xFFFFFFFF, 0x00000001, 0xFFFFFFFF},472 0x00000002,
467 []u32{0xFFFFFFFF, 0x00000002, 0x7FFFFFFF},473 0x00000003,
468 []u32{0xFFFFFFFF, 0x00000003, 0x55555555},474 0x00000000,
469 []u32{0xFFFFFFFF, 0x00000010, 0x0FFFFFFF},475 },
470 []u32{0xFFFFFFFF, 0x078644FA, 0x00000022},476 []u32{
471 []u32{0xFFFFFFFF, 0x0747AE14, 0x00000023},477 0x00000002,
472 []u32{0xFFFFFFFF, 0x7FFFFFFF, 0x00000002},478 0x00000010,
473 []u32{0xFFFFFFFF, 0x80000000, 0x00000001},479 0x00000000,
474 []u32{0xFFFFFFFF, 0xFFFFFFFD, 0x00000001},480 },
475 []u32{0xFFFFFFFF, 0xFFFFFFFE, 0x00000001},481 []u32{
476 []u32{0xFFFFFFFF, 0xFFFFFFFF, 0x00000001},482 0x00000002,
483 0x078644FA,
484 0x00000000,
485 },
486 []u32{
487 0x00000002,
488 0x0747AE14,
489 0x00000000,
490 },
491 []u32{
492 0x00000002,
493 0x7FFFFFFF,
494 0x00000000,
495 },
496 []u32{
497 0x00000002,
498 0x80000000,
499 0x00000000,
500 },
501 []u32{
502 0x00000002,
503 0xFFFFFFFD,
504 0x00000000,
505 },
506 []u32{
507 0x00000002,
508 0xFFFFFFFE,
509 0x00000000,
510 },
511 []u32{
512 0x00000002,
513 0xFFFFFFFF,
514 0x00000000,
515 },
516 []u32{
517 0x00000003,
518 0x00000001,
519 0x00000003,
520 },
521 []u32{
522 0x00000003,
523 0x00000002,
524 0x00000001,
525 },
526 []u32{
527 0x00000003,
528 0x00000003,
529 0x00000001,
530 },
531 []u32{
532 0x00000003,
533 0x00000010,
534 0x00000000,
535 },
536 []u32{
537 0x00000003,
538 0x078644FA,
539 0x00000000,
540 },
541 []u32{
542 0x00000003,
543 0x0747AE14,
544 0x00000000,
545 },
546 []u32{
547 0x00000003,
548 0x7FFFFFFF,
549 0x00000000,
550 },
551 []u32{
552 0x00000003,
553 0x80000000,
554 0x00000000,
555 },
556 []u32{
557 0x00000003,
558 0xFFFFFFFD,
559 0x00000000,
560 },
561 []u32{
562 0x00000003,
563 0xFFFFFFFE,
564 0x00000000,
565 },
566 []u32{
567 0x00000003,
568 0xFFFFFFFF,
569 0x00000000,
570 },
571 []u32{
572 0x00000010,
573 0x00000001,
574 0x00000010,
575 },
576 []u32{
577 0x00000010,
578 0x00000002,
579 0x00000008,
580 },
581 []u32{
582 0x00000010,
583 0x00000003,
584 0x00000005,
585 },
586 []u32{
587 0x00000010,
588 0x00000010,
589 0x00000001,
590 },
591 []u32{
592 0x00000010,
593 0x078644FA,
594 0x00000000,
595 },
596 []u32{
597 0x00000010,
598 0x0747AE14,
599 0x00000000,
600 },
601 []u32{
602 0x00000010,
603 0x7FFFFFFF,
604 0x00000000,
605 },
606 []u32{
607 0x00000010,
608 0x80000000,
609 0x00000000,
610 },
611 []u32{
612 0x00000010,
613 0xFFFFFFFD,
614 0x00000000,
615 },
616 []u32{
617 0x00000010,
618 0xFFFFFFFE,
619 0x00000000,
620 },
621 []u32{
622 0x00000010,
623 0xFFFFFFFF,
624 0x00000000,
625 },
626 []u32{
627 0x078644FA,
628 0x00000001,
629 0x078644FA,
630 },
631 []u32{
632 0x078644FA,
633 0x00000002,
634 0x03C3227D,
635 },
636 []u32{
637 0x078644FA,
638 0x00000003,
639 0x028216FE,
640 },
641 []u32{
642 0x078644FA,
643 0x00000010,
644 0x0078644F,
645 },
646 []u32{
647 0x078644FA,
648 0x078644FA,
649 0x00000001,
650 },
651 []u32{
652 0x078644FA,
653 0x0747AE14,
654 0x00000001,
655 },
656 []u32{
657 0x078644FA,
658 0x7FFFFFFF,
659 0x00000000,
660 },
661 []u32{
662 0x078644FA,
663 0x80000000,
664 0x00000000,
665 },
666 []u32{
667 0x078644FA,
668 0xFFFFFFFD,
669 0x00000000,
670 },
671 []u32{
672 0x078644FA,
673 0xFFFFFFFE,
674 0x00000000,
675 },
676 []u32{
677 0x078644FA,
678 0xFFFFFFFF,
679 0x00000000,
680 },
681 []u32{
682 0x0747AE14,
683 0x00000001,
684 0x0747AE14,
685 },
686 []u32{
687 0x0747AE14,
688 0x00000002,
689 0x03A3D70A,
690 },
691 []u32{
692 0x0747AE14,
693 0x00000003,
694 0x026D3A06,
695 },
696 []u32{
697 0x0747AE14,
698 0x00000010,
699 0x00747AE1,
700 },
701 []u32{
702 0x0747AE14,
703 0x078644FA,
704 0x00000000,
705 },
706 []u32{
707 0x0747AE14,
708 0x0747AE14,
709 0x00000001,
710 },
711 []u32{
712 0x0747AE14,
713 0x7FFFFFFF,
714 0x00000000,
715 },
716 []u32{
717 0x0747AE14,
718 0x80000000,
719 0x00000000,
720 },
721 []u32{
722 0x0747AE14,
723 0xFFFFFFFD,
724 0x00000000,
725 },
726 []u32{
727 0x0747AE14,
728 0xFFFFFFFE,
729 0x00000000,
730 },
731 []u32{
732 0x0747AE14,
733 0xFFFFFFFF,
734 0x00000000,
735 },
736 []u32{
737 0x7FFFFFFF,
738 0x00000001,
739 0x7FFFFFFF,
740 },
741 []u32{
742 0x7FFFFFFF,
743 0x00000002,
744 0x3FFFFFFF,
745 },
746 []u32{
747 0x7FFFFFFF,
748 0x00000003,
749 0x2AAAAAAA,
750 },
751 []u32{
752 0x7FFFFFFF,
753 0x00000010,
754 0x07FFFFFF,
755 },
756 []u32{
757 0x7FFFFFFF,
758 0x078644FA,
759 0x00000011,
760 },
761 []u32{
762 0x7FFFFFFF,
763 0x0747AE14,
764 0x00000011,
765 },
766 []u32{
767 0x7FFFFFFF,
768 0x7FFFFFFF,
769 0x00000001,
770 },
771 []u32{
772 0x7FFFFFFF,
773 0x80000000,
774 0x00000000,
775 },
776 []u32{
777 0x7FFFFFFF,
778 0xFFFFFFFD,
779 0x00000000,
780 },
781 []u32{
782 0x7FFFFFFF,
783 0xFFFFFFFE,
784 0x00000000,
785 },
786 []u32{
787 0x7FFFFFFF,
788 0xFFFFFFFF,
789 0x00000000,
790 },
791 []u32{
792 0x80000000,
793 0x00000001,
794 0x80000000,
795 },
796 []u32{
797 0x80000000,
798 0x00000002,
799 0x40000000,
800 },
801 []u32{
802 0x80000000,
803 0x00000003,
804 0x2AAAAAAA,
805 },
806 []u32{
807 0x80000000,
808 0x00000010,
809 0x08000000,
810 },
811 []u32{
812 0x80000000,
813 0x078644FA,
814 0x00000011,
815 },
816 []u32{
817 0x80000000,
818 0x0747AE14,
819 0x00000011,
820 },
821 []u32{
822 0x80000000,
823 0x7FFFFFFF,
824 0x00000001,
825 },
826 []u32{
827 0x80000000,
828 0x80000000,
829 0x00000001,
830 },
831 []u32{
832 0x80000000,
833 0xFFFFFFFD,
834 0x00000000,
835 },
836 []u32{
837 0x80000000,
838 0xFFFFFFFE,
839 0x00000000,
840 },
841 []u32{
842 0x80000000,
843 0xFFFFFFFF,
844 0x00000000,
845 },
846 []u32{
847 0xFFFFFFFD,
848 0x00000001,
849 0xFFFFFFFD,
850 },
851 []u32{
852 0xFFFFFFFD,
853 0x00000002,
854 0x7FFFFFFE,
855 },
856 []u32{
857 0xFFFFFFFD,
858 0x00000003,
859 0x55555554,
860 },
861 []u32{
862 0xFFFFFFFD,
863 0x00000010,
864 0x0FFFFFFF,
865 },
866 []u32{
867 0xFFFFFFFD,
868 0x078644FA,
869 0x00000022,
870 },
871 []u32{
872 0xFFFFFFFD,
873 0x0747AE14,
874 0x00000023,
875 },
876 []u32{
877 0xFFFFFFFD,
878 0x7FFFFFFF,
879 0x00000001,
880 },
881 []u32{
882 0xFFFFFFFD,
883 0x80000000,
884 0x00000001,
885 },
886 []u32{
887 0xFFFFFFFD,
888 0xFFFFFFFD,
889 0x00000001,
890 },
891 []u32{
892 0xFFFFFFFD,
893 0xFFFFFFFE,
894 0x00000000,
895 },
896 []u32{
897 0xFFFFFFFD,
898 0xFFFFFFFF,
899 0x00000000,
900 },
901 []u32{
902 0xFFFFFFFE,
903 0x00000001,
904 0xFFFFFFFE,
905 },
906 []u32{
907 0xFFFFFFFE,
908 0x00000002,
909 0x7FFFFFFF,
910 },
911 []u32{
912 0xFFFFFFFE,
913 0x00000003,
914 0x55555554,
915 },
916 []u32{
917 0xFFFFFFFE,
918 0x00000010,
919 0x0FFFFFFF,
920 },
921 []u32{
922 0xFFFFFFFE,
923 0x078644FA,
924 0x00000022,
925 },
926 []u32{
927 0xFFFFFFFE,
928 0x0747AE14,
929 0x00000023,
930 },
931 []u32{
932 0xFFFFFFFE,
933 0x7FFFFFFF,
934 0x00000002,
935 },
936 []u32{
937 0xFFFFFFFE,
938 0x80000000,
939 0x00000001,
940 },
941 []u32{
942 0xFFFFFFFE,
943 0xFFFFFFFD,
944 0x00000001,
945 },
946 []u32{
947 0xFFFFFFFE,
948 0xFFFFFFFE,
949 0x00000001,
950 },
951 []u32{
952 0xFFFFFFFE,
953 0xFFFFFFFF,
954 0x00000000,
955 },
956 []u32{
957 0xFFFFFFFF,
958 0x00000001,
959 0xFFFFFFFF,
960 },
961 []u32{
962 0xFFFFFFFF,
963 0x00000002,
964 0x7FFFFFFF,
965 },
966 []u32{
967 0xFFFFFFFF,
968 0x00000003,
969 0x55555555,
970 },
971 []u32{
972 0xFFFFFFFF,
973 0x00000010,
974 0x0FFFFFFF,
975 },
976 []u32{
977 0xFFFFFFFF,
978 0x078644FA,
979 0x00000022,
980 },
981 []u32{
982 0xFFFFFFFF,
983 0x0747AE14,
984 0x00000023,
985 },
986 []u32{
987 0xFFFFFFFF,
988 0x7FFFFFFF,
989 0x00000002,
990 },
991 []u32{
992 0xFFFFFFFF,
993 0x80000000,
994 0x00000001,
995 },
996 []u32{
997 0xFFFFFFFF,
998 0xFFFFFFFD,
999 0x00000001,
1000 },
1001 []u32{
1002 0xFFFFFFFF,
1003 0xFFFFFFFE,
1004 0x00000001,
1005 },
1006 []u32{
1007 0xFFFFFFFF,
1008 0xFFFFFFFF,
1009 0x00000001,
1010 },
477 };1011 };
4781012
479 for (cases) |case| {1013 for (cases) |case| {
std/special/compiler_rt/udivmod.zig+23-20
...@@ -1,7 +1,10 @@...@@ -1,7 +1,10 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const is_test = builtin.is_test;2const is_test = builtin.is_test;
33
4const low = switch (builtin.endian) { builtin.Endian.Big => 1, builtin.Endian.Little => 0 };4const low = switch (builtin.endian) {
5 builtin.Endian.Big => 1,
6 builtin.Endian.Little => 0,
7};
5const high = 1 - low;8const high = 1 - low;
69
7pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?&DoubleInt) DoubleInt {10pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?&DoubleInt) DoubleInt {
...@@ -11,8 +14,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -11,8 +14,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
11 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);14 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);
12 const Log2SingleInt = @import("std").math.Log2Int(SingleInt);15 const Log2SingleInt = @import("std").math.Log2Int(SingleInt);
1316
14 const n = *@ptrCast(&const [2]SingleInt, &a); // TODO issue #42117 const n = @ptrCast(&const [2]SingleInt, &a).*; // TODO issue #421
15 const d = *@ptrCast(&const [2]SingleInt, &b); // TODO issue #42118 const d = @ptrCast(&const [2]SingleInt, &b).*; // TODO issue #421
16 var q: [2]SingleInt = undefined;19 var q: [2]SingleInt = undefined;
17 var r: [2]SingleInt = undefined;20 var r: [2]SingleInt = undefined;
18 var sr: c_uint = undefined;21 var sr: c_uint = undefined;
...@@ -23,7 +26,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -23,7 +26,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
23 // ---26 // ---
24 // 0 X27 // 0 X
25 if (maybe_rem) |rem| {28 if (maybe_rem) |rem| {
26 *rem = n[low] % d[low];29 rem.* = n[low] % d[low];
27 }30 }
28 return n[low] / d[low];31 return n[low] / d[low];
29 }32 }
...@@ -31,7 +34,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -31,7 +34,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
31 // ---34 // ---
32 // K X35 // K X
33 if (maybe_rem) |rem| {36 if (maybe_rem) |rem| {
34 *rem = n[low];37 rem.* = n[low];
35 }38 }
36 return 0;39 return 0;
37 }40 }
...@@ -42,7 +45,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -42,7 +45,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
42 // ---45 // ---
43 // 0 046 // 0 0
44 if (maybe_rem) |rem| {47 if (maybe_rem) |rem| {
45 *rem = n[high] % d[low];48 rem.* = n[high] % d[low];
46 }49 }
47 return n[high] / d[low];50 return n[high] / d[low];
48 }51 }
...@@ -54,7 +57,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -54,7 +57,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
54 if (maybe_rem) |rem| {57 if (maybe_rem) |rem| {
55 r[high] = n[high] % d[high];58 r[high] = n[high] % d[high];
56 r[low] = 0;59 r[low] = 0;
57 *rem = *@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &r[0]); // TODO issue #42160 rem.* = @ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421
58 }61 }
59 return n[high] / d[high];62 return n[high] / d[high];
60 }63 }
...@@ -66,7 +69,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -66,7 +69,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
66 if (maybe_rem) |rem| {69 if (maybe_rem) |rem| {
67 r[low] = n[low];70 r[low] = n[low];
68 r[high] = n[high] & (d[high] - 1);71 r[high] = n[high] & (d[high] - 1);
69 *rem = *@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &r[0]); // TODO issue #42172 rem.* = @ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421
70 }73 }
71 return n[high] >> Log2SingleInt(@ctz(d[high]));74 return n[high] >> Log2SingleInt(@ctz(d[high]));
72 }75 }
...@@ -77,7 +80,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -77,7 +80,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
77 // 0 <= sr <= SingleInt.bit_count - 2 or sr large80 // 0 <= sr <= SingleInt.bit_count - 2 or sr large
78 if (sr > SingleInt.bit_count - 2) {81 if (sr > SingleInt.bit_count - 2) {
79 if (maybe_rem) |rem| {82 if (maybe_rem) |rem| {
80 *rem = a;83 rem.* = a;
81 }84 }
82 return 0;85 return 0;
83 }86 }
...@@ -98,7 +101,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -98,7 +101,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
98 if ((d[low] & (d[low] - 1)) == 0) {101 if ((d[low] & (d[low] - 1)) == 0) {
99 // d is a power of 2102 // d is a power of 2
100 if (maybe_rem) |rem| {103 if (maybe_rem) |rem| {
101 *rem = n[low] & (d[low] - 1);104 rem.* = n[low] & (d[low] - 1);
102 }105 }
103 if (d[low] == 1) {106 if (d[low] == 1) {
104 return a;107 return a;
...@@ -106,7 +109,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -106,7 +109,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
106 sr = @ctz(d[low]);109 sr = @ctz(d[low]);
107 q[high] = n[high] >> Log2SingleInt(sr);110 q[high] = n[high] >> Log2SingleInt(sr);
108 q[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr));111 q[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr));
109 return *@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &q[0]); // TODO issue #421112 return @ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421
110 }113 }
111 // K X114 // K X
112 // ---115 // ---
...@@ -141,7 +144,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -141,7 +144,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
141 // 0 <= sr <= SingleInt.bit_count - 1 or sr large144 // 0 <= sr <= SingleInt.bit_count - 1 or sr large
142 if (sr > SingleInt.bit_count - 1) {145 if (sr > SingleInt.bit_count - 1) {
143 if (maybe_rem) |rem| {146 if (maybe_rem) |rem| {
144 *rem = a;147 rem.* = a;
145 }148 }
146 return 0;149 return 0;
147 }150 }
...@@ -170,25 +173,25 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -170,25 +173,25 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
170 var r_all: DoubleInt = undefined;173 var r_all: DoubleInt = undefined;
171 while (sr > 0) : (sr -= 1) {174 while (sr > 0) : (sr -= 1) {
172 // r:q = ((r:q) << 1) | carry175 // r:q = ((r:q) << 1) | carry
173 r[high] = (r[high] << 1) | (r[low] >> (SingleInt.bit_count - 1));176 r[high] = (r[high] << 1) | (r[low] >> (SingleInt.bit_count - 1));
174 r[low] = (r[low] << 1) | (q[high] >> (SingleInt.bit_count - 1));177 r[low] = (r[low] << 1) | (q[high] >> (SingleInt.bit_count - 1));
175 q[high] = (q[high] << 1) | (q[low] >> (SingleInt.bit_count - 1));178 q[high] = (q[high] << 1) | (q[low] >> (SingleInt.bit_count - 1));
176 q[low] = (q[low] << 1) | carry;179 q[low] = (q[low] << 1) | carry;
177 // carry = 0;180 // carry = 0;
178 // if (r.all >= b)181 // if (r.all >= b)
179 // {182 // {
180 // r.all -= b;183 // r.all -= b;
181 // carry = 1;184 // carry = 1;
182 // }185 // }
183 r_all = *@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &r[0]); // TODO issue #421186 r_all = @ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421
184 const s: SignedDoubleInt = SignedDoubleInt(b -% r_all -% 1) >> (DoubleInt.bit_count - 1);187 const s: SignedDoubleInt = SignedDoubleInt(b -% r_all -% 1) >> (DoubleInt.bit_count - 1);
185 carry = u32(s & 1);188 carry = u32(s & 1);
186 r_all -= b & @bitCast(DoubleInt, s);189 r_all -= b & @bitCast(DoubleInt, s);
187 r = *@ptrCast(&[2]SingleInt, &r_all); // TODO issue #421190 r = @ptrCast(&[2]SingleInt, &r_all).*; // TODO issue #421
188 }191 }
189 const q_all = ((*@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &q[0])) << 1) | carry; // TODO issue #421192 const q_all = ((@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &q[0]).*) << 1) | carry; // TODO issue #421
190 if (maybe_rem) |rem| {193 if (maybe_rem) |rem| {
191 *rem = r_all;194 rem.* = r_all;
192 }195 }
193 return q_all;196 return q_all;
194}197}
std/special/compiler_rt/udivmodti4.zig+1-1
...@@ -9,7 +9,7 @@ pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) u128 {...@@ -9,7 +9,7 @@ pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) u128 {
99
10pub extern fn __udivmodti4_windows_x86_64(a: &const u128, b: &const u128, maybe_rem: ?&u128) void {10pub extern fn __udivmodti4_windows_x86_64(a: &const u128, b: &const u128, maybe_rem: ?&u128) void {
11 @setRuntimeSafety(builtin.is_test);11 @setRuntimeSafety(builtin.is_test);
12 compiler_rt.setXmm0(u128, udivmod(u128, *a, *b, maybe_rem));12 compiler_rt.setXmm0(u128, udivmod(u128, a.*, b.*, maybe_rem));
13}13}
1414
15test "import udivmodti4" {15test "import udivmodti4" {
std/special/compiler_rt/umodti3.zig+1-1
...@@ -11,5 +11,5 @@ pub extern fn __umodti3(a: u128, b: u128) u128 {...@@ -11,5 +11,5 @@ pub extern fn __umodti3(a: u128, b: u128) u128 {
1111
12pub extern fn __umodti3_windows_x86_64(a: &const u128, b: &const u128) void {12pub extern fn __umodti3_windows_x86_64(a: &const u128, b: &const u128) void {
13 @setRuntimeSafety(builtin.is_test);13 @setRuntimeSafety(builtin.is_test);
14 compiler_rt.setXmm0(u128, __umodti3(*a, *b));14 compiler_rt.setXmm0(u128, __umodti3(a.*, b.*));
15}15}
std/unicode.zig+13-9
...@@ -58,6 +58,7 @@ pub fn utf8Encode(c: u32, out: []u8) !u3 {...@@ -58,6 +58,7 @@ pub fn utf8Encode(c: u32, out: []u8) !u3 {
58}58}
5959
60const Utf8DecodeError = Utf8Decode2Error || Utf8Decode3Error || Utf8Decode4Error;60const Utf8DecodeError = Utf8Decode2Error || Utf8Decode3Error || Utf8Decode4Error;
61
61/// Decodes the UTF-8 codepoint encoded in the given slice of bytes.62/// Decodes the UTF-8 codepoint encoded in the given slice of bytes.
62/// bytes.len must be equal to utf8ByteSequenceLength(bytes[0]) catch unreachable.63/// bytes.len must be equal to utf8ByteSequenceLength(bytes[0]) catch unreachable.
63/// If you already know the length at comptime, you can call one of64/// If you already know the length at comptime, you can call one of
...@@ -150,7 +151,9 @@ pub fn utf8ValidateSlice(s: []const u8) bool {...@@ -150,7 +151,9 @@ pub fn utf8ValidateSlice(s: []const u8) bool {
150 return false;151 return false;
151 }152 }
152153
153 if (utf8Decode(s[i..i+cp_len])) |_| {} else |_| { return false; }154 if (utf8Decode(s[i..i + cp_len])) |_| {} else |_| {
155 return false;
156 }
154 i += cp_len;157 i += cp_len;
155 } else |err| {158 } else |err| {
156 return false;159 return false;
...@@ -179,9 +182,7 @@ pub const Utf8View = struct {...@@ -179,9 +182,7 @@ pub const Utf8View = struct {
179 }182 }
180183
181 pub fn initUnchecked(s: []const u8) Utf8View {184 pub fn initUnchecked(s: []const u8) Utf8View {
182 return Utf8View {185 return Utf8View{ .bytes = s };
183 .bytes = s,
184 };
185 }186 }
186187
187 pub fn initComptime(comptime s: []const u8) Utf8View {188 pub fn initComptime(comptime s: []const u8) Utf8View {
...@@ -191,12 +192,12 @@ pub const Utf8View = struct {...@@ -191,12 +192,12 @@ pub const Utf8View = struct {
191 error.InvalidUtf8 => {192 error.InvalidUtf8 => {
192 @compileError("invalid utf8");193 @compileError("invalid utf8");
193 unreachable;194 unreachable;
194 }195 },
195 }196 }
196 }197 }
197198
198 pub fn iterator(s: &const Utf8View) Utf8Iterator {199 pub fn iterator(s: &const Utf8View) Utf8Iterator {
199 return Utf8Iterator {200 return Utf8Iterator{
200 .bytes = s.bytes,201 .bytes = s.bytes,
201 .i = 0,202 .i = 0,
202 };203 };
...@@ -215,7 +216,7 @@ const Utf8Iterator = struct {...@@ -215,7 +216,7 @@ const Utf8Iterator = struct {
215 const cp_len = utf8ByteSequenceLength(it.bytes[it.i]) catch unreachable;216 const cp_len = utf8ByteSequenceLength(it.bytes[it.i]) catch unreachable;
216217
217 it.i += cp_len;218 it.i += cp_len;
218 return it.bytes[it.i-cp_len..it.i];219 return it.bytes[it.i - cp_len..it.i];
219 }220 }
220221
221 pub fn nextCodepoint(it: &Utf8Iterator) ?u32 {222 pub fn nextCodepoint(it: &Utf8Iterator) ?u32 {
...@@ -304,9 +305,12 @@ test "utf8 view bad" {...@@ -304,9 +305,12 @@ test "utf8 view bad" {
304fn testUtf8ViewBad() void {305fn testUtf8ViewBad() void {
305 // Compile-time error.306 // Compile-time error.
306 // const s3 = Utf8View.initComptime("\xfe\xf2");307 // const s3 = Utf8View.initComptime("\xfe\xf2");
307
308 const s = Utf8View.init("hel\xadlo");308 const s = Utf8View.init("hel\xadlo");
309 if (s) |_| { unreachable; } else |err| { debug.assert(err == error.InvalidUtf8); }309 if (s) |_| {
310 unreachable;
311 } else |err| {
312 debug.assert(err == error.InvalidUtf8);
313 }
310}314}
311315
312test "utf8 view ok" {316test "utf8 view ok" {
std/zig/ast.zig+147-116
...@@ -40,7 +40,7 @@ pub const Tree = struct {...@@ -40,7 +40,7 @@ pub const Tree = struct {
40 };40 };
4141
42 pub fn tokenLocationPtr(self: &Tree, start_index: usize, token: &const Token) Location {42 pub fn tokenLocationPtr(self: &Tree, start_index: usize, token: &const Token) Location {
43 var loc = Location {43 var loc = Location{
44 .line = 0,44 .line = 0,
45 .column = 0,45 .column = 0,
46 .line_start = start_index,46 .line_start = start_index,
...@@ -67,6 +67,36 @@ pub const Tree = struct {...@@ -67,6 +67,36 @@ pub const Tree = struct {
67 pub fn tokenLocation(self: &Tree, start_index: usize, token_index: TokenIndex) Location {67 pub fn tokenLocation(self: &Tree, start_index: usize, token_index: TokenIndex) Location {
68 return self.tokenLocationPtr(start_index, self.tokens.at(token_index));68 return self.tokenLocationPtr(start_index, self.tokens.at(token_index));
69 }69 }
70
71 pub fn tokensOnSameLine(self: &Tree, token1_index: TokenIndex, token2_index: TokenIndex) bool {
72 return self.tokensOnSameLinePtr(self.tokens.at(token1_index), self.tokens.at(token2_index));
73 }
74
75 pub fn tokensOnSameLinePtr(self: &Tree, token1: &const Token, token2: &const Token) bool {
76 return mem.indexOfScalar(u8, self.source[token1.end..token2.start], '\n') == null;
77 }
78
79 pub fn dump(self: &Tree) void {
80 self.root_node.base.dump(0);
81 }
82
83 /// Skips over comments
84 pub fn prevToken(self: &Tree, token_index: TokenIndex) TokenIndex {
85 var index = token_index - 1;
86 while (self.tokens.at(index).id == Token.Id.LineComment) {
87 index -= 1;
88 }
89 return index;
90 }
91
92 /// Skips over comments
93 pub fn nextToken(self: &Tree, token_index: TokenIndex) TokenIndex {
94 var index = token_index + 1;
95 while (self.tokens.at(index).id == Token.Id.LineComment) {
96 index += 1;
97 }
98 return index;
99 }
70};100};
71101
72pub const Error = union(enum) {102pub const Error = union(enum) {
...@@ -76,6 +106,7 @@ pub const Error = union(enum) {...@@ -76,6 +106,7 @@ pub const Error = union(enum) {
76 UnattachedDocComment: UnattachedDocComment,106 UnattachedDocComment: UnattachedDocComment,
77 ExpectedEqOrSemi: ExpectedEqOrSemi,107 ExpectedEqOrSemi: ExpectedEqOrSemi,
78 ExpectedSemiOrLBrace: ExpectedSemiOrLBrace,108 ExpectedSemiOrLBrace: ExpectedSemiOrLBrace,
109 ExpectedColonOrRParen: ExpectedColonOrRParen,
79 ExpectedLabelable: ExpectedLabelable,110 ExpectedLabelable: ExpectedLabelable,
80 ExpectedInlinable: ExpectedInlinable,111 ExpectedInlinable: ExpectedInlinable,
81 ExpectedAsmOutputReturnOrType: ExpectedAsmOutputReturnOrType,112 ExpectedAsmOutputReturnOrType: ExpectedAsmOutputReturnOrType,
...@@ -90,14 +121,15 @@ pub const Error = union(enum) {...@@ -90,14 +121,15 @@ pub const Error = union(enum) {
90 ExpectedCommaOrEnd: ExpectedCommaOrEnd,121 ExpectedCommaOrEnd: ExpectedCommaOrEnd,
91122
92 pub fn render(self: &Error, tokens: &Tree.TokenList, stream: var) !void {123 pub fn render(self: &Error, tokens: &Tree.TokenList, stream: var) !void {
93 switch (*self) {124 switch (self.*) {
94 // TODO https://github.com/zig-lang/zig/issues/683125 // TODO https://github.com/ziglang/zig/issues/683
95 @TagType(Error).InvalidToken => |*x| return x.render(tokens, stream),126 @TagType(Error).InvalidToken => |*x| return x.render(tokens, stream),
96 @TagType(Error).ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),127 @TagType(Error).ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),
97 @TagType(Error).ExpectedAggregateKw => |*x| return x.render(tokens, stream),128 @TagType(Error).ExpectedAggregateKw => |*x| return x.render(tokens, stream),
98 @TagType(Error).UnattachedDocComment => |*x| return x.render(tokens, stream),129 @TagType(Error).UnattachedDocComment => |*x| return x.render(tokens, stream),
99 @TagType(Error).ExpectedEqOrSemi => |*x| return x.render(tokens, stream),130 @TagType(Error).ExpectedEqOrSemi => |*x| return x.render(tokens, stream),
100 @TagType(Error).ExpectedSemiOrLBrace => |*x| return x.render(tokens, stream),131 @TagType(Error).ExpectedSemiOrLBrace => |*x| return x.render(tokens, stream),
132 @TagType(Error).ExpectedColonOrRParen => |*x| return x.render(tokens, stream),
101 @TagType(Error).ExpectedLabelable => |*x| return x.render(tokens, stream),133 @TagType(Error).ExpectedLabelable => |*x| return x.render(tokens, stream),
102 @TagType(Error).ExpectedInlinable => |*x| return x.render(tokens, stream),134 @TagType(Error).ExpectedInlinable => |*x| return x.render(tokens, stream),
103 @TagType(Error).ExpectedAsmOutputReturnOrType => |*x| return x.render(tokens, stream),135 @TagType(Error).ExpectedAsmOutputReturnOrType => |*x| return x.render(tokens, stream),
...@@ -114,14 +146,15 @@ pub const Error = union(enum) {...@@ -114,14 +146,15 @@ pub const Error = union(enum) {
114 }146 }
115147
116 pub fn loc(self: &Error) TokenIndex {148 pub fn loc(self: &Error) TokenIndex {
117 switch (*self) {149 switch (self.*) {
118 // TODO https://github.com/zig-lang/zig/issues/683150 // TODO https://github.com/ziglang/zig/issues/683
119 @TagType(Error).InvalidToken => |x| return x.token,151 @TagType(Error).InvalidToken => |x| return x.token,
120 @TagType(Error).ExpectedVarDeclOrFn => |x| return x.token,152 @TagType(Error).ExpectedVarDeclOrFn => |x| return x.token,
121 @TagType(Error).ExpectedAggregateKw => |x| return x.token,153 @TagType(Error).ExpectedAggregateKw => |x| return x.token,
122 @TagType(Error).UnattachedDocComment => |x| return x.token,154 @TagType(Error).UnattachedDocComment => |x| return x.token,
123 @TagType(Error).ExpectedEqOrSemi => |x| return x.token,155 @TagType(Error).ExpectedEqOrSemi => |x| return x.token,
124 @TagType(Error).ExpectedSemiOrLBrace => |x| return x.token,156 @TagType(Error).ExpectedSemiOrLBrace => |x| return x.token,
157 @TagType(Error).ExpectedColonOrRParen => |x| return x.token,
125 @TagType(Error).ExpectedLabelable => |x| return x.token,158 @TagType(Error).ExpectedLabelable => |x| return x.token,
126 @TagType(Error).ExpectedInlinable => |x| return x.token,159 @TagType(Error).ExpectedInlinable => |x| return x.token,
127 @TagType(Error).ExpectedAsmOutputReturnOrType => |x| return x.token,160 @TagType(Error).ExpectedAsmOutputReturnOrType => |x| return x.token,
...@@ -139,15 +172,13 @@ pub const Error = union(enum) {...@@ -139,15 +172,13 @@ pub const Error = union(enum) {
139172
140 pub const InvalidToken = SingleTokenError("Invalid token {}");173 pub const InvalidToken = SingleTokenError("Invalid token {}");
141 pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found {}");174 pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found {}");
142 pub const ExpectedAggregateKw = SingleTokenError("Expected " ++175 pub const ExpectedAggregateKw = SingleTokenError("Expected " ++ @tagName(Token.Id.Keyword_struct) ++ ", " ++ @tagName(Token.Id.Keyword_union) ++ ", or " ++ @tagName(Token.Id.Keyword_enum) ++ ", found {}");
143 @tagName(Token.Id.Keyword_struct) ++ ", " ++ @tagName(Token.Id.Keyword_union) ++ ", or " ++
144 @tagName(Token.Id.Keyword_enum) ++ ", found {}");
145 pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found {}");176 pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found {}");
146 pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found {}");177 pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found {}");
178 pub const ExpectedColonOrRParen = SingleTokenError("Expected ':' or ')', found {}");
147 pub const ExpectedLabelable = SingleTokenError("Expected 'while', 'for', 'inline', 'suspend', or '{{', found {}");179 pub const ExpectedLabelable = SingleTokenError("Expected 'while', 'for', 'inline', 'suspend', or '{{', found {}");
148 pub const ExpectedInlinable = SingleTokenError("Expected 'while' or 'for', found {}");180 pub const ExpectedInlinable = SingleTokenError("Expected 'while' or 'for', found {}");
149 pub const ExpectedAsmOutputReturnOrType = SingleTokenError("Expected '->' or " ++181 pub const ExpectedAsmOutputReturnOrType = SingleTokenError("Expected '->' or " ++ @tagName(Token.Id.Identifier) ++ ", found {}");
150 @tagName(Token.Id.Identifier) ++ ", found {}");
151 pub const ExpectedSliceOrRBracket = SingleTokenError("Expected ']' or '..', found {}");182 pub const ExpectedSliceOrRBracket = SingleTokenError("Expected ']' or '..', found {}");
152 pub const ExpectedPrimaryExpr = SingleTokenError("Expected primary expression, found {}");183 pub const ExpectedPrimaryExpr = SingleTokenError("Expected primary expression, found {}");
153184
...@@ -160,8 +191,7 @@ pub const Error = union(enum) {...@@ -160,8 +191,7 @@ pub const Error = union(enum) {
160 node: &Node,191 node: &Node,
161192
162 pub fn render(self: &ExpectedCall, tokens: &Tree.TokenList, stream: var) !void {193 pub fn render(self: &ExpectedCall, tokens: &Tree.TokenList, stream: var) !void {
163 return stream.print("expected " ++ @tagName(@TagType(Node.SuffixOp.Op).Call) ++ ", found {}",194 return stream.print("expected " ++ @tagName(@TagType(Node.SuffixOp.Op).Call) ++ ", found {}", @tagName(self.node.id));
164 @tagName(self.node.id));
165 }195 }
166 };196 };
167197
...@@ -169,8 +199,7 @@ pub const Error = union(enum) {...@@ -169,8 +199,7 @@ pub const Error = union(enum) {
169 node: &Node,199 node: &Node,
170200
171 pub fn render(self: &ExpectedCallOrFnProto, tokens: &Tree.TokenList, stream: var) !void {201 pub fn render(self: &ExpectedCallOrFnProto, tokens: &Tree.TokenList, stream: var) !void {
172 return stream.print("expected " ++ @tagName(@TagType(Node.SuffixOp.Op).Call) ++ " or " ++202 return stream.print("expected " ++ @tagName(@TagType(Node.SuffixOp.Op).Call) ++ " or " ++ @tagName(Node.Id.FnProto) ++ ", found {}", @tagName(self.node.id));
173 @tagName(Node.Id.FnProto) ++ ", found {}", @tagName(self.node.id));
174 }203 }
175 };204 };
176205
...@@ -273,7 +302,6 @@ pub const Node = struct {...@@ -273,7 +302,6 @@ pub const Node = struct {
273 Block,302 Block,
274303
275 // Misc304 // Misc
276 LineComment,
277 DocComment,305 DocComment,
278 SwitchCase,306 SwitchCase,
279 SwitchElse,307 SwitchElse,
...@@ -360,8 +388,8 @@ pub const Node = struct {...@@ -360,8 +388,8 @@ pub const Node = struct {
360 Id.SwitchElse,388 Id.SwitchElse,
361 Id.FieldInitializer,389 Id.FieldInitializer,
362 Id.DocComment,390 Id.DocComment,
363 Id.LineComment,391 Id.TestDecl,
364 Id.TestDecl => return false,392 => return false,
365 Id.While => {393 Id.While => {
366 const while_node = @fieldParentPtr(While, "base", n);394 const while_node = @fieldParentPtr(While, "base", n);
367 if (while_node.@"else") |@"else"| {395 if (while_node.@"else") |@"else"| {
...@@ -415,6 +443,20 @@ pub const Node = struct {...@@ -415,6 +443,20 @@ pub const Node = struct {
415 }443 }
416 }444 }
417445
446 pub fn dump(self: &Node, indent: usize) void {
447 {
448 var i: usize = 0;
449 while (i < indent) : (i += 1) {
450 std.debug.warn(" ");
451 }
452 }
453 std.debug.warn("{}\n", @tagName(self.id));
454
455 var child_i: usize = 0;
456 while (self.iterate(child_i)) |child| : (child_i += 1) {
457 child.dump(indent + 2);
458 }
459 }
418460
419 pub const Root = struct {461 pub const Root = struct {
420 base: Node,462 base: Node,
...@@ -426,17 +468,17 @@ pub const Node = struct {...@@ -426,17 +468,17 @@ pub const Node = struct {
426468
427 pub fn iterate(self: &Root, index: usize) ?&Node {469 pub fn iterate(self: &Root, index: usize) ?&Node {
428 if (index < self.decls.len) {470 if (index < self.decls.len) {
429 return self.decls.items[self.decls.len - index - 1];471 return self.decls.at(index).*;
430 }472 }
431 return null;473 return null;
432 }474 }
433475
434 pub fn firstToken(self: &Root) TokenIndex {476 pub fn firstToken(self: &Root) TokenIndex {
435 return if (self.decls.len == 0) self.eof_token else (*self.decls.at(0)).firstToken();477 return if (self.decls.len == 0) self.eof_token else (self.decls.at(0).*).firstToken();
436 }478 }
437479
438 pub fn lastToken(self: &Root) TokenIndex {480 pub fn lastToken(self: &Root) TokenIndex {
439 return if (self.decls.len == 0) self.eof_token else (*self.decls.at(self.decls.len - 1)).lastToken();481 return if (self.decls.len == 0) self.eof_token else (self.decls.at(self.decls.len - 1).*).lastToken();
440 }482 }
441 };483 };
442484
...@@ -493,6 +535,7 @@ pub const Node = struct {...@@ -493,6 +535,7 @@ pub const Node = struct {
493 base: Node,535 base: Node,
494 doc_comments: ?&DocComment,536 doc_comments: ?&DocComment,
495 visib_token: ?TokenIndex,537 visib_token: ?TokenIndex,
538 use_token: TokenIndex,
496 expr: &Node,539 expr: &Node,
497 semicolon_token: TokenIndex,540 semicolon_token: TokenIndex,
498541
...@@ -507,7 +550,7 @@ pub const Node = struct {...@@ -507,7 +550,7 @@ pub const Node = struct {
507550
508 pub fn firstToken(self: &Use) TokenIndex {551 pub fn firstToken(self: &Use) TokenIndex {
509 if (self.visib_token) |visib_token| return visib_token;552 if (self.visib_token) |visib_token| return visib_token;
510 return self.expr.firstToken();553 return self.use_token;
511 }554 }
512555
513 pub fn lastToken(self: &Use) TokenIndex {556 pub fn lastToken(self: &Use) TokenIndex {
...@@ -526,7 +569,7 @@ pub const Node = struct {...@@ -526,7 +569,7 @@ pub const Node = struct {
526 pub fn iterate(self: &ErrorSetDecl, index: usize) ?&Node {569 pub fn iterate(self: &ErrorSetDecl, index: usize) ?&Node {
527 var i = index;570 var i = index;
528571
529 if (i < self.decls.len) return *self.decls.at(i);572 if (i < self.decls.len) return self.decls.at(i).*;
530 i -= self.decls.len;573 i -= self.decls.len;
531574
532 return null;575 return null;
...@@ -543,27 +586,15 @@ pub const Node = struct {...@@ -543,27 +586,15 @@ pub const Node = struct {
543586
544 pub const ContainerDecl = struct {587 pub const ContainerDecl = struct {
545 base: Node,588 base: Node,
546 ltoken: TokenIndex,589 layout_token: ?TokenIndex,
547 layout: Layout,590 kind_token: TokenIndex,
548 kind: Kind,
549 init_arg_expr: InitArg,591 init_arg_expr: InitArg,
550 fields_and_decls: DeclList,592 fields_and_decls: DeclList,
593 lbrace_token: TokenIndex,
551 rbrace_token: TokenIndex,594 rbrace_token: TokenIndex,
552595
553 pub const DeclList = Root.DeclList;596 pub const DeclList = Root.DeclList;
554597
555 const Layout = enum {
556 Auto,
557 Extern,
558 Packed,
559 };
560
561 const Kind = enum {
562 Struct,
563 Enum,
564 Union,
565 };
566
567 const InitArg = union(enum) {598 const InitArg = union(enum) {
568 None,599 None,
569 Enum: ?&Node,600 Enum: ?&Node,
...@@ -578,18 +609,20 @@ pub const Node = struct {...@@ -578,18 +609,20 @@ pub const Node = struct {
578 if (i < 1) return t;609 if (i < 1) return t;
579 i -= 1;610 i -= 1;
580 },611 },
581 InitArg.None,612 InitArg.None, InitArg.Enum => {},
582 InitArg.Enum => { }
583 }613 }
584614
585 if (i < self.fields_and_decls.len) return *self.fields_and_decls.at(i);615 if (i < self.fields_and_decls.len) return self.fields_and_decls.at(i).*;
586 i -= self.fields_and_decls.len;616 i -= self.fields_and_decls.len;
587617
588 return null;618 return null;
589 }619 }
590620
591 pub fn firstToken(self: &ContainerDecl) TokenIndex {621 pub fn firstToken(self: &ContainerDecl) TokenIndex {
592 return self.ltoken;622 if (self.layout_token) |layout_token| {
623 return layout_token;
624 }
625 return self.kind_token;
593 }626 }
594627
595 pub fn lastToken(self: &ContainerDecl) TokenIndex {628 pub fn lastToken(self: &ContainerDecl) TokenIndex {
...@@ -790,8 +823,16 @@ pub const Node = struct {...@@ -790,8 +823,16 @@ pub const Node = struct {
790 pub fn iterate(self: &FnProto, index: usize) ?&Node {823 pub fn iterate(self: &FnProto, index: usize) ?&Node {
791 var i = index;824 var i = index;
792825
793 if (self.body_node) |body_node| {826 if (self.lib_name) |lib_name| {
794 if (i < 1) return body_node;827 if (i < 1) return lib_name;
828 i -= 1;
829 }
830
831 if (i < self.params.len) return self.params.at(self.params.len - i - 1).*;
832 i -= self.params.len;
833
834 if (self.align_expr) |align_expr| {
835 if (i < 1) return align_expr;
795 i -= 1;836 i -= 1;
796 }837 }
797838
...@@ -807,16 +848,8 @@ pub const Node = struct {...@@ -807,16 +848,8 @@ pub const Node = struct {
807 },848 },
808 }849 }
809850
810 if (self.align_expr) |align_expr| {851 if (self.body_node) |body_node| {
811 if (i < 1) return align_expr;852 if (i < 1) return body_node;
812 i -= 1;
813 }
814
815 if (i < self.params.len) return self.params.items[self.params.len - i - 1];
816 i -= self.params.len;
817
818 if (self.lib_name) |lib_name| {
819 if (i < 1) return lib_name;
820 i -= 1;853 i -= 1;
821 }854 }
822855
...@@ -914,7 +947,7 @@ pub const Node = struct {...@@ -914,7 +947,7 @@ pub const Node = struct {
914 pub fn iterate(self: &Block, index: usize) ?&Node {947 pub fn iterate(self: &Block, index: usize) ?&Node {
915 var i = index;948 var i = index;
916949
917 if (i < self.statements.len) return self.statements.items[i];950 if (i < self.statements.len) return self.statements.at(i).*;
918 i -= self.statements.len;951 i -= self.statements.len;
919952
920 return null;953 return null;
...@@ -1099,7 +1132,8 @@ pub const Node = struct {...@@ -1099,7 +1132,8 @@ pub const Node = struct {
1099 base: Node,1132 base: Node,
1100 switch_token: TokenIndex,1133 switch_token: TokenIndex,
1101 expr: &Node,1134 expr: &Node,
1102 /// these can be SwitchCase nodes or LineComment nodes1135
1136 /// these must be SwitchCase nodes
1103 cases: CaseList,1137 cases: CaseList,
1104 rbrace: TokenIndex,1138 rbrace: TokenIndex,
11051139
...@@ -1111,7 +1145,7 @@ pub const Node = struct {...@@ -1111,7 +1145,7 @@ pub const Node = struct {
1111 if (i < 1) return self.expr;1145 if (i < 1) return self.expr;
1112 i -= 1;1146 i -= 1;
11131147
1114 if (i < self.cases.len) return *self.cases.at(i);1148 if (i < self.cases.len) return self.cases.at(i).*;
1115 i -= self.cases.len;1149 i -= self.cases.len;
11161150
1117 return null;1151 return null;
...@@ -1129,6 +1163,7 @@ pub const Node = struct {...@@ -1129,6 +1163,7 @@ pub const Node = struct {
1129 pub const SwitchCase = struct {1163 pub const SwitchCase = struct {
1130 base: Node,1164 base: Node,
1131 items: ItemList,1165 items: ItemList,
1166 arrow_token: TokenIndex,
1132 payload: ?&Node,1167 payload: ?&Node,
1133 expr: &Node,1168 expr: &Node,
11341169
...@@ -1137,7 +1172,7 @@ pub const Node = struct {...@@ -1137,7 +1172,7 @@ pub const Node = struct {
1137 pub fn iterate(self: &SwitchCase, index: usize) ?&Node {1172 pub fn iterate(self: &SwitchCase, index: usize) ?&Node {
1138 var i = index;1173 var i = index;
11391174
1140 if (i < self.items.len) return *self.items.at(i);1175 if (i < self.items.len) return self.items.at(i).*;
1141 i -= self.items.len;1176 i -= self.items.len;
11421177
1143 if (self.payload) |payload| {1178 if (self.payload) |payload| {
...@@ -1152,7 +1187,7 @@ pub const Node = struct {...@@ -1152,7 +1187,7 @@ pub const Node = struct {
1152 }1187 }
11531188
1154 pub fn firstToken(self: &SwitchCase) TokenIndex {1189 pub fn firstToken(self: &SwitchCase) TokenIndex {
1155 return (*self.items.at(0)).firstToken();1190 return (self.items.at(0).*).firstToken();
1156 }1191 }
11571192
1158 pub fn lastToken(self: &SwitchCase) TokenIndex {1193 pub fn lastToken(self: &SwitchCase) TokenIndex {
...@@ -1440,7 +1475,8 @@ pub const Node = struct {...@@ -1440,7 +1475,8 @@ pub const Node = struct {
1440 Op.Range,1475 Op.Range,
1441 Op.Sub,1476 Op.Sub,
1442 Op.SubWrap,1477 Op.SubWrap,
1443 Op.UnwrapMaybe => {},1478 Op.UnwrapMaybe,
1479 => {},
1444 }1480 }
14451481
1446 if (i < 1) return self.rhs;1482 if (i < 1) return self.rhs;
...@@ -1464,14 +1500,14 @@ pub const Node = struct {...@@ -1464,14 +1500,14 @@ pub const Node = struct {
1464 op: Op,1500 op: Op,
1465 rhs: &Node,1501 rhs: &Node,
14661502
1467 const Op = union(enum) {1503 pub const Op = union(enum) {
1468 AddrOf: AddrOfInfo,1504 AddrOf: AddrOfInfo,
1469 ArrayType: &Node,1505 ArrayType: &Node,
1470 Await,1506 Await,
1471 BitNot,1507 BitNot,
1472 BoolNot,1508 BoolNot,
1473 Cancel,1509 Cancel,
1474 Deref,1510 PointerType,
1475 MaybeType,1511 MaybeType,
1476 Negation,1512 Negation,
1477 NegationWrap,1513 NegationWrap,
...@@ -1481,12 +1517,20 @@ pub const Node = struct {...@@ -1481,12 +1517,20 @@ pub const Node = struct {
1481 UnwrapMaybe,1517 UnwrapMaybe,
1482 };1518 };
14831519
1484 const AddrOfInfo = struct {1520 pub const AddrOfInfo = struct {
1485 align_expr: ?&Node,1521 align_info: ?Align,
1486 bit_offset_start_token: ?TokenIndex,
1487 bit_offset_end_token: ?TokenIndex,
1488 const_token: ?TokenIndex,1522 const_token: ?TokenIndex,
1489 volatile_token: ?TokenIndex,1523 volatile_token: ?TokenIndex,
1524
1525 pub const Align = struct {
1526 node: &Node,
1527 bit_range: ?BitRange,
1528
1529 pub const BitRange = struct {
1530 start: &Node,
1531 end: &Node,
1532 };
1533 };
1490 };1534 };
14911535
1492 pub fn iterate(self: &PrefixOp, index: usize) ?&Node {1536 pub fn iterate(self: &PrefixOp, index: usize) ?&Node {
...@@ -1494,14 +1538,14 @@ pub const Node = struct {...@@ -1494,14 +1538,14 @@ pub const Node = struct {
14941538
1495 switch (self.op) {1539 switch (self.op) {
1496 Op.SliceType => |addr_of_info| {1540 Op.SliceType => |addr_of_info| {
1497 if (addr_of_info.align_expr) |align_expr| {1541 if (addr_of_info.align_info) |align_info| {
1498 if (i < 1) return align_expr;1542 if (i < 1) return align_info.node;
1499 i -= 1;1543 i -= 1;
1500 }1544 }
1501 },1545 },
1502 Op.AddrOf => |addr_of_info| {1546 Op.AddrOf => |addr_of_info| {
1503 if (addr_of_info.align_expr) |align_expr| {1547 if (addr_of_info.align_info) |align_info| {
1504 if (i < 1) return align_expr;1548 if (i < 1) return align_info.node;
1505 i -= 1;1549 i -= 1;
1506 }1550 }
1507 },1551 },
...@@ -1513,13 +1557,14 @@ pub const Node = struct {...@@ -1513,13 +1557,14 @@ pub const Node = struct {
1513 Op.BitNot,1557 Op.BitNot,
1514 Op.BoolNot,1558 Op.BoolNot,
1515 Op.Cancel,1559 Op.Cancel,
1516 Op.Deref,
1517 Op.MaybeType,1560 Op.MaybeType,
1518 Op.Negation,1561 Op.Negation,
1519 Op.NegationWrap,1562 Op.NegationWrap,
1520 Op.Try,1563 Op.Try,
1521 Op.Resume,1564 Op.Resume,
1522 Op.UnwrapMaybe => {},1565 Op.UnwrapMaybe,
1566 Op.PointerType,
1567 => {},
1523 }1568 }
15241569
1525 if (i < 1) return self.rhs;1570 if (i < 1) return self.rhs;
...@@ -1573,6 +1618,7 @@ pub const Node = struct {...@@ -1573,6 +1618,7 @@ pub const Node = struct {
1573 Slice: Slice,1618 Slice: Slice,
1574 ArrayInitializer: InitList,1619 ArrayInitializer: InitList,
1575 StructInitializer: InitList,1620 StructInitializer: InitList,
1621 Deref,
15761622
1577 pub const InitList = SegmentedList(&Node, 2);1623 pub const InitList = SegmentedList(&Node, 2);
15781624
...@@ -1596,15 +1642,15 @@ pub const Node = struct {...@@ -1596,15 +1642,15 @@ pub const Node = struct {
1596 i -= 1;1642 i -= 1;
15971643
1598 switch (self.op) {1644 switch (self.op) {
1599 Op.Call => |call_info| {1645 @TagType(Op).Call => |*call_info| {
1600 if (i < call_info.params.len) return *call_info.params.at(i);1646 if (i < call_info.params.len) return call_info.params.at(i).*;
1601 i -= call_info.params.len;1647 i -= call_info.params.len;
1602 },1648 },
1603 Op.ArrayAccess => |index_expr| {1649 Op.ArrayAccess => |index_expr| {
1604 if (i < 1) return index_expr;1650 if (i < 1) return index_expr;
1605 i -= 1;1651 i -= 1;
1606 },1652 },
1607 Op.Slice => |range| {1653 @TagType(Op).Slice => |range| {
1608 if (i < 1) return range.start;1654 if (i < 1) return range.start;
1609 i -= 1;1655 i -= 1;
16101656
...@@ -1613,20 +1659,25 @@ pub const Node = struct {...@@ -1613,20 +1659,25 @@ pub const Node = struct {
1613 i -= 1;1659 i -= 1;
1614 }1660 }
1615 },1661 },
1616 Op.ArrayInitializer => |exprs| {1662 Op.ArrayInitializer => |*exprs| {
1617 if (i < exprs.len) return *exprs.at(i);1663 if (i < exprs.len) return exprs.at(i).*;
1618 i -= exprs.len;1664 i -= exprs.len;
1619 },1665 },
1620 Op.StructInitializer => |fields| {1666 Op.StructInitializer => |*fields| {
1621 if (i < fields.len) return *fields.at(i);1667 if (i < fields.len) return fields.at(i).*;
1622 i -= fields.len;1668 i -= fields.len;
1623 },1669 },
1670 Op.Deref => {},
1624 }1671 }
16251672
1626 return null;1673 return null;
1627 }1674 }
16281675
1629 pub fn firstToken(self: &SuffixOp) TokenIndex {1676 pub fn firstToken(self: &SuffixOp) TokenIndex {
1677 switch (self.op) {
1678 @TagType(Op).Call => |*call_info| if (call_info.async_attr) |async_attr| return async_attr.firstToken(),
1679 else => {},
1680 }
1630 return self.lhs.firstToken();1681 return self.lhs.firstToken();
1631 }1682 }
16321683
...@@ -1811,7 +1862,7 @@ pub const Node = struct {...@@ -1811,7 +1862,7 @@ pub const Node = struct {
1811 pub fn iterate(self: &BuiltinCall, index: usize) ?&Node {1862 pub fn iterate(self: &BuiltinCall, index: usize) ?&Node {
1812 var i = index;1863 var i = index;
18131864
1814 if (i < self.params.len) return *self.params.at(i);1865 if (i < self.params.len) return self.params.at(i).*;
1815 i -= self.params.len;1866 i -= self.params.len;
18161867
1817 return null;1868 return null;
...@@ -1854,11 +1905,11 @@ pub const Node = struct {...@@ -1854,11 +1905,11 @@ pub const Node = struct {
1854 }1905 }
18551906
1856 pub fn firstToken(self: &MultilineStringLiteral) TokenIndex {1907 pub fn firstToken(self: &MultilineStringLiteral) TokenIndex {
1857 return *self.lines.at(0);1908 return self.lines.at(0).*;
1858 }1909 }
18591910
1860 pub fn lastToken(self: &MultilineStringLiteral) TokenIndex {1911 pub fn lastToken(self: &MultilineStringLiteral) TokenIndex {
1861 return *self.lines.at(self.lines.len - 1);1912 return self.lines.at(self.lines.len - 1).*;
1862 }1913 }
1863 };1914 };
18641915
...@@ -1949,13 +2000,15 @@ pub const Node = struct {...@@ -1949,13 +2000,15 @@ pub const Node = struct {
19492000
1950 pub const AsmOutput = struct {2001 pub const AsmOutput = struct {
1951 base: Node,2002 base: Node,
2003 lbracket: TokenIndex,
1952 symbolic_name: &Node,2004 symbolic_name: &Node,
1953 constraint: &Node,2005 constraint: &Node,
1954 kind: Kind,2006 kind: Kind,
2007 rparen: TokenIndex,
19552008
1956 const Kind = union(enum) {2009 const Kind = union(enum) {
1957 Variable: &Identifier,2010 Variable: &Identifier,
1958 Return: &Node2011 Return: &Node,
1959 };2012 };
19602013
1961 pub fn iterate(self: &AsmOutput, index: usize) ?&Node {2014 pub fn iterate(self: &AsmOutput, index: usize) ?&Node {
...@@ -1975,29 +2028,28 @@ pub const Node = struct {...@@ -1975,29 +2028,28 @@ pub const Node = struct {
1975 Kind.Return => |return_type| {2028 Kind.Return => |return_type| {
1976 if (i < 1) return return_type;2029 if (i < 1) return return_type;
1977 i -= 1;2030 i -= 1;
1978 }2031 },
1979 }2032 }
19802033
1981 return null;2034 return null;
1982 }2035 }
19832036
1984 pub fn firstToken(self: &AsmOutput) TokenIndex {2037 pub fn firstToken(self: &AsmOutput) TokenIndex {
1985 return self.symbolic_name.firstToken();2038 return self.lbracket;
1986 }2039 }
19872040
1988 pub fn lastToken(self: &AsmOutput) TokenIndex {2041 pub fn lastToken(self: &AsmOutput) TokenIndex {
1989 return switch (self.kind) {2042 return self.rparen;
1990 Kind.Variable => |variable_name| variable_name.lastToken(),
1991 Kind.Return => |return_type| return_type.lastToken(),
1992 };
1993 }2043 }
1994 };2044 };
19952045
1996 pub const AsmInput = struct {2046 pub const AsmInput = struct {
1997 base: Node,2047 base: Node,
2048 lbracket: TokenIndex,
1998 symbolic_name: &Node,2049 symbolic_name: &Node,
1999 constraint: &Node,2050 constraint: &Node,
2000 expr: &Node,2051 expr: &Node,
2052 rparen: TokenIndex,
20012053
2002 pub fn iterate(self: &AsmInput, index: usize) ?&Node {2054 pub fn iterate(self: &AsmInput, index: usize) ?&Node {
2003 var i = index;2055 var i = index;
...@@ -2015,11 +2067,11 @@ pub const Node = struct {...@@ -2015,11 +2067,11 @@ pub const Node = struct {
2015 }2067 }
20162068
2017 pub fn firstToken(self: &AsmInput) TokenIndex {2069 pub fn firstToken(self: &AsmInput) TokenIndex {
2018 return self.symbolic_name.firstToken();2070 return self.lbracket;
2019 }2071 }
20202072
2021 pub fn lastToken(self: &AsmInput) TokenIndex {2073 pub fn lastToken(self: &AsmInput) TokenIndex {
2022 return self.expr.lastToken();2074 return self.rparen;
2023 }2075 }
2024 };2076 };
20252077
...@@ -2035,20 +2087,17 @@ pub const Node = struct {...@@ -2035,20 +2087,17 @@ pub const Node = struct {
20352087
2036 const OutputList = SegmentedList(&AsmOutput, 2);2088 const OutputList = SegmentedList(&AsmOutput, 2);
2037 const InputList = SegmentedList(&AsmInput, 2);2089 const InputList = SegmentedList(&AsmInput, 2);
2038 const ClobberList = SegmentedList(&Node, 2);2090 const ClobberList = SegmentedList(TokenIndex, 2);
20392091
2040 pub fn iterate(self: &Asm, index: usize) ?&Node {2092 pub fn iterate(self: &Asm, index: usize) ?&Node {
2041 var i = index;2093 var i = index;
20422094
2043 if (i < self.outputs.len) return &(*self.outputs.at(index)).base;2095 if (i < self.outputs.len) return &(self.outputs.at(index).*).base;
2044 i -= self.outputs.len;2096 i -= self.outputs.len;
20452097
2046 if (i < self.inputs.len) return &(*self.inputs.at(index)).base;2098 if (i < self.inputs.len) return &(self.inputs.at(index).*).base;
2047 i -= self.inputs.len;2099 i -= self.inputs.len;
20482100
2049 if (i < self.clobbers.len) return *self.clobbers.at(index);
2050 i -= self.clobbers.len;
2051
2052 return null;2101 return null;
2053 }2102 }
20542103
...@@ -2112,23 +2161,6 @@ pub const Node = struct {...@@ -2112,23 +2161,6 @@ pub const Node = struct {
2112 }2161 }
2113 };2162 };
21142163
2115 pub const LineComment = struct {
2116 base: Node,
2117 token: TokenIndex,
2118
2119 pub fn iterate(self: &LineComment, index: usize) ?&Node {
2120 return null;
2121 }
2122
2123 pub fn firstToken(self: &LineComment) TokenIndex {
2124 return self.token;
2125 }
2126
2127 pub fn lastToken(self: &LineComment) TokenIndex {
2128 return self.token;
2129 }
2130 };
2131
2132 pub const DocComment = struct {2164 pub const DocComment = struct {
2133 base: Node,2165 base: Node,
2134 lines: LineList,2166 lines: LineList,
...@@ -2140,11 +2172,11 @@ pub const Node = struct {...@@ -2140,11 +2172,11 @@ pub const Node = struct {
2140 }2172 }
21412173
2142 pub fn firstToken(self: &DocComment) TokenIndex {2174 pub fn firstToken(self: &DocComment) TokenIndex {
2143 return *self.lines.at(0);2175 return self.lines.at(0).*;
2144 }2176 }
21452177
2146 pub fn lastToken(self: &DocComment) TokenIndex {2178 pub fn lastToken(self: &DocComment) TokenIndex {
2147 return *self.lines.at(self.lines.len - 1);2179 return self.lines.at(self.lines.len - 1).*;
2148 }2180 }
2149 };2181 };
21502182
...@@ -2173,4 +2205,3 @@ pub const Node = struct {...@@ -2173,4 +2205,3 @@ pub const Node = struct {
2173 }2205 }
2174 };2206 };
2175};2207};
2176
std/zig/parse.zig+1192-1337
...@@ -7,9 +7,8 @@ const Token = std.zig.Token;...@@ -7,9 +7,8 @@ const Token = std.zig.Token;
7const TokenIndex = ast.TokenIndex;7const TokenIndex = ast.TokenIndex;
8const Error = ast.Error;8const Error = ast.Error;
99
10/// Returns an AST tree, allocated with the parser's allocator.
11/// Result should be freed with tree.deinit() when there are10/// Result should be freed with tree.deinit() when there are
12/// no more references to any AST nodes of the tree.11/// no more references to any of the tokens or nodes.
13pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {12pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
14 var tree_arena = std.heap.ArenaAllocator.init(allocator);13 var tree_arena = std.heap.ArenaAllocator.init(allocator);
15 errdefer tree_arena.deinit();14 errdefer tree_arena.deinit();
...@@ -18,17 +17,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -18,17 +17,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
18 defer stack.deinit();17 defer stack.deinit();
1918
20 const arena = &tree_arena.allocator;19 const arena = &tree_arena.allocator;
21 const root_node = try createNode(arena, ast.Node.Root,20 const root_node = try arena.construct(ast.Node.Root{
22 ast.Node.Root {21 .base = ast.Node{ .id = ast.Node.Id.Root },
23 .base = undefined,22 .decls = ast.Node.Root.DeclList.init(arena),
24 .decls = ast.Node.Root.DeclList.init(arena),23 .doc_comments = null,
25 .doc_comments = null,24 // initialized when we get the eof token
26 // initialized when we get the eof token25 .eof_token = undefined,
27 .eof_token = undefined,26 });
28 }
29 );
3027
31 var tree = ast.Tree {28 var tree = ast.Tree{
32 .source = source,29 .source = source,
33 .root_node = root_node,30 .root_node = root_node,
34 .arena_allocator = tree_arena,31 .arena_allocator = tree_arena,
...@@ -39,12 +36,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -39,12 +36,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
39 var tokenizer = Tokenizer.init(tree.source);36 var tokenizer = Tokenizer.init(tree.source);
40 while (true) {37 while (true) {
41 const token_ptr = try tree.tokens.addOne();38 const token_ptr = try tree.tokens.addOne();
42 *token_ptr = tokenizer.next();39 token_ptr.* = tokenizer.next();
43 if (token_ptr.id == Token.Id.Eof)40 if (token_ptr.id == Token.Id.Eof) break;
44 break;
45 }41 }
46 var tok_it = tree.tokens.iterator(0);42 var tok_it = tree.tokens.iterator(0);
4743
44 // skip over line comments at the top of the file
45 while (true) {
46 const next_tok = tok_it.peek() ?? break;
47 if (next_tok.id != Token.Id.LineComment) break;
48 _ = tok_it.next();
49 }
50
48 try stack.append(State.TopLevel);51 try stack.append(State.TopLevel);
4952
50 while (true) {53 while (true) {
...@@ -53,10 +56,6 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -53,10 +56,6 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
5356
54 switch (state) {57 switch (state) {
55 State.TopLevel => {58 State.TopLevel => {
56 while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| {
57 try root_node.decls.push(&line_comment.base);
58 }
59
60 const comments = try eatDocComments(arena, &tok_it, &tree);59 const comments = try eatDocComments(arena, &tok_it, &tree);
6160
62 const token = nextToken(&tok_it, &tree);61 const token = nextToken(&tok_it, &tree);
...@@ -66,33 +65,29 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -66,33 +65,29 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
66 Token.Id.Keyword_test => {65 Token.Id.Keyword_test => {
67 stack.append(State.TopLevel) catch unreachable;66 stack.append(State.TopLevel) catch unreachable;
6867
69 const block = try arena.construct(ast.Node.Block {68 const block = try arena.construct(ast.Node.Block{
70 .base = ast.Node {69 .base = ast.Node{ .id = ast.Node.Id.Block },
71 .id = ast.Node.Id.Block,
72 },
73 .label = null,70 .label = null,
74 .lbrace = undefined,71 .lbrace = undefined,
75 .statements = ast.Node.Block.StatementList.init(arena),72 .statements = ast.Node.Block.StatementList.init(arena),
76 .rbrace = undefined,73 .rbrace = undefined,
77 });74 });
78 const test_node = try arena.construct(ast.Node.TestDecl {75 const test_node = try arena.construct(ast.Node.TestDecl{
79 .base = ast.Node {76 .base = ast.Node{ .id = ast.Node.Id.TestDecl },
80 .id = ast.Node.Id.TestDecl,
81 },
82 .doc_comments = comments,77 .doc_comments = comments,
83 .test_token = token_index,78 .test_token = token_index,
84 .name = undefined,79 .name = undefined,
85 .body_node = &block.base,80 .body_node = &block.base,
86 });81 });
87 try root_node.decls.push(&test_node.base);82 try root_node.decls.push(&test_node.base);
88 try stack.append(State { .Block = block });83 try stack.append(State{ .Block = block });
89 try stack.append(State {84 try stack.append(State{
90 .ExpectTokenSave = ExpectTokenSave {85 .ExpectTokenSave = ExpectTokenSave{
91 .id = Token.Id.LBrace,86 .id = Token.Id.LBrace,
92 .ptr = &block.rbrace,87 .ptr = &block.lbrace,
93 }88 },
94 });89 });
95 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &test_node.name } });90 try stack.append(State{ .StringLiteral = OptionalCtx{ .Required = &test_node.name } });
96 continue;91 continue;
97 },92 },
98 Token.Id.Eof => {93 Token.Id.Eof => {
...@@ -102,31 +97,27 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -102,31 +97,27 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
102 },97 },
103 Token.Id.Keyword_pub => {98 Token.Id.Keyword_pub => {
104 stack.append(State.TopLevel) catch unreachable;99 stack.append(State.TopLevel) catch unreachable;
105 try stack.append(State {100 try stack.append(State{
106 .TopLevelExtern = TopLevelDeclCtx {101 .TopLevelExtern = TopLevelDeclCtx{
107 .decls = &root_node.decls,102 .decls = &root_node.decls,
108 .visib_token = token_index,103 .visib_token = token_index,
109 .extern_export_inline_token = null,104 .extern_export_inline_token = null,
110 .lib_name = null,105 .lib_name = null,
111 .comments = comments,106 .comments = comments,
112 }107 },
113 });108 });
114 continue;109 continue;
115 },110 },
116 Token.Id.Keyword_comptime => {111 Token.Id.Keyword_comptime => {
117 const block = try createNode(arena, ast.Node.Block,112 const block = try arena.construct(ast.Node.Block{
118 ast.Node.Block {113 .base = ast.Node{ .id = ast.Node.Id.Block },
119 .base = undefined,114 .label = null,
120 .label = null,115 .lbrace = undefined,
121 .lbrace = undefined,116 .statements = ast.Node.Block.StatementList.init(arena),
122 .statements = ast.Node.Block.StatementList.init(arena),117 .rbrace = undefined,
123 .rbrace = undefined,118 });
124 }119 const node = try arena.construct(ast.Node.Comptime{
125 );120 .base = ast.Node{ .id = ast.Node.Id.Comptime },
126 const node = try arena.construct(ast.Node.Comptime {
127 .base = ast.Node {
128 .id = ast.Node.Id.Comptime,
129 },
130 .comptime_token = token_index,121 .comptime_token = token_index,
131 .expr = &block.base,122 .expr = &block.base,
132 .doc_comments = comments,123 .doc_comments = comments,
...@@ -134,26 +125,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -134,26 +125,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
134 try root_node.decls.push(&node.base);125 try root_node.decls.push(&node.base);
135126
136 stack.append(State.TopLevel) catch unreachable;127 stack.append(State.TopLevel) catch unreachable;
137 try stack.append(State { .Block = block });128 try stack.append(State{ .Block = block });
138 try stack.append(State {129 try stack.append(State{
139 .ExpectTokenSave = ExpectTokenSave {130 .ExpectTokenSave = ExpectTokenSave{
140 .id = Token.Id.LBrace,131 .id = Token.Id.LBrace,
141 .ptr = &block.rbrace,132 .ptr = &block.lbrace,
142 }133 },
143 });134 });
144 continue;135 continue;
145 },136 },
146 else => {137 else => {
147 putBackToken(&tok_it, &tree);138 prevToken(&tok_it, &tree);
148 stack.append(State.TopLevel) catch unreachable;139 stack.append(State.TopLevel) catch unreachable;
149 try stack.append(State {140 try stack.append(State{
150 .TopLevelExtern = TopLevelDeclCtx {141 .TopLevelExtern = TopLevelDeclCtx{
151 .decls = &root_node.decls,142 .decls = &root_node.decls,
152 .visib_token = null,143 .visib_token = null,
153 .extern_export_inline_token = null,144 .extern_export_inline_token = null,
154 .lib_name = null,145 .lib_name = null,
155 .comments = comments,146 .comments = comments,
156 }147 },
157 });148 });
158 continue;149 continue;
159 },150 },
...@@ -165,11 +156,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -165,11 +156,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
165 const token_ptr = token.ptr;156 const token_ptr = token.ptr;
166 switch (token_ptr.id) {157 switch (token_ptr.id) {
167 Token.Id.Keyword_export, Token.Id.Keyword_inline => {158 Token.Id.Keyword_export, Token.Id.Keyword_inline => {
168 stack.append(State {159 stack.append(State{
169 .TopLevelDecl = TopLevelDeclCtx {160 .TopLevelDecl = TopLevelDeclCtx{
170 .decls = ctx.decls,161 .decls = ctx.decls,
171 .visib_token = ctx.visib_token,162 .visib_token = ctx.visib_token,
172 .extern_export_inline_token = AnnotatedToken {163 .extern_export_inline_token = AnnotatedToken{
173 .index = token_index,164 .index = token_index,
174 .ptr = token_ptr,165 .ptr = token_ptr,
175 },166 },
...@@ -180,11 +171,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -180,11 +171,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
180 continue;171 continue;
181 },172 },
182 Token.Id.Keyword_extern => {173 Token.Id.Keyword_extern => {
183 stack.append(State {174 stack.append(State{
184 .TopLevelLibname = TopLevelDeclCtx {175 .TopLevelLibname = TopLevelDeclCtx{
185 .decls = ctx.decls,176 .decls = ctx.decls,
186 .visib_token = ctx.visib_token,177 .visib_token = ctx.visib_token,
187 .extern_export_inline_token = AnnotatedToken {178 .extern_export_inline_token = AnnotatedToken{
188 .index = token_index,179 .index = token_index,
189 .ptr = token_ptr,180 .ptr = token_ptr,
190 },181 },
...@@ -195,10 +186,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -195,10 +186,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
195 continue;186 continue;
196 },187 },
197 else => {188 else => {
198 putBackToken(&tok_it, &tree);189 prevToken(&tok_it, &tree);
199 stack.append(State { .TopLevelDecl = ctx }) catch unreachable;190 stack.append(State{ .TopLevelDecl = ctx }) catch unreachable;
200 continue;191 continue;
201 }192 },
202 }193 }
203 },194 },
204 State.TopLevelLibname => |ctx| {195 State.TopLevelLibname => |ctx| {
...@@ -207,13 +198,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -207,13 +198,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
207 const lib_name_token_index = lib_name_token.index;198 const lib_name_token_index = lib_name_token.index;
208 const lib_name_token_ptr = lib_name_token.ptr;199 const lib_name_token_ptr = lib_name_token.ptr;
209 break :blk (try parseStringLiteral(arena, &tok_it, lib_name_token_ptr, lib_name_token_index, &tree)) ?? {200 break :blk (try parseStringLiteral(arena, &tok_it, lib_name_token_ptr, lib_name_token_index, &tree)) ?? {
210 putBackToken(&tok_it, &tree);201 prevToken(&tok_it, &tree);
211 break :blk null;202 break :blk null;
212 };203 };
213 };204 };
214205
215 stack.append(State {206 stack.append(State{
216 .TopLevelDecl = TopLevelDeclCtx {207 .TopLevelDecl = TopLevelDeclCtx{
217 .decls = ctx.decls,208 .decls = ctx.decls,
218 .visib_token = ctx.visib_token,209 .visib_token = ctx.visib_token,
219 .extern_export_inline_token = ctx.extern_export_inline_token,210 .extern_export_inline_token = ctx.extern_export_inline_token,
...@@ -230,14 +221,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -230,14 +221,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
230 switch (token_ptr.id) {221 switch (token_ptr.id) {
231 Token.Id.Keyword_use => {222 Token.Id.Keyword_use => {
232 if (ctx.extern_export_inline_token) |annotated_token| {223 if (ctx.extern_export_inline_token) |annotated_token| {
233 *(try tree.errors.addOne()) = Error {224 ((try tree.errors.addOne())).* = Error{ .InvalidToken = Error.InvalidToken{ .token = annotated_token.index } };
234 .InvalidToken = Error.InvalidToken { .token = annotated_token.index },
235 };
236 return tree;225 return tree;
237 }226 }
238227
239 const node = try arena.construct(ast.Node.Use {228 const node = try arena.construct(ast.Node.Use{
240 .base = ast.Node {.id = ast.Node.Id.Use },229 .base = ast.Node{ .id = ast.Node.Id.Use },
230 .use_token = token_index,
241 .visib_token = ctx.visib_token,231 .visib_token = ctx.visib_token,
242 .expr = undefined,232 .expr = undefined,
243 .semicolon_token = undefined,233 .semicolon_token = undefined,
...@@ -245,44 +235,39 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -245,44 +235,39 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
245 });235 });
246 try ctx.decls.push(&node.base);236 try ctx.decls.push(&node.base);
247237
248 stack.append(State {238 stack.append(State{
249 .ExpectTokenSave = ExpectTokenSave {239 .ExpectTokenSave = ExpectTokenSave{
250 .id = Token.Id.Semicolon,240 .id = Token.Id.Semicolon,
251 .ptr = &node.semicolon_token,241 .ptr = &node.semicolon_token,
252 }242 },
253 }) catch unreachable;243 }) catch unreachable;
254 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });244 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
255 continue;245 continue;
256 },246 },
257 Token.Id.Keyword_var, Token.Id.Keyword_const => {247 Token.Id.Keyword_var, Token.Id.Keyword_const => {
258 if (ctx.extern_export_inline_token) |annotated_token| {248 if (ctx.extern_export_inline_token) |annotated_token| {
259 if (annotated_token.ptr.id == Token.Id.Keyword_inline) {249 if (annotated_token.ptr.id == Token.Id.Keyword_inline) {
260 *(try tree.errors.addOne()) = Error {250 ((try tree.errors.addOne())).* = Error{ .InvalidToken = Error.InvalidToken{ .token = annotated_token.index } };
261 .InvalidToken = Error.InvalidToken { .token = annotated_token.index },
262 };
263 return tree;251 return tree;
264 }252 }
265 }253 }
266254
267 try stack.append(State {255 try stack.append(State{
268 .VarDecl = VarDeclCtx {256 .VarDecl = VarDeclCtx{
269 .comments = ctx.comments,257 .comments = ctx.comments,
270 .visib_token = ctx.visib_token,258 .visib_token = ctx.visib_token,
271 .lib_name = ctx.lib_name,259 .lib_name = ctx.lib_name,
272 .comptime_token = null,260 .comptime_token = null,
273 .extern_export_token = if (ctx.extern_export_inline_token) |at| at.index else null,261 .extern_export_token = if (ctx.extern_export_inline_token) |at| at.index else null,
274 .mut_token = token_index,262 .mut_token = token_index,
275 .list = ctx.decls263 .list = ctx.decls,
276 }264 },
277 });265 });
278 continue;266 continue;
279 },267 },
280 Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc,268 Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {
281 Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {269 const fn_proto = try arena.construct(ast.Node.FnProto{
282 const fn_proto = try arena.construct(ast.Node.FnProto {270 .base = ast.Node{ .id = ast.Node.Id.FnProto },
283 .base = ast.Node {
284 .id = ast.Node.Id.FnProto,
285 },
286 .doc_comments = ctx.comments,271 .doc_comments = ctx.comments,
287 .visib_token = ctx.visib_token,272 .visib_token = ctx.visib_token,
288 .name_token = null,273 .name_token = null,
...@@ -298,38 +283,36 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -298,38 +283,36 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
298 .align_expr = null,283 .align_expr = null,
299 });284 });
300 try ctx.decls.push(&fn_proto.base);285 try ctx.decls.push(&fn_proto.base);
301 stack.append(State { .FnDef = fn_proto }) catch unreachable;286 stack.append(State{ .FnDef = fn_proto }) catch unreachable;
302 try stack.append(State { .FnProto = fn_proto });287 try stack.append(State{ .FnProto = fn_proto });
303288
304 switch (token_ptr.id) {289 switch (token_ptr.id) {
305 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {290 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
306 fn_proto.cc_token = token_index;291 fn_proto.cc_token = token_index;
307 try stack.append(State {292 try stack.append(State{
308 .ExpectTokenSave = ExpectTokenSave {293 .ExpectTokenSave = ExpectTokenSave{
309 .id = Token.Id.Keyword_fn,294 .id = Token.Id.Keyword_fn,
310 .ptr = &fn_proto.fn_token,295 .ptr = &fn_proto.fn_token,
311 }296 },
312 });297 });
313 continue;298 continue;
314 },299 },
315 Token.Id.Keyword_async => {300 Token.Id.Keyword_async => {
316 const async_node = try createNode(arena, ast.Node.AsyncAttribute,301 const async_node = try arena.construct(ast.Node.AsyncAttribute{
317 ast.Node.AsyncAttribute {302 .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
318 .base = undefined,303 .async_token = token_index,
319 .async_token = token_index,304 .allocator_type = null,
320 .allocator_type = null,305 .rangle_bracket = null,
321 .rangle_bracket = null,306 });
322 }
323 );
324 fn_proto.async_attr = async_node;307 fn_proto.async_attr = async_node;
325308
326 try stack.append(State {309 try stack.append(State{
327 .ExpectTokenSave = ExpectTokenSave {310 .ExpectTokenSave = ExpectTokenSave{
328 .id = Token.Id.Keyword_fn,311 .id = Token.Id.Keyword_fn,
329 .ptr = &fn_proto.fn_token,312 .ptr = &fn_proto.fn_token,
330 }313 },
331 });314 });
332 try stack.append(State { .AsyncAllocator = async_node });315 try stack.append(State{ .AsyncAllocator = async_node });
333 continue;316 continue;
334 },317 },
335 Token.Id.Keyword_fn => {318 Token.Id.Keyword_fn => {
...@@ -340,43 +323,38 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -340,43 +323,38 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
340 }323 }
341 },324 },
342 else => {325 else => {
343 *(try tree.errors.addOne()) = Error {326 ((try tree.errors.addOne())).* = Error{ .ExpectedVarDeclOrFn = Error.ExpectedVarDeclOrFn{ .token = token_index } };
344 .ExpectedVarDeclOrFn = Error.ExpectedVarDeclOrFn { .token = token_index },
345 };
346 return tree;327 return tree;
347 },328 },
348 }329 }
349 },330 },
350 State.TopLevelExternOrField => |ctx| {331 State.TopLevelExternOrField => |ctx| {
351 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |identifier| {332 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |identifier| {
352 std.debug.assert(ctx.container_decl.kind == ast.Node.ContainerDecl.Kind.Struct);333 const node = try arena.construct(ast.Node.StructField{
353 const node = try arena.construct(ast.Node.StructField {334 .base = ast.Node{ .id = ast.Node.Id.StructField },
354 .base = ast.Node {
355 .id = ast.Node.Id.StructField,
356 },
357 .doc_comments = ctx.comments,335 .doc_comments = ctx.comments,
358 .visib_token = ctx.visib_token,336 .visib_token = ctx.visib_token,
359 .name_token = identifier,337 .name_token = identifier,
360 .type_expr = undefined,338 .type_expr = undefined,
361 });339 });
362 const node_ptr = try ctx.container_decl.fields_and_decls.addOne();340 const node_ptr = try ctx.container_decl.fields_and_decls.addOne();
363 *node_ptr = &node.base;341 node_ptr.* = &node.base;
364342
365 stack.append(State { .FieldListCommaOrEnd = ctx.container_decl }) catch unreachable;343 stack.append(State{ .FieldListCommaOrEnd = ctx.container_decl }) catch unreachable;
366 try stack.append(State { .Expression = OptionalCtx { .Required = &node.type_expr } });344 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.type_expr } });
367 try stack.append(State { .ExpectToken = Token.Id.Colon });345 try stack.append(State{ .ExpectToken = Token.Id.Colon });
368 continue;346 continue;
369 }347 }
370348
371 stack.append(State{ .ContainerDecl = ctx.container_decl }) catch unreachable;349 stack.append(State{ .ContainerDecl = ctx.container_decl }) catch unreachable;
372 try stack.append(State {350 try stack.append(State{
373 .TopLevelExtern = TopLevelDeclCtx {351 .TopLevelExtern = TopLevelDeclCtx{
374 .decls = &ctx.container_decl.fields_and_decls,352 .decls = &ctx.container_decl.fields_and_decls,
375 .visib_token = ctx.visib_token,353 .visib_token = ctx.visib_token,
376 .extern_export_inline_token = null,354 .extern_export_inline_token = null,
377 .lib_name = null,355 .lib_name = null,
378 .comments = ctx.comments,356 .comments = ctx.comments,
379 }357 },
380 });358 });
381 continue;359 continue;
382 },360 },
...@@ -386,10 +364,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -386,10 +364,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
386 const eq_tok_index = eq_tok.index;364 const eq_tok_index = eq_tok.index;
387 const eq_tok_ptr = eq_tok.ptr;365 const eq_tok_ptr = eq_tok.ptr;
388 if (eq_tok_ptr.id != Token.Id.Equal) {366 if (eq_tok_ptr.id != Token.Id.Equal) {
389 putBackToken(&tok_it, &tree);367 prevToken(&tok_it, &tree);
390 continue;368 continue;
391 }369 }
392 stack.append(State { .Expression = ctx }) catch unreachable;370 stack.append(State{ .Expression = ctx }) catch unreachable;
393 continue;371 continue;
394 },372 },
395373
...@@ -397,31 +375,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -397,31 +375,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
397 const token = nextToken(&tok_it, &tree);375 const token = nextToken(&tok_it, &tree);
398 const token_index = token.index;376 const token_index = token.index;
399 const token_ptr = token.ptr;377 const token_ptr = token.ptr;
400 const node = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.ContainerDecl,378 const node = try arena.construct(ast.Node.ContainerDecl{
401 ast.Node.ContainerDecl {379 .base = ast.Node{ .id = ast.Node.Id.ContainerDecl },
402 .base = undefined,380 .layout_token = ctx.layout_token,
403 .ltoken = ctx.ltoken,381 .kind_token = switch (token_ptr.id) {
404 .layout = ctx.layout,382 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => token_index,
405 .kind = switch (token_ptr.id) {383 else => {
406 Token.Id.Keyword_struct => ast.Node.ContainerDecl.Kind.Struct,384 ((try tree.errors.addOne())).* = Error{ .ExpectedAggregateKw = Error.ExpectedAggregateKw{ .token = token_index } };
407 Token.Id.Keyword_union => ast.Node.ContainerDecl.Kind.Union,385 return tree;
408 Token.Id.Keyword_enum => ast.Node.ContainerDecl.Kind.Enum,
409 else => {
410 *(try tree.errors.addOne()) = Error {
411 .ExpectedAggregateKw = Error.ExpectedAggregateKw { .token = token_index },
412 };
413 return tree;
414 },
415 },386 },
416 .init_arg_expr = ast.Node.ContainerDecl.InitArg.None,387 },
417 .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(arena),388 .init_arg_expr = ast.Node.ContainerDecl.InitArg.None,
418 .rbrace_token = undefined,389 .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(arena),
419 }390 .lbrace_token = undefined,
420 );391 .rbrace_token = undefined,
392 });
393 ctx.opt_ctx.store(&node.base);
421394
422 stack.append(State { .ContainerDecl = node }) catch unreachable;395 stack.append(State{ .ContainerDecl = node }) catch unreachable;
423 try stack.append(State { .ExpectToken = Token.Id.LBrace });396 try stack.append(State{
424 try stack.append(State { .ContainerInitArgStart = node });397 .ExpectTokenSave = ExpectTokenSave{
398 .id = Token.Id.LBrace,
399 .ptr = &node.lbrace_token,
400 },
401 });
402 try stack.append(State{ .ContainerInitArgStart = node });
425 continue;403 continue;
426 },404 },
427405
...@@ -430,8 +408,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -430,8 +408,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
430 continue;408 continue;
431 }409 }
432410
433 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;411 stack.append(State{ .ExpectToken = Token.Id.RParen }) catch unreachable;
434 try stack.append(State { .ContainerInitArg = container_decl });412 try stack.append(State{ .ContainerInitArg = container_decl });
435 continue;413 continue;
436 },414 },
437415
...@@ -441,61 +419,53 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -441,61 +419,53 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
441 const init_arg_token_ptr = init_arg_token.ptr;419 const init_arg_token_ptr = init_arg_token.ptr;
442 switch (init_arg_token_ptr.id) {420 switch (init_arg_token_ptr.id) {
443 Token.Id.Keyword_enum => {421 Token.Id.Keyword_enum => {
444 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg {.Enum = null};422 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg{ .Enum = null };
445 const lparen_tok = nextToken(&tok_it, &tree);423 const lparen_tok = nextToken(&tok_it, &tree);
446 const lparen_tok_index = lparen_tok.index;424 const lparen_tok_index = lparen_tok.index;
447 const lparen_tok_ptr = lparen_tok.ptr;425 const lparen_tok_ptr = lparen_tok.ptr;
448 if (lparen_tok_ptr.id == Token.Id.LParen) {426 if (lparen_tok_ptr.id == Token.Id.LParen) {
449 try stack.append(State { .ExpectToken = Token.Id.RParen } );427 try stack.append(State{ .ExpectToken = Token.Id.RParen });
450 try stack.append(State { .Expression = OptionalCtx {428 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &container_decl.init_arg_expr.Enum } });
451 .RequiredNull = &container_decl.init_arg_expr.Enum,
452 } });
453 } else {429 } else {
454 putBackToken(&tok_it, &tree);430 prevToken(&tok_it, &tree);
455 }431 }
456 },432 },
457 else => {433 else => {
458 putBackToken(&tok_it, &tree);434 prevToken(&tok_it, &tree);
459 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg { .Type = undefined };435 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg{ .Type = undefined };
460 stack.append(State { .Expression = OptionalCtx { .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;436 stack.append(State{ .Expression = OptionalCtx{ .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;
461 },437 },
462 }438 }
463 continue;439 continue;
464 },440 },
465441
466 State.ContainerDecl => |container_decl| {442 State.ContainerDecl => |container_decl| {
467 while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| {
468 try container_decl.fields_and_decls.push(&line_comment.base);
469 }
470
471 const comments = try eatDocComments(arena, &tok_it, &tree);443 const comments = try eatDocComments(arena, &tok_it, &tree);
472 const token = nextToken(&tok_it, &tree);444 const token = nextToken(&tok_it, &tree);
473 const token_index = token.index;445 const token_index = token.index;
474 const token_ptr = token.ptr;446 const token_ptr = token.ptr;
475 switch (token_ptr.id) {447 switch (token_ptr.id) {
476 Token.Id.Identifier => {448 Token.Id.Identifier => {
477 switch (container_decl.kind) {449 switch (tree.tokens.at(container_decl.kind_token).id) {
478 ast.Node.ContainerDecl.Kind.Struct => {450 Token.Id.Keyword_struct => {
479 const node = try arena.construct(ast.Node.StructField {451 const node = try arena.construct(ast.Node.StructField{
480 .base = ast.Node {452 .base = ast.Node{ .id = ast.Node.Id.StructField },
481 .id = ast.Node.Id.StructField,
482 },
483 .doc_comments = comments,453 .doc_comments = comments,
484 .visib_token = null,454 .visib_token = null,
485 .name_token = token_index,455 .name_token = token_index,
486 .type_expr = undefined,456 .type_expr = undefined,
487 });457 });
488 const node_ptr = try container_decl.fields_and_decls.addOne();458 const node_ptr = try container_decl.fields_and_decls.addOne();
489 *node_ptr = &node.base;459 node_ptr.* = &node.base;
490460
491 try stack.append(State { .FieldListCommaOrEnd = container_decl });461 try stack.append(State{ .FieldListCommaOrEnd = container_decl });
492 try stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.type_expr } });462 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &node.type_expr } });
493 try stack.append(State { .ExpectToken = Token.Id.Colon });463 try stack.append(State{ .ExpectToken = Token.Id.Colon });
494 continue;464 continue;
495 },465 },
496 ast.Node.ContainerDecl.Kind.Union => {466 Token.Id.Keyword_union => {
497 const node = try arena.construct(ast.Node.UnionTag {467 const node = try arena.construct(ast.Node.UnionTag{
498 .base = ast.Node {.id = ast.Node.Id.UnionTag },468 .base = ast.Node{ .id = ast.Node.Id.UnionTag },
499 .name_token = token_index,469 .name_token = token_index,
500 .type_expr = null,470 .type_expr = null,
501 .value_expr = null,471 .value_expr = null,
...@@ -503,101 +473,97 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -503,101 +473,97 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
503 });473 });
504 try container_decl.fields_and_decls.push(&node.base);474 try container_decl.fields_and_decls.push(&node.base);
505475
506 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;476 stack.append(State{ .FieldListCommaOrEnd = container_decl }) catch unreachable;
507 try stack.append(State { .FieldInitValue = OptionalCtx { .RequiredNull = &node.value_expr } });477 try stack.append(State{ .FieldInitValue = OptionalCtx{ .RequiredNull = &node.value_expr } });
508 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &node.type_expr } });478 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .RequiredNull = &node.type_expr } });
509 try stack.append(State { .IfToken = Token.Id.Colon });479 try stack.append(State{ .IfToken = Token.Id.Colon });
510 continue;480 continue;
511 },481 },
512 ast.Node.ContainerDecl.Kind.Enum => {482 Token.Id.Keyword_enum => {
513 const node = try arena.construct(ast.Node.EnumTag {483 const node = try arena.construct(ast.Node.EnumTag{
514 .base = ast.Node { .id = ast.Node.Id.EnumTag },484 .base = ast.Node{ .id = ast.Node.Id.EnumTag },
515 .name_token = token_index,485 .name_token = token_index,
516 .value = null,486 .value = null,
517 .doc_comments = comments,487 .doc_comments = comments,
518 });488 });
519 try container_decl.fields_and_decls.push(&node.base);489 try container_decl.fields_and_decls.push(&node.base);
520490
521 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;491 stack.append(State{ .FieldListCommaOrEnd = container_decl }) catch unreachable;
522 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &node.value } });492 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &node.value } });
523 try stack.append(State { .IfToken = Token.Id.Equal });493 try stack.append(State{ .IfToken = Token.Id.Equal });
524 continue;494 continue;
525 },495 },
496 else => unreachable,
526 }497 }
527 },498 },
528 Token.Id.Keyword_pub => {499 Token.Id.Keyword_pub => {
529 switch (container_decl.kind) {500 switch (tree.tokens.at(container_decl.kind_token).id) {
530 ast.Node.ContainerDecl.Kind.Struct => {501 Token.Id.Keyword_struct => {
531 try stack.append(State {502 try stack.append(State{
532 .TopLevelExternOrField = TopLevelExternOrFieldCtx {503 .TopLevelExternOrField = TopLevelExternOrFieldCtx{
533 .visib_token = token_index,504 .visib_token = token_index,
534 .container_decl = container_decl,505 .container_decl = container_decl,
535 .comments = comments,506 .comments = comments,
536 }507 },
537 });508 });
538 continue;509 continue;
539 },510 },
540 else => {511 else => {
541 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;512 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
542 try stack.append(State {513 try stack.append(State{
543 .TopLevelExtern = TopLevelDeclCtx {514 .TopLevelExtern = TopLevelDeclCtx{
544 .decls = &container_decl.fields_and_decls,515 .decls = &container_decl.fields_and_decls,
545 .visib_token = token_index,516 .visib_token = token_index,
546 .extern_export_inline_token = null,517 .extern_export_inline_token = null,
547 .lib_name = null,518 .lib_name = null,
548 .comments = comments,519 .comments = comments,
549 }520 },
550 });521 });
551 continue;522 continue;
552 }523 },
553 }524 }
554 },525 },
555 Token.Id.Keyword_export => {526 Token.Id.Keyword_export => {
556 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;527 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
557 try stack.append(State {528 try stack.append(State{
558 .TopLevelExtern = TopLevelDeclCtx {529 .TopLevelExtern = TopLevelDeclCtx{
559 .decls = &container_decl.fields_and_decls,530 .decls = &container_decl.fields_and_decls,
560 .visib_token = token_index,531 .visib_token = token_index,
561 .extern_export_inline_token = null,532 .extern_export_inline_token = null,
562 .lib_name = null,533 .lib_name = null,
563 .comments = comments,534 .comments = comments,
564 }535 },
565 });536 });
566 continue;537 continue;
567 },538 },
568 Token.Id.RBrace => {539 Token.Id.RBrace => {
569 if (comments != null) {540 if (comments != null) {
570 *(try tree.errors.addOne()) = Error {541 ((try tree.errors.addOne())).* = Error{ .UnattachedDocComment = Error.UnattachedDocComment{ .token = token_index } };
571 .UnattachedDocComment = Error.UnattachedDocComment { .token = token_index },
572 };
573 return tree;542 return tree;
574 }543 }
575 container_decl.rbrace_token = token_index;544 container_decl.rbrace_token = token_index;
576 continue;545 continue;
577 },546 },
578 else => {547 else => {
579 putBackToken(&tok_it, &tree);548 prevToken(&tok_it, &tree);
580 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;549 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
581 try stack.append(State {550 try stack.append(State{
582 .TopLevelExtern = TopLevelDeclCtx {551 .TopLevelExtern = TopLevelDeclCtx{
583 .decls = &container_decl.fields_and_decls,552 .decls = &container_decl.fields_and_decls,
584 .visib_token = null,553 .visib_token = null,
585 .extern_export_inline_token = null,554 .extern_export_inline_token = null,
586 .lib_name = null,555 .lib_name = null,
587 .comments = comments,556 .comments = comments,
588 }557 },
589 });558 });
590 continue;559 continue;
591 }560 },
592 }561 }
593 },562 },
594563
595
596 State.VarDecl => |ctx| {564 State.VarDecl => |ctx| {
597 const var_decl = try arena.construct(ast.Node.VarDecl {565 const var_decl = try arena.construct(ast.Node.VarDecl{
598 .base = ast.Node {566 .base = ast.Node{ .id = ast.Node.Id.VarDecl },
599 .id = ast.Node.Id.VarDecl,
600 },
601 .doc_comments = ctx.comments,567 .doc_comments = ctx.comments,
602 .visib_token = ctx.visib_token,568 .visib_token = ctx.visib_token,
603 .mut_token = ctx.mut_token,569 .mut_token = ctx.mut_token,
...@@ -614,31 +580,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -614,31 +580,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
614 });580 });
615 try ctx.list.push(&var_decl.base);581 try ctx.list.push(&var_decl.base);
616582
617 try stack.append(State { .VarDeclAlign = var_decl });583 try stack.append(State{ .VarDeclAlign = var_decl });
618 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} });584 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .RequiredNull = &var_decl.type_node } });
619 try stack.append(State { .IfToken = Token.Id.Colon });585 try stack.append(State{ .IfToken = Token.Id.Colon });
620 try stack.append(State {586 try stack.append(State{
621 .ExpectTokenSave = ExpectTokenSave {587 .ExpectTokenSave = ExpectTokenSave{
622 .id = Token.Id.Identifier,588 .id = Token.Id.Identifier,
623 .ptr = &var_decl.name_token,589 .ptr = &var_decl.name_token,
624 }590 },
625 });591 });
626 continue;592 continue;
627 },593 },
628 State.VarDeclAlign => |var_decl| {594 State.VarDeclAlign => |var_decl| {
629 try stack.append(State { .VarDeclEq = var_decl });595 try stack.append(State{ .VarDeclEq = var_decl });
630596
631 const next_token = nextToken(&tok_it, &tree);597 const next_token = nextToken(&tok_it, &tree);
632 const next_token_index = next_token.index;598 const next_token_index = next_token.index;
633 const next_token_ptr = next_token.ptr;599 const next_token_ptr = next_token.ptr;
634 if (next_token_ptr.id == Token.Id.Keyword_align) {600 if (next_token_ptr.id == Token.Id.Keyword_align) {
635 try stack.append(State { .ExpectToken = Token.Id.RParen });601 try stack.append(State{ .ExpectToken = Token.Id.RParen });
636 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.align_node} });602 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &var_decl.align_node } });
637 try stack.append(State { .ExpectToken = Token.Id.LParen });603 try stack.append(State{ .ExpectToken = Token.Id.LParen });
638 continue;604 continue;
639 }605 }
640606
641 putBackToken(&tok_it, &tree);607 prevToken(&tok_it, &tree);
642 continue;608 continue;
643 },609 },
644 State.VarDeclEq => |var_decl| {610 State.VarDeclEq => |var_decl| {
...@@ -648,13 +614,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -648,13 +614,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
648 switch (token_ptr.id) {614 switch (token_ptr.id) {
649 Token.Id.Equal => {615 Token.Id.Equal => {
650 var_decl.eq_token = token_index;616 var_decl.eq_token = token_index;
651 stack.append(State {617 stack.append(State{ .VarDeclSemiColon = var_decl }) catch unreachable;
652 .ExpectTokenSave = ExpectTokenSave {618 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &var_decl.init_node } });
653 .id = Token.Id.Semicolon,
654 .ptr = &var_decl.semicolon_token,
655 },
656 }) catch unreachable;
657 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.init_node } });
658 continue;619 continue;
659 },620 },
660 Token.Id.Semicolon => {621 Token.Id.Semicolon => {
...@@ -662,45 +623,65 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -662,45 +623,65 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
662 continue;623 continue;
663 },624 },
664 else => {625 else => {
665 *(try tree.errors.addOne()) = Error {626 ((try tree.errors.addOne())).* = Error{ .ExpectedEqOrSemi = Error.ExpectedEqOrSemi{ .token = token_index } };
666 .ExpectedEqOrSemi = Error.ExpectedEqOrSemi { .token = token_index },
667 };
668 return tree;627 return tree;
669 }628 },
670 }629 }
671 },630 },
672631
632 State.VarDeclSemiColon => |var_decl| {
633 const semicolon_token = nextToken(&tok_it, &tree);
634
635 if (semicolon_token.ptr.id != Token.Id.Semicolon) {
636 ((try tree.errors.addOne())).* = Error{
637 .ExpectedToken = Error.ExpectedToken{
638 .token = semicolon_token.index,
639 .expected_id = Token.Id.Semicolon,
640 },
641 };
642 return tree;
643 }
644
645 var_decl.semicolon_token = semicolon_token.index;
646
647 if (eatToken(&tok_it, &tree, Token.Id.DocComment)) |doc_comment_token| {
648 const loc = tree.tokenLocation(semicolon_token.ptr.end, doc_comment_token);
649 if (loc.line == 0) {
650 try pushDocComment(arena, doc_comment_token, &var_decl.doc_comments);
651 } else {
652 prevToken(&tok_it, &tree);
653 }
654 }
655 },
673656
674 State.FnDef => |fn_proto| {657 State.FnDef => |fn_proto| {
675 const token = nextToken(&tok_it, &tree);658 const token = nextToken(&tok_it, &tree);
676 const token_index = token.index;659 const token_index = token.index;
677 const token_ptr = token.ptr;660 const token_ptr = token.ptr;
678 switch(token_ptr.id) {661 switch (token_ptr.id) {
679 Token.Id.LBrace => {662 Token.Id.LBrace => {
680 const block = try arena.construct(ast.Node.Block {663 const block = try arena.construct(ast.Node.Block{
681 .base = ast.Node { .id = ast.Node.Id.Block },664 .base = ast.Node{ .id = ast.Node.Id.Block },
682 .label = null,665 .label = null,
683 .lbrace = token_index,666 .lbrace = token_index,
684 .statements = ast.Node.Block.StatementList.init(arena),667 .statements = ast.Node.Block.StatementList.init(arena),
685 .rbrace = undefined,668 .rbrace = undefined,
686 });669 });
687 fn_proto.body_node = &block.base;670 fn_proto.body_node = &block.base;
688 stack.append(State { .Block = block }) catch unreachable;671 stack.append(State{ .Block = block }) catch unreachable;
689 continue;672 continue;
690 },673 },
691 Token.Id.Semicolon => continue,674 Token.Id.Semicolon => continue,
692 else => {675 else => {
693 *(try tree.errors.addOne()) = Error {676 ((try tree.errors.addOne())).* = Error{ .ExpectedSemiOrLBrace = Error.ExpectedSemiOrLBrace{ .token = token_index } };
694 .ExpectedSemiOrLBrace = Error.ExpectedSemiOrLBrace { .token = token_index },
695 };
696 return tree;677 return tree;
697 },678 },
698 }679 }
699 },680 },
700 State.FnProto => |fn_proto| {681 State.FnProto => |fn_proto| {
701 stack.append(State { .FnProtoAlign = fn_proto }) catch unreachable;682 stack.append(State{ .FnProtoAlign = fn_proto }) catch unreachable;
702 try stack.append(State { .ParamDecl = fn_proto });683 try stack.append(State{ .ParamDecl = fn_proto });
703 try stack.append(State { .ExpectToken = Token.Id.LParen });684 try stack.append(State{ .ExpectToken = Token.Id.LParen });
704685
705 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |name_token| {686 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |name_token| {
706 fn_proto.name_token = name_token;687 fn_proto.name_token = name_token;
...@@ -708,12 +689,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -708,12 +689,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
708 continue;689 continue;
709 },690 },
710 State.FnProtoAlign => |fn_proto| {691 State.FnProtoAlign => |fn_proto| {
711 stack.append(State { .FnProtoReturnType = fn_proto }) catch unreachable;692 stack.append(State{ .FnProtoReturnType = fn_proto }) catch unreachable;
712693
713 if (eatToken(&tok_it, &tree, Token.Id.Keyword_align)) |align_token| {694 if (eatToken(&tok_it, &tree, Token.Id.Keyword_align)) |align_token| {
714 try stack.append(State { .ExpectToken = Token.Id.RParen });695 try stack.append(State{ .ExpectToken = Token.Id.RParen });
715 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } });696 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &fn_proto.align_expr } });
716 try stack.append(State { .ExpectToken = Token.Id.LParen });697 try stack.append(State{ .ExpectToken = Token.Id.LParen });
717 }698 }
718 continue;699 continue;
719 },700 },
...@@ -723,42 +704,37 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -723,42 +704,37 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
723 const token_ptr = token.ptr;704 const token_ptr = token.ptr;
724 switch (token_ptr.id) {705 switch (token_ptr.id) {
725 Token.Id.Bang => {706 Token.Id.Bang => {
726 fn_proto.return_type = ast.Node.FnProto.ReturnType { .InferErrorSet = undefined };707 fn_proto.return_type = ast.Node.FnProto.ReturnType{ .InferErrorSet = undefined };
727 stack.append(State {708 stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &fn_proto.return_type.InferErrorSet } }) catch unreachable;
728 .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.InferErrorSet },
729 }) catch unreachable;
730 continue;709 continue;
731 },710 },
732 else => {711 else => {
733 // TODO: this is a special case. Remove this when #760 is fixed712 // TODO: this is a special case. Remove this when #760 is fixed
734 if (token_ptr.id == Token.Id.Keyword_error) {713 if (token_ptr.id == Token.Id.Keyword_error) {
735 if ((??tok_it.peek()).id == Token.Id.LBrace) {714 if ((??tok_it.peek()).id == Token.Id.LBrace) {
736 const error_type_node = try arena.construct(ast.Node.ErrorType {715 const error_type_node = try arena.construct(ast.Node.ErrorType{
737 .base = ast.Node { .id = ast.Node.Id.ErrorType },716 .base = ast.Node{ .id = ast.Node.Id.ErrorType },
738 .token = token_index,717 .token = token_index,
739 });718 });
740 fn_proto.return_type = ast.Node.FnProto.ReturnType {719 fn_proto.return_type = ast.Node.FnProto.ReturnType{ .Explicit = &error_type_node.base };
741 .Explicit = &error_type_node.base,
742 };
743 continue;720 continue;
744 }721 }
745 }722 }
746723
747 putBackToken(&tok_it, &tree);724 prevToken(&tok_it, &tree);
748 fn_proto.return_type = ast.Node.FnProto.ReturnType { .Explicit = undefined };725 fn_proto.return_type = ast.Node.FnProto.ReturnType{ .Explicit = undefined };
749 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.Explicit }, }) catch unreachable;726 stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &fn_proto.return_type.Explicit } }) catch unreachable;
750 continue;727 continue;
751 },728 },
752 }729 }
753 },730 },
754731
755
756 State.ParamDecl => |fn_proto| {732 State.ParamDecl => |fn_proto| {
757 if (eatToken(&tok_it, &tree, Token.Id.RParen)) |_| {733 if (eatToken(&tok_it, &tree, Token.Id.RParen)) |_| {
758 continue;734 continue;
759 }735 }
760 const param_decl = try arena.construct(ast.Node.ParamDecl {736 const param_decl = try arena.construct(ast.Node.ParamDecl{
761 .base = ast.Node {.id = ast.Node.Id.ParamDecl },737 .base = ast.Node{ .id = ast.Node.Id.ParamDecl },
762 .comptime_token = null,738 .comptime_token = null,
763 .noalias_token = null,739 .noalias_token = null,
764 .name_token = null,740 .name_token = null,
...@@ -767,14 +743,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -767,14 +743,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
767 });743 });
768 try fn_proto.params.push(&param_decl.base);744 try fn_proto.params.push(&param_decl.base);
769745
770 stack.append(State {746 stack.append(State{
771 .ParamDeclEnd = ParamDeclEndCtx {747 .ParamDeclEnd = ParamDeclEndCtx{
772 .param_decl = param_decl,748 .param_decl = param_decl,
773 .fn_proto = fn_proto,749 .fn_proto = fn_proto,
774 }750 },
775 }) catch unreachable;751 }) catch unreachable;
776 try stack.append(State { .ParamDeclName = param_decl });752 try stack.append(State{ .ParamDeclName = param_decl });
777 try stack.append(State { .ParamDeclAliasOrComptime = param_decl });753 try stack.append(State{ .ParamDeclAliasOrComptime = param_decl });
778 continue;754 continue;
779 },755 },
780 State.ParamDeclAliasOrComptime => |param_decl| {756 State.ParamDeclAliasOrComptime => |param_decl| {
...@@ -792,7 +768,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -792,7 +768,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
792 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {768 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {
793 param_decl.name_token = ident_token;769 param_decl.name_token = ident_token;
794 } else {770 } else {
795 putBackToken(&tok_it, &tree);771 prevToken(&tok_it, &tree);
796 }772 }
797 }773 }
798 continue;774 continue;
...@@ -800,21 +776,19 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -800,21 +776,19 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
800 State.ParamDeclEnd => |ctx| {776 State.ParamDeclEnd => |ctx| {
801 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {777 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {
802 ctx.param_decl.var_args_token = ellipsis3;778 ctx.param_decl.var_args_token = ellipsis3;
803 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;779 stack.append(State{ .ExpectToken = Token.Id.RParen }) catch unreachable;
804 continue;780 continue;
805 }781 }
806782
807 try stack.append(State { .ParamDeclComma = ctx.fn_proto });783 try stack.append(State{ .ParamDeclComma = ctx.fn_proto });
808 try stack.append(State {784 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &ctx.param_decl.type_node } });
809 .TypeExprBegin = OptionalCtx { .Required = &ctx.param_decl.type_node }
810 });
811 continue;785 continue;
812 },786 },
813 State.ParamDeclComma => |fn_proto| {787 State.ParamDeclComma => |fn_proto| {
814 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {788 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {
815 ExpectCommaOrEndResult.end_token => |t| {789 ExpectCommaOrEndResult.end_token => |t| {
816 if (t == null) {790 if (t == null) {
817 stack.append(State { .ParamDecl = fn_proto }) catch unreachable;791 stack.append(State{ .ParamDecl = fn_proto }) catch unreachable;
818 }792 }
819 continue;793 continue;
820 },794 },
...@@ -827,11 +801,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -827,11 +801,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
827801
828 State.MaybeLabeledExpression => |ctx| {802 State.MaybeLabeledExpression => |ctx| {
829 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {803 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {
830 stack.append(State {804 stack.append(State{
831 .LabeledExpression = LabelCtx {805 .LabeledExpression = LabelCtx{
832 .label = ctx.label,806 .label = ctx.label,
833 .opt_ctx = ctx.opt_ctx,807 .opt_ctx = ctx.opt_ctx,
834 }808 },
835 }) catch unreachable;809 }) catch unreachable;
836 continue;810 continue;
837 }811 }
...@@ -845,74 +819,69 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -845,74 +819,69 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
845 const token_ptr = token.ptr;819 const token_ptr = token.ptr;
846 switch (token_ptr.id) {820 switch (token_ptr.id) {
847 Token.Id.LBrace => {821 Token.Id.LBrace => {
848 const block = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.Block,822 const block = try arena.construct(ast.Node.Block{
849 ast.Node.Block {823 .base = ast.Node{ .id = ast.Node.Id.Block },
850 .base = undefined,824 .label = ctx.label,
851 .label = ctx.label,825 .lbrace = token_index,
852 .lbrace = token_index,826 .statements = ast.Node.Block.StatementList.init(arena),
853 .statements = ast.Node.Block.StatementList.init(arena),827 .rbrace = undefined,
854 .rbrace = undefined,828 });
855 }829 ctx.opt_ctx.store(&block.base);
856 );830 stack.append(State{ .Block = block }) catch unreachable;
857 stack.append(State { .Block = block }) catch unreachable;
858 continue;831 continue;
859 },832 },
860 Token.Id.Keyword_while => {833 Token.Id.Keyword_while => {
861 stack.append(State {834 stack.append(State{
862 .While = LoopCtx {835 .While = LoopCtx{
863 .label = ctx.label,836 .label = ctx.label,
864 .inline_token = null,837 .inline_token = null,
865 .loop_token = token_index,838 .loop_token = token_index,
866 .opt_ctx = ctx.opt_ctx.toRequired(),839 .opt_ctx = ctx.opt_ctx.toRequired(),
867 }840 },
868 }) catch unreachable;841 }) catch unreachable;
869 continue;842 continue;
870 },843 },
871 Token.Id.Keyword_for => {844 Token.Id.Keyword_for => {
872 stack.append(State {845 stack.append(State{
873 .For = LoopCtx {846 .For = LoopCtx{
874 .label = ctx.label,847 .label = ctx.label,
875 .inline_token = null,848 .inline_token = null,
876 .loop_token = token_index,849 .loop_token = token_index,
877 .opt_ctx = ctx.opt_ctx.toRequired(),850 .opt_ctx = ctx.opt_ctx.toRequired(),
878 }851 },
879 }) catch unreachable;852 }) catch unreachable;
880 continue;853 continue;
881 },854 },
882 Token.Id.Keyword_suspend => {855 Token.Id.Keyword_suspend => {
883 const node = try arena.construct(ast.Node.Suspend {856 const node = try arena.construct(ast.Node.Suspend{
884 .base = ast.Node {857 .base = ast.Node{ .id = ast.Node.Id.Suspend },
885 .id = ast.Node.Id.Suspend,
886 },
887 .label = ctx.label,858 .label = ctx.label,
888 .suspend_token = token_index,859 .suspend_token = token_index,
889 .payload = null,860 .payload = null,
890 .body = null,861 .body = null,
891 });862 });
892 ctx.opt_ctx.store(&node.base);863 ctx.opt_ctx.store(&node.base);
893 stack.append(State { .SuspendBody = node }) catch unreachable;864 stack.append(State{ .SuspendBody = node }) catch unreachable;
894 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });865 try stack.append(State{ .Payload = OptionalCtx{ .Optional = &node.payload } });
895 continue;866 continue;
896 },867 },
897 Token.Id.Keyword_inline => {868 Token.Id.Keyword_inline => {
898 stack.append(State {869 stack.append(State{
899 .Inline = InlineCtx {870 .Inline = InlineCtx{
900 .label = ctx.label,871 .label = ctx.label,
901 .inline_token = token_index,872 .inline_token = token_index,
902 .opt_ctx = ctx.opt_ctx.toRequired(),873 .opt_ctx = ctx.opt_ctx.toRequired(),
903 }874 },
904 }) catch unreachable;875 }) catch unreachable;
905 continue;876 continue;
906 },877 },
907 else => {878 else => {
908 if (ctx.opt_ctx != OptionalCtx.Optional) {879 if (ctx.opt_ctx != OptionalCtx.Optional) {
909 *(try tree.errors.addOne()) = Error {880 ((try tree.errors.addOne())).* = Error{ .ExpectedLabelable = Error.ExpectedLabelable{ .token = token_index } };
910 .ExpectedLabelable = Error.ExpectedLabelable { .token = token_index },
911 };
912 return tree;881 return tree;
913 }882 }
914883
915 putBackToken(&tok_it, &tree);884 prevToken(&tok_it, &tree);
916 continue;885 continue;
917 },886 },
918 }887 }
...@@ -923,112 +892,105 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -923,112 +892,105 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
923 const token_ptr = token.ptr;892 const token_ptr = token.ptr;
924 switch (token_ptr.id) {893 switch (token_ptr.id) {
925 Token.Id.Keyword_while => {894 Token.Id.Keyword_while => {
926 stack.append(State {895 stack.append(State{
927 .While = LoopCtx {896 .While = LoopCtx{
928 .inline_token = ctx.inline_token,897 .inline_token = ctx.inline_token,
929 .label = ctx.label,898 .label = ctx.label,
930 .loop_token = token_index,899 .loop_token = token_index,
931 .opt_ctx = ctx.opt_ctx.toRequired(),900 .opt_ctx = ctx.opt_ctx.toRequired(),
932 }901 },
933 }) catch unreachable;902 }) catch unreachable;
934 continue;903 continue;
935 },904 },
936 Token.Id.Keyword_for => {905 Token.Id.Keyword_for => {
937 stack.append(State {906 stack.append(State{
938 .For = LoopCtx {907 .For = LoopCtx{
939 .inline_token = ctx.inline_token,908 .inline_token = ctx.inline_token,
940 .label = ctx.label,909 .label = ctx.label,
941 .loop_token = token_index,910 .loop_token = token_index,
942 .opt_ctx = ctx.opt_ctx.toRequired(),911 .opt_ctx = ctx.opt_ctx.toRequired(),
943 }912 },
944 }) catch unreachable;913 }) catch unreachable;
945 continue;914 continue;
946 },915 },
947 else => {916 else => {
948 if (ctx.opt_ctx != OptionalCtx.Optional) {917 if (ctx.opt_ctx != OptionalCtx.Optional) {
949 *(try tree.errors.addOne()) = Error {918 ((try tree.errors.addOne())).* = Error{ .ExpectedInlinable = Error.ExpectedInlinable{ .token = token_index } };
950 .ExpectedInlinable = Error.ExpectedInlinable { .token = token_index },
951 };
952 return tree;919 return tree;
953 }920 }
954921
955 putBackToken(&tok_it, &tree);922 prevToken(&tok_it, &tree);
956 continue;923 continue;
957 },924 },
958 }925 }
959 },926 },
960 State.While => |ctx| {927 State.While => |ctx| {
961 const node = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.While,928 const node = try arena.construct(ast.Node.While{
962 ast.Node.While {929 .base = ast.Node{ .id = ast.Node.Id.While },
963 .base = undefined,930 .label = ctx.label,
964 .label = ctx.label,931 .inline_token = ctx.inline_token,
965 .inline_token = ctx.inline_token,932 .while_token = ctx.loop_token,
966 .while_token = ctx.loop_token,933 .condition = undefined,
967 .condition = undefined,934 .payload = null,
968 .payload = null,935 .continue_expr = null,
969 .continue_expr = null,936 .body = undefined,
970 .body = undefined,937 .@"else" = null,
971 .@"else" = null,938 });
972 }939 ctx.opt_ctx.store(&node.base);
973 );940 stack.append(State{ .Else = &node.@"else" }) catch unreachable;
974 stack.append(State { .Else = &node.@"else" }) catch unreachable;941 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });
975 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });942 try stack.append(State{ .WhileContinueExpr = &node.continue_expr });
976 try stack.append(State { .WhileContinueExpr = &node.continue_expr });943 try stack.append(State{ .IfToken = Token.Id.Colon });
977 try stack.append(State { .IfToken = Token.Id.Colon });944 try stack.append(State{ .PointerPayload = OptionalCtx{ .Optional = &node.payload } });
978 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });945 try stack.append(State{ .ExpectToken = Token.Id.RParen });
979 try stack.append(State { .ExpectToken = Token.Id.RParen });946 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.condition } });
980 try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } });947 try stack.append(State{ .ExpectToken = Token.Id.LParen });
981 try stack.append(State { .ExpectToken = Token.Id.LParen });
982 continue;948 continue;
983 },949 },
984 State.WhileContinueExpr => |dest| {950 State.WhileContinueExpr => |dest| {
985 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;951 stack.append(State{ .ExpectToken = Token.Id.RParen }) catch unreachable;
986 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = dest } });952 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .RequiredNull = dest } });
987 try stack.append(State { .ExpectToken = Token.Id.LParen });953 try stack.append(State{ .ExpectToken = Token.Id.LParen });
988 continue;954 continue;
989 },955 },
990 State.For => |ctx| {956 State.For => |ctx| {
991 const node = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.For,957 const node = try arena.construct(ast.Node.For{
992 ast.Node.For {958 .base = ast.Node{ .id = ast.Node.Id.For },
993 .base = undefined,959 .label = ctx.label,
994 .label = ctx.label,960 .inline_token = ctx.inline_token,
995 .inline_token = ctx.inline_token,961 .for_token = ctx.loop_token,
996 .for_token = ctx.loop_token,962 .array_expr = undefined,
997 .array_expr = undefined,963 .payload = null,
998 .payload = null,964 .body = undefined,
999 .body = undefined,965 .@"else" = null,
1000 .@"else" = null,966 });
1001 }967 ctx.opt_ctx.store(&node.base);
1002 );968 stack.append(State{ .Else = &node.@"else" }) catch unreachable;
1003 stack.append(State { .Else = &node.@"else" }) catch unreachable;969 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });
1004 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });970 try stack.append(State{ .PointerIndexPayload = OptionalCtx{ .Optional = &node.payload } });
1005 try stack.append(State { .PointerIndexPayload = OptionalCtx { .Optional = &node.payload } });971 try stack.append(State{ .ExpectToken = Token.Id.RParen });
1006 try stack.append(State { .ExpectToken = Token.Id.RParen });972 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.array_expr } });
1007 try stack.append(State { .Expression = OptionalCtx { .Required = &node.array_expr } });973 try stack.append(State{ .ExpectToken = Token.Id.LParen });
1008 try stack.append(State { .ExpectToken = Token.Id.LParen });
1009 continue;974 continue;
1010 },975 },
1011 State.Else => |dest| {976 State.Else => |dest| {
1012 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {977 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {
1013 const node = try createNode(arena, ast.Node.Else,978 const node = try arena.construct(ast.Node.Else{
1014 ast.Node.Else {979 .base = ast.Node{ .id = ast.Node.Id.Else },
1015 .base = undefined,980 .else_token = else_token,
1016 .else_token = else_token,981 .payload = null,
1017 .payload = null,982 .body = undefined,
1018 .body = undefined,983 });
1019 }984 dest.* = node;
1020 );
1021 *dest = node;
1022985
1023 stack.append(State { .Expression = OptionalCtx { .Required = &node.body } }) catch unreachable;986 stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } }) catch unreachable;
1024 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });987 try stack.append(State{ .Payload = OptionalCtx{ .Optional = &node.payload } });
1025 continue;988 continue;
1026 } else {989 } else {
1027 continue;990 continue;
1028 }991 }
1029 },992 },
1030993
1031
1032 State.Block => |block| {994 State.Block => |block| {
1033 const token = nextToken(&tok_it, &tree);995 const token = nextToken(&tok_it, &tree);
1034 const token_index = token.index;996 const token_index = token.index;
...@@ -1039,17 +1001,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1039,17 +1001,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1039 continue;1001 continue;
1040 },1002 },
1041 else => {1003 else => {
1042 putBackToken(&tok_it, &tree);1004 prevToken(&tok_it, &tree);
1043 stack.append(State { .Block = block }) catch unreachable;1005 stack.append(State{ .Block = block }) catch unreachable;
1044
1045 var any_comments = false;
1046 while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| {
1047 try block.statements.push(&line_comment.base);
1048 any_comments = true;
1049 }
1050 if (any_comments) continue;
10511006
1052 try stack.append(State { .Statement = block });1007 try stack.append(State{ .Statement = block });
1053 continue;1008 continue;
1054 },1009 },
1055 }1010 }
...@@ -1060,17 +1015,17 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1060,17 +1015,17 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1060 const token_ptr = token.ptr;1015 const token_ptr = token.ptr;
1061 switch (token_ptr.id) {1016 switch (token_ptr.id) {
1062 Token.Id.Keyword_comptime => {1017 Token.Id.Keyword_comptime => {
1063 stack.append(State {1018 stack.append(State{
1064 .ComptimeStatement = ComptimeStatementCtx {1019 .ComptimeStatement = ComptimeStatementCtx{
1065 .comptime_token = token_index,1020 .comptime_token = token_index,
1066 .block = block,1021 .block = block,
1067 }1022 },
1068 }) catch unreachable;1023 }) catch unreachable;
1069 continue;1024 continue;
1070 },1025 },
1071 Token.Id.Keyword_var, Token.Id.Keyword_const => {1026 Token.Id.Keyword_var, Token.Id.Keyword_const => {
1072 stack.append(State {1027 stack.append(State{
1073 .VarDecl = VarDeclCtx {1028 .VarDecl = VarDeclCtx{
1074 .comments = null,1029 .comments = null,
1075 .visib_token = null,1030 .visib_token = null,
1076 .comptime_token = null,1031 .comptime_token = null,
...@@ -1078,15 +1033,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1078,15 +1033,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1078 .lib_name = null,1033 .lib_name = null,
1079 .mut_token = token_index,1034 .mut_token = token_index,
1080 .list = &block.statements,1035 .list = &block.statements,
1081 }1036 },
1082 }) catch unreachable;1037 }) catch unreachable;
1083 continue;1038 continue;
1084 },1039 },
1085 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {1040 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
1086 const node = try arena.construct(ast.Node.Defer {1041 const node = try arena.construct(ast.Node.Defer{
1087 .base = ast.Node {1042 .base = ast.Node{ .id = ast.Node.Id.Defer },
1088 .id = ast.Node.Id.Defer,
1089 },
1090 .defer_token = token_index,1043 .defer_token = token_index,
1091 .kind = switch (token_ptr.id) {1044 .kind = switch (token_ptr.id) {
1092 Token.Id.Keyword_defer => ast.Node.Defer.Kind.Unconditional,1045 Token.Id.Keyword_defer => ast.Node.Defer.Kind.Unconditional,
...@@ -1096,15 +1049,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1096,15 +1049,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1096 .expr = undefined,1049 .expr = undefined,
1097 });1050 });
1098 const node_ptr = try block.statements.addOne();1051 const node_ptr = try block.statements.addOne();
1099 *node_ptr = &node.base;1052 node_ptr.* = &node.base;
11001053
1101 stack.append(State { .Semicolon = node_ptr }) catch unreachable;1054 stack.append(State{ .Semicolon = node_ptr }) catch unreachable;
1102 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });1055 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
1103 continue;1056 continue;
1104 },1057 },
1105 Token.Id.LBrace => {1058 Token.Id.LBrace => {
1106 const inner_block = try arena.construct(ast.Node.Block {1059 const inner_block = try arena.construct(ast.Node.Block{
1107 .base = ast.Node { .id = ast.Node.Id.Block },1060 .base = ast.Node{ .id = ast.Node.Id.Block },
1108 .label = null,1061 .label = null,
1109 .lbrace = token_index,1062 .lbrace = token_index,
1110 .statements = ast.Node.Block.StatementList.init(arena),1063 .statements = ast.Node.Block.StatementList.init(arena),
...@@ -1112,16 +1065,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1112,16 +1065,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1112 });1065 });
1113 try block.statements.push(&inner_block.base);1066 try block.statements.push(&inner_block.base);
11141067
1115 stack.append(State { .Block = inner_block }) catch unreachable;1068 stack.append(State{ .Block = inner_block }) catch unreachable;
1116 continue;1069 continue;
1117 },1070 },
1118 else => {1071 else => {
1119 putBackToken(&tok_it, &tree);1072 prevToken(&tok_it, &tree);
1120 const statement = try block.statements.addOne();1073 const statement = try block.statements.addOne();
1121 try stack.append(State { .Semicolon = statement });1074 try stack.append(State{ .Semicolon = statement });
1122 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } });1075 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } });
1123 continue;1076 continue;
1124 }1077 },
1125 }1078 }
1126 },1079 },
1127 State.ComptimeStatement => |ctx| {1080 State.ComptimeStatement => |ctx| {
...@@ -1130,8 +1083,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1130,8 +1083,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1130 const token_ptr = token.ptr;1083 const token_ptr = token.ptr;
1131 switch (token_ptr.id) {1084 switch (token_ptr.id) {
1132 Token.Id.Keyword_var, Token.Id.Keyword_const => {1085 Token.Id.Keyword_var, Token.Id.Keyword_const => {
1133 stack.append(State {1086 stack.append(State{
1134 .VarDecl = VarDeclCtx {1087 .VarDecl = VarDeclCtx{
1135 .comments = null,1088 .comments = null,
1136 .visib_token = null,1089 .visib_token = null,
1137 .comptime_token = ctx.comptime_token,1090 .comptime_token = ctx.comptime_token,
...@@ -1139,24 +1092,24 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1139,24 +1092,24 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1139 .lib_name = null,1092 .lib_name = null,
1140 .mut_token = token_index,1093 .mut_token = token_index,
1141 .list = &ctx.block.statements,1094 .list = &ctx.block.statements,
1142 }1095 },
1143 }) catch unreachable;1096 }) catch unreachable;
1144 continue;1097 continue;
1145 },1098 },
1146 else => {1099 else => {
1147 putBackToken(&tok_it, &tree);1100 prevToken(&tok_it, &tree);
1148 putBackToken(&tok_it, &tree);1101 prevToken(&tok_it, &tree);
1149 const statement = try ctx.block.statements.addOne();1102 const statement = try ctx.block.statements.addOne();
1150 try stack.append(State { .Semicolon = statement });1103 try stack.append(State{ .Semicolon = statement });
1151 try stack.append(State { .Expression = OptionalCtx { .Required = statement } });1104 try stack.append(State{ .Expression = OptionalCtx{ .Required = statement } });
1152 continue;1105 continue;
1153 }1106 },
1154 }1107 }
1155 },1108 },
1156 State.Semicolon => |node_ptr| {1109 State.Semicolon => |node_ptr| {
1157 const node = *node_ptr;1110 const node = node_ptr.*;
1158 if (node.requireSemiColon()) {1111 if (node.requireSemiColon()) {
1159 stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable;1112 stack.append(State{ .ExpectToken = Token.Id.Semicolon }) catch unreachable;
1160 continue;1113 continue;
1161 }1114 }
1162 continue;1115 continue;
...@@ -1167,28 +1120,33 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1167,28 +1120,33 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1167 const lbracket_index = lbracket.index;1120 const lbracket_index = lbracket.index;
1168 const lbracket_ptr = lbracket.ptr;1121 const lbracket_ptr = lbracket.ptr;
1169 if (lbracket_ptr.id != Token.Id.LBracket) {1122 if (lbracket_ptr.id != Token.Id.LBracket) {
1170 putBackToken(&tok_it, &tree);1123 prevToken(&tok_it, &tree);
1171 continue;1124 continue;
1172 }1125 }
11731126
1174 const node = try createNode(arena, ast.Node.AsmOutput,1127 const node = try arena.construct(ast.Node.AsmOutput{
1175 ast.Node.AsmOutput {1128 .base = ast.Node{ .id = ast.Node.Id.AsmOutput },
1176 .base = undefined,1129 .lbracket = lbracket_index,
1177 .symbolic_name = undefined,1130 .symbolic_name = undefined,
1178 .constraint = undefined,1131 .constraint = undefined,
1179 .kind = undefined,1132 .kind = undefined,
1180 }1133 .rparen = undefined,
1181 );1134 });
1182 try items.push(node);1135 try items.push(node);
11831136
1184 stack.append(State { .AsmOutputItems = items }) catch unreachable;1137 stack.append(State{ .AsmOutputItems = items }) catch unreachable;
1185 try stack.append(State { .IfToken = Token.Id.Comma });1138 try stack.append(State{ .IfToken = Token.Id.Comma });
1186 try stack.append(State { .ExpectToken = Token.Id.RParen });1139 try stack.append(State{
1187 try stack.append(State { .AsmOutputReturnOrType = node });1140 .ExpectTokenSave = ExpectTokenSave{
1188 try stack.append(State { .ExpectToken = Token.Id.LParen });1141 .id = Token.Id.RParen,
1189 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });1142 .ptr = &node.rparen,
1190 try stack.append(State { .ExpectToken = Token.Id.RBracket });1143 },
1191 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });1144 });
1145 try stack.append(State{ .AsmOutputReturnOrType = node });
1146 try stack.append(State{ .ExpectToken = Token.Id.LParen });
1147 try stack.append(State{ .StringLiteral = OptionalCtx{ .Required = &node.constraint } });
1148 try stack.append(State{ .ExpectToken = Token.Id.RBracket });
1149 try stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.symbolic_name } });
1192 continue;1150 continue;
1193 },1151 },
1194 State.AsmOutputReturnOrType => |node| {1152 State.AsmOutputReturnOrType => |node| {
...@@ -1197,20 +1155,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1197,20 +1155,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1197 const token_ptr = token.ptr;1155 const token_ptr = token.ptr;
1198 switch (token_ptr.id) {1156 switch (token_ptr.id) {
1199 Token.Id.Identifier => {1157 Token.Id.Identifier => {
1200 node.kind = ast.Node.AsmOutput.Kind { .Variable = try createLiteral(arena, ast.Node.Identifier, token_index) };1158 node.kind = ast.Node.AsmOutput.Kind{ .Variable = try createLiteral(arena, ast.Node.Identifier, token_index) };
1201 continue;1159 continue;
1202 },1160 },
1203 Token.Id.Arrow => {1161 Token.Id.Arrow => {
1204 node.kind = ast.Node.AsmOutput.Kind { .Return = undefined };1162 node.kind = ast.Node.AsmOutput.Kind{ .Return = undefined };
1205 try stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.kind.Return } });1163 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &node.kind.Return } });
1206 continue;1164 continue;
1207 },1165 },
1208 else => {1166 else => {
1209 *(try tree.errors.addOne()) = Error {1167 ((try tree.errors.addOne())).* = Error{ .ExpectedAsmOutputReturnOrType = Error.ExpectedAsmOutputReturnOrType{ .token = token_index } };
1210 .ExpectedAsmOutputReturnOrType = Error.ExpectedAsmOutputReturnOrType {
1211 .token = token_index,
1212 },
1213 };
1214 return tree;1168 return tree;
1215 },1169 },
1216 }1170 }
...@@ -1220,55 +1174,61 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1220,55 +1174,61 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1220 const lbracket_index = lbracket.index;1174 const lbracket_index = lbracket.index;
1221 const lbracket_ptr = lbracket.ptr;1175 const lbracket_ptr = lbracket.ptr;
1222 if (lbracket_ptr.id != Token.Id.LBracket) {1176 if (lbracket_ptr.id != Token.Id.LBracket) {
1223 putBackToken(&tok_it, &tree);1177 prevToken(&tok_it, &tree);
1224 continue;1178 continue;
1225 }1179 }
12261180
1227 const node = try createNode(arena, ast.Node.AsmInput,1181 const node = try arena.construct(ast.Node.AsmInput{
1228 ast.Node.AsmInput {1182 .base = ast.Node{ .id = ast.Node.Id.AsmInput },
1229 .base = undefined,1183 .lbracket = lbracket_index,
1230 .symbolic_name = undefined,1184 .symbolic_name = undefined,
1231 .constraint = undefined,1185 .constraint = undefined,
1232 .expr = undefined,1186 .expr = undefined,
1233 }1187 .rparen = undefined,
1234 );1188 });
1235 try items.push(node);1189 try items.push(node);
12361190
1237 stack.append(State { .AsmInputItems = items }) catch unreachable;1191 stack.append(State{ .AsmInputItems = items }) catch unreachable;
1238 try stack.append(State { .IfToken = Token.Id.Comma });1192 try stack.append(State{ .IfToken = Token.Id.Comma });
1239 try stack.append(State { .ExpectToken = Token.Id.RParen });1193 try stack.append(State{
1240 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });1194 .ExpectTokenSave = ExpectTokenSave{
1241 try stack.append(State { .ExpectToken = Token.Id.LParen });1195 .id = Token.Id.RParen,
1242 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });1196 .ptr = &node.rparen,
1243 try stack.append(State { .ExpectToken = Token.Id.RBracket });1197 },
1244 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });1198 });
1199 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
1200 try stack.append(State{ .ExpectToken = Token.Id.LParen });
1201 try stack.append(State{ .StringLiteral = OptionalCtx{ .Required = &node.constraint } });
1202 try stack.append(State{ .ExpectToken = Token.Id.RBracket });
1203 try stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.symbolic_name } });
1245 continue;1204 continue;
1246 },1205 },
1247 State.AsmClobberItems => |items| {1206 State.AsmClobberItems => |items| {
1248 stack.append(State { .AsmClobberItems = items }) catch unreachable;1207 while (eatToken(&tok_it, &tree, Token.Id.StringLiteral)) |strlit| {
1249 try stack.append(State { .IfToken = Token.Id.Comma });1208 try items.push(strlit);
1250 try stack.append(State { .StringLiteral = OptionalCtx { .Required = try items.addOne() } });1209 if (eatToken(&tok_it, &tree, Token.Id.Comma) == null)
1210 break;
1211 }
1251 continue;1212 continue;
1252 },1213 },
12531214
1254
1255 State.ExprListItemOrEnd => |list_state| {1215 State.ExprListItemOrEnd => |list_state| {
1256 if (eatToken(&tok_it, &tree, list_state.end)) |token_index| {1216 if (eatToken(&tok_it, &tree, list_state.end)) |token_index| {
1257 *list_state.ptr = token_index;1217 (list_state.ptr).* = token_index;
1258 continue;1218 continue;
1259 }1219 }
12601220
1261 stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable;1221 stack.append(State{ .ExprListCommaOrEnd = list_state }) catch unreachable;
1262 try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } });1222 try stack.append(State{ .Expression = OptionalCtx{ .Required = try list_state.list.addOne() } });
1263 continue;1223 continue;
1264 },1224 },
1265 State.ExprListCommaOrEnd => |list_state| {1225 State.ExprListCommaOrEnd => |list_state| {
1266 switch (expectCommaOrEnd(&tok_it, &tree, list_state.end)) {1226 switch (expectCommaOrEnd(&tok_it, &tree, list_state.end)) {
1267 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {1227 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
1268 *list_state.ptr = end;1228 (list_state.ptr).* = end;
1269 continue;1229 continue;
1270 } else {1230 } else {
1271 stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable;1231 stack.append(State{ .ExprListItemOrEnd = list_state }) catch unreachable;
1272 continue;1232 continue;
1273 },1233 },
1274 ExpectCommaOrEndResult.parse_error => |e| {1234 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1278,49 +1238,43 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1278,49 +1238,43 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1278 }1238 }
1279 },1239 },
1280 State.FieldInitListItemOrEnd => |list_state| {1240 State.FieldInitListItemOrEnd => |list_state| {
1281 while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| {
1282 try list_state.list.push(&line_comment.base);
1283 }
1284
1285 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {1241 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {
1286 *list_state.ptr = rbrace;1242 (list_state.ptr).* = rbrace;
1287 continue;1243 continue;
1288 }1244 }
12891245
1290 const node = try arena.construct(ast.Node.FieldInitializer {1246 const node = try arena.construct(ast.Node.FieldInitializer{
1291 .base = ast.Node {1247 .base = ast.Node{ .id = ast.Node.Id.FieldInitializer },
1292 .id = ast.Node.Id.FieldInitializer,
1293 },
1294 .period_token = undefined,1248 .period_token = undefined,
1295 .name_token = undefined,1249 .name_token = undefined,
1296 .expr = undefined,1250 .expr = undefined,
1297 });1251 });
1298 try list_state.list.push(&node.base);1252 try list_state.list.push(&node.base);
12991253
1300 stack.append(State { .FieldInitListCommaOrEnd = list_state }) catch unreachable;1254 stack.append(State{ .FieldInitListCommaOrEnd = list_state }) catch unreachable;
1301 try stack.append(State { .Expression = OptionalCtx{ .Required = &node.expr } });1255 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
1302 try stack.append(State { .ExpectToken = Token.Id.Equal });1256 try stack.append(State{ .ExpectToken = Token.Id.Equal });
1303 try stack.append(State {1257 try stack.append(State{
1304 .ExpectTokenSave = ExpectTokenSave {1258 .ExpectTokenSave = ExpectTokenSave{
1305 .id = Token.Id.Identifier,1259 .id = Token.Id.Identifier,
1306 .ptr = &node.name_token,1260 .ptr = &node.name_token,
1307 }1261 },
1308 });1262 });
1309 try stack.append(State {1263 try stack.append(State{
1310 .ExpectTokenSave = ExpectTokenSave {1264 .ExpectTokenSave = ExpectTokenSave{
1311 .id = Token.Id.Period,1265 .id = Token.Id.Period,
1312 .ptr = &node.period_token,1266 .ptr = &node.period_token,
1313 }1267 },
1314 });1268 });
1315 continue;1269 continue;
1316 },1270 },
1317 State.FieldInitListCommaOrEnd => |list_state| {1271 State.FieldInitListCommaOrEnd => |list_state| {
1318 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {1272 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {
1319 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {1273 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
1320 *list_state.ptr = end;1274 (list_state.ptr).* = end;
1321 continue;1275 continue;
1322 } else {1276 } else {
1323 stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable;1277 stack.append(State{ .FieldInitListItemOrEnd = list_state }) catch unreachable;
1324 continue;1278 continue;
1325 },1279 },
1326 ExpectCommaOrEndResult.parse_error => |e| {1280 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1335,7 +1289,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1335,7 +1289,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1335 container_decl.rbrace_token = end;1289 container_decl.rbrace_token = end;
1336 continue;1290 continue;
1337 } else {1291 } else {
1338 try stack.append(State { .ContainerDecl = container_decl });1292 try stack.append(State{ .ContainerDecl = container_decl });
1339 continue;1293 continue;
1340 },1294 },
1341 ExpectCommaOrEndResult.parse_error => |e| {1295 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1345,28 +1299,24 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1345,28 +1299,24 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1345 }1299 }
1346 },1300 },
1347 State.ErrorTagListItemOrEnd => |list_state| {1301 State.ErrorTagListItemOrEnd => |list_state| {
1348 while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| {
1349 try list_state.list.push(&line_comment.base);
1350 }
1351
1352 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {1302 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {
1353 *list_state.ptr = rbrace;1303 (list_state.ptr).* = rbrace;
1354 continue;1304 continue;
1355 }1305 }
13561306
1357 const node_ptr = try list_state.list.addOne();1307 const node_ptr = try list_state.list.addOne();
13581308
1359 try stack.append(State { .ErrorTagListCommaOrEnd = list_state });1309 try stack.append(State{ .ErrorTagListCommaOrEnd = list_state });
1360 try stack.append(State { .ErrorTag = node_ptr });1310 try stack.append(State{ .ErrorTag = node_ptr });
1361 continue;1311 continue;
1362 },1312 },
1363 State.ErrorTagListCommaOrEnd => |list_state| {1313 State.ErrorTagListCommaOrEnd => |list_state| {
1364 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {1314 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {
1365 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {1315 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
1366 *list_state.ptr = end;1316 (list_state.ptr).* = end;
1367 continue;1317 continue;
1368 } else {1318 } else {
1369 stack.append(State { .ErrorTagListItemOrEnd = list_state }) catch unreachable;1319 stack.append(State{ .ErrorTagListItemOrEnd = list_state }) catch unreachable;
1370 continue;1320 continue;
1371 },1321 },
1372 ExpectCommaOrEndResult.parse_error => |e| {1322 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1376,40 +1326,35 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1376,40 +1326,35 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1376 }1326 }
1377 },1327 },
1378 State.SwitchCaseOrEnd => |list_state| {1328 State.SwitchCaseOrEnd => |list_state| {
1379 while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| {
1380 try list_state.list.push(&line_comment.base);
1381 }
1382
1383 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {1329 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {
1384 *list_state.ptr = rbrace;1330 (list_state.ptr).* = rbrace;
1385 continue;1331 continue;
1386 }1332 }
13871333
1388 const comments = try eatDocComments(arena, &tok_it, &tree);1334 const comments = try eatDocComments(arena, &tok_it, &tree);
1389 const node = try arena.construct(ast.Node.SwitchCase {1335 const node = try arena.construct(ast.Node.SwitchCase{
1390 .base = ast.Node {1336 .base = ast.Node{ .id = ast.Node.Id.SwitchCase },
1391 .id = ast.Node.Id.SwitchCase,
1392 },
1393 .items = ast.Node.SwitchCase.ItemList.init(arena),1337 .items = ast.Node.SwitchCase.ItemList.init(arena),
1394 .payload = null,1338 .payload = null,
1395 .expr = undefined,1339 .expr = undefined,
1340 .arrow_token = undefined,
1396 });1341 });
1397 try list_state.list.push(&node.base);1342 try list_state.list.push(&node.base);
1398 try stack.append(State { .SwitchCaseCommaOrEnd = list_state });1343 try stack.append(State{ .SwitchCaseCommaOrEnd = list_state });
1399 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .Required = &node.expr } });1344 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
1400 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });1345 try stack.append(State{ .PointerPayload = OptionalCtx{ .Optional = &node.payload } });
1401 try stack.append(State { .SwitchCaseFirstItem = &node.items });1346 try stack.append(State{ .SwitchCaseFirstItem = node });
14021347
1403 continue;1348 continue;
1404 },1349 },
14051350
1406 State.SwitchCaseCommaOrEnd => |list_state| {1351 State.SwitchCaseCommaOrEnd => |list_state| {
1407 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {1352 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {
1408 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {1353 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
1409 *list_state.ptr = end;1354 (list_state.ptr).* = end;
1410 continue;1355 continue;
1411 } else {1356 } else {
1412 try stack.append(State { .SwitchCaseOrEnd = list_state });1357 try stack.append(State{ .SwitchCaseOrEnd = list_state });
1413 continue;1358 continue;
1414 },1359 },
1415 ExpectCommaOrEndResult.parse_error => |e| {1360 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1419,34 +1364,50 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1419,34 +1364,50 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1419 }1364 }
1420 },1365 },
14211366
1422 State.SwitchCaseFirstItem => |case_items| {1367 State.SwitchCaseFirstItem => |switch_case| {
1423 const token = nextToken(&tok_it, &tree);1368 const token = nextToken(&tok_it, &tree);
1424 const token_index = token.index;1369 const token_index = token.index;
1425 const token_ptr = token.ptr;1370 const token_ptr = token.ptr;
1426 if (token_ptr.id == Token.Id.Keyword_else) {1371 if (token_ptr.id == Token.Id.Keyword_else) {
1427 const else_node = try arena.construct(ast.Node.SwitchElse {1372 const else_node = try arena.construct(ast.Node.SwitchElse{
1428 .base = ast.Node{ .id = ast.Node.Id.SwitchElse},1373 .base = ast.Node{ .id = ast.Node.Id.SwitchElse },
1429 .token = token_index,1374 .token = token_index,
1430 });1375 });
1431 try case_items.push(&else_node.base);1376 try switch_case.items.push(&else_node.base);
14321377
1433 try stack.append(State { .ExpectToken = Token.Id.EqualAngleBracketRight });1378 try stack.append(State{
1379 .ExpectTokenSave = ExpectTokenSave{
1380 .id = Token.Id.EqualAngleBracketRight,
1381 .ptr = &switch_case.arrow_token,
1382 },
1383 });
1434 continue;1384 continue;
1435 } else {1385 } else {
1436 putBackToken(&tok_it, &tree);1386 prevToken(&tok_it, &tree);
1437 try stack.append(State { .SwitchCaseItem = case_items });1387 stack.append(State{ .SwitchCaseItemCommaOrEnd = switch_case }) catch unreachable;
1388 try stack.append(State{ .RangeExpressionBegin = OptionalCtx{ .Required = try switch_case.items.addOne() } });
1438 continue;1389 continue;
1439 }1390 }
1440 },1391 },
1441 State.SwitchCaseItem => |case_items| {1392 State.SwitchCaseItemOrEnd => |switch_case| {
1442 stack.append(State { .SwitchCaseItemCommaOrEnd = case_items }) catch unreachable;1393 const token = nextToken(&tok_it, &tree);
1443 try stack.append(State { .RangeExpressionBegin = OptionalCtx { .Required = try case_items.addOne() } });1394 if (token.ptr.id == Token.Id.EqualAngleBracketRight) {
1395 switch_case.arrow_token = token.index;
1396 continue;
1397 } else {
1398 prevToken(&tok_it, &tree);
1399 stack.append(State{ .SwitchCaseItemCommaOrEnd = switch_case }) catch unreachable;
1400 try stack.append(State{ .RangeExpressionBegin = OptionalCtx{ .Required = try switch_case.items.addOne() } });
1401 continue;
1402 }
1444 },1403 },
1445 State.SwitchCaseItemCommaOrEnd => |case_items| {1404 State.SwitchCaseItemCommaOrEnd => |switch_case| {
1446 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.EqualAngleBracketRight)) {1405 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.EqualAngleBracketRight)) {
1447 ExpectCommaOrEndResult.end_token => |t| {1406 ExpectCommaOrEndResult.end_token => |end_token| {
1448 if (t == null) {1407 if (end_token) |t| {
1449 stack.append(State { .SwitchCaseItem = case_items }) catch unreachable;1408 switch_case.arrow_token = t;
1409 } else {
1410 stack.append(State{ .SwitchCaseItemOrEnd = switch_case }) catch unreachable;
1450 }1411 }
1451 continue;1412 continue;
1452 },1413 },
...@@ -1458,10 +1419,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1458,10 +1419,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1458 continue;1419 continue;
1459 },1420 },
14601421
1461
1462 State.SuspendBody => |suspend_node| {1422 State.SuspendBody => |suspend_node| {
1463 if (suspend_node.payload != null) {1423 if (suspend_node.payload != null) {
1464 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = &suspend_node.body } });1424 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .RequiredNull = &suspend_node.body } });
1465 }1425 }
1466 continue;1426 continue;
1467 },1427 },
...@@ -1471,13 +1431,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1471,13 +1431,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1471 }1431 }
14721432
1473 async_node.rangle_bracket = TokenIndex(0);1433 async_node.rangle_bracket = TokenIndex(0);
1474 try stack.append(State {1434 try stack.append(State{
1475 .ExpectTokenSave = ExpectTokenSave {1435 .ExpectTokenSave = ExpectTokenSave{
1476 .id = Token.Id.AngleBracketRight,1436 .id = Token.Id.AngleBracketRight,
1477 .ptr = &??async_node.rangle_bracket,1437 .ptr = &??async_node.rangle_bracket,
1478 }1438 },
1479 });1439 });
1480 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &async_node.allocator_type } });1440 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .RequiredNull = &async_node.allocator_type } });
1481 continue;1441 continue;
1482 },1442 },
1483 State.AsyncEnd => |ctx| {1443 State.AsyncEnd => |ctx| {
...@@ -1496,27 +1456,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1496,27 +1456,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1496 continue;1456 continue;
1497 }1457 }
14981458
1499 *(try tree.errors.addOne()) = Error {1459 ((try tree.errors.addOne())).* = Error{ .ExpectedCall = Error.ExpectedCall{ .node = node } };
1500 .ExpectedCall = Error.ExpectedCall { .node = node },
1501 };
1502 return tree;1460 return tree;
1503 },1461 },
1504 else => {1462 else => {
1505 *(try tree.errors.addOne()) = Error {1463 ((try tree.errors.addOne())).* = Error{ .ExpectedCallOrFnProto = Error.ExpectedCallOrFnProto{ .node = node } };
1506 .ExpectedCallOrFnProto = Error.ExpectedCallOrFnProto { .node = node },
1507 };
1508 return tree;1464 return tree;
1509 }1465 },
1510 }1466 }
1511 },1467 },
15121468
1513
1514 State.ExternType => |ctx| {1469 State.ExternType => |ctx| {
1515 if (eatToken(&tok_it, &tree, Token.Id.Keyword_fn)) |fn_token| {1470 if (eatToken(&tok_it, &tree, Token.Id.Keyword_fn)) |fn_token| {
1516 const fn_proto = try arena.construct(ast.Node.FnProto {1471 const fn_proto = try arena.construct(ast.Node.FnProto{
1517 .base = ast.Node {1472 .base = ast.Node{ .id = ast.Node.Id.FnProto },
1518 .id = ast.Node.Id.FnProto,
1519 },
1520 .doc_comments = ctx.comments,1473 .doc_comments = ctx.comments,
1521 .visib_token = null,1474 .visib_token = null,
1522 .name_token = null,1475 .name_token = null,
...@@ -1532,15 +1485,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1532,15 +1485,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1532 .align_expr = null,1485 .align_expr = null,
1533 });1486 });
1534 ctx.opt_ctx.store(&fn_proto.base);1487 ctx.opt_ctx.store(&fn_proto.base);
1535 stack.append(State { .FnProto = fn_proto }) catch unreachable;1488 stack.append(State{ .FnProto = fn_proto }) catch unreachable;
1536 continue;1489 continue;
1537 }1490 }
15381491
1539 stack.append(State {1492 stack.append(State{
1540 .ContainerKind = ContainerKindCtx {1493 .ContainerKind = ContainerKindCtx{
1541 .opt_ctx = ctx.opt_ctx,1494 .opt_ctx = ctx.opt_ctx,
1542 .ltoken = ctx.extern_token,1495 .layout_token = ctx.extern_token,
1543 .layout = ast.Node.ContainerDecl.Layout.Extern,
1544 },1496 },
1545 }) catch unreachable;1497 }) catch unreachable;
1546 continue;1498 continue;
...@@ -1552,20 +1504,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1552,20 +1504,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1552 switch (token_ptr.id) {1504 switch (token_ptr.id) {
1553 Token.Id.Ellipsis2 => {1505 Token.Id.Ellipsis2 => {
1554 const start = node.op.ArrayAccess;1506 const start = node.op.ArrayAccess;
1555 node.op = ast.Node.SuffixOp.Op {1507 node.op = ast.Node.SuffixOp.Op{
1556 .Slice = ast.Node.SuffixOp.Op.Slice {1508 .Slice = ast.Node.SuffixOp.Op.Slice{
1557 .start = start,1509 .start = start,
1558 .end = null,1510 .end = null,
1559 }1511 },
1560 };1512 };
15611513
1562 stack.append(State {1514 stack.append(State{
1563 .ExpectTokenSave = ExpectTokenSave {1515 .ExpectTokenSave = ExpectTokenSave{
1564 .id = Token.Id.RBracket,1516 .id = Token.Id.RBracket,
1565 .ptr = &node.rtoken,1517 .ptr = &node.rtoken,
1566 }1518 },
1567 }) catch unreachable;1519 }) catch unreachable;
1568 try stack.append(State { .Expression = OptionalCtx { .Optional = &node.op.Slice.end } });1520 try stack.append(State{ .Expression = OptionalCtx{ .Optional = &node.op.Slice.end } });
1569 continue;1521 continue;
1570 },1522 },
1571 Token.Id.RBracket => {1523 Token.Id.RBracket => {
...@@ -1573,35 +1525,32 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1573,35 +1525,32 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1573 continue;1525 continue;
1574 },1526 },
1575 else => {1527 else => {
1576 *(try tree.errors.addOne()) = Error {1528 ((try tree.errors.addOne())).* = Error{ .ExpectedSliceOrRBracket = Error.ExpectedSliceOrRBracket{ .token = token_index } };
1577 .ExpectedSliceOrRBracket = Error.ExpectedSliceOrRBracket { .token = token_index },
1578 };
1579 return tree;1529 return tree;
1580 }1530 },
1581 }1531 }
1582 },1532 },
1583 State.SliceOrArrayType => |node| {1533 State.SliceOrArrayType => |node| {
1584 if (eatToken(&tok_it, &tree, Token.Id.RBracket)) |_| {1534 if (eatToken(&tok_it, &tree, Token.Id.RBracket)) |_| {
1585 node.op = ast.Node.PrefixOp.Op {1535 node.op = ast.Node.PrefixOp.Op{
1586 .SliceType = ast.Node.PrefixOp.AddrOfInfo {1536 .SliceType = ast.Node.PrefixOp.AddrOfInfo{
1587 .align_expr = null,1537 .align_info = null,
1588 .bit_offset_start_token = null,
1589 .bit_offset_end_token = null,
1590 .const_token = null,1538 .const_token = null,
1591 .volatile_token = null,1539 .volatile_token = null,
1592 }1540 },
1593 };1541 };
1594 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;1542 stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
1595 try stack.append(State { .AddrOfModifiers = &node.op.SliceType });1543 try stack.append(State{ .AddrOfModifiers = &node.op.SliceType });
1596 continue;1544 continue;
1597 }1545 }
15981546
1599 node.op = ast.Node.PrefixOp.Op { .ArrayType = undefined };1547 node.op = ast.Node.PrefixOp.Op{ .ArrayType = undefined };
1600 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;1548 stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
1601 try stack.append(State { .ExpectToken = Token.Id.RBracket });1549 try stack.append(State{ .ExpectToken = Token.Id.RBracket });
1602 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayType } });1550 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.op.ArrayType } });
1603 continue;1551 continue;
1604 },1552 },
1553
1605 State.AddrOfModifiers => |addr_of_info| {1554 State.AddrOfModifiers => |addr_of_info| {
1606 const token = nextToken(&tok_it, &tree);1555 const token = nextToken(&tok_it, &tree);
1607 const token_index = token.index;1556 const token_index = token.index;
...@@ -1609,23 +1558,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1609,23 +1558,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1609 switch (token_ptr.id) {1558 switch (token_ptr.id) {
1610 Token.Id.Keyword_align => {1559 Token.Id.Keyword_align => {
1611 stack.append(state) catch unreachable;1560 stack.append(state) catch unreachable;
1612 if (addr_of_info.align_expr != null) {1561 if (addr_of_info.align_info != null) {
1613 *(try tree.errors.addOne()) = Error {1562 ((try tree.errors.addOne())).* = Error{ .ExtraAlignQualifier = Error.ExtraAlignQualifier{ .token = token_index } };
1614 .ExtraAlignQualifier = Error.ExtraAlignQualifier { .token = token_index },
1615 };
1616 return tree;1563 return tree;
1617 }1564 }
1618 try stack.append(State { .ExpectToken = Token.Id.RParen });1565 addr_of_info.align_info = ast.Node.PrefixOp.AddrOfInfo.Align{
1619 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &addr_of_info.align_expr} });1566 .node = undefined,
1620 try stack.append(State { .ExpectToken = Token.Id.LParen });1567 .bit_range = null,
1568 };
1569 // TODO https://github.com/ziglang/zig/issues/1022
1570 const align_info = &??addr_of_info.align_info;
1571
1572 try stack.append(State{ .AlignBitRange = align_info });
1573 try stack.append(State{ .Expression = OptionalCtx{ .Required = &align_info.node } });
1574 try stack.append(State{ .ExpectToken = Token.Id.LParen });
1621 continue;1575 continue;
1622 },1576 },
1623 Token.Id.Keyword_const => {1577 Token.Id.Keyword_const => {
1624 stack.append(state) catch unreachable;1578 stack.append(state) catch unreachable;
1625 if (addr_of_info.const_token != null) {1579 if (addr_of_info.const_token != null) {
1626 *(try tree.errors.addOne()) = Error {1580 ((try tree.errors.addOne())).* = Error{ .ExtraConstQualifier = Error.ExtraConstQualifier{ .token = token_index } };
1627 .ExtraConstQualifier = Error.ExtraConstQualifier { .token = token_index },
1628 };
1629 return tree;1581 return tree;
1630 }1582 }
1631 addr_of_info.const_token = token_index;1583 addr_of_info.const_token = token_index;
...@@ -1634,21 +1586,41 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1634,21 +1586,41 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1634 Token.Id.Keyword_volatile => {1586 Token.Id.Keyword_volatile => {
1635 stack.append(state) catch unreachable;1587 stack.append(state) catch unreachable;
1636 if (addr_of_info.volatile_token != null) {1588 if (addr_of_info.volatile_token != null) {
1637 *(try tree.errors.addOne()) = Error {1589 ((try tree.errors.addOne())).* = Error{ .ExtraVolatileQualifier = Error.ExtraVolatileQualifier{ .token = token_index } };
1638 .ExtraVolatileQualifier = Error.ExtraVolatileQualifier { .token = token_index },
1639 };
1640 return tree;1590 return tree;
1641 }1591 }
1642 addr_of_info.volatile_token = token_index;1592 addr_of_info.volatile_token = token_index;
1643 continue;1593 continue;
1644 },1594 },
1645 else => {1595 else => {
1646 putBackToken(&tok_it, &tree);1596 prevToken(&tok_it, &tree);
1647 continue;1597 continue;
1648 },1598 },
1649 }1599 }
1650 },1600 },
16511601
1602 State.AlignBitRange => |align_info| {
1603 const token = nextToken(&tok_it, &tree);
1604 switch (token.ptr.id) {
1605 Token.Id.Colon => {
1606 align_info.bit_range = ast.Node.PrefixOp.AddrOfInfo.Align.BitRange(undefined);
1607 const bit_range = &??align_info.bit_range;
1608
1609 try stack.append(State{ .ExpectToken = Token.Id.RParen });
1610 try stack.append(State{ .Expression = OptionalCtx{ .Required = &bit_range.end } });
1611 try stack.append(State{ .ExpectToken = Token.Id.Colon });
1612 try stack.append(State{ .Expression = OptionalCtx{ .Required = &bit_range.start } });
1613 continue;
1614 },
1615 Token.Id.RParen => continue,
1616 else => {
1617 (try tree.errors.addOne()).* = Error{
1618 .ExpectedColonOrRParen = Error.ExpectedColonOrRParen{ .token = token.index },
1619 };
1620 return tree;
1621 },
1622 }
1623 },
16521624
1653 State.Payload => |opt_ctx| {1625 State.Payload => |opt_ctx| {
1654 const token = nextToken(&tok_it, &tree);1626 const token = nextToken(&tok_it, &tree);
...@@ -1656,8 +1628,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1656,8 +1628,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1656 const token_ptr = token.ptr;1628 const token_ptr = token.ptr;
1657 if (token_ptr.id != Token.Id.Pipe) {1629 if (token_ptr.id != Token.Id.Pipe) {
1658 if (opt_ctx != OptionalCtx.Optional) {1630 if (opt_ctx != OptionalCtx.Optional) {
1659 *(try tree.errors.addOne()) = Error {1631 ((try tree.errors.addOne())).* = Error{
1660 .ExpectedToken = Error.ExpectedToken {1632 .ExpectedToken = Error.ExpectedToken{
1661 .token = token_index,1633 .token = token_index,
1662 .expected_id = Token.Id.Pipe,1634 .expected_id = Token.Id.Pipe,
1663 },1635 },
...@@ -1665,26 +1637,25 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1665,26 +1637,25 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1665 return tree;1637 return tree;
1666 }1638 }
16671639
1668 putBackToken(&tok_it, &tree);1640 prevToken(&tok_it, &tree);
1669 continue;1641 continue;
1670 }1642 }
16711643
1672 const node = try createToCtxNode(arena, opt_ctx, ast.Node.Payload,1644 const node = try arena.construct(ast.Node.Payload{
1673 ast.Node.Payload {1645 .base = ast.Node{ .id = ast.Node.Id.Payload },
1674 .base = undefined,1646 .lpipe = token_index,
1675 .lpipe = token_index,1647 .error_symbol = undefined,
1676 .error_symbol = undefined,1648 .rpipe = undefined,
1677 .rpipe = undefined1649 });
1678 }1650 opt_ctx.store(&node.base);
1679 );
16801651
1681 stack.append(State {1652 stack.append(State{
1682 .ExpectTokenSave = ExpectTokenSave {1653 .ExpectTokenSave = ExpectTokenSave{
1683 .id = Token.Id.Pipe,1654 .id = Token.Id.Pipe,
1684 .ptr = &node.rpipe,1655 .ptr = &node.rpipe,
1685 }1656 },
1686 }) catch unreachable;1657 }) catch unreachable;
1687 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.error_symbol } });1658 try stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.error_symbol } });
1688 continue;1659 continue;
1689 },1660 },
1690 State.PointerPayload => |opt_ctx| {1661 State.PointerPayload => |opt_ctx| {
...@@ -1693,8 +1664,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1693,8 +1664,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1693 const token_ptr = token.ptr;1664 const token_ptr = token.ptr;
1694 if (token_ptr.id != Token.Id.Pipe) {1665 if (token_ptr.id != Token.Id.Pipe) {
1695 if (opt_ctx != OptionalCtx.Optional) {1666 if (opt_ctx != OptionalCtx.Optional) {
1696 *(try tree.errors.addOne()) = Error {1667 ((try tree.errors.addOne())).* = Error{
1697 .ExpectedToken = Error.ExpectedToken {1668 .ExpectedToken = Error.ExpectedToken{
1698 .token = token_index,1669 .token = token_index,
1699 .expected_id = Token.Id.Pipe,1670 .expected_id = Token.Id.Pipe,
1700 },1671 },
...@@ -1702,32 +1673,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1702,32 +1673,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1702 return tree;1673 return tree;
1703 }1674 }
17041675
1705 putBackToken(&tok_it, &tree);1676 prevToken(&tok_it, &tree);
1706 continue;1677 continue;
1707 }1678 }
17081679
1709 const node = try createToCtxNode(arena, opt_ctx, ast.Node.PointerPayload,1680 const node = try arena.construct(ast.Node.PointerPayload{
1710 ast.Node.PointerPayload {1681 .base = ast.Node{ .id = ast.Node.Id.PointerPayload },
1711 .base = undefined,1682 .lpipe = token_index,
1712 .lpipe = token_index,1683 .ptr_token = null,
1713 .ptr_token = null,1684 .value_symbol = undefined,
1714 .value_symbol = undefined,1685 .rpipe = undefined,
1715 .rpipe = undefined1686 });
1716 }1687 opt_ctx.store(&node.base);
1717 );
17181688
1719 try stack.append(State {1689 try stack.append(State{
1720 .ExpectTokenSave = ExpectTokenSave {1690 .ExpectTokenSave = ExpectTokenSave{
1721 .id = Token.Id.Pipe,1691 .id = Token.Id.Pipe,
1722 .ptr = &node.rpipe,1692 .ptr = &node.rpipe,
1723 }1693 },
1724 });1694 });
1725 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });1695 try stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.value_symbol } });
1726 try stack.append(State {1696 try stack.append(State{
1727 .OptionalTokenSave = OptionalTokenSave {1697 .OptionalTokenSave = OptionalTokenSave{
1728 .id = Token.Id.Asterisk,1698 .id = Token.Id.Asterisk,
1729 .ptr = &node.ptr_token,1699 .ptr = &node.ptr_token,
1730 }1700 },
1731 });1701 });
1732 continue;1702 continue;
1733 },1703 },
...@@ -1737,8 +1707,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1737,8 +1707,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1737 const token_ptr = token.ptr;1707 const token_ptr = token.ptr;
1738 if (token_ptr.id != Token.Id.Pipe) {1708 if (token_ptr.id != Token.Id.Pipe) {
1739 if (opt_ctx != OptionalCtx.Optional) {1709 if (opt_ctx != OptionalCtx.Optional) {
1740 *(try tree.errors.addOne()) = Error {1710 ((try tree.errors.addOne())).* = Error{
1741 .ExpectedToken = Error.ExpectedToken {1711 .ExpectedToken = Error.ExpectedToken{
1742 .token = token_index,1712 .token = token_index,
1743 .expected_id = Token.Id.Pipe,1713 .expected_id = Token.Id.Pipe,
1744 },1714 },
...@@ -1746,67 +1716,64 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1746,67 +1716,64 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1746 return tree;1716 return tree;
1747 }1717 }
17481718
1749 putBackToken(&tok_it, &tree);1719 prevToken(&tok_it, &tree);
1750 continue;1720 continue;
1751 }1721 }
17521722
1753 const node = try createToCtxNode(arena, opt_ctx, ast.Node.PointerIndexPayload,1723 const node = try arena.construct(ast.Node.PointerIndexPayload{
1754 ast.Node.PointerIndexPayload {1724 .base = ast.Node{ .id = ast.Node.Id.PointerIndexPayload },
1755 .base = undefined,1725 .lpipe = token_index,
1756 .lpipe = token_index,1726 .ptr_token = null,
1757 .ptr_token = null,1727 .value_symbol = undefined,
1758 .value_symbol = undefined,1728 .index_symbol = null,
1759 .index_symbol = null,1729 .rpipe = undefined,
1760 .rpipe = undefined1730 });
1761 }1731 opt_ctx.store(&node.base);
1762 );
17631732
1764 stack.append(State {1733 stack.append(State{
1765 .ExpectTokenSave = ExpectTokenSave {1734 .ExpectTokenSave = ExpectTokenSave{
1766 .id = Token.Id.Pipe,1735 .id = Token.Id.Pipe,
1767 .ptr = &node.rpipe,1736 .ptr = &node.rpipe,
1768 }1737 },
1769 }) catch unreachable;1738 }) catch unreachable;
1770 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.index_symbol } });1739 try stack.append(State{ .Identifier = OptionalCtx{ .RequiredNull = &node.index_symbol } });
1771 try stack.append(State { .IfToken = Token.Id.Comma });1740 try stack.append(State{ .IfToken = Token.Id.Comma });
1772 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });1741 try stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.value_symbol } });
1773 try stack.append(State {1742 try stack.append(State{
1774 .OptionalTokenSave = OptionalTokenSave {1743 .OptionalTokenSave = OptionalTokenSave{
1775 .id = Token.Id.Asterisk,1744 .id = Token.Id.Asterisk,
1776 .ptr = &node.ptr_token,1745 .ptr = &node.ptr_token,
1777 }1746 },
1778 });1747 });
1779 continue;1748 continue;
1780 },1749 },
17811750
1782
1783 State.Expression => |opt_ctx| {1751 State.Expression => |opt_ctx| {
1784 const token = nextToken(&tok_it, &tree);1752 const token = nextToken(&tok_it, &tree);
1785 const token_index = token.index;1753 const token_index = token.index;
1786 const token_ptr = token.ptr;1754 const token_ptr = token.ptr;
1787 switch (token_ptr.id) {1755 switch (token_ptr.id) {
1788 Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {1756 Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {
1789 const node = try createToCtxNode(arena, opt_ctx, ast.Node.ControlFlowExpression,1757 const node = try arena.construct(ast.Node.ControlFlowExpression{
1790 ast.Node.ControlFlowExpression {1758 .base = ast.Node{ .id = ast.Node.Id.ControlFlowExpression },
1791 .base = undefined,1759 .ltoken = token_index,
1792 .ltoken = token_index,1760 .kind = undefined,
1793 .kind = undefined,1761 .rhs = null,
1794 .rhs = null,1762 });
1795 }1763 opt_ctx.store(&node.base);
1796 );
17971764
1798 stack.append(State { .Expression = OptionalCtx { .Optional = &node.rhs } }) catch unreachable;1765 stack.append(State{ .Expression = OptionalCtx{ .Optional = &node.rhs } }) catch unreachable;
17991766
1800 switch (token_ptr.id) {1767 switch (token_ptr.id) {
1801 Token.Id.Keyword_break => {1768 Token.Id.Keyword_break => {
1802 node.kind = ast.Node.ControlFlowExpression.Kind { .Break = null };1769 node.kind = ast.Node.ControlFlowExpression.Kind{ .Break = null };
1803 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Break } });1770 try stack.append(State{ .Identifier = OptionalCtx{ .RequiredNull = &node.kind.Break } });
1804 try stack.append(State { .IfToken = Token.Id.Colon });1771 try stack.append(State{ .IfToken = Token.Id.Colon });
1805 },1772 },
1806 Token.Id.Keyword_continue => {1773 Token.Id.Keyword_continue => {
1807 node.kind = ast.Node.ControlFlowExpression.Kind { .Continue = null };1774 node.kind = ast.Node.ControlFlowExpression.Kind{ .Continue = null };
1808 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } });1775 try stack.append(State{ .Identifier = OptionalCtx{ .RequiredNull = &node.kind.Continue } });
1809 try stack.append(State { .IfToken = Token.Id.Colon });1776 try stack.append(State{ .IfToken = Token.Id.Colon });
1810 },1777 },
1811 Token.Id.Keyword_return => {1778 Token.Id.Keyword_return => {
1812 node.kind = ast.Node.ControlFlowExpression.Kind.Return;1779 node.kind = ast.Node.ControlFlowExpression.Kind.Return;
...@@ -1816,57 +1783,55 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1816,57 +1783,55 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1816 continue;1783 continue;
1817 },1784 },
1818 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {1785 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
1819 const node = try createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp,1786 const node = try arena.construct(ast.Node.PrefixOp{
1820 ast.Node.PrefixOp {1787 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
1821 .base = undefined,1788 .op_token = token_index,
1822 .op_token = token_index,1789 .op = switch (token_ptr.id) {
1823 .op = switch (token_ptr.id) {1790 Token.Id.Keyword_try => ast.Node.PrefixOp.Op{ .Try = void{} },
1824 Token.Id.Keyword_try => ast.Node.PrefixOp.Op { .Try = void{} },1791 Token.Id.Keyword_cancel => ast.Node.PrefixOp.Op{ .Cancel = void{} },
1825 Token.Id.Keyword_cancel => ast.Node.PrefixOp.Op { .Cancel = void{} },1792 Token.Id.Keyword_resume => ast.Node.PrefixOp.Op{ .Resume = void{} },
1826 Token.Id.Keyword_resume => ast.Node.PrefixOp.Op { .Resume = void{} },1793 else => unreachable,
1827 else => unreachable,1794 },
1828 },1795 .rhs = undefined,
1829 .rhs = undefined,1796 });
1830 }1797 opt_ctx.store(&node.base);
1831 );
18321798
1833 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;1799 stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
1834 continue;1800 continue;
1835 },1801 },
1836 else => {1802 else => {
1837 if (!try parseBlockExpr(&stack, arena, opt_ctx, token_ptr, token_index)) {1803 if (!try parseBlockExpr(&stack, arena, opt_ctx, token_ptr, token_index)) {
1838 putBackToken(&tok_it, &tree);1804 prevToken(&tok_it, &tree);
1839 stack.append(State { .UnwrapExpressionBegin = opt_ctx }) catch unreachable;1805 stack.append(State{ .UnwrapExpressionBegin = opt_ctx }) catch unreachable;
1840 }1806 }
1841 continue;1807 continue;
1842 }1808 },
1843 }1809 }
1844 },1810 },
1845 State.RangeExpressionBegin => |opt_ctx| {1811 State.RangeExpressionBegin => |opt_ctx| {
1846 stack.append(State { .RangeExpressionEnd = opt_ctx }) catch unreachable;1812 stack.append(State{ .RangeExpressionEnd = opt_ctx }) catch unreachable;
1847 try stack.append(State { .Expression = opt_ctx });1813 try stack.append(State{ .Expression = opt_ctx });
1848 continue;1814 continue;
1849 },1815 },
1850 State.RangeExpressionEnd => |opt_ctx| {1816 State.RangeExpressionEnd => |opt_ctx| {
1851 const lhs = opt_ctx.get() ?? continue;1817 const lhs = opt_ctx.get() ?? continue;
18521818
1853 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {1819 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {
1854 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1820 const node = try arena.construct(ast.Node.InfixOp{
1855 ast.Node.InfixOp {1821 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1856 .base = undefined,1822 .lhs = lhs,
1857 .lhs = lhs,1823 .op_token = ellipsis3,
1858 .op_token = ellipsis3,1824 .op = ast.Node.InfixOp.Op.Range,
1859 .op = ast.Node.InfixOp.Op.Range,1825 .rhs = undefined,
1860 .rhs = undefined,1826 });
1861 }1827 opt_ctx.store(&node.base);
1862 );1828 stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
1863 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1864 continue;1829 continue;
1865 }1830 }
1866 },1831 },
1867 State.AssignmentExpressionBegin => |opt_ctx| {1832 State.AssignmentExpressionBegin => |opt_ctx| {
1868 stack.append(State { .AssignmentExpressionEnd = opt_ctx }) catch unreachable;1833 stack.append(State{ .AssignmentExpressionEnd = opt_ctx }) catch unreachable;
1869 try stack.append(State { .Expression = opt_ctx });1834 try stack.append(State{ .Expression = opt_ctx });
1870 continue;1835 continue;
1871 },1836 },
18721837
...@@ -1877,27 +1842,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1877,27 +1842,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1877 const token_index = token.index;1842 const token_index = token.index;
1878 const token_ptr = token.ptr;1843 const token_ptr = token.ptr;
1879 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {1844 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {
1880 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1845 const node = try arena.construct(ast.Node.InfixOp{
1881 ast.Node.InfixOp {1846 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1882 .base = undefined,1847 .lhs = lhs,
1883 .lhs = lhs,1848 .op_token = token_index,
1884 .op_token = token_index,1849 .op = ass_id,
1885 .op = ass_id,1850 .rhs = undefined,
1886 .rhs = undefined,1851 });
1887 }1852 opt_ctx.store(&node.base);
1888 );1853 stack.append(State{ .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1889 stack.append(State { .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1854 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } });
1890 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
1891 continue;1855 continue;
1892 } else {1856 } else {
1893 putBackToken(&tok_it, &tree);1857 prevToken(&tok_it, &tree);
1894 continue;1858 continue;
1895 }1859 }
1896 },1860 },
18971861
1898 State.UnwrapExpressionBegin => |opt_ctx| {1862 State.UnwrapExpressionBegin => |opt_ctx| {
1899 stack.append(State { .UnwrapExpressionEnd = opt_ctx }) catch unreachable;1863 stack.append(State{ .UnwrapExpressionEnd = opt_ctx }) catch unreachable;
1900 try stack.append(State { .BoolOrExpressionBegin = opt_ctx });1864 try stack.append(State{ .BoolOrExpressionBegin = opt_ctx });
1901 continue;1865 continue;
1902 },1866 },
19031867
...@@ -1908,32 +1872,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1908,32 +1872,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1908 const token_index = token.index;1872 const token_index = token.index;
1909 const token_ptr = token.ptr;1873 const token_ptr = token.ptr;
1910 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {1874 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {
1911 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1875 const node = try arena.construct(ast.Node.InfixOp{
1912 ast.Node.InfixOp {1876 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1913 .base = undefined,1877 .lhs = lhs,
1914 .lhs = lhs,1878 .op_token = token_index,
1915 .op_token = token_index,1879 .op = unwrap_id,
1916 .op = unwrap_id,1880 .rhs = undefined,
1917 .rhs = undefined,1881 });
1918 }1882 opt_ctx.store(&node.base);
1919 );
19201883
1921 stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1884 stack.append(State{ .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1922 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });1885 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } });
19231886
1924 if (node.op == ast.Node.InfixOp.Op.Catch) {1887 if (node.op == ast.Node.InfixOp.Op.Catch) {
1925 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.op.Catch } });1888 try stack.append(State{ .Payload = OptionalCtx{ .Optional = &node.op.Catch } });
1926 }1889 }
1927 continue;1890 continue;
1928 } else {1891 } else {
1929 putBackToken(&tok_it, &tree);1892 prevToken(&tok_it, &tree);
1930 continue;1893 continue;
1931 }1894 }
1932 },1895 },
19331896
1934 State.BoolOrExpressionBegin => |opt_ctx| {1897 State.BoolOrExpressionBegin => |opt_ctx| {
1935 stack.append(State { .BoolOrExpressionEnd = opt_ctx }) catch unreachable;1898 stack.append(State{ .BoolOrExpressionEnd = opt_ctx }) catch unreachable;
1936 try stack.append(State { .BoolAndExpressionBegin = opt_ctx });1899 try stack.append(State{ .BoolAndExpressionBegin = opt_ctx });
1937 continue;1900 continue;
1938 },1901 },
19391902
...@@ -1941,24 +1904,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1941,24 +1904,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1941 const lhs = opt_ctx.get() ?? continue;1904 const lhs = opt_ctx.get() ?? continue;
19421905
1943 if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {1906 if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {
1944 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1907 const node = try arena.construct(ast.Node.InfixOp{
1945 ast.Node.InfixOp {1908 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1946 .base = undefined,1909 .lhs = lhs,
1947 .lhs = lhs,1910 .op_token = or_token,
1948 .op_token = or_token,1911 .op = ast.Node.InfixOp.Op.BoolOr,
1949 .op = ast.Node.InfixOp.Op.BoolOr,1912 .rhs = undefined,
1950 .rhs = undefined,1913 });
1951 }1914 opt_ctx.store(&node.base);
1952 );1915 stack.append(State{ .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1953 stack.append(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1916 try stack.append(State{ .BoolAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
1954 try stack.append(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });
1955 continue;1917 continue;
1956 }1918 }
1957 },1919 },
19581920
1959 State.BoolAndExpressionBegin => |opt_ctx| {1921 State.BoolAndExpressionBegin => |opt_ctx| {
1960 stack.append(State { .BoolAndExpressionEnd = opt_ctx }) catch unreachable;1922 stack.append(State{ .BoolAndExpressionEnd = opt_ctx }) catch unreachable;
1961 try stack.append(State { .ComparisonExpressionBegin = opt_ctx });1923 try stack.append(State{ .ComparisonExpressionBegin = opt_ctx });
1962 continue;1924 continue;
1963 },1925 },
19641926
...@@ -1966,24 +1928,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1966,24 +1928,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1966 const lhs = opt_ctx.get() ?? continue;1928 const lhs = opt_ctx.get() ?? continue;
19671929
1968 if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {1930 if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {
1969 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1931 const node = try arena.construct(ast.Node.InfixOp{
1970 ast.Node.InfixOp {1932 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1971 .base = undefined,1933 .lhs = lhs,
1972 .lhs = lhs,1934 .op_token = and_token,
1973 .op_token = and_token,1935 .op = ast.Node.InfixOp.Op.BoolAnd,
1974 .op = ast.Node.InfixOp.Op.BoolAnd,1936 .rhs = undefined,
1975 .rhs = undefined,1937 });
1976 }1938 opt_ctx.store(&node.base);
1977 );1939 stack.append(State{ .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1978 stack.append(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1940 try stack.append(State{ .ComparisonExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
1979 try stack.append(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } });
1980 continue;1941 continue;
1981 }1942 }
1982 },1943 },
19831944
1984 State.ComparisonExpressionBegin => |opt_ctx| {1945 State.ComparisonExpressionBegin => |opt_ctx| {
1985 stack.append(State { .ComparisonExpressionEnd = opt_ctx }) catch unreachable;1946 stack.append(State{ .ComparisonExpressionEnd = opt_ctx }) catch unreachable;
1986 try stack.append(State { .BinaryOrExpressionBegin = opt_ctx });1947 try stack.append(State{ .BinaryOrExpressionBegin = opt_ctx });
1987 continue;1948 continue;
1988 },1949 },
19891950
...@@ -1994,27 +1955,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1994,27 +1955,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1994 const token_index = token.index;1955 const token_index = token.index;
1995 const token_ptr = token.ptr;1956 const token_ptr = token.ptr;
1996 if (tokenIdToComparison(token_ptr.id)) |comp_id| {1957 if (tokenIdToComparison(token_ptr.id)) |comp_id| {
1997 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1958 const node = try arena.construct(ast.Node.InfixOp{
1998 ast.Node.InfixOp {1959 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
1999 .base = undefined,1960 .lhs = lhs,
2000 .lhs = lhs,1961 .op_token = token_index,
2001 .op_token = token_index,1962 .op = comp_id,
2002 .op = comp_id,1963 .rhs = undefined,
2003 .rhs = undefined,1964 });
2004 }1965 opt_ctx.store(&node.base);
2005 );1966 stack.append(State{ .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2006 stack.append(State { .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1967 try stack.append(State{ .BinaryOrExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2007 try stack.append(State { .BinaryOrExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2008 continue;1968 continue;
2009 } else {1969 } else {
2010 putBackToken(&tok_it, &tree);1970 prevToken(&tok_it, &tree);
2011 continue;1971 continue;
2012 }1972 }
2013 },1973 },
20141974
2015 State.BinaryOrExpressionBegin => |opt_ctx| {1975 State.BinaryOrExpressionBegin => |opt_ctx| {
2016 stack.append(State { .BinaryOrExpressionEnd = opt_ctx }) catch unreachable;1976 stack.append(State{ .BinaryOrExpressionEnd = opt_ctx }) catch unreachable;
2017 try stack.append(State { .BinaryXorExpressionBegin = opt_ctx });1977 try stack.append(State{ .BinaryXorExpressionBegin = opt_ctx });
2018 continue;1978 continue;
2019 },1979 },
20201980
...@@ -2022,24 +1982,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2022,24 +1982,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2022 const lhs = opt_ctx.get() ?? continue;1982 const lhs = opt_ctx.get() ?? continue;
20231983
2024 if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {1984 if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {
2025 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,1985 const node = try arena.construct(ast.Node.InfixOp{
2026 ast.Node.InfixOp {1986 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2027 .base = undefined,1987 .lhs = lhs,
2028 .lhs = lhs,1988 .op_token = pipe,
2029 .op_token = pipe,1989 .op = ast.Node.InfixOp.Op.BitOr,
2030 .op = ast.Node.InfixOp.Op.BitOr,1990 .rhs = undefined,
2031 .rhs = undefined,1991 });
2032 }1992 opt_ctx.store(&node.base);
2033 );1993 stack.append(State{ .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2034 stack.append(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1994 try stack.append(State{ .BinaryXorExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2035 try stack.append(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2036 continue;1995 continue;
2037 }1996 }
2038 },1997 },
20391998
2040 State.BinaryXorExpressionBegin => |opt_ctx| {1999 State.BinaryXorExpressionBegin => |opt_ctx| {
2041 stack.append(State { .BinaryXorExpressionEnd = opt_ctx }) catch unreachable;2000 stack.append(State{ .BinaryXorExpressionEnd = opt_ctx }) catch unreachable;
2042 try stack.append(State { .BinaryAndExpressionBegin = opt_ctx });2001 try stack.append(State{ .BinaryAndExpressionBegin = opt_ctx });
2043 continue;2002 continue;
2044 },2003 },
20452004
...@@ -2047,24 +2006,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2047,24 +2006,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2047 const lhs = opt_ctx.get() ?? continue;2006 const lhs = opt_ctx.get() ?? continue;
20482007
2049 if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {2008 if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {
2050 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2009 const node = try arena.construct(ast.Node.InfixOp{
2051 ast.Node.InfixOp {2010 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2052 .base = undefined,2011 .lhs = lhs,
2053 .lhs = lhs,2012 .op_token = caret,
2054 .op_token = caret,2013 .op = ast.Node.InfixOp.Op.BitXor,
2055 .op = ast.Node.InfixOp.Op.BitXor,2014 .rhs = undefined,
2056 .rhs = undefined,2015 });
2057 }2016 opt_ctx.store(&node.base);
2058 );2017 stack.append(State{ .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2059 stack.append(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2018 try stack.append(State{ .BinaryAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2060 try stack.append(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2061 continue;2019 continue;
2062 }2020 }
2063 },2021 },
20642022
2065 State.BinaryAndExpressionBegin => |opt_ctx| {2023 State.BinaryAndExpressionBegin => |opt_ctx| {
2066 stack.append(State { .BinaryAndExpressionEnd = opt_ctx }) catch unreachable;2024 stack.append(State{ .BinaryAndExpressionEnd = opt_ctx }) catch unreachable;
2067 try stack.append(State { .BitShiftExpressionBegin = opt_ctx });2025 try stack.append(State{ .BitShiftExpressionBegin = opt_ctx });
2068 continue;2026 continue;
2069 },2027 },
20702028
...@@ -2072,24 +2030,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2072,24 +2030,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2072 const lhs = opt_ctx.get() ?? continue;2030 const lhs = opt_ctx.get() ?? continue;
20732031
2074 if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {2032 if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {
2075 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2033 const node = try arena.construct(ast.Node.InfixOp{
2076 ast.Node.InfixOp {2034 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2077 .base = undefined,2035 .lhs = lhs,
2078 .lhs = lhs,2036 .op_token = ampersand,
2079 .op_token = ampersand,2037 .op = ast.Node.InfixOp.Op.BitAnd,
2080 .op = ast.Node.InfixOp.Op.BitAnd,2038 .rhs = undefined,
2081 .rhs = undefined,2039 });
2082 }2040 opt_ctx.store(&node.base);
2083 );2041 stack.append(State{ .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2084 stack.append(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2042 try stack.append(State{ .BitShiftExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2085 try stack.append(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2086 continue;2043 continue;
2087 }2044 }
2088 },2045 },
20892046
2090 State.BitShiftExpressionBegin => |opt_ctx| {2047 State.BitShiftExpressionBegin => |opt_ctx| {
2091 stack.append(State { .BitShiftExpressionEnd = opt_ctx }) catch unreachable;2048 stack.append(State{ .BitShiftExpressionEnd = opt_ctx }) catch unreachable;
2092 try stack.append(State { .AdditionExpressionBegin = opt_ctx });2049 try stack.append(State{ .AdditionExpressionBegin = opt_ctx });
2093 continue;2050 continue;
2094 },2051 },
20952052
...@@ -2100,27 +2057,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2100,27 +2057,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2100 const token_index = token.index;2057 const token_index = token.index;
2101 const token_ptr = token.ptr;2058 const token_ptr = token.ptr;
2102 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {2059 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {
2103 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2060 const node = try arena.construct(ast.Node.InfixOp{
2104 ast.Node.InfixOp {2061 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2105 .base = undefined,2062 .lhs = lhs,
2106 .lhs = lhs,2063 .op_token = token_index,
2107 .op_token = token_index,2064 .op = bitshift_id,
2108 .op = bitshift_id,2065 .rhs = undefined,
2109 .rhs = undefined,2066 });
2110 }2067 opt_ctx.store(&node.base);
2111 );2068 stack.append(State{ .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2112 stack.append(State { .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2069 try stack.append(State{ .AdditionExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2113 try stack.append(State { .AdditionExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2114 continue;2070 continue;
2115 } else {2071 } else {
2116 putBackToken(&tok_it, &tree);2072 prevToken(&tok_it, &tree);
2117 continue;2073 continue;
2118 }2074 }
2119 },2075 },
21202076
2121 State.AdditionExpressionBegin => |opt_ctx| {2077 State.AdditionExpressionBegin => |opt_ctx| {
2122 stack.append(State { .AdditionExpressionEnd = opt_ctx }) catch unreachable;2078 stack.append(State{ .AdditionExpressionEnd = opt_ctx }) catch unreachable;
2123 try stack.append(State { .MultiplyExpressionBegin = opt_ctx });2079 try stack.append(State{ .MultiplyExpressionBegin = opt_ctx });
2124 continue;2080 continue;
2125 },2081 },
21262082
...@@ -2131,27 +2087,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2131,27 +2087,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2131 const token_index = token.index;2087 const token_index = token.index;
2132 const token_ptr = token.ptr;2088 const token_ptr = token.ptr;
2133 if (tokenIdToAddition(token_ptr.id)) |add_id| {2089 if (tokenIdToAddition(token_ptr.id)) |add_id| {
2134 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2090 const node = try arena.construct(ast.Node.InfixOp{
2135 ast.Node.InfixOp {2091 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2136 .base = undefined,2092 .lhs = lhs,
2137 .lhs = lhs,2093 .op_token = token_index,
2138 .op_token = token_index,2094 .op = add_id,
2139 .op = add_id,2095 .rhs = undefined,
2140 .rhs = undefined,2096 });
2141 }2097 opt_ctx.store(&node.base);
2142 );2098 stack.append(State{ .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2143 stack.append(State { .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2099 try stack.append(State{ .MultiplyExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2144 try stack.append(State { .MultiplyExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2145 continue;2100 continue;
2146 } else {2101 } else {
2147 putBackToken(&tok_it, &tree);2102 prevToken(&tok_it, &tree);
2148 continue;2103 continue;
2149 }2104 }
2150 },2105 },
21512106
2152 State.MultiplyExpressionBegin => |opt_ctx| {2107 State.MultiplyExpressionBegin => |opt_ctx| {
2153 stack.append(State { .MultiplyExpressionEnd = opt_ctx }) catch unreachable;2108 stack.append(State{ .MultiplyExpressionEnd = opt_ctx }) catch unreachable;
2154 try stack.append(State { .CurlySuffixExpressionBegin = opt_ctx });2109 try stack.append(State{ .CurlySuffixExpressionBegin = opt_ctx });
2155 continue;2110 continue;
2156 },2111 },
21572112
...@@ -2162,28 +2117,27 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2162,28 +2117,27 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2162 const token_index = token.index;2117 const token_index = token.index;
2163 const token_ptr = token.ptr;2118 const token_ptr = token.ptr;
2164 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {2119 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {
2165 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2120 const node = try arena.construct(ast.Node.InfixOp{
2166 ast.Node.InfixOp {2121 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2167 .base = undefined,2122 .lhs = lhs,
2168 .lhs = lhs,2123 .op_token = token_index,
2169 .op_token = token_index,2124 .op = mult_id,
2170 .op = mult_id,2125 .rhs = undefined,
2171 .rhs = undefined,2126 });
2172 }2127 opt_ctx.store(&node.base);
2173 );2128 stack.append(State{ .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2174 stack.append(State { .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2129 try stack.append(State{ .CurlySuffixExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
2175 try stack.append(State { .CurlySuffixExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2176 continue;2130 continue;
2177 } else {2131 } else {
2178 putBackToken(&tok_it, &tree);2132 prevToken(&tok_it, &tree);
2179 continue;2133 continue;
2180 }2134 }
2181 },2135 },
21822136
2183 State.CurlySuffixExpressionBegin => |opt_ctx| {2137 State.CurlySuffixExpressionBegin => |opt_ctx| {
2184 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx }) catch unreachable;2138 stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx }) catch unreachable;
2185 try stack.append(State { .IfToken = Token.Id.LBrace });2139 try stack.append(State{ .IfToken = Token.Id.LBrace });
2186 try stack.append(State { .TypeExprBegin = opt_ctx });2140 try stack.append(State{ .TypeExprBegin = opt_ctx });
2187 continue;2141 continue;
2188 },2142 },
21892143
...@@ -2191,52 +2145,47 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2191,52 +2145,47 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2191 const lhs = opt_ctx.get() ?? continue;2145 const lhs = opt_ctx.get() ?? continue;
21922146
2193 if ((??tok_it.peek()).id == Token.Id.Period) {2147 if ((??tok_it.peek()).id == Token.Id.Period) {
2194 const node = try arena.construct(ast.Node.SuffixOp {2148 const node = try arena.construct(ast.Node.SuffixOp{
2195 .base = ast.Node { .id = ast.Node.Id.SuffixOp },2149 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2196 .lhs = lhs,2150 .lhs = lhs,
2197 .op = ast.Node.SuffixOp.Op {2151 .op = ast.Node.SuffixOp.Op{ .StructInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },
2198 .StructInitializer = ast.Node.SuffixOp.Op.InitList.init(arena),
2199 },
2200 .rtoken = undefined,2152 .rtoken = undefined,
2201 });2153 });
2202 opt_ctx.store(&node.base);2154 opt_ctx.store(&node.base);
22032155
2204 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2156 stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2205 try stack.append(State { .IfToken = Token.Id.LBrace });2157 try stack.append(State{ .IfToken = Token.Id.LBrace });
2206 try stack.append(State {2158 try stack.append(State{
2207 .FieldInitListItemOrEnd = ListSave(@typeOf(node.op.StructInitializer)) {2159 .FieldInitListItemOrEnd = ListSave(@typeOf(node.op.StructInitializer)){
2208 .list = &node.op.StructInitializer,2160 .list = &node.op.StructInitializer,
2209 .ptr = &node.rtoken,2161 .ptr = &node.rtoken,
2210 }2162 },
2211 });2163 });
2212 continue;2164 continue;
2213 }2165 }
22142166
2215 const node = try createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,2167 const node = try arena.construct(ast.Node.SuffixOp{
2216 ast.Node.SuffixOp {2168 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2217 .base = undefined,2169 .lhs = lhs,
2218 .lhs = lhs,2170 .op = ast.Node.SuffixOp.Op{ .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },
2219 .op = ast.Node.SuffixOp.Op {2171 .rtoken = undefined,
2220 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(arena),2172 });
2221 },2173 opt_ctx.store(&node.base);
2222 .rtoken = undefined,2174 stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2223 }2175 try stack.append(State{ .IfToken = Token.Id.LBrace });
2224 );2176 try stack.append(State{
2225 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2177 .ExprListItemOrEnd = ExprListCtx{
2226 try stack.append(State { .IfToken = Token.Id.LBrace });
2227 try stack.append(State {
2228 .ExprListItemOrEnd = ExprListCtx {
2229 .list = &node.op.ArrayInitializer,2178 .list = &node.op.ArrayInitializer,
2230 .end = Token.Id.RBrace,2179 .end = Token.Id.RBrace,
2231 .ptr = &node.rtoken,2180 .ptr = &node.rtoken,
2232 }2181 },
2233 });2182 });
2234 continue;2183 continue;
2235 },2184 },
22362185
2237 State.TypeExprBegin => |opt_ctx| {2186 State.TypeExprBegin => |opt_ctx| {
2238 stack.append(State { .TypeExprEnd = opt_ctx }) catch unreachable;2187 stack.append(State{ .TypeExprEnd = opt_ctx }) catch unreachable;
2239 try stack.append(State { .PrefixOpExpression = opt_ctx });2188 try stack.append(State{ .PrefixOpExpression = opt_ctx });
2240 continue;2189 continue;
2241 },2190 },
22422191
...@@ -2244,17 +2193,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2244,17 +2193,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2244 const lhs = opt_ctx.get() ?? continue;2193 const lhs = opt_ctx.get() ?? continue;
22452194
2246 if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {2195 if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {
2247 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2196 const node = try arena.construct(ast.Node.InfixOp{
2248 ast.Node.InfixOp {2197 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2249 .base = undefined,2198 .lhs = lhs,
2250 .lhs = lhs,2199 .op_token = bang,
2251 .op_token = bang,2200 .op = ast.Node.InfixOp.Op.ErrorUnion,
2252 .op = ast.Node.InfixOp.Op.ErrorUnion,2201 .rhs = undefined,
2253 .rhs = undefined,2202 });
2254 }2203 opt_ctx.store(&node.base);
2255 );2204 stack.append(State{ .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;
2256 stack.append(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;2205 try stack.append(State{ .PrefixOpExpression = OptionalCtx{ .Required = &node.rhs } });
2257 try stack.append(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } });
2258 continue;2206 continue;
2259 }2207 }
2260 },2208 },
...@@ -2264,65 +2212,60 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2264,65 +2212,60 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2264 const token_index = token.index;2212 const token_index = token.index;
2265 const token_ptr = token.ptr;2213 const token_ptr = token.ptr;
2266 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {2214 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {
2267 var node = try createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp,2215 var node = try arena.construct(ast.Node.PrefixOp{
2268 ast.Node.PrefixOp {2216 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
2269 .base = undefined,2217 .op_token = token_index,
2270 .op_token = token_index,2218 .op = prefix_id,
2271 .op = prefix_id,2219 .rhs = undefined,
2272 .rhs = undefined,2220 });
2273 }2221 opt_ctx.store(&node.base);
2274 );
22752222
2276 // Treat '**' token as two derefs2223 // Treat '**' token as two derefs
2277 if (token_ptr.id == Token.Id.AsteriskAsterisk) {2224 if (token_ptr.id == Token.Id.AsteriskAsterisk) {
2278 const child = try createNode(arena, ast.Node.PrefixOp,2225 const child = try arena.construct(ast.Node.PrefixOp{
2279 ast.Node.PrefixOp {2226 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
2280 .base = undefined,2227 .op_token = token_index,
2281 .op_token = token_index,2228 .op = prefix_id,
2282 .op = prefix_id,2229 .rhs = undefined,
2283 .rhs = undefined,2230 });
2284 }
2285 );
2286 node.rhs = &child.base;2231 node.rhs = &child.base;
2287 node = child;2232 node = child;
2288 }2233 }
22892234
2290 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;2235 stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
2291 if (node.op == ast.Node.PrefixOp.Op.AddrOf) {2236 if (node.op == ast.Node.PrefixOp.Op.AddrOf) {
2292 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });2237 try stack.append(State{ .AddrOfModifiers = &node.op.AddrOf });
2293 }2238 }
2294 continue;2239 continue;
2295 } else {2240 } else {
2296 putBackToken(&tok_it, &tree);2241 prevToken(&tok_it, &tree);
2297 stack.append(State { .SuffixOpExpressionBegin = opt_ctx }) catch unreachable;2242 stack.append(State{ .SuffixOpExpressionBegin = opt_ctx }) catch unreachable;
2298 continue;2243 continue;
2299 }2244 }
2300 },2245 },
23012246
2302 State.SuffixOpExpressionBegin => |opt_ctx| {2247 State.SuffixOpExpressionBegin => |opt_ctx| {
2303 if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {2248 if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {
2304 const async_node = try createNode(arena, ast.Node.AsyncAttribute,2249 const async_node = try arena.construct(ast.Node.AsyncAttribute{
2305 ast.Node.AsyncAttribute {2250 .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
2306 .base = undefined,2251 .async_token = async_token,
2307 .async_token = async_token,2252 .allocator_type = null,
2308 .allocator_type = null,2253 .rangle_bracket = null,
2309 .rangle_bracket = null,2254 });
2310 }2255 stack.append(State{
2311 );2256 .AsyncEnd = AsyncEndCtx{
2312 stack.append(State {
2313 .AsyncEnd = AsyncEndCtx {
2314 .ctx = opt_ctx,2257 .ctx = opt_ctx,
2315 .attribute = async_node,2258 .attribute = async_node,
2316 }2259 },
2317 }) catch unreachable;2260 }) catch unreachable;
2318 try stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() });2261 try stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() });
2319 try stack.append(State { .PrimaryExpression = opt_ctx.toRequired() });2262 try stack.append(State{ .PrimaryExpression = opt_ctx.toRequired() });
2320 try stack.append(State { .AsyncAllocator = async_node });2263 try stack.append(State{ .AsyncAllocator = async_node });
2321 continue;2264 continue;
2322 }2265 }
23232266
2324 stack.append(State { .SuffixOpExpressionEnd = opt_ctx }) catch unreachable;2267 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx }) catch unreachable;
2325 try stack.append(State { .PrimaryExpression = opt_ctx });2268 try stack.append(State{ .PrimaryExpression = opt_ctx });
2326 continue;2269 continue;
2327 },2270 },
23282271
...@@ -2334,61 +2277,70 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2334,61 +2277,70 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2334 const token_ptr = token.ptr;2277 const token_ptr = token.ptr;
2335 switch (token_ptr.id) {2278 switch (token_ptr.id) {
2336 Token.Id.LParen => {2279 Token.Id.LParen => {
2337 const node = try createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,2280 const node = try arena.construct(ast.Node.SuffixOp{
2338 ast.Node.SuffixOp {2281 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2339 .base = undefined,2282 .lhs = lhs,
2340 .lhs = lhs,2283 .op = ast.Node.SuffixOp.Op{
2341 .op = ast.Node.SuffixOp.Op {2284 .Call = ast.Node.SuffixOp.Op.Call{
2342 .Call = ast.Node.SuffixOp.Op.Call {2285 .params = ast.Node.SuffixOp.Op.Call.ParamList.init(arena),
2343 .params = ast.Node.SuffixOp.Op.Call.ParamList.init(arena),2286 .async_attr = null,
2344 .async_attr = null,
2345 }
2346 },2287 },
2347 .rtoken = undefined,2288 },
2348 }2289 .rtoken = undefined,
2349 );2290 });
2350 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2291 opt_ctx.store(&node.base);
2351 try stack.append(State {2292
2352 .ExprListItemOrEnd = ExprListCtx {2293 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2294 try stack.append(State{
2295 .ExprListItemOrEnd = ExprListCtx{
2353 .list = &node.op.Call.params,2296 .list = &node.op.Call.params,
2354 .end = Token.Id.RParen,2297 .end = Token.Id.RParen,
2355 .ptr = &node.rtoken,2298 .ptr = &node.rtoken,
2356 }2299 },
2357 });2300 });
2358 continue;2301 continue;
2359 },2302 },
2360 Token.Id.LBracket => {2303 Token.Id.LBracket => {
2361 const node = try createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,2304 const node = try arena.construct(ast.Node.SuffixOp{
2362 ast.Node.SuffixOp {2305 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2363 .base = undefined,2306 .lhs = lhs,
2364 .lhs = lhs,2307 .op = ast.Node.SuffixOp.Op{ .ArrayAccess = undefined },
2365 .op = ast.Node.SuffixOp.Op {2308 .rtoken = undefined,
2366 .ArrayAccess = undefined,2309 });
2367 },2310 opt_ctx.store(&node.base);
2368 .rtoken = undefined2311
2369 }2312 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2370 );2313 try stack.append(State{ .SliceOrArrayAccess = node });
2371 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2314 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.op.ArrayAccess } });
2372 try stack.append(State { .SliceOrArrayAccess = node });
2373 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayAccess }});
2374 continue;2315 continue;
2375 },2316 },
2376 Token.Id.Period => {2317 Token.Id.Period => {
2377 const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,2318 if (eatToken(&tok_it, &tree, Token.Id.Asterisk)) |asterisk_token| {
2378 ast.Node.InfixOp {2319 const node = try arena.construct(ast.Node.SuffixOp{
2379 .base = undefined,2320 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
2380 .lhs = lhs,2321 .lhs = lhs,
2381 .op_token = token_index,2322 .op = ast.Node.SuffixOp.Op.Deref,
2382 .op = ast.Node.InfixOp.Op.Period,2323 .rtoken = asterisk_token,
2383 .rhs = undefined,2324 });
2384 }2325 opt_ctx.store(&node.base);
2385 );2326 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2386 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2327 continue;
2387 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.rhs } });2328 }
2329 const node = try arena.construct(ast.Node.InfixOp{
2330 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
2331 .lhs = lhs,
2332 .op_token = token_index,
2333 .op = ast.Node.InfixOp.Op.Period,
2334 .rhs = undefined,
2335 });
2336 opt_ctx.store(&node.base);
2337
2338 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2339 try stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.rhs } });
2388 continue;2340 continue;
2389 },2341 },
2390 else => {2342 else => {
2391 putBackToken(&tok_it, &tree);2343 prevToken(&tok_it, &tree);
2392 continue;2344 continue;
2393 },2345 },
2394 }2346 }
...@@ -2434,10 +2386,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2434,10 +2386,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2434 continue;2386 continue;
2435 },2387 },
2436 Token.Id.Keyword_promise => {2388 Token.Id.Keyword_promise => {
2437 const node = try arena.construct(ast.Node.PromiseType {2389 const node = try arena.construct(ast.Node.PromiseType{
2438 .base = ast.Node {2390 .base = ast.Node{ .id = ast.Node.Id.PromiseType },
2439 .id = ast.Node.Id.PromiseType,
2440 },
2441 .promise_token = token.index,2391 .promise_token = token.index,
2442 .result = null,2392 .result = null,
2443 });2393 });
...@@ -2446,15 +2396,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2446,15 +2396,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2446 const next_token_index = next_token.index;2396 const next_token_index = next_token.index;
2447 const next_token_ptr = next_token.ptr;2397 const next_token_ptr = next_token.ptr;
2448 if (next_token_ptr.id != Token.Id.Arrow) {2398 if (next_token_ptr.id != Token.Id.Arrow) {
2449 putBackToken(&tok_it, &tree);2399 prevToken(&tok_it, &tree);
2450 continue;2400 continue;
2451 }2401 }
2452 node.result = ast.Node.PromiseType.Result {2402 node.result = ast.Node.PromiseType.Result{
2453 .arrow_token = next_token_index,2403 .arrow_token = next_token_index,
2454 .return_type = undefined,2404 .return_type = undefined,
2455 };2405 };
2456 const return_type_ptr = &((??node.result).return_type);2406 const return_type_ptr = &((??node.result).return_type);
2457 try stack.append(State { .Expression = OptionalCtx { .Required = return_type_ptr, } });2407 try stack.append(State{ .Expression = OptionalCtx{ .Required = return_type_ptr } });
2458 continue;2408 continue;
2459 },2409 },
2460 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {2410 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
...@@ -2462,76 +2412,75 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2462,76 +2412,75 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2462 continue;2412 continue;
2463 },2413 },
2464 Token.Id.LParen => {2414 Token.Id.LParen => {
2465 const node = try createToCtxNode(arena, opt_ctx, ast.Node.GroupedExpression,2415 const node = try arena.construct(ast.Node.GroupedExpression{
2466 ast.Node.GroupedExpression {2416 .base = ast.Node{ .id = ast.Node.Id.GroupedExpression },
2467 .base = undefined,2417 .lparen = token.index,
2468 .lparen = token.index,2418 .expr = undefined,
2469 .expr = undefined,2419 .rparen = undefined,
2470 .rparen = undefined,2420 });
2471 }2421 opt_ctx.store(&node.base);
2472 );2422
2473 stack.append(State {2423 stack.append(State{
2474 .ExpectTokenSave = ExpectTokenSave {2424 .ExpectTokenSave = ExpectTokenSave{
2475 .id = Token.Id.RParen,2425 .id = Token.Id.RParen,
2476 .ptr = &node.rparen,2426 .ptr = &node.rparen,
2477 }2427 },
2478 }) catch unreachable;2428 }) catch unreachable;
2479 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });2429 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
2480 continue;2430 continue;
2481 },2431 },
2482 Token.Id.Builtin => {2432 Token.Id.Builtin => {
2483 const node = try createToCtxNode(arena, opt_ctx, ast.Node.BuiltinCall,2433 const node = try arena.construct(ast.Node.BuiltinCall{
2484 ast.Node.BuiltinCall {2434 .base = ast.Node{ .id = ast.Node.Id.BuiltinCall },
2485 .base = undefined,2435 .builtin_token = token.index,
2486 .builtin_token = token.index,2436 .params = ast.Node.BuiltinCall.ParamList.init(arena),
2487 .params = ast.Node.BuiltinCall.ParamList.init(arena),2437 .rparen_token = undefined,
2488 .rparen_token = undefined,2438 });
2489 }2439 opt_ctx.store(&node.base);
2490 );2440
2491 stack.append(State {2441 stack.append(State{
2492 .ExprListItemOrEnd = ExprListCtx {2442 .ExprListItemOrEnd = ExprListCtx{
2493 .list = &node.params,2443 .list = &node.params,
2494 .end = Token.Id.RParen,2444 .end = Token.Id.RParen,
2495 .ptr = &node.rparen_token,2445 .ptr = &node.rparen_token,
2496 }2446 },
2497 }) catch unreachable;2447 }) catch unreachable;
2498 try stack.append(State { .ExpectToken = Token.Id.LParen, });2448 try stack.append(State{ .ExpectToken = Token.Id.LParen });
2499 continue;2449 continue;
2500 },2450 },
2501 Token.Id.LBracket => {2451 Token.Id.LBracket => {
2502 const node = try createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp,2452 const node = try arena.construct(ast.Node.PrefixOp{
2503 ast.Node.PrefixOp {2453 .base = ast.Node{ .id = ast.Node.Id.PrefixOp },
2504 .base = undefined,2454 .op_token = token.index,
2505 .op_token = token.index,2455 .op = undefined,
2506 .op = undefined,2456 .rhs = undefined,
2507 .rhs = undefined,2457 });
2508 }2458 opt_ctx.store(&node.base);
2509 );2459
2510 stack.append(State { .SliceOrArrayType = node }) catch unreachable;2460 stack.append(State{ .SliceOrArrayType = node }) catch unreachable;
2511 continue;2461 continue;
2512 },2462 },
2513 Token.Id.Keyword_error => {2463 Token.Id.Keyword_error => {
2514 stack.append(State {2464 stack.append(State{
2515 .ErrorTypeOrSetDecl = ErrorTypeOrSetDeclCtx {2465 .ErrorTypeOrSetDecl = ErrorTypeOrSetDeclCtx{
2516 .error_token = token.index,2466 .error_token = token.index,
2517 .opt_ctx = opt_ctx2467 .opt_ctx = opt_ctx,
2518 }2468 },
2519 }) catch unreachable;2469 }) catch unreachable;
2520 continue;2470 continue;
2521 },2471 },
2522 Token.Id.Keyword_packed => {2472 Token.Id.Keyword_packed => {
2523 stack.append(State {2473 stack.append(State{
2524 .ContainerKind = ContainerKindCtx {2474 .ContainerKind = ContainerKindCtx{
2525 .opt_ctx = opt_ctx,2475 .opt_ctx = opt_ctx,
2526 .ltoken = token.index,2476 .layout_token = token.index,
2527 .layout = ast.Node.ContainerDecl.Layout.Packed,
2528 },2477 },
2529 }) catch unreachable;2478 }) catch unreachable;
2530 continue;2479 continue;
2531 },2480 },
2532 Token.Id.Keyword_extern => {2481 Token.Id.Keyword_extern => {
2533 stack.append(State {2482 stack.append(State{
2534 .ExternType = ExternTypeCtx {2483 .ExternType = ExternTypeCtx{
2535 .opt_ctx = opt_ctx,2484 .opt_ctx = opt_ctx,
2536 .extern_token = token.index,2485 .extern_token = token.index,
2537 .comments = null,2486 .comments = null,
...@@ -2540,30 +2489,27 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2540,30 +2489,27 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2540 continue;2489 continue;
2541 },2490 },
2542 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {2491 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
2543 putBackToken(&tok_it, &tree);2492 prevToken(&tok_it, &tree);
2544 stack.append(State {2493 stack.append(State{
2545 .ContainerKind = ContainerKindCtx {2494 .ContainerKind = ContainerKindCtx{
2546 .opt_ctx = opt_ctx,2495 .opt_ctx = opt_ctx,
2547 .ltoken = token.index,2496 .layout_token = null,
2548 .layout = ast.Node.ContainerDecl.Layout.Auto,
2549 },2497 },
2550 }) catch unreachable;2498 }) catch unreachable;
2551 continue;2499 continue;
2552 },2500 },
2553 Token.Id.Identifier => {2501 Token.Id.Identifier => {
2554 stack.append(State {2502 stack.append(State{
2555 .MaybeLabeledExpression = MaybeLabeledExpressionCtx {2503 .MaybeLabeledExpression = MaybeLabeledExpressionCtx{
2556 .label = token.index,2504 .label = token.index,
2557 .opt_ctx = opt_ctx2505 .opt_ctx = opt_ctx,
2558 }2506 },
2559 }) catch unreachable;2507 }) catch unreachable;
2560 continue;2508 continue;
2561 },2509 },
2562 Token.Id.Keyword_fn => {2510 Token.Id.Keyword_fn => {
2563 const fn_proto = try arena.construct(ast.Node.FnProto {2511 const fn_proto = try arena.construct(ast.Node.FnProto{
2564 .base = ast.Node {2512 .base = ast.Node{ .id = ast.Node.Id.FnProto },
2565 .id = ast.Node.Id.FnProto,
2566 },
2567 .doc_comments = null,2513 .doc_comments = null,
2568 .visib_token = null,2514 .visib_token = null,
2569 .name_token = null,2515 .name_token = null,
...@@ -2579,14 +2525,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2579,14 +2525,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2579 .align_expr = null,2525 .align_expr = null,
2580 });2526 });
2581 opt_ctx.store(&fn_proto.base);2527 opt_ctx.store(&fn_proto.base);
2582 stack.append(State { .FnProto = fn_proto }) catch unreachable;2528 stack.append(State{ .FnProto = fn_proto }) catch unreachable;
2583 continue;2529 continue;
2584 },2530 },
2585 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {2531 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
2586 const fn_proto = try arena.construct(ast.Node.FnProto {2532 const fn_proto = try arena.construct(ast.Node.FnProto{
2587 .base = ast.Node {2533 .base = ast.Node{ .id = ast.Node.Id.FnProto },
2588 .id = ast.Node.Id.FnProto,
2589 },
2590 .doc_comments = null,2534 .doc_comments = null,
2591 .visib_token = null,2535 .visib_token = null,
2592 .name_token = null,2536 .name_token = null,
...@@ -2602,96 +2546,91 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2602,96 +2546,91 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2602 .align_expr = null,2546 .align_expr = null,
2603 });2547 });
2604 opt_ctx.store(&fn_proto.base);2548 opt_ctx.store(&fn_proto.base);
2605 stack.append(State { .FnProto = fn_proto }) catch unreachable;2549 stack.append(State{ .FnProto = fn_proto }) catch unreachable;
2606 try stack.append(State {2550 try stack.append(State{
2607 .ExpectTokenSave = ExpectTokenSave {2551 .ExpectTokenSave = ExpectTokenSave{
2608 .id = Token.Id.Keyword_fn,2552 .id = Token.Id.Keyword_fn,
2609 .ptr = &fn_proto.fn_token2553 .ptr = &fn_proto.fn_token,
2610 }2554 },
2611 });2555 });
2612 continue;2556 continue;
2613 },2557 },
2614 Token.Id.Keyword_asm => {2558 Token.Id.Keyword_asm => {
2615 const node = try createToCtxNode(arena, opt_ctx, ast.Node.Asm,2559 const node = try arena.construct(ast.Node.Asm{
2616 ast.Node.Asm {2560 .base = ast.Node{ .id = ast.Node.Id.Asm },
2617 .base = undefined,2561 .asm_token = token.index,
2618 .asm_token = token.index,2562 .volatile_token = null,
2619 .volatile_token = null,2563 .template = undefined,
2620 .template = undefined,2564 .outputs = ast.Node.Asm.OutputList.init(arena),
2621 .outputs = ast.Node.Asm.OutputList.init(arena),2565 .inputs = ast.Node.Asm.InputList.init(arena),
2622 .inputs = ast.Node.Asm.InputList.init(arena),2566 .clobbers = ast.Node.Asm.ClobberList.init(arena),
2623 .clobbers = ast.Node.Asm.ClobberList.init(arena),2567 .rparen = undefined,
2624 .rparen = undefined,2568 });
2625 }2569 opt_ctx.store(&node.base);
2626 );2570
2627 stack.append(State {2571 stack.append(State{
2628 .ExpectTokenSave = ExpectTokenSave {2572 .ExpectTokenSave = ExpectTokenSave{
2629 .id = Token.Id.RParen,2573 .id = Token.Id.RParen,
2630 .ptr = &node.rparen,2574 .ptr = &node.rparen,
2631 }2575 },
2632 }) catch unreachable;2576 }) catch unreachable;
2633 try stack.append(State { .AsmClobberItems = &node.clobbers });2577 try stack.append(State{ .AsmClobberItems = &node.clobbers });
2634 try stack.append(State { .IfToken = Token.Id.Colon });2578 try stack.append(State{ .IfToken = Token.Id.Colon });
2635 try stack.append(State { .AsmInputItems = &node.inputs });2579 try stack.append(State{ .AsmInputItems = &node.inputs });
2636 try stack.append(State { .IfToken = Token.Id.Colon });2580 try stack.append(State{ .IfToken = Token.Id.Colon });
2637 try stack.append(State { .AsmOutputItems = &node.outputs });2581 try stack.append(State{ .AsmOutputItems = &node.outputs });
2638 try stack.append(State { .IfToken = Token.Id.Colon });2582 try stack.append(State{ .IfToken = Token.Id.Colon });
2639 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.template } });2583 try stack.append(State{ .StringLiteral = OptionalCtx{ .Required = &node.template } });
2640 try stack.append(State { .ExpectToken = Token.Id.LParen });2584 try stack.append(State{ .ExpectToken = Token.Id.LParen });
2641 try stack.append(State {2585 try stack.append(State{
2642 .OptionalTokenSave = OptionalTokenSave {2586 .OptionalTokenSave = OptionalTokenSave{
2643 .id = Token.Id.Keyword_volatile,2587 .id = Token.Id.Keyword_volatile,
2644 .ptr = &node.volatile_token,2588 .ptr = &node.volatile_token,
2645 }2589 },
2646 });2590 });
2647 },2591 },
2648 Token.Id.Keyword_inline => {2592 Token.Id.Keyword_inline => {
2649 stack.append(State {2593 stack.append(State{
2650 .Inline = InlineCtx {2594 .Inline = InlineCtx{
2651 .label = null,2595 .label = null,
2652 .inline_token = token.index,2596 .inline_token = token.index,
2653 .opt_ctx = opt_ctx,2597 .opt_ctx = opt_ctx,
2654 }2598 },
2655 }) catch unreachable;2599 }) catch unreachable;
2656 continue;2600 continue;
2657 },2601 },
2658 else => {2602 else => {
2659 if (!try parseBlockExpr(&stack, arena, opt_ctx, token.ptr, token.index)) {2603 if (!try parseBlockExpr(&stack, arena, opt_ctx, token.ptr, token.index)) {
2660 putBackToken(&tok_it, &tree);2604 prevToken(&tok_it, &tree);
2661 if (opt_ctx != OptionalCtx.Optional) {2605 if (opt_ctx != OptionalCtx.Optional) {
2662 *(try tree.errors.addOne()) = Error {2606 ((try tree.errors.addOne())).* = Error{ .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr{ .token = token.index } };
2663 .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr { .token = token.index },
2664 };
2665 return tree;2607 return tree;
2666 }2608 }
2667 }2609 }
2668 continue;2610 continue;
2669 }2611 },
2670 }2612 }
2671 },2613 },
26722614
2673
2674 State.ErrorTypeOrSetDecl => |ctx| {2615 State.ErrorTypeOrSetDecl => |ctx| {
2675 if (eatToken(&tok_it, &tree, Token.Id.LBrace) == null) {2616 if (eatToken(&tok_it, &tree, Token.Id.LBrace) == null) {
2676 _ = try createToCtxLiteral(arena, ctx.opt_ctx, ast.Node.ErrorType, ctx.error_token);2617 _ = try createToCtxLiteral(arena, ctx.opt_ctx, ast.Node.ErrorType, ctx.error_token);
2677 continue;2618 continue;
2678 }2619 }
26792620
2680 const node = try arena.construct(ast.Node.ErrorSetDecl {2621 const node = try arena.construct(ast.Node.ErrorSetDecl{
2681 .base = ast.Node {2622 .base = ast.Node{ .id = ast.Node.Id.ErrorSetDecl },
2682 .id = ast.Node.Id.ErrorSetDecl,
2683 },
2684 .error_token = ctx.error_token,2623 .error_token = ctx.error_token,
2685 .decls = ast.Node.ErrorSetDecl.DeclList.init(arena),2624 .decls = ast.Node.ErrorSetDecl.DeclList.init(arena),
2686 .rbrace_token = undefined,2625 .rbrace_token = undefined,
2687 });2626 });
2688 ctx.opt_ctx.store(&node.base);2627 ctx.opt_ctx.store(&node.base);
26892628
2690 stack.append(State {2629 stack.append(State{
2691 .ErrorTagListItemOrEnd = ListSave(@typeOf(node.decls)) {2630 .ErrorTagListItemOrEnd = ListSave(@typeOf(node.decls)){
2692 .list = &node.decls,2631 .list = &node.decls,
2693 .ptr = &node.rbrace_token,2632 .ptr = &node.rbrace_token,
2694 }2633 },
2695 }) catch unreachable;2634 }) catch unreachable;
2696 continue;2635 continue;
2697 },2636 },
...@@ -2699,19 +2638,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2699,19 +2638,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2699 const token = nextToken(&tok_it, &tree);2638 const token = nextToken(&tok_it, &tree);
2700 const token_index = token.index;2639 const token_index = token.index;
2701 const token_ptr = token.ptr;2640 const token_ptr = token.ptr;
2702 opt_ctx.store(2641 opt_ctx.store((try parseStringLiteral(arena, &tok_it, token_ptr, token_index, &tree)) ?? {
2703 (try parseStringLiteral(arena, &tok_it, token_ptr, token_index, &tree)) ?? {2642 prevToken(&tok_it, &tree);
2704 putBackToken(&tok_it, &tree);2643 if (opt_ctx != OptionalCtx.Optional) {
2705 if (opt_ctx != OptionalCtx.Optional) {2644 ((try tree.errors.addOne())).* = Error{ .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr{ .token = token_index } };
2706 *(try tree.errors.addOne()) = Error {2645 return tree;
2707 .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr { .token = token_index },
2708 };
2709 return tree;
2710 }
2711
2712 continue;
2713 }2646 }
2714 );2647
2648 continue;
2649 });
2715 },2650 },
27162651
2717 State.Identifier => |opt_ctx| {2652 State.Identifier => |opt_ctx| {
...@@ -2724,8 +2659,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2724,8 +2659,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2724 const token = nextToken(&tok_it, &tree);2659 const token = nextToken(&tok_it, &tree);
2725 const token_index = token.index;2660 const token_index = token.index;
2726 const token_ptr = token.ptr;2661 const token_ptr = token.ptr;
2727 *(try tree.errors.addOne()) = Error {2662 ((try tree.errors.addOne())).* = Error{
2728 .ExpectedToken = Error.ExpectedToken {2663 .ExpectedToken = Error.ExpectedToken{
2729 .token = token_index,2664 .token = token_index,
2730 .expected_id = Token.Id.Identifier,2665 .expected_id = Token.Id.Identifier,
2731 },2666 },
...@@ -2740,8 +2675,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2740,8 +2675,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2740 const ident_token_index = ident_token.index;2675 const ident_token_index = ident_token.index;
2741 const ident_token_ptr = ident_token.ptr;2676 const ident_token_ptr = ident_token.ptr;
2742 if (ident_token_ptr.id != Token.Id.Identifier) {2677 if (ident_token_ptr.id != Token.Id.Identifier) {
2743 *(try tree.errors.addOne()) = Error {2678 ((try tree.errors.addOne())).* = Error{
2744 .ExpectedToken = Error.ExpectedToken {2679 .ExpectedToken = Error.ExpectedToken{
2745 .token = ident_token_index,2680 .token = ident_token_index,
2746 .expected_id = Token.Id.Identifier,2681 .expected_id = Token.Id.Identifier,
2747 },2682 },
...@@ -2749,14 +2684,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2749,14 +2684,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2749 return tree;2684 return tree;
2750 }2685 }
27512686
2752 const node = try arena.construct(ast.Node.ErrorTag {2687 const node = try arena.construct(ast.Node.ErrorTag{
2753 .base = ast.Node {2688 .base = ast.Node{ .id = ast.Node.Id.ErrorTag },
2754 .id = ast.Node.Id.ErrorTag,
2755 },
2756 .doc_comments = comments,2689 .doc_comments = comments,
2757 .name_token = ident_token_index,2690 .name_token = ident_token_index,
2758 });2691 });
2759 *node_ptr = &node.base;2692 node_ptr.* = &node.base;
2760 continue;2693 continue;
2761 },2694 },
27622695
...@@ -2765,8 +2698,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2765,8 +2698,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2765 const token_index = token.index;2698 const token_index = token.index;
2766 const token_ptr = token.ptr;2699 const token_ptr = token.ptr;
2767 if (token_ptr.id != token_id) {2700 if (token_ptr.id != token_id) {
2768 *(try tree.errors.addOne()) = Error {2701 ((try tree.errors.addOne())).* = Error{
2769 .ExpectedToken = Error.ExpectedToken {2702 .ExpectedToken = Error.ExpectedToken{
2770 .token = token_index,2703 .token = token_index,
2771 .expected_id = token_id,2704 .expected_id = token_id,
2772 },2705 },
...@@ -2780,15 +2713,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2780,15 +2713,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2780 const token_index = token.index;2713 const token_index = token.index;
2781 const token_ptr = token.ptr;2714 const token_ptr = token.ptr;
2782 if (token_ptr.id != expect_token_save.id) {2715 if (token_ptr.id != expect_token_save.id) {
2783 *(try tree.errors.addOne()) = Error {2716 ((try tree.errors.addOne())).* = Error{
2784 .ExpectedToken = Error.ExpectedToken {2717 .ExpectedToken = Error.ExpectedToken{
2785 .token = token_index,2718 .token = token_index,
2786 .expected_id = expect_token_save.id,2719 .expected_id = expect_token_save.id,
2787 },2720 },
2788 };2721 };
2789 return tree;2722 return tree;
2790 }2723 }
2791 *expect_token_save.ptr = token_index;2724 expect_token_save.ptr.* = token_index;
2792 continue;2725 continue;
2793 },2726 },
2794 State.IfToken => |token_id| {2727 State.IfToken => |token_id| {
...@@ -2801,7 +2734,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2801,7 +2734,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2801 },2734 },
2802 State.IfTokenSave => |if_token_save| {2735 State.IfTokenSave => |if_token_save| {
2803 if (eatToken(&tok_it, &tree, if_token_save.id)) |token_index| {2736 if (eatToken(&tok_it, &tree, if_token_save.id)) |token_index| {
2804 *if_token_save.ptr = token_index;2737 (if_token_save.ptr).* = token_index;
2805 continue;2738 continue;
2806 }2739 }
28072740
...@@ -2810,7 +2743,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2810,7 +2743,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2810 },2743 },
2811 State.OptionalTokenSave => |optional_token_save| {2744 State.OptionalTokenSave => |optional_token_save| {
2812 if (eatToken(&tok_it, &tree, optional_token_save.id)) |token_index| {2745 if (eatToken(&tok_it, &tree, optional_token_save.id)) |token_index| {
2813 *optional_token_save.ptr = token_index;2746 (optional_token_save.ptr).* = token_index;
2814 continue;2747 continue;
2815 }2748 }
28162749
...@@ -2857,8 +2790,7 @@ const ExternTypeCtx = struct {...@@ -2857,8 +2790,7 @@ const ExternTypeCtx = struct {
28572790
2858const ContainerKindCtx = struct {2791const ContainerKindCtx = struct {
2859 opt_ctx: OptionalCtx,2792 opt_ctx: OptionalCtx,
2860 ltoken: TokenIndex,2793 layout_token: ?TokenIndex,
2861 layout: ast.Node.ContainerDecl.Layout,
2862};2794};
28632795
2864const ExpectTokenSave = struct {2796const ExpectTokenSave = struct {
...@@ -2933,28 +2865,28 @@ const OptionalCtx = union(enum) {...@@ -2933,28 +2865,28 @@ const OptionalCtx = union(enum) {
2933 Required: &&ast.Node,2865 Required: &&ast.Node,
29342866
2935 pub fn store(self: &const OptionalCtx, value: &ast.Node) void {2867 pub fn store(self: &const OptionalCtx, value: &ast.Node) void {
2936 switch (*self) {2868 switch (self.*) {
2937 OptionalCtx.Optional => |ptr| *ptr = value,2869 OptionalCtx.Optional => |ptr| ptr.* = value,
2938 OptionalCtx.RequiredNull => |ptr| *ptr = value,2870 OptionalCtx.RequiredNull => |ptr| ptr.* = value,
2939 OptionalCtx.Required => |ptr| *ptr = value,2871 OptionalCtx.Required => |ptr| ptr.* = value,
2940 }2872 }
2941 }2873 }
29422874
2943 pub fn get(self: &const OptionalCtx) ?&ast.Node {2875 pub fn get(self: &const OptionalCtx) ?&ast.Node {
2944 switch (*self) {2876 switch (self.*) {
2945 OptionalCtx.Optional => |ptr| return *ptr,2877 OptionalCtx.Optional => |ptr| return ptr.*,
2946 OptionalCtx.RequiredNull => |ptr| return ??*ptr,2878 OptionalCtx.RequiredNull => |ptr| return ??ptr.*,
2947 OptionalCtx.Required => |ptr| return *ptr,2879 OptionalCtx.Required => |ptr| return ptr.*,
2948 }2880 }
2949 }2881 }
29502882
2951 pub fn toRequired(self: &const OptionalCtx) OptionalCtx {2883 pub fn toRequired(self: &const OptionalCtx) OptionalCtx {
2952 switch (*self) {2884 switch (self.*) {
2953 OptionalCtx.Optional => |ptr| {2885 OptionalCtx.Optional => |ptr| {
2954 return OptionalCtx { .RequiredNull = ptr };2886 return OptionalCtx{ .RequiredNull = ptr };
2955 },2887 },
2956 OptionalCtx.RequiredNull => |ptr| return *self,2888 OptionalCtx.RequiredNull => |ptr| return self.*,
2957 OptionalCtx.Required => |ptr| return *self,2889 OptionalCtx.Required => |ptr| return self.*,
2958 }2890 }
2959 }2891 }
2960};2892};
...@@ -2979,6 +2911,7 @@ const State = union(enum) {...@@ -2979,6 +2911,7 @@ const State = union(enum) {
2979 VarDecl: VarDeclCtx,2911 VarDecl: VarDeclCtx,
2980 VarDeclAlign: &ast.Node.VarDecl,2912 VarDeclAlign: &ast.Node.VarDecl,
2981 VarDeclEq: &ast.Node.VarDecl,2913 VarDeclEq: &ast.Node.VarDecl,
2914 VarDeclSemiColon: &ast.Node.VarDecl,
29822915
2983 FnDef: &ast.Node.FnProto,2916 FnDef: &ast.Node.FnProto,
2984 FnProto: &ast.Node.FnProto,2917 FnProto: &ast.Node.FnProto,
...@@ -3019,9 +2952,9 @@ const State = union(enum) {...@@ -3019,9 +2952,9 @@ const State = union(enum) {
3019 ErrorTagListCommaOrEnd: ListSave(ast.Node.ErrorSetDecl.DeclList),2952 ErrorTagListCommaOrEnd: ListSave(ast.Node.ErrorSetDecl.DeclList),
3020 SwitchCaseOrEnd: ListSave(ast.Node.Switch.CaseList),2953 SwitchCaseOrEnd: ListSave(ast.Node.Switch.CaseList),
3021 SwitchCaseCommaOrEnd: ListSave(ast.Node.Switch.CaseList),2954 SwitchCaseCommaOrEnd: ListSave(ast.Node.Switch.CaseList),
3022 SwitchCaseFirstItem: &ast.Node.SwitchCase.ItemList,2955 SwitchCaseFirstItem: &ast.Node.SwitchCase,
3023 SwitchCaseItem: &ast.Node.SwitchCase.ItemList,2956 SwitchCaseItemCommaOrEnd: &ast.Node.SwitchCase,
3024 SwitchCaseItemCommaOrEnd: &ast.Node.SwitchCase.ItemList,2957 SwitchCaseItemOrEnd: &ast.Node.SwitchCase,
30252958
3026 SuspendBody: &ast.Node.Suspend,2959 SuspendBody: &ast.Node.Suspend,
3027 AsyncAllocator: &ast.Node.AsyncAttribute,2960 AsyncAllocator: &ast.Node.AsyncAttribute,
...@@ -3031,6 +2964,7 @@ const State = union(enum) {...@@ -3031,6 +2964,7 @@ const State = union(enum) {
3031 SliceOrArrayAccess: &ast.Node.SuffixOp,2964 SliceOrArrayAccess: &ast.Node.SuffixOp,
3032 SliceOrArrayType: &ast.Node.PrefixOp,2965 SliceOrArrayType: &ast.Node.PrefixOp,
3033 AddrOfModifiers: &ast.Node.PrefixOp.AddrOfInfo,2966 AddrOfModifiers: &ast.Node.PrefixOp.AddrOfInfo,
2967 AlignBitRange: &ast.Node.PrefixOp.AddrOfInfo.Align,
30342968
3035 Payload: OptionalCtx,2969 Payload: OptionalCtx,
3036 PointerPayload: OptionalCtx,2970 PointerPayload: OptionalCtx,
...@@ -3075,7 +3009,6 @@ const State = union(enum) {...@@ -3075,7 +3009,6 @@ const State = union(enum) {
3075 Identifier: OptionalCtx,3009 Identifier: OptionalCtx,
3076 ErrorTag: &&ast.Node,3010 ErrorTag: &&ast.Node,
30773011
3078
3079 IfToken: @TagType(Token.Id),3012 IfToken: @TagType(Token.Id),
3080 IfTokenSave: ExpectTokenSave,3013 IfTokenSave: ExpectTokenSave,
3081 ExpectToken: @TagType(Token.Id),3014 ExpectToken: @TagType(Token.Id),
...@@ -3083,25 +3016,27 @@ const State = union(enum) {...@@ -3083,25 +3016,27 @@ const State = union(enum) {
3083 OptionalTokenSave: OptionalTokenSave,3016 OptionalTokenSave: OptionalTokenSave,
3084};3017};
30853018
3019fn pushDocComment(arena: &mem.Allocator, line_comment: TokenIndex, result: &?&ast.Node.DocComment) !void {
3020 const node = blk: {
3021 if (result.*) |comment_node| {
3022 break :blk comment_node;
3023 } else {
3024 const comment_node = try arena.construct(ast.Node.DocComment{
3025 .base = ast.Node{ .id = ast.Node.Id.DocComment },
3026 .lines = ast.Node.DocComment.LineList.init(arena),
3027 });
3028 result.* = comment_node;
3029 break :blk comment_node;
3030 }
3031 };
3032 try node.lines.push(line_comment);
3033}
3034
3086fn eatDocComments(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) !?&ast.Node.DocComment {3035fn eatDocComments(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) !?&ast.Node.DocComment {
3087 var result: ?&ast.Node.DocComment = null;3036 var result: ?&ast.Node.DocComment = null;
3088 while (true) {3037 while (true) {
3089 if (eatToken(tok_it, tree, Token.Id.DocComment)) |line_comment| {3038 if (eatToken(tok_it, tree, Token.Id.DocComment)) |line_comment| {
3090 const node = blk: {3039 try pushDocComment(arena, line_comment, &result);
3091 if (result) |comment_node| {
3092 break :blk comment_node;
3093 } else {
3094 const comment_node = try arena.construct(ast.Node.DocComment {
3095 .base = ast.Node {
3096 .id = ast.Node.Id.DocComment,
3097 },
3098 .lines = ast.Node.DocComment.LineList.init(arena),
3099 });
3100 result = comment_node;
3101 break :blk comment_node;
3102 }
3103 };
3104 try node.lines.push(line_comment);
3105 continue;3040 continue;
3106 }3041 }
3107 break;3042 break;
...@@ -3109,26 +3044,14 @@ fn eatDocComments(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, t...@@ -3109,26 +3044,14 @@ fn eatDocComments(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, t
3109 return result;3044 return result;
3110}3045}
31113046
3112fn eatLineComment(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) !?&ast.Node.LineComment {3047fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, token_ptr: &const Token, token_index: TokenIndex, tree: &ast.Tree) !?&ast.Node {
3113 const token = eatToken(tok_it, tree, Token.Id.LineComment) ?? return null;
3114 return try arena.construct(ast.Node.LineComment {
3115 .base = ast.Node {
3116 .id = ast.Node.Id.LineComment,
3117 },
3118 .token = token,
3119 });
3120}
3121
3122fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator,
3123 token_ptr: &const Token, token_index: TokenIndex, tree: &ast.Tree) !?&ast.Node
3124{
3125 switch (token_ptr.id) {3048 switch (token_ptr.id) {
3126 Token.Id.StringLiteral => {3049 Token.Id.StringLiteral => {
3127 return &(try createLiteral(arena, ast.Node.StringLiteral, token_index)).base;3050 return &(try createLiteral(arena, ast.Node.StringLiteral, token_index)).base;
3128 },3051 },
3129 Token.Id.MultilineStringLiteralLine => {3052 Token.Id.MultilineStringLiteralLine => {
3130 const node = try arena.construct(ast.Node.MultilineStringLiteral {3053 const node = try arena.construct(ast.Node.MultilineStringLiteral{
3131 .base = ast.Node { .id = ast.Node.Id.MultilineStringLiteral },3054 .base = ast.Node{ .id = ast.Node.Id.MultilineStringLiteral },
3132 .lines = ast.Node.MultilineStringLiteral.LineList.init(arena),3055 .lines = ast.Node.MultilineStringLiteral.LineList.init(arena),
3133 });3056 });
3134 try node.lines.push(token_index);3057 try node.lines.push(token_index);
...@@ -3137,7 +3060,7 @@ fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterato...@@ -3137,7 +3060,7 @@ fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterato
3137 const multiline_str_index = multiline_str.index;3060 const multiline_str_index = multiline_str.index;
3138 const multiline_str_ptr = multiline_str.ptr;3061 const multiline_str_ptr = multiline_str.ptr;
3139 if (multiline_str_ptr.id != Token.Id.MultilineStringLiteralLine) {3062 if (multiline_str_ptr.id != Token.Id.MultilineStringLiteralLine) {
3140 putBackToken(tok_it, tree);3063 prevToken(tok_it, tree);
3141 break;3064 break;
3142 }3065 }
31433066
...@@ -3152,71 +3075,66 @@ fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterato...@@ -3152,71 +3075,66 @@ fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterato
3152 }3075 }
3153}3076}
31543077
3155fn parseBlockExpr(stack: &std.ArrayList(State), arena: &mem.Allocator, ctx: &const OptionalCtx,3078fn parseBlockExpr(stack: &std.ArrayList(State), arena: &mem.Allocator, ctx: &const OptionalCtx, token_ptr: &const Token, token_index: TokenIndex) !bool {
3156 token_ptr: &const Token, token_index: TokenIndex) !bool {
3157 switch (token_ptr.id) {3079 switch (token_ptr.id) {
3158 Token.Id.Keyword_suspend => {3080 Token.Id.Keyword_suspend => {
3159 const node = try createToCtxNode(arena, ctx, ast.Node.Suspend,3081 const node = try arena.construct(ast.Node.Suspend{
3160 ast.Node.Suspend {3082 .base = ast.Node{ .id = ast.Node.Id.Suspend },
3161 .base = undefined,3083 .label = null,
3162 .label = null,3084 .suspend_token = token_index,
3163 .suspend_token = token_index,3085 .payload = null,
3164 .payload = null,3086 .body = null,
3165 .body = null,3087 });
3166 }3088 ctx.store(&node.base);
3167 );
31683089
3169 stack.append(State { .SuspendBody = node }) catch unreachable;3090 stack.append(State{ .SuspendBody = node }) catch unreachable;
3170 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });3091 try stack.append(State{ .Payload = OptionalCtx{ .Optional = &node.payload } });
3171 return true;3092 return true;
3172 },3093 },
3173 Token.Id.Keyword_if => {3094 Token.Id.Keyword_if => {
3174 const node = try createToCtxNode(arena, ctx, ast.Node.If,3095 const node = try arena.construct(ast.Node.If{
3175 ast.Node.If {3096 .base = ast.Node{ .id = ast.Node.Id.If },
3176 .base = undefined,3097 .if_token = token_index,
3177 .if_token = token_index,3098 .condition = undefined,
3178 .condition = undefined,3099 .payload = null,
3179 .payload = null,3100 .body = undefined,
3180 .body = undefined,3101 .@"else" = null,
3181 .@"else" = null,3102 });
3182 }3103 ctx.store(&node.base);
3183 );
31843104
3185 stack.append(State { .Else = &node.@"else" }) catch unreachable;3105 stack.append(State{ .Else = &node.@"else" }) catch unreachable;
3186 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });3106 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });
3187 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });3107 try stack.append(State{ .PointerPayload = OptionalCtx{ .Optional = &node.payload } });
3188 try stack.append(State { .ExpectToken = Token.Id.RParen });3108 try stack.append(State{ .ExpectToken = Token.Id.RParen });
3189 try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } });3109 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.condition } });
3190 try stack.append(State { .ExpectToken = Token.Id.LParen });3110 try stack.append(State{ .ExpectToken = Token.Id.LParen });
3191 return true;3111 return true;
3192 },3112 },
3193 Token.Id.Keyword_while => {3113 Token.Id.Keyword_while => {
3194 stack.append(State {3114 stack.append(State{
3195 .While = LoopCtx {3115 .While = LoopCtx{
3196 .label = null,3116 .label = null,
3197 .inline_token = null,3117 .inline_token = null,
3198 .loop_token = token_index,3118 .loop_token = token_index,
3199 .opt_ctx = *ctx,3119 .opt_ctx = ctx.*,
3200 }3120 },
3201 }) catch unreachable;3121 }) catch unreachable;
3202 return true;3122 return true;
3203 },3123 },
3204 Token.Id.Keyword_for => {3124 Token.Id.Keyword_for => {
3205 stack.append(State {3125 stack.append(State{
3206 .For = LoopCtx {3126 .For = LoopCtx{
3207 .label = null,3127 .label = null,
3208 .inline_token = null,3128 .inline_token = null,
3209 .loop_token = token_index,3129 .loop_token = token_index,
3210 .opt_ctx = *ctx,3130 .opt_ctx = ctx.*,
3211 }3131 },
3212 }) catch unreachable;3132 }) catch unreachable;
3213 return true;3133 return true;
3214 },3134 },
3215 Token.Id.Keyword_switch => {3135 Token.Id.Keyword_switch => {
3216 const node = try arena.construct(ast.Node.Switch {3136 const node = try arena.construct(ast.Node.Switch{
3217 .base = ast.Node {3137 .base = ast.Node{ .id = ast.Node.Id.Switch },
3218 .id = ast.Node.Id.Switch,
3219 },
3220 .switch_token = token_index,3138 .switch_token = token_index,
3221 .expr = undefined,3139 .expr = undefined,
3222 .cases = ast.Node.Switch.CaseList.init(arena),3140 .cases = ast.Node.Switch.CaseList.init(arena),
...@@ -3224,45 +3142,45 @@ fn parseBlockExpr(stack: &std.ArrayList(State), arena: &mem.Allocator, ctx: &con...@@ -3224,45 +3142,45 @@ fn parseBlockExpr(stack: &std.ArrayList(State), arena: &mem.Allocator, ctx: &con
3224 });3142 });
3225 ctx.store(&node.base);3143 ctx.store(&node.base);
32263144
3227 stack.append(State {3145 stack.append(State{
3228 .SwitchCaseOrEnd = ListSave(@typeOf(node.cases)) {3146 .SwitchCaseOrEnd = ListSave(@typeOf(node.cases)){
3229 .list = &node.cases,3147 .list = &node.cases,
3230 .ptr = &node.rbrace,3148 .ptr = &node.rbrace,
3231 },3149 },
3232 }) catch unreachable;3150 }) catch unreachable;
3233 try stack.append(State { .ExpectToken = Token.Id.LBrace });3151 try stack.append(State{ .ExpectToken = Token.Id.LBrace });
3234 try stack.append(State { .ExpectToken = Token.Id.RParen });3152 try stack.append(State{ .ExpectToken = Token.Id.RParen });
3235 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });3153 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
3236 try stack.append(State { .ExpectToken = Token.Id.LParen });3154 try stack.append(State{ .ExpectToken = Token.Id.LParen });
3237 return true;3155 return true;
3238 },3156 },
3239 Token.Id.Keyword_comptime => {3157 Token.Id.Keyword_comptime => {
3240 const node = try createToCtxNode(arena, ctx, ast.Node.Comptime,3158 const node = try arena.construct(ast.Node.Comptime{
3241 ast.Node.Comptime {3159 .base = ast.Node{ .id = ast.Node.Id.Comptime },
3242 .base = undefined,3160 .comptime_token = token_index,
3243 .comptime_token = token_index,3161 .expr = undefined,
3244 .expr = undefined,3162 .doc_comments = null,
3245 .doc_comments = null,3163 });
3246 }3164 ctx.store(&node.base);
3247 );3165
3248 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });3166 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
3249 return true;3167 return true;
3250 },3168 },
3251 Token.Id.LBrace => {3169 Token.Id.LBrace => {
3252 const block = try arena.construct(ast.Node.Block {3170 const block = try arena.construct(ast.Node.Block{
3253 .base = ast.Node {.id = ast.Node.Id.Block },3171 .base = ast.Node{ .id = ast.Node.Id.Block },
3254 .label = null,3172 .label = null,
3255 .lbrace = token_index,3173 .lbrace = token_index,
3256 .statements = ast.Node.Block.StatementList.init(arena),3174 .statements = ast.Node.Block.StatementList.init(arena),
3257 .rbrace = undefined,3175 .rbrace = undefined,
3258 });3176 });
3259 ctx.store(&block.base);3177 ctx.store(&block.base);
3260 stack.append(State { .Block = block }) catch unreachable;3178 stack.append(State{ .Block = block }) catch unreachable;
3261 return true;3179 return true;
3262 },3180 },
3263 else => {3181 else => {
3264 return false;3182 return false;
3265 }3183 },
3266 }3184 }
3267}3185}
32683186
...@@ -3276,15 +3194,15 @@ fn expectCommaOrEnd(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree, end:...@@ -3276,15 +3194,15 @@ fn expectCommaOrEnd(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree, end:
3276 const token_index = token.index;3194 const token_index = token.index;
3277 const token_ptr = token.ptr;3195 const token_ptr = token.ptr;
3278 switch (token_ptr.id) {3196 switch (token_ptr.id) {
3279 Token.Id.Comma => return ExpectCommaOrEndResult { .end_token = null},3197 Token.Id.Comma => return ExpectCommaOrEndResult{ .end_token = null },
3280 else => {3198 else => {
3281 if (end == token_ptr.id) {3199 if (end == token_ptr.id) {
3282 return ExpectCommaOrEndResult { .end_token = token_index };3200 return ExpectCommaOrEndResult{ .end_token = token_index };
3283 }3201 }
32843202
3285 return ExpectCommaOrEndResult {3203 return ExpectCommaOrEndResult{
3286 .parse_error = Error {3204 .parse_error = Error{
3287 .ExpectedCommaOrEnd = Error.ExpectedCommaOrEnd {3205 .ExpectedCommaOrEnd = Error.ExpectedCommaOrEnd{
3288 .token = token_index,3206 .token = token_index,
3289 .end_id = end,3207 .end_id = end,
3290 },3208 },
...@@ -3297,127 +3215,103 @@ fn expectCommaOrEnd(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree, end:...@@ -3297,127 +3215,103 @@ fn expectCommaOrEnd(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree, end:
3297fn tokenIdToAssignment(id: &const Token.Id) ?ast.Node.InfixOp.Op {3215fn tokenIdToAssignment(id: &const Token.Id) ?ast.Node.InfixOp.Op {
3298 // TODO: We have to cast all cases because of this:3216 // TODO: We have to cast all cases because of this:
3299 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'3217 // error: expected type '?InfixOp', found '?@TagType(InfixOp)'
3300 return switch (*id) {3218 return switch (id.*) {
3301 Token.Id.AmpersandEqual => ast.Node.InfixOp.Op { .AssignBitAnd = {} },3219 Token.Id.AmpersandEqual => ast.Node.InfixOp.Op{ .AssignBitAnd = {} },
3302 Token.Id.AngleBracketAngleBracketLeftEqual => ast.Node.InfixOp.Op { .AssignBitShiftLeft = {} },3220 Token.Id.AngleBracketAngleBracketLeftEqual => ast.Node.InfixOp.Op{ .AssignBitShiftLeft = {} },
3303 Token.Id.AngleBracketAngleBracketRightEqual => ast.Node.InfixOp.Op { .AssignBitShiftRight = {} },3221 Token.Id.AngleBracketAngleBracketRightEqual => ast.Node.InfixOp.Op{ .AssignBitShiftRight = {} },
3304 Token.Id.AsteriskEqual => ast.Node.InfixOp.Op { .AssignTimes = {} },3222 Token.Id.AsteriskEqual => ast.Node.InfixOp.Op{ .AssignTimes = {} },
3305 Token.Id.AsteriskPercentEqual => ast.Node.InfixOp.Op { .AssignTimesWarp = {} },3223 Token.Id.AsteriskPercentEqual => ast.Node.InfixOp.Op{ .AssignTimesWarp = {} },
3306 Token.Id.CaretEqual => ast.Node.InfixOp.Op { .AssignBitXor = {} },3224 Token.Id.CaretEqual => ast.Node.InfixOp.Op{ .AssignBitXor = {} },
3307 Token.Id.Equal => ast.Node.InfixOp.Op { .Assign = {} },3225 Token.Id.Equal => ast.Node.InfixOp.Op{ .Assign = {} },
3308 Token.Id.MinusEqual => ast.Node.InfixOp.Op { .AssignMinus = {} },3226 Token.Id.MinusEqual => ast.Node.InfixOp.Op{ .AssignMinus = {} },
3309 Token.Id.MinusPercentEqual => ast.Node.InfixOp.Op { .AssignMinusWrap = {} },3227 Token.Id.MinusPercentEqual => ast.Node.InfixOp.Op{ .AssignMinusWrap = {} },
3310 Token.Id.PercentEqual => ast.Node.InfixOp.Op { .AssignMod = {} },3228 Token.Id.PercentEqual => ast.Node.InfixOp.Op{ .AssignMod = {} },
3311 Token.Id.PipeEqual => ast.Node.InfixOp.Op { .AssignBitOr = {} },3229 Token.Id.PipeEqual => ast.Node.InfixOp.Op{ .AssignBitOr = {} },
3312 Token.Id.PlusEqual => ast.Node.InfixOp.Op { .AssignPlus = {} },3230 Token.Id.PlusEqual => ast.Node.InfixOp.Op{ .AssignPlus = {} },
3313 Token.Id.PlusPercentEqual => ast.Node.InfixOp.Op { .AssignPlusWrap = {} },3231 Token.Id.PlusPercentEqual => ast.Node.InfixOp.Op{ .AssignPlusWrap = {} },
3314 Token.Id.SlashEqual => ast.Node.InfixOp.Op { .AssignDiv = {} },3232 Token.Id.SlashEqual => ast.Node.InfixOp.Op{ .AssignDiv = {} },
3315 else => null,3233 else => null,
3316 };3234 };
3317}3235}
33183236
3319fn tokenIdToUnwrapExpr(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {3237fn tokenIdToUnwrapExpr(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
3320 return switch (id) {3238 return switch (id) {
3321 Token.Id.Keyword_catch => ast.Node.InfixOp.Op { .Catch = null },3239 Token.Id.Keyword_catch => ast.Node.InfixOp.Op{ .Catch = null },
3322 Token.Id.QuestionMarkQuestionMark => ast.Node.InfixOp.Op { .UnwrapMaybe = void{} },3240 Token.Id.QuestionMarkQuestionMark => ast.Node.InfixOp.Op{ .UnwrapMaybe = void{} },
3323 else => null,3241 else => null,
3324 };3242 };
3325}3243}
33263244
3327fn tokenIdToComparison(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {3245fn tokenIdToComparison(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
3328 return switch (id) {3246 return switch (id) {
3329 Token.Id.BangEqual => ast.Node.InfixOp.Op { .BangEqual = void{} },3247 Token.Id.BangEqual => ast.Node.InfixOp.Op{ .BangEqual = void{} },
3330 Token.Id.EqualEqual => ast.Node.InfixOp.Op { .EqualEqual = void{} },3248 Token.Id.EqualEqual => ast.Node.InfixOp.Op{ .EqualEqual = void{} },
3331 Token.Id.AngleBracketLeft => ast.Node.InfixOp.Op { .LessThan = void{} },3249 Token.Id.AngleBracketLeft => ast.Node.InfixOp.Op{ .LessThan = void{} },
3332 Token.Id.AngleBracketLeftEqual => ast.Node.InfixOp.Op { .LessOrEqual = void{} },3250 Token.Id.AngleBracketLeftEqual => ast.Node.InfixOp.Op{ .LessOrEqual = void{} },
3333 Token.Id.AngleBracketRight => ast.Node.InfixOp.Op { .GreaterThan = void{} },3251 Token.Id.AngleBracketRight => ast.Node.InfixOp.Op{ .GreaterThan = void{} },
3334 Token.Id.AngleBracketRightEqual => ast.Node.InfixOp.Op { .GreaterOrEqual = void{} },3252 Token.Id.AngleBracketRightEqual => ast.Node.InfixOp.Op{ .GreaterOrEqual = void{} },
3335 else => null,3253 else => null,
3336 };3254 };
3337}3255}
33383256
3339fn tokenIdToBitShift(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {3257fn tokenIdToBitShift(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
3340 return switch (id) {3258 return switch (id) {
3341 Token.Id.AngleBracketAngleBracketLeft => ast.Node.InfixOp.Op { .BitShiftLeft = void{} },3259 Token.Id.AngleBracketAngleBracketLeft => ast.Node.InfixOp.Op{ .BitShiftLeft = void{} },
3342 Token.Id.AngleBracketAngleBracketRight => ast.Node.InfixOp.Op { .BitShiftRight = void{} },3260 Token.Id.AngleBracketAngleBracketRight => ast.Node.InfixOp.Op{ .BitShiftRight = void{} },
3343 else => null,3261 else => null,
3344 };3262 };
3345}3263}
33463264
3347fn tokenIdToAddition(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {3265fn tokenIdToAddition(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
3348 return switch (id) {3266 return switch (id) {
3349 Token.Id.Minus => ast.Node.InfixOp.Op { .Sub = void{} },3267 Token.Id.Minus => ast.Node.InfixOp.Op{ .Sub = void{} },
3350 Token.Id.MinusPercent => ast.Node.InfixOp.Op { .SubWrap = void{} },3268 Token.Id.MinusPercent => ast.Node.InfixOp.Op{ .SubWrap = void{} },
3351 Token.Id.Plus => ast.Node.InfixOp.Op { .Add = void{} },3269 Token.Id.Plus => ast.Node.InfixOp.Op{ .Add = void{} },
3352 Token.Id.PlusPercent => ast.Node.InfixOp.Op { .AddWrap = void{} },3270 Token.Id.PlusPercent => ast.Node.InfixOp.Op{ .AddWrap = void{} },
3353 Token.Id.PlusPlus => ast.Node.InfixOp.Op { .ArrayCat = void{} },3271 Token.Id.PlusPlus => ast.Node.InfixOp.Op{ .ArrayCat = void{} },
3354 else => null,3272 else => null,
3355 };3273 };
3356}3274}
33573275
3358fn tokenIdToMultiply(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {3276fn tokenIdToMultiply(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
3359 return switch (id) {3277 return switch (id) {
3360 Token.Id.Slash => ast.Node.InfixOp.Op { .Div = void{} },3278 Token.Id.Slash => ast.Node.InfixOp.Op{ .Div = void{} },
3361 Token.Id.Asterisk => ast.Node.InfixOp.Op { .Mult = void{} },3279 Token.Id.Asterisk => ast.Node.InfixOp.Op{ .Mult = void{} },
3362 Token.Id.AsteriskAsterisk => ast.Node.InfixOp.Op { .ArrayMult = void{} },3280 Token.Id.AsteriskAsterisk => ast.Node.InfixOp.Op{ .ArrayMult = void{} },
3363 Token.Id.AsteriskPercent => ast.Node.InfixOp.Op { .MultWrap = void{} },3281 Token.Id.AsteriskPercent => ast.Node.InfixOp.Op{ .MultWrap = void{} },
3364 Token.Id.Percent => ast.Node.InfixOp.Op { .Mod = void{} },3282 Token.Id.Percent => ast.Node.InfixOp.Op{ .Mod = void{} },
3365 Token.Id.PipePipe => ast.Node.InfixOp.Op { .MergeErrorSets = void{} },3283 Token.Id.PipePipe => ast.Node.InfixOp.Op{ .MergeErrorSets = void{} },
3366 else => null,3284 else => null,
3367 };3285 };
3368}3286}
33693287
3370fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.Node.PrefixOp.Op {3288fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.Node.PrefixOp.Op {
3371 return switch (id) {3289 return switch (id) {
3372 Token.Id.Bang => ast.Node.PrefixOp.Op { .BoolNot = void{} },3290 Token.Id.Bang => ast.Node.PrefixOp.Op{ .BoolNot = void{} },
3373 Token.Id.Tilde => ast.Node.PrefixOp.Op { .BitNot = void{} },3291 Token.Id.Tilde => ast.Node.PrefixOp.Op{ .BitNot = void{} },
3374 Token.Id.Minus => ast.Node.PrefixOp.Op { .Negation = void{} },3292 Token.Id.Minus => ast.Node.PrefixOp.Op{ .Negation = void{} },
3375 Token.Id.MinusPercent => ast.Node.PrefixOp.Op { .NegationWrap = void{} },3293 Token.Id.MinusPercent => ast.Node.PrefixOp.Op{ .NegationWrap = void{} },
3376 Token.Id.Asterisk, Token.Id.AsteriskAsterisk => ast.Node.PrefixOp.Op { .Deref = void{} },3294 Token.Id.Asterisk, Token.Id.AsteriskAsterisk => ast.Node.PrefixOp.Op{ .PointerType = void{} },
3377 Token.Id.Ampersand => ast.Node.PrefixOp.Op {3295 Token.Id.Ampersand => ast.Node.PrefixOp.Op{
3378 .AddrOf = ast.Node.PrefixOp.AddrOfInfo {3296 .AddrOf = ast.Node.PrefixOp.AddrOfInfo{
3379 .align_expr = null,3297 .align_info = null,
3380 .bit_offset_start_token = null,
3381 .bit_offset_end_token = null,
3382 .const_token = null,3298 .const_token = null,
3383 .volatile_token = null,3299 .volatile_token = null,
3384 },3300 },
3385 },3301 },
3386 Token.Id.QuestionMark => ast.Node.PrefixOp.Op { .MaybeType = void{} },3302 Token.Id.QuestionMark => ast.Node.PrefixOp.Op{ .MaybeType = void{} },
3387 Token.Id.QuestionMarkQuestionMark => ast.Node.PrefixOp.Op { .UnwrapMaybe = void{} },3303 Token.Id.QuestionMarkQuestionMark => ast.Node.PrefixOp.Op{ .UnwrapMaybe = void{} },
3388 Token.Id.Keyword_await => ast.Node.PrefixOp.Op { .Await = void{} },3304 Token.Id.Keyword_await => ast.Node.PrefixOp.Op{ .Await = void{} },
3389 Token.Id.Keyword_try => ast.Node.PrefixOp.Op { .Try = void{ } },3305 Token.Id.Keyword_try => ast.Node.PrefixOp.Op{ .Try = void{} },
3390 else => null,3306 else => null,
3391 };3307 };
3392}3308}
33933309
3394fn createNode(arena: &mem.Allocator, comptime T: type, init_to: &const T) !&T {
3395 const node = try arena.create(T);
3396 *node = *init_to;
3397 node.base = blk: {
3398 const id = ast.Node.typeToId(T);
3399 break :blk ast.Node {
3400 .id = id,
3401 };
3402 };
3403
3404 return node;
3405}
3406
3407fn createToCtxNode(arena: &mem.Allocator, opt_ctx: &const OptionalCtx, comptime T: type, init_to: &const T) !&T {
3408 const node = try createNode(arena, T, init_to);
3409 opt_ctx.store(&node.base);
3410
3411 return node;
3412}
3413
3414fn createLiteral(arena: &mem.Allocator, comptime T: type, token_index: TokenIndex) !&T {3310fn createLiteral(arena: &mem.Allocator, comptime T: type, token_index: TokenIndex) !&T {
3415 return createNode(arena, T,3311 return arena.construct(T{
3416 T {3312 .base = ast.Node{ .id = ast.Node.typeToId(T) },
3417 .base = undefined,3313 .token = token_index,
3418 .token = token_index,3314 });
3419 }
3420 );
3421}3315}
34223316
3423fn createToCtxLiteral(arena: &mem.Allocator, opt_ctx: &const OptionalCtx, comptime T: type, token_index: TokenIndex) !&T {3317fn createToCtxLiteral(arena: &mem.Allocator, opt_ctx: &const OptionalCtx, comptime T: type, token_index: TokenIndex) !&T {
...@@ -3428,73 +3322,34 @@ fn createToCtxLiteral(arena: &mem.Allocator, opt_ctx: &const OptionalCtx, compti...@@ -3428,73 +3322,34 @@ fn createToCtxLiteral(arena: &mem.Allocator, opt_ctx: &const OptionalCtx, compti
3428}3322}
34293323
3430fn eatToken(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree, id: @TagType(Token.Id)) ?TokenIndex {3324fn eatToken(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree, id: @TagType(Token.Id)) ?TokenIndex {
3431 const token = nextToken(tok_it, tree);3325 const token = ??tok_it.peek();
34323326
3433 if (token.ptr.id == id)3327 if (token.id == id) {
3434 return token.index;3328 return nextToken(tok_it, tree).index;
3329 }
34353330
3436 putBackToken(tok_it, tree);
3437 return null;3331 return null;
3438}3332}
34393333
3440fn nextToken(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) AnnotatedToken {3334fn nextToken(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) AnnotatedToken {
3441 const result = AnnotatedToken {3335 const result = AnnotatedToken{
3442 .index = tok_it.index,3336 .index = tok_it.index,
3443 .ptr = ??tok_it.next(),3337 .ptr = ??tok_it.next(),
3444 };3338 };
3445 // possibly skip a following same line token3339 assert(result.ptr.id != Token.Id.LineComment);
3446 const token = tok_it.next() ?? return result;
3447 if (token.id != Token.Id.LineComment) {
3448 putBackToken(tok_it, tree);
3449 return result;
3450 }
3451 const loc = tree.tokenLocationPtr(result.ptr.end, token);
3452 if (loc.line != 0) {
3453 putBackToken(tok_it, tree);
3454 }
3455 return result;
3456}
34573340
3458fn putBackToken(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) void {3341 while (true) {
3459 const prev_tok = ??tok_it.prev();3342 const next_tok = tok_it.peek() ?? return result;
3460 if (prev_tok.id == Token.Id.LineComment) {3343 if (next_tok.id != Token.Id.LineComment) return result;
3461 const minus2_tok = tok_it.prev() ?? return;3344 _ = tok_it.next();
3462 const loc = tree.tokenLocationPtr(minus2_tok.end, prev_tok);
3463 if (loc.line != 0) {
3464 _ = tok_it.next();
3465 }
3466 }3345 }
3467}3346}
34683347
3469const RenderAstFrame = struct {3348fn prevToken(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) void {
3470 node: &ast.Node,3349 while (true) {
3471 indent: usize,3350 const prev_tok = tok_it.prev() ?? return;
3472};3351 if (prev_tok.id == Token.Id.LineComment) continue;
34733352 return;
3474pub fn renderAst(allocator: &mem.Allocator, tree: &const ast.Tree, stream: var) !void {
3475 var stack = std.ArrayList(State).init(allocator);
3476 defer stack.deinit();
3477
3478 try stack.append(RenderAstFrame {
3479 .node = &root_node.base,
3480 .indent = 0,
3481 });
3482
3483 while (stack.popOrNull()) |frame| {
3484 {
3485 var i: usize = 0;
3486 while (i < frame.indent) : (i += 1) {
3487 try stream.print(" ");
3488 }
3489 }
3490 try stream.print("{}\n", @tagName(frame.node.id));
3491 var child_i: usize = 0;
3492 while (frame.node.iterate(child_i)) |child| : (child_i += 1) {
3493 try stack.append(RenderAstFrame {
3494 .node = child,
3495 .indent = frame.indent + 2,
3496 });
3497 }
3498 }3353 }
3499}3354}
35003355
std/zig/parser_test.zig+720-20
...@@ -1,3 +1,701 @@...@@ -1,3 +1,701 @@
1test "zig fmt: async call in if condition" {
2 try testCanonical(
3 \\comptime {
4 \\ if (async<a> b()) {
5 \\ a();
6 \\ }
7 \\}
8 \\
9 );
10}
11
12test "zig fmt: 2nd arg multiline string" {
13 try testCanonical(
14 \\comptime {
15 \\ cases.addAsm("hello world linux x86_64",
16 \\ \\.text
17 \\ , "Hello, world!\n");
18 \\}
19 \\
20 );
21}
22
23test "zig fmt: if condition wraps" {
24 try testTransform(
25 \\comptime {
26 \\ if (cond and
27 \\ cond) {
28 \\ return x;
29 \\ }
30 \\ while (cond and
31 \\ cond) {
32 \\ return x;
33 \\ }
34 \\ if (a == b and
35 \\ c) {
36 \\ a = b;
37 \\ }
38 \\ while (a == b and
39 \\ c) {
40 \\ a = b;
41 \\ }
42 \\ if ((cond and
43 \\ cond)) {
44 \\ return x;
45 \\ }
46 \\ while ((cond and
47 \\ cond)) {
48 \\ return x;
49 \\ }
50 \\ var a = if (a) |*f| x: {
51 \\ break :x &a.b;
52 \\ } else |err| err;
53 \\}
54 ,
55 \\comptime {
56 \\ if (cond and
57 \\ cond)
58 \\ {
59 \\ return x;
60 \\ }
61 \\ while (cond and
62 \\ cond)
63 \\ {
64 \\ return x;
65 \\ }
66 \\ if (a == b and
67 \\ c)
68 \\ {
69 \\ a = b;
70 \\ }
71 \\ while (a == b and
72 \\ c)
73 \\ {
74 \\ a = b;
75 \\ }
76 \\ if ((cond and
77 \\ cond))
78 \\ {
79 \\ return x;
80 \\ }
81 \\ while ((cond and
82 \\ cond))
83 \\ {
84 \\ return x;
85 \\ }
86 \\ var a = if (a) |*f| x: {
87 \\ break :x &a.b;
88 \\ } else |err| err;
89 \\}
90 \\
91 );
92}
93
94test "zig fmt: if condition has line break but must not wrap" {
95 try testCanonical(
96 \\comptime {
97 \\ if (self.user_input_options.put(name, UserInputOption{
98 \\ .name = name,
99 \\ .used = false,
100 \\ }) catch unreachable) |*prev_value| {
101 \\ foo();
102 \\ bar();
103 \\ }
104 \\ if (put(
105 \\ a,
106 \\ b,
107 \\ )) {
108 \\ foo();
109 \\ }
110 \\}
111 \\
112 );
113}
114
115test "zig fmt: same-line doc comment on variable declaration" {
116 try testTransform(
117 \\pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space
118 \\pub const MAP_FILE = 0x0000; /// map from file (default)
119 \\
120 \\pub const EMEDIUMTYPE = 124; /// Wrong medium type
121 \\
122 \\// nameserver query return codes
123 \\pub const ENSROK = 0; /// DNS server returned answer with no data
124 ,
125 \\/// allocated from memory, swap space
126 \\pub const MAP_ANONYMOUS = 0x1000;
127 \\/// map from file (default)
128 \\pub const MAP_FILE = 0x0000;
129 \\
130 \\/// Wrong medium type
131 \\pub const EMEDIUMTYPE = 124;
132 \\
133 \\// nameserver query return codes
134 \\/// DNS server returned answer with no data
135 \\pub const ENSROK = 0;
136 \\
137 );
138}
139
140test "zig fmt: if-else with comment before else" {
141 try testCanonical(
142 \\comptime {
143 \\ // cexp(finite|nan +- i inf|nan) = nan + i nan
144 \\ if ((hx & 0x7fffffff) != 0x7f800000) {
145 \\ return Complex(f32).new(y - y, y - y);
146 \\ } // cexp(-inf +- i inf|nan) = 0 + i0
147 \\ else if (hx & 0x80000000 != 0) {
148 \\ return Complex(f32).new(0, 0);
149 \\ } // cexp(+inf +- i inf|nan) = inf + i nan
150 \\ else {
151 \\ return Complex(f32).new(x, y - y);
152 \\ }
153 \\}
154 \\
155 );
156}
157
158test "zig fmt: respect line breaks in if-else" {
159 try testCanonical(
160 \\comptime {
161 \\ return if (cond) a else b;
162 \\ return if (cond)
163 \\ a
164 \\ else
165 \\ b;
166 \\ return if (cond)
167 \\ a
168 \\ else if (cond)
169 \\ b
170 \\ else
171 \\ c;
172 \\}
173 \\
174 );
175}
176
177test "zig fmt: respect line breaks after infix operators" {
178 try testCanonical(
179 \\comptime {
180 \\ self.crc =
181 \\ lookup_tables[0][p[7]] ^
182 \\ lookup_tables[1][p[6]] ^
183 \\ lookup_tables[2][p[5]] ^
184 \\ lookup_tables[3][p[4]] ^
185 \\ lookup_tables[4][@truncate(u8, self.crc >> 24)] ^
186 \\ lookup_tables[5][@truncate(u8, self.crc >> 16)] ^
187 \\ lookup_tables[6][@truncate(u8, self.crc >> 8)] ^
188 \\ lookup_tables[7][@truncate(u8, self.crc >> 0)];
189 \\}
190 \\
191 );
192}
193
194test "zig fmt: fn decl with trailing comma" {
195 try testTransform(
196 \\fn foo(a: i32, b: i32,) void {}
197 ,
198 \\fn foo(
199 \\ a: i32,
200 \\ b: i32,
201 \\) void {}
202 \\
203 );
204}
205
206test "zig fmt: enum decl with no trailing comma" {
207 try testTransform(
208 \\const StrLitKind = enum {Normal, C};
209 ,
210 \\const StrLitKind = enum {
211 \\ Normal,
212 \\ C,
213 \\};
214 \\
215 );
216}
217
218test "zig fmt: switch comment before prong" {
219 try testCanonical(
220 \\comptime {
221 \\ switch (a) {
222 \\ // hi
223 \\ 0 => {},
224 \\ }
225 \\}
226 \\
227 );
228}
229
230test "zig fmt: struct literal no trailing comma" {
231 try testTransform(
232 \\const a = foo{ .x = 1, .y = 2 };
233 \\const a = foo{ .x = 1,
234 \\ .y = 2 };
235 ,
236 \\const a = foo{ .x = 1, .y = 2 };
237 \\const a = foo{
238 \\ .x = 1,
239 \\ .y = 2,
240 \\};
241 \\
242 );
243}
244
245test "zig fmt: array literal with hint" {
246 try testTransform(
247 \\const a = []u8{
248 \\ 1, 2, //
249 \\ 3,
250 \\ 4,
251 \\ 5,
252 \\ 6,
253 \\ 7 };
254 \\const a = []u8{
255 \\ 1, 2, //
256 \\ 3,
257 \\ 4,
258 \\ 5,
259 \\ 6,
260 \\ 7, 8 };
261 \\const a = []u8{
262 \\ 1, 2, //
263 \\ 3,
264 \\ 4,
265 \\ 5,
266 \\ 6, // blah
267 \\ 7, 8 };
268 \\const a = []u8{
269 \\ 1, 2, //
270 \\ 3, //
271 \\ 4,
272 \\ 5,
273 \\ 6,
274 \\ 7 };
275 \\const a = []u8{
276 \\ 1,
277 \\ 2,
278 \\ 3, 4, //
279 \\ 5, 6, //
280 \\ 7, 8, //
281 \\};
282 ,
283 \\const a = []u8{
284 \\ 1, 2,
285 \\ 3, 4,
286 \\ 5, 6,
287 \\ 7,
288 \\};
289 \\const a = []u8{
290 \\ 1, 2,
291 \\ 3, 4,
292 \\ 5, 6,
293 \\ 7, 8,
294 \\};
295 \\const a = []u8{
296 \\ 1, 2,
297 \\ 3, 4,
298 \\ 5, 6, // blah
299 \\ 7, 8,
300 \\};
301 \\const a = []u8{
302 \\ 1, 2,
303 \\ 3, //
304 \\ 4,
305 \\ 5, 6,
306 \\ 7,
307 \\};
308 \\const a = []u8{
309 \\ 1,
310 \\ 2,
311 \\ 3,
312 \\ 4,
313 \\ 5,
314 \\ 6,
315 \\ 7,
316 \\ 8,
317 \\};
318 \\
319 );
320}
321
322test "zig fmt: multiline string with backslash at end of line" {
323 try testCanonical(
324 \\comptime {
325 \\ err(
326 \\ \\\
327 \\ );
328 \\}
329 \\
330 );
331}
332
333test "zig fmt: multiline string parameter in fn call with trailing comma" {
334 try testCanonical(
335 \\fn foo() void {
336 \\ try stdout.print(
337 \\ \\ZIG_CMAKE_BINARY_DIR {}
338 \\ \\ZIG_C_HEADER_FILES {}
339 \\ \\ZIG_DIA_GUIDS_LIB {}
340 \\ \\
341 \\ ,
342 \\ std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR),
343 \\ std.cstr.toSliceConst(c.ZIG_CXX_COMPILER),
344 \\ std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB),
345 \\ );
346 \\}
347 \\
348 );
349}
350
351test "zig fmt: trailing comma on fn call" {
352 try testCanonical(
353 \\comptime {
354 \\ var module = try Module.create(
355 \\ allocator,
356 \\ zig_lib_dir,
357 \\ full_cache_dir,
358 \\ );
359 \\}
360 \\
361 );
362}
363
364test "zig fmt: empty block with only comment" {
365 try testCanonical(
366 \\comptime {
367 \\ {
368 \\ // comment
369 \\ }
370 \\}
371 \\
372 );
373}
374
375test "zig fmt: no trailing comma on struct decl" {
376 try testTransform(
377 \\const RoundParam = struct {
378 \\ k: usize, s: u32, t: u32
379 \\};
380 ,
381 \\const RoundParam = struct {
382 \\ k: usize,
383 \\ s: u32,
384 \\ t: u32,
385 \\};
386 \\
387 );
388}
389
390test "zig fmt: simple asm" {
391 try testTransform(
392 \\comptime {
393 \\ asm volatile (
394 \\ \\.globl aoeu;
395 \\ \\.type aoeu, @function;
396 \\ \\.set aoeu, derp;
397 \\ );
398 \\
399 \\ asm ("not real assembly"
400 \\ :[a] "x" (x),);
401 \\ asm ("not real assembly"
402 \\ :[a] "x" (->i32),:[a] "x" (1),);
403 \\ asm ("still not real assembly"
404 \\ :::"a","b",);
405 \\}
406 ,
407 \\comptime {
408 \\ asm volatile (
409 \\ \\.globl aoeu;
410 \\ \\.type aoeu, @function;
411 \\ \\.set aoeu, derp;
412 \\ );
413 \\
414 \\ asm ("not real assembly"
415 \\ : [a] "x" (x)
416 \\ );
417 \\ asm ("not real assembly"
418 \\ : [a] "x" (-> i32)
419 \\ : [a] "x" (1)
420 \\ );
421 \\ asm ("still not real assembly"
422 \\ :
423 \\ :
424 \\ : "a", "b"
425 \\ );
426 \\}
427 \\
428 );
429}
430
431test "zig fmt: nested struct literal with one item" {
432 try testCanonical(
433 \\const a = foo{
434 \\ .item = bar{ .a = b },
435 \\};
436 \\
437 );
438}
439
440test "zig fmt: switch cases trailing comma" {
441 try testTransform(
442 \\fn switch_cases(x: i32) void {
443 \\ switch (x) {
444 \\ 1,2,3 => {},
445 \\ 4,5, => {},
446 \\ 6... 8, => {},
447 \\ else => {},
448 \\ }
449 \\}
450 ,
451 \\fn switch_cases(x: i32) void {
452 \\ switch (x) {
453 \\ 1, 2, 3 => {},
454 \\ 4,
455 \\ 5,
456 \\ => {},
457 \\ 6...8 => {},
458 \\ else => {},
459 \\ }
460 \\}
461 \\
462 );
463}
464
465test "zig fmt: slice align" {
466 try testCanonical(
467 \\const A = struct {
468 \\ items: []align(A) T,
469 \\};
470 \\
471 );
472}
473
474test "zig fmt: add trailing comma to array literal" {
475 try testTransform(
476 \\comptime {
477 \\ return []u16{'m', 's', 'y', 's', '-' // hi
478 \\ };
479 \\ return []u16{'m', 's', 'y', 's',
480 \\ '-'};
481 \\ return []u16{'m', 's', 'y', 's', '-'};
482 \\}
483 ,
484 \\comptime {
485 \\ return []u16{
486 \\ 'm', 's', 'y', 's', '-', // hi
487 \\ };
488 \\ return []u16{
489 \\ 'm', 's', 'y', 's',
490 \\ '-',
491 \\ };
492 \\ return []u16{ 'm', 's', 'y', 's', '-' };
493 \\}
494 \\
495 );
496}
497
498test "zig fmt: first thing in file is line comment" {
499 try testCanonical(
500 \\// Introspection and determination of system libraries needed by zig.
501 \\
502 \\// Introspection and determination of system libraries needed by zig.
503 \\
504 \\const std = @import("std");
505 \\
506 );
507}
508
509test "zig fmt: line comment after doc comment" {
510 try testCanonical(
511 \\/// doc comment
512 \\// line comment
513 \\fn foo() void {}
514 \\
515 );
516}
517
518test "zig fmt: float literal with exponent" {
519 try testCanonical(
520 \\test "bit field alignment" {
521 \\ assert(@typeOf(&blah.b) == &align(1:3:6) const u3);
522 \\}
523 \\
524 );
525}
526
527test "zig fmt: float literal with exponent" {
528 try testCanonical(
529 \\test "aoeu" {
530 \\ switch (state) {
531 \\ TermState.Start => switch (c) {
532 \\ '\x1b' => state = TermState.Escape,
533 \\ else => try out.writeByte(c),
534 \\ },
535 \\ }
536 \\}
537 \\
538 );
539}
540test "zig fmt: float literal with exponent" {
541 try testCanonical(
542 \\pub const f64_true_min = 4.94065645841246544177e-324;
543 \\const threshold = 0x1.a827999fcef32p+1022;
544 \\
545 );
546}
547
548test "zig fmt: if-else end of comptime" {
549 try testCanonical(
550 \\comptime {
551 \\ if (a) {
552 \\ b();
553 \\ } else {
554 \\ b();
555 \\ }
556 \\}
557 \\
558 );
559}
560
561test "zig fmt: nested blocks" {
562 try testCanonical(
563 \\comptime {
564 \\ {
565 \\ {
566 \\ {
567 \\ a();
568 \\ }
569 \\ }
570 \\ }
571 \\}
572 \\
573 );
574}
575
576test "zig fmt: block with same line comment after end brace" {
577 try testCanonical(
578 \\comptime {
579 \\ {
580 \\ b();
581 \\ } // comment
582 \\}
583 \\
584 );
585}
586
587test "zig fmt: statements with comment between" {
588 try testCanonical(
589 \\comptime {
590 \\ a = b;
591 \\ // comment
592 \\ a = b;
593 \\}
594 \\
595 );
596}
597
598test "zig fmt: statements with empty line between" {
599 try testCanonical(
600 \\comptime {
601 \\ a = b;
602 \\
603 \\ a = b;
604 \\}
605 \\
606 );
607}
608
609test "zig fmt: ptr deref operator" {
610 try testCanonical(
611 \\const a = b.*;
612 \\
613 );
614}
615
616test "zig fmt: comment after if before another if" {
617 try testCanonical(
618 \\test "aoeu" {
619 \\ // comment
620 \\ if (x) {
621 \\ bar();
622 \\ }
623 \\}
624 \\
625 \\test "aoeu" {
626 \\ if (x) {
627 \\ foo();
628 \\ }
629 \\ // comment
630 \\ if (x) {
631 \\ bar();
632 \\ }
633 \\}
634 \\
635 );
636}
637
638test "zig fmt: line comment between if block and else keyword" {
639 try testCanonical(
640 \\test "aoeu" {
641 \\ // cexp(finite|nan +- i inf|nan) = nan + i nan
642 \\ if ((hx & 0x7fffffff) != 0x7f800000) {
643 \\ return Complex(f32).new(y - y, y - y);
644 \\ }
645 \\ // cexp(-inf +- i inf|nan) = 0 + i0
646 \\ else if (hx & 0x80000000 != 0) {
647 \\ return Complex(f32).new(0, 0);
648 \\ }
649 \\ // cexp(+inf +- i inf|nan) = inf + i nan
650 \\ // another comment
651 \\ else {
652 \\ return Complex(f32).new(x, y - y);
653 \\ }
654 \\}
655 \\
656 );
657}
658
659test "zig fmt: same line comments in expression" {
660 try testCanonical(
661 \\test "aoeu" {
662 \\ const x = ( // a
663 \\ 0 // b
664 \\ ); // c
665 \\}
666 \\
667 );
668}
669
670test "zig fmt: add comma on last switch prong" {
671 try testTransform(
672 \\test "aoeu" {
673 \\switch (self.init_arg_expr) {
674 \\ InitArg.Type => |t| { },
675 \\ InitArg.None,
676 \\ InitArg.Enum => { }
677 \\}
678 \\ switch (self.init_arg_expr) {
679 \\ InitArg.Type => |t| { },
680 \\ InitArg.None,
681 \\ InitArg.Enum => { }//line comment
682 \\ }
683 \\}
684 ,
685 \\test "aoeu" {
686 \\ switch (self.init_arg_expr) {
687 \\ InitArg.Type => |t| {},
688 \\ InitArg.None, InitArg.Enum => {},
689 \\ }
690 \\ switch (self.init_arg_expr) {
691 \\ InitArg.Type => |t| {},
692 \\ InitArg.None, InitArg.Enum => {}, //line comment
693 \\ }
694 \\}
695 \\
696 );
697}
698
1test "zig fmt: same-line comment after a statement" {699test "zig fmt: same-line comment after a statement" {
2 try testCanonical(700 try testCanonical(
3 \\test "" {701 \\test "" {
...@@ -71,13 +769,6 @@ test "zig fmt: switch with empty body" {...@@ -71,13 +769,6 @@ test "zig fmt: switch with empty body" {
71 );769 );
72}770}
73771
74test "zig fmt: float literal with exponent" {
75 try testCanonical(
76 \\pub const f64_true_min = 4.94065645841246544177e-324;
77 \\
78 );
79}
80
81test "zig fmt: line comments in struct initializer" {772test "zig fmt: line comments in struct initializer" {
82 try testCanonical(773 try testCanonical(
83 \\fn foo() void {774 \\fn foo() void {
...@@ -330,7 +1021,7 @@ test "zig fmt: extern declaration" {...@@ -330,7 +1021,7 @@ test "zig fmt: extern declaration" {
330}1021}
3311022
332test "zig fmt: alignment" {1023test "zig fmt: alignment" {
333 try testCanonical(1024 try testCanonical(
334 \\var foo: c_int align(1);1025 \\var foo: c_int align(1);
335 \\1026 \\
336 );1027 );
...@@ -379,7 +1070,7 @@ test "zig fmt: slice attributes" {...@@ -379,7 +1070,7 @@ test "zig fmt: slice attributes" {
379}1070}
3801071
381test "zig fmt: test declaration" {1072test "zig fmt: test declaration" {
382 try testCanonical(1073 try testCanonical(
383 \\test "test name" {1074 \\test "test name" {
384 \\ const a = 1;1075 \\ const a = 1;
385 \\ var b = 1;1076 \\ var b = 1;
...@@ -539,6 +1230,11 @@ test "zig fmt: multiline string" {...@@ -539,6 +1230,11 @@ test "zig fmt: multiline string" {
539 \\ c\\two)1230 \\ c\\two)
540 \\ c\\three1231 \\ c\\three
541 \\ ;1232 \\ ;
1233 \\ const s3 = // hi
1234 \\ \\one
1235 \\ \\two)
1236 \\ \\three
1237 \\ ;
542 \\}1238 \\}
543 \\1239 \\
544 );1240 );
...@@ -616,7 +1312,7 @@ test "zig fmt: struct declaration" {...@@ -616,7 +1312,7 @@ test "zig fmt: struct declaration" {
616}1312}
6171313
618test "zig fmt: enum declaration" {1314test "zig fmt: enum declaration" {
619 try testCanonical(1315 try testCanonical(
620 \\const E = enum {1316 \\const E = enum {
621 \\ Ok,1317 \\ Ok,
622 \\ SomethingElse = 0,1318 \\ SomethingElse = 0,
...@@ -644,7 +1340,7 @@ test "zig fmt: enum declaration" {...@@ -644,7 +1340,7 @@ test "zig fmt: enum declaration" {
644}1340}
6451341
646test "zig fmt: union declaration" {1342test "zig fmt: union declaration" {
647 try testCanonical(1343 try testCanonical(
648 \\const U = union {1344 \\const U = union {
649 \\ Int: u8,1345 \\ Int: u8,
650 \\ Float: f32,1346 \\ Float: f32,
...@@ -759,9 +1455,8 @@ test "zig fmt: switch" {...@@ -759,9 +1455,8 @@ test "zig fmt: switch" {
759 \\ switch (0) {1455 \\ switch (0) {
760 \\ 0 => {},1456 \\ 0 => {},
761 \\ 1 => unreachable,1457 \\ 1 => unreachable,
762 \\ 2,1458 \\ 2, 3 => {},
763 \\ 3 => {},1459 \\ 4...7 => {},
764 \\ 4 ... 7 => {},
765 \\ 1 + 4 * 3 + 22 => {},1460 \\ 1 + 4 * 3 + 22 => {},
766 \\ else => {1461 \\ else => {
767 \\ const a = 1;1462 \\ const a = 1;
...@@ -1021,7 +1716,8 @@ test "zig fmt: inline asm" {...@@ -1021,7 +1716,8 @@ test "zig fmt: inline asm" {
1021 \\ : [ret] "={rax}" (-> usize)1716 \\ : [ret] "={rax}" (-> usize)
1022 \\ : [number] "{rax}" (number),1717 \\ : [number] "{rax}" (number),
1023 \\ [arg1] "{rdi}" (arg1)1718 \\ [arg1] "{rdi}" (arg1)
1024 \\ : "rcx", "r11");1719 \\ : "rcx", "r11"
1720 \\ );
1025 \\}1721 \\}
1026 \\1722 \\
1027 );1723 );
...@@ -1164,10 +1860,15 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {...@@ -1164,10 +1860,15 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
1164 } else |err| switch (err) {1860 } else |err| switch (err) {
1165 error.OutOfMemory => {1861 error.OutOfMemory => {
1166 if (failing_allocator.allocated_bytes != failing_allocator.freed_bytes) {1862 if (failing_allocator.allocated_bytes != failing_allocator.freed_bytes) {
1167 warn("\nfail_index: {}/{}\nallocated bytes: {}\nfreed bytes: {}\nallocations: {}\ndeallocations: {}\n",1863 warn(
1168 fail_index, needed_alloc_count,1864 "\nfail_index: {}/{}\nallocated bytes: {}\nfreed bytes: {}\nallocations: {}\ndeallocations: {}\n",
1169 failing_allocator.allocated_bytes, failing_allocator.freed_bytes,1865 fail_index,
1170 failing_allocator.index, failing_allocator.deallocations);1866 needed_alloc_count,
1867 failing_allocator.allocated_bytes,
1868 failing_allocator.freed_bytes,
1869 failing_allocator.index,
1870 failing_allocator.deallocations,
1871 );
1171 return error.MemoryLeakDetected;1872 return error.MemoryLeakDetected;
1172 }1873 }
1173 },1874 },
...@@ -1180,4 +1881,3 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {...@@ -1180,4 +1881,3 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
1180fn testCanonical(source: []const u8) !void {1881fn testCanonical(source: []const u8) !void {
1181 return testTransform(source, source);1882 return testTransform(source, source);
1182}1883}
1183
std/zig/render.zig+1767-1132
...@@ -1,1270 +1,1905 @@...@@ -1,1270 +1,1905 @@
1const std = @import("../index.zig");1const std = @import("../index.zig");
2const builtin = @import("builtin");
2const assert = std.debug.assert;3const assert = std.debug.assert;
3const mem = std.mem;4const mem = std.mem;
4const ast = std.zig.ast;5const ast = std.zig.ast;
5const Token = std.zig.Token;6const Token = std.zig.Token;
67
7const RenderState = union(enum) {
8 TopLevelDecl: &ast.Node,
9 ParamDecl: &ast.Node,
10 Text: []const u8,
11 Expression: &ast.Node,
12 VarDecl: &ast.Node.VarDecl,
13 Statement: &ast.Node,
14 PrintIndent,
15 Indent: usize,
16 MaybeSemiColon: &ast.Node,
17 Token: ast.TokenIndex,
18 NonBreakToken: ast.TokenIndex,
19};
20
21const indent_delta = 4;8const indent_delta = 4;
229
23pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {10pub const Error = error{
24 var stack = std.ArrayList(RenderState).init(allocator);11 /// Ran out of memory allocating call stack frames to complete rendering.
25 defer stack.deinit();12 OutOfMemory,
2613};
27 {14
28 try stack.append(RenderState { .Text = "\n"});15pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf(stream).Child.Error || Error)!void {
2916 comptime assert(@typeId(@typeOf(stream)) == builtin.TypeId.Pointer);
30 var i = tree.root_node.decls.len;17
31 while (i != 0) {18 // render all the line comments at the beginning of the file
32 i -= 1;19 var tok_it = tree.tokens.iterator(0);
33 const decl = *tree.root_node.decls.at(i);20 while (tok_it.next()) |token| {
34 try stack.append(RenderState {.TopLevelDecl = decl});21 if (token.id != Token.Id.LineComment) break;
35 if (i != 0) {22 try stream.print("{}\n", mem.trimRight(u8, tree.tokenSlicePtr(token), " "));
36 try stack.append(RenderState {23 if (tok_it.peek()) |next_token| {
37 .Text = blk: {24 const loc = tree.tokenLocationPtr(token.end, next_token);
38 const prev_node = *tree.root_node.decls.at(i - 1);25 if (loc.line >= 2) {
39 const prev_node_last_token = tree.tokens.at(prev_node.lastToken());26 try stream.writeByte('\n');
40 const loc = tree.tokenLocation(prev_node_last_token.end, decl.firstToken());
41 if (loc.line >= 2) {
42 break :blk "\n\n";
43 }
44 break :blk "\n";
45 },
46 });
47 }27 }
48 }28 }
49 }29 }
5030
51 var indent: usize = 0;31 var start_col: usize = 0;
52 while (stack.popOrNull()) |state| {32 var it = tree.root_node.decls.iterator(0);
53 switch (state) {33 while (it.next()) |decl| {
54 RenderState.TopLevelDecl => |decl| {34 try renderTopLevelDecl(allocator, stream, tree, 0, &start_col, decl.*);
55 switch (decl.id) {35 if (it.peek()) |next_decl| {
56 ast.Node.Id.FnProto => {36 try renderExtraNewline(tree, stream, &start_col, next_decl.*);
57 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);37 }
58 try renderComments(tree, stream, fn_proto, indent);38 }
5939}
60 if (fn_proto.body_node) |body_node| {
61 stack.append(RenderState { .Expression = body_node}) catch unreachable;
62 try stack.append(RenderState { .Text = " "});
63 } else {
64 stack.append(RenderState { .Text = ";" }) catch unreachable;
65 }
6640
67 try stack.append(RenderState { .Expression = decl });41fn renderExtraNewline(tree: &ast.Tree, stream: var, start_col: &usize, node: &ast.Node) !void {
68 },42 const first_token = node.firstToken();
69 ast.Node.Id.Use => {43 var prev_token = first_token;
70 const use_decl = @fieldParentPtr(ast.Node.Use, "base", decl);44 while (tree.tokens.at(prev_token - 1).id == Token.Id.DocComment) {
71 if (use_decl.visib_token) |visib_token| {45 prev_token -= 1;
72 try stream.print("{} ", tree.tokenSlice(visib_token));46 }
73 }47 const prev_token_end = tree.tokens.at(prev_token - 1).end;
74 try stream.print("use ");48 const loc = tree.tokenLocation(prev_token_end, first_token);
75 try stack.append(RenderState { .Text = ";" });49 if (loc.line >= 2) {
76 try stack.append(RenderState { .Expression = use_decl.expr });50 try stream.writeByte('\n');
77 },51 start_col.* = 0;
78 ast.Node.Id.VarDecl => {52 }
79 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl);53}
80 try renderComments(tree, stream, var_decl, indent);
81 try stack.append(RenderState { .VarDecl = var_decl});
82 },
83 ast.Node.Id.TestDecl => {
84 const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl);
85 try renderComments(tree, stream, test_decl, indent);
86 try stream.print("test ");
87 try stack.append(RenderState { .Expression = test_decl.body_node });
88 try stack.append(RenderState { .Text = " " });
89 try stack.append(RenderState { .Expression = test_decl.name });
90 },
91 ast.Node.Id.StructField => {
92 const field = @fieldParentPtr(ast.Node.StructField, "base", decl);
93 try renderComments(tree, stream, field, indent);
94 if (field.visib_token) |visib_token| {
95 try stream.print("{} ", tree.tokenSlice(visib_token));
96 }
97 try stream.print("{}: ", tree.tokenSlice(field.name_token));
98 try stack.append(RenderState { .Token = field.lastToken() + 1 });
99 try stack.append(RenderState { .Expression = field.type_expr});
100 },
101 ast.Node.Id.UnionTag => {
102 const tag = @fieldParentPtr(ast.Node.UnionTag, "base", decl);
103 try renderComments(tree, stream, tag, indent);
104 try stream.print("{}", tree.tokenSlice(tag.name_token));
105
106 try stack.append(RenderState { .Text = "," });
107
108 if (tag.value_expr) |value_expr| {
109 try stack.append(RenderState { .Expression = value_expr });
110 try stack.append(RenderState { .Text = " = " });
111 }
11254
113 if (tag.type_expr) |type_expr| {55fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, start_col: &usize, decl: &ast.Node) (@typeOf(stream).Child.Error || Error)!void {
114 try stream.print(": ");56 switch (decl.id) {
115 try stack.append(RenderState { .Expression = type_expr});57 ast.Node.Id.FnProto => {
116 }58 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);
117 },
118 ast.Node.Id.EnumTag => {
119 const tag = @fieldParentPtr(ast.Node.EnumTag, "base", decl);
120 try renderComments(tree, stream, tag, indent);
121 try stream.print("{}", tree.tokenSlice(tag.name_token));
122
123 try stack.append(RenderState { .Text = "," });
124 if (tag.value) |value| {
125 try stream.print(" = ");
126 try stack.append(RenderState { .Expression = value});
127 }
128 },
129 ast.Node.Id.ErrorTag => {
130 const tag = @fieldParentPtr(ast.Node.ErrorTag, "base", decl);
131 try renderComments(tree, stream, tag, indent);
132 try stream.print("{}", tree.tokenSlice(tag.name_token));
133 },
134 ast.Node.Id.Comptime => {
135 try stack.append(RenderState { .MaybeSemiColon = decl });
136 try stack.append(RenderState { .Expression = decl });
137 },
138 ast.Node.Id.LineComment => {
139 const line_comment_node = @fieldParentPtr(ast.Node.LineComment, "base", decl);
140 try stream.write(tree.tokenSlice(line_comment_node.token));
141 },
142 else => unreachable,
143 }
144 },
14559
146 RenderState.VarDecl => |var_decl| {60 try renderDocComments(tree, stream, fn_proto, indent, start_col);
147 try stack.append(RenderState { .Token = var_decl.semicolon_token });
148 if (var_decl.init_node) |init_node| {
149 try stack.append(RenderState { .Expression = init_node });
150 const text = if (init_node.id == ast.Node.Id.MultilineStringLiteral) " =" else " = ";
151 try stack.append(RenderState { .Text = text });
152 }
153 if (var_decl.align_node) |align_node| {
154 try stack.append(RenderState { .Text = ")" });
155 try stack.append(RenderState { .Expression = align_node });
156 try stack.append(RenderState { .Text = " align(" });
157 }
158 if (var_decl.type_node) |type_node| {
159 try stack.append(RenderState { .Expression = type_node });
160 try stack.append(RenderState { .Text = ": " });
161 }
162 try stack.append(RenderState { .Text = tree.tokenSlice(var_decl.name_token) });
163 try stack.append(RenderState { .Text = " " });
164 try stack.append(RenderState { .Text = tree.tokenSlice(var_decl.mut_token) });
16561
166 if (var_decl.comptime_token) |comptime_token| {62 if (fn_proto.body_node) |body_node| {
167 try stack.append(RenderState { .Text = " " });63 try renderExpression(allocator, stream, tree, indent, start_col, decl, Space.Space);
168 try stack.append(RenderState { .Text = tree.tokenSlice(comptime_token) });64 try renderExpression(allocator, stream, tree, indent, start_col, body_node, Space.Newline);
169 }65 } else {
66 try renderExpression(allocator, stream, tree, indent, start_col, decl, Space.None);
67 try renderToken(tree, stream, tree.nextToken(decl.lastToken()), indent, start_col, Space.Newline);
68 }
69 },
17070
171 if (var_decl.extern_export_token) |extern_export_token| {71 ast.Node.Id.Use => {
172 if (var_decl.lib_name != null) {72 const use_decl = @fieldParentPtr(ast.Node.Use, "base", decl);
173 try stack.append(RenderState { .Text = " " });
174 try stack.append(RenderState { .Expression = ??var_decl.lib_name });
175 }
176 try stack.append(RenderState { .Text = " " });
177 try stack.append(RenderState { .Text = tree.tokenSlice(extern_export_token) });
178 }
17973
180 if (var_decl.visib_token) |visib_token| {74 if (use_decl.visib_token) |visib_token| {
181 try stack.append(RenderState { .Text = " " });75 try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
182 try stack.append(RenderState { .Text = tree.tokenSlice(visib_token) });76 }
183 }77 try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // use
184 },78 try renderExpression(allocator, stream, tree, indent, start_col, use_decl.expr, Space.None);
79 try renderToken(tree, stream, use_decl.semicolon_token, indent, start_col, Space.Newline); // ;
80 },
18581
186 RenderState.ParamDecl => |base| {82 ast.Node.Id.VarDecl => {
187 const param_decl = @fieldParentPtr(ast.Node.ParamDecl, "base", base);83 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl);
188 if (param_decl.comptime_token) |comptime_token| {84
189 try stream.print("{} ", tree.tokenSlice(comptime_token));85 try renderDocComments(tree, stream, var_decl, indent, start_col);
190 }86 try renderVarDecl(allocator, stream, tree, indent, start_col, var_decl);
191 if (param_decl.noalias_token) |noalias_token| {87 },
192 try stream.print("{} ", tree.tokenSlice(noalias_token));88
193 }89 ast.Node.Id.TestDecl => {
194 if (param_decl.name_token) |name_token| {90 const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl);
195 try stream.print("{}: ", tree.tokenSlice(name_token));91
196 }92 try renderDocComments(tree, stream, test_decl, indent, start_col);
197 if (param_decl.var_args_token) |var_args_token| {93 try renderToken(tree, stream, test_decl.test_token, indent, start_col, Space.Space);
198 try stream.print("{}", tree.tokenSlice(var_args_token));94 try renderExpression(allocator, stream, tree, indent, start_col, test_decl.name, Space.Space);
95 try renderExpression(allocator, stream, tree, indent, start_col, test_decl.body_node, Space.Newline);
96 },
97
98 ast.Node.Id.StructField => {
99 const field = @fieldParentPtr(ast.Node.StructField, "base", decl);
100
101 try renderDocComments(tree, stream, field, indent, start_col);
102 if (field.visib_token) |visib_token| {
103 try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
104 }
105 try renderToken(tree, stream, field.name_token, indent, start_col, Space.None); // name
106 try renderToken(tree, stream, tree.nextToken(field.name_token), indent, start_col, Space.Space); // :
107 try renderExpression(allocator, stream, tree, indent, start_col, field.type_expr, Space.Comma); // type,
108 },
109
110 ast.Node.Id.UnionTag => {
111 const tag = @fieldParentPtr(ast.Node.UnionTag, "base", decl);
112
113 try renderDocComments(tree, stream, tag, indent, start_col);
114
115 if (tag.type_expr == null and tag.value_expr == null) {
116 return renderToken(tree, stream, tag.name_token, indent, start_col, Space.Comma); // name,
117 }
118
119 if (tag.type_expr == null) {
120 try renderToken(tree, stream, tag.name_token, indent, start_col, Space.Space); // name
121 } else {
122 try renderToken(tree, stream, tag.name_token, indent, start_col, Space.None); // name
123 }
124
125 if (tag.type_expr) |type_expr| {
126 try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, start_col, Space.Space); // :
127
128 if (tag.value_expr == null) {
129 try renderExpression(allocator, stream, tree, indent, start_col, type_expr, Space.Comma); // type,
130 return;
199 } else {131 } else {
200 try stack.append(RenderState { .Expression = param_decl.type_node});132 try renderExpression(allocator, stream, tree, indent, start_col, type_expr, Space.Space); // type
201 }133 }
202 },134 }
203 RenderState.Text => |bytes| {
204 try stream.write(bytes);
205 },
206 RenderState.Expression => |base| switch (base.id) {
207 ast.Node.Id.Identifier => {
208 const identifier = @fieldParentPtr(ast.Node.Identifier, "base", base);
209 try stream.print("{}", tree.tokenSlice(identifier.token));
210 },
211 ast.Node.Id.Block => {
212 const block = @fieldParentPtr(ast.Node.Block, "base", base);
213 if (block.label) |label| {
214 try stream.print("{}: ", tree.tokenSlice(label));
215 }
216135
217 if (block.statements.len == 0) {136 const value_expr = ??tag.value_expr;
218 try stream.write("{}");137 try renderToken(tree, stream, tree.prevToken(value_expr.firstToken()), indent, start_col, Space.Space); // =
219 } else {138 try renderExpression(allocator, stream, tree, indent, start_col, value_expr, Space.Comma); // value,
220 try stream.write("{");139 },
221 try stack.append(RenderState { .Text = "}"});
222 try stack.append(RenderState.PrintIndent);
223 try stack.append(RenderState { .Indent = indent});
224 try stack.append(RenderState { .Text = "\n"});
225 var i = block.statements.len;
226 while (i != 0) {
227 i -= 1;
228 const statement_node = *block.statements.at(i);
229 try stack.append(RenderState { .Statement = statement_node});
230 try stack.append(RenderState.PrintIndent);
231 try stack.append(RenderState { .Indent = indent + indent_delta});
232 try stack.append(RenderState {
233 .Text = blk: {
234 if (i != 0) {
235 const prev_node = *block.statements.at(i - 1);
236 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;
237 const loc = tree.tokenLocation(prev_node_last_token_end, statement_node.firstToken());
238 if (loc.line >= 2) {
239 break :blk "\n\n";
240 }
241 }
242 break :blk "\n";
243 },
244 });
245 }
246 }
247 },
248 ast.Node.Id.Defer => {
249 const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base);
250 try stream.print("{} ", tree.tokenSlice(defer_node.defer_token));
251 try stack.append(RenderState { .Expression = defer_node.expr });
252 },
253 ast.Node.Id.Comptime => {
254 const comptime_node = @fieldParentPtr(ast.Node.Comptime, "base", base);
255 try stream.print("{} ", tree.tokenSlice(comptime_node.comptime_token));
256 try stack.append(RenderState { .Expression = comptime_node.expr });
257 },
258 ast.Node.Id.AsyncAttribute => {
259 const async_attr = @fieldParentPtr(ast.Node.AsyncAttribute, "base", base);
260 try stream.print("{}", tree.tokenSlice(async_attr.async_token));
261
262 if (async_attr.allocator_type) |allocator_type| {
263 try stack.append(RenderState { .Text = ">" });
264 try stack.append(RenderState { .Expression = allocator_type });
265 try stack.append(RenderState { .Text = "<" });
266 }
267 },
268 ast.Node.Id.Suspend => {
269 const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base);
270 if (suspend_node.label) |label| {
271 try stream.print("{}: ", tree.tokenSlice(label));
272 }
273 try stream.print("{}", tree.tokenSlice(suspend_node.suspend_token));
274140
275 if (suspend_node.body) |body| {141 ast.Node.Id.EnumTag => {
276 try stack.append(RenderState { .Expression = body });142 const tag = @fieldParentPtr(ast.Node.EnumTag, "base", decl);
277 try stack.append(RenderState { .Text = " " });
278 }
279143
280 if (suspend_node.payload) |payload| {144 try renderDocComments(tree, stream, tag, indent, start_col);
281 try stack.append(RenderState { .Expression = payload });
282 try stack.append(RenderState { .Text = " " });
283 }
284 },
285 ast.Node.Id.InfixOp => {
286 const prefix_op_node = @fieldParentPtr(ast.Node.InfixOp, "base", base);
287 try stack.append(RenderState { .Expression = prefix_op_node.rhs });
288
289 if (prefix_op_node.op == ast.Node.InfixOp.Op.Catch) {
290 if (prefix_op_node.op.Catch) |payload| {
291 try stack.append(RenderState { .Text = " " });
292 try stack.append(RenderState { .Expression = payload });
293 }
294 try stack.append(RenderState { .Text = " catch " });
295 } else {
296 const text = switch (prefix_op_node.op) {
297 ast.Node.InfixOp.Op.Add => " + ",
298 ast.Node.InfixOp.Op.AddWrap => " +% ",
299 ast.Node.InfixOp.Op.ArrayCat => " ++ ",
300 ast.Node.InfixOp.Op.ArrayMult => " ** ",
301 ast.Node.InfixOp.Op.Assign => " = ",
302 ast.Node.InfixOp.Op.AssignBitAnd => " &= ",
303 ast.Node.InfixOp.Op.AssignBitOr => " |= ",
304 ast.Node.InfixOp.Op.AssignBitShiftLeft => " <<= ",
305 ast.Node.InfixOp.Op.AssignBitShiftRight => " >>= ",
306 ast.Node.InfixOp.Op.AssignBitXor => " ^= ",
307 ast.Node.InfixOp.Op.AssignDiv => " /= ",
308 ast.Node.InfixOp.Op.AssignMinus => " -= ",
309 ast.Node.InfixOp.Op.AssignMinusWrap => " -%= ",
310 ast.Node.InfixOp.Op.AssignMod => " %= ",
311 ast.Node.InfixOp.Op.AssignPlus => " += ",
312 ast.Node.InfixOp.Op.AssignPlusWrap => " +%= ",
313 ast.Node.InfixOp.Op.AssignTimes => " *= ",
314 ast.Node.InfixOp.Op.AssignTimesWarp => " *%= ",
315 ast.Node.InfixOp.Op.BangEqual => " != ",
316 ast.Node.InfixOp.Op.BitAnd => " & ",
317 ast.Node.InfixOp.Op.BitOr => " | ",
318 ast.Node.InfixOp.Op.BitShiftLeft => " << ",
319 ast.Node.InfixOp.Op.BitShiftRight => " >> ",
320 ast.Node.InfixOp.Op.BitXor => " ^ ",
321 ast.Node.InfixOp.Op.BoolAnd => " and ",
322 ast.Node.InfixOp.Op.BoolOr => " or ",
323 ast.Node.InfixOp.Op.Div => " / ",
324 ast.Node.InfixOp.Op.EqualEqual => " == ",
325 ast.Node.InfixOp.Op.ErrorUnion => "!",
326 ast.Node.InfixOp.Op.GreaterOrEqual => " >= ",
327 ast.Node.InfixOp.Op.GreaterThan => " > ",
328 ast.Node.InfixOp.Op.LessOrEqual => " <= ",
329 ast.Node.InfixOp.Op.LessThan => " < ",
330 ast.Node.InfixOp.Op.MergeErrorSets => " || ",
331 ast.Node.InfixOp.Op.Mod => " % ",
332 ast.Node.InfixOp.Op.Mult => " * ",
333 ast.Node.InfixOp.Op.MultWrap => " *% ",
334 ast.Node.InfixOp.Op.Period => ".",
335 ast.Node.InfixOp.Op.Sub => " - ",
336 ast.Node.InfixOp.Op.SubWrap => " -% ",
337 ast.Node.InfixOp.Op.UnwrapMaybe => " ?? ",
338 ast.Node.InfixOp.Op.Range => " ... ",
339 ast.Node.InfixOp.Op.Catch => unreachable,
340 };
341145
342 try stack.append(RenderState { .Text = text });146 if (tag.value) |value| {
343 }147 try renderToken(tree, stream, tag.name_token, indent, start_col, Space.Space); // name
344 try stack.append(RenderState { .Expression = prefix_op_node.lhs });
345 },
346 ast.Node.Id.PrefixOp => {
347 const prefix_op_node = @fieldParentPtr(ast.Node.PrefixOp, "base", base);
348 try stack.append(RenderState { .Expression = prefix_op_node.rhs });
349 switch (prefix_op_node.op) {
350 ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| {
351 try stream.write("&");
352 if (addr_of_info.volatile_token != null) {
353 try stack.append(RenderState { .Text = "volatile "});
354 }
355 if (addr_of_info.const_token != null) {
356 try stack.append(RenderState { .Text = "const "});
357 }
358 if (addr_of_info.align_expr) |align_expr| {
359 try stream.print("align(");
360 try stack.append(RenderState { .Text = ") "});
361 try stack.append(RenderState { .Expression = align_expr});
362 }
363 },
364 ast.Node.PrefixOp.Op.SliceType => |addr_of_info| {
365 try stream.write("[]");
366 if (addr_of_info.volatile_token != null) {
367 try stack.append(RenderState { .Text = "volatile "});
368 }
369 if (addr_of_info.const_token != null) {
370 try stack.append(RenderState { .Text = "const "});
371 }
372 if (addr_of_info.align_expr) |align_expr| {
373 try stream.print("align(");
374 try stack.append(RenderState { .Text = ") "});
375 try stack.append(RenderState { .Expression = align_expr});
376 }
377 },
378 ast.Node.PrefixOp.Op.ArrayType => |array_index| {
379 try stack.append(RenderState { .Text = "]"});
380 try stack.append(RenderState { .Expression = array_index});
381 try stack.append(RenderState { .Text = "["});
382 },
383 ast.Node.PrefixOp.Op.BitNot => try stream.write("~"),
384 ast.Node.PrefixOp.Op.BoolNot => try stream.write("!"),
385 ast.Node.PrefixOp.Op.Deref => try stream.write("*"),
386 ast.Node.PrefixOp.Op.Negation => try stream.write("-"),
387 ast.Node.PrefixOp.Op.NegationWrap => try stream.write("-%"),
388 ast.Node.PrefixOp.Op.Try => try stream.write("try "),
389 ast.Node.PrefixOp.Op.UnwrapMaybe => try stream.write("??"),
390 ast.Node.PrefixOp.Op.MaybeType => try stream.write("?"),
391 ast.Node.PrefixOp.Op.Await => try stream.write("await "),
392 ast.Node.PrefixOp.Op.Cancel => try stream.write("cancel "),
393 ast.Node.PrefixOp.Op.Resume => try stream.write("resume "),
394 }
395 },
396 ast.Node.Id.SuffixOp => {
397 const suffix_op = @fieldParentPtr(ast.Node.SuffixOp, "base", base);
398
399 switch (suffix_op.op) {
400 @TagType(ast.Node.SuffixOp.Op).Call => |*call_info| {
401 try stack.append(RenderState { .Text = ")"});
402 var i = call_info.params.len;
403 while (i != 0) {
404 i -= 1;
405 const param_node = *call_info.params.at(i);
406 try stack.append(RenderState { .Expression = param_node});
407 if (i != 0) {
408 try stack.append(RenderState { .Text = ", " });
409 }
410 }
411 try stack.append(RenderState { .Text = "("});
412 try stack.append(RenderState { .Expression = suffix_op.lhs });
413148
414 if (call_info.async_attr) |async_attr| {149 try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, start_col, Space.Space); // =
415 try stack.append(RenderState { .Text = " "});150 try renderExpression(allocator, stream, tree, indent, start_col, value, Space.Comma);
416 try stack.append(RenderState { .Expression = &async_attr.base });151 } else {
417 }152 try renderToken(tree, stream, tag.name_token, indent, start_col, Space.Comma); // name
418 },153 }
419 ast.Node.SuffixOp.Op.ArrayAccess => |index_expr| {154 },
420 try stack.append(RenderState { .Text = "]"});
421 try stack.append(RenderState { .Expression = index_expr});
422 try stack.append(RenderState { .Text = "["});
423 try stack.append(RenderState { .Expression = suffix_op.lhs });
424 },
425 @TagType(ast.Node.SuffixOp.Op).Slice => |range| {
426 try stack.append(RenderState { .Text = "]"});
427 if (range.end) |end| {
428 try stack.append(RenderState { .Expression = end});
429 }
430 try stack.append(RenderState { .Text = ".."});
431 try stack.append(RenderState { .Expression = range.start});
432 try stack.append(RenderState { .Text = "["});
433 try stack.append(RenderState { .Expression = suffix_op.lhs });
434 },
435 ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {
436 if (field_inits.len == 0) {
437 try stack.append(RenderState { .Text = "{}" });
438 try stack.append(RenderState { .Expression = suffix_op.lhs });
439 continue;
440 }
441 if (field_inits.len == 1) {
442 const field_init = *field_inits.at(0);
443
444 try stack.append(RenderState { .Text = " }" });
445 try stack.append(RenderState { .Expression = field_init });
446 try stack.append(RenderState { .Text = "{ " });
447 try stack.append(RenderState { .Expression = suffix_op.lhs });
448 continue;
449 }
450 try stack.append(RenderState { .Text = "}"});
451 try stack.append(RenderState.PrintIndent);
452 try stack.append(RenderState { .Indent = indent });
453 try stack.append(RenderState { .Text = "\n" });
454 var i = field_inits.len;
455 while (i != 0) {
456 i -= 1;
457 const field_init = *field_inits.at(i);
458 if (field_init.id != ast.Node.Id.LineComment) {
459 try stack.append(RenderState { .Text = "," });
460 }
461 try stack.append(RenderState { .Expression = field_init });
462 try stack.append(RenderState.PrintIndent);
463 if (i != 0) {
464 try stack.append(RenderState { .Text = blk: {
465 const prev_node = *field_inits.at(i - 1);
466 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;
467 const loc = tree.tokenLocation(prev_node_last_token_end, field_init.firstToken());
468 if (loc.line >= 2) {
469 break :blk "\n\n";
470 }
471 break :blk "\n";
472 }});
473 }
474 }
475 try stack.append(RenderState { .Indent = indent + indent_delta });
476 try stack.append(RenderState { .Text = "{\n"});
477 try stack.append(RenderState { .Expression = suffix_op.lhs });
478 },
479 ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {
480 if (exprs.len == 0) {
481 try stack.append(RenderState { .Text = "{}" });
482 try stack.append(RenderState { .Expression = suffix_op.lhs });
483 continue;
484 }
485 if (exprs.len == 1) {
486 const expr = *exprs.at(0);
487
488 try stack.append(RenderState { .Text = "}" });
489 try stack.append(RenderState { .Expression = expr });
490 try stack.append(RenderState { .Text = "{" });
491 try stack.append(RenderState { .Expression = suffix_op.lhs });
492 continue;
493 }
494155
495 try stack.append(RenderState { .Text = "}"});156 ast.Node.Id.Comptime => {
496 try stack.append(RenderState.PrintIndent);157 assert(!decl.requireSemiColon());
497 try stack.append(RenderState { .Indent = indent });158 try renderExpression(allocator, stream, tree, indent, start_col, decl, Space.Newline);
498 var i = exprs.len;159 },
499 while (i != 0) {160 else => unreachable,
500 i -= 1;161 }
501 const expr = *exprs.at(i);162}
502 try stack.append(RenderState { .Text = ",\n" });
503 try stack.append(RenderState { .Expression = expr });
504 try stack.append(RenderState.PrintIndent);
505 }
506 try stack.append(RenderState { .Indent = indent + indent_delta });
507 try stack.append(RenderState { .Text = "{\n"});
508 try stack.append(RenderState { .Expression = suffix_op.lhs });
509 },
510 }
511 },
512 ast.Node.Id.ControlFlowExpression => {
513 const flow_expr = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", base);
514163
515 if (flow_expr.rhs) |rhs| {164fn renderExpression(
516 try stack.append(RenderState { .Expression = rhs });165 allocator: &mem.Allocator,
517 try stack.append(RenderState { .Text = " " });166 stream: var,
518 }167 tree: &ast.Tree,
168 indent: usize,
169 start_col: &usize,
170 base: &ast.Node,
171 space: Space,
172) (@typeOf(stream).Child.Error || Error)!void {
173 switch (base.id) {
174 ast.Node.Id.Identifier => {
175 const identifier = @fieldParentPtr(ast.Node.Identifier, "base", base);
176 return renderToken(tree, stream, identifier.token, indent, start_col, space);
177 },
178 ast.Node.Id.Block => {
179 const block = @fieldParentPtr(ast.Node.Block, "base", base);
180
181 if (block.label) |label| {
182 try renderToken(tree, stream, label, indent, start_col, Space.None);
183 try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space);
184 }
519185
520 switch (flow_expr.kind) {186 if (block.statements.len == 0) {
521 ast.Node.ControlFlowExpression.Kind.Break => |maybe_label| {187 try renderToken(tree, stream, block.lbrace, indent + indent_delta, start_col, Space.None);
522 try stream.print("break");188 return renderToken(tree, stream, block.rbrace, indent, start_col, space);
523 if (maybe_label) |label| {189 } else {
524 try stream.print(" :");190 const block_indent = indent + indent_delta;
525 try stack.append(RenderState { .Expression = label });191 try renderToken(tree, stream, block.lbrace, block_indent, start_col, Space.Newline);
526 }
527 },
528 ast.Node.ControlFlowExpression.Kind.Continue => |maybe_label| {
529 try stream.print("continue");
530 if (maybe_label) |label| {
531 try stream.print(" :");
532 try stack.append(RenderState { .Expression = label });
533 }
534 },
535 ast.Node.ControlFlowExpression.Kind.Return => {
536 try stream.print("return");
537 },
538192
539 }193 var it = block.statements.iterator(0);
540 },194 while (it.next()) |statement| {
541 ast.Node.Id.Payload => {195 try stream.writeByteNTimes(' ', block_indent);
542 const payload = @fieldParentPtr(ast.Node.Payload, "base", base);196 try renderStatement(allocator, stream, tree, block_indent, start_col, statement.*);
543 try stack.append(RenderState { .Text = "|"});
544 try stack.append(RenderState { .Expression = payload.error_symbol });
545 try stack.append(RenderState { .Text = "|"});
546 },
547 ast.Node.Id.PointerPayload => {
548 const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base);
549 try stack.append(RenderState { .Text = "|"});
550 try stack.append(RenderState { .Expression = payload.value_symbol });
551197
552 if (payload.ptr_token) |ptr_token| {198 if (it.peek()) |next_statement| {
553 try stack.append(RenderState { .Text = tree.tokenSlice(ptr_token) });199 try renderExtraNewline(tree, stream, start_col, next_statement.*);
554 }200 }
201 }
555202
556 try stack.append(RenderState { .Text = "|"});203 try stream.writeByteNTimes(' ', indent);
557 },204 return renderToken(tree, stream, block.rbrace, indent, start_col, space);
558 ast.Node.Id.PointerIndexPayload => {205 }
559 const payload = @fieldParentPtr(ast.Node.PointerIndexPayload, "base", base);206 },
560 try stack.append(RenderState { .Text = "|"});207 ast.Node.Id.Defer => {
208 const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base);
209
210 try renderToken(tree, stream, defer_node.defer_token, indent, start_col, Space.Space);
211 return renderExpression(allocator, stream, tree, indent, start_col, defer_node.expr, space);
212 },
213 ast.Node.Id.Comptime => {
214 const comptime_node = @fieldParentPtr(ast.Node.Comptime, "base", base);
215
216 try renderToken(tree, stream, comptime_node.comptime_token, indent, start_col, Space.Space);
217 return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);
218 },
219
220 ast.Node.Id.AsyncAttribute => {
221 const async_attr = @fieldParentPtr(ast.Node.AsyncAttribute, "base", base);
222
223 if (async_attr.allocator_type) |allocator_type| {
224 try renderToken(tree, stream, async_attr.async_token, indent, start_col, Space.None); // async
225
226 try renderToken(tree, stream, tree.nextToken(async_attr.async_token), indent, start_col, Space.None); // <
227 try renderExpression(allocator, stream, tree, indent, start_col, allocator_type, Space.None); // allocator
228 return renderToken(tree, stream, tree.nextToken(allocator_type.lastToken()), indent, start_col, space); // >
229 } else {
230 return renderToken(tree, stream, async_attr.async_token, indent, start_col, space); // async
231 }
232 },
561233
562 if (payload.index_symbol) |index_symbol| {234 ast.Node.Id.Suspend => {
563 try stack.append(RenderState { .Expression = index_symbol });235 const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base);
564 try stack.append(RenderState { .Text = ", "});
565 }
566236
567 try stack.append(RenderState { .Expression = payload.value_symbol });237 if (suspend_node.label) |label| {
238 try renderToken(tree, stream, label, indent, start_col, Space.None);
239 try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space);
240 }
568241
569 if (payload.ptr_token) |ptr_token| {242 if (suspend_node.payload) |payload| {
570 try stack.append(RenderState { .Text = tree.tokenSlice(ptr_token) });243 if (suspend_node.body) |body| {
571 }244 try renderToken(tree, stream, suspend_node.suspend_token, indent, start_col, Space.Space);
245 try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
246 return renderExpression(allocator, stream, tree, indent, start_col, body, space);
247 } else {
248 try renderToken(tree, stream, suspend_node.suspend_token, indent, start_col, Space.Space);
249 return renderExpression(allocator, stream, tree, indent, start_col, payload, space);
250 }
251 } else if (suspend_node.body) |body| {
252 try renderToken(tree, stream, suspend_node.suspend_token, indent, start_col, Space.Space);
253 return renderExpression(allocator, stream, tree, indent, start_col, body, space);
254 } else {
255 return renderToken(tree, stream, suspend_node.suspend_token, indent, start_col, space);
256 }
257 },
572258
573 try stack.append(RenderState { .Text = "|"});259 ast.Node.Id.InfixOp => {
574 },260 const infix_op_node = @fieldParentPtr(ast.Node.InfixOp, "base", base);
575 ast.Node.Id.GroupedExpression => {
576 const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base);
577 try stack.append(RenderState { .Text = ")"});
578 try stack.append(RenderState { .Expression = grouped_expr.expr });
579 try stack.append(RenderState { .Text = "("});
580 },
581 ast.Node.Id.FieldInitializer => {
582 const field_init = @fieldParentPtr(ast.Node.FieldInitializer, "base", base);
583 try stream.print(".{} = ", tree.tokenSlice(field_init.name_token));
584 try stack.append(RenderState { .Expression = field_init.expr });
585 },
586 ast.Node.Id.IntegerLiteral => {
587 const integer_literal = @fieldParentPtr(ast.Node.IntegerLiteral, "base", base);
588 try stream.print("{}", tree.tokenSlice(integer_literal.token));
589 },
590 ast.Node.Id.FloatLiteral => {
591 const float_literal = @fieldParentPtr(ast.Node.FloatLiteral, "base", base);
592 try stream.print("{}", tree.tokenSlice(float_literal.token));
593 },
594 ast.Node.Id.StringLiteral => {
595 const string_literal = @fieldParentPtr(ast.Node.StringLiteral, "base", base);
596 try stream.print("{}", tree.tokenSlice(string_literal.token));
597 },
598 ast.Node.Id.CharLiteral => {
599 const char_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
600 try stream.print("{}", tree.tokenSlice(char_literal.token));
601 },
602 ast.Node.Id.BoolLiteral => {
603 const bool_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
604 try stream.print("{}", tree.tokenSlice(bool_literal.token));
605 },
606 ast.Node.Id.NullLiteral => {
607 const null_literal = @fieldParentPtr(ast.Node.NullLiteral, "base", base);
608 try stream.print("{}", tree.tokenSlice(null_literal.token));
609 },
610 ast.Node.Id.ThisLiteral => {
611 const this_literal = @fieldParentPtr(ast.Node.ThisLiteral, "base", base);
612 try stream.print("{}", tree.tokenSlice(this_literal.token));
613 },
614 ast.Node.Id.Unreachable => {
615 const unreachable_node = @fieldParentPtr(ast.Node.Unreachable, "base", base);
616 try stream.print("{}", tree.tokenSlice(unreachable_node.token));
617 },
618 ast.Node.Id.ErrorType => {
619 const error_type = @fieldParentPtr(ast.Node.ErrorType, "base", base);
620 try stream.print("{}", tree.tokenSlice(error_type.token));
621 },
622 ast.Node.Id.VarType => {
623 const var_type = @fieldParentPtr(ast.Node.VarType, "base", base);
624 try stream.print("{}", tree.tokenSlice(var_type.token));
625 },
626 ast.Node.Id.ContainerDecl => {
627 const container_decl = @fieldParentPtr(ast.Node.ContainerDecl, "base", base);
628261
629 switch (container_decl.layout) {262 const op_token = tree.tokens.at(infix_op_node.op_token);
630 ast.Node.ContainerDecl.Layout.Packed => try stream.print("packed "),263 const op_space = switch (infix_op_node.op) {
631 ast.Node.ContainerDecl.Layout.Extern => try stream.print("extern "),264 ast.Node.InfixOp.Op.Period, ast.Node.InfixOp.Op.ErrorUnion, ast.Node.InfixOp.Op.Range => Space.None,
632 ast.Node.ContainerDecl.Layout.Auto => { },265 else => Space.Space,
633 }266 };
267 try renderExpression(allocator, stream, tree, indent, start_col, infix_op_node.lhs, op_space);
634268
635 switch (container_decl.kind) {269 const after_op_space = blk: {
636 ast.Node.ContainerDecl.Kind.Struct => try stream.print("struct"),270 const loc = tree.tokenLocation(tree.tokens.at(infix_op_node.op_token).end, tree.nextToken(infix_op_node.op_token));
637 ast.Node.ContainerDecl.Kind.Enum => try stream.print("enum"),271 break :blk if (loc.line == 0) op_space else Space.Newline;
638 ast.Node.ContainerDecl.Kind.Union => try stream.print("union"),272 };
639 }
640273
641 if (container_decl.fields_and_decls.len == 0) {274 try renderToken(tree, stream, infix_op_node.op_token, indent, start_col, after_op_space);
642 try stack.append(RenderState { .Text = "{}"});275 if (after_op_space == Space.Newline) {
643 } else {276 try stream.writeByteNTimes(' ', indent + indent_delta);
644 try stack.append(RenderState { .Text = "}"});277 start_col.* = indent + indent_delta;
645 try stack.append(RenderState.PrintIndent);278 }
646 try stack.append(RenderState { .Indent = indent });
647 try stack.append(RenderState { .Text = "\n"});
648
649 var i = container_decl.fields_and_decls.len;
650 while (i != 0) {
651 i -= 1;
652 const node = *container_decl.fields_and_decls.at(i);
653 try stack.append(RenderState { .TopLevelDecl = node});
654 try stack.append(RenderState.PrintIndent);
655 try stack.append(RenderState {
656 .Text = blk: {
657 if (i != 0) {
658 const prev_node = *container_decl.fields_and_decls.at(i - 1);
659 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;
660 const loc = tree.tokenLocation(prev_node_last_token_end, node.firstToken());
661 if (loc.line >= 2) {
662 break :blk "\n\n";
663 }
664 }
665 break :blk "\n";
666 },
667 });
668 }
669 try stack.append(RenderState { .Indent = indent + indent_delta});
670 try stack.append(RenderState { .Text = "{"});
671 }
672279
673 switch (container_decl.init_arg_expr) {280 switch (infix_op_node.op) {
674 ast.Node.ContainerDecl.InitArg.None => try stack.append(RenderState { .Text = " "}),281 ast.Node.InfixOp.Op.Catch => |maybe_payload| if (maybe_payload) |payload| {
675 ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {282 try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
676 if (enum_tag_type) |expr| {
677 try stack.append(RenderState { .Text = ")) "});
678 try stack.append(RenderState { .Expression = expr});
679 try stack.append(RenderState { .Text = "(enum("});
680 } else {
681 try stack.append(RenderState { .Text = "(enum) "});
682 }
683 },
684 ast.Node.ContainerDecl.InitArg.Type => |type_expr| {
685 try stack.append(RenderState { .Text = ") "});
686 try stack.append(RenderState { .Expression = type_expr});
687 try stack.append(RenderState { .Text = "("});
688 },
689 }
690 },283 },
691 ast.Node.Id.ErrorSetDecl => {284 else => {},
692 const err_set_decl = @fieldParentPtr(ast.Node.ErrorSetDecl, "base", base);285 }
693286
694 if (err_set_decl.decls.len == 0) {287 return renderExpression(allocator, stream, tree, indent, start_col, infix_op_node.rhs, space);
695 try stream.write("error{}");288 },
696 continue;
697 }
698289
699 if (err_set_decl.decls.len == 1) blk: {290 ast.Node.Id.PrefixOp => {
700 const node = *err_set_decl.decls.at(0);291 const prefix_op_node = @fieldParentPtr(ast.Node.PrefixOp, "base", base);
701292
702 // if there are any doc comments or same line comments293 switch (prefix_op_node.op) {
703 // don't try to put it all on one line294 ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| {
704 if (node.cast(ast.Node.ErrorTag)) |tag| {295 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None); // &
705 if (tag.doc_comments != null) break :blk;296 if (addr_of_info.align_info) |align_info| {
706 } else {297 const lparen_token = tree.prevToken(align_info.node.firstToken());
707 break :blk;298 const align_token = tree.prevToken(lparen_token);
708 }
709299
300 try renderToken(tree, stream, align_token, indent, start_col, Space.None); // align
301 try renderToken(tree, stream, lparen_token, indent, start_col, Space.None); // (
710302
711 try stream.write("error{");303 try renderExpression(allocator, stream, tree, indent, start_col, align_info.node, Space.None);
712 try stack.append(RenderState { .Text = "}" });
713 try stack.append(RenderState { .TopLevelDecl = node });
714 continue;
715 }
716304
717 try stream.write("error{");305 if (align_info.bit_range) |bit_range| {
306 const colon1 = tree.prevToken(bit_range.start.firstToken());
307 const colon2 = tree.prevToken(bit_range.end.firstToken());
718308
719 try stack.append(RenderState { .Text = "}"});309 try renderToken(tree, stream, colon1, indent, start_col, Space.None); // :
720 try stack.append(RenderState.PrintIndent);310 try renderExpression(allocator, stream, tree, indent, start_col, bit_range.start, Space.None);
721 try stack.append(RenderState { .Indent = indent });311 try renderToken(tree, stream, colon2, indent, start_col, Space.None); // :
722 try stack.append(RenderState { .Text = "\n"});312 try renderExpression(allocator, stream, tree, indent, start_col, bit_range.end, Space.None);
723313
724 var i = err_set_decl.decls.len;314 const rparen_token = tree.nextToken(bit_range.end.lastToken());
725 while (i != 0) {315 try renderToken(tree, stream, rparen_token, indent, start_col, Space.Space); // )
726 i -= 1;316 } else {
727 const node = *err_set_decl.decls.at(i);317 const rparen_token = tree.nextToken(align_info.node.lastToken());
728 if (node.id != ast.Node.Id.LineComment) {318 try renderToken(tree, stream, rparen_token, indent, start_col, Space.Space); // )
729 try stack.append(RenderState { .Text = "," });
730 }319 }
731 try stack.append(RenderState { .TopLevelDecl = node });
732 try stack.append(RenderState.PrintIndent);
733 try stack.append(RenderState {
734 .Text = blk: {
735 if (i != 0) {
736 const prev_node = *err_set_decl.decls.at(i - 1);
737 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;
738 const loc = tree.tokenLocation(prev_node_last_token_end, node.firstToken());
739 if (loc.line >= 2) {
740 break :blk "\n\n";
741 }
742 }
743 break :blk "\n";
744 },
745 });
746 }320 }
747 try stack.append(RenderState { .Indent = indent + indent_delta});321 if (addr_of_info.const_token) |const_token| {
748 },322 try renderToken(tree, stream, const_token, indent, start_col, Space.Space); // const
749 ast.Node.Id.MultilineStringLiteral => {
750 const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base);
751 try stream.print("\n");
752
753 var i : usize = 0;
754 while (i < multiline_str_literal.lines.len) : (i += 1) {
755 const t = *multiline_str_literal.lines.at(i);
756 try stream.writeByteNTimes(' ', indent + indent_delta);
757 try stream.print("{}", tree.tokenSlice(t));
758 }323 }
759 try stream.writeByteNTimes(' ', indent);324 if (addr_of_info.volatile_token) |volatile_token| {
760 },325 try renderToken(tree, stream, volatile_token, indent, start_col, Space.Space); // volatile
761 ast.Node.Id.UndefinedLiteral => {
762 const undefined_literal = @fieldParentPtr(ast.Node.UndefinedLiteral, "base", base);
763 try stream.print("{}", tree.tokenSlice(undefined_literal.token));
764 },
765 ast.Node.Id.BuiltinCall => {
766 const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base);
767 try stream.print("{}(", tree.tokenSlice(builtin_call.builtin_token));
768 try stack.append(RenderState { .Text = ")"});
769 var i = builtin_call.params.len;
770 while (i != 0) {
771 i -= 1;
772 const param_node = *builtin_call.params.at(i);
773 try stack.append(RenderState { .Expression = param_node});
774 if (i != 0) {
775 try stack.append(RenderState { .Text = ", " });
776 }
777 }326 }
778 },327 },
779 ast.Node.Id.FnProto => {
780 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", base);
781
782 switch (fn_proto.return_type) {
783 ast.Node.FnProto.ReturnType.Explicit => |node| {
784 try stack.append(RenderState { .Expression = node});
785 },
786 ast.Node.FnProto.ReturnType.InferErrorSet => |node| {
787 try stack.append(RenderState { .Expression = node});
788 try stack.append(RenderState { .Text = "!"});
789 },
790 }
791328
792 if (fn_proto.align_expr) |align_expr| {329 ast.Node.PrefixOp.Op.SliceType => |addr_of_info| {
793 try stack.append(RenderState { .Text = ") " });330 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None); // [
794 try stack.append(RenderState { .Expression = align_expr});331 try renderToken(tree, stream, tree.nextToken(prefix_op_node.op_token), indent, start_col, Space.None); // ]
795 try stack.append(RenderState { .Text = "align(" });
796 }
797332
798 try stack.append(RenderState { .Text = ") " });333 if (addr_of_info.align_info) |align_info| {
799 var i = fn_proto.params.len;334 const lparen_token = tree.prevToken(align_info.node.firstToken());
800 while (i != 0) {335 const align_token = tree.prevToken(lparen_token);
801 i -= 1;
802 const param_decl_node = *fn_proto.params.at(i);
803 try stack.append(RenderState { .ParamDecl = param_decl_node});
804 if (i != 0) {
805 try stack.append(RenderState { .Text = ", " });
806 }
807 }
808336
809 try stack.append(RenderState { .Text = "(" });337 try renderToken(tree, stream, align_token, indent, start_col, Space.None); // align
810 if (fn_proto.name_token) |name_token| {338 try renderToken(tree, stream, lparen_token, indent, start_col, Space.None); // (
811 try stack.append(RenderState { .Text = tree.tokenSlice(name_token) });
812 try stack.append(RenderState { .Text = " " });
813 }
814339
815 try stack.append(RenderState { .Text = "fn" });340 try renderExpression(allocator, stream, tree, indent, start_col, align_info.node, Space.None);
816341
817 if (fn_proto.async_attr) |async_attr| {342 if (align_info.bit_range) |bit_range| {
818 try stack.append(RenderState { .Text = " " });343 const colon1 = tree.prevToken(bit_range.start.firstToken());
819 try stack.append(RenderState { .Expression = &async_attr.base });344 const colon2 = tree.prevToken(bit_range.end.firstToken());
820 }
821345
822 if (fn_proto.cc_token) |cc_token| {346 try renderToken(tree, stream, colon1, indent, start_col, Space.None); // :
823 try stack.append(RenderState { .Text = " " });347 try renderExpression(allocator, stream, tree, indent, start_col, bit_range.start, Space.None);
824 try stack.append(RenderState { .Text = tree.tokenSlice(cc_token) });348 try renderToken(tree, stream, colon2, indent, start_col, Space.None); // :
825 }349 try renderExpression(allocator, stream, tree, indent, start_col, bit_range.end, Space.None);
826350
827 if (fn_proto.lib_name) |lib_name| {351 const rparen_token = tree.nextToken(bit_range.end.lastToken());
828 try stack.append(RenderState { .Text = " " });352 try renderToken(tree, stream, rparen_token, indent, start_col, Space.Space); // )
829 try stack.append(RenderState { .Expression = lib_name });353 } else {
354 const rparen_token = tree.nextToken(align_info.node.lastToken());
355 try renderToken(tree, stream, rparen_token, indent, start_col, Space.Space); // )
356 }
830 }357 }
831 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {358 if (addr_of_info.const_token) |const_token| {
832 try stack.append(RenderState { .Text = " " });359 try renderToken(tree, stream, const_token, indent, start_col, Space.Space);
833 try stack.append(RenderState { .Text = tree.tokenSlice(extern_export_inline_token) });
834 }360 }
835361 if (addr_of_info.volatile_token) |volatile_token| {
836 if (fn_proto.visib_token) |visib_token_index| {362 try renderToken(tree, stream, volatile_token, indent, start_col, Space.Space);
837 const visib_token = tree.tokens.at(visib_token_index);
838 assert(visib_token.id == Token.Id.Keyword_pub or visib_token.id == Token.Id.Keyword_export);
839 try stack.append(RenderState { .Text = " " });
840 try stack.append(RenderState { .Text = tree.tokenSlice(visib_token_index) });
841 }363 }
842 },364 },
843 ast.Node.Id.PromiseType => {365
844 const promise_type = @fieldParentPtr(ast.Node.PromiseType, "base", base);366 ast.Node.PrefixOp.Op.ArrayType => |array_index| {
845 try stream.write(tree.tokenSlice(promise_type.promise_token));367 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None); // [
846 if (promise_type.result) |result| {368 try renderExpression(allocator, stream, tree, indent, start_col, array_index, Space.None);
847 try stream.write(tree.tokenSlice(result.arrow_token));369 try renderToken(tree, stream, tree.nextToken(array_index.lastToken()), indent, start_col, Space.None); // ]
848 try stack.append(RenderState { .Expression = result.return_type});370 },
849 }371 ast.Node.PrefixOp.Op.BitNot,
372 ast.Node.PrefixOp.Op.BoolNot,
373 ast.Node.PrefixOp.Op.Negation,
374 ast.Node.PrefixOp.Op.NegationWrap,
375 ast.Node.PrefixOp.Op.UnwrapMaybe,
376 ast.Node.PrefixOp.Op.MaybeType,
377 ast.Node.PrefixOp.Op.PointerType,
378 => {
379 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None);
850 },380 },
851 ast.Node.Id.LineComment => {381
852 const line_comment_node = @fieldParentPtr(ast.Node.LineComment, "base", base);382 ast.Node.PrefixOp.Op.Try,
853 try stream.write(tree.tokenSlice(line_comment_node.token));383 ast.Node.PrefixOp.Op.Await,
384 ast.Node.PrefixOp.Op.Cancel,
385 ast.Node.PrefixOp.Op.Resume,
386 => {
387 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space);
854 },388 },
855 ast.Node.Id.DocComment => unreachable, // doc comments are attached to nodes389 }
856 ast.Node.Id.Switch => {
857 const switch_node = @fieldParentPtr(ast.Node.Switch, "base", base);
858390
859 try stream.print("{} (", tree.tokenSlice(switch_node.switch_token));391 return renderExpression(allocator, stream, tree, indent, start_col, prefix_op_node.rhs, space);
392 },
860393
861 if (switch_node.cases.len == 0) {394 ast.Node.Id.SuffixOp => {
862 try stack.append(RenderState { .Text = ") {}"});395 const suffix_op = @fieldParentPtr(ast.Node.SuffixOp, "base", base);
863 try stack.append(RenderState { .Expression = switch_node.expr });396
864 continue;397 switch (suffix_op.op) {
398 @TagType(ast.Node.SuffixOp.Op).Call => |*call_info| {
399 if (call_info.async_attr) |async_attr| {
400 try renderExpression(allocator, stream, tree, indent, start_col, &async_attr.base, Space.Space);
865 }401 }
866402
867 try stack.append(RenderState { .Text = "}"});403 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
868 try stack.append(RenderState.PrintIndent);404
869 try stack.append(RenderState { .Indent = indent });405 const lparen = tree.nextToken(suffix_op.lhs.lastToken());
870 try stack.append(RenderState { .Text = "\n"});406
871407 if (call_info.params.len == 0) {
872 var i = switch_node.cases.len;408 try renderToken(tree, stream, lparen, indent, start_col, Space.None);
873 while (i != 0) {409 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
874 i -= 1;
875 const node = *switch_node.cases.at(i);
876 try stack.append(RenderState { .Expression = node});
877 try stack.append(RenderState.PrintIndent);
878 try stack.append(RenderState {
879 .Text = blk: {
880 if (i != 0) {
881 const prev_node = *switch_node.cases.at(i - 1);
882 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;
883 const loc = tree.tokenLocation(prev_node_last_token_end, node.firstToken());
884 if (loc.line >= 2) {
885 break :blk "\n\n";
886 }
887 }
888 break :blk "\n";
889 },
890 });
891 }410 }
892 try stack.append(RenderState { .Indent = indent + indent_delta});411
893 try stack.append(RenderState { .Text = ") {"});412 const src_has_trailing_comma = blk: {
894 try stack.append(RenderState { .Expression = switch_node.expr });413 const maybe_comma = tree.prevToken(suffix_op.rtoken);
895 },414 break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
896 ast.Node.Id.SwitchCase => {415 };
897 const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base);416
898417 if (src_has_trailing_comma) {
899 try stack.append(RenderState { .Token = switch_case.lastToken() + 1 });418 const new_indent = indent + indent_delta;
900 try stack.append(RenderState { .Expression = switch_case.expr });419 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline);
901 if (switch_case.payload) |payload| {420
902 try stack.append(RenderState { .Text = " " });421 var it = call_info.params.iterator(0);
903 try stack.append(RenderState { .Expression = payload });422 while (true) {
423 const param_node = ??it.next();
424
425 const param_node_new_indent = if (param_node.*.id == ast.Node.Id.MultilineStringLiteral) blk: {
426 break :blk indent;
427 } else blk: {
428 try stream.writeByteNTimes(' ', new_indent);
429 break :blk new_indent;
430 };
431
432 if (it.peek()) |next_node| {
433 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node.*, Space.None);
434 const comma = tree.nextToken(param_node.*.lastToken());
435 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,
436 try renderExtraNewline(tree, stream, start_col, next_node.*);
437 } else {
438 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node.*, Space.Comma);
439 try stream.writeByteNTimes(' ', indent);
440 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
441 }
442 }
904 }443 }
905 try stack.append(RenderState { .Text = " => "});
906444
907 var i = switch_case.items.len;445 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
908 while (i != 0) {
909 i -= 1;
910 try stack.append(RenderState { .Expression = *switch_case.items.at(i) });
911446
912 if (i != 0) {447 var it = call_info.params.iterator(0);
913 try stack.append(RenderState.PrintIndent);448 while (it.next()) |param_node| {
914 try stack.append(RenderState { .Text = ",\n" });449 try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.None);
450
451 if (it.peek() != null) {
452 const comma = tree.nextToken(param_node.*.lastToken());
453 try renderToken(tree, stream, comma, indent, start_col, Space.Space);
915 }454 }
916 }455 }
456 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
457 },
458
459 ast.Node.SuffixOp.Op.ArrayAccess => |index_expr| {
460 const lbracket = tree.prevToken(index_expr.firstToken());
461 const rbracket = tree.nextToken(index_expr.lastToken());
462
463 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
464 try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
465 try renderExpression(allocator, stream, tree, indent, start_col, index_expr, Space.None);
466 return renderToken(tree, stream, rbracket, indent, start_col, space); // ]
917 },467 },
918 ast.Node.Id.SwitchElse => {468
919 const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);469 ast.Node.SuffixOp.Op.Deref => {
920 try stream.print("{}", tree.tokenSlice(switch_else.token));470 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
471 try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, start_col, Space.None); // .
472 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // *
921 },473 },
922 ast.Node.Id.Else => {
923 const else_node = @fieldParentPtr(ast.Node.Else, "base", base);
924 try stream.print("{}", tree.tokenSlice(else_node.else_token));
925
926 switch (else_node.body.id) {
927 ast.Node.Id.Block, ast.Node.Id.If,
928 ast.Node.Id.For, ast.Node.Id.While,
929 ast.Node.Id.Switch => {
930 try stream.print(" ");
931 try stack.append(RenderState { .Expression = else_node.body });
932 },
933 else => {
934 try stack.append(RenderState { .Indent = indent });
935 try stack.append(RenderState { .Expression = else_node.body });
936 try stack.append(RenderState.PrintIndent);
937 try stack.append(RenderState { .Indent = indent + indent_delta });
938 try stack.append(RenderState { .Text = "\n" });
939 }
940 }
941474
942 if (else_node.payload) |payload| {475 @TagType(ast.Node.SuffixOp.Op).Slice => |range| {
943 try stack.append(RenderState { .Text = " " });476 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
944 try stack.append(RenderState { .Expression = payload });477
478 const lbracket = tree.prevToken(range.start.firstToken());
479 const dotdot = tree.nextToken(range.start.lastToken());
480
481 try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
482 try renderExpression(allocator, stream, tree, indent, start_col, range.start, Space.None);
483 try renderToken(tree, stream, dotdot, indent, start_col, Space.None); // ..
484 if (range.end) |end| {
485 try renderExpression(allocator, stream, tree, indent, start_col, end, Space.None);
945 }486 }
487 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ]
946 },488 },
947 ast.Node.Id.While => {
948 const while_node = @fieldParentPtr(ast.Node.While, "base", base);
949 if (while_node.label) |label| {
950 try stream.print("{}: ", tree.tokenSlice(label));
951 }
952489
953 if (while_node.inline_token) |inline_token| {490 ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {
954 try stream.print("{} ", tree.tokenSlice(inline_token));491 const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
955 }
956492
957 try stream.print("{} ", tree.tokenSlice(while_node.while_token));493 if (field_inits.len == 0) {
494 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
495 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
496 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
497 }
958498
959 if (while_node.@"else") |@"else"| {499 if (field_inits.len == 1) blk: {
960 try stack.append(RenderState { .Expression = &@"else".base });500 const field_init = ??field_inits.at(0).*.cast(ast.Node.FieldInitializer);
961501
962 if (while_node.body.id == ast.Node.Id.Block) {502 if (field_init.expr.cast(ast.Node.SuffixOp)) |nested_suffix_op| {
963 try stack.append(RenderState { .Text = " " });503 if (nested_suffix_op.op == ast.Node.SuffixOp.Op.StructInitializer) {
964 } else {504 break :blk;
965 try stack.append(RenderState.PrintIndent);505 }
966 try stack.append(RenderState { .Text = "\n" });
967 }506 }
968 }
969507
970 if (while_node.body.id == ast.Node.Id.Block) {508 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
971 try stack.append(RenderState { .Expression = while_node.body });509 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
972 try stack.append(RenderState { .Text = " " });510 try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);
973 } else {511 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
974 try stack.append(RenderState { .Indent = indent });
975 try stack.append(RenderState { .Expression = while_node.body });
976 try stack.append(RenderState.PrintIndent);
977 try stack.append(RenderState { .Indent = indent + indent_delta });
978 try stack.append(RenderState { .Text = "\n" });
979 }512 }
980513
981 if (while_node.continue_expr) |continue_expr| {514 const src_has_trailing_comma = blk: {
982 try stack.append(RenderState { .Text = ")" });515 const maybe_comma = tree.prevToken(suffix_op.rtoken);
983 try stack.append(RenderState { .Expression = continue_expr });516 break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
984 try stack.append(RenderState { .Text = ": (" });517 };
985 try stack.append(RenderState { .Text = " " });
986 }
987518
988 if (while_node.payload) |payload| {519 const src_same_line = blk: {
989 try stack.append(RenderState { .Expression = payload });520 const loc = tree.tokenLocation(tree.tokens.at(lbrace).end, suffix_op.rtoken);
990 try stack.append(RenderState { .Text = " " });521 break :blk loc.line == 0;
991 }522 };
992523
993 try stack.append(RenderState { .Text = ")" });524 if (!src_has_trailing_comma and src_same_line) {
994 try stack.append(RenderState { .Expression = while_node.condition });525 // render all on one line, no trailing comma
995 try stack.append(RenderState { .Text = "(" });526 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
996 },527 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
997 ast.Node.Id.For => {528
998 const for_node = @fieldParentPtr(ast.Node.For, "base", base);529 var it = field_inits.iterator(0);
999 if (for_node.label) |label| {530 while (it.next()) |field_init| {
1000 try stream.print("{}: ", tree.tokenSlice(label));531 if (it.peek() != null) {
1001 }532 try renderExpression(allocator, stream, tree, indent, start_col, field_init.*, Space.None);
533
534 const comma = tree.nextToken(field_init.*.lastToken());
535 try renderToken(tree, stream, comma, indent, start_col, Space.Space);
536 } else {
537 try renderExpression(allocator, stream, tree, indent, start_col, field_init.*, Space.Space);
538 }
539 }
1002540
1003 if (for_node.inline_token) |inline_token| {541 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
1004 try stream.print("{} ", tree.tokenSlice(inline_token));
1005 }542 }
1006543
1007 try stream.print("{} ", tree.tokenSlice(for_node.for_token));544 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
545 try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline);
546
547 const new_indent = indent + indent_delta;
1008548
1009 if (for_node.@"else") |@"else"| {549 var it = field_inits.iterator(0);
1010 try stack.append(RenderState { .Expression = &@"else".base });550 while (it.next()) |field_init| {
551 try stream.writeByteNTimes(' ', new_indent);
1011552
1012 if (for_node.body.id == ast.Node.Id.Block) {553 if (it.peek()) |next_field_init| {
1013 try stack.append(RenderState { .Text = " " });554 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init.*, Space.None);
555
556 const comma = tree.nextToken(field_init.*.lastToken());
557 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline);
558
559 try renderExtraNewline(tree, stream, start_col, next_field_init.*);
1014 } else {560 } else {
1015 try stack.append(RenderState.PrintIndent);561 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init.*, Space.Comma);
1016 try stack.append(RenderState { .Text = "\n" });
1017 }562 }
1018 }563 }
1019564
1020 if (for_node.body.id == ast.Node.Id.Block) {565 try stream.writeByteNTimes(' ', indent);
1021 try stack.append(RenderState { .Expression = for_node.body });566 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
1022 try stack.append(RenderState { .Text = " " });567 },
1023 } else {568
1024 try stack.append(RenderState { .Indent = indent });569 ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {
1025 try stack.append(RenderState { .Expression = for_node.body });570 const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
1026 try stack.append(RenderState.PrintIndent);571
1027 try stack.append(RenderState { .Indent = indent + indent_delta });572 if (exprs.len == 0) {
1028 try stack.append(RenderState { .Text = "\n" });573 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
574 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
575 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
1029 }576 }
577 if (exprs.len == 1) {
578 const expr = exprs.at(0).*;
1030579
1031 if (for_node.payload) |payload| {580 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
1032 try stack.append(RenderState { .Expression = payload });581 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
1033 try stack.append(RenderState { .Text = " " });582 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
583 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
1034 }584 }
1035585
1036 try stack.append(RenderState { .Text = ")" });586 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
1037 try stack.append(RenderState { .Expression = for_node.array_expr });587
1038 try stack.append(RenderState { .Text = "(" });588 // scan to find row size
1039 },589 const maybe_row_size: ?usize = blk: {
1040 ast.Node.Id.If => {590 var count: usize = 1;
1041 const if_node = @fieldParentPtr(ast.Node.If, "base", base);591 var it = exprs.iterator(0);
1042 try stream.print("{} ", tree.tokenSlice(if_node.if_token));592 while (true) {
1043593 const expr = (??it.next()).*;
1044 switch (if_node.body.id) {594 if (it.peek()) |next_expr| {
1045 ast.Node.Id.Block, ast.Node.Id.If,595 const expr_last_token = expr.*.lastToken() + 1;
1046 ast.Node.Id.For, ast.Node.Id.While,596 const loc = tree.tokenLocation(tree.tokens.at(expr_last_token).end, next_expr.*.firstToken());
1047 ast.Node.Id.Switch => {597 if (loc.line != 0) break :blk count;
1048 if (if_node.@"else") |@"else"| {598 count += 1;
1049 try stack.append(RenderState { .Expression = &@"else".base });599 } else {
1050600 const expr_last_token = expr.*.lastToken();
1051 if (if_node.body.id == ast.Node.Id.Block) {601 const loc = tree.tokenLocation(tree.tokens.at(expr_last_token).end, suffix_op.rtoken);
1052 try stack.append(RenderState { .Text = " " });602 if (loc.line == 0) {
1053 } else {603 // all on one line
1054 try stack.append(RenderState.PrintIndent);604 const src_has_trailing_comma = trailblk: {
1055 try stack.append(RenderState { .Text = "\n" });605 const maybe_comma = tree.prevToken(suffix_op.rtoken);
1056 }606 break :trailblk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
1057 }607 };
1058 },608 if (src_has_trailing_comma) {
1059 else => {609 break :blk 1; // force row size 1
1060 if (if_node.@"else") |@"else"| {610 } else {
1061 try stack.append(RenderState { .Expression = @"else".body });611 break :blk null; // no newlines
1062612 }
1063 if (@"else".payload) |payload| {
1064 try stack.append(RenderState { .Text = " " });
1065 try stack.append(RenderState { .Expression = payload });
1066 }613 }
1067614 break :blk count;
1068 try stack.append(RenderState { .Text = " " });
1069 try stack.append(RenderState { .Text = tree.tokenSlice(@"else".else_token) });
1070 try stack.append(RenderState { .Text = " " });
1071 }615 }
1072 }616 }
1073 }617 };
1074618
1075 try stack.append(RenderState { .Expression = if_node.body });619 if (maybe_row_size) |row_size| {
620 const new_indent = indent + indent_delta;
621 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
622 try stream.writeByteNTimes(' ', new_indent);
1076623
1077 if (if_node.payload) |payload| {624 var it = exprs.iterator(0);
1078 try stack.append(RenderState { .Text = " " });625 var i: usize = 1;
1079 try stack.append(RenderState { .Expression = payload });626 while (it.next()) |expr| {
1080 }627 if (it.peek()) |next_expr| {
628 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.None);
1081629
1082 try stack.append(RenderState { .NonBreakToken = if_node.condition.lastToken() + 1 });630 const comma = tree.nextToken(expr.*.lastToken());
1083 try stack.append(RenderState { .Expression = if_node.condition });
1084 try stack.append(RenderState { .Text = "(" });
1085 },
1086 ast.Node.Id.Asm => {
1087 const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base);
1088 try stream.print("{} ", tree.tokenSlice(asm_node.asm_token));
1089631
1090 if (asm_node.volatile_token) |volatile_token| {632 if (i != row_size) {
1091 try stream.print("{} ", tree.tokenSlice(volatile_token));633 try renderToken(tree, stream, comma, new_indent, start_col, Space.Space); // ,
1092 }634 i += 1;
635 continue;
636 }
637 i = 1;
1093638
1094 try stack.append(RenderState { .Indent = indent });639 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,
1095 try stack.append(RenderState { .Text = ")" });
1096 {
1097 var i = asm_node.clobbers.len;
1098 while (i != 0) {
1099 i -= 1;
1100 try stack.append(RenderState { .Expression = *asm_node.clobbers.at(i) });
1101640
1102 if (i != 0) {641 try renderExtraNewline(tree, stream, start_col, next_expr.*);
1103 try stack.append(RenderState { .Text = ", " });642 try stream.writeByteNTimes(' ', new_indent);
643 } else {
644 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // ,
1104 }645 }
1105 }646 }
1106 }647 try stream.writeByteNTimes(' ', indent);
1107 try stack.append(RenderState { .Text = ": " });648 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
1108 try stack.append(RenderState.PrintIndent);649 } else {
1109 try stack.append(RenderState { .Indent = indent + indent_delta });650 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
1110 try stack.append(RenderState { .Text = "\n" });651 var it = exprs.iterator(0);
1111 {652 while (it.next()) |expr| {
1112 var i = asm_node.inputs.len;653 if (it.peek()) |next_expr| {
1113 while (i != 0) {654 try renderExpression(allocator, stream, tree, indent, start_col, expr.*, Space.None);
1114 i -= 1;655 const comma = tree.nextToken(expr.*.lastToken());
1115 const node = *asm_node.inputs.at(i);656 try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,
1116 try stack.append(RenderState { .Expression = &node.base});657 } else {
1117658 try renderExpression(allocator, stream, tree, indent, start_col, expr.*, Space.Space);
1118 if (i != 0) {
1119 try stack.append(RenderState.PrintIndent);
1120 try stack.append(RenderState {
1121 .Text = blk: {
1122 const prev_node = *asm_node.inputs.at(i - 1);
1123 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;
1124 const loc = tree.tokenLocation(prev_node_last_token_end, node.firstToken());
1125 if (loc.line >= 2) {
1126 break :blk "\n\n";
1127 }
1128 break :blk "\n";
1129 },
1130 });
1131 try stack.append(RenderState { .Text = "," });
1132 }659 }
1133 }660 }
661
662 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
1134 }663 }
1135 try stack.append(RenderState { .Indent = indent + indent_delta + 2});664 },
1136 try stack.append(RenderState { .Text = ": "});665 }
1137 try stack.append(RenderState.PrintIndent);666 },
1138 try stack.append(RenderState { .Indent = indent + indent_delta});667
1139 try stack.append(RenderState { .Text = "\n" });668 ast.Node.Id.ControlFlowExpression => {
1140 {669 const flow_expr = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", base);
1141 var i = asm_node.outputs.len;670
1142 while (i != 0) {671 switch (flow_expr.kind) {
1143 i -= 1;672 ast.Node.ControlFlowExpression.Kind.Break => |maybe_label| {
1144 const node = *asm_node.outputs.at(i);673 if (maybe_label == null and flow_expr.rhs == null) {
1145 try stack.append(RenderState { .Expression = &node.base});674 return renderToken(tree, stream, flow_expr.ltoken, indent, start_col, space); // break
1146675 }
1147 if (i != 0) {676
1148 try stack.append(RenderState.PrintIndent);677 try renderToken(tree, stream, flow_expr.ltoken, indent, start_col, Space.Space); // break
1149 try stack.append(RenderState {678 if (maybe_label) |label| {
1150 .Text = blk: {679 const colon = tree.nextToken(flow_expr.ltoken);
1151 const prev_node = *asm_node.outputs.at(i - 1);680 try renderToken(tree, stream, colon, indent, start_col, Space.None); // :
1152 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;681
1153 const loc = tree.tokenLocation(prev_node_last_token_end, node.firstToken());682 if (flow_expr.rhs == null) {
1154 if (loc.line >= 2) {683 return renderExpression(allocator, stream, tree, indent, start_col, label, space); // label
1155 break :blk "\n\n";
1156 }
1157 break :blk "\n";
1158 },
1159 });
1160 try stack.append(RenderState { .Text = "," });
1161 }
1162 }684 }
685 try renderExpression(allocator, stream, tree, indent, start_col, label, Space.Space); // label
1163 }686 }
1164 try stack.append(RenderState { .Indent = indent + indent_delta + 2});
1165 try stack.append(RenderState { .Text = ": "});
1166 try stack.append(RenderState.PrintIndent);
1167 try stack.append(RenderState { .Indent = indent + indent_delta});
1168 try stack.append(RenderState { .Text = "\n" });
1169 try stack.append(RenderState { .Expression = asm_node.template });
1170 try stack.append(RenderState { .Text = "(" });
1171 },687 },
1172 ast.Node.Id.AsmInput => {688 ast.Node.ControlFlowExpression.Kind.Continue => |maybe_label| {
1173 const asm_input = @fieldParentPtr(ast.Node.AsmInput, "base", base);689 assert(flow_expr.rhs == null);
1174690
1175 try stack.append(RenderState { .Text = ")"});691 if (maybe_label == null and flow_expr.rhs == null) {
1176 try stack.append(RenderState { .Expression = asm_input.expr});692 return renderToken(tree, stream, flow_expr.ltoken, indent, start_col, space); // continue
1177 try stack.append(RenderState { .Text = " ("});693 }
1178 try stack.append(RenderState { .Expression = asm_input.constraint });694
1179 try stack.append(RenderState { .Text = "] "});695 try renderToken(tree, stream, flow_expr.ltoken, indent, start_col, Space.Space); // continue
1180 try stack.append(RenderState { .Expression = asm_input.symbolic_name });696 if (maybe_label) |label| {
1181 try stack.append(RenderState { .Text = "["});697 const colon = tree.nextToken(flow_expr.ltoken);
698 try renderToken(tree, stream, colon, indent, start_col, Space.None); // :
699
700 return renderExpression(allocator, stream, tree, indent, start_col, label, space);
701 }
1182 },702 },
1183 ast.Node.Id.AsmOutput => {703 ast.Node.ControlFlowExpression.Kind.Return => {
1184 const asm_output = @fieldParentPtr(ast.Node.AsmOutput, "base", base);704 if (flow_expr.rhs == null) {
1185705 return renderToken(tree, stream, flow_expr.ltoken, indent, start_col, space);
1186 try stack.append(RenderState { .Text = ")"});
1187 switch (asm_output.kind) {
1188 ast.Node.AsmOutput.Kind.Variable => |variable_name| {
1189 try stack.append(RenderState { .Expression = &variable_name.base});
1190 },
1191 ast.Node.AsmOutput.Kind.Return => |return_type| {
1192 try stack.append(RenderState { .Expression = return_type});
1193 try stack.append(RenderState { .Text = "-> "});
1194 },
1195 }706 }
1196 try stack.append(RenderState { .Text = " ("});707 try renderToken(tree, stream, flow_expr.ltoken, indent, start_col, Space.Space);
1197 try stack.append(RenderState { .Expression = asm_output.constraint });
1198 try stack.append(RenderState { .Text = "] "});
1199 try stack.append(RenderState { .Expression = asm_output.symbolic_name });
1200 try stack.append(RenderState { .Text = "["});
1201 },708 },
709 }
1202710
1203 ast.Node.Id.StructField,711 return renderExpression(allocator, stream, tree, indent, start_col, ??flow_expr.rhs, space);
1204 ast.Node.Id.UnionTag,712 },
1205 ast.Node.Id.EnumTag,
1206 ast.Node.Id.ErrorTag,
1207 ast.Node.Id.Root,
1208 ast.Node.Id.VarDecl,
1209 ast.Node.Id.Use,
1210 ast.Node.Id.TestDecl,
1211 ast.Node.Id.ParamDecl => unreachable,
1212 },
1213 RenderState.Statement => |base| {
1214 switch (base.id) {
1215 ast.Node.Id.VarDecl => {
1216 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
1217 try stack.append(RenderState { .VarDecl = var_decl});
1218 },
1219 else => {
1220 try stack.append(RenderState { .MaybeSemiColon = base });
1221 try stack.append(RenderState { .Expression = base });
1222 },
1223 }
1224 },
1225 RenderState.Indent => |new_indent| indent = new_indent,
1226 RenderState.PrintIndent => try stream.writeByteNTimes(' ', indent),
1227 RenderState.Token => |token_index| try renderToken(tree, stream, token_index, indent, true),
1228 RenderState.NonBreakToken => |token_index| try renderToken(tree, stream, token_index, indent, false),
1229 RenderState.MaybeSemiColon => |base| {
1230 if (base.requireSemiColon()) {
1231 const semicolon_index = base.lastToken() + 1;
1232 assert(tree.tokens.at(semicolon_index).id == Token.Id.Semicolon);
1233 try renderToken(tree, stream, semicolon_index, indent, true);
1234 }
1235 },
1236 }
1237 }
1238}
1239713
1240fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, line_break: bool) !void {714 ast.Node.Id.Payload => {
1241 const token = tree.tokens.at(token_index);715 const payload = @fieldParentPtr(ast.Node.Payload, "base", base);
1242 try stream.write(tree.tokenSlicePtr(token));
1243716
1244 const next_token = tree.tokens.at(token_index + 1);717 try renderToken(tree, stream, payload.lpipe, indent, start_col, Space.None);
1245 if (next_token.id == Token.Id.LineComment) {718 try renderExpression(allocator, stream, tree, indent, start_col, payload.error_symbol, Space.None);
1246 const loc = tree.tokenLocationPtr(token.end, next_token);719 return renderToken(tree, stream, payload.rpipe, indent, start_col, space);
1247 if (loc.line == 0) {720 },
1248 try stream.print(" {}", tree.tokenSlicePtr(next_token));721
1249 if (!line_break) {722 ast.Node.Id.PointerPayload => {
1250 try stream.write("\n");723 const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base);
1251 try stream.writeByteNTimes(' ', indent + indent_delta);724
1252 return;725 try renderToken(tree, stream, payload.lpipe, indent, start_col, Space.None);
726 if (payload.ptr_token) |ptr_token| {
727 try renderToken(tree, stream, ptr_token, indent, start_col, Space.None);
1253 }728 }
1254 }729 try renderExpression(allocator, stream, tree, indent, start_col, payload.value_symbol, Space.None);
1255 }730 return renderToken(tree, stream, payload.rpipe, indent, start_col, space);
731 },
1256732
1257 if (!line_break) {733 ast.Node.Id.PointerIndexPayload => {
1258 try stream.writeByte(' ');734 const payload = @fieldParentPtr(ast.Node.PointerIndexPayload, "base", base);
1259 }
1260}
1261735
1262fn renderComments(tree: &ast.Tree, stream: var, node: var, indent: usize) !void {736 try renderToken(tree, stream, payload.lpipe, indent, start_col, Space.None);
737 if (payload.ptr_token) |ptr_token| {
738 try renderToken(tree, stream, ptr_token, indent, start_col, Space.None);
739 }
740 try renderExpression(allocator, stream, tree, indent, start_col, payload.value_symbol, Space.None);
741
742 if (payload.index_symbol) |index_symbol| {
743 const comma = tree.nextToken(payload.value_symbol.lastToken());
744
745 try renderToken(tree, stream, comma, indent, start_col, Space.Space);
746 try renderExpression(allocator, stream, tree, indent, start_col, index_symbol, Space.None);
747 }
748
749 return renderToken(tree, stream, payload.rpipe, indent, start_col, space);
750 },
751
752 ast.Node.Id.GroupedExpression => {
753 const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base);
754
755 try renderToken(tree, stream, grouped_expr.lparen, indent, start_col, Space.None);
756 try renderExpression(allocator, stream, tree, indent, start_col, grouped_expr.expr, Space.None);
757 return renderToken(tree, stream, grouped_expr.rparen, indent, start_col, space);
758 },
759
760 ast.Node.Id.FieldInitializer => {
761 const field_init = @fieldParentPtr(ast.Node.FieldInitializer, "base", base);
762
763 try renderToken(tree, stream, field_init.period_token, indent, start_col, Space.None); // .
764 try renderToken(tree, stream, field_init.name_token, indent, start_col, Space.Space); // name
765 try renderToken(tree, stream, tree.nextToken(field_init.name_token), indent, start_col, Space.Space); // =
766 return renderExpression(allocator, stream, tree, indent, start_col, field_init.expr, space);
767 },
768
769 ast.Node.Id.IntegerLiteral => {
770 const integer_literal = @fieldParentPtr(ast.Node.IntegerLiteral, "base", base);
771 return renderToken(tree, stream, integer_literal.token, indent, start_col, space);
772 },
773 ast.Node.Id.FloatLiteral => {
774 const float_literal = @fieldParentPtr(ast.Node.FloatLiteral, "base", base);
775 return renderToken(tree, stream, float_literal.token, indent, start_col, space);
776 },
777 ast.Node.Id.StringLiteral => {
778 const string_literal = @fieldParentPtr(ast.Node.StringLiteral, "base", base);
779 return renderToken(tree, stream, string_literal.token, indent, start_col, space);
780 },
781 ast.Node.Id.CharLiteral => {
782 const char_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
783 return renderToken(tree, stream, char_literal.token, indent, start_col, space);
784 },
785 ast.Node.Id.BoolLiteral => {
786 const bool_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
787 return renderToken(tree, stream, bool_literal.token, indent, start_col, space);
788 },
789 ast.Node.Id.NullLiteral => {
790 const null_literal = @fieldParentPtr(ast.Node.NullLiteral, "base", base);
791 return renderToken(tree, stream, null_literal.token, indent, start_col, space);
792 },
793 ast.Node.Id.ThisLiteral => {
794 const this_literal = @fieldParentPtr(ast.Node.ThisLiteral, "base", base);
795 return renderToken(tree, stream, this_literal.token, indent, start_col, space);
796 },
797 ast.Node.Id.Unreachable => {
798 const unreachable_node = @fieldParentPtr(ast.Node.Unreachable, "base", base);
799 return renderToken(tree, stream, unreachable_node.token, indent, start_col, space);
800 },
801 ast.Node.Id.ErrorType => {
802 const error_type = @fieldParentPtr(ast.Node.ErrorType, "base", base);
803 return renderToken(tree, stream, error_type.token, indent, start_col, space);
804 },
805 ast.Node.Id.VarType => {
806 const var_type = @fieldParentPtr(ast.Node.VarType, "base", base);
807 return renderToken(tree, stream, var_type.token, indent, start_col, space);
808 },
809 ast.Node.Id.ContainerDecl => {
810 const container_decl = @fieldParentPtr(ast.Node.ContainerDecl, "base", base);
811
812 if (container_decl.layout_token) |layout_token| {
813 try renderToken(tree, stream, layout_token, indent, start_col, Space.Space);
814 }
815
816 switch (container_decl.init_arg_expr) {
817 ast.Node.ContainerDecl.InitArg.None => {
818 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.Space); // union
819 },
820 ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {
821 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
822
823 const lparen = tree.nextToken(container_decl.kind_token);
824 const enum_token = tree.nextToken(lparen);
825
826 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
827 try renderToken(tree, stream, enum_token, indent, start_col, Space.None); // enum
828
829 if (enum_tag_type) |expr| {
830 try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.None); // (
831 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
832
833 const rparen = tree.nextToken(expr.lastToken());
834 try renderToken(tree, stream, rparen, indent, start_col, Space.None); // )
835 try renderToken(tree, stream, tree.nextToken(rparen), indent, start_col, Space.Space); // )
836 } else {
837 try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.Space); // )
838 }
839 },
840 ast.Node.ContainerDecl.InitArg.Type => |type_expr| {
841 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
842
843 const lparen = tree.nextToken(container_decl.kind_token);
844 const rparen = tree.nextToken(type_expr.lastToken());
845
846 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
847 try renderExpression(allocator, stream, tree, indent, start_col, type_expr, Space.None);
848 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
849 },
850 }
851
852 if (container_decl.fields_and_decls.len == 0) {
853 try renderToken(tree, stream, container_decl.lbrace_token, indent + indent_delta, start_col, Space.None); // {
854 return renderToken(tree, stream, container_decl.rbrace_token, indent, start_col, space); // }
855 } else {
856 const new_indent = indent + indent_delta;
857 try renderToken(tree, stream, container_decl.lbrace_token, new_indent, start_col, Space.Newline); // {
858
859 var it = container_decl.fields_and_decls.iterator(0);
860 while (it.next()) |decl| {
861 try stream.writeByteNTimes(' ', new_indent);
862 try renderTopLevelDecl(allocator, stream, tree, new_indent, start_col, decl.*);
863
864 if (it.peek()) |next_decl| {
865 try renderExtraNewline(tree, stream, start_col, next_decl.*);
866 }
867 }
868
869 try stream.writeByteNTimes(' ', indent);
870 return renderToken(tree, stream, container_decl.rbrace_token, indent, start_col, space); // }
871 }
872 },
873
874 ast.Node.Id.ErrorSetDecl => {
875 const err_set_decl = @fieldParentPtr(ast.Node.ErrorSetDecl, "base", base);
876
877 const lbrace = tree.nextToken(err_set_decl.error_token);
878
879 if (err_set_decl.decls.len == 0) {
880 try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None);
881 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
882 return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space);
883 }
884
885 if (err_set_decl.decls.len == 1) blk: {
886 const node = err_set_decl.decls.at(0).*;
887
888 // if there are any doc comments or same line comments
889 // don't try to put it all on one line
890 if (node.cast(ast.Node.ErrorTag)) |tag| {
891 if (tag.doc_comments != null) break :blk;
892 } else {
893 break :blk;
894 }
895
896 try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None); // error
897 try renderToken(tree, stream, lbrace, indent, start_col, Space.None); // {
898 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None);
899 return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // }
900 }
901
902 try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None); // error
903 try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // {
904 const new_indent = indent + indent_delta;
905
906 var it = err_set_decl.decls.iterator(0);
907 while (it.next()) |node| {
908 try stream.writeByteNTimes(' ', new_indent);
909
910 if (it.peek()) |next_node| {
911 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.None);
912 try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, start_col, Space.Newline); // ,
913
914 try renderExtraNewline(tree, stream, start_col, next_node.*);
915 } else {
916 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);
917 }
918 }
919
920 try stream.writeByteNTimes(' ', indent);
921 return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // }
922 },
923
924 ast.Node.Id.ErrorTag => {
925 const tag = @fieldParentPtr(ast.Node.ErrorTag, "base", base);
926
927 try renderDocComments(tree, stream, tag, indent, start_col);
928 return renderToken(tree, stream, tag.name_token, indent, start_col, space); // name
929 },
930
931 ast.Node.Id.MultilineStringLiteral => {
932 const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base);
933
934 var skip_first_indent = true;
935 if (tree.tokens.at(multiline_str_literal.firstToken() - 1).id != Token.Id.LineComment) {
936 try stream.print("\n");
937 skip_first_indent = false;
938 }
939
940 var i: usize = 0;
941 while (i < multiline_str_literal.lines.len) : (i += 1) {
942 const t = multiline_str_literal.lines.at(i).*;
943 if (!skip_first_indent) {
944 try stream.writeByteNTimes(' ', indent + indent_delta);
945 }
946 try renderToken(tree, stream, t, indent, start_col, Space.None);
947 skip_first_indent = false;
948 }
949 try stream.writeByteNTimes(' ', indent);
950 },
951 ast.Node.Id.UndefinedLiteral => {
952 const undefined_literal = @fieldParentPtr(ast.Node.UndefinedLiteral, "base", base);
953 return renderToken(tree, stream, undefined_literal.token, indent, start_col, space);
954 },
955
956 ast.Node.Id.BuiltinCall => {
957 const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base);
958
959 try renderToken(tree, stream, builtin_call.builtin_token, indent, start_col, Space.None); // @name
960 try renderToken(tree, stream, tree.nextToken(builtin_call.builtin_token), indent, start_col, Space.None); // (
961
962 var it = builtin_call.params.iterator(0);
963 while (it.next()) |param_node| {
964 try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.None);
965
966 if (it.peek() != null) {
967 const comma_token = tree.nextToken(param_node.*.lastToken());
968 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
969 }
970 }
971 return renderToken(tree, stream, builtin_call.rparen_token, indent, start_col, space); // )
972 },
973
974 ast.Node.Id.FnProto => {
975 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", base);
976
977 if (fn_proto.visib_token) |visib_token_index| {
978 const visib_token = tree.tokens.at(visib_token_index);
979 assert(visib_token.id == Token.Id.Keyword_pub or visib_token.id == Token.Id.Keyword_export);
980
981 try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub
982 }
983
984 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
985 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
986 }
987
988 if (fn_proto.lib_name) |lib_name| {
989 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);
990 }
991
992 if (fn_proto.cc_token) |cc_token| {
993 try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
994 }
995
996 if (fn_proto.async_attr) |async_attr| {
997 try renderExpression(allocator, stream, tree, indent, start_col, &async_attr.base, Space.Space);
998 }
999
1000 const lparen = if (fn_proto.name_token) |name_token| blk: {
1001 try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn
1002 try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name
1003 break :blk tree.nextToken(name_token);
1004 } else blk: {
1005 try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.None); // fn
1006 break :blk tree.nextToken(fn_proto.fn_token);
1007 };
1008
1009 const rparen = tree.prevToken(switch (fn_proto.return_type) {
1010 ast.Node.FnProto.ReturnType.Explicit => |node| node.firstToken(),
1011 ast.Node.FnProto.ReturnType.InferErrorSet => |node| tree.prevToken(node.firstToken()),
1012 });
1013
1014 const src_params_trailing_comma = blk: {
1015 const maybe_comma = tree.prevToken(rparen);
1016 break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
1017 };
1018 const src_params_same_line = blk: {
1019 const loc = tree.tokenLocation(tree.tokens.at(lparen).end, rparen);
1020 break :blk loc.line == 0;
1021 };
1022
1023 if (!src_params_trailing_comma and src_params_same_line) {
1024 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
1025
1026 // render all on one line, no trailing comma
1027 var it = fn_proto.params.iterator(0);
1028 while (it.next()) |param_decl_node| {
1029 try renderParamDecl(allocator, stream, tree, indent, start_col, param_decl_node.*, Space.None);
1030
1031 if (it.peek() != null) {
1032 const comma = tree.nextToken(param_decl_node.*.lastToken());
1033 try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,
1034 }
1035 }
1036 } else {
1037 // one param per line
1038 const new_indent = indent + indent_delta;
1039 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline); // (
1040
1041 var it = fn_proto.params.iterator(0);
1042 while (it.next()) |param_decl_node| {
1043 try stream.writeByteNTimes(' ', new_indent);
1044 try renderParamDecl(allocator, stream, tree, indent, start_col, param_decl_node.*, Space.Comma);
1045 }
1046 try stream.writeByteNTimes(' ', indent);
1047 }
1048
1049 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
1050
1051 if (fn_proto.align_expr) |align_expr| {
1052 const align_rparen = tree.nextToken(align_expr.lastToken());
1053 const align_lparen = tree.prevToken(align_expr.firstToken());
1054 const align_kw = tree.prevToken(align_lparen);
1055
1056 try renderToken(tree, stream, align_kw, indent, start_col, Space.None); // align
1057 try renderToken(tree, stream, align_lparen, indent, start_col, Space.None); // (
1058 try renderExpression(allocator, stream, tree, indent, start_col, align_expr, Space.None);
1059 try renderToken(tree, stream, align_rparen, indent, start_col, Space.Space); // )
1060 }
1061
1062 switch (fn_proto.return_type) {
1063 ast.Node.FnProto.ReturnType.Explicit => |node| {
1064 return renderExpression(allocator, stream, tree, indent, start_col, node, space);
1065 },
1066 ast.Node.FnProto.ReturnType.InferErrorSet => |node| {
1067 try renderToken(tree, stream, tree.prevToken(node.firstToken()), indent, start_col, Space.None); // !
1068 return renderExpression(allocator, stream, tree, indent, start_col, node, space);
1069 },
1070 }
1071 },
1072
1073 ast.Node.Id.PromiseType => {
1074 const promise_type = @fieldParentPtr(ast.Node.PromiseType, "base", base);
1075
1076 if (promise_type.result) |result| {
1077 try renderToken(tree, stream, promise_type.promise_token, indent, start_col, Space.None); // promise
1078 try renderToken(tree, stream, result.arrow_token, indent, start_col, Space.None); // ->
1079 return renderExpression(allocator, stream, tree, indent, start_col, result.return_type, space);
1080 } else {
1081 return renderToken(tree, stream, promise_type.promise_token, indent, start_col, space); // promise
1082 }
1083 },
1084
1085 ast.Node.Id.DocComment => unreachable, // doc comments are attached to nodes
1086
1087 ast.Node.Id.Switch => {
1088 const switch_node = @fieldParentPtr(ast.Node.Switch, "base", base);
1089
1090 try renderToken(tree, stream, switch_node.switch_token, indent, start_col, Space.Space); // switch
1091 try renderToken(tree, stream, tree.nextToken(switch_node.switch_token), indent, start_col, Space.None); // (
1092
1093 const rparen = tree.nextToken(switch_node.expr.lastToken());
1094 const lbrace = tree.nextToken(rparen);
1095
1096 if (switch_node.cases.len == 0) {
1097 try renderExpression(allocator, stream, tree, indent, start_col, switch_node.expr, Space.None);
1098 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
1099 try renderToken(tree, stream, lbrace, indent, start_col, Space.None); // {
1100 return renderToken(tree, stream, switch_node.rbrace, indent, start_col, space); // }
1101 }
1102
1103 try renderExpression(allocator, stream, tree, indent, start_col, switch_node.expr, Space.None);
1104
1105 const new_indent = indent + indent_delta;
1106
1107 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
1108 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); // {
1109
1110 var it = switch_node.cases.iterator(0);
1111 while (it.next()) |node| {
1112 try stream.writeByteNTimes(' ', new_indent);
1113 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);
1114
1115 if (it.peek()) |next_node| {
1116 try renderExtraNewline(tree, stream, start_col, next_node.*);
1117 }
1118 }
1119
1120 try stream.writeByteNTimes(' ', indent);
1121 return renderToken(tree, stream, switch_node.rbrace, indent, start_col, space); // }
1122 },
1123
1124 ast.Node.Id.SwitchCase => {
1125 const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base);
1126
1127 assert(switch_case.items.len != 0);
1128 const src_has_trailing_comma = blk: {
1129 const last_node = switch_case.items.at(switch_case.items.len - 1).*;
1130 const maybe_comma = tree.nextToken(last_node.lastToken());
1131 break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
1132 };
1133
1134 if (switch_case.items.len == 1 or !src_has_trailing_comma) {
1135 var it = switch_case.items.iterator(0);
1136 while (it.next()) |node| {
1137 if (it.peek()) |next_node| {
1138 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
1139
1140 const comma_token = tree.nextToken(node.*.lastToken());
1141 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
1142 try renderExtraNewline(tree, stream, start_col, next_node.*);
1143 } else {
1144 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Space);
1145 }
1146 }
1147 } else {
1148 var it = switch_case.items.iterator(0);
1149 while (true) {
1150 const node = ??it.next();
1151 if (it.peek()) |next_node| {
1152 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
1153
1154 const comma_token = tree.nextToken(node.*.lastToken());
1155 try renderToken(tree, stream, comma_token, indent, start_col, Space.Newline); // ,
1156 try renderExtraNewline(tree, stream, start_col, next_node.*);
1157 try stream.writeByteNTimes(' ', indent);
1158 } else {
1159 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Comma);
1160 try stream.writeByteNTimes(' ', indent);
1161 break;
1162 }
1163 }
1164 }
1165
1166 try renderToken(tree, stream, switch_case.arrow_token, indent, start_col, Space.Space); // =>
1167
1168 if (switch_case.payload) |payload| {
1169 try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
1170 }
1171
1172 return renderExpression(allocator, stream, tree, indent, start_col, switch_case.expr, space);
1173 },
1174 ast.Node.Id.SwitchElse => {
1175 const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);
1176 return renderToken(tree, stream, switch_else.token, indent, start_col, space);
1177 },
1178 ast.Node.Id.Else => {
1179 const else_node = @fieldParentPtr(ast.Node.Else, "base", base);
1180
1181 const body_is_block = nodeIsBlock(else_node.body);
1182 const same_line = body_is_block or tree.tokensOnSameLine(else_node.else_token, else_node.body.lastToken());
1183
1184 const after_else_space = if (same_line or else_node.payload != null) Space.Space else Space.Newline;
1185 try renderToken(tree, stream, else_node.else_token, indent, start_col, after_else_space);
1186
1187 if (else_node.payload) |payload| {
1188 const payload_space = if (same_line) Space.Space else Space.Newline;
1189 try renderExpression(allocator, stream, tree, indent, start_col, payload, payload_space);
1190 }
1191
1192 if (same_line) {
1193 return renderExpression(allocator, stream, tree, indent, start_col, else_node.body, space);
1194 }
1195
1196 try stream.writeByteNTimes(' ', indent + indent_delta);
1197 start_col.* = indent + indent_delta;
1198 return renderExpression(allocator, stream, tree, indent, start_col, else_node.body, space);
1199 },
1200
1201 ast.Node.Id.While => {
1202 const while_node = @fieldParentPtr(ast.Node.While, "base", base);
1203
1204 if (while_node.label) |label| {
1205 try renderToken(tree, stream, label, indent, start_col, Space.None); // label
1206 try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space); // :
1207 }
1208
1209 if (while_node.inline_token) |inline_token| {
1210 try renderToken(tree, stream, inline_token, indent, start_col, Space.Space); // inline
1211 }
1212
1213 try renderToken(tree, stream, while_node.while_token, indent, start_col, Space.Space); // while
1214 try renderToken(tree, stream, tree.nextToken(while_node.while_token), indent, start_col, Space.None); // (
1215 try renderExpression(allocator, stream, tree, indent, start_col, while_node.condition, Space.None);
1216
1217 const cond_rparen = tree.nextToken(while_node.condition.lastToken());
1218
1219 const body_is_block = nodeIsBlock(while_node.body);
1220
1221 var block_start_space: Space = undefined;
1222 var after_body_space: Space = undefined;
1223
1224 if (body_is_block) {
1225 block_start_space = Space.BlockStart;
1226 after_body_space = if (while_node.@"else" == null) space else Space.SpaceOrOutdent;
1227 } else if (tree.tokensOnSameLine(cond_rparen, while_node.body.lastToken())) {
1228 block_start_space = Space.Space;
1229 after_body_space = if (while_node.@"else" == null) space else Space.Space;
1230 } else {
1231 block_start_space = Space.Newline;
1232 after_body_space = if (while_node.@"else" == null) space else Space.Newline;
1233 }
1234
1235 {
1236 const rparen_space = if (while_node.payload != null or while_node.continue_expr != null) Space.Space else block_start_space;
1237 try renderToken(tree, stream, cond_rparen, indent, start_col, rparen_space); // )
1238 }
1239
1240 if (while_node.payload) |payload| {
1241 const payload_space = if (while_node.continue_expr != null) Space.Space else block_start_space;
1242 try renderExpression(allocator, stream, tree, indent, start_col, payload, payload_space);
1243 }
1244
1245 if (while_node.continue_expr) |continue_expr| {
1246 const rparen = tree.nextToken(continue_expr.lastToken());
1247 const lparen = tree.prevToken(continue_expr.firstToken());
1248 const colon = tree.prevToken(lparen);
1249
1250 try renderToken(tree, stream, colon, indent, start_col, Space.Space); // :
1251 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
1252
1253 try renderExpression(allocator, stream, tree, indent, start_col, continue_expr, Space.None);
1254
1255 try renderToken(tree, stream, rparen, indent, start_col, block_start_space); // )
1256 }
1257
1258 var new_indent = indent;
1259 if (block_start_space == Space.Newline) {
1260 new_indent += indent_delta;
1261 try stream.writeByteNTimes(' ', new_indent);
1262 start_col.* = new_indent;
1263 }
1264
1265 try renderExpression(allocator, stream, tree, indent, start_col, while_node.body, after_body_space);
1266
1267 if (while_node.@"else") |@"else"| {
1268 if (after_body_space == Space.Newline) {
1269 try stream.writeByteNTimes(' ', indent);
1270 start_col.* = indent;
1271 }
1272 return renderExpression(allocator, stream, tree, indent, start_col, &@"else".base, space);
1273 }
1274 },
1275
1276 ast.Node.Id.For => {
1277 const for_node = @fieldParentPtr(ast.Node.For, "base", base);
1278
1279 if (for_node.label) |label| {
1280 try renderToken(tree, stream, label, indent, start_col, Space.None); // label
1281 try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space); // :
1282 }
1283
1284 if (for_node.inline_token) |inline_token| {
1285 try renderToken(tree, stream, inline_token, indent, start_col, Space.Space); // inline
1286 }
1287
1288 try renderToken(tree, stream, for_node.for_token, indent, start_col, Space.Space); // for
1289 try renderToken(tree, stream, tree.nextToken(for_node.for_token), indent, start_col, Space.None); // (
1290 try renderExpression(allocator, stream, tree, indent, start_col, for_node.array_expr, Space.None);
1291
1292 const rparen = tree.nextToken(for_node.array_expr.lastToken());
1293 const rparen_space = if (for_node.payload != null or
1294 for_node.body.id == ast.Node.Id.Block) Space.Space else Space.Newline;
1295 try renderToken(tree, stream, rparen, indent, start_col, rparen_space); // )
1296
1297 if (for_node.payload) |payload| {
1298 const payload_space = if (for_node.body.id == ast.Node.Id.Block) Space.Space else Space.Newline;
1299 try renderExpression(allocator, stream, tree, indent, start_col, payload, payload_space);
1300 }
1301
1302 const body_space = blk: {
1303 if (for_node.@"else" != null) {
1304 if (for_node.body.id == ast.Node.Id.Block) {
1305 break :blk Space.Space;
1306 } else {
1307 break :blk Space.Newline;
1308 }
1309 } else {
1310 break :blk space;
1311 }
1312 };
1313 if (for_node.body.id == ast.Node.Id.Block) {
1314 try renderExpression(allocator, stream, tree, indent, start_col, for_node.body, body_space);
1315 } else {
1316 try stream.writeByteNTimes(' ', indent + indent_delta);
1317 try renderExpression(allocator, stream, tree, indent, start_col, for_node.body, body_space);
1318 }
1319
1320 if (for_node.@"else") |@"else"| {
1321 if (for_node.body.id != ast.Node.Id.Block) {
1322 try stream.writeByteNTimes(' ', indent);
1323 }
1324
1325 return renderExpression(allocator, stream, tree, indent, start_col, &@"else".base, space);
1326 }
1327 },
1328
1329 ast.Node.Id.If => {
1330 const if_node = @fieldParentPtr(ast.Node.If, "base", base);
1331
1332 const lparen = tree.prevToken(if_node.condition.firstToken());
1333 const rparen = tree.nextToken(if_node.condition.lastToken());
1334
1335 try renderToken(tree, stream, if_node.if_token, indent, start_col, Space.Space); // if
1336 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
1337
1338 try renderExpression(allocator, stream, tree, indent, start_col, if_node.condition, Space.None); // condition
1339
1340 const body_is_block = nodeIsBlock(if_node.body);
1341
1342 if (body_is_block) {
1343 const after_rparen_space = if (if_node.payload == null) Space.BlockStart else Space.Space;
1344 try renderToken(tree, stream, rparen, indent, start_col, after_rparen_space); // )
1345
1346 if (if_node.payload) |payload| {
1347 try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.BlockStart); // |x|
1348 }
1349
1350 if (if_node.@"else") |@"else"| {
1351 try renderExpression(allocator, stream, tree, indent, start_col, if_node.body, Space.SpaceOrOutdent);
1352 return renderExpression(allocator, stream, tree, indent, start_col, &@"else".base, space);
1353 } else {
1354 return renderExpression(allocator, stream, tree, indent, start_col, if_node.body, space);
1355 }
1356 }
1357
1358 const src_has_newline = !tree.tokensOnSameLine(rparen, if_node.body.lastToken());
1359
1360 if (src_has_newline) {
1361 const after_rparen_space = if (if_node.payload == null) Space.Newline else Space.Space;
1362 try renderToken(tree, stream, rparen, indent, start_col, after_rparen_space); // )
1363
1364 if (if_node.payload) |payload| {
1365 try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Newline);
1366 }
1367
1368 const new_indent = indent + indent_delta;
1369 try stream.writeByteNTimes(' ', new_indent);
1370
1371 if (if_node.@"else") |@"else"| {
1372 const else_is_block = nodeIsBlock(@"else".body);
1373 try renderExpression(allocator, stream, tree, new_indent, start_col, if_node.body, Space.Newline);
1374 try stream.writeByteNTimes(' ', indent);
1375
1376 if (else_is_block) {
1377 try renderToken(tree, stream, @"else".else_token, indent, start_col, Space.Space); // else
1378
1379 if (@"else".payload) |payload| {
1380 try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
1381 }
1382
1383 return renderExpression(allocator, stream, tree, indent, start_col, @"else".body, space);
1384 } else {
1385 const after_else_space = if (@"else".payload == null) Space.Newline else Space.Space;
1386 try renderToken(tree, stream, @"else".else_token, indent, start_col, after_else_space); // else
1387
1388 if (@"else".payload) |payload| {
1389 try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Newline);
1390 }
1391 try stream.writeByteNTimes(' ', new_indent);
1392
1393 return renderExpression(allocator, stream, tree, new_indent, start_col, @"else".body, space);
1394 }
1395 } else {
1396 return renderExpression(allocator, stream, tree, new_indent, start_col, if_node.body, space);
1397 }
1398 }
1399
1400 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
1401
1402 if (if_node.payload) |payload| {
1403 try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
1404 }
1405
1406 if (if_node.@"else") |@"else"| {
1407 try renderExpression(allocator, stream, tree, indent, start_col, if_node.body, Space.Space);
1408 try renderToken(tree, stream, @"else".else_token, indent, start_col, Space.Space);
1409
1410 if (@"else".payload) |payload| {
1411 try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
1412 }
1413
1414 return renderExpression(allocator, stream, tree, indent, start_col, @"else".body, space);
1415 } else {
1416 return renderExpression(allocator, stream, tree, indent, start_col, if_node.body, space);
1417 }
1418 },
1419
1420 ast.Node.Id.Asm => {
1421 const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base);
1422
1423 try renderToken(tree, stream, asm_node.asm_token, indent, start_col, Space.Space); // asm
1424
1425 if (asm_node.volatile_token) |volatile_token| {
1426 try renderToken(tree, stream, volatile_token, indent, start_col, Space.Space); // volatile
1427 try renderToken(tree, stream, tree.nextToken(volatile_token), indent, start_col, Space.None); // (
1428 } else {
1429 try renderToken(tree, stream, tree.nextToken(asm_node.asm_token), indent, start_col, Space.None); // (
1430 }
1431
1432 if (asm_node.outputs.len == 0 and asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
1433 try renderExpression(allocator, stream, tree, indent, start_col, asm_node.template, Space.None);
1434 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
1435 }
1436
1437 try renderExpression(allocator, stream, tree, indent, start_col, asm_node.template, Space.Newline);
1438
1439 const indent_once = indent + indent_delta;
1440 try stream.writeByteNTimes(' ', indent_once);
1441
1442 const colon1 = tree.nextToken(asm_node.template.lastToken());
1443 const indent_extra = indent_once + 2;
1444
1445 const colon2 = if (asm_node.outputs.len == 0) blk: {
1446 try renderToken(tree, stream, colon1, indent, start_col, Space.Newline); // :
1447 try stream.writeByteNTimes(' ', indent_once);
1448
1449 break :blk tree.nextToken(colon1);
1450 } else blk: {
1451 try renderToken(tree, stream, colon1, indent, start_col, Space.Space); // :
1452
1453 var it = asm_node.outputs.iterator(0);
1454 while (true) {
1455 const asm_output = ??it.next();
1456 const node = &(asm_output.*).base;
1457
1458 if (it.peek()) |next_asm_output| {
1459 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);
1460 const next_node = &(next_asm_output.*).base;
1461
1462 const comma = tree.prevToken(next_asm_output.*.firstToken());
1463 try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,
1464 try renderExtraNewline(tree, stream, start_col, next_node);
1465
1466 try stream.writeByteNTimes(' ', indent_extra);
1467 } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
1468 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
1469 try stream.writeByteNTimes(' ', indent);
1470 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
1471 } else {
1472 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
1473 try stream.writeByteNTimes(' ', indent_once);
1474 const comma_or_colon = tree.nextToken(node.lastToken());
1475 break :blk switch (tree.tokens.at(comma_or_colon).id) {
1476 Token.Id.Comma => tree.nextToken(comma_or_colon),
1477 else => comma_or_colon,
1478 };
1479 }
1480 }
1481 };
1482
1483 const colon3 = if (asm_node.inputs.len == 0) blk: {
1484 try renderToken(tree, stream, colon2, indent, start_col, Space.Newline); // :
1485 try stream.writeByteNTimes(' ', indent_once);
1486
1487 break :blk tree.nextToken(colon2);
1488 } else blk: {
1489 try renderToken(tree, stream, colon2, indent, start_col, Space.Space); // :
1490
1491 var it = asm_node.inputs.iterator(0);
1492 while (true) {
1493 const asm_input = ??it.next();
1494 const node = &(asm_input.*).base;
1495
1496 if (it.peek()) |next_asm_input| {
1497 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);
1498 const next_node = &(next_asm_input.*).base;
1499
1500 const comma = tree.prevToken(next_asm_input.*.firstToken());
1501 try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,
1502 try renderExtraNewline(tree, stream, start_col, next_node);
1503
1504 try stream.writeByteNTimes(' ', indent_extra);
1505 } else if (asm_node.clobbers.len == 0) {
1506 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
1507 try stream.writeByteNTimes(' ', indent);
1508 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space); // )
1509 } else {
1510 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
1511 try stream.writeByteNTimes(' ', indent_once);
1512 const comma_or_colon = tree.nextToken(node.lastToken());
1513 break :blk switch (tree.tokens.at(comma_or_colon).id) {
1514 Token.Id.Comma => tree.nextToken(comma_or_colon),
1515 else => comma_or_colon,
1516 };
1517 }
1518 }
1519 };
1520
1521 try renderToken(tree, stream, colon3, indent, start_col, Space.Space); // :
1522
1523 var it = asm_node.clobbers.iterator(0);
1524 while (true) {
1525 const clobber_token = ??it.next();
1526
1527 if (it.peek() == null) {
1528 try renderToken(tree, stream, clobber_token.*, indent_once, start_col, Space.Newline);
1529 try stream.writeByteNTimes(' ', indent);
1530 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
1531 } else {
1532 try renderToken(tree, stream, clobber_token.*, indent_once, start_col, Space.None);
1533 const comma = tree.nextToken(clobber_token.*);
1534 try renderToken(tree, stream, comma, indent_once, start_col, Space.Space); // ,
1535 }
1536 }
1537 },
1538
1539 ast.Node.Id.AsmInput => {
1540 const asm_input = @fieldParentPtr(ast.Node.AsmInput, "base", base);
1541
1542 try stream.write("[");
1543 try renderExpression(allocator, stream, tree, indent, start_col, asm_input.symbolic_name, Space.None);
1544 try stream.write("] ");
1545 try renderExpression(allocator, stream, tree, indent, start_col, asm_input.constraint, Space.None);
1546 try stream.write(" (");
1547 try renderExpression(allocator, stream, tree, indent, start_col, asm_input.expr, Space.None);
1548 return renderToken(tree, stream, asm_input.lastToken(), indent, start_col, space); // )
1549 },
1550
1551 ast.Node.Id.AsmOutput => {
1552 const asm_output = @fieldParentPtr(ast.Node.AsmOutput, "base", base);
1553
1554 try stream.write("[");
1555 try renderExpression(allocator, stream, tree, indent, start_col, asm_output.symbolic_name, Space.None);
1556 try stream.write("] ");
1557 try renderExpression(allocator, stream, tree, indent, start_col, asm_output.constraint, Space.None);
1558 try stream.write(" (");
1559
1560 switch (asm_output.kind) {
1561 ast.Node.AsmOutput.Kind.Variable => |variable_name| {
1562 try renderExpression(allocator, stream, tree, indent, start_col, &variable_name.base, Space.None);
1563 },
1564 ast.Node.AsmOutput.Kind.Return => |return_type| {
1565 try stream.write("-> ");
1566 try renderExpression(allocator, stream, tree, indent, start_col, return_type, Space.None);
1567 },
1568 }
1569
1570 return renderToken(tree, stream, asm_output.lastToken(), indent, start_col, space); // )
1571 },
1572
1573 ast.Node.Id.StructField,
1574 ast.Node.Id.UnionTag,
1575 ast.Node.Id.EnumTag,
1576 ast.Node.Id.Root,
1577 ast.Node.Id.VarDecl,
1578 ast.Node.Id.Use,
1579 ast.Node.Id.TestDecl,
1580 ast.Node.Id.ParamDecl,
1581 => unreachable,
1582 }
1583}
1584
1585fn renderVarDecl(
1586 allocator: &mem.Allocator,
1587 stream: var,
1588 tree: &ast.Tree,
1589 indent: usize,
1590 start_col: &usize,
1591 var_decl: &ast.Node.VarDecl,
1592) (@typeOf(stream).Child.Error || Error)!void {
1593 if (var_decl.visib_token) |visib_token| {
1594 try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
1595 }
1596
1597 if (var_decl.extern_export_token) |extern_export_token| {
1598 try renderToken(tree, stream, extern_export_token, indent, start_col, Space.Space); // extern
1599
1600 if (var_decl.lib_name) |lib_name| {
1601 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space); // "lib"
1602 }
1603 }
1604
1605 if (var_decl.comptime_token) |comptime_token| {
1606 try renderToken(tree, stream, comptime_token, indent, start_col, Space.Space); // comptime
1607 }
1608
1609 try renderToken(tree, stream, var_decl.mut_token, indent, start_col, Space.Space); // var
1610
1611 const name_space = if (var_decl.type_node == null and (var_decl.align_node != null or
1612 var_decl.init_node != null)) Space.Space else Space.None;
1613 try renderToken(tree, stream, var_decl.name_token, indent, start_col, name_space);
1614
1615 if (var_decl.type_node) |type_node| {
1616 try renderToken(tree, stream, tree.nextToken(var_decl.name_token), indent, start_col, Space.Space);
1617 const s = if (var_decl.align_node != null or var_decl.init_node != null) Space.Space else Space.None;
1618 try renderExpression(allocator, stream, tree, indent, start_col, type_node, s);
1619 }
1620
1621 if (var_decl.align_node) |align_node| {
1622 const lparen = tree.prevToken(align_node.firstToken());
1623 const align_kw = tree.prevToken(lparen);
1624 const rparen = tree.nextToken(align_node.lastToken());
1625 try renderToken(tree, stream, align_kw, indent, start_col, Space.None); // align
1626 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
1627 try renderExpression(allocator, stream, tree, indent, start_col, align_node, Space.None);
1628 const s = if (var_decl.init_node != null) Space.Space else Space.None;
1629 try renderToken(tree, stream, rparen, indent, start_col, s); // )
1630 }
1631
1632 if (var_decl.init_node) |init_node| {
1633 const s = if (init_node.id == ast.Node.Id.MultilineStringLiteral) Space.None else Space.Space;
1634 try renderToken(tree, stream, var_decl.eq_token, indent, start_col, s); // =
1635 try renderExpression(allocator, stream, tree, indent, start_col, init_node, Space.None);
1636 }
1637
1638 try renderToken(tree, stream, var_decl.semicolon_token, indent, start_col, Space.Newline);
1639}
1640
1641fn renderParamDecl(
1642 allocator: &mem.Allocator,
1643 stream: var,
1644 tree: &ast.Tree,
1645 indent: usize,
1646 start_col: &usize,
1647 base: &ast.Node,
1648 space: Space,
1649) (@typeOf(stream).Child.Error || Error)!void {
1650 const param_decl = @fieldParentPtr(ast.Node.ParamDecl, "base", base);
1651
1652 if (param_decl.comptime_token) |comptime_token| {
1653 try renderToken(tree, stream, comptime_token, indent, start_col, Space.Space);
1654 }
1655 if (param_decl.noalias_token) |noalias_token| {
1656 try renderToken(tree, stream, noalias_token, indent, start_col, Space.Space);
1657 }
1658 if (param_decl.name_token) |name_token| {
1659 try renderToken(tree, stream, name_token, indent, start_col, Space.None);
1660 try renderToken(tree, stream, tree.nextToken(name_token), indent, start_col, Space.Space); // :
1661 }
1662 if (param_decl.var_args_token) |var_args_token| {
1663 try renderToken(tree, stream, var_args_token, indent, start_col, space);
1664 } else {
1665 try renderExpression(allocator, stream, tree, indent, start_col, param_decl.type_node, space);
1666 }
1667}
1668
1669fn renderStatement(
1670 allocator: &mem.Allocator,
1671 stream: var,
1672 tree: &ast.Tree,
1673 indent: usize,
1674 start_col: &usize,
1675 base: &ast.Node,
1676) (@typeOf(stream).Child.Error || Error)!void {
1677 switch (base.id) {
1678 ast.Node.Id.VarDecl => {
1679 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
1680 try renderVarDecl(allocator, stream, tree, indent, start_col, var_decl);
1681 },
1682 else => {
1683 if (base.requireSemiColon()) {
1684 try renderExpression(allocator, stream, tree, indent, start_col, base, Space.None);
1685
1686 const semicolon_index = tree.nextToken(base.lastToken());
1687 assert(tree.tokens.at(semicolon_index).id == Token.Id.Semicolon);
1688 try renderToken(tree, stream, semicolon_index, indent, start_col, Space.Newline);
1689 } else {
1690 try renderExpression(allocator, stream, tree, indent, start_col, base, Space.Newline);
1691 }
1692 },
1693 }
1694}
1695
1696const Space = enum {
1697 None,
1698 Newline,
1699 Comma,
1700 Space,
1701 SpaceOrOutdent,
1702 NoNewline,
1703 NoComment,
1704 BlockStart,
1705};
1706
1707fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, start_col: &usize, space: Space) (@typeOf(stream).Child.Error || Error)!void {
1708 if (space == Space.BlockStart) {
1709 if (start_col.* < indent + indent_delta)
1710 return renderToken(tree, stream, token_index, indent, start_col, Space.Space);
1711 try renderToken(tree, stream, token_index, indent, start_col, Space.Newline);
1712 try stream.writeByteNTimes(' ', indent);
1713 start_col.* = indent;
1714 return;
1715 }
1716
1717 var token = tree.tokens.at(token_index);
1718 try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(token), " "));
1719
1720 if (space == Space.NoComment)
1721 return;
1722
1723 var next_token = tree.tokens.at(token_index + 1);
1724
1725 if (space == Space.Comma) switch (next_token.id) {
1726 Token.Id.Comma => return renderToken(tree, stream, token_index + 1, indent, start_col, Space.Newline),
1727 Token.Id.LineComment => {
1728 try stream.write(", ");
1729 return renderToken(tree, stream, token_index + 1, indent, start_col, Space.Newline);
1730 },
1731 else => {
1732 if (tree.tokens.at(token_index + 2).id == Token.Id.MultilineStringLiteralLine) {
1733 try stream.write(",");
1734 return;
1735 } else {
1736 try stream.write(",\n");
1737 start_col.* = 0;
1738 return;
1739 }
1740 },
1741 };
1742
1743 // Skip over same line doc comments
1744 var offset: usize = 1;
1745 if (next_token.id == Token.Id.DocComment) {
1746 const loc = tree.tokenLocationPtr(token.end, next_token);
1747 if (loc.line == 0) {
1748 offset += 1;
1749 next_token = tree.tokens.at(token_index + offset);
1750 }
1751 }
1752
1753 if (next_token.id != Token.Id.LineComment) blk: {
1754 switch (space) {
1755 Space.None, Space.NoNewline => return,
1756 Space.Newline => {
1757 if (next_token.id == Token.Id.MultilineStringLiteralLine) {
1758 return;
1759 } else {
1760 try stream.write("\n");
1761 start_col.* = 0;
1762 return;
1763 }
1764 },
1765 Space.Space, Space.SpaceOrOutdent => {
1766 if (next_token.id == Token.Id.MultilineStringLiteralLine)
1767 return;
1768 try stream.writeByte(' ');
1769 return;
1770 },
1771 Space.NoComment, Space.Comma, Space.BlockStart => unreachable,
1772 }
1773 }
1774
1775 const comment_is_empty = mem.trimRight(u8, tree.tokenSlicePtr(next_token), " ").len == 2;
1776 if (comment_is_empty) {
1777 switch (space) {
1778 Space.Newline => {
1779 try stream.writeByte('\n');
1780 start_col.* = 0;
1781 return;
1782 },
1783 else => {},
1784 }
1785 }
1786
1787 var loc = tree.tokenLocationPtr(token.end, next_token);
1788 if (loc.line == 0) {
1789 try stream.print(" {}", mem.trimRight(u8, tree.tokenSlicePtr(next_token), " "));
1790 offset = 2;
1791 token = next_token;
1792 next_token = tree.tokens.at(token_index + offset);
1793 if (next_token.id != Token.Id.LineComment) {
1794 switch (space) {
1795 Space.None, Space.Space => {
1796 try stream.writeByte('\n');
1797 const after_comment_token = tree.tokens.at(token_index + offset);
1798 const next_line_indent = switch (after_comment_token.id) {
1799 Token.Id.RParen, Token.Id.RBrace, Token.Id.RBracket => indent,
1800 else => indent + indent_delta,
1801 };
1802 try stream.writeByteNTimes(' ', next_line_indent);
1803 start_col.* = next_line_indent;
1804 },
1805 Space.SpaceOrOutdent => {
1806 try stream.writeByte('\n');
1807 try stream.writeByteNTimes(' ', indent);
1808 start_col.* = indent;
1809 },
1810 Space.Newline => {
1811 if (next_token.id == Token.Id.MultilineStringLiteralLine) {
1812 return;
1813 } else {
1814 try stream.write("\n");
1815 start_col.* = 0;
1816 return;
1817 }
1818 },
1819 Space.NoNewline => {},
1820 Space.NoComment, Space.Comma, Space.BlockStart => unreachable,
1821 }
1822 return;
1823 }
1824 loc = tree.tokenLocationPtr(token.end, next_token);
1825 }
1826
1827 while (true) {
1828 assert(loc.line != 0);
1829 const newline_count = if (loc.line == 1) u8(1) else u8(2);
1830 try stream.writeByteNTimes('\n', newline_count);
1831 try stream.writeByteNTimes(' ', indent);
1832 try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(next_token), " "));
1833
1834 offset += 1;
1835 token = next_token;
1836 next_token = tree.tokens.at(token_index + offset);
1837 if (next_token.id != Token.Id.LineComment) {
1838 switch (space) {
1839 Space.Newline => {
1840 if (next_token.id == Token.Id.MultilineStringLiteralLine) {
1841 return;
1842 } else {
1843 try stream.write("\n");
1844 start_col.* = 0;
1845 return;
1846 }
1847 },
1848 Space.None, Space.Space => {
1849 try stream.writeByte('\n');
1850
1851 const after_comment_token = tree.tokens.at(token_index + offset);
1852 const next_line_indent = switch (after_comment_token.id) {
1853 Token.Id.RParen, Token.Id.RBrace, Token.Id.RBracket => indent - indent_delta,
1854 else => indent,
1855 };
1856 try stream.writeByteNTimes(' ', next_line_indent);
1857 start_col.* = next_line_indent;
1858 },
1859 Space.SpaceOrOutdent => {
1860 try stream.writeByte('\n');
1861 try stream.writeByteNTimes(' ', indent);
1862 start_col.* = indent;
1863 },
1864 Space.NoNewline => {},
1865 Space.NoComment, Space.Comma, Space.BlockStart => unreachable,
1866 }
1867 return;
1868 }
1869 loc = tree.tokenLocationPtr(token.end, next_token);
1870 }
1871}
1872
1873fn renderDocComments(
1874 tree: &ast.Tree,
1875 stream: var,
1876 node: var,
1877 indent: usize,
1878 start_col: &usize,
1879) (@typeOf(stream).Child.Error || Error)!void {
1263 const comment = node.doc_comments ?? return;1880 const comment = node.doc_comments ?? return;
1264 var it = comment.lines.iterator(0);1881 var it = comment.lines.iterator(0);
1882 const first_token = node.firstToken();
1265 while (it.next()) |line_token_index| {1883 while (it.next()) |line_token_index| {
1266 try stream.print("{}\n", tree.tokenSlice(*line_token_index));1884 if (line_token_index.* < first_token) {
1267 try stream.writeByteNTimes(' ', indent);1885 try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.Newline);
1886 try stream.writeByteNTimes(' ', indent);
1887 } else {
1888 try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.NoComment);
1889 try stream.write("\n");
1890 try stream.writeByteNTimes(' ', indent);
1891 }
1268 }1892 }
1269}1893}
12701894
1895fn nodeIsBlock(base: &const ast.Node) bool {
1896 return switch (base.id) {
1897 ast.Node.Id.Block,
1898 ast.Node.Id.If,
1899 ast.Node.Id.For,
1900 ast.Node.Id.While,
1901 ast.Node.Id.Switch,
1902 => true,
1903 else => false,
1904 };
1905}
std/zig/tokenizer.zig+195-110
...@@ -6,62 +6,63 @@ pub const Token = struct {...@@ -6,62 +6,63 @@ pub const Token = struct {
6 start: usize,6 start: usize,
7 end: usize,7 end: usize,
88
9 const Keyword = struct {9 pub const Keyword = struct {
10 bytes: []const u8,10 bytes: []const u8,
11 id: Id,11 id: Id,
12 };12 };
1313
14 const keywords = []Keyword {14 pub const keywords = []Keyword{
15 Keyword{.bytes="align", .id = Id.Keyword_align},15 Keyword{ .bytes = "align", .id = Id.Keyword_align },
16 Keyword{.bytes="and", .id = Id.Keyword_and},16 Keyword{ .bytes = "and", .id = Id.Keyword_and },
17 Keyword{.bytes="asm", .id = Id.Keyword_asm},17 Keyword{ .bytes = "asm", .id = Id.Keyword_asm },
18 Keyword{.bytes="async", .id = Id.Keyword_async},18 Keyword{ .bytes = "async", .id = Id.Keyword_async },
19 Keyword{.bytes="await", .id = Id.Keyword_await},19 Keyword{ .bytes = "await", .id = Id.Keyword_await },
20 Keyword{.bytes="break", .id = Id.Keyword_break},20 Keyword{ .bytes = "break", .id = Id.Keyword_break },
21 Keyword{.bytes="catch", .id = Id.Keyword_catch},21 Keyword{ .bytes = "catch", .id = Id.Keyword_catch },
22 Keyword{.bytes="cancel", .id = Id.Keyword_cancel},22 Keyword{ .bytes = "cancel", .id = Id.Keyword_cancel },
23 Keyword{.bytes="comptime", .id = Id.Keyword_comptime},23 Keyword{ .bytes = "comptime", .id = Id.Keyword_comptime },
24 Keyword{.bytes="const", .id = Id.Keyword_const},24 Keyword{ .bytes = "const", .id = Id.Keyword_const },
25 Keyword{.bytes="continue", .id = Id.Keyword_continue},25 Keyword{ .bytes = "continue", .id = Id.Keyword_continue },
26 Keyword{.bytes="defer", .id = Id.Keyword_defer},26 Keyword{ .bytes = "defer", .id = Id.Keyword_defer },
27 Keyword{.bytes="else", .id = Id.Keyword_else},27 Keyword{ .bytes = "else", .id = Id.Keyword_else },
28 Keyword{.bytes="enum", .id = Id.Keyword_enum},28 Keyword{ .bytes = "enum", .id = Id.Keyword_enum },
29 Keyword{.bytes="errdefer", .id = Id.Keyword_errdefer},29 Keyword{ .bytes = "errdefer", .id = Id.Keyword_errdefer },
30 Keyword{.bytes="error", .id = Id.Keyword_error},30 Keyword{ .bytes = "error", .id = Id.Keyword_error },
31 Keyword{.bytes="export", .id = Id.Keyword_export},31 Keyword{ .bytes = "export", .id = Id.Keyword_export },
32 Keyword{.bytes="extern", .id = Id.Keyword_extern},32 Keyword{ .bytes = "extern", .id = Id.Keyword_extern },
33 Keyword{.bytes="false", .id = Id.Keyword_false},33 Keyword{ .bytes = "false", .id = Id.Keyword_false },
34 Keyword{.bytes="fn", .id = Id.Keyword_fn},34 Keyword{ .bytes = "fn", .id = Id.Keyword_fn },
35 Keyword{.bytes="for", .id = Id.Keyword_for},35 Keyword{ .bytes = "for", .id = Id.Keyword_for },
36 Keyword{.bytes="if", .id = Id.Keyword_if},36 Keyword{ .bytes = "if", .id = Id.Keyword_if },
37 Keyword{.bytes="inline", .id = Id.Keyword_inline},37 Keyword{ .bytes = "inline", .id = Id.Keyword_inline },
38 Keyword{.bytes="nakedcc", .id = Id.Keyword_nakedcc},38 Keyword{ .bytes = "nakedcc", .id = Id.Keyword_nakedcc },
39 Keyword{.bytes="noalias", .id = Id.Keyword_noalias},39 Keyword{ .bytes = "noalias", .id = Id.Keyword_noalias },
40 Keyword{.bytes="null", .id = Id.Keyword_null},40 Keyword{ .bytes = "null", .id = Id.Keyword_null },
41 Keyword{.bytes="or", .id = Id.Keyword_or},41 Keyword{ .bytes = "or", .id = Id.Keyword_or },
42 Keyword{.bytes="packed", .id = Id.Keyword_packed},42 Keyword{ .bytes = "packed", .id = Id.Keyword_packed },
43 Keyword{.bytes="promise", .id = Id.Keyword_promise},43 Keyword{ .bytes = "promise", .id = Id.Keyword_promise },
44 Keyword{.bytes="pub", .id = Id.Keyword_pub},44 Keyword{ .bytes = "pub", .id = Id.Keyword_pub },
45 Keyword{.bytes="resume", .id = Id.Keyword_resume},45 Keyword{ .bytes = "resume", .id = Id.Keyword_resume },
46 Keyword{.bytes="return", .id = Id.Keyword_return},46 Keyword{ .bytes = "return", .id = Id.Keyword_return },
47 Keyword{.bytes="section", .id = Id.Keyword_section},47 Keyword{ .bytes = "section", .id = Id.Keyword_section },
48 Keyword{.bytes="stdcallcc", .id = Id.Keyword_stdcallcc},48 Keyword{ .bytes = "stdcallcc", .id = Id.Keyword_stdcallcc },
49 Keyword{.bytes="struct", .id = Id.Keyword_struct},49 Keyword{ .bytes = "struct", .id = Id.Keyword_struct },
50 Keyword{.bytes="suspend", .id = Id.Keyword_suspend},50 Keyword{ .bytes = "suspend", .id = Id.Keyword_suspend },
51 Keyword{.bytes="switch", .id = Id.Keyword_switch},51 Keyword{ .bytes = "switch", .id = Id.Keyword_switch },
52 Keyword{.bytes="test", .id = Id.Keyword_test},52 Keyword{ .bytes = "test", .id = Id.Keyword_test },
53 Keyword{.bytes="this", .id = Id.Keyword_this},53 Keyword{ .bytes = "this", .id = Id.Keyword_this },
54 Keyword{.bytes="true", .id = Id.Keyword_true},54 Keyword{ .bytes = "true", .id = Id.Keyword_true },
55 Keyword{.bytes="try", .id = Id.Keyword_try},55 Keyword{ .bytes = "try", .id = Id.Keyword_try },
56 Keyword{.bytes="undefined", .id = Id.Keyword_undefined},56 Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },
57 Keyword{.bytes="union", .id = Id.Keyword_union},57 Keyword{ .bytes = "union", .id = Id.Keyword_union },
58 Keyword{.bytes="unreachable", .id = Id.Keyword_unreachable},58 Keyword{ .bytes = "unreachable", .id = Id.Keyword_unreachable },
59 Keyword{.bytes="use", .id = Id.Keyword_use},59 Keyword{ .bytes = "use", .id = Id.Keyword_use },
60 Keyword{.bytes="var", .id = Id.Keyword_var},60 Keyword{ .bytes = "var", .id = Id.Keyword_var },
61 Keyword{.bytes="volatile", .id = Id.Keyword_volatile},61 Keyword{ .bytes = "volatile", .id = Id.Keyword_volatile },
62 Keyword{.bytes="while", .id = Id.Keyword_while},62 Keyword{ .bytes = "while", .id = Id.Keyword_while },
63 };63 };
6464
65 // TODO perfect hash at comptime
65 fn getKeyword(bytes: []const u8) ?Id {66 fn getKeyword(bytes: []const u8) ?Id {
66 for (keywords) |kw| {67 for (keywords) |kw| {
67 if (mem.eql(u8, kw.bytes, bytes)) {68 if (mem.eql(u8, kw.bytes, bytes)) {
...@@ -71,7 +72,10 @@ pub const Token = struct {...@@ -71,7 +72,10 @@ pub const Token = struct {
71 return null;72 return null;
72 }73 }
7374
74 const StrLitKind = enum {Normal, C};75 const StrLitKind = enum {
76 Normal,
77 C,
78 };
7579
76 pub const Id = union(enum) {80 pub const Id = union(enum) {
77 Invalid,81 Invalid,
...@@ -201,7 +205,7 @@ pub const Tokenizer = struct {...@@ -201,7 +205,7 @@ pub const Tokenizer = struct {
201 }205 }
202206
203 pub fn init(buffer: []const u8) Tokenizer {207 pub fn init(buffer: []const u8) Tokenizer {
204 return Tokenizer {208 return Tokenizer{
205 .buffer = buffer,209 .buffer = buffer,
206 .index = 0,210 .index = 0,
207 .pending_invalid_token = null,211 .pending_invalid_token = null,
...@@ -216,9 +220,10 @@ pub const Tokenizer = struct {...@@ -216,9 +220,10 @@ pub const Tokenizer = struct {
216 StringLiteral,220 StringLiteral,
217 StringLiteralBackslash,221 StringLiteralBackslash,
218 MultilineStringLiteralLine,222 MultilineStringLiteralLine,
219 MultilineStringLiteralLineBackslash,
220 CharLiteral,223 CharLiteral,
221 CharLiteralBackslash,224 CharLiteralBackslash,
225 CharLiteralEscape1,
226 CharLiteralEscape2,
222 CharLiteralEnd,227 CharLiteralEnd,
223 Backslash,228 Backslash,
224 Equal,229 Equal,
...@@ -236,10 +241,15 @@ pub const Tokenizer = struct {...@@ -236,10 +241,15 @@ pub const Tokenizer = struct {
236 Zero,241 Zero,
237 IntegerLiteral,242 IntegerLiteral,
238 IntegerLiteralWithRadix,243 IntegerLiteralWithRadix,
244 IntegerLiteralWithRadixHex,
239 NumberDot,245 NumberDot,
246 NumberDotHex,
240 FloatFraction,247 FloatFraction,
248 FloatFractionHex,
241 FloatExponentUnsigned,249 FloatExponentUnsigned,
250 FloatExponentUnsignedHex,
242 FloatExponentNumber,251 FloatExponentNumber,
252 FloatExponentNumberHex,
243 Ampersand,253 Ampersand,
244 Caret,254 Caret,
245 Percent,255 Percent,
...@@ -262,7 +272,7 @@ pub const Tokenizer = struct {...@@ -262,7 +272,7 @@ pub const Tokenizer = struct {
262 }272 }
263 const start_index = self.index;273 const start_index = self.index;
264 var state = State.Start;274 var state = State.Start;
265 var result = Token {275 var result = Token{
266 .id = Token.Id.Eof,276 .id = Token.Id.Eof,
267 .start = self.index,277 .start = self.index,
268 .end = undefined,278 .end = undefined,
...@@ -283,7 +293,7 @@ pub const Tokenizer = struct {...@@ -283,7 +293,7 @@ pub const Tokenizer = struct {
283 },293 },
284 '"' => {294 '"' => {
285 state = State.StringLiteral;295 state = State.StringLiteral;
286 result.id = Token.Id { .StringLiteral = Token.StrLitKind.Normal };296 result.id = Token.Id{ .StringLiteral = Token.StrLitKind.Normal };
287 },297 },
288 '\'' => {298 '\'' => {
289 state = State.CharLiteral;299 state = State.CharLiteral;
...@@ -362,7 +372,7 @@ pub const Tokenizer = struct {...@@ -362,7 +372,7 @@ pub const Tokenizer = struct {
362 },372 },
363 '\\' => {373 '\\' => {
364 state = State.Backslash;374 state = State.Backslash;
365 result.id = Token.Id { .MultilineStringLiteralLine = Token.StrLitKind.Normal };375 result.id = Token.Id{ .MultilineStringLiteralLine = Token.StrLitKind.Normal };
366 },376 },
367 '{' => {377 '{' => {
368 result.id = Token.Id.LBrace;378 result.id = Token.Id.LBrace;
...@@ -448,7 +458,7 @@ pub const Tokenizer = struct {...@@ -448,7 +458,7 @@ pub const Tokenizer = struct {
448 else => {458 else => {
449 result.id = Token.Id.Asterisk;459 result.id = Token.Id.Asterisk;
450 break;460 break;
451 }461 },
452 },462 },
453463
454 State.AsteriskPercent => switch (c) {464 State.AsteriskPercent => switch (c) {
...@@ -460,7 +470,7 @@ pub const Tokenizer = struct {...@@ -460,7 +470,7 @@ pub const Tokenizer = struct {
460 else => {470 else => {
461 result.id = Token.Id.AsteriskPercent;471 result.id = Token.Id.AsteriskPercent;
462 break;472 break;
463 }473 },
464 },474 },
465475
466 State.QuestionMark => switch (c) {476 State.QuestionMark => switch (c) {
...@@ -528,7 +538,7 @@ pub const Tokenizer = struct {...@@ -528,7 +538,7 @@ pub const Tokenizer = struct {
528 else => {538 else => {
529 result.id = Token.Id.Caret;539 result.id = Token.Id.Caret;
530 break;540 break;
531 }541 },
532 },542 },
533543
534 State.Identifier => switch (c) {544 State.Identifier => switch (c) {
...@@ -553,11 +563,11 @@ pub const Tokenizer = struct {...@@ -553,11 +563,11 @@ pub const Tokenizer = struct {
553 State.C => switch (c) {563 State.C => switch (c) {
554 '\\' => {564 '\\' => {
555 state = State.Backslash;565 state = State.Backslash;
556 result.id = Token.Id { .MultilineStringLiteralLine = Token.StrLitKind.C };566 result.id = Token.Id{ .MultilineStringLiteralLine = Token.StrLitKind.C };
557 },567 },
558 '"' => {568 '"' => {
559 state = State.StringLiteral;569 state = State.StringLiteral;
560 result.id = Token.Id { .StringLiteral = Token.StrLitKind.C };570 result.id = Token.Id{ .StringLiteral = Token.StrLitKind.C };
561 },571 },
562 'a'...'z', 'A'...'Z', '_', '0'...'9' => {572 'a'...'z', 'A'...'Z', '_', '0'...'9' => {
563 state = State.Identifier;573 state = State.Identifier;
...@@ -598,7 +608,7 @@ pub const Tokenizer = struct {...@@ -598,7 +608,7 @@ pub const Tokenizer = struct {
598 }608 }
599609
600 state = State.CharLiteralEnd;610 state = State.CharLiteralEnd;
601 }611 },
602 },612 },
603613
604 State.CharLiteralBackslash => switch (c) {614 State.CharLiteralBackslash => switch (c) {
...@@ -606,11 +616,34 @@ pub const Tokenizer = struct {...@@ -606,11 +616,34 @@ pub const Tokenizer = struct {
606 result.id = Token.Id.Invalid;616 result.id = Token.Id.Invalid;
607 break;617 break;
608 },618 },
619 'x' => {
620 state = State.CharLiteralEscape1;
621 },
609 else => {622 else => {
610 state = State.CharLiteralEnd;623 state = State.CharLiteralEnd;
611 },624 },
612 },625 },
613626
627 State.CharLiteralEscape1 => switch (c) {
628 '0'...'9', 'a'...'z', 'A'...'F' => {
629 state = State.CharLiteralEscape2;
630 },
631 else => {
632 result.id = Token.Id.Invalid;
633 break;
634 },
635 },
636
637 State.CharLiteralEscape2 => switch (c) {
638 '0'...'9', 'a'...'z', 'A'...'F' => {
639 state = State.CharLiteralEnd;
640 },
641 else => {
642 result.id = Token.Id.Invalid;
643 break;
644 },
645 },
646
614 State.CharLiteralEnd => switch (c) {647 State.CharLiteralEnd => switch (c) {
615 '\'' => {648 '\'' => {
616 result.id = Token.Id.CharLiteral;649 result.id = Token.Id.CharLiteral;
...@@ -624,9 +657,6 @@ pub const Tokenizer = struct {...@@ -624,9 +657,6 @@ pub const Tokenizer = struct {
624 },657 },
625658
626 State.MultilineStringLiteralLine => switch (c) {659 State.MultilineStringLiteralLine => switch (c) {
627 '\\' => {
628 state = State.MultilineStringLiteralLineBackslash;
629 },
630 '\n' => {660 '\n' => {
631 self.index += 1;661 self.index += 1;
632 break;662 break;
...@@ -634,13 +664,6 @@ pub const Tokenizer = struct {...@@ -634,13 +664,6 @@ pub const Tokenizer = struct {
634 else => self.checkLiteralCharacter(),664 else => self.checkLiteralCharacter(),
635 },665 },
636666
637 State.MultilineStringLiteralLineBackslash => switch (c) {
638 '\n' => break, // Look for this error later.
639 else => {
640 state = State.MultilineStringLiteralLine;
641 },
642 },
643
644 State.Bang => switch (c) {667 State.Bang => switch (c) {
645 '=' => {668 '=' => {
646 result.id = Token.Id.BangEqual;669 result.id = Token.Id.BangEqual;
...@@ -716,7 +739,7 @@ pub const Tokenizer = struct {...@@ -716,7 +739,7 @@ pub const Tokenizer = struct {
716 else => {739 else => {
717 result.id = Token.Id.MinusPercent;740 result.id = Token.Id.MinusPercent;
718 break;741 break;
719 }742 },
720 },743 },
721744
722 State.AngleBracketLeft => switch (c) {745 State.AngleBracketLeft => switch (c) {
...@@ -839,9 +862,12 @@ pub const Tokenizer = struct {...@@ -839,9 +862,12 @@ pub const Tokenizer = struct {
839 else => self.checkLiteralCharacter(),862 else => self.checkLiteralCharacter(),
840 },863 },
841 State.Zero => switch (c) {864 State.Zero => switch (c) {
842 'b', 'o', 'x' => {865 'b', 'o' => {
843 state = State.IntegerLiteralWithRadix;866 state = State.IntegerLiteralWithRadix;
844 },867 },
868 'x' => {
869 state = State.IntegerLiteralWithRadixHex;
870 },
845 else => {871 else => {
846 // reinterpret as a normal number872 // reinterpret as a normal number
847 self.index -= 1;873 self.index -= 1;
...@@ -862,8 +888,15 @@ pub const Tokenizer = struct {...@@ -862,8 +888,15 @@ pub const Tokenizer = struct {
862 '.' => {888 '.' => {
863 state = State.NumberDot;889 state = State.NumberDot;
864 },890 },
891 '0'...'9' => {},
892 else => break,
893 },
894 State.IntegerLiteralWithRadixHex => switch (c) {
895 '.' => {
896 state = State.NumberDotHex;
897 },
865 'p', 'P' => {898 'p', 'P' => {
866 state = State.FloatExponentUnsigned;899 state = State.FloatExponentUnsignedHex;
867 },900 },
868 '0'...'9', 'a'...'f', 'A'...'F' => {},901 '0'...'9', 'a'...'f', 'A'...'F' => {},
869 else => break,902 else => break,
...@@ -880,13 +913,32 @@ pub const Tokenizer = struct {...@@ -880,13 +913,32 @@ pub const Tokenizer = struct {
880 state = State.FloatFraction;913 state = State.FloatFraction;
881 },914 },
882 },915 },
916 State.NumberDotHex => switch (c) {
917 '.' => {
918 self.index -= 1;
919 state = State.Start;
920 break;
921 },
922 else => {
923 self.index -= 1;
924 result.id = Token.Id.FloatLiteral;
925 state = State.FloatFractionHex;
926 },
927 },
883 State.FloatFraction => switch (c) {928 State.FloatFraction => switch (c) {
884 'p', 'P', 'e', 'E' => {929 'e', 'E' => {
885 state = State.FloatExponentUnsigned;930 state = State.FloatExponentUnsigned;
886 },931 },
887 '0'...'9' => {},932 '0'...'9' => {},
888 else => break,933 else => break,
889 },934 },
935 State.FloatFractionHex => switch (c) {
936 'p', 'P' => {
937 state = State.FloatExponentUnsignedHex;
938 },
939 '0'...'9', 'a'...'f', 'A'...'F' => {},
940 else => break,
941 },
890 State.FloatExponentUnsigned => switch (c) {942 State.FloatExponentUnsigned => switch (c) {
891 '+', '-' => {943 '+', '-' => {
892 state = State.FloatExponentNumber;944 state = State.FloatExponentNumber;
...@@ -895,9 +947,23 @@ pub const Tokenizer = struct {...@@ -895,9 +947,23 @@ pub const Tokenizer = struct {
895 // reinterpret as a normal exponent number947 // reinterpret as a normal exponent number
896 self.index -= 1;948 self.index -= 1;
897 state = State.FloatExponentNumber;949 state = State.FloatExponentNumber;
898 }950 },
951 },
952 State.FloatExponentUnsignedHex => switch (c) {
953 '+', '-' => {
954 state = State.FloatExponentNumberHex;
955 },
956 else => {
957 // reinterpret as a normal exponent number
958 self.index -= 1;
959 state = State.FloatExponentNumberHex;
960 },
899 },961 },
900 State.FloatExponentNumber => switch (c) {962 State.FloatExponentNumber => switch (c) {
963 '0'...'9' => {},
964 else => break,
965 },
966 State.FloatExponentNumberHex => switch (c) {
901 '0'...'9', 'a'...'f', 'A'...'F' => {},967 '0'...'9', 'a'...'f', 'A'...'F' => {},
902 else => break,968 else => break,
903 },969 },
...@@ -908,19 +974,22 @@ pub const Tokenizer = struct {...@@ -908,19 +974,22 @@ pub const Tokenizer = struct {
908 State.C,974 State.C,
909 State.IntegerLiteral,975 State.IntegerLiteral,
910 State.IntegerLiteralWithRadix,976 State.IntegerLiteralWithRadix,
977 State.IntegerLiteralWithRadixHex,
911 State.FloatFraction,978 State.FloatFraction,
979 State.FloatFractionHex,
912 State.FloatExponentNumber,980 State.FloatExponentNumber,
981 State.FloatExponentNumberHex,
913 State.StringLiteral, // find this error later982 State.StringLiteral, // find this error later
914 State.MultilineStringLiteralLine,983 State.MultilineStringLiteralLine,
915 State.Builtin => {},984 State.Builtin,
985 => {},
916986
917 State.Identifier => {987 State.Identifier => {
918 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {988 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
919 result.id = id;989 result.id = id;
920 }990 }
921 },991 },
922 State.LineCommentStart,992 State.LineCommentStart, State.LineComment => {
923 State.LineComment => {
924 result.id = Token.Id.LineComment;993 result.id = Token.Id.LineComment;
925 },994 },
926 State.DocComment, State.DocCommentStart => {995 State.DocComment, State.DocCommentStart => {
...@@ -928,14 +997,18 @@ pub const Tokenizer = struct {...@@ -928,14 +997,18 @@ pub const Tokenizer = struct {
928 },997 },
929998
930 State.NumberDot,999 State.NumberDot,
1000 State.NumberDotHex,
931 State.FloatExponentUnsigned,1001 State.FloatExponentUnsigned,
1002 State.FloatExponentUnsignedHex,
932 State.SawAtSign,1003 State.SawAtSign,
933 State.Backslash,1004 State.Backslash,
934 State.MultilineStringLiteralLineBackslash,
935 State.CharLiteral,1005 State.CharLiteral,
936 State.CharLiteralBackslash,1006 State.CharLiteralBackslash,
1007 State.CharLiteralEscape1,
1008 State.CharLiteralEscape2,
937 State.CharLiteralEnd,1009 State.CharLiteralEnd,
938 State.StringLiteralBackslash => {1010 State.StringLiteralBackslash,
1011 => {
939 result.id = Token.Id.Invalid;1012 result.id = Token.Id.Invalid;
940 },1013 },
9411014
...@@ -1020,7 +1093,7 @@ pub const Tokenizer = struct {...@@ -1020,7 +1093,7 @@ pub const Tokenizer = struct {
1020 if (self.pending_invalid_token != null) return;1093 if (self.pending_invalid_token != null) return;
1021 const invalid_length = self.getInvalidCharacterLength();1094 const invalid_length = self.getInvalidCharacterLength();
1022 if (invalid_length == 0) return;1095 if (invalid_length == 0) return;
1023 self.pending_invalid_token = Token {1096 self.pending_invalid_token = Token{
1024 .id = Token.Id.Invalid,1097 .id = Token.Id.Invalid,
1025 .start = self.index,1098 .start = self.index,
1026 .end = self.index + invalid_length,1099 .end = self.index + invalid_length,
...@@ -1065,16 +1138,27 @@ pub const Tokenizer = struct {...@@ -1065,16 +1138,27 @@ pub const Tokenizer = struct {
1065 }1138 }
1066};1139};
10671140
1141test "tokenizer" {
1142 testTokenize("test", []Token.Id{Token.Id.Keyword_test});
1143}
10681144
1145test "tokenizer - char literal with hex escape" {
1146 testTokenize(
1147 \\'\x1b'
1148 , []Token.Id{Token.Id.CharLiteral});
1149}
10691150
1070test "tokenizer" {1151test "tokenizer - float literal e exponent" {
1071 testTokenize("test", []Token.Id {1152 testTokenize("a = 4.94065645841246544177e-324;\n", []Token.Id{
1072 Token.Id.Keyword_test,1153 Token.Id.Identifier,
1154 Token.Id.Equal,
1155 Token.Id.FloatLiteral,
1156 Token.Id.Semicolon,
1073 });1157 });
1074}1158}
10751159
1076test "tokenizer - float literal" {1160test "tokenizer - float literal p exponent" {
1077 testTokenize("a = 4.94065645841246544177e-324;\n", []Token.Id {1161 testTokenize("a = 0x1.a827999fcef32p+1022;\n", []Token.Id{
1078 Token.Id.Identifier,1162 Token.Id.Identifier,
1079 Token.Id.Equal,1163 Token.Id.Equal,
1080 Token.Id.FloatLiteral,1164 Token.Id.FloatLiteral,
...@@ -1083,31 +1167,31 @@ test "tokenizer - float literal" {...@@ -1083,31 +1167,31 @@ test "tokenizer - float literal" {
1083}1167}
10841168
1085test "tokenizer - chars" {1169test "tokenizer - chars" {
1086 testTokenize("'c'", []Token.Id {Token.Id.CharLiteral});1170 testTokenize("'c'", []Token.Id{Token.Id.CharLiteral});
1087}1171}
10881172
1089test "tokenizer - invalid token characters" {1173test "tokenizer - invalid token characters" {
1090 testTokenize("#", []Token.Id{Token.Id.Invalid});1174 testTokenize("#", []Token.Id{Token.Id.Invalid});
1091 testTokenize("`", []Token.Id{Token.Id.Invalid});1175 testTokenize("`", []Token.Id{Token.Id.Invalid});
1092 testTokenize("'c", []Token.Id {Token.Id.Invalid});1176 testTokenize("'c", []Token.Id{Token.Id.Invalid});
1093 testTokenize("'", []Token.Id {Token.Id.Invalid});1177 testTokenize("'", []Token.Id{Token.Id.Invalid});
1094 testTokenize("''", []Token.Id {Token.Id.Invalid, Token.Id.Invalid});1178 testTokenize("''", []Token.Id{ Token.Id.Invalid, Token.Id.Invalid });
1095}1179}
10961180
1097test "tokenizer - invalid literal/comment characters" {1181test "tokenizer - invalid literal/comment characters" {
1098 testTokenize("\"\x00\"", []Token.Id {1182 testTokenize("\"\x00\"", []Token.Id{
1099 Token.Id { .StringLiteral = Token.StrLitKind.Normal },1183 Token.Id{ .StringLiteral = Token.StrLitKind.Normal },
1100 Token.Id.Invalid,1184 Token.Id.Invalid,
1101 });1185 });
1102 testTokenize("//\x00", []Token.Id {1186 testTokenize("//\x00", []Token.Id{
1103 Token.Id.LineComment,1187 Token.Id.LineComment,
1104 Token.Id.Invalid,1188 Token.Id.Invalid,
1105 });1189 });
1106 testTokenize("//\x1f", []Token.Id {1190 testTokenize("//\x1f", []Token.Id{
1107 Token.Id.LineComment,1191 Token.Id.LineComment,
1108 Token.Id.Invalid,1192 Token.Id.Invalid,
1109 });1193 });
1110 testTokenize("//\x7f", []Token.Id {1194 testTokenize("//\x7f", []Token.Id{
1111 Token.Id.LineComment,1195 Token.Id.LineComment,
1112 Token.Id.Invalid,1196 Token.Id.Invalid,
1113 });1197 });
...@@ -1176,18 +1260,16 @@ test "tokenizer - illegal unicode codepoints" {...@@ -1176,18 +1260,16 @@ test "tokenizer - illegal unicode codepoints" {
1176test "tokenizer - string identifier and builtin fns" {1260test "tokenizer - string identifier and builtin fns" {
1177 testTokenize(1261 testTokenize(
1178 \\const @"if" = @import("std");1262 \\const @"if" = @import("std");
1179 ,1263 , []Token.Id{
1180 []Token.Id{1264 Token.Id.Keyword_const,
1181 Token.Id.Keyword_const,1265 Token.Id.Identifier,
1182 Token.Id.Identifier,1266 Token.Id.Equal,
1183 Token.Id.Equal,1267 Token.Id.Builtin,
1184 Token.Id.Builtin,1268 Token.Id.LParen,
1185 Token.Id.LParen,1269 Token.Id{ .StringLiteral = Token.StrLitKind.Normal },
1186 Token.Id {.StringLiteral = Token.StrLitKind.Normal},1270 Token.Id.RParen,
1187 Token.Id.RParen,1271 Token.Id.Semicolon,
1188 Token.Id.Semicolon,1272 });
1189 }
1190 );
1191}1273}
11921274
1193test "tokenizer - pipe and then invalid" {1275test "tokenizer - pipe and then invalid" {
...@@ -1229,7 +1311,10 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {...@@ -1229,7 +1311,10 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
1229 }1311 }
1230 switch (expected_token_id) {1312 switch (expected_token_id) {
1231 Token.Id.StringLiteral => |expected_kind| {1313 Token.Id.StringLiteral => |expected_kind| {
1232 std.debug.assert(expected_kind == switch (token.id) { Token.Id.StringLiteral => |kind| kind, else => unreachable });1314 std.debug.assert(expected_kind == switch (token.id) {
1315 Token.Id.StringLiteral => |kind| kind,
1316 else => unreachable,
1317 });
1233 },1318 },
1234 else => {},1319 else => {},
1235 }1320 }
test/behavior.zig+4-2
...@@ -23,6 +23,7 @@ comptime {...@@ -23,6 +23,7 @@ comptime {
23 _ = @import("cases/eval.zig");23 _ = @import("cases/eval.zig");
24 _ = @import("cases/field_parent_ptr.zig");24 _ = @import("cases/field_parent_ptr.zig");
25 _ = @import("cases/fn.zig");25 _ = @import("cases/fn.zig");
26 _ = @import("cases/fn_in_struct_in_comptime.zig");
26 _ = @import("cases/for.zig");27 _ = @import("cases/for.zig");
27 _ = @import("cases/generics.zig");28 _ = @import("cases/generics.zig");
28 _ = @import("cases/if.zig");29 _ = @import("cases/if.zig");
...@@ -32,11 +33,12 @@ comptime {...@@ -32,11 +33,12 @@ comptime {
32 _ = @import("cases/math.zig");33 _ = @import("cases/math.zig");
33 _ = @import("cases/misc.zig");34 _ = @import("cases/misc.zig");
34 _ = @import("cases/namespace_depends_on_compile_var/index.zig");35 _ = @import("cases/namespace_depends_on_compile_var/index.zig");
36 _ = @import("cases/new_stack_call.zig");
35 _ = @import("cases/null.zig");37 _ = @import("cases/null.zig");
38 _ = @import("cases/pointers.zig");
36 _ = @import("cases/pub_enum/index.zig");39 _ = @import("cases/pub_enum/index.zig");
37 _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");40 _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");
38 _ = @import("cases/reflection.zig");41 _ = @import("cases/reflection.zig");
39 _ = @import("cases/type_info.zig");
40 _ = @import("cases/sizeof_and_typeof.zig");42 _ = @import("cases/sizeof_and_typeof.zig");
41 _ = @import("cases/slice.zig");43 _ = @import("cases/slice.zig");
42 _ = @import("cases/struct.zig");44 _ = @import("cases/struct.zig");
...@@ -48,10 +50,10 @@ comptime {...@@ -48,10 +50,10 @@ comptime {
48 _ = @import("cases/syntax.zig");50 _ = @import("cases/syntax.zig");
49 _ = @import("cases/this.zig");51 _ = @import("cases/this.zig");
50 _ = @import("cases/try.zig");52 _ = @import("cases/try.zig");
53 _ = @import("cases/type_info.zig");
51 _ = @import("cases/undefined.zig");54 _ = @import("cases/undefined.zig");
52 _ = @import("cases/union.zig");55 _ = @import("cases/union.zig");
53 _ = @import("cases/var_args.zig");56 _ = @import("cases/var_args.zig");
54 _ = @import("cases/void.zig");57 _ = @import("cases/void.zig");
55 _ = @import("cases/while.zig");58 _ = @import("cases/while.zig");
56 _ = @import("cases/fn_in_struct_in_comptime.zig");
57}59}
test/build_examples.zig+1-1
...@@ -9,7 +9,7 @@ pub fn addCases(cases: &tests.BuildExamplesContext) void {...@@ -9,7 +9,7 @@ pub fn addCases(cases: &tests.BuildExamplesContext) void {
9 cases.add("example/guess_number/main.zig");9 cases.add("example/guess_number/main.zig");
10 if (!is_windows) {10 if (!is_windows) {
11 // TODO get this test passing on windows11 // TODO get this test passing on windows
12 // See https://github.com/zig-lang/zig/issues/53812 // See https://github.com/ziglang/zig/issues/538
13 cases.addBuildFile("example/shared_library/build.zig");13 cases.addBuildFile("example/shared_library/build.zig");
14 cases.addBuildFile("example/mix_o_files/build.zig");14 cases.addBuildFile("example/mix_o_files/build.zig");
15 }15 }
test/cases/align.zig+60-26
...@@ -10,7 +10,9 @@ test "global variable alignment" {...@@ -10,7 +10,9 @@ test "global variable alignment" {
10 assert(@typeOf(slice) == []align(4) u8);10 assert(@typeOf(slice) == []align(4) u8);
11}11}
1212
13fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; }13fn derp() align(@sizeOf(usize) * 2) i32 {
14 return 1234;
15}
14fn noop1() align(1) void {}16fn noop1() align(1) void {}
15fn noop4() align(4) void {}17fn noop4() align(4) void {}
1618
...@@ -22,7 +24,6 @@ test "function alignment" {...@@ -22,7 +24,6 @@ test "function alignment" {
22 noop4();24 noop4();
23}25}
2426
25
26var baz: packed struct {27var baz: packed struct {
27 a: u32,28 a: u32,
28 b: u32,29 b: u32,
...@@ -32,7 +33,6 @@ test "packed struct alignment" {...@@ -32,7 +33,6 @@ test "packed struct alignment" {
32 assert(@typeOf(&baz.b) == &align(1) u32);33 assert(@typeOf(&baz.b) == &align(1) u32);
33}34}
3435
35
36const blah: packed struct {36const blah: packed struct {
37 a: u3,37 a: u3,
38 b: u3,38 b: u3,
...@@ -53,29 +53,43 @@ test "implicitly decreasing pointer alignment" {...@@ -53,29 +53,43 @@ test "implicitly decreasing pointer alignment" {
53 assert(addUnaligned(&a, &b) == 7);53 assert(addUnaligned(&a, &b) == 7);
54}54}
5555
56fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) u32 { return *a + *b; }56fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) u32 {
57 return a.* + b.*;
58}
5759
58test "implicitly decreasing slice alignment" {60test "implicitly decreasing slice alignment" {
59 const a: u32 align(4) = 3;61 const a: u32 align(4) = 3;
60 const b: u32 align(8) = 4;62 const b: u32 align(8) = 4;
61 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);63 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);
62}64}
63fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { return a[0] + b[0]; }65fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
66 return a[0] + b[0];
67}
6468
65test "specifying alignment allows pointer cast" {69test "specifying alignment allows pointer cast" {
66 testBytesAlign(0x33);70 testBytesAlign(0x33);
67}71}
68fn testBytesAlign(b: u8) void {72fn testBytesAlign(b: u8) void {
69 var bytes align(4) = []u8{b, b, b, b};73 var bytes align(4) = []u8{
74 b,
75 b,
76 b,
77 b,
78 };
70 const ptr = @ptrCast(&u32, &bytes[0]);79 const ptr = @ptrCast(&u32, &bytes[0]);
71 assert(*ptr == 0x33333333);80 assert(ptr.* == 0x33333333);
72}81}
7382
74test "specifying alignment allows slice cast" {83test "specifying alignment allows slice cast" {
75 testBytesAlignSlice(0x33);84 testBytesAlignSlice(0x33);
76}85}
77fn testBytesAlignSlice(b: u8) void {86fn testBytesAlignSlice(b: u8) void {
78 var bytes align(4) = []u8{b, b, b, b};87 var bytes align(4) = []u8{
88 b,
89 b,
90 b,
91 b,
92 };
79 const slice = ([]u32)(bytes[0..]);93 const slice = ([]u32)(bytes[0..]);
80 assert(slice[0] == 0x33333333);94 assert(slice[0] == 0x33333333);
81}95}
...@@ -89,11 +103,14 @@ fn expectsOnly1(x: &align(1) u32) void {...@@ -89,11 +103,14 @@ fn expectsOnly1(x: &align(1) u32) void {
89 expects4(@alignCast(4, x));103 expects4(@alignCast(4, x));
90}104}
91fn expects4(x: &align(4) u32) void {105fn expects4(x: &align(4) u32) void {
92 *x += 1;106 x.* += 1;
93}107}
94108
95test "@alignCast slices" {109test "@alignCast slices" {
96 var array align(4) = []u32{1, 1};110 var array align(4) = []u32{
111 1,
112 1,
113 };
97 const slice = array[0..];114 const slice = array[0..];
98 sliceExpectsOnly1(slice);115 sliceExpectsOnly1(slice);
99 assert(slice[0] == 2);116 assert(slice[0] == 2);
...@@ -105,31 +122,34 @@ fn sliceExpects4(slice: []align(4) u32) void {...@@ -105,31 +122,34 @@ fn sliceExpects4(slice: []align(4) u32) void {
105 slice[0] += 1;122 slice[0] += 1;
106}123}
107124
108
109test "implicitly decreasing fn alignment" {125test "implicitly decreasing fn alignment" {
110 testImplicitlyDecreaseFnAlign(alignedSmall, 1234);126 testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
111 testImplicitlyDecreaseFnAlign(alignedBig, 5678);127 testImplicitlyDecreaseFnAlign(alignedBig, 5678);
112}128}
113129
114fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) void {130fn testImplicitlyDecreaseFnAlign(ptr: fn() align(1) i32, answer: i32) void {
115 assert(ptr() == answer);131 assert(ptr() == answer);
116}132}
117133
118fn alignedSmall() align(8) i32 { return 1234; }134fn alignedSmall() align(8) i32 {
119fn alignedBig() align(16) i32 { return 5678; }135 return 1234;
120136}
137fn alignedBig() align(16) i32 {
138 return 5678;
139}
121140
122test "@alignCast functions" {141test "@alignCast functions" {
123 assert(fnExpectsOnly1(simple4) == 0x19);142 assert(fnExpectsOnly1(simple4) == 0x19);
124}143}
125fn fnExpectsOnly1(ptr: fn()align(1) i32) i32 {144fn fnExpectsOnly1(ptr: fn() align(1) i32) i32 {
126 return fnExpects4(@alignCast(4, ptr));145 return fnExpects4(@alignCast(4, ptr));
127}146}
128fn fnExpects4(ptr: fn()align(4) i32) i32 {147fn fnExpects4(ptr: fn() align(4) i32) i32 {
129 return ptr();148 return ptr();
130}149}
131fn simple4() align(4) i32 { return 0x19; }150fn simple4() align(4) i32 {
132151 return 0x19;
152}
133153
134test "generic function with align param" {154test "generic function with align param" {
135 assert(whyWouldYouEverDoThis(1) == 0x1);155 assert(whyWouldYouEverDoThis(1) == 0x1);
...@@ -137,8 +157,9 @@ test "generic function with align param" {...@@ -137,8 +157,9 @@ test "generic function with align param" {
137 assert(whyWouldYouEverDoThis(8) == 0x1);157 assert(whyWouldYouEverDoThis(8) == 0x1);
138}158}
139159
140fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { return 0x1; }160fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 {
141161 return 0x1;
162}
142163
143test "@ptrCast preserves alignment of bigger source" {164test "@ptrCast preserves alignment of bigger source" {
144 var x: u32 align(16) = 1234;165 var x: u32 align(16) = 1234;
...@@ -146,24 +167,38 @@ test "@ptrCast preserves alignment of bigger source" {...@@ -146,24 +167,38 @@ test "@ptrCast preserves alignment of bigger source" {
146 assert(@typeOf(ptr) == &align(16) u8);167 assert(@typeOf(ptr) == &align(16) u8);
147}168}
148169
149
150test "compile-time known array index has best alignment possible" {170test "compile-time known array index has best alignment possible" {
151 // take full advantage of over-alignment171 // take full advantage of over-alignment
152 var array align(4) = []u8 {1, 2, 3, 4};172 var array align(4) = []u8{
173 1,
174 2,
175 3,
176 4,
177 };
153 assert(@typeOf(&array[0]) == &align(4) u8);178 assert(@typeOf(&array[0]) == &align(4) u8);
154 assert(@typeOf(&array[1]) == &u8);179 assert(@typeOf(&array[1]) == &u8);
155 assert(@typeOf(&array[2]) == &align(2) u8);180 assert(@typeOf(&array[2]) == &align(2) u8);
156 assert(@typeOf(&array[3]) == &u8);181 assert(@typeOf(&array[3]) == &u8);
157182
158 // because align is too small but we still figure out to use 2183 // because align is too small but we still figure out to use 2
159 var bigger align(2) = []u64{1, 2, 3, 4};184 var bigger align(2) = []u64{
185 1,
186 2,
187 3,
188 4,
189 };
160 assert(@typeOf(&bigger[0]) == &align(2) u64);190 assert(@typeOf(&bigger[0]) == &align(2) u64);
161 assert(@typeOf(&bigger[1]) == &align(2) u64);191 assert(@typeOf(&bigger[1]) == &align(2) u64);
162 assert(@typeOf(&bigger[2]) == &align(2) u64);192 assert(@typeOf(&bigger[2]) == &align(2) u64);
163 assert(@typeOf(&bigger[3]) == &align(2) u64);193 assert(@typeOf(&bigger[3]) == &align(2) u64);
164194
165 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2195 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
166 var smaller align(2) = []u32{1, 2, 3, 4};196 var smaller align(2) = []u32{
197 1,
198 2,
199 3,
200 4,
201 };
167 testIndex(&smaller[0], 0, &align(2) u32);202 testIndex(&smaller[0], 0, &align(2) u32);
168 testIndex(&smaller[0], 1, &align(2) u32);203 testIndex(&smaller[0], 1, &align(2) u32);
169 testIndex(&smaller[0], 2, &align(2) u32);204 testIndex(&smaller[0], 2, &align(2) u32);
...@@ -182,7 +217,6 @@ fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) void {...@@ -182,7 +217,6 @@ fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) void {
182 assert(@typeOf(&ptr[index]) == T);217 assert(@typeOf(&ptr[index]) == T);
183}218}
184219
185
186test "alignstack" {220test "alignstack" {
187 assert(fnWithAlignedStack() == 1234);221 assert(fnWithAlignedStack() == 1234);
188}222}
test/cases/alignof.zig+5-1
...@@ -1,7 +1,11 @@...@@ -1,7 +1,11 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4const Foo = struct { x: u32, y: u32, z: u32, };4const Foo = struct {
5 x: u32,
6 y: u32,
7 z: u32,
8};
59
6test "@alignOf(T) before referencing T" {10test "@alignOf(T) before referencing T" {
7 comptime assert(@alignOf(Foo) != @maxValue(usize));11 comptime assert(@alignOf(Foo) != @maxValue(usize));
test/cases/array.zig+29-10
...@@ -2,9 +2,9 @@ const assert = @import("std").debug.assert;...@@ -2,9 +2,9 @@ const assert = @import("std").debug.assert;
2const mem = @import("std").mem;2const mem = @import("std").mem;
33
4test "arrays" {4test "arrays" {
5 var array : [5]u32 = undefined;5 var array: [5]u32 = undefined;
66
7 var i : u32 = 0;7 var i: u32 = 0;
8 while (i < 5) {8 while (i < 5) {
9 array[i] = i + 1;9 array[i] = i + 1;
10 i = array[i];10 i = array[i];
...@@ -34,24 +34,41 @@ test "void arrays" {...@@ -34,24 +34,41 @@ test "void arrays" {
34}34}
3535
36test "array literal" {36test "array literal" {
37 const hex_mult = []u16{4096, 256, 16, 1};37 const hex_mult = []u16{
38 4096,
39 256,
40 16,
41 1,
42 };
3843
39 assert(hex_mult.len == 4);44 assert(hex_mult.len == 4);
40 assert(hex_mult[1] == 256);45 assert(hex_mult[1] == 256);
41}46}
4247
43test "array dot len const expr" {48test "array dot len const expr" {
44 assert(comptime x: {break :x some_array.len == 4;});49 assert(comptime x: {
50 break :x some_array.len == 4;
51 });
45}52}
4653
47const ArrayDotLenConstExpr = struct {54const ArrayDotLenConstExpr = struct {
48 y: [some_array.len]u8,55 y: [some_array.len]u8,
49};56};
50const some_array = []u8 {0, 1, 2, 3};57const some_array = []u8{
5158 0,
59 1,
60 2,
61 3,
62};
5263
53test "nested arrays" {64test "nested arrays" {
54 const array_of_strings = [][]const u8 {"hello", "this", "is", "my", "thing"};65 const array_of_strings = [][]const u8{
66 "hello",
67 "this",
68 "is",
69 "my",
70 "thing",
71 };
55 for (array_of_strings) |s, i| {72 for (array_of_strings) |s, i| {
56 if (i == 0) assert(mem.eql(u8, s, "hello"));73 if (i == 0) assert(mem.eql(u8, s, "hello"));
57 if (i == 1) assert(mem.eql(u8, s, "this"));74 if (i == 1) assert(mem.eql(u8, s, "this"));
...@@ -61,7 +78,6 @@ test "nested arrays" {...@@ -61,7 +78,6 @@ test "nested arrays" {
61 }78 }
62}79}
6380
64
65var s_array: [8]Sub = undefined;81var s_array: [8]Sub = undefined;
66const Sub = struct {82const Sub = struct {
67 b: u8,83 b: u8,
...@@ -70,7 +86,7 @@ const Str = struct {...@@ -70,7 +86,7 @@ const Str = struct {
70 a: []Sub,86 a: []Sub,
71};87};
72test "set global var array via slice embedded in struct" {88test "set global var array via slice embedded in struct" {
73 var s = Str { .a = s_array[0..]};89 var s = Str{ .a = s_array[0..] };
7490
75 s.a[0].b = 1;91 s.a[0].b = 1;
76 s.a[1].b = 2;92 s.a[1].b = 2;
...@@ -82,7 +98,10 @@ test "set global var array via slice embedded in struct" {...@@ -82,7 +98,10 @@ test "set global var array via slice embedded in struct" {
82}98}
8399
84test "array literal with specified size" {100test "array literal with specified size" {
85 var array = [2]u8{1, 2};101 var array = [2]u8{
102 1,
103 2,
104 };
86 assert(array[0] == 1);105 assert(array[0] == 1);
87 assert(array[1] == 2);106 assert(array[1] == 2);
88}107}
test/cases/bitcast.zig+6-2
...@@ -10,5 +10,9 @@ fn testBitCast_i32_u32() void {...@@ -10,5 +10,9 @@ fn testBitCast_i32_u32() void {
10 assert(conv2(@maxValue(u32)) == -1);10 assert(conv2(@maxValue(u32)) == -1);
11}11}
1212
13fn conv(x: i32) u32 { return @bitCast(u32, x); }13fn conv(x: i32) u32 {
14fn conv2(x: u32) i32 { return @bitCast(i32, x); }14 return @bitCast(u32, x);
15}
16fn conv2(x: u32) i32 {
17 return @bitCast(i32, x);
18}
test/cases/bugs/394.zig+12-3
...@@ -1,9 +1,18 @@...@@ -1,9 +1,18 @@
1const E = union(enum) { A: [9]u8, B: u64, };1const E = union(enum) {
2const S = struct { x: u8, y: E, };2 A: [9]u8,
3 B: u64,
4};
5const S = struct {
6 x: u8,
7 y: E,
8};
39
4const assert = @import("std").debug.assert;10const assert = @import("std").debug.assert;
511
6test "bug 394 fixed" {12test "bug 394 fixed" {
7 const x = S { .x = 3, .y = E {.B = 1 } };13 const x = S{
14 .x = 3,
15 .y = E{ .B = 1 },
16 };
8 assert(x.x == 3);17 assert(x.x == 3);
9}18}
test/cases/bugs/655.zig+1-1
...@@ -8,5 +8,5 @@ test "function with &const parameter with type dereferenced by namespace" {...@@ -8,5 +8,5 @@ test "function with &const parameter with type dereferenced by namespace" {
8}8}
99
10fn foo(x: &const other_file.Integer) void {10fn foo(x: &const other_file.Integer) void {
11 std.debug.assert(*x == 1234);11 std.debug.assert(x.* == 1234);
12}12}
test/cases/bugs/656.zig+5-4
...@@ -14,12 +14,13 @@ test "nullable if after an if in a switch prong of a switch with 2 prongs in an...@@ -14,12 +14,13 @@ test "nullable if after an if in a switch prong of a switch with 2 prongs in an
14}14}
1515
16fn foo(a: bool, b: bool) void {16fn foo(a: bool, b: bool) void {
17 var prefix_op = PrefixOp { .AddrOf = Value { .align_expr = 1234 } };17 var prefix_op = PrefixOp{
18 if (a) {18 .AddrOf = Value{ .align_expr = 1234 },
19 } else {19 };
20 if (a) {} else {
20 switch (prefix_op) {21 switch (prefix_op) {
21 PrefixOp.AddrOf => |addr_of_info| {22 PrefixOp.AddrOf => |addr_of_info| {
22 if (b) { }23 if (b) {}
23 if (addr_of_info.align_expr) |align_expr| {24 if (addr_of_info.align_expr) |align_expr| {
24 assert(align_expr == 1234);25 assert(align_expr == 1234);
25 }26 }
test/cases/bugs/828.zig+7-11
...@@ -1,20 +1,16 @@...@@ -1,20 +1,16 @@
1const CountBy = struct {1const CountBy = struct {
2 a: usize,2 a: usize,
3 3
4 const One = CountBy {4 const One = CountBy{ .a = 1 };
5 .a = 1,5
6 };
7
8 pub fn counter(self: &const CountBy) Counter {6 pub fn counter(self: &const CountBy) Counter {
9 return Counter {7 return Counter{ .i = 0 };
10 .i = 0,
11 };
12 }8 }
13};9};
1410
15const Counter = struct {11const Counter = struct {
16 i: usize,12 i: usize,
17 13
18 pub fn count(self: &Counter) bool {14 pub fn count(self: &Counter) bool {
19 self.i += 1;15 self.i += 1;
20 return self.i <= 10;16 return self.i <= 10;
...@@ -24,8 +20,8 @@ const Counter = struct {...@@ -24,8 +20,8 @@ const Counter = struct {
24fn constCount(comptime cb: &const CountBy, comptime unused: u32) void {20fn constCount(comptime cb: &const CountBy, comptime unused: u32) void {
25 comptime {21 comptime {
26 var cnt = cb.counter();22 var cnt = cb.counter();
27 if(cnt.i != 0) @compileError("Counter instance reused!");23 if (cnt.i != 0) @compileError("Counter instance reused!");
28 while(cnt.count()){}24 while (cnt.count()) {}
29 }25 }
30}26}
3127
test/cases/bugs/920.zig+12-7
...@@ -12,8 +12,7 @@ const ZigTable = struct {...@@ -12,8 +12,7 @@ const ZigTable = struct {
12 zero_case: fn(&Random, f64) f64,12 zero_case: fn(&Random, f64) f64,
13};13};
1414
15fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn(f64) f64,15fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn(f64) f64, comptime f_inv: fn(f64) f64, comptime zero_case: fn(&Random, f64) f64) ZigTable {
16 comptime f_inv: fn(f64) f64, comptime zero_case: fn(&Random, f64) f64) ZigTable {
17 var tables: ZigTable = undefined;16 var tables: ZigTable = undefined;
1817
19 tables.is_symmetric = is_symmetric;18 tables.is_symmetric = is_symmetric;
...@@ -26,12 +25,12 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co...@@ -26,12 +25,12 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co
2625
27 for (tables.x[2..256]) |*entry, i| {26 for (tables.x[2..256]) |*entry, i| {
28 const last = tables.x[2 + i - 1];27 const last = tables.x[2 + i - 1];
29 *entry = f_inv(v / last + f(last));28 entry.* = f_inv(v / last + f(last));
30 }29 }
31 tables.x[256] = 0;30 tables.x[256] = 0;
3231
33 for (tables.f[0..]) |*entry, i| {32 for (tables.f[0..]) |*entry, i| {
34 *entry = f(tables.x[i]);33 entry.* = f(tables.x[i]);
35 }34 }
3635
37 return tables;36 return tables;
...@@ -40,9 +39,15 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co...@@ -40,9 +39,15 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co
40const norm_r = 3.6541528853610088;39const norm_r = 3.6541528853610088;
41const norm_v = 0.00492867323399;40const norm_v = 0.00492867323399;
4241
43fn norm_f(x: f64) f64 { return math.exp(-x * x / 2.0); }42fn norm_f(x: f64) f64 {
44fn norm_f_inv(y: f64) f64 { return math.sqrt(-2.0 * math.ln(y)); }43 return math.exp(-x * x / 2.0);
45fn norm_zero_case(random: &Random, u: f64) f64 { return 0.0; }44}
45fn norm_f_inv(y: f64) f64 {
46 return math.sqrt(-2.0 * math.ln(y));
47}
48fn norm_zero_case(random: &Random, u: f64) f64 {
49 return 0.0;
50}
4651
47const NormalDist = blk: {52const NormalDist = blk: {
48 @setEvalBranchQuota(30000);53 @setEvalBranchQuota(30000);
test/cases/cast.zig+27-28
...@@ -17,7 +17,7 @@ test "pointer reinterpret const float to int" {...@@ -17,7 +17,7 @@ test "pointer reinterpret const float to int" {
17 const float: f64 = 5.99999999999994648725e-01;17 const float: f64 = 5.99999999999994648725e-01;
18 const float_ptr = &float;18 const float_ptr = &float;
19 const int_ptr = @ptrCast(&const i32, float_ptr);19 const int_ptr = @ptrCast(&const i32, float_ptr);
20 const int_val = *int_ptr;20 const int_val = int_ptr.*;
21 assert(int_val == 858993411);21 assert(int_val == 858993411);
22}22}
2323
...@@ -29,25 +29,25 @@ test "implicitly cast a pointer to a const pointer of it" {...@@ -29,25 +29,25 @@ test "implicitly cast a pointer to a const pointer of it" {
29}29}
3030
31fn funcWithConstPtrPtr(x: &const &i32) void {31fn funcWithConstPtrPtr(x: &const &i32) void {
32 **x += 1;32 x.*.* += 1;
33}33}
3434
35test "implicitly cast a container to a const pointer of it" {35test "implicitly cast a container to a const pointer of it" {
36 const z = Struct(void) { .x = void{} };36 const z = Struct(void){ .x = void{} };
37 assert(0 == @sizeOf(@typeOf(z)));37 assert(0 == @sizeOf(@typeOf(z)));
38 assert(void{} == Struct(void).pointer(z).x);38 assert(void{} == Struct(void).pointer(z).x);
39 assert(void{} == Struct(void).pointer(&z).x);39 assert(void{} == Struct(void).pointer(&z).x);
40 assert(void{} == Struct(void).maybePointer(z).x);40 assert(void{} == Struct(void).maybePointer(z).x);
41 assert(void{} == Struct(void).maybePointer(&z).x);41 assert(void{} == Struct(void).maybePointer(&z).x);
42 assert(void{} == Struct(void).maybePointer(null).x);42 assert(void{} == Struct(void).maybePointer(null).x);
43 const s = Struct(u8) { .x = 42 };43 const s = Struct(u8){ .x = 42 };
44 assert(0 != @sizeOf(@typeOf(s)));44 assert(0 != @sizeOf(@typeOf(s)));
45 assert(42 == Struct(u8).pointer(s).x);45 assert(42 == Struct(u8).pointer(s).x);
46 assert(42 == Struct(u8).pointer(&s).x);46 assert(42 == Struct(u8).pointer(&s).x);
47 assert(42 == Struct(u8).maybePointer(s).x);47 assert(42 == Struct(u8).maybePointer(s).x);
48 assert(42 == Struct(u8).maybePointer(&s).x);48 assert(42 == Struct(u8).maybePointer(&s).x);
49 assert(0 == Struct(u8).maybePointer(null).x);49 assert(0 == Struct(u8).maybePointer(null).x);
50 const u = Union { .x = 42 };50 const u = Union{ .x = 42 };
51 assert(42 == Union.pointer(u).x);51 assert(42 == Union.pointer(u).x);
52 assert(42 == Union.pointer(&u).x);52 assert(42 == Union.pointer(&u).x);
53 assert(42 == Union.maybePointer(u).x);53 assert(42 == Union.maybePointer(u).x);
...@@ -67,12 +67,12 @@ fn Struct(comptime T: type) type {...@@ -67,12 +67,12 @@ fn Struct(comptime T: type) type {
67 x: T,67 x: T,
6868
69 fn pointer(self: &const Self) Self {69 fn pointer(self: &const Self) Self {
70 return *self;70 return self.*;
71 }71 }
7272
73 fn maybePointer(self: ?&const Self) Self {73 fn maybePointer(self: ?&const Self) Self {
74 const none = Self { .x = if (T == void) void{} else 0 };74 const none = Self{ .x = if (T == void) void{} else 0 };
75 return *(self ?? &none);75 return (self ?? &none).*;
76 }76 }
77 };77 };
78}78}
...@@ -81,12 +81,12 @@ const Union = union {...@@ -81,12 +81,12 @@ const Union = union {
81 x: u8,81 x: u8,
8282
83 fn pointer(self: &const Union) Union {83 fn pointer(self: &const Union) Union {
84 return *self;84 return self.*;
85 }85 }
8686
87 fn maybePointer(self: ?&const Union) Union {87 fn maybePointer(self: ?&const Union) Union {
88 const none = Union { .x = 0 };88 const none = Union{ .x = 0 };
89 return *(self ?? &none);89 return (self ?? &none).*;
90 }90 }
91};91};
9292
...@@ -95,11 +95,11 @@ const Enum = enum {...@@ -95,11 +95,11 @@ const Enum = enum {
95 Some,95 Some,
9696
97 fn pointer(self: &const Enum) Enum {97 fn pointer(self: &const Enum) Enum {
98 return *self;98 return self.*;
99 }99 }
100100
101 fn maybePointer(self: ?&const Enum) Enum {101 fn maybePointer(self: ?&const Enum) Enum {
102 return *(self ?? &Enum.None);102 return (self ?? &Enum.None).*;
103 }103 }
104};104};
105105
...@@ -108,19 +108,19 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" {...@@ -108,19 +108,19 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" {
108 const Self = this;108 const Self = this;
109 x: u8,109 x: u8,
110 fn constConst(p: &const &const Self) u8 {110 fn constConst(p: &const &const Self) u8 {
111 return (*p).x;111 return (p.*).x;
112 }112 }
113 fn maybeConstConst(p: ?&const &const Self) u8 {113 fn maybeConstConst(p: ?&const &const Self) u8 {
114 return (*??p).x;114 return ((??p).*).x;
115 }115 }
116 fn constConstConst(p: &const &const &const Self) u8 {116 fn constConstConst(p: &const &const &const Self) u8 {
117 return (**p).x;117 return (p.*.*).x;
118 }118 }
119 fn maybeConstConstConst(p: ?&const &const &const Self) u8 {119 fn maybeConstConstConst(p: ?&const &const &const Self) u8 {
120 return (**??p).x;120 return ((??p).*.*).x;
121 }121 }
122 };122 };
123 const s = S { .x = 42 };123 const s = S{ .x = 42 };
124 const p = &s;124 const p = &s;
125 const q = &p;125 const q = &p;
126 const r = &q;126 const r = &q;
...@@ -154,7 +154,6 @@ fn boolToStr(b: bool) []const u8 {...@@ -154,7 +154,6 @@ fn boolToStr(b: bool) []const u8 {
154 return if (b) "true" else "false";154 return if (b) "true" else "false";
155}155}
156156
157
158test "peer resolve array and const slice" {157test "peer resolve array and const slice" {
159 testPeerResolveArrayConstSlice(true);158 testPeerResolveArrayConstSlice(true);
160 comptime testPeerResolveArrayConstSlice(true);159 comptime testPeerResolveArrayConstSlice(true);
...@@ -168,12 +167,12 @@ fn testPeerResolveArrayConstSlice(b: bool) void {...@@ -168,12 +167,12 @@ fn testPeerResolveArrayConstSlice(b: bool) void {
168167
169test "integer literal to &const int" {168test "integer literal to &const int" {
170 const x: &const i32 = 3;169 const x: &const i32 = 3;
171 assert(*x == 3);170 assert(x.* == 3);
172}171}
173172
174test "string literal to &const []const u8" {173test "string literal to &const []const u8" {
175 const x: &const []const u8 = "hello";174 const x: &const []const u8 = "hello";
176 assert(mem.eql(u8, *x, "hello"));175 assert(mem.eql(u8, x.*, "hello"));
177}176}
178177
179test "implicitly cast from T to error!?T" {178test "implicitly cast from T to error!?T" {
...@@ -205,7 +204,6 @@ fn implicitIntLitToMaybe() void {...@@ -205,7 +204,6 @@ fn implicitIntLitToMaybe() void {
205 const g: error!?i32 = 1;204 const g: error!?i32 = 1;
206}205}
207206
208
209test "return null from fn() error!?&T" {207test "return null from fn() error!?&T" {
210 const a = returnNullFromMaybeTypeErrorRef();208 const a = returnNullFromMaybeTypeErrorRef();
211 const b = returnNullLitFromMaybeTypeErrorRef();209 const b = returnNullLitFromMaybeTypeErrorRef();
...@@ -235,7 +233,6 @@ fn peerTypeTAndMaybeT(c: bool, b: bool) ?usize {...@@ -235,7 +233,6 @@ fn peerTypeTAndMaybeT(c: bool, b: bool) ?usize {
235 return usize(3);233 return usize(3);
236}234}
237235
238
239test "peer type resolution: [0]u8 and []const u8" {236test "peer type resolution: [0]u8 and []const u8" {
240 assert(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);237 assert(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
241 assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);238 assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
...@@ -246,7 +243,7 @@ test "peer type resolution: [0]u8 and []const u8" {...@@ -246,7 +243,7 @@ test "peer type resolution: [0]u8 and []const u8" {
246}243}
247fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {244fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
248 if (a) {245 if (a) {
249 return []const u8 {};246 return []const u8{};
250 }247 }
251248
252 return slice[0..1];249 return slice[0..1];
...@@ -261,7 +258,6 @@ fn castToMaybeSlice() ?[]const u8 {...@@ -261,7 +258,6 @@ fn castToMaybeSlice() ?[]const u8 {
261 return "hi";258 return "hi";
262}259}
263260
264
265test "implicitly cast from [0]T to error![]T" {261test "implicitly cast from [0]T to error![]T" {
266 testCastZeroArrayToErrSliceMut();262 testCastZeroArrayToErrSliceMut();
267 comptime testCastZeroArrayToErrSliceMut();263 comptime testCastZeroArrayToErrSliceMut();
...@@ -329,12 +325,10 @@ fn foo(args: ...) void {...@@ -329,12 +325,10 @@ fn foo(args: ...) void {
329 assert(@typeOf(args[0]) == &const [5]u8);325 assert(@typeOf(args[0]) == &const [5]u8);
330}326}
331327
332
333test "peer type resolution: error and [N]T" {328test "peer type resolution: error and [N]T" {
334 // TODO: implicit error!T to error!U where T can implicitly cast to U329 // TODO: implicit error!T to error!U where T can implicitly cast to U
335 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));330 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
336 //comptime assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));331 //comptime assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
337
338 assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));332 assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
339 comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));333 comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
340}334}
...@@ -378,7 +372,12 @@ fn cast128Float(x: u128) f128 {...@@ -378,7 +372,12 @@ fn cast128Float(x: u128) f128 {
378}372}
379373
380test "const slice widen cast" {374test "const slice widen cast" {
381 const bytes align(4) = []u8{0x12, 0x12, 0x12, 0x12};375 const bytes align(4) = []u8{
376 0x12,
377 0x12,
378 0x12,
379 0x12,
380 };
382381
383 const u32_value = ([]const u32)(bytes[0..])[0];382 const u32_value = ([]const u32)(bytes[0..])[0];
384 assert(u32_value == 0x12121212);383 assert(u32_value == 0x12121212);
test/cases/const_slice_child.zig+1-1
...@@ -4,7 +4,7 @@ const assert = debug.assert;...@@ -4,7 +4,7 @@ const assert = debug.assert;
4var argv: &const &const u8 = undefined;4var argv: &const &const u8 = undefined;
55
6test "const slice child" {6test "const slice child" {
7 const strs = ([]&const u8) {7 const strs = ([]&const u8){
8 c"one",8 c"one",
9 c"two",9 c"two",
10 c"three",10 c"three",
test/cases/coroutines.zig+7-22
...@@ -10,7 +10,6 @@ test "create a coroutine and cancel it" {...@@ -10,7 +10,6 @@ test "create a coroutine and cancel it" {
10 cancel p;10 cancel p;
11 assert(x == 2);11 assert(x == 2);
12}12}
13
14async fn simpleAsyncFn() void {13async fn simpleAsyncFn() void {
15 x += 1;14 x += 1;
16 suspend;15 suspend;
...@@ -28,7 +27,6 @@ test "coroutine suspend, resume, cancel" {...@@ -28,7 +27,6 @@ test "coroutine suspend, resume, cancel" {
2827
29 assert(std.mem.eql(u8, points, "abcdefg"));28 assert(std.mem.eql(u8, points, "abcdefg"));
30}29}
31
32async fn testAsyncSeq() void {30async fn testAsyncSeq() void {
33 defer seq('e');31 defer seq('e');
3432
...@@ -54,7 +52,6 @@ test "coroutine suspend with block" {...@@ -54,7 +52,6 @@ test "coroutine suspend with block" {
5452
55var a_promise: promise = undefined;53var a_promise: promise = undefined;
56var result = false;54var result = false;
57
58async fn testSuspendBlock() void {55async fn testSuspendBlock() void {
59 suspend |p| {56 suspend |p| {
60 comptime assert(@typeOf(p) == promise->void);57 comptime assert(@typeOf(p) == promise->void);
...@@ -75,7 +72,6 @@ test "coroutine await" {...@@ -75,7 +72,6 @@ test "coroutine await" {
75 assert(await_final_result == 1234);72 assert(await_final_result == 1234);
76 assert(std.mem.eql(u8, await_points, "abcdefghi"));73 assert(std.mem.eql(u8, await_points, "abcdefghi"));
77}74}
78
79async fn await_amain() void {75async fn await_amain() void {
80 await_seq('b');76 await_seq('b');
81 const p = async await_another() catch unreachable;77 const p = async await_another() catch unreachable;
...@@ -83,7 +79,6 @@ async fn await_amain() void {...@@ -83,7 +79,6 @@ async fn await_amain() void {
83 await_final_result = await p;79 await_final_result = await p;
84 await_seq('h');80 await_seq('h');
85}81}
86
87async fn await_another() i32 {82async fn await_another() i32 {
88 await_seq('c');83 await_seq('c');
89 suspend |p| {84 suspend |p| {
...@@ -102,7 +97,6 @@ fn await_seq(c: u8) void {...@@ -102,7 +97,6 @@ fn await_seq(c: u8) void {
102 await_seq_index += 1;97 await_seq_index += 1;
103}98}
10499
105
106var early_final_result: i32 = 0;100var early_final_result: i32 = 0;
107101
108test "coroutine await early return" {102test "coroutine await early return" {
...@@ -112,7 +106,6 @@ test "coroutine await early return" {...@@ -112,7 +106,6 @@ test "coroutine await early return" {
112 assert(early_final_result == 1234);106 assert(early_final_result == 1234);
113 assert(std.mem.eql(u8, early_points, "abcdef"));107 assert(std.mem.eql(u8, early_points, "abcdef"));
114}108}
115
116async fn early_amain() void {109async fn early_amain() void {
117 early_seq('b');110 early_seq('b');
118 const p = async early_another() catch unreachable;111 const p = async early_another() catch unreachable;
...@@ -120,7 +113,6 @@ async fn early_amain() void {...@@ -120,7 +113,6 @@ async fn early_amain() void {
120 early_final_result = await p;113 early_final_result = await p;
121 early_seq('e');114 early_seq('e');
122}115}
123
124async fn early_another() i32 {116async fn early_another() i32 {
125 early_seq('c');117 early_seq('c');
126 return 1234;118 return 1234;
...@@ -142,7 +134,6 @@ test "coro allocation failure" {...@@ -142,7 +134,6 @@ test "coro allocation failure" {
142 error.OutOfMemory => {},134 error.OutOfMemory => {},
143 }135 }
144}136}
145
146async fn asyncFuncThatNeverGetsRun() void {137async fn asyncFuncThatNeverGetsRun() void {
147 @panic("coro frame allocation should fail");138 @panic("coro frame allocation should fail");
148}139}
...@@ -165,18 +156,15 @@ test "async fn pointer in a struct field" {...@@ -165,18 +156,15 @@ test "async fn pointer in a struct field" {
165 const Foo = struct {156 const Foo = struct {
166 bar: async<&std.mem.Allocator> fn(&i32) void,157 bar: async<&std.mem.Allocator> fn(&i32) void,
167 };158 };
168 var foo = Foo {159 var foo = Foo{ .bar = simpleAsyncFn2 };
169 .bar = simpleAsyncFn2,
170 };
171 const p = (async<std.debug.global_allocator> foo.bar(&data)) catch unreachable;160 const p = (async<std.debug.global_allocator> foo.bar(&data)) catch unreachable;
172 assert(data == 2);161 assert(data == 2);
173 cancel p;162 cancel p;
174 assert(data == 4);163 assert(data == 4);
175}164}
176
177async<&std.mem.Allocator> fn simpleAsyncFn2(y: &i32) void {165async<&std.mem.Allocator> fn simpleAsyncFn2(y: &i32) void {
178 defer *y += 2;166 defer y.* += 2;
179 *y += 1;167 y.* += 1;
180 suspend;168 suspend;
181}169}
182170
...@@ -185,7 +173,6 @@ test "async fn with inferred error set" {...@@ -185,7 +173,6 @@ test "async fn with inferred error set" {
185 resume p;173 resume p;
186 cancel p;174 cancel p;
187}175}
188
189async fn failing() !void {176async fn failing() !void {
190 suspend;177 suspend;
191 return error.Fail;178 return error.Fail;
...@@ -205,15 +192,14 @@ test "error return trace across suspend points - async return" {...@@ -205,15 +192,14 @@ test "error return trace across suspend points - async return" {
205 cancel p2;192 cancel p2;
206}193}
207194
208fn nonFailing() promise->error!void {195// TODO https://github.com/ziglang/zig/issues/760
196fn nonFailing() (promise->error!void) {
209 return async<std.debug.global_allocator> suspendThenFail() catch unreachable;197 return async<std.debug.global_allocator> suspendThenFail() catch unreachable;
210}198}
211
212async fn suspendThenFail() error!void {199async fn suspendThenFail() error!void {
213 suspend;200 suspend;
214 return error.Fail;201 return error.Fail;
215}202}
216
217async fn printTrace(p: promise->error!void) void {203async fn printTrace(p: promise->error!void) void {
218 (await p) catch |e| {204 (await p) catch |e| {
219 std.debug.assert(e == error.Fail);205 std.debug.assert(e == error.Fail);
...@@ -234,12 +220,11 @@ test "break from suspend" {...@@ -234,12 +220,11 @@ test "break from suspend" {
234 cancel p;220 cancel p;
235 std.debug.assert(my_result == 2);221 std.debug.assert(my_result == 2);
236}222}
237
238async fn testBreakFromSuspend(my_result: &i32) void {223async fn testBreakFromSuspend(my_result: &i32) void {
239 s: suspend |p| {224 s: suspend |p| {
240 break :s;225 break :s;
241 }226 }
242 *my_result += 1;227 my_result.* += 1;
243 suspend;228 suspend;
244 *my_result += 1;229 my_result.* += 1;
245}230}
test/cases/defer.zig+12-3
...@@ -5,9 +5,18 @@ var index: usize = undefined;...@@ -5,9 +5,18 @@ var index: usize = undefined;
55
6fn runSomeErrorDefers(x: bool) !bool {6fn runSomeErrorDefers(x: bool) !bool {
7 index = 0;7 index = 0;
8 defer {result[index] = 'a'; index += 1;}8 defer {
9 errdefer {result[index] = 'b'; index += 1;}9 result[index] = 'a';
10 defer {result[index] = 'c'; index += 1;}10 index += 1;
11 }
12 errdefer {
13 result[index] = 'b';
14 index += 1;
15 }
16 defer {
17 result[index] = 'c';
18 index += 1;
19 }
11 return if (x) x else error.FalseNotAllowed;20 return if (x) x else error.FalseNotAllowed;
12}21}
1322
test/cases/enum.zig+541-59
...@@ -2,8 +2,13 @@ const assert = @import("std").debug.assert;...@@ -2,8 +2,13 @@ const assert = @import("std").debug.assert;
2const mem = @import("std").mem;2const mem = @import("std").mem;
33
4test "enum type" {4test "enum type" {
5 const foo1 = Foo{ .One = 13};5 const foo1 = Foo{ .One = 13 };
6 const foo2 = Foo{. Two = Point { .x = 1234, .y = 5678, }};6 const foo2 = Foo{
7 .Two = Point{
8 .x = 1234,
9 .y = 5678,
10 },
11 };
7 const bar = Bar.B;12 const bar = Bar.B;
813
9 assert(bar == Bar.B);14 assert(bar == Bar.B);
...@@ -41,26 +46,25 @@ const Bar = enum {...@@ -41,26 +46,25 @@ const Bar = enum {
41};46};
4247
43fn returnAnInt(x: i32) Foo {48fn returnAnInt(x: i32) Foo {
44 return Foo { .One = x };49 return Foo{ .One = x };
45}50}
4651
47
48test "constant enum with payload" {52test "constant enum with payload" {
49 var empty = AnEnumWithPayload {.Empty = {}};53 var empty = AnEnumWithPayload{ .Empty = {} };
50 var full = AnEnumWithPayload {.Full = 13};54 var full = AnEnumWithPayload{ .Full = 13 };
51 shouldBeEmpty(empty);55 shouldBeEmpty(empty);
52 shouldBeNotEmpty(full);56 shouldBeNotEmpty(full);
53}57}
5458
55fn shouldBeEmpty(x: &const AnEnumWithPayload) void {59fn shouldBeEmpty(x: &const AnEnumWithPayload) void {
56 switch (*x) {60 switch (x.*) {
57 AnEnumWithPayload.Empty => {},61 AnEnumWithPayload.Empty => {},
58 else => unreachable,62 else => unreachable,
59 }63 }
60}64}
6165
62fn shouldBeNotEmpty(x: &const AnEnumWithPayload) void {66fn shouldBeNotEmpty(x: &const AnEnumWithPayload) void {
63 switch (*x) {67 switch (x.*) {
64 AnEnumWithPayload.Empty => unreachable,68 AnEnumWithPayload.Empty => unreachable,
65 else => {},69 else => {},
66 }70 }
...@@ -71,8 +75,6 @@ const AnEnumWithPayload = union(enum) {...@@ -71,8 +75,6 @@ const AnEnumWithPayload = union(enum) {
71 Full: i32,75 Full: i32,
72};76};
7377
74
75
76const Number = enum {78const Number = enum {
77 Zero,79 Zero,
78 One,80 One,
...@@ -93,7 +95,6 @@ fn shouldEqual(n: Number, expected: u3) void {...@@ -93,7 +95,6 @@ fn shouldEqual(n: Number, expected: u3) void {
93 assert(u3(n) == expected);95 assert(u3(n) == expected);
94}96}
9597
96
97test "int to enum" {98test "int to enum" {
98 testIntToEnumEval(3);99 testIntToEnumEval(3);
99}100}
...@@ -108,7 +109,6 @@ const IntToEnumNumber = enum {...@@ -108,7 +109,6 @@ const IntToEnumNumber = enum {
108 Four,109 Four,
109};110};
110111
111
112test "@tagName" {112test "@tagName" {
113 assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));113 assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
114 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));114 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
...@@ -124,7 +124,6 @@ const BareNumber = enum {...@@ -124,7 +124,6 @@ const BareNumber = enum {
124 Three,124 Three,
125};125};
126126
127
128test "enum alignment" {127test "enum alignment" {
129 comptime {128 comptime {
130 assert(@alignOf(AlignTestEnum) >= @alignOf([9]u8));129 assert(@alignOf(AlignTestEnum) >= @alignOf([9]u8));
...@@ -137,47 +136,529 @@ const AlignTestEnum = union(enum) {...@@ -137,47 +136,529 @@ const AlignTestEnum = union(enum) {
137 B: u64,136 B: u64,
138};137};
139138
140const ValueCount1 = enum { I0 };139const ValueCount1 = enum {
141const ValueCount2 = enum { I0, I1 };140 I0,
141};
142const ValueCount2 = enum {
143 I0,
144 I1,
145};
142const ValueCount256 = enum {146const ValueCount256 = enum {
143 I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15,147 I0,
144 I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31,148 I1,
145 I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47,149 I2,
146 I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63,150 I3,
147 I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79,151 I4,
148 I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95,152 I5,
149 I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109,153 I6,
150 I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123,154 I7,
151 I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137,155 I8,
152 I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151,156 I9,
153 I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165,157 I10,
154 I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179,158 I11,
155 I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193,159 I12,
156 I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207,160 I13,
157 I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221,161 I14,
158 I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235,162 I15,
159 I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249,163 I16,
160 I250, I251, I252, I253, I254, I255164 I17,
165 I18,
166 I19,
167 I20,
168 I21,
169 I22,
170 I23,
171 I24,
172 I25,
173 I26,
174 I27,
175 I28,
176 I29,
177 I30,
178 I31,
179 I32,
180 I33,
181 I34,
182 I35,
183 I36,
184 I37,
185 I38,
186 I39,
187 I40,
188 I41,
189 I42,
190 I43,
191 I44,
192 I45,
193 I46,
194 I47,
195 I48,
196 I49,
197 I50,
198 I51,
199 I52,
200 I53,
201 I54,
202 I55,
203 I56,
204 I57,
205 I58,
206 I59,
207 I60,
208 I61,
209 I62,
210 I63,
211 I64,
212 I65,
213 I66,
214 I67,
215 I68,
216 I69,
217 I70,
218 I71,
219 I72,
220 I73,
221 I74,
222 I75,
223 I76,
224 I77,
225 I78,
226 I79,
227 I80,
228 I81,
229 I82,
230 I83,
231 I84,
232 I85,
233 I86,
234 I87,
235 I88,
236 I89,
237 I90,
238 I91,
239 I92,
240 I93,
241 I94,
242 I95,
243 I96,
244 I97,
245 I98,
246 I99,
247 I100,
248 I101,
249 I102,
250 I103,
251 I104,
252 I105,
253 I106,
254 I107,
255 I108,
256 I109,
257 I110,
258 I111,
259 I112,
260 I113,
261 I114,
262 I115,
263 I116,
264 I117,
265 I118,
266 I119,
267 I120,
268 I121,
269 I122,
270 I123,
271 I124,
272 I125,
273 I126,
274 I127,
275 I128,
276 I129,
277 I130,
278 I131,
279 I132,
280 I133,
281 I134,
282 I135,
283 I136,
284 I137,
285 I138,
286 I139,
287 I140,
288 I141,
289 I142,
290 I143,
291 I144,
292 I145,
293 I146,
294 I147,
295 I148,
296 I149,
297 I150,
298 I151,
299 I152,
300 I153,
301 I154,
302 I155,
303 I156,
304 I157,
305 I158,
306 I159,
307 I160,
308 I161,
309 I162,
310 I163,
311 I164,
312 I165,
313 I166,
314 I167,
315 I168,
316 I169,
317 I170,
318 I171,
319 I172,
320 I173,
321 I174,
322 I175,
323 I176,
324 I177,
325 I178,
326 I179,
327 I180,
328 I181,
329 I182,
330 I183,
331 I184,
332 I185,
333 I186,
334 I187,
335 I188,
336 I189,
337 I190,
338 I191,
339 I192,
340 I193,
341 I194,
342 I195,
343 I196,
344 I197,
345 I198,
346 I199,
347 I200,
348 I201,
349 I202,
350 I203,
351 I204,
352 I205,
353 I206,
354 I207,
355 I208,
356 I209,
357 I210,
358 I211,
359 I212,
360 I213,
361 I214,
362 I215,
363 I216,
364 I217,
365 I218,
366 I219,
367 I220,
368 I221,
369 I222,
370 I223,
371 I224,
372 I225,
373 I226,
374 I227,
375 I228,
376 I229,
377 I230,
378 I231,
379 I232,
380 I233,
381 I234,
382 I235,
383 I236,
384 I237,
385 I238,
386 I239,
387 I240,
388 I241,
389 I242,
390 I243,
391 I244,
392 I245,
393 I246,
394 I247,
395 I248,
396 I249,
397 I250,
398 I251,
399 I252,
400 I253,
401 I254,
402 I255,
161};403};
162const ValueCount257 = enum {404const ValueCount257 = enum {
163 I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15,405 I0,
164 I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31,406 I1,
165 I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47,407 I2,
166 I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63,408 I3,
167 I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79,409 I4,
168 I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95,410 I5,
169 I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109,411 I6,
170 I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123,412 I7,
171 I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137,413 I8,
172 I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151,414 I9,
173 I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165,415 I10,
174 I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179,416 I11,
175 I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193,417 I12,
176 I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207,418 I13,
177 I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221,419 I14,
178 I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235,420 I15,
179 I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249,421 I16,
180 I250, I251, I252, I253, I254, I255, I256422 I17,
423 I18,
424 I19,
425 I20,
426 I21,
427 I22,
428 I23,
429 I24,
430 I25,
431 I26,
432 I27,
433 I28,
434 I29,
435 I30,
436 I31,
437 I32,
438 I33,
439 I34,
440 I35,
441 I36,
442 I37,
443 I38,
444 I39,
445 I40,
446 I41,
447 I42,
448 I43,
449 I44,
450 I45,
451 I46,
452 I47,
453 I48,
454 I49,
455 I50,
456 I51,
457 I52,
458 I53,
459 I54,
460 I55,
461 I56,
462 I57,
463 I58,
464 I59,
465 I60,
466 I61,
467 I62,
468 I63,
469 I64,
470 I65,
471 I66,
472 I67,
473 I68,
474 I69,
475 I70,
476 I71,
477 I72,
478 I73,
479 I74,
480 I75,
481 I76,
482 I77,
483 I78,
484 I79,
485 I80,
486 I81,
487 I82,
488 I83,
489 I84,
490 I85,
491 I86,
492 I87,
493 I88,
494 I89,
495 I90,
496 I91,
497 I92,
498 I93,
499 I94,
500 I95,
501 I96,
502 I97,
503 I98,
504 I99,
505 I100,
506 I101,
507 I102,
508 I103,
509 I104,
510 I105,
511 I106,
512 I107,
513 I108,
514 I109,
515 I110,
516 I111,
517 I112,
518 I113,
519 I114,
520 I115,
521 I116,
522 I117,
523 I118,
524 I119,
525 I120,
526 I121,
527 I122,
528 I123,
529 I124,
530 I125,
531 I126,
532 I127,
533 I128,
534 I129,
535 I130,
536 I131,
537 I132,
538 I133,
539 I134,
540 I135,
541 I136,
542 I137,
543 I138,
544 I139,
545 I140,
546 I141,
547 I142,
548 I143,
549 I144,
550 I145,
551 I146,
552 I147,
553 I148,
554 I149,
555 I150,
556 I151,
557 I152,
558 I153,
559 I154,
560 I155,
561 I156,
562 I157,
563 I158,
564 I159,
565 I160,
566 I161,
567 I162,
568 I163,
569 I164,
570 I165,
571 I166,
572 I167,
573 I168,
574 I169,
575 I170,
576 I171,
577 I172,
578 I173,
579 I174,
580 I175,
581 I176,
582 I177,
583 I178,
584 I179,
585 I180,
586 I181,
587 I182,
588 I183,
589 I184,
590 I185,
591 I186,
592 I187,
593 I188,
594 I189,
595 I190,
596 I191,
597 I192,
598 I193,
599 I194,
600 I195,
601 I196,
602 I197,
603 I198,
604 I199,
605 I200,
606 I201,
607 I202,
608 I203,
609 I204,
610 I205,
611 I206,
612 I207,
613 I208,
614 I209,
615 I210,
616 I211,
617 I212,
618 I213,
619 I214,
620 I215,
621 I216,
622 I217,
623 I218,
624 I219,
625 I220,
626 I221,
627 I222,
628 I223,
629 I224,
630 I225,
631 I226,
632 I227,
633 I228,
634 I229,
635 I230,
636 I231,
637 I232,
638 I233,
639 I234,
640 I235,
641 I236,
642 I237,
643 I238,
644 I239,
645 I240,
646 I241,
647 I242,
648 I243,
649 I244,
650 I245,
651 I246,
652 I247,
653 I248,
654 I249,
655 I250,
656 I251,
657 I252,
658 I253,
659 I254,
660 I255,
661 I256,
181};662};
182663
183test "enum sizes" {664test "enum sizes" {
...@@ -189,11 +670,11 @@ test "enum sizes" {...@@ -189,11 +670,11 @@ test "enum sizes" {
189 }670 }
190}671}
191672
192const Small2 = enum (u2) {673const Small2 = enum(u2) {
193 One,674 One,
194 Two,675 Two,
195};676};
196const Small = enum (u2) {677const Small = enum(u2) {
197 One,678 One,
198 Two,679 Two,
199 Three,680 Three,
...@@ -213,8 +694,7 @@ test "set enum tag type" {...@@ -213,8 +694,7 @@ test "set enum tag type" {
213 }694 }
214}695}
215696
216697const A = enum(u3) {
217const A = enum (u3) {
218 One,698 One,
219 Two,699 Two,
220 Three,700 Three,
...@@ -225,7 +705,7 @@ const A = enum (u3) {...@@ -225,7 +705,7 @@ const A = enum (u3) {
225 Four2,705 Four2,
226};706};
227707
228const B = enum (u3) {708const B = enum(u3) {
229 One3,709 One3,
230 Two3,710 Two3,
231 Three3,711 Three3,
...@@ -236,7 +716,7 @@ const B = enum (u3) {...@@ -236,7 +716,7 @@ const B = enum (u3) {
236 Four23,716 Four23,
237};717};
238718
239const C = enum (u2) {719const C = enum(u2) {
240 One4,720 One4,
241 Two4,721 Two4,
242 Three4,722 Three4,
...@@ -249,7 +729,7 @@ const BitFieldOfEnums = packed struct {...@@ -249,7 +729,7 @@ const BitFieldOfEnums = packed struct {
249 c: C,729 c: C,
250};730};
251731
252const bit_field_1 = BitFieldOfEnums {732const bit_field_1 = BitFieldOfEnums{
253 .a = A.Two,733 .a = A.Two,
254 .b = B.Three3,734 .b = B.Three3,
255 .c = C.Four4,735 .c = C.Four4,
...@@ -389,7 +869,9 @@ test "enum with tag values don't require parens" {...@@ -389,7 +869,9 @@ test "enum with tag values don't require parens" {
389}869}
390870
391test "enum with 1 field but explicit tag type should still have the tag type" {871test "enum with 1 field but explicit tag type should still have the tag type" {
392 const Enum = enum(u8) { B = 2 };872 const Enum = enum(u8) {
873 B = 2,
874 };
393 comptime @import("std").debug.assert(@sizeOf(Enum) == @sizeOf(u8));875 comptime @import("std").debug.assert(@sizeOf(Enum) == @sizeOf(u8));
394}876}
395877
test/cases/enum_with_members.zig+3-3
...@@ -7,7 +7,7 @@ const ET = union(enum) {...@@ -7,7 +7,7 @@ const ET = union(enum) {
7 UINT: u32,7 UINT: u32,
88
9 pub fn print(a: &const ET, buf: []u8) error!usize {9 pub fn print(a: &const ET, buf: []u8) error!usize {
10 return switch (*a) {10 return switch (a.*) {
11 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),11 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
12 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),12 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
13 };13 };
...@@ -15,8 +15,8 @@ const ET = union(enum) {...@@ -15,8 +15,8 @@ const ET = union(enum) {
15};15};
1616
17test "enum with members" {17test "enum with members" {
18 const a = ET { .SINT = -42 };18 const a = ET{ .SINT = -42 };
19 const b = ET { .UINT = 42 };19 const b = ET{ .UINT = 42 };
20 var buf: [20]u8 = undefined;20 var buf: [20]u8 = undefined;
2121
22 assert((a.print(buf[0..]) catch unreachable) == 3);22 assert((a.print(buf[0..]) catch unreachable) == 3);
test/cases/error.zig+27-25
...@@ -30,14 +30,12 @@ test "@errorName" {...@@ -30,14 +30,12 @@ test "@errorName" {
30 assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));30 assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
31}31}
3232
33
34test "error values" {33test "error values" {
35 const a = i32(error.err1);34 const a = i32(error.err1);
36 const b = i32(error.err2);35 const b = i32(error.err2);
37 assert(a != b);36 assert(a != b);
38}37}
3938
40
41test "redefinition of error values allowed" {39test "redefinition of error values allowed" {
42 shouldBeNotEqual(error.AnError, error.SecondError);40 shouldBeNotEqual(error.AnError, error.SecondError);
43}41}
...@@ -45,7 +43,6 @@ fn shouldBeNotEqual(a: error, b: error) void {...@@ -45,7 +43,6 @@ fn shouldBeNotEqual(a: error, b: error) void {
45 if (a == b) unreachable;43 if (a == b) unreachable;
46}44}
4745
48
49test "error binary operator" {46test "error binary operator" {
50 const a = errBinaryOperatorG(true) catch 3;47 const a = errBinaryOperatorG(true) catch 3;
51 const b = errBinaryOperatorG(false) catch 3;48 const b = errBinaryOperatorG(false) catch 3;
...@@ -56,20 +53,20 @@ fn errBinaryOperatorG(x: bool) error!isize {...@@ -56,20 +53,20 @@ fn errBinaryOperatorG(x: bool) error!isize {
56 return if (x) error.ItBroke else isize(10);53 return if (x) error.ItBroke else isize(10);
57}54}
5855
59
60test "unwrap simple value from error" {56test "unwrap simple value from error" {
61 const i = unwrapSimpleValueFromErrorDo() catch unreachable;57 const i = unwrapSimpleValueFromErrorDo() catch unreachable;
62 assert(i == 13);58 assert(i == 13);
63}59}
64fn unwrapSimpleValueFromErrorDo() error!isize { return 13; }60fn unwrapSimpleValueFromErrorDo() error!isize {
6561 return 13;
62}
6663
67test "error return in assignment" {64test "error return in assignment" {
68 doErrReturnInAssignment() catch unreachable;65 doErrReturnInAssignment() catch unreachable;
69}66}
7067
71fn doErrReturnInAssignment() error!void {68fn doErrReturnInAssignment() error!void {
72 var x : i32 = undefined;69 var x: i32 = undefined;
73 x = try makeANonErr();70 x = try makeANonErr();
74}71}
7572
...@@ -95,7 +92,10 @@ test "error set type " {...@@ -95,7 +92,10 @@ test "error set type " {
95 comptime testErrorSetType();92 comptime testErrorSetType();
96}93}
9794
98const MyErrSet = error {OutOfMemory, FileNotFound};95const MyErrSet = error{
96 OutOfMemory,
97 FileNotFound,
98};
9999
100fn testErrorSetType() void {100fn testErrorSetType() void {
101 assert(@memberCount(MyErrSet) == 2);101 assert(@memberCount(MyErrSet) == 2);
...@@ -109,14 +109,19 @@ fn testErrorSetType() void {...@@ -109,14 +109,19 @@ fn testErrorSetType() void {
109 }109 }
110}110}
111111
112
113test "explicit error set cast" {112test "explicit error set cast" {
114 testExplicitErrorSetCast(Set1.A);113 testExplicitErrorSetCast(Set1.A);
115 comptime testExplicitErrorSetCast(Set1.A);114 comptime testExplicitErrorSetCast(Set1.A);
116}115}
117116
118const Set1 = error{A, B};117const Set1 = error{
119const Set2 = error{A, C};118 A,
119 B,
120};
121const Set2 = error{
122 A,
123 C,
124};
120125
121fn testExplicitErrorSetCast(set1: Set1) void {126fn testExplicitErrorSetCast(set1: Set1) void {
122 var x = Set2(set1);127 var x = Set2(set1);
...@@ -129,7 +134,7 @@ test "comptime test error for empty error set" {...@@ -129,7 +134,7 @@ test "comptime test error for empty error set" {
129 comptime testComptimeTestErrorEmptySet(1234);134 comptime testComptimeTestErrorEmptySet(1234);
130}135}
131136
132const EmptyErrorSet = error {};137const EmptyErrorSet = error{};
133138
134fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void {139fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void {
135 if (x) |v| assert(v == 1234) else |err| @compileError("bad");140 if (x) |v| assert(v == 1234) else |err| @compileError("bad");
...@@ -145,7 +150,10 @@ test "comptime err to int of error set with only 1 possible value" {...@@ -145,7 +150,10 @@ test "comptime err to int of error set with only 1 possible value" {
145 testErrToIntWithOnePossibleValue(error.A, u32(error.A));150 testErrToIntWithOnePossibleValue(error.A, u32(error.A));
146 comptime testErrToIntWithOnePossibleValue(error.A, u32(error.A));151 comptime testErrToIntWithOnePossibleValue(error.A, u32(error.A));
147}152}
148fn testErrToIntWithOnePossibleValue(x: error{A}, comptime value: u32) void {153fn testErrToIntWithOnePossibleValue(
154 x: error{A},
155 comptime value: u32,
156) void {
149 if (u32(x) != value) {157 if (u32(x) != value) {
150 @compileError("bad");158 @compileError("bad");
151 }159 }
...@@ -176,7 +184,6 @@ fn quux_1() !i32 {...@@ -176,7 +184,6 @@ fn quux_1() !i32 {
176 return error.C;184 return error.C;
177}185}
178186
179
180test "error: fn returning empty error set can be passed as fn returning any error" {187test "error: fn returning empty error set can be passed as fn returning any error" {
181 entry();188 entry();
182 comptime entry();189 comptime entry();
...@@ -186,12 +193,11 @@ fn entry() void {...@@ -186,12 +193,11 @@ fn entry() void {
186 foo2(bar2);193 foo2(bar2);
187}194}
188195
189fn foo2(f: fn()error!void) void {196fn foo2(f: fn() error!void) void {
190 const x = f();197 const x = f();
191}198}
192199
193fn bar2() (error{}!void) { }200fn bar2() (error{}!void) {}
194
195201
196test "error: Zero sized error set returned with value payload crash" {202test "error: Zero sized error set returned with value payload crash" {
197 _ = foo3(0);203 _ = foo3(0);
...@@ -203,7 +209,6 @@ fn foo3(b: usize) Error!usize {...@@ -203,7 +209,6 @@ fn foo3(b: usize) Error!usize {
203 return b;209 return b;
204}210}
205211
206
207test "error: Infer error set from literals" {212test "error: Infer error set from literals" {
208 _ = nullLiteral("n") catch |err| handleErrors(err);213 _ = nullLiteral("n") catch |err| handleErrors(err);
209 _ = floatLiteral("n") catch |err| handleErrors(err);214 _ = floatLiteral("n") catch |err| handleErrors(err);
...@@ -215,29 +220,26 @@ test "error: Infer error set from literals" {...@@ -215,29 +220,26 @@ test "error: Infer error set from literals" {
215220
216fn handleErrors(err: var) noreturn {221fn handleErrors(err: var) noreturn {
217 switch (err) {222 switch (err) {
218 error.T => {}223 error.T => {},
219 }224 }
220225
221 unreachable;226 unreachable;
222}227}
223228
224fn nullLiteral(str: []const u8) !?i64 {229fn nullLiteral(str: []const u8) !?i64 {
225 if (str[0] == 'n')230 if (str[0] == 'n') return null;
226 return null;
227231
228 return error.T;232 return error.T;
229}233}
230234
231fn floatLiteral(str: []const u8) !?f64 {235fn floatLiteral(str: []const u8) !?f64 {
232 if (str[0] == 'n')236 if (str[0] == 'n') return 1.0;
233 return 1.0;
234237
235 return error.T;238 return error.T;
236}239}
237240
238fn intLiteral(str: []const u8) !?i64 {241fn intLiteral(str: []const u8) !?i64 {
239 if (str[0] == 'n')242 if (str[0] == 'n') return 1;
240 return 1;
241243
242 return error.T;244 return error.T;
243}245}
test/cases/eval.zig+98-58
...@@ -11,8 +11,6 @@ fn fibonacci(x: i32) i32 {...@@ -11,8 +11,6 @@ fn fibonacci(x: i32) i32 {
11 return fibonacci(x - 1) + fibonacci(x - 2);11 return fibonacci(x - 1) + fibonacci(x - 2);
12}12}
1313
14
15
16fn unwrapAndAddOne(blah: ?i32) i32 {14fn unwrapAndAddOne(blah: ?i32) i32 {
17 return ??blah + 1;15 return ??blah + 1;
18}16}
...@@ -40,13 +38,13 @@ test "inline variable gets result of const if" {...@@ -40,13 +38,13 @@ test "inline variable gets result of const if" {
40 assert(gimme1or2(false) == 2);38 assert(gimme1or2(false) == 2);
41}39}
4240
43
44test "static function evaluation" {41test "static function evaluation" {
45 assert(statically_added_number == 3);42 assert(statically_added_number == 3);
46}43}
47const statically_added_number = staticAdd(1, 2);44const statically_added_number = staticAdd(1, 2);
48fn staticAdd(a: i32, b: i32) i32 { return a + b; }45fn staticAdd(a: i32, b: i32) i32 {
4946 return a + b;
47}
5048
51test "const expr eval on single expr blocks" {49test "const expr eval on single expr blocks" {
52 assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);50 assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
...@@ -64,9 +62,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {...@@ -64,9 +62,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
64 return result;62 return result;
65}63}
6664
67
68
69
70test "statically initialized list" {65test "statically initialized list" {
71 assert(static_point_list[0].x == 1);66 assert(static_point_list[0].x == 1);
72 assert(static_point_list[0].y == 2);67 assert(static_point_list[0].y == 2);
...@@ -77,15 +72,17 @@ const Point = struct {...@@ -77,15 +72,17 @@ const Point = struct {
77 x: i32,72 x: i32,
78 y: i32,73 y: i32,
79};74};
80const static_point_list = []Point { makePoint(1, 2), makePoint(3, 4) };75const static_point_list = []Point{
76 makePoint(1, 2),
77 makePoint(3, 4),
78};
81fn makePoint(x: i32, y: i32) Point {79fn makePoint(x: i32, y: i32) Point {
82 return Point {80 return Point{
83 .x = x,81 .x = x,
84 .y = y,82 .y = y,
85 };83 };
86}84}
8785
88
89test "static eval list init" {86test "static eval list init" {
90 assert(static_vec3.data[2] == 1.0);87 assert(static_vec3.data[2] == 1.0);
91 assert(vec3(0.0, 0.0, 3.0).data[2] == 3.0);88 assert(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
...@@ -95,18 +92,18 @@ pub const Vec3 = struct {...@@ -95,18 +92,18 @@ pub const Vec3 = struct {
95 data: [3]f32,92 data: [3]f32,
96};93};
97pub fn vec3(x: f32, y: f32, z: f32) Vec3 {94pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
98 return Vec3 {95 return Vec3{ .data = []f32{
99 .data = []f32 { x, y, z, },96 x,
100 };97 y,
98 z,
99 } };
101}100}
102101
103
104test "constant expressions" {102test "constant expressions" {
105 var array : [array_size]u8 = undefined;103 var array: [array_size]u8 = undefined;
106 assert(@sizeOf(@typeOf(array)) == 20);104 assert(@sizeOf(@typeOf(array)) == 20);
107}105}
108const array_size : u8 = 20;106const array_size: u8 = 20;
109
110107
111test "constant struct with negation" {108test "constant struct with negation" {
112 assert(vertices[0].x == -0.6);109 assert(vertices[0].x == -0.6);
...@@ -118,13 +115,30 @@ const Vertex = struct {...@@ -118,13 +115,30 @@ const Vertex = struct {
118 g: f32,115 g: f32,
119 b: f32,116 b: f32,
120};117};
121const vertices = []Vertex {118const vertices = []Vertex{
122 Vertex { .x = -0.6, .y = -0.4, .r = 1.0, .g = 0.0, .b = 0.0 },119 Vertex{
123 Vertex { .x = 0.6, .y = -0.4, .r = 0.0, .g = 1.0, .b = 0.0 },120 .x = -0.6,
124 Vertex { .x = 0.0, .y = 0.6, .r = 0.0, .g = 0.0, .b = 1.0 },121 .y = -0.4,
122 .r = 1.0,
123 .g = 0.0,
124 .b = 0.0,
125 },
126 Vertex{
127 .x = 0.6,
128 .y = -0.4,
129 .r = 0.0,
130 .g = 1.0,
131 .b = 0.0,
132 },
133 Vertex{
134 .x = 0.0,
135 .y = 0.6,
136 .r = 0.0,
137 .g = 0.0,
138 .b = 1.0,
139 },
125};140};
126141
127
128test "statically initialized struct" {142test "statically initialized struct" {
129 st_init_str_foo.x += 1;143 st_init_str_foo.x += 1;
130 assert(st_init_str_foo.x == 14);144 assert(st_init_str_foo.x == 14);
...@@ -133,15 +147,21 @@ const StInitStrFoo = struct {...@@ -133,15 +147,21 @@ const StInitStrFoo = struct {
133 x: i32,147 x: i32,
134 y: bool,148 y: bool,
135};149};
136var st_init_str_foo = StInitStrFoo { .x = 13, .y = true, };150var st_init_str_foo = StInitStrFoo{
137151 .x = 13,
152 .y = true,
153};
138154
139test "statically initalized array literal" {155test "statically initalized array literal" {
140 const y : [4]u8 = st_init_arr_lit_x;156 const y: [4]u8 = st_init_arr_lit_x;
141 assert(y[3] == 4);157 assert(y[3] == 4);
142}158}
143const st_init_arr_lit_x = []u8{1,2,3,4};159const st_init_arr_lit_x = []u8{
144160 1,
161 2,
162 3,
163 4,
164};
145165
146test "const slice" {166test "const slice" {
147 comptime {167 comptime {
...@@ -199,13 +219,28 @@ const CmdFn = struct {...@@ -199,13 +219,28 @@ const CmdFn = struct {
199};219};
200220
201const cmd_fns = []CmdFn{221const cmd_fns = []CmdFn{
202 CmdFn {.name = "one", .func = one},222 CmdFn{
203 CmdFn {.name = "two", .func = two},223 .name = "one",
204 CmdFn {.name = "three", .func = three},224 .func = one,
225 },
226 CmdFn{
227 .name = "two",
228 .func = two,
229 },
230 CmdFn{
231 .name = "three",
232 .func = three,
233 },
205};234};
206fn one(value: i32) i32 { return value + 1; }235fn one(value: i32) i32 {
207fn two(value: i32) i32 { return value + 2; }236 return value + 1;
208fn three(value: i32) i32 { return value + 3; }237}
238fn two(value: i32) i32 {
239 return value + 2;
240}
241fn three(value: i32) i32 {
242 return value + 3;
243}
209244
210fn performFn(comptime prefix_char: u8, start_value: i32) i32 {245fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
211 var result: i32 = start_value;246 var result: i32 = start_value;
...@@ -229,7 +264,7 @@ test "eval @setRuntimeSafety at compile-time" {...@@ -229,7 +264,7 @@ test "eval @setRuntimeSafety at compile-time" {
229 assert(result == 1234);264 assert(result == 1234);
230}265}
231266
232fn fnWithSetRuntimeSafety() i32{267fn fnWithSetRuntimeSafety() i32 {
233 @setRuntimeSafety(true);268 @setRuntimeSafety(true);
234 return 1234;269 return 1234;
235}270}
...@@ -244,7 +279,6 @@ fn fnWithFloatMode() f32 {...@@ -244,7 +279,6 @@ fn fnWithFloatMode() f32 {
244 return 1234.0;279 return 1234.0;
245}280}
246281
247
248const SimpleStruct = struct {282const SimpleStruct = struct {
249 field: i32,283 field: i32,
250284
...@@ -253,7 +287,7 @@ const SimpleStruct = struct {...@@ -253,7 +287,7 @@ const SimpleStruct = struct {
253 }287 }
254};288};
255289
256var simple_struct = SimpleStruct{ .field = 1234, };290var simple_struct = SimpleStruct{ .field = 1234 };
257291
258const bound_fn = simple_struct.method;292const bound_fn = simple_struct.method;
259293
...@@ -261,8 +295,6 @@ test "call method on bound fn referring to var instance" {...@@ -261,8 +295,6 @@ test "call method on bound fn referring to var instance" {
261 assert(bound_fn() == 1237);295 assert(bound_fn() == 1237);
262}296}
263297
264
265
266test "ptr to local array argument at comptime" {298test "ptr to local array argument at comptime" {
267 comptime {299 comptime {
268 var bytes: [10]u8 = undefined;300 var bytes: [10]u8 = undefined;
...@@ -277,7 +309,6 @@ fn modifySomeBytes(bytes: []u8) void {...@@ -277,7 +309,6 @@ fn modifySomeBytes(bytes: []u8) void {
277 bytes[9] = 'b';309 bytes[9] = 'b';
278}310}
279311
280
281test "comparisons 0 <= uint and 0 > uint should be comptime" {312test "comparisons 0 <= uint and 0 > uint should be comptime" {
282 testCompTimeUIntComparisons(1234);313 testCompTimeUIntComparisons(1234);
283}314}
...@@ -296,8 +327,6 @@ fn testCompTimeUIntComparisons(x: u32) void {...@@ -296,8 +327,6 @@ fn testCompTimeUIntComparisons(x: u32) void {
296 }327 }
297}328}
298329
299
300
301test "const ptr to variable data changes at runtime" {330test "const ptr to variable data changes at runtime" {
302 assert(foo_ref.name[0] == 'a');331 assert(foo_ref.name[0] == 'a');
303 foo_ref.name = "b";332 foo_ref.name = "b";
...@@ -308,11 +337,9 @@ const Foo = struct {...@@ -308,11 +337,9 @@ const Foo = struct {
308 name: []const u8,337 name: []const u8,
309};338};
310339
311var foo_contents = Foo { .name = "a", };340var foo_contents = Foo{ .name = "a" };
312const foo_ref = &foo_contents;341const foo_ref = &foo_contents;
313342
314
315
316test "create global array with for loop" {343test "create global array with for loop" {
317 assert(global_array[5] == 5 * 5);344 assert(global_array[5] == 5 * 5);
318 assert(global_array[9] == 9 * 9);345 assert(global_array[9] == 9 * 9);
...@@ -321,7 +348,7 @@ test "create global array with for loop" {...@@ -321,7 +348,7 @@ test "create global array with for loop" {
321const global_array = x: {348const global_array = x: {
322 var result: [10]usize = undefined;349 var result: [10]usize = undefined;
323 for (result) |*item, index| {350 for (result) |*item, index| {
324 *item = index * index;351 item.* = index * index;
325 }352 }
326 break :x result;353 break :x result;
327};354};
...@@ -379,7 +406,7 @@ test "f128 at compile time is lossy" {...@@ -379,7 +406,7 @@ test "f128 at compile time is lossy" {
379406
380pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {407pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
381 return struct {408 return struct {
382 pub const Node = struct { };409 pub const Node = struct {};
383 };410 };
384}411}
385412
...@@ -401,10 +428,10 @@ fn copyWithPartialInline(s: []u32, b: []u8) void {...@@ -401,10 +428,10 @@ fn copyWithPartialInline(s: []u32, b: []u8) void {
401 comptime var i: usize = 0;428 comptime var i: usize = 0;
402 inline while (i < 4) : (i += 1) {429 inline while (i < 4) : (i += 1) {
403 s[i] = 0;430 s[i] = 0;
404 s[i] |= u32(b[i*4+0]) << 24;431 s[i] |= u32(b[i * 4 + 0]) << 24;
405 s[i] |= u32(b[i*4+1]) << 16;432 s[i] |= u32(b[i * 4 + 1]) << 16;
406 s[i] |= u32(b[i*4+2]) << 8;433 s[i] |= u32(b[i * 4 + 2]) << 8;
407 s[i] |= u32(b[i*4+3]) << 0;434 s[i] |= u32(b[i * 4 + 3]) << 0;
408 }435 }
409}436}
410437
...@@ -413,7 +440,7 @@ test "binary math operator in partially inlined function" {...@@ -413,7 +440,7 @@ test "binary math operator in partially inlined function" {
413 var b: [16]u8 = undefined;440 var b: [16]u8 = undefined;
414441
415 for (b) |*r, i|442 for (b) |*r, i|
416 *r = u8(i + 1);443 r.* = u8(i + 1);
417444
418 copyWithPartialInline(s[0..], b[0..]);445 copyWithPartialInline(s[0..], b[0..]);
419 assert(s[0] == 0x1020304);446 assert(s[0] == 0x1020304);
...@@ -422,7 +449,6 @@ test "binary math operator in partially inlined function" {...@@ -422,7 +449,6 @@ test "binary math operator in partially inlined function" {
422 assert(s[3] == 0xd0e0f10);449 assert(s[3] == 0xd0e0f10);
423}450}
424451
425
426test "comptime function with the same args is memoized" {452test "comptime function with the same args is memoized" {
427 comptime {453 comptime {
428 assert(MakeType(i32) == MakeType(i32));454 assert(MakeType(i32) == MakeType(i32));
...@@ -447,12 +473,12 @@ test "comptime function with mutable pointer is not memoized" {...@@ -447,12 +473,12 @@ test "comptime function with mutable pointer is not memoized" {
447}473}
448474
449fn increment(value: &i32) void {475fn increment(value: &i32) void {
450 *value += 1;476 value.* += 1;
451}477}
452478
453fn generateTable(comptime T: type) [1010]T {479fn generateTable(comptime T: type) [1010]T {
454 var res : [1010]T = undefined;480 var res: [1010]T = undefined;
455 var i : usize = 0;481 var i: usize = 0;
456 while (i < 1010) : (i += 1) {482 while (i < 1010) : (i += 1) {
457 res[i] = T(i);483 res[i] = T(i);
458 }484 }
...@@ -496,9 +522,8 @@ const SingleFieldStruct = struct {...@@ -496,9 +522,8 @@ const SingleFieldStruct = struct {
496 }522 }
497};523};
498test "const ptr to comptime mutable data is not memoized" {524test "const ptr to comptime mutable data is not memoized" {
499
500 comptime {525 comptime {
501 var foo = SingleFieldStruct {.x = 1};526 var foo = SingleFieldStruct{ .x = 1 };
502 assert(foo.read_x() == 1);527 assert(foo.read_x() == 1);
503 foo.x = 2;528 foo.x = 2;
504 assert(foo.read_x() == 2);529 assert(foo.read_x() == 2);
...@@ -536,3 +561,18 @@ test "runtime 128 bit integer division" {...@@ -536,3 +561,18 @@ test "runtime 128 bit integer division" {
536 var c = a / b;561 var c = a / b;
537 assert(c == 15231399999);562 assert(c == 15231399999);
538}563}
564
565pub const Info = struct {
566 version: u8,
567};
568
569pub const diamond_info = Info{ .version = 0 };
570
571test "comptime modification of const struct field" {
572 comptime {
573 var res = diamond_info;
574 res.version = 1;
575 assert(diamond_info.version == 0);
576 assert(res.version == 1);
577 }
578}
test/cases/field_parent_ptr.zig+1-1
...@@ -17,7 +17,7 @@ const Foo = struct {...@@ -17,7 +17,7 @@ const Foo = struct {
17 d: i32,17 d: i32,
18};18};
1919
20const foo = Foo {20const foo = Foo{
21 .a = true,21 .a = true,
22 .b = 0.123,22 .b = 0.123,
23 .c = 1234,23 .c = 1234,
test/cases/fn.zig+26-18
...@@ -7,7 +7,6 @@ fn testParamsAdd(a: i32, b: i32) i32 {...@@ -7,7 +7,6 @@ fn testParamsAdd(a: i32, b: i32) i32 {
7 return a + b;7 return a + b;
8}8}
99
10
11test "local variables" {10test "local variables" {
12 testLocVars(2);11 testLocVars(2);
13}12}
...@@ -16,7 +15,6 @@ fn testLocVars(b: i32) void {...@@ -16,7 +15,6 @@ fn testLocVars(b: i32) void {
16 if (a + b != 3) unreachable;15 if (a + b != 3) unreachable;
17}16}
1817
19
20test "void parameters" {18test "void parameters" {
21 voidFun(1, void{}, 2, {});19 voidFun(1, void{}, 2, {});
22}20}
...@@ -27,9 +25,8 @@ fn voidFun(a: i32, b: void, c: i32, d: void) void {...@@ -27,9 +25,8 @@ fn voidFun(a: i32, b: void, c: i32, d: void) void {
27 return vv;25 return vv;
28}26}
2927
30
31test "mutable local variables" {28test "mutable local variables" {
32 var zero : i32 = 0;29 var zero: i32 = 0;
33 assert(zero == 0);30 assert(zero == 0);
3431
35 var i = i32(0);32 var i = i32(0);
...@@ -41,7 +38,7 @@ test "mutable local variables" {...@@ -41,7 +38,7 @@ test "mutable local variables" {
4138
42test "separate block scopes" {39test "separate block scopes" {
43 {40 {
44 const no_conflict : i32 = 5;41 const no_conflict: i32 = 5;
45 assert(no_conflict == 5);42 assert(no_conflict == 5);
46 }43 }
4744
...@@ -56,8 +53,7 @@ test "call function with empty string" {...@@ -56,8 +53,7 @@ test "call function with empty string" {
56 acceptsString("");53 acceptsString("");
57}54}
5855
59fn acceptsString(foo: []u8) void { }56fn acceptsString(foo: []u8) void {}
60
6157
62fn @"weird function name"() i32 {58fn @"weird function name"() i32 {
63 return 1234;59 return 1234;
...@@ -70,31 +66,43 @@ test "implicit cast function unreachable return" {...@@ -70,31 +66,43 @@ test "implicit cast function unreachable return" {
70 wantsFnWithVoid(fnWithUnreachable);66 wantsFnWithVoid(fnWithUnreachable);
71}67}
7268
73fn wantsFnWithVoid(f: fn() void) void { }69fn wantsFnWithVoid(f: fn() void) void {}
7470
75fn fnWithUnreachable() noreturn {71fn fnWithUnreachable() noreturn {
76 unreachable;72 unreachable;
77}73}
7874
79
80test "function pointers" {75test "function pointers" {
81 const fns = []@typeOf(fn1) { fn1, fn2, fn3, fn4, };76 const fns = []@typeOf(fn1){
77 fn1,
78 fn2,
79 fn3,
80 fn4,
81 };
82 for (fns) |f, i| {82 for (fns) |f, i| {
83 assert(f() == u32(i) + 5);83 assert(f() == u32(i) + 5);
84 }84 }
85}85}
86fn fn1() u32 {return 5;}86fn fn1() u32 {
87fn fn2() u32 {return 6;}87 return 5;
88fn fn3() u32 {return 7;}88}
89fn fn4() u32 {return 8;}89fn fn2() u32 {
9090 return 6;
91}
92fn fn3() u32 {
93 return 7;
94}
95fn fn4() u32 {
96 return 8;
97}
9198
92test "inline function call" {99test "inline function call" {
93 assert(@inlineCall(add, 3, 9) == 12);100 assert(@inlineCall(add, 3, 9) == 12);
94}101}
95102
96fn add(a: i32, b: i32) i32 { return a + b; }103fn add(a: i32, b: i32) i32 {
97104 return a + b;
105}
98106
99test "number literal as an argument" {107test "number literal as an argument" {
100 numberLiteralArg(3);108 numberLiteralArg(3);
...@@ -110,4 +118,4 @@ test "assign inline fn to const variable" {...@@ -110,4 +118,4 @@ test "assign inline fn to const variable" {
110 a();118 a();
111}119}
112120
113inline fn inlineFn() void { }121inline fn inlineFn() void {}
test/cases/fn_in_struct_in_comptime.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
22
3fn get_foo() fn(&u8)usize {3fn get_foo() fn(&u8) usize {
4 comptime {4 comptime {
5 return struct {5 return struct {
6 fn func(ptr: &u8) usize {6 fn func(ptr: &u8) usize {
test/cases/for.zig+37-7
...@@ -3,8 +3,14 @@ const assert = std.debug.assert;...@@ -3,8 +3,14 @@ const assert = std.debug.assert;
3const mem = std.mem;3const mem = std.mem;
44
5test "continue in for loop" {5test "continue in for loop" {
6 const array = []i32 {1, 2, 3, 4, 5};6 const array = []i32{
7 var sum : i32 = 0;7 1,
8 2,
9 3,
10 4,
11 5,
12 };
13 var sum: i32 = 0;
8 for (array) |x| {14 for (array) |x| {
9 sum += x;15 sum += x;
10 if (x < 3) {16 if (x < 3) {
...@@ -24,17 +30,39 @@ test "for loop with pointer elem var" {...@@ -24,17 +30,39 @@ test "for loop with pointer elem var" {
24}30}
25fn mangleString(s: []u8) void {31fn mangleString(s: []u8) void {
26 for (s) |*c| {32 for (s) |*c| {
27 *c += 1;33 c.* += 1;
28 }34 }
29}35}
3036
31test "basic for loop" {37test "basic for loop" {
32 const expected_result = []u8{9, 8, 7, 6, 0, 1, 2, 3, 9, 8, 7, 6, 0, 1, 2, 3 };38 const expected_result = []u8{
39 9,
40 8,
41 7,
42 6,
43 0,
44 1,
45 2,
46 3,
47 9,
48 8,
49 7,
50 6,
51 0,
52 1,
53 2,
54 3,
55 };
3356
34 var buffer: [expected_result.len]u8 = undefined;57 var buffer: [expected_result.len]u8 = undefined;
35 var buf_index: usize = 0;58 var buf_index: usize = 0;
3659
37 const array = []u8 {9, 8, 7, 6};60 const array = []u8{
61 9,
62 8,
63 7,
64 6,
65 };
38 for (array) |item| {66 for (array) |item| {
39 buffer[buf_index] = item;67 buffer[buf_index] = item;
40 buf_index += 1;68 buf_index += 1;
...@@ -65,7 +93,8 @@ fn testBreakOuter() void {...@@ -65,7 +93,8 @@ fn testBreakOuter() void {
65 var array = "aoeu";93 var array = "aoeu";
66 var count: usize = 0;94 var count: usize = 0;
67 outer: for (array) |_| {95 outer: for (array) |_| {
68 for (array) |_2| { // TODO shouldn't get error for redeclaring "_"96 // TODO shouldn't get error for redeclaring "_"
97 for (array) |_2| {
69 count += 1;98 count += 1;
70 break :outer;99 break :outer;
71 }100 }
...@@ -82,7 +111,8 @@ fn testContinueOuter() void {...@@ -82,7 +111,8 @@ fn testContinueOuter() void {
82 var array = "aoeu";111 var array = "aoeu";
83 var counter: usize = 0;112 var counter: usize = 0;
84 outer: for (array) |_| {113 outer: for (array) |_| {
85 for (array) |_2| { // TODO shouldn't get error for redeclaring "_"114 // TODO shouldn't get error for redeclaring "_"
115 for (array) |_2| {
86 counter += 1;116 counter += 1;
87 continue :outer;117 continue :outer;
88 }118 }
test/cases/generics.zig+29-15
...@@ -37,7 +37,6 @@ test "fn with comptime args" {...@@ -37,7 +37,6 @@ test "fn with comptime args" {
37 assert(sameButWithFloats(0.43, 0.49) == 0.49);37 assert(sameButWithFloats(0.43, 0.49) == 0.49);
38}38}
3939
40
41test "var params" {40test "var params" {
42 assert(max_i32(12, 34) == 34);41 assert(max_i32(12, 34) == 34);
43 assert(max_f64(1.2, 3.4) == 3.4);42 assert(max_f64(1.2, 3.4) == 3.4);
...@@ -60,7 +59,6 @@ fn max_f64(a: f64, b: f64) f64 {...@@ -60,7 +59,6 @@ fn max_f64(a: f64, b: f64) f64 {
60 return max_var(a, b);59 return max_var(a, b);
61}60}
6261
63
64pub fn List(comptime T: type) type {62pub fn List(comptime T: type) type {
65 return SmallList(T, 8);63 return SmallList(T, 8);
66}64}
...@@ -82,10 +80,15 @@ test "function with return type type" {...@@ -82,10 +80,15 @@ test "function with return type type" {
82 assert(list2.prealloc_items.len == 8);80 assert(list2.prealloc_items.len == 8);
83}81}
8482
85
86test "generic struct" {83test "generic struct" {
87 var a1 = GenNode(i32) {.value = 13, .next = null,};84 var a1 = GenNode(i32){
88 var b1 = GenNode(bool) {.value = true, .next = null,};85 .value = 13,
86 .next = null,
87 };
88 var b1 = GenNode(bool){
89 .value = true,
90 .next = null,
91 };
89 assert(a1.value == 13);92 assert(a1.value == 13);
90 assert(a1.value == a1.getVal());93 assert(a1.value == a1.getVal());
91 assert(b1.getVal());94 assert(b1.getVal());
...@@ -94,7 +97,9 @@ fn GenNode(comptime T: type) type {...@@ -94,7 +97,9 @@ fn GenNode(comptime T: type) type {
94 return struct {97 return struct {
95 value: T,98 value: T,
96 next: ?&GenNode(T),99 next: ?&GenNode(T),
97 fn getVal(n: &const GenNode(T)) T { return n.value; }100 fn getVal(n: &const GenNode(T)) T {
101 return n.value;
102 }
98 };103 };
99}104}
100105
...@@ -107,7 +112,6 @@ fn GenericDataThing(comptime count: isize) type {...@@ -107,7 +112,6 @@ fn GenericDataThing(comptime count: isize) type {
107 };112 };
108}113}
109114
110
111test "use generic param in generic param" {115test "use generic param in generic param" {
112 assert(aGenericFn(i32, 3, 4) == 7);116 assert(aGenericFn(i32, 3, 4) == 7);
113}117}
...@@ -115,21 +119,31 @@ fn aGenericFn(comptime T: type, comptime a: T, b: T) T {...@@ -115,21 +119,31 @@ fn aGenericFn(comptime T: type, comptime a: T, b: T) T {
115 return a + b;119 return a + b;
116}120}
117121
118
119test "generic fn with implicit cast" {122test "generic fn with implicit cast" {
120 assert(getFirstByte(u8, []u8 {13}) == 13);123 assert(getFirstByte(u8, []u8{13}) == 13);
121 assert(getFirstByte(u16, []u16 {0, 13}) == 0);124 assert(getFirstByte(u16, []u16{
125 0,
126 13,
127 }) == 0);
128}
129fn getByte(ptr: ?&const u8) u8 {
130 return (??ptr).*;
122}131}
123fn getByte(ptr: ?&const u8) u8 {return *??ptr;}
124fn getFirstByte(comptime T: type, mem: []const T) u8 {132fn getFirstByte(comptime T: type, mem: []const T) u8 {
125 return getByte(@ptrCast(&const u8, &mem[0]));133 return getByte(@ptrCast(&const u8, &mem[0]));
126}134}
127135
136const foos = []fn(var) bool{
137 foo1,
138 foo2,
139};
128140
129const foos = []fn(var) bool { foo1, foo2 };141fn foo1(arg: var) bool {
130142 return arg;
131fn foo1(arg: var) bool { return arg; }143}
132fn foo2(arg: var) bool { return !arg; }144fn foo2(arg: var) bool {
145 return !arg;
146}
133147
134test "array of generic fns" {148test "array of generic fns" {
135 assert(foos[0](true));149 assert(foos[0](true));
test/cases/if.zig-1
...@@ -23,7 +23,6 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void {...@@ -23,7 +23,6 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void {
23 }23 }
24}24}
2525
26
27test "else if expression" {26test "else if expression" {
28 assert(elseIfExpressionF(1) == 1);27 assert(elseIfExpressionF(1) == 1);
29}28}
test/cases/import/a_namespace.zig+3-1
...@@ -1 +1,3 @@...@@ -1 +1,3 @@
1pub fn foo() i32 { return 1234; }1pub fn foo() i32 {
2 return 1234;
3}
test/cases/incomplete_struct_param_tld.zig+3-5
...@@ -21,11 +21,9 @@ fn foo(a: &const A) i32 {...@@ -21,11 +21,9 @@ fn foo(a: &const A) i32 {
21}21}
2222
23test "incomplete struct param top level declaration" {23test "incomplete struct param top level declaration" {
24 const a = A {24 const a = A{
25 .b = B {25 .b = B{
26 .c = C {26 .c = C{ .x = 13 },
27 .x = 13,
28 },
29 },27 },
30 };28 };
31 assert(foo(a) == 13);29 assert(foo(a) == 13);
test/cases/ir_block_deps.zig+3-1
...@@ -11,7 +11,9 @@ fn foo(id: u64) !i32 {...@@ -11,7 +11,9 @@ fn foo(id: u64) !i32 {
11 };11 };
12}12}
1313
14fn getErrInt() error!i32 { return 0; }14fn getErrInt() error!i32 {
15 return 0;
16}
1517
16test "ir block deps" {18test "ir block deps" {
17 assert((foo(1) catch unreachable) == 0);19 assert((foo(1) catch unreachable) == 0);
test/cases/math.zig+41-53
...@@ -28,25 +28,12 @@ fn testDivision() void {...@@ -28,25 +28,12 @@ fn testDivision() void {
28 assert(divTrunc(f32, -5.0, 3.0) == -1.0);28 assert(divTrunc(f32, -5.0, 3.0) == -1.0);
2929
30 comptime {30 comptime {
31 assert(31 assert(1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600);
32 1194735857077236777412821811143690633098347576 %32 assert(@rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600);
33 508740759824825164163191790951174292733114988 ==33 assert(1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2);
34 177254337427586449086438229241342047632117600);34 assert(@divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2);
35 assert(@rem(-1194735857077236777412821811143690633098347576,35 assert(@divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2);
36 508740759824825164163191790951174292733114988) ==36 assert(@divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2);
37 -177254337427586449086438229241342047632117600);
38 assert(1194735857077236777412821811143690633098347576 /
39 508740759824825164163191790951174292733114988 ==
40 2);
41 assert(@divTrunc(-1194735857077236777412821811143690633098347576,
42 508740759824825164163191790951174292733114988) ==
43 -2);
44 assert(@divTrunc(1194735857077236777412821811143690633098347576,
45 -508740759824825164163191790951174292733114988) ==
46 -2);
47 assert(@divTrunc(-1194735857077236777412821811143690633098347576,
48 -508740759824825164163191790951174292733114988) ==
49 2);
50 assert(4126227191251978491697987544882340798050766755606969681711 % 10 == 1);37 assert(4126227191251978491697987544882340798050766755606969681711 % 10 == 1);
51 }38 }
52}39}
...@@ -114,18 +101,28 @@ fn ctz(x: var) usize {...@@ -114,18 +101,28 @@ fn ctz(x: var) usize {
114101
115test "assignment operators" {102test "assignment operators" {
116 var i: u32 = 0;103 var i: u32 = 0;
117 i += 5; assert(i == 5);104 i += 5;
118 i -= 2; assert(i == 3);105 assert(i == 5);
119 i *= 20; assert(i == 60);106 i -= 2;
120 i /= 3; assert(i == 20);107 assert(i == 3);
121 i %= 11; assert(i == 9);108 i *= 20;
122 i <<= 1; assert(i == 18);109 assert(i == 60);
123 i >>= 2; assert(i == 4);110 i /= 3;
111 assert(i == 20);
112 i %= 11;
113 assert(i == 9);
114 i <<= 1;
115 assert(i == 18);
116 i >>= 2;
117 assert(i == 4);
124 i = 6;118 i = 6;
125 i &= 5; assert(i == 4);119 i &= 5;
126 i ^= 6; assert(i == 2);120 assert(i == 4);
121 i ^= 6;
122 assert(i == 2);
127 i = 6;123 i = 6;
128 i |= 3; assert(i == 7);124 i |= 3;
125 assert(i == 7);
129}126}
130127
131test "three expr in a row" {128test "three expr in a row" {
...@@ -138,7 +135,7 @@ fn testThreeExprInARow(f: bool, t: bool) void {...@@ -138,7 +135,7 @@ fn testThreeExprInARow(f: bool, t: bool) void {
138 assertFalse(1 | 2 | 4 != 7);135 assertFalse(1 | 2 | 4 != 7);
139 assertFalse(3 ^ 6 ^ 8 != 13);136 assertFalse(3 ^ 6 ^ 8 != 13);
140 assertFalse(7 & 14 & 28 != 4);137 assertFalse(7 & 14 & 28 != 4);
141 assertFalse(9 << 1 << 2 != 9 << 3);138 assertFalse(9 << 1 << 2 != 9 << 3);
142 assertFalse(90 >> 1 >> 2 != 90 >> 3);139 assertFalse(90 >> 1 >> 2 != 90 >> 3);
143 assertFalse(100 - 1 + 1000 != 1099);140 assertFalse(100 - 1 + 1000 != 1099);
144 assertFalse(5 * 4 / 2 % 3 != 1);141 assertFalse(5 * 4 / 2 % 3 != 1);
...@@ -150,7 +147,6 @@ fn assertFalse(b: bool) void {...@@ -150,7 +147,6 @@ fn assertFalse(b: bool) void {
150 assert(!b);147 assert(!b);
151}148}
152149
153
154test "const number literal" {150test "const number literal" {
155 const one = 1;151 const one = 1;
156 const eleven = ten + one;152 const eleven = ten + one;
...@@ -159,8 +155,6 @@ test "const number literal" {...@@ -159,8 +155,6 @@ test "const number literal" {
159}155}
160const ten = 10;156const ten = 10;
161157
162
163
164test "unsigned wrapping" {158test "unsigned wrapping" {
165 testUnsignedWrappingEval(@maxValue(u32));159 testUnsignedWrappingEval(@maxValue(u32));
166 comptime testUnsignedWrappingEval(@maxValue(u32));160 comptime testUnsignedWrappingEval(@maxValue(u32));
...@@ -203,7 +197,7 @@ fn test_u64_div() void {...@@ -203,7 +197,7 @@ fn test_u64_div() void {
203 assert(result.remainder == 100663296);197 assert(result.remainder == 100663296);
204}198}
205fn divWithResult(a: u64, b: u64) DivResult {199fn divWithResult(a: u64, b: u64) DivResult {
206 return DivResult {200 return DivResult{
207 .quotient = a / b,201 .quotient = a / b,
208 .remainder = a % b,202 .remainder = a % b,
209 };203 };
...@@ -214,8 +208,12 @@ const DivResult = struct {...@@ -214,8 +208,12 @@ const DivResult = struct {
214};208};
215209
216test "binary not" {210test "binary not" {
217 assert(comptime x: {break :x ~u16(0b1010101010101010) == 0b0101010101010101;});211 assert(comptime x: {
218 assert(comptime x: {break :x ~u64(2147483647) == 18446744071562067968;});212 break :x ~u16(0b1010101010101010) == 0b0101010101010101;
213 });
214 assert(comptime x: {
215 break :x ~u64(2147483647) == 18446744071562067968;
216 });
219 testBinaryNot(0b1010101010101010);217 testBinaryNot(0b1010101010101010);
220}218}
221219
...@@ -319,27 +317,15 @@ fn testShrExact(x: u8) void {...@@ -319,27 +317,15 @@ fn testShrExact(x: u8) void {
319317
320test "big number addition" {318test "big number addition" {
321 comptime {319 comptime {
322 assert(320 assert(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950);
323 35361831660712422535336160538497375248 +321 assert(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380);
324 101752735581729509668353361206450473702 ==
325 137114567242441932203689521744947848950);
326 assert(
327 594491908217841670578297176641415611445982232488944558774612 +
328 390603545391089362063884922208143568023166603618446395589768 ==
329 985095453608931032642182098849559179469148836107390954364380);
330 }322 }
331}323}
332324
333test "big number multiplication" {325test "big number multiplication" {
334 comptime {326 comptime {
335 assert(327 assert(45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567);
336 45960427431263824329884196484953148229 *328 assert(594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016);
337 128339149605334697009938835852565949723 ==
338 5898522172026096622534201617172456926982464453350084962781392314016180490567);
339 assert(
340 594491908217841670578297176641415611445982232488944558774612 *
341 390603545391089362063884922208143568023166603618446395589768 ==
342 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016);
343 }329 }
344}330}
345331
...@@ -405,7 +391,9 @@ test "f128" {...@@ -405,7 +391,9 @@ test "f128" {
405 comptime test_f128();391 comptime test_f128();
406}392}
407393
408fn make_f128(x: f128) f128 { return x; }394fn make_f128(x: f128) f128 {
395 return x;
396}
409397
410fn test_f128() void {398fn test_f128() void {
411 assert(@sizeOf(f128) == 16);399 assert(@sizeOf(f128) == 16);
test/cases/misc.zig+127-86
...@@ -4,6 +4,7 @@ const cstr = @import("std").cstr;...@@ -4,6 +4,7 @@ const cstr = @import("std").cstr;
4const builtin = @import("builtin");4const builtin = @import("builtin");
55
6// normal comment6// normal comment
7
7/// this is a documentation comment8/// this is a documentation comment
8/// doc comment line 29/// doc comment line 2
9fn emptyFunctionWithComments() void {}10fn emptyFunctionWithComments() void {}
...@@ -16,8 +17,7 @@ comptime {...@@ -16,8 +17,7 @@ comptime {
16 @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal);17 @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal);
17}18}
1819
19extern fn disabledExternFn() void {20extern fn disabledExternFn() void {}
20}
2121
22test "call disabled extern fn" {22test "call disabled extern fn" {
23 disabledExternFn();23 disabledExternFn();
...@@ -110,17 +110,29 @@ fn testShortCircuit(f: bool, t: bool) void {...@@ -110,17 +110,29 @@ fn testShortCircuit(f: bool, t: bool) void {
110 var hit_3 = f;110 var hit_3 = f;
111 var hit_4 = f;111 var hit_4 = f;
112112
113 if (t or x: {assert(f); break :x f;}) {113 if (t or x: {
114 assert(f);
115 break :x f;
116 }) {
114 hit_1 = t;117 hit_1 = t;
115 }118 }
116 if (f or x: { hit_2 = t; break :x f; }) {119 if (f or x: {
120 hit_2 = t;
121 break :x f;
122 }) {
117 assert(f);123 assert(f);
118 }124 }
119125
120 if (t and x: { hit_3 = t; break :x f; }) {126 if (t and x: {
127 hit_3 = t;
128 break :x f;
129 }) {
121 assert(f);130 assert(f);
122 }131 }
123 if (f and x: {assert(f); break :x f;}) {132 if (f and x: {
133 assert(f);
134 break :x f;
135 }) {
124 assert(f);136 assert(f);
125 } else {137 } else {
126 hit_4 = t;138 hit_4 = t;
...@@ -146,8 +158,8 @@ test "return string from function" {...@@ -146,8 +158,8 @@ test "return string from function" {
146 assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));158 assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
147}159}
148160
149const g1 : i32 = 1233 + 1;161const g1: i32 = 1233 + 1;
150var g2 : i32 = 0;162var g2: i32 = 0;
151163
152test "global variables" {164test "global variables" {
153 assert(g2 == 0);165 assert(g2 == 0);
...@@ -155,10 +167,9 @@ test "global variables" {...@@ -155,10 +167,9 @@ test "global variables" {
155 assert(g2 == 1234);167 assert(g2 == 1234);
156}168}
157169
158
159test "memcpy and memset intrinsics" {170test "memcpy and memset intrinsics" {
160 var foo : [20]u8 = undefined;171 var foo: [20]u8 = undefined;
161 var bar : [20]u8 = undefined;172 var bar: [20]u8 = undefined;
162173
163 @memset(&foo[0], 'A', foo.len);174 @memset(&foo[0], 'A', foo.len);
164 @memcpy(&bar[0], &foo[0], bar.len);175 @memcpy(&bar[0], &foo[0], bar.len);
...@@ -167,12 +178,14 @@ test "memcpy and memset intrinsics" {...@@ -167,12 +178,14 @@ test "memcpy and memset intrinsics" {
167}178}
168179
169test "builtin static eval" {180test "builtin static eval" {
170 const x : i32 = comptime x: {break :x 1 + 2 + 3;};181 const x: i32 = comptime x: {
182 break :x 1 + 2 + 3;
183 };
171 assert(x == comptime 6);184 assert(x == comptime 6);
172}185}
173186
174test "slicing" {187test "slicing" {
175 var array : [20]i32 = undefined;188 var array: [20]i32 = undefined;
176189
177 array[5] = 1234;190 array[5] = 1234;
178191
...@@ -187,15 +200,15 @@ test "slicing" {...@@ -187,15 +200,15 @@ test "slicing" {
187 if (slice_rest.len != 10) unreachable;200 if (slice_rest.len != 10) unreachable;
188}201}
189202
190
191test "constant equal function pointers" {203test "constant equal function pointers" {
192 const alias = emptyFn;204 const alias = emptyFn;
193 assert(comptime x: {break :x emptyFn == alias;});205 assert(comptime x: {
206 break :x emptyFn == alias;
207 });
194}208}
195209
196fn emptyFn() void {}210fn emptyFn() void {}
197211
198
199test "hex escape" {212test "hex escape" {
200 assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));213 assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));
201}214}
...@@ -238,18 +251,16 @@ test "multiline C string" {...@@ -238,18 +251,16 @@ test "multiline C string" {
238 assert(cstr.cmp(s1, s2) == 0);251 assert(cstr.cmp(s1, s2) == 0);
239}252}
240253
241
242test "type equality" {254test "type equality" {
243 assert(&const u8 != &u8);255 assert(&const u8 != &u8);
244}256}
245257
246
247const global_a: i32 = 1234;258const global_a: i32 = 1234;
248const global_b: &const i32 = &global_a;259const global_b: &const i32 = &global_a;
249const global_c: &const f32 = @ptrCast(&const f32, global_b);260const global_c: &const f32 = @ptrCast(&const f32, global_b);
250test "compile time global reinterpret" {261test "compile time global reinterpret" {
251 const d = @ptrCast(&const i32, global_c);262 const d = @ptrCast(&const i32, global_c);
252 assert(*d == 1234);263 assert(d.* == 1234);
253}264}
254265
255test "explicit cast maybe pointers" {266test "explicit cast maybe pointers" {
...@@ -261,12 +272,11 @@ test "generic malloc free" {...@@ -261,12 +272,11 @@ test "generic malloc free" {
261 const a = memAlloc(u8, 10) catch unreachable;272 const a = memAlloc(u8, 10) catch unreachable;
262 memFree(u8, a);273 memFree(u8, a);
263}274}
264var some_mem : [100]u8 = undefined;275var some_mem: [100]u8 = undefined;
265fn memAlloc(comptime T: type, n: usize) error![]T {276fn memAlloc(comptime T: type, n: usize) error![]T {
266 return @ptrCast(&T, &some_mem[0])[0..n];277 return @ptrCast(&T, &some_mem[0])[0..n];
267}278}
268fn memFree(comptime T: type, memory: []T) void { }279fn memFree(comptime T: type, memory: []T) void {}
269
270280
271test "cast undefined" {281test "cast undefined" {
272 const array: [100]u8 = undefined;282 const array: [100]u8 = undefined;
...@@ -275,32 +285,35 @@ test "cast undefined" {...@@ -275,32 +285,35 @@ test "cast undefined" {
275}285}
276fn testCastUndefined(x: []const u8) void {}286fn testCastUndefined(x: []const u8) void {}
277287
278
279test "cast small unsigned to larger signed" {288test "cast small unsigned to larger signed" {
280 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));289 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
281 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));290 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
282}291}
283fn castSmallUnsignedToLargerSigned1(x: u8) i16 { return x; }292fn castSmallUnsignedToLargerSigned1(x: u8) i16 {
284fn castSmallUnsignedToLargerSigned2(x: u16) i64 { return x; }293 return x;
285294}
295fn castSmallUnsignedToLargerSigned2(x: u16) i64 {
296 return x;
297}
286298
287test "implicit cast after unreachable" {299test "implicit cast after unreachable" {
288 assert(outer() == 1234);300 assert(outer() == 1234);
289}301}
290fn inner() i32 { return 1234; }302fn inner() i32 {
303 return 1234;
304}
291fn outer() i64 {305fn outer() i64 {
292 return inner();306 return inner();
293}307}
294308
295
296test "pointer dereferencing" {309test "pointer dereferencing" {
297 var x = i32(3);310 var x = i32(3);
298 const y = &x;311 const y = &x;
299312
300 *y += 1;313 y.* += 1;
301314
302 assert(x == 4);315 assert(x == 4);
303 assert(*y == 4);316 assert(y.* == 4);
304}317}
305318
306test "call result of if else expression" {319test "call result of if else expression" {
...@@ -310,9 +323,12 @@ test "call result of if else expression" {...@@ -310,9 +323,12 @@ test "call result of if else expression" {
310fn f2(x: bool) []const u8 {323fn f2(x: bool) []const u8 {
311 return (if (x) fA else fB)();324 return (if (x) fA else fB)();
312}325}
313fn fA() []const u8 { return "a"; }326fn fA() []const u8 {
314fn fB() []const u8 { return "b"; }327 return "a";
315328}
329fn fB() []const u8 {
330 return "b";
331}
316332
317test "const expression eval handling of variables" {333test "const expression eval handling of variables" {
318 var x = true;334 var x = true;
...@@ -321,8 +337,6 @@ test "const expression eval handling of variables" {...@@ -321,8 +337,6 @@ test "const expression eval handling of variables" {
321 }337 }
322}338}
323339
324
325
326test "constant enum initialization with differing sizes" {340test "constant enum initialization with differing sizes" {
327 test3_1(test3_foo);341 test3_1(test3_foo);
328 test3_2(test3_bar);342 test3_2(test3_bar);
...@@ -336,10 +350,15 @@ const Test3Point = struct {...@@ -336,10 +350,15 @@ const Test3Point = struct {
336 x: i32,350 x: i32,
337 y: i32,351 y: i32,
338};352};
339const test3_foo = Test3Foo { .Three = Test3Point {.x = 3, .y = 4}};353const test3_foo = Test3Foo{
340const test3_bar = Test3Foo { .Two = 13};354 .Three = Test3Point{
355 .x = 3,
356 .y = 4,
357 },
358};
359const test3_bar = Test3Foo{ .Two = 13 };
341fn test3_1(f: &const Test3Foo) void {360fn test3_1(f: &const Test3Foo) void {
342 switch (*f) {361 switch (f.*) {
343 Test3Foo.Three => |pt| {362 Test3Foo.Three => |pt| {
344 assert(pt.x == 3);363 assert(pt.x == 3);
345 assert(pt.y == 4);364 assert(pt.y == 4);
...@@ -348,7 +367,7 @@ fn test3_1(f: &const Test3Foo) void {...@@ -348,7 +367,7 @@ fn test3_1(f: &const Test3Foo) void {
348 }367 }
349}368}
350fn test3_2(f: &const Test3Foo) void {369fn test3_2(f: &const Test3Foo) void {
351 switch (*f) {370 switch (f.*) {
352 Test3Foo.Two => |x| {371 Test3Foo.Two => |x| {
353 assert(x == 13);372 assert(x == 13);
354 },373 },
...@@ -356,23 +375,19 @@ fn test3_2(f: &const Test3Foo) void {...@@ -356,23 +375,19 @@ fn test3_2(f: &const Test3Foo) void {
356 }375 }
357}376}
358377
359
360test "character literals" {378test "character literals" {
361 assert('\'' == single_quote);379 assert('\'' == single_quote);
362}380}
363const single_quote = '\'';381const single_quote = '\'';
364382
365
366
367test "take address of parameter" {383test "take address of parameter" {
368 testTakeAddressOfParameter(12.34);384 testTakeAddressOfParameter(12.34);
369}385}
370fn testTakeAddressOfParameter(f: f32) void {386fn testTakeAddressOfParameter(f: f32) void {
371 const f_ptr = &f;387 const f_ptr = &f;
372 assert(*f_ptr == 12.34);388 assert(f_ptr.* == 12.34);
373}389}
374390
375
376test "pointer comparison" {391test "pointer comparison" {
377 const a = ([]const u8)("a");392 const a = ([]const u8)("a");
378 const b = &a;393 const b = &a;
...@@ -382,23 +397,30 @@ fn ptrEql(a: &const []const u8, b: &const []const u8) bool {...@@ -382,23 +397,30 @@ fn ptrEql(a: &const []const u8, b: &const []const u8) bool {
382 return a == b;397 return a == b;
383}398}
384399
385
386test "C string concatenation" {400test "C string concatenation" {
387 const a = c"OK" ++ c" IT " ++ c"WORKED";401 const a = c"OK" ++ c" IT " ++ c"WORKED";
388 const b = c"OK IT WORKED";402 const b = c"OK IT WORKED";
389403
390 const len = cstr.len(b);404 const len = cstr.len(b);
391 const len_with_null = len + 1;405 const len_with_null = len + 1;
392 {var i: u32 = 0; while (i < len_with_null) : (i += 1) {406 {
393 assert(a[i] == b[i]);407 var i: u32 = 0;
394 }}408 while (i < len_with_null) : (i += 1) {
409 assert(a[i] == b[i]);
410 }
411 }
395 assert(a[len] == 0);412 assert(a[len] == 0);
396 assert(b[len] == 0);413 assert(b[len] == 0);
397}414}
398415
399test "cast slice to u8 slice" {416test "cast slice to u8 slice" {
400 assert(@sizeOf(i32) == 4);417 assert(@sizeOf(i32) == 4);
401 var big_thing_array = []i32{1, 2, 3, 4};418 var big_thing_array = []i32{
419 1,
420 2,
421 3,
422 4,
423 };
402 const big_thing_slice: []i32 = big_thing_array[0..];424 const big_thing_slice: []i32 = big_thing_array[0..];
403 const bytes = ([]u8)(big_thing_slice);425 const bytes = ([]u8)(big_thing_slice);
404 assert(bytes.len == 4 * 4);426 assert(bytes.len == 4 * 4);
...@@ -421,23 +443,20 @@ test "pointer to void return type" {...@@ -421,23 +443,20 @@ test "pointer to void return type" {
421}443}
422fn testPointerToVoidReturnType() error!void {444fn testPointerToVoidReturnType() error!void {
423 const a = testPointerToVoidReturnType2();445 const a = testPointerToVoidReturnType2();
424 return *a;446 return a.*;
425}447}
426const test_pointer_to_void_return_type_x = void{};448const test_pointer_to_void_return_type_x = void{};
427fn testPointerToVoidReturnType2() &const void {449fn testPointerToVoidReturnType2() &const void {
428 return &test_pointer_to_void_return_type_x;450 return &test_pointer_to_void_return_type_x;
429}451}
430452
431
432test "non const ptr to aliased type" {453test "non const ptr to aliased type" {
433 const int = i32;454 const int = i32;
434 assert(?&int == ?&i32);455 assert(?&int == ?&i32);
435}456}
436457
437
438
439test "array 2D const double ptr" {458test "array 2D const double ptr" {
440 const rect_2d_vertexes = [][1]f32 {459 const rect_2d_vertexes = [][1]f32{
441 []f32{1.0},460 []f32{1.0},
442 []f32{2.0},461 []f32{2.0},
443 };462 };
...@@ -450,10 +469,21 @@ fn testArray2DConstDoublePtr(ptr: &const f32) void {...@@ -450,10 +469,21 @@ fn testArray2DConstDoublePtr(ptr: &const f32) void {
450}469}
451470
452const Tid = builtin.TypeId;471const Tid = builtin.TypeId;
453const AStruct = struct { x: i32, };472const AStruct = struct {
454const AnEnum = enum { One, Two, };473 x: i32,
455const AUnionEnum = union(enum) { One: i32, Two: void, };474};
456const AUnion = union { One: void, Two: void };475const AnEnum = enum {
476 One,
477 Two,
478};
479const AUnionEnum = union(enum) {
480 One: i32,
481 Two: void,
482};
483const AUnion = union {
484 One: void,
485 Two: void,
486};
457487
458test "@typeId" {488test "@typeId" {
459 comptime {489 comptime {
...@@ -481,9 +511,11 @@ test "@typeId" {...@@ -481,9 +511,11 @@ test "@typeId" {
481 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);511 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
482 assert(@typeId(AUnionEnum) == Tid.Union);512 assert(@typeId(AUnionEnum) == Tid.Union);
483 assert(@typeId(AUnion) == Tid.Union);513 assert(@typeId(AUnion) == Tid.Union);
484 assert(@typeId(fn()void) == Tid.Fn);514 assert(@typeId(fn() void) == Tid.Fn);
485 assert(@typeId(@typeOf(builtin)) == Tid.Namespace);515 assert(@typeId(@typeOf(builtin)) == Tid.Namespace);
486 assert(@typeId(@typeOf(x: {break :x this;})) == Tid.Block);516 assert(@typeId(@typeOf(x: {
517 break :x this;
518 })) == Tid.Block);
487 // TODO bound fn519 // TODO bound fn
488 // TODO arg tuple520 // TODO arg tuple
489 // TODO opaque521 // TODO opaque
...@@ -499,8 +531,7 @@ test "@canImplicitCast" {...@@ -499,8 +531,7 @@ test "@canImplicitCast" {
499}531}
500532
501test "@typeName" {533test "@typeName" {
502 const Struct = struct {534 const Struct = struct {};
503 };
504 const Union = union {535 const Union = union {
505 unused: u8,536 unused: u8,
506 };537 };
...@@ -510,7 +541,7 @@ test "@typeName" {...@@ -510,7 +541,7 @@ test "@typeName" {
510 comptime {541 comptime {
511 assert(mem.eql(u8, @typeName(i64), "i64"));542 assert(mem.eql(u8, @typeName(i64), "i64"));
512 assert(mem.eql(u8, @typeName(&usize), "&usize"));543 assert(mem.eql(u8, @typeName(&usize), "&usize"));
513 // https://github.com/zig-lang/zig/issues/675544 // https://github.com/ziglang/zig/issues/675
514 assert(mem.eql(u8, @typeName(TypeFromFn(u8)), "TypeFromFn(u8)"));545 assert(mem.eql(u8, @typeName(TypeFromFn(u8)), "TypeFromFn(u8)"));
515 assert(mem.eql(u8, @typeName(Struct), "Struct"));546 assert(mem.eql(u8, @typeName(Struct), "Struct"));
516 assert(mem.eql(u8, @typeName(Union), "Union"));547 assert(mem.eql(u8, @typeName(Union), "Union"));
...@@ -525,14 +556,19 @@ fn TypeFromFn(comptime T: type) type {...@@ -525,14 +556,19 @@ fn TypeFromFn(comptime T: type) type {
525test "volatile load and store" {556test "volatile load and store" {
526 var number: i32 = 1234;557 var number: i32 = 1234;
527 const ptr = (&volatile i32)(&number);558 const ptr = (&volatile i32)(&number);
528 *ptr += 1;559 ptr.* += 1;
529 assert(*ptr == 1235);560 assert(ptr.* == 1235);
530}561}
531562
532test "slice string literal has type []const u8" {563test "slice string literal has type []const u8" {
533 comptime {564 comptime {
534 assert(@typeOf("aoeu"[0..]) == []const u8);565 assert(@typeOf("aoeu"[0..]) == []const u8);
535 const array = []i32{1, 2, 3, 4};566 const array = []i32{
567 1,
568 2,
569 3,
570 4,
571 };
536 assert(@typeOf(array[0..]) == []const i32);572 assert(@typeOf(array[0..]) == []const i32);
537 }573 }
538}574}
...@@ -543,13 +579,12 @@ test "global variable initialized to global variable array element" {...@@ -543,13 +579,12 @@ test "global variable initialized to global variable array element" {
543const GDTEntry = struct {579const GDTEntry = struct {
544 field: i32,580 field: i32,
545};581};
546var gdt = []GDTEntry {582var gdt = []GDTEntry{
547 GDTEntry {.field = 1},583 GDTEntry{ .field = 1 },
548 GDTEntry {.field = 2},584 GDTEntry{ .field = 2 },
549};585};
550var global_ptr = &gdt[0];586var global_ptr = &gdt[0];
551587
552
553// can't really run this test but we can make sure it has no compile error588// can't really run this test but we can make sure it has no compile error
554// and generates code589// and generates code
555const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];590const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];
...@@ -584,7 +619,7 @@ test "comptime if inside runtime while which unconditionally breaks" {...@@ -584,7 +619,7 @@ test "comptime if inside runtime while which unconditionally breaks" {
584}619}
585fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {620fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {
586 while (cond) {621 while (cond) {
587 if (false) { }622 if (false) {}
588 break;623 break;
589 }624 }
590}625}
...@@ -607,7 +642,7 @@ fn testStructInFn() void {...@@ -607,7 +642,7 @@ fn testStructInFn() void {
607 kind: BlockKind,642 kind: BlockKind,
608 };643 };
609644
610 var block = Block { .kind = 1234 };645 var block = Block{ .kind = 1234 };
611646
612 block.kind += 1;647 block.kind += 1;
613648
...@@ -617,7 +652,9 @@ fn testStructInFn() void {...@@ -617,7 +652,9 @@ fn testStructInFn() void {
617fn fnThatClosesOverLocalConst() type {652fn fnThatClosesOverLocalConst() type {
618 const c = 1;653 const c = 1;
619 return struct {654 return struct {
620 fn g() i32 { return c; }655 fn g() i32 {
656 return c;
657 }
621 };658 };
622}659}
623660
...@@ -635,22 +672,27 @@ fn thisIsAColdFn() void {...@@ -635,22 +672,27 @@ fn thisIsAColdFn() void {
635 @setCold(true);672 @setCold(true);
636}673}
637674
638675const PackedStruct = packed struct {
639const PackedStruct = packed struct { a: u8, b: u8, };676 a: u8,
640const PackedUnion = packed union { a: u8, b: u32, };677 b: u8,
641const PackedEnum = packed enum { A, B, };678};
679const PackedUnion = packed union {
680 a: u8,
681 b: u32,
682};
683const PackedEnum = packed enum {
684 A,
685 B,
686};
642687
643test "packed struct, enum, union parameters in extern function" {688test "packed struct, enum, union parameters in extern function" {
644 testPackedStuff(689 testPackedStuff(PackedStruct{
645 PackedStruct{.a = 1, .b = 2},690 .a = 1,
646 PackedUnion{.a = 1},691 .b = 2,
647 PackedEnum.A,692 }, PackedUnion{ .a = 1 }, PackedEnum.A);
648 );
649}
650
651export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {
652}693}
653694
695export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {}
654696
655test "slicing zero length array" {697test "slicing zero length array" {
656 const s1 = ""[0..];698 const s1 = ""[0..];
...@@ -661,7 +703,6 @@ test "slicing zero length array" {...@@ -661,7 +703,6 @@ test "slicing zero length array" {
661 assert(mem.eql(u32, s2, []u32{}));703 assert(mem.eql(u32, s2, []u32{}));
662}704}
663705
664
665const addr1 = @ptrCast(&const u8, emptyFn);706const addr1 = @ptrCast(&const u8, emptyFn);
666test "comptime cast fn to ptr" {707test "comptime cast fn to ptr" {
667 const addr2 = @ptrCast(&const u8, emptyFn);708 const addr2 = @ptrCast(&const u8, emptyFn);
test/cases/namespace_depends_on_compile_var/index.zig+1-1
...@@ -8,7 +8,7 @@ test "namespace depends on compile var" {...@@ -8,7 +8,7 @@ test "namespace depends on compile var" {
8 assert(!some_namespace.a_bool);8 assert(!some_namespace.a_bool);
9 }9 }
10}10}
11const some_namespace = switch(builtin.os) {11const some_namespace = switch (builtin.os) {
12 builtin.Os.linux => @import("a.zig"),12 builtin.Os.linux => @import("a.zig"),
13 else => @import("b.zig"),13 else => @import("b.zig"),
14};14};
test/cases/new_stack_call.zig created+26
...@@ -0,0 +1,26 @@
1const std = @import("std");
2const assert = std.debug.assert;
3
4var new_stack_bytes: [1024]u8 = undefined;
5
6test "calling a function with a new stack" {
7 const arg = 1234;
8
9 const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg);
10 const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
11 _ = targetFunction(arg);
12
13 assert(arg == 1234);
14 assert(a < b);
15}
16
17fn targetFunction(x: i32) usize {
18 assert(x == 1234);
19
20 var local_variable: i32 = 42;
21 const ptr = &local_variable;
22 ptr.* += 1;
23
24 assert(local_variable == 43);
25 return @ptrToInt(ptr);
26}
test/cases/null.zig+13-18
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
22
3test "nullable type" {3test "nullable type" {
4 const x : ?bool = true;4 const x: ?bool = true;
55
6 if (x) |y| {6 if (x) |y| {
7 if (y) {7 if (y) {
...@@ -13,13 +13,13 @@ test "nullable type" {...@@ -13,13 +13,13 @@ test "nullable type" {
13 unreachable;13 unreachable;
14 }14 }
1515
16 const next_x : ?i32 = null;16 const next_x: ?i32 = null;
1717
18 const z = next_x ?? 1234;18 const z = next_x ?? 1234;
1919
20 assert(z == 1234);20 assert(z == 1234);
2121
22 const final_x : ?i32 = 13;22 const final_x: ?i32 = 13;
2323
24 const num = final_x ?? unreachable;24 const num = final_x ?? unreachable;
2525
...@@ -30,19 +30,17 @@ test "test maybe object and get a pointer to the inner value" {...@@ -30,19 +30,17 @@ test "test maybe object and get a pointer to the inner value" {
30 var maybe_bool: ?bool = true;30 var maybe_bool: ?bool = true;
3131
32 if (maybe_bool) |*b| {32 if (maybe_bool) |*b| {
33 *b = false;33 b.* = false;
34 }34 }
3535
36 assert(??maybe_bool == false);36 assert(??maybe_bool == false);
37}37}
3838
39
40test "rhs maybe unwrap return" {39test "rhs maybe unwrap return" {
41 const x: ?bool = true;40 const x: ?bool = true;
42 const y = x ?? return;41 const y = x ?? return;
43}42}
4443
45
46test "maybe return" {44test "maybe return" {
47 maybeReturnImpl();45 maybeReturnImpl();
48 comptime maybeReturnImpl();46 comptime maybeReturnImpl();
...@@ -50,8 +48,7 @@ test "maybe return" {...@@ -50,8 +48,7 @@ test "maybe return" {
5048
51fn maybeReturnImpl() void {49fn maybeReturnImpl() void {
52 assert(??foo(1235));50 assert(??foo(1235));
53 if (foo(null) != null)51 if (foo(null) != null) unreachable;
54 unreachable;
55 assert(!??foo(1234));52 assert(!??foo(1234));
56}53}
5754
...@@ -60,12 +57,16 @@ fn foo(x: ?i32) ?bool {...@@ -60,12 +57,16 @@ fn foo(x: ?i32) ?bool {
60 return value > 1234;57 return value > 1234;
61}58}
6259
63
64test "if var maybe pointer" {60test "if var maybe pointer" {
65 assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15);61 assert(shouldBeAPlus1(Particle{
62 .a = 14,
63 .b = 1,
64 .c = 1,
65 .d = 1,
66 }) == 15);
66}67}
67fn shouldBeAPlus1(p: &const Particle) u64 {68fn shouldBeAPlus1(p: &const Particle) u64 {
68 var maybe_particle: ?Particle = *p;69 var maybe_particle: ?Particle = p.*;
69 if (maybe_particle) |*particle| {70 if (maybe_particle) |*particle| {
70 particle.a += 1;71 particle.a += 1;
71 }72 }
...@@ -81,7 +82,6 @@ const Particle = struct {...@@ -81,7 +82,6 @@ const Particle = struct {
81 d: u64,82 d: u64,
82};83};
8384
84
85test "null literal outside function" {85test "null literal outside function" {
86 const is_null = here_is_a_null_literal.context == null;86 const is_null = here_is_a_null_literal.context == null;
87 assert(is_null);87 assert(is_null);
...@@ -92,10 +92,7 @@ test "null literal outside function" {...@@ -92,10 +92,7 @@ test "null literal outside function" {
92const SillyStruct = struct {92const SillyStruct = struct {
93 context: ?i32,93 context: ?i32,
94};94};
95const here_is_a_null_literal = SillyStruct {95const here_is_a_null_literal = SillyStruct{ .context = null };
96 .context = null,
97};
98
9996
100test "test null runtime" {97test "test null runtime" {
101 testTestNullRuntime(null);98 testTestNullRuntime(null);
...@@ -123,8 +120,6 @@ fn bar(x: ?void) ?void {...@@ -123,8 +120,6 @@ fn bar(x: ?void) ?void {
123 }120 }
124}121}
125122
126
127
128const StructWithNullable = struct {123const StructWithNullable = struct {
129 field: ?i32,124 field: ?i32,
130};125};
test/cases/pointers.zig created+14
...@@ -0,0 +1,14 @@
1const std = @import("std");
2const assert = std.debug.assert;
3
4test "dereference pointer" {
5 comptime testDerefPtr();
6 testDerefPtr();
7}
8
9fn testDerefPtr() void {
10 var x: i32 = 1234;
11 var y = &x;
12 y.* += 1;
13 assert(x == 1235);
14}
test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig+1-1
...@@ -23,7 +23,7 @@ fn foo(c: bool, k: Num, c2: bool, b: []const u8) void {...@@ -23,7 +23,7 @@ fn foo(c: bool, k: Num, c2: bool, b: []const u8) void {
23 if (c) {23 if (c) {
24 const output_path = b;24 const output_path = b;
2525
26 if (c2) { }26 if (c2) {}
2727
28 a(output_path);28 a(output_path);
29 }29 }
test/cases/reflection.zig+4-3
...@@ -23,7 +23,9 @@ test "reflection: function return type, var args, and param types" {...@@ -23,7 +23,9 @@ test "reflection: function return type, var args, and param types" {
23 }23 }
24}24}
2525
26fn dummy(a: bool, b: i32, c: f32) i32 { return 1234; }26fn dummy(a: bool, b: i32, c: f32) i32 {
27 return 1234;
28}
27fn dummy_varargs(args: ...) void {}29fn dummy_varargs(args: ...) void {}
2830
29test "reflection: struct member types and names" {31test "reflection: struct member types and names" {
...@@ -54,11 +56,10 @@ test "reflection: enum member types and names" {...@@ -54,11 +56,10 @@ test "reflection: enum member types and names" {
54 assert(mem.eql(u8, @memberName(Bar, 2), "Three"));56 assert(mem.eql(u8, @memberName(Bar, 2), "Three"));
55 assert(mem.eql(u8, @memberName(Bar, 3), "Four"));57 assert(mem.eql(u8, @memberName(Bar, 3), "Four"));
56 }58 }
57
58}59}
5960
60test "reflection: @field" {61test "reflection: @field" {
61 var f = Foo {62 var f = Foo{
62 .one = 42,63 .one = 42,
63 .two = true,64 .two = true,
64 .three = void{},65 .three = void{},
test/cases/slice.zig+6-2
...@@ -18,7 +18,11 @@ test "slice child property" {...@@ -18,7 +18,11 @@ test "slice child property" {
18}18}
1919
20test "runtime safety lets us slice from len..len" {20test "runtime safety lets us slice from len..len" {
21 var an_array = []u8{1, 2, 3};21 var an_array = []u8{
22 1,
23 2,
24 3,
25 };
22 assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));26 assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
23}27}
2428
...@@ -27,7 +31,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {...@@ -27,7 +31,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
27}31}
2832
29test "implicitly cast array of size 0 to slice" {33test "implicitly cast array of size 0 to slice" {
30 var msg = []u8 {};34 var msg = []u8{};
31 assertLenIsZero(msg);35 assertLenIsZero(msg);
32}36}
3337
test/cases/struct.zig+41-38
...@@ -2,9 +2,11 @@ const assert = @import("std").debug.assert;...@@ -2,9 +2,11 @@ const assert = @import("std").debug.assert;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4const StructWithNoFields = struct {4const StructWithNoFields = struct {
5 fn add(a: i32, b: i32) i32 { return a + b; }5 fn add(a: i32, b: i32) i32 {
6 return a + b;
7 }
6};8};
7const empty_global_instance = StructWithNoFields {};9const empty_global_instance = StructWithNoFields{};
810
9test "call struct static method" {11test "call struct static method" {
10 const result = StructWithNoFields.add(3, 4);12 const result = StructWithNoFields.add(3, 4);
...@@ -25,7 +27,7 @@ test "invake static method in global scope" {...@@ -25,7 +27,7 @@ test "invake static method in global scope" {
25}27}
2628
27test "void struct fields" {29test "void struct fields" {
28 const foo = VoidStructFieldsFoo {30 const foo = VoidStructFieldsFoo{
29 .a = void{},31 .a = void{},
30 .b = 1,32 .b = 1,
31 .c = void{},33 .c = void{},
...@@ -34,12 +36,11 @@ test "void struct fields" {...@@ -34,12 +36,11 @@ test "void struct fields" {
34 assert(@sizeOf(VoidStructFieldsFoo) == 4);36 assert(@sizeOf(VoidStructFieldsFoo) == 4);
35}37}
36const VoidStructFieldsFoo = struct {38const VoidStructFieldsFoo = struct {
37 a : void,39 a: void,
38 b : i32,40 b: i32,
39 c : void,41 c: void,
40};42};
4143
42
43test "structs" {44test "structs" {
44 var foo: StructFoo = undefined;45 var foo: StructFoo = undefined;
45 @memset(@ptrCast(&u8, &foo), 0, @sizeOf(StructFoo));46 @memset(@ptrCast(&u8, &foo), 0, @sizeOf(StructFoo));
...@@ -50,9 +51,9 @@ test "structs" {...@@ -50,9 +51,9 @@ test "structs" {
50 assert(foo.c == 100);51 assert(foo.c == 100);
51}52}
52const StructFoo = struct {53const StructFoo = struct {
53 a : i32,54 a: i32,
54 b : bool,55 b: bool,
55 c : f32,56 c: f32,
56};57};
57fn testFoo(foo: &const StructFoo) void {58fn testFoo(foo: &const StructFoo) void {
58 assert(foo.b);59 assert(foo.b);
...@@ -61,7 +62,6 @@ fn testMutation(foo: &StructFoo) void {...@@ -61,7 +62,6 @@ fn testMutation(foo: &StructFoo) void {
61 foo.c = 100;62 foo.c = 100;
62}63}
6364
64
65const Node = struct {65const Node = struct {
66 val: Val,66 val: Val,
67 next: &Node,67 next: &Node,
...@@ -72,10 +72,10 @@ const Val = struct {...@@ -72,10 +72,10 @@ const Val = struct {
72};72};
7373
74test "struct point to self" {74test "struct point to self" {
75 var root : Node = undefined;75 var root: Node = undefined;
76 root.val.x = 1;76 root.val.x = 1;
7777
78 var node : Node = undefined;78 var node: Node = undefined;
79 node.next = &root;79 node.next = &root;
80 node.val.x = 2;80 node.val.x = 2;
8181
...@@ -85,8 +85,8 @@ test "struct point to self" {...@@ -85,8 +85,8 @@ test "struct point to self" {
85}85}
8686
87test "struct byval assign" {87test "struct byval assign" {
88 var foo1 : StructFoo = undefined;88 var foo1: StructFoo = undefined;
89 var foo2 : StructFoo = undefined;89 var foo2: StructFoo = undefined;
9090
91 foo1.a = 1234;91 foo1.a = 1234;
92 foo2.a = 0;92 foo2.a = 0;
...@@ -96,46 +96,47 @@ test "struct byval assign" {...@@ -96,46 +96,47 @@ test "struct byval assign" {
96}96}
9797
98fn structInitializer() void {98fn structInitializer() void {
99 const val = Val { .x = 42 };99 const val = Val{ .x = 42 };
100 assert(val.x == 42);100 assert(val.x == 42);
101}101}
102102
103
104test "fn call of struct field" {103test "fn call of struct field" {
105 assert(callStructField(Foo {.ptr = aFunc,}) == 13);104 assert(callStructField(Foo{ .ptr = aFunc }) == 13);
106}105}
107106
108const Foo = struct {107const Foo = struct {
109 ptr: fn() i32,108 ptr: fn() i32,
110};109};
111110
112fn aFunc() i32 { return 13; }111fn aFunc() i32 {
112 return 13;
113}
113114
114fn callStructField(foo: &const Foo) i32 {115fn callStructField(foo: &const Foo) i32 {
115 return foo.ptr();116 return foo.ptr();
116}117}
117118
118
119test "store member function in variable" {119test "store member function in variable" {
120 const instance = MemberFnTestFoo { .x = 1234, };120 const instance = MemberFnTestFoo{ .x = 1234 };
121 const memberFn = MemberFnTestFoo.member;121 const memberFn = MemberFnTestFoo.member;
122 const result = memberFn(instance);122 const result = memberFn(instance);
123 assert(result == 1234);123 assert(result == 1234);
124}124}
125const MemberFnTestFoo = struct {125const MemberFnTestFoo = struct {
126 x: i32,126 x: i32,
127 fn member(foo: &const MemberFnTestFoo) i32 { return foo.x; }127 fn member(foo: &const MemberFnTestFoo) i32 {
128 return foo.x;
129 }
128};130};
129131
130
131test "call member function directly" {132test "call member function directly" {
132 const instance = MemberFnTestFoo { .x = 1234, };133 const instance = MemberFnTestFoo{ .x = 1234 };
133 const result = MemberFnTestFoo.member(instance);134 const result = MemberFnTestFoo.member(instance);
134 assert(result == 1234);135 assert(result == 1234);
135}136}
136137
137test "member functions" {138test "member functions" {
138 const r = MemberFnRand {.seed = 1234};139 const r = MemberFnRand{ .seed = 1234 };
139 assert(r.getSeed() == 1234);140 assert(r.getSeed() == 1234);
140}141}
141const MemberFnRand = struct {142const MemberFnRand = struct {
...@@ -154,7 +155,7 @@ const Bar = struct {...@@ -154,7 +155,7 @@ const Bar = struct {
154 y: i32,155 y: i32,
155};156};
156fn makeBar(x: i32, y: i32) Bar {157fn makeBar(x: i32, y: i32) Bar {
157 return Bar {158 return Bar{
158 .x = x,159 .x = x,
159 .y = y,160 .y = y,
160 };161 };
...@@ -170,17 +171,16 @@ const EmptyStruct = struct {...@@ -170,17 +171,16 @@ const EmptyStruct = struct {
170 }171 }
171};172};
172173
173
174test "return empty struct from fn" {174test "return empty struct from fn" {
175 _ = testReturnEmptyStructFromFn();175 _ = testReturnEmptyStructFromFn();
176}176}
177const EmptyStruct2 = struct {};177const EmptyStruct2 = struct {};
178fn testReturnEmptyStructFromFn() EmptyStruct2 {178fn testReturnEmptyStructFromFn() EmptyStruct2 {
179 return EmptyStruct2 {};179 return EmptyStruct2{};
180}180}
181181
182test "pass slice of empty struct to fn" {182test "pass slice of empty struct to fn" {
183 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);183 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{EmptyStruct2{}}) == 1);
184}184}
185fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {185fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {
186 return slice.len;186 return slice.len;
...@@ -192,7 +192,7 @@ const APackedStruct = packed struct {...@@ -192,7 +192,7 @@ const APackedStruct = packed struct {
192};192};
193193
194test "packed struct" {194test "packed struct" {
195 var foo = APackedStruct {195 var foo = APackedStruct{
196 .x = 1,196 .x = 1,
197 .y = 2,197 .y = 2,
198 };198 };
...@@ -201,14 +201,13 @@ test "packed struct" {...@@ -201,14 +201,13 @@ test "packed struct" {
201 assert(four == 4);201 assert(four == 4);
202}202}
203203
204
205const BitField1 = packed struct {204const BitField1 = packed struct {
206 a: u3,205 a: u3,
207 b: u3,206 b: u3,
208 c: u2,207 c: u2,
209};208};
210209
211const bit_field_1 = BitField1 {210const bit_field_1 = BitField1{
212 .a = 1,211 .a = 1,
213 .b = 2,212 .b = 2,
214 .c = 3,213 .c = 3,
...@@ -258,7 +257,7 @@ test "packed struct 24bits" {...@@ -258,7 +257,7 @@ test "packed struct 24bits" {
258 assert(@sizeOf(Foo96Bits) == 12);257 assert(@sizeOf(Foo96Bits) == 12);
259 }258 }
260259
261 var value = Foo96Bits {260 var value = Foo96Bits{
262 .a = 0,261 .a = 0,
263 .b = 0,262 .b = 0,
264 .c = 0,263 .c = 0,
...@@ -360,11 +359,15 @@ test "aligned array of packed struct" {...@@ -360,11 +359,15 @@ test "aligned array of packed struct" {
360 assert(ptr.a[1].b == 0xbb);359 assert(ptr.a[1].b == 0xbb);
361}360}
362361
363
364
365test "runtime struct initialization of bitfield" {362test "runtime struct initialization of bitfield" {
366 const s1 = Nibbles { .x = x1, .y = x1 };363 const s1 = Nibbles{
367 const s2 = Nibbles { .x = u4(x2), .y = u4(x2) };364 .x = x1,
365 .y = x1,
366 };
367 const s2 = Nibbles{
368 .x = u4(x2),
369 .y = u4(x2),
370 };
368371
369 assert(s1.x == x1);372 assert(s1.x == x1);
370 assert(s1.y == x1);373 assert(s1.y == x1);
...@@ -394,7 +397,7 @@ test "native bit field understands endianness" {...@@ -394,7 +397,7 @@ test "native bit field understands endianness" {
394 var all: u64 = 0x7765443322221111;397 var all: u64 = 0x7765443322221111;
395 var bytes: [8]u8 = undefined;398 var bytes: [8]u8 = undefined;
396 @memcpy(&bytes[0], @ptrCast(&u8, &all), 8);399 @memcpy(&bytes[0], @ptrCast(&u8, &all), 8);
397 var bitfields = *@ptrCast(&Bitfields, &bytes[0]);400 var bitfields = @ptrCast(&Bitfields, &bytes[0]).*;
398401
399 assert(bitfields.f1 == 0x1111);402 assert(bitfields.f1 == 0x1111);
400 assert(bitfields.f2 == 0x2222);403 assert(bitfields.f2 == 0x2222);
test/cases/struct_contains_null_ptr_itself.zig-1
...@@ -19,4 +19,3 @@ pub const Node = struct {...@@ -19,4 +19,3 @@ pub const Node = struct {
19pub const NodeLineComment = struct {19pub const NodeLineComment = struct {
20 base: Node,20 base: Node,
21};21};
22
test/cases/struct_contains_slice_of_itself.zig+7-7
...@@ -7,30 +7,30 @@ const Node = struct {...@@ -7,30 +7,30 @@ const Node = struct {
77
8test "struct contains slice of itself" {8test "struct contains slice of itself" {
9 var other_nodes = []Node{9 var other_nodes = []Node{
10 Node {10 Node{
11 .payload = 31,11 .payload = 31,
12 .children = []Node{},12 .children = []Node{},
13 },13 },
14 Node {14 Node{
15 .payload = 32,15 .payload = 32,
16 .children = []Node{},16 .children = []Node{},
17 },17 },
18 };18 };
19 var nodes = []Node {19 var nodes = []Node{
20 Node {20 Node{
21 .payload = 1,21 .payload = 1,
22 .children = []Node{},22 .children = []Node{},
23 },23 },
24 Node {24 Node{
25 .payload = 2,25 .payload = 2,
26 .children = []Node{},26 .children = []Node{},
27 },27 },
28 Node {28 Node{
29 .payload = 3,29 .payload = 3,
30 .children = other_nodes[0..],30 .children = other_nodes[0..],
31 },31 },
32 };32 };
33 const root = Node {33 const root = Node{
34 .payload = 1234,34 .payload = 1234,
35 .children = nodes[0..],35 .children = nodes[0..],
36 };36 };
test/cases/switch.zig+14-17
...@@ -6,7 +6,7 @@ test "switch with numbers" {...@@ -6,7 +6,7 @@ test "switch with numbers" {
66
7fn testSwitchWithNumbers(x: u32) void {7fn testSwitchWithNumbers(x: u32) void {
8 const result = switch (x) {8 const result = switch (x) {
9 1, 2, 3, 4 ... 8 => false,9 1, 2, 3, 4...8 => false,
10 13 => true,10 13 => true,
11 else => false,11 else => false,
12 };12 };
...@@ -22,9 +22,9 @@ test "switch with all ranges" {...@@ -22,9 +22,9 @@ test "switch with all ranges" {
2222
23fn testSwitchWithAllRanges(x: u32, y: u32) u32 {23fn testSwitchWithAllRanges(x: u32, y: u32) u32 {
24 return switch (x) {24 return switch (x) {
25 0 ... 100 => 1,25 0...100 => 1,
26 101 ... 200 => 2,26 101...200 => 2,
27 201 ... 300 => 3,27 201...300 => 3,
28 else => y,28 else => y,
29 };29 };
30}30}
...@@ -61,7 +61,6 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void {...@@ -61,7 +61,6 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void {
61 }61 }
62}62}
6363
64
65test "switch statement" {64test "switch statement" {
66 nonConstSwitch(SwitchStatmentFoo.C);65 nonConstSwitch(SwitchStatmentFoo.C);
67}66}
...@@ -81,11 +80,10 @@ const SwitchStatmentFoo = enum {...@@ -81,11 +80,10 @@ const SwitchStatmentFoo = enum {
81 D,80 D,
82};81};
8382
84
85test "switch prong with variable" {83test "switch prong with variable" {
86 switchProngWithVarFn(SwitchProngWithVarEnum { .One = 13});84 switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 });
87 switchProngWithVarFn(SwitchProngWithVarEnum { .Two = 13.0});85 switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 });
88 switchProngWithVarFn(SwitchProngWithVarEnum { .Meh = {}});86 switchProngWithVarFn(SwitchProngWithVarEnum{ .Meh = {} });
89}87}
90const SwitchProngWithVarEnum = union(enum) {88const SwitchProngWithVarEnum = union(enum) {
91 One: i32,89 One: i32,
...@@ -93,7 +91,7 @@ const SwitchProngWithVarEnum = union(enum) {...@@ -93,7 +91,7 @@ const SwitchProngWithVarEnum = union(enum) {
93 Meh: void,91 Meh: void,
94};92};
95fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) void {93fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) void {
96 switch(*a) {94 switch (a.*) {
97 SwitchProngWithVarEnum.One => |x| {95 SwitchProngWithVarEnum.One => |x| {
98 assert(x == 13);96 assert(x == 13);
99 },97 },
...@@ -112,9 +110,9 @@ test "switch on enum using pointer capture" {...@@ -112,9 +110,9 @@ test "switch on enum using pointer capture" {
112}110}
113111
114fn testSwitchEnumPtrCapture() void {112fn testSwitchEnumPtrCapture() void {
115 var value = SwitchProngWithVarEnum { .One = 1234 };113 var value = SwitchProngWithVarEnum{ .One = 1234 };
116 switch (value) {114 switch (value) {
117 SwitchProngWithVarEnum.One => |*x| *x += 1,115 SwitchProngWithVarEnum.One => |*x| x.* += 1,
118 else => unreachable,116 else => unreachable,
119 }117 }
120 switch (value) {118 switch (value) {
...@@ -135,14 +133,13 @@ fn returnsFive() i32 {...@@ -135,14 +133,13 @@ fn returnsFive() i32 {
135 return 5;133 return 5;
136}134}
137135
138
139const Number = union(enum) {136const Number = union(enum) {
140 One: u64,137 One: u64,
141 Two: u8,138 Two: u8,
142 Three: f32,139 Three: f32,
143};140};
144141
145const number = Number { .Three = 1.23 };142const number = Number{ .Three = 1.23 };
146143
147fn returnsFalse() bool {144fn returnsFalse() bool {
148 switch (number) {145 switch (number) {
...@@ -196,11 +193,11 @@ fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {...@@ -196,11 +193,11 @@ fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {
196193
197fn testSwitchHandleAllCasesRange(x: u8) u8 {194fn testSwitchHandleAllCasesRange(x: u8) u8 {
198 return switch (x) {195 return switch (x) {
199 0 ... 100 => u8(0),196 0...100 => u8(0),
200 101 ... 200 => 1,197 101...200 => 1,
201 201, 203 => 2,198 201, 203 => 2,
202 202 => 4,199 202 => 4,
203 204 ... 255 => 3,200 204...255 => 3,
204 };201 };
205}202}
206203
test/cases/switch_prong_err_enum.zig+4-2
...@@ -14,14 +14,16 @@ const FormValue = union(enum) {...@@ -14,14 +14,16 @@ const FormValue = union(enum) {
1414
15fn doThing(form_id: u64) error!FormValue {15fn doThing(form_id: u64) error!FormValue {
16 return switch (form_id) {16 return switch (form_id) {
17 17 => FormValue { .Address = try readOnce() },17 17 => FormValue{ .Address = try readOnce() },
18 else => error.InvalidDebugInfo,18 else => error.InvalidDebugInfo,
19 };19 };
20}20}
2121
22test "switch prong returns error enum" {22test "switch prong returns error enum" {
23 switch (doThing(17) catch unreachable) {23 switch (doThing(17) catch unreachable) {
24 FormValue.Address => |payload| { assert(payload == 1); },24 FormValue.Address => |payload| {
25 assert(payload == 1);
26 },
25 else => unreachable,27 else => unreachable,
26 }28 }
27 assert(read_count == 1);29 assert(read_count == 1);
test/cases/switch_prong_implicit_cast.zig+2-2
...@@ -7,8 +7,8 @@ const FormValue = union(enum) {...@@ -7,8 +7,8 @@ const FormValue = union(enum) {
77
8fn foo(id: u64) !FormValue {8fn foo(id: u64) !FormValue {
9 return switch (id) {9 return switch (id) {
10 2 => FormValue { .Two = true },10 2 => FormValue{ .Two = true },
11 1 => FormValue { .One = {} },11 1 => FormValue{ .One = {} },
12 else => return error.Whatever,12 else => return error.Whatever,
13 };13 };
14}14}
test/cases/syntax.zig-7
...@@ -2,11 +2,9 @@...@@ -2,11 +2,9 @@
22
3const struct_trailing_comma = struct { x: i32, y: i32, };3const struct_trailing_comma = struct { x: i32, y: i32, };
4const struct_no_comma = struct { x: i32, y: i32 };4const struct_no_comma = struct { x: i32, y: i32 };
5const struct_no_comma_void_type = struct { x: i32, y };
6const struct_fn_no_comma = struct { fn m() void {} y: i32 };5const struct_fn_no_comma = struct { fn m() void {} y: i32 };
76
8const enum_no_comma = enum { A, B };7const enum_no_comma = enum { A, B };
9const enum_no_comma_type = enum { A, B: i32 };
108
11fn container_init() void {9fn container_init() void {
12 const S = struct { x: i32, y: i32 };10 const S = struct { x: i32, y: i32 };
...@@ -36,16 +34,11 @@ fn switch_prongs(x: i32) void {...@@ -36,16 +34,11 @@ fn switch_prongs(x: i32) void {
3634
37const fn_no_comma = fn(i32, i32)void;35const fn_no_comma = fn(i32, i32)void;
38const fn_trailing_comma = fn(i32, i32,)void;36const fn_trailing_comma = fn(i32, i32,)void;
39const fn_vararg_trailing_comma = fn(i32, i32, ...,)void;
4037
41fn fn_calls() void {38fn fn_calls() void {
42 fn add(x: i32, y: i32,) i32 { x + y };39 fn add(x: i32, y: i32,) i32 { x + y };
43 _ = add(1, 2);40 _ = add(1, 2);
44 _ = add(1, 2,);41 _ = add(1, 2,);
45
46 fn swallow(x: ...,) void {};
47 _ = swallow(1,2,3,);
48 _ = swallow();
49}42}
5043
51fn asm_lists() void {44fn asm_lists() void {
test/cases/this.zig+1-1
...@@ -29,7 +29,7 @@ test "this refer to module call private fn" {...@@ -29,7 +29,7 @@ test "this refer to module call private fn" {
29}29}
3030
31test "this refer to container" {31test "this refer to container" {
32 var pt = Point(i32) {32 var pt = Point(i32){
33 .x = 12,33 .x = 12,
34 .y = 34,34 .y = 34,
35 };35 };
test/cases/try.zig+1-4
...@@ -3,13 +3,10 @@ const assert = @import("std").debug.assert;...@@ -3,13 +3,10 @@ const assert = @import("std").debug.assert;
3test "try on error union" {3test "try on error union" {
4 tryOnErrorUnionImpl();4 tryOnErrorUnionImpl();
5 comptime tryOnErrorUnionImpl();5 comptime tryOnErrorUnionImpl();
6
7}6}
87
9fn tryOnErrorUnionImpl() void {8fn tryOnErrorUnionImpl() void {
10 const x = if (returnsTen()) |val|9 const x = if (returnsTen()) |val| val + 1 else |err| switch (err) {
11 val + 1
12 else |err| switch (err) {
13 error.ItBroke, error.NoMem => 1,10 error.ItBroke, error.NoMem => 1,
14 error.CrappedOut => i32(2),11 error.CrappedOut => i32(2),
15 else => unreachable,12 else => unreachable,
test/cases/type_info.zig+184-142
...@@ -4,167 +4,199 @@ const TypeInfo = @import("builtin").TypeInfo;...@@ -4,167 +4,199 @@ const TypeInfo = @import("builtin").TypeInfo;
4const TypeId = @import("builtin").TypeId;4const TypeId = @import("builtin").TypeId;
55
6test "type info: tag type, void info" {6test "type info: tag type, void info" {
7 comptime {7 testBasic();
8 assert(@TagType(TypeInfo) == TypeId);8 comptime testBasic();
9 const void_info = @typeInfo(void);9}
10 assert(TypeId(void_info) == TypeId.Void);10
11 assert(void_info.Void == {});11fn testBasic() void {
12 }12 assert(@TagType(TypeInfo) == TypeId);
13 const void_info = @typeInfo(void);
14 assert(TypeId(void_info) == TypeId.Void);
15 assert(void_info.Void == {});
13}16}
1417
15test "type info: integer, floating point type info" {18test "type info: integer, floating point type info" {
16 comptime {19 testIntFloat();
17 const u8_info = @typeInfo(u8);20 comptime testIntFloat();
18 assert(TypeId(u8_info) == TypeId.Int);21}
19 assert(!u8_info.Int.is_signed);
20 assert(u8_info.Int.bits == 8);
2122
22 const f64_info = @typeInfo(f64);23fn testIntFloat() void {
23 assert(TypeId(f64_info) == TypeId.Float);24 const u8_info = @typeInfo(u8);
24 assert(f64_info.Float.bits == 64);25 assert(TypeId(u8_info) == TypeId.Int);
25 }26 assert(!u8_info.Int.is_signed);
27 assert(u8_info.Int.bits == 8);
28
29 const f64_info = @typeInfo(f64);
30 assert(TypeId(f64_info) == TypeId.Float);
31 assert(f64_info.Float.bits == 64);
26}32}
2733
28test "type info: pointer type info" {34test "type info: pointer type info" {
29 comptime {35 testPointer();
30 const u32_ptr_info = @typeInfo(&u32);36 comptime testPointer();
31 assert(TypeId(u32_ptr_info) == TypeId.Pointer);37}
32 assert(u32_ptr_info.Pointer.is_const == false);38
33 assert(u32_ptr_info.Pointer.is_volatile == false);39fn testPointer() void {
34 assert(u32_ptr_info.Pointer.alignment == 4);40 const u32_ptr_info = @typeInfo(&u32);
35 assert(u32_ptr_info.Pointer.child == u32);41 assert(TypeId(u32_ptr_info) == TypeId.Pointer);
36 }42 assert(u32_ptr_info.Pointer.is_const == false);
43 assert(u32_ptr_info.Pointer.is_volatile == false);
44 assert(u32_ptr_info.Pointer.alignment == 4);
45 assert(u32_ptr_info.Pointer.child == u32);
37}46}
3847
39test "type info: slice type info" {48test "type info: slice type info" {
40 comptime {49 testSlice();
41 const u32_slice_info = @typeInfo([]u32);50 comptime testSlice();
42 assert(TypeId(u32_slice_info) == TypeId.Slice);51}
43 assert(u32_slice_info.Slice.is_const == false);52
44 assert(u32_slice_info.Slice.is_volatile == false);53fn testSlice() void {
45 assert(u32_slice_info.Slice.alignment == 4);54 const u32_slice_info = @typeInfo([]u32);
46 assert(u32_slice_info.Slice.child == u32);55 assert(TypeId(u32_slice_info) == TypeId.Slice);
47 }56 assert(u32_slice_info.Slice.is_const == false);
57 assert(u32_slice_info.Slice.is_volatile == false);
58 assert(u32_slice_info.Slice.alignment == 4);
59 assert(u32_slice_info.Slice.child == u32);
48}60}
4961
50test "type info: array type info" {62test "type info: array type info" {
51 comptime {63 testArray();
52 const arr_info = @typeInfo([42]bool);64 comptime testArray();
53 assert(TypeId(arr_info) == TypeId.Array);65}
54 assert(arr_info.Array.len == 42);66
55 assert(arr_info.Array.child == bool);67fn testArray() void {
56 }68 const arr_info = @typeInfo([42]bool);
69 assert(TypeId(arr_info) == TypeId.Array);
70 assert(arr_info.Array.len == 42);
71 assert(arr_info.Array.child == bool);
57}72}
5873
59test "type info: nullable type info" {74test "type info: nullable type info" {
60 comptime {75 testNullable();
61 const null_info = @typeInfo(?void);76 comptime testNullable();
62 assert(TypeId(null_info) == TypeId.Nullable);77}
63 assert(null_info.Nullable.child == void);78
64 }79fn testNullable() void {
80 const null_info = @typeInfo(?void);
81 assert(TypeId(null_info) == TypeId.Nullable);
82 assert(null_info.Nullable.child == void);
65}83}
6684
67test "type info: promise info" {85test "type info: promise info" {
68 comptime {86 testPromise();
69 const null_promise_info = @typeInfo(promise);87 comptime testPromise();
70 assert(TypeId(null_promise_info) == TypeId.Promise);88}
71 assert(null_promise_info.Promise.child == @typeOf(undefined));
7289
73 const promise_info = @typeInfo(promise->usize);90fn testPromise() void {
74 assert(TypeId(promise_info) == TypeId.Promise);91 const null_promise_info = @typeInfo(promise);
75 assert(promise_info.Promise.child == usize);92 assert(TypeId(null_promise_info) == TypeId.Promise);
76 }93 assert(null_promise_info.Promise.child == @typeOf(undefined));
7794
95 const promise_info = @typeInfo(promise->usize);
96 assert(TypeId(promise_info) == TypeId.Promise);
97 assert(promise_info.Promise.child == usize);
78}98}
7999
80test "type info: error set, error union info" {100test "type info: error set, error union info" {
81 comptime {101 testErrorSet();
82 const TestErrorSet = error {102 comptime testErrorSet();
83 First,103}
84 Second,104
85 Third,105fn testErrorSet() void {
86 };106 const TestErrorSet = error{
87107 First,
88 const error_set_info = @typeInfo(TestErrorSet);108 Second,
89 assert(TypeId(error_set_info) == TypeId.ErrorSet);109 Third,
90 assert(error_set_info.ErrorSet.errors.len == 3);110 };
91 assert(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First"));111
92 assert(error_set_info.ErrorSet.errors[2].value == usize(TestErrorSet.Third));112 const error_set_info = @typeInfo(TestErrorSet);
93113 assert(TypeId(error_set_info) == TypeId.ErrorSet);
94 const error_union_info = @typeInfo(TestErrorSet!usize);114 assert(error_set_info.ErrorSet.errors.len == 3);
95 assert(TypeId(error_union_info) == TypeId.ErrorUnion);115 assert(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First"));
96 assert(error_union_info.ErrorUnion.error_set == TestErrorSet);116 assert(error_set_info.ErrorSet.errors[2].value == usize(TestErrorSet.Third));
97 assert(error_union_info.ErrorUnion.payload == usize);117
98 }118 const error_union_info = @typeInfo(TestErrorSet!usize);
119 assert(TypeId(error_union_info) == TypeId.ErrorUnion);
120 assert(error_union_info.ErrorUnion.error_set == TestErrorSet);
121 assert(error_union_info.ErrorUnion.payload == usize);
99}122}
100123
101test "type info: enum info" {124test "type info: enum info" {
102 comptime {125 testEnum();
103 const Os = @import("builtin").Os;126 comptime testEnum();
127}
104128
105 const os_info = @typeInfo(Os);129fn testEnum() void {
106 assert(TypeId(os_info) == TypeId.Enum);130 const Os = @import("builtin").Os;
107 assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);131
108 assert(os_info.Enum.fields.len == 32);132 const os_info = @typeInfo(Os);
109 assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas"));133 assert(TypeId(os_info) == TypeId.Enum);
110 assert(os_info.Enum.fields[10].value == 10);134 assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);
111 assert(os_info.Enum.tag_type == u5);135 assert(os_info.Enum.fields.len == 32);
112 assert(os_info.Enum.defs.len == 0);136 assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas"));
113 }137 assert(os_info.Enum.fields[10].value == 10);
138 assert(os_info.Enum.tag_type == u5);
139 assert(os_info.Enum.defs.len == 0);
114}140}
115141
116test "type info: union info" {142test "type info: union info" {
117 comptime {143 testUnion();
118 const typeinfo_info = @typeInfo(TypeInfo);144 comptime testUnion();
119 assert(TypeId(typeinfo_info) == TypeId.Union);145}
120 assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);146
121 assert(typeinfo_info.Union.tag_type == TypeId);147fn testUnion() void {
122 assert(typeinfo_info.Union.fields.len == 26);148 const typeinfo_info = @typeInfo(TypeInfo);
123 assert(typeinfo_info.Union.fields[4].enum_field != null);149 assert(TypeId(typeinfo_info) == TypeId.Union);
124 assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);150 assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
125 assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));151 assert(typeinfo_info.Union.tag_type == TypeId);
126 assert(typeinfo_info.Union.defs.len == 21);152 assert(typeinfo_info.Union.fields.len == 26);
127153 assert(typeinfo_info.Union.fields[4].enum_field != null);
128 const TestNoTagUnion = union {154 assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);
129 Foo: void,155 assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
130 Bar: u32,156 assert(typeinfo_info.Union.defs.len == 21);
131 };157
132158 const TestNoTagUnion = union {
133 const notag_union_info = @typeInfo(TestNoTagUnion);159 Foo: void,
134 assert(TypeId(notag_union_info) == TypeId.Union);160 Bar: u32,
135 assert(notag_union_info.Union.tag_type == @typeOf(undefined));161 };
136 assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);162
137 assert(notag_union_info.Union.fields.len == 2);163 const notag_union_info = @typeInfo(TestNoTagUnion);
138 assert(notag_union_info.Union.fields[0].enum_field == null);164 assert(TypeId(notag_union_info) == TypeId.Union);
139 assert(notag_union_info.Union.fields[1].field_type == u32);165 assert(notag_union_info.Union.tag_type == @typeOf(undefined));
140166 assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
141 const TestExternUnion = extern union {167 assert(notag_union_info.Union.fields.len == 2);
142 foo: &c_void,168 assert(notag_union_info.Union.fields[0].enum_field == null);
143 };169 assert(notag_union_info.Union.fields[1].field_type == u32);
144170
145 const extern_union_info = @typeInfo(TestExternUnion);171 const TestExternUnion = extern union {
146 assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);172 foo: &c_void,
147 assert(extern_union_info.Union.tag_type == @typeOf(undefined));173 };
148 assert(extern_union_info.Union.fields[0].enum_field == null);174
149 assert(extern_union_info.Union.fields[0].field_type == &c_void);175 const extern_union_info = @typeInfo(TestExternUnion);
150 }176 assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);
177 assert(extern_union_info.Union.tag_type == @typeOf(undefined));
178 assert(extern_union_info.Union.fields[0].enum_field == null);
179 assert(extern_union_info.Union.fields[0].field_type == &c_void);
151}180}
152181
153test "type info: struct info" {182test "type info: struct info" {
154 comptime {183 testStruct();
155 const struct_info = @typeInfo(TestStruct);184 comptime testStruct();
156 assert(TypeId(struct_info) == TypeId.Struct);185}
157 assert(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);186
158 assert(struct_info.Struct.fields.len == 3);187fn testStruct() void {
159 assert(struct_info.Struct.fields[1].offset == null);188 const struct_info = @typeInfo(TestStruct);
160 assert(struct_info.Struct.fields[2].field_type == &TestStruct);189 assert(TypeId(struct_info) == TypeId.Struct);
161 assert(struct_info.Struct.defs.len == 2);190 assert(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);
162 assert(struct_info.Struct.defs[0].is_pub);191 assert(struct_info.Struct.fields.len == 3);
163 assert(!struct_info.Struct.defs[0].data.Fn.is_extern);192 assert(struct_info.Struct.fields[1].offset == null);
164 assert(struct_info.Struct.defs[0].data.Fn.lib_name == null);193 assert(struct_info.Struct.fields[2].field_type == &TestStruct);
165 assert(struct_info.Struct.defs[0].data.Fn.return_type == void);194 assert(struct_info.Struct.defs.len == 2);
166 assert(struct_info.Struct.defs[0].data.Fn.fn_type == fn(&const TestStruct)void);195 assert(struct_info.Struct.defs[0].is_pub);
167 }196 assert(!struct_info.Struct.defs[0].data.Fn.is_extern);
197 assert(struct_info.Struct.defs[0].data.Fn.lib_name == null);
198 assert(struct_info.Struct.defs[0].data.Fn.return_type == void);
199 assert(struct_info.Struct.defs[0].data.Fn.fn_type == fn(&const TestStruct) void);
168}200}
169201
170const TestStruct = packed struct {202const TestStruct = packed struct {
...@@ -178,23 +210,33 @@ const TestStruct = packed struct {...@@ -178,23 +210,33 @@ const TestStruct = packed struct {
178};210};
179211
180test "type info: function type info" {212test "type info: function type info" {
181 comptime {213 testFunction();
182 const fn_info = @typeInfo(@typeOf(foo));214 comptime testFunction();
183 assert(TypeId(fn_info) == TypeId.Fn);215}
184 assert(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);216
185 assert(fn_info.Fn.is_generic);217fn testFunction() void {
186 assert(fn_info.Fn.args.len == 2);218 const fn_info = @typeInfo(@typeOf(foo));
187 assert(fn_info.Fn.is_var_args);219 assert(TypeId(fn_info) == TypeId.Fn);
188 assert(fn_info.Fn.return_type == @typeOf(undefined));220 assert(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);
189 assert(fn_info.Fn.async_allocator_type == @typeOf(undefined));221 assert(fn_info.Fn.is_generic);
190222 assert(fn_info.Fn.args.len == 2);
191 const test_instance: TestStruct = undefined;223 assert(fn_info.Fn.is_var_args);
192 const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));224 assert(fn_info.Fn.return_type == @typeOf(undefined));
193 assert(TypeId(bound_fn_info) == TypeId.BoundFn);225 assert(fn_info.Fn.async_allocator_type == @typeOf(undefined));
194 assert(bound_fn_info.BoundFn.args[0].arg_type == &const TestStruct);226
195 }227 const test_instance: TestStruct = undefined;
228 const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
229 assert(TypeId(bound_fn_info) == TypeId.BoundFn);
230 assert(bound_fn_info.BoundFn.args[0].arg_type == &const TestStruct);
196}231}
197232
198fn foo(comptime a: usize, b: bool, args: ...) usize {233fn foo(comptime a: usize, b: bool, args: ...) usize {
199 return 0;234 return 0;
200}235}
236
237test "typeInfo with comptime parameter in struct fn def" {
238 const S = struct {
239 pub fn func(comptime x: f32) void {}
240 };
241 comptime var info = @typeInfo(S);
242}
test/cases/undefined.zig+2-2
...@@ -63,6 +63,6 @@ test "assign undefined to struct with method" {...@@ -63,6 +63,6 @@ test "assign undefined to struct with method" {
63}63}
6464
65test "type name of undefined" {65test "type name of undefined" {
66 const x = undefined;66 const x = undefined;
67 assert(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));67 assert(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));
68}68}
test/cases/union.zig+52-39
...@@ -10,47 +10,50 @@ const Agg = struct {...@@ -10,47 +10,50 @@ const Agg = struct {
10 val2: Value,10 val2: Value,
11};11};
1212
13const v1 = Value { .Int = 1234 };13const v1 = Value{ .Int = 1234 };
14const v2 = Value { .Array = []u8{3} ** 9 };14const v2 = Value{ .Array = []u8{3} ** 9 };
1515
16const err = (error!Agg)(Agg {16const err = (error!Agg)(Agg{
17 .val1 = v1,17 .val1 = v1,
18 .val2 = v2,18 .val2 = v2,
19});19});
2020
21const array = []Value { v1, v2, v1, v2};21const array = []Value{
2222 v1,
23 v2,
24 v1,
25 v2,
26};
2327
24test "unions embedded in aggregate types" {28test "unions embedded in aggregate types" {
25 switch (array[1]) {29 switch (array[1]) {
26 Value.Array => |arr| assert(arr[4] == 3),30 Value.Array => |arr| assert(arr[4] == 3),
27 else => unreachable,31 else => unreachable,
28 }32 }
29 switch((err catch unreachable).val1) {33 switch ((err catch unreachable).val1) {
30 Value.Int => |x| assert(x == 1234),34 Value.Int => |x| assert(x == 1234),
31 else => unreachable,35 else => unreachable,
32 }36 }
33}37}
3438
35
36const Foo = union {39const Foo = union {
37 float: f64,40 float: f64,
38 int: i32,41 int: i32,
39};42};
4043
41test "basic unions" {44test "basic unions" {
42 var foo = Foo { .int = 1 };45 var foo = Foo{ .int = 1 };
43 assert(foo.int == 1);46 assert(foo.int == 1);
44 foo = Foo {.float = 12.34};47 foo = Foo{ .float = 12.34 };
45 assert(foo.float == 12.34);48 assert(foo.float == 12.34);
46}49}
4750
48test "comptime union field access" {51test "comptime union field access" {
49 comptime {52 comptime {
50 var foo = Foo { .int = 0 };53 var foo = Foo{ .int = 0 };
51 assert(foo.int == 0);54 assert(foo.int == 0);
5255
53 foo = Foo { .float = 42.42 };56 foo = Foo{ .float = 42.42 };
54 assert(foo.float == 42.42);57 assert(foo.float == 42.42);
55 }58 }
56}59}
...@@ -66,11 +69,11 @@ test "init union with runtime value" {...@@ -66,11 +69,11 @@ test "init union with runtime value" {
66}69}
6770
68fn setFloat(foo: &Foo, x: f64) void {71fn setFloat(foo: &Foo, x: f64) void {
69 *foo = Foo { .float = x };72 foo.* = Foo{ .float = x };
70}73}
7174
72fn setInt(foo: &Foo, x: i32) void {75fn setInt(foo: &Foo, x: i32) void {
73 *foo = Foo { .int = x };76 foo.* = Foo{ .int = x };
74}77}
7578
76const FooExtern = extern union {79const FooExtern = extern union {
...@@ -79,13 +82,12 @@ const FooExtern = extern union {...@@ -79,13 +82,12 @@ const FooExtern = extern union {
79};82};
8083
81test "basic extern unions" {84test "basic extern unions" {
82 var foo = FooExtern { .int = 1 };85 var foo = FooExtern{ .int = 1 };
83 assert(foo.int == 1);86 assert(foo.int == 1);
84 foo.float = 12.34;87 foo.float = 12.34;
85 assert(foo.float == 12.34);88 assert(foo.float == 12.34);
86}89}
8790
88
89const Letter = enum {91const Letter = enum {
90 A,92 A,
91 B,93 B,
...@@ -103,12 +105,12 @@ test "union with specified enum tag" {...@@ -103,12 +105,12 @@ test "union with specified enum tag" {
103}105}
104106
105fn doTest() void {107fn doTest() void {
106 assert(bar(Payload {.A = 1234}) == -10);108 assert(bar(Payload{ .A = 1234 }) == -10);
107}109}
108110
109fn bar(value: &const Payload) i32 {111fn bar(value: &const Payload) i32 {
110 assert(Letter(*value) == Letter.A);112 assert(Letter(value.*) == Letter.A);
111 return switch (*value) {113 return switch (value.*) {
112 Payload.A => |x| return x - 1244,114 Payload.A => |x| return x - 1244,
113 Payload.B => |x| if (x == 12.34) i32(20) else 21,115 Payload.B => |x| if (x == 12.34) i32(20) else 21,
114 Payload.C => |x| if (x) i32(30) else 31,116 Payload.C => |x| if (x) i32(30) else 31,
...@@ -141,13 +143,13 @@ const MultipleChoice2 = union(enum(u32)) {...@@ -141,13 +143,13 @@ const MultipleChoice2 = union(enum(u32)) {
141143
142test "union(enum(u32)) with specified and unspecified tag values" {144test "union(enum(u32)) with specified and unspecified tag values" {
143 comptime assert(@TagType(@TagType(MultipleChoice2)) == u32);145 comptime assert(@TagType(@TagType(MultipleChoice2)) == u32);
144 testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 {.C = 123});146 testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
145 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 { .C = 123} );147 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
146}148}
147149
148fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void {150fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void {
149 assert(u32(@TagType(MultipleChoice2)(*x)) == 60);151 assert(u32(@TagType(MultipleChoice2)(x.*)) == 60);
150 assert(1123 == switch (*x) {152 assert(1123 == switch (x.*) {
151 MultipleChoice2.A => 1,153 MultipleChoice2.A => 1,
152 MultipleChoice2.B => 2,154 MultipleChoice2.B => 2,
153 MultipleChoice2.C => |v| i32(1000) + v,155 MultipleChoice2.C => |v| i32(1000) + v,
...@@ -160,10 +162,9 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void...@@ -160,10 +162,9 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void
160 });162 });
161}163}
162164
163
164const ExternPtrOrInt = extern union {165const ExternPtrOrInt = extern union {
165 ptr: &u8,166 ptr: &u8,
166 int: u64167 int: u64,
167};168};
168test "extern union size" {169test "extern union size" {
169 comptime assert(@sizeOf(ExternPtrOrInt) == 8);170 comptime assert(@sizeOf(ExternPtrOrInt) == 8);
...@@ -171,7 +172,7 @@ test "extern union size" {...@@ -171,7 +172,7 @@ test "extern union size" {
171172
172const PackedPtrOrInt = packed union {173const PackedPtrOrInt = packed union {
173 ptr: &u8,174 ptr: &u8,
174 int: u64175 int: u64,
175};176};
176test "extern union size" {177test "extern union size" {
177 comptime assert(@sizeOf(PackedPtrOrInt) == 8);178 comptime assert(@sizeOf(PackedPtrOrInt) == 8);
...@@ -184,8 +185,16 @@ test "union with only 1 field which is void should be zero bits" {...@@ -184,8 +185,16 @@ test "union with only 1 field which is void should be zero bits" {
184 comptime assert(@sizeOf(ZeroBits) == 0);185 comptime assert(@sizeOf(ZeroBits) == 0);
185}186}
186187
187const TheTag = enum {A, B, C};188const TheTag = enum {
188const TheUnion = union(TheTag) { A: i32, B: i32, C: i32 };189 A,
190 B,
191 C,
192};
193const TheUnion = union(TheTag) {
194 A: i32,
195 B: i32,
196 C: i32,
197};
189test "union field access gives the enum values" {198test "union field access gives the enum values" {
190 assert(TheUnion.A == TheTag.A);199 assert(TheUnion.A == TheTag.A);
191 assert(TheUnion.B == TheTag.B);200 assert(TheUnion.B == TheTag.B);
...@@ -193,20 +202,28 @@ test "union field access gives the enum values" {...@@ -193,20 +202,28 @@ test "union field access gives the enum values" {
193}202}
194203
195test "cast union to tag type of union" {204test "cast union to tag type of union" {
196 testCastUnionToTagType(TheUnion {.B = 1234});205 testCastUnionToTagType(TheUnion{ .B = 1234 });
197 comptime testCastUnionToTagType(TheUnion {.B = 1234});206 comptime testCastUnionToTagType(TheUnion{ .B = 1234 });
198}207}
199208
200fn testCastUnionToTagType(x: &const TheUnion) void {209fn testCastUnionToTagType(x: &const TheUnion) void {
201 assert(TheTag(*x) == TheTag.B);210 assert(TheTag(x.*) == TheTag.B);
202}211}
203212
204test "cast tag type of union to union" {213test "cast tag type of union to union" {
205 var x: Value2 = Letter2.B;214 var x: Value2 = Letter2.B;
206 assert(Letter2(x) == Letter2.B);215 assert(Letter2(x) == Letter2.B);
207}216}
208const Letter2 = enum { A, B, C };217const Letter2 = enum {
209const Value2 = union(Letter2) { A: i32, B, C, };218 A,
219 B,
220 C,
221};
222const Value2 = union(Letter2) {
223 A: i32,
224 B,
225 C,
226};
210227
211test "implicit cast union to its tag type" {228test "implicit cast union to its tag type" {
212 var x: Value2 = Letter2.B;229 var x: Value2 = Letter2.B;
...@@ -227,19 +244,16 @@ const TheUnion2 = union(enum) {...@@ -227,19 +244,16 @@ const TheUnion2 = union(enum) {
227};244};
228245
229fn assertIsTheUnion2Item1(value: &const TheUnion2) void {246fn assertIsTheUnion2Item1(value: &const TheUnion2) void {
230 assert(*value == TheUnion2.Item1);247 assert(value.* == TheUnion2.Item1);
231}248}
232249
233
234pub const PackThis = union(enum) {250pub const PackThis = union(enum) {
235 Invalid: bool,251 Invalid: bool,
236 StringLiteral: u2,252 StringLiteral: u2,
237};253};
238254
239test "constant packed union" {255test "constant packed union" {
240 testConstPackedUnion([]PackThis {256 testConstPackedUnion([]PackThis{PackThis{ .StringLiteral = 1 }});
241 PackThis { .StringLiteral = 1 },
242 });
243}257}
244258
245fn testConstPackedUnion(expected_tokens: []const PackThis) void {259fn testConstPackedUnion(expected_tokens: []const PackThis) void {
...@@ -252,7 +266,7 @@ test "switch on union with only 1 field" {...@@ -252,7 +266,7 @@ test "switch on union with only 1 field" {
252 switch (r) {266 switch (r) {
253 PartialInst.Compiled => {267 PartialInst.Compiled => {
254 var z: PartialInstWithPayload = undefined;268 var z: PartialInstWithPayload = undefined;
255 z = PartialInstWithPayload { .Compiled = 1234 };269 z = PartialInstWithPayload{ .Compiled = 1234 };
256 switch (z) {270 switch (z) {
257 PartialInstWithPayload.Compiled => |x| {271 PartialInstWithPayload.Compiled => |x| {
258 assert(x == 1234);272 assert(x == 1234);
...@@ -272,7 +286,6 @@ const PartialInstWithPayload = union(enum) {...@@ -272,7 +286,6 @@ const PartialInstWithPayload = union(enum) {
272 Compiled: i32,286 Compiled: i32,
273};287};
274288
275
276test "access a member of tagged union with conflicting enum tag name" {289test "access a member of tagged union with conflicting enum tag name" {
277 const Bar = union(enum) {290 const Bar = union(enum) {
278 A: A,291 A: A,
test/cases/var_args.zig+16-9
...@@ -2,9 +2,12 @@ const assert = @import("std").debug.assert;...@@ -2,9 +2,12 @@ const assert = @import("std").debug.assert;
22
3fn add(args: ...) i32 {3fn add(args: ...) i32 {
4 var sum = i32(0);4 var sum = i32(0);
5 {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {5 {
6 sum += args[i];6 comptime var i: usize = 0;
7 }}7 inline while (i < args.len) : (i += 1) {
8 sum += args[i];
9 }
10 }
8 return sum;11 return sum;
9}12}
1013
...@@ -55,18 +58,23 @@ fn extraFn(extra: u32, args: ...) usize {...@@ -55,18 +58,23 @@ fn extraFn(extra: u32, args: ...) usize {
55 return args.len;58 return args.len;
56}59}
5760
61const foos = []fn(...) bool{
62 foo1,
63 foo2,
64};
5865
59const foos = []fn(...) bool { foo1, foo2 };66fn foo1(args: ...) bool {
6067 return true;
61fn foo1(args: ...) bool { return true; }68}
62fn foo2(args: ...) bool { return false; }69fn foo2(args: ...) bool {
70 return false;
71}
6372
64test "array of var args functions" {73test "array of var args functions" {
65 assert(foos[0]());74 assert(foos[0]());
66 assert(!foos[1]());75 assert(!foos[1]());
67}76}
6877
69
70test "pass array and slice of same array to var args should have same pointers" {78test "pass array and slice of same array to var args should have same pointers" {
71 const array = "hi";79 const array = "hi";
72 const slice: []const u8 = array;80 const slice: []const u8 = array;
...@@ -79,7 +87,6 @@ fn assertSlicePtrsEql(args: ...) void {...@@ -79,7 +87,6 @@ fn assertSlicePtrsEql(args: ...) void {
79 assert(s1.ptr == s2.ptr);87 assert(s1.ptr == s2.ptr);
80}88}
8189
82
83test "pass zero length array to var args param" {90test "pass zero length array to var args param" {
84 doNothingWithFirstArg("");91 doNothingWithFirstArg("");
85}92}
test/cases/void.zig+1-1
...@@ -8,7 +8,7 @@ const Foo = struct {...@@ -8,7 +8,7 @@ const Foo = struct {
88
9test "compare void with void compile time known" {9test "compare void with void compile time known" {
10 comptime {10 comptime {
11 const foo = Foo {11 const foo = Foo{
12 .a = {},12 .a = {},
13 .b = 1,13 .b = 1,
14 .c = {},14 .c = {},
test/cases/while.zig+41-24
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
22
3test "while loop" {3test "while loop" {
4 var i : i32 = 0;4 var i: i32 = 0;
5 while (i < 4) {5 while (i < 4) {
6 i += 1;6 i += 1;
7 }7 }
...@@ -35,7 +35,7 @@ test "continue and break" {...@@ -35,7 +35,7 @@ test "continue and break" {
35}35}
36var continue_and_break_counter: i32 = 0;36var continue_and_break_counter: i32 = 0;
37fn runContinueAndBreakTest() void {37fn runContinueAndBreakTest() void {
38 var i : i32 = 0;38 var i: i32 = 0;
39 while (true) {39 while (true) {
40 continue_and_break_counter += 2;40 continue_and_break_counter += 2;
41 i += 1;41 i += 1;
...@@ -58,10 +58,13 @@ fn returnWithImplicitCastFromWhileLoopTest() error!void {...@@ -58,10 +58,13 @@ fn returnWithImplicitCastFromWhileLoopTest() error!void {
5858
59test "while with continue expression" {59test "while with continue expression" {
60 var sum: i32 = 0;60 var sum: i32 = 0;
61 {var i: i32 = 0; while (i < 10) : (i += 1) {61 {
62 if (i == 5) continue;62 var i: i32 = 0;
63 sum += i;63 while (i < 10) : (i += 1) {
64 }}64 if (i == 5) continue;
65 sum += i;
66 }
67 }
65 assert(sum == 40);68 assert(sum == 40);
66}69}
6770
...@@ -117,17 +120,13 @@ test "while with error union condition" {...@@ -117,17 +120,13 @@ test "while with error union condition" {
117120
118var numbers_left: i32 = undefined;121var numbers_left: i32 = undefined;
119fn getNumberOrErr() error!i32 {122fn getNumberOrErr() error!i32 {
120 return if (numbers_left == 0)123 return if (numbers_left == 0) error.OutOfNumbers else x: {
121 error.OutOfNumbers
122 else x: {
123 numbers_left -= 1;124 numbers_left -= 1;
124 break :x numbers_left;125 break :x numbers_left;
125 };126 };
126}127}
127fn getNumberOrNull() ?i32 {128fn getNumberOrNull() ?i32 {
128 return if (numbers_left == 0)129 return if (numbers_left == 0) null else x: {
129 null
130 else x: {
131 numbers_left -= 1;130 numbers_left -= 1;
132 break :x numbers_left;131 break :x numbers_left;
133 };132 };
...@@ -136,42 +135,48 @@ fn getNumberOrNull() ?i32 {...@@ -136,42 +135,48 @@ fn getNumberOrNull() ?i32 {
136test "while on nullable with else result follow else prong" {135test "while on nullable with else result follow else prong" {
137 const result = while (returnNull()) |value| {136 const result = while (returnNull()) |value| {
138 break value;137 break value;
139 } else i32(2);138 } else
139 i32(2);
140 assert(result == 2);140 assert(result == 2);
141}141}
142142
143test "while on nullable with else result follow break prong" {143test "while on nullable with else result follow break prong" {
144 const result = while (returnMaybe(10)) |value| {144 const result = while (returnMaybe(10)) |value| {
145 break value;145 break value;
146 } else i32(2);146 } else
147 i32(2);
147 assert(result == 10);148 assert(result == 10);
148}149}
149150
150test "while on error union with else result follow else prong" {151test "while on error union with else result follow else prong" {
151 const result = while (returnError()) |value| {152 const result = while (returnError()) |value| {
152 break value;153 break value;
153 } else |err| i32(2);154 } else |err|
155 i32(2);
154 assert(result == 2);156 assert(result == 2);
155}157}
156158
157test "while on error union with else result follow break prong" {159test "while on error union with else result follow break prong" {
158 const result = while (returnSuccess(10)) |value| {160 const result = while (returnSuccess(10)) |value| {
159 break value;161 break value;
160 } else |err| i32(2);162 } else |err|
163 i32(2);
161 assert(result == 10);164 assert(result == 10);
162}165}
163166
164test "while on bool with else result follow else prong" {167test "while on bool with else result follow else prong" {
165 const result = while (returnFalse()) {168 const result = while (returnFalse()) {
166 break i32(10);169 break i32(10);
167 } else i32(2);170 } else
171 i32(2);
168 assert(result == 2);172 assert(result == 2);
169}173}
170174
171test "while on bool with else result follow break prong" {175test "while on bool with else result follow break prong" {
172 const result = while (returnTrue()) {176 const result = while (returnTrue()) {
173 break i32(10);177 break i32(10);
174 } else i32(2);178 } else
179 i32(2);
175 assert(result == 10);180 assert(result == 10);
176}181}
177182
...@@ -202,9 +207,21 @@ fn testContinueOuter() void {...@@ -202,9 +207,21 @@ fn testContinueOuter() void {
202 }207 }
203}208}
204209
205fn returnNull() ?i32 { return null; }210fn returnNull() ?i32 {
206fn returnMaybe(x: i32) ?i32 { return x; }211 return null;
207fn returnError() error!i32 { return error.YouWantedAnError; }212}
208fn returnSuccess(x: i32) error!i32 { return x; }213fn returnMaybe(x: i32) ?i32 {
209fn returnFalse() bool { return false; }214 return x;
210fn returnTrue() bool { return true; }215}
216fn returnError() error!i32 {
217 return error.YouWantedAnError;
218}
219fn returnSuccess(x: i32) error!i32 {
220 return x;
221}
222fn returnFalse() bool {
223 return false;
224}
225fn returnTrue() bool {
226 return true;
227}
test/compare_output.zig+6-6
...@@ -131,7 +131,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {...@@ -131,7 +131,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
131 \\const is_windows = builtin.os == builtin.Os.windows;131 \\const is_windows = builtin.os == builtin.Os.windows;
132 \\const c = @cImport({132 \\const c = @cImport({
133 \\ if (is_windows) {133 \\ if (is_windows) {
134 \\ // See https://github.com/zig-lang/zig/issues/515134 \\ // See https://github.com/ziglang/zig/issues/515
135 \\ @cDefine("_NO_CRT_STDIO_INLINE", "1");135 \\ @cDefine("_NO_CRT_STDIO_INLINE", "1");
136 \\ @cInclude("io.h");136 \\ @cInclude("io.h");
137 \\ @cInclude("fcntl.h");137 \\ @cInclude("fcntl.h");
...@@ -287,9 +287,9 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {...@@ -287,9 +287,9 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
287 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) c_int {287 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) c_int {
288 \\ const a_int = @ptrCast(&align(1) const i32, a ?? unreachable);288 \\ const a_int = @ptrCast(&align(1) const i32, a ?? unreachable);
289 \\ const b_int = @ptrCast(&align(1) const i32, b ?? unreachable);289 \\ const b_int = @ptrCast(&align(1) const i32, b ?? unreachable);
290 \\ if (*a_int < *b_int) {290 \\ if (a_int.* < b_int.*) {
291 \\ return -1;291 \\ return -1;
292 \\ } else if (*a_int > *b_int) {292 \\ } else if (a_int.* > b_int.*) {
293 \\ return 1;293 \\ return 1;
294 \\ } else {294 \\ } else {
295 \\ return 0;295 \\ return 0;
...@@ -316,7 +316,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {...@@ -316,7 +316,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
316 \\const is_windows = builtin.os == builtin.Os.windows;316 \\const is_windows = builtin.os == builtin.Os.windows;
317 \\const c = @cImport({317 \\const c = @cImport({
318 \\ if (is_windows) {318 \\ if (is_windows) {
319 \\ // See https://github.com/zig-lang/zig/issues/515319 \\ // See https://github.com/ziglang/zig/issues/515
320 \\ @cDefine("_NO_CRT_STDIO_INLINE", "1");320 \\ @cDefine("_NO_CRT_STDIO_INLINE", "1");
321 \\ @cInclude("io.h");321 \\ @cInclude("io.h");
322 \\ @cInclude("fcntl.h");322 \\ @cInclude("fcntl.h");
...@@ -475,7 +475,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {...@@ -475,7 +475,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
475 \\475 \\
476 );476 );
477477
478 tc.setCommandLineArgs([][]const u8 {478 tc.setCommandLineArgs([][]const u8{
479 "first arg",479 "first arg",
480 "'a' 'b' \\",480 "'a' 'b' \\",
481 "bare",481 "bare",
...@@ -516,7 +516,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {...@@ -516,7 +516,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
516 \\516 \\
517 );517 );
518518
519 tc.setCommandLineArgs([][]const u8 {519 tc.setCommandLineArgs([][]const u8{
520 "first arg",520 "first arg",
521 "'a' 'b' \\",521 "'a' 'b' \\",
522 "bare",522 "bare",
test/compile_errors.zig+1514-730
...@@ -1,10 +1,11 @@...@@ -1,10 +1,11 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: &tests.CompileErrorContext) void {3pub fn addCases(cases: &tests.CompileErrorContext) void {
4 cases.add("invalid deref on switch target",4 cases.add(
5 "invalid deref on switch target",
5 \\comptime {6 \\comptime {
6 \\ var tile = Tile.Empty;7 \\ var tile = Tile.Empty;
7 \\ switch (*tile) {8 \\ switch (tile.*) {
8 \\ Tile.Empty => {},9 \\ Tile.Empty => {},
9 \\ Tile.Filled => {},10 \\ Tile.Filled => {},
10 \\ }11 \\ }
...@@ -14,15 +15,19 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -14,15 +15,19 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
14 \\ Filled,15 \\ Filled,
15 \\};16 \\};
16 ,17 ,
17 ".tmp_source.zig:3:13: error: invalid deref on switch target");18 ".tmp_source.zig:3:17: error: invalid deref on switch target",
19 );
1820
19 cases.add("invalid field access in comptime",21 cases.add(
22 "invalid field access in comptime",
20 \\comptime { var x = doesnt_exist.whatever; }23 \\comptime { var x = doesnt_exist.whatever; }
21 ,24 ,
22 ".tmp_source.zig:1:20: error: use of undeclared identifier 'doesnt_exist'");25 ".tmp_source.zig:1:20: error: use of undeclared identifier 'doesnt_exist'",
26 );
2327
24 cases.add("suspend inside suspend block",28 cases.add(
25 \\const std = @import("std");29 "suspend inside suspend block",
30 \\const std = @import("std",);
26 \\31 \\
27 \\export fn entry() void {32 \\export fn entry() void {
28 \\ var buf: [500]u8 = undefined;33 \\ var buf: [500]u8 = undefined;
...@@ -39,27 +44,32 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -39,27 +44,32 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
39 \\}44 \\}
40 ,45 ,
41 ".tmp_source.zig:12:9: error: cannot suspend inside suspend block",46 ".tmp_source.zig:12:9: error: cannot suspend inside suspend block",
42 ".tmp_source.zig:11:5: note: other suspend block here");47 ".tmp_source.zig:11:5: note: other suspend block here",
48 );
4349
44 cases.add("assign inline fn to non-comptime var",50 cases.add(
51 "assign inline fn to non-comptime var",
45 \\export fn entry() void {52 \\export fn entry() void {
46 \\ var a = b;53 \\ var a = b;
47 \\}54 \\}
48 \\inline fn b() void { }55 \\inline fn b() void { }
49 ,56 ,
50 ".tmp_source.zig:2:5: error: functions marked inline must be stored in const or comptime var",57 ".tmp_source.zig:2:5: error: functions marked inline must be stored in const or comptime var",
51 ".tmp_source.zig:4:8: note: declared here");58 ".tmp_source.zig:4:8: note: declared here",
59 );
5260
53 cases.add("wrong type passed to @panic",61 cases.add(
62 "wrong type passed to @panic",
54 \\export fn entry() void {63 \\export fn entry() void {
55 \\ var e = error.Foo;64 \\ var e = error.Foo;
56 \\ @panic(e);65 \\ @panic(e);
57 \\}66 \\}
58 ,67 ,
59 ".tmp_source.zig:3:12: error: expected type '[]const u8', found 'error{Foo}'");68 ".tmp_source.zig:3:12: error: expected type '[]const u8', found 'error{Foo}'",
69 );
6070
6171 cases.add(
62 cases.add("@tagName used on union with no associated enum tag",72 "@tagName used on union with no associated enum tag",
63 \\const FloatInt = extern union {73 \\const FloatInt = extern union {
64 \\ Float: f32,74 \\ Float: f32,
65 \\ Int: i32,75 \\ Int: i32,
...@@ -70,10 +80,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -70,10 +80,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
70 \\}80 \\}
71 ,81 ,
72 ".tmp_source.zig:7:19: error: union has no associated enum",82 ".tmp_source.zig:7:19: error: union has no associated enum",
73 ".tmp_source.zig:1:18: note: declared here");83 ".tmp_source.zig:1:18: note: declared here",
84 );
7485
75 cases.add("returning error from void async function",86 cases.add(
76 \\const std = @import("std");87 "returning error from void async function",
88 \\const std = @import("std",);
77 \\export fn entry() void {89 \\export fn entry() void {
78 \\ const p = async<std.debug.global_allocator> amain() catch unreachable;90 \\ const p = async<std.debug.global_allocator> amain() catch unreachable;
79 \\}91 \\}
...@@ -81,31 +93,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -81,31 +93,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
81 \\ return error.ShouldBeCompileError;93 \\ return error.ShouldBeCompileError;
82 \\}94 \\}
83 ,95 ,
84 ".tmp_source.zig:6:17: error: expected type 'void', found 'error{ShouldBeCompileError}'");96 ".tmp_source.zig:6:17: error: expected type 'void', found 'error{ShouldBeCompileError}'",
97 );
8598
86 cases.add("var not allowed in structs",99 cases.add(
100 "var not allowed in structs",
87 \\export fn entry() void {101 \\export fn entry() void {
88 \\ var s = (struct{v: var}){.v=i32(10)};102 \\ var s = (struct{v: var}){.v=i32(10)};
89 \\}103 \\}
90 ,104 ,
91 ".tmp_source.zig:2:23: error: invalid token: 'var'");105 ".tmp_source.zig:2:23: error: invalid token: 'var'",
106 );
92107
93 cases.add("@ptrCast discards const qualifier",108 cases.add(
109 "@ptrCast discards const qualifier",
94 \\export fn entry() void {110 \\export fn entry() void {
95 \\ const x: i32 = 1234;111 \\ const x: i32 = 1234;
96 \\ const y = @ptrCast(&i32, &x);112 \\ const y = @ptrCast(&i32, &x);
97 \\}113 \\}
98 ,114 ,
99 ".tmp_source.zig:3:15: error: cast discards const qualifier");115 ".tmp_source.zig:3:15: error: cast discards const qualifier",
116 );
100117
101 cases.add("comptime slice of undefined pointer non-zero len",118 cases.add(
119 "comptime slice of undefined pointer non-zero len",
102 \\export fn entry() void {120 \\export fn entry() void {
103 \\ const slice = (&i32)(undefined)[0..1];121 \\ const slice = (&i32)(undefined)[0..1];
104 \\}122 \\}
105 ,123 ,
106 ".tmp_source.zig:2:36: error: non-zero length slice of undefined pointer");124 ".tmp_source.zig:2:36: error: non-zero length slice of undefined pointer",
125 );
107126
108 cases.add("type checking function pointers",127 cases.add(
128 "type checking function pointers",
109 \\fn a(b: fn (&const u8) void) void {129 \\fn a(b: fn (&const u8) void) void {
110 \\ b('a');130 \\ b('a');
111 \\}131 \\}
...@@ -116,9 +136,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -116,9 +136,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
116 \\ a(c);136 \\ a(c);
117 \\}137 \\}
118 ,138 ,
119 ".tmp_source.zig:8:7: error: expected type 'fn(&const u8) void', found 'fn(u8) void'");139 ".tmp_source.zig:8:7: error: expected type 'fn(&const u8) void', found 'fn(u8) void'",
140 );
120141
121 cases.add("no else prong on switch on global error set",142 cases.add(
143 "no else prong on switch on global error set",
122 \\export fn entry() void {144 \\export fn entry() void {
123 \\ foo(error.A);145 \\ foo(error.A);
124 \\}146 \\}
...@@ -128,18 +150,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -128,18 +150,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
128 \\ }150 \\ }
129 \\}151 \\}
130 ,152 ,
131 ".tmp_source.zig:5:5: error: else prong required when switching on type 'error'");153 ".tmp_source.zig:5:5: error: else prong required when switching on type 'error'",
154 );
132155
133 cases.add("inferred error set with no returned error",156 cases.add(
157 "inferred error set with no returned error",
134 \\export fn entry() void {158 \\export fn entry() void {
135 \\ foo() catch unreachable;159 \\ foo() catch unreachable;
136 \\}160 \\}
137 \\fn foo() !void {161 \\fn foo() !void {
138 \\}162 \\}
139 ,163 ,
140 ".tmp_source.zig:4:11: error: function with inferred error set must return at least one possible error");164 ".tmp_source.zig:4:11: error: function with inferred error set must return at least one possible error",
165 );
141166
142 cases.add("error not handled in switch",167 cases.add(
168 "error not handled in switch",
143 \\export fn entry() void {169 \\export fn entry() void {
144 \\ foo(452) catch |err| switch (err) {170 \\ foo(452) catch |err| switch (err) {
145 \\ error.Foo => {},171 \\ error.Foo => {},
...@@ -155,9 +181,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -155,9 +181,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
155 \\}181 \\}
156 ,182 ,
157 ".tmp_source.zig:2:26: error: error.Baz not handled in switch",183 ".tmp_source.zig:2:26: error: error.Baz not handled in switch",
158 ".tmp_source.zig:2:26: error: error.Bar not handled in switch");184 ".tmp_source.zig:2:26: error: error.Bar not handled in switch",
185 );
159186
160 cases.add("duplicate error in switch",187 cases.add(
188 "duplicate error in switch",
161 \\export fn entry() void {189 \\export fn entry() void {
162 \\ foo(452) catch |err| switch (err) {190 \\ foo(452) catch |err| switch (err) {
163 \\ error.Foo => {},191 \\ error.Foo => {},
...@@ -175,9 +203,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -175,9 +203,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
175 \\}203 \\}
176 ,204 ,
177 ".tmp_source.zig:5:14: error: duplicate switch value: '@typeOf(foo).ReturnType.ErrorSet.Foo'",205 ".tmp_source.zig:5:14: error: duplicate switch value: '@typeOf(foo).ReturnType.ErrorSet.Foo'",
178 ".tmp_source.zig:3:14: note: other value is here");206 ".tmp_source.zig:3:14: note: other value is here",
207 );
179208
180 cases.add("range operator in switch used on error set",209 cases.add(
210 "range operator in switch used on error set",
181 \\export fn entry() void {211 \\export fn entry() void {
182 \\ try foo(452) catch |err| switch (err) {212 \\ try foo(452) catch |err| switch (err) {
183 \\ error.A ... error.B => {},213 \\ error.A ... error.B => {},
...@@ -192,31 +222,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -192,31 +222,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
192 \\ }222 \\ }
193 \\}223 \\}
194 ,224 ,
195 ".tmp_source.zig:3:17: error: operator not allowed for errors");225 ".tmp_source.zig:3:17: error: operator not allowed for errors",
226 );
196227
197 cases.add("inferring error set of function pointer",228 cases.add(
229 "inferring error set of function pointer",
198 \\comptime {230 \\comptime {
199 \\ const z: ?fn()!void = null;231 \\ const z: ?fn()!void = null;
200 \\}232 \\}
201 ,233 ,
202 ".tmp_source.zig:2:15: error: inferring error set of return type valid only for function definitions");234 ".tmp_source.zig:2:15: error: inferring error set of return type valid only for function definitions",
235 );
203236
204 cases.add("access non-existent member of error set",237 cases.add(
238 "access non-existent member of error set",
205 \\const Foo = error{A};239 \\const Foo = error{A};
206 \\comptime {240 \\comptime {
207 \\ const z = Foo.Bar;241 \\ const z = Foo.Bar;
208 \\}242 \\}
209 ,243 ,
210 ".tmp_source.zig:3:18: error: no error named 'Bar' in 'Foo'");244 ".tmp_source.zig:3:18: error: no error named 'Bar' in 'Foo'",
245 );
211246
212 cases.add("error union operator with non error set LHS",247 cases.add(
248 "error union operator with non error set LHS",
213 \\comptime {249 \\comptime {
214 \\ const z = i32!i32;250 \\ const z = i32!i32;
215 \\}251 \\}
216 ,252 ,
217 ".tmp_source.zig:2:15: error: expected error set type, found type 'i32'");253 ".tmp_source.zig:2:15: error: expected error set type, found type 'i32'",
254 );
218255
219 cases.add("error equality but sets have no common members",256 cases.add(
257 "error equality but sets have no common members",
220 \\const Set1 = error{A, C};258 \\const Set1 = error{A, C};
221 \\const Set2 = error{B, D};259 \\const Set2 = error{B, D};
222 \\export fn entry() void {260 \\export fn entry() void {
...@@ -228,16 +266,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -228,16 +266,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
228 \\ }266 \\ }
229 \\}267 \\}
230 ,268 ,
231 ".tmp_source.zig:7:11: error: error sets 'Set1' and 'Set2' have no common errors");269 ".tmp_source.zig:7:11: error: error sets 'Set1' and 'Set2' have no common errors",
270 );
232271
233 cases.add("only equality binary operator allowed for error sets",272 cases.add(
273 "only equality binary operator allowed for error sets",
234 \\comptime {274 \\comptime {
235 \\ const z = error.A > error.B;275 \\ const z = error.A > error.B;
236 \\}276 \\}
237 ,277 ,
238 ".tmp_source.zig:2:23: error: operator not allowed for errors");278 ".tmp_source.zig:2:23: error: operator not allowed for errors",
279 );
239280
240 cases.add("explicit error set cast known at comptime violates error sets",281 cases.add(
282 "explicit error set cast known at comptime violates error sets",
241 \\const Set1 = error {A, B};283 \\const Set1 = error {A, B};
242 \\const Set2 = error {A, C};284 \\const Set2 = error {A, C};
243 \\comptime {285 \\comptime {
...@@ -245,9 +287,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -245,9 +287,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
245 \\ var y = Set2(x);287 \\ var y = Set2(x);
246 \\}288 \\}
247 ,289 ,
248 ".tmp_source.zig:5:17: error: error.B not a member of error set 'Set2'");290 ".tmp_source.zig:5:17: error: error.B not a member of error set 'Set2'",
291 );
249292
250 cases.add("cast error union of global error set to error union of smaller error set",293 cases.add(
294 "cast error union of global error set to error union of smaller error set",
251 \\const SmallErrorSet = error{A};295 \\const SmallErrorSet = error{A};
252 \\export fn entry() void {296 \\export fn entry() void {
253 \\ var x: SmallErrorSet!i32 = foo();297 \\ var x: SmallErrorSet!i32 = foo();
...@@ -257,9 +301,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -257,9 +301,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
257 \\}301 \\}
258 ,302 ,
259 ".tmp_source.zig:3:35: error: expected 'SmallErrorSet!i32', found 'error!i32'",303 ".tmp_source.zig:3:35: error: expected 'SmallErrorSet!i32', found 'error!i32'",
260 ".tmp_source.zig:3:35: note: unable to cast global error set into smaller set");304 ".tmp_source.zig:3:35: note: unable to cast global error set into smaller set",
305 );
261306
262 cases.add("cast global error set to error set",307 cases.add(
308 "cast global error set to error set",
263 \\const SmallErrorSet = error{A};309 \\const SmallErrorSet = error{A};
264 \\export fn entry() void {310 \\export fn entry() void {
265 \\ var x: SmallErrorSet = foo();311 \\ var x: SmallErrorSet = foo();
...@@ -269,9 +315,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -269,9 +315,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
269 \\}315 \\}
270 ,316 ,
271 ".tmp_source.zig:3:31: error: expected 'SmallErrorSet', found 'error'",317 ".tmp_source.zig:3:31: error: expected 'SmallErrorSet', found 'error'",
272 ".tmp_source.zig:3:31: note: unable to cast global error set into smaller set");318 ".tmp_source.zig:3:31: note: unable to cast global error set into smaller set",
319 );
273320
274 cases.add("recursive inferred error set",321 cases.add(
322 "recursive inferred error set",
275 \\export fn entry() void {323 \\export fn entry() void {
276 \\ foo() catch unreachable;324 \\ foo() catch unreachable;
277 \\}325 \\}
...@@ -279,9 +327,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -279,9 +327,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
279 \\ try foo();327 \\ try foo();
280 \\}328 \\}
281 ,329 ,
282 ".tmp_source.zig:5:5: error: cannot resolve inferred error set '@typeOf(foo).ReturnType.ErrorSet': function 'foo' not fully analyzed yet");330 ".tmp_source.zig:5:5: error: cannot resolve inferred error set '@typeOf(foo).ReturnType.ErrorSet': function 'foo' not fully analyzed yet",
331 );
283332
284 cases.add("implicit cast of error set not a subset",333 cases.add(
334 "implicit cast of error set not a subset",
285 \\const Set1 = error{A, B};335 \\const Set1 = error{A, B};
286 \\const Set2 = error{A, C};336 \\const Set2 = error{A, C};
287 \\export fn entry() void {337 \\export fn entry() void {
...@@ -292,18 +342,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -292,18 +342,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
292 \\}342 \\}
293 ,343 ,
294 ".tmp_source.zig:7:19: error: expected 'Set2', found 'Set1'",344 ".tmp_source.zig:7:19: error: expected 'Set2', found 'Set1'",
295 ".tmp_source.zig:1:23: note: 'error.B' not a member of destination error set");345 ".tmp_source.zig:1:23: note: 'error.B' not a member of destination error set",
346 );
296347
297 cases.add("int to err global invalid number",348 cases.add(
349 "int to err global invalid number",
298 \\const Set1 = error{A, B};350 \\const Set1 = error{A, B};
299 \\comptime {351 \\comptime {
300 \\ var x: usize = 3;352 \\ var x: usize = 3;
301 \\ var y = error(x);353 \\ var y = error(x);
302 \\}354 \\}
303 ,355 ,
304 ".tmp_source.zig:4:18: error: integer value 3 represents no error");356 ".tmp_source.zig:4:18: error: integer value 3 represents no error",
357 );
305358
306 cases.add("int to err non global invalid number",359 cases.add(
360 "int to err non global invalid number",
307 \\const Set1 = error{A, B};361 \\const Set1 = error{A, B};
308 \\const Set2 = error{A, C};362 \\const Set2 = error{A, C};
309 \\comptime {363 \\comptime {
...@@ -311,16 +365,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -311,16 +365,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
311 \\ var y = Set2(x);365 \\ var y = Set2(x);
312 \\}366 \\}
313 ,367 ,
314 ".tmp_source.zig:5:17: error: integer value 2 represents no error in 'Set2'");368 ".tmp_source.zig:5:17: error: integer value 2 represents no error in 'Set2'",
369 );
315370
316 cases.add("@memberCount of error",371 cases.add(
372 "@memberCount of error",
317 \\comptime {373 \\comptime {
318 \\ _ = @memberCount(error);374 \\ _ = @memberCount(error);
319 \\}375 \\}
320 ,376 ,
321 ".tmp_source.zig:2:9: error: global error set member count not available at comptime");377 ".tmp_source.zig:2:9: error: global error set member count not available at comptime",
378 );
322379
323 cases.add("duplicate error value in error set",380 cases.add(
381 "duplicate error value in error set",
324 \\const Foo = error {382 \\const Foo = error {
325 \\ Bar,383 \\ Bar,
326 \\ Bar,384 \\ Bar,
...@@ -330,22 +388,30 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -330,22 +388,30 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
330 \\}388 \\}
331 ,389 ,
332 ".tmp_source.zig:3:5: error: duplicate error: 'Bar'",390 ".tmp_source.zig:3:5: error: duplicate error: 'Bar'",
333 ".tmp_source.zig:2:5: note: other error here");391 ".tmp_source.zig:2:5: note: other error here",
392 );
334393
335 cases.add("cast negative integer literal to usize",394 cases.add(
395 "cast negative integer literal to usize",
336 \\export fn entry() void {396 \\export fn entry() void {
337 \\ const x = usize(-10);397 \\ const x = usize(-10);
338 \\}398 \\}
339 , ".tmp_source.zig:2:21: error: cannot cast negative value -10 to unsigned integer type 'usize'");399 ,
400 ".tmp_source.zig:2:21: error: cannot cast negative value -10 to unsigned integer type 'usize'",
401 );
340402
341 cases.add("use invalid number literal as array index",403 cases.add(
404 "use invalid number literal as array index",
342 \\var v = 25;405 \\var v = 25;
343 \\export fn entry() void {406 \\export fn entry() void {
344 \\ var arr: [v]u8 = undefined;407 \\ var arr: [v]u8 = undefined;
345 \\}408 \\}
346 , ".tmp_source.zig:1:1: error: unable to infer variable type");409 ,
410 ".tmp_source.zig:1:1: error: unable to infer variable type",
411 );
347412
348 cases.add("duplicate struct field",413 cases.add(
414 "duplicate struct field",
349 \\const Foo = struct {415 \\const Foo = struct {
350 \\ Bar: i32,416 \\ Bar: i32,
351 \\ Bar: usize,417 \\ Bar: usize,
...@@ -355,9 +421,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -355,9 +421,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
355 \\}421 \\}
356 ,422 ,
357 ".tmp_source.zig:3:5: error: duplicate struct field: 'Bar'",423 ".tmp_source.zig:3:5: error: duplicate struct field: 'Bar'",
358 ".tmp_source.zig:2:5: note: other field here");424 ".tmp_source.zig:2:5: note: other field here",
425 );
359426
360 cases.add("duplicate union field",427 cases.add(
428 "duplicate union field",
361 \\const Foo = union {429 \\const Foo = union {
362 \\ Bar: i32,430 \\ Bar: i32,
363 \\ Bar: usize,431 \\ Bar: usize,
...@@ -367,9 +435,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -367,9 +435,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
367 \\}435 \\}
368 ,436 ,
369 ".tmp_source.zig:3:5: error: duplicate union field: 'Bar'",437 ".tmp_source.zig:3:5: error: duplicate union field: 'Bar'",
370 ".tmp_source.zig:2:5: note: other field here");438 ".tmp_source.zig:2:5: note: other field here",
439 );
371440
372 cases.add("duplicate enum field",441 cases.add(
442 "duplicate enum field",
373 \\const Foo = enum {443 \\const Foo = enum {
374 \\ Bar,444 \\ Bar,
375 \\ Bar,445 \\ Bar,
...@@ -380,77 +450,108 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -380,77 +450,108 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
380 \\}450 \\}
381 ,451 ,
382 ".tmp_source.zig:3:5: error: duplicate enum field: 'Bar'",452 ".tmp_source.zig:3:5: error: duplicate enum field: 'Bar'",
383 ".tmp_source.zig:2:5: note: other field here");453 ".tmp_source.zig:2:5: note: other field here",
454 );
384455
385 cases.add("calling function with naked calling convention",456 cases.add(
457 "calling function with naked calling convention",
386 \\export fn entry() void {458 \\export fn entry() void {
387 \\ foo();459 \\ foo();
388 \\}460 \\}
389 \\nakedcc fn foo() void { }461 \\nakedcc fn foo() void { }
390 ,462 ,
391 ".tmp_source.zig:2:5: error: unable to call function with naked calling convention",463 ".tmp_source.zig:2:5: error: unable to call function with naked calling convention",
392 ".tmp_source.zig:4:9: note: declared here");464 ".tmp_source.zig:4:9: note: declared here",
465 );
393466
394 cases.add("function with invalid return type",467 cases.add(
468 "function with invalid return type",
395 \\export fn foo() boid {}469 \\export fn foo() boid {}
396 , ".tmp_source.zig:1:17: error: use of undeclared identifier 'boid'");470 ,
471 ".tmp_source.zig:1:17: error: use of undeclared identifier 'boid'",
472 );
397473
398 cases.add("function with non-extern non-packed enum parameter",474 cases.add(
475 "function with non-extern non-packed enum parameter",
399 \\const Foo = enum { A, B, C };476 \\const Foo = enum { A, B, C };
400 \\export fn entry(foo: Foo) void { }477 \\export fn entry(foo: Foo) void { }
401 , ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");478 ,
479 ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'",
480 );
402481
403 cases.add("function with non-extern non-packed struct parameter",482 cases.add(
483 "function with non-extern non-packed struct parameter",
404 \\const Foo = struct {484 \\const Foo = struct {
405 \\ A: i32,485 \\ A: i32,
406 \\ B: f32,486 \\ B: f32,
407 \\ C: bool,487 \\ C: bool,
408 \\};488 \\};
409 \\export fn entry(foo: Foo) void { }489 \\export fn entry(foo: Foo) void { }
410 , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");490 ,
491 ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'",
492 );
411493
412 cases.add("function with non-extern non-packed union parameter",494 cases.add(
495 "function with non-extern non-packed union parameter",
413 \\const Foo = union {496 \\const Foo = union {
414 \\ A: i32,497 \\ A: i32,
415 \\ B: f32,498 \\ B: f32,
416 \\ C: bool,499 \\ C: bool,
417 \\};500 \\};
418 \\export fn entry(foo: Foo) void { }501 \\export fn entry(foo: Foo) void { }
419 , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");502 ,
503 ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'",
504 );
420505
421 cases.add("switch on enum with 1 field with no prongs",506 cases.add(
507 "switch on enum with 1 field with no prongs",
422 \\const Foo = enum { M };508 \\const Foo = enum { M };
423 \\509 \\
424 \\export fn entry() void {510 \\export fn entry() void {
425 \\ var f = Foo.M;511 \\ var f = Foo.M;
426 \\ switch (f) {}512 \\ switch (f) {}
427 \\}513 \\}
428 , ".tmp_source.zig:5:5: error: enumeration value 'Foo.M' not handled in switch");514 ,
515 ".tmp_source.zig:5:5: error: enumeration value 'Foo.M' not handled in switch",
516 );
429517
430 cases.add("shift by negative comptime integer",518 cases.add(
519 "shift by negative comptime integer",
431 \\comptime {520 \\comptime {
432 \\ var a = 1 >> -1;521 \\ var a = 1 >> -1;
433 \\}522 \\}
434 , ".tmp_source.zig:2:18: error: shift by negative value -1");523 ,
524 ".tmp_source.zig:2:18: error: shift by negative value -1",
525 );
435526
436 cases.add("@panic called at compile time",527 cases.add(
528 "@panic called at compile time",
437 \\export fn entry() void {529 \\export fn entry() void {
438 \\ comptime {530 \\ comptime {
439 \\ @panic("aoeu");531 \\ @panic("aoeu",);
440 \\ }532 \\ }
441 \\}533 \\}
442 , ".tmp_source.zig:3:9: error: encountered @panic at compile-time");534 ,
535 ".tmp_source.zig:3:9: error: encountered @panic at compile-time",
536 );
443537
444 cases.add("wrong return type for main",538 cases.add(
539 "wrong return type for main",
445 \\pub fn main() f32 { }540 \\pub fn main() f32 { }
446 , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'");541 ,
542 "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'",
543 );
447544
448 cases.add("double ?? on main return value",545 cases.add(
546 "double ?? on main return value",
449 \\pub fn main() ??void {547 \\pub fn main() ??void {
450 \\}548 \\}
451 , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'");549 ,
550 "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'",
551 );
452552
453 cases.add("bad identifier in function with struct defined inside function which references local const",553 cases.add(
554 "bad identifier in function with struct defined inside function which references local const",
454 \\export fn entry() void {555 \\export fn entry() void {
455 \\ const BlockKind = u32;556 \\ const BlockKind = u32;
456 \\557 \\
...@@ -460,9 +561,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -460,9 +561,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
460 \\561 \\
461 \\ bogus;562 \\ bogus;
462 \\}563 \\}
463 , ".tmp_source.zig:8:5: error: use of undeclared identifier 'bogus'");564 ,
565 ".tmp_source.zig:8:5: error: use of undeclared identifier 'bogus'",
566 );
464567
465 cases.add("labeled break not found",568 cases.add(
569 "labeled break not found",
466 \\export fn entry() void {570 \\export fn entry() void {
467 \\ blah: while (true) {571 \\ blah: while (true) {
468 \\ while (true) {572 \\ while (true) {
...@@ -470,9 +574,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -470,9 +574,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
470 \\ }574 \\ }
471 \\ }575 \\ }
472 \\}576 \\}
473 , ".tmp_source.zig:4:13: error: label not found: 'outer'");577 ,
578 ".tmp_source.zig:4:13: error: label not found: 'outer'",
579 );
474580
475 cases.add("labeled continue not found",581 cases.add(
582 "labeled continue not found",
476 \\export fn entry() void {583 \\export fn entry() void {
477 \\ var i: usize = 0;584 \\ var i: usize = 0;
478 \\ blah: while (i < 10) : (i += 1) {585 \\ blah: while (i < 10) : (i += 1) {
...@@ -481,9 +588,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -481,9 +588,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
481 \\ }588 \\ }
482 \\ }589 \\ }
483 \\}590 \\}
484 , ".tmp_source.zig:5:13: error: labeled loop not found: 'outer'");591 ,
592 ".tmp_source.zig:5:13: error: labeled loop not found: 'outer'",
593 );
485594
486 cases.add("attempt to use 0 bit type in extern fn",595 cases.add(
596 "attempt to use 0 bit type in extern fn",
487 \\extern fn foo(ptr: extern fn(&void) void) void;597 \\extern fn foo(ptr: extern fn(&void) void) void;
488 \\598 \\
489 \\export fn entry() void {599 \\export fn entry() void {
...@@ -491,390 +601,541 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -491,390 +601,541 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
491 \\}601 \\}
492 \\602 \\
493 \\extern fn bar(x: &void) void { }603 \\extern fn bar(x: &void) void { }
494 , ".tmp_source.zig:7:18: error: parameter of type '&void' has 0 bits; not allowed in function with calling convention 'ccc'");604 ,
605 ".tmp_source.zig:7:18: error: parameter of type '&void' has 0 bits; not allowed in function with calling convention 'ccc'",
606 );
495607
496 cases.add("implicit semicolon - block statement",608 cases.add(
609 "implicit semicolon - block statement",
497 \\export fn entry() void {610 \\export fn entry() void {
498 \\ {}611 \\ {}
499 \\ var good = {};612 \\ var good = {};
500 \\ ({})613 \\ ({})
501 \\ var bad = {};614 \\ var bad = {};
502 \\}615 \\}
503 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");616 ,
617 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
618 );
504619
505 cases.add("implicit semicolon - block expr",620 cases.add(
621 "implicit semicolon - block expr",
506 \\export fn entry() void {622 \\export fn entry() void {
507 \\ _ = {};623 \\ _ = {};
508 \\ var good = {};624 \\ var good = {};
509 \\ _ = {}625 \\ _ = {}
510 \\ var bad = {};626 \\ var bad = {};
511 \\}627 \\}
512 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");628 ,
629 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
630 );
513631
514 cases.add("implicit semicolon - comptime statement",632 cases.add(
633 "implicit semicolon - comptime statement",
515 \\export fn entry() void {634 \\export fn entry() void {
516 \\ comptime {}635 \\ comptime {}
517 \\ var good = {};636 \\ var good = {};
518 \\ comptime ({})637 \\ comptime ({})
519 \\ var bad = {};638 \\ var bad = {};
520 \\}639 \\}
521 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");640 ,
641 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
642 );
522643
523 cases.add("implicit semicolon - comptime expression",644 cases.add(
645 "implicit semicolon - comptime expression",
524 \\export fn entry() void {646 \\export fn entry() void {
525 \\ _ = comptime {};647 \\ _ = comptime {};
526 \\ var good = {};648 \\ var good = {};
527 \\ _ = comptime {}649 \\ _ = comptime {}
528 \\ var bad = {};650 \\ var bad = {};
529 \\}651 \\}
530 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");652 ,
653 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
654 );
531655
532 cases.add("implicit semicolon - defer",656 cases.add(
657 "implicit semicolon - defer",
533 \\export fn entry() void {658 \\export fn entry() void {
534 \\ defer {}659 \\ defer {}
535 \\ var good = {};660 \\ var good = {};
536 \\ defer ({})661 \\ defer ({})
537 \\ var bad = {};662 \\ var bad = {};
538 \\}663 \\}
539 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");664 ,
665 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
666 );
540667
541 cases.add("implicit semicolon - if statement",668 cases.add(
669 "implicit semicolon - if statement",
542 \\export fn entry() void {670 \\export fn entry() void {
543 \\ if(true) {}671 \\ if(true) {}
544 \\ var good = {};672 \\ var good = {};
545 \\ if(true) ({})673 \\ if(true) ({})
546 \\ var bad = {};674 \\ var bad = {};
547 \\}675 \\}
548 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");676 ,
677 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
678 );
549679
550 cases.add("implicit semicolon - if expression",680 cases.add(
681 "implicit semicolon - if expression",
551 \\export fn entry() void {682 \\export fn entry() void {
552 \\ _ = if(true) {};683 \\ _ = if(true) {};
553 \\ var good = {};684 \\ var good = {};
554 \\ _ = if(true) {}685 \\ _ = if(true) {}
555 \\ var bad = {};686 \\ var bad = {};
556 \\}687 \\}
557 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");688 ,
689 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
690 );
558691
559 cases.add("implicit semicolon - if-else statement",692 cases.add(
693 "implicit semicolon - if-else statement",
560 \\export fn entry() void {694 \\export fn entry() void {
561 \\ if(true) {} else {}695 \\ if(true) {} else {}
562 \\ var good = {};696 \\ var good = {};
563 \\ if(true) ({}) else ({})697 \\ if(true) ({}) else ({})
564 \\ var bad = {};698 \\ var bad = {};
565 \\}699 \\}
566 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");700 ,
701 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
702 );
567703
568 cases.add("implicit semicolon - if-else expression",704 cases.add(
705 "implicit semicolon - if-else expression",
569 \\export fn entry() void {706 \\export fn entry() void {
570 \\ _ = if(true) {} else {};707 \\ _ = if(true) {} else {};
571 \\ var good = {};708 \\ var good = {};
572 \\ _ = if(true) {} else {}709 \\ _ = if(true) {} else {}
573 \\ var bad = {};710 \\ var bad = {};
574 \\}711 \\}
575 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");712 ,
713 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
714 );
576715
577 cases.add("implicit semicolon - if-else-if statement",716 cases.add(
717 "implicit semicolon - if-else-if statement",
578 \\export fn entry() void {718 \\export fn entry() void {
579 \\ if(true) {} else if(true) {}719 \\ if(true) {} else if(true) {}
580 \\ var good = {};720 \\ var good = {};
581 \\ if(true) ({}) else if(true) ({})721 \\ if(true) ({}) else if(true) ({})
582 \\ var bad = {};722 \\ var bad = {};
583 \\}723 \\}
584 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");724 ,
725 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
726 );
585727
586 cases.add("implicit semicolon - if-else-if expression",728 cases.add(
729 "implicit semicolon - if-else-if expression",
587 \\export fn entry() void {730 \\export fn entry() void {
588 \\ _ = if(true) {} else if(true) {};731 \\ _ = if(true) {} else if(true) {};
589 \\ var good = {};732 \\ var good = {};
590 \\ _ = if(true) {} else if(true) {}733 \\ _ = if(true) {} else if(true) {}
591 \\ var bad = {};734 \\ var bad = {};
592 \\}735 \\}
593 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");736 ,
737 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
738 );
594739
595 cases.add("implicit semicolon - if-else-if-else statement",740 cases.add(
741 "implicit semicolon - if-else-if-else statement",
596 \\export fn entry() void {742 \\export fn entry() void {
597 \\ if(true) {} else if(true) {} else {}743 \\ if(true) {} else if(true) {} else {}
598 \\ var good = {};744 \\ var good = {};
599 \\ if(true) ({}) else if(true) ({}) else ({})745 \\ if(true) ({}) else if(true) ({}) else ({})
600 \\ var bad = {};746 \\ var bad = {};
601 \\}747 \\}
602 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");748 ,
749 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
750 );
603751
604 cases.add("implicit semicolon - if-else-if-else expression",752 cases.add(
753 "implicit semicolon - if-else-if-else expression",
605 \\export fn entry() void {754 \\export fn entry() void {
606 \\ _ = if(true) {} else if(true) {} else {};755 \\ _ = if(true) {} else if(true) {} else {};
607 \\ var good = {};756 \\ var good = {};
608 \\ _ = if(true) {} else if(true) {} else {}757 \\ _ = if(true) {} else if(true) {} else {}
609 \\ var bad = {};758 \\ var bad = {};
610 \\}759 \\}
611 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");760 ,
761 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
762 );
612763
613 cases.add("implicit semicolon - test statement",764 cases.add(
765 "implicit semicolon - test statement",
614 \\export fn entry() void {766 \\export fn entry() void {
615 \\ if (foo()) |_| {}767 \\ if (foo()) |_| {}
616 \\ var good = {};768 \\ var good = {};
617 \\ if (foo()) |_| ({})769 \\ if (foo()) |_| ({})
618 \\ var bad = {};770 \\ var bad = {};
619 \\}771 \\}
620 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");772 ,
773 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
774 );
621775
622 cases.add("implicit semicolon - test expression",776 cases.add(
777 "implicit semicolon - test expression",
623 \\export fn entry() void {778 \\export fn entry() void {
624 \\ _ = if (foo()) |_| {};779 \\ _ = if (foo()) |_| {};
625 \\ var good = {};780 \\ var good = {};
626 \\ _ = if (foo()) |_| {}781 \\ _ = if (foo()) |_| {}
627 \\ var bad = {};782 \\ var bad = {};
628 \\}783 \\}
629 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");784 ,
785 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
786 );
630787
631 cases.add("implicit semicolon - while statement",788 cases.add(
789 "implicit semicolon - while statement",
632 \\export fn entry() void {790 \\export fn entry() void {
633 \\ while(true) {}791 \\ while(true) {}
634 \\ var good = {};792 \\ var good = {};
635 \\ while(true) ({})793 \\ while(true) ({})
636 \\ var bad = {};794 \\ var bad = {};
637 \\}795 \\}
638 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");796 ,
797 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
798 );
639799
640 cases.add("implicit semicolon - while expression",800 cases.add(
801 "implicit semicolon - while expression",
641 \\export fn entry() void {802 \\export fn entry() void {
642 \\ _ = while(true) {};803 \\ _ = while(true) {};
643 \\ var good = {};804 \\ var good = {};
644 \\ _ = while(true) {}805 \\ _ = while(true) {}
645 \\ var bad = {};806 \\ var bad = {};
646 \\}807 \\}
647 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");808 ,
809 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
810 );
648811
649 cases.add("implicit semicolon - while-continue statement",812 cases.add(
813 "implicit semicolon - while-continue statement",
650 \\export fn entry() void {814 \\export fn entry() void {
651 \\ while(true):({}) {}815 \\ while(true):({}) {}
652 \\ var good = {};816 \\ var good = {};
653 \\ while(true):({}) ({})817 \\ while(true):({}) ({})
654 \\ var bad = {};818 \\ var bad = {};
655 \\}819 \\}
656 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");820 ,
821 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
822 );
657823
658 cases.add("implicit semicolon - while-continue expression",824 cases.add(
825 "implicit semicolon - while-continue expression",
659 \\export fn entry() void {826 \\export fn entry() void {
660 \\ _ = while(true):({}) {};827 \\ _ = while(true):({}) {};
661 \\ var good = {};828 \\ var good = {};
662 \\ _ = while(true):({}) {}829 \\ _ = while(true):({}) {}
663 \\ var bad = {};830 \\ var bad = {};
664 \\}831 \\}
665 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");832 ,
833 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
834 );
666835
667 cases.add("implicit semicolon - for statement",836 cases.add(
837 "implicit semicolon - for statement",
668 \\export fn entry() void {838 \\export fn entry() void {
669 \\ for(foo()) {}839 \\ for(foo()) {}
670 \\ var good = {};840 \\ var good = {};
671 \\ for(foo()) ({})841 \\ for(foo()) ({})
672 \\ var bad = {};842 \\ var bad = {};
673 \\}843 \\}
674 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");844 ,
845 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
846 );
675847
676 cases.add("implicit semicolon - for expression",848 cases.add(
849 "implicit semicolon - for expression",
677 \\export fn entry() void {850 \\export fn entry() void {
678 \\ _ = for(foo()) {};851 \\ _ = for(foo()) {};
679 \\ var good = {};852 \\ var good = {};
680 \\ _ = for(foo()) {}853 \\ _ = for(foo()) {}
681 \\ var bad = {};854 \\ var bad = {};
682 \\}855 \\}
683 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");856 ,
857 ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
858 );
684859
685 cases.add("multiple function definitions",860 cases.add(
861 "multiple function definitions",
686 \\fn a() void {}862 \\fn a() void {}
687 \\fn a() void {}863 \\fn a() void {}
688 \\export fn entry() void { a(); }864 \\export fn entry() void { a(); }
689 , ".tmp_source.zig:2:1: error: redefinition of 'a'");865 ,
866 ".tmp_source.zig:2:1: error: redefinition of 'a'",
867 );
690868
691 cases.add("unreachable with return",869 cases.add(
870 "unreachable with return",
692 \\fn a() noreturn {return;}871 \\fn a() noreturn {return;}
693 \\export fn entry() void { a(); }872 \\export fn entry() void { a(); }
694 , ".tmp_source.zig:1:18: error: expected type 'noreturn', found 'void'");873 ,
874 ".tmp_source.zig:1:18: error: expected type 'noreturn', found 'void'",
875 );
695876
696 cases.add("control reaches end of non-void function",877 cases.add(
878 "control reaches end of non-void function",
697 \\fn a() i32 {}879 \\fn a() i32 {}
698 \\export fn entry() void { _ = a(); }880 \\export fn entry() void { _ = a(); }
699 , ".tmp_source.zig:1:12: error: expected type 'i32', found 'void'");881 ,
882 ".tmp_source.zig:1:12: error: expected type 'i32', found 'void'",
883 );
700884
701 cases.add("undefined function call",885 cases.add(
886 "undefined function call",
702 \\export fn a() void {887 \\export fn a() void {
703 \\ b();888 \\ b();
704 \\}889 \\}
705 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");890 ,
891 ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'",
892 );
706893
707 cases.add("wrong number of arguments",894 cases.add(
895 "wrong number of arguments",
708 \\export fn a() void {896 \\export fn a() void {
709 \\ b(1);897 \\ b(1);
710 \\}898 \\}
711 \\fn b(a: i32, b: i32, c: i32) void { }899 \\fn b(a: i32, b: i32, c: i32) void { }
712 , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1");900 ,
901 ".tmp_source.zig:2:6: error: expected 3 arguments, found 1",
902 );
713903
714 cases.add("invalid type",904 cases.add(
905 "invalid type",
715 \\fn a() bogus {}906 \\fn a() bogus {}
716 \\export fn entry() void { _ = a(); }907 \\export fn entry() void { _ = a(); }
717 , ".tmp_source.zig:1:8: error: use of undeclared identifier 'bogus'");908 ,
909 ".tmp_source.zig:1:8: error: use of undeclared identifier 'bogus'",
910 );
718911
719 cases.add("pointer to noreturn",912 cases.add(
913 "pointer to noreturn",
720 \\fn a() &noreturn {}914 \\fn a() &noreturn {}
721 \\export fn entry() void { _ = a(); }915 \\export fn entry() void { _ = a(); }
722 , ".tmp_source.zig:1:9: error: pointer to noreturn not allowed");916 ,
917 ".tmp_source.zig:1:9: error: pointer to noreturn not allowed",
918 );
723919
724 cases.add("unreachable code",920 cases.add(
921 "unreachable code",
725 \\export fn a() void {922 \\export fn a() void {
726 \\ return;923 \\ return;
727 \\ b();924 \\ b();
728 \\}925 \\}
729 \\926 \\
730 \\fn b() void {}927 \\fn b() void {}
731 , ".tmp_source.zig:3:5: error: unreachable code");928 ,
929 ".tmp_source.zig:3:5: error: unreachable code",
930 );
732931
733 cases.add("bad import",932 cases.add(
734 \\const bogus = @import("bogus-does-not-exist.zig");933 "bad import",
934 \\const bogus = @import("bogus-does-not-exist.zig",);
735 \\export fn entry() void { bogus.bogo(); }935 \\export fn entry() void { bogus.bogo(); }
736 , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'");936 ,
937 ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'",
938 );
737939
738 cases.add("undeclared identifier",940 cases.add(
941 "undeclared identifier",
739 \\export fn a() void {942 \\export fn a() void {
740 \\ return943 \\ return
741 \\ b +944 \\ b +
742 \\ c;945 \\ c;
743 \\}946 \\}
744 ,947 ,
745 ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'",948 ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'",
746 ".tmp_source.zig:4:5: error: use of undeclared identifier 'c'");949 ".tmp_source.zig:4:5: error: use of undeclared identifier 'c'",
950 );
747951
748 cases.add("parameter redeclaration",952 cases.add(
953 "parameter redeclaration",
749 \\fn f(a : i32, a : i32) void {954 \\fn f(a : i32, a : i32) void {
750 \\}955 \\}
751 \\export fn entry() void { f(1, 2); }956 \\export fn entry() void { f(1, 2); }
752 , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'");957 ,
958 ".tmp_source.zig:1:15: error: redeclaration of variable 'a'",
959 );
753960
754 cases.add("local variable redeclaration",961 cases.add(
962 "local variable redeclaration",
755 \\export fn f() void {963 \\export fn f() void {
756 \\ const a : i32 = 0;964 \\ const a : i32 = 0;
757 \\ const a = 0;965 \\ const a = 0;
758 \\}966 \\}
759 , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");967 ,
968 ".tmp_source.zig:3:5: error: redeclaration of variable 'a'",
969 );
760970
761 cases.add("local variable redeclares parameter",971 cases.add(
972 "local variable redeclares parameter",
762 \\fn f(a : i32) void {973 \\fn f(a : i32) void {
763 \\ const a = 0;974 \\ const a = 0;
764 \\}975 \\}
765 \\export fn entry() void { f(1); }976 \\export fn entry() void { f(1); }
766 , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'");977 ,
978 ".tmp_source.zig:2:5: error: redeclaration of variable 'a'",
979 );
767980
768 cases.add("variable has wrong type",981 cases.add(
982 "variable has wrong type",
769 \\export fn f() i32 {983 \\export fn f() i32 {
770 \\ const a = c"a";984 \\ const a = c"a";
771 \\ return a;985 \\ return a;
772 \\}986 \\}
773 , ".tmp_source.zig:3:12: error: expected type 'i32', found '&const u8'");987 ,
988 ".tmp_source.zig:3:12: error: expected type 'i32', found '&const u8'",
989 );
774990
775 cases.add("if condition is bool, not int",991 cases.add(
992 "if condition is bool, not int",
776 \\export fn f() void {993 \\export fn f() void {
777 \\ if (0) {}994 \\ if (0) {}
778 \\}995 \\}
779 , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'");996 ,
997 ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'",
998 );
780999
781 cases.add("assign unreachable",1000 cases.add(
1001 "assign unreachable",
782 \\export fn f() void {1002 \\export fn f() void {
783 \\ const a = return;1003 \\ const a = return;
784 \\}1004 \\}
785 , ".tmp_source.zig:2:5: error: unreachable code");1005 ,
1006 ".tmp_source.zig:2:5: error: unreachable code",
1007 );
7861008
787 cases.add("unreachable variable",1009 cases.add(
1010 "unreachable variable",
788 \\export fn f() void {1011 \\export fn f() void {
789 \\ const a: noreturn = {};1012 \\ const a: noreturn = {};
790 \\}1013 \\}
791 , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed");1014 ,
1015 ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed",
1016 );
7921017
793 cases.add("unreachable parameter",1018 cases.add(
1019 "unreachable parameter",
794 \\fn f(a: noreturn) void {}1020 \\fn f(a: noreturn) void {}
795 \\export fn entry() void { f(); }1021 \\export fn entry() void { f(); }
796 , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed");1022 ,
1023 ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed",
1024 );
7971025
798 cases.add("bad assignment target",1026 cases.add(
1027 "bad assignment target",
799 \\export fn f() void {1028 \\export fn f() void {
800 \\ 3 = 3;1029 \\ 3 = 3;
801 \\}1030 \\}
802 , ".tmp_source.zig:2:7: error: cannot assign to constant");1031 ,
1032 ".tmp_source.zig:2:7: error: cannot assign to constant",
1033 );
8031034
804 cases.add("assign to constant variable",1035 cases.add(
1036 "assign to constant variable",
805 \\export fn f() void {1037 \\export fn f() void {
806 \\ const a = 3;1038 \\ const a = 3;
807 \\ a = 4;1039 \\ a = 4;
808 \\}1040 \\}
809 , ".tmp_source.zig:3:7: error: cannot assign to constant");1041 ,
1042 ".tmp_source.zig:3:7: error: cannot assign to constant",
1043 );
8101044
811 cases.add("use of undeclared identifier",1045 cases.add(
1046 "use of undeclared identifier",
812 \\export fn f() void {1047 \\export fn f() void {
813 \\ b = 3;1048 \\ b = 3;
814 \\}1049 \\}
815 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");1050 ,
1051 ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'",
1052 );
8161053
817 cases.add("const is a statement, not an expression",1054 cases.add(
1055 "const is a statement, not an expression",
818 \\export fn f() void {1056 \\export fn f() void {
819 \\ (const a = 0);1057 \\ (const a = 0);
820 \\}1058 \\}
821 , ".tmp_source.zig:2:6: error: invalid token: 'const'");1059 ,
1060 ".tmp_source.zig:2:6: error: invalid token: 'const'",
1061 );
8221062
823 cases.add("array access of undeclared identifier",1063 cases.add(
1064 "array access of undeclared identifier",
824 \\export fn f() void {1065 \\export fn f() void {
825 \\ i[i] = i[i];1066 \\ i[i] = i[i];
826 \\}1067 \\}
827 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",1068 ,
828 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'");1069 ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
1070 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'",
1071 );
8291072
830 cases.add("array access of non array",1073 cases.add(
1074 "array access of non array",
831 \\export fn f() void {1075 \\export fn f() void {
832 \\ var bad : bool = undefined;1076 \\ var bad : bool = undefined;
833 \\ bad[bad] = bad[bad];1077 \\ bad[bad] = bad[bad];
834 \\}1078 \\}
835 , ".tmp_source.zig:3:8: error: array access of non-array type 'bool'",1079 ,
836 ".tmp_source.zig:3:19: error: array access of non-array type 'bool'");1080 ".tmp_source.zig:3:8: error: array access of non-array type 'bool'",
1081 ".tmp_source.zig:3:19: error: array access of non-array type 'bool'",
1082 );
8371083
838 cases.add("array access with non integer index",1084 cases.add(
1085 "array access with non integer index",
839 \\export fn f() void {1086 \\export fn f() void {
840 \\ var array = "aoeu";1087 \\ var array = "aoeu";
841 \\ var bad = false;1088 \\ var bad = false;
842 \\ array[bad] = array[bad];1089 \\ array[bad] = array[bad];
843 \\}1090 \\}
844 , ".tmp_source.zig:4:11: error: expected type 'usize', found 'bool'",1091 ,
845 ".tmp_source.zig:4:24: error: expected type 'usize', found 'bool'");1092 ".tmp_source.zig:4:11: error: expected type 'usize', found 'bool'",
1093 ".tmp_source.zig:4:24: error: expected type 'usize', found 'bool'",
1094 );
8461095
847 cases.add("write to const global variable",1096 cases.add(
1097 "write to const global variable",
848 \\const x : i32 = 99;1098 \\const x : i32 = 99;
849 \\fn f() void {1099 \\fn f() void {
850 \\ x = 1;1100 \\ x = 1;
851 \\}1101 \\}
852 \\export fn entry() void { f(); }1102 \\export fn entry() void { f(); }
853 , ".tmp_source.zig:3:7: error: cannot assign to constant");1103 ,
8541104 ".tmp_source.zig:3:7: error: cannot assign to constant",
1105 );
8551106
856 cases.add("missing else clause",1107 cases.add(
1108 "missing else clause",
857 \\fn f(b: bool) void {1109 \\fn f(b: bool) void {
858 \\ const x : i32 = if (b) h: { break :h 1; };1110 \\ const x : i32 = if (b) h: { break :h 1; };
859 \\ const y = if (b) h: { break :h i32(1); };1111 \\ const y = if (b) h: { break :h i32(1); };
860 \\}1112 \\}
861 \\export fn entry() void { f(true); }1113 \\export fn entry() void { f(true); }
862 , ".tmp_source.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",1114 ,
863 ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'");1115 ".tmp_source.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",
1116 ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'",
1117 );
8641118
865 cases.add("direct struct loop",1119 cases.add(
1120 "direct struct loop",
866 \\const A = struct { a : A, };1121 \\const A = struct { a : A, };
867 \\export fn entry() usize { return @sizeOf(A); }1122 \\export fn entry() usize { return @sizeOf(A); }
868 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");1123 ,
1124 ".tmp_source.zig:1:11: error: struct 'A' contains itself",
1125 );
8691126
870 cases.add("indirect struct loop",1127 cases.add(
1128 "indirect struct loop",
871 \\const A = struct { b : B, };1129 \\const A = struct { b : B, };
872 \\const B = struct { c : C, };1130 \\const B = struct { c : C, };
873 \\const C = struct { a : A, };1131 \\const C = struct { a : A, };
874 \\export fn entry() usize { return @sizeOf(A); }1132 \\export fn entry() usize { return @sizeOf(A); }
875 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");1133 ,
1134 ".tmp_source.zig:1:11: error: struct 'A' contains itself",
1135 );
8761136
877 cases.add("invalid struct field",1137 cases.add(
1138 "invalid struct field",
878 \\const A = struct { x : i32, };1139 \\const A = struct { x : i32, };
879 \\export fn f() void {1140 \\export fn f() void {
880 \\ var a : A = undefined;1141 \\ var a : A = undefined;
...@@ -882,27 +1143,37 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -882,27 +1143,37 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
882 \\ const y = a.bar;1143 \\ const y = a.bar;
883 \\}1144 \\}
884 ,1145 ,
885 ".tmp_source.zig:4:6: error: no member named 'foo' in struct 'A'",1146 ".tmp_source.zig:4:6: error: no member named 'foo' in struct 'A'",
886 ".tmp_source.zig:5:16: error: no member named 'bar' in struct 'A'");1147 ".tmp_source.zig:5:16: error: no member named 'bar' in struct 'A'",
1148 );
8871149
888 cases.add("redefinition of struct",1150 cases.add(
1151 "redefinition of struct",
889 \\const A = struct { x : i32, };1152 \\const A = struct { x : i32, };
890 \\const A = struct { y : i32, };1153 \\const A = struct { y : i32, };
891 , ".tmp_source.zig:2:1: error: redefinition of 'A'");1154 ,
1155 ".tmp_source.zig:2:1: error: redefinition of 'A'",
1156 );
8921157
893 cases.add("redefinition of enums",1158 cases.add(
1159 "redefinition of enums",
894 \\const A = enum {};1160 \\const A = enum {};
895 \\const A = enum {};1161 \\const A = enum {};
896 , ".tmp_source.zig:2:1: error: redefinition of 'A'");1162 ,
1163 ".tmp_source.zig:2:1: error: redefinition of 'A'",
1164 );
8971165
898 cases.add("redefinition of global variables",1166 cases.add(
1167 "redefinition of global variables",
899 \\var a : i32 = 1;1168 \\var a : i32 = 1;
900 \\var a : i32 = 2;1169 \\var a : i32 = 2;
901 ,1170 ,
902 ".tmp_source.zig:2:1: error: redefinition of 'a'",1171 ".tmp_source.zig:2:1: error: redefinition of 'a'",
903 ".tmp_source.zig:1:1: note: previous definition is here");1172 ".tmp_source.zig:1:1: note: previous definition is here",
1173 );
9041174
905 cases.add("duplicate field in struct value expression",1175 cases.add(
1176 "duplicate field in struct value expression",
906 \\const A = struct {1177 \\const A = struct {
907 \\ x : i32,1178 \\ x : i32,
908 \\ y : i32,1179 \\ y : i32,
...@@ -916,9 +1187,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -916,9 +1187,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
916 \\ .z = 4,1187 \\ .z = 4,
917 \\ };1188 \\ };
918 \\}1189 \\}
919 , ".tmp_source.zig:11:9: error: duplicate field");1190 ,
1191 ".tmp_source.zig:11:9: error: duplicate field",
1192 );
9201193
921 cases.add("missing field in struct value expression",1194 cases.add(
1195 "missing field in struct value expression",
922 \\const A = struct {1196 \\const A = struct {
923 \\ x : i32,1197 \\ x : i32,
924 \\ y : i32,1198 \\ y : i32,
...@@ -932,9 +1206,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -932,9 +1206,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
932 \\ .y = 2,1206 \\ .y = 2,
933 \\ };1207 \\ };
934 \\}1208 \\}
935 , ".tmp_source.zig:9:17: error: missing field: 'x'");1209 ,
1210 ".tmp_source.zig:9:17: error: missing field: 'x'",
1211 );
9361212
937 cases.add("invalid field in struct value expression",1213 cases.add(
1214 "invalid field in struct value expression",
938 \\const A = struct {1215 \\const A = struct {
939 \\ x : i32,1216 \\ x : i32,
940 \\ y : i32,1217 \\ y : i32,
...@@ -947,66 +1224,95 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -947,66 +1224,95 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
947 \\ .foo = 42,1224 \\ .foo = 42,
948 \\ };1225 \\ };
949 \\}1226 \\}
950 , ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'");1227 ,
1228 ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'",
1229 );
9511230
952 cases.add("invalid break expression",1231 cases.add(
1232 "invalid break expression",
953 \\export fn f() void {1233 \\export fn f() void {
954 \\ break;1234 \\ break;
955 \\}1235 \\}
956 , ".tmp_source.zig:2:5: error: break expression outside loop");1236 ,
1237 ".tmp_source.zig:2:5: error: break expression outside loop",
1238 );
9571239
958 cases.add("invalid continue expression",1240 cases.add(
1241 "invalid continue expression",
959 \\export fn f() void {1242 \\export fn f() void {
960 \\ continue;1243 \\ continue;
961 \\}1244 \\}
962 , ".tmp_source.zig:2:5: error: continue expression outside loop");1245 ,
1246 ".tmp_source.zig:2:5: error: continue expression outside loop",
1247 );
9631248
964 cases.add("invalid maybe type",1249 cases.add(
1250 "invalid maybe type",
965 \\export fn f() void {1251 \\export fn f() void {
966 \\ if (true) |x| { }1252 \\ if (true) |x| { }
967 \\}1253 \\}
968 , ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'");1254 ,
1255 ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'",
1256 );
9691257
970 cases.add("cast unreachable",1258 cases.add(
1259 "cast unreachable",
971 \\fn f() i32 {1260 \\fn f() i32 {
972 \\ return i32(return 1);1261 \\ return i32(return 1);
973 \\}1262 \\}
974 \\export fn entry() void { _ = f(); }1263 \\export fn entry() void { _ = f(); }
975 , ".tmp_source.zig:2:15: error: unreachable code");1264 ,
1265 ".tmp_source.zig:2:15: error: unreachable code",
1266 );
9761267
977 cases.add("invalid builtin fn",1268 cases.add(
1269 "invalid builtin fn",
978 \\fn f() @bogus(foo) {1270 \\fn f() @bogus(foo) {
979 \\}1271 \\}
980 \\export fn entry() void { _ = f(); }1272 \\export fn entry() void { _ = f(); }
981 , ".tmp_source.zig:1:8: error: invalid builtin function: 'bogus'");1273 ,
1274 ".tmp_source.zig:1:8: error: invalid builtin function: 'bogus'",
1275 );
9821276
983 cases.add("top level decl dependency loop",1277 cases.add(
1278 "top level decl dependency loop",
984 \\const a : @typeOf(b) = 0;1279 \\const a : @typeOf(b) = 0;
985 \\const b : @typeOf(a) = 0;1280 \\const b : @typeOf(a) = 0;
986 \\export fn entry() void {1281 \\export fn entry() void {
987 \\ const c = a + b;1282 \\ const c = a + b;
988 \\}1283 \\}
989 , ".tmp_source.zig:1:1: error: 'a' depends on itself");1284 ,
1285 ".tmp_source.zig:1:1: error: 'a' depends on itself",
1286 );
9901287
991 cases.add("noalias on non pointer param",1288 cases.add(
1289 "noalias on non pointer param",
992 \\fn f(noalias x: i32) void {}1290 \\fn f(noalias x: i32) void {}
993 \\export fn entry() void { f(1234); }1291 \\export fn entry() void { f(1234); }
994 , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter");1292 ,
1293 ".tmp_source.zig:1:6: error: noalias on non-pointer parameter",
1294 );
9951295
996 cases.add("struct init syntax for array",1296 cases.add(
1297 "struct init syntax for array",
997 \\const foo = []u16{.x = 1024,};1298 \\const foo = []u16{.x = 1024,};
998 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }1299 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
999 , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax");1300 ,
1301 ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax",
1302 );
10001303
1001 cases.add("type variables must be constant",1304 cases.add(
1305 "type variables must be constant",
1002 \\var foo = u8;1306 \\var foo = u8;
1003 \\export fn entry() foo {1307 \\export fn entry() foo {
1004 \\ return 1;1308 \\ return 1;
1005 \\}1309 \\}
1006 , ".tmp_source.zig:1:1: error: variable of type 'type' must be constant");1310 ,
10071311 ".tmp_source.zig:1:1: error: variable of type 'type' must be constant",
1312 );
10081313
1009 cases.add("variables shadowing types",1314 cases.add(
1315 "variables shadowing types",
1010 \\const Foo = struct {};1316 \\const Foo = struct {};
1011 \\const Bar = struct {};1317 \\const Bar = struct {};
1012 \\1318 \\
...@@ -1018,12 +1324,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1018,12 +1324,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1018 \\ f(1234);1324 \\ f(1234);
1019 \\}1325 \\}
1020 ,1326 ,
1021 ".tmp_source.zig:4:6: error: redefinition of 'Foo'",1327 ".tmp_source.zig:4:6: error: redefinition of 'Foo'",
1022 ".tmp_source.zig:1:1: note: previous definition is here",1328 ".tmp_source.zig:1:1: note: previous definition is here",
1023 ".tmp_source.zig:5:5: error: redefinition of 'Bar'",1329 ".tmp_source.zig:5:5: error: redefinition of 'Bar'",
1024 ".tmp_source.zig:2:1: note: previous definition is here");1330 ".tmp_source.zig:2:1: note: previous definition is here",
1331 );
10251332
1026 cases.add("switch expression - missing enumeration prong",1333 cases.add(
1334 "switch expression - missing enumeration prong",
1027 \\const Number = enum {1335 \\const Number = enum {
1028 \\ One,1336 \\ One,
1029 \\ Two,1337 \\ Two,
...@@ -1039,9 +1347,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1039,9 +1347,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1039 \\}1347 \\}
1040 \\1348 \\
1041 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }1349 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1042 , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch");1350 ,
1351 ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch",
1352 );
10431353
1044 cases.add("switch expression - duplicate enumeration prong",1354 cases.add(
1355 "switch expression - duplicate enumeration prong",
1045 \\const Number = enum {1356 \\const Number = enum {
1046 \\ One,1357 \\ One,
1047 \\ Two,1358 \\ Two,
...@@ -1059,10 +1370,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1059,10 +1370,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1059 \\}1370 \\}
1060 \\1371 \\
1061 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }1372 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1062 , ".tmp_source.zig:13:15: error: duplicate switch value",1373 ,
1063 ".tmp_source.zig:10:15: note: other value is here");1374 ".tmp_source.zig:13:15: error: duplicate switch value",
1375 ".tmp_source.zig:10:15: note: other value is here",
1376 );
10641377
1065 cases.add("switch expression - duplicate enumeration prong when else present",1378 cases.add(
1379 "switch expression - duplicate enumeration prong when else present",
1066 \\const Number = enum {1380 \\const Number = enum {
1067 \\ One,1381 \\ One,
1068 \\ Two,1382 \\ Two,
...@@ -1081,10 +1395,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1081,10 +1395,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1081 \\}1395 \\}
1082 \\1396 \\
1083 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }1397 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1084 , ".tmp_source.zig:13:15: error: duplicate switch value",1398 ,
1085 ".tmp_source.zig:10:15: note: other value is here");1399 ".tmp_source.zig:13:15: error: duplicate switch value",
1400 ".tmp_source.zig:10:15: note: other value is here",
1401 );
10861402
1087 cases.add("switch expression - multiple else prongs",1403 cases.add(
1404 "switch expression - multiple else prongs",
1088 \\fn f(x: u32) void {1405 \\fn f(x: u32) void {
1089 \\ const value: bool = switch (x) {1406 \\ const value: bool = switch (x) {
1090 \\ 1234 => false,1407 \\ 1234 => false,
...@@ -1095,9 +1412,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1095,9 +1412,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1095 \\export fn entry() void {1412 \\export fn entry() void {
1096 \\ f(1234);1413 \\ f(1234);
1097 \\}1414 \\}
1098 , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression");1415 ,
1416 ".tmp_source.zig:5:9: error: multiple else prongs in switch expression",
1417 );
10991418
1100 cases.add("switch expression - non exhaustive integer prongs",1419 cases.add(
1420 "switch expression - non exhaustive integer prongs",
1101 \\fn foo(x: u8) void {1421 \\fn foo(x: u8) void {
1102 \\ switch (x) {1422 \\ switch (x) {
1103 \\ 0 => {},1423 \\ 0 => {},
...@@ -1105,9 +1425,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1105,9 +1425,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1105 \\}1425 \\}
1106 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }1426 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1107 ,1427 ,
1108 ".tmp_source.zig:2:5: error: switch must handle all possibilities");1428 ".tmp_source.zig:2:5: error: switch must handle all possibilities",
1429 );
11091430
1110 cases.add("switch expression - duplicate or overlapping integer value",1431 cases.add(
1432 "switch expression - duplicate or overlapping integer value",
1111 \\fn foo(x: u8) u8 {1433 \\fn foo(x: u8) u8 {
1112 \\ return switch (x) {1434 \\ return switch (x) {
1113 \\ 0 ... 100 => u8(0),1435 \\ 0 ... 100 => u8(0),
...@@ -1119,9 +1441,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1119,9 +1441,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1119 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }1441 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1120 ,1442 ,
1121 ".tmp_source.zig:6:9: error: duplicate switch value",1443 ".tmp_source.zig:6:9: error: duplicate switch value",
1122 ".tmp_source.zig:5:14: note: previous value is here");1444 ".tmp_source.zig:5:14: note: previous value is here",
1445 );
11231446
1124 cases.add("switch expression - switch on pointer type with no else",1447 cases.add(
1448 "switch expression - switch on pointer type with no else",
1125 \\fn foo(x: &u8) void {1449 \\fn foo(x: &u8) void {
1126 \\ switch (x) {1450 \\ switch (x) {
1127 \\ &y => {},1451 \\ &y => {},
...@@ -1130,54 +1454,77 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1130,54 +1454,77 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1130 \\const y: u8 = 100;1454 \\const y: u8 = 100;
1131 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }1455 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1132 ,1456 ,
1133 ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'");1457 ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'",
1458 );
11341459
1135 cases.add("global variable initializer must be constant expression",1460 cases.add(
1461 "global variable initializer must be constant expression",
1136 \\extern fn foo() i32;1462 \\extern fn foo() i32;
1137 \\const x = foo();1463 \\const x = foo();
1138 \\export fn entry() i32 { return x; }1464 \\export fn entry() i32 { return x; }
1139 , ".tmp_source.zig:2:11: error: unable to evaluate constant expression");1465 ,
1466 ".tmp_source.zig:2:11: error: unable to evaluate constant expression",
1467 );
11401468
1141 cases.add("array concatenation with wrong type",1469 cases.add(
1470 "array concatenation with wrong type",
1142 \\const src = "aoeu";1471 \\const src = "aoeu";
1143 \\const derp = usize(1234);1472 \\const derp = usize(1234);
1144 \\const a = derp ++ "foo";1473 \\const a = derp ++ "foo";
1145 \\1474 \\
1146 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }1475 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
1147 , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'");1476 ,
1477 ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'",
1478 );
11481479
1149 cases.add("non compile time array concatenation",1480 cases.add(
1481 "non compile time array concatenation",
1150 \\fn f() []u8 {1482 \\fn f() []u8 {
1151 \\ return s ++ "foo";1483 \\ return s ++ "foo";
1152 \\}1484 \\}
1153 \\var s: [10]u8 = undefined;1485 \\var s: [10]u8 = undefined;
1154 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }1486 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1155 , ".tmp_source.zig:2:12: error: unable to evaluate constant expression");1487 ,
1488 ".tmp_source.zig:2:12: error: unable to evaluate constant expression",
1489 );
11561490
1157 cases.add("@cImport with bogus include",1491 cases.add(
1492 "@cImport with bogus include",
1158 \\const c = @cImport(@cInclude("bogus.h"));1493 \\const c = @cImport(@cInclude("bogus.h"));
1159 \\export fn entry() usize { return @sizeOf(@typeOf(c.bogo)); }1494 \\export fn entry() usize { return @sizeOf(@typeOf(c.bogo)); }
1160 , ".tmp_source.zig:1:11: error: C import failed",1495 ,
1161 ".h:1:10: note: 'bogus.h' file not found");1496 ".tmp_source.zig:1:11: error: C import failed",
1497 ".h:1:10: note: 'bogus.h' file not found",
1498 );
11621499
1163 cases.add("address of number literal",1500 cases.add(
1501 "address of number literal",
1164 \\const x = 3;1502 \\const x = 3;
1165 \\const y = &x;1503 \\const y = &x;
1166 \\fn foo() &const i32 { return y; }1504 \\fn foo() &const i32 { return y; }
1167 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }1505 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1168 , ".tmp_source.zig:3:30: error: expected type '&const i32', found '&const (integer literal)'");1506 ,
1507 ".tmp_source.zig:3:30: error: expected type '&const i32', found '&const (integer literal)'",
1508 );
11691509
1170 cases.add("integer overflow error",1510 cases.add(
1511 "integer overflow error",
1171 \\const x : u8 = 300;1512 \\const x : u8 = 300;
1172 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }1513 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
1173 , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'");1514 ,
1515 ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'",
1516 );
11741517
1175 cases.add("incompatible number literals",1518 cases.add(
1519 "incompatible number literals",
1176 \\const x = 2 == 2.0;1520 \\const x = 2 == 2.0;
1177 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }1521 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
1178 , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");1522 ,
1523 ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'",
1524 );
11791525
1180 cases.add("missing function call param",1526 cases.add(
1527 "missing function call param",
1181 \\const Foo = struct {1528 \\const Foo = struct {
1182 \\ a: i32,1529 \\ a: i32,
1183 \\ b: i32,1530 \\ b: i32,
...@@ -1201,58 +1548,73 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1201,58 +1548,73 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1201 \\}1548 \\}
1202 \\1549 \\
1203 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }1550 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1204 , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0");1551 ,
1552 ".tmp_source.zig:20:34: error: expected 1 arguments, found 0",
1553 );
12051554
1206 cases.add("missing function name and param name",1555 cases.add(
1556 "missing function name and param name",
1207 \\fn () void {}1557 \\fn () void {}
1208 \\fn f(i32) void {}1558 \\fn f(i32) void {}
1209 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }1559 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1210 ,1560 ,
1211 ".tmp_source.zig:1:1: error: missing function name",1561 ".tmp_source.zig:1:1: error: missing function name",
1212 ".tmp_source.zig:2:6: error: missing parameter name");1562 ".tmp_source.zig:2:6: error: missing parameter name",
1563 );
12131564
1214 cases.add("wrong function type",1565 cases.add(
1566 "wrong function type",
1215 \\const fns = []fn() void { a, b, c };1567 \\const fns = []fn() void { a, b, c };
1216 \\fn a() i32 {return 0;}1568 \\fn a() i32 {return 0;}
1217 \\fn b() i32 {return 1;}1569 \\fn b() i32 {return 1;}
1218 \\fn c() i32 {return 2;}1570 \\fn c() i32 {return 2;}
1219 \\export fn entry() usize { return @sizeOf(@typeOf(fns)); }1571 \\export fn entry() usize { return @sizeOf(@typeOf(fns)); }
1220 , ".tmp_source.zig:1:27: error: expected type 'fn() void', found 'fn() i32'");1572 ,
1573 ".tmp_source.zig:1:27: error: expected type 'fn() void', found 'fn() i32'",
1574 );
12211575
1222 cases.add("extern function pointer mismatch",1576 cases.add(
1577 "extern function pointer mismatch",
1223 \\const fns = [](fn(i32)i32) { a, b, c };1578 \\const fns = [](fn(i32)i32) { a, b, c };
1224 \\pub fn a(x: i32) i32 {return x + 0;}1579 \\pub fn a(x: i32) i32 {return x + 0;}
1225 \\pub fn b(x: i32) i32 {return x + 1;}1580 \\pub fn b(x: i32) i32 {return x + 1;}
1226 \\export fn c(x: i32) i32 {return x + 2;}1581 \\export fn c(x: i32) i32 {return x + 2;}
1227 \\1582 \\
1228 \\export fn entry() usize { return @sizeOf(@typeOf(fns)); }1583 \\export fn entry() usize { return @sizeOf(@typeOf(fns)); }
1229 , ".tmp_source.zig:1:36: error: expected type 'fn(i32) i32', found 'extern fn(i32) i32'");1584 ,
12301585 ".tmp_source.zig:1:36: error: expected type 'fn(i32) i32', found 'extern fn(i32) i32'",
1586 );
12311587
1232 cases.add("implicit cast from f64 to f32",1588 cases.add(
1589 "implicit cast from f64 to f32",
1233 \\const x : f64 = 1.0;1590 \\const x : f64 = 1.0;
1234 \\const y : f32 = x;1591 \\const y : f32 = x;
1235 \\1592 \\
1236 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }1593 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1237 , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'");1594 ,
12381595 ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'",
1596 );
12391597
1240 cases.add("colliding invalid top level functions",1598 cases.add(
1599 "colliding invalid top level functions",
1241 \\fn func() bogus {}1600 \\fn func() bogus {}
1242 \\fn func() bogus {}1601 \\fn func() bogus {}
1243 \\export fn entry() usize { return @sizeOf(@typeOf(func)); }1602 \\export fn entry() usize { return @sizeOf(@typeOf(func)); }
1244 ,1603 ,
1245 ".tmp_source.zig:2:1: error: redefinition of 'func'",1604 ".tmp_source.zig:2:1: error: redefinition of 'func'",
1246 ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'");1605 ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'",
1606 );
12471607
12481608 cases.add(
1249 cases.add("bogus compile var",1609 "bogus compile var",
1250 \\const x = @import("builtin").bogus;1610 \\const x = @import("builtin").bogus;
1251 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }1611 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
1252 , ".tmp_source.zig:1:29: error: no member named 'bogus' in '");1612 ,
12531613 ".tmp_source.zig:1:29: error: no member named 'bogus' in '",
1614 );
12541615
1255 cases.add("non constant expression in array size outside function",1616 cases.add(
1617 "non constant expression in array size outside function",
1256 \\const Foo = struct {1618 \\const Foo = struct {
1257 \\ y: [get()]u8,1619 \\ y: [get()]u8,
1258 \\};1620 \\};
...@@ -1261,22 +1623,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1261,22 +1623,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1261 \\1623 \\
1262 \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }1624 \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }
1263 ,1625 ,
1264 ".tmp_source.zig:5:25: error: unable to evaluate constant expression",1626 ".tmp_source.zig:5:25: error: unable to evaluate constant expression",
1265 ".tmp_source.zig:2:12: note: called from here",1627 ".tmp_source.zig:2:12: note: called from here",
1266 ".tmp_source.zig:2:8: note: called from here");1628 ".tmp_source.zig:2:8: note: called from here",
12671629 );
12681630
1269 cases.add("addition with non numbers",1631 cases.add(
1632 "addition with non numbers",
1270 \\const Foo = struct {1633 \\const Foo = struct {
1271 \\ field: i32,1634 \\ field: i32,
1272 \\};1635 \\};
1273 \\const x = Foo {.field = 1} + Foo {.field = 2};1636 \\const x = Foo {.field = 1} + Foo {.field = 2};
1274 \\1637 \\
1275 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }1638 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
1276 , ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");1639 ,
12771640 ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'",
1641 );
12781642
1279 cases.add("division by zero",1643 cases.add(
1644 "division by zero",
1280 \\const lit_int_x = 1 / 0;1645 \\const lit_int_x = 1 / 0;
1281 \\const lit_float_x = 1.0 / 0.0;1646 \\const lit_float_x = 1.0 / 0.0;
1282 \\const int_x = u32(1) / u32(0);1647 \\const int_x = u32(1) / u32(0);
...@@ -1287,49 +1652,65 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1287,49 +1652,65 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1287 \\export fn entry3() usize { return @sizeOf(@typeOf(int_x)); }1652 \\export fn entry3() usize { return @sizeOf(@typeOf(int_x)); }
1288 \\export fn entry4() usize { return @sizeOf(@typeOf(float_x)); }1653 \\export fn entry4() usize { return @sizeOf(@typeOf(float_x)); }
1289 ,1654 ,
1290 ".tmp_source.zig:1:21: error: division by zero",1655 ".tmp_source.zig:1:21: error: division by zero",
1291 ".tmp_source.zig:2:25: error: division by zero",1656 ".tmp_source.zig:2:25: error: division by zero",
1292 ".tmp_source.zig:3:22: error: division by zero",1657 ".tmp_source.zig:3:22: error: division by zero",
1293 ".tmp_source.zig:4:26: error: division by zero");1658 ".tmp_source.zig:4:26: error: division by zero",
12941659 );
12951660
1296 cases.add("normal string with newline",1661 cases.add(
1662 "normal string with newline",
1297 \\const foo = "a1663 \\const foo = "a
1298 \\b";1664 \\b";
1299 \\1665 \\
1300 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }1666 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1301 , ".tmp_source.zig:1:13: error: newline not allowed in string literal");1667 ,
1668 ".tmp_source.zig:1:13: error: newline not allowed in string literal",
1669 );
13021670
1303 cases.add("invalid comparison for function pointers",1671 cases.add(
1672 "invalid comparison for function pointers",
1304 \\fn foo() void {}1673 \\fn foo() void {}
1305 \\const invalid = foo > foo;1674 \\const invalid = foo > foo;
1306 \\1675 \\
1307 \\export fn entry() usize { return @sizeOf(@typeOf(invalid)); }1676 \\export fn entry() usize { return @sizeOf(@typeOf(invalid)); }
1308 , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn() void'");1677 ,
1678 ".tmp_source.zig:2:21: error: operator not allowed for type 'fn() void'",
1679 );
13091680
1310 cases.add("generic function instance with non-constant expression",1681 cases.add(
1682 "generic function instance with non-constant expression",
1311 \\fn foo(comptime x: i32, y: i32) i32 { return x + y; }1683 \\fn foo(comptime x: i32, y: i32) i32 { return x + y; }
1312 \\fn test1(a: i32, b: i32) i32 {1684 \\fn test1(a: i32, b: i32) i32 {
1313 \\ return foo(a, b);1685 \\ return foo(a, b);
1314 \\}1686 \\}
1315 \\1687 \\
1316 \\export fn entry() usize { return @sizeOf(@typeOf(test1)); }1688 \\export fn entry() usize { return @sizeOf(@typeOf(test1)); }
1317 , ".tmp_source.zig:3:16: error: unable to evaluate constant expression");1689 ,
1690 ".tmp_source.zig:3:16: error: unable to evaluate constant expression",
1691 );
13181692
1319 cases.add("assign null to non-nullable pointer",1693 cases.add(
1694 "assign null to non-nullable pointer",
1320 \\const a: &u8 = null;1695 \\const a: &u8 = null;
1321 \\1696 \\
1322 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }1697 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
1323 , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'");1698 ,
1699 ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'",
1700 );
13241701
1325 cases.add("indexing an array of size zero",1702 cases.add(
1703 "indexing an array of size zero",
1326 \\const array = []u8{};1704 \\const array = []u8{};
1327 \\export fn foo() void {1705 \\export fn foo() void {
1328 \\ const pointer = &array[0];1706 \\ const pointer = &array[0];
1329 \\}1707 \\}
1330 , ".tmp_source.zig:3:27: error: index 0 outside array of size 0");1708 ,
1709 ".tmp_source.zig:3:27: error: index 0 outside array of size 0",
1710 );
13311711
1332 cases.add("compile time division by zero",1712 cases.add(
1713 "compile time division by zero",
1333 \\const y = foo(0);1714 \\const y = foo(0);
1334 \\fn foo(x: u32) u32 {1715 \\fn foo(x: u32) u32 {
1335 \\ return 1 / x;1716 \\ return 1 / x;
...@@ -1337,17 +1718,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1337,17 +1718,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1337 \\1718 \\
1338 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }1719 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1339 ,1720 ,
1340 ".tmp_source.zig:3:14: error: division by zero",1721 ".tmp_source.zig:3:14: error: division by zero",
1341 ".tmp_source.zig:1:14: note: called from here");1722 ".tmp_source.zig:1:14: note: called from here",
1723 );
13421724
1343 cases.add("branch on undefined value",1725 cases.add(
1726 "branch on undefined value",
1344 \\const x = if (undefined) true else false;1727 \\const x = if (undefined) true else false;
1345 \\1728 \\
1346 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }1729 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
1347 , ".tmp_source.zig:1:15: error: use of undefined value");1730 ,
13481731 ".tmp_source.zig:1:15: error: use of undefined value",
1732 );
13491733
1350 cases.add("endless loop in function evaluation",1734 cases.add(
1735 "endless loop in function evaluation",
1351 \\const seventh_fib_number = fibbonaci(7);1736 \\const seventh_fib_number = fibbonaci(7);
1352 \\fn fibbonaci(x: i32) i32 {1737 \\fn fibbonaci(x: i32) i32 {
1353 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);1738 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);
...@@ -1355,16 +1740,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1355,16 +1740,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1355 \\1740 \\
1356 \\export fn entry() usize { return @sizeOf(@typeOf(seventh_fib_number)); }1741 \\export fn entry() usize { return @sizeOf(@typeOf(seventh_fib_number)); }
1357 ,1742 ,
1358 ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",1743 ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",
1359 ".tmp_source.zig:3:21: note: called from here");1744 ".tmp_source.zig:3:21: note: called from here",
1745 );
13601746
1361 cases.add("@embedFile with bogus file",1747 cases.add(
1362 \\const resource = @embedFile("bogus.txt");1748 "@embedFile with bogus file",
1749 \\const resource = @embedFile("bogus.txt",);
1363 \\1750 \\
1364 \\export fn entry() usize { return @sizeOf(@typeOf(resource)); }1751 \\export fn entry() usize { return @sizeOf(@typeOf(resource)); }
1365 , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");1752 ,
1753 ".tmp_source.zig:1:29: error: unable to find '",
1754 "bogus.txt'",
1755 );
13661756
1367 cases.add("non-const expression in struct literal outside function",1757 cases.add(
1758 "non-const expression in struct literal outside function",
1368 \\const Foo = struct {1759 \\const Foo = struct {
1369 \\ x: i32,1760 \\ x: i32,
1370 \\};1761 \\};
...@@ -1372,9 +1763,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1372,9 +1763,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1372 \\extern fn get_it() i32;1763 \\extern fn get_it() i32;
1373 \\1764 \\
1374 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }1765 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
1375 , ".tmp_source.zig:4:21: error: unable to evaluate constant expression");1766 ,
1767 ".tmp_source.zig:4:21: error: unable to evaluate constant expression",
1768 );
13761769
1377 cases.add("non-const expression function call with struct return value outside function",1770 cases.add(
1771 "non-const expression function call with struct return value outside function",
1378 \\const Foo = struct {1772 \\const Foo = struct {
1379 \\ x: i32,1773 \\ x: i32,
1380 \\};1774 \\};
...@@ -1387,19 +1781,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1387,19 +1781,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1387 \\1781 \\
1388 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }1782 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
1389 ,1783 ,
1390 ".tmp_source.zig:6:24: error: unable to evaluate constant expression",1784 ".tmp_source.zig:6:24: error: unable to evaluate constant expression",
1391 ".tmp_source.zig:4:17: note: called from here");1785 ".tmp_source.zig:4:17: note: called from here",
1786 );
13921787
1393 cases.add("undeclared identifier error should mark fn as impure",1788 cases.add(
1789 "undeclared identifier error should mark fn as impure",
1394 \\export fn foo() void {1790 \\export fn foo() void {
1395 \\ test_a_thing();1791 \\ test_a_thing();
1396 \\}1792 \\}
1397 \\fn test_a_thing() void {1793 \\fn test_a_thing() void {
1398 \\ bad_fn_call();1794 \\ bad_fn_call();
1399 \\}1795 \\}
1400 , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'");1796 ,
1797 ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'",
1798 );
14011799
1402 cases.add("illegal comparison of types",1800 cases.add(
1801 "illegal comparison of types",
1403 \\fn bad_eql_1(a: []u8, b: []u8) bool {1802 \\fn bad_eql_1(a: []u8, b: []u8) bool {
1404 \\ return a == b;1803 \\ return a == b;
1405 \\}1804 \\}
...@@ -1408,16 +1807,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1408,16 +1807,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1408 \\ Two: i32,1807 \\ Two: i32,
1409 \\};1808 \\};
1410 \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) bool {1809 \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) bool {
1411 \\ return *a == *b;1810 \\ return a.* == b.*;
1412 \\}1811 \\}
1413 \\1812 \\
1414 \\export fn entry1() usize { return @sizeOf(@typeOf(bad_eql_1)); }1813 \\export fn entry1() usize { return @sizeOf(@typeOf(bad_eql_1)); }
1415 \\export fn entry2() usize { return @sizeOf(@typeOf(bad_eql_2)); }1814 \\export fn entry2() usize { return @sizeOf(@typeOf(bad_eql_2)); }
1416 ,1815 ,
1417 ".tmp_source.zig:2:14: error: operator not allowed for type '[]u8'",1816 ".tmp_source.zig:2:14: error: operator not allowed for type '[]u8'",
1418 ".tmp_source.zig:9:15: error: operator not allowed for type 'EnumWithData'");1817 ".tmp_source.zig:9:16: error: operator not allowed for type 'EnumWithData'",
1818 );
14191819
1420 cases.add("non-const switch number literal",1820 cases.add(
1821 "non-const switch number literal",
1421 \\export fn foo() void {1822 \\export fn foo() void {
1422 \\ const x = switch (bar()) {1823 \\ const x = switch (bar()) {
1423 \\ 1, 2 => 1,1824 \\ 1, 2 => 1,
...@@ -1428,25 +1829,34 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1428,25 +1829,34 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1428 \\fn bar() i32 {1829 \\fn bar() i32 {
1429 \\ return 2;1830 \\ return 2;
1430 \\}1831 \\}
1431 , ".tmp_source.zig:2:15: error: unable to infer expression type");1832 ,
1833 ".tmp_source.zig:2:15: error: unable to infer expression type",
1834 );
14321835
1433 cases.add("atomic orderings of cmpxchg - failure stricter than success",1836 cases.add(
1837 "atomic orderings of cmpxchg - failure stricter than success",
1434 \\const AtomicOrder = @import("builtin").AtomicOrder;1838 \\const AtomicOrder = @import("builtin").AtomicOrder;
1435 \\export fn f() void {1839 \\export fn f() void {
1436 \\ var x: i32 = 1234;1840 \\ var x: i32 = 1234;
1437 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}1841 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
1438 \\}1842 \\}
1439 , ".tmp_source.zig:4:81: error: failure atomic ordering must be no stricter than success");1843 ,
1844 ".tmp_source.zig:4:81: error: failure atomic ordering must be no stricter than success",
1845 );
14401846
1441 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",1847 cases.add(
1848 "atomic orderings of cmpxchg - success Monotonic or stricter",
1442 \\const AtomicOrder = @import("builtin").AtomicOrder;1849 \\const AtomicOrder = @import("builtin").AtomicOrder;
1443 \\export fn f() void {1850 \\export fn f() void {
1444 \\ var x: i32 = 1234;1851 \\ var x: i32 = 1234;
1445 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}1852 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
1446 \\}1853 \\}
1447 , ".tmp_source.zig:4:58: error: success atomic ordering must be Monotonic or stricter");1854 ,
1855 ".tmp_source.zig:4:58: error: success atomic ordering must be Monotonic or stricter",
1856 );
14481857
1449 cases.add("negation overflow in function evaluation",1858 cases.add(
1859 "negation overflow in function evaluation",
1450 \\const y = neg(-128);1860 \\const y = neg(-128);
1451 \\fn neg(x: i8) i8 {1861 \\fn neg(x: i8) i8 {
1452 \\ return -x;1862 \\ return -x;
...@@ -1454,10 +1864,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1454,10 +1864,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1454 \\1864 \\
1455 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }1865 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1456 ,1866 ,
1457 ".tmp_source.zig:3:12: error: negation caused overflow",1867 ".tmp_source.zig:3:12: error: negation caused overflow",
1458 ".tmp_source.zig:1:14: note: called from here");1868 ".tmp_source.zig:1:14: note: called from here",
1869 );
14591870
1460 cases.add("add overflow in function evaluation",1871 cases.add(
1872 "add overflow in function evaluation",
1461 \\const y = add(65530, 10);1873 \\const y = add(65530, 10);
1462 \\fn add(a: u16, b: u16) u16 {1874 \\fn add(a: u16, b: u16) u16 {
1463 \\ return a + b;1875 \\ return a + b;
...@@ -1465,11 +1877,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1465,11 +1877,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1465 \\1877 \\
1466 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }1878 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1467 ,1879 ,
1468 ".tmp_source.zig:3:14: error: operation caused overflow",1880 ".tmp_source.zig:3:14: error: operation caused overflow",
1469 ".tmp_source.zig:1:14: note: called from here");1881 ".tmp_source.zig:1:14: note: called from here",
14701882 );
14711883
1472 cases.add("sub overflow in function evaluation",1884 cases.add(
1885 "sub overflow in function evaluation",
1473 \\const y = sub(10, 20);1886 \\const y = sub(10, 20);
1474 \\fn sub(a: u16, b: u16) u16 {1887 \\fn sub(a: u16, b: u16) u16 {
1475 \\ return a - b;1888 \\ return a - b;
...@@ -1477,10 +1890,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1477,10 +1890,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1477 \\1890 \\
1478 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }1891 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1479 ,1892 ,
1480 ".tmp_source.zig:3:14: error: operation caused overflow",1893 ".tmp_source.zig:3:14: error: operation caused overflow",
1481 ".tmp_source.zig:1:14: note: called from here");1894 ".tmp_source.zig:1:14: note: called from here",
1895 );
14821896
1483 cases.add("mul overflow in function evaluation",1897 cases.add(
1898 "mul overflow in function evaluation",
1484 \\const y = mul(300, 6000);1899 \\const y = mul(300, 6000);
1485 \\fn mul(a: u16, b: u16) u16 {1900 \\fn mul(a: u16, b: u16) u16 {
1486 \\ return a * b;1901 \\ return a * b;
...@@ -1488,58 +1903,77 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1488,58 +1903,77 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1488 \\1903 \\
1489 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }1904 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1490 ,1905 ,
1491 ".tmp_source.zig:3:14: error: operation caused overflow",1906 ".tmp_source.zig:3:14: error: operation caused overflow",
1492 ".tmp_source.zig:1:14: note: called from here");1907 ".tmp_source.zig:1:14: note: called from here",
1908 );
14931909
1494 cases.add("truncate sign mismatch",1910 cases.add(
1911 "truncate sign mismatch",
1495 \\fn f() i8 {1912 \\fn f() i8 {
1496 \\ const x: u32 = 10;1913 \\ const x: u32 = 10;
1497 \\ return @truncate(i8, x);1914 \\ return @truncate(i8, x);
1498 \\}1915 \\}
1499 \\1916 \\
1500 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }1917 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1501 , ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'");1918 ,
1919 ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'",
1920 );
15021921
1503 cases.add("try in function with non error return type",1922 cases.add(
1923 "try in function with non error return type",
1504 \\export fn f() void {1924 \\export fn f() void {
1505 \\ try something();1925 \\ try something();
1506 \\}1926 \\}
1507 \\fn something() error!void { }1927 \\fn something() error!void { }
1508 ,1928 ,
1509 ".tmp_source.zig:2:5: error: expected type 'void', found 'error'");1929 ".tmp_source.zig:2:5: error: expected type 'void', found 'error'",
1930 );
15101931
1511 cases.add("invalid pointer for var type",1932 cases.add(
1933 "invalid pointer for var type",
1512 \\extern fn ext() usize;1934 \\extern fn ext() usize;
1513 \\var bytes: [ext()]u8 = undefined;1935 \\var bytes: [ext()]u8 = undefined;
1514 \\export fn f() void {1936 \\export fn f() void {
1515 \\ for (bytes) |*b, i| {1937 \\ for (bytes) |*b, i| {
1516 \\ *b = u8(i);1938 \\ b.* = u8(i);
1517 \\ }1939 \\ }
1518 \\}1940 \\}
1519 , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");1941 ,
1942 ".tmp_source.zig:2:13: error: unable to evaluate constant expression",
1943 );
15201944
1521 cases.add("export function with comptime parameter",1945 cases.add(
1946 "export function with comptime parameter",
1522 \\export fn foo(comptime x: i32, y: i32) i32{1947 \\export fn foo(comptime x: i32, y: i32) i32{
1523 \\ return x + y;1948 \\ return x + y;
1524 \\}1949 \\}
1525 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");1950 ,
1951 ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'",
1952 );
15261953
1527 cases.add("extern function with comptime parameter",1954 cases.add(
1955 "extern function with comptime parameter",
1528 \\extern fn foo(comptime x: i32, y: i32) i32;1956 \\extern fn foo(comptime x: i32, y: i32) i32;
1529 \\fn f() i32 {1957 \\fn f() i32 {
1530 \\ return foo(1, 2);1958 \\ return foo(1, 2);
1531 \\}1959 \\}
1532 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }1960 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1533 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");1961 ,
1962 ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'",
1963 );
15341964
1535 cases.add("convert fixed size array to slice with invalid size",1965 cases.add(
1966 "convert fixed size array to slice with invalid size",
1536 \\export fn f() void {1967 \\export fn f() void {
1537 \\ var array: [5]u8 = undefined;1968 \\ var array: [5]u8 = undefined;
1538 \\ var foo = ([]const u32)(array)[0];1969 \\ var foo = ([]const u32)(array)[0];
1539 \\}1970 \\}
1540 , ".tmp_source.zig:3:28: error: unable to convert [5]u8 to []const u32: size mismatch");1971 ,
1972 ".tmp_source.zig:3:28: error: unable to convert [5]u8 to []const u32: size mismatch",
1973 );
15411974
1542 cases.add("non-pure function returns type",1975 cases.add(
1976 "non-pure function returns type",
1543 \\var a: u32 = 0;1977 \\var a: u32 = 0;
1544 \\pub fn List(comptime T: type) type {1978 \\pub fn List(comptime T: type) type {
1545 \\ a += 1;1979 \\ a += 1;
...@@ -1558,18 +1992,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1558,18 +1992,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1558 \\ var list: List(i32) = undefined;1992 \\ var list: List(i32) = undefined;
1559 \\ list.length = 10;1993 \\ list.length = 10;
1560 \\}1994 \\}
1561 , ".tmp_source.zig:3:7: error: unable to evaluate constant expression",1995 ,
1562 ".tmp_source.zig:16:19: note: called from here");1996 ".tmp_source.zig:3:7: error: unable to evaluate constant expression",
1997 ".tmp_source.zig:16:19: note: called from here",
1998 );
15631999
1564 cases.add("bogus method call on slice",2000 cases.add(
2001 "bogus method call on slice",
1565 \\var self = "aoeu";2002 \\var self = "aoeu";
1566 \\fn f(m: []const u8) void {2003 \\fn f(m: []const u8) void {
1567 \\ m.copy(u8, self[0..], m);2004 \\ m.copy(u8, self[0..], m);
1568 \\}2005 \\}
1569 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }2006 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1570 , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'");2007 ,
2008 ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'",
2009 );
15712010
1572 cases.add("wrong number of arguments for method fn call",2011 cases.add(
2012 "wrong number of arguments for method fn call",
1573 \\const Foo = struct {2013 \\const Foo = struct {
1574 \\ fn method(self: &const Foo, a: i32) void {}2014 \\ fn method(self: &const Foo, a: i32) void {}
1575 \\};2015 \\};
...@@ -1578,34 +2018,49 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1578,34 +2018,49 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1578 \\ foo.method(1, 2);2018 \\ foo.method(1, 2);
1579 \\}2019 \\}
1580 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }2020 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1581 , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3");2021 ,
2022 ".tmp_source.zig:6:15: error: expected 2 arguments, found 3",
2023 );
15822024
1583 cases.add("assign through constant pointer",2025 cases.add(
2026 "assign through constant pointer",
1584 \\export fn f() void {2027 \\export fn f() void {
1585 \\ var cstr = c"Hat";2028 \\ var cstr = c"Hat";
1586 \\ cstr[0] = 'W';2029 \\ cstr[0] = 'W';
1587 \\}2030 \\}
1588 , ".tmp_source.zig:3:11: error: cannot assign to constant");2031 ,
2032 ".tmp_source.zig:3:11: error: cannot assign to constant",
2033 );
15892034
1590 cases.add("assign through constant slice",2035 cases.add(
2036 "assign through constant slice",
1591 \\export fn f() void {2037 \\export fn f() void {
1592 \\ var cstr: []const u8 = "Hat";2038 \\ var cstr: []const u8 = "Hat";
1593 \\ cstr[0] = 'W';2039 \\ cstr[0] = 'W';
1594 \\}2040 \\}
1595 , ".tmp_source.zig:3:11: error: cannot assign to constant");2041 ,
2042 ".tmp_source.zig:3:11: error: cannot assign to constant",
2043 );
15962044
1597 cases.add("main function with bogus args type",2045 cases.add(
2046 "main function with bogus args type",
1598 \\pub fn main(args: [][]bogus) !void {}2047 \\pub fn main(args: [][]bogus) !void {}
1599 , ".tmp_source.zig:1:23: error: use of undeclared identifier 'bogus'");2048 ,
2049 ".tmp_source.zig:1:23: error: use of undeclared identifier 'bogus'",
2050 );
16002051
1601 cases.add("for loop missing element param",2052 cases.add(
2053 "for loop missing element param",
1602 \\fn foo(blah: []u8) void {2054 \\fn foo(blah: []u8) void {
1603 \\ for (blah) { }2055 \\ for (blah) { }
1604 \\}2056 \\}
1605 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }2057 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1606 , ".tmp_source.zig:2:5: error: for loop expression missing element parameter");2058 ,
2059 ".tmp_source.zig:2:5: error: for loop expression missing element parameter",
2060 );
16072061
1608 cases.add("misspelled type with pointer only reference",2062 cases.add(
2063 "misspelled type with pointer only reference",
1609 \\const JasonHM = u8;2064 \\const JasonHM = u8;
1610 \\const JasonList = &JsonNode;2065 \\const JasonList = &JsonNode;
1611 \\2066 \\
...@@ -1636,9 +2091,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1636,9 +2091,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1636 \\}2091 \\}
1637 \\2092 \\
1638 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }2093 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1639 , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'");2094 ,
2095 ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'",
2096 );
16402097
1641 cases.add("method call with first arg type primitive",2098 cases.add(
2099 "method call with first arg type primitive",
1642 \\const Foo = struct {2100 \\const Foo = struct {
1643 \\ x: i32,2101 \\ x: i32,
1644 \\2102 \\
...@@ -1654,9 +2112,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1654,9 +2112,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1654 \\2112 \\
1655 \\ derp.init();2113 \\ derp.init();
1656 \\}2114 \\}
1657 , ".tmp_source.zig:14:5: error: expected type 'i32', found '&const Foo'");2115 ,
2116 ".tmp_source.zig:14:5: error: expected type 'i32', found '&const Foo'",
2117 );
16582118
1659 cases.add("method call with first arg type wrong container",2119 cases.add(
2120 "method call with first arg type wrong container",
1660 \\pub const List = struct {2121 \\pub const List = struct {
1661 \\ len: usize,2122 \\ len: usize,
1662 \\ allocator: &Allocator,2123 \\ allocator: &Allocator,
...@@ -1681,26 +2142,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1681,26 +2142,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1681 \\ var x = List.init(&global_allocator);2142 \\ var x = List.init(&global_allocator);
1682 \\ x.init();2143 \\ x.init();
1683 \\}2144 \\}
1684 , ".tmp_source.zig:23:5: error: expected type '&Allocator', found '&List'");2145 ,
2146 ".tmp_source.zig:23:5: error: expected type '&Allocator', found '&List'",
2147 );
16852148
1686 cases.add("binary not on number literal",2149 cases.add(
2150 "binary not on number literal",
1687 \\const TINY_QUANTUM_SHIFT = 4;2151 \\const TINY_QUANTUM_SHIFT = 4;
1688 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;2152 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
1689 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);2153 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
1690 \\2154 \\
1691 \\export fn entry() usize { return @sizeOf(@typeOf(block_aligned_stuff)); }2155 \\export fn entry() usize { return @sizeOf(@typeOf(block_aligned_stuff)); }
1692 , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'");2156 ,
2157 ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'",
2158 );
16932159
1694 cases.addCase(x: {2160 cases.addCase(x: {
1695 const tc = cases.create("multiple files with private function error",2161 const tc = cases.create(
1696 \\const foo = @import("foo.zig");2162 "multiple files with private function error",
2163 \\const foo = @import("foo.zig",);
1697 \\2164 \\
1698 \\export fn callPrivFunction() void {2165 \\export fn callPrivFunction() void {
1699 \\ foo.privateFunction();2166 \\ foo.privateFunction();
1700 \\}2167 \\}
1701 ,2168 ,
1702 ".tmp_source.zig:4:8: error: 'privateFunction' is private",2169 ".tmp_source.zig:4:8: error: 'privateFunction' is private",
1703 "foo.zig:1:1: note: declared here");2170 "foo.zig:1:1: note: declared here",
2171 );
17042172
1705 tc.addSourceFile("foo.zig",2173 tc.addSourceFile("foo.zig",
1706 \\fn privateFunction() void { }2174 \\fn privateFunction() void { }
...@@ -1709,14 +2177,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1709,14 +2177,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1709 break :x tc;2177 break :x tc;
1710 });2178 });
17112179
1712 cases.add("container init with non-type",2180 cases.add(
2181 "container init with non-type",
1713 \\const zero: i32 = 0;2182 \\const zero: i32 = 0;
1714 \\const a = zero{1};2183 \\const a = zero{1};
1715 \\2184 \\
1716 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }2185 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
1717 , ".tmp_source.zig:2:11: error: expected type, found 'i32'");2186 ,
2187 ".tmp_source.zig:2:11: error: expected type, found 'i32'",
2188 );
17182189
1719 cases.add("assign to constant field",2190 cases.add(
2191 "assign to constant field",
1720 \\const Foo = struct {2192 \\const Foo = struct {
1721 \\ field: i32,2193 \\ field: i32,
1722 \\};2194 \\};
...@@ -1724,9 +2196,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1724,9 +2196,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1724 \\ const f = Foo {.field = 1234,};2196 \\ const f = Foo {.field = 1234,};
1725 \\ f.field = 0;2197 \\ f.field = 0;
1726 \\}2198 \\}
1727 , ".tmp_source.zig:6:13: error: cannot assign to constant");2199 ,
2200 ".tmp_source.zig:6:13: error: cannot assign to constant",
2201 );
17282202
1729 cases.add("return from defer expression",2203 cases.add(
2204 "return from defer expression",
1730 \\pub fn testTrickyDefer() !void {2205 \\pub fn testTrickyDefer() !void {
1731 \\ defer canFail() catch {};2206 \\ defer canFail() catch {};
1732 \\2207 \\
...@@ -1742,9 +2217,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1742,9 +2217,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1742 \\}2217 \\}
1743 \\2218 \\
1744 \\export fn entry() usize { return @sizeOf(@typeOf(testTrickyDefer)); }2219 \\export fn entry() usize { return @sizeOf(@typeOf(testTrickyDefer)); }
1745 , ".tmp_source.zig:4:11: error: cannot return from defer expression");2220 ,
2221 ".tmp_source.zig:4:11: error: cannot return from defer expression",
2222 );
17462223
1747 cases.add("attempt to access var args out of bounds",2224 cases.add(
2225 "attempt to access var args out of bounds",
1748 \\fn add(args: ...) i32 {2226 \\fn add(args: ...) i32 {
1749 \\ return args[0] + args[1];2227 \\ return args[0] + args[1];
1750 \\}2228 \\}
...@@ -1755,10 +2233,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1755,10 +2233,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1755 \\2233 \\
1756 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }2234 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1757 ,2235 ,
1758 ".tmp_source.zig:2:26: error: index 1 outside argument list of size 1",2236 ".tmp_source.zig:2:26: error: index 1 outside argument list of size 1",
1759 ".tmp_source.zig:6:15: note: called from here");2237 ".tmp_source.zig:6:15: note: called from here",
2238 );
17602239
1761 cases.add("pass integer literal to var args",2240 cases.add(
2241 "pass integer literal to var args",
1762 \\fn add(args: ...) i32 {2242 \\fn add(args: ...) i32 {
1763 \\ var sum = i32(0);2243 \\ var sum = i32(0);
1764 \\ {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {2244 \\ {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {
...@@ -1772,32 +2252,44 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1772,32 +2252,44 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1772 \\}2252 \\}
1773 \\2253 \\
1774 \\export fn entry() usize { return @sizeOf(@typeOf(bar)); }2254 \\export fn entry() usize { return @sizeOf(@typeOf(bar)); }
1775 , ".tmp_source.zig:10:16: error: compiler bug: integer and float literals in var args function must be casted");2255 ,
2256 ".tmp_source.zig:10:16: error: compiler bug: integer and float literals in var args function must be casted",
2257 );
17762258
1777 cases.add("assign too big number to u16",2259 cases.add(
2260 "assign too big number to u16",
1778 \\export fn foo() void {2261 \\export fn foo() void {
1779 \\ var vga_mem: u16 = 0xB8000;2262 \\ var vga_mem: u16 = 0xB8000;
1780 \\}2263 \\}
1781 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");2264 ,
2265 ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'",
2266 );
17822267
1783 cases.add("global variable alignment non power of 2",2268 cases.add(
2269 "global variable alignment non power of 2",
1784 \\const some_data: [100]u8 align(3) = undefined;2270 \\const some_data: [100]u8 align(3) = undefined;
1785 \\export fn entry() usize { return @sizeOf(@typeOf(some_data)); }2271 \\export fn entry() usize { return @sizeOf(@typeOf(some_data)); }
1786 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");2272 ,
2273 ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2",
2274 );
17872275
1788 cases.add("function alignment non power of 2",2276 cases.add(
2277 "function alignment non power of 2",
1789 \\extern fn foo() align(3) void;2278 \\extern fn foo() align(3) void;
1790 \\export fn entry() void { return foo(); }2279 \\export fn entry() void { return foo(); }
1791 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");2280 ,
2281 ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2",
2282 );
17922283
1793 cases.add("compile log",2284 cases.add(
2285 "compile log",
1794 \\export fn foo() void {2286 \\export fn foo() void {
1795 \\ comptime bar(12, "hi");2287 \\ comptime bar(12, "hi",);
1796 \\}2288 \\}
1797 \\fn bar(a: i32, b: []const u8) void {2289 \\fn bar(a: i32, b: []const u8) void {
1798 \\ @compileLog("begin");2290 \\ @compileLog("begin",);
1799 \\ @compileLog("a", a, "b", b);2291 \\ @compileLog("a", a, "b", b);
1800 \\ @compileLog("end");2292 \\ @compileLog("end",);
1801 \\}2293 \\}
1802 ,2294 ,
1803 ".tmp_source.zig:5:5: error: found compile log statement",2295 ".tmp_source.zig:5:5: error: found compile log statement",
...@@ -1805,9 +2297,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1805,9 +2297,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1805 ".tmp_source.zig:6:5: error: found compile log statement",2297 ".tmp_source.zig:6:5: error: found compile log statement",
1806 ".tmp_source.zig:2:17: note: called from here",2298 ".tmp_source.zig:2:17: note: called from here",
1807 ".tmp_source.zig:7:5: error: found compile log statement",2299 ".tmp_source.zig:7:5: error: found compile log statement",
1808 ".tmp_source.zig:2:17: note: called from here");2300 ".tmp_source.zig:2:17: note: called from here",
2301 );
18092302
1810 cases.add("casting bit offset pointer to regular pointer",2303 cases.add(
2304 "casting bit offset pointer to regular pointer",
1811 \\const BitField = packed struct {2305 \\const BitField = packed struct {
1812 \\ a: u3,2306 \\ a: u3,
1813 \\ b: u3,2307 \\ b: u3,
...@@ -1819,13 +2313,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1819,13 +2313,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1819 \\}2313 \\}
1820 \\2314 \\
1821 \\fn bar(x: &const u3) u3 {2315 \\fn bar(x: &const u3) u3 {
1822 \\ return *x;2316 \\ return x.*;
1823 \\}2317 \\}
1824 \\2318 \\
1825 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }2319 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1826 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'");2320 ,
2321 ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'",
2322 );
18272323
1828 cases.add("referring to a struct that is invalid",2324 cases.add(
2325 "referring to a struct that is invalid",
1829 \\const UsbDeviceRequest = struct {2326 \\const UsbDeviceRequest = struct {
1830 \\ Type: u8,2327 \\ Type: u8,
1831 \\};2328 \\};
...@@ -1838,10 +2335,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1838,10 +2335,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1838 \\ if (!ok) unreachable;2335 \\ if (!ok) unreachable;
1839 \\}2336 \\}
1840 ,2337 ,
1841 ".tmp_source.zig:10:14: error: unable to evaluate constant expression",2338 ".tmp_source.zig:10:14: error: unable to evaluate constant expression",
1842 ".tmp_source.zig:6:20: note: called from here");2339 ".tmp_source.zig:6:20: note: called from here",
2340 );
18432341
1844 cases.add("control flow uses comptime var at runtime",2342 cases.add(
2343 "control flow uses comptime var at runtime",
1845 \\export fn foo() void {2344 \\export fn foo() void {
1846 \\ comptime var i = 0;2345 \\ comptime var i = 0;
1847 \\ while (i < 5) : (i += 1) {2346 \\ while (i < 5) : (i += 1) {
...@@ -1851,68 +2350,94 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1851,68 +2350,94 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1851 \\2350 \\
1852 \\fn bar() void { }2351 \\fn bar() void { }
1853 ,2352 ,
1854 ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",2353 ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",
1855 ".tmp_source.zig:3:24: note: compile-time variable assigned here");2354 ".tmp_source.zig:3:24: note: compile-time variable assigned here",
2355 );
18562356
1857 cases.add("ignored return value",2357 cases.add(
2358 "ignored return value",
1858 \\export fn foo() void {2359 \\export fn foo() void {
1859 \\ bar();2360 \\ bar();
1860 \\}2361 \\}
1861 \\fn bar() i32 { return 0; }2362 \\fn bar() i32 { return 0; }
1862 , ".tmp_source.zig:2:8: error: expression value is ignored");2363 ,
2364 ".tmp_source.zig:2:8: error: expression value is ignored",
2365 );
18632366
1864 cases.add("ignored assert-err-ok return value",2367 cases.add(
2368 "ignored assert-err-ok return value",
1865 \\export fn foo() void {2369 \\export fn foo() void {
1866 \\ bar() catch unreachable;2370 \\ bar() catch unreachable;
1867 \\}2371 \\}
1868 \\fn bar() error!i32 { return 0; }2372 \\fn bar() error!i32 { return 0; }
1869 , ".tmp_source.zig:2:11: error: expression value is ignored");2373 ,
2374 ".tmp_source.zig:2:11: error: expression value is ignored",
2375 );
18702376
1871 cases.add("ignored statement value",2377 cases.add(
2378 "ignored statement value",
1872 \\export fn foo() void {2379 \\export fn foo() void {
1873 \\ 1;2380 \\ 1;
1874 \\}2381 \\}
1875 , ".tmp_source.zig:2:5: error: expression value is ignored");2382 ,
2383 ".tmp_source.zig:2:5: error: expression value is ignored",
2384 );
18762385
1877 cases.add("ignored comptime statement value",2386 cases.add(
2387 "ignored comptime statement value",
1878 \\export fn foo() void {2388 \\export fn foo() void {
1879 \\ comptime {1;}2389 \\ comptime {1;}
1880 \\}2390 \\}
1881 , ".tmp_source.zig:2:15: error: expression value is ignored");2391 ,
2392 ".tmp_source.zig:2:15: error: expression value is ignored",
2393 );
18822394
1883 cases.add("ignored comptime value",2395 cases.add(
2396 "ignored comptime value",
1884 \\export fn foo() void {2397 \\export fn foo() void {
1885 \\ comptime 1;2398 \\ comptime 1;
1886 \\}2399 \\}
1887 , ".tmp_source.zig:2:5: error: expression value is ignored");2400 ,
2401 ".tmp_source.zig:2:5: error: expression value is ignored",
2402 );
18882403
1889 cases.add("ignored defered statement value",2404 cases.add(
2405 "ignored defered statement value",
1890 \\export fn foo() void {2406 \\export fn foo() void {
1891 \\ defer {1;}2407 \\ defer {1;}
1892 \\}2408 \\}
1893 , ".tmp_source.zig:2:12: error: expression value is ignored");2409 ,
2410 ".tmp_source.zig:2:12: error: expression value is ignored",
2411 );
18942412
1895 cases.add("ignored defered function call",2413 cases.add(
2414 "ignored defered function call",
1896 \\export fn foo() void {2415 \\export fn foo() void {
1897 \\ defer bar();2416 \\ defer bar();
1898 \\}2417 \\}
1899 \\fn bar() error!i32 { return 0; }2418 \\fn bar() error!i32 { return 0; }
1900 , ".tmp_source.zig:2:14: error: expression value is ignored");2419 ,
2420 ".tmp_source.zig:2:14: error: expression value is ignored",
2421 );
19012422
1902 cases.add("dereference an array",2423 cases.add(
2424 "dereference an array",
1903 \\var s_buffer: [10]u8 = undefined;2425 \\var s_buffer: [10]u8 = undefined;
1904 \\pub fn pass(in: []u8) []u8 {2426 \\pub fn pass(in: []u8) []u8 {
1905 \\ var out = &s_buffer;2427 \\ var out = &s_buffer;
1906 \\ *out[0] = in[0];2428 \\ out[0].* = in[0];
1907 \\ return (*out)[0..1];2429 \\ return out.*[0..1];
1908 \\}2430 \\}
1909 \\2431 \\
1910 \\export fn entry() usize { return @sizeOf(@typeOf(pass)); }2432 \\export fn entry() usize { return @sizeOf(@typeOf(pass)); }
1911 , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'");2433 ,
2434 ".tmp_source.zig:4:11: error: attempt to dereference non pointer type '[10]u8'",
2435 );
19122436
1913 cases.add("pass const ptr to mutable ptr fn",2437 cases.add(
2438 "pass const ptr to mutable ptr fn",
1914 \\fn foo() bool {2439 \\fn foo() bool {
1915 \\ const a = ([]const u8)("a");2440 \\ const a = ([]const u8)("a",);
1916 \\ const b = &a;2441 \\ const b = &a;
1917 \\ return ptrEql(b, b);2442 \\ return ptrEql(b, b);
1918 \\}2443 \\}
...@@ -1921,18 +2446,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1921,18 +2446,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1921 \\}2446 \\}
1922 \\2447 \\
1923 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }2448 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1924 , ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'");2449 ,
2450 ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'",
2451 );
19252452
1926 cases.addCase(x: {2453 cases.addCase(x: {
1927 const tc = cases.create("export collision",2454 const tc = cases.create(
1928 \\const foo = @import("foo.zig");2455 "export collision",
2456 \\const foo = @import("foo.zig",);
1929 \\2457 \\
1930 \\export fn bar() usize {2458 \\export fn bar() usize {
1931 \\ return foo.baz;2459 \\ return foo.baz;
1932 \\}2460 \\}
1933 ,2461 ,
1934 "foo.zig:1:8: error: exported symbol collision: 'bar'",2462 "foo.zig:1:8: error: exported symbol collision: 'bar'",
1935 ".tmp_source.zig:3:8: note: other symbol here");2463 ".tmp_source.zig:3:8: note: other symbol here",
2464 );
19362465
1937 tc.addSourceFile("foo.zig",2466 tc.addSourceFile("foo.zig",
1938 \\export fn bar() void {}2467 \\export fn bar() void {}
...@@ -1942,35 +2471,48 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1942,35 +2471,48 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1942 break :x tc;2471 break :x tc;
1943 });2472 });
19442473
1945 cases.add("pass non-copyable type by value to function",2474 cases.add(
2475 "pass non-copyable type by value to function",
1946 \\const Point = struct { x: i32, y: i32, };2476 \\const Point = struct { x: i32, y: i32, };
1947 \\fn foo(p: Point) void { }2477 \\fn foo(p: Point) void { }
1948 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }2478 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1949 , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value");2479 ,
2480 ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value",
2481 );
19502482
1951 cases.add("implicit cast from array to mutable slice",2483 cases.add(
2484 "implicit cast from array to mutable slice",
1952 \\var global_array: [10]i32 = undefined;2485 \\var global_array: [10]i32 = undefined;
1953 \\fn foo(param: []i32) void {}2486 \\fn foo(param: []i32) void {}
1954 \\export fn entry() void {2487 \\export fn entry() void {
1955 \\ foo(global_array);2488 \\ foo(global_array);
1956 \\}2489 \\}
1957 , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'");2490 ,
2491 ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'",
2492 );
19582493
1959 cases.add("ptrcast to non-pointer",2494 cases.add(
2495 "ptrcast to non-pointer",
1960 \\export fn entry(a: &i32) usize {2496 \\export fn entry(a: &i32) usize {
1961 \\ return @ptrCast(usize, a);2497 \\ return @ptrCast(usize, a);
1962 \\}2498 \\}
1963 , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'");2499 ,
2500 ".tmp_source.zig:2:21: error: expected pointer, found 'usize'",
2501 );
19642502
1965 cases.add("too many error values to cast to small integer",2503 cases.add(
2504 "too many error values to cast to small integer",
1966 \\const Error = error { A, B, C, D, E, F, G, H };2505 \\const Error = error { A, B, C, D, E, F, G, H };
1967 \\fn foo(e: Error) u2 {2506 \\fn foo(e: Error) u2 {
1968 \\ return u2(e);2507 \\ return u2(e);
1969 \\}2508 \\}
1970 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }2509 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1971 , ".tmp_source.zig:3:14: error: too many error values to fit in 'u2'");2510 ,
2511 ".tmp_source.zig:3:14: error: too many error values to fit in 'u2'",
2512 );
19722513
1973 cases.add("asm at compile time",2514 cases.add(
2515 "asm at compile time",
1974 \\comptime {2516 \\comptime {
1975 \\ doSomeAsm();2517 \\ doSomeAsm();
1976 \\}2518 \\}
...@@ -1982,48 +2524,66 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1982,48 +2524,66 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1982 \\ \\.set aoeu, derp;2524 \\ \\.set aoeu, derp;
1983 \\ );2525 \\ );
1984 \\}2526 \\}
1985 , ".tmp_source.zig:6:5: error: unable to evaluate constant expression");2527 ,
2528 ".tmp_source.zig:6:5: error: unable to evaluate constant expression",
2529 );
19862530
1987 cases.add("invalid member of builtin enum",2531 cases.add(
1988 \\const builtin = @import("builtin");2532 "invalid member of builtin enum",
2533 \\const builtin = @import("builtin",);
1989 \\export fn entry() void {2534 \\export fn entry() void {
1990 \\ const foo = builtin.Arch.x86;2535 \\ const foo = builtin.Arch.x86;
1991 \\}2536 \\}
1992 , ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'");2537 ,
2538 ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'",
2539 );
19932540
1994 cases.add("int to ptr of 0 bits",2541 cases.add(
2542 "int to ptr of 0 bits",
1995 \\export fn foo() void {2543 \\export fn foo() void {
1996 \\ var x: usize = 0x1000;2544 \\ var x: usize = 0x1000;
1997 \\ var y: &void = @intToPtr(&void, x);2545 \\ var y: &void = @intToPtr(&void, x);
1998 \\}2546 \\}
1999 , ".tmp_source.zig:3:31: error: type '&void' has 0 bits and cannot store information");2547 ,
2548 ".tmp_source.zig:3:31: error: type '&void' has 0 bits and cannot store information",
2549 );
20002550
2001 cases.add("@fieldParentPtr - non struct",2551 cases.add(
2552 "@fieldParentPtr - non struct",
2002 \\const Foo = i32;2553 \\const Foo = i32;
2003 \\export fn foo(a: &i32) &Foo {2554 \\export fn foo(a: &i32) &Foo {
2004 \\ return @fieldParentPtr(Foo, "a", a);2555 \\ return @fieldParentPtr(Foo, "a", a);
2005 \\}2556 \\}
2006 , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'");2557 ,
2558 ".tmp_source.zig:3:28: error: expected struct type, found 'i32'",
2559 );
20072560
2008 cases.add("@fieldParentPtr - bad field name",2561 cases.add(
2562 "@fieldParentPtr - bad field name",
2009 \\const Foo = extern struct {2563 \\const Foo = extern struct {
2010 \\ derp: i32,2564 \\ derp: i32,
2011 \\};2565 \\};
2012 \\export fn foo(a: &i32) &Foo {2566 \\export fn foo(a: &i32) &Foo {
2013 \\ return @fieldParentPtr(Foo, "a", a);2567 \\ return @fieldParentPtr(Foo, "a", a);
2014 \\}2568 \\}
2015 , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'");2569 ,
2570 ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'",
2571 );
20162572
2017 cases.add("@fieldParentPtr - field pointer is not pointer",2573 cases.add(
2574 "@fieldParentPtr - field pointer is not pointer",
2018 \\const Foo = extern struct {2575 \\const Foo = extern struct {
2019 \\ a: i32,2576 \\ a: i32,
2020 \\};2577 \\};
2021 \\export fn foo(a: i32) &Foo {2578 \\export fn foo(a: i32) &Foo {
2022 \\ return @fieldParentPtr(Foo, "a", a);2579 \\ return @fieldParentPtr(Foo, "a", a);
2023 \\}2580 \\}
2024 , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'");2581 ,
2582 ".tmp_source.zig:5:38: error: expected pointer, found 'i32'",
2583 );
20252584
2026 cases.add("@fieldParentPtr - comptime field ptr not based on struct",2585 cases.add(
2586 "@fieldParentPtr - comptime field ptr not based on struct",
2027 \\const Foo = struct {2587 \\const Foo = struct {
2028 \\ a: i32,2588 \\ a: i32,
2029 \\ b: i32,2589 \\ b: i32,
...@@ -2034,9 +2594,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2034,9 +2594,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2034 \\ const field_ptr = @intToPtr(&i32, 0x1234);2594 \\ const field_ptr = @intToPtr(&i32, 0x1234);
2035 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr);2595 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr);
2036 \\}2596 \\}
2037 , ".tmp_source.zig:9:55: error: pointer value not based on parent struct");2597 ,
2598 ".tmp_source.zig:9:55: error: pointer value not based on parent struct",
2599 );
20382600
2039 cases.add("@fieldParentPtr - comptime wrong field index",2601 cases.add(
2602 "@fieldParentPtr - comptime wrong field index",
2040 \\const Foo = struct {2603 \\const Foo = struct {
2041 \\ a: i32,2604 \\ a: i32,
2042 \\ b: i32,2605 \\ b: i32,
...@@ -2046,76 +2609,100 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2046,76 +2609,100 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2046 \\comptime {2609 \\comptime {
2047 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a);2610 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a);
2048 \\}2611 \\}
2049 , ".tmp_source.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'");2612 ,
2613 ".tmp_source.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'",
2614 );
20502615
2051 cases.add("@offsetOf - non struct",2616 cases.add(
2617 "@offsetOf - non struct",
2052 \\const Foo = i32;2618 \\const Foo = i32;
2053 \\export fn foo() usize {2619 \\export fn foo() usize {
2054 \\ return @offsetOf(Foo, "a");2620 \\ return @offsetOf(Foo, "a",);
2055 \\}2621 \\}
2056 , ".tmp_source.zig:3:22: error: expected struct type, found 'i32'");2622 ,
2623 ".tmp_source.zig:3:22: error: expected struct type, found 'i32'",
2624 );
20572625
2058 cases.add("@offsetOf - bad field name",2626 cases.add(
2627 "@offsetOf - bad field name",
2059 \\const Foo = struct {2628 \\const Foo = struct {
2060 \\ derp: i32,2629 \\ derp: i32,
2061 \\};2630 \\};
2062 \\export fn foo() usize {2631 \\export fn foo() usize {
2063 \\ return @offsetOf(Foo, "a");2632 \\ return @offsetOf(Foo, "a",);
2064 \\}2633 \\}
2065 , ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'");2634 ,
2635 ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'",
2636 );
20662637
2067 cases.addExe("missing main fn in executable",2638 cases.addExe(
2639 "missing main fn in executable",
2068 \\2640 \\
2069 , "error: no member named 'main' in '");2641 ,
2642 "error: no member named 'main' in '",
2643 );
20702644
2071 cases.addExe("private main fn",2645 cases.addExe(
2646 "private main fn",
2072 \\fn main() void {}2647 \\fn main() void {}
2073 ,2648 ,
2074 "error: 'main' is private",2649 "error: 'main' is private",
2075 ".tmp_source.zig:1:1: note: declared here");2650 ".tmp_source.zig:1:1: note: declared here",
2651 );
20762652
2077 cases.add("setting a section on an extern variable",2653 cases.add(
2654 "setting a section on an extern variable",
2078 \\extern var foo: i32 section(".text2");2655 \\extern var foo: i32 section(".text2");
2079 \\export fn entry() i32 {2656 \\export fn entry() i32 {
2080 \\ return foo;2657 \\ return foo;
2081 \\}2658 \\}
2082 ,2659 ,
2083 ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'");2660 ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'",
2661 );
20842662
2085 cases.add("setting a section on a local variable",2663 cases.add(
2664 "setting a section on a local variable",
2086 \\export fn entry() i32 {2665 \\export fn entry() i32 {
2087 \\ var foo: i32 section(".text2") = 1234;2666 \\ var foo: i32 section(".text2") = 1234;
2088 \\ return foo;2667 \\ return foo;
2089 \\}2668 \\}
2090 ,2669 ,
2091 ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'");2670 ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'",
2671 );
20922672
2093 cases.add("setting a section on an extern fn",2673 cases.add(
2674 "setting a section on an extern fn",
2094 \\extern fn foo() section(".text2") void;2675 \\extern fn foo() section(".text2") void;
2095 \\export fn entry() void {2676 \\export fn entry() void {
2096 \\ foo();2677 \\ foo();
2097 \\}2678 \\}
2098 ,2679 ,
2099 ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'");2680 ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'",
2681 );
21002682
2101 cases.add("returning address of local variable - simple",2683 cases.add(
2684 "returning address of local variable - simple",
2102 \\export fn foo() &i32 {2685 \\export fn foo() &i32 {
2103 \\ var a: i32 = undefined;2686 \\ var a: i32 = undefined;
2104 \\ return &a;2687 \\ return &a;
2105 \\}2688 \\}
2106 ,2689 ,
2107 ".tmp_source.zig:3:13: error: function returns address of local variable");2690 ".tmp_source.zig:3:13: error: function returns address of local variable",
2691 );
21082692
2109 cases.add("returning address of local variable - phi",2693 cases.add(
2694 "returning address of local variable - phi",
2110 \\export fn foo(c: bool) &i32 {2695 \\export fn foo(c: bool) &i32 {
2111 \\ var a: i32 = undefined;2696 \\ var a: i32 = undefined;
2112 \\ var b: i32 = undefined;2697 \\ var b: i32 = undefined;
2113 \\ return if (c) &a else &b;2698 \\ return if (c) &a else &b;
2114 \\}2699 \\}
2115 ,2700 ,
2116 ".tmp_source.zig:4:12: error: function returns address of local variable");2701 ".tmp_source.zig:4:12: error: function returns address of local variable",
2702 );
21172703
2118 cases.add("inner struct member shadowing outer struct member",2704 cases.add(
2705 "inner struct member shadowing outer struct member",
2119 \\fn A() type {2706 \\fn A() type {
2120 \\ return struct {2707 \\ return struct {
2121 \\ b: B(),2708 \\ b: B(),
...@@ -2137,57 +2724,71 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2137,57 +2724,71 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2137 \\}2724 \\}
2138 ,2725 ,
2139 ".tmp_source.zig:9:17: error: redefinition of 'Self'",2726 ".tmp_source.zig:9:17: error: redefinition of 'Self'",
2140 ".tmp_source.zig:5:9: note: previous definition is here");2727 ".tmp_source.zig:5:9: note: previous definition is here",
2728 );
21412729
2142 cases.add("while expected bool, got nullable",2730 cases.add(
2731 "while expected bool, got nullable",
2143 \\export fn foo() void {2732 \\export fn foo() void {
2144 \\ while (bar()) {}2733 \\ while (bar()) {}
2145 \\}2734 \\}
2146 \\fn bar() ?i32 { return 1; }2735 \\fn bar() ?i32 { return 1; }
2147 ,2736 ,
2148 ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'");2737 ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'",
2738 );
21492739
2150 cases.add("while expected bool, got error union",2740 cases.add(
2741 "while expected bool, got error union",
2151 \\export fn foo() void {2742 \\export fn foo() void {
2152 \\ while (bar()) {}2743 \\ while (bar()) {}
2153 \\}2744 \\}
2154 \\fn bar() error!i32 { return 1; }2745 \\fn bar() error!i32 { return 1; }
2155 ,2746 ,
2156 ".tmp_source.zig:2:15: error: expected type 'bool', found 'error!i32'");2747 ".tmp_source.zig:2:15: error: expected type 'bool', found 'error!i32'",
2748 );
21572749
2158 cases.add("while expected nullable, got bool",2750 cases.add(
2751 "while expected nullable, got bool",
2159 \\export fn foo() void {2752 \\export fn foo() void {
2160 \\ while (bar()) |x| {}2753 \\ while (bar()) |x| {}
2161 \\}2754 \\}
2162 \\fn bar() bool { return true; }2755 \\fn bar() bool { return true; }
2163 ,2756 ,
2164 ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'");2757 ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'",
2758 );
21652759
2166 cases.add("while expected nullable, got error union",2760 cases.add(
2761 "while expected nullable, got error union",
2167 \\export fn foo() void {2762 \\export fn foo() void {
2168 \\ while (bar()) |x| {}2763 \\ while (bar()) |x| {}
2169 \\}2764 \\}
2170 \\fn bar() error!i32 { return 1; }2765 \\fn bar() error!i32 { return 1; }
2171 ,2766 ,
2172 ".tmp_source.zig:2:15: error: expected nullable type, found 'error!i32'");2767 ".tmp_source.zig:2:15: error: expected nullable type, found 'error!i32'",
2768 );
21732769
2174 cases.add("while expected error union, got bool",2770 cases.add(
2771 "while expected error union, got bool",
2175 \\export fn foo() void {2772 \\export fn foo() void {
2176 \\ while (bar()) |x| {} else |err| {}2773 \\ while (bar()) |x| {} else |err| {}
2177 \\}2774 \\}
2178 \\fn bar() bool { return true; }2775 \\fn bar() bool { return true; }
2179 ,2776 ,
2180 ".tmp_source.zig:2:15: error: expected error union type, found 'bool'");2777 ".tmp_source.zig:2:15: error: expected error union type, found 'bool'",
2778 );
21812779
2182 cases.add("while expected error union, got nullable",2780 cases.add(
2781 "while expected error union, got nullable",
2183 \\export fn foo() void {2782 \\export fn foo() void {
2184 \\ while (bar()) |x| {} else |err| {}2783 \\ while (bar()) |x| {} else |err| {}
2185 \\}2784 \\}
2186 \\fn bar() ?i32 { return 1; }2785 \\fn bar() ?i32 { return 1; }
2187 ,2786 ,
2188 ".tmp_source.zig:2:15: error: expected error union type, found '?i32'");2787 ".tmp_source.zig:2:15: error: expected error union type, found '?i32'",
2788 );
21892789
2190 cases.add("inline fn calls itself indirectly",2790 cases.add(
2791 "inline fn calls itself indirectly",
2191 \\export fn foo() void {2792 \\export fn foo() void {
2192 \\ bar();2793 \\ bar();
2193 \\}2794 \\}
...@@ -2201,91 +2802,113 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2201,91 +2802,113 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2201 \\}2802 \\}
2202 \\extern fn quux() void;2803 \\extern fn quux() void;
2203 ,2804 ,
2204 ".tmp_source.zig:4:8: error: unable to inline function");2805 ".tmp_source.zig:4:8: error: unable to inline function",
2806 );
22052807
2206 cases.add("save reference to inline function",2808 cases.add(
2809 "save reference to inline function",
2207 \\export fn foo() void {2810 \\export fn foo() void {
2208 \\ quux(@ptrToInt(bar));2811 \\ quux(@ptrToInt(bar));
2209 \\}2812 \\}
2210 \\inline fn bar() void { }2813 \\inline fn bar() void { }
2211 \\extern fn quux(usize) void;2814 \\extern fn quux(usize) void;
2212 ,2815 ,
2213 ".tmp_source.zig:4:8: error: unable to inline function");2816 ".tmp_source.zig:4:8: error: unable to inline function",
2817 );
22142818
2215 cases.add("signed integer division",2819 cases.add(
2820 "signed integer division",
2216 \\export fn foo(a: i32, b: i32) i32 {2821 \\export fn foo(a: i32, b: i32) i32 {
2217 \\ return a / b;2822 \\ return a / b;
2218 \\}2823 \\}
2219 ,2824 ,
2220 ".tmp_source.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact");2825 ".tmp_source.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact",
2826 );
22212827
2222 cases.add("signed integer remainder division",2828 cases.add(
2829 "signed integer remainder division",
2223 \\export fn foo(a: i32, b: i32) i32 {2830 \\export fn foo(a: i32, b: i32) i32 {
2224 \\ return a % b;2831 \\ return a % b;
2225 \\}2832 \\}
2226 ,2833 ,
2227 ".tmp_source.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod");2834 ".tmp_source.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod",
2835 );
22282836
2229 cases.add("cast negative value to unsigned integer",2837 cases.add(
2838 "cast negative value to unsigned integer",
2230 \\comptime {2839 \\comptime {
2231 \\ const value: i32 = -1;2840 \\ const value: i32 = -1;
2232 \\ const unsigned = u32(value);2841 \\ const unsigned = u32(value);
2233 \\}2842 \\}
2234 ,2843 ,
2235 ".tmp_source.zig:3:25: error: attempt to cast negative value to unsigned integer");2844 ".tmp_source.zig:3:25: error: attempt to cast negative value to unsigned integer",
2845 );
22362846
2237 cases.add("compile-time division by zero",2847 cases.add(
2848 "compile-time division by zero",
2238 \\comptime {2849 \\comptime {
2239 \\ const a: i32 = 1;2850 \\ const a: i32 = 1;
2240 \\ const b: i32 = 0;2851 \\ const b: i32 = 0;
2241 \\ const c = a / b;2852 \\ const c = a / b;
2242 \\}2853 \\}
2243 ,2854 ,
2244 ".tmp_source.zig:4:17: error: division by zero");2855 ".tmp_source.zig:4:17: error: division by zero",
2856 );
22452857
2246 cases.add("compile-time remainder division by zero",2858 cases.add(
2859 "compile-time remainder division by zero",
2247 \\comptime {2860 \\comptime {
2248 \\ const a: i32 = 1;2861 \\ const a: i32 = 1;
2249 \\ const b: i32 = 0;2862 \\ const b: i32 = 0;
2250 \\ const c = a % b;2863 \\ const c = a % b;
2251 \\}2864 \\}
2252 ,2865 ,
2253 ".tmp_source.zig:4:17: error: division by zero");2866 ".tmp_source.zig:4:17: error: division by zero",
2867 );
22542868
2255 cases.add("compile-time integer cast truncates bits",2869 cases.add(
2870 "compile-time integer cast truncates bits",
2256 \\comptime {2871 \\comptime {
2257 \\ const spartan_count: u16 = 300;2872 \\ const spartan_count: u16 = 300;
2258 \\ const byte = u8(spartan_count);2873 \\ const byte = u8(spartan_count);
2259 \\}2874 \\}
2260 ,2875 ,
2261 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");2876 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits",
2877 );
22622878
2263 cases.add("@setRuntimeSafety twice for same scope",2879 cases.add(
2880 "@setRuntimeSafety twice for same scope",
2264 \\export fn foo() void {2881 \\export fn foo() void {
2265 \\ @setRuntimeSafety(false);2882 \\ @setRuntimeSafety(false);
2266 \\ @setRuntimeSafety(false);2883 \\ @setRuntimeSafety(false);
2267 \\}2884 \\}
2268 ,2885 ,
2269 ".tmp_source.zig:3:5: error: runtime safety set twice for same scope",2886 ".tmp_source.zig:3:5: error: runtime safety set twice for same scope",
2270 ".tmp_source.zig:2:5: note: first set here");2887 ".tmp_source.zig:2:5: note: first set here",
2888 );
22712889
2272 cases.add("@setFloatMode twice for same scope",2890 cases.add(
2891 "@setFloatMode twice for same scope",
2273 \\export fn foo() void {2892 \\export fn foo() void {
2274 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);2893 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
2275 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);2894 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
2276 \\}2895 \\}
2277 ,2896 ,
2278 ".tmp_source.zig:3:5: error: float mode set twice for same scope",2897 ".tmp_source.zig:3:5: error: float mode set twice for same scope",
2279 ".tmp_source.zig:2:5: note: first set here");2898 ".tmp_source.zig:2:5: note: first set here",
2899 );
22802900
2281 cases.add("array access of type",2901 cases.add(
2902 "array access of type",
2282 \\export fn foo() void {2903 \\export fn foo() void {
2283 \\ var b: u8[40] = undefined;2904 \\ var b: u8[40] = undefined;
2284 \\}2905 \\}
2285 ,2906 ,
2286 ".tmp_source.zig:2:14: error: array access of non-array type 'type'");2907 ".tmp_source.zig:2:14: error: array access of non-array type 'type'",
2908 );
22872909
2288 cases.add("cannot break out of defer expression",2910 cases.add(
2911 "cannot break out of defer expression",
2289 \\export fn foo() void {2912 \\export fn foo() void {
2290 \\ while (true) {2913 \\ while (true) {
2291 \\ defer {2914 \\ defer {
...@@ -2294,9 +2917,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2294,9 +2917,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2294 \\ }2917 \\ }
2295 \\}2918 \\}
2296 ,2919 ,
2297 ".tmp_source.zig:4:13: error: cannot break out of defer expression");2920 ".tmp_source.zig:4:13: error: cannot break out of defer expression",
2921 );
22982922
2299 cases.add("cannot continue out of defer expression",2923 cases.add(
2924 "cannot continue out of defer expression",
2300 \\export fn foo() void {2925 \\export fn foo() void {
2301 \\ while (true) {2926 \\ while (true) {
2302 \\ defer {2927 \\ defer {
...@@ -2305,9 +2930,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2305,9 +2930,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2305 \\ }2930 \\ }
2306 \\}2931 \\}
2307 ,2932 ,
2308 ".tmp_source.zig:4:13: error: cannot continue out of defer expression");2933 ".tmp_source.zig:4:13: error: cannot continue out of defer expression",
2934 );
23092935
2310 cases.add("calling a var args function only known at runtime",2936 cases.add(
2937 "calling a var args function only known at runtime",
2311 \\var foos = []fn(...) void { foo1, foo2 };2938 \\var foos = []fn(...) void { foo1, foo2 };
2312 \\2939 \\
2313 \\fn foo1(args: ...) void {}2940 \\fn foo1(args: ...) void {}
...@@ -2317,9 +2944,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2317,9 +2944,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2317 \\ foos[0]();2944 \\ foos[0]();
2318 \\}2945 \\}
2319 ,2946 ,
2320 ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value");2947 ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value",
2948 );
23212949
2322 cases.add("calling a generic function only known at runtime",2950 cases.add(
2951 "calling a generic function only known at runtime",
2323 \\var foos = []fn(var) void { foo1, foo2 };2952 \\var foos = []fn(var) void { foo1, foo2 };
2324 \\2953 \\
2325 \\fn foo1(arg: var) void {}2954 \\fn foo1(arg: var) void {}
...@@ -2329,10 +2958,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2329,10 +2958,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2329 \\ foos[0](true);2958 \\ foos[0](true);
2330 \\}2959 \\}
2331 ,2960 ,
2332 ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value");2961 ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value",
2962 );
23332963
2334 cases.add("@compileError shows traceback of references that caused it",2964 cases.add(
2335 \\const foo = @compileError("aoeu");2965 "@compileError shows traceback of references that caused it",
2966 \\const foo = @compileError("aoeu",);
2336 \\2967 \\
2337 \\const bar = baz + foo;2968 \\const bar = baz + foo;
2338 \\const baz = 1;2969 \\const baz = 1;
...@@ -2343,9 +2974,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2343,9 +2974,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2343 ,2974 ,
2344 ".tmp_source.zig:1:13: error: aoeu",2975 ".tmp_source.zig:1:13: error: aoeu",
2345 ".tmp_source.zig:3:19: note: referenced here",2976 ".tmp_source.zig:3:19: note: referenced here",
2346 ".tmp_source.zig:7:12: note: referenced here");2977 ".tmp_source.zig:7:12: note: referenced here",
2978 );
23472979
2348 cases.add("instantiating an undefined value for an invalid struct that contains itself",2980 cases.add(
2981 "instantiating an undefined value for an invalid struct that contains itself",
2349 \\const Foo = struct {2982 \\const Foo = struct {
2350 \\ x: Foo,2983 \\ x: Foo,
2351 \\};2984 \\};
...@@ -2356,73 +2989,93 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2356,73 +2989,93 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2356 \\ return @sizeOf(@typeOf(foo.x));2989 \\ return @sizeOf(@typeOf(foo.x));
2357 \\}2990 \\}
2358 ,2991 ,
2359 ".tmp_source.zig:1:13: error: struct 'Foo' contains itself");2992 ".tmp_source.zig:1:13: error: struct 'Foo' contains itself",
2993 );
23602994
2361 cases.add("float literal too large error",2995 cases.add(
2996 "float literal too large error",
2362 \\comptime {2997 \\comptime {
2363 \\ const a = 0x1.0p16384;2998 \\ const a = 0x1.0p16384;
2364 \\}2999 \\}
2365 ,3000 ,
2366 ".tmp_source.zig:2:15: error: float literal out of range of any type");3001 ".tmp_source.zig:2:15: error: float literal out of range of any type",
3002 );
23673003
2368 cases.add("float literal too small error (denormal)",3004 cases.add(
3005 "float literal too small error (denormal)",
2369 \\comptime {3006 \\comptime {
2370 \\ const a = 0x1.0p-16384;3007 \\ const a = 0x1.0p-16384;
2371 \\}3008 \\}
2372 ,3009 ,
2373 ".tmp_source.zig:2:15: error: float literal out of range of any type");3010 ".tmp_source.zig:2:15: error: float literal out of range of any type",
3011 );
23743012
2375 cases.add("explicit cast float literal to integer when there is a fraction component",3013 cases.add(
3014 "explicit cast float literal to integer when there is a fraction component",
2376 \\export fn entry() i32 {3015 \\export fn entry() i32 {
2377 \\ return i32(12.34);3016 \\ return i32(12.34);
2378 \\}3017 \\}
2379 ,3018 ,
2380 ".tmp_source.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'");3019 ".tmp_source.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
3020 );
23813021
2382 cases.add("non pointer given to @ptrToInt",3022 cases.add(
3023 "non pointer given to @ptrToInt",
2383 \\export fn entry(x: i32) usize {3024 \\export fn entry(x: i32) usize {
2384 \\ return @ptrToInt(x);3025 \\ return @ptrToInt(x);
2385 \\}3026 \\}
2386 ,3027 ,
2387 ".tmp_source.zig:2:22: error: expected pointer, found 'i32'");3028 ".tmp_source.zig:2:22: error: expected pointer, found 'i32'",
3029 );
23883030
2389 cases.add("@shlExact shifts out 1 bits",3031 cases.add(
3032 "@shlExact shifts out 1 bits",
2390 \\comptime {3033 \\comptime {
2391 \\ const x = @shlExact(u8(0b01010101), 2);3034 \\ const x = @shlExact(u8(0b01010101), 2);
2392 \\}3035 \\}
2393 ,3036 ,
2394 ".tmp_source.zig:2:15: error: operation caused overflow");3037 ".tmp_source.zig:2:15: error: operation caused overflow",
3038 );
23953039
2396 cases.add("@shrExact shifts out 1 bits",3040 cases.add(
3041 "@shrExact shifts out 1 bits",
2397 \\comptime {3042 \\comptime {
2398 \\ const x = @shrExact(u8(0b10101010), 2);3043 \\ const x = @shrExact(u8(0b10101010), 2);
2399 \\}3044 \\}
2400 ,3045 ,
2401 ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits");3046 ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits",
3047 );
24023048
2403 cases.add("shifting without int type or comptime known",3049 cases.add(
3050 "shifting without int type or comptime known",
2404 \\export fn entry(x: u8) u8 {3051 \\export fn entry(x: u8) u8 {
2405 \\ return 0x11 << x;3052 \\ return 0x11 << x;
2406 \\}3053 \\}
2407 ,3054 ,
2408 ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known");3055 ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known",
3056 );
24093057
2410 cases.add("shifting RHS is log2 of LHS int bit width",3058 cases.add(
3059 "shifting RHS is log2 of LHS int bit width",
2411 \\export fn entry(x: u8, y: u8) u8 {3060 \\export fn entry(x: u8, y: u8) u8 {
2412 \\ return x << y;3061 \\ return x << y;
2413 \\}3062 \\}
2414 ,3063 ,
2415 ".tmp_source.zig:2:17: error: expected type 'u3', found 'u8'");3064 ".tmp_source.zig:2:17: error: expected type 'u3', found 'u8'",
3065 );
24163066
2417 cases.add("globally shadowing a primitive type",3067 cases.add(
3068 "globally shadowing a primitive type",
2418 \\const u16 = @intType(false, 8);3069 \\const u16 = @intType(false, 8);
2419 \\export fn entry() void {3070 \\export fn entry() void {
2420 \\ const a: u16 = 300;3071 \\ const a: u16 = 300;
2421 \\}3072 \\}
2422 ,3073 ,
2423 ".tmp_source.zig:1:1: error: declaration shadows type 'u16'");3074 ".tmp_source.zig:1:1: error: declaration shadows type 'u16'",
3075 );
24243076
2425 cases.add("implicitly increasing pointer alignment",3077 cases.add(
3078 "implicitly increasing pointer alignment",
2426 \\const Foo = packed struct {3079 \\const Foo = packed struct {
2427 \\ a: u8,3080 \\ a: u8,
2428 \\ b: u32,3081 \\ b: u32,
...@@ -2434,12 +3087,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2434,12 +3087,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2434 \\}3087 \\}
2435 \\3088 \\
2436 \\fn bar(x: &u32) void {3089 \\fn bar(x: &u32) void {
2437 \\ *x += 1;3090 \\ x.* += 1;
2438 \\}3091 \\}
2439 ,3092 ,
2440 ".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'");3093 ".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'",
3094 );
24413095
2442 cases.add("implicitly increasing slice alignment",3096 cases.add(
3097 "implicitly increasing slice alignment",
2443 \\const Foo = packed struct {3098 \\const Foo = packed struct {
2444 \\ a: u8,3099 \\ a: u8,
2445 \\ b: u32,3100 \\ b: u32,
...@@ -2455,20 +3110,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2455,20 +3110,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2455 \\ x[0] += 1;3110 \\ x[0] += 1;
2456 \\}3111 \\}
2457 ,3112 ,
2458 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'");3113 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'",
3114 );
24593115
2460 cases.add("increase pointer alignment in @ptrCast",3116 cases.add(
3117 "increase pointer alignment in @ptrCast",
2461 \\export fn entry() u32 {3118 \\export fn entry() u32 {
2462 \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};3119 \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};
2463 \\ const ptr = @ptrCast(&u32, &bytes[0]);3120 \\ const ptr = @ptrCast(&u32, &bytes[0]);
2464 \\ return *ptr;3121 \\ return ptr.*;
2465 \\}3122 \\}
2466 ,3123 ,
2467 ".tmp_source.zig:3:17: error: cast increases pointer alignment",3124 ".tmp_source.zig:3:17: error: cast increases pointer alignment",
2468 ".tmp_source.zig:3:38: note: '&u8' has alignment 1",3125 ".tmp_source.zig:3:38: note: '&u8' has alignment 1",
2469 ".tmp_source.zig:3:27: note: '&u32' has alignment 4");3126 ".tmp_source.zig:3:27: note: '&u32' has alignment 4",
3127 );
24703128
2471 cases.add("increase pointer alignment in slice resize",3129 cases.add(
3130 "increase pointer alignment in slice resize",
2472 \\export fn entry() u32 {3131 \\export fn entry() u32 {
2473 \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};3132 \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};
2474 \\ return ([]u32)(bytes[0..])[0];3133 \\ return ([]u32)(bytes[0..])[0];
...@@ -2476,16 +3135,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2476,16 +3135,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2476 ,3135 ,
2477 ".tmp_source.zig:3:19: error: cast increases pointer alignment",3136 ".tmp_source.zig:3:19: error: cast increases pointer alignment",
2478 ".tmp_source.zig:3:19: note: '[]u8' has alignment 1",3137 ".tmp_source.zig:3:19: note: '[]u8' has alignment 1",
2479 ".tmp_source.zig:3:19: note: '[]u32' has alignment 4");3138 ".tmp_source.zig:3:19: note: '[]u32' has alignment 4",
3139 );
24803140
2481 cases.add("@alignCast expects pointer or slice",3141 cases.add(
3142 "@alignCast expects pointer or slice",
2482 \\export fn entry() void {3143 \\export fn entry() void {
2483 \\ @alignCast(4, u32(3));3144 \\ @alignCast(4, u32(3));
2484 \\}3145 \\}
2485 ,3146 ,
2486 ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'");3147 ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'",
3148 );
24873149
2488 cases.add("passing an under-aligned function pointer",3150 cases.add(
3151 "passing an under-aligned function pointer",
2489 \\export fn entry() void {3152 \\export fn entry() void {
2490 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);3153 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
2491 \\}3154 \\}
...@@ -2494,9 +3157,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2494,9 +3157,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2494 \\}3157 \\}
2495 \\fn alignedSmall() align(4) i32 { return 1234; }3158 \\fn alignedSmall() align(4) i32 { return 1234; }
2496 ,3159 ,
2497 ".tmp_source.zig:2:35: error: expected type 'fn() align(8) i32', found 'fn() align(4) i32'");3160 ".tmp_source.zig:2:35: error: expected type 'fn() align(8) i32', found 'fn() align(4) i32'",
3161 );
24983162
2499 cases.add("passing a not-aligned-enough pointer to cmpxchg",3163 cases.add(
3164 "passing a not-aligned-enough pointer to cmpxchg",
2500 \\const AtomicOrder = @import("builtin").AtomicOrder;3165 \\const AtomicOrder = @import("builtin").AtomicOrder;
2501 \\export fn entry() bool {3166 \\export fn entry() bool {
2502 \\ var x: i32 align(1) = 1234;3167 \\ var x: i32 align(1) = 1234;
...@@ -2504,16 +3169,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2504,16 +3169,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2504 \\ return x == 5678;3169 \\ return x == 5678;
2505 \\}3170 \\}
2506 ,3171 ,
2507 ".tmp_source.zig:4:32: error: expected type '&i32', found '&align(1) i32'");3172 ".tmp_source.zig:4:32: error: expected type '&i32', found '&align(1) i32'",
3173 );
25083174
2509 cases.add("wrong size to an array literal",3175 cases.add(
3176 "wrong size to an array literal",
2510 \\comptime {3177 \\comptime {
2511 \\ const array = [2]u8{1, 2, 3};3178 \\ const array = [2]u8{1, 2, 3};
2512 \\}3179 \\}
2513 ,3180 ,
2514 ".tmp_source.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal");3181 ".tmp_source.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal",
3182 );
25153183
2516 cases.add("@setEvalBranchQuota in non-root comptime execution context",3184 cases.add(
3185 "@setEvalBranchQuota in non-root comptime execution context",
2517 \\comptime {3186 \\comptime {
2518 \\ foo();3187 \\ foo();
2519 \\}3188 \\}
...@@ -2523,9 +3192,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2523,9 +3192,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2523 ,3192 ,
2524 ".tmp_source.zig:5:5: error: @setEvalBranchQuota must be called from the top of the comptime stack",3193 ".tmp_source.zig:5:5: error: @setEvalBranchQuota must be called from the top of the comptime stack",
2525 ".tmp_source.zig:2:8: note: called from here",3194 ".tmp_source.zig:2:8: note: called from here",
2526 ".tmp_source.zig:1:10: note: called from here");3195 ".tmp_source.zig:1:10: note: called from here",
3196 );
25273197
2528 cases.add("wrong pointer implicitly casted to pointer to @OpaqueType()",3198 cases.add(
3199 "wrong pointer implicitly casted to pointer to @OpaqueType()",
2529 \\const Derp = @OpaqueType();3200 \\const Derp = @OpaqueType();
2530 \\extern fn bar(d: &Derp) void;3201 \\extern fn bar(d: &Derp) void;
2531 \\export fn foo() void {3202 \\export fn foo() void {
...@@ -2533,23 +3204,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2533,23 +3204,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2533 \\ bar(@ptrCast(&c_void, &x));3204 \\ bar(@ptrCast(&c_void, &x));
2534 \\}3205 \\}
2535 ,3206 ,
2536 ".tmp_source.zig:5:9: error: expected type '&Derp', found '&c_void'");3207 ".tmp_source.zig:5:9: error: expected type '&Derp', found '&c_void'",
3208 );
25373209
2538 cases.add("non-const variables of things that require const variables",3210 cases.add(
3211 "non-const variables of things that require const variables",
2539 \\const Opaque = @OpaqueType();3212 \\const Opaque = @OpaqueType();
2540 \\3213 \\
2541 \\export fn entry(opaque: &Opaque) void {3214 \\export fn entry(opaque: &Opaque) void {
2542 \\ var m2 = &2;3215 \\ var m2 = &2;
2543 \\ const y: u32 = *m2;3216 \\ const y: u32 = m2.*;
2544 \\3217 \\
2545 \\ var a = undefined;3218 \\ var a = undefined;
2546 \\ var b = 1;3219 \\ var b = 1;
2547 \\ var c = 1.0;3220 \\ var c = 1.0;
2548 \\ var d = this;3221 \\ var d = this;
2549 \\ var e = null;3222 \\ var e = null;
2550 \\ var f = *opaque;3223 \\ var f = opaque.*;
2551 \\ var g = i32;3224 \\ var g = i32;
2552 \\ var h = @import("std");3225 \\ var h = @import("std",);
2553 \\ var i = (Foo {}).bar;3226 \\ var i = (Foo {}).bar;
2554 \\3227 \\
2555 \\ var z: noreturn = return;3228 \\ var z: noreturn = return;
...@@ -2569,26 +3242,32 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2569,26 +3242,32 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2569 ".tmp_source.zig:13:4: error: variable of type 'type' must be const or comptime",3242 ".tmp_source.zig:13:4: error: variable of type 'type' must be const or comptime",
2570 ".tmp_source.zig:14:4: error: variable of type '(namespace)' must be const or comptime",3243 ".tmp_source.zig:14:4: error: variable of type '(namespace)' must be const or comptime",
2571 ".tmp_source.zig:15:4: error: variable of type '(bound fn(&const Foo) void)' must be const or comptime",3244 ".tmp_source.zig:15:4: error: variable of type '(bound fn(&const Foo) void)' must be const or comptime",
2572 ".tmp_source.zig:17:4: error: unreachable code");3245 ".tmp_source.zig:17:4: error: unreachable code",
3246 );
25733247
2574 cases.add("wrong types given to atomic order args in cmpxchg",3248 cases.add(
3249 "wrong types given to atomic order args in cmpxchg",
2575 \\export fn entry() void {3250 \\export fn entry() void {
2576 \\ var x: i32 = 1234;3251 \\ var x: i32 = 1234;
2577 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, u32(1234), u32(1234))) {}3252 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, u32(1234), u32(1234))) {}
2578 \\}3253 \\}
2579 ,3254 ,
2580 ".tmp_source.zig:3:50: error: expected type 'AtomicOrder', found 'u32'");3255 ".tmp_source.zig:3:50: error: expected type 'AtomicOrder', found 'u32'",
3256 );
25813257
2582 cases.add("wrong types given to @export",3258 cases.add(
3259 "wrong types given to @export",
2583 \\extern fn entry() void { }3260 \\extern fn entry() void { }
2584 \\comptime {3261 \\comptime {
2585 \\ @export("entry", entry, u32(1234));3262 \\ @export("entry", entry, u32(1234));
2586 \\}3263 \\}
2587 ,3264 ,
2588 ".tmp_source.zig:3:32: error: expected type 'GlobalLinkage', found 'u32'");3265 ".tmp_source.zig:3:32: error: expected type 'GlobalLinkage', found 'u32'",
3266 );
25893267
2590 cases.add("struct with invalid field",3268 cases.add(
2591 \\const std = @import("std");3269 "struct with invalid field",
3270 \\const std = @import("std",);
2592 \\const Allocator = std.mem.Allocator;3271 \\const Allocator = std.mem.Allocator;
2593 \\const ArrayList = std.ArrayList;3272 \\const ArrayList = std.ArrayList;
2594 \\3273 \\
...@@ -2612,23 +3291,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2612,23 +3291,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2612 \\ };3291 \\ };
2613 \\}3292 \\}
2614 ,3293 ,
2615 ".tmp_source.zig:14:17: error: use of undeclared identifier 'HeaderValue'");3294 ".tmp_source.zig:14:17: error: use of undeclared identifier 'HeaderValue'",
3295 );
26163296
2617 cases.add("@setAlignStack outside function",3297 cases.add(
3298 "@setAlignStack outside function",
2618 \\comptime {3299 \\comptime {
2619 \\ @setAlignStack(16);3300 \\ @setAlignStack(16);
2620 \\}3301 \\}
2621 ,3302 ,
2622 ".tmp_source.zig:2:5: error: @setAlignStack outside function");3303 ".tmp_source.zig:2:5: error: @setAlignStack outside function",
3304 );
26233305
2624 cases.add("@setAlignStack in naked function",3306 cases.add(
3307 "@setAlignStack in naked function",
2625 \\export nakedcc fn entry() void {3308 \\export nakedcc fn entry() void {
2626 \\ @setAlignStack(16);3309 \\ @setAlignStack(16);
2627 \\}3310 \\}
2628 ,3311 ,
2629 ".tmp_source.zig:2:5: error: @setAlignStack in naked function");3312 ".tmp_source.zig:2:5: error: @setAlignStack in naked function",
3313 );
26303314
2631 cases.add("@setAlignStack in inline function",3315 cases.add(
3316 "@setAlignStack in inline function",
2632 \\export fn entry() void {3317 \\export fn entry() void {
2633 \\ foo();3318 \\ foo();
2634 \\}3319 \\}
...@@ -2636,25 +3321,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2636,25 +3321,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2636 \\ @setAlignStack(16);3321 \\ @setAlignStack(16);
2637 \\}3322 \\}
2638 ,3323 ,
2639 ".tmp_source.zig:5:5: error: @setAlignStack in inline function");3324 ".tmp_source.zig:5:5: error: @setAlignStack in inline function",
3325 );
26403326
2641 cases.add("@setAlignStack set twice",3327 cases.add(
3328 "@setAlignStack set twice",
2642 \\export fn entry() void {3329 \\export fn entry() void {
2643 \\ @setAlignStack(16);3330 \\ @setAlignStack(16);
2644 \\ @setAlignStack(16);3331 \\ @setAlignStack(16);
2645 \\}3332 \\}
2646 ,3333 ,
2647 ".tmp_source.zig:3:5: error: alignstack set twice",3334 ".tmp_source.zig:3:5: error: alignstack set twice",
2648 ".tmp_source.zig:2:5: note: first set here");3335 ".tmp_source.zig:2:5: note: first set here",
3336 );
26493337
2650 cases.add("@setAlignStack too big",3338 cases.add(
3339 "@setAlignStack too big",
2651 \\export fn entry() void {3340 \\export fn entry() void {
2652 \\ @setAlignStack(511 + 1);3341 \\ @setAlignStack(511 + 1);
2653 \\}3342 \\}
2654 ,3343 ,
2655 ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256");3344 ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256",
3345 );
26563346
2657 cases.add("storing runtime value in compile time variable then using it",3347 cases.add(
3348 "storing runtime value in compile time variable then using it",
2658 \\const Mode = @import("builtin").Mode;3349 \\const Mode = @import("builtin").Mode;
2659 \\3350 \\
2660 \\fn Free(comptime filename: []const u8) TestCase {3351 \\fn Free(comptime filename: []const u8) TestCase {
...@@ -2697,9 +3388,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2697,9 +3388,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2697 \\ }3388 \\ }
2698 \\}3389 \\}
2699 ,3390 ,
2700 ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable");3391 ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable",
3392 );
27013393
2702 cases.add("field access of opaque type",3394 cases.add(
3395 "field access of opaque type",
2703 \\const MyType = @OpaqueType();3396 \\const MyType = @OpaqueType();
2704 \\3397 \\
2705 \\export fn entry() bool {3398 \\export fn entry() bool {
...@@ -2711,120 +3404,148 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2711,120 +3404,148 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2711 \\ return x.blah;3404 \\ return x.blah;
2712 \\}3405 \\}
2713 ,3406 ,
2714 ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");3407 ".tmp_source.zig:9:13: error: type '&MyType' does not support field access",
3408 );
27153409
2716 cases.add("carriage return special case",3410 cases.add(
3411 "carriage return special case",
2717 "fn test() bool {\r\n" ++3412 "fn test() bool {\r\n" ++
2718 " true\r\n" ++3413 " true\r\n" ++
2719 "}\r\n"3414 "}\r\n",
2720 ,3415 ".tmp_source.zig:1:17: error: invalid carriage return, only '\\n' line endings are supported",
2721 ".tmp_source.zig:1:17: error: invalid carriage return, only '\\n' line endings are supported");3416 );
27223417
2723 cases.add("non-printable invalid character",3418 cases.add(
2724 "\xff\xfe" ++3419 "non-printable invalid character",
2725 \\fn test() bool {\r3420 "\xff\xfe" ++
2726 \\ true\r3421 \\fn test() bool {\r
2727 \\}3422 \\ true\r
2728 ,3423 \\}
2729 ".tmp_source.zig:1:1: error: invalid character: '\\xff'");3424 ,
3425 ".tmp_source.zig:1:1: error: invalid character: '\\xff'",
3426 );
27303427
2731 cases.add("non-printable invalid character with escape alternative",3428 cases.add(
3429 "non-printable invalid character with escape alternative",
2732 "fn test() bool {\n" ++3430 "fn test() bool {\n" ++
2733 "\ttrue\n" ++3431 "\ttrue\n" ++
2734 "}\n"3432 "}\n",
2735 ,3433 ".tmp_source.zig:2:1: error: invalid character: '\\t'",
2736 ".tmp_source.zig:2:1: error: invalid character: '\\t'");3434 );
27373435
2738 cases.add("@ArgType given non function parameter",3436 cases.add(
3437 "@ArgType given non function parameter",
2739 \\comptime {3438 \\comptime {
2740 \\ _ = @ArgType(i32, 3);3439 \\ _ = @ArgType(i32, 3);
2741 \\}3440 \\}
2742 ,3441 ,
2743 ".tmp_source.zig:2:18: error: expected function, found 'i32'");3442 ".tmp_source.zig:2:18: error: expected function, found 'i32'",
3443 );
27443444
2745 cases.add("@ArgType arg index out of bounds",3445 cases.add(
3446 "@ArgType arg index out of bounds",
2746 \\comptime {3447 \\comptime {
2747 \\ _ = @ArgType(@typeOf(add), 2);3448 \\ _ = @ArgType(@typeOf(add), 2);
2748 \\}3449 \\}
2749 \\fn add(a: i32, b: i32) i32 { return a + b; }3450 \\fn add(a: i32, b: i32) i32 { return a + b; }
2750 ,3451 ,
2751 ".tmp_source.zig:2:32: error: arg index 2 out of bounds; 'fn(i32, i32) i32' has 2 arguments");3452 ".tmp_source.zig:2:32: error: arg index 2 out of bounds; 'fn(i32, i32) i32' has 2 arguments",
3453 );
27523454
2753 cases.add("@memberType on unsupported type",3455 cases.add(
3456 "@memberType on unsupported type",
2754 \\comptime {3457 \\comptime {
2755 \\ _ = @memberType(i32, 0);3458 \\ _ = @memberType(i32, 0);
2756 \\}3459 \\}
2757 ,3460 ,
2758 ".tmp_source.zig:2:21: error: type 'i32' does not support @memberType");3461 ".tmp_source.zig:2:21: error: type 'i32' does not support @memberType",
3462 );
27593463
2760 cases.add("@memberType on enum",3464 cases.add(
3465 "@memberType on enum",
2761 \\comptime {3466 \\comptime {
2762 \\ _ = @memberType(Foo, 0);3467 \\ _ = @memberType(Foo, 0);
2763 \\}3468 \\}
2764 \\const Foo = enum {A,};3469 \\const Foo = enum {A,};
2765 ,3470 ,
2766 ".tmp_source.zig:2:21: error: type 'Foo' does not support @memberType");3471 ".tmp_source.zig:2:21: error: type 'Foo' does not support @memberType",
3472 );
27673473
2768 cases.add("@memberType struct out of bounds",3474 cases.add(
3475 "@memberType struct out of bounds",
2769 \\comptime {3476 \\comptime {
2770 \\ _ = @memberType(Foo, 0);3477 \\ _ = @memberType(Foo, 0);
2771 \\}3478 \\}
2772 \\const Foo = struct {};3479 \\const Foo = struct {};
2773 ,3480 ,
2774 ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members");3481 ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members",
3482 );
27753483
2776 cases.add("@memberType union out of bounds",3484 cases.add(
3485 "@memberType union out of bounds",
2777 \\comptime {3486 \\comptime {
2778 \\ _ = @memberType(Foo, 1);3487 \\ _ = @memberType(Foo, 1);
2779 \\}3488 \\}
2780 \\const Foo = union {A: void,};3489 \\const Foo = union {A: void,};
2781 ,3490 ,
2782 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");3491 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
3492 );
27833493
2784 cases.add("@memberName on unsupported type",3494 cases.add(
3495 "@memberName on unsupported type",
2785 \\comptime {3496 \\comptime {
2786 \\ _ = @memberName(i32, 0);3497 \\ _ = @memberName(i32, 0);
2787 \\}3498 \\}
2788 ,3499 ,
2789 ".tmp_source.zig:2:21: error: type 'i32' does not support @memberName");3500 ".tmp_source.zig:2:21: error: type 'i32' does not support @memberName",
3501 );
27903502
2791 cases.add("@memberName struct out of bounds",3503 cases.add(
3504 "@memberName struct out of bounds",
2792 \\comptime {3505 \\comptime {
2793 \\ _ = @memberName(Foo, 0);3506 \\ _ = @memberName(Foo, 0);
2794 \\}3507 \\}
2795 \\const Foo = struct {};3508 \\const Foo = struct {};
2796 ,3509 ,
2797 ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members");3510 ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members",
3511 );
27983512
2799 cases.add("@memberName enum out of bounds",3513 cases.add(
3514 "@memberName enum out of bounds",
2800 \\comptime {3515 \\comptime {
2801 \\ _ = @memberName(Foo, 1);3516 \\ _ = @memberName(Foo, 1);
2802 \\}3517 \\}
2803 \\const Foo = enum {A,};3518 \\const Foo = enum {A,};
2804 ,3519 ,
2805 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");3520 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
3521 );
28063522
2807 cases.add("@memberName union out of bounds",3523 cases.add(
3524 "@memberName union out of bounds",
2808 \\comptime {3525 \\comptime {
2809 \\ _ = @memberName(Foo, 1);3526 \\ _ = @memberName(Foo, 1);
2810 \\}3527 \\}
2811 \\const Foo = union {A:i32,};3528 \\const Foo = union {A:i32,};
2812 ,3529 ,
2813 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");3530 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
3531 );
28143532
2815 cases.add("calling var args extern function, passing array instead of pointer",3533 cases.add(
3534 "calling var args extern function, passing array instead of pointer",
2816 \\export fn entry() void {3535 \\export fn entry() void {
2817 \\ foo("hello");3536 \\ foo("hello",);
2818 \\}3537 \\}
2819 \\pub extern fn foo(format: &const u8, ...) void;3538 \\pub extern fn foo(format: &const u8, ...) void;
2820 ,3539 ,
2821 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");3540 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'",
3541 );
28223542
2823 cases.add("constant inside comptime function has compile error",3543 cases.add(
3544 "constant inside comptime function has compile error",
2824 \\const ContextAllocator = MemoryPool(usize);3545 \\const ContextAllocator = MemoryPool(usize);
2825 \\3546 \\
2826 \\pub fn MemoryPool(comptime T: type) type {3547 \\pub fn MemoryPool(comptime T: type) type {
2827 \\ const free_list_t = @compileError("aoeu");3548 \\ const free_list_t = @compileError("aoeu",);
2828 \\3549 \\
2829 \\ return struct {3550 \\ return struct {
2830 \\ free_list: free_list_t,3551 \\ free_list: free_list_t,
...@@ -2837,9 +3558,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2837,9 +3558,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2837 ,3558 ,
2838 ".tmp_source.zig:4:25: error: aoeu",3559 ".tmp_source.zig:4:25: error: aoeu",
2839 ".tmp_source.zig:1:36: note: called from here",3560 ".tmp_source.zig:1:36: note: called from here",
2840 ".tmp_source.zig:12:20: note: referenced here");3561 ".tmp_source.zig:12:20: note: referenced here",
3562 );
28413563
2842 cases.add("specify enum tag type that is too small",3564 cases.add(
3565 "specify enum tag type that is too small",
2843 \\const Small = enum (u2) {3566 \\const Small = enum (u2) {
2844 \\ One,3567 \\ One,
2845 \\ Two,3568 \\ Two,
...@@ -2852,9 +3575,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2852,9 +3575,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2852 \\ var x = Small.One;3575 \\ var x = Small.One;
2853 \\}3576 \\}
2854 ,3577 ,
2855 ".tmp_source.zig:1:20: error: 'u2' too small to hold all bits; must be at least 'u3'");3578 ".tmp_source.zig:1:20: error: 'u2' too small to hold all bits; must be at least 'u3'",
3579 );
28563580
2857 cases.add("specify non-integer enum tag type",3581 cases.add(
3582 "specify non-integer enum tag type",
2858 \\const Small = enum (f32) {3583 \\const Small = enum (f32) {
2859 \\ One,3584 \\ One,
2860 \\ Two,3585 \\ Two,
...@@ -2865,9 +3590,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2865,9 +3590,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2865 \\ var x = Small.One;3590 \\ var x = Small.One;
2866 \\}3591 \\}
2867 ,3592 ,
2868 ".tmp_source.zig:1:20: error: expected integer, found 'f32'");3593 ".tmp_source.zig:1:20: error: expected integer, found 'f32'",
3594 );
28693595
2870 cases.add("implicitly casting enum to tag type",3596 cases.add(
3597 "implicitly casting enum to tag type",
2871 \\const Small = enum(u2) {3598 \\const Small = enum(u2) {
2872 \\ One,3599 \\ One,
2873 \\ Two,3600 \\ Two,
...@@ -2879,9 +3606,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2879,9 +3606,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2879 \\ var x: u2 = Small.Two;3606 \\ var x: u2 = Small.Two;
2880 \\}3607 \\}
2881 ,3608 ,
2882 ".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'");3609 ".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'",
3610 );
28833611
2884 cases.add("explicitly casting enum to non tag type",3612 cases.add(
3613 "explicitly casting enum to non tag type",
2885 \\const Small = enum(u2) {3614 \\const Small = enum(u2) {
2886 \\ One,3615 \\ One,
2887 \\ Two,3616 \\ Two,
...@@ -2893,9 +3622,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2893,9 +3622,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2893 \\ var x = u3(Small.Two);3622 \\ var x = u3(Small.Two);
2894 \\}3623 \\}
2895 ,3624 ,
2896 ".tmp_source.zig:9:15: error: enum to integer cast to 'u3' instead of its tag type, 'u2'");3625 ".tmp_source.zig:9:15: error: enum to integer cast to 'u3' instead of its tag type, 'u2'",
3626 );
28973627
2898 cases.add("explicitly casting non tag type to enum",3628 cases.add(
3629 "explicitly casting non tag type to enum",
2899 \\const Small = enum(u2) {3630 \\const Small = enum(u2) {
2900 \\ One,3631 \\ One,
2901 \\ Two,3632 \\ Two,
...@@ -2908,9 +3639,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2908,9 +3639,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2908 \\ var x = Small(y);3639 \\ var x = Small(y);
2909 \\}3640 \\}
2910 ,3641 ,
2911 ".tmp_source.zig:10:18: error: integer to enum cast from 'u3' instead of its tag type, 'u2'");3642 ".tmp_source.zig:10:18: error: integer to enum cast from 'u3' instead of its tag type, 'u2'",
3643 );
29123644
2913 cases.add("non unsigned integer enum tag type",3645 cases.add(
3646 "non unsigned integer enum tag type",
2914 \\const Small = enum(i2) {3647 \\const Small = enum(i2) {
2915 \\ One,3648 \\ One,
2916 \\ Two,3649 \\ Two,
...@@ -2922,9 +3655,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2922,9 +3655,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2922 \\ var y = Small.Two;3655 \\ var y = Small.Two;
2923 \\}3656 \\}
2924 ,3657 ,
2925 ".tmp_source.zig:1:19: error: expected unsigned integer, found 'i2'");3658 ".tmp_source.zig:1:19: error: expected unsigned integer, found 'i2'",
3659 );
29263660
2927 cases.add("struct fields with value assignments",3661 cases.add(
3662 "struct fields with value assignments",
2928 \\const MultipleChoice = struct {3663 \\const MultipleChoice = struct {
2929 \\ A: i32 = 20,3664 \\ A: i32 = 20,
2930 \\};3665 \\};
...@@ -2932,9 +3667,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2932,9 +3667,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2932 \\ var x: MultipleChoice = undefined;3667 \\ var x: MultipleChoice = undefined;
2933 \\}3668 \\}
2934 ,3669 ,
2935 ".tmp_source.zig:2:14: error: enums, not structs, support field assignment");3670 ".tmp_source.zig:2:14: error: enums, not structs, support field assignment",
3671 );
29363672
2937 cases.add("union fields with value assignments",3673 cases.add(
3674 "union fields with value assignments",
2938 \\const MultipleChoice = union {3675 \\const MultipleChoice = union {
2939 \\ A: i32 = 20,3676 \\ A: i32 = 20,
2940 \\};3677 \\};
...@@ -2943,25 +3680,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2943,25 +3680,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2943 \\}3680 \\}
2944 ,3681 ,
2945 ".tmp_source.zig:2:14: error: non-enum union field assignment",3682 ".tmp_source.zig:2:14: error: non-enum union field assignment",
2946 ".tmp_source.zig:1:24: note: consider 'union(enum)' here");3683 ".tmp_source.zig:1:24: note: consider 'union(enum)' here",
3684 );
29473685
2948 cases.add("enum with 0 fields",3686 cases.add(
3687 "enum with 0 fields",
2949 \\const Foo = enum {};3688 \\const Foo = enum {};
2950 \\export fn entry() usize {3689 \\export fn entry() usize {
2951 \\ return @sizeOf(Foo);3690 \\ return @sizeOf(Foo);
2952 \\}3691 \\}
2953 ,3692 ,
2954 ".tmp_source.zig:1:13: error: enums must have 1 or more fields");3693 ".tmp_source.zig:1:13: error: enums must have 1 or more fields",
3694 );
29553695
2956 cases.add("union with 0 fields",3696 cases.add(
3697 "union with 0 fields",
2957 \\const Foo = union {};3698 \\const Foo = union {};
2958 \\export fn entry() usize {3699 \\export fn entry() usize {
2959 \\ return @sizeOf(Foo);3700 \\ return @sizeOf(Foo);
2960 \\}3701 \\}
2961 ,3702 ,
2962 ".tmp_source.zig:1:13: error: unions must have 1 or more fields");3703 ".tmp_source.zig:1:13: error: unions must have 1 or more fields",
3704 );
29633705
2964 cases.add("enum value already taken",3706 cases.add(
3707 "enum value already taken",
2965 \\const MultipleChoice = enum(u32) {3708 \\const MultipleChoice = enum(u32) {
2966 \\ A = 20,3709 \\ A = 20,
2967 \\ B = 40,3710 \\ B = 40,
...@@ -2974,9 +3717,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2974,9 +3717,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2974 \\}3717 \\}
2975 ,3718 ,
2976 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",3719 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",
2977 ".tmp_source.zig:4:9: note: other occurrence here");3720 ".tmp_source.zig:4:9: note: other occurrence here",
3721 );
29783722
2979 cases.add("union with specified enum omits field",3723 cases.add(
3724 "union with specified enum omits field",
2980 \\const Letter = enum {3725 \\const Letter = enum {
2981 \\ A,3726 \\ A,
2982 \\ B,3727 \\ B,
...@@ -2991,9 +3736,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -2991,9 +3736,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
2991 \\}3736 \\}
2992 ,3737 ,
2993 ".tmp_source.zig:6:17: error: enum field missing: 'C'",3738 ".tmp_source.zig:6:17: error: enum field missing: 'C'",
2994 ".tmp_source.zig:4:5: note: declared here");3739 ".tmp_source.zig:4:5: note: declared here",
3740 );
29953741
2996 cases.add("@TagType when union has no attached enum",3742 cases.add(
3743 "@TagType when union has no attached enum",
2997 \\const Foo = union {3744 \\const Foo = union {
2998 \\ A: i32,3745 \\ A: i32,
2999 \\};3746 \\};
...@@ -3002,9 +3749,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3002,9 +3749,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3002 \\}3749 \\}
3003 ,3750 ,
3004 ".tmp_source.zig:5:24: error: union 'Foo' has no tag",3751 ".tmp_source.zig:5:24: error: union 'Foo' has no tag",
3005 ".tmp_source.zig:1:13: note: consider 'union(enum)' here");3752 ".tmp_source.zig:1:13: note: consider 'union(enum)' here",
3753 );
30063754
3007 cases.add("non-integer tag type to automatic union enum",3755 cases.add(
3756 "non-integer tag type to automatic union enum",
3008 \\const Foo = union(enum(f32)) {3757 \\const Foo = union(enum(f32)) {
3009 \\ A: i32,3758 \\ A: i32,
3010 \\};3759 \\};
...@@ -3012,9 +3761,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3012,9 +3761,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3012 \\ const x = @TagType(Foo);3761 \\ const x = @TagType(Foo);
3013 \\}3762 \\}
3014 ,3763 ,
3015 ".tmp_source.zig:1:23: error: expected integer tag type, found 'f32'");3764 ".tmp_source.zig:1:23: error: expected integer tag type, found 'f32'",
3765 );
30163766
3017 cases.add("non-enum tag type passed to union",3767 cases.add(
3768 "non-enum tag type passed to union",
3018 \\const Foo = union(u32) {3769 \\const Foo = union(u32) {
3019 \\ A: i32,3770 \\ A: i32,
3020 \\};3771 \\};
...@@ -3022,9 +3773,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3022,9 +3773,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3022 \\ const x = @TagType(Foo);3773 \\ const x = @TagType(Foo);
3023 \\}3774 \\}
3024 ,3775 ,
3025 ".tmp_source.zig:1:18: error: expected enum tag type, found 'u32'");3776 ".tmp_source.zig:1:18: error: expected enum tag type, found 'u32'",
3777 );
30263778
3027 cases.add("union auto-enum value already taken",3779 cases.add(
3780 "union auto-enum value already taken",
3028 \\const MultipleChoice = union(enum(u32)) {3781 \\const MultipleChoice = union(enum(u32)) {
3029 \\ A = 20,3782 \\ A = 20,
3030 \\ B = 40,3783 \\ B = 40,
...@@ -3037,9 +3790,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3037,9 +3790,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3037 \\}3790 \\}
3038 ,3791 ,
3039 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",3792 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",
3040 ".tmp_source.zig:4:9: note: other occurrence here");3793 ".tmp_source.zig:4:9: note: other occurrence here",
3794 );
30413795
3042 cases.add("union enum field does not match enum",3796 cases.add(
3797 "union enum field does not match enum",
3043 \\const Letter = enum {3798 \\const Letter = enum {
3044 \\ A,3799 \\ A,
3045 \\ B,3800 \\ B,
...@@ -3056,9 +3811,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3056,9 +3811,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3056 \\}3811 \\}
3057 ,3812 ,
3058 ".tmp_source.zig:10:5: error: enum field not found: 'D'",3813 ".tmp_source.zig:10:5: error: enum field not found: 'D'",
3059 ".tmp_source.zig:1:16: note: enum declared here");3814 ".tmp_source.zig:1:16: note: enum declared here",
3815 );
30603816
3061 cases.add("field type supplied in an enum",3817 cases.add(
3818 "field type supplied in an enum",
3062 \\const Letter = enum {3819 \\const Letter = enum {
3063 \\ A: void,3820 \\ A: void,
3064 \\ B,3821 \\ B,
...@@ -3069,9 +3826,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3069,9 +3826,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3069 \\}3826 \\}
3070 ,3827 ,
3071 ".tmp_source.zig:2:8: error: structs and unions, not enums, support field types",3828 ".tmp_source.zig:2:8: error: structs and unions, not enums, support field types",
3072 ".tmp_source.zig:1:16: note: consider 'union(enum)' here");3829 ".tmp_source.zig:1:16: note: consider 'union(enum)' here",
3830 );
30733831
3074 cases.add("struct field missing type",3832 cases.add(
3833 "struct field missing type",
3075 \\const Letter = struct {3834 \\const Letter = struct {
3076 \\ A,3835 \\ A,
3077 \\};3836 \\};
...@@ -3079,9 +3838,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3079,9 +3838,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3079 \\ var a = Letter { .A = {} };3838 \\ var a = Letter { .A = {} };
3080 \\}3839 \\}
3081 ,3840 ,
3082 ".tmp_source.zig:2:5: error: struct field missing type");3841 ".tmp_source.zig:2:5: error: struct field missing type",
3842 );
30833843
3084 cases.add("extern union field missing type",3844 cases.add(
3845 "extern union field missing type",
3085 \\const Letter = extern union {3846 \\const Letter = extern union {
3086 \\ A,3847 \\ A,
3087 \\};3848 \\};
...@@ -3089,9 +3850,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3089,9 +3850,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3089 \\ var a = Letter { .A = {} };3850 \\ var a = Letter { .A = {} };
3090 \\}3851 \\}
3091 ,3852 ,
3092 ".tmp_source.zig:2:5: error: union field missing type");3853 ".tmp_source.zig:2:5: error: union field missing type",
3854 );
30933855
3094 cases.add("extern union given enum tag type",3856 cases.add(
3857 "extern union given enum tag type",
3095 \\const Letter = enum {3858 \\const Letter = enum {
3096 \\ A,3859 \\ A,
3097 \\ B,3860 \\ B,
...@@ -3106,9 +3869,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3106,9 +3869,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3106 \\ var a = Payload { .A = 1234 };3869 \\ var a = Payload { .A = 1234 };
3107 \\}3870 \\}
3108 ,3871 ,
3109 ".tmp_source.zig:6:29: error: extern union does not support enum tag type");3872 ".tmp_source.zig:6:29: error: extern union does not support enum tag type",
3873 );
31103874
3111 cases.add("packed union given enum tag type",3875 cases.add(
3876 "packed union given enum tag type",
3112 \\const Letter = enum {3877 \\const Letter = enum {
3113 \\ A,3878 \\ A,
3114 \\ B,3879 \\ B,
...@@ -3123,9 +3888,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3123,9 +3888,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3123 \\ var a = Payload { .A = 1234 };3888 \\ var a = Payload { .A = 1234 };
3124 \\}3889 \\}
3125 ,3890 ,
3126 ".tmp_source.zig:6:29: error: packed union does not support enum tag type");3891 ".tmp_source.zig:6:29: error: packed union does not support enum tag type",
3892 );
31273893
3128 cases.add("switch on union with no attached enum",3894 cases.add(
3895 "switch on union with no attached enum",
3129 \\const Payload = union {3896 \\const Payload = union {
3130 \\ A: i32,3897 \\ A: i32,
3131 \\ B: f64,3898 \\ B: f64,
...@@ -3136,16 +3903,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3136,16 +3903,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3136 \\ foo(a);3903 \\ foo(a);
3137 \\}3904 \\}
3138 \\fn foo(a: &const Payload) void {3905 \\fn foo(a: &const Payload) void {
3139 \\ switch (*a) {3906 \\ switch (a.*) {
3140 \\ Payload.A => {},3907 \\ Payload.A => {},
3141 \\ else => unreachable,3908 \\ else => unreachable,
3142 \\ }3909 \\ }
3143 \\}3910 \\}
3144 ,3911 ,
3145 ".tmp_source.zig:11:13: error: switch on union which has no attached enum",3912 ".tmp_source.zig:11:14: error: switch on union which has no attached enum",
3146 ".tmp_source.zig:1:17: note: consider 'union(enum)' here");3913 ".tmp_source.zig:1:17: note: consider 'union(enum)' here",
3914 );
31473915
3148 cases.add("enum in field count range but not matching tag",3916 cases.add(
3917 "enum in field count range but not matching tag",
3149 \\const Foo = enum(u32) {3918 \\const Foo = enum(u32) {
3150 \\ A = 10,3919 \\ A = 10,
3151 \\ B = 11,3920 \\ B = 11,
...@@ -3155,9 +3924,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3155,9 +3924,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3155 \\}3924 \\}
3156 ,3925 ,
3157 ".tmp_source.zig:6:16: error: enum 'Foo' has no tag matching integer value 0",3926 ".tmp_source.zig:6:16: error: enum 'Foo' has no tag matching integer value 0",
3158 ".tmp_source.zig:1:13: note: 'Foo' declared here");3927 ".tmp_source.zig:1:13: note: 'Foo' declared here",
3928 );
31593929
3160 cases.add("comptime cast enum to union but field has payload",3930 cases.add(
3931 "comptime cast enum to union but field has payload",
3161 \\const Letter = enum { A, B, C };3932 \\const Letter = enum { A, B, C };
3162 \\const Value = union(Letter) {3933 \\const Value = union(Letter) {
3163 \\ A: i32,3934 \\ A: i32,
...@@ -3169,9 +3940,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3169,9 +3940,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3169 \\}3940 \\}
3170 ,3941 ,
3171 ".tmp_source.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'",3942 ".tmp_source.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'",
3172 ".tmp_source.zig:3:5: note: field 'A' declared here");3943 ".tmp_source.zig:3:5: note: field 'A' declared here",
3944 );
31733945
3174 cases.add("runtime cast to union which has non-void fields",3946 cases.add(
3947 "runtime cast to union which has non-void fields",
3175 \\const Letter = enum { A, B, C };3948 \\const Letter = enum { A, B, C };
3176 \\const Value = union(Letter) {3949 \\const Value = union(Letter) {
3177 \\ A: i32,3950 \\ A: i32,
...@@ -3186,9 +3959,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3186,9 +3959,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3186 \\}3959 \\}
3187 ,3960 ,
3188 ".tmp_source.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",3961 ".tmp_source.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",
3189 ".tmp_source.zig:3:5: note: field 'A' has type 'i32'");3962 ".tmp_source.zig:3:5: note: field 'A' has type 'i32'",
3963 );
31903964
3191 cases.add("self-referencing function pointer field",3965 cases.add(
3966 "self-referencing function pointer field",
3192 \\const S = struct {3967 \\const S = struct {
3193 \\ f: fn(_: S) void,3968 \\ f: fn(_: S) void,
3194 \\};3969 \\};
...@@ -3198,19 +3973,23 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3198,19 +3973,23 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3198 \\ var _ = S { .f = f };3973 \\ var _ = S { .f = f };
3199 \\}3974 \\}
3200 ,3975 ,
3201 ".tmp_source.zig:4:9: error: type 'S' is not copyable; cannot pass by value");3976 ".tmp_source.zig:4:9: error: type 'S' is not copyable; cannot pass by value",
3977 );
32023978
3203 cases.add("taking offset of void field in struct",3979 cases.add(
3980 "taking offset of void field in struct",
3204 \\const Empty = struct {3981 \\const Empty = struct {
3205 \\ val: void,3982 \\ val: void,
3206 \\};3983 \\};
3207 \\export fn foo() void {3984 \\export fn foo() void {
3208 \\ const fieldOffset = @offsetOf(Empty, "val");3985 \\ const fieldOffset = @offsetOf(Empty, "val",);
3209 \\}3986 \\}
3210 ,3987 ,
3211 ".tmp_source.zig:5:42: error: zero-bit field 'val' in struct 'Empty' has no offset");3988 ".tmp_source.zig:5:42: error: zero-bit field 'val' in struct 'Empty' has no offset",
3989 );
32123990
3213 cases.add("invalid union field access in comptime",3991 cases.add(
3992 "invalid union field access in comptime",
3214 \\const Foo = union {3993 \\const Foo = union {
3215 \\ Bar: u8,3994 \\ Bar: u8,
3216 \\ Baz: void,3995 \\ Baz: void,
...@@ -3220,21 +3999,26 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -3220,21 +3999,26 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
3220 \\ const bar_val = foo.Bar;3999 \\ const bar_val = foo.Bar;
3221 \\}4000 \\}
3222 ,4001 ,
3223 ".tmp_source.zig:7:24: error: accessing union field 'Bar' while field 'Baz' is set");4002 ".tmp_source.zig:7:24: error: accessing union field 'Bar' while field 'Baz' is set",
4003 );
32244004
3225 cases.add("getting return type of generic function",4005 cases.add(
4006 "getting return type of generic function",
3226 \\fn generic(a: var) void {}4007 \\fn generic(a: var) void {}
3227 \\comptime {4008 \\comptime {
3228 \\ _ = @typeOf(generic).ReturnType;4009 \\ _ = @typeOf(generic).ReturnType;
3229 \\}4010 \\}
3230 ,4011 ,
3231 ".tmp_source.zig:3:25: error: ReturnType has not been resolved because 'fn(var)var' is generic");4012 ".tmp_source.zig:3:25: error: ReturnType has not been resolved because 'fn(var)var' is generic",
4013 );
32324014
3233 cases.add("getting @ArgType of generic function",4015 cases.add(
4016 "getting @ArgType of generic function",
3234 \\fn generic(a: var) void {}4017 \\fn generic(a: var) void {}
3235 \\comptime {4018 \\comptime {
3236 \\ _ = @ArgType(@typeOf(generic), 0);4019 \\ _ = @ArgType(@typeOf(generic), 0);
3237 \\}4020 \\}
3238 ,4021 ,
3239 ".tmp_source.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var)var' is generic");4022 ".tmp_source.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var)var' is generic",
4023 );
3240}4024}
test/gen_h.zig-1
...@@ -76,5 +76,4 @@ pub fn addCases(cases: &tests.GenHContext) void {...@@ -76,5 +76,4 @@ pub fn addCases(cases: &tests.GenHContext) void {
76 \\TEST_EXPORT void entry(struct Foo foo, uint8_t bar[]);76 \\TEST_EXPORT void entry(struct Foo foo, uint8_t bar[]);
77 \\77 \\
78 );78 );
79
80}79}
test/standalone/brace_expansion/main.zig+14-16
...@@ -16,7 +16,7 @@ const Token = union(enum) {...@@ -16,7 +16,7 @@ const Token = union(enum) {
1616
17var global_allocator: &mem.Allocator = undefined;17var global_allocator: &mem.Allocator = undefined;
1818
19fn tokenize(input:[] const u8) !ArrayList(Token) {19fn tokenize(input: []const u8) !ArrayList(Token) {
20 const State = enum {20 const State = enum {
21 Start,21 Start,
22 Word,22 Word,
...@@ -41,7 +41,7 @@ fn tokenize(input:[] const u8) !ArrayList(Token) {...@@ -41,7 +41,7 @@ fn tokenize(input:[] const u8) !ArrayList(Token) {
41 State.Word => switch (b) {41 State.Word => switch (b) {
42 'a'...'z', 'A'...'Z' => {},42 'a'...'z', 'A'...'Z' => {},
43 '{', '}', ',' => {43 '{', '}', ',' => {
44 try token_list.append(Token { .Word = input[tok_begin..i] });44 try token_list.append(Token{ .Word = input[tok_begin..i] });
45 switch (b) {45 switch (b) {
46 '{' => try token_list.append(Token.OpenBrace),46 '{' => try token_list.append(Token.OpenBrace),
47 '}' => try token_list.append(Token.CloseBrace),47 '}' => try token_list.append(Token.CloseBrace),
...@@ -56,7 +56,7 @@ fn tokenize(input:[] const u8) !ArrayList(Token) {...@@ -56,7 +56,7 @@ fn tokenize(input:[] const u8) !ArrayList(Token) {
56 }56 }
57 switch (state) {57 switch (state) {
58 State.Start => {},58 State.Start => {},
59 State.Word => try token_list.append(Token {.Word = input[tok_begin..] }),59 State.Word => try token_list.append(Token{ .Word = input[tok_begin..] }),
60 }60 }
61 try token_list.append(Token.Eof);61 try token_list.append(Token.Eof);
62 return token_list;62 return token_list;
...@@ -68,24 +68,24 @@ const Node = union(enum) {...@@ -68,24 +68,24 @@ const Node = union(enum) {
68 Combine: []Node,68 Combine: []Node,
69};69};
7070
71const ParseError = error {71const ParseError = error{
72 InvalidInput,72 InvalidInput,
73 OutOfMemory,73 OutOfMemory,
74};74};
7575
76fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node {76fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node {
77 const first_token = tokens.items[*token_index];77 const first_token = tokens.items[token_index.*];
78 *token_index += 1;78 token_index.* += 1;
7979
80 const result_node = switch (first_token) {80 const result_node = switch (first_token) {
81 Token.Word => |word| Node { .Scalar = word },81 Token.Word => |word| Node{ .Scalar = word },
82 Token.OpenBrace => blk: {82 Token.OpenBrace => blk: {
83 var list = ArrayList(Node).init(global_allocator);83 var list = ArrayList(Node).init(global_allocator);
84 while (true) {84 while (true) {
85 try list.append(try parse(tokens, token_index));85 try list.append(try parse(tokens, token_index));
8686
87 const token = tokens.items[*token_index];87 const token = tokens.items[token_index.*];
88 *token_index += 1;88 token_index.* += 1;
8989
90 switch (token) {90 switch (token) {
91 Token.CloseBrace => break,91 Token.CloseBrace => break,
...@@ -93,17 +93,17 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node {...@@ -93,17 +93,17 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node {
93 else => return error.InvalidInput,93 else => return error.InvalidInput,
94 }94 }
95 }95 }
96 break :blk Node { .List = list };96 break :blk Node{ .List = list };
97 },97 },
98 else => return error.InvalidInput,98 else => return error.InvalidInput,
99 };99 };
100100
101 switch (tokens.items[*token_index]) {101 switch (tokens.items[token_index.*]) {
102 Token.Word, Token.OpenBrace => {102 Token.Word, Token.OpenBrace => {
103 const pair = try global_allocator.alloc(Node, 2);103 const pair = try global_allocator.alloc(Node, 2);
104 pair[0] = result_node;104 pair[0] = result_node;
105 pair[1] = try parse(tokens, token_index);105 pair[1] = try parse(tokens, token_index);
106 return Node { .Combine = pair };106 return Node{ .Combine = pair };
107 },107 },
108 else => return result_node,108 else => return result_node,
109 }109 }
...@@ -137,13 +137,11 @@ fn expandString(input: []const u8, output: &Buffer) !void {...@@ -137,13 +137,11 @@ fn expandString(input: []const u8, output: &Buffer) !void {
137 }137 }
138}138}
139139
140const ExpandNodeError = error {140const ExpandNodeError = error{OutOfMemory};
141 OutOfMemory,
142};
143141
144fn expandNode(node: &const Node, output: &ArrayList(Buffer)) ExpandNodeError!void {142fn expandNode(node: &const Node, output: &ArrayList(Buffer)) ExpandNodeError!void {
145 assert(output.len == 0);143 assert(output.len == 0);
146 switch (*node) {144 switch (node.*) {
147 Node.Scalar => |scalar| {145 Node.Scalar => |scalar| {
148 try output.append(try Buffer.init(global_allocator, scalar));146 try output.append(try Buffer.init(global_allocator, scalar));
149 },147 },
test/standalone/issue_339/test.zig+4-1
...@@ -1,5 +1,8 @@...@@ -1,5 +1,8 @@
1const StackTrace = @import("builtin").StackTrace;1const StackTrace = @import("builtin").StackTrace;
2pub fn panic(msg: []const u8, stack_trace: ?&StackTrace) noreturn { @breakpoint(); while (true) {} }2pub fn panic(msg: []const u8, stack_trace: ?&StackTrace) noreturn {
3 @breakpoint();
4 while (true) {}
5}
36
4fn bar() error!void {}7fn bar() error!void {}
58
test/standalone/pkg_import/pkg.zig+3-1
...@@ -1 +1,3 @@...@@ -1 +1,3 @@
1pub fn add(a: i32, b: i32) i32 { return a + b; }1pub fn add(a: i32, b: i32) i32 {
2 return a + b;
3}
test/standalone/use_alias/main.zig+1-1
...@@ -2,7 +2,7 @@ const c = @import("c.zig");...@@ -2,7 +2,7 @@ const c = @import("c.zig");
2const assert = @import("std").debug.assert;2const assert = @import("std").debug.assert;
33
4test "symbol exists" {4test "symbol exists" {
5 var foo = c.Foo {5 var foo = c.Foo{
6 .a = 1,6 .a = 1,
7 .b = 1,7 .b = 1,
8 };8 };
test/tests.zig+90-100
...@@ -27,18 +27,18 @@ const TestTarget = struct {...@@ -27,18 +27,18 @@ const TestTarget = struct {
27 environ: builtin.Environ,27 environ: builtin.Environ,
28};28};
2929
30const test_targets = []TestTarget {30const test_targets = []TestTarget{
31 TestTarget {31 TestTarget{
32 .os = builtin.Os.linux,32 .os = builtin.Os.linux,
33 .arch = builtin.Arch.x86_64,33 .arch = builtin.Arch.x86_64,
34 .environ = builtin.Environ.gnu,34 .environ = builtin.Environ.gnu,
35 },35 },
36 TestTarget {36 TestTarget{
37 .os = builtin.Os.macosx,37 .os = builtin.Os.macosx,
38 .arch = builtin.Arch.x86_64,38 .arch = builtin.Arch.x86_64,
39 .environ = builtin.Environ.unknown,39 .environ = builtin.Environ.unknown,
40 },40 },
41 TestTarget {41 TestTarget{
42 .os = builtin.Os.windows,42 .os = builtin.Os.windows,
43 .arch = builtin.Arch.x86_64,43 .arch = builtin.Arch.x86_64,
44 .environ = builtin.Environ.msvc,44 .environ = builtin.Environ.msvc,
...@@ -49,7 +49,7 @@ const max_stdout_size = 1 * 1024 * 1024; // 1 MB...@@ -49,7 +49,7 @@ const max_stdout_size = 1 * 1024 * 1024; // 1 MB
4949
50pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {50pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
51 const cases = b.allocator.create(CompareOutputContext) catch unreachable;51 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
52 *cases = CompareOutputContext {52 cases.* = CompareOutputContext{
53 .b = b,53 .b = b,
54 .step = b.step("test-compare-output", "Run the compare output tests"),54 .step = b.step("test-compare-output", "Run the compare output tests"),
55 .test_index = 0,55 .test_index = 0,
...@@ -63,7 +63,7 @@ pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build...@@ -63,7 +63,7 @@ pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build
6363
64pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {64pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
65 const cases = b.allocator.create(CompareOutputContext) catch unreachable;65 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
66 *cases = CompareOutputContext {66 cases.* = CompareOutputContext{
67 .b = b,67 .b = b,
68 .step = b.step("test-runtime-safety", "Run the runtime safety tests"),68 .step = b.step("test-runtime-safety", "Run the runtime safety tests"),
69 .test_index = 0,69 .test_index = 0,
...@@ -77,7 +77,7 @@ pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) &build...@@ -77,7 +77,7 @@ pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) &build
7777
78pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {78pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
79 const cases = b.allocator.create(CompileErrorContext) catch unreachable;79 const cases = b.allocator.create(CompileErrorContext) catch unreachable;
80 *cases = CompileErrorContext {80 cases.* = CompileErrorContext{
81 .b = b,81 .b = b,
82 .step = b.step("test-compile-errors", "Run the compile error tests"),82 .step = b.step("test-compile-errors", "Run the compile error tests"),
83 .test_index = 0,83 .test_index = 0,
...@@ -91,7 +91,7 @@ pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) &build....@@ -91,7 +91,7 @@ pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) &build.
9191
92pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {92pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
93 const cases = b.allocator.create(BuildExamplesContext) catch unreachable;93 const cases = b.allocator.create(BuildExamplesContext) catch unreachable;
94 *cases = BuildExamplesContext {94 cases.* = BuildExamplesContext{
95 .b = b,95 .b = b,
96 .step = b.step("test-build-examples", "Build the examples"),96 .step = b.step("test-build-examples", "Build the examples"),
97 .test_index = 0,97 .test_index = 0,
...@@ -105,7 +105,7 @@ pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) &build....@@ -105,7 +105,7 @@ pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) &build.
105105
106pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {106pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
107 const cases = b.allocator.create(CompareOutputContext) catch unreachable;107 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
108 *cases = CompareOutputContext {108 cases.* = CompareOutputContext{
109 .b = b,109 .b = b,
110 .step = b.step("test-asm-link", "Run the assemble and link tests"),110 .step = b.step("test-asm-link", "Run the assemble and link tests"),
111 .test_index = 0,111 .test_index = 0,
...@@ -119,7 +119,7 @@ pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) &bui...@@ -119,7 +119,7 @@ pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) &bui
119119
120pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {120pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
121 const cases = b.allocator.create(TranslateCContext) catch unreachable;121 const cases = b.allocator.create(TranslateCContext) catch unreachable;
122 *cases = TranslateCContext {122 cases.* = TranslateCContext{
123 .b = b,123 .b = b,
124 .step = b.step("test-translate-c", "Run the C transation tests"),124 .step = b.step("test-translate-c", "Run the C transation tests"),
125 .test_index = 0,125 .test_index = 0,
...@@ -133,7 +133,7 @@ pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) &build.St...@@ -133,7 +133,7 @@ pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) &build.St
133133
134pub fn addGenHTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {134pub fn addGenHTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
135 const cases = b.allocator.create(GenHContext) catch unreachable;135 const cases = b.allocator.create(GenHContext) catch unreachable;
136 *cases = GenHContext {136 cases.* = GenHContext{
137 .b = b,137 .b = b,
138 .step = b.step("test-gen-h", "Run the C header file generation tests"),138 .step = b.step("test-gen-h", "Run the C header file generation tests"),
139 .test_index = 0,139 .test_index = 0,
...@@ -145,22 +145,26 @@ pub fn addGenHTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {...@@ -145,22 +145,26 @@ pub fn addGenHTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
145 return cases.step;145 return cases.step;
146}146}
147147
148148pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []const u8, name: []const u8, desc: []const u8, with_lldb: bool) &build.Step {
149pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []const u8,
150 name:[] const u8, desc: []const u8, with_lldb: bool) &build.Step
151{
152 const step = b.step(b.fmt("test-{}", name), desc);149 const step = b.step(b.fmt("test-{}", name), desc);
153 for (test_targets) |test_target| {150 for (test_targets) |test_target| {
154 const is_native = (test_target.os == builtin.os and test_target.arch == builtin.arch);151 const is_native = (test_target.os == builtin.os and test_target.arch == builtin.arch);
155 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast, Mode.ReleaseSmall}) |mode| {152 for ([]Mode{
156 for ([]bool{false, true}) |link_libc| {153 Mode.Debug,
154 Mode.ReleaseSafe,
155 Mode.ReleaseFast,
156 Mode.ReleaseSmall,
157 }) |mode| {
158 for ([]bool{
159 false,
160 true,
161 }) |link_libc| {
157 if (link_libc and !is_native) {162 if (link_libc and !is_native) {
158 // don't assume we have a cross-compiling libc set up163 // don't assume we have a cross-compiling libc set up
159 continue;164 continue;
160 }165 }
161 const these_tests = b.addTest(root_src);166 const these_tests = b.addTest(root_src);
162 these_tests.setNamePrefix(b.fmt("{}-{}-{}-{}-{} ", name, @tagName(test_target.os),167 these_tests.setNamePrefix(b.fmt("{}-{}-{}-{}-{} ", name, @tagName(test_target.os), @tagName(test_target.arch), @tagName(mode), if (link_libc) "c" else "bare"));
163 @tagName(test_target.arch), @tagName(mode), if (link_libc) "c" else "bare"));
164 these_tests.setFilter(test_filter);168 these_tests.setFilter(test_filter);
165 these_tests.setBuildMode(mode);169 these_tests.setBuildMode(mode);
166 if (!is_native) {170 if (!is_native) {
...@@ -171,7 +175,15 @@ pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []cons...@@ -171,7 +175,15 @@ pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []cons
171 }175 }
172 if (with_lldb) {176 if (with_lldb) {
173 these_tests.setExecCmd([]?[]const u8{177 these_tests.setExecCmd([]?[]const u8{
174 "lldb", null, "-o", "run", "-o", "bt", "-o", "exit"});178 "lldb",
179 null,
180 "-o",
181 "run",
182 "-o",
183 "bt",
184 "-o",
185 "exit",
186 });
175 }187 }
176 step.dependOn(&these_tests.step);188 step.dependOn(&these_tests.step);
177 }189 }
...@@ -206,7 +218,7 @@ pub const CompareOutputContext = struct {...@@ -206,7 +218,7 @@ pub const CompareOutputContext = struct {
206 };218 };
207219
208 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {220 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
209 self.sources.append(SourceFile {221 self.sources.append(SourceFile{
210 .filename = filename,222 .filename = filename,
211 .source = source,223 .source = source,
212 }) catch unreachable;224 }) catch unreachable;
...@@ -226,13 +238,10 @@ pub const CompareOutputContext = struct {...@@ -226,13 +238,10 @@ pub const CompareOutputContext = struct {
226 test_index: usize,238 test_index: usize,
227 cli_args: []const []const u8,239 cli_args: []const []const u8,
228240
229 pub fn create(context: &CompareOutputContext, exe_path: []const u8,241 pub fn create(context: &CompareOutputContext, exe_path: []const u8, name: []const u8, expected_output: []const u8, cli_args: []const []const u8) &RunCompareOutputStep {
230 name: []const u8, expected_output: []const u8,
231 cli_args: []const []const u8) &RunCompareOutputStep
232 {
233 const allocator = context.b.allocator;242 const allocator = context.b.allocator;
234 const ptr = allocator.create(RunCompareOutputStep) catch unreachable;243 const ptr = allocator.create(RunCompareOutputStep) catch unreachable;
235 *ptr = RunCompareOutputStep {244 ptr.* = RunCompareOutputStep{
236 .context = context,245 .context = context,
237 .exe_path = exe_path,246 .exe_path = exe_path,
238 .name = name,247 .name = name,
...@@ -258,7 +267,7 @@ pub const CompareOutputContext = struct {...@@ -258,7 +267,7 @@ pub const CompareOutputContext = struct {
258 args.append(arg) catch unreachable;267 args.append(arg) catch unreachable;
259 }268 }
260269
261 warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);270 warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
262271
263 const child = os.ChildProcess.init(args.toSliceConst(), b.allocator) catch unreachable;272 const child = os.ChildProcess.init(args.toSliceConst(), b.allocator) catch unreachable;
264 defer child.deinit();273 defer child.deinit();
...@@ -295,7 +304,6 @@ pub const CompareOutputContext = struct {...@@ -295,7 +304,6 @@ pub const CompareOutputContext = struct {
295 },304 },
296 }305 }
297306
298
299 if (!mem.eql(u8, self.expected_output, stdout.toSliceConst())) {307 if (!mem.eql(u8, self.expected_output, stdout.toSliceConst())) {
300 warn(308 warn(
301 \\309 \\
...@@ -318,12 +326,10 @@ pub const CompareOutputContext = struct {...@@ -318,12 +326,10 @@ pub const CompareOutputContext = struct {
318 name: []const u8,326 name: []const u8,
319 test_index: usize,327 test_index: usize,
320328
321 pub fn create(context: &CompareOutputContext, exe_path: []const u8,329 pub fn create(context: &CompareOutputContext, exe_path: []const u8, name: []const u8) &RuntimeSafetyRunStep {
322 name: []const u8) &RuntimeSafetyRunStep
323 {
324 const allocator = context.b.allocator;330 const allocator = context.b.allocator;
325 const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;331 const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
326 *ptr = RuntimeSafetyRunStep {332 ptr.* = RuntimeSafetyRunStep{
327 .context = context,333 .context = context,
328 .exe_path = exe_path,334 .exe_path = exe_path,
329 .name = name,335 .name = name,
...@@ -340,7 +346,7 @@ pub const CompareOutputContext = struct {...@@ -340,7 +346,7 @@ pub const CompareOutputContext = struct {
340346
341 const full_exe_path = b.pathFromRoot(self.exe_path);347 const full_exe_path = b.pathFromRoot(self.exe_path);
342348
343 warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);349 warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
344350
345 const child = os.ChildProcess.init([][]u8{full_exe_path}, b.allocator) catch unreachable;351 const child = os.ChildProcess.init([][]u8{full_exe_path}, b.allocator) catch unreachable;
346 defer child.deinit();352 defer child.deinit();
...@@ -358,19 +364,16 @@ pub const CompareOutputContext = struct {...@@ -358,19 +364,16 @@ pub const CompareOutputContext = struct {
358 switch (term) {364 switch (term) {
359 Term.Exited => |code| {365 Term.Exited => |code| {
360 if (code != expected_exit_code) {366 if (code != expected_exit_code) {
361 warn("\nProgram expected to exit with code {} " ++367 warn("\nProgram expected to exit with code {} " ++ "but exited with code {}\n", expected_exit_code, code);
362 "but exited with code {}\n", expected_exit_code, code);
363 return error.TestFailed;368 return error.TestFailed;
364 }369 }
365 },370 },
366 Term.Signal => |sig| {371 Term.Signal => |sig| {
367 warn("\nProgram expected to exit with code {} " ++372 warn("\nProgram expected to exit with code {} " ++ "but instead signaled {}\n", expected_exit_code, sig);
368 "but instead signaled {}\n", expected_exit_code, sig);
369 return error.TestFailed;373 return error.TestFailed;
370 },374 },
371 else => {375 else => {
372 warn("\nProgram expected to exit with code {}" ++376 warn("\nProgram expected to exit with code {}" ++ " but exited in an unexpected way\n", expected_exit_code);
373 " but exited in an unexpected way\n", expected_exit_code);
374 return error.TestFailed;377 return error.TestFailed;
375 },378 },
376 }379 }
...@@ -379,10 +382,8 @@ pub const CompareOutputContext = struct {...@@ -379,10 +382,8 @@ pub const CompareOutputContext = struct {
379 }382 }
380 };383 };
381384
382 pub fn createExtra(self: &CompareOutputContext, name: []const u8, source: []const u8,385 pub fn createExtra(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8, special: Special) TestCase {
383 expected_output: []const u8, special: Special) TestCase386 var tc = TestCase{
384 {
385 var tc = TestCase {
386 .name = name,387 .name = name,
387 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),388 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
388 .expected_output = expected_output,389 .expected_output = expected_output,
...@@ -395,9 +396,7 @@ pub const CompareOutputContext = struct {...@@ -395,9 +396,7 @@ pub const CompareOutputContext = struct {
395 return tc;396 return tc;
396 }397 }
397398
398 pub fn create(self: &CompareOutputContext, name: []const u8, source: []const u8,399 pub fn create(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) TestCase {
399 expected_output: []const u8) TestCase
400 {
401 return createExtra(self, name, source, expected_output, Special.None);400 return createExtra(self, name, source, expected_output, Special.None);
402 }401 }
403402
...@@ -431,8 +430,7 @@ pub const CompareOutputContext = struct {...@@ -431,8 +430,7 @@ pub const CompareOutputContext = struct {
431 Special.Asm => {430 Special.Asm => {
432 const annotated_case_name = fmt.allocPrint(self.b.allocator, "assemble-and-link {}", case.name) catch unreachable;431 const annotated_case_name = fmt.allocPrint(self.b.allocator, "assemble-and-link {}", case.name) catch unreachable;
433 if (self.test_filter) |filter| {432 if (self.test_filter) |filter| {
434 if (mem.indexOf(u8, annotated_case_name, filter) == null)433 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
435 return;
436 }434 }
437435
438 const exe = b.addExecutable("test", null);436 const exe = b.addExecutable("test", null);
...@@ -444,19 +442,21 @@ pub const CompareOutputContext = struct {...@@ -444,19 +442,21 @@ pub const CompareOutputContext = struct {
444 exe.step.dependOn(&write_src.step);442 exe.step.dependOn(&write_src.step);
445 }443 }
446444
447 const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), annotated_case_name,445 const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), annotated_case_name, case.expected_output, case.cli_args);
448 case.expected_output, case.cli_args);
449 run_and_cmp_output.step.dependOn(&exe.step);446 run_and_cmp_output.step.dependOn(&exe.step);
450447
451 self.step.dependOn(&run_and_cmp_output.step);448 self.step.dependOn(&run_and_cmp_output.step);
452 },449 },
453 Special.None => {450 Special.None => {
454 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast, Mode.ReleaseSmall}) |mode| {451 for ([]Mode{
455 const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {} ({})",452 Mode.Debug,
456 "compare-output", case.name, @tagName(mode)) catch unreachable;453 Mode.ReleaseSafe,
454 Mode.ReleaseFast,
455 Mode.ReleaseSmall,
456 }) |mode| {
457 const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {} ({})", "compare-output", case.name, @tagName(mode)) catch unreachable;
457 if (self.test_filter) |filter| {458 if (self.test_filter) |filter| {
458 if (mem.indexOf(u8, annotated_case_name, filter) == null)459 if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
459 continue;
460 }460 }
461461
462 const exe = b.addExecutable("test", root_src);462 const exe = b.addExecutable("test", root_src);
...@@ -471,8 +471,7 @@ pub const CompareOutputContext = struct {...@@ -471,8 +471,7 @@ pub const CompareOutputContext = struct {
471 exe.step.dependOn(&write_src.step);471 exe.step.dependOn(&write_src.step);
472 }472 }
473473
474 const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(),474 const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), annotated_case_name, case.expected_output, case.cli_args);
475 annotated_case_name, case.expected_output, case.cli_args);
476 run_and_cmp_output.step.dependOn(&exe.step);475 run_and_cmp_output.step.dependOn(&exe.step);
477476
478 self.step.dependOn(&run_and_cmp_output.step);477 self.step.dependOn(&run_and_cmp_output.step);
...@@ -481,8 +480,7 @@ pub const CompareOutputContext = struct {...@@ -481,8 +480,7 @@ pub const CompareOutputContext = struct {
481 Special.RuntimeSafety => {480 Special.RuntimeSafety => {
482 const annotated_case_name = fmt.allocPrint(self.b.allocator, "safety {}", case.name) catch unreachable;481 const annotated_case_name = fmt.allocPrint(self.b.allocator, "safety {}", case.name) catch unreachable;
483 if (self.test_filter) |filter| {482 if (self.test_filter) |filter| {
484 if (mem.indexOf(u8, annotated_case_name, filter) == null)483 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
485 return;
486 }484 }
487485
488 const exe = b.addExecutable("test", root_src);486 const exe = b.addExecutable("test", root_src);
...@@ -524,7 +522,7 @@ pub const CompileErrorContext = struct {...@@ -524,7 +522,7 @@ pub const CompileErrorContext = struct {
524 };522 };
525523
526 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {524 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
527 self.sources.append(SourceFile {525 self.sources.append(SourceFile{
528 .filename = filename,526 .filename = filename,
529 .source = source,527 .source = source,
530 }) catch unreachable;528 }) catch unreachable;
...@@ -543,12 +541,10 @@ pub const CompileErrorContext = struct {...@@ -543,12 +541,10 @@ pub const CompileErrorContext = struct {
543 case: &const TestCase,541 case: &const TestCase,
544 build_mode: Mode,542 build_mode: Mode,
545543
546 pub fn create(context: &CompileErrorContext, name: []const u8,544 pub fn create(context: &CompileErrorContext, name: []const u8, case: &const TestCase, build_mode: Mode) &CompileCmpOutputStep {
547 case: &const TestCase, build_mode: Mode) &CompileCmpOutputStep
548 {
549 const allocator = context.b.allocator;545 const allocator = context.b.allocator;
550 const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;546 const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
551 *ptr = CompileCmpOutputStep {547 ptr.* = CompileCmpOutputStep{
552 .step = build.Step.init("CompileCmpOutput", allocator, make),548 .step = build.Step.init("CompileCmpOutput", allocator, make),
553 .context = context,549 .context = context,
554 .name = name,550 .name = name,
...@@ -586,7 +582,7 @@ pub const CompileErrorContext = struct {...@@ -586,7 +582,7 @@ pub const CompileErrorContext = struct {
586 Mode.ReleaseSmall => zig_args.append("--release-small") catch unreachable,582 Mode.ReleaseSmall => zig_args.append("--release-small") catch unreachable,
587 }583 }
588584
589 warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);585 warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
590586
591 if (b.verbose) {587 if (b.verbose) {
592 printInvocation(zig_args.toSliceConst());588 printInvocation(zig_args.toSliceConst());
...@@ -626,7 +622,6 @@ pub const CompileErrorContext = struct {...@@ -626,7 +622,6 @@ pub const CompileErrorContext = struct {
626 },622 },
627 }623 }
628624
629
630 const stdout = stdout_buf.toSliceConst();625 const stdout = stdout_buf.toSliceConst();
631 const stderr = stderr_buf.toSliceConst();626 const stderr = stderr_buf.toSliceConst();
632627
...@@ -666,11 +661,9 @@ pub const CompileErrorContext = struct {...@@ -666,11 +661,9 @@ pub const CompileErrorContext = struct {
666 warn("\n");661 warn("\n");
667 }662 }
668663
669 pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8,664 pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) &TestCase {
670 expected_lines: ...) &TestCase
671 {
672 const tc = self.b.allocator.create(TestCase) catch unreachable;665 const tc = self.b.allocator.create(TestCase) catch unreachable;
673 *tc = TestCase {666 tc.* = TestCase{
674 .name = name,667 .name = name,
675 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),668 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
676 .expected_errors = ArrayList([]const u8).init(self.b.allocator),669 .expected_errors = ArrayList([]const u8).init(self.b.allocator),
...@@ -705,12 +698,13 @@ pub const CompileErrorContext = struct {...@@ -705,12 +698,13 @@ pub const CompileErrorContext = struct {
705 pub fn addCase(self: &CompileErrorContext, case: &const TestCase) void {698 pub fn addCase(self: &CompileErrorContext, case: &const TestCase) void {
706 const b = self.b;699 const b = self.b;
707700
708 for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| {701 for ([]Mode{
709 const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {} ({})",702 Mode.Debug,
710 case.name, @tagName(mode)) catch unreachable;703 Mode.ReleaseFast,
704 }) |mode| {
705 const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {} ({})", case.name, @tagName(mode)) catch unreachable;
711 if (self.test_filter) |filter| {706 if (self.test_filter) |filter| {
712 if (mem.indexOf(u8, annotated_case_name, filter) == null)707 if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
713 continue;
714 }708 }
715709
716 const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, mode);710 const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, mode);
...@@ -744,8 +738,7 @@ pub const BuildExamplesContext = struct {...@@ -744,8 +738,7 @@ pub const BuildExamplesContext = struct {
744738
745 const annotated_case_name = b.fmt("build {} (Debug)", build_file);739 const annotated_case_name = b.fmt("build {} (Debug)", build_file);
746 if (self.test_filter) |filter| {740 if (self.test_filter) |filter| {
747 if (mem.indexOf(u8, annotated_case_name, filter) == null)741 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
748 return;
749 }742 }
750743
751 var zig_args = ArrayList([]const u8).init(b.allocator);744 var zig_args = ArrayList([]const u8).init(b.allocator);
...@@ -773,12 +766,15 @@ pub const BuildExamplesContext = struct {...@@ -773,12 +766,15 @@ pub const BuildExamplesContext = struct {
773 pub fn addAllArgs(self: &BuildExamplesContext, root_src: []const u8, link_libc: bool) void {766 pub fn addAllArgs(self: &BuildExamplesContext, root_src: []const u8, link_libc: bool) void {
774 const b = self.b;767 const b = self.b;
775768
776 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast, Mode.ReleaseSmall}) |mode| {769 for ([]Mode{
777 const annotated_case_name = fmt.allocPrint(self.b.allocator, "build {} ({})",770 Mode.Debug,
778 root_src, @tagName(mode)) catch unreachable;771 Mode.ReleaseSafe,
772 Mode.ReleaseFast,
773 Mode.ReleaseSmall,
774 }) |mode| {
775 const annotated_case_name = fmt.allocPrint(self.b.allocator, "build {} ({})", root_src, @tagName(mode)) catch unreachable;
779 if (self.test_filter) |filter| {776 if (self.test_filter) |filter| {
780 if (mem.indexOf(u8, annotated_case_name, filter) == null)777 if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
781 continue;
782 }778 }
783779
784 const exe = b.addExecutable("test", root_src);780 const exe = b.addExecutable("test", root_src);
...@@ -813,7 +809,7 @@ pub const TranslateCContext = struct {...@@ -813,7 +809,7 @@ pub const TranslateCContext = struct {
813 };809 };
814810
815 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {811 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
816 self.sources.append(SourceFile {812 self.sources.append(SourceFile{
817 .filename = filename,813 .filename = filename,
818 .source = source,814 .source = source,
819 }) catch unreachable;815 }) catch unreachable;
...@@ -834,7 +830,7 @@ pub const TranslateCContext = struct {...@@ -834,7 +830,7 @@ pub const TranslateCContext = struct {
834 pub fn create(context: &TranslateCContext, name: []const u8, case: &const TestCase) &TranslateCCmpOutputStep {830 pub fn create(context: &TranslateCContext, name: []const u8, case: &const TestCase) &TranslateCCmpOutputStep {
835 const allocator = context.b.allocator;831 const allocator = context.b.allocator;
836 const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;832 const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;
837 *ptr = TranslateCCmpOutputStep {833 ptr.* = TranslateCCmpOutputStep{
838 .step = build.Step.init("ParseCCmpOutput", allocator, make),834 .step = build.Step.init("ParseCCmpOutput", allocator, make),
839 .context = context,835 .context = context,
840 .name = name,836 .name = name,
...@@ -857,7 +853,7 @@ pub const TranslateCContext = struct {...@@ -857,7 +853,7 @@ pub const TranslateCContext = struct {
857 zig_args.append("translate-c") catch unreachable;853 zig_args.append("translate-c") catch unreachable;
858 zig_args.append(b.pathFromRoot(root_src)) catch unreachable;854 zig_args.append(b.pathFromRoot(root_src)) catch unreachable;
859855
860 warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);856 warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
861857
862 if (b.verbose) {858 if (b.verbose) {
863 printInvocation(zig_args.toSliceConst());859 printInvocation(zig_args.toSliceConst());
...@@ -939,11 +935,9 @@ pub const TranslateCContext = struct {...@@ -939,11 +935,9 @@ pub const TranslateCContext = struct {
939 warn("\n");935 warn("\n");
940 }936 }
941937
942 pub fn create(self: &TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8,938 pub fn create(self: &TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) &TestCase {
943 source: []const u8, expected_lines: ...) &TestCase
944 {
945 const tc = self.b.allocator.create(TestCase) catch unreachable;939 const tc = self.b.allocator.create(TestCase) catch unreachable;
946 *tc = TestCase {940 tc.* = TestCase{
947 .name = name,941 .name = name,
948 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),942 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
949 .expected_lines = ArrayList([]const u8).init(self.b.allocator),943 .expected_lines = ArrayList([]const u8).init(self.b.allocator),
...@@ -977,8 +971,7 @@ pub const TranslateCContext = struct {...@@ -977,8 +971,7 @@ pub const TranslateCContext = struct {
977971
978 const annotated_case_name = fmt.allocPrint(self.b.allocator, "translate-c {}", case.name) catch unreachable;972 const annotated_case_name = fmt.allocPrint(self.b.allocator, "translate-c {}", case.name) catch unreachable;
979 if (self.test_filter) |filter| {973 if (self.test_filter) |filter| {
980 if (mem.indexOf(u8, annotated_case_name, filter) == null)974 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
981 return;
982 }975 }
983976
984 const translate_c_and_cmp = TranslateCCmpOutputStep.create(self, annotated_case_name, case);977 const translate_c_and_cmp = TranslateCCmpOutputStep.create(self, annotated_case_name, case);
...@@ -1009,7 +1002,7 @@ pub const GenHContext = struct {...@@ -1009,7 +1002,7 @@ pub const GenHContext = struct {
1009 };1002 };
10101003
1011 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {1004 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
1012 self.sources.append(SourceFile {1005 self.sources.append(SourceFile{
1013 .filename = filename,1006 .filename = filename,
1014 .source = source,1007 .source = source,
1015 }) catch unreachable;1008 }) catch unreachable;
...@@ -1031,7 +1024,7 @@ pub const GenHContext = struct {...@@ -1031,7 +1024,7 @@ pub const GenHContext = struct {
1031 pub fn create(context: &GenHContext, h_path: []const u8, name: []const u8, case: &const TestCase) &GenHCmpOutputStep {1024 pub fn create(context: &GenHContext, h_path: []const u8, name: []const u8, case: &const TestCase) &GenHCmpOutputStep {
1032 const allocator = context.b.allocator;1025 const allocator = context.b.allocator;
1033 const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;1026 const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;
1034 *ptr = GenHCmpOutputStep {1027 ptr.* = GenHCmpOutputStep{
1035 .step = build.Step.init("ParseCCmpOutput", allocator, make),1028 .step = build.Step.init("ParseCCmpOutput", allocator, make),
1036 .context = context,1029 .context = context,
1037 .h_path = h_path,1030 .h_path = h_path,
...@@ -1047,7 +1040,7 @@ pub const GenHContext = struct {...@@ -1047,7 +1040,7 @@ pub const GenHContext = struct {
1047 const self = @fieldParentPtr(GenHCmpOutputStep, "step", step);1040 const self = @fieldParentPtr(GenHCmpOutputStep, "step", step);
1048 const b = self.context.b;1041 const b = self.context.b;
10491042
1050 warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);1043 warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
10511044
1052 const full_h_path = b.pathFromRoot(self.h_path);1045 const full_h_path = b.pathFromRoot(self.h_path);
1053 const actual_h = try io.readFileAlloc(b.allocator, full_h_path);1046 const actual_h = try io.readFileAlloc(b.allocator, full_h_path);
...@@ -1076,11 +1069,9 @@ pub const GenHContext = struct {...@@ -1076,11 +1069,9 @@ pub const GenHContext = struct {
1076 warn("\n");1069 warn("\n");
1077 }1070 }
10781071
1079 pub fn create(self: &GenHContext, filename: []const u8, name: []const u8,1072 pub fn create(self: &GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) &TestCase {
1080 source: []const u8, expected_lines: ...) &TestCase
1081 {
1082 const tc = self.b.allocator.create(TestCase) catch unreachable;1073 const tc = self.b.allocator.create(TestCase) catch unreachable;
1083 *tc = TestCase {1074 tc.* = TestCase{
1084 .name = name,1075 .name = name,
1085 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),1076 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
1086 .expected_lines = ArrayList([]const u8).init(self.b.allocator),1077 .expected_lines = ArrayList([]const u8).init(self.b.allocator),
...@@ -1105,8 +1096,7 @@ pub const GenHContext = struct {...@@ -1105,8 +1096,7 @@ pub const GenHContext = struct {
1105 const mode = builtin.Mode.Debug;1096 const mode = builtin.Mode.Debug;
1106 const annotated_case_name = fmt.allocPrint(self.b.allocator, "gen-h {} ({})", case.name, @tagName(mode)) catch unreachable;1097 const annotated_case_name = fmt.allocPrint(self.b.allocator, "gen-h {} ({})", case.name, @tagName(mode)) catch unreachable;
1107 if (self.test_filter) |filter| {1098 if (self.test_filter) |filter| {
1108 if (mem.indexOf(u8, annotated_case_name, filter) == null)1099 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
1109 return;
1110 }1100 }
11111101
1112 const obj = b.addObject("test", root_src);1102 const obj = b.addObject("test", root_src);
test/translate_c.zig+74-75
...@@ -638,7 +638,6 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -638,7 +638,6 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
638 \\}638 \\}
639 );639 );
640640
641
642 cases.addC("c style cast",641 cases.addC("c style cast",
643 \\int float_to_int(float a) {642 \\int float_to_int(float a) {
644 \\ return (int)a;643 \\ return (int)a;
...@@ -720,43 +719,43 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -720,43 +719,43 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
720 \\ var a: c_int = 0;719 \\ var a: c_int = 0;
721 \\ a += x: {720 \\ a += x: {
722 \\ const _ref = &a;721 \\ const _ref = &a;
723 \\ (*_ref) = ((*_ref) + 1);722 \\ _ref.* = (_ref.* + 1);
724 \\ break :x *_ref;723 \\ break :x _ref.*;
725 \\ };724 \\ };
726 \\ a -= x: {725 \\ a -= x: {
727 \\ const _ref = &a;726 \\ const _ref = &a;
728 \\ (*_ref) = ((*_ref) - 1);727 \\ _ref.* = (_ref.* - 1);
729 \\ break :x *_ref;728 \\ break :x _ref.*;
730 \\ };729 \\ };
731 \\ a *= x: {730 \\ a *= x: {
732 \\ const _ref = &a;731 \\ const _ref = &a;
733 \\ (*_ref) = ((*_ref) * 1);732 \\ _ref.* = (_ref.* * 1);
734 \\ break :x *_ref;733 \\ break :x _ref.*;
735 \\ };734 \\ };
736 \\ a &= x: {735 \\ a &= x: {
737 \\ const _ref = &a;736 \\ const _ref = &a;
738 \\ (*_ref) = ((*_ref) & 1);737 \\ _ref.* = (_ref.* & 1);
739 \\ break :x *_ref;738 \\ break :x _ref.*;
740 \\ };739 \\ };
741 \\ a |= x: {740 \\ a |= x: {
742 \\ const _ref = &a;741 \\ const _ref = &a;
743 \\ (*_ref) = ((*_ref) | 1);742 \\ _ref.* = (_ref.* | 1);
744 \\ break :x *_ref;743 \\ break :x _ref.*;
745 \\ };744 \\ };
746 \\ a ^= x: {745 \\ a ^= x: {
747 \\ const _ref = &a;746 \\ const _ref = &a;
748 \\ (*_ref) = ((*_ref) ^ 1);747 \\ _ref.* = (_ref.* ^ 1);
749 \\ break :x *_ref;748 \\ break :x _ref.*;
750 \\ };749 \\ };
751 \\ a >>= @import("std").math.Log2Int(c_int)(x: {750 \\ a >>= @import("std").math.Log2Int(c_int)(x: {
752 \\ const _ref = &a;751 \\ const _ref = &a;
753 \\ (*_ref) = ((*_ref) >> @import("std").math.Log2Int(c_int)(1));752 \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_int)(1));
754 \\ break :x *_ref;753 \\ break :x _ref.*;
755 \\ });754 \\ });
756 \\ a <<= @import("std").math.Log2Int(c_int)(x: {755 \\ a <<= @import("std").math.Log2Int(c_int)(x: {
757 \\ const _ref = &a;756 \\ const _ref = &a;
758 \\ (*_ref) = ((*_ref) << @import("std").math.Log2Int(c_int)(1));757 \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_int)(1));
759 \\ break :x *_ref;758 \\ break :x _ref.*;
760 \\ });759 \\ });
761 \\}760 \\}
762 );761 );
...@@ -778,43 +777,43 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -778,43 +777,43 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
778 \\ var a: c_uint = c_uint(0);777 \\ var a: c_uint = c_uint(0);
779 \\ a +%= x: {778 \\ a +%= x: {
780 \\ const _ref = &a;779 \\ const _ref = &a;
781 \\ (*_ref) = ((*_ref) +% c_uint(1));780 \\ _ref.* = (_ref.* +% c_uint(1));
782 \\ break :x *_ref;781 \\ break :x _ref.*;
783 \\ };782 \\ };
784 \\ a -%= x: {783 \\ a -%= x: {
785 \\ const _ref = &a;784 \\ const _ref = &a;
786 \\ (*_ref) = ((*_ref) -% c_uint(1));785 \\ _ref.* = (_ref.* -% c_uint(1));
787 \\ break :x *_ref;786 \\ break :x _ref.*;
788 \\ };787 \\ };
789 \\ a *%= x: {788 \\ a *%= x: {
790 \\ const _ref = &a;789 \\ const _ref = &a;
791 \\ (*_ref) = ((*_ref) *% c_uint(1));790 \\ _ref.* = (_ref.* *% c_uint(1));
792 \\ break :x *_ref;791 \\ break :x _ref.*;
793 \\ };792 \\ };
794 \\ a &= x: {793 \\ a &= x: {
795 \\ const _ref = &a;794 \\ const _ref = &a;
796 \\ (*_ref) = ((*_ref) & c_uint(1));795 \\ _ref.* = (_ref.* & c_uint(1));
797 \\ break :x *_ref;796 \\ break :x _ref.*;
798 \\ };797 \\ };
799 \\ a |= x: {798 \\ a |= x: {
800 \\ const _ref = &a;799 \\ const _ref = &a;
801 \\ (*_ref) = ((*_ref) | c_uint(1));800 \\ _ref.* = (_ref.* | c_uint(1));
802 \\ break :x *_ref;801 \\ break :x _ref.*;
803 \\ };802 \\ };
804 \\ a ^= x: {803 \\ a ^= x: {
805 \\ const _ref = &a;804 \\ const _ref = &a;
806 \\ (*_ref) = ((*_ref) ^ c_uint(1));805 \\ _ref.* = (_ref.* ^ c_uint(1));
807 \\ break :x *_ref;806 \\ break :x _ref.*;
808 \\ };807 \\ };
809 \\ a >>= @import("std").math.Log2Int(c_uint)(x: {808 \\ a >>= @import("std").math.Log2Int(c_uint)(x: {
810 \\ const _ref = &a;809 \\ const _ref = &a;
811 \\ (*_ref) = ((*_ref) >> @import("std").math.Log2Int(c_uint)(1));810 \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_uint)(1));
812 \\ break :x *_ref;811 \\ break :x _ref.*;
813 \\ });812 \\ });
814 \\ a <<= @import("std").math.Log2Int(c_uint)(x: {813 \\ a <<= @import("std").math.Log2Int(c_uint)(x: {
815 \\ const _ref = &a;814 \\ const _ref = &a;
816 \\ (*_ref) = ((*_ref) << @import("std").math.Log2Int(c_uint)(1));815 \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_uint)(1));
817 \\ break :x *_ref;816 \\ break :x _ref.*;
818 \\ });817 \\ });
819 \\}818 \\}
820 );819 );
...@@ -853,26 +852,26 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -853,26 +852,26 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
853 \\ u -%= 1;852 \\ u -%= 1;
854 \\ i = x: {853 \\ i = x: {
855 \\ const _ref = &i;854 \\ const _ref = &i;
856 \\ const _tmp = *_ref;855 \\ const _tmp = _ref.*;
857 \\ (*_ref) += 1;856 \\ _ref.* += 1;
858 \\ break :x _tmp;857 \\ break :x _tmp;
859 \\ };858 \\ };
860 \\ i = x: {859 \\ i = x: {
861 \\ const _ref = &i;860 \\ const _ref = &i;
862 \\ const _tmp = *_ref;861 \\ const _tmp = _ref.*;
863 \\ (*_ref) -= 1;862 \\ _ref.* -= 1;
864 \\ break :x _tmp;863 \\ break :x _tmp;
865 \\ };864 \\ };
866 \\ u = x: {865 \\ u = x: {
867 \\ const _ref = &u;866 \\ const _ref = &u;
868 \\ const _tmp = *_ref;867 \\ const _tmp = _ref.*;
869 \\ (*_ref) +%= 1;868 \\ _ref.* +%= 1;
870 \\ break :x _tmp;869 \\ break :x _tmp;
871 \\ };870 \\ };
872 \\ u = x: {871 \\ u = x: {
873 \\ const _ref = &u;872 \\ const _ref = &u;
874 \\ const _tmp = *_ref;873 \\ const _tmp = _ref.*;
875 \\ (*_ref) -%= 1;874 \\ _ref.* -%= 1;
876 \\ break :x _tmp;875 \\ break :x _tmp;
877 \\ };876 \\ };
878 \\}877 \\}
...@@ -901,23 +900,23 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -901,23 +900,23 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
901 \\ u -%= 1;900 \\ u -%= 1;
902 \\ i = x: {901 \\ i = x: {
903 \\ const _ref = &i;902 \\ const _ref = &i;
904 \\ (*_ref) += 1;903 \\ _ref.* += 1;
905 \\ break :x *_ref;904 \\ break :x _ref.*;
906 \\ };905 \\ };
907 \\ i = x: {906 \\ i = x: {
908 \\ const _ref = &i;907 \\ const _ref = &i;
909 \\ (*_ref) -= 1;908 \\ _ref.* -= 1;
910 \\ break :x *_ref;909 \\ break :x _ref.*;
911 \\ };910 \\ };
912 \\ u = x: {911 \\ u = x: {
913 \\ const _ref = &u;912 \\ const _ref = &u;
914 \\ (*_ref) +%= 1;913 \\ _ref.* +%= 1;
915 \\ break :x *_ref;914 \\ break :x _ref.*;
916 \\ };915 \\ };
917 \\ u = x: {916 \\ u = x: {
918 \\ const _ref = &u;917 \\ const _ref = &u;
919 \\ (*_ref) -%= 1;918 \\ _ref.* -%= 1;
920 \\ break :x *_ref;919 \\ break :x _ref.*;
921 \\ };920 \\ };
922 \\}921 \\}
923 );922 );
...@@ -985,7 +984,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -985,7 +984,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
985 \\}984 \\}
986 ,985 ,
987 \\pub export fn foo(x: ?&c_int) void {986 \\pub export fn foo(x: ?&c_int) void {
988 \\ (*??x) = 1;987 \\ (??x).* = 1;
989 \\}988 \\}
990 );989 );
991990
...@@ -1013,7 +1012,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -1013,7 +1012,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
1013 \\pub fn foo() c_int {1012 \\pub fn foo() c_int {
1014 \\ var x: c_int = 1234;1013 \\ var x: c_int = 1234;
1015 \\ var ptr: ?&c_int = &x;1014 \\ var ptr: ?&c_int = &x;
1016 \\ return *??ptr;1015 \\ return (??ptr).*;
1017 \\}1016 \\}
1018 );1017 );
10191018
...@@ -1289,29 +1288,29 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -1289,29 +1288,29 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
1289 \\ }1288 \\ }
1290 \\}1289 \\}
1291 ,1290 ,
1292 \\pub fn switch_fn(i: c_int) c_int {1291 \\pub fn switch_fn(i: c_int) c_int {
1293 \\ var res: c_int = 0;1292 \\ var res: c_int = 0;
1294 \\ __switch: {1293 \\ __switch: {
1295 \\ __case_2: {1294 \\ __case_2: {
1296 \\ __default: {1295 \\ __default: {
1297 \\ __case_1: {1296 \\ __case_1: {
1298 \\ __case_0: {1297 \\ __case_0: {
1299 \\ switch (i) {1298 \\ switch (i) {
1300 \\ 0 => break :__case_0,1299 \\ 0 => break :__case_0,
1301 \\ 1 => break :__case_1,1300 \\ 1 => break :__case_1,
1302 \\ else => break :__default,1301 \\ else => break :__default,
1303 \\ 2 => break :__case_2,1302 \\ 2 => break :__case_2,
1304 \\ }1303 \\ }
1305 \\ }1304 \\ }
1306 \\ res = 1;1305 \\ res = 1;
1307 \\ }1306 \\ }
1308 \\ res = 2;1307 \\ res = 2;
1309 \\ }1308 \\ }
1310 \\ res = (3 * i);1309 \\ res = (3 * i);
1311 \\ break :__switch;1310 \\ break :__switch;
1312 \\ }1311 \\ }
1313 \\ res = 5;1312 \\ res = 5;
1314 \\ }1313 \\ }
1315 \\}1314 \\}
1316 );1315 );
1317}1316}