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

@@ -27,9 +27,10 @@ These data structures should be as independent as they can be, but there are som
```mermaid
graph TB
Toy_Value ---> Toy_Stack
Toy_Array
Toy_Bucket ---> Toy_String
Toy_Value ---> Toy_String
Toy_Value ---> Toy_Table
Toy_Bucket ---> Toy_String
Toy_Array
```
*TODO: Toy_Value will eventually depend on other structures, includeing those shown here, once the related features are implemented in v2.*

View File

@@ -3,6 +3,7 @@
//general utilities
#include "toy_common.h"
#include "toy_console_colors.h"
#include "toy_print.h"
//basic structures
#include "toy_value.h"
@@ -21,3 +22,4 @@
#include "toy_parser.h"
#include "toy_bytecode.h"
#include "toy_vm.h"

View File

@@ -131,3 +131,4 @@ void Toy_private_emitAstPrint(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstError(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstEnd(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);

View File

@@ -11,3 +11,4 @@ typedef struct Toy_Bytecode {
TOY_API Toy_Bytecode Toy_compileBytecode(Toy_Ast* ast);
TOY_API void Toy_freeBytecode(Toy_Bytecode bc);

View File

@@ -75,3 +75,4 @@ NOTE: you need both font AND background for these to work
#define TOY_CC_RESET
#endif

View File

@@ -13,3 +13,4 @@ extern const Toy_KeywordTypeTuple Toy_private_keywords[];
//access
const char* Toy_private_findKeywordByType(const Toy_TokenType type);
Toy_TokenType Toy_private_findTypeByKeyword(const char* keyword);

View File

@@ -1,7 +1,7 @@
#pragma once
#include "toy_token_types.h"
#include "toy_common.h"
#include "toy_token_types.h"
//lexers are bound to a string of code
typedef struct {
@@ -25,3 +25,4 @@ TOY_API void Toy_private_printToken(Toy_Token* token); //debugging
//util
#define TOY_BLANK_TOKEN() ((Toy_Token){TOY_TOKEN_NULL, 0, 0, NULL})

View File

@@ -42,3 +42,4 @@ typedef enum Toy_OpcodeType {
TOY_OPCODE_ERROR,
TOY_OPCODE_EOF = 255,
} Toy_OpcodeType;

View File

@@ -217,15 +217,15 @@ static ParsingTuple parsingRulesetTable[] = {
static Toy_AstFlag atomic(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
switch(parser->previous.type) {
case TOY_TOKEN_NULL:
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_NULL());
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_FROM_NULL());
return TOY_AST_FLAG_NONE;
case TOY_TOKEN_LITERAL_TRUE:
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_BOOLEAN(true));
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_FROM_BOOLEAN(true));
return TOY_AST_FLAG_NONE;
case TOY_TOKEN_LITERAL_FALSE:
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_BOOLEAN(false));
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_FROM_BOOLEAN(false));
return TOY_AST_FLAG_NONE;
case TOY_TOKEN_LITERAL_INTEGER: {
@@ -241,7 +241,7 @@ static Toy_AstFlag atomic(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast
int value = 0;
sscanf(buffer, "%d", &value);
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_INTEGER(value));
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_FROM_INTEGER(value));
return TOY_AST_FLAG_NONE;
}
@@ -258,7 +258,7 @@ static Toy_AstFlag atomic(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast
float value = 0;
sscanf(buffer, "%f", &value);
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_FLOAT(value));
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_FROM_FLOAT(value));
return TOY_AST_FLAG_NONE;
}
@@ -280,10 +280,10 @@ static Toy_AstFlag unary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast*
//negative numbers
if ((*rootHandle)->type == TOY_AST_VALUE && TOY_VALUE_IS_INTEGER((*rootHandle)->value.value) && connectedDigit) {
(*rootHandle)->value.value = TOY_VALUE_TO_INTEGER( -TOY_VALUE_AS_INTEGER((*rootHandle)->value.value) );
(*rootHandle)->value.value = TOY_VALUE_FROM_INTEGER( -TOY_VALUE_AS_INTEGER((*rootHandle)->value.value) );
}
else if ((*rootHandle)->type == TOY_AST_VALUE && TOY_VALUE_IS_FLOAT((*rootHandle)->value.value) && connectedDigit) {
(*rootHandle)->value.value = TOY_VALUE_TO_FLOAT( -TOY_VALUE_AS_FLOAT((*rootHandle)->value.value) );
(*rootHandle)->value.value = TOY_VALUE_FROM_FLOAT( -TOY_VALUE_AS_FLOAT((*rootHandle)->value.value) );
}
else {
//actually emit the negation node
@@ -296,7 +296,7 @@ static Toy_AstFlag unary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast*
//inverted booleans
if ((*rootHandle)->type == TOY_AST_VALUE && TOY_VALUE_IS_BOOLEAN((*rootHandle)->value.value)) {
(*rootHandle)->value.value = TOY_VALUE_TO_BOOLEAN( !TOY_VALUE_AS_BOOLEAN((*rootHandle)->value.value) );
(*rootHandle)->value.value = TOY_VALUE_FROM_BOOLEAN( !TOY_VALUE_AS_BOOLEAN((*rootHandle)->value.value) );
}
else {
//actually emit the negation node

View File

@@ -19,3 +19,4 @@ typedef struct Toy_Parser {
TOY_API void Toy_bindParser(Toy_Parser* parser, Toy_Lexer* lexer);
TOY_API Toy_Ast* Toy_scanParser(Toy_Bucket** bucketHandle, Toy_Parser* parser);
TOY_API void Toy_resetParser(Toy_Parser* parser);

View File

@@ -1,3 +1,5 @@
#pragma once
#include "toy_common.h"
//handle callbacks for printing to the terminal, or elsewhere

View File

@@ -27,3 +27,4 @@ typedef struct Toy_Routine {
} Toy_Routine;
TOY_API void* Toy_compileRoutine(Toy_Ast* ast);

View File

@@ -15,3 +15,4 @@ TOY_API void Toy_freeStack(Toy_Stack* stack);
TOY_API void Toy_pushStack(Toy_Stack** stackHandle, Toy_Value value);
TOY_API Toy_Value Toy_peekStack(Toy_Stack** stackHandle);
TOY_API Toy_Value Toy_popStack(Toy_Stack** stackHandle);

View File

@@ -47,6 +47,7 @@ Toy_String* Toy_createStringLength(Toy_Bucket** bucketHandle, const char* cstrin
ret->type = TOY_STRING_LEAF;
ret->length = length;
ret->refCount = 1;
ret->cachedHash = 0; //don't calc until needed
memcpy(ret->as.leaf.data, cstring, length);
ret->as.leaf.data[length] = '\0';
@@ -61,6 +62,7 @@ TOY_API Toy_String* Toy_createNameString(Toy_Bucket** bucketHandle, const char*
ret->type = TOY_STRING_NAME;
ret->length = length;
ret->refCount = 1;
ret->cachedHash = 0; //don't calc until needed
memcpy(ret->as.name.data, cname, length);
ret->as.name.data[length] = '\0';
@@ -87,6 +89,7 @@ Toy_String* Toy_deepCopyString(Toy_Bucket** bucketHandle, Toy_String* str) {
ret->type = TOY_STRING_LEAF;
ret->length = str->length;
ret->refCount = 1;
ret->cachedHash = str->cachedHash;
deepCopyUtil(ret->as.leaf.data, str); //copy each leaf into the buffer
ret->as.leaf.data[ret->length] = '\0';
}
@@ -94,6 +97,7 @@ Toy_String* Toy_deepCopyString(Toy_Bucket** bucketHandle, Toy_String* str) {
ret->type = TOY_STRING_NAME;
ret->length = str->length;
ret->refCount = 1;
ret->cachedHash = str->cachedHash;
memcpy(ret->as.name.data, str->as.name.data, str->length);
ret->as.name.data[ret->length] = '\0';
}
@@ -117,6 +121,7 @@ Toy_String* Toy_concatStrings(Toy_Bucket** bucketHandle, Toy_String* left, Toy_S
ret->type = TOY_STRING_NODE;
ret->length = left->length + right->length;
ret->refCount = 1;
ret->cachedHash = 0; //don't calc until needed
ret->as.node.left = left;
ret->as.node.right = right;

View File

@@ -1,3 +1,5 @@
#pragma once
#include "toy_common.h"
#include "toy_bucket.h"
@@ -13,8 +15,7 @@ typedef struct Toy_String { //32 | 64 BITNESS
unsigned int length; //4 | 4
unsigned int refCount; //4 | 4
int _padding; //4 | 4
unsigned int cachedHash; //4 | 4
union {
struct {
@@ -52,3 +53,4 @@ TOY_API int Toy_getStringRefCount(Toy_String* str);
TOY_API char* Toy_getStringRawBuffer(Toy_String* str); //allocates the buffer on the heap, needs to be freed
TOY_API int Toy_compareStrings(Toy_String* left, Toy_String* right); //return value mimics strcmp()

View File

@@ -18,7 +18,7 @@ static void probeAndInsert(Toy_Table** tableHandle, Toy_Value key, Toy_Value val
//probe
while (true) {
//if we're overriding an existing value
if (TOY_VALUE_IS_EQUAL((*tableHandle)->data[probe].key, key)) {
if (TOY_VALUES_ARE_EQUAL((*tableHandle)->data[probe].key, key)) {
(*tableHandle)->data[probe] = entry;
//TODO: benchmark the psl optimisation
@@ -120,13 +120,13 @@ Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key) {
while (true) {
//found the entry
if (TOY_VALUE_IS_EQUAL((*tableHandle)->data[probe].key, key)) {
if (TOY_VALUES_ARE_EQUAL((*tableHandle)->data[probe].key, key)) {
return (*tableHandle)->data[probe].value;
}
//if its an empty slot
if (TOY_VALUE_IS_NULL((*tableHandle)->data[probe].key)) {
return TOY_VALUE_TO_NULL();
return TOY_VALUE_FROM_NULL();
}
//adjust and continue
@@ -145,7 +145,7 @@ void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key) {
while (true) {
//found the entry
if (TOY_VALUE_IS_EQUAL((*tableHandle)->data[probe].key, key)) {
if (TOY_VALUES_ARE_EQUAL((*tableHandle)->data[probe].key, key)) {
break;
}
@@ -174,6 +174,6 @@ void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key) {
}
//finally, wipe the removed entry
(*tableHandle)->data[wipe] = (Toy_TableEntry){ .key = TOY_VALUE_TO_NULL(), .value = TOY_VALUE_TO_NULL(), .psl = 0 };
(*tableHandle)->data[wipe] = (Toy_TableEntry){ .key = TOY_VALUE_FROM_NULL(), .value = TOY_VALUE_FROM_NULL(), .psl = 0 };
(*tableHandle)->count--;
}

View File

@@ -25,3 +25,4 @@ TOY_API void Toy_freeTable(Toy_Table* table);
TOY_API void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value);
TOY_API Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key);
TOY_API void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key);

View File

@@ -106,3 +106,4 @@ typedef enum Toy_TokenType {
TOY_TOKEN_ERROR,
TOY_TOKEN_EOF,
} Toy_TokenType;

View File

@@ -1,8 +1,11 @@
#include "toy_value.h"
#include "toy_console_colors.h"
#include "toy_print.h"
#include "toy_string.h"
#include <stdio.h>
#include <stdlib.h>
bool Toy_private_isTruthy(Toy_Value value) {
//null is an error
@@ -21,7 +24,7 @@ bool Toy_private_isTruthy(Toy_Value value) {
bool Toy_private_isEqual(Toy_Value left, Toy_Value right) {
//temp check
if (right.type > TOY_VALUE_FLOAT) {
if (right.type > TOY_VALUE_STRING) {
Toy_error(TOY_CC_ERROR "ERROR: Unknown types in value equality comparison\n" TOY_CC_RESET); //TODO: varargs
}
@@ -51,6 +54,11 @@ bool Toy_private_isEqual(Toy_Value left, Toy_Value right) {
return false;
case TOY_VALUE_STRING:
if (TOY_VALUE_IS_STRING(right)) {
return Toy_compareStrings(TOY_VALUE_AS_STRING(left), TOY_VALUE_AS_STRING(right)) == 0;
}
return false;
case TOY_VALUE_ARRAY:
case TOY_VALUE_DICTIONARY:
case TOY_VALUE_FUNCTION:
@@ -96,7 +104,28 @@ unsigned int Toy_hashValue(Toy_Value value) {
case TOY_VALUE_FLOAT:
return hashUInt( *((int*)(&TOY_VALUE_AS_FLOAT(value))) );
case TOY_VALUE_STRING:
case TOY_VALUE_STRING: {
Toy_String* str = TOY_VALUE_AS_STRING(value);
if (str->cachedHash != 0) {
return str->cachedHash;
}
else if (str->type == TOY_STRING_NODE) {
//TODO: I wonder it it would be possible to discretely swap the composite node string with a new leaf string here? Would that speed up other parts of the code by not having to walk the tree?
char* buffer = Toy_getStringRawBuffer(str);
str->cachedHash = hashCString(buffer);
free(buffer);
}
else if (str->type == TOY_STRING_LEAF) {
str->cachedHash = hashCString(str->as.leaf.data);
}
else if (str->type == TOY_STRING_NAME) {
str->cachedHash = hashCString(str->as.name.data);
}
return str->cachedHash;
}
case TOY_VALUE_ARRAY:
case TOY_VALUE_DICTIONARY:
case TOY_VALUE_FUNCTION:

View File

@@ -2,6 +2,9 @@
#include "toy_common.h"
//forward declarations
struct Toy_String;
typedef enum Toy_ValueType {
TOY_VALUE_NULL,
TOY_VALUE_BOOLEAN,
@@ -20,15 +23,15 @@ typedef struct Toy_Value { //32 | 64 BITNESS
bool boolean; //1 | 1
int integer; //4 | 4
float number; //4 | 4
//TODO: strings
struct Toy_String* string; //4 | 8
//TODO: arrays
//TODO: dictonaries
//TODO: functions
//TODO: opaque
} as; //4 | 4
} as; //4 | 8
Toy_ValueType type; //4 | 4
} Toy_Value; //8 | 8
} Toy_Value; //8 | 12
#define TOY_VALUE_IS_NULL(value) ((value).type == TOY_VALUE_NULL)
#define TOY_VALUE_IS_BOOLEAN(value) ((value).type == TOY_VALUE_BOOLEAN)
@@ -43,18 +46,21 @@ typedef struct Toy_Value { //32 | 64 BITNESS
#define TOY_VALUE_AS_BOOLEAN(value) ((value).as.boolean)
#define TOY_VALUE_AS_INTEGER(value) ((value).as.integer)
#define TOY_VALUE_AS_FLOAT(value) ((value).as.number)
#define TOY_VALUE_AS_STRING(value) ((value).as.string)
//TODO: more
#define TOY_VALUE_TO_NULL() ((Toy_Value){{ .integer = 0 }, TOY_VALUE_NULL})
#define TOY_VALUE_TO_BOOLEAN(value) ((Toy_Value){{ .boolean = value }, TOY_VALUE_BOOLEAN})
#define TOY_VALUE_TO_INTEGER(value) ((Toy_Value){{ .integer = value }, TOY_VALUE_INTEGER})
#define TOY_VALUE_TO_FLOAT(value) ((Toy_Value){{ .number = value }, TOY_VALUE_FLOAT})
#define TOY_VALUE_FROM_NULL() ((Toy_Value){{ .integer = 0 }, TOY_VALUE_NULL})
#define TOY_VALUE_FROM_BOOLEAN(value) ((Toy_Value){{ .boolean = value }, TOY_VALUE_BOOLEAN})
#define TOY_VALUE_FROM_INTEGER(value) ((Toy_Value){{ .integer = value }, TOY_VALUE_INTEGER})
#define TOY_VALUE_FROM_FLOAT(value) ((Toy_Value){{ .number = value }, TOY_VALUE_FLOAT})
#define TOY_VALUE_FROM_STRING(value) ((Toy_Value){{ .string = value }, TOY_VALUE_STRING})
//TODO: more
#define TOY_VALUE_IS_TRUTHY(value) Toy_private_isTruthy(value)
TOY_API bool Toy_private_isTruthy(Toy_Value value);
#define TOY_VALUE_IS_EQUAL(left, right) Toy_private_isEqual(left, right)
#define TOY_VALUES_ARE_EQUAL(left, right) Toy_private_isEqual(left, right)
TOY_API bool Toy_private_isEqual(Toy_Value left, Toy_Value right);
unsigned int Toy_hashValue(Toy_Value value);

View File

@@ -38,7 +38,7 @@ static inline void fix_alignment(Toy_VM* vm) {
static void processRead(Toy_VM* vm) {
Toy_ValueType type = READ_BYTE(vm);
Toy_Value value = TOY_VALUE_TO_NULL();
Toy_Value value = TOY_VALUE_FROM_NULL();
switch(type) {
case TOY_VALUE_NULL: {
@@ -47,19 +47,19 @@ static void processRead(Toy_VM* vm) {
}
case TOY_VALUE_BOOLEAN: {
value = TOY_VALUE_TO_BOOLEAN((bool)READ_BYTE(vm));
value = TOY_VALUE_FROM_BOOLEAN((bool)READ_BYTE(vm));
break;
}
case TOY_VALUE_INTEGER: {
fix_alignment(vm);
value = TOY_VALUE_TO_INTEGER(READ_INT(vm));
value = TOY_VALUE_FROM_INTEGER(READ_INT(vm));
break;
}
case TOY_VALUE_FLOAT: {
fix_alignment(vm);
value = TOY_VALUE_TO_FLOAT(READ_FLOAT(vm));
value = TOY_VALUE_FROM_FLOAT(READ_FLOAT(vm));
break;
}
@@ -126,30 +126,30 @@ static void processArithmetic(Toy_VM* vm, Toy_OpcodeType opcode) {
//coerce ints into floats if needed
if (TOY_VALUE_IS_INTEGER(left) && TOY_VALUE_IS_FLOAT(right)) {
left = TOY_VALUE_TO_FLOAT( (float)TOY_VALUE_AS_INTEGER(left) );
left = TOY_VALUE_FROM_FLOAT( (float)TOY_VALUE_AS_INTEGER(left) );
}
else
if (TOY_VALUE_IS_FLOAT(left) && TOY_VALUE_IS_INTEGER(right)) {
right = TOY_VALUE_TO_FLOAT( (float)TOY_VALUE_AS_INTEGER(right) );
right = TOY_VALUE_FROM_FLOAT( (float)TOY_VALUE_AS_INTEGER(right) );
}
//apply operation
Toy_Value result = TOY_VALUE_TO_NULL();
Toy_Value result = TOY_VALUE_FROM_NULL();
if (opcode == TOY_OPCODE_ADD) {
result = TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_TO_FLOAT( TOY_VALUE_AS_FLOAT(left) + TOY_VALUE_AS_FLOAT(right)) : TOY_VALUE_TO_INTEGER( TOY_VALUE_AS_INTEGER(left) + TOY_VALUE_AS_INTEGER(right) );
result = TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_FROM_FLOAT( TOY_VALUE_AS_FLOAT(left) + TOY_VALUE_AS_FLOAT(right)) : TOY_VALUE_FROM_INTEGER( TOY_VALUE_AS_INTEGER(left) + TOY_VALUE_AS_INTEGER(right) );
}
else if (opcode == TOY_OPCODE_SUBTRACT) {
result = TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_TO_FLOAT( TOY_VALUE_AS_FLOAT(left) - TOY_VALUE_AS_FLOAT(right)) : TOY_VALUE_TO_INTEGER( TOY_VALUE_AS_INTEGER(left) - TOY_VALUE_AS_INTEGER(right) );
result = TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_FROM_FLOAT( TOY_VALUE_AS_FLOAT(left) - TOY_VALUE_AS_FLOAT(right)) : TOY_VALUE_FROM_INTEGER( TOY_VALUE_AS_INTEGER(left) - TOY_VALUE_AS_INTEGER(right) );
}
else if (opcode == TOY_OPCODE_MULTIPLY) {
result = TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_TO_FLOAT( TOY_VALUE_AS_FLOAT(left) * TOY_VALUE_AS_FLOAT(right)) : TOY_VALUE_TO_INTEGER( TOY_VALUE_AS_INTEGER(left) * TOY_VALUE_AS_INTEGER(right) );
result = TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_FROM_FLOAT( TOY_VALUE_AS_FLOAT(left) * TOY_VALUE_AS_FLOAT(right)) : TOY_VALUE_FROM_INTEGER( TOY_VALUE_AS_INTEGER(left) * TOY_VALUE_AS_INTEGER(right) );
}
else if (opcode == TOY_OPCODE_DIVIDE) {
result = TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_TO_FLOAT( TOY_VALUE_AS_FLOAT(left) / TOY_VALUE_AS_FLOAT(right)) : TOY_VALUE_TO_INTEGER( TOY_VALUE_AS_INTEGER(left) / TOY_VALUE_AS_INTEGER(right) );
result = TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_FROM_FLOAT( TOY_VALUE_AS_FLOAT(left) / TOY_VALUE_AS_FLOAT(right)) : TOY_VALUE_FROM_INTEGER( TOY_VALUE_AS_INTEGER(left) / TOY_VALUE_AS_INTEGER(right) );
}
else if (opcode == TOY_OPCODE_MODULO) {
result = TOY_VALUE_TO_INTEGER( TOY_VALUE_AS_INTEGER(left) % TOY_VALUE_AS_INTEGER(right) );
result = TOY_VALUE_FROM_INTEGER( TOY_VALUE_AS_INTEGER(left) % TOY_VALUE_AS_INTEGER(right) );
}
else {
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid opcode %d passed to processArithmetic, exiting\n" TOY_CC_RESET, opcode);
@@ -166,14 +166,14 @@ static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) {
//most things can be equal, so handle it separately
if (opcode == TOY_OPCODE_COMPARE_EQUAL) {
bool equal = TOY_VALUE_IS_EQUAL(left, right);
bool equal = TOY_VALUES_ARE_EQUAL(left, right);
//equality has an optional "negate" opcode within it's word
if (READ_BYTE(vm) != TOY_OPCODE_NEGATE) {
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN(equal) );
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(equal) );
}
else {
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN(!equal) );
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(!equal) );
}
return;
@@ -181,25 +181,25 @@ static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) {
//coerce ints into floats if needed
if (TOY_VALUE_IS_INTEGER(left) && TOY_VALUE_IS_FLOAT(right)) {
left = TOY_VALUE_TO_FLOAT( (float)TOY_VALUE_AS_INTEGER(left) );
left = TOY_VALUE_FROM_FLOAT( (float)TOY_VALUE_AS_INTEGER(left) );
}
else
if (TOY_VALUE_IS_FLOAT(left) && TOY_VALUE_IS_INTEGER(right)) {
right = TOY_VALUE_TO_FLOAT( (float)TOY_VALUE_AS_INTEGER(right) );
right = TOY_VALUE_FROM_FLOAT( (float)TOY_VALUE_AS_INTEGER(right) );
}
//other opcodes
if (opcode == TOY_OPCODE_COMPARE_LESS) {
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN(TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_AS_FLOAT(left) < TOY_VALUE_AS_FLOAT(right) : TOY_VALUE_AS_INTEGER(left) < TOY_VALUE_AS_INTEGER(right)) );
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_AS_FLOAT(left) < TOY_VALUE_AS_FLOAT(right) : TOY_VALUE_AS_INTEGER(left) < TOY_VALUE_AS_INTEGER(right)) );
}
else if (opcode == TOY_OPCODE_COMPARE_LESS_EQUAL) {
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN(TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_AS_FLOAT(left) <= TOY_VALUE_AS_FLOAT(right) : TOY_VALUE_AS_INTEGER(left) <= TOY_VALUE_AS_INTEGER(right)) );
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_AS_FLOAT(left) <= TOY_VALUE_AS_FLOAT(right) : TOY_VALUE_AS_INTEGER(left) <= TOY_VALUE_AS_INTEGER(right)) );
}
else if (opcode == TOY_OPCODE_COMPARE_GREATER) {
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN(TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_AS_FLOAT(left) > TOY_VALUE_AS_FLOAT(right) : TOY_VALUE_AS_INTEGER(left) > TOY_VALUE_AS_INTEGER(right)) );
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_AS_FLOAT(left) > TOY_VALUE_AS_FLOAT(right) : TOY_VALUE_AS_INTEGER(left) > TOY_VALUE_AS_INTEGER(right)) );
}
else if (opcode == TOY_OPCODE_COMPARE_GREATER_EQUAL) {
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN(TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_AS_FLOAT(left) >= TOY_VALUE_AS_FLOAT(right) : TOY_VALUE_AS_INTEGER(left) >= TOY_VALUE_AS_INTEGER(right)) );
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(TOY_VALUE_IS_FLOAT(left) ? TOY_VALUE_AS_FLOAT(left) >= TOY_VALUE_AS_FLOAT(right) : TOY_VALUE_AS_INTEGER(left) >= TOY_VALUE_AS_INTEGER(right)) );
}
else {
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid opcode %d passed to processComparison, exiting\n" TOY_CC_RESET, opcode);
@@ -212,23 +212,23 @@ static void processLogical(Toy_VM* vm, Toy_OpcodeType opcode) {
Toy_Value right = Toy_popStack(&vm->stack);
Toy_Value left = Toy_popStack(&vm->stack);
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN( TOY_VALUE_IS_TRUTHY(left) && TOY_VALUE_IS_TRUTHY(right) ));
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN( TOY_VALUE_IS_TRUTHY(left) && TOY_VALUE_IS_TRUTHY(right) ));
}
else if (opcode == TOY_OPCODE_OR) {
Toy_Value right = Toy_popStack(&vm->stack);
Toy_Value left = Toy_popStack(&vm->stack);
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN( TOY_VALUE_IS_TRUTHY(left) || TOY_VALUE_IS_TRUTHY(right) ));
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN( TOY_VALUE_IS_TRUTHY(left) || TOY_VALUE_IS_TRUTHY(right) ));
}
else if (opcode == TOY_OPCODE_TRUTHY) {
Toy_Value top = Toy_popStack(&vm->stack);
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN( TOY_VALUE_IS_TRUTHY(top) ));
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN( TOY_VALUE_IS_TRUTHY(top) ));
}
else if (opcode == TOY_OPCODE_NEGATE) {
Toy_Value top = Toy_popStack(&vm->stack);
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN( !TOY_VALUE_IS_TRUTHY(top) ));
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN( !TOY_VALUE_IS_TRUTHY(top) ));
}
else {
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid opcode %d passed to processLogical, exiting\n" TOY_CC_RESET, opcode);

View File

@@ -64,7 +64,7 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
{
//emit to an AST
Toy_Ast* ast = NULL;
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_FROM_INTEGER(42));
//check if it worked
if (
@@ -81,7 +81,7 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
{
//build the AST
Toy_Ast* ast = NULL;
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_FROM_INTEGER(42));
Toy_private_emitAstUnary(bucketHandle, &ast, TOY_AST_FLAG_NEGATE);
//check if it worked
@@ -102,8 +102,8 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
//build the AST
Toy_Ast* ast = NULL;
Toy_Ast* right = NULL;
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_FROM_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_FROM_INTEGER(69));
Toy_private_emitAstBinary(bucketHandle, &ast, TOY_AST_FLAG_ADD, right);
//check if it worked
@@ -126,8 +126,8 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
//build the AST
Toy_Ast* ast = NULL;
Toy_Ast* right = NULL;
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_FROM_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_FROM_INTEGER(69));
Toy_private_emitAstBinary(bucketHandle, &ast, TOY_AST_FLAG_ADD, right);
Toy_private_emitAstGroup(bucketHandle, &ast);
@@ -153,8 +153,8 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
//build the AST
Toy_Ast* ast = NULL;
Toy_Ast* right = NULL;
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_FROM_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_FROM_INTEGER(69));
Toy_private_emitAstBinary(bucketHandle, &ast, TOY_AST_FLAG_ADD, right);
Toy_private_emitAstPrint(bucketHandle, &ast);
@@ -186,8 +186,8 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
//build the AST
Toy_Ast* ast = NULL;
Toy_Ast* right = NULL;
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_FROM_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_FROM_INTEGER(69));
Toy_private_emitAstBinary(bucketHandle, &ast, TOY_AST_FLAG_ADD, right);
Toy_private_emitAstGroup(bucketHandle, &ast);

