source: src/Parser/ExpressionNode.cc @ de62360d

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

fix computed goto, fixed -std=, implicit typedefs for enum and aggregates, add _Noreturn _Thread_local

  • Property mode set to 100644
File size: 22.9 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 : Tue Jun 23 17:46:23 2015
13// Update Count     : 152
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
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", so 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 ) ) ),  // account for '\0'
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( void ) : 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
622CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
623
624CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
625}
626
627CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
628}
629
630CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
631        add_arg( exp );
632
633        return this;
634}
635
636CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
637}
638
639//##############################################################################
640
641ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
642
643ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
644}
645
646ValofExprNode::~ValofExprNode() {
647        delete body;
648}
649
650void ValofExprNode::print( std::ostream &os, int indent ) const {
651        printDesignation( os );
652        os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
653        get_body()->print( os, indent + 4);
654}
655
656void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
657        assert( false );
658}
659
660Expression *ValofExprNode::build() const {
661        return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
662}
663
664//##############################################################################
665
666ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
667        if ( init_ == 0 )
668                init = 0;
669        else {
670                DeclarationNode *decl;
671                ExpressionNode *exp;
672
673                if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
674                        init = new StatementNode( decl );
675                else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
676                        init = new StatementNode( StatementNode::Exp, exp );
677                else
678                        throw SemanticError("Error in for control expression");
679        }
680}
681
682ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
683        : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
684}
685
686ForCtlExprNode::~ForCtlExprNode() {
687        delete init;
688        delete condition;
689        delete change;
690}
691
692Expression *ForCtlExprNode::build() const {
693        // this shouldn't be used!
694        assert( false );
695        return 0;
696}
697
698void ForCtlExprNode::print( std::ostream &os, int indent ) const{
699        os << string( indent,' ' ) << "For Control Expression -- :" << endl;
700
701        os << string( indent + 2, ' ' ) << "initialization:" << endl;
702        if ( init != 0 )
703                init->printList( os, indent + 4 );
704
705        os << string( indent + 2, ' ' ) << "condition: " << endl;
706        if ( condition != 0 )
707                condition->print( os, indent + 4 );
708        os << string( indent + 2, ' ' ) << "increment: " << endl;
709        if ( change != 0 )
710                change->print( os, indent + 4 );
711}
712
713void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
714        assert( false );
715}
716
717//##############################################################################
718
719TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
720}
721
722TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
723}
724
725Expression *TypeValueNode::build() const {
726        return new TypeExpr( decl->buildType() );
727}
728
729void TypeValueNode::print( std::ostream &os, int indent ) const {
730        os << std::string( indent, ' ' ) << "Type:";
731        get_decl()->print( os, indent + 2);
732}
733
734void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
735        os << "Type:";
736        get_decl()->print( os, indent + 2);
737}
738
739ExpressionNode *flattenCommas( ExpressionNode *list ) {
740        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
741                OperatorNode *op;
742                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
743                        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
744                                composite->add_arg( next );
745                        return flattenCommas( composite->get_args() );
746                } // if
747        } // if
748
749        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
750                list->set_next( flattenCommas( next ) );
751
752        return list;
753}
754
755ExpressionNode *tupleContents( ExpressionNode *tuple ) {
756        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
757                OperatorNode *op = 0;
758                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
759                        return composite->get_args();
760        } // if
761        return tuple;
762}
763
764// Local Variables: //
765// tab-width: 4 //
766// mode: c++ //
767// compile-command: "make install" //
768// End: //
Note: See TracBrowser for help on using the repository browser.