void chain_removespecific(chain *c, void *e) { void *ce; ce = chain_first(c); while (ce) { if (e == ce) { chain_remove(c); return; } ce = chain_next(c); } }
// Coerce a literal group (tuple or array) to be the specified target type static bool coerce_group(ast_t** astp, ast_t* target_type, lit_chain_t* chain, size_t cardinality, pass_opt_t* options, bool report_errors) { pony_assert(astp != NULL); ast_t* literal_expr = *astp; pony_assert(literal_expr != NULL); pony_assert(ast_id(literal_expr) == TK_TUPLE || ast_id(literal_expr) == TK_ARRAY); pony_assert(chain != NULL); pony_assert(cardinality != CHAIN_CARD_BASE); size_t i = 0; lit_chain_t link; chain_add(chain, &link, cardinality); if(ast_id(literal_expr) == TK_ARRAY) { // The first child of an array AST is the forced type, the second child is // the sequence of elements. literal_expr = ast_childidx(literal_expr, 1); } // Process each group element separately for(ast_t* p = ast_child(literal_expr); p != NULL; p = ast_sibling(p)) { ast_t* p_type = ast_type(p); if(is_typecheck_error(p_type)) return false; if(is_type_literal(p_type)) { // This element is a literal if(cardinality != CHAIN_CARD_ARRAY) { chain_clear_cache(&link); link.index = i; } if(!coerce_literal_to_type(&p, target_type, &link, options, report_errors)) return false; } i++; } chain_remove(chain); return true; }
void *chain_remove_go_prev(chain *c) { chain_remove(c); return chain_this(c); }