void FsmCodeGen::LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish, bool csForced ) { ret << " switch( " << ACT() << " ) {\n"; bool haveDefault = false; for ( GenInlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ if ( lma->lmId < 0 ) { ret << " default:\n"; haveDefault = true; } else ret << " case " << lma->lmId << ":\n"; /* Write the block and close it off. */ ret << " {"; INLINE_LIST( ret, lma->children, targState, inFinish, csForced ); ret << "}\n"; ret << " break;\n"; } if ( (hostLang->lang == HostLang::D || hostLang->lang == HostLang::D2) && !haveDefault ) ret << " default: break;"; ret << " }\n" "\t"; }
void JavaTabCodeGen::LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish ) { ret << " switch( " << ACT() << " ) {\n"; for ( GenInlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ if ( lma->lmId < 0 ) ret << " default:\n"; else ret << " case " << lma->lmId << ":\n"; /* Write the block and close it off. */ ret << " {"; INLINE_LIST( ret, lma->children, targState, inFinish ); ret << "}\n"; ret << " break;\n"; } ret << " }\n" "\t"; }
void CodeGenData::resolveTargetStates( GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Goto: case GenInlineItem::Call: case GenInlineItem::Next: case GenInlineItem::Entry: item->targState = allStates + item->targId; break; default: break; } if ( item->children != 0 ) resolveTargetStates( item->children ); } }
void CodeGenData::analyzeActionList( RedAction *redAct, GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { /* Any next statements in the action table? */ if ( item->type == GenInlineItem::Next || item->type == GenInlineItem::NextExpr ) redAct->bAnyNextStmt = true; /* Any references to the current state. */ if ( item->type == GenInlineItem::Curs ) redAct->bAnyCurStateRef = true; if ( item->type == GenInlineItem::Break ) redAct->bAnyBreakStmt = true; if ( item->children != 0 ) analyzeActionList( redAct, item->children ); } }
void SplitCodeGen::setLabelsNeeded( RedStateAp *fromState, GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Goto: case GenInlineItem::Call: { /* In split code gen we only need labels for transitions across * partitions. */ if ( fromState->partition == item->targState->partition ){ /* Mark the target as needing a label. */ item->targState->labelNeeded = true; } break; } default: break; } if ( item->children != 0 ) setLabelsNeeded( fromState, item->children ); } }
void CodeGenData::analyzeAction( GenAction *act, GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { /* Only consider actions that are referenced. */ if ( act->numRefs() > 0 ) { if ( item->type == GenInlineItem::Goto || item->type == GenInlineItem::GotoExpr ) redFsm->bAnyActionGotos = true; else if ( item->type == GenInlineItem::Call || item->type == GenInlineItem::CallExpr ) redFsm->bAnyActionCalls = true; else if ( item->type == GenInlineItem::Ret ) redFsm->bAnyActionRets = true; } /* Check for various things in regular actions. */ if ( act->numTransRefs > 0 || act->numToStateRefs > 0 || act->numFromStateRefs > 0 ) { /* Any returns in regular actions? */ if ( item->type == GenInlineItem::Ret ) redFsm->bAnyRegActionRets = true; /* Any next statements in the regular actions? */ if ( item->type == GenInlineItem::Next || item->type == GenInlineItem::NextExpr ) redFsm->bAnyRegNextStmt = true; /* Any by value control in regular actions? */ if ( item->type == GenInlineItem::CallExpr || item->type == GenInlineItem::GotoExpr ) redFsm->bAnyRegActionByValControl = true; /* Any references to the current state in regular actions? */ if ( item->type == GenInlineItem::Curs ) redFsm->bAnyRegCurStateRef = true; if ( item->type == GenInlineItem::Break ) redFsm->bAnyRegBreak = true; } if ( item->children != 0 ) analyzeAction( act, item->children ); } }
void RubyCodeGen::LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish ) { ret << " case " << ACT() << "\n"; for ( GenInlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ if ( lma->lmId < 0 ) ret << " else\n"; else ret << " when " << lma->lmId << " then\n"; /* Write the block and close it off. */ ret << " begin"; INLINE_LIST( ret, lma->children, targState, inFinish ); ret << "end\n"; } ret << "end \n\t"; }
void GoCodeGen::LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish, bool csForced ) { ret << " switch " << ACT() << " {" << endl; for ( GenInlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ if ( lma->lmId < 0 ) { ret << " default:" << endl; } else ret << " case " << lma->lmId << ":" << endl; /* Write the block and close it off. */ ret << " {"; INLINE_LIST( ret, lma->children, targState, inFinish, csForced ); ret << "}" << endl; } ret << " }" << endl << " "; }
/* Write out an inline tree structure. Walks the list and possibly calls out * to virtual functions than handle language specific items in the tree. */ void FsmCodeGen::INLINE_LIST( ostream &ret, GenInlineList *inlineList, int targState, bool inFinish, bool csForced ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Text: ret << item->data; break; case GenInlineItem::Goto: GOTO( ret, item->targState->id, inFinish ); break; case GenInlineItem::Call: CALL( ret, item->targState->id, targState, inFinish ); break; case GenInlineItem::Next: NEXT( ret, item->targState->id, inFinish ); break; case GenInlineItem::Ret: RET( ret, inFinish ); break; case GenInlineItem::PChar: ret << P(); break; case GenInlineItem::Char: ret << GET_KEY(); break; case GenInlineItem::Hold: ret << P() << "--;"; break; case GenInlineItem::Exec: EXEC( ret, item, targState, inFinish ); break; case GenInlineItem::Curs: CURS( ret, inFinish ); break; case GenInlineItem::Targs: TARGS( ret, inFinish, targState ); break; case GenInlineItem::Entry: ret << item->targState->id; break; case GenInlineItem::GotoExpr: GOTO_EXPR( ret, item, inFinish ); break; case GenInlineItem::CallExpr: CALL_EXPR( ret, item, targState, inFinish ); break; case GenInlineItem::NextExpr: NEXT_EXPR( ret, item, inFinish ); break; case GenInlineItem::LmSwitch: LM_SWITCH( ret, item, targState, inFinish, csForced ); break; case GenInlineItem::LmSetActId: SET_ACT( ret, item ); break; case GenInlineItem::LmSetTokEnd: SET_TOKEND( ret, item ); break; case GenInlineItem::LmGetTokEnd: GET_TOKEND( ret, item ); break; case GenInlineItem::LmInitTokStart: INIT_TOKSTART( ret, item ); break; case GenInlineItem::LmInitAct: INIT_ACT( ret, item ); break; case GenInlineItem::LmSetTokStart: SET_TOKSTART( ret, item ); break; case GenInlineItem::SubAction: SUB_ACTION( ret, item, targState, inFinish, csForced ); break; case GenInlineItem::Break: BREAK( ret, targState, csForced ); break; } } }