Changes in / [178e4ec:8dceeb7]


Ignore:
Location:
src
Files:
2 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile.in

    r178e4ec r8dceeb7  
    210210        ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
    211211        ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \
    212         ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT) \
    213212        SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
    214213        SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
     
    512511        ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \
    513512        ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.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 \
     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 \
    523521        SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
    524522        SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    827825        ResolvExpr/$(am__dirstamp) \
    828826        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    829 ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT):  \
    830         ResolvExpr/$(am__dirstamp) \
    831         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    832827SymTab/$(am__dirstamp):
    833828        @$(MKDIR_P) SymTab
     
    10271022@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@
    10281023@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@
    10301024@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@
    10311025@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@
     
    19701964@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`
    19711965
    1972 ResolvExpr/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 
    1979 ResolvExpr/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 
    19861966SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
    19871967@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/Alternative.h

    r178e4ec r8dceeb7  
    3737                void print( std::ostream &os, Indenter indent = {} ) const;
    3838
    39                 /// Returns the stored expression, but released from management of this Alternative
    40                 Expression* release_expr() {
    41                         Expression* tmp = expr;
    42                         expr = nullptr;
    43                         return tmp;
    44                 }
    45 
    4639                Cost cost;
    4740                Cost cvtCost;
  • src/ResolvExpr/AlternativeFinder.cc

    r178e4ec r8dceeb7  
    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
     
    591590                unsigned nextArg;                  ///< Index of next argument in arguments list
    592591                unsigned tupleStart;               ///< Number of tuples that start at this index
    593                 unsigned nextExpl;                 ///< Index of next exploded element
    594                 unsigned explAlt;                  ///< Index of alternative for nextExpl > 0
     592                // TODO fix this somehow
     593                std::vector<Alternative> expls;    ///< Exploded actuals left over from last match
    595594
    596595                ArgPack()
    597596                        : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
    598 
    599                           tupleStart(0), nextExpl(0), explAlt(0) {}
     597                          tupleStart(0), expls() {}
    600598
    601599                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
    602600                                const OpenVarSet& openVars)
    603601                        : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have),
    604                           openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}
     602                          openVars(openVars), nextArg(0), tupleStart(0), expls() {}
    605603
    606604                ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need,
    607605                                AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg,
    608                                 unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0,
    609                                 unsigned explAlt = 0 )
     606                                unsigned tupleStart = 0, Cost cost = Cost::zero,
     607                                std::vector<Alternative>&& expls = std::vector<Alternative>{} )
    610608                        : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)),
    611609                          have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart),
    612                           nextExpl(nextExpl), explAlt(explAlt) {}
     610                          expls(move(expls)) {}
    613611
    614612                ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have,
     
    616614                        : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added),
    617615                          env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)),
    618                           nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}
    619 
    620                 /// true iff this pack is in the middle of an exploded argument
    621                 bool hasExpl() const { return nextExpl > 0; }
    622 
    623                 /// Gets the list of exploded alternatives for this pack
    624                 const ExplodedActual& getExpl( const ExplodedArgs& args ) const {
    625                         return args[nextArg-1][explAlt];
    626                 }
     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;
    627625
    628626                /// Ends a tuple expression, consolidating the appropriate actuals
     
    646644        /// Instantiates an argument to match a formal, returns false if no results left
    647645        bool instantiateArgument( Type* formalType, Initializer* initializer,
    648                         const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart,
    649                         const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
     646                        const std::vector< AlternativeFinder >& args, std::vector<ArgPack>& results,
     647                        std::size_t& genStart, const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
    650648                if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) {
    651649                        // formalType is a TupleType - group actuals into a TupleExpr
     
    678676                                // add another argument to results
    679677                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    680                                         auto nextArg = results[i].nextArg;
    681 
    682                                         // use next element of exploded tuple if present
    683                                         if ( results[i].hasExpl() ) {
    684                                                 const ExplodedActual& expl = results[i].getExpl( args );
    685 
    686                                                 unsigned nextExpl = results[i].nextExpl + 1;
    687                                                 if ( nextExpl == expl.exprs.size() ) {
    688                                                         nextExpl = 0;
    689                                                 }
    690 
     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() );
    691689                                                results.emplace_back(
    692                                                         i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
    693                                                         copy(results[i].need), copy(results[i].have),
    694                                                         copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl,
    695                                                         results[i].explAlt );
     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) );
    696693
    697694                                                continue;
     
    699696
    700697                                        // finish result when out of arguments
    701                                         if ( nextArg >= args.size() ) {
     698                                        if ( results[i].nextArg >= args.size() ) {
    702699                                                ArgPack newResult{
    703700                                                        results[i].env, results[i].need, results[i].have,
    704701                                                        results[i].openVars };
    705                                                 newResult.nextArg = nextArg;
     702                                                newResult.nextArg = results[i].nextArg;
    706703                                                Type* argType;
    707704
     
    747744
    748745                                        // add each possible next argument
    749                                         for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
    750                                                 const ExplodedActual& expl = args[nextArg][j];
    751 
     746                                        auto j = results[i].nextArg;
     747                                        for ( const Alternative& actual : args[j] ) {
    752748                                                // fresh copies of parent parameters for this iteration
    753749                                                TypeEnvironment env = results[i].env;
    754750                                                OpenVarSet openVars = results[i].openVars;
    755751
    756                                                 env.addActual( expl.env, openVars );
    757 
    758                                                 // skip empty tuple arguments by (near-)cloning parent into next gen
    759                                                 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
    760759                                                        results.emplace_back(
    761760                                                                results[i], move(env), copy(results[i].need),
    762                                                                 copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
     761                                                                copy(results[i].have), move(openVars), j + 1, actual.cost );
    763762
    764763                                                        continue;
    765764                                                }
    766765
     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                                                }
    767772                                                // add new result
    768773                                                results.emplace_back(
    769                                                         i, expl.exprs.front().get(), move(env), copy(results[i].need),
    770                                                         copy(results[i].have), move(openVars), nextArg + 1,
    771                                                         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) );
    772777                                        }
    773778                                }
     
    788793                std::size_t genEnd = results.size();
    789794                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    790                         auto nextArg = results[i].nextArg;
    791 
    792795                        // use remainder of exploded tuple if present
    793                         if ( results[i].hasExpl() ) {
    794                                 const ExplodedActual& expl = results[i].getExpl( args );
    795                                 Expression* expr = expl.exprs[results[i].nextExpl].get();
     796                        if ( ! results[i].expls.empty() ) {
     797                                const Alternative& actual = results[i].expls.front();
    796798
    797799                                TypeEnvironment env = results[i].env;
     
    799801                                OpenVarSet openVars = results[i].openVars;
    800802
    801                                 Type* actualType = expr->get_result();
     803                                env.addActual( actual.env, openVars );
     804                                Type* actualType = actual.expr->get_result();
    802805
    803806                                PRINT(
     
    810813
    811814                                if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
    812                                         unsigned nextExpl = results[i].nextExpl + 1;
    813                                         if ( nextExpl == expl.exprs.size() ) {
    814                                                 nextExpl = 0;
    815                                         }
    816 
     815                                        std::vector<Alternative> newExpls(
     816                                                std::next( results[i].expls.begin() ), results[i].expls.end() );
    817817                                        results.emplace_back(
    818                                                 i, expr, move(env), move(need), move(have), move(openVars), nextArg,
    819                                                 nTuples, Cost::zero, nextExpl, results[i].explAlt );
     818                                                i, actual.expr, move(env), move(need), move(have), move(openVars),
     819                                                results[i].nextArg, nTuples, Cost::zero, move(newExpls) );;
    820820                                }
    821821
     
    824824
    825825                        // use default initializers if out of arguments
    826                         if ( nextArg >= args.size() ) {
     826                        if ( results[i].nextArg >= args.size() ) {
    827827                                if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) {
    828828                                        if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) {
     
    835835                                                        results.emplace_back(
    836836                                                                i, cnstExpr, move(env), move(need), move(have),
    837                                                                 move(openVars), nextArg, nTuples );
     837                                                                move(openVars), results[i].nextArg, nTuples );
    838838                                                }
    839839                                        }
     
    844844
    845845                        // Check each possible next argument
    846                         for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
    847                                 const ExplodedActual& expl = args[nextArg][j];
    848 
     846                        auto j = results[i].nextArg;
     847                        for ( const Alternative& actual : args[j] ) {
    849848                                // fresh copies of parent parameters for this iteration
    850849                                TypeEnvironment env = results[i].env;
     
    852851                                OpenVarSet openVars = results[i].openVars;
    853852
    854                                 env.addActual( expl.env, openVars );
    855 
    856                                 // skip empty tuple arguments by (near-)cloning parent into next gen
    857                                 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
    858860                                        results.emplace_back(
    859                                                 results[i], move(env), move(need), move(have), move(openVars),
    860                                                 nextArg + 1, expl.cost );
     861                                                results[i], move(env), move(need), move(have), move(openVars), j + 1,
     862                                                actual.cost );
    861863
    862864                                        continue;
     
    864866
    865867                                // consider only first exploded actual
    866                                 Expression* expr = expl.exprs.front().get();
    867                                 Type* actualType = expr->get_result()->clone();
     868                                const Alternative& aActual = exploded.front();
     869                                Type* actualType = aActual.expr->get_result()->clone();
    868870
    869871                                PRINT(
     
    877879                                // attempt to unify types
    878880                                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                                        }
    879887                                        // add new result
    880888                                        results.emplace_back(
    881                                                 i, expr, move(env), move(need), move(have), move(openVars), nextArg + 1,
    882                                                 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) );
    883891                                }
    884892                        }
     
    916924        template<typename OutputIterator>
    917925        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func,
    918                         FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {
     926                        FunctionType *funcType, const std::vector< AlternativeFinder > &args,
     927                        OutputIterator out ) {
    919928                OpenVarSet funcOpenVars;
    920929                AssertionSet funcNeed, funcHave;
     
    955964                                // iterate results
    956965                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    957                                         auto nextArg = results[i].nextArg;
    958 
    959966                                        // use remainder of exploded tuple if present
    960                                         if ( results[i].hasExpl() ) {
    961                                                 const ExplodedActual& expl = results[i].getExpl( args );
    962 
    963                                                 unsigned nextExpl = results[i].nextExpl + 1;
    964                                                 if ( nextExpl == expl.exprs.size() ) {
    965                                                         nextExpl = 0;
    966                                                 }
    967 
     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() );
    968977                                                results.emplace_back(
    969                                                         i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
    970                                                         copy(results[i].need), copy(results[i].have),
    971                                                         copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl,
    972                                                         results[i].explAlt );
     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) );
    973981
    974982                                                continue;
     
    976984
    977985                                        // finish result when out of arguments
    978                                         if ( nextArg >= args.size() ) {
     986                                        if ( results[i].nextArg >= args.size() ) {
    979987                                                validateFunctionAlternative( func, results[i], results, out );
    980988
     
    983991
    984992                                        // add each possible next argument
    985                                         for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
    986                                                 const ExplodedActual& expl = args[nextArg][j];
    987 
     993                                        auto j = results[i].nextArg;
     994                                        for ( const Alternative& actual : args[j] ) {
    988995                                                // fresh copies of parent parameters for this iteration
    989996                                                TypeEnvironment env = results[i].env;
    990997                                                OpenVarSet openVars = results[i].openVars;
    991998
    992                                                 env.addActual( expl.env, openVars );
    993 
    994                                                 // skip empty tuple arguments by (near-)cloning parent into next gen
    995                                                 if ( expl.exprs.empty() ) {
     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
    9961006                                                        results.emplace_back(
    9971007                                                                results[i], move(env), copy(results[i].need),
    998                                                                 copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
    999 
     1008                                                                copy(results[i].have), move(openVars), j + 1, actual.cost );
    10001009                                                        continue;
    10011010                                                }
    10021011
     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                                                }
    10031018                                                // add new result
    10041019                                                results.emplace_back(
    1005                                                         i, expl.exprs.front().get(), move(env), copy(results[i].need),
    1006                                                         copy(results[i].have), move(openVars), nextArg + 1, 0,
    1007                                                         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) );
    10081023                                        }
    10091024                                }
     
    10151030                        for ( std::size_t i = genStart; i < results.size(); ++i ) {
    10161031                                ArgPack& result = results[i];
    1017                                 if ( ! result.hasExpl() && result.nextArg >= args.size() ) {
     1032                                if ( result.expls.empty() && result.nextArg >= args.size() ) {
    10181033                                        validateFunctionAlternative( func, result, results, out );
    10191034                                }
     
    10451060                        printAlts( funcOpFinder.alternatives, std::cerr, 1 );
    10461061                )
    1047 
    1048                 // pre-explode arguments
    1049                 ExplodedArgs argExpansions;
    1050                 argExpansions.reserve( argAlternatives.size() );
    1051 
    1052                 for ( const AlternativeFinder& arg : argAlternatives ) {
    1053                         argExpansions.emplace_back();
    1054                         auto& argE = argExpansions.back();
    1055                         argE.reserve( arg.alternatives.size() );
    1056 
    1057                         for ( const Alternative& actual : arg ) {
    1058                                 argE.emplace_back( actual, indexer );
    1059                         }
    1060                 }
    10611062
    10621063                AltList candidates;
     
    10731074                                                Alternative newFunc( *func );
    10741075                                                referenceToRvalueConversion( newFunc.expr );
    1075                                                 makeFunctionAlternatives( newFunc, function, argExpansions,
     1076                                                makeFunctionAlternatives( newFunc, function, argAlternatives,
    10761077                                                        std::back_inserter( candidates ) );
    10771078                                        }
     
    10821083                                                        Alternative newFunc( *func );
    10831084                                                        referenceToRvalueConversion( newFunc.expr );
    1084                                                         makeFunctionAlternatives( newFunc, function, argExpansions,
     1085                                                        makeFunctionAlternatives( newFunc, function, argAlternatives,
    10851086                                                                std::back_inserter( candidates ) );
    10861087                                                } // if
     
    10941095                // try each function operator ?() with each function alternative
    10951096                if ( ! funcOpFinder.alternatives.empty() ) {
    1096                         // add exploded function alternatives to front of argument list
    1097                         std::vector<ExplodedActual> funcE;
    1098                         funcE.reserve( funcFinder.alternatives.size() );
    1099                         for ( const Alternative& actual : funcFinder ) {
    1100                                 funcE.emplace_back( actual, indexer );
    1101                         }
    1102                         argExpansions.insert( argExpansions.begin(), move(funcE) );
     1097                        // add function alternatives to front of argument list
     1098                        argAlternatives.insert( argAlternatives.begin(), move(funcFinder) );
    11031099
    11041100                        for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin();
     
    11121108                                                        Alternative newFunc( *funcOp );
    11131109                                                        referenceToRvalueConversion( newFunc.expr );
    1114                                                         makeFunctionAlternatives( newFunc, function, argExpansions,
     1110                                                        makeFunctionAlternatives( newFunc, function, argAlternatives,
    11151111                                                                std::back_inserter( candidates ) );
    11161112                                                }
  • src/ResolvExpr/AlternativeFinder.h

    r178e4ec r8dceeb7  
    2121
    2222#include "Alternative.h"                 // for AltList, Alternative
    23 #include "ExplodedActual.h"              // for ExplodedActual
    2423#include "ResolvExpr/Cost.h"             // for Cost, Cost::infinity
    2524#include "ResolvExpr/TypeEnvironment.h"  // for AssertionSet, OpenVarSet
     
    3332namespace ResolvExpr {
    3433        struct 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 > >;
    3934
    4035        class AlternativeFinder : public Visitor {
     
    138133                /// Finds matching alternatives for a function, given a set of arguments
    139134                template<typename OutputIterator>
    140                 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out );
     135                void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const std::vector< AlternativeFinder >& args, OutputIterator out );
    141136                /// Checks if assertion parameters match for a new alternative
    142137                template< typename OutputIterator >
  • src/ResolvExpr/module.mk

    r178e4ec r8dceeb7  
    3232       ResolvExpr/Occurs.cc \
    3333       ResolvExpr/TypeEnvironment.cc \
    34        ResolvExpr/CurrentObject.cc \
    35        ResolvExpr/ExplodedActual.cc
     34       ResolvExpr/CurrentObject.cc
  • src/Tuples/Explode.h

    r178e4ec r8dceeb7  
    1616#pragma once
    1717
    18 #include <iterator>                     // for back_inserter, back_insert_iterator
    19 #include <utility>                      // for forward
     18#include <iterator>                  // for back_inserter, back_insert_iterator
    2019
    21 #include "ResolvExpr/Alternative.h"     // for Alternative, AltList
    22 #include "ResolvExpr/ExplodedActual.h"  // for ExplodedActual
    23 #include "SynTree/Expression.h"         // for Expression, UniqueExpr, AddressExpr
    24 #include "SynTree/Type.h"               // for TupleType, Type
    25 #include "Tuples.h"                     // for maybeImpure
     20#include "ResolvExpr/Alternative.h"  // for Alternative, AltList
     21#include "SynTree/Expression.h"      // for Expression, UniqueExpr, AddressExpr
     22#include "SynTree/Type.h"            // for TupleType, Type
     23#include "Tuples.h"                  // for maybeImpure
    2624
    2725namespace SymTab {
     
    4139        }
    4240
    43         /// Append alternative to an OutputIterator of Alternatives
    44         template<typename OutputIterator>
    45         void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env,
    46                         const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
    47                 *out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost };
    48         }
    49 
    50         /// Append alternative to an ExplodedActual
    51         static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr,
    52                         const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
    53                 ea.exprs.emplace_back( expr );
    54                 /// xxx -- merge environment, cost?
    55         }
    56 
    5741        /// helper function used by explode
    58         template< typename Output >
    59         void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt,
    60                         const SymTab::Indexer & indexer, Output&& out, bool isTupleAssign ) {
     42        template< typename OutputIterator >
     43        void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
    6144                if ( isTupleAssign ) {
    6245                        // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components
    6346                        if ( CastExpr * castExpr = isReferenceCast( expr ) ) {
    6447                                ResolvExpr::AltList alts;
    65                                 explodeUnique(
    66                                         castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
     48                                explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
    6749                                for ( ResolvExpr::Alternative & alt : alts ) {
    6850                                        // distribute reference cast over all components
    69                                         append( std::forward<Output>(out), distributeReference( alt.release_expr() ),
    70                                                 alt.env, alt.cost, alt.cvtCost );
     51                                        alt.expr = distributeReference( alt.expr );
     52                                        *out++ = alt;
    7153                                }
    7254                                // in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives)
     
    7961                                // can open tuple expr and dump its exploded components
    8062                                for ( Expression * expr : tupleExpr->get_exprs() ) {
    81                                         explodeUnique( expr, alt, indexer, std::forward<Output>(out), isTupleAssign );
     63                                        explodeUnique( expr, alt, indexer, out, isTupleAssign );
    8264                                }
    8365                        } else {
     
    9577                                for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
    9678                                        TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i );
    97                                         explodeUnique( idx, alt, indexer, std::forward<Output>(out), isTupleAssign );
     79                                        explodeUnique( idx, alt, indexer, out, isTupleAssign );
    9880                                        delete idx;
    9981                                }
     
    10284                } else {
    10385                        // atomic (non-tuple) type - output a clone of the expression in a new alternative
    104                         append( std::forward<Output>(out), expr->clone(), alt.env, alt.cost, alt.cvtCost );
     86                        *out++ = ResolvExpr::Alternative( expr->clone(), alt.env, alt.cost, alt.cvtCost );
    10587                }
    10688        }
    10789
    10890        /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type
    109         template< typename Output >
    110         void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer,
    111                         Output&& out, bool isTupleAssign = false ) {
    112                 explodeUnique( alt.expr, alt, indexer, std::forward<Output>(out), isTupleAssign );
     91        template< typename OutputIterator >
     92        void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
     93                explodeUnique( alt.expr, alt, indexer, out, isTupleAssign );
    11394        }
    11495
    11596        // explode list of alternatives
    116         template< typename AltIterator, typename Output >
    117         void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer,
    118                         Output&& out, bool isTupleAssign = false ) {
     97        template< typename AltIterator, typename OutputIterator >
     98        void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
    11999                for ( ; altBegin != altEnd; ++altBegin ) {
    120                         explode( *altBegin, indexer, std::forward<Output>(out), isTupleAssign );
     100                        explode( *altBegin, indexer, out, isTupleAssign );
    121101                }
    122102        }
    123103
    124         template< typename Output >
    125         void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, Output&& out,
    126                         bool isTupleAssign = false ) {
    127                 explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign );
     104        template< typename OutputIterator >
     105        void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
     106                explode( alts.begin(), alts.end(), indexer, out, isTupleAssign );
    128107        }
    129108} // namespace Tuples
Note: See TracChangeset for help on using the changeset viewer.