klisp

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

commit 3deed41b7e100244d8b583e947df8522ff939a9a
parent 8d26769f520c984931a98436ff8f1fc81e0cb3cb
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed,  9 Mar 2011 18:05:28 -0300

Added copy-es-immutable to the ground environment.

Diffstat:
Msrc/kground.c | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 79 insertions(+), 7 deletions(-)

diff --git a/src/kground.c b/src/kground.c @@ -85,6 +85,41 @@ #define kmake_applicative(K_, fn_, ...) \ kwrap(K_, kmake_operative(K_, KNIL, KNIL, fn_, __VA_ARGS__)) +/* +** This states are useful for traversing trees, saving the state in the +** token char buffer +*/ +#define ST_PUSH ((char) 0) +#define ST_CAR ((char) 1) +#define ST_CDR ((char) 2) + +/* +** These two stop at the first object that is not a marked pair +*/ +inline void unmark_list(klisp_State *K, TValue obj) +{ + while(ttispair(obj) && kis_marked(obj)) { + kunmark(obj); + obj = kcdr(obj); + } +} + +inline void unmark_tree(klisp_State *K, TValue obj) +{ + assert(ks_sisempty(K)); + + ks_spush(K, obj); + + while(!ks_sisempty(K)) { + obj = ks_spop(K); + + if (ttispair(obj) && kis_marked(obj)) { + kunmark(obj); + ks_spush(K, kcdr(obj)); + ks_spush(K, kcar(obj)); + } + } +} /* ** This section will roughly follow the report and will reference the @@ -291,10 +326,6 @@ void copy_es_immutable(klisp_State *K, TValue *xparams, ** 0 means just pushed, 1 means return from car, 2 means return from cdr */ -#define CEI_ST_PUSH ((char) 0) -#define CEI_ST_CAR ((char) 1) -#define CEI_ST_CDR ((char) 2) - TValue copy_es_immutable_h(klisp_State *K, char *name, TValue obj) { /* @@ -303,13 +334,51 @@ TValue copy_es_immutable_h(klisp_State *K, char *name, TValue obj) */ TValue copy = obj; + assert(ks_sisempty(K)); + assert(ks_tbisempty(K)); + ks_spush(K, obj); - ks_tbpush(K, CEI_ST_PUSH); + ks_tbpush(K, ST_PUSH); while(!ks_sisempty(K)) { char state = ks_tbpop(K); - } + TValue top = ks_spop(K); + if (state == ST_PUSH) { + if (ttispair(top) && kis_mutable(top)) { + if (kis_marked(top)) { + /* this pair was already seen, use the same */ + copy = kget_mark(top); + } else { + TValue new_pair = kdummy_imm_cons(K); + kset_mark(top, new_pair); + /* leave the pair in the stack, continue with the car */ + ks_spush(K, top); + ks_tbpush(K, ST_CAR); + + ks_spush(K, kcar(top)); + ks_tbpush(K, ST_PUSH); + } + } else { + copy = top; + } + } else { /* last action was a pop */ + TValue new_pair = kget_mark(top); + if (state == ST_CAR) { + kset_car(new_pair, copy); + /* leave the pair on the stack, continue with the cdr */ + ks_spush(K, top); + ks_tbpush(K, ST_CDR); + + ks_spush(K, kcdr(top)); + ks_tbpush(K, ST_PUSH); + } else { + kset_cdr(new_pair, copy); + copy = new_pair; + } + } + } + unmark_tree(K, obj); return copy; } @@ -415,6 +484,7 @@ void SdefineB(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) ** ** It also copies the ptree so that it can't be mutated ** TODO: if ptree is immutable don't copy it +** TODO: replace this mechanism with the states in the token buffer */ inline TValue check_copy_ptree(klisp_State *K, char *name, TValue ptree) { @@ -742,7 +812,9 @@ TValue kmake_ground_env(klisp_State *K) kadd_binding(K, ground_env, symbol, value); /* 4.7.2 copy-es-immutable */ - /* TODO */ + symbol = ksymbol_new(K, "copy-es-immutable"); + value = kmake_applicative(K, copy_es_immutable, 1, symbol); + kadd_binding(K, ground_env, symbol, value); /* ** 4.8 Environments