summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-02-01 14:15:04 -0800
committerKaz Kylheku <kaz@kylheku.com>2012-02-01 14:15:04 -0800
commitdf3337250fdff73a0d6076d4ada1719aaecdaafd (patch)
tree0de3819b927aff20f83a06a06540c4ed386f771b /eval.c
parentda46f6b1d25d2e0a44fb73905dcc8bdc5c35f54a (diff)
downloadtxr-df3337250fdff73a0d6076d4ada1719aaecdaafd.tar.gz
txr-df3337250fdff73a0d6076d4ada1719aaecdaafd.tar.bz2
txr-df3337250fdff73a0d6076d4ada1719aaecdaafd.zip
* eval.c (lookup_sym_lisp1): New function.
(do_eval, do_eval_args): New static functions. (eval, eval_args): Become wrappers for do_eval and do_eval_args, respectively. (eval_lisp1, eval_args_lisp1): New static functions. (dwim_loc, op_dwim): Use eval_lisp1 and eval_args_lisp1 instead of eval and eval_args. * parser.y (meta_expr): Bugfix: expand the whole dwim expression, rather than its arguments, which are not an expression. * txr.1: Updated with notes that dwim really does Lisp-1 style evaluation.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c68
1 files changed, 59 insertions, 9 deletions
diff --git a/eval.c b/eval.c
index 595a3fc8..62832db3 100644
--- a/eval.c
+++ b/eval.c
@@ -171,6 +171,31 @@ val lookup_fun(val env, val sym)
}
}
+static val lookup_sym_lisp1(val env, val sym)
+{
+ uses_or2;
+
+ if (nullp(env)) {
+ val bind = gethash(top_vb, sym);
+ if (cobjp(bind)) {
+ struct c_var *cv = (struct c_var *) cptr_get(bind);
+ cv->bind->c.cdr = *cv->loc;
+ return cv->bind;
+ }
+ return or2(bind, gethash(top_fb, sym));
+ } else {
+ type_check(env, ENV);
+
+ {
+ val binding = or2(assoc(sym, env->e.vbindings),
+ assoc(sym, env->e.fbindings));
+ if (binding)
+ return binding;
+ return lookup_sym_lisp1(env->e.up_env, sym);
+ }
+ }
+}
+
static val bind_args(val env, val params, val args, val ctx_form)
{
val new_bindings = nil;
@@ -300,11 +325,15 @@ static val apply_intrinsic(val fun, val args)
return apply(fun, args, cons(apply_s, nil));
}
-static val eval_args(val form, val env, val ctx_form)
+static val do_eval(val form, val env, val ctx_form,
+ val (*lookup)(val env, val sym));
+
+static val do_eval_args(val form, val env, val ctx_form,
+ val (*lookup)(val env, val sym))
{
list_collect_decl (values, ptail);
for (; form; form = cdr(form))
- list_collect(ptail, eval(car(form), env, ctx_form));
+ list_collect(ptail, do_eval(car(form), env, ctx_form, lookup));
return values;
}
@@ -324,7 +353,8 @@ static val eval_intrinsic(val form, val env)
return eval(form, or2(env, make_env(nil, nil, env)), form);
}
-val eval(val form, val env, val ctx_form)
+static val do_eval(val form, val env, val ctx_form,
+ val (*lookup)(val env, val sym))
{
debug_enter;
@@ -337,7 +367,7 @@ val eval(val form, val env, val ctx_form)
if (!bindable(form)) {
debug_return (form);
} else {
- val binding = lookup_var(env, form);
+ val binding = lookup(env, form);
if (binding)
debug_return (cdr(binding));
eval_error(ctx_form, lit("unbound variable ~s"), form, nao);
@@ -353,7 +383,7 @@ val eval(val form, val env, val ctx_form)
val fbinding = lookup_fun(env, oper);
if (fbinding) {
- val args = eval_args(rest(form), env, form);
+ val args = do_eval_args(rest(form), env, form, lookup);
debug_frame(oper, args, nil, env, nil, nil, nil);
debug_return (apply(cdr(fbinding), args, form));
debug_end;
@@ -376,6 +406,26 @@ val eval(val form, val env, val ctx_form)
debug_leave;
}
+val eval(val form, val env, val ctx_form)
+{
+ return do_eval(form, env, ctx_form, &lookup_var);
+}
+
+static val eval_lisp1(val form, val env, val ctx_form)
+{
+ return do_eval(form, env, ctx_form, &lookup_sym_lisp1);
+}
+
+static val eval_args(val form, val env, val ctx_form)
+{
+ return do_eval_args(form, env, ctx_form, &lookup_var);
+}
+
+static val eval_args_lisp1(val form, val env, val ctx_form)
+{
+ return do_eval_args(form, env, ctx_form, &lookup_sym_lisp1);
+}
+
val bindable(val obj)
{
return (obj && symbolp(obj) && obj != t && !keywordp(obj)) ? t : nil;
@@ -639,8 +689,8 @@ static val op_defun(val form, val env)
static val *dwim_loc(val form, val env, val op, val newval, val *retval)
{
- val obj = eval(second(form), env, form);
- val args = eval_args(rest(rest(form)), env, form);
+ 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);
@@ -936,8 +986,8 @@ static val op_return_from(val form, val env)
static val op_dwim(val form, val env)
{
- val obj = eval(second(form), env, form);
- val args = eval_args(rest(rest(form)), env, form);
+ val obj = eval_lisp1(second(form), env, form);
+ val args = eval_args_lisp1(rest(rest(form)), env, form);
if (!obj)
return nil;