diff --git a/repl/bucket_inspector.c b/repl/bucket_inspector.c index 66d0fee..8bffbf6 100644 --- a/repl/bucket_inspector.c +++ b/repl/bucket_inspector.c @@ -1,5 +1,5 @@ #include "bucket_inspector.h" -// #include +#include #include @@ -13,40 +13,6 @@ int inspect_bucket(Toy_Bucket** bucketHandle) { unsigned char* ptr = iter->data; - while ((ptr - iter->data < iter->count) && *((int*)ptr) != 0) { //for each partition - if ( ( *((int*)ptr) & 1) == 0) { //is this partition still in use? - occupied++; - } - else { - released++; - } - - //jump distance: ((*((int*)ptr) | 1) ^ 1) + 4 - // printf(" jump %d, ", ((*((int*)ptr) | 1) ^ 1) + 4); - ptr += ((*((int*)ptr) | 1) ^ 1) + 4; //OR + XOR to remove the 'free' flag from the size - } - - printf("Bucket link %d: count %u, %d occupied, %d released\n", depth, iter->count, occupied, released); - - depth++; - } - - printf("\n"); - - return depth; -} - -/* -int inspect_bucket_for_strings(Toy_Bucket** bucketHandle) { - int depth = 0; - - //for each bucket - for (Toy_Bucket* iter = (*bucketHandle); iter != NULL; iter = iter->next) { - int occupied = 0; - int released = 0; - unsigned char* ptr = iter->data; - - while ((ptr - iter->data < iter->count) && *((int*)ptr) != 0) { //for each partition if ( ( *((int*)ptr) & 1) == 0) { //is this partition still in use? occupied++; @@ -79,4 +45,3 @@ int inspect_bucket_for_strings(Toy_Bucket** bucketHandle) { return depth; } -*/ \ No newline at end of file diff --git a/repl/bucket_inspector.h b/repl/bucket_inspector.h index c0932fb..3a95302 100644 --- a/repl/bucket_inspector.h +++ b/repl/bucket_inspector.h @@ -2,5 +2,4 @@ #include "toy_bucket.h" -int inspect_bucket(Toy_Bucket** bucketHandle); -// int inspect_bucket_for_strings(Toy_Bucket** bucketHandle); \ No newline at end of file +int inspect_bucket(Toy_Bucket** bucketHandle); \ No newline at end of file diff --git a/repl/main.c b/repl/main.c index a11ce66..499af6f 100644 --- a/repl/main.c +++ b/repl/main.c @@ -280,14 +280,14 @@ static void debugScopePrint(Toy_Scope* scope, int depth) { printf("\n" TOY_CC_NOTICE "Scope Dump [%d]" TOY_CC_RESET "\n" TOY_CC_NOTICE "%-20s%-20s%-20s" TOY_CC_RESET "\n", depth, "type", "name", "value"); for (unsigned int i = 0; i < scope->capacity; i++) { - if (scope->data[i].key.info.length == 0) { + if (scope->data[i].key == NULL || scope->data[i].key->info.length == 0) { continue; } - Toy_String k = scope->data[i].key; + Toy_String* k = scope->data[i].key; Toy_Value v = scope->data[i].value; - printf("%-10s%-10s%-20s", Toy_getValueTypeAsCString(scope->data[i].type), scope->data[i].constant ? "const" : "", k.leaf.data); + printf("%-10s%-10s%-20s", Toy_getValueTypeAsCString(scope->data[i].type), scope->data[i].constant ? "const" : "", k != NULL ? k->leaf.data : ""); //print value Toy_String* string = Toy_stringifyValue(&stringBucket, Toy_unwrapValue(v)); @@ -321,7 +321,7 @@ int repl(const char* filepath, bool verbose) { char inputBuffer[INPUT_BUFFER_SIZE]; memset(inputBuffer, 0, INPUT_BUFFER_SIZE); - Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); //TODO: gc this Toy_VM vm; Toy_initVM(&vm); diff --git a/repl/standard_library.c b/repl/standard_library.c index c0ced3d..2da068f 100644 --- a/repl/standard_library.c +++ b/repl/standard_library.c @@ -56,13 +56,9 @@ void initStandardLibrary(Toy_VM* vm) { //declare each pair for (int i = 0; callbackPairs[i].name; i++) { - //cheat - Toy_String key = (Toy_String){ - .leaf = { ._padding = { .type = TOY_STRING_LEAF, .length = strlen(callbackPairs[i].name), .refCount = 1, .cachedHash = 0 }, .data = callbackPairs[i].name } - }; - + Toy_String* key = Toy_createStringLength(&vm->memoryBucket, callbackPairs[i].name, strlen(callbackPairs[i].name)); Toy_Function* fn = Toy_createFunctionFromCallback(&(vm->memoryBucket), callbackPairs[i].callback); - Toy_declareScope(vm->scope, &key, TOY_VALUE_FUNCTION, TOY_VALUE_FROM_FUNCTION(fn), true); + Toy_declareScope(vm->scope, key, TOY_VALUE_FUNCTION, TOY_VALUE_FROM_FUNCTION(fn), true); } } diff --git a/scripts/hello_world.toy b/scripts/hello_world.toy index 320e2cb..e5d07c7 100644 --- a/scripts/hello_world.toy +++ b/scripts/hello_world.toy @@ -15,5 +15,5 @@ c, d = swap(a, b); */ -{ var str = "Hello"; var i = 0; while (i < 10_000) { str = str .. " World"; i++; } } +{ var str = "Hello"; var i = 0; while (i < 100) { str = str .. " World"; i++; } } diff --git a/source/toy_scope.c b/source/toy_scope.c index 02f3c7c..baef500 100644 --- a/source/toy_scope.c +++ b/source/toy_scope.c @@ -19,12 +19,12 @@ static Toy_ScopeEntry* lookupScopeEntryPtr(Toy_Scope* scope, Toy_String* key, un while (true) { //found the entry - if (Toy_compareStrings(&(scope->data[probe].key), key) == 0) { + if (scope->data[probe].key != NULL && Toy_compareStrings(scope->data[probe].key, key) == 0) { return &(scope->data[probe]); } //if its an empty slot (didn't find it here) - if (scope->data[probe].key.info.length == 0) { + if (scope->data[probe].key == NULL) { return recursive ? lookupScopeEntryPtr(scope->next, key, hash, recursive) : NULL; } @@ -36,12 +36,12 @@ static Toy_ScopeEntry* lookupScopeEntryPtr(Toy_Scope* scope, Toy_String* key, un static void probeAndInsert(Toy_Scope* scope, Toy_String* key, Toy_Value value, Toy_ValueType type, bool constant) { //make the entry unsigned int probe = Toy_hashString(key) % scope->capacity; - Toy_ScopeEntry entry = (Toy_ScopeEntry){ .key = *key, .value = value, .type = type, .constant = constant, .psl = 1 }; + Toy_ScopeEntry entry = (Toy_ScopeEntry){ .key = key, .value = value, .type = type, .constant = constant, .psl = 1 }; //probe while (true) { //if we're overriding an existing value - if (Toy_compareStrings(&(scope->data[probe].key), &(entry.key)) == 0) { + if (scope->data[probe].key != NULL && Toy_compareStrings(scope->data[probe].key, entry.key) == 0) { scope->data[probe] = entry; scope->maxPsl = entry.psl > scope->maxPsl ? entry.psl : scope->maxPsl; return; @@ -94,8 +94,8 @@ static Toy_ScopeEntry* adjustScopeEntries(Toy_Scope* scope, unsigned int newCapa //for each existing entry in the old array, copy it into the new array for (unsigned int i = 0; i < oldCapacity; i++) { - if (oldEntries[i].key.info.length > 0) { - probeAndInsert(scope, &(oldEntries[i].key), oldEntries[i].value, oldEntries[i].type, oldEntries[i].constant); + if (oldEntries[i].key != NULL && oldEntries[i].key->info.length > 0) { + probeAndInsert(scope, oldEntries[i].key, oldEntries[i].value, oldEntries[i].type, oldEntries[i].constant); } } @@ -134,7 +134,10 @@ Toy_Scope* Toy_popScope(Toy_Scope* scope) { } Toy_private_decrementScopeRefCount(scope); - return scope->next; + + Toy_Scope* next = scope->next; + Toy_releaseBucketPartition((void*)scope); + return next; } void Toy_declareScope(Toy_Scope* scope, Toy_String* key, Toy_ValueType type, Toy_Value value, bool constant) { @@ -229,29 +232,21 @@ void Toy_private_incrementScopeRefCount(Toy_Scope* scope) { } void Toy_private_decrementScopeRefCount(Toy_Scope* scope) { - Toy_Scope* iter = scope; - - while (iter) { + for (Toy_Scope* iter = scope; iter != NULL; iter = iter->next) { iter->refCount--; + + //clean up our insides if needed if (iter->refCount == 0) { - //free the scope entries when this scope is no longer needed + //free the data if (iter->data != NULL) { for (unsigned int i = 0; i < iter->capacity; i++) { - if (iter->data[i].psl > 0) { - Toy_freeString(&(iter->data[i].key)); + if (iter->data[i].key != NULL) { + Toy_freeString(iter->data[i].key); Toy_freeValue(iter->data[i].value); } } free(iter->data); } - - //free the scope itself, fixing the iterator for the next loop - Toy_Scope* empty = iter; - iter = iter->next; - Toy_releaseBucketPartition((void*)empty); - } - else { - iter = iter->next; } } } \ No newline at end of file diff --git a/source/toy_scope.h b/source/toy_scope.h index b8c40e1..bdfbe5c 100644 --- a/source/toy_scope.h +++ b/source/toy_scope.h @@ -8,7 +8,7 @@ //keys are leaf-only strings typedef struct Toy_ScopeEntry { - Toy_String key; + Toy_String* key; Toy_Value value; Toy_ValueType type; unsigned int psl; //psl '0' means empty