Changeset 3c13c03 for src/Tuples


Ignore:
Timestamp:
Sep 17, 2016, 8:27:51 AM (7 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:
8c49c0e
Parents:
12bc63a
Message:

expand TupleExpr? and TupleIndexExpr?, add UniqueExpr?

Location:
src/Tuples
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleAssignment.cc

    r12bc63a r3c13c03  
    3939          private:
    4040                void match();
    41                 // records for assignment generation
    42                 struct Options {
    43                         void print( std::ostream & );
    44                         int size() const { return options.size(); }
    45                         bool empty() const { return options.empty(); }
    46                         typedef std::list< ResolvExpr::AltList >::iterator iterator;
    47                         iterator begin() { return options.begin(); }
    48                         iterator end() { return options.end(); }
    49 
    50                         std::list< ResolvExpr::AltList > options;
    51                 };
    5241
    5342                struct Matcher {
    5443                  public:
    55                         Matcher( TupleAssignSpotter &spotter, Expression *_lhs, Expression *_rhs );
     44                        Matcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs );
    5645                        virtual ~Matcher() {}
    5746                        virtual void match( std::list< Expression * > &out ) = 0;
    58                         std::list< Expression * > lhs, rhs;
     47                        ResolvExpr::AltList lhs, rhs;
    5948                        TupleAssignSpotter &spotter;
    6049                        std::list< ObjectDecl * > tmpDecls;
     
    6352                struct MassAssignMatcher : public Matcher {
    6453                  public:
    65                         MassAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) {
    66                                 this->rhs.push_back( rhs );
    67                         }
     54                        MassAssignMatcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs );
    6855                        virtual void match( std::list< Expression * > &out );
    6956                };
     
    7158                struct MultipleAssignMatcher : public Matcher {
    7259                  public:
    73                         MultipleAssignMatcher( TupleAssignSpotter &spot, Expression *lhs, Expression *rhs );
     60                        MultipleAssignMatcher( TupleAssignSpotter &spot, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs );
    7461                        virtual void match( std::list< Expression * > &out );
    7562                };
     
    7865                // Expression *rhs, *lhs;
    7966                Matcher *matcher = nullptr;
    80                 Options options;
    8167        };
    82 
    83         bool isTupleVar( DeclarationWithType *decl ) {
    84                 return dynamic_cast< TupleType * >( decl->get_type() );
    85         }
    8668
    8769        /// true if expr is an expression of tuple type, i.e. a tuple expression, tuple variable, or MRV (multiple-return-value) function
     
    8971                if ( ! expr ) return false;
    9072                assert( expr->has_result() );
    91                 // xxx - used to include cast to varExpr and call to isTupleVar, but this doesn't seem like it should be necessary
    9273                return dynamic_cast<TupleExpr *>(expr) || expr->get_result()->size() > 1;
    9374        }
     
    10182        }
    10283
    103         bool isTupleExpr( Expression *expr ) {
    104                 assert( expr->has_result() );
    105                 return expr->get_result()->size() > 1;
    106         }
    107 
    10884        void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
    10985                TupleAssignSpotter spotter( currentFinder );
     
    11692        void TupleAssignSpotter::spot( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
    11793                if (  NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) {
    118                         if ( assgnop->get_name() == std::string("?=?") ) {
     94                        if ( assgnop->get_name() == "?=?" ) {
    11995                                for ( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
    120                                         assert( ali->size() == 2 );
    121                                         ResolvExpr::Alternative op1 = ali->front(), op2 = ali->back();
    122 
    123                                         MultipleAssignMatcher multiMatcher( *this, op1.expr, op2.expr );
    124                                         MassAssignMatcher massMatcher( *this, op1.expr, op2.expr );
    125                                         if ( pointsToTuple(op1.expr) ) { // also handles tuple vars
    126                                                 if ( isTuple( op2.expr ) ) {
     96                                        if ( ali->size() != 2 ) continue; // what does it mean if an assignment takes >2 arguments? grab args 2-N and group into a TupleExpr, then proceed?
     97                                        ResolvExpr::Alternative & alt1 = ali->front(), & alt2 = ali->back();
     98
     99                                        if ( pointsToTuple(alt1.expr) ) {
     100                                                MultipleAssignMatcher multiMatcher( *this, alt1, alt2 );
     101                                                MassAssignMatcher massMatcher( *this,  alt1, alt2 );
     102                                                if ( isTuple( alt2.expr ) ) {
    127103                                                        matcher = &multiMatcher;
    128104                                                } else {
     
    131107                                                }
    132108                                                match();
    133                                         } else if ( isTuple( op2.expr ) ) {
     109                                        } else if ( isTuple( alt2.expr ) ) {
    134110                                                throw SemanticError("Cannot assign a tuple value into a non-tuple lvalue.", expr);
    135111                                        }
     
    170146        }
    171147
    172         TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : spotter(spotter) {
    173                 // xxx - shouldn't need to be &<tuple-expr>, just &<lvalue-tuple-type>
    174                 if (AddressExpr *addr = dynamic_cast<AddressExpr *>(lhs) )
    175                         if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) )
    176                                 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->lhs) );
    177         }
    178 
    179         TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) {
    180 
    181                 if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(rhs) )
    182                         std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->rhs) );
     148        TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ) : spotter(spotter) {
     149                if (AddressExpr *addr = dynamic_cast<AddressExpr *>(lhs.expr) ) {
     150                        // xxx - not every assignment NEEDS to have the first argument as address-taken, e.g. a manual call to assignment. What to do in this case? skip it as a possibility for TupleAssignment, since the type will always be T*, where T can never be a tuple? Is this true?
     151
     152                        // explode the lhs so that each field of the tuple-valued-expr is assigned.
     153                        ResolvExpr::Alternative lhsAlt( addr->get_arg()->clone(), lhs.env, lhs.cost, lhs.cvtCost );
     154                        explode( lhsAlt, back_inserter(this->lhs) );
     155                }
     156        }
     157
     158        TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ) : Matcher( spotter, lhs, rhs ) {
     159                this->rhs.push_back( rhs );
     160        }
     161
     162        TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ) : Matcher( spotter, lhs, rhs ) {
     163
     164                // explode the rhs so that each field of the tuple-valued-expr is assigned.
     165                explode( rhs, back_inserter(this->rhs) );
    183166        }
    184167
     
    201184                assert ( ! lhs.empty() && rhs.size() == 1);
    202185
    203                 ObjectDecl * rtmp = newObject( rhsNamer, rhs.front() );
    204                 for ( Expression * l : lhs ) {
    205                         ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( l ) );
     186                ObjectDecl * rtmp = newObject( rhsNamer, rhs.front().expr );
     187                for ( ResolvExpr::Alternative & lhsAlt : lhs ) {
     188                        ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( lhsAlt.expr ) );
    206189                        out.push_back( createAssgn( ltmp, rtmp ) );
    207190                        tmpDecls.push_back( ltmp );
     
    217200                        std::list< ObjectDecl * > ltmp;
    218201                        std::list< ObjectDecl * > rtmp;
    219                         std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( Expression * expr ){
    220                                 return newObject( lhsNamer, new AddressExpr( expr ) );
     202                        std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( ResolvExpr::Alternative & alt ){
     203                                return newObject( lhsNamer, new AddressExpr( alt.expr ) );
    221204                        });
    222                         std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( Expression * expr ){
    223                                 return newObject( rhsNamer, expr );
     205                        std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( ResolvExpr::Alternative & alt ){
     206                                return newObject( rhsNamer, alt.expr );
    224207                        });
    225208                        zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), createAssgn );
     
    227210                        tmpDecls.splice( tmpDecls.end(), rtmp );
    228211                }
    229         }
    230 
    231         void TupleAssignSpotter::Options::print( std::ostream &ostr ) {
    232                 for ( ResolvExpr::AltList & l : options ) {
    233                         for ( ResolvExpr::Alternative & alt : l ) {
    234                                 alt.print( ostr );
    235                                 ostr << " ";
    236                         }
    237                         ostr << std::endl;
    238                 } // for
    239212        }
    240213} // namespace Tuples
  • src/Tuples/TupleExpansion.cc

    r12bc63a r3c13c03  
    2323#include "SynTree/Declaration.h"
    2424#include "SynTree/Type.h"
     25#include "SynTree/Expression.h"
     26#include "SynTree/Initializer.h"
    2527#include "SymTab/Mangler.h"
    2628#include "Common/ScopedMap.h"
    2729
    2830namespace Tuples {
    29         class TupleAssignExpander : public Mutator {
    30         public:
    31                 virtual Expression * mutate( TupleAssignExpr * tupleExpr );
    32         };
     31        namespace {
     32                class UniqueExprExpander : public GenPoly::DeclMutator {
     33                public:
     34                        typedef GenPoly::DeclMutator Parent;
     35                        virtual Expression * mutate( UniqueExpr * unqExpr );
     36                        std::map< Expression *, ObjectDecl * > decls;
     37                };
    3338
    34         class TupleTypeReplacer : public GenPoly::DeclMutator {
    35           public:
    36                 typedef GenPoly::DeclMutator Parent;
     39                class TupleAssignExpander : public Mutator {
     40                public:
     41                        typedef Mutator Parent;
     42                        virtual Expression * mutate( TupleAssignExpr * tupleExpr );
     43                };
    3744
    38                 virtual Type * mutate( TupleType * tupleType );
     45                class TupleTypeReplacer : public GenPoly::DeclMutator {
     46                  public:
     47                        typedef GenPoly::DeclMutator Parent;
    3948
    40                 virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
    41                         typeMap.beginScope();
    42                         stmt = Parent::mutate( stmt );
    43                         typeMap.endScope();
    44                         return stmt;
    45                 }
    46           private:
    47                 ScopedMap< std::string, StructDecl * > typeMap;
    48         };
     49                        virtual Type * mutate( TupleType * tupleType );
     50
     51                        virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
     52                                typeMap.beginScope();
     53                                stmt = Parent::mutate( stmt );
     54                                typeMap.endScope();
     55                                return stmt;
     56                        }
     57                  private:
     58                        ScopedMap< std::string, StructDecl * > typeMap;
     59                };
     60
     61                class TupleIndexExpander : public Mutator {
     62                public:
     63                        typedef Mutator Parent;
     64                        virtual Expression * mutate( TupleIndexExpr * tupleExpr );
     65                };
     66
     67                class TupleExprExpander : public Mutator {
     68                public:
     69                        typedef Mutator Parent;
     70                        virtual Expression * mutate( TupleExpr * tupleExpr );
     71                };
     72        }
    4973
    5074        void expandTuples( std::list< Declaration * > & translationUnit ) {
    51                 TupleAssignExpander expander;
    52                 mutateAll( translationUnit, expander );
     75                UniqueExprExpander unqExpander;
     76                unqExpander.mutateDeclarationList( translationUnit );
     77
     78                TupleAssignExpander assnExpander;
     79                mutateAll( translationUnit, assnExpander );
    5380
    5481                TupleTypeReplacer replacer;
    5582                replacer.mutateDeclarationList( translationUnit );
     83
     84                TupleIndexExpander idxExpander;
     85                mutateAll( translationUnit, idxExpander );
     86
     87                TupleExprExpander exprExpander;
     88                mutateAll( translationUnit, exprExpander );
    5689        }
    5790
    58         Expression * TupleAssignExpander::mutate( TupleAssignExpr * tupleExpr ) {
     91        Expression * UniqueExprExpander::mutate( UniqueExpr * unqExpr ) {
     92                static UniqueName tempNamer( "_unq_expr_" );
     93                unqExpr = safe_dynamic_cast< UniqueExpr * > ( Parent::mutate( unqExpr ) );
     94                if ( ! decls.count( unqExpr->get_expr() ) ) {
     95                        // xxx - it's possible (likely?) that expressions can appear in the wrong order because of this. Need to ensure they're placed in the correct location.
     96                        ObjectDecl * decl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), new SingleInit( unqExpr->get_expr()->clone() ) );
     97                        decls[unqExpr->get_expr()] = decl;
     98                        addDeclaration( decl );
     99                }
     100                return new VariableExpr( decls[unqExpr->get_expr()] );
     101        }
     102
     103        Expression * TupleAssignExpander::mutate( TupleAssignExpr * assnExpr ) {
     104                // xxx - Parent::mutate?
    59105                CompoundStmt * compoundStmt = new CompoundStmt( noLabels );
    60106                std::list< Statement * > & stmts = compoundStmt->get_kids();
    61                 for ( ObjectDecl * obj : tupleExpr->get_tempDecls() ) {
     107                for ( ObjectDecl * obj : assnExpr->get_tempDecls() ) {
    62108                        stmts.push_back( new DeclStmt( noLabels, obj ) );
    63109                }
    64                 for ( Expression * assign : tupleExpr->get_assigns() ) {
    65                         stmts.push_back( new ExprStmt( noLabels, assign ) );
    66                 }
    67                 tupleExpr->get_tempDecls().clear();
    68                 tupleExpr->get_assigns().clear();
    69                 delete tupleExpr;
     110                TupleExpr * tupleExpr = new TupleExpr( assnExpr->get_assigns() );
     111                assert( tupleExpr->get_result() );
     112                stmts.push_back( new ExprStmt( noLabels, tupleExpr ) );
     113                assnExpr->get_tempDecls().clear();
     114                assnExpr->get_assigns().clear();
     115                delete assnExpr;
    70116                return new StmtExpr( compoundStmt );
    71117        }
     
    90136        }
    91137
     138        Expression * TupleIndexExpander::mutate( TupleIndexExpr * tupleExpr ) {
     139                Expression * tuple = maybeMutate( tupleExpr->get_tuple(), *this );
     140                assert( tuple );
     141                tupleExpr->set_tuple( nullptr );
     142                unsigned int idx = tupleExpr->get_index();
     143                delete tupleExpr;
     144
     145                StructInstType * type = safe_dynamic_cast< StructInstType * >( tuple->get_result() );
     146                StructDecl * structDecl = type->get_baseStruct();
     147                assert( structDecl->get_members().size() > idx );
     148                Declaration * member = *std::next(structDecl->get_members().begin(), idx);
     149                return new MemberExpr( safe_dynamic_cast< DeclarationWithType * >( member ), tuple );
     150        }
     151
     152        Expression * TupleExprExpander::mutate( TupleExpr * tupleExpr ) {
     153                assert( tupleExpr->get_result() );
     154                std::list< Initializer * > inits;
     155                for ( Expression * expr : tupleExpr->get_exprs() ) {
     156                        inits.push_back( new SingleInit( expr ) );
     157                }
     158                return new CompoundLiteralExpr( tupleExpr->get_result(), new ListInit( inits ) );
     159        }
     160
     161        TupleType * makeTupleType( const std::list< Expression * > & exprs ) {
     162                TupleType *tupleType = new TupleType( Type::Qualifiers(true, true, true, true, true, false) );
     163                Type::Qualifiers &qualifiers = tupleType->get_qualifiers();
     164                for ( Expression * expr : exprs ) {
     165                        assert( expr->get_result() );
     166                        Type * type = expr->get_result()->clone();
     167                        tupleType->get_types().push_back( type );
     168                        qualifiers &= type->get_qualifiers();
     169                } // for
     170                return tupleType;
     171        }
    92172} // namespace Tuples
    93173
  • src/Tuples/Tuples.h

    r12bc63a r3c13c03  
    3131        // TupleExpansion.cc
    3232        void expandTuples( std::list< Declaration * > & translationUnit );
     33
     34  TupleType * makeTupleType( const std::list< Expression * > & exprs );
    3335} // namespace Tuples
    3436
Note: See TracChangeset for help on using the changeset viewer.