Started on the move back to a single executable. The backend programs are now a
[external/ragel.git] / rlgen-cd / fsmcodegen.cpp
index c45be49..ab8f4ad 100644 (file)
@@ -36,14 +36,14 @@ using std::string;
 using std::cerr;
 using std::endl;
 
-void lineDirective( ostream &out, char *fileName, int line )
+void cdLineDirective( ostream &out, const char *fileName, int line )
 {
        if ( noLineDirectives )
                out << "/* ";
 
        /* Write the preprocessor line info for to the input file. */
        out << "#line " << line  << " \"";
-       for ( char *pc = fileName; *pc != 0; pc++ ) {
+       for ( const char *pc = fileName; *pc != 0; pc++ ) {
                if ( *pc == '\\' )
                        out << "\\\\";
                else
@@ -57,11 +57,11 @@ void lineDirective( ostream &out, char *fileName, int line )
        out << '\n';
 }
 
-void genLineDirective( ostream &out )
+void FsmCodeGen::genLineDirective( ostream &out )
 {
        std::streambuf *sbuf = out.rdbuf();
        output_filter *filter = static_cast<output_filter*>(sbuf);
-       lineDirective( out, filter->fileName, filter->line + 1 );
+       cdLineDirective( out, filter->fileName, filter->line + 1 );
 }
 
 
@@ -317,7 +317,7 @@ string FsmCodeGen::KEY( Key key )
        return ret.str();
 }
 
-void FsmCodeGen::EXEC( ostream &ret, InlineItem *item, int targState, int inFinish )
+void FsmCodeGen::EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish )
 {
        /* The parser gives fexec two children. The double brackets are for D
         * code. If the inline list is a single word it will get interpreted as a
@@ -327,36 +327,44 @@ void FsmCodeGen::EXEC( ostream &ret, InlineItem *item, int targState, int inFini
        ret << "))-1;}";
 }
 
-void FsmCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, 
-               int targState, int inFinish )
+void FsmCodeGen::LM_SWITCH( ostream &ret, GenInlineItem *item, 
+               int targState, int inFinish, bool csForced )
 {
        ret << 
                "       switch( " << ACT() << " ) {\n";
 
-       for ( InlineList::Iter lma = *item->children; lma.lte(); lma++ ) {
+       bool haveDefault = false;
+       for ( GenInlineList::Iter lma = *item->children; lma.lte(); lma++ ) {
                /* Write the case label, the action and the case break. */
-               ret << "        case " << lma->lmId << ":\n";
+               if ( lma->lmId < 0 ) {
+                       ret << "        default:\n";
+                       haveDefault = true;
+               }
+               else
+                       ret << "        case " << lma->lmId << ":\n";
 
                /* Write the block and close it off. */
                ret << "        {";
-               INLINE_LIST( ret, lma->children, targState, inFinish, false );
+               INLINE_LIST( ret, lma->children, targState, inFinish, csForced );
                ret << "}\n";
 
                ret << "        break;\n";
        }
-       /* Default required for D code. */
+
+       if ( hostLang->lang == HostLang::D && !haveDefault )
+               ret << "        default: break;";
+
        ret << 
-               "       default: break;\n"
                "       }\n"
                "\t";
 }
 
-void FsmCodeGen::SET_ACT( ostream &ret, InlineItem *item )
+void FsmCodeGen::SET_ACT( ostream &ret, GenInlineItem *item )
 {
        ret << ACT() << " = " << item->lmId << ";";
 }
 
-void FsmCodeGen::SET_TOKEND( ostream &ret, InlineItem *item )
+void FsmCodeGen::SET_TOKEND( ostream &ret, GenInlineItem *item )
 {
        /* The tokend action sets tokend. */
        ret << TOKEND() << " = " << P();
@@ -365,33 +373,33 @@ void FsmCodeGen::SET_TOKEND( ostream &ret, InlineItem *item )
        out << ";";
 }
 
-void FsmCodeGen::GET_TOKEND( ostream &ret, InlineItem *item )
+void FsmCodeGen::GET_TOKEND( ostream &ret, GenInlineItem *item )
 {
        ret << TOKEND();
 }
 
-void FsmCodeGen::INIT_TOKSTART( ostream &ret, InlineItem *item )
+void FsmCodeGen::INIT_TOKSTART( ostream &ret, GenInlineItem *item )
 {
        ret << TOKSTART() << " = " << NULL_ITEM() << ";";
 }
 
-void FsmCodeGen::INIT_ACT( ostream &ret, InlineItem *item )
+void FsmCodeGen::INIT_ACT( ostream &ret, GenInlineItem *item )
 {
        ret << ACT() << " = 0;";
 }
 
-void FsmCodeGen::SET_TOKSTART( ostream &ret, InlineItem *item )
+void FsmCodeGen::SET_TOKSTART( ostream &ret, GenInlineItem *item )
 {
        ret << TOKSTART() << " = " << P() << ";";
 }
 
-void FsmCodeGen::SUB_ACTION( ostream &ret, InlineItem *item, 
-               int targState, bool inFinish )
+void FsmCodeGen::SUB_ACTION( ostream &ret, GenInlineItem *item, 
+               int targState, bool inFinish, bool csForced )
 {
        if ( item->children->length() > 0 ) {
                /* Write the block and close it off. */
                ret << "{";
-               INLINE_LIST( ret, item->children, targState, inFinish, false );
+               INLINE_LIST( ret, item->children, targState, inFinish, csForced );
                ret << "}";
        }
 }
