source: translator/ControlStruct/CaseRangeMutator.cc @ 01aeade

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 01aeade was 51587aa, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

licencing: fourth groups of files

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