source: src/Parser/ExpressionNode.cc@ 77acda06

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 77acda06 was 47534159, checked in by Aaron Moss <a3moss@…>, 10 years ago

Added support for alignof expressions for everything but polymorphic types

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