summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-11-13 21:19:45 -0800
committerKaz Kylheku <kaz@kylheku.com>2018-11-13 21:19:45 -0800
commitbfc527af1af619742163d238eac9f2b24f363b0d (patch)
tree9922d8e4392d3ce95851edb1f0073ed52913f114 /eval.c
parent8e2aef8f2b466b37753ba0acd4bd668ff54b3669 (diff)
downloadtxr-bfc527af1af619742163d238eac9f2b24f363b0d.tar.gz
txr-bfc527af1af619742163d238eac9f2b24f363b0d.tar.bz2
txr-bfc527af1af619742163d238eac9f2b24f363b0d.zip
compile: handle functions that have environments.
With this patch, the compile function can handle interpreted function objects that have captured environments. For instance, if the following expression is evaluated (let ((counter 0)) (labels ((bm () (bump)) (bump () (inc counter))) (lambda () (bm)))) then a function object emerges. We can now feed this function object to the compile function; the environment will now be handled. Of course, the above expression is already compileable; compile-toplevel handles it and so does the file compiler. This patch allows the expression to be interpreted and then the function object to be compiled, without access to the surrounding expression. The compiled function will contain a compiled version of the environment, carrying compiled versions of the captured variables and their contents. * eval.c (env_vbindings, env_fbindings, env_next): New static functions. (eval_init): Register env-vbinding, env-fbindings and env-next intrinsics. * share/txr/stdlib/compiler.tl (sys:env-to-let): New function. (usr:compile): Wrap the interpreted lambda terms with let bindings carefully reconstructed from their captured environments. * txr.1: Documented new intrinsic functions.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index 6053c853..637ed8a6 100644
--- a/eval.c
+++ b/eval.c
@@ -202,6 +202,27 @@ val env_vbind(val env, val sym, val obj)
}
}
+static val env_vbindings(val env)
+{
+ val self = lit("env-vbindings");
+ type_check(self, env, ENV);
+ return env->e.vbindings;
+}
+
+static val env_fbindings(val env)
+{
+ val self = lit("env-fbindings");
+ type_check(self, env, ENV);
+ return env->e.fbindings;
+}
+
+static val env_next(val env)
+{
+ val self = lit("env-next");
+ type_check(self, env, ENV);
+ return env->e.up_env;
+}
+
static void env_vb_to_fb(val env)
{
if (env) {
@@ -6499,6 +6520,9 @@ void eval_init(void)
reg_fun(intern(lit("make-env"), user_package), func_n3o(make_env_intrinsic, 0));
reg_fun(intern(lit("env-fbind"), user_package), func_n3(env_fbind));
reg_fun(intern(lit("env-vbind"), user_package), func_n3(env_vbind));
+ reg_fun(intern(lit("env-vbindings"), user_package), func_n1(env_vbindings));
+ reg_fun(intern(lit("env-fbindings"), user_package), func_n1(env_fbindings));
+ reg_fun(intern(lit("env-next"), user_package), func_n1(env_next));
reg_fun(intern(lit("lexical-var-p"), user_package), func_n2(lexical_var_p));
reg_fun(intern(lit("lexical-fun-p"), user_package), func_n2(lexical_fun_p));
reg_fun(intern(lit("lexical-lisp1-binding"), user_package),