summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-11-11 18:45:47 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-11-11 18:45:47 -0800
commit36fc9556a85f37952da4e3b9ad055b54d969e652 (patch)
treea5b982dd657362299724a500b2f580eebd7290bd /lib.c
parentd3904de7a60b76bd1a3f22e6d110689b6ae75106 (diff)
downloadtxr-36fc9556a85f37952da4e3b9ad055b54d969e652.tar.gz
txr-36fc9556a85f37952da4e3b9ad055b54d969e652.tar.bz2
txr-36fc9556a85f37952da4e3b9ad055b54d969e652.zip
Fix pretty printer mishandling unexpected syntax.
* lib.c (obj_print_impl): When rendering quote, quasiquote, unquote, splice, vector literals, and meta-vars/meta-numbers into their read syntax, we must ensure that these forms have the correct abstract syntax. If not, we must print these as ordinary compound expressions. Otherwise we throw errors, or don't print the complete object.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/lib.c b/lib.c
index bddf7f4a..745714f9 100644
--- a/lib.c
+++ b/lib.c
@@ -7820,27 +7820,28 @@ val obj_print_impl(val obj, val out, val pretty)
val save_mode = test_set_indent_mode(out, num_fast(indent_off),
num_fast(indent_data));
val save_indent = nil;
+ int two_elem = consp(cdr(obj)) && !cddr(obj);
- if (sym == quote_s && consp(cdr(obj)) && !(cdr(cdr(obj)))) {
+ if (sym == quote_s && two_elem) {
put_char(chr('\''), out);
obj_print_impl(second(obj), out, pretty);
- } else if (sym == sys_qquote_s) {
+ } else if (sym == sys_qquote_s && two_elem) {
put_char(chr('^'), out);
obj_print_impl(second(obj), out, pretty);
- } else if (sym == sys_unquote_s) {
+ } else if (sym == sys_unquote_s && two_elem) {
put_char(chr(','), out);
obj_print_impl(second(obj), out, pretty);
- } else if (sym == sys_splice_s) {
+ } else if (sym == sys_splice_s && two_elem) {
put_string(lit(",*"), out);
obj_print_impl(second(obj), out, pretty);
- } else if (sym == vector_lit_s) {
+ } else if (sym == vector_lit_s && two_elem) {
put_string(lit("#"), out);
obj_print_impl(second(obj), out, pretty);
} else if (sym == hash_lit_s) {
put_string(lit("#H"), out);
obj_print_impl(rest(obj), out, pretty);
- } else if (sym == var_s && (symbolp(second(obj)) || integerp(second(obj)))
- && !cdr(cdr(obj)))
+ } else if (sym == var_s && two_elem &&
+ (symbolp(second(obj)) || integerp(second(obj))))
{
put_char(chr('@'), out);
obj_print_impl(second(obj), out, pretty);