source: src/Parser/ExpressionNode.cc @ 47534159

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 47534159 was 47534159, checked in by Aaron Moss <a3moss@…>, 7 years ago

Added support for alignof expressions for everything but polymorphic types

  • Property mode set to 100644
File size: 26.3 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                {
589                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
590                                return new AlignofExpr( arg->get_decl()->buildType());
591                        } else {
592                                return new AlignofExpr( args.front());
593                        } // if
594                }
595          case OperatorNode::SizeOf:
596                {
597                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
598                                return new SizeofExpr( arg->get_decl()->buildType());
599                        } else {
600                                return new SizeofExpr( args.front());
601                        } // if
602                }
603          case OperatorNode::Attr:
604                {
605                        VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
606                        assert( var );
607                        if ( ! get_args()->get_link() ) {
608                                return new AttrExpr( var->build(), ( Expression*)0);
609                        } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
610                                return new AttrExpr( var->build(), arg->get_decl()->buildType());
611                        } else {
612                                return new AttrExpr( var->build(), args.back());
613                        } // if
614                }
615          case OperatorNode::CompLit:
616                throw UnimplementedError( "C99 compound literals" );
617                // the short-circuited operators
618          case OperatorNode::Or:
619          case OperatorNode::And:
620                assert( args.size() == 2);
621                return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
622          case OperatorNode::Cond:
623                {
624                        assert( args.size() == 3);
625                        std::list< Expression * >::const_iterator i = args.begin();
626                        Expression *arg1 = notZeroExpr( *i++ );
627                        Expression *arg2 = *i++;
628                        Expression *arg3 = *i++;
629                        return new ConditionalExpr( arg1, arg2, arg3 );
630                }
631          case OperatorNode::NCond:
632                throw UnimplementedError( "GNU 2-argument conditional expression" );
633          case OperatorNode::Comma:
634                {
635                        assert( args.size() == 2);
636                        std::list< Expression * >::const_iterator i = args.begin();
637                        Expression *ret = *i++;
638                        while ( i != args.end() ) {
639                                ret = new CommaExpr( ret, *i++ );
640                        }
641                        return ret;
642                }
643                // Tuples
644          case OperatorNode::TupleC:
645                {
646                        TupleExpr *ret = new TupleExpr();
647                        std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
648                        return ret;
649                }
650          default:
651                // shouldn't happen
652                return 0;
653        } // switch
654}
655
656void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
657        printDesignation( os );
658        os << "( ";
659        function->printOneLine( os, indent );
660        for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
661                cur->printOneLine( os, indent );
662        }
663        os << ") ";
664}
665
666void CompositeExprNode::print( std::ostream &os, int indent ) const {
667        printDesignation( os );
668        os << string( indent, ' ' ) << "Application of: " << endl;
669        function->print( os, indent + ParseNode::indent_by );
670
671        os << string( indent, ' ' ) ;
672        if ( arguments ) {
673                os << "... on arguments: " << endl;
674                arguments->printList( os, indent + ParseNode::indent_by );
675        } else
676                os << "... on no arguments: " << endl;
677}
678
679void CompositeExprNode::set_function( ExpressionNode *f ) {
680        function = f;
681}
682
683void CompositeExprNode::set_args( ExpressionNode *args ) {
684        arguments = args;
685}
686
687ExpressionNode *CompositeExprNode::get_function( void ) const {
688        return function;
689}
690
691ExpressionNode *CompositeExprNode::get_args( void ) const {
692        return arguments;
693}
694
695void CompositeExprNode::add_arg( ExpressionNode *arg ) {
696        if ( arguments )
697                arguments->set_link( arg );
698        else
699                set_args( arg );
700}
701
702//##############################################################################
703
704Expression *AsmExprNode::build() const {
705        return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)constraint->build(), operand->build() );
706}
707
708void AsmExprNode::print( std::ostream &os, int indent ) const {
709        os << string( indent, ' ' ) << "Assembler Expression:" << endl;
710        if ( inout ) {
711                os << string( indent, ' ' ) << "inout: " << std::endl;
712                inout->print( os, indent + 2 );
713        } // if
714        if ( constraint ) {
715                os << string( indent, ' ' ) << "constraint: " << std::endl;
716                constraint->print( os, indent + 2 );
717        } // if
718        if ( operand ) {
719                os << string( indent, ' ' ) << "operand: " << std::endl;
720                operand->print( os, indent + 2 );
721        } // if
722}
723
724void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
725        printDesignation( os );
726        os << "( ";
727        if ( inout ) inout->printOneLine( os, indent + 2 );
728        os << ", ";
729        if ( constraint ) constraint->printOneLine( os, indent + 2 );
730        os << ", ";
731        if ( operand ) operand->printOneLine( os, indent + 2 );
732        os << ") ";
733}
734
735//##############################################################################
736
737void LabelNode::print( std::ostream &os, int indent ) const {}
738
739void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
740
741//##############################################################################
742
743CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
744
745CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
746}
747
748CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
749}
750
751CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
752        add_arg( exp );
753
754        return this;
755}
756
757CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
758}
759
760//##############################################################################
761
762ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
763
764ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
765}
766
767ValofExprNode::~ValofExprNode() {
768        delete body;
769}
770
771void ValofExprNode::print( std::ostream &os, int indent ) const {
772        printDesignation( os );
773        os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
774        get_body()->print( os, indent + 4);
775}
776
777void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
778        assert( false );
779}
780
781Expression *ValofExprNode::build() const {
782        return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
783}
784
785//##############################################################################
786
787ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
788        if ( init_ == 0 )
789                init = 0;
790        else {
791                DeclarationNode *decl;
792                ExpressionNode *exp;
793
794                if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
795                        init = new StatementNode( decl );
796                else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
797                        init = new StatementNode( StatementNode::Exp, exp );
798                else
799                        throw SemanticError("Error in for control expression");
800        }
801}
802
803ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
804        : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
805}
806
807ForCtlExprNode::~ForCtlExprNode() {
808        delete init;
809        delete condition;
810        delete change;
811}
812
813Expression *ForCtlExprNode::build() const {
814        // this shouldn't be used!
815        assert( false );
816        return 0;
817}
818
819void ForCtlExprNode::print( std::ostream &os, int indent ) const{
820        os << string( indent,' ' ) << "For Control Expression -- :" << endl;
821
822        os << string( indent + 2, ' ' ) << "initialization:" << endl;
823        if ( init != 0 )
824                init->printList( os, indent + 4 );
825
826        os << string( indent + 2, ' ' ) << "condition: " << endl;
827        if ( condition != 0 )
828                condition->print( os, indent + 4 );
829        os << string( indent + 2, ' ' ) << "increment: " << endl;
830        if ( change != 0 )
831                change->print( os, indent + 4 );
832}
833
834void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
835        assert( false );
836}
837
838//##############################################################################
839
840TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
841}
842
843TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
844}
845
846Expression *TypeValueNode::build() const {
847        return new TypeExpr( decl->buildType() );
848}
849
850void TypeValueNode::print( std::ostream &os, int indent ) const {
851        os << std::string( indent, ' ' ) << "Type:";
852        get_decl()->print( os, indent + 2);
853}
854
855void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
856        os << "Type:";
857        get_decl()->print( os, indent + 2);
858}
859
860ExpressionNode *flattenCommas( ExpressionNode *list ) {
861        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
862                OperatorNode *op;
863                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
864                        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
865                                composite->add_arg( next );
866                        return flattenCommas( composite->get_args() );
867                } // if
868        } // if
869
870        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
871                list->set_next( flattenCommas( next ) );
872
873        return list;
874}
875
876ExpressionNode *tupleContents( ExpressionNode *tuple ) {
877        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
878                OperatorNode *op = 0;
879                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
880                        return composite->get_args();
881        } // if
882        return tuple;
883}
884
885// Local Variables: //
886// tab-width: 4 //
887// mode: c++ //
888// compile-command: "make install" //
889// End: //
Note: See TracBrowser for help on using the repository browser.