From 6f126e6daad7955d1e87acb4d5af333e01edadc1 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 18 Feb 2023 11:56:18 +0000 Subject: [PATCH] Minor tweaks and renames, as I'm documenting --- source/toy_interpreter.h | 2 -- source/toy_literal.c | 9 +++++---- source/toy_literal.h | 4 +++- source/toy_literal_dictionary.c | 30 +++++++++++++++--------------- source/toy_literal_dictionary.h | 6 +++--- source/toy_memory.c | 5 ++--- source/toy_memory.h | 17 ++++++++++------- source/toy_refstring.h | 5 ++++- source/toy_scope.c | 2 +- 9 files changed, 43 insertions(+), 37 deletions(-) diff --git a/source/toy_interpreter.h b/source/toy_interpreter.h index 05ae64b..8c8940e 100644 --- a/source/toy_interpreter.h +++ b/source/toy_interpreter.h @@ -6,8 +6,6 @@ #include "toy_literal_dictionary.h" #include "toy_scope.h" -typedef void (*Toy_PrintFn)(const char*); - //the interpreter acts depending on the bytecode instructions typedef struct Toy_Interpreter { //input diff --git a/source/toy_literal.c b/source/toy_literal.c index 2f42478..61944ce 100644 --- a/source/toy_literal.c +++ b/source/toy_literal.c @@ -155,7 +155,8 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) { } case TOY_LITERAL_IDENTIFIER: { - return TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_IDENTIFIER(original))); + //NOTE: could optimise this by copying the hash manually, but it's a very small increase in performance + return TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_IDENTIFIER(original))); } case TOY_LITERAL_TYPE: { @@ -404,13 +405,13 @@ int Toy_hashLiteral(Toy_Literal lit) { case TOY_LITERAL_FUNCTION: case TOY_LITERAL_FUNCTION_NATIVE: case TOY_LITERAL_FUNCTION_HOOK: - return 0; //can't hash these + return -1; //can't hash these case TOY_LITERAL_IDENTIFIER: return TOY_HASH_I(lit); //pre-computed case TOY_LITERAL_TYPE: - return TOY_AS_TYPE(lit).typeOf; //nothing else I can do + return -1; //not much i can really do case TOY_LITERAL_OPAQUE: case TOY_LITERAL_ANY: @@ -453,7 +454,7 @@ void Toy_printLiteral(Toy_Literal literal) { Toy_printLiteralCustom(literal, stdoutWrapper); } -void Toy_printLiteralCustom(Toy_Literal literal, void (printFn)(const char*)) { +void Toy_printLiteralCustom(Toy_Literal literal, Toy_PrintFn printFn) { switch(literal.type) { case TOY_LITERAL_NULL: printFn("null"); diff --git a/source/toy_literal.h b/source/toy_literal.h index a4fb6dc..ed7ad02 100644 --- a/source/toy_literal.h +++ b/source/toy_literal.h @@ -10,6 +10,7 @@ struct Toy_Interpreter; struct Toy_LiteralArray; typedef int (*Toy_NativeFn)(struct Toy_Interpreter* interpreter, struct Toy_LiteralArray* arguments); typedef int (*Toy_HookFn)(struct Toy_Interpreter* interpreter, struct Toy_Literal identifier, struct Toy_Literal alias); +typedef void (*Toy_PrintFn)(const char*); #include @@ -151,5 +152,6 @@ TOY_API Toy_Literal Toy_copyLiteral(Toy_Literal original); TOY_API bool Toy_literalsAreEqual(Toy_Literal lhs, Toy_Literal rhs); TOY_API int Toy_hashLiteral(Toy_Literal lit); +//not thread-safe TOY_API void Toy_printLiteral(Toy_Literal literal); -TOY_API void Toy_printLiteralCustom(Toy_Literal literal, void (printFn)(const char*)); +TOY_API void Toy_printLiteralCustom(Toy_Literal literal, Toy_PrintFn); diff --git a/source/toy_literal_dictionary.c b/source/toy_literal_dictionary.c index 7857c42..0dd7bdf 100644 --- a/source/toy_literal_dictionary.c +++ b/source/toy_literal_dictionary.c @@ -7,7 +7,7 @@ #include //util functions -static void setEntryValues(Toy_private_entry* entry, Toy_Literal key, Toy_Literal value) { +static void setEntryValues(Toy_private_dictionary_entry* entry, Toy_Literal key, Toy_Literal value) { //much simpler now Toy_freeLiteral(entry->key); entry->key = Toy_copyLiteral(key); @@ -16,7 +16,7 @@ static void setEntryValues(Toy_private_entry* entry, Toy_Literal key, Toy_Litera entry->value = Toy_copyLiteral(value); } -static Toy_private_entry* getEntryArray(Toy_private_entry* array, int capacity, Toy_Literal key, unsigned int hash, bool mustExist) { +static Toy_private_dictionary_entry* getEntryArray(Toy_private_dictionary_entry* array, int capacity, Toy_Literal key, unsigned int hash, bool mustExist) { //find "key", starting at index unsigned int index = hash % capacity; unsigned int start = index; @@ -26,7 +26,7 @@ static Toy_private_entry* getEntryArray(Toy_private_entry* array, int capacity, //literal probing and collision checking while (index != start) { //WARNING: this is the only function allowed to retrieve an entry from the array - Toy_private_entry* entry = &array[index]; + Toy_private_dictionary_entry* entry = &array[index]; if (TOY_IS_NULL(entry->key)) { //if key is empty, it's either empty or tombstone if (TOY_IS_NULL(entry->value) && !mustExist) { @@ -46,9 +46,9 @@ static Toy_private_entry* getEntryArray(Toy_private_entry* array, int capacity, return NULL; } -static void adjustEntryCapacity(Toy_private_entry** dictionaryHandle, int oldCapacity, int capacity) { +static void adjustEntryCapacity(Toy_private_dictionary_entry** dictionaryHandle, int oldCapacity, int capacity) { //new entry space - Toy_private_entry* newEntries = TOY_ALLOCATE(Toy_private_entry, capacity); + Toy_private_dictionary_entry* newEntries = TOY_ALLOCATE(Toy_private_dictionary_entry, capacity); for (int i = 0; i < capacity; i++) { newEntries[i].key = TOY_TO_NULL_LITERAL; @@ -62,19 +62,19 @@ static void adjustEntryCapacity(Toy_private_entry** dictionaryHandle, int oldCap } //place the key and value in the new array (reusing string memory) - Toy_private_entry* entry = getEntryArray(newEntries, capacity, TOY_TO_NULL_LITERAL, Toy_hashLiteral((*dictionaryHandle)[i].key), false); + Toy_private_dictionary_entry* entry = getEntryArray(newEntries, capacity, TOY_TO_NULL_LITERAL, Toy_hashLiteral((*dictionaryHandle)[i].key), false); entry->key = (*dictionaryHandle)[i].key; entry->value = (*dictionaryHandle)[i].value; } //clear the old array - TOY_FREE_ARRAY(Toy_private_entry, *dictionaryHandle, oldCapacity); + TOY_FREE_ARRAY(Toy_private_dictionary_entry, *dictionaryHandle, oldCapacity); *dictionaryHandle = newEntries; } -static bool setEntryArray(Toy_private_entry** dictionaryHandle, int* capacityPtr, int contains, Toy_Literal key, Toy_Literal value, int hash) { +static bool setEntryArray(Toy_private_dictionary_entry** dictionaryHandle, int* capacityPtr, int contains, Toy_Literal key, Toy_Literal value, int hash) { //expand array if needed if (contains + 1 > *capacityPtr * TOY_DICTIONARY_MAX_LOAD) { int oldCapacity = *capacityPtr; @@ -82,7 +82,7 @@ static bool setEntryArray(Toy_private_entry** dictionaryHandle, int* capacityPtr adjustEntryCapacity(dictionaryHandle, oldCapacity, *capacityPtr); //custom rather than automatic reallocation } - Toy_private_entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false); + Toy_private_dictionary_entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false); //true = contains increase if (TOY_IS_NULL(entry->key)) { @@ -97,14 +97,14 @@ static bool setEntryArray(Toy_private_entry** dictionaryHandle, int* capacityPtr return false; } -static void freeEntry(Toy_private_entry* entry) { +static void freeEntry(Toy_private_dictionary_entry* entry) { Toy_freeLiteral(entry->key); Toy_freeLiteral(entry->value); entry->key = TOY_TO_NULL_LITERAL; entry->value = TOY_TO_NULL_LITERAL; } -static void freeEntryArray(Toy_private_entry* array, int capacity) { +static void freeEntryArray(Toy_private_dictionary_entry* array, int capacity) { if (array == NULL) { return; } @@ -115,7 +115,7 @@ static void freeEntryArray(Toy_private_entry* array, int capacity) { } } - TOY_FREE_ARRAY(Toy_private_entry, array, capacity); + TOY_FREE_ARRAY(Toy_private_dictionary_entry, array, capacity); } //exposed functions @@ -176,7 +176,7 @@ Toy_Literal Toy_getLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Lite return TOY_TO_NULL_LITERAL; } - Toy_private_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true); + Toy_private_dictionary_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true); if (entry != NULL) { return Toy_copyLiteral(entry->value); @@ -203,7 +203,7 @@ void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal return; } - Toy_private_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true); + Toy_private_dictionary_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true); if (entry != NULL) { freeEntry(entry); @@ -214,6 +214,6 @@ void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal bool Toy_existsLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key) { //null & not tombstoned - Toy_private_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), false); + Toy_private_dictionary_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), false); return !(TOY_IS_NULL(entry->key) && TOY_IS_NULL(entry->value)); } diff --git a/source/toy_literal_dictionary.h b/source/toy_literal_dictionary.h index 3929c20..7b594bf 100644 --- a/source/toy_literal_dictionary.h +++ b/source/toy_literal_dictionary.h @@ -7,13 +7,13 @@ //TODO: benchmark this #define TOY_DICTIONARY_MAX_LOAD 0.75 -typedef struct Toy_private_entry { +typedef struct Toy_private_dictionary_entry { Toy_Literal key; Toy_Literal value; -} Toy_private_entry; +} Toy_private_dictionary_entry; typedef struct Toy_LiteralDictionary { - Toy_private_entry* entries; + Toy_private_dictionary_entry* entries; int capacity; int count; int contains; //count + tombstones, for internal use diff --git a/source/toy_memory.c b/source/toy_memory.c index 32f8218..a8920e7 100644 --- a/source/toy_memory.c +++ b/source/toy_memory.c @@ -15,15 +15,14 @@ void* Toy_private_defaultMemoryAllocator(void* pointer, size_t oldSize, size_t n if (newSize == 0) { free(pointer); - return NULL; } void* mem = realloc(pointer, newSize); if (mem == NULL) { - fprintf(stderr, TOY_CC_ERROR "[internal] Memory allocation error (requested %d, replacing %d)\n" TOY_CC_RESET, (int)newSize, (int)oldSize); - exit(-1); + fprintf(stderr, TOY_CC_ERROR "[internal] Memory allocation error (requested %zu, replacing %zu)\n" TOY_CC_RESET, newSize, oldSize); + return NULL; } return mem; diff --git a/source/toy_memory.h b/source/toy_memory.h index 8132b4e..191ecc2 100644 --- a/source/toy_memory.h +++ b/source/toy_memory.h @@ -2,13 +2,16 @@ #include "toy_common.h" -#define TOY_ALLOCATE(type, count) ((type*)Toy_reallocate(NULL, 0, sizeof(type) * (count))) -#define TOY_FREE(type, pointer) Toy_reallocate(pointer, sizeof(type), 0) -#define TOY_GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2) -#define TOY_GROW_CAPACITY_FAST(capacity) ((capacity) < 32 ? 32 : (capacity) * 2) -#define TOY_GROW_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) -#define TOY_SHRINK_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) -#define TOY_FREE_ARRAY(type, pointer, oldCount) Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), 0) +#define TOY_GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2) +#define TOY_GROW_CAPACITY_FAST(capacity) ((capacity) < 32 ? 32 : (capacity) * 2) + +#define TOY_ALLOCATE(type, count) ((type*)Toy_reallocate(NULL, 0, sizeof(type) * (count))) + +#define TOY_FREE(type, pointer) Toy_reallocate(pointer, sizeof(type), 0) +#define TOY_FREE_ARRAY(type, pointer, oldCount) Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), 0) + +#define TOY_GROW_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) +#define TOY_SHRINK_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) //implementation details TOY_API void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize); diff --git a/source/toy_refstring.h b/source/toy_refstring.h index b0a97b6..02bbaf9 100644 --- a/source/toy_refstring.h +++ b/source/toy_refstring.h @@ -7,7 +7,7 @@ //memory allocation hook typedef void* (*Toy_RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize); -void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn); +TOY_API void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn); //the RefString structure typedef struct Toy_RefString { @@ -27,3 +27,6 @@ TOY_API Toy_RefString* Toy_deepCopyRefString(Toy_RefString* refString); TOY_API const char* Toy_toCString(Toy_RefString* refString); TOY_API bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs); TOY_API bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring); + +//TODO: merge refstring memory + diff --git a/source/toy_scope.c b/source/toy_scope.c index f33e4e7..cb15fee 100644 --- a/source/toy_scope.c +++ b/source/toy_scope.c @@ -126,7 +126,7 @@ static bool checkType(Toy_Literal typeLiteral, Toy_Literal original, Toy_Literal } //find the internal child of original that matches this child of value - Toy_private_entry* ptr = NULL; + Toy_private_dictionary_entry* ptr = NULL; for (int j = 0; j < TOY_AS_DICTIONARY(original)->capacity; j++) { if (Toy_literalsAreEqual(TOY_AS_DICTIONARY(original)->entries[j].key, TOY_AS_DICTIONARY(value)->entries[i].key)) {