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"; }
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"; }
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"; }
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"; } }
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"; }
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; }
/* 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; }
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); } } }