Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    rca35c51 r0caaa6a  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 30 13:33:16 2016
    13 // Update Count     : 319
     12// Last Modified On : Mon Jun 13 14:46:17 2016
     13// Update Count     : 307
    1414//
    1515
     
    1919#include <sstream>
    2020#include <cstdio>
     21#include <climits>
    2122
    2223#include "ParseNode.h"
     
    8990//##############################################################################
    9091
    91 ConstantNode::ConstantNode( ConstantExpr *expr ) : expr( expr ) {
     92static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
     93static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
     94static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
     95static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
     96static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
     97static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
     98
     99// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
     100//
     101//              prefix action constant action suffix
     102//
     103// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
     104//
     105//              constant BEGIN CONT ...
     106//              <CONT>(...)? BEGIN 0 ... // possible empty suffix
     107//
     108// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
     109// type.
     110
     111ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) {
     112        // lexing divides constants into 4 kinds
     113        switch ( type ) {
     114          case Integer:
     115                {
     116                        static const BasicType::Kind kind[2][3] = {
     117                                { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
     118                                { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
     119                        };
     120                        bool dec = true, Unsigned = false;                      // decimal, unsigned constant
     121                        int size;                                                                       // 0 => int, 1 => long, 2 => long long
     122                        unsigned long long v;                                           // converted integral value
     123                        size_t last = value.length() - 1;                       // last character of constant
     124
     125                        if ( value[0] == '0' ) {                                        // octal constant ?
     126                                dec = false;
     127                                if ( last != 0 && checkX( value[1] ) ) { // hex constant ?
     128                                        sscanf( (char *)value.c_str(), "%llx", &v );
     129                                        //printf( "%llx %llu\n", v, v );
     130                                } else {
     131                                        sscanf( (char *)value.c_str(), "%llo", &v );
     132                                        //printf( "%llo %llu\n", v, v );
     133                                } // if
     134                        } else {                                                                        // decimal constant ?
     135                                sscanf( (char *)value.c_str(), "%llu", &v );
     136                                //printf( "%llu %llu\n", v, v );
     137                        } // if
     138
     139                        if ( v <= INT_MAX ) {                                           // signed int
     140                                size = 0;
     141                        } else if ( v <= UINT_MAX && ! dec ) {          // unsigned int
     142                                size = 0;
     143                                Unsigned = true;                                                // unsigned
     144                        } else if ( v <= LONG_MAX ) {                           // signed long int
     145                                size = 1;
     146                        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
     147                                size = 1;
     148                                Unsigned = true;                                                // unsigned long int
     149                        } else if ( v <= LLONG_MAX ) {                          // signed long long int
     150                                size = 2;
     151                        } else {                                                                        // unsigned long long int
     152                                size = 2;
     153                                Unsigned = true;                                                // unsigned long long int
     154                        } // if
     155
     156                        if ( checkU( value[last] ) ) {                          // suffix 'u' ?
     157                                Unsigned = true;
     158                                if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ?
     159                                        size = 1;
     160                                        if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ?
     161                                                size = 2;
     162                                        } // if
     163                                } // if
     164                        } else if ( checkL( value[ last ] ) ) {         // suffix 'l' ?
     165                                size = 1;
     166                                if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ?
     167                                        size = 2;
     168                                        if ( last > 1 && checkU( value[ last - 2 ] ) ) { // suffix 'u' ?
     169                                                Unsigned = true;
     170                                        } // if
     171                                } else {
     172                                        if ( last > 0 && checkU( value[ last - 1 ] ) ) { // suffix 'u' ?
     173                                                Unsigned = true;
     174                                        } // if
     175                                } // if
     176                        } // if
     177                        btype = kind[Unsigned][size];                           // lookup constant type
     178                        break;
     179                }
     180          case Float:
     181                {
     182                        static const BasicType::Kind kind[2][3] = {
     183                                { BasicType::Float, BasicType::Double, BasicType::LongDouble },
     184                                { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
     185                        };
     186                        bool complx = false;                                            // real, complex
     187                        int size = 1;                                                           // 0 => float, 1 => double (default), 2 => long double
     188                        // floating-point constant has minimum of 2 characters: 1. or .1
     189                        size_t last = value.length() - 1;
     190
     191                        if ( checkI( value[last] ) ) {                          // imaginary ?
     192                                complx = true;
     193                                last -= 1;                                                              // backup one character
     194                        } // if
     195                        if ( checkF( value[last] ) ) {                          // float ?
     196                                size = 0;
     197                        } else if ( checkD( value[last] ) ) {           // double ?
     198                                size = 1;
     199                        } else if ( checkL( value[last] ) ) {           // long double ?
     200                                size = 2;
     201                        } // if
     202                        if ( ! complx && checkI( value[last - 1] ) ) { // imaginary ?
     203                                complx = true;
     204                        } // if
     205                        btype = kind[complx][size];                                     // lookup constant type
     206                        break;
     207                }
     208          case Character:
     209                btype = BasicType::Char;                                                // default
     210                if ( string( "LUu" ).find( value[0] ) != string::npos ) {
     211                        // ???
     212                } // if
     213                break;
     214          case String:
     215                // array of char
     216                if ( string( "LUu" ).find( value[0] ) != string::npos ) {
     217                        if ( value[0] == 'u' && value[1] == '8' ) {
     218                                // ???
     219                        } else {
     220                                // ???
     221                        } // if
     222                } // if
     223                break;
     224        } // switch
    92225} // ConstantNode::ConstantNode
    93226
    94227ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
    95228        assert( newValue != 0 );
    96         string value = expr->get_constant()->get_value();
     229        assert( type == String );
    97230
    98231        // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
     
    104237
    105238void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
    106         // os << string( indent, ' ' );
    107         // printDesignation( os );
    108 
    109         // switch ( type ) {
    110         //   case Integer:
    111         //   case Float:
    112         //      os << value ;
    113         //      break;
    114         //   case Character:
    115         //      os << "'" << value << "'";
    116         //      break;
    117         //   case String:
    118         //      os << '"' << value << '"';
    119         //      break;
    120         // } // switch
    121 
    122         // os << ' ';
     239        os << string( indent, ' ' );
     240        printDesignation( os );
     241
     242        switch ( type ) {
     243          case Integer:
     244          case Float:
     245                os << value ;
     246                break;
     247          case Character:
     248                os << "'" << value << "'";
     249                break;
     250          case String:
     251                os << '"' << value << '"';
     252                break;
     253        } // switch
     254
     255        os << ' ';
    123256}
    124257
     
    129262
    130263Expression *ConstantNode::build() const {
    131         return expr->clone();
     264        ::Type::Qualifiers q;                                                           // no qualifiers on constants
     265
     266        switch ( get_type() ) {
     267          case String:
     268                {
     269                        // string should probably be a primitive type
     270                        ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ),
     271                                                                                   new ConstantExpr(
     272                                                                                           Constant( new BasicType( q, BasicType::UnsignedInt ),
     273                                                                                                                 toString( value.size()+1-2 ) ) ),  // +1 for '\0' and -2 for '"'
     274                                                                                   false, false );
     275                        return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
     276                }
     277          default:
     278                return new ConstantExpr( Constant( new BasicType( q, btype ), get_value() ), maybeBuild< Expression >( get_argName() ) );
     279        }
    132280}
    133281
Note: See TracChangeset for help on using the changeset viewer.