2 * Copyright 2004-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
31 std::ostream
&GoFFlatCodeGen::TO_STATE_ACTION( RedStateAp
*state
)
34 if ( state
->toStateAction
!= 0 )
35 act
= state
->toStateAction
->actListId
+1;
40 std::ostream
&GoFFlatCodeGen::FROM_STATE_ACTION( RedStateAp
*state
)
43 if ( state
->fromStateAction
!= 0 )
44 act
= state
->fromStateAction
->actListId
+1;
49 std::ostream
&GoFFlatCodeGen::EOF_ACTION( RedStateAp
*state
)
52 if ( state
->eofAction
!= 0 )
53 act
= state
->eofAction
->actListId
+1;
58 /* Write out the function for a transition. */
59 std::ostream
&GoFFlatCodeGen::TRANS_ACTION( RedTransAp
*trans
)
62 if ( trans
->action
!= 0 )
63 action
= trans
->action
->actListId
+1;
68 /* Write out the function switch. This switch is keyed on the values
69 * of the func index. */
70 std::ostream
&GoFFlatCodeGen::TO_STATE_ACTION_SWITCH( int level
)
72 /* Loop the actions. */
73 for ( GenActionTableMap::Iter redAct
= redFsm
->actionMap
; redAct
.lte(); redAct
++ ) {
74 if ( redAct
->numToStateRefs
> 0 ) {
75 /* Write the entry label. */
76 out
<< TABS(level
) << "case " << redAct
->actListId
+1 << ":" << endl
;
78 /* Write each action in the list of action items. */
79 for ( GenActionTable::Iter item
= redAct
->key
; item
.lte(); item
++ )
80 ACTION( out
, item
->value
, 0, false, false );
84 genLineDirective( out
);
88 /* Write out the function switch. This switch is keyed on the values
89 * of the func index. */
90 std::ostream
&GoFFlatCodeGen::FROM_STATE_ACTION_SWITCH( int level
)
92 /* Loop the actions. */
93 for ( GenActionTableMap::Iter redAct
= redFsm
->actionMap
; redAct
.lte(); redAct
++ ) {
94 if ( redAct
->numFromStateRefs
> 0 ) {
95 /* Write the entry label. */
96 out
<< TABS(level
) << "case " << redAct
->actListId
+1 << ":" << endl
;
98 /* Write each action in the list of action items. */
99 for ( GenActionTable::Iter item
= redAct
->key
; item
.lte(); item
++ )
100 ACTION( out
, item
->value
, 0, false, false );
104 genLineDirective( out
);
108 std::ostream
&GoFFlatCodeGen::EOF_ACTION_SWITCH( int level
)
110 /* Loop the actions. */
111 for ( GenActionTableMap::Iter redAct
= redFsm
->actionMap
; redAct
.lte(); redAct
++ ) {
112 if ( redAct
->numEofRefs
> 0 ) {
113 /* Write the entry label. */
114 out
<< TABS(level
) << "case " << redAct
->actListId
+1 << ":" << endl
;
116 /* Write each action in the list of action items. */
117 for ( GenActionTable::Iter item
= redAct
->key
; item
.lte(); item
++ )
118 ACTION( out
, item
->value
, 0, true, false );
122 genLineDirective( out
);
126 /* Write out the function switch. This switch is keyed on the values
127 * of the func index. */
128 std::ostream
&GoFFlatCodeGen::ACTION_SWITCH( int level
)
130 /* Loop the actions. */
131 for ( GenActionTableMap::Iter redAct
= redFsm
->actionMap
; redAct
.lte(); redAct
++ ) {
132 if ( redAct
->numTransRefs
> 0 ) {
133 /* Write the entry label. */
134 out
<< TABS(level
) << "case " << redAct
->actListId
+1 << ":" << endl
;
136 /* Write each action in the list of action items. */
137 for ( GenActionTable::Iter item
= redAct
->key
; item
.lte(); item
++ )
138 ACTION( out
, item
->value
, 0, false, false );
142 genLineDirective( out
);
146 void GoFFlatCodeGen::writeData()
148 if ( redFsm
->anyConditions() ) {
149 OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
154 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxCondSpan
), CSP() );
159 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxCond
), C() );
164 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxCondIndexOffset
), CO() );
170 OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
175 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxSpan
), SP() );
180 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxFlatIndexOffset
), IO() );
185 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxIndex
), I() );
190 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxState
), TT() );
195 if ( redFsm
->anyActions() ) {
196 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActListId
), TA() );
202 if ( redFsm
->anyToStateActions() ) {
203 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActionLoc
), TSA() );
209 if ( redFsm
->anyFromStateActions() ) {
210 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActionLoc
), FSA() );
211 FROM_STATE_ACTIONS();
216 if ( redFsm
->anyEofActions() ) {
217 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxActListId
), EA() );
223 if ( redFsm
->anyEofTrans() ) {
224 OPEN_ARRAY( ARRAY_TYPE(redFsm
->maxIndexOffset
+1), ET() );
233 void GoFFlatCodeGen::writeExec()
236 outLabelUsed
= false;
240 " var _slen " << INT() << endl
;
242 if ( redFsm
->anyRegCurStateRef() )
243 out
<< " var _ps " << INT() << endl
;
245 out
<< " var _trans " << INT() << endl
;
247 if ( redFsm
->anyConditions() )
248 out
<< " var _cond " << INT() << endl
;
251 " var _keys " << INT() << endl
<<
252 " var _inds " << INT() << endl
;
254 if ( redFsm
->anyConditions() ) {
256 " var _conds " << INT() << endl
<<
257 " var _widec " << WIDE_ALPH_TYPE() << endl
;
263 " if " << P() << " == " << PE() << " {" << endl
<<
264 " goto _test_eof" << endl
<<
268 if ( redFsm
->errState
!= 0 ) {
271 " if " << vCS() << " == " << redFsm
->errState
->id
<< " {" << endl
<<
272 " goto _out" << endl
<<
276 out
<< "_resume:" << endl
;
278 if ( redFsm
->anyFromStateActions() ) {
280 " switch " << FSA() << "[" << vCS() << "] {" << endl
;
281 FROM_STATE_ACTION_SWITCH(1);
287 if ( redFsm
->anyConditions() )
292 if ( redFsm
->anyEofTrans() )
293 out
<< "_eof_trans:" << endl
;
295 if ( redFsm
->anyRegCurStateRef() )
296 out
<< " _ps = " << vCS() << endl
;
299 " " << vCS() << " = " << CAST(INT(), TT() + "[_trans]") << endl
<<
302 if ( redFsm
->anyRegActions() ) {
304 " if " << TA() << "[_trans] == 0 {" << endl
<<
305 " goto _again" << endl
<<
308 " switch " << TA() << "[_trans] {" << endl
;
315 if ( redFsm
->anyRegActions() || redFsm
->anyActionGotos() ||
316 redFsm
->anyActionCalls() || redFsm
->anyActionRets() )
317 out
<< "_again:" << endl
;
319 if ( redFsm
->anyToStateActions() ) {
321 " switch " << TSA() << "[" << vCS() << "] {" << endl
;
322 TO_STATE_ACTION_SWITCH(1);
328 if ( redFsm
->errState
!= 0 ) {
331 " if " << vCS() << " == " << redFsm
->errState
->id
<< " {" << endl
<<
332 " goto _out" << endl
<<
338 " if " << P() << "++; " << P() << " != " << PE() << " {"
339 " goto _resume" << endl
<<
344 " " << P() << "++" << endl
<<
345 " goto _resume" << endl
;
349 out
<< " _test_eof: {}" << endl
;
351 if ( redFsm
->anyEofTrans() || redFsm
->anyEofActions() ) {
353 " if " << P() << " == " << vEOF() << " {" << endl
;
355 if ( redFsm
->anyEofTrans() ) {
357 " if " << ET() << "[" << vCS() << "] > 0 {" << endl
<<
358 " _trans = " << CAST(INT(), ET() + "[" + vCS() + "] - 1") << endl
<<
359 " goto _eof_trans" << endl
<<
363 if ( redFsm
->anyEofActions() ) {
365 " switch " << EA() << "[" << vCS() << "] {" << endl
;
366 EOF_ACTION_SWITCH(2);
377 out
<< " _out: {}" << endl
;