[pypy-svn] r47851 - in pypy/dist/pypy/lang/smalltalk: . test

lukas at codespeak.net lukas at codespeak.net
Wed Oct 24 18:51:29 CEST 2007


Author: lukas
Date: Wed Oct 24 18:51:29 2007
New Revision: 47851

Modified:
   pypy/dist/pypy/lang/smalltalk/interpreter.py
   pypy/dist/pypy/lang/smalltalk/primitives.py
   pypy/dist/pypy/lang/smalltalk/test/test_primitives.py
Log:
(lr) bit shift primitive



Modified: pypy/dist/pypy/lang/smalltalk/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/interpreter.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/interpreter.py	Wed Oct 24 18:51:29 2007
@@ -331,16 +331,16 @@
         raise MissingBytecode
 
     def bytecodePrimBitShift(self, interp):
-        raise MissingBytecode
+        self.callPrimitiveAndPush(primitives.BIT_SHIFT, "bitShift:", 1, interp)
 
     def bytecodePrimDiv(self, interp):
         self.callPrimitiveAndPush(primitives.DIV, "//", 1, interp)
 
     def bytecodePrimBitAnd(self, interp):
-        raise MissingBytecode
+        self.callPrimitiveAndPush(primitives.BIT_AND, "&&", 1, interp)
 
     def bytecodePrimBitOr(self, interp):
-        raise MissingBytecode
+        self.callPrimitiveAndPush(primitives.BIT_OR, "||", 1, interp)
 
     def bytecodePrimAt(self, interp):
         raise MissingBytecode

Modified: pypy/dist/pypy/lang/smalltalk/primitives.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/primitives.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/primitives.py	Wed Oct 24 18:51:29 2007
@@ -77,11 +77,18 @@
 MOD         = 11
 DIV         = 12
 QUO         = 13
+BIT_AND     = 14
+BIT_OR      = 15
+BIT_XOR     = 16
+BIT_SHIFT   = 17
 
 math_ops = {
     ADD: operator.add,
     SUBTRACT: operator.sub,
     MULTIPLY: operator.mul,
+    BIT_AND: operator.and_,
+    BIT_OR: operator.or_,
+    BIT_XOR: operator.xor
     }
 for (code,op) in math_ops.items():
     @primitive(code)
@@ -141,6 +148,30 @@
     if argument == 0:
         raise PrimitiveFailedError()
     return wrap_int(receiver // argument)
+    
+# #bitShift: -- return the shifted value
+ at primitive(BIT_SHIFT)
+ at stack(2)
+def func(stack):
+    [w_receiver, w_argument] = stack
+    receiver = unwrap_int(w_receiver)
+    argument = unwrap_int(w_argument)
+    
+    # heh, no shifting at all
+    if argument == 0:
+        return w_receiver
+
+    # left shift, must fail if we loose bits beyond 32
+    if argument > 0:
+        shifted = receiver << argument
+        if (shifted >> argument) != receiver:
+            raise PrimitiveFailedError()
+        return wrap_int(shifted)
+            
+    # right shift, ok to lose bits
+    else:
+        return wrap_int(receiver >> -argument)
+   
 
 # ___________________________________________________________________________
 # Float Primitives

Modified: pypy/dist/pypy/lang/smalltalk/test/test_primitives.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/test/test_primitives.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/test/test_primitives.py	Wed Oct 24 18:51:29 2007
@@ -78,7 +78,57 @@
 def test_small_int_quo_fail():
     prim_fails(p.QUO, [12, 0])
     
-
+def test_small_int_bit_and():
+    assert prim(p.BIT_AND, [2, 4]).value == 0
+    assert prim(p.BIT_AND, [2, 3]).value == 2
+    assert prim(p.BIT_AND, [3, 4]).value == 0
+    assert prim(p.BIT_AND, [4, 4]).value == 4
+    
+def test_small_int_bit_or():
+    assert prim(p.BIT_OR, [2, 4]).value == 6
+    assert prim(p.BIT_OR, [2, 3]).value == 3
+    assert prim(p.BIT_OR, [3, 4]).value == 7
+    assert prim(p.BIT_OR, [4, 4]).value == 4
+
+def test_small_int_bit_xor():
+    assert prim(p.BIT_XOR, [2, 4]).value == 6
+    assert prim(p.BIT_XOR, [2, 3]).value == 1
+    assert prim(p.BIT_XOR, [3, 4]).value == 7
+    assert prim(p.BIT_XOR, [4, 4]).value == 0
+
+def test_small_int_bit_shift():
+    assert prim(p.BIT_SHIFT, [0, -3]).value == 0
+    assert prim(p.BIT_SHIFT, [0, -2]).value == 0
+    assert prim(p.BIT_SHIFT, [0, -1]).value == 0
+    assert prim(p.BIT_SHIFT, [0, 0]).value == 0
+    assert prim(p.BIT_SHIFT, [0, 1]).value == 0
+    assert prim(p.BIT_SHIFT, [0, 2]).value == 0
+    assert prim(p.BIT_SHIFT, [0, 3]).value == 0
+    
+def test_small_int_bit_shift_positive():
+    assert prim(p.BIT_SHIFT, [4, -3]).value == 0
+    assert prim(p.BIT_SHIFT, [4, -2]).value == 1
+    assert prim(p.BIT_SHIFT, [4, -1]).value == 2
+    assert prim(p.BIT_SHIFT, [4, 0]).value == 4
+    assert prim(p.BIT_SHIFT, [4, 1]).value == 8
+    assert prim(p.BIT_SHIFT, [4, 2]).value == 16
+    assert prim(p.BIT_SHIFT, [4, 3]).value == 32
+    
+def test_small_int_bit_shift_negative():
+    assert prim(p.BIT_SHIFT, [-4, -3]).value == -1
+    assert prim(p.BIT_SHIFT, [-4, -2]).value == -1
+    assert prim(p.BIT_SHIFT, [-4, -1]).value == -2
+    assert prim(p.BIT_SHIFT, [-4, 0]).value == -4
+    assert prim(p.BIT_SHIFT, [-4, 1]).value == -8
+    assert prim(p.BIT_SHIFT, [-4, 2]).value == -16
+    assert prim(p.BIT_SHIFT, [-4, 3]).value == -32
+    
+def test_small_int_bit_shift_fail():
+    prim_fails(p.BIT_SHIFT, [4, 32])
+    prim_fails(p.BIT_SHIFT, [4, 31])
+    prim_fails(p.BIT_SHIFT, [4, 30])
+    prim_fails(p.BIT_SHIFT, [4, 29])
+    prim_fails(p.BIT_SHIFT, [4, 28])
 
 def test_float():
     assert prim(p.FLOAT_ADD, [1.0,2.0]).value == 3.0



More information about the Pypy-commit mailing list