source: src/Parser/ExpressionNode.cc@ 5aa708c

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since 5aa708c was 1869adf, checked in by Rob Schluntz <rschlunt@…>, 10 years ago

fix label name in label address expression

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