mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
String literals are being parsed, compiled and printed, read more
Strings, due to their potentially large size, are stored outside of a routine's code section, in the data section. To access the correct string, you must read the jump index, then the real address from the jump table - and extra layer of indirection will result in more flexible data down the road, I hope. Other changes include: * Added string concat operator .. * Added TOY_STRING_MAX_LENGTH * Strings can't be created or concatenated longer than the max length * The parser will display a warning if the bucket is too small for a string at max length, but it will continue * Added TOY_BUCKET_IDEAL to correspend with max string length * The bucket now allocates an address that is 4-byte aligned * Fixed missing entries in the parser rule table * Corrected some failing TOY_BITNESS tests
This commit is contained in:
@@ -16,7 +16,7 @@ int test_sizeof_ast_64bit() {
|
||||
//run for each type
|
||||
TEST_SIZEOF(Toy_AstType, 4);
|
||||
TEST_SIZEOF(Toy_AstBlock, 32);
|
||||
TEST_SIZEOF(Toy_AstValue, 12);
|
||||
TEST_SIZEOF(Toy_AstValue, 24);
|
||||
TEST_SIZEOF(Toy_AstUnary, 16);
|
||||
TEST_SIZEOF(Toy_AstBinary, 24);
|
||||
TEST_SIZEOF(Toy_AstGroup, 16);
|
||||
@@ -245,7 +245,7 @@ int main() {
|
||||
#endif
|
||||
|
||||
{
|
||||
Toy_Bucket* bucketHandle = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucketHandle = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_type_emission(&bucketHandle);
|
||||
Toy_freeBucket(&bucketHandle);
|
||||
if (res == 0) {
|
||||
|
||||
@@ -69,33 +69,6 @@ int test_buckets() {
|
||||
Toy_freeBucket(&bucket);
|
||||
}
|
||||
|
||||
//test partitioning a bucket, several times, with an internal expansion, and awkward sizes
|
||||
{
|
||||
//init
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(32);
|
||||
|
||||
//grab some memory
|
||||
void* a = Toy_partitionBucket(&bucket, 16);
|
||||
void* b = Toy_partitionBucket(&bucket, 10);
|
||||
void* c = Toy_partitionBucket(&bucket, 10);
|
||||
void* d = Toy_partitionBucket(&bucket, 10);
|
||||
|
||||
//checks - awkward and mismatched sizes is not officially supported, but it should work
|
||||
if (
|
||||
bucket->capacity != 32 ||
|
||||
bucket->count != 20 ||
|
||||
bucket->next == NULL ||
|
||||
bucket->next->capacity != 32 ||
|
||||
bucket->next->count != 26)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to expand 'Toy_Bucket' with awkward/mismatched sizes correctly\n" TOY_CC_RESET);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
Toy_freeBucket(&bucket);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ int main() {
|
||||
int total = 0, res = 0;
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_bytecode_header(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -185,7 +185,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_bytecode_from_source(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -195,4 +195,4 @@ int main() {
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "toy_parser.h"
|
||||
#include "toy_console_colors.h"
|
||||
#include "toy_string.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//utils
|
||||
Toy_Ast* makeAstFromSource(Toy_Bucket** bucketHandle, const char* source) {
|
||||
@@ -184,7 +186,7 @@ int test_values(Toy_Bucket** bucketHandle) {
|
||||
TOY_VALUE_IS_INTEGER(ast->block.child->value.value) == false ||
|
||||
TOY_VALUE_AS_INTEGER(ast->block.child->value.value) != 1234567890)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser with integer value 42 with separators\n" TOY_CC_RESET);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser with integer value 1_234_567_890\n" TOY_CC_RESET);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -202,7 +204,26 @@ int test_values(Toy_Bucket** bucketHandle) {
|
||||
TOY_VALUE_IS_FLOAT(ast->block.child->value.value) == false ||
|
||||
TOY_VALUE_AS_FLOAT(ast->block.child->value.value) != 3.14159265f)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser with float value 3.1415 with separators\n" TOY_CC_RESET);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser with float value 3.141_592_65\n" TOY_CC_RESET);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//test string
|
||||
{
|
||||
Toy_Ast* ast = makeAstFromSource(bucketHandle, "\"Hello world!\";");
|
||||
|
||||
//check if it worked
|
||||
if (
|
||||
ast == NULL ||
|
||||
ast->type != TOY_AST_BLOCK ||
|
||||
ast->block.child == NULL ||
|
||||
ast->block.child->type != TOY_AST_VALUE ||
|
||||
TOY_VALUE_IS_STRING(ast->block.child->value.value) == false ||
|
||||
TOY_VALUE_AS_STRING(ast->block.child->value.value)->type != TOY_STRING_LEAF ||
|
||||
strcmp(TOY_VALUE_AS_STRING(ast->block.child->value.value)->as.leaf.data, "Hello world!") != 0)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser with string value 'Hello world!'\n" TOY_CC_RESET);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -578,7 +599,7 @@ int main() {
|
||||
int total = 0, res = 0;
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_simple_empty_parsers(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -588,7 +609,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_values(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -598,7 +619,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_unary(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -608,7 +629,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_binary(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -618,7 +639,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_precedence(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
|
||||
@@ -318,6 +318,105 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//produce a string value
|
||||
{
|
||||
//setup
|
||||
const char* source = "\"Hello world!\";";
|
||||
Toy_Lexer lexer;
|
||||
Toy_Parser parser;
|
||||
|
||||
Toy_bindLexer(&lexer, source);
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
void* buffer = Toy_compileRoutine(ast);
|
||||
int len = ((int*)buffer)[0];
|
||||
|
||||
//check header
|
||||
int* header = (int*)buffer;
|
||||
|
||||
if (header[0] != 64 || //total size
|
||||
header[1] != 0 || //param size
|
||||
header[2] != 4 || //jumps size
|
||||
header[3] != 16 || //data size
|
||||
header[4] != 0 || //subs size
|
||||
|
||||
// header[??] != ?? || //params address
|
||||
header[5] != 32 || //code address
|
||||
header[6] != 44 || //jumps address
|
||||
header[7] != 48 || //data address
|
||||
// header[??] != ?? || //subs address
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* code = buffer + 32; //8 values in the header, each 4 bytes
|
||||
|
||||
//check code
|
||||
if (
|
||||
//code start
|
||||
*((unsigned char*)(code + 0)) != TOY_OPCODE_READ ||
|
||||
*((unsigned char*)(code + 1)) != TOY_VALUE_STRING ||
|
||||
*((unsigned char*)(code + 2)) != 0 ||
|
||||
*((unsigned char*)(code + 3)) != 0 ||
|
||||
*(unsigned int*)(code + 4) != 0 || //the jump index
|
||||
*((unsigned char*)(code + 8)) != TOY_OPCODE_RETURN ||
|
||||
*((unsigned char*)(code + 9)) != 0 ||
|
||||
*((unsigned char*)(code + 10)) != 0 ||
|
||||
*((unsigned char*)(code + 11)) != 0 ||
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* jumps = code + 12;
|
||||
|
||||
//check jumps
|
||||
if (
|
||||
//code start
|
||||
*(unsigned int*)(jumps + 0) != 0 || //the address relative to the start of the data section
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine jumps, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* data = jumps + 4;
|
||||
|
||||
//check data
|
||||
if (
|
||||
//data start (the end of the data is padded to the nearest multiple of 4)
|
||||
strcmp( ((char*)data) + ((unsigned int*)jumps)[0], "Hello world!" ) != 0 ||
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine data, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -686,7 +785,7 @@ int main() {
|
||||
int total = 0, res = 0;
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_routine_expressions(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -696,7 +795,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_routine_binary(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -706,7 +805,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_routine_keywords(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -716,4 +815,4 @@ int main() {
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ int test_string_allocation() {
|
||||
//allocate a single string from a c-string
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
|
||||
const char* cstring = "Hello world";
|
||||
Toy_String* str = Toy_createString(&bucket, cstring);
|
||||
@@ -77,7 +77,7 @@ int test_string_allocation() {
|
||||
//copy and deep copy a string
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
|
||||
const char* cstring = "Hello world";
|
||||
Toy_String* str = Toy_createString(&bucket, cstring);
|
||||
@@ -103,7 +103,7 @@ int test_string_allocation() {
|
||||
//copy and deep copy a name string
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
|
||||
const char* cstring = "Hello world";
|
||||
Toy_String* str = Toy_createNameString(&bucket, cstring);
|
||||
@@ -129,7 +129,7 @@ int test_string_allocation() {
|
||||
//allocate a zero-length string
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
|
||||
const char* cstring = "";
|
||||
Toy_String* str = Toy_createString(&bucket, cstring);
|
||||
@@ -138,8 +138,7 @@ int test_string_allocation() {
|
||||
if (str->type != TOY_STRING_LEAF ||
|
||||
str->length != 0 ||
|
||||
str->refCount != 1 ||
|
||||
strcmp(str->as.leaf.data, "") != 0 ||
|
||||
bucket->count != sizeof(Toy_String) + 1) //1 for the null character
|
||||
strcmp(str->as.leaf.data, "") != 0)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a Toy_String with zero length\n" TOY_CC_RESET);
|
||||
Toy_freeBucket(&bucket);
|
||||
@@ -157,7 +156,7 @@ int test_string_allocation() {
|
||||
|
||||
int test_string_concatenation() {
|
||||
//one big bucket o' fun
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
|
||||
//concatenate two strings, and check the refcounts
|
||||
{
|
||||
@@ -298,7 +297,7 @@ int test_string_equality() {
|
||||
//simple string equality (no concats)
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* helloWorldOne = Toy_createString(&bucket, "Hello world");
|
||||
Toy_String* helloWorldTwo = Toy_createString(&bucket, "Hello world");
|
||||
Toy_String* helloEveryone = Toy_createString(&bucket, "Hello everyone");
|
||||
@@ -348,7 +347,7 @@ int test_string_equality() {
|
||||
//string equality (with concat left)
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* helloWorldOne = Toy_concatStrings(&bucket, Toy_createString(&bucket, "Hello "), Toy_createString(&bucket, "world"));
|
||||
Toy_String* helloWorldTwo = Toy_createString(&bucket, "Hello world");
|
||||
Toy_String* helloEveryone = Toy_createString(&bucket, "Hello everyone");
|
||||
@@ -398,7 +397,7 @@ int test_string_equality() {
|
||||
//string equality (with concat right)
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* helloWorldOne = Toy_createString(&bucket, "Hello world");
|
||||
Toy_String* helloWorldTwo = Toy_concatStrings(&bucket, Toy_createString(&bucket, "Hello "), Toy_createString(&bucket, "world"));
|
||||
Toy_String* helloEveryone = Toy_createString(&bucket, "Hello everyone");
|
||||
@@ -424,7 +423,7 @@ int test_string_equality() {
|
||||
//string equality (with concat both)
|
||||
{
|
||||
//setup - these concat points are deliberately different
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* helloWorldOne = Toy_concatStrings(&bucket, Toy_createString(&bucket, "Hello "), Toy_createString(&bucket, "world"));
|
||||
Toy_String* helloWorldTwo = Toy_concatStrings(&bucket, Toy_createString(&bucket, "Hello"), Toy_createString(&bucket, " world"));
|
||||
Toy_String* helloEveryone = Toy_concatStrings(&bucket, Toy_createString(&bucket, "Hell"), Toy_createString(&bucket, "world"));
|
||||
@@ -462,7 +461,7 @@ int test_string_equality() {
|
||||
//string equality (with concat arbitrary)
|
||||
{
|
||||
//setup - The quick brown fox jumps over the lazy dog.
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* helloWorldOne = Toy_concatStrings(&bucket,
|
||||
Toy_createString(&bucket, "The quick brown "),
|
||||
Toy_concatStrings(&bucket,
|
||||
@@ -526,7 +525,7 @@ int test_string_equality() {
|
||||
//string equality (empty strings, no concats)
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* helloWorldOne = Toy_createString(&bucket, "");
|
||||
Toy_String* helloWorldTwo = Toy_createString(&bucket, "");
|
||||
Toy_String* helloEveryone = Toy_createString(&bucket, "Hello everyone");
|
||||
@@ -576,7 +575,7 @@ int test_string_equality() {
|
||||
//string equality (empty strings, deep concats)
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* helloWorldOne = Toy_concatStrings(&bucket,
|
||||
Toy_createString(&bucket, ""),
|
||||
Toy_concatStrings(&bucket,
|
||||
@@ -652,7 +651,7 @@ int test_string_equality() {
|
||||
//simple name equality
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* helloWorldOne = Toy_createNameString(&bucket, "Hello world");
|
||||
Toy_String* helloWorldTwo = Toy_createNameString(&bucket, "Hello world");
|
||||
Toy_String* helloEveryone = Toy_createNameString(&bucket, "Hello everyone");
|
||||
@@ -706,7 +705,7 @@ int test_string_diffs() {
|
||||
//simple string diffs (no concats)
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* helloEveryone = Toy_createString(&bucket, "Hello everyone");
|
||||
Toy_String* helloUniverse = Toy_createString(&bucket, "Hello universe");
|
||||
|
||||
@@ -743,7 +742,7 @@ int test_string_diffs() {
|
||||
//string diffs (with concat arbitrary)
|
||||
{
|
||||
//setup - The quick brown fox jumps over the lazy dog.
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(1024);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_String* pangram = Toy_concatStrings(&bucket,
|
||||
Toy_createString(&bucket, "The quick brown "),
|
||||
Toy_concatStrings(&bucket,
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
int main() {
|
||||
//test for the correct size
|
||||
{
|
||||
#if TOY_BITNESS == 64
|
||||
if (sizeof(Toy_Value) != 16) {
|
||||
#else
|
||||
if (sizeof(Toy_Value) != 8) {
|
||||
#endif
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: 'Toy_Value' is an unexpected size in memory\n" TOY_CC_RESET);
|
||||
return -1;
|
||||
}
|
||||
@@ -56,7 +60,7 @@ int main() {
|
||||
//test value hashing
|
||||
{
|
||||
//setup
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(512);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
|
||||
//values
|
||||
Toy_Value n = TOY_VALUE_FROM_NULL();
|
||||
|
||||
@@ -55,10 +55,10 @@ int test_setup_and_teardown(Toy_Bucket** bucketHandle) {
|
||||
if (
|
||||
vm.routine - vm.bc != headerSize ||
|
||||
vm.routineSize != 72 ||
|
||||
vm.paramCount != 0 ||
|
||||
vm.jumpsCount != 0 ||
|
||||
vm.dataCount != 0 ||
|
||||
vm.subsCount != 0
|
||||
vm.paramSize != 0 ||
|
||||
vm.jumpsSize != 0 ||
|
||||
vm.dataSize != 0 ||
|
||||
vm.subsSize != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to setup and teadown Toy_VM, source: %s\n" TOY_CC_RESET, source);
|
||||
@@ -210,6 +210,89 @@ int test_keywords(Toy_Bucket** bucketHandle) {
|
||||
//teadown
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
}
|
||||
|
||||
//test print with a string
|
||||
{
|
||||
//setup
|
||||
Toy_setPrintCallback(callbackUtil);
|
||||
const char* source = "print \"Hello world!\";";
|
||||
|
||||
Toy_Lexer lexer;
|
||||
Toy_bindLexer(&lexer, source);
|
||||
|
||||
Toy_Parser parser;
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
|
||||
Toy_VM vm;
|
||||
Toy_bindVM(&vm, bc.ptr);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
|
||||
//check the final state of the stack
|
||||
if (callbackUtilReceived == NULL ||
|
||||
strcmp(callbackUtilReceived, "Hello world!") != 0)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' passed to print keyword, source: %s\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL", source);
|
||||
|
||||
//cleanup and return
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//teadown
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
}
|
||||
|
||||
//test print with a string concat
|
||||
{
|
||||
//setup
|
||||
Toy_setPrintCallback(callbackUtil);
|
||||
const char* source = "print \"Hello\" .. \"world!\";";
|
||||
|
||||
Toy_Lexer lexer;
|
||||
Toy_bindLexer(&lexer, source);
|
||||
|
||||
Toy_Parser parser;
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
|
||||
Toy_VM vm;
|
||||
Toy_bindVM(&vm, bc.ptr);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
|
||||
//check the final state of the stack
|
||||
if (callbackUtilReceived == NULL ||
|
||||
strcmp(callbackUtilReceived, "Helloworld!") != 0)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' passed to print keyword, source: %s\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL", source);
|
||||
|
||||
//cleanup and return
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//teadown
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
}
|
||||
|
||||
@@ -221,7 +304,7 @@ int main() {
|
||||
int total = 0, res = 0;
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_setup_and_teardown(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -231,7 +314,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_simple_execution(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -241,7 +324,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_opcode_not_equal(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -251,7 +334,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_keywords(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
|
||||
Reference in New Issue
Block a user