klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 141c1a0e25050e10862828398ad57caa3ccf4fc2
parent 1f3aab1d158d6149314883a315a38bc2380ebf6f
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Mon, 28 Mar 2011 15:25:48 -0300

Added $let to the ground environment.

Diffstat:
Msrc/Makefile | 2+-
Msrc/kgenvironments.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/kstate.c | 4++++
Msrc/kstate.h | 1+
4 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -102,7 +102,7 @@ kgpair_mut.o: kgpair_mut.c kgpair_mut.h kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kpair.h ksymbol.h kcontinuation.h kgeqp.h kgenvironments.o: kgenvironments.c kgenvironments.h kghelpers.h kstate.h \ klisp.h kobject.h kerror.h kpair.h ksymbol.h kcontinuation.h \ - kenvironment.h kgenv_mut.h kgpair_mut.h + kenvironment.h kgenv_mut.h kgpair_mut.h kgcontrol.h kgenv_mut.o: kgenv_mut.c kgenv_mut.h kghelpers.h kstate.h \ klisp.h kobject.h kerror.h kpair.h ksymbol.h kcontinuation.h \ kenvironment.h diff --git a/src/kgenvironments.c b/src/kgenvironments.c @@ -22,6 +22,7 @@ #include "kgenvironments.h" #include "kgenv_mut.h" /* for check_ptree */ #include "kgpair_mut.h" /* for copy_es_immutable_h */ +#include "kgcontrol.h" /* for do_seq */ /* MAYBE: move the above to kghelpers.h */ /* 4.8.1 environment? */ @@ -145,27 +146,77 @@ TValue split_check_let_bindings(klisp_State *K, char *name, TValue bindings, } } +/* +** Continuation function for all the let family +** it expects the result of the last evaluation to be matched to +** this-ptree +*/ +void do_let(klisp_State *K, TValue *xparams, TValue obj) +{ + /* + ** xparams[0]: symbol name + ** xparams[1]: this ptree + ** xparams[2]: remaining bindings + ** xparams[3]: remaining exprs + ** xparams[4]: match environment + ** xparams[5]: rec/not rec flag + ** xparams[6]: body + */ + TValue sname = xparams[0]; + char *name = ksymbol_buf(sname); + TValue ptree = xparams[1]; + TValue bindings = xparams[2]; + TValue exprs = xparams[3]; + TValue env = xparams[4]; + bool recp = bvalue(xparams[5]); + TValue body = xparams[6]; + + /* XXX */ + UNUSED(recp); + UNUSED(bindings); + UNUSED(exprs); + + match(K, name, env, ptree, obj); + + /* TODO: check bindings */ + if (ttisnil(body)) { + kapply_cc(K, KINERT); + } else { + /* this is needed because seq continuation doesn't check for + nil sequence */ + TValue tail = kcdr(body); + if (ttispair(tail)) { + TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, + do_seq, 2, tail, env); + kset_cc(K, new_cont); + } + ktail_eval(K, kcar(body), env); + } +} + /* 5.10.1 $let */ -/* TEMP: for now this only checks the parameters and makes copies */ -/* XXX: it doesn't do any evaluation or env creation */ +/* REFACTOR: reuse code in other members of the $let family */ void Slet(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) { /* ** xparams[0]: symbol name */ - UNUSED(denv); - char *name = ksymbol_buf(xparams[0]); + TValue sname = xparams[0]; + char *name = ksymbol_buf(sname); bind_al1p(K, name, ptree, bindings, body); TValue exprs; - TValue btree = split_check_let_bindings(K, name, bindings, &exprs, false); + TValue bptree = split_check_let_bindings(K, name, bindings, &exprs, false); int32_t dummy; UNUSED(check_list(K, name, true, body, &dummy)); body = copy_es_immutable_h(K, name, body, false); - /* XXX */ - TValue res = kcons(K, btree, kcons(K, exprs, body)); - kapply_cc(K, res); + TValue new_env = kmake_environment(K, denv); + TValue new_cont = + kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, + bptree, KNIL, KNIL, new_env, b2tv(false), body); + kset_cc(K, new_cont); + ktail_eval(K, kcons(K, K->list_app, exprs), denv); } /* 6.7.1 $binds? */ diff --git a/src/kstate.c b/src/kstate.c @@ -33,6 +33,8 @@ #include "kstring.h" #include "kport.h" +#include "kgpairs_lists.h" /* for creating list_app */ + /* ** State creation and destruction */ @@ -65,6 +67,7 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) { /* these will be properly initialized later */ K->eval_op = KINERT; + K->list_app = KINERT; K->ground_env = KINERT; K->module_params_sym = KINERT; K->root_cont = KINERT; @@ -138,6 +141,7 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) { /* create the ground environment and the eval operative */ K->eval_op = kmake_operative(K, KNIL, KNIL, keval_ofn, 0); + K->list_app = kwrap(K, kmake_operative(K, KNIL, KNIL, list, 0)); K->ground_env = kmake_empty_environment(K); K->module_params_sym = ksymbol_new(K, "module-parameters"); diff --git a/src/kstate.h b/src/kstate.h @@ -52,6 +52,7 @@ struct klisp_State { TValue *next_xparams; TValue eval_op; /* the operative for evaluation */ + TValue list_app; /* the applicative for list evaluation */ TValue ground_env; /* the environment with all the ground definitions */ /* standard environments are environments with no bindings and ground_env as parent */