source: src/Parser/ExpressionNode.cc@ cd623a4

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

constant types, second attempt

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