[pypy-svn] r24645 - in pypy/dist/pypy/translator/squeak: . test
nik at codespeak.net
nik at codespeak.net
Mon Mar 20 21:20:08 CET 2006
Author: nik
Date: Mon Mar 20 21:20:01 2006
New Revision: 24645
Modified:
pypy/dist/pypy/translator/squeak/codeformatter.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:
some form of exception support for gensqueak. this needs more tests
and some tidying up.
Modified: pypy/dist/pypy/translator/squeak/codeformatter.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/codeformatter.py (original)
+++ pypy/dist/pypy/translator/squeak/codeformatter.py Mon Mar 20 21:20:01 2006
@@ -104,6 +104,8 @@
return str(value)
elif isinstance(value, ootype._class):
return self.format_Instance(value._INSTANCE)
+ elif isinstance(value, ootype._instance):
+ return self.format_Instance(value._TYPE)
elif isinstance(value, ootype._static_meth):
return self.gen.unique_func_name(value.graph)
else:
@@ -112,7 +114,8 @@
def format_Instance(self, INSTANCE):
if INSTANCE is None:
return "Object"
- return self.gen.unique_class_name(INSTANCE)
+ else:
+ return self.gen.unique_class_name(INSTANCE)
def format_Self(self, _):
return "self"
Modified: pypy/dist/pypy/translator/squeak/node.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/node.py (original)
+++ pypy/dist/pypy/translator/squeak/node.py Mon Mar 20 21:20:01 2006
@@ -1,9 +1,9 @@
import datetime
-from pypy.objspace.flow.model import Constant, Variable
+from pypy.objspace.flow.model import Constant, Variable, c_last_exception
from pypy.translator.squeak.opformatter import OpFormatter
from pypy.translator.squeak.codeformatter import CodeFormatter, Message
from pypy.translator.squeak.codeformatter import Field, Assignment, CustomVariable
-from pypy.rpython.ootypesystem.ootype import Instance, ROOT
+from pypy.rpython.ootypesystem.ootype import Instance, Class, ROOT
class CodeNode:
@@ -21,25 +21,30 @@
class ClassNode(CodeNode):
- def __init__(self, gen, INSTANCE, class_vars=None):
+ def __init__(self, gen, INSTANCE, class_vars=None, host_base=None):
self.gen = gen
self.INSTANCE = INSTANCE
self.class_vars = [] # XXX should probably go away
if class_vars is not None:
self.class_vars = class_vars
+ self.host_base = host_base
self.hash_key = INSTANCE
def dependencies(self):
deps = []
- if self.INSTANCE._superclass is not None: # not root
+ if self.INSTANCE._superclass is not None \
+ and self.host_base is None: # not root
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))
+ if self.host_base is None:
+ superclass = codef.format_Instance(self.INSTANCE._superclass)
+ else:
+ superclass = self.host_base
+ yield "%s subclass: #%s" % \
+ (superclass, codef.format_Instance(self.INSTANCE))
fields = [self.gen.unique_field_name(self.INSTANCE, f) for f in
self.INSTANCE._fields.iterkeys()]
yield " instanceVariableNames: '%s'" % ' '.join(fields)
@@ -74,6 +79,12 @@
class CallableNode(CodeNode):
+ OPERATION_ERROR = Instance("OperationError", ROOT,
+ fields={"type": Class, "value": ROOT})
+
+ def dependencies(self):
+ return [ClassNode(self.gen, self.OPERATION_ERROR, host_base="Exception")]
+
def render_body(self, startblock):
self.codef = CodeFormatter(self.gen)
self.loops = LoopFinder(startblock).loops
@@ -89,14 +100,19 @@
def render_return(self, args):
if len(args) == 2:
# exception
- 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)
+ yield self.render_exception(args[0], args[1])
else:
# regular return block
retval = self.codef.format(args[0])
yield "^%s" % retval
+ def render_exception(self, exception_class, exception_value):
+ exc_cls = self.codef.format(exception_class)
+ exc_val = self.codef.format(exception_value)
+ return "((%s new) type: %s; value: %s) signal." \
+ % (self.codef.format_Instance(self.OPERATION_ERROR),
+ exc_cls, exc_val)
+
def render_link(self, link):
block = link.target
if link.args:
@@ -113,6 +129,8 @@
yield '"skip1"'
return
yield "["
+ if block.exitswitch is c_last_exception:
+ yield "["
formatter = OpFormatter(self.gen, self)
for op in block.operations:
yield "%s." % formatter.format(op)
@@ -125,6 +143,30 @@
assert len(block.exits) == 1
for line in self.render_link(block.exits[0]):
yield line
+ elif block.exitswitch is c_last_exception:
+ # exception branching
+ # wuah. ugly!
+ exc_var = self.gen.unique_name(("var", "exception"), "exception")
+ yield "] on: %s do: [:%s |" \
+ % (formatter.codef.format(self.OPERATION_ERROR), exc_var)
+ exc_exits = []
+ non_exc_exit = None
+ for exit in block.exits:
+ if exit.exitcase is None:
+ non_exc_exit = exit
+ else:
+ exc_exits.append(exit)
+ for exit in exc_exits:
+ yield "(%s type isKindOf: %s) ifTrue: [" \
+ % (exc_var, formatter.codef.format(exit.llexitcase))
+ for line in self.render_link(exit):
+ yield line
+ yield "] ifFalse: ["
+ for exit in exc_exits:
+ yield "]"
+ yield "]."
+ for line in self.render_link(non_exc_exit):
+ yield line
else:
#exitswitch
if self.loops.has_key(block):
@@ -157,7 +199,8 @@
self.hash_key = (INSTANCE, method_name)
def dependencies(self):
- return [ClassNode(self.gen, self.INSTANCE)]
+ return CallableNode.dependencies(self) \
+ + [ClassNode(self.gen, self.INSTANCE)]
def arguments(self, startblock):
# Omit the explicit self
@@ -185,7 +228,8 @@
self.hash_key = graph
def dependencies(self):
- return [ClassNode(self.gen, self.FUNCTIONS)]
+ return CallableNode.dependencies(self) \
+ + [ClassNode(self.gen, self.FUNCTIONS)]
def arguments(self, startblock):
return startblock.inputargs
@@ -215,8 +259,9 @@
def render(self):
yield self.render_fileout_header(
self.codef.format(self.INSTANCE), "accessors")
- yield "%s: value" % self.unique_name
- yield " %s := value" % self.unique_name
+ arg_name = self.gen.unique_name((SetterNode, "arg"), "value")
+ yield "%s: %s" % (self.unique_name, arg_name)
+ yield " %s := %s" % (self.unique_name, arg_name)
yield "! !"
class GetterNode(AccessorNode):
Modified: pypy/dist/pypy/translator/squeak/opformatter.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/opformatter.py (original)
+++ pypy/dist/pypy/translator/squeak/opformatter.py Mon Mar 20 21:20:01 2006
@@ -156,6 +156,7 @@
return Assignment(op.result, op.args[0])
op_oodowncast = noop
+ op_ooupcast = noop
def op_direct_call(self, op):
# XXX how do i get rid of this import?
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 Mon Mar 20 21:20:01 2006
@@ -141,3 +141,18 @@
assert fn(1) == "1"
assert fn(2) == "2"
+ def test_simpleexception(self):
+ def raising(i):
+ if i > 0:
+ raise ValueError
+ else:
+ return i + 1
+ def f(i):
+ try:
+ return raising(i)
+ except ValueError, val:
+ return i - 1
+ fn = compile_function(f, [int])
+ assert fn(-1) == "0"
+ assert fn(2) == "1"
+
More information about the Pypy-commit
mailing list