Implement liberal string copying and destruction

This commit is contained in:
= 2020-05-15 21:28:16 +01:00
parent 82f1f03d7b
commit f488e29c54
4 changed files with 25 additions and 7 deletions

View File

@ -165,7 +165,7 @@ struct Environment defaultEnv()
parseEval("(def min (fn (a b) (if (< a b) a b)))", &e); 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 ad (fn (a) (if (> a 10) a (ad (* 10 a) ))))", &e);
parseEval("(def spent (fn (a) \ parseEval("(def spent (fn (a) \
(cat \"Tip: $\" (/ a 5) \".\" \ (cat \"Tip: $\" \"\" \"\" (/ a 5) \".\" \
(/ (* 100 (% a 5)) 5) \ (/ (* 100 (% a 5)) 5) \
) \ ) \
))", &e); ))", &e);

View File

@ -319,8 +319,8 @@ void cleanObject(Object *target)
// TODO Why does this break? // TODO Why does this break?
// Probably multiple objects referencing the same string // Probably multiple objects referencing the same string
// free(target->string); free(target->string);
// target->string = NULL; target->string = NULL;
} }
target->forward = NULL; target->forward = NULL;
} }
@ -367,10 +367,15 @@ void _copyList(Object *dest, const Object *src, int delete)
deleteList(dest); deleteList(dest);
FOR_POINTER_IN_LIST(src) { FOR_POINTER_IN_LIST(src) {
nf_addToList(dest, *POINTER);
if(POINTER->type == TYPE_LIST) { if(POINTER->type == TYPE_LIST) {
nf_addToList(dest, *POINTER);
tail(dest)->list = NULL; tail(dest)->list = NULL;
_copyList(tail(dest), POINTER, 0); _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; 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) inline Object toBool(const Object test)
{ {
if(test.number == 0) if(test.number == 0)

View File

@ -126,6 +126,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 copyString(Object obj);
// Object version of listLength() // Object version of listLength()
Object len(Object obj1, Object, struct Environment *); Object len(Object obj1, Object, struct Environment *);

View File

@ -92,8 +92,9 @@ Object eval(const Object *obj, struct Environment *env)
switch(obj->type) { switch(obj->type) {
case TYPE_NUMBER: case TYPE_NUMBER:
case TYPE_BOOL: case TYPE_BOOL:
case TYPE_STRING:
return *obj; // Return as is return *obj; // Return as is
case TYPE_STRING:
return copyString(*obj); // Return as is
case TYPE_SYMBOL: case TYPE_SYMBOL:
return fetchFromEnvironment(obj->name, env); return fetchFromEnvironment(obj->name, env);
@ -127,6 +128,7 @@ Object eval(const Object *obj, struct Environment *env)
Object func_eval = rest[0]; Object func_eval = rest[0];
for(int i = 1; i < length; i++) { for(int i = 1; i < length; i++) {
func_eval = first_eval.func(func_eval, rest[i], env); func_eval = first_eval.func(func_eval, rest[i], env);
cleanObject(&rest[i]);
} }
// deleteList(obj); // Decreases indirectly lost memory, but fails on Pebble // 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) Object catObjects(const Object obj1, const Object obj2, struct Environment *env)
{ {
const Object evalObj1 = eval(&obj1, env); Object evalObj1 = eval(&obj1, env);
const Object evalObj2 = eval(&obj2, env); Object evalObj2 = eval(&obj2, env);
char str1[100] = ""; char str1[100] = "";
char str2[100] = ""; char str2[100] = "";
stringObj(str1, &evalObj1); stringObj(str1, &evalObj1);
stringObj(str2, &evalObj2); stringObj(str2, &evalObj2);
cleanObject(&evalObj1);
cleanObject(&evalObj2);
int length = strlen(str1) + strlen(str2) + 1; int length = strlen(str1) + strlen(str2) + 1;
Object o = newObject(TYPE_STRING); Object o = newObject(TYPE_STRING);