Changeset eff03a94 for src/SynTree/TypeSubstitution.cc
- Timestamp:
- Jul 20, 2018, 2:13:20 PM (5 years ago)
- Branches:
- new-env
- Children:
- f89a111
- Parents:
- d318a18
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SynTree/TypeSubstitution.cc
rd318a18 reff03a94 14 14 // 15 15 16 #include <ostream> // for ostream, basic_ostream, operator<<, endl 17 18 #include "Type.h" // for TypeInstType, Type, StructInstType, UnionInstType 16 #include <algorithm> // for find 17 #include <ostream> // for ostream, basic_ostream, operator<<, endl 18 19 #include "Type.h" // for TypeInstType, Type, StructInstType, UnionInstType 19 20 #include "TypeSubstitution.h" 20 21 … … 59 60 60 61 // break on not in substitution set 61 if ( i == typeEnv.end() ) return 0;62 if ( i == typeEnv.end() ) return nullptr; 62 63 63 64 // attempt to transitively follow TypeInstType links. 65 std::vector<std::string> equivNames{ formalType }; 64 66 while ( TypeInstType *actualType = dynamic_cast< TypeInstType* >( i->second ) ) { 65 67 const std::string& typeName = actualType->get_name(); 66 68 67 69 // break cycles in the transitive follow 68 if ( formalType == typeName ) break; 69 70 // Look for the type this maps to, returning previous mapping if none-such 70 if ( std::find( equivNames.begin(), equivNames.end(), typeName ) != equivNames.end() ) { 71 break; 72 } 73 equivNames.emplace_back( typeName ); 74 75 // Look for the type this maps to, returning previous mapping if none such 71 76 i = typeEnv.find( typeName ); 72 77 if ( i == typeEnv.end() ) return actualType; 73 78 } 79 74 80 75 81 // return type from substitution set … … 132 138 return inst; 133 139 } else { 134 // c ut off infinite loop for the case where a type is bound to itself.135 // Note: this does not prevent cycles in the general case, so it may be necessary to do something more sophisticated here.136 // TODO: investigate preventing type variables from being bound to themselves in the first place. 140 // clear equivalent variables on exit 141 auto guard = makeFuncGuard( [&]() { equivVars.clear(); } ); 142 137 143 if ( TypeInstType * replacement = dynamic_cast< TypeInstType * >( i->second ) ) { 138 if ( inst->name == replacement->name ) { 139 return inst; 140 } 141 } 144 // cut off infinite loop if type is bound to itself (possibly transitively) 145 equivVars.push_back( inst ); 146 auto equiv = std::find_if( equivVars.begin(), equivVars.end(), [&]( TypeInstType* e ) { 147 return e->name == replacement->name; 148 } ); 149 if ( equiv != equivVars.end() ) return *equiv; 150 } 151 142 152 // std::cerr << "found " << inst->name << ", replacing with " << i->second << std::endl; 143 153 subCount++;
Note: See TracChangeset
for help on using the changeset viewer.