source: src/SynTree/TypeSubstitution.h @ be9036d

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since be9036d was be9036d, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Reorganize TraitInstType? and TraitDecl?, add sized trait definition to prelude

Previously, TraitInstType? cloned all of the members of TraitDecl?. This commit changes
TraitInstType? to instead contain a pointer to the base TraitDecl?, analogous to StructInstType?
and StructDecl?, etc. In particular, this makes the code simpler and makes it easier to
fully expand the members of a trait declaration.

  • 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 : Sat Jul 22 09:52:24 2017
13// Update Count     : 3
14//
15
16#pragma once
17
18#include <cassert>                 // for assert
19#include <iosfwd>                  // for ostream
20#include <list>                    // for list<>::iterator, _List_iterator
21#include <map>                     // for _Rb_tree_iterator, map, map<>::val...
22#include <set>                     // for set
23#include <string>                  // for string, operator!=
24#include <utility>                 // for pair
25
26#include "Common/SemanticError.h"  // for SemanticError
27#include "SynTree/Declaration.h"   // for TypeDecl, Declaration (ptr only)
28#include "SynTree/Expression.h"    // for Expression (ptr only), NameExpr (p...
29#include "SynTree/Mutator.h"       // for Mutator
30#include "SynTree/Type.h"          // for Type, ArrayType (ptr only), BasicT...
31
32class TypeSubstitution : public Mutator {
33        typedef Mutator Parent;
34  public:
35        TypeSubstitution();
36        template< typename FormalIterator, typename ActualIterator >
37        TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
38        TypeSubstitution( const TypeSubstitution &other );
39        virtual ~TypeSubstitution();
40
41        TypeSubstitution &operator=( const TypeSubstitution &other );
42
43        template< typename SynTreeClass > int apply( SynTreeClass *&input );
44        template< typename SynTreeClass > int applyFree( SynTreeClass *&input );
45
46        void add( std::string formalType, Type *actualType );
47        void add( const TypeSubstitution &other );
48        void remove( std::string formalType );
49        Type *lookup( std::string formalType ) const;
50        bool empty() const;
51
52        template< typename FormalIterator, typename ActualIterator >
53        void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
54
55        /// this function is unused...
56        template< typename TypeInstListIterator >
57        void extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result );
58
59        void normalize();
60
61        TypeSubstitution * acceptMutator( Mutator & mutator );
62
63        void print( std::ostream &os, int indent = 0 ) const;
64        TypeSubstitution *clone() const { return new TypeSubstitution( *this ); }
65  private:
66        virtual Type* mutate(TypeInstType *aggregateUseType);
67        virtual Expression* mutate(NameExpr *nameExpr);
68
69        /// Records type variable bindings from forall-statements
70        template< typename TypeClass > Type *handleType( TypeClass *type );
71        /// Records type variable bindings from forall-statements and instantiations of generic types
72        template< typename TypeClass > Type *handleAggregateType( TypeClass *type );
73
74        virtual Type* mutate(VoidType *basicType);
75        virtual Type* mutate(BasicType *basicType);
76        virtual Type* mutate(PointerType *pointerType);
77        virtual Type* mutate(ArrayType *arrayType);
78        virtual Type* mutate(FunctionType *functionType);
79        virtual Type* mutate(StructInstType *aggregateUseType);
80        virtual Type* mutate(UnionInstType *aggregateUseType);
81        virtual Type* mutate(EnumInstType *aggregateUseType);
82        virtual Type* mutate(TraitInstType *aggregateUseType);
83        virtual Type* mutate(TupleType *tupleType);
84        virtual Type* mutate(VarArgsType *varArgsType);
85        virtual Type* mutate(ZeroType *zeroType);
86        virtual Type* mutate(OneType *oneType);
87
88        // TODO: worry about traversing into a forall-qualified function type or type decl with assertions
89
90        void initialize( const TypeSubstitution &src, TypeSubstitution &dest );
91
92        typedef std::map< std::string, Type* > TypeEnvType;
93        typedef std::map< std::string, Expression* > VarEnvType;
94        typedef std::set< std::string > BoundVarsType;
95        TypeEnvType typeEnv;
96        VarEnvType varEnv;
97        BoundVarsType boundVars;
98        int subCount;
99        bool freeOnly;
100};
101
102template< typename FormalIterator, typename ActualIterator >
103void TypeSubstitution::add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
104        // FormalIterator points to a TypeDecl
105        // ActualIterator points to a Type
106        FormalIterator formalIt = formalBegin;
107        ActualIterator actualIt = actualBegin;
108        for ( ; formalIt != formalEnd; ++formalIt, ++actualIt ) {
109                if ( TypeDecl *formal = dynamic_cast< TypeDecl* >( *formalIt ) ) {
110                        if ( TypeExpr *actual = dynamic_cast< TypeExpr* >( *actualIt ) ) {
111                                if ( formal->get_name() != "" ) {
112                                        TypeEnvType::iterator i = typeEnv.find( formal->get_name() );
113                                        if ( i != typeEnv.end() ) {
114                                                delete i->second;
115                                        } // if
116                                        typeEnv[ formal->get_name() ] = actual->get_type()->clone();
117                                } // if
118                        } else {
119                                throw SemanticError( toString( "Attempt to provide non-type parameter: ", toString( *actualIt ).c_str(), " for type parameter " ), formal );
120                        } // if
121                } else {
122                        // TODO: type check the formal and actual parameters
123                        if ( (*formalIt)->get_name() != "" ) {
124                                varEnv[ (*formalIt)->get_name() ] = (*actualIt)->clone();
125                        } // if
126                } // if
127        } // for
128}
129
130template< typename FormalIterator, typename ActualIterator >
131TypeSubstitution::TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin )
132{
133        add( formalBegin, formalEnd, actualBegin );
134}
135
136template< typename SynTreeClass >
137int TypeSubstitution::apply( SynTreeClass *&input ) {
138        assert( input );
139        subCount = 0;
140        freeOnly = false;
141        input = dynamic_cast< SynTreeClass *>( input->acceptMutator( *this ) );
142        assert( input );
143///     std::cout << "substitution result is: ";
144///     newType->print( std::cout );
145///     std::cout << std::endl;
146        return subCount;
147}
148
149template< typename SynTreeClass >
150int TypeSubstitution::applyFree( SynTreeClass *&input ) {
151        assert( input );
152        subCount = 0;
153        freeOnly = true;
154        input = dynamic_cast< SynTreeClass *>( input->acceptMutator( *this ) );
155        assert( input );
156///     std::cout << "substitution result is: ";
157///     newType->print( std::cout );
158///     std::cout << std::endl;
159        return subCount;
160}
161
162template< typename TypeInstListIterator >
163void TypeSubstitution::extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result ) {
164        // xxx - this function doesn't extract varEnv - is this intentional?
165        while ( begin != end ) {
166                TypeEnvType::iterator cur = typeEnv.find( (*begin++)->get_name() );
167                if ( cur != typeEnv.end() ) {
168                        result.typeEnv[ cur->first ] = cur->second;
169                        typeEnv.erase( cur );
170                } // if
171        } // while
172}
173
174/// Instantiate each member of the context given the actual parameters specified, and store the
175/// instantiations for use by the indexer
176template< typename FormalIterator, typename ActualIterator, typename MemberIterator, typename OutputIterator >
177void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) {
178        TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
179        for ( auto i = memberBegin; i != memberEnd; ++i ) {
180                sub.apply( *i );
181                *out++ = *i;
182        } // for
183}
184
185std::ostream & operator<<( std::ostream & out, const TypeSubstitution & sub );
186
187// Local Variables: //
188// tab-width: 4 //
189// mode: c++ //
190// compile-command: "make install" //
191// End: //
Note: See TracBrowser for help on using the repository browser.