Fixed nested assignment bug

This commit is contained in:
2024-12-24 11:58:51 +11:00
parent 223db840c8
commit 4faa0c0476
2 changed files with 43 additions and 127 deletions

View File

@@ -118,8 +118,6 @@ Toy_Value Toy_copyValue(Toy_Value value) {
} }
void Toy_freeValue(Toy_Value value) { void Toy_freeValue(Toy_Value value) {
//NOTE: do not unwrap this value, as references shouldn't be freed
switch(value.type) { switch(value.type) {
case TOY_VALUE_NULL: case TOY_VALUE_NULL:
case TOY_VALUE_BOOLEAN: case TOY_VALUE_BOOLEAN:
@@ -143,12 +141,15 @@ void Toy_freeValue(Toy_Value value) {
break; break;
} }
case TOY_VALUE_REFERENCE:
//don't free references
return;
case TOY_VALUE_TABLE: case TOY_VALUE_TABLE:
case TOY_VALUE_FUNCTION: case TOY_VALUE_FUNCTION:
case TOY_VALUE_OPAQUE: case TOY_VALUE_OPAQUE:
case TOY_VALUE_TYPE: case TOY_VALUE_TYPE:
case TOY_VALUE_ANY: case TOY_VALUE_ANY:
case TOY_VALUE_REFERENCE:
case TOY_VALUE_UNKNOWN: case TOY_VALUE_UNKNOWN:
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't free an unknown value type, exiting\n" TOY_CC_RESET); fprintf(stderr, TOY_CC_ERROR "ERROR: Can't free an unknown value type, exiting\n" TOY_CC_RESET);
exit(-1); exit(-1);

View File

@@ -303,14 +303,8 @@ static void processArithmetic(Toy_VM* vm, Toy_OpcodeType opcode) {
snprintf(buffer, 256, "Invalid types '%s' and '%s' passed in arithmetic", Toy_private_getValueTypeAsCString(left.type), Toy_private_getValueTypeAsCString(right.type)); snprintf(buffer, 256, "Invalid types '%s' and '%s' passed in arithmetic", Toy_private_getValueTypeAsCString(left.type), Toy_private_getValueTypeAsCString(right.type));
Toy_error(buffer); Toy_error(buffer);
if (TOY_VALUE_IS_REFERENCE(left) != true) {
Toy_freeValue(left); Toy_freeValue(left);
}
if (TOY_VALUE_IS_REFERENCE(right) != true) {
Toy_freeValue(right); Toy_freeValue(right);
}
return; return;
} }
@@ -390,14 +384,8 @@ static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) {
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(!equal) ); Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(!equal) );
} }
if (TOY_VALUE_IS_REFERENCE(left) != true) {
Toy_freeValue(left); Toy_freeValue(left);
}
if (TOY_VALUE_IS_REFERENCE(right) != true) {
Toy_freeValue(right); Toy_freeValue(right);
}
return; return;
} }
@@ -406,14 +394,8 @@ static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) {
snprintf(buffer, 256, "Can't compare value types '%s' and '%s'", Toy_private_getValueTypeAsCString(left.type), Toy_private_getValueTypeAsCString(right.type)); snprintf(buffer, 256, "Can't compare value types '%s' and '%s'", Toy_private_getValueTypeAsCString(left.type), Toy_private_getValueTypeAsCString(right.type));
Toy_error(buffer); Toy_error(buffer);
if (TOY_VALUE_IS_REFERENCE(left) != true) {
Toy_freeValue(left); Toy_freeValue(left);
}
if (TOY_VALUE_IS_REFERENCE(right) != true) {
Toy_freeValue(right); Toy_freeValue(right);
}
return; return;
} }
@@ -439,14 +421,9 @@ static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) {
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(false)); Toy_pushStack(&vm->stack, TOY_VALUE_FROM_BOOLEAN(false));
} }
if (TOY_VALUE_IS_REFERENCE(left) != true) {
Toy_freeValue(left); Toy_freeValue(left);
}
if (TOY_VALUE_IS_REFERENCE(right) != true) {
Toy_freeValue(right); Toy_freeValue(right);
} }
}
static void processLogical(Toy_VM* vm, Toy_OpcodeType opcode) { static void processLogical(Toy_VM* vm, Toy_OpcodeType opcode) {
if (opcode == TOY_OPCODE_AND) { if (opcode == TOY_OPCODE_AND) {
@@ -493,29 +470,22 @@ static void processJump(Toy_VM* vm) {
case TOY_OP_PARAM_JUMP_IF_TRUE: { case TOY_OP_PARAM_JUMP_IF_TRUE: {
Toy_Value value = Toy_popStack(&vm->stack); Toy_Value value = Toy_popStack(&vm->stack);
if (Toy_checkValueIsTruthy(value) == true) { if (Toy_checkValueIsTruthy(value) == true) {
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
break; break;
} }
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
return; return;
} }
case TOY_OP_PARAM_JUMP_IF_FALSE: { case TOY_OP_PARAM_JUMP_IF_FALSE: {
Toy_Value value = Toy_popStack(&vm->stack); Toy_Value value = Toy_popStack(&vm->stack);
if (Toy_checkValueIsTruthy(value) != true) { if (Toy_checkValueIsTruthy(value) != true) {
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
break; break;
} }
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
return; return;
} }
} }
@@ -566,14 +536,9 @@ static void processAssert(Toy_VM* vm) {
} }
//cleanup //cleanup
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
if (TOY_VALUE_IS_REFERENCE(message) != true) {
Toy_freeValue(message); Toy_freeValue(message);
} }
}
static void processPrint(Toy_VM* vm) { static void processPrint(Toy_VM* vm) {
//print the value on top of the stack, popping it //print the value on top of the stack, popping it
@@ -585,11 +550,8 @@ static void processPrint(Toy_VM* vm) {
free(buffer); free(buffer);
Toy_freeString(string); Toy_freeString(string);
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
} }
}
static void processConcat(Toy_VM* vm) { static void processConcat(Toy_VM* vm) {
Toy_Value right = Toy_popStack(&vm->stack); Toy_Value right = Toy_popStack(&vm->stack);
@@ -597,13 +559,8 @@ static void processConcat(Toy_VM* vm) {
if (!TOY_VALUE_IS_STRING(left) || !TOY_VALUE_IS_STRING(right)) { if (!TOY_VALUE_IS_STRING(left) || !TOY_VALUE_IS_STRING(right)) {
Toy_error("Failed to concatenate a value that is not a string"); Toy_error("Failed to concatenate a value that is not a string");
if (TOY_VALUE_IS_REFERENCE(left) != true) {
Toy_freeValue(left); Toy_freeValue(left);
}
if (TOY_VALUE_IS_REFERENCE(right) != true) {
Toy_freeValue(right); Toy_freeValue(right);
}
return; return;
} }
@@ -639,29 +596,17 @@ static void processIndex(Toy_VM* vm) {
//type checks //type checks
if (!TOY_VALUE_IS_INTEGER(index)) { if (!TOY_VALUE_IS_INTEGER(index)) {
Toy_error("Failed to index a string"); Toy_error("Failed to index a string");
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
if (TOY_VALUE_IS_REFERENCE(index) != true) {
Toy_freeValue(index); Toy_freeValue(index);
}
if (TOY_VALUE_IS_REFERENCE(length) != true) {
Toy_freeValue(length); Toy_freeValue(length);
}
return; return;
} }
if (!(TOY_VALUE_IS_NULL(length) || TOY_VALUE_IS_INTEGER(length))) { if (!(TOY_VALUE_IS_NULL(length) || TOY_VALUE_IS_INTEGER(length))) {
Toy_error("Failed to index-length a string"); Toy_error("Failed to index-length a string");
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
if (TOY_VALUE_IS_REFERENCE(index) != true) {
Toy_freeValue(index); Toy_freeValue(index);
}
if (TOY_VALUE_IS_REFERENCE(length) != true) {
Toy_freeValue(length); Toy_freeValue(length);
}
return; return;
} }
@@ -673,15 +618,9 @@ static void processIndex(Toy_VM* vm) {
//check indexing is within bounds //check indexing is within bounds
if ( (i < 0 || (unsigned int)i >= str->info.length) || (i+l <= 0 || (unsigned int)(i+l) > str->info.length)) { if ( (i < 0 || (unsigned int)i >= str->info.length) || (i+l <= 0 || (unsigned int)(i+l) > str->info.length)) {
Toy_error("String index is out of bounds"); Toy_error("String index is out of bounds");
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
if (TOY_VALUE_IS_REFERENCE(index) != true) {
Toy_freeValue(index); Toy_freeValue(index);
}
if (TOY_VALUE_IS_REFERENCE(length) != true) {
Toy_freeValue(length); Toy_freeValue(length);
}
return; return;
} }
@@ -711,29 +650,17 @@ static void processIndex(Toy_VM* vm) {
//type checks //type checks
if (!TOY_VALUE_IS_INTEGER(index)) { if (!TOY_VALUE_IS_INTEGER(index)) {
Toy_error("Failed to index a string"); Toy_error("Failed to index a string");
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
if (TOY_VALUE_IS_REFERENCE(index) != true) {
Toy_freeValue(index); Toy_freeValue(index);
}
if (TOY_VALUE_IS_REFERENCE(length) != true) {
Toy_freeValue(length); Toy_freeValue(length);
}
return; return;
} }
if (!(TOY_VALUE_IS_NULL(length) || TOY_VALUE_IS_INTEGER(length))) { if (!(TOY_VALUE_IS_NULL(length) || TOY_VALUE_IS_INTEGER(length))) {
Toy_error("Failed to index-length a string"); Toy_error("Failed to index-length a string");
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
if (TOY_VALUE_IS_REFERENCE(index) != true) {
Toy_freeValue(index); Toy_freeValue(index);
}
if (TOY_VALUE_IS_REFERENCE(length) != true) {
Toy_freeValue(length); Toy_freeValue(length);
}
return; return;
} }
@@ -745,15 +672,9 @@ static void processIndex(Toy_VM* vm) {
//check indexing is within bounds //check indexing is within bounds
if ( (i < 0 || (unsigned int)i >= array->count) || (i+l <= 0 || (unsigned int)(i+l) > array->count)) { if ( (i < 0 || (unsigned int)i >= array->count) || (i+l <= 0 || (unsigned int)(i+l) > array->count)) {
Toy_error("Array index is out of bounds"); Toy_error("Array index is out of bounds");
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
if (TOY_VALUE_IS_REFERENCE(index) != true) {
Toy_freeValue(index); Toy_freeValue(index);
}
if (TOY_VALUE_IS_REFERENCE(length) != true) {
Toy_freeValue(length); Toy_freeValue(length);
}
return; return;
} }
@@ -775,16 +696,10 @@ static void processIndex(Toy_VM* vm) {
exit(-1); exit(-1);
} }
if (TOY_VALUE_IS_REFERENCE(value) != true) {
Toy_freeValue(value); Toy_freeValue(value);
}
if (TOY_VALUE_IS_REFERENCE(index) != true) {
Toy_freeValue(index); Toy_freeValue(index);
}
if (TOY_VALUE_IS_REFERENCE(length) != true) {
Toy_freeValue(length); Toy_freeValue(length);
} }
}
static void process(Toy_VM* vm) { static void process(Toy_VM* vm) {
while(true) { while(true) {