Changeset 53e3b4a


Ignore:
Timestamp:
Dec 21, 2016, 5:13:15 PM (5 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
64eae56
Parents:
b940dc71
git-author:
Rob Schluntz <rschlunt@…> (12/21/16 16:32:57)
git-committer:
Rob Schluntz <rschlunt@…> (12/21/16 17:13:15)
Message:

refactored computeConversionCost, add ttype parameter handling to instantiate argument, add simple ttype handling code to Unify

Location:
src/ResolvExpr
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rb940dc71 r53e3b4a  
    267267                std::list< Expression* >& actuals = appExpr->get_args();
    268268
    269                 std::list< Type * > formalTypes;
    270                 std::list< Type * >::iterator formalType = formalTypes.end();
    271 
    272269                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    273 
     270                        Type * actualType = (*actualExpr)->get_result();
    274271                        PRINT(
    275272                                std::cerr << "actual expression:" << std::endl;
    276273                                (*actualExpr)->print( std::cerr, 8 );
    277274                                std::cerr << "--- results are" << std::endl;
    278                                 (*actualExpr)->get_result()->print( std::cerr, 8 );
    279                         )
    280                         std::list< DeclarationWithType* >::iterator startFormal = formal;
     275                                actualType->print( std::cerr, 8 );
     276                        )
    281277                        Cost actualCost;
    282                         std::list< Type * > flatActualTypes;
    283                         flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) );
    284                         for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) {
    285 
    286 
    287                                 // tuple handling code
    288                                 if ( formalType == formalTypes.end() ) {
    289                                         // the type of the formal parameter may be a tuple type. To make this easier to work with,
    290                                         // flatten the tuple type and traverse the resulting list of types, incrementing the formal
    291                                         // iterator once its types have been extracted. Once a particular formal parameter's type has
    292                                         // been exhausted load the next formal parameter's type.
    293                                         if ( formal == formals.end() ) {
    294                                                 if ( function->get_isVarArgs() ) {
    295                                                         convCost += Cost( 1, 0, 0 );
    296                                                         break;
    297                                                 } else {
    298                                                         return Cost::infinity;
    299                                                 }
    300                                         }
    301                                         formalTypes.clear();
    302                                         flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
    303                                         formalType = formalTypes.begin();
    304                                         ++formal;
     278                        if ( formal == formals.end() ) {
     279                                if ( function->get_isVarArgs() ) {
     280                                        convCost += Cost( 1, 0, 0 );
     281                                        continue;
     282                                } else {
     283                                        return Cost::infinity;
    305284                                }
    306 
    307                                 PRINT(
    308                                         std::cerr << std::endl << "converting ";
    309                                         (*actualType)->print( std::cerr, 8 );
    310                                         std::cerr << std::endl << " to ";
    311                                         (*formalType)->print( std::cerr, 8 );
    312                                 )
    313                                 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
    314                                 PRINT(
    315                                         std::cerr << std::endl << "cost is" << newCost << std::endl;
    316                                 )
    317 
    318                                 if ( newCost == Cost::infinity ) {
    319                                         return newCost;
    320                                 }
    321                                 convCost += newCost;
    322                                 actualCost += newCost;
    323 
    324                                 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
    325 
    326                                 formalType++;
    327                         }
     285                        }
     286                        Type * formalType = (*formal)->get_type();
     287                        PRINT(
     288                                std::cerr << std::endl << "converting ";
     289                                actualType->print( std::cerr, 8 );
     290                                std::cerr << std::endl << " to ";
     291                                formalType->print( std::cerr, 8 );
     292                        )
     293                        Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
     294                        PRINT(
     295                                std::cerr << std::endl << "cost is" << newCost << std::endl;
     296                        )
     297
     298                        if ( newCost == Cost::infinity ) {
     299                                return newCost;
     300                        }
     301                        convCost += newCost;
     302                        actualCost += newCost;
    328303                        if ( actualCost != Cost( 0, 0, 0 ) ) {
    329                                 std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal;
    330                                 startFormalPlusOne++;
    331                                 if ( formal == startFormalPlusOne ) {
    332                                         // not a tuple type
    333                                         Type *newType = (*startFormal)->get_type()->clone();
    334                                         alt.env.apply( newType );
    335                                         *actualExpr = new CastExpr( *actualExpr, newType );
    336                                 } else {
    337                                         TupleType *newType = new TupleType( Type::Qualifiers() );
    338                                         for ( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) {
    339                                                 newType->get_types().push_back( (*i)->get_type()->clone() );
    340                                         }
    341                                         alt.env.apply( newType );
    342                                         *actualExpr = new CastExpr( *actualExpr, newType );
    343                                 }
    344                         }
    345 
     304                                Type *newType = formalType->clone();
     305                                alt.env.apply( newType );
     306                                *actualExpr = new CastExpr( *actualExpr, newType );
     307                        }
     308                        convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 );
     309                        ++formal; // can't be in for-loop update because of the continue
    346310                }
    347311                if ( formal != formals.end() ) {
     
    364328                        }
    365329                        convCost += newCost;
    366 
    367330                        convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
    368331                }
     
    398361                        *out++ = tupleExpr;
    399362                } else if ( actualIt != actualEnd ) {
     363                        if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {
     364                                // xxx - mixing default arguments with variadic??
     365                                if ( ! Tuples::isTtype( actualIt->expr->get_result() ) ) {
     366                                        // xxx - what if passing multiple arguments, last of which is ttype?
     367
     368                                        // consume all remaining arguments, variadic style
     369                                        std::list< Expression * > exprs;
     370                                        for ( ; actualIt != actualEnd; ++actualIt ) {
     371                                                exprs.push_back( actualIt->expr->clone() );
     372                                                cost += actualIt->cost;
     373                                        }
     374                                        TupleExpr * arg = new TupleExpr( exprs );
     375                                        assert( arg->get_result() );
     376                                        // unification run for side effects
     377                                        bool unifyResult = unify( ttype, arg->get_result(), resultEnv, resultNeed, resultHave, openVars, indexer );
     378                                        assertf( unifyResult, "Somehow unifying ttype failed..." );
     379                                        *out++ = arg;
     380                                        return true;
     381                                }
     382                        }
    400383                        // both actualType and formalType are atomic (non-tuple) types - if they unify
    401384                        // then accept actual as an argument, otherwise return false (fail to instantiate argument)
     
    609592                makeUnifiableVars( funcType, openVars, resultNeed );
    610593                AltList instantiatedActuals; // filled by instantiate function
    611                 if ( targetType && ! targetType->isVoid() ) {
     594                if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) {
    612595                        // attempt to narrow based on expected target type
    613596                        Type * returnType = funcType->get_returnVals().front()->get_type();
  • src/ResolvExpr/Unify.cc

    rb940dc71 r53e3b4a  
    2626#include "SymTab/Indexer.h"
    2727#include "Common/utility.h"
    28 
     28#include "Tuples/Tuples.h"
    2929
    3030// #define DEBUG
     
    160160                  case TypeDecl::Ftype:
    161161                        return isFtype( type, indexer );
     162                        case TypeDecl::Ttype:
     163                        // ttype eats up any remaining parameters, no matter the type
     164                        return true;
    162165                } // switch
    163                 assert( false );
    164166                return false;
    165167        }
     
    485487        }
    486488
     489        template< typename Iterator >
     490        Type * combineTypes( Iterator begin, Iterator end ) {
     491                std::list< Type * > types;
     492                for ( ; begin != end; ++begin ) {
     493                        // might need to break apart these types too?
     494                        // yes, looks like we should flatten begin and push back each types individually
     495                        types.push_back( (*begin)->get_type()->clone() );
     496                }
     497                return new TupleType( Type::Qualifiers(), types );
     498        }
     499
    487500        template< typename Iterator1, typename Iterator2 >
    488501        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    489502                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    490                         // Type * commonType;
    491                         // if ( ! unifyInexact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
    492                         if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
     503                        Type * t1 = (*list1Begin)->get_type();
     504                        Type * t2 = (*list2Begin)->get_type();
     505                        bool isTtype1 = Tuples::isTtype( t1 );
     506                        bool isTtype2 = Tuples::isTtype( t2 );
     507                        // xxx - assumes ttype must be last parameter; needs cleanup; use unique_ptr for combinedType
     508                        if ( isTtype1 && ! isTtype2 ) {
     509                                // combine all of the things in list2, then unify
     510                                Type * combinedType = combineTypes( list2Begin, list2End );
     511                                return unifyExact( t1, combinedType, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     512                        } else if ( isTtype2 && ! isTtype1 ) {
     513                                // combine all of the things in list1, then unify
     514                                Type * combinedType = combineTypes( list1Begin, list1End );
     515                                return unifyExact( combinedType, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     516                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    493517                                return false;
    494518                        } // if
     
    504528                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    505529                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    506                         if ( functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size() ) {
     530                        // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors
     531                        if ( (functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size()) || functionType->isTtype() || otherFunction->isTtype() ) {
    507532                                if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    508533                                        if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
Note: See TracChangeset for help on using the changeset viewer.