Changeset f53acdf8 for src/Tuples


Ignore:
Timestamp:
Jul 19, 2019, 2:16:01 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
4eb43fa
Parents:
1f1c102 (diff), 8ac3b0e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into new-ast

Location:
src/Tuples
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/Explode.h

    r1f1c102 rf53acdf8  
    5151        template<typename OutputIterator>
    5252        void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env,
    53                         const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 
     53                        const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need,
    5454                        const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
    5555                *out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost };
     
    5858        /// Append alternative to an ExplodedActual
    5959        static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr,
    60                         const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 
     60                        const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&,
    6161                        const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
    6262                ea.exprs.emplace_back( expr );
     
    111111                } else {
    112112                        // atomic (non-tuple) type - output a clone of the expression in a new alternative
    113                         append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need, 
     113                        append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need,
    114114                                alt.cost, alt.cvtCost );
    115115                }
     
    174174template< typename Output >
    175175void explodeRecursive(
    176         const ast::CastExpr * expr, const ResolvExpr::Candidate & arg,
    177         const ast::SymbolTable & symtab, Output && out
     176        const ast::CastExpr *, const ResolvExpr::Candidate &,
     177        const ast::SymbolTable &, Output &&
    178178) {
    179179}
     
    239239/// explode list of candidates into flattened list of candidates
    240240template< typename Output >
    241 void explode( 
    242         const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 
     241void explode(
     242        const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out,
    243243        bool isTupleAssign = false
    244244) {
  • src/Tuples/TupleAssignment.cc

    r1f1c102 rf53acdf8  
    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;
    432433
    433434                        virtual std::vector< ast::ptr< ast::Expr > > match() = 0;
    434435
    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 
     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
    437438                        /// bindings to the env
    438439                        struct EnvRemover {
     
    455456                        ast::ObjectDecl * newObject( UniqueName & namer, const ast::Expr * expr ) {
    456457                                assert( expr->result && ! expr->result->isVoid() );
    457                                
    458                                 ast::ObjectDecl * ret = new ast::ObjectDecl{ 
    459                                         location, namer.newName(), expr->result, new ast::SingleInit{ location, expr }, 
     458
     459                                ast::ObjectDecl * ret = new ast::ObjectDecl{
     460                                        location, namer.newName(), expr->result, new ast::SingleInit{ location, expr },
    460461                                        ast::Storage::Classes{}, ast::Linkage::Cforall };
    461                                
     462
    462463                                // if expression type is a reference, just need an initializer, otherwise construct
    463464                                if ( ! expr->result.as< ast::ReferenceType >() ) {
    464465                                        // resolve ctor/dtor for the new object
    465                                         ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 
     466                                        ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit(
    466467                                                        InitTweak::genCtorInit( location, ret ), spotter.crntFinder.localSyms );
    467468                                        // remove environments from subexpressions of stmtExpr
     
    474475                        }
    475476
    476                         ast::UntypedExpr * createFunc( 
    477                                 const std::string & fname, const ast::ObjectDecl * left, 
    478                                 const ast::ObjectDecl * right 
     477                        ast::UntypedExpr * createFunc(
     478                                const std::string & fname, const ast::ObjectDecl * left,
     479                                const ast::ObjectDecl * right
    479480                        ) {
    480481                                assert( left );
     
    486487                                        args.front() = new ast::AddressExpr{ location, args.front() };
    487488                                        if ( right ) { args.back() = new ast::AddressExpr{ location, args.back() }; }
    488                                         return new ast::UntypedExpr{ 
     489                                        return new ast::UntypedExpr{
    489490                                                location, new ast::NameExpr{ location, "?=?" }, std::move(args) };
    490491                                } else {
    491                                         return new ast::UntypedExpr{ 
     492                                        return new ast::UntypedExpr{
    492493                                                location, new ast::NameExpr{ location, fname }, std::move(args) };
    493494                                }
     
    498499                struct MassAssignMatcher final : public Matcher {
    499500                        MassAssignMatcher(
    500                                 TupleAssignSpotter_new & s, const CodeLocation & loc, 
     501                                TupleAssignSpotter_new & s, const CodeLocation & loc,
    501502                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
    502503                        : Matcher( s, loc, l, r ) {}
     
    508509                                assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 );
    509510
    510                                 ast::ptr< ast::ObjectDecl > rtmp = 
     511                                ast::ptr< ast::ObjectDecl > rtmp =
    511512                                        rhs.size() == 1 ? newObject( rhsNamer, rhs.front()->expr ) : nullptr;
    512513
    513514                                std::vector< ast::ptr< ast::Expr > > out;
    514515                                for ( ResolvExpr::CandidateRef & lhsCand : lhs ) {
    515                                         // create a temporary object for each value in the LHS and create a call 
     516                                        // create a temporary object for each value in the LHS and create a call
    516517                                        // involving the RHS
    517518                                        ast::ptr< ast::ObjectDecl > ltmp = newObject( lhsNamer, lhsCand->expr );
     
    528529                struct MultipleAssignMatcher final : public Matcher {
    529530                        MultipleAssignMatcher(
    530                                 TupleAssignSpotter_new & s, const CodeLocation & loc, 
     531                                TupleAssignSpotter_new & s, const CodeLocation & loc,
    531532                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
    532533                        : Matcher( s, loc, l, r ) {}
     
    538539                                if ( lhs.size() != rhs.size() ) return {};
    539540
    540                                 // produce a new temporary object for each value in the LHS and RHS and pairwise 
     541                                // produce a new temporary object for each value in the LHS and RHS and pairwise
    541542                                // create the calls
    542543                                std::vector< ast::ptr< ast::ObjectDecl > > ltmp, rtmp;
     
    547548                                        ResolvExpr::CandidateRef & rhsCand = rhs[i];
    548549
    549                                         // convert RHS to LHS type minus one reference -- important for case where LHS 
     550                                        // convert RHS to LHS type minus one reference -- important for case where LHS
    550551                                        // is && and RHS is lvalue
    551552                                        auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >();
     
    557558                                        rtmp.emplace_back( std::move( robj ) );
    558559
    559                                         // resolve the cast expression so that rhsCand return type is bound by the cast 
     560                                        // resolve the cast expression so that rhsCand return type is bound by the cast
    560561                                        // type as needed, and transfer the resulting environment
    561562                                        ResolvExpr::CandidateFinder finder{ spotter.crntFinder.localSyms, env };
     
    564565                                        env = std::move( finder.candidates.front()->env );
    565566                                }
    566                                
     567
    567568                                splice( tmpDecls, ltmp );
    568569                                splice( tmpDecls, rtmp );
    569                                
     570
    570571                                return out;
    571572                        }
     
    575576                std::string fname;
    576577                std::unique_ptr< Matcher > matcher;
    577        
     578
    578579        public:
    579                 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 
     580                TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f )
    580581                : crntFinder( f ), fname(), matcher() {}
    581582
    582583                // find left- and right-hand-sides for mass or multiple assignment
    583                 void spot( 
    584                         const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 
     584                void spot(
     585                        const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args
    585586                ) {
    586587                        if ( auto op = expr->func.as< ast::NameExpr >() ) {
     
    599600                                        if ( ! refToTuple( lhsCand->expr ) ) continue;
    600601
    601                                         // explode is aware of casts - ensure every LHS is sent into explode with a 
     602                                        // explode is aware of casts - ensure every LHS is sent into explode with a
    602603                                        // reference cast
    603604                                        if ( ! lhsCand->expr.as< ast::CastExpr >() ) {
    604                                                 lhsCand->expr = new ast::CastExpr{ 
     605                                                lhsCand->expr = new ast::CastExpr{
    605606                                                        lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } };
    606607                                        }
     
    610611                                        explode( *lhsCand, crntFinder.localSyms, back_inserter(lhs), true );
    611612                                        for ( ResolvExpr::CandidateRef & cand : lhs ) {
    612                                                 // each LHS value must be a reference - some come in with a cast, if not 
     613                                                // each LHS value must be a reference - some come in with a cast, if not
    613614                                                // just cast to reference here
    614615                                                if ( ! cand->expr->result.as< ast::ReferenceType >() ) {
     
    629630                                                                // multiple assignment
    630631                                                                explode( *rhsCand, crntFinder.localSyms, back_inserter(rhs), true );
    631                                                                 matcher.reset( 
     632                                                                matcher.reset(
    632633                                                                        new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
    633634                                                        } else {
    634635                                                                // mass assignment
    635636                                                                rhs.emplace_back( rhsCand );
    636                                                                 matcher.reset( 
     637                                                                matcher.reset(
    637638                                                                        new MassAssignMatcher{ *this, expr->location, lhs, rhs } );
    638639                                                        }
     
    642643                                                // expand all possible RHS possibilities
    643644                                                std::vector< ResolvExpr::CandidateList > rhsCands;
    644                                                 combos( 
     645                                                combos(
    645646                                                        std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) );
    646647                                                for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) {
     
    648649                                                        ResolvExpr::CandidateList rhs;
    649650                                                        explode( rhsCand, crntFinder.localSyms, back_inserter(rhs), true );
    650                                                         matcher.reset( 
     651                                                        matcher.reset(
    651652                                                                new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
    652653                                                        match();
     
    663664
    664665                        if ( ! ( matcher->lhs.empty() && matcher->rhs.empty() ) ) {
    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 
     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
    667668                                // candidates are generated
    668669                                if ( newAssigns.empty() ) return;
     
    692693                        }
    693694
    694                         // extract expressions from the assignment candidates to produce a list of assignments 
     695                        // extract expressions from the assignment candidates to produce a list of assignments
    695696                        // that together form a sigle candidate
    696697                        std::vector< ast::ptr< ast::Expr > > solved;
     
    701702
    702703                        crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >(
    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 ), 
     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 ),
    706707                                ResolvExpr::sumCost( crnt ) + matcher->baseCost ) );
    707708                }
     
    709710} // anonymous namespace
    710711
    711 void handleTupleAssignment( 
    712         ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 
     712void handleTupleAssignment(
     713        ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign,
    713714        std::vector< ResolvExpr::CandidateFinder > & args
    714715) {
Note: See TracChangeset for help on using the changeset viewer.