Lead on nested function borkage (pebblisp.c:222)

This commit is contained in:
= 2020-05-09 19:57:21 +01:00
parent 3e62d57166
commit 96abccec7e
3 changed files with 67 additions and 32 deletions

View File

@ -17,6 +17,12 @@
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) #define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
#endif #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 * Returns the length of a given list Object
* @param listObj The list to get the length of * @param listObj The list to get the length of
@ -27,15 +33,16 @@ int listLength(const Object *listObj)
if(!listObj || listObj->type != TYPE_LIST) if(!listObj || listObj->type != TYPE_LIST)
return -1; return -1;
Object *march = listObj->list;
int len = 0; int len = 0;
while(march) { FOR_POINTER_IN_LIST(listObj) {
march = march->forward;
len++; len++;
} }
return 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 * Returns a pointer to the Object at the given index in a given list
* @param listObj The list to fetch an Object from * @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) void _printList(const Object *list, int newline)
{ {
printf("("); printf("(");
const Object *tail = list->list; FOR_POINTER_IN_LIST(list) {
while(tail != NULL) {
printf(" "); printf(" ");
_printObj(tail, 0); _printObj(POINTER, 0);
tail = tail->forward;
} }
printf(" )"); printf(" )");
@ -326,6 +331,7 @@ void cleanObject(Object *target)
} else if(t == TYPE_LIST) { } else if(t == TYPE_LIST) {
deleteList(target); deleteList(target);
} }
target->forward = NULL;
} }
void printAndClean(Object *target) void printAndClean(Object *target)
@ -335,7 +341,7 @@ void printAndClean(Object *target)
} }
// Frees all objects in a list // Frees all objects in a list
void deleteList(const Object *dest) void deleteList(Object *dest)
{ {
if(!dest) if(!dest)
return; return;
@ -352,6 +358,7 @@ void deleteList(const Object *dest)
cleanObject(prevMarch); cleanObject(prevMarch);
free(prevMarch); free(prevMarch);
} }
dest->list = NULL;
} }
/** /**
@ -365,10 +372,8 @@ void copyList(Object *dest, const Object *src)
return; return;
deleteList(dest); deleteList(dest);
const Object *march = src->list; FOR_POINTER_IN_LIST(src) {
while(march != NULL) { nf_addToList(dest, *POINTER);
nf_addToList(dest, *march);
march = march->forward;
} }
} }

View File

@ -10,6 +10,7 @@ enum errorCode {
BAD_LIST_OF_SYMBOL_STRINGS, BAD_LIST_OF_SYMBOL_STRINGS,
TYPE_LIST_NOT_CAUGHT, TYPE_LIST_NOT_CAUGHT,
NULL_ENV, NULL_ENV,
EMPTY_ENV,
BUILT_IN_NOT_FOUND, BUILT_IN_NOT_FOUND,
NULL_PARSE, NULL_PARSE,
NULL_LAMBDA_LIST, NULL_LAMBDA_LIST,
@ -26,6 +27,7 @@ static const char *errorText[] = {
"BAD_LIST_OF_SYMBOL_STRINGS", "BAD_LIST_OF_SYMBOL_STRINGS",
"TYPE_LIST_NOT_CAUGHT", "TYPE_LIST_NOT_CAUGHT",
"NULL_ENV", "NULL_ENV",
"EMPTY_ENV",
"BUILT_IN_NOT_FOUND", "BUILT_IN_NOT_FOUND",
"NULL_PARSE", "NULL_PARSE",
"NULL_LAMBDA_LIST", "NULL_LAMBDA_LIST",
@ -84,7 +86,7 @@ Object *tail(const Object *listObj);
void insertIntoList(Object *dest, unsigned ind, const Object src); void insertIntoList(Object *dest, unsigned ind, const Object src);
void replaceListing(Object *list, int i, const Object src); void replaceListing(Object *list, int i, const Object src);
void nf_addToList(Object *dest, Object src); void nf_addToList(Object *dest, Object src);
void deleteList(const Object *dest); void deleteList(Object *dest);
int listLength(const Object *listObj); int listLength(const Object *listObj);
Object *itemAt(const Object *listObj, int n); Object *itemAt(const Object *listObj, int n);
@ -104,4 +106,7 @@ Object numberObject(int num);
Object errorObject(enum errorCode err); Object errorObject(enum errorCode err);
Object constructLambda(const Object *params, const Object *body); Object constructLambda(const Object *params, const Object *body);
// Object version of listLength()
Object len(Object obj1, Object ignore);
#endif #endif

View File

@ -34,16 +34,23 @@ Object fetchFromEnvironment(const char *name, struct Environment *env)
if(!env) if(!env)
return errorObject(NULL_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); // printEnv(env);
for(int i = 0; i < env->size; i++) { 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) { if(strcmp(name, env->strings[i]) == 0) {
return env->objects[i]; return env->objects[i];
} }
} }
printd("Trying outer\n"); printf("Trying outer %p\n", env->outer);
if(env->outer) { if(env->outer) {
printEnv(env->outer);
return fetchFromEnvironment(name, 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) 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); Object o = eval(arg_forms, env);
printObj(&o); debugObj(&o);
printf("eval(arg_forms->forward):\n "); printd("eval(arg_forms->forward):\n ");
o = eval(arg_forms->forward, env); o = eval(arg_forms->forward, env);
printObj(&o); debugObj(&o);
printf("eval(arg_forms->forward->forward):\n "); printd("eval(arg_forms->forward->forward):\n ");
o = eval(arg_forms->forward->forward, env); o = eval(arg_forms->forward->forward, env);
printObj(&o); debugObj(&o);
return eval(arg_forms, env).number? return eval(arg_forms, env).number?
eval(arg_forms->forward, env) : eval(arg_forms->forward, env) :
eval(arg_forms->forward->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"); printd("envForLambda()\n");
debugObj(arg_forms); debugObj(arg_forms);
int length = listLength(params); int paramCount = listLength(params);
struct Environment env = { struct Environment env = {
.outer = outer, .outer = outer,
.strings = NULL, .strings = NULL,
.objects = NULL, .objects = NULL,
.size = length .size = paramCount
}; };
if(length == 0) if(paramCount == 0)
return env; return env;
env.strings = calloc(sizeof(char*), length + 1); env.strings = calloc(sizeof(char*), paramCount + 1);
env.objects = malloc(sizeof(Object) * length + 1); env.objects = malloc(sizeof(Object) * paramCount + 1);
const Object *o = arg_forms; const Object *march = arg_forms;
for(int i = 0; i < length; i++) { printf("Param count: %d\n", paramCount);
const char *n = itemAt(params, i)->name; for(int i = 0; i < paramCount; i++) {
addToEnv(&env, n, eval(o, outer)); // Could use eval_forms? const char *newObjName = itemAt(params, i)->name;
o = o->forward; 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; return env;
@ -208,6 +219,7 @@ Object evalBuiltIns(const Object *first, const Object *rest,
if(strcmp(first->name, "def") == 0) { if(strcmp(first->name, "def") == 0) {
return evalDefArgs(rest, env); return evalDefArgs(rest, env);
} else if(strcmp(first->name, "if") == 0) { } else if(strcmp(first->name, "if") == 0) {
// Seems `rest` is the next *input*, not the next list item
return evalIfArgs(rest, env); return evalIfArgs(rest, env);
} else if(strcmp(first->name, "fn") == 0) { } else if(strcmp(first->name, "fn") == 0) {
return evalLambdaArgs(rest); 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) Object eval(const Object *obj, struct Environment *env)
{ {
printd("eval():\n"); printd("eval():\n");
@ -236,7 +250,13 @@ Object eval(const Object *obj, struct Environment *env)
return *obj; // Return as is return *obj; // Return as is
case TYPE_SYMBOL: 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: 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); env->strings[i] = calloc(sizeof(char), strlen(name) + 1);
strncpy(env->strings[i], name, strlen(name)); strncpy(env->strings[i], name, strlen(name));
env->objects[i] = obj; env->objects[i] = obj;
// if(obj.type == TYPE_LIST)
// copyList(&env->objects[i], &obj);
return; return;
} }
if(strcmp(env->strings[i], name) == 0) { if(strcmp(env->strings[i], name) == 0) {
cleanObject(&env->objects[i]); cleanObject(&env->objects[i]);
env->objects[i] = obj; env->objects[i] = obj;
// if(obj.type == TYPE_LIST)
// copyList(&env->objects[i], &obj);
return; return;
} }
} }
@ -427,6 +451,7 @@ struct Environment defaultEnv() {
addFunc("=", &equ, &e); addFunc("=", &equ, &e);
addFunc(">", &gth, &e); addFunc(">", &gth, &e);
addFunc("<", &lth, &e); addFunc("<", &lth, &e);
addFunc("len", &len, &e);
return e; return e;
} }