[pypy-svn] r7896 - in pypy/trunk/src/pypy/translator/java: . test

arigo at codespeak.net arigo at codespeak.net
Fri Dec 17 10:18:03 CET 2004


Author: arigo
Date: Fri Dec 17 10:18:02 2004
New Revision: 7896

Added:
   pypy/trunk/src/pypy/translator/java/   (props changed)
   pypy/trunk/src/pypy/translator/java/PyBool.java   (contents, props changed)
   pypy/trunk/src/pypy/translator/java/PyInt.java   (contents, props changed)
   pypy/trunk/src/pypy/translator/java/PyList.java   (contents, props changed)
   pypy/trunk/src/pypy/translator/java/PyObject.java   (contents, props changed)
   pypy/trunk/src/pypy/translator/java/PySequence.java   (contents, props changed)
   pypy/trunk/src/pypy/translator/java/PyTuple.java   (contents, props changed)
   pypy/trunk/src/pypy/translator/java/TypeError.java   (contents, props changed)
   pypy/trunk/src/pypy/translator/java/__init__.py
      - copied unchanged from r7804, pypy/trunk/src/pypy/translator/__init__.py
   pypy/trunk/src/pypy/translator/java/autopath.py
      - copied unchanged from r7804, pypy/trunk/src/pypy/translator/autopath.py
   pypy/trunk/src/pypy/translator/java/genjava.py
      - copied, changed from r7804, pypy/trunk/src/pypy/translator/genrpy.py
   pypy/trunk/src/pypy/translator/java/test/   (props changed)
   pypy/trunk/src/pypy/translator/java/test/autopath.py
      - copied unchanged from r7804, pypy/trunk/src/pypy/translator/autopath.py
   pypy/trunk/src/pypy/translator/java/test/test_javatrans.py   (contents, props changed)
Log:
Another possible direction: generating Java code.  The advantage of this would
be that the R-Python semantics can very easily be described as a few Java
classes "PyXxx".



Added: pypy/trunk/src/pypy/translator/java/PyBool.java
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/translator/java/PyBool.java	Fri Dec 17 10:18:02 2004
@@ -0,0 +1,9 @@
+
+
+class PyBool extends PyInt {
+
+    PyBool(boolean x) {
+        super(x ? 1 : 0);
+    }
+
+};

Added: pypy/trunk/src/pypy/translator/java/PyInt.java
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/translator/java/PyInt.java	Fri Dec 17 10:18:02 2004
@@ -0,0 +1,47 @@
+
+
+class PyInt extends PyObject {
+
+    int intval;
+    
+    PyInt(int x) {
+        intval = x;
+    }
+
+    boolean is_true() {
+        return intval != 0;
+    }
+
+    boolean eq(PyObject other) {
+        if (other instanceof PyInt)
+            return intval == ((PyInt) other).intval;
+        else
+            return false;
+    }
+
+    boolean lt(PyObject other) {
+        if (other instanceof PyInt)
+            return intval < ((PyInt) other).intval;
+        else
+            throw new TypeError();
+    }
+
+    PyObject op_neg() {
+        return new PyInt(-intval);
+    }
+
+    PyObject op_add(PyObject other) {
+        if (other instanceof PyInt)
+            return new PyInt(intval + ((PyInt) other).intval);
+        else
+            throw new TypeError();
+    }
+
+    PyObject op_sub(PyObject other) {
+        if (other instanceof PyInt)
+            return new PyInt(intval - ((PyInt) other).intval);
+        else
+            throw new TypeError();
+    }
+
+};

