Пример #1
0
void CSharpGotoCodeGen::emitSingleSwitch( RedStateAp *state )
{
	/* Load up the singles. */
	int numSingles = state->outSingle.length();
	RedTransEl *data = state->outSingle.data;

	if ( numSingles == 1 ) {
		/* If there is a single single key then write it out as an if. */
		out << L"\tif ( " << GET_WIDE_KEY(state) << L" == " << 
				KEY(data[0].lowKey) << L" )\n\t\t"; 

		/* Virtual function for writing the target of the transition. */
		TRANS_GOTO(data[0].value, 0) << L"\n";
	}
	else if ( numSingles > 1 ) {
		/* Write out single keys in a switch if there is more than one. */
		out << L"\tswitch( " << GET_WIDE_KEY(state) << L" ) {\n";

		/* Write out the single indicies. */
		for ( int j = 0; j < numSingles; j++ ) {
			out << L"\t\tcase " << ALPHA_KEY(data[j].lowKey) << L": ";
			TRANS_GOTO(data[j].value, 0) << L"\n";
		}
		
		/* Emits a default case for D code. */
		SWITCH_DEFAULT();

		/* Close off the transition switch. */
		out << L"\t}\n";
	}
}
Пример #2
0
void CSharpFlatCodeGen::COND_TRANSLATE()
{
	out << 
		"	_widec = " << GET_KEY() << ";\n";

	out <<
		"   _keys = " << vCS() << "<<1;\n"
		"   _conds = " << CO() << "[" << vCS() << "];\n"
//		"	_keys = " << ARR_OFF( CK(), "(" + vCS() + "<<1)" ) << ";\n"
//		"	_conds = " << ARR_OFF( C(), CO() + "[" + vCS() + "]" ) << ";\n"
		"\n"
		"	_slen = " << CSP() << "[" << vCS() << "];\n"
		"	if (_slen > 0 && " << CK() << "[_keys] <=" 
			<< GET_WIDE_KEY() << " &&\n"
		"		" << GET_WIDE_KEY() << " <= " << CK() << "[_keys+1])\n"
		"		_cond = " << C() << "[_conds+" << GET_WIDE_KEY() << " - " << 
			CK() << "[_keys]];\n"
		"	else\n"
		"		_cond = 0;"
		"\n";
	/*  XXX This version of the code doesn't work because Mono is weird.  Works
	 *  fine in Microsoft's csc, even though the bug report filed claimed it
	 *  didn't.
		"	_slen = " << CSP() << "[" << vCS() << "];\n"
		"	_cond = _slen > 0 && " << CK() << "[_keys] <=" 
			<< GET_WIDE_KEY() << " &&\n"
		"		" << GET_WIDE_KEY() << " <= " << CK() << "[_keys+1] ?\n"
		"		" << C() << "[_conds+" << GET_WIDE_KEY() << " - " << CK() 
			<< "[_keys]] : 0;\n"
		"\n";
		*/
	out <<
		"	switch ( _cond ) {\n";
	for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) {
		GenCondSpace *condSpace = csi;
		out << "	case " << condSpace->condSpaceId + 1 << ": {\n";
		out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" <<
				KEY(condSpace->baseKey) << " + (" << GET_KEY() << 
				" - " << KEY(keyOps->minKey) << "));\n";

		for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
			out << TABS(2) << "if ( ";
			CONDITION( out, *csi );
			Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
			out << " ) _widec += " << condValOffset << ";\n";
		}

		out << "		}\n";
		out << "		break;\n";
	}

	SWITCH_DEFAULT();

	out <<
		"	}\n";
}
Пример #3
0
void CSharpTabCodeGen::LOCATE_TRANS()
{
    out <<
        "	_keys = " << KO() + "[" + vCS() + "]" << ";\n"
        "	_trans = " << CAST(transType) << IO() << "[" << vCS() << "];\n"
        "\n"
        "	_klen = " << SL() << "[" << vCS() << "];\n"
        "	if ( _klen > 0 ) {\n"
        "		" << signedKeysType << " _lower = _keys;\n"
        "		" << signedKeysType << " _mid;\n"
        "		" << signedKeysType << " _upper = " << CAST(signedKeysType) <<
        " (_keys + _klen - 1);\n"
        "		while (true) {\n"
        "			if ( _upper < _lower )\n"
        "				break;\n"
        "\n"
        "			_mid = " << CAST(signedKeysType) <<
        " (_lower + ((_upper-_lower) >> 1));\n"
        "			if ( " << GET_WIDE_KEY() << " < " << K() << "[_mid] )\n"
        "				_upper = " << CAST(signedKeysType) << " (_mid - 1);\n"
        "			else if ( " << GET_WIDE_KEY() << " > " << K() << "[_mid] )\n"
        "				_lower = " << CAST(signedKeysType) << " (_mid + 1);\n"
        "			else {\n"
        "				_trans += " << CAST(transType) << " (_mid - _keys);\n"
        "				goto _match;\n"
        "			}\n"
        "		}\n"
        "		_keys += " << CAST(keysType) << " _klen;\n"
        "		_trans += " << CAST(transType) << " _klen;\n"
        "	}\n"
        "\n"
        "	_klen = " << RL() << "[" << vCS() << "];\n"
        "	if ( _klen > 0 ) {\n"
        "		" << signedKeysType << " _lower = _keys;\n"
        "		" << signedKeysType << " _mid;\n"
        "		" << signedKeysType << " _upper = " << CAST(signedKeysType) <<
        " (_keys + (_klen<<1) - 2);\n"
        "		while (true) {\n"
        "			if ( _upper < _lower )\n"
        "				break;\n"
        "\n"
        "			_mid = " << CAST(signedKeysType) <<
        " (_lower + (((_upper-_lower) >> 1) & ~1));\n"
        "			if ( " << GET_WIDE_KEY() << " < " << K() << "[_mid] )\n"
        "				_upper = " << CAST(signedKeysType) << " (_mid - 2);\n"
        "			else if ( " << GET_WIDE_KEY() << " > " << K() << "[_mid+1] )\n"
        "				_lower = " << CAST(signedKeysType) << " (_mid + 2);\n"
        "			else {\n"
        "				_trans += " << CAST(transType) << "((_mid - _keys)>>1);\n"
        "				goto _match;\n"
        "			}\n"
        "		}\n"
        "		_trans += " << CAST(transType) << " _klen;\n"
        "	}\n"
        "\n";
}
Пример #4
0
void CSharpTabCodeGen::COND_TRANSLATE()
{
    out <<
        "	_widec = " << GET_KEY() << ";\n"
        "	_klen = " << CL() << "[" << vCS() << "];\n"
        "	_keys = " << CAST(keysType) << " ("<< CO() << "[" << vCS() << "]*2);\n"
        "	if ( _klen > 0 ) {\n"
        "		" << signedKeysType << " _lower = _keys;\n"
        "		" << signedKeysType << " _mid;\n"
        "		" << signedKeysType << " _upper = " << CAST(signedKeysType) <<
        " (_keys + (_klen<<1) - 2);\n"
        "		while (true) {\n"
        "			if ( _upper < _lower )\n"
        "				break;\n"
        "\n"
        "			_mid = " << CAST(signedKeysType) <<
        " (_lower + (((_upper-_lower) >> 1) & ~1));\n"
        "			if ( " << GET_WIDE_KEY() << " < " << CK() << "[_mid] )\n"
        "				_upper = " << CAST(signedKeysType) << " (_mid - 2);\n"
        "			else if ( " << GET_WIDE_KEY() << " > " << CK() << "[_mid+1] )\n"
        "				_lower = " << CAST(signedKeysType) << " (_mid + 2);\n"
        "			else {\n"
        "				switch ( " << C() << "[" << CO() << "[" << vCS() << "]"
        " + ((_mid - _keys)>>1)] ) {\n";

    for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) {
        GenCondSpace *condSpace = csi;
        out << "	case " << condSpace->condSpaceId << ": {\n";
        out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" <<
            KEY(condSpace->baseKey) << " + (" << GET_KEY() <<
            " - " << KEY(keyOps->minKey) << "));\n";

        for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
            out << TABS(2) << "if ( ";
            CONDITION( out, *csi );
            Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
            out << " ) _widec += " << condValOffset << ";\n";
        }

        out <<
            "		break;\n"
            "	}\n";
    }

    SWITCH_DEFAULT();

    out <<
        "				}\n"
        "				break;\n"
        "			}\n"
        "		}\n"
        "	}\n"
        "\n";
}
Пример #5
0
void FlatCodeGen::LOCATE_TRANS()
{
	out <<
		"	_keys = " << ARR_OFF( K(), "(" + vCS() + "<<1)" ) << ";\n"
		"	_inds = " << ARR_OFF( I(), IO() + "[" + vCS() + "]" ) << ";\n"
		"\n"
		"	_slen = " << SP() << "[" << vCS() << "];\n"
		"	_trans = _inds[ _slen > 0 && _keys[0] <=" << GET_WIDE_KEY() << " &&\n"
		"		" << GET_WIDE_KEY() << " <= _keys[1] ?\n"
		"		" << GET_WIDE_KEY() << " - _keys[0] : _slen ];\n"
		"\n";
}
Пример #6
0
void TabCodeGen::COND_TRANSLATE()
{
	out << 
		"	_widec = " << GET_KEY() << ";\n"
		"	_klen = " << CL() << "[" << vCS() << "];\n"
		"	_keys = " << ARR_OFF( CK(), "(" + CO() + "[" + vCS() + "]*2)" ) << ";\n"
		"	if ( _klen > 0 ) {\n"
		"		" << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_lower = _keys;\n"
		"		" << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_mid;\n"
		"		" << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_upper = _keys + (_klen<<1) - 2;\n"
		"		while (1) {\n"
		"			if ( _upper < _lower )\n"
		"				break;\n"
		"\n"
		"			_mid = _lower + (((_upper-_lower) >> 1) & ~1);\n"
		"			if ( " << GET_WIDE_KEY() << " < _mid[0] )\n"
		"				_upper = _mid - 2;\n"
		"			else if ( " << GET_WIDE_KEY() << " > _mid[1] )\n"
		"				_lower = _mid + 2;\n"
		"			else {\n"
		"				switch ( " << C() << "[" << CO() << "[" << vCS() << "]"
							" + ((_mid - _keys)>>1)] ) {\n";

	for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) {
		GenCondSpace *condSpace = csi;
		out << "	case " << condSpace->condSpaceId << ": {\n";
		out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" <<
				KEY(condSpace->baseKey) << " + (" << GET_KEY() << 
				" - " << KEY(keyOps->minKey) << "));\n";

		for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
			out << TABS(2) << "if ( ";
			CONDITION( out, *csi );
			Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
			out << " ) _widec += " << condValOffset << ";\n";
		}

		out << 
			"		break;\n"
			"	}\n";
	}

	SWITCH_DEFAULT();

	out << 
		"				}\n"
		"				break;\n"
		"			}\n"
		"		}\n"
		"	}\n"
		"\n";
}
Пример #7
0
void TabCodeGen::LOCATE_TRANS()
{
	out <<
		"	_keys = " << ARR_OFF( K(), KO() + "[" + vCS() + "]" ) << ";\n"
		"	_trans = " << IO() << "[" << vCS() << "];\n"
		"\n"
		"	_klen = " << SL() << "[" << vCS() << "];\n"
		"	if ( _klen > 0 ) {\n"
		"		" << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_lower = _keys;\n"
		"		" << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_mid;\n"
		"		" << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_upper = _keys + _klen - 1;\n"
		"		while (1) {\n"
		"			if ( _upper < _lower )\n"
		"				break;\n"
		"\n"
		"			_mid = _lower + ((_upper-_lower) >> 1);\n"
		"			if ( " << GET_WIDE_KEY() << " < *_mid )\n"
		"				_upper = _mid - 1;\n"
		"			else if ( " << GET_WIDE_KEY() << " > *_mid )\n"
		"				_lower = _mid + 1;\n"
		"			else {\n"
		"				_trans += " << CAST(UINT()) << "(_mid - _keys);\n"
		"				goto _match;\n"
		"			}\n"
		"		}\n"
		"		_keys += _klen;\n"
		"		_trans += _klen;\n"
		"	}\n"
		"\n"
		"	_klen = " << RL() << "[" << vCS() << "];\n"
		"	if ( _klen > 0 ) {\n"
		"		" << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_lower = _keys;\n"
		"		" << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_mid;\n"
		"		" << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_upper = _keys + (_klen<<1) - 2;\n"
		"		while (1) {\n"
		"			if ( _upper < _lower )\n"
		"				break;\n"
		"\n"
		"			_mid = _lower + (((_upper-_lower) >> 1) & ~1);\n"
		"			if ( " << GET_WIDE_KEY() << " < _mid[0] )\n"
		"				_upper = _mid - 2;\n"
		"			else if ( " << GET_WIDE_KEY() << " > _mid[1] )\n"
		"				_lower = _mid + 2;\n"
		"			else {\n"
		"				_trans += " << CAST(UINT()) << "((_mid - _keys)>>1);\n"
		"				goto _match;\n"
		"			}\n"
		"		}\n"
		"		_trans += _klen;\n"
		"	}\n"
		"\n";
}
Пример #8
0
void CSharpFlatCodeGen::LOCATE_TRANS()
{
	out <<
		"	_keys = " << vCS() << "<<1;\n"
		"	_inds = " << IO() << "[" << vCS() << "];\n"
		"\n"
		"	_slen = " << SP() << "[" << vCS() << "];\n"
		"	_trans = " << I() << "[_inds + (\n"
		"		_slen > 0 && " << K() << "[_keys] <=" << GET_WIDE_KEY() << " &&\n"
		"		" << GET_WIDE_KEY() << " <= " << K() <<"[_keys+1] ?\n"
		"		" << GET_WIDE_KEY() << " - " << K() << "[_keys] : _slen ) ];\n"
		"\n";
}
Пример #9
0
void OCamlTabCodeGen::LOCATE_TRANS()
{
	out <<
		"	state.keys <- " << AT( KO(), vCS() ) << ";\n"
		"	state.trans <- " << CAST(transType) << AT( IO(), vCS() ) << ";\n"
		"\n"
		"	let klen = " << AT( SL(), vCS() ) << " in\n"
		"	if klen > 0 then begin\n"
		"		let lower : " << signedKeysType << " ref = ref state.keys in\n"
		"		let upper : " << signedKeysType << " ref = ref " << CAST(signedKeysType) << 
			"(state.keys + klen - 1) in\n"
		"		while !upper >= !lower do\n"
		"			let mid = " << CAST(signedKeysType) << " (!lower + ((!upper - !lower) / 2)) in\n"
		"			if " << GET_WIDE_KEY() << " < " << AT( K(), "mid" ) << " then\n"
		"				upper := " << CAST(signedKeysType) << " (mid - 1)\n"
		"			else if " << GET_WIDE_KEY() << " > " << AT( K(), "mid" ) << " then\n"
		"				lower := " << CAST(signedKeysType) << " (mid + 1)\n"
		"			else begin\n"
		"				state.trans <- state.trans + " << CAST(transType) << " (mid - state.keys);\n"
		"				raise Goto_match;\n"
		"			end\n"
		"		done;\n"
		"		state.keys <- state.keys + " << CAST(keysType) << " klen;\n"
		"		state.trans <- state.trans + " << CAST(transType) << " klen;\n"
		"	end;\n"
		"\n"
		"	let klen = " << AT( RL(), vCS() ) << " in\n"
		"	if klen > 0 then begin\n"
		"		let lower : " << signedKeysType << " ref = ref state.keys in\n"
		"		let upper : " << signedKeysType << " ref = ref " << CAST(signedKeysType) <<
			"(state.keys + (klen * 2) - 2) in\n"
		"		while !upper >= !lower do\n"
		"			let mid = " << CAST(signedKeysType) << " (!lower + (((!upper - !lower) / 2) land (lnot 1))) in\n"
		"			if " << GET_WIDE_KEY() << " < " << AT( K() , "mid" ) << " then\n"
		"				upper := " << CAST(signedKeysType) << " (mid - 2)\n"
		"			else if " << GET_WIDE_KEY() << " > " << AT( K(), "mid+1" ) << " then\n"
		"				lower := " << CAST(signedKeysType) << " (mid + 2)\n"
		"			else begin\n"
		"				state.trans <- state.trans + " << CAST(transType) << "((mid - state.keys) / 2);\n"
		"				raise Goto_match;\n"
		"		  end\n"
		"		done;\n"
		"		state.trans <- state.trans + " << CAST(transType) << " klen;\n"
		"	end;\n"
		"\n";
}
Пример #10
0
void FlatCodeGen::COND_TRANSLATE()
{
	out << 
		"	_widec = " << GET_KEY() << ";\n";

	out <<
		"	_keys = " << ARR_OFF( CK(), "(" + vCS() + "<<1)" ) << ";\n"
		"	_conds = " << ARR_OFF( C(), CO() + "[" + vCS() + "]" ) << ";\n"
		"\n"
		"	_slen = " << CSP() << "[" << vCS() << "];\n"
		"	_cond = _slen > 0 && _keys[0] <=" << GET_WIDE_KEY() << " &&\n"
		"		" << GET_WIDE_KEY() << " <= _keys[1] ?\n"
		"		_conds[" << GET_WIDE_KEY() << " - _keys[0]] : 0;\n"
		"\n";

	out <<
		"	switch ( _cond ) {\n";
	for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) {
		GenCondSpace *condSpace = csi;
		out << "	case " << condSpace->condSpaceId + 1 << ": {\n";
		out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" <<
				KEY(condSpace->baseKey) << " + (" << GET_KEY() << 
				" - " << KEY(keyOps->minKey) << "));\n";

		for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
			out << TABS(2) << "if ( ";
			CONDITION( out, *csi );
			Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
			out << " ) _widec += " << condValOffset << ";\n";
		}

		out << "		}\n";
		out << "		break;\n";
	}

	SWITCH_DEFAULT();

	out <<
		"	}\n";
}
Пример #11
0
void CSharpGotoCodeGen::emitRangeBSearch( RedStateAp *state, int level, int low, int high )
{
	/* Get the mid position, staying on the lower end of the range. */
	int mid = (low + high) >> 1;
	RedTransEl *data = state->outRange.data;

	/* Determine if we need to look higher or lower. */
	bool anyLower = mid > low;
	bool anyHigher = mid < high;

	/* Determine if the keys at mid are the limits of the alphabet. */
	bool limitLow = data[mid].lowKey == keyOps->minKey;
	bool limitHigh = data[mid].highKey == keyOps->maxKey;

	if ( anyLower && anyHigher ) {
		/* Can go lower and higher than mid. */
		out << TABS(level) << L"if ( " << GET_WIDE_KEY(state) << L" < " << 
				KEY(data[mid].lowKey) << L" ) {\n";
		emitRangeBSearch( state, level+1, low, mid-1 );
		out << TABS(level) << L"} else if ( " << GET_WIDE_KEY(state) << L" > " << 
				KEY(data[mid].highKey) << L" ) {\n";
		emitRangeBSearch( state, level+1, mid+1, high );
		out << TABS(level) << L"} else\n";
		TRANS_GOTO(data[mid].value, level+1) << L"\n";
	}
	else if ( anyLower && !anyHigher ) {
		/* Can go lower than mid but not higher. */
		out << TABS(level) << L"if ( " << GET_WIDE_KEY(state) << L" < " << 
				KEY(data[mid].lowKey) << L" ) {\n";
		emitRangeBSearch( state, level+1, low, mid-1 );

		/* if the higher is the highest in the alphabet then there is no
		 * sense testing it. */
		if ( limitHigh ) {
			out << TABS(level) << L"} else\n";
			TRANS_GOTO(data[mid].value, level+1) << L"\n";
		}
		else {
			out << TABS(level) << L"} else if ( " << GET_WIDE_KEY(state) << L" <= " << 
					KEY(data[mid].highKey) << L" )\n";
			TRANS_GOTO(data[mid].value, level+1) << L"\n";
		}
	}
	else if ( !anyLower && anyHigher ) {
		/* Can go higher than mid but not lower. */
		out << TABS(level) << L"if ( " << GET_WIDE_KEY(state) << L" > " << 
				KEY(data[mid].highKey) << L" ) {\n";
		emitRangeBSearch( state, level+1, mid+1, high );

		/* If the lower end is the lowest in the alphabet then there is no
		 * sense testing it. */
		if ( limitLow ) {
			out << TABS(level) << L"} else\n";
			TRANS_GOTO(data[mid].value, level+1) << L"\n";
		}
		else {
			out << TABS(level) << L"} else if ( " << GET_WIDE_KEY(state) << L" >= " << 
					KEY(data[mid].lowKey) << L" )\n";
			TRANS_GOTO(data[mid].value, level+1) << L"\n";
		}
	}
	else {
		/* Cannot go higher or lower than mid. It's mid or bust. What
		 * tests to do depends on limits of alphabet. */
		if ( !limitLow && !limitHigh ) {
			out << TABS(level) << L"if ( " << KEY(data[mid].lowKey) << L" <= " << 
					GET_WIDE_KEY(state) << L" && " << GET_WIDE_KEY(state) << L" <= " << 
					KEY(data[mid].highKey) << L" )\n";
			TRANS_GOTO(data[mid].value, level+1) << L"\n";
		}
		else if ( limitLow && !limitHigh ) {
			out << TABS(level) << L"if ( " << GET_WIDE_KEY(state) << L" <= " << 
					KEY(data[mid].highKey) << L" )\n";
			TRANS_GOTO(data[mid].value, level+1) << L"\n";
		}
		else if ( !limitLow && limitHigh ) {
			out << TABS(level) << L"if ( " << KEY(data[mid].lowKey) << L" <= " << 
					GET_WIDE_KEY(state) << L" )\n";
			TRANS_GOTO(data[mid].value, level+1) << L"\n";
		}
		else {
			/* Both high and low are at the limit. No tests to do. */
			TRANS_GOTO(data[mid].value, level+1) << L"\n";
		}
	}
}