*improved sub routine.
This commit is contained in:
parent
789cc76eb3
commit
fe3e7db9c9
3
HISTORY
3
HISTORY
@ -1,3 +1,6 @@
|
|||||||
|
Sep. 6 2015
|
||||||
|
Improved sub routine
|
||||||
|
|
||||||
Sep. 2 2015
|
Sep. 2 2015
|
||||||
Added sub routine type insurance
|
Added sub routine type insurance
|
||||||
Prompted more friendly dummy function message
|
Prompted more friendly dummy function message
|
||||||
|
221
core/my_basic.c
221
core/my_basic.c
@ -78,7 +78,7 @@ extern "C" {
|
|||||||
/** Macros */
|
/** Macros */
|
||||||
#define _VER_MAJOR 1
|
#define _VER_MAJOR 1
|
||||||
#define _VER_MINOR 1
|
#define _VER_MINOR 1
|
||||||
#define _VER_REVISION 66
|
#define _VER_REVISION 67
|
||||||
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
|
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
|
||||||
|
|
||||||
/* Uncomment the line below to treat warning as error */
|
/* Uncomment the line below to treat warning as error */
|
||||||
@ -365,14 +365,19 @@ typedef struct _parsing_context_t {
|
|||||||
_object_t* last_symbol;
|
_object_t* last_symbol;
|
||||||
_parsing_state_e parsing_state;
|
_parsing_state_e parsing_state;
|
||||||
_symbol_state_e symbol_state;
|
_symbol_state_e symbol_state;
|
||||||
|
unsigned short routine_state;
|
||||||
|
unsigned short routine_params_state;
|
||||||
int parsing_pos;
|
int parsing_pos;
|
||||||
unsigned short parsing_row;
|
unsigned short parsing_row;
|
||||||
unsigned short parsing_col;
|
unsigned short parsing_col;
|
||||||
} _parsing_context_t;
|
} _parsing_context_t;
|
||||||
|
|
||||||
/* Running context */
|
/* Running context */
|
||||||
|
#define _SCOPE_META_ROOT 'ROOT'
|
||||||
|
|
||||||
typedef struct _running_context_t {
|
typedef struct _running_context_t {
|
||||||
struct _running_context_t* prev;
|
struct _running_context_t* prev;
|
||||||
|
unsigned meta;
|
||||||
_ht_node_t* var_dict;
|
_ht_node_t* var_dict;
|
||||||
_var_t* next_loop_var;
|
_var_t* next_loop_var;
|
||||||
mb_value_t intermediate_value;
|
mb_value_t intermediate_value;
|
||||||
@ -731,6 +736,8 @@ static bool_t _is_print_terminal(mb_interpreter_t* s, _object_t* obj);
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define _OUTTER_SCOPE(__s) ((__s)->prev ? (__s)->prev : (__s))
|
||||||
|
|
||||||
static void _set_current_error(mb_interpreter_t* s, mb_error_e err, char* func);
|
static void _set_current_error(mb_interpreter_t* s, mb_error_e err, char* func);
|
||||||
|
|
||||||
static mb_print_func_t _get_printer(mb_interpreter_t* s);
|
static mb_print_func_t _get_printer(mb_interpreter_t* s);
|
||||||
@ -771,8 +778,14 @@ static char* _extract_string(_object_t* obj);
|
|||||||
|
|
||||||
static void _init_instance(mb_interpreter_t* s, _class_t* instance, char* n);
|
static void _init_instance(mb_interpreter_t* s, _class_t* instance, char* n);
|
||||||
static void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n);
|
static void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n);
|
||||||
static void _end_of_scope(mb_interpreter_t* s);
|
static void _begin_routine(mb_interpreter_t* s);
|
||||||
static _ls_node_t* _search_var_in_scope_chain(mb_interpreter_t* s, char* n);
|
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* _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);
|
||||||
|
static _ls_node_t* _search_var_in_scope_chain(mb_interpreter_t* s, _running_context_t* scope, char* n);
|
||||||
|
|
||||||
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);
|
||||||
@ -1766,7 +1779,8 @@ int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val) {
|
|||||||
} else if(c->type == _DT_ROUTINE) {
|
} else if(c->type == _DT_ROUTINE) {
|
||||||
ast = ast->prev;
|
ast = ast->prev;
|
||||||
result = _eval_routine(s, &ast, c->data.routine);
|
result = _eval_routine(s, &ast, c->data.routine);
|
||||||
ast = ast->prev;
|
if(ast)
|
||||||
|
ast = ast->prev;
|
||||||
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);
|
||||||
}
|
}
|
||||||
@ -1811,10 +1825,15 @@ int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val) {
|
|||||||
_ls_pushback(opnd, arr_elem);
|
_ls_pushback(opnd, arr_elem);
|
||||||
f++;
|
f++;
|
||||||
} else {
|
} else {
|
||||||
if(c->type == _DT_VAR && ast) {
|
if(c->type == _DT_VAR) {
|
||||||
_object_t* _err_var = (_object_t*)(ast->data);
|
_ls_node_t* cs = _search_var_in_scope_chain(s, 0, c->data.variable->name);
|
||||||
if(_IS_FUNC(_err_var, _core_open_bracket)) {
|
if(cs)
|
||||||
_handle_error_on_obj(s, SE_RN_INVALID_ID_USAGE, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
c = (_object_t*)(cs->data);
|
||||||
|
if(ast) {
|
||||||
|
_object_t* _err_var = (_object_t*)(ast->data);
|
||||||
|
if(_IS_FUNC(_err_var, _core_open_bracket)) {
|
||||||
|
_handle_error_on_obj(s, SE_RN_INVALID_ID_USAGE, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(f) {
|
if(f) {
|
||||||
@ -1927,6 +1946,7 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, _routine_t* r) {
|
|||||||
mb_value_t arg;
|
mb_value_t arg;
|
||||||
_ls_node_t* pars = 0;
|
_ls_node_t* pars = 0;
|
||||||
_var_t* var = 0;
|
_var_t* var = 0;
|
||||||
|
_ls_node_t* rnode = 0;
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
|
|
||||||
mb_assert(s && l && r);
|
mb_assert(s && l && r);
|
||||||
@ -1938,12 +1958,18 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, _routine_t* r) {
|
|||||||
pars = r->parameters;
|
pars = r->parameters;
|
||||||
if(pars) {
|
if(pars) {
|
||||||
pars = pars->next;
|
pars = pars->next;
|
||||||
while(pars) {
|
while(pars && mb_has_arg(s, (void**)l)) {
|
||||||
mb_check(mb_pop_value(s, (void**)l, &arg));
|
mb_check(mb_pop_value(s, (void**)l, &arg));
|
||||||
|
|
||||||
var = (_var_t*)(pars->data);
|
var = (_var_t*)(pars->data);
|
||||||
pars = pars->next;
|
pars = pars->next;
|
||||||
|
|
||||||
|
_push_scope(s, r->scope);
|
||||||
|
rnode = _search_var_in_scope_chain(s, 0, var->name);
|
||||||
|
if(rnode)
|
||||||
|
var = ((_object_t*)(rnode->data))->data.variable;
|
||||||
|
_pop_scope(s);
|
||||||
|
|
||||||
result = _public_value_to_internal_object(&arg, var->data);
|
result = _public_value_to_internal_object(&arg, var->data);
|
||||||
if(result != MB_FUNC_OK)
|
if(result != MB_FUNC_OK)
|
||||||
goto _exit;
|
goto _exit;
|
||||||
@ -1955,8 +1981,7 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, _routine_t* r) {
|
|||||||
ast = (_ls_node_t*)(*l);
|
ast = (_ls_node_t*)(*l);
|
||||||
_ls_pushback(s->sub_stack, ast);
|
_ls_pushback(s->sub_stack, ast);
|
||||||
|
|
||||||
r->scope->prev = s->running_context;
|
running = _push_scope(s, r->scope);
|
||||||
running = s->running_context = r->scope;
|
|
||||||
|
|
||||||
*l = r->entry;
|
*l = r->entry;
|
||||||
|
|
||||||
@ -1992,8 +2017,7 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, _routine_t* r) {
|
|||||||
}
|
}
|
||||||
} while(ast);
|
} while(ast);
|
||||||
|
|
||||||
s->running_context = running->prev;
|
_pop_scope(s);
|
||||||
running->prev = 0;
|
|
||||||
|
|
||||||
s->running_context->intermediate_value = running->intermediate_value;
|
s->running_context->intermediate_value = running->intermediate_value;
|
||||||
|
|
||||||
@ -2249,7 +2273,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case _DT_ARRAY:
|
case _DT_ARRAY:
|
||||||
glbsyminscope = _search_var_in_scope_chain(s, sym);
|
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ARRAY) {
|
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ARRAY) {
|
||||||
(*obj)->data.array = ((_object_t*)(glbsyminscope->data))->data.array;
|
(*obj)->data.array = ((_object_t*)(glbsyminscope->data))->data.array;
|
||||||
(*obj)->ref = true;
|
(*obj)->ref = true;
|
||||||
@ -2273,7 +2297,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case _DT_CLASS:
|
case _DT_CLASS:
|
||||||
glbsyminscope = _search_var_in_scope_chain(s, sym);
|
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_CLASS) {
|
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_CLASS) {
|
||||||
(*obj)->data.instance = ((_object_t*)(glbsyminscope->data))->data.instance;
|
(*obj)->data.instance = ((_object_t*)(glbsyminscope->data))->data.instance;
|
||||||
(*obj)->ref = true;
|
(*obj)->ref = true;
|
||||||
@ -2295,18 +2319,28 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case _DT_ROUTINE:
|
case _DT_ROUTINE:
|
||||||
glbsyminscope = _search_var_in_scope_chain(s, sym);
|
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ROUTINE) {
|
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ROUTINE) {
|
||||||
(*obj)->data.routine = ((_object_t*)(glbsyminscope->data))->data.routine;
|
(*obj)->data.routine = ((_object_t*)(glbsyminscope->data))->data.routine;
|
||||||
(*obj)->ref = true;
|
(*obj)->ref = true;
|
||||||
*delsym = true;
|
*delsym = true;
|
||||||
|
if(running != (*obj)->data.routine->scope &&
|
||||||
|
context->routine_state &&
|
||||||
|
_IS_FUNC(context->last_symbol, _core_def)) {
|
||||||
|
_push_scope(s, (*obj)->data.routine->scope);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
_running_context_t* tba = 0;
|
||||||
tmp.routine = (_routine_t*)mb_malloc(sizeof(_routine_t));
|
tmp.routine = (_routine_t*)mb_malloc(sizeof(_routine_t));
|
||||||
_init_routine(s, tmp.routine, sym);
|
_init_routine(s, tmp.routine, sym);
|
||||||
|
_push_scope(s, tmp.routine->scope);
|
||||||
(*obj)->data.routine = tmp.routine;
|
(*obj)->data.routine = tmp.routine;
|
||||||
|
|
||||||
ul = _ht_set_or_insert(running->var_dict, sym, *obj);
|
tba = _get_scope_for_add_routine(s);
|
||||||
|
ul = _ht_set_or_insert(tba->var_dict, sym, *obj);
|
||||||
mb_assert(ul);
|
mb_assert(ul);
|
||||||
|
if(tba != _OUTTER_SCOPE(running))
|
||||||
|
_pop_scope(s);
|
||||||
|
|
||||||
*obj = (_object_t*)mb_malloc(sizeof(_object_t));
|
*obj = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||||
memset(*obj, 0, sizeof(_object_t));
|
memset(*obj, 0, sizeof(_object_t));
|
||||||
@ -2317,7 +2351,10 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case _DT_VAR:
|
case _DT_VAR:
|
||||||
glbsyminscope = _search_var_in_scope_chain(s, sym);
|
if(context->routine_params_state)
|
||||||
|
glbsyminscope = _ht_find(running->var_dict, sym);
|
||||||
|
else
|
||||||
|
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_VAR) {
|
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_VAR) {
|
||||||
(*obj)->data.variable = ((_object_t*)(glbsyminscope->data))->data.variable;
|
(*obj)->data.variable = ((_object_t*)(glbsyminscope->data))->data.variable;
|
||||||
(*obj)->ref = true;
|
(*obj)->ref = true;
|
||||||
@ -2426,14 +2463,14 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
|
|
||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
/* string */
|
/* String */
|
||||||
if(sym[0] == '"' && sym[_sl - 1] == '"' && _sl >= 2) {
|
if(sym[0] == '"' && sym[_sl - 1] == '"' && _sl >= 2) {
|
||||||
result = _DT_STRING;
|
result = _DT_STRING;
|
||||||
|
|
||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
/* _array_t */
|
/* _array_t */
|
||||||
glbsyminscope = _search_var_in_scope_chain(s, sym);
|
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ARRAY) {
|
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ARRAY) {
|
||||||
tmp.obj = (_object_t*)(glbsyminscope->data);
|
tmp.obj = (_object_t*)(glbsyminscope->data);
|
||||||
memcpy(*value, &(tmp.obj->data.array->type), sizeof(tmp.obj->data.array->type));
|
memcpy(*value, &(tmp.obj->data.array->type), sizeof(tmp.obj->data.array->type));
|
||||||
@ -2459,7 +2496,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
/* _class_t */
|
/* _class_t */
|
||||||
if(context->last_symbol && context->last_symbol->type == _DT_FUNC) {
|
if(context->last_symbol && context->last_symbol->type == _DT_FUNC) {
|
||||||
if(context->last_symbol->data.func->pointer == _core_class) {
|
if(context->last_symbol->data.func->pointer == _core_class) {
|
||||||
glbsyminscope = _search_var_in_scope_chain(s, sym);
|
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_VAR) {
|
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_VAR) {
|
||||||
tmp.obj = (_object_t*)(glbsyminscope->data);
|
tmp.obj = (_object_t*)(glbsyminscope->data);
|
||||||
if(!tmp.obj->ref) {
|
if(!tmp.obj->ref) {
|
||||||
@ -2479,13 +2516,17 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
}
|
}
|
||||||
/* _routine_t */
|
/* _routine_t */
|
||||||
if(context->last_symbol && context->last_symbol->type == _DT_FUNC) {
|
if(context->last_symbol && context->last_symbol->type == _DT_FUNC) {
|
||||||
glbsyminscope = _search_var_in_scope_chain(s, sym);
|
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||||
if(glbsyminscope && ((_object_t*)glbsyminscope->data)->type == _DT_ROUTINE) {
|
if(glbsyminscope && ((_object_t*)glbsyminscope->data)->type == _DT_ROUTINE) {
|
||||||
|
if(context->last_symbol->data.func->pointer == _core_def)
|
||||||
|
_begin_routine(s);
|
||||||
result = _DT_ROUTINE;
|
result = _DT_ROUTINE;
|
||||||
|
|
||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
if(context->last_symbol->data.func->pointer == _core_def || context->last_symbol->data.func->pointer == _core_call) {
|
if(context->last_symbol->data.func->pointer == _core_def || context->last_symbol->data.func->pointer == _core_call) {
|
||||||
|
if(context->last_symbol->data.func->pointer == _core_def)
|
||||||
|
_begin_routine(s);
|
||||||
if(!_is_identifier_char(sym[0])) {
|
if(!_is_identifier_char(sym[0])) {
|
||||||
result = _DT_NIL;
|
result = _DT_NIL;
|
||||||
|
|
||||||
@ -2500,6 +2541,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
tmp.obj->type = _DT_ROUTINE;
|
tmp.obj->type = _DT_ROUTINE;
|
||||||
tmp.obj->data.routine = (_routine_t*)mb_malloc(sizeof(_routine_t));
|
tmp.obj->data.routine = (_routine_t*)mb_malloc(sizeof(_routine_t));
|
||||||
_init_routine(s, tmp.obj->data.routine, sym);
|
_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->var_dict, sym, tmp.obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2507,7 +2549,8 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
|
|
||||||
goto _exit;
|
goto _exit;
|
||||||
} else if(context->last_symbol->data.func->pointer == _core_enddef) {
|
} else if(context->last_symbol->data.func->pointer == _core_enddef) {
|
||||||
_end_of_scope(s);
|
_end_routine(s);
|
||||||
|
_pop_scope(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* _func_t */
|
/* _func_t */
|
||||||
@ -2526,6 +2569,15 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
lclsyminscope = _ht_find(s->local_func_dict, sym);
|
lclsyminscope = _ht_find(s->local_func_dict, sym);
|
||||||
glbsyminscope = _ht_find(s->global_func_dict, sym);
|
glbsyminscope = _ht_find(s->global_func_dict, sym);
|
||||||
if(lclsyminscope || glbsyminscope) {
|
if(lclsyminscope || glbsyminscope) {
|
||||||
|
if(context->last_symbol && context->last_symbol->type == _DT_ROUTINE) {
|
||||||
|
if(_sl == 1 && sym[0] == '(')
|
||||||
|
_begin_routine_parameter_list(s);
|
||||||
|
}
|
||||||
|
if(context->routine_params_state) {
|
||||||
|
if(_sl == 1 && sym[0] == ')')
|
||||||
|
_end_routine_parameter_list(s);
|
||||||
|
}
|
||||||
|
|
||||||
ptr = lclsyminscope ? (intptr_t)lclsyminscope->data : (intptr_t)glbsyminscope->data;
|
ptr = lclsyminscope ? (intptr_t)lclsyminscope->data : (intptr_t)glbsyminscope->data;
|
||||||
memcpy(*value, &ptr, sizeof(intptr_t));
|
memcpy(*value, &ptr, sizeof(intptr_t));
|
||||||
|
|
||||||
@ -2542,14 +2594,14 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
|
|
||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
/* separator */
|
/* Separator */
|
||||||
if(_sl == 1 && _is_separator(sym[0])) {
|
if(_sl == 1 && _is_separator(sym[0])) {
|
||||||
result = _DT_SEP;
|
result = _DT_SEP;
|
||||||
|
|
||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
/* _var_t */
|
/* _var_t */
|
||||||
glbsyminscope = _search_var_in_scope_chain(s, sym);
|
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||||
if(glbsyminscope) {
|
if(glbsyminscope) {
|
||||||
if(((_object_t*)glbsyminscope->data)->type != _DT_LABEL) {
|
if(((_object_t*)glbsyminscope->data)->type != _DT_LABEL) {
|
||||||
memcpy(*value, &glbsyminscope->data, sizeof(glbsyminscope->data));
|
memcpy(*value, &glbsyminscope->data, sizeof(glbsyminscope->data));
|
||||||
@ -2562,7 +2614,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
/* _label_t */
|
/* _label_t */
|
||||||
if(context->current_char == ':') {
|
if(context->current_char == ':') {
|
||||||
if(!context->last_symbol || _IS_EOS(context->last_symbol)) {
|
if(!context->last_symbol || _IS_EOS(context->last_symbol)) {
|
||||||
glbsyminscope = _search_var_in_scope_chain(s, sym);
|
glbsyminscope = _search_var_in_scope_chain(s, 0, sym);
|
||||||
if(glbsyminscope) {
|
if(glbsyminscope) {
|
||||||
memcpy(*value, &glbsyminscope->data, sizeof(glbsyminscope->data));
|
memcpy(*value, &glbsyminscope->data, sizeof(glbsyminscope->data));
|
||||||
}
|
}
|
||||||
@ -2579,7 +2631,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* else */
|
/* Otherwise */
|
||||||
result = _DT_VAR;
|
result = _DT_VAR;
|
||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
@ -3085,13 +3137,60 @@ void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n) {
|
|||||||
routine->scope = (_running_context_t*)mb_malloc(sizeof(_running_context_t));
|
routine->scope = (_running_context_t*)mb_malloc(sizeof(_running_context_t));
|
||||||
memset(routine->scope, 0, 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->var_dict = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
||||||
|
|
||||||
routine->scope->prev = running;
|
|
||||||
s->running_context = routine->scope;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _end_of_scope(mb_interpreter_t* s) {
|
void _begin_routine(mb_interpreter_t* s) {
|
||||||
/* Finish encapsule a scope */
|
/* Begin parsing a routine */
|
||||||
|
_parsing_context_t* context = 0;
|
||||||
|
|
||||||
|
mb_assert(s);
|
||||||
|
|
||||||
|
context = s->parsing_context;
|
||||||
|
context->routine_state++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _end_routine(mb_interpreter_t* s) {
|
||||||
|
/* End parsing a routine */
|
||||||
|
_parsing_context_t* context = 0;
|
||||||
|
|
||||||
|
mb_assert(s);
|
||||||
|
|
||||||
|
context = s->parsing_context;
|
||||||
|
context->routine_state--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _begin_routine_parameter_list(mb_interpreter_t* s) {
|
||||||
|
/* Begin parsing parameter list of a routine */
|
||||||
|
_parsing_context_t* context = 0;
|
||||||
|
|
||||||
|
mb_assert(s);
|
||||||
|
|
||||||
|
context = s->parsing_context;
|
||||||
|
context->routine_params_state++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _end_routine_parameter_list(mb_interpreter_t* s) {
|
||||||
|
/* End parsing parameter list of a routine */
|
||||||
|
_parsing_context_t* context = 0;
|
||||||
|
|
||||||
|
mb_assert(s);
|
||||||
|
|
||||||
|
context = s->parsing_context;
|
||||||
|
context->routine_params_state--;
|
||||||
|
}
|
||||||
|
|
||||||
|
_running_context_t* _push_scope(mb_interpreter_t* s, _running_context_t* p) {
|
||||||
|
/* Push encapsule a scope */
|
||||||
|
mb_assert(s);
|
||||||
|
|
||||||
|
p->prev = s->running_context;
|
||||||
|
s->running_context = p;
|
||||||
|
|
||||||
|
return s->running_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
_running_context_t* _pop_scope(mb_interpreter_t* s) {
|
||||||
|
/* Pop encapsule a scope */
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
|
|
||||||
mb_assert(s);
|
mb_assert(s);
|
||||||
@ -3099,18 +3198,43 @@ void _end_of_scope(mb_interpreter_t* s) {
|
|||||||
running = s->running_context;
|
running = s->running_context;
|
||||||
s->running_context = running->prev;
|
s->running_context = running->prev;
|
||||||
running->prev = 0;
|
running->prev = 0;
|
||||||
|
|
||||||
|
return s->running_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ls_node_t* _search_var_in_scope_chain(mb_interpreter_t* s, char* n) {
|
_running_context_t* _get_scope_for_add_routine(mb_interpreter_t* s) {
|
||||||
|
/* Get a scope to add a routine */
|
||||||
|
_running_context_t* running = 0;
|
||||||
|
|
||||||
|
mb_assert(s);
|
||||||
|
|
||||||
|
running = s->running_context;
|
||||||
|
while(running) {
|
||||||
|
if(running->meta)
|
||||||
|
break;
|
||||||
|
|
||||||
|
running = running->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ls_node_t* _search_var_in_scope_chain(mb_interpreter_t* s, _running_context_t* scope, char* n) {
|
||||||
/* Try to search a variable in a scope chain */
|
/* Try to search a variable in a scope chain */
|
||||||
_ls_node_t* result = 0;
|
_ls_node_t* result = 0;
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
|
|
||||||
mb_assert(s && n);
|
mb_assert(s && n);
|
||||||
|
|
||||||
running = s->running_context;
|
if(scope)
|
||||||
|
running = scope;
|
||||||
|
else
|
||||||
|
running = s->running_context;
|
||||||
while(running && !result) {
|
while(running && !result) {
|
||||||
result = _ht_find(running->var_dict, n);
|
result = _ht_find(running->var_dict, n);
|
||||||
|
if(result)
|
||||||
|
break;
|
||||||
|
|
||||||
running = running->prev;
|
running = running->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3935,6 +4059,7 @@ int mb_open(struct mb_interpreter_t** s) {
|
|||||||
|
|
||||||
running = (_running_context_t*)mb_malloc(sizeof(_running_context_t));
|
running = (_running_context_t*)mb_malloc(sizeof(_running_context_t));
|
||||||
memset(running, 0, sizeof(_running_context_t));
|
memset(running, 0, sizeof(_running_context_t));
|
||||||
|
running->meta = _SCOPE_META_ROOT;
|
||||||
(*s)->running_context = running;
|
(*s)->running_context = running;
|
||||||
global_scope = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
global_scope = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
||||||
running->var_dict = global_scope;
|
running->var_dict = global_scope;
|
||||||
@ -4576,11 +4701,6 @@ int mb_load_string(struct mb_interpreter_t* s, const char* l) {
|
|||||||
};
|
};
|
||||||
status = _parse_char(s, MB_EOS, context->parsing_pos, context->parsing_row, context->parsing_col);
|
status = _parse_char(s, MB_EOS, context->parsing_pos, context->parsing_row, context->parsing_col);
|
||||||
|
|
||||||
if(s->running_context->prev) {
|
|
||||||
while(s->running_context->prev)
|
|
||||||
s->running_context = s->running_context->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
context->parsing_state = _PS_NORMAL;
|
context->parsing_state = _PS_NORMAL;
|
||||||
|
|
||||||
@ -4639,6 +4759,9 @@ int mb_run(struct mb_interpreter_t* s) {
|
|||||||
|
|
||||||
running = s->running_context;
|
running = s->running_context;
|
||||||
|
|
||||||
|
while(s->running_context->prev)
|
||||||
|
s->running_context = s->running_context->prev;
|
||||||
|
|
||||||
if(s->parsing_context)
|
if(s->parsing_context)
|
||||||
safe_free(s->parsing_context);
|
safe_free(s->parsing_context);
|
||||||
|
|
||||||
@ -4728,7 +4851,7 @@ int mb_debug_get(struct mb_interpreter_t* s, const char* n, mb_value_t* val) {
|
|||||||
|
|
||||||
running = s->running_context;
|
running = s->running_context;
|
||||||
|
|
||||||
v = _search_var_in_scope_chain(s, (char*)n);
|
v = _search_var_in_scope_chain(s, 0, (char*)n);
|
||||||
if(v) {
|
if(v) {
|
||||||
obj = (_object_t*)(v->data);
|
obj = (_object_t*)(v->data);
|
||||||
mb_assert(obj->type == _DT_VAR);
|
mb_assert(obj->type == _DT_VAR);
|
||||||
@ -4756,7 +4879,7 @@ int mb_debug_set(struct mb_interpreter_t* s, const char* n, mb_value_t val) {
|
|||||||
|
|
||||||
running = s->running_context;
|
running = s->running_context;
|
||||||
|
|
||||||
v = _search_var_in_scope_chain(s, (char*)n);
|
v = _search_var_in_scope_chain(s, 0, (char*)n);
|
||||||
if(v) {
|
if(v) {
|
||||||
obj = (_object_t*)(v->data);
|
obj = (_object_t*)(v->data);
|
||||||
mb_assert(obj->type == _DT_VAR);
|
mb_assert(obj->type == _DT_VAR);
|
||||||
@ -6041,13 +6164,11 @@ int _core_def(mb_interpreter_t* s, void** l) {
|
|||||||
_ls_node_t* ast = 0;
|
_ls_node_t* ast = 0;
|
||||||
_object_t* obj = 0;
|
_object_t* obj = 0;
|
||||||
_var_t* var = 0;
|
_var_t* var = 0;
|
||||||
|
_ls_node_t* rnode = 0;
|
||||||
_routine_t* routine = 0;
|
_routine_t* routine = 0;
|
||||||
_running_context_t* scope = 0;
|
|
||||||
|
|
||||||
mb_assert(s && l);
|
mb_assert(s && l);
|
||||||
|
|
||||||
scope = s->running_context;
|
|
||||||
|
|
||||||
ast = (_ls_node_t*)(*l);
|
ast = (_ls_node_t*)(*l);
|
||||||
ast = ast->next;
|
ast = ast->next;
|
||||||
|
|
||||||
@ -6066,9 +6187,15 @@ int _core_def(mb_interpreter_t* s, void** l) {
|
|||||||
ast = ast->next;
|
ast = ast->next;
|
||||||
obj = (_object_t*)(ast->data);
|
obj = (_object_t*)(ast->data);
|
||||||
while(!_IS_FUNC(obj, _core_close_bracket)) {
|
while(!_IS_FUNC(obj, _core_close_bracket)) {
|
||||||
var = obj->data.variable;
|
if(obj->type == _DT_VAR) {
|
||||||
routine->parameters = _ls_create();
|
var = obj->data.variable;
|
||||||
_ls_pushback(routine->parameters, var);
|
rnode = _search_var_in_scope_chain(s, routine->scope, var->name);
|
||||||
|
if(rnode)
|
||||||
|
var = ((_object_t*)(rnode->data))->data.variable;
|
||||||
|
if(!routine->parameters)
|
||||||
|
routine->parameters = _ls_create();
|
||||||
|
_ls_pushback(routine->parameters, var);
|
||||||
|
}
|
||||||
|
|
||||||
ast = ast->next;
|
ast = ast->next;
|
||||||
obj = (_object_t*)(ast->data);
|
obj = (_object_t*)(ast->data);
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -36,8 +36,8 @@
|
|||||||
IDI_ICON_MAIN ICON "icon.ico"
|
IDI_ICON_MAIN ICON "icon.ico"
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,1,66,0
|
FILEVERSION 1,1,67,0
|
||||||
PRODUCTVERSION 1,1,66,0
|
PRODUCTVERSION 1,1,67,0
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
# ifdef _DEBUG
|
# ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -55,13 +55,13 @@
|
|||||||
VALUE "Comments", "MY-BASIC"
|
VALUE "Comments", "MY-BASIC"
|
||||||
VALUE "CompanyName", "Wang Renxin"
|
VALUE "CompanyName", "Wang Renxin"
|
||||||
VALUE "FileDescription", "MY-BASIC Interpreter for Windows"
|
VALUE "FileDescription", "MY-BASIC Interpreter for Windows"
|
||||||
VALUE "FileVersion", "1, 1, 66, 0"
|
VALUE "FileVersion", "1, 1, 67, 0"
|
||||||
VALUE "InternalName", "my_basic"
|
VALUE "InternalName", "my_basic"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 Wang Renxin"
|
VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 Wang Renxin"
|
||||||
VALUE "LegalTrademarks", "MY-BASIC"
|
VALUE "LegalTrademarks", "MY-BASIC"
|
||||||
VALUE "OriginalFilename", "my_basic.exe"
|
VALUE "OriginalFilename", "my_basic.exe"
|
||||||
VALUE "ProductName", "MY-BASIC"
|
VALUE "ProductName", "MY-BASIC"
|
||||||
VALUE "ProductVersion", "1, 1, 66, 0"
|
VALUE "ProductVersion", "1, 1, 67, 0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -750,8 +750,11 @@ int main(int argc, char* argv[]) {
|
|||||||
status = _do_line();
|
status = _do_line();
|
||||||
} while(_NO_END(status));
|
} while(_NO_END(status));
|
||||||
} else if(argc == 2) {
|
} else if(argc == 2) {
|
||||||
if(mb_load_file(bas, argv[1]) == MB_FUNC_OK)
|
if(mb_load_file(bas, argv[1]) == MB_FUNC_OK) {
|
||||||
mb_run(bas);
|
mb_run(bas);
|
||||||
|
} else {
|
||||||
|
printf("Invalid file\n");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("Unknown arguments\n");
|
printf("Unknown arguments\n");
|
||||||
_show_tip();
|
_show_tip();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user