- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rb6fe7e6 r3b58d91 174 174 } 175 175 } 176 177 // flatten tuple type into list of types 178 template< typename OutputIterator > 179 void flatten( Type * type, OutputIterator out ) { 180 if ( TupleType * tupleType = dynamic_cast< TupleType * >( type ) ) { 181 for ( Type * t : *tupleType ) { 182 flatten( t, out ); 183 } 184 } else { 185 *out++ = type; 186 } 187 } 176 188 } 177 189 … … 197 209 } 198 210 199 void AlternativeFinder::find( Expression *expr, bool adjust , bool prune) {211 void AlternativeFinder::find( Expression *expr, bool adjust ) { 200 212 expr->accept( *this ); 201 213 if ( alternatives.empty() ) { … … 207 219 } 208 220 } 209 if ( prune ) { 210 PRINT( 211 std::cerr << "alternatives before prune:" << std::endl; 212 printAlts( alternatives, std::cerr ); 213 ) 214 AltList::iterator oldBegin = alternatives.begin(); 215 pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer ); 216 if ( alternatives.begin() == oldBegin ) { 217 std::ostringstream stream; 218 stream << "Can't choose between alternatives for expression "; 219 expr->print( stream ); 220 stream << "Alternatives are:"; 221 AltList winners; 222 findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) ); 223 printAlts( winners, stream, 8 ); 224 throw SemanticError( stream.str() ); 225 } 226 alternatives.erase( oldBegin, alternatives.end() ); 227 PRINT( 228 std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl; 229 ) 230 } 221 PRINT( 222 std::cerr << "alternatives before prune:" << std::endl; 223 printAlts( alternatives, std::cerr ); 224 ) 225 AltList::iterator oldBegin = alternatives.begin(); 226 pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer ); 227 if ( alternatives.begin() == oldBegin ) { 228 std::ostringstream stream; 229 stream << "Can't choose between alternatives for expression "; 230 expr->print( stream ); 231 stream << "Alternatives are:"; 232 AltList winners; 233 findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) ); 234 printAlts( winners, stream, 8 ); 235 throw SemanticError( stream.str() ); 236 } 237 alternatives.erase( oldBegin, alternatives.end() ); 238 PRINT( 239 std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl; 240 ) 231 241 232 242 // Central location to handle gcc extension keyword for all expression types. … … 236 246 } 237 247 238 void AlternativeFinder::findWithAdjustment( Expression *expr , bool prune) {239 find( expr, true , prune);248 void AlternativeFinder::findWithAdjustment( Expression *expr ) { 249 find( expr, true ); 240 250 } 241 251 242 252 template< typename StructOrUnionType > 243 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) { 253 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, Expression * member ) { 254 NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member ); 255 const std::string & name = nameExpr->get_name(); 256 244 257 std::list< Declaration* > members; 245 258 aggInst->lookup( name, members ); … … 270 283 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 271 284 std::list< Expression* >& actuals = appExpr->get_args(); 285 286 std::list< Type * > formalTypes; 287 std::list< Type * >::iterator formalType = formalTypes.end(); 288 272 289 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 290 273 291 PRINT( 274 292 std::cerr << "actual expression:" << std::endl; … … 279 297 std::list< DeclarationWithType* >::iterator startFormal = formal; 280 298 Cost actualCost; 281 for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) { 282 if ( formal == formals.end() ) { 283 if ( function->get_isVarArgs() ) { 284 convCost += Cost( 1, 0, 0 ); 285 break; 286 } else { 287 return Cost::infinity; 299 for ( std::list< Type* >::iterator actualType = (*actualExpr)->get_results().begin(); actualType != (*actualExpr)->get_results().end(); ++actualType ) { 300 301 // tuple handling code 302 if ( formalType == formalTypes.end() ) { 303 // the type of the formal parameter may be a tuple type. To make this easier to work with, 304 // flatten the tuple type and traverse the resulting list of types, incrementing the formal 305 // iterator once its types have been extracted. Once a particular formal parameter's type has 306 // been exhausted load the next formal parameter's type. 307 if ( formal == formals.end() ) { 308 if ( function->get_isVarArgs() ) { 309 convCost += Cost( 1, 0, 0 ); 310 break; 311 } else { 312 return Cost::infinity; 313 } 288 314 } 315 formalTypes.clear(); 316 flatten( (*formal)->get_type(), back_inserter( formalTypes ) ); 317 formalType = formalTypes.begin(); 318 ++formal; 289 319 } 320 290 321 PRINT( 291 322 std::cerr << std::endl << "converting "; 292 (*actual )->print( std::cerr, 8 );323 (*actualType)->print( std::cerr, 8 ); 293 324 std::cerr << std::endl << " to "; 294 325 (*formal)->get_type()->print( std::cerr, 8 ); 295 326 ) 296 Cost newCost = conversionCost( *actual , (*formal)->get_type(), indexer, alt.env );327 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env ); 297 328 PRINT( 298 329 std::cerr << std::endl << "cost is" << newCost << std::endl; … … 305 336 actualCost += newCost; 306 337 307 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );308 309 formal ++;338 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 ); 339 340 formalType++; 310 341 } 311 342 if ( actualCost != Cost( 0, 0, 0 ) ) { … … 382 413 */ 383 414 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 415 416 std::list< Type * > formalTypes; 417 std::list< Type * >::iterator formalType = formalTypes.end(); 418 384 419 for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 385 for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) { 386 if ( formal == formals.end() ) { 387 return isVarArgs; 420 std::list< Type* > & actualTypes = actualExpr->expr->get_results(); 421 for ( std::list< Type* >::iterator actualType = actualTypes.begin(); actualType != actualTypes.end(); ++actualType ) { 422 if ( formalType == formalTypes.end() ) { 423 // the type of the formal parameter may be a tuple type. To make this easier to work with, 424 // flatten the tuple type and traverse the resulting list of types, incrementing the formal 425 // iterator once its types have been extracted. Once a particular formal parameter's type has 426 // been exhausted load the next formal parameter's type. 427 if ( formal == formals.end() ) { 428 return isVarArgs; 429 } 430 formalTypes.clear(); 431 flatten( (*formal)->get_type(), back_inserter( formalTypes ) ); 432 formalType = formalTypes.begin(); 433 ++formal; 388 434 } 389 435 PRINT( … … 391 437 (*formal)->get_type()->print( std::cerr ); 392 438 std::cerr << std::endl << "actual type is "; 393 (*actual )->print( std::cerr );439 (*actualType)->print( std::cerr ); 394 440 std::cerr << std::endl; 395 441 ) 396 if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {442 if ( ! unify( *formalType, *actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 397 443 return false; 398 444 } 399 formal++; 400 } 401 } 445 ++formalType; 446 } 447 } 448 449 // xxx - a tuple type was not completely matched 450 // partially handle the tuple with default arguments?? 451 if ( formalType != formalTypes.end() ) return false; 452 402 453 // Handling of default values 403 454 while ( formal != formals.end() ) { … … 762 813 if ( agg->expr->get_results().size() == 1 ) { 763 814 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) { 764 addAggMembers( structInst, agg->expr, agg->cost, agg->env,memberExpr->get_member() );815 addAggMembers( structInst, agg->expr, agg->cost, memberExpr->get_member() ); 765 816 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) { 766 addAggMembers( unionInst, agg->expr, agg->cost, agg->env,memberExpr->get_member() );817 addAggMembers( unionInst, agg->expr, agg->cost, memberExpr->get_member() ); 767 818 } // if 768 819 } // if … … 791 842 renameTypes( alternatives.back().expr ); 792 843 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) { 793 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 844 NameExpr nameExpr( "" ); 845 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), &nameExpr ); 794 846 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) { 795 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 847 NameExpr nameExpr( "" ); 848 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), &nameExpr ); 796 849 } // if 797 850 } // for … … 1014 1067 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) ); 1015 1068 } 1016 1017 void AlternativeFinder::visit( ConstructorExpr * ctorExpr ) {1018 AlternativeFinder finder( indexer, env );1019 // don't prune here, since it's guaranteed all alternatives will have the same type1020 // (giving the alternatives different types is half of the point of ConstructorExpr nodes)1021 finder.findWithAdjustment( ctorExpr->get_callExpr(), false );1022 for ( Alternative & alt : finder.alternatives ) {1023 alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) );1024 }1025 }1026 1069 } // namespace ResolvExpr 1027 1070
Note:
See TracChangeset
for help on using the changeset viewer.