ipgoto.cc (ragel-7.0.0.9) | : | ipgoto.cc (ragel-7.0.0.10) | ||
---|---|---|---|---|
/* | /* | |||
* Copyright 2001-2014 Adrian Thurston <thurston@complang.org> | * Copyright 2001-2014 Adrian Thurston <thurston@colm.net> | |||
*/ | ||||
/* This file is part of Ragel. | ||||
* | * | |||
* Ragel is free software; you can redistribute it and/or modify | * Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* it under the terms of the GNU General Public License as published by | * of this software and associated documentation files (the "Software"), to | |||
* the Free Software Foundation; either version 2 of the License, or | * deal in the Software without restriction, including without limitation the | |||
* (at your option) any later version. | * 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 | ||||
* furnished to do so, subject to the following conditions: | ||||
* | * | |||
* Ragel is distributed in the hope that it will be useful, | * The above copyright notice and this permission notice shall be included in al | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | l | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * copies or substantial portions of the Software. | |||
* GNU General Public License for more details. | ||||
* | * | |||
* You should have received a copy of the GNU General Public License | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* along with Ragel; if not, write to the Free Software | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
* 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 | ||||
* SOFTWARE. | ||||
*/ | */ | |||
#include "ragel.h" | #include "ragel.h" | |||
#include "ipgoto.h" | #include "ipgoto.h" | |||
#include "redfsm.h" | #include "redfsm.h" | |||
#include "gendata.h" | #include "gendata.h" | |||
#include "bstmap.h" | #include "bstmap.h" | |||
#include "parsedata.h" | #include "parsedata.h" | |||
#include "inputdata.h" | #include "inputdata.h" | |||
skipping to change at line 76 | skipping to change at line 77 | |||
/* Run the analysis pass over the table data. */ | /* Run the analysis pass over the table data. */ | |||
setTableState( TableArray::AnalyzePass ); | setTableState( TableArray::AnalyzePass ); | |||
tableDataPass(); | tableDataPass(); | |||
/* Switch the tables over to the code gen mode. */ | /* Switch the tables over to the code gen mode. */ | |||
setTableState( TableArray::GeneratePass ); | setTableState( TableArray::GeneratePass ); | |||
} | } | |||
bool IpGoto::useAgainLabel() | bool IpGoto::useAgainLabel() | |||
{ | { | |||
return redFsm->anyRegActionRets() || | return redFsm->anyActionRets() || | |||
redFsm->anyRegActionByValControl() || | redFsm->anyActionByValControl() || | |||
redFsm->anyRegNextStmt(); | redFsm->anyRegNextStmt(); | |||
} | } | |||
void IpGoto::EOF_CHECK( ostream &ret, int gotoDest ) | ||||
{ | ||||
ret << | ||||
" if ( " << P() << " == " << PE() << " )\n" | ||||
" goto _test_eof" << gotoDest << ";\n"; | ||||
testEofUsed = true; | ||||
} | ||||
void IpGoto::GOTO( ostream &ret, int gotoDest, bool inFinish ) | void IpGoto::GOTO( ostream &ret, int gotoDest, bool inFinish ) | |||
{ | { | |||
ret << OPEN_GEN_BLOCK() << "goto st" << gotoDest << ";" << CLOSE_GEN_BLOC | ret << OPEN_GEN_BLOCK(); | |||
K(); | ||||
if ( inFinish && !noEnd ) | ||||
EOF_CHECK( ret, gotoDest ); | ||||
ret << "goto st" << gotoDest << ";"; | ||||
ret << CLOSE_GEN_BLOCK(); | ||||
} | } | |||
void IpGoto::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) | void IpGoto::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) | |||
{ | { | |||
ret << OPEN_GEN_BLOCK() << vCS() << " = " << OPEN_HOST_EXPR(); | ret << OPEN_GEN_BLOCK() << vCS() << " = " << OPEN_HOST_EXPR(); | |||
INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | |||
ret << CLOSE_HOST_EXPR() << "; " << "goto _again;" << CLOSE_GEN_BLOCK(); | ret << CLOSE_HOST_EXPR() << ";"; | |||
/* Since we are setting CS above and can select on it, call the all-state | ||||
* test_eof. */ | ||||
if ( inFinish && !noEnd ) | ||||
CodeGen::EOF_CHECK( ret ); | ||||
ret << " goto _again;"; | ||||
ret << CLOSE_GEN_BLOCK(); | ||||
} | } | |||
void IpGoto::CALL( ostream &ret, int callDest, int targState, bool inFinish ) | void IpGoto::CALL( ostream &ret, int callDest, int targState, bool inFinish ) | |||
{ | { | |||
ret << OPEN_GEN_BLOCK(); | ret << OPEN_GEN_BLOCK(); | |||
if ( red->prePushExpr != 0 ) { | if ( red->prePushExpr != 0 ) { | |||
ret << OPEN_HOST_BLOCK( red->prePushExpr ); | ret << OPEN_HOST_BLOCK( red->prePushExpr ); | |||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | |||
ret << CLOSE_HOST_BLOCK(); | ret << CLOSE_HOST_BLOCK(); | |||
} | } | |||
ret << STACK() << "[" << TOP() << "] = " << targState << | ret << STACK() << "[" << TOP() << "] = " << targState << | |||
"; " << TOP() << "+= 1; " << "goto st" << callDest << ";" | "; " << TOP() << "+= 1; "; | |||
<< | ||||
CLOSE_GEN_BLOCK(); | if ( inFinish && !noEnd ) | |||
EOF_CHECK( ret, callDest ); | ||||
ret << "goto st" << callDest << ";"; | ||||
ret << CLOSE_GEN_BLOCK(); | ||||
} | } | |||
void IpGoto::NCALL( ostream &ret, int callDest, int targState, bool inFinish ) | void IpGoto::NCALL( ostream &ret, int callDest, int targState, bool inFinish ) | |||
{ | { | |||
ret << OPEN_GEN_BLOCK(); | ret << OPEN_GEN_BLOCK(); | |||
if ( red->prePushExpr != 0 ) { | if ( red->prePushExpr != 0 ) { | |||
ret << OPEN_HOST_BLOCK( red->prePushExpr ); | ret << OPEN_HOST_BLOCK( red->prePushExpr ); | |||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | |||
ret << CLOSE_HOST_BLOCK(); | ret << CLOSE_HOST_BLOCK(); | |||
skipping to change at line 136 | skipping to change at line 168 | |||
if ( red->prePushExpr != 0 ) { | if ( red->prePushExpr != 0 ) { | |||
ret << OPEN_HOST_BLOCK( red->prePushExpr ); | ret << OPEN_HOST_BLOCK( red->prePushExpr ); | |||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | |||
ret << CLOSE_HOST_BLOCK(); | ret << CLOSE_HOST_BLOCK(); | |||
} | } | |||
ret << STACK() << "[" << TOP() << "] = " << targState << "; " << TOP() << "+= 1;" << | ret << STACK() << "[" << TOP() << "] = " << targState << "; " << TOP() << "+= 1;" << | |||
vCS() << " = " << OPEN_HOST_EXPR(); | vCS() << " = " << OPEN_HOST_EXPR(); | |||
INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | |||
ret << CLOSE_HOST_EXPR() << "; goto _again;" << CLOSE_GEN_BLOCK(); | ret << CLOSE_HOST_EXPR() << ";"; | |||
/* Since we are setting CS above and can select on it, call the all-state | ||||
* test_eof. */ | ||||
if ( inFinish && !noEnd ) | ||||
CodeGen::EOF_CHECK( ret ); | ||||
ret << " goto _again;"; | ||||
ret << CLOSE_GEN_BLOCK(); | ||||
} | } | |||
void IpGoto::NCALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, boo l inFinish ) | void IpGoto::NCALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, boo l inFinish ) | |||
{ | { | |||
ret << OPEN_GEN_BLOCK(); | ret << OPEN_GEN_BLOCK(); | |||
if ( red->prePushExpr != 0 ) { | if ( red->prePushExpr != 0 ) { | |||
ret << OPEN_HOST_BLOCK( red->prePushExpr ); | ret << OPEN_HOST_BLOCK( red->prePushExpr ); | |||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | |||
ret << CLOSE_HOST_BLOCK(); | ret << CLOSE_HOST_BLOCK(); | |||
skipping to change at line 166 | skipping to change at line 207 | |||
{ | { | |||
ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = " | ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = " | |||
<< STACK() << "[" << TOP() << "];"; | << STACK() << "[" << TOP() << "];"; | |||
if ( red->postPopExpr != 0 ) { | if ( red->postPopExpr != 0 ) { | |||
ret << OPEN_HOST_BLOCK( red->postPopExpr ); | ret << OPEN_HOST_BLOCK( red->postPopExpr ); | |||
INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) ; | INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) ; | |||
ret << CLOSE_HOST_BLOCK(); | ret << CLOSE_HOST_BLOCK(); | |||
} | } | |||
if ( inFinish && !noEnd ) | ||||
CodeGen::EOF_CHECK( ret ); | ||||
ret << "goto _again;" << CLOSE_GEN_BLOCK(); | ret << "goto _again;" << CLOSE_GEN_BLOCK(); | |||
} | } | |||
void IpGoto::NRET( ostream &ret, bool inFinish ) | void IpGoto::NRET( ostream &ret, bool inFinish ) | |||
{ | { | |||
ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = " | ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = " | |||
<< STACK() << "[" << TOP() << "];"; | << STACK() << "[" << TOP() << "];"; | |||
if ( red->postPopExpr != 0 ) { | if ( red->postPopExpr != 0 ) { | |||
ret << OPEN_HOST_BLOCK( red->postPopExpr ); | ret << OPEN_HOST_BLOCK( red->postPopExpr ); | |||
skipping to change at line 605 | skipping to change at line 649 | |||
for ( GenActionTable::Iter act = pair->action->key; act.lte(); ac t++ ) { | for ( GenActionTable::Iter act = pair->action->key; act.lte(); ac t++ ) { | |||
/* Get the action and walk it's tree. */ | /* Get the action and walk it's tree. */ | |||
setLabelsNeeded( act->value->inlineList ); | setLabelsNeeded( act->value->inlineList ); | |||
} | } | |||
} | } | |||
} | } | |||
/* Set up labelNeeded flag for each state. */ | /* Set up labelNeeded flag for each state. */ | |||
void IpGoto::setLabelsNeeded() | void IpGoto::setLabelsNeeded() | |||
{ | { | |||
/* If we use the _again label, then we the _again switch, which uses all | /* If we use the _again label, then we generate the _again switch, which | |||
* labels. */ | * uses all labels. */ | |||
if ( useAgainLabel() ) { | if ( useAgainLabel() ) { | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | |||
st->labelNeeded = true; | st->labelNeeded = true; | |||
} | } | |||
else { | else { | |||
/* Do not use all labels by default, init all labelNeeded vars to false. */ | /* Do not use all labels by default, init all labelNeeded vars to false. */ | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | |||
st->labelNeeded = false; | st->labelNeeded = false; | |||
for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); tra ns++ ) { | for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); tra ns++ ) { | |||
if ( trans->condSpace == 0 ) | if ( trans->condSpace == 0 ) | |||
setLabelsNeeded( &trans->p ); | setLabelsNeeded( &trans->p ); | |||
} | } | |||
for ( CondApSet::Iter cond = redFsm->condSet; cond.lte(); cond++ ) | for ( CondApSet::Iter cond = redFsm->condSet; cond.lte(); cond++ ) | |||
setLabelsNeeded( &cond->p ); | setLabelsNeeded( &cond->p ); | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | ||||
{ | ||||
if ( st->eofAction != 0 ) { | ||||
for ( GenActionTable::Iter item = st->eofAction-> | ||||
key; item.lte(); item++ ) | ||||
setLabelsNeeded( item->value->inlineList | ||||
); | ||||
} | ||||
} | ||||
} | } | |||
if ( !noEnd ) { | if ( !noEnd ) { | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { | |||
if ( st != redFsm->errState ) | if ( st != redFsm->errState ) | |||
st->outNeeded = st->labelNeeded; | st->outNeeded = st->labelNeeded; | |||
} | } | |||
} | } | |||
} | } | |||
void IpGoto::writeData() | void IpGoto::writeData() | |||
{ | { | |||
STATE_IDS(); | STATE_IDS(); | |||
taNfaTargs(); | taNfaTargs(); | |||
taNfaOffsets(); | taNfaOffsets(); | |||
taNfaPushActions(); | taNfaPushActions(); | |||
End of changes. 14 change blocks. | ||||
26 lines changed or deleted | 80 lines changed or added |