// // 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 : Sat May 16 15:10:45 2015 // Update Count : 7 // #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( 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 ); } } else { if ( decl->get_link() ) { next = new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) ); decl->set_next( 0 ); } this->decl = decl; } } } StatementNode::StatementNode( Type t, ExpressionNode *ctrl_label, StatementNode *block_ ) : type( t ), control( ctrl_label ), block( block_), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) { if ( t == Default ) control = 0; } 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 labels; 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; } newnode->decl = maybeClone( decl ); return newnode; } void StatementNode::set_control( ExpressionNode *c ) { control = c; } StatementNode * StatementNode::set_block( StatementNode *b ) { block = b; return this; } ExpressionNode *StatementNode::get_control() const { return control; } StatementNode *StatementNode::get_block() const { return block; } StatementNode::Type StatementNode::get_type() const { return type; } StatementNode *StatementNode::add_label( std::string *l ) { if ( l != 0 ) { if ( labels == 0 ) labels = new std::list(); labels->push_front(*l ); delete l; } return this; } std::list *StatementNode::get_labels() const { return labels; } 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 ); } 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 ); } return this; } void StatementNode::print( std::ostream &os, int indent ) const { if ( labels != 0 ) if ( ! labels->empty()) { std::list::const_iterator i; os << '\r' << string( indent, ' '); for ( i = labels->begin(); i != labels->end(); i++ ) os << *i << ":"; os << endl; } 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 << '\r' << string( indent, ' ') << StatementNode::StType[type] << endl; if ( type == Catch ) { if ( decl ) { os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Declaration: " << endl; decl->print( os, indent + 2*ParseNode::indent_by ); } else if ( isCatchRest ) { os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Catches the rest " << endl; } else { ; // should never reach here } } if ( control ) { os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Expression: " << endl; control->printList( os, indent + 2*ParseNode::indent_by ); } if ( block ) { os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Branches of execution: " << endl; block->printList( os, indent + 2*ParseNode::indent_by ); } if ( target ) { os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Target: " << get_target() << endl; } break; } } Statement *StatementNode::build() const { std::list branches; std::list exps; std::list