The alphabet type is now communicated from the frontend to the backend using a
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Sun, 29 Apr 2007 23:25:14 +0000 (23:25 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Sun, 29 Apr 2007 23:25:14 +0000 (23:25 +0000)
one-word internal name instead of an array offset.

The Ruby host language types were just copied from Java. Reduced them to two
basic types: char and int, both signed.

git-svn-id: http://svn.complang.org/ragel/trunk@213 052ea7fc-9027-0410-9066-f65837a77df0

12 files changed:
common/common.cpp
common/common.h
ragel/main.cpp
ragel/parsedata.cpp
ragel/rlscan.rl
ragel/xmlcodegen.cpp
redfsm/gendata.cpp
redfsm/xmlparse.kl
rlgen-cd/main.cpp
rlgen-dot/main.cpp
rlgen-java/main.cpp
rlgen-ruby/main.cpp

index 63d8e72..94b55c1 100644 (file)
 
 HostType hostTypesC[] =
 {
-       { "char",     0,       true,   CHAR_MIN,  CHAR_MAX,   sizeof(char) },
-       { "unsigned", "char",  false,  0,         UCHAR_MAX,  sizeof(unsigned char) },
-       { "short",    0,       true,   SHRT_MIN,  SHRT_MAX,   sizeof(short) },
-       { "unsigned", "short", false,  0,         USHRT_MAX,  sizeof(unsigned short) },
-       { "int",      0,       true,   INT_MIN,   INT_MAX,    sizeof(int) },
-       { "unsigned", "int",   false,  0,         UINT_MAX,   sizeof(unsigned int) },
-       { "long",     0,       true,   LONG_MIN,  LONG_MAX,   sizeof(long) },
-       { "unsigned", "long",  false,  0,         ULONG_MAX,  sizeof(unsigned long) }
+       { "char",     0,       "char",    true,   CHAR_MIN,  CHAR_MAX,   sizeof(char) },
+       { "unsigned", "char",  "uchar",   false,  0,         UCHAR_MAX,  sizeof(unsigned char) },
+       { "short",    0,       "short",   true,   SHRT_MIN,  SHRT_MAX,   sizeof(short) },
+       { "unsigned", "short", "ushort",  false,  0,         USHRT_MAX,  sizeof(unsigned short) },
+       { "int",      0,       "int",     true,   INT_MIN,   INT_MAX,    sizeof(int) },
+       { "unsigned", "int",   "uint",    false,  0,         UINT_MAX,   sizeof(unsigned int) },
+       { "long",     0,       "long",    true,   LONG_MIN,  LONG_MAX,   sizeof(long) },
+       { "unsigned", "long",  "ulong",   false,  0,         ULONG_MAX,  sizeof(unsigned long) }
 };
 
 HostType hostTypesD[] =
 {
-       { "byte",     0,  true,   CHAR_MIN,  CHAR_MAX,    1 },
-       { "ubyte",    0,  false,  0,         UCHAR_MAX,   1 },
-       { "char",     0,  false,  0,         UCHAR_MAX,   1 },
-       { "short",    0,  true,   SHRT_MIN,  SHRT_MAX,    2 },
-       { "ushort",   0,  false,  0,         USHRT_MAX,   2 },
-       { "wchar",    0,  false,  0,         USHRT_MAX,   2 },
-       { "int",      0,  true,   INT_MIN,   INT_MAX,     4 },
-       { "uint",     0,  false,  0,         UINT_MAX,    4 },
-       { "dchar",    0,  false,  0,         UINT_MAX,    4 }
+       { "byte",    0,  "byte",    true,   CHAR_MIN,  CHAR_MAX,    1 },
+       { "ubyte",   0,  "ubyte",   false,  0,         UCHAR_MAX,   1 },
+       { "char",    0,  "char",    false,  0,         UCHAR_MAX,   1 },
+       { "short",   0,  "short",   true,   SHRT_MIN,  SHRT_MAX,    2 },
+       { "ushort",  0,  "ushort",  false,  0,         USHRT_MAX,   2 },
+       { "wchar",   0,  "wchar",   false,  0,         USHRT_MAX,   2 },
+       { "int",     0,  "int",     true,   INT_MIN,   INT_MAX,     4 },
+       { "uint",    0,  "uint",    false,  0,         UINT_MAX,    4 },
+       { "dchar",   0,  "dchar",   false,  0,         UINT_MAX,    4 }
 };
 
 HostType hostTypesJava[] = 
 {
-       { "byte",     0,  true,   CHAR_MIN,  CHAR_MAX,    1 },
-       { "short",    0,  true,   SHRT_MIN,  SHRT_MAX,    2 },
-       { "char",     0,  false,  0,         USHRT_MAX,   2 },
-       { "int",      0,  true,   INT_MIN,   INT_MAX,     4 },
+       { "byte",    0,  "byte",   true,   CHAR_MIN,  CHAR_MAX,    1 },
+       { "short",   0,  "short",  true,   SHRT_MIN,  SHRT_MAX,    2 },
+       { "char",    0,  "char",   false,  0,         USHRT_MAX,   2 },
+       { "int",     0,  "int",    true,   INT_MIN,   INT_MAX,     4 },
 };
 
+/* What are the appropriate types for ruby? */
 HostType hostTypesRuby[] = 
 {
-       { "byte",     0,  true,   CHAR_MIN,  CHAR_MAX,    1 },
-       { "short",    0,  true,   SHRT_MIN,  SHRT_MAX,    2 },
-       { "char",     0,  false,  0,         USHRT_MAX,   2 },
-       { "int",      0,  true,   INT_MIN,   INT_MAX,     4 },
+       { "char",    0,  "char",   true,   CHAR_MIN,  CHAR_MAX,    1 },
+       { "int",     0,  "int",    true,   INT_MIN,   INT_MAX,     4 },
 };
 
-HostLang hostLangC =    { hostTypesC,    8, hostTypesC+0,    true };
-HostLang hostLangD =    { hostTypesD,    9, hostTypesD+2,    true };
-HostLang hostLangJava = { hostTypesJava, 4, hostTypesJava+2, false };
-HostLang hostLangRuby = { hostTypesRuby, 4, hostTypesRuby+2, false };
+HostLang hostLangC =    { HostLang::C,    hostTypesC,    8, hostTypesC+0,    true };
+HostLang hostLangD =    { HostLang::D,    hostTypesD,    9, hostTypesD+2,    true };
+HostLang hostLangJava = { HostLang::Java, hostTypesJava, 4, hostTypesJava+2, false };
+HostLang hostLangRuby = { HostLang::Ruby, hostTypesRuby, 2, hostTypesRuby+0, false };
 
 HostLang *hostLang = &hostLangC;
-HostLangType hostLangType = CCode;
+
+HostType *findAlphType( char *s1 )
+{
+       for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
+               if ( strcmp( s1, hostLang->hostTypes[i].data1 ) == 0 && 
+                               hostLang->hostTypes[i].data2 == 0 )
+               {
+                       return hostLang->hostTypes + i;
+               }
+       }
+
+       return 0;
+}
+
+HostType *findAlphType( char *s1, char *s2 )
+{
+       for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
+               if ( strcmp( s1, hostLang->hostTypes[i].data1 ) == 0 && 
+                               hostLang->hostTypes[i].data2 != 0 && 
+                               strcmp( s2, hostLang->hostTypes[i].data2 ) == 0 )
+               {
+                       return hostLang->hostTypes + i;
+               }
+       }
+
+       return 0;
+}
+
+HostType *findAlphTypeInternal( char *s1 )
+{
+       for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
+               if ( strcmp( s1, hostLang->hostTypes[i].internalName ) == 0 )
+                       return hostLang->hostTypes + i;
+       }
+
+       return 0;
+}
 
 /* Construct a new parameter checker with for paramSpec. */
 ParamCheck::ParamCheck(char *paramSpec, int argc, char **argv)
