*avoided cycle importing.

This commit is contained in:
Wang Renxin 2015-10-12 18:46:40 +08:00
parent fca2da3730
commit 1ee5485820

View File

@ -79,7 +79,7 @@ extern "C" {
/** Macros */
#define _VER_MAJOR 1
#define _VER_MINOR 1
#define _VER_REVISION 83
#define _VER_REVISION 84
#define _VER_SUFFIX
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
#define _STRINGIZE(A) _MAKE_STRINGIZE(A)
@ -272,18 +272,6 @@ typedef struct _var_t {
struct _object_t* data;
} _var_t;
typedef struct _array_t {
char* name;
_data_e type;
#ifndef MB_SIMPLE_ARRAY
_data_e* types;
#endif /* MB_SIMPLE_ARRAY */
void* raw;
unsigned int count;
int dimension_count;
int dimensions[MB_MAX_DIMENSION_COUNT];
} _array_t;
struct _ref_t;
typedef void (* _unref_func_t)(struct _ref_t*, void*);
@ -297,6 +285,18 @@ typedef struct _ref_t {
typedef short _lock_t;
typedef struct _array_t {
char* name;
_data_e type;
#ifndef MB_SIMPLE_ARRAY
_data_e* types;
#endif /* MB_SIMPLE_ARRAY */
void* raw;
unsigned int count;
int dimension_count;
int dimensions[MB_MAX_DIMENSION_COUNT];
} _array_t;
#ifdef MB_ENABLE_COLLECTION_LIB
typedef struct _list_t {
_ref_t ref;
@ -434,6 +434,7 @@ typedef enum _symbol_state_e {
} _symbol_state_e;
typedef struct _parsing_context_t {
_ls_node_t* imported;
char current_char;
char current_symbol[_SINGLE_SYMBOL_MAX_LENGTH + 1];
int current_symbol_nonius;
@ -913,7 +914,7 @@ static mb_print_func_t _get_printer(mb_interpreter_t* s);
static mb_input_func_t _get_inputer(mb_interpreter_t* s);
/** Parsing helpers */
static char* _load_file(const char* f, const char* prefix);
static char* _load_file(mb_interpreter_t* s, const char* f, const char* prefix);
static bool_t _is_blank(char c);
static bool_t _is_newline(char c);
@ -1022,6 +1023,7 @@ static int _destroy_object_not_compile_time(void* data, void* extra);
static int _destroy_object_capsule_only(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 _destroy_memory(void* data, void* extra);
static int _compare_numbers(const _object_t* first, const _object_t* second);
static bool_t _is_internal_object(_object_t* obj);
static _data_e _public_type_to_internal_type(mb_data_e t);
@ -1032,6 +1034,8 @@ static int _create_internal_object_from_public_value(mb_value_t* pbl, _object_t*
static void _try_clear_intermediate_value(void* data, void* extra, mb_interpreter_t* s);
static void _mark_lazy_destroy_string(mb_interpreter_t* s, char* ch);
static void _assign_public_value(mb_value_t* tgt, mb_value_t* src);
static int _clear_scope_chain(mb_interpreter_t* s);
static int _dispose_scope_chain(mb_interpreter_t* s);
static void _stepped(mb_interpreter_t* s, _ls_node_t* ast);
static int _execute_statement(mb_interpreter_t* s, _ls_node_t** l);
@ -1040,8 +1044,7 @@ static int _skip_if_chunk(mb_interpreter_t* s, _ls_node_t** l);
static int _skip_struct(mb_interpreter_t* s, _ls_node_t** l, mb_func_t open_func, mb_func_t close_func);
static _parsing_context_t* _reset_parsing_context(_parsing_context_t* context);
static int _clear_scope_chain(mb_interpreter_t* s);
static int _dispose_scope_chain(mb_interpreter_t* s);
static void _destroy_parsing_context(_parsing_context_t** context);
static int _register_func(mb_interpreter_t* s, const char* n, mb_func_t f, bool_t local);
static int _remove_func(mb_interpreter_t* s, const char* n, bool_t local);
@ -2729,13 +2732,25 @@ mb_input_func_t _get_inputer(mb_interpreter_t* s) {
return mb_gets;
}
char* _load_file(const char* f, const char* prefix) {
char* _load_file(mb_interpreter_t* s, const char* f, const char* prefix) {
/* Read all content of a file into a buffer */
FILE* fp = 0;
char* buf = 0;
long curpos = 0;
long l = 0;
long i = 0;
_parsing_context_t* context = 0;
mb_assert(s);
context = (_parsing_context_t*)s->parsing_context;
if(_ls_find(context->imported, (void*)f, (_ls_compare)_ht_cmp_string)) {
buf = (char*)f;
} else {
buf = (char*)mb_memdup((char*)f, strlen(f) + 1);
_ls_pushback(context->imported, buf);
buf = 0;
fp = fopen(f, "rb");
if(fp) {
@ -2756,6 +2771,7 @@ char* _load_file(const char* f, const char* prefix) {
fclose(fp);
buf[l] = '\0';
}
}
return buf;
}
@ -3179,10 +3195,12 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
context->last_symbol = 0;
sym[_sl - 1] = '\0';
context->parsing_state = _PS_NORMAL;
buf = _load_file(sym + 1, ":");
buf = _load_file(s, sym + 1, ":");
if(buf) {
if(buf != sym + 1) {
mb_load_string(s, buf);
safe_free(buf);
}
} else {
_set_current_error(s, SE_PS_FILE_OPEN_FAILED, 0);
if(s->error_handler) {
@ -5104,6 +5122,18 @@ int _remove_source_object(void* data, void* extra) {
return result;
}
int _destroy_memory(void* data, void* extra) {
/* Destroy a chunk of memory */
int result = _OP_RESULT_NORMAL;
mb_unrefvar(extra);
mb_assert(data);
safe_free(data);
return result;
}
int _compare_numbers(const _object_t* first, const _object_t* second) {
/* Compare two numbers in two _object_t */
int result = 0;
@ -5435,6 +5465,57 @@ void _assign_public_value(mb_value_t* tgt, mb_value_t* src) {
memcpy(tgt, src, sizeof(mb_value_t));
}
int _clear_scope_chain(mb_interpreter_t* s) {
/* Clear a scope chain */
int result = 0;
_running_context_t* running = 0;
_running_context_t* prev = 0;
_ht_node_t* global_scope = 0;
mb_assert(s);
running = s->running_context;
while(running) {
prev = running->prev;
global_scope = running->var_dict;
_ht_foreach(global_scope, _destroy_object);
_ht_clear(global_scope);
result++;
running = prev;
}
return result;
}
int _dispose_scope_chain(mb_interpreter_t* s) {
/* Dispose a scope chain */
int result = 0;
_running_context_t* running = 0;
_running_context_t* prev = 0;
_ht_node_t* global_scope = 0;
mb_assert(s);
running = s->running_context;
while(running) {
prev = running->prev;
global_scope = running->var_dict;
_ht_foreach(global_scope, _destroy_object);
_ht_clear(global_scope);
_ht_destroy(global_scope);
mb_dispose_value(s, running->intermediate_value);
safe_free(running);
result++;
running = prev;
}
return result;
}
void _stepped(mb_interpreter_t* s, _ls_node_t* ast) {
/* Called each step */
_object_t* obj = 0;
@ -5653,63 +5734,33 @@ _exit:
_parsing_context_t* _reset_parsing_context(_parsing_context_t* context) {
/* Reset the parsing context of a MY-BASIC environment */
_ls_node_t* imp = 0;
if(!context)
context = (_parsing_context_t*)mb_malloc(sizeof(_parsing_context_t));
else
imp = context->imported;
memset(context, 0, sizeof(_parsing_context_t));
context->parsing_row = 1;
if(!imp)
imp = _ls_create();
context->imported = imp;
return context;
}
int _clear_scope_chain(mb_interpreter_t* s) {
/* Clear a scope chain */
int result = 0;
_running_context_t* running = 0;
_running_context_t* prev = 0;
_ht_node_t* global_scope = 0;
void _destroy_parsing_context(_parsing_context_t** context) {
/* Destroy the parsing context of a MY-BASIC environment */
if(!context || !(*context))
return;
mb_assert(s);
running = s->running_context;
while(running) {
prev = running->prev;
global_scope = running->var_dict;
_ht_foreach(global_scope, _destroy_object);
_ht_clear(global_scope);
result++;
running = prev;
if(*context) {
if((*context)->imported) {
_ls_foreach((*context)->imported, _destroy_memory);
_ls_destroy((*context)->imported);
}
return result;
safe_free(*context);
}
int _dispose_scope_chain(mb_interpreter_t* s) {
/* Dispose a scope chain */
int result = 0;
_running_context_t* running = 0;
_running_context_t* prev = 0;
_ht_node_t* global_scope = 0;
mb_assert(s);
running = s->running_context;
while(running) {
prev = running->prev;
global_scope = running->var_dict;
_ht_foreach(global_scope, _destroy_object);
_ht_clear(global_scope);
_ht_destroy(global_scope);
mb_dispose_value(s, running->intermediate_value);
safe_free(running);
result++;
running = prev;
}
return result;
}
int _register_func(mb_interpreter_t* s, const char* n, mb_func_t f, bool_t local) {
@ -5978,7 +6029,6 @@ int mb_open(struct mb_interpreter_t** s) {
int result = MB_FUNC_OK;
_ht_node_t* local_scope = 0;
_ht_node_t* global_scope = 0;
_parsing_context_t* context = 0;
_running_context_t* running = 0;
*s = (mb_interpreter_t*)mb_malloc(sizeof(mb_interpreter_t));
@ -5992,7 +6042,7 @@ int mb_open(struct mb_interpreter_t** s) {
global_scope = _ht_create(0, _ht_cmp_string, _ht_hash_string, _ls_free_extra);
(*s)->global_func_dict = global_scope;
(*s)->parsing_context = context = _reset_parsing_context((*s)->parsing_context);
(*s)->parsing_context = _reset_parsing_context((*s)->parsing_context);
(*s)->temp_values = _ls_create();
(*s)->lazy_destroy_objects = _ls_create();
@ -6026,12 +6076,9 @@ int mb_close(struct mb_interpreter_t** s) {
_ht_node_t* local_scope = 0;
_ht_node_t* global_scope = 0;
_ls_node_t* ast;
_parsing_context_t* context = 0;
mb_assert(s);
context = (*s)->parsing_context;
#ifdef MB_ENABLE_COLLECTION_LIB
_close_coll_lib(*s);
#endif /* MB_ENABLE_COLLECTION_LIB */
@ -6051,9 +6098,7 @@ int mb_close(struct mb_interpreter_t** s) {
_ls_foreach((*s)->lazy_destroy_objects, _destroy_object);
_ls_destroy((*s)->lazy_destroy_objects);
if(context) {
safe_free(context);
}
_destroy_parsing_context(&(*s)->parsing_context);
global_scope = (*s)->global_func_dict;
_ht_foreach(global_scope, _ls_free_extra);
@ -6743,7 +6788,7 @@ int mb_load_file(struct mb_interpreter_t* s, const char* f) {
s->parsing_context = context = _reset_parsing_context(s->parsing_context);
buf = _load_file(f, 0);
buf = _load_file(s, f, 0);
if(buf) {
result = mb_load_string(s, buf);
safe_free(buf);
@ -6770,8 +6815,7 @@ int mb_run(struct mb_interpreter_t* s) {
running = s->running_context;
if(s->parsing_context)
safe_free(s->parsing_context);
_destroy_parsing_context(&s->parsing_context);
if(s->suspent_point) {
ast = s->suspent_point;