klisp

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

commit 91501ab76d413c4def9670f95cea678197e78638
parent 8c16ff0026717f34b7ec94c0d91d7448cd4b59aa
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Tue,  8 Mar 2011 23:48:08 -0300

Added $if operative to the ground environment. Clauses eval structure copying pending.

Diffstat:
Msrc/kground.c | 51+++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 43 insertions(+), 8 deletions(-)

diff --git a/src/kground.c b/src/kground.c @@ -70,6 +70,18 @@ return; \ } +#define bind_3p(K_, n_, ptree_, v1_, v2_, v3_) \ + TValue v1_, v2_, v3_; \ + if (!ttispair(ptree_) || !ttispair(kcdr(ptree_)) || \ + !ttispair(kcdr (kcdr (ptree_))) || \ + !ttisnil(kcdr(kcdr(kcdr(ptree_))))) { \ + klispE_throw(K_, n_ ": Bad ptree (expected tree arguments)"); \ + return; \ + } \ + v1_ = kcar(ptree_); \ + v2_ = kcar(kcdr(ptree_)); \ + v3_ = kcar(kcdr(kcdr(ptree_))) + /* TODO: add name and source info */ #define kmake_applicative(K_, fn_, ...) \ kwrap(K_, kmake_operative(K_, KNIL, KNIL, fn_, __VA_ARGS__)) @@ -151,17 +163,42 @@ void inertp(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) } /* 4.5.2 $if */ -/* TODO: + +/* helpers */ +void select_clause(klisp_State *K, TValue *xparams, TValue obj); + +/* TODO: both clauses should probably be copied */ void Sif(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) { (void) denv; (void) xparams; - bind_3p(K, "boolean?", ptree, test, consc, altc); - - kapply_cc(K, b2tv(ttisboolean(o))); + bind_3p(K, "$if", ptree, test, cons_c, alt_c); + + TValue new_cont = + kmake_continuation(K, kget_cc(K), KNIL, KNIL, select_clause, + 3, denv, cons_c, alt_c); + + klispS_set_cc(K, new_cont); + ktail_call(K, K->eval_op, test, denv); +} + +void select_clause(klisp_State *K, TValue *xparams, TValue obj) +{ + /* + ** xparams[0]: dynamic env + ** xparams[1]: consequent clause + ** xparams[2]: alternative clause + */ + if (ttisboolean(obj)) { + TValue denv = xparams[0]; + TValue clause = bvalue(obj)? xparams[1] : xparams[2]; + ktail_call(K, K->eval_op, clause, denv); + } else { + klispE_throw(K, "$if: test is not a boolean"); + return; + } } -*/ /* ** 4.6 Pairs and lists @@ -310,7 +347,7 @@ void SdefineB(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) dptree = check_copy_ptree(K, "$define!", dptree); TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, - &match, 3, dptree, denv, + match, 3, dptree, denv, def_sym); kset_cc(K, new_cont); ktail_call(K, K->eval_op, expr, denv); @@ -619,11 +656,9 @@ TValue kmake_ground_env(klisp_State *K) kadd_binding(K, ground_env, symbol, value); /* 4.5.2 $if */ -/* TODO: symbol = ksymbol_new(K, "$if"); value = kmake_operative(K, KNIL, KNIL, Sif, 0); kadd_binding(K, ground_env, symbol, value); -*/ /* ** 4.6 Pairs and lists