Further struct work, fix lots of warnings
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
int currentInstruction = 0;
|
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: ");
|
printf("Ground runtime error:\n ErrorType: ");
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case ARG_TYPE_MISMATCH: {
|
case ARG_TYPE_MISMATCH: {
|
||||||
@@ -46,6 +46,18 @@ void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where
|
|||||||
printf("MathError");
|
printf("MathError");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case RETURN_TYPE_MISMATCH: {
|
||||||
|
printf("ReturnTypeMismatch");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PREMATURE_EOF: {
|
||||||
|
printf("PrematureEof");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INVALID_INSTRUCTION: {
|
||||||
|
printf("InvalidInstruction");
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
case FIXME: {
|
case FIXME: {
|
||||||
printf("FIXME (please report issue to https://chsp.au/ground/cground)");
|
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;
|
spacepos = insize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,8 +246,25 @@ void groundAddNativeFunction(GroundScope* scope, char* name, NativeGroundFunctio
|
|||||||
addVariable(scope->variables, name, createFunctionGroundValue(gf));
|
addVariable(scope->variables, name, createFunctionGroundValue(gf));
|
||||||
}
|
}
|
||||||
|
|
||||||
GroundStruct parseStruct(GroundProgram* in) {
|
GroundStruct parseStruct(GroundProgram* in, size_t errorOffset) {
|
||||||
GroundStruct gstruct = createStruct();
|
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;
|
return gstruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +281,7 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
|||||||
scope.variables = &variables;
|
scope.variables = &variables;
|
||||||
}
|
}
|
||||||
// Preprocess all labels, structs and functions
|
// 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) {
|
if (in->instructions[i].type == CREATELABEL) {
|
||||||
addLabel(scope.labels, in->instructions[i].args.args[0].value.refName, i);
|
addLabel(scope.labels, in->instructions[i].args.args[0].value.refName, i);
|
||||||
}
|
}
|
||||||
@@ -309,7 +338,8 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
|||||||
i++;
|
i++;
|
||||||
|
|
||||||
size_t counter = 1;
|
size_t counter = 1;
|
||||||
GroundProgram gp;
|
GroundProgram gp = createGroundProgram();
|
||||||
|
size_t errorOffset = i;
|
||||||
while (counter > 0) {
|
while (counter > 0) {
|
||||||
if (i >= in->size) {
|
if (i >= in->size) {
|
||||||
runtimeError(PREMATURE_EOF, "Reached end of scope before struct definition ended", &in->instructions[i - 1], i - 1);
|
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--;
|
counter--;
|
||||||
}
|
}
|
||||||
addInstructionToProgram(&gp, in->instructions[i]);
|
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) {
|
if (in->instructions[i].type == FUN) {
|
||||||
int count = 1;
|
int count = 1;
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
@@ -463,7 +494,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
GroundInstruction* in = &copied_inst;
|
GroundInstruction* in = &copied_inst;
|
||||||
|
|
||||||
// Insert variables prefixed with $
|
// 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) {
|
if (in->args.args[i].type == VALREF) {
|
||||||
GroundVariable* variable = findVariable(*scope->variables, in->args.args[i].value.refName);
|
GroundVariable* variable = findVariable(*scope->variables, in->args.args[i].value.refName);
|
||||||
if (variable) {
|
if (variable) {
|
||||||
@@ -476,9 +507,11 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (in->type) {
|
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 FUN:
|
||||||
case ENDFUN:
|
case ENDFUN:
|
||||||
|
case STRUCT:
|
||||||
|
case ENDSTRUCT:
|
||||||
case CREATELABEL: {
|
case CREATELABEL: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -551,7 +584,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
if (in->args.length < 1) {
|
if (in->args.length < 1) {
|
||||||
runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", in, currentInstruction);
|
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(" ");
|
if (i != 0) printf(" ");
|
||||||
printGroundArg(&in->args.args[i]);
|
printGroundArg(&in->args.args[i]);
|
||||||
}
|
}
|
||||||
@@ -561,7 +594,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
if (in->args.length < 1) {
|
if (in->args.length < 1) {
|
||||||
runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", in, currentInstruction);
|
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(" ");
|
if (i != 0) printf(" ");
|
||||||
printGroundArg(&in->args.args[i]);
|
printGroundArg(&in->args.args[i]);
|
||||||
}
|
}
|
||||||
@@ -653,9 +686,15 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
}
|
}
|
||||||
case FUNCTION: {
|
case FUNCTION: {
|
||||||
addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("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: {
|
case NONE: {
|
||||||
addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("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);
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", in, currentInstruction);
|
||||||
}
|
}
|
||||||
List newList = createList();
|
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) {
|
if (in->args.args[i].type != VALUE) {
|
||||||
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for all args after arg 1", in, currentInstruction);
|
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);
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", in, currentInstruction);
|
||||||
}
|
}
|
||||||
char* str = in->args.args[0].value.value.data.stringVal;
|
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)) {
|
if (idx < strlen(str)) {
|
||||||
addVariable(scope->variables, in->args.args[2].value.refName, createCharGroundValue(str[idx]));
|
addVariable(scope->variables, in->args.args[2].value.refName, createCharGroundValue(str[idx]));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "include/uthash.h"
|
#include "include/uthash.h"
|
||||||
|
|
||||||
typedef enum GroundRuntimeError {
|
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;
|
} GroundRuntimeError;
|
||||||
|
|
||||||
typedef enum GroundDebugInstructionType {
|
typedef enum GroundDebugInstructionType {
|
||||||
@@ -36,9 +36,11 @@ typedef struct GroundDebugInstruction {
|
|||||||
char* arg;
|
char* arg;
|
||||||
} GroundDebugInstruction;
|
} GroundDebugInstruction;
|
||||||
|
|
||||||
GroundStruct parseStruct(GroundProgram* in);
|
GroundStruct parseStruct(GroundProgram* in, size_t errorOffset);
|
||||||
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope);
|
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope);
|
||||||
GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scope);
|
GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scope);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
16
src/types.c
16
src/types.c
@@ -74,7 +74,7 @@ GroundValue copyGroundValue(const GroundValue* gv) {
|
|||||||
break;
|
break;
|
||||||
case LIST: {
|
case LIST: {
|
||||||
List newList = createList();
|
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
|
// Recursive call to handle nested lists and other types
|
||||||
appendToList(&newList, copyGroundValue(&gv->data.listVal.values[i]));
|
appendToList(&newList, copyGroundValue(&gv->data.listVal.values[i]));
|
||||||
}
|
}
|
||||||
@@ -93,6 +93,10 @@ GroundValue copyGroundValue(const GroundValue* gv) {
|
|||||||
// FIXME
|
// FIXME
|
||||||
newGv.data.customVal = gv->data.customVal;
|
newGv.data.customVal = gv->data.customVal;
|
||||||
break;
|
break;
|
||||||
|
case NONE:
|
||||||
|
default: {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return newGv;
|
return newGv;
|
||||||
}
|
}
|
||||||
@@ -125,7 +129,7 @@ void printGroundValue(GroundValue* gv) {
|
|||||||
}
|
}
|
||||||
case LIST: {
|
case LIST: {
|
||||||
printf("[");
|
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]);
|
printGroundValue(&gv->data.listVal.values[i]);
|
||||||
if (i < gv->data.listVal.size - 1) {
|
if (i < gv->data.listVal.size - 1) {
|
||||||
printf(", ");
|
printf(", ");
|
||||||
@@ -152,7 +156,7 @@ void freeGroundValue(GroundValue* gv) {
|
|||||||
}
|
}
|
||||||
if (gv->type == LIST && gv->data.listVal.values != NULL) {
|
if (gv->type == LIST && gv->data.listVal.values != NULL) {
|
||||||
List* list = &gv->data.listVal;
|
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]);
|
freeGroundValue(&list->values[i]);
|
||||||
}
|
}
|
||||||
free(list->values);
|
free(list->values);
|
||||||
@@ -394,7 +398,7 @@ void printGroundInstruction(GroundInstruction* gi) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (gi->type != CREATELABEL) printf(" ");
|
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) {
|
if (gi->args.args[i].type == VALUE && gi->args.args[i].value.value.type == STRING) {
|
||||||
printf("\"");
|
printf("\"");
|
||||||
printGroundArg(&gi->args.args[i]);
|
printGroundArg(&gi->args.args[i]);
|
||||||
@@ -428,7 +432,7 @@ void appendToList(List* list, GroundValue value) {
|
|||||||
list->values[list->size - 1] = value;
|
list->values[list->size - 1] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListAccess getListAt(List* list, int idx) {
|
ListAccess getListAt(List* list, size_t idx) {
|
||||||
if (list == NULL) {
|
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");
|
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);
|
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) {
|
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");
|
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);
|
exit(EXIT_FAILURE);
|
||||||
|
|||||||
@@ -234,10 +234,10 @@ void appendToList(List* list, GroundValue value);
|
|||||||
|
|
||||||
// Gets item at index (idx) from list (list). If there is an error, it
|
// Gets item at index (idx) from list (list). If there is an error, it
|
||||||
// will be indicated in the status field.
|
// 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).
|
// 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
|
// Creates a Ground struct
|
||||||
GroundStruct createStruct();
|
GroundStruct createStruct();
|
||||||
|
|||||||
Reference in New Issue
Block a user