summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-12-25 20:28:28 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-12-25 20:28:28 -0800
commit7e704a1c0d76cfef21fd27525023fe44102c83d3 (patch)
tree3516c77163144c118678df0a1ec666a5564ebafc
parenta791cd6527f20c531898390e14f3c7c21c1d9571 (diff)
downloadtxr-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.c6
-rw-r--r--parser.y4
2 files changed, 5 insertions, 5 deletions
diff --git a/eval.c b/eval.c
index 8a4c7366..dbb7a21f 100644
--- a/eval.c
+++ b/eval.c
@@ -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);
diff --git a/parser.y b/parser.y
index 3391c5f3..70f22d91 100644
--- a/parser.y
+++ b/parser.y
@@ -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)); } }
;