source: src/Parser/ExpressionNode.cc@ 59db689

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 stuck-waitfor-destruct with_gc
Last change on this file since 59db689 was 59db689, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

constant types, first attempt

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