Tizen 2.1 base
[external/ragel.git] / rlcodegen / javacodegen.cpp
1 /*
2  *  Copyright 2006 Adrian Thurston <thurston@cs.queensu.ca>
3  */
4
5 /*  This file is part of Ragel.
6  *
7  *  Ragel is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  * 
12  *  Ragel is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  * 
17  *  You should have received a copy of the GNU General Public License
18  *  along with Ragel; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
20  */
21
22 #include "javacodegen.h"
23 #include "rlcodegen.h"
24 #include "tabcodegen.h"
25 #include "redfsm.h"
26 #include "gendata.h"
27
28 void JavaTabCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish )
29 {
30         ret << "{" << CS() << " = " << gotoDest << "; " << 
31                         CTRL_FLOW() << "break _again;}";
32 }
33
34 void JavaTabCodeGen::GOTO_EXPR( ostream &ret, InlineItem *ilItem, bool inFinish )
35 {
36         ret << "{" << CS() << " = (";
37         INLINE_LIST( ret, ilItem->children, 0, inFinish );
38         ret << "); " << CTRL_FLOW() << "break _again;}";
39 }
40
41 void JavaTabCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish )
42 {
43         ret << "{" << STACK() << "[" << TOP() << "++] = " << CS() << "; " << CS() << " = " << 
44                         callDest << "; " << CTRL_FLOW() << "break _again;}";
45 }
46
47 void JavaTabCodeGen::CALL_EXPR( ostream &ret, InlineItem *ilItem, int targState, bool inFinish )
48 {
49         ret << "{" << STACK() << "[" << TOP() << "++] = " << CS() << "; " << CS() << " = (";
50         INLINE_LIST( ret, ilItem->children, targState, inFinish );
51         ret << "); " << CTRL_FLOW() << "break _again;}";
52 }
53
54 void JavaTabCodeGen::RET( ostream &ret, bool inFinish )
55 {
56         ret << "{" << CS() << " = " << STACK() << "[--" << TOP() 
57                         << "]; " << CTRL_FLOW() << "break _again;}";
58 }
59
60 void JavaTabCodeGen::BREAK( ostream &ret, int targState )
61 {
62         ret << CTRL_FLOW() << "break _resume;";
63 }
64
65 void JavaTabCodeGen::COND_TRANSLATE()
66 {
67         out << 
68                 "       _widec = " << GET_KEY() << ";\n"
69                 "       _keys = " << CO() << "[" << CS() << "]*2\n;"
70                 "       _klen = " << CL() << "[" << CS() << "];\n"
71                 "       if ( _klen > 0 ) {\n"
72                 "               int _lower = _keys\n;"
73                 "               int _mid;\n"
74                 "               int _upper = _keys + (_klen<<1) - 2;\n"
75                 "               while (true) {\n"
76                 "                       if ( _upper < _lower )\n"
77                 "                               break;\n"
78                 "\n"
79                 "                       _mid = _lower + (((_upper-_lower) >> 1) & ~1);\n"
80                 "                       if ( " << GET_WIDE_KEY() << " < " << CK() << "[_mid] )\n"
81                 "                               _upper = _mid - 2;\n"
82                 "                       else if ( " << GET_WIDE_KEY() << " > " << CK() << "[_mid] )\n"
83                 "                               _lower = _mid + 2;\n"
84                 "                       else {\n"
85                 "                               switch ( " << C() << "[" << CO() << "[" << CS() << "]"
86                                                         " + ((_mid - _keys)>>1)] ) {\n"
87                 ;
88
89         for ( CondSpaceList::Iter csi = cgd->condSpaceList; csi.lte(); csi++ ) {
90                 CondSpace *condSpace = csi;
91                 out << "        case " << condSpace->condSpaceId << ": {\n";
92                 out << TABS(2) << "_widec = " << KEY(condSpace->baseKey) << 
93                                 " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << ");\n";
94
95                 for ( CondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
96                         out << TABS(2) << "if ( ";
97                         CONDITION( out, *csi );
98                         Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
99                         out << " ) _widec += " << condValOffset << ";\n";
100                 }
101
102                 out << 
103                         "               break;\n"
104                         "       }\n";
105         }
106
107         out << 
108                 "                               }\n"
109                 "                               break;\n"
110                 "                       }\n"
111                 "               }\n"
112                 "       }\n"
113                 "\n";
114 }
115
116
117 void JavaTabCodeGen::LOCATE_TRANS()
118 {
119         out <<
120                 "       _match: do {\n"
121                 "       _keys = " << KO() << "[" << CS() << "]" << ";\n"
122                 "       _trans = " << IO() << "[" << CS() << "];\n"
123                 "       _klen = " << SL() << "[" << CS() << "];\n"
124                 "       if ( _klen > 0 ) {\n"
125                 "               int _lower = _keys;\n"
126                 "               int _mid;\n"
127                 "               int _upper = _keys + _klen - 1;\n"
128                 "               while (true) {\n"
129                 "                       if ( _upper < _lower )\n"
130                 "                               break;\n"
131                 "\n"
132                 "                       _mid = _lower + ((_upper-_lower) >> 1);\n"
133                 "                       if ( " << GET_WIDE_KEY() << " < " << K() << "[_mid] )\n"
134                 "                               _upper = _mid - 1;\n"
135                 "                       else if ( " << GET_WIDE_KEY() << " > " << K() << "[_mid] )\n"
136                 "                               _lower = _mid + 1;\n"
137                 "                       else {\n"
138                 "                               _trans += (_mid - _keys);\n"
139                 "                               break _match;\n"
140                 "                       }\n"
141                 "               }\n"
142                 "               _keys += _klen;\n"
143                 "               _trans += _klen;\n"
144                 "       }\n"
145                 "\n"
146                 "       _klen = " << RL() << "[" << CS() << "];\n"
147                 "       if ( _klen > 0 ) {\n"
148                 "               int _lower = _keys;\n"
149                 "               int _mid;\n"
150                 "               int _upper = _keys + (_klen<<1) - 2;\n"
151                 "               while (true) {\n"
152                 "                       if ( _upper < _lower )\n"
153                 "                               break;\n"
154                 "\n"
155                 "                       _mid = _lower + (((_upper-_lower) >> 1) & ~1);\n"
156                 "                       if ( " << GET_WIDE_KEY() << " < " << K() << "[_mid] )\n"
157                 "                               _upper = _mid - 2;\n"
158                 "                       else if ( " << GET_WIDE_KEY() << " > " << K() << "[_mid+1] )\n"
159                 "                               _lower = _mid + 2;\n"
160                 "                       else {\n"
161                 "                               _trans += ((_mid - _keys)>>1);\n"
162                 "                               break _match;\n"
163                 "                       }\n"
164                 "               }\n"
165                 "               _trans += _klen;\n"
166                 "       }\n"
167                 "       } while (false);\n"
168                 "\n";
169 }
170
171 void JavaTabCodeGen::writeOutExec()
172 {
173         out <<
174                 "       {\n"
175                 "       int _klen";
176
177         if ( anyRegCurStateRef() )
178                 out << ", _ps";
179
180         out << 
181                 ";\n"
182                 "       int _trans;\n";
183
184         if ( anyConditions() )
185                 out << "        int _widec;\n";
186
187         if ( anyToStateActions() || anyRegActions() || anyFromStateActions() ) {
188                 out << 
189                         "       int _acts;\n"
190                         "       int _nacts;\n";
191         }
192
193         out <<
194                 "       int _keys;\n"
195                 "\n";
196
197         if ( cgd->hasEnd )
198                 out << "        if ( " << P() << " != " << PE() << " ) {\n";
199
200         out << "        _resume: while ( true ) {\n";
201
202         out << "        _again: do {\n";
203
204         if ( redFsm->errState != 0 ) {
205                 out << 
206                         "       if ( " << CS() << " == " << redFsm->errState->id << " )\n"
207                         "               break _resume;\n";
208         }
209
210         if ( anyFromStateActions() ) {
211                 out <<
212                         "       _acts = " << FSA() << "[" << CS() << "]" << ";\n"
213                         "       _nacts = " << CAST("int") << " " << A() << "[_acts++];\n"
214                         "       while ( _nacts-- > 0 ) {\n"
215                         "               switch ( " << A() << "[_acts++] ) {\n";
216                         FROM_STATE_ACTION_SWITCH();
217                         SWITCH_DEFAULT() <<
218                         "               }\n"
219                         "       }\n"
220                         "\n";
221         }
222
223         if ( anyConditions() )
224                 COND_TRANSLATE();
225
226         LOCATE_TRANS();
227
228         if ( anyRegCurStateRef() )
229                 out << "        _ps = " << CS() << ";\n";
230
231         if ( useIndicies )
232                 out << "        _trans = " << I() << "[_trans];\n";
233
234         out <<
235                 "       " << CS() << " = " << TT() << "[_trans];\n"
236                 "\n";
237
238         if ( anyRegActions() ) {
239                 out <<
240                         "       if ( " << TA() << "[_trans] == 0 )\n"
241                         "               break _again;\n"
242                         "\n"
243                         "       _acts = " <<  TA() << "[_trans]" << ";\n"
244                         "       _nacts = " << CAST("int") << " " <<  A() << "[_acts++];\n"
245                         "       while ( _nacts-- > 0 )\n        {\n"
246                         "               switch ( " << A() << "[_acts++] )\n"
247                         "               {\n";
248                         ACTION_SWITCH();
249                         SWITCH_DEFAULT() <<
250                         "               }\n"
251                         "       }\n"
252                         "\n";
253         }
254
255         /* Again loop, functions as again label. */
256         out << "        } while (false);\n";
257
258         if ( anyToStateActions() ) {
259                 out <<
260                         "       _acts = " << TSA() << "[" << CS() << "]" << ";\n"
261                         "       _nacts = " << CAST("int") << " " << A() << "[_acts++];\n"
262                         "       while ( _nacts-- > 0 ) {\n"
263                         "               switch ( " << A() << "[_acts++] ) {\n";
264                         TO_STATE_ACTION_SWITCH();
265                         SWITCH_DEFAULT() <<
266                         "               }\n"
267                         "       }\n"
268                         "\n";
269         }
270
271         if ( cgd->hasEnd ) {
272                 out << 
273                         "       if ( ++" << P() << " == " << PE() << " )\n"
274                         "               break _resume;\n";
275         }
276         else {
277                 out << 
278                         "       " << P() << " += 1;\n";
279         }
280
281         /* Close the resume loop. */
282         out << "        }\n";
283
284         /* The if guarding on empty string. */
285         if ( cgd->hasEnd )
286                 out << "        }\n";
287
288         /* The execute block. */
289         out << "        }\n";
290 }
291
292 void JavaTabCodeGen::writeOutEOF()
293 {
294         if ( anyEofActions() ) {
295                 out <<
296                         "       int _acts = " << EA() << "[" << CS() << "]" << ";\n"
297                         "       int _nacts = " << CAST("int") << " " << A() << "[_acts++];\n"
298                         "       while ( _nacts-- > 0 ) {\n"
299                         "               switch ( " << A() << "[_acts++] ) {\n";
300                         EOF_ACTION_SWITCH();
301                         SWITCH_DEFAULT() <<
302                         "               }\n"
303                         "       }\n"
304                         "\n";
305         }
306 }
307