diff --git a/include/alisp/lisp.h b/include/alisp/lisp.h index d4aae26..7ba9974 100644 --- a/include/alisp/lisp.h +++ b/include/alisp/lisp.h @@ -26,7 +26,8 @@ typedef struct /// System context typedef struct { - vec_t memory; + vec_t conses; + vec_t vectors; sym_table_t symtable; } sys_t; diff --git a/src/lisp.c b/src/lisp.c index a64118a..b2cd2cd 100644 --- a/src/lisp.c +++ b/src/lisp.c @@ -19,31 +19,57 @@ void sys_init(sys_t *sys) void sys_register(sys_t *sys, lisp_t *ptr) { // Simply append it to the list of currently active conses - vec_append(&sys->memory, &ptr, sizeof(&ptr)); + switch (get_tag(ptr)) + { + case TAG_CONS: + vec_append(&sys->conses, &ptr, sizeof(&ptr)); + break; + case TAG_VEC: + vec_append(&sys->vectors, &ptr, sizeof(&ptr)); + break; + // Shouldn't be registered + case TAG_NIL: + case TAG_INT: + case TAG_SYM: + break; + case NUM_TAGS: + default: + FAIL("Unreachable"); + } } u64 sys_cost(sys_t *sys) { - return sym_table_cost(&sys->symtable) + sys->memory.capacity; + u64 vec_capacity = 0; + for (u64 i = 0; i < VEC_SIZE(&sys->vectors, lisp_t *); ++i) + { + lisp_t *vec = VEC_GET(&sys->vectors, i, lisp_t *); + vec_capacity += as_vec(vec)->capacity; + } + return sym_table_cost(&sys->symtable) + sys->conses.capacity + vec_capacity; } void sys_free(sys_t *sys) { - static_assert(NUM_TAGS == 5); - sym_table_free(&sys->symtable); - if (sys->memory.size == 0) - return; // Iterate through each cell of memory currently allocated and free them - for (size_t i = 0; i < VEC_SIZE(&sys->memory, lisp_t **); ++i) + for (size_t i = 0; i < VEC_SIZE(&sys->conses, lisp_t **); ++i) { - lisp_t *allocated = VEC_GET(&sys->memory, i, lisp_t *); + lisp_t *allocated = VEC_GET(&sys->conses, i, lisp_t *); lisp_free(allocated); } - // Free the container - vec_free(&sys->memory); + // Iterate through each cell of memory currently allocated and free them + for (size_t i = 0; i < VEC_SIZE(&sys->vectors, lisp_t **); ++i) + { + lisp_t *allocated = VEC_GET(&sys->vectors, i, lisp_t *); + lisp_free(allocated); + } + + // Free the containers + vec_free(&sys->conses); + vec_free(&sys->vectors); // Ensure no one treats this as active in any sense memset(sys, 0, sizeof(*sys)); diff --git a/test/test_lisp_api.c b/test/test_lisp_api.c index b1b3083..915c4e9 100644 --- a/test/test_lisp_api.c +++ b/test/test_lisp_api.c @@ -151,44 +151,42 @@ void sys_test(void) TEST_START(); sys_t sys = {0}; sys_init(&sys); - u64 old_memory_size = sys.memory.size; + u64 old_memory_size = sys_cost(&sys); // Creating integers doesn't affect memory size (void)make_int(2000); - TEST(sys.memory.size == old_memory_size, + TEST(sys_cost(&sys) == old_memory_size, "Making integers doesn't affect system memory size"); - // Creating symbols won't affect memory size, but does affect the symbol table + // Creating symbols does affect memory size and memory table (void)intern(&sys, SV_AUTO("hello world!")); - TEST(sys.memory.size == old_memory_size, + TEST(sys_cost(&sys) > old_memory_size, "Interning doesn't affect system memory size"); TEST(sys.symtable.count > 0, "Interning affects symbol table"); + old_memory_size = sys_cost(&sys); // Creating conses do affect memory size (void)cons(&sys, make_int(1), make_int(2)); - TEST(sys.memory.size > 0, "Creating conses affects memory size"); - old_memory_size = sys.memory.size; + TEST(sys_cost(&sys) > 0, "Creating conses affects memory size"); + old_memory_size = sys_cost(&sys); (void)cons(&sys, intern(&sys, SV_AUTO("test")), NIL); - TEST(sys.memory.size > old_memory_size, + TEST(sys_cost(&sys) > old_memory_size, "Creating conses back to back affects memory size"); - old_memory_size = sys.memory.size; + old_memory_size = sys_cost(&sys); // Creating vectors does affect memory size (void)make_vec(&sys, 8); - TEST(sys.memory.size > old_memory_size, + TEST(sys_cost(&sys) > old_memory_size, "Creating vectors (size 8) affects memory size"); - old_memory_size = sys.memory.size; + old_memory_size = sys_cost(&sys); (void)make_vec(&sys, 1000); - TEST(sys.memory.size > old_memory_size, + TEST(sys_cost(&sys) > old_memory_size, "Creating vectors (size 1000) affects memory size"); - old_memory_size = sys.memory.size; + old_memory_size = sys_cost(&sys); sys_free(&sys); - TEST(sys.memory.size == 0, "sys_free cleans up memory (shallow check)"); - TEST(sys.symtable.count == 0, "sys_free cleans up symtable (shallow check)"); - TEST_END(); }