Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    rbeec62c re612146c  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Sep 12 10:00:29 2017
    13 // Update Count     : 672
     12// Last Modified On : Sun Sep  3 22:21:21 2017
     13// Update Count     : 639
    1414//
    1515
     
    4949// type.
    5050
    51 extern const Type::Qualifiers noQualifiers;                             // no qualifiers on constants
    52 
    53 static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
     51extern const Type::Qualifiers noQualifiers;             // no qualifiers on constants
     52
     53static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
    5454static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
    55 static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
    56 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
    5755static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
    5856static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
     
    6967
    7068Expression * build_constantInteger( string & str ) {
    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 },
     69        static const BasicType::Kind kind[2][3] = {
     70                { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
     71                { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
    7572        };
    7673
     
    7976
    8077        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    81         int size;                                                                                       // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => size_t
     78        int size;                                                                                       // 0 => int, 1 => long, 2 => long long
    8279        unsigned long long int v;                                                       // converted integral value
    8380        size_t last = str.length() - 1;                                         // last character of constant
    8481        Expression * ret;
    8582
     83        // ROB: what do we do with units on 0 and 1?
    8684        // special constants
    8785        if ( str == "0" ) {
     
    109107
    110108        if ( v <= INT_MAX ) {                                                           // signed int
    111                 size = 2;
     109                size = 0;
    112110        } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
    113                 size = 2;
     111                size = 0;
    114112                Unsigned = true;                                                                // unsigned
    115113        } else if ( v <= LONG_MAX ) {                                           // signed long int
    116                 size = 3;
     114                size = 1;
    117115        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
    118                 size = 3;
     116                size = 1;
    119117                Unsigned = true;                                                                // unsigned long int
    120118        } else if ( v <= LLONG_MAX ) {                                          // signed long long int
    121                 size = 4;
     119                size = 2;
    122120        } else {                                                                                        // unsigned long long int
    123                 size = 4;
     121                size = 2;
    124122                Unsigned = true;                                                                // unsigned long long int
    125123        } // if
    126 
    127         // At least one digit in integer constant, so safe to backup while looking for suffix.
    128124
    129125        if ( checkU( str[last] ) ) {                                            // suffix 'u' ?
    130126                Unsigned = true;
    131                 if ( checkL( str[last - 1] ) ) {                                // suffix 'l' ?
    132                         size = 3;
    133                         if ( checkL( str[last - 2] ) ) {                        // suffix "ll" ?
    134                                 size = 4;
     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;
    135131                        } // 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"
    142132                } // if
    143133        } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
    144                 size = 3;
    145                 if ( checkL( str[last - 1] ) ) {                                // suffix 'll' ?
    146                         size = 4;
    147                         if ( checkU( str[last - 2] ) ) {                        // suffix 'u' ?
     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' ?
    148138                                Unsigned = true;
    149139                        } // if
    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' ?
     140                } else {
     141                        if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ?
    158142                                Unsigned = true;
    159143                        } // 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'
     144                } // if
    167145        } // if
    168146
    169147        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
    176148  CLEANUP:
    177149        if ( units.length() != 0 ) {
     
    275247} // build_constantStr
    276248
    277 Expression * 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 
    284 Expression * 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 
    291249Expression * build_field_name_FLOATINGconstant( const string & str ) {
    292250        // str is of the form A.B -> separate at the . and return member expression
     
    315273        return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
    316274} // build_field_name_fraction_constants
     275
     276Expression * 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
     283Expression * 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
    317289
    318290NameExpr * build_varref( const string * name ) {
Note: See TracChangeset for help on using the changeset viewer.