Add lists (MEMORY ERRORS)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user