source: src/Parser/ExpressionNode.cc @ 7f5566b

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

asm statement, memory leaks

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