Initialize Tizen 2.3
[external/ragel.git] / ragel / cdflat.cpp
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 << "{" << vCS() << " = " << gotoDest << "; " << 
458                         CTRL_FLOW() << "goto _again;}";
459 }
460
461 void FlatCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish )
462 {
463         ret << "{" << vCS() << " = (";
464         INLINE_LIST( ret, ilItem->children, 0, inFinish, false );
465         ret << "); " << CTRL_FLOW() << "goto _again;}";
466 }
467
468 void FlatCodeGen::CURS( ostream &ret, bool inFinish )
469 {
470         ret << "(_ps)";
471 }
472
473 void FlatCodeGen::TARGS( ostream &ret, bool inFinish, int targState )
474 {
475         ret << "(" << vCS() << ")";
476 }
477
478 void FlatCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish )
479 {
480         ret << vCS() << " = " << nextDest << ";";
481 }
482
483 void FlatCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish )
484 {
485         ret << vCS() << " = (";
486         INLINE_LIST( ret, ilItem->children, 0, inFinish, false );
487         ret << ");";
488 }
489
490 void FlatCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish )
491 {
492         if ( prePushExpr != 0 ) {
493                 ret << "{";
494                 INLINE_LIST( ret, prePushExpr, 0, false, false );
495         }
496
497         ret << "{" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << 
498                         callDest << "; " << CTRL_FLOW() << "goto _again;}";
499
500         if ( prePushExpr != 0 )
501                 ret << "}";
502 }
503
504
505 void FlatCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish )
506 {
507         if ( prePushExpr != 0 ) {
508                 ret << "{";
509                 INLINE_LIST( ret, prePushExpr, 0, false, false );
510         }
511
512         ret << "{" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = (";
513         INLINE_LIST( ret, ilItem->children, targState, inFinish, false );
514         ret << "); " << CTRL_FLOW() << "goto _again;}";
515
516         if ( prePushExpr != 0 )
517                 ret << "}";
518 }
519
520
521 void FlatCodeGen::RET( ostream &ret, bool inFinish )
522 {
523         ret << "{" << vCS() << " = " << STACK() << "[--" << TOP() << "];";
524
525         if ( postPopExpr != 0 ) {
526                 ret << "{";
527                 INLINE_LIST( ret, postPopExpr, 0, false, false );
528                 ret << "}";
529         }
530
531         ret << CTRL_FLOW() << "goto _again;}";
532 }
533
534 void FlatCodeGen::BREAK( ostream &ret, int targState, bool csForced )
535 {
536         outLabelUsed = true;
537         ret << "{" << P() << "++; " << CTRL_FLOW() << "goto _out; }";
538 }
539
540 void FlatCodeGen::writeData()
541 {
542         /* If there are any transtion functions then output the array. If there
543          * are none, don't bother emitting an empty array that won't be used. */
544         if ( redFsm->anyActions() ) {
545                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() );
546                 ACTIONS_ARRAY();
547                 CLOSE_ARRAY() <<
548                 "\n";
549         }
550
551         if ( redFsm->anyConditions() ) {
552                 OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
553                 COND_KEYS();
554                 CLOSE_ARRAY() <<
555                 "\n";
556
557                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() );
558                 COND_KEY_SPANS();
559                 CLOSE_ARRAY() <<
560                 "\n";
561
562                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() );
563                 CONDS();
564                 CLOSE_ARRAY() <<
565                 "\n";
566
567                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() );
568                 COND_INDEX_OFFSET();
569                 CLOSE_ARRAY() <<
570                 "\n";
571         }
572
573         OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
574         KEYS();
575         CLOSE_ARRAY() <<
576         "\n";
577
578         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() );
579         KEY_SPANS();
580         CLOSE_ARRAY() <<
581         "\n";
582
583         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() );
584         FLAT_INDEX_OFFSET();
585         CLOSE_ARRAY() <<
586         "\n";
587
588         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() );
589         INDICIES();
590         CLOSE_ARRAY() <<
591         "\n";
592
593         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
594         TRANS_TARGS();
595         CLOSE_ARRAY() <<
596         "\n";
597
598         if ( redFsm->anyActions() ) {
599                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() );
600                 TRANS_ACTIONS();
601                 CLOSE_ARRAY() <<
602                 "\n";
603         }
604
605         if ( redFsm->anyToStateActions() ) {
606                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() );
607                 TO_STATE_ACTIONS();
608                 CLOSE_ARRAY() <<
609                 "\n";
610         }
611
612         if ( redFsm->anyFromStateActions() ) {
613                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
614                 FROM_STATE_ACTIONS();
615                 CLOSE_ARRAY() <<
616                 "\n";
617         }
618
619         if ( redFsm->anyEofActions() ) {
620                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() );
621                 EOF_ACTIONS();
622                 CLOSE_ARRAY() <<
623                 "\n";
624         }
625
626         if ( redFsm->anyEofTrans() ) {
627                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() );
628                 EOF_TRANS();
629                 CLOSE_ARRAY() <<
630                 "\n";
631         }
632
633         STATE_IDS();
634 }
635
636 void FlatCodeGen::COND_TRANSLATE()
637 {
638         out << 
639                 "       _widec = " << GET_KEY() << ";\n";
640
641         out <<
642                 "       _keys = " << ARR_OFF( CK(), "(" + vCS() + "<<1)" ) << ";\n"
643                 "       _conds = " << ARR_OFF( C(), CO() + "[" + vCS() + "]" ) << ";\n"
644                 "\n"
645                 "       _slen = " << CSP() << "[" << vCS() << "];\n"
646                 "       _cond = _slen > 0 && _keys[0] <=" << GET_WIDE_KEY() << " &&\n"
647                 "               " << GET_WIDE_KEY() << " <= _keys[1] ?\n"
648                 "               _conds[" << GET_WIDE_KEY() << " - _keys[0]] : 0;\n"
649                 "\n";
650
651         out <<
652                 "       switch ( _cond ) {\n";
653         for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) {
654                 GenCondSpace *condSpace = csi;
655                 out << "        case " << condSpace->condSpaceId + 1 << ": {\n";
656                 out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" <<
657                                 KEY(condSpace->baseKey) << " + (" << GET_KEY() << 
658                                 " - " << KEY(keyOps->minKey) << "));\n";
659
660                 for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
661                         out << TABS(2) << "if ( ";
662                         CONDITION( out, *csi );
663                         Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
664                         out << " ) _widec += " << condValOffset << ";\n";
665                 }
666
667                 out << "                }\n";
668                 out << "                break;\n";
669         }
670
671         SWITCH_DEFAULT();
672
673         out <<
674                 "       }\n";
675 }
676
677 void FlatCodeGen::writeExec()
678 {
679         testEofUsed = false;
680         outLabelUsed = false;
681
682         out << 
683                 "       {\n"
684                 "       int _slen";
685
686         if ( redFsm->anyRegCurStateRef() )
687                 out << ", _ps";
688
689         out << 
690                 ";\n"
691                 "       int _trans";
692
693         if ( redFsm->anyConditions() )
694                 out << ", _cond";
695         out << ";\n";
696
697         if ( redFsm->anyToStateActions() || 
698                         redFsm->anyRegActions() || redFsm->anyFromStateActions() )
699         {
700                 out << 
701                         "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << POINTER() << "_acts;\n"
702                         "       " << UINT() << " _nacts;\n"; 
703         }
704
705         out <<
706                 "       " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n"
707                 "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << POINTER() << "_inds;\n";
708
709         if ( redFsm->anyConditions() ) {
710                 out << 
711                         "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxCond) << POINTER() << "_conds;\n"
712                         "       " << WIDE_ALPH_TYPE() << " _widec;\n";
713         }
714
715         out << "\n";
716
717         if ( !noEnd ) {
718                 testEofUsed = true;
719                 out << 
720                         "       if ( " << P() << " == " << PE() << " )\n"
721                         "               goto _test_eof;\n";
722         }
723
724         if ( redFsm->errState != 0 ) {
725                 outLabelUsed = true;
726                 out << 
727                         "       if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
728                         "               goto _out;\n";
729         }
730
731         out << "_resume:\n";
732
733         if ( redFsm->anyFromStateActions() ) {
734                 out <<
735                         "       _acts = " << ARR_OFF( A(), FSA() + "[" + vCS() + "]" ) << ";\n"
736                         "       _nacts = " << CAST(UINT()) << " *_acts++;\n"
737                         "       while ( _nacts-- > 0 ) {\n"
738                         "               switch ( *_acts++ ) {\n";
739                         FROM_STATE_ACTION_SWITCH();
740                         SWITCH_DEFAULT() <<
741                         "               }\n"
742                         "       }\n"
743                         "\n";
744         }
745
746         if ( redFsm->anyConditions() )
747                 COND_TRANSLATE();
748
749         LOCATE_TRANS();
750
751         if ( redFsm->anyEofTrans() )
752                 out << "_eof_trans:\n";
753
754         if ( redFsm->anyRegCurStateRef() )
755                 out << "        _ps = " << vCS() << ";\n";
756
757         out <<
758                 "       " << vCS() << " = " << TT() << "[_trans];\n"
759                 "\n";
760
761         if ( redFsm->anyRegActions() ) {
762                 out <<
763                         "       if ( " << TA() << "[_trans] == 0 )\n"
764                         "               goto _again;\n"
765                         "\n"
766                         "       _acts = " << ARR_OFF( A(), TA() + "[_trans]" ) << ";\n"
767                         "       _nacts = " << CAST(UINT()) << " *_acts++;\n"
768                         "       while ( _nacts-- > 0 ) {\n"
769                         "               switch ( *(_acts++) )\n         {\n";
770                         ACTION_SWITCH();
771                         SWITCH_DEFAULT() <<
772                         "               }\n"
773                         "       }\n"
774                         "\n";
775         }
776
777         if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || 
778                         redFsm->anyActionCalls() || redFsm->anyActionRets() )
779                 out << "_again:\n";
780
781         if ( redFsm->anyToStateActions() ) {
782                 out <<
783                         "       _acts = " << ARR_OFF( A(),  TSA() + "[" + vCS() + "]" ) << ";\n"
784                         "       _nacts = " << CAST(UINT()) << " *_acts++;\n"
785                         "       while ( _nacts-- > 0 ) {\n"
786                         "               switch ( *_acts++ ) {\n";
787                         TO_STATE_ACTION_SWITCH();
788                         SWITCH_DEFAULT() <<
789                         "               }\n"
790                         "       }\n"
791                         "\n";
792         }
793
794         if ( redFsm->errState != 0 ) {
795                 outLabelUsed = true;
796                 out << 
797                         "       if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
798                         "               goto _out;\n";
799         }
800
801         if ( !noEnd ) {
802                 out << 
803                         "       if ( ++" << P() << " != " << PE() << " )\n"
804                         "               goto _resume;\n";
805         }
806         else {
807                 out << 
808                         "       " << P() << " += 1;\n"
809                         "       goto _resume;\n";
810         }
811
812         if ( testEofUsed )
813                 out << "        _test_eof: {}\n";
814
815         if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
816                 out << 
817                         "       if ( " << P() << " == " << vEOF() << " )\n"
818                         "       {\n";
819
820                 if ( redFsm->anyEofTrans() ) {
821                         out <<
822                                 "       if ( " << ET() << "[" << vCS() << "] > 0 ) {\n"
823                                 "               _trans = " << ET() << "[" << vCS() << "] - 1;\n"
824                                 "               goto _eof_trans;\n"
825                                 "       }\n";
826                 }
827
828                 if ( redFsm->anyEofActions() ) {
829                         out <<
830                                 "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << 
831                                                 POINTER() << "__acts = " << 
832                                                 ARR_OFF( A(), EA() + "[" + vCS() + "]" ) << ";\n"
833                                 "       " << UINT() << " __nacts = " << CAST(UINT()) << " *__acts++;\n"
834                                 "       while ( __nacts-- > 0 ) {\n"
835                                 "               switch ( *__acts++ ) {\n";
836                                 EOF_ACTION_SWITCH();
837                                 SWITCH_DEFAULT() <<
838                                 "               }\n"
839                                 "       }\n";
840                 }
841
842                 out <<
843                         "       }\n"
844                         "\n";
845         }
846
847         if ( outLabelUsed )
848                 out << "        _out: {}\n";
849
850         out << "        }\n";
851 }