"Fossies" - the Fresh Open Source Software Archive

Member "ragel-6.10/ragel/cdflat.cpp" (24 Mar 2017, 20734 Bytes) of package /linux/misc/ragel-6.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cdflat.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 6.9_vs_6.10.

    1 /*
    2  *  Copyright 2004-2006 Adrian Thurston <thurston@complang.org>
    3  *            2004 Erich Ocean <eric.ocean@ampede.com>
    4  *            2005 Alan West <alan@alanz.com>
    5  */
    6 
    7 /*  This file is part of Ragel.
    8  *
    9  *  Ragel is free software; you can redistribute it and/or modify
   10  *  it under the terms of the GNU General Public License as published by
   11  *  the Free Software Foundation; either version 2 of the License, or
   12  *  (at your option) any later version.
   13  * 
   14  *  Ragel is distributed in the hope that it will be useful,
   15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17  *  GNU General Public License for more details.
   18  * 
   19  *  You should have received a copy of the GNU General Public License
   20  *  along with Ragel; if not, write to the Free Software
   21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
   22  */
   23 
   24 #include "ragel.h"
   25 #include "cdflat.h"
   26 #include "redfsm.h"
   27 #include "gendata.h"
   28 
   29 std::ostream &FlatCodeGen::TO_STATE_ACTION( RedStateAp *state )
   30 {
   31     int act = 0;
   32     if ( state->toStateAction != 0 )
   33         act = state->toStateAction->location+1;
   34     out << act;
   35     return out;
   36 }
   37 
   38 std::ostream &FlatCodeGen::FROM_STATE_ACTION( RedStateAp *state )
   39 {
   40     int act = 0;
   41     if ( state->fromStateAction != 0 )
   42         act = state->fromStateAction->location+1;
   43     out << act;
   44     return out;
   45 }
   46 
   47 std::ostream &FlatCodeGen::EOF_ACTION( RedStateAp *state )
   48 {
   49     int act = 0;
   50     if ( state->eofAction != 0 )
   51         act = state->eofAction->location+1;
   52     out << act;
   53     return out;
   54 }
   55 
   56 std::ostream &FlatCodeGen::TRANS_ACTION( RedTransAp *trans )
   57 {
   58     /* If there are actions, emit them. Otherwise emit zero. */
   59     int act = 0;
   60     if ( trans->action != 0 )
   61         act = trans->action->location+1;
   62     out << act;
   63     return out;
   64 }
   65 
   66 std::ostream &FlatCodeGen::TO_STATE_ACTION_SWITCH()
   67 {
   68     /* Walk the list of functions, printing the cases. */
   69     for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
   70         /* Write out referenced actions. */
   71         if ( act->numToStateRefs > 0 ) {
   72             /* Write the case label, the action and the case break */
   73             out << "\tcase " << act->actionId << ":\n";
   74             ACTION( out, act, 0, false, false );
   75             out << "\tbreak;\n";
   76         }
   77     }
   78 
   79     genLineDirective( out );
   80     return out;
   81 }
   82 
   83 std::ostream &FlatCodeGen::FROM_STATE_ACTION_SWITCH()
   84 {
   85     /* Walk the list of functions, printing the cases. */
   86     for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
   87         /* Write out referenced actions. */
   88         if ( act->numFromStateRefs > 0 ) {
   89             /* Write the case label, the action and the case break */
   90             out << "\tcase " << act->actionId << ":\n";
   91             ACTION( out, act, 0, false, false );
   92             out << "\tbreak;\n";
   93         }
   94     }
   95 
   96     genLineDirective( out );
   97     return out;
   98 }
   99 
  100 std::ostream &FlatCodeGen::EOF_ACTION_SWITCH()
  101 {
  102     /* Walk the list of functions, printing the cases. */
  103     for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
  104         /* Write out referenced actions. */
  105         if ( act->numEofRefs > 0 ) {
  106             /* Write the case label, the action and the case break */
  107             out << "\tcase " << act->actionId << ":\n";
  108             ACTION( out, act, 0, true, false );
  109             out << "\tbreak;\n";
  110         }
  111     }
  112 
  113     genLineDirective( out );
  114     return out;
  115 }
  116 
  117 
  118 std::ostream &FlatCodeGen::ACTION_SWITCH()
  119 {
  120     /* Walk the list of functions, printing the cases. */
  121     for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
  122         /* Write out referenced actions. */
  123         if ( act->numTransRefs > 0 ) {
  124             /* Write the case label, the action and the case break */
  125             out << "\tcase " << act->actionId << ":\n";
  126             ACTION( out, act, 0, false, false );
  127             out << "\tbreak;\n";
  128         }
  129     }
  130 
  131     genLineDirective( out );
  132     return out;
  133 }
  134 
  135 
  136 std::ostream &FlatCodeGen::FLAT_INDEX_OFFSET()
  137 {
  138     out << "\t";
  139     int totalStateNum = 0, curIndOffset = 0;
  140     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  141         /* Write the index offset. */
  142         out << curIndOffset;
  143         if ( !st.last() ) {
  144             out << ", ";
  145             if ( ++totalStateNum % IALL == 0 )
  146                 out << "\n\t";
  147         }
  148         
  149         /* Move the index offset ahead. */
  150         if ( st->transList != 0 )
  151             curIndOffset += keyOps->span( st->lowKey, st->highKey );
  152 
  153         if ( st->defTrans != 0 )
  154             curIndOffset += 1;
  155     }
  156     out << "\n";
  157     return out;
  158 }
  159 
  160 std::ostream &FlatCodeGen::KEY_SPANS()
  161 {
  162     out << "\t";
  163     int totalStateNum = 0;
  164     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  165         /* Write singles length. */
  166         unsigned long long span = 0;
  167         if ( st->transList != 0 )
  168             span = keyOps->span( st->lowKey, st->highKey );
  169         out << span;
  170         if ( !st.last() ) {
  171             out << ", ";
  172             if ( ++totalStateNum % IALL == 0 )
  173                 out << "\n\t";
  174         }
  175     }
  176     out << "\n";
  177     return out;
  178 }
  179 
  180 std::ostream &FlatCodeGen::TO_STATE_ACTIONS()
  181 {
  182     out << "\t";
  183     int totalStateNum = 0;
  184     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  185         /* Write any eof action. */
  186         TO_STATE_ACTION(st);
  187         if ( !st.last() ) {
  188             out << ", ";
  189             if ( ++totalStateNum % IALL == 0 )
  190                 out << "\n\t";
  191         }
  192     }
  193     out << "\n";
  194     return out;
  195 }
  196 
  197 std::ostream &FlatCodeGen::FROM_STATE_ACTIONS()
  198 {
  199     out << "\t";
  200     int totalStateNum = 0;
  201     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  202         /* Write any eof action. */
  203         FROM_STATE_ACTION(st);
  204         if ( !st.last() ) {
  205             out << ", ";
  206             if ( ++totalStateNum % IALL == 0 )
  207                 out << "\n\t";
  208         }
  209     }
  210     out << "\n";
  211     return out;
  212 }
  213 
  214 std::ostream &FlatCodeGen::EOF_ACTIONS()
  215 {
  216     out << "\t";
  217     int totalStateNum = 0;
  218     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  219         /* Write any eof action. */
  220         EOF_ACTION(st);
  221         if ( !st.last() ) {
  222             out << ", ";
  223             if ( ++totalStateNum % IALL == 0 )
  224                 out << "\n\t";
  225         }
  226     }
  227     out << "\n";
  228     return out;
  229 }
  230 
  231 std::ostream &FlatCodeGen::EOF_TRANS()
  232 {
  233     out << "\t";
  234     int totalStateNum = 0;
  235     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  236         /* Write any eof action. */
  237 
  238         long trans = 0;
  239         if ( st->eofTrans != 0 ) {
  240             assert( st->eofTrans->pos >= 0 );
  241             trans = st->eofTrans->pos+1;
  242         }
  243         out << trans;
  244 
  245         if ( !st.last() ) {
  246             out << ", ";
  247             if ( ++totalStateNum % IALL == 0 )
  248                 out << "\n\t";
  249         }
  250     }
  251     out << "\n";
  252     return out;
  253 }
  254 
  255 
  256 std::ostream &FlatCodeGen::COND_KEYS()
  257 {
  258     out << '\t';
  259     int totalTrans = 0;
  260     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  261         /* Emit just cond low key and cond high key. */
  262         out << KEY( st->condLowKey ) << ", ";
  263         out << KEY( st->condHighKey ) << ", ";
  264         if ( ++totalTrans % IALL == 0 )
  265             out << "\n\t";
  266     }
  267 
  268     /* Output one last number so we don't have to figure out when the last
  269      * entry is and avoid writing a comma. */
  270     out << 0 << "\n";
  271     return out;
  272 }
  273 
  274 std::ostream &FlatCodeGen::COND_KEY_SPANS()
  275 {
  276     out << "\t";
  277     int totalStateNum = 0;
  278     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  279         /* Write singles length. */
  280         unsigned long long span = 0;
  281         if ( st->condList != 0 )
  282             span = keyOps->span( st->condLowKey, st->condHighKey );
  283         out << span;
  284         if ( !st.last() ) {
  285             out << ", ";
  286             if ( ++totalStateNum % IALL == 0 )
  287                 out << "\n\t";
  288         }
  289     }
  290     out << "\n";
  291     return out;
  292 }
  293 
  294 std::ostream &FlatCodeGen::CONDS()
  295 {
  296     int totalTrans = 0;
  297     out << '\t';
  298     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  299         if ( st->condList != 0 ) {
  300             /* Walk the singles. */
  301             unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey );
  302             for ( unsigned long long pos = 0; pos < span; pos++ ) {
  303                 if ( st->condList[pos] != 0 )
  304                     out << st->condList[pos]->condSpaceId + 1 << ", ";
  305                 else
  306                     out << "0, ";
  307                 if ( ++totalTrans % IALL == 0 )
  308                     out << "\n\t";
  309             }
  310         }
  311     }
  312 
  313     /* Output one last number so we don't have to figure out when the last
  314      * entry is and avoid writing a comma. */
  315     out << 0 << "\n";
  316     return out;
  317 }
  318 
  319 std::ostream &FlatCodeGen::COND_INDEX_OFFSET()
  320 {
  321     out << "\t";
  322     int totalStateNum = 0, curIndOffset = 0;
  323     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  324         /* Write the index offset. */
  325         out << curIndOffset;
  326         if ( !st.last() ) {
  327             out << ", ";
  328             if ( ++totalStateNum % IALL == 0 )
  329                 out << "\n\t";
  330         }
  331         
  332         /* Move the index offset ahead. */
  333         if ( st->condList != 0 )
  334             curIndOffset += keyOps->span( st->condLowKey, st->condHighKey );
  335     }
  336     out << "\n";
  337     return out;
  338 }
  339 
  340 
  341 std::ostream &FlatCodeGen::KEYS()
  342 {
  343     out << '\t';
  344     int totalTrans = 0;
  345     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  346         /* Emit just low key and high key. */
  347         out << KEY( st->lowKey ) << ", ";
  348         out << KEY( st->highKey ) << ", ";
  349         if ( ++totalTrans % IALL == 0 )
  350             out << "\n\t";
  351     }
  352 
  353     /* Output one last number so we don't have to figure out when the last
  354      * entry is and avoid writing a comma. */
  355     out << 0 << "\n";
  356     return out;
  357 }
  358 
  359 std::ostream &FlatCodeGen::INDICIES()
  360 {
  361     int totalTrans = 0;
  362     out << '\t';
  363     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  364         if ( st->transList != 0 ) {
  365             /* Walk the singles. */
  366             unsigned long long span = keyOps->span( st->lowKey, st->highKey );
  367             for ( unsigned long long pos = 0; pos < span; pos++ ) {
  368                 out << st->transList[pos]->id << ", ";
  369                 if ( ++totalTrans % IALL == 0 )
  370                     out << "\n\t";
  371             }
  372         }
  373 
  374         /* The state's default index goes next. */
  375         if ( st->defTrans != 0 )
  376             out << st->defTrans->id << ", ";
  377 
  378         if ( ++totalTrans % IALL == 0 )
  379             out << "\n\t";
  380     }
  381 
  382     /* Output one last number so we don't have to figure out when the last
  383      * entry is and avoid writing a comma. */
  384     out << 0 << "\n";
  385     return out;
  386 }
  387 
  388 std::ostream &FlatCodeGen::TRANS_TARGS()
  389 {
  390     /* Transitions must be written ordered by their id. */
  391     RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
  392     for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
  393         transPtrs[trans->id] = trans;
  394 
  395     /* Keep a count of the num of items in the array written. */
  396     out << '\t';
  397     int totalStates = 0;
  398     for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
  399         /* Save the position. Needed for eofTargs. */
  400         RedTransAp *trans = transPtrs[t];
  401         trans->pos = t;
  402 
  403         /* Write out the target state. */
  404         out << trans->targ->id;
  405         if ( t < redFsm->transSet.length()-1 ) {
  406             out << ", ";
  407             if ( ++totalStates % IALL == 0 )
  408                 out << "\n\t";
  409         }
  410     }
  411     out << "\n";
  412     delete[] transPtrs;
  413     return out;
  414 }
  415 
  416 
  417 std::ostream &FlatCodeGen::TRANS_ACTIONS()
  418 {
  419     /* Transitions must be written ordered by their id. */
  420     RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
  421     for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
  422         transPtrs[trans->id] = trans;
  423 
  424     /* Keep a count of the num of items in the array written. */
  425     out << '\t';
  426     int totalAct = 0;
  427     for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
  428         /* Write the function for the transition. */
  429         RedTransAp *trans = transPtrs[t];
  430         TRANS_ACTION( trans );
  431         if ( t < redFsm->transSet.length()-1 ) {
  432             out << ", ";
  433             if ( ++totalAct % IALL == 0 )
  434                 out << "\n\t";
  435         }
  436     }
  437     out << "\n";
  438     delete[] transPtrs;
  439     return out;
  440 }
  441 
  442 void FlatCodeGen::LOCATE_TRANS()
  443 {
  444     out <<
  445         "   _keys = " << ARR_OFF( K(), "(" + vCS() + "<<1)" ) << ";\n"
  446         "   _inds = " << ARR_OFF( I(), IO() + "[" + vCS() + "]" ) << ";\n"
  447         "\n"
  448         "   _slen = " << SP() << "[" << vCS() << "];\n"
  449         "   _trans = _inds[ _slen > 0 && _keys[0] <=" << GET_WIDE_KEY() << " &&\n"
  450         "       " << GET_WIDE_KEY() << " <= _keys[1] ?\n"
  451         "       " << GET_WIDE_KEY() << " - _keys[0] : _slen ];\n"
  452         "\n";
  453 }
  454 
  455 void FlatCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish )
  456 {
  457     ret << "{";
  458 
  459     ret << vCS() << " = " << gotoDest << ";";
  460 
  461     if ( inFinish && !noEnd )
  462         EOF_CHECK( ret );
  463 
  464     ret << CTRL_FLOW() << "goto _again;";
  465 
  466     ret << "}";
  467 }
  468 
  469 void FlatCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish )
  470 {
  471     ret << "{";
  472 
  473     ret << vCS() << " = (";
  474     INLINE_LIST( ret, ilItem->children, 0, inFinish, false );
  475     ret << "); ";
  476 
  477     if ( inFinish && !noEnd )
  478         EOF_CHECK( ret );
  479 
  480     ret << CTRL_FLOW() << "goto _again;";
  481 
  482     ret << "}";
  483 }
  484 
  485 void FlatCodeGen::CURS( ostream &ret, bool inFinish )
  486 {
  487     ret << "(_ps)";
  488 }
  489 
  490 void FlatCodeGen::TARGS( ostream &ret, bool inFinish, int targState )
  491 {
  492     ret << "(" << vCS() << ")";
  493 }
  494 
  495 void FlatCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish )
  496 {
  497     ret << vCS() << " = " << nextDest << ";";
  498 }
  499 
  500 void FlatCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish )
  501 {
  502     ret << vCS() << " = (";
  503     INLINE_LIST( ret, ilItem->children, 0, inFinish, false );
  504     ret << ");";
  505 }
  506 
  507 void FlatCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish )
  508 {
  509     if ( prePushExpr != 0 ) {
  510         ret << "{";
  511         INLINE_LIST( ret, prePushExpr, 0, false, false );
  512     }
  513 
  514     ret << "{";
  515 
  516     ret << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << callDest << ";";
  517 
  518     if ( inFinish && !noEnd )
  519         EOF_CHECK( ret );
  520 
  521     ret << CTRL_FLOW() << "goto _again;";
  522 
  523     ret << "}";
  524 
  525     if ( prePushExpr != 0 )
  526         ret << "}";
  527 }
  528 
  529 
  530 void FlatCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish )
  531 {
  532     if ( prePushExpr != 0 ) {
  533         ret << "{";
  534         INLINE_LIST( ret, prePushExpr, 0, false, false );
  535     }
  536 
  537     ret << "{" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = (";
  538     INLINE_LIST( ret, ilItem->children, targState, inFinish, false );
  539     ret << ");";
  540 
  541     if ( inFinish && !noEnd )
  542         EOF_CHECK( ret );
  543 
  544     ret << CTRL_FLOW() << "goto _again;";
  545     ret << "}";
  546 
  547     if ( prePushExpr != 0 )
  548         ret << "}";
  549 }
  550 
  551 
  552 void FlatCodeGen::RET( ostream &ret, bool inFinish )
  553 {
  554     ret << "{" << vCS() << " = " << STACK() << "[--" << TOP() << "];";
  555 
  556     if ( postPopExpr != 0 ) {
  557         ret << "{";
  558         INLINE_LIST( ret, postPopExpr, 0, false, false );
  559         ret << "}";
  560     }
  561 
  562     if ( inFinish && !noEnd )
  563         EOF_CHECK( ret );
  564 
  565     ret << CTRL_FLOW() << "goto _again;";
  566 
  567     ret << "}";
  568 }
  569 
  570 void FlatCodeGen::BREAK( ostream &ret, int targState, bool csForced )
  571 {
  572     outLabelUsed = true;
  573     ret << "{" << P() << "++; " << CTRL_FLOW() << "goto _out; }";
  574 }
  575 
  576 void FlatCodeGen::writeData()
  577 {
  578     /* If there are any transtion functions then output the array. If there
  579      * are none, don't bother emitting an empty array that won't be used. */
  580     if ( redFsm->anyActions() ) {
  581         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() );
  582         ACTIONS_ARRAY();
  583         CLOSE_ARRAY() <<
  584         "\n";
  585     }
  586 
  587     if ( redFsm->anyConditions() ) {
  588         OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
  589         COND_KEYS();
  590         CLOSE_ARRAY() <<
  591         "\n";
  592 
  593         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() );
  594         COND_KEY_SPANS();
  595         CLOSE_ARRAY() <<
  596         "\n";
  597 
  598         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() );
  599         CONDS();
  600         CLOSE_ARRAY() <<
  601         "\n";
  602 
  603         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() );
  604         COND_INDEX_OFFSET();
  605         CLOSE_ARRAY() <<
  606         "\n";
  607     }
  608 
  609     OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
  610     KEYS();
  611     CLOSE_ARRAY() <<
  612     "\n";
  613 
  614     OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() );
  615     KEY_SPANS();
  616     CLOSE_ARRAY() <<
  617     "\n";
  618 
  619     OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() );
  620     FLAT_INDEX_OFFSET();
  621     CLOSE_ARRAY() <<
  622     "\n";
  623 
  624     OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() );
  625     INDICIES();
  626     CLOSE_ARRAY() <<
  627     "\n";
  628 
  629     OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
  630     TRANS_TARGS();
  631     CLOSE_ARRAY() <<
  632     "\n";
  633 
  634     if ( redFsm->anyActions() ) {
  635         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() );
  636         TRANS_ACTIONS();
  637         CLOSE_ARRAY() <<
  638         "\n";
  639     }
  640 
  641     if ( redFsm->anyToStateActions() ) {
  642         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() );
  643         TO_STATE_ACTIONS();
  644         CLOSE_ARRAY() <<
  645         "\n";
  646     }
  647 
  648     if ( redFsm->anyFromStateActions() ) {
  649         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
  650         FROM_STATE_ACTIONS();
  651         CLOSE_ARRAY() <<
  652         "\n";
  653     }
  654 
  655     if ( redFsm->anyEofActions() ) {
  656         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() );
  657         EOF_ACTIONS();
  658         CLOSE_ARRAY() <<
  659         "\n";
  660     }
  661 
  662     if ( redFsm->anyEofTrans() ) {
  663         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() );
  664         EOF_TRANS();
  665         CLOSE_ARRAY() <<
  666         "\n";
  667     }
  668 
  669     STATE_IDS();
  670 }
  671 
  672 void FlatCodeGen::COND_TRANSLATE()
  673 {
  674     out << 
  675         "   _widec = " << GET_KEY() << ";\n";
  676 
  677     out <<
  678         "   _keys = " << ARR_OFF( CK(), "(" + vCS() + "<<1)" ) << ";\n"
  679         "   _conds = " << ARR_OFF( C(), CO() + "[" + vCS() + "]" ) << ";\n"
  680         "\n"
  681         "   _slen = " << CSP() << "[" << vCS() << "];\n"
  682         "   _cond = _slen > 0 && _keys[0] <=" << GET_WIDE_KEY() << " &&\n"
  683         "       " << GET_WIDE_KEY() << " <= _keys[1] ?\n"
  684         "       _conds[" << GET_WIDE_KEY() << " - _keys[0]] : 0;\n"
  685         "\n";
  686 
  687     out <<
  688         "   switch ( _cond ) {\n";
  689     for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) {
  690         GenCondSpace *condSpace = csi;
  691         out << "    case " << condSpace->condSpaceId + 1 << ": {\n";
  692         out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" <<
  693                 KEY(condSpace->baseKey) << " + (" << GET_KEY() << 
  694                 " - " << KEY(keyOps->minKey) << "));\n";
  695 
  696         for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
  697             out << TABS(2) << "if ( ";
  698             CONDITION( out, *csi );
  699             Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
  700             out << " ) _widec += " << condValOffset << ";\n";
  701         }
  702 
  703         out << "        }\n";
  704         out << "        break;\n";
  705     }
  706 
  707     SWITCH_DEFAULT();
  708 
  709     out <<
  710         "   }\n";
  711 }
  712 
  713 void FlatCodeGen::writeExec()
  714 {
  715     testEofUsed = false;
  716     outLabelUsed = false;
  717 
  718     out << 
  719         "   {\n"
  720         "   int _slen";
  721 
  722     if ( redFsm->anyRegCurStateRef() )
  723         out << ", _ps";
  724 
  725     out << 
  726         ";\n"
  727         "   int _trans";
  728 
  729     if ( redFsm->anyConditions() )
  730         out << ", _cond";
  731     out << ";\n";
  732 
  733     if ( redFsm->anyToStateActions() || 
  734             redFsm->anyRegActions() || redFsm->anyFromStateActions() )
  735     {
  736         out << 
  737             "   " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << PTR_CONST_END() << POINTER() << "_acts;\n"
  738             "   " << UINT() << " _nacts;\n"; 
  739     }
  740 
  741     out <<
  742         "   " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_keys;\n"
  743         "   " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << PTR_CONST_END() << POINTER() << "_inds;\n";
  744 
  745     if ( redFsm->anyConditions() ) {
  746         out << 
  747             "   " << PTR_CONST() << ARRAY_TYPE(redFsm->maxCond) << PTR_CONST_END() << POINTER() << "_conds;\n"
  748             "   " << WIDE_ALPH_TYPE() << " _widec;\n";
  749     }
  750 
  751     out << "\n";
  752 
  753     if ( !noEnd ) {
  754         testEofUsed = true;
  755         out << 
  756             "   if ( " << P() << " == " << PE() << " )\n"
  757             "       goto _test_eof;\n";
  758     }
  759 
  760     if ( redFsm->errState != 0 ) {
  761         outLabelUsed = true;
  762         out << 
  763             "   if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
  764             "       goto _out;\n";
  765     }
  766 
  767     out << "_resume:\n";
  768 
  769     if ( redFsm->anyFromStateActions() ) {
  770         out <<
  771             "   _acts = " << ARR_OFF( A(), FSA() + "[" + vCS() + "]" ) << ";\n"
  772             "   _nacts = " << CAST(UINT()) << " *_acts++;\n"
  773             "   while ( _nacts-- > 0 ) {\n"
  774             "       switch ( *_acts++ ) {\n";
  775             FROM_STATE_ACTION_SWITCH();
  776             SWITCH_DEFAULT() <<
  777             "       }\n"
  778             "   }\n"
  779             "\n";
  780     }
  781 
  782     if ( redFsm->anyConditions() )
  783         COND_TRANSLATE();
  784 
  785     LOCATE_TRANS();
  786 
  787     if ( redFsm->anyEofTrans() )
  788         out << "_eof_trans:\n";
  789 
  790     if ( redFsm->anyRegCurStateRef() )
  791         out << "    _ps = " << vCS() << ";\n";
  792 
  793     out <<
  794         "   " << vCS() << " = " << TT() << "[_trans];\n"
  795         "\n";
  796 
  797     if ( redFsm->anyRegActions() ) {
  798         out <<
  799             "   if ( " << TA() << "[_trans] == 0 )\n"
  800             "       goto _again;\n"
  801             "\n"
  802             "   _acts = " << ARR_OFF( A(), TA() + "[_trans]" ) << ";\n"
  803             "   _nacts = " << CAST(UINT()) << " *_acts++;\n"
  804             "   while ( _nacts-- > 0 ) {\n"
  805             "       switch ( *(_acts++) )\n     {\n";
  806             ACTION_SWITCH();
  807             SWITCH_DEFAULT() <<
  808             "       }\n"
  809             "   }\n"
  810             "\n";
  811     }
  812 
  813     if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || 
  814             redFsm->anyActionCalls() || redFsm->anyActionRets() )
  815         out << "_again:\n";
  816 
  817     if ( redFsm->anyToStateActions() ) {
  818         out <<
  819             "   _acts = " << ARR_OFF( A(),  TSA() + "[" + vCS() + "]" ) << ";\n"
  820             "   _nacts = " << CAST(UINT()) << " *_acts++;\n"
  821             "   while ( _nacts-- > 0 ) {\n"
  822             "       switch ( *_acts++ ) {\n";
  823             TO_STATE_ACTION_SWITCH();
  824             SWITCH_DEFAULT() <<
  825             "       }\n"
  826             "   }\n"
  827             "\n";
  828     }
  829 
  830     if ( redFsm->errState != 0 ) {
  831         outLabelUsed = true;
  832         out << 
  833             "   if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
  834             "       goto _out;\n";
  835     }
  836 
  837     if ( !noEnd ) {
  838         out << 
  839             "   if ( ++" << P() << " != " << PE() << " )\n"
  840             "       goto _resume;\n";
  841     }
  842     else {
  843         out << 
  844             "   " << P() << " += 1;\n"
  845             "   goto _resume;\n";
  846     }
  847 
  848     if ( testEofUsed )
  849         out << "    _test_eof: {}\n";
  850 
  851     if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
  852         out << 
  853             "   if ( " << P() << " == " << vEOF() << " )\n"
  854             "   {\n";
  855 
  856         if ( redFsm->anyEofTrans() ) {
  857             out <<
  858                 "   if ( " << ET() << "[" << vCS() << "] > 0 ) {\n"
  859                 "       _trans = " << ET() << "[" << vCS() << "] - 1;\n"
  860                 "       goto _eof_trans;\n"
  861                 "   }\n";
  862         }
  863 
  864         if ( redFsm->anyEofActions() ) {
  865             out <<
  866                 "   " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << PTR_CONST_END() << 
  867                         POINTER() << "__acts = " << 
  868                         ARR_OFF( A(), EA() + "[" + vCS() + "]" ) << ";\n"
  869                 "   " << UINT() << " __nacts = " << CAST(UINT()) << " *__acts++;\n"
  870                 "   while ( __nacts-- > 0 ) {\n"
  871                 "       switch ( *__acts++ ) {\n";
  872                 EOF_ACTION_SWITCH();
  873                 SWITCH_DEFAULT() <<
  874                 "       }\n"
  875                 "   }\n";
  876         }
  877 
  878         out <<
  879             "   }\n"
  880             "\n";
  881     }
  882 
  883     if ( outLabelUsed )
  884         out << "    _out: {}\n";
  885 
  886     out << "    }\n";
  887 }