source: src/ControlStruct/CaseRangeMutator.cc@ b44a7c5

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since b44a7c5 was 4e06c1e, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

changes for switch and choose statements

  • Property mode set to 100644
File size: 6.1 KB
RevLine 
[51587aa]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//
[a08ba92]7// CaseRangeMutator.cc --
[51587aa]8//
[843054c2]9// Author : Rodolfo G. Esteves
[51587aa]10// Created On : Mon May 18 07:44:20 2015
[a08ba92]11// Last Modified By : Peter A. Buhr
[4e06c1e]12// Last Modified On : Tue Jul 12 17:35:13 2016
13// Update Count : 9
[51587aa]14//
[a08ba92]15
[51b73452]16#include <list>
17#include <cassert>
18#include <cstdlib>
19#include <iterator>
20
[d3b7937]21#include "Common/utility.h"
[51b73452]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 {
[a08ba92]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 }
[d9a0e76]67
[a08ba92]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() == std::string("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 }
[d9a0e76]92
[a08ba92]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 c_lo = ce_lo->get_constant(); c_hi = ce_hi->get_constant();
102 } /* else {
103 if ( ! ce_lo ) ;
104 if ( ! ce_hi ) ;
105 } */
106 BasicType *ty_lo = dynamic_cast< BasicType * >( c_lo->get_type() ),
107 *ty_hi = dynamic_cast< BasicType * >( c_hi->get_type() );
108
109 if ( ! ty_lo || ! ty_hi )
110 return; // one of them is not a constant
111
112 switch ( ty_lo->get_kind() ) {
[d9a0e76]113 case BasicType::Char:
114 case BasicType::UnsignedChar:
[a08ba92]115 switch ( ty_hi->get_kind() ) {
116 case BasicType::Char:
117 case BasicType::UnsignedChar:
118 // first case, they are both printable ASCII characters represented as 'x'
119 if ( c_lo->get_value().size() == 3 && c_hi->get_value().size() == 3 ) {
120 char ch_lo = ( c_lo->get_value())[1], ch_hi = ( c_hi->get_value())[1];
121
122 if ( ch_lo > ch_hi ) { char t=ch_lo; ch_lo=ch_hi; ch_hi=t; }
123
124 for ( char c = ch_lo; c <= ch_hi; c++ ) {
125 Type::Qualifiers q;
126 Constant cnst( new BasicType( q, BasicType::Char ),
127 std::string("'") + c + std::string("'") );
128 newCaseLabels.push_back( new ConstantExpr( cnst ) );
129 } // for
130
131 return;
132 } // if
133 break;
134 default:
135 // error: incompatible constants
136 break;
137 } // switch
138 break;
139 case BasicType::ShortSignedInt:
140 case BasicType::ShortUnsignedInt:
141 case BasicType::SignedInt:
142 case BasicType::UnsignedInt:
143 case BasicType::LongSignedInt:
144 case BasicType::LongUnsignedInt:
145 case BasicType::LongLongSignedInt:
146 case BasicType::LongLongUnsignedInt:
147 switch ( ty_hi->get_kind() ) {
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 int i_lo = atoi( c_lo->get_value().c_str()),
157 i_hi = atoi( c_hi->get_value().c_str());
158
159 if ( i_lo > i_hi ) { int t=i_lo; i_lo=i_hi; i_hi=t; }
160
161 for ( int c = i_lo; c <= i_hi; c++ ) {
162 Type::Qualifiers q;
163 Constant cnst( new BasicType( q, ty_hi->get_kind()), // figure can't hurt (used to think in positives)
164 toString< int >( c ) );
165 newCaseLabels.push_back( new ConstantExpr( cnst ) );
166 }
167
168 return;
169 }
170 default:
171 // error: incompatible constants
172 break;
[d9a0e76]173 }
[a08ba92]174 break;
175 default:
176 break;
177 } // switch
[d9a0e76]178
[a08ba92]179 /* End: */{
180 // invalid range, signal a warning (it still generates the two case labels)
181 newCaseLabels.push_back( lo );
182 newCaseLabels.push_back( hi );
[d9a0e76]183 return;
184 }
[51b73452]185 }
186} // namespace ControlStruct
[a08ba92]187
[51587aa]188// Local Variables: //
189// tab-width: 4 //
190// mode: c++ //
191// compile-command: "make install" //
192// End: //
Note: See TracBrowser for help on using the repository browser.