Added 'Toy_String' to 'Toy_Value' structure, read more

To help with storing strings within tables, I've replaced the unused
'_padding' member of 'Toy_String' with 'cachedHash', which is set to
zero on string allocation.

The hash of a string isn't generated and stored until it's actually
needed, as the rope pattern means not every string needs a hash -
hopefully this will save unnecessarily wasted time.

When a hash of a string is needed, the hashing function first checks to
see if that string already has one, and if so, returns it. Again, less
time wasted.

When generating a new string hash, the hashing function takes the
string's type into account, as node-based strings first need their
contents assembled into a simple char buffer.

Other changes include:

* Changed 'TOY_VALUE_TO_*' to 'TOY_VALUE_FROM_*'
* Changed 'TOY_VALUE_IS_EQUAL' to 'TOY_VALUES_ARE_EQUAL'
* Added a missing '#pragma once' to 'toy_print.h'
This commit is contained in:
2024-10-07 17:20:08 +11:00
parent d62ee2a9a3
commit 14653a303f
25 changed files with 266 additions and 175 deletions

View File

@@ -1,6 +1,9 @@
#include "toy_value.h"
#include "toy_console_colors.h"
#include "toy_bucket.h"
#include "toy_string.h"
#include <stdio.h>
int main() {
@@ -14,7 +17,7 @@ int main() {
//test creating a null
{
Toy_Value v = TOY_VALUE_TO_NULL();
Toy_Value v = TOY_VALUE_FROM_NULL();
if (!TOY_VALUE_IS_NULL(v)) {
fprintf(stderr, TOY_CC_ERROR "ERROR: creating a 'null' value failed\n" TOY_CC_RESET);
@@ -24,8 +27,8 @@ int main() {
//test creating values
{
Toy_Value t = TOY_VALUE_TO_BOOLEAN(true);
Toy_Value f = TOY_VALUE_TO_BOOLEAN(false);
Toy_Value t = TOY_VALUE_FROM_BOOLEAN(true);
Toy_Value f = TOY_VALUE_FROM_BOOLEAN(false);
if (!TOY_VALUE_IS_TRUTHY(t) || TOY_VALUE_IS_TRUTHY(f)) {
fprintf(stderr, TOY_CC_ERROR "ERROR: 'boolean' value failed\n" TOY_CC_RESET);
@@ -35,21 +38,51 @@ int main() {
//test value equality
{
Toy_Value answer = TOY_VALUE_TO_INTEGER(42);
Toy_Value question = TOY_VALUE_TO_INTEGER(42);
Toy_Value nice = TOY_VALUE_TO_INTEGER(69);
Toy_Value answer = TOY_VALUE_FROM_INTEGER(42);
Toy_Value question = TOY_VALUE_FROM_INTEGER(42);
Toy_Value nice = TOY_VALUE_FROM_INTEGER(69);
if (!TOY_VALUE_IS_EQUAL(answer, question)) {
if (!TOY_VALUES_ARE_EQUAL(answer, question)) {
fprintf(stderr, TOY_CC_ERROR "ERROR: equality check failed, expected true\n" TOY_CC_RESET);
return -1;
}
if (TOY_VALUE_IS_EQUAL(answer, nice)) {
if (TOY_VALUES_ARE_EQUAL(answer, nice)) {
fprintf(stderr, TOY_CC_ERROR "ERROR: equality check failed, expected false\n" TOY_CC_RESET);
return -1;
}
}
//test value hashing
{
//setup
Toy_Bucket* bucket = Toy_allocateBucket(512);
//values
Toy_Value n = TOY_VALUE_FROM_NULL();
Toy_Value t = TOY_VALUE_FROM_BOOLEAN(true);
Toy_Value f = TOY_VALUE_FROM_BOOLEAN(false);
Toy_Value i = TOY_VALUE_FROM_INTEGER(42);
//skip float
Toy_Value s = TOY_VALUE_FROM_STRING(Toy_createString(&bucket, "Hello world"));
if (Toy_hashValue(n) != 0 ||
Toy_hashValue(t) != 1 ||
Toy_hashValue(f) != 0 ||
Toy_hashValue(i) != 4147366645 ||
Toy_hashValue(s) != 994097935 ||
TOY_VALUE_AS_STRING(s)->cachedHash == 0
)
{
fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected hash of a value\n" TOY_CC_RESET);
Toy_freeBucket(&bucket);
return -1;
}
//cleanup
Toy_freeBucket(&bucket);
}
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
return 0;
}