Changeset 4c8621ac for src/Tuples/TupleAssignment.cc
- Timestamp:
- Dec 22, 2016, 4:07:58 PM (8 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:
- 1e3d5b6
- Parents:
- 907eccb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/TupleAssignment.cc
r907eccb r4c8621ac 42 42 private: 43 43 void match(); 44 void handleEmptyTuple( const ResolvExpr::AltList & alts ); 44 45 45 46 struct Matcher { … … 130 131 } 131 132 match(); 133 } else { 134 // handle empty case specially. It is easy to cause conflicts for tuple assignment when we consider any expression with Tuple type to be a tuple. 135 // Instead, only tuple expressions and expressions with at least 2 results are considered tuples for tuple assignment. This most obviously leaves out the 136 // nullary and unary cases. The unary case is handled nicely by the alternative finder as is. For example, an expression of type [int] will be exploded 137 // into a list of one element (combined with the RHS elements), which will easily allow for intrinsic construction. This seems like a best case scenario anyway, 138 // since intrinsic construction is much simpler from a code-gen perspective than tuple construction is. 139 // This leaves the empty case, which is not easily handled by existing alternative finder logic. Instead, it seems simple enough to hanlde here that if the left 140 // side is an empty tuple, then the right side is allowed to be either an empty tuple or an empty list. Fortunately, these cases are identical when exploded. 141 handleEmptyTuple( *ali ); 132 142 } 133 143 } … … 248 258 static UniqueName lhsNamer( "__massassign_L" ); 249 259 static UniqueName rhsNamer( "__massassign_R" ); 250 assert ( ! lhs.empty() && rhs.size() <= 1);260 assert( ! lhs.empty() && rhs.size() <= 1 ); 251 261 252 262 ObjectDecl * rtmp = rhs.size() == 1 ? newObject( rhsNamer, rhs.front().expr ) : nullptr; … … 278 288 } 279 289 } 290 291 // empty case is okay when right side is also "empty" (empty explosion handles no argument case as well as empty tuple case) 292 void TupleAssignSpotter::handleEmptyTuple( const ResolvExpr::AltList & alts ) { 293 assert( ! alts.empty() ); 294 Expression * lhs = alts.front().expr; 295 if ( PointerType * ptrType = dynamic_cast< PointerType * >( lhs->get_result() ) ) { 296 if ( TupleType * tupleType = dynamic_cast< TupleType * >( ptrType->get_base() ) ) { 297 if ( tupleType->size() == 0 ) { 298 ResolvExpr::AltList rhs; 299 explode( std::next(alts.begin(), 1), alts.end(), currentFinder.get_indexer(), back_inserter(rhs) ); 300 if ( rhs.empty() ) { 301 // okay, no other case is allowed 302 ResolvExpr::TypeEnvironment compositeEnv; 303 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 304 currentFinder.get_alternatives().push_front( ResolvExpr::Alternative( new TupleAssignExpr( std::list< Expression * >(), std::list< ObjectDecl * >() ), compositeEnv, ResolvExpr::sumCost( alts ) ) ); 305 } 306 } 307 } 308 } 309 } 280 310 } // namespace Tuples 281 311
Note: See TracChangeset
for help on using the changeset viewer.