Changeset 53e3b4a for src/ResolvExpr/AlternativeFinder.cc
- Timestamp:
- Dec 21, 2016, 5:13:15 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:
- 64eae56
- Parents:
- b940dc71
- git-author:
- Rob Schluntz <rschlunt@…> (12/21/16 16:32:57)
- git-committer:
- Rob Schluntz <rschlunt@…> (12/21/16 17:13:15)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rb940dc71 r53e3b4a 267 267 std::list< Expression* >& actuals = appExpr->get_args(); 268 268 269 std::list< Type * > formalTypes;270 std::list< Type * >::iterator formalType = formalTypes.end();271 272 269 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 273 270 Type * actualType = (*actualExpr)->get_result(); 274 271 PRINT( 275 272 std::cerr << "actual expression:" << std::endl; 276 273 (*actualExpr)->print( std::cerr, 8 ); 277 274 std::cerr << "--- results are" << std::endl; 278 (*actualExpr)->get_result()->print( std::cerr, 8 ); 279 ) 280 std::list< DeclarationWithType* >::iterator startFormal = formal; 275 actualType->print( std::cerr, 8 ); 276 ) 281 277 Cost actualCost; 282 std::list< Type * > flatActualTypes; 283 flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) ); 284 for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) { 285 286 287 // tuple handling code 288 if ( formalType == formalTypes.end() ) { 289 // the type of the formal parameter may be a tuple type. To make this easier to work with, 290 // flatten the tuple type and traverse the resulting list of types, incrementing the formal 291 // iterator once its types have been extracted. Once a particular formal parameter's type has 292 // been exhausted load the next formal parameter's type. 293 if ( formal == formals.end() ) { 294 if ( function->get_isVarArgs() ) { 295 convCost += Cost( 1, 0, 0 ); 296 break; 297 } else { 298 return Cost::infinity; 299 } 300 } 301 formalTypes.clear(); 302 flatten( (*formal)->get_type(), back_inserter( formalTypes ) ); 303 formalType = formalTypes.begin(); 304 ++formal; 278 if ( formal == formals.end() ) { 279 if ( function->get_isVarArgs() ) { 280 convCost += Cost( 1, 0, 0 ); 281 continue; 282 } else { 283 return Cost::infinity; 305 284 } 306 307 PRINT( 308 std::cerr << std::endl << "converting "; 309 (*actualType)->print( std::cerr, 8 ); 310 std::cerr << std::endl << " to "; 311 (*formalType)->print( std::cerr, 8 ); 312 ) 313 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env ); 314 PRINT( 315 std::cerr << std::endl << "cost is" << newCost << std::endl; 316 ) 317 318 if ( newCost == Cost::infinity ) { 319 return newCost; 320 } 321 convCost += newCost; 322 actualCost += newCost; 323 324 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 ); 325 326 formalType++; 327 } 285 } 286 Type * formalType = (*formal)->get_type(); 287 PRINT( 288 std::cerr << std::endl << "converting "; 289 actualType->print( std::cerr, 8 ); 290 std::cerr << std::endl << " to "; 291 formalType->print( std::cerr, 8 ); 292 ) 293 Cost newCost = conversionCost( actualType, formalType, indexer, alt.env ); 294 PRINT( 295 std::cerr << std::endl << "cost is" << newCost << std::endl; 296 ) 297 298 if ( newCost == Cost::infinity ) { 299 return newCost; 300 } 301 convCost += newCost; 302 actualCost += newCost; 328 303 if ( actualCost != Cost( 0, 0, 0 ) ) { 329 std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal; 330 startFormalPlusOne++; 331 if ( formal == startFormalPlusOne ) { 332 // not a tuple type 333 Type *newType = (*startFormal)->get_type()->clone(); 334 alt.env.apply( newType ); 335 *actualExpr = new CastExpr( *actualExpr, newType ); 336 } else { 337 TupleType *newType = new TupleType( Type::Qualifiers() ); 338 for ( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) { 339 newType->get_types().push_back( (*i)->get_type()->clone() ); 340 } 341 alt.env.apply( newType ); 342 *actualExpr = new CastExpr( *actualExpr, newType ); 343 } 344 } 345 304 Type *newType = formalType->clone(); 305 alt.env.apply( newType ); 306 *actualExpr = new CastExpr( *actualExpr, newType ); 307 } 308 convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 ); 309 ++formal; // can't be in for-loop update because of the continue 346 310 } 347 311 if ( formal != formals.end() ) { … … 364 328 } 365 329 convCost += newCost; 366 367 330 convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 ); 368 331 } … … 398 361 *out++ = tupleExpr; 399 362 } else if ( actualIt != actualEnd ) { 363 if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) { 364 // xxx - mixing default arguments with variadic?? 365 if ( ! Tuples::isTtype( actualIt->expr->get_result() ) ) { 366 // xxx - what if passing multiple arguments, last of which is ttype? 367 368 // consume all remaining arguments, variadic style 369 std::list< Expression * > exprs; 370 for ( ; actualIt != actualEnd; ++actualIt ) { 371 exprs.push_back( actualIt->expr->clone() ); 372 cost += actualIt->cost; 373 } 374 TupleExpr * arg = new TupleExpr( exprs ); 375 assert( arg->get_result() ); 376 // unification run for side effects 377 bool unifyResult = unify( ttype, arg->get_result(), resultEnv, resultNeed, resultHave, openVars, indexer ); 378 assertf( unifyResult, "Somehow unifying ttype failed..." ); 379 *out++ = arg; 380 return true; 381 } 382 } 400 383 // both actualType and formalType are atomic (non-tuple) types - if they unify 401 384 // then accept actual as an argument, otherwise return false (fail to instantiate argument) … … 609 592 makeUnifiableVars( funcType, openVars, resultNeed ); 610 593 AltList instantiatedActuals; // filled by instantiate function 611 if ( targetType && ! targetType->isVoid() ) {594 if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) { 612 595 // attempt to narrow based on expected target type 613 596 Type * returnType = funcType->get_returnVals().front()->get_type();
Note: See TracChangeset
for help on using the changeset viewer.