- 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)
- Location:
- src/ResolvExpr
- Files:
-
- 2 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(); -
src/ResolvExpr/Unify.cc
rb940dc71 r53e3b4a 26 26 #include "SymTab/Indexer.h" 27 27 #include "Common/utility.h" 28 28 #include "Tuples/Tuples.h" 29 29 30 30 // #define DEBUG … … 160 160 case TypeDecl::Ftype: 161 161 return isFtype( type, indexer ); 162 case TypeDecl::Ttype: 163 // ttype eats up any remaining parameters, no matter the type 164 return true; 162 165 } // switch 163 assert( false );164 166 return false; 165 167 } … … 485 487 } 486 488 489 template< typename Iterator > 490 Type * combineTypes( Iterator begin, Iterator end ) { 491 std::list< Type * > types; 492 for ( ; begin != end; ++begin ) { 493 // might need to break apart these types too? 494 // yes, looks like we should flatten begin and push back each types individually 495 types.push_back( (*begin)->get_type()->clone() ); 496 } 497 return new TupleType( Type::Qualifiers(), types ); 498 } 499 487 500 template< typename Iterator1, typename Iterator2 > 488 501 bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 489 502 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 490 // Type * commonType; 491 // if ( ! unifyInexact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) { 492 if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 503 Type * t1 = (*list1Begin)->get_type(); 504 Type * t2 = (*list2Begin)->get_type(); 505 bool isTtype1 = Tuples::isTtype( t1 ); 506 bool isTtype2 = Tuples::isTtype( t2 ); 507 // xxx - assumes ttype must be last parameter; needs cleanup; use unique_ptr for combinedType 508 if ( isTtype1 && ! isTtype2 ) { 509 // combine all of the things in list2, then unify 510 Type * combinedType = combineTypes( list2Begin, list2End ); 511 return unifyExact( t1, combinedType, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 512 } else if ( isTtype2 && ! isTtype1 ) { 513 // combine all of the things in list1, then unify 514 Type * combinedType = combineTypes( list1Begin, list1End ); 515 return unifyExact( combinedType, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 516 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 493 517 return false; 494 518 } // if … … 504 528 FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 ); 505 529 if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) { 506 if ( functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size() ) { 530 // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors 531 if ( (functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size()) || functionType->isTtype() || otherFunction->isTtype() ) { 507 532 if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 508 533 if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
Note: See TracChangeset
for help on using the changeset viewer.