source: src/ResolvExpr/RenameVars.cc @ 4e13e2a

arm-ehjacob/cs343-translationnew-astnew-ast-unique-expr
Last change on this file since 4e13e2a was 4e13e2a, checked in by Thierry Delisle <tdelisle@…>, 2 years ago

Added setting of result in Comma expression.
Added asserts in candidate finder to catch null pointers earlier.
ForAll? substituter now properly uses ShallowCopy?.
Added missing makefile.in

  • Property mode set to 100644
File size: 5.4 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                template<typename NodeT>
96                const NodeT * openLevel( const NodeT * type ) {
97                        if ( type->forall.empty() ) return type;
98
99                        nameMap.beginScope();
100
101                        // Load new names from this forall clause and perform renaming.
102                        NodeT * mutType = ast::mutate( type );
103                        assert( type == mutType && "mutated type must be unique from ForallSubstitutor" );
104                        for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) {
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::ParameterizedType * 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                const ast::StructInstType * previsit( const ast::StructInstType * type ) {
152                        return renaming.openLevel( type );
153                }
154                const ast::UnionInstType * previsit( const ast::UnionInstType * type ) {
155                        return renaming.openLevel( type );
156                }
157                const ast::TraitInstType * previsit( const ast::TraitInstType * type ) {
158                        return renaming.openLevel( type );
159                }
160                const ast::TypeInstType * previsit( const ast::TypeInstType * type ) {
161                        return renaming.rename( renaming.openLevel( type ) );
162                }
163                void postvisit( const ast::ParameterizedType * type ) {
164                        renaming.closeLevel( type );
165                }
166        };
167
168} // namespace
169
170void renameTyVars( Type * t ) {
171        PassVisitor<RenameVars_old> renamer;
172        t->accept( renamer );
173}
174
175const ast::Type * renameTyVars( const ast::Type * t ) {
176        ast::Type *tc = ast::deepCopy(t);
177        ast::Pass<RenameVars_new> renamer;
178//      return t->accept( renamer );
179        return tc->accept( renamer );
180}
181
182void resetTyVarRenaming() {
183        renaming.reset();
184}
185
186} // namespace ResolvExpr
187
188// Local Variables: //
189// tab-width: 4 //
190// mode: c++ //
191// compile-command: "make install" //
192// End: //
Note: See TracBrowser for help on using the repository browser.