Changes in / [b8524ca:9af00d23]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/RenameVars.cc
rb8524ca r9af00d23 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:05:18 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Apr 30 17:07:57201913 // Update Count : 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Jun 20 17:39:00 2019 13 // Update Count : 8 14 14 // 15 15 … … 19 19 #include <utility> // for pair 20 20 21 #include "AST/Pass.hpp" 22 #include "AST/Type.hpp" 21 23 #include "Common/PassVisitor.h" 24 #include "Common/ScopedMap.h" 22 25 #include "Common/SemanticError.h" // for SemanticError 23 26 #include "RenameVars.h" … … 28 31 29 32 namespace ResolvExpr { 30 namespace {31 struct RenameVars {32 RenameVars();33 void reset();34 33 35 void previsit( TypeInstType * instType ); 36 void previsit( Type * ); 37 void postvisit( Type * ); 34 namespace { 35 class RenamingData { 36 int level = 0; 37 int resetCount = 0; 38 ScopedMap< std::string, std::string > nameMap; 38 39 39 private: 40 int level, resetCount; 41 std::list< std::unordered_map< std::string, std::string > > mapStack; 42 }; 43 44 PassVisitor<RenameVars> global_renamer; 45 } // namespace 46 47 void renameTyVars( Type * t ) { 48 t->accept( global_renamer ); 49 } 50 51 void resetTyVarRenaming() { 52 global_renamer.pass.reset(); 53 } 54 55 namespace { 56 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 57 mapStack.push_front( std::unordered_map< std::string, std::string >() ); 40 public: 41 void reset() { 42 level = 0; 43 ++resetCount; 58 44 } 59 45 60 void RenameVars::reset() { 61 level = 0; 62 resetCount++; 46 using mapConstIterator = ScopedMap< std::string, std::string >::const_iterator; 47 48 void rename( TypeInstType * type ) { 49 mapConstIterator it = nameMap.find( type->name ); 50 if ( it != nameMap.end() ) { 51 type->name = it->second; 52 } 63 53 } 64 54 65 void RenameVars::previsit( TypeInstType * instType ) { 66 previsit( (Type *)instType ); 67 std::unordered_map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name ); 68 if ( i != mapStack.front().end() ) { 69 instType->name = i->second; 70 } // if 71 } 72 73 void RenameVars::previsit( Type * type ) { 55 void openLevel( Type * type ) { 74 56 if ( ! type->forall.empty() ) { 75 // copies current name mapping into new mapping 76 mapStack.push_front( mapStack.front() ); 57 nameMap.beginScope(); 77 58 // renames all "forall" type names to `_${level}_${name}' 78 59 for ( auto td : type->forall ) { … … 80 61 output << "_" << resetCount << "_" << level << "_" << td->name; 81 62 std::string newname( output.str() ); 82 mapStack.front()[ td->get_name() ] = newname;63 nameMap[ td->get_name() ] = newname; 83 64 td->name = newname; 84 65 // ditto for assertion names, the next level in … … 89 70 } 90 71 91 void RenameVars::postvisit( Type * type ) { 92 // clears name mapping added by typeBefore() 93 if ( ! type->forall.empty() ) { 94 mapStack.pop_front(); 95 } // if 72 void closeLevel( Type * type ) { 73 if ( !type->forall.empty() ) { 74 nameMap.endScope(); 75 } 96 76 } 97 } // namespace98 77 99 const ast::Type * renameTyVars( const ast::Type * t ) { 100 #warning unimplemented; make sure resetTyVarRenaming() updated when implemented 101 (void)t; 102 assert(false); 103 return t; 104 } 78 const ast::TypeInstType * rename( const ast::TypeInstType * type ) { 79 mapConstIterator it = nameMap.find( type->name ); 80 if ( it != nameMap.end() ) { 81 ast::TypeInstType * mutType = ast::mutate( type ); 82 mutType->name = it->second; 83 type = mutType; 84 } 85 return type; 86 } 87 88 template<typename NodeT> 89 const NodeT * openLevel( const NodeT * type ) { 90 if ( !type->forall.empty() ) { 91 nameMap.beginScope(); 92 // Load new names from this forall clause and perform renaming. 93 NodeT * mutType = ast::mutate( type ); 94 for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) { 95 std::ostringstream output; 96 output << "_" << resetCount << "_" << level << "_" << td->name; 97 std::string newname( output.str() ); 98 nameMap[ td->name ] = newname; 99 ++level; 100 101 ast::TypeDecl * decl = ast::mutate( td.get() ); 102 decl->name = newname; 103 td = decl; 104 } 105 } 106 return type; 107 } 108 109 template<typename NodeT> 110 const NodeT * closeLevel( const NodeT * type ) { 111 if ( !type->forall.empty() ) { 112 nameMap.endScope(); 113 } 114 return type; 115 } 116 }; 117 118 // Global State: 119 RenamingData renaming; 120 121 struct RenameVars { 122 void previsit( TypeInstType * instType ) { 123 renaming.openLevel( (Type*)instType ); 124 renaming.rename( instType ); 125 } 126 void previsit( Type * type ) { 127 renaming.openLevel( type ); 128 } 129 void postvisit( Type * type ) { 130 renaming.closeLevel( type ); 131 } 132 133 const ast::FunctionType * previsit( const ast::FunctionType * type ) { 134 return renaming.openLevel( type ); 135 } 136 const ast::StructInstType * previsit( const ast::StructInstType * type ) { 137 return renaming.openLevel( type ); 138 } 139 const ast::UnionInstType * previsit( const ast::UnionInstType * type ) { 140 return renaming.openLevel( type ); 141 } 142 const ast::TraitInstType * previsit( const ast::TraitInstType * type ) { 143 return renaming.openLevel( type ); 144 } 145 const ast::TypeInstType * previsit( const ast::TypeInstType * type ) { 146 return renaming.rename( renaming.openLevel( type ) ); 147 } 148 const ast::ParameterizedType * postvisit( const ast::ParameterizedType * type ) { 149 return renaming.closeLevel( type ); 150 } 151 }; 152 153 } // namespace 154 155 void renameTyVars( Type * t ) { 156 PassVisitor<RenameVars> renamer; 157 t->accept( renamer ); 158 } 159 160 const ast::Type * renameTyVars( const ast::Type * t ) { 161 ast::Pass<RenameVars> renamer; 162 return t->accept( renamer ); 163 } 164 165 void resetTyVarRenaming() { 166 renaming.reset(); 167 } 168 105 169 } // namespace ResolvExpr 106 170
Note: See TracChangeset
for help on using the changeset viewer.