"Fossies" - the Fresh Open Source Software Archive

Member "ragel-6.10/ragel/cstable.cpp" (24 Mar 2017, 28081 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 "cstable.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 2001-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 "cstable.h"
   26 #include "redfsm.h"
   27 #include "gendata.h"
   28 
   29 /* Determine if we should use indicies or not. */
   30 void CSharpTabCodeGen::calcIndexSize()
   31 {
   32     int sizeWithInds = 0, sizeWithoutInds = 0;
   33 
   34     /* Calculate cost of using with indicies. */
   35     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
   36         int totalIndex = st->outSingle.length() + st->outRange.length() + 
   37                 (st->defTrans == 0 ? 0 : 1);
   38         sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex;
   39     }
   40     sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length();
   41     if ( redFsm->anyActions() )
   42         sizeWithInds += arrayTypeSize(redFsm->maxActionLoc) * redFsm->transSet.length();
   43 
   44     /* Calculate the cost of not using indicies. */
   45     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
   46         int totalIndex = st->outSingle.length() + st->outRange.length() + 
   47                 (st->defTrans == 0 ? 0 : 1);
   48         sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex;
   49         if ( redFsm->anyActions() )
   50             sizeWithoutInds += arrayTypeSize(redFsm->maxActionLoc) * totalIndex;
   51     }
   52 
   53     /* If using indicies reduces the size, use them. */
   54     useIndicies = sizeWithInds < sizeWithoutInds;
   55 }
   56 
   57 std::ostream &CSharpTabCodeGen::TO_STATE_ACTION( RedStateAp *state )
   58 {
   59     int act = 0;
   60     if ( state->toStateAction != 0 )
   61         act = state->toStateAction->location+1;
   62     out << act;
   63     return out;
   64 }
   65 
   66 std::ostream &CSharpTabCodeGen::FROM_STATE_ACTION( RedStateAp *state )
   67 {
   68     int act = 0;
   69     if ( state->fromStateAction != 0 )
   70         act = state->fromStateAction->location+1;
   71     out << act;
   72     return out;
   73 }
   74 
   75 std::ostream &CSharpTabCodeGen::EOF_ACTION( RedStateAp *state )
   76 {
   77     int act = 0;
   78     if ( state->eofAction != 0 )
   79         act = state->eofAction->location+1;
   80     out << act;
   81     return out;
   82 }
   83 
   84 
   85 std::ostream &CSharpTabCodeGen::TRANS_ACTION( RedTransAp *trans )
   86 {
   87     /* If there are actions, emit them. Otherwise emit zero. */
   88     int act = 0;
   89     if ( trans->action != 0 )
   90         act = trans->action->location+1;
   91     out << act;
   92     return out;
   93 }
   94 
   95 std::ostream &CSharpTabCodeGen::TO_STATE_ACTION_SWITCH()
   96 {
   97     /* Walk the list of functions, printing the cases. */
   98     for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
   99         /* Write out referenced actions. */
  100         if ( act->numToStateRefs > 0 ) {
  101             /* Write the case label, the action and the case break. */
  102             out << "\tcase " << act->actionId << ":\n";
  103             ACTION( out, act, 0, false );
  104             out << "\tbreak;\n";
  105         }
  106     }
  107 
  108     genLineDirective( out );
  109     return out;
  110 }
  111 
  112 std::ostream &CSharpTabCodeGen::FROM_STATE_ACTION_SWITCH()
  113 {
  114     /* Walk the list of functions, printing the cases. */
  115     for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
  116         /* Write out referenced actions. */
  117         if ( act->numFromStateRefs > 0 ) {
  118             /* Write the case label, the action and the case break. */
  119             out << "\tcase " << act->actionId << ":\n";
  120             ACTION( out, act, 0, false );
  121             out << "\tbreak;\n";
  122         }
  123     }
  124 
  125     genLineDirective( out );
  126     return out;
  127 }
  128 
  129 std::ostream &CSharpTabCodeGen::EOF_ACTION_SWITCH()
  130 {
  131     /* Walk the list of functions, printing the cases. */
  132     for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
  133         /* Write out referenced actions. */
  134         if ( act->numEofRefs > 0 ) {
  135             /* Write the case label, the action and the case break. */
  136             out << "\tcase " << act->actionId << ":\n";
  137             ACTION( out, act, 0, true );
  138             out << "\tbreak;\n";
  139         }
  140     }
  141 
  142     genLineDirective( out );
  143     return out;
  144 }
  145 
  146 
  147 std::ostream &CSharpTabCodeGen::ACTION_SWITCH()
  148 {
  149     /* Walk the list of functions, printing the cases. */
  150     for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
  151         /* Write out referenced actions. */
  152         if ( act->numTransRefs > 0 ) {
  153             /* Write the case label, the action and the case break. */
  154             out << "\tcase " << act->actionId << ":\n";
  155             ACTION( out, act, 0, false );
  156             out << "\tbreak;\n";
  157         }
  158     }
  159 
  160     genLineDirective( out );
  161     return out;
  162 }
  163 
  164 std::ostream &CSharpTabCodeGen::COND_OFFSETS()
  165 {
  166     out << "\t";
  167     int totalStateNum = 0, curKeyOffset = 0;
  168     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  169         /* Write the key offset. */
  170         out << curKeyOffset;
  171         if ( !st.last() ) {
  172             out << ", ";
  173             if ( ++totalStateNum % IALL == 0 )
  174                 out << "\n\t";
  175         }
  176 
  177         /* Move the key offset ahead. */
  178         curKeyOffset += st->stateCondList.length();
  179     }
  180     out << "\n";
  181     return out;
  182 }
  183 
  184 std::ostream &CSharpTabCodeGen::KEY_OFFSETS()
  185 {
  186     out << "\t";
  187     int totalStateNum = 0, curKeyOffset = 0;
  188     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  189         /* Write the key offset. */
  190         out << curKeyOffset;
  191         if ( !st.last() ) {
  192             out << ", ";
  193             if ( ++totalStateNum % IALL == 0 )
  194                 out << "\n\t";
  195         }
  196 
  197         /* Move the key offset ahead. */
  198         curKeyOffset += st->outSingle.length() + st->outRange.length()*2;
  199     }
  200     out << "\n";
  201     return out;
  202 }
  203 
  204 
  205 std::ostream &CSharpTabCodeGen::INDEX_OFFSETS()
  206 {
  207     out << "\t";
  208     int totalStateNum = 0, curIndOffset = 0;
  209     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  210         /* Write the index offset. */
  211         out << curIndOffset;
  212         if ( !st.last() ) {
  213             out << ", ";
  214             if ( ++totalStateNum % IALL == 0 )
  215                 out << "\n\t";
  216         }
  217 
  218         /* Move the index offset ahead. */
  219         curIndOffset += st->outSingle.length() + st->outRange.length();
  220         if ( st->defTrans != 0 )
  221             curIndOffset += 1;
  222     }
  223     out << "\n";
  224     return out;
  225 }
  226 
  227 std::ostream &CSharpTabCodeGen::COND_LENS()
  228 {
  229     out << "\t";
  230     int totalStateNum = 0;
  231     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  232         /* Write singles length. */
  233         out << st->stateCondList.length();
  234         if ( !st.last() ) {
  235             out << ", ";
  236             if ( ++totalStateNum % IALL == 0 )
  237                 out << "\n\t";
  238         }
  239     }
  240     out << "\n";
  241     return out;
  242 }
  243 
  244 
  245 std::ostream &CSharpTabCodeGen::SINGLE_LENS()
  246 {
  247     out << "\t";
  248     int totalStateNum = 0;
  249     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  250         /* Write singles length. */
  251         out << st->outSingle.length();
  252         if ( !st.last() ) {
  253             out << ", ";
  254             if ( ++totalStateNum % IALL == 0 )
  255                 out << "\n\t";
  256         }
  257     }
  258     out << "\n";
  259     return out;
  260 }
  261 
  262 std::ostream &CSharpTabCodeGen::RANGE_LENS()
  263 {
  264     out << "\t";
  265     int totalStateNum = 0;
  266     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  267         /* Emit length of range index. */
  268         out << st->outRange.length();
  269         if ( !st.last() ) {
  270             out << ", ";
  271             if ( ++totalStateNum % IALL == 0 )
  272                 out << "\n\t";
  273         }
  274     }
  275     out << "\n";
  276     return out;
  277 }
  278 
  279 std::ostream &CSharpTabCodeGen::TO_STATE_ACTIONS()
  280 {
  281     out << "\t";
  282     int totalStateNum = 0;
  283     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  284         /* Write any eof action. */
  285         TO_STATE_ACTION(st);
  286         if ( !st.last() ) {
  287             out << ", ";
  288             if ( ++totalStateNum % IALL == 0 )
  289                 out << "\n\t";
  290         }
  291     }
  292     out << "\n";
  293     return out;
  294 }
  295 
  296 std::ostream &CSharpTabCodeGen::FROM_STATE_ACTIONS()
  297 {
  298     out << "\t";
  299     int totalStateNum = 0;
  300     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  301         /* Write any eof action. */
  302         FROM_STATE_ACTION(st);
  303         if ( !st.last() ) {
  304             out << ", ";
  305             if ( ++totalStateNum % IALL == 0 )
  306                 out << "\n\t";
  307         }
  308     }
  309     out << "\n";
  310     return out;
  311 }
  312 
  313 std::ostream &CSharpTabCodeGen::EOF_ACTIONS()
  314 {
  315     out << "\t";
  316     int totalStateNum = 0;
  317     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  318         /* Write any eof action. */
  319         EOF_ACTION(st);
  320         if ( !st.last() ) {
  321             out << ", ";
  322             if ( ++totalStateNum % IALL == 0 )
  323                 out << "\n\t";
  324         }
  325     }
  326     out << "\n";
  327     return out;
  328 }
  329 
  330 std::ostream &CSharpTabCodeGen::EOF_TRANS()
  331 {
  332     out << "\t";
  333     int totalStateNum = 0;
  334     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  335         /* Write any eof action. */
  336         long trans = 0;
  337         if ( st->eofTrans != 0 ) {
  338             assert( st->eofTrans->pos >= 0 );
  339             trans = st->eofTrans->pos+1;
  340         }
  341         out << trans;
  342 
  343         if ( !st.last() ) {
  344             out << ", ";
  345             if ( ++totalStateNum % IALL == 0 )
  346                 out << "\n\t";
  347         }
  348     }
  349     out << "\n";
  350     return out;
  351 }
  352 
  353 
  354 std::ostream &CSharpTabCodeGen::COND_KEYS()
  355 {
  356     out << '\t';
  357     int totalTrans = 0;
  358     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  359         /* Loop the state's transitions. */
  360         for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) {
  361             /* Lower key. */
  362             out << ALPHA_KEY( sc->lowKey ) << ", ";
  363             if ( ++totalTrans % IALL == 0 )
  364                 out << "\n\t";
  365 
  366             /* Upper key. */
  367             out << ALPHA_KEY( sc->highKey ) << ", ";
  368             if ( ++totalTrans % IALL == 0 )
  369                 out << "\n\t";
  370         }
  371     }
  372 
  373     /* Output one last number so we don't have to figure out when the last
  374      * entry is and avoid writing a comma. */
  375     if ( keyOps->alphType->isChar )
  376         out << "(char) " << 0 << "\n";
  377     else
  378         out << 0 << "\n";
  379 
  380     return out;
  381 }
  382 
  383 std::ostream &CSharpTabCodeGen::COND_SPACES()
  384 {
  385     out << '\t';
  386     int totalTrans = 0;
  387     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  388         /* Loop the state's transitions. */
  389         for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) {
  390             /* Cond Space id. */
  391             out << sc->condSpace->condSpaceId << ", ";
  392             if ( ++totalTrans % IALL == 0 )
  393                 out << "\n\t";
  394         }
  395     }
  396 
  397     /* Output one last number so we don't have to figure out when the last
  398      * entry is and avoid writing a comma. */
  399     out << 0 << "\n";
  400     return out;
  401 }
  402 
  403 std::ostream &CSharpTabCodeGen::KEYS()
  404 {
  405     out << '\t';
  406     int totalTrans = 0;
  407     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  408         /* Loop the singles. */
  409         for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
  410             out << ALPHA_KEY( stel->lowKey ) << ", ";
  411             if ( ++totalTrans % IALL == 0 )
  412                 out << "\n\t";
  413         }
  414 
  415         /* Loop the state's transitions. */
  416         for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
  417             /* Lower key. */
  418             out << ALPHA_KEY( rtel->lowKey ) << ", ";
  419             if ( ++totalTrans % IALL == 0 )
  420                 out << "\n\t";
  421 
  422             /* Upper key. */
  423             out << ALPHA_KEY( rtel->highKey ) << ", ";
  424             if ( ++totalTrans % IALL == 0 )
  425                 out << "\n\t";
  426         }
  427     }
  428 
  429     /* Output one last number so we don't have to figure out when the last
  430      * entry is and avoid writing a comma. */
  431     if ( keyOps->alphType->isChar )
  432         out << "(char) " << 0 << "\n";
  433     else
  434         out << 0 << "\n";
  435 
  436     return out;
  437 }
  438 
  439 std::ostream &CSharpTabCodeGen::INDICIES()
  440 {
  441     int totalTrans = 0;
  442     out << '\t';
  443     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  444         /* Walk the singles. */
  445         for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
  446             out << stel->value->id << ", ";
  447             if ( ++totalTrans % IALL == 0 )
  448                 out << "\n\t";
  449         }
  450 
  451         /* Walk the ranges. */
  452         for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
  453             out << rtel->value->id << ", ";
  454             if ( ++totalTrans % IALL == 0 )
  455                 out << "\n\t";
  456         }
  457 
  458         /* The state's default index goes next. */
  459         if ( st->defTrans != 0 ) {
  460             out << st->defTrans->id << ", ";
  461             if ( ++totalTrans % IALL == 0 )
  462                 out << "\n\t";
  463         }
  464     }
  465 
  466     /* Output one last number so we don't have to figure out when the last
  467      * entry is and avoid writing a comma. */
  468     out << 0 << "\n";
  469     return out;
  470 }
  471 
  472 std::ostream &CSharpTabCodeGen::TRANS_TARGS()
  473 {
  474     int totalTrans = 0;
  475     out << '\t';
  476     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  477         /* Walk the singles. */
  478         for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
  479             RedTransAp *trans = stel->value;
  480             out << trans->targ->id << ", ";
  481             if ( ++totalTrans % IALL == 0 )
  482                 out << "\n\t";
  483         }
  484 
  485         /* Walk the ranges. */
  486         for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
  487             RedTransAp *trans = rtel->value;
  488             out << trans->targ->id << ", ";
  489             if ( ++totalTrans % IALL == 0 )
  490                 out << "\n\t";
  491         }
  492 
  493         /* The state's default target state. */
  494         if ( st->defTrans != 0 ) {
  495             RedTransAp *trans = st->defTrans;
  496             out << trans->targ->id << ", ";
  497             if ( ++totalTrans % IALL == 0 )
  498                 out << "\n\t";
  499         }
  500     }
  501 
  502     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  503         if ( st->eofTrans != 0 ) {
  504             RedTransAp *trans = st->eofTrans;
  505             trans->pos = totalTrans;
  506             out << trans->targ->id << ", ";
  507             if ( ++totalTrans % IALL == 0 )
  508                 out << "\n\t";
  509         }
  510     }
  511 
  512 
  513     /* Output one last number so we don't have to figure out when the last
  514      * entry is and avoid writing a comma. */
  515     out << 0 << "\n";
  516     return out;
  517 }
  518 
  519 
  520 std::ostream &CSharpTabCodeGen::TRANS_ACTIONS()
  521 {
  522     int totalTrans = 0;
  523     out << '\t';
  524     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  525         /* Walk the singles. */
  526         for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
  527             RedTransAp *trans = stel->value;
  528             TRANS_ACTION( trans ) << ", ";
  529             if ( ++totalTrans % IALL == 0 )
  530                 out << "\n\t";
  531         }
  532 
  533         /* Walk the ranges. */
  534         for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
  535             RedTransAp *trans = rtel->value;
  536             TRANS_ACTION( trans ) << ", ";
  537             if ( ++totalTrans % IALL == 0 )
  538                 out << "\n\t";
  539         }
  540 
  541         /* The state's default index goes next. */
  542         if ( st->defTrans != 0 ) {
  543             RedTransAp *trans = st->defTrans;
  544             TRANS_ACTION( trans ) << ", ";
  545             if ( ++totalTrans % IALL == 0 )
  546                 out << "\n\t";
  547         }
  548     }
  549 
  550     for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  551         if ( st->eofTrans != 0 ) {
  552             RedTransAp *trans = st->eofTrans;
  553             TRANS_ACTION( trans ) << ", ";
  554             if ( ++totalTrans % IALL == 0 )
  555                 out << "\n\t";
  556         }
  557     }
  558 
  559     /* Output one last number so we don't have to figure out when the last
  560      * entry is and avoid writing a comma. */
  561     out << 0 << "\n";
  562     return out;
  563 }
  564 
  565 std::ostream &CSharpTabCodeGen::TRANS_TARGS_WI()
  566 {
  567     /* Transitions must be written ordered by their id. */
  568     RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
  569     for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
  570         transPtrs[trans->id] = trans;
  571 
  572     /* Keep a count of the num of items in the array written. */
  573     out << '\t';
  574     int totalStates = 0;
  575     for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
  576         /* Record the position, need this for eofTrans. */
  577         RedTransAp *trans = transPtrs[t];
  578         trans->pos = t;
  579 
  580         /* Write out the target state. */
  581         out << trans->targ->id;
  582         if ( t < redFsm->transSet.length()-1 ) {
  583             out << ", ";
  584             if ( ++totalStates % IALL == 0 )
  585                 out << "\n\t";
  586         }
  587     }
  588     out << "\n";
  589     delete[] transPtrs;
  590     return out;
  591 }
  592 
  593 
  594 std::ostream &CSharpTabCodeGen::TRANS_ACTIONS_WI()
  595 {
  596     /* Transitions must be written ordered by their id. */
  597     RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
  598     for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
  599         transPtrs[trans->id] = trans;
  600 
  601     /* Keep a count of the num of items in the array written. */
  602     out << '\t';
  603     int totalAct = 0;
  604     for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
  605         /* Write the function for the transition. */
  606         RedTransAp *trans = transPtrs[t];
  607         TRANS_ACTION( trans );
  608         if ( t < redFsm->transSet.length()-1 ) {
  609             out << ", ";
  610             if ( ++totalAct % IALL == 0 )
  611                 out << "\n\t";
  612         }
  613     }
  614     out << "\n";
  615     delete[] transPtrs;
  616     return out;
  617 }
  618 
  619 void CSharpTabCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish )
  620 {
  621     ret << "{" << vCS() << " = " << gotoDest << ";";
  622 
  623     ret << CTRL_FLOW() << "goto _again;";
  624 
  625     ret << "}";
  626 }
  627 
  628 void CSharpTabCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish )
  629 {
  630     ret << "{" << vCS() << " = (";
  631     INLINE_LIST( ret, ilItem->children, 0, inFinish );
  632     ret << ");";
  633     
  634     ret << CTRL_FLOW() << "goto _again;";
  635 
  636     ret << "}";
  637 }
  638 
  639 void CSharpTabCodeGen::CURS( ostream &ret, bool inFinish )
  640 {
  641     ret << "(_ps)";
  642 }
  643 
  644 void CSharpTabCodeGen::TARGS( ostream &ret, bool inFinish, int targState )
  645 {
  646     ret << "(" << vCS() << ")";
  647 }
  648 
  649 void CSharpTabCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish )
  650 {
  651     ret << vCS() << " = " << nextDest << ";";
  652 }
  653 
  654 void CSharpTabCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish )
  655 {
  656     ret << vCS() << " = (";
  657     INLINE_LIST( ret, ilItem->children, 0, inFinish );
  658     ret << ");";
  659 }
  660 
  661 void CSharpTabCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish )
  662 {
  663     if ( prePushExpr != 0 ) {
  664         ret << "{";
  665         INLINE_LIST( ret, prePushExpr, 0, false );
  666     }
  667 
  668     ret << "{";
  669 
  670     ret << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << callDest << ";";
  671 
  672     ret << CTRL_FLOW() << "goto _again;";
  673 
  674     ret << "}";
  675 
  676     if ( prePushExpr != 0 )
  677         ret << "}";
  678 }
  679 
  680 void CSharpTabCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish )
  681 {
  682     if ( prePushExpr != 0 ) {
  683         ret << "{";
  684         INLINE_LIST( ret, prePushExpr, 0, false );
  685     }
  686 
  687     ret << "{";
  688 
  689     ret << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = (";
  690     INLINE_LIST( ret, ilItem->children, targState, inFinish );
  691     ret << ");";
  692 
  693     ret << CTRL_FLOW() << "goto _again;";
  694 
  695     ret << "}";
  696 
  697     if ( prePushExpr != 0 )
  698         ret << "}";
  699 }
  700 
  701 void CSharpTabCodeGen::RET( ostream &ret, bool inFinish )
  702 {
  703     ret << "{";
  704 
  705     ret << vCS() << " = " << STACK() << "[--" << TOP() << "]; ";
  706 
  707     if ( postPopExpr != 0 ) {
  708         ret << "{";
  709         INLINE_LIST( ret, postPopExpr, 0, false );
  710         ret << "}";
  711     }
  712 
  713     ret << CTRL_FLOW() <<  "goto _again;";
  714 
  715     ret << "}";
  716 }
  717 
  718 void CSharpTabCodeGen::BREAK( ostream &ret, int targState )
  719 {
  720     outLabelUsed = true;
  721     ret << "{" << P() << "++; " << CTRL_FLOW() << "goto _out; }";
  722 }
  723 
  724 void CSharpTabCodeGen::writeData()
  725 {
  726     /* If there are any transtion functions then output the array. If there
  727      * are none, don't bother emitting an empty array that won't be used. */
  728     if ( redFsm->anyActions() ) {
  729         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() );
  730         ACTIONS_ARRAY();
  731         CLOSE_ARRAY() <<
  732         "\n";
  733     }
  734 
  735     if ( redFsm->anyConditions() ) {
  736         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() );
  737         COND_OFFSETS();
  738         CLOSE_ARRAY() <<
  739         "\n";
  740 
  741         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() );
  742         COND_LENS();
  743         CLOSE_ARRAY() <<
  744         "\n";
  745 
  746         OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
  747         COND_KEYS();
  748         CLOSE_ARRAY() <<
  749         "\n";
  750 
  751         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() );
  752         COND_SPACES();
  753         CLOSE_ARRAY() <<
  754         "\n";
  755     }
  756 
  757     OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() );
  758     KEY_OFFSETS();
  759     CLOSE_ARRAY() <<
  760     "\n";
  761 
  762     OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
  763     KEYS();
  764     CLOSE_ARRAY() <<
  765     "\n";
  766 
  767     OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() );
  768     SINGLE_LENS();
  769     CLOSE_ARRAY() <<
  770     "\n";
  771 
  772     OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() );
  773     RANGE_LENS();
  774     CLOSE_ARRAY() <<
  775     "\n";
  776 
  777     OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() );
  778     INDEX_OFFSETS();
  779     CLOSE_ARRAY() <<
  780     "\n";
  781 
  782     if ( useIndicies ) {
  783         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() );
  784         INDICIES();
  785         CLOSE_ARRAY() <<
  786         "\n";
  787 
  788         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
  789         TRANS_TARGS_WI();
  790         CLOSE_ARRAY() <<
  791         "\n";
  792 
  793         if ( redFsm->anyActions() ) {
  794             OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() );
  795             TRANS_ACTIONS_WI();
  796             CLOSE_ARRAY() <<
  797             "\n";
  798         }
  799     }
  800     else {
  801         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
  802         TRANS_TARGS();
  803         CLOSE_ARRAY() <<
  804         "\n";
  805 
  806         if ( redFsm->anyActions() ) {
  807             OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() );
  808             TRANS_ACTIONS();
  809             CLOSE_ARRAY() <<
  810             "\n";
  811         }
  812     }
  813 
  814     if ( redFsm->anyToStateActions() ) {
  815         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() );
  816         TO_STATE_ACTIONS();
  817         CLOSE_ARRAY() <<
  818         "\n";
  819     }
  820 
  821     if ( redFsm->anyFromStateActions() ) {
  822         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
  823         FROM_STATE_ACTIONS();
  824         CLOSE_ARRAY() <<
  825         "\n";
  826     }
  827 
  828     if ( redFsm->anyEofActions() ) {
  829         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() );
  830         EOF_ACTIONS();
  831         CLOSE_ARRAY() <<
  832         "\n";
  833     }
  834 
  835     if ( redFsm->anyEofTrans() ) {
  836         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() );
  837         EOF_TRANS();
  838         CLOSE_ARRAY() <<
  839         "\n";
  840     }
  841 
  842     STATE_IDS();
  843 }
  844 
  845 void CSharpTabCodeGen::LOCATE_TRANS()
  846 {
  847     out <<
  848         "   _keys = " << KO() + "[" + vCS() + "]" << ";\n"
  849         "   _trans = " << CAST(transType) << IO() << "[" << vCS() << "];\n"
  850         "\n"
  851         "   _klen = " << SL() << "[" << vCS() << "];\n"
  852         "   if ( _klen > 0 ) {\n"
  853         "       " << signedKeysType << " _lower = _keys;\n"
  854         "       " << signedKeysType << " _mid;\n"
  855         "       " << signedKeysType << " _upper = " << CAST(signedKeysType) << 
  856             " (_keys + _klen - 1);\n"
  857         "       while (true) {\n"
  858         "           if ( _upper < _lower )\n"
  859         "               break;\n"
  860         "\n"
  861         "           _mid = " << CAST(signedKeysType) << 
  862             " (_lower + ((_upper-_lower) >> 1));\n"
  863         "           if ( " << GET_WIDE_KEY() << " < " << K() << "[_mid] )\n"
  864         "               _upper = " << CAST(signedKeysType) << " (_mid - 1);\n"
  865         "           else if ( " << GET_WIDE_KEY() << " > " << K() << "[_mid] )\n"
  866         "               _lower = " << CAST(signedKeysType) << " (_mid + 1);\n"
  867         "           else {\n"
  868         "               _trans += " << CAST(transType) << " (_mid - _keys);\n"
  869         "               goto _match;\n"
  870         "           }\n"
  871         "       }\n"
  872         "       _keys += " << CAST(keysType) << " _klen;\n"
  873         "       _trans += " << CAST(transType) << " _klen;\n"
  874         "   }\n"
  875         "\n"
  876         "   _klen = " << RL() << "[" << vCS() << "];\n"
  877         "   if ( _klen > 0 ) {\n"
  878         "       " << signedKeysType << " _lower = _keys;\n"
  879         "       " << signedKeysType << " _mid;\n"
  880         "       " << signedKeysType << " _upper = " << CAST(signedKeysType) <<
  881             " (_keys + (_klen<<1) - 2);\n"
  882         "       while (true) {\n"
  883         "           if ( _upper < _lower )\n"
  884         "               break;\n"
  885         "\n"
  886         "           _mid = " << CAST(signedKeysType) << 
  887             " (_lower + (((_upper-_lower) >> 1) & ~1));\n"
  888         "           if ( " << GET_WIDE_KEY() << " < " << K() << "[_mid] )\n"
  889         "               _upper = " << CAST(signedKeysType) << " (_mid - 2);\n"
  890         "           else if ( " << GET_WIDE_KEY() << " > " << K() << "[_mid+1] )\n"
  891         "               _lower = " << CAST(signedKeysType) << " (_mid + 2);\n"
  892         "           else {\n"
  893         "               _trans += " << CAST(transType) << "((_mid - _keys)>>1);\n"
  894         "               goto _match;\n"
  895         "           }\n"
  896         "       }\n"
  897         "       _trans += " << CAST(transType) << " _klen;\n"
  898         "   }\n"
  899         "\n";
  900 }
  901 
  902 void CSharpTabCodeGen::COND_TRANSLATE()
  903 {
  904     out << 
  905         "   _widec = " << GET_KEY() << ";\n"
  906         "   _klen = " << CL() << "[" << vCS() << "];\n"
  907         "   _keys = " << CAST(keysType) << " ("<< CO() << "[" << vCS() << "]*2);\n"
  908         "   if ( _klen > 0 ) {\n"
  909         "       " << signedKeysType << " _lower = _keys;\n"
  910         "       " << signedKeysType << " _mid;\n"
  911         "       " << signedKeysType << " _upper = " << CAST(signedKeysType) << 
  912             " (_keys + (_klen<<1) - 2);\n"
  913         "       while (true) {\n"
  914         "           if ( _upper < _lower )\n"
  915         "               break;\n"
  916         "\n"
  917         "           _mid = " << CAST(signedKeysType) << 
  918             " (_lower + (((_upper-_lower) >> 1) & ~1));\n"
  919         "           if ( " << GET_WIDE_KEY() << " < " << CK() << "[_mid] )\n"
  920         "               _upper = " << CAST(signedKeysType) << " (_mid - 2);\n"
  921         "           else if ( " << GET_WIDE_KEY() << " > " << CK() << "[_mid+1] )\n"
  922         "               _lower = " << CAST(signedKeysType) << " (_mid + 2);\n"
  923         "           else {\n"
  924         "               switch ( " << C() << "[" << CO() << "[" << vCS() << "]"
  925                             " + ((_mid - _keys)>>1)] ) {\n";
  926 
  927     for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) {
  928         GenCondSpace *condSpace = csi;
  929         out << "    case " << condSpace->condSpaceId << ": {\n";
  930         out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" <<
  931                 KEY(condSpace->baseKey) << " + (" << GET_KEY() << 
  932                 " - " << KEY(keyOps->minKey) << "));\n";
  933 
  934         for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
  935             out << TABS(2) << "if ( ";
  936             CONDITION( out, *csi );
  937             Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
  938             out << " ) _widec += " << condValOffset << ";\n";
  939         }
  940 
  941         out << 
  942             "       break;\n"
  943             "   }\n";
  944     }
  945 
  946     SWITCH_DEFAULT();
  947 
  948     out << 
  949         "               }\n"
  950         "               break;\n"
  951         "           }\n"
  952         "       }\n"
  953         "   }\n"
  954         "\n";
  955 }
  956 
  957 void CSharpTabCodeGen::writeExec()
  958 {
  959     testEofUsed = false;
  960     outLabelUsed = false;
  961     initVarTypes();
  962 
  963     out <<
  964         "   {\n"
  965         "   " << klenType << " _klen";
  966 
  967     if ( redFsm->anyRegCurStateRef() )
  968         out << ", _ps";
  969 
  970     out << 
  971         ";\n"
  972         "   " << transType << " _trans;\n";
  973 
  974     if ( redFsm->anyConditions() )
  975         out << "    " << WIDE_ALPH_TYPE() << " _widec;\n";
  976 
  977     if ( redFsm->anyToStateActions() || redFsm->anyRegActions() 
  978             || redFsm->anyFromStateActions() )
  979     {
  980         out << 
  981             "   int _acts;\n"
  982             "   int _nacts;\n";
  983     }
  984 
  985     out <<
  986         "   " << keysType << " _keys;\n"
  987         "\n";
  988 //      "   " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n"
  989 
  990     if ( !noEnd ) {
  991         testEofUsed = true;
  992         out << 
  993             "   if ( " << P() << " == " << PE() << " )\n"
  994             "       goto _test_eof;\n";
  995     }
  996 
  997     if ( redFsm->errState != 0 ) {
  998         outLabelUsed = true;
  999         out << 
 1000             "   if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
 1001             "       goto _out;\n";
 1002     }
 1003 
 1004     out << "_resume:\n";
 1005 
 1006     if ( redFsm->anyFromStateActions() ) {
 1007         out <<
 1008             "   _acts = " << FSA() << "[" + vCS() + "]" << ";\n"
 1009             "   _nacts = " << A() << "[_acts++];\n"
 1010             "   while ( _nacts-- > 0 ) {\n"
 1011             "       switch ( " << A() << "[_acts++] ) {\n";
 1012             FROM_STATE_ACTION_SWITCH();
 1013             SWITCH_DEFAULT() <<
 1014             "       }\n"
 1015             "   }\n"
 1016             "\n";
 1017     }
 1018 
 1019     if ( redFsm->anyConditions() )
 1020         COND_TRANSLATE();
 1021 
 1022     LOCATE_TRANS();
 1023 
 1024     out << "_match:\n";
 1025 
 1026     if ( useIndicies )
 1027         out << "    _trans = " << CAST(transType) << I() << "[_trans];\n";
 1028     
 1029     if ( redFsm->anyEofTrans() )
 1030         out << "_eof_trans:\n";
 1031 
 1032     if ( redFsm->anyRegCurStateRef() )
 1033         out << "    _ps = " << vCS() << ";\n";
 1034 
 1035     out <<
 1036         "   " << vCS() << " = " << TT() << "[_trans];\n"
 1037         "\n";
 1038 
 1039     if ( redFsm->anyRegActions() ) {
 1040         out <<
 1041             "   if ( " << TA() << "[_trans] == 0 )\n"
 1042             "       goto _again;\n"
 1043             "\n"
 1044             "   _acts = " << TA() << "[_trans]" << ";\n"
 1045             "   _nacts = " << A() << "[_acts++];\n"
 1046             "   while ( _nacts-- > 0 )\n    {\n"
 1047             "       switch ( " << A() << "[_acts++] )\n     {\n";
 1048             ACTION_SWITCH();
 1049             SWITCH_DEFAULT() <<
 1050             "       }\n"
 1051             "   }\n"
 1052             "\n";
 1053     }
 1054 
 1055     if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || 
 1056             redFsm->anyActionCalls() || redFsm->anyActionRets() )
 1057         out << "_again:\n";
 1058 
 1059     if ( redFsm->anyToStateActions() ) {
 1060         out <<
 1061             "   _acts = " << TSA() << "[" << vCS() << "]" << ";\n"
 1062             "   _nacts = " << A() << "[_acts++];\n"
 1063             "   while ( _nacts-- > 0 ) {\n"
 1064             "       switch ( " << A() << "[_acts++] ) {\n";
 1065             TO_STATE_ACTION_SWITCH();
 1066             SWITCH_DEFAULT() <<
 1067             "       }\n"
 1068             "   }\n"
 1069             "\n";
 1070     }
 1071 
 1072     if ( redFsm->errState != 0 ) {
 1073         outLabelUsed = true;
 1074         out << 
 1075             "   if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
 1076             "       goto _out;\n";
 1077     }
 1078 
 1079     if ( !noEnd ) {
 1080         out << 
 1081             "   if ( ++" << P() << " != " << PE() << " )\n"
 1082             "       goto _resume;\n";
 1083     }
 1084     else {
 1085         out << 
 1086             "   " << P() << " += 1;\n"
 1087             "   goto _resume;\n";
 1088     }
 1089     
 1090     if ( testEofUsed )
 1091         out << "    _test_eof: {}\n";
 1092     
 1093     if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
 1094         out << 
 1095             "   if ( " << P() << " == " << vEOF() << " )\n"
 1096             "   {\n";
 1097 
 1098         if ( redFsm->anyEofTrans() ) {
 1099             out <<
 1100                 "   if ( " << ET() << "[" << vCS() << "] > 0 ) {\n"
 1101                 "       _trans = " << CAST(transType) << " (" << ET() <<
 1102                     "[" << vCS() << "] - 1);\n"
 1103                 "       goto _eof_trans;\n"
 1104                 "   }\n";
 1105         }
 1106 
 1107         if ( redFsm->anyEofActions() ) {
 1108             out <<
 1109                 "   int __acts = " << 
 1110                         EA() << "[" << vCS() << "]" << ";\n"
 1111                 "   int __nacts = " << 
 1112                 A() << "[__acts++];\n"
 1113                 "   while ( __nacts-- > 0 ) {\n"
 1114                 "       switch ( " << A() << "[__acts++] ) {\n";
 1115                 EOF_ACTION_SWITCH();
 1116                 SWITCH_DEFAULT() <<
 1117                 "       }\n"
 1118                 "   }\n";
 1119         }
 1120         
 1121         out << 
 1122             "   }\n"
 1123             "\n";
 1124     }
 1125 
 1126     if ( outLabelUsed )
 1127         out << "    _out: {}\n";
 1128 
 1129     out << "    }\n";
 1130 }
 1131 
 1132 void CSharpTabCodeGen::initVarTypes()
 1133 {
 1134     int klenMax = MAX(MAX(redFsm->maxCondLen, redFsm->maxRangeLen),
 1135                 redFsm->maxSingleLen);
 1136     int keysMax = MAX(MAX(redFsm->maxKeyOffset, klenMax),
 1137                 redFsm->maxCondOffset);
 1138     int transMax = MAX(MAX(redFsm->maxIndex+1, redFsm->maxIndexOffset), keysMax);
 1139     transMax = MAX(transMax, klenMax);
 1140     transType = ARRAY_TYPE(transMax);
 1141     klenType = ARRAY_TYPE(klenMax);
 1142     keysType = ARRAY_TYPE(keysMax);
 1143     signedKeysType = ARRAY_TYPE(keysMax, true);
 1144 }