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

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


Author: nik
Date: Thu Mar 16 16:45:54 2006
New Revision: 24481

Removed:
   pypy/dist/pypy/translator/squeak/message.py
   pypy/dist/pypy/translator/squeak/test/test_message.py
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/runtest.py
Log:
heavy gensqueak refactoring:
* got rid of old Message class
* use the new CodeFormatter for most object naming and formatting

there should be some actual progress soon now ...


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 16:45:54 2006
@@ -6,7 +6,11 @@
     words = identifier.split('_')
     return ''.join([words[0]] + [w.capitalize() for w in words[1:]])
 
-class Message:
+class AbstractCode:
+
+    pass
+
+class Message(AbstractCode):
 
     def __init__(self, name):
         self.name = camel_case(name) # XXX Should not use camel_case here
@@ -21,7 +25,7 @@
     def send_to(self, receiver, args):
         return self.with_args(args).send_to(receiver)
 
-class MessageWithArgs:
+class MessageWithArgs(AbstractCode):
 
     def __init__(self, message, args):
         self.message = message
@@ -30,7 +34,7 @@
     def send_to(self, receiver):
         return SentMessage(self, receiver)
 
-class SentMessage:
+class SentMessage(AbstractCode):
     
     def __init__(self, message_wargs, receiver):
         self.message_wargs = message_wargs
@@ -39,17 +43,22 @@
     def assign_to(self, result):
         return Assignment(result, self)
 
-class Assignment:
+class Assignment(AbstractCode):
 
     def __init__(self, lvalue, rvalue):
         self.lvalue = lvalue
         self.rvalue = rvalue
 
-class Self:
+class Self(AbstractCode):
 
     pass
 
-class Field:
+class Field(AbstractCode):
+
+    def __init__(self, name):
+        self.name = name
+
+class CustomVariable(AbstractCode):
 
     def __init__(self, name):
         self.name = name
@@ -62,9 +71,13 @@
     def format(self, code):
         if isinstance(code, Variable) or isinstance(code, Constant):
             return self.format_arg(code)
-        type_name = code.__class__.__name__
-        method = getattr(self, "format_%s" % type_name)
-        return method(code)
+        elif isinstance(code, AbstractCode):
+            type_name = code.__class__.__name__
+            method = getattr(self, "format_%s" % type_name)
+            return method(code)
+        else:
+            # Assume it's a constant value to be formatted
+            return self.name_constant(code)
 
     def format_arg(self, arg):
         """Formats Variables and Constants."""
@@ -73,27 +86,40 @@
         elif isinstance(arg, Constant):
             if isinstance(arg.concretetype, ootype.Instance):
                 # XXX fix this
-                #const_id = self.gen.unique_name(
-                #        v, "const_%s" % self.gen.nameof(v.value._TYPE))
-                #self.gen.constant_insts[v] = const_id
-                #return "(PyConstants getConstant: '%s')" % const_id
-                return None
-            elif arg.concretetype == ootype.Bool:
-                return str(arg.value).lower()
-            elif arg.concretetype == ootype.Void:
-                if isinstance(arg.value, ootype.Instance):
-                    return self.format_Instance(arg.value)
-                else:
-                    assert arg.value is None
-                    return "nil"
+                const_id = self.gen.unique_name(
+                        arg, "const_%s" % self.format_Instance(arg.value._TYPE))
+                self.gen.constant_insts[arg] = const_id
+                return "(PyConstants getConstant: '%s')" % const_id
             else:
-                # Integers etc.
-                return str(arg.value)
+                return self.name_constant(arg.value)
         else:
-            raise TypeError, "No representation for argument %r" % (v,)
+            raise TypeError, "No representation for argument %r" % (arg,)
+
+    def name_constant(self, value):
+        if isinstance(value, bool):
+            return str(value).lower()
+        elif isinstance(value, ootype.Instance):
+            return self.format_Instance(value)
+        elif value is None:
+            return "nil"
+        elif isinstance(value, int):
+            return str(value)
+        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)
+        else:
+            raise TypeError, "can't format constant (%s)" % value
 
     def format_Instance(self, INSTANCE):
