Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/CaseRangeMutator.cc

    r08061589 r4e06c1e  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On : Sun Jul 31 12:16:28 2016
    13 // Update Count     : 32
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Jul 12 17:35:13 2016
     13// Update Count     : 9
    1414//
    1515
     
    3434                std::list< Statement * >::iterator i = cases.begin();
    3535                while ( i != cases.end() ) {
    36                         (*i)->acceptMutator( *this );
     36                        (*i )->acceptMutator( *this );
    3737
    3838                        if ( ! newCaseLabels.empty() ) {
    39                                 std::cout << "FRED" << std::endl;
    4039                                std::list< Statement * > newCases;
    4140
    4241                                // transform( newCaseLabels.begin(), newCaseLabels.end(), bnd1st( ptr_fun( ctor< CaseStmt, Label, Expression * > ) ) );
    4342
    44                                 for ( std::list< Expression * >::iterator j = newCaseLabels.begin(); j != newCaseLabels.end(); j++ ) {
    45                                         std::list< Label > emptyLabels;
    46                                         std::list< Statement * > emptyStmts;
     43                                for ( std::list< Expression * >::iterator j = newCaseLabels.begin();
     44                                          j != newCaseLabels.end(); j++ ) {
     45                                        std::list<Label> emptyLabels;
     46                                        std::list< Statement *> emptyStmts;
    4747                                        newCases.push_back( new CaseStmt( emptyLabels, *j, emptyStmts ) );
    4848                                } // for
    4949
    50                                 if ( CaseStmt *currentCase = dynamic_cast< CaseStmt * >( *i ) )
     50                                if ( CaseStmt *currentCase = dynamic_cast< CaseStmt * > ( *i ) )
    5151                                        if ( ! currentCase->get_statements().empty() ) {
    52                                                 CaseStmt *lastCase = dynamic_cast< CaseStmt * >( newCases.back() );
     52                                                CaseStmt *lastCase = dynamic_cast< CaseStmt * > ( newCases.back() );
    5353                                                if ( lastCase == 0 ) { throw ( 0 ); /* FIXME */ } // something is very wrong, as I just made these, and they were all cases
    5454                                                // transfer the statement block ( if any ) to the new list:
    5555                                                lastCase->set_statements( currentCase->get_statements() );
    5656                                        } // if
    57                                 std::list< Statement * >::iterator j = i;
    58                                 advance( j, 1 );
    59                                 replace( cases, i, newCases );
     57                                std::list< Statement * >::iterator j = i; advance( j, 1 );
     58                                replace ( cases, i, newCases );
    6059                                i = j;
    6160                                newCaseLabels.clear();
     
    6564
    6665                return switchStmt;
    67         } // CaseRangeMutator::mutate
     66        }
    6867
    6968        Statement *CaseRangeMutator::mutate( CaseStmt *caseStmt ) {
    70                 // case list, e.g., case 1, 3, 5:
    71                 if ( TupleExpr *tcond = dynamic_cast< TupleExpr * >( caseStmt->get_condition() ) ) {
     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
    7282                        assert( ! tcond->get_exprs().empty() );
    73                         for ( std::list< Expression * >::iterator i = tcond->get_exprs().begin(); i != tcond->get_exprs().end(); i++ ) {
    74                                 newCaseLabels.push_back( *i );                  // do I need to clone them?
    75                         } // for
     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?
    7685                } // if
    7786
    7887                std::list< Statement * > &stmts = caseStmt->get_statements();
    79                 mutateAll( stmts, *this );
     88                mutateAll ( stmts, *this );
    8089
    8190                return caseStmt;
    82         } // CaseRangeMutator::mutate
     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                        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() ) {
     113                  case BasicType::Char:
     114                  case BasicType::UnsignedChar:
     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;
     173                        }
     174                        break;
     175                  default:
     176                        break;
     177                } // switch
     178
     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 );
     183                        return;
     184                }
     185        }
    83186} // namespace ControlStruct
    84187
Note: See TracChangeset for help on using the changeset viewer.