forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   BlitzMax (http://forum.boolean.name/forumdisplay.php?f=104)
-   -   BlitzMax to Java (http://forum.boolean.name/showthread.php?t=17232)

Matt Merkulov 25.08.2012 18:14

BlitzMax to Java
 
Давеча обновил свой конвертер из BlitzMax-кода в Java-код и протестировал его на большом проекте. Некоторые возможности:
* Конвертирует папку с исходниками
* Добавляет название пакета и строки импорта
* Исправляет названия классов и методов на общепринятые в Java
* Меняет названия некоторых стандартных классов и методов на соответствующие названия Java

Код:

SuperStrict

Import bah.regex


Type TClass
        Global Classes:TMap = New TMap
       
        Field ID:String
        Field Package:String
        Field Name:String
       
        Function Create:TClass( Package:String, Name:String )
                Local Class:TClass = New TClass
                Classes.Insert( Name.ToLower(), Class )
               
                If Name.StartsWith( "LT" ) Then Name = Name[ 2.. ]
                If Name.StartsWith( "T" ) And Name.Length > 1 Then
                        If Name[ 1 ] >= Asc( "A" ) And Name[ 1 ] <= Asc( "Z" ) Then Name = Name[ 1.. ]
                End If
                Name = Name[ 0..1 ].ToUpper() + Name[ 1.. ]
               
                Class.Name = Name
                Class.Package = Package
                Return Class
        End Function
End Type

TClass.Create( "java.lang", "System" )
TClass.Create( "java.lang", "Math" )
TClass.Create( "java.util", "LinkedList" )
TClass.Create( "java.util", "HashMap" )


Type TIdentifier
        Global Identifiers:TMap = New TMap
       
        Field Result:String
        Field Class:TClass
End Type

For Local Pair:String[] = Eachin [ ..
        [ "Byte", "byte" ], ..
        [ "Short", "short" ], ..
        [ "Int", "int" ], ..
        [ "Long", "long" ], ..
        [ "Float", "float" ], ..
        [ "Double", "double" ], ..
        [ "Object", "Object" ], ..
        ..
        [ "And", "&&" ], ..
        [ "Or", "||" ], ..
        [ "Not", "!" ], ..
        [ "Mod", "%" ], ..
        ..
        [ "String", "String" ], ..
        [ "Length", "length" ], ..
        [ "Find", "indexOf" ], ..
        [ "FindLast", "lastIndexOf" ], ..
        [ "Trim", "trim" ], ..
        [ "Replace", "replaceAll" ], ..
        [ "StartsWith", "startsWith" ], ..
        [ "EndsWith", "endsWith" ], ..
        [ "Join", "indexOf" ], ..
        [ "Split", "split" ], ..
        [ "ToLower", "toLowerCase" ], ..
        [ "ToUpper", "toUpperCase" ], ..
        [ "Length", "length()" ], ..
        ..
        [ "TList", "LinkedList", "linkedlist" ], ..
        [ "IsEmpty", "isEmpty" ], ..
        [ "Contains", "contains" ], ..
        [ "AddFirst", "addFirst" ], ..
        [ "AddLast", "addLast" ], ..
        [ "First", "getFirst" ], ..
        [ "Last", "getLast" ], ..
        [ "Remove", "remove" ], ..
        [ "RemoveFirst", "removeFirst" ], ..
        [ "RemoveLast", "removeLast" ], ..
        [ "Clear", "clear" ], ..
        [ "ValueAtIndex", "get" ], ..
        [ "ToArray", "toArray" ], ..
        [ "Count", "size" ], ..
        ..
        [ "TMap", "HashMap", "hashmap" ], ..
        [ "ValueForKey", "get" ], ..
        [ "Insert", "put" ], ..
        [ "Keys", "keySet" ], ..
        [ "Values", "values" ], ..
        ..
        [ "Millisecs", "System.currentTimeMillis()", "system" ], ..
        ..
        [ "Max", "Math.max", "math" ], ..
        [ "Min", "Math.min", "math" ], ..
        [ "Sin", "Math.sin", "math" ], ..
        [ "Cos", "Math.cos", "math" ], ..
        [ "Tan", "Math.tan", "math" ], ..
        [ "ACos", "Math.acos", "math" ], ..
        [ "ASin", "Math.asin", "math" ], ..
        [ "ATan", "Math.atan", "math" ], ..
        [ "ATan2", "Math.atan2", "math" ], ..
        [ "Floor", "Math.floor", "math" ], ..
        [ "Ceil", "Math.ceil", "math" ], ..
        [ "Abs", "Math.abs", "math" ], ..
        [ "Sqr", "Math.sqrt", "math" ], ..
        [ "Log", "Math.log", "math" ], ..
        [ "Exp", "Math.exp", "math" ], ..
        [ "Rnd", "Math.random", "math" ], ..
        [ "Pi", "PI", "math" ], ..
        ..
        [ "True", "true" ], ..
        [ "False", "false" ], ..
        [ "Null", "null" ], ..
        ..
        [ "Return", "return" ], ..
        [ "Exit", "break" ], ..
        [ "Super", "super" ], ..
        [ "Self", "this" ], ..
        [ "Extends", "extends" ], ..
        [ "New", "new" ] ..
]
        '[ "", "" ], ..
       
        Local Identifier:TIdentifier = New TIdentifier
        Identifier.Result = Pair[ 1 ]
        If Pair.Length = 3 Then Identifier.Class = TClass( TClass.Classes.ValueForKey( Pair[ 2 ] ) )
        TIdentifier.Identifiers.Insert( Pair[ 0 ].ToLower(), Identifier )
Next



Const Directory:String = "D:\temp\src"

GetClassNames( Directory )
ProcessDirectory( Directory )

Function GetClassNames( DirName:String, Package:String = "" )
        Local Dir:Int = ReadDir( DirName )
        Repeat
                Local FileName:String = NextFile( Dir )
                If Not FileName Then Exit
                If FileName = "." Or FileName = ".." Then Continue
               
                Local FullFileName:String = DirName + "\" + FileName
                If FileType( FullFileName ) = FILETYPE_DIR Then
                        Local NewPackage:String
                        If Package Then NewPackage = Package + "." + FileName Else NewPackage = FileName
                        GetClassNames( FullFileName, NewPackage )
                        Continue
                End If
               
                If Not FileName.ToLower().EndsWith( ".bmx" ) Then Continue
       
                DebugLog "Retrieving class names from " + FileName
                Local File:TStream = ReadFile( FullFileName )
                While Not Eof( File )
                        Local Line:String = ReadLine( File ).Trim()
                        If Line.ToLower().StartsWith( "type" ) Then
                                Line = Line[ 4.. ].Trim() + " "
                                TClass.Create( Package, Line[ ..Line.Find( " " ) ] )
                        End If
                WEnd
        Forever
End Function

Global FileClasses:TMap

Function ProcessDirectory( DirName:String, Start:Int = -1 )
        If Start < 0 Then Start = DirName.Length
       
        Local Dir:Int = ReadDir( DirName )
        Repeat
                Local FileName:String = NextFile( Dir )
                If Not FileName Then Exit
                If FileName = "." Or FileName = ".." Then Continue

                Local FullFileName:String = DirName + "\" + FileName
                If FileType( FullFileName ) = FILETYPE_DIR Then
                        ProcessDirectory( FullFileName, Start )
                        Continue
                End If
       
                If Not FileName.ToLower().EndsWith( ".bmx" ) Then Continue
               
                FileClasses = New TMap
               
                DebugLog "Converting " + FileName
                Local File:TStream = ReadFile( FullFileName )
                Local Text:String = ""
                Local RemBlock:Int = False
                While Not Eof( File )
                        Local Line:String = ReadLine( File )
                        Local Trimmed:String = Line.ToLower().Trim()
                        If Trimmed.StartsWith( "?" ) Then Continue
                        if Text Then Text :+ "~n"
                        If RemBlock Then
                                If Trimmed = "endrem" or Trimmed = "end rem" Then
                                        Text :+ TRegEx.Create( "^((\t| )*)(EndRem|End Rem)" ).ReplaceAll( Line, "\1 */" )
                                        RemBlock = False
                                Else
                                        Local N:Int = 0
                                        Repeat
                                                N = Line.Find( "#", N ) + 1
                                                If N = 0 or N = Line.Length Then Exit
                                                Line = Line[ ..N ] + Chr( Line[ N ] ).ToLower() + Line [ N + 1.. ]
                                        Forever
                                       
                                        Line = TRegEx.Create( "^((\t| )*)(bbdoc|about): *" ).ReplaceAll( Line, "\1" )
                                        Line = TRegEx.Create( "^((\t| )*)returns: *" ).ReplaceAll( Line, "\1@return " )
                                        Line = TRegEx.Create( "^((\t| )*)See also: *" ).ReplaceAll( Line, "\1@see " )
                                        Text :+ TRegEx.Create( "^((\t| )*)(.*)$" ).ReplaceAll( Line, "\1 * \3" )
                                End If
                        ElseIf Trimmed = "rem" Then
                                Text :+ TRegEx.Create( "^((\t| )*)Rem" ).ReplaceAll( Line, "\1/**" )
                                RemBlock = True
                        Else
                                If Trimmed.StartsWith( "import" ) Or Trimmed.StartsWith( "framework" ) Or Trimmed.StartsWith( "include" ) Then Continue
                                If Line.Trim() Then
                                        Line :+ ";"
                                       
                                        Local IdentifierBegin:Int = -1
                                        Local Brackets:Int = False
                                        Local N:Int = 0
                                        While N < Line.Length
                                                If Brackets Then
                                                        If Line[ N ] = Asc( "~q" ) Then Brackets = False
                                                Else
                                                        If Line[ N ] = Asc( "~q" ) Then
                                                                Brackets = True
                                                        ElseIf Line[ N ] = Asc( "'" ) Then
                                                                Line = Line [ ..N ] + "//" + Line[ N + 1..Line.Length - 1 ]
                                                                Exit
                                                        ElseIf IdentifierBegin < 0 Then
                                                                If IsIdentifier( Line[ N ], True ) Then IdentifierBegin = N
                                                        ElseIf Not IsIdentifier( Line[ N ], False ) Then
                                                                Local NewIdentifier:String = ConvertIdentifier( Line[ IdentifierBegin..N ] )
                                                                Line = Line[ ..IdentifierBegin ] + NewIdentifier + Line[ N.. ]
                                                                N = IdentifierBegin + NewIdentifier.Length
                                                                IdentifierBegin = -1
                                                        End If
                                                End If
                                                N :+ 1
                                        WEnd
                                       
                                        Text :+ ApplyRegExs( Line )
                                End If
                        End If
                WEnd
                CloseFile File
               
                If FileName.StartsWith( "LT" ) Then FullFileName = DirName + "\" + FileName[ 2.. ]
                If FileName[ 0 ] = Asc( "T" ) And FileName[ 1 ] >= Asc( "A" ) And FileName[ 1 ] <= Asc( "Z" ) Then FullFileName = DirName + "\" + FileName[ 1.. ]
                File = WriteFile( FullFileName[ ..FullFileName.Length - 4 ] + ".java" )
               
                Local Package:String = DirName[ Start + 1.. ].Replace( "\", "." )
                WriteLine( File, "package " + Package + ";" )
                For Local Class:TClass = Eachin FileClasses.Keys()
                        if Class.Package <> Package Then WriteLine( File, "import " + Class.Package + "." + Class.Name + ";" )
                Next
                WriteLine( File, "" )
               
                WriteLine( File, Text )
               
                CloseFile File
        Forever
End Function

Function ApplyRegExs:String( Text:String )
        Text = TRegEx.Create( "^((\t| )*)Local " ).ReplaceAll( Text, "\1" )
        Text = TRegEx.Create( "^((\t| )*)Global " ).ReplaceAll( Text, "\1public static " )
        Text = TRegEx.Create( "^((\t| )*)Field " ).ReplaceAll( Text, "\1public " )
        Text = TRegEx.Create( "^((\t| )*)Const " ).ReplaceAll( Text, "\1public final " )
       
        Text = TRegEx.Create( "^((\t| )*)(Function|Method) *((\w|\d|_)*) *\(" ).ReplaceAll( Text, "\1\3 \4:void(" )
        Text = TRegEx.Create( "^((\t| )*)Method (.*);" ).ReplaceAll( Text, "\1public \3 {" )
        Text = TRegEx.Create( "^((\t| )*)Function (.*);" ).ReplaceAll( Text, "\1public static \3 {" )
        Text = TRegEx.Create( "^((\t| )*)Type (.*);" ).ReplaceAll( Text, "\1public class \3 {" )
       
        Local RegEx:TRegEx = TRegEx.Create( "^((\t| )*)If (.*)([^=])=([^=])(.*) Then" )
        While RegEx.Find( Text )
                Text = RegEx.ReplaceAll( Text, "\1if \3\4==\5\6 then" )
        Wend
        Text = TRegEx.Create( " *== *~q~q" ).ReplaceAll( Text, ".isEmpty()" )
        Text = TRegEx.Create( " *== *~q(.*?)~q" ).ReplaceAll( Text, ".equals( ~q\1~q )" )
       
        Text = TRegEx.Create( "^((\t| )*)(ElseIf|Else If) (.*?) Then((\t| )*);" ).ReplaceAll( Text, "\1} else if( \4 ) {" )
        Text = TRegEx.Create( "^((\t| )*)(ElseIf|Else If) (.*?)((\t| )*);$" ).ReplaceAll( Text, "\1} else if( \4 ) {" )
        Local LowerText:String =Text.Trim().ToLower()
        if LowerText.StartsWith( "if" ) Then If Not LowerText.Contains( "then" ) Then Text = Text[ ..Text.Length - 1 ] + "then;"
        Text = TRegEx.Create( "^((\t| )*)If (.*?) Then((\t| )*);$" ).ReplaceAll( Text, "\1if( \3 ) {" )
        Text = TRegEx.Create( "^((\t| )*)If (.*?) Then (.*?) else (.*?);$" ).ReplaceAll( Text, "\1if( \3 ) \4; else \5;" )
        Text = TRegEx.Create( "^((\t| )*)If (.*?) Then (.*?)((\t| )*);$" ).ReplaceAll( Text, "\1if( \3 ) \4;" )
        Text = TRegEx.Create( "^((\t| )*)If (.*?) ((\t| )*);$" ).ReplaceAll( Text, "\1if( \3 ) {" )
        Text = TRegEx.Create( "^((\t| )*)Else((\t| )*);" ).ReplaceAll( Text, "\1} else {" )
       
        Text = TRegEx.Create( "^((\t| )*)For Local ((\w|\d|_)*):((\w|\d|_)*) *= *(.*) To (.*) Step (.*);" ).ReplaceAll( Text, "\1for( \3:\5 = \7; \3 <= \8; \3 += \9 ) {" )
        Text = TRegEx.Create( "^((\t| )*)For ((\w|\d|_)*) *= *(.*) To (.*) Step (.*);" ).ReplaceAll( Text, "\1for( \3 = \5; \3 <= \6; \3 += \7 ) {" )
        Text = TRegEx.Create( "^((\t| )*)For Local ((\w|\d|_)*):((\w|\d|_)*) *= *(.*) To (.*);" ).ReplaceAll( Text, "\1for( \3:\5 = \7; \3 <= \8; \3++ ) {" )
        Text = TRegEx.Create( "^((\t| )*)For ((\w|\d|_)*) *= *(.*) To (.*);" ).ReplaceAll( Text, "\1for( \3 = \5; \3 <= \6; \3++ ) {" )
        Text = TRegEx.Create( "^((\t| )*)For Local ((\w|\d|_)*):((\w|\d|_)*) *= *(.*) Until (.*);" ).ReplaceAll( Text, "\1for( \3:\5 = \7; \3 <= \8; \3++ ) {" )
        Text = TRegEx.Create( "^((\t| )*)For ((\w|\d|_)*) *= *(.*) Until (.*);" ).ReplaceAll( Text, "\1for( \3 = \5; \3 < \6; \3++ ) {" )
        Text = TRegEx.Create( "^((\t| )*)For Local ((\w|\d|_)*):((\w|\d|_)*) *= *EachIn (.*);" ).ReplaceAll( Text, "\1for( \3:\5 @@ \7 ) {" )
        Text = TRegEx.Create( "^((\t| )*)For ((\w|\d|_)*) *= *EachIn (.*);" ).ReplaceAll( Text, "\1for( \3 @@ \5 ) {" )
        Text = TRegEx.Create( "^((\t| )*)While *(.*);" ).ReplaceAll( Text, "\1while( \3 ) {" )
        Text = TRegEx.Create( "^((\t| )*)Repeat((\t| )*);" ).ReplaceAll( Text, "\1while( true ) {" )
        Text = TRegEx.Create( "^((\t| )*)Select *(.*);" ).ReplaceAll( Text, "\1switch( \3 ) {" )
        Text = TRegEx.Create( "^((\t| )*)(EndMethod|End Method|EndIf|End If|End Function|EndFunction|End Type|EndType|Next|WEnd|Forever|End Select|EndSelect)((\t| )*);" ).ReplaceAll( Text, "\1}" )
       
        Text = TRegEx.Create( "new +((\w|\d|_)*)" ).ReplaceAll( Text, "new \1()" )
        Text = TRegEx.Create( "^(((\t| )*)case [^;^:]*);" ).ReplaceAll( Text, "\1@@" )
        Text = TRegEx.Create( "^(((\t| )*)default) *;" ).ReplaceAll( Text, "\1@@" )
       
        Text = TRegEx.Create( ":\+" ).ReplaceAll( Text, "+=" )
        Text = TRegEx.Create( ":\-" ).ReplaceAll( Text, "-=" )
        Text = TRegEx.Create( ":\*" ).ReplaceAll( Text, "*=" )
        Text = TRegEx.Create( ":/" ).ReplaceAll( Text, "/=" )
       
        Text = TRegEx.Create( ">==" ).ReplaceAll( Text, ">=" )
        Text = TRegEx.Create( "<==" ).ReplaceAll( Text, "<=" )
        Text = TRegEx.Create( "<>" ).ReplaceAll( Text, "!=" )
       
        Text = TRegEx.Create( "~~q" ).ReplaceAll( Text, "\~q" )
        Text = TRegEx.Create( "~~n" ).ReplaceAll( Text, "\r\n" )
        Text = TRegEx.Create( "~~t" ).ReplaceAll( Text, "\t" )
        Text = TRegEx.Create( "\.\.((\t| )*);$" ).ReplaceAll( Text, "" )
       
        Text = TRegEx.Create( "(\d):Byte" ).ReplaceAll( Text, "\1" )
        Text = TRegEx.Create( "(\d):Short" ).ReplaceAll( Text, "\1" )
        Text = TRegEx.Create( "(\d):Int" ).ReplaceAll( Text, "\1" )
        Text = TRegEx.Create( "(\d):Long" ).ReplaceAll( Text, "\1l" )
        Text = TRegEx.Create( "(\d):Float" ).ReplaceAll( Text, "\1f" )
        Text = TRegEx.Create( "(\d):Double" ).ReplaceAll( Text, "\1d" )
        Text = TRegEx.Create( "((\w|\d|_)*) *: *((\w|\d|_)*)" ).ReplaceAll( Text, "\3 \1" )
       
        Text = TRegEx.Create( "\$(\d)" ).ReplaceAll( Text, "0x\1" )
        Text = TRegEx.Create( "%(\d)" ).ReplaceAll( Text, "0b\1" )
       
        Text = Text.Replace( "@@", ":" )
        'Text = TRegEx.Create( "" ).ReplaceAll( Text, "" )
       
        Return Text
End Function

Function IsIdentifier:Int( Code:Int, StringBeginning:Int )
        If StringBeginning And Code >= Asc( "0" ) And Code <= Asc( "9" ) Then Return True
        If Code >= Asc( "A" ) And Code <= Asc( "Z" ) Then Return True
        If Code >= Asc( "a" ) And Code <= Asc( "z" ) Then Return True
        If Code = Asc( "_" ) Then Return True
End Function

Function ConvertIdentifier:String( Identifier:String )
        Local LowerCaseIdentifer:String = Identifier.ToLower()
       
        Local Class:TClass = TClass( TClass.Classes.ValueForKey( LowerCaseIdentifer ) )
        If Class Then
                FileClasses.Insert( Class, Null )
                Return Class.Name
        End If
       
        Local ID:TIdentifier = TIdentifier( TIdentifier.Identifiers.ValueForKey( LowerCaseIdentifer ) )
        If ID Then
                If ID.Class Then FileClasses.Insert( ID.Class, Null )
                Return ID.Result
        End If
       
        If Identifier.EndsWith( "@" ) Then Identifier = Identifier[ ..Identifier.Length - 1 ] + ":Byte"
        If Identifier.EndsWith( "%" ) Then Identifier = Identifier[ ..Identifier.Length - 1 ] + ":Int"
        If Identifier.EndsWith( "#" ) Then Identifier = Identifier[ ..Identifier.Length - 1 ] + ":Float"
        If Identifier.EndsWith( "!" ) Then Identifier = Identifier[ ..Identifier.Length - 1 ] + ":Double"
        If Identifier.EndsWith( "$" ) Then Identifier = Identifier[ ..Identifier.Length - 1 ] + ":String"
       
        If LowerCaseIdentifer.StartsWith( "l_" ) Then Identifier = Identifier[ 2.. ]
        Return Identifier[ 0..1 ].ToLower() + Identifier[ 1.. ]
End Function

Требует модуль regex от Brucey (https://code.google.com/p/maxmods/do...x_1_04_src.zip)


Часовой пояс GMT +4, время: 01:42.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot