+added an IN keyword; +added support to loop on collections by using FOR-IN statement.
This commit is contained in:
parent
c684f3fcef
commit
d344b05d68
8
HISTORY
8
HISTORY
@ -1,11 +1,13 @@
|
|||||||
Jan. 22 2016
|
Jan. 22 2016
|
||||||
Added a HASH meta method to calculate the hash code of a class instance
|
Added an IN keyword
|
||||||
Added a COMPARE meta method to compare two class instances
|
Added support to loop on collections by using FOR-IN statement
|
||||||
|
Added a "hash" meta method to calculate the hash code of a class instance
|
||||||
|
Added a "compare" meta method to compare two class instances
|
||||||
|
|
||||||
Jan. 21 2016
|
Jan. 21 2016
|
||||||
Fixed a referenced usertype comparison bug
|
Fixed a referenced usertype comparison bug
|
||||||
Fixed a wrong memory copy bug with the PRINT statement
|
Fixed a wrong memory copy bug with the PRINT statement
|
||||||
Added a TOSTRING meta method to serialize a class instance
|
Added a "tostring" meta method to serialize a class instance
|
||||||
Improved type handling
|
Improved type handling
|
||||||
|
|
||||||
Jan. 20 2016
|
Jan. 20 2016
|
||||||
|
Binary file not shown.
239
core/my_basic.c
239
core/my_basic.c
@ -1558,6 +1558,8 @@ static _object_t* _eval_var_in_print(mb_interpreter_t* s, _object_t** val_ptr, _
|
|||||||
|
|
||||||
static void _stepped(mb_interpreter_t* s, _ls_node_t* ast);
|
static void _stepped(mb_interpreter_t* s, _ls_node_t* ast);
|
||||||
static int _execute_statement(mb_interpreter_t* s, _ls_node_t** l);
|
static int _execute_statement(mb_interpreter_t* s, _ls_node_t** l);
|
||||||
|
static int _common_end_looping(mb_interpreter_t* s, _ls_node_t** l);
|
||||||
|
static int _common_keep_looping(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop);
|
||||||
static int _execute_normal_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop);
|
static int _execute_normal_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop);
|
||||||
#ifdef MB_ENABLE_COLLECTION_LIB
|
#ifdef MB_ENABLE_COLLECTION_LIB
|
||||||
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);
|
||||||
@ -8589,78 +8591,30 @@ _exit:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _execute_normal_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop) {
|
int _common_end_looping(mb_interpreter_t* s, _ls_node_t** l) {
|
||||||
/* Execute normal FOR-TO-STEP-NEXT-routine */
|
/* Common function to end current looping */
|
||||||
|
int result = MB_FUNC_OK;
|
||||||
|
|
||||||
|
mb_assert(s && l);
|
||||||
|
|
||||||
|
if(_skip_struct(s, l, _core_for, _core_next) == MB_FUNC_OK)
|
||||||
|
_skip_to(s, l, 0, _DT_EOS);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _common_keep_looping(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop) {
|
||||||
|
/* Common function to keep current looping */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
_ls_node_t* ast = 0;
|
_ls_node_t* ast = 0;
|
||||||
_ls_node_t* to_node = 0;
|
|
||||||
_object_t* obj = 0;
|
_object_t* obj = 0;
|
||||||
_object_t to_val;
|
|
||||||
_object_t step_val;
|
|
||||||
_object_t* to_val_ptr = 0;
|
|
||||||
_object_t* step_val_ptr = 0;
|
|
||||||
_tuple3_t ass_tuple3;
|
|
||||||
_tuple3_t* ass_tuple3_ptr = 0;
|
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
|
|
||||||
mb_assert(s && l && var_loop);
|
mb_assert(s && l);
|
||||||
|
|
||||||
running = s->running_context;
|
running = s->running_context;
|
||||||
ast = *l;
|
ast = *l;
|
||||||
|
|
||||||
to_val_ptr = &to_val;
|
|
||||||
_MAKE_NIL(to_val_ptr);
|
|
||||||
step_val_ptr = &step_val;
|
|
||||||
_MAKE_NIL(step_val_ptr);
|
|
||||||
ass_tuple3_ptr = &ass_tuple3;
|
|
||||||
|
|
||||||
result = _execute_statement(s, &ast);
|
|
||||||
if(result != MB_FUNC_OK)
|
|
||||||
goto _exit;
|
|
||||||
ast = ast->prev;
|
|
||||||
|
|
||||||
obj = (_object_t*)ast->data;
|
|
||||||
if(!_IS_FUNC(obj, _core_to)) {
|
|
||||||
_handle_error_on_obj(s, SE_RN_TO_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
ast = ast->next;
|
|
||||||
if(!ast) {
|
|
||||||
_handle_error_on_obj(s, SE_RN_SYNTAX, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
|
||||||
}
|
|
||||||
to_node = ast;
|
|
||||||
|
|
||||||
_to:
|
|
||||||
ast = to_node;
|
|
||||||
|
|
||||||
result = _calc_expression(s, &ast, &to_val_ptr);
|
|
||||||
if(result != MB_FUNC_OK)
|
|
||||||
goto _exit;
|
|
||||||
|
|
||||||
obj = (_object_t*)ast->data;
|
|
||||||
if(!_IS_FUNC(obj, _core_step)) {
|
|
||||||
step_val = _OBJ_INT_UNIT;
|
|
||||||
} else {
|
|
||||||
ast = ast->next;
|
|
||||||
if(!ast) {
|
|
||||||
_handle_error_on_obj(s, SE_RN_SYNTAX, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = _calc_expression(s, &ast, &step_val_ptr);
|
|
||||||
if(result != MB_FUNC_OK)
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((_compare_numbers(step_val_ptr, &_OBJ_INT_ZERO) == 1 && _compare_numbers(var_loop->data, to_val_ptr) == 1) ||
|
|
||||||
(_compare_numbers(step_val_ptr, &_OBJ_INT_ZERO) == -1 && _compare_numbers(var_loop->data, to_val_ptr) == -1)) {
|
|
||||||
/* End looping */
|
|
||||||
if(_skip_struct(s, &ast, _core_for, _core_next) != MB_FUNC_OK)
|
|
||||||
goto _exit;
|
|
||||||
_skip_to(s, &ast, 0, _DT_EOS);
|
|
||||||
|
|
||||||
goto _exit;
|
|
||||||
} else {
|
|
||||||
/* Keep looping */
|
|
||||||
obj = (_object_t*)ast->data;
|
obj = (_object_t*)ast->data;
|
||||||
while(!_IS_FUNC(obj, _core_next)) {
|
while(!_IS_FUNC(obj, _core_next)) {
|
||||||
result = _execute_statement(s, &ast);
|
result = _execute_statement(s, &ast);
|
||||||
@ -8694,6 +8648,85 @@ _to:
|
|||||||
obj = (_object_t*)ast->data;
|
obj = (_object_t*)ast->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
*l = ast;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _execute_normal_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop) {
|
||||||
|
/* Execute normal FOR-TO-STEP-NEXT-routine */
|
||||||
|
int result = MB_FUNC_OK;
|
||||||
|
_ls_node_t* ast = 0;
|
||||||
|
_ls_node_t* to_node = 0;
|
||||||
|
_object_t* obj = 0;
|
||||||
|
_object_t to_val;
|
||||||
|
_object_t step_val;
|
||||||
|
_object_t* to_val_ptr = 0;
|
||||||
|
_object_t* step_val_ptr = 0;
|
||||||
|
_tuple3_t ass_tuple3;
|
||||||
|
_tuple3_t* ass_tuple3_ptr = 0;
|
||||||
|
|
||||||
|
mb_assert(s && l && var_loop);
|
||||||
|
|
||||||
|
ast = *l;
|
||||||
|
|
||||||
|
to_val_ptr = &to_val;
|
||||||
|
_MAKE_NIL(to_val_ptr);
|
||||||
|
step_val_ptr = &step_val;
|
||||||
|
_MAKE_NIL(step_val_ptr);
|
||||||
|
ass_tuple3_ptr = &ass_tuple3;
|
||||||
|
|
||||||
|
/* Get begin value */
|
||||||
|
result = _execute_statement(s, &ast);
|
||||||
|
if(result != MB_FUNC_OK)
|
||||||
|
goto _exit;
|
||||||
|
ast = ast->prev;
|
||||||
|
|
||||||
|
obj = (_object_t*)ast->data;
|
||||||
|
if(!_IS_FUNC(obj, _core_to)) {
|
||||||
|
_handle_error_on_obj(s, SE_RN_TO_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast = ast->next;
|
||||||
|
if(!ast) {
|
||||||
|
_handle_error_on_obj(s, SE_RN_SYNTAX, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
to_node = ast;
|
||||||
|
|
||||||
|
_to:
|
||||||
|
ast = to_node;
|
||||||
|
|
||||||
|
/* Get end value */
|
||||||
|
result = _calc_expression(s, &ast, &to_val_ptr);
|
||||||
|
if(result != MB_FUNC_OK)
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
obj = (_object_t*)ast->data;
|
||||||
|
if(!_IS_FUNC(obj, _core_step)) {
|
||||||
|
step_val = _OBJ_INT_UNIT;
|
||||||
|
} else {
|
||||||
|
ast = ast->next;
|
||||||
|
if(!ast) {
|
||||||
|
_handle_error_on_obj(s, SE_RN_SYNTAX, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get step value */
|
||||||
|
result = _calc_expression(s, &ast, &step_val_ptr);
|
||||||
|
if(result != MB_FUNC_OK)
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((_compare_numbers(step_val_ptr, &_OBJ_INT_ZERO) == 1 && _compare_numbers(var_loop->data, to_val_ptr) == 1) ||
|
||||||
|
(_compare_numbers(step_val_ptr, &_OBJ_INT_ZERO) == -1 && _compare_numbers(var_loop->data, to_val_ptr) == -1)) {
|
||||||
|
/* End looping */
|
||||||
|
_common_end_looping(s, &ast);
|
||||||
|
|
||||||
|
goto _exit;
|
||||||
|
} else {
|
||||||
|
/* Keep looping */
|
||||||
|
_common_keep_looping(s, &ast, var_loop);
|
||||||
|
|
||||||
ass_tuple3.e1 = var_loop->data;
|
ass_tuple3.e1 = var_loop->data;
|
||||||
ass_tuple3.e2 = step_val_ptr;
|
ass_tuple3.e2 = step_val_ptr;
|
||||||
ass_tuple3.e3 = var_loop->data;
|
ass_tuple3.e3 = var_loop->data;
|
||||||
@ -8712,11 +8745,85 @@ _exit:
|
|||||||
int _execute_ranged_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop) {
|
int _execute_ranged_for_loop(mb_interpreter_t* s, _ls_node_t** l, _var_t* var_loop) {
|
||||||
/* Execute ranged FOR-IN-NEXT-routine */
|
/* Execute ranged FOR-IN-NEXT-routine */
|
||||||
int result = MB_FUNC_ERR;
|
int result = MB_FUNC_ERR;
|
||||||
|
_ls_node_t* ast = 0;
|
||||||
|
_object_t* old_val = 0;
|
||||||
|
_object_t range;
|
||||||
|
_ls_node_t* to_node = 0;
|
||||||
|
_object_t* range_ptr;
|
||||||
|
_list_it_t* lit = 0;
|
||||||
|
_dict_it_t* dit = 0;
|
||||||
|
_list_it_t* tlit = 0;
|
||||||
|
_dict_it_t* tdit = 0;
|
||||||
|
|
||||||
mb_assert(s && l && var_loop);
|
mb_assert(s && l && var_loop);
|
||||||
|
|
||||||
/* TODO: Implement me */
|
old_val = var_loop->data;
|
||||||
mb_assert(0 && "Not implemented.");
|
range_ptr = ⦥
|
||||||
|
_MAKE_NIL(range_ptr);
|
||||||
|
|
||||||
|
ast = *l;
|
||||||
|
ast = ast->next;
|
||||||
|
ast = ast->next;
|
||||||
|
if(!ast) {
|
||||||
|
_handle_error_on_obj(s, SE_RN_SYNTAX, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get collection */
|
||||||
|
result = _calc_expression(s, &ast, &range_ptr);
|
||||||
|
if(result != MB_FUNC_OK)
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
/* Create iterator */
|
||||||
|
switch(range_ptr->type) {
|
||||||
|
case _DT_LIST:
|
||||||
|
tlit = lit = _create_list_it(range_ptr->data.list, true);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_DICT:
|
||||||
|
tdit = dit = _create_dict_it(range_ptr->data.dict, true);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_handle_error_on_obj(s, SE_RN_COLLECTION_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
to_node = ast;
|
||||||
|
|
||||||
|
_to:
|
||||||
|
ast = to_node;
|
||||||
|
|
||||||
|
/* Move next */
|
||||||
|
if(lit) lit = _move_list_it_next(lit);
|
||||||
|
else if(dit) dit = _move_dict_it_next(dit);
|
||||||
|
if((lit && _invalid_list_it(lit)) || (dit && _invalid_dict_it(dit))) {
|
||||||
|
_handle_error_on_obj(s, SE_RN_INVALID_ITERATOR, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
if(!lit && !dit) {
|
||||||
|
/* End looping */
|
||||||
|
_common_end_looping(s, &ast);
|
||||||
|
|
||||||
|
goto _exit;
|
||||||
|
} else {
|
||||||
|
/* Assign loop variable */
|
||||||
|
if(lit && lit->curr && lit->curr->data)
|
||||||
|
var_loop->data = (_object_t*)lit->curr->data;
|
||||||
|
else if(dit && dit->curr_node && dit->curr_node->extra)
|
||||||
|
var_loop->data = (_object_t*)dit->curr_node->extra;
|
||||||
|
/* Keep looping */
|
||||||
|
_common_keep_looping(s, &ast, var_loop);
|
||||||
|
|
||||||
|
goto _to;
|
||||||
|
}
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
if(tlit) _destroy_list_it(tlit);
|
||||||
|
else if(tdit) _destroy_dict_it(tdit);
|
||||||
|
switch(range_ptr->type) { _UNREF_COLL(range_ptr) default: /* Do nothing */ break; }
|
||||||
|
|
||||||
|
*l = ast;
|
||||||
|
|
||||||
|
var_loop->data = old_val;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -14033,7 +14140,7 @@ _print:
|
|||||||
_ls_node_t* tsn = _search_identifier_in_class(s, val_ptr->data.instance, _CLASS_TO_STRING_FUNC, 0, 0);
|
_ls_node_t* tsn = _search_identifier_in_class(s, val_ptr->data.instance, _CLASS_TO_STRING_FUNC, 0, 0);
|
||||||
if(tsn) {
|
if(tsn) {
|
||||||
_object_t* tso = (_object_t*)tsn->data;
|
_object_t* tso = (_object_t*)tsn->data;
|
||||||
_ls_node_t* tmp = *l;
|
_ls_node_t* tmp = (_ls_node_t*)*l;
|
||||||
mb_value_t va[1];
|
mb_value_t va[1];
|
||||||
mb_make_nil(va[0]);
|
mb_make_nil(va[0]);
|
||||||
if(_eval_routine(s, &tmp, va, 1, tso->data.routine, 0, 0) == MB_FUNC_OK) {
|
if(_eval_routine(s, &tmp, va, 1, tso->data.routine, 0, 0) == MB_FUNC_OK) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user