+added array manipulation ability to script, it's able to assign an array to a variable or use it as a scripting interface argument; +added recursive sub routine support; *fixed a wrong argument detection bug in mb_has_arg.
This commit is contained in:
parent
b4d2a05d4e
commit
faae9b4cdc
5
HISTORY
5
HISTORY
@ -1,3 +1,8 @@
|
||||
Sep. 20 2015
|
||||
Added array manipulation ability to script, it's able to assign an array to a variable or use it as a scripting interface argument
|
||||
Added recursive sub routine support
|
||||
Fixed a wrong argument detection bug in mb_has_arg
|
||||
|
||||
Sep. 18 2015
|
||||
Fixed a float number parsing bug, thanks to Cybermonkey342 for pointing it out
|
||||
Added directly expression evaluation shell command
|
||||
|
193
core/my_basic.c
193
core/my_basic.c
@ -79,7 +79,7 @@ extern "C" {
|
||||
/** Macros */
|
||||
#define _VER_MAJOR 1
|
||||
#define _VER_MINOR 1
|
||||
#define _VER_REVISION 71
|
||||
#define _VER_REVISION 72
|
||||
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
|
||||
|
||||
/* Uncomment the line below to treat warning as error */
|
||||
@ -375,11 +375,15 @@ typedef struct _parsing_context_t {
|
||||
|
||||
/* Running context */
|
||||
#define _SCOPE_META_ROOT 'ROOT'
|
||||
#define _SCOPE_META_REF 'REFS'
|
||||
|
||||
typedef struct _running_context_t {
|
||||
struct _running_context_t* prev;
|
||||
unsigned meta;
|
||||
_ht_node_t* var_dict;
|
||||
union {
|
||||
_ht_node_t* var_dict;
|
||||
struct _running_context_t* ref;
|
||||
} data;
|
||||
_var_t* next_loop_var;
|
||||
mb_value_t intermediate_value;
|
||||
} _running_context_t;
|
||||
@ -392,6 +396,7 @@ typedef struct _tuple3_t {
|
||||
} _tuple3_t;
|
||||
|
||||
/* Interpreter tag */
|
||||
#define _JMP_NIL 0x00
|
||||
#define _JMP_INS 0x01
|
||||
#define _JMP_STR 0x02
|
||||
|
||||
@ -829,6 +834,8 @@ static void _begin_routine(mb_interpreter_t* s);
|
||||
static void _end_routine(mb_interpreter_t* s);
|
||||
static void _begin_routine_parameter_list(mb_interpreter_t* s);
|
||||
static void _end_routine_parameter_list(mb_interpreter_t* s);
|
||||
static _running_context_t* _find_scope(mb_interpreter_t* s, _running_context_t* p);
|
||||
static _running_context_t* _reference_scope(mb_interpreter_t* s, _running_context_t* p);
|
||||
static _running_context_t* _push_scope(mb_interpreter_t* s, _running_context_t* p);
|
||||
static _running_context_t* _pop_scope(mb_interpreter_t* s);
|
||||
static _running_context_t* _get_scope_for_add_routine(mb_interpreter_t* s);
|
||||
@ -1789,34 +1796,39 @@ int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val) {
|
||||
}
|
||||
} else {
|
||||
if(c->type == _DT_ARRAY) {
|
||||
ast = ast->prev;
|
||||
result = _get_array_index(s, &ast, &arr_idx);
|
||||
if(result != MB_FUNC_OK) {
|
||||
_handle_error_on_obj(s, SE_RN_CALCULATION_ERROR, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
ast = ast->next;
|
||||
_get_array_elem(s, c->data.array, arr_idx, &arr_val, &arr_type);
|
||||
arr_elem = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||
memset(arr_elem, 0, sizeof(_object_t));
|
||||
_ls_pushback(garbage, arr_elem);
|
||||
arr_elem->type = arr_type;
|
||||
arr_elem->ref = true;
|
||||
if(arr_type == _DT_INT) {
|
||||
arr_elem->data.integer = arr_val.integer;
|
||||
} else if(arr_type == _DT_REAL) {
|
||||
arr_elem->data.float_point = arr_val.float_point;
|
||||
} else if(arr_type == _DT_STRING) {
|
||||
arr_elem->data.string = arr_val.string;
|
||||
} else if(arr_type == _DT_USERTYPE) {
|
||||
arr_elem->data.usertype = arr_val.usertype;
|
||||
if(ast && !_IS_FUNC(((_object_t*)(ast->data)), _core_open_bracket)) {
|
||||
_ls_pushback(opnd, c);
|
||||
f++;
|
||||
} else {
|
||||
mb_assert(0 && "Unsupported");
|
||||
ast = ast->prev;
|
||||
result = _get_array_index(s, &ast, &arr_idx);
|
||||
if(result != MB_FUNC_OK) {
|
||||
_handle_error_on_obj(s, SE_RN_CALCULATION_ERROR, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
ast = ast->next;
|
||||
_get_array_elem(s, c->data.array, arr_idx, &arr_val, &arr_type);
|
||||
arr_elem = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||
memset(arr_elem, 0, sizeof(_object_t));
|
||||
_ls_pushback(garbage, arr_elem);
|
||||
arr_elem->type = arr_type;
|
||||
arr_elem->ref = true;
|
||||
if(arr_type == _DT_INT) {
|
||||
arr_elem->data.integer = arr_val.integer;
|
||||
} else if(arr_type == _DT_REAL) {
|
||||
arr_elem->data.float_point = arr_val.float_point;
|
||||
} else if(arr_type == _DT_STRING) {
|
||||
arr_elem->data.string = arr_val.string;
|
||||
} else if(arr_type == _DT_USERTYPE) {
|
||||
arr_elem->data.usertype = arr_val.usertype;
|
||||
} else {
|
||||
mb_assert(0 && "Unsupported");
|
||||
}
|
||||
if(f) {
|
||||
_handle_error_on_obj(s, SE_RN_OPERATOR_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
_ls_pushback(opnd, arr_elem);
|
||||
f++;
|
||||
}
|
||||
if(f) {
|
||||
_handle_error_on_obj(s, SE_RN_OPERATOR_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
_ls_pushback(opnd, arr_elem);
|
||||
f++;
|
||||
} else if(c->type == _DT_FUNC) {
|
||||
ast = ast->prev;
|
||||
result = (c->data.func->pointer)(s, (void**)(&ast));
|
||||
@ -2046,6 +2058,7 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, _routine_t* r) {
|
||||
|
||||
do {
|
||||
result = _execute_statement(s, l);
|
||||
ast = (_ls_node_t*)(*l);
|
||||
if(result == MB_SUB_RETURN) {
|
||||
result = MB_FUNC_OK;
|
||||
|
||||
@ -2349,7 +2362,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
||||
memcpy(&tmp.array->type, value, sizeof(tmp.array->type));
|
||||
(*obj)->data.array = tmp.array;
|
||||
|
||||
ul = _ht_set_or_insert(running->var_dict, sym, *obj);
|
||||
ul = _ht_set_or_insert(running->data.var_dict, sym, *obj);
|
||||
mb_assert(ul);
|
||||
|
||||
*obj = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||
@ -2377,7 +2390,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
||||
_push_scope(s, tmp.instance->scope);
|
||||
(*obj)->data.instance = tmp.instance;
|
||||
|
||||
ul = _ht_set_or_insert(running->var_dict, sym, *obj);
|
||||
ul = _ht_set_or_insert(running->data.var_dict, sym, *obj);
|
||||
mb_assert(ul);
|
||||
|
||||
*obj = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||
@ -2407,7 +2420,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
||||
(*obj)->data.routine = tmp.routine;
|
||||
|
||||
tba = _get_scope_for_add_routine(s);
|
||||
ul = _ht_set_or_insert(tba->var_dict, sym, *obj);
|
||||
ul = _ht_set_or_insert(tba->data.var_dict, sym, *obj);
|
||||
mb_assert(ul);
|
||||
if(tba != _OUTTER_SCOPE(running))
|
||||
_pop_scope(s);
|
||||
@ -2422,7 +2435,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
||||
break;
|
||||
case _DT_VAR:
|
||||
if(context->routine_params_state)
|
||||
glbsyminscope = _ht_find(running->var_dict, sym);
|
||||
glbsyminscope = _ht_find(running->data.var_dict, sym);
|
||||
else
|
||||
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_VAR) {
|
||||
@ -2439,7 +2452,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
||||
tmp.var->data->data.integer = 0;
|
||||
(*obj)->data.variable = tmp.var;
|
||||
|
||||
ul = _ht_set_or_insert(running->var_dict, sym, *obj);
|
||||
ul = _ht_set_or_insert(running->data.var_dict, sym, *obj);
|
||||
mb_assert(ul);
|
||||
|
||||
*obj = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||
@ -2463,7 +2476,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
||||
*asgn = &(tmp.label->node);
|
||||
(*obj)->data.label = tmp.label;
|
||||
|
||||
ul = _ht_set_or_insert(running->var_dict, sym, *obj);
|
||||
ul = _ht_set_or_insert(running->data.var_dict, sym, *obj);
|
||||
mb_assert(ul);
|
||||
|
||||
*obj = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||
@ -2591,14 +2604,14 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_VAR) {
|
||||
tmp.obj = (_object_t*)(glbsyminscope->data);
|
||||
if(!tmp.obj->ref) {
|
||||
_ht_remove(running->var_dict, sym, _ls_cmp_extra_string);
|
||||
_ht_remove(running->data.var_dict, sym, _ls_cmp_extra_string);
|
||||
_dispose_object(tmp.obj);
|
||||
}
|
||||
tmp.obj->type = _DT_CLASS;
|
||||
tmp.obj->data.instance = (_class_t*)mb_malloc(sizeof(_class_t));
|
||||
_init_class(s, tmp.obj->data.instance, sym);
|
||||
_init_class(s, tmp.obj->data.instance, sym);
|
||||
_ht_set_or_insert(running->var_dict, sym, tmp.obj);
|
||||
_ht_set_or_insert(running->data.var_dict, sym, tmp.obj);
|
||||
}
|
||||
|
||||
result = _DT_CLASS;
|
||||
@ -2630,14 +2643,14 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_VAR) {
|
||||
tmp.obj = (_object_t*)(glbsyminscope->data);
|
||||
if(!tmp.obj->ref) {
|
||||
_ht_remove(running->var_dict, sym, _ls_cmp_extra_string);
|
||||
_ht_remove(running->data.var_dict, sym, _ls_cmp_extra_string);
|
||||
_dispose_object(tmp.obj);
|
||||
}
|
||||
tmp.obj->type = _DT_ROUTINE;
|
||||
tmp.obj->data.routine = (_routine_t*)mb_malloc(sizeof(_routine_t));
|
||||
_init_routine(s, tmp.obj->data.routine, sym);
|
||||
_push_scope(s, tmp.obj->data.routine->scope);
|
||||
_ht_set_or_insert(running->var_dict, sym, tmp.obj);
|
||||
_ht_set_or_insert(running->data.var_dict, sym, tmp.obj);
|
||||
}
|
||||
|
||||
result = _DT_ROUTINE;
|
||||
@ -3219,7 +3232,7 @@ void _init_class(mb_interpreter_t* s, _class_t* instance, char* n) {
|
||||
instance->name = n;
|
||||
instance->scope = (_running_context_t*)mb_malloc(sizeof(_running_context_t));
|
||||
memset(instance->scope, 0, sizeof(_running_context_t));
|
||||
instance->scope->var_dict = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
||||
instance->scope->data.var_dict = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
||||
}
|
||||
|
||||
void _begin_class(mb_interpreter_t* s) {
|
||||
@ -3254,7 +3267,7 @@ void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n) {
|
||||
routine->name = n;
|
||||
routine->scope = (_running_context_t*)mb_malloc(sizeof(_running_context_t));
|
||||
memset(routine->scope, 0, sizeof(_running_context_t));
|
||||
routine->scope->var_dict = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
||||
routine->scope->data.var_dict = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
||||
}
|
||||
|
||||
void _begin_routine(mb_interpreter_t* s) {
|
||||
@ -3297,10 +3310,43 @@ void _end_routine_parameter_list(mb_interpreter_t* s) {
|
||||
context->routine_params_state--;
|
||||
}
|
||||
|
||||
_running_context_t* _find_scope(mb_interpreter_t* s, _running_context_t* p) {
|
||||
/* Find a scope in a scope chain */
|
||||
_running_context_t* running = 0;
|
||||
|
||||
mb_assert(s);
|
||||
|
||||
running = s->running_context;
|
||||
while(running) {
|
||||
if(running == p)
|
||||
break;
|
||||
|
||||
running = running->prev;
|
||||
}
|
||||
|
||||
return running;
|
||||
}
|
||||
|
||||
_running_context_t* _reference_scope(mb_interpreter_t* s, _running_context_t* p) {
|
||||
/* Create a scope reference to an exist one */
|
||||
_running_context_t* result = 0;
|
||||
|
||||
mb_assert(s && p);
|
||||
|
||||
result = (_running_context_t*)mb_malloc(sizeof(_running_context_t));
|
||||
memset(result, 0, sizeof(_running_context_t));
|
||||
result->meta = _SCOPE_META_REF;
|
||||
result->data.ref = p;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
_running_context_t* _push_scope(mb_interpreter_t* s, _running_context_t* p) {
|
||||
/* Push encapsule a scope */
|
||||
mb_assert(s);
|
||||
|
||||
if(_find_scope(s, p))
|
||||
p = _reference_scope(s, p);
|
||||
p->prev = s->running_context;
|
||||
s->running_context = p;
|
||||
|
||||
@ -3316,6 +3362,9 @@ _running_context_t* _pop_scope(mb_interpreter_t* s) {
|
||||
running = s->running_context;
|
||||
s->running_context = running->prev;
|
||||
running->prev = 0;
|
||||
if(running->meta == _SCOPE_META_REF) {
|
||||
mb_free(running);
|
||||
}
|
||||
|
||||
return s->running_context;
|
||||
}
|
||||
@ -3328,7 +3377,7 @@ _running_context_t* _get_scope_for_add_routine(mb_interpreter_t* s) {
|
||||
|
||||
running = s->running_context;
|
||||
while(running) {
|
||||
if(running->meta)
|
||||
if(running->meta == _SCOPE_META_ROOT)
|
||||
break;
|
||||
|
||||
running = running->prev;
|
||||
@ -3341,6 +3390,7 @@ _ls_node_t* _search_var_in_scope_chain(mb_interpreter_t* s, _running_context_t*
|
||||
/* Try to search a variable in a scope chain */
|
||||
_ls_node_t* result = 0;
|
||||
_running_context_t* running = 0;
|
||||
_ht_node_t* var_dict = 0;
|
||||
|
||||
mb_assert(s && n);
|
||||
|
||||
@ -3349,7 +3399,8 @@ _ls_node_t* _search_var_in_scope_chain(mb_interpreter_t* s, _running_context_t*
|
||||
else
|
||||
running = s->running_context;
|
||||
while(running && !result) {
|
||||
result = _ht_find(running->var_dict, n);
|
||||
var_dict = running->meta == _SCOPE_META_REF ? running->data.ref->data.var_dict : running->data.var_dict;
|
||||
result = _ht_find(var_dict, n);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
@ -3407,8 +3458,8 @@ int _dispose_object(_object_t* obj) {
|
||||
case _DT_CLASS:
|
||||
if(!obj->ref) {
|
||||
safe_free(obj->data.instance->name);
|
||||
_ht_foreach(obj->data.instance->scope->var_dict, _destroy_object);
|
||||
_ht_destroy(obj->data.instance->scope->var_dict);
|
||||
_ht_foreach(obj->data.instance->scope->data.var_dict, _destroy_object);
|
||||
_ht_destroy(obj->data.instance->scope->data.var_dict);
|
||||
safe_free(obj->data.instance->scope);
|
||||
safe_free(obj->data.instance);
|
||||
}
|
||||
@ -3417,8 +3468,8 @@ int _dispose_object(_object_t* obj) {
|
||||
case _DT_ROUTINE:
|
||||
if(!obj->ref) {
|
||||
safe_free(obj->data.routine->name);
|
||||
_ht_foreach(obj->data.routine->scope->var_dict, _destroy_object);
|
||||
_ht_destroy(obj->data.routine->scope->var_dict);
|
||||
_ht_foreach(obj->data.routine->scope->data.var_dict, _destroy_object);
|
||||
_ht_destroy(obj->data.routine->scope->data.var_dict);
|
||||
safe_free(obj->data.routine->scope);
|
||||
if(obj->data.routine->parameters)
|
||||
_ls_destroy(obj->data.routine->parameters);
|
||||
@ -3732,11 +3783,13 @@ int _execute_statement(mb_interpreter_t* s, _ls_node_t** l) {
|
||||
_ls_node_t* ast = 0;
|
||||
_object_t* obj = 0;
|
||||
_running_context_t* running = 0;
|
||||
_ls_node_t* sub_stack = 0;
|
||||
bool_t skip_to_eoi = true;
|
||||
|
||||
mb_assert(s && l);
|
||||
|
||||
running = s->running_context;
|
||||
sub_stack = s->sub_stack;
|
||||
|
||||
ast = *l;
|
||||
|
||||
@ -3789,7 +3842,11 @@ int _execute_statement(mb_interpreter_t* s, _ls_node_t** l) {
|
||||
ast = ast->next;
|
||||
} else if(obj && obj->type == _DT_VAR) {
|
||||
_handle_error_on_obj(s, SE_RN_COLON_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
} else if((obj && obj->type != _DT_FUNC) || (obj && obj->type == _DT_FUNC && (_is_operator(obj->data.func->pointer) || _is_flow(obj->data.func->pointer)))) {
|
||||
} else if(_IS_FUNC(obj, _core_enddef)) {
|
||||
ast = (_ls_node_t*)_ls_popback(sub_stack);
|
||||
} else if(obj && obj->type == _DT_FUNC && (_is_operator(obj->data.func->pointer) || _is_flow(obj->data.func->pointer))) {
|
||||
ast = ast->next;
|
||||
} else if(obj && obj->type != _DT_FUNC) {
|
||||
ast = ast->next;
|
||||
} else {
|
||||
_handle_error_on_obj(s, SE_RN_COLON_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
@ -3919,7 +3976,7 @@ int _clear_scope_chain(mb_interpreter_t* s) {
|
||||
while(running) {
|
||||
prev = running->prev;
|
||||
|
||||
global_scope = running->var_dict;
|
||||
global_scope = running->data.var_dict;
|
||||
_ht_foreach(global_scope, _destroy_object);
|
||||
_ht_clear(global_scope);
|
||||
|
||||
@ -3943,7 +4000,7 @@ int _dispose_scope_chain(mb_interpreter_t* s) {
|
||||
while(running) {
|
||||
prev = running->prev;
|
||||
|
||||
global_scope = running->var_dict;
|
||||
global_scope = running->data.var_dict;
|
||||
_ht_foreach(global_scope, _destroy_object);
|
||||
_ht_clear(global_scope);
|
||||
_ht_destroy(global_scope);
|
||||
@ -4022,9 +4079,9 @@ int _open_constant(mb_interpreter_t* s) {
|
||||
|
||||
running = s->running_context;
|
||||
|
||||
ul = _ht_set_or_insert(running->var_dict, "TRUE", _OBJ_BOOL_TRUE);
|
||||
ul = _ht_set_or_insert(running->data.var_dict, "TRUE", _OBJ_BOOL_TRUE);
|
||||
mb_assert(ul);
|
||||
ul = _ht_set_or_insert(running->var_dict, "FALSE", _OBJ_BOOL_FALSE);
|
||||
ul = _ht_set_or_insert(running->data.var_dict, "FALSE", _OBJ_BOOL_FALSE);
|
||||
mb_assert(ul);
|
||||
|
||||
return result;
|
||||
@ -4222,7 +4279,7 @@ int mb_open(struct mb_interpreter_t** s) {
|
||||
running->meta = _SCOPE_META_ROOT;
|
||||
(*s)->running_context = running;
|
||||
global_scope = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
||||
running->var_dict = global_scope;
|
||||
running->data.var_dict = global_scope;
|
||||
|
||||
(*s)->sub_stack = _ls_create();
|
||||
|
||||
@ -4295,6 +4352,7 @@ int mb_reset(struct mb_interpreter_t** s, bool_t clrf/* = false*/) {
|
||||
|
||||
mb_assert(s);
|
||||
|
||||
(*s)->jump_set = _JMP_NIL;
|
||||
(*s)->no_eat_comma_mark = 0;
|
||||
(*s)->last_error = SE_NO_ERR;
|
||||
(*s)->last_error_func = 0;
|
||||
@ -4432,7 +4490,7 @@ int mb_has_arg(struct mb_interpreter_t* s, void** l) {
|
||||
if(ast) {
|
||||
obj = (_object_t*)(ast->data);
|
||||
if(!_IS_FUNC(obj, _core_close_bracket) && obj->type != _DT_EOS)
|
||||
result = obj->data.integer;
|
||||
result = obj->type != _DT_NIL && obj->type != _DT_SEP && obj->type != _DT_EOS;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -5572,13 +5630,18 @@ int _core_let(mb_interpreter_t* s, void** l) {
|
||||
_handle_error_on_obj(s, SE_RN_SYNTAX, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
obj = (_object_t*)(ast->data);
|
||||
if(obj->type == _DT_VAR) {
|
||||
var = obj->data.variable;
|
||||
} else if(obj->type == _DT_ARRAY) {
|
||||
if(obj->type == _DT_ARRAY) {
|
||||
arr = obj->data.array;
|
||||
result = _get_array_index(s, &ast, &arr_idx);
|
||||
if(result != MB_FUNC_OK)
|
||||
goto _exit;
|
||||
} else if(obj->type == _DT_VAR && obj->data.variable->data->type == _DT_ARRAY) {
|
||||
arr = obj->data.variable->data->data.array;
|
||||
result = _get_array_index(s, &ast, &arr_idx);
|
||||
if(result != MB_FUNC_OK)
|
||||
goto _exit;
|
||||
} else if(obj->type == _DT_VAR) {
|
||||
var = obj->data.variable;
|
||||
} else {
|
||||
_handle_error_on_obj(s, SE_RN_VAR_OR_ARRAY_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
@ -5745,10 +5808,12 @@ _elseif:
|
||||
|
||||
if(ast && ast->next && _IS_EOS(ast->next->data))
|
||||
multi_line = true;
|
||||
|
||||
s->skip_to_eoi = _ls_back(s->sub_stack);
|
||||
else
|
||||
s->skip_to_eoi = _ls_back(s->sub_stack);
|
||||
do {
|
||||
ast = ast->next;
|
||||
while(ast && _IS_EOS(ast->data))
|
||||
ast = ast->next;
|
||||
result = _execute_statement(s, &ast);
|
||||
if(result != MB_FUNC_OK)
|
||||
goto _exit;
|
||||
@ -5817,14 +5882,16 @@ _elseif:
|
||||
}
|
||||
|
||||
_exit:
|
||||
if(multi_line)
|
||||
result = _skip_to(s, &ast, _core_endif, _DT_NIL);
|
||||
if(result != MB_SUB_RETURN) {
|
||||
if(multi_line)
|
||||
result = _skip_to(s, &ast, _core_endif, _DT_NIL);
|
||||
}
|
||||
|
||||
*l = ast;
|
||||
|
||||
if(val->type != _DT_ANY)
|
||||
_destroy_object(val, 0);
|
||||
|
||||
*l = ast;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -6224,7 +6291,7 @@ int _core_goto(mb_interpreter_t* s, void** l) {
|
||||
|
||||
label = (_label_t*)(obj->data.label);
|
||||
if(!label->node) {
|
||||
glbsyminscope = _ht_find(running->var_dict, label->name);
|
||||
glbsyminscope = _ht_find(running->data.var_dict, label->name);
|
||||
if(!(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_LABEL)) {
|
||||
_handle_error_on_obj(s, SE_RN_LABEL_NOT_EXISTS, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
|
0
my_basic.sln
Normal file → Executable file
0
my_basic.sln
Normal file → Executable file
22
my_basic.vcproj
Normal file → Executable file
22
my_basic.vcproj
Normal file → Executable file
@ -66,6 +66,7 @@
|
||||
OutputFile="$(OutDir)\$(ProjectName)_d.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\$(ProjectName)_d.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
@ -141,6 +142,7 @@
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\$(ProjectName).pdb"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
@ -287,6 +289,26 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sample\sample05.bas"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="res"
|
||||
|
Binary file not shown.
Binary file not shown.
@ -36,8 +36,8 @@
|
||||
IDI_ICON_MAIN ICON "icon.ico"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,1,71,0
|
||||
PRODUCTVERSION 1,1,71,0
|
||||
FILEVERSION 1,1,72,0
|
||||
PRODUCTVERSION 1,1,72,0
|
||||
FILEFLAGSMASK 0x17L
|
||||
# ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -55,13 +55,13 @@
|
||||
VALUE "Comments", "MY-BASIC"
|
||||
VALUE "CompanyName", "Wang Renxin"
|
||||
VALUE "FileDescription", "MY-BASIC Interpreter for Windows"
|
||||
VALUE "FileVersion", "1, 1, 71, 0"
|
||||
VALUE "FileVersion", "1, 1, 72, 0"
|
||||
VALUE "InternalName", "my_basic"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 Wang Renxin"
|
||||
VALUE "LegalTrademarks", "MY-BASIC"
|
||||
VALUE "OriginalFilename", "my_basic.exe"
|
||||
VALUE "ProductName", "MY-BASIC"
|
||||
VALUE "ProductVersion", "1, 1, 71, 0"
|
||||
VALUE "ProductVersion", "1, 1, 72, 0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
15
sample/sample05.bas
Executable file
15
sample/sample05.bas
Executable file
@ -0,0 +1,15 @@
|
||||
' This script is an example of MY-BASIC
|
||||
' Copyright (c) 2011 - 2015 Wang Renxin. All rights reserved.
|
||||
' For more information, see https://github.com/paladin-t/my_basic/
|
||||
|
||||
DEF AREA(a, b)
|
||||
RETURN CALL MUL(a, b)
|
||||
ENDDEF
|
||||
|
||||
DEF MUL(a, b)
|
||||
return a * b
|
||||
ENDDEF
|
||||
|
||||
a = 3
|
||||
b = 4
|
||||
PRINT a; b; AREA(a, b);
|
@ -67,9 +67,9 @@
|
||||
# define _BIN_FILE_NAME "my_basic"
|
||||
#elif defined __APPLE__
|
||||
# define _BIN_FILE_NAME "my_basic_mac"
|
||||
#else
|
||||
#else /* _MSC_VER */
|
||||
# define _BIN_FILE_NAME "my_basic_bin"
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#define _USE_MEM_POOL /* Comment this macro to disable memory pool */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user