Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r6e3eaa57 rbf4b4cf  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun  4 21:24:45 2018
    13 // Update Count     : 802
     12// Last Modified On : Tue Sep 26 11:23:36 2017
     13// Update Count     : 780
    1414//
    1515
     
    5858static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
    5959static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
    60 static inline bool checkB( char c ) { return c == 'b' || c == 'B'; }
    6160static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    6261
     
    9493} // checkLNInt
    9594
     95static void sepNumeric( string & str, string & units ) {
     96        string::size_type posn = str.find_first_of( "`" );
     97        if ( posn != string::npos ) {
     98                units = "?" + str.substr( posn );                               // extract units
     99                str.erase( posn );                                                              // remove units
     100        } // if
     101} // sepNumeric
     102
    96103Expression * build_constantInteger( string & str ) {
    97104        static const BasicType::Kind kind[2][6] = {
     
    101108        };
    102109
     110        string units;
     111        sepNumeric( str, units );                                                       // separate constant from units
     112
    103113        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    104114        int size;                                                                                       // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     
    106116
    107117        unsigned long long int v;                                                       // converted integral value
    108         size_t last = str.length() - 1;                                         // last subscript of constant
     118        size_t last = str.length() - 1;                                         // last character of constant
    109119        Expression * ret;
    110120
     
    119129        } // if
    120130
    121         // Cannot be "0"
    122 
    123         if ( str[0] == '0' ) {                                                          // radix character ?
     131        if ( str[0] == '0' ) {                                                          // octal/hex constant ?
    124132                dec = false;
    125                 if ( checkX( str[1] ) ) {                                               // hex constant ?
     133                if ( last != 0 && checkX( str[1] ) ) {                  // hex constant ?
    126134                        sscanf( (char *)str.c_str(), "%llx", &v );
    127                         //printf( "%llx %llu\n", v, v );
    128                 } else if ( checkB( str[1] ) ) {                                // binary constant ?
    129                         v = 0;
    130                         for ( unsigned int i = 2;; i += 1 ) {           // compute value
    131                                 if ( str[i] == '1' ) v |= 1;
    132                           if ( i == last ) break;
    133                                 v <<= 1;
    134                         } // for
    135135                        //printf( "%llx %llu\n", v, v );
    136136                } else {                                                                                // octal constant
     
    207207
    208208        assert( 0 <= size && size < 6 );
    209         // Constant type is correct for overload resolving.
    210209        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
    211         if ( Unsigned && size < 2 ) {                                           // hh or h, less than int ?
     210        if ( size < 2 ) {                                                                       // hh or h, less than int ?
    212211                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
    213                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false );
     212                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
    214213        } else if ( lnth != -1 ) {                                                      // explicit length ?
    215214                if ( lnth == 5 ) {                                                              // int128 ?
    216215                        size = 5;
    217                         ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false );
     216                        ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
    218217                } else {
    219                         ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ), false );
     218                        ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ) );
    220219                } // if
    221220        } // if
    222221  CLEANUP:
     222        if ( units.length() != 0 ) {
     223                ret = new UntypedExpr( new NameExpr( units ), { ret } );
     224        } // if
    223225
    224226        delete &str;                                                                            // created by lex
     
    254256        };
    255257
     258        string units;
     259        sepNumeric( str, units );                                                       // separate constant from units
     260
    256261        bool complx = false;                                                            // real, complex
    257262        int size = 1;                                                                           // 0 => float, 1 => double, 2 => long double
     
    285290        Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) );
    286291        if ( lnth != -1 ) {                                                                     // explicit length ?
    287                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][size] ), false );
     292                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][size] ) );
     293        } // if
     294        if ( units.length() != 0 ) {
     295                ret = new UntypedExpr( new NameExpr( units ), { ret } );
    288296        } // if
    289297
     
    314322
    315323Expression * build_constantStr( string & str ) {
    316         assert( str.length() > 0 );
    317324        string units;                                                                           // units
    318325        sepString( str, units, '"' );                                           // separate constant from units
     
    348355
    349356Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
    350         if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) SemanticError( yylloc, "invalid tuple index " + str );
     357        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
    351358        Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
    352359        delete &str;
     
    355362
    356363Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
    357         if ( str[str.size()-1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str );
     364        if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
    358365        Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
    359366        delete &str;
     
    409416        if ( dynamic_cast< VoidType * >( targetType ) ) {
    410417                delete targetType;
    411                 return new CastExpr( maybeMoveBuild< Expression >(expr_node), false );
     418                return new CastExpr( maybeMoveBuild< Expression >(expr_node) );
    412419        } else {
    413                 return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType, false );
     420                return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType );
    414421        } // if
    415422} // build_cast
    416 
    417 Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node ) {
    418         return new KeywordCastExpr( maybeMoveBuild< Expression >(expr_node), target );
    419 }
    420423
    421424Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
Note: See TracChangeset for help on using the changeset viewer.