Add lists (MEMORY ERRORS)

This commit is contained in:
2025-12-01 10:15:37 +11:00
parent 0b917a6702
commit 6eeccf58fe
5 changed files with 202 additions and 16 deletions

View File

@@ -30,6 +30,10 @@ void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where
printf("UnknownVariable");
break;
}
case LIST_ERROR: {
printf("ListError");
break;
}
default:
case FIXME: {
printf("FIXME (please report issue to https://chsp.au/ground/cground)");
@@ -86,6 +90,7 @@ void deleteVariable(GroundVariable** head, GroundVariable *item) {
void addVariable(GroundVariable **head, const char *id, GroundValue data) {
GroundVariable* variable = findVariable(*head, id);
if (variable) {
freeGroundValue(&variable->value);
deleteVariable(head, variable);
}
GroundVariable* item = malloc(sizeof(GroundVariable));
@@ -243,9 +248,7 @@ void interpretGroundInstruction(GroundInstruction inst, GroundScope* scope) {
* VARIABLES AND LISTS
* These instructions are for initializing variables and lists.
* Instructions:
* set, gettype, exists
* WIP Instructions:
* setlist, setlistat, getlistat, getlistsize, listappend
* set, gettype, exists, setlist, setlistat, getlistat, getlistsize, listappend
*/
case SET: {
if (in->args.length < 2) {
@@ -333,6 +336,145 @@ void interpretGroundInstruction(GroundInstruction inst, GroundScope* scope) {
break;
}
case SETLIST: {
if (in->args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", in, currentInstruction);
}
if (in->args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", in, currentInstruction);
}
List newList = createList();
for (int 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);
}
appendToList(&newList, in->args.args[i].value.value);
}
addVariable(scope->variables, in->args.args[0].value.refName, createListGroundValue(newList));
break;
}
case SETLISTAT: {
if (in->args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to a List for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != VALUE && in->args.args[1].value.value.type != INT) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int value for arg 2", in, currentInstruction);
}
if (in->args.args[2].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 3", in, currentInstruction);
}
GroundVariable* var = findVariable(*scope->variables, in->args.args[0].value.refName);
if (var == NULL) {
runtimeError(UNKNOWN_VARIABLE, NULL, in, currentInstruction);
}
GroundValue* value = &var->value;
if (value == NULL) {
runtimeError(FIXME, NULL, in, currentInstruction);
}
if (value->type != LIST) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to a List for arg 1", in, currentInstruction);
}
ListAccessStatus status = setListAt(&value->data.listVal, in->args.args[1].value.value.data.intVal, in->args.args[2].value.value);
switch (status) {
case LIST_OKAY:
return;
case LIST_OUT_OF_BOUNDS:
runtimeError(LIST_ERROR, "Out of bounds index", in, currentInstruction);
case LIST_FIXME:
default:
runtimeError(FIXME, "List related error", in, currentInstruction);
}
break;
}
case GETLISTAT: {
if (in->args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to a List for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != VALUE && in->args.args[1].value.value.type != INT) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an integer value for arg 2", in, currentInstruction);
}
if (in->args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to a List for arg 3", in, currentInstruction);
}
GroundVariable* var = findVariable(*scope->variables, in->args.args[0].value.refName);
if (var == NULL) {
runtimeError(UNKNOWN_VARIABLE, NULL, in, currentInstruction);
}
GroundValue* value = &var->value;
if (value == NULL) {
runtimeError(FIXME, NULL, in, currentInstruction);
}
if (value->type != LIST) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to a List for arg 1", in, currentInstruction);
}
ListAccess status = getListAt(&value->data.listVal, in->args.args[1].value.value.data.intVal);
switch (status.status) {
case LIST_OKAY: {
addVariable(scope->variables, in->args.args[2].value.refName, *status.value);
break;
}
case LIST_OUT_OF_BOUNDS:
runtimeError(LIST_ERROR, "Out of bounds index", in, currentInstruction);
case LIST_FIXME:
default:
runtimeError(FIXME, "List related error", in, currentInstruction);
}
break;
}
case GETLISTSIZE: {
if (in->args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to a List for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 2", in, currentInstruction);
}
GroundVariable* var = findVariable(*scope->variables, in->args.args[0].value.refName);
if (var == NULL) {
runtimeError(UNKNOWN_VARIABLE, NULL, in, currentInstruction);
}
GroundValue* value = &var->value;
if (value == NULL) {
runtimeError(FIXME, NULL, in, currentInstruction);
}
if (value->type != LIST) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to a List for arg 1", in, currentInstruction);
}
addVariable(scope->variables, in->args.args[1].value.refName, createIntGroundValue(value->data.listVal.size));
break;
}
case LISTAPPEND: {
if (in->args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to a List for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 2", in, currentInstruction);
}
GroundVariable* var = findVariable(*scope->variables, in->args.args[0].value.refName);
if (var == NULL) {
runtimeError(UNKNOWN_VARIABLE, NULL, in, currentInstruction);
}
GroundValue* value = &var->value;
if (value == NULL) {
runtimeError(FIXME, NULL, in, currentInstruction);
}
if (value->type != LIST) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to a List for arg 1", in, currentInstruction);
}
appendToList(&value->data.listVal, in->args.args[1].value.value);
break;
}
/*
* MATHS