Ignore:
Timestamp:
Jun 6, 2015, 11:38:58 PM (9 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
cd623a4
Parents:
a65d92e
Message:

constant types, first attempt

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    ra65d92e r59db689  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun  5 07:44:47 2015
    13 // Update Count     : 10
     12// Last Modified On : Sat Jun  6 23:18:19 2015
     13// Update Count     : 128
    1414//
    1515
     
    1717#include <cctype>
    1818#include <algorithm>
     19#include <sstream>
     20#include <cstdio>
     21#include <climits>
    1922
    2023#include "ParseNode.h"
    21 #include "SynTree/Type.h"
    2224#include "SynTree/Constant.h"
    2325#include "SynTree/Expression.h"
    24 #include "SynTree/Declaration.h"
    2526#include "UnimplementedError.h"
    2627#include "parseutility.h"
     
    3132ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {}
    3233
    33 ExpressionNode::ExpressionNode( string *name_) : ParseNode( *name_ ), argName( 0 ) {
    34         delete name_;
    35 }
     34ExpressionNode::ExpressionNode( const string *name_ ) : ParseNode( name_ ), argName( 0 ) {}
    3635
    3736ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {
     
    4342}
    4443
    45 ExpressionNode * ExpressionNode::set_asArgName( std::string *aName ) {
     44ExpressionNode * ExpressionNode::set_asArgName( const std::string *aName ) {
    4645        argName = new VarRefNode( aName );
    4746        return this;
     
    5554void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
    5655        if ( argName ) {
    57                 os << string(' ', indent ) << "(designated by:  ";
     56                os << string( indent, ' ' ) << "(designated by:  ";
    5857                argName->printOneLine( os, indent );
    5958                os << ")" << std::endl;
     
    8584}
    8685
    87 //  enum ConstantNode::Type =  { Integer, Float, Character, String, Range }
    88 
    89 ConstantNode::ConstantNode( void ) : ExpressionNode(), sign( true ), longs(0), size(0) {}
    90 
    91 ConstantNode::ConstantNode( string *name_) : ExpressionNode( name_), sign( true ), longs(0), size(0) {}
    92 
    93 ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), sign( true ), longs(0), size(0) {
    94         if ( inVal ) {
    95                 value = *inVal;
    96                 delete inVal;
    97         } else {
    98                 value = "";
    99         } // if
    100 
    101         classify( value );
    102 }
    103 
    104 ConstantNode::ConstantNode( const ConstantNode &other ) : ExpressionNode( other ), type( other.type ), value( other.value ), sign( other.sign ),
    105                                                                                                                   base( other.base ), longs( other.longs ), size( other.size ) {
    106 }
    107 
    108 // for some reason, std::tolower doesn't work as an argument to std::transform in g++ 3.1
    109 inline char tolower_hack( char c ) {
    110         return std::tolower( c );
    111 }
    112 
    113 void ConstantNode::classify( std::string &str ) {
     86static inline bool checku( char c ) { return c == 'u' || c == 'U'; }
     87static inline bool checkl( char c ) { return c == 'l' || c == 'L'; }
     88static inline bool checkf( char c ) { return c == 'f' || c == 'F'; }
     89static inline bool checkx( char c ) { return c == 'x' || c == 'X'; }
     90
     91ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) {
    11492        switch ( type ) {
    115           case Integer:
    11693          case Float:
    11794                {
    118                         std::string sfx("");
    119                         char c;
    120                         int i = str.length() - 1;
    121 
    122                         while ( i >= 0 && ! isxdigit( c = str.at( i--)) )
    123                                 sfx += c;
    124 
    125                         value = str.substr( 0, i + 2 );
    126 
    127                         // get rid of underscores
    128                         value.erase( remove( value.begin(), value.end(), '_'), value.end());
    129 
    130                         std::transform( sfx.begin(), sfx.end(), sfx.begin(), tolower_hack );
    131 
    132                         if ( sfx.find("ll") != string::npos ) {
    133                                 longs = 2;
    134                         } else if ( sfx.find("l") != string::npos ) {
    135                                 longs = 1;
     95                        size_t len = value.length() - 1;
     96
     97                        btype = BasicType::Double;                                      // default
     98                        if ( checkf( value[len] ) ) {
     99                                btype = BasicType::Float;
    136100                        } // if
    137 
    138                         assert(( longs >= 0) && ( longs <= 2));
    139 
    140                         if ( sfx.find("u") != string::npos )
    141                                 sign = false;
    142 
     101                        if ( checkl( value[len] ) ) {
     102                                btype = BasicType::LongDouble;
     103                        } // if
     104                        break;
     105                }
     106          case Integer:
     107                {
     108                        static const BasicType::Kind kind[2][3] = {
     109                                { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
     110                                { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
     111                        };
     112                        size_t last = value.length() - 1;                       // last character of constant
     113                        unsigned long long v;                                           // converted integral value
     114                        bool dec = true, Unsigned = false;                      // decimal, unsigned constant
     115                        int size;                                                                       // 0 => int, 1 => long, 2 => long long
     116
     117                        if ( value[0] == '0' ) {                                        // octal ?
     118                                dec = false;
     119                                if ( last != 0 && checkx( value[1] ) ) { // hex ?
     120                                        sscanf( (char *)value.c_str(), "%llx", &v );
     121                                        //printf( "%llx %llu\n", v, v );
     122                                } else {
     123                                        sscanf( (char *)value.c_str(), "%llo", &v );
     124                                        //printf( "%llo %llu\n", v, v );
     125                                } // if
     126                        } else {                                                                        // decimal ?
     127                                sscanf( (char *)value.c_str(), "%lld", &v );
     128                                //printf( "%llu %llu\n", v, v );
     129                        } // if
     130
     131                        if ( v <= INT_MAX ) {                                           // signed int
     132                                size = 0;
     133                        } else if ( v <= UINT_MAX ) {                           // unsigned int
     134                                size = 0;
     135                                if ( ! dec ) Unsigned = true;                   // unsigned
     136                        } else if ( v <= LONG_MAX ) {                           // signed long int
     137                                size = 1;
     138                        } else if ( v <= ULONG_MAX ) {                          // signed long int
     139                                size = 1;
     140                                if ( ! dec ) Unsigned = true;                   // unsigned long int
     141                        } else if ( v <= LLONG_MAX ) {                          // signed long long int
     142                                size = 2;
     143                        } else {                                                                        // signed long long int
     144                                size = 2;
     145                                if ( ! dec ) Unsigned = true;                   // unsigned long long int
     146                        } // if
     147
     148                        if ( checku( value[last] ) ) {                          // suffix 'u' ?
     149                                Unsigned = true;
     150                                if ( checkl( value[ last - 1 ] ) ) {    // suffix 'l' ?
     151                                        size = 1;
     152                                        if ( checkl( value[ last - 1 ] ) ) { // suffix 'll' ?
     153                                                size = 2;
     154                                        } // if
     155                                } // if
     156                        } else if ( checkl( value[ last ] ) ) {         // suffix 'l' ?
     157                                size = 1;
     158                                if ( checkl( value[ last - 1 ] ) ) {    // suffix 'll' ?
     159                                        size = 2;
     160                                } // if
     161                                if ( checku( value[ last - 1 ] ) ) {    // suffix 'u' ?
     162                                        Unsigned = true;
     163                                } // if
     164                        } // if
     165                        btype = kind[Unsigned][size];                           // loopup type of constant
    143166                        break;
    144167                }
    145168          case Character:
    146                 {
    147                         // remove underscores from hex and oct escapes
    148                         if ( str.substr(1,2) == "\\x")
    149                                 value.erase( remove( value.begin(), value.end(), '_'), value.end());
    150 
    151                         break;
    152                 }
    153           default:
    154                 // shouldn't be here
    155                 ;
    156         }
    157 }
     169                btype = BasicType::Char;                                                // default
     170                if ( string( "LUu" ).find( value[0] ) != string::npos ) {
     171                        // ???
     172                } // if
     173                break;
     174          case String:
     175                // array of char
     176                if ( string( "LUu" ).find( value[0] ) != string::npos ) {
     177                        if ( value[0] == 'u' && value[1] == '8' ) {
     178                                // ???
     179                        } else {
     180                                // ???
     181                        } // if
     182                } // if
     183                break;
     184        } // switch
     185} // ConstantNode::ConstantNode
    158186
    159187ConstantNode::Type ConstantNode::get_type( void ) const {
     
    161189}
    162190
    163 ConstantNode *ConstantNode::append( std::string *newValue ) {
    164         if ( newValue ) {
    165                 if ( type == String ) {
    166                         std::string temp = *newValue;
    167                         value.resize( value.size() - 1 );
    168                         value += newValue->substr(1, newValue->size());
    169                 } else
    170                         value += *newValue;
    171 
    172                 delete newValue;
    173         } // if
     191ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
     192        assert( newValue != 0 );
     193        assert( type == String );
     194
     195        //printf( "%lu \"%s\" \"%s\"\n", value.length() - 1, value.c_str(), newValue->substr( 1, newValue->length() - 2 ).c_str() );
     196        value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
     197       
     198        delete newValue;                                                                        // allocated by yacc
    174199        return this;
    175200}
    176201
    177202void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
    178         os << string( indent, ' ');
     203        os << string( indent, ' ' );
    179204        printDesignation( os );
    180205
    181206        switch ( type ) {
    182207          case Integer:
    183                 os << value ;
    184                 break;
    185208          case Float:
    186209                os << value ;
     
    206229        BasicType *bt;
    207230
    208         switch ( get_type()) {
    209           case Integer:
    210                 /* Cfr. standard 6.4.4.1 */
    211                 //bt.set_kind( BasicType::SignedInt );
    212                 bt = new BasicType( q, BasicType::SignedInt );
    213                 break;
    214           case Float:
    215                 // floating-point constants are type double
    216                 bt = new BasicType( q, BasicType::Double );
    217                 break;
    218           case Character:
    219                 bt = new BasicType( q, BasicType::Char );
    220                 break;
     231        switch ( get_type() ) {
    221232          case String:
    222                 // string should probably be a primitive type
    223                 ArrayType *at;
    224                 std::string value = get_value();
    225                 at = new ArrayType( q, new BasicType( q, BasicType::Char ),
    226                                                         new ConstantExpr( Constant( new BasicType( q, BasicType::SignedInt ),
    227                                                                                                                 toString( value.size() - 1 ) ) ),  // account for '\0'
    228                                                         false, false );
    229                 return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
     233                {
     234                        // string should probably be a primitive type
     235                        ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ),
     236                                                                                   new ConstantExpr(
     237                                                                                           Constant( new BasicType( q, BasicType::UnsignedInt ),
     238                                                                                                                 toString( value.size() + 1 ) ) ),  // account for '\0'
     239                                                                                   false, false );
     240                        return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
     241                }
     242          default:
     243                bt = new BasicType( q, btype );
     244                return new ConstantExpr( Constant( bt, get_value() ), maybeBuild< Expression >( get_argName() ) );
    230245        }
    231         return new ConstantExpr(  Constant( bt, get_value()),  maybeBuild< Expression >( get_argName() ) );
    232246}
    233247
    234248VarRefNode::VarRefNode() : isLabel( false ) {}
    235249
    236 VarRefNode::VarRefNode( string *name_, bool labelp ) : ExpressionNode( name_), isLabel( labelp ) {}
     250VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
    237251
    238252VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
     
    277291}
    278292
    279 std::string OperatorNode::get_typename( void ) const{
    280         return string( OpName[ type ]);
     293const char *OperatorNode::get_typename( void ) const{
     294        return OpName[ type ];
    281295}
    282296
     
    298312}
    299313
    300 CompositeExprNode::CompositeExprNode( string *name_) : ExpressionNode( name_), function( 0 ), arguments( 0 ) {
     314CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
    301315}
    302316
     
    612626void ValofExprNode::print( std::ostream &os, int indent ) const {
    613627        printDesignation( os );
    614         os << string( indent, ' ') << "Valof Expression:" << std::endl;
     628        os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
    615629        get_body()->print( os, indent + 4);
    616630}
     
    657671
    658672void ForCtlExprNode::print( std::ostream &os, int indent ) const{
    659         os << string( indent,' ') << "For Control Expression -- :" << endl;
    660 
    661         os << string( indent + 2,' ' ) << "initialization:" << endl;
     673        os << string( indent,' ' ) << "For Control Expression -- :" << endl;
     674
     675        os << string( indent + 2, ' ' ) << "initialization:" << endl;
    662676        if ( init != 0 )
    663677                init->printList( os, indent + 4 );
     
    666680        if ( condition != 0 )
    667681                condition->print( os, indent + 4 );
    668         os << string( indent + 2,' ' ) << "increment: " << endl;
     682        os << string( indent + 2, ' ' ) << "increment: " << endl;
    669683        if ( change != 0 )
    670684                change->print( os, indent + 4 );
Note: See TracChangeset for help on using the changeset viewer.