diff --git a/src/interpreter.c b/src/interpreter.c index 2548776..e904467 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -11,7 +11,7 @@ int currentInstruction = 0; -void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where, int whereLine) { +[[noreturn]] void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where, int whereLine) { printf("Ground runtime error:\n ErrorType: "); switch (error) { case ARG_TYPE_MISMATCH: { @@ -46,6 +46,18 @@ void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where printf("MathError"); break; } + case RETURN_TYPE_MISMATCH: { + printf("ReturnTypeMismatch"); + break; + } + case PREMATURE_EOF: { + printf("PrematureEof"); + break; + } + case INVALID_INSTRUCTION: { + printf("InvalidInstruction"); + break; + } default: case FIXME: { printf("FIXME (please report issue to https://chsp.au/ground/cground)"); @@ -173,7 +185,7 @@ GroundDebugInstruction parseDebugInstruction(char* in) { } } - if (spacepos == -1) { + if (spacepos == (size_t) -1) { spacepos = insize; } @@ -234,8 +246,25 @@ void groundAddNativeFunction(GroundScope* scope, char* name, NativeGroundFunctio addVariable(scope->variables, name, createFunctionGroundValue(gf)); } -GroundStruct parseStruct(GroundProgram* in) { +GroundStruct parseStruct(GroundProgram* in, size_t errorOffset) { GroundStruct gstruct = createStruct(); + for (size_t i = 0; i < in->size; i++) { + switch (in->instructions[i].type) { + case SET: { + break; + } + case INIT: { + break; + } + case FUN: { + break; + } + default: { + runtimeError(INVALID_INSTRUCTION, "Unsupported instruction while inside struct", &in->instructions[i], errorOffset + i); + } + + } + } return gstruct; } @@ -252,7 +281,7 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { scope.variables = &variables; } // Preprocess all labels, structs and functions - for (int i = 0; i < in->size; i++) { + for (size_t i = 0; i < in->size; i++) { if (in->instructions[i].type == CREATELABEL) { addLabel(scope.labels, in->instructions[i].args.args[0].value.refName, i); } @@ -309,7 +338,8 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { i++; size_t counter = 1; - GroundProgram gp; + GroundProgram gp = createGroundProgram(); + size_t errorOffset = i; while (counter > 0) { if (i >= in->size) { runtimeError(PREMATURE_EOF, "Reached end of scope before struct definition ended", &in->instructions[i - 1], i - 1); @@ -321,12 +351,13 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { counter--; } addInstructionToProgram(&gp, in->instructions[i]); + i++; } - GroundStruct gs = parseStruct(&gp); + GroundStruct gs = parseStruct(&gp, errorOffset); } } - for (int i = 0; i < in->size; i++) { + for (size_t i = 0; i < in->size; i++) { if (in->instructions[i].type == FUN) { int count = 1; while (count > 0) { @@ -463,7 +494,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop GroundInstruction* in = &copied_inst; // Insert variables prefixed with $ - for (int i = 0; i < in->args.length; i++) { + for (size_t i = 0; i < in->args.length; i++) { if (in->args.args[i].type == VALREF) { GroundVariable* variable = findVariable(*scope->variables, in->args.args[i].value.refName); if (variable) { @@ -476,9 +507,11 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop } } switch (in->type) { - // We can safely ignore any CREATELABEL, FUN, and ENDFUN instructions, these have been preprocessed + // We can safely ignore these instructions, as they have been preprocessed case FUN: case ENDFUN: + case STRUCT: + case ENDSTRUCT: case CREATELABEL: { break; } @@ -551,7 +584,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop if (in->args.length < 1) { runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", in, currentInstruction); } - for (int i = 0; i < in->args.length; i++) { + for (size_t i = 0; i < in->args.length; i++) { if (i != 0) printf(" "); printGroundArg(&in->args.args[i]); } @@ -561,7 +594,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop if (in->args.length < 1) { runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", in, currentInstruction); } - for (int i = 0; i < in->args.length; i++) { + for (size_t i = 0; i < in->args.length; i++) { if (i != 0) printf(" "); printGroundArg(&in->args.args[i]); } @@ -653,9 +686,15 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop } case FUNCTION: { addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("function")); + break; + } + case STRUCTVAL: { + addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("struct")); + break; } case NONE: { addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("none")); + break; } } @@ -690,7 +729,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", in, currentInstruction); } List newList = createList(); - for (int i = 1; i < in->args.length; i++) { + for (size_t i = 1; i < in->args.length; i++) { if (in->args.args[i].type != VALUE) { runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for all args after arg 1", in, currentInstruction); } @@ -1167,7 +1206,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", in, currentInstruction); } char* str = in->args.args[0].value.value.data.stringVal; - int64_t idx = in->args.args[1].value.value.data.intVal; + size_t idx = in->args.args[1].value.value.data.intVal; if (idx < strlen(str)) { addVariable(scope->variables, in->args.args[2].value.refName, createCharGroundValue(str[idx])); } else { diff --git a/src/interpreter.h b/src/interpreter.h index fd6f990..83ce97e 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -7,7 +7,7 @@ #include "include/uthash.h" typedef enum GroundRuntimeError { - ARG_TYPE_MISMATCH, TOO_FEW_ARGS, TOO_MANY_ARGS, UNKNOWN_LABEL, UNKNOWN_VARIABLE, LIST_ERROR, STRING_ERROR, MATH_ERROR, RETURN_TYPE_MISMATCH, PREMATURE_EOF, FIXME + ARG_TYPE_MISMATCH, TOO_FEW_ARGS, TOO_MANY_ARGS, UNKNOWN_LABEL, UNKNOWN_VARIABLE, LIST_ERROR, STRING_ERROR, MATH_ERROR, RETURN_TYPE_MISMATCH, PREMATURE_EOF, INVALID_INSTRUCTION, FIXME } GroundRuntimeError; typedef enum GroundDebugInstructionType { @@ -36,9 +36,11 @@ typedef struct GroundDebugInstruction { char* arg; } GroundDebugInstruction; -GroundStruct parseStruct(GroundProgram* in); +GroundStruct parseStruct(GroundProgram* in, size_t errorOffset); GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope); GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scope); + + #endif diff --git a/src/types.c b/src/types.c index 50271aa..d5b294f 100644 --- a/src/types.c +++ b/src/types.c @@ -74,7 +74,7 @@ GroundValue copyGroundValue(const GroundValue* gv) { break; case LIST: { List newList = createList(); - for (int i = 0; i < gv->data.listVal.size; i++) { + for (size_t i = 0; i < gv->data.listVal.size; i++) { // Recursive call to handle nested lists and other types appendToList(&newList, copyGroundValue(&gv->data.listVal.values[i])); } @@ -93,6 +93,10 @@ GroundValue copyGroundValue(const GroundValue* gv) { // FIXME newGv.data.customVal = gv->data.customVal; break; + case NONE: + default: { + + } } return newGv; } @@ -125,7 +129,7 @@ void printGroundValue(GroundValue* gv) { } case LIST: { printf("["); - for (int i = 0; i < gv->data.listVal.size; i++) { + for (size_t i = 0; i < gv->data.listVal.size; i++) { printGroundValue(&gv->data.listVal.values[i]); if (i < gv->data.listVal.size - 1) { printf(", "); @@ -152,7 +156,7 @@ void freeGroundValue(GroundValue* gv) { } if (gv->type == LIST && gv->data.listVal.values != NULL) { List* list = &gv->data.listVal; - for (int i = 0; i < list->size; i++) { + for (size_t i = 0; i < list->size; i++) { freeGroundValue(&list->values[i]); } free(list->values); @@ -394,7 +398,7 @@ void printGroundInstruction(GroundInstruction* gi) { break; } if (gi->type != CREATELABEL) printf(" "); - for (int i = 0; i < gi->args.length; i++) { + for (size_t i = 0; i < gi->args.length; i++) { if (gi->args.args[i].type == VALUE && gi->args.args[i].value.value.type == STRING) { printf("\""); printGroundArg(&gi->args.args[i]); @@ -428,7 +432,7 @@ void appendToList(List* list, GroundValue value) { list->values[list->size - 1] = value; } -ListAccess getListAt(List* list, int idx) { +ListAccess getListAt(List* list, size_t idx) { if (list == NULL) { printf("Expecting a List ptr, got a null pointer instead.\nThis is likely not an error with your Ground program.\nPlease report this issue to https://chsp.au/ground/cground\n"); exit(EXIT_FAILURE); @@ -446,7 +450,7 @@ ListAccess getListAt(List* list, int idx) { } } -ListAccessStatus setListAt(List* list, int idx, GroundValue value) { +ListAccessStatus setListAt(List* list, size_t idx, GroundValue value) { if (list == NULL) { printf("Expecting a List ptr, got a null pointer instead.\nThis is likely not an error with your Ground program.\nPlease report this issue to https://chsp.au/ground/cground\n"); exit(EXIT_FAILURE); diff --git a/src/types.h b/src/types.h index f5ac32e..b1803ee 100644 --- a/src/types.h +++ b/src/types.h @@ -234,10 +234,10 @@ void appendToList(List* list, GroundValue value); // Gets item at index (idx) from list (list). If there is an error, it // will be indicated in the status field. -ListAccess getListAt(List* list, int idx); +ListAccess getListAt(List* list, size_t idx); // Sets an item in list (list) at index (idx) to GroundValue (value). -ListAccessStatus setListAt(List* list, int idx, GroundValue value); +ListAccessStatus setListAt(List* list, size_t idx, GroundValue value); // Creates a Ground struct GroundStruct createStruct();