Changes in / [9af00d23:b8524ca]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/RenameVars.cc

    r9af00d23 rb8524ca  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:05:18 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Jun 20 17:39:00 2019
    13 // Update Count     : 8
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Apr 30 17:07:57 2019
     13// Update Count     : 7
    1414//
    1515
     
    1919#include <utility>                 // for pair
    2020
    21 #include "AST/Pass.hpp"
    22 #include "AST/Type.hpp"
    2321#include "Common/PassVisitor.h"
    24 #include "Common/ScopedMap.h"
    2522#include "Common/SemanticError.h"  // for SemanticError
    2623#include "RenameVars.h"
     
    3128
    3229namespace ResolvExpr {
     30        namespace {
     31                struct RenameVars {
     32                        RenameVars();
     33                        void reset();
    3334
    34 namespace {
    35         class RenamingData {
    36                 int level = 0;
    37                 int resetCount = 0;
    38                 ScopedMap< std::string, std::string > nameMap;
     35                        void previsit( TypeInstType * instType );
     36                        void previsit( Type * );
     37                        void postvisit( Type * );
    3938
    40         public:
    41                 void reset() {
    42                         level = 0;
    43                         ++resetCount;
     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 >() );
    4458                }
    4559
    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                         }
     60                void RenameVars::reset() {
     61                        level = 0;
     62                        resetCount++;
    5363                }
    5464
    55                 void openLevel( Type * type ) {
     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 ) {
    5674                        if ( ! type->forall.empty() ) {
    57                                 nameMap.beginScope();
     75                                // copies current name mapping into new mapping
     76                                mapStack.push_front( mapStack.front() );
    5877                                // renames all "forall" type names to `_${level}_${name}'
    5978                                for ( auto td : type->forall ) {
     
    6180                                        output << "_" << resetCount << "_" << level << "_" << td->name;
    6281                                        std::string newname( output.str() );
    63                                         nameMap[ td->get_name() ] = newname;
     82                                        mapStack.front()[ td->get_name() ] = newname;
    6483                                        td->name = newname;
    6584                                        // ditto for assertion names, the next level in
     
    7089                }
    7190
    72                 void closeLevel( Type * type ) {
    73                         if ( !type->forall.empty() ) {
    74                                 nameMap.endScope();
    75                         }
     91                void RenameVars::postvisit( Type * type ) {
     92                        // clears name mapping added by typeBefore()
     93                        if ( ! type->forall.empty() ) {
     94                                mapStack.pop_front();
     95                        } // if
    7696                }
     97        } // namespace
    7798
    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 
     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        }
    169105} // namespace ResolvExpr
    170106
Note: See TracChangeset for help on using the changeset viewer.