source: src/Parser/ExpressionNode.cc@ 302d3bf3

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay 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 302d3bf3 was ca35c51, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

move implementation of ConstantNode to ConstantExpr

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