+added an mb_add_var function; +added an mb_set_routine function; +added native sub routine support.
This commit is contained in:
parent
04de3f6a58
commit
fd8f45a234
3
HISTORY
3
HISTORY
@ -1,6 +1,9 @@
|
|||||||
Dec. 15 2015
|
Dec. 15 2015
|
||||||
Added a pair of mb_begin_class/mb_end_class functions
|
Added a pair of mb_begin_class/mb_end_class functions
|
||||||
Added an mb_get_value_by_name function
|
Added an mb_get_value_by_name function
|
||||||
|
Added an mb_add_var function
|
||||||
|
Added an mb_set_routine function
|
||||||
|
Added native sub routine support
|
||||||
|
|
||||||
Dec. 13 2015
|
Dec. 13 2015
|
||||||
Avoided warnings
|
Avoided warnings
|
||||||
|
200
core/my_basic.c
200
core/my_basic.c
@ -225,6 +225,7 @@ static const char* _ERR_DESC[] = {
|
|||||||
"Jump label expected",
|
"Jump label expected",
|
||||||
"Variable expected",
|
"Variable expected",
|
||||||
"Invalid identifier usage",
|
"Invalid identifier usage",
|
||||||
|
"Duplicate identifier",
|
||||||
"Operator expected",
|
"Operator expected",
|
||||||
"Calculation error",
|
"Calculation error",
|
||||||
"Divide by zero",
|
"Divide by zero",
|
||||||
@ -393,11 +394,9 @@ typedef struct _routine_t {
|
|||||||
struct _running_context_t* scope;
|
struct _running_context_t* scope;
|
||||||
_ls_node_t* entry;
|
_ls_node_t* entry;
|
||||||
_ls_node_t* parameters;
|
_ls_node_t* parameters;
|
||||||
|
mb_routine_func_t functor;
|
||||||
} _routine_t;
|
} _routine_t;
|
||||||
|
|
||||||
typedef int (* _has_routine_arg)(struct mb_interpreter_t*, void**, mb_value_t*, unsigned, unsigned*, _routine_t*);
|
|
||||||
typedef int (* _pop_routine_arg)(struct mb_interpreter_t*, void**, mb_value_t*, unsigned, unsigned*, _routine_t*, mb_value_t*);
|
|
||||||
|
|
||||||
typedef union _raw_u { char c; int_t i; real_t r; void* p; mb_val_bytes_t b; } _raw_u;
|
typedef union _raw_u { char c; int_t i; real_t r; void* p; mb_val_bytes_t b; } _raw_u;
|
||||||
|
|
||||||
typedef unsigned char _raw_t[sizeof(_raw_u)];
|
typedef unsigned char _raw_t[sizeof(_raw_u)];
|
||||||
@ -971,12 +970,14 @@ static int _get_priority_index(mb_func_t op);
|
|||||||
static _object_t* _operate_operand(mb_interpreter_t* s, _object_t* optr, _object_t* opnd1, _object_t* opnd2, int* status);
|
static _object_t* _operate_operand(mb_interpreter_t* s, _object_t* optr, _object_t* opnd1, _object_t* opnd2, int* status);
|
||||||
static bool_t _is_expression_terminal(mb_interpreter_t* s, _object_t* obj);
|
static bool_t _is_expression_terminal(mb_interpreter_t* s, _object_t* obj);
|
||||||
static int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val);
|
static int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val);
|
||||||
static int _proc_args(mb_interpreter_t* s, _ls_node_t** l, _running_context_t* running, mb_value_t* va, unsigned ca, _routine_t* r, _has_routine_arg has_arg, _pop_routine_arg pop_arg, bool_t proc_ref);
|
static int _proc_args(mb_interpreter_t* s, _ls_node_t** l, _running_context_t* running, mb_value_t* va, unsigned ca, _routine_t* r, mb_has_routine_arg_func_t has_arg, mb_pop_routine_arg_func_t pop_arg, bool_t proc_ref);
|
||||||
static int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned ca, _routine_t* r, _has_routine_arg has_arg, _pop_routine_arg pop_arg);
|
static int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned ca, _routine_t* r, mb_has_routine_arg_func_t has_arg, mb_pop_routine_arg_func_t pop_arg);
|
||||||
static int _has_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, _routine_t* r);
|
static int _eval_script_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned ca, _routine_t* r, mb_has_routine_arg_func_t has_arg, mb_pop_routine_arg_func_t pop_arg);
|
||||||
static int _pop_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, _routine_t* r, mb_value_t* val);
|
static int _eval_native_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned ca, _routine_t* r, mb_has_routine_arg_func_t has_arg, mb_pop_routine_arg_func_t pop_arg);
|
||||||
static int _has_routine_fun_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, _routine_t* r);
|
static int _has_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, void* r);
|
||||||
static int _pop_routine_fun_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, _routine_t* r, mb_value_t* val);
|
static int _pop_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, void* r, mb_value_t* val);
|
||||||
|
static int _has_routine_fun_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, void* r);
|
||||||
|
static int _pop_routine_fun_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, void* r, mb_value_t* val);
|
||||||
static bool_t _is_print_terminal(mb_interpreter_t* s, _object_t* obj);
|
static bool_t _is_print_terminal(mb_interpreter_t* s, _object_t* obj);
|
||||||
|
|
||||||
/** Handlers */
|
/** Handlers */
|
||||||
@ -1255,7 +1256,7 @@ static int _clone_clsss_field(void* data, void* extra, void* n);
|
|||||||
static bool_t _clone_class_meta_link(_class_t* meta, void* n, void* ret);
|
static bool_t _clone_class_meta_link(_class_t* meta, void* n, void* ret);
|
||||||
static bool_t _is_class(_class_t* instance, void* m, void* ret);
|
static bool_t _is_class(_class_t* instance, void* m, void* ret);
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
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, mb_routine_func_t f);
|
||||||
static void _begin_routine(mb_interpreter_t* s);
|
static void _begin_routine(mb_interpreter_t* s);
|
||||||
static bool_t _end_routine(mb_interpreter_t* s);
|
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);
|
||||||
@ -2907,7 +2908,7 @@ _exit:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _proc_args(mb_interpreter_t* s, _ls_node_t** l, _running_context_t* running, mb_value_t* va, unsigned ca, _routine_t* r, _has_routine_arg has_arg, _pop_routine_arg pop_arg, bool_t proc_ref) {
|
int _proc_args(mb_interpreter_t* s, _ls_node_t** l, _running_context_t* running, mb_value_t* va, unsigned ca, _routine_t* r, mb_has_routine_arg_func_t has_arg, mb_pop_routine_arg_func_t pop_arg, bool_t proc_ref) {
|
||||||
/* Process arguments of a routine */
|
/* Process arguments of a routine */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
mb_value_t arg;
|
mb_value_t arg;
|
||||||
@ -2953,9 +2954,25 @@ int _proc_args(mb_interpreter_t* s, _ls_node_t** l, _running_context_t* running,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned ca, _routine_t* r, _has_routine_arg has_arg, _pop_routine_arg pop_arg) {
|
int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned ca, _routine_t* r, mb_has_routine_arg_func_t has_arg, mb_pop_routine_arg_func_t pop_arg) {
|
||||||
/* Evaluate a routine */
|
/* Evaluate a routine */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
|
|
||||||
|
if(r->entry) {
|
||||||
|
result = _eval_script_routine(s, l, va, ca, r, has_arg, pop_arg);
|
||||||
|
} else if(r->functor) {
|
||||||
|
result = _eval_native_routine(s, l, va, ca, r, has_arg, pop_arg);
|
||||||
|
} else {
|
||||||
|
_handle_error_on_obj(s, SE_RN_INVALID_ROUTINE, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _eval_script_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned ca, _routine_t* r, mb_has_routine_arg_func_t has_arg, mb_pop_routine_arg_func_t pop_arg) {
|
||||||
|
/* Evaluate a script routine */
|
||||||
|
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;
|
||||||
_routine_t* lastr = 0;
|
_routine_t* lastr = 0;
|
||||||
@ -3054,7 +3071,31 @@ _tail:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _has_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, _routine_t* r) {
|
int _eval_native_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned ca, _routine_t* r, mb_has_routine_arg_func_t has_arg, mb_pop_routine_arg_func_t pop_arg) {
|
||||||
|
/* Evaluate a native routine */
|
||||||
|
int result = MB_FUNC_OK;
|
||||||
|
_routine_t* lastr = 0;
|
||||||
|
mb_routine_func_t entry = 0;
|
||||||
|
|
||||||
|
mb_assert(s && l && r);
|
||||||
|
|
||||||
|
lastr = s->last_routine;
|
||||||
|
s->last_routine = r;
|
||||||
|
|
||||||
|
entry = r->functor;
|
||||||
|
if(!entry) {
|
||||||
|
_handle_error_on_obj(s, SE_RN_INVALID_ROUTINE, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = entry(s, l, va, ca, r, has_arg, pop_arg);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
s->last_routine = lastr;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _has_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, void* r) {
|
||||||
/* Detect if there is any more lexical argument */
|
/* Detect if there is any more lexical argument */
|
||||||
mb_unrefvar(va);
|
mb_unrefvar(va);
|
||||||
mb_unrefvar(ca);
|
mb_unrefvar(ca);
|
||||||
@ -3064,7 +3105,7 @@ int _has_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned
|
|||||||
return mb_has_arg(s, l);
|
return mb_has_arg(s, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _pop_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, _routine_t* r, mb_value_t* val) {
|
int _pop_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, void* r, mb_value_t* val) {
|
||||||
/* Pop a lexical argument */
|
/* Pop a lexical argument */
|
||||||
mb_unrefvar(va);
|
mb_unrefvar(va);
|
||||||
mb_unrefvar(ca);
|
mb_unrefvar(ca);
|
||||||
@ -3074,7 +3115,7 @@ int _pop_routine_lex_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned
|
|||||||
return mb_pop_value(s, l, val);
|
return mb_pop_value(s, l, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _has_routine_fun_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, _routine_t* r) {
|
int _has_routine_fun_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, void* r) {
|
||||||
/* Detect if there is any more argument in the argument list */
|
/* Detect if there is any more argument in the argument list */
|
||||||
mb_unrefvar(s);
|
mb_unrefvar(s);
|
||||||
mb_unrefvar(l);
|
mb_unrefvar(l);
|
||||||
@ -3084,7 +3125,7 @@ int _has_routine_fun_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned
|
|||||||
return *ia < ca;
|
return *ia < ca;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _pop_routine_fun_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, _routine_t* r, mb_value_t* val) {
|
int _pop_routine_fun_arg(mb_interpreter_t* s, void** l, mb_value_t* va, unsigned ca, unsigned* ia, void* r, mb_value_t* val) {
|
||||||
/* Pop an argument from the argument list */
|
/* Pop an argument from the argument list */
|
||||||
mb_unrefvar(s);
|
mb_unrefvar(s);
|
||||||
mb_unrefvar(l);
|
mb_unrefvar(l);
|
||||||
@ -3505,7 +3546,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
|||||||
} 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, 0);
|
||||||
_push_scope_by_routine(s, tmp.routine->scope);
|
_push_scope_by_routine(s, tmp.routine->scope);
|
||||||
(*obj)->data.routine = tmp.routine;
|
(*obj)->data.routine = tmp.routine;
|
||||||
|
|
||||||
@ -5593,7 +5634,7 @@ bool_t _is_class(_class_t* instance, void* m, void* ret) {
|
|||||||
}
|
}
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
|
||||||
void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n) {
|
void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n, mb_routine_func_t f) {
|
||||||
/* Initialize a routine */
|
/* Initialize a routine */
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
|
|
||||||
@ -5603,10 +5644,12 @@ void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n) {
|
|||||||
|
|
||||||
memset(routine, 0, sizeof(_routine_t));
|
memset(routine, 0, sizeof(_routine_t));
|
||||||
routine->name = n;
|
routine->name = n;
|
||||||
|
if(!f) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _begin_routine(mb_interpreter_t* s) {
|
void _begin_routine(mb_interpreter_t* s) {
|
||||||
/* Begin parsing a routine */
|
/* Begin parsing a routine */
|
||||||
@ -5822,6 +5865,7 @@ _running_context_t* _push_weak_scope_by_routine(mb_interpreter_t* s, _running_co
|
|||||||
|
|
||||||
if(_find_scope(s, p))
|
if(_find_scope(s, p))
|
||||||
p = _reference_scope_by_routine(s, p, r);
|
p = _reference_scope_by_routine(s, p, r);
|
||||||
|
if(p)
|
||||||
p->prev = s->running_context;
|
p->prev = s->running_context;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
@ -5833,8 +5877,10 @@ _running_context_t* _push_scope_by_routine(mb_interpreter_t* s, _running_context
|
|||||||
|
|
||||||
if(_find_scope(s, p))
|
if(_find_scope(s, p))
|
||||||
p = _reference_scope_by_routine(s, p, 0);
|
p = _reference_scope_by_routine(s, p, 0);
|
||||||
|
if(p) {
|
||||||
p->prev = s->running_context;
|
p->prev = s->running_context;
|
||||||
s->running_context = p;
|
s->running_context = p;
|
||||||
|
}
|
||||||
|
|
||||||
return s->running_context;
|
return s->running_context;
|
||||||
}
|
}
|
||||||
@ -5854,6 +5900,7 @@ _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);
|
||||||
|
|
||||||
|
if(p)
|
||||||
p->prev = 0;
|
p->prev = 0;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
@ -6177,11 +6224,13 @@ int _dispose_object(_object_t* obj) {
|
|||||||
case _DT_ROUTINE:
|
case _DT_ROUTINE:
|
||||||
if(!obj->ref) {
|
if(!obj->ref) {
|
||||||
safe_free(obj->data.routine->name);
|
safe_free(obj->data.routine->name);
|
||||||
|
if(obj->data.routine->scope) {
|
||||||
if(obj->data.routine->scope->var_dict) {
|
if(obj->data.routine->scope->var_dict) {
|
||||||
_ht_foreach(obj->data.routine->scope->var_dict, _destroy_object);
|
_ht_foreach(obj->data.routine->scope->var_dict, _destroy_object);
|
||||||
_ht_destroy(obj->data.routine->scope->var_dict);
|
_ht_destroy(obj->data.routine->scope->var_dict);
|
||||||
}
|
}
|
||||||
safe_free(obj->data.routine->scope);
|
safe_free(obj->data.routine->scope);
|
||||||
|
}
|
||||||
if(obj->data.routine->parameters)
|
if(obj->data.routine->parameters)
|
||||||
_ls_destroy(obj->data.routine->parameters);
|
_ls_destroy(obj->data.routine->parameters);
|
||||||
safe_free(obj->data.routine);
|
safe_free(obj->data.routine);
|
||||||
@ -6564,6 +6613,10 @@ int _internal_object_to_public_value(_object_t* itn, mb_value_t* pbl) {
|
|||||||
mb_assert(pbl && itn);
|
mb_assert(pbl && itn);
|
||||||
|
|
||||||
switch(itn->type) {
|
switch(itn->type) {
|
||||||
|
case _DT_VAR:
|
||||||
|
result = _internal_object_to_public_value(itn->data.variable->data, pbl);
|
||||||
|
|
||||||
|
break;
|
||||||
case _DT_TYPE:
|
case _DT_TYPE:
|
||||||
pbl->type = MB_DT_TYPE;
|
pbl->type = MB_DT_TYPE;
|
||||||
pbl->value.type = itn->data.type;
|
pbl->value.type = itn->data.type;
|
||||||
@ -8126,6 +8179,7 @@ int mb_push_value(struct mb_interpreter_t* s, void** l, mb_value_t val) {
|
|||||||
|
|
||||||
int mb_begin_class(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t** meta, int c, mb_value_t* out) {
|
int mb_begin_class(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t** meta, int c, mb_value_t* out) {
|
||||||
/* Begin a class */
|
/* Begin a class */
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
_class_t* instance = 0;
|
_class_t* instance = 0;
|
||||||
_object_t* obj = 0;
|
_object_t* obj = 0;
|
||||||
@ -8181,10 +8235,21 @@ int mb_begin_class(struct mb_interpreter_t* s, void** l, const char* n, mb_value
|
|||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
return result;
|
return result;
|
||||||
|
#else /* MB_ENABLE_CLASS */
|
||||||
|
mb_unrefvar(s);
|
||||||
|
mb_unrefvar(l);
|
||||||
|
mb_unrefvar(n);
|
||||||
|
mb_unrefvar(meta);
|
||||||
|
mb_unrefvar(c);
|
||||||
|
mb_unrefvar(out);
|
||||||
|
|
||||||
|
return MB_FUNC_ERR;
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
}
|
}
|
||||||
|
|
||||||
int mb_end_class(struct mb_interpreter_t* s, void** l) {
|
int mb_end_class(struct mb_interpreter_t* s, void** l) {
|
||||||
/* End a class */
|
/* End a class */
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
|
|
||||||
mb_assert(s && l);
|
mb_assert(s && l);
|
||||||
@ -8192,6 +8257,12 @@ int mb_end_class(struct mb_interpreter_t* s, void** l) {
|
|||||||
_pop_scope(s);
|
_pop_scope(s);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
#else /* MB_ENABLE_CLASS */
|
||||||
|
mb_unrefvar(s);
|
||||||
|
mb_unrefvar(l);
|
||||||
|
|
||||||
|
return MB_FUNC_ERR;
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
}
|
}
|
||||||
|
|
||||||
int mb_get_value_by_name(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t* val) {
|
int mb_get_value_by_name(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t* val) {
|
||||||
@ -8213,15 +8284,46 @@ int mb_get_value_by_name(struct mb_interpreter_t* s, void** l, const char* n, mb
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mb_add_var(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t val) {
|
int mb_add_var(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t val, bool_t force) {
|
||||||
/* Add a variable with a specific name */
|
/* Add a variable with a specific name */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
mb_unrefvar(s);
|
_running_context_t* running = 0;
|
||||||
mb_unrefvar(l);
|
_object_t* obj = 0;
|
||||||
mb_unrefvar(n);
|
_var_t* var = 0;
|
||||||
mb_unrefvar(val);
|
_ls_node_t* tmp = 0;
|
||||||
/* TODO */
|
|
||||||
|
|
||||||
|
mb_assert(s && l && n);
|
||||||
|
|
||||||
|
running = s->running_context;
|
||||||
|
|
||||||
|
tmp = _ht_find(running->var_dict, (void*)n);
|
||||||
|
|
||||||
|
if(tmp) {
|
||||||
|
if(force) {
|
||||||
|
result = mb_set_var_value(s, tmp->data, val);
|
||||||
|
|
||||||
|
goto _exit;
|
||||||
|
} else {
|
||||||
|
_handle_error_on_obj(s, SE_RN_DUPLICATE_ID, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var = (_var_t*)mb_malloc(sizeof(_var_t));
|
||||||
|
memset(var, 0, sizeof(_var_t));
|
||||||
|
var->name = mb_memdup(n, (unsigned)(strlen(n) + 1));
|
||||||
|
var->data = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||||
|
_MAKE_NIL(var->data);
|
||||||
|
_public_value_to_internal_object(&val, var->data);
|
||||||
|
|
||||||
|
obj = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||||
|
_MAKE_NIL(obj);
|
||||||
|
obj->type = _DT_VAR;
|
||||||
|
obj->data.variable = var;
|
||||||
|
obj->ref = false;
|
||||||
|
|
||||||
|
_ht_set_or_insert(running->var_dict, var->name, obj);
|
||||||
|
|
||||||
|
_exit:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8762,15 +8864,53 @@ _exit:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mb_set_routine(struct mb_interpreter_t* s, void** l, const char* n, mb_func_t f) {
|
int mb_set_routine(struct mb_interpreter_t* s, void** l, const char* n, mb_routine_func_t f, bool_t force) {
|
||||||
/* Set a sub routine with a specific name and functor */
|
/* Set a sub routine with a specific name and functor */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
mb_unrefvar(s);
|
_running_context_t* running = 0;
|
||||||
mb_unrefvar(l);
|
_object_t* obj = 0;
|
||||||
mb_unrefvar(n);
|
_routine_t* routine = 0;
|
||||||
mb_unrefvar(f);
|
_ls_node_t* tmp = 0;
|
||||||
/* TODO */
|
_var_t* var = 0;
|
||||||
|
|
||||||
|
mb_assert(s && l);
|
||||||
|
|
||||||
|
running = s->running_context;
|
||||||
|
|
||||||
|
tmp = _ht_find(running->var_dict, (void*)n);
|
||||||
|
|
||||||
|
if(tmp) {
|
||||||
|
if(force) {
|
||||||
|
obj = (_object_t*)tmp->data;
|
||||||
|
if(obj->type == _DT_VAR)
|
||||||
|
var = obj->data.variable;
|
||||||
|
} else {
|
||||||
|
_handle_error_on_obj(s, SE_RN_DUPLICATE_ROUTINE, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
routine = (_routine_t*)mb_malloc(sizeof(_routine_t));
|
||||||
|
_init_routine(s, routine, mb_memdup(n, (unsigned)(strlen(n) + 1)), f);
|
||||||
|
routine->functor = f;
|
||||||
|
|
||||||
|
obj = (_object_t*)mb_malloc(sizeof(_object_t));
|
||||||
|
_MAKE_NIL(obj);
|
||||||
|
obj->type = _DT_ROUTINE;
|
||||||
|
obj->data.routine = routine;
|
||||||
|
obj->ref = false;
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
routine->instance = s->last_instance;
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
|
||||||
|
if(var && force) {
|
||||||
|
_destroy_object(var->data, 0);
|
||||||
|
var->data = obj;
|
||||||
|
} else {
|
||||||
|
_ht_set_or_insert(running->var_dict, routine->name, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
_exit:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,6 +302,7 @@ typedef enum mb_error_e {
|
|||||||
SE_RN_JUMP_LABEL_EXPECTED,
|
SE_RN_JUMP_LABEL_EXPECTED,
|
||||||
SE_RN_VARIABLE_EXPECTED,
|
SE_RN_VARIABLE_EXPECTED,
|
||||||
SE_RN_INVALID_ID_USAGE,
|
SE_RN_INVALID_ID_USAGE,
|
||||||
|
SE_RN_DUPLICATE_ID,
|
||||||
SE_RN_OPERATOR_EXPECTED,
|
SE_RN_OPERATOR_EXPECTED,
|
||||||
SE_RN_CALCULATION_ERROR,
|
SE_RN_CALCULATION_ERROR,
|
||||||
SE_RN_DIVIDE_BY_ZERO,
|
SE_RN_DIVIDE_BY_ZERO,
|
||||||
@ -385,6 +386,9 @@ typedef struct mb_value_t {
|
|||||||
typedef unsigned short mb_mem_tag_t;
|
typedef unsigned short mb_mem_tag_t;
|
||||||
|
|
||||||
typedef int (* mb_func_t)(struct mb_interpreter_t*, void**);
|
typedef int (* mb_func_t)(struct mb_interpreter_t*, void**);
|
||||||
|
typedef int (* mb_has_routine_arg_func_t)(struct mb_interpreter_t*, void**, mb_value_t*, unsigned, unsigned*, void*);
|
||||||
|
typedef int (* mb_pop_routine_arg_func_t)(struct mb_interpreter_t*, void**, mb_value_t*, unsigned, unsigned*, void*, mb_value_t*);
|
||||||
|
typedef int (* mb_routine_func_t)(struct mb_interpreter_t*, void**, mb_value_t*, unsigned, void*, mb_has_routine_arg_func_t, mb_pop_routine_arg_func_t);
|
||||||
typedef void (* mb_debug_stepped_handler_t)(struct mb_interpreter_t*, int, unsigned short, unsigned short);
|
typedef void (* mb_debug_stepped_handler_t)(struct mb_interpreter_t*, int, unsigned short, unsigned short);
|
||||||
typedef void (* mb_error_handler_t)(struct mb_interpreter_t*, enum mb_error_e, char*, char*, int, unsigned short, unsigned short, int);
|
typedef void (* mb_error_handler_t)(struct mb_interpreter_t*, enum mb_error_e, char*, char*, int, unsigned short, unsigned short, int);
|
||||||
typedef int (* mb_print_func_t)(const char*, ...);
|
typedef int (* mb_print_func_t)(const char*, ...);
|
||||||
@ -433,7 +437,7 @@ MBAPI int mb_begin_class(struct mb_interpreter_t* s, void** l, const char* n, mb
|
|||||||
MBAPI int mb_end_class(struct mb_interpreter_t* s, void** l);
|
MBAPI int mb_end_class(struct mb_interpreter_t* s, void** l);
|
||||||
|
|
||||||
MBAPI int mb_get_value_by_name(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t* val);
|
MBAPI int mb_get_value_by_name(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t* val);
|
||||||
MBAPI int mb_add_var(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t val);
|
MBAPI int mb_add_var(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t val, bool_t force);
|
||||||
MBAPI int mb_get_var(struct mb_interpreter_t* s, void** l, void** v);
|
MBAPI int mb_get_var(struct mb_interpreter_t* s, void** l, void** v);
|
||||||
MBAPI int mb_get_var_value(struct mb_interpreter_t* s, void* v, mb_value_t* val);
|
MBAPI int mb_get_var_value(struct mb_interpreter_t* s, void* v, mb_value_t* val);
|
||||||
MBAPI int mb_set_var_value(struct mb_interpreter_t* s, void* v, mb_value_t val);
|
MBAPI int mb_set_var_value(struct mb_interpreter_t* s, void* v, mb_value_t val);
|
||||||
@ -453,7 +457,7 @@ MBAPI int mb_unref_value(struct mb_interpreter_t* s, void** l, mb_value_t val);
|
|||||||
MBAPI int mb_dispose_value(struct mb_interpreter_t* s, mb_value_t val);
|
MBAPI int mb_dispose_value(struct mb_interpreter_t* s, mb_value_t val);
|
||||||
|
|
||||||
MBAPI int mb_get_routine(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t* val);
|
MBAPI int mb_get_routine(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t* val);
|
||||||
MBAPI int mb_set_routine(struct mb_interpreter_t* s, void** l, const char* n, mb_func_t f);
|
MBAPI int mb_set_routine(struct mb_interpreter_t* s, void** l, const char* n, mb_routine_func_t f, bool_t force);
|
||||||
MBAPI int mb_eval_routine(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_value_t* args, unsigned argc);
|
MBAPI int mb_eval_routine(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_value_t* args, unsigned argc);
|
||||||
|
|
||||||
MBAPI int mb_load_string(struct mb_interpreter_t* s, const char* l);
|
MBAPI int mb_load_string(struct mb_interpreter_t* s, const char* l);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user