diff --git a/src/types.c b/src/types.c index 19b1903..826ca86 100644 --- a/src/types.c +++ b/src/types.c @@ -90,16 +90,55 @@ GroundValue copyGroundValue(const GroundValue* gv) { } case FUNCTION: newGv.data.fnVal = gv->data.fnVal; break; case STRUCTVAL: { - // do this later lmao - // FIXME - newGv.data.structVal = gv->data.structVal; + newGv.data.structVal = malloc(sizeof(GroundStruct)); + if (newGv.data.structVal == NULL) { + printf("Couldn't allocate memory for GroundStruct copy\n"); + exit(1); + } + + newGv.data.structVal->size = gv->data.structVal->size; + newGv.data.structVal->fields = malloc(gv->data.structVal->size * sizeof(GroundStructField)); + if (newGv.data.structVal->fields == NULL && gv->data.structVal->size > 0) { + printf("Couldn't allocate memory for GroundStruct fields copy\n"); + exit(1); + } + + for (size_t i = 0; i < gv->data.structVal->size; i++) { + strncpy(newGv.data.structVal->fields[i].id, + gv->data.structVal->fields[i].id, + sizeof(newGv.data.structVal->fields[i].id) - 1); + newGv.data.structVal->fields[i].id[sizeof(newGv.data.structVal->fields[i].id) - 1] = '\0'; + + newGv.data.structVal->fields[i].value = copyGroundValue(&gv->data.structVal->fields[i].value); + } break; } - case CUSTOM: - // also do this later - // FIXME - newGv.data.customVal = gv->data.customVal; + case CUSTOM: { + newGv.customType = gv->customType; + newGv.data.customVal = malloc(sizeof(GroundObject)); + if (newGv.data.customVal == NULL) { + printf("Couldn't allocate memory for GroundObject copy\n"); + exit(1); + } + + newGv.data.customVal->fields = NULL; + + GroundObjectField *field, *tmp; + HASH_ITER(hh, gv->data.customVal->fields, field, tmp) { + GroundObjectField* newField = malloc(sizeof(GroundObjectField)); + if (newField == NULL) { + printf("Couldn't allocate memory for GroundObjectField copy\n"); + exit(1); + } + + strncpy(newField->id, field->id, sizeof(newField->id) - 1); + newField->id[sizeof(newField->id) - 1] = '\0'; + newField->value = copyGroundValue(&field->value); + + HASH_ADD_STR(newGv.data.customVal->fields, id, newField); + } break; + } case NONE: default: {