Lead on nested function borkage (pebblisp.c:222)
This commit is contained in:
parent
3e62d57166
commit
96abccec7e
29
src/object.c
29
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue