diff --git a/HISTORY b/HISTORY index 16805a6..8cdd66c 100755 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,9 @@ Dec. 24 2015 +Improved defining a class in C +Added a pair of mb_get_class_userdata/mb_set_class_userdata functions +Added a pair of mb_get_userdata/mb_set_userdata functions Refactored memory layout of the _routine_t struct +Polished document Dec. 21 2015 Fixed a class GC bug diff --git a/MY-BASIC Quick Reference.pdf b/MY-BASIC Quick Reference.pdf index 9a14e75..13c988e 100644 Binary files a/MY-BASIC Quick Reference.pdf and b/MY-BASIC Quick Reference.pdf differ diff --git a/core/my_basic.c b/core/my_basic.c index 973d110..7f4ba41 100755 --- a/core/my_basic.c +++ b/core/my_basic.c @@ -385,6 +385,7 @@ typedef struct _class_t { char* name; _ls_node_t* meta_list; struct _running_context_t* scope; + void* userdata; } _class_t; #endif /* MB_ENABLE_CLASS */ @@ -8283,6 +8284,8 @@ int mb_end_class(struct mb_interpreter_t* s, void** l) { _pop_scope(s); + s->last_instance = 0; + return result; #else /* MB_ENABLE_CLASS */ mb_unrefvar(s); @@ -8292,6 +8295,60 @@ int mb_end_class(struct mb_interpreter_t* s, void** l) { #endif /* MB_ENABLE_CLASS */ } +int mb_get_class_userdata(struct mb_interpreter_t* s, void** l, void** d) { + /* Get the userdata of a class instance */ +#ifdef MB_ENABLE_CLASS + int result = MB_FUNC_OK; + + mb_assert(s && l && d); + + if(s && s->last_instance) { + if(d) + *d = s->last_instance->userdata; + } else if(s && s->last_routine && s->last_routine->instance) { + if(d) + *d = s->last_routine->instance->userdata; + } else { + if(d) *d = 0; + + _handle_error_on_obj(s, SE_RN_CLASS_EXPECTED, 0, TON(l), MB_FUNC_ERR, _exit, result); + } + +_exit: + return result; +#else /* MB_ENABLE_CLASS */ + mb_unrefvar(s); + mb_unrefvar(l); + mb_unrefvar(d); + + return MB_FUNC_ERR; +#endif /* MB_ENABLE_CLASS */ +} + +int mb_set_class_userdata(struct mb_interpreter_t* s, void** l, void* d) { + /* Set the userdata of a class instance */ +#ifdef MB_ENABLE_CLASS + int result = MB_FUNC_OK; + + mb_assert(s && l && d); + + if(s && s->last_instance) { + s->last_instance->userdata = d; + } else { + _handle_error_on_obj(s, SE_RN_CLASS_EXPECTED, 0, TON(l), MB_FUNC_ERR, _exit, result); + } + +_exit: + return result; +#else /* MB_ENABLE_CLASS */ + mb_unrefvar(s); + mb_unrefvar(l); + mb_unrefvar(d); + + return MB_FUNC_ERR; +#endif /* MB_ENABLE_CLASS */ +} + int mb_get_value_by_name(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t* val) { /* Get a value by its identifier name */ int result = MB_FUNC_OK; @@ -9280,6 +9337,30 @@ int mb_set_inputer(struct mb_interpreter_t* s, mb_input_func_t p) { return result; } +int mb_get_userdata(struct mb_interpreter_t* s, void** d) { + /* Get the userdata of an interpreter instance */ + int result = MB_FUNC_OK; + + mb_assert(s && d); + + if(s && d) + *d = s->userdata; + + return result; +} + +int mb_set_userdata(struct mb_interpreter_t* s, void* d) { + /* Set the userdata of an interpreter instance */ + int result = MB_FUNC_OK; + + mb_assert(s); + + if(s) + s->userdata = d; + + return result; +} + int mb_set_import_handler(struct mb_interpreter_t* s, mb_import_handler_t h) { /* Set an import handler to an interpreter instance */ int result = MB_FUNC_OK; diff --git a/core/my_basic.h b/core/my_basic.h index 03bf600..1079e04 100755 --- a/core/my_basic.h +++ b/core/my_basic.h @@ -435,6 +435,8 @@ MBAPI int mb_push_value(struct mb_interpreter_t* s, void** l, mb_value_t val); MBAPI int mb_begin_class(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t** meta, int c, mb_value_t* out); MBAPI int mb_end_class(struct mb_interpreter_t* s, void** l); +MBAPI int mb_get_class_userdata(struct mb_interpreter_t* s, void** l, void** d); +MBAPI int mb_set_class_userdata(struct mb_interpreter_t* s, void** l, void* d); MBAPI int mb_get_value_by_name(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t* val); MBAPI int mb_add_var(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t val, bool_t force); @@ -471,16 +473,19 @@ MBAPI int mb_debug_set(struct mb_interpreter_t* s, const char* n, mb_value_t val MBAPI int mb_debug_set_stepped_handler(struct mb_interpreter_t* s, mb_debug_stepped_handler_t h); MBAPI const char* mb_get_type_string(mb_data_e t); + MBAPI int mb_raise_error(struct mb_interpreter_t* s, void** l, mb_error_e err, int ret); MBAPI mb_error_e mb_get_last_error(struct mb_interpreter_t* s); MBAPI const char* mb_get_error_desc(mb_error_e err); MBAPI int mb_set_error_handler(struct mb_interpreter_t* s, mb_error_handler_t h); + MBAPI int mb_set_printer(struct mb_interpreter_t* s, mb_print_func_t p); MBAPI int mb_set_inputer(struct mb_interpreter_t* s, mb_input_func_t p); + +MBAPI int mb_get_userdata(struct mb_interpreter_t* s, void** d); +MBAPI int mb_set_userdata(struct mb_interpreter_t* s, void* d); MBAPI int mb_set_import_handler(struct mb_interpreter_t* s, mb_import_handler_t h); - MBAPI int mb_gets(char* buf, int s); - MBAPI char* mb_memdup(const char* val, unsigned size); MBAPI int mb_set_memory_manager(mb_memory_allocate_func_t a, mb_memory_free_func_t f);