Changeset 1f44196 for src/ResolvExpr/AlternativeFinder.cc
- Timestamp:
- Nov 29, 2016, 3:30:59 PM (9 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:
- 8e5724e
- Parents:
- 3a2128f (diff), 9129a84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r3a2128f r1f44196 38 38 #include "SynTree/TypeSubstitution.h" 39 39 #include "SymTab/Validate.h" 40 #include "Tuples/Tuple Assignment.h"41 #include "Tuples/ NameMatcher.h"40 #include "Tuples/Tuples.h" 41 #include "Tuples/Explode.h" 42 42 #include "Common/utility.h" 43 43 #include "InitTweak/InitTweak.h" 44 #include "InitTweak/GenInit.h" 44 45 #include "ResolveTypeof.h" 45 46 … … 64 65 } 65 66 67 Cost sumCost( const AltList &in ) { 68 Cost total; 69 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) { 70 total += i->cost; 71 } 72 return total; 73 } 74 66 75 namespace { 67 76 void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) { … … 76 85 out.push_back( i->expr->clone() ); 77 86 } 78 }79 80 Cost sumCost( const AltList &in ) {81 Cost total;82 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {83 total += i->cost;84 }85 return total;86 87 } 87 88 … … 101 102 PruneStruct current( candidate ); 102 103 std::string mangleName; 103 for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ){104 Type * newType = (*retType)->clone();104 { 105 Type * newType = candidate->expr->get_result()->clone(); 105 106 candidate->env.apply( newType ); 106 mangleName += SymTab::Mangler::mangle( newType );107 mangleName = SymTab::Mangler::mangle( newType ); 107 108 delete newType; 108 109 } … … 133 134 if ( ! target->second.isAmbiguous ) { 134 135 Alternative &alt = *target->second.candidate; 135 for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) { 136 alt.env.applyFree( *result ); 137 } 136 alt.env.applyFree( alt.expr->get_result() ); 138 137 *out++ = alt; 139 138 } 140 139 } 141 142 }143 144 template< typename InputIterator, typename OutputIterator >145 void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {146 AltList alternatives;147 148 // select the alternatives that have the minimum parameter cost149 Cost minCost = Cost::infinity;150 for ( AltList::iterator i = begin; i != end; ++i ) {151 if ( i->cost < minCost ) {152 minCost = i->cost;153 i->cost = i->cvtCost;154 alternatives.clear();155 alternatives.push_back( *i );156 } else if ( i->cost == minCost ) {157 i->cost = i->cvtCost;158 alternatives.push_back( *i );159 }160 }161 std::copy( alternatives.begin(), alternatives.end(), out );162 }163 164 template< typename InputIterator >165 void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) {166 while ( begin != end ) {167 result.simpleCombine( (*begin++).env );168 }169 140 } 170 141 171 142 void renameTypes( Expression *expr ) { 172 for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) { 173 (*i)->accept( global_renamer ); 174 } 143 expr->get_result()->accept( global_renamer ); 175 144 } 176 145 } … … 204 173 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) { 205 174 if ( adjust ) { 206 adjustExprType List( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );175 adjustExprType( i->expr->get_result(), i->env, indexer ); 207 176 } 208 177 } … … 240 209 } 241 210 211 // std::unordered_map< Expression *, UniqueExpr * > ; 212 242 213 template< typename StructOrUnionType > 243 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) { 214 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 215 // by this point, member must be a name expr 216 NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member ); 217 const std::string & name = nameExpr->get_name(); 244 218 std::list< Declaration* > members; 245 219 aggInst->lookup( name, members ); … … 254 228 } 255 229 230 void AlternativeFinder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 231 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 232 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning 233 // xxx - this should be improved by memoizing the value of constant exprs 234 // during parsing and reusing that information here. 235 std::stringstream ss( constantExpr->get_constant()->get_value() ); 236 int val; 237 std::string tmp; 238 if ( ss >> val && ! (ss >> tmp) ) { 239 if ( val >= 0 && (unsigned int)val < tupleType->size() ) { 240 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) ); 241 } // if 242 } // if 243 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) { 244 // xxx - temporary hack until 0/1 are int constants 245 if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) { 246 std::stringstream ss( nameExpr->get_name() ); 247 int val; 248 ss >> val; 249 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) ); 250 } 251 } // if 252 } 253 256 254 void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) { 257 255 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) ); … … 259 257 260 258 Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 261 ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr ); 262 assert( appExpr ); 263 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 264 assert( pointer ); 265 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 266 assert( function ); 259 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr ); 260 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 261 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 267 262 268 263 Cost convCost( 0, 0, 0 ); … … 270 265 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 271 266 std::list< Expression* >& actuals = appExpr->get_args(); 267 268 std::list< Type * > formalTypes; 269 std::list< Type * >::iterator formalType = formalTypes.end(); 270 272 271 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 272 273 273 PRINT( 274 274 std::cerr << "actual expression:" << std::endl; 275 275 (*actualExpr)->print( std::cerr, 8 ); 276 276 std::cerr << "--- results are" << std::endl; 277 printAll( (*actualExpr)->get_results(),std::cerr, 8 );277 (*actualExpr)->get_result()->print( std::cerr, 8 ); 278 278 ) 279 279 std::list< DeclarationWithType* >::iterator startFormal = formal; 280 280 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; 281 std::list< Type * > flatActualTypes; 282 flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) ); 283 for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) { 284 285 286 // tuple handling code 287 if ( formalType == formalTypes.end() ) { 288 // the type of the formal parameter may be a tuple type. To make this easier to work with, 289 // flatten the tuple type and traverse the resulting list of types, incrementing the formal 290 // iterator once its types have been extracted. Once a particular formal parameter's type has 291 // been exhausted load the next formal parameter's type. 292 if ( formal == formals.end() ) { 293 if ( function->get_isVarArgs() ) { 294 convCost += Cost( 1, 0, 0 ); 295 break; 296 } else { 297 return Cost::infinity; 298 } 288 299 } 300 formalTypes.clear(); 301 flatten( (*formal)->get_type(), back_inserter( formalTypes ) ); 302 formalType = formalTypes.begin(); 303 ++formal; 289 304 } 305 290 306 PRINT( 291 307 std::cerr << std::endl << "converting "; 292 (*actual )->print( std::cerr, 8 );308 (*actualType)->print( std::cerr, 8 ); 293 309 std::cerr << std::endl << " to "; 294 310 (*formal)->get_type()->print( std::cerr, 8 ); 295 311 ) 296 Cost newCost = conversionCost( *actual , (*formal)->get_type(), indexer, alt.env );312 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env ); 297 313 PRINT( 298 314 std::cerr << std::endl << "cost is" << newCost << std::endl; … … 305 321 actualCost += newCost; 306 322 307 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );308 309 formal ++;323 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 ); 324 325 formalType++; 310 326 } 311 327 if ( actualCost != Cost( 0, 0, 0 ) ) { … … 356 372 /// Adds type variables to the open variable set and marks their assertions 357 373 void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) { 358 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {374 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { 359 375 unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind(); 360 376 for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) { … … 365 381 } 366 382 367 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) { 383 /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType, 384 /// producing expression(s) in out and their total cost in cost. 385 template< typename AltIterator, typename OutputIterator > 386 bool instantiateArgument( Type * formalType, Initializer * defaultValue, AltIterator & actualIt, AltIterator actualEnd, OpenVarSet & openVars, TypeEnvironment & resultEnv, AssertionSet & resultNeed, AssertionSet & resultHave, const SymTab::Indexer & indexer, Cost & cost, OutputIterator out ) { 387 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) { 388 // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType 389 TupleExpr * tupleExpr = new TupleExpr(); 390 for ( Type * type : *tupleType ) { 391 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) { 392 delete tupleExpr; 393 return false; 394 } 395 } 396 tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) ); 397 *out++ = tupleExpr; 398 } else if ( actualIt != actualEnd ) { 399 // both actualType and formalType are atomic (non-tuple) types - if they unify 400 // then accept actual as an argument, otherwise return false (fail to instantiate argument) 401 Expression * actual = actualIt->expr; 402 Type * actualType = actual->get_result(); 403 PRINT( 404 std::cerr << "formal type is "; 405 formalType->print( std::cerr ); 406 std::cerr << std::endl << "actual type is "; 407 actualType->print( std::cerr ); 408 std::cerr << std::endl; 409 ) 410 if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 411 return false; 412 } 413 // move the expression from the alternative to the output iterator 414 *out++ = actual; 415 actualIt->expr = nullptr; 416 cost += actualIt->cost; 417 ++actualIt; 418 } else { 419 // End of actuals - Handle default values 420 if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) { 421 // so far, only constant expressions are accepted as default values 422 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) { 423 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) { 424 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 425 // xxx - Don't know if this is right 426 *out++ = cnstexpr->clone(); 427 return true; 428 } // if 429 } // if 430 } // if 431 } // if 432 return false; 433 } // if 434 return true; 435 } 436 437 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) { 368 438 simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv ); 369 439 // make sure we don't widen any existing bindings … … 373 443 resultEnv.extractOpenVars( openVars ); 374 444 375 /* 376 Tuples::NameMatcher matcher( formals ); 377 try { 378 matcher.match( actuals ); 379 } catch ( Tuples::NoMatch &e ) { 380 std::cerr << "Alternative doesn't match: " << e.message << std::endl; 381 } 382 */ 383 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 384 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; 388 } 389 PRINT( 390 std::cerr << "formal type is "; 391 (*formal)->get_type()->print( std::cerr ); 392 std::cerr << std::endl << "actual type is "; 393 (*actual)->print( std::cerr ); 394 std::cerr << std::endl; 395 ) 396 if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 397 return false; 398 } 399 formal++; 400 } 401 } 402 // Handling of default values 403 while ( formal != formals.end() ) { 404 if ( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) ) 405 if ( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() )) 406 // so far, only constant expressions are accepted as default values 407 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) 408 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) 409 if ( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 410 // XXX Don't know if this is right 411 actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) ); 412 formal++; 413 if ( formal == formals.end()) break; 414 } 415 return false; 445 // flatten actuals so that each actual has an atomic (non-tuple) type 446 AltList exploded; 447 Tuples::explode( actuals, indexer, back_inserter( exploded ) ); 448 449 AltList::iterator actualExpr = exploded.begin(); 450 AltList::iterator actualEnd = exploded.end(); 451 for ( DeclarationWithType * formal : formals ) { 452 // match flattened actuals with formal parameters - actuals will be grouped to match 453 // with formals as appropriate 454 Cost cost; 455 std::list< Expression * > newExprs; 456 ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal ); 457 if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) { 458 deleteAll( newExprs ); 459 return false; 460 } 461 // success - produce argument as a new alternative 462 assert( newExprs.size() == 1 ); 463 out.push_back( Alternative( newExprs.front(), resultEnv, cost ) ); 464 } 465 if ( actualExpr != actualEnd ) { 466 // there are still actuals remaining, but we've run out of formal parameters to match against 467 // this is okay only if the function is variadic 468 if ( ! isVarArgs ) { 469 return false; 470 } 471 out.splice( out.end(), exploded, actualExpr, actualEnd ); 416 472 } 417 473 return true; … … 500 556 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 501 557 Expression *varExpr = new VariableExpr( candDecl ); 502 deleteAll( varExpr->get_results() ); 503 varExpr->get_results().clear(); 504 varExpr->get_results().push_front( adjType->clone() ); 558 delete varExpr->get_result(); 559 varExpr->set_result( adjType->clone() ); 505 560 PRINT( 506 561 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; … … 545 600 546 601 template< typename OutputIterator > 547 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {602 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) { 548 603 OpenVarSet openVars; 549 604 AssertionSet resultNeed, resultHave; 550 605 TypeEnvironment resultEnv; 551 606 makeUnifiableVars( funcType, openVars, resultNeed ); 552 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) { 607 AltList instantiatedActuals; // filled by instantiate function 608 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) { 553 609 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 554 Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt) );555 makeExprList( actualAlt, appExpr->get_args() );610 Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) ); 611 makeExprList( instantiatedActuals, appExpr->get_args() ); 556 612 PRINT( 557 613 std::cerr << "need assertions:" << std::endl; … … 574 630 PointerType pt( Type::Qualifiers(), v.clone() ); 575 631 UntypedExpr *vexpr = untypedExpr->clone(); 576 vexpr-> get_results().push_front( pt.clone() );632 vexpr->set_result( pt.clone() ); 577 633 alternatives.push_back( Alternative( vexpr, env, Cost()) ); 578 634 return; … … 587 643 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 588 644 589 Tuples::TupleAssignSpotter tassign( this ); 590 if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) { 591 // take care of possible tuple assignments, or discard expression 592 return; 593 } // else ... 645 // take care of possible tuple assignments 646 // if not tuple assignment, assignment is taken care of as a normal function call 647 Tuples::handleTupleAssignment( *this, untypedExpr, possibilities ); 594 648 595 649 AltList candidates; … … 604 658 // check if the type is pointer to function 605 659 PointerType *pointer; 606 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {660 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) { 607 661 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 608 662 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { … … 640 694 // check if the type is pointer to function 641 695 PointerType *pointer; 642 if ( funcOp->expr->get_results().size() == 1 643 && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) { 696 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) { 644 697 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 645 698 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { … … 665 718 666 719 PRINT( 667 ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr ); 668 assert( appExpr ); 669 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 670 assert( pointer ); 671 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 672 assert( function ); 720 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr ); 721 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 722 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 673 723 std::cerr << "Case +++++++++++++" << std::endl; 674 724 std::cerr << "formals are:" << std::endl; … … 692 742 693 743 bool isLvalue( Expression *expr ) { 694 for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) { 695 if ( !(*i)->get_isLvalue() ) return false; 696 } // for 697 return true; 744 // xxx - recurse into tuples? 745 return expr->has_result() && expr->get_result()->get_isLvalue(); 698 746 } 699 747 … … 709 757 710 758 void AlternativeFinder::visit( CastExpr *castExpr ) { 711 for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) { 712 *i = resolveTypeof( *i, indexer ); 713 SymTab::validateType( *i, &indexer ); 714 adjustExprType( *i, env, indexer ); 715 } // for 759 Type *& toType = castExpr->get_result(); 760 toType = resolveTypeof( toType, indexer ); 761 SymTab::validateType( toType, &indexer ); 762 adjustExprType( toType, env, indexer ); 716 763 717 764 AlternativeFinder finder( indexer, env ); … … 727 774 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 728 775 // to. 729 int discardedValues = (*i).expr->get_result s().size() - castExpr->get_results().size();776 int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size(); 730 777 if ( discardedValues < 0 ) continue; 731 std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin(); 732 std::advance( candidate_end, castExpr->get_results().size() ); 778 // xxx - may need to go into tuple types and extract relavent types and use unifyList 733 779 // unification run for side-effects 734 unifyList( castExpr->get_results().begin(), castExpr->get_results().end(), 735 (*i).expr->get_results().begin(), candidate_end, 736 i->env, needAssertions, haveAssertions, openVars, indexer ); 737 Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end, 738 castExpr->get_results().begin(), castExpr->get_results().end(), 739 indexer, i->env ); 780 unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer ); 781 Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env ); 740 782 if ( thisCost != Cost::infinity ) { 741 783 // count one safe conversion for each value that is thrown away … … 760 802 761 803 for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) { 762 if ( agg->expr->get_results().size() == 1) {763 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {764 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );765 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {766 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );767 } // if804 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) { 805 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 806 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) { 807 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 808 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) { 809 addTupleMembers( tupleType, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 768 810 } // if 769 811 } // for … … 791 833 renameTypes( alternatives.back().expr ); 792 834 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) { 793 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 835 NameExpr nameExpr( "" ); 836 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr ); 794 837 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) { 795 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 838 NameExpr nameExpr( "" ); 839 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr ); 796 840 } // if 797 841 } // for … … 894 938 alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) ); 895 939 for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) { 896 alternatives.back().expr-> get_results().push_back( (*i)->get_type()->clone() );940 alternatives.back().expr->set_result( (*i)->get_type()->clone() ); 897 941 } // for 898 942 } // if … … 917 961 finder.find( attrExpr->get_expr() ); 918 962 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 919 if ( choice->expr->get_result s().size() == 1 ) {920 resolveAttr(*i, function, choice->expr->get_result s().front(), choice->env );963 if ( choice->expr->get_result()->size() == 1 ) { 964 resolveAttr(*i, function, choice->expr->get_result(), choice->env ); 921 965 } // fi 922 966 } // for … … 960 1004 AssertionSet needAssertions, haveAssertions; 961 1005 Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost ); 962 std::list< Type* > commonTypes;963 if ( unify List( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes) ) {1006 Type* commonType = nullptr; 1007 if ( unify( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 964 1008 ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() ); 965 std::list< Type* >::const_iterator original = second->expr->get_results().begin(); 966 std::list< Type* >::const_iterator commonType = commonTypes.begin(); 967 for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) { 968 if ( *commonType ) { 969 newExpr->get_results().push_back( *commonType ); 970 } else { 971 newExpr->get_results().push_back( (*original)->clone() ); 972 } // if 973 } // for 1009 newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() ); 974 1010 newAlt.expr = newExpr; 975 1011 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); … … 999 1035 TupleExpr *newExpr = new TupleExpr; 1000 1036 makeExprList( *i, newExpr->get_exprs() ); 1001 for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) { 1002 for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) { 1003 newExpr->get_results().push_back( (*resultType)->clone() ); 1004 } // for 1005 } // for 1037 newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) ); 1006 1038 1007 1039 TypeEnvironment compositeEnv; … … 1024 1056 } 1025 1057 } 1058 1059 void AlternativeFinder::visit( TupleIndexExpr *tupleExpr ) { 1060 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) ); 1061 } 1062 1063 void AlternativeFinder::visit( TupleAssignExpr *tupleAssignExpr ) { 1064 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) ); 1065 } 1066 1067 void AlternativeFinder::visit( UniqueExpr *unqExpr ) { 1068 AlternativeFinder finder( indexer, env ); 1069 finder.findWithAdjustment( unqExpr->get_expr() ); 1070 for ( Alternative & alt : finder.alternatives ) { 1071 // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked" 1072 UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() ); 1073 alternatives.push_back( Alternative( newUnqExpr, alt.env, alt.cost ) ); 1074 } 1075 } 1076 1026 1077 } // namespace ResolvExpr 1027 1078
Note:
See TracChangeset
for help on using the changeset viewer.