| author | |
| committer | |
| log | 99fc2bd4ddbe36994153f6426f0001d338e90bef |
| tree | e5f2be82ac4ae7793212d218ff20422912fd5d32 |
| parent | b73307befb49dd3b131d99ecf1c7f3fb54578ec8 |
| parent | 942d384831196acf24868c32ef84409b05441960 |
6 files changed, 215 insertions(+), 53 deletions(-)
src/target.cpp+1-1| ... | ... | @@ -702,6 +702,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 702 | 702 | case OsLinux: |
| 703 | 703 | case OsMacOSX: |
| 704 | 704 | case OsZen: |
| 705 | case OsOpenBSD: | |
| 705 | 706 | switch (id) { |
| 706 | 707 | case CIntTypeShort: |
| 707 | 708 | case CIntTypeUShort: |
| ... | ... | @@ -742,7 +743,6 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 742 | 743 | case OsKFreeBSD: |
| 743 | 744 | case OsLv2: |
| 744 | 745 | case OsNetBSD: |
| 745 | case OsOpenBSD: | |
| 746 | 746 | case OsSolaris: |
| 747 | 747 | case OsHaiku: |
| 748 | 748 | case OsMinix: |
std/fmt/index.zig+58-29| ... | ... | @@ -26,6 +26,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context), |
| 26 | 26 | Buf, |
| 27 | 27 | BufWidth, |
| 28 | 28 | Bytes, |
| 29 | BytesBase, | |
| 29 | 30 | BytesWidth, |
| 30 | 31 | }; |
| 31 | 32 | |
| ... | ... | @@ -97,6 +98,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context), |
| 97 | 98 | }, |
| 98 | 99 | 'B' => { |
| 99 | 100 | width = 0; |
| 101 | radix = 1000; | |
| 100 | 102 | state = State.Bytes; |
| 101 | 103 | }, |
| 102 | 104 | else => @compileError("Unknown format character: " ++ []u8{c}), |
| ... | ... | @@ -212,7 +214,24 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context), |
| 212 | 214 | }, |
| 213 | 215 | State.Bytes => switch (c) { |
| 214 | 216 | '}' => { |
| 215 | try formatBytes(args[next_arg], 0, context, Errors, output); | |
| 217 | try formatBytes(args[next_arg], 0, radix, context, Errors, output); | |
| 218 | next_arg += 1; | |
| 219 | state = State.Start; | |
| 220 | start_index = i + 1; | |
| 221 | }, | |
| 222 | 'i' => { | |
| 223 | radix = 1024; | |
| 224 | state = State.BytesBase; | |
| 225 | }, | |
| 226 | '0' ... '9' => { | |
| 227 | width_start = i; | |
| 228 | state = State.BytesWidth; | |
| 229 | }, | |
| 230 | else => @compileError("Unexpected character in format string: " ++ []u8{c}), | |
| 231 | }, | |
| 232 | State.BytesBase => switch (c) { | |
| 233 | '}' => { | |
| 234 | try formatBytes(args[next_arg], 0, radix, context, Errors, output); | |
| 216 | 235 | next_arg += 1; |
| 217 | 236 | state = State.Start; |
| 218 | 237 | start_index = i + 1; |
| ... | ... | @@ -226,7 +245,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context), |
| 226 | 245 | State.BytesWidth => switch (c) { |
| 227 | 246 | '}' => { |
| 228 | 247 | width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable); |
| 229 | try formatBytes(args[next_arg], width, context, Errors, output); | |
| 248 | try formatBytes(args[next_arg], width, radix, context, Errors, output); | |
| 230 | 249 | next_arg += 1; |
| 231 | 250 | state = State.Start; |
| 232 | 251 | start_index = i + 1; |
| ... | ... | @@ -543,7 +562,7 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com |
| 543 | 562 | } |
| 544 | 563 | } |
| 545 | 564 | |
| 546 | pub fn formatBytes(value: var, width: ?usize, | |
| 565 | pub fn formatBytes(value: var, width: ?usize, comptime radix: usize, | |
| 547 | 566 | context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void |
| 548 | 567 | { |
| 549 | 568 | if (value == 0) { |
| ... | ... | @@ -551,16 +570,26 @@ pub fn formatBytes(value: var, width: ?usize, |
| 551 | 570 | } |
| 552 | 571 | |
| 553 | 572 | const mags = " KMGTPEZY"; |
| 554 | const magnitude = math.min(math.log2(value) / 10, mags.len - 1); | |
| 555 | const new_value = f64(value) / math.pow(f64, 1024, f64(magnitude)); | |
| 573 | const magnitude = switch (radix) { | |
| 574 | 1000 => math.min(math.log2(value) / comptime math.log2(1000), mags.len - 1), | |
| 575 | 1024 => math.min(math.log2(value) / 10, mags.len - 1), | |
| 576 | else => unreachable, | |
| 577 | }; | |
| 578 | const new_value = f64(value) / math.pow(f64, f64(radix), f64(magnitude)); | |
| 556 | 579 | const suffix = mags[magnitude]; |
| 557 | 580 | |
| 558 | 581 | try formatFloatDecimal(new_value, width, context, Errors, output); |
| 559 | 582 | |
| 560 | if (suffix != ' ') { | |
| 561 | try output(context, (&suffix)[0..1]); | |
| 583 | if (suffix == ' ') { | |
| 584 | return output(context, "B"); | |
| 562 | 585 | } |
| 563 | return output(context, "B"); | |
| 586 | ||
| 587 | const buf = switch (radix) { | |
| 588 | 1000 => []u8 { suffix, 'B' }, | |
| 589 | 1024 => []u8 { suffix, 'i', 'B' }, | |
| 590 | else => unreachable, | |
| 591 | }; | |
| 592 | return output(context, buf); | |
| 564 | 593 | } |
| 565 | 594 | |
| 566 | 595 | pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize, |
| ... | ... | @@ -773,41 +802,27 @@ test "parse unsigned comptime" { |
| 773 | 802 | |
| 774 | 803 | test "fmt.format" { |
| 775 | 804 | { |
| 776 | var buf1: [32]u8 = undefined; | |
| 777 | 805 | const value: ?i32 = 1234; |
| 778 | const result = try bufPrint(buf1[0..], "nullable: {}\n", value); | |
| 779 | assert(mem.eql(u8, result, "nullable: 1234\n")); | |
| 806 | try testFmt("nullable: 1234\n", "nullable: {}\n", value); | |
| 780 | 807 | } |
| 781 | 808 | { |
| 782 | var buf1: [32]u8 = undefined; | |
| 783 | 809 | const value: ?i32 = null; |
| 784 | const result = try bufPrint(buf1[0..], "nullable: {}\n", value); | |
| 785 | assert(mem.eql(u8, result, "nullable: null\n")); | |
| 810 | try testFmt("nullable: null\n", "nullable: {}\n", value); | |
| 786 | 811 | } |
| 787 | 812 | { |
| 788 | var buf1: [32]u8 = undefined; | |
| 789 | 813 | const value: error!i32 = 1234; |
| 790 | const result = try bufPrint(buf1[0..], "error union: {}\n", value); | |
| 791 | assert(mem.eql(u8, result, "error union: 1234\n")); | |
| 814 | try testFmt("error union: 1234\n", "error union: {}\n", value); | |
| 792 | 815 | } |
| 793 | 816 | { |
| 794 | var buf1: [32]u8 = undefined; | |
| 795 | 817 | const value: error!i32 = error.InvalidChar; |
| 796 | const result = try bufPrint(buf1[0..], "error union: {}\n", value); | |
| 797 | assert(mem.eql(u8, result, "error union: error.InvalidChar\n")); | |
| 818 | try testFmt("error union: error.InvalidChar\n", "error union: {}\n", value); | |
| 798 | 819 | } |
| 799 | 820 | { |
| 800 | var buf1: [32]u8 = undefined; | |
| 801 | 821 | const value: u3 = 0b101; |
| 802 | const result = try bufPrint(buf1[0..], "u3: {}\n", value); | |
| 803 | assert(mem.eql(u8, result, "u3: 5\n")); | |
| 804 | } | |
| 805 | { | |
| 806 | var buf1: [32]u8 = undefined; | |
| 807 | const value: usize = 63 * 1024 * 1024; | |
| 808 | const result = try bufPrint(buf1[0..], "file size: {B}\n", value); | |
| 809 | assert(mem.eql(u8, result, "file size: 63MB\n")); | |
| 822 | try testFmt("u3: 5\n", "u3: {}\n", value); | |
| 810 | 823 | } |
| 824 | try testFmt("file size: 63MiB\n", "file size: {Bi}\n", usize(63 * 1024 * 1024)); | |
| 825 | try testFmt("file size: 66.06MB\n", "file size: {B2}\n", usize(63 * 1024 * 1024)); | |
| 811 | 826 | { |
| 812 | 827 | // Dummy field because of https://github.com/zig-lang/zig/issues/557. |
| 813 | 828 | const Struct = struct { |
| ... | ... | @@ -1025,6 +1040,20 @@ test "fmt.format" { |
| 1025 | 1040 | } |
| 1026 | 1041 | } |
| 1027 | 1042 | |
| 1043 | fn testFmt(expected: []const u8, comptime template: []const u8, args: ...) !void { | |
| 1044 | var buf: [100]u8 = undefined; | |
| 1045 | const result = try bufPrint(buf[0..], template, args); | |
| 1046 | if (mem.eql(u8, result, expected)) | |
| 1047 | return; | |
| 1048 | ||
| 1049 | std.debug.warn("\n====== expected this output: =========\n"); | |
| 1050 | std.debug.warn("{}", expected); | |
| 1051 | std.debug.warn("\n======== instead found this: =========\n"); | |
| 1052 | std.debug.warn("{}", result); | |
| 1053 | std.debug.warn("\n======================================\n"); | |
| 1054 | return error.TestFailed; | |
| 1055 | } | |
| 1056 | ||
| 1028 | 1057 | pub fn trim(buf: []const u8) []const u8 { |
| 1029 | 1058 | var start: usize = 0; |
| 1030 | 1059 | while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) {} |
std/segmented_list.zig+10-6| ... | ... | @@ -294,21 +294,25 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 294 | 294 | |
| 295 | 295 | return &it.list.dynamic_segments[it.shelf_index][it.box_index]; |
| 296 | 296 | } |
| 297 | ||
| 298 | pub fn set(it: &Iterator, index: usize) void { | |
| 299 | it.index = index; | |
| 300 | if (index < prealloc_item_count) return; | |
| 301 | it.shelf_index = shelfIndex(index); | |
| 302 | it.box_index = boxIndex(index, it.shelf_index); | |
| 303 | it.shelf_size = shelfSize(it.shelf_index); | |
| 304 | } | |
| 297 | 305 | }; |
| 298 | 306 | |
| 299 | 307 | pub fn iterator(self: &Self, start_index: usize) Iterator { |
| 300 | 308 | var it = Iterator{ |
| 301 | 309 | .list = self, |
| 302 | .index = start_index, | |
| 310 | .index = undefined, | |
| 303 | 311 | .shelf_index = undefined, |
| 304 | 312 | .box_index = undefined, |
| 305 | 313 | .shelf_size = undefined, |
| 306 | 314 | }; |
| 307 | if (start_index >= prealloc_item_count) { | |
| 308 | it.shelf_index = shelfIndex(start_index); | |
| 309 | it.box_index = boxIndex(start_index, it.shelf_index); | |
| 310 | it.shelf_size = shelfSize(it.shelf_index); | |
| 311 | } | |
| 315 | it.set(start_index); | |
| 312 | 316 | return it; |
| 313 | 317 | } |
| 314 | 318 | }; |
std/zig/parse.zig+9-1| ... | ... | @@ -927,6 +927,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 927 | 927 | continue; |
| 928 | 928 | }, |
| 929 | 929 | State.Else => |dest| { |
| 930 | const old_index = tok_it.index; | |
| 931 | var need_index_restore = false; | |
| 932 | while (try eatLineComment(arena, &tok_it, &tree)) |_| { | |
| 933 | need_index_restore = true; | |
| 934 | } | |
| 930 | 935 | if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| { |
| 931 | 936 | const node = try arena.construct(ast.Node.Else{ |
| 932 | 937 | .base = ast.Node{ .id = ast.Node.Id.Else }, |
| ... | ... | @@ -940,6 +945,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 940 | 945 | try stack.append(State{ .Payload = OptionalCtx{ .Optional = &node.payload } }); |
| 941 | 946 | continue; |
| 942 | 947 | } else { |
| 948 | if (need_index_restore) { | |
| 949 | tok_it.set(old_index); | |
| 950 | } | |
| 943 | 951 | continue; |
| 944 | 952 | } |
| 945 | 953 | }, |
| ... | ... | @@ -1297,7 +1305,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1297 | 1305 | }, |
| 1298 | 1306 | |
| 1299 | 1307 | State.SwitchCaseCommaOrEnd => |list_state| { |
| 1300 | switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) { | |
| 1308 | switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) { | |
| 1301 | 1309 | ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| { |
| 1302 | 1310 | (list_state.ptr).* = end; |
| 1303 | 1311 | continue; |
std/zig/parser_test.zig+92| ... | ... | @@ -1,3 +1,95 @@ |
| 1 | test "zig fmt: comment after if before another if" { | |
| 2 | try testCanonical( | |
| 3 | \\test "aoeu" { | |
| 4 | \\ if (x) { | |
| 5 | \\ foo(); | |
| 6 | \\ } | |
| 7 | \\ // comment | |
| 8 | \\ if (x) { | |
| 9 | \\ bar(); | |
| 10 | \\ } | |
| 11 | \\} | |
| 12 | \\ | |
| 13 | ); | |
| 14 | } | |
| 15 | ||
| 16 | test "zig fmt: line comment between if block and else keyword" { | |
| 17 | try testTransform( | |
| 18 | \\test "aoeu" { | |
| 19 | \\ // cexp(finite|nan +- i inf|nan) = nan + i nan | |
| 20 | \\ if ((hx & 0x7fffffff) != 0x7f800000) { | |
| 21 | \\ return Complex(f32).new(y - y, y - y); | |
| 22 | \\ } | |
| 23 | \\ // cexp(-inf +- i inf|nan) = 0 + i0 | |
| 24 | \\ else if (hx & 0x80000000 != 0) { | |
| 25 | \\ return Complex(f32).new(0, 0); | |
| 26 | \\ } | |
| 27 | \\ // cexp(+inf +- i inf|nan) = inf + i nan | |
| 28 | \\ // another comment | |
| 29 | \\ else { | |
| 30 | \\ return Complex(f32).new(x, y - y); | |
| 31 | \\ } | |
| 32 | \\} | |
| 33 | , | |
| 34 | \\test "aoeu" { | |
| 35 | \\ // cexp(finite|nan +- i inf|nan) = nan + i nan | |
| 36 | \\ if ((hx & 0x7fffffff) != 0x7f800000) { | |
| 37 | \\ return Complex(f32).new(y - y, y - y); | |
| 38 | \\ } // cexp(-inf +- i inf|nan) = 0 + i0 | |
| 39 | \\ else if (hx & 0x80000000 != 0) { | |
| 40 | \\ return Complex(f32).new(0, 0); | |
| 41 | \\ } // cexp(+inf +- i inf|nan) = inf + i nan | |
| 42 | \\ // another comment | |
| 43 | \\ else { | |
| 44 | \\ return Complex(f32).new(x, y - y); | |
| 45 | \\ } | |
| 46 | \\} | |
| 47 | \\ | |
| 48 | ); | |
| 49 | } | |
| 50 | ||
| 51 | test "zig fmt: same line comments in expression" { | |
| 52 | try testCanonical( | |
| 53 | \\test "aoeu" { | |
| 54 | \\ const x = ( // a | |
| 55 | \\ 0 // b | |
| 56 | \\ ); // c | |
| 57 | \\} | |
| 58 | \\ | |
| 59 | ); | |
| 60 | } | |
| 61 | ||
| 62 | test "zig fmt: add comma on last switch prong" { | |
| 63 | try testTransform( | |
| 64 | \\test "aoeu" { | |
| 65 | \\switch (self.init_arg_expr) { | |
| 66 | \\ InitArg.Type => |t| { }, | |
| 67 | \\ InitArg.None, | |
| 68 | \\ InitArg.Enum => { } | |
| 69 | \\} | |
| 70 | \\ switch (self.init_arg_expr) { | |
| 71 | \\ InitArg.Type => |t| { }, | |
| 72 | \\ InitArg.None, | |
| 73 | \\ InitArg.Enum => { }//line comment | |
| 74 | \\ } | |
| 75 | \\} | |
| 76 | , | |
| 77 | \\test "aoeu" { | |
| 78 | \\ switch (self.init_arg_expr) { | |
| 79 | \\ InitArg.Type => |t| {}, | |
| 80 | \\ InitArg.None, | |
| 81 | \\ InitArg.Enum => {}, | |
| 82 | \\ } | |
| 83 | \\ switch (self.init_arg_expr) { | |
| 84 | \\ InitArg.Type => |t| {}, | |
| 85 | \\ InitArg.None, | |
| 86 | \\ InitArg.Enum => {}, //line comment | |
| 87 | \\ } | |
| 88 | \\} | |
| 89 | \\ | |
| 90 | ); | |
| 91 | } | |
| 92 | ||
| 1 | 93 | test "zig fmt: same-line doc comment on variable declaration" { |
| 2 | 94 | try testTransform( |
| 3 | 95 | \\pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space |
std/zig/render.zig+45-16| ... | ... | @@ -81,7 +81,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i |
| 81 | 81 | } |
| 82 | 82 | try stream.print("{}: ", tree.tokenSlice(field.name_token)); |
| 83 | 83 | try renderExpression(allocator, stream, tree, indent, field.type_expr); |
| 84 | try renderToken(tree, stream, field.lastToken() + 1, indent, true); | |
| 84 | try renderToken(tree, stream, field.lastToken() + 1, indent, true, true); | |
| 85 | 85 | }, |
| 86 | 86 | ast.Node.Id.UnionTag => { |
| 87 | 87 | const tag = @fieldParentPtr(ast.Node.UnionTag, "base", decl); |
| ... | ... | @@ -514,9 +514,9 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 514 | 514 | ast.Node.Id.GroupedExpression => { |
| 515 | 515 | const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base); |
| 516 | 516 | |
| 517 | try stream.write("("); | |
| 517 | try renderToken(tree, stream, grouped_expr.lparen, indent, false, false); | |
| 518 | 518 | try renderExpression(allocator, stream, tree, indent, grouped_expr.expr); |
| 519 | try stream.write(")"); | |
| 519 | try renderToken(tree, stream, grouped_expr.rparen, indent, false, false); | |
| 520 | 520 | }, |
| 521 | 521 | |
| 522 | 522 | ast.Node.Id.FieldInitializer => { |
| ... | ... | @@ -528,7 +528,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 528 | 528 | |
| 529 | 529 | ast.Node.Id.IntegerLiteral => { |
| 530 | 530 | const integer_literal = @fieldParentPtr(ast.Node.IntegerLiteral, "base", base); |
| 531 | try stream.print("{}", tree.tokenSlice(integer_literal.token)); | |
| 531 | try renderToken(tree, stream, integer_literal.token, indent, false, false); | |
| 532 | 532 | }, |
| 533 | 533 | ast.Node.Id.FloatLiteral => { |
| 534 | 534 | const float_literal = @fieldParentPtr(ast.Node.FloatLiteral, "base", base); |
| ... | ... | @@ -536,7 +536,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 536 | 536 | }, |
| 537 | 537 | ast.Node.Id.StringLiteral => { |
| 538 | 538 | const string_literal = @fieldParentPtr(ast.Node.StringLiteral, "base", base); |
| 539 | try stream.print("{}", tree.tokenSlice(string_literal.token)); | |
| 539 | try renderToken(tree, stream, string_literal.token, indent, false, false); | |
| 540 | 540 | }, |
| 541 | 541 | ast.Node.Id.CharLiteral => { |
| 542 | 542 | const char_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base); |
| ... | ... | @@ -830,7 +830,20 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 830 | 830 | } |
| 831 | 831 | |
| 832 | 832 | try renderExpression(allocator, stream, tree, indent, switch_case.expr); |
| 833 | try renderToken(tree, stream, switch_case.lastToken() + 1, indent, true); | |
| 833 | { | |
| 834 | // Handle missing comma after last switch case | |
| 835 | var index = switch_case.lastToken() + 1; | |
| 836 | switch (tree.tokens.at(index).id) { | |
| 837 | Token.Id.RBrace => { | |
| 838 | try stream.write(","); | |
| 839 | }, | |
| 840 | Token.Id.LineComment => { | |
| 841 | try stream.write(", "); | |
| 842 | try renderToken(tree, stream, index, indent, true, true); | |
| 843 | }, | |
| 844 | else => try renderToken(tree, stream, index, indent, true, true), | |
| 845 | } | |
| 846 | } | |
| 834 | 847 | }, |
| 835 | 848 | ast.Node.Id.SwitchElse => { |
| 836 | 849 | const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base); |
| ... | ... | @@ -838,6 +851,15 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 838 | 851 | }, |
| 839 | 852 | ast.Node.Id.Else => { |
| 840 | 853 | const else_node = @fieldParentPtr(ast.Node.Else, "base", base); |
| 854 | ||
| 855 | var prev_tok_index = else_node.else_token - 1; | |
| 856 | while (tree.tokens.at(prev_tok_index).id == Token.Id.LineComment) : (prev_tok_index -= 1) { } | |
| 857 | prev_tok_index += 1; | |
| 858 | while (prev_tok_index < else_node.else_token) : (prev_tok_index += 1) { | |
| 859 | try stream.print("{}\n", tree.tokenSlice(prev_tok_index)); | |
| 860 | try stream.writeByteNTimes(' ', indent); | |
| 861 | } | |
| 862 | ||
| 841 | 863 | try stream.print("{}", tree.tokenSlice(else_node.else_token)); |
| 842 | 864 | |
| 843 | 865 | const block_body = switch (else_node.body.id) { |
| ... | ... | @@ -959,7 +981,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 959 | 981 | try stream.print("{} (", tree.tokenSlice(if_node.if_token)); |
| 960 | 982 | |
| 961 | 983 | try renderExpression(allocator, stream, tree, indent, if_node.condition); |
| 962 | try renderToken(tree, stream, if_node.condition.lastToken() + 1, indent, false); | |
| 984 | try renderToken(tree, stream, if_node.condition.lastToken() + 1, indent, false, true); | |
| 963 | 985 | |
| 964 | 986 | if (if_node.payload) |payload| { |
| 965 | 987 | try renderExpression(allocator, stream, tree, indent, payload); |
| ... | ... | @@ -1118,11 +1140,11 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 1118 | 1140 | |
| 1119 | 1141 | fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, var_decl: &ast.Node.VarDecl) (@typeOf(stream).Child.Error || Error)!void { |
| 1120 | 1142 | if (var_decl.visib_token) |visib_token| { |
| 1121 | try stream.print("{} ", tree.tokenSlice(visib_token)); | |
| 1143 | try renderToken(tree, stream, visib_token, indent, false, true); | |
| 1122 | 1144 | } |
| 1123 | 1145 | |
| 1124 | 1146 | if (var_decl.extern_export_token) |extern_export_token| { |
| 1125 | try stream.print("{} ", tree.tokenSlice(extern_export_token)); | |
| 1147 | try renderToken(tree, stream, extern_export_token, indent, false, true); | |
| 1126 | 1148 | |
| 1127 | 1149 | if (var_decl.lib_name) |lib_name| { |
| 1128 | 1150 | try renderExpression(allocator, stream, tree, indent, lib_name); |
| ... | ... | @@ -1131,10 +1153,11 @@ fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent |
| 1131 | 1153 | } |
| 1132 | 1154 | |
| 1133 | 1155 | if (var_decl.comptime_token) |comptime_token| { |
| 1134 | try stream.print("{} ", tree.tokenSlice(comptime_token)); | |
| 1156 | try renderToken(tree, stream, comptime_token, indent, false, true); | |
| 1135 | 1157 | } |
| 1136 | 1158 | |
| 1137 | try stream.print("{} {}", tree.tokenSlice(var_decl.mut_token), tree.tokenSlice(var_decl.name_token)); | |
| 1159 | try renderToken(tree, stream, var_decl.mut_token, indent, false, true); | |
| 1160 | try renderToken(tree, stream, var_decl.name_token, indent, false, false); | |
| 1138 | 1161 | |
| 1139 | 1162 | if (var_decl.type_node) |type_node| { |
| 1140 | 1163 | try stream.write(": "); |
| ... | ... | @@ -1153,14 +1176,14 @@ fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent |
| 1153 | 1176 | try renderExpression(allocator, stream, tree, indent, init_node); |
| 1154 | 1177 | } |
| 1155 | 1178 | |
| 1156 | try renderToken(tree, stream, var_decl.semicolon_token, indent, true); | |
| 1179 | try renderToken(tree, stream, var_decl.semicolon_token, indent, true, false); | |
| 1157 | 1180 | } |
| 1158 | 1181 | |
| 1159 | 1182 | fn maybeRenderSemicolon(stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node) (@typeOf(stream).Child.Error || Error)!void { |
| 1160 | 1183 | if (base.requireSemiColon()) { |
| 1161 | 1184 | const semicolon_index = base.lastToken() + 1; |
| 1162 | 1185 | assert(tree.tokens.at(semicolon_index).id == Token.Id.Semicolon); |
| 1163 | try renderToken(tree, stream, semicolon_index, indent, true); | |
| 1186 | try renderToken(tree, stream, semicolon_index, indent, true, true); | |
| 1164 | 1187 | } |
| 1165 | 1188 | } |
| 1166 | 1189 | |
| ... | ... | @@ -1195,7 +1218,7 @@ fn renderStatement(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, inde |
| 1195 | 1218 | } |
| 1196 | 1219 | } |
| 1197 | 1220 | |
| 1198 | fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, line_break: bool) (@typeOf(stream).Child.Error || Error)!void { | |
| 1221 | fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, line_break: bool, space: bool) (@typeOf(stream).Child.Error || Error)!void { | |
| 1199 | 1222 | const token = tree.tokens.at(token_index); |
| 1200 | 1223 | try stream.write(tree.tokenSlicePtr(token)); |
| 1201 | 1224 | |
| ... | ... | @@ -1206,13 +1229,19 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent |
| 1206 | 1229 | try stream.print(" {}", tree.tokenSlicePtr(next_token)); |
| 1207 | 1230 | if (!line_break) { |
| 1208 | 1231 | try stream.write("\n"); |
| 1209 | try stream.writeByteNTimes(' ', indent + indent_delta); | |
| 1232 | ||
| 1233 | const after_comment_token = tree.tokens.at(token_index + 2); | |
| 1234 | const next_line_indent = switch (after_comment_token.id) { | |
| 1235 | Token.Id.RParen, Token.Id.RBrace, Token.Id.RBracket => indent, | |
| 1236 | else => indent + indent_delta, | |
| 1237 | }; | |
| 1238 | try stream.writeByteNTimes(' ', next_line_indent); | |
| 1210 | 1239 | return; |
| 1211 | 1240 | } |
| 1212 | 1241 | } |
| 1213 | 1242 | } |
| 1214 | 1243 | |
| 1215 | if (!line_break) { | |
| 1244 | if (!line_break and space) { | |
| 1216 | 1245 | try stream.writeByte(' '); |
| 1217 | 1246 | } |
| 1218 | 1247 | } |