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/codegen.h | |
parent | 86bb5882a70224a29650ccfa1e46c9b023c2a3ef (diff) | |
download | colm-85b76476de71f43d3eb25d6bef4ee6d84cb71f6c.tar.gz |
lift all source code into src/ dirinto-src
Diffstat (limited to 'src/libfsm/codegen.h')
-rw-r--r-- | src/libfsm/codegen.h | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/src/libfsm/codegen.h b/src/libfsm/codegen.h new file mode 100644 index 00000000..dcc24e3b --- /dev/null +++ b/src/libfsm/codegen.h @@ -0,0 +1,460 @@ +/* + * Copyright 2001-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. + */ + +#ifndef _C_CODEGEN_H +#define _C_CODEGEN_H + +#include <iostream> +#include <string> +#include <stdio.h> +#include "common.h" +#include "gendata.h" +#include "vector.h" +#include "idbase.h" + +using std::string; +using std::ostream; + +/* Integer array line length. */ +//#define IALL 8 + +#define IALL_INTEGRAL 8 +#define IALL_STRING 128 + + +/* Forwards. */ +struct RedFsmAp; +struct RedStateAp; +struct CodeGenData; +struct GenAction; +struct NameInst; +struct GenInlineItem; +struct GenInlineList; +struct RedAction; +struct FsmLongestMatch; +struct LongestMatchPart; + +string itoa( int i ); + +struct Variable +{ + Variable( const char *name ) : name(name), isReferenced(false) {} + + const std::string ref() { isReferenced = true; return name; } + + const char *name; + bool isReferenced; +}; + +struct GotoLabel +{ + GotoLabel( const char *name ) : name(name), isReferenced(false) {} + + const std::string ref() { isReferenced = true; return name; } + + const char *name; + bool isReferenced; +}; + +std::ostream &operator<<( std::ostream &out, GotoLabel &l ); +std::ostream &operator<<( std::ostream &out, Variable &v ); + +struct TableArray; +typedef Vector<TableArray*> ArrayVector; +class CodeGen; + +struct TableArray +{ + enum State { + InitialState = 1, + AnalyzePass, + GeneratePass + }; + + TableArray( const char *name, CodeGen &codeGen ); + + void start(); + void startAnalyze(); + void startGenerate(); + + void setType( std::string type, int width, bool isChar ) + { + this->type = type; + this->width = width; + this->isChar = isChar; + } + + std::string ref(); + + void value( long long v ); + + void valueAnalyze( long long v ); + void valueGenerate( long long v ); + void stringGenerate( long long value ); + + void finish(); + void finishAnalyze(); + void finishGenerate(); + + void setState( TableArray::State state ) + { this->state = state; } + + long long size(); + + State state; + const char *name; + std::string type; + int width; + bool isSigned; + bool isChar; + bool stringTables; + int iall; + long long values; + long long min; + long long max; + CodeGen &codeGen; + std::ostream &out; + int ln; + bool isReferenced; + bool started; +}; + +struct IlOpts +{ + IlOpts( int targState, bool inFinish, bool csForced ) + : targState(targState), inFinish(inFinish), csForced(csForced) {} + + int targState; + bool inFinish; + bool csForced; +}; + + +/* + * class CodeGen + */ +class CodeGen : public CodeGenData +{ +public: + CodeGen( const CodeGenArgs &args ); + + virtual ~CodeGen() {} + + virtual void writeInit(); + virtual void writeStart(); + virtual void writeFirstFinal(); + virtual void writeError(); + virtual void statsSummary(); + +protected: + friend struct TableArray; + typedef Vector<TableArray*> ArrayVector; + ArrayVector arrayVector; + + Variable cpc; + Variable pop_test; + Variable new_recs; + Variable alt; + + string FSM_NAME(); + string START_STATE_ID(); + void taActions(); + string KEY( Key key ); + string LDIR_PATH( char *path ); + + void ACTION( ostream &ret, GenAction *action, IlOpts opts ); + void NFA_CONDITION( ostream &ret, GenAction *condition, bool last ); + void NFA_POP_TEST_EXEC(); + void CONDITION( ostream &ret, GenAction *condition ); + string ALPH_TYPE(); + + bool isAlphTypeSigned(); + long long tableData; + RagelBackend backend; + bool stringTables; + BackendFeature backendFeature; + + TableArray nfaTargs; + TableArray nfaOffsets; + TableArray nfaPushActions; + TableArray nfaPopTrans; + + virtual string GET_KEY(); + + string P(); + string PE(); + string vEOF(); + + string ACCESS(); + string vCS(); + string STACK(); + string TOP(); + string TOKSTART(); + string TOKEND(); + string ACT(); + + string DATA_PREFIX(); + string START() { return DATA_PREFIX() + "start"; } + string ERROR() { return DATA_PREFIX() + "error"; } + string FIRST_FINAL() { return DATA_PREFIX() + "first_final"; } + + /* Declare a variable only if referenced. */ + void DECLARE( std::string type, Variable &var, std::string init = "" ); + + string CAST( string type ); + + string ARR_TYPE( const TableArray &ta ) + { return ta.type; } + + string ARR_REF( TableArray &ta ) + { return ta.ref(); } + + void INLINE_EXPR( ostream &ret, GenInlineList *inlineList ); + void INLINE_BLOCK( ostream &ret, GenInlineExpr *inlineExpr ); + void INLINE_PLAIN( ostream &ret, GenInlineExpr *inlineExpr ); + + void INLINE_LIST( ostream &ret, GenInlineList *inlineList, + int targState, bool inFinish, bool csForced ); + virtual void GOTO( ostream &ret, int gotoDest, bool inFinish ) = 0; + virtual void CALL( ostream &ret, int callDest, int targState, bool inFinish ) = 0; + virtual void NCALL( ostream &ret, int callDest, int targState, bool inFinish ) = 0; + virtual void NEXT( ostream &ret, int nextDest, bool inFinish ) = 0; + virtual void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) = 0; + virtual void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) = 0; + virtual void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, + int targState, bool inFinish ) = 0; + virtual void NCALL_EXPR( ostream &ret, GenInlineItem *ilItem, + int targState, bool inFinish ) = 0; + virtual void RET( ostream &ret, bool inFinish ) = 0; + virtual void NRET( ostream &ret, bool inFinish ) = 0; + virtual void BREAK( ostream &ret, int targState, bool csForced ) = 0; + virtual void NBREAK( ostream &ret, int targState, bool csForced ) = 0; + virtual void CURS( ostream &ret, bool inFinish ) = 0; + virtual void TARGS( ostream &ret, bool inFinish, int targState ) = 0; + void EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ); + void LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, + int inFinish, bool csForced ); + void LM_EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ); + void SET_ACT( ostream &ret, GenInlineItem *item ); + void INIT_TOKSTART( ostream &ret, GenInlineItem *item ); + void INIT_ACT( ostream &ret, GenInlineItem *item ); + void SET_TOKSTART( ostream &ret, GenInlineItem *item ); + void SET_TOKEND( ostream &ret, GenInlineItem *item ); + void GET_TOKEND( ostream &ret, GenInlineItem *item ); + + void HOST_STMT( ostream &ret, GenInlineItem *item, int targState, bool inFinish, bool csForced ); + void HOST_EXPR( ostream &ret, GenInlineItem *item, int targState, bool inFinish, bool csForced ); + void HOST_TEXT( ostream &ret, GenInlineItem *item, int targState, bool inFinish, bool csForced ); + void GEN_STMT( ostream &ret, GenInlineItem *item, int targState, bool inFinish, bool csForced ); + void GEN_EXPR( ostream &ret, GenInlineItem *item, int targState, bool inFinish, bool csForced ); + + void STATE_IDS(); + + string ERROR_STATE(); + string FIRST_FINAL_STATE(); + + string STR( int v ); + + void VALUE( string type, string name, string value ); + + string ACCESS_OPER() + { return backend == Direct ? "" : " -> "; } + + string OPEN_HOST_EXPR() + { return backend == Direct ? "(" : "host( \"-\", 1 ) ={"; } + + string OPEN_HOST_EXPR( string fileName, int line ) + { + return backend == Direct ? "(" : "host( \"" + fileName + "\", " + STR(line) + " ) ={"; + } + + string CLOSE_HOST_EXPR() + { return backend == Direct ? ")" : "}="; } + + string OPEN_HOST_BLOCK( string fileName, int line ) + { + if ( backend == Direct ) { + std::stringstream ss; + ss << "{\n" ; + (*genLineDirective)( ss, lineDirectives, line, fileName.c_str() ); + return ss.str(); + } + else { + return "host( \"" + fileName + "\", " + STR(line) + " ) ${"; + } + } + + string OPEN_HOST_BLOCK( GenInlineExpr *inlineExpr ) + { + return OPEN_HOST_BLOCK( inlineExpr->loc.fileName, inlineExpr->loc.line ); + } + + string CLOSE_HOST_BLOCK() + { return backend == Direct ? "}\n" : "}$"; } + + string OPEN_HOST_PLAIN() + { return backend == Direct ? "" : "host( \"-\", 1 ) @{"; } + + string CLOSE_HOST_PLAIN() + { return backend == Direct ? "" : "}@"; } + + string OPEN_GEN_EXPR() + { return backend == Direct ? "(" : "={"; } + + string CLOSE_GEN_EXPR() + { return backend == Direct ? ")" : "}="; } + + string OPEN_GEN_BLOCK() + { return backend == Direct ? "{" : "${"; } + + string CLOSE_GEN_BLOCK() + { return backend == Direct ? "}" : "}$"; } + + string OPEN_GEN_PLAIN() + { return backend == Direct ? "" : "@{"; } + + string CLOSE_GEN_PLAIN() + { return backend == Direct ? "" : "}@"; } + + string INT() + { return "int"; } + + string UINT() + { return backend == Direct ? "unsigned int" : "uint"; } + + string INDEX( string type, string name ) + { + if ( backend == Direct ) + return "const " + type + " *" + name; + else + return "index " + type + " " + name; + } + + string INDEX( string type ) + { + if ( backend == Direct ) + return "const " + type + " *"; + else + return "index " + type + " "; + } + + string LABEL( string name ) + { + return name + ": "; + } + + string EMIT_LABEL( GotoLabel label ) + { + if ( label.isReferenced ) + return std::string(label.name) + ": {}\n"; + else + return ""; + } + + string OFFSET( string arr, string off ) + { + if ( backend == Direct ) + return "( " + arr + " + (" + off + "))"; + else + return "offset( " + arr + ", " + off + " )"; + } + + string TRUE() + { + if ( backend == Direct ) + return "1"; + else + return "TRUE"; + } + + string DEREF( string arr, string off ) + { + if ( backend == Direct ) + return "(*( " + off + "))"; + else + return "deref( " + arr + ", " + off + " )"; + } + + string CASE( string val ) + { + if ( backend == Direct ) + return "case " + val + ": "; + else + return "case " + val; + } + + string DEFAULT() + { + if ( backend == Direct ) + return "default:"; + else + return "default"; + } + + string CEND( ) + { + if ( backend == Direct ) + return " break; "; + else + return " "; + } + + string FALLTHROUGH() + { + if ( backend == Direct ) + return " "; + else + return "fallthrough;"; + } + + string NIL() + { + if ( backend == Direct ) + return "0"; + else + return "nil"; + } + + string EXPORT( string type, string name, string value ) + { + if ( backend == Direct ) + return "#define " + name + " " + value; + else + return "export " + type + " " + name + " " + value + ";"; + } + + void NFA_POST_POP(); + virtual void NFA_PUSH( std::string ); + virtual void NFA_POP() = 0; + virtual void LOCATE_TRANS() {} + virtual void LOCATE_COND() {} + virtual void EOF_TRANS() {} + + + virtual void COND_EXEC( std::string expr ) {} + virtual void COND_BIN_SEARCH( Variable &var, TableArray &keys, std::string ok, std::string error ) {} + +public: + virtual void writeExports(); +}; + +#endif |