*fixed a multiple disposing bug with expression calculation; *improved array handling.

This commit is contained in:
paladin-t 2015-12-29 12:37:28 +08:00
parent 545b96b669
commit 1d470685cc
2 changed files with 43 additions and 18 deletions

View File

@ -1,5 +1,7 @@
Dec. 29 2015 Dec. 29 2015
Fixed a multiple disposing bug with expression calculation
Improved GC with an array Improved GC with an array
Improved array handling
Polished array manipulation code Polished array manipulation code
Dec. 28 2015 Dec. 28 2015

View File

@ -124,6 +124,7 @@ extern "C" {
#endif /* toupper */ #endif /* toupper */
#define _copy_bytes(__l, __r) do { memcpy((__l), (__r), sizeof(mb_val_bytes_t)); } while(0) #define _copy_bytes(__l, __r) do { memcpy((__l), (__r), sizeof(mb_val_bytes_t)); } while(0)
#define _cmp_bytes(__l, __r) (memcmp((__l), (__r), sizeof(mb_val_bytes_t)))
#define _mb_check(__expr, __exit) do { if((__expr) != MB_FUNC_OK) goto __exit; } while(0) #define _mb_check(__expr, __exit) do { if((__expr) != MB_FUNC_OK) goto __exit; } while(0)
@ -1224,7 +1225,7 @@ static _array_t* _create_array(const char* n, _data_e t, mb_interpreter_t* s);
static void _destroy_array(_array_t* arr); static void _destroy_array(_array_t* arr);
static void _init_array(_array_t* arr); static void _init_array(_array_t* arr);
static int _get_array_pos(struct mb_interpreter_t* s, _array_t* arr, int* d, int c); static int _get_array_pos(struct mb_interpreter_t* s, _array_t* arr, int* d, int c);
static int _get_array_index(mb_interpreter_t* s, _ls_node_t** l, unsigned int* index, bool_t* literally); static int _get_array_index(mb_interpreter_t* s, _ls_node_t** l, _object_t* c, unsigned int* index, bool_t* literally);
static bool_t _get_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, mb_value_u* val, _data_e* type); static bool_t _get_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, mb_value_u* val, _data_e* type);
static int _set_array_elem(mb_interpreter_t* s, _ls_node_t* ast, _array_t* arr, unsigned int index, mb_value_u* val, _data_e* type); static int _set_array_elem(mb_interpreter_t* s, _ls_node_t* ast, _array_t* arr, unsigned int index, mb_value_u* val, _data_e* type);
static void _clear_array(_array_t* arr); static void _clear_array(_array_t* arr);
@ -1325,6 +1326,7 @@ static mb_data_e _internal_type_to_public_type(_data_e t);
static int _public_value_to_internal_object(mb_value_t* pbl, _object_t* itn); static int _public_value_to_internal_object(mb_value_t* pbl, _object_t* itn);
static int _internal_object_to_public_value(_object_t* itn, mb_value_t* pbl); static int _internal_object_to_public_value(_object_t* itn, mb_value_t* pbl);
static int _create_internal_object_from_public_value(mb_value_t* pbl, _object_t** itn); static int _create_internal_object_from_public_value(mb_value_t* pbl, _object_t** itn);
static int _compare_public_value_and_internal_object(mb_value_t* pbl, _object_t* itn);
static void _try_clear_intermediate_value(void* data, void* extra, mb_interpreter_t* s); static void _try_clear_intermediate_value(void* data, void* extra, mb_interpreter_t* s);
static void _mark_lazy_destroy_string(mb_interpreter_t* s, char* ch); static void _mark_lazy_destroy_string(mb_interpreter_t* s, char* ch);
static void _assign_public_value(mb_value_t* tgt, mb_value_t* src); static void _assign_public_value(mb_value_t* tgt, mb_value_t* src);
@ -2696,12 +2698,13 @@ int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val) {
} }
} else { } else {
if(c->type == _DT_ARRAY) { if(c->type == _DT_ARRAY) {
_array:
if(ast && !_IS_FUNC(((_object_t*)(ast->data)), _core_open_bracket)) { if(ast && !_IS_FUNC(((_object_t*)(ast->data)), _core_open_bracket)) {
_ls_pushback(opnd, c); _ls_pushback(opnd, c);
f++; f++;
} else { } else {
ast = ast->prev; ast = ast->prev;
result = _get_array_index(s, &ast, &arr_idx, 0); result = _get_array_index(s, &ast, c, &arr_idx, 0);
if(result != MB_FUNC_OK) { if(result != MB_FUNC_OK) {
_handle_error_on_obj(s, SE_RN_CALCULATION_ERROR, 0, DON(ast), MB_FUNC_ERR, _exit, result); _handle_error_on_obj(s, SE_RN_CALCULATION_ERROR, 0, DON(ast), MB_FUNC_ERR, _exit, result);
} }
@ -2743,6 +2746,13 @@ int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val) {
if(f) { if(f) {
_handle_error_on_obj(s, SE_RN_OPERATOR_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result); _handle_error_on_obj(s, SE_RN_OPERATOR_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
} }
if(_is_array(c)) {
goto _array;
} else {
if(_IS_FUNC(ast->data, _core_open_bracket)) {
_handle_error_on_obj(s, SE_RN_SYNTAX, 0, DON(ast), MB_FUNC_ERR, _exit, result);
}
}
_ls_pushback(opnd, c); _ls_pushback(opnd, c);
f++; f++;
} else if(c->type == _DT_ROUTINE) { } else if(c->type == _DT_ROUTINE) {
@ -2767,7 +2777,7 @@ _routine:
f++; f++;
} else if(c->type == _DT_VAR && c->data.variable->data->type == _DT_ARRAY) { } else if(c->type == _DT_VAR && c->data.variable->data->type == _DT_ARRAY) {
ast = ast->prev; ast = ast->prev;
result = _get_array_index(s, &ast, &arr_idx, 0); result = _get_array_index(s, &ast, 0, &arr_idx, 0);
if(result != MB_FUNC_OK) { if(result != MB_FUNC_OK) {
_handle_error_on_obj(s, SE_RN_CALCULATION_ERROR, 0, DON(ast), MB_FUNC_ERR, _exit, result); _handle_error_on_obj(s, SE_RN_CALCULATION_ERROR, 0, DON(ast), MB_FUNC_ERR, _exit, result);
} }
@ -4722,7 +4732,7 @@ _exit:
return result; return result;
} }
int _get_array_index(mb_interpreter_t* s, _ls_node_t** l, unsigned int* index, bool_t* literally) { int _get_array_index(mb_interpreter_t* s, _ls_node_t** l, _object_t* c, unsigned int* index, bool_t* literally) {
/* Calculate the index, used when walking through an AST */ /* Calculate the index, used when walking through an AST */
int result = MB_FUNC_OK; int result = MB_FUNC_OK;
_ls_node_t* ast = 0; _ls_node_t* ast = 0;
@ -4743,13 +4753,15 @@ int _get_array_index(mb_interpreter_t* s, _ls_node_t** l, unsigned int* index, b
/* Array name */ /* Array name */
ast = (_ls_node_t*)(*l); ast = (_ls_node_t*)(*l);
if(!ast || !_is_array(ast->data)) { if(!c && ast && _is_array(ast->data))
c = (_object_t*)ast->data;
if(!_is_array(c)) {
_handle_error_on_obj(s, SE_RN_ARRAY_IDENTIFIER_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result); _handle_error_on_obj(s, SE_RN_ARRAY_IDENTIFIER_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
} }
if(((_object_t*)(ast->data))->type == _DT_ARRAY) if(((_object_t*)c)->type == _DT_ARRAY)
arr = (_object_t*)(ast->data); arr = (_object_t*)c;
else else
arr = ((_object_t*)(ast->data))->data.variable->data; arr = ((_object_t*)c)->data.variable->data;
/* = */ /* = */
if(literally && ast->next && _IS_FUNC((_object_t*)(ast->next->data), _core_equal)) { if(literally && ast->next && _IS_FUNC((_object_t*)(ast->next->data), _core_equal)) {
*literally = true; *literally = true;
@ -4947,12 +4959,10 @@ bool_t _is_array(void* obj) {
bool_t result = false; bool_t result = false;
_object_t* o = 0; _object_t* o = 0;
mb_assert(obj);
o = (_object_t*)obj; o = (_object_t*)obj;
if(o->type == _DT_ARRAY) if(o && o->type == _DT_ARRAY)
result = true; result = true;
else if(o->type == _DT_VAR) else if(o && o->type == _DT_VAR)
result = o->data.variable->data->type == _DT_ARRAY; result = o->data.variable->data->type == _DT_ARRAY;
return result; return result;
@ -6830,6 +6840,22 @@ int _create_internal_object_from_public_value(mb_value_t* pbl, _object_t** itn)
return result; return result;
} }
int _compare_public_value_and_internal_object(mb_value_t* pbl, _object_t* itn) {
/* Compare a public value and an internal object */
int result = 0;
mb_value_t tmp;
mb_make_nil(tmp);
_internal_object_to_public_value(itn, &tmp);
if(pbl->type != tmp.type) {
result = pbl->type - tmp.type;
} else {
result = _cmp_bytes(pbl->value.bytes, tmp.value.bytes);
}
return result;
}
void _try_clear_intermediate_value(void* data, void* extra, mb_interpreter_t* s) { void _try_clear_intermediate_value(void* data, void* extra, mb_interpreter_t* s) {
/* Try clear the intermediate value when destroying an object */ /* Try clear the intermediate value when destroying an object */
_object_t* obj = 0; _object_t* obj = 0;
@ -6844,7 +6870,7 @@ void _try_clear_intermediate_value(void* data, void* extra, mb_interpreter_t* s)
obj = (_object_t*)data; obj = (_object_t*)data;
running = s->running_context; running = s->running_context;
if(obj->type == _DT_STRING && running->intermediate_value.type == MB_DT_STRING && obj->data.string == running->intermediate_value.value.string) { if(!_compare_public_value_and_internal_object(&running->intermediate_value, obj)) {
mb_make_nil(running->intermediate_value); mb_make_nil(running->intermediate_value);
} }
} }
@ -8014,9 +8040,6 @@ int mb_attempt_close_bracket(struct mb_interpreter_t* s, void** l) {
_handle_error_on_obj(s, SE_RN_CLOSE_BRACKET_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result); _handle_error_on_obj(s, SE_RN_CLOSE_BRACKET_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
} }
ast = ast->next; ast = ast->next;
if(_IS_FUNC(ast->data, _core_open_bracket)) {
_handle_error_on_obj(s, SE_RN_SYNTAX, 0, DON(ast), MB_FUNC_ERR, _exit, result);
}
_exit: _exit:
*l = ast; *l = ast;
@ -9991,13 +10014,13 @@ int _core_let(mb_interpreter_t* s, void** l) {
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);
result = _get_array_index(s, &ast, &arr_idx, &literally); result = _get_array_index(s, &ast, 0, &arr_idx, &literally);
if(result != MB_FUNC_OK) if(result != MB_FUNC_OK)
goto _exit; goto _exit;
} else if(obj->type == _DT_VAR && obj->data.variable->data->type == _DT_ARRAY) { } else if(obj->type == _DT_VAR && obj->data.variable->data->type == _DT_ARRAY) {
arr_obj = obj->data.variable->data; arr_obj = obj->data.variable->data;
arr = _search_array_in_scope_chain(s, obj->data.variable->data->data.array, &arr_obj); arr = _search_array_in_scope_chain(s, obj->data.variable->data->data.array, &arr_obj);
result = _get_array_index(s, &ast, &arr_idx, &literally); result = _get_array_index(s, &ast, 0, &arr_idx, &literally);
if(result != MB_FUNC_OK) if(result != MB_FUNC_OK)
goto _exit; goto _exit;
} else if(obj->type == _DT_VAR) { } else if(obj->type == _DT_VAR) {