diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-12-06 04:58:48 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-12-06 04:58:48 -0800 |
commit | 279aaa062fafff012b4fdb20e104b6e3fb6aac3e (patch) | |
tree | a5dceac3c3e4576d3d171fa9e0803ee7131f920a | |
parent | 3545fe416495c3244e0b9bda69ab0cf733db0fcd (diff) | |
download | txr-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.c | 20 | ||||
-rw-r--r-- | txr.1 | 23 |
2 files changed, 38 insertions, 5 deletions
@@ -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; } @@ -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 |