Use portable types in the C/C++ code generator
[ragel-jkt.git] / ragel / mlfflat.cpp
blob9251a9aff65f1f546ad79e658012168bdfa2dab3
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 */
7 /* This file is part of Ragel.
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.
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.
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
24 #include "ragel.h"
25 #include "mlfflat.h"
26 #include "redfsm.h"
27 #include "gendata.h"
29 std::ostream &OCamlFFlatCodeGen::TO_STATE_ACTION( RedStateAp *state )
31 int act = 0;
32 if ( state->toStateAction != 0 )
33 act = state->toStateAction->actListId+1;
34 out << act;
35 return out;
38 std::ostream &OCamlFFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state )
40 int act = 0;
41 if ( state->fromStateAction != 0 )
42 act = state->fromStateAction->actListId+1;
43 out << act;
44 return out;
47 std::ostream &OCamlFFlatCodeGen::EOF_ACTION( RedStateAp *state )
49 int act = 0;
50 if ( state->eofAction != 0 )
51 act = state->eofAction->actListId+1;
52 out << act;
53 return out;
56 /* Write out the function for a transition. */
57 std::ostream &OCamlFFlatCodeGen::TRANS_ACTION( RedTransAp *trans )
59 int action = 0;
60 if ( trans->action != 0 )
61 action = trans->action->actListId+1;
62 out << action;
63 return out;
66 /* Write out the function switch. This switch is keyed on the values
67 * of the func index. */
68 std::ostream &OCamlFFlatCodeGen::TO_STATE_ACTION_SWITCH()
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 << "\t| " << redAct->actListId+1 << " ->\n";
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 );
80 out << "\t()\n";
84 genLineDirective( out );
85 return out;
88 /* Write out the function switch. This switch is keyed on the values
89 * of the func index. */
90 std::ostream &OCamlFFlatCodeGen::FROM_STATE_ACTION_SWITCH()
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 << "\t| " << redAct->actListId+1 << " ->\n";
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 );
102 out << "\t()\n";
106 genLineDirective( out );
107 return out;
110 std::ostream &OCamlFFlatCodeGen::EOF_ACTION_SWITCH()
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 << "\t| " << redAct->actListId+1 << " ->\n";
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 );
122 out << "\t()\n";
126 genLineDirective( out );
127 return out;
130 /* Write out the function switch. This switch is keyed on the values
131 * of the func index. */
132 std::ostream &OCamlFFlatCodeGen::ACTION_SWITCH()
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 << "\t| " << redAct->actListId+1 << " ->\n";
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 );
144 out << "\t()\n";
148 genLineDirective( out );
149 return out;
152 void OCamlFFlatCodeGen::writeData()
154 if ( redFsm->anyConditions() ) {
155 OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
156 COND_KEYS();
157 CLOSE_ARRAY() <<
158 "\n";
160 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() );
161 COND_KEY_SPANS();
162 CLOSE_ARRAY() <<
163 "\n";
165 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() );
166 CONDS();
167 CLOSE_ARRAY() <<
168 "\n";
170 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() );
171 COND_INDEX_OFFSET();
172 CLOSE_ARRAY() <<
173 "\n";
176 OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
177 KEYS();
178 CLOSE_ARRAY() <<
179 "\n";
181 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() );
182 KEY_SPANS();
183 CLOSE_ARRAY() <<
184 "\n";
186 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() );
187 FLAT_INDEX_OFFSET();
188 CLOSE_ARRAY() <<
189 "\n";
191 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() );
192 INDICIES();
193 CLOSE_ARRAY() <<
194 "\n";
196 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
197 TRANS_TARGS();
198 CLOSE_ARRAY() <<
199 "\n";
201 if ( redFsm->anyActions() ) {
202 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() );
203 TRANS_ACTIONS();
204 CLOSE_ARRAY() <<
205 "\n";
208 if ( redFsm->anyToStateActions() ) {
209 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() );
210 TO_STATE_ACTIONS();
211 CLOSE_ARRAY() <<
212 "\n";
215 if ( redFsm->anyFromStateActions() ) {
216 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
217 FROM_STATE_ACTIONS();
218 CLOSE_ARRAY() <<
219 "\n";
222 if ( redFsm->anyEofActions() ) {
223 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() );
224 EOF_ACTIONS();
225 CLOSE_ARRAY() <<
226 "\n";
229 if ( redFsm->anyEofTrans() ) {
230 OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() );
231 EOF_TRANS();
232 CLOSE_ARRAY() <<
233 "\n";
236 STATE_IDS();
238 out << "type state = { mutable keys : int; mutable trans : int; }"
239 << TOP_SEP();
241 out << "exception Goto_match" << TOP_SEP();
242 out << "exception Goto_again" << TOP_SEP();
243 out << "exception Goto_eof_trans" << TOP_SEP();
246 void OCamlFFlatCodeGen::writeExec()
248 testEofUsed = false;
249 outLabelUsed = false;
250 initVarTypes();
252 out <<
253 " begin\n";
254 // " " << slenType << " _slen";
256 // if ( redFsm->anyRegCurStateRef() )
257 // out << ", _ps";
259 // out << ";\n";
260 // out << " " << transType << " _trans";
262 // if ( redFsm->anyConditions() )
263 // out << ", _cond";
265 // out << ";\n";
267 // out <<
268 // " " << "int _keys;\n"
269 // " " << indsType << " _inds;\n";
271 " " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n"
272 " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << POINTER() << "_inds;\n";*/
274 out <<
275 " let state = { keys = 0; trans = 0; } in\n"
276 " let rec do_start () =\n";
278 // if ( redFsm->anyConditions() ) {
279 // out <<
280 // " " << condsType << " _conds;\n"
281 // " " << WIDE_ALPH_TYPE() << " _widec;\n";
282 // }
284 if ( !noEnd ) {
285 testEofUsed = true;
286 out <<
287 " if " << P() << " = " << PE() << " then\n"
288 " do_test_eof ()\n"
289 "\telse\n";
292 if ( redFsm->errState != 0 ) {
293 outLabelUsed = true;
294 out <<
295 " if " << vCS() << " = " << redFsm->errState->id << " then\n"
296 " do_out ()\n"
297 "\telse\n";
299 out << "\tdo_resume ()\n";
301 out << "and do_resume () =\n";
303 if ( redFsm->anyFromStateActions() ) {
304 out <<
305 " begin match " << AT( FSA(), vCS() ) << " with\n";
306 FROM_STATE_ACTION_SWITCH();
307 SWITCH_DEFAULT() <<
308 " end;\n"
309 "\n";
312 if ( redFsm->anyConditions() )
313 COND_TRANSLATE();
315 out << "\tbegin try\n";
316 LOCATE_TRANS();
317 out << "\twith Goto_match -> () end;\n";
319 out << "\tdo_eof_trans ()\n";
321 // if ( redFsm->anyEofTrans() )
322 out << "and do_eof_trans () =\n";
324 if ( redFsm->anyRegCurStateRef() )
325 out << " let ps = " << vCS() << " in\n";
327 out <<
328 " " << vCS() << " <- " << AT( TT() ,"state.trans" ) << ";\n"
329 "\n";
331 if ( redFsm->anyRegActions() ) {
332 out <<
333 " begin try if " << AT( TA() , "state.trans" ) << " = 0 then\n"
334 " raise Goto_again;\n"
335 "\n"
336 " match " << AT( TA(), "state.trans" ) << " with\n";
337 ACTION_SWITCH();
338 SWITCH_DEFAULT() <<
339 " with Goto_again -> () end;\n"
340 "\n";
342 out << "\tdo_again ()\n";
344 // if ( redFsm->anyRegActions() || redFsm->anyActionGotos() ||
345 // redFsm->anyActionCalls() || redFsm->anyActionRets() )
346 out << "\tand do_again () =\n";
348 if ( redFsm->anyToStateActions() ) {
349 out <<
350 " begin match " << AT( TSA(), vCS() ) << " with\n";
351 TO_STATE_ACTION_SWITCH();
352 SWITCH_DEFAULT() <<
353 " end;\n"
354 "\n";
357 if ( redFsm->errState != 0 ) {
358 outLabelUsed = true;
359 out <<
360 " match " << vCS() << " with\n"
361 "\t| " << redFsm->errState->id << " -> do_out ()\n"
362 "\t| _ ->\n";
365 out << "\t" << P() << " <- " << P() << " + 1;\n";
367 if ( !noEnd ) {
368 out <<
369 " if " << P() << " <> " << PE() << " then\n"
370 " do_resume ()\n"
371 "\telse do_test_eof ()\n";
373 else {
374 out <<
375 " do_resume ()\n";
378 // if ( testEofUsed )
379 out << "and do_test_eof () =\n";
381 if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
382 out <<
383 " if " << P() << " = " << vEOF() << " then\n"
384 " begin try\n";
386 if ( redFsm->anyEofTrans() ) {
387 out <<
388 " if " << AT( ET(), vCS() ) << " > 0 then\n"
389 " begin\n"
390 " state.trans <- " << CAST(transType) << "(" << AT( ET(), vCS() ) << " - 1);\n"
391 " raise Goto_eof_trans;\n"
392 " end;\n";
395 if ( redFsm->anyEofActions() ) {
396 out <<
397 " begin match " << AT( EA(), vCS() ) << " with\n";
398 EOF_ACTION_SWITCH();
399 SWITCH_DEFAULT() <<
400 " end\n";
403 out <<
404 " with Goto_again -> do_again ()\n"
405 " | Goto_eof_trans -> do_eof_trans () end\n"
406 "\n";
408 else
410 out << "\t()\n";
413 if ( outLabelUsed )
414 out << " and do_out () = ()\n";
416 out << "\tin do_start ()\n";
417 out << " end;\n";