-        return self.gen.nameof_Instance(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
 
     def format_Self(self, _):
         return "self"
@@ -101,6 +127,9 @@
     def format_Field(self, field):
         return field.name
 
+    def format_CustomVariable(self, var):
+        return var.name
+
     def format_MessageWithArgs(self, message):
         name = message.message.name
         arg_count = len(message.args)

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 16:45:54 2006
@@ -1,6 +1,5 @@
-from pypy.objspace.flow.model import Constant
 from pypy.translator.gensupp import NameManager
-from pypy.translator.squeak.message import Message, camel_case
+from pypy.translator.squeak.codeformatter import camel_case
 from pypy.translator.squeak.node import FunctionNode, ClassNode, SetupNode
 try:
     set
@@ -10,12 +9,6 @@
 
 class GenSqueak:
 
-    sqnames = {
-        Constant(None).key:  'nil',
-        Constant(False).key: 'false',
-        Constant(True).key:  'true',
-    }
-    
     def __init__(self, sqdir, translator, modname=None):
         self.sqdir = sqdir
         self.translator = translator
@@ -61,45 +54,8 @@
                 self.pending_nodes.remove(node)
             self.pending_nodes.append(node)
 
-    def nameof(self, obj):
-        key = Constant(obj).key
-        try:
-            return self.sqnames[key]
-        except KeyError:
-            for cls in type(obj).__mro__:
-                meth = getattr(self,
-                               'nameof_' + cls.__name__.replace(' ', ''),
-                               None)
-                if meth:
-                    break
-            else:
-                types = ['nameof_'+t.__name__ for t in type(obj).__mro__]
-                raise Exception, "nameof(%r): no method %s" % (obj, types)
-            name = meth(obj)
-            self.sqnames[key] = name
-            return name
-
-    def nameof_int(self, i):
-        return str(i)
-
-    def nameof_str(self, s):
-        return "'s'"
-
-    def nameof_Instance(self, INSTANCE):
-        if INSTANCE is None:
-            return "Object"
-        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 nameof__class(self, class_):
-        return self.nameof_Instance(class_._INSTANCE)
-
-    def nameof__callable(self, callable):
-        return self.nameof_function(callable.graph.func)
-
-    def nameof_function(self, function):
+    def unique_func_name(self, function):
+        # XXX do FunctionNode registering here
         squeak_func_name = self.unique_name(function, function.__name__)
         return squeak_func_name
         

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 16:45:54 2006
@@ -1,7 +1,8 @@
 import datetime
 from pypy.objspace.flow.model import Constant, Variable
-from pypy.translator.squeak.message import Message, camel_case
 from pypy.translator.squeak.opformatter import OpFormatter
+from pypy.translator.squeak.codeformatter import CodeFormatter, Message, camel_case
+from pypy.translator.squeak.codeformatter import Field, Assignment, CustomVariable
 from pypy.rpython.ootypesystem.ootype import Instance, ROOT
 
 class CodeNode:
@@ -13,8 +14,6 @@
         return isinstance(other, CodeNode) \
                 and self.hash_key == other.hash_key
     
-    # XXX need other comparison methods?
-
     def render_fileout_header(self, class_name, category):
         return "!%s methodsFor: '%s' stamp: 'pypy %s'!" % (
                 class_name, category,
@@ -43,9 +42,10 @@
             return []
 
     def render(self):
+        codef = CodeFormatter(self.gen)
         yield "%s subclass: #%s" % (
-            self.gen.nameof_Instance(self.INSTANCE._superclass), 
-            self.gen.nameof_Instance(self.INSTANCE))
+            codef.format_Instance(self.INSTANCE._superclass), 
+            codef.format_Instance(self.INSTANCE))
         fields = [self.unique_field(self.INSTANCE, f) for f in
             self.INSTANCE._fields.iterkeys()]
         yield "    instanceVariableNames: '%s'" % ' '.join(fields)
@@ -81,38 +81,26 @@
 class CallableNode(CodeNode):
 
     def render_body(self, startblock):
+        self.codef = CodeFormatter(self.gen)
         self.loops = LoopFinder(startblock).loops
         args = self.arguments(startblock)
-        sel = Message(self.name)
-        yield sel.signature([self.expr(v) for v in args])
+        message = Message(self.name).with_args(args)
+        yield self.codef.format(message)
  
         # XXX should declare local variables here
         for line in self.render_block(startblock):
             yield "    %s" % line
         yield '! !'
 
-    def expr(self, v):
-        if isinstance(v, Variable):
-            return camel_case(v.name)
-        elif isinstance(v, Constant):
-            if isinstance(v.concretetype, Instance):
-                const_id = self.gen.unique_name(
-                        v, "const_%s" % self.gen.nameof(v.value._TYPE))
-                self.gen.constant_insts[v] = const_id
-                return "(PyConstants getConstant: '%s')" % const_id
-            return self.gen.nameof(v.value)
-        else:
-            raise TypeError, "expr(%r)" % (v,)
-
     def render_return(self, args):
         if len(args) == 2:
             # exception
-            exc_cls = self.expr(args[0])
-            exc_val = self.expr(args[1])
+            exc_cls = self.codef.format(args[0])
+            exc_val = self.codef.format(args[1])
             yield "(PyOperationError class: %s value: %s) signal." % (exc_cls, exc_val)
         else:
             # regular return block
-            retval = self.expr(args[0])
+            retval = self.codef.format(args[0])
             yield "^%s" % retval
 
     def render_link(self, link):
@@ -120,7 +108,8 @@
         if link.args:
             for i in range(len(link.args)):
                 yield '%s := %s.' % \
-                        (self.expr(block.inputargs[i]), self.expr(link.args[i]))
+                        (self.codef.format(block.inputargs[i]),
+                                self.codef.format(link.args[i]))
         for line in self.render_block(block):
             yield line
 
@@ -147,14 +136,14 @@
             if self.loops.has_key(block):
                 if self.loops[block]:
                     self.loops[block] = False
-                    yield "%s] whileTrue: [" % self.expr(block.exitswitch)
+                    yield "%s] whileTrue: [" % self.codef.format(block.exitswitch)
                     for line in self.render_link(block.exits[True]):
                         yield "    %s" % line
                     yield "]."
                     for line in self.render_link(block.exits[False]):
                         yield "%s" % line
             else:
-                yield "%s ifTrue: [" % self.expr(block.exitswitch)
+                yield "%s ifTrue: [" % self.codef.format(block.exitswitch)
                 for line in self.render_link(block.exits[True]):
                     yield "    %s" % line
                 yield "] ifFalse: [" 
@@ -179,8 +168,9 @@
         return startblock.inputargs[1:]
     
     def render(self):
+        codef = CodeFormatter(self.gen)
         yield self.render_fileout_header(
-                self.gen.nameof(self.INSTANCE), "methods")
+                codef.format(self.INSTANCE), "methods")
         graph = self.INSTANCE._methods[self.name].graph
         self.self = graph.startblock.inputargs[0]
         for line in self.render_body(graph.startblock):
