summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-05-03 20:21:18 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-05-03 20:21:18 -0700
commit6eadc61ddd50207b582a1bcf2b4a9def30104b7a (patch)
treeef7f69dd4775c003b1ae23c48fd39d04df0c463c /eval.c
parent2447f9162f13a41763a3a88ef3275a9e455f1bb5 (diff)
downloadtxr-6eadc61ddd50207b582a1bcf2b4a9def30104b7a.tar.gz
txr-6eadc61ddd50207b582a1bcf2b4a9def30104b7a.tar.bz2
txr-6eadc61ddd50207b582a1bcf2b4a9def30104b7a.zip
bind_args refactoring.
* eval.c (lex_or_dyn_bind_seq, lex_or_dyn_bind): New static functions. (bind_args): Eliminate repeated code using new helper functions. One wrong repetitions is thereby fixed also: a a neglected check of dyn_env_made.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c122
1 files changed, 45 insertions, 77 deletions
diff --git a/eval.c b/eval.c
index b032bc57..45c5ced2 100644
--- a/eval.c
+++ b/eval.c
@@ -753,6 +753,35 @@ static val squash_menv_deleting_range(val menv, val upto_menv)
return out_env;
}
+INLINE val lex_or_dyn_bind_seq(val *dyn_made, val lex_env, val sym, val obj)
+{
+ if (special_var_p(sym)) {
+ if (!*dyn_made) {
+ dyn_env = make_env(nil, nil, dyn_env);
+ *dyn_made = t;
+ }
+ env_vbind(dyn_env, sym, obj);
+ } else {
+ lex_env = make_env(nil, nil, lex_env);
+ env_vbind(lex_env, sym, obj);
+ }
+
+ return lex_env;
+}
+
+INLINE void lex_or_dyn_bind(val *dyn_made, val lex_env, val sym, val obj)
+{
+ if (special_var_p(sym)) {
+ if (!*dyn_made) {
+ dyn_env = make_env(nil, nil, dyn_env);
+ *dyn_made = t;
+ }
+ env_vbind(dyn_env, sym, obj);
+ } else {
+ env_vbind(lex_env, sym, obj);
+ }
+}
+
static val bind_args(val env, val params, struct args *args, val ctx)
{
val new_env = make_env(nil, nil, env);
@@ -768,7 +797,6 @@ static val bind_args(val env, val params, struct args *args, val ctx)
val arg;
val initform = nil;
val presentsym = nil;
- val special_p = nil;
if (param == colon_k) {
optargs = t;
@@ -787,13 +815,6 @@ static val bind_args(val env, val params, struct args *args, val ctx)
}
}
- if ((special_p = special_var_p(param))) {
- if (!dyn_env_made) {
- dyn_env = make_env(nil, nil, dyn_env);
- dyn_env_made = t;
- }
- }
-
arg = args_get(args, &index);
if (optargs) {
@@ -803,30 +824,18 @@ static val bind_args(val env, val params, struct args *args, val ctx)
if (arg == colon_k) {
if (initform) {
initval = eval(initform, new_env, ctx);
- if (!special_p)
- new_env = make_env(nil, nil, new_env);
+ new_env = lex_or_dyn_bind_seq(&dyn_env_made, new_env,
+ param, initval);
}
} else {
- initval = arg;
+ lex_or_dyn_bind(&dyn_env_made, new_env, param, arg);
present = t;
}
- if (special_p) {
- env_vbind(dyn_env, param, initval);
- } else {
- env_vbind(new_env, param, initval);
- }
- if (presentsym) {
- if (special_var_p(presentsym)) {
- env_vbind(dyn_env, presentsym, present);
- } else {
- env_vbind(new_env, presentsym, present);
- }
- }
+
+ if (presentsym)
+ lex_or_dyn_bind(&dyn_env_made, new_env, presentsym, present);
} else {
- if (special_p)
- env_vbind(dyn_env, param, arg);
- else
- env_vbind(new_env, param, arg);
+ lex_or_dyn_bind(&dyn_env_made, new_env, param, arg);
}
}
@@ -845,62 +854,21 @@ static val bind_args(val env, val params, struct args *args, val ctx)
val presentsym = pop(&param);
val initval = eval(initform, new_env, ctx);
- if (special_var_p(sym)) {
- if (!dyn_env_made) {
- dyn_env = make_env(nil, nil, dyn_env);
- dyn_env_made = t;
- }
- env_vbind(dyn_env, sym, initval);
- } else {
- new_env = make_env(nil, nil, new_env);
- env_vbind(new_env, sym, initval);
- }
+ new_env = lex_or_dyn_bind_seq(&dyn_env_made, new_env,
+ sym, initval);
- if (presentsym) {
- if (special_var_p(presentsym)) {
- if (!dyn_env_made) {
- dyn_env = make_env(nil, nil, dyn_env);
- dyn_env_made = t;
- }
- env_vbind(dyn_env, presentsym, nil);
- } else {
- env_vbind(new_env, presentsym, nil);
- }
- }
+ if (presentsym)
+ lex_or_dyn_bind(&dyn_env_made, new_env, presentsym, nil);
} else {
- if (special_var_p(param)) {
- if (!dyn_env_made) {
- dyn_env = make_env(nil, nil, dyn_env);
- dyn_env_made = t;
- }
- env_vbind(dyn_env, param, nil);
- } else {
- env_vbind(new_env, param, nil);
- }
+ lex_or_dyn_bind(&dyn_env_made, new_env, param, nil);
}
params = cdr(params);
}
- if (bindable(params)) {
- if (special_var_p(params)) {
- if (!dyn_env_made) {
- dyn_env = make_env(nil, nil, dyn_env);
- dyn_env_made = t;
- }
- env_vbind(dyn_env, params, nil);
- } else {
- env_vbind(new_env, params, nil);
- }
- }
+ if (bindable(params))
+ lex_or_dyn_bind(&dyn_env_made, new_env, params, nil);
} else if (params) {
- if (special_var_p(params)) {
- if (!dyn_env_made) {
- dyn_env = make_env(nil, nil, dyn_env);
- dyn_env_made = t;
- }
- env_vbind(dyn_env, params, args_get_rest(args, index));
- } else {
- env_vbind(new_env, params, args_get_rest(args, index));
- }
+ lex_or_dyn_bind(&dyn_env_made, new_env, params,
+ args_get_rest(args, index));
} else if (args_more(args, index)) {
eval_error(ctx, lit("~s: too many arguments"),
ctx_name(ctx), nao);