Changes in / [b8524ca:9af00d23]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/RenameVars.cc

    rb8524ca r9af00d23  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:05:18 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr 30 17:07:57 2019
    13 // Update Count     : 7
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Jun 20 17:39:00 2019
     13// Update Count     : 8
    1414//
    1515
     
    1919#include <utility>                 // for pair
    2020
     21#include "AST/Pass.hpp"
     22#include "AST/Type.hpp"
    2123#include "Common/PassVisitor.h"
     24#include "Common/ScopedMap.h"
    2225#include "Common/SemanticError.h"  // for SemanticError
    2326#include "RenameVars.h"
     
    2831
    2932namespace ResolvExpr {
    30         namespace {
    31                 struct RenameVars {
    32                         RenameVars();
    33                         void reset();
    3433
    35                         void previsit( TypeInstType * instType );
    36                         void previsit( Type * );
    37                         void postvisit( Type * );
     34namespace {
     35        class RenamingData {
     36                int level = 0;
     37                int resetCount = 0;
     38                ScopedMap< std::string, std::string > nameMap;
    3839
    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;
    5844                }
    5945
    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                        }
    6353                }
    6454
    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 ) {
    7456                        if ( ! type->forall.empty() ) {
    75                                 // copies current name mapping into new mapping
    76                                 mapStack.push_front( mapStack.front() );
     57                                nameMap.beginScope();
    7758                                // renames all "forall" type names to `_${level}_${name}'
    7859                                for ( auto td : type->forall ) {
     
    8061                                        output << "_" << resetCount << "_" << level << "_" << td->name;
    8162                                        std::string newname( output.str() );
    82                                         mapStack.front()[ td->get_name() ] = newname;
     63                                        nameMap[ td->get_name() ] = newname;
    8364                                        td->name = newname;
    8465                                        // ditto for assertion names, the next level in
     
    8970                }
    9071
    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                        }
    9676                }
    97         } // namespace
    9877
    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
     155void renameTyVars( Type * t ) {
     156        PassVisitor<RenameVars> renamer;
     157        t->accept( renamer );
     158}
     159
     160const ast::Type * renameTyVars( const ast::Type * t ) {
     161        ast::Pass<RenameVars> renamer;
     162        return t->accept( renamer );
     163}
     164
     165void resetTyVarRenaming() {
     166        renaming.reset();
     167}
     168
    105169} // namespace ResolvExpr
    106170
Note: See TracChangeset for help on using the changeset viewer.