From b770a618e06c1fd320b32fcb0af5769cbdf8d57b Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Thu, 31 Mar 2022 15:44:18 -0400 Subject: [PATCH] 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. --- src/examples/pebblisp.pbl | 4 +++- src/pebblisp.c | 34 ++++++++++++++++------------------ src/plfunc.c | 30 +++++++++++++++--------------- src/tests.sh | 1 + 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/examples/pebblisp.pbl b/src/examples/pebblisp.pbl index d3082da..5f667ee 100644 --- a/src/examples/pebblisp.pbl +++ b/src/examples/pebblisp.pbl @@ -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)) diff --git a/src/pebblisp.c b/src/pebblisp.c index 429b4da..599e89e 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -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); diff --git a/src/plfunc.c b/src/plfunc.c index 28234bf..974d874 100644 --- a/src/plfunc.c +++ b/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]; diff --git a/src/tests.sh b/src/tests.sh index ed6c2d9..f72d655 100755 --- a/src/tests.sh +++ b/src/tests.sh @@ -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"