static void chain_remove(lit_chain_t* old_tail) { assert(old_tail != NULL); assert(old_tail->next != NULL); assert(old_tail->next->next != NULL); assert(old_tail->next->next->cardinality == CHAIN_CARD_BASE); old_tail->next = old_tail->next->next; chain_clear_cache(old_tail); }
// 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; }
static void chain_add(lit_chain_t* chain, lit_chain_t* new_link, size_t cardinality) { assert(new_link != NULL); assert(cardinality != CHAIN_CARD_BASE); new_link->cardinality = cardinality; new_link->index = 0; assert(chain != NULL); assert(chain->next != NULL); new_link->next = chain->next; chain->next = new_link; chain_clear_cache(new_link); }