void RubyTabCodeGen::writeExec()

in ragel/src/ragel/rubytable.cpp [237:442]


void RubyTabCodeGen::writeExec()
{
	out << 
		"begin\n"
		"	_klen, _trans, _keys";

	if ( redFsm->anyRegCurStateRef() )
		out << ", _ps";
	if ( redFsm->anyConditions() ) 
		out << ", _widec";
	if ( redFsm->anyToStateActions() || redFsm->anyRegActions() 
			|| redFsm->anyFromStateActions() )
		out << ", _acts, _nacts";

	out << " = nil\n";

	out << 
		"	_goto_level = 0\n"
		"	_resume = 10\n"
		"	_eof_trans = 15\n"
		"	_again = 20\n"
		"	_test_eof = 30\n"
		"	_out = 40\n";

	out << 
		"	while true\n"
		"	_trigger_goto = false\n"
		"	if _goto_level <= 0\n";

	if ( !noEnd ) {
		out << 
			"	if " << P() << " == " << PE() << "\n"
			"		_goto_level = _test_eof\n"
			"		next\n"
			"	end\n";
	}

	if ( redFsm->errState != 0 ) {
		out << 
			"	if " << vCS() << " == " << redFsm->errState->id << "\n"
			"		_goto_level = _out\n"
			"		next\n"
			"	end\n";
	}

	/* The resume label. */
	out << 
		"	end\n"
		"	if _goto_level <= _resume\n";
	
	if ( redFsm->anyFromStateActions() ) {
		out << 
			"	_acts = " << FSA() << "[" << vCS() << "]\n"
			"	_nacts = " << A() << "[_acts]\n"
			"	_acts += 1\n"
			"	while _nacts > 0\n"
			"		_nacts -= 1\n"
			"		_acts += 1\n"
			"		case " << A() << "[_acts - 1]\n";
		FROM_STATE_ACTION_SWITCH();
		out <<
			"		end # from state action switch\n"
			"	end\n"
			"	if _trigger_goto\n"
			"		next\n"
			"	end\n";
	}

	if ( redFsm->anyConditions() )
		COND_TRANSLATE();

	LOCATE_TRANS();

	if ( useIndicies )
		out << "	_trans = " << I() << "[_trans]\n";

	if ( redFsm->anyEofTrans() ) {
		out << 
			"	end\n"
			"	if _goto_level <= _eof_trans\n";
	}

	if ( redFsm->anyRegCurStateRef() )
		out << "	_ps = " << vCS() << "\n";

	out << "	" << vCS() << " = " << TT() << "[_trans]\n";

	if ( redFsm->anyRegActions() ) {
		out << 
			"	if " << TA() << "[_trans] != 0\n"
			"		_acts = " << TA() << "[_trans]\n"
			"		_nacts = " << A() << "[_acts]\n"
			"		_acts += 1\n"
			"		while _nacts > 0\n"
			"			_nacts -= 1\n"
			"			_acts += 1\n"
			"			case " << A() << "[_acts - 1]\n";
		ACTION_SWITCH();
		out <<
			"			end # action switch\n"
			"		end\n"
			"	end\n"
			"	if _trigger_goto\n"
			"		next\n"
			"	end\n";
	}

	/* The again label. */
	out <<
		"	end\n"
		"	if _goto_level <= _again\n";

	if ( redFsm->anyToStateActions() ) {
		out <<
			"	_acts = " << TSA() << "["  << vCS() << "]\n"
			"	_nacts = " << A() << "[_acts]\n"
			"	_acts += 1\n"
			"	while _nacts > 0\n"
			"		_nacts -= 1\n"
			"		_acts += 1\n"
			"		case " << A() << "[_acts - 1]\n";
		TO_STATE_ACTION_SWITCH();
		out <<
			"		end # to state action switch\n"
			"	end\n"
			"	if _trigger_goto\n"
			"		next\n"
			"	end\n";
	}

	if ( redFsm->errState != 0 ) {
		out << 
			"	if " << vCS() << " == " << redFsm->errState->id << "\n"
			"		_goto_level = _out\n"
			"		next\n"
			"	end\n";
	}

	out << "	" << P() << " += 1\n";

	if ( !noEnd ) {
		out << 
			"	if " << P() << " != " << PE() << "\n"
			"		_goto_level = _resume\n"
			"		next\n"
			"	end\n";
	}
	else {
		out <<
			"	_goto_level = _resume\n"
			"	next\n";
	}

	/* The test_eof label. */
	out <<
		"	end\n"
		"	if _goto_level <= _test_eof\n";

	if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
		out << 
			"	if " << P() << " == " << vEOF() << "\n";

		if ( redFsm->anyEofTrans() ) {
			out <<
				"	if " << ET() << "[" << vCS() << "] > 0\n"
				"		_trans = " << ET() << "[" << vCS() << "] - 1;\n"
				"		_goto_level = _eof_trans\n"
				"		next;\n"
				"	end\n";
		}

		if ( redFsm->anyEofActions() ) {
			out << 
				"	__acts = " << EA() << "[" << vCS() << "]\n"
				"	__nacts = " << " " << A() << "[__acts]\n"
				"	__acts += 1\n"
				"	while __nacts > 0\n"
				"		__nacts -= 1\n"
				"		__acts += 1\n"
				"		case " << A() << "[__acts - 1]\n";
			EOF_ACTION_SWITCH() <<
				"		end # eof action switch\n"
				"	end\n"
				"	if _trigger_goto\n"
				"		next\n"
				"	end\n";
		}

		out << 
			"end\n";
	}

	out << 
		"	end\n"
		"	if _goto_level <= _out\n"
		"		break\n"
		"	end\n";

	/* The loop for next. */
	out << 
		"	end\n";

	/* Wrapping the execute block. */
	out << 
		"	end\n";
}