diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-02-01 14:15:04 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-02-01 14:15:04 -0800 |
commit | df3337250fdff73a0d6076d4ada1719aaecdaafd (patch) | |
tree | 0de3819b927aff20f83a06a06540c4ed386f771b /eval.c | |
parent | da46f6b1d25d2e0a44fb73905dcc8bdc5c35f54a (diff) | |
download | txr-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.c | 68 |
1 files changed, 59 insertions, 9 deletions
@@ -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; |