index 864c3ff..c0470d3 100644 (file)
@@ -99,6 +99,7 @@ struct HostType
 {
        char *data1;
        char *data2;
+       char *internalName;
        bool isSigned;
        long long minVal;
        long long maxVal;
@@ -107,30 +108,30 @@ struct HostType
 
 struct HostLang
 {
+       /* Target language. */
+       enum Lang
+       {
+               C, D, Java, Ruby
+       };
+
+       Lang lang;
        HostType *hostTypes;
        int numHostTypes;
        HostType *defaultAlphType;
        bool explicitUnsigned;
 };
 
-
-/* Target language. */
-enum HostLangType
-{
-       CCode,
-       DCode,
-       JavaCode,
-       RubyCode
-};
-
 extern HostLang *hostLang;
-extern HostLangType hostLangType;
 
 extern HostLang hostLangC;
 extern HostLang hostLangD;
 extern HostLang hostLangJava;
 extern HostLang hostLangRuby;
 
+HostType *findAlphType( char *s1 );
+HostType *findAlphType( char *s1, char *s2 );
+HostType *findAlphTypeInternal( char *s1 );
+
 /* An abstraction of the key operators that manages key operations such as
  * comparison and increment according the signedness of the key. */
 struct KeyOps
index 910b1bc..e5f4747 100644 (file)
@@ -202,19 +202,15 @@ int main(int argc, char **argv)
 
                        /* Host language types. */
                        case 'C':
-                               hostLangType = CCode;
                                hostLang = &hostLangC;
                                break;
                        case 'D':
-                               hostLangType = DCode;
                                hostLang = &hostLangD;
                                break;
                        case 'J':
-                               hostLangType = JavaCode;
                                hostLang = &hostLangJava;
                                break;
                        case 'R':
-                               hostLangType = RubyCode;
                                hostLang = &hostLangRuby;
                                break;
 
index b4d8ab2..3a24f2f 100644 (file)
@@ -850,38 +850,17 @@ void ParseData::initGraphDict( )
 /* Set the alphabet type. If the types are not valid returns false. */
 bool ParseData::setAlphType( char *s1, char *s2 )
 {
-       bool valid = false;
-       for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
-               if ( strcmp( s1, hostLang->hostTypes[i].data1 ) == 0 && 
-                               hostLang->hostTypes[i].data2 != 0 && 
-                               strcmp( s2, hostLang->hostTypes[i].data2 ) == 0 )
-               {
-                       valid = true;
-                       userAlphType = hostLang->hostTypes + i;
-                       break;
-               }
-       }
-
+       userAlphType = findAlphType( s1, s2 );
        alphTypeSet = true;
-       return valid;
+       return userAlphType != 0;
 }
 
 /* Set the alphabet type. If the types are not valid returns false. */
 bool ParseData::setAlphType( char *s1 )
 {
-       bool valid = false;
-       for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
-               if ( strcmp( s1, hostLang->hostTypes[i].data1 ) == 0 && 
-                               hostLang->hostTypes[i].data2 == 0 )
-               {
-                       valid = true;
-                       userAlphType = hostLang->hostTypes + i;
-                       break;
-               }
-       }
-
+       userAlphType = findAlphType( s1 );
        alphTypeSet = true;
-       return valid;
+       return userAlphType != 0;
 }
 
 bool ParseData::setVariable( char *var, InlineList *inlineList )
@@ -1460,11 +1439,11 @@ void terminateAllParsers( )
 void writeLanguage( std::ostream &out )
 {
        out << " lang=\"";
-       switch ( hostLangType ) {
-               case CCode:    out << "C"; break;
-               case DCode:    out << "D"; break;
-               case JavaCode: out << "Java"; break;
-               case RubyCode: out << "Ruby"; break;
+       switch ( hostLang->lang ) {
+               case HostLang::C:    out << "C"; break;
+               case HostLang::D:    out << "D"; break;
+               case HostLang::Java: out << "Java"; break;
+               case HostLang::Ruby: out << "Ruby"; break;
        }
        out << "\"";
        
index 5a9babb..e9e1733 100644 (file)
@@ -842,7 +842,7 @@ void Scanner::endSection( )
                'getkey' => { 
                        token( KW_GetKey );
                        inlineBlockType = SemiTerminated;
-                       if ( hostLangType == RubyCode )
+                       if ( hostLang->lang == HostLang::Ruby )
                                fcall inline_code_ruby;
                        else
                                fcall inline_code;
@@ -850,7 +850,7 @@ void Scanner::endSection( )
                'access' => { 
                        token( KW_Access );
                        inlineBlockType = SemiTerminated;
-                       if ( hostLangType == RubyCode )
+                       if ( hostLang->lang == HostLang::Ruby )
                                fcall inline_code_ruby;
                        else
                                fcall inline_code;
@@ -858,7 +858,7 @@ void Scanner::endSection( )
                'variable' => { 
                        token( KW_Variable );
                        inlineBlockType = SemiTerminated;
-                       if ( hostLangType == RubyCode )
+                       if ( hostLang->lang == HostLang::Ruby )
                                fcall inline_code_ruby;
                        else
                                fcall inline_code;
@@ -982,7 +982,7 @@ void Scanner::endSection( )
                                token( '{' );
                                curly_count = 1; 
                                inlineBlockType = CurlyDelimited;
-                               if ( hostLangType == RubyCode )
+                               if ( hostLang->lang == HostLang::Ruby )
                                        fcall inline_code_ruby;
                                else
                                        fcall inline_code;
@@ -1073,7 +1073,7 @@ void Scanner::do_scan()
        /* Set up the start state. FIXME: After 5.20 is released the nocs write
         * init option should be used, the main machine eliminated and this statement moved
         * above the write init. */
-       if ( hostLangType == RubyCode )
+       if ( hostLang->lang == HostLang::Ruby )
                cs = rlscan_en_main_ruby;
        else
                cs = rlscan_en_main;
index 248959a..94443f1 100644 (file)
@@ -656,8 +656,7 @@ void XMLCodeGen::writeXML()
        out << "<ragel_def name=\"" << fsmName << "\">\n";
 
        /* Alphabet type. */
-       out << "  <alphtype>" << 
-               (keyOps->alphType - hostLang->hostTypes) << "</alphtype>\n";
+       out << "  <alphtype>" << keyOps->alphType->internalName << "</alphtype>\n";
        
        /* Getkey expression. */
        if ( pd->getKeyExpr != 0 ) {
index b197f76..8f06de0 100644 (file)
@@ -278,8 +278,10 @@ void CodeGenData::closeMachine()
 
 bool CodeGenData::setAlphType( char *data )
 {
-       /* FIXME: This should validate the alphabet type selection. */
-       HostType *alphType = hostLang->hostTypes + atoi(data);
+       HostType *alphType = findAlphTypeInternal( data );
+       if ( alphType == 0 )
+               return false;
+
        thisKeyOps.setAlphType( alphType );
        return true;
 }
index c7e990a..30f6d3a 100644 (file)
@@ -73,22 +73,14 @@ tag_ragel_head: TAG_ragel
                if ( langAttr == 0 )
                        error($1->loc) << "tag <ragel> requires a lang attribute" << endp;
 
-               if ( strcmp( langAttr->value, "C" ) == 0 ) {
-                       hostLangType = CCode;
+               if ( strcmp( langAttr->value, "C" ) == 0 )
                        hostLang = &hostLangC;
-               }
-               else if ( strcmp( langAttr->value, "D" ) == 0 ) {
-                       hostLangType = DCode;
+               else if ( strcmp( langAttr->value, "D" ) == 0 )
                        hostLang = &hostLangD;
-               }
-               else if ( strcmp( langAttr->value, "Java" ) == 0 ) {
-                       hostLangType = JavaCode;
+               else if ( strcmp( langAttr->value, "Java" ) == 0 )
                        hostLang = &hostLangJava;
-               }
-               else if ( strcmp( langAttr->value, "Ruby" ) == 0 ) {
-                       hostLangType = RubyCode;
+               else if ( strcmp( langAttr->value, "Ruby" ) == 0 )
                        hostLang = &hostLangRuby;
-               }
                else {
                        error($1->loc) << "expecting lang attribute to be "
                                        "one of C, D, Java or Ruby" << endp;
index ce5959b..a001cf6 100644 (file)
@@ -113,7 +113,7 @@ ostream &error()
 /* Invoked by the parser when the root element is opened. */
 ostream *openOutput( char *inputFile )
 {
-       if ( hostLangType != CCode && hostLangType != DCode ) {
+       if ( hostLang->lang != HostLang::C && hostLang->lang != HostLang::D ) {
                error() << "this code generator is for C and D only" << endl;
                exit(1);
        }
@@ -126,9 +126,9 @@ ostream *openOutput( char *inputFile )
                        outputFileName = fileNameFromStem( inputFile, ".h" );
                else {
                        char *defExtension = 0;
-                       switch ( hostLangType ) {
-                               case CCode: defExtension = ".c"; break;
-                               case DCode: defExtension = ".d"; break;
+                       switch ( hostLang->lang ) {
+                               case HostLang::C: defExtension = ".c"; break;
+                               case HostLang::D: defExtension = ".d"; break;
                                default: break;
                        }
                        outputFileName = fileNameFromStem( inputFile, defExtension );
@@ -165,8 +165,8 @@ CodeGenData *makeCodeGen( char *sourceFileName, char *fsmName,
                ostream &out, bool wantComplete )
 {
        CodeGenData *codeGen = 0;
-       switch ( hostLangType ) {
-       case CCode:
+       switch ( hostLang->lang ) {
+       case HostLang::C:
                switch ( codeStyle ) {
                case GenTables:
                        codeGen = new CTabCodeGen(out);
@@ -195,7 +195,7 @@ CodeGenData *makeCodeGen( char *sourceFileName, char *fsmName,
                }
                break;
 
-       case DCode:
+       case HostLang::D:
                switch ( codeStyle ) {
                case GenTables:
                        codeGen = new DTabCodeGen(out);
index 3133808..9201681 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2005 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2001-2007 Adrian Thurston <thurston@cs.queensu.ca>
  */
 
 /*  This file is part of Ragel.
index 6c4eeed..c5bd103 100644 (file)
@@ -89,7 +89,7 @@ ostream &error()
 /* Invoked by the parser when the root element is opened. */
 ostream *openOutput( char *inputFile )
 {
-       if ( hostLangType != JavaCode ) {
+       if ( hostLang->lang != HostLang::Java ) {
                error() << "this code generator is for Java only" << endl;
                exit(1);
        }
index 5a26ea8..8cb1469 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2005 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2001-2007 Adrian Thurston <thurston@cs.queensu.ca>
  */
 
 /*  This file is part of Ragel.
@@ -89,7 +89,7 @@ ostream &error()
 /* Invoked by the parser when the root element is opened. */
 ostream *openOutput( char *inputFile )
 {
-       if ( hostLangType != RubyCode ) {
+       if ( hostLang->lang != HostLang::Ruby ) {
                error() << "this code generator is for Ruby only" << endl;
                exit(1);
        }