// Add provided and delegated methods to the given entity. static bool trait_entity(ast_t* entity, pass_opt_t* opt) { assert(entity != NULL); int state = ast_checkflag(entity, AST_FLAG_RECURSE_1 | AST_FLAG_DONE_1 | AST_FLAG_ERROR_1); // Check for recursive definitions switch(state) { case 0: ast_setflag(entity, AST_FLAG_RECURSE_1); break; case AST_FLAG_RECURSE_1: ast_error(opt->check.errors, entity, "traits and interfaces can't be recursive"); ast_clearflag(entity, AST_FLAG_RECURSE_1); ast_setflag(entity, AST_FLAG_ERROR_1); return false; case AST_FLAG_DONE_1: return true; case AST_FLAG_ERROR_1: return false; default: assert(0); return false; } setup_local_methods(entity); bool r = delegated_methods(entity, opt) && provided_methods(entity, opt) && check_concrete_bodies(entity, opt); tidy_up(entity); ast_clearflag(entity, AST_FLAG_RECURSE_1); ast_setflag(entity, AST_FLAG_DONE_1); return r; }
// Add provided methods to the given entity static bool trait_entity(ast_t* entity, pass_opt_t* options) { assert(entity != NULL); int state = ast_checkflag(entity, AST_FLAG_RECURSE_1 | AST_FLAG_DONE_1 | AST_FLAG_ERROR_1); // Check for recursive definitions switch(state) { case 0: ast_setflag(entity, AST_FLAG_RECURSE_1); break; case AST_FLAG_RECURSE_1: ast_error(entity, "traits and interfaces can't be recursive"); ast_clearflag(entity, AST_FLAG_RECURSE_1); ast_setflag(entity, AST_FLAG_ERROR_1); return false; case AST_FLAG_DONE_1: return true; case AST_FLAG_ERROR_1: return false; default: assert(0); return false; } setup_local_methods(entity); bool r = provides_list(entity, options) && // Stage 1 provided_methods(options, entity) && // Stage 2 field_delegations(entity) && // Stage 3 resolve_methods(entity, options); // Stage 4 tidy_up(entity); ast_clearflag(entity, AST_FLAG_RECURSE_1); ast_setflag(entity, AST_FLAG_DONE_1); return r; }
// Add provided methods to the given entity static bool trait_entity(ast_t* entity, pass_opt_t* options) { assert(entity != NULL); ast_state_t state = (ast_state_t)(uint64_t)ast_data(entity); // Check for recursive definitions switch(state) { case AST_STATE_INITIAL: ast_setdata(entity, (void*)AST_STATE_INPROGRESS); break; case AST_STATE_INPROGRESS: ast_error(entity, "traits and interfaces can't be recursive"); ast_setdata(entity, (void*)AST_STATE_ERROR); return false; case AST_STATE_DONE: return true; case AST_STATE_ERROR: return false; default: assert(0); return false; } setup_local_methods(entity); bool r = provides_list(entity, options) && // Stage 1 provided_methods(entity) && // Stage 2 field_delegations(entity) && // Stage 3 resolve_methods(entity, options); // Stage 4 tidy_up(entity); ast_setdata(entity, r ? (void*)AST_STATE_DONE : (void*)AST_STATE_ERROR); return r; }