Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleAssignment.cc

    r7870799 rb8524ca  
    6767                struct Matcher {
    6868                  public:
    69                         Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs,
     69                        Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 
    7070                                const ResolvExpr::AltList& rhs );
    7171                        virtual ~Matcher() {}
    72 
     72                       
    7373                        virtual void match( std::list< Expression * > &out ) = 0;
    7474                        ObjectDecl * newObject( UniqueName & namer, Expression * expr );
     
    8383                                for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); }
    8484                        }
    85 
     85                       
    8686                        ResolvExpr::AltList lhs, rhs;
    8787                        TupleAssignSpotter_old &spotter;
     
    264264                }
    265265
    266                 // extract expressions from the assignment alternatives to produce a list of assignments
     266                // extract expressions from the assignment alternatives to produce a list of assignments 
    267267                // that together form a single alternative
    268268                std::list< Expression *> solved_assigns;
     
    271271                        matcher->combineState( alt );
    272272                }
    273 
     273               
    274274                // xxx -- was push_front
    275275                currentFinder.get_alternatives().push_back( ResolvExpr::Alternative{
    276                         new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv,
    277                         matcher->openVars,
    278                         ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ),
     276                        new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 
     277                        matcher->openVars, 
     278                        ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 
    279279                        ResolvExpr::sumCost( current ) + matcher->baseCost } );
    280280        }
     
    284284        : lhs(lhs), rhs(rhs), spotter(spotter),
    285285          baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) {
    286                 combineState( lhs );
     286                combineState( lhs ); 
    287287                combineState( rhs );
    288288        }
     
    390390                return dynamic_cast< const ast::TupleType * >( expr->result->stripReferences() );
    391391        }
    392 
     392       
    393393        /// true if `expr` is of tuple type or a reference to one
    394394        bool refToTuple( const ast::Expr * expr ) {
     
    421421                        }
    422422
    423                         Matcher(
     423                        Matcher( 
    424424                                TupleAssignSpotter_new & s, const CodeLocation & loc,
    425425                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
    426                         : lhs( l ), rhs( r ), spotter( s ), location( loc ),
    427                           baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(),
     426                        : lhs( l ), rhs( r ), spotter( s ), location( loc ), 
     427                          baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(), 
    428428                          env(), open(), need() {
    429429                                for ( auto & cand : lhs ) combineState( *cand );
    430430                                for ( auto & cand : rhs ) combineState( *cand );
    431431                        }
    432                         virtual ~Matcher() = default;
    433432
    434433                        virtual std::vector< ast::ptr< ast::Expr > > match() = 0;
    435434
    436                         /// removes environments from subexpressions within statement expressions, which could
    437                         /// throw off later passes like those in Box which rely on PolyMutator, and adds the
     435                        /// removes environments from subexpressions within statement expressions, which could 
     436                        /// throw off later passes like those in Box which rely on PolyMutator, and adds the 
    438437                        /// bindings to the env
    439438                        struct EnvRemover {
     
    456455                        ast::ObjectDecl * newObject( UniqueName & namer, const ast::Expr * expr ) {
    457456                                assert( expr->result && ! expr->result->isVoid() );
    458 
    459                                 ast::ObjectDecl * ret = new ast::ObjectDecl{
    460                                         location, namer.newName(), expr->result, new ast::SingleInit{ location, expr },
     457                               
     458                                ast::ObjectDecl * ret = new ast::ObjectDecl{ 
     459                                        location, namer.newName(), expr->result, new ast::SingleInit{ location, expr }, 
    461460                                        ast::Storage::Classes{}, ast::Linkage::Cforall };
    462 
     461                               
    463462                                // if expression type is a reference, just need an initializer, otherwise construct
    464463                                if ( ! expr->result.as< ast::ReferenceType >() ) {
    465464                                        // resolve ctor/dtor for the new object
    466                                         ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit(
     465                                        ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 
    467466                                                        InitTweak::genCtorInit( location, ret ), spotter.crntFinder.symtab );
    468467                                        // remove environments from subexpressions of stmtExpr
     
    475474                        }
    476475
    477                         ast::UntypedExpr * createFunc(
    478                                 const std::string & fname, const ast::ObjectDecl * left,
    479                                 const ast::ObjectDecl * right
     476                        ast::UntypedExpr * createFunc( 
     477                                const std::string & fname, const ast::ObjectDecl * left, 
     478                                const ast::ObjectDecl * right 
    480479                        ) {
    481480                                assert( left );
     
    487486                                        args.front() = new ast::AddressExpr{ location, args.front() };
    488487                                        if ( right ) { args.back() = new ast::AddressExpr{ location, args.back() }; }
    489                                         return new ast::UntypedExpr{
     488                                        return new ast::UntypedExpr{ 
    490489                                                location, new ast::NameExpr{ location, "?=?" }, std::move(args) };
    491490                                } else {
    492                                         return new ast::UntypedExpr{
     491                                        return new ast::UntypedExpr{ 
    493492                                                location, new ast::NameExpr{ location, fname }, std::move(args) };
    494493                                }
     
    499498                struct MassAssignMatcher final : public Matcher {
    500499                        MassAssignMatcher(
    501                                 TupleAssignSpotter_new & s, const CodeLocation & loc,
     500                                TupleAssignSpotter_new & s, const CodeLocation & loc, 
    502501                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
    503502                        : Matcher( s, loc, l, r ) {}
     
    509508                                assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 );
    510509
    511                                 ast::ptr< ast::ObjectDecl > rtmp =
     510                                ast::ptr< ast::ObjectDecl > rtmp = 
    512511                                        rhs.size() == 1 ? newObject( rhsNamer, rhs.front()->expr ) : nullptr;
    513512
    514513                                std::vector< ast::ptr< ast::Expr > > out;
    515514                                for ( ResolvExpr::CandidateRef & lhsCand : lhs ) {
    516                                         // create a temporary object for each value in the LHS and create a call
     515                                        // create a temporary object for each value in the LHS and create a call 
    517516                                        // involving the RHS
    518517                                        ast::ptr< ast::ObjectDecl > ltmp = newObject( lhsNamer, lhsCand->expr );
     
    529528                struct MultipleAssignMatcher final : public Matcher {
    530529                        MultipleAssignMatcher(
    531                                 TupleAssignSpotter_new & s, const CodeLocation & loc,
     530                                TupleAssignSpotter_new & s, const CodeLocation & loc, 
    532531                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
    533532                        : Matcher( s, loc, l, r ) {}
     
    539538                                if ( lhs.size() != rhs.size() ) return {};
    540539
    541                                 // produce a new temporary object for each value in the LHS and RHS and pairwise
     540                                // produce a new temporary object for each value in the LHS and RHS and pairwise 
    542541                                // create the calls
    543542                                std::vector< ast::ptr< ast::ObjectDecl > > ltmp, rtmp;
     
    548547                                        ResolvExpr::CandidateRef & rhsCand = rhs[i];
    549548
    550                                         // convert RHS to LHS type minus one reference -- important for case where LHS
     549                                        // convert RHS to LHS type minus one reference -- important for case where LHS 
    551550                                        // is && and RHS is lvalue
    552551                                        auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >();
     
    558557                                        rtmp.emplace_back( std::move( robj ) );
    559558
    560                                         // resolve the cast expression so that rhsCand return type is bound by the cast
     559                                        // resolve the cast expression so that rhsCand return type is bound by the cast 
    561560                                        // type as needed, and transfer the resulting environment
    562561                                        ResolvExpr::CandidateFinder finder{ spotter.crntFinder.symtab, env };
     
    565564                                        env = std::move( finder.candidates.front()->env );
    566565                                }
    567 
     566                               
    568567                                splice( tmpDecls, ltmp );
    569568                                splice( tmpDecls, rtmp );
    570 
     569                               
    571570                                return out;
    572571                        }
     
    576575                std::string fname;
    577576                std::unique_ptr< Matcher > matcher;
    578 
     577       
    579578        public:
    580                 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f )
     579                TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 
    581580                : crntFinder( f ), fname(), matcher() {}
    582581
    583582                // find left- and right-hand-sides for mass or multiple assignment
    584                 void spot(
    585                         const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args
     583                void spot( 
     584                        const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 
    586585                ) {
    587586                        if ( auto op = expr->func.as< ast::NameExpr >() ) {
     
    600599                                        if ( ! refToTuple( lhsCand->expr ) ) continue;
    601600
    602                                         // explode is aware of casts - ensure every LHS is sent into explode with a
     601                                        // explode is aware of casts - ensure every LHS is sent into explode with a 
    603602                                        // reference cast
    604603                                        if ( ! lhsCand->expr.as< ast::CastExpr >() ) {
    605                                                 lhsCand->expr = new ast::CastExpr{
     604                                                lhsCand->expr = new ast::CastExpr{ 
    606605                                                        lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } };
    607606                                        }
     
    611610                                        explode( *lhsCand, crntFinder.symtab, back_inserter(lhs), true );
    612611                                        for ( ResolvExpr::CandidateRef & cand : lhs ) {
    613                                                 // each LHS value must be a reference - some come in with a cast, if not
     612                                                // each LHS value must be a reference - some come in with a cast, if not 
    614613                                                // just cast to reference here
    615614                                                if ( ! cand->expr->result.as< ast::ReferenceType >() ) {
     
    630629                                                                // multiple assignment
    631630                                                                explode( *rhsCand, crntFinder.symtab, back_inserter(rhs), true );
    632                                                                 matcher.reset(
     631                                                                matcher.reset( 
    633632                                                                        new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
    634633                                                        } else {
    635634                                                                // mass assignment
    636635                                                                rhs.emplace_back( rhsCand );
    637                                                                 matcher.reset(
     636                                                                matcher.reset( 
    638637                                                                        new MassAssignMatcher{ *this, expr->location, lhs, rhs } );
    639638                                                        }
     
    643642                                                // expand all possible RHS possibilities
    644643                                                std::vector< ResolvExpr::CandidateList > rhsCands;
    645                                                 combos(
     644                                                combos( 
    646645                                                        std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) );
    647646                                                for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) {
     
    649648                                                        ResolvExpr::CandidateList rhs;
    650649                                                        explode( rhsCand, crntFinder.symtab, back_inserter(rhs), true );
    651                                                         matcher.reset(
     650                                                        matcher.reset( 
    652651                                                                new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
    653652                                                        match();
     
    664663
    665664                        if ( ! ( matcher->lhs.empty() && matcher->rhs.empty() ) ) {
    666                                 // if both LHS and RHS are empty than this is the empty tuple case, wherein it's
    667                                 // okay for newAssigns to be empty. Otherwise, return early so that no new
     665                                // if both LHS and RHS are empty than this is the empty tuple case, wherein it's 
     666                                // okay for newAssigns to be empty. Otherwise, return early so that no new 
    668667                                // candidates are generated
    669668                                if ( newAssigns.empty() ) return;
     
    693692                        }
    694693
    695                         // extract expressions from the assignment candidates to produce a list of assignments
     694                        // extract expressions from the assignment candidates to produce a list of assignments 
    696695                        // that together form a sigle candidate
    697696                        std::vector< ast::ptr< ast::Expr > > solved;
     
    702701
    703702                        crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >(
    704                                 new ast::TupleAssignExpr{
    705                                         matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) },
    706                                 std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ),
     703                                new ast::TupleAssignExpr{ 
     704                                        matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) }, 
     705                                std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ), 
    707706                                ResolvExpr::sumCost( crnt ) + matcher->baseCost ) );
    708707                }
     
    710709} // anonymous namespace
    711710
    712 void handleTupleAssignment(
    713         ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign,
     711void handleTupleAssignment( 
     712        ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 
    714713        std::vector< ResolvExpr::CandidateFinder > & args
    715714) {
Note: See TracChangeset for help on using the changeset viewer.