authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-09 20:08:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-09 20:08:40-07:00
log39acc4c02004f4e106b7c280f3f6bb070df88178
tree40aa89c158e10f85c15cbd42b3f8b468cc76b485
parent1c79eea125c7e21b00a7abeffdc3b64548c54257

zig fmt: for loops


4 files changed, 200 insertions(+), 212 deletions(-)

lib/std/zig/ast.zig+27-4
...@@ -512,6 +512,7 @@ pub const Tree = struct {...@@ -512,6 +512,7 @@ pub const Tree = struct {
512 .ErrorUnion,512 .ErrorUnion,
513 .IfSimple,513 .IfSimple,
514 .WhileSimple,514 .WhileSimple,
515 .ForSimple,
515 .FnDecl,516 .FnDecl,
516 .PtrTypeAligned,517 .PtrTypeAligned,
517 .PtrTypeSentinel,518 .PtrTypeSentinel,
...@@ -531,6 +532,7 @@ pub const Tree = struct {...@@ -531,6 +532,7 @@ pub const Tree = struct {
531 .AsmInput,532 .AsmInput,
532 .FnProtoSimple,533 .FnProtoSimple,
533 .FnProtoMulti,534 .FnProtoMulti,
535 .ErrorValue,
534 => return datas[n].rhs + end_offset,536 => return datas[n].rhs + end_offset,
535537
536 .AnyType,538 .AnyType,
...@@ -854,7 +856,7 @@ pub const Tree = struct {...@@ -854,7 +856,7 @@ pub const Tree = struct {
854 assert(extra.else_expr != 0);856 assert(extra.else_expr != 0);
855 n = extra.else_expr;857 n = extra.else_expr;
856 },858 },
857 .If => {859 .If, .For => {
858 const extra = tree.extraData(datas[n].rhs, Node.If);860 const extra = tree.extraData(datas[n].rhs, Node.If);
859 assert(extra.else_expr != 0);861 assert(extra.else_expr != 0);
860 n = extra.else_expr;862 n = extra.else_expr;
...@@ -876,9 +878,6 @@ pub const Tree = struct {...@@ -876,9 +878,6 @@ pub const Tree = struct {
876 .SwitchRange => unreachable, // TODO878 .SwitchRange => unreachable, // TODO
877 .ArrayType => unreachable, // TODO879 .ArrayType => unreachable, // TODO
878 .ArrayTypeSentinel => unreachable, // TODO880 .ArrayTypeSentinel => unreachable, // TODO
879 .ForSimple => unreachable, // TODO
880 .For => unreachable, // TODO
881 .ErrorValue => unreachable, // TODO
882 };881 };
883 }882 }
884883
...@@ -1457,6 +1456,29 @@ pub const Tree = struct {...@@ -1457,6 +1456,29 @@ pub const Tree = struct {
1457 });1456 });
1458 }1457 }
14591458
1459 pub fn forSimple(tree: Tree, node: Node.Index) full.While {
1460 const data = tree.nodes.items(.data)[node];
1461 return tree.fullWhile(.{
1462 .while_token = tree.nodes.items(.main_token)[node],
1463 .cond_expr = data.lhs,
1464 .cont_expr = 0,
1465 .then_expr = data.rhs,
1466 .else_expr = 0,
1467 });
1468 }
1469
1470 pub fn forFull(tree: Tree, node: Node.Index) full.While {
1471 const data = tree.nodes.items(.data)[node];
1472 const extra = tree.extraData(data.rhs, Node.If);
1473 return tree.fullWhile(.{
1474 .while_token = tree.nodes.items(.main_token)[node],
1475 .cond_expr = data.lhs,
1476 .cont_expr = 0,
1477 .then_expr = extra.then_expr,
1478 .else_expr = extra.else_expr,
1479 });
1480 }
1481
1460 fn fullVarDecl(tree: Tree, info: full.VarDecl.Ast) full.VarDecl {1482 fn fullVarDecl(tree: Tree, info: full.VarDecl.Ast) full.VarDecl {
1461 const token_tags = tree.tokens.items(.tag);1483 const token_tags = tree.tokens.items(.tag);
1462 var result: full.VarDecl = .{1484 var result: full.VarDecl = .{
...@@ -2356,6 +2378,7 @@ pub const Node = struct {...@@ -2356,6 +2378,7 @@ pub const Node = struct {
2356 /// main_token is the `=>`2378 /// main_token is the `=>`
2357 SwitchCaseOne,2379 SwitchCaseOne,
2358 /// `a, b, c => rhs`. `SubRange[lhs]`.2380 /// `a, b, c => rhs`. `SubRange[lhs]`.
2381 /// main_token is the `=>`
2359 SwitchCase,2382 SwitchCase,
2360 /// `lhs...rhs`.2383 /// `lhs...rhs`.
2361 SwitchRange,2384 SwitchRange,
lib/std/zig/parse.zig+14-19
...@@ -835,12 +835,11 @@ const Parser = struct {...@@ -835,12 +835,11 @@ const Parser = struct {
835 });835 });
836 }836 }
837837
838 const token = p.nextToken();838 switch (p.token_tags[p.tok_i]) {
839 switch (p.token_tags[token]) {
840 .Keyword_nosuspend => {839 .Keyword_nosuspend => {
841 return p.addNode(.{840 return p.addNode(.{
842 .tag = .Nosuspend,841 .tag = .Nosuspend,
843 .main_token = token,842 .main_token = p.nextToken(),
844 .data = .{843 .data = .{
845 .lhs = try p.expectBlockExprStatement(),844 .lhs = try p.expectBlockExprStatement(),
846 .rhs = undefined,845 .rhs = undefined,
...@@ -848,6 +847,7 @@ const Parser = struct {...@@ -848,6 +847,7 @@ const Parser = struct {
848 });847 });
849 },848 },
850 .Keyword_suspend => {849 .Keyword_suspend => {
850 const token = p.nextToken();
851 const block_expr: Node.Index = if (p.eatToken(.Semicolon) != null)851 const block_expr: Node.Index = if (p.eatToken(.Semicolon) != null)
852 0852 0
853 else853 else
...@@ -863,7 +863,7 @@ const Parser = struct {...@@ -863,7 +863,7 @@ const Parser = struct {
863 },863 },
864 .Keyword_defer => return p.addNode(.{864 .Keyword_defer => return p.addNode(.{
865 .tag = .Defer,865 .tag = .Defer,
866 .main_token = token,866 .main_token = p.nextToken(),
867 .data = .{867 .data = .{
868 .lhs = undefined,868 .lhs = undefined,
869 .rhs = try p.expectBlockExprStatement(),869 .rhs = try p.expectBlockExprStatement(),
...@@ -871,24 +871,20 @@ const Parser = struct {...@@ -871,24 +871,20 @@ const Parser = struct {
871 }),871 }),
872 .Keyword_errdefer => return p.addNode(.{872 .Keyword_errdefer => return p.addNode(.{
873 .tag = .ErrDefer,873 .tag = .ErrDefer,
874 .main_token = token,874 .main_token = p.nextToken(),
875 .data = .{875 .data = .{
876 .lhs = try p.parsePayload(),876 .lhs = try p.parsePayload(),
877 .rhs = try p.expectBlockExprStatement(),877 .rhs = try p.expectBlockExprStatement(),
878 },878 },
879 }),879 }),
880 else => p.tok_i -= 1,880 .Keyword_switch => return p.expectSwitchExpr(),
881 .Keyword_if => return p.expectIfStatement(),
882 else => {},
881 }883 }
882884
883 const if_statement = try p.parseIfStatement();
884 if (if_statement != 0) return if_statement;
885
886 const labeled_statement = try p.parseLabeledStatement();885 const labeled_statement = try p.parseLabeledStatement();
887 if (labeled_statement != 0) return labeled_statement;886 if (labeled_statement != 0) return labeled_statement;
888887
889 const switch_expr = try p.parseSwitchExpr();
890 if (switch_expr != 0) return switch_expr;
891
892 const assign_expr = try p.parseAssignExpr();888 const assign_expr = try p.parseAssignExpr();
893 if (assign_expr != 0) {889 if (assign_expr != 0) {
894 _ = try p.expectTokenRecoverable(.Semicolon);890 _ = try p.expectTokenRecoverable(.Semicolon);
...@@ -925,8 +921,8 @@ const Parser = struct {...@@ -925,8 +921,8 @@ const Parser = struct {
925 /// IfStatement921 /// IfStatement
926 /// <- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?922 /// <- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
927 /// / IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )923 /// / IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
928 fn parseIfStatement(p: *Parser) !Node.Index {924 fn expectIfStatement(p: *Parser) !Node.Index {
929 const if_token = p.eatToken(.Keyword_if) orelse return null_node;925 const if_token = p.assertToken(.Keyword_if);
930 _ = try p.expectToken(.LParen);926 _ = try p.expectToken(.LParen);
931 const condition = try p.expectExpr();927 const condition = try p.expectExpr();
932 _ = try p.expectToken(.RParen);928 _ = try p.expectToken(.RParen);
...@@ -2441,7 +2437,7 @@ const Parser = struct {...@@ -2441,7 +2437,7 @@ const Parser = struct {
2441 .Builtin => return p.parseBuiltinCall(),2437 .Builtin => return p.parseBuiltinCall(),
2442 .Keyword_fn => return p.parseFnProto(),2438 .Keyword_fn => return p.parseFnProto(),
2443 .Keyword_if => return p.parseIf(parseTypeExpr),2439 .Keyword_if => return p.parseIf(parseTypeExpr),
2444 .Keyword_switch => return p.parseSwitchExpr(),2440 .Keyword_switch => return p.expectSwitchExpr(),
24452441
2446 .Keyword_extern,2442 .Keyword_extern,
2447 .Keyword_packed,2443 .Keyword_packed,
...@@ -2880,8 +2876,8 @@ const Parser = struct {...@@ -2880,8 +2876,8 @@ const Parser = struct {
2880 }2876 }
28812877
2882 /// SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE2878 /// SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
2883 fn parseSwitchExpr(p: *Parser) !Node.Index {2879 fn expectSwitchExpr(p: *Parser) !Node.Index {
2884 const switch_token = p.eatToken(.Keyword_switch) orelse return null_node;2880 const switch_token = p.assertToken(.Keyword_switch);
2885 _ = try p.expectToken(.LParen);2881 _ = try p.expectToken(.LParen);
2886 const expr_node = try p.expectExpr();2882 const expr_node = try p.expectExpr();
2887 _ = try p.expectToken(.RParen);2883 _ = try p.expectToken(.RParen);
...@@ -3191,8 +3187,7 @@ const Parser = struct {...@@ -3191,8 +3187,7 @@ const Parser = struct {
3191 const first_item = try p.parseSwitchItem();3187 const first_item = try p.parseSwitchItem();
3192 if (first_item == 0) return null_node;3188 if (first_item == 0) return null_node;
31933189
3194 if (p.token_tags[p.tok_i] == .RBrace) {3190 if (p.eatToken(.EqualAngleBracketRight)) |arrow_token| {
3195 const arrow_token = try p.expectToken(.EqualAngleBracketRight);
3196 _ = try p.parsePtrPayload();3191 _ = try p.parsePtrPayload();
3197 return p.addNode(.{3192 return p.addNode(.{
3198 .tag = .SwitchCaseOne,3193 .tag = .SwitchCaseOne,
lib/std/zig/parser_test.zig+75-80
...@@ -2830,86 +2830,81 @@ test "zig fmt: switch" {...@@ -2830,86 +2830,81 @@ test "zig fmt: switch" {
2830// \\2830// \\
2831// );2831// );
2832//}2832//}
2833//2833
2834//test "zig fmt: for" {2834test "zig fmt: for" {
2835// try testCanonical(2835 try testCanonical(
2836// \\test "for" {2836 \\test "for" {
2837// \\ for (a) |v| {2837 \\ for (a) |v| {
2838// \\ continue;2838 \\ continue;
2839// \\ }2839 \\ }
2840// \\2840 \\
2841// \\ for (a) |v| continue;2841 \\ for (a) |v| continue;
2842// \\2842 \\
2843// \\ for (a) |v| continue else return;2843 \\ for (a) |v| continue else return;
2844// \\2844 \\
2845// \\ for (a) |v| {2845 \\ for (a) |v| {
2846// \\ continue;2846 \\ continue;
2847// \\ } else return;2847 \\ } else return;
2848// \\2848 \\
2849// \\ for (a) |v| continue else {2849 \\ for (a) |v| continue else {
2850// \\ return;2850 \\ return;
2851// \\ }2851 \\ }
2852// \\2852 \\
2853// \\ for (a) |v|2853 \\ for (a) |v|
2854// \\ continue2854 \\ continue
2855// \\ else2855 \\ else
2856// \\ return;2856 \\ return;
2857// \\2857 \\
2858// \\ for (a) |v|2858 \\ for (a) |v|
2859// \\ continue;2859 \\ continue;
2860// \\2860 \\
2861// \\ for (a) |*v|2861 \\ for (a) |*v|
2862// \\ continue;2862 \\ continue;
2863// \\2863 \\
2864// \\ for (a) |v, i| {2864 \\ for (a) |v, i| {
2865// \\ continue;2865 \\ continue;
2866// \\ }2866 \\ }
2867// \\2867 \\
2868// \\ for (a) |v, i|2868 \\ for (a) |v, i|
2869// \\ continue;2869 \\ continue;
2870// \\2870 \\
2871// \\ for (a) |b| switch (b) {2871 \\ for (a) |b| switch (b) {
2872// \\ c => {},2872 \\ c => {},
2873// \\ d => {},2873 \\ d => {},
2874// \\ };2874 \\ };
2875// \\2875 \\
2876// \\ for (a) |b|2876 \\ const res = for (a) |v, i| {
2877// \\ switch (b) {2877 \\ break v;
2878// \\ c => {},2878 \\ } else {
2879// \\ d => {},2879 \\ unreachable;
2880// \\ };2880 \\ };
2881// \\2881 \\
2882// \\ const res = for (a) |v, i| {2882 \\ var num: usize = 0;
2883// \\ break v;2883 \\ inline for (a) |v, i| {
2884// \\ } else {2884 \\ num += v;
2885// \\ unreachable;2885 \\ num += i;
2886// \\ };2886 \\ }
2887// \\2887 \\}
2888// \\ var num: usize = 0;2888 \\
2889// \\ inline for (a) |v, i| {2889 );
2890// \\ num += v;2890
2891// \\ num += i;2891 try testTransform(
2892// \\ }2892 \\test "fix for" {
2893// \\}2893 \\ for (a) |x|
2894// \\2894 \\ f(x) else continue;
2895// );2895 \\}
2896//2896 \\
2897// try testTransform(2897 ,
2898// \\test "fix for" {2898 \\test "fix for" {
2899// \\ for (a) |x|2899 \\ for (a) |x|
2900// \\ f(x) else continue;2900 \\ f(x)
2901// \\}2901 \\ else
2902// \\2902 \\ continue;
2903// ,2903 \\}
2904// \\test "fix for" {2904 \\
2905// \\ for (a) |x|2905 );
2906// \\ f(x)2906}
2907// \\ else continue;2907
2908// \\}
2909// \\
2910// );
2911//}
2912//
2913//test "zig fmt: if" {2908//test "zig fmt: if" {
2914// try testCanonical(2909// try testCanonical(
2915// \\test "if" {2910// \\test "if" {
lib/std/zig/render.zig+84-109
...@@ -498,18 +498,17 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -498,18 +498,17 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
498 }498 }
499 },499 },
500500
501 .Continue => unreachable, // TODO501 .Continue => {
502 //.Continue => {502 const main_token = main_tokens[node];
503 // const flow_expr = base.castTag(.Continue).?;503 const label = datas[node].lhs;
504 // if (flow_expr.getLabel()) |label| {504 if (label != 0) {
505 // try renderToken(ais, tree, flow_expr.ltoken, Space.Space); // continue505 try renderToken(ais, tree, main_token, .Space); // continue
506 // const colon = tree.nextToken(flow_expr.ltoken);506 try renderToken(ais, tree, label - 1, .None); // :
507 // try renderToken(ais, tree, colon, Space.None); // :507 return renderToken(ais, tree, label, space); // label
508 // return renderToken(ais, tree, label, space); // label508 } else {
509 // } else {509 return renderToken(ais, tree, main_token, space); // continue
510 // return renderToken(ais, tree, flow_expr.ltoken, space); // continue510 }
511 // }511 },
512 //},
513512
514 .Return => {513 .Return => {
515 if (datas[node].lhs != 0) {514 if (datas[node].lhs != 0) {
...@@ -664,17 +663,16 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -664,17 +663,16 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
664 if (cases.len == 0) {663 if (cases.len == 0) {
665 try renderToken(ais, tree, rparen + 1, .None); // lbrace664 try renderToken(ais, tree, rparen + 1, .None); // lbrace
666 return renderToken(ais, tree, rparen + 2, space); // rbrace665 return renderToken(ais, tree, rparen + 2, space); // rbrace
667 } else {
668 try renderToken(ais, tree, rparen + 1, .Newline); // lbrace
669 ais.pushIndent();
670 try renderExpression(ais, tree, cases[0], .Comma);
671 for (cases[1..]) |case| {
672 try renderExtraNewline(ais, tree, case);
673 try renderExpression(ais, tree, case, .Comma);
674 }
675 ais.popIndent();
676 return renderToken(ais, tree, tree.lastToken(node), space); // rbrace
677 }666 }
667 try renderToken(ais, tree, rparen + 1, .Newline); // lbrace
668 ais.pushIndent();
669 try renderExpression(ais, tree, cases[0], .Comma);
670 for (cases[1..]) |case| {
671 try renderExtraNewline(ais, tree, case);
672 try renderExpression(ais, tree, case, .Comma);
673 }
674 ais.popIndent();
675 return renderToken(ais, tree, tree.lastToken(node), space); // rbrace
678 },676 },
679677
680 .SwitchCaseOne => return renderSwitchCase(ais, tree, tree.switchCaseOne(node), space),678 .SwitchCaseOne => return renderSwitchCase(ais, tree, tree.switchCaseOne(node), space),
...@@ -683,59 +681,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -683,59 +681,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
683 .WhileSimple => return renderWhile(ais, tree, tree.whileSimple(node), space),681 .WhileSimple => return renderWhile(ais, tree, tree.whileSimple(node), space),
684 .WhileCont => return renderWhile(ais, tree, tree.whileCont(node), space),682 .WhileCont => return renderWhile(ais, tree, tree.whileCont(node), space),
685 .While => return renderWhile(ais, tree, tree.whileFull(node), space),683 .While => return renderWhile(ais, tree, tree.whileFull(node), space),
686684 .ForSimple => return renderWhile(ais, tree, tree.forSimple(node), space),
687 .ForSimple => unreachable, // TODO685 .For => return renderWhile(ais, tree, tree.forFull(node), space),
688 .For => unreachable, // TODO
689 //.For => {
690 // const for_node = @fieldParentPtr(ast.Node.For, "base", base);
691
692 // if (for_node.label) |label| {
693 // try renderToken(ais, tree, label, Space.None); // label
694 // try renderToken(ais, tree, tree.nextToken(label), Space.Space); // :
695 // }
696
697 // if (for_node.inline_token) |inline_token| {
698 // try renderToken(ais, tree, inline_token, Space.Space); // inline
699 // }
700
701 // try renderToken(ais, tree, for_node.for_token, Space.Space); // for
702 // try renderToken(ais, tree, tree.nextToken(for_node.for_token), Space.None); // (
703 // try renderExpression(ais, tree, for_node.array_expr, Space.None);
704
705 // const rparen = tree.nextToken(for_node.array_expr.lastToken());
706
707 // const body_is_block = for_node.body.tag.isBlock();
708 // const src_one_line_to_body = !body_is_block and tree.tokensOnSameLine(rparen, for_node.body.firstToken());
709 // const body_on_same_line = body_is_block or src_one_line_to_body;
710
711 // try renderToken(ais, tree, rparen, Space.Space); // )
712
713 // const space_after_payload = if (body_on_same_line) Space.Space else Space.Newline;
714 // try renderExpression(ais, tree, for_node.payload, space_after_payload); // |x|
715
716 // const space_after_body = blk: {
717 // if (for_node.@"else") |@"else"| {
718 // const src_one_line_to_else = tree.tokensOnSameLine(rparen, @"else".firstToken());
719 // if (body_is_block or src_one_line_to_else) {
720 // break :blk Space.Space;
721 // } else {
722 // break :blk Space.Newline;
723 // }
724 // } else {
725 // break :blk space;
726 // }
727 // };
728
729 // {
730 // if (!body_on_same_line) ais.pushIndent();
731 // defer if (!body_on_same_line) ais.popIndent();
732 // try renderExpression(ais, tree, for_node.body, space_after_body); // { body }
733 // }
734
735 // if (for_node.@"else") |@"else"| {
736 // return renderExpression(ais, tree, &@"else".base, space); // else
737 // }
738 //},
739686
740 .IfSimple => return renderIf(ais, tree, tree.ifSimple(node), space),687 .IfSimple => return renderIf(ais, tree, tree.ifSimple(node), space),
741 .If => return renderIf(ais, tree, tree.ifFull(node), space),688 .If => return renderIf(ais, tree, tree.ifFull(node), space),
...@@ -1041,7 +988,7 @@ fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.full.If, space: Space) Error...@@ -1041,7 +988,7 @@ fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.full.If, space: Space) Error
1041 }, space);988 }, space);
1042}989}
1043990
1044/// Note that this function is additionally used to render if expressions, with991/// Note that this function is additionally used to render if and for expressions, with
1045/// respective values set to null.992/// respective values set to null.
1046fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Space) Error!void {993fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Space) Error!void {
1047 const node_tags = tree.nodes.items(.tag);994 const node_tags = tree.nodes.items(.tag);
...@@ -1061,21 +1008,31 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa...@@ -1061,21 +1008,31 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
1061 try renderExpression(ais, tree, while_node.ast.cond_expr, .None); // condition1008 try renderExpression(ais, tree, while_node.ast.cond_expr, .None); // condition
10621009
1063 if (nodeIsBlock(node_tags[while_node.ast.then_expr])) {1010 if (nodeIsBlock(node_tags[while_node.ast.then_expr])) {
1064 const payload_space: Space = if (while_node.ast.cont_expr != 0) .Space else .BlockStart;
1065 if (while_node.payload_token) |payload_token| {1011 if (while_node.payload_token) |payload_token| {
1066 try renderToken(ais, tree, payload_token - 2, .Space); // )1012 try renderToken(ais, tree, payload_token - 2, .Space); // )
1067 try renderToken(ais, tree, payload_token - 1, .None); // |1013 try renderToken(ais, tree, payload_token - 1, .None); // |
1068 if (token_tags[payload_token] == .Asterisk) {1014 const ident = blk: {
1069 try renderToken(ais, tree, payload_token, .None); // *1015 if (token_tags[payload_token] == .Asterisk) {
1070 try renderToken(ais, tree, payload_token + 1, .None); // identifier1016 try renderToken(ais, tree, payload_token, .None); // *
1071 try renderToken(ais, tree, payload_token + 2, payload_space); // |1017 break :blk payload_token + 1;
1072 } else {1018 } else {
1073 try renderToken(ais, tree, payload_token, .None); // identifier1019 break :blk payload_token;
1074 try renderToken(ais, tree, payload_token + 1, payload_space); // |1020 }
1075 }1021 };
1022 try renderToken(ais, tree, ident, .None); // identifier
1023 const pipe = blk: {
1024 if (token_tags[ident + 1] == .Comma) {
1025 try renderToken(ais, tree, ident + 1, .Space); // ,
1026 try renderToken(ais, tree, ident + 2, .None); // index
1027 break :blk payload_token + 3;
1028 } else {
1029 break :blk ident + 1;
1030 }
1031 };
1032 try renderToken(ais, tree, pipe, .Space); // |
1076 } else {1033 } else {
1077 const rparen = tree.lastToken(while_node.ast.cond_expr) + 1;1034 const rparen = tree.lastToken(while_node.ast.cond_expr) + 1;
1078 try renderToken(ais, tree, rparen, payload_space); // )1035 try renderToken(ais, tree, rparen, .Space); // )
1079 }1036 }
1080 if (while_node.ast.cont_expr != 0) {1037 if (while_node.ast.cont_expr != 0) {
1081 const rparen = tree.lastToken(while_node.ast.cont_expr) + 1;1038 const rparen = tree.lastToken(while_node.ast.cont_expr) + 1;
...@@ -1083,7 +1040,7 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa...@@ -1083,7 +1040,7 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
1083 try renderToken(ais, tree, lparen - 1, .Space); // :1040 try renderToken(ais, tree, lparen - 1, .Space); // :
1084 try renderToken(ais, tree, lparen, .None); // lparen1041 try renderToken(ais, tree, lparen, .None); // lparen
1085 try renderExpression(ais, tree, while_node.ast.cont_expr, .None);1042 try renderExpression(ais, tree, while_node.ast.cont_expr, .None);
1086 try renderToken(ais, tree, rparen, .BlockStart); // rparen1043 try renderToken(ais, tree, rparen, .Space); // rparen
1087 }1044 }
1088 if (while_node.ast.else_expr != 0) {1045 if (while_node.ast.else_expr != 0) {
1089 try renderExpression(ais, tree, while_node.ast.then_expr, Space.Space);1046 try renderExpression(ais, tree, while_node.ast.then_expr, Space.Space);
...@@ -1104,15 +1061,31 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa...@@ -1104,15 +1061,31 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
1104 const src_has_newline = !tree.tokensOnSameLine(rparen, last_then_token);1061 const src_has_newline = !tree.tokensOnSameLine(rparen, last_then_token);
11051062
1106 if (src_has_newline) {1063 if (src_has_newline) {
1107 const payload_space: Space = if (while_node.ast.cont_expr != 0) .Space else .Newline;
1108 if (while_node.payload_token) |payload_token| {1064 if (while_node.payload_token) |payload_token| {
1109 try renderToken(ais, tree, payload_token - 2, .Space); // )1065 try renderToken(ais, tree, payload_token - 2, .Space); // )
1110 try renderToken(ais, tree, payload_token - 1, .None); // |1066 try renderToken(ais, tree, payload_token - 1, .None); // |
1111 try renderToken(ais, tree, payload_token, .None); // identifier1067 const ident = blk: {
1112 try renderToken(ais, tree, payload_token + 1, payload_space); // |1068 if (token_tags[payload_token] == .Asterisk) {
1069 try renderToken(ais, tree, payload_token, .None); // *
1070 break :blk payload_token + 1;
1071 } else {
1072 break :blk payload_token;
1073 }
1074 };
1075 try renderToken(ais, tree, ident, .None); // identifier
1076 const pipe = blk: {
1077 if (token_tags[ident + 1] == .Comma) {
1078 try renderToken(ais, tree, ident + 1, .Space); // ,
1079 try renderToken(ais, tree, ident + 2, .None); // index
1080 break :blk payload_token + 3;
1081 } else {
1082 break :blk ident + 1;
1083 }
1084 };
1085 try renderToken(ais, tree, pipe, .Newline); // |
1113 } else {1086 } else {
1114 ais.pushIndent();1087 ais.pushIndent();
1115 try renderToken(ais, tree, rparen, payload_space); // )1088 try renderToken(ais, tree, rparen, .Newline); // )
1116 ais.popIndent();1089 ais.popIndent();
1117 }1090 }
1118 if (while_node.ast.cont_expr != 0) {1091 if (while_node.ast.cont_expr != 0) {
...@@ -1164,14 +1137,25 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa...@@ -1164,14 +1137,25 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
1164 assert(payload_token - 2 == rparen);1137 assert(payload_token - 2 == rparen);
1165 try renderToken(ais, tree, payload_token - 2, .Space); // )1138 try renderToken(ais, tree, payload_token - 2, .Space); // )
1166 try renderToken(ais, tree, payload_token - 1, .None); // |1139 try renderToken(ais, tree, payload_token - 1, .None); // |
1167 if (token_tags[payload_token] == .Asterisk) {1140 const ident = blk: {
1168 try renderToken(ais, tree, payload_token, .None); // *1141 if (token_tags[payload_token] == .Asterisk) {
1169 try renderToken(ais, tree, payload_token + 1, .None); // identifier1142 try renderToken(ais, tree, payload_token, .None); // *
1170 try renderToken(ais, tree, payload_token + 2, .Space); // |1143 break :blk payload_token + 1;
1171 } else {1144 } else {
1172 try renderToken(ais, tree, payload_token, .None); // identifier1145 break :blk payload_token;
1173 try renderToken(ais, tree, payload_token + 1, .Space); // |1146 }
1174 }1147 };
1148 try renderToken(ais, tree, ident, .None); // identifier
1149 const pipe = blk: {
1150 if (token_tags[ident + 1] == .Comma) {
1151 try renderToken(ais, tree, ident + 1, .Space); // ,
1152 try renderToken(ais, tree, ident + 2, .None); // index
1153 break :blk payload_token + 3;
1154 } else {
1155 break :blk ident + 1;
1156 }
1157 };
1158 try renderToken(ais, tree, pipe, .Space); // |
1175 } else {1159 } else {
1176 try renderToken(ais, tree, rparen, .Space); // )1160 try renderToken(ais, tree, rparen, .Space); // )
1177 }1161 }
...@@ -1952,18 +1936,9 @@ const Space = enum {...@@ -1952,18 +1936,9 @@ const Space = enum {
1952 Semicolon,1936 Semicolon,
1953 /// Skips writing the possible line comment after the token.1937 /// Skips writing the possible line comment after the token.
1954 NoComment,1938 NoComment,
1955 /// Intended when rendering lbrace tokens. Depending on whether the line is
1956 /// "over indented", will output a newline or a single space afterwards.
1957 /// See `std.io.AutoIndentingStream` for the definition of "over indented".
1958 BlockStart,
1959};1939};
19601940
1961fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void {1941fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void {
1962 if (space == Space.BlockStart) {
1963 const new_space: Space = if (ais.isLineOverIndented()) .Newline else .Space;
1964 return renderToken(ais, tree, token_index, new_space);
1965 }
1966
1967 const token_tags = tree.tokens.items(.tag);1942 const token_tags = tree.tokens.items(.tag);
1968 const token_starts = tree.tokens.items(.start);1943 const token_starts = tree.tokens.items(.start);
19691944
...@@ -2020,7 +1995,6 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp...@@ -2020,7 +1995,6 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp
2020 try ais.insertNewline();1995 try ais.insertNewline();
2021 }1996 }
2022 },1997 },
2023 .BlockStart => unreachable,
2024 }1998 }
2025}1999}
20262000
...@@ -2069,6 +2043,7 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool {...@@ -2069,6 +2043,7 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool {
2069 .WhileSimple,2043 .WhileSimple,
2070 .WhileCont,2044 .WhileCont,
2071 .Switch,2045 .Switch,
2046 .SwitchComma,
2072 => true,2047 => true,
2073 else => false,2048 else => false,
2074 };2049 };