Added: pypy/trunk/src/pypy/translator/java/PyList.java
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/translator/java/PyList.java	Fri Dec 17 10:18:02 2004
@@ -0,0 +1,74 @@
+
+
+class PyList extends PySequence {
+
+    PyList(PyObject[] x) {
+        super(x);
+    }
+
+    PyObject op_setitem(PyObject index, PyObject o) {
+        if (index instanceof PyInt) {
+            int i = ((PyInt) index).intval;
+            items[i] = o;
+            return null;
+        }
+        throw new TypeError();
+    }
+
+    PyObject op_add(PyObject other) {
+        if (other instanceof PyList) {
+            PyObject[] items2 = ((PyList) other).items;
+            PyObject[] nitems = new PyObject[items.length + items2.length];
+            System.arraycopy(items, 0, nitems, 0, items.length);
+            System.arraycopy(items2, 0, nitems, items.length, items2.length);
+            return new PyList(nitems);
+        }
+        throw new TypeError();
+    }
+
+    PyObject op_inplace_add(PyObject other) {
+        if (other instanceof PySequence) {
+            PyObject[] items2 = ((PySequence) other).items;
+            PyObject[] nitems = new PyObject[items.length + items2.length];
+            System.arraycopy(items, 0, nitems, 0, items.length);
+            System.arraycopy(items2, 0, nitems, items.length, items2.length);
+            items = nitems;
+            return this;
+        }
+        throw new TypeError();
+    }
+
+    PyObject op_mul(PyObject other) {
+        if (items.length == 1 && other instanceof PyInt) {
+            int i, count = ((PyInt) other).intval;
+            PyObject item = items[0];
+            PyObject[] nitems = new PyObject[count];
+            for (i=0; i<count; i++)
+                nitems[i] = item;
+            return new PyList(nitems);
+        }
+        throw new TypeError();
+    }
+
+    PyObject op_inplace_mul(PyObject other) {
+        if (items.length == 1 && other instanceof PyInt) {
+            int i, count = ((PyInt) other).intval;
+            PyObject item = items[0];
+            PyObject[] nitems = new PyObject[count];
+            for (i=0; i<count; i++)
+                nitems[i] = item;
+            items = nitems;
+            return this;
+        }
+        throw new TypeError();
+    }
+
+    PyObject meth_append_1(PyObject item) {
+        PyObject[] nitems = new PyObject[items.length + 1];
+        System.arraycopy(items, 0, nitems, 0, items.length);
+        nitems[items.length] = item;
+        items = nitems;
+        return null;
+    }
+
+};

Added: pypy/trunk/src/pypy/translator/java/PyObject.java
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/translator/java/PyObject.java	Fri Dec 17 10:18:02 2004
@@ -0,0 +1,44 @@
+
+
+class PyObject {
+
+    static PyBool Py_False = new PyBool(false);
+    static PyBool Py_True  = new PyBool(true);
+
+    boolean is_true() { return true; }
+    PyObject op_is_true() { return new PyBool(is_true()); }
+
+    boolean eq(PyObject other) { return this == other; }
+    boolean lt(PyObject other) { throw new TypeError(); }
+    PyObject op_lt(PyObject other) { return new PyBool(lt(other)); }
+    PyObject op_le(PyObject other) { return new PyBool(!other.lt(this)); }
+    PyObject op_eq(PyObject other) { return new PyBool(eq(other)); }
+    PyObject op_ne(PyObject other) { return new PyBool(!eq(other)); }
+    PyObject op_gt(PyObject other) { return new PyBool(other.lt(this)); }
+    PyObject op_ge(PyObject other) { return new PyBool(!lt(other)); }
+
+    PyObject op_neg() { throw new TypeError(); }
+    PyObject op_add(PyObject other) { throw new TypeError(); }
+    PyObject op_sub(PyObject other) { throw new TypeError(); }
+    PyObject op_mul(PyObject other) { throw new TypeError(); }
+    PyObject op_inplace_add(PyObject other) { return op_add(other); }
+    PyObject op_inplace_sub(PyObject other) { return op_sub(other); }
+    PyObject op_inplace_mul(PyObject other) { return op_mul(other); }
+
+    int len() { throw new TypeError(); }
+    PyObject op_len() { return new PyInt(len()); }
+    PyObject op_getitem(PyObject index) { throw new TypeError(); }
+    PyObject op_setitem(PyObject index, PyObject o) { throw new TypeError(); }
+    PyObject[] unpack(int expected_length, PyObject[] defaults) {
+        throw new TypeError();
+    }
+
+    /* CUT HERE -- automatically generated code below this line */
+    PyObject meth_append_1(PyObject x) {
+        return op_getattr_append().op_call_1(x);
+    }
+    PyObject op_getattr_append() { throw new TypeError(); }
+    PyObject op_call_0() { throw new TypeError(); }
+    PyObject op_call_1(PyObject x) { throw new TypeError(); }
+    PyObject op_call_0_5tar(PyObject stararg) { throw new TypeError(); }
+};

