std::ostream &RbxGotoCodeGen::EXEC_FUNCS() { /* Make labels that set acts and jump to execFuncs. Loop func indicies. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { rbxLabel(out, label("f", redAct->actListId)) << "\n" << "_acts = " << itoa( redAct->location+1 ) << "\n"; rbxGoto(out, "execFuncs") << "\n"; } } rbxLabel(out, "execFuncs") << "\n" " _nacts = " << A() << "[_acts]\n" " _acts += 1\n" " while ( _nacts > 0 ) \n" " _nacts -= 1\n" " _acts += 1\n" " case ( "<< A() << "[_acts-1] ) \n"; ACTION_SWITCH(); out << " end\n" " end \n"; rbxGoto(out, "_again"); return out; }
/* Gather various info on the machine. */ void CodeGenData::analyzeMachine() { /* Find the true count of action references. */ findFinalActionRefs(); /* Check if there are any calls in action code. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Record the occurrence of various kinds of actions. */ if ( act->numToStateRefs > 0 ) redFsm->bAnyToStateActions = true; if ( act->numFromStateRefs > 0 ) redFsm->bAnyFromStateActions = true; if ( act->numEofRefs > 0 ) redFsm->bAnyEofActions = true; if ( act->numTransRefs > 0 ) redFsm->bAnyRegActions = true; /* Recurse through the action's parse tree looking for various things. */ analyzeAction( act, act->inlineList ); } /* Analyze reduced action lists. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { for ( GenActionTable::Iter act = redAct->key; act.lte(); act++ ) analyzeActionList( redAct, act->value->inlineList ); } /* Find states that have transitions with actions that have next * statements. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Check any actions out of outSinge. */ for ( RedTransList::Iter rtel = st->outSingle; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) st->bAnyRegCurStateRef = true; } /* Check any actions out of outRange. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) st->bAnyRegCurStateRef = true; } /* Check any action out of default. */ if ( st->defTrans != 0 && st->defTrans->action != 0 && st->defTrans->action->anyCurStateRef() ) st->bAnyRegCurStateRef = true; if ( st->stateCondList.length() > 0 ) redFsm->bAnyConditions = true; if ( st->eofTrans != 0 ) redFsm->bAnyEofTrans = true; } /* Assign ids to actions that are referenced. */ assignActionIds(); /* Set the maximums of various values used for deciding types. */ setValueLimits(); }
void RedFsmAp::assignActionLocs() { int nextLocation = 0; for ( GenActionTableMap::Iter act = actionMap; act.lte(); act++ ) { /* Store the loc, skip over the array and a null terminator. */ act->location = nextLocation; nextLocation += act->key.length() + 1; } }
/* Write out the array of actions. */ std::ostream &JavaTabCodeGen::ACTIONS_ARRAY() { ARRAY_ITEM( INT(0), false ); for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) { /* Write out the length, which will never be the last character. */ ARRAY_ITEM( INT(act->key.length()), false ); for ( GenActionTable::Iter item = act->key; item.lte(); item++ ) ARRAY_ITEM( INT(item->value->actionId), (act.last() && item.last()) ); } return out; }
/* Write out the array of actions. */ std::ostream &JSCodeGen::ACTIONS_ARRAY() { START_ARRAY_LINE(); int totalActions = 0; ARRAY_ITEM( INT(0), ++totalActions, false ); for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) { /* Write out the length, which will never be the last character. */ ARRAY_ITEM( INT(act->key.length()), ++totalActions, false ); for ( GenActionTable::Iter item = act->key; item.lte(); item++ ) { ARRAY_ITEM( INT(item->value->actionId), ++totalActions, (act.last() && item.last()) ); } } END_ARRAY_LINE(); return out; }
std::wostream &FGotoCodeGen::EXEC_ACTIONS() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* We are at the start of a glob, write the case. */ out << L"f" << redAct->actListId << L":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << L"\tgoto _again;\n"; } } return out; }
std::ostream &GoFGotoCodeGen::EOF_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true, false ); } } genLineDirective( out ); return out; }
/* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &RubyFTabCodeGen::ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << "\twhen " << redAct->actListId+1 << " then\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); } } genLineDirective( out ); return out; }
/* Write out the function switch. This switch is keyed on the values * of the func index. */ std::wostream &FGotoCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << L"\tcase " << redAct->actListId+1 << L":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << L"\tbreak;\n"; } } genLineDirective( out ); return out; }
std::ostream &OCamlFGotoCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\t| " << redAct->actListId+1 << " ->\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true ); // out << "\tbreak;\n"; } } genLineDirective( out ); return out; }
std::ostream &OCamlFGotoCodeGen::EXEC_ACTIONS() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* We are at the start of a glob, write the case. */ out << "and f" << redAct->actListId << " () =\n"; out << "\tbegin try\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\twith Goto_again -> () end;\n"; out << "\tdo_again ()\n"; } } return out; }
/* Write out the function switch. This switch is keyed on the values * of the func index. */ std::wostream &OCamlFFlatCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << L"\t| " << redAct->actListId+1 << L" ->\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << L"\t()\n"; } } genLineDirective( out ); return out; }
/* Write out the array of actions. */ std::ostream &GoCodeGen::ACTIONS_ARRAY() { out << " 0, "; int totalActions = 1; for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) { /* Write out the length, which will never be the last character. */ out << act->key.length() << ", "; if ( totalActions++ % IALL == 0 ) out << endl << " "; for ( GenActionTable::Iter item = act->key; item.lte(); item++ ) { out << item->value->actionId << ", "; if ( ! (act.last() && item.last()) ) { if ( totalActions++ % IALL == 0 ) out << endl << " "; } } } out << endl; return out; }
/* Write out the array of actions. */ std::ostream &FsmCodeGen::ACTIONS_ARRAY() { out << "\t0, "; int totalActions = 1; for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) { /* Write out the length, which will never be the last character. */ out << act->key.length() << ", "; /* Put in a line break every 8 */ if ( totalActions++ % 8 == 7 ) out << "\n\t"; for ( GenActionTable::Iter item = act->key; item.lte(); item++ ) { out << item->value->actionId; if ( ! (act.last() && item.last()) ) out << ", "; /* Put in a line break every 8 */ if ( totalActions++ % 8 == 7 ) out << "\n\t"; } } out << "\n"; return out; }
std::wostream &CSharpGotoCodeGen::EXEC_FUNCS() { /* Make labels that set acts and jump to execFuncs. Loop func indicies. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { out << L" f" << redAct->actListId << L": " << L"_acts = " << itoa( redAct->location+1 ) << L";" L" goto execFuncs;\n"; } } out << L"\n" L"execFuncs:\n" L" _nacts = " << A() << L"[_acts++];\n" L" while ( _nacts-- > 0 ) {\n" L" switch ( " << A() << L"[_acts++] ) {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << L" }\n" L" }\n" L" goto _again;\n"; return out; }
void CodeGenData::setValueLimits() { redFsm->maxSingleLen = 0; redFsm->maxRangeLen = 0; redFsm->maxKeyOffset = 0; redFsm->maxIndexOffset = 0; redFsm->maxActListId = 0; redFsm->maxActionLoc = 0; redFsm->maxActArrItem = 0; redFsm->maxSpan = 0; redFsm->maxCondSpan = 0; redFsm->maxFlatIndexOffset = 0; redFsm->maxCondOffset = 0; redFsm->maxCondLen = 0; redFsm->maxCondSpaceId = 0; redFsm->maxCondIndexOffset = 0; /* In both of these cases the 0 index is reserved for no value, so the max * is one more than it would be if they started at 0. */ redFsm->maxIndex = redFsm->transSet.length(); redFsm->maxCond = condSpaceList.length(); /* The nextStateId - 1 is the last state id assigned. */ redFsm->maxState = redFsm->nextStateId - 1; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { if ( csi->condSpaceId > redFsm->maxCondSpaceId ) redFsm->maxCondSpaceId = csi->condSpaceId; } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Maximum cond length. */ if ( st->stateCondList.length() > redFsm->maxCondLen ) redFsm->maxCondLen = st->stateCondList.length(); /* Maximum single length. */ if ( st->outSingle.length() > redFsm->maxSingleLen ) redFsm->maxSingleLen = st->outSingle.length(); /* Maximum range length. */ if ( st->outRange.length() > redFsm->maxRangeLen ) redFsm->maxRangeLen = st->outRange.length(); /* The key offset index offset for the state after last is not used, skip it.. */ if ( ! st.last() ) { redFsm->maxCondOffset += st->stateCondList.length(); redFsm->maxKeyOffset += st->outSingle.length() + st->outRange.length()*2; redFsm->maxIndexOffset += st->outSingle.length() + st->outRange.length() + 2; } /* Max cond span. */ if ( st->condList != 0 ) { unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey ); if ( span > redFsm->maxCondSpan ) redFsm->maxCondSpan = span; } /* Max key span. */ if ( st->transList != 0 ) { unsigned long long span = keyOps->span( st->lowKey, st->highKey ); if ( span > redFsm->maxSpan ) redFsm->maxSpan = span; } /* Max cond index offset. */ if ( ! st.last() ) { if ( st->condList != 0 ) redFsm->maxCondIndexOffset += keyOps->span( st->condLowKey, st->condHighKey ); } /* Max flat index offset. */ if ( ! st.last() ) { if ( st->transList != 0 ) redFsm->maxFlatIndexOffset += keyOps->span( st->lowKey, st->highKey ); redFsm->maxFlatIndexOffset += 1; } } for ( GenActionTableMap::Iter at = redFsm->actionMap; at.lte(); at++ ) { /* Maximum id of action lists. */ if ( at->actListId+1 > redFsm->maxActListId ) redFsm->maxActListId = at->actListId+1; /* Maximum location of items in action array. */ if ( at->location+1 > redFsm->maxActionLoc ) redFsm->maxActionLoc = at->location+1; /* Maximum values going into the action array. */ if ( at->key.length() > redFsm->maxActArrItem ) redFsm->maxActArrItem = at->key.length(); for ( GenActionTable::Iter item = at->key; item.lte(); item++ ) { if ( item->value->actionId > redFsm->maxActArrItem ) redFsm->maxActArrItem = item->value->actionId; } } }