[pypy-svn] r33803 - in pypy/dist/pypy: annotation rpython/ootypesystem

antocuni at codespeak.net antocuni at codespeak.net
Fri Oct 27 12:11:54 CEST 2006


Author: antocuni
Date: Fri Oct 27 12:11:53 2006
New Revision: 33803

Modified:
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/rpython/ootypesystem/ootype.py
Log:
Get rid of _overloaded_mixin for overloading resolution, but use
OverloadingResolver instead: this is no longer a mixin but a class
meant to be instantiated: this means that backends can easly override
the default behaviour of OverloadingResolver by simply pass their own
class.



Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Fri Oct 27 12:11:53 2006
@@ -706,7 +706,7 @@
         inst = m.ootype._example()
         _, meth = m.ootype._lookup(m.name)
         if isinstance(meth, ootype._overloaded_meth):
-            return meth._annotate_overloading(args_s)
+            return meth._resolver.annotate(args_s)
         else:
             METH = ootype.typeOf(meth)
             return lltype_to_annotation(METH.RESULT)

Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py	Fri Oct 27 12:11:53 2006
@@ -870,7 +870,7 @@
 
     def _get_bound_meth(self, *args):
         ARGS = tuple([typeOf(arg) for arg in args])
-        meth = self.meth._resolve_overloading(ARGS)
+        meth = self.meth._resolver.resolve(ARGS)
         assert isinstance(meth, _meth)
         return meth._bound(self.DEFINST, self.inst)
 
@@ -879,27 +879,38 @@
         return bound_meth(*args)
 
 
-class _overloaded_mixin(object):
+class OverloadingResolver(object):
+
+    def __init__(self, overloadings):
+        self.overloadings = overloadings
+        self._check_overloadings()
+
     def _check_overloadings(self):
         signatures = set()
-        for meth in self._overloadings:
+        for meth in self.overloadings:
             ARGS = meth._TYPE.ARGS
             if ARGS in signatures:
                 raise TypeError, 'Bad overloading'
             signatures.add(ARGS)
 
-    def _resolve_overloading(self, ARGS):
+    def annotate(self, args_s):
+        ARGS = tuple([self.annotation_to_lltype(arg_s) for arg_s in args_s])
+        METH = self.resolve(ARGS)._TYPE
+        return self.lltype_to_annotation(METH.RESULT)
+
+
+    def resolve(self, ARGS):
         # this overloading resolution algorithm is quite simple:
         # 1) if there is an exact match between ARGS and meth.ARGS, return meth
         # 2) if there is *only one* meth such as ARGS can be converted
         #    to meth.ARGS with one or more upcasts, return meth
         # 3) otherwise, fail
         matches = []
-        for meth in self._overloadings:
+        for meth in self.overloadings:
             METH = meth._TYPE
             if METH.ARGS == ARGS:
                 return meth # case 1
-            elif self._check_upcast(ARGS, METH.ARGS):
+            elif self._check_signature(ARGS, METH.ARGS):
                 matches.append(meth)
         if len(matches) == 1:
             return matches[0]
@@ -908,22 +919,21 @@
         else:
             raise TypeError, 'No suitable overloading found for method'
 
-    def _check_upcast(self, ARGS1, ARGS2):
+    def _check_signature(self, ARGS1, ARGS2):
         if len(ARGS1) != len(ARGS2):
             return False
         for ARG1, ARG2 in zip(ARGS1, ARGS2):
-            if not (isinstance(ARG1, Instance) and isinstance(ARG2, Instance)):
-                return False
-            if not isSubclass(ARG1, ARG2):
+            if not self._can_convert_from_to(ARG1, ARG2):
                 return False
         return True
 
-    def _annotate_overloading(self, args_s):
-        ARGS = tuple([self._annotation_to_lltype(arg_s) for arg_s in args_s])
-        METH = self._resolve_overloading(ARGS)._TYPE
-        return self._lltype_to_annotation(METH.RESULT)
-
-    def _annotation_to_lltype(cls, ann):
+    def _can_convert_from_to(self, ARG1, ARG2):
+        if isinstance(ARG1, Instance) and isinstance(ARG2, Instance) and isSubclass(ARG1, ARG2):
+            return True
+        else:
+            return False
+    
+    def annotation_to_lltype(cls, ann):
         from pypy.annotation import model as annmodel
         if isinstance(ann, annmodel.SomeChar):
             return Char
@@ -931,9 +941,9 @@
             return String
         else:
             return annmodel.annotation_to_lltype(ann)
-    _annotation_to_lltype = classmethod(_annotation_to_lltype)
+    annotation_to_lltype = classmethod(annotation_to_lltype)
 
-    def _lltype_to_annotation(cls, TYPE):
+    def lltype_to_annotation(cls, TYPE):
         from pypy.annotation import model as annmodel
         if TYPE is Char:
             return annmodel.SomeChar()
@@ -941,21 +951,21 @@
             return annmodel.SomeString()
         else:
             return annmodel.lltype_to_annotation(TYPE)
-    _lltype_to_annotation = classmethod(_lltype_to_annotation)
+    lltype_to_annotation = classmethod(lltype_to_annotation)
 
 
-class _overloaded_meth(_meth, _overloaded_mixin):
+class _overloaded_meth(_meth):
     _bound_class = _overloaded_bound_meth
     _desc_class = _overloaded_meth_desc
 
     def __init__(self, *overloadings, **attrs):
         assert '_callable' not in attrs
+        resolver = attrs.pop('resolver', OverloadingResolver)
         _meth.__init__(self, Meth([], Void), _callable=None, **attrs) # use a fake method type
-        self._overloadings = overloadings
-        self._check_overloadings()
+        self._resolver = resolver(overloadings)
 
     def _get_desc(self, name, ARGS):
-        meth = self._resolve_overloading(ARGS)
+        meth = self._resolver.resolve(ARGS)
         return _overloaded_meth_desc(name, meth._TYPE)
 
 



More information about the Pypy-commit mailing list