Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r62194cb r83882e9  
    3030#include "Common/utility.h"        // for deleteAll, printAll, CodeLocation
    3131#include "Cost.h"                  // for Cost, Cost::zero, operator<<, Cost...
    32 #include "ExplodedActual.h"        // for ExplodedActual
    3332#include "InitTweak/InitTweak.h"   // for getFunctionName
    3433#include "RenameVars.h"            // for RenameVars, global_renamer
     
    187186                expr->accept( *this );
    188187                if ( failFast && alternatives.empty() ) {
     188                        PRINT(
     189                                std::cerr << "No reasonable alternatives for expression " << expr << std::endl;
     190                        )
    189191                        throw SemanticError( "No reasonable alternatives for expression ", expr );
    190192                }
     
    579581        /// State to iteratively build a match of parameter expressions to arguments
    580582        struct ArgPack {
    581                 std::size_t parent;                ///< Index of parent pack 
     583                std::size_t parent;                ///< Index of parent pack
    582584                std::unique_ptr<Expression> expr;  ///< The argument stored here
    583585                Cost cost;                         ///< The cost of this argument
     
    588590                unsigned nextArg;                  ///< Index of next argument in arguments list
    589591                unsigned tupleStart;               ///< Number of tuples that start at this index
    590                 unsigned nextExpl;                 ///< Index of next exploded element
    591                 unsigned explAlt;                  ///< Index of alternative for nextExpl > 0
    592                
     592                // TODO fix this somehow
     593                std::vector<Alternative> expls;    ///< Exploded actuals left over from last match
     594
    593595                ArgPack()
    594596                        : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
    595                           tupleStart(0), nextExpl(0), explAlt(0) {}
    596                
    597                 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 
     597                          tupleStart(0), expls() {}
     598
     599                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
    598600                                const OpenVarSet& openVars)
    599                         : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 
    600                           openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}
    601                
    602                 ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need, 
    603                                 AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg, 
    604                                 unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0,
    605                                 unsigned explAlt = 0 )
    606                         : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 
     601                        : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have),
     602                          openVars(openVars), nextArg(0), tupleStart(0), expls() {}
     603
     604                ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need,
     605                                AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg,
     606                                unsigned tupleStart = 0, Cost cost = Cost::zero,
     607                                std::vector<Alternative>&& expls = std::vector<Alternative>{} )
     608                        : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)),
    607609                          have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart),
    608                           nextExpl(nextExpl), explAlt(explAlt) {}
    609                
    610                 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 
     610                          expls(move(expls)) {}
     611
     612                ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have,
    611613                                OpenVarSet&& openVars, unsigned nextArg, Cost added )
    612                         : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 
    613                           env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 
    614                           nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}
    615                
    616                 /// true iff this pack is in the middle of an exploded argument
    617                 bool hasExpl() const { return nextExpl > 0; }
    618 
    619                 /// Gets the list of exploded alternatives for this pack
    620                 const ExplodedActual& getExpl( const ExplodedArgs& args ) const {
    621                         return args[nextArg-1][explAlt];
    622                 }
    623                          
     614                        : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added),
     615                          env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)),
     616                          nextArg(nextArg), tupleStart(o.tupleStart), expls() {}
     617
     618
     619                // ArgPack(const ArgPack& o)
     620                //      : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), env(o.env),
     621                //        need(o.need), have(o.have), openVars(o.openVars), nextArg(o.nextArg),
     622                //        tupleStart(o.tupleStart), expls(o.expls) {}
     623
     624                // ArgPack(ArgPack&&) = default;
     625
    624626                /// Ends a tuple expression, consolidating the appropriate actuals
    625627                void endTuple( const std::vector<ArgPack>& packs ) {
     
    641643
    642644        /// Instantiates an argument to match a formal, returns false if no results left
    643         bool instantiateArgument( Type* formalType, Initializer* initializer, 
    644                         const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart,
    645                         const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
     645        bool instantiateArgument( Type* formalType, Initializer* initializer,
     646                        const std::vector< AlternativeFinder >& args, std::vector<ArgPack>& results,
     647                        std::size_t& genStart, const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
    646648                if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) {
    647649                        // formalType is a TupleType - group actuals into a TupleExpr
     
    649651                        for ( Type* type : *tupleType ) {
    650652                                // xxx - dropping initializer changes behaviour from previous, but seems correct
    651                                 if ( ! instantiateArgument( 
    652                                                 type, nullptr, args, results, genStart, indexer, nTuples ) ) 
     653                                if ( ! instantiateArgument(
     654                                                type, nullptr, args, results, genStart, indexer, nTuples ) )
    653655                                        return false;
    654656                                nTuples = 0;
     
    674676                                // add another argument to results
    675677                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    676                                         auto nextArg = results[i].nextArg;
    677 
    678                                         // use next element of exploded tuple if present
    679                                         if ( results[i].hasExpl() ) {
    680                                                 const ExplodedActual& expl = results[i].getExpl( args );
    681                                                
    682                                                 unsigned nextExpl = results[i].nextExpl + 1;
    683                                                 if ( nextExpl == expl.exprs.size() ) {
    684                                                         nextExpl = 0;
    685                                                 }
    686 
     678                                        // use remainder of exploded tuple if present
     679                                        if ( ! results[i].expls.empty() ) {
     680                                                const Alternative& actual = results[i].expls.front();
     681
     682                                                TypeEnvironment env = results[i].env;
     683                                                OpenVarSet openVars = results[i].openVars;
     684
     685                                                env.addActual( actual.env, openVars );
     686
     687                                                std::vector<Alternative> newExpls(
     688                                                        std::next( results[i].expls.begin() ), results[i].expls.end() );
    687689                                                results.emplace_back(
    688                                                         i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
    689                                                         copy(results[i].need), copy(results[i].have),
    690                                                         copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl,
    691                                                         results[i].explAlt );
    692                                                
     690                                                        i, actual.expr, move(env), copy(results[i].need),
     691                                                        copy(results[i].have), move(openVars), results[i].nextArg, nTuples,
     692                                                        Cost::zero, move(newExpls) );
     693
    693694                                                continue;
    694695                                        }
    695                                        
     696
    696697                                        // finish result when out of arguments
    697                                         if ( nextArg >= args.size() ) {
    698                                                 ArgPack newResult{ 
    699                                                         results[i].env, results[i].need, results[i].have, 
     698                                        if ( results[i].nextArg >= args.size() ) {
     699                                                ArgPack newResult{
     700                                                        results[i].env, results[i].need, results[i].have,
    700701                                                        results[i].openVars };
    701                                                 newResult.nextArg = nextArg;
     702                                                newResult.nextArg = results[i].nextArg;
    702703                                                Type* argType;
    703704
     
    717718
    718719                                                        if ( results[i].tupleStart > 0 && Tuples::isTtype( argType ) ) {
    719                                                                 // the case where a ttype value is passed directly is special, 
     720                                                                // the case where a ttype value is passed directly is special,
    720721                                                                // e.g. for argument forwarding purposes
    721                                                                 // xxx - what if passing multiple arguments, last of which is 
     722                                                                // xxx - what if passing multiple arguments, last of which is
    722723                                                                //       ttype?
    723                                                                 // xxx - what would happen if unify was changed so that unifying 
    724                                                                 //       tuple 
    725                                                                 // types flattened both before unifying lists? then pass in 
     724                                                                // xxx - what would happen if unify was changed so that unifying
     725                                                                //       tuple
     726                                                                // types flattened both before unifying lists? then pass in
    726727                                                                // TupleType (ttype) below.
    727728                                                                --newResult.tupleStart;
     
    734735
    735736                                                // check unification for ttype before adding to final
    736                                                 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have, 
     737                                                if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have,
    737738                                                                newResult.openVars, indexer ) ) {
    738739                                                        finalResults.push_back( move(newResult) );
    739740                                                }
    740                                                
     741
    741742                                                continue;
    742743                                        }
    743744
    744745                                        // add each possible next argument
    745                                         for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
    746                                                 const ExplodedActual& expl = args[nextArg][j];
    747                                        
     746                                        auto j = results[i].nextArg;
     747                                        for ( const Alternative& actual : args[j] ) {
    748748                                                // fresh copies of parent parameters for this iteration
    749749                                                TypeEnvironment env = results[i].env;
    750750                                                OpenVarSet openVars = results[i].openVars;
    751751
    752                                                 env.addActual( expl.env, openVars );
    753 
    754                                                 // skip empty tuple arguments by (near-)cloning parent into next gen
    755                                                 if ( expl.exprs.empty() ) {
     752                                                env.addActual( actual.env, openVars );
     753
     754                                                // explode argument
     755                                                std::vector<Alternative> exploded;
     756                                                Tuples::explode( actual, indexer, back_inserter( exploded ) );
     757                                                if ( exploded.empty() ) {
     758                                                        // skip empty tuple arguments by (near-)cloning parent into next gen
    756759                                                        results.emplace_back(
    757                                                                 results[i], move(env), copy(results[i].need), 
    758                                                                 copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
    759                                                        
     760                                                                results[i], move(env), copy(results[i].need),
     761                                                                copy(results[i].have), move(openVars), j + 1, actual.cost );
     762
    760763                                                        continue;
    761764                                                }
    762765
     766                                                // trim first element from exploded
     767                                                std::vector<Alternative> newExpls;
     768                                                newExpls.reserve( exploded.size() - 1 );
     769                                                for ( std::size_t i = 1; i < exploded.size(); ++i ) {
     770                                                        newExpls.push_back( move(exploded[i]) );
     771                                                }
    763772                                                // add new result
    764773                                                results.emplace_back(
    765                                                         i, expl.exprs.front().get(), move(env), copy(results[i].need),
    766                                                         copy(results[i].have), move(openVars), nextArg + 1,
    767                                                         nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     774                                                        i, exploded.front().expr, move(env), copy(results[i].need),
     775                                                        copy(results[i].have), move(openVars), results[i].nextArg + 1,
     776                                                        nTuples, actual.cost, move(newExpls) );
    768777                                        }
    769778                                }
     
    784793                std::size_t genEnd = results.size();
    785794                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    786                         auto nextArg = results[i].nextArg;
    787 
    788795                        // use remainder of exploded tuple if present
    789                         if ( results[i].hasExpl() ) {
    790                                 const ExplodedActual& expl = results[i].getExpl( args );
    791                                 Expression* expr = expl.exprs[results[i].nextExpl].get();
    792                                
     796                        if ( ! results[i].expls.empty() ) {
     797                                const Alternative& actual = results[i].expls.front();
     798
    793799                                TypeEnvironment env = results[i].env;
    794800                                AssertionSet need = results[i].need, have = results[i].have;
    795801                                OpenVarSet openVars = results[i].openVars;
    796802
    797                                 Type* actualType = expr->get_result();
     803                                env.addActual( actual.env, openVars );
     804                                Type* actualType = actual.expr->get_result();
    798805
    799806                                PRINT(
     
    804811                                        std::cerr << std::endl;
    805812                                )
    806                                
     813
    807814                                if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
    808                                         unsigned nextExpl = results[i].nextExpl + 1;
    809                                         if ( nextExpl == expl.exprs.size() ) {
    810                                                 nextExpl = 0;
    811                                         }
    812                                        
    813                                         results.emplace_back(
    814                                                 i, expr, move(env), move(need), move(have), move(openVars), nextArg,
    815                                                 nTuples, Cost::zero, nextExpl, results[i].explAlt );
     815                                        std::vector<Alternative> newExpls(
     816                                                std::next( results[i].expls.begin() ), results[i].expls.end() );
     817                                        results.emplace_back(
     818                                                i, actual.expr, move(env), move(need), move(have), move(openVars),
     819                                                results[i].nextArg, nTuples, Cost::zero, move(newExpls) );;
    816820                                }
    817821
    818822                                continue;
    819823                        }
    820                        
     824
    821825                        // use default initializers if out of arguments
    822                         if ( nextArg >= args.size() ) {
     826                        if ( results[i].nextArg >= args.size() ) {
    823827                                if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) {
    824828                                        if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) {
     
    827831                                                OpenVarSet openVars = results[i].openVars;
    828832
    829                                                 if ( unify( formalType, cnst->get_type(), env, need, have, openVars, 
     833                                                if ( unify( formalType, cnst->get_type(), env, need, have, openVars,
    830834                                                                indexer ) ) {
    831835                                                        results.emplace_back(
    832                                                                 i, cnstExpr, move(env), move(need), move(have), 
    833                                                                 move(openVars), nextArg, nTuples );
     836                                                                i, cnstExpr, move(env), move(need), move(have),
     837                                                                move(openVars), results[i].nextArg, nTuples );
    834838                                                }
    835839                                        }
     
    840844
    841845                        // Check each possible next argument
    842                         for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
    843                                 const ExplodedActual& expl = args[nextArg][j];
    844 
     846                        auto j = results[i].nextArg;
     847                        for ( const Alternative& actual : args[j] ) {
    845848                                // fresh copies of parent parameters for this iteration
    846849                                TypeEnvironment env = results[i].env;
     
    848851                                OpenVarSet openVars = results[i].openVars;
    849852
    850                                 env.addActual( expl.env, openVars );
    851                                
    852                                 // skip empty tuple arguments by (near-)cloning parent into next gen
    853                                 if ( expl.exprs.empty() ) {
     853                                env.addActual( actual.env, openVars );
     854
     855                                // explode argument
     856                                std::vector<Alternative> exploded;
     857                                Tuples::explode( actual, indexer, back_inserter( exploded ) );
     858                                if ( exploded.empty() ) {
     859                                        // skip empty tuple arguments by (near-)cloning parent into next gen
    854860                                        results.emplace_back(
    855                                                 results[i], move(env), move(need), move(have), move(openVars),
    856                                                 nextArg + 1, expl.cost );
     861                                                results[i], move(env), move(need), move(have), move(openVars), j + 1,
     862                                                actual.cost );
    857863
    858864                                        continue;
     
    860866
    861867                                // consider only first exploded actual
    862                                 Expression* expr = expl.exprs.front().get();
    863                                 Type* actualType = expr->get_result()->clone();
     868                                const Alternative& aActual = exploded.front();
     869                                Type* actualType = aActual.expr->get_result()->clone();
    864870
    865871                                PRINT(
     
    873879                                // attempt to unify types
    874880                                if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
     881                                        // trim first element from exploded
     882                                        std::vector<Alternative> newExpls;
     883                                        newExpls.reserve( exploded.size() - 1 );
     884                                        for ( std::size_t i = 1; i < exploded.size(); ++i ) {
     885                                                newExpls.push_back( move(exploded[i]) );
     886                                        }
    875887                                        // add new result
    876888                                        results.emplace_back(
    877                                                 i, expr, move(env), move(need), move(have), move(openVars), nextArg + 1,
    878                                                 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     889                                                i, aActual.expr, move(env), move(need), move(have), move(openVars),
     890                                                j + 1, nTuples, actual.cost, move(newExpls) );
    879891                                }
    880892                        }
     
    883895                // reset for next parameter
    884896                genStart = genEnd;
    885                
     897
    886898                return genEnd != results.size();
    887899        }
    888900
    889901        template<typename OutputIterator>
    890         void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 
     902        void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result,
    891903                        const std::vector<ArgPack>& results, OutputIterator out ) {
    892904                ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
     
    912924        template<typename OutputIterator>
    913925        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func,
    914                         FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {
     926                        FunctionType *funcType, const std::vector< AlternativeFinder > &args,
     927                        OutputIterator out ) {
    915928                OpenVarSet funcOpenVars;
    916929                AssertionSet funcNeed, funcHave;
     
    938951                for ( DeclarationWithType* formal : funcType->get_parameters() ) {
    939952                        ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal );
    940                         if ( ! instantiateArgument( 
     953                        if ( ! instantiateArgument(
    941954                                        obj->get_type(), obj->get_init(), args, results, genStart, indexer ) )
    942955                                return;
     
    951964                                // iterate results
    952965                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    953                                         auto nextArg = results[i].nextArg;
    954 
    955966                                        // use remainder of exploded tuple if present
    956                                         if ( results[i].hasExpl() ) {
    957                                                 const ExplodedActual& expl = results[i].getExpl( args );
    958                                                
    959                                                 unsigned nextExpl = results[i].nextExpl + 1;
    960                                                 if ( nextExpl == expl.exprs.size() ) {
    961                                                         nextExpl = 0;
    962                                                 }
    963 
     967                                        if ( ! results[i].expls.empty() ) {
     968                                                const Alternative& actual = results[i].expls.front();
     969
     970                                                TypeEnvironment env = results[i].env;
     971                                                OpenVarSet openVars = results[i].openVars;
     972
     973                                                env.addActual( actual.env, openVars );
     974
     975                                                std::vector<Alternative> newExpls(
     976                                                        std::next( results[i].expls.begin() ), results[i].expls.end() );
    964977                                                results.emplace_back(
    965                                                         i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
    966                                                         copy(results[i].need), copy(results[i].have),
    967                                                         copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl,
    968                                                         results[i].explAlt );
    969                                                
     978                                                        i, actual.expr, move(env), copy(results[i].need),
     979                                                        copy(results[i].have), move(openVars), results[i].nextArg, 0,
     980                                                        Cost::zero, move(newExpls) );
     981
    970982                                                continue;
    971983                                        }
    972984
    973985                                        // finish result when out of arguments
    974                                         if ( nextArg >= args.size() ) {
     986                                        if ( results[i].nextArg >= args.size() ) {
    975987                                                validateFunctionAlternative( func, results[i], results, out );
    976988
     
    979991
    980992                                        // add each possible next argument
    981                                         for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
    982                                                 const ExplodedActual& expl = args[nextArg][j];
    983 
     993                                        auto j = results[i].nextArg;
     994                                        for ( const Alternative& actual : args[j] ) {
    984995                                                // fresh copies of parent parameters for this iteration
    985996                                                TypeEnvironment env = results[i].env;
    986997                                                OpenVarSet openVars = results[i].openVars;
    987998
    988                                                 env.addActual( expl.env, openVars );
    989 
    990                                                 // skip empty tuple arguments by (near-)cloning parent into next gen
    991                                                 if ( expl.exprs.empty() ) {
    992                                                         results.emplace_back(
    993                                                                 results[i], move(env), copy(results[i].need),
    994                                                                 copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
    995                                                        
     999                                                env.addActual( actual.env, openVars );
     1000
     1001                                                // explode argument
     1002                                                std::vector<Alternative> exploded;
     1003                                                Tuples::explode( actual, indexer, back_inserter( exploded ) );
     1004                                                if ( exploded.empty() ) {
     1005                                                        // skip empty tuple arguments by (near-)cloning parent into next gen
     1006                                                        results.emplace_back(
     1007                                                                results[i], move(env), copy(results[i].need),
     1008                                                                copy(results[i].have), move(openVars), j + 1, actual.cost );
    9961009                                                        continue;
    9971010                                                }
    9981011
     1012                                                // trim first element from exploded
     1013                                                std::vector<Alternative> newExpls;
     1014                                                newExpls.reserve( exploded.size() - 1 );
     1015                                                for ( std::size_t i = 1; i < exploded.size(); ++i ) {
     1016                                                        newExpls.push_back( move(exploded[i]) );
     1017                                                }
    9991018                                                // add new result
    10001019                                                results.emplace_back(
    1001                                                         i, expl.exprs.front().get(), move(env), copy(results[i].need),
    1002                                                         copy(results[i].have), move(openVars), nextArg + 1, 0,
    1003                                                         expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     1020                                                        i, exploded.front().expr, move(env), copy(results[i].need),
     1021                                                        copy(results[i].have), move(openVars), j + 1, 0,
     1022                                                        actual.cost, move(newExpls) );
    10041023                                        }
    10051024                                }
     
    10111030                        for ( std::size_t i = genStart; i < results.size(); ++i ) {
    10121031                                ArgPack& result = results[i];
    1013                                 if ( ! result.hasExpl() && result.nextArg >= args.size() ) {
     1032                                if ( result.expls.empty() && result.nextArg >= args.size() ) {
    10141033                                        validateFunctionAlternative( func, result, results, out );
    10151034                                }
     
    10411060                        printAlts( funcOpFinder.alternatives, std::cerr, 1 );
    10421061                )
    1043 
    1044                 // pre-explode arguments
    1045                 ExplodedArgs argExpansions;
    1046                 argExpansions.reserve( argAlternatives.size() );
    1047 
    1048                 for ( const AlternativeFinder& arg : argAlternatives ) {
    1049                         argExpansions.emplace_back();
    1050                         auto& argE = argExpansions.back();
    1051                         argE.reserve( arg.alternatives.size() );
    1052                        
    1053                         for ( const Alternative& actual : arg ) {
    1054                                 argE.emplace_back( actual, indexer );
    1055                         }
    1056                 }
    10571062
    10581063                AltList candidates;
     
    10691074                                                Alternative newFunc( *func );
    10701075                                                referenceToRvalueConversion( newFunc.expr );
    1071                                                 makeFunctionAlternatives( newFunc, function, argExpansions,
     1076                                                makeFunctionAlternatives( newFunc, function, argAlternatives,
    10721077                                                        std::back_inserter( candidates ) );
    10731078                                        }
     
    10781083                                                        Alternative newFunc( *func );
    10791084                                                        referenceToRvalueConversion( newFunc.expr );
    1080                                                         makeFunctionAlternatives( newFunc, function, argExpansions,
     1085                                                        makeFunctionAlternatives( newFunc, function, argAlternatives,
    10811086                                                                std::back_inserter( candidates ) );
    10821087                                                } // if
     
    10901095                // try each function operator ?() with each function alternative
    10911096                if ( ! funcOpFinder.alternatives.empty() ) {
    1092                         // add exploded function alternatives to front of argument list
    1093                         std::vector<ExplodedActual> funcE;
    1094                         funcE.reserve( funcFinder.alternatives.size() );
    1095                         for ( const Alternative& actual : funcFinder ) {
    1096                                 funcE.emplace_back( actual, indexer );
    1097                         }
    1098                         argExpansions.insert( argExpansions.begin(), move(funcE) );
     1097                        // add function alternatives to front of argument list
     1098                        argAlternatives.insert( argAlternatives.begin(), move(funcFinder) );
    10991099
    11001100                        for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin();
     
    11081108                                                        Alternative newFunc( *funcOp );
    11091109                                                        referenceToRvalueConversion( newFunc.expr );
    1110                                                         makeFunctionAlternatives( newFunc, function, argExpansions,
     1110                                                        makeFunctionAlternatives( newFunc, function, argAlternatives,
    11111111                                                                std::back_inserter( candidates ) );
    11121112                                                }
     
    11501150                findMinCost( candidates.begin(), candidates.end(), std::back_inserter( winners ) );
    11511151
    1152                 // function may return struct or union value, in which case we need to add alternatives 
    1153                 // for implicitconversions to each of the anonymous members, must happen after findMinCost 
     1152                // function may return struct or union value, in which case we need to add alternatives
     1153                // for implicitconversions to each of the anonymous members, must happen after findMinCost
    11541154                // since anon conversions are never the cheapest expression
    11551155                for ( const Alternative & alt : winners ) {
     
    11821182                for ( Alternative& alt : finder.alternatives ) {
    11831183                        if ( isLvalue( alt.expr ) ) {
    1184                                 alternatives.push_back( 
     1184                                alternatives.push_back(
    11851185                                        Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } );
    11861186                        } // if
     
    12311231
    12321232                AltList candidates;
    1233                 for ( Alternative& alt : finder.alternatives ) {
     1233                for ( Alternative & alt : finder.alternatives ) {
    12341234                        AssertionSet needAssertions, haveAssertions;
    12351235                        OpenVarSet openVars;
     
    12441244                        // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
    12451245                        // unification run for side-effects
    1246                         unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions, 
     1246                        unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions,
    12471247                                haveAssertions, openVars, indexer );
    1248                         Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer, 
     1248                        Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer,
    12491249                                alt.env );
     1250                        PRINT(
     1251                                std::cerr << "working on cast with result: " << castExpr->result << std::endl;
     1252                                std::cerr << "and expr type: " << alt.expr->result << std::endl;
     1253                                std::cerr << "env: " << alt.env << std::endl;
     1254                        )
    12501255                        if ( thisCost != Cost::infinity ) {
     1256                                PRINT(
     1257                                        std::cerr << "has finite cost." << std::endl;
     1258                                )
    12511259                                // count one safe conversion for each value that is thrown away
    12521260                                thisCost.incSafe( discardedValues );
    1253                                 Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env, 
     1261                                Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env,
    12541262                                        alt.cost, thisCost );
    1255                                 inferParameters( needAssertions, haveAssertions, newAlt, openVars, 
     1263                                inferParameters( needAssertions, haveAssertions, newAlt, openVars,
    12561264                                        back_inserter( candidates ) );
    12571265                        } // if
     
    15421550        void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) {
    15431551                std::vector< AlternativeFinder > subExprAlternatives;
    1544                 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 
     1552                findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(),
    15451553                        back_inserter( subExprAlternatives ) );
    15461554                std::vector< AltList > possibilities;
    1547                 combos( subExprAlternatives.begin(), subExprAlternatives.end(), 
     1555                combos( subExprAlternatives.begin(), subExprAlternatives.end(),
    15481556                        back_inserter( possibilities ) );
    15491557                for ( const AltList& alts : possibilities ) {
     
    15531561                        TypeEnvironment compositeEnv;
    15541562                        simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv );
    1555                         alternatives.push_back( 
     1563                        alternatives.push_back(
    15561564                                Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } );
    15571565                } // for
Note: See TracChangeset for help on using the changeset viewer.