@@ -399,81 +407,81 @@ void FsmCodeGen::SUB_ACTION( ostream &ret, InlineItem *item,
 
 /* Write out an inline tree structure. Walks the list and possibly calls out
  * to virtual functions than handle language specific items in the tree. */
-void FsmCodeGen::INLINE_LIST( ostream &ret, InlineList *inlineList, 
+void FsmCodeGen::INLINE_LIST( ostream &ret, GenInlineList *inlineList, 
                int targState, bool inFinish, bool csForced )
 {
-       for ( InlineList::Iter item = *inlineList; item.lte(); item++ ) {
+       for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) {
                switch ( item->type ) {
-               case InlineItem::Text:
+               case GenInlineItem::Text:
                        ret << item->data;
                        break;
-               case InlineItem::Goto:
+               case GenInlineItem::Goto:
                        GOTO( ret, item->targState->id, inFinish );
                        break;
-               case InlineItem::Call:
+               case GenInlineItem::Call:
                        CALL( ret, item->targState->id, targState, inFinish );
                        break;
-               case InlineItem::Next:
+               case GenInlineItem::Next:
                        NEXT( ret, item->targState->id, inFinish );
                        break;
-               case InlineItem::Ret:
+               case GenInlineItem::Ret:
                        RET( ret, inFinish );
                        break;
-               case InlineItem::PChar:
+               case GenInlineItem::PChar:
                        ret << P();
                        break;
-               case InlineItem::Char:
+               case GenInlineItem::Char:
                        ret << GET_KEY();
                        break;
-               case InlineItem::Hold:
+               case GenInlineItem::Hold:
                        ret << P() << "--;";
                        break;
-               case InlineItem::Exec:
+               case GenInlineItem::Exec:
                        EXEC( ret, item, targState, inFinish );
                        break;
-               case InlineItem::Curs:
+               case GenInlineItem::Curs:
                        CURS( ret, inFinish );
                        break;
-               case InlineItem::Targs:
+               case GenInlineItem::Targs:
                        TARGS( ret, inFinish, targState );
                        break;
-               case InlineItem::Entry:
+               case GenInlineItem::Entry:
                        ret << item->targState->id;
                        break;
-               case InlineItem::GotoExpr:
+               case GenInlineItem::GotoExpr:
                        GOTO_EXPR( ret, item, inFinish );
                        break;
-               case InlineItem::CallExpr:
+               case GenInlineItem::CallExpr:
                        CALL_EXPR( ret, item, targState, inFinish );
                        break;
-               case InlineItem::NextExpr:
+               case GenInlineItem::NextExpr:
                        NEXT_EXPR( ret, item, inFinish );
                        break;
-               case InlineItem::LmSwitch:
-                       LM_SWITCH( ret, item, targState, inFinish );
+               case GenInlineItem::LmSwitch:
+                       LM_SWITCH( ret, item, targState, inFinish, csForced );
                        break;
-               case InlineItem::LmSetActId:
+               case GenInlineItem::LmSetActId:
                        SET_ACT( ret, item );
                        break;
-               case InlineItem::LmSetTokEnd:
+               case GenInlineItem::LmSetTokEnd:
                        SET_TOKEND( ret, item );
                        break;
-               case InlineItem::LmGetTokEnd:
+               case GenInlineItem::LmGetTokEnd:
                        GET_TOKEND( ret, item );
                        break;
-               case InlineItem::LmInitTokStart:
+               case GenInlineItem::LmInitTokStart:
                        INIT_TOKSTART( ret, item );
                        break;
-               case InlineItem::LmInitAct:
+               case GenInlineItem::LmInitAct:
                        INIT_ACT( ret, item );
                        break;
-               case InlineItem::LmSetTokStart:
+               case GenInlineItem::LmSetTokStart:
                        SET_TOKSTART( ret, item );
                        break;
-               case InlineItem::SubAction:
-                       SUB_ACTION( ret, item, targState, inFinish );
+               case GenInlineItem::SubAction:
+                       SUB_ACTION( ret, item, targState, inFinish, csForced );
                        break;
-               case InlineItem::Break:
+               case GenInlineItem::Break:
                        BREAK( ret, targState, csForced );
                        break;
                }
@@ -496,7 +504,7 @@ void FsmCodeGen::ACTION( ostream &ret, Action *action, int targState,
                bool inFinish, bool csForced )
 {
        /* Write the preprocessor line info for going into the source file. */
-       lineDirective( ret, sourceFileName, action->loc.line );
+       cdLineDirective( ret, sourceFileName, action->loc.line );
 
        /* Write the block and close it off. */
        ret << "\t{";
@@ -507,7 +515,7 @@ void FsmCodeGen::ACTION( ostream &ret, Action *action, int targState,
 void FsmCodeGen::CONDITION( ostream &ret, Action *condition )
 {
        ret << "\n";
-       lineDirective( ret, sourceFileName, condition->loc.line );
+       cdLineDirective( ret, sourceFileName, condition->loc.line );
        INLINE_LIST( ret, condition->inlineList, 0, false, false );
 }
 
@@ -806,13 +814,13 @@ void FsmCodeGen::finishRagelDef()
        calcIndexSize();
 }
 
-ostream &FsmCodeGen::source_warning( const InputLoc &loc )
+ostream &FsmCodeGen::source_warning( const GenInputLoc &loc )
 {
        cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": warning: ";
        return cerr;
 }
 
-ostream &FsmCodeGen::source_error( const InputLoc &loc )
+ostream &FsmCodeGen::source_error( const GenInputLoc &loc )
 {
        gblErrorCount += 1;
        assert( sourceFileName != 0 );