+developing lambda, added a _core_lambda function .

This commit is contained in:
paladin-t 2016-01-05 19:40:22 +08:00
parent 48cb90c234
commit 3b898b9460
2 changed files with 57 additions and 3 deletions

View File

@ -1,6 +1,7 @@
Jan. 5 2016 Jan. 5 2016
Developing lambda, added data structure Developing lambda, added data structure
Developing lambda, added a LAMBDA statement Developing lambda, added a LAMBDA statement
Developing lambda, added a _core_lambda function
Developing lambda, added an MB_ENABLE_LAMBDA macro Developing lambda, added an MB_ENABLE_LAMBDA macro
Jan. 4 2016 Jan. 4 2016

View File

@ -127,6 +127,7 @@ extern "C" {
#define _cmp_bytes(__l, __r) (memcmp((__l), (__r), sizeof(mb_val_bytes_t))) #define _cmp_bytes(__l, __r) (memcmp((__l), (__r), sizeof(mb_val_bytes_t)))
#define _mb_check(__expr, __exit) do { if((__expr) != MB_FUNC_OK) goto __exit; } while(0) #define _mb_check(__expr, __exit) do { if((__expr) != MB_FUNC_OK) goto __exit; } while(0)
#define _mb_check_mark(__expr, __err, __exit) do { __err |= (__expr) != MB_FUNC_OK; if(__err) goto __exit; } while(0)
#define DON(__o) ((__o) ? ((_object_t*)((__o)->data)) : 0) #define DON(__o) ((__o) ? ((_object_t*)((__o)->data)) : 0)
#define TON(__t) (((__t) && *(__t)) ? ((_object_t*)(((_tuple3_t*)(*(__t)))->e1)) : 0) #define TON(__t) (((__t) && *(__t)) ? ((_object_t*)(((_tuple3_t*)(*(__t)))->e1)) : 0)
@ -439,6 +440,7 @@ typedef struct _routine_t {
struct _running_context_ref_t* scope; struct _running_context_ref_t* scope;
_ls_node_t* entry; _ls_node_t* entry;
_ls_node_t* parameters; _ls_node_t* parameters;
_ls_node_t* upvalues;
} lambda; } lambda;
#endif /* MB_ENABLE_LAMBDA */ #endif /* MB_ENABLE_LAMBDA */
struct { struct {
@ -6027,6 +6029,10 @@ void _destroy_routine(_routine_t* r) {
break; break;
case _IT_LAMBDA: case _IT_LAMBDA:
_destroy_ref(&r->func.lambda.ref); _destroy_ref(&r->func.lambda.ref);
if(r->func.lambda.parameters)
_ls_destroy(r->func.lambda.parameters);
if(r->func.lambda.upvalues)
_ls_destroy(r->func.lambda.upvalues);
break; break;
case _IT_NATIVE: /* Do nothing */ case _IT_NATIVE: /* Do nothing */
@ -11415,20 +11421,67 @@ int _core_lambda(mb_interpreter_t* s, void** l) {
/* LAMBDA statement */ /* LAMBDA statement */
int result = MB_FUNC_OK; int result = MB_FUNC_OK;
mb_value_t ret; mb_value_t ret;
bool_t err = false;
_routine_t* routine = 0; _routine_t* routine = 0;
_ls_node_t* ast = 0;
int brackets = 0;
mb_assert(s && l); mb_assert(s && l);
routine = (_routine_t*)mb_malloc(sizeof(_routine_t)); routine = (_routine_t*)mb_malloc(sizeof(_routine_t));
_init_routine(s, routine, 0, 0); _init_routine(s, routine, 0, 0);
mb_check(mb_attempt_open_bracket(s, l)); /* Parameter list */
mb_check(mb_attempt_close_bracket(s, l)); _mb_check_mark(mb_attempt_open_bracket(s, l), err, _error);
while(mb_has_arg(s, l)) {
void* v = 0;
_mb_check_mark(mb_get_var(s, l, &v), err, _error);
if(!routine->func.lambda.parameters)
routine->func.lambda.parameters = _ls_create();
_ls_pushback(routine->func.lambda.parameters, v);
ast = (_ls_node_t*)*l;
if(_IS_FUNC(ast->data, _core_close_bracket))
break;
ast = ast->next;
*l = ast;
}
_mb_check_mark(mb_attempt_close_bracket(s, l), err, _error);
/* Lambda body */
ast = (_ls_node_t*)*l;
if(ast) ast = ast->prev;
*l = ast;
_mb_check_mark(mb_attempt_open_bracket(s, l), err, _error);
ast = (_ls_node_t*)*l;
routine->func.lambda.entry = ast;
while(ast && (brackets || !_IS_FUNC(ast->data, _core_close_bracket))) {
if(_IS_FUNC(ast->data, _core_open_bracket))
brackets++;
else if(_IS_FUNC(ast->data, _core_close_bracket))
brackets--;
ast = ast->next;
}
*l = ast;
_mb_check_mark(mb_attempt_close_bracket(s, l), err, _error);
/* Return the value */
ret.type = MB_DT_ROUTINE; ret.type = MB_DT_ROUTINE;
ret.value.routine = routine; ret.value.routine = routine;
mb_check(mb_push_value(s, l, ret)); _mb_check_mark(mb_push_value(s, l, ret), err, _error);
/* Error processing */
while(0) {
_error:
if(routine)
_destroy_routine(routine);
}
return result; return result;
} }