source: src/ResolvExpr/RenameVars.cc @ 361bf01

arm-ehjacob/cs343-translationnew-ast-unique-expr
Last change on this file since 361bf01 was 361bf01, checked in by Fangren Yu <f37yu@…>, 10 months ago

remove ParameterizedType? and put content into FunctionType?

  • Property mode set to 100644
File size: 5.5 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/ForallSubstitutionTable.hpp"
22#include "AST/Pass.hpp"
23#include "AST/Type.hpp"
24#include "Common/PassVisitor.h"
25#include "Common/ScopedMap.h"
26#include "Common/SemanticError.h"  // for SemanticError
27#include "RenameVars.h"
28#include "SynTree/Declaration.h"   // for DeclarationWithType, TypeDecl, Dec...
29#include "SynTree/Expression.h"    // for Expression
30#include "SynTree/Type.h"          // for Type, TypeInstType, TraitInstType
31#include "SynTree/Visitor.h"       // for acceptAll, maybeAccept
32
33#include "AST/Copy.hpp"
34
35namespace ResolvExpr {
36
37namespace {
38        class RenamingData {
39                int level = 0;
40                int resetCount = 0;
41                ScopedMap< std::string, std::string > nameMap;
42        public:
43                ast::ForallSubstitutionTable subs;
44
45                void reset() {
46                        level = 0;
47                        ++resetCount;
48                }
49
50                void rename( TypeInstType * type ) {
51                        auto it = nameMap.find( type->name );
52                        if ( it != nameMap.end() ) {
53                                type->name = it->second;
54                        }
55                }
56
57                void openLevel( Type * type ) {
58                        if ( ! type->forall.empty() ) {
59                                nameMap.beginScope();
60                                // renames all "forall" type names to `_${level}_${name}'
61                                for ( auto td : type->forall ) {
62                                        std::ostringstream output;
63                                        output << "_" << resetCount << "_" << level << "_" << td->name;
64                                        std::string newname( output.str() );
65                                        nameMap[ td->get_name() ] = newname;
66                                        td->name = newname;
67                                        // ditto for assertion names, the next level in
68                                        level++;
69                                }
70                        }
71                }
72
73                void closeLevel( Type * type ) {
74                        if ( !type->forall.empty() ) {
75                                nameMap.endScope();
76                        }
77                }
78
79                const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
80                        // re-linking of base type handled by WithForallSubstitutor
81
82                        // rename
83                        auto it = nameMap.find( type->name );
84                        if ( it != nameMap.end() ) {
85                                // unconditionally mutate because map will *always* have different name,
86                                // if this mutates, will *always* have been mutated by ForallSubstitutor above
87                                ast::TypeInstType * mut = ast::mutate( type );
88                                mut->name = it->second;
89                    type = mut;
90                        }
91
92                        return type;
93                }
94
95                const ast::FunctionType * openLevel( const ast::FunctionType * type ) {
96                        if ( type->forall.empty() ) return type;
97
98                        nameMap.beginScope();
99
100                        // Load new names from this forall clause and perform renaming.
101                        auto mutType = ast::mutate( type );
102                        assert( type == mutType && "mutated type must be unique from ForallSubstitutor" );
103                        for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) {
104                                assertf(dynamic_cast<ast::FunctionType *>(mutType), "renaming vars in non-function type");
105                                std::ostringstream output;
106                                output << "_" << resetCount << "_" << level << "_" << td->name;
107                                std::string newname =  output.str();
108                                nameMap[ td->name ] = newname;
109                                ++level;
110
111                                ast::TypeDecl * mutDecl = ast::mutate( td.get() );
112                                assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" );
113                                mutDecl->name = newname;
114                                // assertion above means `td = mutDecl;` is unnecessary
115                        }
116                        // assertion above means `type = mutType;` is unnecessary
117
118                        return type;
119                }
120
121                void closeLevel( const ast::FunctionType * type ) {
122                        if ( type->forall.empty() ) return;
123
124                        nameMap.endScope();
125                }
126        };
127
128        // Global State:
129        RenamingData renaming;
130
131        struct RenameVars_old {
132                void previsit( TypeInstType * instType ) {
133                        renaming.openLevel( (Type*)instType );
134                        renaming.rename( instType );
135                }
136                void previsit( Type * type ) {
137                        renaming.openLevel( type );
138                }
139                void postvisit( Type * type ) {
140                        renaming.closeLevel( type );
141                }
142        };
143
144        struct RenameVars_new /*: public ast::WithForallSubstitutor*/ {
145                #warning when old RenameVars goes away, replace hack below with global pass inheriting from WithForallSubstitutor
146                ast::ForallSubstitutionTable & subs = renaming.subs;
147
148                const ast::FunctionType * previsit( const ast::FunctionType * type ) {
149                        return renaming.openLevel( type );
150                }
151
152                /*
153                const ast::StructInstType * previsit( const ast::StructInstType * type ) {
154                        return renaming.openLevel( type );
155                }
156                const ast::UnionInstType * previsit( const ast::UnionInstType * type ) {
157                        return renaming.openLevel( type );
158                }
159                const ast::TraitInstType * previsit( const ast::TraitInstType * type ) {
160                        return renaming.openLevel( type );
161                }
162                */
163
164                const ast::TypeInstType * previsit( const ast::TypeInstType * type ) {
165                        return renaming.rename( type );
166                }
167                void postvisit( const ast::FunctionType * type ) {
168                        renaming.closeLevel( type );
169                }
170        };
171
172} // namespace
173
174void renameTyVars( Type * t ) {
175        PassVisitor<RenameVars_old> renamer;
176        t->accept( renamer );
177}
178
179const ast::Type * renameTyVars( const ast::Type * t ) {
180        ast::Type *tc = ast::deepCopy(t);
181        ast::Pass<RenameVars_new> renamer;
182//      return t->accept( renamer );
183        return tc->accept( renamer );
184}
185
186void resetTyVarRenaming() {
187        renaming.reset();
188}
189
190} // namespace ResolvExpr
191
192// Local Variables: //
193// tab-width: 4 //
194// mode: c++ //
195// compile-command: "make install" //
196// End: //
Note: See TracBrowser for help on using the repository browser.