- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r3b58d91 rb6fe7e6 174 174 } 175 175 } 176 177 // flatten tuple type into list of types178 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 }188 176 } 189 177 … … 209 197 } 210 198 211 void AlternativeFinder::find( Expression *expr, bool adjust ) {199 void AlternativeFinder::find( Expression *expr, bool adjust, bool prune ) { 212 200 expr->accept( *this ); 213 201 if ( alternatives.empty() ) { … … 219 207 } 220 208 } 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 ) 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 } 241 231 242 232 // Central location to handle gcc extension keyword for all expression types. … … 246 236 } 247 237 248 void AlternativeFinder::findWithAdjustment( Expression *expr ) {249 find( expr, true );238 void AlternativeFinder::findWithAdjustment( Expression *expr, bool prune ) { 239 find( expr, true, prune ); 250 240 } 251 241 252 242 template< typename StructOrUnionType > 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 243 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) { 257 244 std::list< Declaration* > members; 258 245 aggInst->lookup( name, members ); … … 283 270 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 284 271 std::list< Expression* >& actuals = appExpr->get_args(); 285 286 std::list< Type * > formalTypes;287 std::list< Type * >::iterator formalType = formalTypes.end();288 289 272 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 290 291 273 PRINT( 292 274 std::cerr << "actual expression:" << std::endl; … … 297 279 std::list< DeclarationWithType* >::iterator startFormal = formal; 298 280 Cost actualCost; 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 } 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; 314 288 } 315 formalTypes.clear();316 flatten( (*formal)->get_type(), back_inserter( formalTypes ) );317 formalType = formalTypes.begin();318 ++formal;319 289 } 320 321 290 PRINT( 322 291 std::cerr << std::endl << "converting "; 323 (*actual Type)->print( std::cerr, 8 );292 (*actual)->print( std::cerr, 8 ); 324 293 std::cerr << std::endl << " to "; 325 294 (*formal)->get_type()->print( std::cerr, 8 ); 326 295 ) 327 Cost newCost = conversionCost( *actual Type, *formalType, indexer, alt.env );296 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env ); 328 297 PRINT( 329 298 std::cerr << std::endl << "cost is" << newCost << std::endl; … … 336 305 actualCost += newCost; 337 306 338 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );339 340 formal Type++;307 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 ); 308 309 formal++; 341 310 } 342 311 if ( actualCost != Cost( 0, 0, 0 ) ) { … … 413 382 */ 414 383 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 415 416 std::list< Type * > formalTypes;417 std::list< Type * >::iterator formalType = formalTypes.end();418 419 384 for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 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; 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; 434 388 } 435 389 PRINT( … … 437 391 (*formal)->get_type()->print( std::cerr ); 438 392 std::cerr << std::endl << "actual type is "; 439 (*actual Type)->print( std::cerr );393 (*actual)->print( std::cerr ); 440 394 std::cerr << std::endl; 441 395 ) 442 if ( ! unify( *formalType, *actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {396 if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 443 397 return false; 444 398 } 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 399 formal++; 400 } 401 } 453 402 // Handling of default values 454 403 while ( formal != formals.end() ) { … … 813 762 if ( agg->expr->get_results().size() == 1 ) { 814 763 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) { 815 addAggMembers( structInst, agg->expr, agg->cost, memberExpr->get_member() );764 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 816 765 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) { 817 addAggMembers( unionInst, agg->expr, agg->cost, memberExpr->get_member() );766 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 818 767 } // if 819 768 } // if … … 842 791 renameTypes( alternatives.back().expr ); 843 792 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) { 844 NameExpr nameExpr( "" ); 845 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), &nameExpr ); 793 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 846 794 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) { 847 NameExpr nameExpr( "" ); 848 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), &nameExpr ); 795 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 849 796 } // if 850 797 } // for … … 1067 1014 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) ); 1068 1015 } 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 type 1020 // (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 } 1069 1026 } // namespace ResolvExpr 1070 1027
Note:
See TracChangeset
for help on using the changeset viewer.