diff options
Diffstat (limited to 'clox/src/object.c')
-rw-r--r-- | clox/src/object.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/clox/src/object.c b/clox/src/object.c index 9622327..361e315 100644 --- a/clox/src/object.c +++ b/clox/src/object.c @@ -3,6 +3,7 @@ #include "memory.h" #include "object.h" +#include "table.h" #include "value.h" #include "vm.h" @@ -18,22 +19,45 @@ static Obj *allocateObject(size_t size, ObjType type) { return object; } -static ObjString *allocateString(char *chars, int length) { +static ObjString *allocateString(char *chars, int length, uint32_t hash) { ObjString *string = ALLOCATE_OBJ(ObjString, OBJ_STRING); string->length = length; string->chars = chars; + string->hash = hash; + tableSet(&vm.strings, string, NIL_VAL); return string; } +static uint32_t hashString(const char *key, int length) { + uint32_t hash = 2166136261u; + for (int i = 0; i < length; i++) { + hash ^= (uint32_t)key[i]; + hash *= 16777619; + } + return hash; +} + ObjString *takeString(char *chars, int length) { - return allocateString(chars, length); + uint32_t hash = hashString(chars, length); + ObjString *interned = tableFindString(&vm.strings, chars, length, hash); + if (interned != NULL) { + FREE_ARRAY(char, chars, length + 1); + return interned; + } + + return allocateString(chars, length, hash); } ObjString *copyString(const char *chars, int length) { + uint32_t hash = hashString(chars, length); + ObjString *interned = tableFindString(&vm.strings, chars, length, hash); + if (interned != NULL) + return interned; + char *heapChars = ALLOCATE(char, length + 1); memcpy(heapChars, chars, length); heapChars[length] = '\0'; - return allocateString(heapChars, length); + return allocateString(heapChars, length, hash); } void printObject(Value value) { |