2 * Copyright 2001-2006 Adrian Thurston <thurston@complang.org>
3 * 2004 Erich Ocean <eric.ocean@ampede.com>
4 * 2005 Alan West <alan@alanz.com>
7 /* This file is part of Ragel.
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.
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.
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
32 /* Determine if we should use indicies or not. */
33 void GoTabCodeGen::calcIndexSize()
35 int sizeWithInds
= 0, sizeWithoutInds
= 0;
37 /* Calculate cost of using with indicies. */
38 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
39 int totalIndex
= st
->outSingle
.length() + st
->outRange
.length() +
40 (st
->defTrans
== 0 ? 0 : 1);
41 sizeWithInds
+= arrayTypeSize(redFsm
->maxIndex
) * totalIndex
;
43 sizeWithInds
+= arrayTypeSize(redFsm
->maxState
) * redFsm
->transSet
.length();
44 if ( redFsm
->anyActions() )
45 sizeWithInds
+= arrayTypeSize(redFsm
->maxActionLoc
) * redFsm
->transSet
.length();
47 /* Calculate the cost of not using indicies. */
48 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
49 int totalIndex
= st
->outSingle
.length() + st
->outRange
.length() +
50 (st
->defTrans
== 0 ? 0 : 1);
51 sizeWithoutInds
+= arrayTypeSize(redFsm
->maxState
) * totalIndex
;
52 if ( redFsm
->anyActions() )
53 sizeWithoutInds
+= arrayTypeSize(redFsm
->maxActionLoc
) * totalIndex
;
56 /* If using indicies reduces the size, use them. */
57 useIndicies
= sizeWithInds
< sizeWithoutInds
;
60 std::ostream
&GoTabCodeGen::TO_STATE_ACTION( RedStateAp
*state
)
63 if ( state
->toStateAction
!= 0 )
64 act
= state
->toStateAction
->location
+1;
69 std::ostream
&GoTabCodeGen::FROM_STATE_ACTION( RedStateAp
*state
)
72 if ( state
->fromStateAction
!= 0 )
73 act
= state
->fromStateAction
->location
+1;
78 std::ostream
&GoTabCodeGen::EOF_ACTION( RedStateAp
*state
)
81 if ( state
->eofAction
!= 0 )
82 act
= state
->eofAction
->location
+1;
88 std::ostream
&GoTabCodeGen::TRANS_ACTION( RedTransAp
*trans
)
90 /* If there are actions, emit them. Otherwise emit zero. */
92 if ( trans
->action
!= 0 )
93 act
= trans
->action
->location
+1;
98 std::ostream
&GoTabCodeGen::TO_STATE_ACTION_SWITCH( int level
)
100 /* Walk the list of functions, printing the cases. */
101 for ( GenActionList::Iter act
= actionList
; act
.lte(); act
++ ) {
102 /* Write out referenced actions. */
103 if ( act
->numToStateRefs
> 0 ) {
104 /* Write the case label, the action and the case break. */
105 out
<< TABS(level
) << "case " << act
->actionId
<< ":" << endl
;
106 ACTION( out
, act
, 0, false, false );
110 genLineDirective( out
);
114 std::ostream
&GoTabCodeGen::FROM_STATE_ACTION_SWITCH( int level
)
116 /* Walk the list of functions, printing the cases. */
117 for ( GenActionList::Iter act
= actionList
; act
.lte(); act
++ ) {
118 /* Write out referenced actions. */
119 if ( act
->numFromStateRefs
> 0 ) {
120 /* Write the case label, the action and the case break. */
121 out
<< TABS(level
) << "case " << act
->actionId
<< ":" << endl
;
122 ACTION( out
, act
, 0, false, false );
126 genLineDirective( out
);
130 std::ostream
&GoTabCodeGen::EOF_ACTION_SWITCH( int level
)
132 /* Walk the list of functions, printing the cases. */
133 for ( GenActionList::Iter act
= actionList
; act
.lte(); act
++ ) {
134 /* Write out referenced actions. */
135 if ( act
->numEofRefs
> 0 ) {
136 /* Write the case label, the action and the case break. */
137 out
<< TABS(level
) << "case " << act
->actionId
<< ":" << endl
;
138 ACTION( out
, act
, 0, true, false );
142 genLineDirective(out
);
147 std::ostream
&GoTabCodeGen::ACTION_SWITCH( int level
)
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
<< TABS(level
) << "case " << act
->actionId
<< ":" << endl
;
155 ACTION( out
, act
, 0, false, false );
159 genLineDirective(out
);
163 std::ostream
&GoTabCodeGen::COND_OFFSETS()
166 int totalStateNum
= 0, curKeyOffset
= 0;
167 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
168 /* Write the key offset. */
172 if ( ++totalStateNum
% IALL
== 0 )
176 /* Move the key offset ahead. */
177 curKeyOffset
+= st
->stateCondList
.length();
183 std::ostream
&GoTabCodeGen::KEY_OFFSETS()
186 int totalStateNum
= 0, curKeyOffset
= 0;
187 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
188 /* Write the key offset. */
192 if ( ++totalStateNum
% IALL
== 0 )
196 /* Move the key offset ahead. */
197 curKeyOffset
+= st
->outSingle
.length() + st
->outRange
.length()*2;
204 std::ostream
&GoTabCodeGen::INDEX_OFFSETS()
207 int totalStateNum
= 0, curIndOffset
= 0;
208 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
209 /* Write the index offset. */
213 if ( ++totalStateNum
% IALL
== 0 )
217 /* Move the index offset ahead. */
218 curIndOffset
+= st
->outSingle
.length() + st
->outRange
.length();
219 if ( st
->defTrans
!= 0 )
226 std::ostream
&GoTabCodeGen::COND_LENS()
229 int totalStateNum
= 0;
230 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
231 /* Write singles length. */
232 out
<< st
->stateCondList
.length();
235 if ( ++totalStateNum
% IALL
== 0 )
244 std::ostream
&GoTabCodeGen::SINGLE_LENS()
247 int totalStateNum
= 0;
248 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
249 /* Write singles length. */
250 out
<< st
->outSingle
.length();
253 if ( ++totalStateNum
% IALL
== 0 )
261 std::ostream
&GoTabCodeGen::RANGE_LENS()
264 int totalStateNum
= 0;
265 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
266 /* Emit length of range index. */
267 out
<< st
->outRange
.length();
270 if ( ++totalStateNum
% IALL
== 0 )
278 std::ostream
&GoTabCodeGen::TO_STATE_ACTIONS()
281 int totalStateNum
= 0;
282 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
283 /* Write any eof action. */
287 if ( ++totalStateNum
% IALL
== 0 )
295 std::ostream
&GoTabCodeGen::FROM_STATE_ACTIONS()
298 int totalStateNum
= 0;
299 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
300 /* Write any eof action. */
301 FROM_STATE_ACTION(st
);
304 if ( ++totalStateNum
% IALL
== 0 )
312 std::ostream
&GoTabCodeGen::EOF_ACTIONS()
315 int totalStateNum
= 0;
316 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
317 /* Write any eof action. */
321 if ( ++totalStateNum
% IALL
== 0 )
329 std::ostream
&GoTabCodeGen::EOF_TRANS()
332 int totalStateNum
= 0;
333 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
334 /* Write any eof action. */
336 if ( st
->eofTrans
!= 0 ) {
337 assert( st
->eofTrans
->pos
>= 0 );
338 trans
= st
->eofTrans
->pos
+1;
344 if ( ++totalStateNum
% IALL
== 0 )
353 std::ostream
&GoTabCodeGen::COND_KEYS()
357 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
358 /* Loop the state's transitions. */
359 for ( GenStateCondList::Iter sc
= st
->stateCondList
; sc
.lte(); sc
++ ) {
361 out
<< KEY( sc
->lowKey
) << ", ";
362 if ( ++totalTrans
% IALL
== 0 )
366 out
<< KEY( sc
->highKey
) << ", ";
367 if ( ++totalTrans
% IALL
== 0 )
376 std::ostream
&GoTabCodeGen::COND_SPACES()
380 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
381 /* Loop the state's transitions. */
382 for ( GenStateCondList::Iter sc
= st
->stateCondList
; sc
.lte(); sc
++ ) {
384 out
<< sc
->condSpace
->condSpaceId
<< ", ";
385 if ( ++totalTrans
% IALL
== 0 )
394 std::ostream
&GoTabCodeGen::KEYS()
398 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
399 /* Loop the singles. */
400 for ( RedTransList::Iter stel
= st
->outSingle
; stel
.lte(); stel
++ ) {
401 out
<< KEY( stel
->lowKey
) << ", ";
402 if ( ++totalTrans
% IALL
== 0 )
406 /* Loop the state's transitions. */
407 for ( RedTransList::Iter rtel
= st
->outRange
; rtel
.lte(); rtel
++ ) {
409 out
<< KEY( rtel
->lowKey
) << ", ";
410 if ( ++totalTrans
% IALL
== 0 )
414 out
<< KEY( rtel
->highKey
) << ", ";
415 if ( ++totalTrans
% IALL
== 0 )
424 std::ostream
&GoTabCodeGen::INDICIES()
428 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
429 /* Walk the singles. */
430 for ( RedTransList::Iter stel
= st
->outSingle
; stel
.lte(); stel
++ ) {
431 out
<< stel
->value
->id
<< ", ";
432 if ( ++totalTrans
% IALL
== 0 )
436 /* Walk the ranges. */
437 for ( RedTransList::Iter rtel
= st
->outRange
; rtel
.lte(); rtel
++ ) {
438 out
<< rtel
->value
->id
<< ", ";
439 if ( ++totalTrans
% IALL
== 0 )
443 /* The state's default index goes next. */
444 if ( st
->defTrans
!= 0 ) {
445 out
<< st
->defTrans
->id
<< ", ";
446 if ( ++totalTrans
% IALL
== 0 )
455 std::ostream
&GoTabCodeGen::TRANS_TARGS()
459 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
460 /* Walk the singles. */
461 for ( RedTransList::Iter stel
= st
->outSingle
; stel
.lte(); stel
++ ) {
462 RedTransAp
*trans
= stel
->value
;
463 out
<< trans
->targ
->id
<< ", ";
464 if ( ++totalTrans
% IALL
== 0 )
468 /* Walk the ranges. */
469 for ( RedTransList::Iter rtel
= st
->outRange
; rtel
.lte(); rtel
++ ) {
470 RedTransAp
*trans
= rtel
->value
;
471 out
<< trans
->targ
->id
<< ", ";
472 if ( ++totalTrans
% IALL
== 0 )
476 /* The state's default target state. */
477 if ( st
->defTrans
!= 0 ) {
478 RedTransAp
*trans
= st
->defTrans
;
479 out
<< trans
->targ
->id
<< ", ";
480 if ( ++totalTrans
% IALL
== 0 )
485 /* Add any eof transitions that have not yet been written out above. */
486 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
487 if ( st
->eofTrans
!= 0 ) {
488 RedTransAp
*trans
= st
->eofTrans
;
489 trans
->pos
= totalTrans
;
490 out
<< trans
->targ
->id
<< ", ";
491 if ( ++totalTrans
% IALL
== 0 )
502 std::ostream
&GoTabCodeGen::TRANS_ACTIONS()
506 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
507 /* Walk the singles. */
508 for ( RedTransList::Iter stel
= st
->outSingle
; stel
.lte(); stel
++ ) {
509 RedTransAp
*trans
= stel
->value
;
510 TRANS_ACTION( trans
) << ", ";
511 if ( ++totalTrans
% IALL
== 0 )
515 /* Walk the ranges. */
516 for ( RedTransList::Iter rtel
= st
->outRange
; rtel
.lte(); rtel
++ ) {
517 RedTransAp
*trans
= rtel
->value
;
518 TRANS_ACTION( trans
) << ", ";
519 if ( ++totalTrans
% IALL
== 0 )
523 /* The state's default index goes next. */
524 if ( st
->defTrans
!= 0 ) {
525 RedTransAp
*trans
= st
->defTrans
;
526 TRANS_ACTION( trans
) << ", ";
527 if ( ++totalTrans
% IALL
== 0 )
532 /* Add any eof transitions that have not yet been written out above. */
533 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
534 if ( st
->eofTrans
!= 0 ) {
535 RedTransAp
*trans
= st
->eofTrans
;
536 TRANS_ACTION( trans
) << ", ";
537 if ( ++totalTrans
% IALL
== 0 )
546 std::ostream
&GoTabCodeGen::TRANS_TARGS_WI()
548 /* Transitions must be written ordered by their id. */
549 RedTransAp
**transPtrs
= new RedTransAp
*[redFsm
->transSet
.length()];
550 for ( TransApSet::Iter trans
= redFsm
->transSet
; trans
.lte(); trans
++ )
551 transPtrs
[trans
->id
] = trans
;
553 /* Keep a count of the num of items in the array written. */
556 for ( int t
= 0; t
< redFsm
->transSet
.length(); t
++ ) {
557 /* Record the position, need this for eofTrans. */
558 RedTransAp
*trans
= transPtrs
[t
];
561 /* Write out the target state. */
562 out
<< trans
->targ
->id
<< ", ";
563 if ( t
< redFsm
->transSet
.length()-1 ) {
564 if ( ++totalStates
% IALL
== 0 )
574 std::ostream
&GoTabCodeGen::TRANS_ACTIONS_WI()
576 /* Transitions must be written ordered by their id. */
577 RedTransAp
**transPtrs
= new RedTransAp
*[redFsm
->transSet
.length()];
578 for ( TransApSet::Iter trans
= redFsm
->transSet
; trans
.lte(); trans
++ )
579 transPtrs
[trans
->id
] = trans
;
581 /* Keep a count of the num of items in the array written. */
584 for ( int t
= 0; t
< redFsm
->transSet
.length(); t
++ ) {
585 /* Write the function for the transition. */
586 RedTransAp
*trans
= transPtrs
[t
];
587 TRANS_ACTION( trans
);
589 if ( t
< redFsm
->transSet
.length()-1 ) {
590 if ( ++totalAct
% IALL
== 0 )
599 void GoTabCodeGen::writeData()
601 /* If there are any transtion functions then output the array. If there
602 * are none, don't bother emitting an empty array that won't be used. */
603 if ( redFsm
->anyActions() ) {
604 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActArrItem
), A() );
606 CLOSE_ARRAY() << endl
;
609 if ( redFsm
->anyConditions() ) {
610 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxCondOffset
), CO() );
612 CLOSE_ARRAY() << endl
;
614 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxCondLen
), CL() );
616 CLOSE_ARRAY() << endl
;
618 OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
620 CLOSE_ARRAY() << endl
;
622 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxCondSpaceId
), C() );
624 CLOSE_ARRAY() << endl
;
627 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxKeyOffset
), KO() );
629 CLOSE_ARRAY() << endl
;
631 OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
633 CLOSE_ARRAY() << endl
;
635 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxSingleLen
), SL() );
637 CLOSE_ARRAY() << endl
;
639 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxRangeLen
), RL() );
641 CLOSE_ARRAY() << endl
;
643 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxIndexOffset
), IO() );
645 CLOSE_ARRAY() << endl
;
648 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxIndex
), I() );
650 CLOSE_ARRAY() << endl
;
652 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxState
), TT() );
654 CLOSE_ARRAY() << endl
;
656 if ( redFsm
->anyActions() ) {
657 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActionLoc
), TA() );
659 CLOSE_ARRAY() << endl
;
663 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxState
), TT() );
665 CLOSE_ARRAY() << endl
;
667 if ( redFsm
->anyActions() ) {
668 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActionLoc
), TA() );
670 CLOSE_ARRAY() << endl
;
674 if ( redFsm
->anyToStateActions() ) {
675 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActionLoc
), TSA() );
677 CLOSE_ARRAY() << endl
;
680 if ( redFsm
->anyFromStateActions() ) {
681 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActionLoc
), FSA() );
682 FROM_STATE_ACTIONS();
683 CLOSE_ARRAY() << endl
;
686 if ( redFsm
->anyEofActions() ) {
687 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActionLoc
), EA() );
689 CLOSE_ARRAY() << endl
;
692 if ( redFsm
->anyEofTrans() ) {
693 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxIndexOffset
+1), ET() );
695 CLOSE_ARRAY() << endl
;
701 void GoTabCodeGen::LOCATE_TRANS()
704 " _keys = " << CAST(INT(), KO() + "[" + vCS() + "]") << endl
<<
705 " _trans = " << CAST(INT(), IO() + "[" + vCS() + "]") << endl
<<
707 " _klen = " << CAST(INT(), SL() + "[" + vCS() + "]") << endl
<<
708 " if _klen > 0 {" << endl
<<
709 " _lower := " << CAST(INT(), "_keys") << endl
<<
710 " var _mid " << INT() << endl
<<
711 " _upper := " << CAST(INT(), "_keys + _klen - 1") << endl
<<
713 " if _upper < _lower {" << endl
<<
717 " _mid = _lower + ((_upper - _lower) >> 1)" << endl
<<
718 " switch {" << endl
<<
719 " case " << GET_WIDE_KEY() << " < " << K() << "[_mid]" << ":" << endl
<<
720 " _upper = _mid - 1" << endl
<<
721 " case " << GET_WIDE_KEY() << " > " << K() << "[_mid]" << ":" << endl
<<
722 " _lower = _mid + 1" << endl
<<
723 " default:" << endl
<<
724 " _trans += " << CAST(INT(), "_mid - " + CAST(INT(), "_keys")) << endl
<<
725 " goto _match" << endl
<<
728 " _keys += _klen" << endl
<<
729 " _trans += _klen" << endl
<<
732 " _klen = " << CAST(INT(), RL() + "[" + vCS() + "]") << endl
<<
733 " if _klen > 0 {" << endl
<<
734 " _lower := " << CAST(INT(), "_keys") << endl
<<
735 " var _mid " << INT() << endl
<<
736 " _upper := " << CAST(INT(), "_keys + (_klen << 1) - 2") << endl
<<
738 " if _upper < _lower {" << endl
<<
742 " _mid = _lower + (((_upper - _lower) >> 1) & ^1)" << endl
<<
743 " switch {" << endl
<<
744 " case " << GET_WIDE_KEY() << " < " << K() << "[_mid]" << ":" << endl
<<
745 " _upper = _mid - 2" << endl
<<
746 " case " << GET_WIDE_KEY() << " > " << K() << "[_mid + 1]" << ":" << endl
<<
747 " _lower = _mid + 2" << endl
<<
748 " default:" << endl
<<
749 " _trans += " << CAST(INT(), "(_mid - " + CAST(INT(), "_keys") + ") >> 1") << endl
<<
750 " goto _match" << endl
<<
753 " _trans += _klen" << endl
<<
758 void GoTabCodeGen::COND_TRANSLATE()
761 " _widec = " << CAST(WIDE_ALPH_TYPE(), GET_KEY()) << endl
<<
762 " _klen = " << CAST(INT(), CL() + "[" + vCS() + "]") << endl
<<
763 " _keys = " << CAST(INT(), CO() + "[" + vCS() + "] * 2") << endl
<<
764 " if _klen > 0 {" << endl
<<
765 " _lower := " << CAST(INT(), "_keys") << endl
<<
766 " var _mid " << INT() << endl
<<
767 " _upper := " << CAST(INT(), "_keys + (_klen << 1) - 2") << endl
<<
768 " COND_LOOP:" << endl
<<
770 " if _upper < _lower {" << endl
<<
774 " _mid = _lower + (((_upper - _lower) >> 1) & ^1)" << endl
<<
775 " switch {" << endl
<<
776 " case " << GET_WIDE_KEY() << " < " << CAST(WIDE_ALPH_TYPE(), CK() + "[_mid]") << ":" << endl
<<
777 " _upper = _mid - 2" << endl
<<
778 " case " << GET_WIDE_KEY() << " > " << CAST(WIDE_ALPH_TYPE(), CK() + "[_mid + 1]") << ":" << endl
<<
779 " _lower = _mid + 2" << endl
<<
780 " default:" << endl
<<
781 " switch " << C() << "[" << CAST(INT(), CO() + "[" + vCS() + "]") <<
782 " + ((_mid - _keys)>>1)] {" << endl
;
784 for ( CondSpaceList::Iter csi
= condSpaceList
; csi
.lte(); csi
++ ) {
785 GenCondSpace
*condSpace
= csi
;
786 out
<< TABS(4) << "case " << condSpace
->condSpaceId
<< ":" << endl
;
787 out
<< TABS(5) << "_widec = " << KEY(condSpace
->baseKey
) << " + (" << CAST(WIDE_ALPH_TYPE(), GET_KEY()) <<
788 " - " << KEY(keyOps
->minKey
) << ")" << endl
;
790 for ( GenCondSet::Iter csi
= condSpace
->condSet
; csi
.lte(); csi
++ ) {
791 out
<< TABS(5) << "if ";
792 CONDITION( out
, *csi
);
793 Size condValOffset
= ((1 << csi
.pos()) * keyOps
->alphSize());
794 out
<< " {" << endl
<< TABS(6) << "_widec += " << condValOffset
<< endl
<< TABS(5) << "}" << endl
;
800 " break COND_LOOP" << endl
<<
807 void GoTabCodeGen::writeExec()
810 outLabelUsed
= false;
814 " var _klen " << INT() << endl
;
816 if ( redFsm
->anyRegCurStateRef() )
817 out
<< " var _ps " << INT() << endl
;
820 " var _trans " << INT() << endl
;
822 if ( redFsm
->anyConditions() )
823 out
<< " var _widec " << WIDE_ALPH_TYPE() << endl
;
825 if ( redFsm
->anyToStateActions() || redFsm
->anyRegActions()
826 || redFsm
->anyFromStateActions() )
829 " var _acts " << INT() << endl
<<
830 " var _nacts " << UINT() << endl
;
834 " var _keys " << INT() << endl
;
839 " if " << P() << " == " << PE() << " {" << endl
<<
840 " goto _test_eof" << endl
<<
844 if ( redFsm
->errState
!= 0 ) {
847 " if " << vCS() << " == " << redFsm
->errState
->id
<< " {" << endl
<<
848 " goto _out" << endl
<<
852 out
<< "_resume:" << endl
;
854 if ( redFsm
->anyFromStateActions() ) {
856 " _acts = " << CAST(INT(), FSA() + "[" + vCS() + "]") << endl
<<
857 " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl
<<
858 " for ; _nacts > 0; _nacts-- {" << endl
<<
859 " _acts++" << endl
<<
860 " switch " << A() << "[_acts - 1]" << " {" << endl
;
861 FROM_STATE_ACTION_SWITCH(2);
864 " }" << endl
<< endl
;
867 if ( redFsm
->anyConditions() )
872 out
<< "_match:" << endl
;
875 out
<< " _trans = " << CAST(INT(), I() + "[_trans]") << endl
;
877 if ( redFsm
->anyEofTrans() )
878 out
<< "_eof_trans:" << endl
;
880 if ( redFsm
->anyRegCurStateRef() )
881 out
<< " _ps = " << vCS() << endl
;
884 " " << vCS() << " = " << CAST(INT(), TT() + "[_trans]") << endl
<< endl
;
886 if ( redFsm
->anyRegActions() ) {
888 " if " << TA() << "[_trans] == 0 {" << endl
<<
889 " goto _again" << endl
<<
892 " _acts = " << CAST(INT(), TA() + "[_trans]") << endl
<<
893 " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl
<<
894 " for ; _nacts > 0; _nacts-- {" << endl
<<
895 " _acts++" << endl
<<
896 " switch " << A() << "[_acts-1]" << " {" << endl
;
900 " }" << endl
<< endl
;
903 if ( redFsm
->anyRegActions() || redFsm
->anyActionGotos() ||
904 redFsm
->anyActionCalls() || redFsm
->anyActionRets() )
905 out
<< "_again:" << endl
;
907 if ( redFsm
->anyToStateActions() ) {
909 " _acts = " << CAST(INT(), TSA() + "[" + vCS() + "]") << endl
<<
910 " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl
<<
911 " for ; _nacts > 0; _nacts-- {" << endl
<<
912 " _acts++" << endl
<<
913 " switch " << A() << "[_acts-1] {" << endl
;
914 TO_STATE_ACTION_SWITCH(2);
917 " }" << endl
<< endl
;
920 if ( redFsm
->errState
!= 0 ) {
923 " if " << vCS() << " == " << redFsm
->errState
->id
<< " {" << endl
<<
924 " goto _out" << endl
<<
930 " " << P() << "++" << endl
<<
931 " if " << P() << " != " << PE() << " {" << endl
<<
932 " goto _resume" << endl
<<
937 " " << P() << "++" << endl
<<
938 " goto _resume" << endl
;
942 out
<< " _test_eof: {}" << endl
;
944 if ( redFsm
->anyEofTrans() || redFsm
->anyEofActions() ) {
946 " if " << P() << " == " << vEOF() << " {" << endl
;
948 if ( redFsm
->anyEofTrans() ) {
950 " if " << ET() << "[" << vCS() << "] > 0 {" << endl
<<
951 " _trans = " << CAST(INT(), ET() + "[" + vCS() + "] - 1") << endl
<<
952 " goto _eof_trans" << endl
<<
956 if ( redFsm
->anyEofActions() ) {
958 " __acts := " << EA() << "[" << vCS() << "]" << endl
<<
959 " __nacts := " << CAST(UINT(), A() + "[__acts]") << "; __acts++" << endl
<<
960 " for ; __nacts > 0; __nacts-- {" << endl
<<
961 " __acts++" << endl
<<
962 " switch " << A() << "[__acts-1] {" << endl
;
963 EOF_ACTION_SWITCH(3);
970 " }" << endl
<< endl
;
974 out
<< " _out: {}" << endl
;