Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r2f22cc4 r658fafe4  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 10 11:07:38 2016
    13 // Update Count     : 486
     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"
     
    3231using namespace std;
    3332
    34 ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {}
    35 
    36 //##############################################################################
    37 
    38 // Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
    39 //
    40 //              prefix action constant action suffix
    41 //
    42 // Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
    43 //
    44 //              constant BEGIN CONT ...
    45 //              <CONT>(...)? BEGIN 0 ... // possible empty suffix
    46 //
    47 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
    48 // type.
    49 
    50 static Type::Qualifiers emptyQualifiers;                                // no qualifiers on constants
    51 
    52 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
    53 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
    54 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
    55 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
    56 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
    57 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    58 
    59 Expression *build_constantInteger( std::string & str ) {
    60         static const BasicType::Kind kind[2][3] = {
    61                 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
    62                 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
    63         };
    64         bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    65         int size;                                                                                       // 0 => int, 1 => long, 2 => long long
    66         unsigned long long v;                                                           // converted integral value
    67         size_t last = str.length() - 1;                                         // last character of constant
    68 
    69         if ( str[0] == '0' ) {                                                          // octal/hex constant ?
    70                 dec = false;
    71                 if ( last != 0 && checkX( str[1] ) ) {                  // hex constant ?
    72                         sscanf( (char *)str.c_str(), "%llx", &v );
    73                         //printf( "%llx %llu\n", v, v );
    74                 } else {                                                                                // octal constant
    75                         sscanf( (char *)str.c_str(), "%llo", &v );
    76                         //printf( "%llo %llu\n", v, v );
    77                 } // if
    78         } else {                                                                                        // decimal constant ?
    79                 sscanf( (char *)str.c_str(), "%llu", &v );
    80                 //printf( "%llu %llu\n", v, v );
    81         } // if
    82 
    83         if ( v <= INT_MAX ) {                                                           // signed int
    84                 size = 0;
    85         } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
    86                 size = 0;
    87                 Unsigned = true;                                                                // unsigned
    88         } else if ( v <= LONG_MAX ) {                                           // signed long int
    89                 size = 1;
    90         } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
    91                 size = 1;
    92                 Unsigned = true;                                                                // unsigned long int
    93         } else if ( v <= LLONG_MAX ) {                                          // signed long long int
    94                 size = 2;
    95         } else {                                                                                        // unsigned long long int
    96                 size = 2;
    97                 Unsigned = true;                                                                // unsigned long long int
    98         } // if
    99 
    100         if ( checkU( str[last] ) ) {                                            // suffix 'u' ?
    101                 Unsigned = true;
    102                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'l' ?
    103                         size = 1;
    104                         if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ?
    105                                 size = 2;
     33ExpressionNode::ExpressionNode() : ParseNode() {}
     34
     35ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}
     36
     37ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
     38        if ( other.argName ) {
     39                argName = other.argName->clone();
     40        } else {
     41                argName = 0;
     42        } // if
     43}
     44
     45ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
     46        argName = new VarRefNode( aName );
     47        return this;
     48}
     49
     50ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
     51        argName = aDesignator;
     52        return this;
     53}
     54
     55void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
     56        if ( argName ) {
     57                os << string( indent, ' ' ) << "(designated by:  ";
     58                argName->printOneLine( os, indent );
     59                os << ")" << std::endl;
     60        } // if
     61}
     62
     63//##############################################################################
     64
     65NullExprNode::NullExprNode() {}
     66
     67NullExprNode *NullExprNode::clone() const {
     68        return new NullExprNode();
     69}
     70
     71void NullExprNode::print( std::ostream & os, int indent ) const {
     72        printDesignation( os );
     73        os << "null expression";
     74}
     75
     76void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
     77        printDesignation( os );
     78        os << "null";
     79}
     80
     81Expression *NullExprNode::build() const {
     82        return 0;
     83}
     84
     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 ) {}
     141
     142VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
     143}
     144
     145Expression *VarRefNode::build() const {
     146        return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
     147}
     148
     149void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
     150        printDesignation( os );
     151        os << get_name() << ' ';
     152}
     153
     154void VarRefNode::print( std::ostream &os, int indent ) const {
     155        printDesignation( os );
     156        os << string( indent, ' ' ) << "Referencing: ";
     157        os << "Variable: " << get_name();
     158        os << endl;
     159}
     160
     161//##############################################################################
     162
     163DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
     164        set_argName( expr );
     165        assert( get_argName() );
     166
     167        if ( ! isArrayIndex ) {
     168                if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
     169
     170                        stringstream ss( var->get_name() );
     171                        double value;
     172                        if ( ss >> value ) {
     173                                // this is a floating point constant. It MUST be
     174                                // ".0" or ".1", otherwise the program is invalid
     175                                if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
     176                                        throw SemanticError( "invalid designator name: " + var->get_name() );
     177                                } // if
     178                                var->set_name( var->get_name().substr(1) );
    106179                        } // if
    107180                } // if
    108         } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
    109                 size = 1;
    110                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'll' ?
    111                         size = 2;
    112                         if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ?
    113                                 Unsigned = true;
    114                         } // if
     181        } // if
     182}
     183
     184DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
     185}
     186
     187class DesignatorFixer : public Mutator {
     188public:
     189        virtual Expression* mutate( NameExpr *nameExpr ) {
     190                if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
     191                        Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
     192                        delete nameExpr;
     193                        return new ConstantExpr( val );
     194                }
     195                return nameExpr;
     196        }
     197};
     198
     199Expression *DesignatorNode::build() const {
     200        Expression * ret = maybeBuild<Expression>(get_argName());
     201
     202        if ( isArrayIndex ) {
     203                // need to traverse entire structure and change any instances of 0 or 1 to
     204                // ConstantExpr
     205                DesignatorFixer fixer;
     206                ret = ret->acceptMutator( fixer );
     207        } // if
     208
     209        return ret;
     210}
     211
     212void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
     213        if ( get_argName() ) {
     214                if ( isArrayIndex ) {
     215                        os << "[";
     216                        get_argName()->printOneLine( os, indent );
     217                        os << "]";
    115218                } else {
    116                         if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ?
    117                                 Unsigned = true;
    118                         } // if
    119                 } // if
    120         } // if
    121 
    122         return new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[Unsigned][size] ), str ) );
    123 } // build_constantInteger
    124 
    125 Expression *build_constantFloat( std::string & str ) {
    126         static const BasicType::Kind kind[2][3] = {
    127                 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
    128                 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
    129         };
    130 
    131         bool complx = false;                                                            // real, complex
    132         int size = 1;                                                                           // 0 => float, 1 => double (default), 2 => long double
    133         // floating-point constant has minimum of 2 characters: 1. or .1
    134         size_t last = str.length() - 1;
    135 
    136         if ( checkI( str[last] ) ) {                                            // imaginary ?
    137                 complx = true;
    138                 last -= 1;                                                                              // backup one character
    139         } // if
    140 
    141         if ( checkF( str[last] ) ) {                                            // float ?
    142                 size = 0;
    143         } else if ( checkD( str[last] ) ) {                                     // double ?
    144                 size = 1;
    145         } else if ( checkL( str[last] ) ) {                                     // long double ?
    146                 size = 2;
    147         } // if
    148         if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
    149                 complx = true;
    150         } // if
    151 
    152         return new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str ) );
    153 } // build_constantFloat
    154 
    155 Expression *build_constantChar( std::string & str ) {
    156         return new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str ) );
    157 } // build_constantChar
    158 
    159 ConstantExpr *build_constantStr( std::string & str ) {
    160         // string should probably be a primitive type
    161         ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ),
    162                                 new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ),
    163                                                                                         toString( str.size()+1-2 ) ) ),  // +1 for '\0' and -2 for '"'
    164                                                                    false, false );
    165         return new ConstantExpr( Constant( at, str ) );
    166 } // build_constantStr
    167 
    168 //##############################################################################
    169 
    170 NameExpr * build_varref( const string *name, bool labelp ) {
    171         return new NameExpr( *name, nullptr );
    172 }
    173 
    174 //##############################################################################
    175 
    176 static const char *OperName[] = {
     219                        os << ".";
     220                        get_argName()->printOneLine( os, indent );
     221                }
     222        } // if
     223}
     224
     225void DesignatorNode::print( std::ostream &os, int indent ) const {
     226        if ( get_argName() ) {
     227                if ( isArrayIndex ) {
     228                        os << "[";
     229                        get_argName()->print( os, indent );
     230                        os << "]";
     231                } else {
     232                        os << ".";
     233                        get_argName()->print( os, indent );
     234                }
     235        } // if
     236}
     237
     238//##############################################################################
     239
     240static const char *opName[] = {
     241        "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic
     242        // triadic
     243        "Cond", "NCond",
    177244        // diadic
    178         "SizeOf", "AlignOf", "OffsetOf", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
     245        "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
    179246        "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
    180247        "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
    181         "?[?]", "...",
     248        "?[?]", "FieldSel", "PFieldSel", "...",
    182249        // monadic
    183250        "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
    184251};
    185252
    186 //##############################################################################
    187 
    188 Expression *build_cast( DeclarationNode *decl_node, ExpressionNode *expr_node ) {
    189         Type *targetType = decl_node->buildType();
    190         if ( dynamic_cast< VoidType * >( targetType ) ) {
    191                 delete targetType;
    192                 return new CastExpr( maybeBuild<Expression>(expr_node) );
    193         } else {
    194                 return new CastExpr( maybeBuild<Expression>(expr_node), targetType );
    195         } // if
    196 }
    197 
    198 Expression *build_fieldSel( ExpressionNode *expr_node, NameExpr *member ) {
    199         UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), maybeBuild<Expression>(expr_node) );
    200         delete member;
    201         return ret;
    202 }
    203 
    204 Expression *build_pfieldSel( ExpressionNode *expr_node, NameExpr *member ) {
    205         UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    206         deref->get_args().push_back( maybeBuild<Expression>(expr_node) );
    207         UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
    208         delete member;
    209         return ret;
    210 }
    211 
    212 Expression *build_addressOf( ExpressionNode *expr_node ) {
    213                 return new AddressExpr( maybeBuild<Expression>(expr_node) );
    214 }
    215 Expression *build_sizeOfexpr( ExpressionNode *expr_node ) {
    216         return new SizeofExpr( maybeBuild<Expression>(expr_node) );
    217 }
    218 Expression *build_sizeOftype( DeclarationNode *decl_node ) {
    219         return new SizeofExpr( decl_node->buildType() );
    220 }
    221 Expression *build_alignOfexpr( ExpressionNode *expr_node ) {
    222         return new AlignofExpr( maybeBuild<Expression>(expr_node) );
    223 }
    224 Expression *build_alignOftype( DeclarationNode *decl_node ) {
    225         return new AlignofExpr( decl_node->buildType() );
    226 }
    227 Expression *build_offsetOf( DeclarationNode *decl_node, NameExpr *member ) {
    228         return new UntypedOffsetofExpr( decl_node->buildType(), member->get_name() );
    229 }
    230 
    231 Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ) {
    232         return new LogicalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), notZeroExpr( maybeBuild<Expression>(expr_node2) ), kind );
    233 }
    234 
    235 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;
    236317        std::list<Expression *> args;
    237         args.push_back( maybeBuild<Expression>(expr_node) );
    238         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    239 }
    240 Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ) {
    241         std::list<Expression *> args;
    242         args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node) ) );
    243         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    244 }
    245 Expression *build_binary_val( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
    246         std::list<Expression *> args;
    247         args.push_back( maybeBuild<Expression>(expr_node1) );
    248         args.push_back( maybeBuild<Expression>(expr_node2) );
    249         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    250 }
    251 Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
    252         std::list<Expression *> args;
    253         args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node1) ) );
    254         args.push_back( maybeBuild<Expression>(expr_node2) );
    255         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    256 }
    257 
    258 Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ) {
    259         return new ConditionalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), maybeBuild<Expression>(expr_node2), maybeBuild<Expression>(expr_node3) );
    260 }
    261 
    262 Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
    263         return new CommaExpr( maybeBuild<Expression>(expr_node1), maybeBuild<Expression>(expr_node2) );
    264 }
    265 
    266 Expression *build_attrexpr( NameExpr *var, ExpressionNode * expr_node ) {
    267         return new AttrExpr( var, maybeBuild<Expression>(expr_node) );
    268 }
    269 Expression *build_attrtype( NameExpr *var, DeclarationNode * decl_node ) {
    270         return new AttrExpr( var, decl_node->buildType() );
    271 }
    272 
    273 Expression *build_tuple( ExpressionNode * expr_node ) {
    274         TupleExpr *ret = new TupleExpr();
    275         buildList( expr_node, ret->get_exprs() );
    276         return ret;
    277 }
    278 
    279 Expression *build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
    280         std::list<Expression *> args;
    281 
    282         buildList( expr_node, args );
    283         return new UntypedExpr( maybeBuild<Expression>(function), args, nullptr );
    284 }
    285 
    286 Expression *build_range( ExpressionNode * low, ExpressionNode *high ) {
    287         Expression *low_cexpr = maybeBuild<Expression>( low );
    288         Expression *high_cexpr = maybeBuild<Expression>( high );
    289         return new RangeExpr( low_cexpr, high_cexpr );
    290 }
    291 
    292 //##############################################################################
    293 
    294 Expression *build_asm( ExpressionNode *inout, ConstantExpr *constraint, ExpressionNode *operand ) {
    295         return new AsmExpr( maybeBuild< Expression >( inout ), constraint, maybeBuild<Expression>(operand) );
     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 );
     567}
     568
     569//##############################################################################
     570
     571Expression *AsmExprNode::build() const {
     572        return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
     573}
     574
     575void AsmExprNode::print( std::ostream &os, int indent ) const {
     576        os << string( indent, ' ' ) << "Assembler Expression:" << endl;
     577        if ( inout ) {
     578                os << string( indent, ' ' ) << "inout: " << std::endl;
     579                inout->print( os, indent + 2 );
     580        } // if
     581        if ( constraint ) {
     582                os << string( indent, ' ' ) << "constraint: " << std::endl;
     583                constraint->print( os, indent + 2 );
     584        } // if
     585        if ( operand ) {
     586                os << string( indent, ' ' ) << "operand: " << std::endl;
     587                operand->print( os, indent + 2 );
     588        } // if
     589}
     590
     591void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
     592        printDesignation( os );
     593        os << "( ";
     594        if ( inout ) inout->printOneLine( os, indent + 2 );
     595        os << ", ";
     596        if ( constraint ) constraint->printOneLine( os, indent + 2 );
     597        os << ", ";
     598        if ( operand ) operand->printOneLine( os, indent + 2 );
     599        os << ") ";
    296600}
    297601
     
    304608//##############################################################################
    305609
    306 Expression *build_valexpr( StatementNode *s ) {
    307         return new UntypedValofExpr( maybeBuild<Statement>(s), nullptr );
    308 }
    309 
    310 //##############################################################################
    311  
    312 // ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
    313 //      if ( init_ == 0 )
    314 //              init = 0;
    315 //      else {
    316 //              DeclarationNode *decl;
    317 //              ExpressionNode *exp;
    318 
    319 //              if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
    320 //                      init = new StatementNode( decl );
    321 //              else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
    322 //                      init = new StatementNode( StatementNode::Exp, exp );
    323 //              else
    324 //                      throw SemanticError("Error in for control expression");
    325 //      }
    326 // }
    327 
    328 // ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
    329 //      : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
    330 // }
    331 
    332 // ForCtlExprNode::~ForCtlExprNode() {
    333 //      delete init;
    334 //      delete condition;
    335 //      delete change;
    336 // }
    337 
    338 // Expression *ForCtlExprNode::build() const {
    339 //      // this shouldn't be used!
    340 //      assert( false );
    341 //      return 0;
    342 // }
    343 
    344 // void ForCtlExprNode::print( std::ostream &os, int indent ) const{
    345 //      os << string( indent,' ' ) << "For Control Expression -- :" << endl;
    346 
    347 //      os << string( indent + 2, ' ' ) << "initialization:" << endl;
    348 //      if ( init != 0 )
    349 //              init->printList( os, indent + 4 );
    350 
    351 //      os << string( indent + 2, ' ' ) << "condition: " << endl;
    352 //      if ( condition != 0 )
    353 //              condition->print( os, indent + 4 );
    354 //      os << string( indent + 2, ' ' ) << "increment: " << endl;
    355 //      if ( change != 0 )
    356 //              change->print( os, indent + 4 );
    357 // }
    358 
    359 // void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
    360 //      assert( false );
    361 // }
    362 
    363 //##############################################################################
    364 
    365 Expression *build_typevalue( DeclarationNode *decl ) {
     610ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
     611
     612ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
     613}
     614
     615ValofExprNode::~ValofExprNode() {
     616        delete body;
     617}
     618
     619void ValofExprNode::print( std::ostream &os, int indent ) const {
     620        printDesignation( os );
     621        os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
     622        get_body()->print( os, indent + 4);
     623}
     624
     625void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
     626        assert( false );
     627}
     628
     629Expression *ValofExprNode::build() const {
     630        return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
     631}
     632
     633//##############################################################################
     634
     635ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
     636        if ( init_ == 0 )
     637                init = 0;
     638        else {
     639                DeclarationNode *decl;
     640                ExpressionNode *exp;
     641
     642                if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
     643                        init = new StatementNode( decl );
     644                else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
     645                        init = new StatementNode( StatementNode::Exp, exp );
     646                else
     647                        throw SemanticError("Error in for control expression");
     648        }
     649}
     650
     651ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
     652        : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
     653}
     654
     655ForCtlExprNode::~ForCtlExprNode() {
     656        delete init;
     657        delete condition;
     658        delete change;
     659}
     660
     661Expression *ForCtlExprNode::build() const {
     662        // this shouldn't be used!
     663        assert( false );
     664        return 0;
     665}
     666
     667void ForCtlExprNode::print( std::ostream &os, int indent ) const{
     668        os << string( indent,' ' ) << "For Control Expression -- :" << endl;
     669
     670        os << string( indent + 2, ' ' ) << "initialization:" << endl;
     671        if ( init != 0 )
     672                init->printList( os, indent + 4 );
     673
     674        os << string( indent + 2, ' ' ) << "condition: " << endl;
     675        if ( condition != 0 )
     676                condition->print( os, indent + 4 );
     677        os << string( indent + 2, ' ' ) << "increment: " << endl;
     678        if ( change != 0 )
     679                change->print( os, indent + 4 );
     680}
     681
     682void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
     683        assert( false );
     684}
     685
     686//##############################################################################
     687
     688TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
     689}
     690
     691TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
     692}
     693
     694Expression *TypeValueNode::build() const {
    366695        return new TypeExpr( decl->buildType() );
    367696}
    368697
    369 //##############################################################################
    370 
    371 Expression *build_compoundLiteral( DeclarationNode *decl_node, InitializerNode *kids ) {
    372         Declaration * newDecl = maybeBuild<Declaration>(decl_node); // compound literal type
     698void TypeValueNode::print( std::ostream &os, int indent ) const {
     699        os << std::string( indent, ' ' ) << "Type:";
     700        get_decl()->print( os, indent + 2);
     701}
     702
     703void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
     704        os << "Type:";
     705        get_decl()->print( os, indent + 2);
     706}
     707
     708
     709CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
     710CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
     711
     712CompoundLiteralNode::~CompoundLiteralNode() {
     713        delete kids;
     714        delete type;
     715}
     716
     717CompoundLiteralNode *CompoundLiteralNode::clone() const {
     718        return new CompoundLiteralNode( *this );
     719}
     720
     721void 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
     733void 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
     741Expression *CompoundLiteralNode::build() const {
     742        Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
    373743        if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
    374744                return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
     
    385755}
    386756
     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
    387783// Local Variables: //
    388784// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.