Changeset c43c171


Ignore:
Timestamp:
Oct 5, 2017, 3:55:26 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:
b5a8ef7
Parents:
a585396
Message:

Add tuple handling to iterative resolver rewrite

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    ra585396 rc43c171  
    887887                // take care of possible tuple assignments
    888888                // if not tuple assignment, assignment is taken care of as a normal function call
    889 /*FIX   Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );
    890 */
     889                Tuples::handleTupleAssignment( *this, untypedExpr, argAlternatives );
     890
    891891                // find function operators
    892892                AlternativeFinder funcOpFinder( indexer, env );
  • src/Tuples/Explode.h

    ra585396 rc43c171  
    3030        Expression * distributeReference( Expression * );
    3131
     32        static inline CastExpr * isReferenceCast( Expression * expr ) {
     33                if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
     34                        if ( dynamic_cast< ReferenceType * >( castExpr->result ) ) {
     35                                return castExpr;
     36                        }
     37                }
     38                return nullptr;
     39        }
     40
    3241        /// helper function used by explode
    3342        template< typename OutputIterator >
     
    3544                if ( isTupleAssign ) {
    3645                        // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components
    37                         if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
     46                        if ( CastExpr * castExpr = isReferenceCast( expr ) ) {
    3847                                ResolvExpr::AltList alts;
    3948                                explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
  • src/Tuples/TupleAssignment.cc

    ra585396 rc43c171  
    2020#include <memory>                          // for unique_ptr, allocator_trai...
    2121#include <string>                          // for string
     22#include <vector>
    2223
    2324#include "CodeGen/OperatorTable.h"
     
    3334#include "ResolvExpr/Resolver.h"           // for resolveCtorInit
    3435#include "ResolvExpr/TypeEnvironment.h"    // for TypeEnvironment
     36#include "ResolvExpr/typeops.h"            // for combos
    3537#include "SynTree/Declaration.h"           // for ObjectDecl
    3638#include "SynTree/Expression.h"            // for Expression, CastExpr, Name...
     
    4648                // dispatcher for Tuple (multiple and mass) assignment operations
    4749                TupleAssignSpotter( ResolvExpr::AlternativeFinder & );
    48                 void spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities );
     50                void spot( UntypedExpr * expr, std::vector<ResolvExpr::AlternativeFinder> &args );
    4951
    5052          private:
     
    5355                struct Matcher {
    5456                  public:
    55                         Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts );
     57                        Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const
     58                                ResolvExpr::AltList& rhs );
    5659                        virtual ~Matcher() {}
    5760                        virtual void match( std::list< Expression * > &out ) = 0;
     
    6669                struct MassAssignMatcher : public Matcher {
    6770                  public:
    68                         MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts );
     71                        MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,
     72                                const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {}
    6973                        virtual void match( std::list< Expression * > &out );
    7074                };
     
    7276                struct MultipleAssignMatcher : public Matcher {
    7377                  public:
    74                         MultipleAssignMatcher( TupleAssignSpotter &spot, const ResolvExpr::AltList & alts );
     78                        MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,
     79                                const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {}
    7580                        virtual void match( std::list< Expression * > &out );
    7681                };
     
    108113        }
    109114
    110         void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) {
     115        void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr,
     116                                std::vector<ResolvExpr::AlternativeFinder> &args ) {
    111117                TupleAssignSpotter spotter( currentFinder );
    112                 spotter.spot( expr, possibilities );
     118                spotter.spot( expr, args );
    113119        }
    114120
     
    116122                : currentFinder(f) {}
    117123
    118         void TupleAssignSpotter::spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) {
     124        void TupleAssignSpotter::spot( UntypedExpr * expr,
     125                        std::vector<ResolvExpr::AlternativeFinder> &args ) {
    119126                if (  NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) {
    120127                        if ( CodeGen::isCtorDtorAssign( op->get_name() ) ) {
    121128                                fname = op->get_name();
    122                                 for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
    123                                         if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal
    124                                         if ( ali->size() <= 1 && CodeGen::isAssignment( op->get_name() ) ) {
    125                                                 // what does it mean if an assignment takes 1 argument? maybe someone defined such a function, in which case AlternativeFinder will naturally handle it
    126                                                 continue;
     129
     130                                // AlternativeFinder will naturally handle this case case, if it's legal
     131                                if ( args.size() == 0 ) return;
     132
     133                                // if an assignment only takes 1 argument, that's odd, but maybe someone wrote
     134                                // the function, in which case AlternativeFinder will handle it normally
     135                                if ( args.size() == 1 && CodeGen::isAssignment( fname ) ) return;
     136
     137                                // look over all possible left-hand-sides
     138                                for ( ResolvExpr::Alternative& lhsAlt : args[0] ) {
     139                                        // skip non-tuple LHS
     140                                        if ( ! refToTuple(lhsAlt.expr) ) continue;
     141
     142                                        // explode is aware of casts - ensure every LHS expression is sent into explode
     143                                        // with a reference cast
     144                                        // xxx - this seems to change the alternatives before the normal
     145                                        //  AlternativeFinder flow; maybe this is desired?
     146                                        if ( ! dynamic_cast<CastExpr*>( lhsAlt.expr ) ) {
     147                                                lhsAlt.expr = new CastExpr( lhsAlt.expr,
     148                                                                new ReferenceType( Type::Qualifiers(),
     149                                                                        lhsAlt.expr->get_result()->clone() ) );
    127150                                        }
    128151
    129                                         assert( ! ali->empty() );
    130                                         // grab args 2-N and group into a TupleExpr
    131                                         const ResolvExpr::Alternative & alt1 = ali->front();
    132                                         auto begin = std::next(ali->begin(), 1), end = ali->end();
    133                                         if ( refToTuple(alt1.expr) ) {
    134                                                 if ( isMultAssign( begin, end ) ) {
    135                                                         matcher.reset( new MultipleAssignMatcher( *this, *ali ) );
    136                                                 } else {
    137                                                         // mass assignment
    138                                                         matcher.reset( new MassAssignMatcher( *this,  *ali ) );
     152                                        // explode the LHS so that each field of a tuple-valued-expr is assigned
     153                                        ResolvExpr::AltList lhs;
     154                                        explode( lhsAlt, currentFinder.get_indexer(), back_inserter(lhs), true );
     155                                        for ( ResolvExpr::Alternative& alt : lhs ) {
     156                                                // each LHS value must be a reference - some come in with a cast expression,
     157                                                // if not just cast to reference here
     158                                                if ( ! dynamic_cast<ReferenceType*>( alt.expr->get_result() ) ) {
     159                                                        alt.expr = new CastExpr( alt.expr,
     160                                                                new ReferenceType( Type::Qualifiers(),
     161                                                                        alt.expr->get_result()->clone() ) );
    139162                                                }
    140                                                 match();
     163                                        }
     164
     165                                        if ( args.size() > 2 ) {
     166                                                // expand all possible RHS possibilities
     167                                                // TODO build iterative version of this instead of using combos
     168                                                std::vector< ResolvExpr::AltList > rhsAlts;
     169                                                combos( std::next(args.begin(), 1), args.end(),
     170                                                        std::back_inserter( rhsAlts ) );
     171                                                for ( const ResolvExpr::AltList& rhsAlt : rhsAlts ) {
     172                                                        // multiple assignment
     173                                                        ResolvExpr::AltList rhs;
     174                                                        explode( rhsAlt, currentFinder.get_indexer(),
     175                                                                std::back_inserter(rhs), true );
     176                                                        matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) );
     177                                                        match();
     178                                                }
     179                                        } else {
     180                                                for ( const ResolvExpr::Alternative& rhsAlt : args[1] ) {
     181                                                        ResolvExpr::AltList rhs;
     182                                                        if ( isTuple(rhsAlt.expr) ) {
     183                                                                // multiple assignment
     184                                                                explode( rhsAlt, currentFinder.get_indexer(), 
     185                                                                        std::back_inserter(rhs), true );
     186                                                                matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) );
     187                                                        } else {
     188                                                                // mass assignment
     189                                                                rhs.push_back( rhsAlt );
     190                                                                matcher.reset( new MassAssignMatcher( *this, lhs, rhs ) );
     191                                                        }
     192                                                        match();
     193                                                }
    141194                                        }
    142195                                }
     
    183236        }
    184237
    185         TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList &alts ) : spotter(spotter), baseCost( ResolvExpr::sumCost( alts ) ) {
    186                 assert( ! alts.empty() );
    187                 // combine argument environments into combined expression environment
    188                 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv );
    189 
    190                 ResolvExpr::Alternative lhsAlt = alts.front();
    191                 // explode is aware of casts - ensure every LHS expression is sent into explode with a reference cast
    192                 if ( ! dynamic_cast< CastExpr * >( lhsAlt.expr ) ) {
    193                         lhsAlt.expr = new CastExpr( lhsAlt.expr, new ReferenceType( Type::Qualifiers(), lhsAlt.expr->get_result()->clone() ) );
    194                 }
    195 
    196                 // explode the lhs so that each field of the tuple-valued-expr is assigned.
    197                 explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs), true );
    198 
    199                 for ( ResolvExpr::Alternative & alt : lhs ) {
    200                         // every LHS value must be a reference - some come in with a cast expression, if it doesn't just cast to reference here.
    201                         if ( ! dynamic_cast< ReferenceType * >( alt.expr->get_result() ) ) {
    202                                 alt.expr = new CastExpr( alt.expr, new ReferenceType( Type::Qualifiers(), alt.expr->get_result()->clone() ) );
    203                         }
    204                 }
    205         }
    206 
    207         TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) {
    208                 assert( alts.size() == 1 || alts.size() == 2 );
    209                 if ( alts.size() == 2 ) {
    210                         rhs.push_back( alts.back() );
    211                 }
    212         }
    213 
    214         TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) {
    215                 // explode the rhs so that each field of the tuple-valued-expr is assigned.
    216                 explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs), true );
    217         }
     238        TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter,
     239                const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs )
     240        : lhs(lhs), rhs(rhs), spotter(spotter),
     241          baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) {}
    218242
    219243        UntypedExpr * createFunc( const std::string &fname, ObjectDecl *left, ObjectDecl *right ) {
  • src/Tuples/Tuples.h

    ra585396 rc43c171  
    1717
    1818#include <string>
     19#include <vector>
    1920
    2021#include "SynTree/Expression.h"
     
    2627namespace Tuples {
    2728        // TupleAssignment.cc
    28         void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, const std::list<ResolvExpr::AltList> & possibilities );
    29 
     29        void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign,
     30                std::vector< ResolvExpr::AlternativeFinder >& args );
     31       
    3032        // TupleExpansion.cc
    3133        /// expands z.[a, b.[x, y], c] into [z.a, z.b.x, z.b.y, z.c], inserting UniqueExprs as appropriate
Note: See TracChangeset for help on using the changeset viewer.