aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2024-09-08 18:36:07 +0300
committerkartofen <mladenovnasko0@gmail.com>2024-09-08 18:36:07 +0300
commit4308cd4abe5a75fb8410df929eac687cbd04032b (patch)
tree4a5871db2168cb96deab29be7aed36262511c0c1
parentdb32849ce314a93db01f877a057a91022fec7c8b (diff)
update mempool and add implement hash array mapped trie (not integrated)
-rw-r--r--README.md3
-rw-r--r--files/test-lambda.l7
-rw-r--r--src/env.c5
-rw-r--r--src/hamt.c337
-rw-r--r--src/hamt.h45
-rw-r--r--src/hashtable.c9
-rw-r--r--src/main.c18
-rw-r--r--src/memdebug.h35
-rw-r--r--src/mempool.h22
-rw-r--r--src/value.c5
10 files changed, 438 insertions, 48 deletions
diff --git a/README.md b/README.md
index a830f03..59ef04b 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,9 @@ A simple lisp/scheme interpreter
#### TODO
+* totally opaque value_t (maybe add add something with tagged pointers)
+* hamt for allocations
+
* reduce allocations
* overhaul environement/closures
* improve errors
diff --git a/files/test-lambda.l b/files/test-lambda.l
index 29e1f52..d58169a 100644
--- a/files/test-lambda.l
+++ b/files/test-lambda.l
@@ -77,6 +77,9 @@
(defmacro let* (vars body)
(foldr (lambda (var rest) `(let (,var) ,rest)) body vars))
+(defmacro cond (vars)
+ (foldr (lambda (clause rest) `(if ,(car clause) ,(cdar clause) ,rest)) 1 vars))
+
(let ((a 9)
(b 13))
(+ a b))
@@ -85,3 +88,7 @@
(b (- a 3))
(c (+ a b)))
(- c 3))
+
+(cond (((= 1 2) 3)
+ ((= 1 (+ 1 1)) (+ 6 2))
+ (1 (quote test))))
diff --git a/src/env.c b/src/env.c
index 35b2ddf..ff9da33 100644
--- a/src/env.c
+++ b/src/env.c
@@ -6,10 +6,7 @@
#include "value.h"
#include "mempool.h"
-
-#define MEMPOOL_OBJ_TYPE struct symbol_table
-#define MEMPOOL_CAP 64
-MEMPOOL_GENERATE(env)
+MEMPOOL_GENERATE(env, struct symbol_table, 64)
#define ENV_TABLE_CAP (1 << 3)
diff --git a/src/hamt.c b/src/hamt.c
new file mode 100644
index 0000000..a6be3ba
--- /dev/null
+++ b/src/hamt.c
@@ -0,0 +1,337 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include "hamt.h"
+
+#include "mempool.h"
+MEMPOOL_GENERATE(hamt, struct hamt, 16)
+MEMPOOL_GENERATE(hl, struct hamt_nodelist, 64)
+MEMPOOL_GENERATE(hi, struct hamt_item, 32)
+
+#define tag_ptr(ptr, tag) ((uintptr_t)(ptr) | (tag))
+#define untag_ptr(ptr, tag) ((uintptr_t)(ptr) & ~(tag))
+#define is_tagged(ptr, tag) ((uintptr_t)(ptr) & (tag))
+
+#define HAMT_ITEM_TAG 0x1
+#define TAG_NODELIST(ptr) \
+ (hamtptr_t)untag_ptr(ptr, HAMT_ITEM_TAG)
+#define TAG_ITEM(ptr) \
+ (hamtptr_t)tag_ptr(ptr, HAMT_ITEM_TAG)
+#define AS_NODELIST(ptr) \
+ ((struct hamt_nodelist *)untag_ptr(ptr, HAMT_ITEM_TAG))
+#define AS_ITEM(ptr) \
+ ((struct hamt_item *)untag_ptr(ptr, HAMT_ITEM_TAG))
+#define AS_VOIDPTR(ptr) \
+ ((void *)untag_ptr(ptr, HAMT_ITEM_TAG)
+#define IS_NODELIST(hamtptr) \
+ !is_tagged(hamtptr, HAMT_ITEM_TAG)
+#define IS_ITEM(hamtptr) \
+ is_tagged(hamtptr, HAMT_ITEM_TAG)
+
+#define for_each_item(item, head) \
+ for(struct hamt_item *item = (head), *next = NULL; \
+ item && (next = item->next, 1); item = next)
+
+#define popcount(i) __builtin_popcount(i)
+
+#define BITS 6
+#define BITS_MASK 0x3f
+
+static inline struct hamt_nodelist *hamt_nodelist_alloc(void);
+static inline struct hamt_item *hamt_item_alloc(void);
+
+static void hamtptr_destroy(hamtptr_t hamtptr);
+static inline void hamtptr_add_ref(hamtptr_t hamtptr);
+
+// static void hamt_print_hamtptr(hamtptr_t hamtptr, int depth);
+
+hamt_t hamt_create(hamt_equal_fn equal_fn, hamt_hash_fn hash_fn)
+{
+ // hamt_t hamt = malloc(sizeof(*hamt));
+ hamt_t hamt = hamt_mempool_allocate();
+ hamt->equal_fn = equal_fn;
+ hamt->hash_fn = hash_fn;
+ hamt->root = TAG_NODELIST(hamt_nodelist_alloc());
+
+ return hamt;
+}
+
+void hamt_destroy(hamt_t hamt)
+{
+ if(!hamt) return;
+
+ hamtptr_destroy(hamt->root);
+ // free(hamt);
+ hamt_mempool_free(hamt);
+}
+
+hamt_t hamt_clone(hamt_t src)
+{
+ // hamt_t hamt = malloc(sizeof(*hamt));
+ hamt_t hamt = hamt_mempool_allocate();
+
+ if(!src) return hamt;
+
+ hamt->equal_fn = src->equal_fn;
+ hamt->hash_fn = src->hash_fn;
+ hamt->root = src->root;
+ hamtptr_add_ref(hamt->root);
+
+ return hamt;
+}
+
+static int hamt_find_hamtptr(hamtptr_t root, hamtptr_t *ret, uint32_t *hash)
+{
+ *ret = root;
+
+ for(size_t i = 0; i < sizeof(*hash)*8/BITS; i++) {
+ assert(IS_NODELIST(*ret));
+ struct hamt_nodelist *nodelist = AS_NODELIST(*ret);
+
+ size_t rawidx = *hash & BITS_MASK;
+ if(!(nodelist->bitmask & (1 << rawidx))) {
+ return sizeof(*hash)*8/BITS - i;
+ }
+
+ *hash >>= BITS;
+
+ size_t idx = popcount(nodelist->bitmask & ((1 << rawidx) - 1));
+ *ret = nodelist->list[idx];
+ }
+
+ return 0;
+}
+
+int hamt_get(hamt_t hamt, void *key, void **data)
+{
+ hamtptr_t hamtptr;
+ uint32_t hash = hamt->hash_fn(key);
+
+ if(hamt_find_hamtptr(hamt->root, &hamtptr, &hash) != 0)
+ return 1;
+
+ assert(IS_ITEM(hamtptr));
+ struct hamt_item *item = AS_ITEM(hamtptr);
+
+ while(!hamt->equal_fn(key, item->key)) {
+ if(item->next == NULL) return 1;
+ item = item->next;
+ }
+
+ *data = item->data;
+ return 0;
+}
+
+static hamtptr_t hamt_build(uint32_t hash, size_t iter, struct hamt_item **item)
+{
+ if(iter == 1) {
+ *item = hamt_item_alloc();
+ return TAG_ITEM(*item);
+ }
+
+ hash >>= BITS;
+ size_t next_idx = hash & BITS_MASK;
+
+ hamtptr_t next = hamt_build(hash, iter-1, item);
+
+ struct hamt_nodelist *nodelist = hamt_nodelist_alloc();
+
+ // nodelist->list = &next;
+ nodelist->list = calloc(1, sizeof(*nodelist->list));
+ nodelist->list[0] = next;
+
+ nodelist->bitmask = 1 << next_idx;
+
+ return TAG_NODELIST(nodelist);
+}
+
+static hamtptr_t hamt_insert_hamtptr(hamtptr_t root, hamtptr_t hamtptr, uint32_t hash, hamt_equal_fn equal_fn)
+{
+ if(IS_ITEM(root)) {
+ struct hamt_item *item = AS_ITEM(root);
+
+ if(equal_fn(item->key, AS_ITEM(hamtptr)->key)) {
+ item->refs--;
+ AS_ITEM(hamtptr)->next = item->next;
+ return hamtptr;
+ }
+
+ if(item->next) {
+ hamtptr = hamt_insert_hamtptr(TAG_ITEM(item->next), hamtptr, hash, equal_fn);
+ }
+
+ struct hamt_item *new;
+
+ if(item->refs == 1) {
+ new = item;
+ } else {
+ item->refs--;
+ new = hamt_item_alloc();
+ new->key = item->key;
+ new->data = item->data;
+ }
+
+ new->next = AS_ITEM(hamtptr);
+ return TAG_ITEM(new);
+ }
+
+ struct hamt_nodelist *nodelist = AS_NODELIST(root);
+
+ size_t rawidx = hash & BITS_MASK;
+ size_t idx = popcount(nodelist->bitmask & ((1 << rawidx) - 1));
+
+ size_t list_len = popcount(nodelist->bitmask);
+ size_t newlist_len = list_len;
+
+ if(nodelist->bitmask & (1 << rawidx)) {
+ hamtptr = hamt_insert_hamtptr(nodelist->list[idx], hamtptr, hash >> BITS, equal_fn);
+
+ if(nodelist->refs == 1) {
+ nodelist->list[idx] = hamtptr;
+ return TAG_NODELIST(nodelist);
+ }
+ } else {
+ newlist_len++;
+ }
+
+ hamtptr_t *newlist = calloc(newlist_len, sizeof(*newlist));
+ newlist[idx] = hamtptr;
+
+ for(size_t i = 0; i < idx; i++)
+ newlist[i] = nodelist->list[i];
+
+ if(list_len == newlist_len)
+ for(size_t i = idx+1; i < newlist_len; i++)
+ newlist[i] = nodelist->list[i];
+ else
+ for(size_t i = idx+1; i < newlist_len; i++)
+ newlist[i] = nodelist->list[i-1];
+
+ struct hamt_nodelist *new;
+
+ if(nodelist->refs == 1) {
+ new = nodelist;
+ free(nodelist->list);
+ } else {
+ nodelist->refs--;
+ new = hamt_nodelist_alloc();
+ }
+
+ new->list = newlist;
+ new->bitmask = nodelist->bitmask | (1 << rawidx);
+ return TAG_NODELIST(new);
+}
+
+int hamt_set(hamt_t hamt, void *key, void *data, void **keyptr, void **prevdata)
+{
+ hamtptr_t hamtptr;
+ uint32_t hash = hamt->hash_fn(key);
+ uint32_t hash_cpy = hash;
+
+ size_t iter;
+ if((iter = hamt_find_hamtptr(hamt->root, &hamtptr, &hash_cpy)) != 0) {
+ struct hamt_item *item;
+ hamtptr_t new = hamt_build(hash_cpy, iter, &item);
+
+ hamt->root = hamt_insert_hamtptr(hamt->root, new, hash, hamt->equal_fn);
+
+ item->key = key;
+ item->data = data;
+ return 0;
+ }
+
+ assert(IS_ITEM(hamtptr));
+
+ for_each_item(item, AS_ITEM(hamtptr)) {
+ if(hamt->equal_fn(item->key, key)) {
+ if(keyptr) *keyptr = item->key;
+ if(prevdata) *prevdata = item->data;
+ if(item->refs == 1) {
+ item->data = data;
+ return 0;
+ }
+
+ key = item->key;
+ break;
+ }
+ }
+
+ struct hamt_item *new = hamt_item_alloc();
+ new->key = key;
+ new->data = data;
+
+ hamt->root = hamt_insert_hamtptr(hamt->root, TAG_ITEM(new), hash, hamt->equal_fn);
+ return 0;
+}
+
+static inline struct hamt_nodelist *hamt_nodelist_alloc(void)
+{
+ // struct hamt_nodelist *nodelist = malloc(sizeof(*nodelist));
+ struct hamt_nodelist *nodelist = hl_mempool_allocate();
+ nodelist->refs = 1;
+ nodelist->list = 0;
+ nodelist->bitmask = 0;
+ return nodelist;
+}
+
+static inline struct hamt_item *hamt_item_alloc(void)
+{
+ // struct hamt_item *item = malloc(sizeof(*item));
+ struct hamt_item *item = hi_mempool_allocate();
+ item->refs = 1;
+ item->key = NULL;
+ item->data = NULL;
+ item->next = NULL;
+ return item;
+}
+
+static inline void hamtptr_destroy(hamtptr_t hamtptr)
+{
+ if(IS_NODELIST(hamtptr)) {
+ struct hamt_nodelist *nodelist = AS_NODELIST(hamtptr);
+
+ for(size_t i = 0; i < popcount(nodelist->bitmask); i++)
+ hamtptr_destroy(nodelist->list[i]);
+
+ if(--nodelist->refs == 0) {
+ free(nodelist->list);
+ // free(nodelist);
+ hl_mempool_free(nodelist);
+ }
+ } else {
+ for_each_item(item, AS_ITEM(hamtptr))
+ if(--item->refs == 0)
+ hi_mempool_free(item);
+ // free(item);
+ }
+}
+
+static inline void hamtptr_add_ref(hamtptr_t hamtptr)
+{
+ if(IS_NODELIST(hamtptr)) {
+ for(size_t i = 0; i < popcount(AS_NODELIST(hamtptr)->bitmask); i++)
+ hamtptr_add_ref(AS_NODELIST(hamtptr)->list[i]);
+ AS_NODELIST(hamtptr)->refs++;
+ } else {
+ for_each_item(item, AS_ITEM(hamtptr))
+ item->refs++;
+ }
+}
+
+// static void hamt_print_hamtptr(hamtptr_t hamtptr, int depth)
+// {
+// for(int i = 0; i < depth; i++) printf(" ");
+
+// if(IS_NODELIST(hamtptr)) {
+// printf("%d, MASK %b\n", AS_NODELIST(hamtptr)->refs, AS_NODELIST(hamtptr)->bitmask);
+// for(size_t i = 0; i < popcount(AS_NODELIST(hamtptr)->bitmask); i++) {
+// hamt_print_hamtptr(AS_NODELIST(hamtptr)->list[i], depth+1);
+// }
+// } else {
+// printf("%d, %s: %s\n", AS_ITEM(hamtptr)->refs, (char *)AS_ITEM(hamtptr)->key, (char *)AS_ITEM(hamtptr)->data);
+// if(AS_ITEM(hamtptr)->next)
+// hamt_print_hamtptr(TAG_ITEM(AS_ITEM(hamtptr)->next), depth+1);
+// }
+// }
diff --git a/src/hamt.h b/src/hamt.h
new file mode 100644
index 0000000..6ef27ba
--- /dev/null
+++ b/src/hamt.h
@@ -0,0 +1,45 @@
+#ifndef HAMT_H
+#define HAMT_H
+
+#include <stdint.h>
+
+typedef struct hamt *hamt_t;
+
+// tagged pointer to either
+// hamt_item or hamt_nodelist
+typedef uintptr_t hamtptr_t;
+
+struct hamt_item {
+ uint32_t refs;
+
+ void *key;
+ void *data;
+ struct hamt_item *next;
+};
+
+struct hamt_nodelist {
+ uint32_t refs;
+
+ uint64_t bitmask;
+ hamtptr_t *list;
+};
+
+typedef int (*hamt_equal_fn)(void *key1, void *key2);
+typedef uint32_t (*hamt_hash_fn)(void *key);
+
+struct hamt {
+ hamt_equal_fn equal_fn;
+ hamt_hash_fn hash_fn;
+
+ hamtptr_t root;
+};
+
+hamt_t hamt_create(hamt_equal_fn equal_fn, hamt_hash_fn hash_fn);
+void hamt_destroy(hamt_t hamt);
+
+hamt_t hamt_clone(hamt_t src);
+
+int hamt_get(hamt_t hamt, void *key, void **data);
+int hamt_set(hamt_t hamt, void *key, void *data, void **keyptr, void **prevdata);
+
+#endif
diff --git a/src/hashtable.c b/src/hashtable.c
index 955a3bf..e9845f2 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -5,13 +5,8 @@
#include "hashtable.h"
#include "mempool.h"
-
-#define MEMPOOL_CAP 32
-#define MEMPOOL_OBJ_TYPE struct hashtable
-MEMPOOL_GENERATE(ht)
-#define MEMPOOL_CAP 128
-#define MEMPOOL_OBJ_TYPE struct hashtable_item
-MEMPOOL_GENERATE(hi)
+MEMPOOL_GENERATE(ht, struct hashtable, 32)
+MEMPOOL_GENERATE(hi, struct hashtable_item, 128)
// TODO:
// - insertion options
diff --git a/src/main.c b/src/main.c
index 8c4bfec..8baaa94 100644
--- a/src/main.c
+++ b/src/main.c
@@ -811,7 +811,10 @@ static int toklist_expr(struct tctx *tctx, struct toklist **toklist)
if(TOKEN(tctx)->type == TOKEN_LP) depth++;
else if(TOKEN(tctx)->type == TOKEN_RP) depth--;
-
+
+ // printf("%zu\n", depth);
+ // print_token(TOKEN(tctx));
+
if(toklist)
token_clone(&tokens[tokens_len++], TOKEN(tctx));
@@ -823,10 +826,6 @@ static int toklist_expr(struct tctx *tctx, struct toklist **toklist)
}
return 0;
-
-// fail:
- // for(size_t i = 0; i < tokens_len; i++) token_dealloc(&tokens[i]);
- // return 1;
}
#define SET_TOKEN_TYPE(t, ttype) (t)->type = (ttype)
@@ -842,6 +841,15 @@ static struct toklist *value_to_toklist(value_t value)
if(strcmp(value->value.atom, "lambda") == 0) {
SET_TOKEN_TYPE(&token, TOKEN_LAMBDA);
break;
+ } else if(strcmp(value->value.atom, "if") == 0) {
+ SET_TOKEN_TYPE(&token, TOKEN_IF);
+ break;
+ } else if(strcmp(value->value.atom, "quote") == 0) {
+ SET_TOKEN_TYPE(&token, TOKEN_QUOTE_FORM);
+ break;
+ } else if(strcmp(value->value.atom, "'") == 0) {
+ SET_TOKEN_TYPE(&token, TOKEN_QUOTE);
+ break;
}
SET_TOKEN_TYPE(&token, TOKEN_ID);
diff --git a/src/memdebug.h b/src/memdebug.h
index 358203a..7d72a10 100644
--- a/src/memdebug.h
+++ b/src/memdebug.h
@@ -64,6 +64,7 @@ typedef long long int memdebug_suffix;
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <time.h>
@@ -80,17 +81,19 @@ static FILE *_memdebug_fp = NULL;
errno, strerror(errno)); \
} while(0)
-#define MEMDEBUG_OUT_OF_BOUNDS_CHECK(addr, size) \
- do { \
- if(addr != NULL) { \
- *(size_t*)addr = size; \
- addr += sizeof(size_t); \
- \
- memdebug_suffix suffix = MEMDEBUG_MAGIC_SUFFIX; \
- memcpy(addr + size, &suffix, sizeof(suffix)); \
- } \
- } while(0);
+static inline void *memdebug_add_out_of_bounds_check(void *addr, size_t size)
+{
+ uintptr_t size_addr = (uintptr_t)addr;
+ uintptr_t suffix_addr = size_addr +
+ sizeof(size) + size;
+
+ memcpy((void *)size_addr, &size, sizeof(size));
+ memdebug_suffix suffix = MEMDEBUG_MAGIC_SUFFIX;
+ memcpy((void *)suffix_addr, &suffix, sizeof(suffix));
+
+ return (void *)((uintptr_t)addr + sizeof(size));
+}
void *__memdebug_malloc(size_t size, char *file, int line)
{
@@ -99,7 +102,7 @@ void *__memdebug_malloc(size_t size, char *file, int line)
#else
void *addr = MEMDEBUG_MALLOC_SYMBOL(
size + MEMDEBUG_OUT_OF_BOUNDS_EXTRA_SIZE);
- MEMDEBUG_OUT_OF_BOUNDS_CHECK(addr, size);
+ if(addr) addr = memdebug_add_out_of_bounds_check(addr, size);
#endif
MEMDEBUG_LOG_FUNC(malloc, addr, file, line);
@@ -118,7 +121,7 @@ void *__memdebug_realloc(void *ptr, size_t size, char *file, int line)
#else
void *addr = MEMDEBUG_REALLOC_SYMBOL(
ptr, size + MEMDEBUG_OUT_OF_BOUNDS_EXTRA_SIZE);
- MEMDEBUG_OUT_OF_BOUNDS_CHECK(addr, size);
+ if(addr) addr = memdebug_add_out_of_bounds_check(addr, size);
#endif
MEMDEBUG_LOG_FUNC(realloc, addr, file, line);
@@ -137,7 +140,7 @@ void *__memdebug_calloc(size_t nmemb, size_t size, char *file, int line)
#else
void *addr = MEMDEBUG_MALLOC_SYMBOL(
nmemb * size + MEMDEBUG_OUT_OF_BOUNDS_EXTRA_SIZE);
- MEMDEBUG_OUT_OF_BOUNDS_CHECK(addr, nmemb * size);
+ if(addr) addr = memdebug_add_out_of_bounds_check(addr, nmemb * size);
memset(addr, 0, nmemb * size);
#endif
@@ -158,9 +161,9 @@ void __memdebug_free(void *ptr, char *file, int line)
#ifdef MEMDEBUG_OUT_OF_BOUNDS
if(ptr != NULL) {
- size_t size = *(size_t *)(ptr - sizeof(size_t));
+ size_t size = *(size_t *)((uintptr_t)ptr - sizeof(size_t));
memdebug_suffix suffix = 0;
- memcpy(&suffix, ptr + size, sizeof(suffix));
+ memcpy(&suffix, (void *)((uintptr_t)ptr + size), sizeof(suffix));
MEMDEBUG_LOG(", ");
MEMDEBUG_LOG("out-of-bounds-check: ");
@@ -169,7 +172,7 @@ void __memdebug_free(void *ptr, char *file, int line)
MEMDEBUG_LOG("SUCCESS");
else MEMDEBUG_LOG("FAILED");
- ptr -= sizeof(size_t);
+ ptr = (void *)((uintptr_t)ptr + sizeof(size_t));
}
#endif
diff --git a/src/mempool.h b/src/mempool.h
index 6c25ac9..7d065f5 100644
--- a/src/mempool.h
+++ b/src/mempool.h
@@ -1,13 +1,11 @@
#ifndef MEMPOOL_H
#define MEMPOOL_H
-#ifndef MEMPOOL_OBJ_TYPE
-#define MEMPOOL_OBJ_TYPE int
-#endif
-
-#ifndef MEMPOOL_CAP
-#define MEMPOOL_CAP (1 << 16)
-#endif
+/* To generate use MEMPOOL_GENERATE(id, type, cap), where functions
+ * _mempool_allocate() and _mempool_free(type *obj) will be prefixed with id
+ * and can be used to allocate objects of type <type> with <cap> objects in
+ * each block
+ */
#define for_each_block(id, b, head) \
for(struct id##_block *b = (head), *next = NULL; \
@@ -15,13 +13,13 @@
#define get_last_block(b) \
while((b)->next != NULL) (b) = (b)->next
-#define MEMPOOL_GENERATE(id) \
+#define MEMPOOL_GENERATE(id, type, cap) \
\
struct id##_block { \
union id##_chunk { \
- MEMPOOL_OBJ_TYPE obj; \
+ type obj; \
union id##_chunk *next; \
- } chunks[MEMPOOL_CAP]; \
+ } chunks[cap]; \
\
struct id##_block *next; \
}; \
@@ -33,9 +31,9 @@
static inline void *_##id##_mempool_init_block(struct id##_block *b) \
{ \
b->next = NULL; \
- for(size_t i = 0; i < MEMPOOL_CAP; i++) \
+ for(size_t i = 0; i < cap; i++) \
b->chunks[i].next = &b->chunks[i+1]; \
- b->chunks[MEMPOOL_CAP-1].next = NULL; \
+ b->chunks[cap-1].next = NULL; \
\
return b->chunks; \
} \
diff --git a/src/value.c b/src/value.c
index 0d263d7..c72c4a2 100644
--- a/src/value.c
+++ b/src/value.c
@@ -6,10 +6,7 @@
#include "lexer.h"
#include "mempool.h"
-
-#define MEMPOOL_OBJ_TYPE struct value
-#define MEMPOOL_CAP 64
-MEMPOOL_GENERATE(value)
+MEMPOOL_GENERATE(value, struct value, 64)
#define NOT_IMPLEMENTED() die("Not Implemented. ABORTING")