Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r251ce80 r46da46b  
    3333#include "AST/TypeEnvironment.hpp"
    3434#include "Common/PassVisitor.h"     // for PassVisitor
    35 #include "CommonType.hpp"           // for commonType
    3635#include "FindOpenVars.h"           // for findOpenVars
    37 #include "SpecCost.hpp"             // for SpecCost
    3836#include "SynTree/LinkageSpec.h"    // for C
    3937#include "SynTree/Constant.h"       // for Constant
     
    4543#include "Tuples/Tuples.h"          // for isTtype
    4644#include "TypeEnvironment.h"        // for EqvClass, AssertionSet, OpenVarSet
    47 #include "typeops.h"                // for flatten, occurs
     45#include "typeops.h"                // for flatten, occurs, commonType
    4846
    4947namespace ast {
     
    5250
    5351namespace SymTab {
    54         class Indexer;
     52class Indexer;
    5553}  // namespace SymTab
    5654
     
    5856
    5957namespace ResolvExpr {
    60 
    61 // Template Helpers:
    62 template< typename Iterator1, typename Iterator2 >
    63 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
    64         for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    65                 Type *commonType = 0;
    66                 if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    67                         return false;
    68                 } // if
    69                 commonTypes.push_back( commonType );
    70         } // for
    71         return ( list1Begin == list1End && list2Begin == list2End );
    72 }
    73 
    74 template< typename Iterator1, typename Iterator2 >
    75 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    76         std::list< Type* > commonTypes;
    77         if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions,  openVars, indexer, commonTypes ) ) {
    78                 deleteAll( commonTypes );
    79                 return true;
    80         } else {
    81                 return false;
    82         } // if
    83 }
    8458
    8559        struct Unify_old : public WithShortCircuiting {
     
    128102                const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    129103                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    130                 WidenMode widen );
     104                WidenMode widen, const ast::SymbolTable & symtab );
    131105
    132106        bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     
    150124
    151125        bool typesCompatible(
    152                         const ast::Type * first, const ast::Type * second,
     126                        const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
    153127                        const ast::TypeEnvironment & env ) {
    154128                ast::TypeEnvironment newEnv;
     
    160134                env.apply( newSecond );
    161135
    162                 findOpenVars( newFirst, open, closed, need, have, FirstClosed );
    163                 findOpenVars( newSecond, open, closed, need, have, FirstOpen );
    164 
    165                 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden() );
     136                // findOpenVars( newFirst, open, closed, need, have, FirstClosed );
     137                findOpenVars( newSecond, open, closed, need, have, newEnv, FirstOpen );
     138
     139                return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
    166140        }
    167141
     
    183157
    184158        bool typesCompatibleIgnoreQualifiers(
    185                         const ast::Type * first, const ast::Type * second,
     159                        const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
    186160                        const ast::TypeEnvironment & env ) {
    187161                ast::TypeEnvironment newEnv;
     
    216190                        subFirst,
    217191                        subSecond,
    218                         newEnv, need, have, open, noWiden() );
     192                        newEnv, need, have, open, noWiden(), symtab );
    219193        }
    220194
     
    786760                const ast::OpenVarSet & open;
    787761                WidenMode widen;
     762                const ast::SymbolTable & symtab;
    788763        public:
    789764                static size_t traceId;
     
    792767                Unify_new(
    793768                        const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need,
    794                         ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen )
     769                        ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen,
     770                        const ast::SymbolTable & symtab )
    795771                : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen),
    796                 result(false) {}
     772                  symtab(symtab), result(false) {}
    797773
    798774                void previsit( const ast::Node * ) { visit_children = false; }
     
    812788                                result = unifyExact(
    813789                                        pointer->base, pointer2->base, tenv, need, have, open,
    814                                         noWiden());
     790                                        noWiden(), symtab );
    815791                        }
    816792                }
     
    835811
    836812                        result = unifyExact(
    837                                 array->base, array2->base, tenv, need, have, open, noWiden());
     813                                array->base, array2->base, tenv, need, have, open, noWiden(),
     814                                symtab );
    838815                }
    839816
     
    841818                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
    842819                                result = unifyExact(
    843                                         ref->base, ref2->base, tenv, need, have, open, noWiden());
     820                                        ref->base, ref2->base, tenv, need, have, open, noWiden(),
     821                                        symtab );
    844822                        }
    845823                }
     
    850828                static bool unifyTypeList(
    851829                        Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
    852                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open
     830                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     831                        const ast::SymbolTable & symtab
    853832                ) {
    854833                        while ( crnt1 != end1 && crnt2 != end2 ) {
     
    863842                                        return unifyExact(
    864843                                                t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    865                                                 noWiden() );
     844                                                noWiden(), symtab );
    866845                                } else if ( ! isTuple1 && isTuple2 ) {
    867846                                        // combine remainder of list1, then unify
    868847                                        return unifyExact(
    869848                                                tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    870                                                 noWiden() );
     849                                                noWiden(), symtab );
    871850                                }
    872851
    873852                                if ( ! unifyExact(
    874                                         t1, t2, env, need, have, open, noWiden() )
     853                                        t1, t2, env, need, have, open, noWiden(), symtab )
    875854                                ) return false;
    876855
     
    886865                                return unifyExact(
    887866                                        t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    888                                         noWiden() );
     867                                        noWiden(), symtab );
    889868                        } else if ( crnt2 != end2 ) {
    890869                                // try unifying empty tuple with ttype
     
    893872                                return unifyExact(
    894873                                        tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    895                                         noWiden() );
     874                                        noWiden(), symtab );
    896875                        }
    897876
     
    903882                        const std::vector< ast::ptr< ast::Type > > & list2,
    904883                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    905                         const ast::OpenVarSet & open
     884                        const ast::OpenVarSet & open, const ast::SymbolTable & symtab
    906885                ) {
    907886                        return unifyTypeList(
    908                                 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open);
     887                                list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
     888                                symtab );
    909889                }
    910890
     
    947927                        ) return;
    948928
    949                         if ( ! unifyTypeList( params, params2, tenv, need, have, open ) ) return;
     929                        if ( ! unifyTypeList( params, params2, tenv, need, have, open, symtab ) ) return;
    950930                        if ( ! unifyTypeList(
    951                                 func->returns, func2->returns, tenv, need, have, open ) ) return;
     931                                func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
    952932
    953933                        markAssertions( have, need, func );
     
    10201000
    10211001                                if ( ! unifyExact(
    1022                                                 pty, pty2, tenv, need, have, open, noWiden() ) ) {
     1002                                                pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
    10231003                                        result = false;
    10241004                                        return;
     
    10491029
    10501030                void postvisit( const ast::TypeInstType * typeInst ) {
    1051                         assert( open.find( *typeInst ) == open.end() );
     1031                        // assert( open.find( *typeInst ) == open.end() );
    10521032                        handleRefType( typeInst, type2 );
    10531033                }
     
    10591039                        const std::vector< ast::ptr< ast::Type > > & list1,
    10601040                        const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env,
    1061                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open
     1041                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     1042                        const ast::SymbolTable & symtab
    10621043                ) {
    10631044                        auto crnt1 = list1.begin();
     
    10741055                                        return unifyExact(
    10751056                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1076                                                 noWiden() );
     1057                                                noWiden(), symtab );
    10771058                                } else if ( ! isTuple1 && isTuple2 ) {
    10781059                                        // combine entirety of list1, then unify
    10791060                                        return unifyExact(
    10801061                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1081                                                 noWiden() );
     1062                                                noWiden(), symtab );
    10821063                                }
    10831064
    10841065                                if ( ! unifyExact(
    1085                                         t1, t2, env, need, have, open, noWiden() )
     1066                                        t1, t2, env, need, have, open, noWiden(), symtab )
    10861067                                ) return false;
    10871068
     
    10971078                                return unifyExact(
    10981079                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1099                                                 noWiden() );
     1080                                                noWiden(), symtab );
    11001081                        } else if ( crnt2 != list2.end() ) {
    11011082                                // try unifying empty tuple with ttype
     
    11061087                                return unifyExact(
    11071088                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1108                                                 noWiden() );
     1089                                                noWiden(), symtab );
    11091090                        }
    11101091
     
    11251106                        auto types2 = flatten( flat2 );
    11261107
    1127                         result = unifyList( types, types2, tenv, need, have, open );
     1108                        result = unifyList( types, types2, tenv, need, have, open, symtab );
    11281109                }
    11291110
     
    11491130                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    11501131                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1151                         ast::OpenVarSet & open
     1132                        ast::OpenVarSet & open, const ast::SymbolTable & symtab
    11521133        ) {
    11531134                ast::ptr<ast::Type> common;
    1154                 return unify( type1, type2, env, need, have, open, common );
     1135                return unify( type1, type2, env, need, have, open, symtab, common );
    11551136        }
    11561137
     
    11581139                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    11591140                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1160                         ast::OpenVarSet & open, ast::ptr<ast::Type> & common
     1141                        ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
    11611142        ) {
    11621143                ast::OpenVarSet closed;
    1163                 findOpenVars( type1, open, closed, need, have, FirstClosed );
    1164                 findOpenVars( type2, open, closed, need, have, FirstOpen );
     1144                // findOpenVars( type1, open, closed, need, have, FirstClosed );
     1145                findOpenVars( type2, open, closed, need, have, env, FirstOpen );
    11651146                return unifyInexact(
    1166                         type1, type2, env, need, have, open, WidenMode{ true, true }, common );
     1147                        type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
    11671148        }
    11681149
     
    11701151                        const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    11711152                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    1172                         WidenMode widen
     1153                        WidenMode widen, const ast::SymbolTable & symtab
    11731154        ) {
    11741155                if ( type1->qualifiers != type2->qualifiers ) return false;
     
    11791160                        entry1 = var1 ? open.find( *var1 ) : open.end(),
    11801161                        entry2 = var2 ? open.find( *var2 ) : open.end();
    1181                 bool isopen1 = entry1 != open.end();
    1182                 bool isopen2 = entry2 != open.end();
    1183 
     1162                // bool isopen1 = entry1 != open.end();
     1163                // bool isopen2 = entry2 != open.end();
     1164                bool isopen1 = var1 && env.lookup(*var1);
     1165                bool isopen2 = var2 && env.lookup(*var2);
     1166
     1167                /*
    11841168                if ( isopen1 && isopen2 ) {
    11851169                        if ( entry1->second.kind != entry2->second.kind ) return false;
    11861170                        return env.bindVarToVar(
    11871171                                var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have,
    1188                                 open, widen );
     1172                                open, widen, symtab );
    11891173                } else if ( isopen1 ) {
    1190                         return env.bindVar( var1, type2, entry1->second, need, have, open, widen );
     1174                        return env.bindVar( var1, type2, entry1->second, need, have, open, widen, symtab );
    11911175                } else if ( isopen2 ) {
    1192                         return env.bindVar( var2, type1, entry2->second, need, have, open, widen );
    1193                 } else {
     1176                        return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab );
     1177                } */
     1178                if ( isopen1 && isopen2 ) {
     1179                        if ( var1->base->kind != var2->base->kind ) return false;
     1180                        return env.bindVarToVar(
     1181                                var1, var2, ast::TypeData{ var1->base->kind, var1->base->sized||var2->base->sized }, need, have,
     1182                                open, widen, symtab );
     1183                } else if ( isopen1 ) {
     1184                        return env.bindVar( var1, type2, ast::TypeData{var1->base}, need, have, open, widen, symtab );
     1185                } else if ( isopen2 ) {
     1186                        return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen, symtab );
     1187                }else {
    11941188                        return ast::Pass<Unify_new>::read(
    1195                                 type1, type2, env, need, have, open, widen );
    1196                 }
     1189                                type1, type2, env, need, have, open, widen, symtab );
     1190                }
     1191               
    11971192        }
    11981193
     
    12001195                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    12011196                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1202                         const ast::OpenVarSet & open, WidenMode widen,
     1197                        const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
    12031198                        ast::ptr<ast::Type> & common
    12041199        ) {
     
    12141209                ast::ptr< ast::Type > t2_(t2);
    12151210
    1216                 if ( unifyExact( t1, t2, env, need, have, open, widen ) ) {
     1211                if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
    12171212                        // if exact unification on unqualified types, try to merge qualifiers
    12181213                        if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) {
     
    12241219                        }
    12251220
    1226                 } else if (( common = commonType( t1, t2, env, need, have, open, widen ))) {
     1221                } else if (( common = commonType( t1, t2, env, need, have, open, widen, symtab ))) {
    12271222                        // no exact unification, but common type
    12281223                        auto c = shallowCopy(common.get());
Note: See TracChangeset for help on using the changeset viewer.