summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--eval.c15
-rw-r--r--lib.h2
3 files changed, 22 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 71b672e1..1a9afc59 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2011-11-30 Kaz Kylheku <kaz@kylheku.com>
+ * eval.c (op_modplace): Bugfix: conflation of new value and
+ increment value. Separate new value and increment value, and check
+ number of arguments.
+
+ * lib.h (or2): Turned into inline function due to multiple
+ argument evaluation.
+
+2011-11-30 Kaz Kylheku <kaz@kylheku.com>
+
* txr.vim: New operators added.
2011-11-29 Kaz Kylheku <kaz@kylheku.com>
diff --git a/eval.c b/eval.c
index 5e1c7d13..c932c51b 100644
--- a/eval.c
+++ b/eval.c
@@ -509,7 +509,8 @@ static val op_modplace(val form, val env)
{
val op = first(form);
val place = second(form);
- val inc = or2(eval(third(form), env, form), num(1));
+ val third_arg_p = rest(rest(form));
+ val newval = if3(car(third_arg_p), eval(third(form), env, form), nil);
val *loc = 0;
val binding = nil;
@@ -547,14 +548,22 @@ static val op_modplace(val form, val env)
eval_error(form, lit("~a: place ~s doesn't exist"), op, place, nao);
if (op == set_s) {
- return *loc = inc;
+ if (!third_arg_p)
+ eval_error(form, lit("~a: missing argument"), op, place, nao);
+ return *loc = newval;
} else if (op == inc_s) {
+ val inc = or2(newval, num(1));
return *loc = plus(*loc, inc);
} else if (op == dec_s) {
+ val inc = or2(newval, num(1));
return *loc = plus(*loc, inc);
} else if (op == push_s) {
- return push(inc, loc);
+ if (!third_arg_p)
+ eval_error(form, lit("~a: missing argument"), op, place, nao);
+ return push(newval, loc);
} else if (op == pop_s) {
+ if (third_arg_p)
+ eval_error(form, lit("~a: superfluous argument"), op, place, nao);
return pop(loc);
}
diff --git a/lib.h b/lib.h
index aa3064f0..732c5eb8 100644
--- a/lib.h
+++ b/lib.h
@@ -506,7 +506,7 @@ INLINE val eq(val a, val b) { return ((a) == (b) ? t : nil); }
#define if3(a, b, c) ((a) ? (b) : (c))
-#define or2(a, b) ((a) ? (a) : (b))
+INLINE val or2(val a, val b) { return a ? a : b; }
#define or3(a, b, c) or2(a, or2(b, c))