mirror of
https://github.com/samsonjs/lake.git
synced 2026-04-27 14:57:43 +00:00
add cond special form
This commit is contained in:
parent
7eb66463b0
commit
43d6ca80f0
2 changed files with 33 additions and 4 deletions
36
src/eval.c
36
src/eval.c
|
|
@ -162,6 +162,28 @@ static LakeVal *_if(Env *env, LakeList *expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LakeVal *_cond(Env *env, LakeList *expr)
|
||||||
|
{
|
||||||
|
static LakeVal *ELSE = NULL;
|
||||||
|
if (!ELSE) ELSE = VAL(sym_intern("else"));
|
||||||
|
|
||||||
|
list_shift(expr); /* "cond" token */
|
||||||
|
LakeVal *pred;
|
||||||
|
LakeList *conseq;
|
||||||
|
while (LIST_N(expr)) {
|
||||||
|
if (!IS(TYPE_LIST, LIST_VAL(expr, 0))) {
|
||||||
|
invalid_special_form(expr, "expected a (predicate consequence) pair");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
conseq = LIST(list_shift(expr));
|
||||||
|
pred = list_shift(conseq);
|
||||||
|
if (pred == ELSE || IS_TRUTHY(eval(env, pred))) {
|
||||||
|
return eval_exprs1(env, conseq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void init_special_form_handlers(void)
|
static void init_special_form_handlers(void)
|
||||||
{
|
{
|
||||||
#define HANDLER(name, fn) g_hash_table_insert(special_form_handlers, \
|
#define HANDLER(name, fn) g_hash_table_insert(special_form_handlers, \
|
||||||
|
|
@ -170,12 +192,12 @@ static void init_special_form_handlers(void)
|
||||||
|
|
||||||
special_form_handlers = symtable_make();
|
special_form_handlers = symtable_make();
|
||||||
/* HANDLER("load", &load_special_form); */
|
/* HANDLER("load", &load_special_form); */
|
||||||
/* HANDLER("cond", &cond_special_form); */
|
|
||||||
HANDLER("quote", &_quote);
|
HANDLER("quote", &_quote);
|
||||||
HANDLER("and", &_and);
|
HANDLER("and", &_and);
|
||||||
HANDLER("or", &_or);
|
HANDLER("or", &_or);
|
||||||
HANDLER("if", &_if);
|
HANDLER("if", &_if);
|
||||||
/* HANDLER("when", &_when); */
|
/* HANDLER("when", &_when); */
|
||||||
|
HANDLER("cond", &_cond);
|
||||||
HANDLER("set!", &_setB);
|
HANDLER("set!", &_setB);
|
||||||
HANDLER("define", &_define);
|
HANDLER("define", &_define);
|
||||||
HANDLER("lambda", &_lambda);
|
HANDLER("lambda", &_lambda);
|
||||||
|
|
@ -294,6 +316,14 @@ LakeList *eval_exprs(Env *env, LakeList *exprs)
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LakeVal *eval_exprs1(Env *env, LakeList *exprs)
|
||||||
|
{
|
||||||
|
LakeList *results = eval_exprs(env, exprs);
|
||||||
|
LakeVal *result = list_pop(results);
|
||||||
|
list_free(results);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
LakeVal *apply(LakeVal *fnVal, LakeList *args)
|
LakeVal *apply(LakeVal *fnVal, LakeList *args)
|
||||||
{
|
{
|
||||||
LakeVal *result = NULL;
|
LakeVal *result = NULL;
|
||||||
|
|
@ -340,9 +370,7 @@ LakeVal *apply(LakeVal *fnVal, LakeList *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* evaluate body */
|
/* evaluate body */
|
||||||
LakeList *results = eval_exprs(env, fn->body);
|
result = eval_exprs1(env, fn->body);
|
||||||
result = list_pop(results);
|
|
||||||
list_free(results);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ERR("not a function: %s", repr(fnVal));
|
ERR("not a function: %s", repr(fnVal));
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
LakeVal *eval(Env *env, LakeVal *expr);
|
LakeVal *eval(Env *env, LakeVal *expr);
|
||||||
LakeList *eval_exprs(Env *env, LakeList *exprs);
|
LakeList *eval_exprs(Env *env, LakeList *exprs);
|
||||||
|
LakeVal *eval_exprs1(Env *env, LakeList *exprs);
|
||||||
LakeVal *apply(LakeVal *fnVal, LakeList *args);
|
LakeVal *apply(LakeVal *fnVal, LakeList *args);
|
||||||
gboolean is_special_form(LakeList *expr);
|
gboolean is_special_form(LakeList *expr);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue