[goos] support improper lists in pretty printer (#1001)

This commit is contained in:
water111
2021-12-09 20:56:50 -05:00
committed by GitHub
parent 1cac684f1b
commit fe9c5c10d1
2 changed files with 39 additions and 9 deletions
+19 -7
View File
@@ -26,13 +26,10 @@ struct Node {
}
Node(std::vector<Node>&& list, bool is_list) {
kind = is_list ? Kind::LIST : Kind::PAIR;
if (!is_list) {
assert(list.size() == 2);
}
kind = is_list ? Kind::LIST : Kind::IMPROPER_LIST;
child_nodes = std::move(list);
}
enum class Kind : u8 { ATOM, LIST, PAIR, INVALID } kind = Kind::INVALID;
enum class Kind : u8 { ATOM, LIST, IMPROPER_LIST, INVALID } kind = Kind::INVALID;
std::vector<Node> child_nodes;
std::string atom_str;
@@ -51,7 +48,7 @@ struct Node {
case Kind::ATOM:
break;
case Kind::LIST:
case Kind::PAIR:
case Kind::IMPROPER_LIST:
assert(!child_nodes.empty());
for (auto& child : child_nodes) {
child.link(this, bfs_order, depth + 1);
@@ -122,7 +119,6 @@ Node to_node(const goos::Object& obj) {
}
} else {
children.push_back(to_node(*to_print));
assert(false); // untested
return Node(std::move(children), false);
}
}
@@ -147,6 +143,7 @@ void recompute_lengths(const std::vector<Node*>& bfs_order) {
case Node::Kind::ATOM:
node->text_len = node->atom_str.length() + node->quoted;
break;
case Node::Kind::IMPROPER_LIST:
case Node::Kind::LIST: {
if (node->break_list) {
// special case compute first line length
@@ -323,6 +320,7 @@ void append_node_to_string(const Node* node,
case Node::Kind::ATOM:
str.append(node->atom_str);
break;
case Node::Kind::IMPROPER_LIST:
case Node::Kind::LIST:
if (node->break_list) {
str.push_back('(');
@@ -332,6 +330,10 @@ void append_node_to_string(const Node* node,
int extra_indent = 0;
for (; node_idx < node->top_line_count; node_idx++) {
size_t s0 = str.length();
if (node->kind == Node::Kind::IMPROPER_LIST &&
&node->child_nodes.at(node_idx) == &node->child_nodes.back()) {
str.append(". ");
}
append_node_to_string(&node->child_nodes.at(node_idx), str, 0,
listing_indent + extra_indent);
// extra_indent += (str.length() - s0);
@@ -343,6 +345,13 @@ void append_node_to_string(const Node* node,
}
str.push_back('\n');
for (; node_idx < node->child_nodes.size(); node_idx++) {
if (node->kind == Node::Kind::IMPROPER_LIST &&
&node->child_nodes.at(node_idx) == &node->child_nodes.back()) {
for (int i = 0; i < listing_indent; i++) {
str.push_back(' ');
}
str.append(".\n");
}
append_node_to_string(&node->child_nodes.at(node_idx), str, listing_indent,
listing_indent);
str.push_back('\n');
@@ -358,6 +367,9 @@ void append_node_to_string(const Node* node,
int extra_indent = 1;
int c0 = 0;
for (auto& child : node->child_nodes) {
if (node->kind == Node::Kind::IMPROPER_LIST && &child == &node->child_nodes.back()) {
str.append(". ");
}
size_t s0 = str.length();
append_node_to_string(&child, str, 0, listing_indent + extra_indent);
str.push_back(' ');
+20 -2
View File
@@ -102,10 +102,10 @@ TEST(PrettyPrinter2, Debugging) {
}
namespace {
std::string pretty_print_v2(const std::string& str) {
std::string pretty_print_v2(const std::string& str, int line_length = 110) {
auto obj =
pretty_print::get_pretty_printer_reader().read_from_string(str).as_pair()->cdr.as_pair()->car;
return pretty_print::to_string(obj);
return pretty_print::to_string(obj, line_length);
}
} // namespace
@@ -240,3 +240,21 @@ TEST(PrettyPrint2, ParenWayOutToTheRight) {
)
))");
}
TEST(PrettyPrint2, ImproperList) {
std::string code = "( ( a . b) ( c . d ) ( e f . g) . #f )";
EXPECT_EQ(pretty_print_v2(code), "((a . b) (c . d) (e f . g) . #f)");
}
TEST(PrettyPrint2, ImproperListMultiLine) {
std::string code =
"( ( asdfasfdasdf . b) ( casdfsadfasdf . dsadfasfdsf ) ( esdfasdf fdasfsadf . gdfasfd) . "
"#f )";
EXPECT_EQ(pretty_print_v2(code, 40),
"((asdfasfdasdf . b)\n"
" (casdfsadfasdf . dsadfasfdsf)\n"
" (esdfasdf fdasfsadf . gdfasfd)\n"
" .\n"
" #f\n"
" )");
}