chore: remove trailing whitespace from README.md line 42

This commit is contained in:
2025-12-04 15:49:20 +00:00
parent ed69521892
commit ce7624e693
13 changed files with 1046 additions and 18 deletions
+401 -1
View File
@@ -1661,6 +1661,156 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
break;
}
case RAVA_OP_ARRAYLIST_NEW: {
RavaArrayList_t *list = rava_arraylist_create();
rava_stack_push(stack, rava_value_arraylist(list));
break;
}
case RAVA_OP_ARRAYLIST_ADD: {
RavaValue_t value = rava_stack_pop(stack);
RavaValue_t list_val = rava_stack_pop(stack);
if (list_val.type == RAVA_VAL_ARRAYLIST) {
rava_arraylist_add(list_val.data.arraylist_val, value);
}
break;
}
case RAVA_OP_ARRAYLIST_GET: {
RavaValue_t index_or_key = rava_stack_pop(stack);
RavaValue_t coll_val = rava_stack_pop(stack);
if (coll_val.type == RAVA_VAL_ARRAYLIST) {
rava_stack_push(stack, rava_arraylist_get(coll_val.data.arraylist_val, (size_t)rava_value_as_int(index_or_key)));
} else if (coll_val.type == RAVA_VAL_HASHMAP && index_or_key.type == RAVA_VAL_STRING) {
rava_stack_push(stack, rava_hashmap_get(coll_val.data.hashmap_val, index_or_key.data.string_val));
} else {
rava_stack_push(stack, rava_value_null());
}
break;
}
case RAVA_OP_ARRAYLIST_SET: {
RavaValue_t value = rava_stack_pop(stack);
RavaValue_t index = rava_stack_pop(stack);
RavaValue_t list_val = rava_stack_pop(stack);
if (list_val.type == RAVA_VAL_ARRAYLIST) {
rava_arraylist_set(list_val.data.arraylist_val, (size_t)rava_value_as_int(index), value);
}
break;
}
case RAVA_OP_ARRAYLIST_SIZE: {
RavaValue_t coll_val = rava_stack_pop(stack);
if (coll_val.type == RAVA_VAL_ARRAYLIST) {
rava_stack_push(stack, rava_value_int((int32_t)rava_arraylist_size(coll_val.data.arraylist_val)));
} else if (coll_val.type == RAVA_VAL_HASHMAP) {
rava_stack_push(stack, rava_value_int((int32_t)rava_hashmap_size(coll_val.data.hashmap_val)));
} else {
rava_stack_push(stack, rava_value_int(0));
}
break;
}
case RAVA_OP_ARRAYLIST_REMOVE: {
RavaValue_t index_or_key = rava_stack_pop(stack);
RavaValue_t coll_val = rava_stack_pop(stack);
if (coll_val.type == RAVA_VAL_ARRAYLIST) {
rava_stack_push(stack, rava_arraylist_remove(coll_val.data.arraylist_val, (size_t)rava_value_as_int(index_or_key)));
} else if (coll_val.type == RAVA_VAL_HASHMAP && index_or_key.type == RAVA_VAL_STRING) {
rava_stack_push(stack, rava_hashmap_remove(coll_val.data.hashmap_val, index_or_key.data.string_val));
} else {
rava_stack_push(stack, rava_value_null());
}
break;
}
case RAVA_OP_ARRAYLIST_CLEAR: {
RavaValue_t coll_val = rava_stack_pop(stack);
if (coll_val.type == RAVA_VAL_ARRAYLIST) {
rava_arraylist_clear(coll_val.data.arraylist_val);
} else if (coll_val.type == RAVA_VAL_HASHMAP) {
rava_hashmap_clear(coll_val.data.hashmap_val);
}
break;
}
case RAVA_OP_ARRAYLIST_ISEMPTY: {
RavaValue_t list_val = rava_stack_pop(stack);
if (list_val.type == RAVA_VAL_ARRAYLIST) {
rava_stack_push(stack, rava_value_boolean(rava_arraylist_isempty(list_val.data.arraylist_val)));
} else {
rava_stack_push(stack, rava_value_boolean(true));
}
break;
}
case RAVA_OP_HASHMAP_NEW: {
RavaHashMap_t *map = rava_hashmap_create();
rava_stack_push(stack, rava_value_hashmap(map));
break;
}
case RAVA_OP_HASHMAP_PUT: {
RavaValue_t value = rava_stack_pop(stack);
RavaValue_t key_val = rava_stack_pop(stack);
RavaValue_t map_val = rava_stack_pop(stack);
if (map_val.type == RAVA_VAL_HASHMAP && key_val.type == RAVA_VAL_STRING) {
rava_hashmap_put(map_val.data.hashmap_val, key_val.data.string_val, value);
}
break;
}
case RAVA_OP_HASHMAP_GET: {
RavaValue_t key_val = rava_stack_pop(stack);
RavaValue_t map_val = rava_stack_pop(stack);
if (map_val.type == RAVA_VAL_HASHMAP && key_val.type == RAVA_VAL_STRING) {
rava_stack_push(stack, rava_hashmap_get(map_val.data.hashmap_val, key_val.data.string_val));
} else {
rava_stack_push(stack, rava_value_null());
}
break;
}
case RAVA_OP_HASHMAP_REMOVE: {
RavaValue_t key_val = rava_stack_pop(stack);
RavaValue_t map_val = rava_stack_pop(stack);
if (map_val.type == RAVA_VAL_HASHMAP && key_val.type == RAVA_VAL_STRING) {
rava_stack_push(stack, rava_hashmap_remove(map_val.data.hashmap_val, key_val.data.string_val));
} else {
rava_stack_push(stack, rava_value_null());
}
break;
}
case RAVA_OP_HASHMAP_SIZE: {
RavaValue_t map_val = rava_stack_pop(stack);
if (map_val.type == RAVA_VAL_HASHMAP) {
rava_stack_push(stack, rava_value_int((int32_t)rava_hashmap_size(map_val.data.hashmap_val)));
} else {
rava_stack_push(stack, rava_value_int(0));
}
break;
}
case RAVA_OP_HASHMAP_CONTAINSKEY: {
RavaValue_t key_val = rava_stack_pop(stack);
RavaValue_t map_val = rava_stack_pop(stack);
if (map_val.type == RAVA_VAL_HASHMAP && key_val.type == RAVA_VAL_STRING) {
rava_stack_push(stack, rava_value_boolean(rava_hashmap_containskey(map_val.data.hashmap_val, key_val.data.string_val)));
} else {
rava_stack_push(stack, rava_value_boolean(false));
}
break;
}
case RAVA_OP_HASHMAP_CLEAR: {
RavaValue_t map_val = rava_stack_pop(stack);
if (map_val.type == RAVA_VAL_HASHMAP) {
rava_hashmap_clear(map_val.data.hashmap_val);
}
break;
}
case RAVA_OP_CAST: {
RavaValue_t val = rava_stack_pop(stack);
RavaType_t *target_type = instr->operand.var.type;
@@ -3090,7 +3240,11 @@ static bool _rava_vm_execute_ultrafast(RavaVM_t *vm, RavaMethod_t *entry_method)
&&uf_math_abs, &&uf_math_sqrt, &&uf_math_pow, &&uf_math_min, &&uf_math_max,
&&uf_math_floor, &&uf_math_ceil, &&uf_math_round,
&&uf_math_sin, &&uf_math_cos, &&uf_math_tan, &&uf_math_log, &&uf_math_exp,
&&uf_math_random
&&uf_math_random,
&&uf_arraylist_new, &&uf_arraylist_add, &&uf_arraylist_get, &&uf_arraylist_set,
&&uf_arraylist_size, &&uf_arraylist_remove, &&uf_arraylist_clear, &&uf_arraylist_isempty,
&&uf_hashmap_new, &&uf_hashmap_put, &&uf_hashmap_get, &&uf_hashmap_remove,
&&uf_hashmap_size, &&uf_hashmap_containskey, &&uf_hashmap_clear
};
rava_fastframe_reset();
@@ -4248,6 +4402,252 @@ uf_math_random: {
UF_DISPATCH();
}
uf_arraylist_new: {
RavaArrayList_t *list = rava_arraylist_create();
UF_PUSH(rava_nanbox_object(list));
UF_DISPATCH();
}
uf_arraylist_add: {
RavaNanboxValue_t val = UF_POP();
RavaNanboxValue_t list_nb = UF_POP();
RavaArrayList_t *list = (RavaArrayList_t*)rava_nanbox_as_object(list_nb);
if (list) {
RavaValue_t v;
if (rava_nanbox_is_int(val)) {
v = rava_value_int(rava_nanbox_to_int(val));
} else if (rava_nanbox_is_double(val)) {
v = rava_value_double(rava_nanbox_to_double(val));
} else {
v = rava_value_null();
}
rava_arraylist_add(list, v);
}
UF_DISPATCH();
}
uf_arraylist_get: {
RavaNanboxValue_t idx_nb = UF_POP();
RavaNanboxValue_t coll_nb = UF_POP();
void *ptr = rava_nanbox_as_object(coll_nb);
if (rava_nanbox_is_int(idx_nb)) {
RavaArrayList_t *list = (RavaArrayList_t*)ptr;
if (list) {
RavaValue_t v = rava_arraylist_get(list, (size_t)rava_nanbox_to_int(idx_nb));
if (v.type == RAVA_VAL_INT) {
UF_PUSH(rava_nanbox_int(v.data.int_val));
} else if (v.type == RAVA_VAL_DOUBLE) {
UF_PUSH(rava_nanbox_double(v.data.double_val));
} else {
UF_PUSH(rava_nanbox_null());
}
} else {
UF_PUSH(rava_nanbox_null());
}
} else if (rava_nanbox_is_string(idx_nb)) {
RavaHashMap_t *map = (RavaHashMap_t*)ptr;
if (map) {
RavaValue_t v = rava_hashmap_get(map, rava_nanbox_as_string(idx_nb));
if (v.type == RAVA_VAL_INT) {
UF_PUSH(rava_nanbox_int(v.data.int_val));
} else if (v.type == RAVA_VAL_DOUBLE) {
UF_PUSH(rava_nanbox_double(v.data.double_val));
} else {
UF_PUSH(rava_nanbox_null());
}
} else {
UF_PUSH(rava_nanbox_null());
}
} else {
UF_PUSH(rava_nanbox_null());
}
UF_DISPATCH();
}
uf_arraylist_set: {
RavaNanboxValue_t val = UF_POP();
RavaNanboxValue_t idx_nb = UF_POP();
RavaNanboxValue_t list_nb = UF_POP();
RavaArrayList_t *list = (RavaArrayList_t*)rava_nanbox_as_object(list_nb);
if (list) {
RavaValue_t v;
if (rava_nanbox_is_int(val)) {
v = rava_value_int(rava_nanbox_to_int(val));
} else if (rava_nanbox_is_double(val)) {
v = rava_value_double(rava_nanbox_to_double(val));
} else {
v = rava_value_null();
}
rava_arraylist_set(list, (size_t)rava_nanbox_to_int(idx_nb), v);
}
UF_DISPATCH();
}
uf_arraylist_size: {
RavaNanboxValue_t coll_nb = UF_POP();
void *ptr = rava_nanbox_as_object(coll_nb);
if (ptr) {
int type = *(int*)ptr;
if (type == RAVA_COLLECTION_ARRAYLIST) {
UF_PUSH(rava_nanbox_int((int32_t)rava_arraylist_size((RavaArrayList_t*)ptr)));
} else if (type == RAVA_COLLECTION_HASHMAP) {
UF_PUSH(rava_nanbox_int((int32_t)rava_hashmap_size((RavaHashMap_t*)ptr)));
} else {
UF_PUSH(rava_nanbox_int(0));
}
} else {
UF_PUSH(rava_nanbox_int(0));
}
UF_DISPATCH();
}
uf_arraylist_remove: {
RavaNanboxValue_t idx_or_key = UF_POP();
RavaNanboxValue_t coll_nb = UF_POP();
void *ptr = rava_nanbox_as_object(coll_nb);
if (ptr) {
int type = *(int*)ptr;
if (type == RAVA_COLLECTION_ARRAYLIST && rava_nanbox_is_int(idx_or_key)) {
RavaValue_t v = rava_arraylist_remove((RavaArrayList_t*)ptr, (size_t)rava_nanbox_to_int(idx_or_key));
if (v.type == RAVA_VAL_INT) {
UF_PUSH(rava_nanbox_int(v.data.int_val));
} else {
UF_PUSH(rava_nanbox_null());
}
} else if (type == RAVA_COLLECTION_HASHMAP && rava_nanbox_is_string(idx_or_key)) {
RavaValue_t v = rava_hashmap_remove((RavaHashMap_t*)ptr, rava_nanbox_as_string(idx_or_key));
if (v.type == RAVA_VAL_INT) {
UF_PUSH(rava_nanbox_int(v.data.int_val));
} else {
UF_PUSH(rava_nanbox_null());
}
} else {
UF_PUSH(rava_nanbox_null());
}
} else {
UF_PUSH(rava_nanbox_null());
}
UF_DISPATCH();
}
uf_arraylist_clear: {
RavaNanboxValue_t coll_nb = UF_POP();
void *ptr = rava_nanbox_as_object(coll_nb);
if (ptr) {
int type = *(int*)ptr;
if (type == RAVA_COLLECTION_ARRAYLIST) {
rava_arraylist_clear((RavaArrayList_t*)ptr);
} else if (type == RAVA_COLLECTION_HASHMAP) {
rava_hashmap_clear((RavaHashMap_t*)ptr);
}
}
UF_DISPATCH();
}
uf_arraylist_isempty: {
RavaNanboxValue_t list_nb = UF_POP();
RavaArrayList_t *list = (RavaArrayList_t*)rava_nanbox_as_object(list_nb);
if (list) {
UF_PUSH(rava_nanbox_int(rava_arraylist_isempty(list) ? 1 : 0));
} else {
UF_PUSH(rava_nanbox_int(1));
}
UF_DISPATCH();
}
uf_hashmap_new: {
RavaHashMap_t *map = rava_hashmap_create();
UF_PUSH(rava_nanbox_object(map));
UF_DISPATCH();
}
uf_hashmap_put: {
RavaNanboxValue_t val = UF_POP();
RavaNanboxValue_t key_nb = UF_POP();
RavaNanboxValue_t map_nb = UF_POP();
RavaHashMap_t *map = (RavaHashMap_t*)rava_nanbox_as_object(map_nb);
if (map && rava_nanbox_is_string(key_nb)) {
RavaValue_t v;
if (rava_nanbox_is_int(val)) {
v = rava_value_int(rava_nanbox_to_int(val));
} else if (rava_nanbox_is_double(val)) {
v = rava_value_double(rava_nanbox_to_double(val));
} else {
v = rava_value_null();
}
rava_hashmap_put(map, rava_nanbox_as_string(key_nb), v);
}
UF_DISPATCH();
}
uf_hashmap_get: {
RavaNanboxValue_t key_nb = UF_POP();
RavaNanboxValue_t map_nb = UF_POP();
RavaHashMap_t *map = (RavaHashMap_t*)rava_nanbox_as_object(map_nb);
if (map && rava_nanbox_is_string(key_nb)) {
RavaValue_t v = rava_hashmap_get(map, rava_nanbox_as_string(key_nb));
if (v.type == RAVA_VAL_INT) {
UF_PUSH(rava_nanbox_int(v.data.int_val));
} else if (v.type == RAVA_VAL_DOUBLE) {
UF_PUSH(rava_nanbox_double(v.data.double_val));
} else {
UF_PUSH(rava_nanbox_null());
}
} else {
UF_PUSH(rava_nanbox_null());
}
UF_DISPATCH();
}
uf_hashmap_remove: {
RavaNanboxValue_t key_nb = UF_POP();
RavaNanboxValue_t map_nb = UF_POP();
RavaHashMap_t *map = (RavaHashMap_t*)rava_nanbox_as_object(map_nb);
if (map && rava_nanbox_is_string(key_nb)) {
RavaValue_t v = rava_hashmap_remove(map, rava_nanbox_as_string(key_nb));
if (v.type == RAVA_VAL_INT) {
UF_PUSH(rava_nanbox_int(v.data.int_val));
} else {
UF_PUSH(rava_nanbox_null());
}
} else {
UF_PUSH(rava_nanbox_null());
}
UF_DISPATCH();
}
uf_hashmap_size: {
RavaNanboxValue_t map_nb = UF_POP();
RavaHashMap_t *map = (RavaHashMap_t*)rava_nanbox_as_object(map_nb);
if (map) {
UF_PUSH(rava_nanbox_int((int32_t)rava_hashmap_size(map)));
} else {
UF_PUSH(rava_nanbox_int(0));
}
UF_DISPATCH();
}
uf_hashmap_containskey: {
RavaNanboxValue_t key_nb = UF_POP();
RavaNanboxValue_t map_nb = UF_POP();
RavaHashMap_t *map = (RavaHashMap_t*)rava_nanbox_as_object(map_nb);
if (map && rava_nanbox_is_string(key_nb)) {
UF_PUSH(rava_nanbox_int(rava_hashmap_containskey(map, rava_nanbox_as_string(key_nb)) ? 1 : 0));
} else {
UF_PUSH(rava_nanbox_int(0));
}
UF_DISPATCH();
}
uf_hashmap_clear: {
RavaNanboxValue_t map_nb = UF_POP();
RavaHashMap_t *map = (RavaHashMap_t*)rava_nanbox_as_object(map_nb);
if (map) {
rava_hashmap_clear(map);
}
UF_DISPATCH();
}
uf_done:
rava_fastframe_reset();
return !vm->had_error;
+65 -1
View File
@@ -17,7 +17,9 @@ typedef enum {
RAVA_VAL_NULL,
RAVA_VAL_OBJECT,
RAVA_VAL_ARRAY,
RAVA_VAL_STRING
RAVA_VAL_STRING,
RAVA_VAL_ARRAYLIST,
RAVA_VAL_HASHMAP
} RavaValueType_e;
typedef struct {
@@ -28,6 +30,8 @@ typedef struct {
typedef struct RavaObject_t RavaObject_t;
typedef struct RavaValue_t RavaValue_t;
typedef struct RavaArrayList_t RavaArrayList_t;
typedef struct RavaHashMap_t RavaHashMap_t;
#define RAVA_OBJECT_HASH_SIZE 32
@@ -52,9 +56,36 @@ struct RavaValue_t {
RavaObject_t *object_val;
RavaArray_t *array_val;
char *string_val;
RavaArrayList_t *arraylist_val;
RavaHashMap_t *hashmap_val;
} data;
};
#define RAVA_COLLECTION_ARRAYLIST 1
#define RAVA_COLLECTION_HASHMAP 2
struct RavaArrayList_t {
int collection_type;
RavaValue_t *data;
size_t size;
size_t capacity;
};
#define RAVA_HASHMAP_BUCKET_SIZE 32
typedef struct {
char *key;
RavaValue_t value;
bool occupied;
} RavaHashMapEntry_t;
struct RavaHashMap_t {
int collection_type;
RavaHashMapEntry_t *buckets;
size_t bucket_count;
size_t size;
};
typedef struct {
RavaValue_t *values;
size_t capacity;
@@ -197,6 +228,20 @@ static inline RavaValue_t rava_value_object(RavaObject_t *obj) {
return val;
}
static inline RavaValue_t rava_value_arraylist(RavaArrayList_t *list) {
RavaValue_t val;
val.type = RAVA_VAL_ARRAYLIST;
val.data.arraylist_val = list;
return val;
}
static inline RavaValue_t rava_value_hashmap(RavaHashMap_t *map) {
RavaValue_t val;
val.type = RAVA_VAL_HASHMAP;
val.data.hashmap_val = map;
return val;
}
RavaValue_t rava_value_string(const char *str);
int32_t rava_value_as_int(RavaValue_t value);
@@ -225,6 +270,25 @@ int rava_object_get_field_index(RavaObject_t *obj, const char *name);
RavaValue_t rava_object_get_field_by_index(RavaObject_t *obj, int index);
void rava_object_set_field_by_index(RavaObject_t *obj, int index, RavaValue_t value);
RavaArrayList_t* rava_arraylist_create(void);
void rava_arraylist_destroy(RavaArrayList_t *list);
void rava_arraylist_add(RavaArrayList_t *list, RavaValue_t value);
RavaValue_t rava_arraylist_get(RavaArrayList_t *list, size_t index);
void rava_arraylist_set(RavaArrayList_t *list, size_t index, RavaValue_t value);
size_t rava_arraylist_size(RavaArrayList_t *list);
RavaValue_t rava_arraylist_remove(RavaArrayList_t *list, size_t index);
void rava_arraylist_clear(RavaArrayList_t *list);
bool rava_arraylist_isempty(RavaArrayList_t *list);
RavaHashMap_t* rava_hashmap_create(void);
void rava_hashmap_destroy(RavaHashMap_t *map);
void rava_hashmap_put(RavaHashMap_t *map, const char *key, RavaValue_t value);
RavaValue_t rava_hashmap_get(RavaHashMap_t *map, const char *key);
RavaValue_t rava_hashmap_remove(RavaHashMap_t *map, const char *key);
size_t rava_hashmap_size(RavaHashMap_t *map);
bool rava_hashmap_containskey(RavaHashMap_t *map, const char *key);
void rava_hashmap_clear(RavaHashMap_t *map);
RavaStack_t* rava_stack_create(size_t capacity);
void rava_stack_destroy(RavaStack_t *stack);
void rava_stack_push(RavaStack_t *stack, RavaValue_t value);
+202
View File
@@ -0,0 +1,202 @@
#define _POSIX_C_SOURCE 200809L
#include "runtime.h"
#include <stdlib.h>
#include <string.h>
#define ARRAYLIST_INITIAL_CAPACITY 16
RavaArrayList_t* rava_arraylist_create(void) {
RavaArrayList_t *list = calloc(1, sizeof(RavaArrayList_t));
list->collection_type = RAVA_COLLECTION_ARRAYLIST;
list->data = calloc(ARRAYLIST_INITIAL_CAPACITY, sizeof(RavaValue_t));
list->size = 0;
list->capacity = ARRAYLIST_INITIAL_CAPACITY;
return list;
}
void rava_arraylist_destroy(RavaArrayList_t *list) {
if (!list) return;
free(list->data);
free(list);
}
void rava_arraylist_add(RavaArrayList_t *list, RavaValue_t value) {
if (list->size >= list->capacity) {
list->capacity *= 2;
list->data = realloc(list->data, list->capacity * sizeof(RavaValue_t));
}
list->data[list->size++] = value;
}
RavaValue_t rava_arraylist_get(RavaArrayList_t *list, size_t index) {
if (index >= list->size) {
return rava_value_null();
}
return list->data[index];
}
void rava_arraylist_set(RavaArrayList_t *list, size_t index, RavaValue_t value) {
if (index < list->size) {
list->data[index] = value;
}
}
size_t rava_arraylist_size(RavaArrayList_t *list) {
return list->size;
}
RavaValue_t rava_arraylist_remove(RavaArrayList_t *list, size_t index) {
if (index >= list->size) {
return rava_value_null();
}
RavaValue_t removed = list->data[index];
for (size_t i = index; i < list->size - 1; i++) {
list->data[i] = list->data[i + 1];
}
list->size--;
return removed;
}
void rava_arraylist_clear(RavaArrayList_t *list) {
list->size = 0;
}
bool rava_arraylist_isempty(RavaArrayList_t *list) {
return list->size == 0;
}
static unsigned int _rava_hash_string(const char *str) {
unsigned int hash = 5381;
int c;
while ((c = *str++)) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
RavaHashMap_t* rava_hashmap_create(void) {
RavaHashMap_t *map = calloc(1, sizeof(RavaHashMap_t));
map->collection_type = RAVA_COLLECTION_HASHMAP;
map->bucket_count = RAVA_HASHMAP_BUCKET_SIZE;
map->buckets = calloc(map->bucket_count, sizeof(RavaHashMapEntry_t));
map->size = 0;
return map;
}
void rava_hashmap_destroy(RavaHashMap_t *map) {
if (!map) return;
for (size_t i = 0; i < map->bucket_count; i++) {
if (map->buckets[i].occupied) {
free(map->buckets[i].key);
}
}
free(map->buckets);
free(map);
}
static void _rava_hashmap_resize(RavaHashMap_t *map) {
size_t old_count = map->bucket_count;
RavaHashMapEntry_t *old_buckets = map->buckets;
map->bucket_count *= 2;
map->buckets = calloc(map->bucket_count, sizeof(RavaHashMapEntry_t));
map->size = 0;
for (size_t i = 0; i < old_count; i++) {
if (old_buckets[i].occupied) {
rava_hashmap_put(map, old_buckets[i].key, old_buckets[i].value);
free(old_buckets[i].key);
}
}
free(old_buckets);
}
void rava_hashmap_put(RavaHashMap_t *map, const char *key, RavaValue_t value) {
if (map->size >= map->bucket_count * 7 / 10) {
_rava_hashmap_resize(map);
}
unsigned int hash = _rava_hash_string(key);
size_t index = hash % map->bucket_count;
while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) {
map->buckets[index].value = value;
return;
}
index = (index + 1) % map->bucket_count;
}
map->buckets[index].key = strdup(key);
map->buckets[index].value = value;
map->buckets[index].occupied = true;
map->size++;
}
RavaValue_t rava_hashmap_get(RavaHashMap_t *map, const char *key) {
unsigned int hash = _rava_hash_string(key);
size_t index = hash % map->bucket_count;
size_t start = index;
while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) {
return map->buckets[index].value;
}
index = (index + 1) % map->bucket_count;
if (index == start) break;
}
return rava_value_null();
}
RavaValue_t rava_hashmap_remove(RavaHashMap_t *map, const char *key) {
unsigned int hash = _rava_hash_string(key);
size_t index = hash % map->bucket_count;
size_t start = index;
while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) {
RavaValue_t removed = map->buckets[index].value;
free(map->buckets[index].key);
map->buckets[index].key = NULL;
map->buckets[index].occupied = false;
map->size--;
return removed;
}
index = (index + 1) % map->bucket_count;
if (index == start) break;
}
return rava_value_null();
}
size_t rava_hashmap_size(RavaHashMap_t *map) {
return map->size;
}
bool rava_hashmap_containskey(RavaHashMap_t *map, const char *key) {
unsigned int hash = _rava_hash_string(key);
size_t index = hash % map->bucket_count;
size_t start = index;
while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) {
return true;
}
index = (index + 1) % map->bucket_count;
if (index == start) break;
}
return false;
}
void rava_hashmap_clear(RavaHashMap_t *map) {
for (size_t i = 0; i < map->bucket_count; i++) {
if (map->buckets[i].occupied) {
free(map->buckets[i].key);
map->buckets[i].key = NULL;
map->buckets[i].occupied = false;
}
}
map->size = 0;
}