Removed array.forEach, tweaked error messages

This commit is contained in:
2026-05-25 11:42:43 +10:00
parent e59bcd0572
commit c097dd5514
3 changed files with 10 additions and 92 deletions
+3 -6
View File
@@ -1,10 +1,7 @@
var array = ["foo", "bar", "buzz", "fizz"];
var table = ["alpha": 1, "beta": 2];
for (var i in array) {
if (i == "buzz") break; //use break or continue
for (var i in table) {
print i;
}
print "done";
}
-79
View File
@@ -90,70 +90,6 @@ static void attr_arrayPopBack(Toy_VM* vm, Toy_FunctionNative* self) {
Toy_pushStack(&vm->stack, element);
}
static void attr_arrayForEach(Toy_VM* vm, Toy_FunctionNative* self) {
//URGENT: replace with for-loop
(void)self;
Toy_Value compound = Toy_popStack(&vm->stack);
Toy_Value callback = Toy_popStack(&vm->stack);
if (TOY_VALUE_IS_FUNCTION(callback) != true) {
char buffer[256];
snprintf(buffer, 256, "Expected function, found '%s'", Toy_getValueTypeAsCString(callback.type));
Toy_error(buffer);
return;
}
Toy_Array* array = TOY_VALUE_AS_ARRAY(compound);
Toy_Function* fn = TOY_VALUE_AS_FUNCTION(callback);
//this emulates 'processInvoke' a bit, but not entirely
Toy_VM subVM;
Toy_inheritVM(vm, &subVM);
switch(fn->type) {
case TOY_FUNCTION_CUSTOM: {
//push and run for each element
for (unsigned int iterator = 0; iterator < array->count; iterator++) {
//bind to the subVM (more expensive than I'd like)
Toy_bindVM(&subVM, fn->bytecode.code, fn->bytecode.parentScope);
//get parameter name as a string
unsigned int paramAddr = ((unsigned int*)(subVM.code + subVM.paramAddr))[0];
Toy_ValueType paramType = (Toy_ValueType)(((unsigned int*)(subVM.code + subVM.paramAddr))[1]);
const char* cstr = ((char*)(subVM.code + subVM.dataAddr)) + paramAddr;
Toy_String* name = Toy_toStringLength(&subVM.memoryBucket, cstr, strlen(cstr));
Toy_declareScope(subVM.scope, Toy_copyString(name), paramType, Toy_copyValue(&subVM.memoryBucket, array->data[iterator]), true);
Toy_freeString(name);
Toy_runVM(&subVM);
Toy_resetVM(&subVM, false, true);
subVM.scope = NULL; //BUGFIX: need to clear the scope when iterating
}
}
break;
case TOY_FUNCTION_NATIVE: {
//this uses a subVM for the native function, which is a slight difference than 'processInoke'
for (unsigned int iterator = 0; iterator < array->count; iterator++) {
Toy_pushStack(&subVM.stack, Toy_copyValue(&subVM.memoryBucket, array->data[iterator]));
fn->native.callback(&subVM, &fn->native); //NOTE: try not to leave anything on the stack afterwards
}
}
break;
default:
Toy_error("Can't call an unknown function type in 'forEach'");
break;
}
//cleanup
Toy_freeVM(&subVM);
}
static void attr_arraySort(Toy_VM* vm, Toy_FunctionNative* self) {
(void)vm;
(void)self;
@@ -173,10 +109,6 @@ Toy_Value Toy_private_handleArrayAttributes(Toy_VM* vm, Toy_Value compound, Toy_
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arrayPopBack);
return TOY_VALUE_FROM_FUNCTION(fn);
}
else if (MATCH_VALUE_AND_CSTRING(attribute, "forEach")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arrayForEach);
return TOY_VALUE_FROM_FUNCTION(fn);
}
else if (MATCH_VALUE_AND_CSTRING(attribute, "sort")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arraySort);
return TOY_VALUE_FROM_FUNCTION(fn);
@@ -238,13 +170,6 @@ static void attr_tableRemove(Toy_VM* vm, Toy_FunctionNative* self) {
Toy_removeTable(&table, key);
}
static void attr_tableForEach(Toy_VM* vm, Toy_FunctionNative* self) {
(void)vm;
(void)self;
//URGENT: replace with for-loop
}
Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_ARRAY(compound)->count);
@@ -261,10 +186,6 @@ Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableRemove);
return TOY_VALUE_FROM_FUNCTION(fn);
}
else if (MATCH_VALUE_AND_CSTRING(attribute, "forEach")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableForEach);
return TOY_VALUE_FROM_FUNCTION(fn);
}
else {
char buffer[256];
snprintf(buffer, 256, "Unknown attribute '%s' of type '%s'", TOY_VALUE_AS_STRING(attribute)->leaf.data, Toy_getValueTypeAsCString(compound.type));
+7 -7
View File
@@ -150,7 +150,7 @@ static void processRead(Toy_VM* 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, vm->scope); //BUG: functions don't have the jumps indirection?
Toy_Function* function = Toy_createFunctionFromBytecode(&vm->memoryBucket, vm->code + vm->subsAddr + addr, vm->scope); //BUG: functions don't have the jumpTable indirection?
value = TOY_VALUE_FROM_FUNCTION(function);
break;
@@ -442,7 +442,7 @@ static void processAttribute(Toy_VM* vm) {
}
else {
char buffer[256];
snprintf(buffer, 256, "Can't access an attribute of type '%s'", Toy_getValueTypeAsCString(compound.type));
snprintf(buffer, 256, "Can't access an attribute of type '%s'", Toy_getValueTypeAsCString(Toy_unwrapValue(compound).type));
Toy_error(buffer);
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_NULL());
return;
@@ -490,7 +490,7 @@ static void processIterate(Toy_VM* vm) {
Toy_Value compound = Toy_popStack(&vm->stack);
if (!TOY_VALUE_IS_INTEGER(counter)) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown counter type '%s' found in for loop, exiting\n" TOY_CC_RESET, Toy_getValueTypeAsCString(counter.type));
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown counter type '%s' found in for loop, exiting\n" TOY_CC_RESET, Toy_getValueTypeAsCString(Toy_unwrapValue(counter).type));
exit(-1);
}
@@ -518,7 +518,7 @@ static void processIterate(Toy_VM* vm) {
Toy_pushStack(&vm->stack, value);
}
else {
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown iterable type '%s' found in for loop, exiting\n" TOY_CC_RESET, Toy_getValueTypeAsCString(compound.type));
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown iterable type '%s' found in for loop, exiting\n" TOY_CC_RESET, Toy_getValueTypeAsCString(Toy_unwrapValue(compound).type));
exit(-1);
}
}
@@ -530,7 +530,7 @@ static void processArithmetic(Toy_VM* vm, Toy_OpcodeType opcode) {
//check types
if ((!TOY_VALUE_IS_INTEGER(left) && !TOY_VALUE_IS_FLOAT(left)) || (!TOY_VALUE_IS_INTEGER(right) && !TOY_VALUE_IS_FLOAT(right))) {
char buffer[256];
snprintf(buffer, 256, "Invalid types '%s' and '%s' passed in arithmetic", Toy_getValueTypeAsCString(left.type), Toy_getValueTypeAsCString(right.type));
snprintf(buffer, 256, "Invalid types '%s' and '%s' passed in arithmetic", Toy_getValueTypeAsCString(Toy_unwrapValue(left).type), Toy_getValueTypeAsCString(Toy_unwrapValue(right).type));
Toy_error(buffer);
Toy_freeValue(left);
@@ -624,7 +624,7 @@ static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) {
if (Toy_checkValuesAreComparable(left, right) != true) {
char buffer[256];
snprintf(buffer, 256, "Can't compare value types '%s' and '%s'", Toy_getValueTypeAsCString(left.type), Toy_getValueTypeAsCString(right.type));
snprintf(buffer, 256, "Can't compare value types '%s' and '%s'", Toy_getValueTypeAsCString(Toy_unwrapValue(left).type), Toy_getValueTypeAsCString(Toy_unwrapValue(right).type));
Toy_error(buffer);
Toy_freeValue(left);
@@ -1002,7 +1002,7 @@ static void processIndex(Toy_VM* vm) {
}
else {
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown value type '%s' found in processIndex, exiting\n" TOY_CC_RESET, Toy_getValueTypeAsCString(value.type));
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown value type '%s' found in processIndex, exiting\n" TOY_CC_RESET, Toy_getValueTypeAsCString(Toy_unwrapValue(value).type));
exit(-1);
}