authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-19 23:07:16-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-19 23:08:48-04:00
log82225f6568969856ffe9363d2b8b0f39548bd9df
treea74377f8e12cfd8c26fb001dc90a6230ff28c5cb
parent93384f7428c5186a1b44c6f5f8891ce40bc46e72

zig fmt parser tests are compiling again


2 files changed, 238 insertions(+), 185 deletions(-)

lib/std/zig/ast.zig+2-2
...@@ -36,7 +36,7 @@ pub const Tree = struct {...@@ -36,7 +36,7 @@ pub const Tree = struct {
36 return self.tokenSlicePtr(self.tokens[token_index]);36 return self.tokenSlicePtr(self.tokens[token_index]);
37 }37 }
3838
39 pub fn tokenSlicePtr(self: *Tree, token: *const Token) []const u8 {39 pub fn tokenSlicePtr(self: *Tree, token: Token) []const u8 {
40 return self.source[token.start..token.end];40 return self.source[token.start..token.end];
41 }41 }
4242
...@@ -89,7 +89,7 @@ pub const Tree = struct {...@@ -89,7 +89,7 @@ pub const Tree = struct {
89 return self.tokensOnSameLinePtr(self.tokens[token1_index], self.tokens[token2_index]);89 return self.tokensOnSameLinePtr(self.tokens[token1_index], self.tokens[token2_index]);
90 }90 }
9191
92 pub fn tokensOnSameLinePtr(self: *Tree, token1: *const Token, token2: *const Token) bool {92 pub fn tokensOnSameLinePtr(self: *Tree, token1: Token, token2: Token) bool {
93 return mem.indexOfScalar(u8, self.source[token1.end..token2.start], '\n') == null;93 return mem.indexOfScalar(u8, self.source[token1.end..token2.start], '\n') == null;
94 }94 }
9595
lib/std/zig/render.zig+236-183
...@@ -68,7 +68,7 @@ fn renderRoot(...@@ -68,7 +68,7 @@ fn renderRoot(
68 tree: *ast.Tree,68 tree: *ast.Tree,
69) (@TypeOf(stream).Error || Error)!void {69) (@TypeOf(stream).Error || Error)!void {
70 // render all the line comments at the beginning of the file70 // render all the line comments at the beginning of the file
71 for (tree.tokens) |*token, i| {71 for (tree.tokens) |token, i| {
72 if (token.id != .LineComment) break;72 if (token.id != .LineComment) break;
73 try stream.print("{}\n", .{mem.trimRight(u8, tree.tokenSlicePtr(token), " ")});73 try stream.print("{}\n", .{mem.trimRight(u8, tree.tokenSlicePtr(token), " ")});
74 const next_token = &tree.tokens[i + 1];74 const next_token = &tree.tokens[i + 1];
...@@ -321,10 +321,10 @@ fn renderContainerDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree,...@@ -321,10 +321,10 @@ fn renderContainerDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree,
321321
322 .DocComment => {322 .DocComment => {
323 const comment = @fieldParentPtr(ast.Node.DocComment, "base", decl);323 const comment = @fieldParentPtr(ast.Node.DocComment, "base", decl);
324 var it = comment.lines.iterator(0);324 var it = comment.lines.first;
325 while (it.next()) |line_token_index| {325 while (it) |node| : (it = node.next) {
326 try renderToken(tree, stream, line_token_index.*, indent, start_col, .Newline);326 try renderToken(tree, stream, node.data, indent, start_col, .Newline);
327 if (it.peek()) |_| {327 if (node.next != null) {
328 try stream.writeByteNTimes(' ', indent);328 try stream.writeByteNTimes(' ', indent);
329 }329 }
330 }330 }
...@@ -355,20 +355,21 @@ fn renderExpression(...@@ -355,20 +355,21 @@ fn renderExpression(
355 try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space);355 try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space);
356 }356 }
357357
358 if (block.statements.len == 0) {358 if (block.statements.first == null) {
359 try renderToken(tree, stream, block.lbrace, indent + indent_delta, start_col, Space.None);359 try renderToken(tree, stream, block.lbrace, indent + indent_delta, start_col, Space.None);
360 return renderToken(tree, stream, block.rbrace, indent, start_col, space);360 return renderToken(tree, stream, block.rbrace, indent, start_col, space);
361 } else {361 } else {
362 const block_indent = indent + indent_delta;362 const block_indent = indent + indent_delta;
363 try renderToken(tree, stream, block.lbrace, block_indent, start_col, Space.Newline);363 try renderToken(tree, stream, block.lbrace, block_indent, start_col, Space.Newline);
364364
365 var it = block.statements.iterator(0);365 var it = block.statements.first;
366 while (it.next()) |statement| {366 while (it) |statement_node| : (it = statement_node.next) {
367 const statement = statement_node.data;
367 try stream.writeByteNTimes(' ', block_indent);368 try stream.writeByteNTimes(' ', block_indent);
368 try renderStatement(allocator, stream, tree, block_indent, start_col, statement.*);369 try renderStatement(allocator, stream, tree, block_indent, start_col, statement);
369370
370 if (it.peek()) |next_statement| {371 if (statement_node.next) |next_statement| {
371 try renderExtraNewline(tree, stream, start_col, next_statement.*);372 try renderExtraNewline(tree, stream, start_col, next_statement.data);
372 }373 }
373 }374 }
374375
...@@ -620,7 +621,7 @@ fn renderExpression(...@@ -620,7 +621,7 @@ fn renderExpression(
620621
621 const lparen = tree.nextToken(suffix_op.lhs.node.lastToken());622 const lparen = tree.nextToken(suffix_op.lhs.node.lastToken());
622623
623 if (call_info.params.len == 0) {624 if (call_info.params.first == null) {
624 try renderToken(tree, stream, lparen, indent, start_col, Space.None);625 try renderToken(tree, stream, lparen, indent, start_col, Space.None);
625 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);626 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
626 }627 }
...@@ -634,24 +635,26 @@ fn renderExpression(...@@ -634,24 +635,26 @@ fn renderExpression(
634 const new_indent = indent + indent_delta;635 const new_indent = indent + indent_delta;
635 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline);636 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline);
636637
637 var it = call_info.params.iterator(0);638 var it = call_info.params.first;
638 while (true) {639 while (true) {
639 const param_node = it.next().?;640 const param_node_node = it.?;
641 it = param_node_node.next;
642 const param_node = param_node_node.data;
640643
641 const param_node_new_indent = if (param_node.*.id == .MultilineStringLiteral) blk: {644 const param_node_new_indent = if (param_node.id == .MultilineStringLiteral) blk: {
642 break :blk indent;645 break :blk indent;
643 } else blk: {646 } else blk: {
644 try stream.writeByteNTimes(' ', new_indent);647 try stream.writeByteNTimes(' ', new_indent);
645 break :blk new_indent;648 break :blk new_indent;
646 };649 };
647650
648 if (it.peek()) |next_node| {651 if (it) |next_node| {
649 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node.*, Space.None);652 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node, Space.None);
650 const comma = tree.nextToken(param_node.*.lastToken());653 const comma = tree.nextToken(param_node.lastToken());
651 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,654 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,
652 try renderExtraNewline(tree, stream, start_col, next_node.*);655 try renderExtraNewline(tree, stream, start_col, next_node.data);
653 } else {656 } else {
654 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node.*, Space.Comma);657 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node, Space.Comma);
655 try stream.writeByteNTimes(' ', indent);658 try stream.writeByteNTimes(' ', indent);
656 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);659 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
657 }660 }
...@@ -660,12 +663,13 @@ fn renderExpression(...@@ -660,12 +663,13 @@ fn renderExpression(
660663
661 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (664 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
662665
663 var it = call_info.params.iterator(0);666 var it = call_info.params.first;
664 while (it.next()) |param_node| {667 while (it) |param_node_node| : (it = param_node_node.next) {
665 try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.None);668 const param_node = param_node_node.data;
669 try renderExpression(allocator, stream, tree, indent, start_col, param_node, Space.None);
666670
667 if (it.peek() != null) {671 if (param_node_node.next != null) {
668 const comma = tree.nextToken(param_node.*.lastToken());672 const comma = tree.nextToken(param_node.lastToken());
669 try renderToken(tree, stream, comma, indent, start_col, Space.Space);673 try renderToken(tree, stream, comma, indent, start_col, Space.Space);
670 }674 }
671 }675 }
...@@ -736,7 +740,7 @@ fn renderExpression(...@@ -736,7 +740,7 @@ fn renderExpression(
736 .node => |node| tree.nextToken(node.lastToken()),740 .node => |node| tree.nextToken(node.lastToken()),
737 };741 };
738742
739 if (field_inits.len == 0) {743 if (field_inits.first == null) {
740 switch (suffix_op.lhs) {744 switch (suffix_op.lhs) {
741 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),745 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
742 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),746 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
...@@ -757,18 +761,19 @@ fn renderExpression(...@@ -757,18 +761,19 @@ fn renderExpression(
757761
758 const expr_outputs_one_line = blk: {762 const expr_outputs_one_line = blk: {
759 // render field expressions until a LF is found763 // render field expressions until a LF is found
760 var it = field_inits.iterator(0);764 var it = field_inits.first;
761 while (it.next()) |field_init| {765 while (it) |field_init_node| : (it = field_init_node.next) {
766 const field_init = field_init_node.data;
762 var find_stream = FindByteOutStream.init('\n');767 var find_stream = FindByteOutStream.init('\n');
763 var dummy_col: usize = 0;768 var dummy_col: usize = 0;
764 try renderExpression(allocator, find_stream.outStream(), tree, 0, &dummy_col, field_init.*, Space.None);769 try renderExpression(allocator, find_stream.outStream(), tree, 0, &dummy_col, field_init, Space.None);
765 if (find_stream.byte_found) break :blk false;770 if (find_stream.byte_found) break :blk false;
766 }771 }
767 break :blk true;772 break :blk true;
768 };773 };
769774
770 if (field_inits.len == 1) blk: {775 if (field_inits.first != null and field_inits.first.?.next == null) blk: {
771 const field_init = field_inits.at(0).*.cast(ast.Node.FieldInitializer).?;776 const field_init = field_inits.first.?.data.cast(ast.Node.FieldInitializer).?;
772777
773 if (field_init.expr.cast(ast.Node.SuffixOp)) |nested_suffix_op| {778 if (field_init.expr.cast(ast.Node.SuffixOp)) |nested_suffix_op| {
774 if (nested_suffix_op.op == .StructInitializer) {779 if (nested_suffix_op.op == .StructInitializer) {
...@@ -798,15 +803,16 @@ fn renderExpression(...@@ -798,15 +803,16 @@ fn renderExpression(
798 }803 }
799 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);804 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
800805
801 var it = field_inits.iterator(0);806 var it = field_inits.first;
802 while (it.next()) |field_init| {807 while (it) |field_init_node| : (it = field_init_node.next) {
803 if (it.peek() != null) {808 const field_init = field_init_node.data;
804 try renderExpression(allocator, stream, tree, indent, start_col, field_init.*, Space.None);809 if (field_init_node.next != null) {
810 try renderExpression(allocator, stream, tree, indent, start_col, field_init, Space.None);
805811
806 const comma = tree.nextToken(field_init.*.lastToken());812 const comma = tree.nextToken(field_init.lastToken());
807 try renderToken(tree, stream, comma, indent, start_col, Space.Space);813 try renderToken(tree, stream, comma, indent, start_col, Space.Space);
808 } else {814 } else {
809 try renderExpression(allocator, stream, tree, indent, start_col, field_init.*, Space.Space);815 try renderExpression(allocator, stream, tree, indent, start_col, field_init, Space.Space);
810 }816 }
811 }817 }
812818
...@@ -821,19 +827,20 @@ fn renderExpression(...@@ -821,19 +827,20 @@ fn renderExpression(
821 }827 }
822 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);828 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
823829
824 var it = field_inits.iterator(0);830 var it = field_inits.first;
825 while (it.next()) |field_init| {831 while (it) |field_init_node| : (it = field_init_node.next) {
832 const field_init = field_init_node.data;
826 try stream.writeByteNTimes(' ', new_indent);833 try stream.writeByteNTimes(' ', new_indent);
827834
828 if (it.peek()) |next_field_init| {835 if (field_init_node.next) |next_field_init| {
829 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init.*, Space.None);836 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init, Space.None);
830837
831 const comma = tree.nextToken(field_init.*.lastToken());838 const comma = tree.nextToken(field_init.lastToken());
832 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline);839 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline);
833840
834 try renderExtraNewline(tree, stream, start_col, next_field_init.*);841 try renderExtraNewline(tree, stream, start_col, next_field_init.data);
835 } else {842 } else {
836 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init.*, Space.Comma);843 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init, Space.Comma);
837 }844 }
838 }845 }
839846
...@@ -847,7 +854,7 @@ fn renderExpression(...@@ -847,7 +854,7 @@ fn renderExpression(
847 .node => |node| tree.nextToken(node.lastToken()),854 .node => |node| tree.nextToken(node.lastToken()),
848 };855 };
849856
850 if (exprs.len == 0) {857 if (exprs.first == null) {
851 switch (suffix_op.lhs) {858 switch (suffix_op.lhs) {
852 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),859 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
853 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),860 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
...@@ -855,16 +862,17 @@ fn renderExpression(...@@ -855,16 +862,17 @@ fn renderExpression(
855 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);862 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
856 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);863 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
857 }864 }
858 if (exprs.len == 1 and tree.tokens[exprs.at(0).*.lastToken() + 1].id == .RBrace) {865 if (exprs.first) |first_expr_node| {
859 const expr = exprs.at(0).*;866 const expr = first_expr_node.data;
860867 if (first_expr_node.next == null and tree.tokens[expr.lastToken() + 1].id == .RBrace) {
861 switch (suffix_op.lhs) {868 switch (suffix_op.lhs) {
862 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),869 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
863 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),870 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
871 }
872 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
873 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
874 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
864 }875 }
865 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
866 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
867 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
868 }876 }
869877
870 switch (suffix_op.lhs) {878 switch (suffix_op.lhs) {
...@@ -875,16 +883,18 @@ fn renderExpression(...@@ -875,16 +883,18 @@ fn renderExpression(
875 // scan to find row size883 // scan to find row size
876 const maybe_row_size: ?usize = blk: {884 const maybe_row_size: ?usize = blk: {
877 var count: usize = 1;885 var count: usize = 1;
878 var it = exprs.iterator(0);886 var it = exprs.first;
879 while (true) {887 while (true) {
880 const expr = it.next().?.*;888 const expr_node = it.?;
881 if (it.peek()) |next_expr| {889 it = expr_node.next;
882 const expr_last_token = expr.*.lastToken() + 1;890 const expr = expr_node.data;
883 const loc = tree.tokenLocation(tree.tokens[expr_last_token].end, next_expr.*.firstToken());891 if (expr_node.next) |next_expr| {
892 const expr_last_token = expr.lastToken() + 1;
893 const loc = tree.tokenLocation(tree.tokens[expr_last_token].end, next_expr.data.firstToken());
884 if (loc.line != 0) break :blk count;894 if (loc.line != 0) break :blk count;
885 count += 1;895 count += 1;
886 } else {896 } else {
887 const expr_last_token = expr.*.lastToken();897 const expr_last_token = expr.lastToken();
888 const loc = tree.tokenLocation(tree.tokens[expr_last_token].end, suffix_op.rtoken);898 const loc = tree.tokenLocation(tree.tokens[expr_last_token].end, suffix_op.rtoken);
889 if (loc.line == 0) {899 if (loc.line == 0) {
890 // all on one line900 // all on one line
...@@ -905,7 +915,8 @@ fn renderExpression(...@@ -905,7 +915,8 @@ fn renderExpression(
905915
906 if (maybe_row_size) |row_size| {916 if (maybe_row_size) |row_size| {
907 // A place to store the width of each expression and its column's maximum917 // A place to store the width of each expression and its column's maximum
908 var widths = try allocator.alloc(usize, exprs.len + row_size);918 const exprs_len = countLen(exprs.first);
919 var widths = try allocator.alloc(usize, exprs_len + row_size);
909 defer allocator.free(widths);920 defer allocator.free(widths);
910 mem.set(usize, widths, 0);921 mem.set(usize, widths, 0);
911922
...@@ -915,13 +926,14 @@ fn renderExpression(...@@ -915,13 +926,14 @@ fn renderExpression(
915 // Null stream for counting the printed length of each expression926 // Null stream for counting the printed length of each expression
916 var counting_stream = std.io.countingOutStream(std.io.null_out_stream);927 var counting_stream = std.io.countingOutStream(std.io.null_out_stream);
917928
918 var it = exprs.iterator(0);929 var it = exprs.first;
919 var i: usize = 0;930 var i: usize = 0;
920931
921 while (it.next()) |expr| : (i += 1) {932 while (it) |expr_node| : ({i += 1; it = expr_node.next;}) {
933 const expr = expr_node.data;
922 counting_stream.bytes_written = 0;934 counting_stream.bytes_written = 0;
923 var dummy_col: usize = 0;935 var dummy_col: usize = 0;
924 try renderExpression(allocator, counting_stream.outStream(), tree, indent, &dummy_col, expr.*, Space.None);936 try renderExpression(allocator, counting_stream.outStream(), tree, indent, &dummy_col, expr, Space.None);
925 const width = @intCast(usize, counting_stream.bytes_written);937 const width = @intCast(usize, counting_stream.bytes_written);
926 const col = i % row_size;938 const col = i % row_size;
927 column_widths[col] = std.math.max(column_widths[col], width);939 column_widths[col] = std.math.max(column_widths[col], width);
...@@ -938,14 +950,16 @@ fn renderExpression(...@@ -938,14 +950,16 @@ fn renderExpression(
938 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.None);950 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.None);
939 }951 }
940952
941 it.set(0);953 it = exprs.first;
942 i = 0;954 i = 0;
943 var col: usize = 1;955 var col: usize = 1;
944 while (it.next()) |expr| : (i += 1) {956 var last_node = it.?;
945 if (it.peek()) |next_expr| {957 while (it) |expr_node| : ({i += 1; it = expr_node.next; last_node = expr_node;}) {
946 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.None);958 const expr = expr_node.data;
959 if (expr_node.next) |next_expr| {
960 try renderExpression(allocator, stream, tree, new_indent, start_col, expr, Space.None);
947961
948 const comma = tree.nextToken(expr.*.lastToken());962 const comma = tree.nextToken(expr.lastToken());
949963
950 if (col != row_size) {964 if (col != row_size) {
951 try renderToken(tree, stream, comma, new_indent, start_col, Space.Space); // ,965 try renderToken(tree, stream, comma, new_indent, start_col, Space.Space); // ,
...@@ -964,29 +978,29 @@ fn renderExpression(...@@ -964,29 +978,29 @@ fn renderExpression(
964 try renderToken(tree, stream, comma, new_indent, start_col, Space.None); // ,978 try renderToken(tree, stream, comma, new_indent, start_col, Space.None); // ,
965 }979 }
966980
967 try renderExtraNewline(tree, stream, start_col, next_expr.*);981 try renderExtraNewline(tree, stream, start_col, next_expr.data);
968 if (next_expr.*.id != .MultilineStringLiteral) {982 if (next_expr.data.id != .MultilineStringLiteral) {
969 try stream.writeByteNTimes(' ', new_indent);983 try stream.writeByteNTimes(' ', new_indent);
970 }984 }
971 } else {985 } else {
972 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // ,986 try renderExpression(allocator, stream, tree, new_indent, start_col, expr, Space.Comma); // ,
973 }987 }
974 }988 }
975 const last_node = it.prev().?;989 if (last_node.data.id != .MultilineStringLiteral) {
976 if (last_node.*.id != .MultilineStringLiteral) {
977 try stream.writeByteNTimes(' ', indent);990 try stream.writeByteNTimes(' ', indent);
978 }991 }
979 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);992 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
980 } else {993 } else {
981 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);994 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
982 var it = exprs.iterator(0);995 var it = exprs.first;
983 while (it.next()) |expr| {996 while (it) |expr_node| : (it = expr_node.next) {
984 if (it.peek()) |next_expr| {997 const expr = expr_node.data;
985 try renderExpression(allocator, stream, tree, indent, start_col, expr.*, Space.None);998 if (expr_node.next) |next_expr| {
986 const comma = tree.nextToken(expr.*.lastToken());999 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
1000 const comma = tree.nextToken(expr.lastToken());
987 try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,1001 try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,
988 } else {1002 } else {
989 try renderExpression(allocator, stream, tree, indent, start_col, expr.*, Space.Space);1003 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.Space);
990 }1004 }
991 }1005 }
9921006
...@@ -1176,7 +1190,7 @@ fn renderExpression(...@@ -1176,7 +1190,7 @@ fn renderExpression(
1176 },1190 },
1177 }1191 }
11781192
1179 if (container_decl.fields_and_decls.len == 0) {1193 if (container_decl.fields_and_decls.first == null) {
1180 try renderToken(tree, stream, container_decl.lbrace_token, indent + indent_delta, start_col, Space.None); // {1194 try renderToken(tree, stream, container_decl.lbrace_token, indent + indent_delta, start_col, Space.None); // {
1181 return renderToken(tree, stream, container_decl.rbrace_token, indent, start_col, space); // }1195 return renderToken(tree, stream, container_decl.rbrace_token, indent, start_col, space); // }
1182 }1196 }
...@@ -1193,15 +1207,16 @@ fn renderExpression(...@@ -1193,15 +1207,16 @@ fn renderExpression(
1193 // Check if the first declaration and the { are on the same line1207 // Check if the first declaration and the { are on the same line
1194 const src_has_newline = !tree.tokensOnSameLine(1208 const src_has_newline = !tree.tokensOnSameLine(
1195 container_decl.lbrace_token,1209 container_decl.lbrace_token,
1196 container_decl.fields_and_decls.at(0).*.firstToken(),1210 container_decl.fields_and_decls.first.?.data.firstToken(),
1197 );1211 );
11981212
1199 // We can only print all the elements in-line if all the1213 // We can only print all the elements in-line if all the
1200 // declarations inside are fields1214 // declarations inside are fields
1201 const src_has_only_fields = blk: {1215 const src_has_only_fields = blk: {
1202 var it = container_decl.fields_and_decls.iterator(0);1216 var it = container_decl.fields_and_decls.first;
1203 while (it.next()) |decl| {1217 while (it) |decl_node| : (it = decl_node.next) {
1204 if (decl.*.id != .ContainerField) break :blk false;1218 const decl = decl_node.data;
1219 if (decl.id != .ContainerField) break :blk false;
1205 }1220 }
1206 break :blk true;1221 break :blk true;
1207 };1222 };
...@@ -1211,13 +1226,14 @@ fn renderExpression(...@@ -1211,13 +1226,14 @@ fn renderExpression(
1211 const new_indent = indent + indent_delta;1226 const new_indent = indent + indent_delta;
1212 try renderToken(tree, stream, container_decl.lbrace_token, new_indent, start_col, .Newline); // {1227 try renderToken(tree, stream, container_decl.lbrace_token, new_indent, start_col, .Newline); // {
12131228
1214 var it = container_decl.fields_and_decls.iterator(0);1229 var it = container_decl.fields_and_decls.first;
1215 while (it.next()) |decl| {1230 while (it) |decl_node| : (it = decl_node.next) {
1231 const decl = decl_node.data;
1216 try stream.writeByteNTimes(' ', new_indent);1232 try stream.writeByteNTimes(' ', new_indent);
1217 try renderContainerDecl(allocator, stream, tree, new_indent, start_col, decl.*, .Newline);1233 try renderContainerDecl(allocator, stream, tree, new_indent, start_col, decl, .Newline);
12181234
1219 if (it.peek()) |next_decl| {1235 if (decl_node.next) |next_decl| {
1220 try renderExtraNewline(tree, stream, start_col, next_decl.*);1236 try renderExtraNewline(tree, stream, start_col, next_decl.data);
1221 }1237 }
1222 }1238 }
12231239
...@@ -1230,10 +1246,11 @@ fn renderExpression(...@@ -1230,10 +1246,11 @@ fn renderExpression(
1230 const new_indent = indent + indent_delta;1246 const new_indent = indent + indent_delta;
1231 try stream.writeByteNTimes(' ', new_indent);1247 try stream.writeByteNTimes(' ', new_indent);
12321248
1233 var it = container_decl.fields_and_decls.iterator(0);1249 var it = container_decl.fields_and_decls.first;
1234 while (it.next()) |decl| {1250 while (it) |decl_node| : (it = decl_node.next) {
1235 const space_after_decl: Space = if (it.peek() == null) .Newline else .Space;1251 const decl = decl_node.data;
1236 try renderContainerDecl(allocator, stream, tree, new_indent, start_col, decl.*, space_after_decl);1252 const space_after_decl: Space = if (decl_node.next == null) .Newline else .Space;
1253 try renderContainerDecl(allocator, stream, tree, new_indent, start_col, decl, space_after_decl);
1237 }1254 }
12381255
1239 try stream.writeByteNTimes(' ', indent);1256 try stream.writeByteNTimes(' ', indent);
...@@ -1241,9 +1258,10 @@ fn renderExpression(...@@ -1241,9 +1258,10 @@ fn renderExpression(
1241 // All the declarations on the same line1258 // All the declarations on the same line
1242 try renderToken(tree, stream, container_decl.lbrace_token, indent, start_col, .Space); // {1259 try renderToken(tree, stream, container_decl.lbrace_token, indent, start_col, .Space); // {
12431260
1244 var it = container_decl.fields_and_decls.iterator(0);1261 var it = container_decl.fields_and_decls.first;
1245 while (it.next()) |decl| {1262 while (it) |decl_node| : (it = decl_node.next) {
1246 try renderContainerDecl(allocator, stream, tree, indent, start_col, decl.*, .Space);1263 const decl = decl_node.data;
1264 try renderContainerDecl(allocator, stream, tree, indent, start_col, decl, .Space);
1247 }1265 }
1248 }1266 }
12491267
...@@ -1255,14 +1273,14 @@ fn renderExpression(...@@ -1255,14 +1273,14 @@ fn renderExpression(
12551273
1256 const lbrace = tree.nextToken(err_set_decl.error_token);1274 const lbrace = tree.nextToken(err_set_decl.error_token);
12571275
1258 if (err_set_decl.decls.len == 0) {1276 if (err_set_decl.decls.first == null) {
1259 try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None);1277 try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None);
1260 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);1278 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
1261 return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space);1279 return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space);
1262 }1280 }
12631281
1264 if (err_set_decl.decls.len == 1) blk: {1282 if (err_set_decl.decls.first.?.next == null) blk: {
1265 const node = err_set_decl.decls.at(0).*;1283 const node = err_set_decl.decls.first.?.data;
12661284
1267 // if there are any doc comments or same line comments1285 // if there are any doc comments or same line comments
1268 // don't try to put it all on one line1286 // don't try to put it all on one line
...@@ -1289,17 +1307,18 @@ fn renderExpression(...@@ -1289,17 +1307,18 @@ fn renderExpression(
1289 try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // {1307 try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // {
1290 const new_indent = indent + indent_delta;1308 const new_indent = indent + indent_delta;
12911309
1292 var it = err_set_decl.decls.iterator(0);1310 var it = err_set_decl.decls.first;
1293 while (it.next()) |node| {1311 while (it) |node_node| : (it = node_node.next) {
1312 const node = node_node.data;
1294 try stream.writeByteNTimes(' ', new_indent);1313 try stream.writeByteNTimes(' ', new_indent);
12951314
1296 if (it.peek()) |next_node| {1315 if (node_node.next) |next_node| {
1297 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.None);1316 try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.None);
1298 try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, start_col, Space.Newline); // ,1317 try renderToken(tree, stream, tree.nextToken(node.lastToken()), new_indent, start_col, Space.Newline); // ,
12991318
1300 try renderExtraNewline(tree, stream, start_col, next_node.*);1319 try renderExtraNewline(tree, stream, start_col, next_node.data);
1301 } else {1320 } else {
1302 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);1321 try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.Comma);
1303 }1322 }
1304 }1323 }
13051324
...@@ -1308,17 +1327,18 @@ fn renderExpression(...@@ -1308,17 +1327,18 @@ fn renderExpression(
1308 } else {1327 } else {
1309 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); // {1328 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); // {
13101329
1311 var it = err_set_decl.decls.iterator(0);1330 var it = err_set_decl.decls.first;
1312 while (it.next()) |node| {1331 while (it) |node_node| : (it = node_node.next) {
1313 if (it.peek()) |next_node| {1332 const node = node_node.data;
1314 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);1333 if (node_node.next) |next_node| {
1334 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None);
13151335
1316 const comma_token = tree.nextToken(node.*.lastToken());1336 const comma_token = tree.nextToken(node.lastToken());
1317 assert(tree.tokens[comma_token].id == .Comma);1337 assert(tree.tokens[comma_token].id == .Comma);
1318 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,1338 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
1319 try renderExtraNewline(tree, stream, start_col, next_node.*);1339 try renderExtraNewline(tree, stream, start_col, next_node.data);
1320 } else {1340 } else {
1321 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Space);1341 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.Space);
1322 }1342 }
1323 }1343 }
13241344
...@@ -1344,9 +1364,9 @@ fn renderExpression(...@@ -1344,9 +1364,9 @@ fn renderExpression(
1344 skip_first_indent = false;1364 skip_first_indent = false;
1345 }1365 }
13461366
1347 var i: usize = 0;1367 var it = multiline_str_literal.lines.first;
1348 while (i < multiline_str_literal.lines.len) : (i += 1) {1368 while (it) |t_node| : (it = t_node.next) {
1349 const t = multiline_str_literal.lines.at(i).*;1369 const t = t_node.data;
1350 if (!skip_first_indent) {1370 if (!skip_first_indent) {
1351 try stream.writeByteNTimes(' ', indent + indent_delta);1371 try stream.writeByteNTimes(' ', indent + indent_delta);
1352 }1372 }
...@@ -1366,8 +1386,12 @@ fn renderExpression(...@@ -1366,8 +1386,12 @@ fn renderExpression(
1366 try renderToken(tree, stream, builtin_call.builtin_token, indent, start_col, Space.None); // @name1386 try renderToken(tree, stream, builtin_call.builtin_token, indent, start_col, Space.None); // @name
13671387
1368 const src_params_trailing_comma = blk: {1388 const src_params_trailing_comma = blk: {
1369 if (builtin_call.params.len < 2) break :blk false;1389 if (builtin_call.params.first == null or
1370 const last_node = builtin_call.params.at(builtin_call.params.len - 1).*;1390 builtin_call.params.first.?.next == null)
1391 {
1392 break :blk false;
1393 }
1394 const last_node = findLast(builtin_call.params.first.?).data;
1371 const maybe_comma = tree.nextToken(last_node.lastToken());1395 const maybe_comma = tree.nextToken(last_node.lastToken());
1372 break :blk tree.tokens[maybe_comma].id == .Comma;1396 break :blk tree.tokens[maybe_comma].id == .Comma;
1373 };1397 };
...@@ -1378,12 +1402,13 @@ fn renderExpression(...@@ -1378,12 +1402,13 @@ fn renderExpression(
1378 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (1402 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
13791403
1380 // render all on one line, no trailing comma1404 // render all on one line, no trailing comma
1381 var it = builtin_call.params.iterator(0);1405 var it = builtin_call.params.first;
1382 while (it.next()) |param_node| {1406 while (it) |param_node_node| : (it = param_node_node.next) {
1383 try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.None);1407 const param_node = param_node_node.data;
1408 try renderExpression(allocator, stream, tree, indent, start_col, param_node, Space.None);
13841409
1385 if (it.peek() != null) {1410 if (param_node_node.next != null) {
1386 const comma_token = tree.nextToken(param_node.*.lastToken());1411 const comma_token = tree.nextToken(param_node.lastToken());
1387 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,1412 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
1388 }1413 }
1389 }1414 }
...@@ -1392,10 +1417,11 @@ fn renderExpression(...@@ -1392,10 +1417,11 @@ fn renderExpression(
1392 const new_indent = indent + indent_delta;1417 const new_indent = indent + indent_delta;
1393 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline); // (1418 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline); // (
13941419
1395 var it = builtin_call.params.iterator(0);1420 var it = builtin_call.params.first;
1396 while (it.next()) |param_node| {1421 while (it) |param_node_node| : (it = param_node_node.next) {
1422 const param_node = param_node_node.data;
1397 try stream.writeByteNTimes(' ', new_indent);1423 try stream.writeByteNTimes(' ', new_indent);
1398 try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.Comma);1424 try renderExpression(allocator, stream, tree, indent, start_col, param_node, Space.Comma);
1399 }1425 }
1400 try stream.writeByteNTimes(' ', indent);1426 try stream.writeByteNTimes(' ', indent);
1401 }1427 }
...@@ -1457,12 +1483,13 @@ fn renderExpression(...@@ -1457,12 +1483,13 @@ fn renderExpression(
1457 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (1483 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
14581484
1459 // render all on one line, no trailing comma1485 // render all on one line, no trailing comma
1460 var it = fn_proto.params.iterator(0);1486 var it = fn_proto.params.first;
1461 while (it.next()) |param_decl_node| {1487 while (it) |param_decl_node_node| : (it = param_decl_node_node.next) {
1462 try renderParamDecl(allocator, stream, tree, indent, start_col, param_decl_node.*, Space.None);1488 const param_decl_node = param_decl_node_node.data;
1489 try renderParamDecl(allocator, stream, tree, indent, start_col, param_decl_node, Space.None);
14631490
1464 if (it.peek() != null) {1491 if (param_decl_node_node.next != null) {
1465 const comma = tree.nextToken(param_decl_node.*.lastToken());1492 const comma = tree.nextToken(param_decl_node.lastToken());
1466 try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,1493 try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,
1467 }1494 }
1468 }1495 }
...@@ -1471,10 +1498,11 @@ fn renderExpression(...@@ -1471,10 +1498,11 @@ fn renderExpression(
1471 const new_indent = indent + indent_delta;1498 const new_indent = indent + indent_delta;
1472 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline); // (1499 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline); // (
14731500
1474 var it = fn_proto.params.iterator(0);1501 var it = fn_proto.params.first;
1475 while (it.next()) |param_decl_node| {1502 while (it) |param_decl_node_node| : (it = param_decl_node_node.next) {
1503 const param_decl_node = param_decl_node_node.data;
1476 try stream.writeByteNTimes(' ', new_indent);1504 try stream.writeByteNTimes(' ', new_indent);
1477 try renderParamDecl(allocator, stream, tree, new_indent, start_col, param_decl_node.*, Space.Comma);1505 try renderParamDecl(allocator, stream, tree, new_indent, start_col, param_decl_node, Space.Comma);
1478 }1506 }
1479 try stream.writeByteNTimes(' ', indent);1507 try stream.writeByteNTimes(' ', indent);
1480 }1508 }
...@@ -1553,7 +1581,7 @@ fn renderExpression(...@@ -1553,7 +1581,7 @@ fn renderExpression(
1553 const rparen = tree.nextToken(switch_node.expr.lastToken());1581 const rparen = tree.nextToken(switch_node.expr.lastToken());
1554 const lbrace = tree.nextToken(rparen);1582 const lbrace = tree.nextToken(rparen);
15551583
1556 if (switch_node.cases.len == 0) {1584 if (switch_node.cases.first == null) {
1557 try renderExpression(allocator, stream, tree, indent, start_col, switch_node.expr, Space.None);1585 try renderExpression(allocator, stream, tree, indent, start_col, switch_node.expr, Space.None);
1558 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )1586 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
1559 try renderToken(tree, stream, lbrace, indent, start_col, Space.None); // {1587 try renderToken(tree, stream, lbrace, indent, start_col, Space.None); // {
...@@ -1567,13 +1595,14 @@ fn renderExpression(...@@ -1567,13 +1595,14 @@ fn renderExpression(
1567 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )1595 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
1568 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); // {1596 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); // {
15691597
1570 var it = switch_node.cases.iterator(0);1598 var it = switch_node.cases.first;
1571 while (it.next()) |node| {1599 while (it) |node_node| : (it = node_node.next) {
1600 const node = node_node.data;
1572 try stream.writeByteNTimes(' ', new_indent);1601 try stream.writeByteNTimes(' ', new_indent);
1573 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);1602 try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.Comma);
15741603
1575 if (it.peek()) |next_node| {1604 if (node_node.next) |next_node| {
1576 try renderExtraNewline(tree, stream, start_col, next_node.*);1605 try renderExtraNewline(tree, stream, start_col, next_node.data);
1577 }1606 }
1578 }1607 }
15791608
...@@ -1584,38 +1613,40 @@ fn renderExpression(...@@ -1584,38 +1613,40 @@ fn renderExpression(
1584 .SwitchCase => {1613 .SwitchCase => {
1585 const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base);1614 const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base);
15861615
1587 assert(switch_case.items.len != 0);1616 assert(switch_case.items.first != null);
1588 const src_has_trailing_comma = blk: {1617 const src_has_trailing_comma = blk: {
1589 const last_node = switch_case.items.at(switch_case.items.len - 1).*;1618 const last_node = findLast(switch_case.items.first.?).data;
1590 const maybe_comma = tree.nextToken(last_node.lastToken());1619 const maybe_comma = tree.nextToken(last_node.lastToken());
1591 break :blk tree.tokens[maybe_comma].id == .Comma;1620 break :blk tree.tokens[maybe_comma].id == .Comma;
1592 };1621 };
15931622
1594 if (switch_case.items.len == 1 or !src_has_trailing_comma) {1623 if (switch_case.items.first.?.next == null or !src_has_trailing_comma) {
1595 var it = switch_case.items.iterator(0);1624 var it = switch_case.items.first;
1596 while (it.next()) |node| {1625 while (it) |node_node| : (it = node_node.next) {
1597 if (it.peek()) |next_node| {1626 const node = node_node.data;
1598 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);1627 if (node_node.next) |next_node| {
1628 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None);
15991629
1600 const comma_token = tree.nextToken(node.*.lastToken());1630 const comma_token = tree.nextToken(node.lastToken());
1601 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,1631 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
1602 try renderExtraNewline(tree, stream, start_col, next_node.*);1632 try renderExtraNewline(tree, stream, start_col, next_node.data);
1603 } else {1633 } else {
1604 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Space);1634 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.Space);
1605 }1635 }
1606 }1636 }
1607 } else {1637 } else {
1608 var it = switch_case.items.iterator(0);1638 var it = switch_case.items.first;
1609 while (it.next()) |node| {1639 while (it) |node_node| : (it = node_node.next) {
1610 if (it.peek()) |next_node| {1640 const node = node_node.data;
1611 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);1641 if (node_node.next) |next_node| {
1642 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None);
16121643
1613 const comma_token = tree.nextToken(node.*.lastToken());1644 const comma_token = tree.nextToken(node.lastToken());
1614 try renderToken(tree, stream, comma_token, indent, start_col, Space.Newline); // ,1645 try renderToken(tree, stream, comma_token, indent, start_col, Space.Newline); // ,
1615 try renderExtraNewline(tree, stream, start_col, next_node.*);1646 try renderExtraNewline(tree, stream, start_col, next_node.data);
1616 try stream.writeByteNTimes(' ', indent);1647 try stream.writeByteNTimes(' ', indent);
1617 } else {1648 } else {
1618 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Comma);1649 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.Comma);
1619 try stream.writeByteNTimes(' ', indent);1650 try stream.writeByteNTimes(' ', indent);
1620 }1651 }
1621 }1652 }
...@@ -1887,7 +1918,7 @@ fn renderExpression(...@@ -1887,7 +1918,7 @@ fn renderExpression(
1887 try renderToken(tree, stream, tree.nextToken(asm_node.asm_token), indent, start_col, Space.None); // (1918 try renderToken(tree, stream, tree.nextToken(asm_node.asm_token), indent, start_col, Space.None); // (
1888 }1919 }
18891920
1890 if (asm_node.outputs.len == 0 and asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {1921 if (asm_node.outputs.first == null and asm_node.inputs.first == null and asm_node.clobbers.first == null) {
1891 try renderExpression(allocator, stream, tree, indent, start_col, asm_node.template, Space.None);1922 try renderExpression(allocator, stream, tree, indent, start_col, asm_node.template, Space.None);
1892 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);1923 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
1893 }1924 }
...@@ -1907,7 +1938,7 @@ fn renderExpression(...@@ -1907,7 +1938,7 @@ fn renderExpression(
1907 const colon1 = tree.nextToken(asm_node.template.lastToken());1938 const colon1 = tree.nextToken(asm_node.template.lastToken());
1908 const indent_extra = indent_once + 2;1939 const indent_extra = indent_once + 2;
19091940
1910 const colon2 = if (asm_node.outputs.len == 0) blk: {1941 const colon2 = if (asm_node.outputs.first == null) blk: {
1911 try renderToken(tree, stream, colon1, indent, start_col, Space.Newline); // :1942 try renderToken(tree, stream, colon1, indent, start_col, Space.Newline); // :
1912 try stream.writeByteNTimes(' ', indent_once);1943 try stream.writeByteNTimes(' ', indent_once);
19131944
...@@ -1915,21 +1946,23 @@ fn renderExpression(...@@ -1915,21 +1946,23 @@ fn renderExpression(
1915 } else blk: {1946 } else blk: {
1916 try renderToken(tree, stream, colon1, indent, start_col, Space.Space); // :1947 try renderToken(tree, stream, colon1, indent, start_col, Space.Space); // :
19171948
1918 var it = asm_node.outputs.iterator(0);1949 var it = asm_node.outputs.first;
1919 while (true) {1950 while (true) {
1920 const asm_output = it.next().?;1951 const asm_output_node = it.?;
1921 const node = &(asm_output.*).base;1952 it = asm_output_node.next;
1953 const asm_output = asm_output_node.data;
1954 const node = &asm_output.base;
19221955
1923 if (it.peek()) |next_asm_output| {1956 if (asm_output_node.next) |next_asm_output| {
1924 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);1957 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);
1925 const next_node = &(next_asm_output.*).base;1958 const next_node = &next_asm_output.data.base;
19261959
1927 const comma = tree.prevToken(next_asm_output.*.firstToken());1960 const comma = tree.prevToken(next_asm_output.data.firstToken());
1928 try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,1961 try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,
1929 try renderExtraNewline(tree, stream, start_col, next_node);1962 try renderExtraNewline(tree, stream, start_col, next_node);
19301963
1931 try stream.writeByteNTimes(' ', indent_extra);1964 try stream.writeByteNTimes(' ', indent_extra);
1932 } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {1965 } else if (asm_node.inputs.first == null and asm_node.clobbers.first == null) {
1933 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);1966 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
1934 try stream.writeByteNTimes(' ', indent);1967 try stream.writeByteNTimes(' ', indent);
1935 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);1968 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
...@@ -1945,7 +1978,7 @@ fn renderExpression(...@@ -1945,7 +1978,7 @@ fn renderExpression(
1945 }1978 }
1946 };1979 };
19471980
1948 const colon3 = if (asm_node.inputs.len == 0) blk: {1981 const colon3 = if (asm_node.inputs.first == null) blk: {
1949 try renderToken(tree, stream, colon2, indent, start_col, Space.Newline); // :1982 try renderToken(tree, stream, colon2, indent, start_col, Space.Newline); // :
1950 try stream.writeByteNTimes(' ', indent_once);1983 try stream.writeByteNTimes(' ', indent_once);
19511984
...@@ -1953,21 +1986,22 @@ fn renderExpression(...@@ -1953,21 +1986,22 @@ fn renderExpression(
1953 } else blk: {1986 } else blk: {
1954 try renderToken(tree, stream, colon2, indent, start_col, Space.Space); // :1987 try renderToken(tree, stream, colon2, indent, start_col, Space.Space); // :
19551988
1956 var it = asm_node.inputs.iterator(0);1989 var it = asm_node.inputs.first;
1957 while (true) {1990 while (true) {
1958 const asm_input = it.next().?;1991 const asm_input_node = it.?;
1959 const node = &(asm_input.*).base;1992 it = asm_input_node.next;
1993 const node = &asm_input_node.data.base;
19601994
1961 if (it.peek()) |next_asm_input| {1995 if (it) |next_asm_input| {
1962 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);1996 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);
1963 const next_node = &(next_asm_input.*).base;1997 const next_node = &next_asm_input.data.base;
19641998
1965 const comma = tree.prevToken(next_asm_input.*.firstToken());1999 const comma = tree.prevToken(next_asm_input.data.firstToken());
1966 try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,2000 try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,
1967 try renderExtraNewline(tree, stream, start_col, next_node);2001 try renderExtraNewline(tree, stream, start_col, next_node);
19682002
1969 try stream.writeByteNTimes(' ', indent_extra);2003 try stream.writeByteNTimes(' ', indent_extra);
1970 } else if (asm_node.clobbers.len == 0) {2004 } else if (asm_node.clobbers.first == null) {
1971 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);2005 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
1972 try stream.writeByteNTimes(' ', indent);2006 try stream.writeByteNTimes(' ', indent);
1973 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space); // )2007 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space); // )
...@@ -1985,11 +2019,13 @@ fn renderExpression(...@@ -1985,11 +2019,13 @@ fn renderExpression(
19852019
1986 try renderToken(tree, stream, colon3, indent, start_col, Space.Space); // :2020 try renderToken(tree, stream, colon3, indent, start_col, Space.Space); // :
19872021
1988 var it = asm_node.clobbers.iterator(0);2022 var it = asm_node.clobbers.first;
1989 while (true) {2023 while (true) {
1990 const clobber_node = it.next().?.*;2024 const clobber_node_node = it.?;
2025 it = clobber_node_node.next;
2026 const clobber_node = clobber_node_node.data;
19912027
1992 if (it.peek() == null) {2028 if (it == null) {
1993 try renderExpression(allocator, stream, tree, indent_extra, start_col, clobber_node, Space.Newline);2029 try renderExpression(allocator, stream, tree, indent_extra, start_col, clobber_node, Space.Newline);
1994 try stream.writeByteNTimes(' ', indent);2030 try stream.writeByteNTimes(' ', indent);
1995 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);2031 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
...@@ -2401,14 +2437,15 @@ fn renderDocComments(...@@ -2401,14 +2437,15 @@ fn renderDocComments(
2401 start_col: *usize,2437 start_col: *usize,
2402) (@TypeOf(stream).Error || Error)!void {2438) (@TypeOf(stream).Error || Error)!void {
2403 const comment = node.doc_comments orelse return;2439 const comment = node.doc_comments orelse return;
2404 var it = comment.lines.iterator(0);2440 var it = comment.lines.first;
2405 const first_token = node.firstToken();2441 const first_token = node.firstToken();
2406 while (it.next()) |line_token_index| {2442 while (it) |line_token_index_node| : (it = line_token_index_node.next) {
2407 if (line_token_index.* < first_token) {2443 const line_token_index = line_token_index_node.data;
2408 try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.Newline);2444 if (line_token_index < first_token) {
2445 try renderToken(tree, stream, line_token_index, indent, start_col, Space.Newline);
2409 try stream.writeByteNTimes(' ', indent);2446 try stream.writeByteNTimes(' ', indent);
2410 } else {2447 } else {
2411 try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.NoComment);2448 try renderToken(tree, stream, line_token_index, indent, start_col, Space.NoComment);
2412 try stream.writeAll("\n");2449 try stream.writeAll("\n");
2413 try stream.writeByteNTimes(' ', indent);2450 try stream.writeByteNTimes(' ', indent);
2414 }2451 }
...@@ -2473,3 +2510,19 @@ fn copyFixingWhitespace(stream: var, slice: []const u8) @TypeOf(stream).Error!vo...@@ -2473,3 +2510,19 @@ fn copyFixingWhitespace(stream: var, slice: []const u8) @TypeOf(stream).Error!vo
2473 else => try stream.writeByte(byte),2510 else => try stream.writeByte(byte),
2474 };2511 };
2475}2512}
2513
2514fn countLen(node: ?*std.SinglyLinkedList(*ast.Node).Node) usize {
2515 var count: usize = 0;
2516 var it = node;
2517 while (it) |n| : (it = n.next) {
2518 count += 1;
2519 }
2520 return count;
2521}
2522
2523fn findLast(node: *std.SinglyLinkedList(*ast.Node).Node) *std.SinglyLinkedList(*ast.Node).Node {
2524 var it = node;
2525 while (true) {
2526 it = it.next orelse return it;
2527 }
2528}