Fixed nagging issues, read more

* A segfault from the inspector
* multiple returns no longer a goal
* Cleaned up the 'URGENT' comment tags
* Narrowed down what is needed for alpha
This commit is contained in:
2026-05-15 14:13:54 +10:00
parent 1660dc8b53
commit 3ab18c7b14
11 changed files with 50 additions and 61 deletions
+19 -15
View File
@@ -9,13 +9,17 @@
//if set, used for delegating to user-defined code
static Toy_OpaqueAttributeHandler opaqueAttributeCallback = NULL;
//NOTE: there is no need to call 'Toy_freeValue' on the arguments, as the VM assumes you don't
//utils
#define MATCH_VALUE_AND_CSTRING(value, cstring) \
((TOY_VALUE_AS_STRING(value)->info.length == strlen(cstring)) && \
(strncmp(cstring, TOY_VALUE_AS_STRING(value)->leaf.data, TOY_VALUE_AS_STRING(value)->info.length) == 0))
//NOTE: there is no need to call 'Toy_freeValue' on the arguments, as the VM assumes you don't
Toy_Value Toy_private_handleStringAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "length", 6) == 0) {
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_STRING(compound)->info.length);
}
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "asUpper", 7) == 0) {
else if (MATCH_VALUE_AND_CSTRING(attribute, "asUpper")) {
char* buffer = Toy_getStringRaw(TOY_VALUE_AS_STRING(compound));
for (int i = 0; buffer[i] != '\0'; i++) {
buffer[i] = toupper(buffer[i]);
@@ -24,7 +28,7 @@ Toy_Value Toy_private_handleStringAttributes(Toy_VM* vm, Toy_Value compound, Toy
free(buffer);
return TOY_VALUE_FROM_STRING(str);
}
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "asLower", 7) == 0) {
else if (MATCH_VALUE_AND_CSTRING(attribute, "asLower")) {
char* buffer = Toy_getStringRaw(TOY_VALUE_AS_STRING(compound));
for (int i = 0; buffer[i] != '\0'; i++) {
buffer[i] = tolower(buffer[i]);
@@ -116,7 +120,7 @@ static void attr_arrayForEach(Toy_VM* vm) {
Toy_declareScope(subVM.scope, Toy_copyString(name), paramType, Toy_copyValue(&subVM.memoryBucket, array->data[iterator]), true);
Toy_freeString(name);
Toy_runVM(&subVM); //TODO: could use a 'map'-style method by storing the results
Toy_runVM(&subVM);
Toy_resetVM(&subVM, false, true);
}
@@ -148,22 +152,22 @@ static void attr_arraySort(Toy_VM* vm) {
}
Toy_Value Toy_private_handleArrayAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "length", 6) == 0) {
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_ARRAY(compound)->count);
}
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "pushBack", 8) == 0) {
else if (MATCH_VALUE_AND_CSTRING(attribute, "pushBack")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arrayPushBack);
return TOY_VALUE_FROM_FUNCTION(fn);
}
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "popBack", 7) == 0) {
else if (MATCH_VALUE_AND_CSTRING(attribute, "popBack")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arrayPopBack);
return TOY_VALUE_FROM_FUNCTION(fn);
}
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "forEach", 7) == 0) {
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 (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "sort", 4) == 0) {
else if (MATCH_VALUE_AND_CSTRING(attribute, "sort")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arraySort);
return TOY_VALUE_FROM_FUNCTION(fn);
}
@@ -224,22 +228,22 @@ static void attr_tableForEach(Toy_VM* vm) {
}
Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "length", 6) == 0) {
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_ARRAY(compound)->count);
}
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "insert", 6) == 0) {
else if (MATCH_VALUE_AND_CSTRING(attribute, "insert")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableInsert);
return TOY_VALUE_FROM_FUNCTION(fn);
}
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "hasKey", 6) == 0) {
else if (MATCH_VALUE_AND_CSTRING(attribute, "hasKey")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableHasKey);
return TOY_VALUE_FROM_FUNCTION(fn);
}
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "remove", 6) == 0) {
else if (MATCH_VALUE_AND_CSTRING(attribute, "remove")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableRemove);
return TOY_VALUE_FROM_FUNCTION(fn);
}
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "forEach", 7) == 0) { //URGENT: compare the contents AND length of these strings
else if (MATCH_VALUE_AND_CSTRING(attribute, "forEach")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableForEach);
return TOY_VALUE_FROM_FUNCTION(fn);
}
-3
View File
@@ -820,9 +820,6 @@ static unsigned int writeInstructionVarDeclare(Toy_Bytecode** mb, Toy_AstVarDecl
static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign ast, bool chainedAssignment) {
unsigned int result = 0;
//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
if (ast.target->type == TOY_AST_VALUE && TOY_VALUE_IS_STRING(ast.target->value.value)) {
//name string
+1 -1
View File
@@ -1066,7 +1066,7 @@ static void makeStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** ro
return;
}
//TODO: for-pre-clause-post-then
//URGENT: for-pre-clause-post-then
//break
else if (match(parser, TOY_TOKEN_KEYWORD_BREAK)) {
-1
View File
@@ -494,7 +494,6 @@ Toy_String* Toy_stringifyValue(Toy_Bucket** bucketHandle, Toy_Value value) {
return Toy_copyString(value.as.string);
case TOY_VALUE_ARRAY: {
//TODO: concat + free is definitely a performance nightmare, could make an append function?
Toy_Array* ptr = value.as.array;
//if array is empty, skip below
+8 -23
View File
@@ -394,15 +394,8 @@ static void processInvoke(Toy_VM* vm) {
//extract and store any results
if (resultCount > 0) {
Toy_Array* results = Toy_extractResultsFromVM(vm, &subVM, resultCount);
for (unsigned int i = 0; i < results->count; i++) {
//NOTE: since the results array is being immediately freed, just push each element without a call to copy
Toy_pushStack(&vm->stack, results->data[i]);
}
//a bit naughty
free(results);
Toy_Value result = Toy_getReturnValueFromVM(vm, &subVM);
Toy_pushStack(&vm->stack, result);
}
//cleanup
@@ -1104,7 +1097,7 @@ void Toy_resetVM(Toy_VM* vm, bool preserveScope, bool preserveStack) {
//not sure how often to call teh GC
if (vm->memoryBucket) {
Toy_collectBucketGarbage(&vm->memoryBucket); //URGENT: call GC after a certain number of bucket links allocated
Toy_collectBucketGarbage(&vm->memoryBucket); //WONTFIX: call GC after a certain number of bucket links allocated
}
}
@@ -1189,19 +1182,11 @@ void Toy_freeVM(Toy_VM* vm) {
}
}
Toy_Array* Toy_extractResultsFromVM(Toy_VM* parentVM, Toy_VM* subVM, unsigned int resultCount) {
if (subVM->stack->count != resultCount) {
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);
Toy_Value Toy_getReturnValueFromVM(Toy_VM* parentVM, Toy_VM* subVM) {
if (subVM->stack->count > 0) {
return Toy_copyValue(&parentVM->memoryBucket, subVM->stack->data[subVM->stack->count-1]);
}
Toy_Array* results = Toy_resizeArray(NULL, resultCount);
const unsigned int offset = subVM->stack->count - resultCount; //first element to extract
for (/* EMPTY */; results->count < resultCount; results->count++) {
results->data[results->count] = Toy_copyValue(&parentVM->memoryBucket, subVM->stack->data[offset + results->count]);
else {
return TOY_VALUE_FROM_NULL();
}
return results;
}
+1 -1
View File
@@ -51,5 +51,5 @@ 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);
TOY_API Toy_Array* Toy_extractResultsFromVM(Toy_VM* parentVM, Toy_VM* subVM, unsigned int resultCount);
TOY_API Toy_Value Toy_getReturnValueFromVM(Toy_VM* parentVM, Toy_VM* subVM);