source: src/Parser/ExpressionNode.cc @ ba407ce

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since ba407ce was 097e2b0, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

constructor/destructor, more example programs

  • Property mode set to 100644
File size: 26.1 KB
RevLine 
[b87a5ed]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ExpressionNode.cc --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 13:17:07 2015
[097e2b0]11// Last Modified By : Peter A. Buhr
12// Last Modified On : Mon Oct  5 16:37:24 2015
13// Update Count     : 255
[b87a5ed]14//
15
[51b7345]16#include <cassert>
17#include <cctype>
18#include <algorithm>
[59db689]19#include <sstream>
20#include <cstdio>
21#include <climits>
[51b7345]22
23#include "ParseNode.h"
24#include "SynTree/Constant.h"
25#include "SynTree/Expression.h"
26#include "UnimplementedError.h"
27#include "parseutility.h"
28#include "utility.h"
29
30using namespace std;
31
[3848e0e]32ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {}
[51b7345]33
[e869d663]34ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ), argName( 0 ) {}
[51b7345]35
[3848e0e]36ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {
[b87a5ed]37        if ( other.argName ) {
38                argName = other.argName->clone();
39        } else {
40                argName = 0;
41        } // if
[51b7345]42}
43
[7f5566b]44ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
[b87a5ed]45        argName = new VarRefNode( aName );
46        return this;
[51b7345]47}
48
[7f5566b]49ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
[b87a5ed]50        argName = aDesignator;
51        return this;
[51b7345]52}
53
54void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
[b87a5ed]55        if ( argName ) {
[59db689]56                os << string( indent, ' ' ) << "(designated by:  ";
[b87a5ed]57                argName->printOneLine( os, indent );
58                os << ")" << std::endl;
59        } // if
[51b7345]60}
61
[cd623a4]62//##############################################################################
63
[3848e0e]64NullExprNode::NullExprNode() {}
[51b7345]65
[3848e0e]66NullExprNode *NullExprNode::clone() const {
[b87a5ed]67        return new NullExprNode();
[51b7345]68}
69
[bdd516a]70void NullExprNode::print( std::ostream & os, int indent ) const {
[b87a5ed]71        printDesignation( os );
72        os << "null expression";
[51b7345]73}
74
[bdd516a]75void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
[b87a5ed]76        printDesignation( os );
77        os << "null";
[51b7345]78}
79
[3848e0e]80Expression *NullExprNode::build() const {
[b87a5ed]81        return 0;
[51b7345]82}
83
[a08ba92]84CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
[b87a5ed]85        return new CommaExprNode( this, exp );
[51b7345]86}
87
[cd623a4]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
[5f2f2d7]95// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
[cd623a4]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.
[51b7345]106
[59db689]107ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) {
[cd623a4]108        // lexing divides constants into 4 kinds
[a08ba92]109        switch ( type ) {
[59db689]110          case Integer:
[b87a5ed]111                {
[59db689]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
[cd623a4]121                        if ( value[0] == '0' ) {                                        // octal constant ?
[59db689]122                                dec = false;
[cd623a4]123                                if ( last != 0 && checkX( value[1] ) ) { // hex constant ?
[59db689]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
[cd623a4]130                        } else {                                                                        // decimal constant ?
[5f2f2d7]131                                sscanf( (char *)value.c_str(), "%llu", &v );
[59db689]132                                //printf( "%llu %llu\n", v, v );
133                        } // if
134
135                        if ( v <= INT_MAX ) {                                           // signed int
136                                size = 0;
[5f2f2d7]137                        } else if ( v <= UINT_MAX && ! dec ) {          // unsigned int
[59db689]138                                size = 0;
[5f2f2d7]139                                Unsigned = true;                                                // unsigned
[59db689]140                        } else if ( v <= LONG_MAX ) {                           // signed long int
141                                size = 1;
[5f2f2d7]142                        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
[59db689]143                                size = 1;
[5f2f2d7]144                                Unsigned = true;                                                // unsigned long int
[59db689]145                        } else if ( v <= LLONG_MAX ) {                          // signed long long int
146                                size = 2;
[5f2f2d7]147                        } else {                                                                        // unsigned long long int
[59db689]148                                size = 2;
[5f2f2d7]149                                Unsigned = true;                                                // unsigned long long int
[59db689]150                        } // if
[51b7345]151
[cd623a4]152                        if ( checkU( value[last] ) ) {                          // suffix 'u' ?
[59db689]153                                Unsigned = true;
[5f2f2d7]154                                if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ?
[59db689]155                                        size = 1;
[5f2f2d7]156                                        if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ?
[59db689]157                                                size = 2;
158                                        } // if
159                                } // if
[cd623a4]160                        } else if ( checkL( value[ last ] ) ) {         // suffix 'l' ?
[59db689]161                                size = 1;
[5f2f2d7]162                                if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ?
[59db689]163                                        size = 2;
[5f2f2d7]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
[59db689]171                                } // if
172                        } // if
[cd623a4]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
[b87a5ed]187                        break;
188                }
[59db689]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
206} // ConstantNode::ConstantNode
[51b7345]207
[59db689]208ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
209        assert( newValue != 0 );
210        assert( type == String );
[51b7345]211
[7f5566b]212        // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
[59db689]213        value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
214       
[cd623a4]215        delete newValue;                                                                        // allocated by lexer
[b87a5ed]216        return this;
[51b7345]217}
218
[bdd516a]219void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
[59db689]220        os << string( indent, ' ' );
[b87a5ed]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;
[c7ed6d0]234        } // switch
[51b7345]235
[b87a5ed]236        os << ' ';
[51b7345]237}
238
[bdd516a]239void ConstantNode::print( std::ostream &os, int indent ) const {
[b87a5ed]240        printOneLine( os, indent );
241        os << endl;
[51b7345]242}
243
244Expression *ConstantNode::build() const {
[cd623a4]245        ::Type::Qualifiers q;                                                           // no qualifiers on constants
[b87a5ed]246
[59db689]247        switch ( get_type() ) {
[b87a5ed]248          case String:
[59db689]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 ),
[ea9b9d3]254                                                                                                                 toString( value.size()+1-2 ) ) ),  // +1 for '\0' and -2 for '"'
[59db689]255                                                                                   false, false );
256                        return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
257                }
258          default:
[cd623a4]259                return new ConstantExpr( Constant( new BasicType( q, btype ), get_value() ), maybeBuild< Expression >( get_argName() ) );
[b87a5ed]260        }
[51b7345]261}
262
[cd623a4]263//##############################################################################
264
[bdd516a]265VarRefNode::VarRefNode() : isLabel( false ) {}
[51b7345]266
[59db689]267VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
[51b7345]268
[3848e0e]269VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
[51b7345]270}
271
272Expression *VarRefNode::build() const {
[b87a5ed]273        return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
[51b7345]274}
275
[bdd516a]276void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]277        printDesignation( os );
278        os << get_name() << ' ';
[51b7345]279}
280
[bdd516a]281void VarRefNode::print( std::ostream &os, int indent ) const {
[b87a5ed]282        printDesignation( os );
[44b5ca0]283        os << string( indent, ' ' ) << "Referencing: ";
[b87a5ed]284        os << "Variable: " << get_name();
285        os << endl;
[51b7345]286}
287
[cd623a4]288//##############################################################################
289
[51b1202]290DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
291        set_argName( expr );
[e869d663]292        assert( get_argName() );
293
294        if ( ! isArrayIndex ) {
295                if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
296
297                        stringstream ss( var->get_name() );
298                        double value;
299                        if ( ss >> value ) {
300                                // this is a floating point constant. It MUST be
301                                // ".0" or ".1", otherwise the program is invalid
302                                if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
303                                        throw SemanticError( "invalid designator name: " + var->get_name() );
304                                } // if
305                                var->set_name( var->get_name().substr(1) );
306                        } // if
307                } // if
308        } // if
[51b1202]309}
310
311DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
312}
313
[e869d663]314class DesignatorFixer : public Mutator {
315public:
316        virtual Expression* mutate( NameExpr *nameExpr ) {
317                if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
318                        Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
319                        delete nameExpr;
320                        return new ConstantExpr( val );
321                }
322                return nameExpr;
323        }
324};
325
[51b1202]326Expression *DesignatorNode::build() const {
[e869d663]327        Expression * ret = get_argName()->build();
328
[51b1202]329        if ( isArrayIndex ) {
[e869d663]330                // need to traverse entire structure and change any instances of 0 or 1 to
331                // ConstantExpr
332                DesignatorFixer fixer;
333                ret = ret->acceptMutator( fixer );
[51b1202]334        } // if
[e869d663]335
336        return ret;
[51b1202]337}
338
339void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
340        if ( get_argName() ) {
341                if ( isArrayIndex ) {
342                        os << "[";
343                        get_argName()->printOneLine( os, indent );
344                        os << "]";
345                } else {
346                        os << ".";
347                        get_argName()->printOneLine( os, indent );
348                }
349        } // if
350}
351
352void DesignatorNode::print( std::ostream &os, int indent ) const {
353        if ( get_argName() ) {
354                if ( isArrayIndex ) {
355                        os << "[";
356                        get_argName()->print( os, indent );
357                        os << "]";
358                } else {
359                        os << ".";
360                        get_argName()->print( os, indent );
361                }
362        } // if
363}
364
365//##############################################################################
366
[bdd516a]367OperatorNode::OperatorNode( Type t ) : type( t ) {}
[51b7345]368
[3848e0e]369OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
[51b7345]370}
371
372OperatorNode::~OperatorNode() {}
373
[bdd516a]374OperatorNode::Type OperatorNode::get_type( void ) const{
[b87a5ed]375        return type;
[51b7345]376}
377
[3848e0e]378void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]379        printDesignation( os );
380        os << OpName[ type ] << ' ';
[51b7345]381}
382
383void OperatorNode::print( std::ostream &os, int indent ) const{
[b87a5ed]384        printDesignation( os );
[44b5ca0]385        os << string( indent, ' ' ) << "Operator: " << OpName[type] << endl;
[b87a5ed]386        return;
[51b7345]387}
388
[59db689]389const char *OperatorNode::get_typename( void ) const{
390        return OpName[ type ];
[51b7345]391}
392
[3848e0e]393const char *OperatorNode::OpName[] = {
[b87a5ed]394        "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
395        // triadic
396        "Cond",   "NCond",
397        // diadic
[cd623a4]398        "SizeOf",     "AlignOf", "Attr", "CompLit", "Plus",    "Minus",   "Mul",     "Div",     "Mod",      "Or",
[b87a5ed]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"
[3848e0e]405};
[51b7345]406
[cd623a4]407//##############################################################################
408
[7f5566b]409CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) {
[51b7345]410}
411
[59db689]412CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
[51b7345]413}
414
[bdd516a]415CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
[b87a5ed]416        function( f ), arguments( args ) {
[51b7345]417}
418
[bdd516a]419CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
[097e2b0]420        function( f ), arguments( arg1 ) {
421        arguments->set_link( arg2 );
[51b7345]422}
423
[3848e0e]424CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
[b87a5ed]425        ParseNode *cur = other.arguments;
426        while ( cur ) {
427                if ( arguments ) {
428                        arguments->set_link( cur->clone() );
429                } else {
430                        arguments = ( ExpressionNode*)cur->clone();
431                } // if
432                cur = cur->get_link();
433        }
[51b7345]434}
435
[3848e0e]436CompositeExprNode::~CompositeExprNode() {
[b87a5ed]437        delete function;
438        delete arguments;
[51b7345]439}
440
441// the names that users use to define operator functions
[3848e0e]442static const char *opFuncName[] = {
[de62360d]443        "",             "",             "",
444        "",             "",
445        //diadic
446        "",             "",             "",             "",             "?+?",          "?-?",  "?*?",  "?/?",  "?%?",  "",              "",
447        "?|?",          "?&?",          "?^?",  "",             "?<<?", "?>>?", "?<?",  "?>?",  "?<=?",
448        "?>=?",         "?==?",         "?!=?", "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
449        "?<<=?",        "?>>=?",        "?&=?", "?^=?", "?|=?", "?[?]", "",             "",             "Range",
450        //monadic
451        "+?",           "-?",           "",             "*?",   "!?",   "~?",   "++?",  "?++",  "--?",  "?--",  "&&"
[3848e0e]452};
[51b7345]453
454#include "utility.h"
455
[3848e0e]456Expression *CompositeExprNode::build() const {
[b87a5ed]457        OperatorNode *op;
458        std::list<Expression *> args;
[51b7345]459
[b87a5ed]460        buildList( get_args(), args );
461
[cd623a4]462        if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
[b87a5ed]463                return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
[cd623a4]464        } // if
[b87a5ed]465
[cd623a4]466        switch ( op->get_type()) {
467          case OperatorNode::Incr:
468          case OperatorNode::Decr:
469          case OperatorNode::IncrPost:
470          case OperatorNode::DecrPost:
471          case OperatorNode::Assign:
472          case OperatorNode::MulAssn:
473          case OperatorNode::DivAssn:
474          case OperatorNode::ModAssn:
475          case OperatorNode::PlusAssn:
476          case OperatorNode::MinusAssn:
477          case OperatorNode::LSAssn:
478          case OperatorNode::RSAssn:
479          case OperatorNode::AndAssn:
480          case OperatorNode::ERAssn:
481          case OperatorNode::OrAssn:
482                // the rewrite rules for these expressions specify that the first argument has its address taken
483                assert( ! args.empty() );
484                args.front() = new AddressExpr( args.front() );
485                break;
486          default:
487                /* do nothing */
488                ;
489        }
490
491        switch ( op->get_type() ) {
492          case OperatorNode::Incr:
493          case OperatorNode::Decr:
494          case OperatorNode::IncrPost:
495          case OperatorNode::DecrPost:
496          case OperatorNode::Assign:
497          case OperatorNode::MulAssn:
498          case OperatorNode::DivAssn:
499          case OperatorNode::ModAssn:
500          case OperatorNode::PlusAssn:
501          case OperatorNode::MinusAssn:
502          case OperatorNode::LSAssn:
503          case OperatorNode::RSAssn:
504          case OperatorNode::AndAssn:
505          case OperatorNode::ERAssn:
506          case OperatorNode::OrAssn:
507          case OperatorNode::Plus:
508          case OperatorNode::Minus:
509          case OperatorNode::Mul:
510          case OperatorNode::Div:
511          case OperatorNode::Mod:
512          case OperatorNode::BitOr:
513          case OperatorNode::BitAnd:
514          case OperatorNode::Xor:
515          case OperatorNode::LShift:
516          case OperatorNode::RShift:
517          case OperatorNode::LThan:
518          case OperatorNode::GThan:
519          case OperatorNode::LEThan:
520          case OperatorNode::GEThan:
521          case OperatorNode::Eq:
522          case OperatorNode::Neq:
523          case OperatorNode::Index:
524          case OperatorNode::Range:
525          case OperatorNode::UnPlus:
526          case OperatorNode::UnMinus:
527          case OperatorNode::PointTo:
528          case OperatorNode::Neg:
529          case OperatorNode::BitNeg:
530          case OperatorNode::LabelAddress:
531                return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
532          case OperatorNode::AddressOf:
533                assert( args.size() == 1 );
534                assert( args.front() );
535
536                return new AddressExpr( args.front() );
537          case OperatorNode::Cast:
538                {
539                        TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
540                        assert( arg );
[b87a5ed]541
[cd623a4]542                        DeclarationNode *decl_node = arg->get_decl();
543                        ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
[b87a5ed]544
[cd623a4]545                        Type *targetType = decl_node->buildType();
546                        if ( dynamic_cast< VoidType* >( targetType ) ) {
547                                delete targetType;
548                                return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
549                        } else {
550                                return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
551                        } // if
552                }
553          case OperatorNode::FieldSel:
554                {
555                        assert( args.size() == 2 );
556
557                        NameExpr *member = dynamic_cast<NameExpr *>( args.back());
558                        // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
[b87a5ed]559
[cd623a4]560                        if ( member != 0 ) {
561                                UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
[b87a5ed]562                                delete member;
563                                return ret;
[cd623a4]564                                /* else if ( memberTup != 0 )
565                                   {
566                                   UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
567                                   delete member;
568                                   return ret;
569                                   } */
570                        } else
571                                assert( false );
572                }
573          case OperatorNode::PFieldSel:
574                {
575                        assert( args.size() == 2 );
576
577                        NameExpr *member = dynamic_cast<NameExpr *>( args.back());  // modify for Tuples   xxx
578                        assert( member != 0 );
579
580                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
581                        deref->get_args().push_back( args.front() );
582
583                        UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
584                        delete member;
585                        return ret;
586                }
587          case OperatorNode::AlignOf:
588          case OperatorNode::SizeOf:
589                {
[bdd516a]590///     bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
[51b7345]591
[cd623a4]592                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
593                                return new SizeofExpr( arg->get_decl()->buildType());
594                        } else {
595                                return new SizeofExpr( args.front());
596                        } // if
597                }
598          case OperatorNode::Attr:
599                {
600                        VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
601                        assert( var );
602                        if ( ! get_args()->get_link() ) {
603                                return new AttrExpr( var->build(), ( Expression*)0);
604                        } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
605                                return new AttrExpr( var->build(), arg->get_decl()->buildType());
606                        } else {
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
613          case OperatorNode::Or:
614          case OperatorNode::And:
615                assert( args.size() == 2);
616                return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
617          case OperatorNode::Cond:
618                {
619                        assert( args.size() == 3);
[7f5566b]620                        std::list< Expression * >::const_iterator i = args.begin();
[cd623a4]621                        Expression *arg1 = notZeroExpr( *i++ );
622                        Expression *arg2 = *i++;
623                        Expression *arg3 = *i++;
624                        return new ConditionalExpr( arg1, arg2, arg3 );
625                }
626          case OperatorNode::NCond:
627                throw UnimplementedError( "GNU 2-argument conditional expression" );
628          case OperatorNode::Comma:
629                {
[b87a5ed]630                        assert( args.size() == 2);
[7f5566b]631                        std::list< Expression * >::const_iterator i = args.begin();
[cd623a4]632                        Expression *ret = *i++;
633                        while ( i != args.end() ) {
634                                ret = new CommaExpr( ret, *i++ );
[b87a5ed]635                        }
[cd623a4]636                        return ret;
[3848e0e]637                }
[cd623a4]638                // Tuples
639          case OperatorNode::TupleC:
640                {
641                        TupleExpr *ret = new TupleExpr();
642                        std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
643                        return ret;
644                }
645          default:
646                // shouldn't happen
647                return 0;
648        } // switch
[51b7345]649}
650
[bdd516a]651void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]652        printDesignation( os );
653        os << "( ";
654        function->printOneLine( os, indent );
655        for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
656                cur->printOneLine( os, indent );
657        }
658        os << ") ";
[51b7345]659}
660
[bdd516a]661void CompositeExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]662        printDesignation( os );
[44b5ca0]663        os << string( indent, ' ' ) << "Application of: " << endl;
[b87a5ed]664        function->print( os, indent + ParseNode::indent_by );
[51b7345]665
[44b5ca0]666        os << string( indent, ' ' ) ;
[b87a5ed]667        if ( arguments ) {
668                os << "... on arguments: " << endl;
669                arguments->printList( os, indent + ParseNode::indent_by );
670        } else
671                os << "... on no arguments: " << endl;
[51b7345]672}
673
[a08ba92]674void CompositeExprNode::set_function( ExpressionNode *f ) {
[b87a5ed]675        function = f;
[51b7345]676}
677
[a08ba92]678void CompositeExprNode::set_args( ExpressionNode *args ) {
[b87a5ed]679        arguments = args;
[51b7345]680}
681
[bdd516a]682ExpressionNode *CompositeExprNode::get_function( void ) const {
[b87a5ed]683        return function;
[51b7345]684}
685
[bdd516a]686ExpressionNode *CompositeExprNode::get_args( void ) const {
[b87a5ed]687        return arguments;
[51b7345]688}
689
[a08ba92]690void CompositeExprNode::add_arg( ExpressionNode *arg ) {
[b87a5ed]691        if ( arguments )
692                arguments->set_link( arg );
693        else
694                set_args( arg );
[51b7345]695}
696
[cd623a4]697//##############################################################################
698
[7f5566b]699Expression *AsmExprNode::build() const {
700        return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)constraint->build(), operand->build() );
701}
702
703void AsmExprNode::print( std::ostream &os, int indent ) const {
704        os << string( indent, ' ' ) << "Assembler Expression:" << endl;
705        if ( inout ) {
706                os << string( indent, ' ' ) << "inout: " << std::endl;
707                inout->print( os, indent + 2 );
708        } // if
709        if ( constraint ) {
710                os << string( indent, ' ' ) << "constraint: " << std::endl;
711                constraint->print( os, indent + 2 );
712        } // if
713        if ( operand ) {
714                os << string( indent, ' ' ) << "operand: " << std::endl;
715                operand->print( os, indent + 2 );
716        } // if
717}
718
719void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
720        printDesignation( os );
721        os << "( ";
722        if ( inout ) inout->printOneLine( os, indent + 2 );
723        os << ", ";
724        if ( constraint ) constraint->printOneLine( os, indent + 2 );
725        os << ", ";
726        if ( operand ) operand->printOneLine( os, indent + 2 );
727        os << ") ";
728}
729
730//##############################################################################
731
732void LabelNode::print( std::ostream &os, int indent ) const {}
733
734void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
735
736//##############################################################################
737
[bdd516a]738CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
[51b7345]739
[bdd516a]740CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
[3848e0e]741}
[51b7345]742
[bdd516a]743CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
[51b7345]744}
745
[a08ba92]746CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
[b87a5ed]747        add_arg( exp );
[51b7345]748
[b87a5ed]749        return this;
[51b7345]750}
751
[3848e0e]752CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
[51b7345]753}
754
[cd623a4]755//##############################################################################
756
[bdd516a]757ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
[51b7345]758
[3848e0e]759ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
[51b7345]760}
761
762ValofExprNode::~ValofExprNode() {
[b87a5ed]763        delete body;
[51b7345]764}
765
766void ValofExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]767        printDesignation( os );
[59db689]768        os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
[b87a5ed]769        get_body()->print( os, indent + 4);
[51b7345]770}
771
[3848e0e]772void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]773        assert( false );
[51b7345]774}
775
776Expression *ValofExprNode::build() const {
[b87a5ed]777        return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
[3848e0e]778}
779
[cd623a4]780//##############################################################################
781
[bdd516a]782ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
[b87a5ed]783        if ( init_ == 0 )
784                init = 0;
785        else {
786                DeclarationNode *decl;
787                ExpressionNode *exp;
788
[a61fea9a]789                if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
[b87a5ed]790                        init = new StatementNode( decl );
791                else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
792                        init = new StatementNode( StatementNode::Exp, exp );
793                else
794                        throw SemanticError("Error in for control expression");
795        }
[51b7345]796}
797
798ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
[b87a5ed]799        : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
[51b7345]800}
801
[a08ba92]802ForCtlExprNode::~ForCtlExprNode() {
[b87a5ed]803        delete init;
804        delete condition;
805        delete change;
[51b7345]806}
807
808Expression *ForCtlExprNode::build() const {
[b87a5ed]809        // this shouldn't be used!
810        assert( false );
811        return 0;
[51b7345]812}
813
814void ForCtlExprNode::print( std::ostream &os, int indent ) const{
[59db689]815        os << string( indent,' ' ) << "For Control Expression -- :" << endl;
[a61fea9a]816
[59db689]817        os << string( indent + 2, ' ' ) << "initialization:" << endl;
[a61fea9a]818        if ( init != 0 )
819                init->printList( os, indent + 4 );
820
821        os << string( indent + 2, ' ' ) << "condition: " << endl;
822        if ( condition != 0 )
823                condition->print( os, indent + 4 );
[59db689]824        os << string( indent + 2, ' ' ) << "increment: " << endl;
[a61fea9a]825        if ( change != 0 )
826                change->print( os, indent + 4 );
[51b7345]827}
828
[3848e0e]829void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]830        assert( false );
[51b7345]831}
832
[cd623a4]833//##############################################################################
834
835TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
[51b7345]836}
837
[cd623a4]838TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
[51b7345]839}
840
[3848e0e]841Expression *TypeValueNode::build() const {
[b87a5ed]842        return new TypeExpr( decl->buildType() );
[51b7345]843}
844
[bdd516a]845void TypeValueNode::print( std::ostream &os, int indent ) const {
[b87a5ed]846        os << std::string( indent, ' ' ) << "Type:";
847        get_decl()->print( os, indent + 2);
[51b7345]848}
849
[bdd516a]850void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]851        os << "Type:";
852        get_decl()->print( os, indent + 2);
[51b7345]853}
854
[3848e0e]855ExpressionNode *flattenCommas( ExpressionNode *list ) {
[cd623a4]856        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
857                OperatorNode *op;
858                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
859                        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
860                                composite->add_arg( next );
861                        return flattenCommas( composite->get_args() );
862                } // if
863        } // if
[51b7345]864
[b87a5ed]865        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
866                list->set_next( flattenCommas( next ) );
[51b7345]867
[b87a5ed]868        return list;
[51b7345]869}
870
[3848e0e]871ExpressionNode *tupleContents( ExpressionNode *tuple ) {
[b87a5ed]872        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
873                OperatorNode *op = 0;
874                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
875                        return composite->get_args();
[cd623a4]876        } // if
[b87a5ed]877        return tuple;
[51b7345]878}
[b87a5ed]879
880// Local Variables: //
881// tab-width: 4 //
882// mode: c++ //
883// compile-command: "make install" //
884// End: //
Note: See TracBrowser for help on using the repository browser.