Ignore:
Timestamp:
Jun 12, 2023, 2:45:32 PM (13 months ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ast-experimental, master
Children:
62d62db
Parents:
34b4268 (diff), 251ce80 (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.
Message:

Merge branch 'master' into ast-experimental

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r34b4268 r24d6572  
    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;
     
    137163                findOpenVars( newSecond, open, closed, need, have, newEnv, FirstOpen );
    138164
    139                 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
     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 );
     
    944964                        // check that the other type is compatible and named the same
    945965                        auto otherInst = dynamic_cast< const XInstType * >( other );
    946                         if (otherInst && inst->name == otherInst->name) this->result = otherInst;
     966                        if (otherInst && inst->name == otherInst->name)
     967                                this->result = otherInst;
    947968                        return otherInst;
    948969                }
     
    10001021
    10011022                                if ( ! unifyExact(
    1002                                                 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
     1023                                                pty, pty2, tenv, need, have, open, noWiden() ) ) {
    10031024                                        result = false;
    10041025                                        return;
     
    10301051                void postvisit( const ast::TypeInstType * typeInst ) {
    10311052                        // assert( open.find( *typeInst ) == open.end() );
    1032                         handleRefType( typeInst, type2 );
     1053                        auto otherInst = dynamic_cast< const ast::TypeInstType * >( type2 );
     1054                        if (otherInst && typeInst->name == otherInst->name)
     1055                                this->result = otherInst;
     1056                        // return otherInst;
    10331057                }
    10341058
     
    10391063                        const std::vector< ast::ptr< ast::Type > > & list1,
    10401064                        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
     1065                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open
    10431066                ) {
    10441067                        auto crnt1 = list1.begin();
     
    10551078                                        return unifyExact(
    10561079                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1057                                                 noWiden(), symtab );
     1080                                                noWiden() );
    10581081                                } else if ( ! isTuple1 && isTuple2 ) {
    10591082                                        // combine entirety of list1, then unify
    10601083                                        return unifyExact(
    10611084                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1062                                                 noWiden(), symtab );
     1085                                                noWiden() );
    10631086                                }
    10641087
    10651088                                if ( ! unifyExact(
    1066                                         t1, t2, env, need, have, open, noWiden(), symtab )
     1089                                        t1, t2, env, need, have, open, noWiden() )
    10671090                                ) return false;
    10681091
     
    10781101                                return unifyExact(
    10791102                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1080                                                 noWiden(), symtab );
     1103                                                noWiden() );
    10811104                        } else if ( crnt2 != list2.end() ) {
    10821105                                // try unifying empty tuple with ttype
     
    10871110                                return unifyExact(
    10881111                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1089                                                 noWiden(), symtab );
     1112                                                noWiden() );
    10901113                        }
    10911114
     
    11061129                        auto types2 = flatten( flat2 );
    11071130
    1108                         result = unifyList( types, types2, tenv, need, have, open, symtab );
     1131                        result = unifyList( types, types2, tenv, need, have, open );
    11091132                }
    11101133
     
    11301153                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    11311154                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1132                         ast::OpenVarSet & open, const ast::SymbolTable & symtab
     1155                        ast::OpenVarSet & open
    11331156        ) {
    11341157                ast::ptr<ast::Type> common;
    1135                 return unify( type1, type2, env, need, have, open, symtab, common );
     1158                return unify( type1, type2, env, need, have, open, common );
    11361159        }
    11371160
     
    11391162                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    11401163                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1141                         ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
     1164                        ast::OpenVarSet & open, ast::ptr<ast::Type> & common
    11421165        ) {
    11431166                ast::OpenVarSet closed;
     
    11451168                findOpenVars( type2, open, closed, need, have, env, FirstOpen );
    11461169                return unifyInexact(
    1147                         type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
     1170                        type1, type2, env, need, have, open, WidenMode{ true, true }, common );
    11481171        }
    11491172
     
    11511174                        const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    11521175                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    1153                         WidenMode widen, const ast::SymbolTable & symtab
     1176                        WidenMode widen
    11541177        ) {
    11551178                if ( type1->qualifiers != type2->qualifiers ) return false;
     
    11701193                        return env.bindVarToVar(
    11711194                                var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have,
    1172                                 open, widen, symtab );
     1195                                open, widen );
    11731196                } else if ( isopen1 ) {
    1174                         return env.bindVar( var1, type2, entry1->second, need, have, open, widen, symtab );
     1197                        return env.bindVar( var1, type2, entry1->second, need, have, open, widen );
    11751198                } else if ( isopen2 ) {
    11761199                        return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab );
     
    11801203                        return env.bindVarToVar(
    11811204                                var1, var2, ast::TypeData{ var1->base->kind, var1->base->sized||var2->base->sized }, need, have,
    1182                                 open, widen, symtab );
     1205                                open, widen );
    11831206                } else if ( isopen1 ) {
    1184                         return env.bindVar( var1, type2, ast::TypeData{var1->base}, need, have, open, widen, symtab );
     1207                        return env.bindVar( var1, type2, ast::TypeData{var1->base}, need, have, open, widen );
    11851208                } else if ( isopen2 ) {
    1186                         return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen, symtab );
     1209                        return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen );
    11871210                }else {
    11881211                        return ast::Pass<Unify_new>::read(
    1189                                 type1, type2, env, need, have, open, widen, symtab );
     1212                                type1, type2, env, need, have, open, widen );
    11901213                }
    11911214               
     
    11951218                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    11961219                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1197                         const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
     1220                        const ast::OpenVarSet & open, WidenMode widen,
    11981221                        ast::ptr<ast::Type> & common
    11991222        ) {
     
    12091232                ast::ptr< ast::Type > t2_(t2);
    12101233
    1211                 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
     1234                if ( unifyExact( t1, t2, env, need, have, open, widen ) ) {
    12121235                        // if exact unification on unqualified types, try to merge qualifiers
    12131236                        if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) {
     
    12191242                        }
    12201243
    1221                 } else if (( common = commonType( t1, t2, env, need, have, open, widen, symtab ))) {
     1244                } else if (( common = commonType( t1, t2, env, need, have, open, widen ))) {
    12221245                        // no exact unification, but common type
    12231246                        auto c = shallowCopy(common.get());
Note: See TracChangeset for help on using the changeset viewer.