[pypy-svn] pypy default: (lac, arigo)

arigo commits-noreply at bitbucket.org
Thu Jan 20 11:52:01 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r40970:88878852dd75
Date: 2011-01-20 11:48 +0100
http://bitbucket.org/pypy/pypy/changeset/88878852dd75/

Log:	(lac, arigo)

	Merge the cmath branch, implementing cmath at interp-level.

diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -204,49 +204,61 @@
             container[name] = index
         return index
 
-    def add_const(self, obj, w_key=None):
+    def add_const(self, obj):
         """Add a W_Root to the constant array and return its location."""
         space = self.space
-        # To avoid confusing equal but separate types, we hash store the type of
-        # the constant in the dictionary.
-        if w_key is None:
-            # We have to keep the difference between -0.0 and 0.0 floats.
-            w_type = space.type(obj)
-            if space.is_w(w_type, space.w_float):
-                val = space.float_w(obj)
-                if val == 0.0 and rarithmetic.copysign(1., val) < 0:
-                    w_key = space.newtuple([obj, space.w_float, space.w_None])
-                else:
-                    w_key = space.newtuple([obj, space.w_float])
-            elif space.is_w(w_type, space.w_complex):
-                w_real = space.getattr(obj, space.wrap("real"))
-                w_imag = space.getattr(obj, space.wrap("imag"))
-                real = space.float_w(w_real)
-                imag = space.float_w(w_imag)
-                real_negzero = (real == 0.0 and
-                                rarithmetic.copysign(1., real) < 0)
-                imag_negzero = (imag == 0.0 and
-                                rarithmetic.copysign(1., imag) < 0)
-                if real_negzero and imag_negzero:
-                    tup = [obj, space.w_complex, space.w_None, space.w_None,
-                           space.w_None]
-                elif imag_negzero:
-                    tup = [obj, space.w_complex, space.w_None, space.w_None]
-                elif real_negzero:
-                    tup = [obj, space.w_complex, space.w_None]
-                else:
-                    tup = [obj, space.w_complex]
-                w_key = space.newtuple(tup)
-            else:
-                w_key = space.newtuple([obj, w_type])
+        # To avoid confusing equal but separate types, we hash store the type
+        # of the constant in the dictionary.  Moreover, we have to keep the
+        # difference between -0.0 and 0.0 floats, and this recursively in
+        # tuples.
+        w_key = self._make_key(obj)
+
         w_len = space.finditem(self.w_consts, w_key)
         if w_len is None:
             w_len = space.len(self.w_consts)
             space.setitem(self.w_consts, w_key, w_len)
         return space.int_w(w_len)
 
-    def load_const(self, obj, w_key=None):
-        index = self.add_const(obj, w_key)
+    def _make_key(self, obj):
+        # see the tests 'test_zeros_not_mixed*' in ../test/test_compiler.py
+        space = self.space
+        w_type = space.type(obj)
+        if space.is_w(w_type, space.w_float):
+            val = space.float_w(obj)
+            if val == 0.0 and rarithmetic.copysign(1., val) < 0:
+                w_key = space.newtuple([obj, space.w_float, space.w_None])
+            else:
+                w_key = space.newtuple([obj, space.w_float])
+        elif space.is_w(w_type, space.w_complex):
+            w_real = space.getattr(obj, space.wrap("real"))
+            w_imag = space.getattr(obj, space.wrap("imag"))
+            real = space.float_w(w_real)
+            imag = space.float_w(w_imag)
+            real_negzero = (real == 0.0 and
+                            rarithmetic.copysign(1., real) < 0)
+            imag_negzero = (imag == 0.0 and
+                            rarithmetic.copysign(1., imag) < 0)
+            if real_negzero and imag_negzero:
+                tup = [obj, space.w_complex, space.w_None, space.w_None,
+                       space.w_None]
+            elif imag_negzero:
+                tup = [obj, space.w_complex, space.w_None, space.w_None]
+            elif real_negzero:
+                tup = [obj, space.w_complex, space.w_None]
+            else:
+                tup = [obj, space.w_complex]
+            w_key = space.newtuple(tup)
+        elif space.is_w(w_type, space.w_tuple):
+            result_w = [obj, w_type]
+            for w_item in space.fixedview(obj):
+                result_w.append(self._make_key(w_item))
+            w_key = space.newtuple(result_w[:])
+        else:
+            w_key = space.newtuple([obj, w_type])
+        return w_key
+
+    def load_const(self, obj):
+        index = self.add_const(obj)
         self.emit_op_arg(ops.LOAD_CONST, index)
 
     def update_position(self, lineno, force=False):

diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -266,6 +266,10 @@
     def newcomplex(self, realval, imagval):
         return W_ComplexObject(realval, imagval)
 
+    def unpackcomplex(self, w_complex):
+        from pypy.objspace.std.complextype import unpackcomplex
+        return unpackcomplex(self, w_complex)
+
     def newlong(self, val): # val is an int
         return W_LongObject.fromint(self, val)
 

diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -163,11 +163,16 @@
     immutable = True
 
     def __eq__(self, other):
-        # NaN unpleasantness.
         if (type(self) is SomeFloat and type(other) is SomeFloat and
-            self.is_constant() and other.is_constant() and
-            isnan(self.const) and isnan(other.const)):
-            return True
+            self.is_constant() and other.is_constant()):
+            # NaN unpleasantness.
+            if isnan(self.const) and isnan(other.const):
+                return True
+            # 0.0 vs -0.0 unpleasantness.
+            if not self.const and not other.const:
+                from pypy.rlib.rarithmetic import copysign
+                return copysign(1., self.const) == copysign(1., other.const)
+            #
         return super(SomeFloat, self).__eq__(other)
 
     def can_be_none(self):


More information about the Pypy-commit mailing list