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:
Sage Vaillancourt 2022-03-31 15:44:18 -04:00 committed by Sage Vaillancourt
parent 2fb6643326
commit b770a618e0
4 changed files with 35 additions and 34 deletions

View File

@ -12,7 +12,9 @@
(def nl (ch 10)) (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 hour (fn (ti) (
(def h (% ti.hour 12)) (def h (% ti.hour 12))

View File

@ -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 * Tries to either apply the function to its parameters, or create a partial
* function, if not enough parameters were passed. * function, if not enough parameters were passed.
* *
* @param list The list being evaluated * @param function First element of the paramList, already evaluated to be a function
* @param function First element of the list, already evaluated to be a function * @param paramList The parameters to the function
* @param length Length of `list` - 1, to exclude the already-evaluated element * @param length Length of `paramList` - 1, to exclude the already-evaluated element
* @param env The environment to evaluate in * @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) const int length, struct Environment* env)
{ {
Object rest[length]; Object rest[length];
const Object* start = list->list->forward;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
rest[i] = eval(start, env); rest[i] = eval(paramList, env);
start = start->forward; paramList = paramList->forward;
} }
Object result = function->func(rest, length, env); 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 simpleFuncEval(const Object func, Object arg1, Object arg2, struct Environment* env)
{ {
Object funcList = startList(func); arg2 = cloneObject(arg2);
nf_addToList(&funcList, arg1); arg1.forward = &arg2;
Object current = cloneObject(arg2); Object first_eval = eval(&func, env);
nf_addToList(&funcList, current); Object ret = listEvalFunc(&first_eval, &arg1, 2, env);
Object first_eval = eval(funcList.list, env); cleanObject(&first_eval);
arg1 = listEvalFunc(&funcList, &first_eval, 2, env); cleanObject(&arg2);
cleanObject(&funcList); return ret;
return arg1;
} }
/** /**
@ -267,8 +265,8 @@ Object evalList(const Object* obj, struct Environment* env)
Object first_eval = eval(first_form, env); Object first_eval = eval(first_form, env);
switch (first_eval.type) { switch (first_eval.type) {
case TYPE_FUNC: case TYPE_FUNC:
// Uses evalLength - 1 because we skip the first form // Uses evalLength - 1 because we skip the first form (the function itself)
return listEvalFunc(obj, &first_eval, evalLength - 1, env); return listEvalFunc(&first_eval, obj->list->forward, evalLength - 1, env);
case TYPE_LAMBDA: case TYPE_LAMBDA:
return listEvalLambda(&first_eval, first_form->forward, evalLength, env); return listEvalLambda(&first_eval, first_form->forward, evalLength, env);

View File

@ -163,6 +163,14 @@ Object isString(Object* params, int length, struct Environment* env)
return boolObject(test.type == TYPE_STRING); 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) Object charVal(Object* params, int length, struct Environment* env)
{ {
checkTypes(charVal) checkTypes(charVal)
@ -171,12 +179,14 @@ Object charVal(Object* params, int length, struct Environment* env)
return numberObject(test.string[0]); 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) int printPointers = 0;
Object test = params[0]; if (length > 0 && params[0].type == TYPE_BOOL) {
printPointers = params[0].number;
return boolObject(test.type == TYPE_ERROR); }
printEnv(global(), printPointers);
return numberObject(0);
} }
Object parseEvalO(Object* params, int length, struct Environment* env) 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); 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 takeInput(Object* params, int length, struct Environment* env)
{ {
Object prompt = params[0]; Object prompt = params[0];

View File

@ -211,6 +211,7 @@ check "Accessing struct fields"\
title "HigherOrder" title "HigherOrder"
check "Simple reducing" '(reduce (1 2 3) + 0)' '6' check "Simple reducing" '(reduce (1 2 3) + 0)' '6'
check "NonListReducing" '(reduce 1 + 0)' '1' 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))))\ check "FuncReturningAFunc" "(def plusser (fn (outer) (fn (inner) (+ outer inner))))\
(def plusFive (plusser 5))\ (def plusFive (plusser 5))\
(plusFive 10)" "15" (plusFive 10)" "15"