Ignore:
Timestamp:
Dec 21, 2016, 5:13:15 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, 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

File:
1 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();
Note: See TracChangeset for help on using the changeset viewer.