math library #8

Merged
max merged 4 commits from math-branch into unstable 2026-01-19 20:44:04 +11:00
4 changed files with 387 additions and 48 deletions
Showing only changes of commit fb4ded3f9e - Show all commits

View File

@@ -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,6 +246,186 @@ void groundAddNativeFunction(GroundScope* scope, char* name, NativeGroundFunctio
addVariable(scope->variables, name, createFunctionGroundValue(gf)); addVariable(scope->variables, name, createFunctionGroundValue(gf));
} }
GroundFunction* parseFunction(GroundProgram* in, size_t errorOffset) {
GroundFunction* function = createGroundFunction();
for (size_t i = 0; i < in->size; i++) {
if (in->instructions[i].args.length < 2) {
function->returnType = NONE;
} else {
if (in->instructions[i].args.args[1].type != TYPEREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef for arg 2", &in->instructions[i], errorOffset + i);
}
GroundArg* args = in->instructions[i].args.args;
function->returnType = stringToValueType(args[1].value.refName);
size_t length = in->instructions[i].args.length;
for (size_t j = 2; j < length; j += 2) {
if (args[j].type != TYPEREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef", &in->instructions[i], errorOffset + i);
}
if (j + 1 >= length) {
runtimeError(TOO_FEW_ARGS, "Expecting a DirectRef after a TypeRef", &in->instructions[i], errorOffset + i);
}
if (args[j + 1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef after a TypeRef", &in->instructions[i], errorOffset + i);
}
addArgsToGroundFunction(function, stringToValueType(args[j].value.refName), args[j + 1].value.refName);
}
}
i++;
while (i < in->size) {
addInstructionToProgram(&function->program, in->instructions[i]);
i++;
}
break;
}
return function;
}
GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffset) {
GroundStruct gstruct = createStruct();
for (size_t i = 0; i < in->size; i++) {
switch (in->instructions[i].type) {
case SET: {
if (in->instructions[i].args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", &in->instructions[i], i + errorOffset);
}
if (in->instructions[i].args.length > 2) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", &in->instructions[i], i + errorOffset);
}
if (in->instructions[i].args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", &in->instructions[i], i + errorOffset);
}
if (in->instructions[i].args.args[1].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 2", &in->instructions[i], i + errorOffset);
}
addFieldToStruct(&gstruct, in->instructions[i].args.args[0].value.refName, in->instructions[i].args.args[1].value.value);
break;
}
case INIT: {
if (in->instructions[i].args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", &in->instructions[i], currentInstruction);
}
if (in->instructions[i].args.length > 2) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", &in->instructions[i], currentInstruction);
}
if (in->instructions[i].args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", &in->instructions[i], currentInstruction);
}
if (in->instructions[i].args.args[1].type != TYPEREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef for arg 2", &in->instructions[i], currentInstruction);
}
GroundValue gv;
switch (stringToValueType(in->instructions[i].args.args[0].value.refName)) {
case INT: {
gv = createIntGroundValue(0);
break;
}
case DOUBLE: {
gv = createDoubleGroundValue(0);
break;
}
case STRING: {
gv = createStringGroundValue("");
break;
}
case CHAR: {
gv = createCharGroundValue('\0');
break;
}
case BOOL: {
gv = createBoolGroundValue(false);
break;
}
case LIST: {
gv = createListGroundValue(createList());
break;
}
case FUNCTION: {
gv = createFunctionGroundValue(createGroundFunction());
break;
}
case STRUCTVAL: {
gv.type = STRUCTVAL;
gv.data.structVal = malloc(sizeof(GroundStruct));
*gv.data.structVal = createStruct();
break;
}
case CUSTOM: {
GroundVariable* var = findVariable(*scope->variables, in->instructions[i].args.args[1].value.refName);
if (var == NULL) {
runtimeError(UNKNOWN_VARIABLE, "Couldn't find the specified type", &in->instructions[i], currentInstruction);
}
if (var->value.type != STRUCTVAL) {
runtimeError(ARG_TYPE_MISMATCH, "TypeRef does not reference a struct", &in->instructions[i], currentInstruction);
}
GroundStruct* gstruct = var->value.data.structVal;
gv.type = CUSTOM;
gv.data.customVal = malloc(sizeof(GroundObject));
*gv.data.customVal = createObject(*gstruct);
break;
}
case NONE: {
gv.type = NONE;
break;
}
default: {
runtimeError(FIXME, "Reached should-be-impossible state", &in->instructions[i], currentInstruction);
break;
}
}
addFieldToStruct(&gstruct, in->instructions[i].args.args[0].value.refName, gv);
break;
}
case FUN: {
if (in->instructions[i].args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", &in->instructions[i], i);
}
if (in->instructions[i].args.args[0].type != FNREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a FunctionRef for arg 1", &in->instructions[i], i);
}
char* name = malloc(strlen(in->instructions[i].args.args[0].value.refName) + 1);
strcpy(name, in->instructions[i].args.args[0].value.refName);
size_t counter = 1;
GroundProgram gp = createGroundProgram();
addInstructionToProgram(&gp, in->instructions[i]);
size_t errorOffset = i;
i++;
while (counter > 0) {
if (i >= in->size) {
runtimeError(PREMATURE_EOF, "Reached end of scope before function definition ended", &in->instructions[i - 1], i - 1);
}
if (in->instructions[i].type == FUN) {
counter++;
}
if (in->instructions[i].type == ENDFUN) {
counter--;
}
addInstructionToProgram(&gp, in->instructions[i]);
i++;
}
GroundFunction* function = parseFunction(&gp, errorOffset);
function->startLine = i;
GroundValue gv = createFunctionGroundValue(function);
addFieldToStruct(&gstruct, name, gv);
break;
}
case ENDSTRUCT: {
break;
}
default: {
runtimeError(INVALID_INSTRUCTION, "Unsupported instruction while inside struct", &in->instructions[i], errorOffset + i);
}
}
}
return gstruct;
}
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
GroundLabel* labels = NULL; GroundLabel* labels = NULL;
GroundVariable* variables = NULL; GroundVariable* variables = NULL;
@@ -246,52 +438,87 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
scope.labels = &labels; scope.labels = &labels;
scope.variables = &variables; scope.variables = &variables;
} }
// Preprocess all labels 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);
} }
if (in->instructions[i].type == FUN) { if (in->instructions[i].type == FUN) {
GroundFunction* function = createGroundFunction();
function->startLine = i;
if (in->instructions[i].args.length < 1) { if (in->instructions[i].args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", &in->instructions[i], i); runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", &in->instructions[i], i);
} }
if (in->instructions[i].args.args[0].type != FNREF) { if (in->instructions[i].args.args[0].type != FNREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a FunctionRef for arg 1", &in->instructions[i], i); runtimeError(ARG_TYPE_MISMATCH, "Expecting a FunctionRef for arg 1", &in->instructions[i], i);
} }
char* functionName = in->instructions[i].args.args[0].value.refName; char* name = malloc(strlen(in->instructions[i].args.args[0].value.refName) + 1);
if (in->instructions[i].args.length < 2) { strcpy(name, in->instructions[i].args.args[0].value.refName);
function->returnType = NONE;
} else { size_t counter = 1;
if (in->instructions[i].args.args[1].type != TYPEREF) { GroundProgram gp = createGroundProgram();
runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef for arg 2", &in->instructions[i], i); addInstructionToProgram(&gp, in->instructions[i]);
} size_t errorOffset = i;
GroundArg* args = in->instructions[i].args.args;
function->returnType = stringToValueType(args[1].value.refName);
size_t length = in->instructions[i].args.length;
for (size_t j = 2; j < length; j += 2) {
if (args[j].type != TYPEREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef", &in->instructions[i], i);
}
if (j + 1 >= length) {
runtimeError(TOO_FEW_ARGS, "Expecting a DirectRef after a TypeRef", &in->instructions[i], i);
}
if (args[j + 1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef after a TypeRef", &in->instructions[i], i);
}
addArgsToGroundFunction(function, stringToValueType(args[j].value.refName), args[j + 1].value.refName);
}
}
i++; i++;
while (in->instructions[i].type != ENDFUN) { while (counter > 0) {
addInstructionToProgram(&function->program, in->instructions[i]); if (i >= in->size) {
runtimeError(PREMATURE_EOF, "Reached end of scope before function definition ended", &in->instructions[i - 1], i - 1);
}
if (in->instructions[i].type == FUN) {
counter++;
}
if (in->instructions[i].type == ENDFUN) {
counter--;
}
addInstructionToProgram(&gp, in->instructions[i]);
i++; i++;
} }
addVariable(scope.variables, functionName, createFunctionGroundValue(function));
GroundFunction* function = parseFunction(&gp, errorOffset);
function->startLine = i;
GroundValue gv = createFunctionGroundValue(function);
addVariable(scope.variables, name, gv);
}
if (in->instructions[i].type == STRUCT) {
if (in->instructions[i].args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", &in->instructions[i], i);
}
if (in->instructions[i].args.length > 1) {
runtimeError(TOO_MANY_ARGS, "Expecting 1 arg", &in->instructions[i], i);
}
if (in->instructions[i].args.args[0].type != TYPEREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expected arg 1 to be a typeref", &in->instructions[i], i);
}
char* name = malloc(strlen(in->instructions[i].args.args[0].value.refName) + 1);
strcpy(name, in->instructions[i].args.args[0].value.refName);
i++;
size_t counter = 1;
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);
}
if (in->instructions[i].type == STRUCT) {
counter++;
}
if (in->instructions[i].type == ENDSTRUCT) {
counter--;
}
addInstructionToProgram(&gp, in->instructions[i]);
i++;
}
GroundValue gv = {
.type = STRUCTVAL,
.data.structVal = malloc(sizeof(GroundStruct))
};
*gv.data.structVal = parseStruct(&gp, &scope, errorOffset);
addVariable(scope.variables, name, gv);
} }
} }
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) {
@@ -307,6 +534,21 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
} }
} }
} }
if (in->instructions[i].type == STRUCT) {
int count = 1;
while (count > 0) {
i++;
if (i >= in->size) {
return createNoneGroundValue();
}
if (in->instructions[i].type == STRUCT) {
count++;
}
if (in->instructions[i].type == ENDSTRUCT) {
count--;
}
}
}
if (in->instructions[i].type == PAUSE || instructionsToPause == 0) { if (in->instructions[i].type == PAUSE || instructionsToPause == 0) {
printf("Paused execution\n"); printf("Paused execution\n");
printf("Previous instruction: "); printf("Previous instruction: ");
@@ -428,7 +670,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) {
@@ -441,9 +683,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;
} }
@@ -516,7 +760,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]);
} }
@@ -526,7 +770,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]);
} }
@@ -618,9 +862,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;
} }
} }
@@ -655,7 +905,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);
} }
@@ -1132,7 +1382,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 {
@@ -1628,6 +1878,87 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
break; break;
} }
case INIT: {
if (in->args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.length > 2) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != TYPEREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef for arg 2", in, currentInstruction);
}
GroundValue gv;
switch (stringToValueType(in->args.args[1].value.refName)) {
case INT: {
gv = createIntGroundValue(0);
break;
}
case DOUBLE: {
gv = createDoubleGroundValue(0);
break;
}
case STRING: {
gv = createStringGroundValue("");
break;
}
case CHAR: {
gv = createCharGroundValue('\0');
break;
}
case BOOL: {
gv = createBoolGroundValue(false);
break;
}
case LIST: {
gv = createListGroundValue(createList());
break;
}
case FUNCTION: {
GroundFunction* gf = createGroundFunction();
gf->returnType = NONE;
gv = createFunctionGroundValue(gf);
break;
}
case STRUCTVAL: {
gv.type = STRUCTVAL;
gv.data.structVal = malloc(sizeof(GroundStruct));
*gv.data.structVal = createStruct();
break;
}
case CUSTOM: {
GroundVariable* var = findVariable(*scope->variables, in->args.args[1].value.refName);
if (var == NULL) {
runtimeError(UNKNOWN_VARIABLE, "Couldn't find the specified type", in, currentInstruction);
}
if (var->value.type != STRUCTVAL) {
runtimeError(ARG_TYPE_MISMATCH, "TypeRef does not reference a struct", in, currentInstruction);
}
GroundStruct* gstruct = var->value.data.structVal;
gv.type = CUSTOM;
gv.data.customVal = malloc(sizeof(GroundObject));
*gv.data.customVal = createObject(*gstruct);
break;
}
case NONE: {
gv.type = NONE;
break;
}
default: {
runtimeError(FIXME, "Reached should-be-impossible state", in, currentInstruction);
break;
}
}
addVariable(scope->variables, in->args.args[0].value.refName, gv);
break;
}
case DROP: { case DROP: {
if (in->args.length < 1) { if (in->args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", in, currentInstruction); runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", in, currentInstruction);

View File

@@ -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, 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,8 +36,12 @@ typedef struct GroundDebugInstruction {
char* arg; char* arg;
} GroundDebugInstruction; } GroundDebugInstruction;
GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffset);
GroundFunction* parseFunction(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

View File

@@ -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);

View File

@@ -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();