diff --git a/src/env.c b/src/env.c index 529bd9d..0a266f0 100644 --- a/src/env.c +++ b/src/env.c @@ -41,9 +41,6 @@ Object fetchFromEnvironment(const char *name, struct Environment *env) struct Environment envForLambda(const Object *params, const Object *arg_forms, struct Environment *outer) { - printd("envForLambda()\n"); - debugObj(arg_forms); - int paramCount = listLength(params); struct Environment env = { @@ -60,12 +57,9 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms, env.objects = malloc(sizeof(Object) * paramCount + 1); const Object *march = arg_forms; - printd("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); - printd("Adding new object '%s' to lambda env: ", newObjName); - debugObj(&newEnvObj); addToEnv(&env, newObjName, newEnvObj); // Could use eval_forms? march = march->forward; } diff --git a/src/object.c b/src/object.c index daa3222..81a3fbb 100644 --- a/src/object.c +++ b/src/object.c @@ -28,9 +28,7 @@ int listLength(const Object *listObj) return -1; int len = 0; - FOR_POINTER_IN_LIST(listObj) { - len++; - } + FOR_POINTER_IN_LIST(listObj) { len++; } return len; } @@ -48,13 +46,12 @@ Object *itemAt(const Object *listObj, int n) if(!listObj || listObj->type != TYPE_LIST) return NULL; - Object *march = listObj->list; - for(int i = 0; i < n; i++) { - if(march == NULL) + FOR_POINTER_IN_LIST(listObj) { + if(POINTER == NULL) return NULL; - march = march->forward; + if(n-- == 0) + return POINTER; } - return march; } /** @@ -67,11 +64,11 @@ Object *tail(const Object *listObj) if(!listObj || listObj->type != TYPE_LIST) return NULL; - Object *march = listObj->list; - while(march->forward != NULL) { - march = march->forward; + Object *tail = NULL; + FOR_POINTER_IN_LIST(listObj) { + tail = POINTER; } - return march; + return tail; } /** @@ -135,30 +132,22 @@ void allocObject(Object **spot, const Object src) */ void insertIntoList(Object *dest, unsigned ind, const Object src) { - // Only work with non-null list types if(!dest || dest->type != TYPE_LIST) return; - if(isEmpty(dest)) { - allocObject(&dest->list, src); + // Merely append, when possible + if(ind >= listLength(dest)) { + nf_addToList(dest, src); return; } - // TODO Check for off-by-one errors - // ensure pointers connect old and new - Object *march = dest->list; - for(unsigned i = 1; i < ind; i++) { - if(march->forward == NULL) { - allocObject(&march->forward, src); - return; - } - march = march->forward; - } + // The objects to preceed and follow the new one + Object *beforeNew = itemAt(dest, ind - 1); + Object *afterNew = beforeNew->forward; - // Save and re-apply current march->forward - Object *oldForward = march->forward; - allocObject(&march->forward, src); - march->forward->forward = oldForward; + // Replace the `before` object's pointer + allocObject(&beforeNew->forward, src); + beforeNew->forward->forward = afterNew; } /** @@ -174,9 +163,10 @@ void replaceListing(Object *list, int i, const Object src) if(!list || list->type != TYPE_LIST) return; Object *replace = itemAt(list, i); + Object *oldForward = replace->forward; cleanObject(replace); *replace = src; - replace->forward = NULL; + replace->forward = oldForward; } /** @@ -211,13 +201,11 @@ void stringList(char *dest, const Object *obj) dest[0] = '('; dest[1] = '\0'; - const Object *tail = obj->list; - while(tail != NULL) { + FOR_POINTER_IN_LIST(obj) { strcat(dest, " "); char tok[90] = ""; - stringObj(tok, tail); + stringObj(tok, POINTER); strcat(dest, tok); - tail = tail->forward; } strcat(dest, " )"); } @@ -363,7 +351,8 @@ void deleteList(Object *dest) dest->list = NULL; } -void _copyList(Object *dest, const Object *src, int delete) { +void _copyList(Object *dest, const Object *src, int delete) +{ if(!dest || !src) { printd("NULL\n"); return; @@ -377,7 +366,6 @@ void _copyList(Object *dest, const Object *src, int delete) { deleteList(dest); FOR_POINTER_IN_LIST(src) { - debugObj(POINTER); nf_addToList(dest, *POINTER); if(POINTER->type == TYPE_LIST) { tail(dest)->list = NULL; @@ -385,16 +373,22 @@ void _copyList(Object *dest, const Object *src, int delete) { } } } + /** * Does a deep copy of all items from `src` to `dest` * Does nothing if either is NULL, or not a list type - * Deletes all items from `dest` before copying + * Does a shallow delete of items from `dest` before copying */ void copyList(Object *dest, const Object *src) { _copyList(dest, src, 1); } +void appendList(Object *dest, const Object *src) +{ + _copyList(dest, src, 0); +} + // Returns a basic object with NULL forward and the given `type` inline Object newObject(Type type) { diff --git a/src/object.h b/src/object.h index 99477fc..afb70cb 100644 --- a/src/object.h +++ b/src/object.h @@ -80,7 +80,7 @@ struct Object { Object *list; char name[MAX_TOK_LEN]; char *string; - Object (*func)(Object, Object, struct Environment *env); + Object (*func)(Object, Object, struct Environment *); struct Lambda *lambda; // Maybe better as not a pointer? enum errorCode err; }; @@ -97,7 +97,6 @@ void printList(const Object *list); void printObj(const Object *obj); void debugObj(const Object *obj); void printErr(const Object *obj); -int wasMalloc(const Object *obj); int getType(const Object *obj); int isEmpty(const Object *obj); @@ -114,6 +113,7 @@ void copyList(Object *dest, const Object *src); void cleanObject(Object *target); void printAndClean(Object *target); void allocObject(Object **spot, const Object src); +void appendList(Object *dest, const Object *src); Object newObject(Type type); Object listObject(); diff --git a/src/pebblisp.c b/src/pebblisp.c index 706630b..2699a4e 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -20,17 +20,17 @@ void copySlice(char * dest, struct Slice *src) void debugSlice(struct Slice *s) { if(!s) { - printd("NULL SLICE\n"); + printf("NULL SLICE\n"); return; } - printd("Debug Slice\n text:'"); + printf("Debug Slice\n text:'"); for(int i = 0; i < s->length; i++) { - printd("%c", s->text[i]); + printf("%c", s->text[i]); if(s->text[i] == '\0') - printd("NULLCHAR\n"); + printf("NULLCHAR\n"); } - printd("'\n"); - printd(" length: %d\n", s->length); + printf("'\n"); + printf(" length: %d\n", s->length); } Result parse(struct Slice *slices) @@ -220,7 +220,10 @@ Object eval(const Object *obj, struct Environment *env) return ret; } else { - return *obj; + Object newList = listObject(); + copyList(&newList, obj); + return newList; + //return *obj; } } case TYPE_LAMBDA: @@ -356,19 +359,26 @@ Object parseEval(const char *input, struct Environment *env) int parens = 0; Object obj; struct Slice *tok = tokens; - while(tok[i].text != NULL) { - if(tok[i].text[0] == '(') { - parens++; - } else if(tok[i].text[0] == ')') { - parens--; - if(parens == 0) { - Object parsed = parse(tok).obj; - tok = &tok[i + 1]; - i = -1; - obj = eval(&parsed, env); + if(tok[i].text[0] != '(') { + Object parsed = parse(tok).obj; + obj = eval(&parsed, env); + cleanObject(&parsed); + } else { + while(tok[i].text != NULL) { + if(tok[i].text[0] == '(') { + parens++; + } else if(tok[i].text[0] == ')') { + parens--; + if(parens == 0) { + Object parsed = parse(tok).obj; + tok = &tok[i + 1]; + i = -1; + obj = eval(&parsed, env); + cleanObject(&parsed); + } } + i++; } - i++; } free(tokens); return obj; @@ -394,11 +404,13 @@ int main(int argc, const char* argv[]) for(int i = 1; i < argc; i++) { // cleanObject(&r); r = parseEval(argv[i], &env); + printAndClean(&r); } - printObj(&r); - // printAndClean(&r); + // printObj(&r); + //printAndClean(&r); } else { repl(&env); } + // deleteEnv(&env); } #endif diff --git a/src/pebblisp.h b/src/pebblisp.h index 34e571f..4bfa11e 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -49,13 +49,13 @@ Result result(Object obj, struct Slice *slices); void copySlice(char * dest, struct Slice *src); void debugSlice(struct Slice *s); -#define bopf(_name) \ +#define BASIC_OP(_name) \ Object _name(Object obj1, Object obj2, struct Environment *env); -bopf(add); bopf(sub); -bopf(mul); bopf(dvi); -bopf(mod); bopf(equ); -bopf(gth); bopf(lth); -#undef bopf +BASIC_OP(add); BASIC_OP(sub); +BASIC_OP(mul); BASIC_OP(dvi); +BASIC_OP(mod); BASIC_OP(equ); +BASIC_OP(gth); BASIC_OP(lth); +#undef BASIC_OP Object catObjects(const Object obj1, const Object obj2, struct Environment *env); #endif diff --git a/src/tokens.c b/src/tokens.c index cc7ab1a..81ea9d3 100644 --- a/src/tokens.c +++ b/src/tokens.c @@ -80,12 +80,12 @@ struct Slice *nf_tokenize(const char *input) i++; } else if(input[i] == '"') { - while(input[++i] != '"') { + while(input[++i] != '"' && input[i] != '\0') { l++; } i++; } else { - while(!isWhitespace(input[++i]) && !isSingle(input[i])) { + while(!isWhitespace(input[++i]) && !isSingle(input[i]) && input[i] != '\0') { l++; } }