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__)
#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);
}
}

View File

@ -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

View File

@ -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(">", &gth, &e);
addFunc("<", &lth, &e);
addFunc("len", &len, &e);
return e;
}