Changeset a8b27c6


Ignore:
Timestamp:
Nov 22, 2017, 5:55:13 PM (4 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
62194cb, 88ef2af
Parents:
c2c6177
git-author:
Aaron Moss <a3moss@…> (11/22/17 17:27:05)
git-committer:
Aaron Moss <a3moss@…> (11/22/17 17:55:13)
Message:

Pre-explode arguments in AlternativeFinder?

Location:
src
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile.in

    rc2c6177 ra8b27c6  
    210210        ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
    211211        ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \
     212        ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT) \
    212213        SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
    213214        SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
     
    511512        ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \
    512513        ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \
    513         ResolvExpr/CurrentObject.cc SymTab/Indexer.cc \
    514         SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
    515         SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
    516         SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
    517         SynTree/BasicType.cc SynTree/PointerType.cc \
    518         SynTree/ArrayType.cc SynTree/ReferenceType.cc \
    519         SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
    520         SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
     514        ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \
     515        SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
     516        SymTab/FixFunction.cc SymTab/ImplementationType.cc \
     517        SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \
     518        SynTree/VoidType.cc SynTree/BasicType.cc \
     519        SynTree/PointerType.cc SynTree/ArrayType.cc \
     520        SynTree/ReferenceType.cc SynTree/FunctionType.cc \
     521        SynTree/ReferenceToType.cc SynTree/TupleType.cc \
     522        SynTree/TypeofType.cc SynTree/AttrType.cc \
    521523        SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
    522524        SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    825827        ResolvExpr/$(am__dirstamp) \
    826828        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     829ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT):  \
     830        ResolvExpr/$(am__dirstamp) \
     831        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    827832SymTab/$(am__dirstamp):
    828833        @$(MKDIR_P) SymTab
     
    10221027@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@
    10231028@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@
     1029@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po@am__quote@
    10241030@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@
    10251031@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@
     
    19641970@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
    19651971
     1972ResolvExpr/driver_cfa_cpp-ExplodedActual.o: ResolvExpr/ExplodedActual.cc
     1973@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc
     1974@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po
     1975@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.o' libtool=no @AMDEPBACKSLASH@
     1976@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1977@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc
     1978
     1979ResolvExpr/driver_cfa_cpp-ExplodedActual.obj: ResolvExpr/ExplodedActual.cc
     1980@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi`
     1981@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po
     1982@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.obj' libtool=no @AMDEPBACKSLASH@
     1983@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1984@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi`
     1985
    19661986SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
    19671987@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc
  • src/ResolvExpr/AlternativeFinder.cc

    rc2c6177 ra8b27c6  
    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
     
    587588                unsigned nextArg;                  ///< Index of next argument in arguments list
    588589                unsigned tupleStart;               ///< Number of tuples that start at this index
    589                 // TODO fix this somehow
    590                 std::vector<Alternative> expls;    ///< Exploded actuals left over from last match
    591 
     590                unsigned nextExpl;                 ///< Index of next exploded element
     591                unsigned explAlt;                  ///< Index of alternative for nextExpl > 0
     592               
    592593                ArgPack()
    593594                        : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
    594                           tupleStart(0), expls() {}
     595                          tupleStart(0), nextExpl(0), explAlt(0) {}
    595596               
    596597                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
    597598                                const OpenVarSet& openVars)
    598599                        : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have),
    599                           openVars(openVars), nextArg(0), tupleStart(0), expls() {}
     600                          openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}
    600601               
    601602                ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need,
    602603                                AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg,
    603                                 unsigned tupleStart = 0, Cost cost = Cost::zero,
    604                                 std::vector<Alternative>&& expls = std::vector<Alternative>{} )
     604                                unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0,
     605                                unsigned explAlt = 0 )
    605606                        : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)),
    606607                          have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart),
    607                           expls(move(expls)) {}
     608                          nextExpl(nextExpl), explAlt(explAlt) {}
    608609               
    609610                ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have,
     
    611612                        : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added),
    612613                          env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)),
    613                           nextArg(nextArg), tupleStart(o.tupleStart), expls() {}
     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                }
    614623                         
    615 
    616                 // ArgPack(const ArgPack& o)
    617                 //      : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), env(o.env),
    618                 //        need(o.need), have(o.have), openVars(o.openVars), nextArg(o.nextArg),
    619                 //        tupleStart(o.tupleStart), expls(o.expls) {}
    620 
    621                 // ArgPack(ArgPack&&) = default;
    622                
    623624                /// Ends a tuple expression, consolidating the appropriate actuals
    624625                void endTuple( const std::vector<ArgPack>& packs ) {
     
    641642        /// Instantiates an argument to match a formal, returns false if no results left
    642643        bool instantiateArgument( Type* formalType, Initializer* initializer,
    643                         const std::vector< AlternativeFinder >& args, std::vector<ArgPack>& results,
    644                         std::size_t& genStart, const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
     644                        const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart,
     645                        const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
    645646                if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) {
    646647                        // formalType is a TupleType - group actuals into a TupleExpr
     
    673674                                // add another argument to results
    674675                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
     676                                        auto nextArg = results[i].nextArg;
     677
    675678                                        // use remainder of exploded tuple if present
    676                                         if ( ! results[i].expls.empty() ) {
    677                                                 const Alternative& actual = results[i].expls.front();
     679                                        if ( results[i].hasExpl() ) {
     680                                                const ExplodedActual& expl = results[i].getExpl( args );
     681                                                const Alternative& actual = expl.alts[results[i].nextExpl];
    678682                                               
    679683                                                TypeEnvironment env = results[i].env;
     
    682686                                                env.addActual( actual.env, openVars );
    683687
    684                                                 std::vector<Alternative> newExpls(
    685                                                         std::next( results[i].expls.begin() ), results[i].expls.end() );
     688                                                unsigned nextExpl = results[i].nextExpl + 1;
     689                                                if ( nextExpl == expl.alts.size() ) {
     690                                                        nextExpl = 0;
     691                                                }
     692
    686693                                                results.emplace_back(
    687694                                                        i, actual.expr, move(env), copy(results[i].need),
    688                                                         copy(results[i].have), move(openVars), results[i].nextArg, nTuples,
    689                                                         Cost::zero, move(newExpls) );
     695                                                        copy(results[i].have), move(openVars), nextArg, nTuples,
     696                                                        Cost::zero, nextExpl, results[i].explAlt );
    690697                                               
    691698                                                continue;
     
    693700                                       
    694701                                        // finish result when out of arguments
    695                                         if ( results[i].nextArg >= args.size() ) {
     702                                        if ( nextArg >= args.size() ) {
    696703                                                ArgPack newResult{
    697704                                                        results[i].env, results[i].need, results[i].have,
    698705                                                        results[i].openVars };
    699                                                 newResult.nextArg = results[i].nextArg;
     706                                                newResult.nextArg = nextArg;
    700707                                                Type* argType;
    701708
     
    741748
    742749                                        // add each possible next argument
    743                                         auto j = results[i].nextArg;
    744                                         for ( const Alternative& actual : args[j] ) {
     750                                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
     751                                                const ExplodedActual& expl = args[nextArg][j];
     752                                       
    745753                                                // fresh copies of parent parameters for this iteration
    746754                                                TypeEnvironment env = results[i].env;
    747755                                                OpenVarSet openVars = results[i].openVars;
    748756
    749                                                 env.addActual( actual.env, openVars );
    750 
    751                                                 // explode argument
    752                                                 std::vector<Alternative> exploded;
    753                                                 Tuples::explode( actual, indexer, back_inserter( exploded ) );
    754                                                 if ( exploded.empty() ) {
    755                                                         // skip empty tuple arguments by (near-)cloning parent into next gen
     757                                                env.addActual( expl.env, openVars );
     758
     759                                                // skip empty tuple arguments by (near-)cloning parent into next gen
     760                                                if ( expl.alts.empty() ) {
    756761                                                        results.emplace_back(
    757762                                                                results[i], move(env), copy(results[i].need),
    758                                                                 copy(results[i].have), move(openVars), j + 1, actual.cost );
     763                                                                copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
    759764                                                       
    760765                                                        continue;
    761766                                                }
    762767
    763                                                 // trim first element from exploded
    764                                                 std::vector<Alternative> newExpls;
    765                                                 newExpls.reserve( exploded.size() - 1 );
    766                                                 for ( std::size_t i = 1; i < exploded.size(); ++i ) {
    767                                                         newExpls.push_back( move(exploded[i]) );
    768                                                 }
    769768                                                // add new result
    770769                                                results.emplace_back(
    771                                                         i, exploded.front().expr, move(env), copy(results[i].need),
    772                                                         copy(results[i].have), move(openVars), results[i].nextArg + 1,
    773                                                         nTuples, actual.cost, move(newExpls) );
     770                                                        i, expl.alts.front().expr, move(env), copy(results[i].need),
     771                                                        copy(results[i].have), move(openVars), nextArg + 1,
     772                                                        nTuples, expl.cost, expl.alts.size() == 1 ? 0 : 1, j );
    774773                                        }
    775774                                }
     
    790789                std::size_t genEnd = results.size();
    791790                for ( std::size_t i = genStart; i < genEnd; ++i ) {
     791                        auto nextArg = results[i].nextArg;
     792
    792793                        // use remainder of exploded tuple if present
    793                         if ( ! results[i].expls.empty() ) {
    794                                 const Alternative& actual = results[i].expls.front();
     794                        if ( results[i].hasExpl() ) {
     795                                const ExplodedActual& expl = results[i].getExpl( args );
     796                                const Alternative& actual = expl.alts[results[i].nextExpl];
    795797                               
    796798                                TypeEnvironment env = results[i].env;
     
    810812                               
    811813                                if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
    812                                         std::vector<Alternative> newExpls(
    813                                                 std::next( results[i].expls.begin() ), results[i].expls.end() );
     814                                        unsigned nextExpl = results[i].nextExpl + 1;
     815                                        if ( nextExpl == expl.alts.size() ) {
     816                                                nextExpl = 0;
     817                                        }
     818                                       
    814819                                        results.emplace_back(
    815820                                                i, actual.expr, move(env), move(need), move(have), move(openVars),
    816                                                 results[i].nextArg, nTuples, Cost::zero, move(newExpls) );;
     821                                                nextArg, nTuples, Cost::zero, nextExpl, results[i].explAlt );
    817822                                }
    818823
     
    821826                       
    822827                        // use default initializers if out of arguments
    823                         if ( results[i].nextArg >= args.size() ) {
     828                        if ( nextArg >= args.size() ) {
    824829                                if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) {
    825830                                        if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) {
     
    832837                                                        results.emplace_back(
    833838                                                                i, cnstExpr, move(env), move(need), move(have),
    834                                                                 move(openVars), results[i].nextArg, nTuples );
     839                                                                move(openVars), nextArg, nTuples );
    835840                                                }
    836841                                        }
     
    841846
    842847                        // Check each possible next argument
    843                         auto j = results[i].nextArg;
    844                         for ( const Alternative& actual : args[j] ) {
     848                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
     849                                const ExplodedActual& expl = args[nextArg][j];
     850
    845851                                // fresh copies of parent parameters for this iteration
    846852                                TypeEnvironment env = results[i].env;
     
    848854                                OpenVarSet openVars = results[i].openVars;
    849855
    850                                 env.addActual( actual.env, openVars );
     856                                env.addActual( expl.env, openVars );
    851857                               
    852                                 // explode argument
    853                                 std::vector<Alternative> exploded;
    854                                 Tuples::explode( actual, indexer, back_inserter( exploded ) );
    855                                 if ( exploded.empty() ) {
    856                                         // skip empty tuple arguments by (near-)cloning parent into next gen
     858                                // skip empty tuple arguments by (near-)cloning parent into next gen
     859                                if ( expl.alts.empty() ) {
    857860                                        results.emplace_back(
    858                                                 results[i], move(env), move(need), move(have), move(openVars), j + 1,
    859                                                 actual.cost );
     861                                                results[i], move(env), move(need), move(have), move(openVars),
     862                                                nextArg + 1, expl.cost );
    860863
    861864                                        continue;
     
    863866
    864867                                // consider only first exploded actual
    865                                 const Alternative& aActual = exploded.front();
    866                                 Type* actualType = aActual.expr->get_result()->clone();
     868                                const Alternative& actual = expl.alts.front();
     869                                Type* actualType = actual.expr->get_result()->clone();
    867870
    868871                                PRINT(
     
    876879                                // attempt to unify types
    877880                                if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
    878                                         // trim first element from exploded
    879                                         std::vector<Alternative> newExpls;
    880                                         newExpls.reserve( exploded.size() - 1 );
    881                                         for ( std::size_t i = 1; i < exploded.size(); ++i ) {
    882                                                 newExpls.push_back( move(exploded[i]) );
    883                                         }
    884881                                        // add new result
    885882                                        results.emplace_back(
    886                                                 i, aActual.expr, move(env), move(need), move(have), move(openVars),
    887                                                 j + 1, nTuples, actual.cost, move(newExpls) );
     883                                                i, actual.expr, move(env), move(need), move(have), move(openVars),
     884                                                nextArg + 1, nTuples, expl.cost, expl.alts.size() == 1 ? 0 : 1, j );
    888885                                }
    889886                        }
     
    921918        template<typename OutputIterator>
    922919        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func,
    923                         FunctionType *funcType, const std::vector< AlternativeFinder > &args,
    924                         OutputIterator out ) {
     920                        FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {
    925921                OpenVarSet funcOpenVars;
    926922                AssertionSet funcNeed, funcHave;
     
    961957                                // iterate results
    962958                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
     959                                        auto nextArg = results[i].nextArg;
     960
    963961                                        // use remainder of exploded tuple if present
    964                                         if ( ! results[i].expls.empty() ) {
    965                                                 const Alternative& actual = results[i].expls.front();
     962                                        if ( results[i].hasExpl() ) {
     963                                                const ExplodedActual& expl = results[i].getExpl( args );
     964                                                const Alternative& actual = expl.alts[results[i].nextExpl];
    966965                                               
    967966                                                TypeEnvironment env = results[i].env;
     
    970969                                                env.addActual( actual.env, openVars );
    971970
    972                                                 std::vector<Alternative> newExpls(
    973                                                         std::next( results[i].expls.begin() ), results[i].expls.end() );
     971                                                unsigned nextExpl = results[i].nextExpl + 1;
     972                                                if ( nextExpl == expl.alts.size() ) {
     973                                                        nextExpl = 0;
     974                                                }
     975
    974976                                                results.emplace_back(
    975977                                                        i, actual.expr, move(env), copy(results[i].need),
    976                                                         copy(results[i].have), move(openVars), results[i].nextArg, 0,
    977                                                         Cost::zero, move(newExpls) );
     978                                                        copy(results[i].have), move(openVars), nextArg, 0,
     979                                                        Cost::zero, nextExpl, results[i].explAlt );
    978980                                               
    979981                                                continue;
     
    981983
    982984                                        // finish result when out of arguments
    983                                         if ( results[i].nextArg >= args.size() ) {
     985                                        if ( nextArg >= args.size() ) {
    984986                                                validateFunctionAlternative( func, results[i], results, out );
    985987
     
    988990
    989991                                        // add each possible next argument
    990                                         auto j = results[i].nextArg;
    991                                         for ( const Alternative& actual : args[j] ) {
     992                                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
     993                                                const ExplodedActual& expl = args[nextArg][j];
     994
    992995                                                // fresh copies of parent parameters for this iteration
    993996                                                TypeEnvironment env = results[i].env;
    994997                                                OpenVarSet openVars = results[i].openVars;
    995998
    996                                                 env.addActual( actual.env, openVars );
    997 
    998                                                 // explode argument
    999                                                 std::vector<Alternative> exploded;
    1000                                                 Tuples::explode( actual, indexer, back_inserter( exploded ) );
    1001                                                 if ( exploded.empty() ) {
    1002                                                         // skip empty tuple arguments by (near-)cloning parent into next gen
     999                                                env.addActual( expl.env, openVars );
     1000
     1001                                                // skip empty tuple arguments by (near-)cloning parent into next gen
     1002                                                if ( expl.alts.empty() ) {
    10031003                                                        results.emplace_back(
    10041004                                                                results[i], move(env), copy(results[i].need),
    1005                                                                 copy(results[i].have), move(openVars), j + 1, actual.cost );
     1005                                                                copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
     1006                                                       
    10061007                                                        continue;
    10071008                                                }
    10081009
    1009                                                 // trim first element from exploded
    1010                                                 std::vector<Alternative> newExpls;
    1011                                                 newExpls.reserve( exploded.size() - 1 );
    1012                                                 for ( std::size_t i = 1; i < exploded.size(); ++i ) {
    1013                                                         newExpls.push_back( move(exploded[i]) );
    1014                                                 }
    10151010                                                // add new result
    10161011                                                results.emplace_back(
    1017                                                         i, exploded.front().expr, move(env), copy(results[i].need),
    1018                                                         copy(results[i].have), move(openVars), j + 1, 0,
    1019                                                         actual.cost, move(newExpls) );
     1012                                                        i, expl.alts.front().expr, move(env), copy(results[i].need),
     1013                                                        copy(results[i].have), move(openVars), nextArg + 1, 0,
     1014                                                        expl.cost, expl.alts.size() == 1 ? 0 : 1, j );
    10201015                                        }
    10211016                                }
     
    10271022                        for ( std::size_t i = genStart; i < results.size(); ++i ) {
    10281023                                ArgPack& result = results[i];
    1029                                 if ( result.expls.empty() && result.nextArg >= args.size() ) {
     1024                                if ( ! result.hasExpl() && result.nextArg >= args.size() ) {
    10301025                                        validateFunctionAlternative( func, result, results, out );
    10311026                                }
     
    10571052                        printAlts( funcOpFinder.alternatives, std::cerr, 1 );
    10581053                )
     1054
     1055                // pre-explode arguments
     1056                ExplodedArgs argExpansions;
     1057                argExpansions.reserve( argAlternatives.size() );
     1058
     1059                for ( const AlternativeFinder& arg : argAlternatives ) {
     1060                        argExpansions.emplace_back();
     1061                        auto& argE = argExpansions.back();
     1062                        argE.reserve( arg.alternatives.size() );
     1063                       
     1064                        for ( const Alternative& actual : arg ) {
     1065                                argE.emplace_back( actual, indexer );
     1066                        }
     1067                }
    10591068
    10601069                AltList candidates;
     
    10711080                                                Alternative newFunc( *func );
    10721081                                                referenceToRvalueConversion( newFunc.expr );
    1073                                                 makeFunctionAlternatives( newFunc, function, argAlternatives,
     1082                                                makeFunctionAlternatives( newFunc, function, argExpansions,
    10741083                                                        std::back_inserter( candidates ) );
    10751084                                        }
     
    10801089                                                        Alternative newFunc( *func );
    10811090                                                        referenceToRvalueConversion( newFunc.expr );
    1082                                                         makeFunctionAlternatives( newFunc, function, argAlternatives,
     1091                                                        makeFunctionAlternatives( newFunc, function, argExpansions,
    10831092                                                                std::back_inserter( candidates ) );
    10841093                                                } // if
     
    10921101                // try each function operator ?() with each function alternative
    10931102                if ( ! funcOpFinder.alternatives.empty() ) {
    1094                         // add function alternatives to front of argument list
    1095                         argAlternatives.insert( argAlternatives.begin(), move(funcFinder) );
     1103                        // add exploded function alternatives to front of argument list
     1104                        std::vector<ExplodedActual> funcE;
     1105                        funcE.reserve( funcFinder.alternatives.size() );
     1106                        for ( const Alternative& actual : funcFinder ) {
     1107                                funcE.emplace_back( actual, indexer );
     1108                        }
     1109                        argExpansions.insert( argExpansions.begin(), move(funcE) );
    10961110
    10971111                        for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin();
     
    11051119                                                        Alternative newFunc( *funcOp );
    11061120                                                        referenceToRvalueConversion( newFunc.expr );
    1107                                                         makeFunctionAlternatives( newFunc, function, argAlternatives,
     1121                                                        makeFunctionAlternatives( newFunc, function, argExpansions,
    11081122                                                                std::back_inserter( candidates ) );
    11091123                                                }
  • src/ResolvExpr/AlternativeFinder.h

    rc2c6177 ra8b27c6  
    2121
    2222#include "Alternative.h"                 // for AltList, Alternative
     23#include "ExplodedActual.h"              // for ExplodedActual
    2324#include "ResolvExpr/Cost.h"             // for Cost, Cost::infinity
    2425#include "ResolvExpr/TypeEnvironment.h"  // for AssertionSet, OpenVarSet
     
    3233namespace ResolvExpr {
    3334        class ArgPack;
     35       
     36        /// First index is which argument, second index is which alternative for that argument,
     37        /// third index is which exploded element of that alternative
     38        using ExplodedArgs = std::vector< std::vector< ExplodedActual > >;
    3439       
    3540        class AlternativeFinder : public Visitor {
     
    133138                /// Finds matching alternatives for a function, given a set of arguments
    134139                template<typename OutputIterator>
    135                 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const std::vector< AlternativeFinder >& args, OutputIterator out );
     140                void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out );
    136141                /// Checks if assertion parameters match for a new alternative
    137142                template< typename OutputIterator >
  • src/ResolvExpr/module.mk

    rc2c6177 ra8b27c6  
    3232       ResolvExpr/Occurs.cc \
    3333       ResolvExpr/TypeEnvironment.cc \
    34        ResolvExpr/CurrentObject.cc
     34       ResolvExpr/CurrentObject.cc \
     35       ResolvExpr/ExplodedActual.cc
Note: See TracChangeset for help on using the changeset viewer.