diff options
Diffstat (limited to 'src/std_gc/list.c')
-rw-r--r-- | src/std_gc/list.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/std_gc/list.c b/src/std_gc/list.c new file mode 100644 index 0000000..5b7c7b6 --- /dev/null +++ b/src/std_gc/list.c @@ -0,0 +1,67 @@ +#include "../../include/std_gc/list.h" +#include "../../include/value.h" +#include <stdio.h> +#include <string.h> +#include <assert.h> +#ifdef DEBUG +#define GC_DEBUG +#endif +#include <gc.h> + +void tsl_list_init(TslList *self) { + self->data = NULL; + self->size = 0; + self->capacity = 0; +} + +static int tsl_list_ensure_capacity(TslList *self, size_t new_size) { + void *new_ptr; + size_t new_capacity = self->capacity; + if(new_size <= self->capacity) + return 1; + + if(new_capacity == 0) + new_capacity = 8; + + while(new_capacity < new_size) { + new_capacity <<= 1; + } + + new_ptr = GC_REALLOC(self->data, new_capacity); + if(!new_ptr) { + fprintf(stderr, "Error: buffer append failed. Reason: out of memory\n"); + return 0; + } + + self->data = new_ptr; + self->capacity = new_capacity; + return 1; +} + +int tsl_list_append(TslList *self, const TslValue *data) { + if(!tsl_list_ensure_capacity(self, self->size + sizeof(TslValue))) + return 0; + memcpy((char*)self->data + self->size, data, sizeof(TslValue)); + self->size += sizeof(TslValue); + return 1; +} + +int tsl_list_set_capacity_hint(TslList *self, size_t capacity) { + return tsl_list_ensure_capacity(self, capacity); +} + +TslValue* tsl_list_begin(TslList *self) { + return self->data; +} + +TslValue* tsl_list_end(TslList *self) { + return (TslValue*)((char*)self->data + self->size); +} + +TslValue* tsl_list_get(TslList *self, double index) { + /* TODO: Verify if overflow check is needed */ + intptr_t index_i = index; + if(index_i >= 0 && index_i < (intptr_t)self->size / (intptr_t)sizeof(TslValue)) + return (TslValue*)self->data + index_i; + return NULL; +} |