source: src/ControlStruct/CaseRangeMutator.cc @ 66d12f7

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglerjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 66d12f7 was 66d12f7, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

change case ranges to use gcc syntax, first attempt

  • Property mode set to 100644
File size: 6.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// CaseRangeMutator.cc --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Jul 28 01:56:47 2016
13// Update Count     : 14
14//
15
16#include <list>
17#include <cassert>
18#include <cstdlib>
19#include <iterator>
20
21#include "Common/utility.h"
22
23#include "SynTree/Statement.h"
24#include "SynTree/Expression.h"
25#include "SynTree/Constant.h"
26#include "SynTree/Type.h"
27#include "CaseRangeMutator.h"
28
29namespace ControlStruct {
30        Statement *CaseRangeMutator::mutate( SwitchStmt *switchStmt ) {
31                std::list< Statement * > &cases = switchStmt->get_branches();
32
33                // a `for' would be more natural... all this contortions are because `replace' invalidates the iterator
34                std::list< Statement * >::iterator i = cases.begin();
35                while ( i != cases.end() ) {
36                        (*i )->acceptMutator( *this );
37
38                        if ( ! newCaseLabels.empty() ) {
39                                std::list< Statement * > newCases;
40
41                                // transform( newCaseLabels.begin(), newCaseLabels.end(), bnd1st( ptr_fun( ctor< CaseStmt, Label, Expression * > ) ) );
42
43                                for ( std::list< Expression * >::iterator j = newCaseLabels.begin();
44                                          j != newCaseLabels.end(); j++ ) {
45                                        std::list<Label> emptyLabels;
46                                        std::list< Statement *> emptyStmts;
47                                        newCases.push_back( new CaseStmt( emptyLabels, *j, emptyStmts ) );
48                                } // for
49
50                                if ( CaseStmt *currentCase = dynamic_cast< CaseStmt * > ( *i ) )
51                                        if ( ! currentCase->get_statements().empty() ) {
52                                                CaseStmt *lastCase = dynamic_cast< CaseStmt * > ( newCases.back() );
53                                                if ( lastCase == 0 ) { throw ( 0 ); /* FIXME */ } // something is very wrong, as I just made these, and they were all cases
54                                                // transfer the statement block ( if any ) to the new list:
55                                                lastCase->set_statements( currentCase->get_statements() );
56                                        } // if
57                                std::list< Statement * >::iterator j = i; advance( j, 1 );
58                                replace ( cases, i, newCases );
59                                i = j;
60                                newCaseLabels.clear();
61                        } else
62                                i++;
63                } // while
64
65                return switchStmt;
66        }
67
68        Statement *CaseRangeMutator::mutate( CaseStmt *caseStmt ) {
69                UntypedExpr *cond;
70                if ( ( cond = dynamic_cast< UntypedExpr * >( caseStmt->get_condition() )) != 0 ) {
71                        NameExpr *nmfunc;
72                        if ( ( nmfunc = dynamic_cast< NameExpr *>( cond->get_function() )) != 0 ) {
73                                if ( nmfunc->get_name() == "Range" ) {
74                                        assert( cond->get_args().size() == 2 );
75                                        std::list<Expression *>::iterator i = cond->get_args().begin();
76                                        Expression *lo = *i, *hi = *(++i ); // "unnecessary" temporaries
77                                        //fillRange( lo, hi );
78                                } // if
79                        } // if
80                } else if ( TupleExpr *tcond = dynamic_cast< TupleExpr * >( caseStmt->get_condition() ) ) {
81                        // case list
82                        assert( ! tcond->get_exprs().empty() );
83                        for ( std::list< Expression * >::iterator i = tcond->get_exprs().begin(); i != tcond->get_exprs().end(); i++ )
84                                newCaseLabels.push_back( *i );                  // do I need to clone them?
85                } // if
86
87                std::list< Statement * > &stmts = caseStmt->get_statements();
88                mutateAll ( stmts, *this );
89
90                return caseStmt;
91        }
92
93        void CaseRangeMutator::fillRange( Expression *lo, Expression *hi ) {
94                // generate the actual range ( and check for consistency )
95                Constant *c_lo, *c_hi;
96                ConstantExpr *ce_lo, *ce_hi;
97                ce_lo = dynamic_cast< ConstantExpr * >( lo );
98                ce_hi = dynamic_cast< ConstantExpr * >( hi );
99
100                if ( ce_lo && ce_hi ) {
101                        std::cout << ce_lo->get_constant()->get_value() << " " << ce_hi->get_constant()->get_value() << std::endl;
102                        c_lo = ce_lo->get_constant(); c_hi = ce_hi->get_constant();
103                } /* else {
104                         if ( ! ce_lo ) ;
105                         if ( ! ce_hi ) ;
106                         } */
107                BasicType *ty_lo = dynamic_cast< BasicType * >( c_lo->get_type() ),
108                        *ty_hi = dynamic_cast< BasicType * >( c_hi->get_type() );
109       
110                if ( ! ty_lo || ! ty_hi )
111                        return; // one of them is not a constant
112#if 0
113                switch ( ty_lo->get_kind() ) {
114                  case BasicType::Char:
115                  case BasicType::UnsignedChar:
116                        switch ( ty_hi->get_kind() ) {
117                          case BasicType::Char:
118                          case BasicType::UnsignedChar:
119                                // first case, they are both printable ASCII characters represented as 'x'
120                                if ( c_lo->get_value().size() == 3 && c_hi->get_value().size() == 3 ) {
121                                        char ch_lo = ( c_lo->get_value())[1], ch_hi = ( c_hi->get_value())[1];
122
123                                        if ( ch_lo > ch_hi ) { char t=ch_lo; ch_lo=ch_hi; ch_hi=t; }
124
125                                        for ( char c = ch_lo; c <=  ch_hi; c++ ) {
126                                                Type::Qualifiers q;
127                                                Constant cnst( new BasicType( q, BasicType::Char ),
128                                                                           std::string("'") + c + std::string("'") );
129                                                newCaseLabels.push_back( new ConstantExpr( cnst ) );
130                                        } // for
131
132                                        return;
133                                } // if
134                                break;
135                          default:
136                                // error: incompatible constants
137                                break;
138                        } // switch
139                        break;
140                  case BasicType::ShortSignedInt:
141                  case BasicType::ShortUnsignedInt:
142                  case BasicType::SignedInt:
143                  case BasicType::UnsignedInt:
144                  case BasicType::LongSignedInt:
145                  case BasicType::LongUnsignedInt:
146                  case BasicType::LongLongSignedInt:
147                  case BasicType::LongLongUnsignedInt:
148                        switch ( ty_hi->get_kind() ) {
149                          case BasicType::ShortSignedInt:
150                          case BasicType::ShortUnsignedInt:
151                          case BasicType::SignedInt:
152                          case BasicType::UnsignedInt:
153                          case BasicType::LongSignedInt:
154                          case BasicType::LongUnsignedInt:
155                          case BasicType::LongLongSignedInt:
156                          case BasicType::LongLongUnsignedInt: {
157                                  int i_lo = atoi( c_lo->get_value().c_str()),
158                                          i_hi = atoi( c_hi->get_value().c_str());
159
160                                  if ( i_lo > i_hi ) { int t=i_lo; i_lo=i_hi; i_hi=t; }
161
162                                  for ( int c = i_lo; c <=  i_hi; c++ ) {
163                                          Type::Qualifiers q;
164                                          Constant cnst( new BasicType( q, ty_hi->get_kind()), // figure can't hurt (used to think in positives)
165                                                                         toString< int >( c ) );
166                                          newCaseLabels.push_back( new ConstantExpr( cnst ) );
167                                  }
168
169                                  return;
170                          }
171                          default:
172                                // error: incompatible constants
173                                break;
174                        }
175                        break;
176                  default:
177                        break;
178                } // switch
179#endif
180                /* End: */{ 
181                        // invalid range, signal a warning (it still generates the two case labels)
182//                      newCaseLabels.push_back( lo );
183//                      newCaseLabels.push_back( hi );
184                        return;
185                }
186        }
187} // namespace ControlStruct
188
189// Local Variables: //
190// tab-width: 4 //
191// mode: c++ //
192// compile-command: "make install" //
193// End: //
Note: See TracBrowser for help on using the repository browser.