source: src/Parser/ExpressionNode.cc@ 2bae7307

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 2bae7307 was 843054c2, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

licencing: seventh groups of files

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