[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