summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-11-30 07:17:57 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-11-30 07:17:57 -0800
commit7ef6686ce7020df5618cd5c9ed737c4655f08ef4 (patch)
treec8794a24e9e0a64f9e8bdf09c0cea3c48ccc60ff /eval.c
parent4acf4217af8e9c830f89e8586e5ec62e97cb85b0 (diff)
downloadtxr-7ef6686ce7020df5618cd5c9ed737c4655f08ef4.tar.gz
txr-7ef6686ce7020df5618cd5c9ed737c4655f08ef4.tar.bz2
txr-7ef6686ce7020df5618cd5c9ed737c4655f08ef4.zip
Refactor propagation of contexts in evaluator.
The context form arguments become just context objects in various places. When a context form is actually needed, or the context's symbolic name, they must be retrieved via functions applied to a context. * debug.c (debug): form argument is now a context. Use the ctx_form function to retrieve the form. * debug.h (debug_check): Rename form parameter to ctx. * eval.c (ctx_form, ctx_name): New functions. (eval_error): Leftmost parameter is a context now. Use ctx_form API to obtain the context form from this object, from which the source location info can then be retrieved as before. (abbrev_ctx): Function removed. (bind_args, bindings_helper, fbindings_helper): Convert ctx_form argument to ctx, and use the API to access name or form. (do_eval, do_eval_args, eval, eval_args_lisp1, eval_lisp1, eval_progn, eval_prog1): ctx_form param renamed to ctx. (funcall_interp): Pass the original interpreted function as the context to bind_args, not the extracted code. When ctx_name sees this object, it will compute the function name, which was not possible from the code being used as the context. This is the big reason for all these changes. * eval.h (eval_error): Declaration updated. (ctx_form, ctx_name): Declared.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c132
1 files changed, 74 insertions, 58 deletions
diff --git a/eval.c b/eval.c
index a3a8b2ea..99f0ac0f 100644
--- a/eval.c
+++ b/eval.c
@@ -171,10 +171,34 @@ static void env_vb_to_fb(val env)
}
}
-noreturn val eval_error(val form, val fmt, ...)
+val ctx_form(val obj)
+{
+ if (consp(obj))
+ return obj;
+ if (interp_fun_p(obj))
+ return obj->f.f.interp_fun;
+ return nil;
+}
+
+val ctx_name(val obj)
+{
+ if (consp(obj)) {
+ if (car(obj) == lambda_s)
+ return list(lambda_s, second(obj), nao);
+ else
+ return car(obj);
+ }
+
+ if (interp_fun_p(obj))
+ return func_get_name(obj, obj->f.env);
+ return nil;
+}
+
+noreturn val eval_error(val ctx, val fmt, ...)
{
uses_or2;
va_list vl;
+ val form = ctx_form(ctx);
val stream = make_string_output_stream();
val loc = or2(source_loc_str(form, nil),
source_loc_str(last_form_evaled, nil));
@@ -511,20 +535,13 @@ static val env_vbind_special(val env, val sym, val obj,
}
}
-static val abbrev_ctx(val ctx_form)
-{
- if (car(ctx_form) == lambda_s)
- return format(nil, lit(" for ~!~s"), ctx_form, nao);
- return lit("");
-}
-
static void copy_env_handler(mem_t *ptr, int parent)
{
val *penv = coerce(val *, ptr);
*penv = copy_env(*penv);
}
-static val bind_args(val env, val params, struct args *args, val ctx_form)
+static val bind_args(val env, val params, struct args *args, val ctx)
{
val new_env = make_env(nil, nil, env);
val optargs = nil;
@@ -557,20 +574,20 @@ static val bind_args(val env, val params, struct args *args, val ctx_form)
special_list = param;
continue;
} else {
- eval_error(ctx_form, lit("~s: bad object ~s in param list"),
- car(ctx_form), sym, nao);
+ eval_error(ctx, lit("~s: bad object ~s in param list"),
+ ctx_name(ctx), sym, nao);
}
}
if (!bindable(param))
- eval_error(ctx_form, lit("~s: ~s is not a bindable symbol"),
- car(ctx_form), param, nao);
+ eval_error(ctx, lit("~s: ~s is not a bindable symbol"),
+ ctx_name(ctx), param, nao);
if (presentsym && !bindable(presentsym))
- eval_error(ctx_form, lit("~s: ~s is not a bindable symbol"),
- car(ctx_form), presentsym, nao);
+ eval_error(ctx, lit("~s: ~s is not a bindable symbol"),
+ ctx_name(ctx), presentsym, nao);
- arg = args_get_checked(ctx_form, args, &index);
+ arg = args_get(args, &index);
if (optargs) {
val initval = nil;
@@ -578,7 +595,7 @@ static val bind_args(val env, val params, struct args *args, val ctx_form)
if (arg == colon_k) {
if (initform) {
- initval = eval(initform, new_env, ctx_form);
+ initval = eval(initform, new_env, ctx);
new_env = make_env(nil, nil, new_env);
}
} else {
@@ -604,8 +621,7 @@ static val bind_args(val env, val params, struct args *args, val ctx_form)
params = cdr(params);
}
if (!optargs)
- eval_error(ctx_form, lit("~s: too few arguments~!~a"),
- car(ctx_form), abbrev_ctx(ctx_form), nao);
+ eval_error(ctx, lit("~s: too few arguments"), ctx_name(ctx), nao);
while (consp(params)) {
val param = car(params);
if (param == colon_k)
@@ -614,17 +630,17 @@ static val bind_args(val env, val params, struct args *args, val ctx_form)
val sym = pop(&param);
val initform = pop(&param);
val presentsym = pop(&param);
- val initval = eval(initform, new_env, ctx_form);
+ val initval = eval(initform, new_env, ctx);
if (!bindable(sym))
- eval_error(ctx_form, lit("~s: ~s is not a bindable symbol"),
- car(ctx_form), sym, nao);
+ eval_error(ctx, lit("~s: ~s is not a bindable symbol"),
+ ctx_name(ctx), sym, nao);
new_env = make_env(nil, nil, new_env);
env_vbind_special(new_env, sym, initval, special_list);
if (presentsym) {
if (!bindable(presentsym))
- eval_error(ctx_form, lit("~s: ~s is not a bindable symbol"),
- car(ctx_form), presentsym, nao);
+ eval_error(ctx, lit("~s: ~s is not a bindable symbol"),
+ ctx_name(ctx), presentsym, nao);
env_vbind_special(new_env, presentsym, nil, special_list);
}
} else {
@@ -635,11 +651,11 @@ static val bind_args(val env, val params, struct args *args, val ctx_form)
if (bindable(params))
env_vbind_special(new_env, params, nil, special_list);
} else if (params) {
- eval_error(ctx_form, lit("~s: ~s is not a bindable symbol"),
- car(ctx_form), params, nao);
+ eval_error(ctx, lit("~s: ~s is not a bindable symbol"),
+ ctx_name(ctx), params, nao);
} else if (args_more(args, index)) {
- eval_error(ctx_form, lit("~s: too many arguments~!~a"),
- car(ctx_form), abbrev_ctx(ctx_form), nao);
+ eval_error(ctx, lit("~s: too many arguments"),
+ ctx_name(ctx), nao);
}
@@ -647,8 +663,8 @@ static val bind_args(val env, val params, struct args *args, val ctx_form)
return new_env;
twocol:
- eval_error(ctx_form, lit("~s: multiple colons in parameter list"),
- car(ctx_form), nao);
+ eval_error(ctx, lit("~s: multiple colons in parameter list"),
+ ctx_name(ctx), nao);
}
static val expand_opt_params_rec(val params, val menv, val *pspecials)
@@ -1000,18 +1016,18 @@ twocol:
car(ctx_form), nao);
}
-static val do_eval(val form, val env, val ctx_form,
+static val do_eval(val form, val env, val ctx,
val (*lookup)(val env, val sym));
-static void do_eval_args(val form, val env, val ctx_form,
+static void do_eval_args(val form, val env, val ctx,
val (*lookup)(val env, val sym),
struct args *args)
{
for (; consp(form); form = cdr(form))
- args_add(args, do_eval(car(form), env, ctx_form, lookup));
+ args_add(args, do_eval(car(form), env, ctx, lookup));
if (form) {
- val dotpos = do_eval(form, env, ctx_form, lookup);
+ val dotpos = do_eval(form, env, ctx, lookup);
args_add_list(args, if3(listp(dotpos), dotpos, tolist(dotpos)));
}
}
@@ -1034,11 +1050,11 @@ val funcall_interp(val interp_fun, struct args *args)
if (!consp(firstparam) || car(firstparam) != special_s)
{
- val fun_env = bind_args(env, params, args, fun);
+ val fun_env = bind_args(env, params, args, interp_fun);
return eval_progn(body, fun_env, body);
} else {
val saved_de = set_dyn_env(make_env(nil, nil, dyn_env));
- val fun_env = bind_args(env, params, args, fun);
+ val fun_env = bind_args(env, params, args, interp_fun);
val ret = eval_progn(body, fun_env, body);
set_dyn_env(saved_de);
return ret;
@@ -1057,12 +1073,12 @@ val eval_intrinsic(val form, val env)
return ret;
}
-static val do_eval(val form, val env, val ctx_form,
+static val do_eval(val form, val env, val ctx,
val (*lookup)(val env, val sym))
{
debug_enter;
- debug_check(consp(form) ? form : ctx_form, env, nil, nil, nil, nil);
+ debug_check(consp(form) ? form : ctx, env, nil, nil, nil, nil);
sig_check_fast();
if (nilp(form)) {
@@ -1074,7 +1090,7 @@ static val do_eval(val form, val env, val ctx_form,
val binding = lookup(env, form);
if (binding)
debug_return (cdr(binding));
- eval_error(ctx_form, lit("unbound variable ~s"), form, nao);
+ eval_error(ctx, lit("unbound variable ~s"), form, nao);
abort();
}
} else if (consp(form)) {
@@ -1121,19 +1137,19 @@ static val do_eval(val form, val env, val ctx_form,
debug_leave;
}
-val eval(val form, val env, val ctx_form)
+val eval(val form, val env, val ctx)
{
- return do_eval(form, env, ctx_form, &lookup_var);
+ return do_eval(form, env, ctx, &lookup_var);
}
-static void eval_args_lisp1(val form, val env, val ctx_form, struct args *args)
+static void eval_args_lisp1(val form, val env, val ctx, struct args *args)
{
- do_eval_args(form, env, ctx_form, &lookup_sym_lisp1, args);
+ do_eval_args(form, env, ctx, &lookup_sym_lisp1, args);
}
-static val eval_lisp1(val form, val env, val ctx_form)
+static val eval_lisp1(val form, val env, val ctx)
{
- return do_eval(form, env, ctx_form, &lookup_sym_lisp1);
+ return do_eval(form, env, ctx, &lookup_sym_lisp1);
}
val bindable(val obj)
@@ -1141,7 +1157,7 @@ val bindable(val obj)
return (obj && symbolp(obj) && obj != t && !keywordp(obj)) ? t : nil;
}
-val eval_progn(val forms, val env, val ctx_form)
+val eval_progn(val forms, val env, val ctx)
{
val retval = nil;
@@ -1151,22 +1167,22 @@ val eval_progn(val forms, val env, val ctx_form)
}
for (; forms; forms = cdr(forms))
- retval = eval(car(forms), env, ctx_form);
+ retval = eval(car(forms), env, ctx);
return retval;
}
-static val eval_prog1(val forms, val env, val ctx_form)
+static val eval_prog1(val forms, val env, val ctx)
{
val retval = nil;
if (forms) {
- retval = eval(car(forms), env, ctx_form);
+ retval = eval(car(forms), env, ctx);
forms = cdr(forms);
}
for (; forms; forms = cdr(forms))
- eval(car(forms), env, ctx_form);
+ eval(car(forms), env, ctx);
return retval;
}
@@ -1218,7 +1234,7 @@ static void copy_bh_env_handler(mem_t *ptr, int parent)
static val bindings_helper(val vars, val env, val sequential,
val *env_out, val ret_new_bindings,
- val ctx_form)
+ val ctx)
{
val iter;
struct bindings_helper_vars v;
@@ -1235,7 +1251,7 @@ static val bindings_helper(val vars, val env, val sequential,
if (consp(item)) {
var = pop(&item);
- value = eval(pop(&item), if3(sequential, v.ne, env), ctx_form);
+ value = eval(pop(&item), if3(sequential, v.ne, env), ctx);
} else {
var = item;
}
@@ -1254,8 +1270,8 @@ static val bindings_helper(val vars, val env, val sequential,
ptail = list_collect (ptail, binding);
v.ne = le;
} else {
- eval_error(ctx_form, lit("~s: ~s is not a bindable symbol"),
- car(ctx_form), var, nao);
+ eval_error(ctx, lit("~s: ~s is not a bindable symbol"),
+ ctx_name(ctx), var, nao);
}
}
@@ -1268,7 +1284,7 @@ static val bindings_helper(val vars, val env, val sequential,
return new_bindings;
}
-static val fbindings_helper(val vars, val env, val lbind, val ctx_form)
+static val fbindings_helper(val vars, val env, val lbind, val ctx)
{
val iter;
val nenv = make_env(nil, nil, env);
@@ -1277,13 +1293,13 @@ static val fbindings_helper(val vars, val env, val lbind, val ctx_form)
for (iter = vars; iter; iter = cdr(iter)) {
val item = car(iter);
val var = pop(&item);
- val value = eval(pop(&item), lenv, ctx_form);
+ val value = eval(pop(&item), lenv, ctx);
if (bindable(var)) {
(void) env_fbind(nenv, var, value);
} else {
- eval_error(ctx_form, lit("~s: ~s is not a bindable symbol"),
- car(ctx_form), var, nao);
+ eval_error(ctx, lit("~s: ~s is not a bindable symbol"),
+ ctx_name(ctx), var, nao);
}
}