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

nik at codespeak.net nik at codespeak.net
Thu Mar 16 18:13:30 CET 2006


Author: nik
Date: Thu Mar 16 18:13:19 2006
New Revision: 24488

Modified:
   pypy/dist/pypy/translator/squeak/codeformatter.py
   pypy/dist/pypy/translator/squeak/gensqueak.py
   pypy/dist/pypy/translator/squeak/node.py
   pypy/dist/pypy/translator/squeak/opformatter.py
   pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py
Log:
look again closely into nameclash issues, pass some new tests.
route all unique name generation through the GenSqueak class,
all node scheduling should get through there as well soon.


Modified: pypy/dist/pypy/translator/squeak/codeformatter.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/codeformatter.py	(original)
+++ pypy/dist/pypy/translator/squeak/codeformatter.py	Thu Mar 16 18:13:19 2006
@@ -107,19 +107,14 @@
         elif isinstance(value, ootype._class):
             return self.format_Instance(value._INSTANCE)
         elif isinstance(value, ootype._static_meth):
-            return self.gen.unique_func_name(value.graph.func)
+            return self.gen.unique_func_name(value.graph)
         else:
             raise TypeError, "can't format constant (%s)" % value
 
     def format_Instance(self, INSTANCE):
         if INSTANCE is None:
             return "Object"
-        from pypy.translator.squeak.node import ClassNode
-        # XXX move scheduling/unique name thingies to gensqueak.py
-        self.gen.schedule_node(ClassNode(self.gen, INSTANCE))
-        class_name = INSTANCE._name.split(".")[-1]
-        squeak_class_name = self.gen.unique_name(INSTANCE, class_name)
-        return "Py%s" % squeak_class_name
+        return self.gen.unique_class_name(INSTANCE)
 
     def format_Self(self, _):
         return "self"

Modified: pypy/dist/pypy/translator/squeak/gensqueak.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/gensqueak.py	(original)
+++ pypy/dist/pypy/translator/squeak/gensqueak.py	Thu Mar 16 18:13:19 2006
@@ -1,6 +1,7 @@
 from pypy.translator.gensupp import NameManager
 from pypy.translator.squeak.codeformatter import camel_case
 from pypy.translator.squeak.node import FunctionNode, ClassNode, SetupNode
+from pypy.translator.squeak.node import MethodNode
 try:
     set
 except NameError:
@@ -54,11 +55,28 @@
                 self.pending_nodes.remove(node)
             self.pending_nodes.append(node)
 
-    def unique_func_name(self, function):
-        # XXX do FunctionNode registering here
+    def unique_func_name(self, funcgraph, schedule=True):
+        function = funcgraph.func
         squeak_func_name = self.unique_name(function, function.__name__)
+        if schedule:
+            self.schedule_node(FunctionNode(self, funcgraph))
         return squeak_func_name
         
+    def unique_method_name(self, INSTANCE, method_name, schedule=True):
+        # XXX it's actually more complicated than that because of
+        # inheritance ...
+        squeak_method_name = self.unique_name(
+                (INSTANCE, method_name), method_name)
+        if schedule:
+            self.schedule_node(MethodNode(self, INSTANCE, method_name))
+        return squeak_method_name
+        
+    def unique_class_name(self, INSTANCE):
+        self.schedule_node(ClassNode(self, INSTANCE))
+        class_name = INSTANCE._name.split(".")[-1]
+        squeak_class_name = self.unique_name(INSTANCE, class_name)
+        return "Py%s" % squeak_class_name
+
     def unique_name(self, key, basename):
         if self.unique_name_mapping.has_key(key):
             unique = self.unique_name_mapping[key]

Modified: pypy/dist/pypy/translator/squeak/node.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/node.py	(original)
+++ pypy/dist/pypy/translator/squeak/node.py	Thu Mar 16 18:13:19 2006
@@ -84,7 +84,7 @@
         self.codef = CodeFormatter(self.gen)
         self.loops = LoopFinder(startblock).loops
         args = self.arguments(startblock)
-        message = Message(self.name).with_args(args)
+        message = Message(self.unique_name).with_args(args)
         yield self.codef.format(message)
  
         # XXX should declare local variables here
@@ -157,6 +157,8 @@
         self.gen = gen
         self.INSTANCE = INSTANCE
         self.name = method_name
+        self.unique_name = gen.unique_method_name(
+                INSTANCE, method_name, schedule=False)
         self.self = None # Will be set upon rendering
         self.hash_key = (INSTANCE, method_name)
 
@@ -183,8 +185,9 @@
     def __init__(self, gen, graph):
         self.gen = gen
         self.graph = graph
