summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-12-06 04:58:48 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-12-06 04:58:48 -0800
commit279aaa062fafff012b4fdb20e104b6e3fb6aac3e (patch)
treea5dceac3c3e4576d3d171fa9e0803ee7131f920a
parent3545fe416495c3244e0b9bda69ab0cf733db0fcd (diff)
downloadtxr-279aaa062fafff012b4fdb20e104b6e3fb6aac3e.tar.gz
txr-279aaa062fafff012b4fdb20e104b6e3fb6aac3e.tar.bz2
txr-279aaa062fafff012b4fdb20e104b6e3fb6aac3e.zip
bugfix: , *sym printed as ,*sym.
We are lacking read/print consistency in the handling of unquotes applied to symbols whose names begin with a star. * lib.c (unquote_star_check): New static function. (obj_print_impl): Use unquote_star check when printing an unquote to determine whether a space is needed so that the result doesn't read back as a ,* splice. * txr.1: Change "should" to "must": the whitespace is absolutely required in , *x*. Adding more discussion as a dialect note.
-rw-r--r--lib.c20
-rw-r--r--txr.123
2 files changed, 38 insertions, 5 deletions
diff --git a/lib.c b/lib.c
index c443d9b6..dd599d22 100644
--- a/lib.c
+++ b/lib.c
@@ -9514,6 +9514,15 @@ INLINE int circle_print_eligible(val obj)
return is_ptr(obj) && (!symbolp(obj) || !symbol_package(obj));
}
+static int unquote_star_check(val obj, val pretty)
+{
+ if (!obj || !symbolp(obj))
+ return 0;
+ if (car(obj->s.name) != chr('*'))
+ return 0;
+ return pretty || symbol_present(cur_package, obj);
+}
+
val obj_print_impl(val obj, val out, val pretty, struct strm_ctx *ctx)
{
val ret = obj;
@@ -9556,7 +9565,10 @@ val obj_print_impl(val obj, val out, val pretty, struct strm_ctx *ctx)
put_char(chr('^'), out);
obj_print_impl(second(obj), out, pretty, ctx);
} else if (sym == sys_unquote_s && two_elem) {
+ val arg = second(obj);
put_char(chr(','), out);
+ if (unquote_star_check(arg, pretty))
+ put_char(chr(' '), out);
obj_print_impl(second(obj), out, pretty, ctx);
} else if (sym == sys_splice_s && two_elem) {
put_string(lit(",*"), out);
@@ -9660,10 +9672,14 @@ val obj_print_impl(val obj, val out, val pretty, struct strm_ctx *ctx)
unq = lit(". ,*");
if (unq) {
- d = cdr(iter);
+ val d = cdr(iter);
+ val ad = car(d);
+
if (consp(d) && !cdr(d)) {
put_string(unq, out);
- obj_print_impl(car(d), out, pretty, ctx);
+ if (a == sys_unquote_s && unquote_star_check(ad, pretty))
+ put_char(chr(' '), out);
+ obj_print_impl(ad, out, pretty, ctx);
put_char(closepar, out);
break;
}
diff --git a/txr.1 b/txr.1
index 255e90ec..0679a1b2 100644
--- a/txr.1
+++ b/txr.1
@@ -10357,7 +10357,7 @@ splice
the value of
.codn x* .
In this situation, whitespace between the comma and the
-variable name should be used:
+variable name must be used:
.codn ", *x*" .
.meIP >> ,* expr
@@ -10376,14 +10376,31 @@ is evaluated to produce the list
.codn "(6 8)" ,
and this list is spliced into the quoted template.
-Dialect note: in other Lisp dialects, the equivalent syntax is usually
+.TP* "Dialect Notes:"
+
+In other Lisp dialects, like Scheme and ANSI Common Lisp, the equivalent syntax
+is usually
.code ,@
(comma at). The
.code @
-character already has an assigned meaning, so
+character already has an assigned meaning in \*(TX, so
.code *
is used.
+However,
+.code *
+is also a character that may appear in a symbol name, which creates
+a potential for ambiguity. The syntax
+.code ,*abc
+denotes the application of the
+.code ,*
+splicing operator to the symbolic expression
+.codn abc ;
+to apply the ordinary non-splicing unquote to the symbol
+.codn *abc ,
+whitespace must be used:
+.codn ", *abc" .
+
.NP* Quasiquoting non-List Objects
Quasiquoting is supported over hash table and vector literals (see Vectors
and Hashes below). A hash table or vector literal can be quoted, like any