From 158c21f441a0cf006032fe7e3855a5ef582b300c Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Sat, 26 Mar 2022 19:51:52 -0400 Subject: [PATCH] Reference count LAMBDAS. Remove more unused code/checks. Simplify evalList (though it could use more work). --- src/env.h | 2 -- src/object.c | 59 ++++++++----------------------------------- src/object.h | 4 +-- src/pebblisp.c | 68 +++++++++++++++----------------------------------- src/tokens.c | 2 -- 5 files changed, 31 insertions(+), 104 deletions(-) diff --git a/src/env.h b/src/env.h index b1bb2c2..78da27b 100644 --- a/src/env.h +++ b/src/env.h @@ -38,8 +38,6 @@ void deleteEnv(struct Environment* e); struct Environment defaultEnv(); -struct StructDef getStructDef(struct Environment* env, const char* name); - int getStructIndex(struct Environment* env, const char* name); /// Needs to be freed! diff --git a/src/object.c b/src/object.c index d48e05a..b899427 100644 --- a/src/object.c +++ b/src/object.c @@ -59,9 +59,6 @@ Object* itemAt(const Object* listObj, int n) } FOR_POINTER_IN_LIST(listObj) { - if (POINTER == NULL) { - return NULL; - } if (n-- == 0) { return POINTER; } @@ -179,7 +176,6 @@ void nf_addToList(Object* dest, const Object src) static const char* errorText[] = {"MISMATCHED_PARENS", "NULL_ENV", "EMPTY_ENV", - "BUILT_IN_NOT_FOUND", "NULL_PARSE", "NULL_LAMBDA_LIST", "NULL_MAP_ARGS", @@ -189,7 +185,6 @@ static const char* errorText[] = {"MISMATCHED_PARENS", "LISTS_NOT_SAME_SIZE", "BAD_NUMBER", "UNSUPPORTED_NUMBER_TYPE", - "NOT_A_SYMBOL", "ONLY_ONE_ARGUMENT", "NOT_A_LIST", "SCRIPT_NOT_FOUND", @@ -279,9 +274,6 @@ int stringStruct(char* dest, const Object* obj) int stringNObj(char* dest, const Object* obj, const size_t len) { const char* initial = dest; - if (!dest || !obj) { - return 0; - } switch (obj->type) { case TYPE_NUMBER: @@ -396,8 +388,6 @@ void printType(const Object* obj) } } -void nestedPrintList(const Object* list, int newline); - void _printObj(const Object* obj, int newline) { #ifdef DEBUG @@ -440,29 +430,12 @@ inline void printObj(const Object* obj) _printObj(obj, 1); } -void nestedPrintList(const Object* list, int newline) -{ - printf("("); - if (list && isListy(*list)) { - FOR_POINTER_IN_LIST(list) { - printf(" "); - _printObj(POINTER, 0); - } - } - printf(" )"); - - if (newline) { - printf("\n"); - } -} - #endif /** * Performs appropriate free() on a given Object and NULLs its ->forward - * Returns immediately if param is NULL * - * Strings: The Object's ->string is freed and NULLed + * Strings: The Object's ->string is freed * Lists: deleteList() is called on the Object (may recurse) * Lambdas: The body and params are cleaned, and the lambda itself is freed * @@ -470,24 +443,22 @@ void nestedPrintList(const Object* list, int newline) */ void cleanObject(Object* target) { - if (target == NULL) { - return; - } - switch (target->type) { case TYPE_STRING: case TYPE_SYMBOL: free(target->string); - target->string = NULL; break; case TYPE_LIST: case TYPE_SLIST: deleteList(target); break; case TYPE_LAMBDA: - cleanObject(&target->lambda->params); - cleanObject(&target->lambda->body); - free(target->lambda); + target->lambda->refs -= 1; + if (!target->lambda->refs) { + cleanObject(&target->lambda->params); + cleanObject(&target->lambda->body); + free(target->lambda); + } break; case TYPE_STRUCT: for (int i = 0; i < global()->structDefs[target->structObject->definition].fieldCount; i++) { @@ -495,14 +466,12 @@ void cleanObject(Object* target) } free(target->structObject->fields); free(target->structObject); - target->structObject = NULL; break; case TYPE_ERROR: #ifndef SIMPLE_ERRORS free(target->error->plContext); free(target->error->context); free(target->error); - target->error = NULL; #endif break; case TYPE_OTHER: @@ -515,8 +484,6 @@ void cleanObject(Object* target) case TYPE_FUNC: break; } - - target->forward = NULL; } /** @@ -553,18 +520,10 @@ void deleteList(Object* dest) cleanObject(prevMarch); free(prevMarch); } - dest->list = NULL; } void _copyList(Object* dest, const Object* src, int delete) { - if (!dest || !src) { printd("NULL\n"); - return; - } - if (!isListy(*dest) || !isListy(*src)) { printd("NOT A LIST\n"); - return; - } - if (delete) { deleteList(dest); } @@ -684,7 +643,8 @@ inline int isValidType(const Object test) */ inline Object cloneLambda(const Object old) { - return constructLambda(&old.lambda->params, &old.lambda->body, NULL); + old.lambda->refs += 1; + return old; } Object cloneString(Object obj) @@ -796,6 +756,7 @@ inline Object constructLambda(const Object* params, const Object* body, struct E o.lambda = malloc(sizeof(struct Lambda)); o.lambda->params = listObject(); o.lambda->body = listObject(); + o.lambda->refs = 1; copyList(&o.lambda->params, params); copyList(&o.lambda->body, body); diff --git a/src/object.h b/src/object.h index c51e9e7..824d71e 100644 --- a/src/object.h +++ b/src/object.h @@ -44,7 +44,6 @@ enum errorCode { MISMATCHED_PARENS, NULL_ENV, EMPTY_ENV, - BUILT_IN_NOT_FOUND, NULL_PARSE, NULL_LAMBDA_LIST, NULL_MAP_ARGS, @@ -54,7 +53,6 @@ enum errorCode { LISTS_NOT_SAME_SIZE, BAD_NUMBER, UNSUPPORTED_NUMBER_TYPE, - NOT_A_SYMBOL, ONLY_ONE_ARGUMENT, NOT_A_LIST, SCRIPT_NOT_FOUND, @@ -120,11 +118,11 @@ struct StructDef { struct StructObject { int definition; - //struct StructDef *definition; struct Object* fields; // Order should match that in the definition. }; struct Lambda { + int refs; Object params; Object body; }; diff --git a/src/pebblisp.c b/src/pebblisp.c index 0061833..3fe7f60 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -39,17 +39,6 @@ Object evalDefArgs(const Object* symbol, const Object* value, { const char* name = symbol->string; - // Handles multi-definitions - if (bothAre(TYPE_LIST, symbol, value) && - listLength(symbol) == listLength(value)) { - FOR_POINTERS_IN_LISTS(symbol, value) { - Object finalValue = eval(P2, env); - addToEnv(env, P1->string, finalValue); - cleanObject(&finalValue); - } - return cloneObject(*symbol); - } - Object finalValue = eval(value, env); addToEnv(env, name, finalValue); @@ -87,9 +76,7 @@ Object evalStructArgs(const Object* symbol, const Object* fields, struct Environ } } - while (env->outer) { - env = env->outer; - } + env = global(); env->structDefs[env->structCount] = def; env->structCount += 1; @@ -157,12 +144,9 @@ Object evalMapArgs(const Object* argForms, struct Environment* env) } Object evalBuiltIns(const Object* first, const Object* rest, - struct Environment* env) + struct Environment* env, int* found) { - if (first->type != TYPE_SYMBOL) { - return errorObject(NOT_A_SYMBOL); - } - + *found = 1; if (strcmp(first->string, "def") == 0) { return evalDefArgs(rest, rest->forward, env); #ifndef LOW_MEM @@ -182,7 +166,8 @@ Object evalBuiltIns(const Object* first, const Object* rest, return evalStructArgs(rest, rest->forward, env); } - return errorObject(BUILT_IN_NOT_FOUND); + *found = 0; + return *first; } /** @@ -296,37 +281,28 @@ Object evalList(const Object* obj, struct Environment* env) } Object* first_form = obj->list; - { // Try to eval built-ins - Object builtIn = evalBuiltIns(first_form, first_form->forward, env); - - if (!isError(builtIn, BUILT_IN_NOT_FOUND) && - !isError(builtIn, NOT_A_SYMBOL)) { + if (first_form->type == TYPE_SYMBOL) { + int found; + Object builtIn = evalBuiltIns(first_form, first_form->forward, env, &found); + if (found) { return builtIn; } - cleanObject(&builtIn); - } - int def = -1; - if (first_form->type == TYPE_SYMBOL) { struct Environment* outerEnv = global(); for (int i = 0; i < outerEnv->structCount; i++) { if (strcmp(first_form->string, outerEnv->structDefs[i].name) == 0) { - def = i; - break; + Object structo = structObject(i); + int s = 0; + FOR_POINTER_IN_LIST(obj) { + if (s != 0) { // Skip the field name + structo.structObject->fields[s - 1] = eval(POINTER, env); + } + s++; + } + return structo; } } } - if (def >= 0) { - Object structo = structObject(def); - int i = 0; - FOR_POINTER_IN_LIST(obj) { - if (i != 0) { - structo.structObject->fields[i - 1] = eval(POINTER, env); - } - i++; - } - return structo; - } // Evaluate the list based on the first element's type Object first_eval = eval(first_form, env); @@ -338,7 +314,7 @@ Object evalList(const Object* obj, struct Environment* env) case TYPE_LAMBDA: return listEvalLambda(&first_eval, first_form->forward, env); - default: { // Return list with each element evaluated + default: { // Return list with each element evaluated Object list = listObject(); int i = 0; nf_addToList(&list, first_eval); @@ -597,7 +573,7 @@ Object parseEval(const char* input, struct Environment* env) cleanObject(&obj); Object parsed = parse(tok).obj; if (parsed.type == TYPE_ERROR) { - obj = parsed; // TODO Check necessity + obj = parsed; // TODO Check necessity obj.error->plContext = malloc(sizeof(struct Slice)); *obj.error->plContext = *lastOpen; break; @@ -749,10 +725,6 @@ int main(int argc, const char* argv[]) action.sa_sigaction = handler; sigaction(SIGSEGV, &action, NULL); - // struct Environment* e = &env; - // e += 10000; - // printEnv(e); - readFile(SCRIPTDIR "/lib.pbl", &env); if (argc >= 2) { FILE* file = fopen(argv[1], "r"); diff --git a/src/tokens.c b/src/tokens.c index 9257634..036b6c5 100644 --- a/src/tokens.c +++ b/src/tokens.c @@ -65,8 +65,6 @@ struct Slice* nf_tokenize(const char* input, struct Error* err) int parens = 0; while (input[i] != '\0') { int l = 1; - // printd("input: '%c'\n", input[i]); - if (isWhitespace(input[i]) || input[i] == ';') { if (input[i] == '\n') { lineNumber++;