From fb11e75c2a4e0f9988c3e22c629a014de97c8271 Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Mon, 13 Apr 2026 12:09:49 +1000 Subject: [PATCH] added destructors to List and Hashmap in the collections lib --- libs/collections/hashmap.c | 42 +++++++++++++++++++++++++++----------- libs/collections/list.c | 16 +++++++++++++-- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/libs/collections/hashmap.c b/libs/collections/hashmap.c index eb92c4c..61c7451 100644 --- a/libs/collections/hashmap.c +++ b/libs/collections/hashmap.c @@ -12,9 +12,9 @@ GroundValue hashmapStructSet(GroundScope* scope, List args) { char* key = args.values[0].data.stringVal; GroundValue value = args.values[1]; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; @@ -32,9 +32,9 @@ GroundValue hashmapStructSet(GroundScope* scope, List args) { GroundValue hashmapStructGet(GroundScope* scope, List args) { char* query = args.values[0].data.stringVal; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; @@ -53,9 +53,9 @@ GroundValue hashmapStructGetOr(GroundScope* scope, List args) { char* query = args.values[0].data.stringVal; GroundValue fallback = args.values[1]; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; @@ -72,9 +72,9 @@ GroundValue hashmapStructGetOr(GroundScope* scope, List args) { GroundValue hashmapStructRemove(GroundScope* scope, List args) { char* query = args.values[0].data.stringVal; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; @@ -97,9 +97,9 @@ GroundValue hashmapStructRemove(GroundScope* scope, List args) { GroundValue hashmapStructRemoveIfPresent(GroundScope* scope, List args) { char* query = args.values[0].data.stringVal; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; @@ -125,17 +125,35 @@ GroundValue hashmapStructConstructor(GroundScope* scope, List args) { return value; } +GroundValue destroyHashmapStruct(GroundScope* scope, List args) { + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); + if (ptrField == NULL) { + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); + } + HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; + HashmapItem* current, *temp; + + HASH_ITER(hh, keys, current, temp) { + HASH_DEL(keys, current); + free(current->key); + free(current); + } + + return groundCreateValue(NONE); +} + void initHashmaps(GroundScope* scope) { hashmapStruct = groundCreateStruct(); - groundAddFieldToStruct(&hashmapStruct, "private_ptr", groundCreateValue(INT, 0)); + groundAddFieldToStruct(&hashmapStruct, "ptr", groundCreateValue(INT, 0)); groundAddFunctionToStruct(&hashmapStruct, "set", hashmapStructSet, INT, 2, STRING, "key", ANY, "value"); // set a key in the hashmap groundAddFunctionToStruct(&hashmapStruct, "get", hashmapStructGet, ANY, 1, STRING, "key"); // get a key in the hashmap, throws KeyNotFound if the key does not exist groundAddFunctionToStruct(&hashmapStruct, "getOr", hashmapStructGetOr, ANY, 2, STRING, "key", ANY, "default"); // get a key in the hashmap, or fallback to a default value groundAddFunctionToStruct(&hashmapStruct, "remove", hashmapStructRemove, INT, 1, STRING, "key"); // remove a key from the hashmap, throws KeyNotFound if the key does not exist groundAddFunctionToStruct(&hashmapStruct, "removeIfPresent", hashmapStructRemoveIfPresent, BOOL, 1, STRING, "key"); // remove a key from the hashmap, returns true if the key was removed or false if it didn't exist - + + groundAddFunctionToStruct(&hashmapStruct, "destructor", destroyHashmapStruct, ANY, 0); groundAddNativeFunction(scope, "newHashmap", hashmapStructConstructor, CUSTOM, 0); groundAddNativeFunction(scope, "Hashmap_SOLS_CONSTRUCTOR", hashmapStructConstructor, CUSTOM, 0); } \ No newline at end of file diff --git a/libs/collections/list.c b/libs/collections/list.c index df44717..6fbe4bd 100644 --- a/libs/collections/list.c +++ b/libs/collections/list.c @@ -477,12 +477,22 @@ GroundValue listStructConstructor(GroundScope* scope, List args) { return value; } +GroundValue destroyListStruct(GroundScope* scope, List args) { + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); + if (ptrField == NULL) { + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); + } + + free((GroundValue*)ptrField->value.data.intVal); + return groundCreateValue(NONE); +} + void initLists(GroundScope* scope) { listStruct = groundCreateStruct(); groundAddFieldToStruct(&listStruct, "size", groundCreateValue(INT, 0)); // number of elements groundAddFieldToStruct(&listStruct, "memSize", groundCreateValue(INT, sizeof(GroundValue) * STARTING_ELEMENTS)); // number of bytes allocated groundAddFieldToStruct(&listStruct, "capacity", groundCreateValue(INT, STARTING_ELEMENTS)); // number of elements that can fit in the currently allocated space - groundAddFieldToStruct(&listStruct, "ptr", groundCreateValue(INT, 0)); // pointer to internal list struct + groundAddFieldToStruct(&listStruct, "ptr", groundCreateValue(INT, 0)); // pointer to internal list struct groundAddFunctionToStruct(&listStruct, "init", listStructConstructor, INT, 1, INT, "startingCapacity"); // init struct (ground constructor) groundAddFunctionToStruct(&listStruct, "append", appendToListStruct, INT, 1, ANY, "value"); // append item to end of list @@ -496,7 +506,9 @@ void initLists(GroundScope* scope) { groundAddFunctionToStruct(&listStruct, "reverse", reverseListStruct, INT, 0); // return list struct in reverse order groundAddFunctionToStruct(&listStruct, "find", findListStruct, INT, 1, ANY, "value"); // return index of value in list, if not found, returns -1 groundAddFunctionToStruct(&listStruct, "reserve", reserveListStruct, BOOL, 1, INT, "amount"); // ensure list capacity >= amount. returns true if the list's capacity was expanded - + + + groundAddFunctionToStruct(&listStruct, "destructor", destroyListStruct, ANY,0); groundAddNativeFunction(scope, "newList", listStructConstructor, CUSTOM, 1, INT, "startingCapacity"); groundAddNativeFunction(scope, "List_SOLS_CONSTRUCTOR", listStructConstructor, CUSTOM, 1, INT, "startingCapacity"); } \ No newline at end of file