예제 #1
0
파일: csflat.cpp 프로젝트: Mirocow/balancer
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";
}
예제 #2
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";
}
예제 #3
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";
}
예제 #4
0
void CSharpGotoCodeGen::COND_TRANSLATE( GenStateCond *stateCond, int level )
{
	GenCondSpace *condSpace = stateCond->condSpace;
	out << TABS(level) << L"_widec = " << CAST(WIDE_ALPH_TYPE()) << L"(" <<
			KEY(condSpace->baseKey) << L" + (" << GET_KEY() << 
			L" - " << KEY(keyOps->minKey) << L"));\n";

	for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
		out << TABS(level) << L"if ( ";
		CONDITION( out, *csi );
		Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
		out << L" ) _widec += " << condValOffset << L";\n";
	}
}
예제 #5
0
파일: cdflat.cpp 프로젝트: Mirocow/balancer
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";
}
예제 #6
0
파일: pr.c 프로젝트: 00001/plan9port
int
findopt(int argc, char *argv[])
{
	char **eargv = argv;
	int eargc = 0, c;

	while(--argc > 0) {
		switch(c = **++argv) {
		case '-':
			if((c = *++*argv) == '\0')
				break;
		case '+':
			do {
				if(isdigit(c)) {
					--*argv;
					Ncols = atoix(argv);
				} else
				switch(c = TOLOWER(c)) {
				case '+':
					if((Fpage = atoix(argv)) < 1)
						Fpage = 1;
					continue;
				case 'd':
					Dblspace = 2;
					continue;
				case 'e':
					TABS(Etabn, Etabc);
					continue;
				case 'f':
					Formfeed++;
					continue;
				case 'h':
					if(--argc > 0)
						Head = argv[1];
					continue;
				case 'i':
					TABS(Itabn, Itabc);
					continue;
				case 'l':
					Len = atoix(argv);
					continue;
				case 'a':
				case 'm':
					Multi = c;
					continue;
				case 'o':
					Offset = atoix(argv);
					continue;
				case 's':
					if((Sepc = (*argv)[1]) != '\0')
						++*argv;
					else
						Sepc = '\t';
					continue;
				case 't':
					Margin = 0;
					continue;
				case 'w':
					Linew = atoix(argv);
					continue;
				case 'n':
					Lnumb++;
					if((Numw = intopt(argv, &Nsepc)) <= 0)
						Numw = NUMW;
				case 'b':
					Balance = 1;
					continue;
				case 'p':
					Padodd = 1;
					continue;
				default:
					die("bad option");
				}
			} while((c = *++*argv) != '\0');
			if(Head == argv[1])
				argv++;
			continue;
		}
		*eargv++ = *argv;
		eargc++;
	}
	if(Len == 0)
		Len = LENGTH;
	if(Len <= Margin)
		Margin = 0;
	Plength = Len - Margin/2;
	if(Multi == 'm')
		Ncols = eargc;
	switch(Ncols) {
	case 0:
		Ncols = 1;
	case 1:
		break;
	default:
		if(Etabn == 0)		/* respect explicit tab specification */
			Etabn = DEFTAB;
	}
	if(Linew == 0)
		Linew = Ncols != 1 && Sepc == 0? LINEW: 512;
	if(Lnumb)
		Linew -= Multi == 'm'? Numw: Numw*Ncols;
	if((Colw = (Linew - Ncols + 1)/Ncols) < 1)
		die("width too small");
	if(Ncols != 1 && Multi == 0) {
		ulong buflen = ((ulong)(Plength/Dblspace + 1))*(Linew+1)*sizeof(char);
		Buffer = getspace(buflen*sizeof(*Buffer));
		Bufend = &Buffer[buflen];
		Colpts = getspace((Ncols+1)*sizeof(*Colpts));
	}
	return eargc;
}
예제 #7
0
/* Emit the goto to take for a given transition. */
std::wostream &CSharpGotoCodeGen::TRANS_GOTO( RedTransAp *trans, int level )
{
	out << TABS(level) << L"goto tr" << trans->id << L";";
	return out;
}
예제 #8
0
void CSharpGotoCodeGen::emitCondBSearch( 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;
	GenStateCond **data = state->stateCondVect.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_KEY() << L" < " << 
				KEY(data[mid]->lowKey) << L" ) {\n";
		emitCondBSearch( state, level+1, low, mid-1 );
		out << TABS(level) << L"} else if ( " << GET_KEY() << L" > " << 
				KEY(data[mid]->highKey) << L" ) {\n";
		emitCondBSearch( state, level+1, mid+1, high );
		out << TABS(level) << L"} else {\n";
		COND_TRANSLATE(data[mid], level+1);
		out << TABS(level) << L"}\n";
	}
	else if ( anyLower && !anyHigher ) {
		/* Can go lower than mid but not higher. */
		out << TABS(level) << L"if ( " << GET_KEY() << L" < " << 
				KEY(data[mid]->lowKey) << L" ) {\n";
		emitCondBSearch( 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";
			COND_TRANSLATE(data[mid], level+1);
			out << TABS(level) << L"}\n";
		}
		else {
			out << TABS(level) << L"} else if ( " << GET_KEY() << L" <= " << 
					KEY(data[mid]->highKey) << L" ) {\n";
			COND_TRANSLATE(data[mid], level+1);
			out << TABS(level) << L"}\n";
		}
	}
	else if ( !anyLower && anyHigher ) {
		/* Can go higher than mid but not lower. */
		out << TABS(level) << L"if ( " << GET_KEY() << L" > " << 
				KEY(data[mid]->highKey) << L" ) {\n";
		emitCondBSearch( 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";
			COND_TRANSLATE(data[mid], level+1);
			out << TABS(level) << L"}\n";
		}
		else {
			out << TABS(level) << L"} else if ( " << GET_KEY() << L" >= " << 
					KEY(data[mid]->lowKey) << L" ) {\n";
			COND_TRANSLATE(data[mid], level+1);
			out << TABS(level) << 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_KEY() << L" && " << GET_KEY() << L" <= " << 
					KEY(data[mid]->highKey) << L" ) {\n";
			COND_TRANSLATE(data[mid], level+1);
			out << TABS(level) << L"}\n";
		}
		else if ( limitLow && !limitHigh ) {
			out << TABS(level) << L"if ( " << GET_KEY() << L" <= " << 
					KEY(data[mid]->highKey) << L" ) {\n";
			COND_TRANSLATE(data[mid], level+1);
			out << TABS(level) << L"}\n";
		}
		else if ( !limitLow && limitHigh ) {
			out << TABS(level) << L"if ( " << KEY(data[mid]->lowKey) << L" <= " << 
					GET_KEY() << L" )\n {";
			COND_TRANSLATE(data[mid], level+1);
			out << TABS(level) << L"}\n";
		}
		else {
			/* Both high and low are at the limit. No tests to do. */
			COND_TRANSLATE(data[mid], level);
		}
	}
}