source: translator/ResolvExpr/TypeEnvironment.cc @ 0b8cd722

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 0b8cd722 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

initial commit

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/*
2 * This file is part of the Cforall project
3 *
4 * $Id: TypeEnvironment.cc,v 1.7 2005/08/29 20:14:16 rcbilson Exp $
5 *
6 */
7
8#include <algorithm>
9#include <iterator>
10
11#include "TypeEnvironment.h"
12#include "SynTree/Type.h"
13#include "SynTree/TypeSubstitution.h"
14#include "utility.h"
15
16namespace ResolvExpr {
17
18void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent )
19{
20  for( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
21    i->first->print( os, indent );
22    if( i->second ) {
23      os << "(used)";
24    } else {
25      os << "(not used)";
26    }
27  }
28}
29
30void printOpenVarSet( const OpenVarSet &openVars, std::ostream &os, int indent )
31{
32  os << std::string( indent, ' ' );
33  for( OpenVarSet::const_iterator i = openVars.begin(); i != openVars.end(); ++i ) {
34    os << i->first << "(" << i->second << ") ";
35  }
36}
37
38void
39EqvClass::initialize( const EqvClass &src, EqvClass &dest )
40{
41  dest.vars = src.vars;
42  dest.type = maybeClone( src.type );
43  dest.allowWidening = src.allowWidening;
44  dest.kind = src.kind;
45}
46
47EqvClass::EqvClass() : type( 0 ), allowWidening( true )
48{
49}
50
51EqvClass::EqvClass( const EqvClass &other )
52{
53  initialize( other, *this );
54}
55
56EqvClass &
57EqvClass::operator=( const EqvClass &other )
58{
59  if( this == &other ) return *this;
60  delete type;
61  initialize( other, *this );
62  return *this;
63}
64
65EqvClass::~EqvClass()
66{
67  delete type;
68}
69
70void 
71EqvClass::print( std::ostream &os, int indent ) const
72{
73  os << std::string( indent, ' ' ) << "( ";
74  std::copy( vars.begin(), vars.end(), std::ostream_iterator< std::string >( os, " " ) );
75  os << ")";
76  if( type ) {
77    os << " -> ";
78    type->print( os, indent );
79  }
80  if( !allowWidening ) {
81    os << " (no widening)";
82  }
83  os << std::endl;
84}
85
86bool 
87TypeEnvironment::lookup( const std::string &var, EqvClass &eqvClass ) const
88{
89  for( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
90    if( i->vars.find( var ) != i->vars.end() ) {
91///       std::cout << var << " is in class ";
92///       i->print( std::cout );
93      eqvClass = *i;
94      return true;
95    }
96///     std::cout << var << " is not in class ";
97///     i->print( std::cout );
98  }
99  return false;
100}
101
102void 
103TypeEnvironment::add( const EqvClass &eqvClass )
104{
105  std::list< EqvClass >::iterator i = env.begin();
106  while( i != env.end() ) {
107    std::list< EqvClass >::iterator next = i;
108    next++;
109    std::set< std::string > intersection;
110    std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), std::inserter( intersection, intersection.begin() ) );
111    if( !intersection.empty() ) {
112      env.erase( i );
113    }
114    i = next;
115  }
116  env.insert( env.end(), eqvClass );
117}
118
119void 
120TypeEnvironment::add( const std::list< TypeDecl* > &tyDecls )
121{
122  for( std::list< TypeDecl* >::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) {
123    EqvClass newClass;
124    newClass.vars.insert( (*i)->get_name() );
125    newClass.kind = (*i)->get_kind();
126    env.push_back( newClass );
127  }
128}
129
130void 
131TypeEnvironment::makeSubstitution( TypeSubstitution &sub ) const
132{
133  for( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
134    for( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
135///       std::cout << "adding " << *theVar;
136      if( theClass->type ) {
137///         std::cout << " bound to ";
138///         theClass->type->print( std::cout );
139///         std::cout << std::endl;
140        sub.add( *theVar, theClass->type );
141      } else if( theVar != theClass->vars.begin() ) {
142        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->kind == TypeDecl::Ftype );
143///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
144        sub.add( *theVar, newTypeInst );
145        delete newTypeInst;
146      }
147    }
148  }
149///   std::cerr << "input env is:" << std::endl;
150///   print( std::cerr, 8 );
151///   std::cerr << "sub is:" << std::endl;
152///   sub.print( std::cerr, 8 );
153  sub.normalize();
154}
155
156void 
157TypeEnvironment::print( std::ostream &os, int indent ) const
158{
159  for( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
160    i->print( os, indent );
161  }
162}
163
164std::list< EqvClass >::iterator
165TypeEnvironment::internal_lookup( const std::string &var )
166{
167  for( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) {
168    if( i->vars.find( var ) == i->vars.end() ) {
169      return i;
170    }
171  }
172  return env.end();
173}
174
175void 
176TypeEnvironment::simpleCombine( const TypeEnvironment &second )
177{
178  env.insert( env.end(), second.env.begin(), second.env.end() );
179}
180
181void 
182TypeEnvironment::combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) )
183{
184  TypeEnvironment secondCopy( second );
185  for( std::list< EqvClass >::iterator firstClass = env.begin(); firstClass != env.end(); ++firstClass ) {
186    EqvClass &newClass = *firstClass;
187    std::set< std::string > newVars;
188    for( std::set< std::string >::const_iterator var = firstClass->vars.begin(); var != firstClass->vars.end(); ++var ) {
189      std::list< EqvClass >::iterator secondClass = secondCopy.internal_lookup( *var );
190      if( secondClass != secondCopy.env.end() ) {
191        newVars.insert( secondClass->vars.begin(), secondClass->vars.end() );
192        if( secondClass->type ) {
193          if( newClass.type ) {
194            Type *newType = combineFunc( newClass.type, secondClass->type );
195            delete newClass.type;
196            newClass.type = newType;
197            newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening;
198          } else {
199            newClass.type = secondClass->type->clone();
200            newClass.allowWidening = secondClass->allowWidening;
201          }
202        }
203        secondCopy.env.erase( secondClass );
204      }
205    }
206    newClass.vars.insert( newVars.begin(), newVars.end() );
207  }
208  for( std::list< EqvClass >::iterator secondClass = secondCopy.env.begin(); secondClass != secondCopy.env.end(); ++secondClass ) {
209    env.push_back( *secondClass );
210  }
211}
212
213void 
214TypeEnvironment::extractOpenVars( OpenVarSet &openVars ) const
215{
216  for( std::list< EqvClass >::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) {
217    for( std::set< std::string >::const_iterator var = eqvClass->vars.begin(); var != eqvClass->vars.end(); ++var ) {
218      openVars[ *var ] = eqvClass->kind;
219    }
220  }
221}
222
223} // namespace ResolvExpr
Note: See TracBrowser for help on using the repository browser.