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

nik at codespeak.net nik at codespeak.net
Thu Mar 16 21:45:37 CET 2006


Author: nik
Date: Thu Mar 16 21:45:36 2006
New Revision: 24493

Modified:
   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:
somewhat resolve unique field name issues.


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 21:45:36 2006
@@ -1,7 +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
+from pypy.translator.squeak.node import MethodNode, SetterNode, GetterNode
 try:
     set
 except NameError:
@@ -77,7 +77,22 @@
         squeak_class_name = self.unique_name(INSTANCE, class_name)
         return "Py%s" % squeak_class_name
 
+    def unique_field_name(self, INSTANCE, field_name, schedule=True):
+        # XXX nameclashes with superclasses must be considered, too.
+        while not INSTANCE._fields.has_key(field_name):
+            # This is necessary to prevent a field from having different
+            # unique names in different subclasses.
+            INSTANCE = INSTANCE._superclass
+        if schedule:
+            # Generating getters and setters for all fields by default which
+            # is potentially a waste, but easier for now.
+            self.schedule_node(SetterNode(self, INSTANCE, field_name))
+            self.schedule_node(GetterNode(self, INSTANCE, field_name))
+        return self.unique_name(
+                (INSTANCE, "field", field_name), field_name)
+
     def unique_name(self, key, basename):
+        # XXX should account for squeak keywords here
         if self.unique_name_mapping.has_key(key):
             unique = self.unique_name_mapping[key]
         else:
@@ -86,4 +101,3 @@
             self.unique_name_mapping[key] = unique
         return unique
 
-

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 21:45:36 2006
@@ -19,12 +19,6 @@
                 class_name, category,
                 datetime.datetime.now().strftime("%m/%d/%Y %H:%M"))
 
-    def unique_field(self, INSTANCE, field_name):
-        # XXX for now we ignore the issue of nameclashes between
-        # field names. It's not so simple because superclasses must
-        # be considered, too.
-        return camel_case(field_name)
-
 class ClassNode(CodeNode):
 
     def __init__(self, gen, INSTANCE, class_vars=None):
@@ -36,17 +30,17 @@
         self.hash_key = INSTANCE
 
     def dependencies(self):
+        deps = []
         if self.INSTANCE._superclass is not None: # not root
-            return [ClassNode(self.gen, self.INSTANCE._superclass)]
-        else:
-            return []
+            deps.append(ClassNode(self.gen, self.INSTANCE._superclass))
+        return deps
 
     def render(self):
         codef = CodeFormatter(self.gen)
         yield "%s subclass: #%s" % (
             codef.format_Instance(self.INSTANCE._superclass), 
             codef.format_Instance(self.INSTANCE))
-        fields = [self.unique_field(self.INSTANCE, f) for f in
+        fields = [self.gen.unique_field_name(self.INSTANCE, f) for f in
             self.INSTANCE._fields.iterkeys()]
         yield "    instanceVariableNames: '%s'" % ' '.join(fields)
         yield "    classVariableNames: '%s'" % ' '.join(self.class_vars)
@@ -208,6 +202,8 @@
         self.gen = gen
         self.INSTANCE = INSTANCE
         self.field_name = field_name
+        self.unique_name = gen.unique_field_name(
+                INSTANCE, field_name, schedule=False)
         self.codef = CodeFormatter(gen)
         self.hash_key = (INSTANCE, field_name, self.__class__)
 
@@ -219,8 +215,8 @@
     def render(self):
         yield self.render_fileout_header(
                 self.codef.format(self.INSTANCE), "accessors")
-        yield "%s: value" % self.field_name
-        yield "    %s := value" % self.field_name
+        yield "%s: value" % self.unique_name
+        yield "    %s := value" % self.unique_name
         yield "! !"
 
 class GetterNode(AccessorNode):
@@ -228,8 +224,8 @@
     def render(self):
         yield self.render_fileout_header(
                 self.codef.format(self.INSTANCE), "accessors")
-        yield self.field_name
-        yield "    ^%s" % self.field_name
+        yield self.unique_name
+        yield "    ^%s" % self.unique_name
         yield "! !"
 
 class HelperNode(CodeNode):
@@ -276,7 +272,7 @@
         message = Message("field_init").with_args(args)
         yield codef.format(message)
         for field_name, arg in zip(fields.keys(), args):
-            unique_field = self.unique_field(self.INSTANCE, field_name)
+            unique_field = self.gen.unique_field_name(self.INSTANCE, field_name)
             ass = Assignment(Field(unique_field), arg)
             yield "    %s." % codef.format(ass)
         yield "! !"

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 21:45:36 2006
@@ -75,6 +75,7 @@
         sent_message = message.send_to(op.args[0], op.args[1:])
         if opname in self.wrapping_ops \
                 and self.int_masks.has_key(ptype):
+            # XXX how do i get rid of this import?
             from pypy.translator.squeak.node import HelperNode
             mask_name, mask_code = self.int_masks[ptype]
             helper = HelperNode(self.gen, Message(mask_name), mask_code)
@@ -95,7 +96,7 @@
 
     def op_oogetfield(self, op):
         INST = op.args[0].concretetype
-        field_name = self.node.unique_field(INST, op.args[1].value)
+        field_name = self.gen.unique_field_name(INST, op.args[1].value)
         if op.args[0] == self.node.self:
             # Private field access
             # Could also directly substitute op.result with name
@@ -103,23 +104,19 @@
             rvalue = Field(field_name)
         else:
             # Public field access
-            from pypy.translator.squeak.node import GetterNode
-            self.gen.schedule_node(GetterNode(self.gen, INST, field_name))
             rvalue = Message(field_name).send_to(op.args[0], [])
         return self.codef.format(Assignment(op.result, rvalue))
 
     def op_oosetfield(self, op):
         # Note that the result variable is never used
         INST = op.args[0].concretetype
-        field_name = self.node.unique_field(INST, op.args[1].value)
+        field_name = self.gen.unique_field_name(INST, op.args[1].value)
         field_value = op.args[2]
         if op.args[0] == self.node.self:
             # Private field access
             return self.codef.format(Assignment(Field(field_name), field_value))
         else:
             # Public field access
-            from pypy.translator.squeak.node import SetterNode
-            self.gen.schedule_node(SetterNode(self.gen, INST, field_name))
             setter = Message(field_name).send_to(op.args[0], [field_value])
             return self.codef.format(setter)
 

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 21:45:36 2006
@@ -87,6 +87,18 @@
         fn = compile_function(f)
         assert fn() == "3"
 
+    def test_nameclash_fields(self):
+        class A:
+            def m(self, i):
+                self.var1 = i
+                self.var_1 = i + 1
+        def f():
+            a = A()
+            a.m(1)
+            return a.var1 + a.var_1
+        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