summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-01-30 16:54:07 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-01-30 16:54:07 -0800
commit78f186f057733ac5c7ac2b524a31960f77935958 (patch)
tree5a1515746d3100728a90e961651ad662f0164b9a
parent266f327291c92c3e26bfb2b9dccaa9136e7604b4 (diff)
downloadtxr-78f186f057733ac5c7ac2b524a31960f77935958.tar.gz
txr-78f186f057733ac5c7ac2b524a31960f77935958.tar.bz2
txr-78f186f057733ac5c7ac2b524a31960f77935958.zip
* eval.c (expand_op): When the variant is do, and the symbol
is an operator, then suppress the addition of the rest parameter in the dotted cons position at the end of the form, since this mechanism for applying additional arguments is only supported by function calls, not by special forms. * lib.h (and2, and3): New macros.
-rw-r--r--ChangeLog10
-rw-r--r--eval.c5
-rw-r--r--lib.h4
3 files changed, 17 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 414918aa..3191ffea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2014-01-30 Kaz Kylheku <kaz@kylheku.com>
+ * eval.c (expand_op): When the variant is do, and the symbol
+ is an operator, then suppress the addition of the rest
+ parameter in the dotted cons position at the end of the form,
+ since this mechanism for applying additional arguments is only
+ supported by function calls, not by special forms.
+
+ * lib.h (and2, and3): New macros.
+
+2014-01-30 Kaz Kylheku <kaz@kylheku.com>
+
* eval.c (expand_op): Fix broken do operator. In the case of the do
operator, we must feed the entire form to the expander, not the
individual forms. That is to say (do operator arg) must expand the
diff --git a/eval.c b/eval.c
index 1d8c5ce4..3d4ebbfd 100644
--- a/eval.c
+++ b/eval.c
@@ -1656,6 +1656,8 @@ static val expand_op(val sym, val body)
val max = if3(nums, maxv(car(nums), cdr(nums)), zero);
val min = if3(nums, minv(car(nums), cdr(nums)), zero);
val has_rest = cons_find(rest_gensym, body_trans, eq_f);
+ val is_op = and3(sym == do_s, consp(body_trans),
+ gethash(op_table, car(body_trans)));
if (!eql(max, length(nums)) && !zerop(min))
ssyms = supplement_op_syms(ssyms, max);
@@ -1665,8 +1667,7 @@ static val expand_op(val sym, val body)
{
uses_or2;
val dwim_body = rlcp(cons(dwim_s,
- if3(or3(has_rest,
- ssyms,
+ if3(or4(is_op, has_rest, ssyms,
nullp(proper_listp(body_trans))),
body_trans,
append2(body_trans, rest_gensym))),
diff --git a/lib.h b/lib.h
index 5c9b89ce..6a12cf36 100644
--- a/lib.h
+++ b/lib.h
@@ -726,6 +726,10 @@ INLINE val eq(val a, val b) { return ((a) == (b) ? t : nil); }
#define or4(a, b, c, d) or2(a, or3(b, c, d))
+#define and2(a, b) ((a) ? (b) : nil)
+
+#define and3(a, b, c) ((a) && (b) ? (c) : nil)
+
#define c_true(c_cond) ((c_cond) ? t : nil)
#define list_collect_decl(OUT, PTAIL) \