Changeset f3b0a07 for src/ResolvExpr
- Timestamp:
- Jan 16, 2017, 3:29:18 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:
- 5ebb2fbc
- Parents:
- 981bdc6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/ResolvExpr/Unify.cc ¶
r981bdc6 rf3b0a07 163 163 case TypeDecl::Ttype: 164 164 // ttype unifies with any tuple type 165 return dynamic_cast< TupleType * >( type ) ;165 return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type ); 166 166 } // switch 167 167 return false; … … 488 488 } 489 489 490 template< typename Iterator >491 std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end ) {490 template< typename Iterator, typename Func > 491 std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) { 492 492 std::list< Type * > types; 493 493 for ( ; begin != end; ++begin ) { 494 494 // it's guaranteed that a ttype variable will be bound to a flat tuple, so ensure that this results in a flat tuple 495 flatten( (*begin)->get_type(), back_inserter( types ) );495 flatten( toType( *begin ), back_inserter( types ) ); 496 496 } 497 497 return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) ); … … 500 500 template< typename Iterator1, typename Iterator2 > 501 501 bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 502 auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); }; 502 503 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 503 504 Type * t1 = (*list1Begin)->get_type(); … … 509 510 if ( isTtype1 && ! isTtype2 ) { 510 511 // combine all of the things in list2, then unify 511 return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );512 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 512 513 } else if ( isTtype2 && ! isTtype1 ) { 513 514 // combine all of the things in list1, then unify 514 return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );515 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 515 516 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 516 517 return false; … … 522 523 Type * t1 = (*list1Begin)->get_type(); 523 524 if ( Tuples::isTtype( t1 ) ) { 524 return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );525 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 525 526 } else return false; 526 527 } else if ( list2Begin != list2End ) { … … 528 529 Type * t2 = (*list2Begin)->get_type(); 529 530 if ( Tuples::isTtype( t2 ) ) { 530 return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );531 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 531 532 } else return false; 532 533 } else { … … 665 666 template< typename Iterator1, typename Iterator2 > 666 667 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 668 auto get_type = [](Type * t) { return t; }; 667 669 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 668 Type *commonType = 0; 669 if ( ! unifyInexact( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, widenMode, indexer, commonType ) ) { 670 Type * t1 = *list1Begin; 671 Type * t2 = *list2Begin; 672 bool isTtype1 = Tuples::isTtype( t1 ); 673 bool isTtype2 = Tuples::isTtype( t2 ); 674 // xxx - assumes ttype must be last parameter 675 // xxx - there may be a nice way to refactor this, but be careful because the argument positioning might matter in some cases. 676 if ( isTtype1 && ! isTtype2 ) { 677 // combine all of the things in list2, then unify 678 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 679 } else if ( isTtype2 && ! isTtype1 ) { 680 // combine all of the things in list1, then unify 681 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 682 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 670 683 return false; 671 } 672 delete commonType; 684 } // if 685 673 686 } // for 674 if ( list1Begin != list1End || list2Begin != list2End ) { 675 return false; 687 if ( list1Begin != list1End ) { 688 // try unifying empty tuple type with ttype 689 Type * t1 = *list1Begin; 690 if ( Tuples::isTtype( t1 ) ) { 691 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 692 } else return false; 693 } else if ( list2Begin != list2End ) { 694 // try unifying empty tuple type with ttype 695 Type * t2 = *list2Begin; 696 if ( Tuples::isTtype( t2 ) ) { 697 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 698 } else return false; 676 699 } else { 677 700 return true; 678 } // if701 } // if 679 702 } 680 703 681 704 void Unify::visit(TupleType *tupleType) { 682 705 if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) { 683 result = unifyList( tupleType->get_types().begin(), tupleType->get_types().end(), otherTuple->get_types().begin(), otherTuple->get_types().end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 706 std::unique_ptr<TupleType> flat1( tupleType->clone() ); 707 std::unique_ptr<TupleType> flat2( otherTuple->clone() ); 708 std::list<Type *> types1, types2; 709 710 TtypeExpander expander( env ); 711 flat1->acceptMutator( expander ); 712 flat2->acceptMutator( expander ); 713 714 flatten( flat1.get(), back_inserter( types1 ) ); 715 flatten( flat2.get(), back_inserter( types2 ) ); 716 717 result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 684 718 } // if 685 719 }
Note: See TracChangeset
for help on using the changeset viewer.