From 842f041a505c6fa55c94be7c16489065e4f55920 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 7 Apr 2026 21:34:05 +1000 Subject: [PATCH] VM test is passing --- source/toy_vm.c | 3 +- tests/units/test_vm.c | 890 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 889 insertions(+), 4 deletions(-) diff --git a/source/toy_vm.c b/source/toy_vm.c index f0b2677..8a71a7c 100644 --- a/source/toy_vm.c +++ b/source/toy_vm.c @@ -63,7 +63,8 @@ static void processRead(Toy_VM* vm) { case TOY_VALUE_STRING: { enum Toy_StringType stringType = READ_BYTE(vm); - //int len = (int)READ_BYTE(vm); //WARN: only used for name strings + int len = (int)READ_BYTE(vm); //WARN: only used for name strings + (void)len; //grab the jump as an integer unsigned int jump = *((int*)(vm->code + vm->jumpsAddr + READ_INT(vm))); diff --git a/tests/units/test_vm.c b/tests/units/test_vm.c index a83d5bf..d609304 100644 --- a/tests/units/test_vm.c +++ b/tests/units/test_vm.c @@ -1,9 +1,893 @@ #include "toy_vm.h" #include "toy_console_colors.h" +#include "toy_lexer.h" +#include "toy_parser.h" +#include "toy_compiler.h" +#include "toy_print.h" + #include +#include +#include + +//utils +unsigned char* makeCodeFromSource(Toy_Bucket** bucketHandle, const char* source) { + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + return Toy_compileToBytecode(ast); +} + +//tests +int test_setup_and_teardown(Toy_Bucket** bucketHandle) { + //basic init & quit + { + //generate bytecode for testing + const char* source = "(1 + 2) * (3 + 4);"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //check the bytecode was loaded correctly + if ( + vm.codeAddr != 24 || // bytecode header is: total, jumps, prams, data, subs, codeAddr + vm.jumpsCount != 0 || + vm.paramCount != 0 || + vm.dataCount != 0 || + vm.subsCount != 0 + ) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: failed to setup and teadown Toy_VM, source: %s\n" TOY_CC_RESET, source); + + //cleanup and return + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //don't run it this time, simply teadown + Toy_freeVM(&vm); + free(bytecode); + } + + return 0; +} + +int test_simple_execution(Toy_Bucket** bucketHandle) { + //test execution + { + //generate bytecode for testing + const char* source = "(1 + 2) * (3 + 4);"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check the final state of the stack + if (vm.stack == NULL || + vm.stack->count != 1 || + TOY_VALUE_IS_INTEGER( Toy_peekStack(&vm.stack) ) != true || + TOY_VALUE_AS_INTEGER( Toy_peekStack(&vm.stack) ) != 21 + ) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected result in 'Toy_VM', source: %s\n" TOY_CC_RESET, source); + + //cleanup and return + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_freeVM(&vm); + free(bytecode); + } + + return 0; +} + +int test_opcode_not_equal(Toy_Bucket** bucketHandle) { + //testing a specific opcode; '!=' is compressed into a single word, so lets check it works + { + //generate bytecode for testing + const char* source = "3 != 5;"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check the final state of the stack + if (vm.stack == NULL || + vm.stack->count != 1 || + TOY_VALUE_IS_BOOLEAN( Toy_peekStack(&vm.stack) ) != true || + TOY_VALUE_AS_BOOLEAN( Toy_peekStack(&vm.stack) ) != true + ) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected result in 'Toy_VM', source: %s\n" TOY_CC_RESET, source); + + //cleanup and return + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_freeVM(&vm); + free(bytecode); + } + + return 0; +} + +static char* callbackUtilReceived = NULL; +static void callbackUtil(const char* msg) { + if (msg != NULL) { + free(callbackUtilReceived); + callbackUtilReceived = (char*)malloc(strlen(msg) + 1); + strcpy(callbackUtilReceived, msg); + } +} + +int test_keyword_assert(Toy_Bucket** bucketHandle) { + //test assert true + { + //setup + Toy_setAssertFailureCallback(callbackUtil); + const char* source = "assert true;"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + if (callbackUtilReceived != NULL) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected assert message '%s' found, source: %s\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL", source); + + //cleanup and return + Toy_resetAssertFailureCallback(); + free(callbackUtilReceived); + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_resetAssertFailureCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + //test assert false + { + //setup + Toy_setAssertFailureCallback(callbackUtil); + const char* source = "assert false;"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + if (callbackUtilReceived == NULL || + strcmp(callbackUtilReceived, "assertion failed") != 0) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected assert failure message '%s' found, source: %s\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL", source); + + //cleanup and return + Toy_resetAssertFailureCallback(); + free(callbackUtilReceived); + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_resetAssertFailureCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + //test assert false with message + { + //setup + Toy_setAssertFailureCallback(callbackUtil); + const char* source = "assert false, \"You passed a false to assert\";"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + if (callbackUtilReceived == NULL || + strcmp(callbackUtilReceived, "You passed a false to assert") != 0) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected assert failure message '%s' found, source: %s\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL", source); + + //cleanup and return + Toy_resetAssertFailureCallback(); + free(callbackUtilReceived); + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_resetAssertFailureCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + return 0; +} + +int test_keyword_print(Toy_Bucket** bucketHandle) { + //test print + { + //setup + Toy_setPrintCallback(callbackUtil); + const char* source = "print 42;"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + if (callbackUtilReceived == NULL || + strcmp(callbackUtilReceived, "42") != 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); + free(bytecode); + return -1; + } + + //teadown + Toy_resetPrintCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + //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); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + 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); + free(bytecode); + return -1; + } + + //teadown + Toy_resetPrintCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + //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); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + 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); + free(bytecode); + return -1; + } + + //teadown + Toy_resetPrintCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + return 0; +} + +int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) { + //test if-then (truthy) + { + //setup + Toy_setPrintCallback(callbackUtil); + const char* source = "if (true) print \"hello world\";"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + if (callbackUtilReceived == NULL || + strcmp(callbackUtilReceived, "hello world") != 0) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' passed to print in if keyword, source: %s\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL", source); + + //cleanup and return + Toy_resetPrintCallback(); + free(callbackUtilReceived); + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_resetPrintCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + //test if-then (falsy) + { + //setup + Toy_setPrintCallback(callbackUtil); + const char* source = "if (false) print \"hello world\";"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + if (callbackUtilReceived != NULL) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' passed to print in if keyword, source: %s\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL", source); + + //cleanup and return + Toy_resetPrintCallback(); + free(callbackUtilReceived); + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_resetPrintCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + //test if-then-else (truthy) + { + //setup + Toy_setPrintCallback(callbackUtil); + const char* source = "if (true) print \"hello world\"; else print \"failed\";"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + if (callbackUtilReceived == NULL || + strcmp(callbackUtilReceived, "hello world") != 0) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' passed to print in if keyword, source: %s\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL", source); + + //cleanup and return + Toy_resetPrintCallback(); + free(callbackUtilReceived); + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_resetPrintCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + //test if-then-else (falsy) + { + //setup + Toy_setPrintCallback(callbackUtil); + const char* source = "if (false) print \"hello world\"; else print \"failed\";"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + if (callbackUtilReceived == NULL || + strcmp(callbackUtilReceived, "failed") != 0) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' passed to print in if keyword, source: %s\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL", source); + + //cleanup and return + Toy_resetPrintCallback(); + free(callbackUtilReceived); + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_resetPrintCallback(); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_freeVM(&vm); + free(bytecode); + } + + return 0; +} + +int test_scope(Toy_Bucket** bucketHandle) { + //test declaration with initial value + { + //generate bytecode for testing + const char* source = "var foobar = 42;"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + Toy_String* key = Toy_createStringLength(bucketHandle, "foobar", 6); + + if (vm.stack == NULL || + vm.stack->count != 0 || + + vm.scope == NULL || + Toy_isDeclaredScope(vm.scope, key) == false || + TOY_VALUE_IS_INTEGER(*Toy_accessScopeAsPointer(vm.scope, key)) != true || + TOY_VALUE_AS_INTEGER(*Toy_accessScopeAsPointer(vm.scope, key)) != 42 + + ) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected result in 'Toy_VM' when testing scope, source: %s\n" TOY_CC_RESET, source); + + //cleanup and return + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_freeVM(&vm); + free(bytecode); + } + + //test declaration with absent value + { + //generate bytecode for testing + const char* source = "var foobar;"; + + Toy_Lexer lexer; + Toy_bindLexer(&lexer, source); + + Toy_Parser parser; + Toy_bindParser(&parser, &lexer); + + Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser); + unsigned char* bytecode = Toy_compileToBytecode(ast); + + //run the setup + Toy_VM vm; + Toy_initVM(&vm); + Toy_bindVM(&vm, bytecode, false); + + //run + Toy_runVM(&vm); + + //check + Toy_String* key = Toy_createStringLength(bucketHandle, "foobar", 6); + + if (vm.stack == NULL || + vm.stack->count != 0 || + + vm.scope == NULL || + Toy_isDeclaredScope(vm.scope, key) == false || + TOY_VALUE_IS_NULL(*Toy_accessScopeAsPointer(vm.scope, key)) != true + ) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected result in 'Toy_VM' when testing scope, source: %s\n" TOY_CC_RESET, source); + + //cleanup and return + Toy_freeVM(&vm); + free(bytecode); + return -1; + } + + //teadown + Toy_freeVM(&vm); + free(bytecode); + } + + return 0; +} + +int test_vm_reuse(Toy_Bucket** bucketHandle) { + //run code in the same vm multiple times + { + Toy_setPrintCallback(callbackUtil); + + Toy_VM vm; + Toy_initVM(&vm); + + //run 1 + unsigned char* bytecode1 = makeCodeFromSource(bucketHandle, "print \"Hello world!\";"); + Toy_bindVM(&vm, bytecode1, false); + + Toy_runVM(&vm); + Toy_resetVM(&vm, true); + + if (callbackUtilReceived == NULL || strcmp(callbackUtilReceived, "Hello world!") != 0) { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' found in VM reuse run 1\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL"); + + //cleanup and return + free(callbackUtilReceived); + callbackUtilReceived = NULL; + free(bytecode1); + Toy_freeVM(&vm); + Toy_resetPrintCallback(); + return -1; + } + free(bytecode1); + + //run 2 + unsigned char* bytecode2 = makeCodeFromSource(bucketHandle, "print \"Hello world!\";"); + Toy_bindVM(&vm, bytecode2, true); //preserve during repeated calls + + Toy_runVM(&vm); + Toy_resetVM(&vm, true); + + if (callbackUtilReceived == NULL || strcmp(callbackUtilReceived, "Hello world!") != 0) { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' found in VM reuse run 2\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL"); + + //cleanup and return + free(callbackUtilReceived); + callbackUtilReceived = NULL; + free(bytecode2); + Toy_freeVM(&vm); + Toy_resetPrintCallback(); + return -1; + } + free(bytecode2); + + //run 3 + unsigned char* bytecode3 = makeCodeFromSource(bucketHandle, "print \"Hello world!\";"); + Toy_bindVM(&vm, bytecode3, true); //preserve during repeated calls + + Toy_runVM(&vm); + Toy_resetVM(&vm, true); + + if (callbackUtilReceived == NULL || strcmp(callbackUtilReceived, "Hello world!") != 0) { + fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' found in VM reuse run 3\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL"); + + //cleanup and return + free(callbackUtilReceived); + callbackUtilReceived = NULL; + free(bytecode3); + Toy_freeVM(&vm); + Toy_resetPrintCallback(); + return -1; + } + free(bytecode3); + + //cleanup + Toy_freeVM(&vm); + free(callbackUtilReceived); + callbackUtilReceived = NULL; + Toy_resetPrintCallback(); + } + + return 0; +} int main(void) { - printf(TOY_CC_WARN "Test not yet implemented: %s\n" TOY_CC_RESET, __FILE__); - return -1; -} + //run each test set, returning the total errors given + int total = 0, res = 0; + + { + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + res = test_setup_and_teardown(&bucket); + Toy_freeBucket(&bucket); + if (res == 0) { + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); + } + total += res; + } + + { + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + res = test_simple_execution(&bucket); + Toy_freeBucket(&bucket); + if (res == 0) { + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); + } + total += res; + } + + { + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + res = test_opcode_not_equal(&bucket); + Toy_freeBucket(&bucket); + if (res == 0) { + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); + } + total += res; + } + + { + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + res = test_keyword_print(&bucket); + Toy_freeBucket(&bucket); + if (res == 0) { + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); + } + total += res; + } + + { + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + res = test_keyword_assert(&bucket); + Toy_freeBucket(&bucket); + if (res == 0) { + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); + } + total += res; + } + + { + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + res = test_keyword_ifThenElse(&bucket); + Toy_freeBucket(&bucket); + if (res == 0) { + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); + } + total += res; + } + + { + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + res = test_scope(&bucket); + Toy_freeBucket(&bucket); + if (res == 0) { + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); + } + total += res; + } + + { + Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + res = test_vm_reuse(&bucket); + Toy_freeBucket(&bucket); + if (res == 0) { + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); + } + total += res; + } + + return total; +} \ No newline at end of file