From b198d914dba288c736973e38b6fde06b768b8587 Mon Sep 17 00:00:00 2001 From: sanine Date: Sun, 29 Aug 2021 19:52:14 -0500 Subject: strengthen tests and implement table creation cleanup --- src/honeysuckle.h | 30 +++--- src/hs_create_table.c | 121 ++++++++++++++++++++- src/tests/hs_create_table_tests.c | 215 +++++++++++++++++++++++++++++++++++--- 3 files changed, 330 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/honeysuckle.h b/src/honeysuckle.h index f215528..378e0a1 100644 --- a/src/honeysuckle.h +++ b/src/honeysuckle.h @@ -80,27 +80,21 @@ int hs_parse_overloaded_(lua_State *L, ...); * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +typedef union { + bool boolean; + lua_Integer integer; + lua_Number number; + char *string; + int stack_index; + lua_CFunction function; + void *userdata; +} hs_value; + struct hs_tbl_entry { hs_type key_type; - union { - bool boolean; - lua_Integer integer; - lua_Number number; - char *string; - int stack_index; - lua_CFunction function; - void *userdata; - } key; + hs_value key; hs_type value_type; - union { - bool boolean; - lua_Integer integer; - lua_Number number; - char *string; - int stack_index; - lua_CFunction function; - void *userdata; - } value; + hs_value value; }; #define hs_bool_bool(k, v) \ diff --git a/src/hs_create_table.c b/src/hs_create_table.c index 5441dae..422a480 100644 --- a/src/hs_create_table.c +++ b/src/hs_create_table.c @@ -1,12 +1,123 @@ +#include + #include "honeysuckle.h" +static void push_value(lua_State *L, hs_type type, hs_value value) +{ + switch (type) { + case HS_BOOL: + lua_pushboolean(L, value.boolean); + break; + + case HS_INT: + lua_pushinteger(L, value.integer); + break; + + case HS_NUM: + lua_pushnumber(L, value.number); + break; + + case HS_STR: + lua_pushstring(L, value.string); + break; + + case HS_TBL: + lua_pushvalue(L, value.stack_index); + break; + + case HS_FUNC: + lua_pushvalue(L, value.stack_index); + break; + + case HS_CFUNC: + lua_pushcfunction(L, value.function); + break; + + case HS_USER: + lua_pushvalue(L, value.stack_index); + break; + + case HS_LIGHT: + lua_pushlightuserdata(L, value.userdata); + break; + + default: + hs_throw_error(L, "attempted to push data of invalid type %d", type); + break; + } +} + + +static inline bool poppable(hs_type type) +{ + if (type == HS_TBL || + type == HS_FUNC || + type == HS_USER) { + return true; + } + return false; +} + + +static void print_stack(lua_State *L) +{ + printf("stack: %d [", lua_gettop(L)); + for (int i=0; ikey_type, e->key); + // print_stack(L); + push_value(L, e->value_type, e->value); + // print_stack(L); + lua_rawset(L, index); + // print_stack(L); + } + + int n_poppable = 0; + int pop_indices[n_elements]; + + for (int i=0; ikey_type)) + pop_indices[n_poppable++] = e->key.stack_index; + if (poppable(e->value_type)) + pop_indices[n_poppable++] = e->value.stack_index; + } + + // printf("cleaning up\n"); + + qsort(pop_indices, n_poppable, sizeof(int), descending); + for (int i=0; i