Simpler listEvalFunc() implementation.
Simpler simpleFuncEval(), which should eventually be removed, anyway. - Something with it or (reduce) is a bit leaky, but actually less so than before. Small plfunc.c reordering.
This commit is contained in:
parent
2fb6643326
commit
b770a618e0
|
@ -12,7 +12,9 @@
|
|||
|
||||
(def nl (ch 10))
|
||||
|
||||
(def reload (fn () (loadfile (cat (env "HOME") "/.pebblisp.pbl"))))
|
||||
(def conf (cat (env "HOME") "/.pebblisp.pbl"))
|
||||
|
||||
(def reload (fn () (loadfile conf)))
|
||||
|
||||
(def hour (fn (ti) (
|
||||
(def h (% ti.hour 12))
|
||||
|
|
|
@ -151,25 +151,24 @@ Object evalBuiltIns(const Object* first, const Object* rest,
|
|||
}
|
||||
|
||||
/**
|
||||
* Evaluates a list whose first element is a function, applying that function
|
||||
* Evaluates a paramList whose first element is a function, applying that function
|
||||
*
|
||||
* Tries to either apply the function to its parameters, or create a partial
|
||||
* function, if not enough parameters were passed.
|
||||
*
|
||||
* @param list The list being evaluated
|
||||
* @param function First element of the list, already evaluated to be a function
|
||||
* @param length Length of `list` - 1, to exclude the already-evaluated element
|
||||
* @param function First element of the paramList, already evaluated to be a function
|
||||
* @param paramList The parameters to the function
|
||||
* @param length Length of `paramList` - 1, to exclude the already-evaluated element
|
||||
* @param env The environment to evaluate in
|
||||
*/
|
||||
Object listEvalFunc(const Object* list, const Object* function,
|
||||
Object listEvalFunc(const Object* function, const Object* paramList,
|
||||
const int length, struct Environment* env)
|
||||
{
|
||||
Object rest[length];
|
||||
|
||||
const Object* start = list->list->forward;
|
||||
for (int i = 0; i < length; i++) {
|
||||
rest[i] = eval(start, env);
|
||||
start = start->forward;
|
||||
rest[i] = eval(paramList, env);
|
||||
paramList = paramList->forward;
|
||||
}
|
||||
|
||||
Object result = function->func(rest, length, env);
|
||||
|
@ -181,14 +180,13 @@ Object listEvalFunc(const Object* list, const Object* function,
|
|||
|
||||
Object simpleFuncEval(const Object func, Object arg1, Object arg2, struct Environment* env)
|
||||
{
|
||||
Object funcList = startList(func);
|
||||
nf_addToList(&funcList, arg1);
|
||||
Object current = cloneObject(arg2);
|
||||
nf_addToList(&funcList, current);
|
||||
Object first_eval = eval(funcList.list, env);
|
||||
arg1 = listEvalFunc(&funcList, &first_eval, 2, env);
|
||||
cleanObject(&funcList);
|
||||
return arg1;
|
||||
arg2 = cloneObject(arg2);
|
||||
arg1.forward = &arg2;
|
||||
Object first_eval = eval(&func, env);
|
||||
Object ret = listEvalFunc(&first_eval, &arg1, 2, env);
|
||||
cleanObject(&first_eval);
|
||||
cleanObject(&arg2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,8 +265,8 @@ Object evalList(const Object* obj, struct Environment* env)
|
|||
Object first_eval = eval(first_form, env);
|
||||
switch (first_eval.type) {
|
||||
case TYPE_FUNC:
|
||||
// Uses evalLength - 1 because we skip the first form
|
||||
return listEvalFunc(obj, &first_eval, evalLength - 1, env);
|
||||
// Uses evalLength - 1 because we skip the first form (the function itself)
|
||||
return listEvalFunc(&first_eval, obj->list->forward, evalLength - 1, env);
|
||||
|
||||
case TYPE_LAMBDA:
|
||||
return listEvalLambda(&first_eval, first_form->forward, evalLength, env);
|
||||
|
|
30
src/plfunc.c
30
src/plfunc.c
|
@ -163,6 +163,14 @@ Object isString(Object* params, int length, struct Environment* env)
|
|||
return boolObject(test.type == TYPE_STRING);
|
||||
}
|
||||
|
||||
Object isErr(Object* params, int length, struct Environment* env)
|
||||
{
|
||||
checkTypes(isErr)
|
||||
Object test = params[0];
|
||||
|
||||
return boolObject(test.type == TYPE_ERROR);
|
||||
}
|
||||
|
||||
Object charVal(Object* params, int length, struct Environment* env)
|
||||
{
|
||||
checkTypes(charVal)
|
||||
|
@ -171,12 +179,14 @@ Object charVal(Object* params, int length, struct Environment* env)
|
|||
return numberObject(test.string[0]);
|
||||
}
|
||||
|
||||
Object isErr(Object* params, int length, struct Environment* env)
|
||||
Object printEnvO(Object* params, int length, struct Environment* env)
|
||||
{
|
||||
checkTypes(isErr)
|
||||
Object test = params[0];
|
||||
|
||||
return boolObject(test.type == TYPE_ERROR);
|
||||
int printPointers = 0;
|
||||
if (length > 0 && params[0].type == TYPE_BOOL) {
|
||||
printPointers = params[0].number;
|
||||
}
|
||||
printEnv(global(), printPointers);
|
||||
return numberObject(0);
|
||||
}
|
||||
|
||||
Object parseEvalO(Object* params, int length, struct Environment* env)
|
||||
|
@ -356,16 +366,6 @@ Object numToChar(Object* params, int length, struct Environment* env)
|
|||
return stringFromSlice(ch, 1);
|
||||
}
|
||||
|
||||
Object printEnvO(Object* params, int length, struct Environment* env)
|
||||
{
|
||||
int printPointers = 0;
|
||||
if (length > 0 && params[0].type == TYPE_BOOL) {
|
||||
printPointers = params[0].number;
|
||||
}
|
||||
printEnv(global(), printPointers);
|
||||
return numberObject(0);
|
||||
}
|
||||
|
||||
Object takeInput(Object* params, int length, struct Environment* env)
|
||||
{
|
||||
Object prompt = params[0];
|
||||
|
|
|
@ -211,6 +211,7 @@ check "Accessing struct fields"\
|
|||
title "HigherOrder"
|
||||
check "Simple reducing" '(reduce (1 2 3) + 0)' '6'
|
||||
check "NonListReducing" '(reduce 1 + 0)' '1'
|
||||
check "StringReducing" '(reduce (" my" " friend") cat "Hello,")' 'Hello, my friend'
|
||||
check "FuncReturningAFunc" "(def plusser (fn (outer) (fn (inner) (+ outer inner))))\
|
||||
(def plusFive (plusser 5))\
|
||||
(plusFive 10)" "15"
|
||||
|
|
Loading…
Reference in New Issue