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__)
|
#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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(">", >h, &e);
|
addFunc(">", >h, &e);
|
||||||
addFunc("<", <h, &e);
|
addFunc("<", <h, &e);
|
||||||
|
addFunc("len", &len, &e);
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue