source: src/Parser/ExpressionNode.cc @ 097e2b0

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglergc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newstringwith_gc
Last change on this file since 097e2b0 was 097e2b0, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

constructor/destructor, more example programs

  • Property mode set to 100644
File size: 26.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 : Mon Oct  5 16:37:24 2015
13// Update Count     : 255
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
290DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
291        set_argName( expr );
292        assert( get_argName() );
293
294        if ( ! isArrayIndex ) {
295                if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
296
297                        stringstream ss( var->get_name() );
298                        double value;
299                        if ( ss >> value ) {
300                                // this is a floating point constant. It MUST be
301                                // ".0" or ".1", otherwise the program is invalid
302                                if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
303                                        throw SemanticError( "invalid designator name: " + var->get_name() );
304                                } // if
305                                var->set_name( var->get_name().substr(1) );
306                        } // if
307                } // if
308        } // if
309}
310
311DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
312}
313
314class DesignatorFixer : public Mutator {
315public:
316        virtual Expression* mutate( NameExpr *nameExpr ) {
317                if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
318                        Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
319                        delete nameExpr;
320                        return new ConstantExpr( val );
321                }
322                return nameExpr;
323        }
324};
325
326Expression *DesignatorNode::build() const {
327        Expression * ret = get_argName()->build();
328
329        if ( isArrayIndex ) {
330                // need to traverse entire structure and change any instances of 0 or 1 to
331                // ConstantExpr
332                DesignatorFixer fixer;
333                ret = ret->acceptMutator( fixer );
334        } // if
335
336        return ret;
337}
338
339void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
340        if ( get_argName() ) {
341                if ( isArrayIndex ) {
342                        os << "[";
343                        get_argName()->printOneLine( os, indent );
344                        os << "]";
345                } else {
346                        os << ".";
347                        get_argName()->printOneLine( os, indent );
348                }
349        } // if
350}
351
352void DesignatorNode::print( std::ostream &os, int indent ) const {
353        if ( get_argName() ) {
354                if ( isArrayIndex ) {
355                        os << "[";
356                        get_argName()->print( os, indent );
357                        os << "]";
358                } else {
359                        os << ".";
360                        get_argName()->print( os, indent );
361                }
362        } // if
363}
364
365//##############################################################################
366
367OperatorNode::OperatorNode( Type t ) : type( t ) {}
368
369OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
370}
371
372OperatorNode::~OperatorNode() {}
373
374OperatorNode::Type OperatorNode::get_type( void ) const{
375        return type;
376}
377
378void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
379        printDesignation( os );
380        os << OpName[ type ] << ' ';
381}
382
383void OperatorNode::print( std::ostream &os, int indent ) const{
384        printDesignation( os );
385        os << string( indent, ' ' ) << "Operator: " << OpName[type] << endl;
386        return;
387}
388
389const char *OperatorNode::get_typename( void ) const{
390        return OpName[ type ];
391}
392
393const char *OperatorNode::OpName[] = {
394        "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
395        // triadic
396        "Cond",   "NCond",
397        // diadic
398        "SizeOf",     "AlignOf", "Attr", "CompLit", "Plus",    "Minus",   "Mul",     "Div",     "Mod",      "Or",
399        "And",       "BitOr",   "BitAnd",  "Xor",     "Cast",    "LShift",  "RShift",  "LThan",   "GThan",
400        "LEThan",    "GEThan", "Eq",      "Neq",     "Assign",  "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
401        "MinusAssn", "LSAssn", "RSAssn",  "AndAssn", "ERAssn",  "OrAssn",  "Index",   "FieldSel","PFieldSel",
402        "Range",
403        // monadic
404        "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
405};
406
407//##############################################################################
408
409CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) {
410}
411
412CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
413}
414
415CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
416        function( f ), arguments( args ) {
417}
418
419CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
420        function( f ), arguments( arg1 ) {
421        arguments->set_link( arg2 );
422}
423
424CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
425        ParseNode *cur = other.arguments;
426        while ( cur ) {
427                if ( arguments ) {
428                        arguments->set_link( cur->clone() );
429                } else {
430                        arguments = ( ExpressionNode*)cur->clone();
431                } // if
432                cur = cur->get_link();
433        }
434}
435
436CompositeExprNode::~CompositeExprNode() {
437        delete function;
438        delete arguments;
439}
440
441// the names that users use to define operator functions
442static const char *opFuncName[] = {
443        "",             "",             "",
444        "",             "",
445        //diadic
446        "",             "",             "",             "",             "?+?",          "?-?",  "?*?",  "?/?",  "?%?",  "",              "",
447        "?|?",          "?&?",          "?^?",  "",             "?<<?", "?>>?", "?<?",  "?>?",  "?<=?",
448        "?>=?",         "?==?",         "?!=?", "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
449        "?<<=?",        "?>>=?",        "?&=?", "?^=?", "?|=?", "?[?]", "",             "",             "Range",
450        //monadic
451        "+?",           "-?",           "",             "*?",   "!?",   "~?",   "++?",  "?++",  "--?",  "?--",  "&&"
452};
453
454#include "utility.h"
455
456Expression *CompositeExprNode::build() const {
457        OperatorNode *op;
458        std::list<Expression *> args;
459
460        buildList( get_args(), args );
461
462        if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
463                return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
464        } // if
465
466        switch ( op->get_type()) {
467          case OperatorNode::Incr:
468          case OperatorNode::Decr:
469          case OperatorNode::IncrPost:
470          case OperatorNode::DecrPost:
471          case OperatorNode::Assign:
472          case OperatorNode::MulAssn:
473          case OperatorNode::DivAssn:
474          case OperatorNode::ModAssn:
475          case OperatorNode::PlusAssn:
476          case OperatorNode::MinusAssn:
477          case OperatorNode::LSAssn:
478          case OperatorNode::RSAssn:
479          case OperatorNode::AndAssn:
480          case OperatorNode::ERAssn:
481          case OperatorNode::OrAssn:
482                // the rewrite rules for these expressions specify that the first argument has its address taken
483                assert( ! args.empty() );
484                args.front() = new AddressExpr( args.front() );
485                break;
486          default:
487                /* do nothing */
488                ;
489        }
490
491        switch ( op->get_type() ) {
492          case OperatorNode::Incr:
493          case OperatorNode::Decr:
494          case OperatorNode::IncrPost:
495          case OperatorNode::DecrPost:
496          case OperatorNode::Assign:
497          case OperatorNode::MulAssn:
498          case OperatorNode::DivAssn:
499          case OperatorNode::ModAssn:
500          case OperatorNode::PlusAssn:
501          case OperatorNode::MinusAssn:
502          case OperatorNode::LSAssn:
503          case OperatorNode::RSAssn:
504          case OperatorNode::AndAssn:
505          case OperatorNode::ERAssn:
506          case OperatorNode::OrAssn:
507          case OperatorNode::Plus:
508          case OperatorNode::Minus:
509          case OperatorNode::Mul:
510          case OperatorNode::Div:
511          case OperatorNode::Mod:
512          case OperatorNode::BitOr:
513          case OperatorNode::BitAnd:
514          case OperatorNode::Xor:
515          case OperatorNode::LShift:
516          case OperatorNode::RShift:
517          case OperatorNode::LThan:
518          case OperatorNode::GThan:
519          case OperatorNode::LEThan:
520          case OperatorNode::GEThan:
521          case OperatorNode::Eq:
522          case OperatorNode::Neq:
523          case OperatorNode::Index:
524          case OperatorNode::Range:
525          case OperatorNode::UnPlus:
526          case OperatorNode::UnMinus:
527          case OperatorNode::PointTo:
528          case OperatorNode::Neg:
529          case OperatorNode::BitNeg:
530          case OperatorNode::LabelAddress:
531                return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
532          case OperatorNode::AddressOf:
533                assert( args.size() == 1 );
534                assert( args.front() );
535
536                return new AddressExpr( args.front() );
537          case OperatorNode::Cast:
538                {
539                        TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
540                        assert( arg );
541
542                        DeclarationNode *decl_node = arg->get_decl();
543                        ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
544
545                        Type *targetType = decl_node->buildType();
546                        if ( dynamic_cast< VoidType* >( targetType ) ) {
547                                delete targetType;
548                                return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
549                        } else {
550                                return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
551                        } // if
552                }
553          case OperatorNode::FieldSel:
554                {
555                        assert( args.size() == 2 );
556
557                        NameExpr *member = dynamic_cast<NameExpr *>( args.back());
558                        // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
559
560                        if ( member != 0 ) {
561                                UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
562                                delete member;
563                                return ret;
564                                /* else if ( memberTup != 0 )
565                                   {
566                                   UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
567                                   delete member;
568                                   return ret;
569                                   } */
570                        } else
571                                assert( false );
572                }
573          case OperatorNode::PFieldSel:
574                {
575                        assert( args.size() == 2 );
576
577                        NameExpr *member = dynamic_cast<NameExpr *>( args.back());  // modify for Tuples   xxx
578                        assert( member != 0 );
579
580                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
581                        deref->get_args().push_back( args.front() );
582
583                        UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
584                        delete member;
585                        return ret;
586                }
587          case OperatorNode::AlignOf:
588          case OperatorNode::SizeOf:
589                {
590///     bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
591
592                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
593                                return new SizeofExpr( arg->get_decl()->buildType());
594                        } else {
595                                return new SizeofExpr( args.front());
596                        } // if
597                }
598          case OperatorNode::Attr:
599                {
600                        VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
601                        assert( var );
602                        if ( ! get_args()->get_link() ) {
603                                return new AttrExpr( var->build(), ( Expression*)0);
604                        } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
605                                return new AttrExpr( var->build(), arg->get_decl()->buildType());
606                        } else {
607                                return new AttrExpr( var->build(), args.back());
608                        } // if
609                }
610          case OperatorNode::CompLit:
611                throw UnimplementedError( "C99 compound literals" );
612                // the short-circuited operators
613          case OperatorNode::Or:
614          case OperatorNode::And:
615                assert( args.size() == 2);
616                return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
617          case OperatorNode::Cond:
618                {
619                        assert( args.size() == 3);
620                        std::list< Expression * >::const_iterator i = args.begin();
621                        Expression *arg1 = notZeroExpr( *i++ );
622                        Expression *arg2 = *i++;
623                        Expression *arg3 = *i++;
624                        return new ConditionalExpr( arg1, arg2, arg3 );
625                }
626          case OperatorNode::NCond:
627                throw UnimplementedError( "GNU 2-argument conditional expression" );
628          case OperatorNode::Comma:
629                {
630                        assert( args.size() == 2);
631                        std::list< Expression * >::const_iterator i = args.begin();
632                        Expression *ret = *i++;
633                        while ( i != args.end() ) {
634                                ret = new CommaExpr( ret, *i++ );
635                        }
636                        return ret;
637                }
638                // Tuples
639          case OperatorNode::TupleC:
640                {
641                        TupleExpr *ret = new TupleExpr();
642                        std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
643                        return ret;
644                }
645          default:
646                // shouldn't happen
647                return 0;
648        } // switch
649}
650
651void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
652        printDesignation( os );
653        os << "( ";
654        function->printOneLine( os, indent );
655        for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
656                cur->printOneLine( os, indent );
657        }
658        os << ") ";
659}
660
661void CompositeExprNode::print( std::ostream &os, int indent ) const {
662        printDesignation( os );
663        os << string( indent, ' ' ) << "Application of: " << endl;
664        function->print( os, indent + ParseNode::indent_by );
665
666        os << string( indent, ' ' ) ;
667        if ( arguments ) {
668                os << "... on arguments: " << endl;
669                arguments->printList( os, indent + ParseNode::indent_by );
670        } else
671                os << "... on no arguments: " << endl;
672}
673
674void CompositeExprNode::set_function( ExpressionNode *f ) {
675        function = f;
676}
677
678void CompositeExprNode::set_args( ExpressionNode *args ) {
679        arguments = args;
680}
681
682ExpressionNode *CompositeExprNode::get_function( void ) const {
683        return function;
684}
685
686ExpressionNode *CompositeExprNode::get_args( void ) const {
687        return arguments;
688}
689
690void CompositeExprNode::add_arg( ExpressionNode *arg ) {
691        if ( arguments )
692                arguments->set_link( arg );
693        else
694                set_args( arg );
695}
696
697//##############################################################################
698
699Expression *AsmExprNode::build() const {
700        return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)constraint->build(), operand->build() );
701}
702
703void AsmExprNode::print( std::ostream &os, int indent ) const {
704        os << string( indent, ' ' ) << "Assembler Expression:" << endl;
705        if ( inout ) {
706                os << string( indent, ' ' ) << "inout: " << std::endl;
707                inout->print( os, indent + 2 );
708        } // if
709        if ( constraint ) {
710                os << string( indent, ' ' ) << "constraint: " << std::endl;
711                constraint->print( os, indent + 2 );
712        } // if
713        if ( operand ) {
714                os << string( indent, ' ' ) << "operand: " << std::endl;
715                operand->print( os, indent + 2 );
716        } // if
717}
718
719void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
720        printDesignation( os );
721        os << "( ";
722        if ( inout ) inout->printOneLine( os, indent + 2 );
723        os << ", ";
724        if ( constraint ) constraint->printOneLine( os, indent + 2 );
725        os << ", ";
726        if ( operand ) operand->printOneLine( os, indent + 2 );
727        os << ") ";
728}
729
730//##############################################################################
731
732void LabelNode::print( std::ostream &os, int indent ) const {}
733
734void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
735
736//##############################################################################
737
738CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
739
740CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
741}
742
743CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
744}
745
746CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
747        add_arg( exp );
748
749        return this;
750}
751
752CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
753}
754
755//##############################################################################
756
757ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
758
759ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
760}
761
762ValofExprNode::~ValofExprNode() {
763        delete body;
764}
765
766void ValofExprNode::print( std::ostream &os, int indent ) const {
767        printDesignation( os );
768        os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
769        get_body()->print( os, indent + 4);
770}
771
772void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
773        assert( false );
774}
775
776Expression *ValofExprNode::build() const {
777        return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
778}
779
780//##############################################################################
781
782ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
783        if ( init_ == 0 )
784                init = 0;
785        else {
786                DeclarationNode *decl;
787                ExpressionNode *exp;
788
789                if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
790                        init = new StatementNode( decl );
791                else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
792                        init = new StatementNode( StatementNode::Exp, exp );
793                else
794                        throw SemanticError("Error in for control expression");
795        }
796}
797
798ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
799        : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
800}
801
802ForCtlExprNode::~ForCtlExprNode() {
803        delete init;
804        delete condition;
805        delete change;
806}
807
808Expression *ForCtlExprNode::build() const {
809        // this shouldn't be used!
810        assert( false );
811        return 0;
812}
813
814void ForCtlExprNode::print( std::ostream &os, int indent ) const{
815        os << string( indent,' ' ) << "For Control Expression -- :" << endl;
816
817        os << string( indent + 2, ' ' ) << "initialization:" << endl;
818        if ( init != 0 )
819                init->printList( os, indent + 4 );
820
821        os << string( indent + 2, ' ' ) << "condition: " << endl;
822        if ( condition != 0 )
823                condition->print( os, indent + 4 );
824        os << string( indent + 2, ' ' ) << "increment: " << endl;
825        if ( change != 0 )
826                change->print( os, indent + 4 );
827}
828
829void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
830        assert( false );
831}
832
833//##############################################################################
834
835TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
836}
837
838TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
839}
840
841Expression *TypeValueNode::build() const {
842        return new TypeExpr( decl->buildType() );
843}
844
845void TypeValueNode::print( std::ostream &os, int indent ) const {
846        os << std::string( indent, ' ' ) << "Type:";
847        get_decl()->print( os, indent + 2);
848}
849
850void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
851        os << "Type:";
852        get_decl()->print( os, indent + 2);
853}
854
855ExpressionNode *flattenCommas( ExpressionNode *list ) {
856        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
857                OperatorNode *op;
858                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
859                        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
860                                composite->add_arg( next );
861                        return flattenCommas( composite->get_args() );
862                } // if
863        } // if
864
865        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
866                list->set_next( flattenCommas( next ) );
867
868        return list;
869}
870
871ExpressionNode *tupleContents( ExpressionNode *tuple ) {
872        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
873                OperatorNode *op = 0;
874                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
875                        return composite->get_args();
876        } // if
877        return tuple;
878}
879
880// Local Variables: //
881// tab-width: 4 //
882// mode: c++ //
883// compile-command: "make install" //
884// End: //
Note: See TracBrowser for help on using the repository browser.