void ASTfunction_call::print (std::ostream &out, int indentlevel) const { ASTNode::print (out, indentlevel); #if 0 if (is_user_function()) { out << "\n"; user_function()->print (out, indentlevel+1); out << "\n"; } #endif }
TypeSpec ASTfunction_call::typecheck (TypeSpec expected) { typecheck_children (); bool match = false; // Look for an exact match, including expected return type m_typespec = typecheck_all_poly (expected, false); if (m_typespec != TypeSpec()) match = true; // Now look for an exact match on args, but any assignable return type if (! match && expected != TypeSpec()) { m_typespec = typecheck_all_poly (TypeSpec(), false); if (m_typespec != TypeSpec()) match = true; } // Now look for a coercible match of args, exact march on return type if (! match) { m_typespec = typecheck_all_poly (expected, true); if (m_typespec != TypeSpec()) match = true; } // All that failed, try for a coercible match on everything if (! match && expected != TypeSpec()) { m_typespec = typecheck_all_poly (TypeSpec(), true); if (m_typespec != TypeSpec()) match = true; } if (match) { if (! is_user_function ()) typecheck_builtin_specialcase (); return m_typespec; } // Couldn't find any way to match any polymorphic version of the // function that we know about. OK, at least try for helpful error // message. std::string choices (""); for (FunctionSymbol *poly = func(); poly; poly = poly->nextpoly()) { const char *code = poly->argcodes().c_str(); int advance; TypeSpec returntype = m_compiler->type_from_code (code, &advance); code += advance; if (choices.length()) choices += "\n"; choices += Strutil::format ("\t%s %s (%s)", type_c_str(returntype), m_name.c_str(), m_compiler->typelist_from_code(code).c_str()); } std::string actualargs; for (ASTNode::ref arg = args(); arg; arg = arg->next()) { if (actualargs.length()) actualargs += ", "; actualargs += arg->typespec().string(); } error ("No matching function call to '%s (%s)'\n Candidates are:\n%s", m_name.c_str(), actualargs.c_str(), choices.c_str()); return TypeSpec(); }