diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-12-25 20:28:28 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-12-25 20:28:28 -0800 |
commit | 7e704a1c0d76cfef21fd27525023fe44102c83d3 (patch) | |
tree | 3516c77163144c118678df0a1ec666a5564ebafc | |
parent | a791cd6527f20c531898390e14f3c7c21c1d9571 (diff) | |
download | txr-7e704a1c0d76cfef21fd27525023fe44102c83d3.tar.gz txr-7e704a1c0d76cfef21fd27525023fe44102c83d3.tar.bz2 txr-7e704a1c0d76cfef21fd27525023fe44102c83d3.zip |
Bugfix: incorrect quasi-quoting over #R syntax.
The issue is that ^#R(,(+ 2 2) ,(+ 3 3)) produces 4..6 rather
than #R(4..6). 4..6 is, of course, the syntax (rcons 4 6)
which evaluates to a range. Here we want the range to which
it evaluates, not the syntax.
* eval.c (expand_qquote_rec): Handle the case when the
qquoted_form is a range atom: expand the from and to parts,
and generate a rcons expression. Though this seems to be
opposite to the previous paragraph, it's the right thing.
* parser.y (range): Drop the unquotes_occurs case which
produces rcons syntax. Produce a range object, always.
This is the source of the problem: a (rcons ...) expression
was produced here which was just traversed by the qquote
expander as list. It's the expander that must produce
the rcons expression.
-rw-r--r-- | eval.c | 6 | ||||
-rw-r--r-- | parser.y | 4 |
2 files changed, 5 insertions, 5 deletions
@@ -2900,7 +2900,11 @@ static val expand_qquote_rec(val qquoted_form, val qq, val unq, val spl) { if (nilp(qquoted_form)) { return nil; - } if (atom(qquoted_form)) { + } else if (rangep(qquoted_form)) { + val frexp = expand_qquote(from(qquoted_form), qq, unq, spl); + val toexp = expand_qquote(to(qquoted_form), qq, unq, spl); + return rlcp(list(rcons_s, frexp, toexp, nao), qquoted_form); + } else if (atom(qquoted_form)) { return cons(quote_s, cons(qquoted_form, nil)); } else { val sym = car(qquoted_form); @@ -848,10 +848,6 @@ struct : HASH_S list { if (unquotes_occur($2, 0)) range : HASH_R list { if (length($2) != two) yyerr("range literal needs two elements"); - - if (unquotes_occur($2, 0)) - $$ = rl(cons(rcons_s, $2), num($1)); - else { val range = rcons(first($2), second($2)); $$ = rl(range, num($1)); } } ; |