@@ -193,7 +183,7 @@
     def __init__(self, gen, graph):
         self.gen = gen
         self.graph = graph
-        self.name = gen.nameof(graph.func)
+        self.name = gen.unique_func_name(graph.func) # XXX messy
         self.self = None
         self.hash_key = graph
 
@@ -214,6 +204,7 @@
         self.gen = gen
         self.INSTANCE = INSTANCE
         self.field_name = field_name
+        self.codef = CodeFormatter(gen)
         self.hash_key = (INSTANCE, field_name, self.__class__)
 
     def dependencies(self):
@@ -223,7 +214,7 @@
 
     def render(self):
         yield self.render_fileout_header(
-                self.gen.nameof_Instance(self.INSTANCE), "accessors")
+                self.codef.format(self.INSTANCE), "accessors")
         yield "%s: value" % self.field_name
         yield "    %s := value" % self.field_name
         yield "! !"
@@ -232,7 +223,7 @@
 
     def render(self):
         yield self.render_fileout_header(
-                self.gen.nameof_Instance(self.INSTANCE), "accessors")
+                self.codef.format(self.INSTANCE), "accessors")
         yield self.field_name
         yield "    ^%s" % self.field_name
         yield "! !"
@@ -271,16 +262,17 @@
         return [ClassNode(self.gen, self.INSTANCE)]
 
     def render(self):
