| ... | @@ -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 | }, |
| 500 | | 500 | |
| 501 | .Continue => unreachable, // TODO | 501 | .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); // continue | 505 | 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); // label | 508 | } else { |
| 509 | // } else { | 509 | return renderToken(ais, tree, main_token, space); // continue |
| 510 | // return renderToken(ais, tree, flow_expr.ltoken, space); // continue | 510 | } |
| 511 | // } | 511 | }, |
| 512 | //}, | | |
| 513 | | 512 | |
| 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); // lbrace | 664 | try renderToken(ais, tree, rparen + 1, .None); // lbrace |
| 666 | return renderToken(ais, tree, rparen + 2, space); // rbrace | 665 | 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 | }, |
| 679 | | 677 | |
| 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), |
| 686 | | 684 | .ForSimple => return renderWhile(ais, tree, tree.forSimple(node), space), |
| 687 | .ForSimple => unreachable, // TODO | 685 | .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 | //}, | | |
| 739 | | 686 | |
| 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 | } |
| 1043 | | 990 | |
| 1044 | /// Note that this function is additionally used to render if expressions, with | 991 | /// 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. |
| 1046 | fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Space) Error!void { | 993 | fn 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); // condition | 1008 | try renderExpression(ais, tree, while_node.ast.cond_expr, .None); // condition |
| 1062 | | 1009 | |
| 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); // identifier | 1016 | 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); // identifier | 1019 | 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); // lparen | 1041 | 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); // rparen | 1043 | 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); |
| 1105 | | 1062 | |
| 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); // identifier | 1067 | 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); // identifier | 1142 | 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); // identifier | 1145 | 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 | }; |
| 1960 | | 1940 | |
| 1961 | fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void { | 1941 | fn 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); |
| 1969 | | 1944 | |
| ... | @@ -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 | } |
| 2026 | | 2000 | |
| ... | @@ -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 | }; |