| ... | @@ -19,7 +19,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf( | ... | @@ -19,7 +19,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf( |
| 19 | var tok_it = tree.tokens.iterator(0); | 19 | var tok_it = tree.tokens.iterator(0); |
| 20 | while (tok_it.next()) |token| { | 20 | while (tok_it.next()) |token| { |
| 21 | if (token.id != Token.Id.LineComment) break; | 21 | if (token.id != Token.Id.LineComment) break; |
| 22 | try stream.print("{}\n", tree.tokenSlicePtr(token)); | 22 | try stream.print("{}\n", mem.trimRight(u8, tree.tokenSlicePtr(token), " ")); |
| 23 | if (tok_it.peek()) |next_token| { | 23 | if (tok_it.peek()) |next_token| { |
| 24 | const loc = tree.tokenLocationPtr(token.end, next_token); | 24 | const loc = tree.tokenLocationPtr(token.end, next_token); |
| 25 | if (loc.line >= 2) { | 25 | if (loc.line >= 2) { |
| ... | @@ -532,12 +532,73 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind | ... | @@ -532,12 +532,73 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 532 | | 532 | |
| 533 | try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None); | 533 | try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None); |
| 534 | | 534 | |
| | 535 | // scan to find row size |
| | 536 | const maybe_row_size: ?usize = blk: { |
| | 537 | var count: usize = 0; |
| | 538 | var it = exprs.iterator(0); |
| | 539 | var prev_token = (??it.peek()).*.lastToken() + 1; |
| | 540 | while (it.next()) |expr| { |
| | 541 | const expr_last_token = expr.*.lastToken() + 1; |
| | 542 | const next_token = tree.tokens.at(expr_last_token + 1); |
| | 543 | const loc = tree.tokenLocationPtr(tree.tokens.at(prev_token).end, next_token); |
| | 544 | if (loc.line != 0) break :blk null; |
| | 545 | if (next_token.id == Token.Id.LineComment) { |
| | 546 | const trimmed = mem.trimRight(u8, tree.tokenSlicePtr(next_token), " "); |
| | 547 | if (trimmed.len == 2) { |
| | 548 | break :blk count; |
| | 549 | } else { |
| | 550 | break :blk null; |
| | 551 | } |
| | 552 | } |
| | 553 | prev_token = expr_last_token; |
| | 554 | count += 1; |
| | 555 | } |
| | 556 | break :blk null; |
| | 557 | }; |
| | 558 | |
| | 559 | |
| 535 | const new_indent = indent + indent_delta; | 560 | const new_indent = indent + indent_delta; |
| 536 | try renderToken(tree, stream, lbrace, new_indent, Space.Newline); | 561 | try renderToken(tree, stream, lbrace, new_indent, Space.Newline); |
| | 562 | try stream.writeByteNTimes(' ', new_indent); |
| | 563 | |
| | 564 | if (maybe_row_size) |row_size| { |
| | 565 | var it = exprs.iterator(0); |
| | 566 | var i: usize = 0; |
| | 567 | while (it.next()) |expr| { |
| | 568 | if (it.peek()) |next_expr| { |
| | 569 | try renderExpression(allocator, stream, tree, new_indent, expr.*, Space.None); |
| | 570 | |
| | 571 | const comma = tree.nextToken(expr.*.lastToken()); |
| | 572 | |
| | 573 | if (i != row_size) { |
| | 574 | try renderToken(tree, stream, comma, new_indent, Space.IgnoreEmptyComment); // , |
| | 575 | i += 1; |
| | 576 | continue; |
| | 577 | } |
| | 578 | i = 0; |
| | 579 | |
| | 580 | try renderToken(tree, stream, comma, new_indent, Space.NoIndent); // , |
| | 581 | |
| | 582 | const next_token = tree.tokens.at(comma + 1); |
| | 583 | if (next_token.id != Token.Id.LineComment) { |
| | 584 | try stream.print(" //\n"); |
| | 585 | } |
| | 586 | |
| | 587 | try renderExtraNewline(tree, stream, next_expr.*); |
| | 588 | try stream.writeByteNTimes(' ', new_indent); |
| | 589 | } else if (i == row_size) { |
| | 590 | try renderTrailingCommaAndEmptyComment(allocator, stream, tree, new_indent, expr.*); // , // |
| | 591 | } else { |
| | 592 | try renderTrailingComma(allocator, stream, tree, new_indent, expr.*, Space.Newline); // , |
| | 593 | } |
| | 594 | } |
| | 595 | try stream.writeByteNTimes(' ', indent); |
| | 596 | try renderToken(tree, stream, suffix_op.rtoken, indent, space); |
| | 597 | return; |
| | 598 | } |
| 537 | | 599 | |
| 538 | var it = exprs.iterator(0); | 600 | var it = exprs.iterator(0); |
| 539 | while (it.next()) |expr| { | 601 | while (it.next()) |expr| { |
| 540 | try stream.writeByteNTimes(' ', new_indent); | | |
| 541 | | 602 | |
| 542 | if (it.peek()) |next_expr| { | 603 | if (it.peek()) |next_expr| { |
| 543 | try renderExpression(allocator, stream, tree, new_indent, expr.*, Space.None); | 604 | try renderExpression(allocator, stream, tree, new_indent, expr.*, Space.None); |
| ... | @@ -546,6 +607,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind | ... | @@ -546,6 +607,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 546 | try renderToken(tree, stream, comma, new_indent, Space.Newline); // , | 607 | try renderToken(tree, stream, comma, new_indent, Space.Newline); // , |
| 547 | | 608 | |
| 548 | try renderExtraNewline(tree, stream, next_expr.*); | 609 | try renderExtraNewline(tree, stream, next_expr.*); |
| | 610 | try stream.writeByteNTimes(' ', new_indent); |
| 549 | } else { | 611 | } else { |
| 550 | try renderTrailingComma(allocator, stream, tree, new_indent, expr.*, Space.Newline); | 612 | try renderTrailingComma(allocator, stream, tree, new_indent, expr.*, Space.Newline); |
| 551 | } | 613 | } |
| ... | @@ -1496,11 +1558,12 @@ const Space = enum { | ... | @@ -1496,11 +1558,12 @@ const Space = enum { |
| 1496 | NoNewline, | 1558 | NoNewline, |
| 1497 | NoIndent, | 1559 | NoIndent, |
| 1498 | NoComment, | 1560 | NoComment, |
| | 1561 | IgnoreEmptyComment, |
| 1499 | }; | 1562 | }; |
| 1500 | | 1563 | |
| 1501 | fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, space: Space) (@typeOf(stream).Child.Error || Error)!void { | 1564 | fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, space: Space) (@typeOf(stream).Child.Error || Error)!void { |
| 1502 | var token = tree.tokens.at(token_index); | 1565 | var token = tree.tokens.at(token_index); |
| 1503 | try stream.write(tree.tokenSlicePtr(token)); | 1566 | try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(token), " ")); |
| 1504 | | 1567 | |
| 1505 | if (space == Space.NoComment) return; | 1568 | if (space == Space.NoComment) return; |
| 1506 | | 1569 | |
| ... | @@ -1515,15 +1578,19 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent | ... | @@ -1515,15 +1578,19 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent |
| 1515 | return stream.write("\n"); | 1578 | return stream.write("\n"); |
| 1516 | } | 1579 | } |
| 1517 | }, | 1580 | }, |
| 1518 | Space.Space => return stream.writeByte(' '), | 1581 | Space.Space, Space.IgnoreEmptyComment => return stream.writeByte(' '), |
| 1519 | Space.NoComment => unreachable, | 1582 | Space.NoComment => unreachable, |
| 1520 | } | 1583 | } |
| 1521 | } | 1584 | } |
| 1522 | | 1585 | |
| | 1586 | if (space == Space.IgnoreEmptyComment and mem.trimRight(u8, tree.tokenSlicePtr(next_token), " ").len == 2) { |
| | 1587 | return stream.writeByte(' '); |
| | 1588 | } |
| | 1589 | |
| 1523 | var loc = tree.tokenLocationPtr(token.end, next_token); | 1590 | var loc = tree.tokenLocationPtr(token.end, next_token); |
| 1524 | var offset: usize = 1; | 1591 | var offset: usize = 1; |
| 1525 | if (loc.line == 0) { | 1592 | if (loc.line == 0) { |
| 1526 | try stream.print(" {}", tree.tokenSlicePtr(next_token)); | 1593 | try stream.print(" {}", mem.trimRight(u8, tree.tokenSlicePtr(next_token), " ")); |
| 1527 | offset = 2; | 1594 | offset = 2; |
| 1528 | token = next_token; | 1595 | token = next_token; |
| 1529 | next_token = tree.tokens.at(token_index + offset); | 1596 | next_token = tree.tokens.at(token_index + offset); |
| ... | @@ -1546,7 +1613,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent | ... | @@ -1546,7 +1613,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent |
| 1546 | } | 1613 | } |
| 1547 | }, | 1614 | }, |
| 1548 | Space.NoNewline => {}, | 1615 | Space.NoNewline => {}, |
| 1549 | Space.NoComment => unreachable, | 1616 | Space.NoComment, Space.IgnoreEmptyComment => unreachable, |
| 1550 | } | 1617 | } |
| 1551 | return; | 1618 | return; |
| 1552 | } | 1619 | } |
| ... | @@ -1558,7 +1625,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent | ... | @@ -1558,7 +1625,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent |
| 1558 | const newline_count = if (loc.line == 1) u8(1) else u8(2); | 1625 | const newline_count = if (loc.line == 1) u8(1) else u8(2); |
| 1559 | try stream.writeByteNTimes('\n', newline_count); | 1626 | try stream.writeByteNTimes('\n', newline_count); |
| 1560 | try stream.writeByteNTimes(' ', indent); | 1627 | try stream.writeByteNTimes(' ', indent); |
| 1561 | try stream.write(tree.tokenSlicePtr(next_token)); | 1628 | try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(next_token), " ")); |
| 1562 | | 1629 | |
| 1563 | offset += 1; | 1630 | offset += 1; |
| 1564 | token = next_token; | 1631 | token = next_token; |
| ... | @@ -1583,7 +1650,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent | ... | @@ -1583,7 +1650,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent |
| 1583 | try stream.writeByteNTimes(' ', next_line_indent); | 1650 | try stream.writeByteNTimes(' ', next_line_indent); |
| 1584 | }, | 1651 | }, |
| 1585 | Space.NoNewline => {}, | 1652 | Space.NoNewline => {}, |
| 1586 | Space.NoComment => unreachable, | 1653 | Space.NoComment, Space.IgnoreEmptyComment => unreachable, |
| 1587 | } | 1654 | } |
| 1588 | return; | 1655 | return; |
| 1589 | } | 1656 | } |
| ... | @@ -1621,3 +1688,28 @@ fn renderTrailingComma(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, | ... | @@ -1621,3 +1688,28 @@ fn renderTrailingComma(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, |
| 1621 | }, | 1688 | }, |
| 1622 | } | 1689 | } |
| 1623 | } | 1690 | } |
| | 1691 | |
| | 1692 | fn renderTrailingCommaAndEmptyComment(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node) (@typeOf(stream).Child.Error || Error)!void |
| | 1693 | { |
| | 1694 | const end_token = base.lastToken() + 1; |
| | 1695 | switch (tree.tokens.at(end_token).id) { |
| | 1696 | Token.Id.Comma => { |
| | 1697 | try renderExpression(allocator, stream, tree, indent, base, Space.None); |
| | 1698 | try renderToken(tree, stream, end_token, indent, Space.Space); // , |
| | 1699 | |
| | 1700 | const next_token = tree.tokens.at(end_token + 1); |
| | 1701 | if (next_token.id != Token.Id.LineComment) { |
| | 1702 | try stream.print("//\n"); |
| | 1703 | } |
| | 1704 | }, |
| | 1705 | Token.Id.LineComment => { |
| | 1706 | try renderExpression(allocator, stream, tree, indent, base, Space.NoComment); |
| | 1707 | try stream.write(", "); |
| | 1708 | try renderToken(tree, stream, end_token, indent, Space.Newline); |
| | 1709 | }, |
| | 1710 | else => { |
| | 1711 | try renderExpression(allocator, stream, tree, indent, base, Space.None); |
| | 1712 | try stream.write(", //\n"); |
| | 1713 | }, |
| | 1714 | } |
| | 1715 | } |