Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r83882e9 r62194cb  
    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
    3233#include "InitTweak/InitTweak.h"   // for getFunctionName
    3334#include "RenameVars.h"            // for RenameVars, global_renamer
     
    186187                expr->accept( *this );
    187188                if ( failFast && alternatives.empty() ) {
    188                         PRINT(
    189                                 std::cerr << "No reasonable alternatives for expression " << expr << std::endl;
    190                         )
    191189                        throw SemanticError( "No reasonable alternatives for expression ", expr );
    192190                }
     
    581579        /// State to iteratively build a match of parameter expressions to arguments
    582580        struct ArgPack {
    583                 std::size_t parent;                ///< Index of parent pack
     581                std::size_t parent;                ///< Index of parent pack 
    584582                std::unique_ptr<Expression> expr;  ///< The argument stored here
    585583                Cost cost;                         ///< The cost of this argument
     
    590588                unsigned nextArg;                  ///< Index of next argument in arguments list
    591589                unsigned tupleStart;               ///< Number of tuples that start at this index
    592                 // TODO fix this somehow
    593                 std::vector<Alternative> expls;    ///< Exploded actuals left over from last match
    594 
     590                unsigned nextExpl;                 ///< Index of next exploded element
     591                unsigned explAlt;                  ///< Index of alternative for nextExpl > 0
     592               
    595593                ArgPack()
    596594                        : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
    597                           tupleStart(0), expls() {}
    598 
    599                 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
     595                          tupleStart(0), nextExpl(0), explAlt(0) {}
     596               
     597                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 
    600598                                const OpenVarSet& openVars)
    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)),
     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)), 
    609607                          have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart),
    610                           expls(move(expls)) {}
    611 
    612                 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have,
     608                          nextExpl(nextExpl), explAlt(explAlt) {}
     609               
     610                ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 
    613611                                OpenVarSet&& openVars, unsigned nextArg, Cost added )
    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 
     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                         
    626624                /// Ends a tuple expression, consolidating the appropriate actuals
    627625                void endTuple( const std::vector<ArgPack>& packs ) {
     
    643641
    644642        /// Instantiates an argument to match a formal, returns false if no results left
    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 ) {
     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 ) {
    648646                if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) {
    649647                        // formalType is a TupleType - group actuals into a TupleExpr
     
    651649                        for ( Type* type : *tupleType ) {
    652650                                // xxx - dropping initializer changes behaviour from previous, but seems correct
    653                                 if ( ! instantiateArgument(
    654                                                 type, nullptr, args, results, genStart, indexer, nTuples ) )
     651                                if ( ! instantiateArgument( 
     652                                                type, nullptr, args, results, genStart, indexer, nTuples ) ) 
    655653                                        return false;
    656654                                nTuples = 0;
     
    676674                                // add another argument to results
    677675                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    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() );
     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
    689687                                                results.emplace_back(
    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 
     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                                               
    694693                                                continue;
    695694                                        }
    696 
     695                                       
    697696                                        // finish result when out of arguments
    698                                         if ( results[i].nextArg >= args.size() ) {
    699                                                 ArgPack newResult{
    700                                                         results[i].env, results[i].need, results[i].have,
     697                                        if ( nextArg >= args.size() ) {
     698                                                ArgPack newResult{ 
     699                                                        results[i].env, results[i].need, results[i].have, 
    701700                                                        results[i].openVars };
    702                                                 newResult.nextArg = results[i].nextArg;
     701                                                newResult.nextArg = nextArg;
    703702                                                Type* argType;
    704703
     
    718717
    719718                                                        if ( results[i].tupleStart > 0 && Tuples::isTtype( argType ) ) {
    720                                                                 // the case where a ttype value is passed directly is special,
     719                                                                // the case where a ttype value is passed directly is special, 
    721720                                                                // e.g. for argument forwarding purposes
    722                                                                 // xxx - what if passing multiple arguments, last of which is
     721                                                                // xxx - what if passing multiple arguments, last of which is 
    723722                                                                //       ttype?
    724                                                                 // xxx - what would happen if unify was changed so that unifying
    725                                                                 //       tuple
    726                                                                 // types flattened both before unifying lists? then pass in
     723                                                                // xxx - what would happen if unify was changed so that unifying 
     724                                                                //       tuple 
     725                                                                // types flattened both before unifying lists? then pass in 
    727726                                                                // TupleType (ttype) below.
    728727                                                                --newResult.tupleStart;
     
    735734
    736735                                                // check unification for ttype before adding to final
    737                                                 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have,
     736                                                if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have, 
    738737                                                                newResult.openVars, indexer ) ) {
    739738                                                        finalResults.push_back( move(newResult) );
    740739                                                }
    741 
     740                                               
    742741                                                continue;
    743742                                        }
    744743
    745744                                        // add each possible next argument
    746                                         auto j = results[i].nextArg;
    747                                         for ( const Alternative& actual : args[j] ) {
     745                                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
     746                                                const ExplodedActual& expl = args[nextArg][j];
     747                                       
    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( 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
     752                                                env.addActual( expl.env, openVars );
     753
     754                                                // skip empty tuple arguments by (near-)cloning parent into next gen
     755                                                if ( expl.exprs.empty() ) {
    759756                                                        results.emplace_back(
    760                                                                 results[i], move(env), copy(results[i].need),
    761                                                                 copy(results[i].have), move(openVars), j + 1, actual.cost );
    762 
     757                                                                results[i], move(env), copy(results[i].need), 
     758                                                                copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
     759                                                       
    763760                                                        continue;
    764761                                                }
    765762
    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                                                 }
    772763                                                // add new result
    773764                                                results.emplace_back(
    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) );
     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 );
    777768                                        }
    778769                                }
     
    793784                std::size_t genEnd = results.size();
    794785                for ( std::size_t i = genStart; i < genEnd; ++i ) {
     786                        auto nextArg = results[i].nextArg;
     787
    795788                        // use remainder of exploded tuple if present
    796                         if ( ! results[i].expls.empty() ) {
    797                                 const Alternative& actual = results[i].expls.front();
    798 
     789                        if ( results[i].hasExpl() ) {
     790                                const ExplodedActual& expl = results[i].getExpl( args );
     791                                Expression* expr = expl.exprs[results[i].nextExpl].get();
     792                               
    799793                                TypeEnvironment env = results[i].env;
    800794                                AssertionSet need = results[i].need, have = results[i].have;
    801795                                OpenVarSet openVars = results[i].openVars;
    802796
    803                                 env.addActual( actual.env, openVars );
    804                                 Type* actualType = actual.expr->get_result();
     797                                Type* actualType = expr->get_result();
    805798
    806799                                PRINT(
     
    811804                                        std::cerr << std::endl;
    812805                                )
    813 
     806                               
    814807                                if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
    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) );;
     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 );
    820816                                }
    821817
    822818                                continue;
    823819                        }
    824 
     820                       
    825821                        // use default initializers if out of arguments
    826                         if ( results[i].nextArg >= args.size() ) {
     822                        if ( nextArg >= args.size() ) {
    827823                                if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) {
    828824                                        if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) {
     
    831827                                                OpenVarSet openVars = results[i].openVars;
    832828
    833                                                 if ( unify( formalType, cnst->get_type(), env, need, have, openVars,
     829                                                if ( unify( formalType, cnst->get_type(), env, need, have, openVars, 
    834830                                                                indexer ) ) {
    835831                                                        results.emplace_back(
    836                                                                 i, cnstExpr, move(env), move(need), move(have),
    837                                                                 move(openVars), results[i].nextArg, nTuples );
     832                                                                i, cnstExpr, move(env), move(need), move(have), 
     833                                                                move(openVars), nextArg, nTuples );
    838834                                                }
    839835                                        }
     
    844840
    845841                        // Check each possible next argument
    846                         auto j = results[i].nextArg;
    847                         for ( const Alternative& actual : args[j] ) {
     842                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
     843                                const ExplodedActual& expl = args[nextArg][j];
     844
    848845                                // fresh copies of parent parameters for this iteration
    849846                                TypeEnvironment env = results[i].env;
     
    851848                                OpenVarSet openVars = results[i].openVars;
    852849
    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
     850                                env.addActual( expl.env, openVars );
     851                               
     852                                // skip empty tuple arguments by (near-)cloning parent into next gen
     853                                if ( expl.exprs.empty() ) {
    860854                                        results.emplace_back(
    861                                                 results[i], move(env), move(need), move(have), move(openVars), j + 1,
    862                                                 actual.cost );
     855                                                results[i], move(env), move(need), move(have), move(openVars),
     856                                                nextArg + 1, expl.cost );
    863857
    864858                                        continue;
     
    866860
    867861                                // consider only first exploded actual
    868                                 const Alternative& aActual = exploded.front();
    869                                 Type* actualType = aActual.expr->get_result()->clone();
     862                                Expression* expr = expl.exprs.front().get();
     863                                Type* actualType = expr->get_result()->clone();
    870864
    871865                                PRINT(
     
    879873                                // attempt to unify types
    880874                                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                                         }
    887875                                        // add new result
    888876                                        results.emplace_back(
    889                                                 i, aActual.expr, move(env), move(need), move(have), move(openVars),
    890                                                 j + 1, nTuples, actual.cost, move(newExpls) );
     877                                                i, expr, move(env), move(need), move(have), move(openVars), nextArg + 1,
     878                                                nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    891879                                }
    892880                        }
     
    895883                // reset for next parameter
    896884                genStart = genEnd;
    897 
     885               
    898886                return genEnd != results.size();
    899887        }
    900888
    901889        template<typename OutputIterator>
    902         void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result,
     890        void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 
    903891                        const std::vector<ArgPack>& results, OutputIterator out ) {
    904892                ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
     
    924912        template<typename OutputIterator>
    925913        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func,
    926                         FunctionType *funcType, const std::vector< AlternativeFinder > &args,
    927                         OutputIterator out ) {
     914                        FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {
    928915                OpenVarSet funcOpenVars;
    929916                AssertionSet funcNeed, funcHave;
     
    951938                for ( DeclarationWithType* formal : funcType->get_parameters() ) {
    952939                        ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal );
    953                         if ( ! instantiateArgument(
     940                        if ( ! instantiateArgument( 
    954941                                        obj->get_type(), obj->get_init(), args, results, genStart, indexer ) )
    955942                                return;
     
    964951                                // iterate results
    965952                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
     953                                        auto nextArg = results[i].nextArg;
     954
    966955                                        // use remainder of exploded tuple if present
    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() );
     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
    977964                                                results.emplace_back(
    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 
     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                                               
    982970                                                continue;
    983971                                        }
    984972
    985973                                        // finish result when out of arguments
    986                                         if ( results[i].nextArg >= args.size() ) {
     974                                        if ( nextArg >= args.size() ) {
    987975                                                validateFunctionAlternative( func, results[i], results, out );
    988976
     
    991979
    992980                                        // add each possible next argument
    993                                         auto j = results[i].nextArg;
    994                                         for ( const Alternative& actual : args[j] ) {
     981                                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
     982                                                const ExplodedActual& expl = args[nextArg][j];
     983
    995984                                                // fresh copies of parent parameters for this iteration
    996985                                                TypeEnvironment env = results[i].env;
    997986                                                OpenVarSet openVars = results[i].openVars;
    998987
    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 );
     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                                                       
    1009996                                                        continue;
    1010997                                                }
    1011998
    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                                                 }
    1018999                                                // add new result
    10191000                                                results.emplace_back(
    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) );
     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 );
    10231004                                        }
    10241005                                }
     
    10301011                        for ( std::size_t i = genStart; i < results.size(); ++i ) {
    10311012                                ArgPack& result = results[i];
    1032                                 if ( result.expls.empty() && result.nextArg >= args.size() ) {
     1013                                if ( ! result.hasExpl() && result.nextArg >= args.size() ) {
    10331014                                        validateFunctionAlternative( func, result, results, out );
    10341015                                }
     
    10601041                        printAlts( funcOpFinder.alternatives, std::cerr, 1 );
    10611042                )
     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                }
    10621057
    10631058                AltList candidates;
     
    10741069                                                Alternative newFunc( *func );
    10751070                                                referenceToRvalueConversion( newFunc.expr );
    1076                                                 makeFunctionAlternatives( newFunc, function, argAlternatives,
     1071                                                makeFunctionAlternatives( newFunc, function, argExpansions,
    10771072                                                        std::back_inserter( candidates ) );
    10781073                                        }
     
    10831078                                                        Alternative newFunc( *func );
    10841079                                                        referenceToRvalueConversion( newFunc.expr );
    1085                                                         makeFunctionAlternatives( newFunc, function, argAlternatives,
     1080                                                        makeFunctionAlternatives( newFunc, function, argExpansions,
    10861081                                                                std::back_inserter( candidates ) );
    10871082                                                } // if
     
    10951090                // try each function operator ?() with each function alternative
    10961091                if ( ! funcOpFinder.alternatives.empty() ) {
    1097                         // add function alternatives to front of argument list
    1098                         argAlternatives.insert( argAlternatives.begin(), move(funcFinder) );
     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) );
    10991099
    11001100                        for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin();
     
    11081108                                                        Alternative newFunc( *funcOp );
    11091109                                                        referenceToRvalueConversion( newFunc.expr );
    1110                                                         makeFunctionAlternatives( newFunc, function, argAlternatives,
     1110                                                        makeFunctionAlternatives( newFunc, function, argExpansions,
    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                         )
    12551250                        if ( thisCost != Cost::infinity ) {
    1256                                 PRINT(
    1257                                         std::cerr << "has finite cost." << std::endl;
    1258                                 )
    12591251                                // count one safe conversion for each value that is thrown away
    12601252                                thisCost.incSafe( discardedValues );
    1261                                 Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env,
     1253                                Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env, 
    12621254                                        alt.cost, thisCost );
    1263                                 inferParameters( needAssertions, haveAssertions, newAlt, openVars,
     1255                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, 
    12641256                                        back_inserter( candidates ) );
    12651257                        } // if
     
    15501542        void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) {
    15511543                std::vector< AlternativeFinder > subExprAlternatives;
    1552                 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(),
     1544                findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 
    15531545                        back_inserter( subExprAlternatives ) );
    15541546                std::vector< AltList > possibilities;
    1555                 combos( subExprAlternatives.begin(), subExprAlternatives.end(),
     1547                combos( subExprAlternatives.begin(), subExprAlternatives.end(), 
    15561548                        back_inserter( possibilities ) );
    15571549                for ( const AltList& alts : possibilities ) {
     
    15611553                        TypeEnvironment compositeEnv;
    15621554                        simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv );
    1563                         alternatives.push_back(
     1555                        alternatives.push_back( 
    15641556                                Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } );
    15651557                } // for
Note: See TracChangeset for help on using the changeset viewer.