source: src/ResolvExpr/RenameVars.cc @ dc33b5b

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since dc33b5b was f5edcb4, checked in by Andrew Beach <ajbeach@…>, 5 years ago

RenameVars? needed a rather significant rework for the new AST.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// RenameVars.cc --
8//
9// Author           : Richard C. Bilson
10// 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
14//
15
16#include <ext/alloc_traits.h>      // for __alloc_traits<>::value_type
17#include <memory>                  // for allocator_traits<>::value_type
18#include <sstream>                 // for operator<<, basic_ostream, ostring...
19#include <utility>                 // for pair
20
21#include "AST/Pass.hpp"
22#include "AST/Type.hpp"
23#include "Common/PassVisitor.h"
24#include "Common/ScopedMap.h"
25#include "Common/SemanticError.h"  // for SemanticError
26#include "RenameVars.h"
27#include "SynTree/Declaration.h"   // for DeclarationWithType, TypeDecl, Dec...
28#include "SynTree/Expression.h"    // for Expression
29#include "SynTree/Type.h"          // for Type, TypeInstType, TraitInstType
30#include "SynTree/Visitor.h"       // for acceptAll, maybeAccept
31
32namespace ResolvExpr {
33
34namespace {
35        class RenamingData {
36                int level = 0;
37                int resetCount = 0;
38                ScopedMap< std::string, std::string > nameMap;
39
40        public:
41                void reset() {
42                        level = 0;
43                        ++resetCount;
44                }
45
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                        }
53                }
54
55                void openLevel( Type * type ) {
56                        if ( ! type->forall.empty() ) {
57                                nameMap.beginScope();
58                                // renames all "forall" type names to `_${level}_${name}'
59                                for ( auto td : type->forall ) {
60                                        std::ostringstream output;
61                                        output << "_" << resetCount << "_" << level << "_" << td->name;
62                                        std::string newname( output.str() );
63                                        nameMap[ td->get_name() ] = newname;
64                                        td->name = newname;
65                                        // ditto for assertion names, the next level in
66                                        level++;
67                                        // acceptAll( td->assertions, *this );
68                                } // for
69                        } // if
70                }
71
72                void closeLevel( Type * type ) {
73                        if ( !type->forall.empty() ) {
74                                nameMap.endScope();
75                        }
76                }
77
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
169} // namespace ResolvExpr
170
171// Local Variables: //
172// tab-width: 4 //
173// mode: c++ //
174// compile-command: "make install" //
175// End: //
Note: See TracBrowser for help on using the repository browser.