[pypy-svn] r6222 - pypy/branch/pypy-genc/translator

arigo at codespeak.net arigo at codespeak.net
Mon Aug 30 14:08:04 CEST 2004


Author: arigo
Date: Mon Aug 30 14:08:04 2004
New Revision: 6222

Modified:
   pypy/branch/pypy-genc/translator/genc.h
   pypy/branch/pypy-genc/translator/genc.py
   pypy/branch/pypy-genc/translator/typer.py
Log:
Slowly progressing...


Modified: pypy/branch/pypy-genc/translator/genc.h
==============================================================================
--- pypy/branch/pypy-genc/translator/genc.h	(original)
+++ pypy/branch/pypy-genc/translator/genc.h	Mon Aug 30 14:08:04 2004
@@ -34,9 +34,12 @@
 
 #define OP_IS_TRUE_oi(x,r,err)      if ((r=PyObject_IsTrue(x))<0)      goto err;
 #define OP_ADD_ooo(x,y,r,err)       if (!(r=PyNumber_Add(x,y)))        goto err;
+#define OP_MUL_ooo(x,y,r,err)       if (!(r=PyNumber_Mul(x,y)))        goto err;
 #define OP_MOD_ooo(x,y,r,err)       if (!(r=PyNumber_Remainder(x,y)))  goto err;
 #define OP_INPLACE_ADD_ooo(x,y,r,err) if(!(r=PyNumber_InPlaceAdd(x,y)))goto err;
 
+#define OP_GETITEM_ooo(x,y,r,err)   if (!(r=PyObject_GetItem(x,y)))    goto err;
+
 
 /*** conversions ***/
 

Modified: pypy/branch/pypy-genc/translator/genc.py
==============================================================================
--- pypy/branch/pypy-genc/translator/genc.py	(original)
+++ pypy/branch/pypy-genc/translator/genc.py	Mon Aug 30 14:08:04 2004
@@ -24,6 +24,10 @@
             return '<C: %s>' % ' '.join(self.impl)
 
 
+class TypingError(Exception):
+    pass
+
+
 class CTypeSet:
     "A (small) set of C types that typer.LLFunction can manipulate."
 
@@ -63,6 +67,15 @@
     def represent(self, hltype):
         return hltype.impl
 
+    def typingerror(self, opname, hltypes):
+        # build operations with a variable number of argument on demand
+        if opname == 'OP_NEWLIST':
+            opnewlist = self.lloperations.setdefault('OP_NEWLIST', {})
+            sig = (self.R_OBJECT,) * len(hltypes)
+            opnewlist[sig] = 'newlist', True
+            return   # retry
+        raise TypingError((opname,) + hltypes)
+
     # ____________________________________________________________
 
     def constant_representation(self, value):
@@ -84,8 +97,13 @@
                 # can convert the constant to a PyObject*
                 llname = 'convert_io(' + r.const + ', %s, %s)'
                 conv[r, self.R_OBJECT] = llname, True
+            elif value is None:
+                # can convert the constant to Py_None
+                r.const = 'Py_None'
+                llname = '%s = ' + r.const + ';'
+                conv[r, self.R_OBJECT] = llname, False
             else:
-                pass # XXX not implemented
+                print "// XXX not implemented: constant", key
             return r
 
     def parse_operation_templates(self):
@@ -178,6 +196,7 @@
         llfunc = self.llfunctions[func]
         llargs, rettype = llfunc.ll_header()
         l = ['%s %s' % (a.type, a.name) for a in llargs]
+        l = l or ['void']
         return '%s %s(%s)' % (rettype,
                               llfunc.name,
                               ', '.join(l))
@@ -230,23 +249,40 @@
                 seen[a] = True
         print >> f
 
+        # define special cases for some operations
+        def print_move(x, y):
+            print >> f, '\t%s = %s;' % (y, x)
+
+        def print_goto(lbl):
+            print >> f, '\tgoto %s;' % lbl
+
+        def print_returnerror():
+            v = llfunc.graph.getreturnvar()
+            hltype = self.typeset.gethltype(v)
+            print >> f, '\treturn %s;' % hltype.error_retval
+
+        def print_newlist(*args):
+            content = args[:-2]
+            result = args[-2]
+            err = args[-1]
+            print >> f, '\t%s = PyList_New(%d);' % (result, len(content))
+            print >> f, '\tif (!%s) goto %s;' % (result, err)
+            for i in range(len(content)):
+                print >> f, '\tPyList_SET_ITEM(%s, %d, %s); Py_INCREF(%s);' % (
+                    result, i, content[i], content[i])
+
         # print the body
         for line in body:
             if isinstance(line, LLOp):
                 args = [a.name for a in line.args]
                 if line.errtarget:
                     args.append(line.errtarget)
-                s = line.name
-                if s == 'move':
-                    print >> f, '\t%s = %s;' % (args[1], args[0])
-                elif s == 'goto':
-                    print >> f, '\tgoto %s;' % tuple(args)
-                elif s == 'returnerror':
-                    v = llfunc.graph.getreturnvar()
-                    hltype = self.typeset.gethltype(v)
-                    print >> f, '\treturn %s;' % hltype.error_retval
-                else:  # common case of operations
+                try:
+                    fn = locals()['print_' + line.name]
+                except KeyError:        # common case operations
                     print >> f, '\t' + s % tuple(args)
+                else:                   # special case operations
+                    fn(*args)
             elif line:  # label
                 print >> f, '   %s:' % line
             else:  # empty line

Modified: pypy/branch/pypy-genc/translator/typer.py
==============================================================================
--- pypy/branch/pypy-genc/translator/typer.py	(original)
+++ pypy/branch/pypy-genc/translator/typer.py	Mon Aug 30 14:08:04 2004
@@ -48,6 +48,11 @@
 #         'goto'        : fails unconditionally (i.e. jump to errlabel)
 #         'move'    x y : raw copy of the LLVar x to the LLVar y
 #         'returnerror' : return an error code from the function
+#
+#   def typingerror(self, opname, hltypes):
+#       Called when no match is found in lloperations.  This function must
+#       either extend lloperations and return (to retry), or raise an
+#       exception (to stop).
 # ____________________________________________________________
 
 
@@ -61,6 +66,7 @@
         self.gethltype    = typeset.gethltype
         self.represent    = typeset.represent
         self.lloperations = typeset.lloperations
+        self.typingerror  = typeset.typingerror
         self.hltypes = {}
         self.llreprs = {}
 
@@ -209,13 +215,18 @@
             args_t.append(self.hltypes[result])
             directions.append(self.convert_to)
         # enumerate possible signatures until we get a match
-        llsigs = self.lloperations[opname]
+        llsigs = self.lloperations.get(opname, {})
         for sig in variants(tuple(args_t), directions):
             if sig in llsigs:
                 llname, can_fail = llsigs[sig]
                 break
         else:
-            raise TypingError, (opname, args_t)
+            self.typingerror(opname, tuple(args_t))
+            # if 'typingerror' did not raise an exception, try again.
+            # infinite recursion here means that 'typingerror' did not
+            # correctly extend 'lloperations'.
+            self.operation(opname, args, result, errlabel)
+            return
         # convert input args to temporary variables
         llargs = []
         for v, v_t, s_t in zip(args, args_t, sig):
@@ -278,11 +289,6 @@
 
 # ____________________________________________________________
 
-
-class TypingError(Exception):
-    pass
-
-
 # In a function, all the variables that have to released can be organized
 # in a tree in which each node is a variable: whenever this variable has
 # to be released, its parent in the tree has to be release too, and its



More information about the Pypy-commit mailing list