From f488e29c5434b8055fef6abbeb45062ebe463c2b Mon Sep 17 00:00:00 2001 From: = <=> Date: Fri, 15 May 2020 21:28:16 +0100 Subject: [PATCH] Implement liberal string copying and destruction --- src/env.c | 2 +- src/object.c | 19 ++++++++++++++++--- src/object.h | 1 + src/pebblisp.c | 10 +++++++--- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/env.c b/src/env.c index 0a266f0..590f0af 100644 --- a/src/env.c +++ b/src/env.c @@ -165,7 +165,7 @@ struct Environment defaultEnv() parseEval("(def min (fn (a b) (if (< a b) a b)))", &e); parseEval("(def ad (fn (a) (if (> a 10) a (ad (* 10 a) ))))", &e); parseEval("(def spent (fn (a) \ - (cat \"Tip: $\" (/ a 5) \".\" \ + (cat \"Tip: $\" \"\" \"\" (/ a 5) \".\" \ (/ (* 100 (% a 5)) 5) \ ) \ ))", &e); diff --git a/src/object.c b/src/object.c index 0d359ad..e29b355 100644 --- a/src/object.c +++ b/src/object.c @@ -319,8 +319,8 @@ void cleanObject(Object *target) // TODO Why does this break? // Probably multiple objects referencing the same string - // free(target->string); - // target->string = NULL; + free(target->string); + target->string = NULL; } target->forward = NULL; } @@ -367,10 +367,15 @@ void _copyList(Object *dest, const Object *src, int delete) deleteList(dest); FOR_POINTER_IN_LIST(src) { - nf_addToList(dest, *POINTER); if(POINTER->type == TYPE_LIST) { + nf_addToList(dest, *POINTER); tail(dest)->list = NULL; _copyList(tail(dest), POINTER, 0); + } else if (POINTER->type == TYPE_STRING) { + Object t = copyString(*POINTER); + nf_addToList(dest, t); + } else { + nf_addToList(dest, *POINTER); } } } @@ -486,6 +491,14 @@ inline Object errorObject(enum errorCode err) return o; } +Object copyString(Object obj) +{ + const char* string = obj.string; + obj.string = malloc(sizeof(char) * (strlen(string) + 1)); + strcpy(obj.string, string); + return obj; +} + inline Object toBool(const Object test) { if(test.number == 0) diff --git a/src/object.h b/src/object.h index cd9c5fb..2233133 100644 --- a/src/object.h +++ b/src/object.h @@ -126,6 +126,7 @@ Object numberObject(int num); Object errorObject(enum errorCode err); Object constructLambda(const Object *params, const Object *body); +Object copyString(Object obj); // Object version of listLength() Object len(Object obj1, Object, struct Environment *); diff --git a/src/pebblisp.c b/src/pebblisp.c index 4255110..a831b1b 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -92,8 +92,9 @@ Object eval(const Object *obj, struct Environment *env) switch(obj->type) { case TYPE_NUMBER: case TYPE_BOOL: - case TYPE_STRING: return *obj; // Return as is + case TYPE_STRING: + return copyString(*obj); // Return as is case TYPE_SYMBOL: return fetchFromEnvironment(obj->name, env); @@ -127,6 +128,7 @@ Object eval(const Object *obj, struct Environment *env) Object func_eval = rest[0]; for(int i = 1; i < length; i++) { func_eval = first_eval.func(func_eval, rest[i], env); + cleanObject(&rest[i]); } // deleteList(obj); // Decreases indirectly lost memory, but fails on Pebble @@ -164,13 +166,15 @@ Result result(Object obj, struct Slice *slices) Object catObjects(const Object obj1, const Object obj2, struct Environment *env) { - const Object evalObj1 = eval(&obj1, env); - const Object evalObj2 = eval(&obj2, env); + Object evalObj1 = eval(&obj1, env); + Object evalObj2 = eval(&obj2, env); char str1[100] = ""; char str2[100] = ""; stringObj(str1, &evalObj1); stringObj(str2, &evalObj2); + cleanObject(&evalObj1); + cleanObject(&evalObj2); int length = strlen(str1) + strlen(str2) + 1; Object o = newObject(TYPE_STRING);