*class.
This commit is contained in:
parent
af19c636bd
commit
01d9211d08
173
core/my_basic.c
173
core/my_basic.c
@ -123,6 +123,9 @@ extern "C" {
|
|||||||
#define _IS_EOS(__o) (__o && ((_object_t*)(__o))->type == _DT_EOS)
|
#define _IS_EOS(__o) (__o && ((_object_t*)(__o))->type == _DT_EOS)
|
||||||
#define _IS_SEP(__o, __c) (((_object_t*)(__o))->type == _DT_SEP && ((_object_t*)(__o))->data.separator == __c)
|
#define _IS_SEP(__o, __c) (((_object_t*)(__o))->type == _DT_SEP && ((_object_t*)(__o))->data.separator == __c)
|
||||||
#define _IS_FUNC(__o, __f) (((_object_t*)(__o))->type == _DT_FUNC && ((_object_t*)(__o))->data.func->pointer == __f)
|
#define _IS_FUNC(__o, __f) (((_object_t*)(__o))->type == _DT_FUNC && ((_object_t*)(__o))->data.func->pointer == __f)
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
# define _IS_CLASS(__o) (__o && ((_object_t*)(__o))->type == _DT_CLASS)
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
#define _IS_ROUTINE(__o) (__o && ((_object_t*)(__o))->type == _DT_ROUTINE)
|
#define _IS_ROUTINE(__o) (__o && ((_object_t*)(__o))->type == _DT_ROUTINE)
|
||||||
|
|
||||||
/* Hash table size */
|
/* Hash table size */
|
||||||
@ -230,6 +233,7 @@ static const char* _ERR_DESC[] = {
|
|||||||
"Routine expected",
|
"Routine expected",
|
||||||
"Duplicate routine",
|
"Duplicate routine",
|
||||||
"Invalid class",
|
"Invalid class",
|
||||||
|
"Class expected",
|
||||||
"Collection expected",
|
"Collection expected",
|
||||||
"Iterator expected",
|
"Iterator expected",
|
||||||
"Collection or iterator expected",
|
"Collection or iterator expected",
|
||||||
@ -1174,13 +1178,17 @@ static bool_t _end_routine(mb_interpreter_t* s);
|
|||||||
static void _begin_routine_parameter_list(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 void _end_routine_parameter_list(mb_interpreter_t* s);
|
||||||
static void _duplicate_parameter(void* data, void* extra, _running_context_t* running);
|
static void _duplicate_parameter(void* data, void* extra, _running_context_t* running);
|
||||||
static _running_context_t* _find_scope(mb_interpreter_t* s, _running_context_t* p);
|
#ifdef MB_ENABLE_CLASS
|
||||||
static _running_context_t* _reference_scope(mb_interpreter_t* s, _running_context_t* p, _routine_t* r);
|
static _running_context_t* _reference_scope_by_class(mb_interpreter_t* s, _running_context_t* p, _class_t* c);
|
||||||
|
static _running_context_t* _push_scope_by_class(mb_interpreter_t* s, _running_context_t* p);
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
static _running_context_t* _reference_scope_by_routine(mb_interpreter_t* s, _running_context_t* p, _routine_t* r);
|
||||||
|
static _running_context_t* _push_weak_scope_by_routine(mb_interpreter_t* s, _running_context_t* p, _routine_t* r);
|
||||||
|
static _running_context_t* _push_scope_by_routine(mb_interpreter_t* s, _running_context_t* p);
|
||||||
static void _unreference_scope(mb_interpreter_t* s, _running_context_t* p);
|
static void _unreference_scope(mb_interpreter_t* s, _running_context_t* p);
|
||||||
static _running_context_t* _push_weak_scope(mb_interpreter_t* s, _running_context_t* p, _routine_t* r);
|
|
||||||
static _running_context_t* _pop_weak_scope(mb_interpreter_t* s, _running_context_t* p);
|
static _running_context_t* _pop_weak_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* _pop_scope(mb_interpreter_t* s);
|
||||||
|
static _running_context_t* _find_scope(mb_interpreter_t* s, _running_context_t* p);
|
||||||
static _running_context_t* _get_scope_for_add_routine(mb_interpreter_t* s);
|
static _running_context_t* _get_scope_for_add_routine(mb_interpreter_t* s);
|
||||||
static _ls_node_t* _search_identifier_in_scope_chain(mb_interpreter_t* s, _running_context_t* scope, char* n);
|
static _ls_node_t* _search_identifier_in_scope_chain(mb_interpreter_t* s, _running_context_t* scope, char* n);
|
||||||
static _array_t* _search_array_in_scope_chain(mb_interpreter_t* s, _array_t* i, _object_t** o);
|
static _array_t* _search_array_in_scope_chain(mb_interpreter_t* s, _array_t* i, _object_t** o);
|
||||||
@ -1323,8 +1331,10 @@ static int _core_return(mb_interpreter_t* s, void** l);
|
|||||||
static int _core_call(mb_interpreter_t* s, void** l);
|
static int _core_call(mb_interpreter_t* s, void** l);
|
||||||
static int _core_def(mb_interpreter_t* s, void** l);
|
static int _core_def(mb_interpreter_t* s, void** l);
|
||||||
static int _core_enddef(mb_interpreter_t* s, void** l);
|
static int _core_enddef(mb_interpreter_t* s, void** l);
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
static int _core_class(mb_interpreter_t* s, void** l);
|
static int _core_class(mb_interpreter_t* s, void** l);
|
||||||
static int _core_endclass(mb_interpreter_t* s, void** l);
|
static int _core_endclass(mb_interpreter_t* s, void** l);
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
#ifdef MB_ENABLE_ALLOC_STAT
|
#ifdef MB_ENABLE_ALLOC_STAT
|
||||||
static int _core_mem(mb_interpreter_t* s, void** l);
|
static int _core_mem(mb_interpreter_t* s, void** l);
|
||||||
#endif /* MB_ENABLE_ALLOC_STAT */
|
#endif /* MB_ENABLE_ALLOC_STAT */
|
||||||
@ -2862,7 +2872,7 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned
|
|||||||
mb_check(mb_attempt_open_bracket(s, (void**)l));
|
mb_check(mb_attempt_open_bracket(s, (void**)l));
|
||||||
}
|
}
|
||||||
|
|
||||||
running = _push_weak_scope(s, r->scope, r);
|
running = _push_weak_scope_by_routine(s, r->scope, r);
|
||||||
result = _proc_args(s, l, running, va, ca, r, has_arg, pop_arg, true);
|
result = _proc_args(s, l, running, va, ca, r, has_arg, pop_arg, true);
|
||||||
if(result != MB_FUNC_OK) {
|
if(result != MB_FUNC_OK) {
|
||||||
if(running->meta == _SCOPE_META_REF)
|
if(running->meta == _SCOPE_META_REF)
|
||||||
@ -2881,7 +2891,7 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned
|
|||||||
ast = (_ls_node_t*)(*l);
|
ast = (_ls_node_t*)(*l);
|
||||||
_ls_pushback(s->sub_stack, ast);
|
_ls_pushback(s->sub_stack, ast);
|
||||||
|
|
||||||
running = _push_scope(s, running);
|
running = _push_scope_by_routine(s, running);
|
||||||
|
|
||||||
*l = r->entry;
|
*l = r->entry;
|
||||||
if(!(*l)) {
|
if(!(*l)) {
|
||||||
@ -3337,12 +3347,12 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
|||||||
if(running != (*obj)->data.instance->scope &&
|
if(running != (*obj)->data.instance->scope &&
|
||||||
context->class_state &&
|
context->class_state &&
|
||||||
_IS_FUNC(context->last_symbol, _core_class)) {
|
_IS_FUNC(context->last_symbol, _core_class)) {
|
||||||
_push_scope(s, (*obj)->data.instance->scope);
|
_push_scope_by_class(s, (*obj)->data.instance->scope);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmp.instance = (_class_t*)mb_malloc(sizeof(_class_t));
|
tmp.instance = (_class_t*)mb_malloc(sizeof(_class_t));
|
||||||
_init_class(s, tmp.instance, sym);
|
_init_class(s, tmp.instance, sym);
|
||||||
_push_scope(s, tmp.instance->scope);
|
_push_scope_by_class(s, tmp.instance->scope);
|
||||||
(*obj)->data.instance = tmp.instance;
|
(*obj)->data.instance = tmp.instance;
|
||||||
|
|
||||||
ul = _ht_set_or_insert(running->var_dict, sym, *obj);
|
ul = _ht_set_or_insert(running->var_dict, sym, *obj);
|
||||||
@ -3366,13 +3376,13 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
|||||||
if(running != (*obj)->data.routine->scope &&
|
if(running != (*obj)->data.routine->scope &&
|
||||||
context->routine_state &&
|
context->routine_state &&
|
||||||
_IS_FUNC(context->last_symbol, _core_def)) {
|
_IS_FUNC(context->last_symbol, _core_def)) {
|
||||||
_push_scope(s, (*obj)->data.routine->scope);
|
_push_scope_by_routine(s, (*obj)->data.routine->scope);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_running_context_t* tba = 0;
|
_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);
|
_push_scope_by_routine(s, tmp.routine->scope);
|
||||||
(*obj)->data.routine = tmp.routine;
|
(*obj)->data.routine = tmp.routine;
|
||||||
|
|
||||||
tba = _get_scope_for_add_routine(s);
|
tba = _get_scope_for_add_routine(s);
|
||||||
@ -5245,28 +5255,40 @@ void _duplicate_parameter(void* data, void* extra, _running_context_t* running)
|
|||||||
_ht_set_or_insert(running->var_dict, var->name, obj);
|
_ht_set_or_insert(running->var_dict, var->name, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
_running_context_t* _find_scope(mb_interpreter_t* s, _running_context_t* p) {
|
#ifdef MB_ENABLE_CLASS
|
||||||
/* Find a scope in a scope chain */
|
_running_context_t* _reference_scope_by_class(mb_interpreter_t* s, _running_context_t* p, _class_t* c) {
|
||||||
_running_context_t* running = 0;
|
/* Create a scope reference to an exist one by a class */
|
||||||
|
_running_context_t* result = 0;
|
||||||
|
mb_unrefvar(c);
|
||||||
|
|
||||||
|
mb_assert(s && p);
|
||||||
|
|
||||||
|
if(p->meta == _SCOPE_META_REF)
|
||||||
|
p = p->ref;
|
||||||
|
|
||||||
|
result = (_running_context_t*)mb_malloc(sizeof(_running_context_t));
|
||||||
|
memset(result, 0, sizeof(_running_context_t));
|
||||||
|
result->meta = _SCOPE_META_REF;
|
||||||
|
result->ref = p;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_running_context_t* _push_scope_by_class(mb_interpreter_t* s, _running_context_t* p) {
|
||||||
|
/* Push a scope by a class */
|
||||||
mb_assert(s);
|
mb_assert(s);
|
||||||
|
|
||||||
running = s->running_context;
|
if(_find_scope(s, p))
|
||||||
while(running) {
|
p = _reference_scope_by_class(s, p, 0);
|
||||||
if(running == p)
|
p->prev = s->running_context;
|
||||||
return running;
|
s->running_context = p;
|
||||||
|
|
||||||
if(running->ref == p)
|
return s->running_context;
|
||||||
return running->ref;
|
|
||||||
|
|
||||||
running = running->prev;
|
|
||||||
}
|
}
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
|
||||||
return running;
|
_running_context_t* _reference_scope_by_routine(mb_interpreter_t* s, _running_context_t* p, _routine_t* r) {
|
||||||
}
|
/* Create a scope reference to an exist one by a routine */
|
||||||
|
|
||||||
_running_context_t* _reference_scope(mb_interpreter_t* s, _running_context_t* p, _routine_t* r) {
|
|
||||||
/* Create a scope reference to an exist one */
|
|
||||||
_running_context_t* result = 0;
|
_running_context_t* result = 0;
|
||||||
|
|
||||||
mb_assert(s && p);
|
mb_assert(s && p);
|
||||||
@ -5286,6 +5308,29 @@ _running_context_t* _reference_scope(mb_interpreter_t* s, _running_context_t* p,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_running_context_t* _push_weak_scope_by_routine(mb_interpreter_t* s, _running_context_t* p, _routine_t* r) {
|
||||||
|
/* Push a weak scope by a routine */
|
||||||
|
mb_assert(s);
|
||||||
|
|
||||||
|
if(_find_scope(s, p))
|
||||||
|
p = _reference_scope_by_routine(s, p, r);
|
||||||
|
p->prev = s->running_context;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
_running_context_t* _push_scope_by_routine(mb_interpreter_t* s, _running_context_t* p) {
|
||||||
|
/* Push a scope by a routine */
|
||||||
|
mb_assert(s);
|
||||||
|
|
||||||
|
if(_find_scope(s, p))
|
||||||
|
p = _reference_scope_by_routine(s, p, 0);
|
||||||
|
p->prev = s->running_context;
|
||||||
|
s->running_context = p;
|
||||||
|
|
||||||
|
return s->running_context;
|
||||||
|
}
|
||||||
|
|
||||||
void _unreference_scope(mb_interpreter_t* s, _running_context_t* p) {
|
void _unreference_scope(mb_interpreter_t* s, _running_context_t* p) {
|
||||||
/* Unreference and destroy a scope */
|
/* Unreference and destroy a scope */
|
||||||
mb_unrefvar(s);
|
mb_unrefvar(s);
|
||||||
@ -5297,17 +5342,6 @@ void _unreference_scope(mb_interpreter_t* s, _running_context_t* p) {
|
|||||||
safe_free(p);
|
safe_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
_running_context_t* _push_weak_scope(mb_interpreter_t* s, _running_context_t* p, _routine_t* r) {
|
|
||||||
/* Push a weak scope */
|
|
||||||
mb_assert(s);
|
|
||||||
|
|
||||||
if(_find_scope(s, p))
|
|
||||||
p = _reference_scope(s, p, r);
|
|
||||||
p->prev = s->running_context;
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
_running_context_t* _pop_weak_scope(mb_interpreter_t* s, _running_context_t* p) {
|
_running_context_t* _pop_weak_scope(mb_interpreter_t* s, _running_context_t* p) {
|
||||||
/* Pop a weak scope */
|
/* Pop a weak scope */
|
||||||
mb_assert(s);
|
mb_assert(s);
|
||||||
@ -5317,18 +5351,6 @@ _running_context_t* _pop_weak_scope(mb_interpreter_t* s, _running_context_t* p)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
_running_context_t* _push_scope(mb_interpreter_t* s, _running_context_t* p) {
|
|
||||||
/* Push a scope */
|
|
||||||
mb_assert(s);
|
|
||||||
|
|
||||||
if(_find_scope(s, p))
|
|
||||||
p = _reference_scope(s, p, 0);
|
|
||||||
p->prev = s->running_context;
|
|
||||||
s->running_context = p;
|
|
||||||
|
|
||||||
return s->running_context;
|
|
||||||
}
|
|
||||||
|
|
||||||
_running_context_t* _pop_scope(mb_interpreter_t* s) {
|
_running_context_t* _pop_scope(mb_interpreter_t* s) {
|
||||||
/* Pop a scope */
|
/* Pop a scope */
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
@ -5344,6 +5366,26 @@ _running_context_t* _pop_scope(mb_interpreter_t* s) {
|
|||||||
return s->running_context;
|
return s->running_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_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)
|
||||||
|
return running;
|
||||||
|
|
||||||
|
if(running->ref == p)
|
||||||
|
return running->ref;
|
||||||
|
|
||||||
|
running = running->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
_running_context_t* _get_scope_for_add_routine(mb_interpreter_t* s) {
|
_running_context_t* _get_scope_for_add_routine(mb_interpreter_t* s) {
|
||||||
/* Get a proper scope to add a routine */
|
/* Get a proper scope to add a routine */
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
@ -9679,11 +9721,14 @@ _exit:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
int _core_class(mb_interpreter_t* s, void** l) {
|
int _core_class(mb_interpreter_t* s, void** l) {
|
||||||
/* CLASS statement */
|
/* CLASS statement */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
_ls_node_t* ast = 0;
|
_ls_node_t* ast = 0;
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
|
_object_t* obj = 0;
|
||||||
|
_class_t* instance = 0;
|
||||||
|
|
||||||
mb_assert(s && l);
|
mb_assert(s && l);
|
||||||
|
|
||||||
@ -9694,11 +9739,40 @@ int _core_class(mb_interpreter_t* s, void** l) {
|
|||||||
|
|
||||||
_using_jump_set_of_structured(s, ast, _exit, result);
|
_using_jump_set_of_structured(s, ast, _exit, result);
|
||||||
|
|
||||||
|
obj = (_object_t*)(ast->data);
|
||||||
|
if(!_IS_CLASS(obj)) {
|
||||||
|
_handle_error_on_obj(s, SE_RN_CLASS_EXPECTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
instance = (_class_t*)(((_object_t*)(ast->data))->data.instance);
|
||||||
|
ast = ast->next;
|
||||||
|
|
||||||
|
*l = ast;
|
||||||
|
|
||||||
|
running = _push_scope_by_class(s, running);
|
||||||
|
|
||||||
|
do {
|
||||||
|
result = _execute_statement(s, (_ls_node_t**)l);
|
||||||
|
if(result != MB_FUNC_OK && s->error_handler) {
|
||||||
|
if(result >= MB_EXTENDED_ABORT)
|
||||||
|
s->last_error = SE_EA_EXTENDED_ABORT;
|
||||||
|
_handle_error_now(s, s->last_error, s->last_error_func, result);
|
||||||
|
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
ast = (_ls_node_t*)(*l);
|
||||||
|
obj = (_object_t*)(ast->data);
|
||||||
|
} while(ast && !_IS_FUNC(obj, _core_endclass));
|
||||||
|
|
||||||
|
_pop_scope(s);
|
||||||
|
|
||||||
_skip_to(s, &ast, _core_endclass, _DT_NIL);
|
_skip_to(s, &ast, _core_endclass, _DT_NIL);
|
||||||
|
|
||||||
ast = ast->next;
|
ast = ast->next;
|
||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
|
if(result != MB_FUNC_OK)
|
||||||
|
_pop_scope(s);
|
||||||
|
|
||||||
*l = ast;
|
*l = ast;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -9713,6 +9787,7 @@ int _core_endclass(mb_interpreter_t* s, void** l) {
|
|||||||
_exit:
|
_exit:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
|
||||||
#ifdef MB_ENABLE_ALLOC_STAT
|
#ifdef MB_ENABLE_ALLOC_STAT
|
||||||
int _core_mem(mb_interpreter_t* s, void** l) {
|
int _core_mem(mb_interpreter_t* s, void** l) {
|
||||||
|
@ -314,6 +314,7 @@ typedef enum mb_error_e {
|
|||||||
SE_RN_ROUTINE_EXPECTED,
|
SE_RN_ROUTINE_EXPECTED,
|
||||||
SE_RN_DUPLICATE_ROUTINE,
|
SE_RN_DUPLICATE_ROUTINE,
|
||||||
SE_RN_INVALID_CLASS,
|
SE_RN_INVALID_CLASS,
|
||||||
|
SE_RN_CLASS_EXPECTED,
|
||||||
SE_RN_COLLECTION_EXPECTED,
|
SE_RN_COLLECTION_EXPECTED,
|
||||||
SE_RN_ITERATOR_EXPECTED,
|
SE_RN_ITERATOR_EXPECTED,
|
||||||
SE_RN_COLLECTION_OR_ITERATOR_EXPECTED,
|
SE_RN_COLLECTION_OR_ITERATOR_EXPECTED,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user