diff options
Diffstat (limited to 'src/node_vec.c')
| -rw-r--r-- | src/node_vec.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/node_vec.c b/src/node_vec.c new file mode 100644 index 0000000..f327585 --- /dev/null +++ b/src/node_vec.c @@ -0,0 +1,114 @@ +#include "node_vec.h" +#include "all.h" +#include <stdio.h> +#include <stdlib.h> + +void node_vec_free(node_vec *v) { + free(v->_data); + v->_data = NULL; + v->_cap = 0; + v->len = 0; +} + +static void _node_vec_init(node_vec *v) { + if (v->_data) + return; + + v->_cap = 16; + v->len = 0; + + v->_data = malloc(v->_cap * sizeof(ast_node_t *)); + if (!v->_data) { + perror("_node_vec_init.malloc"); + abort(); + } +} + +static void _node_vec_ensure(node_vec *v) { + _node_vec_init(v); + + if (v->len >= v->_cap) { + v->_cap = (v->_cap == 0) ? 16 : v->_cap * 2; + + ast_node_t **tmp = realloc(v->_data, v->_cap * sizeof(ast_node_t *)); + if (!tmp) { + perror("_node_vec_ensure.realloc"); + abort(); + } + + v->_data = tmp; + } +} + +size_t node_vec_push(node_vec *v, ast_node_t *data) { + _node_vec_ensure(v); + + v->_data[v->len++] = data; + return v->len - 1; +} + +ast_node_t *node_vec_get(node_vec *v, size_t idx) { + _node_vec_init(v); + + if (idx < v->len) + return v->_data[idx]; + + return NULL; +} + +ast_node_t *node_vec_rem_shift(node_vec *v, size_t idx) { + _node_vec_init(v); + + if (idx >= v->len) + return NULL; + + ast_node_t *old = v->_data[idx]; + + for (size_t j = idx; j + 1 < v->len; j++) { + v->_data[j] = v->_data[j + 1]; + } + + v->len--; + return old; +} + +ast_node_t *node_vec_rem(node_vec *v, size_t idx) { + _node_vec_init(v); + + if (idx >= v->len) + return NULL; + + ast_node_t *old = v->_data[idx]; + v->_data[idx] = v->_data[--v->len]; + return old; +} + +ast_node_t *node_vec_has(node_vec *v, ast_node_t *x, + int (*comp)(const ast_node_t *, const ast_node_t *)) { + _node_vec_init(v); + + if (!comp) + return NULL; + + for (size_t i = 0; i < v->len; i++) { + if (comp(v->_data[i], x) == 0) + return v->_data[i]; + } + + return NULL; +} + +void node_vec_shrink(node_vec *v) { + _node_vec_init(v); + + size_t new_cap = v->len ? v->len : 1; + + ast_node_t **tmp = realloc(v->_data, new_cap * sizeof(ast_node_t *)); + if (!tmp) { + perror("node_vec_shrink.realloc"); + abort(); + } + + v->_cap = new_cap; + v->_data = tmp; +} |