Added: pypy/trunk/src/pypy/translator/java/PySequence.java
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/translator/java/PySequence.java	Fri Dec 17 10:18:02 2004
@@ -0,0 +1,41 @@
+
+
+class PySequence extends PyObject {
+
+    PyObject[] items;
+
+    PySequence(PyObject[] x) {
+        items = x;
+    }
+
+    boolean is_true() {
+        return items.length != 0;
+    }
+
+    int len() {
+        return items.length;
+    }
+
+    PyObject op_getitem(PyObject index) {
+        if (index instanceof PyInt) {
+            int i = ((PyInt) index).intval;
+            return items[i];
+        }
+        throw new TypeError();
+    }
+
+    PyObject[] unpack(int expected_length, PyObject[] defaults) {
+        int missing = expected_length - items.length;
+        if (missing == 0)
+            return items;
+        if (defaults == null || missing < 0 || missing > defaults.length) {
+            throw new TypeError();
+        }
+        PyObject[] result = new PyObject[expected_length];
+        System.arraycopy(items, 0, result, 0, items.length);
+        System.arraycopy(defaults, defaults.length-missing,
+                         result, items.length, missing);
+        return result;
+    }
+
+};

Added: pypy/trunk/src/pypy/translator/java/PyTuple.java
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/translator/java/PyTuple.java	Fri Dec 17 10:18:02 2004
@@ -0,0 +1,20 @@
+
+
+class PyTuple extends PySequence {
+
+    PyTuple(PyObject[] x) {
+        super(x);
+    }
+
+    PyObject op_add(PyObject other) {
+        if (other instanceof PyTuple) {
+            PyObject[] items2 = ((PyTuple) other).items;
+            PyObject[] nitems = new PyObject[items.length + items2.length];
+            System.arraycopy(items, 0, nitems, 0, items.length);
+            System.arraycopy(items2, 0, nitems, items.length, items2.length);
+            return new PyTuple(nitems);
+        }
+        throw new TypeError();
+    }
+
+};

Added: pypy/trunk/src/pypy/translator/java/TypeError.java
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/translator/java/TypeError.java	Fri Dec 17 10:18:02 2004
@@ -0,0 +1,5 @@
+
+
+class TypeError extends RuntimeException {
+
+};

Copied: pypy/trunk/src/pypy/translator/java/genjava.py (from r7804, pypy/trunk/src/pypy/translator/genrpy.py)
==============================================================================
--- pypy/trunk/src/pypy/translator/genrpy.py	(original)
+++ pypy/trunk/src/pypy/translator/java/genjava.py	Fri Dec 17 10:18:02 2004
@@ -1,83 +1,19 @@
 """
-Implementation of a translator from application Python to interpreter level RPython.
+Generate a Java source file from the flowmodel.
 
-The idea is that we can automatically transform app-space implementations
-of methods into some equivalent representation at interpreter level.
-Then, the RPython to C translation might hopefully spit out some
-more efficient code than always interpreting these methods.
-
-Note that the appspace functions are treated as rpythonic, in a sense
-that globals are constants, for instance. This definition is not
-exact and might change.
-
-This module is very much under construction and not yet usable for much
-more than testing.
 """
 
+import sys, os
 from pypy.objspace.flow.model import traverse
 from pypy.objspace.flow import FlowObjSpace
 from pypy.objspace.flow.model import FunctionGraph, Block, Link, Variable, Constant
-from pypy.objspace.flow.model import last_exception, last_exc_value
-from pypy.translator.simplify import simplify_graph
+from pypy.objspace.flow.model import last_exception, last_exc_value, checkgraph
+from pypy.translator.simplify import remove_direct_loops
 from pypy.interpreter.error import OperationError
 from types import FunctionType
 
 from pypy.translator.translator import Translator
 
