source: src/Parser/ExpressionNode.cc @ 59db689

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 59db689 was 59db689, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

constant types, first attempt

  • Property mode set to 100644
File size: 21.7 KB
Line 
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
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sat Jun  6 23:18:19 2015
13// Update Count     : 128
14//
15
16#include <cassert>
17#include <cctype>
18#include <algorithm>
19#include <sstream>
20#include <cstdio>
21#include <climits>
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
32ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {}
33
34ExpressionNode::ExpressionNode( const string *name_ ) : ParseNode( name_ ), argName( 0 ) {}
35
36ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {
37        if ( other.argName ) {
38                argName = other.argName->clone();
39        } else {
40                argName = 0;
41        } // if
42}
43
44ExpressionNode * ExpressionNode::set_asArgName( const std::string *aName ) {
45        argName = new VarRefNode( aName );
46        return this;
47}
48
49ExpressionNode * ExpressionNode::set_asArgName( ExpressionNode *aDesignator ) {
50        argName = aDesignator;
51        return this;
52}
53
54void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
55        if ( argName ) {
56                os << string( indent, ' ' ) << "(designated by:  ";
57                argName->printOneLine( os, indent );
58                os << ")" << std::endl;
59        } // if
60}
61
62NullExprNode::NullExprNode() {}
63
64NullExprNode *NullExprNode::clone() const {
65        return new NullExprNode();
66}
67
68void NullExprNode::print( std::ostream & os, int indent ) const {
69        printDesignation( os );
70        os << "null expression";
71}
72
73void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
74        printDesignation( os );
75        os << "null";
76}
77
78Expression *NullExprNode::build() const {
79        return 0;
80}
81
82CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
83        return new CommaExprNode( this, exp );
84}
85
86static inline bool checku( char c ) { return c == 'u' || c == 'U'; }
87static inline bool checkl( char c ) { return c == 'l' || c == 'L'; }
88static inline bool checkf( char c ) { return c == 'f' || c == 'F'; }
89static inline bool checkx( char c ) { return c == 'x' || c == 'X'; }
90
91ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) {
92        switch ( type ) {
93          case Float:
94                {
95                        size_t len = value.length() - 1;
96
97                        btype = BasicType::Double;                                      // default
98                        if ( checkf( value[len] ) ) {
99                                btype = BasicType::Float;
100                        } // if
101                        if ( checkl( value[len] ) ) {
102                                btype = BasicType::LongDouble;
103                        } // if
104                        break;
105                }
106          case Integer:
107                {
108                        static const BasicType::Kind kind[2][3] = {
109                                { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
110                                { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
111                        };
112                        size_t last = value.length() - 1;                       // last character of constant
113                        unsigned long long v;                                           // converted integral value
114                        bool dec = true, Unsigned = false;                      // decimal, unsigned constant
115                        int size;                                                                       // 0 => int, 1 => long, 2 => long long
116
117                        if ( value[0] == '0' ) {                                        // octal ?
118                                dec = false;
119                                if ( last != 0 && checkx( value[1] ) ) { // hex ?
120                                        sscanf( (char *)value.c_str(), "%llx", &v );
121                                        //printf( "%llx %llu\n", v, v );
122                                } else {
123                                        sscanf( (char *)value.c_str(), "%llo", &v );
124                                        //printf( "%llo %llu\n", v, v );
125                                } // if
126                        } else {                                                                        // decimal ?
127                                sscanf( (char *)value.c_str(), "%lld", &v );
128                                //printf( "%llu %llu\n", v, v );
129                        } // if
130
131                        if ( v <= INT_MAX ) {                                           // signed int
132                                size = 0;
133                        } else if ( v <= UINT_MAX ) {                           // unsigned int
134                                size = 0;
135                                if ( ! dec ) Unsigned = true;                   // unsigned
136                        } else if ( v <= LONG_MAX ) {                           // signed long int
137                                size = 1;
138                        } else if ( v <= ULONG_MAX ) {                          // signed long int
139                                size = 1;
140                                if ( ! dec ) Unsigned = true;                   // unsigned long int
141                        } else if ( v <= LLONG_MAX ) {                          // signed long long int
142                                size = 2;
143                        } else {                                                                        // signed long long int
144                                size = 2;
145                                if ( ! dec ) Unsigned = true;                   // unsigned long long int
146                        } // if
147
148                        if ( checku( value[last] ) ) {                          // suffix 'u' ?
149                                Unsigned = true;
150                                if ( checkl( value[ last - 1 ] ) ) {    // suffix 'l' ?
151                                        size = 1;
152                                        if ( checkl( value[ last - 1 ] ) ) { // suffix 'll' ?
153                                                size = 2;
154                                        } // if
155                                } // if
156                        } else if ( checkl( value[ last ] ) ) {         // suffix 'l' ?
157                                size = 1;
158                                if ( checkl( value[ last - 1 ] ) ) {    // suffix 'll' ?
159                                        size = 2;
160                                } // if
161                                if ( checku( value[ last - 1 ] ) ) {    // suffix 'u' ?
162                                        Unsigned = true;
163                                } // if
164                        } // if
165                        btype = kind[Unsigned][size];                           // loopup type of constant
166                        break;
167                }
168          case Character:
169                btype = BasicType::Char;                                                // default
170                if ( string( "LUu" ).find( value[0] ) != string::npos ) {
171                        // ???
172                } // if
173                break;
174          case String:
175                // array of char
176                if ( string( "LUu" ).find( value[0] ) != string::npos ) {
177                        if ( value[0] == 'u' && value[1] == '8' ) {
178                                // ???
179                        } else {
180                                // ???
181                        } // if
182                } // if
183                break;
184        } // switch
185} // ConstantNode::ConstantNode
186
187ConstantNode::Type ConstantNode::get_type( void ) const {
188        return type;
189}
190
191ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
192        assert( newValue != 0 );
193        assert( type == String );
194
195        //printf( "%lu \"%s\" \"%s\"\n", value.length() - 1, value.c_str(), newValue->substr( 1, newValue->length() - 2 ).c_str() );
196        value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
197       
198        delete newValue;                                                                        // allocated by yacc
199        return this;
200}
201
202void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
203        os << string( indent, ' ' );
204        printDesignation( os );
205
206        switch ( type ) {
207          case Integer:
208          case Float:
209                os << value ;
210                break;
211          case Character:
212                os << "'" << value << "'";
213                break;
214          case String:
215                os << '"' << value << '"';
216                break;
217        } // switch
218
219        os << ' ';
220}
221
222void ConstantNode::print( std::ostream &os, int indent ) const {
223        printOneLine( os, indent );
224        os << endl;
225}
226
227Expression *ConstantNode::build() const {
228        ::Type::Qualifiers q;
229        BasicType *bt;
230
231        switch ( get_type() ) {
232          case String:
233                {
234                        // string should probably be a primitive type
235                        ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ),
236                                                                                   new ConstantExpr(
237                                                                                           Constant( new BasicType( q, BasicType::UnsignedInt ),
238                                                                                                                 toString( value.size() + 1 ) ) ),  // account for '\0'
239                                                                                   false, false );
240                        return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
241                }
242          default:
243                bt = new BasicType( q, btype );
244                return new ConstantExpr( Constant( bt, get_value() ), maybeBuild< Expression >( get_argName() ) );
245        }
246}
247
248VarRefNode::VarRefNode() : isLabel( false ) {}
249
250VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
251
252VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
253}
254
255Expression *VarRefNode::build() const {
256        return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
257}
258
259void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
260        printDesignation( os );
261        os << get_name() << ' ';
262}
263
264void VarRefNode::print( std::ostream &os, int indent ) const {
265        printDesignation( os );
266        os << string( indent, ' ' ) << "Referencing: ";
267        os << "Variable: " << get_name();
268        os << endl;
269}
270
271OperatorNode::OperatorNode( Type t ) : type( t ) {}
272
273OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
274}
275
276OperatorNode::~OperatorNode() {}
277
278OperatorNode::Type OperatorNode::get_type( void ) const{
279        return type;
280}
281
282void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
283        printDesignation( os );
284        os << OpName[ type ] << ' ';
285}
286
287void OperatorNode::print( std::ostream &os, int indent ) const{
288        printDesignation( os );
289        os << string( indent, ' ' ) << "Operator: " << OpName[type] << endl;
290        return;
291}
292
293const char *OperatorNode::get_typename( void ) const{
294        return OpName[ type ];
295}
296
297const char *OperatorNode::OpName[] = {
298        "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
299        // triadic
300        "Cond",   "NCond",
301        // diadic
302        "SizeOf",      "AlignOf", "Attr", "CompLit", "Plus",    "Minus",   "Mul",     "Div",     "Mod",      "Or",
303        "And",       "BitOr",   "BitAnd",  "Xor",     "Cast",    "LShift",  "RShift",  "LThan",   "GThan",
304        "LEThan",    "GEThan", "Eq",      "Neq",     "Assign",  "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
305        "MinusAssn", "LSAssn", "RSAssn",  "AndAssn", "ERAssn",  "OrAssn",  "Index",   "FieldSel","PFieldSel",
306        "Range",
307        // monadic
308        "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
309};
310
311CompositeExprNode::CompositeExprNode( void ) : ExpressionNode(), function( 0 ), arguments( 0 ) {
312}
313
314CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
315}
316
317CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
318        function( f ), arguments( args ) {
319}
320
321CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
322        function( f ), arguments( arg1) {
323        arguments->set_link( arg2);
324}
325
326CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
327        ParseNode *cur = other.arguments;
328        while ( cur ) {
329                if ( arguments ) {
330                        arguments->set_link( cur->clone() );
331                } else {
332                        arguments = ( ExpressionNode*)cur->clone();
333                } // if
334                cur = cur->get_link();
335        }
336}
337
338CompositeExprNode::~CompositeExprNode() {
339        delete function;
340        delete arguments;
341}
342
343// the names that users use to define operator functions
344static const char *opFuncName[] = {
345        "",  "", "",
346        "",   "",
347        // diadic
348        "",   "", "", "", "?+?",    "?-?",   "?*?",     "?/?",     "?%?",     "",       "",
349        "?|?",  "?&?",  "?^?",     "",    "?<<?",  "?>>?",  "?<?",   "?>?",    "?<=?",
350        "?>=?", "?==?",      "?!=?",     "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
351        "?<<=?", "?>>=?",  "?&=?", "?^=?",  "?|=?",  "?[?]",   "","","Range",
352        // monadic
353        "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "LabAddress"
354};
355
356#include "utility.h"
357
358Expression *CompositeExprNode::build() const {
359        OperatorNode *op;
360        std::list<Expression *> args;
361
362        buildList( get_args(), args );
363
364        if ( ! ( op = dynamic_cast<OperatorNode *>( function )) ) {
365                // a function as opposed to an operator
366                return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
367        } else {
368                switch ( op->get_type()) {
369                  case OperatorNode::Incr:
370                  case OperatorNode::Decr:
371                  case OperatorNode::IncrPost:
372                  case OperatorNode::DecrPost:
373                  case OperatorNode::Assign:
374                  case OperatorNode::MulAssn:
375                  case OperatorNode::DivAssn:
376                  case OperatorNode::ModAssn:
377                  case OperatorNode::PlusAssn:
378                  case OperatorNode::MinusAssn:
379                  case OperatorNode::LSAssn:
380                  case OperatorNode::RSAssn:
381                  case OperatorNode::AndAssn:
382                  case OperatorNode::ERAssn:
383                  case OperatorNode::OrAssn:
384                        // the rewrite rules for these expressions specify that the first argument has its address taken
385                        assert( ! args.empty() );
386                        args.front() = new AddressExpr( args.front() );
387                        break;
388                  default:
389                        /* do nothing */
390                        ;
391                }
392
393                switch ( op->get_type() ) {
394                  case OperatorNode::Incr:
395                  case OperatorNode::Decr:
396                  case OperatorNode::IncrPost:
397                  case OperatorNode::DecrPost:
398                  case OperatorNode::Assign:
399                  case OperatorNode::MulAssn:
400                  case OperatorNode::DivAssn:
401                  case OperatorNode::ModAssn:
402                  case OperatorNode::PlusAssn:
403                  case OperatorNode::MinusAssn:
404                  case OperatorNode::LSAssn:
405                  case OperatorNode::RSAssn:
406                  case OperatorNode::AndAssn:
407                  case OperatorNode::ERAssn:
408                  case OperatorNode::OrAssn:
409                  case OperatorNode::Plus:
410                  case OperatorNode::Minus:
411                  case OperatorNode::Mul:
412                  case OperatorNode::Div:
413                  case OperatorNode::Mod:
414                  case OperatorNode::BitOr:
415                  case OperatorNode::BitAnd:
416                  case OperatorNode::Xor:
417                  case OperatorNode::LShift:
418                  case OperatorNode::RShift:
419                  case OperatorNode::LThan:
420                  case OperatorNode::GThan:
421                  case OperatorNode::LEThan:
422                  case OperatorNode::GEThan:
423                  case OperatorNode::Eq:
424                  case OperatorNode::Neq:
425                  case OperatorNode::Index:
426                  case OperatorNode::Range:
427                  case OperatorNode::UnPlus:
428                  case OperatorNode::UnMinus:
429                  case OperatorNode::PointTo:
430                  case OperatorNode::Neg:
431                  case OperatorNode::BitNeg:
432                  case OperatorNode::LabelAddress:
433                        return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
434                  case OperatorNode::AddressOf:
435                        assert( args.size() == 1 );
436                        assert( args.front() );
437
438                        return new AddressExpr( args.front() );
439                  case OperatorNode::Cast:
440                        {
441                                TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
442                                assert( arg );
443
444                                DeclarationNode *decl_node = arg->get_decl();
445                                ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
446
447                                Type *targetType = decl_node->buildType();
448                                if ( dynamic_cast< VoidType* >( targetType ) ) {
449                                        delete targetType;
450                                        return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
451                                } else {
452                                        return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
453                                } // if
454                        }
455                  case OperatorNode::FieldSel:
456                        {
457                                assert( args.size() == 2 );
458
459                                NameExpr *member = dynamic_cast<NameExpr *>( args.back());
460                                // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
461
462                                if ( member != 0 ) {
463                                        UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
464                                        delete member;
465                                        return ret;
466                                        /* else if ( memberTup != 0 )
467                                           {
468                                           UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
469                                           delete member;
470                                           return ret;
471                                           } */
472                                } else
473                                        assert( false );
474                        }
475                  case OperatorNode::PFieldSel:
476                        {
477                                assert( args.size() == 2 );
478
479                                NameExpr *member = dynamic_cast<NameExpr *>( args.back());  // modify for Tuples   xxx
480                                assert( member != 0 );
481
482                                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
483                                deref->get_args().push_back( args.front() );
484
485                                UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
486                                delete member;
487                                return ret;
488                        }
489                  case OperatorNode::AlignOf:
490                  case OperatorNode::SizeOf:
491                        {
492///     bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
493
494                                if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
495                                        return new SizeofExpr( arg->get_decl()->buildType());
496                                } else {
497                                        return new SizeofExpr( args.front());
498                                } // if
499                        }
500                  case OperatorNode::Attr:
501                        {
502                                VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
503                                assert( var );
504                                if ( ! get_args()->get_link() ) {
505                                        return new AttrExpr( var->build(), ( Expression*)0);
506                                } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
507                                        return new AttrExpr( var->build(), arg->get_decl()->buildType());
508                                } else {
509                                        return new AttrExpr( var->build(), args.back());
510                                } // if
511                        }
512                  case OperatorNode::CompLit:
513                        throw UnimplementedError( "C99 compound literals" );
514                        // the short-circuited operators
515                  case OperatorNode::Or:
516                  case OperatorNode::And:
517                        assert( args.size() == 2);
518                        return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
519                  case OperatorNode::Cond:
520                        {
521                                assert( args.size() == 3);
522                                std::list< Expression* >::const_iterator i = args.begin();
523                                Expression *arg1 = notZeroExpr( *i++ );
524                                Expression *arg2 = *i++;
525                                Expression *arg3 = *i++;
526                                return new ConditionalExpr( arg1, arg2, arg3 );
527                        }
528                  case OperatorNode::NCond:
529                        throw UnimplementedError( "GNU 2-argument conditional expression" );
530                  case OperatorNode::Comma:
531                        {
532                                assert( args.size() == 2);
533                                std::list< Expression* >::const_iterator i = args.begin();
534                                Expression *ret = *i++;
535                                while ( i != args.end() ) {
536                                        ret = new CommaExpr( ret, *i++ );
537                                }
538                                return ret;
539                        }
540                        // Tuples
541                  case OperatorNode::TupleC:
542                        {
543                                TupleExpr *ret = new TupleExpr();
544                                std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
545                                return ret;
546                        }
547                  default:
548                        // shouldn't happen
549                        return 0;
550                }
551        }
552}
553
554void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
555        printDesignation( os );
556        os << "( ";
557        function->printOneLine( os, indent );
558        for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
559                cur->printOneLine( os, indent );
560        }
561        os << ") ";
562}
563
564void CompositeExprNode::print( std::ostream &os, int indent ) const {
565        printDesignation( os );
566        os << string( indent, ' ' ) << "Application of: " << endl;
567        function->print( os, indent + ParseNode::indent_by );
568
569        os << string( indent, ' ' ) ;
570        if ( arguments ) {
571                os << "... on arguments: " << endl;
572                arguments->printList( os, indent + ParseNode::indent_by );
573        } else
574                os << "... on no arguments: " << endl;
575}
576
577void CompositeExprNode::set_function( ExpressionNode *f ) {
578        function = f;
579}
580
581void CompositeExprNode::set_args( ExpressionNode *args ) {
582        arguments = args;
583}
584
585ExpressionNode *CompositeExprNode::get_function( void ) const {
586        return function;
587}
588
589ExpressionNode *CompositeExprNode::get_args( void ) const {
590        return arguments;
591}
592
593void CompositeExprNode::add_arg( ExpressionNode *arg ) {
594        if ( arguments )
595                arguments->set_link( arg );
596        else
597                set_args( arg );
598}
599
600CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
601
602CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
603}
604
605CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
606}
607
608CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
609        add_arg( exp );
610
611        return this;
612}
613
614CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
615}
616
617ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
618
619ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
620}
621
622ValofExprNode::~ValofExprNode() {
623        delete body;
624}
625
626void ValofExprNode::print( std::ostream &os, int indent ) const {
627        printDesignation( os );
628        os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
629        get_body()->print( os, indent + 4);
630}
631
632void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
633        assert( false );
634}
635
636Expression *ValofExprNode::build() const {
637        return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
638}
639
640ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
641        if ( init_ == 0 )
642                init = 0;
643        else {
644                DeclarationNode *decl;
645                ExpressionNode *exp;
646
647                if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
648                        init = new StatementNode( decl );
649                else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
650                        init = new StatementNode( StatementNode::Exp, exp );
651                else
652                        throw SemanticError("Error in for control expression");
653        }
654}
655
656ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
657        : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
658}
659
660ForCtlExprNode::~ForCtlExprNode() {
661        delete init;
662        delete condition;
663        delete change;
664}
665
666Expression *ForCtlExprNode::build() const {
667        // this shouldn't be used!
668        assert( false );
669        return 0;
670}
671
672void ForCtlExprNode::print( std::ostream &os, int indent ) const{
673        os << string( indent,' ' ) << "For Control Expression -- :" << endl;
674
675        os << string( indent + 2, ' ' ) << "initialization:" << endl;
676        if ( init != 0 )
677                init->printList( os, indent + 4 );
678
679        os << string( indent + 2, ' ' ) << "condition: " << endl;
680        if ( condition != 0 )
681                condition->print( os, indent + 4 );
682        os << string( indent + 2, ' ' ) << "increment: " << endl;
683        if ( change != 0 )
684                change->print( os, indent + 4 );
685}
686
687void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
688        assert( false );
689}
690
691TypeValueNode::TypeValueNode( DeclarationNode *decl )
692        : decl( decl ) {
693}
694
695TypeValueNode::TypeValueNode( const TypeValueNode &other )
696        : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
697}
698
699Expression *TypeValueNode::build() const {
700        return new TypeExpr( decl->buildType() );
701}
702
703void TypeValueNode::print( std::ostream &os, int indent ) const {
704        os << std::string( indent, ' ' ) << "Type:";
705        get_decl()->print( os, indent + 2);
706}
707
708void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
709        os << "Type:";
710        get_decl()->print( os, indent + 2);
711}
712
713ExpressionNode *flattenCommas( ExpressionNode *list ) {
714        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) )
715                {
716                        OperatorNode *op;
717                        if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) )
718                                {
719                                        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
720                                                composite->add_arg( next );
721                                        return flattenCommas( composite->get_args() );
722                                }
723                }
724
725        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
726                list->set_next( flattenCommas( next ) );
727
728        return list;
729}
730
731ExpressionNode *tupleContents( ExpressionNode *tuple ) {
732        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
733                OperatorNode *op = 0;
734                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
735                        return composite->get_args();
736        }
737        return tuple;
738}
739
740// Local Variables: //
741// tab-width: 4 //
742// mode: c++ //
743// compile-command: "make install" //
744// End: //
Note: See TracBrowser for help on using the repository browser.