#include #include #include "memory.h" #include "object.h" #include "table.h" #include "value.h" #include "vm.h" #define ALLOCATE_OBJ(type, objectType) \ (type*)allocateObject(sizeof(type), objectType) static Obj* allocateObject(size_t size, ObjType type) { Obj* object = (Obj*) reallocate(NULL, 0, size); object->type = type; object->next = vm.objects; vm.objects = object; return object; } 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, OBJ_VAL(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 ^= key[i]; hash *= 16777619; } return hash; } ObjArray* takeArray(ValueArray* valArray) { ObjArray* array = ALLOCATE_OBJ(ObjArray, OBJ_ARRAY); array->array = valArray; return array; } ObjHash* takeHash(Table* hashTable) { ObjHash* hash = ALLOCATE_OBJ(ObjHash, OBJ_HASH); hash->hashTable = hashTable; return hash; } ObjString* takeString(char* chars, int length) { uint32_t hash = hashString(chars, length); 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, hash); } void printObject(Value value) { switch (OBJ_TYPE(value)) { case OBJ_STRING: printf("%s", AS_CSTRING(value)); break; case OBJ_ARRAY: printf("["); ValueArray* array=AS_VARRAY(value); for (int i=0;icount;i++) { printValue(array->values[i]); if (i<(array->count-1)) { printf(", "); } } printf("]"); break; case OBJ_HASH: printf("{"); Table* hash=AS_HASH(value); Entry** entries=getEntries(hash); for (int i=0;entries[i]!=NULL;i++) { Entry* entry=entries[i]; printValue(entry->key); printf("=>"); printValue(entry->value); if (entries[i+1]!=NULL) { printf(", "); } } printf("}"); break; } }