// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // StatementNode.cc -- // // Author : Rodolfo G. Esteves // Created On : Sat May 16 14:59:41 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Thu Jul 30 14:39:39 2015 // Update Count : 130 // #include #include #include #include "ParseNode.h" #include "SynTree/Statement.h" #include "SynTree/Expression.h" #include "parseutility.h" #include "utility.h" using namespace std; const char *StatementNode::StType[] = { "Exp", "If", "Switch", "Case", "Default", "Choose", "Fallthru", "While", "Do", "For", "Goto", "Continue", "Break", "Return", "Throw", "Try", "Catch", "Finally", "Asm", "Decl" }; StatementNode::StatementNode() : ParseNode(), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) {} StatementNode::StatementNode( const string *name ) : ParseNode( name ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) {} StatementNode::StatementNode( DeclarationNode *decl ) : type( Decl ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), isCatchRest ( false ) { if ( decl ) { if ( DeclarationNode *agg = decl->extractAggregate() ) { this->decl = agg; StatementNode *nextStmt = new StatementNode; nextStmt->type = Decl; nextStmt->decl = decl; next = nextStmt; if ( decl->get_link() ) { next->set_next( new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) ) ); decl->set_next( 0 ); } // if } else { if ( decl->get_link() ) { next = new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) ); decl->set_next( 0 ); } // if this->decl = decl; } // if } // if } StatementNode::StatementNode( Type t, ExpressionNode *ctrl_label, StatementNode *block ) : type( t ), control( ctrl_label ), block( block ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) { this->control = ( t == Default ) ? 0 : control; } StatementNode::StatementNode( Type t, string *target ) : type( t ), control( 0 ), block( 0 ), labels( 0 ), target( target ), decl( 0 ), isCatchRest ( false ) {} StatementNode::~StatementNode() { delete control; delete block; delete target; delete decl; } StatementNode * StatementNode::newCatchStmt( DeclarationNode *d, StatementNode *s, bool catchRestP ) { StatementNode *ret = new StatementNode( StatementNode::Catch, 0, s ); ret->addDeclaration( d ); ret->setCatchRest( catchRestP ); return ret; } std::string StatementNode::get_target() const{ if ( target ) return *target; return string(""); } StatementNode * StatementNode::clone() const { StatementNode *newnode = new StatementNode( type, maybeClone( control ), maybeClone( block ) ); if ( target ) { newnode->target = new string( *target ); } else { newnode->target = 0; } // if newnode->decl = maybeClone( decl ); return newnode; } StatementNode *StatementNode::add_label( const std::string *l ) { if ( l != 0 ) { labels.push_front( *l ); delete l; } // if return this; } StatementNode *StatementNode::add_controlexp( ExpressionNode *e ) { if ( control && e ) control->add_to_list( e ); // xxx - check this return this; } StatementNode *StatementNode::append_block( StatementNode *stmt ) { if ( stmt != 0 ) { if ( block == 0 ) block = stmt; else block->set_link( stmt ); } // if return this; } StatementNode *StatementNode::append_last_case( StatementNode *stmt ) { if ( stmt != 0 ) { StatementNode *next = ( StatementNode *)get_link(); if ( next && ( next->get_type() == StatementNode::Case || next->get_type() == StatementNode::Default ) ) next->append_last_case ( stmt ); else if ( block == 0 ) block = stmt; else block->set_link( stmt ); } // if return this; } void StatementNode::print( std::ostream &os, int indent ) const { if ( ! labels.empty() ) { std::list::const_iterator i; os << string( indent, ' ' ); for ( i = labels.begin(); i != labels.end(); i++ ) os << *i << ":"; os << endl; } // if switch ( type ) { case Decl: decl->print( os, indent ); break; case Exp: if ( control ) { os << string( indent, ' ' ); control->print( os, indent ); os << endl; } else os << string( indent, ' ' ) << "Null Statement" << endl; break; default: os << string( indent, ' ' ) << StatementNode::StType[type] << endl; if ( type == Catch ) { if ( decl ) { os << string( indent + ParseNode::indent_by, ' ' ) << "Declaration: " << endl; decl->print( os, indent + 2 * ParseNode::indent_by ); } else if ( isCatchRest ) { os << string( indent + ParseNode::indent_by, ' ' ) << "Catches the rest " << endl; } else { ; // should never reach here } // if } // if if ( control ) { os << string( indent + ParseNode::indent_by, ' ' ) << "Control: " << endl; control->printList( os, indent + 2 * ParseNode::indent_by ); } // if if ( block ) { os << string( indent + ParseNode::indent_by, ' ' ) << "Branches of execution: " << endl; block->printList( os, indent + 2 * ParseNode::indent_by ); } // if if ( target ) { os << string( indent + ParseNode::indent_by, ' ' ) << "Target: " << get_target() << endl; } // if break; } // switch } Statement *StatementNode::build() const { std::list branches; std::list exps; std::list