Changes in / [63238a4:3d56d15b]
- Location:
- src/ResolvExpr
- Files:
-
- 1 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r63238a4 r3d56d15b 1099 1099 argExpansions.emplace_back(); 1100 1100 auto& argE = argExpansions.back(); 1101 //argE.reserve( arg.alternatives.size() );1101 argE.reserve( arg.alternatives.size() ); 1102 1102 1103 1103 for ( const Alternative& actual : arg ) { -
src/ResolvExpr/CommonType.cc
r63238a4 r3d56d15b 24 24 #include "SynTree/Type.h" // for BasicType, BasicType::Kind::... 25 25 #include "SynTree/Visitor.h" // for Visitor 26 #include "Unify.h" // for unifyExact, WidenMode26 #include "Unify.h" // for unifyExact, bindVar, WidenMode 27 27 #include "typeops.h" // for isFtype 28 28 … … 238 238 AssertionSet need, have; 239 239 WidenMode widen( widenFirst, widenSecond ); 240 if ( entry != openVars.end() && ! env.bindVar(var, voidPointer->get_base(), entry->second, need, have, openVars, widen, indexer ) ) return;240 if ( entry != openVars.end() && ! bindVar(var, voidPointer->get_base(), entry->second, env, need, have, openVars, widen, indexer ) ) return; 241 241 } 242 242 } -
src/ResolvExpr/ExplodedActual.h
r63238a4 r3d56d15b 32 32 33 33 ExplodedActual() : env(), cost(Cost::zero), exprs() {} 34 34 35 ExplodedActual( const Alternative& actual, const SymTab::Indexer& indexer ); 35 ExplodedActual(ExplodedActual&&) = default;36 ExplodedActual& operator= (ExplodedActual&&) = default;37 36 }; 38 37 } -
src/ResolvExpr/Resolver.cc
r63238a4 r3d56d15b 582 582 583 583 // Make sure we don't widen any existing bindings 584 resultEnv.forbidWidening(); 585 584 for ( auto & i : resultEnv ) { 585 i.allowWidening = false; 586 } 587 586 588 // Find any unbound type variables 587 589 resultEnv.extractOpenVars( openVars ); -
src/ResolvExpr/TypeEnvironment.cc
r63238a4 r3d56d15b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:19:47 2015 11 // Last Modified By : Aaron B. Moss12 // Last Modified On : Mon Jun 18 11:58:00 201813 // Update Count : 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 17 12:23:36 2015 13 // Update Count : 3 14 14 // 15 15 … … 17 17 #include <algorithm> // for copy, set_intersection 18 18 #include <iterator> // for ostream_iterator, insert_iterator 19 #include <memory> // for unique_ptr20 19 #include <utility> // for pair, move 21 20 … … 23 22 #include "SynTree/Type.h" // for Type, FunctionType, Type::Fora... 24 23 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 25 #include "Tuples/Tuples.h" // for isTtype26 24 #include "TypeEnvironment.h" 27 #include "typeops.h" // for occurs28 #include "Unify.h" // for unifyInexact29 25 30 26 namespace ResolvExpr { … … 69 65 } 70 66 71 EqvClass::EqvClass( EqvClass &&other )72 : vars{std::move(other.vars)}, type{other.type},73 allowWidening{std::move(other.allowWidening)}, data{std::move(other.data)} {74 other.type = nullptr;75 }76 77 67 EqvClass &EqvClass::operator=( const EqvClass &other ) { 78 68 if ( this == &other ) return *this; … … 82 72 } 83 73 84 EqvClass &EqvClass::operator=( EqvClass &&other ) {85 if ( this == &other ) return *this;86 delete type;87 88 vars = std::move(other.vars);89 type = other.type;90 other.type = nullptr;91 allowWidening = std::move(other.allowWidening);92 data = std::move(other.data);93 94 return *this;95 }96 97 74 EqvClass::~EqvClass() { 98 75 delete type; 99 }100 101 void EqvClass::set_type( Type* ty ) {102 if ( ty == type ) return;103 delete type;104 type = ty;105 76 } 106 77 … … 121 92 const EqvClass* TypeEnvironment::lookup( const std::string &var ) const { 122 93 for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) { 123 if ( i->vars.find( var ) != i->vars.end() ) return &*i; 94 if ( i->vars.find( var ) != i->vars.end() ) { 95 /// std::cout << var << " is in class "; 96 /// i->print( std::cout ); 97 return &*i; 98 } 99 /// std::cout << var << " is not in class "; 100 /// i->print( std::cout ); 124 101 } // for 125 102 return nullptr; … … 139 116 } 140 117 118 void TypeEnvironment::add( const EqvClass &eqvClass ) { 119 filterOverlappingClasses( env, eqvClass ); 120 env.push_back( eqvClass ); 121 } 122 141 123 void TypeEnvironment::add( EqvClass &&eqvClass ) { 142 124 filterOverlappingClasses( env, eqvClass ); … … 149 131 newClass.vars.insert( (*i)->get_name() ); 150 132 newClass.data = TypeDecl::Data{ (*i) }; 151 env.push_back( std::move(newClass));133 env.push_back( newClass ); 152 134 } // for 153 135 } … … 163 145 // transition to TypeSubstitution 164 146 newClass.data = TypeDecl::Data{ TypeDecl::Dtype, false }; 165 add( std::move(newClass));147 add( newClass ); 166 148 } 167 149 } … … 170 152 for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) { 171 153 for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) { 154 /// std::cerr << "adding " << *theVar; 172 155 if ( theClass->type ) { 156 /// std::cerr << " bound to "; 157 /// theClass->type->print( std::cerr ); 158 /// std::cerr << std::endl; 173 159 sub.add( *theVar, theClass->type ); 174 160 } else if ( theVar != theClass->vars.begin() ) { 175 161 TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype ); 162 /// std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl; 176 163 sub.add( *theVar, newTypeInst ); 177 164 delete newTypeInst; … … 179 166 } // for 180 167 } // for 168 /// std::cerr << "input env is:" << std::endl; 169 /// print( std::cerr, 8 ); 170 /// std::cerr << "sub is:" << std::endl; 171 /// sub.print( std::cerr, 8 ); 181 172 sub.normalize(); 182 173 } … … 190 181 std::list< EqvClass >::iterator TypeEnvironment::internal_lookup( const std::string &var ) { 191 182 for ( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) { 192 if ( i->vars.count( var ) ) return i; 183 if ( i->vars.find( var ) == i->vars.end() ) { 184 return i; 185 } // if 193 186 } // for 194 187 return env.end(); … … 197 190 void TypeEnvironment::simpleCombine( const TypeEnvironment &second ) { 198 191 env.insert( env.end(), second.env.begin(), second.env.end() ); 192 } 193 194 void TypeEnvironment::combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ) { 195 TypeEnvironment secondCopy( second ); 196 for ( std::list< EqvClass >::iterator firstClass = env.begin(); firstClass != env.end(); ++firstClass ) { 197 EqvClass &newClass = *firstClass; 198 std::set< std::string > newVars; 199 for ( std::set< std::string >::const_iterator var = firstClass->vars.begin(); var != firstClass->vars.end(); ++var ) { 200 std::list< EqvClass >::iterator secondClass = secondCopy.internal_lookup( *var ); 201 if ( secondClass != secondCopy.env.end() ) { 202 newVars.insert( secondClass->vars.begin(), secondClass->vars.end() ); 203 if ( secondClass->type ) { 204 if ( newClass.type ) { 205 Type *newType = combineFunc( newClass.type, secondClass->type ); 206 delete newClass.type; 207 newClass.type = newType; 208 newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening; 209 } else { 210 newClass.type = secondClass->type->clone(); 211 newClass.allowWidening = secondClass->allowWidening; 212 } // if 213 } // if 214 secondCopy.env.erase( secondClass ); 215 } // if 216 } // for 217 newClass.vars.insert( newVars.begin(), newVars.end() ); 218 } // for 219 for ( std::list< EqvClass >::iterator secondClass = secondCopy.env.begin(); secondClass != secondCopy.env.end(); ++secondClass ) { 220 env.push_back( *secondClass ); 221 } // for 199 222 } 200 223 … … 218 241 } 219 242 220 bool isFtype( Type *type ) {221 if ( dynamic_cast< FunctionType* >( type ) ) {222 return true;223 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {224 return typeInst->get_isFtype();225 } // if226 return false;227 }228 229 bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {230 switch ( data.kind ) {231 case TypeDecl::Dtype:232 // to bind to an object type variable, the type must not be a function type.233 // if the type variable is specified to be a complete type then the incoming234 // type must also be complete235 // xxx - should this also check that type is not a tuple type and that it's not a ttype?236 return ! isFtype( type ) && (! data.isComplete || type->isComplete() );237 case TypeDecl::Ftype:238 return isFtype( type );239 case TypeDecl::Ttype:240 // ttype unifies with any tuple type241 return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );242 } // switch243 return false;244 }245 246 bool TypeEnvironment::bindVar( TypeInstType *typeInst, Type *bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {247 248 // remove references from other, so that type variables can only bind to value types249 bindTo = bindTo->stripReferences();250 OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );251 assert( tyvar != openVars.end() );252 if ( ! tyVarCompatible( tyvar->second, bindTo ) ) {253 return false;254 } // if255 if ( occurs( bindTo, typeInst->get_name(), *this ) ) {256 return false;257 } // if258 auto curClass = internal_lookup( typeInst->get_name() );259 if ( curClass != env.end() ) {260 if ( curClass->type ) {261 Type *common = 0;262 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to263 std::unique_ptr< Type > newType( curClass->type->clone() );264 newType->get_qualifiers() = typeInst->get_qualifiers();265 if ( unifyInexact( newType.get(), bindTo, *this, need, have, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {266 if ( common ) {267 common->get_qualifiers() = Type::Qualifiers{};268 curClass->set_type( common );269 } // if270 } else return false;271 } else {272 Type* newType = bindTo->clone();273 newType->get_qualifiers() = Type::Qualifiers{};274 curClass->set_type( newType );275 curClass->allowWidening = widenMode.widenFirst && widenMode.widenSecond;276 } // if277 } else {278 EqvClass newClass;279 newClass.vars.insert( typeInst->get_name() );280 newClass.type = bindTo->clone();281 newClass.type->get_qualifiers() = Type::Qualifiers();282 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;283 newClass.data = data;284 env.push_back( std::move(newClass) );285 } // if286 return true;287 }288 289 bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {290 291 auto class1 = internal_lookup( var1->get_name() );292 auto class2 = internal_lookup( var2->get_name() );293 294 // exit early if variables already bound together295 if ( class1 != env.end() && class1 == class2 ) {296 class1->allowWidening &= widenMode;297 return true;298 }299 300 bool widen1 = false, widen2 = false;301 const Type *type1 = nullptr, *type2 = nullptr;302 303 // check for existing bindings, perform occurs check304 if ( class1 != env.end() ) {305 if ( class1->type ) {306 if ( occurs( class1->type, var2->get_name(), *this ) ) return false;307 type1 = class1->type;308 } // if309 widen1 = widenMode.widenFirst && class1->allowWidening;310 } // if311 if ( class2 != env.end() ) {312 if ( class2->type ) {313 if ( occurs( class2->type, var1->get_name(), *this ) ) return false;314 type2 = class2->type;315 } // if316 widen2 = widenMode.widenSecond && class2->allowWidening;317 } // if318 319 if ( type1 && type2 ) {320 // both classes bound, merge if bound types can be unified321 std::unique_ptr<Type> newType1{ type1->clone() }, newType2{ type2->clone() };322 WidenMode newWidenMode{ widen1, widen2 };323 Type *common = 0;324 if ( unifyInexact( newType1.get(), newType2.get(), *this, need, have, openVars, newWidenMode, indexer, common ) ) {325 class1->vars.insert( class2->vars.begin(), class2->vars.end() );326 class1->allowWidening = widen1 && widen2;327 if ( common ) {328 common->get_qualifiers() = Type::Qualifiers{};329 class1->set_type( common );330 }331 env.erase( class2 );332 } else return false;333 } else if ( class1 != env.end() && class2 != env.end() ) {334 // both classes exist, at least one unbound, merge unconditionally335 if ( type1 ) {336 class1->vars.insert( class2->vars.begin(), class2->vars.end() );337 class1->allowWidening = widen1;338 env.erase( class2 );339 } else {340 class2->vars.insert( class1->vars.begin(), class1->vars.end() );341 class2->allowWidening = widen2;342 env.erase( class1 );343 } // if344 } else if ( class1 != env.end() ) {345 // var2 unbound, add to class1346 class1->vars.insert( var2->get_name() );347 class1->allowWidening = widen1;348 } else if ( class2 != env.end() ) {349 // var1 unbound, add to class2350 class2->vars.insert( var1->get_name() );351 class2->allowWidening = widen2;352 } else {353 // neither var bound, create new class354 EqvClass newClass;355 newClass.vars.insert( var1->get_name() );356 newClass.vars.insert( var2->get_name() );357 newClass.allowWidening = widen1 && widen2;358 newClass.data = data;359 env.push_back( std::move(newClass) );360 } // if361 return true;362 }363 364 void TypeEnvironment::forbidWidening() {365 for ( EqvClass& c : env ) c.allowWidening = false;366 }367 368 243 std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ) { 369 244 env.print( out ); -
src/ResolvExpr/TypeEnvironment.h
r63238a4 r3d56d15b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:24:58 2015 11 // Last Modified By : Aaron B. Moss12 // Last Modified On : Mon Jun 18 11:58:00 201813 // Update Count : 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:35:45 2017 13 // Update Count : 3 14 14 // 15 15 … … 21 21 #include <set> // for set 22 22 #include <string> // for string 23 #include <utility> // for move, swap24 25 #include "WidenMode.h" // for WidenMode26 23 27 24 #include "SynTree/Declaration.h" // for TypeDecl::Data, DeclarationWit... … … 80 77 EqvClass( const EqvClass &other ); 81 78 EqvClass( const EqvClass &other, const Type *ty ); 82 EqvClass( EqvClass &&other );83 79 EqvClass &operator=( const EqvClass &other ); 84 EqvClass &operator=( EqvClass &&other );85 80 ~EqvClass(); 86 81 void print( std::ostream &os, Indenter indent = {} ) const; 87 88 /// Takes ownership of `ty`, freeing old `type`89 void set_type(Type* ty);90 82 }; 91 83 … … 93 85 public: 94 86 const EqvClass* lookup( const std::string &var ) const; 95 private:87 void add( const EqvClass &eqvClass ); 96 88 void add( EqvClass &&eqvClass ); 97 public:98 89 void add( const Type::ForallList &tyDecls ); 99 90 void add( const TypeSubstitution & sub ); … … 103 94 bool isEmpty() const { return env.empty(); } 104 95 void print( std::ostream &os, Indenter indent = {} ) const; 105 //void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );96 void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ); 106 97 void simpleCombine( const TypeEnvironment &second ); 107 98 void extractOpenVars( OpenVarSet &openVars ) const; … … 112 103 void addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars ); 113 104 114 /// Binds the type class represented by `typeInst` to the type `bindTo`; will add 115 /// the class if needed. Returns false on failure. 116 bool bindVar( TypeInstType *typeInst, Type *bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 117 118 /// Binds the type classes represented by `var1` and `var2` together; will add 119 /// one or both classes if needed. Returns false on failure. 120 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 121 122 /// Disallows widening for all bindings in the environment 123 void forbidWidening(); 124 125 using iterator = std::list< EqvClass >::const_iterator; 126 iterator begin() const { return env.begin(); } 127 iterator end() const { return env.end(); } 128 105 typedef std::list< EqvClass >::iterator iterator; 106 iterator begin() { return env.begin(); } 107 iterator end() { return env.end(); } 108 typedef std::list< EqvClass >::const_iterator const_iterator; 109 const_iterator begin() const { return env.begin(); } 110 const_iterator end() const { return env.end(); } 129 111 private: 130 112 std::list< EqvClass > env; 131 132 113 std::list< EqvClass >::iterator internal_lookup( const std::string &var ); 133 114 }; -
src/ResolvExpr/Unify.cc
r63238a4 r3d56d15b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:27:10 2015 11 // Last Modified By : Aaron B. Moss12 // Last Modified On : Mon Jun 18 11:58:00 201813 // Update Count : 4 311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 16 16:22:54 2017 13 // Update Count : 42 14 14 // 15 15 … … 129 129 } 130 130 131 bool isFtype( Type *type ) { 132 if ( dynamic_cast< FunctionType* >( type ) ) { 133 return true; 134 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) { 135 return typeInst->get_isFtype(); 136 } // if 137 return false; 138 } 139 140 bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) { 141 switch ( data.kind ) { 142 case TypeDecl::Dtype: 143 // to bind to an object type variable, the type must not be a function type. 144 // if the type variable is specified to be a complete type then the incoming 145 // type must also be complete 146 // xxx - should this also check that type is not a tuple type and that it's not a ttype? 147 return ! isFtype( type ) && (! data.isComplete || type->isComplete() ); 148 case TypeDecl::Ftype: 149 return isFtype( type ); 150 case TypeDecl::Ttype: 151 // ttype unifies with any tuple type 152 return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type ); 153 } // switch 154 return false; 155 } 156 157 bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 158 // remove references from other, so that type variables can only bind to value types 159 other = other->stripReferences(); 160 OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() ); 161 assert( tyvar != openVars.end() ); 162 if ( ! tyVarCompatible( tyvar->second, other ) ) { 163 return false; 164 } // if 165 if ( occurs( other, typeInst->get_name(), env ) ) { 166 return false; 167 } // if 168 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) { 169 if ( curClass->type ) { 170 Type *common = 0; 171 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to 172 std::unique_ptr< Type > newType( curClass->type->clone() ); 173 newType->get_qualifiers() = typeInst->get_qualifiers(); 174 if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) { 175 if ( common ) { 176 common->get_qualifiers() = Type::Qualifiers(); 177 env.add( EqvClass{ *curClass, common } ); 178 } // if 179 return true; 180 } else { 181 return false; 182 } // if 183 } else { 184 EqvClass newClass { *curClass, other }; 185 newClass.type->get_qualifiers() = Type::Qualifiers(); 186 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond; 187 env.add( std::move(newClass) ); 188 } // if 189 } else { 190 EqvClass newClass; 191 newClass.vars.insert( typeInst->get_name() ); 192 newClass.type = other->clone(); 193 newClass.type->get_qualifiers() = Type::Qualifiers(); 194 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond; 195 newClass.data = data; 196 env.add( newClass ); 197 } // if 198 return true; 199 } 200 201 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 202 bool result = true; 203 const EqvClass *class1 = env.lookup( var1->get_name() ); 204 const EqvClass *class2 = env.lookup( var2->get_name() ); 205 bool widen1 = false, widen2 = false; 206 Type *type1 = nullptr, *type2 = nullptr; 207 208 if ( class1 ) { 209 if ( class1->type ) { 210 if ( occurs( class1->type, var2->get_name(), env ) ) { 211 return false; 212 } // if 213 type1 = class1->type->clone(); 214 } // if 215 widen1 = widenMode.widenFirst && class1->allowWidening; 216 } // if 217 if ( class2 ) { 218 if ( class2->type ) { 219 if ( occurs( class2->type, var1->get_name(), env ) ) { 220 return false; 221 } // if 222 type2 = class2->type->clone(); 223 } // if 224 widen2 = widenMode.widenSecond && class2->allowWidening; 225 } // if 226 227 if ( type1 && type2 ) { 228 // std::cerr << "has type1 && type2" << std::endl; 229 WidenMode newWidenMode ( widen1, widen2 ); 230 Type *common = 0; 231 if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) { 232 EqvClass newClass1 = *class1; 233 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() ); 234 newClass1.allowWidening = widen1 && widen2; 235 if ( common ) { 236 common->get_qualifiers() = Type::Qualifiers(); 237 delete newClass1.type; 238 newClass1.type = common; 239 } // if 240 env.add( std::move(newClass1) ); 241 } else { 242 result = false; 243 } // if 244 } else if ( class1 && class2 ) { 245 if ( type1 ) { 246 EqvClass newClass1 = *class1; 247 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() ); 248 newClass1.allowWidening = widen1; 249 env.add( std::move(newClass1) ); 250 } else { 251 EqvClass newClass2 = *class2; 252 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() ); 253 newClass2.allowWidening = widen2; 254 env.add( std::move(newClass2) ); 255 } // if 256 } else if ( class1 ) { 257 EqvClass newClass1 = *class1; 258 newClass1.vars.insert( var2->get_name() ); 259 newClass1.allowWidening = widen1; 260 env.add( std::move(newClass1) ); 261 } else if ( class2 ) { 262 EqvClass newClass2 = *class2; 263 newClass2.vars.insert( var1->get_name() ); 264 newClass2.allowWidening = widen2; 265 env.add( std::move(newClass2) ); 266 } else { 267 EqvClass newClass; 268 newClass.vars.insert( var1->get_name() ); 269 newClass.vars.insert( var2->get_name() ); 270 newClass.allowWidening = widen1 && widen2; 271 newClass.data = data; 272 env.add( newClass ); 273 } // if 274 delete type1; 275 delete type2; 276 return result; 277 } 278 131 279 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 132 280 OpenVarSet closedVars; … … 173 321 174 322 if ( isopen1 && isopen2 && entry1->second == entry2->second ) { 175 result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );323 result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 176 324 } else if ( isopen1 ) { 177 result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );325 result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 178 326 } else if ( isopen2 ) { // TODO: swap widenMode values in call, since type positions are flipped? 179 result = env.bindVar( var2, type1, entry2->second, needAssertions, haveAssertions, openVars, widenMode, indexer );327 result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 180 328 } else { 181 329 PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); -
src/ResolvExpr/Unify.h
r63238a4 r3d56d15b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 13:09:04 2015 11 // Last Modified By : Aaron B. Moss12 // Last Modified On : Mon Jun 18 11:58:00 201813 // Update Count : 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 23:09:34 2017 13 // Update Count : 3 14 14 // 15 15 … … 21 21 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Data 22 22 #include "TypeEnvironment.h" // for AssertionSet, OpenVarSet 23 #include "WidenMode.h" // for WidenMode24 23 25 24 class Type; … … 30 29 31 30 namespace ResolvExpr { 31 struct WidenMode { 32 WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {} 33 WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; } 34 WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; } 35 WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; } 36 WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; } 37 operator bool() { return widenFirst && widenSecond; } 38 39 bool widenFirst : 1, widenSecond : 1; 40 }; 41 42 bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 32 43 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ); 33 44 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType ); 34 45 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ); 35 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );36 46 37 47 template< typename Iterator1, typename Iterator2 >
Note: See TracChangeset
for help on using the changeset viewer.