From 7e704a1c0d76cfef21fd27525023fe44102c83d3 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 25 Dec 2016 20:28:28 -0800 Subject: 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. --- eval.c | 6 +++++- parser.y | 4 ---- 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)); } } ; -- cgit v1.2.3