source: src/AST/TypeSubstitution.hpp@ 4073b16

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 4073b16 was 172d9342, checked in by Michael Brooks <mlbrooks@…>, 6 years ago

added old-to-new conversion for TypeSubstitution, within a framework for expressions

  • Property mode set to 100644
File size: 7.2 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// TypeSubstitution.h --
8//
9// Author : Richard C. Bilson
10// Created On : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Tue Apr 30 22:52:47 2019
13// Update Count : 9
14//
15
16#pragma once
17
18#include <cassert> // for assert
19#include <list> // for list<>::iterator, _List_iterator
20#include <unordered_map>
21#include <unordered_set>
22#include <string> // for string, operator!=
23#include <utility> // for pair
24
25#include "Fwd.hpp" // for UniqueId
26#include "ParseNode.hpp"
27#include "Type.hpp" // for ptr<Type>
28#include "Common/SemanticError.h" // for SemanticError
29#include "Visitor.hpp"
30#include "Decl.hpp"
31#include "Expr.hpp"
32
33namespace ast {
34
35class TypeSubstitution : public Node {
36 public:
37 TypeSubstitution();
38 template< typename FormalIterator, typename ActualIterator >
39 TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
40 TypeSubstitution( const TypeSubstitution &other );
41 virtual ~TypeSubstitution();
42
43 TypeSubstitution &operator=( const TypeSubstitution &other );
44
45 template< typename SynTreeClass > int apply( SynTreeClass *&input ) const;
46 template< typename SynTreeClass > int applyFree( SynTreeClass *&input ) const;
47
48 void add( std::string formalType, const Type *actualType );
49 void add( const TypeSubstitution &other );
50 void remove( std::string formalType );
51 const Type *lookup( std::string formalType ) const;
52 bool empty() const;
53
54 void addVar( std::string formalExpr, const Expr *actualExpr );
55
56 template< typename FormalIterator, typename ActualIterator >
57 void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
58
59 /// create a new TypeSubstitution using bindings from env containing all of the type variables in expr
60 static TypeSubstitution * newFromExpr( const Expr * expr, const TypeSubstitution * env );
61
62 void normalize();
63
64 const TypeSubstitution * accept( Visitor & v ) const override { return v.visit( this ); }
65
66 TypeSubstitution * clone() const override { return new TypeSubstitution( *this ); }
67
68 private:
69
70 // Mutator that performs the substitution
71 struct Substituter;
72
73 // TODO: worry about traversing into a forall-qualified function type or type decl with assertions
74
75 void initialize( const TypeSubstitution &src, TypeSubstitution &dest );
76
77 template<typename pass_type>
78 friend class Pass;
79
80 typedef std::unordered_map< std::string, ptr<Type> > TypeEnvType;
81 typedef std::unordered_map< std::string, ptr<Expr> > VarEnvType;
82 TypeEnvType typeEnv;
83 VarEnvType varEnv;
84
85 public:
86 // has to come after declaration of typeEnv
87 auto begin() -> decltype( typeEnv.begin() ) { return typeEnv.begin(); }
88 auto end() -> decltype( typeEnv. end() ) { return typeEnv. end(); }
89 auto begin() const -> decltype( typeEnv.begin() ) { return typeEnv.begin(); }
90 auto end() const -> decltype( typeEnv. end() ) { return typeEnv. end(); }
91
92 auto beginVar() -> decltype( varEnv.begin() ) { return varEnv.begin(); }
93 auto endVar() -> decltype( varEnv. end() ) { return varEnv. end(); }
94 auto beginVar() const -> decltype( varEnv.begin() ) { return varEnv.begin(); }
95 auto endVar() const -> decltype( varEnv. end() ) { return varEnv. end(); }
96};
97
98template< typename FormalIterator, typename ActualIterator >
99void TypeSubstitution::add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
100 // FormalIterator points to a TypeDecl
101 // ActualIterator points to a Type
102 FormalIterator formalIt = formalBegin;
103 ActualIterator actualIt = actualBegin;
104 for ( ; formalIt != formalEnd; ++formalIt, ++actualIt ) {
105 if ( const TypeDecl *formal = formalIt->template as<TypeDecl>() ) {
106 if ( const TypeExpr *actual = actualIt->template as<TypeExpr>() ) {
107 if ( formal->name != "" ) {
108 typeEnv[ formal->name ] = actual->type;
109 } // if
110 } else {
111 SemanticError( formal, toString( "Attempt to provide non-type parameter: ", toString( *actualIt ).c_str(), " for type parameter " ) );
112 } // if
113 } else {
114 // TODO: type check the formal and actual parameters
115 if ( (*formalIt)->name != "" ) {
116 varEnv[ (*formalIt)->name ] = *actualIt;
117 } // if
118 } // if
119 } // for
120}
121
122template< typename FormalIterator, typename ActualIterator >
123TypeSubstitution::TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
124 add( formalBegin, formalEnd, actualBegin );
125}
126
127} // namespace ast
128
129// include needs to happen after TypeSubstitution is defined so that both TypeSubstitution and
130// PassVisitor are defined before PassVisitor implementation accesses TypeSubstitution internals.
131#include "Pass.hpp"
132
133namespace ast {
134
135// definitition must happen after PassVisitor is included so that WithGuards can be used
136struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter> {
137
138 Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
139
140#if TIME_TO_CONVERT_PASSES
141
142 Type * postmutate( TypeInstType * aggregateUseType );
143 Expression * postmutate( NameExpr * nameExpr );
144
145 /// Records type variable bindings from forall-statements
146 void premutate( Type * type );
147 /// Records type variable bindings from forall-statements and instantiations of generic types
148 template< typename TypeClass > void handleAggregateType( TypeClass * type );
149
150 void premutate( StructInstType * aggregateUseType );
151 void premutate( UnionInstType * aggregateUseType );
152
153#endif
154
155 const TypeSubstitution & sub;
156 int subCount = 0;
157 bool freeOnly;
158 typedef std::unordered_set< std::string > BoundVarsType;
159 BoundVarsType boundVars;
160
161};
162
163template< typename SynTreeClass >
164int TypeSubstitution::apply( SynTreeClass *&input ) const {
165 assert( input );
166 Pass<Substituter> sub( *this, false );
167 input = dynamic_cast< SynTreeClass * >( input->acceptMutator( sub ) );
168 assert( input );
169/// std::cerr << "substitution result is: ";
170/// newType->print( std::cerr );
171/// std::cerr << std::endl;
172 return sub.pass.subCount;
173}
174
175template< typename SynTreeClass >
176int TypeSubstitution::applyFree( SynTreeClass *&input ) const {
177 assert( input );
178 Pass<Substituter> sub( *this, true );
179 input = dynamic_cast< SynTreeClass * >( input->acceptMutator( sub ) );
180 assert( input );
181/// std::cerr << "substitution result is: ";
182/// newType->print( std::cerr );
183/// std::cerr << std::endl;
184 return sub.pass.subCount;
185}
186
187/// Instantiate each member of the context given the actual parameters specified, and store the
188/// instantiations for use by the indexer
189template< typename FormalIterator, typename ActualIterator, typename MemberIterator, typename OutputIterator >
190void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) {
191 TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
192 for ( auto i = memberBegin; i != memberEnd; ++i ) {
193 sub.apply( *i );
194 *out++ = *i;
195 } // for
196}
197
198} // namespace ast
199
200// Local Variables: //
201// tab-width: 4 //
202// mode: c++ //
203// compile-command: "make install" //
204// End: //
Note: See TracBrowser for help on using the repository browser.