View File

@@ -27,9 +27,9 @@ int test_stack_basics() {
Toy_Stack* stack = Toy_allocateStack();
//check if it worked (push)
Toy_pushStack(&stack, TOY_VALUE_TO_INTEGER(42));
Toy_pushStack(&stack, TOY_VALUE_TO_INTEGER(69));
Toy_pushStack(&stack, TOY_VALUE_TO_INTEGER(420));
Toy_pushStack(&stack, TOY_VALUE_FROM_INTEGER(42));
Toy_pushStack(&stack, TOY_VALUE_FROM_INTEGER(69));
Toy_pushStack(&stack, TOY_VALUE_FROM_INTEGER(420));
if (
stack == NULL ||
stack->capacity != 64 ||
@@ -89,7 +89,7 @@ int test_stack_stress() {
//allocate 500 values
for (int i = 0; i < 500; i++) {
Toy_pushStack(&stack, TOY_VALUE_TO_INTEGER(i));
Toy_pushStack(&stack, TOY_VALUE_FROM_INTEGER(i));
}
//check if it worked

View File

@@ -30,8 +30,8 @@ int test_table_simple_insert_lookup_and_remove() {
//setup
Toy_Table* table = Toy_allocateTable();
Toy_Value key = TOY_VALUE_TO_INTEGER(1);
Toy_Value value = TOY_VALUE_TO_INTEGER(42);
Toy_Value key = TOY_VALUE_FROM_INTEGER(1);
Toy_Value value = TOY_VALUE_FROM_INTEGER(42);
//insert
Toy_insertTable(&table, key, value);
@@ -45,7 +45,7 @@ int test_table_simple_insert_lookup_and_remove() {
}
//lookup
Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_TO_INTEGER(1));
Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_FROM_INTEGER(1));
//check lookup
if (table == NULL ||
@@ -59,7 +59,7 @@ int test_table_simple_insert_lookup_and_remove() {
}
//remove
Toy_removeTable(&table, TOY_VALUE_TO_INTEGER(1));
Toy_removeTable(&table, TOY_VALUE_FROM_INTEGER(1));
//check remove
if (table == NULL ||
@@ -93,7 +93,7 @@ int test_table_contents_no_expansion() {
Toy_Table* table = Toy_allocateTable();
//insert a key and value
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42));
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(1), TOY_VALUE_FROM_INTEGER(42));
//check the state
if (table == NULL ||
@@ -118,9 +118,9 @@ int test_table_contents_no_expansion() {
Toy_Table* table = Toy_allocateTable();
//inserts
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(2), TOY_VALUE_TO_INTEGER(69)); //hash: 8
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(3), TOY_VALUE_TO_INTEGER(420)); //hash: 5
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(1), TOY_VALUE_FROM_INTEGER(42)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(2), TOY_VALUE_FROM_INTEGER(69)); //hash: 8
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(3), TOY_VALUE_FROM_INTEGER(420)); //hash: 5
//check the state
if (table == NULL ||
@@ -147,10 +147,10 @@ int test_table_contents_no_expansion() {
Toy_Table* table = Toy_allocateTable();
//inserts
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(14), TOY_VALUE_TO_INTEGER(69)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(76), TOY_VALUE_TO_INTEGER(420)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(80), TOY_VALUE_TO_INTEGER(8891)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(1), TOY_VALUE_FROM_INTEGER(42)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(14), TOY_VALUE_FROM_INTEGER(69)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(76), TOY_VALUE_FROM_INTEGER(420)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(80), TOY_VALUE_FROM_INTEGER(8891)); //hash: 7
//check the state
if (table == NULL ||
@@ -178,9 +178,9 @@ int test_table_contents_no_expansion() {
Toy_Table* table = Toy_allocateTable();
//inserts
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(69)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(420)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(17), TOY_VALUE_FROM_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(33), TOY_VALUE_FROM_INTEGER(69)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(70), TOY_VALUE_FROM_INTEGER(420)); //hash: 15
//check the state
if (table == NULL ||
@@ -207,12 +207,12 @@ int test_table_contents_no_expansion() {
Toy_Table* table = Toy_allocateTable();
//inserts
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(69)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(420)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(17), TOY_VALUE_FROM_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(33), TOY_VALUE_FROM_INTEGER(69)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(70), TOY_VALUE_FROM_INTEGER(420)); //hash: 15
//lookup
Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_TO_INTEGER(33));
Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_FROM_INTEGER(33));
//check the state
if (table == NULL ||
@@ -238,10 +238,10 @@ int test_table_contents_no_expansion() {
Toy_Table* table = Toy_allocateTable();
//inserts
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(69)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(420)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(8891)); //hash: 1
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(17), TOY_VALUE_FROM_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(33), TOY_VALUE_FROM_INTEGER(69)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(70), TOY_VALUE_FROM_INTEGER(420)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(35), TOY_VALUE_FROM_INTEGER(8891)); //hash: 1
//check the state
if (table == NULL ||
@@ -269,13 +269,13 @@ int test_table_contents_no_expansion() {
Toy_Table* table = Toy_allocateTable();
//inserts
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(69)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(420)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(8891)); //hash: 1
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(17), TOY_VALUE_FROM_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(33), TOY_VALUE_FROM_INTEGER(69)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(70), TOY_VALUE_FROM_INTEGER(420)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(35), TOY_VALUE_FROM_INTEGER(8891)); //hash: 1
//remove
Toy_removeTable(&table, TOY_VALUE_TO_INTEGER(33));
Toy_removeTable(&table, TOY_VALUE_FROM_INTEGER(33));
//check the state
if (table == NULL ||
@@ -307,7 +307,7 @@ int test_table_contents_with_expansions() {
//insert a key and value
for (int i = 0; i < 20; i++) {
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(i), TOY_VALUE_TO_INTEGER(42));
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(i), TOY_VALUE_FROM_INTEGER(42));
}
//check the state
@@ -331,26 +331,26 @@ int test_table_contents_with_expansions() {
Toy_Table* table = Toy_allocateTable();
//inserts
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(0), TOY_VALUE_TO_INTEGER(42)); //hash: 0
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(42)); //hash: 1
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(19), TOY_VALUE_TO_INTEGER(42)); //hash: 2
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(8), TOY_VALUE_TO_INTEGER(42)); //hash: 3
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(10), TOY_VALUE_TO_INTEGER(42)); //hash: 4
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(3), TOY_VALUE_TO_INTEGER(42)); //hash: 5
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(28), TOY_VALUE_TO_INTEGER(42)); //hash: 6
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(6), TOY_VALUE_TO_INTEGER(42)); //hash: 8
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(93), TOY_VALUE_TO_INTEGER(42)); //hash: 9
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(85), TOY_VALUE_TO_INTEGER(42)); //hash: 10
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(9), TOY_VALUE_TO_INTEGER(42)); //hash: 11
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(11), TOY_VALUE_TO_INTEGER(42)); //hash: 12
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(22), TOY_VALUE_TO_INTEGER(42)); //hash: 13
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(13), TOY_VALUE_TO_INTEGER(42)); //hash: 14
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(43), TOY_VALUE_TO_INTEGER(42)); //hash: 16
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(4), TOY_VALUE_TO_INTEGER(42)); //hash: 17
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(5), TOY_VALUE_TO_INTEGER(42)); //hash: 18
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(7), TOY_VALUE_TO_INTEGER(42)); //hash: 19
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(0), TOY_VALUE_FROM_INTEGER(42)); //hash: 0
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(35), TOY_VALUE_FROM_INTEGER(42)); //hash: 1
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(19), TOY_VALUE_FROM_INTEGER(42)); //hash: 2
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(8), TOY_VALUE_FROM_INTEGER(42)); //hash: 3
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(10), TOY_VALUE_FROM_INTEGER(42)); //hash: 4
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(3), TOY_VALUE_FROM_INTEGER(42)); //hash: 5
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(28), TOY_VALUE_FROM_INTEGER(42)); //hash: 6
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(1), TOY_VALUE_FROM_INTEGER(42)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(6), TOY_VALUE_FROM_INTEGER(42)); //hash: 8
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(93), TOY_VALUE_FROM_INTEGER(42)); //hash: 9
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(85), TOY_VALUE_FROM_INTEGER(42)); //hash: 10
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(9), TOY_VALUE_FROM_INTEGER(42)); //hash: 11
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(11), TOY_VALUE_FROM_INTEGER(42)); //hash: 12
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(22), TOY_VALUE_FROM_INTEGER(42)); //hash: 13
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(13), TOY_VALUE_FROM_INTEGER(42)); //hash: 14
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(17), TOY_VALUE_FROM_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(43), TOY_VALUE_FROM_INTEGER(42)); //hash: 16
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(4), TOY_VALUE_FROM_INTEGER(42)); //hash: 17
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(5), TOY_VALUE_FROM_INTEGER(42)); //hash: 18
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(7), TOY_VALUE_FROM_INTEGER(42)); //hash: 19
//check the state
if (table == NULL ||
@@ -395,29 +395,29 @@ int test_table_contents_with_expansions() {
Toy_Table* table = Toy_allocateTable();
//inserts
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(0), TOY_VALUE_TO_INTEGER(42)); //hash: 0
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(42)); //hash: 1
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(19), TOY_VALUE_TO_INTEGER(42)); //hash: 2
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(8), TOY_VALUE_TO_INTEGER(42)); //hash: 3
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(10), TOY_VALUE_TO_INTEGER(42)); //hash: 4
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(3), TOY_VALUE_TO_INTEGER(42)); //hash: 5
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(28), TOY_VALUE_TO_INTEGER(42)); //hash: 6
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(6), TOY_VALUE_TO_INTEGER(42)); //hash: 8
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(93), TOY_VALUE_TO_INTEGER(42)); //hash: 9
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(85), TOY_VALUE_TO_INTEGER(42)); //hash: 10
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(9), TOY_VALUE_TO_INTEGER(42)); //hash: 11
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(11), TOY_VALUE_TO_INTEGER(42)); //hash: 12
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(22), TOY_VALUE_TO_INTEGER(42)); //hash: 13
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(13), TOY_VALUE_TO_INTEGER(42)); //hash: 14
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(43), TOY_VALUE_TO_INTEGER(42)); //hash: 16
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(4), TOY_VALUE_TO_INTEGER(42)); //hash: 17
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(5), TOY_VALUE_TO_INTEGER(42)); //hash: 18
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(7), TOY_VALUE_TO_INTEGER(42)); //hash: 19
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(0), TOY_VALUE_FROM_INTEGER(42)); //hash: 0
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(35), TOY_VALUE_FROM_INTEGER(42)); //hash: 1
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(19), TOY_VALUE_FROM_INTEGER(42)); //hash: 2
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(8), TOY_VALUE_FROM_INTEGER(42)); //hash: 3
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(10), TOY_VALUE_FROM_INTEGER(42)); //hash: 4
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(3), TOY_VALUE_FROM_INTEGER(42)); //hash: 5
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(28), TOY_VALUE_FROM_INTEGER(42)); //hash: 6
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(1), TOY_VALUE_FROM_INTEGER(42)); //hash: 7
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(6), TOY_VALUE_FROM_INTEGER(42)); //hash: 8
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(93), TOY_VALUE_FROM_INTEGER(42)); //hash: 9
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(85), TOY_VALUE_FROM_INTEGER(42)); //hash: 10
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(9), TOY_VALUE_FROM_INTEGER(42)); //hash: 11
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(11), TOY_VALUE_FROM_INTEGER(42)); //hash: 12
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(22), TOY_VALUE_FROM_INTEGER(42)); //hash: 13
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(13), TOY_VALUE_FROM_INTEGER(42)); //hash: 14
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(17), TOY_VALUE_FROM_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(43), TOY_VALUE_FROM_INTEGER(42)); //hash: 16
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(4), TOY_VALUE_FROM_INTEGER(42)); //hash: 17
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(5), TOY_VALUE_FROM_INTEGER(42)); //hash: 18
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(7), TOY_VALUE_FROM_INTEGER(42)); //hash: 19
//insert one more
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(42)); //hash: 15
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(70), TOY_VALUE_FROM_INTEGER(42)); //hash: 15
//check the state
if (table == NULL ||
@@ -464,29 +464,29 @@ int test_table_contents_with_expansions() {
Toy_Table* table = Toy_allocateTable();
//inserts
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(123), TOY_VALUE_TO_INTEGER(42)); //hash: 20
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(42), TOY_VALUE_TO_INTEGER(42)); //hash: 21
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(132), TOY_VALUE_TO_INTEGER(42)); //hash: 22
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(34), TOY_VALUE_TO_INTEGER(42)); //hash: 23
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(2), TOY_VALUE_TO_INTEGER(42)); //hash: 24
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(32), TOY_VALUE_TO_INTEGER(42)); //hash: 25
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(21), TOY_VALUE_TO_INTEGER(42)); //hash: 26
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(44), TOY_VALUE_TO_INTEGER(42)); //hash: 27
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(104), TOY_VALUE_TO_INTEGER(42)); //hash: 28
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(15), TOY_VALUE_TO_INTEGER(42)); //hash: 29
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(57), TOY_VALUE_TO_INTEGER(42)); //hash: 30
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(42)); //hash: 31
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(0), TOY_VALUE_TO_INTEGER(42)); //hash: 32
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(42)); //hash: 33
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(19), TOY_VALUE_TO_INTEGER(42)); //hash: 34
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(8), TOY_VALUE_TO_INTEGER(42)); //hash: 35
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(10), TOY_VALUE_TO_INTEGER(42)); //hash: 36
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(3), TOY_VALUE_TO_INTEGER(42)); //hash: 37
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(28), TOY_VALUE_TO_INTEGER(42)); //hash: 38
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 39
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(123), TOY_VALUE_FROM_INTEGER(42)); //hash: 20
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(42), TOY_VALUE_FROM_INTEGER(42)); //hash: 21
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(132), TOY_VALUE_FROM_INTEGER(42)); //hash: 22
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(34), TOY_VALUE_FROM_INTEGER(42)); //hash: 23
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(2), TOY_VALUE_FROM_INTEGER(42)); //hash: 24
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(32), TOY_VALUE_FROM_INTEGER(42)); //hash: 25
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(21), TOY_VALUE_FROM_INTEGER(42)); //hash: 26
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(44), TOY_VALUE_FROM_INTEGER(42)); //hash: 27
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(104), TOY_VALUE_FROM_INTEGER(42)); //hash: 28
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(15), TOY_VALUE_FROM_INTEGER(42)); //hash: 29
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(57), TOY_VALUE_FROM_INTEGER(42)); //hash: 30
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(33), TOY_VALUE_FROM_INTEGER(42)); //hash: 31
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(0), TOY_VALUE_FROM_INTEGER(42)); //hash: 32
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(35), TOY_VALUE_FROM_INTEGER(42)); //hash: 33
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(19), TOY_VALUE_FROM_INTEGER(42)); //hash: 34
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(8), TOY_VALUE_FROM_INTEGER(42)); //hash: 35
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(10), TOY_VALUE_FROM_INTEGER(42)); //hash: 36
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(3), TOY_VALUE_FROM_INTEGER(42)); //hash: 37
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(28), TOY_VALUE_FROM_INTEGER(42)); //hash: 38
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(1), TOY_VALUE_FROM_INTEGER(42)); //hash: 39
//insert one more
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(79), TOY_VALUE_TO_INTEGER(42)); //hash: 23
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(79), TOY_VALUE_FROM_INTEGER(42)); //hash: 23
//check the state
if (table == NULL ||
@@ -534,11 +534,11 @@ int test_table_contents_with_expansions() {
//inserts
for (int i = 0; i < 20; i++) { //enough to expand
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(i), TOY_VALUE_TO_INTEGER(100 - i));
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(i), TOY_VALUE_FROM_INTEGER(100 - i));
}
//lookup
Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_TO_INTEGER(15));
Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_FROM_INTEGER(15));
//check the state
if (table == NULL ||
@@ -576,10 +576,10 @@ int test_table_expansions_under_stress() {
//insert keys and values
for (int i = 0; i < 400; i++) {
Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(i), TOY_VALUE_TO_INTEGER(top - i));
Toy_insertTable(&table, TOY_VALUE_FROM_INTEGER(i), TOY_VALUE_FROM_INTEGER(top - i));
}
Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_TO_INTEGER(265));
Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_FROM_INTEGER(265));
//check the state
if (table == NULL ||

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;
}