bool prism::resolve::type_can_convert_to( sooty::const_parseme_ptr_ref lhsi, sooty::const_parseme_ptr_ref rhsi ) { ATMA_ASSERT(lhsi && rhsi); sooty::parseme_ptr lhs = type_of(lhsi); sooty::parseme_ptr rhs = type_of(rhsi); if (lhs->id == ID::reference_type) if (rhs->id == ID::reference_type) return types_match(lhs->children.front(), rhs->children.front()); else return types_match(lhs->children.front(), rhs); else if (rhs->id == ID::reference_type) return types_match(lhs, rhs->children.front()); else return types_match(lhs, rhs); }
static void private_array_resolve_symbols (type_t * tself, container_t * context, logger_t * log) { estring_t * tmp = NULL; t_array_t * self = &(tself->t_array); // We need to resolve array bounds. boundspair_t * bp = self->bounds; expression_t * hi = boundspair_hi (bp); expression_t * lo = boundspair_lo (bp); // symbols in bounds are resolved with use of parental // symtab. The following is illegal: // 'begin' 'integer' y; 'integer' 'array' z[1:y]; 'end'; expr_resolve_symbols (lo, container_parent (context), log); expr_resolve_symbols (hi, container_parent (context), log); type_resolve_symbols (self->host, context, log); type_t * lot = expr_type (lo); type_t * hit = expr_type (hi); // Type of `unknown' means that appropriate reporting action has // already been taken. Type of `implicit' means the symbol is yet // to be resolved. if (!type_is_unknown (lot) && !type_is_implicit (lot) && !types_match (lot, type_int ())) { log_printfc (log, ll_error, expr_cursor (lo), "invalid type %s in lower boundary", estr_cstr (tmp = type_to_str (lot, tmp))); boundspair_set_lo (bp, expr_primitive_for_type (type_int ())); } if (!type_is_unknown (hit) && !type_is_implicit (hit) && !types_match (hit, type_int ())) { log_printfc (log, ll_error, expr_cursor (hi), "invalid type %s in upper boundary", estr_cstr (tmp = type_to_str (hit, tmp))); boundspair_set_hi (bp, expr_primitive_for_type (type_int ())); } delete_estring (tmp); }
/*----------------------------------------------------------------------*/ int types_match(type_t *a, type_t *b) { if (a->tag != b->tag) { return 0; } /* both tags are equal... */ if (a->tag == TTAG_BASIC_TYPE) { return a->u.basic_type == b->u.basic_type; } else if (a->tag == TTAG_POINTER) { return types_match(a->u.pointer_type, b->u.pointer_type); } /*else if (a->tag == TTAG_STRUCT) { TODO:jkd }*/ assert(0); /* unreachable */ return 0; }
bool prism::resolve::types_match( sooty::const_parseme_ptr_ref lhsi, sooty::const_parseme_ptr_ref rhsi ) { ATMA_ASSERT(lhsi && rhsi); sooty::parseme_ptr lhs = type_of(lhsi); sooty::parseme_ptr rhs = type_of(rhsi); if (lhs->id == ID::any_type || rhs->id == ID::any_type) return true; // pointers and arrays are different! if (lhs->id == ID::pointer_type) return rhs->id == ID::pointer_type && types_match(marshall::pointer_type::pointee_type(lhs), marshall::pointer_type::pointee_type(rhs)); else if (lhs->id == ID::array_type) return rhs->id == ID::array_type && types_match(marshall::array_type::type(lhs), marshall::array_type::type(rhs)); else if (lhs->id == ID::reference_type) return rhs->id == ID::reference_type && types_match(marshall::array_type::type(lhs), marshall::array_type::type(rhs)); if (rhs->id == ID::pointer_type || rhs->id == ID::array_type || rhs->id == ID::reference_type) return false; ATMA_ASSERT(rhs->id == ID::type_definition); return marshall::type_definition::name(lhs)->value.string == marshall::type_definition::name(rhs)->value.string; }
bool prism::resolve::type_matches_pred::operator()( sooty::const_parseme_ptr_ref rhs ) const { return types_match(lhs, rhs); }