Ignore:
Timestamp:
Jan 7, 2021, 3:27:00 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
2b4daf2, 64aeca0
Parents:
3c64c668 (diff), eef8dfb (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 park_unpark

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/TypeEnvironment.cpp

    r3c64c668 r58fe85a  
    3434#include "ResolvExpr/Unify.h"      // for unifyInexact
    3535#include "Tuples/Tuples.h"         // for isTtype
     36#include "CompilationState.h"
    3637
    3738using ResolvExpr::WidenMode;
     
    5152        for ( const auto & i : open ) {
    5253                if ( first ) { first = false; } else { out << ' '; }
    53                 out << i.first << "(" << i.second << ")";
     54                out << i.first.typeString() << "(" << i.second << ")";
    5455        }
    5556}
    5657
    5758void print( std::ostream & out, const EqvClass & clz, Indenter indent ) {
    58         out << "( ";
    59         std::copy( clz.vars.begin(), clz.vars.end(), std::ostream_iterator< std::string >( out, " " ) );
     59        out << "(";
     60        bool first = true;
     61        for(const auto & var : clz.vars) {
     62                if(first) first = false;
     63                else out << " ";
     64
     65                if( deterministic_output ) out << "[unbound]";
     66                else out << "_" << var.formal_usage << "_" << var.expr_id << "_";
     67
     68                out << var.base->name;
     69        }
    6070        out << ")";
    61        
     71
    6272        if ( clz.bound ) {
    6373                out << " -> ";
     
    7282}
    7383
    74 const EqvClass * TypeEnvironment::lookup( const std::string & var ) const {
     84const EqvClass * TypeEnvironment::lookup( const TypeInstType::TypeEnvKey & var ) const {
    7585        for ( ClassList::const_iterator i = env.begin(); i != env.end(); ++i ) {
    7686                if ( i->vars.find( var ) != i->vars.end() ) return &*i;
     
    92102                                }
    93103                        }
    94                        
     104
    95105                        i = next;  // go to next node even if this removed
    96106                }
     
    98108}
    99109
    100 void TypeEnvironment::add( const ParameterizedType::ForallList & tyDecls ) {
    101         for ( const TypeDecl * tyDecl : tyDecls ) {
     110void TypeEnvironment::add( const FunctionType::ForallList & tyDecls ) {
     111        for ( auto & tyDecl : tyDecls ) {
    102112                env.emplace_back( tyDecl );
    103113        }
     
    112122void TypeEnvironment::writeToSubstitution( TypeSubstitution & sub ) const {
    113123        for ( const auto & clz : env ) {
    114                 std::string clzRep;
     124                TypeInstType::TypeEnvKey clzRep;
     125                bool first = true;
    115126                for ( const auto & var : clz.vars ) {
    116127                        if ( clz.bound ) {
    117128                                sub.add( var, clz.bound );
    118                         } else if ( clzRep.empty() ) {
     129                        } else if ( first ) {
    119130                                clzRep = var;
     131                                first = false;
    120132                        } else {
    121                                 sub.add( var, new TypeInstType{ clzRep, clz.data.kind } );
     133                                sub.add( var, new TypeInstType{ clzRep } );
    122134                        }
    123135                }
     
    134146        struct Occurs : public ast::WithVisitorRef<Occurs> {
    135147                bool result;
    136                 std::set< std::string > vars;
     148                std::unordered_set< TypeInstType::TypeEnvKey > vars;
    137149                const TypeEnvironment & tenv;
    138150
    139                 Occurs( const std::string & var, const TypeEnvironment & env )
     151                Occurs( const TypeInstType::TypeEnvKey & var, const TypeEnvironment & env )
    140152                : result( false ), vars(), tenv( env ) {
    141153                        if ( const EqvClass * clz = tenv.lookup( var ) ) {
     
    147159
    148160                void previsit( const TypeInstType * typeInst ) {
    149                         if ( vars.count( typeInst->name ) ) {
     161                        if ( vars.count( *typeInst ) ) {
    150162                                result = true;
    151                         } else if ( const EqvClass * clz = tenv.lookup( typeInst->name ) ) {
     163                        } else if ( const EqvClass * clz = tenv.lookup( *typeInst ) ) {
    152164                                if ( clz->bound ) {
    153165                                        clz->bound->accept( *visitor );
     
    158170
    159171        /// true if `var` occurs in `ty` under `env`
    160         bool occurs( const Type * ty, const std::string & var, const TypeEnvironment & env ) {
     172        bool occurs( const Type * ty, const TypeInstType::TypeEnvKey & var, const TypeEnvironment & env ) {
    161173                Pass<Occurs> occur{ var, env };
    162174                maybe_accept( ty, occur );
    163                 return occur.pass.result;
    164         }
    165 }
    166 
    167 bool TypeEnvironment::combine( 
     175                return occur.core.result;
     176        }
     177}
     178
     179bool TypeEnvironment::combine(
    168180                const TypeEnvironment & o, OpenVarSet & open, const SymbolTable & symtab ) {
    169181        // short-circuit easy cases
     
    199211                                auto st = internal_lookup( *vt );
    200212                                if ( st == env.end() ) {
    201                                         // unbound, safe to add if occurs 
     213                                        // unbound, safe to add if occurs
    202214                                        if ( r.bound && occurs( r.bound, *vt, *this ) ) return false;
    203215                                        r.vars.emplace( *vt );
     
    266278}
    267279
    268 bool TypeEnvironment::bindVar( 
    269                 const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data, 
    270                 AssertionSet & need, AssertionSet & have, const OpenVarSet & open, WidenMode widen, 
    271                 const SymbolTable & symtab 
     280bool TypeEnvironment::bindVar(
     281                const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data,
     282                AssertionSet & need, AssertionSet & have, const OpenVarSet & open, WidenMode widen,
     283                const SymbolTable & symtab
    272284) {
    273285        // remove references from bound type, so that type variables can only bind to value types
    274286        ptr<Type> target = bindTo->stripReferences();
    275         auto tyvar = open.find( typeInst->name );
     287        auto tyvar = open.find( *typeInst );
    276288        assert( tyvar != open.end() );
    277289        if ( ! tyVarCompatible( tyvar->second, target ) ) return false;
    278         if ( occurs( target, typeInst->name, *this ) ) return false;
    279 
    280         auto it = internal_lookup( typeInst->name );
     290        if ( occurs( target, *typeInst, *this ) ) return false;
     291
     292        auto it = internal_lookup( *typeInst );
    281293        if ( it != env.end() ) {
    282294                if ( it->bound ) {
     
    286298                        ptr<Type> newType = it->bound;
    287299                        reset_qualifiers( newType, typeInst->qualifiers );
    288                         if ( unifyInexact( 
    289                                         newType, target, *this, need, have, open, 
     300                        if ( unifyInexact(
     301                                        newType, target, *this, need, have, open,
    290302                                        widen & WidenMode{ it->allowWidening, true }, symtab, common ) ) {
    291303                                if ( common ) {
     
    300312                }
    301313        } else {
    302                 env.emplace_back( 
    303                         typeInst->name, target, widen.first && widen.second, data );
     314                env.emplace_back(
     315                        *typeInst, target, widen.first && widen.second, data );
    304316        }
    305317        return true;
    306318}
    307319
    308 bool TypeEnvironment::bindVarToVar( 
    309                 const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data, 
    310                 AssertionSet & need, AssertionSet & have, const OpenVarSet & open, 
    311                 WidenMode widen, const SymbolTable & symtab 
     320bool TypeEnvironment::bindVarToVar(
     321                const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data,
     322                AssertionSet & need, AssertionSet & have, const OpenVarSet & open,
     323                WidenMode widen, const SymbolTable & symtab
    312324) {
    313         auto c1 = internal_lookup( var1->name );
    314         auto c2 = internal_lookup( var2->name );
    315        
     325        auto c1 = internal_lookup( *var1 );
     326        auto c2 = internal_lookup( *var2 );
     327
    316328        // exit early if variables already bound together
    317329        if ( c1 != env.end() && c1 == c2 ) {
     
    326338        if ( c1 != env.end() ) {
    327339                if ( c1->bound ) {
    328                         if ( occurs( c1->bound, var2->name, *this ) ) return false;
     340                        if ( occurs( c1->bound, *var2, *this ) ) return false;
    329341                        type1 = c1->bound;
    330342                }
     
    333345        if ( c2 != env.end() ) {
    334346                if ( c2->bound ) {
    335                         if ( occurs( c2->bound, var1->name, *this ) ) return false;
     347                        if ( occurs( c2->bound, *var1, *this ) ) return false;
    336348                        type2 = c2->bound;
    337349                }
     
    371383        } else if ( c1 != env.end() ) {
    372384                // var2 unbound, add to env[c1]
    373                 c1->vars.emplace( var2->name );
     385                c1->vars.emplace( *var2 );
    374386                c1->allowWidening = widen1;
    375387                c1->data.isComplete |= data.isComplete;
    376388        } else if ( c2 != env.end() ) {
    377389                // var1 unbound, add to env[c2]
    378                 c2->vars.emplace( var1->name );
     390                c2->vars.emplace( *var1 );
    379391                c2->allowWidening = widen2;
    380392                c2->data.isComplete |= data.isComplete;
    381393        } else {
    382394                // neither var bound, create new class
    383                 env.emplace_back( var1->name, var2->name, widen1 && widen2, data );
     395                env.emplace_back( *var1, *var2, widen1 && widen2, data );
    384396        }
    385397
     
    396408}
    397409
    398 bool TypeEnvironment::mergeBound( 
     410bool TypeEnvironment::mergeBound(
    399411                EqvClass & to, const EqvClass & from, OpenVarSet & open, const SymbolTable & symtab ) {
    400412        if ( from.bound ) {
     
    406418                        AssertionSet need, have;
    407419
    408                         if ( unifyInexact( 
     420                        if ( unifyInexact(
    409421                                        toType, fromType, *this, need, have, open, widen, symtab, common ) ) {
    410422                                // unifies, set common type if necessary
     
    424436}
    425437
    426 bool TypeEnvironment::mergeClasses( 
     438bool TypeEnvironment::mergeClasses(
    427439        ClassList::iterator to, ClassList::iterator from, OpenVarSet & open, const SymbolTable & symtab
    428440) {
     
    445457}
    446458
    447 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const std::string & var ) {
     459TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const TypeInstType::TypeEnvKey & var ) {
    448460        for ( ClassList::iterator i = env.begin(); i != env.end(); ++i ) {
    449461                if ( i->vars.count( var ) ) return i;
Note: See TracChangeset for help on using the changeset viewer.