diff --git a/src/types.c b/src/types.c index 017e551..50271aa 100644 --- a/src/types.c +++ b/src/types.c @@ -82,8 +82,16 @@ GroundValue copyGroundValue(const GroundValue* gv) { break; } case FUNCTION: newGv.data.fnVal = gv->data.fnVal; break; + case STRUCTVAL: { + // do this later lmao + // FIXME + newGv.data.structVal = gv->data.structVal; + break; + } case CUSTOM: - newGv.data.customVal = gv->data.customVal; // Shallow copy for custom + // also do this later + // FIXME + newGv.data.customVal = gv->data.customVal; break; } return newGv; @@ -151,6 +159,11 @@ void freeGroundValue(GroundValue* gv) { list->values = NULL; gv->data.listVal = createList(); } + if (gv->type == STRUCTVAL && gv->data.structVal->fields != NULL) { + GroundStruct* gstruct = gv->data.structVal; + freeGroundStruct(gstruct); + free(gstruct); + } } GroundArg createValueGroundArg(GroundValue value) { @@ -445,3 +458,70 @@ ListAccessStatus setListAt(List* list, int idx, GroundValue value) { return LIST_OUT_OF_BOUNDS; } } + +GroundStruct createStruct() { + return (GroundStruct) { + .fields = malloc(sizeof(GroundStructField)), + .size = 0 + }; +} + +void addFieldToStruct(GroundStruct* gstruct, char* name, GroundValue field) { + GroundStructField* tmpPointer = realloc(gstruct->fields, (gstruct->size + 1) * sizeof(GroundStructField)); + if (tmpPointer == NULL) { + printf("Couldn't allocate memory for GroundStruct\n"); + exit(1); + } + gstruct->size++; + gstruct->fields = tmpPointer; + gstruct->fields[gstruct->size - 1].value = field; + strncpy(gstruct->fields[gstruct->size - 1].id, name, sizeof(gstruct->fields->id) - 1); + gstruct->fields[gstruct->size - 1].id[sizeof(gstruct->fields[gstruct->size - 1].id) - 1] = '\0'; +} + +void freeGroundStruct(GroundStruct* gstruct) { + for (size_t i = 0; i < gstruct->size; i++) { + freeGroundValue(&gstruct->fields[i].value); + } +} + +void addFieldToObject(GroundObject* object, const char *id, GroundValue data) { + GroundObjectField* field = malloc(sizeof(GroundObjectField)); + if (field == NULL) { + printf("Couldnt allocate stuff lmao\n"); + exit(1); + } + + strncpy(field->id, id, sizeof(field->id) - 1); + field->id[sizeof(field->id) - 1] = '\0'; + field->value = copyGroundValue(&data); + + HASH_ADD_STR(object->fields, id, field); +} + +GroundObject createObject(GroundStruct gstruct) { + GroundObject object; + object.fields = NULL; + for (size_t i = 0; i < gstruct.size; i++) { + addFieldToObject(&object, gstruct.fields[i].id, gstruct.fields[i].value); + } + + return object; +} + +GroundObjectField* findField(GroundObject head, const char *id) { + GroundObjectField* s; + HASH_FIND_STR(head.fields, id, s); + return s; +} + +void freeGroundObject(GroundObject* object) { + GroundObjectField *current_field, *tmp; + + HASH_ITER(hh, object->fields, current_field, tmp) { + HASH_DEL(object->fields, current_field); + freeGroundValue(¤t_field->value); + free(current_field); + } + object->fields = NULL; +} diff --git a/src/types.h b/src/types.h index 574137a..f5ac32e 100644 --- a/src/types.h +++ b/src/types.h @@ -6,13 +6,14 @@ #include #include #include +#include "include/uthash.h" typedef enum GroundInstType { IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, USE, EXTERN, CREATELABEL, PAUSE, DROP } GroundInstType; typedef enum GroundValueType { - INT, DOUBLE, STRING, CHAR, BOOL, LIST, FUNCTION, CUSTOM, NONE + INT, DOUBLE, STRING, CHAR, BOOL, LIST, FUNCTION, STRUCTVAL, CUSTOM, NONE } GroundValueType; typedef enum GroundArgType { @@ -26,6 +27,8 @@ typedef enum ListAccessStatus { struct GroundValue; struct GroundFunction; struct GroundScope; +struct GroundStruct; +struct GroundObject; struct List; @@ -55,7 +58,8 @@ typedef struct GroundValue { bool boolVal; List listVal; struct GroundFunction* fnVal; - void* customVal; + struct GroundStruct* structVal; + struct GroundObject* customVal; } data; } GroundValue; @@ -129,6 +133,38 @@ typedef struct GroundFunction { NativeGroundFunction nativeFn; } GroundFunction; +/* + * Field for a GroundStruct + */ +typedef struct GroundStructField { + char id[64]; + GroundValue value; + UT_hash_handle hh; +} GroundStructField; + +/* + * Represents a Ground struct. + */ +typedef struct GroundStruct { + GroundStructField* fields; + size_t size; +} GroundStruct; + +/* + * Field for a GroundObject + */ +typedef struct GroundObjectField { + char id[64]; + GroundValue value; + UT_hash_handle hh; +} GroundObjectField; + +/* + * Represents an initialised Ground struct. + */ +typedef struct GroundObject { + GroundObjectField* fields; +} GroundObject; // Creates a GroundValue containing (in), with type INT. GroundValue createIntGroundValue(int64_t in); @@ -203,4 +239,22 @@ ListAccess getListAt(List* list, int idx); // Sets an item in list (list) at index (idx) to GroundValue (value). ListAccessStatus setListAt(List* list, int idx, GroundValue value); +// Creates a Ground struct +GroundStruct createStruct(); + +// Adds a field (field) to Ground struct (gstruct) +void addFieldToStruct(GroundStruct* gstruct, char* name, GroundValue field); + +// Frees a Ground struct +void freeGroundStruct(GroundStruct* gstruct); + +// Creates a Ground object from GroundStruct (gstruct) +GroundObject createObject(GroundStruct gstruct); + +// Finds a field in an object for modification or copying out. +GroundObjectField* findField(GroundObject head, const char *id); + +// Frees a GroundObject +void freeGroundObject(GroundObject* object); + #endif