From 8c190e955dc4edf7fb1116293a71414ea1d16367 Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Wed, 21 Jan 2026 09:44:18 +0000 Subject: [PATCH] Make conses a vector, add VEC_SIZE macro Easier to iterate through, O(1) amortized registering just like the Linked List. VEC_SIZE just makes it easier to iterate through a vector of specially typed elements. --- alisp.h | 5 +++-- runtime/sys.c | 28 +++++++++++----------------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/alisp.h b/alisp.h index 7f4c909..e552aff 100644 --- a/alisp.h +++ b/alisp.h @@ -76,7 +76,8 @@ typedef struct Vector static_assert(sizeof(vec_t) == 64, "vec_t has to be 64 bytes as part of SBO"); -#define VEC_GET(V, T) ((T *)vec_data(V)) +#define VEC_GET(V, T) ((T *)vec_data(V)) +#define VEC_SIZE(V, T) ((V)->size / (sizeof(T))) void vec_init(vec_t *, u64); void vec_free(vec_t *); @@ -183,7 +184,7 @@ typedef struct /// System context typedef struct { - lisp_t *conses; + vec_t conses; sym_table_t symtable; } sys_t; diff --git a/runtime/sys.c b/runtime/sys.c index 90d7b73..689a28e 100644 --- a/runtime/sys.c +++ b/runtime/sys.c @@ -25,11 +25,8 @@ void sys_init(sys_t *sys) void sys_register(sys_t *sys, lisp_t *ptr) { - // Generate an unmanaged cons - cons_t *cons = calloc(1, sizeof(*cons)); - cons->car = ptr; - cons->cdr = sys->conses; - sys->conses = tag_cons(cons); + // Simply append it to the list of currently active conses + vec_append(&sys->conses, ptr, sizeof(ptr)); } void sys_cleanup(sys_t *sys) @@ -37,18 +34,13 @@ void sys_cleanup(sys_t *sys) static_assert(NUM_TAGS == 5); sym_table_cleanup(&sys->symtable); - - if (!sys->conses) + if (sys->conses.size == 0) return; - // Iterate through each element of memory - for (lisp_t *cell = sys->conses, *next = cdr(cell); cell; - cell = next, next = cdr(next)) + // Iterate through each cons currently allocated and free them + for (size_t i = 0; i < VEC_SIZE(&sys->conses, lisp_t **); ++i) { - // Only reason allocated exists is because we had to allocate memory on the - // heap for it. It's therefore enough to deal with only the allocated - // types. - lisp_t *allocated = car(cell); + lisp_t *allocated = VEC_GET(&sys->conses, lisp_t *)[i]; switch (get_tag(allocated)) { case TAG_CONS: @@ -69,9 +61,11 @@ void sys_cleanup(sys_t *sys) // shouldn't be dealt with (either constant or dealt with elsewhere) break; } - - // Then free the current cell - free(as_cons(cell)); } + + // Free the container + vec_free(&sys->conses); + + // Ensure no one treats this as active in any sense memset(sys, 0, sizeof(*sys)); }