aboutsummaryrefslogtreecommitdiff
path: root/std
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-05-29 03:22:52 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-05-29 03:22:52 -0400
commitcb042c8343eb94a8d149fe1f5d69aa2746aa85d0 (patch)
tree36b9711c480b61c372c86bc47dd20a635d624d3a /std
parent7fa97b752e167de6df9a8a76999456d2c199b345 (diff)
parenteda6898c5b253367174172db909ee23013f32733 (diff)
downloadzig-cb042c8343eb94a8d149fe1f5d69aa2746aa85d0.tar.gz
zig-cb042c8343eb94a8d149fe1f5d69aa2746aa85d0.zip
Merge remote-tracking branch 'origin/master' into llvm7
Diffstat (limited to 'std')
-rw-r--r--std/array_list.zig9
-rw-r--r--std/base64.zig117
-rw-r--r--std/buf_map.zig4
-rw-r--r--std/buf_set.zig4
-rw-r--r--std/build.zig59
-rw-r--r--std/c/darwin.zig2
-rw-r--r--std/c/index.zig12
-rw-r--r--std/crypto/md5.zig138
-rw-r--r--std/crypto/sha1.zig86
-rw-r--r--std/crypto/sha2.zig861
-rw-r--r--std/crypto/test.zig2
-rw-r--r--std/crypto/throughput_test.zig2
-rw-r--r--std/cstr.zig4
-rw-r--r--std/debug/failing_allocator.zig4
-rw-r--r--std/debug/index.zig18
-rw-r--r--std/dwarf.zig2
-rw-r--r--std/elf.zig42
-rw-r--r--std/event.zig13
-rw-r--r--std/fmt/errol/enum3.zig7
-rw-r--r--std/mem.zig8
-rw-r--r--std/zig/ast.zig26
-rw-r--r--std/zig/parse.zig8
-rw-r--r--std/zig/parser_test.zig457
-rw-r--r--std/zig/render.zig1424
-rw-r--r--std/zig/tokenizer.zig12
25 files changed, 2040 insertions, 1281 deletions
diff --git a/std/array_list.zig b/std/array_list.zig
index d1165c626d..679f7d73b8 100644
--- a/std/array_list.zig
+++ b/std/array_list.zig
@@ -150,7 +150,10 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
};
pub fn iterator(self: &const Self) Iterator {
- return Iterator { .list = self, .count = 0 };
+ return Iterator{
+ .list = self,
+ .count = 0,
+ };
}
};
}
@@ -207,7 +210,7 @@ test "iterator ArrayList test" {
try list.append(2);
try list.append(3);
- var count : i32 = 0;
+ var count: i32 = 0;
var it = list.iterator();
while (it.next()) |next| {
assert(next == count + 1);
@@ -225,7 +228,7 @@ test "iterator ArrayList test" {
}
it.reset();
- assert(?? it.next() == 1);
+ assert(??it.next() == 1);
}
test "insert ArrayList test" {
diff --git a/std/base64.zig b/std/base64.zig
index 13f3ea5714..515738a99e 100644
--- a/std/base64.zig
+++ b/std/base64.zig
@@ -41,12 +41,10 @@ pub const Base64Encoder = struct {
dest[out_index] = encoder.alphabet_chars[(source[i] >> 2) & 0x3f];
out_index += 1;
- dest[out_index] = encoder.alphabet_chars[((source[i] & 0x3) << 4) |
- ((source[i + 1] & 0xf0) >> 4)];
+ dest[out_index] = encoder.alphabet_chars[((source[i] & 0x3) << 4) | ((source[i + 1] & 0xf0) >> 4)];
out_index += 1;
- dest[out_index] = encoder.alphabet_chars[((source[i + 1] & 0xf) << 2) |
- ((source[i + 2] & 0xc0) >> 6)];
+ dest[out_index] = encoder.alphabet_chars[((source[i + 1] & 0xf) << 2) | ((source[i + 2] & 0xc0) >> 6)];
out_index += 1;
dest[out_index] = encoder.alphabet_chars[source[i + 2] & 0x3f];
@@ -64,8 +62,7 @@ pub const Base64Encoder = struct {
dest[out_index] = encoder.pad_char;
out_index += 1;
} else {
- dest[out_index] = encoder.alphabet_chars[((source[i] & 0x3) << 4) |
- ((source[i + 1] & 0xf0) >> 4)];
+ dest[out_index] = encoder.alphabet_chars[((source[i] & 0x3) << 4) | ((source[i + 1] & 0xf0) >> 4)];
out_index += 1;
dest[out_index] = encoder.alphabet_chars[(source[i + 1] & 0xf) << 2];
@@ -131,26 +128,20 @@ pub const Base64Decoder = struct {
// common case
if (!decoder.char_in_alphabet[source[src_cursor + 2]]) return error.InvalidCharacter;
if (!decoder.char_in_alphabet[source[src_cursor + 3]]) return error.InvalidCharacter;
- dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 |
- decoder.char_to_index[source[src_cursor + 1]] >> 4;
- dest[dest_cursor + 1] = decoder.char_to_index[source[src_cursor + 1]] << 4 |
- decoder.char_to_index[source[src_cursor + 2]] >> 2;
- dest[dest_cursor + 2] = decoder.char_to_index[source[src_cursor + 2]] << 6 |
- decoder.char_to_index[source[src_cursor + 3]];
+ dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 | decoder.char_to_index[source[src_cursor + 1]] >> 4;
+ dest[dest_cursor + 1] = decoder.char_to_index[source[src_cursor + 1]] << 4 | decoder.char_to_index[source[src_cursor + 2]] >> 2;
+ dest[dest_cursor + 2] = decoder.char_to_index[source[src_cursor + 2]] << 6 | decoder.char_to_index[source[src_cursor + 3]];
dest_cursor += 3;
} else if (source[src_cursor + 2] != decoder.pad_char) {
// one pad char
if (!decoder.char_in_alphabet[source[src_cursor + 2]]) return error.InvalidCharacter;
- dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 |
- decoder.char_to_index[source[src_cursor + 1]] >> 4;
- dest[dest_cursor + 1] = decoder.char_to_index[source[src_cursor + 1]] << 4 |
- decoder.char_to_index[source[src_cursor + 2]] >> 2;
+ dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 | decoder.char_to_index[source[src_cursor + 1]] >> 4;
+ dest[dest_cursor + 1] = decoder.char_to_index[source[src_cursor + 1]] << 4 | decoder.char_to_index[source[src_cursor + 2]] >> 2;
if (decoder.char_to_index[source[src_cursor + 2]] << 6 != 0) return error.InvalidPadding;
dest_cursor += 2;
} else {
// two pad chars
- dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 |
- decoder.char_to_index[source[src_cursor + 1]] >> 4;
+ dest[dest_cursor + 0] = decoder.char_to_index[source[src_cursor + 0]] << 2 | decoder.char_to_index[source[src_cursor + 1]] >> 4;
if (decoder.char_to_index[source[src_cursor + 1]] << 4 != 0) return error.InvalidPadding;
dest_cursor += 1;
}
@@ -165,7 +156,7 @@ pub const Base64DecoderWithIgnore = struct {
decoder: Base64Decoder,
char_is_ignored: [256]bool,
pub fn init(alphabet_chars: []const u8, pad_char: u8, ignore_chars: []const u8) Base64DecoderWithIgnore {
- var result = Base64DecoderWithIgnore {
+ var result = Base64DecoderWithIgnore{
.decoder = Base64Decoder.init(alphabet_chars, pad_char),
.char_is_ignored = []bool{false} ** 256,
};
@@ -223,10 +214,12 @@ pub const Base64DecoderWithIgnore = struct {
} else if (decoder_with_ignore.char_is_ignored[c]) {
// we can even ignore chars during the padding
continue;
- } else return error.InvalidCharacter;
+ } else
+ return error.InvalidCharacter;
}
break;
- } else return error.InvalidCharacter;
+ } else
+ return error.InvalidCharacter;
}
switch (available_chars) {
@@ -234,22 +227,17 @@ pub const Base64DecoderWithIgnore = struct {
// common case
if (dest_cursor + 3 > dest.len) return error.OutputTooSmall;
assert(pad_char_count == 0);
- dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 |
- decoder.char_to_index[next_4_chars[1]] >> 4;
- dest[dest_cursor + 1] = decoder.char_to_index[next_4_chars[1]] << 4 |
- decoder.char_to_index[next_4_chars[2]] >> 2;
- dest[dest_cursor + 2] = decoder.char_to_index[next_4_chars[2]] << 6 |
- decoder.char_to_index[next_4_chars[3]];
+ dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 | decoder.char_to_index[next_4_chars[1]] >> 4;
+ dest[dest_cursor + 1] = decoder.char_to_index[next_4_chars[1]] << 4 | decoder.char_to_index[next_4_chars[2]] >> 2;
+ dest[dest_cursor + 2] = decoder.char_to_index[next_4_chars[2]] << 6 | decoder.char_to_index[next_4_chars[3]];
dest_cursor += 3;
continue;
},
3 => {
if (dest_cursor + 2 > dest.len) return error.OutputTooSmall;
if (pad_char_count != 1) return error.InvalidPadding;
- dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 |
- decoder.char_to_index[next_4_chars[1]] >> 4;
- dest[dest_cursor + 1] = decoder.char_to_index[next_4_chars[1]] << 4 |
- decoder.char_to_index[next_4_chars[2]] >> 2;
+ dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 | decoder.char_to_index[next_4_chars[1]] >> 4;
+ dest[dest_cursor + 1] = decoder.char_to_index[next_4_chars[1]] << 4 | decoder.char_to_index[next_4_chars[2]] >> 2;
if (decoder.char_to_index[next_4_chars[2]] << 6 != 0) return error.InvalidPadding;
dest_cursor += 2;
break;
@@ -257,8 +245,7 @@ pub const Base64DecoderWithIgnore = struct {
2 => {
if (dest_cursor + 1 > dest.len) return error.OutputTooSmall;
if (pad_char_count != 2) return error.InvalidPadding;
- dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 |
- decoder.char_to_index[next_4_chars[1]] >> 4;
+ dest[dest_cursor + 0] = decoder.char_to_index[next_4_chars[0]] << 2 | decoder.char_to_index[next_4_chars[1]] >> 4;
if (decoder.char_to_index[next_4_chars[1]] << 4 != 0) return error.InvalidPadding;
dest_cursor += 1;
break;
@@ -280,7 +267,6 @@ pub const Base64DecoderWithIgnore = struct {
}
};
-
pub const standard_decoder_unsafe = Base64DecoderUnsafe.init(standard_alphabet_chars, standard_pad_char);
pub const Base64DecoderUnsafe = struct {
@@ -291,7 +277,7 @@ pub const Base64DecoderUnsafe = struct {
pub fn init(alphabet_chars: []const u8, pad_char: u8) Base64DecoderUnsafe {
assert(alphabet_chars.len == 64);
- var result = Base64DecoderUnsafe {
+ var result = Base64DecoderUnsafe{
.char_to_index = undefined,
.pad_char = pad_char,
};
@@ -321,16 +307,13 @@ pub const Base64DecoderUnsafe = struct {
}
while (in_buf_len > 4) {
- dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 |
- decoder.char_to_index[source[src_index + 1]] >> 4;
+ dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 | decoder.char_to_index[source[src_index + 1]] >> 4;
dest_index += 1;
- dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 |
- decoder.char_to_index[source[src_index + 2]] >> 2;
+ dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 | decoder.char_to_index[source[src_index + 2]] >> 2;
dest_index += 1;
- dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 |
- decoder.char_to_index[source[src_index + 3]];
+ dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 | decoder.char_to_index[source[src_index + 3]];
dest_index += 1;
src_index += 4;
@@ -338,18 +321,15 @@ pub const Base64DecoderUnsafe = struct {
}
if (in_buf_len > 1) {
- dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 |
- decoder.char_to_index[source[src_index + 1]] >> 4;
+ dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 | decoder.char_to_index[source[src_index + 1]] >> 4;
dest_index += 1;
}
if (in_buf_len > 2) {
- dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 |
- decoder.char_to_index[source[src_index + 2]] >> 2;
+ dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 | decoder.char_to_index[source[src_index + 2]] >> 2;
dest_index += 1;
}
if (in_buf_len > 3) {
- dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 |
- decoder.char_to_index[source[src_index + 3]];
+ dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 | decoder.char_to_index[source[src_index + 3]];
dest_index += 1;
}
}
@@ -367,7 +347,6 @@ fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) usize {
return result;
}
-
test "base64" {
@setEvalBranchQuota(8000);
testBase64() catch unreachable;
@@ -375,26 +354,26 @@ test "base64" {
}
fn testBase64() !void {
- try testAllApis("", "");
- try testAllApis("f", "Zg==");
- try testAllApis("fo", "Zm8=");
- try testAllApis("foo", "Zm9v");
- try testAllApis("foob", "Zm9vYg==");
- try testAllApis("fooba", "Zm9vYmE=");
+ try testAllApis("", "");
+ try testAllApis("f", "Zg==");
+ try testAllApis("fo", "Zm8=");
+ try testAllApis("foo", "Zm9v");
+ try testAllApis("foob", "Zm9vYg==");
+ try testAllApis("fooba", "Zm9vYmE=");
try testAllApis("foobar", "Zm9vYmFy");
- try testDecodeIgnoreSpace("", " ");
- try testDecodeIgnoreSpace("f", "Z g= =");
- try testDecodeIgnoreSpace("fo", " Zm8=");
- try testDecodeIgnoreSpace("foo", "Zm9v ");
- try testDecodeIgnoreSpace("foob", "Zm9vYg = = ");
- try testDecodeIgnoreSpace("fooba", "Zm9v YmE=");
+ try testDecodeIgnoreSpace("", " ");
+ try testDecodeIgnoreSpace("f", "Z g= =");
+ try testDecodeIgnoreSpace("fo", " Zm8=");
+ try testDecodeIgnoreSpace("foo", "Zm9v ");
+ try testDecodeIgnoreSpace("foob", "Zm9vYg = = ");
+ try testDecodeIgnoreSpace("fooba", "Zm9v YmE=");
try testDecodeIgnoreSpace("foobar", " Z m 9 v Y m F y ");
// test getting some api errors
- try testError("A", error.InvalidPadding);
- try testError("AA", error.InvalidPadding);
- try testError("AAA", error.InvalidPadding);
+ try testError("A", error.InvalidPadding);
+ try testError("AA", error.InvalidPadding);
+ try testError("AAA", error.InvalidPadding);
try testError("A..A", error.InvalidCharacter);
try testError("AA=A", error.InvalidCharacter);
try testError("AA/=", error.InvalidPadding);
@@ -427,8 +406,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void
// Base64DecoderWithIgnore
{
- const standard_decoder_ignore_nothing = Base64DecoderWithIgnore.init(
- standard_alphabet_chars, standard_pad_char, "");
+ const standard_decoder_ignore_nothing = Base64DecoderWithIgnore.init(standard_alphabet_chars, standard_pad_char, "");
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)];
var written = try standard_decoder_ignore_nothing.decode(decoded, expected_encoded);
@@ -446,8 +424,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void
}
fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) !void {
- const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
- standard_alphabet_chars, standard_pad_char, " ");
+ const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)];
var written = try standard_decoder_ignore_space.decode(decoded, encoded);
@@ -455,8 +432,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) !voi
}
fn testError(encoded: []const u8, expected_err: error) !void {
- const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
- standard_alphabet_chars, standard_pad_char, " ");
+ const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;
if (standard_decoder.calcSize(encoded)) |decoded_size| {
var decoded = buffer[0..decoded_size];
@@ -471,8 +447,7 @@ fn testError(encoded: []const u8, expected_err: error) !void {
}
fn testOutputTooSmallError(encoded: []const u8) !void {
- const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
- standard_alphabet_chars, standard_pad_char, " ");
+ const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..calcDecodedSizeExactUnsafe(encoded, standard_pad_char) - 1];
if (standard_decoder_ignore_space.decode(decoded, encoded)) |_| {
diff --git a/std/buf_map.zig b/std/buf_map.zig
index 57c5830bbe..930fc36a78 100644
--- a/std/buf_map.zig
+++ b/std/buf_map.zig
@@ -12,9 +12,7 @@ pub const BufMap = struct {
const BufMapHashMap = HashMap([]const u8, []const u8, mem.hash_slice_u8, mem.eql_slice_u8);
pub fn init(allocator: &Allocator) BufMap {
- var self = BufMap {
- .hash_map = BufMapHashMap.init(allocator),
- };
+ var self = BufMap{ .hash_map = BufMapHashMap.init(allocator) };
return self;
}
diff --git a/std/buf_set.zig b/std/buf_set.zig
index 1badb5bf18..c5a80e16fb 100644
--- a/std/buf_set.zig
+++ b/std/buf_set.zig
@@ -10,9 +10,7 @@ pub const BufSet = struct {
const BufSetHashMap = HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);
pub fn init(a: &Allocator) BufSet {
- var self = BufSet {
- .hash_map = BufSetHashMap.init(a),
- };
+ var self = BufSet{ .hash_map = BufSetHashMap.init(a) };
return self;
}
diff --git a/std/build.zig b/std/build.zig
index 276176c63c..f86c3d394f 100644
--- a/std/build.zig
+++ b/std/build.zig
@@ -420,15 +420,7 @@ pub const Builder = struct {
const release_fast = self.option(bool, "release-fast", "optimizations on and safety off") ?? false;
const release_small = self.option(bool, "release-small", "size optimizations on and safety off") ?? false;
- 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: {
+ 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: {
warn("Multiple release modes (of -Drelease-safe, -Drelease-fast and -Drelease-small)");
self.markInvalidUserInput();
break :x builtin.Mode.Debug;
@@ -649,11 +641,7 @@ pub const Builder = struct {
if (builtin.environ == builtin.Environ.msvc) {
return "cl.exe";
} else {
- return os.getEnvVarOwned(self.allocator, "CC") catch |err|
- if (err == error.EnvironmentVariableNotFound)
- ([]const u8)("cc")
- else
- debug.panic("Unable to get environment variable: {}", err);
+ return os.getEnvVarOwned(self.allocator, "CC") catch |err| if (err == error.EnvironmentVariableNotFound) ([]const u8)("cc") else debug.panic("Unable to get environment variable: {}", err);
}
}
@@ -782,8 +770,7 @@ pub const Target = union(enum) {
pub fn isDarwin(self: &const Target) bool {
return switch (self.getOs()) {
- builtin.Os.ios,
- builtin.Os.macosx => true,
+ builtin.Os.ios, builtin.Os.macosx => true,
else => false,
};
}
@@ -990,8 +977,7 @@ pub const LibExeObjStep = struct {
self.out_filename = self.builder.fmt("lib{}.a", self.name);
} else {
switch (self.target.getOs()) {
- builtin.Os.ios,
- builtin.Os.macosx => {
+ builtin.Os.ios, builtin.Os.macosx => {
self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", self.name, self.version.major, self.version.minor, self.version.patch);
self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major);
self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
@@ -1011,11 +997,13 @@ pub const LibExeObjStep = struct {
}
pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os, target_environ: builtin.Environ) void {
- self.target = Target{ .Cross = CrossTarget{
- .arch = target_arch,
- .os = target_os,
- .environ = target_environ,
- } };
+ self.target = Target{
+ .Cross = CrossTarget{
+ .arch = target_arch,
+ .os = target_os,
+ .environ = target_environ,
+ },
+ };
self.computeOutFileNames();
}
@@ -1079,10 +1067,7 @@ pub const LibExeObjStep = struct {
}
pub fn getOutputPath(self: &LibExeObjStep) []const u8 {
- 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;
+ 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;
}
pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) void {
@@ -1095,10 +1080,7 @@ pub const LibExeObjStep = struct {
}
pub fn getOutputHPath(self: &LibExeObjStep) []const u8 {
- 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;
+ 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;
}
pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) void {
@@ -1352,8 +1334,7 @@ pub const LibExeObjStep = struct {
args.append("ssp-buffer-size=4") catch unreachable;
}
},
- builtin.Mode.ReleaseFast,
- builtin.Mode.ReleaseSmall => {
+ builtin.Mode.ReleaseFast, builtin.Mode.ReleaseSmall => {
args.append("-O2") catch unreachable;
args.append("-fno-stack-protector") catch unreachable;
},
@@ -1652,11 +1633,13 @@ pub const TestStep = struct {
}
pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os, target_environ: builtin.Environ) void {
- self.target = Target{ .Cross = CrossTarget{
- .arch = target_arch,
- .os = target_os,
- .environ = target_environ,
- } };
+ self.target = Target{
+ .Cross = CrossTarget{
+ .arch = target_arch,
+ .os = target_os,
+ .environ = target_environ,
+ },
+ };
}
pub fn setExecCmd(self: &TestStep, args: []const ?[]const u8) void {
diff --git a/std/c/darwin.zig b/std/c/darwin.zig
index 7ac57514c9..24be832d01 100644
--- a/std/c/darwin.zig
+++ b/std/c/darwin.zig
@@ -60,7 +60,7 @@ pub const sigset_t = u32;
/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
pub const Sigaction = extern struct {
- handler: extern fn(c_int)void,
+ handler: extern fn(c_int) void,
sa_mask: sigset_t,
sa_flags: c_int,
};
diff --git a/std/c/index.zig b/std/c/index.zig
index 34269d2aa2..b5e6b48751 100644
--- a/std/c/index.zig
+++ b/std/c/index.zig
@@ -1,7 +1,7 @@
const builtin = @import("builtin");
const Os = builtin.Os;
-pub use switch(builtin.os) {
+pub use switch (builtin.os) {
Os.linux => @import("linux.zig"),
Os.windows => @import("windows.zig"),
Os.macosx, Os.ios => @import("darwin.zig"),
@@ -21,8 +21,7 @@ pub extern "c" fn raise(sig: c_int) c_int;
pub extern "c" fn read(fd: c_int, buf: &c_void, nbyte: usize) isize;
pub extern "c" fn stat(noalias path: &const u8, noalias buf: &Stat) c_int;
pub extern "c" fn write(fd: c_int, buf: &const c_void, nbyte: usize) isize;
-pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int,
- fd: c_int, offset: isize) ?&c_void;
+pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int, fd: c_int, offset: isize) ?&c_void;
pub extern "c" fn munmap(addr: &c_void, len: usize) c_int;
pub extern "c" fn unlink(path: &const u8) c_int;
pub 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;
pub extern "c" fn symlink(existing: &const u8, new: &const u8) c_int;
pub extern "c" fn rename(old: &const u8, new: &const u8) c_int;
pub extern "c" fn chdir(path: &const u8) c_int;
-pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8,
- envp: &const ?&const u8) c_int;
+pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) c_int;
pub extern "c" fn dup(fd: c_int) c_int;
pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) c_int;
pub 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;
pub extern "c" fn free(&c_void) void;
pub extern "c" fn posix_memalign(memptr: &&c_void, alignment: usize, size: usize) c_int;
-pub 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;
+pub 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;
pub extern "pthread" fn pthread_attr_init(attr: &pthread_attr_t) c_int;
pub extern "pthread" fn pthread_attr_setstack(attr: &pthread_attr_t, stackaddr: &c_void, stacksize: usize) c_int;
pub extern "pthread" fn pthread_attr_destroy(attr: &pthread_attr_t) c_int;
diff --git a/std/crypto/md5.zig b/std/crypto/md5.zig
index 705b2428a7..e0473884cd 100644
--- a/std/crypto/md5.zig
+++ b/std/crypto/md5.zig
@@ -6,12 +6,25 @@ const debug = @import("../debug/index.zig");
const fmt = @import("../fmt/index.zig");
const RoundParam = struct {
- a: usize, b: usize, c: usize, d: usize,
- k: usize, s: u32, t: u32
+ a: usize,
+ b: usize,
+ c: usize,
+ d: usize,
+ k: usize,
+ s: u32,
+ t: u32,
};
fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundParam {
- return RoundParam { .a = a, .b = b, .c = c, .d = d, .k = k, .s = s, .t = t };
+ return RoundParam{
+ .a = a,
+ .b = b,
+ .c = c,
+ .d = d,
+ .k = k,
+ .s = s,
+ .t = t,
+ };
}
pub const Md5 = struct {
@@ -99,7 +112,7 @@ pub const Md5 = struct {
d.round(d.buf[0..]);
for (d.s) |s, j| {
- mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Little);
+ mem.writeInt(out[4 * j..4 * j + 4], s, builtin.Endian.Little);
}
}
@@ -112,30 +125,33 @@ pub const Md5 = struct {
while (i < 16) : (i += 1) {
// NOTE: Performing or's separately improves perf by ~10%
s[i] = 0;
- s[i] |= u32(b[i*4+0]);
- s[i] |= u32(b[i*4+1]) << 8;
- s[i] |= u32(b[i*4+2]) << 16;
- s[i] |= u32(b[i*4+3]) << 24;
+ s[i] |= u32(b[i * 4 + 0]);
+ s[i] |= u32(b[i * 4 + 1]) << 8;
+ s[i] |= u32(b[i * 4 + 2]) << 16;
+ s[i] |= u32(b[i * 4 + 3]) << 24;
}
- var v: [4]u32 = []u32 {
- d.s[0], d.s[1], d.s[2], d.s[3],
+ var v: [4]u32 = []u32{
+ d.s[0],
+ d.s[1],
+ d.s[2],
+ d.s[3],
};
- const round0 = comptime []RoundParam {
- Rp(0, 1, 2, 3, 0, 7, 0xD76AA478),
- Rp(3, 0, 1, 2, 1, 12, 0xE8C7B756),
- Rp(2, 3, 0, 1, 2, 17, 0x242070DB),
- Rp(1, 2, 3, 0, 3, 22, 0xC1BDCEEE),
- Rp(0, 1, 2, 3, 4, 7, 0xF57C0FAF),
- Rp(3, 0, 1, 2, 5, 12, 0x4787C62A),
- Rp(2, 3, 0, 1, 6, 17, 0xA8304613),
- Rp(1, 2, 3, 0, 7, 22, 0xFD469501),
- Rp(0, 1, 2, 3, 8, 7, 0x698098D8),
- Rp(3, 0, 1, 2, 9, 12, 0x8B44F7AF),
+ const round0 = comptime []RoundParam{
+ Rp(0, 1, 2, 3, 0, 7, 0xD76AA478),
+ Rp(3, 0, 1, 2, 1, 12, 0xE8C7B756),
+ Rp(2, 3, 0, 1, 2, 17, 0x242070DB),
+ Rp(1, 2, 3, 0, 3, 22, 0xC1BDCEEE),
+ Rp(0, 1, 2, 3, 4, 7, 0xF57C0FAF),
+ Rp(3, 0, 1, 2, 5, 12, 0x4787C62A),
+ Rp(2, 3, 0, 1, 6, 17, 0xA8304613),
+ Rp(1, 2, 3, 0, 7, 22, 0xFD469501),
+ Rp(0, 1, 2, 3, 8, 7, 0x698098D8),
+ Rp(3, 0, 1, 2, 9, 12, 0x8B44F7AF),
Rp(2, 3, 0, 1, 10, 17, 0xFFFF5BB1),
Rp(1, 2, 3, 0, 11, 22, 0x895CD7BE),
- Rp(0, 1, 2, 3, 12, 7, 0x6B901122),
+ Rp(0, 1, 2, 3, 12, 7, 0x6B901122),
Rp(3, 0, 1, 2, 13, 12, 0xFD987193),
Rp(2, 3, 0, 1, 14, 17, 0xA679438E),
Rp(1, 2, 3, 0, 15, 22, 0x49B40821),
@@ -145,22 +161,22 @@ pub const Md5 = struct {
v[r.a] = v[r.b] +% math.rotl(u32, v[r.a], r.s);
}
- const round1 = comptime []RoundParam {
- Rp(0, 1, 2, 3, 1, 5, 0xF61E2562),
- Rp(3, 0, 1, 2, 6, 9, 0xC040B340),
+ const round1 = comptime []RoundParam{
+ Rp(0, 1, 2, 3, 1, 5, 0xF61E2562),
+ Rp(3, 0, 1, 2, 6, 9, 0xC040B340),
Rp(2, 3, 0, 1, 11, 14, 0x265E5A51),
- Rp(1, 2, 3, 0, 0, 20, 0xE9B6C7AA),
- Rp(0, 1, 2, 3, 5, 5, 0xD62F105D),
- Rp(3, 0, 1, 2, 10, 9, 0x02441453),
+ Rp(1, 2, 3, 0, 0, 20, 0xE9B6C7AA),
+ Rp(0, 1, 2, 3, 5, 5, 0xD62F105D),
+ Rp(3, 0, 1, 2, 10, 9, 0x02441453),
Rp(2, 3, 0, 1, 15, 14, 0xD8A1E681),
- Rp(1, 2, 3, 0, 4, 20, 0xE7D3FBC8),
- Rp(0, 1, 2, 3, 9, 5, 0x21E1CDE6),
- Rp(3, 0, 1, 2, 14, 9, 0xC33707D6),
- Rp(2, 3, 0, 1, 3, 14, 0xF4D50D87),
- Rp(1, 2, 3, 0, 8, 20, 0x455A14ED),
- Rp(0, 1, 2, 3, 13, 5, 0xA9E3E905),
- Rp(3, 0, 1, 2, 2, 9, 0xFCEFA3F8),
- Rp(2, 3, 0, 1, 7, 14, 0x676F02D9),
+ Rp(1, 2, 3, 0, 4, 20, 0xE7D3FBC8),
+ Rp(0, 1, 2, 3, 9, 5, 0x21E1CDE6),
+ Rp(3, 0, 1, 2, 14, 9, 0xC33707D6),
+ Rp(2, 3, 0, 1, 3, 14, 0xF4D50D87),
+ Rp(1, 2, 3, 0, 8, 20, 0x455A14ED),
+ Rp(0, 1, 2, 3, 13, 5, 0xA9E3E905),
+ Rp(3, 0, 1, 2, 2, 9, 0xFCEFA3F8),
+ Rp(2, 3, 0, 1, 7, 14, 0x676F02D9),
Rp(1, 2, 3, 0, 12, 20, 0x8D2A4C8A),
};
inline for (round1) |r| {
@@ -168,46 +184,46 @@ pub const Md5 = struct {
v[r.a] = v[r.b] +% math.rotl(u32, v[r.a], r.s);
}
- const round2 = comptime []RoundParam {
- Rp(0, 1, 2, 3, 5, 4, 0xFFFA3942),
- Rp(3, 0, 1, 2, 8, 11, 0x8771F681),
+ const round2 = comptime []RoundParam{
+ Rp(0, 1, 2, 3, 5, 4, 0xFFFA3942),
+ Rp(3, 0, 1, 2, 8, 11, 0x8771F681),
Rp(2, 3, 0, 1, 11, 16, 0x6D9D6122),
Rp(1, 2, 3, 0, 14, 23, 0xFDE5380C),
- Rp(0, 1, 2, 3, 1, 4, 0xA4BEEA44),
- Rp(3, 0, 1, 2, 4, 11, 0x4BDECFA9),
- Rp(2, 3, 0, 1, 7, 16, 0xF6BB4B60),
+ Rp(0, 1, 2, 3, 1, 4, 0xA4BEEA44),
+ Rp(3, 0, 1, 2, 4, 11, 0x4BDECFA9),
+ Rp(2, 3, 0, 1, 7, 16, 0xF6BB4B60),
Rp(1, 2, 3, 0, 10, 23, 0xBEBFBC70),
- Rp(0, 1, 2, 3, 13, 4, 0x289B7EC6),
- Rp(3, 0, 1, 2, 0, 11, 0xEAA127FA),
- Rp(2, 3, 0, 1, 3, 16, 0xD4EF3085),
- Rp(1, 2, 3, 0, 6, 23, 0x04881D05),
- Rp(0, 1, 2, 3, 9, 4, 0xD9D4D039),
+ Rp(0, 1, 2, 3, 13, 4, 0x289B7EC6),
+ Rp(3, 0, 1, 2, 0, 11, 0xEAA127FA),
+ Rp(2, 3, 0, 1, 3, 16, 0xD4EF3085),
+ Rp(1, 2, 3, 0, 6, 23, 0x04881D05),
+ Rp(0, 1, 2, 3, 9, 4, 0xD9D4D039),
Rp(3, 0, 1, 2, 12, 11, 0xE6DB99E5),
Rp(2, 3, 0, 1, 15, 16, 0x1FA27CF8),
- Rp(1, 2, 3, 0, 2, 23, 0xC4AC5665),
+ Rp(1, 2, 3, 0, 2, 23, 0xC4AC5665),
};
inline for (round2) |r| {
v[r.a] = v[r.a] +% (v[r.b] ^ v[r.c] ^ v[r.d]) +% r.t +% s[r.k];
v[r.a] = v[r.b] +% math.rotl(u32, v[r.a], r.s);
}
- const round3 = comptime []RoundParam {
- Rp(0, 1, 2, 3, 0, 6, 0xF4292244),
- Rp(3, 0, 1, 2, 7, 10, 0x432AFF97),
+ const round3 = comptime []RoundParam{
+ Rp(0, 1, 2, 3, 0, 6, 0xF4292244),
+ Rp(3, 0, 1, 2, 7, 10, 0x432AFF97),
Rp(2, 3, 0, 1, 14, 15, 0xAB9423A7),
- Rp(1, 2, 3, 0, 5, 21, 0xFC93A039),
- Rp(0, 1, 2, 3, 12, 6, 0x655B59C3),
- Rp(3, 0, 1, 2, 3, 10, 0x8F0CCC92),
+ Rp(1, 2, 3, 0, 5, 21, 0xFC93A039),
+ Rp(0, 1, 2, 3, 12, 6, 0x655B59C3),
+ Rp(3, 0, 1, 2, 3, 10, 0x8F0CCC92),
Rp(2, 3, 0, 1, 10, 15, 0xFFEFF47D),
- Rp(1, 2, 3, 0, 1, 21, 0x85845DD1),
- Rp(0, 1, 2, 3, 8, 6, 0x6FA87E4F),
+ Rp(1, 2, 3, 0, 1, 21, 0x85845DD1),
+ Rp(0, 1, 2, 3, 8, 6, 0x6FA87E4F),
Rp(3, 0, 1, 2, 15, 10, 0xFE2CE6E0),
- Rp(2, 3, 0, 1, 6, 15, 0xA3014314),
+ Rp(2, 3, 0, 1, 6, 15, 0xA3014314),
Rp(1, 2, 3, 0, 13, 21, 0x4E0811A1),
- Rp(0, 1, 2, 3, 4, 6, 0xF7537E82),
+ Rp(0, 1, 2, 3, 4, 6, 0xF7537E82),
Rp(3, 0, 1, 2, 11, 10, 0xBD3AF235),
- Rp(2, 3, 0, 1, 2, 15, 0x2AD7D2BB),
- Rp(1, 2, 3, 0, 9, 21, 0xEB86D391),
+ Rp(2, 3, 0, 1, 2, 15, 0x2AD7D2BB),
+ Rp(1, 2, 3, 0, 9, 21, 0xEB86D391),
};
inline for (round3) |r| {
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" {
}
test "md5 aligned final" {
- var block = []u8 {0} ** Md5.block_size;
+ var block = []u8{0} ** Md5.block_size;
var out: [Md5.digest_size]u8 = undefined;
var h = Md5.init();
diff --git a/std/crypto/sha1.zig b/std/crypto/sha1.zig
index 333597b12d..77324b482f 100644
--- a/std/crypto/sha1.zig
+++ b/std/crypto/sha1.zig
@@ -7,11 +7,23 @@ const builtin = @import("builtin");
pub const u160 = @IntType(false, 160);
const RoundParam = struct {
- a: usize, b: usize, c: usize, d: usize, e: usize, i: u32,
+ a: usize,
+ b: usize,
+ c: usize,
+ d: usize,
+ e: usize,
+ i: u32,
};
fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam {
- return RoundParam { .a = a, .b = b, .c = c, .d = d, .e = e, .i = i };
+ return RoundParam{
+ .a = a,
+ .b = b,
+ .c = c,
+ .d = d,
+ .e = e,
+ .i = i,
+ };
}
pub const Sha1 = struct {
@@ -99,7 +111,7 @@ pub const Sha1 = struct {
d.round(d.buf[0..]);
for (d.s) |s, j| {
- mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Big);
+ mem.writeInt(out[4 * j..4 * j + 4], s, builtin.Endian.Big);
}
}
@@ -108,21 +120,25 @@ pub const Sha1 = struct {
var s: [16]u32 = undefined;
- var v: [5]u32 = []u32 {
- d.s[0], d.s[1], d.s[2], d.s[3], d.s[4],
+ var v: [5]u32 = []u32{
+ d.s[0],
+ d.s[1],
+ d.s[2],
+ d.s[3],
+ d.s[4],
};
- const round0a = comptime []RoundParam {
- Rp(0, 1, 2, 3, 4, 0),
- Rp(4, 0, 1, 2, 3, 1),
- Rp(3, 4, 0, 1, 2, 2),
- Rp(2, 3, 4, 0, 1, 3),
- Rp(1, 2, 3, 4, 0, 4),
- Rp(0, 1, 2, 3, 4, 5),
- Rp(4, 0, 1, 2, 3, 6),
- Rp(3, 4, 0, 1, 2, 7),
- Rp(2, 3, 4, 0, 1, 8),
- Rp(1, 2, 3, 4, 0, 9),
+ const round0a = comptime []RoundParam{
+ Rp(0, 1, 2, 3, 4, 0),
+ Rp(4, 0, 1, 2, 3, 1),
+ Rp(3, 4, 0, 1, 2, 2),
+ Rp(2, 3, 4, 0, 1, 3),
+ Rp(1, 2, 3, 4, 0, 4),
+ Rp(0, 1, 2, 3, 4, 5),
+ Rp(4, 0, 1, 2, 3, 6),
+ Rp(3, 4, 0, 1, 2, 7),
+ Rp(2, 3, 4, 0, 1, 8),
+ Rp(1, 2, 3, 4, 0, 9),
Rp(0, 1, 2, 3, 4, 10),
Rp(4, 0, 1, 2, 3, 11),
Rp(3, 4, 0, 1, 2, 12),
@@ -131,32 +147,27 @@ pub const Sha1 = struct {
Rp(0, 1, 2, 3, 4, 15),
};
inline for (round0a) |r| {
- 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);
+ 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);
- 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]));
+ 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]));
v[r.b] = math.rotl(u32, v[r.b], u32(30));
}
- const round0b = comptime []RoundParam {
+ const round0b = comptime []RoundParam{
Rp(4, 0, 1, 2, 3, 16),
Rp(3, 4, 0, 1, 2, 17),
Rp(2, 3, 4, 0, 1, 18),
Rp(1, 2, 3, 4, 0, 19),
};
inline for (round0b) |r| {
- const t = s[(r.i-3) & 0xf] ^ s[(r.i-8) & 0xf] ^ s[(r.i-14) & 0xf] ^ s[(r.i-16) & 0xf];
+ const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
s[r.i & 0xf] = math.rotl(u32, t, u32(1));
- 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]));
+ 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]));
v[r.b] = math.rotl(u32, v[r.b], u32(30));
}
- const round1 = comptime []RoundParam {
+ const round1 = comptime []RoundParam{
Rp(0, 1, 2, 3, 4, 20),
Rp(4, 0, 1, 2, 3, 21),
Rp(3, 4, 0, 1, 2, 22),
@@ -179,15 +190,14 @@ pub const Sha1 = struct {
Rp(1, 2, 3, 4, 0, 39),
};
inline for (round1) |r| {
- const t = s[(r.i-3) & 0xf] ^ s[(r.i-8) & 0xf] ^ s[(r.i-14) & 0xf] ^ s[(r.i-16) & 0xf];
+ const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
s[r.i & 0xf] = math.rotl(u32, t, u32(1));
- 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]);
+ 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]);
v[r.b] = math.rotl(u32, v[r.b], u32(30));
}
- const round2 = comptime []RoundParam {
+ const round2 = comptime []RoundParam{
Rp(0, 1, 2, 3, 4, 40),
Rp(4, 0, 1, 2, 3, 41),
Rp(3, 4, 0, 1, 2, 42),
@@ -210,15 +220,14 @@ pub const Sha1 = struct {
Rp(1, 2, 3, 4, 0, 59),
};
inline for (round2) |r| {
- const t = s[(r.i-3) & 0xf] ^ s[(r.i-8) & 0xf] ^ s[(r.i-14) & 0xf] ^ s[(r.i-16) & 0xf];
+ const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
s[r.i & 0xf] = math.rotl(u32, t, u32(1));
- 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]));
+ 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]));
v[r.b] = math.rotl(u32, v[r.b], u32(30));
}
- const round3 = comptime []RoundParam {
+ const round3 = comptime []RoundParam{
Rp(0, 1, 2, 3, 4, 60),
Rp(4, 0, 1, 2, 3, 61),
Rp(3, 4, 0, 1, 2, 62),
@@ -241,11 +250,10 @@ pub const Sha1 = struct {
Rp(1, 2, 3, 4, 0, 79),
};
inline for (round3) |r| {
- const t = s[(r.i-3) & 0xf] ^ s[(r.i-8) & 0xf] ^ s[(r.i-14) & 0xf] ^ s[(r.i-16) & 0xf];
+ const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
s[r.i & 0xf] = math.rotl(u32, t, u32(1));
- 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]);
+ 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]);
v[r.b] = math.rotl(u32, v[r.b], u32(30));
}
@@ -286,7 +294,7 @@ test "sha1 streaming" {
}
test "sha1 aligned final" {
- var block = []u8 {0} ** Sha1.block_size;
+ var block = []u8{0} ** Sha1.block_size;
var out: [Sha1.digest_size]u8 = undefined;
var h = Sha1.init();
diff --git a/std/crypto/sha2.zig b/std/crypto/sha2.zig
index b70450c0ad..a55182aacd 100644
--- a/std/crypto/sha2.zig
+++ b/std/crypto/sha2.zig
@@ -9,12 +9,31 @@ const htest = @import("test.zig");
// Sha224 + Sha256
const RoundParam256 = struct {
- a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize,
- i: usize, k: u32,
+ a: usize,
+ b: usize,
+ c: usize,
+ d: usize,
+ e: usize,
+ f: usize,
+ g: usize,
+ h: usize,
+ i: usize,
+ k: u32,
};
fn Rp256(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u32) RoundParam256 {
- return RoundParam256 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };
+ return RoundParam256{
+ .a = a,
+ .b = b,
+ .c = c,
+ .d = d,
+ .e = e,
+ .f = f,
+ .g = g,
+ .h = h,
+ .i = i,
+ .k = k,
+ };
}
const Sha2Params32 = struct {
@@ -29,7 +48,7 @@ const Sha2Params32 = struct {
out_len: usize,
};
-const Sha224Params = Sha2Params32 {
+const Sha224Params = Sha2Params32{
.iv0 = 0xC1059ED8,
.iv1 = 0x367CD507,
.iv2 = 0x3070DD17,
@@ -41,7 +60,7 @@ const Sha224Params = Sha2Params32 {
.out_len = 224,
};
-const Sha256Params = Sha2Params32 {
+const Sha256Params = Sha2Params32{
.iv0 = 0x6A09E667,
.iv1 = 0xBB67AE85,
.iv2 = 0x3C6EF372,
@@ -56,216 +75,215 @@ const Sha256Params = Sha2Params32 {
pub const Sha224 = Sha2_32(Sha224Params);
pub const Sha256 = Sha2_32(Sha256Params);
-fn Sha2_32(comptime params: Sha2Params32) type { return struct {
- const Self = this;
- const block_size = 64;
- const digest_size = params.out_len / 8;
-
- s: [8]u32,
- // Streaming Cache
- buf: [64]u8,
- buf_len: u8,
- total_len: u64,
-
- pub fn init() Self {
- var d: Self = undefined;
- d.reset();
- return d;
- }
-
- pub fn reset(d: &Self) void {
- d.s[0] = params.iv0;
- d.s[1] = params.iv1;
- d.s[2] = params.iv2;
- d.s[3] = params.iv3;
- d.s[4] = params.iv4;
- d.s[5] = params.iv5;
- d.s[6] = params.iv6;
- d.s[7] = params.iv7;
- d.buf_len = 0;
- d.total_len = 0;
- }
-
- pub fn hash(b: []const u8, out: []u8) void {
- var d = Self.init();
- d.update(b);
- d.final(out);
- }
-
- pub fn update(d: &Self, b: []const u8) void {
- var off: usize = 0;
-
- // Partial buffer exists from previous update. Copy into buffer then hash.
- if (d.buf_len != 0 and d.buf_len + b.len > 64) {
- off += 64 - d.buf_len;
- mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
+fn Sha2_32(comptime params: Sha2Params32) type {
+ return struct {
+ const Self = this;
+ const block_size = 64;
+ const digest_size = params.out_len / 8;
+
+ s: [8]u32,
+ // Streaming Cache
+ buf: [64]u8,
+ buf_len: u8,
+ total_len: u64,
+
+ pub fn init() Self {
+ var d: Self = undefined;
+ d.reset();
+ return d;
+ }
- d.round(d.buf[0..]);
+ pub fn reset(d: &Self) void {
+ d.s[0] = params.iv0;
+ d.s[1] = params.iv1;
+ d.s[2] = params.iv2;
+ d.s[3] = params.iv3;
+ d.s[4] = params.iv4;
+ d.s[5] = params.iv5;
+ d.s[6] = params.iv6;
+ d.s[7] = params.iv7;
d.buf_len = 0;
+ d.total_len = 0;
}
- // Full middle blocks.
- while (off + 64 <= b.len) : (off += 64) {
- d.round(b[off..off + 64]);
+ pub fn hash(b: []const u8, out: []u8) void {
+ var d = Self.init();
+ d.update(b);
+ d.final(out);
}
- // Copy any remainder for next pass.
- mem.copy(u8, d.buf[d.buf_len..], b[off..]);
- d.buf_len += u8(b[off..].len);
+ pub fn update(d: &Self, b: []const u8) void {
+ var off: usize = 0;
- d.total_len += b.len;
- }
+ // Partial buffer exists from previous update. Copy into buffer then hash.
+ if (d.buf_len != 0 and d.buf_len + b.len > 64) {
+ off += 64 - d.buf_len;
+ mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
- pub fn final(d: &Self, out: []u8) void {
- debug.assert(out.len >= params.out_len / 8);
+ d.round(d.buf[0..]);
+ d.buf_len = 0;
+ }
- // The buffer here will never be completely full.
- mem.set(u8, d.buf[d.buf_len..], 0);
+ // Full middle blocks.
+ while (off + 64 <= b.len) : (off += 64) {
+ d.round(b[off..off + 64]);
+ }
- // Append padding bits.
- d.buf[d.buf_len] = 0x80;
- d.buf_len += 1;
+ // Copy any remainder for next pass.
+ mem.copy(u8, d.buf[d.buf_len..], b[off..]);
+ d.buf_len += u8(b[off..].len);
- // > 448 mod 512 so need to add an extra round to wrap around.
- if (64 - d.buf_len < 8) {
- d.round(d.buf[0..]);
- mem.set(u8, d.buf[0..], 0);
+ d.total_len += b.len;
}
- // Append message length.
- var i: usize = 1;
- var len = d.total_len >> 5;
- d.buf[63] = u8(d.total_len & 0x1f) << 3;
- while (i < 8) : (i += 1) {
- d.buf[63 - i] = u8(len & 0xff);
- len >>= 8;
- }
+ pub fn final(d: &Self, out: []u8) void {
+ debug.assert(out.len >= params.out_len / 8);
- d.round(d.buf[0..]);
+ // The buffer here will never be completely full.
+ mem.set(u8, d.buf[d.buf_len..], 0);
- // May truncate for possible 224 output
- const rr = d.s[0 .. params.out_len / 32];
+ // Append padding bits.
+ d.buf[d.buf_len] = 0x80;
+ d.buf_len += 1;
- for (rr) |s, j| {
- mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Big);
- }
- }
+ // > 448 mod 512 so need to add an extra round to wrap around.
+ if (64 - d.buf_len < 8) {
+ d.round(d.buf[0..]);
+ mem.set(u8, d.buf[0..], 0);
+ }
+
+ // Append message length.
+ var i: usize = 1;
+ var len = d.total_len >> 5;
+ d.buf[63] = u8(d.total_len & 0x1f) << 3;
+ while (i < 8) : (i += 1) {
+ d.buf[63 - i] = u8(len & 0xff);
+ len >>= 8;
+ }
- fn round(d: &Self, b: []const u8) void {
- debug.assert(b.len == 64);
+ d.round(d.buf[0..]);
- var s: [64]u32 = undefined;
+ // May truncate for possible 224 output
+ const rr = d.s[0..params.out_len / 32];
- var i: usize = 0;
- while (i < 16) : (i += 1) {
- s[i] = 0;
- s[i] |= u32(b[i*4+0]) << 24;
- s[i] |= u32(b[i*4+1]) << 16;
- s[i] |= u32(b[i*4+2]) << 8;
- s[i] |= u32(b[i*4+3]) << 0;
- }
- while (i < 64) : (i += 1) {
- 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));
+ for (rr) |s, j| {
+ mem.writeInt(out[4 * j..4 * j + 4], s, builtin.Endian.Big);
+ }
}
- var v: [8]u32 = []u32 {
- d.s[0], d.s[1], d.s[2], d.s[3], d.s[4], d.s[5], d.s[6], d.s[7],
- };
-
- const round0 = comptime []RoundParam256 {
- Rp256(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98),
- Rp256(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x71374491),
- Rp256(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCF),
- Rp256(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA5),
- Rp256(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25B),
- Rp256(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1),
- Rp256(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4),
- Rp256(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5),
- Rp256(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98),
- Rp256(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B01),
- Rp256(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE),
- Rp256(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3),
- Rp256(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74),
- Rp256(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE),
- Rp256(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A7),
- Rp256(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174),
- Rp256(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C1),
- Rp256(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786),
- Rp256(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC6),
- Rp256(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC),
- Rp256(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F),
- Rp256(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA),
- Rp256(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DC),
- Rp256(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA),
- Rp256(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152),
- Rp256(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D),
- Rp256(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C8),
- Rp256(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7),
- Rp256(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF3),
- Rp256(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147),
- Rp256(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351),
- Rp256(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x14292967),
- Rp256(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A85),
- Rp256(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B2138),
- Rp256(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC),
- Rp256(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D13),
- Rp256(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A7354),
- Rp256(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB),
- Rp256(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E),
- Rp256(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C85),
- Rp256(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A1),
- Rp256(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664B),
- Rp256(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70),
- Rp256(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A3),
- Rp256(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819),
- Rp256(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD6990624),
- Rp256(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E3585),
- Rp256(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA070),
- Rp256(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116),
- Rp256(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C08),
- Rp256(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774C),
- Rp256(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5),
- Rp256(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3),
- Rp256(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4A),
- Rp256(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F),
- Rp256(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3),
- Rp256(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE),
- Rp256(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F),
- Rp256(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814),
- Rp256(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC70208),
- Rp256(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA),
- Rp256(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEB),
- Rp256(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7),
- Rp256(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2),
- };
- inline for (round0) |r| {
- 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];
-
- v[r.d] = v[r.d] +% v[r.h];
-
- 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]));
+ fn round(d: &Self, b: []const u8) void {
+ debug.assert(b.len == 64);
+
+ var s: [64]u32 = undefined;
+
+ var i: usize = 0;
+ while (i < 16) : (i += 1) {
+ s[i] = 0;
+ s[i] |= u32(b[i * 4 + 0]) << 24;
+ s[i] |= u32(b[i * 4 + 1]) << 16;
+ s[i] |= u32(b[i * 4 + 2]) << 8;
+ s[i] |= u32(b[i * 4 + 3]) << 0;
+ }
+ while (i < 64) : (i += 1) {
+ 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));
+ }
+
+ var v: [8]u32 = []u32{
+ d.s[0],
+ d.s[1],
+ d.s[2],
+ d.s[3],
+ d.s[4],
+ d.s[5],
+ d.s[6],
+ d.s[7],
+ };
+
+ const round0 = comptime []RoundParam256{
+ Rp256(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98),
+ Rp256(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x71374491),
+ Rp256(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCF),
+ Rp256(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA5),
+ Rp256(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25B),
+ Rp256(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1),
+ Rp256(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4),
+ Rp256(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5),
+ Rp256(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98),
+ Rp256(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B01),
+ Rp256(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE),
+ Rp256(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3),
+ Rp256(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74),
+ Rp256(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE),
+ Rp256(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A7),
+ Rp256(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174),
+ Rp256(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C1),
+ Rp256(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786),
+ Rp256(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC6),
+ Rp256(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC),
+ Rp256(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F),
+ Rp256(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA),
+ Rp256(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DC),
+ Rp256(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA),
+ Rp256(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152),
+ Rp256(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D),
+ Rp256(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C8),
+ Rp256(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7),
+ Rp256(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF3),
+ Rp256(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147),
+ Rp256(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351),
+ Rp256(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x14292967),
+ Rp256(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A85),
+ Rp256(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B2138),
+ Rp256(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC),
+ Rp256(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D13),
+ Rp256(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A7354),
+ Rp256(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB),
+ Rp256(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E),
+ Rp256(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C85),
+ Rp256(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A1),
+ Rp256(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664B),
+ Rp256(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70),
+ Rp256(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A3),
+ Rp256(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819),
+ Rp256(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD6990624),
+ Rp256(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E3585),
+ Rp256(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA070),
+ Rp256(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116),
+ Rp256(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C08),
+ Rp256(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774C),
+ Rp256(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5),
+ Rp256(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3),
+ Rp256(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4A),
+ Rp256(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F),
+ Rp256(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3),
+ Rp256(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE),
+ Rp256(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F),
+ Rp256(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814),
+ Rp256(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC70208),
+ Rp256(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA),
+ Rp256(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEB),
+ Rp256(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7),
+ Rp256(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2),
+ };
+ inline for (round0) |r| {
+ 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];
+
+ v[r.d] = v[r.d] +% v[r.h];
+
+ 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]));
+ }
+
+ d.s[0] +%= v[0];
+ d.s[1] +%= v[1];
+ d.s[2] +%= v[2];
+ d.s[3] +%= v[3];
+ d.s[4] +%= v[4];
+ d.s[5] +%= v[5];
+ d.s[6] +%= v[6];
+ d.s[7] +%= v[7];
}
-
- d.s[0] +%= v[0];
- d.s[1] +%= v[1];
- d.s[2] +%= v[2];
- d.s[3] +%= v[3];
- d.s[4] +%= v[4];
- d.s[5] +%= v[5];
- d.s[6] +%= v[6];
- d.s[7] +%= v[7];
- }
-};}
+ };
+}
test "sha224 single" {
htest.assertEqualHash(Sha224, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "");
@@ -320,7 +338,7 @@ test "sha256 streaming" {
}
test "sha256 aligned final" {
- var block = []u8 {0} ** Sha256.block_size;
+ var block = []u8{0} ** Sha256.block_size;
var out: [Sha256.digest_size]u8 = undefined;
var h = Sha256.init();
@@ -328,17 +346,35 @@ test "sha256 aligned final" {
h.final(out[0..]);
}
-
/////////////////////
// Sha384 + Sha512
const RoundParam512 = struct {
- a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize,
- i: usize, k: u64,
+ a: usize,
+ b: usize,
+ c: usize,
+ d: usize,
+ e: usize,
+ f: usize,
+ g: usize,
+ h: usize,
+ i: usize,
+ k: u64,
};
fn Rp512(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u64) RoundParam512 {
- return RoundParam512 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };
+ return RoundParam512{
+ .a = a,
+ .b = b,
+ .c = c,
+ .d = d,
+ .e = e,
+ .f = f,
+ .g = g,
+ .h = h,
+ .i = i,
+ .k = k,
+ };
}
const Sha2Params64 = struct {
@@ -353,7 +389,7 @@ const Sha2Params64 = struct {
out_len: usize,
};
-const Sha384Params = Sha2Params64 {
+const Sha384Params = Sha2Params64{
.iv0 = 0xCBBB9D5DC1059ED8,
.iv1 = 0x629A292A367CD507,
.iv2 = 0x9159015A3070DD17,
@@ -365,7 +401,7 @@ const Sha384Params = Sha2Params64 {
.out_len = 384,
};
-const Sha512Params = Sha2Params64 {
+const Sha512Params = Sha2Params64{
.iv0 = 0x6A09E667F3BCC908,
.iv1 = 0xBB67AE8584CAA73B,
.iv2 = 0x3C6EF372FE94F82B,
@@ -374,242 +410,241 @@ const Sha512Params = Sha2Params64 {
.iv5 = 0x9B05688C2B3E6C1F,
.iv6 = 0x1F83D9ABFB41BD6B,
.iv7 = 0x5BE0CD19137E2179,
- .out_len = 512
+ .out_len = 512,
};
pub const Sha384 = Sha2_64(Sha384Params);
pub const Sha512 = Sha2_64(Sha512Params);
-fn Sha2_64(comptime params: Sha2Params64) type { return struct {
- const Self = this;
- const block_size = 128;
- const digest_size = params.out_len / 8;
-
- s: [8]u64,
- // Streaming Cache
- buf: [128]u8,
- buf_len: u8,
- total_len: u128,
-
- pub fn init() Self {
- var d: Self = undefined;
- d.reset();
- return d;
- }
-
- pub fn reset(d: &Self) void {
- d.s[0] = params.iv0;
- d.s[1] = params.iv1;
- d.s[2] = params.iv2;
- d.s[3] = params.iv3;
- d.s[4] = params.iv4;
- d.s[5] = params.iv5;
- d.s[6] = params.iv6;
- d.s[7] = params.iv7;
- d.buf_len = 0;
- d.total_len = 0;
- }
-
- pub fn hash(b: []const u8, out: []u8) void {
- var d = Self.init();
- d.update(b);
- d.final(out);
- }
-
- pub fn update(d: &Self, b: []const u8) void {
- var off: usize = 0;
-
- // Partial buffer exists from previous update. Copy into buffer then hash.
- if (d.buf_len != 0 and d.buf_len + b.len > 128) {
- off += 128 - d.buf_len;
- mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
+fn Sha2_64(comptime params: Sha2Params64) type {
+ return struct {
+ const Self = this;
+ const block_size = 128;
+ const digest_size = params.out_len / 8;
+
+ s: [8]u64,
+ // Streaming Cache
+ buf: [128]u8,
+ buf_len: u8,
+ total_len: u128,
+
+ pub fn init() Self {
+ var d: Self = undefined;
+ d.reset();
+ return d;
+ }
- d.round(d.buf[0..]);
+ pub fn reset(d: &Self) void {
+ d.s[0] = params.iv0;
+ d.s[1] = params.iv1;
+ d.s[2] = params.iv2;
+ d.s[3] = params.iv3;
+ d.s[4] = params.iv4;
+ d.s[5] = params.iv5;
+ d.s[6] = params.iv6;
+ d.s[7] = params.iv7;
d.buf_len = 0;
+ d.total_len = 0;
}
- // Full middle blocks.
- while (off + 128 <= b.len) : (off += 128) {
- d.round(b[off..off + 128]);
+ pub fn hash(b: []const u8, out: []u8) void {
+ var d = Self.init();
+ d.update(b);
+ d.final(out);
}
- // Copy any remainder for next pass.
- mem.copy(u8, d.buf[d.buf_len..], b[off..]);
- d.buf_len += u8(b[off..].len);
+ pub fn update(d: &Self, b: []const u8) void {
+ var off: usize = 0;
- d.total_len += b.len;
- }
+ // Partial buffer exists from previous update. Copy into buffer then hash.
+ if (d.buf_len != 0 and d.buf_len + b.len > 128) {
+ off += 128 - d.buf_len;
+ mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
- pub fn final(d: &Self, out: []u8) void {
- debug.assert(out.len >= params.out_len / 8);
+ d.round(d.buf[0..]);
+ d.buf_len = 0;
+ }
- // The buffer here will never be completely full.
- mem.set(u8, d.buf[d.buf_len..], 0);
+ // Full middle blocks.
+ while (off + 128 <= b.len) : (off += 128) {
+ d.round(b[off..off + 128]);
+ }
- // Append padding bits.
- d.buf[d.buf_len] = 0x80;
- d.buf_len += 1;
+ // Copy any remainder for next pass.
+ mem.copy(u8, d.buf[d.buf_len..], b[off..]);
+ d.buf_len += u8(b[off..].len);
- // > 896 mod 1024 so need to add an extra round to wrap around.
- if (128 - d.buf_len < 16) {
- d.round(d.buf[0..]);
- mem.set(u8, d.buf[0..], 0);
+ d.total_len += b.len;
}
- // Append message length.
- var i: usize = 1;
- var len = d.total_len >> 5;
- d.buf[127] = u8(d.total_len & 0x1f) << 3;
- while (i < 16) : (i += 1) {
- d.buf[127 - i] = u8(len & 0xff);
- len >>= 8;
- }
+ pub fn final(d: &Self, out: []u8) void {
+ debug.assert(out.len >= params.out_len / 8);
- d.round(d.buf[0..]);
+ // The buffer here will never be completely full.
+ mem.set(u8, d.buf[d.buf_len..], 0);
- // May truncate for possible 384 output
- const rr = d.s[0 .. params.out_len / 64];
+ // Append padding bits.
+ d.buf[d.buf_len] = 0x80;
+ d.buf_len += 1;
- for (rr) |s, j| {
- mem.writeInt(out[8*j .. 8*j + 8], s, builtin.Endian.Big);
- }
- }
-
- fn round(d: &Self, b: []const u8) void {
- debug.assert(b.len == 128);
-
- var s: [80]u64 = undefined;
-
- var i: usize = 0;
- while (i < 16) : (i += 1) {
- s[i] = 0;
- s[i] |= u64(b[i*8+0]) << 56;
- s[i] |= u64(b[i*8+1]) << 48;
- s[i] |= u64(b[i*8+2]) << 40;
- s[i] |= u64(b[i*8+3]) << 32;
- s[i] |= u64(b[i*8+4]) << 24;
- s[i] |= u64(b[i*8+5]) << 16;
- s[i] |= u64(b[i*8+6]) << 8;
- s[i] |= u64(b[i*8+7]) << 0;
- }
- while (i < 80) : (i += 1) {
- 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));
- }
+ // > 896 mod 1024 so need to add an extra round to wrap around.
+ if (128 - d.buf_len < 16) {
+ d.round(d.buf[0..]);
+ mem.set(u8, d.buf[0..], 0);
+ }
- var v: [8]u64 = []u64 {
- d.s[0], d.s[1], d.s[2], d.s[3], d.s[4], d.s[5], d.s[6], d.s[7],
- };
-
- const round0 = comptime []RoundParam512 {
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98D728AE22),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x7137449123EF65CD),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCFEC4D3B2F),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA58189DBBC),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25BF348B538),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1B605D019),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4AF194F9B),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5DA6D8118),
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98A3030242),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B0145706FBE),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE4EE4B28C),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3D5FFB4E2),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74F27B896F),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE3B1696B1),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A725C71235),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174CF692694),
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C19EF14AD2),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786384F25E3),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC68B8CD5B5),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC77AC9C65),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F592B0275),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA6EA6E483),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DCBD41FBD4),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA831153B5),
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152EE66DFAB),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D2DB43210),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C898FB213F),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7BEEF0EE4),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF33DA88FC2),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147930AA725),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351E003826F),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x142929670A0E6E70),
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A8546D22FFC),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B21385C26C926),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC5AC42AED),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D139D95B3DF),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A73548BAF63DE),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB3C77B2A8),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E47EDAEE6),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C851482353B),
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A14CF10364),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664BBC423001),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70D0F89791),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A30654BE30),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819D6EF5218),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD69906245565A910),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E35855771202A),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA07032BBD1B8),
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116B8D2D0C8),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C085141AB53),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774CDF8EEB99),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5E19B48A8),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3C5C95A63),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4AE3418ACB),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F7763E373),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3D6B2B8A3),
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE5DEFB2FC),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F43172F60),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814A1F0AB72),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC702081A6439EC),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA23631E28),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEBDE82BDE9),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7B2C67915),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2E372532B),
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 64, 0xCA273ECEEA26619C),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 65, 0xD186B8C721C0C207),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 66, 0xEADA7DD6CDE0EB1E),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 67, 0xF57D4F7FEE6ED178),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 68, 0x06F067AA72176FBA),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 69, 0x0A637DC5A2C898A6),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 70, 0x113F9804BEF90DAE),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 71, 0x1B710B35131C471B),
- Rp512(0, 1, 2, 3, 4, 5, 6, 7, 72, 0x28DB77F523047D84),
- Rp512(7, 0, 1, 2, 3, 4, 5, 6, 73, 0x32CAAB7B40C72493),
- Rp512(6, 7, 0, 1, 2, 3, 4, 5, 74, 0x3C9EBE0A15C9BEBC),
- Rp512(5, 6, 7, 0, 1, 2, 3, 4, 75, 0x431D67C49C100D4C),
- Rp512(4, 5, 6, 7, 0, 1, 2, 3, 76, 0x4CC5D4BECB3E42B6),
- Rp512(3, 4, 5, 6, 7, 0, 1, 2, 77, 0x597F299CFC657E2A),
- Rp512(2, 3, 4, 5, 6, 7, 0, 1, 78, 0x5FCB6FAB3AD6FAEC),
- Rp512(1, 2, 3, 4, 5, 6, 7, 0, 79, 0x6C44198C4A475817),
- };
- inline for (round0) |r| {
- 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];
-
- v[r.d] = v[r.d] +% v[r.h];
-
- 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]));
+ // Append message length.
+ var i: usize = 1;
+ var len = d.total_len >> 5;
+ d.buf[127] = u8(d.total_len & 0x1f) << 3;
+ while (i < 16) : (i += 1) {
+ d.buf[127 - i] = u8(len & 0xff);
+ len >>= 8;
+ }
+
+ d.round(d.buf[0..]);
+
+ // May truncate for possible 384 output
+ const rr = d.s[0..params.out_len / 64];
+
+ for (rr) |s, j| {
+ mem.writeInt(out[8 * j..8 * j + 8], s, builtin.Endian.Big);
+ }
}
- d.s[0] +%= v[0];
- d.s[1] +%= v[1];
- d.s[2] +%= v[2];
- d.s[3] +%= v[3];
- d.s[4] +%= v[4];
- d.s[5] +%= v[5];
- d.s[6] +%= v[6];
- d.s[7] +%= v[7];
- }
-};}
+ fn round(d: &Self, b: []const u8) void {
+ debug.assert(b.len == 128);
+
+ var s: [80]u64 = undefined;
+
+ var i: usize = 0;
+ while (i < 16) : (i += 1) {
+ s[i] = 0;
+ s[i] |= u64(b[i * 8 + 0]) << 56;
+ s[i] |= u64(b[i * 8 + 1]) << 48;
+ s[i] |= u64(b[i * 8 + 2]) << 40;
+ s[i] |= u64(b[i * 8 + 3]) << 32;
+ s[i] |= u64(b[i * 8 + 4]) << 24;
+ s[i] |= u64(b[i * 8 + 5]) << 16;
+ s[i] |= u64(b[i * 8 + 6]) << 8;
+ s[i] |= u64(b[i * 8 + 7]) << 0;
+ }
+ while (i < 80) : (i += 1) {
+ 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));
+ }
+
+ var v: [8]u64 = []u64{
+ d.s[0],
+ d.s[1],
+ d.s[2],
+ d.s[3],
+ d.s[4],
+ d.s[5],
+ d.s[6],
+ d.s[7],
+ };
+
+ const round0 = comptime []RoundParam512{
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 0, 0x428A2F98D728AE22),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 1, 0x7137449123EF65CD),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 2, 0xB5C0FBCFEC4D3B2F),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 3, 0xE9B5DBA58189DBBC),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 4, 0x3956C25BF348B538),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 5, 0x59F111F1B605D019),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 6, 0x923F82A4AF194F9B),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 7, 0xAB1C5ED5DA6D8118),
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 8, 0xD807AA98A3030242),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 9, 0x12835B0145706FBE),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 10, 0x243185BE4EE4B28C),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 11, 0x550C7DC3D5FFB4E2),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 12, 0x72BE5D74F27B896F),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 13, 0x80DEB1FE3B1696B1),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 14, 0x9BDC06A725C71235),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 15, 0xC19BF174CF692694),
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 16, 0xE49B69C19EF14AD2),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 17, 0xEFBE4786384F25E3),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 18, 0x0FC19DC68B8CD5B5),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 19, 0x240CA1CC77AC9C65),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 20, 0x2DE92C6F592B0275),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 21, 0x4A7484AA6EA6E483),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 22, 0x5CB0A9DCBD41FBD4),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 23, 0x76F988DA831153B5),
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 24, 0x983E5152EE66DFAB),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 25, 0xA831C66D2DB43210),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 26, 0xB00327C898FB213F),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 27, 0xBF597FC7BEEF0EE4),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 28, 0xC6E00BF33DA88FC2),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 29, 0xD5A79147930AA725),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 30, 0x06CA6351E003826F),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 31, 0x142929670A0E6E70),
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 32, 0x27B70A8546D22FFC),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 33, 0x2E1B21385C26C926),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 34, 0x4D2C6DFC5AC42AED),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 35, 0x53380D139D95B3DF),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 36, 0x650A73548BAF63DE),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 37, 0x766A0ABB3C77B2A8),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 38, 0x81C2C92E47EDAEE6),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 39, 0x92722C851482353B),
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 40, 0xA2BFE8A14CF10364),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 41, 0xA81A664BBC423001),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 42, 0xC24B8B70D0F89791),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 43, 0xC76C51A30654BE30),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 44, 0xD192E819D6EF5218),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 45, 0xD69906245565A910),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 46, 0xF40E35855771202A),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 47, 0x106AA07032BBD1B8),
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 48, 0x19A4C116B8D2D0C8),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 49, 0x1E376C085141AB53),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 50, 0x2748774CDF8EEB99),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 51, 0x34B0BCB5E19B48A8),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 52, 0x391C0CB3C5C95A63),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 53, 0x4ED8AA4AE3418ACB),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 54, 0x5B9CCA4F7763E373),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 55, 0x682E6FF3D6B2B8A3),
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 56, 0x748F82EE5DEFB2FC),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 57, 0x78A5636F43172F60),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 58, 0x84C87814A1F0AB72),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 59, 0x8CC702081A6439EC),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 60, 0x90BEFFFA23631E28),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 61, 0xA4506CEBDE82BDE9),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 62, 0xBEF9A3F7B2C67915),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2E372532B),
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 64, 0xCA273ECEEA26619C),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 65, 0xD186B8C721C0C207),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 66, 0xEADA7DD6CDE0EB1E),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 67, 0xF57D4F7FEE6ED178),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 68, 0x06F067AA72176FBA),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 69, 0x0A637DC5A2C898A6),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 70, 0x113F9804BEF90DAE),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 71, 0x1B710B35131C471B),
+ Rp512(0, 1, 2, 3, 4, 5, 6, 7, 72, 0x28DB77F523047D84),
+ Rp512(7, 0, 1, 2, 3, 4, 5, 6, 73, 0x32CAAB7B40C72493),
+ Rp512(6, 7, 0, 1, 2, 3, 4, 5, 74, 0x3C9EBE0A15C9BEBC),
+ Rp512(5, 6, 7, 0, 1, 2, 3, 4, 75, 0x431D67C49C100D4C),
+ Rp512(4, 5, 6, 7, 0, 1, 2, 3, 76, 0x4CC5D4BECB3E42B6),
+ Rp512(3, 4, 5, 6, 7, 0, 1, 2, 77, 0x597F299CFC657E2A),
+ Rp512(2, 3, 4, 5, 6, 7, 0, 1, 78, 0x5FCB6FAB3AD6FAEC),
+ Rp512(1, 2, 3, 4, 5, 6, 7, 0, 79, 0x6C44198C4A475817),
+ };
+ inline for (round0) |r| {
+ 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];
+
+ v[r.d] = v[r.d] +% v[r.h];
+
+ 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]));
+ }
+
+ d.s[0] +%= v[0];
+ d.s[1] +%= v[1];
+ d.s[2] +%= v[2];
+ d.s[3] +%= v[3];
+ d.s[4] +%= v[4];
+ d.s[5] +%= v[5];
+ d.s[6] +%= v[6];
+ d.s[7] +%= v[7];
+ }
+ };
+}
test "sha384 single" {
const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";
@@ -680,7 +715,7 @@ test "sha512 streaming" {
}
test "sha512 aligned final" {
- var block = []u8 {0} ** Sha512.block_size;
+ var block = []u8{0} ** Sha512.block_size;
var out: [Sha512.digest_size]u8 = undefined;
var h = Sha512.init();
diff --git a/std/crypto/test.zig b/std/crypto/test.zig
index 3fa24272e5..c0a96a98de 100644
--- a/std/crypto/test.zig
+++ b/std/crypto/test.zig
@@ -14,7 +14,7 @@ pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, inpu
pub fn assertEqual(comptime expected: []const u8, input: []const u8) void {
var expected_bytes: [expected.len / 2]u8 = undefined;
for (expected_bytes) |*r, i| {
- r.* = fmt.parseInt(u8, expected[2 * i .. 2 * i + 2], 16) catch unreachable;
+ r.* = fmt.parseInt(u8, expected[2 * i..2 * i + 2], 16) catch unreachable;
}
debug.assert(mem.eql(u8, expected_bytes, input));
diff --git a/std/crypto/throughput_test.zig b/std/crypto/throughput_test.zig
index 0756f9a4eb..c5c4f9fe10 100644
--- a/std/crypto/throughput_test.zig
+++ b/std/crypto/throughput_test.zig
@@ -11,7 +11,7 @@ const Timer = time.Timer;
const HashFunction = @import("md5.zig").Md5;
const MiB = 1024 * 1024;
-const BytesToHash = 1024 * MiB;
+const BytesToHash = 1024 * MiB;
pub fn main() !void {
var stdout_file = try std.io.getStdOut();
diff --git a/std/cstr.zig b/std/cstr.zig
index d396dcbce3..c9f3026064 100644
--- a/std/cstr.zig
+++ b/std/cstr.zig
@@ -9,7 +9,6 @@ pub const line_sep = switch (builtin.os) {
else => "\n",
};
-
pub fn len(ptr: &const u8) usize {
var count: usize = 0;
while (ptr[count] != 0) : (count += 1) {}
@@ -95,7 +94,7 @@ pub const NullTerminated2DArray = struct {
}
index_buf[i] = null;
- return NullTerminated2DArray {
+ return NullTerminated2DArray{
.allocator = allocator,
.byte_count = byte_count,
.ptr = @ptrCast(?&?&u8, buf.ptr),
@@ -107,4 +106,3 @@ pub const NullTerminated2DArray = struct {
self.allocator.free(buf[0..self.byte_count]);
}
};
-
diff --git a/std/debug/failing_allocator.zig b/std/debug/failing_allocator.zig
index f876b7902d..6b5edff5bf 100644
--- a/std/debug/failing_allocator.zig
+++ b/std/debug/failing_allocator.zig
@@ -13,14 +13,14 @@ pub const FailingAllocator = struct {
deallocations: usize,
pub fn init(allocator: &mem.Allocator, fail_index: usize) FailingAllocator {
- return FailingAllocator {
+ return FailingAllocator{
.internal_allocator = allocator,
.fail_index = fail_index,
.index = 0,
.allocated_bytes = 0,
.freed_bytes = 0,
.deallocations = 0,
- .allocator = mem.Allocator {
+ .allocator = mem.Allocator{
.allocFn = alloc,
.reallocFn = realloc,
.freeFn = free,
diff --git a/std/debug/index.zig b/std/debug/index.zig
index 36ac2e8a3f..92e565b391 100644
--- a/std/debug/index.zig
+++ b/std/debug/index.zig
@@ -227,8 +227,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: var, address: us
else => return err,
}
} else |err| switch (err) {
- error.MissingDebugInfo,
- error.InvalidDebugInfo => {
+ error.MissingDebugInfo, error.InvalidDebugInfo => {
try out_stream.print(ptr_hex ++ " in ??? ({})\n", address, compile_unit_name);
},
else => return err,
@@ -597,10 +596,12 @@ fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: var, size: usize) !
}
fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue {
- return FormValue{ .Const = Constant{
- .signed = signed,
- .payload = try readAllocBytes(allocator, in_stream, size),
- } };
+ return FormValue{
+ .Const = Constant{
+ .signed = signed,
+ .payload = try readAllocBytes(allocator, in_stream, size),
+ },
+ };
}
fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 {
@@ -621,7 +622,7 @@ fn parseFormValueRef(allocator: &mem.Allocator, in_stream: var, comptime T: type
return parseFormValueRefLen(allocator, in_stream, block_len);
}
-const ParseFormValueError = error {
+const ParseFormValueError = error{
EndOfStream,
Io,
BadFd,
@@ -645,8 +646,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64
DW.FORM_data2 => parseFormValueConstant(allocator, in_stream, false, 2),
DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4),
DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8),
- DW.FORM_udata,
- DW.FORM_sdata => {
+ DW.FORM_udata, DW.FORM_sdata => {
const block_len = try readULeb128(in_stream);
const signed = form_id == DW.FORM_sdata;
return parseFormValueConstant(allocator, in_stream, signed, block_len);
diff --git a/std/dwarf.zig b/std/dwarf.zig
index 04456d9e5c..76ed122447 100644
--- a/std/dwarf.zig
+++ b/std/dwarf.zig
@@ -337,7 +337,6 @@ pub const AT_PGI_lbase = 0x3a00;
pub const AT_PGI_soffset = 0x3a01;
pub const AT_PGI_lstride = 0x3a02;
-
pub const OP_addr = 0x03;
pub const OP_deref = 0x06;
pub const OP_const1u = 0x08;
@@ -577,7 +576,6 @@ pub const ATE_HP_unsigned_fixed = 0x8e; // Cobol.
pub const ATE_HP_VAX_complex_float = 0x8f; // F or G floating complex.
pub const ATE_HP_VAX_complex_float_d = 0x90; // D floating complex.
-
pub const CFA_advance_loc = 0x40;
pub const CFA_offset = 0x80;
pub const CFA_restore = 0xc0;
diff --git a/std/elf.zig b/std/elf.zig
index 1764829bc8..29b9473f98 100644
--- a/std/elf.zig
+++ b/std/elf.zig
@@ -123,13 +123,11 @@ pub const DT_SYMINFO = 0x6ffffeff;
pub const DT_ADDRRNGHI = 0x6ffffeff;
pub const DT_ADDRNUM = 11;
-
pub const DT_VERSYM = 0x6ffffff0;
pub const DT_RELACOUNT = 0x6ffffff9;
pub const DT_RELCOUNT = 0x6ffffffa;
-
pub const DT_FLAGS_1 = 0x6ffffffb;
pub const DT_VERDEF = 0x6ffffffc;
@@ -139,13 +137,10 @@ pub const DT_VERNEED = 0x6ffffffe;
pub const DT_VERNEEDNUM = 0x6fffffff;
pub const DT_VERSIONTAGNUM = 16;
-
-
pub const DT_AUXILIARY = 0x7ffffffd;
pub const DT_FILTER = 0x7fffffff;
pub const DT_EXTRANUM = 3;
-
pub const DT_SPARC_REGISTER = 0x70000001;
pub const DT_SPARC_NUM = 2;
@@ -434,9 +429,7 @@ pub const Elf = struct {
try elf.in_file.seekForward(4);
const header_size = try in.readInt(elf.endian, u16);
- if ((elf.is_64 and header_size != 64) or
- (!elf.is_64 and header_size != 52))
- {
+ if ((elf.is_64 and header_size != 64) or (!elf.is_64 and header_size != 52)) {
return error.InvalidFormat;
}
@@ -467,16 +460,16 @@ pub const Elf = struct {
if (sh_entry_size != 64) return error.InvalidFormat;
for (elf.section_headers) |*elf_section| {
- elf_section.name = try in.readInt(elf.endian, u32);
- elf_section.sh_type = try in.readInt(elf.endian, u32);
- elf_section.flags = try in.readInt(elf.endian, u64);
- elf_section.addr = try in.readInt(elf.endian, u64);
- elf_section.offset = try in.readInt(elf.endian, u64);
- elf_section.size = try in.readInt(elf.endian, u64);
- elf_section.link = try in.readInt(elf.endian, u32);
- elf_section.info = try in.readInt(elf.endian, u32);
- elf_section.addr_align = try in.readInt(elf.endian, u64);
- elf_section.ent_size = try in.readInt(elf.endian, u64);
+ elf_section.name = try in.readInt(elf.endian, u32);
+ elf_section.sh_type = try in.readInt(elf.endian, u32);
+ elf_section.flags = try in.readInt(elf.endian, u64);
+ elf_section.addr = try in.readInt(elf.endian, u64);
+ elf_section.offset = try in.readInt(elf.endian, u64);
+ elf_section.size = try in.readInt(elf.endian, u64);
+ elf_section.link = try in.readInt(elf.endian, u32);
+ elf_section.info = try in.readInt(elf.endian, u32);
+ elf_section.addr_align = try in.readInt(elf.endian, u64);
+ elf_section.ent_size = try in.readInt(elf.endian, u64);
}
} else {
if (sh_entry_size != 40) return error.InvalidFormat;
@@ -513,8 +506,7 @@ pub const Elf = struct {
pub fn close(elf: &Elf) void {
elf.allocator.free(elf.section_headers);
- if (elf.auto_close_stream)
- elf.in_file.close();
+ if (elf.auto_close_stream) elf.in_file.close();
}
pub fn findSection(elf: &Elf, name: []const u8) !?&SectionHeader {
@@ -852,27 +844,27 @@ pub const Elf_MIPS_ABIFlags_v0 = extern struct {
flags2: Elf32_Word,
};
-pub const Ehdr = switch(@sizeOf(usize)) {
+pub const Ehdr = switch (@sizeOf(usize)) {
4 => Elf32_Ehdr,
8 => Elf64_Ehdr,
else => @compileError("expected pointer size of 32 or 64"),
};
-pub const Phdr = switch(@sizeOf(usize)) {
+pub const Phdr = switch (@sizeOf(usize)) {
4 => Elf32_Phdr,
8 => Elf64_Phdr,
else => @compileError("expected pointer size of 32 or 64"),
};
-pub const Sym = switch(@sizeOf(usize)) {
+pub const Sym = switch (@sizeOf(usize)) {
4 => Elf32_Sym,
8 => Elf64_Sym,
else => @compileError("expected pointer size of 32 or 64"),
};
-pub const Verdef = switch(@sizeOf(usize)) {
+pub const Verdef = switch (@sizeOf(usize)) {
4 => Elf32_Verdef,
8 => Elf64_Verdef,
else => @compileError("expected pointer size of 32 or 64"),
};
-pub const Verdaux = switch(@sizeOf(usize)) {
+pub const Verdaux = switch (@sizeOf(usize)) {
4 => Elf32_Verdaux,
8 => Elf64_Verdaux,
else => @compileError("expected pointer size of 32 or 64"),
diff --git a/std/event.zig b/std/event.zig
index 558bd2a188..6ee8ab35f1 100644
--- a/std/event.zig
+++ b/std/event.zig
@@ -76,19 +76,14 @@ pub const TcpServer = struct {
}
continue;
},
- error.ConnectionAborted,
- error.FileDescriptorClosed => continue,
+ error.ConnectionAborted, error.FileDescriptorClosed => continue,
error.PageFault => unreachable,
error.InvalidSyscall => unreachable,
error.FileDescriptorNotASocket => unreachable,
error.OperationNotSupported => unreachable,
- error.SystemFdQuotaExceeded,
- error.SystemResources,
- error.ProtocolFailure,
- error.BlockedByFirewall,
- error.Unexpected => {
+ error.SystemFdQuotaExceeded, error.SystemResources, error.ProtocolFailure, error.BlockedByFirewall, error.Unexpected => {
@panic("TODO handle this error");
},
}
@@ -121,7 +116,6 @@ pub const Loop = struct {
pub fn removeFd(self: &Loop, fd: i32) void {
std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};
}
-
async fn waitFd(self: &Loop, fd: i32) !void {
defer self.removeFd(fd);
suspend |p| {
@@ -169,7 +163,6 @@ test "listen on a port, send bytes, receive bytes" {
tcp_server: TcpServer,
const Self = this;
-
async<&mem.Allocator> fn handler(tcp_server: &TcpServer, _addr: &const std.net.Address, _socket: &const std.os.File) void {
const self = @fieldParentPtr(Self, "tcp_server", tcp_server);
var socket = _socket.*; // TODO https://github.com/ziglang/zig/issues/733
@@ -184,7 +177,6 @@ test "listen on a port, send bytes, receive bytes" {
cancel p;
}
}
-
async fn errorableHandler(self: &Self, _addr: &const std.net.Address, _socket: &const std.os.File) !void {
const addr = _addr.*; // TODO https://github.com/ziglang/zig/issues/733
var socket = _socket.*; // TODO https://github.com/ziglang/zig/issues/733
@@ -207,7 +199,6 @@ test "listen on a port, send bytes, receive bytes" {
defer cancel p;
loop.run();
}
-
async fn doAsyncTest(loop: &Loop, address: &const std.net.Address) void {
errdefer @panic("test failure");
diff --git a/std/fmt/errol/enum3.zig b/std/fmt/errol/enum3.zig
index f8299d3c6f..7663f9b5d9 100644
--- a/std/fmt/errol/enum3.zig
+++ b/std/fmt/errol/enum3.zig
@@ -1,4 +1,4 @@
-pub const enum3 = []u64 {
+pub const enum3 = []u64{
0x4e2e2785c3a2a20b,
0x240a28877a09a4e1,
0x728fca36c06cf106,
@@ -439,13 +439,13 @@ const Slab = struct {
};
fn slab(str: []const u8, exp: i32) Slab {
- return Slab {
+ return Slab{
.str = str,
.exp = exp,
};
}
-pub const enum3_data = []Slab {
+pub const enum3_data = []Slab{
slab("40648030339495312", 69),
slab("4498645355592131", -134),
slab("678321594594593", 244),
@@ -879,4 +879,3 @@ pub const enum3_data = []Slab {
slab("32216657306260762", 218),
slab("30423431424080128", 219),
};
-
diff --git a/std/mem.zig b/std/mem.zig
index 617c1de2f5..70f2fe22ac 100644
--- a/std/mem.zig
+++ b/std/mem.zig
@@ -177,6 +177,14 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool {
return true;
}
+/// Returns true if all elements in a slice are equal to the scalar value provided
+pub fn allEqual(comptime T: type, slice: []const T, scalar: T) bool {
+ for (slice) |item| {
+ if (item != scalar) return false;
+ }
+ return true;
+}
+
/// Copies ::m to newly allocated memory. Caller is responsible to free it.
pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) ![]T {
const new_buf = try allocator.alloc(T, m.len);
diff --git a/std/zig/ast.zig b/std/zig/ast.zig
index 6c848b4a54..3b705e2ee6 100644
--- a/std/zig/ast.zig
+++ b/std/zig/ast.zig
@@ -68,6 +68,14 @@ pub const Tree = struct {
return self.tokenLocationPtr(start_index, self.tokens.at(token_index));
}
+ pub fn tokensOnSameLine(self: &Tree, token1_index: TokenIndex, token2_index: TokenIndex) bool {
+ return self.tokensOnSameLinePtr(self.tokens.at(token1_index), self.tokens.at(token2_index));
+ }
+
+ pub fn tokensOnSameLinePtr(self: &Tree, token1: &const Token, token2: &const Token) bool {
+ return mem.indexOfScalar(u8, self.source[token1.end..token2.start], '\n') == null;
+ }
+
pub fn dump(self: &Tree) void {
self.root_node.base.dump(0);
}
@@ -1529,14 +1537,14 @@ pub const Node = struct {
switch (self.op) {
Op.SliceType => |addr_of_info| {
- if (addr_of_info.align_expr) |align_expr| {
- if (i < 1) return align_expr;
+ if (addr_of_info.align_info) |align_info| {
+ if (i < 1) return align_info.node;
i -= 1;
}
},
Op.AddrOf => |addr_of_info| {
- if (addr_of_info.align_expr) |align_expr| {
- if (i < 1) return align_expr;
+ if (addr_of_info.align_info) |align_info| {
+ if (i < 1) return align_info.node;
i -= 1;
}
},
@@ -1553,7 +1561,9 @@ pub const Node = struct {
Op.NegationWrap,
Op.Try,
Op.Resume,
- Op.UnwrapMaybe => {},
+ Op.UnwrapMaybe,
+ Op.PointerType,
+ => {},
}
if (i < 1) return self.rhs;
@@ -1656,6 +1666,7 @@ pub const Node = struct {
if (i < fields.len) return fields.at(i).*;
i -= fields.len;
},
+ Op.Deref => {},
}
return null;
@@ -2071,7 +2082,7 @@ pub const Node = struct {
const OutputList = SegmentedList(&AsmOutput, 2);
const InputList = SegmentedList(&AsmInput, 2);
- const ClobberList = SegmentedList(&Node, 2);
+ const ClobberList = SegmentedList(TokenIndex, 2);
pub fn iterate(self: &Asm, index: usize) ?&Node {
var i = index;
@@ -2082,9 +2093,6 @@ pub const Node = struct {
if (i < self.inputs.len) return &(self.inputs.at(index).*).base;
i -= self.inputs.len;
- if (i < self.clobbers.len) return self.clobbers.at(index).*;
- i -= self.clobbers.len;
-
return null;
}
diff --git a/std/zig/parse.zig b/std/zig/parse.zig
index a6eb22a2d0..1bc64c3ddb 100644
--- a/std/zig/parse.zig
+++ b/std/zig/parse.zig
@@ -1153,9 +1153,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
State.AsmClobberItems => |items| {
- stack.append(State{ .AsmClobberItems = items }) catch unreachable;
- try stack.append(State{ .IfToken = Token.Id.Comma });
- try stack.append(State{ .StringLiteral = OptionalCtx{ .Required = try items.addOne() } });
+ while (eatToken(&tok_it, &tree, Token.Id.StringLiteral)) |strlit| {
+ try items.push(strlit);
+ if (eatToken(&tok_it, &tree, Token.Id.Comma) == null)
+ break;
+ }
continue;
},
diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig
index 9d5e64a66f..8ed748ed30 100644
--- a/std/zig/parser_test.zig
+++ b/std/zig/parser_test.zig
@@ -1,10 +1,427 @@
+test "zig fmt: if condition wraps" {
+ try testTransform(
+ \\comptime {
+ \\ if (cond and
+ \\ cond) {
+ \\ return x;
+ \\ }
+ \\ while (cond and
+ \\ cond) {
+ \\ return x;
+ \\ }
+ \\ if (a == b and
+ \\ c) {
+ \\ a = b;
+ \\ }
+ \\ while (a == b and
+ \\ c) {
+ \\ a = b;
+ \\ }
+ \\ if ((cond and
+ \\ cond)) {
+ \\ return x;
+ \\ }
+ \\ while ((cond and
+ \\ cond)) {
+ \\ return x;
+ \\ }
+ \\ var a = if (a) |*f| x: {
+ \\ break :x &a.b;
+ \\ } else |err| err;
+ \\}
+ ,
+ \\comptime {
+ \\ if (cond and
+ \\ cond)
+ \\ {
+ \\ return x;
+ \\ }
+ \\ while (cond and
+ \\ cond)
+ \\ {
+ \\ return x;
+ \\ }
+ \\ if (a == b and
+ \\ c)
+ \\ {
+ \\ a = b;
+ \\ }
+ \\ while (a == b and
+ \\ c)
+ \\ {
+ \\ a = b;
+ \\ }
+ \\ if ((cond and
+ \\ cond))
+ \\ {
+ \\ return x;
+ \\ }
+ \\ while ((cond and
+ \\ cond))
+ \\ {
+ \\ return x;
+ \\ }
+ \\ var a = if (a) |*f| x: {
+ \\ break :x &a.b;
+ \\ } else |err| err;
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: if condition has line break but must not wrap" {
+ try testCanonical(
+ \\comptime {
+ \\ if (self.user_input_options.put(name, UserInputOption{
+ \\ .name = name,
+ \\ .used = false,
+ \\ }) catch unreachable) |*prev_value| {
+ \\ foo();
+ \\ bar();
+ \\ }
+ \\ if (put(
+ \\ a,
+ \\ b,
+ \\ )) {
+ \\ foo();
+ \\ }
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: same-line doc comment on variable declaration" {
+ try testTransform(
+ \\pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space
+ \\pub const MAP_FILE = 0x0000; /// map from file (default)
+ \\
+ \\pub const EMEDIUMTYPE = 124; /// Wrong medium type
+ \\
+ \\// nameserver query return codes
+ \\pub const ENSROK = 0; /// DNS server returned answer with no data
+ ,
+ \\/// allocated from memory, swap space
+ \\pub const MAP_ANONYMOUS = 0x1000;
+ \\/// map from file (default)
+ \\pub const MAP_FILE = 0x0000;
+ \\
+ \\/// Wrong medium type
+ \\pub const EMEDIUMTYPE = 124;
+ \\
+ \\// nameserver query return codes
+ \\/// DNS server returned answer with no data
+ \\pub const ENSROK = 0;
+ \\
+ );
+}
+
+test "zig fmt: if-else with comment before else" {
+ try testCanonical(
+ \\comptime {
+ \\ // cexp(finite|nan +- i inf|nan) = nan + i nan
+ \\ if ((hx & 0x7fffffff) != 0x7f800000) {
+ \\ return Complex(f32).new(y - y, y - y);
+ \\ } // cexp(-inf +- i inf|nan) = 0 + i0
+ \\ else if (hx & 0x80000000 != 0) {
+ \\ return Complex(f32).new(0, 0);
+ \\ } // cexp(+inf +- i inf|nan) = inf + i nan
+ \\ else {
+ \\ return Complex(f32).new(x, y - y);
+ \\ }
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: respect line breaks in if-else" {
+ try testCanonical(
+ \\comptime {
+ \\ return if (cond) a else b;
+ \\ return if (cond)
+ \\ a
+ \\ else
+ \\ b;
+ \\ return if (cond)
+ \\ a
+ \\ else if (cond)
+ \\ b
+ \\ else
+ \\ c;
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: respect line breaks after infix operators" {
+ try testCanonical(
+ \\comptime {
+ \\ self.crc =
+ \\ lookup_tables[0][p[7]] ^
+ \\ lookup_tables[1][p[6]] ^
+ \\ lookup_tables[2][p[5]] ^
+ \\ lookup_tables[3][p[4]] ^
+ \\ lookup_tables[4][@truncate(u8, self.crc >> 24)] ^
+ \\ lookup_tables[5][@truncate(u8, self.crc >> 16)] ^
+ \\ lookup_tables[6][@truncate(u8, self.crc >> 8)] ^
+ \\ lookup_tables[7][@truncate(u8, self.crc >> 0)];
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: fn decl with trailing comma" {
+ try testTransform(
+ \\fn foo(a: i32, b: i32,) void {}
+ ,
+ \\fn foo(
+ \\ a: i32,
+ \\ b: i32,
+ \\) void {}
+ \\
+ );
+}
+
+test "zig fmt: enum decl with no trailing comma" {
+ try testTransform(
+ \\const StrLitKind = enum {Normal, C};
+ ,
+ \\const StrLitKind = enum {
+ \\ Normal,
+ \\ C,
+ \\};
+ \\
+ );
+}
+
+test "zig fmt: switch comment before prong" {
+ try testCanonical(
+ \\comptime {
+ \\ switch (a) {
+ \\ // hi
+ \\ 0 => {},
+ \\ }
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: struct literal no trailing comma" {
+ try testTransform(
+ \\const a = foo{ .x = 1, .y = 2 };
+ \\const a = foo{ .x = 1,
+ \\ .y = 2 };
+ ,
+ \\const a = foo{ .x = 1, .y = 2 };
+ \\const a = foo{
+ \\ .x = 1,
+ \\ .y = 2,
+ \\};
+ \\
+ );
+}
+
+test "zig fmt: array literal with hint" {
+ try testTransform(
+ \\const a = []u8{
+ \\ 1, 2, //
+ \\ 3,
+ \\ 4,
+ \\ 5,
+ \\ 6,
+ \\ 7 };
+ \\const a = []u8{
+ \\ 1, 2, //
+ \\ 3,
+ \\ 4,
+ \\ 5,
+ \\ 6,
+ \\ 7, 8 };
+ \\const a = []u8{
+ \\ 1, 2, //
+ \\ 3,
+ \\ 4,
+ \\ 5,
+ \\ 6, // blah
+ \\ 7, 8 };
+ \\const a = []u8{
+ \\ 1, 2, //
+ \\ 3, //
+ \\ 4,
+ \\ 5,
+ \\ 6,
+ \\ 7 };
+ \\const a = []u8{
+ \\ 1,
+ \\ 2,
+ \\ 3, 4, //
+ \\ 5, 6, //
+ \\ 7, 8, //
+ \\};
+ ,
+ \\const a = []u8{
+ \\ 1, 2,
+ \\ 3, 4,
+ \\ 5, 6,
+ \\ 7,
+ \\};
+ \\const a = []u8{
+ \\ 1, 2,
+ \\ 3, 4,
+ \\ 5, 6,
+ \\ 7, 8,
+ \\};
+ \\const a = []u8{
+ \\ 1, 2,
+ \\ 3, 4,
+ \\ 5, 6, // blah
+ \\ 7, 8,
+ \\};
+ \\const a = []u8{
+ \\ 1, 2,
+ \\ 3, //
+ \\ 4,
+ \\ 5, 6,
+ \\ 7,
+ \\};
+ \\const a = []u8{
+ \\ 1,
+ \\ 2,
+ \\ 3,
+ \\ 4,
+ \\ 5,
+ \\ 6,
+ \\ 7,
+ \\ 8,
+ \\};
+ \\
+ );
+}
+
+test "zig fmt: multiline string with backslash at end of line" {
+ try testCanonical(
+ \\comptime {
+ \\ err(
+ \\ \\\
+ \\ );
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: multiline string parameter in fn call with trailing comma" {
+ try testCanonical(
+ \\fn foo() void {
+ \\ try stdout.print(
+ \\ \\ZIG_CMAKE_BINARY_DIR {}
+ \\ \\ZIG_C_HEADER_FILES {}
+ \\ \\ZIG_DIA_GUIDS_LIB {}
+ \\ \\
+ \\ ,
+ \\ std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR),
+ \\ std.cstr.toSliceConst(c.ZIG_CXX_COMPILER),
+ \\ std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB),
+ \\ );
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: trailing comma on fn call" {
+ try testCanonical(
+ \\comptime {
+ \\ var module = try Module.create(
+ \\ allocator,
+ \\ zig_lib_dir,
+ \\ full_cache_dir,
+ \\ );
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: empty block with only comment" {
+ try testCanonical(
+ \\comptime {
+ \\ {
+ \\ // comment
+ \\ }
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: no trailing comma on struct decl" {
+ try testTransform(
+ \\const RoundParam = struct {
+ \\ k: usize, s: u32, t: u32
+ \\};
+ ,
+ \\const RoundParam = struct {
+ \\ k: usize,
+ \\ s: u32,
+ \\ t: u32,
+ \\};
+ \\
+ );
+}
+
+test "zig fmt: simple asm" {
+ try testTransform(
+ \\comptime {
+ \\ asm volatile (
+ \\ \\.globl aoeu;
+ \\ \\.type aoeu, @function;
+ \\ \\.set aoeu, derp;
+ \\ );
+ \\
+ \\ asm ("not real assembly"
+ \\ :[a] "x" (x),);
+ \\ asm ("not real assembly"
+ \\ :[a] "x" (->i32),:[a] "x" (1),);
+ \\ asm ("still not real assembly"
+ \\ :::"a","b",);
+ \\}
+ ,
+ \\comptime {
+ \\ asm volatile (
+ \\ \\.globl aoeu;
+ \\ \\.type aoeu, @function;
+ \\ \\.set aoeu, derp;
+ \\ );
+ \\
+ \\ asm ("not real assembly"
+ \\ : [a] "x" (x)
+ \\ );
+ \\ asm ("not real assembly"
+ \\ : [a] "x" (-> i32)
+ \\ : [a] "x" (1)
+ \\ );
+ \\ asm ("still not real assembly"
+ \\ :
+ \\ :
+ \\ : "a", "b"
+ \\ );
+ \\}
+ \\
+ );
+}
+
+test "zig fmt: nested struct literal with one item" {
+ try testCanonical(
+ \\const a = foo{
+ \\ .item = bar{ .a = b },
+ \\};
+ \\
+ );
+}
+
test "zig fmt: switch cases trailing comma" {
try testTransform(
\\fn switch_cases(x: i32) void {
\\ switch (x) {
\\ 1,2,3 => {},
\\ 4,5, => {},
- \\ 6...8, => {},
+ \\ 6... 8, => {},
\\ else => {},
\\ }
\\}
@@ -13,8 +430,9 @@ test "zig fmt: switch cases trailing comma" {
\\ switch (x) {
\\ 1, 2, 3 => {},
\\ 4,
- \\ 5, => {},
- \\ 6 ... 8 => {},
+ \\ 5,
+ \\ => {},
+ \\ 6...8 => {},
\\ else => {},
\\ }
\\}
@@ -36,16 +454,20 @@ test "zig fmt: add trailing comma to array literal" {
\\comptime {
\\ return []u16{'m', 's', 'y', 's', '-' // hi
\\ };
+ \\ return []u16{'m', 's', 'y', 's',
+ \\ '-'};
+ \\ return []u16{'m', 's', 'y', 's', '-'};
\\}
,
\\comptime {
\\ return []u16{
- \\ 'm',
- \\ 's',
- \\ 'y',
- \\ 's',
- \\ '-', // hi
+ \\ 'm', 's', 'y', 's', '-', // hi
\\ };
+ \\ return []u16{
+ \\ 'm', 's', 'y', 's',
+ \\ '-',
+ \\ };
+ \\ return []u16{ 'm', 's', 'y', 's', '-' };
\\}
\\
);
@@ -252,20 +674,6 @@ test "zig fmt: add comma on last switch prong" {
);
}
-test "zig fmt: same-line doc comment on variable declaration" {
- try testTransform(
- \\pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space
- \\pub const MAP_FILE = 0x0000; /// map from file (default)
- \\
- ,
- \\/// allocated from memory, swap space
- \\pub const MAP_ANONYMOUS = 0x1000;
- \\/// map from file (default)
- \\pub const MAP_FILE = 0x0000;
- \\
- );
-}
-
test "zig fmt: same-line comment after a statement" {
try testCanonical(
\\test "" {
@@ -1026,7 +1434,7 @@ test "zig fmt: switch" {
\\ 0 => {},
\\ 1 => unreachable,
\\ 2, 3 => {},
- \\ 4 ... 7 => {},
+ \\ 4...7 => {},
\\ 1 + 4 * 3 + 22 => {},
\\ else => {
\\ const a = 1;
@@ -1286,7 +1694,8 @@ test "zig fmt: inline asm" {
\\ : [ret] "={rax}" (-> usize)
\\ : [number] "{rax}" (number),
\\ [arg1] "{rdi}" (arg1)
- \\ : "rcx", "r11");
+ \\ : "rcx", "r11"
+ \\ );
\\}
\\
);
diff --git a/std/zig/render.zig b/std/zig/render.zig
index 4691d836c3..16aed808fc 100644
--- a/std/zig/render.zig
+++ b/std/zig/render.zig
@@ -19,7 +19,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf(
var tok_it = tree.tokens.iterator(0);
while (tok_it.next()) |token| {
if (token.id != Token.Id.LineComment) break;
- try stream.print("{}\n", tree.tokenSlicePtr(token));
+ try stream.print("{}\n", mem.trimRight(u8, tree.tokenSlicePtr(token), " "));
if (tok_it.peek()) |next_token| {
const loc = tree.tokenLocationPtr(token.end, next_token);
if (loc.line >= 2) {
@@ -28,41 +28,43 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf(
}
}
-
+ var start_col: usize = 0;
var it = tree.root_node.decls.iterator(0);
while (it.next()) |decl| {
- try renderTopLevelDecl(allocator, stream, tree, 0, decl.*);
+ try renderTopLevelDecl(allocator, stream, tree, 0, &start_col, decl.*);
if (it.peek()) |next_decl| {
- try renderExtraNewline(tree, stream, next_decl.*);
+ try renderExtraNewline(tree, stream, &start_col, next_decl.*);
}
}
}
-fn renderExtraNewline(tree: &ast.Tree, stream: var, node: &ast.Node) !void {
- var first_token = node.firstToken();
- while (tree.tokens.at(first_token - 1).id == Token.Id.DocComment) {
- first_token -= 1;
+fn renderExtraNewline(tree: &ast.Tree, stream: var, start_col: &usize, node: &ast.Node) !void {
+ const first_token = node.firstToken();
+ var prev_token = first_token;
+ while (tree.tokens.at(prev_token - 1).id == Token.Id.DocComment) {
+ prev_token -= 1;
}
- const prev_token_end = tree.tokens.at(first_token - 1).end;
+ const prev_token_end = tree.tokens.at(prev_token - 1).end;
const loc = tree.tokenLocation(prev_token_end, first_token);
if (loc.line >= 2) {
try stream.writeByte('\n');
+ start_col.* = 0;
}
}
-fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, decl: &ast.Node) (@typeOf(stream).Child.Error || Error)!void {
+fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, start_col: &usize, decl: &ast.Node) (@typeOf(stream).Child.Error || Error)!void {
switch (decl.id) {
ast.Node.Id.FnProto => {
const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);
- try renderDocComments(tree, stream, fn_proto, indent);
+ try renderDocComments(tree, stream, fn_proto, indent, start_col);
if (fn_proto.body_node) |body_node| {
- try renderExpression(allocator, stream, tree, indent, decl, Space.Space);
- try renderExpression(allocator, stream, tree, indent, body_node, Space.Newline);
+ try renderExpression(allocator, stream, tree, indent, start_col, decl, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, body_node, Space.Newline);
} else {
- try renderExpression(allocator, stream, tree, indent, decl, Space.None);
- try renderToken(tree, stream, tree.nextToken(decl.lastToken()), indent, Space.Newline);
+ try renderExpression(allocator, stream, tree, indent, start_col, decl, Space.None);
+ try renderToken(tree, stream, tree.nextToken(decl.lastToken()), indent, start_col, Space.Newline);
}
},
@@ -70,148 +72,154 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i
const use_decl = @fieldParentPtr(ast.Node.Use, "base", decl);
if (use_decl.visib_token) |visib_token| {
- try renderToken(tree, stream, visib_token, indent, Space.Space); // pub
+ try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
}
- try renderToken(tree, stream, use_decl.use_token, indent, Space.Space); // use
- try renderExpression(allocator, stream, tree, indent, use_decl.expr, Space.None);
- try renderToken(tree, stream, use_decl.semicolon_token, indent, Space.Newline); // ;
+ try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // use
+ try renderExpression(allocator, stream, tree, indent, start_col, use_decl.expr, Space.None);
+ try renderToken(tree, stream, use_decl.semicolon_token, indent, start_col, Space.Newline); // ;
},
ast.Node.Id.VarDecl => {
const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl);
- try renderDocComments(tree, stream, var_decl, indent);
- try renderVarDecl(allocator, stream, tree, indent, var_decl);
+ try renderDocComments(tree, stream, var_decl, indent, start_col);
+ try renderVarDecl(allocator, stream, tree, indent, start_col, var_decl);
},
ast.Node.Id.TestDecl => {
const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl);
- try renderDocComments(tree, stream, test_decl, indent);
- try renderToken(tree, stream, test_decl.test_token, indent, Space.Space);
- try renderExpression(allocator, stream, tree, indent, test_decl.name, Space.Space);
- try renderExpression(allocator, stream, tree, indent, test_decl.body_node, Space.Newline);
+ try renderDocComments(tree, stream, test_decl, indent, start_col);
+ try renderToken(tree, stream, test_decl.test_token, indent, start_col, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, test_decl.name, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, test_decl.body_node, Space.Newline);
},
ast.Node.Id.StructField => {
const field = @fieldParentPtr(ast.Node.StructField, "base", decl);
- try renderDocComments(tree, stream, field, indent);
+ try renderDocComments(tree, stream, field, indent, start_col);
if (field.visib_token) |visib_token| {
- try renderToken(tree, stream, visib_token, indent, Space.Space); // pub
+ try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
}
- try renderToken(tree, stream, field.name_token, indent, Space.None); // name
- try renderToken(tree, stream, tree.nextToken(field.name_token), indent, Space.Space); // :
- try renderExpression(allocator, stream, tree, indent, field.type_expr, Space.None); // type
- try renderToken(tree, stream, tree.nextToken(field.lastToken()), indent, Space.Newline); // ,
+ try renderToken(tree, stream, field.name_token, indent, start_col, Space.None); // name
+ try renderToken(tree, stream, tree.nextToken(field.name_token), indent, start_col, Space.Space); // :
+ try renderExpression(allocator, stream, tree, indent, start_col, field.type_expr, Space.Comma); // type,
},
ast.Node.Id.UnionTag => {
const tag = @fieldParentPtr(ast.Node.UnionTag, "base", decl);
- try renderDocComments(tree, stream, tag, indent);
-
- const name_space = if (tag.type_expr == null and tag.value_expr != null) Space.Space else Space.None;
- try renderToken(tree, stream, tag.name_token, indent, name_space); // name
+ try renderDocComments(tree, stream, tag, indent, start_col);
- if (tag.type_expr) |type_expr| {
- try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, Space.Space); // :
+ if (tag.type_expr == null and tag.value_expr == null) {
+ return renderToken(tree, stream, tag.name_token, indent, start_col, Space.Comma); // name,
+ }
- const after_type_space = if (tag.value_expr == null) Space.None else Space.Space;
- try renderExpression(allocator, stream, tree, indent, type_expr, after_type_space);
+ if (tag.type_expr == null) {
+ try renderToken(tree, stream, tag.name_token, indent, start_col, Space.Space); // name
+ } else {
+ try renderToken(tree, stream, tag.name_token, indent, start_col, Space.None); // name
}
- if (tag.value_expr) |value_expr| {
- try renderToken(tree, stream, tree.prevToken(value_expr.firstToken()), indent, Space.Space); // =
- try renderExpression(allocator, stream, tree, indent, value_expr, Space.None);
+ if (tag.type_expr) |type_expr| {
+ try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, start_col, Space.Space); // :
+
+ if (tag.value_expr == null) {
+ try renderExpression(allocator, stream, tree, indent, start_col, type_expr, Space.Comma); // type,
+ return;
+ } else {
+ try renderExpression(allocator, stream, tree, indent, start_col, type_expr, Space.Space); // type
+ }
}
- try renderToken(tree, stream, tree.nextToken(decl.lastToken()), indent, Space.Newline); // ,
+ const value_expr = ??tag.value_expr;
+ try renderToken(tree, stream, tree.prevToken(value_expr.firstToken()), indent, start_col, Space.Space); // =
+ try renderExpression(allocator, stream, tree, indent, start_col, value_expr, Space.Comma); // value,
},
ast.Node.Id.EnumTag => {
const tag = @fieldParentPtr(ast.Node.EnumTag, "base", decl);
- try renderDocComments(tree, stream, tag, indent);
-
- const after_name_space = if (tag.value == null) Space.None else Space.Space;
- try renderToken(tree, stream, tag.name_token, indent, after_name_space); // name
+ try renderDocComments(tree, stream, tag, indent, start_col);
if (tag.value) |value| {
- try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, Space.Space); // =
- try renderExpression(allocator, stream, tree, indent, value, Space.None);
- }
+ try renderToken(tree, stream, tag.name_token, indent, start_col, Space.Space); // name
- try renderToken(tree, stream, tree.nextToken(decl.lastToken()), indent, Space.Newline); // ,
+ try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, start_col, Space.Space); // =
+ try renderExpression(allocator, stream, tree, indent, start_col, value, Space.Comma);
+ } else {
+ try renderToken(tree, stream, tag.name_token, indent, start_col, Space.Comma); // name
+ }
},
ast.Node.Id.Comptime => {
assert(!decl.requireSemiColon());
- try renderExpression(allocator, stream, tree, indent, decl, Space.Newline);
+ try renderExpression(allocator, stream, tree, indent, start_col, decl, Space.Newline);
},
else => unreachable,
}
}
-fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node, space: Space) (@typeOf(stream).Child.Error || Error)!void {
+fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, start_col: &usize, base: &ast.Node, space: Space,) (@typeOf(stream).Child.Error || Error)!void {
switch (base.id) {
ast.Node.Id.Identifier => {
const identifier = @fieldParentPtr(ast.Node.Identifier, "base", base);
- try renderToken(tree, stream, identifier.token, indent, space);
+ return renderToken(tree, stream, identifier.token, indent, start_col, space);
},
ast.Node.Id.Block => {
const block = @fieldParentPtr(ast.Node.Block, "base", base);
if (block.label) |label| {
- try renderToken(tree, stream, label, indent, Space.None);
- try renderToken(tree, stream, tree.nextToken(label), indent, Space.Space);
+ try renderToken(tree, stream, label, indent, start_col, Space.None);
+ try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space);
}
if (block.statements.len == 0) {
- try renderToken(tree, stream, block.lbrace, indent + indent_delta, Space.None);
- try renderToken(tree, stream, block.rbrace, indent, space);
+ try renderToken(tree, stream, block.lbrace, indent + indent_delta, start_col, Space.None);
+ return renderToken(tree, stream, block.rbrace, indent, start_col, space);
} else {
const block_indent = indent + indent_delta;
- try renderToken(tree, stream, block.lbrace, block_indent, Space.Newline);
+ try renderToken(tree, stream, block.lbrace, block_indent, start_col, Space.Newline);
var it = block.statements.iterator(0);
while (it.next()) |statement| {
try stream.writeByteNTimes(' ', block_indent);
- try renderStatement(allocator, stream, tree, block_indent, statement.*);
+ try renderStatement(allocator, stream, tree, block_indent, start_col, statement.*);
if (it.peek()) |next_statement| {
- try renderExtraNewline(tree, stream, next_statement.*);
+ try renderExtraNewline(tree, stream, start_col, next_statement.*);
}
}
try stream.writeByteNTimes(' ', indent);
- try renderToken(tree, stream, block.rbrace, indent, space);
+ return renderToken(tree, stream, block.rbrace, indent, start_col, space);
}
},
ast.Node.Id.Defer => {
const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base);
- try renderToken(tree, stream, defer_node.defer_token, indent, Space.Space);
- try renderExpression(allocator, stream, tree, indent, defer_node.expr, space);
+ try renderToken(tree, stream, defer_node.defer_token, indent, start_col, Space.Space);
+ return renderExpression(allocator, stream, tree, indent, start_col, defer_node.expr, space);
},
ast.Node.Id.Comptime => {
const comptime_node = @fieldParentPtr(ast.Node.Comptime, "base", base);
- try renderToken(tree, stream, comptime_node.comptime_token, indent, Space.Space);
- try renderExpression(allocator, stream, tree, indent, comptime_node.expr, space);
+ try renderToken(tree, stream, comptime_node.comptime_token, indent, start_col, Space.Space);
+ return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);
},
ast.Node.Id.AsyncAttribute => {
const async_attr = @fieldParentPtr(ast.Node.AsyncAttribute, "base", base);
if (async_attr.allocator_type) |allocator_type| {
- try renderToken(tree, stream, async_attr.async_token, indent, Space.None);
+ try renderToken(tree, stream, async_attr.async_token, indent, start_col, Space.None);
- try renderToken(tree, stream, tree.nextToken(async_attr.async_token), indent, Space.None);
- try renderExpression(allocator, stream, tree, indent, allocator_type, Space.None);
- try renderToken(tree, stream, tree.nextToken(allocator_type.lastToken()), indent, space);
+ try renderToken(tree, stream, tree.nextToken(async_attr.async_token), indent, start_col, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, allocator_type, Space.None);
+ return renderToken(tree, stream, tree.nextToken(allocator_type.lastToken()), indent, start_col, space);
} else {
- try renderToken(tree, stream, async_attr.async_token, indent, space);
+ return renderToken(tree, stream, async_attr.async_token, indent, start_col, space);
}
},
@@ -219,24 +227,24 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base);
if (suspend_node.label) |label| {
- try renderToken(tree, stream, label, indent, Space.None);
- try renderToken(tree, stream, tree.nextToken(label), indent, Space.Space);
+ try renderToken(tree, stream, label, indent, start_col, Space.None);
+ try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space);
}
if (suspend_node.payload) |payload| {
if (suspend_node.body) |body| {
- try renderToken(tree, stream, suspend_node.suspend_token, indent, Space.Space);
- try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
- try renderExpression(allocator, stream, tree, indent, body, space);
+ try renderToken(tree, stream, suspend_node.suspend_token, indent, start_col, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
+ return renderExpression(allocator, stream, tree, indent, start_col, body, space);
} else {
- try renderToken(tree, stream, suspend_node.suspend_token, indent, Space.Space);
- try renderExpression(allocator, stream, tree, indent, payload, space);
+ try renderToken(tree, stream, suspend_node.suspend_token, indent, start_col, Space.Space);
+ return renderExpression(allocator, stream, tree, indent, start_col, payload, space);
}
} else if (suspend_node.body) |body| {
- try renderToken(tree, stream, suspend_node.suspend_token, indent, Space.Space);
- try renderExpression(allocator, stream, tree, indent, body, space);
+ try renderToken(tree, stream, suspend_node.suspend_token, indent, start_col, Space.Space);
+ return renderExpression(allocator, stream, tree, indent, start_col, body, space);
} else {
- try renderToken(tree, stream, suspend_node.suspend_token, indent, space);
+ return renderToken(tree, stream, suspend_node.suspend_token, indent, start_col, space);
}
},
@@ -245,20 +253,31 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
const op_token = tree.tokens.at(infix_op_node.op_token);
const op_space = switch (infix_op_node.op) {
- ast.Node.InfixOp.Op.Period, ast.Node.InfixOp.Op.ErrorUnion => Space.None,
+ ast.Node.InfixOp.Op.Period, ast.Node.InfixOp.Op.ErrorUnion, ast.Node.InfixOp.Op.Range => Space.None,
else => Space.Space,
};
- try renderExpression(allocator, stream, tree, indent, infix_op_node.lhs, op_space);
- try renderToken(tree, stream, infix_op_node.op_token, indent, op_space);
+ try renderExpression(allocator, stream, tree, indent, start_col, infix_op_node.lhs, op_space);
+
+ const after_op_space = blk: {
+ const loc = tree.tokenLocation(tree.tokens.at(infix_op_node.op_token).end,
+ tree.nextToken(infix_op_node.op_token));
+ break :blk if (loc.line == 0) op_space else Space.Newline;
+ };
+
+ try renderToken(tree, stream, infix_op_node.op_token, indent, start_col, after_op_space);
+ if (after_op_space == Space.Newline) {
+ try stream.writeByteNTimes(' ', indent + indent_delta);
+ start_col.* = indent + indent_delta;
+ }
switch (infix_op_node.op) {
ast.Node.InfixOp.Op.Catch => |maybe_payload| if (maybe_payload) |payload| {
- try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
},
else => {},
}
- try renderExpression(allocator, stream, tree, indent, infix_op_node.rhs, space);
+ return renderExpression(allocator, stream, tree, indent, start_col, infix_op_node.rhs, space);
},
ast.Node.Id.PrefixOp => {
@@ -266,81 +285,81 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
switch (prefix_op_node.op) {
ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| {
- try renderToken(tree, stream, prefix_op_node.op_token, indent, Space.None); // &
+ try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None); // &
if (addr_of_info.align_info) |align_info| {
const lparen_token = tree.prevToken(align_info.node.firstToken());
const align_token = tree.prevToken(lparen_token);
- try renderToken(tree, stream, align_token, indent, Space.None); // align
- try renderToken(tree, stream, lparen_token, indent, Space.None); // (
+ try renderToken(tree, stream, align_token, indent, start_col, Space.None); // align
+ try renderToken(tree, stream, lparen_token, indent, start_col, Space.None); // (
- try renderExpression(allocator, stream, tree, indent, align_info.node, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, align_info.node, Space.None);
if (align_info.bit_range) |bit_range| {
const colon1 = tree.prevToken(bit_range.start.firstToken());
const colon2 = tree.prevToken(bit_range.end.firstToken());
- try renderToken(tree, stream, colon1, indent, Space.None); // :
- try renderExpression(allocator, stream, tree, indent, bit_range.start, Space.None);
- try renderToken(tree, stream, colon2, indent, Space.None); // :
- try renderExpression(allocator, stream, tree, indent, bit_range.end, Space.None);
+ try renderToken(tree, stream, colon1, indent, start_col, Space.None); // :
+ try renderExpression(allocator, stream, tree, indent, start_col, bit_range.start, Space.None);
+ try renderToken(tree, stream, colon2, indent, start_col, Space.None); // :
+ try renderExpression(allocator, stream, tree, indent, start_col, bit_range.end, Space.None);
const rparen_token = tree.nextToken(bit_range.end.lastToken());
- try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
+ try renderToken(tree, stream, rparen_token, indent, start_col, Space.Space); // )
} else {
const rparen_token = tree.nextToken(align_info.node.lastToken());
- try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
+ try renderToken(tree, stream, rparen_token, indent, start_col, Space.Space); // )
}
}
if (addr_of_info.const_token) |const_token| {
- try renderToken(tree, stream, const_token, indent, Space.Space); // const
+ try renderToken(tree, stream, const_token, indent, start_col, Space.Space); // const
}
if (addr_of_info.volatile_token) |volatile_token| {
- try renderToken(tree, stream, volatile_token, indent, Space.Space); // volatile
+ try renderToken(tree, stream, volatile_token, indent, start_col, Space.Space); // volatile
}
},
ast.Node.PrefixOp.Op.SliceType => |addr_of_info| {
- try renderToken(tree, stream, prefix_op_node.op_token, indent, Space.None); // [
- try renderToken(tree, stream, tree.nextToken(prefix_op_node.op_token), indent, Space.None); // ]
+ try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None); // [
+ try renderToken(tree, stream, tree.nextToken(prefix_op_node.op_token), indent, start_col, Space.None); // ]
if (addr_of_info.align_info) |align_info| {
const lparen_token = tree.prevToken(align_info.node.firstToken());
const align_token = tree.prevToken(lparen_token);
- try renderToken(tree, stream, align_token, indent, Space.None); // align
- try renderToken(tree, stream, lparen_token, indent, Space.None); // (
+ try renderToken(tree, stream, align_token, indent, start_col, Space.None); // align
+ try renderToken(tree, stream, lparen_token, indent, start_col, Space.None); // (
- try renderExpression(allocator, stream, tree, indent, align_info.node, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, align_info.node, Space.None);
if (align_info.bit_range) |bit_range| {
const colon1 = tree.prevToken(bit_range.start.firstToken());
const colon2 = tree.prevToken(bit_range.end.firstToken());
- try renderToken(tree, stream, colon1, indent, Space.None); // :
- try renderExpression(allocator, stream, tree, indent, bit_range.start, Space.None);
- try renderToken(tree, stream, colon2, indent, Space.None); // :
- try renderExpression(allocator, stream, tree, indent, bit_range.end, Space.None);
+ try renderToken(tree, stream, colon1, indent, start_col, Space.None); // :
+ try renderExpression(allocator, stream, tree, indent, start_col, bit_range.start, Space.None);
+ try renderToken(tree, stream, colon2, indent, start_col, Space.None); // :
+ try renderExpression(allocator, stream, tree, indent, start_col, bit_range.end, Space.None);
const rparen_token = tree.nextToken(bit_range.end.lastToken());
- try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
+ try renderToken(tree, stream, rparen_token, indent, start_col, Space.Space); // )
} else {
const rparen_token = tree.nextToken(align_info.node.lastToken());
- try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
+ try renderToken(tree, stream, rparen_token, indent, start_col, Space.Space); // )
}
}
if (addr_of_info.const_token) |const_token| {
- try renderToken(tree, stream, const_token, indent, Space.Space);
+ try renderToken(tree, stream, const_token, indent, start_col, Space.Space);
}
if (addr_of_info.volatile_token) |volatile_token| {
- try renderToken(tree, stream, volatile_token, indent, Space.Space);
+ try renderToken(tree, stream, volatile_token, indent, start_col, Space.Space);
}
},
ast.Node.PrefixOp.Op.ArrayType => |array_index| {
- try renderToken(tree, stream, prefix_op_node.op_token, indent, Space.None); // [
- try renderExpression(allocator, stream, tree, indent, array_index, Space.None);
- try renderToken(tree, stream, tree.nextToken(array_index.lastToken()), indent, Space.None); // ]
+ try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None); // [
+ try renderExpression(allocator, stream, tree, indent, start_col, array_index, Space.None);
+ try renderToken(tree, stream, tree.nextToken(array_index.lastToken()), indent, start_col, Space.None); // ]
},
ast.Node.PrefixOp.Op.BitNot,
ast.Node.PrefixOp.Op.BoolNot,
@@ -349,18 +368,18 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
ast.Node.PrefixOp.Op.UnwrapMaybe,
ast.Node.PrefixOp.Op.MaybeType,
ast.Node.PrefixOp.Op.PointerType => {
- try renderToken(tree, stream, prefix_op_node.op_token, indent, Space.None);
+ try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None);
},
ast.Node.PrefixOp.Op.Try,
ast.Node.PrefixOp.Op.Await,
ast.Node.PrefixOp.Op.Cancel,
ast.Node.PrefixOp.Op.Resume => {
- try renderToken(tree, stream, prefix_op_node.op_token, indent, Space.Space);
+ try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space);
},
}
- try renderExpression(allocator, stream, tree, indent, prefix_op_node.rhs, space);
+ return renderExpression(allocator, stream, tree, indent, start_col, prefix_op_node.rhs, space);
},
ast.Node.Id.SuffixOp => {
@@ -369,80 +388,152 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
switch (suffix_op.op) {
@TagType(ast.Node.SuffixOp.Op).Call => |*call_info| {
if (call_info.async_attr) |async_attr| {
- try renderExpression(allocator, stream, tree, indent, &async_attr.base, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, &async_attr.base, Space.Space);
}
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
const lparen = tree.nextToken(suffix_op.lhs.lastToken());
- try renderToken(tree, stream, lparen, indent, Space.None);
+
+ if (call_info.params.len == 0) {
+ try renderToken(tree, stream, lparen, indent, start_col, Space.None);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
+ }
+
+ const src_has_trailing_comma = blk: {
+ const maybe_comma = tree.prevToken(suffix_op.rtoken);
+ break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
+ };
+
+ if (src_has_trailing_comma) {
+ const new_indent = indent + indent_delta;
+ try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline);
+
+ var it = call_info.params.iterator(0);
+ while (true) {
+ const param_node = ??it.next();
+
+ const param_node_new_indent = if (param_node.*.id == ast.Node.Id.MultilineStringLiteral) blk: {
+ break :blk indent;
+ } else blk: {
+ try stream.writeByteNTimes(' ', new_indent);
+ break :blk new_indent;
+ };
+
+ if (it.peek()) |next_node| {
+ try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node.*, Space.None);
+ const comma = tree.nextToken(param_node.*.lastToken());
+ try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,
+ try renderExtraNewline(tree, stream, start_col, next_node.*);
+ } else {
+ try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node.*, Space.Comma);
+ try stream.writeByteNTimes(' ', indent);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
+ }
+ }
+ }
+
+ try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
var it = call_info.params.iterator(0);
while (it.next()) |param_node| {
- try renderExpression(allocator, stream, tree, indent, param_node.*, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.None);
if (it.peek() != null) {
const comma = tree.nextToken(param_node.*.lastToken());
- try renderToken(tree, stream, comma, indent, Space.Space);
+ try renderToken(tree, stream, comma, indent, start_col, Space.Space);
}
}
-
- try renderToken(tree, stream, suffix_op.rtoken, indent, space);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
},
ast.Node.SuffixOp.Op.ArrayAccess => |index_expr| {
const lbracket = tree.prevToken(index_expr.firstToken());
const rbracket = tree.nextToken(index_expr.lastToken());
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
- try renderToken(tree, stream, lbracket, indent, Space.None); // [
- try renderExpression(allocator, stream, tree, indent, index_expr, Space.None);
- try renderToken(tree, stream, rbracket, indent, space); // ]
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
+ try renderExpression(allocator, stream, tree, indent, start_col, index_expr, Space.None);
+ return renderToken(tree, stream, rbracket, indent, start_col, space); // ]
},
ast.Node.SuffixOp.Op.Deref => {
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
- try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, Space.None); // .
- try renderToken(tree, stream, suffix_op.rtoken, indent, space); // *
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, start_col, Space.None); // .
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // *
},
@TagType(ast.Node.SuffixOp.Op).Slice => |range| {
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
const lbracket = tree.prevToken(range.start.firstToken());
const dotdot = tree.nextToken(range.start.lastToken());
- try renderToken(tree, stream, lbracket, indent, Space.None); // [
- try renderExpression(allocator, stream, tree, indent, range.start, Space.None);
- try renderToken(tree, stream, dotdot, indent, Space.None); // ..
+ try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
+ try renderExpression(allocator, stream, tree, indent, start_col, range.start, Space.None);
+ try renderToken(tree, stream, dotdot, indent, start_col, Space.None); // ..
if (range.end) |end| {
- try renderExpression(allocator, stream, tree, indent, end, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, end, Space.None);
}
- try renderToken(tree, stream, suffix_op.rtoken, indent, space); // ]
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ]
},
ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {
const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
if (field_inits.len == 0) {
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
- try renderToken(tree, stream, lbrace, indent, Space.None);
- try renderToken(tree, stream, suffix_op.rtoken, indent, space);
- return;
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
}
- if (field_inits.len == 1) {
- const field_init = field_inits.at(0).*;
+ if (field_inits.len == 1) blk: {
+ const field_init = ??field_inits.at(0).*.cast(ast.Node.FieldInitializer);
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
- try renderToken(tree, stream, lbrace, indent, Space.Space);
- try renderExpression(allocator, stream, tree, indent, field_init, Space.Space);
- try renderToken(tree, stream, suffix_op.rtoken, indent, space);
- return;
+ if (field_init.expr.cast(ast.Node.SuffixOp)) |nested_suffix_op| {
+ if (nested_suffix_op.op == ast.Node.SuffixOp.Op.StructInitializer) {
+ break :blk;
+ }
+ }
+
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
}
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
- try renderToken(tree, stream, lbrace, indent, Space.Newline);
+ const src_has_trailing_comma = blk: {
+ const maybe_comma = tree.prevToken(suffix_op.rtoken);
+ break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
+ };
+
+ const src_same_line = blk: {
+ const loc = tree.tokenLocation(tree.tokens.at(lbrace).end, suffix_op.rtoken);
+ break :blk loc.line == 0;
+ };
+
+ if (!src_has_trailing_comma and src_same_line) {
+ // render all on one line, no trailing comma
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
+
+ var it = field_inits.iterator(0);
+ while (it.next()) |field_init| {
+ if (it.peek() != null) {
+ try renderExpression(allocator, stream, tree, indent, start_col, field_init.*, Space.None);
+
+ const comma = tree.nextToken(field_init.*.lastToken());
+ try renderToken(tree, stream, comma, indent, start_col, Space.Space);
+ } else {
+ try renderExpression(allocator, stream, tree, indent, start_col, field_init.*, Space.Space);
+ }
+ }
+
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
+ }
+
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline);
const new_indent = indent + indent_delta;
@@ -451,63 +542,116 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
try stream.writeByteNTimes(' ', new_indent);
if (it.peek()) |next_field_init| {
- try renderExpression(allocator, stream, tree, new_indent, field_init.*, Space.None);
+ try renderExpression(allocator, stream, tree, new_indent, start_col, field_init.*, Space.None);
const comma = tree.nextToken(field_init.*.lastToken());
- try renderToken(tree, stream, comma, new_indent, Space.Newline);
+ try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline);
- try renderExtraNewline(tree, stream, next_field_init.*);
+ try renderExtraNewline(tree, stream, start_col, next_field_init.*);
} else {
- try renderTrailingComma(allocator, stream, tree, new_indent, field_init.*, Space.Newline);
+ try renderExpression(allocator, stream, tree, new_indent, start_col, field_init.*, Space.Comma);
}
}
try stream.writeByteNTimes(' ', indent);
- try renderToken(tree, stream, suffix_op.rtoken, indent, space);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
},
ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {
const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
if (exprs.len == 0) {
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
- try renderToken(tree, stream, lbrace, indent, Space.None);
- try renderToken(tree, stream, suffix_op.rtoken, indent, space);
- return;
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
}
if (exprs.len == 1) {
const expr = exprs.at(0).*;
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
- try renderToken(tree, stream, lbrace, indent, Space.None);
- try renderExpression(allocator, stream, tree, indent, expr, Space.None);
- try renderToken(tree, stream, suffix_op.rtoken, indent, space);
- return;
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
}
- try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None);
-
- const new_indent = indent + indent_delta;
- try renderToken(tree, stream, lbrace, new_indent, Space.Newline);
+ try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
+
+ // scan to find row size
+ const maybe_row_size: ?usize = blk: {
+ var count: usize = 1;
+ var it = exprs.iterator(0);
+ while (true) {
+ const expr = (??it.next()).*;
+ if (it.peek()) |next_expr| {
+ const expr_last_token = expr.*.lastToken() + 1;
+ const loc = tree.tokenLocation(tree.tokens.at(expr_last_token).end, next_expr.*.firstToken());
+ if (loc.line != 0) break :blk count;
+ count += 1;
+ } else {
+ const expr_last_token = expr.*.lastToken();
+ const loc = tree.tokenLocation(tree.tokens.at(expr_last_token).end, suffix_op.rtoken);
+ if (loc.line == 0) {
+ // all on one line
+ const src_has_trailing_comma = trailblk: {
+ const maybe_comma = tree.prevToken(suffix_op.rtoken);
+ break :trailblk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
+ };
+ if (src_has_trailing_comma) {
+ break :blk 1; // force row size 1
+ } else {
+ break :blk null; // no newlines
+ }
+ }
+ break :blk count;
+ }
+ }
+ };
- var it = exprs.iterator(0);
- while (it.next()) |expr| {
+ if (maybe_row_size) |row_size| {
+ const new_indent = indent + indent_delta;
+ try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
try stream.writeByteNTimes(' ', new_indent);
- if (it.peek()) |next_expr| {
- try renderExpression(allocator, stream, tree, new_indent, expr.*, Space.None);
+ var it = exprs.iterator(0);
+ var i: usize = 1;
+ while (it.next()) |expr| {
+ if (it.peek()) |next_expr| {
+ try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.None);
- const comma = tree.nextToken(expr.*.lastToken());
- try renderToken(tree, stream, comma, new_indent, Space.Newline); // ,
+ const comma = tree.nextToken(expr.*.lastToken());
- try renderExtraNewline(tree, stream, next_expr.*);
- } else {
- try renderTrailingComma(allocator, stream, tree, new_indent, expr.*, Space.Newline);
+ if (i != row_size) {
+ try renderToken(tree, stream, comma, new_indent, start_col, Space.Space); // ,
+ i += 1;
+ continue;
+ }
+ i = 1;
+
+ try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,
+
+ try renderExtraNewline(tree, stream, start_col, next_expr.*);
+ try stream.writeByteNTimes(' ', new_indent);
+ } else {
+ try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // ,
+ }
+ }
+ try stream.writeByteNTimes(' ', indent);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
+ } else {
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
+ var it = exprs.iterator(0);
+ while (it.next()) |expr| {
+ if (it.peek()) |next_expr| {
+ try renderExpression(allocator, stream, tree, indent, start_col, expr.*, Space.None);
+ const comma = tree.nextToken(expr.*.lastToken());
+ try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,
+ } else {
+ try renderExpression(allocator, stream, tree, indent, start_col, expr.*, Space.Space);
+ }
}
- }
- try stream.writeByteNTimes(' ', indent);
- try renderToken(tree, stream, suffix_op.rtoken, indent, space);
+ return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
+ }
},
}
},
@@ -517,195 +661,204 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
switch (flow_expr.kind) {
ast.Node.ControlFlowExpression.Kind.Break => |maybe_label| {
- const kw_space = if (maybe_label != null or flow_expr.rhs != null) Space.Space else space;
- try renderToken(tree, stream, flow_expr.ltoken, indent, kw_space);
+ if (maybe_label == null and flow_expr.rhs == null) {
+ return renderToken(tree, stream, flow_expr.ltoken, indent, start_col, space); // break
+ }
+
+ try renderToken(tree, stream, flow_expr.ltoken, indent, start_col, Space.Space); // break
if (maybe_label) |label| {
const colon = tree.nextToken(flow_expr.ltoken);
- try renderToken(tree, stream, colon, indent, Space.None);
+ try renderToken(tree, stream, colon, indent, start_col, Space.None); // :
- const expr_space = if (flow_expr.rhs != null) Space.Space else space;
- try renderExpression(allocator, stream, tree, indent, label, expr_space);
+ if (flow_expr.rhs == null) {
+ return renderExpression(allocator, stream, tree, indent, start_col, label, space); // label
+ }
+ try renderExpression(allocator, stream, tree, indent, start_col, label, Space.Space); // label
}
},
ast.Node.ControlFlowExpression.Kind.Continue => |maybe_label| {
- const kw_space = if (maybe_label != null or flow_expr.rhs != null) Space.Space else space;
- try renderToken(tree, stream, flow_expr.ltoken, indent, kw_space);
+ assert(flow_expr.rhs == null);
+
+ if (maybe_label == null and flow_expr.rhs == null) {
+ return renderToken(tree, stream, flow_expr.ltoken, indent, start_col, space); // continue
+ }
+
+ try renderToken(tree, stream, flow_expr.ltoken, indent, start_col, Space.Space); // continue
if (maybe_label) |label| {
const colon = tree.nextToken(flow_expr.ltoken);
- try renderToken(tree, stream, colon, indent, Space.None);
+ try renderToken(tree, stream, colon, indent, start_col, Space.None); // :
- const expr_space = if (flow_expr.rhs != null) Space.Space else space;
- try renderExpression(allocator, stream, tree, indent, label, space);
+ return renderExpression(allocator, stream, tree, indent, start_col, label, space);
}
},
ast.Node.ControlFlowExpression.Kind.Return => {
- const kw_space = if (flow_expr.rhs != null) Space.Space else space;
- try renderToken(tree, stream, flow_expr.ltoken, indent, kw_space);
+ if (flow_expr.rhs == null) {
+ return renderToken(tree, stream, flow_expr.ltoken, indent, start_col, space);
+ }
+ try renderToken(tree, stream, flow_expr.ltoken, indent, start_col, Space.Space);
},
}
- if (flow_expr.rhs) |rhs| {
- try renderExpression(allocator, stream, tree, indent, rhs, space);
- }
+ return renderExpression(allocator, stream, tree, indent, start_col, ??flow_expr.rhs, space);
},
ast.Node.Id.Payload => {
const payload = @fieldParentPtr(ast.Node.Payload, "base", base);
- try renderToken(tree, stream, payload.lpipe, indent, Space.None);
- try renderExpression(allocator, stream, tree, indent, payload.error_symbol, Space.None);
- try renderToken(tree, stream, payload.rpipe, indent, space);
+ try renderToken(tree, stream, payload.lpipe, indent, start_col, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, payload.error_symbol, Space.None);
+ return renderToken(tree, stream, payload.rpipe, indent, start_col, space);
},
ast.Node.Id.PointerPayload => {
const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base);
- try renderToken(tree, stream, payload.lpipe, indent, Space.None);
+ try renderToken(tree, stream, payload.lpipe, indent, start_col, Space.None);
if (payload.ptr_token) |ptr_token| {
- try renderToken(tree, stream, ptr_token, indent, Space.None);
+ try renderToken(tree, stream, ptr_token, indent, start_col, Space.None);
}
- try renderExpression(allocator, stream, tree, indent, payload.value_symbol, Space.None);
- try renderToken(tree, stream, payload.rpipe, indent, space);
+ try renderExpression(allocator, stream, tree, indent, start_col, payload.value_symbol, Space.None);
+ return renderToken(tree, stream, payload.rpipe, indent, start_col, space);
},
ast.Node.Id.PointerIndexPayload => {
const payload = @fieldParentPtr(ast.Node.PointerIndexPayload, "base", base);
- try renderToken(tree, stream, payload.lpipe, indent, Space.None);
+ try renderToken(tree, stream, payload.lpipe, indent, start_col, Space.None);
if (payload.ptr_token) |ptr_token| {
- try renderToken(tree, stream, ptr_token, indent, Space.None);
+ try renderToken(tree, stream, ptr_token, indent, start_col, Space.None);
}
- try renderExpression(allocator, stream, tree, indent, payload.value_symbol, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, payload.value_symbol, Space.None);
if (payload.index_symbol) |index_symbol| {
const comma = tree.nextToken(payload.value_symbol.lastToken());
- try renderToken(tree, stream, comma, indent, Space.Space);
- try renderExpression(allocator, stream, tree, indent, index_symbol, Space.None);
+ try renderToken(tree, stream, comma, indent, start_col, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, index_symbol, Space.None);
}
- try renderToken(tree, stream, payload.rpipe, indent, space);
+ return renderToken(tree, stream, payload.rpipe, indent, start_col, space);
},
ast.Node.Id.GroupedExpression => {
const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base);
- try renderToken(tree, stream, grouped_expr.lparen, indent, Space.None);
- try renderExpression(allocator, stream, tree, indent, grouped_expr.expr, Space.None);
- try renderToken(tree, stream, grouped_expr.rparen, indent, space);
+ try renderToken(tree, stream, grouped_expr.lparen, indent, start_col, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, grouped_expr.expr, Space.None);
+ return renderToken(tree, stream, grouped_expr.rparen, indent, start_col, space);
},
ast.Node.Id.FieldInitializer => {
const field_init = @fieldParentPtr(ast.Node.FieldInitializer, "base", base);
- try renderToken(tree, stream, field_init.period_token, indent, Space.None); // .
- try renderToken(tree, stream, field_init.name_token, indent, Space.Space); // name
- try renderToken(tree, stream, tree.nextToken(field_init.name_token), indent, Space.Space); // =
- try renderExpression(allocator, stream, tree, indent, field_init.expr, space);
+ try renderToken(tree, stream, field_init.period_token, indent, start_col, Space.None); // .
+ try renderToken(tree, stream, field_init.name_token, indent, start_col, Space.Space); // name
+ try renderToken(tree, stream, tree.nextToken(field_init.name_token), indent, start_col, Space.Space); // =
+ return renderExpression(allocator, stream, tree, indent, start_col, field_init.expr, space);
},
ast.Node.Id.IntegerLiteral => {
const integer_literal = @fieldParentPtr(ast.Node.IntegerLiteral, "base", base);
- try renderToken(tree, stream, integer_literal.token, indent, space);
+ return renderToken(tree, stream, integer_literal.token, indent, start_col, space);
},
ast.Node.Id.FloatLiteral => {
const float_literal = @fieldParentPtr(ast.Node.FloatLiteral, "base", base);
- try renderToken(tree, stream, float_literal.token, indent, space);
+ return renderToken(tree, stream, float_literal.token, indent, start_col, space);
},
ast.Node.Id.StringLiteral => {
const string_literal = @fieldParentPtr(ast.Node.StringLiteral, "base", base);
- try renderToken(tree, stream, string_literal.token, indent, space);
+ return renderToken(tree, stream, string_literal.token, indent, start_col, space);
},
ast.Node.Id.CharLiteral => {
const char_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
- try renderToken(tree, stream, char_literal.token, indent, space);
+ return renderToken(tree, stream, char_literal.token, indent, start_col, space);
},
ast.Node.Id.BoolLiteral => {
const bool_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
- try renderToken(tree, stream, bool_literal.token, indent, space);
+ return renderToken(tree, stream, bool_literal.token, indent, start_col, space);
},
ast.Node.Id.NullLiteral => {
const null_literal = @fieldParentPtr(ast.Node.NullLiteral, "base", base);
- try renderToken(tree, stream, null_literal.token, indent, space);
+ return renderToken(tree, stream, null_literal.token, indent, start_col, space);
},
ast.Node.Id.ThisLiteral => {
const this_literal = @fieldParentPtr(ast.Node.ThisLiteral, "base", base);
- try renderToken(tree, stream, this_literal.token, indent, space);
+ return renderToken(tree, stream, this_literal.token, indent, start_col, space);
},
ast.Node.Id.Unreachable => {
const unreachable_node = @fieldParentPtr(ast.Node.Unreachable, "base", base);
- try renderToken(tree, stream, unreachable_node.token, indent, space);
+ return renderToken(tree, stream, unreachable_node.token, indent, start_col, space);
},
ast.Node.Id.ErrorType => {
const error_type = @fieldParentPtr(ast.Node.ErrorType, "base", base);
- try renderToken(tree, stream, error_type.token, indent, space);
+ return renderToken(tree, stream, error_type.token, indent, start_col, space);
},
ast.Node.Id.VarType => {
const var_type = @fieldParentPtr(ast.Node.VarType, "base", base);
- try renderToken(tree, stream, var_type.token, indent, space);
+ return renderToken(tree, stream, var_type.token, indent, start_col, space);
},
ast.Node.Id.ContainerDecl => {
const container_decl = @fieldParentPtr(ast.Node.ContainerDecl, "base", base);
if (container_decl.layout_token) |layout_token| {
- try renderToken(tree, stream, layout_token, indent, Space.Space);
+ try renderToken(tree, stream, layout_token, indent, start_col, Space.Space);
}
switch (container_decl.init_arg_expr) {
ast.Node.ContainerDecl.InitArg.None => {
- try renderToken(tree, stream, container_decl.kind_token, indent, Space.Space); // union
+ try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.Space); // union
},
ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {
- try renderToken(tree, stream, container_decl.kind_token, indent, Space.None); // union
+ try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
const lparen = tree.nextToken(container_decl.kind_token);
const enum_token = tree.nextToken(lparen);
- try renderToken(tree, stream, lparen, indent, Space.None); // (
- try renderToken(tree, stream, enum_token, indent, Space.None); // enum
+ try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
+ try renderToken(tree, stream, enum_token, indent, start_col, Space.None); // enum
if (enum_tag_type) |expr| {
- try renderToken(tree, stream, tree.nextToken(enum_token), indent, Space.None); // (
- try renderExpression(allocator, stream, tree, indent, expr, Space.None);
+ try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.None); // (
+ try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
const rparen = tree.nextToken(expr.lastToken());
- try renderToken(tree, stream, rparen, indent, Space.None); // )
- try renderToken(tree, stream, tree.nextToken(rparen), indent, Space.Space); // )
+ try renderToken(tree, stream, rparen, indent, start_col, Space.None); // )
+ try renderToken(tree, stream, tree.nextToken(rparen), indent, start_col, Space.Space); // )
} else {
- try renderToken(tree, stream, tree.nextToken(enum_token), indent, Space.Space); // )
+ try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.Space); // )
}
},
ast.Node.ContainerDecl.InitArg.Type => |type_expr| {
- try renderToken(tree, stream, container_decl.kind_token, indent, Space.None); // union
+ try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
const lparen = tree.nextToken(container_decl.kind_token);
const rparen = tree.nextToken(type_expr.lastToken());
- try renderToken(tree, stream, lparen, indent, Space.None); // (
- try renderExpression(allocator, stream, tree, indent, type_expr, Space.None);
- try renderToken(tree, stream, rparen, indent, Space.Space); // )
+ try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
+ try renderExpression(allocator, stream, tree, indent, start_col, type_expr, Space.None);
+ try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
},
}
if (container_decl.fields_and_decls.len == 0) {
- try renderToken(tree, stream, container_decl.lbrace_token, indent + indent_delta, Space.None); // {
- try renderToken(tree, stream, container_decl.rbrace_token, indent, space); // }
+ try renderToken(tree, stream, container_decl.lbrace_token, indent + indent_delta, start_col, Space.None); // {
+ return renderToken(tree, stream, container_decl.rbrace_token, indent, start_col, space); // }
} else {
const new_indent = indent + indent_delta;
- try renderToken(tree, stream, container_decl.lbrace_token, new_indent, Space.Newline); // {
+ try renderToken(tree, stream, container_decl.lbrace_token, new_indent, start_col, Space.Newline); // {
var it = container_decl.fields_and_decls.iterator(0);
while (it.next()) |decl| {
try stream.writeByteNTimes(' ', new_indent);
- try renderTopLevelDecl(allocator, stream, tree, new_indent, decl.*);
+ try renderTopLevelDecl(allocator, stream, tree, new_indent, start_col, decl.*);
if (it.peek()) |next_decl| {
- try renderExtraNewline(tree, stream, next_decl.*);
+ try renderExtraNewline(tree, stream, start_col, next_decl.*);
}
}
try stream.writeByteNTimes(' ', indent);
- try renderToken(tree, stream, container_decl.rbrace_token, indent, space); // }
+ return renderToken(tree, stream, container_decl.rbrace_token, indent, start_col, space); // }
}
},
@@ -715,10 +868,9 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
const lbrace = tree.nextToken(err_set_decl.error_token);
if (err_set_decl.decls.len == 0) {
- try renderToken(tree, stream, err_set_decl.error_token, indent, Space.None);
- try renderToken(tree, stream, lbrace, indent, Space.None);
- try renderToken(tree, stream, err_set_decl.rbrace_token, indent, space);
- return;
+ try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None);
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
+ return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space);
}
if (err_set_decl.decls.len == 1) blk: {
@@ -732,15 +884,14 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
break :blk;
}
- try renderToken(tree, stream, err_set_decl.error_token, indent, Space.None); // error
- try renderToken(tree, stream, lbrace, indent, Space.None); // {
- try renderExpression(allocator, stream, tree, indent, node, Space.None);
- try renderToken(tree, stream, err_set_decl.rbrace_token, indent, space); // }
- return;
+ try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None); // error
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.None); // {
+ try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None);
+ return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // }
}
- try renderToken(tree, stream, err_set_decl.error_token, indent, Space.None); // error
- try renderToken(tree, stream, lbrace, indent, Space.Newline); // {
+ try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None); // error
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // {
const new_indent = indent + indent_delta;
var it = err_set_decl.decls.iterator(0);
@@ -748,24 +899,24 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
try stream.writeByteNTimes(' ', new_indent);
if (it.peek()) |next_node| {
- try renderExpression(allocator, stream, tree, new_indent, node.*, Space.None);
- try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, Space.Newline); // ,
+ try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.None);
+ try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, start_col, Space.Newline); // ,
- try renderExtraNewline(tree, stream, next_node.*);
+ try renderExtraNewline(tree, stream, start_col, next_node.*);
} else {
- try renderTrailingComma(allocator, stream, tree, new_indent, node.*, Space.Newline);
+ try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);
}
}
try stream.writeByteNTimes(' ', indent);
- try renderToken(tree, stream, err_set_decl.rbrace_token, indent, space); // }
+ return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // }
},
ast.Node.Id.ErrorTag => {
const tag = @fieldParentPtr(ast.Node.ErrorTag, "base", base);
- try renderDocComments(tree, stream, tag, indent);
- try renderToken(tree, stream, tag.name_token, indent, space); // name
+ try renderDocComments(tree, stream, tag, indent, start_col);
+ return renderToken(tree, stream, tag.name_token, indent, start_col, space); // name
},
ast.Node.Id.MultilineStringLiteral => {
@@ -783,32 +934,32 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
if (!skip_first_indent) {
try stream.writeByteNTimes(' ', indent + indent_delta);
}
- try renderToken(tree, stream, t, indent, Space.None);
+ try renderToken(tree, stream, t, indent, start_col, Space.None);
skip_first_indent = false;
}
try stream.writeByteNTimes(' ', indent);
},
ast.Node.Id.UndefinedLiteral => {
const undefined_literal = @fieldParentPtr(ast.Node.UndefinedLiteral, "base", base);
- try renderToken(tree, stream, undefined_literal.token, indent, space);
+ return renderToken(tree, stream, undefined_literal.token, indent, start_col, space);
},
ast.Node.Id.BuiltinCall => {
const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base);
- try renderToken(tree, stream, builtin_call.builtin_token, indent, Space.None); // @name
- try renderToken(tree, stream, tree.nextToken(builtin_call.builtin_token), indent, Space.None); // (
+ try renderToken(tree, stream, builtin_call.builtin_token, indent, start_col, Space.None); // @name
+ try renderToken(tree, stream, tree.nextToken(builtin_call.builtin_token), indent, start_col, Space.None); // (
var it = builtin_call.params.iterator(0);
while (it.next()) |param_node| {
- try renderExpression(allocator, stream, tree, indent, param_node.*, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.None);
if (it.peek() != null) {
const comma_token = tree.nextToken(param_node.*.lastToken());
- try renderToken(tree, stream, comma_token, indent, Space.Space); // ,
+ try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
}
}
- try renderToken(tree, stream, builtin_call.rparen_token, indent, space); // )
+ return renderToken(tree, stream, builtin_call.rparen_token, indent, start_col, space); // )
},
ast.Node.Id.FnProto => {
@@ -818,68 +969,94 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
const visib_token = tree.tokens.at(visib_token_index);
assert(visib_token.id == Token.Id.Keyword_pub or visib_token.id == Token.Id.Keyword_export);
- try renderToken(tree, stream, visib_token_index, indent, Space.Space); // pub
+ try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub
}
if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
- try renderToken(tree, stream, extern_export_inline_token, indent, Space.Space); // extern/export
+ try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
}
if (fn_proto.lib_name) |lib_name| {
- try renderExpression(allocator, stream, tree, indent, lib_name, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);
}
if (fn_proto.cc_token) |cc_token| {
- try renderToken(tree, stream, cc_token, indent, Space.Space); // stdcallcc
+ try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
}
if (fn_proto.async_attr) |async_attr| {
- try renderExpression(allocator, stream, tree, indent, &async_attr.base, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, &async_attr.base, Space.Space);
}
- if (fn_proto.name_token) |name_token| blk: {
- try renderToken(tree, stream, fn_proto.fn_token, indent, Space.Space); // fn
- try renderToken(tree, stream, name_token, indent, Space.None); // name
- try renderToken(tree, stream, tree.nextToken(name_token), indent, Space.None); // (
+ const lparen = if (fn_proto.name_token) |name_token| blk: {
+ try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn
+ try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name
+ break :blk tree.nextToken(name_token);
} else blk: {
- try renderToken(tree, stream, fn_proto.fn_token, indent, Space.None); // fn
- try renderToken(tree, stream, tree.nextToken(fn_proto.fn_token), indent, Space.None); // (
- }
-
- var it = fn_proto.params.iterator(0);
- while (it.next()) |param_decl_node| {
- try renderParamDecl(allocator, stream, tree, indent, param_decl_node.*);
-
- if (it.peek() != null) {
- const comma = tree.nextToken(param_decl_node.*.lastToken());
- try renderToken(tree, stream, comma, indent, Space.Space); // ,
- }
- }
+ try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.None); // fn
+ break :blk tree.nextToken(fn_proto.fn_token);
+ };
const rparen = tree.prevToken(switch (fn_proto.return_type) {
ast.Node.FnProto.ReturnType.Explicit => |node| node.firstToken(),
ast.Node.FnProto.ReturnType.InferErrorSet => |node| tree.prevToken(node.firstToken()),
});
- try renderToken(tree, stream, rparen, indent, Space.Space); // )
+
+ const src_params_trailing_comma = blk: {
+ const maybe_comma = tree.prevToken(rparen);
+ break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
+ };
+ const src_params_same_line = blk: {
+ const loc = tree.tokenLocation(tree.tokens.at(lparen).end, rparen);
+ break :blk loc.line == 0;
+ };
+
+ if (!src_params_trailing_comma and src_params_same_line) {
+ try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
+
+ // render all on one line, no trailing comma
+ var it = fn_proto.params.iterator(0);
+ while (it.next()) |param_decl_node| {
+ try renderParamDecl(allocator, stream, tree, indent, start_col, param_decl_node.*, Space.None);
+
+ if (it.peek() != null) {
+ const comma = tree.nextToken(param_decl_node.*.lastToken());
+ try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,
+ }
+ }
+ } else {
+ // one param per line
+ const new_indent = indent + indent_delta;
+ try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline); // (
+
+ var it = fn_proto.params.iterator(0);
+ while (it.next()) |param_decl_node| {
+ try stream.writeByteNTimes(' ', new_indent);
+ try renderParamDecl(allocator, stream, tree, indent, start_col, param_decl_node.*, Space.Comma);
+ }
+ try stream.writeByteNTimes(' ', indent);
+ }
+
+ try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
if (fn_proto.align_expr) |align_expr| {
const align_rparen = tree.nextToken(align_expr.lastToken());
const align_lparen = tree.prevToken(align_expr.firstToken());
const align_kw = tree.prevToken(align_lparen);
- try renderToken(tree, stream, align_kw, indent, Space.None); // align
- try renderToken(tree, stream, align_lparen, indent, Space.None); // (
- try renderExpression(allocator, stream, tree, indent, align_expr, Space.None);
- try renderToken(tree, stream, align_rparen, indent, Space.Space); // )
+ try renderToken(tree, stream, align_kw, indent, start_col, Space.None); // align
+ try renderToken(tree, stream, align_lparen, indent, start_col, Space.None); // (
+ try renderExpression(allocator, stream, tree, indent, start_col, align_expr, Space.None);
+ try renderToken(tree, stream, align_rparen, indent, start_col, Space.Space); // )
}
switch (fn_proto.return_type) {
ast.Node.FnProto.ReturnType.Explicit => |node| {
- try renderExpression(allocator, stream, tree, indent, node, space);
+ return renderExpression(allocator, stream, tree, indent, start_col, node, space);
},
ast.Node.FnProto.ReturnType.InferErrorSet => |node| {
- try renderToken(tree, stream, tree.prevToken(node.firstToken()), indent, Space.None); // !
- try renderExpression(allocator, stream, tree, indent, node, space);
+ try renderToken(tree, stream, tree.prevToken(node.firstToken()), indent, start_col, Space.None); // !
+ return renderExpression(allocator, stream, tree, indent, start_col, node, space);
},
}
},
@@ -888,11 +1065,11 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
const promise_type = @fieldParentPtr(ast.Node.PromiseType, "base", base);
if (promise_type.result) |result| {
- try renderToken(tree, stream, promise_type.promise_token, indent, Space.None); // promise
- try renderToken(tree, stream, result.arrow_token, indent, Space.None); // ->
- try renderExpression(allocator, stream, tree, indent, result.return_type, space);
+ try renderToken(tree, stream, promise_type.promise_token, indent, start_col, Space.None); // promise
+ try renderToken(tree, stream, result.arrow_token, indent, start_col, Space.None); // ->
+ return renderExpression(allocator, stream, tree, indent, start_col, result.return_type, space);
} else {
- try renderToken(tree, stream, promise_type.promise_token, indent, space); // promise
+ return renderToken(tree, stream, promise_type.promise_token, indent, start_col, space); // promise
}
},
@@ -901,39 +1078,38 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
ast.Node.Id.Switch => {
const switch_node = @fieldParentPtr(ast.Node.Switch, "base", base);
- try renderToken(tree, stream, switch_node.switch_token, indent, Space.Space); // switch
- try renderToken(tree, stream, tree.nextToken(switch_node.switch_token), indent, Space.None); // (
+ try renderToken(tree, stream, switch_node.switch_token, indent, start_col, Space.Space); // switch
+ try renderToken(tree, stream, tree.nextToken(switch_node.switch_token), indent, start_col, Space.None); // (
const rparen = tree.nextToken(switch_node.expr.lastToken());
const lbrace = tree.nextToken(rparen);
if (switch_node.cases.len == 0) {
- try renderExpression(allocator, stream, tree, indent, switch_node.expr, Space.None);
- try renderToken(tree, stream, rparen, indent, Space.Space); // )
- try renderToken(tree, stream, lbrace, indent, Space.None); // {
- try renderToken(tree, stream, switch_node.rbrace, indent, space); // }
- return;
+ try renderExpression(allocator, stream, tree, indent, start_col, switch_node.expr, Space.None);
+ try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
+ try renderToken(tree, stream, lbrace, indent, start_col, Space.None); // {
+ return renderToken(tree, stream, switch_node.rbrace, indent, start_col, space); // }
}
- try renderExpression(allocator, stream, tree, indent, switch_node.expr, Space.None);
-
- try renderToken(tree, stream, rparen, indent, Space.Space); // )
- try renderToken(tree, stream, lbrace, indent, Space.Newline); // {
+ try renderExpression(allocator, stream, tree, indent, start_col, switch_node.expr, Space.None);
const new_indent = indent + indent_delta;
+ try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
+ try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); // {
+
var it = switch_node.cases.iterator(0);
while (it.next()) |node| {
try stream.writeByteNTimes(' ', new_indent);
- try renderExpression(allocator, stream, tree, new_indent, node.*, Space.Newline);
+ try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);
if (it.peek()) |next_node| {
- try renderExtraNewline(tree, stream, next_node.*);
+ try renderExtraNewline(tree, stream, start_col, next_node.*);
}
}
try stream.writeByteNTimes(' ', indent);
- try renderToken(tree, stream, switch_node.rbrace, indent, space); // }
+ return renderToken(tree, stream, switch_node.rbrace, indent, start_col, space); // }
},
ast.Node.Id.SwitchCase => {
@@ -950,13 +1126,13 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
var it = switch_case.items.iterator(0);
while (it.next()) |node| {
if (it.peek()) |next_node| {
- try renderExpression(allocator, stream, tree, indent, node.*, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
const comma_token = tree.nextToken(node.*.lastToken());
- try renderToken(tree, stream, comma_token, indent, Space.Space); // ,
- try renderExtraNewline(tree, stream, next_node.*);
+ try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
+ try renderExtraNewline(tree, stream, start_col, next_node.*);
} else {
- try renderExpression(allocator, stream, tree, indent, node.*, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Space);
}
}
} else {
@@ -964,84 +1140,97 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
while (true) {
const node = ??it.next();
if (it.peek()) |next_node| {
- try renderExpression(allocator, stream, tree, indent, node.*, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
const comma_token = tree.nextToken(node.*.lastToken());
- try renderToken(tree, stream, comma_token, indent, Space.Newline); // ,
- try renderExtraNewline(tree, stream, next_node.*);
+ try renderToken(tree, stream, comma_token, indent, start_col, Space.Newline); // ,
+ try renderExtraNewline(tree, stream, start_col, next_node.*);
try stream.writeByteNTimes(' ', indent);
} else {
- try renderTrailingComma(allocator, stream, tree, indent, node.*, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Comma);
+ try stream.writeByteNTimes(' ', indent);
break;
}
}
}
- try renderToken(tree, stream, switch_case.arrow_token, indent, Space.Space); // =>
+ try renderToken(tree, stream, switch_case.arrow_token, indent, start_col, Space.Space); // =>
if (switch_case.payload) |payload| {
- try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
}
- try renderTrailingComma(allocator, stream, tree, indent, switch_case.expr, space);
+ return renderExpression(allocator, stream, tree, indent, start_col, switch_case.expr, space);
},
ast.Node.Id.SwitchElse => {
const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);
- try renderToken(tree, stream, switch_else.token, indent, space);
+ return renderToken(tree, stream, switch_else.token, indent, start_col, space);
},
ast.Node.Id.Else => {
const else_node = @fieldParentPtr(ast.Node.Else, "base", base);
- const block_body = switch (else_node.body.id) {
- ast.Node.Id.Block,
- ast.Node.Id.If,
- ast.Node.Id.For,
- ast.Node.Id.While,
- ast.Node.Id.Switch => true,
- else => false,
- };
+ const body_is_block = nodeIsBlock(else_node.body);
+ const same_line = body_is_block or tree.tokensOnSameLine(else_node.else_token, else_node.body.lastToken());
- const after_else_space = if (block_body or else_node.payload != null) Space.Space else Space.Newline;
- try renderToken(tree, stream, else_node.else_token, indent, after_else_space);
+ const after_else_space = if (same_line or else_node.payload != null) Space.Space else Space.Newline;
+ try renderToken(tree, stream, else_node.else_token, indent, start_col, after_else_space);
if (else_node.payload) |payload| {
- const payload_space = if (block_body) Space.Space else Space.Newline;
- try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
+ const payload_space = if (same_line) Space.Space else Space.Newline;
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, payload_space);
}
- if (block_body) {
- try renderExpression(allocator, stream, tree, indent, else_node.body, space);
- } else {
- try stream.writeByteNTimes(' ', indent + indent_delta);
- try renderExpression(allocator, stream, tree, indent, else_node.body, space);
+ if (same_line) {
+ return renderExpression(allocator, stream, tree, indent, start_col, else_node.body, space);
}
+
+ try stream.writeByteNTimes(' ', indent + indent_delta);
+ start_col.* = indent + indent_delta;
+ return renderExpression(allocator, stream, tree, indent, start_col, else_node.body, space);
},
ast.Node.Id.While => {
const while_node = @fieldParentPtr(ast.Node.While, "base", base);
if (while_node.label) |label| {
- try renderToken(tree, stream, label, indent, Space.None); // label
- try renderToken(tree, stream, tree.nextToken(label), indent, Space.Space); // :
+ try renderToken(tree, stream, label, indent, start_col, Space.None); // label
+ try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space); // :
}
if (while_node.inline_token) |inline_token| {
- try renderToken(tree, stream, inline_token, indent, Space.Space); // inline
+ try renderToken(tree, stream, inline_token, indent, start_col, Space.Space); // inline
}
- try renderToken(tree, stream, while_node.while_token, indent, Space.Space); // while
- try renderToken(tree, stream, tree.nextToken(while_node.while_token), indent, Space.None); // (
- try renderExpression(allocator, stream, tree, indent, while_node.condition, Space.None);
+ try renderToken(tree, stream, while_node.while_token, indent, start_col, Space.Space); // while
+ try renderToken(tree, stream, tree.nextToken(while_node.while_token), indent, start_col, Space.None); // (
+ try renderExpression(allocator, stream, tree, indent, start_col, while_node.condition, Space.None);
+
+ const cond_rparen = tree.nextToken(while_node.condition.lastToken());
+
+ const body_is_block = nodeIsBlock(while_node.body);
+
+ var block_start_space: Space = undefined;
+ var after_body_space: Space = undefined;
+
+ if (body_is_block) {
+ block_start_space = Space.BlockStart;
+ after_body_space = if (while_node.@"else" == null) space else Space.SpaceOrOutdent;
+ } else if (tree.tokensOnSameLine(cond_rparen, while_node.body.lastToken())) {
+ block_start_space = Space.Space;
+ after_body_space = if (while_node.@"else" == null) space else Space.Space;
+ } else {
+ block_start_space = Space.Newline;
+ after_body_space = if (while_node.@"else" == null) space else Space.Newline;
+ }
{
- const rparen = tree.nextToken(while_node.condition.lastToken());
- const rparen_space = if (while_node.payload != null or while_node.continue_expr != null or
- while_node.body.id == ast.Node.Id.Block) Space.Space else Space.Newline;
- try renderToken(tree, stream, rparen, indent, rparen_space); // )
+ const rparen_space = if (while_node.payload != null or while_node.continue_expr != null) Space.Space else block_start_space;
+ try renderToken(tree, stream, cond_rparen, indent, start_col, rparen_space); // )
}
if (while_node.payload) |payload| {
- try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
+ const payload_space = if (while_node.continue_expr != null) Space.Space else block_start_space;
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, payload_space);
}
if (while_node.continue_expr) |continue_expr| {
@@ -1049,37 +1238,29 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
const lparen = tree.prevToken(continue_expr.firstToken());
const colon = tree.prevToken(lparen);
- try renderToken(tree, stream, colon, indent, Space.Space); // :
- try renderToken(tree, stream, lparen, indent, Space.None); // (
+ try renderToken(tree, stream, colon, indent, start_col, Space.Space); // :
+ try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
- try renderExpression(allocator, stream, tree, indent, continue_expr, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, continue_expr, Space.None);
- const rparen_space = if (while_node.body.id == ast.Node.Id.Block) Space.Space else Space.Newline;
- try renderToken(tree, stream, rparen, indent, rparen_space); // )
+ try renderToken(tree, stream, rparen, indent, start_col, block_start_space); // )
}
- const body_space = blk: {
- if (while_node.@"else" != null) {
- break :blk if (while_node.body.id == ast.Node.Id.Block) Space.Space else Space.Newline;
- } else {
- break :blk space;
- }
- };
-
- if (while_node.body.id == ast.Node.Id.Block) {
- try renderExpression(allocator, stream, tree, indent, while_node.body, body_space);
- } else {
- try stream.writeByteNTimes(' ', indent + indent_delta);
- try renderExpression(allocator, stream, tree, indent, while_node.body, body_space);
+ var new_indent = indent;
+ if (block_start_space == Space.Newline) {
+ new_indent += indent_delta;
+ try stream.writeByteNTimes(' ', new_indent);
+ start_col.* = new_indent;
}
+ try renderExpression(allocator, stream, tree, indent, start_col, while_node.body, after_body_space);
+
if (while_node.@"else") |@"else"| {
- if (while_node.body.id == ast.Node.Id.Block) {
- } else {
+ if (after_body_space == Space.Newline) {
try stream.writeByteNTimes(' ', indent);
+ start_col.* = indent;
}
-
- try renderExpression(allocator, stream, tree, indent, &@"else".base, space);
+ return renderExpression(allocator, stream, tree, indent, start_col, &@"else".base, space);
}
},
@@ -1087,26 +1268,26 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
const for_node = @fieldParentPtr(ast.Node.For, "base", base);
if (for_node.label) |label| {
- try renderToken(tree, stream, label, indent, Space.None); // label
- try renderToken(tree, stream, tree.nextToken(label), indent, Space.Space); // :
+ try renderToken(tree, stream, label, indent, start_col, Space.None); // label
+ try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space); // :
}
if (for_node.inline_token) |inline_token| {
- try renderToken(tree, stream, inline_token, indent, Space.Space); // inline
+ try renderToken(tree, stream, inline_token, indent, start_col, Space.Space); // inline
}
- try renderToken(tree, stream, for_node.for_token, indent, Space.Space); // for
- try renderToken(tree, stream, tree.nextToken(for_node.for_token), indent, Space.None); // (
- try renderExpression(allocator, stream, tree, indent, for_node.array_expr, Space.None);
+ try renderToken(tree, stream, for_node.for_token, indent, start_col, Space.Space); // for
+ try renderToken(tree, stream, tree.nextToken(for_node.for_token), indent, start_col, Space.None); // (
+ try renderExpression(allocator, stream, tree, indent, start_col, for_node.array_expr, Space.None);
const rparen = tree.nextToken(for_node.array_expr.lastToken());
const rparen_space = if (for_node.payload != null or
for_node.body.id == ast.Node.Id.Block) Space.Space else Space.Newline;
- try renderToken(tree, stream, rparen, indent, rparen_space); // )
+ try renderToken(tree, stream, rparen, indent, start_col, rparen_space); // )
if (for_node.payload) |payload| {
const payload_space = if (for_node.body.id == ast.Node.Id.Block) Space.Space else Space.Newline;
- try renderExpression(allocator, stream, tree, indent, payload, payload_space);
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, payload_space);
}
const body_space = blk: {
@@ -1121,10 +1302,10 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
}
};
if (for_node.body.id == ast.Node.Id.Block) {
- try renderExpression(allocator, stream, tree, indent, for_node.body, body_space);
+ try renderExpression(allocator, stream, tree, indent, start_col, for_node.body, body_space);
} else {
try stream.writeByteNTimes(' ', indent + indent_delta);
- try renderExpression(allocator, stream, tree, indent, for_node.body, body_space);
+ try renderExpression(allocator, stream, tree, indent, start_col, for_node.body, body_space);
}
if (for_node.@"else") |@"else"| {
@@ -1132,167 +1313,252 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
try stream.writeByteNTimes(' ', indent);
}
- try renderExpression(allocator, stream, tree, indent, &@"else".base, space);
+ return renderExpression(allocator, stream, tree, indent, start_col, &@"else".base, space);
}
},
ast.Node.Id.If => {
const if_node = @fieldParentPtr(ast.Node.If, "base", base);
- try renderToken(tree, stream, if_node.if_token, indent, Space.Space);
- try renderToken(tree, stream, tree.prevToken(if_node.condition.firstToken()), indent, Space.None);
+ const lparen = tree.prevToken(if_node.condition.firstToken());
+ const rparen = tree.nextToken(if_node.condition.lastToken());
- try renderExpression(allocator, stream, tree, indent, if_node.condition, Space.None);
- try renderToken(tree, stream, tree.nextToken(if_node.condition.lastToken()), indent, Space.Space);
+ try renderToken(tree, stream, if_node.if_token, indent, start_col, Space.Space); // if
+ try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
- if (if_node.payload) |payload| {
- try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
- }
-
- switch (if_node.body.id) {
- ast.Node.Id.Block,
- ast.Node.Id.If,
- ast.Node.Id.For,
- ast.Node.Id.While,
- ast.Node.Id.Switch => {
- if (if_node.@"else") |@"else"| {
- if (if_node.body.id == ast.Node.Id.Block) {
- try renderExpression(allocator, stream, tree, indent, if_node.body, Space.Space);
- } else {
- try renderExpression(allocator, stream, tree, indent, if_node.body, Space.Newline);
- try stream.writeByteNTimes(' ', indent);
+ try renderExpression(allocator, stream, tree, indent, start_col, if_node.condition, Space.None); // condition
+
+ const body_is_block = nodeIsBlock(if_node.body);
+
+ if (body_is_block) {
+ const after_rparen_space = if (if_node.payload == null) Space.BlockStart else Space.Space;
+ try renderToken(tree, stream, rparen, indent, start_col, after_rparen_space); // )
+
+ if (if_node.payload) |payload| {
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.BlockStart); // |x|
+ }
+
+ if (if_node.@"else") |@"else"| {
+ try renderExpression(allocator, stream, tree, indent, start_col, if_node.body, Space.SpaceOrOutdent);
+ return renderExpression(allocator, stream, tree, indent, start_col, &@"else".base, space);
+ } else {
+ return renderExpression(allocator, stream, tree, indent, start_col, if_node.body, space);
+ }
+ }
+
+ const src_has_newline = !tree.tokensOnSameLine(rparen, if_node.body.lastToken());
+
+ if (src_has_newline) {
+ const after_rparen_space = if (if_node.payload == null) Space.Newline else Space.Space;
+ try renderToken(tree, stream, rparen, indent, start_col, after_rparen_space); // )
+
+ if (if_node.payload) |payload| {
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Newline);
+ }
+
+ const new_indent = indent + indent_delta;
+ try stream.writeByteNTimes(' ', new_indent);
+
+ if (if_node.@"else") |@"else"| {
+ const else_is_block = nodeIsBlock(@"else".body);
+ try renderExpression(allocator, stream, tree, new_indent, start_col, if_node.body, Space.Newline);
+ try stream.writeByteNTimes(' ', indent);
+
+ if (else_is_block) {
+ try renderToken(tree, stream, @"else".else_token, indent, start_col, Space.Space); // else
+
+ if (@"else".payload) |payload| {
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
}
- try renderExpression(allocator, stream, tree, indent, &@"else".base, space);
+ return renderExpression(allocator, stream, tree, indent, start_col, @"else".body, space);
} else {
- try renderExpression(allocator, stream, tree, indent, if_node.body, space);
- }
- },
- else => {
- if (if_node.@"else") |@"else"| {
- try renderExpression(allocator, stream, tree, indent, if_node.body, Space.Space);
- try renderToken(tree, stream, @"else".else_token, indent, Space.Space);
+ const after_else_space = if (@"else".payload == null) Space.Newline else Space.Space;
+ try renderToken(tree, stream, @"else".else_token, indent, start_col, after_else_space); // else
if (@"else".payload) |payload| {
- try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Newline);
}
+ try stream.writeByteNTimes(' ', new_indent);
- try renderExpression(allocator, stream, tree, indent, @"else".body, space);
- } else {
- try renderExpression(allocator, stream, tree, indent, if_node.body, space);
+ return renderExpression(allocator, stream, tree, new_indent, start_col, @"else".body, space);
}
- },
+ } else {
+ return renderExpression(allocator, stream, tree, new_indent, start_col, if_node.body, space);
+ }
+ }
+
+ try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
+
+ if (if_node.payload) |payload| {
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
+ }
+
+ if (if_node.@"else") |@"else"| {
+ try renderExpression(allocator, stream, tree, indent, start_col, if_node.body, Space.Space);
+ try renderToken(tree, stream, @"else".else_token, indent, start_col, Space.Space);
+
+ if (@"else".payload) |payload| {
+ try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space);
+ }
+
+ return renderExpression(allocator, stream, tree, indent, start_col, @"else".body, space);
+ } else {
+ return renderExpression(allocator, stream, tree, indent, start_col, if_node.body, space);
}
},
ast.Node.Id.Asm => {
const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base);
- try renderToken(tree, stream, asm_node.asm_token, indent, Space.Space); // asm
+ try renderToken(tree, stream, asm_node.asm_token, indent, start_col, Space.Space); // asm
if (asm_node.volatile_token) |volatile_token| {
- try renderToken(tree, stream, volatile_token, indent, Space.Space); // volatile
- try renderToken(tree, stream, tree.nextToken(volatile_token), indent, Space.None); // (
+ try renderToken(tree, stream, volatile_token, indent, start_col, Space.Space); // volatile
+ try renderToken(tree, stream, tree.nextToken(volatile_token), indent, start_col, Space.None); // (
} else {
- try renderToken(tree, stream, tree.nextToken(asm_node.asm_token), indent, Space.None); // (
+ try renderToken(tree, stream, tree.nextToken(asm_node.asm_token), indent, start_col, Space.None); // (
+ }
+
+ if (asm_node.outputs.len == 0 and asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
+ try renderExpression(allocator, stream, tree, indent, start_col, asm_node.template, Space.None);
+ return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
}
- try renderExpression(allocator, stream, tree, indent, asm_node.template, Space.Newline);
+ try renderExpression(allocator, stream, tree, indent, start_col, asm_node.template, Space.Newline);
+
const indent_once = indent + indent_delta;
try stream.writeByteNTimes(' ', indent_once);
- try stream.print(": ");
+
+ const colon1 = tree.nextToken(asm_node.template.lastToken());
const indent_extra = indent_once + 2;
- {
+ const colon2 = if (asm_node.outputs.len == 0) blk: {
+ try renderToken(tree, stream, colon1, indent, start_col, Space.Newline); // :
+ try stream.writeByteNTimes(' ', indent_once);
+
+ break :blk tree.nextToken(colon1);
+ } else blk: {
+ try renderToken(tree, stream, colon1, indent, start_col, Space.Space); // :
+
var it = asm_node.outputs.iterator(0);
- while (it.next()) |asm_output| {
+ while (true) {
+ const asm_output = ??it.next();
const node = &(asm_output.*).base;
- try renderExpression(allocator, stream, tree, indent_extra, node, Space.None);
if (it.peek()) |next_asm_output| {
+ try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);
const next_node = &(next_asm_output.*).base;
const comma = tree.prevToken(next_asm_output.*.firstToken());
- try renderToken(tree, stream, comma, indent_extra, Space.Newline); // ,
- try renderExtraNewline(tree, stream, next_node);
+ try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,
+ try renderExtraNewline(tree, stream, start_col, next_node);
try stream.writeByteNTimes(' ', indent_extra);
+ } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
+ try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
+ try stream.writeByteNTimes(' ', indent);
+ return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
+ } else {
+ try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
+ try stream.writeByteNTimes(' ', indent_once);
+ const comma_or_colon = tree.nextToken(node.lastToken());
+ break :blk switch (tree.tokens.at(comma_or_colon).id) {
+ Token.Id.Comma => tree.nextToken(comma_or_colon),
+ else => comma_or_colon,
+ };
}
}
- }
+ };
- try stream.write("\n");
- try stream.writeByteNTimes(' ', indent_once);
- try stream.write(": ");
+ const colon3 = if (asm_node.inputs.len == 0) blk: {
+ try renderToken(tree, stream, colon2, indent, start_col, Space.Newline); // :
+ try stream.writeByteNTimes(' ', indent_once);
+
+ break :blk tree.nextToken(colon2);
+ } else blk: {
+ try renderToken(tree, stream, colon2, indent, start_col, Space.Space); // :
- {
var it = asm_node.inputs.iterator(0);
- while (it.next()) |asm_input| {
+ while (true) {
+ const asm_input = ??it.next();
const node = &(asm_input.*).base;
- try renderExpression(allocator, stream, tree, indent_extra, node, Space.None);
if (it.peek()) |next_asm_input| {
+ try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);
const next_node = &(next_asm_input.*).base;
const comma = tree.prevToken(next_asm_input.*.firstToken());
- try renderToken(tree, stream, comma, indent_extra, Space.Newline); // ,
- try renderExtraNewline(tree, stream, next_node);
+ try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,
+ try renderExtraNewline(tree, stream, start_col, next_node);
try stream.writeByteNTimes(' ', indent_extra);
+ } else if (asm_node.clobbers.len == 0) {
+ try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
+ try stream.writeByteNTimes(' ', indent);
+ return renderToken(tree, stream, asm_node.rparen, indent, start_col, space); // )
+ } else {
+ try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
+ try stream.writeByteNTimes(' ', indent_once);
+ const comma_or_colon = tree.nextToken(node.lastToken());
+ break :blk switch (tree.tokens.at(comma_or_colon).id) {
+ Token.Id.Comma => tree.nextToken(comma_or_colon),
+ else => comma_or_colon,
+ };
}
}
- }
+ };
- try stream.write("\n");
- try stream.writeByteNTimes(' ', indent_once);
- try stream.write(": ");
+ try renderToken(tree, stream, colon3, indent, start_col, Space.Space); // :
- {
- var it = asm_node.clobbers.iterator(0);
- while (it.next()) |node| {
- try renderExpression(allocator, stream, tree, indent_once, node.*, Space.None);
+ var it = asm_node.clobbers.iterator(0);
+ while (true) {
+ const clobber_token = ??it.next();
- if (it.peek() != null) {
- try stream.write(", ");
- }
+ if (it.peek() == null) {
+ try renderToken(tree, stream, clobber_token.*, indent_once, start_col, Space.Newline);
+ try stream.writeByteNTimes(' ', indent);
+ return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
+ } else {
+ try renderToken(tree, stream, clobber_token.*, indent_once, start_col, Space.None);
+ const comma = tree.nextToken(clobber_token.*);
+ try renderToken(tree, stream, comma, indent_once, start_col, Space.Space); // ,
}
}
-
- try renderToken(tree, stream, asm_node.rparen, indent, space);
},
ast.Node.Id.AsmInput => {
const asm_input = @fieldParentPtr(ast.Node.AsmInput, "base", base);
try stream.write("[");
- try renderExpression(allocator, stream, tree, indent, asm_input.symbolic_name, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, asm_input.symbolic_name, Space.None);
try stream.write("] ");
- try renderExpression(allocator, stream, tree, indent, asm_input.constraint, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, asm_input.constraint, Space.None);
try stream.write(" (");
- try renderExpression(allocator, stream, tree, indent, asm_input.expr, Space.None);
- try renderToken(tree, stream, asm_input.lastToken(), indent, space); // )
+ try renderExpression(allocator, stream, tree, indent, start_col, asm_input.expr, Space.None);
+ return renderToken(tree, stream, asm_input.lastToken(), indent, start_col, space); // )
},
ast.Node.Id.AsmOutput => {
const asm_output = @fieldParentPtr(ast.Node.AsmOutput, "base", base);
try stream.write("[");
- try renderExpression(allocator, stream, tree, indent, asm_output.symbolic_name, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, asm_output.symbolic_name, Space.None);
try stream.write("] ");
- try renderExpression(allocator, stream, tree, indent, asm_output.constraint, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, asm_output.constraint, Space.None);
try stream.write(" (");
switch (asm_output.kind) {
ast.Node.AsmOutput.Kind.Variable => |variable_name| {
- try renderExpression(allocator, stream, tree, indent, &variable_name.base, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, &variable_name.base, Space.None);
},
ast.Node.AsmOutput.Kind.Return => |return_type| {
try stream.write("-> ");
- try renderExpression(allocator, stream, tree, indent, return_type, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, return_type, Space.None);
},
}
- try renderToken(tree, stream, asm_output.lastToken(), indent, space); // )
+ return renderToken(tree, stream, asm_output.lastToken(), indent, start_col, space); // )
},
ast.Node.Id.StructField,
@@ -1306,92 +1572,92 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
}
}
-fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize,
- var_decl: &ast.Node.VarDecl) (@typeOf(stream).Child.Error || Error)!void
+fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, start_col: &usize,
+ var_decl: &ast.Node.VarDecl,) (@typeOf(stream).Child.Error || Error)!void
{
if (var_decl.visib_token) |visib_token| {
- try renderToken(tree, stream, visib_token, indent, Space.Space); // pub
+ try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
}
if (var_decl.extern_export_token) |extern_export_token| {
- try renderToken(tree, stream, extern_export_token, indent, Space.Space); // extern
+ try renderToken(tree, stream, extern_export_token, indent, start_col, Space.Space); // extern
if (var_decl.lib_name) |lib_name| {
- try renderExpression(allocator, stream, tree, indent, lib_name, Space.Space); // "lib"
+ try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space); // "lib"
}
}
if (var_decl.comptime_token) |comptime_token| {
- try renderToken(tree, stream, comptime_token, indent, Space.Space); // comptime
+ try renderToken(tree, stream, comptime_token, indent, start_col, Space.Space); // comptime
}
- try renderToken(tree, stream, var_decl.mut_token, indent, Space.Space); // var
+ try renderToken(tree, stream, var_decl.mut_token, indent, start_col, Space.Space); // var
const name_space = if (var_decl.type_node == null and (var_decl.align_node != null or
var_decl.init_node != null)) Space.Space else Space.None;
- try renderToken(tree, stream, var_decl.name_token, indent, name_space);
+ try renderToken(tree, stream, var_decl.name_token, indent, start_col, name_space);
if (var_decl.type_node) |type_node| {
- try renderToken(tree, stream, tree.nextToken(var_decl.name_token), indent, Space.Space);
+ try renderToken(tree, stream, tree.nextToken(var_decl.name_token), indent, start_col, Space.Space);
const s = if (var_decl.align_node != null or var_decl.init_node != null) Space.Space else Space.None;
- try renderExpression(allocator, stream, tree, indent, type_node, s);
+ try renderExpression(allocator, stream, tree, indent, start_col, type_node, s);
}
if (var_decl.align_node) |align_node| {
const lparen = tree.prevToken(align_node.firstToken());
const align_kw = tree.prevToken(lparen);
const rparen = tree.nextToken(align_node.lastToken());
- try renderToken(tree, stream, align_kw, indent, Space.None); // align
- try renderToken(tree, stream, lparen, indent, Space.None); // (
- try renderExpression(allocator, stream, tree, indent, align_node, Space.None);
+ try renderToken(tree, stream, align_kw, indent, start_col, Space.None); // align
+ try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
+ try renderExpression(allocator, stream, tree, indent, start_col, align_node, Space.None);
const s = if (var_decl.init_node != null) Space.Space else Space.None;
- try renderToken(tree, stream, rparen, indent, s); // )
+ try renderToken(tree, stream, rparen, indent, start_col, s); // )
}
if (var_decl.init_node) |init_node| {
const s = if (init_node.id == ast.Node.Id.MultilineStringLiteral) Space.None else Space.Space;
- try renderToken(tree, stream, var_decl.eq_token, indent, s); // =
- try renderExpression(allocator, stream, tree, indent, init_node, Space.None);
+ try renderToken(tree, stream, var_decl.eq_token, indent, start_col, s); // =
+ try renderExpression(allocator, stream, tree, indent, start_col, init_node, Space.None);
}
- try renderToken(tree, stream, var_decl.semicolon_token, indent, Space.Newline);
+ try renderToken(tree, stream, var_decl.semicolon_token, indent, start_col, Space.Newline);
}
-fn renderParamDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node) (@typeOf(stream).Child.Error || Error)!void {
+fn renderParamDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, start_col: &usize, base: &ast.Node, space: Space,) (@typeOf(stream).Child.Error || Error)!void {
const param_decl = @fieldParentPtr(ast.Node.ParamDecl, "base", base);
if (param_decl.comptime_token) |comptime_token| {
- try renderToken(tree, stream, comptime_token, indent, Space.Space);
+ try renderToken(tree, stream, comptime_token, indent, start_col, Space.Space);
}
if (param_decl.noalias_token) |noalias_token| {
- try renderToken(tree, stream, noalias_token, indent, Space.Space);
+ try renderToken(tree, stream, noalias_token, indent, start_col, Space.Space);
}
if (param_decl.name_token) |name_token| {
- try renderToken(tree, stream, name_token, indent, Space.None);
- try renderToken(tree, stream, tree.nextToken(name_token), indent, Space.Space); // :
+ try renderToken(tree, stream, name_token, indent, start_col, Space.None);
+ try renderToken(tree, stream, tree.nextToken(name_token), indent, start_col, Space.Space); // :
}
if (param_decl.var_args_token) |var_args_token| {
- try renderToken(tree, stream, var_args_token, indent, Space.None);
+ try renderToken(tree, stream, var_args_token, indent, start_col, space);
} else {
- try renderExpression(allocator, stream, tree, indent, param_decl.type_node, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, param_decl.type_node, space);
}
}
-fn renderStatement(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node) (@typeOf(stream).Child.Error || Error)!void {
+fn renderStatement(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, start_col: &usize, base: &ast.Node,) (@typeOf(stream).Child.Error || Error)!void {
switch (base.id) {
ast.Node.Id.VarDecl => {
const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
- try renderVarDecl(allocator, stream, tree, indent, var_decl);
+ try renderVarDecl(allocator, stream, tree, indent, start_col, var_decl);
},
else => {
if (base.requireSemiColon()) {
- try renderExpression(allocator, stream, tree, indent, base, Space.None);
+ try renderExpression(allocator, stream, tree, indent, start_col, base, Space.None);
const semicolon_index = tree.nextToken(base.lastToken());
assert(tree.tokens.at(semicolon_index).id == Token.Id.Semicolon);
- try renderToken(tree, stream, semicolon_index, indent, Space.Newline);
+ try renderToken(tree, stream, semicolon_index, indent, start_col, Space.Newline);
} else {
- try renderExpression(allocator, stream, tree, indent, base, Space.Newline);
+ try renderExpression(allocator, stream, tree, indent, start_col, base, Space.Newline);
}
},
}
@@ -1400,32 +1666,95 @@ fn renderStatement(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, inde
const Space = enum {
None,
Newline,
+ Comma,
Space,
+ SpaceOrOutdent,
NoNewline,
- NoIndent,
NoComment,
+ BlockStart,
};
-fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, space: Space) (@typeOf(stream).Child.Error || Error)!void {
+fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, start_col: &usize, space: Space) (@typeOf(stream).Child.Error || Error)!void {
+ if (space == Space.BlockStart) {
+ if (start_col.* < indent + indent_delta)
+ return renderToken(tree, stream, token_index, indent, start_col, Space.Space);
+ try renderToken(tree, stream, token_index, indent, start_col, Space.Newline);
+ try stream.writeByteNTimes(' ', indent);
+ start_col.* = indent;
+ return;
+ }
+
var token = tree.tokens.at(token_index);
- try stream.write(tree.tokenSlicePtr(token));
+ try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(token), " "));
- if (space == Space.NoComment) return;
+ if (space == Space.NoComment)
+ return;
var next_token = tree.tokens.at(token_index + 1);
- if (next_token.id != Token.Id.LineComment) {
+
+ if (space == Space.Comma) switch (next_token.id) {
+ Token.Id.Comma => return renderToken(tree, stream, token_index + 1, indent, start_col, Space.Newline),
+ Token.Id.LineComment => {
+ try stream.write(", ");
+ return renderToken(tree, stream, token_index + 1, indent, start_col, Space.Newline);
+ },
+ else => {
+ if (tree.tokens.at(token_index + 2).id == Token.Id.MultilineStringLiteralLine) {
+ try stream.write(",");
+ return;
+ } else {
+ try stream.write(",\n");
+ start_col.* = 0;
+ return;
+ }
+ },
+ };
+
+ // Skip over same line doc comments
+ var offset: usize = 1;
+ if (next_token.id == Token.Id.DocComment) {
+ const loc = tree.tokenLocationPtr(token.end, next_token);
+ if (loc.line == 0) {
+ offset += 1;
+ next_token = tree.tokens.at(token_index + offset);
+ }
+ }
+
+ if (next_token.id != Token.Id.LineComment) blk: {
switch (space) {
- Space.None, Space.NoNewline, Space.NoIndent => return,
- Space.Newline => return stream.write("\n"),
- Space.Space => return stream.writeByte(' '),
- Space.NoComment => unreachable,
+ Space.None, Space.NoNewline => return,
+ Space.Newline => {
+ if (next_token.id == Token.Id.MultilineStringLiteralLine) {
+ return;
+ } else {
+ try stream.write("\n");
+ start_col.* = 0;
+ return;
+ }
+ },
+ Space.Space, Space.SpaceOrOutdent => {
+ try stream.writeByte(' ');
+ return;
+ },
+ Space.NoComment, Space.Comma, Space.BlockStart => unreachable,
+ }
+ }
+
+ const comment_is_empty = mem.trimRight(u8, tree.tokenSlicePtr(next_token), " ").len == 2;
+ if (comment_is_empty) {
+ switch (space) {
+ Space.Newline => {
+ try stream.writeByte('\n');
+ start_col.* = 0;
+ return;
+ },
+ else => {},
}
}
var loc = tree.tokenLocationPtr(token.end, next_token);
- var offset: usize = 1;
if (loc.line == 0) {
- try stream.print(" {}", tree.tokenSlicePtr(next_token));
+ try stream.print(" {}", mem.trimRight(u8, tree.tokenSlicePtr(next_token), " "));
offset = 2;
token = next_token;
next_token = tree.tokens.at(token_index + offset);
@@ -1439,10 +1768,24 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent
else => indent + indent_delta,
};
try stream.writeByteNTimes(' ', next_line_indent);
+ start_col.* = next_line_indent;
+ },
+ Space.SpaceOrOutdent => {
+ try stream.writeByte('\n');
+ try stream.writeByteNTimes(' ', indent);
+ start_col.* = indent;
+ },
+ Space.Newline => {
+ if (next_token.id == Token.Id.MultilineStringLiteralLine) {
+ return;
+ } else {
+ try stream.write("\n");
+ start_col.* = 0;
+ return;
+ }
},
- Space.Newline, Space.NoIndent => try stream.write("\n"),
Space.NoNewline => {},
- Space.NoComment => unreachable,
+ Space.NoComment, Space.Comma, Space.BlockStart => unreachable,
}
return;
}
@@ -1454,26 +1797,40 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent
const newline_count = if (loc.line == 1) u8(1) else u8(2);
try stream.writeByteNTimes('\n', newline_count);
try stream.writeByteNTimes(' ', indent);
- try stream.write(tree.tokenSlicePtr(next_token));
+ try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(next_token), " "));
offset += 1;
token = next_token;
next_token = tree.tokens.at(token_index + offset);
if (next_token.id != Token.Id.LineComment) {
switch (space) {
- Space.Newline, Space.NoIndent => try stream.writeByte('\n'),
+ Space.Newline => {
+ if (next_token.id == Token.Id.MultilineStringLiteralLine) {
+ return;
+ } else {
+ try stream.write("\n");
+ start_col.* = 0;
+ return;
+ }
+ },
Space.None, Space.Space => {
try stream.writeByte('\n');
const after_comment_token = tree.tokens.at(token_index + offset);
const next_line_indent = switch (after_comment_token.id) {
- Token.Id.RParen, Token.Id.RBrace, Token.Id.RBracket => indent,
+ Token.Id.RParen, Token.Id.RBrace, Token.Id.RBracket => indent - indent_delta,
else => indent,
};
try stream.writeByteNTimes(' ', next_line_indent);
+ start_col.* = next_line_indent;
+ },
+ Space.SpaceOrOutdent => {
+ try stream.writeByte('\n');
+ try stream.writeByteNTimes(' ', indent);
+ start_col.* = indent;
},
Space.NoNewline => {},
- Space.NoComment => unreachable,
+ Space.NoComment, Space.Comma, Space.BlockStart => unreachable,
}
return;
}
@@ -1481,33 +1838,30 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent
}
}
-fn renderDocComments(tree: &ast.Tree, stream: var, node: var, indent: usize) (@typeOf(stream).Child.Error || Error)!void {
+fn renderDocComments(tree: &ast.Tree, stream: var, node: var, indent: usize, start_col: &usize,) (@typeOf(stream).Child.Error || Error)!void {
const comment = node.doc_comments ?? return;
var it = comment.lines.iterator(0);
+ const first_token = node.firstToken();
while (it.next()) |line_token_index| {
- try renderToken(tree, stream, line_token_index.*, indent, Space.Newline);
- try stream.writeByteNTimes(' ', indent);
+ if (line_token_index.* < first_token) {
+ try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.Newline);
+ try stream.writeByteNTimes(' ', indent);
+ } else {
+ try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.NoComment);
+ try stream.write("\n");
+ try stream.writeByteNTimes(' ', indent);
+ }
}
}
-fn renderTrailingComma(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node,
- space: Space) (@typeOf(stream).Child.Error || Error)!void
-{
- const end_token = base.lastToken() + 1;
- switch (tree.tokens.at(end_token).id) {
- Token.Id.Comma => {
- try renderExpression(allocator, stream, tree, indent, base, Space.None);
- try renderToken(tree, stream, end_token, indent, space); // ,
- },
- Token.Id.LineComment => {
- try renderExpression(allocator, stream, tree, indent, base, Space.NoComment);
- try stream.write(", ");
- try renderToken(tree, stream, end_token, indent, space);
- },
- else => {
- try renderExpression(allocator, stream, tree, indent, base, Space.None);
- try stream.write(",\n");
- assert(space == Space.Newline);
- },
- }
+fn nodeIsBlock(base: &const ast.Node) bool {
+ return switch (base.id) {
+ ast.Node.Id.Block,
+ ast.Node.Id.If,
+ ast.Node.Id.For,
+ ast.Node.Id.While,
+ ast.Node.Id.Switch,
+ => true,
+ else => false,
+ };
}
diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig
index f4cd847dff..b90a40108f 100644
--- a/std/zig/tokenizer.zig
+++ b/std/zig/tokenizer.zig
@@ -217,7 +217,6 @@ pub const Tokenizer = struct {
StringLiteral,
StringLiteralBackslash,
MultilineStringLiteralLine,
- MultilineStringLiteralLineBackslash,
CharLiteral,
CharLiteralBackslash,
CharLiteralEscape1,
@@ -655,9 +654,6 @@ pub const Tokenizer = struct {
},
State.MultilineStringLiteralLine => switch (c) {
- '\\' => {
- state = State.MultilineStringLiteralLineBackslash;
- },
'\n' => {
self.index += 1;
break;
@@ -665,13 +661,6 @@ pub const Tokenizer = struct {
else => self.checkLiteralCharacter(),
},
- State.MultilineStringLiteralLineBackslash => switch (c) {
- '\n' => break, // Look for this error later.
- else => {
- state = State.MultilineStringLiteralLine;
- },
- },
-
State.Bang => switch (c) {
'=' => {
result.id = Token.Id.BangEqual;
@@ -1010,7 +999,6 @@ pub const Tokenizer = struct {
State.FloatExponentUnsignedHex,
State.SawAtSign,
State.Backslash,
- State.MultilineStringLiteralLineBackslash,
State.CharLiteral,
State.CharLiteralBackslash,
State.CharLiteralEscape1,