Cleanup and a couple (micro) optimizations.
This commit is contained in:
parent
66a07e395c
commit
af7a2e6265
|
@ -56,11 +56,9 @@ Object fetchFromEnvironment(const char* name, struct Environment* env)
|
|||
return errorWithContext(DID_NOT_FIND_SYMBOL, name);
|
||||
}
|
||||
|
||||
struct Environment envForLambda(const Object* params, const Object* arg_forms,
|
||||
struct Environment envForLambda(const Object* params, const Object* arg_forms, int paramCount,
|
||||
struct Environment* outer)
|
||||
{
|
||||
int paramCount = listLength(params);
|
||||
|
||||
if (outer) {
|
||||
outer->refs += 1;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ void setGlobal(struct Environment* env);
|
|||
|
||||
Object fetchFromEnvironment(const char* name, struct Environment* env);
|
||||
|
||||
struct Environment envForLambda(const Object* params, const Object* arg_forms,
|
||||
struct Environment envForLambda(const Object* params, const Object* arg_forms, int paramCount,
|
||||
struct Environment* outer);
|
||||
|
||||
void addToEnv(struct Environment* env, const char* name, Object obj);
|
||||
|
|
67
src/object.c
67
src/object.c
|
@ -50,10 +50,6 @@ int listLength(const Object* listObj)
|
|||
*/
|
||||
Object* itemAt(const Object* listObj, int n)
|
||||
{
|
||||
if (!listObj || !isListy(*listObj)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FOR_POINTER_IN_LIST(listObj) {
|
||||
if (n-- == 0) {
|
||||
return POINTER;
|
||||
|
@ -80,46 +76,6 @@ Object* tail(const Object* listObj)
|
|||
return tail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given object is empty.
|
||||
*
|
||||
* BOOL, NUMBER, and ERROR types return true only when 0
|
||||
* LIST, LAMBDA, and FUNC types return true only when NULL
|
||||
* SYMBOL returns true only when it begins with a nullchar
|
||||
* @param obj A pointer to the object to check
|
||||
* @return True only if the non-null Object is empty/non-zero
|
||||
*/
|
||||
inline int isEmpty(const Object* obj)
|
||||
{
|
||||
if (obj == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (obj->type) {
|
||||
case TYPE_NUMBER:
|
||||
case TYPE_BOOL:
|
||||
return obj->number == 0;
|
||||
case TYPE_LIST:
|
||||
case TYPE_SLIST:
|
||||
return obj->list == NULL;
|
||||
case TYPE_LAMBDA:
|
||||
return obj->lambda == NULL;
|
||||
case TYPE_STRUCT:
|
||||
return obj->structObject == NULL;
|
||||
case TYPE_SYMBOL:
|
||||
case TYPE_STRING:
|
||||
return obj->string == NULL || obj->string[0] == '\0';
|
||||
case TYPE_FUNC:
|
||||
return obj->func == NULL;
|
||||
case TYPE_OTHER:
|
||||
return obj->other == NULL;
|
||||
case TYPE_ERROR:
|
||||
return getErrorCode(*obj);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int allocations = 0;
|
||||
|
||||
int getAllocations()
|
||||
|
@ -153,19 +109,18 @@ void allocObject(Object** spot, const Object src)
|
|||
* Does nothing if `dest` is NULL or not a list type
|
||||
* @param dest The list to append to
|
||||
* @param src The Object to copy into the list
|
||||
* @returns A pointer to the tail of the destination list
|
||||
*/
|
||||
void nf_addToList(Object* dest, const Object src)
|
||||
Object* nf_addToList(Object* dest, const Object src)
|
||||
{
|
||||
if (!dest || !isListy(*dest)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEmpty(dest)) {
|
||||
if (dest->list == NULL) {
|
||||
allocObject(&dest->list, src);
|
||||
return;
|
||||
return dest->list;
|
||||
}
|
||||
|
||||
allocObject(&tail(dest)->forward, src);
|
||||
Object* listTail = tail(dest);
|
||||
allocObject(&listTail->forward, src);
|
||||
return listTail->forward;
|
||||
}
|
||||
|
||||
#ifndef SIMPLE_ERRORS
|
||||
|
@ -199,9 +154,6 @@ static const char* errorText[] = {"MISMATCHED_PARENS",
|
|||
*/
|
||||
int stringList(char* dest, const Object* obj)
|
||||
{
|
||||
if (!dest || !isListy(*obj)) {
|
||||
return 0;
|
||||
}
|
||||
const char* initial = dest;
|
||||
|
||||
dest += sprintf(dest, "(");
|
||||
|
@ -503,11 +455,6 @@ void printAndClean(Object* target)
|
|||
*/
|
||||
void deleteList(Object* dest)
|
||||
{
|
||||
if (!isListy(*dest)) {
|
||||
printf("Tried to delete something other than a list\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Object* march = dest->list;
|
||||
while (march != NULL) {
|
||||
Object* prevMarch = march;
|
||||
|
|
|
@ -144,7 +144,7 @@ int isEmpty(const Object* obj);
|
|||
|
||||
Object* tail(const Object* listObj);
|
||||
|
||||
void nf_addToList(Object* dest, Object src);
|
||||
Object* nf_addToList(Object* dest, Object src);
|
||||
|
||||
void deleteList(Object* dest);
|
||||
|
||||
|
|
|
@ -103,12 +103,12 @@ Object evalMapArgs(const Object* argForms, struct Environment* env)
|
|||
|
||||
Object lambda = eval(argForms, env);
|
||||
const Object* inputList = argForms->forward;
|
||||
Object outputList = listObject();
|
||||
|
||||
if (lambda.type != TYPE_LAMBDA) {
|
||||
return errorObject(BAD_TYPE);
|
||||
}
|
||||
|
||||
Object outputList = listObject();
|
||||
if (inputList) {
|
||||
FOR_POINTER_IN_LIST(inputList) {
|
||||
// Create a new list for each element,
|
||||
|
@ -116,7 +116,7 @@ Object evalMapArgs(const Object* argForms, struct Environment* env)
|
|||
Object tempInput = cloneObject(*POINTER);
|
||||
|
||||
Object* params = &lambda.lambda->params;
|
||||
struct Environment newEnv = envForLambda(params, &tempInput, env);
|
||||
struct Environment newEnv = envForLambda(params, &tempInput, listLength(params), env);
|
||||
|
||||
// Add the lambda evaluation to the list
|
||||
Object lambda_output = eval(&lambda.lambda->body, &newEnv);
|
||||
|
@ -208,11 +208,11 @@ Object simpleFuncEval(const Object func, Object arg1, Object arg2, struct Enviro
|
|||
* @param remaining The first element after `lambda`
|
||||
* @param env The environment to evaluate in
|
||||
*/
|
||||
Object listEvalLambda(Object* lambda, const Object* remaining,
|
||||
Object listEvalLambda(Object* lambda, const Object* remaining, int evalLength,
|
||||
struct Environment* env)
|
||||
{
|
||||
struct Environment newEnv =
|
||||
envForLambda(&lambda->lambda->params, remaining, env);
|
||||
envForLambda(&lambda->lambda->params, remaining, evalLength - 1, env);
|
||||
Object ret = eval(&lambda->lambda->body, &newEnv);
|
||||
deleteEnv(&newEnv);
|
||||
cleanObject(lambda);
|
||||
|
@ -278,15 +278,16 @@ Object evalList(const Object* obj, struct Environment* env)
|
|||
return listEvalFunc(obj, &first_eval, evalLength - 1, env);
|
||||
|
||||
case TYPE_LAMBDA:
|
||||
return listEvalLambda(&first_eval, first_form->forward, env);
|
||||
return listEvalLambda(&first_eval, first_form->forward, evalLength, env);
|
||||
|
||||
default: { // Return list with each element evaluated
|
||||
Object list = listObject();
|
||||
int i = 0;
|
||||
nf_addToList(&list, first_eval);
|
||||
Object* t = nf_addToList(&list, first_eval);
|
||||
FOR_POINTER_IN_LIST(obj) {
|
||||
if (i != 0) {
|
||||
nf_addToList(&list, eval(POINTER, env));
|
||||
allocObject(&t->forward, eval(POINTER, env));
|
||||
t = t->forward;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -319,15 +320,6 @@ Object eval(const Object* obj, struct Environment* env)
|
|||
return errorObject(BAD_TYPE);
|
||||
}
|
||||
|
||||
void copySlice(char* dest, struct Slice* src)
|
||||
{
|
||||
if (!dest || !src) {
|
||||
return;
|
||||
}
|
||||
strncpy(dest, src->text, src->length);
|
||||
dest[(int) src->length] = '\0';
|
||||
}
|
||||
|
||||
Object possessive(Object* params, int length, struct Environment* env)
|
||||
{
|
||||
Object structo = params[0];
|
||||
|
@ -510,19 +502,6 @@ Object parseEval(const char* input, struct Environment* env)
|
|||
return symFromSlice(" ", 1);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
struct Slice *debug = tokens;
|
||||
printd("start slice\n");
|
||||
if (debug) {
|
||||
while (debug->text) {
|
||||
char tok[100];
|
||||
copySlice(tok, debug);
|
||||
printd("slice: '%s'\n", tok);
|
||||
debug++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
int parens = 0;
|
||||
Object obj = numberObject(0);
|
||||
|
|
|
@ -54,7 +54,7 @@ void copySlice(char* dest, struct Slice* src);
|
|||
|
||||
Object evalLambdaArgs(const Object* arg_forms, struct Environment* env);
|
||||
|
||||
Object listEvalLambda(Object* lambda, const Object* remaining,
|
||||
Object listEvalLambda(Object* lambda, const Object* remaining, int evalLength,
|
||||
struct Environment* env);
|
||||
|
||||
Object simpleFuncEval(Object func, Object arg1, Object arg2, struct Environment* env);
|
||||
|
|
13
src/plfunc.c
13
src/plfunc.c
|
@ -3,10 +3,11 @@
|
|||
|
||||
#include "plfunc.h"
|
||||
|
||||
Object typeCheck(const char* funcName, Object* params, int length, int (*typeChecks[])(Object), int typeLength, int* failed)
|
||||
Object typeCheck(const char* funcName, Object* params, int length,
|
||||
int (* typeChecks[])(Object), int typeLength, int* failed)
|
||||
{
|
||||
*failed = 1;
|
||||
if ((typeLength - 1) > length ) {
|
||||
if ((typeLength - 1) > length) {
|
||||
return errorObject(NOT_ENOUGH_ARGUMENTS);
|
||||
}
|
||||
for (int i = 0; i < typeLength - 1; i++) {
|
||||
|
@ -76,7 +77,7 @@ Object filter(Object* params, int length, struct Environment* env)
|
|||
Object cloned = cloneObject(condition);
|
||||
Object first_eval = eval(&cloned, env);
|
||||
Object testee = cloneObject(*POINTER);
|
||||
Object e = listEvalLambda(&first_eval, &testee, env);
|
||||
Object e = listEvalLambda(&first_eval, &testee, 2, env);
|
||||
if (e.number) {
|
||||
nf_addToList(&filtered, testee); // May need to re-clone testee?
|
||||
}
|
||||
|
@ -299,10 +300,10 @@ int areEqual(const Object* obj1, const Object* obj2);
|
|||
|
||||
int listEquality(const Object* list1, const Object* list2)
|
||||
{
|
||||
Object* element1, *element2;
|
||||
Object* element1, * element2;
|
||||
for (element1 = (list1)->list, element2 = (list2)->list;
|
||||
element1 != ((void*) 0) && element2 != ((void*) 0);
|
||||
element1 = element1->forward, element2 = element2->forward) {
|
||||
element1 != ((void*) 0) && element2 != ((void*) 0);
|
||||
element1 = element1->forward, element2 = element2->forward) {
|
||||
if (!areEqual(element1, element2)) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ answer_to_connection(void* cls, struct MHD_Connection* connection,
|
|||
//res.structObject->fields[0] = queryParams;
|
||||
Object route = cloneObject(routes[i].routeAction);
|
||||
|
||||
Object result = listEvalLambda(&route, &res, routes[i].env);
|
||||
Object result = listEvalLambda(&route, &res, 2, routes[i].env);
|
||||
cleanObject(&res);
|
||||
page = result.string;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue