Compare commits

...

3 Commits

Author SHA1 Message Date
Kayne Ruse 6901b9a6c9 Opaque values can be referenced 2026-05-13 17:54:24 +10:00
Kayne Ruse c9d4b9965c Added function invoke in RHS values
Return also supports chained expressions.
2026-05-13 17:32:05 +10:00
Kayne Ruse ff1ef1352a Reviewed and updated tagged comments 2026-05-13 10:56:40 +10:00
11 changed files with 89 additions and 39 deletions
+12
View File
@@ -0,0 +1,12 @@
var randi: Int = 69420;
fn rand() {
return randi = randi * 1664525 + 1013904223;
}
var a = rand();
+1 -1
View File
@@ -20,7 +20,7 @@ Toy_Array* Toy_resizeArray(Toy_Array* paramArray, unsigned int capacity) {
unsigned int originalCapacity = paramArray == NULL ? 0 : paramArray->capacity; unsigned int originalCapacity = paramArray == NULL ? 0 : paramArray->capacity;
Toy_Array* array = realloc(paramArray, capacity * sizeof(Toy_Value) + sizeof(Toy_Array)); //URGENT: Swap to a bucket Toy_Array* array = realloc(paramArray, capacity * sizeof(Toy_Value) + sizeof(Toy_Array));
if (array == NULL) { if (array == NULL) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to resize a 'Toy_Array' from %d to %d capacity\n" TOY_CC_RESET, (int)originalCapacity, (int)capacity); fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to resize a 'Toy_Array' from %d to %d capacity\n" TOY_CC_RESET, (int)originalCapacity, (int)capacity);
+1 -1
View File
@@ -239,7 +239,7 @@ Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableRemove); Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableRemove);
return TOY_VALUE_FROM_FUNCTION(fn); return TOY_VALUE_FROM_FUNCTION(fn);
} }
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "forEach", 7) == 0) { //BUG: compare the contents AND length of these strings else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "forEach", 7) == 0) { //URGENT: compare the contents AND length of these strings
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableForEach); Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableForEach);
return TOY_VALUE_FROM_FUNCTION(fn); return TOY_VALUE_FROM_FUNCTION(fn);
} }
+60 -18
View File
@@ -10,7 +10,7 @@
#include <string.h> #include <string.h>
//misc. utils //misc. utils
static bool checkForChaining(Toy_Ast* ptr) { static bool checkForChainedAssign(Toy_Ast* ptr) {
if (ptr == NULL) { if (ptr == NULL) {
return false; return false;
} }
@@ -19,10 +19,16 @@ static bool checkForChaining(Toy_Ast* ptr) {
return true; return true;
} }
if (ptr->type == TOY_AST_UNARY) { return false;
if (ptr->unary.flag >= TOY_AST_FLAG_PREFIX_INCREMENT && ptr->unary.flag <= TOY_AST_FLAG_POSTFIX_DECREMENT) { }
return true;
static bool checkForChainedInvoke(Toy_Ast* ptr) {
if (ptr == NULL) {
return false;
} }
if (ptr->type == TOY_AST_FN_INVOKE) {
return true;
} }
return false; return false;
@@ -220,6 +226,7 @@ static unsigned int writeBytecodeFromAst(Toy_Bytecode** mb, Toy_Ast* ast); //for
static void writeBytecodeBody(Toy_Bytecode* mb, Toy_Ast* ast); static void writeBytecodeBody(Toy_Bytecode* mb, Toy_Ast* ast);
static unsigned char* collateBytecodeBody(Toy_Bytecode* mb); static unsigned char* collateBytecodeBody(Toy_Bytecode* mb);
static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign ast, bool chainedAssignment); //forward declare for chaining of var declarations static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign ast, bool chainedAssignment); //forward declare for chaining of var declarations
static unsigned int writeInstructionFnInvoke(Toy_Bytecode** mb, Toy_AstFnInvoke ast, bool chainedInvoke);
static unsigned int writeInstructionValue(Toy_Bytecode** mb, Toy_AstValue ast) { static unsigned int writeInstructionValue(Toy_Bytecode** mb, Toy_AstValue ast) {
EMIT_BYTE(mb, code, TOY_OPCODE_READ); EMIT_BYTE(mb, code, TOY_OPCODE_READ);
@@ -748,8 +755,18 @@ static unsigned int writeInstructionContinue(Toy_Bytecode** mb, Toy_AstContinue
} }
static unsigned int writeInstructionReturn(Toy_Bytecode** mb, Toy_AstReturn ast) { static unsigned int writeInstructionReturn(Toy_Bytecode** mb, Toy_AstReturn ast) {
//the things to return unsigned int retCount = 0;
unsigned int retCount = writeBytecodeFromAst(mb, ast.child);
//what is returned
if (checkForChainedAssign(ast.child)) {
retCount = writeInstructionAssign(mb, ast.child->varAssign, true);
}
else if (checkForChainedInvoke(ast.child)) {
retCount = writeInstructionFnInvoke(mb, ast.child->fnInvoke, true);
}
else {
retCount = writeBytecodeFromAst(mb, ast.child); //default value
}
//output the print opcode //output the print opcode
EMIT_BYTE(mb, code,TOY_OPCODE_RETURN); EMIT_BYTE(mb, code,TOY_OPCODE_RETURN);
@@ -779,9 +796,12 @@ static unsigned int writeInstructionPrint(Toy_Bytecode** mb, Toy_AstPrint ast) {
static unsigned int writeInstructionVarDeclare(Toy_Bytecode** mb, Toy_AstVarDeclare ast) { static unsigned int writeInstructionVarDeclare(Toy_Bytecode** mb, Toy_AstVarDeclare ast) {
//if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true
if (checkForChaining(ast.expr)) { if (checkForChainedAssign(ast.expr)) {
writeInstructionAssign(mb, ast.expr->varAssign, true); writeInstructionAssign(mb, ast.expr->varAssign, true);
} }
else if (checkForChainedInvoke(ast.expr)) {
writeInstructionFnInvoke(mb, ast.expr->fnInvoke, true);
}
else { else {
writeBytecodeFromAst(mb, ast.expr); //default value writeBytecodeFromAst(mb, ast.expr); //default value
} }
@@ -801,6 +821,7 @@ static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign a
unsigned int result = 0; unsigned int result = 0;
//BUG: flip the order of target & value, to allow chained assignment AND multiple return values //BUG: flip the order of target & value, to allow chained assignment AND multiple return values
//do I need multiple return values?
//target is a variable name //target is a variable name
if (ast.target->type == TOY_AST_VALUE && TOY_VALUE_IS_STRING(ast.target->value.value)) { if (ast.target->type == TOY_AST_VALUE && TOY_VALUE_IS_STRING(ast.target->value.value)) {
@@ -822,9 +843,12 @@ static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign a
writeBytecodeFromAst(mb, ast.target->aggregate.right); //key writeBytecodeFromAst(mb, ast.target->aggregate.right); //key
//if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true
if (checkForChaining(ast.expr)) { if (checkForChainedAssign(ast.expr)) {
result += writeInstructionAssign(mb, ast.expr->varAssign, true); result += writeInstructionAssign(mb, ast.expr->varAssign, true);
} }
else if (checkForChainedInvoke(ast.expr)) {
result += writeInstructionFnInvoke(mb, ast.expr->fnInvoke, true);
}
else { else {
result += writeBytecodeFromAst(mb, ast.expr); //default value result += writeBytecodeFromAst(mb, ast.expr); //default value
} }
@@ -847,9 +871,12 @@ static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign a
//determine RHS, include duplication if needed //determine RHS, include duplication if needed
if (ast.flag == TOY_AST_FLAG_ASSIGN) { if (ast.flag == TOY_AST_FLAG_ASSIGN) {
//if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true
if (checkForChaining(ast.expr)) { if (checkForChainedAssign(ast.expr)) {
result += writeInstructionAssign(mb, ast.expr->varAssign, true); result += writeInstructionAssign(mb, ast.expr->varAssign, true);
} }
else if (checkForChainedInvoke(ast.expr)) {
result += writeInstructionFnInvoke(mb, ast.expr->fnInvoke, true);
}
else { else {
result += writeBytecodeFromAst(mb, ast.expr); //default value result += writeBytecodeFromAst(mb, ast.expr); //default value
} }
@@ -866,9 +893,12 @@ static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign a
EMIT_BYTE(mb, code,0); EMIT_BYTE(mb, code,0);
//if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true
if (checkForChaining(ast.expr)) { if (checkForChainedAssign(ast.expr)) {
result += writeInstructionAssign(mb, ast.expr->varAssign, true); result += writeInstructionAssign(mb, ast.expr->varAssign, true);
} }
else if (checkForChainedInvoke(ast.expr)) {
result += writeInstructionFnInvoke(mb, ast.expr->fnInvoke, true);
}
else { else {
result += writeBytecodeFromAst(mb, ast.expr); //default value result += writeBytecodeFromAst(mb, ast.expr); //default value
} }
@@ -885,9 +915,12 @@ static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign a
EMIT_BYTE(mb, code,0); EMIT_BYTE(mb, code,0);
//if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true
if (checkForChaining(ast.expr)) { if (checkForChainedAssign(ast.expr)) {
result += writeInstructionAssign(mb, ast.expr->varAssign, true); result += writeInstructionAssign(mb, ast.expr->varAssign, true);
} }
else if (checkForChainedInvoke(ast.expr)) {
result += writeInstructionFnInvoke(mb, ast.expr->fnInvoke, true);
}
else { else {
result += writeBytecodeFromAst(mb, ast.expr); //default value result += writeBytecodeFromAst(mb, ast.expr); //default value
} }
@@ -904,9 +937,12 @@ static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign a
EMIT_BYTE(mb, code,0); EMIT_BYTE(mb, code,0);
//if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true
if (checkForChaining(ast.expr)) { if (checkForChainedAssign(ast.expr)) {
result += writeInstructionAssign(mb, ast.expr->varAssign, true); result += writeInstructionAssign(mb, ast.expr->varAssign, true);
} }
else if (checkForChainedInvoke(ast.expr)) {
result += writeInstructionFnInvoke(mb, ast.expr->fnInvoke, true);
}
else { else {
result += writeBytecodeFromAst(mb, ast.expr); //default value result += writeBytecodeFromAst(mb, ast.expr); //default value
} }
@@ -923,9 +959,12 @@ static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign a
EMIT_BYTE(mb, code,0); EMIT_BYTE(mb, code,0);
//if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true
if (checkForChaining(ast.expr)) { if (checkForChainedAssign(ast.expr)) {
result += writeInstructionAssign(mb, ast.expr->varAssign, true); result += writeInstructionAssign(mb, ast.expr->varAssign, true);
} }
else if (checkForChainedInvoke(ast.expr)) {
result += writeInstructionFnInvoke(mb, ast.expr->fnInvoke, true);
}
else { else {
result += writeBytecodeFromAst(mb, ast.expr); //default value result += writeBytecodeFromAst(mb, ast.expr); //default value
} }
@@ -942,9 +981,12 @@ static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign a
EMIT_BYTE(mb, code,0); EMIT_BYTE(mb, code,0);
//if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true
if (checkForChaining(ast.expr)) { if (checkForChainedAssign(ast.expr)) {
result += writeInstructionAssign(mb, ast.expr->varAssign, true); result += writeInstructionAssign(mb, ast.expr->varAssign, true);
} }
else if (checkForChainedInvoke(ast.expr)) {
result += writeInstructionFnInvoke(mb, ast.expr->fnInvoke, true);
}
else { else {
result += writeBytecodeFromAst(mb, ast.expr); //default value result += writeBytecodeFromAst(mb, ast.expr); //default value
} }
@@ -960,7 +1002,7 @@ static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign a
exit(-1); exit(-1);
} }
return result + (chainedAssignment ? 1 : 0); return result;
} }
static unsigned int writeInstructionAccess(Toy_Bytecode** mb, Toy_AstVarAccess ast) { static unsigned int writeInstructionAccess(Toy_Bytecode** mb, Toy_AstVarAccess ast) {
@@ -1054,7 +1096,7 @@ static unsigned int writeInstructionFnDeclare(Toy_Bytecode** mb, Toy_AstFnDeclar
return 0; return 0;
} }
static unsigned int writeInstructionFnInvoke(Toy_Bytecode** mb, Toy_AstFnInvoke ast) { static unsigned int writeInstructionFnInvoke(Toy_Bytecode** mb, Toy_AstFnInvoke ast, bool chainedInvoke) {
unsigned int argCount = writeBytecodeFromAst(mb, ast.args); unsigned int argCount = writeBytecodeFromAst(mb, ast.args);
if (argCount > 255) { if (argCount > 255) {
@@ -1077,7 +1119,7 @@ static unsigned int writeInstructionFnInvoke(Toy_Bytecode** mb, Toy_AstFnInvoke
EMIT_BYTE(mb, code, (unsigned char)argCount); EMIT_BYTE(mb, code, (unsigned char)argCount);
EMIT_BYTE(mb, code, 0); //IDK how many returns EMIT_BYTE(mb, code, 0); //IDK how many returns
return 0; return chainedInvoke ? 1 : 0;
} }
static unsigned int writeInstructionAttribute(Toy_Bytecode** mb, Toy_AstAttribute ast) { static unsigned int writeInstructionAttribute(Toy_Bytecode** mb, Toy_AstAttribute ast) {
@@ -1226,7 +1268,7 @@ static unsigned int writeBytecodeFromAst(Toy_Bytecode** mb, Toy_Ast* ast) {
break; break;
case TOY_AST_FN_INVOKE: case TOY_AST_FN_INVOKE:
result += writeInstructionFnInvoke(mb, ast->fnInvoke); result += writeInstructionFnInvoke(mb, ast->fnInvoke, false);
break; break;
case TOY_AST_ATTRIBUTE: case TOY_AST_ATTRIBUTE:
+1 -1
View File
@@ -71,7 +71,7 @@ static void probeAndInsert(Toy_Scope* scope, Toy_String* key, Toy_Value value, T
static 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 //allocate and zero a new Toy_ScopeEntry array in memory
Toy_ScopeEntry* newEntries = malloc(newCapacity * sizeof(Toy_ScopeEntry)); //URGENT: Swap to a bucket Toy_ScopeEntry* newEntries = malloc(newCapacity * sizeof(Toy_ScopeEntry));
if (newEntries == NULL) { if (newEntries == NULL) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate space for 'Toy_Scope' entries\n" TOY_CC_RESET); fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate space for 'Toy_Scope' entries\n" TOY_CC_RESET);
+2 -2
View File
@@ -5,8 +5,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
Toy_Stack* Toy_allocateStack(void) { //TODO: add initial size as parameter Toy_Stack* Toy_allocateStack(void) {
Toy_Stack* stack = malloc(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack)); //URGENT: Swap to a bucket (4 instances) Toy_Stack* stack = malloc(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack));
if (stack == NULL) { if (stack == NULL) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Stack' of %d capacity (%d space in memory)\n" TOY_CC_RESET, TOY_STACK_INITIAL_CAPACITY, (int)(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack))); fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Stack' of %d capacity (%d space in memory)\n" TOY_CC_RESET, TOY_STACK_INITIAL_CAPACITY, (int)(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack)));
+1 -1
View File
@@ -46,7 +46,7 @@ static void probeAndInsert(Toy_Table** tableHandle, Toy_Value key, Toy_Value val
//exposed functions //exposed functions
Toy_Table* Toy_private_adjustTableCapacity(Toy_Table* oldTable, unsigned int newCapacity) { Toy_Table* Toy_private_adjustTableCapacity(Toy_Table* oldTable, unsigned int newCapacity) {
//allocate and zero a new table in memory //allocate and zero a new table in memory
Toy_Table* newTable = malloc(newCapacity * sizeof(Toy_TableEntry) + sizeof(Toy_Table)); //URGENT: Swap to a bucket Toy_Table* newTable = malloc(newCapacity * sizeof(Toy_TableEntry) + sizeof(Toy_Table));
if (newTable == NULL) { if (newTable == NULL) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Table'\n" TOY_CC_RESET); fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Table'\n" TOY_CC_RESET);
+3 -5
View File
@@ -104,7 +104,7 @@ Toy_Value Toy_copyValue(Toy_Bucket** bucketHandle, Toy_Value value) {
return TOY_VALUE_FROM_STRING(Toy_copyString(value.as.string)); return TOY_VALUE_FROM_STRING(Toy_copyString(value.as.string));
} }
case TOY_VALUE_ARRAY: { //TODO: switch to buckets case TOY_VALUE_ARRAY: {
//arrays probably won't get copied much //arrays probably won't get copied much
Toy_Array* ptr = value.as.array; Toy_Array* ptr = value.as.array;
Toy_Array* result = Toy_resizeArray(NULL, ptr->capacity); Toy_Array* result = Toy_resizeArray(NULL, ptr->capacity);
@@ -119,7 +119,7 @@ Toy_Value Toy_copyValue(Toy_Bucket** bucketHandle, Toy_Value value) {
return TOY_VALUE_FROM_ARRAY(result); return TOY_VALUE_FROM_ARRAY(result);
} }
case TOY_VALUE_TABLE: { //TODO: switch to buckets case TOY_VALUE_TABLE: {
//tables probably won't get copied much //tables probably won't get copied much
Toy_Table* ptr = value.as.table; Toy_Table* ptr = value.as.table;
Toy_Table* result = Toy_allocateTable(ptr->capacity); Toy_Table* result = Toy_allocateTable(ptr->capacity);
@@ -550,7 +550,7 @@ Toy_String* Toy_stringifyValue(Toy_Bucket** bucketHandle, Toy_Value value) {
//clean up //clean up
Toy_freeString(open); Toy_freeString(open);
Toy_freeString(close); Toy_freeString(close);
Toy_freeString(comma); //TODO: reusable global, or string type "permanent", needs benchmarking Toy_freeString(comma);
Toy_freeString(quote); Toy_freeString(quote);
return string; return string;
@@ -626,8 +626,6 @@ Toy_String* Toy_stringifyValue(Toy_Bucket** bucketHandle, Toy_Value value) {
//finally //finally
string = final; string = final;
//TODO: would a simple buffer be faster here?
//if there's more elements //if there's more elements
needsComma = true; needsComma = true;
} }
+1 -1
View File
@@ -51,7 +51,7 @@ typedef struct Toy_Value { //32 | 64 BITNESS
#define TOY_VALUE_IS_ARRAY(value) ((value).type == TOY_VALUE_ARRAY || (TOY_VALUE_IS_REFERENCE(value) && Toy_unwrapValue(value).type == TOY_VALUE_ARRAY)) #define TOY_VALUE_IS_ARRAY(value) ((value).type == TOY_VALUE_ARRAY || (TOY_VALUE_IS_REFERENCE(value) && Toy_unwrapValue(value).type == TOY_VALUE_ARRAY))
#define TOY_VALUE_IS_TABLE(value) ((value).type == TOY_VALUE_TABLE || (TOY_VALUE_IS_REFERENCE(value) && Toy_unwrapValue(value).type == TOY_VALUE_TABLE)) #define TOY_VALUE_IS_TABLE(value) ((value).type == TOY_VALUE_TABLE || (TOY_VALUE_IS_REFERENCE(value) && Toy_unwrapValue(value).type == TOY_VALUE_TABLE))
#define TOY_VALUE_IS_FUNCTION(value) ((value).type == TOY_VALUE_FUNCTION || (TOY_VALUE_IS_REFERENCE(value) && Toy_unwrapValue(value).type == TOY_VALUE_FUNCTION)) #define TOY_VALUE_IS_FUNCTION(value) ((value).type == TOY_VALUE_FUNCTION || (TOY_VALUE_IS_REFERENCE(value) && Toy_unwrapValue(value).type == TOY_VALUE_FUNCTION))
#define TOY_VALUE_IS_OPAQUE(value) ((value).type == TOY_VALUE_OPAQUE) #define TOY_VALUE_IS_OPAQUE(value) ((value).type == TOY_VALUE_OPAQUE || (TOY_VALUE_IS_REFERENCE(value) && Toy_unwrapValue(value).type == TOY_VALUE_OPAQUE))
#define TOY_VALUE_IS_REFERENCE(value) ((value).type == TOY_VALUE_REFERENCE) #define TOY_VALUE_IS_REFERENCE(value) ((value).type == TOY_VALUE_REFERENCE)
#define TOY_VALUE_AS_BOOLEAN(value) ((value).as.boolean) #define TOY_VALUE_AS_BOOLEAN(value) ((value).as.boolean)
+6 -6
View File
@@ -725,7 +725,7 @@ static void processAssert(Toy_VM* vm) {
//determine the args //determine the args
if (count == 1) { if (count == 1) {
message = TOY_VALUE_FROM_STRING(Toy_toString(&vm->memoryBucket, "assertion failed")); //TODO: needs a better default message message = TOY_VALUE_FROM_STRING(Toy_toString(&vm->memoryBucket, "assertion failed"));
value = Toy_popStack(&vm->stack); value = Toy_popStack(&vm->stack);
} }
else if (count == 2) { else if (count == 2) {
@@ -1099,12 +1099,12 @@ void Toy_resetVM(Toy_VM* vm, bool preserveScope, bool preserveStack) {
} }
if (!preserveStack) { if (!preserveStack) {
Toy_resetStack(&vm->stack); //NOTE: has a realloc() Toy_resetStack(&vm->stack); //WARN: has a realloc()
} }
//not sure how often to call teh GC //not sure how often to call teh GC
if (vm->memoryBucket) { if (vm->memoryBucket) {
Toy_collectBucketGarbage(&vm->memoryBucket); Toy_collectBucketGarbage(&vm->memoryBucket); //URGENT: call GC after a certain number of bucket links allocated
} }
} }
@@ -1190,8 +1190,8 @@ void Toy_freeVM(Toy_VM* vm) {
} }
Toy_Array* Toy_extractResultsFromVM(Toy_VM* parentVM, Toy_VM* subVM, unsigned int resultCount) { Toy_Array* Toy_extractResultsFromVM(Toy_VM* parentVM, Toy_VM* subVM, unsigned int resultCount) {
if (subVM->stack->count < resultCount) { if (subVM->stack->count != resultCount) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Too many results requested from VM, exiting\n" TOY_CC_RESET); fprintf(stderr, TOY_CC_ERROR "ERROR: Too %s results requested from VM, exiting\n" TOY_CC_RESET, subVM->stack->count < resultCount ? "many":"few");
exit(-1); exit(-1);
} }
@@ -1199,7 +1199,7 @@ Toy_Array* Toy_extractResultsFromVM(Toy_VM* parentVM, Toy_VM* subVM, unsigned in
const unsigned int offset = subVM->stack->count - resultCount; //first element to extract const unsigned int offset = subVM->stack->count - resultCount; //first element to extract
for (/* EMPTY */; results->count < resultCount; results->count++) { //TODO: make sure the parent bucket adopts the child bucket's responsibilities for (/* EMPTY */; results->count < resultCount; results->count++) {
results->data[results->count] = Toy_copyValue(&parentVM->memoryBucket, subVM->stack->data[offset + results->count]); results->data[results->count] = Toy_copyValue(&parentVM->memoryBucket, subVM->stack->data[offset + results->count]);
} }
-2
View File
@@ -5,8 +5,6 @@ a["beta"] = 6;
print a; print a;
assert a == ["alpha": 1, "beta": 6, "gamma": 3], "1-D tables failed"; assert a == ["alpha": 1, "beta": 6, "gamma": 3], "1-D tables failed";
//WONTFIX: Nested tables cause an issue under very specific circumstances: run under GDB, in verbose mode, only in github's CI runner. The reason is unclear.
//nested //nested
var b = [ var b = [
"outer": ["inner": true], "outer": ["inner": true],