diff --git a/src/object.c b/src/object.c index 16a9af9..9bbbcbe 100644 --- a/src/object.c +++ b/src/object.c @@ -17,6 +17,12 @@ #define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) #endif +#define FOR_POINTER_IN_LIST(_list) \ + for(Object *_element = _list->list; \ + _element != NULL;\ + _element = _element->forward) +#define POINTER _element + /** * Returns the length of a given list Object * @param listObj The list to get the length of @@ -27,15 +33,16 @@ int listLength(const Object *listObj) if(!listObj || listObj->type != TYPE_LIST) return -1; - Object *march = listObj->list; int len = 0; - while(march) { - march = march->forward; + FOR_POINTER_IN_LIST(listObj) { len++; } return len; } +Object len(Object obj1, Object ignore) + { return numberObject(listLength(&obj1)); } + /** * Returns a pointer to the Object at the given index in a given list * @param listObj The list to fetch an Object from @@ -296,11 +303,9 @@ void printObj(const Object *obj) void _printList(const Object *list, int newline) { printf("("); - const Object *tail = list->list; - while(tail != NULL) { + FOR_POINTER_IN_LIST(list) { printf(" "); - _printObj(tail, 0); - tail = tail->forward; + _printObj(POINTER, 0); } printf(" )"); @@ -326,6 +331,7 @@ void cleanObject(Object *target) } else if(t == TYPE_LIST) { deleteList(target); } + target->forward = NULL; } void printAndClean(Object *target) @@ -335,7 +341,7 @@ void printAndClean(Object *target) } // Frees all objects in a list -void deleteList(const Object *dest) +void deleteList(Object *dest) { if(!dest) return; @@ -352,6 +358,7 @@ void deleteList(const Object *dest) cleanObject(prevMarch); free(prevMarch); } + dest->list = NULL; } /** @@ -365,10 +372,8 @@ void copyList(Object *dest, const Object *src) return; deleteList(dest); - const Object *march = src->list; - while(march != NULL) { - nf_addToList(dest, *march); - march = march->forward; + FOR_POINTER_IN_LIST(src) { + nf_addToList(dest, *POINTER); } } diff --git a/src/object.h b/src/object.h index a3630b6..d485d27 100644 --- a/src/object.h +++ b/src/object.h @@ -10,6 +10,7 @@ enum errorCode { BAD_LIST_OF_SYMBOL_STRINGS, TYPE_LIST_NOT_CAUGHT, NULL_ENV, + EMPTY_ENV, BUILT_IN_NOT_FOUND, NULL_PARSE, NULL_LAMBDA_LIST, @@ -26,6 +27,7 @@ static const char *errorText[] = { "BAD_LIST_OF_SYMBOL_STRINGS", "TYPE_LIST_NOT_CAUGHT", "NULL_ENV", + "EMPTY_ENV", "BUILT_IN_NOT_FOUND", "NULL_PARSE", "NULL_LAMBDA_LIST", @@ -84,7 +86,7 @@ Object *tail(const Object *listObj); void insertIntoList(Object *dest, unsigned ind, const Object src); void replaceListing(Object *list, int i, const Object src); void nf_addToList(Object *dest, Object src); -void deleteList(const Object *dest); +void deleteList(Object *dest); int listLength(const Object *listObj); Object *itemAt(const Object *listObj, int n); @@ -104,4 +106,7 @@ Object numberObject(int num); Object errorObject(enum errorCode err); Object constructLambda(const Object *params, const Object *body); +// Object version of listLength() +Object len(Object obj1, Object ignore); + #endif diff --git a/src/pebblisp.c b/src/pebblisp.c index 8551dc9..a35e172 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -34,16 +34,23 @@ Object fetchFromEnvironment(const char *name, struct Environment *env) if(!env) return errorObject(NULL_ENV); - printd("Fetching '%s' from env\n", name); + if(env->size == 0) + return errorObject(EMPTY_ENV); + + printf("Fetching '%s' from env\n", name); // printEnv(env); for(int i = 0; i < env->size; i++) { + printf("Try %d\n", i); + if(env->strings[i] == NULL) + break; if(strcmp(name, env->strings[i]) == 0) { return env->objects[i]; } } - printd("Trying outer\n"); + printf("Trying outer %p\n", env->outer); if(env->outer) { + printEnv(env->outer); return fetchFromEnvironment(name, env->outer); } @@ -121,15 +128,15 @@ Object evalDefArgs(const Object *arg_forms, struct Environment *env) Object evalIfArgs(const Object *arg_forms, struct Environment *env) { - printf("eval(arg_forms):\n "); + printd("eval(arg_forms):\n "); Object o = eval(arg_forms, env); - printObj(&o); - printf("eval(arg_forms->forward):\n "); + debugObj(&o); + printd("eval(arg_forms->forward):\n "); o = eval(arg_forms->forward, env); - printObj(&o); - printf("eval(arg_forms->forward->forward):\n "); + debugObj(&o); + printd("eval(arg_forms->forward->forward):\n "); o = eval(arg_forms->forward->forward, env); - printObj(&o); + debugObj(&o); return eval(arg_forms, env).number? eval(arg_forms->forward, env) : eval(arg_forms->forward->forward, env); @@ -177,26 +184,30 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms, printd("envForLambda()\n"); debugObj(arg_forms); - int length = listLength(params); + int paramCount = listLength(params); struct Environment env = { .outer = outer, .strings = NULL, .objects = NULL, - .size = length + .size = paramCount }; - if(length == 0) + if(paramCount == 0) return env; - env.strings = calloc(sizeof(char*), length + 1); - env.objects = malloc(sizeof(Object) * length + 1); + env.strings = calloc(sizeof(char*), paramCount + 1); + env.objects = malloc(sizeof(Object) * paramCount + 1); - const Object *o = arg_forms; - for(int i = 0; i < length; i++) { - const char *n = itemAt(params, i)->name; - addToEnv(&env, n, eval(o, outer)); // Could use eval_forms? - o = o->forward; + const Object *march = arg_forms; + printf("Param count: %d\n", paramCount); + for(int i = 0; i < paramCount; i++) { + const char *newObjName = itemAt(params, i)->name; + const Object newEnvObj = eval(march, outer); + printf("Adding new object '%s' to lambda env: ", newObjName); + printObj(&newEnvObj); + addToEnv(&env, newObjName, newEnvObj); // Could use eval_forms? + march = march->forward; } return env; @@ -208,6 +219,7 @@ Object evalBuiltIns(const Object *first, const Object *rest, if(strcmp(first->name, "def") == 0) { return evalDefArgs(rest, env); } else if(strcmp(first->name, "if") == 0) { + // Seems `rest` is the next *input*, not the next list item return evalIfArgs(rest, env); } else if(strcmp(first->name, "fn") == 0) { return evalLambdaArgs(rest); @@ -226,6 +238,8 @@ void eval_forms(Object *destList, const Object *src, struct Environment *env) } } +static int depth = 0; + Object eval(const Object *obj, struct Environment *env) { printd("eval():\n"); @@ -236,7 +250,13 @@ Object eval(const Object *obj, struct Environment *env) return *obj; // Return as is case TYPE_SYMBOL: - return fetchFromEnvironment(obj->name, env); + { + depth++; + printf("depth: %d\n", depth); + const Object oi = fetchFromEnvironment(obj->name, env); + depth--; + return oi; + } case TYPE_LIST: { @@ -310,11 +330,15 @@ void addToEnv(struct Environment *env, const char *name, const Object obj) env->strings[i] = calloc(sizeof(char), strlen(name) + 1); strncpy(env->strings[i], name, strlen(name)); env->objects[i] = obj; + // if(obj.type == TYPE_LIST) + // copyList(&env->objects[i], &obj); return; } if(strcmp(env->strings[i], name) == 0) { cleanObject(&env->objects[i]); env->objects[i] = obj; + // if(obj.type == TYPE_LIST) + // copyList(&env->objects[i], &obj); return; } } @@ -427,6 +451,7 @@ struct Environment defaultEnv() { addFunc("=", &equ, &e); addFunc(">", >h, &e); addFunc("<", <h, &e); + addFunc("len", &len, &e); return e; }