Initialize Tizen 2.3
[external/ragel.git] / ragel / csfgoto.cpp
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 "csfgoto.h"
26 #include "redfsm.h"
27 #include "gendata.h"
28 #include "bstmap.h"
29
30 std::ostream &CSharpFGotoCodeGen::EXEC_ACTIONS()
31 {
32         /* Loop the actions. */
33         for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
34                 if ( redAct->numTransRefs > 0 ) {
35                         /*      We are at the start of a glob, write the case. */
36                         out << "f" << redAct->actListId << ":\n";
37
38                         /* Write each action in the list of action items. */
39                         for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
40                                 ACTION( out, item->value, 0, false );
41
42                         out << "\tgoto _again;\n";
43                 }
44         }
45         return out;
46 }
47
48 /* Write out the function switch. This switch is keyed on the values
49  * of the func index. */
50 std::ostream &CSharpFGotoCodeGen::TO_STATE_ACTION_SWITCH()
51 {
52         /* Loop the actions. */
53         for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
54                 if ( redAct->numToStateRefs > 0 ) {
55                         /* Write the entry label. */
56                         out << "\tcase " << redAct->actListId+1 << ":\n";
57
58                         /* Write each action in the list of action items. */
59                         for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
60                                 ACTION( out, item->value, 0, false );
61
62                         out << "\tbreak;\n";
63                 }
64         }
65
66         genLineDirective( out );
67         return out;
68 }
69
70 /* Write out the function switch. This switch is keyed on the values
71  * of the func index. */
72 std::ostream &CSharpFGotoCodeGen::FROM_STATE_ACTION_SWITCH()
73 {
74         /* Loop the actions. */
75         for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
76                 if ( redAct->numFromStateRefs > 0 ) {
77                         /* Write the entry label. */
78                         out << "\tcase " << redAct->actListId+1 << ":\n";
79
80                         /* Write each action in the list of action items. */
81                         for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
82                                 ACTION( out, item->value, 0, false );
83
84                         out << "\tbreak;\n";
85                 }
86         }
87
88         genLineDirective( out );
89         return out;
90 }
91
92 std::ostream &CSharpFGotoCodeGen::EOF_ACTION_SWITCH()
93 {
94         /* Loop the actions. */
95         for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
96                 if ( redAct->numEofRefs > 0 ) {
97                         /* Write the entry label. */
98                         out << "\tcase " << redAct->actListId+1 << ":\n";
99
100                         /* Write each action in the list of action items. */
101                         for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
102                                 ACTION( out, item->value, 0, true );
103
104                         out << "\tbreak;\n";
105                 }
106         }
107
108         genLineDirective( out );
109         return out;
110 }
111
112
113 std::ostream &CSharpFGotoCodeGen::FINISH_CASES()
114 {
115         for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
116                 /* States that are final and have an out action need a case. */
117                 if ( st->eofAction != 0 ) {
118                         /* Write the case label. */
119                         out << "\t\tcase " << st->id << ": ";
120
121                         /* Jump to the func. */
122                         out << "goto f" << st->eofAction->actListId << ";\n";
123                 }
124         }
125
126         return out;
127 }
128
129 unsigned int CSharpFGotoCodeGen::TO_STATE_ACTION( RedStateAp *state )
130 {
131         int act = 0;
132         if ( state->toStateAction != 0 )
133                 act = state->toStateAction->actListId+1;
134         return act;
135 }
136
137 unsigned int CSharpFGotoCodeGen::FROM_STATE_ACTION( RedStateAp *state )
138 {
139         int act = 0;
140         if ( state->fromStateAction != 0 )
141                 act = state->fromStateAction->actListId+1;
142         return act;
143 }
144
145 unsigned int CSharpFGotoCodeGen::EOF_ACTION( RedStateAp *state )
146 {
147         int act = 0;
148         if ( state->eofAction != 0 )
149                 act = state->eofAction->actListId+1;
150         return act;
151 }
152
153 void CSharpFGotoCodeGen::writeData()
154 {
155         if ( redFsm->anyToStateActions() ) {
156                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() );
157                 TO_STATE_ACTIONS();
158                 CLOSE_ARRAY() <<
159                 "\n";
160         }
161
162         if ( redFsm->anyFromStateActions() ) {
163                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
164                 FROM_STATE_ACTIONS();
165                 CLOSE_ARRAY() <<
166                 "\n";
167         }
168
169         if ( redFsm->anyEofActions() ) {
170                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() );
171                 EOF_ACTIONS();
172                 CLOSE_ARRAY() <<
173                 "\n";
174         }
175
176         STATE_IDS();
177 }
178
179 void CSharpFGotoCodeGen::writeExec()
180 {
181         testEofUsed = false;
182         outLabelUsed = false;
183
184         out << "        {\n";
185
186         if ( redFsm->anyRegCurStateRef() )
187                 out << "        int _ps = 0;\n";
188
189         if ( redFsm->anyConditions() )
190                 out << "        " << WIDE_ALPH_TYPE() << " _widec;\n";
191
192         if ( !noEnd ) {
193                 testEofUsed = true;
194                 out << 
195                         "       if ( " << P() << " == " << PE() << " )\n"
196                         "               goto _test_eof;\n";
197         }
198
199         if ( redFsm->errState != 0 ) {
200                 outLabelUsed = true;
201                 out << 
202                         "       if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
203                         "               goto _out;\n";
204         }
205
206         out << "_resume:\n";
207
208         if ( redFsm->anyFromStateActions() ) {
209                 out <<
210                         "       switch ( " << FSA() << "[" << vCS() << "] ) {\n";
211                         FROM_STATE_ACTION_SWITCH();
212                         SWITCH_DEFAULT() <<
213                         "       }\n"
214                         "\n";
215         }
216
217         out << 
218                 "       switch ( " << vCS() << " ) {\n";
219                 STATE_GOTOS();
220                 SWITCH_DEFAULT() <<
221                 "       }\n"
222                 "\n";
223                 TRANSITIONS() << 
224                 "\n";
225
226         if ( redFsm->anyRegActions() )
227                 EXEC_ACTIONS() << "\n";
228
229         out << "_again:\n";
230
231         if ( redFsm->anyToStateActions() ) {
232                 out <<
233                         "       switch ( " << TSA() << "[" << vCS() << "] ) {\n";
234                         TO_STATE_ACTION_SWITCH();
235                         SWITCH_DEFAULT() <<
236                         "       }\n"
237                         "\n";
238         }
239
240         if ( redFsm->errState != 0 ) {
241                 outLabelUsed = true;
242                 out << 
243                         "       if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
244                         "               goto _out;\n";
245         }
246
247         if ( !noEnd ) {
248                 out << 
249                         "       if ( ++" << P() << " != " << PE() << " )\n"
250                         "               goto _resume;\n";
251         }
252         else {
253                 out << 
254                         "       " << P() << " += 1;\n"
255                         "       goto _resume;\n";
256         }
257
258         if ( testEofUsed )
259                 out << "        _test_eof: {}\n";
260
261         if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
262                 out <<
263                         "       if ( " << P() << " == " << vEOF() << " )\n"
264                         "       {\n";
265
266                 if ( redFsm->anyEofTrans() ) {
267                         out <<
268                                 "       switch ( " << vCS() << " ) {\n";
269
270                         for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
271                                 if ( st->eofTrans != 0 )
272                                         out << "        case " << st->id << ": goto tr" << st->eofTrans->id << ";\n";
273                         }
274
275                         SWITCH_DEFAULT() <<
276                                 "       }\n";
277                 }
278
279                 if ( redFsm->anyEofActions() ) {
280                         out <<
281                                 "       switch ( " << EA() << "[" << vCS() << "] ) {\n";
282                                 EOF_ACTION_SWITCH();
283                                 SWITCH_DEFAULT() <<
284                                 "       }\n";
285                 }
286
287                 out <<
288                         "       }\n"
289                         "\n";
290         }
291
292         if ( outLabelUsed )
293                 out << "        _out: {}\n";
294
295         out << "        }\n";
296 }