From af7a2e6265bf3bcc423a486eb2959ad240efa4f6 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Mon, 28 Mar 2022 23:51:05 -0400 Subject: [PATCH] Cleanup and a couple (micro) optimizations. --- src/env.c | 4 +-- src/env.h | 2 +- src/object.c | 67 ++++++-------------------------------------------- src/object.h | 2 +- src/pebblisp.c | 37 ++++++---------------------- src/pebblisp.h | 2 +- src/plfunc.c | 13 +++++----- src/web.c | 2 +- 8 files changed, 27 insertions(+), 102 deletions(-) diff --git a/src/env.c b/src/env.c index dc8e7c8..c5b91ac 100644 --- a/src/env.c +++ b/src/env.c @@ -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; } diff --git a/src/env.h b/src/env.h index 827dbab..a198b0e 100644 --- a/src/env.h +++ b/src/env.h @@ -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); diff --git a/src/object.c b/src/object.c index f8c6040..2ec6de4 100644 --- a/src/object.c +++ b/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; diff --git a/src/object.h b/src/object.h index b99f6b9..20d85b5 100644 --- a/src/object.h +++ b/src/object.h @@ -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); diff --git a/src/pebblisp.c b/src/pebblisp.c index 9d95bf4..e9954c1 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -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); diff --git a/src/pebblisp.h b/src/pebblisp.h index 619688d..c734775 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -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); diff --git a/src/plfunc.c b/src/plfunc.c index c88a141..a92ac81 100644 --- a/src/plfunc.c +++ b/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; } diff --git a/src/web.c b/src/web.c index f7d8523..93644e5 100644 --- a/src/web.c +++ b/src/web.c @@ -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;