-import sys
-
-def somefunc(arg):
-    pass
-
-def f(a,b):
-    print "start"
-    a = []
-    a.append(3)
-    for i in range(3):
-        print i
-    if a > b:
-        try:
-            if b == 123:
-                raise ValueError
-            elif b == 321:
-                raise IndexError
-            return 123
-        except ValueError:
-            raise TypeError
-    else:
-        dummy = somefunc(23)
-        return 42
-
-def ff(a, b):
-    try:
-        raise SystemError, 42
-        return a+b
-    finally:
-        a = 7
-
-glob = 100
-def fff():
-    global glob
-    return 42+glob
-
-def app_mod__String_ANY(format, values):
-    import _formatting
-    if isinstance(values, tuple):
-        return _formatting.format(format, values, None)
-    else:
-        if hasattr(values, 'keys'):
-            return _formatting.format(format, (values,), values)
-        else:
-            return _formatting.format(format, (values,), None)
-
-def app_str_decode__String_ANY_ANY(str, encoding=None, errors=None):
-    if encoding is None and errors is None:
-        return unicode(str)
-    elif errors is None:
-        return unicode(str, encoding)
-    else:
-        return unicode(str, encoding, errors)
-        
 
 def ordered_blocks(graph):
     # collect all blocks
@@ -102,16 +38,16 @@
     return [block for ofs, txt, block in allblocks]
 
 
-class GenRpy:
-    def __init__(self, f, translator, modname=None):
-        self.f = f
+class GenJava:
+    def __init__(self, jdir, translator, modname=None):
+        self.jdir = jdir
         self.translator = translator
         self.modname = (modname or
                         translator.functions[0].__name__)
-        self.rpynames = {Constant(None).key:  'w(None)',
-                         Constant(False).key: 'w(False)',
-                         Constant(True).key:  'w(True)',
-                       }
+        self.javanames = {Constant(None).key:  'null',
+                          Constant(False).key: 'Py_False',
+                          Constant(True).key:  'Py_True',
+                          }
         
         self.seennames = {}
         self.initcode = []     # list of lines for the module's initxxx()
@@ -121,21 +57,44 @@
         self.globaldecl = []
         self.globalobjects = []
         self.pendingfunctions = []
+        self.callpatterns = {}
 
         # special constructors:
-        self.has_listarg = {}
-        for name in "newtuple newlist newdict newstring".split():
-            self.has_listarg[name] = name
+        self.has_listarg = {
+            'newlist':  'PyList',
+            'newtuple': 'PyTuple',
+            'newdict':  'PyDict',
+            'newstring':'PyString',
+            }
+
+        self.nameof(self.translator.functions[0])
+        self.gen_source()
 
-        self.gen_source()            
+    def gen_test_class(self, inputargs, expectedresult):
+        entrypoint = self.nameof(self.translator.functions[0])
+        f = self.jdir.join('test.java').open('w')
+        print >> f, 'class test extends PyObject {'
+        print >> f, '    static void main(String[] argv) {'
+        print >> f, '        PyObject result = %s.op_call_%d(%s);' % (
+            entrypoint, len(inputargs),
+            ', '.join([self.nameof(x) for x in inputargs]))
+        print >> f, '        if (result.eq(%s))' % (
+            self.nameof(expectedresult),)
+        print >> f, '            System.out.println("OK");'
+        print >> f, '        else'
+        print >> f, '            System.out.println("FAIL");'
+        print >> f, '    }'
+        self.gen_initcode(f)
+        print >> f, '};'
+        f.close()
 
     def nameof(self, obj):
         key = Constant(obj).key
         try:
-            return self.rpynames[key]
+            return self.javanames[key]
         except KeyError:
             #name = "w(%s)" % str(obj)
-            #self.rpynames[key] = name
+            #self.javanames[key] = name
             #return name
             if (type(obj).__module__ != '__builtin__' and
                 not isinstance(obj, type)):   # skip user-defined metaclasses
@@ -151,7 +110,7 @@
                 else:
                     raise Exception, "nameof(%r) in %r" % (obj, self.current_func)
                 name = meth(obj)
-            self.rpynames[key] = name
+            self.javanames[key] = name
             return name
 
     def uniquename(self, basename):
@@ -183,7 +142,7 @@
         
 
     def nameof_int(self, value):
-        return "w(%d)" % value
+        return "new PyInt(%d)" % value
 
     def nameof_long(self, value):
         # assume we want them in hex most of the time
@@ -224,9 +183,7 @@
                 print "skipped", printable_name
                 return self.skipped_function(func)
         name = self.uniquename('gfunc_' + func.__name__)
-        self.initcode.append('INITCHK(%s = PyCFunction_New('
-                             '&ml_%s, NULL))' % (name, name))
-        self.initcode.append('\t%s->ob_type = &PyGenCFunction_Type;' % name)
+        self.initcode.append('static PyObject %s = new C_%s();' % (name, name))
         self.pendingfunctions.append(func)
         return name
 
