mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Minor tweaks and renames, as I'm documenting
This commit is contained in:
@@ -6,8 +6,6 @@
|
|||||||
#include "toy_literal_dictionary.h"
|
#include "toy_literal_dictionary.h"
|
||||||
#include "toy_scope.h"
|
#include "toy_scope.h"
|
||||||
|
|
||||||
typedef void (*Toy_PrintFn)(const char*);
|
|
||||||
|
|
||||||
//the interpreter acts depending on the bytecode instructions
|
//the interpreter acts depending on the bytecode instructions
|
||||||
typedef struct Toy_Interpreter {
|
typedef struct Toy_Interpreter {
|
||||||
//input
|
//input
|
||||||
|
|||||||
@@ -155,7 +155,8 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case TOY_LITERAL_IDENTIFIER: {
|
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: {
|
case TOY_LITERAL_TYPE: {
|
||||||
@@ -404,13 +405,13 @@ int Toy_hashLiteral(Toy_Literal lit) {
|
|||||||
case TOY_LITERAL_FUNCTION:
|
case TOY_LITERAL_FUNCTION:
|
||||||
case TOY_LITERAL_FUNCTION_NATIVE:
|
case TOY_LITERAL_FUNCTION_NATIVE:
|
||||||
case TOY_LITERAL_FUNCTION_HOOK:
|
case TOY_LITERAL_FUNCTION_HOOK:
|
||||||
return 0; //can't hash these
|
return -1; //can't hash these
|
||||||
|
|
||||||
case TOY_LITERAL_IDENTIFIER:
|
case TOY_LITERAL_IDENTIFIER:
|
||||||
return TOY_HASH_I(lit); //pre-computed
|
return TOY_HASH_I(lit); //pre-computed
|
||||||
|
|
||||||
case TOY_LITERAL_TYPE:
|
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_OPAQUE:
|
||||||
case TOY_LITERAL_ANY:
|
case TOY_LITERAL_ANY:
|
||||||
@@ -453,7 +454,7 @@ void Toy_printLiteral(Toy_Literal literal) {
|
|||||||
Toy_printLiteralCustom(literal, stdoutWrapper);
|
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) {
|
switch(literal.type) {
|
||||||
case TOY_LITERAL_NULL:
|
case TOY_LITERAL_NULL:
|
||||||
printFn("null");
|
printFn("null");
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ struct Toy_Interpreter;
|
|||||||
struct Toy_LiteralArray;
|
struct Toy_LiteralArray;
|
||||||
typedef int (*Toy_NativeFn)(struct Toy_Interpreter* interpreter, struct Toy_LiteralArray* arguments);
|
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 int (*Toy_HookFn)(struct Toy_Interpreter* interpreter, struct Toy_Literal identifier, struct Toy_Literal alias);
|
||||||
|
typedef void (*Toy_PrintFn)(const char*);
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -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 bool Toy_literalsAreEqual(Toy_Literal lhs, Toy_Literal rhs);
|
||||||
TOY_API int Toy_hashLiteral(Toy_Literal lit);
|
TOY_API int Toy_hashLiteral(Toy_Literal lit);
|
||||||
|
|
||||||
|
//not thread-safe
|
||||||
TOY_API void Toy_printLiteral(Toy_Literal literal);
|
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);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
//util functions
|
//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
|
//much simpler now
|
||||||
Toy_freeLiteral(entry->key);
|
Toy_freeLiteral(entry->key);
|
||||||
entry->key = Toy_copyLiteral(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);
|
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
|
//find "key", starting at index
|
||||||
unsigned int index = hash % capacity;
|
unsigned int index = hash % capacity;
|
||||||
unsigned int start = index;
|
unsigned int start = index;
|
||||||
@@ -26,7 +26,7 @@ static Toy_private_entry* getEntryArray(Toy_private_entry* array, int capacity,
|
|||||||
|
|
||||||
//literal probing and collision checking
|
//literal probing and collision checking
|
||||||
while (index != start) { //WARNING: this is the only function allowed to retrieve an entry from the array
|
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->key)) { //if key is empty, it's either empty or tombstone
|
||||||
if (TOY_IS_NULL(entry->value) && !mustExist) {
|
if (TOY_IS_NULL(entry->value) && !mustExist) {
|
||||||
@@ -46,9 +46,9 @@ static Toy_private_entry* getEntryArray(Toy_private_entry* array, int capacity,
|
|||||||
return NULL;
|
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
|
//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++) {
|
for (int i = 0; i < capacity; i++) {
|
||||||
newEntries[i].key = TOY_TO_NULL_LITERAL;
|
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)
|
//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->key = (*dictionaryHandle)[i].key;
|
||||||
entry->value = (*dictionaryHandle)[i].value;
|
entry->value = (*dictionaryHandle)[i].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear the old array
|
//clear the old array
|
||||||
TOY_FREE_ARRAY(Toy_private_entry, *dictionaryHandle, oldCapacity);
|
TOY_FREE_ARRAY(Toy_private_dictionary_entry, *dictionaryHandle, oldCapacity);
|
||||||
|
|
||||||
*dictionaryHandle = newEntries;
|
*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
|
//expand array if needed
|
||||||
if (contains + 1 > *capacityPtr * TOY_DICTIONARY_MAX_LOAD) {
|
if (contains + 1 > *capacityPtr * TOY_DICTIONARY_MAX_LOAD) {
|
||||||
int oldCapacity = *capacityPtr;
|
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
|
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
|
//true = contains increase
|
||||||
if (TOY_IS_NULL(entry->key)) {
|
if (TOY_IS_NULL(entry->key)) {
|
||||||
@@ -97,14 +97,14 @@ static bool setEntryArray(Toy_private_entry** dictionaryHandle, int* capacityPtr
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeEntry(Toy_private_entry* entry) {
|
static void freeEntry(Toy_private_dictionary_entry* entry) {
|
||||||
Toy_freeLiteral(entry->key);
|
Toy_freeLiteral(entry->key);
|
||||||
Toy_freeLiteral(entry->value);
|
Toy_freeLiteral(entry->value);
|
||||||
entry->key = TOY_TO_NULL_LITERAL;
|
entry->key = TOY_TO_NULL_LITERAL;
|
||||||
entry->value = 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) {
|
if (array == NULL) {
|
||||||
return;
|
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
|
//exposed functions
|
||||||
@@ -176,7 +176,7 @@ Toy_Literal Toy_getLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Lite
|
|||||||
return TOY_TO_NULL_LITERAL;
|
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) {
|
if (entry != NULL) {
|
||||||
return Toy_copyLiteral(entry->value);
|
return Toy_copyLiteral(entry->value);
|
||||||
@@ -203,7 +203,7 @@ void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal
|
|||||||
return;
|
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) {
|
if (entry != NULL) {
|
||||||
freeEntry(entry);
|
freeEntry(entry);
|
||||||
@@ -214,6 +214,6 @@ void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal
|
|||||||
|
|
||||||
bool Toy_existsLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key) {
|
bool Toy_existsLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key) {
|
||||||
//null & not tombstoned
|
//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));
|
return !(TOY_IS_NULL(entry->key) && TOY_IS_NULL(entry->value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
//TODO: benchmark this
|
//TODO: benchmark this
|
||||||
#define TOY_DICTIONARY_MAX_LOAD 0.75
|
#define TOY_DICTIONARY_MAX_LOAD 0.75
|
||||||
|
|
||||||
typedef struct Toy_private_entry {
|
typedef struct Toy_private_dictionary_entry {
|
||||||
Toy_Literal key;
|
Toy_Literal key;
|
||||||
Toy_Literal value;
|
Toy_Literal value;
|
||||||
} Toy_private_entry;
|
} Toy_private_dictionary_entry;
|
||||||
|
|
||||||
typedef struct Toy_LiteralDictionary {
|
typedef struct Toy_LiteralDictionary {
|
||||||
Toy_private_entry* entries;
|
Toy_private_dictionary_entry* entries;
|
||||||
int capacity;
|
int capacity;
|
||||||
int count;
|
int count;
|
||||||
int contains; //count + tombstones, for internal use
|
int contains; //count + tombstones, for internal use
|
||||||
|
|||||||
@@ -15,15 +15,14 @@ void* Toy_private_defaultMemoryAllocator(void* pointer, size_t oldSize, size_t n
|
|||||||
|
|
||||||
if (newSize == 0) {
|
if (newSize == 0) {
|
||||||
free(pointer);
|
free(pointer);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* mem = realloc(pointer, newSize);
|
void* mem = realloc(pointer, newSize);
|
||||||
|
|
||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
fprintf(stderr, TOY_CC_ERROR "[internal] Memory allocation error (requested %d, replacing %d)\n" TOY_CC_RESET, (int)newSize, (int)oldSize);
|
fprintf(stderr, TOY_CC_ERROR "[internal] Memory allocation error (requested %zu, replacing %zu)\n" TOY_CC_RESET, newSize, oldSize);
|
||||||
exit(-1);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
|
|||||||
@@ -2,13 +2,16 @@
|
|||||||
|
|
||||||
#include "toy_common.h"
|
#include "toy_common.h"
|
||||||
|
|
||||||
#define TOY_ALLOCATE(type, count) ((type*)Toy_reallocate(NULL, 0, sizeof(type) * (count)))
|
#define TOY_GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2)
|
||||||
#define TOY_FREE(type, pointer) Toy_reallocate(pointer, sizeof(type), 0)
|
#define TOY_GROW_CAPACITY_FAST(capacity) ((capacity) < 32 ? 32 : (capacity) * 2)
|
||||||
#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_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(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_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
|
//implementation details
|
||||||
TOY_API void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize);
|
TOY_API void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
//memory allocation hook
|
//memory allocation hook
|
||||||
typedef void* (*Toy_RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize);
|
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
|
//the RefString structure
|
||||||
typedef struct Toy_RefString {
|
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 const char* Toy_toCString(Toy_RefString* refString);
|
||||||
TOY_API bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs);
|
TOY_API bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs);
|
||||||
TOY_API bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring);
|
TOY_API bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring);
|
||||||
|
|
||||||
|
//TODO: merge refstring memory
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
//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++) {
|
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)) {
|
if (Toy_literalsAreEqual(TOY_AS_DICTIONARY(original)->entries[j].key, TOY_AS_DICTIONARY(value)->entries[i].key)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user