Ignore:
Timestamp:
Sep 12, 2016, 6:32:46 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
f006f01
Parents:
8f7cea1
git-author:
Rob Schluntz <rschlunt@…> (09/12/16 18:24:34)
git-committer:
Rob Schluntz <rschlunt@…> (09/12/16 18:32:46)
Message:

make TupleAssignment? generate temporaries, add StmtExpr? for GCC statement expressions, expand tuple assignment expressions, collapse SolvedTupleExpr?, MassAssignExpr?, and MultipleAssignExpr? into TupleAssignExpr?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleAssignment.cc

    r8f7cea1 r6eb8948  
    1818#include "ResolvExpr/typeops.h"
    1919#include "SynTree/Expression.h"
    20 #include "TupleAssignment.h"
     20#include "SynTree/Initializer.h"
     21#include "Tuples.h"
    2122#include "Common/SemanticError.h"
    2223
     
    4041                // records for assignment generation
    4142                struct Options {
    42                         std::list< ResolvExpr::AltList > get_best();
    4343                        void print( std::ostream & );
    4444                        int size() const { return options.size(); }
     
    5151                };
    5252
    53                 class Matcher {
     53                struct Matcher {
    5454                  public:
    5555                        Matcher( TupleAssignSpotter &spotter, Expression *_lhs, Expression *_rhs );
    5656                        virtual ~Matcher() {}
    5757                        virtual void match( std::list< Expression * > &out ) = 0;
    58                         virtual void solve() = 0;
    59                         static UntypedExpr *createAssgn( Expression *left, Expression *right );
    60                   protected:
    6158                        std::list< Expression * > lhs, rhs;
    6259                        TupleAssignSpotter &spotter;
    63                 };
    64 
    65                 class MassAssignMatcher : public Matcher {
     60                        std::list< ObjectDecl * > tmpDecls;
     61                };
     62
     63                struct MassAssignMatcher : public Matcher {
    6664                  public:
    6765                        MassAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) {
     
    6967                        }
    7068                        virtual void match( std::list< Expression * > &out );
    71                         virtual void solve();
    72                 };
    73 
    74                 class MultipleAssignMatcher : public Matcher {
     69                };
     70
     71                struct MultipleAssignMatcher : public Matcher {
    7572                  public:
    7673                        MultipleAssignMatcher( TupleAssignSpotter &spot, Expression *lhs, Expression *rhs );
    7774                        virtual void match( std::list< Expression * > &out );
    78                         virtual void solve();
    7975                };
    8076
    8177                ResolvExpr::AlternativeFinder &currentFinder;
    82                 Expression *rhs, *lhs;
     78                // Expression *rhs, *lhs;
    8379                Matcher *matcher = nullptr;
    8480                Options options;
     
    149145
    150146                if ( new_assigns.empty() ) return;
    151                 std::list< Expression * > solved_assigns;
    152147                ResolvExpr::AltList current;
    153148                // now resolve new assignments
     
    161156                        current.push_back( alts.front() );
    162157                }
    163                 options.options.push_back( current );
    164 
    165                 matcher->solve();
     158
     159                // extract expressions from the assignment alternatives to produce a list of assignments that
     160                // together form a single alternative
     161                std::list< Expression *> solved_assigns;
     162                for ( ResolvExpr::Alternative & alt : current ) {
     163                        solved_assigns.push_back( alt.expr->clone() );
     164                }
     165                // xxx - need to do this??
     166                // TypeEnvironment compositeEnv;
     167                // simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
     168                currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), currentFinder.get_environ(), ResolvExpr::sumCost( current ) ) );
    166169        }
    167170
     
    179182        }
    180183
    181         UntypedExpr *TupleAssignSpotter::Matcher::createAssgn( Expression *left, Expression *right ) {
     184        UntypedExpr * createAssgn( ObjectDecl *left, ObjectDecl *right ) {
    182185                assert( left && right );
    183186                std::list< Expression * > args;
    184                 args.push_back( new AddressExpr( left->clone() ) );
    185                 args.push_back( right->clone() );
     187                args.push_back( new AddressExpr( new UntypedExpr( new NameExpr("*?"), std::list< Expression * >{ new VariableExpr( left ) } ) ) );
     188                args.push_back( new VariableExpr( right ) );
    186189                return new UntypedExpr( new NameExpr( "?=?" ), args );
    187190        }
    188191
     192        ObjectDecl * newObject( UniqueName & namer, Expression * expr ) {
     193                Type * type;
     194                assert( expr->get_results().size() >= 1 );
     195                if ( expr->get_results().size() > 1 ) {
     196                        TupleType * tt = new TupleType( Type::Qualifiers() );
     197                        cloneAll( expr->get_results(), tt->get_types() );
     198                        type = tt;
     199                } else {
     200                        type = expr->get_results().front()->clone();
     201                }
     202                return new ObjectDecl( namer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, type, new SingleInit( expr->clone() ) );
     203        }
     204
    189205        void TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
     206                static UniqueName lhsNamer( "__massassign_L" );
     207                static UniqueName rhsNamer( "__massassign_R" );
    190208                assert ( ! lhs.empty() && rhs.size() == 1);
    191209
     210                ObjectDecl * rtmp = newObject( rhsNamer, rhs.front() );
    192211                for ( Expression * l : lhs ) {
    193                         out.push_back( createAssgn( l, rhs.front() ) );
    194                 }
    195         }
    196 
    197         void TupleAssignSpotter::MassAssignMatcher::solve() {
    198                 assert( ! spotter.options.empty() );
    199                 for ( std::list< ResolvExpr::AltList >::iterator i = spotter.options.begin(); i != spotter.options.end(); ++i ) {
    200                         // extract expressions from the alternatives to produce a list of assignments that
    201                         // together form a single alternative
    202                         std::list< Expression *> solved_assigns;
    203                         for ( ResolvExpr::Alternative & alt : *i ) {
    204                                 solved_assigns.push_back( alt.expr );
    205                         }
    206                         spotter.currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns), spotter.currentFinder.get_environ(), ResolvExpr::sumCost( *i ) ) );
    207                 }
     212                        ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( l ) );
     213                        out.push_back( createAssgn( ltmp, rtmp ) );
     214                        tmpDecls.push_back( ltmp );
     215                }
     216                tmpDecls.push_back( rtmp );
    208217        }
    209218
    210219        void TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
     220                static UniqueName lhsNamer( "__multassign_L" );
     221                static UniqueName rhsNamer( "__multassign_R" );
    211222                // xxx - need more complicated matching?
    212223                if ( lhs.size() == rhs.size() ) {
    213                         zipWith( lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), back_inserter(out), TupleAssignSpotter::Matcher::createAssgn );
    214                 }
    215         }
    216 
    217         void TupleAssignSpotter::MultipleAssignMatcher::solve() {
    218                 // options.print( std::cerr );
    219                 std::list< ResolvExpr::AltList > best = spotter.options.get_best();
    220                 if ( best.size() == 1 ) {
    221                         std::list<Expression *> solved_assigns;
    222                         for ( ResolvExpr::AltList::iterator i = best.front().begin(); i != best.front().end(); ++i ) {
    223                                 solved_assigns.push_back( i->expr );
    224                         }
    225                         /* assigning cost zero? */
    226                         spotter.currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns), spotter.currentFinder.get_environ(), ResolvExpr::Cost() ) );
    227                 }
    228         }
    229 
    230         std::list< ResolvExpr::AltList > TupleAssignSpotter::Options::get_best() {
    231                 std::list< ResolvExpr::AltList > ret;
    232                 std::list< ResolvExpr::AltList > solns;
    233                 for ( ResolvExpr::AltList & i : options ) {
    234                         ResolvExpr::AltList current;
    235                         findMinCost( i.begin(), i.end(), back_inserter(current) );
    236                         solns.push_back( ResolvExpr::AltList(current.begin(), current.end()) );
    237                 }
    238                 // need to combine -- previously "lift_intersection", which
    239                 // did some madness involving, effectively, the intersection of
    240                 // a bunch of AltLists
    241                 std::list<ResolvExpr::AltList> result = solns;
    242                 if ( result.size() != 1 ) {
    243                         throw SemanticError("Ambiguous tuple expression");
    244                 }
    245                 ret.push_back( *result.begin() );
    246                 return ret;
     224                        std::list< ObjectDecl * > ltmp;
     225                        std::list< ObjectDecl * > rtmp;
     226                        std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( Expression * expr ){
     227                                return newObject( lhsNamer, new AddressExpr( expr ) );
     228                        });
     229                        std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( Expression * expr ){
     230                                return newObject( rhsNamer, expr );
     231                        });
     232                        zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), createAssgn );
     233                        tmpDecls.splice( tmpDecls.end(), ltmp );
     234                        tmpDecls.splice( tmpDecls.end(), rtmp );
     235                }
    247236        }
    248237
Note: See TracChangeset for help on using the changeset viewer.