[pypy-svn] r24321 - in pypy/dist/pypy/translator/squeak: . test

nik at codespeak.net nik at codespeak.net
Mon Mar 13 23:16:32 CET 2006


Author: nik
Date: Mon Mar 13 23:16:26 2006
New Revision: 24321

Modified:
   pypy/dist/pypy/translator/squeak/gensqueak.py
   pypy/dist/pypy/translator/squeak/test/test_llops.py
   pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py
Log:
- an attempt at a general solution to integer llops and wraparound
  for the various rpython datatypes. still a bit clumsy.
- deleted old tests that didn't really prove anything and are hard
  to keep green with gensqueak heavily in flux.


Modified: pypy/dist/pypy/translator/squeak/gensqueak.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/gensqueak.py	(original)
+++ pypy/dist/pypy/translator/squeak/gensqueak.py	Mon Mar 13 23:16:26 2006
@@ -244,19 +244,34 @@
         'runtimenew':    Selector('new', 0),
         'classof':       Selector('class', 0),
         'sameAs':        Selector('yourself', 0), 
-        
-        # XXX need to handle overflow for all integer ops
-        'intAbs':        Selector('abs', 0),
-        'intIsTrue':     Selector('isZero not', 0),
-        'intNeg':        Selector('negated', 0),
-        'intInvert':     Selector('bitInvert', 0), # maybe bitInvert32?
-
-        'intAdd:':       Selector('+', 1),
-        'intSub:':       Selector('-', 1),
-        'intEq:':        Selector('=', 1),
-        'intMul:':       Selector('*', 1),
-        'intDiv:':       Selector('//', 1),
-        'intFloordiv:':  Selector('//', 1),
+    }
+
+    primitive_ops = {
+        'abs':       'abs',
+        'is_true':   'isZero not',
+        'neg':       'negated',
+        'invert':    'bitInvert', # maybe bitInvert32?
+
+        'add':       '+',
+        'sub':       '-',
+        'eq':        '=',
+        'mul':       '*',
+        'div':       '//',
+        'floordiv':  '//',
+    }
+    
+    primitive_opprefixes = "int", "uint", "llong", "ullong", "float"
+
+    primitive_wrapping_ops = "add", "sub", "mul"
+
+    primitive_masks = {
+        # XXX horrendous, but I can't figure out how to do this cleanly
+        "int": (Selector("maskInt", 1),
+                """maskInt: i 
+                    ((i <= %s) & (i >= %s)) ifTrue: [^i].
+                    ^ i + %s \\\\ %s - %s
+                  """ % (sys.maxint, -sys.maxint-1,
+                      sys.maxint+1, 2*(sys.maxint+1), sys.maxint+1)),
     }
 
     def render_body(self, startblock):
@@ -284,6 +299,10 @@
             raise TypeError, "expr(%r)" % (v,)
 
     def oper(self, op):
+        opname_parts = op.opname.split("_")
+        if opname_parts[0] in self.primitive_opprefixes:
+            return self.oper_primitive(
+                    op, opname_parts[0], "_".join(opname_parts[1:]))
         op_method = getattr(self, "op_%s" % op.opname, None)
         if op_method is not None:
             return op_method(op)
@@ -293,6 +312,19 @@
             args = [self.expr(arg) for arg in op.args[1:]]
             return self.assignment(op, receiver, name, args)
 
+    def oper_primitive(self, op, ptype, opname):
+        receiver = self.expr(op.args[0])
+        args = [self.expr(arg) for arg in op.args[1:]]
+        sel = Selector(self.primitive_ops[opname], len(args))
+        message = "%s %s" % (receiver, sel.signature(args))
+        if opname in self.primitive_wrapping_ops \
+                and self.primitive_masks.has_key(ptype):
+            mask_selector, mask_code = self.primitive_masks[ptype]
+            helper = HelperNode(self.gen, mask_selector, mask_code)
+            message = helper.apply(["(%s)" % message])
+            self.gen.schedule_node(helper)
+        return "%s := %s." % (self.expr(op.result), message)
+
     def assignment(self, op, receiver_name, sel_name, arg_names):
         sel = Selector(sel_name, len(arg_names))
         if op.opname != "oosend":
@@ -482,6 +514,29 @@
         yield "    ^%s" % self.field_name
         yield "! !"
 
+class HelperNode(CodeNode):
+    
+    HELPERS = Instance("Helpers", ROOT)
+
+    def __init__(self, gen, selector, code):
+        self.gen = gen
+        self.selector = selector
+        self.code = code
+        self.hash_key = ("helper", code)
+
+    def apply(self, args):
+        return "PyHelpers %s" % self.selector.signature(args)
+    
+    def dependencies(self):
+        return [ClassNode(self.gen, self.HELPERS)]
+
+    def render(self):
+        # XXX should not use explicit name "PyHelpers" here
+        yield self.render_fileout_header("PyHelpers class", "helpers")
+        for line in self.code.strip().split("\n"):
+            yield line
+        yield "! !"
+
 class FieldInitializerNode(CodeNode):
 
     def __init__(self, gen, INSTANCE):

Modified: pypy/dist/pypy/translator/squeak/test/test_llops.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/test/test_llops.py	(original)
+++ pypy/dist/pypy/translator/squeak/test/test_llops.py	Mon Mar 13 23:16:26 2006
@@ -1,3 +1,4 @@
+import sys
 from pypy.translator.squeak.test.runtest import compile_function
 from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy
 from pypy.rpython.lltypesystem.lloperation import llop
@@ -20,12 +21,10 @@
     sqfunc = compile_function(lloptest, annotation)
     expected_res = interpret(lloptest, args, policy=LowLevelAnnotatorPolicy())
     res = sqfunc(*args)
-    assert res == str(res).lower() # lowercasing for booleans
+    assert res == str(expected_res).lower() # lowercasing for booleans
 
 def test_intoperations():
     tests = [
-        # XXX Must handle overflows for all integer ops
-
         # unary
         ("int_abs", Signed, 7),
         ("int_abs", Signed, -7),
@@ -43,6 +42,11 @@
         ("int_div", Signed, 7, 3),
         ("int_floordiv", Signed, 7, 3),
         ("int_floordiv", Signed, -7, 3),
+
+        # binary wraparounds
+        ("int_add", Signed, sys.maxint, 1),
+        ("int_sub", Signed, -sys.maxint-1, 2),
+        ("int_mul", Signed, sys.maxint/2, 3),
     ]
     for t in tests:
         yield optest, t

Modified: pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py	(original)
+++ pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py	Mon Mar 13 23:16:26 2006
@@ -4,28 +4,6 @@
 from pypy.translator.squeak.gensqueak import Selector, camel_case
 from pypy.translator.squeak.test.runtest import compile_function
 
-
-def looping(i, j):
-    while i > 0:
-        i -= 1
-        while j > 0:
-            j -= 1
-
-class TestSqueakTrans:
-
-    def test_simple_func(self):
-        compile_function(snippet.simple_func, [int])
-
-    def test_if_then_else(self):
-        compile_function(snippet.if_then_else, [bool, int, int])
-
-    def test_my_gcd(self):
-        compile_function(snippet.my_gcd, [int, int])
-
-    def test_looping(self):
-        compile_function(looping, [int, int])
-
-
 class TestGenSqueak:
 
     def test_theanswer(self):



More information about the Pypy-commit mailing list