Implement liberal string copying and destruction
This commit is contained in:
parent
82f1f03d7b
commit
f488e29c54
|
@ -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);
|
||||
|
|
19
src/object.c
19
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)
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue