| ... | ... | @@ -14,8 +14,13 @@ const RenderState = union(enum) { |
| 14 | 14 | Statement: &ast.Node, |
| 15 | 15 | PrintIndent, |
| 16 | 16 | Indent: usize, |
| 17 | MaybeSemiColon: &ast.Node, |
| 18 | Token: ast.TokenIndex, |
| 19 | NonBreakToken: ast.TokenIndex, |
| 17 | 20 | }; |
| 18 | 21 | |
| 22 | const indent_delta = 4; |
| 23 | |
| 19 | 24 | pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void { |
| 20 | 25 | var stack = SegmentedList(RenderState, 32).init(allocator); |
| 21 | 26 | defer stack.deinit(); |
| ... | ... | @@ -44,7 +49,6 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void { |
| 44 | 49 | } |
| 45 | 50 | } |
| 46 | 51 | |
| 47 | | const indent_delta = 4; |
| 48 | 52 | var indent: usize = 0; |
| 49 | 53 | while (stack.pop()) |state| { |
| 50 | 54 | switch (state) { |
| ... | ... | @@ -92,7 +96,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void { |
| 92 | 96 | try stream.print("{} ", tree.tokenSlice(visib_token)); |
| 93 | 97 | } |
| 94 | 98 | try stream.print("{}: ", tree.tokenSlice(field.name_token)); |
| 95 | | try stack.push(RenderState { .Text = "," }); |
| 99 | try stack.push(RenderState { .Token = field.lastToken() + 1 }); |
| 96 | 100 | try stack.push(RenderState { .Expression = field.type_expr}); |
| 97 | 101 | }, |
| 98 | 102 | ast.Node.Id.UnionTag => { |
| ... | ... | @@ -129,9 +133,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void { |
| 129 | 133 | try stream.print("{}", tree.tokenSlice(tag.name_token)); |
| 130 | 134 | }, |
| 131 | 135 | ast.Node.Id.Comptime => { |
| 132 | | if (decl.requireSemiColon()) { |
| 133 | | try stack.push(RenderState { .Text = ";" }); |
| 134 | | } |
| 136 | try stack.push(RenderState { .MaybeSemiColon = decl }); |
| 135 | 137 | try stack.push(RenderState { .Expression = decl }); |
| 136 | 138 | }, |
| 137 | 139 | ast.Node.Id.LineComment => { |
| ... | ... | @@ -143,7 +145,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void { |
| 143 | 145 | }, |
| 144 | 146 | |
| 145 | 147 | RenderState.VarDecl => |var_decl| { |
| 146 | | try stack.push(RenderState { .Text = ";" }); |
| 148 | try stack.push(RenderState { .Token = var_decl.semicolon_token }); |
| 147 | 149 | if (var_decl.init_node) |init_node| { |
| 148 | 150 | try stack.push(RenderState { .Expression = init_node }); |
| 149 | 151 | const text = if (init_node.id == ast.Node.Id.MultilineStringLiteral) " =" else " = "; |
| ... | ... | @@ -895,7 +897,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void { |
| 895 | 897 | ast.Node.Id.SwitchCase => { |
| 896 | 898 | const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base); |
| 897 | 899 | |
| 898 | | try stack.push(RenderState { .Text = "," }); |
| 900 | try stack.push(RenderState { .Token = switch_case.lastToken() + 1 }); |
| 899 | 901 | try stack.push(RenderState { .Expression = switch_case.expr }); |
| 900 | 902 | if (switch_case.payload) |payload| { |
| 901 | 903 | try stack.push(RenderState { .Text = " " }); |
| ... | ... | @@ -1072,14 +1074,13 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void { |
| 1072 | 1074 | } |
| 1073 | 1075 | |
| 1074 | 1076 | try stack.push(RenderState { .Expression = if_node.body }); |
| 1075 | | try stack.push(RenderState { .Text = " " }); |
| 1076 | 1077 | |
| 1077 | 1078 | if (if_node.payload) |payload| { |
| 1078 | | try stack.push(RenderState { .Expression = payload }); |
| 1079 | 1079 | try stack.push(RenderState { .Text = " " }); |
| 1080 | try stack.push(RenderState { .Expression = payload }); |
| 1080 | 1081 | } |
| 1081 | 1082 | |
| 1082 | | try stack.push(RenderState { .Text = ")" }); |
| 1083 | try stack.push(RenderState { .NonBreakToken = if_node.condition.lastToken() + 1 }); |
| 1083 | 1084 | try stack.push(RenderState { .Expression = if_node.condition }); |
| 1084 | 1085 | try stack.push(RenderState { .Text = "(" }); |
| 1085 | 1086 | }, |
| ... | ... | @@ -1217,17 +1218,46 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void { |
| 1217 | 1218 | try stack.push(RenderState { .VarDecl = var_decl}); |
| 1218 | 1219 | }, |
| 1219 | 1220 | else => { |
| 1220 | | if (base.requireSemiColon()) { |
| 1221 | | try stack.push(RenderState { .Text = ";" }); |
| 1222 | | } |
| 1221 | try stack.push(RenderState { .MaybeSemiColon = base }); |
| 1223 | 1222 | try stack.push(RenderState { .Expression = base }); |
| 1224 | 1223 | }, |
| 1225 | 1224 | } |
| 1226 | 1225 | }, |
| 1227 | 1226 | RenderState.Indent => |new_indent| indent = new_indent, |
| 1228 | 1227 | RenderState.PrintIndent => try stream.writeByteNTimes(' ', indent), |
| 1228 | RenderState.Token => |token_index| try renderToken(tree, stream, token_index, indent, true), |
| 1229 | RenderState.NonBreakToken => |token_index| try renderToken(tree, stream, token_index, indent, false), |
| 1230 | RenderState.MaybeSemiColon => |base| { |
| 1231 | if (base.requireSemiColon()) { |
| 1232 | const semicolon_index = base.lastToken() + 1; |
| 1233 | assert(tree.tokens.at(semicolon_index).id == Token.Id.Semicolon); |
| 1234 | try renderToken(tree, stream, semicolon_index, indent, true); |
| 1235 | } |
| 1236 | }, |
| 1237 | } |
| 1238 | } |
| 1239 | } |
| 1240 | |
| 1241 | fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, line_break: bool) !void { |
| 1242 | const token = tree.tokens.at(token_index); |
| 1243 | try stream.write(tree.tokenSlicePtr(token)); |
| 1244 | |
| 1245 | const next_token = tree.tokens.at(token_index + 1); |
| 1246 | if (next_token.id == Token.Id.LineComment) { |
| 1247 | const loc = tree.tokenLocationPtr(token.end, next_token); |
| 1248 | if (loc.line == 0) { |
| 1249 | try stream.print(" {}", tree.tokenSlicePtr(next_token)); |
| 1250 | if (!line_break) { |
| 1251 | try stream.write("\n"); |
| 1252 | try stream.writeByteNTimes(' ', indent + indent_delta); |
| 1253 | return; |
| 1254 | } |
| 1229 | 1255 | } |
| 1230 | 1256 | } |
| 1257 | |
| 1258 | if (!line_break) { |
| 1259 | try stream.writeByte(' '); |
| 1260 | } |
| 1231 | 1261 | } |
| 1232 | 1262 | |
| 1233 | 1263 | fn renderComments(tree: &ast.Tree, stream: var, node: var, indent: usize) !void { |