diff --git a/src/interpreter.c b/src/interpreter.c index 5e6ac0a..fe76d0c 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -1753,7 +1753,8 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop if (in->args.args[i + 1].type != VALUE) { runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value", in, currentInstruction); } - if (in->args.args[i + 1].value.value.type != function->args[i].type) { + //if (in->args.args[i + 1].value.value.type != function->args[i].type) { + if (!checkFnTypes(&in->args.args[i + 1].value.value, &function->args[i])) { runtimeError(ARG_TYPE_MISMATCH, "Mismatched function argument types", in, currentInstruction); } appendToList(&argsList, in->args.args[i + 1].value.value); @@ -1781,7 +1782,8 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop if (in->args.args[i + 1].type != VALUE) { runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value", in, currentInstruction); } - if (in->args.args[i + 1].value.value.type != function->args[i].type) { + //if (in->args.args[i + 1].value.value.type != function->args[i].type) { + if (!checkFnTypes(&in->args.args[i + 1].value.value, &function->args[i])) { runtimeError(ARG_TYPE_MISMATCH, "Mismatched function argument types", in, currentInstruction); } addVariable(newScope.variables, function->args[i].name, in->args.args[i + 1].value.value); diff --git a/src/types.c b/src/types.c index 01becb4..4a55807 100644 --- a/src/types.c +++ b/src/types.c @@ -582,3 +582,43 @@ GroundError createGroundError(char* what, char* type, GroundInstruction* where, return ge; } + +bool checkFnTypes(GroundValue* left, GroundFunctionArgs* right) { + if (left->type != right->type) { + return false; + } + if (left->type == CUSTOM) { + if (left->customType->size != right->customType->size) { + return false; + } + for (size_t i = 0; i < left->customType->size; i++) { + if (strcmp(left->customType->fields[i].id, right->customType->fields[i].id) != 0) { + return false; + } + if (!checkTypes(&left->customType->fields[i].value, &right->customType->fields[i].value)) { + return false; + } + } + } + return true; +} + +bool checkTypes(GroundValue* left, GroundValue* right) { + if (left->type != right->type) { + return false; + } + if (left->type == CUSTOM) { + if (left->customType->size != right->customType->size) { + return false; + } + for (size_t i = 0; i < left->customType->size; i++) { + if (strcmp(left->customType->fields[i].id, right->customType->fields[i].id) != 0) { + return false; + } + if (!checkTypes(&left->customType->fields[i].value, &right->customType->fields[i].value)) { + return false; + } + } + } + return true; +} diff --git a/src/types.h b/src/types.h index 0b3c903..a24ab32 100644 --- a/src/types.h +++ b/src/types.h @@ -62,6 +62,7 @@ typedef struct GroundError { */ typedef struct GroundValue { GroundValueType type; + struct GroundStruct* customType; union { int64_t intVal; double doubleVal; @@ -125,6 +126,7 @@ typedef struct GroundProgram { */ typedef struct GroundFunctionArgs { GroundValueType type; + struct GroundStruct* customType; char* name; } GroundFunctionArgs; @@ -276,6 +278,11 @@ void freeGroundObject(GroundObject* object); // Creates a GroundError. GroundError createGroundError(char* what, char* type, GroundInstruction* where, size_t* line); +// Compares types of a value and function args. +bool checkFnTypes(GroundValue* left, GroundFunctionArgs* arg); + +// Compares types of two values. +bool checkTypes(GroundValue* left, GroundValue* right); #endif