summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-02-13 17:37:20 -0800
committerKaz Kylheku <kaz@kylheku.com>2012-02-13 17:37:20 -0800
commit6f8875ff5beadd34a3ce94c40bfc1dc36b26a114 (patch)
treecd38ab2617c62a7801ac437728830d972a9bd219 /eval.c
parent35dbebb52a72343b9834092de3f6d1d9614d1f74 (diff)
downloadtxr-6f8875ff5beadd34a3ce94c40bfc1dc36b26a114.tar.gz
txr-6f8875ff5beadd34a3ce94c40bfc1dc36b26a114.tar.bz2
txr-6f8875ff5beadd34a3ce94c40bfc1dc36b26a114.zip
* eval.c (dwim_loc): Allow assignment to the dwim place when it
evaluates to nil, by building a form targetting the place, and recursing into op_modplace. Also, optimization: don't use eval on a form built from the operator; just go to op_modplace directly.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/eval.c b/eval.c
index 380b4623..b3f62189 100644
--- a/eval.c
+++ b/eval.c
@@ -689,13 +689,19 @@ static val op_defun(val form, val env)
return name;
}
+static val op_modplace(val form, val env);
+
static val *dwim_loc(val form, val env, val op, val newval, val *retval)
{
val obj = eval_lisp1(second(form), env, form);
val args = eval_args_lisp1(rest(rest(form)), env, form);
- if (!obj)
- eval_error(form, lit("[~s ]: cannot assign nil"), obj, nao);
+ if (!obj) {
+ val tempform = list(op, second(form),
+ cons(quote_s, cons(newval, nil)), nao);
+ *retval = op_modplace(tempform, env);
+ return 0;
+ }
switch (type(obj)) {
case LIT:
@@ -777,7 +783,7 @@ static val *dwim_loc(val form, val env, val op, val newval, val *retval)
newlist = replace_list(obj, car(index), cdr(index), newval);
tempform = list(op, second(form),
cons(quote_s, cons(newlist, nil)), nao);
- eval(tempform, env, form);
+ op_modplace(tempform, env);
*retval = newval;
return 0;
} else {