Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    re612146c rbeec62c  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep  3 22:21:21 2017
    13 // Update Count     : 639
     12// Last Modified On : Tue Sep 12 10:00:29 2017
     13// Update Count     : 672
    1414//
    1515
     
    4949// type.
    5050
    51 extern const Type::Qualifiers noQualifiers;             // no qualifiers on constants
    52 
     51extern const Type::Qualifiers noQualifiers;                             // no qualifiers on constants
     52
     53static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
     54static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
     55static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
    5356static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
    54 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
    5557static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
    5658static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
     
    6769
    6870Expression * build_constantInteger( string & str ) {
    69         static const BasicType::Kind kind[2][3] = {
    70                 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
    71                 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
     71        static const BasicType::Kind kind[2][5] = {
     72                // short (h) must be before char (hh)
     73                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
     74                { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
    7275        };
    7376
     
    7679
    7780        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    78         int size;                                                                                       // 0 => int, 1 => long, 2 => long long
     81        int size;                                                                                       // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => size_t
    7982        unsigned long long int v;                                                       // converted integral value
    8083        size_t last = str.length() - 1;                                         // last character of constant
    8184        Expression * ret;
    8285
    83         // ROB: what do we do with units on 0 and 1?
    8486        // special constants
    8587        if ( str == "0" ) {
     
    107109
    108110        if ( v <= INT_MAX ) {                                                           // signed int
    109                 size = 0;
     111                size = 2;
    110112        } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
    111                 size = 0;
     113                size = 2;
    112114                Unsigned = true;                                                                // unsigned
    113115        } else if ( v <= LONG_MAX ) {                                           // signed long int
    114                 size = 1;
     116                size = 3;
    115117        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
    116                 size = 1;
     118                size = 3;
    117119                Unsigned = true;                                                                // unsigned long int
    118120        } else if ( v <= LLONG_MAX ) {                                          // signed long long int
    119                 size = 2;
     121                size = 4;
    120122        } else {                                                                                        // unsigned long long int
    121                 size = 2;
     123                size = 4;
    122124                Unsigned = true;                                                                // unsigned long long int
    123125        } // if
     126
     127        // At least one digit in integer constant, so safe to backup while looking for suffix.
    124128
    125129        if ( checkU( str[last] ) ) {                                            // suffix 'u' ?
    126130                Unsigned = true;
    127                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'l' ?
    128                         size = 1;
    129                         if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ?
    130                                 size = 2;
     131                if ( checkL( str[last - 1] ) ) {                                // suffix 'l' ?
     132                        size = 3;
     133                        if ( checkL( str[last - 2] ) ) {                        // suffix "ll" ?
     134                                size = 4;
    131135                        } // if
     136                } else if ( checkH( str[last - 1] ) ) {                 // suffix 'h' ?
     137                        size = 0;
     138                        if ( checkH( str[last - 2] ) ) {                        // suffix "hh" ?
     139                                size = 1;
     140                        } // if
     141                        str.erase( last - size - 1, size + 1 );         // remove 'h'/"hh"
    132142                } // if
    133143        } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
    134                 size = 1;
    135                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'll' ?
    136                         size = 2;
    137                         if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ?
     144                size = 3;
     145                if ( checkL( str[last - 1] ) ) {                                // suffix 'll' ?
     146                        size = 4;
     147                        if ( checkU( str[last - 2] ) ) {                        // suffix 'u' ?
    138148                                Unsigned = true;
    139149                        } // if
    140                 } else {
    141                         if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ?
     150                } else if ( checkU( str[last - 1] ) ) {                 // suffix 'u' ?
     151                        Unsigned = true;
     152                } // if
     153        } else if ( checkH( str[ last ] ) ) {                           // suffix 'h' ?
     154                size = 0;
     155                if ( checkH( str[last - 1] ) ) {                                // suffix "hh" ?
     156                        size = 1;
     157                        if ( checkU( str[last - 2] ) ) {                        // suffix 'u' ?
    142158                                Unsigned = true;
    143159                        } // if
    144                 } // if
     160                } else if ( checkU( str[last - 1] ) ) {                 // suffix 'u' ?
     161                        Unsigned = true;
     162                } // if
     163                str.erase( last - size, size + 1 );                             // remove 'h'/"hh"
     164        } else if ( checkZ( str[last] ) ) {                                     // suffix 'z' ?
     165                size = 5;
     166                str.erase( last, 1 );                                                   // remove 'z'
    145167        } // if
    146168
    147169        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
     170        if ( Unsigned && size < 2 ) {                                           // less than int ?
     171                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which eliminates warnings for large values.
     172                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
     173        } else if ( size == 5 ) {                                                       // explicit cast to size_t
     174                ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), "size_t", false ) );
     175        } // if
    148176  CLEANUP:
    149177        if ( units.length() != 0 ) {
     
    247275} // build_constantStr
    248276
     277Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
     278        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
     279        Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
     280        delete &str;
     281        return ret;
     282} // build_field_name_FLOATING_FRACTIONconstant
     283
     284Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
     285        if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
     286        Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
     287        delete &str;
     288        return ret;
     289} // build_field_name_FLOATING_DECIMALconstant
     290
    249291Expression * build_field_name_FLOATINGconstant( const string & str ) {
    250292        // str is of the form A.B -> separate at the . and return member expression
     
    273315        return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
    274316} // build_field_name_fraction_constants
    275 
    276 Expression * build_field_name_REALFRACTIONconstant( const string & str ) {
    277         if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
    278         Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
    279         delete &str;
    280         return ret;
    281 } // build_field_name_REALFRACTIONconstant
    282 
    283 Expression * build_field_name_REALDECIMALconstant( const string & str ) {
    284         if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
    285         Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
    286         delete &str;
    287         return ret;
    288 } // build_field_name_REALDECIMALconstant
    289317
    290318NameExpr * build_varref( const string * name ) {
Note: See TracChangeset for help on using the changeset viewer.