Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r6c3a988f r722617d  
    267267                std::list< Expression* >& actuals = appExpr->get_args();
    268268
     269                std::list< Type * > formalTypes;
     270                std::list< Type * >::iterator formalType = formalTypes.end();
     271
    269272                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    270                         Type * actualType = (*actualExpr)->get_result();
     273
    271274                        PRINT(
    272275                                std::cerr << "actual expression:" << std::endl;
    273276                                (*actualExpr)->print( std::cerr, 8 );
    274277                                std::cerr << "--- results are" << std::endl;
    275                                 actualType->print( std::cerr, 8 );
    276                         )
     278                                (*actualExpr)->get_result()->print( std::cerr, 8 );
     279                        )
     280                        std::list< DeclarationWithType* >::iterator startFormal = formal;
    277281                        Cost actualCost;
    278                         if ( formal == formals.end() ) {
    279                                 if ( function->get_isVarArgs() ) {
    280                                         convCost += Cost( 1, 0, 0 );
    281                                         continue;
     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;
     305                                }
     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                        }
     328                        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 );
    282336                                } else {
    283                                         return Cost::infinity;
     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 );
    284343                                }
    285344                        }
    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;
    303                         if ( actualCost != Cost( 0, 0, 0 ) ) {
    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
     345
    310346                }
    311347                if ( formal != formals.end() ) {
     
    328364                        }
    329365                        convCost += newCost;
     366
    330367                        convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
    331368                }
     
    339376                        unifiableVars[ (*tyvar)->get_name() ] = TypeDecl::Data{ *tyvar };
    340377                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
    341                                 needAssertions[ *assert ].isUsed = true;
     378                                needAssertions[ *assert ] = true;
    342379                        }
    343380///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
     
    351388                if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {
    352389                        // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType
    353                         std::list< Expression * > exprs;
     390                        TupleExpr * tupleExpr = new TupleExpr();
    354391                        for ( Type * type : *tupleType ) {
    355                                 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( exprs ) ) ) {
    356                                         deleteAll( exprs );
     392                                if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) {
     393                                        delete tupleExpr;
    357394                                        return false;
    358395                                }
    359396                        }
    360                         *out++ = new TupleExpr( exprs );
    361                 } else if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {
    362                         // xxx - mixing default arguments with variadic??
    363                         std::list< Expression * > exprs;
    364                         for ( ; actualIt != actualEnd; ++actualIt ) {
    365                                 exprs.push_back( actualIt->expr->clone() );
    366                                 cost += actualIt->cost;
    367                         }
    368                         Expression * arg = nullptr;
    369                         if ( exprs.size() == 1 && Tuples::isTtype( exprs.front()->get_result() ) ) {
    370                                 // the case where a ttype value is passed directly is special, e.g. for argument forwarding purposes
    371                                 // xxx - what if passing multiple arguments, last of which is ttype?
    372                                 // xxx - what would happen if unify was changed so that unifying tuple types flattened both before unifying lists? then pass in TupleType(ttype) below.
    373                                 arg = exprs.front();
    374                         } else {
    375                                 arg = new TupleExpr( exprs );
    376                         }
    377                         assert( arg && arg->get_result() );
    378                         if ( ! unify( ttype, arg->get_result(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    379                                 return false;
    380                         }
    381                         *out++ = arg;
     397                        tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) );
     398                        *out++ = tupleExpr;
    382399                } else if ( actualIt != actualEnd ) {
    383400                        // both actualType and formalType are atomic (non-tuple) types - if they unify
     
    466483        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
    467484                for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    468                         if ( i->second.isUsed ) {
     485                        if ( i->second == true ) {
    469486                                i->first->accept( indexer );
    470487                        }
     
    477494                if ( begin == end ) {
    478495                        if ( newNeed.empty() ) {
    479                                 PRINT(
    480                                         std::cerr << "all assertions satisfied, output alternative: ";
    481                                         newAlt.print( std::cerr );
    482                                         std::cerr << std::endl;
    483                                 );
    484496                                *out++ = newAlt;
    485497                                return;
     
    498510
    499511                ForwardIterator cur = begin++;
    500                 if ( ! cur->second.isUsed ) {
     512                if ( ! cur->second ) {
    501513                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
    502514                        return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
     
    542554                                assert( (*candidate)->get_uniqueId() );
    543555                                DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
    544 
    545                                 // everything with an empty idChain was pulled in by the current assertion.
    546                                 // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found.
    547                                 for ( auto & a : newerNeed ) {
    548                                         if ( a.second.idChain.empty() ) {
    549                                                 a.second.idChain = cur->second.idChain;
    550                                                 a.second.idChain.push_back( curDecl->get_uniqueId() );
    551                                         }
    552                                 }
    553 
    554556                                //AssertionParentSet newNeedParents( needParents );
    555557                                // skip repeatingly-self-recursive assertion satisfaction
     
    567569                                )
    568570                                ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
    569                                 // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
    570                                 InferredParams * inferParameters = &appExpr->get_inferParams();
    571                                 for ( UniqueId id : cur->second.idChain ) {
    572                                         inferParameters = (*inferParameters)[ id ].inferParams.get();
    573                                 }
    574571                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    575                                 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
     572                                appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    576573                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    577574                        } else {
     
    612609                makeUnifiableVars( funcType, openVars, resultNeed );
    613610                AltList instantiatedActuals; // filled by instantiate function
    614                 if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) {
     611                if ( targetType && ! targetType->isVoid() ) {
    615612                        // attempt to narrow based on expected target type
    616613                        Type * returnType = funcType->get_returnVals().front()->get_type();
     
    10781075        }
    10791076
    1080         void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) {
     1077        void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
    10811078                std::list< AlternativeFinder > subExprAlternatives;
    10821079                findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
     
    10841081                combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
    10851082                for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
    1086                         std::list< Expression * > exprs;
    1087                         makeExprList( *i, exprs );
     1083                        TupleExpr *newExpr = new TupleExpr;
     1084                        makeExprList( *i, newExpr->get_exprs() );
     1085                        newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) );
    10881086
    10891087                        TypeEnvironment compositeEnv;
    10901088                        simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
    1091                         alternatives.push_back( Alternative( new TupleExpr( exprs ) , compositeEnv, sumCost( *i ) ) );
     1089                        alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) );
    10921090                } // for
    1093         }
    1094 
    1095         void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
    1096                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    10971091        }
    10981092
Note: See TracChangeset for help on using the changeset viewer.