diff options
author | Adrian Thurston <thurston@colm.net> | 2020-10-18 11:44:43 -0700 |
---|---|---|
committer | Adrian Thurston <thurston@colm.net> | 2020-10-18 11:44:43 -0700 |
commit | 85b76476de71f43d3eb25d6bef4ee6d84cb71f6c (patch) | |
tree | 65c127fbcf70e62d8a4848be2c9c4ff7d74d86a1 /src/libfsm/tabbreak.cc | |
parent | 86bb5882a70224a29650ccfa1e46c9b023c2a3ef (diff) | |
download | colm-into-src.tar.gz |
lift all source code into src/ dirinto-src
Diffstat (limited to 'src/libfsm/tabbreak.cc')
-rw-r--r-- | src/libfsm/tabbreak.cc | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/src/libfsm/tabbreak.cc b/src/libfsm/tabbreak.cc new file mode 100644 index 00000000..ee82cc0c --- /dev/null +++ b/src/libfsm/tabbreak.cc @@ -0,0 +1,379 @@ +/* + * Copyright 2018 Adrian Thurston <thurston@colm.net> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * 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: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * 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 "tables.h" +#include "binary.h" +#include "flat.h" + +std::string TabBreak::BREAK( GotoLabel &label ) +{ + string ret = "break"; + if ( loopLabels ) { + ret += " "; + ret += label.ref(); + } + return ret; +} + +std::string TabBreak::CONTINUE( GotoLabel &label ) +{ + string ret = "continue"; + if ( loopLabels ) { + ret += " "; + ret += label.ref(); + } + return ret; +} + +std::string TabBreak::BREAK_LABEL( GotoLabel &label ) +{ + if ( loopLabels ) { + if ( label.isReferenced ) + return std::string(label.name) + "::\n"; + } + return ""; +} + +void TabBreak::CONTROL_JUMP( ostream &ret, bool inFinish ) +{ + ret << "if ( " << TRUE() << " ) break " << _again << ";"; +} + +void TabBreak::GOTO( ostream &ret, int gotoDest, bool inFinish ) +{ + ret << OPEN_GEN_BLOCK() << vCS() << " = " << gotoDest << ";"; + CONTROL_JUMP( ret, inFinish ); + ret << CLOSE_GEN_BLOCK(); +} + +void TabBreak::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() << ";"; + + CONTROL_JUMP( ret, inFinish ); + ret << CLOSE_GEN_BLOCK(); +} + +void TabBreak::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 << ";"; + + CONTROL_JUMP( ret, inFinish ); + ret << CLOSE_GEN_BLOCK(); +} + +void TabBreak::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 TabBreak::CALL_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() << ";"; + + CONTROL_JUMP( ret, inFinish ); + ret << CLOSE_GEN_BLOCK(); +} + +void TabBreak::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 TabBreak::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(); + } + + CONTROL_JUMP( ret, inFinish ); + ret << CLOSE_GEN_BLOCK(); +} + +void TabBreak::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(); + } + + ret << CLOSE_GEN_BLOCK(); +} + +void TabBreak::BREAK( ostream &ret, int targState, bool csForced ) +{ + ret << + OPEN_GEN_BLOCK() << + P() << " += 1; " << + "break " << _resume << "; " << + CLOSE_GEN_BLOCK(); +} + +void TabBreak::NBREAK( ostream &ret, int targState, bool csForced ) +{ + ret << + OPEN_GEN_BLOCK() << + P() << " += 1; " << + nbreak << " = 1;" << + CLOSE_GEN_BLOCK(); +} + +void TabBreak::writeExec() +{ + out << + " {\n"; + + DECLARE( INT(), ps ); + DECLARE( INT(), cpc ); + DECLARE( INT(), nbreak ); + DECLARE( INT(), klen ); + DECLARE( INDEX( ARR_TYPE( condKeys ) ), ckeys ); + DECLARE( INDEX( ARR_TYPE( eofCondKeys ) ), cekeys ); + DECLARE( UINT(), trans, " = 0" ); + DECLARE( UINT(), cond, " = 0" ); + DECLARE( INDEX( ALPH_TYPE() ), keys ); + DECLARE( INDEX( ARR_TYPE( actions ) ), acts ); + DECLARE( INDEX( ARR_TYPE( indices ) ), inds ); + DECLARE( UINT(), nacts ); + DECLARE( INT(), have ); + DECLARE( INT(), pop_test ); + DECLARE( INT(), new_recs ); + DECLARE( INT(), alt ); + DECLARE( INT(), ic ); + + out << BREAK_LABEL( _resume ); + + /* Do we break out on no more input. */ + bool eof = redFsm->anyEofActivity() || redFsm->anyNfaStates(); + if ( !noEnd ) { + if ( eof ) { + out << + " while ( " << P() << " != " << PE() << " || " << P() << " == " << vEOF() << " ) {\n"; + } + else { + out << + " while ( " << P() << " != " << PE() << " ) {\n"; + } + } + else { + out << + " while ( " << TRUE() << " ) {\n"; + + } + + NFA_PUSH( vCS() ); + + if ( loopLabels ) { + out << BREAK_LABEL( _again ); + out << "while ( " << TRUE() << " ) {\n"; + } + + FROM_STATE_ACTIONS(); + + if ( !noEnd && eof ) { + out << + "if ( " << P() << " == " << vEOF() << " ) {\n"; + + if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { + if ( redFsm->anyEofTrans() ) { + out << + " if ( " << ARR_REF( eofTrans ) << "[" << vCS() << "] > 0 ) {\n" + " " << trans << " = " << + CAST(UINT()) << ARR_REF( eofTrans ) << "[" << vCS() << "] - 1;\n" + " }\n"; + } + } + + out << + "}\n" + "else {\n"; + } + + LOCATE_TRANS(); + + if ( !noEnd && eof ) { + out << + "}\n"; + } + + LOCATE_COND(); + + if ( redFsm->anyRegCurStateRef() ) + out << " " << ps << " = " << vCS() << ";\n"; + + string condVar = + red->condSpaceList.length() != 0 ? cond.ref() : trans.ref(); + + out << + " " << vCS() << " = " << CAST(INT()) << ARR_REF( condTargs ) << "[" << condVar << "];\n\n"; + + if ( redFsm->anyRegActions() ) { + out << + " if ( " << ARR_REF( condActions ) << "[" << condVar << "] != 0 ) {\n" + "\n"; + + if ( redFsm->anyRegNbreak() ) + out << " " << nbreak << " = 0;\n"; + + REG_ACTIONS( condVar ); + + if ( redFsm->anyRegNbreak() ) { + out << + " if ( " << nbreak << " == 1 )\n" + " " << BREAK( _resume ) << ";\n"; + } + + out << "}\n"; + } + + + if ( loopLabels ) { + out << BREAK( _again ) << ";\n}\n"; + } + else { + out << "\n" << EMIT_LABEL( _again ); + } + + if ( !noEnd && eof ) { + out << + " if ( " << P() << " == " << vEOF() << " ) {\n" + " if ( " << vCS() << " >= " << FIRST_FINAL_STATE() << " )\n" + " " << BREAK( _resume ) << ";\n" + " }\n" + " else {\n"; + } + + TO_STATE_ACTIONS(); + + if ( redFsm->errState != 0 ) { + out << + " if ( " << vCS() << " != " << redFsm->errState->id << " ) {\n"; + } + + out << + " " << P() << " += 1;\n" + " " << CONTINUE( _resume ) << ";\n"; + + if ( redFsm->errState != 0 ) { + out << + " }\n"; + } + + if ( !noEnd && eof ) { + out << + " }\n"; + } + + if ( redFsm->anyNfaStates() ) { + out << + " if ( nfa_len == 0 )\n" + " " << BREAK ( _resume ) << ";\n" + "\n" + " nfa_count += 1;\n" + " nfa_len -= 1;\n" + " " << P() << " = nfa_bp[nfa_len].p;\n" + ; + + if ( redFsm->bAnyNfaPops ) { + NFA_FROM_STATE_ACTION_EXEC(); + + NFA_POP_TEST_EXEC(); + + out << + " if ( " << pop_test << " )\n" + " " << vCS() << " = nfa_bp[nfa_len].state;\n" + " else\n" + " " << vCS() << " = " << ERROR_STATE() << ";\n"; + } + else { + out << + " " << vCS() << " = nfa_bp[nfa_len].state;\n"; + + } + + NFA_POST_POP(); + } + else { + out << + " " << BREAK( _resume ) << ";\n"; + } + + out << + "}\n"; + + out << EMIT_LABEL( _out ); + + out << " }\n"; +} + |