klisp

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

commit 025be6b4696f25c850721116c1931dcb83a656a5
parent a687e51f12618b281ab6ebedd9bbb867299a59b4
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Thu,  7 Apr 2011 14:34:11 -0300

Added for-each to the ground environment. All modules implemented modules complete. Still missing numbers other than integers. Integers above fixnums, garbage collection and a working implementation of char-ready?.

Diffstat:
Msrc/Makefile | 2+-
Msrc/kgcombiners.c | 3+--
Msrc/kgcontrol.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/kgcontrol.h | 3+++
Msrc/kground.c | 4+---
5 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -96,7 +96,7 @@ kgequalp.o: kgequalp.c kgequalp.c kghelpers.h kstate.h klisp.h \ kgsymbols.o: kgsymbols.c kgsymbols.c kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kpair.h kcontinuation.h kstring.h kgcontrol.o: kgcontrol.c kgcontrol.c kghelpers.h kstate.h klisp.h \ - kobject.h kerror.h kpair.h kcontinuation.h + kobject.h kerror.h kpair.h kcontinuation.h kgcombiners.h kgpairs_lists.o: kgpairs_lists.c kgpairs_lists.h kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kpair.h ksymbol.h kcontinuation.h kgequalp.h \ kenvironment.h diff --git a/src/kgcombiners.c b/src/kgcombiners.c @@ -466,8 +466,7 @@ void map(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) { (void) xparams; - bind_al1tp(K, "map", ptree, "applicative", ttisapplicative, app, - lss); + bind_al1tp(K, "map", ptree, "applicative", ttisapplicative, app, lss); if (ttisnil(lss)) { klispE_throw(K, "map: no lists"); diff --git a/src/kgcontrol.c b/src/kgcontrol.c @@ -18,6 +18,7 @@ #include "kghelpers.h" #include "kgcontrol.h" +#include "kgcombiners.h" /* for map/for-each helpers */ /* 4.5.1 inert? */ /* uses typep */ @@ -259,3 +260,76 @@ void Scond(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) } kapply_cc(K, obj); } + +/* Helper continuation for for-each */ +void do_for_each(klisp_State *K, TValue *xparams, TValue obj) +{ + /* + ** xparams[0]: app + ** xparams[1]: rem-ls + ** xparams[2]: n + ** xparams[3]: denv + */ + TValue app = xparams[0]; + TValue ls = xparams[1]; + int32_t n = ivalue(xparams[2]); + TValue denv = xparams[3]; + + /* the resulting value is just ignored */ + UNUSED(obj); + + if (n == 0) { + /* return inert as the final result to for-each */ + kapply_cc(K, KINERT); + } else { + /* copy the ptree to avoid problems with mutation */ + /* XXX: no check necessary, could just use copy_list if there + was such a procedure */ + TValue first_ptree = check_copy_list(K, "for-each", kcar(ls), false); + ls = kcdr(ls); + n = n-1; + /* have to unwrap the applicative to avoid extra evaluation of first */ + TValue new_expr = kcons(K, kunwrap(app), first_ptree); + TValue new_cont = + kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_for_each, 4, + app, ls, i2tv(n), denv); + kset_cc(K, new_cont); + ktail_eval(K, new_expr, denv); + } +} + +/* 6.9.1 for-each */ +void for_each(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) +{ + (void) xparams; + + bind_al1tp(K, "for-each", ptree, "applicative", ttisapplicative, app, lss); + + if (ttisnil(lss)) { + klispE_throw(K, "for-each: no lists"); + return; + } + + /* get the metrics of the ptree of each call to app and + of the result list */ + int32_t app_pairs, app_apairs, app_cpairs; + int32_t res_pairs, res_apairs, res_cpairs; + + map_for_each_get_metrics(K, "for-each", lss, &app_apairs, &app_cpairs, + &res_apairs, &res_cpairs); + app_pairs = app_apairs + app_cpairs; + res_pairs = res_apairs + res_cpairs; + + /* create the list of parameters to app */ + lss = map_for_each_transpose(K, lss, app_apairs, app_cpairs, + res_apairs, res_cpairs); + + /* schedule all elements at once, the cycle is just ignored, this + will also return #inert once done. */ + TValue new_cont = + kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_for_each, 4, app, lss, + i2tv(res_pairs), denv); + kset_cc(K, new_cont); + /* this will be a nop */ + kapply_cc(K, KINERT); +} diff --git a/src/kgcontrol.h b/src/kgcontrol.h @@ -40,4 +40,7 @@ void do_cond(klisp_State *K, TValue *xparams, TValue obj); /* 5.6.1 $cond */ void Scond(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); +/* 6.9.1 for-each */ +void for_each(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); + #endif diff --git a/src/kground.c b/src/kground.c @@ -491,9 +491,7 @@ void kinit_ground_env(klisp_State *K) */ /* 6.9.1 for-each */ - /* TODO */ - - + add_applicative(K, ground_env, "for-each", for_each, 0); /* **