// // 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 : Sun Aug 14 08:09:31 2016 // Update Count : 271 // #include #include #include #include "ParseNode.h" #include "SynTree/Statement.h" #include "SynTree/Expression.h" #include "parseutility.h" #include "Common/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 ), catchAny( false ) {} StatementNode::StatementNode( const string *name ) : ParseNode( name ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), catchAny( false ) { assert( false ); } StatementNode::StatementNode( DeclarationNode *decl ) : type( Decl ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), catchAny( false ) { assert( 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_next() ) { next->set_next( new StatementNode( dynamic_cast( decl->get_next() ) ) ); decl->set_next( 0 ); } // if } else { if ( decl->get_next() ) { next = new StatementNode( dynamic_cast( decl->get_next() ) ); decl->set_next( 0 ); } // if this->decl = decl; } // if } // if } StatementNode2::StatementNode2( DeclarationNode *decl ) { if ( decl ) { DeclarationNode *agg = decl->extractAggregate(); if ( agg ) { StatementNode *nextStmt = new StatementNode; nextStmt->type = Decl; nextStmt->decl = decl; next = nextStmt; if ( decl->get_next() ) { next->set_next( new StatementNode2( dynamic_cast(decl->get_next()) ) ); decl->set_next( 0 ); } // if } else { if ( decl->get_next() ) { next = new StatementNode2( dynamic_cast( decl->get_next() ) ); decl->set_next( 0 ); } // if agg = decl; } // if stmt = new DeclStmt( noLabels, maybeBuild(agg) ); } else { assert( false ); } // if } StatementNode::StatementNode( Type t, ExpressionNode *ctrl_label, StatementNode *block ) : type( t ), control( ctrl_label ), block( block ), labels( 0 ), target( 0 ), decl( 0 ), catchAny( 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 ), catchAny( false ) {} StatementNode::~StatementNode() { delete control; delete block; delete target; delete decl; } StatementNode * StatementNode::clone() const { assert( false ); 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::append_block( StatementNode *stmt ) { if ( stmt != 0 ) { if ( block == 0 ) block = stmt; else block->set_last( stmt ); } // if return this; } StatementNode *StatementNode::append_last_case( StatementNode *stmt ) { assert( false ); if ( stmt != 0 ) { StatementNode *next = ( StatementNode *)get_next(); 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_last( stmt ); } // if return this; } StatementNode *StatementNode2::append_last_case( StatementNode *stmt ) { StatementNode *prev = this; // find end of list and maintain previous pointer for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) { StatementNode2 *node = dynamic_cast(curr); assert( node ); assert( dynamic_cast(node->stmt) ); prev = curr; } // for // conver from StatementNode list to Statement list StatementNode2 *node = dynamic_cast(prev); std::list stmts; buildList( stmt, stmts ); // splice any new Statements to end of currents Statements CaseStmt * caseStmt = dynamic_cast(node->stmt); caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts ); 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 ( catchAny ) { 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, ' ' ) << "Cases: " << endl; block->printList( os, indent + 2 * ParseNode::indent_by ); } // if break; } // switch } Statement *StatementNode::build() const { std::list branches; std::list exps; std::list