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 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))
|
||||||
|
|
|
@ -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);
|
||||||
|
|
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);
|
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];
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue