#ifndef HONEYSUCKLE_H #define HONEYSUCKLE_H #include #include #include #include #include "va_nargs.h" /* type constants */ typedef enum { HS_BOOL, HS_INT, HS_NUM, HS_STR, HS_TBL, HS_FUNC, HS_CFUNC, HS_USER, HS_LIGHT, HS_NIL, HS_ANY, } hs_type; const char* hs_type_to_string(hs_type type); /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * hs_parse_args and hs_parse_overloaded * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ struct hs_arg { hs_type type; union { bool *boolean; lua_Integer *integer; lua_Number *number; char **string; int *stack_index; lua_CFunction *function; void **userdata; } ptr; }; #define hs_bool(x) { .type=HS_BOOL, .ptr.boolean = &(x) } #define hs_int(x) { .type=HS_INT, .ptr.integer = &(x) } #define hs_num(x) { .type=HS_NUM, .ptr.number = &(x) } #define hs_str(x) { .type=HS_STR, .ptr.string = &(x) } #define hs_tbl(x) { .type=HS_TBL, .ptr.stack_index = &(x) } #define hs_func(x) { .type=HS_FUNC, .ptr.stack_index = &(x) } #define hs_cfunc(x) { .type=HS_CFUNC, .ptr.function = &(x) } #define hs_user(x) { .type=HS_USER, .ptr.userdata = &(x) } #define hs_light(x) { .type=HS_LIGHT, .ptr.userdata = &(x) } #define hs_nil(x) { .type=HS_NIL, .ptr.stack_index = &(x) } #define hs_any(x) { .type=HS_ANY, .ptr.stack_index = &(x) } void hs_parse_args_(lua_State *L, int n_args, struct hs_arg *arguments); #define hs_parse_args(L, ...) \ hs_parse_args_(L, \ VA_NARGS(__VA_ARGS__)/2, \ (struct hs_arg[]) { __VA_ARGS__ }) #define hs_overload(...) VA_NARGS(__VA_ARGS__)/2, (struct hs_arg[]) { __VA_ARGS__ } int hs_parse_overloaded_(lua_State *L, ...); #define hs_parse_overloaded(L, ...) \ hs_parse_overloaded_(L, __VA_ARGS__, -1) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * hs_create_table * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 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_type value_type; union { bool boolean; lua_Integer integer; lua_Number number; char *string; int stack_index; lua_CFunction function; void *userdata; } value; }; #define hs_bool_bool(key, value) \ { HS_BOOL, .key.boolean=key, HS_BOOL, .value.boolean=value } #define hs_bool_int(key, value) \ { HS_BOOL, .key.boolean=key, HS_INT, .value.integer=value } #define hs_bool_num(key, value) \ { HS_BOOL, .key.boolean=key, HS_NUM, .value.number=value } #define hs_bool_str(key, value) \ { HS_BOOL, .key.boolean=key, HS_STR, .value.string=value } #define hs_bool_tbl(key, value) \ { HS_BOOL, .key.boolean=key, HS_TBL, .value.stack_index=value } #define hs_bool_func(key, value) \ { HS_BOOL, .key.boolean=key, HS_FUNC, .value.stack_index=value } #define hs_bool_cfunc(key, value) \ { HS_BOOL, .key.boolean=key, HS_CFUNC, .value.function=value } #define hs_bool_user(key, value) \ { HS_BOOL, .key.boolean=key, HS_USER, .value.stack_index=value } #define hs_bool_light(key, value) \ { HS_BOOL, .key.boolean=key, HS_LIGHT, .value.userdata=value } #define hs_int_bool(key, value) \ { HS_INT, .key.integer=key, HS_BOOL, .value.boolean=value } #define hs_int_int(key, value) \ { HS_INT, .key.integer=key, HS_INT, .value.integer=value } #define hs_int_num(key, value) \ { HS_INT, .key.integer=key, HS_NUM, .value.number=value } #define hs_int_str(key, value) \ { HS_INT, .key.integer=key, HS_STR, .value.string=value } #define hs_int_tbl(key, value) \ { HS_INT, .key.integer=key, HS_TBL, .value.stack_index=value } #define hs_int_func(key, value) \ { HS_INT, .key.integer=key, HS_FUNC, .value.stack_index=value } #define hs_int_cfunc(key, value) \ { HS_INT, .key.integer=key, HS_CFUNC, .value.function=value } #define hs_int_user(key, value) \ { HS_INT, .key.integer=key, HS_USER, .value.stack_index=value } #define hs_int_light(key, value) \ { HS_INT, .key.integer=key, HS_LIGHT, .value.userdata=value } #define hs_num_bool(key, value) \ { HS_NUM, .key.number=key, HS_BOOL, .value.boolean=value } #define hs_num_int(key, value) \ { HS_NUM, .key.number=key, HS_INT, .value.integer=value } #define hs_num_num(key, value) \ { HS_NUM, .key.number=key, HS_NUM, .value.number=value } #define hs_num_str(key, value) \ { HS_NUM, .key.number=key, HS_STR, .value.string=value } #define hs_num_tbl(key, value) \ { HS_NUM, .key.number=key, HS_TBL, .value.stack_index=value } #define hs_num_func(key, value) \ { HS_NUM, .key.number=key, HS_FUNC, .value.stack_index=value } #define hs_num_cfunc(key, value) \ { HS_NUM, .key.number=key, HS_CFUNC, .value.function=value } #define hs_num_user(key, value) \ { HS_NUM, .key.number=key, HS_USER, .value.stack_index=value } #define hs_num_light(key, value) \ { HS_NUM, .key.number=key, HS_LIGHT, .value.userdata=value } #define hs_tbl_bool(key, value) \ { HS_TBL, .key.stack_index=key, HS_BOOL, .value.boolean=value } #define hs_tbl_int(key, value) \ { HS_TBL, .key.stack_index=key, HS_INT, .value.integer=value } #define hs_tbl_num(key, value) \ { HS_TBL, .key.stack_index=key, HS_NUM, .value.number=value } #define hs_tbl_str(key, value) \ { HS_TBL, .key.stack_index=key, HS_STR, .value.string=value } #define hs_tbl_tbl(key, value) \ { HS_TBL, .key.stack_index=key, HS_TBL, .value.stack_index=value } #define hs_tbl_func(key, value) \ { HS_TBL, .key.stack_index=key, HS_FUNC, .value.stack_index=value } #define hs_tbl_cfunc(key, value) \ { HS_TBL, .key.stack_index=key, HS_CFUNC, .value.function=value } #define hs_tbl_user(key, value) \ { HS_TBL, .key.stack_index=key, HS_USER, .value.stack_index=value } #define hs_tbl_light(key, value) \ { HS_TBL, .key.stack_index=key, HS_LIGHT, .value.userdata=value } #define hs_func_bool(key, value) \ { HS_FUNC, .key.stack_index=key, HS_BOOL, .value.boolean=value } #define hs_func_int(key, value) \ { HS_FUNC, .key.stack_index=key, HS_INT, .value.integer=value } #define hs_func_num(key, value) \ { HS_FUNC, .key.stack_index=key, HS_NUM, .value.number=value } #define hs_func_str(key, value) \ { HS_FUNC, .key.stack_index=key, HS_STR, .value.string=value } #define hs_func_tbl(key, value) \ { HS_FUNC, .key.stack_index=key, HS_TBL, .value.stack_index=value } #define hs_func_func(key, value) \ { HS_FUNC, .key.stack_index=key, HS_FUNC, .value.stack_index=value } #define hs_func_cfunc(key, value) \ { HS_FUNC, .key.stack_index=key, HS_CFUNC, .value.function=value } #define hs_func_user(key, value) \ { HS_FUNC, .key.stack_index=key, HS_USER, .value.stack_index=value } #define hs_func_light(key, value) \ { HS_FUNC, .key.stack_index=key, HS_LIGHT, .value.userdata=value } #define hs_cfunc_bool(key, value) \ { HS_CFUNC, .key.function=key, HS_BOOL, .value.boolean=value } #define hs_cfunc_int(key, value) \ { HS_CFUNC, .key.function=key, HS_INT, .value.integer=value } #define hs_cfunc_num(key, value) \ { HS_CFUNC, .key.function=key, HS_NUM, .value.number=value } #define hs_cfunc_str(key, value) \ { HS_CFUNC, .key.function=key, HS_STR, .value.string=value } #define hs_cfunc_tbl(key, value) \ { HS_CFUNC, .key.function=key, HS_TBL, .value.stack_index=value } #define hs_cfunc_func(key, value) \ { HS_CFUNC, .key.function=key, HS_FUNC, .value.stack_index=value } #define hs_cfunc_cfunc(key, value) \ { HS_CFUNC, .key.function=key, HS_CFUNC, .value.function=value } #define hs_cfunc_user(key, value) \ { HS_CFUNC, .key.function=key, HS_USER, .value.stack_index=value } #define hs_cfunc_light(key, value) \ { HS_CFUNC, .key.function=key, HS_LIGHT, .value.userdata=value } #define hs_user_bool(key, value) \ { HS_USER, .key.stack_index=key, HS_BOOL, .value.boolean=value } #define hs_user_int(key, value) \ { HS_USER, .key.stack_index=key, HS_INT, .value.integer=value } #define hs_user_num(key, value) \ { HS_USER, .key.stack_index=key, HS_NUM, .value.number=value } #define hs_user_str(key, value) \ { HS_USER, .key.stack_index=key, HS_STR, .value.string=value } #define hs_user_tbl(key, value) \ { HS_USER, .key.stack_index=key, HS_TBL, .value.stack_index=value } #define hs_user_func(key, value) \ { HS_USER, .key.stack_index=key, HS_FUNC, .value.stack_index=value } #define hs_user_cfunc(key, value) \ { HS_USER, .key.stack_index=key, HS_CFUNC, .value.function=value } #define hs_user_user(key, value) \ { HS_USER, .key.stack_index=key, HS_USER, .value.stack_index=value } #define hs_user_light(key, value) \ { HS_USER, .key.stack_index=key, HS_LIGHT, .value.userdata=value } #define hs_light_bool(key, value) \ { HS_LIGHT, .key.userdata=key, HS_BOOL, .value.boolean=value } #define hs_light_int(key, value) \ { HS_LIGHT, .key.userdata=key, HS_INT, .value.integer=value } #define hs_light_num(key, value) \ { HS_LIGHT, .key.userdata=key, HS_NUM, .value.number=value } #define hs_light_str(key, value) \ { HS_LIGHT, .key.userdata=key, HS_STR, .value.string=value } #define hs_light_tbl(key, value) \ { HS_LIGHT, .key.userdata=key, HS_TBL, .value.stack_index=value } #define hs_light_func(key, value) \ { HS_LIGHT, .key.userdata=key, HS_FUNC, .value.stack_index=value } #define hs_light_cfunc(key, value) \ { HS_LIGHT, .key.userdata=key, HS_CFUNC, .value.function=value } #define hs_light_user(key, value) \ { HS_LIGHT, .key.userdata=key, HS_USER, .value.stack_index=value } #define hs_light_light(key, value) \ { HS_LIGHT, .key.userdata=key, HS_LIGHT, .value.userdata=value } int hs_create_table_(lua_State *L, int n_elements, struct hs_tbl_entry *elements); #define hs_create_table(L, ...) \ hs_create_table_(L, \ VA_NARGS(__VA_ARGS__)/4, \ (struct hs_tbl_entry[]) { __VA_ARGS__ }) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * hs_process_table * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ void hs_process_table(lua_State *L, int table_index, void *data, ...); // default processors void hs_pt_set_boolean(bool value, void *data); void hs_pt_set_integer(lua_Integer value, void *data); void hs_pt_set_number(lua_Number value, void *data); void hs_pt_set_string(const char *value, void *data); /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * hs_pushstring * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ void hs_vpushstring(lua_State *L, const char *format_string, va_list args); void hs_pushstring(lua_State *L, const char *format_string, ...); /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * error creation and handling * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ void hs_throw_error(lua_State *L, const char *format_string, ...); int hs_traceback(lua_State *L); int hs_call(lua_State *L, int nargs, int nret); /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * registry operations * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #define hs_rstore(L) luaL_ref(L, LUA_REGISTRYINDEX); #define hs_rload(L, ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref) #define hs_rdel(L, ref) luaL_unref(L, LUA_REGISTRYINDEX, ref) #endif