Added verbose debugging option to the REPL

This commit is contained in:
2024-11-12 11:16:50 +11:00
parent 935993ee8a
commit b74aa63c1c
9 changed files with 74 additions and 44 deletions

View File

@@ -173,7 +173,7 @@ Toy_Value Toy_accessScope(Toy_Scope* scope, Toy_String* key) {
if (entryPtr == NULL) {
char buffer[key->length + 256];
sprintf(buffer, "Undefined variable: %s\n", key->as.name.data); //TODO: Toy_error
sprintf(buffer, "Undefined variable: %s\n", key->as.name.data);
Toy_error(buffer);
return TOY_VALUE_FROM_NULL();
}

View File

@@ -299,3 +299,22 @@ void Toy_stringifyValue(Toy_Value value, Toy_callbackType callback) {
exit(-1);
}
}
const char* Toy_private_getValueTypeAsCString(Toy_ValueType type) {
switch (type) {
case TOY_VALUE_NULL: return "null";
case TOY_VALUE_BOOLEAN: return "bool";
case TOY_VALUE_INTEGER: return "int";
case TOY_VALUE_FLOAT: return "float";
case TOY_VALUE_STRING: return "string";
case TOY_VALUE_ARRAY: return "array";
case TOY_VALUE_TABLE: return "table";
case TOY_VALUE_FUNCTION: return "function";
case TOY_VALUE_OPAQUE: return "opaque";
case TOY_VALUE_TYPE: return "type";
case TOY_VALUE_ANY: return "any";
case TOY_VALUE_UNKNOWN: return "unknown";
}
return NULL;
}

View File

@@ -18,7 +18,7 @@ typedef enum Toy_ValueType {
TOY_VALUE_OPAQUE,
TOY_VALUE_TYPE,
TOY_VALUE_ANY,
TOY_VALUE_UNKNOWN, //The correct value is unknown, but will be determined later
TOY_VALUE_UNKNOWN, //The correct type is unknown, but will be determined later
} Toy_ValueType;
//8 bytes in size
@@ -71,3 +71,6 @@ TOY_API int Toy_compareValues(Toy_Value left, Toy_Value right);
//convert the value to a string, then forward it to a callback
TOY_API void Toy_stringifyValue(Toy_Value value, Toy_callbackType callback);
//for debugging
TOY_API const char* Toy_private_getValueTypeAsCString(Toy_ValueType type);

View File

@@ -213,22 +213,30 @@ 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))) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid types %d and %d passed to processArithmetic, exiting\n" TOY_CC_RESET, left.type, right.type);
exit(-1);
char buffer[256];
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_freeValue(left);
Toy_freeValue(right);
return;
}
//check for divide by zero
if (opcode == TOY_OPCODE_DIVIDE || opcode == TOY_OPCODE_MODULO) {
if ((TOY_VALUE_IS_INTEGER(right) && TOY_VALUE_AS_INTEGER(right) == 0) || (TOY_VALUE_IS_FLOAT(right) && TOY_VALUE_AS_FLOAT(right) == 0)) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't divide by zero, exiting\n" TOY_CC_RESET);
exit(-1);
Toy_error("Can't divide or modulo by zero");
Toy_freeValue(left);
Toy_freeValue(right);
return;
}
}
//check for modulo by a float
if (opcode == TOY_OPCODE_MODULO && TOY_VALUE_IS_FLOAT(right)) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't modulo by a float, exiting\n" TOY_CC_RESET); //TODO: swap these with Toy_error so the repl doens't exit
exit(-1);
Toy_error("Can't modulo by a float");
Toy_freeValue(left);
Toy_freeValue(right);
return;
}
//coerce ints into floats if needed
@@ -293,8 +301,12 @@ static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) {
}
if (Toy_checkValuesAreComparable(left, right) == false) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't compare value types %d and %d\n" TOY_CC_RESET, left.type, right.type); //TODO: typeToCString for error messages
exit(-1);
char buffer[256];
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_freeValue(left);
Toy_freeValue(right);
return;
}
//get the comparison
@@ -470,7 +482,7 @@ static void processIndex(Toy_VM* vm) {
}
else {
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown value type %d found in processIndex, exiting\n" TOY_CC_RESET, value.type);
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown value type '%s' found in processIndex, exiting\n" TOY_CC_RESET, Toy_private_getValueTypeAsCString(value.type));
exit(-1);
}
@@ -481,6 +493,9 @@ static void processIndex(Toy_VM* vm) {
static void process(Toy_VM* vm) {
while(true) {
//prep by aligning to the 4-byte word
fixAlignment(vm);
Toy_OpcodeType opcode = READ_BYTE(vm);
switch(opcode) {
@@ -567,9 +582,6 @@ static void process(Toy_VM* vm) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid opcode %d found, exiting\n" TOY_CC_RESET, opcode);
exit(-1);
}
//prepare for the next instruction
fixAlignment(vm);
}
}

View File

@@ -36,6 +36,8 @@ typedef struct Toy_VM {
//easy access to memory
Toy_Bucket* stringBucket; //stores the string literals
Toy_Bucket* scopeBucket; //stores the scopes
//TODO: panic flag
} Toy_VM;
TOY_API void Toy_initVM(Toy_VM* vm);