Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r658fafe4 re869d663  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ExpressionNode.cc --
    8 //
     7// ExpressionNode.cc -- 
     8// 
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:17:07 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Aug  2 15:10:23 2016
    13 // Update Count     : 322
    14 //
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Aug 12 13:51:11 2015
     13// Update Count     : 254
     14// 
    1515
    1616#include <cassert>
     
    1919#include <sstream>
    2020#include <cstdio>
     21#include <climits>
    2122
    2223#include "ParseNode.h"
    23 #include "TypeData.h"
    2424#include "SynTree/Constant.h"
    2525#include "SynTree/Expression.h"
    26 #include "SynTree/Declaration.h"
    27 #include "Common/UnimplementedError.h"
     26#include "UnimplementedError.h"
    2827#include "parseutility.h"
    29 #include "Common/utility.h"
     28#include "utility.h"
    3029
    3130using namespace std;
    3231
    33 ExpressionNode::ExpressionNode() : ParseNode() {}
    34 
    35 ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}
    36 
    37 ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
     32ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {}
     33
     34ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ), argName( 0 ) {}
     35
     36ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {
    3837        if ( other.argName ) {
    3938                argName = other.argName->clone();
     
    8382}
    8483
    85 // CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
    86 //      return new CommaExprNode( this, exp );
    87 // }
    88 
    89 //##############################################################################
    90 
    91 ConstantNode::ConstantNode( ConstantExpr *expr ) : expr( expr ) {
     84CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
     85        return new CommaExprNode( this, exp );
     86}
     87
     88//##############################################################################
     89
     90static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
     91static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
     92static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
     93static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
     94
     95// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
     96//
     97//              prefix action constant action suffix
     98//
     99// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
     100//
     101//              constant BEGIN CONT ...
     102//              <CONT>(...)? BEGIN 0 ... // possible empty suffix
     103//
     104// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
     105// type.
     106
     107ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) {
     108        // lexing divides constants into 4 kinds
     109        switch ( type ) {
     110          case Integer:
     111                {
     112                        static const BasicType::Kind kind[2][3] = {
     113                                { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
     114                                { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
     115                        };
     116                        size_t last = value.length() - 1;                       // last character of constant
     117                        unsigned long long v;                                           // converted integral value
     118                        bool dec = true, Unsigned = false;                      // decimal, unsigned constant
     119                        int size;                                                                       // 0 => int, 1 => long, 2 => long long
     120
     121                        if ( value[0] == '0' ) {                                        // octal constant ?
     122                                dec = false;
     123                                if ( last != 0 && checkX( value[1] ) ) { // hex constant ?
     124                                        sscanf( (char *)value.c_str(), "%llx", &v );
     125                                        //printf( "%llx %llu\n", v, v );
     126                                } else {
     127                                        sscanf( (char *)value.c_str(), "%llo", &v );
     128                                        //printf( "%llo %llu\n", v, v );
     129                                } // if
     130                        } else {                                                                        // decimal constant ?
     131                                sscanf( (char *)value.c_str(), "%llu", &v );
     132                                //printf( "%llu %llu\n", v, v );
     133                        } // if
     134
     135                        if ( v <= INT_MAX ) {                                           // signed int
     136                                size = 0;
     137                        } else if ( v <= UINT_MAX && ! dec ) {          // unsigned int
     138                                size = 0;
     139                                Unsigned = true;                                                // unsigned
     140                        } else if ( v <= LONG_MAX ) {                           // signed long int
     141                                size = 1;
     142                        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
     143                                size = 1;
     144                                Unsigned = true;                                                // unsigned long int
     145                        } else if ( v <= LLONG_MAX ) {                          // signed long long int
     146                                size = 2;
     147                        } else {                                                                        // unsigned long long int
     148                                size = 2;
     149                                Unsigned = true;                                                // unsigned long long int
     150                        } // if
     151
     152                        if ( checkU( value[last] ) ) {                          // suffix 'u' ?
     153                                Unsigned = true;
     154                                if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ?
     155                                        size = 1;
     156                                        if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ?
     157                                                size = 2;
     158                                        } // if
     159                                } // if
     160                        } else if ( checkL( value[ last ] ) ) {         // suffix 'l' ?
     161                                size = 1;
     162                                if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ?
     163                                        size = 2;
     164                                        if ( last > 1 && checkU( value[ last - 2 ] ) ) { // suffix 'u' ?
     165                                                Unsigned = true;
     166                                        } // if
     167                                } else {
     168                                        if ( last > 0 && checkU( value[ last - 1 ] ) ) { // suffix 'u' ?
     169                                                Unsigned = true;
     170                                        } // if
     171                                } // if
     172                        } // if
     173                        btype = kind[Unsigned][size];                           // lookup constant type
     174                        break;
     175                }
     176          case Float:
     177                {
     178                        size_t len = value.length() - 1;
     179
     180                        btype = BasicType::Double;                                      // default
     181                        if ( checkF( value[len] ) ) {                           // float ?
     182                                btype = BasicType::Float;
     183                        } // if
     184                        if ( checkL( value[len] ) ) {                           // long double ?
     185                                btype = BasicType::LongDouble;
     186                        } // if
     187                        break;
     188                }
     189          case Character:
     190                btype = BasicType::Char;                                                // default
     191                if ( string( "LUu" ).find( value[0] ) != string::npos ) {
     192                        // ???
     193                } // if
     194                break;
     195          case String:
     196                // array of char
     197                if ( string( "LUu" ).find( value[0] ) != string::npos ) {
     198                        if ( value[0] == 'u' && value[1] == '8' ) {
     199                                // ???
     200                        } else {
     201                                // ???
     202                        } // if
     203                } // if
     204                break;
     205        } // switch
    92206} // ConstantNode::ConstantNode
    93207
    94208ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
    95209        assert( newValue != 0 );
    96 
    97         string value = expr->get_constant()->get_value();
     210        assert( type == String );
    98211
    99212        // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
    100213        value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
    101         expr->get_constant()->set_value( value );
    102 
     214       
    103215        delete newValue;                                                                        // allocated by lexer
    104216        return this;
     
    106218
    107219void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
    108         // os << string( indent, ' ' );
    109         // printDesignation( os );
    110 
    111         // switch ( type ) {
    112         //   case Integer:
    113         //   case Float:
    114         //      os << value ;
    115         //      break;
    116         //   case Character:
    117         //      os << "'" << value << "'";
    118         //      break;
    119         //   case String:
    120         //      os << '"' << value << '"';
    121         //      break;
    122         // } // switch
    123 
    124         // os << ' ';
     220        os << string( indent, ' ' );
     221        printDesignation( os );
     222
     223        switch ( type ) {
     224          case Integer:
     225          case Float:
     226                os << value ;
     227                break;
     228          case Character:
     229                os << "'" << value << "'";
     230                break;
     231          case String:
     232                os << '"' << value << '"';
     233                break;
     234        } // switch
     235
     236        os << ' ';
    125237}
    126238
     
    131243
    132244Expression *ConstantNode::build() const {
    133         return expr->clone();
     245        ::Type::Qualifiers q;                                                           // no qualifiers on constants
     246
     247        switch ( get_type() ) {
     248          case String:
     249                {
     250                        // string should probably be a primitive type
     251                        ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ),
     252                                                                                   new ConstantExpr(
     253                                                                                           Constant( new BasicType( q, BasicType::UnsignedInt ),
     254                                                                                                                 toString( value.size()+1-2 ) ) ),  // +1 for '\0' and -2 for '"'
     255                                                                                   false, false );
     256                        return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
     257                }
     258          default:
     259                return new ConstantExpr( Constant( new BasicType( q, btype ), get_value() ), maybeBuild< Expression >( get_argName() ) );
     260        }
    134261}
    135262
     
    198325
    199326Expression *DesignatorNode::build() const {
    200         Expression * ret = maybeBuild<Expression>(get_argName());
     327        Expression * ret = get_argName()->build();
    201328
    202329        if ( isArrayIndex ) {
    203                 // need to traverse entire structure and change any instances of 0 or 1 to
     330                // need to traverse entire structure and change any instances of 0 or 1 to 
    204331                // ConstantExpr
    205332                DesignatorFixer fixer;
     
    238365//##############################################################################
    239366
    240 static const char *opName[] = {
    241         "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic
    242         // triadic
    243         "Cond", "NCond",
    244         // diadic
    245         "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
    246         "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
    247         "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
    248         "?[?]", "FieldSel", "PFieldSel", "...",
    249         // monadic
    250         "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
    251 };
    252 
    253367OperatorNode::OperatorNode( Type t ) : type( t ) {}
    254368
     
    264378void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
    265379        printDesignation( os );
    266         os << opName[ type ] << ' ';
     380        os << OpName[ type ] << ' ';
    267381}
    268382
    269383void OperatorNode::print( std::ostream &os, int indent ) const{
    270384        printDesignation( os );
    271         os << string( indent, ' ' ) << "Operator: " << opName[type] << endl;
     385        os << string( indent, ' ' ) << "Operator: " << OpName[type] << endl;
    272386        return;
    273387}
    274388
    275389const char *OperatorNode::get_typename( void ) const{
    276         return opName[ type ];
    277 }
     390        return OpName[ type ];
     391}
     392
     393const char *OperatorNode::OpName[] = {
     394        "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
     395        // triadic
     396        "Cond",   "NCond",
     397        // diadic
     398        "SizeOf",     "AlignOf", "Attr", "CompLit", "Plus",    "Minus",   "Mul",     "Div",     "Mod",      "Or",
     399        "And",       "BitOr",   "BitAnd",  "Xor",     "Cast",    "LShift",  "RShift",  "LThan",   "GThan",
     400        "LEThan",    "GEThan", "Eq",      "Neq",     "Assign",  "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
     401        "MinusAssn", "LSAssn", "RSAssn",  "AndAssn", "ERAssn",  "OrAssn",  "Index",   "FieldSel","PFieldSel",
     402        "Range",
     403        // monadic
     404        "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
     405};
    278406
    279407//##############################################################################
     
    290418
    291419CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
    292         function( f ), arguments( arg1 ) {
    293         arguments->set_link( arg2 );
    294 }
    295 
    296 CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ), arguments( 0 ) {
     420        function( f ), arguments( arg1) {
     421        arguments->set_link( arg2);
     422}
     423
     424CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
    297425        ParseNode *cur = other.arguments;
    298426        while ( cur ) {
     
    311439}
    312440
    313 #include "Common/utility.h"
     441// the names that users use to define operator functions
     442static const char *opFuncName[] = {
     443        "",             "",             "",
     444        "",             "",
     445        //diadic
     446        "",             "",             "",             "",             "?+?",          "?-?",  "?*?",  "?/?",  "?%?",  "",              "",
     447        "?|?",          "?&?",          "?^?",  "",             "?<<?", "?>>?", "?<?",  "?>?",  "?<=?",
     448        "?>=?",         "?==?",         "?!=?", "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
     449        "?<<=?",        "?>>=?",        "?&=?", "?^=?", "?|=?", "?[?]", "",             "",             "Range",
     450        //monadic
     451        "+?",           "-?",           "",             "*?",   "!?",   "~?",   "++?",  "?++",  "--?",  "?--",  "&&"
     452};
     453
     454#include "utility.h"
    314455
    315456Expression *CompositeExprNode::build() const {
     
    320461
    321462        if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
    322                 return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() ));
     463                return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
    323464        } // if
    324465
     
    343484                args.front() = new AddressExpr( args.front() );
    344485                break;
    345           default:              // do nothing
     486          default:
     487                /* do nothing */
    346488                ;
    347         } // switch
     489        }
    348490
    349491        switch ( op->get_type() ) {
     
    387529          case OperatorNode::BitNeg:
    388530          case OperatorNode::LabelAddress:
    389                 return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args );
     531                return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
    390532          case OperatorNode::AddressOf:
    391533                assert( args.size() == 1 );
     
    404546                        if ( dynamic_cast< VoidType* >( targetType ) ) {
    405547                                delete targetType;
    406                                 return new CastExpr( maybeBuild<Expression>(expr_node), maybeBuild< Expression >( get_argName() ) );
     548                                return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
    407549                        } else {
    408                                 return new CastExpr( maybeBuild<Expression>(expr_node),targetType, maybeBuild< Expression >( get_argName() ) );
     550                                return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
    409551                        } // if
    410552                }
     
    443585                        return ret;
    444586                }
     587          case OperatorNode::AlignOf:
    445588          case OperatorNode::SizeOf:
    446589                {
     590///     bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
     591
    447592                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
    448593                                return new SizeofExpr( arg->get_decl()->buildType());
     
    451596                        } // if
    452597                }
    453           case OperatorNode::AlignOf:
    454                 {
    455                         if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
    456                                 return new AlignofExpr( arg->get_decl()->buildType());
    457                         } else {
    458                                 return new AlignofExpr( args.front());
    459                         } // if
    460                 }
    461           case OperatorNode::OffsetOf:
    462                 {
    463                         assert( args.size() == 2 );
    464 
    465                         if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args() ) ) {
    466                                 NameExpr *member = dynamic_cast<NameExpr *>( args.back() );
    467                                 assert( member != 0 );
    468 
    469                                 return new UntypedOffsetofExpr( arg->get_decl()->buildType(), member->get_name() );
    470                         } else assert( false );
    471                 }
    472598          case OperatorNode::Attr:
    473599                {
     
    475601                        assert( var );
    476602                        if ( ! get_args()->get_link() ) {
    477                                 return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);
     603                                return new AttrExpr( var->build(), ( Expression*)0);
    478604                        } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
    479                                 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType());
     605                                return new AttrExpr( var->build(), arg->get_decl()->buildType());
    480606                        } else {
    481                                 return new AttrExpr( maybeBuild<Expression>(var), args.back());
    482                         } // if
    483                 }
     607                                return new AttrExpr( var->build(), args.back());
     608                        } // if
     609                }
     610          case OperatorNode::CompLit:
     611                throw UnimplementedError( "C99 compound literals" );
     612                // the short-circuited operators
    484613          case OperatorNode::Or:
    485614          case OperatorNode::And:
     
    516645          default:
    517646                // shouldn't happen
    518                 assert( false );
    519647                return 0;
    520648        } // switch
     
    527655        for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
    528656                cur->printOneLine( os, indent );
    529         } // for
     657        }
    530658        os << ") ";
    531659}
     
    570698
    571699Expression *AsmExprNode::build() const {
    572         return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
     700        return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)constraint->build(), operand->build() );
    573701}
    574702
     
    608736//##############################################################################
    609737
     738CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
     739
     740CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
     741}
     742
     743CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
     744}
     745
     746CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
     747        add_arg( exp );
     748
     749        return this;
     750}
     751
     752CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
     753}
     754
     755//##############################################################################
     756
    610757ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
    611758
     
    628775
    629776Expression *ValofExprNode::build() const {
    630         return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
     777        return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
    631778}
    632779
     
    705852        get_decl()->print( os, indent + 2);
    706853}
    707 
    708 
    709 CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
    710 CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
    711 
    712 CompoundLiteralNode::~CompoundLiteralNode() {
    713         delete kids;
    714         delete type;
    715 }
    716 
    717 CompoundLiteralNode *CompoundLiteralNode::clone() const {
    718         return new CompoundLiteralNode( *this );
    719 }
    720 
    721 void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
    722         os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
    723 
    724         os << string( indent + 2, ' ' ) << "type:" << endl;
    725         if ( type != 0 )
    726                 type->print( os, indent + 4 );
    727 
    728         os << string( indent + 2, ' ' ) << "initialization:" << endl;
    729         if ( kids != 0 )
    730                 kids->printList( os, indent + 4 );
    731 }
    732 
    733 void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
    734         os << "( ";
    735         if ( type ) type->print( os );
    736         os << ", ";
    737         if ( kids ) kids->printOneLine( os );
    738         os << ") ";
    739 }
    740 
    741 Expression *CompoundLiteralNode::build() const {
    742         Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
    743         if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
    744                 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
    745         // these types do not have associated type information
    746         } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
    747                 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
    748         } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
    749                 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
    750         } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
    751                 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
    752         } else {
    753                 assert( false );
    754         } // if
    755 }
    756 
    757854
    758855ExpressionNode *flattenCommas( ExpressionNode *list ) {
Note: See TracChangeset for help on using the changeset viewer.