+added an IN keyword; +added support to loop on collections by using FOR-IN statement.

This commit is contained in:
paladin-t 2016-01-22 19:26:36 +08:00
parent c684f3fcef
commit d344b05d68
3 changed files with 152 additions and 43 deletions

View File

@ -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.

View File

@ -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) {