Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r46da46b r251ce80  
    3333#include "AST/TypeEnvironment.hpp"
    3434#include "Common/PassVisitor.h"     // for PassVisitor
     35#include "CommonType.hpp"           // for commonType
    3536#include "FindOpenVars.h"           // for findOpenVars
     37#include "SpecCost.hpp"             // for SpecCost
    3638#include "SynTree/LinkageSpec.h"    // for C
    3739#include "SynTree/Constant.h"       // for Constant
     
    4345#include "Tuples/Tuples.h"          // for isTtype
    4446#include "TypeEnvironment.h"        // for EqvClass, AssertionSet, OpenVarSet
    45 #include "typeops.h"                // for flatten, occurs, commonType
     47#include "typeops.h"                // for flatten, occurs
    4648
    4749namespace ast {
     
    5052
    5153namespace SymTab {
    52 class Indexer;
     54        class Indexer;
    5355}  // namespace SymTab
    5456
     
    5658
    5759namespace ResolvExpr {
     60
     61// Template Helpers:
     62template< typename Iterator1, typename Iterator2 >
     63bool 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
     74template< typename Iterator1, typename Iterator2 >
     75bool 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}
    5884
    5985        struct Unify_old : public WithShortCircuiting {
     
    102128                const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    103129                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    104                 WidenMode widen, const ast::SymbolTable & symtab );
     130                WidenMode widen );
    105131
    106132        bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     
    124150
    125151        bool typesCompatible(
    126                         const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
     152                        const ast::Type * first, const ast::Type * second,
    127153                        const ast::TypeEnvironment & env ) {
    128154                ast::TypeEnvironment newEnv;
     
    134160                env.apply( newSecond );
    135161
    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 );
     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() );
    140166        }
    141167
     
    157183
    158184        bool typesCompatibleIgnoreQualifiers(
    159                         const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
     185                        const ast::Type * first, const ast::Type * second,
    160186                        const ast::TypeEnvironment & env ) {
    161187                ast::TypeEnvironment newEnv;
     
    190216                        subFirst,
    191217                        subSecond,
    192                         newEnv, need, have, open, noWiden(), symtab );
     218                        newEnv, need, have, open, noWiden() );
    193219        }
    194220
     
    760786                const ast::OpenVarSet & open;
    761787                WidenMode widen;
    762                 const ast::SymbolTable & symtab;
    763788        public:
    764789                static size_t traceId;
     
    767792                Unify_new(
    768793                        const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need,
    769                         ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen,
    770                         const ast::SymbolTable & symtab )
     794                        ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen )
    771795                : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen),
    772                   symtab(symtab), result(false) {}
     796                result(false) {}
    773797
    774798                void previsit( const ast::Node * ) { visit_children = false; }
     
    788812                                result = unifyExact(
    789813                                        pointer->base, pointer2->base, tenv, need, have, open,
    790                                         noWiden(), symtab );
     814                                        noWiden());
    791815                        }
    792816                }
     
    811835
    812836                        result = unifyExact(
    813                                 array->base, array2->base, tenv, need, have, open, noWiden(),
    814                                 symtab );
     837                                array->base, array2->base, tenv, need, have, open, noWiden());
    815838                }
    816839
     
    818841                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
    819842                                result = unifyExact(
    820                                         ref->base, ref2->base, tenv, need, have, open, noWiden(),
    821                                         symtab );
     843                                        ref->base, ref2->base, tenv, need, have, open, noWiden());
    822844                        }
    823845                }
     
    828850                static bool unifyTypeList(
    829851                        Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
    830                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    831                         const ast::SymbolTable & symtab
     852                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open
    832853                ) {
    833854                        while ( crnt1 != end1 && crnt2 != end2 ) {
     
    842863                                        return unifyExact(
    843864                                                t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    844                                                 noWiden(), symtab );
     865                                                noWiden() );
    845866                                } else if ( ! isTuple1 && isTuple2 ) {
    846867                                        // combine remainder of list1, then unify
    847868                                        return unifyExact(
    848869                                                tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    849                                                 noWiden(), symtab );
     870                                                noWiden() );
    850871                                }
    851872
    852873                                if ( ! unifyExact(
    853                                         t1, t2, env, need, have, open, noWiden(), symtab )
     874                                        t1, t2, env, need, have, open, noWiden() )
    854875                                ) return false;
    855876
     
    865886                                return unifyExact(
    866887                                        t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    867                                         noWiden(), symtab );
     888                                        noWiden() );
    868889                        } else if ( crnt2 != end2 ) {
    869890                                // try unifying empty tuple with ttype
     
    872893                                return unifyExact(
    873894                                        tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    874                                         noWiden(), symtab );
     895                                        noWiden() );
    875896                        }
    876897
     
    882903                        const std::vector< ast::ptr< ast::Type > > & list2,
    883904                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    884                         const ast::OpenVarSet & open, const ast::SymbolTable & symtab
     905                        const ast::OpenVarSet & open
    885906                ) {
    886907                        return unifyTypeList(
    887                                 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
    888                                 symtab );
     908                                list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open);
    889909                }
    890910
     
    927947                        ) return;
    928948
    929                         if ( ! unifyTypeList( params, params2, tenv, need, have, open, symtab ) ) return;
     949                        if ( ! unifyTypeList( params, params2, tenv, need, have, open ) ) return;
    930950                        if ( ! unifyTypeList(
    931                                 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
     951                                func->returns, func2->returns, tenv, need, have, open ) ) return;
    932952
    933953                        markAssertions( have, need, func );
     
    10001020
    10011021                                if ( ! unifyExact(
    1002                                                 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
     1022                                                pty, pty2, tenv, need, have, open, noWiden() ) ) {
    10031023                                        result = false;
    10041024                                        return;
     
    10291049
    10301050                void postvisit( const ast::TypeInstType * typeInst ) {
    1031                         // assert( open.find( *typeInst ) == open.end() );
     1051                        assert( open.find( *typeInst ) == open.end() );
    10321052                        handleRefType( typeInst, type2 );
    10331053                }
     
    10391059                        const std::vector< ast::ptr< ast::Type > > & list1,
    10401060                        const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env,
    1041                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    1042                         const ast::SymbolTable & symtab
     1061                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open
    10431062                ) {
    10441063                        auto crnt1 = list1.begin();
     
    10551074                                        return unifyExact(
    10561075                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1057                                                 noWiden(), symtab );
     1076                                                noWiden() );
    10581077                                } else if ( ! isTuple1 && isTuple2 ) {
    10591078                                        // combine entirety of list1, then unify
    10601079                                        return unifyExact(
    10611080                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1062                                                 noWiden(), symtab );
     1081                                                noWiden() );
    10631082                                }
    10641083
    10651084                                if ( ! unifyExact(
    1066                                         t1, t2, env, need, have, open, noWiden(), symtab )
     1085                                        t1, t2, env, need, have, open, noWiden() )
    10671086                                ) return false;
    10681087
     
    10781097                                return unifyExact(
    10791098                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1080                                                 noWiden(), symtab );
     1099                                                noWiden() );
    10811100                        } else if ( crnt2 != list2.end() ) {
    10821101                                // try unifying empty tuple with ttype
     
    10871106                                return unifyExact(
    10881107                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1089                                                 noWiden(), symtab );
     1108                                                noWiden() );
    10901109                        }
    10911110
     
    11061125                        auto types2 = flatten( flat2 );
    11071126
    1108                         result = unifyList( types, types2, tenv, need, have, open, symtab );
     1127                        result = unifyList( types, types2, tenv, need, have, open );
    11091128                }
    11101129
     
    11301149                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    11311150                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1132                         ast::OpenVarSet & open, const ast::SymbolTable & symtab
     1151                        ast::OpenVarSet & open
    11331152        ) {
    11341153                ast::ptr<ast::Type> common;
    1135                 return unify( type1, type2, env, need, have, open, symtab, common );
     1154                return unify( type1, type2, env, need, have, open, common );
    11361155        }
    11371156
     
    11391158                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    11401159                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1141                         ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
     1160                        ast::OpenVarSet & open, ast::ptr<ast::Type> & common
    11421161        ) {
    11431162                ast::OpenVarSet closed;
    1144                 // findOpenVars( type1, open, closed, need, have, FirstClosed );
    1145                 findOpenVars( type2, open, closed, need, have, env, FirstOpen );
     1163                findOpenVars( type1, open, closed, need, have, FirstClosed );
     1164                findOpenVars( type2, open, closed, need, have, FirstOpen );
    11461165                return unifyInexact(
    1147                         type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
     1166                        type1, type2, env, need, have, open, WidenMode{ true, true }, common );
    11481167        }
    11491168
     
    11511170                        const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    11521171                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    1153                         WidenMode widen, const ast::SymbolTable & symtab
     1172                        WidenMode widen
    11541173        ) {
    11551174                if ( type1->qualifiers != type2->qualifiers ) return false;
     
    11601179                        entry1 = var1 ? open.find( *var1 ) : open.end(),
    11611180                        entry2 = var2 ? open.find( *var2 ) : open.end();
    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                 /*
     1181                bool isopen1 = entry1 != open.end();
     1182                bool isopen2 = entry2 != open.end();
     1183
    11681184                if ( isopen1 && isopen2 ) {
    11691185                        if ( entry1->second.kind != entry2->second.kind ) return false;
    11701186                        return env.bindVarToVar(
    11711187                                var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have,
    1172                                 open, widen, symtab );
     1188                                open, widen );
    11731189                } else if ( isopen1 ) {
    1174                         return env.bindVar( var1, type2, entry1->second, need, have, open, widen, symtab );
     1190                        return env.bindVar( var1, type2, entry1->second, need, have, open, widen );
    11751191                } else if ( isopen2 ) {
    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 {
     1192                        return env.bindVar( var2, type1, entry2->second, need, have, open, widen );
     1193                } else {
    11881194                        return ast::Pass<Unify_new>::read(
    1189                                 type1, type2, env, need, have, open, widen, symtab );
    1190                 }
    1191                
     1195                                type1, type2, env, need, have, open, widen );
     1196                }
    11921197        }
    11931198
     
    11951200                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    11961201                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1197                         const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
     1202                        const ast::OpenVarSet & open, WidenMode widen,
    11981203                        ast::ptr<ast::Type> & common
    11991204        ) {
     
    12091214                ast::ptr< ast::Type > t2_(t2);
    12101215
    1211                 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
     1216                if ( unifyExact( t1, t2, env, need, have, open, widen ) ) {
    12121217                        // if exact unification on unqualified types, try to merge qualifiers
    12131218                        if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) {
     
    12191224                        }
    12201225
    1221                 } else if (( common = commonType( t1, t2, env, need, have, open, widen, symtab ))) {
     1226                } else if (( common = commonType( t1, t2, env, need, have, open, widen ))) {
    12221227                        // no exact unification, but common type
    12231228                        auto c = shallowCopy(common.get());
Note: See TracChangeset for help on using the changeset viewer.