in ragel/src/ragel/mlflat.cpp [702:903]
void OCamlFlatCodeGen::writeExec()
{
testEofUsed = false;
outLabelUsed = false;
initVarTypes();
out <<
" begin\n";
// " " << slenType << " _slen";
// if ( redFsm->anyRegCurStateRef() )
// out << ", _ps";
// out <<
// " " << transType << " _trans";
// if ( redFsm->anyConditions() )
// out << ", _cond";
// out << ";\n";
// if ( redFsm->anyToStateActions() ||
// redFsm->anyRegActions() || redFsm->anyFromStateActions() )
// {
// out <<
// " int _acts;\n"
// " int _nacts;\n";
// }
// out <<
// " " << "int _keys;\n"
// " " << indsType << " _inds;\n";
/*
" " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n"
" " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << POINTER() << "_inds;\n";*/
if ( redFsm->anyConditions() ) {
out <<
" " << condsType << " _conds;\n"
" " << WIDE_ALPH_TYPE() << " _widec;\n";
}
out << "\n";
out <<
" let state = { trans = 0; acts = 0; nacts = 0; } in\n"
" let rec do_start () =\n";
if ( !noEnd ) {
testEofUsed = true;
out <<
" if " << P() << " = " << PE() << " then\n"
" do_test_eof ()\n"
"\telse\n";
}
if ( redFsm->errState != 0 ) {
outLabelUsed = true;
out <<
" if " << vCS() << " = " << redFsm->errState->id << " then\n"
" do_out ()\n"
"\telse\n";
}
out << "\tdo_resume ()\n";
out << "and do_resume () =\n";
if ( redFsm->anyFromStateActions() ) {
out <<
" state.acts <- " << AT( FSA(), vCS() ) << ";\n"
" state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n"
" while " << POST_DECR("state.nacts") << " > 0 do\n"
" begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n";
FROM_STATE_ACTION_SWITCH();
SWITCH_DEFAULT() <<
" end\n"
" done;\n"
"\n";
}
if ( redFsm->anyConditions() )
COND_TRANSLATE();
// out << "\tbegin try\n";
LOCATE_TRANS();
// out << "\twith Goto_match -> () end;\n";
out << "\tdo_eof_trans ()\n";
// if ( redFsm->anyEofTrans() )
out << "and do_eof_trans () =\n";
if ( redFsm->anyRegCurStateRef() )
out << " let ps = " << vCS() << " in\n";
out <<
" " << vCS() << " <- " << AT( TT() ,"state.trans" ) << ";\n"
"\n";
if ( redFsm->anyRegActions() ) {
out <<
"\tbegin try\n"
" match " << AT( TA(), "state.trans" ) << " with\n"
"\t| 0 -> raise Goto_again\n"
"\t| _ ->\n"
" state.acts <- " << AT( TA(), "state.trans" ) << ";\n"
" state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n"
" while " << POST_DECR("state.nacts") << " > 0 do\n"
" begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n";
ACTION_SWITCH();
SWITCH_DEFAULT() <<
" end;\n"
" done\n"
"\twith Goto_again -> () end;\n";
}
out << "\tdo_again ()\n";
// if ( redFsm->anyRegActions() || redFsm->anyActionGotos() ||
// redFsm->anyActionCalls() || redFsm->anyActionRets() )
out << "\tand do_again () =\n";
if ( redFsm->anyToStateActions() ) {
out <<
" state.acts <- " << AT( TSA(), vCS() ) << ";\n"
" state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n"
" while " << POST_DECR("state.nacts") << " > 0 do\n"
" begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n";
TO_STATE_ACTION_SWITCH();
SWITCH_DEFAULT() <<
" end\n"
" done;\n"
"\n";
}
if ( redFsm->errState != 0 ) {
outLabelUsed = true;
out <<
" match " << vCS() << " with\n"
"\t| " << redFsm->errState->id << " -> do_out ()\n"
"\t| _ ->\n";
}
out << "\t" << P() << " <- " << P() << " + 1;\n";
if ( !noEnd ) {
out <<
" if " << P() << " <> " << PE() << " then\n"
" do_resume ()\n"
"\telse do_test_eof ()\n";
}
else {
out <<
" do_resume ()\n";
}
// if ( testEofUsed )
out << "and do_test_eof () =\n";
if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
out <<
" if " << P() << " = " << vEOF() << " then\n"
" begin try\n";
if ( redFsm->anyEofTrans() ) {
out <<
" if " << AT( ET(), vCS() ) << " > 0 then\n"
" begin\n"
" state.trans <- " << CAST(transType) << "(" << AT( ET(), vCS() ) << " - 1);\n"
" raise Goto_eof_trans;\n"
" end;\n";
}
if ( redFsm->anyEofActions() ) {
out <<
" let __acts = ref " << AT( EA(), vCS() ) << " in\n"
" let __nacts = ref " << AT( A(), "!__acts" ) << " in\n"
" incr __acts;\n"
" while !__nacts > 0 do\n"
" decr __nacts;\n"
" begin match " << AT( A(), POST_INCR("__acts.contents") ) << " with\n";
EOF_ACTION_SWITCH();
SWITCH_DEFAULT() <<
" end;\n"
" done\n";
}
out <<
" with Goto_again -> do_again ()\n"
" | Goto_eof_trans -> do_eof_trans () end\n"
"\n";
}
else
{
out << "\t()\n";
}
if ( outLabelUsed )
out << " and do_out () = ()\n";
out << "\tin do_start ()\n";
out << " end;\n";
}