From c1d72adb718f92bf2a9dee7dfe7f5bc84738c114 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 12 Oct 2024 19:34:37 +1100 Subject: [PATCH] Finished the scope tests --- source/toy_scope.c | 12 +-- source/toy_scope.h | 8 +- source/toy_string.c | 2 +- source/toy_string.h | 4 +- tests/cases/test_scope.c | 192 +++++++++++++++++++++++++++++++++++++- tests/cases/test_string.c | 4 +- 6 files changed, 204 insertions(+), 18 deletions(-) diff --git a/source/toy_scope.c b/source/toy_scope.c index d8bd7ca..0c15757 100644 --- a/source/toy_scope.c +++ b/source/toy_scope.c @@ -31,7 +31,7 @@ static Toy_Value* lookupScope(Toy_Scope* scope, Toy_String* key, unsigned int ha while (true) { //found the entry - if (Toy_compareStrings(TOY_VALUE_AS_STRING(scope->table->data[probe].key), key)) { + if (TOY_VALUE_IS_STRING(scope->table->data[probe].key) && Toy_compareStrings(TOY_VALUE_AS_STRING(scope->table->data[probe].key), key) == 0) { return &(scope->table->data[probe].value); } @@ -89,7 +89,7 @@ Toy_Scope* Toy_deepCopyScope(Toy_Bucket** bucketHandle, Toy_Scope* scope) { return newScope; } -void Toy_declareScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* key, Toy_Value value) { +void Toy_declareScope(Toy_Scope* scope, Toy_String* key, Toy_Value value) { if (key->type != TOY_STRING_NAME) { fprintf(stderr, TOY_CC_ERROR "ERROR: Toy_Scope only allows name strings as keys\n" TOY_CC_RESET); exit(-1); @@ -105,10 +105,10 @@ void Toy_declareScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* k return; } - Toy_insertTable(&scope->table, TOY_VALUE_FROM_STRING(Toy_copyString(bucketHandle, key)), value); + Toy_insertTable(&scope->table, TOY_VALUE_FROM_STRING(Toy_copyString(key)), value); } -void Toy_assignScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* key, Toy_Value value) { +void Toy_assignScope(Toy_Scope* scope, Toy_String* key, Toy_Value value) { if (key->type != TOY_STRING_NAME) { fprintf(stderr, TOY_CC_ERROR "ERROR: Toy_Scope only allows name strings as keys\n" TOY_CC_RESET); exit(-1); @@ -126,7 +126,7 @@ void Toy_assignScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* ke *valuePtr = value; } -Toy_Value Toy_accessScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* key) { +Toy_Value Toy_accessScope(Toy_Scope* scope, Toy_String* key) { if (key->type != TOY_STRING_NAME) { fprintf(stderr, TOY_CC_ERROR "ERROR: Toy_Scope only allows name strings as keys\n" TOY_CC_RESET); exit(-1); @@ -144,7 +144,7 @@ Toy_Value Toy_accessScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_Strin return *valuePtr; } -bool Toy_isDeclaredScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* key) { +bool Toy_isDeclaredScope(Toy_Scope* scope, Toy_String* key) { if (key->type != TOY_STRING_NAME) { fprintf(stderr, TOY_CC_ERROR "ERROR: Toy_Scope only allows name strings as keys\n" TOY_CC_RESET); exit(-1); diff --git a/source/toy_scope.h b/source/toy_scope.h index b7395d9..618dd9e 100644 --- a/source/toy_scope.h +++ b/source/toy_scope.h @@ -21,8 +21,8 @@ TOY_API Toy_Scope* Toy_popScope(Toy_Scope* scope); TOY_API Toy_Scope* Toy_deepCopyScope(Toy_Bucket** bucketHandle, Toy_Scope* scope); //manage the contents -TOY_API void Toy_declareScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* key, Toy_Value value); -TOY_API void Toy_assignScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* key, Toy_Value value); -TOY_API Toy_Value Toy_accessScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* key); +TOY_API void Toy_declareScope(Toy_Scope* scope, Toy_String* key, Toy_Value value); +TOY_API void Toy_assignScope(Toy_Scope* scope, Toy_String* key, Toy_Value value); +TOY_API Toy_Value Toy_accessScope(Toy_Scope* scope, Toy_String* key); -TOY_API bool Toy_isDeclaredScope(Toy_Bucket** bucketHandle, Toy_Scope* scope, Toy_String* key); +TOY_API bool Toy_isDeclaredScope(Toy_Scope* scope, Toy_String* key); diff --git a/source/toy_string.c b/source/toy_string.c index 55635b3..147bd20 100644 --- a/source/toy_string.c +++ b/source/toy_string.c @@ -91,7 +91,7 @@ TOY_API Toy_String* Toy_createNameString(Toy_Bucket** bucketHandle, const char* return ret; } -Toy_String* Toy_copyString(Toy_Bucket** bucketHandle, Toy_String* str) { +Toy_String* Toy_copyString(Toy_String* str) { if (str->refCount == 0) { fprintf(stderr, TOY_CC_ERROR "ERROR: Can't copy a string with refcount of zero\n" TOY_CC_RESET); exit(-1); diff --git a/source/toy_string.h b/source/toy_string.h index aaba337..61d208d 100644 --- a/source/toy_string.h +++ b/source/toy_string.h @@ -5,7 +5,7 @@ #include "toy_bucket.h" #include "toy_value.h" -//TODO: Remove this +//TODO: Remove this (related to partitioning more space in a bucket issue) #define TOY_STRING_MAX_LENGTH 1000 //rope pattern @@ -43,7 +43,7 @@ TOY_API Toy_String* Toy_createStringLength(Toy_Bucket** bucketHandle, const char TOY_API Toy_String* Toy_createNameString(Toy_Bucket** bucketHandle, const char* cname, Toy_ValueType type); //for variable names -TOY_API Toy_String* Toy_copyString(Toy_Bucket** bucketHandle, Toy_String* str); +TOY_API Toy_String* Toy_copyString(Toy_String* str); TOY_API Toy_String* Toy_deepCopyString(Toy_Bucket** bucketHandle, Toy_String* str); TOY_API Toy_String* Toy_concatStrings(Toy_Bucket** bucketHandle, Toy_String* left, Toy_String* right); diff --git a/tests/cases/test_scope.c b/tests/cases/test_scope.c index 1b1d11c..678f9de 100644 --- a/tests/cases/test_scope.c +++ b/tests/cases/test_scope.c @@ -298,8 +298,194 @@ int test_scope_allocation() { } int test_scope_elements() { - //TODO: Ensure the scope's primary function of handling key-value pairs works correctly. - printf(TOY_CC_WARN "'test_scope_elements()' not yet implemented\n" TOY_CC_RESET); + //allocate, access and assign an element + { + //setup + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + Toy_Scope* scope = Toy_pushScope(&bucket, NULL); + + Toy_String* hello1 = Toy_createNameString(&bucket, "hello", TOY_VALUE_NULL); + Toy_String* hello2 = Toy_createNameString(&bucket, "hello", TOY_VALUE_NULL); + + //check nothing is here + if (Toy_isDeclaredScope(scope, hello2)) { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected entry found in Toy_Scope\n" TOY_CC_RESET); + Toy_freeString(hello2); + Toy_freeString(hello1); + Toy_popScope(scope); + Toy_freeBucket(&bucket); + return -1; + } + + //declare and access values + Toy_declareScope(scope, hello1, TOY_VALUE_FROM_INTEGER(42)); + + if (!Toy_isDeclaredScope(scope, hello2)) { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected missing entry in Toy_Scope\n" TOY_CC_RESET); + Toy_freeString(hello2); + Toy_freeString(hello1); + Toy_popScope(scope); + Toy_freeBucket(&bucket); + return -1; + } + + Toy_Value result = Toy_accessScope(scope, hello2); + + //check integer + if (scope == NULL || + scope->next != NULL || + scope->table == NULL || + scope->table->capacity != 16 || + scope->refCount != 1 || + + TOY_VALUE_IS_INTEGER(result) != true || + TOY_VALUE_AS_INTEGER(result) != 42 || + + false) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to declare in Toy_Scope\n" TOY_CC_RESET); + Toy_freeString(hello2); + Toy_freeString(hello1); + Toy_popScope(scope); + Toy_freeBucket(&bucket); + return -1; + } + + //assign values + Toy_assignScope(scope, hello1, TOY_VALUE_FROM_FLOAT(3.1415f)); + + Toy_Value resultTwo = Toy_accessScope(scope, hello2); + + //check float + if (scope == NULL || + scope->next != NULL || + scope->table == NULL || + scope->table->capacity != 16 || + scope->refCount != 1 || + + TOY_VALUE_IS_FLOAT(resultTwo) != true || + TOY_VALUE_AS_FLOAT(resultTwo) != 3.1415f || + + false) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to assign in Toy_Scope\n" TOY_CC_RESET); + Toy_freeString(hello2); + Toy_freeString(hello1); + Toy_popScope(scope); + Toy_freeBucket(&bucket); + return -1; + } + + //cleanup + Toy_freeString(hello2); + Toy_freeString(hello1); + Toy_popScope(scope); + Toy_freeBucket(&bucket); + } + + //find an entry in an ancestor scope + { + //setup + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + Toy_Scope* scope = Toy_pushScope(&bucket, NULL); + + Toy_String* hello = Toy_createNameString(&bucket, "hello", TOY_VALUE_NULL); + + //declare and push + Toy_declareScope(scope, hello, TOY_VALUE_FROM_INTEGER(42)); + + scope = Toy_pushScope(&bucket, scope); + scope = Toy_pushScope(&bucket, scope); + + { + //check it's accessible + Toy_Value result1 = Toy_accessScope(scope, hello); + + if (TOY_VALUE_IS_INTEGER(result1) != true || + TOY_VALUE_AS_INTEGER(result1) != 42) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to access from an ancestor Toy_Scope\n" TOY_CC_RESET); + Toy_freeString(hello); + while ((scope = Toy_popScope(scope)) != NULL) /* */; + Toy_freeBucket(&bucket); + return -1; + } + } + + Toy_declareScope(scope, hello, TOY_VALUE_FROM_FLOAT(3.1415f)); + + { + //check it's shadowed correctly + Toy_Value result2 = Toy_accessScope(scope, hello); + + if (TOY_VALUE_IS_FLOAT(result2) != true || + TOY_VALUE_AS_FLOAT(result2) != 3.1415f) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to shadow an entry in Toy_Scope\n" TOY_CC_RESET); + Toy_freeString(hello); + while ((scope = Toy_popScope(scope)) != NULL) /* */; + Toy_freeBucket(&bucket); + return -1; + } + } + + scope = Toy_popScope(scope); + + { + //check it's recovered correctly + Toy_Value result3 = Toy_accessScope(scope, hello); + + if (TOY_VALUE_IS_INTEGER(result3) != true || + TOY_VALUE_AS_INTEGER(result3) != 42) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to recover an entry in Toy_Scope\n" TOY_CC_RESET); + Toy_freeString(hello); + while ((scope = Toy_popScope(scope)) != NULL) /* */; + Toy_freeBucket(&bucket); + return -1; + } + } + + Toy_assignScope(scope, hello, TOY_VALUE_FROM_INTEGER(8891)); + + { + //check it's assigned correctly + Toy_Value result4 = Toy_accessScope(scope, hello); + + if (TOY_VALUE_IS_INTEGER(result4) != true || + TOY_VALUE_AS_INTEGER(result4) != 8891) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to assign to an ancestor in Toy_Scope\n" TOY_CC_RESET); + Toy_freeString(hello); + while ((scope = Toy_popScope(scope)) != NULL) /* */; + Toy_freeBucket(&bucket); + return -1; + } + } + + scope = Toy_popScope(scope); + + { + //check it's in the correct state + Toy_Value result5 = Toy_accessScope(scope, hello); + + if (TOY_VALUE_IS_INTEGER(result5) != true || + TOY_VALUE_AS_INTEGER(result5) != 8891) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to access an altered entry of an ancestor in Toy_Scope\n" TOY_CC_RESET); + Toy_freeString(hello); + while ((scope = Toy_popScope(scope)) != NULL) /* */; + Toy_freeBucket(&bucket); + return -1; + } + } + + //cleanup + Toy_freeString(hello); + while ((scope = Toy_popScope(scope)) != NULL) /* */; + Toy_freeBucket(&bucket); + } + return 0; } @@ -318,7 +504,7 @@ int main() { { res = test_scope_elements(); if (res == 0) { - // printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); } total += res; } diff --git a/tests/cases/test_string.c b/tests/cases/test_string.c index 1b381a1..004d866 100644 --- a/tests/cases/test_string.c +++ b/tests/cases/test_string.c @@ -83,7 +83,7 @@ int test_string_allocation() { Toy_String* str = Toy_createString(&bucket, cstring); //shallow and deep - Toy_String* shallow = Toy_copyString(&bucket, str); + Toy_String* shallow = Toy_copyString(str); Toy_String* deep = Toy_deepCopyString(&bucket, str); if (str != shallow || @@ -109,7 +109,7 @@ int test_string_allocation() { Toy_String* str = Toy_createNameString(&bucket, cstring, TOY_VALUE_NULL); //shallow and deep - Toy_String* shallow = Toy_copyString(&bucket, str); + Toy_String* shallow = Toy_copyString(str); Toy_String* deep = Toy_deepCopyString(&bucket, str); if (str != shallow ||