+added member accessing support following a routine of a class instance.
This commit is contained in:
parent
a6aeab3ad8
commit
ae971aefbd
1
HISTORY
1
HISTORY
@ -1,5 +1,6 @@
|
|||||||
Feb. 19 2016
|
Feb. 19 2016
|
||||||
Added source tracing for sub routine invoking
|
Added source tracing for sub routine invoking
|
||||||
|
Added member accessing support following a routine of a class instance
|
||||||
Fixed a lexical object convertion issue
|
Fixed a lexical object convertion issue
|
||||||
|
|
||||||
Feb. 18 2016
|
Feb. 18 2016
|
||||||
|
@ -711,6 +711,7 @@ typedef struct mb_interpreter_t {
|
|||||||
unsigned char jump_set;
|
unsigned char jump_set;
|
||||||
#ifdef MB_ENABLE_CLASS
|
#ifdef MB_ENABLE_CLASS
|
||||||
_class_t* last_instance;
|
_class_t* last_instance;
|
||||||
|
bool_t calling;
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
_routine_t* last_routine;
|
_routine_t* last_routine;
|
||||||
_ls_node_t* sub_stack;
|
_ls_node_t* sub_stack;
|
||||||
@ -1490,6 +1491,7 @@ static bool_t _add_class_meta_reachable(_class_t* meta, void* ht, void* ret);
|
|||||||
static int _reflect_class_field(void* data, void* extra, void* d);
|
static int _reflect_class_field(void* data, void* extra, void* d);
|
||||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
static _class_t* _reflect_string_to_class(mb_interpreter_t* s, const char* n, mb_value_t* arg);
|
static _class_t* _reflect_string_to_class(mb_interpreter_t* s, const char* n, mb_value_t* arg);
|
||||||
|
static bool_t _is_valid_class_accessor_following_routine(mb_interpreter_t* s, _var_t* var, _ls_node_t* ast, _ls_node_t** out);
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
static void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n, mb_routine_func_t f);
|
static void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n, mb_routine_func_t f);
|
||||||
static void _begin_routine(mb_interpreter_t* s);
|
static void _begin_routine(mb_interpreter_t* s);
|
||||||
@ -3239,9 +3241,35 @@ _array:
|
|||||||
_ls_pushback(opnd, c);
|
_ls_pushback(opnd, c);
|
||||||
f++;
|
f++;
|
||||||
} else if(c->type == _DT_ROUTINE) {
|
} else if(c->type == _DT_ROUTINE) {
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
bool_t calling = false;
|
||||||
|
_object_t* obj = 0;
|
||||||
|
_ls_node_t* fn = 0;
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
_routine:
|
_routine:
|
||||||
ast = ast->prev;
|
ast = ast->prev;
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
calling = s->calling;
|
||||||
|
s->calling = false;
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
result = _eval_routine(s, &ast, 0, 0, c->data.routine, _has_routine_lex_arg, _pop_routine_lex_arg);
|
result = _eval_routine(s, &ast, 0, 0, c->data.routine, _has_routine_lex_arg, _pop_routine_lex_arg);
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
s->calling = calling;
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
obj = (_object_t*)ast->data;
|
||||||
|
if(_IS_VAR(obj) && _is_valid_class_accessor_following_routine(s, obj->data.variable, ast, &fn)) {
|
||||||
|
if(fn) {
|
||||||
|
if(ast) ast = ast->next;
|
||||||
|
obj = (_object_t*)fn->data;
|
||||||
|
if(_IS_VAR(obj)) {
|
||||||
|
c = obj;
|
||||||
|
|
||||||
|
goto _var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
if(ast)
|
if(ast)
|
||||||
ast = ast->prev;
|
ast = ast->prev;
|
||||||
if(result != MB_FUNC_OK) {
|
if(result != MB_FUNC_OK) {
|
||||||
@ -3310,6 +3338,9 @@ _routine:
|
|||||||
goto _routine;
|
goto _routine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
_var:
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
if(ast) {
|
if(ast) {
|
||||||
_object_t* _err_or_bracket = (_object_t*)ast->data;
|
_object_t* _err_or_bracket = (_object_t*)ast->data;
|
||||||
do {
|
do {
|
||||||
@ -6855,6 +6886,28 @@ static _class_t* _reflect_string_to_class(mb_interpreter_t* s, const char* n, mb
|
|||||||
|
|
||||||
return c->data.instance;
|
return c->data.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool_t _is_valid_class_accessor_following_routine(mb_interpreter_t* s, _var_t* var, _ls_node_t* ast, _ls_node_t** out) {
|
||||||
|
/* Detect whether it's accessing a member of a class instance following a sub routine */
|
||||||
|
bool_t result = false;
|
||||||
|
_running_context_t* running = 0;
|
||||||
|
|
||||||
|
mb_assert(s && var && ast);
|
||||||
|
|
||||||
|
running = s->running_context;
|
||||||
|
|
||||||
|
if(out) *out = 0;
|
||||||
|
|
||||||
|
if(_is_accessor(*var->name) && (ast && ast->prev && _IS_FUNC(ast->prev->data, _core_close_bracket)) && running->intermediate_value.type == MB_DT_CLASS) {
|
||||||
|
_class_t* instance = (_class_t*)running->intermediate_value.value.instance;
|
||||||
|
_ls_node_t* fn = _search_identifier_in_class(s, instance, var->name + 1, 0, 0);
|
||||||
|
result = true;
|
||||||
|
if(fn && out)
|
||||||
|
*out = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
|
||||||
static void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n, mb_routine_func_t f) {
|
static void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n, mb_routine_func_t f) {
|
||||||
@ -8830,7 +8883,21 @@ _retry:
|
|||||||
skip_to_eoi = false;
|
skip_to_eoi = false;
|
||||||
ast = ast->next;
|
ast = ast->next;
|
||||||
} else if(obj && obj->type == _DT_VAR) {
|
} else if(obj && obj->type == _DT_VAR) {
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
_ls_node_t* fn = 0;
|
||||||
|
if(_is_valid_class_accessor_following_routine(s, obj->data.variable, ast, &fn)) {
|
||||||
|
if(fn) {
|
||||||
|
if(s->calling)
|
||||||
|
result = _core_let(s, (void**)&ast);
|
||||||
|
} else {
|
||||||
|
_handle_error_on_obj(s, SE_RN_INVALID_ID_USAGE, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_handle_error_on_obj(s, SE_RN_COLON_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
#else /* MB_ENABLE_CLASS */
|
||||||
_handle_error_on_obj(s, SE_RN_COLON_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_COLON_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
} else if(_IS_FUNC(obj, _core_enddef) && result != MB_SUB_RETURN) {
|
} else if(_IS_FUNC(obj, _core_enddef) && result != MB_SUB_RETURN) {
|
||||||
ast = (_ls_node_t*)_ls_popback(sub_stack);
|
ast = (_ls_node_t*)_ls_popback(sub_stack);
|
||||||
#ifdef MB_ENABLE_LAMBDA
|
#ifdef MB_ENABLE_LAMBDA
|
||||||
@ -11171,6 +11238,12 @@ int mb_run(struct mb_interpreter_t* s) {
|
|||||||
s->suspent_point = 0;
|
s->suspent_point = 0;
|
||||||
} else {
|
} else {
|
||||||
s->source_file = 0;
|
s->source_file = 0;
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
s->last_instance = 0;
|
||||||
|
s->calling = false;
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
s->last_routine = 0;
|
||||||
|
|
||||||
mb_assert(!s->no_eat_comma_mark);
|
mb_assert(!s->no_eat_comma_mark);
|
||||||
while(s->running_context->prev)
|
while(s->running_context->prev)
|
||||||
s->running_context = s->running_context->prev;
|
s->running_context = s->running_context->prev;
|
||||||
@ -12046,6 +12119,15 @@ static int _core_let(mb_interpreter_t* s, void** l) {
|
|||||||
_handle_error_on_obj(s, SE_RN_SYNTAX, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_SYNTAX, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
}
|
}
|
||||||
obj = (_object_t*)ast->data;
|
obj = (_object_t*)ast->data;
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
if(_IS_VAR(obj)) {
|
||||||
|
_ls_node_t* fn = 0;
|
||||||
|
if(_is_valid_class_accessor_following_routine(s, obj->data.variable, ast, &fn)) {
|
||||||
|
if(fn)
|
||||||
|
obj = (_object_t*)fn->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
if(obj->type == _DT_ARRAY) {
|
if(obj->type == _DT_ARRAY) {
|
||||||
arr_obj = obj;
|
arr_obj = obj;
|
||||||
arr = _search_array_in_scope_chain(s, obj->data.array, &arr_obj);
|
arr = _search_array_in_scope_chain(s, obj->data.array, &arr_obj);
|
||||||
@ -12924,8 +13006,14 @@ _retry:
|
|||||||
routine = obj->data.routine;
|
routine = obj->data.routine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
s->calling = true;
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
result = _eval_routine(s, &ast, 0, 0, routine, _has_routine_lex_arg, _pop_routine_lex_arg);
|
result = _eval_routine(s, &ast, 0, 0, routine, _has_routine_lex_arg, _pop_routine_lex_arg);
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
s->calling = false;
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
if(ast)
|
if(ast)
|
||||||
ast = ast->prev;
|
ast = ast->prev;
|
||||||
|
|
||||||
|
Binary file not shown.
@ -1268,9 +1268,9 @@ static void _on_error(struct mb_interpreter_t* s, mb_error_e e, char* m, char* f
|
|||||||
|
|
||||||
if(SE_NO_ERR != e) {
|
if(SE_NO_ERR != e) {
|
||||||
if(f) {
|
if(f) {
|
||||||
_printf("Error:\n Line %d, Col %d in File: %s\n Code: %d; Message: %s; Abort Code: %d.\n", row, col, f, e, m, abort_code);
|
_printf("Error:\n Line %d, Col %d in File: %s\n Code %d, Abort Code %d\n Message: %s.\n", row, col, f, e, abort_code, m);
|
||||||
} else {
|
} else {
|
||||||
_printf("Error:\n Line %d, Col %d\n Code: %d; Message: %s; Abort Code: %d.\n", row, col, e, m, abort_code);
|
_printf("Error:\n Line %d, Col %d\n Code %d, Abort Code %d\n Message: %s.\n", row, col, e, abort_code, m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user