source: src/AST/TypeSubstitution.hpp@ 4d5c5b6a

Last change on this file since 4d5c5b6a was c92bdcc, checked in by Andrew Beach <ajbeach@…>, 17 months ago

Updated the rest of the names in src/ (except for the generated files).

  • Property mode set to 100644
File size: 6.0 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.hpp --
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 : Mon Dec 11 16:07:30 2023
13// Update Count : 15
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"
28#include "Common/SemanticError.hpp" // for SemanticError
29#include "Visitor.hpp"
30#include "Decl.hpp"
31#include "Expr.hpp"
32#include "Node.hpp"
33
34namespace ast {
35
36class TypeSubstitution : public Node {
37 public:
38 TypeSubstitution();
39 template< typename FormalContainer, typename ActualContainer >
40 TypeSubstitution( FormalContainer formals, ActualContainer actuals );
41 template< typename FormalIterator, typename ActualIterator >
42 TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
43 TypeSubstitution( const TypeSubstitution &other );
44 virtual ~TypeSubstitution();
45
46 TypeSubstitution &operator=( const TypeSubstitution &other );
47
48 template< typename node_t >
49 struct ApplyResult {
50 ast::ptr<node_t> node;
51 int count;
52 };
53
54 template< typename node_t >
55 ApplyResult<node_t> apply( const node_t * input ) const {
56 ApplyResult<Node> ret = applyBase( input, false );
57 return { ret.node.strict_as<node_t>(), ret.count };
58 }
59
60 template< typename node_t, enum Node::ref_type ref_t >
61 int apply( ptr_base< node_t, ref_t > & input ) const {
62 ApplyResult<Node> ret = applyBase( input.get(), false );
63 input = ret.node.strict_as<node_t>();
64 return ret.count;
65 }
66
67 template< typename node_t >
68 ApplyResult<node_t> applyFree( const node_t * input ) const {
69 ApplyResult<Node> ret = applyBase( input, true );
70 return { ret.node.strict_as<node_t>(), ret.count };
71 }
72
73 template< typename node_t, enum Node::ref_type ref_t >
74 int applyFree( ptr_base< node_t, ref_t > & input ) const {
75 ApplyResult<Node> ret = applyBase( input.get(), true );
76 input = ret.node.strict_as<node_t>();
77 return ret.count;
78 }
79
80 void add( const TypeInstType * formalType, const Type *actualType );
81 void add( const TypeEnvKey & key, const Type *actualType );
82 void add( const TypeSubstitution &other );
83 void remove( const TypeInstType * formalType );
84 const Type *lookup( const TypeEnvKey & formalType ) const;
85 const Type *lookup( const TypeInstType * formalType ) const;
86 bool empty() const;
87
88 template< typename FormalContainer, typename ActualContainer >
89 void addAll( FormalContainer formals, ActualContainer actuals );
90 template< typename FormalIterator, typename ActualIterator >
91 void addAll( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
92
93 /// create a new TypeSubstitution using bindings from env containing all of the type variables in expr
94 static TypeSubstitution * newFromExpr( const Expr * expr, const TypeSubstitution * env );
95
96 void normalize();
97
98 const TypeSubstitution * accept( Visitor & v ) const override { return v.visit( this ); }
99
100 TypeSubstitution * clone() const override { return new TypeSubstitution( *this ); }
101
102 private:
103
104 // Mutator that performs the substitution
105 struct Substituter;
106 ApplyResult<Node> applyBase( const Node * input, bool isFree ) const;
107
108 // TODO: worry about traversing into a forall-qualified function type or type decl with assertions
109
110 void initialize( const TypeSubstitution &src, TypeSubstitution &dest );
111
112 template<typename core_t>
113 friend class Pass;
114
115 typedef std::unordered_map< TypeEnvKey, ptr<Type> > TypeMap;
116 TypeMap typeMap;
117
118 public:
119 // has to come after declaration of typeMap
120 auto begin() -> decltype( typeMap.begin() ) { return typeMap.begin(); }
121 auto end() -> decltype( typeMap. end() ) { return typeMap. end(); }
122 auto begin() const -> decltype( typeMap.begin() ) { return typeMap.begin(); }
123 auto end() const -> decltype( typeMap. end() ) { return typeMap. end(); }
124
125};
126
127template< typename FormalContainer, typename ActualContainer >
128TypeSubstitution::TypeSubstitution( FormalContainer formals, ActualContainer actuals ) {
129 assert( formals.size() == actuals.size() );
130 addAll( formals.begin(), formals.end(), actuals.begin() );
131}
132
133template< typename FormalIterator, typename ActualIterator >
134TypeSubstitution::TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
135 addAll( formalBegin, formalEnd, actualBegin );
136}
137
138template< typename FormalContainer, typename ActualContainer >
139void TypeSubstitution::addAll( FormalContainer formals, ActualContainer actuals ) {
140 assert( formals.size() == actuals.size() );
141 addAll( formals.begin(), formals.end(), actuals.begin() );
142}
143
144// this is the only place where type parameters outside a function formal may be substituted.
145template< typename FormalIterator, typename ActualIterator >
146void TypeSubstitution::addAll( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
147 // FormalIterator points to a TypeDecl
148 // ActualIterator points to a Type
149 FormalIterator formalIt = formalBegin;
150 ActualIterator actualIt = actualBegin;
151 for ( ; formalIt != formalEnd; ++formalIt, ++actualIt ) {
152 if ( const TypeDecl *formal = formalIt->template as<TypeDecl>() ) {
153 if ( const TypeExpr *actual = actualIt->template as<TypeExpr>() ) {
154 if ( formal->name != "" ) {
155 typeMap[ formal ] = actual->type;
156 } // if
157 } else {
158 SemanticError( formal->location, "Attempt to provide non-type parameter %s for type parameter %s",
159 toString( *actualIt ).c_str(), formal->name.c_str() );
160 } // if
161 } else {
162 // Is this an error?
163 } // if
164 } // for
165}
166
167} // namespace ast
168
169// Local Variables: //
170// tab-width: 4 //
171// mode: c++ //
172// compile-command: "make install" //
173// End: //
Note: See TracBrowser for help on using the repository browser.