Reference count strings.

This commit is contained in:
Sage Vaillancourt 2022-03-28 09:56:24 -04:00 committed by Sage Vaillancourt
parent ded215a1cb
commit e22e022cd8
6 changed files with 32 additions and 21 deletions

View File

@ -32,7 +32,7 @@ run:
install: install:
cp -pf ./$(exe) $(BINPREFIX) cp -pf ./$(exe) $(BINPREFIX)
mkdir -p $(SCRIPTDIR) mkdir -p $(SCRIPTDIR)
cp ./examples/* $(SCRIPTDIR) cp -r ./examples/* $(SCRIPTDIR)
uninstall: uninstall:
rm $(BINPREFIX)/$(exe) rm $(BINPREFIX)/$(exe)

View File

@ -363,6 +363,8 @@ int runTests(int detailed)
printf(""); printf("");
} }
printf("%d tests failed!\n", failureCount); printf("%d tests failed!\n", failureCount);
// fprintf(stderr, "TOTAL ALLOCATIONS: %d\n", getAllocations());
// fprintf(stderr, "TOTAL BYTES: %zu\n", getBytes());
return failureCount; return failureCount;
} }

View File

@ -207,7 +207,7 @@ int stringList(char* dest, const Object* obj)
dest += sprintf(dest, "("); dest += sprintf(dest, "(");
FOR_POINTER_IN_LIST(obj) { FOR_POINTER_IN_LIST(obj) {
char tok[90] = ""; char tok[256] = "";
stringObj(tok, POINTER); stringObj(tok, POINTER);
dest += sprintf(dest, " %s", tok); dest += sprintf(dest, " %s", tok);
} }
@ -439,7 +439,9 @@ void cleanObject(Object* target)
switch (target->type) { switch (target->type) {
case TYPE_STRING: case TYPE_STRING:
case TYPE_SYMBOL: case TYPE_SYMBOL:
free(target->string); if (!(target->string[-1] -= 1)) {
free(target->string - 1);
}
break; break;
case TYPE_LIST: case TYPE_LIST:
case TYPE_SLIST: case TYPE_SLIST:
@ -642,9 +644,7 @@ inline Object cloneLambda(const Object old)
Object cloneString(Object obj) Object cloneString(Object obj)
{ {
const char* string = obj.string; obj.string[-1] += 1;
obj.string = malloc(sizeof(char) * (strlen(string) + 1));
strcpy(obj.string, string);
return obj; return obj;
} }
@ -721,9 +721,19 @@ inline Object stringFromSlice(const char* string, int len)
inline Object symFromSlice(const char* string, int len) inline Object symFromSlice(const char* string, int len)
{ {
Object o = newObject(TYPE_SYMBOL); Object o = withLen(len, TYPE_SYMBOL);
o.string = calloc(sizeof(char), len + 1); snprintf(o.string, len + 1, "%s", string);
strncpy(o.string, string, len); return o;
}
/// Creates a stringy object with room for a reference-count prefix and trailing null byte.
/// Thus, withLen(3, TYPE_STRING) will actually allocate a 5-byte "string".
inline Object withLen(int len, enum Type type)
{
Object o = newObject(type);
o.string = malloc(sizeof(char) * (len + 2));
o.string[0] = 1;
o.string += 1;
return o; return o;
} }

View File

@ -201,6 +201,8 @@ Object stringFromSlice(const char* string, int len);
Object symFromSlice(const char* string, int len); Object symFromSlice(const char* string, int len);
Object withLen(int len, enum Type type);
Object boolObject(int b); Object boolObject(int b);
Object numberObject(int num); Object numberObject(int num);

View File

@ -714,8 +714,8 @@ int main(int argc, const char* argv[])
} }
deleteEnv(&env); deleteEnv(&env);
shredDictionary(); shredDictionary();
// printf("TOTAL ALLOCATIONS: %d\n", getAllocations()); // fprintf(stderr, "TOTAL ALLOCATIONS: %d\n", getAllocations());
// printf("TOTAL BYTES: %d\n", getBytes()); // fprintf(stderr, "TOTAL BYTES: %zu\n", getBytes());
} }
#endif #endif

View File

@ -25,20 +25,18 @@ Object charAt(Object* params, int length, struct Environment* env)
Object string = params[0]; Object string = params[0];
Object at = params[1]; Object at = params[1];
char* c = malloc(sizeof(char) * 2); Object c = withLen(1, string.type);
c[1] = '\0'; c.string[1] = '\0';
for (int i = 0; i < at.number; i++) { for (int i = 0; i < at.number; i++) {
if (string.string[i] == '\0') { if (string.string[i] == '\0') {
c[0] = '\0'; c.string[0] = '\0';
string.string = c; return c;
return string;
} }
} }
c[0] = string.string[at.number]; c.string[0] = string.string[at.number];
string.string = c; return c;
return string;
} }
Object filter(Object* params, int length, struct Environment* env) Object filter(Object* params, int length, struct Environment* env)
@ -216,8 +214,7 @@ Object _catObjects(Object obj1, Object obj2, struct Environment* env)
cleanObject(&evalObj1); cleanObject(&evalObj1);
cleanObject(&evalObj2); cleanObject(&evalObj2);
Object o = newObject(TYPE_STRING); Object o = withLen(length, TYPE_STRING);
o.string = malloc(sizeof(char) * length + 1);
sprintf(o.string, "%s%s", str1, str2); sprintf(o.string, "%s%s", str1, str2);
return o; return o;