+added a CLONE statement/function for collections.
This commit is contained in:
parent
1f56b39a4f
commit
a0aee0f46a
1
HISTORY
1
HISTORY
@ -1,4 +1,5 @@
|
|||||||
Oct. 11 2015
|
Oct. 11 2015
|
||||||
|
Added a CLONE statement/function for collections
|
||||||
Optimized LIST indexing
|
Optimized LIST indexing
|
||||||
Optimized LIST counting
|
Optimized LIST counting
|
||||||
|
|
||||||
|
241
core/my_basic.c
241
core/my_basic.c
@ -818,6 +818,16 @@ static unsigned int _ht_foreach(_ht_node_t* ht, _ht_operation op);
|
|||||||
static unsigned int _ht_count(_ht_node_t* ht);
|
static unsigned int _ht_count(_ht_node_t* ht);
|
||||||
static void _ht_clear(_ht_node_t* ht);
|
static void _ht_clear(_ht_node_t* ht);
|
||||||
static void _ht_destroy(_ht_node_t* ht);
|
static void _ht_destroy(_ht_node_t* ht);
|
||||||
|
#define _HT_FOREACH(H, O, P, E) \
|
||||||
|
do { \
|
||||||
|
_ls_node_t* __bucket = 0; \
|
||||||
|
unsigned int __ul = 0; \
|
||||||
|
for(__ul = 0; __ul < (H)->array_size; ++__ul) { \
|
||||||
|
__bucket = (H)->array[__ul]; \
|
||||||
|
if(__bucket) \
|
||||||
|
_LS_FOREACH(__bucket, O, P, E); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/** Memory manipulations */
|
/** Memory manipulations */
|
||||||
#define _MB_CHECK_MEM_TAG_SIZE(y, s) do { mb_mem_tag_t _tmp = (mb_mem_tag_t)s; if((y)_tmp != s) { mb_assert(0 && "\"mb_mem_tag_t\" is too small."); printf("The type \"mb_mem_tag_t\" is not precise enough to hold the given data, please redefine it!"); } } while(0)
|
#define _MB_CHECK_MEM_TAG_SIZE(y, s) do { mb_mem_tag_t _tmp = (mb_mem_tag_t)s; if((y)_tmp != s) { mb_assert(0 && "\"mb_mem_tag_t\" is too small."); printf("The type \"mb_mem_tag_t\" is not precise enough to hold the given data, please redefine it!"); } } while(0)
|
||||||
@ -953,7 +963,7 @@ static bool_t _destroy_dict_it(_dict_it_t* it);
|
|||||||
static _dict_it_t* _move_dict_it_next(_dict_it_t* it);
|
static _dict_it_t* _move_dict_it_next(_dict_it_t* it);
|
||||||
static void _unref_list(_ref_t* ref, void* data);
|
static void _unref_list(_ref_t* ref, void* data);
|
||||||
static void _unref_dict(_ref_t* ref, void* data);
|
static void _unref_dict(_ref_t* ref, void* data);
|
||||||
static void _push_list(_list_t* coll, mb_value_t* val);
|
static void _push_list(_list_t* coll, mb_value_t* val, _object_t* oarg);
|
||||||
static bool_t _pop_list(_list_t* coll, mb_value_t* val, mb_interpreter_t* s);
|
static bool_t _pop_list(_list_t* coll, mb_value_t* val, mb_interpreter_t* s);
|
||||||
static bool_t _insert_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval);
|
static bool_t _insert_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval);
|
||||||
static bool_t _set_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval);
|
static bool_t _set_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval);
|
||||||
@ -964,13 +974,15 @@ static bool_t _find_list(_list_t* coll, mb_value_t* val);
|
|||||||
static void _clear_list(_list_t* coll);
|
static void _clear_list(_list_t* coll);
|
||||||
static void _sort_list(_list_t* coll);
|
static void _sort_list(_list_t* coll);
|
||||||
static void _invalidate_list_cache(_list_t* coll);
|
static void _invalidate_list_cache(_list_t* coll);
|
||||||
static void _set_dict(_dict_t* coll, mb_value_t* key, mb_value_t *val);
|
static void _set_dict(_dict_t* coll, mb_value_t* key, mb_value_t* val, _object_t* okey, _object_t* oval);
|
||||||
static bool_t _remove_dict(_dict_t* coll, mb_value_t* key);
|
static bool_t _remove_dict(_dict_t* coll, mb_value_t* key);
|
||||||
static bool_t _find_dict(_dict_t* coll, mb_value_t* val, mb_value_t* oval);
|
static bool_t _find_dict(_dict_t* coll, mb_value_t* val, mb_value_t* oval);
|
||||||
static void _clear_dict(_dict_t* coll);
|
static void _clear_dict(_dict_t* coll);
|
||||||
static bool_t _invalid_list_it(_list_it_t* it);
|
static bool_t _invalid_list_it(_list_it_t* it);
|
||||||
static bool_t _invalid_dict_it(_dict_it_t* it);
|
static bool_t _invalid_dict_it(_dict_it_t* it);
|
||||||
static bool_t _assign_with_it(_object_t* tgt, _object_t* src);
|
static bool_t _assign_with_it(_object_t* tgt, _object_t* src);
|
||||||
|
static int _clone_to_list(void* data, void* extra, _list_t* coll);
|
||||||
|
static int _clone_to_dict(void* data, void* extra, _dict_t* coll);
|
||||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
static bool_t _lock_ref_object(_lock_t* lk, _ref_t* ref, void* obj);
|
static bool_t _lock_ref_object(_lock_t* lk, _ref_t* ref, void* obj);
|
||||||
static bool_t _unlock_ref_object(_lock_t* lk, _ref_t* ref, void* obj);
|
static bool_t _unlock_ref_object(_lock_t* lk, _ref_t* ref, void* obj);
|
||||||
@ -1002,12 +1014,13 @@ static _ls_node_t* _search_identifier_in_scope_chain(mb_interpreter_t* s, _runni
|
|||||||
static _array_t* _search_array_in_scope_chain(mb_interpreter_t* s, _array_t* i);
|
static _array_t* _search_array_in_scope_chain(mb_interpreter_t* s, _array_t* i);
|
||||||
static _var_t* _search_var_in_scope_chain(mb_interpreter_t* s, _var_t* i);
|
static _var_t* _search_var_in_scope_chain(mb_interpreter_t* s, _var_t* i);
|
||||||
|
|
||||||
|
static int _clone_object(_object_t* obj, _object_t* tgt);
|
||||||
static int _dispose_object(_object_t* obj);
|
static int _dispose_object(_object_t* obj);
|
||||||
static int _destroy_object(void* data, void* extra);
|
static int _destroy_object(void* data, void* extra);
|
||||||
static int _destroy_object_with_extra(void* data, void* extra);
|
static int _destroy_object_with_extra(void* data, void* extra);
|
||||||
static int _destroy_object_not_compile_time(void* data, void* extra);
|
static int _destroy_object_not_compile_time(void* data, void* extra);
|
||||||
static int _destroy_object_capsule_only(void* data, void* extra);
|
static int _destroy_object_capsule_only(void* data, void* extra);
|
||||||
static int _destroy_object_nothing(void* data, void* extra);
|
static int _do_nothing_on_object(void* data, void* extra);
|
||||||
static int _remove_source_object(void* data, void* extra);
|
static int _remove_source_object(void* data, void* extra);
|
||||||
static int _compare_numbers(const _object_t* first, const _object_t* second);
|
static int _compare_numbers(const _object_t* first, const _object_t* second);
|
||||||
static bool_t _is_internal_object(_object_t* obj);
|
static bool_t _is_internal_object(_object_t* obj);
|
||||||
@ -1178,6 +1191,7 @@ static int _coll_get(mb_interpreter_t* s, void** l);
|
|||||||
static int _coll_set(mb_interpreter_t* s, void** l);
|
static int _coll_set(mb_interpreter_t* s, void** l);
|
||||||
static int _coll_remove(mb_interpreter_t* s, void** l);
|
static int _coll_remove(mb_interpreter_t* s, void** l);
|
||||||
static int _coll_clear(mb_interpreter_t* s, void** l);
|
static int _coll_clear(mb_interpreter_t* s, void** l);
|
||||||
|
static int _coll_clone(mb_interpreter_t* s, void** l);
|
||||||
static int _coll_iterator(mb_interpreter_t* s, void** l);
|
static int _coll_iterator(mb_interpreter_t* s, void** l);
|
||||||
static int _coll_move_next(mb_interpreter_t* s, void** l);
|
static int _coll_move_next(mb_interpreter_t* s, void** l);
|
||||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
@ -1290,6 +1304,7 @@ static const _func_t _coll_libs[] = {
|
|||||||
{ "SET", _coll_set },
|
{ "SET", _coll_set },
|
||||||
{ "REMOVE", _coll_remove },
|
{ "REMOVE", _coll_remove },
|
||||||
{ "CLEAR", _coll_clear },
|
{ "CLEAR", _coll_clear },
|
||||||
|
{ "CLONE", _coll_clone },
|
||||||
{ "ITERATOR", _coll_iterator },
|
{ "ITERATOR", _coll_iterator },
|
||||||
{ "MOVE_NEXT", _coll_move_next }
|
{ "MOVE_NEXT", _coll_move_next }
|
||||||
};
|
};
|
||||||
@ -4030,13 +4045,12 @@ void _unref_dict(_ref_t* ref, void* data) {
|
|||||||
_destroy_dict((_dict_t*)data);
|
_destroy_dict((_dict_t*)data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _push_list(_list_t* coll, mb_value_t* val) {
|
void _push_list(_list_t* coll, mb_value_t* val, _object_t* oarg) {
|
||||||
/* Push a value to a list */
|
/* Push a value to a list */
|
||||||
_object_t* oarg = 0;
|
mb_assert(coll && (val || oarg));
|
||||||
|
|
||||||
mb_assert(coll && val);
|
if(val && !oarg)
|
||||||
|
_create_internal_object_from_public_value(val, &oarg);
|
||||||
_create_internal_object_from_public_value(val, &oarg);
|
|
||||||
_ls_pushback(coll->list, oarg);
|
_ls_pushback(coll->list, oarg);
|
||||||
coll->count++;
|
coll->count++;
|
||||||
|
|
||||||
@ -4231,18 +4245,18 @@ void _invalidate_list_cache(_list_t* coll) {
|
|||||||
coll->cached_index = 0;
|
coll->cached_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _set_dict(_dict_t* coll, mb_value_t* key, mb_value_t *val) {
|
void _set_dict(_dict_t* coll, mb_value_t* key, mb_value_t* val, _object_t* okey, _object_t* oval) {
|
||||||
/* Set an element to a dictionary with a key-value pair */
|
/* Set an element to a dictionary with a key-value pair */
|
||||||
_object_t* okey = 0;
|
|
||||||
_object_t* oval = 0;
|
|
||||||
_ls_node_t* exist = 0;
|
_ls_node_t* exist = 0;
|
||||||
void* data = 0;
|
void* data = 0;
|
||||||
void* extra = 0;
|
void* extra = 0;
|
||||||
|
|
||||||
mb_assert(coll && key && val);
|
mb_assert(coll && (key || okey) && (val || oval));
|
||||||
|
|
||||||
_create_internal_object_from_public_value(key, &okey);
|
if(key && !okey)
|
||||||
_create_internal_object_from_public_value(val, &oval);
|
_create_internal_object_from_public_value(key, &okey);
|
||||||
|
if(val && !oval)
|
||||||
|
_create_internal_object_from_public_value(val, &oval);
|
||||||
exist = _ht_find(coll->dict, okey);
|
exist = _ht_find(coll->dict, okey);
|
||||||
if(exist) {
|
if(exist) {
|
||||||
data = exist->data;
|
data = exist->data;
|
||||||
@ -4353,6 +4367,55 @@ bool_t _assign_with_it(_object_t* tgt, _object_t* src) {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _clone_to_list(void* data, void* extra, _list_t* coll) {
|
||||||
|
/* Clone an object to a list */
|
||||||
|
_object_t* obj = 0;
|
||||||
|
_object_t* tgt = 0;
|
||||||
|
|
||||||
|
mb_assert(data && coll);
|
||||||
|
|
||||||
|
tgt = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||||
|
obj = (_object_t*)data;
|
||||||
|
_clone_object(obj, tgt);
|
||||||
|
_push_list(coll, 0, tgt);
|
||||||
|
if(tgt->type == _DT_LIST)
|
||||||
|
_ref(&tgt->data.list->ref, tgt->data.list);
|
||||||
|
else if(tgt->type == _DT_DICT)
|
||||||
|
_ref(&tgt->data.dict->ref, tgt->data.dict);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _clone_to_dict(void* data, void* extra, _dict_t* coll) {
|
||||||
|
/* Clone a key-value pair to a dictionary */
|
||||||
|
_object_t* kobj = 0;
|
||||||
|
_object_t* ktgt = 0;
|
||||||
|
_object_t* vobj = 0;
|
||||||
|
_object_t* vtgt = 0;
|
||||||
|
|
||||||
|
mb_assert(data && extra && coll);
|
||||||
|
|
||||||
|
ktgt = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||||
|
kobj = (_object_t*)extra;
|
||||||
|
_clone_object(kobj, ktgt);
|
||||||
|
|
||||||
|
vtgt = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||||
|
vobj = (_object_t*)data;
|
||||||
|
_clone_object(vobj, vtgt);
|
||||||
|
|
||||||
|
_set_dict(coll, 0, 0, ktgt, vtgt);
|
||||||
|
if(ktgt->type == _DT_LIST)
|
||||||
|
_ref(&ktgt->data.list->ref, ktgt->data.list);
|
||||||
|
else if(ktgt->type == _DT_DICT)
|
||||||
|
_ref(&ktgt->data.dict->ref, ktgt->data.dict);
|
||||||
|
if(vtgt->type == _DT_LIST)
|
||||||
|
_ref(&vtgt->data.list->ref, vtgt->data.list);
|
||||||
|
else if(vtgt->type == _DT_DICT)
|
||||||
|
_ref(&vtgt->data.dict->ref, vtgt->data.dict);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
|
|
||||||
bool_t _lock_ref_object(_lock_t* lk, _ref_t* ref, void* obj) {
|
bool_t _lock_ref_object(_lock_t* lk, _ref_t* ref, void* obj) {
|
||||||
@ -4592,7 +4655,7 @@ _running_context_t* _reference_scope(mb_interpreter_t* s, _running_context_t* p,
|
|||||||
result->ref = p;
|
result->ref = p;
|
||||||
if(r && r->parameters) {
|
if(r && r->parameters) {
|
||||||
result->var_dict = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
result->var_dict = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
||||||
_LS_FOREACH(r->parameters, _destroy_object_nothing, _duplicate_parameter, result);
|
_LS_FOREACH(r->parameters, _do_nothing_on_object, _duplicate_parameter, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -4735,6 +4798,99 @@ _var_t* _search_var_in_scope_chain(mb_interpreter_t* s, _var_t* i) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _clone_object(_object_t* obj, _object_t* tgt) {
|
||||||
|
/* Clone the data of an object */
|
||||||
|
int result = 0;
|
||||||
|
_var_t* var = 0;
|
||||||
|
|
||||||
|
mb_assert(obj && tgt);
|
||||||
|
|
||||||
|
memset(tgt, 0, sizeof(_object_t));
|
||||||
|
tgt->type = _DT_NIL;
|
||||||
|
if(_is_internal_object(obj))
|
||||||
|
goto _exit;
|
||||||
|
tgt->type = obj->type;
|
||||||
|
switch(obj->type) {
|
||||||
|
case _DT_VAR:
|
||||||
|
_clone_object(obj->data.variable->data, tgt);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_STRING:
|
||||||
|
tgt->data.string = mb_memdup(obj->data.string, (unsigned)strlen(obj->data.string) + 1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_FUNC:
|
||||||
|
tgt->data.func->name = mb_memdup(obj->data.func->name, (unsigned)strlen(obj->data.func->name) + 1);
|
||||||
|
tgt->data.func->pointer = obj->data.func->pointer;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_ARRAY:
|
||||||
|
tgt->data.array = obj->data.array;
|
||||||
|
|
||||||
|
break;
|
||||||
|
#ifdef MB_ENABLE_COLLECTION_LIB
|
||||||
|
case _DT_LIST:
|
||||||
|
tgt->data.list = _create_list();
|
||||||
|
_LS_FOREACH(obj->data.list->list, _do_nothing_on_object, _clone_to_list, tgt->data.list);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_LIST_IT:
|
||||||
|
tgt->data.list_it = _create_list_it(obj->data.list_it->list, false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_DICT:
|
||||||
|
tgt->data.dict = _create_dict();
|
||||||
|
_HT_FOREACH(obj->data.dict->dict, _do_nothing_on_object, _clone_to_dict, tgt->data.dict);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_DICT_IT:
|
||||||
|
tgt->data.dict_it = _create_dict_it(obj->data.dict_it->dict, false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
|
case _DT_LABEL:
|
||||||
|
tgt->data.label->name = mb_memdup(obj->data.label->name, (unsigned)strlen(obj->data.label->name) + 1);
|
||||||
|
tgt->data.label->node = obj->data.label->node;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_CLASS:
|
||||||
|
mb_assert(0 && "Not implemented");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_ROUTINE:
|
||||||
|
mb_assert(0 && "Not implemented");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _DT_TYPE: /* Fall through */
|
||||||
|
case _DT_NIL: /* Fall through */
|
||||||
|
case _DT_ANY: /* Fall through */
|
||||||
|
case _DT_INT: /* Fall through */
|
||||||
|
case _DT_REAL: /* Fall through */
|
||||||
|
case _DT_SEP: /* Fall through */
|
||||||
|
case _DT_EOS: /* Fall through */
|
||||||
|
case _DT_USERTYPE:
|
||||||
|
tgt->data = obj->data;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mb_assert(0 && "Invalid type");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tgt->ref = false;
|
||||||
|
#ifdef MB_ENABLE_SOURCE_TRACE
|
||||||
|
tgt->source_pos = 0;
|
||||||
|
tgt->source_row = 0;
|
||||||
|
tgt->source_col = 0;
|
||||||
|
#else /* MB_ENABLE_SOURCE_TRACE */
|
||||||
|
tgt->source_pos = 0;
|
||||||
|
#endif /* MB_ENABLE_SOURCE_TRACE */
|
||||||
|
++result;
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int _dispose_object(_object_t* obj) {
|
int _dispose_object(_object_t* obj) {
|
||||||
/* Dispose the data of an object */
|
/* Dispose the data of an object */
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -4928,7 +5084,7 @@ int _destroy_object_capsule_only(void* data, void* extra) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _destroy_object_nothing(void* data, void* extra) {
|
int _do_nothing_on_object(void* data, void* extra) {
|
||||||
/* Do nothing with an object, this is a helper function */
|
/* Do nothing with an object, this is a helper function */
|
||||||
int result = _OP_RESULT_NORMAL;
|
int result = _OP_RESULT_NORMAL;
|
||||||
|
|
||||||
@ -9222,7 +9378,7 @@ int _coll_list(mb_interpreter_t* s, void** l) {
|
|||||||
_handle_error_on_obj(s, SE_RN_TYPE_NOT_MATCH, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_TYPE_NOT_MATCH, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
_push_list(coll, &arg);
|
_push_list(coll, &arg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mb_check(mb_attempt_close_bracket(s, l));
|
mb_check(mb_attempt_close_bracket(s, l));
|
||||||
@ -9257,7 +9413,7 @@ int _coll_dict(mb_interpreter_t* s, void** l) {
|
|||||||
_handle_error_on_obj(s, SE_RN_TYPE_NOT_MATCH, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_TYPE_NOT_MATCH, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_dict(coll, &arg, &val);
|
_set_dict(coll, &arg, &val, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mb_check(mb_attempt_close_bracket(s, l));
|
mb_check(mb_attempt_close_bracket(s, l));
|
||||||
@ -9294,7 +9450,7 @@ int _coll_push(mb_interpreter_t* s, void** l) {
|
|||||||
_handle_error_on_obj(s, SE_RN_TYPE_NOT_MATCH, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_TYPE_NOT_MATCH, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
_push_list(olst.data.list, &arg);
|
_push_list(olst.data.list, &arg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mb_check(mb_attempt_close_bracket(s, l));
|
mb_check(mb_attempt_close_bracket(s, l));
|
||||||
@ -9605,7 +9761,7 @@ int _coll_set(mb_interpreter_t* s, void** l) {
|
|||||||
_handle_error_on_obj(s, SE_RN_TYPE_NOT_MATCH, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_TYPE_NOT_MATCH, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_dict(ocoll.data.dict, &key, &val);
|
_set_dict(ocoll.data.dict, &key, &val, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -9716,6 +9872,51 @@ _exit:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _coll_clone(mb_interpreter_t* s, void** l) {
|
||||||
|
/* CLONE statement */
|
||||||
|
int result = MB_FUNC_OK;
|
||||||
|
mb_value_t coll;
|
||||||
|
_object_t ocoll;
|
||||||
|
_object_t otgt;
|
||||||
|
mb_value_t ret;
|
||||||
|
|
||||||
|
mb_assert(s && l);
|
||||||
|
|
||||||
|
mb_check(mb_attempt_open_bracket(s, l));
|
||||||
|
|
||||||
|
mb_check(mb_pop_value(s, l, &coll));
|
||||||
|
|
||||||
|
mb_check(mb_attempt_close_bracket(s, l));
|
||||||
|
|
||||||
|
switch(coll.type) {
|
||||||
|
case MB_DT_LIST:
|
||||||
|
_public_value_to_internal_object(&coll, &ocoll);
|
||||||
|
_clone_object(&ocoll, &otgt);
|
||||||
|
ret.type = MB_DT_LIST;
|
||||||
|
ret.value.list = otgt.data.list;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MB_DT_DICT:
|
||||||
|
_public_value_to_internal_object(&coll, &ocoll);
|
||||||
|
_clone_object(&ocoll, &otgt);
|
||||||
|
ret.type = MB_DT_DICT;
|
||||||
|
ret.value.dict = otgt.data.dict;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_handle_error_on_obj(s, SE_RN_COLLECTION_EXPECTED, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mb_check(mb_push_value(s, l, ret));
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
_assign_public_value(&coll, 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int _coll_iterator(mb_interpreter_t* s, void** l) {
|
int _coll_iterator(mb_interpreter_t* s, void** l) {
|
||||||
/* ITERATOR statement */
|
/* ITERATOR statement */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user