summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--RELNOTES5
-rw-r--r--parser.y38
-rw-r--r--txr.146
4 files changed, 51 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index c35467ff..768eff4f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2011-12-04 Kaz Kylheku <kaz@kylheku.com>
+ * parser.y (force_regular_quotes): Function removed.
+ (list): Prior commit reversed.
+
+ * txr.1: Prior commit reversed.
+
+ * RELNOTES: No semantics clarification in quasiquote; bugfixes only.
+
+2011-12-04 Kaz Kylheku <kaz@kylheku.com>
+
* eval.c (op_qquote_error, op_unquote_error): New static functions.
(expand_qquote): Bugfix: missing case added to handle directly quoted
quasiquote.
diff --git a/RELNOTES b/RELNOTES
index 295a6891..7cbb57af 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -6,12 +6,13 @@
- New functions exposed in Lisp interpreter: strings, characters,
symbols and lazy lists.
- - Quasiquote semantics clarified.
-
Bugs
- Flaws in some string-splitting functions identified and fixed.
+ - Bugs in quasiquote.
+
+
TXR 044
diff --git a/parser.y b/parser.y
index e4f954ce..82fd9101 100644
--- a/parser.y
+++ b/parser.y
@@ -50,7 +50,6 @@ static val define_transform(val define_form);
static val lit_char_helper(val litchars);
static val optimize_text(val text_form);
static val choose_quote(val quoted_form);
-static val force_regular_quotes(val form);
static wchar_t char_from_name(wchar_t *name);
static val parsed_spec;
@@ -608,14 +607,16 @@ var_op : '*' { $$ = list(t, nao); }
list : '(' exprs ')' { $$ = rl($2, num($1)); }
| '(' ')' { $$ = nil; }
- | ',' expr { $$ = rlcp(list(unquote_s,
- force_regular_quotes($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,
- force_regular_quotes($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")); }
;
@@ -911,29 +912,6 @@ static val choose_quote(val quoted_form)
return unquotes_occur(quoted_form) ? qquote_s : quote_s;
}
-static val force_regular_quotes(val form)
-{
- if (atom(form)) {
- return form;
- } else {
- val sym = car(form);
- val body = cdr(form);
-
- if (sym == qquote_s) {
- return rlcp(cons(quote_s, force_regular_quotes(body)), form);
- } if (sym == unquote_s || sym == splice_s) {
- return form;
- } else {
- val car_sub = force_regular_quotes(sym);
- val cdr_sub = force_regular_quotes(body);
-
- if (car_sub == sym && cdr_sub == body)
- return form;
- return rlcp(cons(car_sub, cdr_sub), form);
- }
- }
-}
-
val rl(val form, val lineno)
{
sethash(form_to_ln_hash, form, lineno);
diff --git a/txr.1 b/txr.1
index 7a21a2b3..0ad576c7 100644
--- a/txr.1
+++ b/txr.1
@@ -4223,16 +4223,11 @@ value of 'a is the symbol a itself, whereas the value of a is the value
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. The quote behaves
-either like a quasiquote or a regular quote according to these rules:
+There is only one quote, which supports unquoting.
-1. A quoted form which contains no unquotes or splices is an ordinary quote.
+A quoted form which contains no unquotes codifies an ordinary quote.
-2. Quotes occuring within forms that are unquoted or spliced are ordinary
-quotes, not quasiquotes.
-
-3. Quotes which contain unquotes and splices and are not within unquotes
-or splices are quasiquotes.
+A quoted form which contains unquotes expresses a quasiquote.
.IP ,form
@@ -4244,13 +4239,34 @@ in the quote stands for itself, except for the ,(+ 2 2) which is evaluated.
.IP ,*form
-The comma-star operator is used within a quoted list to denote a splicing
-unquote. Wheras the quote suppresses evaluation, the comma introduces an
-exception: 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
+The comma-star operator is used within a quoted list to denote a splicing unquote.
+Wheras the quote suppresses evaluation, the comma introduces an exception:
+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
@@ -4263,8 +4279,8 @@ quote, which protects it from evaluation. To get the (+ 1 2) value "through"
to the inner quote, the unquote syntax must also be nested using multiple
commas, like this: '(1 2 3 '(4 5 6 ,',(+ 1 2))). The leftmost comma goes
with the innermost quote. The quote between the commas protects the (+ 1 2)
-from repeated evaluations. According to rule 2 above, it is a regular
-quote, and so it does not capture the following comma.
+from repeated evaluations: the two unquotes call for two evaluations, but
+we only want (+ 1 2) to be evaluated once.
.SS Lisp Operators