Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r7bf7fb9 r658fafe4  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Aug  7 09:23:12 2016
    13 // Update Count     : 437
     12// Last Modified On : Tue Aug  2 15:10:23 2016
     13// Update Count     : 322
    1414//
    1515
    1616#include <cassert>
    1717#include <cctype>
    18 #include <climits>
    19 #include <cstdio>
    2018#include <algorithm>
    2119#include <sstream>
     20#include <cstdio>
    2221
    2322#include "ParseNode.h"
     
    3837ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
    3938        if ( other.argName ) {
    40                 std::cout << "ExpressionNode" << std::endl;
    4139                argName = other.argName->clone();
    4240        } else {
     
    8583}
    8684
    87 //##############################################################################
    88 
    89 // Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
    90 //
    91 //              prefix action constant action suffix
    92 //
    93 // Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
    94 //
    95 //              constant BEGIN CONT ...
    96 //              <CONT>(...)? BEGIN 0 ... // possible empty suffix
    97 //
    98 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
    99 // type.
    100 
    101 static Type::Qualifiers emptyQualifiers;                                // no qualifiers on constants
    102 
    103 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
    104 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
    105 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
    106 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
    107 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
    108 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    109 
    110 ConstantNode *build_constantInteger( std::string & str ) {
    111         static const BasicType::Kind kind[2][3] = {
    112                 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
    113                 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
    114         };
    115         bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    116         int size;                                                                                       // 0 => int, 1 => long, 2 => long long
    117         unsigned long long v;                                                           // converted integral value
    118         size_t last = str.length() - 1;                                         // last character of constant
    119 
    120         if ( str[0] == '0' ) {                                                          // octal/hex constant ?
    121                 dec = false;
    122                 if ( last != 0 && checkX( str[1] ) ) {                  // hex constant ?
    123                         sscanf( (char *)str.c_str(), "%llx", &v );
    124                         //printf( "%llx %llu\n", v, v );
    125                 } else {                                                                                // octal constant
    126                         sscanf( (char *)str.c_str(), "%llo", &v );
    127                         //printf( "%llo %llu\n", v, v );
    128                 } // if
    129         } else {                                                                                        // decimal constant ?
    130                 sscanf( (char *)str.c_str(), "%llu", &v );
    131                 //printf( "%llu %llu\n", v, v );
    132         } // if
    133 
    134         if ( v <= INT_MAX ) {                                                           // signed int
    135                 size = 0;
    136         } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
    137                 size = 0;
    138                 Unsigned = true;                                                                // unsigned
    139         } else if ( v <= LONG_MAX ) {                                           // signed long int
    140                 size = 1;
    141         } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
    142                 size = 1;
    143                 Unsigned = true;                                                                // unsigned long int
    144         } else if ( v <= LLONG_MAX ) {                                          // signed long long int
    145                 size = 2;
    146         } else {                                                                                        // unsigned long long int
    147                 size = 2;
    148                 Unsigned = true;                                                                // unsigned long long int
    149         } // if
    150 
    151         if ( checkU( str[last] ) ) {                                            // suffix 'u' ?
    152                 Unsigned = true;
    153                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'l' ?
    154                         size = 1;
    155                         if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ?
    156                                 size = 2;
    157                         } // if
    158                 } // if
    159         } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
    160                 size = 1;
    161                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'll' ?
    162                         size = 2;
    163                         if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ?
    164                                 Unsigned = true;
    165                         } // if
    166                 } else {
    167                         if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ?
    168                                 Unsigned = true;
    169                         } // if
    170                 } // if
    171         } // if
    172 
    173         return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[Unsigned][size] ), str ) ) );
    174 } // build_constantInteger
    175 
    176 ConstantNode *build_constantFloat( std::string & str ) {
    177         static const BasicType::Kind kind[2][3] = {
    178                 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
    179                 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
    180         };
    181 
    182         bool complx = false;                                                            // real, complex
    183         int size = 1;                                                                           // 0 => float, 1 => double (default), 2 => long double
    184         // floating-point constant has minimum of 2 characters: 1. or .1
    185         size_t last = str.length() - 1;
    186 
    187         if ( checkI( str[last] ) ) {                                            // imaginary ?
    188                 complx = true;
    189                 last -= 1;                                                                              // backup one character
    190         } // if
    191 
    192         if ( checkF( str[last] ) ) {                                            // float ?
    193                 size = 0;
    194         } else if ( checkD( str[last] ) ) {                                     // double ?
    195                 size = 1;
    196         } else if ( checkL( str[last] ) ) {                                     // long double ?
    197                 size = 2;
    198         } // if
    199         if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
    200                 complx = true;
    201         } // if
    202 
    203         return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str ) ) );
    204 } // build_constantFloat
    205 
    206 ConstantNode *build_constantChar( std::string & str ) {
    207         return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str ) ) );
    208 } // build_constantChar
    209 
    210 ConstantNode *build_constantStr( std::string & str ) {
    211         // string should probably be a primitive type
    212         ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ),
    213                                 new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ),
    214                                                                                         toString( str.size()+1-2 ) ) ),  // +1 for '\0' and -2 for '"'
    215                                                                    false, false );
    216         return new ConstantNode( new ConstantExpr( Constant( at, str ) ) );
    217 } // build_constantStr
    218 
    219 //##############################################################################
    220 
    221 //Expression *build_varref( ExpressionNode expr ) {
    222 //      return new NameExpr( get_name(), maybeBuild<Expression>( get_argName() ) );
    223 //}
    224 
    225 VarRefNode::VarRefNode( const string *name, bool labelp ) : ExpressionNode( name ), isLabel( labelp ) {}
     85// CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
     86//      return new CommaExprNode( this, exp );
     87// }
     88
     89//##############################################################################
     90
     91ConstantNode::ConstantNode( ConstantExpr *expr ) : expr( expr ) {
     92} // ConstantNode::ConstantNode
     93
     94ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
     95        assert( newValue != 0 );
     96
     97        string value = expr->get_constant()->get_value();
     98
     99        // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
     100        value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
     101        expr->get_constant()->set_value( value );
     102
     103        delete newValue;                                                                        // allocated by lexer
     104        return this;
     105}
     106
     107void 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 << ' ';
     125}
     126
     127void ConstantNode::print( std::ostream &os, int indent ) const {
     128        printOneLine( os, indent );
     129        os << endl;
     130}
     131
     132Expression *ConstantNode::build() const {
     133        return expr->clone();
     134}
     135
     136//##############################################################################
     137
     138VarRefNode::VarRefNode() : isLabel( false ) {}
     139
     140VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
    226141
    227142VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
     
    256171                        double value;
    257172                        if ( ss >> value ) {
    258                                 // this is a floating point constant. It MUST be ".0" or ".1", otherwise the program is invalid
     173                                // this is a floating point constant. It MUST be
     174                                // ".0" or ".1", otherwise the program is invalid
    259175                                if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
    260176                                        throw SemanticError( "invalid designator name: " + var->get_name() );
     
    285201
    286202        if ( isArrayIndex ) {
    287                 // need to traverse entire structure and change any instances of 0 or 1 to ConstantExpr
     203                // need to traverse entire structure and change any instances of 0 or 1 to
     204                // ConstantExpr
    288205                DesignatorFixer fixer;
    289206                ret = ret->acceptMutator( fixer );
     
    321238//##############################################################################
    322239
    323 static const char *OperName[] = {
     240static const char *opName[] = {
     241        "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic
     242        // triadic
     243        "Cond", "NCond",
    324244        // diadic
    325         "SizeOf", "AlignOf", "OffsetOf", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
     245        "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
    326246        "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
    327247        "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
    328         "?[?]", "...",
     248        "?[?]", "FieldSel", "PFieldSel", "...",
    329249        // monadic
    330250        "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
    331251};
    332252
    333 //##############################################################################
    334 
    335 Expression *build_cast( TypeValueNode * arg, ExpressionNode *expr_node ) {
    336         DeclarationNode *decl_node = arg->get_decl();
    337 
    338         Type *targetType = decl_node->buildType();
    339         if ( dynamic_cast< VoidType* >( targetType ) ) {
    340                 delete targetType;
    341                 return new CastExpr( maybeBuild<Expression>(expr_node) );
    342         } else {
    343                 return new CastExpr( maybeBuild<Expression>(expr_node), targetType );
    344         } // if
    345 }
    346 
    347 Expression *build_fieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
    348         NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
    349         assert( memberExpr );
    350         UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), maybeBuild<Expression>(expr_node) );
    351         delete member;
    352         return ret;
    353 }
    354 
    355 Expression *build_pfieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
    356         NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
    357         assert( memberExpr );
    358         UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    359         deref->get_args().push_back( maybeBuild<Expression>(expr_node) );
    360         UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), deref );
    361         delete member;
    362         return ret;
    363 }
    364 
    365 Expression *build_addressOf( ExpressionNode *expr_node ) {
    366                 return new AddressExpr( maybeBuild<Expression>(expr_node) );
    367 }
    368 Expression *build_sizeOf( ExpressionNode *expr_node ) {
    369         if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
    370                 return new SizeofExpr( arg->get_decl()->buildType() );
    371         } else {
    372                 return new SizeofExpr( maybeBuild<Expression>(expr_node) );
    373         } // if
    374 }
    375 Expression *build_alignOf( ExpressionNode *expr_node ) {
    376         if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
    377                 return new AlignofExpr( arg->get_decl()->buildType() );
    378         } else {
    379                 return new AlignofExpr( maybeBuild<Expression>(expr_node) );
    380         } // if
    381 }
    382 Expression *build_offsetOf( TypeValueNode * arg, VarRefNode *member ) {
    383         NameExpr *memberExpr = dynamic_cast<NameExpr *>( maybeBuild<Expression>( member ) );
    384         assert( memberExpr );
    385         return new UntypedOffsetofExpr( arg->get_decl()->buildType(), memberExpr->get_name() );
    386 }
    387 
    388 Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ) {
    389         return new LogicalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), notZeroExpr( maybeBuild<Expression>(expr_node2) ), kind );
    390 }
    391 
    392 Expression *build_unary_val( OperKinds op, ExpressionNode *expr_node ) {
     253OperatorNode::OperatorNode( Type t ) : type( t ) {}
     254
     255OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
     256}
     257
     258OperatorNode::~OperatorNode() {}
     259
     260OperatorNode::Type OperatorNode::get_type( void ) const{
     261        return type;
     262}
     263
     264void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
     265        printDesignation( os );
     266        os << opName[ type ] << ' ';
     267}
     268
     269void OperatorNode::print( std::ostream &os, int indent ) const{
     270        printDesignation( os );
     271        os << string( indent, ' ' ) << "Operator: " << opName[type] << endl;
     272        return;
     273}
     274
     275const char *OperatorNode::get_typename( void ) const{
     276        return opName[ type ];
     277}
     278
     279//##############################################################################
     280
     281CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) {
     282}
     283
     284CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
     285}
     286
     287CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
     288        function( f ), arguments( args ) {
     289}
     290
     291CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
     292        function( f ), arguments( arg1 ) {
     293        arguments->set_link( arg2 );
     294}
     295
     296CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ), arguments( 0 ) {
     297        ParseNode *cur = other.arguments;
     298        while ( cur ) {
     299                if ( arguments ) {
     300                        arguments->set_link( cur->clone() );
     301                } else {
     302                        arguments = ( ExpressionNode*)cur->clone();
     303                } // if
     304                cur = cur->get_link();
     305        }
     306}
     307
     308CompositeExprNode::~CompositeExprNode() {
     309        delete function;
     310        delete arguments;
     311}
     312
     313#include "Common/utility.h"
     314
     315Expression *CompositeExprNode::build() const {
     316        OperatorNode *op;
    393317        std::list<Expression *> args;
    394         args.push_back( maybeBuild<Expression>(expr_node) );
    395         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    396 }
    397 Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ) {
    398         std::list<Expression *> args;
    399         args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node) ) );
    400         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    401 }
    402 Expression *build_binary_val( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
    403         std::list<Expression *> args;
    404         args.push_back( maybeBuild<Expression>(expr_node1) );
    405         args.push_back( maybeBuild<Expression>(expr_node2) );
    406         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    407 }
    408 Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
    409         std::list<Expression *> args;
    410         args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node1) ) );
    411         args.push_back( maybeBuild<Expression>(expr_node2) );
    412         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    413 }
    414 
    415 Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ) {
    416         return new ConditionalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), maybeBuild<Expression>(expr_node2), maybeBuild<Expression>(expr_node3) );
    417 }
    418 
    419 Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
    420         return new CommaExpr( maybeBuild<Expression>(expr_node1), maybeBuild<Expression>(expr_node2) );
    421 }
    422 
    423 Expression *build_attr( VarRefNode *var, ExpressionNode * expr ) {
    424         if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr ) ) {
    425                 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType() );
    426         } else {
    427                 return new AttrExpr( maybeBuild<Expression>(var), maybeBuild<Expression>(expr) );
    428         } // if
    429 }
    430 
    431 Expression *build_tuple( ExpressionNode * expr ) {
    432         TupleExpr *ret = new TupleExpr();
    433         buildList( expr, ret->get_exprs() );
    434         return ret;
    435 }
    436 
    437 Expression *build_func( ExpressionNode * function, ExpressionNode * expr ) {
    438         std::list<Expression *> args;
    439 
    440         buildList( expr, args );
    441         return new UntypedExpr( maybeBuild<Expression>(function), args, nullptr );
    442 }
    443 
    444 Expression *build_range( ExpressionNode * low, ExpressionNode *high ) {
    445         Expression *low_cexpr = maybeBuild<Expression>( low );
    446         Expression *high_cexpr = maybeBuild<Expression>( high );
    447         return new RangeExpr( low_cexpr, high_cexpr );
     318
     319        buildList( get_args(), args );
     320
     321        if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
     322                return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() ));
     323        } // if
     324
     325        switch ( op->get_type()) {
     326          case OperatorNode::Incr:
     327          case OperatorNode::Decr:
     328          case OperatorNode::IncrPost:
     329          case OperatorNode::DecrPost:
     330          case OperatorNode::Assign:
     331          case OperatorNode::MulAssn:
     332          case OperatorNode::DivAssn:
     333          case OperatorNode::ModAssn:
     334          case OperatorNode::PlusAssn:
     335          case OperatorNode::MinusAssn:
     336          case OperatorNode::LSAssn:
     337          case OperatorNode::RSAssn:
     338          case OperatorNode::AndAssn:
     339          case OperatorNode::ERAssn:
     340          case OperatorNode::OrAssn:
     341                // the rewrite rules for these expressions specify that the first argument has its address taken
     342                assert( ! args.empty() );
     343                args.front() = new AddressExpr( args.front() );
     344                break;
     345          default:              // do nothing
     346                ;
     347        } // switch
     348
     349        switch ( op->get_type() ) {
     350          case OperatorNode::Incr:
     351          case OperatorNode::Decr:
     352          case OperatorNode::IncrPost:
     353          case OperatorNode::DecrPost:
     354          case OperatorNode::Assign:
     355          case OperatorNode::MulAssn:
     356          case OperatorNode::DivAssn:
     357          case OperatorNode::ModAssn:
     358          case OperatorNode::PlusAssn:
     359          case OperatorNode::MinusAssn:
     360          case OperatorNode::LSAssn:
     361          case OperatorNode::RSAssn:
     362          case OperatorNode::AndAssn:
     363          case OperatorNode::ERAssn:
     364          case OperatorNode::OrAssn:
     365          case OperatorNode::Plus:
     366          case OperatorNode::Minus:
     367          case OperatorNode::Mul:
     368          case OperatorNode::Div:
     369          case OperatorNode::Mod:
     370          case OperatorNode::BitOr:
     371          case OperatorNode::BitAnd:
     372          case OperatorNode::Xor:
     373          case OperatorNode::LShift:
     374          case OperatorNode::RShift:
     375          case OperatorNode::LThan:
     376          case OperatorNode::GThan:
     377          case OperatorNode::LEThan:
     378          case OperatorNode::GEThan:
     379          case OperatorNode::Eq:
     380          case OperatorNode::Neq:
     381          case OperatorNode::Index:
     382          case OperatorNode::Range:
     383          case OperatorNode::UnPlus:
     384          case OperatorNode::UnMinus:
     385          case OperatorNode::PointTo:
     386          case OperatorNode::Neg:
     387          case OperatorNode::BitNeg:
     388          case OperatorNode::LabelAddress:
     389                return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args );
     390          case OperatorNode::AddressOf:
     391                assert( args.size() == 1 );
     392                assert( args.front() );
     393
     394                return new AddressExpr( args.front() );
     395          case OperatorNode::Cast:
     396                {
     397                        TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
     398                        assert( arg );
     399
     400                        DeclarationNode *decl_node = arg->get_decl();
     401                        ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
     402
     403                        Type *targetType = decl_node->buildType();
     404                        if ( dynamic_cast< VoidType* >( targetType ) ) {
     405                                delete targetType;
     406                                return new CastExpr( maybeBuild<Expression>(expr_node), maybeBuild< Expression >( get_argName() ) );
     407                        } else {
     408                                return new CastExpr( maybeBuild<Expression>(expr_node),targetType, maybeBuild< Expression >( get_argName() ) );
     409                        } // if
     410                }
     411          case OperatorNode::FieldSel:
     412                {
     413                        assert( args.size() == 2 );
     414
     415                        NameExpr *member = dynamic_cast<NameExpr *>( args.back());
     416                        // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
     417
     418                        if ( member != 0 ) {
     419                                UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
     420                                delete member;
     421                                return ret;
     422                                /* else if ( memberTup != 0 )
     423                                   {
     424                                   UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
     425                                   delete member;
     426                                   return ret;
     427                                   } */
     428                        } else
     429                                assert( false );
     430                }
     431          case OperatorNode::PFieldSel:
     432                {
     433                        assert( args.size() == 2 );
     434
     435                        NameExpr *member = dynamic_cast<NameExpr *>( args.back());  // modify for Tuples   xxx
     436                        assert( member != 0 );
     437
     438                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     439                        deref->get_args().push_back( args.front() );
     440
     441                        UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
     442                        delete member;
     443                        return ret;
     444                }
     445          case OperatorNode::SizeOf:
     446                {
     447                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
     448                                return new SizeofExpr( arg->get_decl()->buildType());
     449                        } else {
     450                                return new SizeofExpr( args.front());
     451                        } // if
     452                }
     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                }
     472          case OperatorNode::Attr:
     473                {
     474                        VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
     475                        assert( var );
     476                        if ( ! get_args()->get_link() ) {
     477                                return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);
     478                        } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
     479                                return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType());
     480                        } else {
     481                                return new AttrExpr( maybeBuild<Expression>(var), args.back());
     482                        } // if
     483                }
     484          case OperatorNode::Or:
     485          case OperatorNode::And:
     486                assert( args.size() == 2);
     487                return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
     488          case OperatorNode::Cond:
     489                {
     490                        assert( args.size() == 3);
     491                        std::list< Expression * >::const_iterator i = args.begin();
     492                        Expression *arg1 = notZeroExpr( *i++ );
     493                        Expression *arg2 = *i++;
     494                        Expression *arg3 = *i++;
     495                        return new ConditionalExpr( arg1, arg2, arg3 );
     496                }
     497          case OperatorNode::NCond:
     498                throw UnimplementedError( "GNU 2-argument conditional expression" );
     499          case OperatorNode::Comma:
     500                {
     501                        assert( args.size() == 2);
     502                        std::list< Expression * >::const_iterator i = args.begin();
     503                        Expression *ret = *i++;
     504                        while ( i != args.end() ) {
     505                                ret = new CommaExpr( ret, *i++ );
     506                        }
     507                        return ret;
     508                }
     509                // Tuples
     510          case OperatorNode::TupleC:
     511                {
     512                        TupleExpr *ret = new TupleExpr();
     513                        std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
     514                        return ret;
     515                }
     516          default:
     517                // shouldn't happen
     518                assert( false );
     519                return 0;
     520        } // switch
     521}
     522
     523void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
     524        printDesignation( os );
     525        os << "( ";
     526        function->printOneLine( os, indent );
     527        for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
     528                cur->printOneLine( os, indent );
     529        } // for
     530        os << ") ";
     531}
     532
     533void CompositeExprNode::print( std::ostream &os, int indent ) const {
     534        printDesignation( os );
     535        os << string( indent, ' ' ) << "Application of: " << endl;
     536        function->print( os, indent + ParseNode::indent_by );
     537
     538        os << string( indent, ' ' ) ;
     539        if ( arguments ) {
     540                os << "... on arguments: " << endl;
     541                arguments->printList( os, indent + ParseNode::indent_by );
     542        } else
     543                os << "... on no arguments: " << endl;
     544}
     545
     546void CompositeExprNode::set_function( ExpressionNode *f ) {
     547        function = f;
     548}
     549
     550void CompositeExprNode::set_args( ExpressionNode *args ) {
     551        arguments = args;
     552}
     553
     554ExpressionNode *CompositeExprNode::get_function( void ) const {
     555        return function;
     556}
     557
     558ExpressionNode *CompositeExprNode::get_args( void ) const {
     559        return arguments;
     560}
     561
     562void CompositeExprNode::add_arg( ExpressionNode *arg ) {
     563        if ( arguments )
     564                arguments->set_link( arg );
     565        else
     566                set_args( arg );
    448567}
    449568
     
    636755}
    637756
     757
     758ExpressionNode *flattenCommas( ExpressionNode *list ) {
     759        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
     760                OperatorNode *op;
     761                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
     762                        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
     763                                composite->add_arg( next );
     764                        return flattenCommas( composite->get_args() );
     765                } // if
     766        } // if
     767
     768        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
     769                list->set_next( flattenCommas( next ) );
     770
     771        return list;
     772}
     773
     774ExpressionNode *tupleContents( ExpressionNode *tuple ) {
     775        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
     776                OperatorNode *op = 0;
     777                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
     778                        return composite->get_args();
     779        } // if
     780        return tuple;
     781}
     782
    638783// Local Variables: //
    639784// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.