tizen 2.3.1 release
[external/ragel.git] / ragel / csfflat.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 "csfflat.h"
26 #include "redfsm.h"
27 #include "gendata.h"
28
29 std::ostream &CSharpFFlatCodeGen::TO_STATE_ACTION( RedStateAp *state )
30 {
31         int act = 0;
32         if ( state->toStateAction != 0 )
33                 act = state->toStateAction->actListId+1;
34         out << act;
35         return out;
36 }
37
38 std::ostream &CSharpFFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state )
39 {
40         int act = 0;
41         if ( state->fromStateAction != 0 )
42                 act = state->fromStateAction->actListId+1;
43         out << act;
44         return out;
45 }
46
47 std::ostream &CSharpFFlatCodeGen::EOF_ACTION( RedStateAp *state )
48 {
49         int act = 0;
50         if ( state->eofAction != 0 )
51                 act = state->eofAction->actListId+1;
52         out << act;
53         return out;
54 }
55
56 /* Write out the function for a transition. */
57 std::ostream &CSharpFFlatCodeGen::TRANS_ACTION( RedTransAp *trans )
58 {
59         int action = 0;
60         if ( trans->action != 0 )
61                 action = trans->action->actListId+1;
62         out << action;
63         return out;
64 }
65
66 /* Write out the function switch. This switch is keyed on the values
67  * of the func index. */
68 std::ostream &CSharpFFlatCodeGen::TO_STATE_ACTION_SWITCH()
69 {
70         /* Loop the actions. */
71         for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
72                 if ( redAct->numToStateRefs > 0 ) {
73                         /* Write the entry label. */
74                         out << "\tcase " << redAct->actListId+1 << ":\n";
75
76                         /* Write each action in the list of action items. */
77                         for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
78                                 ACTION( out, item->value, 0, false );
79
80                         out << "\tbreak;\n";
81                 }
82         }
83
84         genLineDirective( out );
85         return out;
86 }
87
88 /* Write out the function switch. This switch is keyed on the values
89  * of the func index. */
90 std::ostream &CSharpFFlatCodeGen::FROM_STATE_ACTION_SWITCH()
91 {
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 << "\tcase " << redAct->actListId+1 << ":\n";
97
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 );
101
102                         out << "\tbreak;\n";
103                 }
104         }
105
106         genLineDirective( out );
107         return out;
108 }
109
110 std::ostream &CSharpFFlatCodeGen::EOF_ACTION_SWITCH()
111 {
112         /* Loop the actions. */
113         for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
114                 if ( redAct->numEofRefs > 0 ) {
115                         /* Write the entry label. */
116                         out << "\tcase " << redAct->actListId+1 << ":\n";
117
118                         /* Write each action in the list of action items. */
119                         for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
120                                 ACTION( out, item->value, 0, true );
121
122                         out << "\tbreak;\n";
123                 }
124         }
125
126         genLineDirective( out );
127         return out;
128 }
129
130 /* Write out the function switch. This switch is keyed on the values
131  * of the func index. */
132 std::ostream &CSharpFFlatCodeGen::ACTION_SWITCH()
133 {
134         /* Loop the actions. */
135         for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
136                 if ( redAct->numTransRefs > 0 ) {
137                         /* Write the entry label. */
138                         out << "\tcase " << redAct->actListId+1 << ":\n";
139
140                         /* Write each action in the list of action items. */
141                         for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
142                                 ACTION( out, item->value, 0, false );
143
144                         out << "\tbreak;\n";
145                 }
146         }
147
148         genLineDirective( out );
149         return out;
150 }
151
152 void CSharpFFlatCodeGen::writeData()
153 {
154         if ( redFsm->anyConditions() ) {
155                 OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
156                 COND_KEYS();
157                 CLOSE_ARRAY() <<
158                 "\n";
159
160                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() );
161                 COND_KEY_SPANS();
162                 CLOSE_ARRAY() <<
163                 "\n";
164
165                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() );
166                 CONDS();
167                 CLOSE_ARRAY() <<
168                 "\n";
169
170                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() );
171                 COND_INDEX_OFFSET();
172                 CLOSE_ARRAY() <<
173                 "\n";
174         }
175
176         OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
177         KEYS();
178         CLOSE_ARRAY() <<
179         "\n";
180
181         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() );
182         KEY_SPANS();
183         CLOSE_ARRAY() <<
184         "\n";
185
186         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() );
187         FLAT_INDEX_OFFSET();
188         CLOSE_ARRAY() <<
189         "\n";
190
191         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() );
192         INDICIES();
193         CLOSE_ARRAY() <<
194         "\n";
195
196         OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
197         TRANS_TARGS();
198         CLOSE_ARRAY() <<
199         "\n";
200
201         if ( redFsm->anyActions() ) {
202                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() );
203                 TRANS_ACTIONS();
204                 CLOSE_ARRAY() <<
205                 "\n";
206         }
207
208         if ( redFsm->anyToStateActions() ) {
209                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc),  TSA() );
210                 TO_STATE_ACTIONS();
211                 CLOSE_ARRAY() <<
212                 "\n";
213         }
214
215         if ( redFsm->anyFromStateActions() ) {
216                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
217                 FROM_STATE_ACTIONS();
218                 CLOSE_ARRAY() <<
219                 "\n";
220         }
221
222         if ( redFsm->anyEofActions() ) {
223                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() );
224                 EOF_ACTIONS();
225                 CLOSE_ARRAY() <<
226                 "\n";
227         }
228
229         if ( redFsm->anyEofTrans() ) {
230                 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() );
231                 EOF_TRANS();
232                 CLOSE_ARRAY() <<
233                 "\n";
234         }
235
236         STATE_IDS();
237 }
238
239 void CSharpFFlatCodeGen::writeExec()
240 {
241         testEofUsed = false;
242         outLabelUsed = false;
243         initVarTypes();
244
245         out << 
246                 "       {\n"
247                 "       " << slenType << " _slen";
248
249         if ( redFsm->anyRegCurStateRef() )
250                 out << ", _ps";
251         
252         out << ";\n";
253         out << "        " << transType << " _trans";
254
255         if ( redFsm->anyConditions() )
256                 out << ", _cond";
257
258         out << ";\n";
259
260         out <<
261                 "       " << "int _keys;\n"
262                 "       " << indsType << " _inds;\n";
263                 /*
264                 "       " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n"
265                 "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << POINTER() << "_inds;\n";*/
266
267         if ( redFsm->anyConditions() ) {
268                 out << 
269                         "       " << condsType << " _conds;\n"
270                         "       " << WIDE_ALPH_TYPE() << " _widec;\n";
271         }
272
273         if ( !noEnd ) {
274                 testEofUsed = true;
275                 out << 
276                         "       if ( " << P() << " == " << PE() << " )\n"
277                         "               goto _test_eof;\n";
278         }
279
280         if ( redFsm->errState != 0 ) {
281                 outLabelUsed = true;
282                 out << 
283                         "       if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
284                         "               goto _out;\n";
285         }
286
287         out << "_resume:\n";
288
289         if ( redFsm->anyFromStateActions() ) {
290                 out <<
291                         "       switch ( " << FSA() << "[" << vCS() << "] ) {\n";
292                         FROM_STATE_ACTION_SWITCH();
293                         SWITCH_DEFAULT() <<
294                         "       }\n"
295                         "\n";
296         }
297
298         if ( redFsm->anyConditions() )
299                 COND_TRANSLATE();
300
301         LOCATE_TRANS();
302
303         if ( redFsm->anyEofTrans() )
304                 out << "_eof_trans:\n";
305         
306         if ( redFsm->anyRegCurStateRef() )
307                 out << "        _ps = " << vCS() << ";\n";
308
309         out << 
310                 "       " << vCS() << " = " << TT() << "[_trans];\n\n";
311
312         if ( redFsm->anyRegActions() ) {
313                 out << 
314                         "       if ( " << TA() << "[_trans] == 0 )\n"
315                         "               goto _again;\n"
316                         "\n"
317                         "       switch ( " << TA() << "[_trans] ) {\n";
318                         ACTION_SWITCH();
319                         SWITCH_DEFAULT() <<
320                         "       }\n"
321                         "\n";
322         }
323
324         if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || 
325                         redFsm->anyActionCalls() || redFsm->anyActionRets() )
326                 out << "_again:\n";
327
328         if ( redFsm->anyToStateActions() ) {
329                 out <<
330                         "       switch ( " << TSA() << "[" << vCS() << "] ) {\n";
331                         TO_STATE_ACTION_SWITCH();
332                         SWITCH_DEFAULT() <<
333                         "       }\n"
334                         "\n";
335         }
336
337         if ( redFsm->errState != 0 ) {
338                 outLabelUsed = true;
339                 out << 
340                         "       if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
341                         "               goto _out;\n";
342         }
343
344         if ( !noEnd ) {
345                 out << 
346                         "       if ( ++" << P() << " != " << PE() << " )\n"
347                         "               goto _resume;\n";
348         }
349         else {
350                 out << 
351                         "       " << P() << " += 1;\n"
352                         "       goto _resume;\n";
353         }
354
355         if ( testEofUsed )
356                 out << "        _test_eof: {}\n";
357
358         if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
359                 out <<
360                         "       if ( " << P() << " == " << vEOF() << " )\n"
361                         "       {\n";
362
363                 if ( redFsm->anyEofTrans() ) {
364                         out <<
365                                 "       if ( " << ET() << "[" << vCS() << "] > 0 ) {\n"
366                                 "               _trans = " << CAST(transType) << " (" << ET() <<
367                                         "[" << vCS() << "] - 1);\n"
368                                 "               goto _eof_trans;\n"
369                                 "       }\n";
370                 }
371
372                 if ( redFsm->anyEofActions() ) {
373                         out <<
374                                 "       switch ( " << EA() << "[" << vCS() << "] ) {\n";
375                                 EOF_ACTION_SWITCH();
376                                 SWITCH_DEFAULT() <<
377                                 "       }\n";
378                 }
379
380                 out <<
381                         "       }\n"
382                         "\n";
383         }
384
385         if ( outLabelUsed )
386                 out << "        _out: {}\n";
387
388         out << "        }\n";
389 }