Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    rbf4b4cf r6e3eaa57  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Sep 26 11:23:36 2017
    13 // Update Count     : 780
     12// Last Modified On : Mon Jun  4 21:24:45 2018
     13// Update Count     : 802
    1414//
    1515
     
    5858static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
    5959static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
     60static inline bool checkB( char c ) { return c == 'b' || c == 'B'; }
    6061static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    6162
     
    9394} // checkLNInt
    9495
    95 static 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 
    10396Expression * build_constantInteger( string & str ) {
    10497        static const BasicType::Kind kind[2][6] = {
     
    108101        };
    109102
    110         string units;
    111         sepNumeric( str, units );                                                       // separate constant from units
    112 
    113103        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    114104        int size;                                                                                       // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     
    116106
    117107        unsigned long long int v;                                                       // converted integral value
    118         size_t last = str.length() - 1;                                         // last character of constant
     108        size_t last = str.length() - 1;                                         // last subscript of constant
    119109        Expression * ret;
    120110
     
    129119        } // if
    130120
    131         if ( str[0] == '0' ) {                                                          // octal/hex constant ?
     121        // Cannot be "0"
     122
     123        if ( str[0] == '0' ) {                                                          // radix character ?
    132124                dec = false;
    133                 if ( last != 0 && checkX( str[1] ) ) {                  // hex constant ?
     125                if ( checkX( str[1] ) ) {                                               // hex constant ?
    134126                        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.
    209210        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
    210         if ( size < 2 ) {                                                                       // hh or h, less than int ?
     211        if ( Unsigned && size < 2 ) {                                           // hh or h, less than int ?
    211212                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
    212                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
     213                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false );
    213214        } else if ( lnth != -1 ) {                                                      // explicit length ?
    214215                if ( lnth == 5 ) {                                                              // int128 ?
    215216                        size = 5;
    216                         ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
     217                        ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false );
    217218                } else {
    218                         ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ) );
     219                        ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ), false );
    219220                } // if
    220221        } // if
    221222  CLEANUP:
    222         if ( units.length() != 0 ) {
    223                 ret = new UntypedExpr( new NameExpr( units ), { ret } );
    224         } // if
    225223
    226224        delete &str;                                                                            // created by lex
     
    256254        };
    257255
    258         string units;
    259         sepNumeric( str, units );                                                       // separate constant from units
    260 
    261256        bool complx = false;                                                            // real, complex
    262257        int size = 1;                                                                           // 0 => float, 1 => double, 2 => long double
     
    290285        Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) );
    291286        if ( lnth != -1 ) {                                                                     // explicit length ?
    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 } );
     287                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][size] ), false );
    296288        } // if
    297289
     
    322314
    323315Expression * build_constantStr( string & str ) {
     316        assert( str.length() > 0 );
    324317        string units;                                                                           // units
    325318        sepString( str, units, '"' );                                           // separate constant from units
     
    355348
    356349Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
    357         if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
     350        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) SemanticError( yylloc, "invalid tuple index " + str );
    358351        Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
    359352        delete &str;
     
    362355
    363356Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
    364         if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
     357        if ( str[str.size()-1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str );
    365358        Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
    366359        delete &str;
     
    416409        if ( dynamic_cast< VoidType * >( targetType ) ) {
    417410                delete targetType;
    418                 return new CastExpr( maybeMoveBuild< Expression >(expr_node) );
     411                return new CastExpr( maybeMoveBuild< Expression >(expr_node), false );
    419412        } else {
    420                 return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType );
     413                return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType, false );
    421414        } // if
    422415} // build_cast
     416
     417Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node ) {
     418        return new KeywordCastExpr( maybeMoveBuild< Expression >(expr_node), target );
     419}
    423420
    424421Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
Note: See TracChangeset for help on using the changeset viewer.