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 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);
|
||||||
|
|
19
src/object.c
19
src/object.c
|
@ -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)
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue