[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