diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | parser.y | 10 | ||||
-rw-r--r-- | txr.1 | 26 |
3 files changed, 45 insertions, 2 deletions
@@ -1,5 +1,16 @@ 2011-12-02 Kaz Kylheku <kaz@kylheku.com> + * parser.y (list): unquote and splice actions look inside the + argument form. If an unquote or splice are applied to a quoted + form, its quote becomes a regular quote. + This behavior is necessary to make ,',form work in nested + quotes, otherwise the ' is a quasiquote which captures + the comma in ,form, reducing ,',form to ,form. + + * txr.1: Documented this special behavior. + +2011-12-02 Kaz Kylheku <kaz@kylheku.com> + * eval.c (expand_qquote): Bugfix: removed bogus recognition and processing of regular quote form. This broke nested backquote processing, and quasiquote forms containing @@ -607,10 +607,16 @@ var_op : '*' { $$ = list(t, nao); } list : '(' exprs ')' { $$ = rl($2, num($1)); } | '(' ')' { $$ = nil; } - | ',' expr { $$ = rlcp(list(unquote_s, $2, nao), $2); } + | ',' expr { val expr = $2; + if (consp(expr) && first(expr) == qquote_s) + expr = cons(quote_s, rest(expr)); + $$ = rlcp(list(unquote_s, expr, nao), $2); } | '\'' expr { $$ = rlcp(list(choose_quote($2), $2, nao), $2); } - | SPLICE expr { $$ = rlcp(list(splice_s, $2, nao), $2); } + | SPLICE expr { val expr = $2; + if (consp(expr) && first(expr) == qquote_s) + expr = cons(quote_s, rest(expr)); + $$ = rlcp(list(splice_s, expr, nao), $2); } | '(' error { $$ = nil; yybadtoken(yychar, lit("list expression")); } ; @@ -4225,6 +4225,10 @@ of the variable a. Note that TXR Lisp does not have a distinct quote and backquote syntax. There is only one quote, which supports unquoting. +A quoted form which contains no unquotes codifies an ordinary quote. + +A quoted form which contains unquotes expresses a quasiquote. + .IP ,form Thes comma character is used within a quoted list to denote an unquote. Wheras @@ -4241,6 +4245,28 @@ the form which follows ,* must evaluate to a list. That list is spliced into the quoted list. For example: '(a b c ,*(list (+ 3 3) (+ 4 4) d) evaluates to (a b c 6 8 d). The expression (list (+ 3 3) (+ 4 4)) is evaluated to produce the list (6 8), and this list is spliced into the quoted template. + +.IP ,'form + +The comma-quote combination has a special meaning: the quote always +behaves as a regular quote and not a quasiquote, even if form contains +unquotes. Therefore, it does not "capture" these unquotes: they cannot +"belong" to this quote. The comma and quote "cancel out", so the only effect +of comma-quote is to add one level of unquoting. So for instance, whereas in +'(a b c '(,d)), the subsitution of d belongs to the inner quote (it is unquoted +by the leftmost comma which belongs to the innermost quote) by contrast, +in '(a b c '(,',d)) the d is now one comma removed from the leftmost comma and +thus the substitution of d belongs to the outer quote. +In other dialects of Lisp, this would be written `(a b c `(,',d)), making it +explicit which kind of quote is being specified. TXR Lisp works out which +kind of quote to use internally. + +.IP ,*'form + +The comma-splice form is analogous to comma-quote (see above). Like in the +,' combination, in the ,*' combination, the quote behaves as a regular quote +and not a quasiquote. + .PP .SS Nested Quotes |