+        codef = CodeFormatter(self.gen)
         yield self.render_fileout_header(
-                self.gen.nameof_Instance(self.INSTANCE), "initializers")
+                codef.format(self.INSTANCE), "initializers")
         fields = self.INSTANCE._allfields()
-        sel = Message("field_init")
-        arg_names = ["a%s" % i for i in range(len(fields))]
-        yield sel.signature(arg_names)
-        for field_name, arg_name in zip(fields.keys(), arg_names):
-            yield "    %s := %s." % (
-                    self.unique_field(self.INSTANCE, field_name),
-                    arg_name)
+        args = [CustomVariable("a%s" % i) for i in range(len(fields))]
+        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)
+            ass = Assignment(Field(unique_field), arg)
+            yield "    %s." % codef.format(ass)
         yield "! !"
 
 class SetupNode(CodeNode):
@@ -299,26 +291,27 @@
             [ClassNode(self.gen, self.CONSTANTS, class_vars=["Constants"])]
 
     def render(self):
+        codef = CodeFormatter(self.gen)
+        # XXX use CodeFormatter throughout here
         yield self.render_fileout_header("PyConstants class", "internals")
-        sel = Message("setupConstants")
-        yield sel.signature([])
+        message = Message("setupConstants")
+        yield codef.format(message.with_args([]))
         yield "    Constants := Dictionary new."
         for const, const_id in self.constants.iteritems():
             INST = const.value._TYPE
-            class_name = self.gen.nameof(INST)
             field_names = INST._allfields().keys()
-            field_values = [self.gen.nameof(getattr(const.value, f))
-                    for f in field_names]
-            init_sel = Message("field_init")
-            yield "    Constants at: '%s' put: (%s new %s)." \
-                    % (const_id, class_name,
-                        init_sel.signature(field_values))
+            field_values = [getattr(const.value, f) for f in field_names]
+            new = Message("new").send_to(INST, [])
+            init_message = Message("field_init").send_to(new, field_values)
+            yield "    Constants at: '%s' put: %s." \
+                    % (const_id, codef.format(init_message))
         yield "! !"
         yield ""
 
         yield self.render_fileout_header("PyConstants class", "internals")
-        sel = Message("getConstant")
-        yield sel.signature(["constId"])
+        arg = CustomVariable("constId")
+        get_message = Message("getConstant")
+        yield codef.format(get_message.with_args([arg]))
         yield "    ^ Constants at: constId"
         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 16:45:54 2006
@@ -129,7 +129,7 @@
 
     def op_direct_call(self, op):
         from pypy.translator.squeak.node import FunctionNode
-        function_name = self.node.expr(op.args[0])
+        function_name = self.codef.format(op.args[0])
         self.gen.schedule_node(
             FunctionNode(self.gen, op.args[0].value.graph))
         msg = Message(function_name).send_to(FunctionNode.FUNCTIONS, op.args[1:])

Modified: pypy/dist/pypy/translator/squeak/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/squeak/test/runtest.py	Thu Mar 16 16:45:54 2006
@@ -2,7 +2,6 @@
 import py
 from pypy.tool.udir import udir
 from pypy.translator.squeak.gensqueak import GenSqueak
-from pypy.translator.squeak.message import Message
 from pypy.translator.translator import TranslationContext
 from pypy import conftest
 
@@ -67,6 +66,16 @@
             f.close()
         return startup_st
 
+    def _symbol(self, arg_count):
+        name = self._func.__name__
+        if arg_count == 0:
+            return name
+        else:
+            parts = [name]
+            if arg_count > 1:
+                parts += ["with"] * (arg_count - 1)
+            return "%s:%s" % (parts[0], "".join([p + ":" for p in parts[1:]]))
+
     def __call__(self, *args):
         # NB: only integers arguments are supported currently
         try:
@@ -86,7 +95,7 @@
             options = ""
         cmd = 'squeak %s -- %s %s "%s" %s' \
                 % (options, startup_st, udir.join(self._gen.filename),
-                   Message(self._func.__name__).symbol(len(args)),
+                   self._symbol(len(args)),
                    " ".join(['"%s"' % a for a in args]))
         squeak_process = os.popen(cmd)
         result = squeak_process.read()



More information about the Pypy-commit mailing list