std::ostream &TabCodeGen::TRANS_TARGS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalStates % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; }
std::ostream &JavaTabCodeGen::TRANS_ACTIONS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; ARRAY_ITEM( INT(TRANS_ACTION( trans )), ( t >= redFsm->transSet.length()-1 ) ); } delete[] transPtrs; return out; }
std::wostream &SplitCodeGen::PART_TRANS( int partition ) { for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { if ( trans->partitionBoundary ) { out << L"ptr" << trans->id << L":\n"; if ( trans->action != 0 ) { /* If the action contains a next, then we must preload the current * state since the action may or may not set it. */ if ( trans->action->anyNextStmt() ) out << L" " << vCS() << L" = " << trans->targ->id << L";\n"; /* Write each action in the list. */ for ( GenActionTable::Iter item = trans->action->key; item.lte(); item++ ) { ACTION( out, item->value, trans->targ->id, false, trans->action->anyNextStmt() ); } } out << L" goto pst" << trans->targ->id << L";\n"; trans->targ->partitionBoundary = true; } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->partitionBoundary ) { out << L" pst" << st->id << L":\n" L" " << vCS() << L" = " << st->id << L";\n"; if ( st->toStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ for ( GenActionTable::Iter item = st->toStateAction->key; item.lte(); item++ ) { ACTION( out, item->value, st->id, false, st->toStateAction->anyNextStmt() ); } genLineDirective( out ); } ptOutLabelUsed = true; out << L" goto _pt_out; \n"; } } return out; }
void RedFsmAp::setInTrans() { /* First pass counts the number of transitions. */ for ( TransApSet::Iter trans = transSet; trans.lte(); trans++ ) trans->targ->numInTrans += 1; /* Pass over states to allocate the needed memory. Reset the counts so we * can use them as the current size. */ for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { st->inTrans = new RedTransAp*[st->numInTrans]; st->numInTrans = 0; } /* Second pass over transitions copies pointers into the in trans list. */ for ( TransApSet::Iter trans = transSet; trans.lte(); trans++ ) trans->targ->inTrans[trans->targ->numInTrans++] = trans; }
/* Set up labelNeeded flag for each state. */ void SplitCodeGen::setLabelsNeeded() { /* If we use the _again label, then we the _again switch, which uses all * labels. */ if ( useAgainLabel() ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = true; } else { /* Do not use all labels by default, init all labelNeeded vars to false. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = false; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) trans->labelNeeded = false; /* Walk all transitions and set only those that have targs. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedTransList::Iter tel = st->outRange; tel.lte(); tel++ ) setLabelsNeeded( st, tel->value ); for ( RedTransList::Iter tel = st->outSingle; tel.lte(); tel++ ) setLabelsNeeded( st, tel->value ); if ( st->defTrans != 0 ) setLabelsNeeded( st, st->defTrans ); } } if ( !noEnd ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->outNeeded = st->labelNeeded; } else { if ( redFsm->errState != 0 ) redFsm->errState->outNeeded = true; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Any state with a transition in that has a break will need an * out label. */ if ( trans->action != 0 && trans->action->anyBreakStmt() ) trans->targ->outNeeded = true; } } }
std::ostream &JavaTabCodeGen::TRANS_TARGS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Save the position. Needed for eofTargs. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ ARRAY_ITEM( INT(trans->targ->id), ( t >= redFsm->transSet.length()-1 ) ); } delete[] transPtrs; return out; }
std::ostream &TabCodeGen::TRANS_ACTIONS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; TRANS_ACTION( trans ); if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalAct % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; }
std::ostream &RbxGotoCodeGen::TRANSITIONS() { /* Emit any transitions that have functions and that go to * this state. */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Write the label for the transition so it can be jumped to. */ rbxLabel(out << " ", label("tr", trans->id)) << "\n"; /* Destination state. */ if ( trans->action != 0 && trans->action->anyCurStateRef() ) out << "_ps = " << vCS() << "'n"; out << vCS() << " = " << trans->targ->id << "\n"; if ( trans->action != 0 ) { /* Write out the transition func. */ rbxGoto(out, label("f", trans->action->actListId)) << "\n"; } else { /* No code to execute, just loop around. */ rbxGoto(out, "_again") << "\n"; } } return out; }
std::wostream &CSharpGotoCodeGen::TRANSITIONS() { /* Emit any transitions that have functions and that go to * this state. */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Write the label for the transition so it can be jumped to. */ out << L" tr" << trans->id << L": "; /* Destination state. */ if ( trans->action != 0 && trans->action->anyCurStateRef() ) out << L"_ps = " << vCS() << L";"; out << vCS() << L" = " << trans->targ->id << L"; "; if ( trans->action != 0 ) { /* Write out the transition func. */ out << L"goto f" << trans->action->actListId << L";\n"; } else { /* No code to execute, just loop around. */ out << L"goto _again;\n"; } } return out; }
std::wostream &SplitCodeGen::PARTITION( int partition ) { outLabelUsed = false; ptOutLabelUsed = false; /* Initialize the partition boundaries, which get set during the writing * of states. After the state writing we will */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) trans->partitionBoundary = false; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->partitionBoundary = false; out << L" " << ALPH_TYPE() << L" *p = *_pp, *pe = *_ppe;\n"; if ( redFsm->anyRegCurStateRef() ) out << L" int _ps = 0;\n"; if ( redFsm->anyConditions() ) out << L" " << WIDE_ALPH_TYPE() << L" _widec;\n"; if ( useAgainLabel() ) { out << L" goto _resume;\n" L"\n" L"_again:\n" L" switch ( " << vCS() << L" ) {\n"; AGAIN_CASES() << L" default: break;\n" L" }\n" L"\n"; if ( !noEnd ) { outLabelUsed = true; out << L" if ( ++" << P() << L" == " << PE() << L" )\n" L" goto _out;\n"; } else { out << L" " << P() << L" += 1;\n"; } out << L"_resume:\n"; } out << L" switch ( " << vCS() << L" )\n {\n"; STATE_GOTOS( partition ); SWITCH_DEFAULT() << L" }\n"; PART_TRANS( partition ); EXIT_STATES( partition ); if ( outLabelUsed ) { out << L"\n" L" _out:\n" L" *_pp = p;\n" L" *_ppe = pe;\n" L" return 0;\n"; } if ( ptOutLabelUsed ) { out << L"\n" L" _pt_out:\n" L" *_pp = p;\n" L" *_ppe = pe;\n" L" return 1;\n"; } return out; }