source: src/Parser/ExpressionNode.cc @ f6835e5

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

move constant/string to unary_expression, temporarily separate asm and local label, introduce DesignatorNode?

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