From c0c03a41107bf0b7a4499bcb0faad004c3f867fc Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 12 Apr 2026 11:47:26 +1000 Subject: [PATCH] Functions are working, tests incomplete This required a massive cross-cutting rework to the scope system, multiple subtle bugfixes and relearning of the parser internals, but it does appear that functions are working correctly. A few caveats: for now, parameters are always constant, regardless of type, return values can't be specified, and some script tests have been written. Most importantly, a key feature is working: closures. --- repl/main.c | 7 +--- scripts/fib.toy | 11 ++---- scripts/leapyear.toy | 5 ++- scripts/{funky.toy => tally.toy} | 5 ++- source/toy_ast.h | 2 + source/toy_compiler.c | 8 ++-- source/toy_function.c | 10 ++++- source/toy_function.h | 6 ++- source/toy_parser.c | 20 +++++----- source/toy_scope.c | 68 ++++++++++++++++---------------- source/toy_scope.h | 4 ++ source/toy_value.c | 2 +- source/toy_vm.c | 13 +++--- source/toy_vm.h | 2 +- tests/scripts/test_closures.toy | 22 +++++++++++ tests/scripts/test_fibonacci.toy | 20 ++++++++++ tests/units/test_function.c | 9 +++++ tests/units/test_vm.c | 36 ++++++++--------- 18 files changed, 158 insertions(+), 92 deletions(-) rename scripts/{funky.toy => tally.toy} (74%) create mode 100644 tests/scripts/test_closures.toy create mode 100644 tests/scripts/test_fibonacci.toy create mode 100644 tests/units/test_function.c diff --git a/repl/main.c b/repl/main.c index d85f8af..9ce6df1 100644 --- a/repl/main.c +++ b/repl/main.c @@ -334,8 +334,6 @@ int repl(const char* filepath, bool verbose) { printf("%s> ", prompt); //shows the terminal prompt and begin - unsigned int runCount = 0; //used for initial preserveScope - //read from the terminal while(fgets(inputBuffer, INPUT_BUFFER_SIZE, stdin)) { //work around fgets() adding a newline @@ -366,9 +364,8 @@ int repl(const char* filepath, bool verbose) { printf("%s> ", prompt); //shows the terminal prompt continue; } - unsigned char* bytecode = Toy_compileToBytecode(ast); - Toy_bindVM(&vm, bytecode, runCount++ > 0); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -466,7 +463,7 @@ int main(int argc, const char* argv[]) { //run the compiled code Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); Toy_runVM(&vm); diff --git a/scripts/fib.toy b/scripts/fib.toy index 902dc6a..79e290d 100644 --- a/scripts/fib.toy +++ b/scripts/fib.toy @@ -1,15 +1,12 @@ -//BUG: Not yet functional +//tentatively functional -//example of the fibonacci sequence -fn fib(n: int) { +//fibonacci sequence +fn fib(n) { if (n < 2) return n; return fib(n-1) + fib(n-2); } -//TODO: type coercion syntax hasn't been decided on yet, but it will be needed -for (var i = 1; i <= 10; i++) { - print i .. ":" .. fib(i); -} +print fib(12); //Note to my future self: yes, the base case in 'fib()' is 'n < 2', stop second guessing yourself! //Note to my past self: don't tell me what to do! diff --git a/scripts/leapyear.toy b/scripts/leapyear.toy index f9410ab..bdd2348 100644 --- a/scripts/leapyear.toy +++ b/scripts/leapyear.toy @@ -1,8 +1,9 @@ -//BUG: Not yet functional - //find the leap years fn isLeapYear(n: int) { if (n % 400 == 0) return true; if (n % 100 == 0) return false; return n % 4 == 0; } +print isLeapYear(1999); +print isLeapYear(2000); +print isLeapYear(2004); diff --git a/scripts/funky.toy b/scripts/tally.toy similarity index 74% rename from scripts/funky.toy rename to scripts/tally.toy index 532933d..dcd5bfe 100644 --- a/scripts/funky.toy +++ b/scripts/tally.toy @@ -1,4 +1,3 @@ -//BUG: functions aren't working yet fn makeCounter() { var counter: int = 0; @@ -14,7 +13,9 @@ var tally = makeCounter(); while (true) { var result = tally(); - if (result >= 10_000_000) { + print result; + + if (result >= 10) { break; } } diff --git a/source/toy_ast.h b/source/toy_ast.h index c57fb76..b82dc70 100644 --- a/source/toy_ast.h +++ b/source/toy_ast.h @@ -81,6 +81,8 @@ typedef enum Toy_AstFlag { TOY_AST_FLAG_POSTFIX_INCREMENT = 43, TOY_AST_FLAG_POSTFIX_DECREMENT = 44, + TOY_AST_FLAG_INVOKATION = 45, + // TOY_AST_FLAG_TERNARY, } Toy_AstFlag; diff --git a/source/toy_compiler.c b/source/toy_compiler.c index 3caf966..99deeab 100644 --- a/source/toy_compiler.c +++ b/source/toy_compiler.c @@ -188,14 +188,16 @@ static unsigned int emitParameters(Toy_Bytecode* mb, Toy_Ast* ast) { total += emitParameters(mb, ast->aggregate.right); return total; } - else if (ast->type != TOY_AST_VALUE) { + else if (ast->type != TOY_AST_VAR_DECLARE) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown AST type passed to 'emitParameters()'\n" TOY_CC_RESET); exit(-1); return 0; } //the address within the data section - unsigned int dataAddr = emitCStringToData(&(mb->data), &(mb->dataCapacity), &(mb->dataCount), TOY_VALUE_AS_STRING(ast->value.value)->leaf.data); + char buffer[128]; + snprintf(buffer, 128, "%.*s", ast->varDeclare.name->info.length, ast->varDeclare.name->leaf.data); + unsigned int dataAddr = emitCStringToData(&(mb->data), &(mb->dataCapacity), &(mb->dataCount), buffer); //check the param index for that entry i.e. don't reuse parameter names for (unsigned int i = 0; i < mb->paramCount; i++) { @@ -209,7 +211,7 @@ static unsigned int emitParameters(Toy_Bytecode* mb, Toy_Ast* ast) { //emit to the param index EMIT_INT(&mb, param, dataAddr); - EMIT_INT(&mb, param, ast->value.value.type); + EMIT_INT(&mb, param, ast->varDeclare.valueType); //'constant' is lost, but that's fine for params //this returns the number of written parameters return 1; diff --git a/source/toy_function.c b/source/toy_function.c index a0af800..42e5227 100644 --- a/source/toy_function.c +++ b/source/toy_function.c @@ -1,10 +1,18 @@ #include "toy_function.h" -Toy_Function* Toy_createFunctionFromBytecode(Toy_Bucket** bucketHandle, unsigned char* bytecode) { +Toy_Function* Toy_createFunctionFromBytecode(Toy_Bucket** bucketHandle, unsigned char* bytecode, Toy_Scope* parentScope) { Toy_Function* fn = (Toy_Function*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Function)); fn->type = TOY_FUNCTION_CUSTOM; fn->bytecode.code = bytecode; + fn->bytecode.parentScope = parentScope; + Toy_private_incrementScopeRefCount(fn->bytecode.parentScope); return fn; +} + +TOY_API void Toy_freeFunction(Toy_Function* fn) { + if (fn->type == TOY_FUNCTION_CUSTOM) { + Toy_private_decrementScopeRefCount(fn->bytecode.parentScope); + } } \ No newline at end of file diff --git a/source/toy_function.h b/source/toy_function.h index 741f33f..b282176 100644 --- a/source/toy_function.h +++ b/source/toy_function.h @@ -2,6 +2,7 @@ #include "toy_common.h" #include "toy_bucket.h" +#include "toy_scope.h" typedef enum Toy_FunctionType { TOY_FUNCTION_CUSTOM, @@ -11,6 +12,7 @@ typedef enum Toy_FunctionType { typedef struct Toy_FunctionBytecode { Toy_FunctionType type; unsigned char* code; + Toy_Scope* parentScope; } Toy_FunctionBytecode; typedef struct Toy_FunctionNative { @@ -24,4 +26,6 @@ typedef union Toy_Function_t { Toy_FunctionNative native; } Toy_Function; -TOY_API Toy_Function* Toy_createFunctionFromBytecode(Toy_Bucket** bucketHandle, unsigned char* bytecode); +TOY_API Toy_Function* Toy_createFunctionFromBytecode(Toy_Bucket** bucketHandle, unsigned char* bytecode, Toy_Scope* parentScope); + +TOY_API void Toy_freeFunction(Toy_Function* fn); \ No newline at end of file diff --git a/source/toy_parser.c b/source/toy_parser.c index 8615009..ea462c8 100644 --- a/source/toy_parser.c +++ b/source/toy_parser.c @@ -731,7 +731,7 @@ static Toy_AstFlag invoke(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast //finally, emit the call as an Ast Toy_private_emitAstFunctionInvokation(bucketHandle, rootHandle, args); - return TOY_AST_FLAG_NONE; + return TOY_AST_FLAG_INVOKATION; } //grammar rules @@ -964,25 +964,23 @@ static void makeFunctionDeclarationStmt(Toy_Bucket** bucketHandle, Toy_Parser* p advance(parser); Toy_Token nameToken = parser->previous; - //TODO: fix this with param type info + //URGENT: fix this with param type info //read the type specifier if present - // Toy_ValueType varType = TOY_VALUE_ANY; - // bool constant = true; //parameters are immutable + Toy_ValueType varType = TOY_VALUE_ANY; + bool constant = true; //parameters are immutable if (match(parser, TOY_TOKEN_OPERATOR_COLON)) { - // varType = readType(parser); - readType(parser); + varType = readType(parser); if (match(parser, TOY_TOKEN_KEYWORD_CONST)) { - // constant = true; + constant = true; } } - //emit the parameter as a name string - Toy_String* name = Toy_toStringLength(bucketHandle, nameToken.lexeme, nameToken.length); - Toy_Value value = TOY_VALUE_FROM_STRING(name); + //emit the parameter as a var declaration Toy_Ast* ast = NULL; - Toy_private_emitAstValue(bucketHandle, &ast, value); //TODO: params with type info + Toy_String* name = Toy_toStringLength(bucketHandle, nameToken.lexeme, nameToken.length); + Toy_private_emitAstVariableDeclaration(bucketHandle, &ast, name, varType, constant, NULL); //add to the params aggregate (is added backwards, because weird) Toy_private_emitAstAggregate(bucketHandle, ¶ms, TOY_AST_FLAG_COLLECTION, ast); diff --git a/source/toy_scope.c b/source/toy_scope.c index e78d01f..a7b3e16 100644 --- a/source/toy_scope.c +++ b/source/toy_scope.c @@ -8,34 +8,6 @@ #include "toy_print.h" //utils -static void incrementRefCount(Toy_Scope* scope) { - for (Toy_Scope* iter = scope; iter; iter = iter->next) { - //check for issues - if (iter->next != NULL && iter->next->refCount == 0) { - fprintf(stderr, TOY_CC_ERROR "ERROR: Toy_Scope's ancestor has a refcount of 0'\n" TOY_CC_RESET); - exit(-1); - } - - iter->refCount++; - } -} - -static void decrementRefCount(Toy_Scope* scope) { - for (Toy_Scope* iter = scope; iter; iter = iter->next) { - iter->refCount--; - if (iter->refCount == 0 && iter->data != NULL) { - //free the scope entries when this scope is no longer needed - for (unsigned int i = 0; i < iter->capacity; i++) { - if (iter->data[i].psl > 0) { - Toy_freeString(&(iter->data[i].key)); - Toy_freeValue(iter->data[i].value); - } - } - free(iter->data); - } - } -} - static Toy_ScopeEntry* lookupScopeEntryPtr(Toy_Scope* scope, Toy_String* key, unsigned int hash, bool recursive) { //terminate if (scope == NULL || scope->data == NULL) { @@ -61,7 +33,7 @@ static Toy_ScopeEntry* lookupScopeEntryPtr(Toy_Scope* scope, Toy_String* key, un } } -void probeAndInsert(Toy_Scope* scope, Toy_String* key, Toy_Value value, Toy_ValueType type, bool constant) { +static void probeAndInsert(Toy_Scope* scope, Toy_String* key, Toy_Value value, Toy_ValueType type, bool constant) { //make the entry unsigned int probe = Toy_hashString(key) % scope->capacity; Toy_ScopeEntry entry = (Toy_ScopeEntry){ .key = *key, .value = value, .type = type, .constant = constant, .psl = 1 }; @@ -97,7 +69,7 @@ void probeAndInsert(Toy_Scope* scope, Toy_String* key, Toy_Value value, Toy_Valu } } -Toy_ScopeEntry* adjustScopeEntries(Toy_Scope* scope, unsigned int newCapacity) { +static Toy_ScopeEntry* adjustScopeEntries(Toy_Scope* scope, unsigned int newCapacity) { //allocate and zero a new Toy_ScopeEntry array in memory Toy_ScopeEntry* newEntries = malloc(newCapacity * sizeof(Toy_ScopeEntry)); @@ -142,7 +114,7 @@ Toy_Scope* Toy_pushScope(Toy_Bucket** bucketHandle, Toy_Scope* scope) { newScope->count = 0; newScope->maxPsl = 0; - incrementRefCount(newScope); + Toy_private_incrementScopeRefCount(newScope); return newScope; } @@ -152,7 +124,7 @@ Toy_Scope* Toy_popScope(Toy_Scope* scope) { return NULL; } - decrementRefCount(scope); + Toy_private_decrementScopeRefCount(scope); return scope->next; } @@ -169,7 +141,7 @@ void Toy_declareScope(Toy_Scope* scope, Toy_String* key, Toy_ValueType type, Toy //type check if (type != TOY_VALUE_ANY && value.type != TOY_VALUE_NULL && type != value.type && value.type != TOY_VALUE_REFERENCE) { char buffer[key->info.length + 256]; - sprintf(buffer, "Incorrect value type in declaration of '%s' (expected %s, got %s)", key->leaf.data, Toy_private_getValueTypeAsCString(type), Toy_private_getValueTypeAsCString(value.type)); + sprintf(buffer, "Incorrect value type in declaration of '%.*s' (expected %s, got %s)", key->info.length, key->leaf.data, Toy_private_getValueTypeAsCString(type), Toy_private_getValueTypeAsCString(value.type)); Toy_error(buffer); return; } @@ -190,7 +162,7 @@ void Toy_assignScope(Toy_Scope* scope, Toy_String* key, Toy_Value value) { //type check if (entryPtr->type != TOY_VALUE_ANY && value.type != TOY_VALUE_NULL && entryPtr->type != value.type && value.type != TOY_VALUE_REFERENCE) { char buffer[key->info.length + 256]; - sprintf(buffer, "Incorrect value type in assignment of '%s' (expected %s, got %s)", key->leaf.data, Toy_private_getValueTypeAsCString(entryPtr->type), Toy_private_getValueTypeAsCString(value.type)); + sprintf(buffer, "Incorrect value type in assignment of '%.*s' (expected %s, got %s)", key->info.length, key->leaf.data, Toy_private_getValueTypeAsCString(entryPtr->type), Toy_private_getValueTypeAsCString(value.type)); Toy_error(buffer); return; } @@ -223,3 +195,31 @@ bool Toy_isDeclaredScope(Toy_Scope* scope, Toy_String* key) { Toy_ScopeEntry* entryPtr = lookupScopeEntryPtr(scope, key, Toy_hashString(key), true); return entryPtr != NULL; } + +void Toy_private_incrementScopeRefCount(Toy_Scope* scope) { + for (Toy_Scope* iter = scope; iter; iter = iter->next) { + //check for issues + if (iter->next != NULL && iter->next->refCount == 0) { + fprintf(stderr, TOY_CC_ERROR "ERROR: Toy_Scope's ancestor has a refcount of 0'\n" TOY_CC_RESET); + exit(-1); + } + + iter->refCount++; + } +} + +void Toy_private_decrementScopeRefCount(Toy_Scope* scope) { + for (Toy_Scope* iter = scope; iter; iter = iter->next) { + iter->refCount--; + if (iter->refCount == 0 && iter->data != NULL) { + //free the scope entries when this scope is no longer needed + for (unsigned int i = 0; i < iter->capacity; i++) { + if (iter->data[i].psl > 0) { + Toy_freeString(&(iter->data[i].key)); + Toy_freeValue(iter->data[i].value); + } + } + free(iter->data); + } + } +} \ No newline at end of file diff --git a/source/toy_scope.h b/source/toy_scope.h index cf55fe0..da30b2e 100644 --- a/source/toy_scope.h +++ b/source/toy_scope.h @@ -36,6 +36,10 @@ TOY_API Toy_Value* Toy_accessScopeAsPointer(Toy_Scope* scope, Toy_String* key); TOY_API bool Toy_isDeclaredScope(Toy_Scope* scope, Toy_String* key); +//manage refcounting +TOY_API void Toy_private_incrementScopeRefCount(Toy_Scope* scope); +TOY_API void Toy_private_decrementScopeRefCount(Toy_Scope* scope); + //some useful sizes, could be swapped out as needed #ifndef TOY_SCOPE_INITIAL_CAPACITY #define TOY_SCOPE_INITIAL_CAPACITY 8 diff --git a/source/toy_value.c b/source/toy_value.c index 4fdd5b2..7476953 100644 --- a/source/toy_value.c +++ b/source/toy_value.c @@ -178,7 +178,7 @@ void Toy_freeValue(Toy_Value value) { return; case TOY_VALUE_FUNCTION: - //not sure this needs to be freed + Toy_freeFunction(value.as.function); return; case TOY_VALUE_OPAQUE: diff --git a/source/toy_vm.c b/source/toy_vm.c index 9a7b116..ce1b6b7 100644 --- a/source/toy_vm.c +++ b/source/toy_vm.c @@ -151,14 +151,15 @@ static void processRead(Toy_VM* vm) { } case TOY_VALUE_FUNCTION: { - // unsigned int paramCount = (unsigned int)READ_BYTE(vm); //unused + unsigned int paramCount = (unsigned int)READ_BYTE(vm); //unused + (void)paramCount; fixAlignment(vm); unsigned int addr = (unsigned int)READ_INT(vm); //create and push the function value - Toy_Function* function = Toy_createFunctionFromBytecode(&vm->memoryBucket, vm->code + vm->subsAddr + addr); + Toy_Function* function = Toy_createFunctionFromBytecode(&vm->memoryBucket, vm->code + vm->subsAddr + addr, vm->scope); value = TOY_VALUE_FROM_FUNCTION(function); break; @@ -396,7 +397,7 @@ static void processInvoke(Toy_VM* vm) { //spin up a new sub-vm Toy_VM subVM; Toy_inheritVM(&subVM, vm); - Toy_bindVM(&subVM, fn->bytecode.code, false); + Toy_bindVM(&subVM, fn->bytecode.code, fn->bytecode.parentScope); //check args count if (argCount * 8 != subVM.paramCount) { @@ -1104,7 +1105,7 @@ void Toy_inheritVM(Toy_VM* vm, Toy_VM* parent) { Toy_resetVM(vm, true); } -void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, bool preserveScope) { +void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, Toy_Scope* parentScope) { vm->code = bytecode; //set code, so it can be read (void)READ_UNSIGNED_INT(vm); //global header @@ -1131,8 +1132,8 @@ void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, bool preserveScope) { } //scopes - if (preserveScope == false) { - vm->scope = Toy_pushScope(&vm->memoryBucket, NULL); + if (vm->scope == NULL) { + vm->scope = Toy_pushScope(&vm->memoryBucket, parentScope); } } diff --git a/source/toy_vm.h b/source/toy_vm.h index a6ce92e..2600218 100644 --- a/source/toy_vm.h +++ b/source/toy_vm.h @@ -47,7 +47,7 @@ TOY_API void Toy_resetVM(Toy_VM* vm, bool preserveScope); TOY_API void Toy_initVM(Toy_VM* vm); //creates memory TOY_API void Toy_inheritVM(Toy_VM* vm, Toy_VM* parent); //inherits scope bucket -void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, bool preserveScope); +void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, Toy_Scope* parentScope); TOY_API unsigned int Toy_runVM(Toy_VM* vm); TOY_API void Toy_freeVM(Toy_VM* vm); diff --git a/tests/scripts/test_closures.toy b/tests/scripts/test_closures.toy new file mode 100644 index 0000000..08776f1 --- /dev/null +++ b/tests/scripts/test_closures.toy @@ -0,0 +1,22 @@ +//closures +fn makeCounter() { + var counter: int = 0; + + fn increment() { + return ++counter; + } + + return increment; +} + +var tally = makeCounter(); + +while (true) { + var result = tally(); + + print result; + + if (result >= 10) { + break; + } +} diff --git a/tests/scripts/test_fibonacci.toy b/tests/scripts/test_fibonacci.toy new file mode 100644 index 0000000..744fceb --- /dev/null +++ b/tests/scripts/test_fibonacci.toy @@ -0,0 +1,20 @@ + +fn fib(n) { + if (n < 2) return n; + return fib(n-1) + fib(n-2); +} + +assert fib(1) == 1; +assert fib(2) == 1; +assert fib(3) == 2; +assert fib(4) == 3; +assert fib(5) == 5; +assert fib(6) == 8; +assert fib(7) == 13; +assert fib(8) == 21; +assert fib(9) == 34; +assert fib(10) == 55; +assert fib(11) == 89; +assert fib(12) == 144; + +print "Fibonacci passed"; \ No newline at end of file diff --git a/tests/units/test_function.c b/tests/units/test_function.c new file mode 100644 index 0000000..4d1aaf8 --- /dev/null +++ b/tests/units/test_function.c @@ -0,0 +1,9 @@ +#include "toy_console_colors.h" + +#include +#include + +int main(void) { + printf(TOY_CC_WARN "Test not yet implemented: %s\n" TOY_CC_RESET, __FILE__); + return -1; +} \ No newline at end of file diff --git a/tests/units/test_vm.c b/tests/units/test_vm.c index d609304..3b6fd84 100644 --- a/tests/units/test_vm.c +++ b/tests/units/test_vm.c @@ -41,7 +41,7 @@ int test_setup_and_teardown(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //check the bytecode was loaded correctly if ( @@ -86,7 +86,7 @@ int test_simple_execution(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -132,7 +132,7 @@ int test_opcode_not_equal(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -188,7 +188,7 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -232,7 +232,7 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -277,7 +277,7 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -326,7 +326,7 @@ int test_keyword_print(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -371,7 +371,7 @@ int test_keyword_print(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -416,7 +416,7 @@ int test_keyword_print(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -465,7 +465,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -510,7 +510,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -554,7 +554,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -599,7 +599,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -647,7 +647,7 @@ int test_scope(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -695,7 +695,7 @@ int test_scope(Toy_Bucket** bucketHandle) { //run the setup Toy_VM vm; Toy_initVM(&vm); - Toy_bindVM(&vm, bytecode, false); + Toy_bindVM(&vm, bytecode, NULL); //run Toy_runVM(&vm); @@ -737,7 +737,7 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) { //run 1 unsigned char* bytecode1 = makeCodeFromSource(bucketHandle, "print \"Hello world!\";"); - Toy_bindVM(&vm, bytecode1, false); + Toy_bindVM(&vm, bytecode1, NULL); Toy_runVM(&vm); Toy_resetVM(&vm, true); @@ -757,7 +757,7 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) { //run 2 unsigned char* bytecode2 = makeCodeFromSource(bucketHandle, "print \"Hello world!\";"); - Toy_bindVM(&vm, bytecode2, true); //preserve during repeated calls + Toy_bindVM(&vm, bytecode2, NULL); //preserve during repeated calls Toy_runVM(&vm); Toy_resetVM(&vm, true); @@ -777,7 +777,7 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) { //run 3 unsigned char* bytecode3 = makeCodeFromSource(bucketHandle, "print \"Hello world!\";"); - Toy_bindVM(&vm, bytecode3, true); //preserve during repeated calls + Toy_bindVM(&vm, bytecode3, NULL); //preserve during repeated calls Toy_runVM(&vm); Toy_resetVM(&vm, true);