2 * Copyright 2006 Adrian Thurston <thurston@cs.queensu.ca>
5 /* This file is part of Ragel.
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.
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.
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
22 #include "javacodegen.h"
23 #include "rlcodegen.h"
24 #include "tabcodegen.h"
28 void JavaTabCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish )
30 ret << "{" << CS() << " = " << gotoDest << "; " <<
31 CTRL_FLOW() << "break _again;}";
34 void JavaTabCodeGen::GOTO_EXPR( ostream &ret, InlineItem *ilItem, bool inFinish )
36 ret << "{" << CS() << " = (";
37 INLINE_LIST( ret, ilItem->children, 0, inFinish );
38 ret << "); " << CTRL_FLOW() << "break _again;}";
41 void JavaTabCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish )
43 ret << "{" << STACK() << "[" << TOP() << "++] = " << CS() << "; " << CS() << " = " <<
44 callDest << "; " << CTRL_FLOW() << "break _again;}";
47 void JavaTabCodeGen::CALL_EXPR( ostream &ret, InlineItem *ilItem, int targState, bool inFinish )
49 ret << "{" << STACK() << "[" << TOP() << "++] = " << CS() << "; " << CS() << " = (";
50 INLINE_LIST( ret, ilItem->children, targState, inFinish );
51 ret << "); " << CTRL_FLOW() << "break _again;}";
54 void JavaTabCodeGen::RET( ostream &ret, bool inFinish )
56 ret << "{" << CS() << " = " << STACK() << "[--" << TOP()
57 << "]; " << CTRL_FLOW() << "break _again;}";
60 void JavaTabCodeGen::BREAK( ostream &ret, int targState )
62 ret << CTRL_FLOW() << "break _resume;";
65 void JavaTabCodeGen::COND_TRANSLATE()
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;"
74 " int _upper = _keys + (_klen<<1) - 2;\n"
76 " if ( _upper < _lower )\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"
85 " switch ( " << C() << "[" << CO() << "[" << CS() << "]"
86 " + ((_mid - _keys)>>1)] ) {\n"
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";
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";
117 void JavaTabCodeGen::LOCATE_TRANS()
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"
127 " int _upper = _keys + _klen - 1;\n"
129 " if ( _upper < _lower )\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"
138 " _trans += (_mid - _keys);\n"
143 " _trans += _klen;\n"
146 " _klen = " << RL() << "[" << CS() << "];\n"
147 " if ( _klen > 0 ) {\n"
148 " int _lower = _keys;\n"
150 " int _upper = _keys + (_klen<<1) - 2;\n"
152 " if ( _upper < _lower )\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"
161 " _trans += ((_mid - _keys)>>1);\n"
165 " _trans += _klen;\n"
167 " } while (false);\n"
171 void JavaTabCodeGen::writeOutExec()
177 if ( anyRegCurStateRef() )
184 if ( anyConditions() )
185 out << " int _widec;\n";
187 if ( anyToStateActions() || anyRegActions() || anyFromStateActions() ) {
198 out << " if ( " << P() << " != " << PE() << " ) {\n";
200 out << " _resume: while ( true ) {\n";
202 out << " _again: do {\n";
204 if ( redFsm->errState != 0 ) {
206 " if ( " << CS() << " == " << redFsm->errState->id << " )\n"
210 if ( anyFromStateActions() ) {
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();
223 if ( anyConditions() )
228 if ( anyRegCurStateRef() )
229 out << " _ps = " << CS() << ";\n";
232 out << " _trans = " << I() << "[_trans];\n";
235 " " << CS() << " = " << TT() << "[_trans];\n"
238 if ( anyRegActions() ) {
240 " if ( " << TA() << "[_trans] == 0 )\n"
243 " _acts = " << TA() << "[_trans]" << ";\n"
244 " _nacts = " << CAST("int") << " " << A() << "[_acts++];\n"
245 " while ( _nacts-- > 0 )\n {\n"
246 " switch ( " << A() << "[_acts++] )\n"
255 /* Again loop, functions as again label. */
256 out << " } while (false);\n";
258 if ( anyToStateActions() ) {
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();
273 " if ( ++" << P() << " == " << PE() << " )\n"
278 " " << P() << " += 1;\n";
281 /* Close the resume loop. */
284 /* The if guarding on empty string. */
288 /* The execute block. */
292 void JavaTabCodeGen::writeOutEOF()
294 if ( anyEofActions() ) {
296 " int _acts = " << EA() << "[" << CS() << "]" << ";\n"
297 " int _nacts = " << CAST("int") << " " << A() << "[_acts++];\n"
298 " while ( _nacts-- > 0 ) {\n"
299 " switch ( " << A() << "[_acts++] ) {\n";