Changeset f3b0a07 for src/ResolvExpr


Ignore:
Timestamp:
Jan 16, 2017, 3:29:18 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
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
Message:

allow ttypes contained in tuple types to unify, refactor and simplify Specialize pass

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/ResolvExpr/Unify.cc

    r981bdc6 rf3b0a07  
    163163                        case TypeDecl::Ttype:
    164164                        // ttype unifies with any tuple type
    165                         return dynamic_cast< TupleType * >( type );
     165                        return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );
    166166                } // switch
    167167                return false;
     
    488488        }
    489489
    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 ) {
    492492                std::list< Type * > types;
    493493                for ( ; begin != end; ++begin ) {
    494494                        // 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 ) );
    496496                }
    497497                return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );
     
    500500        template< typename Iterator1, typename Iterator2 >
    501501        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(); };
    502503                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    503504                        Type * t1 = (*list1Begin)->get_type();
     
    509510                        if ( isTtype1 && ! isTtype2 ) {
    510511                                // 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 );
    512513                        } else if ( isTtype2 && ! isTtype1 ) {
    513514                                // 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 );
    515516                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    516517                                return false;
     
    522523                        Type * t1 = (*list1Begin)->get_type();
    523524                        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 );
    525526                        } else return false;
    526527                } else if ( list2Begin != list2End ) {
     
    528529                        Type * t2 = (*list2Begin)->get_type();
    529530                        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 );
    531532                        } else return false;
    532533                } else {
     
    665666        template< typename Iterator1, typename Iterator2 >
    666667        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; };
    667669                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 ) ) {
    670683                                return false;
    671                         }
    672                         delete commonType;
     684                        } // if
     685
    673686                } // 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;
    676699                } else {
    677700                        return true;
    678                 } //if
     701                } // if
    679702        }
    680703
    681704        void Unify::visit(TupleType *tupleType) {
    682705                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 );
    684718                } // if
    685719        }
Note: See TracChangeset for help on using the changeset viewer.