@@ -444,113 +401,140 @@
         raise Exception, 'Cannot translate an already-open file: %r' % (fil,)
 
     def gen_source(self):
-        f = self.f
-        info = {
-            'modname': self.modname,
-            'entrypointname': self.translator.functions[0].__name__,
-            'entrypoint': self.nameof(self.translator.functions[0]),
-            }
+##        info = {
+##            'modname': self.modname,
+##            'entrypointname': self.translator.functions[0].__name__,
+##            'entrypoint': self.nameof(self.translator.functions[0]),
+##            }
 
         # function implementations
         while self.pendingfunctions:
             func = self.current_func = self.pendingfunctions.pop()
-            print "#######", func.__name__
-            self.gen_rpyfunction(func)
+            self.gen_javafunction(func)
             # collect more of the latercode after each function
-            while self.latercode:
-                #gen, self.debugstack = self.latercode.pop()
-                gen = self.latercode.pop()
-                #self.initcode.extend(gen) -- eats TypeError! bad CPython!
-                for line in gen:
-                    self.initcode.append(line)
-                self.debugstack = ()
+            self.collect_latercode()
             #self.gen_global_declarations()
 
-        # footer
-        # maybe not needed
-        return
-        print >> f, self.C_INIT_HEADER % info
-        if self.f2name is not None:
-            print >> f, '#include "%s"' % self.f2name
-        for codeline in self.initcode:
-            print >> f, '\t' + codeline
-        print >> f, self.C_INIT_FOOTER % info
+        # copy over the PyXxx classes
+        mydir = os.path.dirname(__file__)
+        for fn in os.listdir(mydir):
+            if fn.lower().endswith('.java'):
+                g = open(os.path.join(mydir, fn), 'r')
+                f = self.jdir.join(fn).open('w')
+                data = g.read()
+                i = data.find('/* CUT HERE')
+                if i < 0:
+                    f.write(data)
+                else:
+                    f.write(data[:i])
+                    print >> f
+                    print >> f, '    /* call patterns */'
+                    callpatterns = self.callpatterns.items()
+                    callpatterns.sort()
+                    for callpattern, args in callpatterns:
+                        print >> f, ('    PyObject %s(%s) { throw new '
+                                     'TypeError(); }' % (callpattern, args))
+                    print >> f
+                    self.gen_initcode(f)
+                    print >> f, '};'
+                f.close()
+                g.close()
+
+    def collect_latercode(self):
+        while self.latercode:
+            gen = self.latercode.pop()
+            #self.initcode.extend(gen) -- eats TypeError! bad CPython!
+            for line in gen:
+                self.initcode.append(line)
+
+    def gen_initcode(self, f):
+        self.collect_latercode()
+        print >> f, '    /* init code */'
+        for line in self.initcode:
+            print >> f, '    ' + line
+        print >> f
+        self.initcode = []
 
-    def gen_rpyfunction(self, func):
+    def gen_javafunction(self, func):
+        t = self.translator
+        #t.simplify(func)
+        graph = t.getflowgraph(func)
+        remove_direct_loops(graph)
+        checkgraph(graph)
 
-        local_names = {}
+        name = self.nameof(func)
+        f = self.jdir.join('C_%s.java' % name).open('w')
+        try:
+            src = graph.source
+        except AttributeError:
+            pass
+        else:
+            print >> f, '//'
+            for line in src.rstrip().split('\n'):
+                print >> f, '// ', line
+            print >> f, '//'
+        print >> f
+        print >> f, 'class C_%s extends PyObject {' % name
+        print >> f
 
-        def expr(v, wrapped = True):
+        def expr(v):
             if isinstance(v, Variable):
-                n = v.name
-                if n.startswith("v") and n[1:].isdigit():
-                    ret = local_names.get(v.name)
-                    if not ret:
-                        if wrapped:
-                            local_names[v.name] = ret = "w_%d" % len(local_names)
-                        else:
-                            local_names[v.name] = ret = "v%d" % len(local_names)
-                    return ret
                 return v.name
             elif isinstance(v, Constant):
                 return self.nameof(v.value)
             else:
-                #raise TypeError, "expr(%r)" % (v,)
-                # XXX how do I resolve these?
-                return "space.%s" % str(v)
+                raise TypeError, "expr(%r)" % (v,)
 
-        def arglist(args):
-            res = [expr(arg) for arg in args]
+        def arglist(args, prefix=''):
+            res = [prefix + expr(arg) for arg in args]
             return ", ".join(res)
         
         def oper(op):
-            # specialcase is_true
             if op.opname in self.has_listarg:
-                fmt = "%s = %s([%s])"
+                fmt = "PyObject[] a_%s = {%s}; PyObject %s = new %s(a_%s);"
+                v = expr(op.result)
+                return fmt % (v, arglist(op.args), v,
+                              self.has_listarg[op.opname], v)
             else:
-                fmt = "%s = %s(%s)"
-            if op.opname == "is_true":
-                return fmt % (expr(op.result, False), expr(op.opname), arglist(op.args))    
-            return fmt % (expr(op.result), expr(op.opname), arglist(op.args))    
+                fmt = "PyObject %s = %s.op_%s(%s);"
+                return fmt % (expr(op.result), expr(op.args[0]),
+                              op.opname, arglist(op.args[1:]))
 
-        def gen_link(link, linklocalvars=None):
+        def gen_link(link, linklocalvars={}):
             "Generate the code to jump across the given Link."
-            linklocalvars = linklocalvars or {}
-            left, right = [], []
             for a1, a2 in zip(link.args, link.target.inputargs):
                 if a1 in linklocalvars:
                     src = linklocalvars[a1]
                 else:
                     src = expr(a1)
-                left.append(expr(a2))
-                right.append(src)
-            yield "%s = %s" % (", ".join(left), ", ".join(right))
+                yield "%s = %s;" % (expr(a2), src)
             goto = blocknum[link.target]
-            yield 'goto = %d' % goto
-            if goto <= blocknum[block]:
-                yield 'continue'
+            if goto == blocknum[block]+1:
+                yield '// falls through'
+            else:
+                yield 'block = %d;' % goto
+                yield 'continue;'
         
-        f = self.f
-        t = self.translator
-        #t.simplify(func)
-        graph = t.getflowgraph(func)
-
         start = graph.startblock
         blocks = ordered_blocks(graph)
         nblocks = len(blocks)
 
         blocknum = {}
+        localvars = []
         for block in blocks:
             blocknum[block] = len(blocknum)+1
+            if block is not start:
+                localvars += block.inputargs
 
         # create function declaration
-        name = func.__name__  # change this
-        args = [expr(var) for var in start.inputargs]
-        argstr = ", ".join(args)
-        print >> f, "def %s(space, %s):" % (name, argstr)
-        print >> f, "    w = space.wrap"
-        print >> f, "    goto = %d # startblock" % blocknum[start]
-        print >> f, "    while True:"
+        callpattern = "op_call_%d" % len(start.inputargs)
+        args = arglist(start.inputargs, prefix='PyObject ')
+        self.callpatterns[callpattern] = args
+        print >> f, "    PyObject %s(%s) {" % (callpattern, args)
+        for v in localvars:
+            print >> f, "        PyObject %s = null;" % v
+        print >> f, "        int block = %d; // startblock" % blocknum[start]
+        print >> f, "        while (true) switch (block) {"
         
         def render_block(block):
             catch_exception = block.exitswitch == Constant(last_exception)
@@ -560,7 +544,7 @@
                 yield "%s" % oper(op)
             # render the last op if it is exception handled
             for op in block.operations[regular_op:]:
-                yield "try:"
+                yield "try {"
                 yield "    %s" % oper(op)
 
             if len(block.exits) == 0:
@@ -568,11 +552,12 @@
                     # exceptional return block
                     exc_cls = expr(block.inputargs[0])
                     exc_val = expr(block.inputargs[1])
+                    XXX
                     yield "raise OperationError(%s, %s)" % (exc_cls, exc_val)
                 else:
                     # regular return block
                     retval = expr(block.inputargs[0])
-                    yield "return %s" % retval
+                    yield "return %s;" % retval
                 return
             elif block.exitswitch is None:
                 # single-exit block
@@ -580,6 +565,7 @@
                 for op in gen_link(block.exits[0]):
                     yield "%s" % op
             elif catch_exception:
