source: src/Parser/ExpressionNode.cc@ aaf1f4d

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 with_gc
Last change on this file since aaf1f4d was 0caaa6a, checked in by Rob Schluntz <rschlunt@…>, 9 years ago

fix CompositeExprNode copy ctor bug

  • Property mode set to 100644
File size: 29.0 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 : Mon Jun 13 14:46:17 2016
13// Update Count : 307
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 "TypeData.h"
25#include "SynTree/Constant.h"
26#include "SynTree/Expression.h"
27#include "SynTree/Declaration.h"
28#include "Common/UnimplementedError.h"
29#include "parseutility.h"
30#include "Common/utility.h"
31
32using namespace std;
33
34ExpressionNode::ExpressionNode() : ParseNode() {}
35
36ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}
37
38ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
39 if ( other.argName ) {
40 argName = other.argName->clone();
41 } else {
42 argName = 0;
43 } // if
44}
45
46ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
47 argName = new VarRefNode( aName );
48 return this;
49}
50
51ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
52 argName = aDesignator;
53 return this;
54}
55
56void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
57 if ( argName ) {
58 os << string( indent, ' ' ) << "(designated by: ";
59 argName->printOneLine( os, indent );
60 os << ")" << std::endl;
61 } // if
62}
63
64//##############################################################################
65
66NullExprNode::NullExprNode() {}
67
68NullExprNode *NullExprNode::clone() const {
69 return new NullExprNode();
70}
71
72void NullExprNode::print( std::ostream & os, int indent ) const {
73 printDesignation( os );
74 os << "null expression";
75}
76
77void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
78 printDesignation( os );
79 os << "null";
80}
81
82Expression *NullExprNode::build() const {
83 return 0;
84}
85
86CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
87 return new CommaExprNode( this, exp );
88}
89
90//##############################################################################
91
92static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
93static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
94static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
95static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
96static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
97static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
98
99// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
100//
101// prefix action constant action suffix
102//
103// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
104//
105// constant BEGIN CONT ...
106// <CONT>(...)? BEGIN 0 ... // possible empty suffix
107//
108// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
109// type.
110
111ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) {
112 // lexing divides constants into 4 kinds
113 switch ( type ) {
114 case Integer:
115 {
116 static const BasicType::Kind kind[2][3] = {
117 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
118 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
119 };
120 bool dec = true, Unsigned = false; // decimal, unsigned constant
121 int size; // 0 => int, 1 => long, 2 => long long
122 unsigned long long v; // converted integral value
123 size_t last = value.length() - 1; // last character of constant
124
125 if ( value[0] == '0' ) { // octal constant ?
126 dec = false;
127 if ( last != 0 && checkX( value[1] ) ) { // hex constant ?
128 sscanf( (char *)value.c_str(), "%llx", &v );
129 //printf( "%llx %llu\n", v, v );
130 } else {
131 sscanf( (char *)value.c_str(), "%llo", &v );
132 //printf( "%llo %llu\n", v, v );
133 } // if
134 } else { // decimal constant ?
135 sscanf( (char *)value.c_str(), "%llu", &v );
136 //printf( "%llu %llu\n", v, v );
137 } // if
138
139 if ( v <= INT_MAX ) { // signed int
140 size = 0;
141 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int
142 size = 0;
143 Unsigned = true; // unsigned
144 } else if ( v <= LONG_MAX ) { // signed long int
145 size = 1;
146 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
147 size = 1;
148 Unsigned = true; // unsigned long int
149 } else if ( v <= LLONG_MAX ) { // signed long long int
150 size = 2;
151 } else { // unsigned long long int
152 size = 2;
153 Unsigned = true; // unsigned long long int
154 } // if
155
156 if ( checkU( value[last] ) ) { // suffix 'u' ?
157 Unsigned = true;
158 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ?
159 size = 1;
160 if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ?
161 size = 2;
162 } // if
163 } // if
164 } else if ( checkL( value[ last ] ) ) { // suffix 'l' ?
165 size = 1;
166 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ?
167 size = 2;
168 if ( last > 1 && checkU( value[ last - 2 ] ) ) { // suffix 'u' ?
169 Unsigned = true;
170 } // if
171 } else {
172 if ( last > 0 && checkU( value[ last - 1 ] ) ) { // suffix 'u' ?
173 Unsigned = true;
174 } // if
175 } // if
176 } // if
177 btype = kind[Unsigned][size]; // lookup constant type
178 break;
179 }
180 case Float:
181 {
182 static const BasicType::Kind kind[2][3] = {
183 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
184 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
185 };
186 bool complx = false; // real, complex
187 int size = 1; // 0 => float, 1 => double (default), 2 => long double
188 // floating-point constant has minimum of 2 characters: 1. or .1
189 size_t last = value.length() - 1;
190
191 if ( checkI( value[last] ) ) { // imaginary ?
192 complx = true;
193 last -= 1; // backup one character
194 } // if
195 if ( checkF( value[last] ) ) { // float ?
196 size = 0;
197 } else if ( checkD( value[last] ) ) { // double ?
198 size = 1;
199 } else if ( checkL( value[last] ) ) { // long double ?
200 size = 2;
201 } // if
202 if ( ! complx && checkI( value[last - 1] ) ) { // imaginary ?
203 complx = true;
204 } // if
205 btype = kind[complx][size]; // lookup constant type
206 break;
207 }
208 case Character:
209 btype = BasicType::Char; // default
210 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
211 // ???
212 } // if
213 break;
214 case String:
215 // array of char
216 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
217 if ( value[0] == 'u' && value[1] == '8' ) {
218 // ???
219 } else {
220 // ???
221 } // if
222 } // if
223 break;
224 } // switch
225} // ConstantNode::ConstantNode
226
227ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
228 assert( newValue != 0 );
229 assert( type == String );
230
231 // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
232 value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
233
234 delete newValue; // allocated by lexer
235 return this;
236}
237
238void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
239 os << string( indent, ' ' );
240 printDesignation( os );
241
242 switch ( type ) {
243 case Integer:
244 case Float:
245 os << value ;
246 break;
247 case Character:
248 os << "'" << value << "'";
249 break;
250 case String:
251 os << '"' << value << '"';
252 break;
253 } // switch
254
255 os << ' ';
256}
257
258void ConstantNode::print( std::ostream &os, int indent ) const {
259 printOneLine( os, indent );
260 os << endl;
261}
262
263Expression *ConstantNode::build() const {
264 ::Type::Qualifiers q; // no qualifiers on constants
265
266 switch ( get_type() ) {
267 case String:
268 {
269 // string should probably be a primitive type
270 ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ),
271 new ConstantExpr(
272 Constant( new BasicType( q, BasicType::UnsignedInt ),
273 toString( value.size()+1-2 ) ) ), // +1 for '\0' and -2 for '"'
274 false, false );
275 return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
276 }
277 default:
278 return new ConstantExpr( Constant( new BasicType( q, btype ), get_value() ), maybeBuild< Expression >( get_argName() ) );
279 }
280}
281
282//##############################################################################
283
284VarRefNode::VarRefNode() : isLabel( false ) {}
285
286VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
287
288VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
289}
290
291Expression *VarRefNode::build() const {
292 return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
293}
294
295void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
296 printDesignation( os );
297 os << get_name() << ' ';
298}
299
300void VarRefNode::print( std::ostream &os, int indent ) const {
301 printDesignation( os );
302 os << string( indent, ' ' ) << "Referencing: ";
303 os << "Variable: " << get_name();
304 os << endl;
305}
306
307//##############################################################################
308
309DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
310 set_argName( expr );
311 assert( get_argName() );
312
313 if ( ! isArrayIndex ) {
314 if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
315
316 stringstream ss( var->get_name() );
317 double value;
318 if ( ss >> value ) {
319 // this is a floating point constant. It MUST be
320 // ".0" or ".1", otherwise the program is invalid
321 if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
322 throw SemanticError( "invalid designator name: " + var->get_name() );
323 } // if
324 var->set_name( var->get_name().substr(1) );
325 } // if
326 } // if
327 } // if
328}
329
330DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
331}
332
333class DesignatorFixer : public Mutator {
334public:
335 virtual Expression* mutate( NameExpr *nameExpr ) {
336 if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
337 Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
338 delete nameExpr;
339 return new ConstantExpr( val );
340 }
341 return nameExpr;
342 }
343};
344
345Expression *DesignatorNode::build() const {
346 Expression * ret = maybeBuild<Expression>(get_argName());
347
348 if ( isArrayIndex ) {
349 // need to traverse entire structure and change any instances of 0 or 1 to
350 // ConstantExpr
351 DesignatorFixer fixer;
352 ret = ret->acceptMutator( fixer );
353 } // if
354
355 return ret;
356}
357
358void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
359 if ( get_argName() ) {
360 if ( isArrayIndex ) {
361 os << "[";
362 get_argName()->printOneLine( os, indent );
363 os << "]";
364 } else {
365 os << ".";
366 get_argName()->printOneLine( os, indent );
367 }
368 } // if
369}
370
371void DesignatorNode::print( std::ostream &os, int indent ) const {
372 if ( get_argName() ) {
373 if ( isArrayIndex ) {
374 os << "[";
375 get_argName()->print( os, indent );
376 os << "]";
377 } else {
378 os << ".";
379 get_argName()->print( os, indent );
380 }
381 } // if
382}
383
384//##############################################################################
385
386static const char *opName[] = {
387 "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic
388 // triadic
389 "Cond", "NCond",
390 // diadic
391 "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
392 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
393 "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
394 "?[?]", "FieldSel", "PFieldSel", "Range",
395 // monadic
396 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
397};
398
399OperatorNode::OperatorNode( Type t ) : type( t ) {}
400
401OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
402}
403
404OperatorNode::~OperatorNode() {}
405
406OperatorNode::Type OperatorNode::get_type( void ) const{
407 return type;
408}
409
410void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
411 printDesignation( os );
412 os << opName[ type ] << ' ';
413}
414
415void OperatorNode::print( std::ostream &os, int indent ) const{
416 printDesignation( os );
417 os << string( indent, ' ' ) << "Operator: " << opName[type] << endl;
418 return;
419}
420
421const char *OperatorNode::get_typename( void ) const{
422 return opName[ type ];
423}
424
425//##############################################################################
426
427CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) {
428}
429
430CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
431}
432
433CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
434 function( f ), arguments( args ) {
435}
436
437CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
438 function( f ), arguments( arg1 ) {
439 arguments->set_link( arg2 );
440}
441
442CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ), arguments( 0 ) {
443 ParseNode *cur = other.arguments;
444 while ( cur ) {
445 if ( arguments ) {
446 arguments->set_link( cur->clone() );
447 } else {
448 arguments = ( ExpressionNode*)cur->clone();
449 } // if
450 cur = cur->get_link();
451 }
452}
453
454CompositeExprNode::~CompositeExprNode() {
455 delete function;
456 delete arguments;
457}
458
459#include "Common/utility.h"
460
461Expression *CompositeExprNode::build() const {
462 OperatorNode *op;
463 std::list<Expression *> args;
464
465 buildList( get_args(), args );
466
467 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
468 return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() ));
469 } // if
470
471 switch ( op->get_type()) {
472 case OperatorNode::Incr:
473 case OperatorNode::Decr:
474 case OperatorNode::IncrPost:
475 case OperatorNode::DecrPost:
476 case OperatorNode::Assign:
477 case OperatorNode::MulAssn:
478 case OperatorNode::DivAssn:
479 case OperatorNode::ModAssn:
480 case OperatorNode::PlusAssn:
481 case OperatorNode::MinusAssn:
482 case OperatorNode::LSAssn:
483 case OperatorNode::RSAssn:
484 case OperatorNode::AndAssn:
485 case OperatorNode::ERAssn:
486 case OperatorNode::OrAssn:
487 // the rewrite rules for these expressions specify that the first argument has its address taken
488 assert( ! args.empty() );
489 args.front() = new AddressExpr( args.front() );
490 break;
491 default: // do nothing
492 ;
493 } // switch
494
495 switch ( op->get_type() ) {
496 case OperatorNode::Incr:
497 case OperatorNode::Decr:
498 case OperatorNode::IncrPost:
499 case OperatorNode::DecrPost:
500 case OperatorNode::Assign:
501 case OperatorNode::MulAssn:
502 case OperatorNode::DivAssn:
503 case OperatorNode::ModAssn:
504 case OperatorNode::PlusAssn:
505 case OperatorNode::MinusAssn:
506 case OperatorNode::LSAssn:
507 case OperatorNode::RSAssn:
508 case OperatorNode::AndAssn:
509 case OperatorNode::ERAssn:
510 case OperatorNode::OrAssn:
511 case OperatorNode::Plus:
512 case OperatorNode::Minus:
513 case OperatorNode::Mul:
514 case OperatorNode::Div:
515 case OperatorNode::Mod:
516 case OperatorNode::BitOr:
517 case OperatorNode::BitAnd:
518 case OperatorNode::Xor:
519 case OperatorNode::LShift:
520 case OperatorNode::RShift:
521 case OperatorNode::LThan:
522 case OperatorNode::GThan:
523 case OperatorNode::LEThan:
524 case OperatorNode::GEThan:
525 case OperatorNode::Eq:
526 case OperatorNode::Neq:
527 case OperatorNode::Index:
528 case OperatorNode::Range:
529 case OperatorNode::UnPlus:
530 case OperatorNode::UnMinus:
531 case OperatorNode::PointTo:
532 case OperatorNode::Neg:
533 case OperatorNode::BitNeg:
534 case OperatorNode::LabelAddress:
535 return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args );
536 case OperatorNode::AddressOf:
537 assert( args.size() == 1 );
538 assert( args.front() );
539
540 return new AddressExpr( args.front() );
541 case OperatorNode::Cast:
542 {
543 TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
544 assert( arg );
545
546 DeclarationNode *decl_node = arg->get_decl();
547 ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
548
549 Type *targetType = decl_node->buildType();
550 if ( dynamic_cast< VoidType* >( targetType ) ) {
551 delete targetType;
552 return new CastExpr( maybeBuild<Expression>(expr_node), maybeBuild< Expression >( get_argName() ) );
553 } else {
554 return new CastExpr( maybeBuild<Expression>(expr_node),targetType, maybeBuild< Expression >( get_argName() ) );
555 } // if
556 }
557 case OperatorNode::FieldSel:
558 {
559 assert( args.size() == 2 );
560
561 NameExpr *member = dynamic_cast<NameExpr *>( args.back());
562 // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
563
564 if ( member != 0 ) {
565 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
566 delete member;
567 return ret;
568 /* else if ( memberTup != 0 )
569 {
570 UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
571 delete member;
572 return ret;
573 } */
574 } else
575 assert( false );
576 }
577 case OperatorNode::PFieldSel:
578 {
579 assert( args.size() == 2 );
580
581 NameExpr *member = dynamic_cast<NameExpr *>( args.back()); // modify for Tuples xxx
582 assert( member != 0 );
583
584 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
585 deref->get_args().push_back( args.front() );
586
587 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
588 delete member;
589 return ret;
590 }
591 case OperatorNode::SizeOf:
592 {
593 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
594 return new SizeofExpr( arg->get_decl()->buildType());
595 } else {
596 return new SizeofExpr( args.front());
597 } // if
598 }
599 case OperatorNode::AlignOf:
600 {
601 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
602 return new AlignofExpr( arg->get_decl()->buildType());
603 } else {
604 return new AlignofExpr( args.front());
605 } // if
606 }
607 case OperatorNode::OffsetOf:
608 {
609 assert( args.size() == 2 );
610
611 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args() ) ) {
612 NameExpr *member = dynamic_cast<NameExpr *>( args.back() );
613 assert( member != 0 );
614
615 return new UntypedOffsetofExpr( arg->get_decl()->buildType(), member->get_name() );
616 } else assert( false );
617 }
618 case OperatorNode::Attr:
619 {
620 VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
621 assert( var );
622 if ( ! get_args()->get_link() ) {
623 return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);
624 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
625 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType());
626 } else {
627 return new AttrExpr( maybeBuild<Expression>(var), args.back());
628 } // if
629 }
630 case OperatorNode::Or:
631 case OperatorNode::And:
632 assert( args.size() == 2);
633 return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
634 case OperatorNode::Cond:
635 {
636 assert( args.size() == 3);
637 std::list< Expression * >::const_iterator i = args.begin();
638 Expression *arg1 = notZeroExpr( *i++ );
639 Expression *arg2 = *i++;
640 Expression *arg3 = *i++;
641 return new ConditionalExpr( arg1, arg2, arg3 );
642 }
643 case OperatorNode::NCond:
644 throw UnimplementedError( "GNU 2-argument conditional expression" );
645 case OperatorNode::Comma:
646 {
647 assert( args.size() == 2);
648 std::list< Expression * >::const_iterator i = args.begin();
649 Expression *ret = *i++;
650 while ( i != args.end() ) {
651 ret = new CommaExpr( ret, *i++ );
652 }
653 return ret;
654 }
655 // Tuples
656 case OperatorNode::TupleC:
657 {
658 TupleExpr *ret = new TupleExpr();
659 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
660 return ret;
661 }
662 default:
663 // shouldn't happen
664 assert( false );
665 return 0;
666 } // switch
667}
668
669void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
670 printDesignation( os );
671 os << "( ";
672 function->printOneLine( os, indent );
673 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
674 cur->printOneLine( os, indent );
675 } // for
676 os << ") ";
677}
678
679void CompositeExprNode::print( std::ostream &os, int indent ) const {
680 printDesignation( os );
681 os << string( indent, ' ' ) << "Application of: " << endl;
682 function->print( os, indent + ParseNode::indent_by );
683
684 os << string( indent, ' ' ) ;
685 if ( arguments ) {
686 os << "... on arguments: " << endl;
687 arguments->printList( os, indent + ParseNode::indent_by );
688 } else
689 os << "... on no arguments: " << endl;
690}
691
692void CompositeExprNode::set_function( ExpressionNode *f ) {
693 function = f;
694}
695
696void CompositeExprNode::set_args( ExpressionNode *args ) {
697 arguments = args;
698}
699
700ExpressionNode *CompositeExprNode::get_function( void ) const {
701 return function;
702}
703
704ExpressionNode *CompositeExprNode::get_args( void ) const {
705 return arguments;
706}
707
708void CompositeExprNode::add_arg( ExpressionNode *arg ) {
709 if ( arguments )
710 arguments->set_link( arg );
711 else
712 set_args( arg );
713}
714
715//##############################################################################
716
717Expression *AsmExprNode::build() const {
718 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
719}
720
721void AsmExprNode::print( std::ostream &os, int indent ) const {
722 os << string( indent, ' ' ) << "Assembler Expression:" << endl;
723 if ( inout ) {
724 os << string( indent, ' ' ) << "inout: " << std::endl;
725 inout->print( os, indent + 2 );
726 } // if
727 if ( constraint ) {
728 os << string( indent, ' ' ) << "constraint: " << std::endl;
729 constraint->print( os, indent + 2 );
730 } // if
731 if ( operand ) {
732 os << string( indent, ' ' ) << "operand: " << std::endl;
733 operand->print( os, indent + 2 );
734 } // if
735}
736
737void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
738 printDesignation( os );
739 os << "( ";
740 if ( inout ) inout->printOneLine( os, indent + 2 );
741 os << ", ";
742 if ( constraint ) constraint->printOneLine( os, indent + 2 );
743 os << ", ";
744 if ( operand ) operand->printOneLine( os, indent + 2 );
745 os << ") ";
746}
747
748//##############################################################################
749
750void LabelNode::print( std::ostream &os, int indent ) const {}
751
752void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
753
754//##############################################################################
755
756CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
757
758CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
759}
760
761CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
762}
763
764CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
765 add_arg( exp );
766
767 return this;
768}
769
770CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
771}
772
773//##############################################################################
774
775ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
776
777ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
778}
779
780ValofExprNode::~ValofExprNode() {
781 delete body;
782}
783
784void ValofExprNode::print( std::ostream &os, int indent ) const {
785 printDesignation( os );
786 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
787 get_body()->print( os, indent + 4);
788}
789
790void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
791 assert( false );
792}
793
794Expression *ValofExprNode::build() const {
795 return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
796}
797
798//##############################################################################
799
800ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
801 if ( init_ == 0 )
802 init = 0;
803 else {
804 DeclarationNode *decl;
805 ExpressionNode *exp;
806
807 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
808 init = new StatementNode( decl );
809 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
810 init = new StatementNode( StatementNode::Exp, exp );
811 else
812 throw SemanticError("Error in for control expression");
813 }
814}
815
816ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
817 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
818}
819
820ForCtlExprNode::~ForCtlExprNode() {
821 delete init;
822 delete condition;
823 delete change;
824}
825
826Expression *ForCtlExprNode::build() const {
827 // this shouldn't be used!
828 assert( false );
829 return 0;
830}
831
832void ForCtlExprNode::print( std::ostream &os, int indent ) const{
833 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
834
835 os << string( indent + 2, ' ' ) << "initialization:" << endl;
836 if ( init != 0 )
837 init->printList( os, indent + 4 );
838
839 os << string( indent + 2, ' ' ) << "condition: " << endl;
840 if ( condition != 0 )
841 condition->print( os, indent + 4 );
842 os << string( indent + 2, ' ' ) << "increment: " << endl;
843 if ( change != 0 )
844 change->print( os, indent + 4 );
845}
846
847void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
848 assert( false );
849}
850
851//##############################################################################
852
853TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
854}
855
856TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
857}
858
859Expression *TypeValueNode::build() const {
860 return new TypeExpr( decl->buildType() );
861}
862
863void TypeValueNode::print( std::ostream &os, int indent ) const {
864 os << std::string( indent, ' ' ) << "Type:";
865 get_decl()->print( os, indent + 2);
866}
867
868void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
869 os << "Type:";
870 get_decl()->print( os, indent + 2);
871}
872
873
874CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
875CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
876
877CompoundLiteralNode::~CompoundLiteralNode() {
878 delete kids;
879 delete type;
880}
881
882CompoundLiteralNode *CompoundLiteralNode::clone() const {
883 return new CompoundLiteralNode( *this );
884}
885
886void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
887 os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
888
889 os << string( indent + 2, ' ' ) << "type:" << endl;
890 if ( type != 0 )
891 type->print( os, indent + 4 );
892
893 os << string( indent + 2, ' ' ) << "initialization:" << endl;
894 if ( kids != 0 )
895 kids->printList( os, indent + 4 );
896}
897
898void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
899 os << "( ";
900 if ( type ) type->print( os );
901 os << ", ";
902 if ( kids ) kids->printOneLine( os );
903 os << ") ";
904}
905
906Expression *CompoundLiteralNode::build() const {
907 Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
908 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
909 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
910 // these types do not have associated type information
911 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) {
912 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
913 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) {
914 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
915 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) {
916 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
917 } else {
918 assert( false );
919 } // if
920}
921
922
923ExpressionNode *flattenCommas( ExpressionNode *list ) {
924 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
925 OperatorNode *op;
926 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
927 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
928 composite->add_arg( next );
929 return flattenCommas( composite->get_args() );
930 } // if
931 } // if
932
933 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
934 list->set_next( flattenCommas( next ) );
935
936 return list;
937}
938
939ExpressionNode *tupleContents( ExpressionNode *tuple ) {
940 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
941 OperatorNode *op = 0;
942 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
943 return composite->get_args();
944 } // if
945 return tuple;
946}
947
948// Local Variables: //
949// tab-width: 4 //
950// mode: c++ //
951// compile-command: "make install" //
952// End: //
Note: See TracBrowser for help on using the repository browser.