Changeset c43c171
- Timestamp:
- Oct 5, 2017, 3:55:26 PM (7 years ago)
- 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:
- b5a8ef7
- Parents:
- a585396
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
ra585396 rc43c171 887 887 // take care of possible tuple assignments 888 888 // 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 891 891 // find function operators 892 892 AlternativeFinder funcOpFinder( indexer, env ); -
src/Tuples/Explode.h
ra585396 rc43c171 30 30 Expression * distributeReference( Expression * ); 31 31 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 32 41 /// helper function used by explode 33 42 template< typename OutputIterator > … … 35 44 if ( isTupleAssign ) { 36 45 // 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 ) ) { 38 47 ResolvExpr::AltList alts; 39 48 explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); -
src/Tuples/TupleAssignment.cc
ra585396 rc43c171 20 20 #include <memory> // for unique_ptr, allocator_trai... 21 21 #include <string> // for string 22 #include <vector> 22 23 23 24 #include "CodeGen/OperatorTable.h" … … 33 34 #include "ResolvExpr/Resolver.h" // for resolveCtorInit 34 35 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 36 #include "ResolvExpr/typeops.h" // for combos 35 37 #include "SynTree/Declaration.h" // for ObjectDecl 36 38 #include "SynTree/Expression.h" // for Expression, CastExpr, Name... … … 46 48 // dispatcher for Tuple (multiple and mass) assignment operations 47 49 TupleAssignSpotter( ResolvExpr::AlternativeFinder & ); 48 void spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities );50 void spot( UntypedExpr * expr, std::vector<ResolvExpr::AlternativeFinder> &args ); 49 51 50 52 private: … … 53 55 struct Matcher { 54 56 public: 55 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ); 57 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const 58 ResolvExpr::AltList& rhs ); 56 59 virtual ~Matcher() {} 57 60 virtual void match( std::list< Expression * > &out ) = 0; … … 66 69 struct MassAssignMatcher : public Matcher { 67 70 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) {} 69 73 virtual void match( std::list< Expression * > &out ); 70 74 }; … … 72 76 struct MultipleAssignMatcher : public Matcher { 73 77 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) {} 75 80 virtual void match( std::list< Expression * > &out ); 76 81 }; … … 108 113 } 109 114 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 ) { 111 117 TupleAssignSpotter spotter( currentFinder ); 112 spotter.spot( expr, possibilities );118 spotter.spot( expr, args ); 113 119 } 114 120 … … 116 122 : currentFinder(f) {} 117 123 118 void TupleAssignSpotter::spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) { 124 void TupleAssignSpotter::spot( UntypedExpr * expr, 125 std::vector<ResolvExpr::AlternativeFinder> &args ) { 119 126 if ( NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) { 120 127 if ( CodeGen::isCtorDtorAssign( op->get_name() ) ) { 121 128 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() ) ); 127 150 } 128 151 129 assert( ! ali->empty() );130 // grab args 2-N and group into a TupleExpr131 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 assignment138 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() ) ); 139 162 } 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 } 141 194 } 142 195 } … … 183 236 } 184 237 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 ) ) {} 218 242 219 243 UntypedExpr * createFunc( const std::string &fname, ObjectDecl *left, ObjectDecl *right ) { -
src/Tuples/Tuples.h
ra585396 rc43c171 17 17 18 18 #include <string> 19 #include <vector> 19 20 20 21 #include "SynTree/Expression.h" … … 26 27 namespace Tuples { 27 28 // 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 30 32 // TupleExpansion.cc 31 33 /// 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.