#include "hashmap.h" #include #include #include #include #include #include GroundValue hashmapStructSet(GroundScope* scope, List args) { char* key = args.values[0].data.stringVal; GroundValue value = args.values[1]; GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); if (ptrField == NULL) { ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; HashmapItem* newItem = malloc(sizeof(HashmapItem)); newItem->key = strdup(key); newItem->value = value; HASH_ADD_KEYPTR(hh, keys, newItem->key, strlen(newItem->key), newItem); ptrField->value.data.intVal = (long long)keys; return groundCreateValue(INT, 0); } GroundValue hashmapStructGet(GroundScope* scope, List args) { char* query = args.values[0].data.stringVal; GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); if (ptrField == NULL) { ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; HashmapItem* out; HASH_FIND_STR(keys, query, out); if (out == NULL) { ERROR("Key was not found in hashmap (tip: use hashmap.getOr if you want to specify a fallback value)", "KeyNotFound"); } return out->value; } GroundValue hashmapStructGetOr(GroundScope* scope, List args) { char* query = args.values[0].data.stringVal; GroundValue fallback = args.values[1]; GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); if (ptrField == NULL) { ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; HashmapItem* out; HASH_FIND_STR(keys, query, out); if (out == NULL) return fallback; return out->value; } GroundValue hashmapStructRemove(GroundScope* scope, List args) { char* query = args.values[0].data.stringVal; GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); if (ptrField == NULL) { ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; HashmapItem* out; HASH_FIND_STR(keys, query, out); if (out == NULL) { ERROR("Key was not found in hashmap (tip: use hashmap.removeIfPresent if you want to avoid errors)", "KeyNotFound"); } HASH_DEL(keys, out); free(out->key); free(out); return groundCreateValue(INT, 0); } GroundValue hashmapStructRemoveIfPresent(GroundScope* scope, List args) { char* query = args.values[0].data.stringVal; GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); if (ptrField == NULL) { ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); } HashmapItem* keys = (HashmapItem*)ptrField->value.data.intVal; HashmapItem* out; HASH_FIND_STR(keys, query, out); if (out == NULL) { return groundCreateValue(BOOL, false); } HASH_DEL(keys, out); free(out->key); free(out); return groundCreateValue(BOOL, true); } GroundValue createHashmapStruct() { GroundStruct hashmapStruct = groundCreateStruct(); groundAddFieldToStruct(&hashmapStruct, "private_ptr", groundCreateValue(INT, 0)); groundAddFunctionToStruct(&hashmapStruct, "set", hashmapStructSet, INT, 2, STRING, "key", ANY, "value"); // set a key in the hashmap groundAddFunctionToStruct(&hashmapStruct, "get", hashmapStructGet, INT, 1, STRING, "key"); // get a key in the hashmap, throws KeyNotFound if the key does not exist groundAddFunctionToStruct(&hashmapStruct, "getOr", hashmapStructGetOr, INT, 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 return groundCreateValue(STRUCTVAL, hashmapStruct); }