flat.cc (ragel-7.0.0.10) | : | flat.cc (ragel-7.0.0.11) | ||
---|---|---|---|---|
/* | /* | |||
* Copyright 2004-2014 Adrian Thurston <thurston@colm.net> | * Copyright 2004-2018 Adrian Thurston <thurston@colm.net> | |||
* | * | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | * Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to | * of this software and associated documentation files (the "Software"), to | |||
* deal in the Software without restriction, including without limitation the | * deal in the Software without restriction, including without limitation the | |||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |||
* sell copies of the Software, and to permit persons to whom the Software is | * sell copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | * furnished to do so, subject to the following conditions: | |||
* | * | |||
* The above copyright notice and this permission notice shall be included in al l | * The above copyright notice and this permission notice shall be included in al l | |||
* copies or substantial portions of the Software. | * copies or substantial portions of the Software. | |||
skipping to change at line 28 | skipping to change at line 28 | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
* SOFTWARE. | * SOFTWARE. | |||
*/ | */ | |||
#include "ragel.h" | #include "ragel.h" | |||
#include "flat.h" | #include "flat.h" | |||
#include "redfsm.h" | #include "redfsm.h" | |||
#include "gendata.h" | #include "gendata.h" | |||
Flat::Flat( const CodeGenArgs &args ) | void Flat::genAnalysis() | |||
: | { | |||
CodeGen( args ), | redFsm->sortByStateId(); | |||
actions( "actions", *this ), | ||||
keys( "trans_keys", *this ), | /* Choose default transitions and the single transition. */ | |||
charClass( "char_class", *this ), | redFsm->chooseDefaultSpan(); | |||
flatIndexOffset( "index_offsets", *this ), | ||||
indicies( "indicies", *this ), | /* Do flat expand. */ | |||
indexDefaults( "index_defaults", *this ), | redFsm->makeFlatClass(); | |||
transCondSpaces( "trans_cond_spaces", *this ), | ||||
transOffsets( "trans_offsets", *this ), | /* If any errors have occured in the input file then don't write anything | |||
condTargs( "cond_targs", *this ), | . */ | |||
condActions( "cond_actions", *this ), | if ( red->id->errorCount > 0 ) | |||
toStateActions( "to_state_actions", *this ), | return; | |||
fromStateActions( "from_state_actions", *this ), | ||||
eofActions( "eof_actions", *this ), | /* Anlayze Machine will find the final action reference counts, among oth | |||
eofTrans( "eof_trans", *this ), | er | |||
nfaTargs( "nfa_targs", *this ), | * things. We will use these in reporting the usage of fsm directives in | |||
nfaOffsets( "nfa_offsets", *this ), | * action code. */ | |||
nfaPushActions( "nfa_push_actions", *this ), | red->analyzeMachine(); | |||
nfaPopTrans( "nfa_pop_trans", *this ) | ||||
{} | setKeyType(); | |||
/* Run the analysis pass over the table data. */ | ||||
setTableState( TableArray::AnalyzePass ); | ||||
tableDataPass(); | ||||
/* Switch the tables over to the code gen mode. */ | ||||
setTableState( TableArray::GeneratePass ); | ||||
} | ||||
void Flat::tableDataPass() | ||||
{ | ||||
if ( type == Flat::Loop ) { | ||||
if ( redFsm->anyActions() ) | ||||
taActions(); | ||||
} | ||||
taKeys(); | ||||
taCharClass(); | ||||
taFlatIndexOffset(); | ||||
taIndicies(); | ||||
taIndexDefaults(); | ||||
taTransCondSpaces(); | ||||
if ( red->condSpaceList.length() > 0 ) | ||||
taTransOffsets(); | ||||
taCondTargs(); | ||||
taCondActions(); | ||||
taToStateActions(); | ||||
taFromStateActions(); | ||||
taEofConds(); | ||||
taEofActions(); | ||||
taEofTrans(); | ||||
taNfaTargs(); | ||||
taNfaOffsets(); | ||||
taNfaPushActions(); | ||||
taNfaPopTrans(); | ||||
} | ||||
void Flat::writeData() | ||||
{ | ||||
if ( type == Flat::Loop ) { | ||||
/* If there are any transtion functions then output the array. If | ||||
there | ||||
* are none, don't bother emitting an empty array that won't be u | ||||
sed. */ | ||||
if ( redFsm->anyActions() ) | ||||
taActions(); | ||||
} | ||||
taKeys(); | ||||
taCharClass(); | ||||
taFlatIndexOffset(); | ||||
taIndicies(); | ||||
taIndexDefaults(); | ||||
taTransCondSpaces(); | ||||
if ( red->condSpaceList.length() > 0 ) | ||||
taTransOffsets(); | ||||
taCondTargs(); | ||||
taCondActions(); | ||||
if ( redFsm->anyToStateActions() ) | ||||
taToStateActions(); | ||||
if ( redFsm->anyFromStateActions() ) | ||||
taFromStateActions(); | ||||
taEofConds(); | ||||
if ( redFsm->anyEofActions() ) | ||||
taEofActions(); | ||||
if ( redFsm->anyEofTrans() ) | ||||
taEofTrans(); | ||||
taNfaTargs(); | ||||
taNfaOffsets(); | ||||
taNfaPushActions(); | ||||
taNfaPopTrans(); | ||||
STATE_IDS(); | ||||
} | ||||
void Flat::setKeyType() | void Flat::setKeyType() | |||
{ | { | |||
keys.setType( ALPH_TYPE(), alphType->size, alphType->isChar ); | transKeys.setType( ALPH_TYPE(), alphType->size, alphType->isChar ); | |||
keys.isSigned = keyOps->isSigned; | transKeys.isSigned = keyOps->isSigned; | |||
} | } | |||
void Flat::setTableState( TableArray::State state ) | void Flat::setTableState( TableArray::State state ) | |||
{ | { | |||
for ( ArrayVector::Iter i = arrayVector; i.lte(); i++ ) { | for ( ArrayVector::Iter i = arrayVector; i.lte(); i++ ) { | |||
TableArray *tableArray = *i; | TableArray *tableArray = *i; | |||
tableArray->setState( state ); | tableArray->setState( state ); | |||
} | } | |||
} | } | |||
skipping to change at line 132 | skipping to change at line 213 | |||
eofActions.start(); | eofActions.start(); | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | |||
/* Write any eof action. */ | /* Write any eof action. */ | |||
EOF_ACTION( st ); | EOF_ACTION( st ); | |||
} | } | |||
eofActions.finish(); | eofActions.finish(); | |||
} | } | |||
void Flat::taEofConds() | ||||
{ | ||||
/* | ||||
* EOF Cond Spaces | ||||
*/ | ||||
eofCondSpaces.start(); | ||||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | ||||
if ( st->outCondSpace != 0 ) | ||||
transCondSpaces.value( st->outCondSpace->condSpaceId ); | ||||
else | ||||
transCondSpaces.value( -1 ); | ||||
} | ||||
eofCondSpaces.finish(); | ||||
/* | ||||
* EOF Cond Key Indixes | ||||
*/ | ||||
eofCondKeyOffs.start(); | ||||
int curOffset = 0; | ||||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | ||||
long off = 0; | ||||
if ( st->outCondSpace != 0 ) { | ||||
off = curOffset; | ||||
curOffset += st->outCondKeys.length(); | ||||
} | ||||
eofCondKeyOffs.value( off ); | ||||
} | ||||
eofCondKeyOffs.finish(); | ||||
/* | ||||
* EOF Cond Key Lengths. | ||||
*/ | ||||
eofCondKeyLens.start(); | ||||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | ||||
long len = 0; | ||||
if ( st->outCondSpace != 0 ) | ||||
len = st->outCondKeys.length(); | ||||
eofCondKeyLens.value( len ); | ||||
} | ||||
eofCondKeyLens.finish(); | ||||
/* | ||||
* EOF Cond Keys | ||||
*/ | ||||
eofCondKeys.start(); | ||||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | ||||
if ( st->outCondSpace != 0 ) { | ||||
for ( int c = 0; c < st->outCondKeys.length(); c++ ) { | ||||
CondKey key = st->outCondKeys[c]; | ||||
eofCondKeys.value( key.getVal() ); | ||||
} | ||||
} | ||||
} | ||||
eofCondKeys.finish(); | ||||
} | ||||
void Flat::taEofTrans() | void Flat::taEofTrans() | |||
{ | { | |||
/* Transitions must be written ordered by their id. */ | /* Transitions must be written ordered by their id. */ | |||
RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; | RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; | |||
for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) | for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) | |||
transPtrs[trans->id] = trans; | transPtrs[trans->id] = trans; | |||
long *transPos = new long[redFsm->transSet.length()]; | long *transPos = new long[redFsm->transSet.length()]; | |||
for ( int t = 0; t < redFsm->transSet.length(); t++ ) { | for ( int t = 0; t < redFsm->transSet.length(); t++ ) { | |||
/* Save the position. Needed for eofTargs. */ | /* Save the position. Needed for eofTargs. */ | |||
skipping to change at line 165 | skipping to change at line 308 | |||
} | } | |||
eofTrans.finish(); | eofTrans.finish(); | |||
delete[] transPtrs; | delete[] transPtrs; | |||
delete[] transPos; | delete[] transPos; | |||
} | } | |||
void Flat::taKeys() | void Flat::taKeys() | |||
{ | { | |||
keys.start(); | transKeys.start(); | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | |||
if ( st->transList ) { | if ( st->transList ) { | |||
/* Emit just low key and high key. */ | /* Emit just low key and high key. */ | |||
keys.value( st->low ); | transKeys.value( st->low ); | |||
keys.value( st->high ); | transKeys.value( st->high ); | |||
} | } | |||
else { | else { | |||
/* Emit an impossible range so the driver fails the looku p. */ | /* Emit an impossible range so the driver fails the looku p. */ | |||
keys.value( 1 ); | transKeys.value( 1 ); | |||
keys.value( 0 ); | transKeys.value( 0 ); | |||
} | } | |||
} | } | |||
keys.finish(); | transKeys.finish(); | |||
} | } | |||
void Flat::taIndicies() | void Flat::taIndicies() | |||
{ | { | |||
indicies.start(); | indicies.start(); | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | |||
if ( st->transList != 0 ) { | if ( st->transList != 0 ) { | |||
long long span = st->high - st->low + 1; | long long span = st->high - st->low + 1; | |||
for ( long long pos = 0; pos < span; pos++ ) | for ( long long pos = 0; pos < span; pos++ ) | |||
skipping to change at line 422 | skipping to change at line 565 | |||
nfaOffsets.value( 0 ); | nfaOffsets.value( 0 ); | |||
} | } | |||
else { | else { | |||
nfaOffsets.value( offset ); | nfaOffsets.value( offset ); | |||
offset += 1 + st->nfaTargs->length(); | offset += 1 + st->nfaTargs->length(); | |||
} | } | |||
} | } | |||
nfaOffsets.finish(); | nfaOffsets.finish(); | |||
} | } | |||
void Flat::NFA_PUSH() | ||||
{ | ||||
if ( redFsm->anyNfaStates() ) { | ||||
out << | ||||
" if ( " << ARR_REF( nfaOffsets ) << "[" << vCS() < | ||||
< "] ) {\n" | ||||
" int alt = 0; \n" | ||||
" int new_recs = " << ARR_REF( nfaTargs ) < | ||||
< "[" << CAST("int") << | ||||
ARR_REF( nfaOffsets ) << "[" << v | ||||
CS() << "]];\n"; | ||||
if ( red->nfaPrePushExpr != 0 ) { | ||||
out << OPEN_HOST_BLOCK( red->nfaPrePushExpr ); | ||||
INLINE_LIST( out, red->nfaPrePushExpr->inlineList, 0, fal | ||||
se, false ); | ||||
out << CLOSE_HOST_BLOCK(); | ||||
} | ||||
out << | ||||
" while ( alt < new_recs ) { \n"; | ||||
out << | ||||
" nfa_bp[nfa_len].state = " << ARR_ | ||||
REF( nfaTargs ) << "[" << CAST("int") << | ||||
ARR_REF( nfaOffsets ) << | ||||
"[" << vCS() << "] + 1 + alt];\n" | ||||
" nfa_bp[nfa_len].p = " << P() << " | ||||
;\n"; | ||||
if ( redFsm->bAnyNfaPops ) { | ||||
out << | ||||
" nfa_bp[nfa_len].popTrans | ||||
= " << CAST("long") << | ||||
ARR_REF( nfaOffse | ||||
ts ) << "[" << vCS() << "] + 1 + alt;\n" | ||||
"\n" | ||||
; | ||||
} | ||||
if ( redFsm->bAnyNfaPushes ) { | ||||
out << | ||||
" switch ( " << ARR_REF( nf | ||||
aPushActions ) << "[" << CAST("int") << | ||||
ARR_REF( nfaOffse | ||||
ts ) << "[" << vCS() << "] + 1 + alt] ) {\n"; | ||||
/* Loop the actions. */ | ||||
for ( GenActionTableMap::Iter redAct = redFsm->actionMap; | ||||
redAct.lte(); redAct++ ) | ||||
{ | ||||
if ( redAct->numNfaPushRefs > 0 ) { | ||||
/* Write the entry label. */ | ||||
out << "\t " << CASE( STR( redAct->actLis | ||||
tId+1 ) ) << " {\n"; | ||||
/* Write each action in the list of actio | ||||
n items. */ | ||||
for ( GenActionTable::Iter item = redAct- | ||||
>key; item.lte(); item++ ) | ||||
ACTION( out, item->value, IlOpts( | ||||
0, false, false ) ); | ||||
out << "\n\t" << CEND() << "}\n"; | ||||
} | ||||
} | ||||
out << | ||||
" }\n"; | ||||
} | ||||
out << | ||||
" nfa_len += 1;\n" | ||||
" alt += 1;\n" | ||||
" }\n" | ||||
" }\n" | ||||
; | ||||
} | ||||
} | ||||
void Flat::NFA_POP() | ||||
{ | ||||
if ( redFsm->anyNfaStates() ) { | ||||
out << | ||||
" if ( nfa_len > 0 ) {\n" | ||||
" nfa_count += 1;\n" | ||||
" nfa_len -= 1;\n" | ||||
" " << P() << " = nfa_bp[nfa_len].p;\n" | ||||
; | ||||
if ( redFsm->bAnyNfaPops ) { | ||||
NFA_FROM_STATE_ACTION_EXEC(); | ||||
out << | ||||
" int _pop_test = 1;\n" | ||||
" switch ( " << ARR_REF( nfaPopTran | ||||
s ) << | ||||
"[nfa_bp[nfa_len].popTran | ||||
s] ) {\n"; | ||||
/* Loop the actions. */ | ||||
for ( GenActionTableMap::Iter redAct = redFsm->actionMap; | ||||
redAct.lte(); redAct++ ) | ||||
{ | ||||
if ( redAct->numNfaPopTestRefs > 0 ) { | ||||
/* Write the entry label. */ | ||||
out << "\t " << CASE( STR( redAct->actLis | ||||
tId+1 ) ) << " {\n"; | ||||
/* Write each action in the list of actio | ||||
n items. */ | ||||
for ( GenActionTable::Iter item = redAct- | ||||
>key; item.lte(); item++ ) | ||||
NFA_CONDITION( out, item->value, | ||||
item.last() ); | ||||
out << CEND() << "\n}\n"; | ||||
} | ||||
} | ||||
out << | ||||
" }\n"; | ||||
out << | ||||
" if ( _pop_test ) {\n" | ||||
" " << vCS() << " = nfa_bp[ | ||||
nfa_len].state;\n"; | ||||
if ( red->nfaPostPopExpr != 0 ) { | ||||
out << OPEN_HOST_BLOCK( red->nfaPostPopExpr ); | ||||
INLINE_LIST( out, red->nfaPostPopExpr->inlineList | ||||
, 0, false, false ); | ||||
out << CLOSE_HOST_BLOCK(); | ||||
} | ||||
out << | ||||
" goto _resume;\n" | ||||
" }\n"; | ||||
if ( red->nfaPostPopExpr != 0 ) { | ||||
out << | ||||
" else {\n" | ||||
" " << OPEN_HOST_BLOCK( red | ||||
->nfaPostPopExpr ); | ||||
INLINE_LIST( out, red->nfaPostPopExpr->inlineList | ||||
, 0, false, false ); | ||||
out << CLOSE_HOST_BLOCK() << "\n" | ||||
" }\n"; | ||||
} | ||||
} | ||||
else { | ||||
out << | ||||
" " << vCS() << " = nfa_bp[nfa_len] | ||||
.state;\n"; | ||||
if ( red->nfaPostPopExpr != 0 ) { | ||||
out << OPEN_HOST_BLOCK( red->nfaPostPopExpr ); | ||||
INLINE_LIST( out, red->nfaPostPopExpr->inlineList | ||||
, 0, false, false ); | ||||
out << CLOSE_HOST_BLOCK(); | ||||
} | ||||
out << | ||||
" goto _resume;\n"; | ||||
} | ||||
out << | ||||
" goto _out;\n" | ||||
" }\n"; | ||||
} | ||||
} | ||||
void Flat::LOCATE_TRANS() | ||||
{ | ||||
if ( redFsm->classMap == 0 ) { | ||||
out << | ||||
" _trans = " << CAST("int") << ARR_REF( indexDefaul | ||||
ts ) << "[" << vCS() << "]" << ";\n"; | ||||
} | ||||
else { | ||||
long lowKey = redFsm->lowKey.getVal(); | ||||
long highKey = redFsm->highKey.getVal(); | ||||
bool limitLow = keyOps->eq( lowKey, keyOps->minKey ); | ||||
bool limitHigh = keyOps->eq( highKey, keyOps->maxKey ); | ||||
out << | ||||
" _keys = " << OFFSET( ARR_REF( keys ), "(" + vCS() | ||||
+ "<<1)" ) << ";\n" | ||||
" _inds = " << OFFSET( ARR_REF( indicies ), | ||||
ARR_REF( flatIndexOffset ) + "[" + vCS() | ||||
+ "]" ) << ";\n" | ||||
"\n"; | ||||
if ( !limitLow || !limitHigh ) { | ||||
out << " if ( "; | ||||
if ( !limitHigh ) | ||||
out << GET_KEY() << " <= " << highKey; | ||||
if ( !limitHigh && !limitLow ) | ||||
out << " && "; | ||||
if ( !limitLow ) | ||||
out << GET_KEY() << " >= " << lowKey; | ||||
out << " )\n {\n"; | ||||
} | ||||
out << | ||||
" int _ic = " << CAST("int") << ARR_REF( charClass | ||||
) << "[" << CAST("int") << GET_KEY() << | ||||
" - " << lowKey << "];\n" | ||||
" if ( _ic <= " << CAST("int") << DEREF( AR | ||||
R_REF( keys ), "_keys+1" ) << " && " << | ||||
"_ic >= " << CAST("int") << DEREF | ||||
( ARR_REF( keys ), "_keys" ) << " )\n" | ||||
" _trans = " << CAST("int") << DERE | ||||
F( ARR_REF( indicies ), | ||||
"_inds + " + CAST | ||||
("int") + "( _ic - " + CAST("int") + | ||||
DEREF( ARR_REF( k | ||||
eys ), "_keys" ) + " ) " ) << "; \n" | ||||
" else\n" | ||||
" _trans = " << CAST("int") << ARR_ | ||||
REF( indexDefaults ) << | ||||
"[" << vCS() << " | ||||
]" << ";\n"; | ||||
if ( !limitLow || !limitHigh ) { | ||||
out << | ||||
" }\n" | ||||
" else {\n" | ||||
" _trans = " << CAST("int") << ARR_ | ||||
REF( indexDefaults ) << "[" << vCS() << "]" << ";\n" | ||||
" }\n" | ||||
"\n"; | ||||
} | ||||
} | ||||
if ( red->condSpaceList.length() > 0 ) { | ||||
out << | ||||
" _cond = " << CAST( UINT() ) << ARR_REF( transOffs | ||||
ets ) << "[_trans];\n" | ||||
"\n"; | ||||
out << | ||||
" _cpc = 0;\n"; | ||||
out << | ||||
" switch ( " << ARR_REF( transCondSpaces ) << "[_tr | ||||
ans] ) {\n" | ||||
"\n"; | ||||
for ( CondSpaceList::Iter csi = red->condSpaceList; csi.lte(); cs | ||||
i++ ) { | ||||
GenCondSpace *condSpace = csi; | ||||
if ( condSpace->numTransRefs > 0 ) { | ||||
out << " " << CASE( STR(condSpace->condSpa | ||||
ceId) ) << " {\n"; | ||||
for ( GenCondSet::Iter csi = condSpace->condSet; | ||||
csi.lte(); csi++ ) { | ||||
out << TABS(2) << "if ( "; | ||||
CONDITION( out, *csi ); | ||||
Size condValOffset = (1 << csi.pos()); | ||||
out << " ) _cpc += " << condValOffset << | ||||
";\n"; | ||||
} | ||||
out << | ||||
" " << CEND() << "}\n"; | ||||
} | ||||
} | ||||
out << | ||||
" }\n" | ||||
" _cond += " << CAST( UINT() ) << "_cpc;\n"; | ||||
} | ||||
out << | ||||
" goto _match_cond;\n" | ||||
; | ||||
} | ||||
void Flat::GOTO( ostream &ret, int gotoDest, bool inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK() << vCS() << " = " << gotoDest << "; "; | ||||
if ( inFinish && !noEnd ) | ||||
EOF_CHECK( ret ); | ||||
ret << "goto _again;"; | ||||
ret << CLOSE_GEN_BLOCK(); | ||||
} | ||||
void Flat::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK() << vCS() << " = " << OPEN_HOST_EXPR(); | ||||
INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | ||||
ret << CLOSE_HOST_EXPR() << ";"; | ||||
if ( inFinish && !noEnd ) | ||||
EOF_CHECK( ret ); | ||||
ret << " goto _again;"; | ||||
ret << CLOSE_GEN_BLOCK(); | ||||
} | ||||
void Flat::CURS( ostream &ret, bool inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_EXPR() << "_ps" << CLOSE_GEN_EXPR(); | ||||
} | ||||
void Flat::TARGS( ostream &ret, bool inFinish, int targState ) | ||||
{ | ||||
ret << OPEN_GEN_EXPR() << vCS() << CLOSE_GEN_EXPR(); | ||||
} | ||||
void Flat::NEXT( ostream &ret, int nextDest, bool inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK() << vCS() << " = " << nextDest << ";" << CLOSE_GEN | ||||
_BLOCK(); | ||||
} | ||||
void Flat::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK() << "" << vCS() << " = " << OPEN_HOST_EXPR(); | ||||
INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | ||||
ret << CLOSE_HOST_EXPR() << ";" << CLOSE_GEN_BLOCK(); | ||||
} | ||||
void Flat::CALL( ostream &ret, int callDest, int targState, bool inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK(); | ||||
if ( red->prePushExpr != 0 ) { | ||||
ret << OPEN_HOST_BLOCK( red->prePushExpr ); | ||||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) | ||||
; | ||||
ret << CLOSE_HOST_BLOCK(); | ||||
} | ||||
ret << STACK() << "[" << TOP() << "] = " << vCS() << "; " << TOP() << " + | ||||
= 1;" << vCS() << " = " << | ||||
callDest << ";"; | ||||
if ( inFinish && !noEnd ) | ||||
EOF_CHECK( ret ); | ||||
ret << " goto _again;"; | ||||
ret << CLOSE_GEN_BLOCK(); | ||||
} | ||||
void Flat::NCALL( ostream &ret, int callDest, int targState, bool inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK(); | ||||
if ( red->prePushExpr != 0 ) { | ||||
ret << OPEN_HOST_BLOCK( red->prePushExpr ); | ||||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) | ||||
; | ||||
ret << CLOSE_HOST_BLOCK(); | ||||
} | ||||
ret << STACK() << "[" << TOP() << "] = " << vCS() << "; " << | ||||
TOP() << " += 1;" << vCS() << " = " << | ||||
callDest << "; " << CLOSE_GEN_BLOCK(); | ||||
} | ||||
void Flat::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool i | ||||
nFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK(); | ||||
if ( red->prePushExpr != 0 ) { | ||||
ret << OPEN_HOST_BLOCK( red->prePushExpr ); | ||||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) | ||||
; | ||||
ret << CLOSE_HOST_BLOCK(); | ||||
} | ||||
ret << STACK() << "[" << TOP() << "] = " << vCS() << "; " << | ||||
TOP() << " += 1;" << vCS() << " = " << OPEN_HOST_EXPR(); | ||||
INLINE_LIST( ret, ilItem->children, targState, inFinish, false ); | ||||
ret << CLOSE_HOST_EXPR() << ";"; | ||||
if ( inFinish && !noEnd ) | ||||
EOF_CHECK( ret ); | ||||
ret << "goto _again;"; | ||||
ret << CLOSE_GEN_BLOCK(); | ||||
} | ||||
void Flat::NCALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool | ||||
inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK(); | ||||
if ( red->prePushExpr != 0 ) { | ||||
ret << OPEN_HOST_BLOCK( red->prePushExpr ); | ||||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) | ||||
; | ||||
ret << CLOSE_HOST_BLOCK(); | ||||
} | ||||
ret << STACK() << "[" << TOP() << "] = " << vCS() << "; " << TOP() << " + | ||||
= 1;" << vCS() << | ||||
" = " << OPEN_HOST_EXPR(); | ||||
INLINE_LIST( ret, ilItem->children, targState, inFinish, false ); | ||||
ret << CLOSE_HOST_EXPR() << "; " << CLOSE_GEN_BLOCK(); | ||||
} | ||||
void Flat::RET( ostream &ret, bool inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = " << STACK() | ||||
<< "[" << TOP() << "];"; | ||||
if ( red->postPopExpr != 0 ) { | ||||
ret << OPEN_HOST_BLOCK( red->postPopExpr ); | ||||
INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) | ||||
; | ||||
ret << CLOSE_HOST_BLOCK(); | ||||
} | ||||
if ( inFinish && !noEnd ) | ||||
EOF_CHECK( ret ); | ||||
ret << "goto _again;" << CLOSE_GEN_BLOCK(); | ||||
} | ||||
void Flat::NRET( ostream &ret, bool inFinish ) | ||||
{ | ||||
ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = " << STACK() | ||||
<< "[" << TOP() << "];"; | ||||
if ( red->postPopExpr != 0 ) { | ||||
ret << OPEN_HOST_BLOCK( red->postPopExpr ); | ||||
INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) | ||||
; | ||||
ret << CLOSE_HOST_BLOCK(); | ||||
} | ||||
/* FIXME: ws in front of } will cause rlhc failure. */ | ||||
ret << CLOSE_GEN_BLOCK(); | ||||
} | ||||
void Flat::BREAK( ostream &ret, int targState, bool csForced ) | ||||
{ | ||||
outLabelUsed = true; | ||||
ret << OPEN_GEN_BLOCK() << P() << " += 1; " << "goto _out; " << CLOSE_GEN | ||||
_BLOCK(); | ||||
} | ||||
void Flat::NBREAK( ostream &ret, int targState, bool csForced ) | ||||
{ | ||||
outLabelUsed = true; | ||||
ret << OPEN_GEN_BLOCK() << P() << " += 1; " << " _nbreak = 1; " << CLOSE_ | ||||
GEN_BLOCK(); | ||||
} | ||||
End of changes. 9 change blocks. | ||||
31 lines changed or deleted | 178 lines changed or added |