diff --git a/java2python/compiler/visitor.py b/java2python/compiler/visitor.py index f62e53e..14b77a3 100644 --- a/java2python/compiler/visitor.py +++ b/java2python/compiler/visitor.py @@ -434,6 +434,7 @@ def acceptDo(self, node, memo): tokens.FOR_EACH, tokens.METHOD_CALL, tokens.ARGUMENT_LIST, + tokens.FOR, ) def acceptExpr(self, node, memo): @@ -452,7 +453,9 @@ def acceptFor(self, node, memo): else: whileStat.expr.walk(cond, memo) whileBlock = self.factory.methodContent(parent=self) - if not node.firstChildOfType(tokens.BLOCK_SCOPE).children: + if not node.firstChildOfType(tokens.BLOCK_SCOPE): # A for loop without braces + whileBlock.walk(node.children[3], memo) + elif not node.firstChildOfType(tokens.BLOCK_SCOPE).children: self.factory.expr(left='pass', parent=whileBlock) else: whileBlock.walk(node.firstChildOfType(tokens.BLOCK_SCOPE), memo) diff --git a/java2python/config/algs4.py b/java2python/config/algs4.py new file mode 100644 index 0000000..61132f4 --- /dev/null +++ b/java2python/config/algs4.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This is the default configuration file for java2python. Unless +# explicity disabled with the '-n' or '--nodefaults' option, the j2py +# script will import this module for runtime configuration. + +from java2python.mod import basic, transform +from java2python.lang.selector import * + + +# Leading indent character or characters. Four spaces are used +# because that is the recommendation of PEP 8. +indentPrefix = ' ' * 4 + + +# Prefix character or characters for comments. The hash+space is +# recommended by PEP 8. +commentPrefix = '# ' + + +# These values are strings or generators that yield strings +# for a module prologue. +modulePrologueHandlers = [ + basic.shebangLine, + basic.simpleDocString, + 'from __future__ import print_function', + basic.maybeBsr, + basic.maybeAbstractHelpers, + basic.maybeSyncHelpers, +] + + +# These generators yield lines for a module epilogue. +moduleEpilogueHandlers = [ + basic.scriptMainStanza, +] + + +# These generators yield (possibly modified) source strings for a +# module. The `basic.outputSubs` handler references the list of +# regular expression substitutions near the end of this module. +moduleOutputHandlers = [ + basic.outputSubs, +] + + +# These generators yield doc strings for a class. +classHeadHandlers = [ + basic.simpleDocString, +] + +methodParamHandlers = [ + basic.defaultParams, +] + +# This is the name of the callable used to construct locks for an object with +# the synchronized keyword. +methodLockFunctionName = 'lock_for_object' + +classBaseHandlers = [ + basic.defaultBases, +] + +interfaceBaseHandlers = [ + basic.defaultBases, +] + +# These generators are called after a class has been completely +# generated. The class content sorter sorts the methods of a class by +# name. It's commented out because its output differs so greatly +# from its input, and because it's really not very useful. +classPostWalkHandlers = [ + basic.moveStaticExpressions, + ## basic.classContentSort, +] + + +enumHeadHandlers = [ + basic.simpleDocString, +] + + +interfaceHeadHandlers = [ + basic.simpleDocString, + '__metaclass__ = ABCMeta', +] + + +interfacePostWalkMutators = [ +] + + +methodHeadHandlers = [ + basic.simpleDocString, +] + + +methodPrologueHandlers = [ + basic.maybeAbstractMethod, + basic.maybeClassMethod, + basic.overloadedClassMethods, + # NB: synchronized should come after classmethod + basic.maybeSynchronizedMethod, +] + + +# This handler creates enum values on enum classes after they've been +# defined. The handler tries to match Java semantics by using +# strings. Refer to the documentation for details. +enumValueHandler = basic.enumConstStrings + +# Alternatively, you can use this handler to construct enum values as +# integers. +#enumValueHandler = basic.enumConstInts + + +# When the compiler needs to make up a variable name (for example, to +# emulate assignment expressions), it calls this handler to produce a +# new one. +expressionVariableNamingHandler = basic.globalNameCounter + + +# This handler simply creates comments in the file for package +# declarations. +modulePackageDeclarationHandler = basic.commentedPackages + + +# This handler can be used instead to create __init__.py files for +# 'namespace packages' via pkgutil. +# modulePackageDeclarationHandler = basic.namespacePackages + + +# This handler is turns java imports into python imports. No mapping +# of packages is performed: +# moduleImportDeclarationHandler = basic.simpleImports + +# This import decl. handler can be used instead to produce comments +# instead of import statements: +# moduleImportDeclarationHandler = basic.commentedImports + +# The AST transformation function uses these declarations to modify an +# AST before compiling it to python source. Having these declarations +# in a config file gives clients an opportunity to change the +# transformation behavior. + +astTransforms = [ + (Type('NULL'), transform.null2None), + (Type('FALSE'), transform.false2False), + (Type('TRUE'), transform.true2True), + (Type('IDENT'), transform.keywordSafeIdent), + + (Type('DECIMAL_LITERAL'), transform.syntaxSafeDecimalLiteral), + (Type('FLOATING_POINT_LITERAL'), transform.syntaxSafeFloatLiteral), + + (Type('TYPE') > Type('BOOLEAN'), transform.typeSub), + (Type('TYPE') > Type('BYTE'), transform.typeSub), + (Type('TYPE') > Type('CHAR'), transform.typeSub), + (Type('TYPE') > Type('FLOAT'), transform.typeSub), + (Type('TYPE') > Type('INT'), transform.typeSub), + (Type('TYPE') > Type('SHORT'), transform.typeSub), + (Type('TYPE') > Type('LONG'), transform.typeSub), + (Type('TYPE') > Type('DOUBLE'), transform.typeSub), + + (Type('METHOD_CALL') > Type('DOT') > Type('IDENT', 'length'), + transform.lengthToLen), + + (Type('METHOD_CALL') > Type('DOT') > ( + Type('IDENT', 'String') + + Type('IDENT', 'format') + ), + transform.formatString), + + (Type('TYPE') > Type('QUALIFIED_TYPE_IDENT') > Type('IDENT'), + transform.typeSub), + +] + + +# not implemented: + +# minimum parameter count to trigger indentation of parameter names +# in method declarations. set to 0 to disable. +#minIndentParams = 5 + +# Specifies handler for cast operations of non-primitive types are handled +# (primitive types are automatically handled). Use basic.castDrop to leave +# cast expressions out of generated source. Use basic.castCtor to transform +# casts into constructor calls. Or you can specify a function of your own. +expressionCastHandler = basic.castDrop + + +# Values below are used by the handlers. They're here for +# convenience. + + +# module output subs. +moduleOutputSubs = [ + (r'System\.out\.println\((.*)\)', r'print(\1)'), + (r'StdOut\.println\((.*)\)', r'print(\1)'), + (r'System\.err\.println\((.*)\)', r'print(\1, file=sys.stderr)'), + (r'System\.out\.print_\((.*?)\)', r'print(\1, end="")'), + (r'(.*?)\.equals\((.*?)\)', r'\1 == \2'), + (r'(.*?)\.equalsIgnoreCase\((.*?)\)', r'\1.lower() == \2.lower()'), + (r'([\w.]+)\.size\(\)', r'len(\1)'), + #(r'(\w+)\.get\((.*?)\)', r'\1[\2]'), + (r'(\s)(\S*?)(\.toString\(\))', r'\1\2.__str__()'), + (r'(\s)def toString', r'\1def __str__'), + (r'(\s)(\S*?)(\.toLowerCase\(\))', r'\1\2.lower()'), + (r'(.*?)IndexOutOfBoundsException\((.*?)\)', r'\1IndexError(\2)'), + (r'\.__class__\.getName\(\)', '.__class__.__name__'), + (r'\.getClass\(\)', '.__class__'), + (r'\.getName\(\)', '.__name__'), + (r'\.getInterfaces\(\)', '.__bases__'), + (r'String\.valueOf\((.*?)\)', r'str(\1)'), + #(r'(\s)(\S*?)(\.toString\(\))', r'\1str(\2)'), + (r'Math\.', ''), +] + + +typeSubs = { + 'Boolean' : 'bool', + 'boolean' : 'bool', + + 'Byte' : 'int', + 'byte' : 'int', + + 'Char' : 'str', + 'char' : 'str', + + 'Integer' : 'int', + 'int' : 'int', + + 'Short' : 'int', + 'short' : 'int', + + 'Long' : 'long', + 'long' : 'long', + + 'Float' : 'float', + 'float' : 'float', + + 'Double' : 'float', + 'double' : 'float', + + 'String' : 'str', + 'java.lang.String' : 'str', + + 'Object' : 'object', + + 'IndexOutOfBoundsException' : 'IndexError', + 'IOException': 'IOError', + 'NoSuchElementException': 'Exception' + } diff --git a/test/ForLoop3.java b/test/ForLoop3.java new file mode 100644 index 0000000..56507ec --- /dev/null +++ b/test/ForLoop3.java @@ -0,0 +1,7 @@ +class ForLoop3 { + public static void main(String[] args) { + for (int i = 0; i < 3; i++) + System.out.println(i); + System.out.println("outside of loop"); + } +} diff --git a/test/ForLoop4.java b/test/ForLoop4.java new file mode 100644 index 0000000..2ccb177 --- /dev/null +++ b/test/ForLoop4.java @@ -0,0 +1,8 @@ +class ForLoop4 { + public static void main(String[] args) { + for (int i = 0; i < 3; i++) + if (i > 0) + System.out.println(i); + System.out.println("outside of loop"); + } +}