+                XXX
                 # block catching the exceptions raised by its last operation
                 # we handle the non-exceptional case first
                 link = block.exits[0]
@@ -605,48 +591,29 @@
                     exits.reverse()
                 q = "if"
                 for link in exits[:-1]:
-                    yield "%s %s == %s:" % (q, expr(block.exitswitch),
-                                                     link.exitcase)
+                    yield "%s (%s.eq(%s)) {" % (q, expr(block.exitswitch),
+                                               self.nameof(link.exitcase))
                     for op in gen_link(link):
                         yield "    %s" % op
-                    q = "elif"
+                    yield "}"
+                    q = "else if"
                 link = exits[-1]
-                yield "else:"
-                yield "    assert %s == %s" % (expr(block.exitswitch),
-                                                    link.exitcase)
+                yield "else {"
+                yield "    // assert %s.eq(%s)" % (expr(block.exitswitch),
+                                                  self.nameof(link.exitcase))
                 for op in gen_link(exits[-1]):
                     yield "    %s" % op
+                yield "}"
 
         for block in blocks:
             blockno = blocknum[block]
             print >> f
-            print "        if goto == %d:" % blockno
+            print >> f, "        case %d:" % blockno
             for line in render_block(block):
-                print "            %s" % line
-
-def test_md5():
-    #import md5
-    # how do I avoid the builtin module?
-    from pypy.appspace import md5
-    digest = md5.new("hello")
-
-entry_point = (f, ff, fff, app_str_decode__String_ANY_ANY, app_mod__String_ANY, test_md5) [-1]
-
-import os, sys
-from pypy.interpreter import autopath
-srcdir = os.path.dirname(autopath.pypydir)
-appdir = os.path.join(autopath.pypydir, 'appspace')
-
-try:
-    hold = sys.path[:]
-    sys.path.insert(0, appdir)
-    t = Translator(entry_point, verbose=False, simplifying=True)
-    gen = GenRpy(sys.stdout, t)
-finally:
-    sys.path[:] = hold
-#t.simplify()
-#t.view()
-# debugging
-graph = t.getflowgraph()
-ab = ordered_blocks(graph) # use ctrl-b in PyWin with ab
+                print >> f, "            %s" % line
 
+        print >> f, "        }"
+        print >> f, "    }"
+        print >> f
+        print >> f, "};"
+        f.close()

Added: pypy/trunk/src/pypy/translator/java/test/test_javatrans.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/translator/java/test/test_javatrans.py	Fri Dec 17 10:18:02 2004
@@ -0,0 +1,54 @@
+import autopath, os
+from py.process import cmdexec 
+from pypy.tool import testit
+from pypy.tool.udir import udir
+from pypy.translator.java.genjava import GenJava
+from pypy.translator.test import snippet
+from pypy.translator.translator import Translator
+
+
+class NoTypeCGenTestCase(testit.IntTestCase):
+
+    def setUp(self):
+        self.space = testit.objspace('flow')
+
+    def build_jfunc(self, func):
+        try: func = func.im_func
+        except AttributeError: pass
+        t = Translator(func)
+        t.simplify()
+        name = func.func_name
+        self.jdir = udir.mkdir(name)
+        self.gen = GenJava(self.jdir, t)
+
+    def check(self, inputargs, expectedresult):
+        self.gen.gen_test_class(inputargs, expectedresult)
+        cwd = os.getcwd()
+        try:
+            os.chdir(str(self.jdir))
+            cmdexec('javac *.java')
+            self.assertEquals(cmdexec('java test').strip(), 'OK')
+        finally:
+            os.chdir(cwd)
+
+    def test_simple_func(self):
+        self.build_jfunc(snippet.simple_func)
+        self.check([123], 124)
+
+    def test_if_then_else(self):
+        self.build_jfunc(snippet.if_then_else)
+        self.check([2,3,4], 3)
+        self.check([0,3,4], 4)
+        self.check([-1,3,4], 3)
+
+    def test_two_plus_two(self):
+        self.build_jfunc(snippet.two_plus_two)
+        self.check([], 4)
+
+    def test_sieve_of_eratosthenes(self):
+        self.build_jfunc(snippet.sieve_of_eratosthenes)
+        self.check([], 1028)
+
+
+if __name__ == '__main__':
+    testit.main()



More information about the Pypy-commit mailing list