+added support to apply the FOR statement to an iterable referenced usertype.
This commit is contained in:
parent
283b7aa593
commit
3fd45e45fd
1
HISTORY
1
HISTORY
@ -1,5 +1,6 @@
|
|||||||
Jul. 4 2017
|
Jul. 4 2017
|
||||||
Added function overriding support of the ITERATOR statement
|
Added function overriding support of the ITERATOR statement
|
||||||
|
Added support to apply the FOR statement to an iterable referenced usertype
|
||||||
|
|
||||||
Jul. 3 2017
|
Jul. 3 2017
|
||||||
Fixed a disposing bug with non-referenced array
|
Fixed a disposing bug with non-referenced array
|
||||||
|
@ -10658,20 +10658,29 @@ _exit:
|
|||||||
static int _execute_ranged_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop) {
|
static int _execute_ranged_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop) {
|
||||||
int result = MB_FUNC_ERR;
|
int result = MB_FUNC_ERR;
|
||||||
_ls_node_t* ast = 0;
|
_ls_node_t* ast = 0;
|
||||||
|
_running_context_t* running = 0;
|
||||||
_object_t* old_val = 0;
|
_object_t* old_val = 0;
|
||||||
_object_t range;
|
|
||||||
_ls_node_t* to_node = 0;
|
_ls_node_t* to_node = 0;
|
||||||
|
_object_t range;
|
||||||
_object_t* range_ptr = 0;
|
_object_t* range_ptr = 0;
|
||||||
_list_it_t* lit = 0;
|
_list_it_t* lit = 0;
|
||||||
_dict_it_t* dit = 0;
|
_dict_it_t* dit = 0;
|
||||||
_list_it_t* tlit = 0;
|
_list_it_t* tlit = 0;
|
||||||
_dict_it_t* tdit = 0;
|
_dict_it_t* tdit = 0;
|
||||||
|
mb_value_t ref_val;
|
||||||
|
mb_value_t ref_it;
|
||||||
|
#ifdef MB_ENABLE_USERTYPE_REF
|
||||||
|
mb_meta_status_e os = MB_MS_NONE;
|
||||||
|
#endif /* MB_ENABLE_USERTYPE_REF */
|
||||||
|
|
||||||
mb_assert(s && l && var_loop);
|
mb_assert(s && l && var_loop);
|
||||||
|
|
||||||
|
running = s->running_context;
|
||||||
old_val = var_loop->data;
|
old_val = var_loop->data;
|
||||||
range_ptr = ⦥
|
range_ptr = ⦥
|
||||||
_MAKE_NIL(range_ptr);
|
_MAKE_NIL(range_ptr);
|
||||||
|
mb_make_nil(ref_val);
|
||||||
|
mb_make_nil(ref_it);
|
||||||
|
|
||||||
ast = *l;
|
ast = *l;
|
||||||
ast = ast->next;
|
ast = ast->next;
|
||||||
@ -10687,6 +10696,15 @@ static int _execute_ranged_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t*
|
|||||||
|
|
||||||
/* Create iterator */
|
/* Create iterator */
|
||||||
switch(range_ptr->type) {
|
switch(range_ptr->type) {
|
||||||
|
#ifdef MB_ENABLE_USERTYPE_REF
|
||||||
|
case _DT_USERTYPE_REF:
|
||||||
|
_internal_object_to_public_value(range_ptr, &ref_val);
|
||||||
|
os = _try_overridden(s, l, &ref_val, _COLL_ID_ITERATOR, MB_MF_COLL);
|
||||||
|
if((os & MB_MS_DONE) != MB_MS_NONE && (os & MB_MS_RETURNED) != MB_MS_NONE)
|
||||||
|
_swap_public_value(&ref_it, &running->intermediate_value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif /* MB_ENABLE_USERTYPE_REF */
|
||||||
case _DT_LIST:
|
case _DT_LIST:
|
||||||
tlit = lit = _create_list_it(range_ptr->data.list, true);
|
tlit = lit = _create_list_it(range_ptr->data.list, true);
|
||||||
|
|
||||||
@ -10701,12 +10719,56 @@ static int _execute_ranged_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t*
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
to_node = ast;
|
to_node = ast;
|
||||||
switch(range_ptr->type) { _REF_COLL(range_ptr) default: /* Do nothing */ break; }
|
switch(range_ptr->type) { _REF_COLL(range_ptr) _REF_USERTYPE_REF(range_ptr) default: /* Do nothing */ break; }
|
||||||
|
|
||||||
_to:
|
_to:
|
||||||
ast = to_node;
|
ast = to_node;
|
||||||
|
|
||||||
/* Move next */
|
/* Move next */
|
||||||
|
#ifdef MB_ENABLE_USERTYPE_REF
|
||||||
|
if(ref_it.type != MB_DT_NIL) {
|
||||||
|
mb_value_t moved_next;
|
||||||
|
mb_value_t curr_val;
|
||||||
|
_object_t curr_obj;
|
||||||
|
|
||||||
|
mb_make_nil(moved_next);
|
||||||
|
mb_make_nil(curr_val);
|
||||||
|
_MAKE_NIL(&curr_obj);
|
||||||
|
|
||||||
|
/* Move next */
|
||||||
|
os = _try_overridden(s, l, &ref_it, _COLL_ID_MOVE_NEXT, MB_MF_COLL);
|
||||||
|
if((os & MB_MS_DONE) != MB_MS_NONE && (os & MB_MS_RETURNED) != MB_MS_NONE)
|
||||||
|
_swap_public_value(&moved_next, &running->intermediate_value);
|
||||||
|
|
||||||
|
if(moved_next.type == MB_DT_INT && moved_next.value.integer) {
|
||||||
|
/* Get current value */
|
||||||
|
os = _try_overridden(s, l, &ref_it, _STD_ID_GET, MB_MF_FUNC);
|
||||||
|
if((os & MB_MS_DONE) != MB_MS_NONE && (os & MB_MS_RETURNED) != MB_MS_NONE)
|
||||||
|
_swap_public_value(&curr_val, &running->intermediate_value);
|
||||||
|
|
||||||
|
/* Assign loop variable */
|
||||||
|
_public_value_to_internal_object(&curr_val, &curr_obj);
|
||||||
|
var_loop->data = &curr_obj;
|
||||||
|
/* Keep looping */
|
||||||
|
result = _common_keep_looping(s, &ast, var_loop);
|
||||||
|
_UNREF(&curr_obj)
|
||||||
|
if(result == MB_LOOP_BREAK) {
|
||||||
|
result = MB_FUNC_OK;
|
||||||
|
|
||||||
|
goto _exit;
|
||||||
|
} else if(result != MB_FUNC_OK || result == MB_SUB_RETURN) {
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto _to;
|
||||||
|
} else {
|
||||||
|
/* End looping */
|
||||||
|
result = _common_end_looping(s, &ast);
|
||||||
|
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* MB_ENABLE_USERTYPE_REF */
|
||||||
if(lit) lit = _move_list_it_next(lit);
|
if(lit) lit = _move_list_it_next(lit);
|
||||||
else if(dit) dit = _move_dict_it_next(dit);
|
else if(dit) dit = _move_dict_it_next(dit);
|
||||||
if((lit && _invalid_list_it(lit)) || (dit && _invalid_dict_it(dit))) {
|
if((lit && _invalid_list_it(lit)) || (dit && _invalid_dict_it(dit))) {
|
||||||
@ -10741,9 +10803,18 @@ _to:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
|
#ifdef MB_ENABLE_USERTYPE_REF
|
||||||
|
if(ref_it.type != MB_DT_NIL) {
|
||||||
|
_object_t it_obj;
|
||||||
|
_MAKE_NIL(&it_obj);
|
||||||
|
|
||||||
|
_public_value_to_internal_object(&ref_it, &it_obj);
|
||||||
|
_UNREF(&it_obj)
|
||||||
|
}
|
||||||
|
#endif /* MB_ENABLE_USERTYPE_REF */
|
||||||
if(tlit) _destroy_list_it(tlit);
|
if(tlit) _destroy_list_it(tlit);
|
||||||
else if(tdit) _destroy_dict_it(tdit);
|
else if(tdit) _destroy_dict_it(tdit);
|
||||||
switch(range_ptr->type) { _UNREF_COLL(range_ptr) default: /* Do nothing */ break; }
|
switch(range_ptr->type) { _UNREF_COLL(range_ptr) _UNREF_USERTYPE_REF(range_ptr) default: /* Do nothing */ break; }
|
||||||
|
|
||||||
*l = ast;
|
*l = ast;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user