source: translator/Parser.old/ExpressionNode.cc@ c8ffe20b

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 c8ffe20b was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

initial commit

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