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

arigo at codespeak.net arigo at codespeak.net
Sat Oct 9 10:44:34 CEST 2004


Author: arigo
Date: Sat Oct  9 10:44:33 2004
New Revision: 6876

Removed:
   pypy/trunk/src/pypy/translator/classtyper.py
   pypy/trunk/src/pypy/translator/genc_op.py
   pypy/trunk/src/pypy/translator/genc_repr.py
   pypy/trunk/src/pypy/translator/genc_typeset.py
   pypy/trunk/src/pypy/translator/typer.py
Modified:
   pypy/trunk/src/pypy/translator/genc.h
   pypy/trunk/src/pypy/translator/genc.py
   pypy/trunk/src/pypy/translator/test/test_ctrans.py
Log:
Deleted all the complicated genc_* and *typer sources.  There is only a
typeless genc.py left.  Getting it to work with types again should be done by
a preprocessor phase which updates the control flow graph before genc.py
translates it.



Deleted: /pypy/trunk/src/pypy/translator/classtyper.py
==============================================================================
--- /pypy/trunk/src/pypy/translator/classtyper.py	Sat Oct  9 10:44:33 2004
+++ (empty file)
@@ -1,161 +0,0 @@
-"""
-Extension to typer.py to preprocess class definitions and usage into
-lower-level field and function definitions.
-"""
-from __future__ import generators
-import re
-from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
-from pypy.objspace.flow.model import FunctionGraph, Block, Link
-from pypy.annotation import model as annmodel
-from pypy.translator.typer import LLTyper, LLFunction, LLVar
-from pypy.translator.genc_repr import R_OBJECT
-
-r_ends_in_underscore_digit = re.compile(r'_\d+$')
-
-# ____________________________________________________________
-
-class ClassField:
-    "An attribute of a class, mapped to some field(s) of a low-level struct."
-    
-    def __init__(self, hltype, name, llclass, is_class_attr):
-        self.hltype  = hltype
-        self.name    = name
-        self.llclass = llclass
-        self.is_class_attr = is_class_attr
-        varname = '%s_%s' % (llclass.field_prefix, name)
-        # to avoid name collisions between the 2nd lltype of a field called xyz
-        # and another field whose name is exactly xyz_1, forbid field names
-        # ending in '_\d+'
-        if r_ends_in_underscore_digit.search(name):
-            varname += '_'
-        # self.var is a Variable that can stand for this field
-        self.var = Variable(varname)
-        llclass.makevar(self.var, hltype=hltype)
-        # this (high-level) field is implemented as a list of LLVars
-        # that are real fields for the C struct
-        self.llvars = llclass.llreprs[self.var]
-
-    def getllvars(self, pattern='%s'):
-        """Return a list of fresh LLVars that implement the fields in this
-        C struct.  The name of the variables are %'ed with 'pattern',
-        which can be a C expression template to generate expressions to
-        access this field.
-        """
-        return [LLVar(x.type, pattern % x.name) for x in self.llvars]
-
-# ____________________________________________________________
-
-class LLClass(LLTyper):
-    """Low-level representation of a class as a structure and
-    global functions that operate on it."""
-    
-    def __init__(self, typeset, name, cdef, llparent):
-        LLTyper.__init__(self, typeset)
-        self.typeset = typeset
-        self.name = name
-        self.cdef = cdef    # instance of pypy.annotator.factory.ClassDef
-        self.llparent = llparent
-        self.bindings = typeset.bindings
-        self.s_instance = annmodel.SomeInstance(self.cdef)
-
-    def setup(self):
-        # two-phase initialization.  The code below might require other
-        # classes to be already present in GenC.llclasses.
-
-        # collect the fields that the annotator deduced for this class
-        typeset = self.typeset
-        cdef = self.cdef
-        cls = cdef.cls
-        mainletters = [c.lower() for c in cls.__name__ if 'A' <= c <= 'Z']
-        self.field_prefix = ''.join(mainletters[:3] or ['f'])
-        self.fields_here = []
-        for attr, s_value in cdef.attrs.items():
-            is_class_attr = cdef.readonly[attr]
-            hltype = typeset.gethltype(s_value, unbound=is_class_attr)
-            fld = ClassField(hltype, attr, self, is_class_attr)
-            self.fields_here.append(fld)
-        # fields are categorized as instance attributes and class attributes
-        # according to whether they are ever accessed with SET_ATTR or not
-        if self.llparent:
-            self.instance_fields = list(self.llparent.instance_fields)
-            self.class_fields    = list(self.llparent.class_fields)
-        else:
-            self.instance_fields = []
-            self.class_fields    = []
-        self.instance_fields += [fld for fld in self.fields_here
-                                 if not fld.is_class_attr]
-        self.class_fields    += [fld for fld in self.fields_here
-                                 if fld.is_class_attr]
-
-    def get_instance_field(self, name):
-        """Returns the ClassField corresponding to this attribute name.
-        Keep in mind that it might be from some parent LLClass."""
-        for fld in self.instance_fields:
-            if fld.name == name:
-                return fld
-        return None
-
-    def get_class_field(self, name):
-        """Returns the ClassField corresponding to this class attribute name.
-        Keep in mind that it might be from some parent LLClass."""
-        for fld in self.class_fields:
-            if fld.name == name:
-                return fld
-        return None
-
-    def get_management_functions(self):
-        "Generate LLFunctions that operate on this class' structure."
-        yield self.make_fn_new()
-        yield self.make_fn_typenew()
-
-    def build_llfunc(self, graph):
-        return LLFunction(self.typeset, graph.name, graph)
-
-    def put_op(self, b):
-        def op(opname, *args, **kw):
-            assert kw.keys() == ['s_result']
-            result = Variable()
-            self.bindings[result] = kw['s_result']
-            b.operations.append(SpaceOperation(opname, args, result))
-            return result
-        return op
-
-    def make_fn_new(self):
-        # generate the flow graph of the new_xxx() function
-        b = Block([])
-        op = self.put_op(b)
-        cls = self.cdef.cls
-        v1 = op('alloc_instance', Constant(cls),
-                s_result = self.s_instance)
-        # class attributes are used as defaults to initialize instance fields
-        for fld in self.instance_fields:
-            if hasattr(cls, fld.name):
-                value = getattr(cls, fld.name)
-                op('setattr', v1, Constant(fld.name), Constant(value),
-                   s_result = annmodel.SomeImpossibleValue())
-        # finally, return v1
-        graph = FunctionGraph('new_%s' % self.name, b)
-        self.bindings[graph.getreturnvar()] = self.bindings[v1]
-        b.closeblock(Link([v1], graph.returnblock))
-        return self.build_llfunc(graph)
-
-    def make_fn_typenew(self):
-        # generate the flow graph of the typenew_xxx() function that
-        # initializes the class attributes of the type object
-        b = Block([])
-        op = self.put_op(b)
-        cls = self.cdef.cls
-        v1 = Constant(cls)
-        # initialize class attributes
-        for fld in self.class_fields:
-            # some attributes might be missing from 'cls' if it is an abstract
-            # base class.  We left the field uninitialized in this case.
-            if hasattr(cls, fld.name):
-                value = getattr(cls, fld.name)
-                op('initclassattr', v1, Constant(fld.name), Constant(value),
-                   s_result = annmodel.SomeImpossibleValue())
-        # finally, return None
-        graph = FunctionGraph('typenew_%s' % self.name, b)
-        self.bindings[graph.getreturnvar()] = annmodel.immutablevalue(None)
-        b.closeblock(Link([Constant(None)], graph.returnblock))
-        return self.build_llfunc(graph)

Modified: pypy/trunk/src/pypy/translator/genc.h
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.h	(original)
+++ pypy/trunk/src/pypy/translator/genc.h	Sat Oct  9 10:44:33 2004
@@ -6,157 +6,56 @@
 #include <structmember.h>
 
 
-/*** operations on ints ***/
+#define op_richcmp(x,y,r,err,dir)   \
+                       if (!(r=PyObject_RichCompare(x,y,dir))) goto err;
+#define OP_LT(x,y,r,err)  op_richcmp(x,y,r,err, Py_LT)
+#define OP_LE(x,y,r,err)  op_richcmp(x,y,r,err, Py_LE)
+#define OP_EQ(x,y,r,err)  op_richcmp(x,y,r,err, Py_EQ)
+#define OP_NE(x,y,r,err)  op_richcmp(x,y,r,err, Py_NE)
+#define OP_GT(x,y,r,err)  op_richcmp(x,y,r,err, Py_GT)
+#define OP_GE(x,y,r,err)  op_richcmp(x,y,r,err, Py_GE)
+
+#define OP_IS_TRUE(x,r,err)	switch (PyObject_IsTrue(x)) {	\
+				case 0: r=Py_False; break;	\
+				case 1: r=Py_True;  break;	\
+				default: goto err;		\
+				}				\
+				Py_INCREF(r);
+
+#define OP_ADD(x,y,r,err)         if (!(r=PyNumber_Add(x,y)))        goto err;
+#define OP_SUB(x,y,r,err)         if (!(r=PyNumber_Subtract(x,y)))   goto err;
+#define OP_MUL(x,y,r,err)         if (!(r=PyNumber_Multiply(x,y)))   goto err;
+#define OP_DIV(x,y,r,err)         if (!(r=PyNumber_Divide(x,y)))     goto err;
+#define OP_MOD(x,y,r,err)         if (!(r=PyNumber_Remainder(x,y)))  goto err;
+#define OP_INPLACE_ADD(x,y,r,err) if(!(r=PyNumber_InPlaceAdd(x,y)))  goto err;
+
+#define OP_GETITEM(x,y,r,err)     if (!(r=PyObject_GetItem(x,y)))    goto err;
+#define OP_SETITEM(x,y,z,r,err)   if ((PyObject_SetItem(x,y,z))<0)   goto err; \
+				  r = NULL;
+
+#define OP_GETATTR(x,y,r,err)     if (!(r=PyObject_GetAttr(x,y)))    goto err;
+#define OP_SETATTR(x,y,z,r,err)   if ((PyObject_SetAttr(x,y,z))<0)   goto err; \
+				  r = NULL;
+#define OP_DELATTR(x,y,r,err)     if ((PyObject_SetAttr(x,y,NULL))<0)goto err; \
+				  r = NULL;
+
+#define OP_NEWSLICE(x,y,z,r,err)  if (!(r=PySlice_New(x,y,z)))       goto err;
 
-#define OP_LT_iii(x,y,r)           r = x < y;
-#define OP_LE_iii(x,y,r)           r = x <= y;
-#define OP_EQ_iii(x,y,r)           r = x == y;
-#define OP_NE_iii(x,y,r)           r = x != y;
-#define OP_GT_iii(x,y,r)           r = x > y;
-#define OP_GE_iii(x,y,r)           r = x >= y;
-
-#define OP_IS_TRUE_ii(x,r)         r = !(!x);
-
-#define OP_ADD_iii(x,y,r)          r = x + y;
-#define OP_SUB_iii(x,y,r)          r = x - y;
-#define OP_MUL_iii(x,y,r)          r = x * y;
-#define OP_DIV_iii(x,y,r)          r = x / y;
-#define OP_MOD_iii(x,y,r)          r = x % y;
-#define OP_INPLACE_ADD_iii(x,y,r)  r = x + y;
-
-
-/*** generic operations on PyObjects ***/
-
-#define op_richcmp_ooi(x,y,r,err,dir)   \
-                       if ((r=PyObject_RichCompareBool(x,y,dir))<0) goto err;
-#define OP_LT_ooi(x,y,r,err)  op_richcmp_ooi(x,y,r,err, Py_LT)
-#define OP_LE_ooi(x,y,r,err)  op_richcmp_ooi(x,y,r,err, Py_LE)
-#define OP_EQ_ooi(x,y,r,err)  op_richcmp_ooi(x,y,r,err, Py_EQ)
-#define OP_NE_ooi(x,y,r,err)  op_richcmp_ooi(x,y,r,err, Py_NE)
-#define OP_GT_ooi(x,y,r,err)  op_richcmp_ooi(x,y,r,err, Py_GT)
-#define OP_GE_ooi(x,y,r,err)  op_richcmp_ooi(x,y,r,err, Py_GE)
-
-#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_SUB_ooo(x,y,r,err)       if (!(r=PyNumber_Subtract(x,y)))   goto err;
-#define OP_MUL_ooo(x,y,r,err)       if (!(r=PyNumber_Multiply(x,y)))   goto err;
-#define OP_DIV_ooo(x,y,r,err)       if (!(r=PyNumber_Divide(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;
-#define OP_SETITEM_ooov(x,y,z,err)  if ((PyObject_SetItem(x,y,z))<0)   goto err;
-#define OP_GETATTR_ooo(x,y,r,err)   if (!(r=PyObject_GetAttr(x,y)))    goto err;
-#define OP_SETATTR_ooov(x,y,z,err)  if ((PyObject_SetAttr(x,y,z))<0)   goto err;
-#define OP_DELATTR_oov(x,y,err)     if ((PyObject_SetAttr(x,y,NULL))<0)goto err;
-#define OP_NEWSLICE_oooo(x,y,z,r,err)  if (!(r=PySlice_New(x,y,z)))    goto err;
-
-/* temporary hack */
-#define OP_GETITEM_ooi(x,y,r,err)   {                           \
-  PyObject* o = PyObject_GetItem(x,y);                          \
-  if (!o) goto err;                                             \
-  if ((r=PyInt_AsLong(o)) == -1 && PyErr_Occurred()) goto err;  \
-}
-
-
-/*** conversions ***/
-
-#define CONVERT_io(x,r,err)   if (!(r=PyInt_FromLong(x))) goto err;
-#define CONVERT_so(c,l,r,err) if (!(r=PyString_FromStringAndSize(c,l)))goto err;
-#define CONVERT_vo(r)         r = Py_None; Py_INCREF(r);
-
-/*#define convert_oi(x,r,err)   if ((r=PyInt_AsLong(x)) == -1             \
- *                                  && PyErr_Occurred()) goto err;
- * -- should be done differently */
 
 /*** tests ***/
 
