source: src/ResolvExpr/RenameVars.cc @ 0a9b5c1

Last change on this file since 0a9b5c1 was 0bd3faf, checked in by Andrew Beach <ajbeach@…>, 12 months ago

Removed forward declarations missed in the BaseSyntaxNode? removal. Removed code and modified names to support two versions of the ast.

  • Property mode set to 100644
File size: 4.1 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/ScopedMap.h"
24#include "Common/SemanticError.h"  // for SemanticError
25#include "RenameVars.h"
26
27#include "AST/Copy.hpp"
28
29namespace ResolvExpr {
30
31namespace {
32        class RenamingData {
33                int level = 0;
34                int resetCount = 0;
35
36                int next_expr_id = 1;
37                int next_usage_id = 1;
38                ScopedMap< std::string, std::string > nameMap;
39                ScopedMap< std::string, ast::TypeEnvKey > idMap;
40        public:
41                void reset() {
42                        level = 0;
43                        ++resetCount;
44                }
45
46                void nextUsage() {
47                        ++next_usage_id;
48                }
49
50                const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
51                        auto it = idMap.find( type->name );
52                        if ( it == idMap.end() ) return type;
53
54                        // Unconditionally mutate because map will *always* have different name.
55                        ast::TypeInstType * mut = ast::shallowCopy( type );
56                        // Reconcile base node since some copies might have been made.
57                        mut->base = it->second.base;
58                        mut->formal_usage = it->second.formal_usage;
59                        mut->expr_id = it->second.expr_id;
60                        return mut;
61                }
62
63                const ast::FunctionType * openLevel( const ast::FunctionType * type, RenameMode mode ) {
64                        if ( type->forall.empty() ) return type;
65                        idMap.beginScope();
66
67                        // Load new names from this forall clause and perform renaming.
68                        auto mutType = ast::shallowCopy( type );
69                        // assert( type == mutType && "mutated type must be unique from ForallSubstitutor" );
70                        for ( auto & td : mutType->forall ) {
71                                auto mut = ast::shallowCopy( td.get() );
72                                // assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" );
73
74                                if (mode == GEN_EXPR_ID) {
75                                        mut->expr_id = next_expr_id;
76                                        mut->formal_usage = -1;
77                                        ++next_expr_id;
78                                }
79                                else if (mode == GEN_USAGE) {
80                                        assertf(mut->expr_id, "unfilled expression id in generating candidate type");
81                                        mut->formal_usage = next_usage_id;
82                                }
83                                else {
84                                        assert(false);
85                                }
86                                idMap[ td->name ] = ast::TypeEnvKey( *mut );
87
88                                td = mut;
89                        }
90
91                        return mutType;
92                }
93
94                void closeLevel( const ast::FunctionType * type ) {
95                        if ( type->forall.empty() ) return;
96                        idMap.endScope();
97                }
98        };
99
100        // Global State:
101        RenamingData renaming;
102
103        struct RenameVars final : public ast::PureVisitor /*: public ast::WithForallSubstitutor*/ {
104                RenameMode mode;
105
106                const ast::FunctionType * previsit( const ast::FunctionType * type ) {
107                        return renaming.openLevel( type, mode );
108                }
109
110                /*
111                const ast::StructInstType * previsit( const ast::StructInstType * type ) {
112                        return renaming.openLevel( type );
113                }
114                const ast::UnionInstType * previsit( const ast::UnionInstType * type ) {
115                        return renaming.openLevel( type );
116                }
117                const ast::TraitInstType * previsit( const ast::TraitInstType * type ) {
118                        return renaming.openLevel( type );
119                }
120                */
121
122                const ast::TypeInstType * previsit( const ast::TypeInstType * type ) {
123                        if (mode == GEN_USAGE && !type->formal_usage) return type; // do not rename an actual type
124                        return renaming.rename( type );
125                }
126                void postvisit( const ast::FunctionType * type ) {
127                        renaming.closeLevel( type );
128                }
129        };
130
131} // namespace
132
133const ast::Type * renameTyVars( const ast::Type * t, RenameMode mode, bool reset ) {
134        ast::Pass<RenameVars> renamer;
135        renamer.core.mode = mode;
136        if (mode == GEN_USAGE && reset) {
137                renaming.nextUsage();
138        }
139        return t->accept( renamer );
140}
141
142void resetTyVarRenaming() {
143        renaming.reset();
144        renaming.nextUsage();
145}
146
147} // namespace ResolvExpr
148
149// Local Variables: //
150// tab-width: 4 //
151// mode: c++ //
152// compile-command: "make install" //
153// End: //
Note: See TracBrowser for help on using the repository browser.