/* -*- C++ -*- */ #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(void) : 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(void){ 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(void) const { return control; } StatementNode *StatementNode::get_block(void) const { return block; } StatementNode::Type StatementNode::get_type(void) 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