-#define CASE_False_i(n, err)    if (n) goto err;
-#define CASE_True_i(n, err)     if (!n) goto err;
-#define CASE_0_i(n, err)        if (n != 0) goto err;
-#define CASE_1_i(n, err)        if (n != 1) goto err;
-
-#define CASE_False_o(o, err)    if (!(PyInt_Check(o) && !PyInt_AS_LONG(o))) goto err;
-#define CASE_True_o(o, err)     if (!(PyInt_Check(o) && PyInt_AS_LONG(o))) goto err;
-#define CASE_0_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==0)) goto err;
-#define CASE_1_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==1)) goto err;
+#define EQ_False(o)     (o == Py_False)
+#define EQ_True(o)      (o == Py_True)
+#define EQ_0(o)         (PyInt_Check(o) && PyInt_AS_LONG(o)==0)
+#define EQ_1(o)         (PyInt_Check(o) && PyInt_AS_LONG(o)==1)
 
 
 /*** misc ***/
 
-#define OP_EXCEPTION_ov(x)    /* XXX exceptions not implemented */
+#define OP_EXCEPTION(x,r,err)  r = NULL;  /* XXX exceptions not implemented */
+
+#define MOVE(x, y)             y = x;
 
-#define OP_ALLOC_AND_SET_ioo(l,o,r,err)  {              \
-		int i;                                  \
-		if (!(r = PyList_New(l))) goto err;     \
-		for (i=l; --i >= 0; ) {                 \
-			PyList_SET_ITEM(r, i, o);       \
-			Py_INCREF(o);                   \
-		}                                       \
-	}
-
-/* a few built-in functions */
-
-#define CALL_len_oi(o,r,err)  if ((r=PyObject_Size(o))<0) goto err;
-#define CALL_pow_iii(x,y,r)   { int i=y; r=1; while (--i>=0) r*=x; } /*slow*/
-
-
-/*** macros used directly by genc_op.py ***/
-
-#define OP_NEWLIST(len, r, err)        if (!(r=PyList_New(len))) goto err;
-#define OP_NEWLIST_SET(r, i, o)        PyList_SET_ITEM(r, i, o); Py_INCREF(o);
-#define OP_NEWTUPLE(len, r, err)       if (!(r=PyTuple_New(len))) goto err;
-#define OP_NEWTUPLE_SET(r, i, o)       PyTuple_SET_ITEM(r, i, o); Py_INCREF(o);
-
-#define OP_CALL_PYOBJ(args, r, err)    if (!(r=PyObject_CallFunction args)) \
-						goto err;
-
-#define OP_INSTANTIATE(cls, r, err)    if (!(r=new_##cls())) goto err;
-#define ALLOC_INSTANCE(cls, r, err)                             \
-		if (!(r=PyType_GenericAlloc(&g_Type_##cls.type, 0))) goto err;
-#define SETUP_TYPE(cls)                         \
-		PyType_Ready(&g_Type_##cls.type); \
-		typenew_##cls();
-
-#define OP_GETINSTATTR(cls,o,f,r)    r=((PyObj_##cls*) o)->f;
-#define OP_GETINSTATTR_o(cls,o,f,r)  r=((PyObj_##cls*) o)->f; Py_INCREF(r);
-#define OP_GETCLASSATTR(cls,o,f,r)   r=((PyTypeObject_##cls*)(o->ob_type))->f;
-#define OP_GETCLASSATTR_o(cls,o,f,r) r=((PyTypeObject_##cls*)(o->ob_type))->f;\
-								  Py_INCREF(r);
-#define OP_SETINSTATTR(cls, o, f, v)    ((PyObj_##cls*) o)->f=v;
-#define OP_SETINSTATTR_o(cls, o, f, v)  { PyObject* tmp;                    \
-					  OP_GETINSTATTR(cls, o, f, tmp)    \
-					  OP_SETINSTATTR(cls, o, f, v)      \
-					  Py_INCREF(v); Py_XDECREF(tmp);    \
-					}
-#define OP_INITCLASSATTR(cls, f, v)     g_Type_##cls.f=v;
-#define OP_INITCLASSATTR_o(cls, f, v)   g_Type_##cls.f=v; Py_INCREF(v);
-
-#define OP_DUMMYREF(r)                  r = Py_None; Py_INCREF(r);
-
-#define MOVE(x, y)                      y = x;
-
-#define OP_CCALL_v(fn, args, err)       if (fn args < 0) goto err;
-#define OP_CCALL(fn, args, r, err)      if ((r=fn args) == NULL) goto err;
-#define OP_CCALL_i(fn, args, r, err)    if ((r=fn args) == -1 &&            \
-                                            PyErr_Occurred()) goto err;
-
-#define OP_NEWARRAY(name,len,r,err)   if (!(r=alloclist_##name(len))) goto err;
-#define OP_NEWARRAY_SET(name,a,i,f,v)   ((PyList_##name*) a)->ob_item[i].f=v;
-#define OP_NEWARRAY_SET_o(name,a,i,f,v) ((PyList_##name*) a)->ob_item[i].f=v; \
-								  Py_INCREF(v);
-#define OP_GETARRAYITEM(name,a,i,f,r)   r=((PyList_##name*) a)->ob_item[i].f;
-#define OP_GETARRAYITEM_o(name,a,i,f,r) r=((PyList_##name*) a)->ob_item[i].f; \
-								  Py_INCREF(r);
-#define OP_SETARRAYITEM(name,a,i,f,v)   ((PyList_##name*) a)->ob_item[i].f=v;
-#define OP_SETARRAYITEM_o(name,a,i,f,v) { PyObject* tmp;                    \
-					  OP_GETARRAYITEM(name,a,i,f,tmp)   \
-					  OP_SETARRAYITEM(name,a,i,f,v)     \
-					  Py_INCREF(v); Py_DECREF(tmp);     \
-					}
-#define ARRAYLEN(a)                    (((PyVarObject*) a)->ob_size)
-#define OP_ARRAYLEN(a,r)               r=ARRAYLEN(a);
-#define OP_GROWLIST(name,a,l,err)      if (growlist_##name(a,l) < 0) goto err;
 
 /************************************************************/
  /***  The rest is produced by genc.py                     ***/

Modified: pypy/trunk/src/pypy/translator/genc.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.py	(original)
+++ pypy/trunk/src/pypy/translator/genc.py	Sat Oct  9 10:44:33 2004
@@ -6,11 +6,7 @@
 import autopath, os
 from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
 from pypy.objspace.flow.model import FunctionGraph, Block, Link
-from pypy.translator.typer import LLFunction, LLOp, LLVar, LLConst
-from pypy.translator.classtyper import LLClass
-from pypy.translator.genc_typeset import CTypeSet
-from pypy.translator.genc_op import ERROR_RETVAL
-from pypy.translator.genc_repr import R_INT, R_OBJECT, cdecl
+from pypy.objspace.flow.model import traverse, uniqueitems
 
 # ____________________________________________________________
 
@@ -33,323 +29,200 @@
         self.translator = translator
         self.modname = (modname or
                         uniquemodulename(translator.functions[0].__name__))
-        if translator.annotator:
-            bindings = translator.annotator.bindings.copy()
-        else:
-            bindings = {}
-        self.typeset = CTypeSet(self, bindings)
-        self.initializationcode = []
-        self.llclasses = {};   self.classeslist = []
-        self.llfunctions = {}; self.functionslist = []
-        self.llarrays = {}
-        # must build functions first, otherwise methods are not found
-        self.build_llfunctions()
-        self.build_llclasses()
-        self.build_llentrypoint()
+        self.cnames = {}
+        self.seennames = {}
+        self.initcode = []
+        self.globaldecl = []
+        self.pendingfunctions = []
         self.gen_source()
 
+    def nameof(self, obj):
+        key = type(obj), obj   # to avoid confusing e.g. 0 and 0.0
+        try:
+            return self.cnames[key]
+        except KeyError:
+            for cls in type(obj).__mro__:
+                meth = getattr(self, 'nameof_' + cls.__name__, None)
+                if meth:
+                    break
+            else:
+                raise TypeError, "nameof(%r)" % (obj,)
+            name = meth(obj)
+            self.cnames[key] = name
+            return name
+
+    def uniquename(self, basename):
+        name = basename
+        i = 0
+        while name in self.seennames:
+            i += 1
+            name = '%s_%d' % (basename, i)
+        self.seennames[name] = True
+        return name
+
+    def nameof_int(self, value):
+        if value >= 0:
+            name = 'gint_%d' % value
+        else:
+            name = 'gint_minus%d' % abs(value)
+        self.globaldecl.append('static PyObject* %s;' % name)
+        self.initcode.append('%s = PyInt_FromLong(%d);' % (name, value))
+        return name
+
+    def nameof_function(self, func):
+        name = self.uniquename('gfunc_' + func.__name__)
+        self.globaldecl.append('static PyObject* %s;' % name)
+        self.initcode.append('%s = PyCFunction_New(&ml_%s, NULL);' % (name,
+                                                                      name))
+        self.pendingfunctions.append(func)
+        return name
+
     def gen_source(self):
         f = self.f
         info = {
             'modname': self.modname,
-            'exported': self.translator.functions[0].__name__,
+            'entrypointname': self.translator.functions[0].__name__,
+            'entrypoint': self.nameof(self.translator.functions[0]),
             }
         # header
         print >> f, self.C_HEADER
 
-        # forward declarations
-        print >> f, '/* forward declarations */'
-        for llfunc in self.functionslist:
-            print >> f, '%s;' % self.cfunction_header(llfunc)
-        print >> f
-
-        # declaration of class structures
-        for llclass in self.classeslist:
-            self.gen_cclass(llclass)
-
-        # function implementation
-        print >> f, self.C_SEP
-        print >> f
-        for llfunc in self.functionslist:
-            self.gen_cfunction(llfunc)
-            print >> f
-
-        # entry point
-        print >> f, self.C_SEP
-        print >> f, self.C_ENTRYPOINT_HEADER % info
-        self.gen_entrypoint()
-        print >> f, self.C_ENTRYPOINT_FOOTER % info
+        # function implementations
+        for func in self.pendingfunctions:
+            self.gen_cfunction(func)
 
         # footer
-        print >> f, self.C_METHOD_TABLE % info
         print >> f, self.C_INIT_HEADER % info
-        for codeline in self.initializationcode:
+        for codeline in self.initcode:
             print >> f, '\t' + codeline
         print >> f, self.C_INIT_FOOTER % info
 
-
-    def build_llclasses(self):
-        if not self.translator.annotator:
-            return
-        n = 0
-        for cdef in self.translator.annotator.getuserclassdefinitions():
-            # annotation.factory guarantees that this will enumerate
-            # the ClassDefs in a parent-first, children-last order.
-            cls = cdef.cls
-            assert cls not in self.llclasses, '%r duplicate' % (cls,)
-            if cdef.basedef is None:
-                llparent = None
-            else:
-                llparent = self.llclasses[cdef.basedef.cls]
-            llclass = LLClass(
-                typeset = self.typeset,
-                name = '%s__%d' % (cls.__name__, n),
-                cdef = cdef,
-                llparent = llparent,
-                )
-            self.llclasses[cls] = llclass
-            self.classeslist.append(llclass)
-            n += 1
-        for llclass in self.classeslist:
-            llclass.setup()
-        management_functions = []
-        for llclass in self.classeslist:
-            management_functions += llclass.get_management_functions()
-        self.functionslist[:0] = management_functions
-
-    def build_llfunctions(self):
-        n = 0
-        for func in self.translator.functions:
-            assert func not in self.llfunctions, '%r duplicate' % (func,)
-            llfunc = LLFunction(
-                typeset = self.typeset,
-                name    = 'f%d_%s' % (n, func.func_name),
-                graph   = self.translator.flowgraphs[func])
-            self.llfunctions[func] = llfunc
-            self.functionslist.append(llfunc)
-            n += 1
-
-    def build_llentrypoint(self):
-        # create a LLFunc that calls the entry point function and returns
-        # whatever it returns, but converted to PyObject*.
-        main = self.translator.functions[0]
-        llmain = self.llfunctions[main]
-        inputargs = llmain.graph.getargs()
-        b = Block(inputargs)
-        v1 = Variable()
-        b.operations.append(SpaceOperation('simple_call',
-                                           [Constant(main)] + inputargs,
-                                           v1))
-        # finally, return v1
-        graph = FunctionGraph('entry_point', b)
-        b.closeblock(Link([v1], graph.returnblock))
-        llfunc = LLFunction(self.typeset, graph.name, graph)
-        self.functionslist.append(llfunc)
-
-    def get_llfunc_header(self, llfunc):
-        llargs, llret = llfunc.ll_header()
-        if len(llret) == 0:
-            retlltype = None
-        elif len(llret) == 1:
-            retlltype = llret[0].type
-        else:
-            # if there is more than one return LLVar, only the first one is
-            # returned and the other ones are returned via ptr output args
-            retlltype = llret[0].type
-            llargs += [LLVar(a.type, '*output_'+a.name) for a in llret[1:]]
-        return llargs, retlltype
-
-    def cfunction_header(self, llfunc):
-        llargs, rettype = self.get_llfunc_header(llfunc)
-        l = [cdecl(a.type, a.name) for a in llargs]
-        l = l or ['void']
-        return 'static ' + cdecl(rettype or 'int',
-                                 '%s(%s)' % (llfunc.name, ', '.join(l)))
-
-    def gen_entrypoint(self):
-        f = self.f
-        llfunc = self.functionslist[-1]
-        llargs, rettype = self.get_llfunc_header(llfunc)
-        assert llfunc.name == 'entry_point', llfunc.name
-        assert rettype == 'PyObject*', rettype
-        l = []
-        l2 = []
-        for a in llargs:
-            print >> f, '\t%s;' % cdecl(a.type, a.name)
-            l.append('&' + a.name)
-            l2.append(a.name)
-        formatstr = []
-        for v in llfunc.graph.getargs():
-            hltype = self.typeset.gethltype(v)
-            assert hltype.parse_code, (
-                "entry point arg %s has unsupported type %s" % (v, hltype))
-            formatstr.append(hltype.parse_code)
-        l.insert(0, '"' + ''.join(formatstr) + '"')
-        print >> f, '\tif (!PyArg_ParseTuple(args, %s))' % ', '.join(l)
-        print >> f, '\t\treturn NULL;'
-        print >> f, '\treturn entry_point(%s);' % (', '.join(l2))
-
-    def gen_cfunction(self, llfunc):
+    def gen_cfunction(self, func):
         f = self.f
-
-        # generate the body of the function
-        llargs, rettype = self.get_llfunc_header(llfunc)
-        error_retval = LLConst(rettype, ERROR_RETVAL.get(rettype, 'NULL'))
-        body = list(llfunc.ll_body([error_retval]))
-
-        # print the declaration of the new global constants needed by
-        # the current function
-        to_declare = []
-        for line in body:
-            if isinstance(line, LLOp):
-                for a in line.using():
-                    if isinstance(a, LLConst) and a.to_declare:
-                        to_declare.append(a)
-                        if a.initexpr:
-                            self.initializationcode.append('%s = %s;' % (
-                                a.name, a.initexpr))
-                        a.to_declare = False
-        if to_declare:
-            print >> f, '/* global constant%s */' % ('s'*(len(to_declare)>1))
-            for a in to_declare:
-                print >> f, 'static %s;' % cdecl(a.type, a.name)
+        body = list(self.cfunction_body(func))
+        g = self.globaldecl
+        if g:
+            print >> f, '/* global declaration%s */' % ('s'*(len(g)>1))
+            for line in g:
+                print >> f, line
             print >> f
+            del g[:]
 
         # print header
-        print >> f, self.cfunction_header(llfunc)
+        name = self.nameof(func)
+        assert name.startswith('gfunc_')
+        f_name = 'f_' + name[6:]
+        print >> f, 'static PyObject* %s(PyObject* self, PyObject* args)' % (
+            f_name,)
         print >> f, '{'
 
-        # collect and print all the local variables from the body
-        lllocals = []
-        for line in body:
-            if isinstance(line, LLOp):
-                lllocals += line.using()
-        seen = {}
-        for a in llargs:
-            seen[a] = True
-        for a in lllocals:
-            if a not in seen:
-                if not isinstance(a, LLConst):
-                    print >> f, '\t%s;' % cdecl(a.type, a.name)
-                seen[a] = True
+        # collect and print all the local variables
+        graph = self.translator.flowgraphs[func]
+        localslst = []
+        def visit(node):
+            if isinstance(node, Block):
+                localslst.extend(node.getvariables())
+        traverse(visit, graph)
+        for a in uniqueitems(localslst):
+            print >> f, '\tPyObject* %s;' % a.name
         print >> f
 
+        # argument unpacking
+        lst = ['"' + 'O'*len(graph.getargs()) + '"']
+        lst += ['&' + a.name for a in graph.getargs()]
+        print >> f, '\tif (!PyArg_ParseTuple(args, %s))' % ', '.join(lst)
+        print >> f, '\t\treturn NULL;'
+
         # print the body
         for line in body:
-            if isinstance(line, LLOp):
-                code = line.write()
-                if code:
-                    for codeline in code.split('\n'):
-                        print >> f, '\t' + codeline
-            elif line:  # label
-                print >> f, '   %s:' % line
-            else:  # empty line
-                print >> f
+            if line.endswith(':'):
+                line = '    ' + line
+            else:
+                line = '\t' + line
+            print >> f, line
         print >> f, '}'
 
-    def gen_cclass(self, llclass):
-        f = self.f
-        cls = llclass.cdef.cls
-        info = {
-            'module': cls.__module__,
-            'basename': cls.__name__,
-            'name': llclass.name,
-            'base': '0',
-            }
-        if llclass.llparent is not None:
-            info['base'] = '&g_Type_%s.type' % llclass.llparent.name
+        # print the PyMethodDef
+        print >> f, 'static PyMethodDef ml_%s = { "%s", %s, METH_VARARGS };' % (
+            name, func.__name__, f_name)
+        print >> f
 
-        # print the C struct declaration
-        print >> f, self.C_STRUCT_HEADER % info
-        for fld in llclass.instance_fields:
-            for llvar in fld.llvars:
-                print >> f, '\t%s;' % cdecl(llvar.type, llvar.name)
-        print >> f, self.C_STRUCT_FOOTER % info
-
-        # print the struct PyTypeObject_Xxx, which is an extension of
-        # PyTypeObject with the class attributes of this class
-        print >> f, self.C_TYPESTRUCT_HEADER % info
-        for fld in llclass.class_fields:
-            for llvar in fld.llvars:
-                print >> f, '\t%s;' % cdecl(llvar.type, llvar.name)
-        print >> f, self.C_TYPESTRUCT_FOOTER % info
-
-        # generate the deallocator function -- must special-case it;
-        # other functions are generated by LLClass.get_management_functions()
-        print >> f, self.C_DEALLOC_HEADER % info
-        llxdecref = self.typeset.rawoperations['xdecref']
-        for fld in llclass.instance_fields:
-            llvars = fld.getllvars('op->%s')
-            line = llxdecref(llvars)
-            code = line.write()
-            if code:
-                for codeline in code.split('\n'):
-                    print >> f, '\t' + codeline
-        print >> f, self.C_DEALLOC_FOOTER % info
-
-        # generate the member list for the type object
-        print >> f, self.C_MEMBERLIST_HEADER % info
-        # XXX write member definitions for member with well-known types only
-        #     members from the parents are inherited via tp_base
-        for fld in llclass.fields_here:
-            if fld.is_class_attr:
-                continue   # XXX should provide a reader
-            if fld.hltype == R_OBJECT:
-                t = 'T_OBJECT_EX'
-            elif fld.hltype == R_INT:
-                t = 'T_INT'
+    def cfunction_body(self, func):
+        graph = self.translator.flowgraphs[func]
+        blocknum = {}
+        allblocks = []
+
+        def expr(v):
+            if isinstance(v, Variable):
+                return v.name
+            elif isinstance(v, Constant):
+                return self.nameof(v.value)
             else:
-                continue   # ignored
-            print >> f, '\t{"%s",\t%s,\toffsetof(PyObj_%s, %s)},' % (
-                fld.name, t, llclass.name, fld.llvars[0].name)
-        print >> f, self.C_MEMBERLIST_FOOTER % info
-
-        # declare and initialize the static PyTypeObject
-        print >> f, self.C_TYPEOBJECT % info
-
-        self.initializationcode.append('SETUP_TYPE(%s)' % llclass.name)
-
-    def declare_list(self, lltypes):
-        # called by genc_typer.py to write the type definition of a list
-        # as an array of "struct { lltypes };"
-        lltypes = tuple(lltypes)
-        if lltypes in self.llarrays:
-            return self.llarrays[lltypes]   # already seen
-
-        s = '_'.join(lltypes)
-        name = ''.join([('a'<=c<='z' or
-                         'A'<=c<='Z' or
-                         '0'<=c<='9') and c or '_'
-                        for c in s])
-        name = name or 'void'
-        name += '_%d' % len(self.llarrays)
-        self.llarrays[lltypes] = name
-        
-        f = self.f
-        info = {
-            'name': name,
-            }
-        print >> f, self.C_LIST_HEADER % info
-        llvars1 = []
-        for i in range(len(lltypes)):
-            print >> f, '\t%s;' % cdecl(lltypes[i], 'a%d'%i)
-            llvars1.append(LLVar(lltypes[i], 'item->a%d'%i))
-        print >> f, self.C_LIST_FOOTER % info
-
-        print >> f, self.C_LIST_DEALLOC_HEADER % info
-        lldecref = self.typeset.rawoperations['decref']
-        line = lldecref(llvars1)
-        code = line.write()
-        if code:
-            print >> f, self.C_LIST_DEALLOC_LOOP_HEADER % info
-            for codeline in code.split('\n'):
-                print >> f, '\t\t' + codeline
-            print >> f, self.C_LIST_DEALLOC_LOOP_FOOTER % info
-        print >> f, self.C_LIST_DEALLOC_FOOTER % info
-
-        print >> f, self.C_LIST_TYPEOBJECT % info
+                raise TypeError, "expr(%r)" % (v,)
 
-        return name
+        def gen_link(link):
+            "Generate the code to jump across the given Link."
+            has_ref = {}
+            for v in to_release:
+                has_ref[v] = True
+            for a1, a2 in zip(link.args, link.target.inputargs):
+                line = 'MOVE(%s, %s)' % (expr(a1), a2.name)
+                if a1 in has_ref:
+                    del has_ref[a1]
+                else:
+                    line += '\tPy_INCREF(%s);' % a2.name
+                yield line
+            for v in to_release:
+                if v in has_ref:
+                    yield 'Py_XDECREF(%s);' % v.name
+            yield 'goto block%d;' % blocknum[link.target]
+
+        # collect all blocks
+        def visit(block):
+            if isinstance(block, Block):
+                allblocks.append(block)
+                blocknum[block] = len(blocknum)
+        traverse(visit, graph)
+
+        # generate an incref for each input argument
+        for v in graph.getargs():
+            yield 'Py_INCREF(%s);' % v.name
+
+        # generate the body of each block
+        for block in allblocks:
+            yield ''
+            yield 'block%d:' % blocknum[block]
+            to_release = list(block.inputargs)
+            for op in block.operations:
+                lst = [expr(v) for v in op.args]
+                lst.append(op.result.name)
+                lst.append('err%d_%d' % (blocknum[block], len(to_release)))
+                yield 'OP_%s(%s)' % (op.opname.upper(), ', '.join(lst))
+                to_release.append(op.result)
+
+            if len(block.exits) == 0:
+                yield 'return %s;' % expr(block.inputargs[0])
+                continue
+            if block.exitswitch is not None:
+                for link in block.exits[:-1]:
+                    yield 'if (EQ_%s(%s)) {' % (link.exitcase,
+                                                block.exitswitch.name)
+                    for op in gen_link(link):
+                        yield '\t' + op
+                    yield '}'
+                link = block.exits[-1]
+                yield 'assert(EQ_%s(%s));' % (link.exitcase,
+                                              block.exitswitch.name)
+            for op in gen_link(block.exits[-1]):
+                yield op
+
+            yield ''
+            to_release.pop()  # this label is never reachable
+            while to_release:
+                n = len(to_release)
+                v = to_release.pop()
+                yield 'err%d_%d: Py_XDECREF(%s);' % (blocknum[block], n, v.name)
+            yield 'return NULL;'
 
 # ____________________________________________________________
 
@@ -357,205 +230,26 @@
 
     C_SEP = "/************************************************************/"
 
-    C_ENTRYPOINT_HEADER = '''
-static PyObject* c_%(exported)s(PyObject* self, PyObject* args)
-{'''
-
-    C_ENTRYPOINT_FOOTER = '''}'''
-
-    C_METHOD_TABLE = '''
-static PyMethodDef g_methods_%(modname)s[] = {
-\t{"%(exported)s", (PyCFunction)c_%(exported)s, METH_VARARGS},
-\t{NULL, NULL}
-};'''
+    C_INIT_HEADER = C_SEP + '''
 
-    C_INIT_HEADER = '''
 void init%(modname)s(void)
 {
-\tPy_InitModule("%(modname)s", g_methods_%(modname)s);'''
-
-    C_INIT_FOOTER = '''}'''
-
-    C_STRUCT_HEADER = C_SEP + '''
-/*** Definition of class %(module)s.%(basename)s ***/
-
-typedef struct {
-	PyObject_HEAD'''
-
-    C_STRUCT_FOOTER = '''} PyObj_%(name)s;
-'''
-
-    C_DEALLOC_HEADER = '''static void dealloc_%(name)s(PyObj_%(name)s* op)
-{'''
-
-    C_DEALLOC_FOOTER = '''	PyObject_Del((PyObject*) op);
-}
+\tPyObject* m = Py_InitModule("%(modname)s", NULL);
 '''
 
-    C_MEMBERLIST_HEADER = '''static PyMemberDef g_memberlist_%(name)s[] = {'''
-
-    C_MEMBERLIST_FOOTER = '''	{NULL}	/* Sentinel */
-};
-'''
-
-    # NB: our types don't have Py_TPFLAGS_BASETYPE because we do not want
-    #     the complications of dynamically created subclasses.  This doesn't
-    #     prevent the various types from inheriting from each other via
-    #     tp_base.  This is ok because we expect all RPython classes to exist
-    #     and be analyzed in advance.  This allows class attributes to be stored
-    #     as an extensison of the PyTypeObject structure, which are then
-    #     accessed with ((PyTypeObject_Xxx*)op->ob_type)->classattrname.
-    #     This doesn't work if op->ob_type can point to a heap-allocated
-    #     type object over which we have no control.
-
-    C_TYPESTRUCT_HEADER = '''typedef struct {
-	PyTypeObject type;
-	/* class attributes follow */'''
-
-    C_TYPESTRUCT_FOOTER = '''} PyTypeObject_%(name)s;
-'''
-
-    C_TYPEOBJECT = '''static PyTypeObject_%(name)s g_Type_%(name)s = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
-	"%(name)s",
-	sizeof(PyObj_%(name)s),
-	0,
-	(destructor)dealloc_%(name)s,		/* tp_dealloc */
-	0,					/* tp_print */
-	0,					/* tp_getattr */
-	0,					/* tp_setattr */
-	0,					/* tp_compare */
-	0,					/* tp_repr */
-	0,					/* tp_as_number */
-	0,					/* tp_as_sequence */
-	0,					/* tp_as_mapping */
-	0,					/* tp_hash */
-	0,					/* tp_call */
-	0,					/* tp_str */
-	PyObject_GenericGetAttr,		/* tp_getattro */
-	PyObject_GenericSetAttr,		/* tp_setattro */
-	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
- 	0,					/* tp_doc */
- 	0,	/* XXX need GC */		/* tp_traverse */
- 	0,					/* tp_clear */
-	0,					/* tp_richcompare */
-	0,					/* tp_weaklistoffset */
-	0,					/* tp_iter */
-	0,					/* tp_iternext */
-	0,					/* tp_methods */
-	g_memberlist_%(name)s,			/* tp_members */
-	0,					/* tp_getset */
-	%(base)s,				/* tp_base */
-	0,					/* tp_dict */
-	0,					/* tp_descr_get */
-	0,					/* tp_descr_set */
-	0,					/* tp_dictoffset */
-	0,  /* XXX call %(name)s_new() */	/* tp_init */
-	PyType_GenericAlloc,			/* tp_alloc */
-	PyType_GenericNew,			/* tp_new */
-	PyObject_Del,				/* tp_free */
-};
-'''
-
-    C_LIST_HEADER = '''/* the type "list of %(name)s" */
-typedef struct {'''
-
-    C_LIST_FOOTER = '''} ListItem_%(name)s;
-
-typedef struct {
-	PyObject_VAR_HEAD
-	ListItem_%(name)s* ob_item;
-} PyList_%(name)s;
-'''
-
-    C_LIST_DEALLOC_HEADER = (
-'''static void dealloclist_%(name)s(PyList_%(name)s* op)
-{''')
-
-    C_LIST_DEALLOC_LOOP_HEADER = (
-'''	int i = op->ob_size;
-	ListItem_%(name)s* item = op->ob_item + i;
-	while (--i >= 0) {
-		--item;''')
-
-    C_LIST_DEALLOC_LOOP_FOOTER = (
-'''	}''')
-
-    C_LIST_DEALLOC_FOOTER = (
-'''	PyMem_Free(op->ob_item);
-	PyObject_Del((PyObject*) op);
-}
-''')
-
-    C_LIST_TYPEOBJECT = '''static PyTypeObject g_ListType_%(name)s = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
-	"list of %(name)s",
-	sizeof(PyList_%(name)s),
-	0,
-	(destructor)dealloclist_%(name)s,	/* tp_dealloc */
-	0,					/* tp_print */
-	0,					/* tp_getattr */
-	0,					/* tp_setattr */
-	0,					/* tp_compare */
-	0,					/* tp_repr */
-	0,					/* tp_as_number */
-	0,					/* tp_as_sequence */
-	0,					/* tp_as_mapping */
-	0,					/* tp_hash */
-	0,					/* tp_call */
-	0,					/* tp_str */
-	PyObject_GenericGetAttr,		/* tp_getattro */
-	0,					/* tp_setattro */
-	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
- 	0,					/* tp_doc */
- 	0,	/* XXX need GC */		/* tp_traverse */
- 	0,					/* tp_clear */
-};
-
-static PyObject* alloclist_%(name)s(int len)
-{
-	void* buffer;
-	PyList_%(name)s* o;
-
-	if (len > 0) {
-		buffer = PyMem_Malloc(len * sizeof(ListItem_%(name)s));
-		if (buffer == NULL) {
-			PyErr_NoMemory();
-			return NULL;
-		}
-	}
-	else
-		buffer = NULL;
-
-	o = PyObject_New(PyList_%(name)s, &g_ListType_%(name)s);
-	if (o != NULL) {
-		o->ob_size = len;
-		o->ob_item = (ListItem_%(name)s*) buffer;
-	}
-	else {
-		PyMem_Free(buffer);
-	}
-	return (PyObject*) o;
-}
-
-static int growlist_%(name)s(PyObject* a, int extralen)
-{
-	/* NB. this function does not update o->ob_size */
-	PyList_%(name)s* o = (PyList_%(name)s*) a;
-	int newlen = o->ob_size + extralen;
-	void* buffer = PyMem_Realloc(o->ob_item,
-				     newlen*sizeof(ListItem_%(name)s));
-	if (buffer == NULL) {
-		PyErr_NoMemory();
-		return -1;
-	}
-	o->ob_item = (ListItem_%(name)s*) buffer;
-	return 0;
-}
-'''
+    C_INIT_FOOTER = '''
+\tPyModule_AddObject(m, "%(entrypointname)s", %(entrypoint)s);
+}'''
 
 # ____________________________________________________________
+
+def cdecl(type, name):
+    # Utility to generate a typed name declaration in C syntax.
+    # For local variables, struct fields, function declarations, etc.
+    # For complex C types, the 'type' can contain a '@' character that
+    # specifies where the 'name' should be inserted; for example, an
+    # array of 10 ints has a type of "int @[10]".
+    if '@' in type:
+        return type.replace('@', name)
+    else:
+        return ('%s %s' % (type, name)).rstrip()

Deleted: /pypy/trunk/src/pypy/translator/genc_op.py
==============================================================================
--- /pypy/trunk/src/pypy/translator/genc_op.py	Sat Oct  9 10:44:33 2004
+++ (empty file)
@@ -1,443 +0,0 @@
-"""
-Low-level operations for C code generation.
-"""
-
-from pypy.translator.typer import LLOp
-
-# This file defines one class per possible operation.  But there are families
-# of very similar operations (e.g. incref/decref/xdecref).  To make it easy
-# to follow which class is really an operation and which class represents a
-# family, we introduce a simple mecanism: class attributes that are set to
-# PARAMETER are parameters that can be set by calling the class method With().
-PARAMETER = object()   # marker
-
-
-class LoC(LLOp):
-    # base class for LLOps that produce C code.
-    cost = 2
-
-    def write(self):
-        "Default write method, delegating to writestr()."
-        args = [a.name for a in self.args]
-        if self.can_fail:
-            args.append(self.errtarget)
-        return self.writestr(*args)
-
-    def using(self):
-        return self.args    # all locals and constants needed by write()
-
-    def With(cls, **params):
-        class subcls(cls):
-            pass
-        items = params.items()
-        items.sort()
-        info = [repr(value) for name, value in items]
-        subcls.__name__ = '%s.With(%s)' % (cls.__name__, ', '.join(info))
-        for name, value in items:
-            assert hasattr(cls, name), 'not a parameter: %r' % (name,)
-            setattr(subcls, name, value)
-        # check that all PARAMETERs, at least from this class,
-        # have been given a value
-        for name, value in cls.__dict__.items():
-            if value is PARAMETER:
-                assert name in params, 'missing definition for parameter '+name
-        return subcls
-    With = classmethod(With)
-
-class LoOptimized(LoC):
-    def write(self):
-        raise NotImplementedError, 'should be optimized away'
-    def optimize(self, typer, llresult):
-        # patch the result with the known answer
-        constantsllrepr = self.optimized_result(typer)
-        assert len(constantsllrepr) == len(llresult)
-        llresult[:] = constantsllrepr
-        return True
-
-# ____________________________________________________________
-#
-# For each operation we describe what argument list it expected.
-# These arguments are LLVars expanded from high-level arguments (Variables)
-# and the result, also as zero or more LLVars, all put together in a single
-# list.  The occasionally hackish look of self.args manipulations come from
-# the fact that the boundaries between the original high-level arguments
-# are lost by design.  In the #self.args comments below, a trailing '..'
-# means that zero or more items can come here.
-
-class LoStandardOperation(LoC):
-    "A standard operation is one defined by a macro in genc.h."
-    can_fail = PARAMETER
-    llname   = PARAMETER
-    cost     = PARAMETER
-    # self.args: [macro args expanded from Variables..]
-    def writestr(self, *args):
-        return self.llname + '(' + ', '.join(args) + ')'
-
-class LoKnownAnswer(LoOptimized):
-    known_answer = PARAMETER
-    cost         = 0
-    # self.args: [ignored input args..,
-    #             output args to replace with known_answer..]
-    def optimized_result(self, typer):
-        return self.known_answer
-
-class LoCallFunction(LoC):
-    can_fail = True
-    cost     = 3
-    # self.args: [callable PyObject, argument PyObjects.., result PyObject]
-    def writestr(self, func, *stuff):
-        args = stuff[:-2]
-        result = stuff[-2]
-        err = stuff[-1]
-        format = '"' + 'O' * len(args) + '"'
-        args = (func, format) + args
-        return ('OP_CALL_PYOBJ((%s), %s, %s)' % (', '.join(args), result, err))
-
-class LoInstantiate(LoC):
-    can_fail = True
-    llclass  = PARAMETER
-    # self.args: [output PyObject instance]
-    def writestr(self, res, err):
-        return 'OP_INSTANTIATE(%s, %s, %s)' % (self.llclass.name, res, err)
-
-class LoAllocInstance(LoC):
-    can_fail = True
-    llclass  = PARAMETER
-    # self.args: [output PyObject instance]
-    def writestr(self, res, err):
-        return 'ALLOC_INSTANCE(%s, %s, %s)' % (self.llclass.name, res, err)
-
-class LoConvertTupleItem(LoOptimized):
-    source_r = PARAMETER   # tuple-of-hltypes, one per item of the input tuple
-    target_r = PARAMETER   # tuple-of-hltypes, one per item of the output tuple
-    cost     = PARAMETER
-    # self.args: [input unpacked tuple items.., output unpacked tuple items..]
-    def optimized_result(self, typer):
-        # replace this complex conversion by the simpler conversion of
-        # only the items that changed
-        llinputs = []
-        pos = 0
-        for r in self.source_r:
-            L = len(r.impl)
-            llinputs.append(self.args[pos:pos+L])
-            pos += L
-        lloutputs = []
-        for r in self.target_r:
-            L = len(r.impl)
-            lloutputs.append(self.args[pos:pos+L])
-            pos += L
-
-        llrepr = []     # answer
-        for i in range(len(self.source_r)):
-            if self.source_r[i] != self.target_r[i]:
-                # convert this item
-                llrepr += typer.convert(self.source_r[i], llinputs[i],
-                                        self.target_r[i], lloutputs[i])
-            else:
-                # don't convert, just pass this item unchanged to the result
-                llrepr += llinputs[i]
-        return llrepr
-
-class LoNewTuple(LoC):
-    can_fail = True
-    cost     = 3
-    macro    = 'OP_NEWTUPLE'
-    # self.args: [input PyObjects.., output PyObject]
-    def writestr(self, *stuff):
-        args   = stuff[:-2]
-        result = stuff[-2]
-        err    = stuff[-1]
-        ls = ['%s(%d, %s, %s)' % (self.macro, len(args), result, err)]
-        for i in range(len(args)):
-            ls.append('%s_SET(%s, %d, %s)' % (self.macro, result, i, args[i]))
-        return '\n'.join(ls)
-
-class LoNewList(LoNewTuple):
-    macro    = 'OP_NEWLIST'
-    # self.args: [input PyObjects.., output PyObject]
-
-class LoNewArray(LoC):
-    can_fail = True
-    typename = PARAMETER   # the name of the PyList_Xxx type in the C source
-    lltypes  = PARAMETER   # the C types needed to represent each array item
-    length   = PARAMETER
-    # self.args: [item0.., item1.., item2.., ..., output PyObject]
-    def writestr(self, *stuff):
-        args   = stuff[:-2]
-        result = stuff[-2]
-        err    = stuff[-1]
-        assert len(args) == self.length * len(self.lltypes)
-        ls = ['OP_NEWARRAY(%s, %d, %s, %s)' % (
-            self.typename, self.length, result, err)]
-        for i in range(self.length):
-            for j in range(len(self.lltypes)):
-                if self.lltypes[j] == 'PyObject*':
-                    typecode = '_o'
-                else:
-                    typecode = ''
-                a = args[i*len(self.lltypes) + j]
-                ls.append('OP_NEWARRAY_SET%s(%s, %s, %d, a%d, %s)' % (
-                    typecode, self.typename, result, i, j, a))
-        return '\n'.join(ls)
-
-class LoAllocAndSetArray(LoC):
-    can_fail = True
-    typename = PARAMETER   # the name of the PyList_Xxx type in the C source
-    lltypes  = PARAMETER   # the C types needed to represent each array item
-    # self.args: [length, input_item.., output PyObject]
-    def writestr(self, length, *stuff):
-        input  = stuff[:-2]
-        result = stuff[-2]
-        err    = stuff[-1]
-        assert len(input) == len(self.lltypes)
-        ls = ['OP_NEWARRAY(%s, %s, %s, %s)' % (
-            self.typename, length, result, err)]
-        if len(self.lltypes) > 0:
-            ls.append('{ int i; for (i=0; i<%s; i++) {' % length)
-            for j in range(len(self.lltypes)):
-                if self.lltypes[j] == 'PyObject*':
-                    typecode = '_o'
-                else:
-                    typecode = ''
-                a = input[j]
-                ls.append('\tOP_NEWARRAY_SET%s(%s, %s, i, a%d, %s)' % (
-                    typecode, self.typename, result, j, a))
-            ls.append('} }')
-        return '\n'.join(ls)
-
-class LoGetArrayItem(LoC):
-    typename = PARAMETER   # the name of the PyList_Xxx type in the C source
-    lltypes  = PARAMETER   # the C types needed to represent each array item
-    macro    = 'OP_GETARRAYITEM'
-    # self.args: [PyObject, int_index, output_item..]
-    def writestr(self, array, index, *output):
-        assert len(output) == len(self.lltypes)
-        ls = []
-        for j in range(len(self.lltypes)):
-            if self.lltypes[j] == 'PyObject*':
-                typecode = '_o'
-            else:
-                typecode = ''
-            ls.append('%s%s(%s, %s, %s, a%d, %s)' % (
-                self.macro, typecode, self.typename,
-                array, index, j, output[j]))
-        return '\n'.join(ls)
-
-class LoSetArrayItem(LoGetArrayItem):
-    macro = 'OP_SETARRAYITEM'
-    # self.args: [PyObject, int_index, input_item..]
-
-class LoArrayGrow(LoC):
-    can_fail = True
-    cost     = 3
-    typename = PARAMETER
-    # self.args: [PyObject, int_extralen]
-    def writestr(self, array, extralen, err):
-        return 'OP_GROWLIST(%s, %s, %s, %s)' % (self.typename, array,
-                                                extralen, err)
-
-class LoArrayFastAppend(LoSetArrayItem):
-    # self.args: [PyObject, new_item..]
-    def writestr(self, array, *newitem):
-        index = 'ARRAYLEN(%s)' % array
-        ls = [LoSetArrayItem.writestr(self, array, index, *newitem),
-              '%s++;' % index]
-        return '\n'.join(ls)
-
-class LoGetAttr(LoC):
-    cost = 1
-    fld  = PARAMETER
-    # self.args: [PyObject instance, result..]
-    def writestr(self, inst, *result):
-        ls = []
-        if self.fld.is_class_attr:
-            macro = 'OP_GETCLASSATTR'
-        else:
-            macro = 'OP_GETINSTATTR'
-        llclass = self.fld.llclass
-        for src, dstname in zip(self.fld.llvars, result):
-            if src.type == 'PyObject*':
-                typecode = '_o'
-            else:
-                typecode = ''
-            ls.append('%s%s(%s, %s, %s, %s)' % (
-                macro, typecode, llclass.name, inst, src.name, dstname))
-        return '\n'.join(ls)
-
-class LoGetAttrMethod(LoGetAttr):
-    # self.args: [PyObject instance, result..]
-    def optimize(self, typer, llresult):
-        # for a OP_GETATTR that must return a bound method.  The 'self'
-        # part of the result can be statically copied from self.args[0].
-        # The rest is done as with LoGetAttr.
-        inst = self.args[0]
-        llresult[-1] = inst  # patch to do the copy statically
-        return False  # proceed with the normal LoGetAttr.writestr()
-
-class LoSetAttr(LoC):
-    cost    = 1
-    llclass = PARAMETER   # the class involved in the operation
-    fld     = PARAMETER   # the field, which might come from a parent class
-    # self.args: [PyObject instance, new value..]
-    def writestr(self, inst, *value):
-        assert len(value) == len(self.fld.llvars)
-        ls = []
-        for srcname, dst in zip(value, self.fld.llvars):
-            if dst.type == 'PyObject*':
-                typecode = '_o'
-            else:
-                typecode = ''
-            ls.append('OP_SETINSTATTR%s(%s, %s, %s, %s)' % (
-                typecode, self.llclass.name, inst, dst.name, srcname))
-        return '\n'.join(ls)
-
-class LoInitClassAttr(LoC):
-    cost    = 1
-    llclass = PARAMETER   # the class involved in the operation
-    fld     = PARAMETER   # the field, which might come from a parent class
-    # self.args: [constant value to store..]
-    def writestr(self, *value):
-        assert len(value) == len(self.fld.llvars)
-        ls = []
-        # setting class attributes is only used for initialization
-        for srcname, dst in zip(value, self.fld.llvars):
-            if dst.type == 'PyObject*':
-                typecode = '_o'
-            else:
-                typecode = ''
-            ls.append('OP_INITCLASSATTR%s(%s, %s, %s)' % (
-                typecode, self.llclass.name, dst.name, srcname))
-        return '\n'.join(ls)
-
-class LoConvertBoundMethod(LoOptimized):
-    r_source = PARAMETER
-    r_target = PARAMETER
-    cost     = PARAMETER
-    # self.args: [im_func.., im_self PyObject, output im_func.., im_self PyObj]
-    def optimized_result(self, typer):
-        slen = len(self.r_source.impl)
-        tlen = len(self.r_target.impl)
-        assert len(self.args) == slen+1+tlen+1
-        # convert the 'func' part of the method
-        answer = typer.convert(self.r_source, self.args[:slen],
-                               self.r_target, self.args[slen+1:-1])
-        # pass the 'self' argument unchanged
-        answer.append(self.args[slen])
-        return answer
-
-class LoConvertChain(LoOptimized):
-    r_from   = PARAMETER
-    r_middle = PARAMETER
-    r_to     = PARAMETER
-    cost     = PARAMETER
-    # self.args: [input value.., output value..]
-    def optimized_result(self, typer):
-        half = len(self.r_from.impl)
-        assert half + len(self.r_to.impl) == len(self.args)
-        input = self.args[:half]
-        output = self.args[half:]
-        middle = typer.convert(self.r_from, input, self.r_middle)
-        return typer.convert(self.r_middle, middle, self.r_to, output)
-
-class LoDummyResult(LoC):
-    cost = 1
-    # self.args: [output value..]
-    def write(self):
-        ls = []
-        for a in self.args:
-            if a.type == 'PyObject*':
-                ls.append('OP_DUMMYREF(%s)' % a.name)
-        return '\n'.join(ls)
-
-# ____________________________________________________________
-
-class LoMove(LoC):
-    cost = 1
-    # self.args: [input LLVar, output LLVar]
-    def writestr(self, x, y):
-        return 'MOVE(%s, %s)' % (x, y)
-
-class LoGoto(LoC):
-    cost = 0
-    # self.args: []
-    def write(self):
-        return 'goto %s;' % self.errtarget
-
-class LoCopy(LoOptimized):
-    cost = 0
-    # self.args: [input LLVars.., output LLVars..]
-    def optimized_result(self, typer):
-        # the result's llvars is equal to the input's llvars.
-        assert len(self.args) % 2 == 0
-        half = len(self.args) // 2
-        return self.args[:half]
-
-class LoDoSomethingWithRef(LoC):
-    do_what = PARAMETER
-    cost    = 1
-    # self.args: [value..]
-    def write(self):
-        ls = []
-        for a in self.args:
-            if a.type == 'PyObject*':
-                ls.append('%s(%s);' % (self.do_what, a.name))
-        return ' '.join(ls)
-
-LoIncref  = LoDoSomethingWithRef.With(do_what = 'Py_INCREF')
-LoDecref  = LoDoSomethingWithRef.With(do_what = 'Py_DECREF')
-LoXDecref = LoDoSomethingWithRef.With(do_what = 'Py_XDECREF')
-
-class LoComment(LoC):
-    cost = 0
-    # self.args: []
-    def write(self):
-        s = self.errtarget
-        s = s.replace('/*', '/+')
-        s = s.replace('*/', '+/')
-        return '/* %s */' % s
-
-# ____________________________________________________________
-
-ERROR_RETVAL = {
-    None:        '-1',
-    'int':       '-1',
-    }
-
-class LoCallPyFunction(LoC):
-    can_fail  = True
-    hlrettype = PARAMETER
-    # self.args: [C function pointer, arguments.., result..]
-    def write(self):
-        funcptr = self.args[0].name
-        L = len(self.hlrettype.impl)
-        R = len(self.args) - L
-        args = [a.name for a in self.args[1:R]]
-        err = self.errtarget
-        if L == 0:  # no return value
-            return 'OP_CCALL_v(%s, (%s), %s)' % (funcptr, ', '.join(args), err)
-        else:
-            # the return value is the first return LLVar:
-            retvar = self.args[R]
-            # if there are several return LLVars, the extra ones are passed
-            # in by reference as output arguments
-            args += ['&%s' % a.name for a in self.args[R+1:]]
-            if retvar.type == 'int':
-                typecode = '_i'
-            else:
-                typecode = ''
-            return 'OP_CCALL%s(%s, (%s), %s, %s)' % (
-                typecode, funcptr, ', '.join(args), retvar.name, err)
-
-class LoReturn(LoC):
-    cost = 1
-    # self.args: [return value..]
-    def write(self):
-        if not self.args:
-            return 'return 0;'
-        ls = []
-        for extra in self.args[1:]:
-            ls.append('*output_%s = %s;' % (extra.name, extra.name))
-        ls.append('return %s;' % self.args[0].name)
-        return '\n'.join(ls)
-
-# ____________________________________________________________

Deleted: /pypy/trunk/src/pypy/translator/genc_repr.py
==============================================================================
--- /pypy/trunk/src/pypy/translator/genc_repr.py	Sat Oct  9 10:44:33 2004
+++ (empty file)
@@ -1,385 +0,0 @@
-"""
-High-level types and how variables of that type are represented by a
-series of low-level variables.
-"""
-
-import types, __builtin__
-from pypy.translator.typer import CannotConvert, LLConst
-from pypy.translator import genc_op
-
-
-class CRepr:
-    "A possible representation of a flow-graph variable as C-level variables."
-    parse_code = None    # character(s) for PyArg_ParseTuple()
-
-    def __repr__(self):
-        return '%s(%s)' % (self.__class__.__name__, ' + '.join(self.impl))
-
-    def convert_to(self, target, typeset):
-        raise CannotConvert
-
-
-class CAtomicRepr(CRepr):
-    "A simple C type."
-
-    def __init__(self, impl, parse_code=None):
-        self.impl = impl
-        self.parse_code = parse_code
-
-
-class CUndefined(CRepr):
-    "An undefined value. (singleton class)"
-    impl = []
-    
-    def convert_to(self, target, typeset):
-        return genc_op.LoDummyResult
-
-
-class CConstant(CRepr):
-    "A constant value."
-    impl = []
-
-    def __init__(self, value):
-        self.value = value
-
-    def __repr__(self):
-        return 'CConstant(%r)' % (self.value,)
-
-    def convert_to_pyobj(self, initexpr, globalname):
-        # helper for subclasses
-        return genc_op.LoKnownAnswer.With(
-            known_answer = [LLConst('PyObject*', globalname, initexpr,
-                                    to_declare = bool(initexpr))],
-            )
-
-class CConstantInt(CConstant):
-    def convert_to(self, target, typeset):
-        if target == R_INT:
-            # can convert the constant to a C int
-            return genc_op.LoKnownAnswer.With(
-                known_answer = [LLConst('int', '%d' % self.value)],
-                )
-        elif target == R_OBJECT:
-            # can convert the constant to a PyObject*
-            if self.value >= 0:
-                name = 'g_IntObj_%d' % self.value
-            else:
-                name = 'g_IntObj_minus%d' % abs(self.value)
-            return self.convert_to_pyobj(
-                'PyInt_FromLong(%d)' % self.value,
-                name)
-        else:
-            raise CannotConvert
-
-class CConstantStr(CConstant):
-    def convert_to(self, target, typeset):
-        if target == R_OBJECT:
-            # can convert the constant to a PyObject*
-            return self.convert_to_pyobj(
-                'PyString_FromStringAndSize(%s, %d)' % (c_str(self.value),
-                                                        len(self.value)),
-                'g_StrObj_%s' % manglestr(self.value))
-        else:
-            raise CannotConvert
-
-class CConstantNone(CConstant):
-    def convert_to(self, target, typeset):
-        if target == R_OBJECT:
-            # can convert the constant to a PyObject*
-            return self.convert_to_pyobj(None, 'Py_None')
-        else:
-            raise CannotConvert
-
-class CConstantBuiltin(CConstant):   # a constant from the __builtin__ module
-    def convert_to(self, target, typeset):
-        if target == R_OBJECT:
-            # can load the constant as a PyObject* from the builtins
-            fn = self.value
-            if getattr(__builtin__, fn.__name__, None) is not fn:
-                raise CannotConvert   # unless it doesn't appear to be there
-            return self.convert_to_pyobj(
-                'PyMapping_GetItemString(PyEval_GetBuiltins(), %s)' % (
-                    c_str(fn.__name__)),
-                'g_Builtin_%s' % manglestr(fn.__name__))
-        else:
-            raise CannotConvert
-
-class CConstantFunction(CConstant):
-    def convert_to(self, target, typeset):
-        if isinstance(target, CFunction):
-            fn = self.value
-            if fn not in typeset.genc.llfunctions:
-                raise CannotConvert
-            llfunc = typeset.genc.llfunctions[fn]
-            my_header_r = typeset.getfunctionsig(llfunc)
-            if my_header_r != target.header_r:
-                raise CannotConvert(self, my_header_r, target)
-            cfunctype, = target.impl
-            return genc_op.LoKnownAnswer.With(
-                known_answer = [LLConst(cfunctype, llfunc.name)],
-                )
-        else:
-            raise CannotConvert
-
-
-class CTuple(CRepr):
-    "An unpacked tuple.  Represents all its items independently."
-
-    def __init__(self, items_r):
-        self.items_r = tuple(items_r)
-        self.impl = []
-        for r in items_r:
-            self.impl += r.impl
-
-    def __repr__(self):
-        return 'CTuple(%s)' % ', '.join([repr(r) for r in self.items_r])
-
-    def convert_to(self, target, typeset):
-        if isinstance(target, CTuple):
-            if len(self.items_r) != len(target.items_r):
-                raise CannotConvert
-            # convert each tuple item that needs to be converted
-            cost = 0
-            for r1, r2 in zip(self.items_r, target.items_r):
-                if r1 != r2:
-                    cost += typeset.getconversion(r1, r2).cost
-            return genc_op.LoConvertTupleItem.With(
-                source_r = self.items_r,
-                target_r = target.items_r,
-                cost     = cost,
-                )
-        elif target == R_OBJECT:
-            # to convert a tuple to a PyTupleObject* we first need to
-            # make sure that all items are PyObject*.
-            intermediate_r = (R_OBJECT,) * len(self.items_r)
-            if self.items_r == intermediate_r:
-                return genc_op.LoNewTuple   # already the case
-            else:
-                r_middle = tuple_representation(intermediate_r)
-                cost1 = typeset.getconversion(self, r_middle).cost
-                return genc_op.LoConvertChain.With(
-                    r_from   = self,
-                    r_middle = r_middle,
-                    r_to     = target,
-                    cost     = cost1 + genc_op.LoNewTuple.cost,
-                    )
-        else:
-            raise CannotConvert
-
-
-class CInstance(CRepr):
-    "An instance of some class (or a subclass of it)."
-    impl = ['PyObject*']
-
-    def __init__(self, llclass):
-        self.llclass = llclass     # instance of classtyper.LLClass or None
-        # R_INSTANCE is CInstance(None): a match-all, any-type instance.
-
-    def __repr__(self):
-        if self.llclass is None:
-            return 'CInstance(*)'
-        else:
-            cls = self.llclass.cdef.cls
-            return 'CInstance(%s.%s)' % (cls.__module__, cls.__name__)
-
-    def convert_to(self, target, typeset):
-        if isinstance(target, CInstance):
-            if not (self.llclass is None or target.llclass is None):
-                # can only convert to an instance of a parent class
-                if target.llclass.cdef not in self.llclass.cdef.getmro():
-                    raise CannotConvert
-            return genc_op.LoCopy
-        elif target == R_OBJECT:
-            # can convert to a generic PyObject*
-            return genc_op.LoCopy
-        else:
-            raise CannotConvert
-
-
-class CFunction(CRepr):
-    "A C-level function or a pointer to a function."
-
-    def __init__(self, header_r):
-        self.header_r = header_r  # list of CReprs: [arg1, arg2, ..., retval]
-        # C syntax is quite strange: a pointer to a function is declared
-        # with a syntax like "int (*varname)(long, char*)".  We build here
-        # a 'type' string like "int (*@)(long, char*)" that will be combined
-        # with an actual name by cdecl() below.  Oh, and by the way, to
-        # make a string like "int (*@)(long, char*)" we need to use cdecl()
-        # as well, because the "int" which is the return type could itself
-        # contain a "@"... for functions returning pointers to functions.
-        llargs = []
-        for r in  header_r[:-1]:
-            llargs += [cdecl(atype, '') for atype in r.impl]
-        llret = header_r[-1].impl
-        # same logic as get_llfunc_header()
-        if len(llret) == 0:
-            retlltype = 'int' # no return value needed, returns an error flag
-        elif len(llret) == 1:
-            retlltype = llret[0]
-        else:
-            # if there is more than one C return type, only the first one is
-            # returned and the other ones are returned via ptr output args
-            retlltype = llret[0]
-            llargs += [cdecl(atype, '*') for atype in llret[1:]]
-        cfunctype = cdecl(retlltype, '(*@)(%s)' % ', '.join(llargs))
-        self.impl = [cfunctype]
-
-    def __repr__(self):
-        args = [repr(r) for r in self.header_r[:-1]]
-        return 'CFunction(%s -> %r)' % (', '.join(args), self.header_r[-1])
-
-
-class CMethod(CRepr):
-    "A CFunction or CConstantFunction with its first argument bound."
-
-    def __init__(self, r_func):
-        self.r_func = r_func
-        self.impl = r_func.impl + ['PyObject*']
-
-    def __repr__(self):
-        return 'CMethod(%r)' % (self.r_func,)
-
-    def convert_to(self, target, typeset):
-        if not isinstance(target, CMethod):
-            raise CannotConvert
-        cost = typeset.getconversion(self.r_func, target.r_func).cost
-        return genc_op.LoConvertBoundMethod.With(
-            r_source = self.r_func,
-            r_target = target.r_func,
-            cost     = cost,
-            )
-
-class CList(CRepr):
-    "A list as an array whose items are represented as r_item."
-
-    def __init__(self, r_item):
-        self.r_item = r_item
-        self.impl = ['PyObject*']
-
-    def __repr__(self):
-        return 'CList(%r)' % (self.r_item,)
-
-    def convert_to(self, target, typeset):
-        if target == R_OBJECT:
-            # can convert to a generic PyObject*
-            # (but not, or not yet, to a regular PyListObject*!)
-            return genc_op.LoCopy
-        else:
-            raise CannotConvert
-
-# ____________________________________________________________
-#
-# Predefined CReprs and caches for building more
-
-R_VOID      = CAtomicRepr([])
-R_INT       = CAtomicRepr(['int'],       parse_code='i')
-R_OBJECT    = CAtomicRepr(['PyObject*'], parse_code='O')
-R_UNDEFINED = CUndefined()
-R_INSTANCE  = CInstance(None)
-
-R_TUPLE_CACHE    = {}
-R_CONSTANT_CACHE = {}
-R_INSTANCE_CACHE = {}
-R_FUNCTION_CACHE = {}
-R_METHOD_CACHE   = {}
-R_LIST_CACHE     = {}
-
-def tuple_representation(items_r):
-    items_r = tuple(items_r)
-    try:
-        return R_TUPLE_CACHE[items_r]
-    except KeyError:
-        rt   = R_TUPLE_CACHE[items_r] = CTuple(items_r)
-        return rt
-
-CONST_TYPES = {
-    int:                       CConstantInt,
-    str:                       CConstantStr,
-    types.NoneType:            CConstantNone,
-    types.BuiltinFunctionType: CConstantBuiltin,
-    types.FunctionType:        CConstantFunction,
-    }
-
-def constant_representation(value):
-    key = type(value), value   # to avoid mixing for example 0 and 0.0
-    try:
-        return R_CONSTANT_CACHE[key]
-    except KeyError:
-        if isinstance(value, tuple):
-            # tuples have their own representation and
-            # don't need a fully constant representation
-            items_r = [constant_representation(x) for x in value]
-            return tuple_representation(items_r)
-        for cls in type(value).__mro__:
-            if cls in CONST_TYPES:
-                cls = CONST_TYPES[cls]
-                break
-        else:
-            if isinstance(value, types.MethodType) and value.im_self is None:
-                # replace unbound methods with plain funcs
-                return constant_representation(value.im_func)
-            cls = CConstant
-        r = R_CONSTANT_CACHE[key] = cls(value)
-        return r
-
-def instance_representation(llclass):
-    try:
-        return R_INSTANCE_CACHE[llclass]
-    except KeyError:
-        r = R_INSTANCE_CACHE[llclass] = CInstance(llclass)
-        return r
-
-def function_representation(sig):
-    key = tuple(sig)
-    try:
-        return R_FUNCTION_CACHE[key]
-    except KeyError:
-        r = R_FUNCTION_CACHE[key] = CFunction(sig)
-        return r
-
-def method_representation(r_func):
-    key = r_func
-    try:
-        return R_METHOD_CACHE[key]
-    except KeyError:
-        r = R_METHOD_CACHE[key] = CMethod(r_func)
-        return r
-
-def list_representation(r_item):
-    try:
-        return R_LIST_CACHE[r_item]
-    except KeyError:
-        r = R_LIST_CACHE[r_item] = CList(r_item)
-        return r
-
-
-def c_str(s):
-    "Return the C expression for the string 's'."
-    s = repr(s)
-    if s.startswith("'"):
-        s = '"' + s[1:-1].replace('"', r'\"') + '"'
-    return s
-
-def manglestr(s):
-    "Return an identifier name unique for the string 's'."
-    l = []
-    for c in s:
-        if not ('a' <= c <= 'z' or 'A' <= c <= 'Z' or '0' <= c <= '9'):
-            if c == '_':
-                c = '__'
-            else:
-                c = '_%02x' % ord(c)
-        l.append(c)
-    return ''.join(l)
-
-def cdecl(type, name):
-    # Utility to generate a typed name declaration in C syntax.
-    # For local variables, struct fields, function declarations, etc.
-    # For complex C types, the 'type' can contain a '@' character that
-    # specifies where the 'name' should be inserted; for example, an
-    # array of 10 ints has a type of "int @[10]".
-    if '@' in type:
-        return type.replace('@', name)
-    else:
-        return ('%s %s' % (type, name)).rstrip()

Deleted: /pypy/trunk/src/pypy/translator/genc_typeset.py
==============================================================================
--- /pypy/trunk/src/pypy/translator/genc_typeset.py	Sat Oct  9 10:44:33 2004
+++ (empty file)
@@ -1,446 +0,0 @@
-from __future__ import generators
-import re
-from pypy.objspace.flow.model import Variable, Constant, UndefinedConstant
-from pypy.annotation import model as annmodel
-from pypy.translator import genc_op
-from pypy.translator.typer import CannotConvert, TypingError, LLConst
-from pypy.translator.genc_repr import R_VOID, R_INT, R_OBJECT, R_UNDEFINED
-from pypy.translator.genc_repr import R_INSTANCE
-from pypy.translator.genc_repr import tuple_representation
-from pypy.translator.genc_repr import constant_representation, CConstant
-from pypy.translator.genc_repr import instance_representation, CInstance
-from pypy.translator.genc_repr import function_representation, CFunction
-from pypy.translator.genc_repr import CConstantFunction
-from pypy.translator.genc_repr import method_representation, CMethod
-from pypy.translator.genc_repr import list_representation, CList
-
-
-class CTypeSet:
-    "A (small) set of C types that typer.LLFunction can manipulate."
-
-    REPR_BY_CODE = {
-        'v': R_VOID,
-        'i': R_INT,
-        'o': R_OBJECT,
-        }
-
-    rawoperations = {
-        'goto'   : genc_op.LoGoto,
-        'move'   : genc_op.LoMove,
-        'copy'   : genc_op.LoCopy,
-        'incref' : genc_op.LoIncref,
-        'decref' : genc_op.LoDecref,
-        'xdecref': genc_op.LoXDecref,
-        'comment': genc_op.LoComment,
-        'return' : genc_op.LoReturn,
-        }
-
-    def __init__(self, genc, bindings):
-        self.genc = genc
-        self.bindings = bindings
-        self.conversion_cache = {}
-        self.conversion_errors = {}
-        self.lloperations = {'CONVERT': self.conversion_cache}
-        self.parse_operation_templates()
-
-    # __________ methods required by LLFunction __________
-    #
-    # Here, we assume that every high-level type has a canonical representation
-    # so a high-level type is just a CRepr.
-
-    def gethltype(self, var, unbound=False):
-        if isinstance(var, Variable):
-            var = self.bindings.get(var) or annmodel.SomeObject()
-        if isinstance(var, annmodel.SomeObject):
-            if var.is_constant():
-                return constant_representation(var.const)
-            if issubclass(var.knowntype, int):
-                return R_INT
-            if isinstance(var, annmodel.SomeImpossibleValue):
-                return R_VOID
-            if isinstance(var, annmodel.SomeTuple):
-                items_r = [self.gethltype(s_item) for s_item in var.items]
-                return tuple_representation(items_r)
-            if isinstance(var, annmodel.SomeInstance):
-                llclass = self.genc.llclasses[var.knowntype]
-                return instance_representation(llclass)
-            if isinstance(var, annmodel.SomeFunction):
-                func_sig = self.regroup_func_sig(var.funcs)
-                return function_representation(func_sig)
-            if isinstance(var, annmodel.SomeMethod):
-                r_func = self.gethltype(annmodel.SomeFunction(var.meths))
-                if unbound:
-                    return r_func
-                else:
-                    return method_representation(r_func)
-            if isinstance(var, annmodel.SomeList):
-                r_item = self.gethltype(var.s_item)
-                typename = self.genc.declare_list(r_item.impl)
-                r = list_representation(r_item)
-                r.typename = typename
-                return r
-            # fall-back
-            return R_OBJECT
-        if isinstance(var, UndefinedConstant):
-            return R_UNDEFINED
-        if isinstance(var, Constant):
-            return constant_representation(var.value)
-        raise TypeError, var
-
-    def represent(self, hltype):
-        return hltype.impl
-
-    def getconversion(self, hltype1, hltype2):
-        sig = hltype1, hltype2
-        if sig in self.conversion_errors:
-            raise CannotConvert(hltype1, hltype2)   # shortcut
-        try:
-            return self.conversion_cache[sig]
-        except KeyError:
-            try:
-                llopcls = hltype1.convert_to(hltype2, self)
-                self.conversion_cache[sig] = llopcls
-                return llopcls
-            except CannotConvert, e:
-                self.conversion_errors[sig] = True
-                if not e.args:
-                    e.args = hltype1, hltype2
-                raise
-
-    def typemismatch(self, opname, hltypes):
-        # build operations on demand, e.g. if they take a variable number
-        # of arguments or depend on a constant value (e.g. the class being
-        # instantiated).
-        try:
-            extender = getattr(self, 'extend_' + opname)
-        except AttributeError:
-            return
-        for newsig, newop in extender(hltypes):
-            # record the new operation only if it has a lower cost than
-            # an existing operation with the same signature
-            llops = self.lloperations.setdefault(opname, {})
-            if newsig not in llops or newop.cost < llops[newsig].cost:
-                llops[newsig] = newop
-
-    # ____________________________________________________________
-
-    def getfunctionsig(self, llfunc):
-        "Get the high-level header (argument types and result) for a function."
-        # XXX messy! we allow different CInstances to appear as function
-        #     arguments by replacing them with the generic R_INSTANCE.
-        #     This is not too clean, but it might be unavoidable, because
-        #     the whole implementation relies on this "coincidence" that
-        #     pointers to objects of different classes are interchangeable.
-        result = []
-        for v in llfunc.graph.getargs() + [llfunc.graph.getreturnvar()]:
-            r = self.gethltype(v)
-            if isinstance(r, CInstance):
-                r = R_INSTANCE
-            result.append(r)
-        return result
-
-    def regroup_func_sig(self, funcs):
-        # find a common signature for the given functions
-        signatures = []
-        for func in funcs:
-            llfunc = self.genc.llfunctions[func]
-            signatures.append(self.getfunctionsig(llfunc))
-        # XXX we expect the functions to have exactly the same signature
-        #     but this is currently not enforced by the annotator.
-        result = signatures[0]
-        for test in signatures[1:]:
-            if test != result:
-                raise TypingError(test, result)
-        return result
-
-    # ____________________________________________________________
-    #
-    # Each extend_OPNAME() method below is called when there is no direct
-    # match for the given hltypes for the operation OPNAME.
-    # The extend_XXX() methods should produce (yield) as many low-level
-    # operation signatures as they like, using the hltypes as a guide;
-    # once all these have been generated, the algorithms in typer.py will
-    # look for a best approximate match, doing conversions if needed.
-    #
-    # For example, extend_OP_GETITEM() is called with
-    #    hltypes == (repr_of_obj, repr_of_index, repr_of_result).
-    # When it is called with an instance of CList in hltypes[0], it
-    # generates the operation that reads an item out of this kind of array.
-    # This operation takes exactly an R_INT index (which may differ from
-    # hltypes[1]) and produce a result of exactly the CList's r_item type
-    # (which may differ from hltypes[2]).  Then typer.py will try to
-    # convert the index from hltypes[1] to R_INT and convert the result back
-    # to hltypes[2].
-
-    def extend_OP_NEWLIST(self, hltypes):
-        if not hltypes:
-            return
-        # LoNewList can build a list of any length from PyObject* args.
-        sig = (R_OBJECT,) * len(hltypes)
-        yield sig, genc_op.LoNewList
-
-        # LoNewArray can build an array from items of the correct type.
-        r = hltypes[-1]
-        if isinstance(r, CList):
-            sig = (r.r_item,) * (len(hltypes)-1) + (r,)
-            yield sig, genc_op.LoNewArray.With(
-                typename = r.typename,
-                lltypes  = r.r_item.impl,
-                length   = len(hltypes)-1,
-                )
-
-    def extend_OP_ALLOC_AND_SET(self, hltypes):
-        if len(hltypes) != 3:
-            return
-        # we have LoAllocAndSetArray
-        r_length, r_input, r = hltypes
-        if isinstance(r, CList):
-            sig = (R_INT, r.r_item, r)
-            yield sig, genc_op.LoAllocAndSetArray.With(
-                typename = r.typename,
-                lltypes  = r.r_item.impl,
-                )
-
-    def extend_OP_NEWTUPLE(self, hltypes):
-        # We can use LoCopy to virtually build a tuple because
-        # the tuple representation 'rt' is just the collection of all the
-        # representations for the input args.
-        rt = tuple_representation(hltypes[:-1])
-        sig = tuple(hltypes[:-1]) + (rt,)
-        yield sig, genc_op.LoCopy
-
-    def extend_OP_SIMPLE_CALL(self, hltypes):
-        if not hltypes:
-            return
-        # We can call the function using PyObject_CallFunction(), if
-        # it can be converted to PyObject*.
-        sig = (R_OBJECT,) * len(hltypes)
-        yield sig, genc_op.LoCallFunction
-
-        r = hltypes[0]
-        if (isinstance(r, CConstantFunction) and
-            r.value in self.genc.llfunctions):
-            # a constant function can be converted to a function pointer,
-            # so we fall back to the latter case
-            llfunc = self.genc.llfunctions[r.value]
-            r = function_representation(self.getfunctionsig(llfunc))
-
-        if isinstance(r, CFunction):
-            # a function pointer (the pointer is a C pointer, but points
-            # to a C function generated from a user-defined Python function).
-            sig = (r,) + tuple(r.header_r)
-            yield sig, genc_op.LoCallPyFunction.With(
-                hlrettype = sig[-1],
-                )
-
-        if isinstance(r, CMethod):
-            # first consider how we could call the underlying function
-            # with an extra R_INSTANCE first argument
-            hltypes2 = (r.r_func, R_INSTANCE) + hltypes[1:]
-            self.typemismatch('OP_SIMPLE_CALL', hltypes2)
-            # then lift all OP_SIMPLE_CALLs to method calls
-            opsimplecall = self.lloperations.setdefault('OP_SIMPLE_CALL', {})
-            for sig, opcls in opsimplecall.items():
-                if sig[1:2] == (R_INSTANCE,):
-                    r_meth = method_representation(sig[0])
-                    sig2 = (r_meth,) + sig[2:]
-                    yield sig2, opcls
-            # Note that we are reusing the same opcls.  Indeed, both the
-            # original 'sig' and the modified one expand to the same list
-            # of LLVars, so opcls cannot tell the difference:
-            #
-            # sig =    r.r_func     R_INSTANCE      ...
-            #          /-----\    /------------\
-            # LLVars:  funcptr,   PyObject* self,  arguments..., result
-            #          \-----------------------/
-            # sig2 =            r_meth              ...
-
-        if isinstance(r, CConstant):
-            # maybe it is a well-known constant non-user-defined function
-            fn = r.value
-            if not callable(fn):
-                return
-            # Instantiating a user-defined class
-            if fn in self.genc.llclasses:
-                # XXX do __init__
-                llclass = self.genc.llclasses[fn]
-                r_result = instance_representation(llclass)
-                sig = (r, r_result)   # r_result is the result of the op
-                yield sig, genc_op.LoInstantiate.With(
-                    llclass = self.genc.llclasses[fn],
-                    )
-            # Calling a built-in defined in genc.h, if we have a macro
-            # CALL_funcname()
-            opname = 'CALL_' + getattr(fn, '__name__', '?')
-            self.typemismatch(opname, hltypes[1:])  # invoke extend_CALL_xxx()
-            if opname in self.lloperations:
-                for sig, llopcls in self.lloperations[opname].items():
-                    sig = (r,) + sig
-                    yield sig, llopcls
-
-    def extend_OP_ALLOC_INSTANCE(self, hltypes):
-        # OP_ALLOC_INSTANCE is used by the constructor functions xxx_new()
-        if not hltypes:
-            return
-        r = hltypes[0]
-        if isinstance(r, CConstant):
-            fn = r.value
-            if not callable(fn):
-                return
-            if fn in self.genc.llclasses:
-                llclass = self.genc.llclasses[fn]
-                r_result = instance_representation(llclass)
-                sig = (r, r_result)   # r_result is the result of the op
-                yield sig, genc_op.LoAllocInstance.With(
-                    llclass = llclass,
-                    )
-
-    def extend_OP_GETATTR(self, hltypes):
-        if len(hltypes) != 3:
-            return
-        r_obj, r_attr, r_result = hltypes
-        if not isinstance(r_attr, CConstant):
-            return
-        if isinstance(r_obj, CInstance):
-            # record the OP_GETATTR operation for this field
-            fld = (r_obj.llclass.get_instance_field(r_attr.value) or
-                   r_obj.llclass.get_class_field(r_attr.value))
-            if fld is None:
-                return
-            sig = (r_obj, r_attr, fld.hltype)
-            # special case: reading a function out of a class attribute
-            # produces a bound method
-            if fld.is_class_attr:
-                r = sig[-1]
-                if isinstance(r, (CFunction, CConstantFunction)):
-                    r_method = method_representation(r)
-                    sig = (r_obj, r_attr, r_method)
-                    yield sig, genc_op.LoGetAttrMethod.With(
-                        fld = fld,
-                        )
-                    return
-            # common case
-            yield sig, genc_op.LoGetAttr.With(
-                fld = fld,
-                )
-
-    def extend_OP_SETATTR(self, hltypes):
-        if len(hltypes) != 4:
-            return
-        r_obj, r_attr, r_value, r_voidresult = hltypes
-        if not isinstance(r_attr, CConstant):
-            return
-        if isinstance(r_obj, CInstance):
-            # record the OP_SETATTR operation for this field
-            fld = r_obj.llclass.get_instance_field(r_attr.value)
-            if fld is not None:
-                sig = (r_obj, r_attr, fld.hltype, R_VOID)
-                yield sig, genc_op.LoSetAttr.With(
-                    fld     = fld,
-                    llclass = r_obj.llclass,
-                    )
-
-    def extend_OP_INITCLASSATTR(self, hltypes):
-        # only to initialize class attributes
-        if len(hltypes) != 4:
-            return
-        r_obj, r_attr, r_value, r_voidresult = hltypes
-        if isinstance(r_attr, CConstant) and isinstance(r_obj, CConstant):
-            cls = r_obj.value
-            if cls in self.genc.llclasses:
-                llclass = self.genc.llclasses[cls]
-                fld = llclass.get_class_field(r_attr.value)
-                if fld is not None:
-                    sig = (r_obj, r_attr, fld.hltype, R_VOID)
-                    yield sig, genc_op.LoInitClassAttr.With(
-                        fld     = fld,
-                        llclass = llclass,
-                        )
-
-    def extend_OP_GETITEM(self, hltypes):
-        if len(hltypes) != 3:
-            return
-        r, r_index, r_result = hltypes
-        # reading from a CList
-        if isinstance(r, CList):
-            sig = (r, R_INT, r.r_item)
-            yield sig, genc_op.LoGetArrayItem.With(
-                typename = r.typename,
-                lltypes  = r.r_item.impl,
-                )
-
-    def extend_OP_SETITEM(self, hltypes):
-        if len(hltypes) != 4:
-            return
-        r, r_index, r_value, r_void = hltypes
-        # writing into a CList
-        if isinstance(r, CList):
-            sig = (r, R_INT, r.r_item, R_VOID)
-            yield sig, genc_op.LoSetArrayItem.With(
-                typename = r.typename,
-                lltypes  = r.r_item.impl,
-                )
-
-    def extend_OP_LEN(self, hltypes):
-        if len(hltypes) != 2:
-            return
-        r, r_result = hltypes
-        # the length of a CList
-        if isinstance(r, CList):
-            sig = (r, R_INT)
-            yield sig, genc_op.LoStandardOperation.With(
-                can_fail = False,
-                llname   = 'OP_ARRAYLEN',
-                cost     = 1,
-                )
-
-    extend_CALL_len = extend_OP_LEN
-
-    def extend_OP_GROWLIST(self, hltypes):
-        if len(hltypes) != 3:
-            return
-        r, r_newlen, r_void = hltypes
-        # grow a CList
-        if isinstance(r, CList):
-            sig = (r, R_INT, R_VOID)
-            yield sig, genc_op.LoArrayGrow.With(
-                typename = r.typename,
-                )
-
-    def extend_OP_FASTAPPEND(self, hltypes):
-        # like append() but can assume that the list was already
-        # reallocated with OP_GROWLIST and has enough room
-        if len(hltypes) != 3:
-            return
-        r, r_newitem, r_void = hltypes
-        # append to a CList
-        if isinstance(r, CList):
-            sig = (r, r.r_item, R_VOID)
-            yield sig, genc_op.LoArrayFastAppend.With(
-                typename = r.typename,
-                lltypes  = r.r_item.impl,
-                )
-
-    # ____________________________________________________________
-
-    def parse_operation_templates(self):
-        # parse the genc.h header to figure out which macros are implemented
-        codes = ''.join(self.REPR_BY_CODE.keys())
-        pattern = r"#define ([A-Za-z_][0-9A-Za-z_]*)_([%s]*)[(](.*?)[)]" % codes
-        rexp = re.compile(pattern)
-        for line in self.genc.C_HEADER.split('\n'):
-            match = rexp.match(line)
-            if match:
-                self.register_operation_template(*match.groups())
-
-    def register_operation_template(self, opname, typecodes, formalargs):
-        llname = '%s_%s' % (opname, typecodes)
-        sig = tuple([self.REPR_BY_CODE[code] for code in typecodes])
-        can_fail = formalargs.replace(' ','').endswith(',err')
-        ops = self.lloperations.setdefault(opname, {})
-        assert sig not in ops, llname
-        ops.setdefault(sig, genc_op.LoStandardOperation.With(
-            can_fail = can_fail,
-            llname   = llname,
-            cost     = 1 + typecodes.count('o'),   # rough cost estimate
-            ))

Modified: pypy/trunk/src/pypy/translator/test/test_ctrans.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_ctrans.py	(original)
+++ pypy/trunk/src/pypy/translator/test/test_ctrans.py	Sat Oct  9 10:44:33 2004
@@ -84,7 +84,8 @@
         self.assertEquals(sand(0, 6), "no")
         self.assertEquals(sand(0, 0), "no")
 
-class TypedTestCase(testit.IntTestCase):
+if 0:
+  class TypedTestCase(testit.IntTestCase):
 
     def getcompiled(self, func):
         t = Translator(func) 

Deleted: /pypy/trunk/src/pypy/translator/typer.py
==============================================================================
--- /pypy/trunk/src/pypy/translator/typer.py	Sat Oct  9 10:44:33 2004
+++ (empty file)
@@ -1,439 +0,0 @@
-"""
-Graph-to-low-level transformer for C/Assembler code generators.
-"""
-
-from __future__ import generators
-from pypy.objspace.flow.model import Variable, Block, Link, traverse
-from pypy.translator.simplify import remove_direct_loops
-
-
-class LLVar:
-    "A variable in the low-level language."
-    def __init__(self, type, name):
-        self.type = type   # low-level type in any format, e.g. a C type name
-        self.name = name
-
-class LLConst(LLVar):
-    "A global, constant, preinitialized variable."
-    def __init__(self, type, name, initexpr=None, to_declare=False):
-        LLVar.__init__(self, type, name)
-        self.initexpr = initexpr
-        self.to_declare = to_declare
-
-class LLOp(object):
-    "A low-level operation.  Must be subclassed, one subclass per operation."
-    can_fail = False  # boolean attribute: should an errtarget be generated?
-
-    def __init__(self, args, errtarget=None):
-        self.args = args            # list of LLVars
-        self.errtarget = errtarget  # label to jump to in case of error
-
-    def optimize(self, typer, llresult):
-        """If the operation can be statically optimized, this method can
-        patch the llresult list of LLVars and optionally generate
-        replacement operations by calling typer.operation() or
-        typer.convert().  Can return True to skip the 'self' operation."""
-        return False
-
-class TypingError(Exception):
-    pass
-
-class CannotConvert(Exception):
-    pass
-
-
-# ____________________________________________________________
-#
-# below, a 'typeset' is an object with the following methods/attributes:
-#
-#   def gethltype(self, var_or_const)
-#       Return the high-level type of a var or const.
-#
-#   def represent(self, hltype)
-#       Return a list of LLTypes that together implement the high-level type.
-#
-#   lloperations = {
-#       'opname': {
-#           (tuple-of-hltypes): subclass-of-LLOp,
-#           ... },
-#       ...}
-#       This dict contains the known signatures of each space operation.
-#       Special opnames:
-#         'CASE_XXX'    v : fails (i.e. jump to errlabel) if v is not XXX
-#
-#   rawoperations = {
-#       'opname': subclass-of-LLOp,
-#       ...}
-#       Low-level-only operations on raw LLVars (as opposed to lloperations,
-#       which are on flow.model.Variables as found in SpaceOperations):
-#         'goto'          : fails unconditionally (i.e. jump to errlabel)
-#         'move'    x y   : raw copy of the LLVar x to the LLVar y
-#         'copy' x1 x2.. y1 y2...: raw copy x1 to y1, x2 to y2, etc. and incref
-#         'incref'  x y...: raw incref of the LLVars x, y, etc.
-#         'decref'  x y...: raw decref of the LLVars x, y, etc.
-#         'xdecref' x y...: raw xdecref of the LLVars x, y, etc.
-#         'comment'       : comment (text is in errtarget)
-#         'return'  x y...: return the value stored in the LLVars
-#
-#   def getconvertion(self, hltype1, hltype2):
-#       If it is possible to convert from 'hltype1' to 'hltype2', this
-#       function should return the conversion operation (as a subclass of
-#       LLOp).  Otherwise, it should raise CannotConvert.
-#
-#   def typemismatch(self, opname, hltypes):
-#       Called when no exact match is found in lloperations.  This function
-#       can extend lloperations[opname] to provide a better match for hltypes.
-#       Partial matches (i.e. ones requiring conversions) are only considered
-#       after this function returns.
-# ____________________________________________________________
-
-
-class LLTyper:
-    "Base class for type-oriented low-level generators."
-
-    def __init__(self, typeset):
-        self.gethltype    = typeset.gethltype
-        self.represent    = typeset.represent
-        self.lloperations = typeset.lloperations
-        self.rawoperations= typeset.rawoperations
-        self.getconversion= typeset.getconversion
-        self.typemismatch = typeset.typemismatch
-        self.hltypes = {}
-        self.llreprs = {}
-
-    def makevar(self, v, hltype=None):
-        "Record v in self.hltypes and self.llreprs."
-        if v in self.llreprs:
-            return
-        if hltype is None:
-            hltype = self.gethltype(v)
-        llrepr = []
-        lltypes = self.represent(hltype)
-        for i, lltype in zip(range(len(lltypes)), lltypes):
-            if i:
-                suffix = '_%d' % i
-            else:
-                suffix = ''
-            llrepr.append(LLVar(lltype, v.name + suffix))
-        self.hltypes[v] = hltype
-        self.llreprs[v] = llrepr
-
-# ____________________________________________________________
-
-class LLFunction(LLTyper):
-    "A low-level version of a function from a control flow graph."
-
-    def __init__(self, typeset, name, graph):
-        LLTyper.__init__(self, typeset)
-        remove_direct_loops(graph)
-        self.name = name
-        self.graph = graph
-
-    def ll_header(self):
-        """
-        Get the low-level representation of the header.
-        """
-        llrepr = []
-        for v in self.graph.getargs():
-            self.makevar(v)
-            llrepr += self.llreprs[v]
-        v = self.graph.getreturnvar()
-        self.makevar(v)
-        llret = self.llreprs[v]
-        return llrepr, llret
-
-    def ll_body(self, error_retvals):
-        """
-        Get the body by flattening and low-level-izing the flow graph.
-        Enumerates low-level operations: LLOps with labels inbetween (strings).
-        """
-        self.blockname = {}
-        llreturn = self.rawoperations['return']
-        assert not llreturn.can_fail
-        self.release_root = ReleaseNode(None, llreturn(error_retvals), None)
-        allblocks = []
-        
-        # collect all blocks
-        def visit(block):
-            if isinstance(block, Block):
-                allblocks.append(block)
-                self.blockname[block] = 'block%d' % len(self.blockname)
-                for v in block.inputargs:
-                    self.makevar(v)
-        traverse(visit, self.graph)
-
-        # generate an incref for each input argument
-        for v in self.graph.getargs():
-            yield self.rawoperations['incref'](self.llreprs[v])
-
-        # generate the body of each block
-        for block in allblocks:
-            for op in self.generate_block(block):
-                yield op
-            yield ''   # empty line
-
-        # generate the code to handle errors
-        for op in self.release_root.error_code(self.rawoperations):
-            yield op
-
-    def generate_block(self, block):
-        "Generate the operations for one basic block."
-        self.to_release = self.release_root
-        llrepr = []
-        for v in block.inputargs:
-            llrepr += self.llreprs[v]
-        self.mark_release(llrepr)
-        # entry point
-        self.blockops = [self.blockname[block]]   # label
-        # basic block operations
-        for op in block.operations:
-            self.operation('OP_' + op.opname.upper(), list(op.args), op.result)
-        # exits
-        if block.exits:
-            for exit in block.exits[:-1]:
-                # generate | CASE_XXX v elselabel
-                #          |   copy output vars to next block's input vars
-                #          |   jump to next block
-                #          | elselabel:
-                elselabel = '%s_not%s' % (self.blockname[block], exit.exitcase)
-                self.operation('CASE_%s' % exit.exitcase,
-                               [block.exitswitch],
-                               errlabel = elselabel)
-                self.goto(exit)
-                self.blockops.append(elselabel)
-            # for the last exit, generate only the jump to next block
-            exit = block.exits[-1]
-            self.goto(exit)
-
-        elif hasattr(block, 'exc_type'):
-            XXX("to do")
-        else:
-            llreturn = self.rawoperations['return']
-            assert not llreturn.can_fail
-            llrepr = self.llreprs[block.inputargs[0]]
-            self.blockops.append(llreturn(llrepr))
-        return self.blockops
-
-    # __________ Type checking and conversion routines __________
-
-    def mark_release(self, llrepr):
-        if llrepr:
-            llop = self.rawoperations['decref'](llrepr)
-            # make a new node for the release tree
-            self.to_release = ReleaseNode(llrepr, llop, self.to_release)
-
-    def find_best_match(self, opname, args_t, directions):
-        # look for an exact match first
-        llsigs = self.lloperations.setdefault(opname, {})
-        sig = tuple(args_t)
-        if sig in llsigs:
-            return sig, llsigs[sig]
-        # no exact match, give the typeset a chance to provide an
-        # accurate version
-        self.typemismatch(opname, tuple(args_t))
-        if sig in llsigs:
-            return sig, llsigs[sig]
-        # enumerate the existing operation signatures and their costs
-        choices = []
-        for sig, llopcls in llsigs.items():
-            if len(sig) != len(args_t):
-                continue   # wrong number of arguments
-            try:
-                cost = llopcls.cost
-                for hltype1, hltype2, reverse in zip(args_t, sig,
-                                                     directions):
-                    if hltype1 != hltype2:
-                        if reverse:
-                            hltype1, hltype2 = hltype2, hltype1
-                        convop = self.getconversion(hltype1, hltype2)
-                        cost += convop.cost
-                choices.append((cost, sig, llopcls))
-            except CannotConvert:
-                continue   # non-matching signature
-        if choices:
-            cost, sig, llopcls = min(choices)
-            # for performance, cache the approximate match
-            # back into self.lloperations
-            llsigs[sig] = llopcls
-            return sig, llopcls
-        raise TypingError([opname] + list(args_t))
-
-    def operation(self, opname, args, result=None, errlabel=None):
-        "Helper to build the LLOps for a single high-level operation."
-        # get the hltypes of the input arguments
-        for v in args:
-            self.makevar(v)
-        args_t = [self.hltypes[v] for v in args]
-        directions = [False] * len(args)
-        # append the hltype of the result
-        if result:
-            self.makevar(result)
-            args_t.append(self.hltypes[result])
-            directions.append(True)
-        # look for the low-level operation class that implements these types
-        sig, llopcls = self.find_best_match(opname, args_t, directions)
-        # convert input args to temporary variables, if needed
-        llargs = []
-        for v, v_t, s_t in zip(args, args_t, sig):
-            if v_t != s_t:
-                llargs += self.convert(v_t, self.llreprs[v], s_t)
-            else:
-                llargs += self.llreprs[v]
-        # case-by-case analysis of the result variable
-        if result:
-            if args_t[-1] == sig[-1]:
-                # the result has the correct type
-                self.writeoperation(llopcls, llargs,
-                                    self.llreprs[result], errlabel)
-            else:
-                # the result has to be converted
-                tmp = Variable()
-                self.makevar(tmp, hltype=sig[-1])
-                self.writeoperation(llopcls, llargs,
-                                    self.llreprs[tmp], errlabel)
-                self.convert_variable(tmp, result)
-        else:
-            # no result variable
-            self.writeoperation(llopcls, llargs, [], errlabel)
-
-    def writeoperation(self, llopcls, llargs, llresult, errlabel=None):
-        # generate an error label if the operation can fail
-        if llopcls.can_fail and errlabel is None:
-            errlabel = self.to_release.getlabel()
-        # create the LLOp instance
-        llresultcopy = list(llresult)
-        llop = llopcls(llargs + llresult, errlabel)
-        if llop.optimize(self, llresult):
-            return   # skip the operation
-        # common case: emit the LLOp.
-        self.blockops.append(llop)
-        # all LLVars that are still in llresult (haven't been optimized away)
-        # are new and marked as "to be released".
-        assert len(llresult) == len(llresultcopy)
-        llrepr = [new for new, prev in zip(llresult, llresultcopy)
-                      if new == prev]
-        self.mark_release(llrepr)
-
-    def convert(self, inputtype, inputrepr, outputtype, outputrepr=None):
-        convop = self.getconversion(inputtype, outputtype)
-        if outputrepr is None:
-            tmp = Variable()
-            self.makevar(tmp, hltype=outputtype)
-            outputrepr = self.llreprs[tmp]
-        self.writeoperation(convop, inputrepr, outputrepr)
-        return outputrepr
-
-    def convert_variable(self, v1, v2):
-        self.makevar(v1)
-        self.makevar(v2)
-        convop = self.getconversion(self.hltypes[v1], self.hltypes[v2])
-        self.writeoperation(convop, self.llreprs[v1], self.llreprs[v2])
-
-    def goto(self, exit):
-        # generate the exit.args -> target.inputargs copying operations
-        to_release_copy = self.to_release
-        try:
-            # convert the exit.args to the type expected by the target.inputargs
-            exitargs = []
-            for v, w in zip(exit.args, exit.target.inputargs):
-                self.makevar(v)
-                if self.hltypes[v] != self.hltypes[w]:
-                    tmp = Variable()
-                    self.makevar(tmp, hltype=self.hltypes[w])
-                    self.convert_variable(v, tmp)
-                    v = tmp
-                exitargs.append(v)
-            # move the data from exit.args to target.inputargs
-            # See also remove_direct_loops() for why we don't worry about
-            # the order of the move operations
-            current_refcnt = {}
-            needed_refcnt = {}
-            llmove = self.rawoperations['move']
-            for v, w in zip(exitargs, exit.target.inputargs):
-                for x, y in zip(self.llreprs[v], self.llreprs[w]):
-                    self.blockops.append(llmove([x, y]))
-                    needed_refcnt.setdefault(x, 0)
-                    needed_refcnt[x] += 1
-            # list all variables that go out of scope: by default
-            # they need no reference, but have one reference.
-            for node in self.to_release.getbranch():
-                for x in node.llrepr:
-                    current_refcnt[x] = 1
-                    needed_refcnt.setdefault(x, 0)
-            # now adjust all reference counters: first increfs, then decrefs
-            # (in case a variable to decref points to the same objects than
-            #  another variable to incref).
-            llincref = self.rawoperations['incref']
-            for x, needed in needed_refcnt.items():
-                current_refcnt.setdefault(x, 0)
-                while current_refcnt[x] < needed:
-                    self.blockops.append(llincref([x]))
-                    current_refcnt[x] += 1
-            lldecref = self.rawoperations['decref']
-            for x, needed in needed_refcnt.items():
-                while current_refcnt[x] > needed:
-                    self.blockops.append(lldecref([x]))
-                    current_refcnt[x] -= 1
-            # finally jump to the target block
-            llgoto = self.rawoperations['goto']
-            self.blockops.append(llgoto([], self.blockname[exit.target]))
-        finally:
-            self.to_release = to_release_copy
-            # after a call to goto() we are back to generating ops for
-            # other cases, so we restore the previous self.to_release.
-
-# ____________________________________________________________
-
-# 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
-# parent's parent and so on up to the root.
-class ReleaseNode:
-    accessible = False
-    label = None
-    counter = 0
-    
-    def __init__(self, llrepr, release_operation, parent):
-        self.llrepr = llrepr
-        self.release_operation = release_operation
-        self.parent = parent
-        self.accessible_children = []
-
-    def mark_accessible(self):
-        if not self.accessible:
-            self.accessible = True
-            if self.parent:
-                self.parent.accessible_children.append(self)
-                self.parent.mark_accessible()
-
-    def nextlabel(self):
-        while self.parent:
-            self = self.parent
-        self.counter += 1
-        return 'err%d' % self.counter
-
-    def getlabel(self):
-        if self.label is None:
-            self.mark_accessible()
-            self.label = self.nextlabel()
-        return self.label
-
-    def getbranch(self):
-        while self.parent:
-            yield self
-            self = self.parent
-
-    def error_code(self, rawoperations):
-        N = len(self.accessible_children)
-        for i in range(N):
-            if i > 0:
-                llgoto = rawoperations['goto']
-                yield llgoto([], self.getlabel())
-            node = self.accessible_children[~i]
-            for op in node.error_code(rawoperations):
-                yield op
-        if self.label:
-            yield self.label
-        elif not N:
-            return
-        yield self.release_operation



More information about the Pypy-commit mailing list