source: src/Parser/ExpressionNode.cc @ cd623a4

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

constant types, second attempt

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