-        self.name = gen.unique_func_name(graph.func) # XXX messy
+        self.unique_name = gen.unique_func_name(graph, schedule=False)
         self.self = None
+        self._class_name = gen.unique_class_name(self.FUNCTIONS)
         self.hash_key = graph
 
     def dependencies(self):
@@ -194,7 +197,8 @@
         return startblock.inputargs
     
     def render(self):
-        yield self.render_fileout_header("PyFunctions class", "functions")
+        yield self.render_fileout_header(
+                "%s class" % self._class_name, "functions")
         for line in self.render_body(self.graph.startblock):
             yield line
 
@@ -236,6 +240,7 @@
         self.gen = gen
         self.message = message
         self.code = code
+        self._class_name = gen.unique_class_name(self.HELPERS)
         self.hash_key = ("helper", code)
 
     def apply(self, args):
@@ -246,7 +251,8 @@
 
     def render(self):
         # XXX should not use explicit name "PyHelpers" here
-        yield self.render_fileout_header("PyHelpers class", "helpers")
+        yield self.render_fileout_header(
+                "%s class" % self._class_name, "helpers")
         for line in self.code.strip().split("\n"):
             yield line
         yield "! !"
@@ -282,6 +288,7 @@
     def __init__(self, gen, constants):
         self.gen = gen
         self.constants = constants
+        self._class_name = gen.unique_class_name(self.CONSTANTS)
         self.hash_key = "setup"
 
     def dependencies(self):
@@ -293,7 +300,8 @@
     def render(self):
         codef = CodeFormatter(self.gen)
         # XXX use CodeFormatter throughout here
-        yield self.render_fileout_header("PyConstants class", "internals")
+        yield self.render_fileout_header(
+                "%s class" % self._class_name, "internals")
         message = Message("setupConstants")
         yield codef.format(message.with_args([]))
         yield "    Constants := Dictionary new."
@@ -308,7 +316,8 @@
         yield "! !"
         yield ""
 
-        yield self.render_fileout_header("PyConstants class", "internals")
+        yield self.render_fileout_header(
+                "%s class" % self._class_name, "internals")
         arg = CustomVariable("constId")
         get_message = Message("getConstant")
         yield codef.format(get_message.with_args([arg]))

Modified: pypy/dist/pypy/translator/squeak/opformatter.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/opformatter.py	(original)
+++ pypy/dist/pypy/translator/squeak/opformatter.py	Thu Mar 16 18:13:19 2006
@@ -84,13 +84,12 @@
 
     def op_oosend(self, op):
         message_name = op.args[0].value
+        message_name = self.gen.unique_method_name(
+                op.args[1].concretetype, message_name)
         if op.args[1] == self.node.self:
             receiver = Self()
         else:
             receiver = op.args[1]
-        from pypy.translator.squeak.node import MethodNode
-        self.gen.schedule_node(
-                MethodNode(self.gen, op.args[1].concretetype, message_name))
         sent_message = Message(message_name).send_to(receiver, op.args[2:])
         return  self.codef.format(sent_message.assign_to(op.result))
 
@@ -128,10 +127,9 @@
         return self.codef.format(Assignment(op.result, op.args[0]))
 
     def op_direct_call(self, op):
+        # XXX how do i get rid of this import?
         from pypy.translator.squeak.node import FunctionNode
-        function_name = self.codef.format(op.args[0])
-        self.gen.schedule_node(
-            FunctionNode(self.gen, op.args[0].value.graph))
+        function_name = self.gen.unique_func_name(op.args[0].value.graph)
         msg = Message(function_name).send_to(FunctionNode.FUNCTIONS, op.args[1:])
         return self.codef.format(msg.assign_to(op.result))
 

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	Thu Mar 16 18:13:19 2006
@@ -39,8 +39,10 @@
         from pypy.translator.squeak.test.support import A as A2
         class A:
             def m(self, i): return 2 + i
+        class Functions:
+            def m(self, i): return 1 + i
         def f():
-            return A().m(0) + A2().m(0)
+            return A().m(0) + A2().m(0) + Functions().m(-1)
         fn = compile_function(f)
         assert fn() == "3"
 
@@ -75,6 +77,16 @@
         fn = compile_function(g)
         assert fn() == "3"
 
+    def test_nameclash_methods(self):
+        class A:
+            def some_method(self, i): return i + 1
+            def someMethod(self, i): return i + 2
+        def f():
+            a = A()
+            return a.some_method(0) + a.someMethod(0)
+        fn = compile_function(f)
+        assert fn() == "3"
+
     def test_direct_call(self):
         def h(i):
             return g(i) + 1 # another call to g to try to trap GenSqueak



More information about the Pypy-commit mailing list