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 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);

View File

@ -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)

View File

@ -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 *);

View File

@ -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);