| ... | @@ -203,7 +203,9 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I | ... | @@ -203,7 +203,9 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I |
| 203 | | 203 | |
| 204 | switch (space) { | 204 | switch (space) { |
| 205 | .none, .space, .newline => {}, | 205 | .none, .space, .newline => {}, |
| | 206 | .newline_pop => ais.popIndent(), |
| 206 | .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline), | 207 | .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline), |
| | 208 | .semicolon_pop => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline_pop), |
| 207 | .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline), | 209 | .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline), |
| 208 | .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space), | 210 | .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space), |
| 209 | } | 211 | } |
| ... | @@ -1152,8 +1154,8 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full. | ... | @@ -1152,8 +1154,8 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full. |
| 1152 | } | 1154 | } |
| 1153 | } else { | 1155 | } else { |
| 1154 | ais.pushIndent(); | 1156 | ais.pushIndent(); |
| 1155 | try renderExpression(gpa, ais, tree, while_node.ast.then_expr, space); | 1157 | assert(space == .semicolon); |
| 1156 | ais.popIndent(); | 1158 | try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .semicolon_pop); |
| 1157 | return; | 1159 | return; |
| 1158 | } | 1160 | } |
| 1159 | } | 1161 | } |
| ... | @@ -2196,6 +2198,9 @@ const Space = enum { | ... | @@ -2196,6 +2198,9 @@ const Space = enum { |
| 2196 | space, | 2198 | space, |
| 2197 | /// Output the token lexeme followed by a newline. | 2199 | /// Output the token lexeme followed by a newline. |
| 2198 | newline, | 2200 | newline, |
| | 2201 | /// Same as newline, but pop an indent level before rendering the |
| | 2202 | /// following comments if any. |
| | 2203 | newline_pop, |
| 2199 | /// If the next token is a comma, render it as well. If not, insert one. | 2204 | /// If the next token is a comma, render it as well. If not, insert one. |
| 2200 | /// In either case, a newline will be inserted afterwards. | 2205 | /// In either case, a newline will be inserted afterwards. |
| 2201 | comma, | 2206 | comma, |
| ... | @@ -2205,6 +2210,9 @@ const Space = enum { | ... | @@ -2205,6 +2210,9 @@ const Space = enum { |
| 2205 | /// Additionally consume the next token if it is a semicolon. | 2210 | /// Additionally consume the next token if it is a semicolon. |
| 2206 | /// In either case, a newline will be inserted afterwards. | 2211 | /// In either case, a newline will be inserted afterwards. |
| 2207 | semicolon, | 2212 | semicolon, |
| | 2213 | /// Same as semicolon, but pop an indent level before rendering the |
| | 2214 | /// following comments if any. |
| | 2215 | semicolon_pop, |
| 2208 | }; | 2216 | }; |
| 2209 | | 2217 | |
| 2210 | fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void { | 2218 | fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void { |
| ... | @@ -2216,32 +2224,64 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp | ... | @@ -2216,32 +2224,64 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp |
| 2216 | | 2224 | |
| 2217 | try ais.writer().writeAll(lexeme); | 2225 | try ais.writer().writeAll(lexeme); |
| 2218 | | 2226 | |
| 2219 | if (space == .comma and token_tags[token_index + 1] != .comma) { | 2227 | const token_end = token_start + lexeme.len; |
| 2220 | try ais.writer().writeByte(','); | 2228 | const next_token_start = token_starts[token_index + 1]; |
| 2221 | } | | |
| 2222 | | | |
| 2223 | const comment = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1]); | | |
| 2224 | switch (space) { | 2229 | switch (space) { |
| 2225 | .none => {}, | 2230 | .none => _ = try renderComments(ais, tree, token_end, next_token_start), |
| 2226 | .space => if (!comment) try ais.writer().writeByte(' '), | | |
| 2227 | .newline => if (!comment) try ais.insertNewline(), | | |
| 2228 | | 2231 | |
| 2229 | .comma => if (token_tags[token_index + 1] == .comma) { | 2232 | .space => if (!try renderComments(ais, tree, token_end, next_token_start)) { |
| 2230 | try renderToken(ais, tree, token_index + 1, .newline); | 2233 | try ais.writer().writeByte(' '); |
| 2231 | } else if (!comment) { | 2234 | }, |
| | 2235 | |
| | 2236 | .newline => if (!try renderComments(ais, tree, token_end, next_token_start)) { |
| 2232 | try ais.insertNewline(); | 2237 | try ais.insertNewline(); |
| 2233 | }, | 2238 | }, |
| 2234 | | 2239 | |
| 2235 | .comma_space => if (token_tags[token_index + 1] == .comma) { | 2240 | .newline_pop => { |
| 2236 | try renderToken(ais, tree, token_index + 1, .space); | 2241 | ais.popIndent(); |
| 2237 | } else if (!comment) { | 2242 | if (!try renderComments(ais, tree, token_end, next_token_start)) { |
| 2238 | try ais.writer().writeByte(' '); | 2243 | try ais.insertNewline(); |
| | 2244 | } |
| 2239 | }, | 2245 | }, |
| 2240 | | 2246 | |
| 2241 | .semicolon => if (token_tags[token_index + 1] == .semicolon) { | 2247 | .comma => if (token_tags[token_index + 1] == .comma) { |
| | 2248 | _ = try renderComments(ais, tree, token_end, next_token_start); |
| 2242 | try renderToken(ais, tree, token_index + 1, .newline); | 2249 | try renderToken(ais, tree, token_index + 1, .newline); |
| 2243 | } else if (!comment) { | 2250 | } else { |
| 2244 | try ais.insertNewline(); | 2251 | try ais.writer().writeByte(','); |
| | 2252 | if (!try renderComments(ais, tree, token_end, next_token_start)) { |
| | 2253 | try ais.insertNewline(); |
| | 2254 | } |
| | 2255 | }, |
| | 2256 | |
| | 2257 | .comma_space => { |
| | 2258 | const comment = try renderComments(ais, tree, token_end, next_token_start); |
| | 2259 | if (token_tags[token_index + 1] == .comma) { |
| | 2260 | try renderToken(ais, tree, token_index + 1, .space); |
| | 2261 | } else if (!comment) { |
| | 2262 | try ais.writer().writeByte(' '); |
| | 2263 | } |
| | 2264 | }, |
| | 2265 | |
| | 2266 | .semicolon => { |
| | 2267 | const comment = try renderComments(ais, tree, token_end, next_token_start); |
| | 2268 | if (token_tags[token_index + 1] == .semicolon) { |
| | 2269 | try renderToken(ais, tree, token_index + 1, .newline); |
| | 2270 | } else if (!comment) { |
| | 2271 | try ais.insertNewline(); |
| | 2272 | } |
| | 2273 | }, |
| | 2274 | |
| | 2275 | .semicolon_pop => { |
| | 2276 | if (token_tags[token_index + 1] == .semicolon) { |
| | 2277 | _ = try renderComments(ais, tree, token_end, next_token_start); |
| | 2278 | try renderToken(ais, tree, token_index + 1, .newline_pop); |
| | 2279 | } else { |
| | 2280 | ais.popIndent(); |
| | 2281 | if (!try renderComments(ais, tree, token_end, next_token_start)) { |
| | 2282 | try ais.insertNewline(); |
| | 2283 | } |
| | 2284 | } |
| 2245 | }, | 2285 | }, |
| 2246 | } | 2286 | } |
| 2247 | } | 2287 | } |