summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-10-15 19:56:39 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-10-15 19:56:39 -0700
commit6a5ea25622c3dbab61b35bab87506c83206ec5fd (patch)
treee1542341ee87c35487c1d79baca3e2bce02a1093 /eval.c
parente6f9e99876d2d8d4cda79dc4a0d8dd3bbb0953e1 (diff)
downloadtxr-6a5ea25622c3dbab61b35bab87506c83206ec5fd.tar.gz
txr-6a5ea25622c3dbab61b35bab87506c83206ec5fd.tar.bz2
txr-6a5ea25622c3dbab61b35bab87506c83206ec5fd.zip
Support nil env in env-fbind and env-vbind.
* eval.c (env_fbind, env_vbind): Allow env to be nil, indicating that the binding is to take place in the global environment. * txr.1: Documented.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/eval.c b/eval.c
index ed87549b..82afee1c 100644
--- a/eval.c
+++ b/eval.c
@@ -149,20 +149,34 @@ static val make_env_intrinsic(val vbindings, val fbindings, val up_env)
val env_fbind(val env, val sym, val fun)
{
- val cell;
- type_check(env, ENV);
- cell = acons_new_c(sym, nulloc, mkloc(env->e.fbindings, env));
- rplacd(cell, fun);
- return cell;
+ if (env) {
+ val cell;
+ type_check(env, ENV);
+ cell = acons_new_c(sym, nulloc, mkloc(env->e.fbindings, env));
+ return rplacd(cell, fun);
+ } else {
+ val hcell = gethash_c(top_fb, sym, nulloc);
+ val cell = cdr(hcell);
+ if (cell)
+ return rplacd(cell, fun);
+ return sys_rplacd(hcell, cons(sym, fun));
+ }
}
val env_vbind(val env, val sym, val obj)
{
- val cell;
- type_check(env, ENV);
- cell = acons_new_c(sym, nulloc, mkloc(env->e.vbindings, env));
- rplacd(cell, obj);
- return cell;
+ if (env) {
+ val cell;
+ type_check(env, ENV);
+ cell = acons_new_c(sym, nulloc, mkloc(env->e.vbindings, env));
+ return rplacd(cell, obj);
+ } else {
+ val hcell = gethash_c(top_vb, sym, nulloc);
+ val cell = cdr(hcell);
+ if (cell)
+ return rplacd(cell, obj);
+ return sys_rplacd(hcell, cons(sym, obj));
+ }
}
static void env_vb_to_fb(val env)