+developing lambda, added lambda evaluation.

This commit is contained in:
paladin-t 2016-01-07 20:13:37 +08:00
parent 552c975401
commit 6033366ec1
2 changed files with 74 additions and 21 deletions

View File

@ -1,6 +1,7 @@
Jan. 7 2016 Jan. 7 2016
Developing lambda, added parameter and upvalue processing Developing lambda, added parameter and upvalue processing
Developing lambda, added closure maintenance Developing lambda, added closure maintenance
Developing lambda, added lambda evaluation
Developing lambda, added lambda unreferencing functions Developing lambda, added lambda unreferencing functions
Jan. 6 2016 Jan. 6 2016

View File

@ -1407,6 +1407,8 @@ static int _do_nothing_on_ht_for_lambda(void* data, void* extra);
static int _fill_with_upvalue(void* data, void* extra, void* p); static int _fill_with_upvalue(void* data, void* extra, void* p);
static int _remove_filled_upvalue(void* data, void* extra, void* u); static int _remove_filled_upvalue(void* data, void* extra, void* u);
static int _fill_outer_scope(void* data, void* extra, void* t); static int _fill_outer_scope(void* data, void* extra, void* t);
static _running_context_t* _link_lambda_scope_chain(mb_interpreter_t* s, _lambda_t* lambda, _running_context_t* running, bool_t weak);
static _running_context_t* _unlink_lambda_scope_chain(mb_interpreter_t* s, _lambda_t* lambda, _running_context_t* running, bool_t weak);
#endif /* MB_ENABLE_LAMBDA */ #endif /* MB_ENABLE_LAMBDA */
#ifdef MB_ENABLE_CLASS #ifdef MB_ENABLE_CLASS
static _running_context_t* _reference_scope_by_class(mb_interpreter_t* s, _running_context_t* p, _class_t* c); static _running_context_t* _reference_scope_by_class(mb_interpreter_t* s, _running_context_t* p, _class_t* c);
@ -1422,6 +1424,7 @@ static _running_context_t* _pop_weak_scope(mb_interpreter_t* s, _running_context
static _running_context_t* _pop_scope(mb_interpreter_t* s, bool_t tidy); static _running_context_t* _pop_scope(mb_interpreter_t* s, bool_t tidy);
static void _out_of_scope(mb_interpreter_t* s, _running_context_t* running); static void _out_of_scope(mb_interpreter_t* s, _running_context_t* running);
static _running_context_t* _find_scope(mb_interpreter_t* s, _running_context_t* p); static _running_context_t* _find_scope(mb_interpreter_t* s, _running_context_t* p);
static _running_context_t* _get_root_scope(_running_context_t* scope);
static _running_context_t* _get_scope_to_add_routine(mb_interpreter_t* s); static _running_context_t* _get_scope_to_add_routine(mb_interpreter_t* s);
static _ls_node_t* _search_identifier_in_scope_chain(mb_interpreter_t* s, _running_context_t* scope, const char* n, int pathing, _ht_node_t** ht, _running_context_t** sp); static _ls_node_t* _search_identifier_in_scope_chain(mb_interpreter_t* s, _running_context_t* scope, const char* n, int pathing, _ht_node_t** ht, _running_context_t** sp);
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);
@ -1455,7 +1458,7 @@ static int _clear_scope_chain(mb_interpreter_t* s);
static int _dispose_scope_chain(mb_interpreter_t* s); static int _dispose_scope_chain(mb_interpreter_t* s);
static void _tidy_scope_chain(mb_interpreter_t* s); static void _tidy_scope_chain(mb_interpreter_t* s);
static void _tidy_intermediate_value(_ref_t* ref, void* data); static void _tidy_intermediate_value(_ref_t* ref, void* data);
static _object_t* _eval_var_in_print(mb_interpreter_t* s, _ls_node_t* ast, _object_t* obj); static _object_t* _eval_var_in_print(mb_interpreter_t* s, _ls_node_t** ast, _object_t* obj);
static void _stepped(mb_interpreter_t* s, _ls_node_t* ast); static void _stepped(mb_interpreter_t* s, _ls_node_t* ast);
static int _execute_statement(mb_interpreter_t* s, _ls_node_t** l); static int _execute_statement(mb_interpreter_t* s, _ls_node_t** l);
@ -3344,17 +3347,14 @@ int _eval_lambda_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, un
mb_check(mb_attempt_open_bracket(s, (void**)l)); mb_check(mb_attempt_open_bracket(s, (void**)l));
} }
running = _push_weak_scope_by_routine(s, r->func.lambda.scope, r); running = _link_lambda_scope_chain(s, &r->func.lambda, 0, true);
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) _unlink_lambda_scope_chain(s, &r->func.lambda, running, true);
_destroy_scope(s, running);
else
_pop_weak_scope(s, running);
goto _exit; goto _exit;
} }
running = _pop_weak_scope(s, running); running = _unlink_lambda_scope_chain(s, &r->func.lambda, running, true);
if(!va) { if(!va) {
mb_check(mb_attempt_close_bracket(s, (void**)l)); mb_check(mb_attempt_close_bracket(s, (void**)l));
@ -3363,7 +3363,7 @@ int _eval_lambda_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, un
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_by_routine(s, running); running = _link_lambda_scope_chain(s, 0, running, false);
*l = r->func.lambda.entry; *l = r->func.lambda.entry;
if(!(*l)) { if(!(*l)) {
@ -3400,16 +3400,18 @@ int _eval_lambda_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, un
_swap_public_value(&inte, &running->intermediate_value); _swap_public_value(&inte, &running->intermediate_value);
_pop_scope(s, true); _unlink_lambda_scope_chain(s, &r->func.lambda, 0, false);
_assign_public_value(&s->running_context->intermediate_value, &inte); _assign_public_value(&s->running_context->intermediate_value, &inte);
_exit: _exit:
if(result != MB_FUNC_OK) if(result != MB_FUNC_OK)
_pop_scope(s, true); _unlink_lambda_scope_chain(s, &r->func.lambda, 0, false);
s->last_routine = lastr; s->last_routine = lastr;
*l = ast;
return result; return result;
} }
#endif /* MB_ENABLE_LAMBDA */ #endif /* MB_ENABLE_LAMBDA */
@ -6339,14 +6341,50 @@ int _fill_outer_scope(void* data, void* extra, void* t) {
_HT_FOREACH(tuple->filled, _do_nothing_on_ht_for_lambda, _remove_filled_upvalue, lambda->upvalues); _HT_FOREACH(tuple->filled, _do_nothing_on_ht_for_lambda, _remove_filled_upvalue, lambda->upvalues);
_ht_destroy(tuple->filled); _ht_destroy(tuple->filled);
if(lambda->outer_scope) if(lambda->outer_scope) {
tuple->outer_scope->scope->prev = lambda->outer_scope->scope; if(tuple->outer_scope->scope != lambda->outer_scope->scope)
tuple->outer_scope->scope->prev = lambda->outer_scope->scope;
}
tuple->outer_scope->prev = lambda->outer_scope; if(tuple->outer_scope != lambda->outer_scope) {
lambda->outer_scope = tuple->outer_scope; tuple->outer_scope->prev = lambda->outer_scope;
lambda->outer_scope = tuple->outer_scope;
}
return 0; return 0;
} }
_running_context_t* _link_lambda_scope_chain(mb_interpreter_t* s, _lambda_t* lambda, _running_context_t* running, bool_t weak) {
/* Link a lambda's local scope and its upvalue scope chain to a given scope */
_running_context_t* result = 0;
if(lambda) {
lambda->scope->prev = lambda->outer_scope->scope;
result = _get_root_scope(lambda->scope);
}
if(weak)
result = _push_weak_scope_by_routine(s, lambda->scope, 0);
else
result = _push_scope_by_routine(s, running);
return result;
}
_running_context_t* _unlink_lambda_scope_chain(mb_interpreter_t* s, _lambda_t* lambda, _running_context_t* running, bool_t weak) {
/* Unlink a lambda's local scope and its upvalue scope chain from a given scope */
_running_context_t* result = 0;
if(weak)
result = _pop_weak_scope(s, running);
else
result = _pop_scope(s, true);
if(lambda)
lambda->scope->prev = 0;
return result;
}
#endif /* MB_ENABLE_LAMBDA */ #endif /* MB_ENABLE_LAMBDA */
#ifdef MB_ENABLE_CLASS #ifdef MB_ENABLE_CLASS
@ -6590,6 +6628,18 @@ _running_context_t* _find_scope(mb_interpreter_t* s, _running_context_t* p) {
return running; return running;
} }
_running_context_t* _get_root_scope(_running_context_t* scope) {
/* Get the root scope in a scope chain */
_running_context_t* result = 0;
while(scope) {
result = scope;
scope = scope->prev;
}
return result;
}
_running_context_t* _get_scope_to_add_routine(mb_interpreter_t* s) { _running_context_t* _get_scope_to_add_routine(mb_interpreter_t* s) {
/* Get a proper scope to add a routine */ /* Get a proper scope to add a routine */
_parsing_context_t* context = 0; _parsing_context_t* context = 0;
@ -7582,25 +7632,25 @@ void _tidy_intermediate_value(_ref_t* ref, void* data) {
} }
} }
_object_t* _eval_var_in_print(mb_interpreter_t* s, _ls_node_t* ast, _object_t* obj) { _object_t* _eval_var_in_print(mb_interpreter_t* s, _ls_node_t** ast, _object_t* obj) {
/* Evaluate a variable, this is a helper function for the PRINT statement */ /* Evaluate a variable, this is a helper function for the PRINT statement */
_object_t* val_ptr = 0; _object_t* val_ptr = 0;
_object_t tmp; _object_t tmp;
if(obj->type == _DT_ROUTINE) { if(obj->type == _DT_ROUTINE) {
_execute_statement(s, &ast); _execute_statement(s, ast);
_MAKE_NIL(&tmp); _MAKE_NIL(&tmp);
_public_value_to_internal_object(&s->running_context->intermediate_value, &tmp); _public_value_to_internal_object(&s->running_context->intermediate_value, &tmp);
val_ptr = obj = &tmp; val_ptr = obj = &tmp;
if(tmp.type == _DT_STRING) if(tmp.type == _DT_STRING)
tmp.data.string = mb_strdup(tmp.data.string, strlen(tmp.data.string) + 1); tmp.data.string = mb_strdup(tmp.data.string, strlen(tmp.data.string) + 1);
if(ast) ast = ast->prev; if(*ast) *ast = (*ast)->prev;
} else if(obj->type == _DT_VAR) { } else if(obj->type == _DT_VAR) {
val_ptr = obj = obj->data.variable->data; val_ptr = obj = obj->data.variable->data;
if(ast) ast = ast->next; if(*ast) *ast = (*ast)->next;
} else { } else {
val_ptr = obj; val_ptr = obj;
if(ast) ast = ast->next; if(*ast) *ast = (*ast)->next;
} }
return val_ptr; return val_ptr;
@ -11867,6 +11917,8 @@ int _core_lambda(mb_interpreter_t* s, void** l) {
/* Lambda body */ /* Lambda body */
ast = (_ls_node_t*)*l; ast = (_ls_node_t*)*l;
if(ast) ast = ast->prev; if(ast) ast = ast->prev;
while(ast && _IS_EOS(ast->next->data))
ast = ast->next;
*l = ast; *l = ast;
_mb_check_mark(mb_attempt_open_bracket(s, l), err, _error); _mb_check_mark(mb_attempt_open_bracket(s, l), err, _error);
@ -12838,7 +12890,7 @@ int _std_print(mb_interpreter_t* s, void** l) {
case _DT_VAR: case _DT_VAR:
if(obj->data.variable->data->type == _DT_ROUTINE) { if(obj->data.variable->data->type == _DT_ROUTINE) {
obj = obj->data.variable->data; obj = obj->data.variable->data;
val_ptr = _eval_var_in_print(s, ast, obj); val_ptr = _eval_var_in_print(s, &ast, obj);
goto _print; goto _print;
} }
@ -12848,7 +12900,7 @@ int _std_print(mb_interpreter_t* s, void** l) {
if(pathed && pathed->data) { if(pathed && pathed->data) {
if(obj != (_object_t*)pathed->data) { if(obj != (_object_t*)pathed->data) {
obj = (_object_t*)pathed->data; obj = (_object_t*)pathed->data;
val_ptr = _eval_var_in_print(s, ast, obj); val_ptr = _eval_var_in_print(s, &ast, obj);
} }
} }