+added support to apply the LEN statement to variable arguments as LEN(...).
This commit is contained in:
parent
891c601b35
commit
40e79143b1
3
HISTORY
3
HISTORY
@ -1,3 +1,6 @@
|
||||
Jan. 19 2016
|
||||
Added support to apply the LEN statement to variable arguments as LEN(...)
|
||||
|
||||
Jan. 18 2016
|
||||
Added variable arguments support
|
||||
Added a NOW statement to the shell
|
||||
|
242
core/my_basic.c
242
core/my_basic.c
@ -994,6 +994,7 @@ static unsigned int _ls_remove(_ls_node_t* list, _ls_node_t* node, _ls_operation
|
||||
static unsigned int _ls_try_remove(_ls_node_t* list, void* info, _ls_compare cmp, _ls_operation op);
|
||||
static unsigned int _ls_foreach(_ls_node_t* list, _ls_operation op);
|
||||
static void _ls_sort(_ls_node_t* list, _ls_compare cmp);
|
||||
static int _ls_count(_ls_node_t* list);
|
||||
static bool_t _ls_empty(_ls_node_t* list);
|
||||
static void _ls_clear(_ls_node_t* list);
|
||||
static void _ls_destroy(_ls_node_t* list);
|
||||
@ -1020,6 +1021,7 @@ static int _ls_free_extra(void* data, void* extra);
|
||||
__lst->prev = __tmp->prev; \
|
||||
} \
|
||||
safe_free(__tmp); \
|
||||
(L)->data = (char*)(L)->data - 1; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
@ -1704,6 +1706,7 @@ static int _std_right(mb_interpreter_t* s, void** l);
|
||||
static int _std_str(mb_interpreter_t* s, void** l);
|
||||
static int _std_val(mb_interpreter_t* s, void** l);
|
||||
static int _std_len(mb_interpreter_t* s, void** l);
|
||||
static int _std_get(mb_interpreter_t* s, void** l);
|
||||
static int _std_print(mb_interpreter_t* s, void** l);
|
||||
static int _std_input(mb_interpreter_t* s, void** l);
|
||||
|
||||
@ -1717,7 +1720,6 @@ static int _coll_peek(mb_interpreter_t* s, void** l);
|
||||
static int _coll_insert(mb_interpreter_t* s, void** l);
|
||||
static int _coll_sort(mb_interpreter_t* s, void** l);
|
||||
static int _coll_exist(mb_interpreter_t* s, void** l);
|
||||
static int _coll_get(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_clear(mb_interpreter_t* s, void** l);
|
||||
@ -1829,6 +1831,7 @@ static const _func_t _std_libs[] = {
|
||||
{ "VAL", _std_val },
|
||||
|
||||
{ "LEN", _std_len },
|
||||
{ "GET", _std_get },
|
||||
|
||||
{ "PRINT", _std_print },
|
||||
{ "INPUT", _std_input }
|
||||
@ -1844,7 +1847,6 @@ static const _func_t _coll_libs[] = {
|
||||
{ "INSERT", _coll_insert },
|
||||
{ "SORT", _coll_sort },
|
||||
{ "EXIST", _coll_exist },
|
||||
{ "GET", _coll_get },
|
||||
{ "SET", _coll_set },
|
||||
{ "REMOVE", _coll_remove },
|
||||
{ "CLEAR", _coll_clear },
|
||||
@ -1956,6 +1958,7 @@ _ls_node_t* _ls_pushback(_ls_node_t* list, void* data) {
|
||||
tmp->next = result;
|
||||
result->prev = tmp;
|
||||
list->prev = result;
|
||||
list->data = (char*)list->data + 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1975,6 +1978,7 @@ void* _ls_popback(_ls_node_t* list) {
|
||||
list->prev = 0;
|
||||
tmp->prev->next = 0;
|
||||
safe_free(tmp);
|
||||
list->data = (char*)list->data - 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -2004,6 +2008,7 @@ void* _ls_popfront(_ls_node_t* list) {
|
||||
list->prev = 0;
|
||||
tmp->prev = tmp->next = 0;
|
||||
safe_free(tmp);
|
||||
list->data = (char*)list->data - 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -2030,6 +2035,7 @@ _ls_node_t* _ls_insert_at(_ls_node_t* list, int index, void* data) {
|
||||
result->next = tmp;
|
||||
tmp->prev = result;
|
||||
}
|
||||
list->data = (char*)list->data + 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -2051,6 +2057,7 @@ unsigned int _ls_remove(_ls_node_t* list, _ls_node_t* node, _ls_operation op) {
|
||||
op(node->data, node->extra);
|
||||
safe_free(node);
|
||||
++result;
|
||||
list->data = (char*)list->data - 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -2076,6 +2083,7 @@ unsigned int _ls_try_remove(_ls_node_t* list, void* info, _ls_compare cmp, _ls_o
|
||||
op(tmp->data, tmp->extra);
|
||||
safe_free(tmp);
|
||||
++result;
|
||||
list->data = (char*)list->data - 1;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -2088,24 +2096,26 @@ unsigned int _ls_try_remove(_ls_node_t* list, void* info, _ls_compare cmp, _ls_o
|
||||
unsigned int _ls_foreach(_ls_node_t* list, _ls_operation op) {
|
||||
unsigned int idx = 0;
|
||||
int opresult = _OP_RESULT_NORMAL;
|
||||
_ls_node_t* node = 0;
|
||||
_ls_node_t* tmp = 0;
|
||||
|
||||
mb_assert(list && op);
|
||||
|
||||
list = list->next;
|
||||
while(list) {
|
||||
opresult = op(list->data, list->extra);
|
||||
node = list->next;
|
||||
while(node) {
|
||||
opresult = op(node->data, node->extra);
|
||||
++idx;
|
||||
tmp = list;
|
||||
list = list->next;
|
||||
tmp = node;
|
||||
node = node->next;
|
||||
|
||||
if(_OP_RESULT_NORMAL == opresult) {
|
||||
/* Do nothing */
|
||||
} else if(_OP_RESULT_DEL_NODE == opresult) {
|
||||
tmp->prev->next = list;
|
||||
if(list)
|
||||
list->prev = tmp->prev;
|
||||
tmp->prev->next = node;
|
||||
if(node)
|
||||
node->prev = tmp->prev;
|
||||
safe_free(tmp);
|
||||
list->data = (char*)list->data - 1;
|
||||
} else {
|
||||
/* Do nothing */
|
||||
}
|
||||
@ -2132,6 +2142,14 @@ void _ls_sort(_ls_node_t* list, _ls_compare cmp) {
|
||||
}
|
||||
}
|
||||
|
||||
int _ls_count(_ls_node_t* list) {
|
||||
union { void* p; unsigned u; } tmp;
|
||||
|
||||
tmp.p = list->data;
|
||||
|
||||
return tmp.u;
|
||||
}
|
||||
|
||||
bool_t _ls_empty(_ls_node_t* list) {
|
||||
bool_t result = false;
|
||||
|
||||
@ -2147,6 +2165,8 @@ void _ls_clear(_ls_node_t* list) {
|
||||
|
||||
mb_assert(list);
|
||||
|
||||
list->data = 0;
|
||||
|
||||
tmp = list;
|
||||
list = list->next;
|
||||
tmp->next = 0;
|
||||
@ -5972,7 +5992,7 @@ bool_t _at_list(_list_t* coll, int_t idx, mb_value_t* oval) {
|
||||
|
||||
mb_assert(coll && oval);
|
||||
|
||||
result = _node_at_list(coll, idx);
|
||||
result = _node_at_list(coll, (int)idx);
|
||||
if(oval && result && result->data)
|
||||
_internal_object_to_public_value((_object_t*)result->data, oval);
|
||||
|
||||
@ -13363,7 +13383,7 @@ int _std_left(mb_interpreter_t* s, void** l) {
|
||||
}
|
||||
|
||||
#ifdef MB_ENABLE_UNICODE
|
||||
switch(mb_uu_substr(arg, 0, count, &sub)) {
|
||||
switch(mb_uu_substr(arg, 0, (int)count, &sub)) {
|
||||
case 0:
|
||||
_handle_error_on_obj(s, SE_RN_INVALID_STRING, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
|
||||
@ -13409,7 +13429,7 @@ int _std_mid(mb_interpreter_t* s, void** l) {
|
||||
}
|
||||
|
||||
#ifdef MB_ENABLE_UNICODE
|
||||
switch(mb_uu_substr(arg, start, count, &sub)) {
|
||||
switch(mb_uu_substr(arg, start, (int)count, &sub)) {
|
||||
case 0:
|
||||
_handle_error_on_obj(s, SE_RN_INVALID_STRING, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
|
||||
@ -13453,7 +13473,7 @@ int _std_right(mb_interpreter_t* s, void** l) {
|
||||
}
|
||||
|
||||
#ifdef MB_ENABLE_UNICODE
|
||||
switch(mb_uu_substr(arg, mb_uu_strlen(arg) - count, count, &sub)) {
|
||||
switch(mb_uu_substr(arg, (int)(mb_uu_strlen(arg) - count), (int)count, &sub)) {
|
||||
case 0:
|
||||
_handle_error_on_obj(s, SE_RN_INVALID_STRING, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
|
||||
@ -13574,6 +13594,7 @@ int _std_len(mb_interpreter_t* s, void** l) {
|
||||
/* Get the length of a string or an array */
|
||||
int result = MB_FUNC_OK;
|
||||
_ls_node_t* ast = 0;
|
||||
_object_t* obj = 0;
|
||||
mb_value_t arg;
|
||||
_array_t* arr = 0;
|
||||
#ifdef MB_ENABLE_COLLECTION_LIB
|
||||
@ -13585,10 +13606,19 @@ int _std_len(mb_interpreter_t* s, void** l) {
|
||||
|
||||
mb_make_nil(arg);
|
||||
|
||||
ast = (_ls_node_t*)*l;
|
||||
|
||||
mb_check(mb_attempt_open_bracket(s, l));
|
||||
|
||||
ast = (_ls_node_t*)*l;
|
||||
if(ast) obj = (_object_t*)ast->data;
|
||||
if(obj && _IS_FUNC(obj, _core_args)) {
|
||||
ast = ast->next;
|
||||
*l = ast;
|
||||
mb_check(mb_push_int(s, l, (int_t)_ls_count(s->var_args)));
|
||||
|
||||
mb_check(mb_attempt_close_bracket(s, l));
|
||||
|
||||
goto _exit;
|
||||
}
|
||||
mb_check(mb_pop_value(s, l, &arg));
|
||||
|
||||
mb_check(mb_attempt_close_bracket(s, l));
|
||||
@ -13631,6 +13661,98 @@ _exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
int _std_get(mb_interpreter_t* s, void** l) {
|
||||
/* GET statement */
|
||||
int result = MB_FUNC_OK;
|
||||
mb_value_t coi;
|
||||
mb_value_t arg;
|
||||
_object_t ocoi;
|
||||
#ifdef MB_ENABLE_COLLECTION_LIB
|
||||
int_t index = 0;
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
char* field = 0;
|
||||
_ls_node_t* fnode = 0;
|
||||
_object_t* fobj = 0;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
mb_value_t ret;
|
||||
|
||||
mb_assert(s && l);
|
||||
|
||||
mb_make_nil(coi);
|
||||
mb_make_nil(arg);
|
||||
mb_make_nil(ret);
|
||||
|
||||
mb_check(mb_attempt_open_bracket(s, l));
|
||||
|
||||
mb_check(mb_pop_value(s, l, &coi));
|
||||
_MAKE_NIL(&ocoi);
|
||||
switch(coi.type) {
|
||||
#ifdef MB_ENABLE_COLLECTION_LIB
|
||||
case MB_DT_LIST:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
mb_check(mb_pop_int(s, l, &index));
|
||||
if(!_at_list(ocoi.data.list, index, &ret)) {
|
||||
_handle_error_on_obj(s, SE_RN_CANNOT_FIND_WITH_GIVEN_INDEX, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
|
||||
break;
|
||||
case MB_DT_DICT:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
mb_check(mb_pop_value(s, l, &arg));
|
||||
if(!_find_dict(ocoi.data.dict, &arg, &ret)) {
|
||||
_handle_error_on_obj(s, SE_RN_CANNOT_FIND_WITH_GIVEN_INDEX, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
|
||||
break;
|
||||
case MB_DT_LIST_IT:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
if(ocoi.data.list_it && ocoi.data.list_it->curr && ocoi.data.list_it->curr->data) {
|
||||
_internal_object_to_public_value((_object_t*)ocoi.data.list_it->curr->data, &ret);
|
||||
} else {
|
||||
_handle_error_on_obj(s, SE_RN_INVALID_ITERATOR, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
|
||||
break;
|
||||
case MB_DT_DICT_IT:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
if(ocoi.data.dict_it && ocoi.data.dict_it->curr_node && ocoi.data.dict_it->curr_node->extra) {
|
||||
_internal_object_to_public_value((_object_t*)ocoi.data.dict_it->curr_node->extra, &ret);
|
||||
} else {
|
||||
_handle_error_on_obj(s, SE_RN_INVALID_ITERATOR, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case MB_DT_CLASS:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
mb_check(mb_pop_string(s, l, &field));
|
||||
field = mb_strupr(field);
|
||||
fnode = _search_identifier_in_class(s, ocoi.data.instance, field, 0, 0);
|
||||
if(fnode && fnode->data) {
|
||||
fobj = (_object_t*)fnode->data;
|
||||
_internal_object_to_public_value(fobj, &ret);
|
||||
}
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
default:
|
||||
_handle_error_on_obj(s, SE_RN_COLLECTION_OR_ITERATOR_EXPECTED, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mb_check(mb_attempt_close_bracket(s, l));
|
||||
|
||||
mb_check(mb_push_value(s, l, ret));
|
||||
|
||||
_exit:
|
||||
_assign_public_value(&coi, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int _std_print(mb_interpreter_t* s, void** l) {
|
||||
/* PRINT statement */
|
||||
int result = MB_FUNC_OK;
|
||||
@ -14165,94 +14287,6 @@ _exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
int _coll_get(mb_interpreter_t* s, void** l) {
|
||||
/* GET statement */
|
||||
int result = MB_FUNC_OK;
|
||||
mb_value_t coi;
|
||||
int_t index = 0;
|
||||
mb_value_t arg;
|
||||
_object_t ocoi;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
char* field = 0;
|
||||
_ls_node_t* fnode = 0;
|
||||
_object_t* fobj = 0;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
mb_value_t ret;
|
||||
|
||||
mb_assert(s && l);
|
||||
|
||||
mb_make_nil(coi);
|
||||
mb_make_nil(arg);
|
||||
mb_make_nil(ret);
|
||||
|
||||
mb_check(mb_attempt_open_bracket(s, l));
|
||||
|
||||
mb_check(mb_pop_value(s, l, &coi));
|
||||
_MAKE_NIL(&ocoi);
|
||||
switch(coi.type) {
|
||||
case MB_DT_LIST:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
mb_check(mb_pop_int(s, l, &index));
|
||||
if(!_at_list(ocoi.data.list, index, &ret)) {
|
||||
_handle_error_on_obj(s, SE_RN_CANNOT_FIND_WITH_GIVEN_INDEX, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
|
||||
break;
|
||||
case MB_DT_DICT:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
mb_check(mb_pop_value(s, l, &arg));
|
||||
if(!_find_dict(ocoi.data.dict, &arg, &ret)) {
|
||||
_handle_error_on_obj(s, SE_RN_CANNOT_FIND_WITH_GIVEN_INDEX, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
|
||||
break;
|
||||
case MB_DT_LIST_IT:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
if(ocoi.data.list_it && ocoi.data.list_it->curr && ocoi.data.list_it->curr->data) {
|
||||
_internal_object_to_public_value((_object_t*)ocoi.data.list_it->curr->data, &ret);
|
||||
} else {
|
||||
_handle_error_on_obj(s, SE_RN_INVALID_ITERATOR, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
|
||||
break;
|
||||
case MB_DT_DICT_IT:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
if(ocoi.data.dict_it && ocoi.data.dict_it->curr_node && ocoi.data.dict_it->curr_node->extra) {
|
||||
_internal_object_to_public_value((_object_t*)ocoi.data.dict_it->curr_node->extra, &ret);
|
||||
} else {
|
||||
_handle_error_on_obj(s, SE_RN_INVALID_ITERATOR, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
|
||||
break;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case MB_DT_CLASS:
|
||||
_public_value_to_internal_object(&coi, &ocoi);
|
||||
mb_check(mb_pop_string(s, l, &field));
|
||||
field = mb_strupr(field);
|
||||
fnode = _search_identifier_in_class(s, ocoi.data.instance, field, 0, 0);
|
||||
if(fnode && fnode->data) {
|
||||
fobj = (_object_t*)fnode->data;
|
||||
_internal_object_to_public_value(fobj, &ret);
|
||||
}
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
default:
|
||||
_handle_error_on_obj(s, SE_RN_COLLECTION_OR_ITERATOR_EXPECTED, s->source_file, TON(l), MB_FUNC_ERR, _exit, result);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mb_check(mb_attempt_close_bracket(s, l));
|
||||
|
||||
mb_check(mb_push_value(s, l, ret));
|
||||
|
||||
_exit:
|
||||
_assign_public_value(&coi, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int _coll_set(mb_interpreter_t* s, void** l) {
|
||||
/* SET statement */
|
||||
int result = MB_FUNC_OK;
|
||||
|
Loading…
x
Reference in New Issue
Block a user