Compare commits

..

7 Commits

5 changed files with 90 additions and 4 deletions

View File

@@ -13,6 +13,23 @@ int currentInstruction = 0;
bool isMainScopeGlobal = true;
[[noreturn]] void customError(GroundArg type, GroundArg what, GroundInstruction* where, int whereLine, int exitCode) {
printf("Ground runtime error:\n ErrorType: ");
printGroundArg(&type);
printf("\n ErrorContext: ");
printGroundArg(&what);
printf("\n");
if (where != NULL) {
printf(" ErrorInstruction: ");
printGroundInstruction(where);
printf("\n");
}
if (whereLine > -1) {
printf(" ErrorLine: %d\n", whereLine + 1);
}
exit(exitCode);
}
[[noreturn]] void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where, int whereLine) {
printf("Ground runtime error:\n ErrorType: ");
switch (error) {
@@ -382,6 +399,7 @@ GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffs
gv.type = CUSTOM;
gv.data.customVal = malloc(sizeof(GroundObject));
*gv.data.customVal = createObject(*gstruct);
gv.customType = gstruct;
break;
}
case NONE: {
@@ -813,7 +831,19 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
}
break;
}
case ERRORCMD: {
if (in->args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);
} else if (in->args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.args[2].value.value.type != INT ) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an int for arg 2", in, currentInstruction);
}
customError(in->args.args[0], in->args.args[1], in, currentInstruction, in->args.args[2].value.value.data.intVal);
break;
}
/*
* VARIABLES AND LISTS
* These instructions are for initializing variables and lists.
@@ -1753,7 +1783,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 +1812,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);
@@ -1979,6 +2011,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
gv.type = CUSTOM;
gv.data.customVal = malloc(sizeof(GroundObject));
*gv.data.customVal = createObject(*gstruct);
gv.customType = gstruct;
break;
}
case NONE: {

View File

@@ -137,6 +137,7 @@ static GroundInstType getInstructionType(const char* inst) {
if (strcmp(inst, "input") == 0 || strcmp(inst, "stdin") == 0) return INPUT;
if (strcmp(inst, "print") == 0 || strcmp(inst, "stdout") == 0) return PRINT;
if (strcmp(inst, "println") == 0 || strcmp(inst, "stdlnout") == 0) return PRINTLN;
if (strcmp(inst, "error") == 0) return ERRORCMD;
if (strcmp(inst, "set") == 0) return SET;
if (strcmp(inst, "gettype") == 0) return GETTYPE;
if (strcmp(inst, "exists") == 0) return EXISTS;

View File

@@ -412,6 +412,9 @@ void printGroundInstruction(GroundInstruction* gi) {
break;
case CREATELABEL:
break;
case ERRORCMD:
printf("error");
break;
default:
printf("FIXME");
break;
@@ -582,3 +585,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;
}

View File

@@ -9,7 +9,7 @@
#include "include/uthash.h"
typedef enum GroundInstType {
IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, USE, EXTERN, CREATELABEL, PAUSE, DROP
IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD
} GroundInstType;
typedef enum GroundValueType {
@@ -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

2
tests/error.grnd Normal file
View File

@@ -0,0 +1,2 @@
setlist &dat 1 2 3 "Hi!"
error "Hello" $dat 1