Initialize Tizen 2.3
[external/ragel.git] / ragel / cdfflat.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 "cdfflat.h"
26 #include "redfsm.h"
27 #include "gendata.h"
28
29 std::ostream &FFlatCodeGen::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 &FFlatCodeGen::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 &FFlatCodeGen::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 &FFlatCodeGen::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 &FFlatCodeGen::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, 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 &FFlatCodeGen::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, false );
101
102                         out << "\tbreak;\n";
103                 }
104         }
105
106         genLineDirective( out );
107         return out;
108 }
109
110 std::ostream &FFlatCodeGen::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, false );
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 &FFlatCodeGen::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, false );
143
144                         out << "\tbreak;\n";
145                 }
146         }
147
148         genLineDirective( out );
149         return out;
150 }
151
152 void FFlatCodeGen::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 FFlatCodeGen::writeExec()
240 {
241         testEofUsed = false;
242         outLabelUsed = false;
243
244         out << 
245                 "       {\n"
246                 "       int _slen";
247
248         if ( redFsm->anyRegCurStateRef() )
249                 out << ", _ps";
250         
251         out << ";\n";
252         out << "        int _trans";
253
254         if ( redFsm->anyConditions() )
255                 out << ", _cond";
256
257         out << ";\n";
258
259         out <<
260                 "       " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n"
261                 "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << POINTER() << "_inds;\n";
262
263         if ( redFsm->anyConditions() ) {
264                 out << 
265                         "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxCond) << POINTER() << "_conds;\n"
266                         "       " << WIDE_ALPH_TYPE() << " _widec;\n";
267         }
268
269         if ( !noEnd ) {
270                 testEofUsed = true;
271                 out << 
272                         "       if ( " << P() << " == " << PE() << " )\n"
273                         "               goto _test_eof;\n";
274         }
275
276         if ( redFsm->errState != 0 ) {
277                 outLabelUsed = true;
278                 out << 
279                         "       if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
280                         "               goto _out;\n";
281         }
282
283         out << "_resume:\n";
284
285         if ( redFsm->anyFromStateActions() ) {
286                 out <<
287                         "       switch ( " << FSA() << "[" << vCS() << "] ) {\n";
288                         FROM_STATE_ACTION_SWITCH();
289                         SWITCH_DEFAULT() <<
290                         "       }\n"
291                         "\n";
292         }
293
294         if ( redFsm->anyConditions() )
295                 COND_TRANSLATE();
296
297         LOCATE_TRANS();
298
299         if ( redFsm->anyEofTrans() )
300                 out << "_eof_trans:\n";
301         
302         if ( redFsm->anyRegCurStateRef() )
303                 out << "        _ps = " << vCS() << ";\n";
304
305         out << 
306                 "       " << vCS() << " = " << TT() << "[_trans];\n\n";
307
308         if ( redFsm->anyRegActions() ) {
309                 out << 
310                         "       if ( " << TA() << "[_trans] == 0 )\n"
311                         "               goto _again;\n"
312                         "\n"
313                         "       switch ( " << TA() << "[_trans] ) {\n";
314                         ACTION_SWITCH();
315                         SWITCH_DEFAULT() <<
316                         "       }\n"
317                         "\n";
318         }
319
320         if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || 
321                         redFsm->anyActionCalls() || redFsm->anyActionRets() )
322                 out << "_again:\n";
323
324         if ( redFsm->anyToStateActions() ) {
325                 out <<
326                         "       switch ( " << TSA() << "[" << vCS() << "] ) {\n";
327                         TO_STATE_ACTION_SWITCH();
328                         SWITCH_DEFAULT() <<
329                         "       }\n"
330                         "\n";
331         }
332
333         if ( redFsm->errState != 0 ) {
334                 outLabelUsed = true;
335                 out << 
336                         "       if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
337                         "               goto _out;\n";
338         }
339
340         if ( !noEnd ) {
341                 out << 
342                         "       if ( ++" << P() << " != " << PE() << " )\n"
343                         "               goto _resume;\n";
344         }
345         else {
346                 out << 
347                         "       " << P() << " += 1;\n"
348                         "       goto _resume;\n";
349         }
350
351         if ( testEofUsed )
352                 out << "        _test_eof: {}\n";
353
354         if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
355                 out <<
356                         "       if ( " << P() << " == " << vEOF() << " )\n"
357                         "       {\n";
358
359                 if ( redFsm->anyEofTrans() ) {
360                         out <<
361                                 "       if ( " << ET() << "[" << vCS() << "] > 0 ) {\n"
362                                 "               _trans = " << ET() << "[" << vCS() << "] - 1;\n"
363                                 "               goto _eof_trans;\n"
364                                 "       }\n";
365                 }
366
367                 if ( redFsm->anyEofActions() ) {
368                         out <<
369                                 "       switch ( " << EA() << "[" << vCS() << "] ) {\n";
370                                 EOF_ACTION_SWITCH();
371                                 SWITCH_DEFAULT() <<
372                                 "       }\n";
373                 }
374
375                 out <<
376                         "       }\n"
377                         "\n";
378         }
379
380         if ( outLabelUsed )
381                 out << "        _out: {}\n";
382
383         out << "        }\n";
384 }