Changeset 41cde266 for src/AST/TypeEnvironment.cpp
- Timestamp:
- Dec 17, 2020, 4:18:23 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 089b1a9, f4f79dd
- Parents:
- c5a98f3 (diff), 68a867ee (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/TypeEnvironment.cpp
rc5a98f3 r41cde266 52 52 for ( const auto & i : open ) { 53 53 if ( first ) { first = false; } else { out << ' '; } 54 out << i.first << "(" << i.second << ")";54 out << i.first.typeString() << "(" << i.second << ")"; 55 55 } 56 56 } … … 62 62 if(first) first = false; 63 63 else out << " "; 64 if( deterministic_output && isUnboundType(var) ) out << "[unbound]"; 65 else out << var; 64 65 if( deterministic_output ) out << "[unbound]"; 66 else out << "_" << var.formal_usage << "_" << var.expr_id << "_"; 67 68 out << var.base->name; 66 69 } 67 70 out << ")"; … … 79 82 } 80 83 81 const EqvClass * TypeEnvironment::lookup( const std::string& var ) const {84 const EqvClass * TypeEnvironment::lookup( const TypeInstType::TypeEnvKey & var ) const { 82 85 for ( ClassList::const_iterator i = env.begin(); i != env.end(); ++i ) { 83 86 if ( i->vars.find( var ) != i->vars.end() ) return &*i; … … 106 109 107 110 void TypeEnvironment::add( const FunctionType::ForallList & tyDecls ) { 108 for ( const TypeDecl *tyDecl : tyDecls ) {111 for ( auto & tyDecl : tyDecls ) { 109 112 env.emplace_back( tyDecl ); 110 113 } … … 119 122 void TypeEnvironment::writeToSubstitution( TypeSubstitution & sub ) const { 120 123 for ( const auto & clz : env ) { 121 std::string clzRep; 124 TypeInstType::TypeEnvKey clzRep; 125 bool first = true; 122 126 for ( const auto & var : clz.vars ) { 123 127 if ( clz.bound ) { 124 128 sub.add( var, clz.bound ); 125 } else if ( clzRep.empty()) {129 } else if ( first ) { 126 130 clzRep = var; 131 first = false; 127 132 } else { 128 sub.add( var, new TypeInstType{ clzRep , clz.data.kind} );133 sub.add( var, new TypeInstType{ clzRep } ); 129 134 } 130 135 } … … 141 146 struct Occurs : public ast::WithVisitorRef<Occurs> { 142 147 bool result; 143 std:: set< std::string> vars;148 std::unordered_set< TypeInstType::TypeEnvKey > vars; 144 149 const TypeEnvironment & tenv; 145 150 146 Occurs( const std::string& var, const TypeEnvironment & env )151 Occurs( const TypeInstType::TypeEnvKey & var, const TypeEnvironment & env ) 147 152 : result( false ), vars(), tenv( env ) { 148 153 if ( const EqvClass * clz = tenv.lookup( var ) ) { … … 154 159 155 160 void previsit( const TypeInstType * typeInst ) { 156 if ( vars.count( typeInst->name) ) {161 if ( vars.count( *typeInst ) ) { 157 162 result = true; 158 } else if ( const EqvClass * clz = tenv.lookup( typeInst->name) ) {163 } else if ( const EqvClass * clz = tenv.lookup( *typeInst ) ) { 159 164 if ( clz->bound ) { 160 165 clz->bound->accept( *visitor ); … … 165 170 166 171 /// true if `var` occurs in `ty` under `env` 167 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 ) { 168 173 Pass<Occurs> occur{ var, env }; 169 174 maybe_accept( ty, occur ); … … 280 285 // remove references from bound type, so that type variables can only bind to value types 281 286 ptr<Type> target = bindTo->stripReferences(); 282 auto tyvar = open.find( typeInst->name);287 auto tyvar = open.find( *typeInst ); 283 288 assert( tyvar != open.end() ); 284 289 if ( ! tyVarCompatible( tyvar->second, target ) ) return false; 285 if ( occurs( target, typeInst->name, *this ) ) return false;286 287 auto it = internal_lookup( typeInst->name);290 if ( occurs( target, *typeInst, *this ) ) return false; 291 292 auto it = internal_lookup( *typeInst ); 288 293 if ( it != env.end() ) { 289 294 if ( it->bound ) { … … 308 313 } else { 309 314 env.emplace_back( 310 typeInst->name, target, widen.first && widen.second, data );315 *typeInst, target, widen.first && widen.second, data ); 311 316 } 312 317 return true; … … 318 323 WidenMode widen, const SymbolTable & symtab 319 324 ) { 320 auto c1 = internal_lookup( var1->name);321 auto c2 = internal_lookup( var2->name);325 auto c1 = internal_lookup( *var1 ); 326 auto c2 = internal_lookup( *var2 ); 322 327 323 328 // exit early if variables already bound together … … 333 338 if ( c1 != env.end() ) { 334 339 if ( c1->bound ) { 335 if ( occurs( c1->bound, var2->name, *this ) ) return false;340 if ( occurs( c1->bound, *var2, *this ) ) return false; 336 341 type1 = c1->bound; 337 342 } … … 340 345 if ( c2 != env.end() ) { 341 346 if ( c2->bound ) { 342 if ( occurs( c2->bound, var1->name, *this ) ) return false;347 if ( occurs( c2->bound, *var1, *this ) ) return false; 343 348 type2 = c2->bound; 344 349 } … … 378 383 } else if ( c1 != env.end() ) { 379 384 // var2 unbound, add to env[c1] 380 c1->vars.emplace( var2->name);385 c1->vars.emplace( *var2 ); 381 386 c1->allowWidening = widen1; 382 387 c1->data.isComplete |= data.isComplete; 383 388 } else if ( c2 != env.end() ) { 384 389 // var1 unbound, add to env[c2] 385 c2->vars.emplace( var1->name);390 c2->vars.emplace( *var1 ); 386 391 c2->allowWidening = widen2; 387 392 c2->data.isComplete |= data.isComplete; 388 393 } else { 389 394 // neither var bound, create new class 390 env.emplace_back( var1->name, var2->name, widen1 && widen2, data );395 env.emplace_back( *var1, *var2, widen1 && widen2, data ); 391 396 } 392 397 … … 452 457 } 453 458 454 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const std::string& var ) {459 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const TypeInstType::TypeEnvKey & var ) { 455 460 for ( ClassList::iterator i = env.begin(); i != env.end(); ++i ) { 456 461 if ( i->vars.count( var ) ) return i;
Note: See TracChangeset
for help on using the changeset viewer.