[pypy-svn] r24591 - in pypy/dist/pypy/translator/squeak: . test
nik at codespeak.net
nik at codespeak.net
Mon Mar 20 14:43:33 CET 2006
Author: nik
Date: Mon Mar 20 14:43:26 2006
New Revision: 24591
Modified:
pypy/dist/pypy/translator/squeak/codeformatter.py
pypy/dist/pypy/translator/squeak/opformatter.py
pypy/dist/pypy/translator/squeak/test/test_llops.py
Log:
full support for floats in gensqueak.
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 14:43:26 2006
@@ -100,7 +100,7 @@
return self.format_Instance(value)
elif value is None:
return "nil"
- elif isinstance(value, int):
+ elif isinstance(value, (int, float)):
return str(value)
elif isinstance(value, ootype._class):
return self.format_Instance(value._INSTANCE)
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 14:43:26 2006
@@ -31,6 +31,13 @@
'classof': 'class',
'same_as': 'yourself',
'bool_not': 'not',
+
+ 'cast_int_to_float': 'asFloat',
+ 'float_div': '/', # overrides the div definition in number_ops
+ 'float_fmod': r'\\', # we can't really distinguish mod and fmod
+ 'float_floor': 'floor',
+ # XXX this potentially incorrect (may return LargeIntegers)
+ 'cast_float_to_int': 'truncated',
}
number_ops = {
@@ -45,7 +52,7 @@
'mul': '*',
'div': '//',
'floordiv': '//',
- #'truediv': '/', # XXX fix this when we have float support
+ 'truediv': '/ asFloat',
'mod': r'\\',
'eq': '=',
'ne': '~=',
@@ -74,6 +81,10 @@
self.codef = CodeFormatter(gen)
def format(self, op):
+ if self.ops.has_key(op.opname):
+ name = self.ops[op.opname]
+ sent = Message(name).send_to(op.args[0], op.args[1:])
+ return self.codef.format(sent.assign_to(op.result))
opname_parts = op.opname.split("_")
if opname_parts[0] in self.number_opprefixes:
return self.format_number_op(
@@ -82,26 +93,29 @@
if op_method is not None:
return self.codef.format(op_method(op))
else:
- if not self.ops.has_key(op.opname):
- raise NotImplementedError(
+ raise NotImplementedError(
"operation not supported: %s" % op.opname)
- name = self.ops[op.opname]
- sent = Message(name).send_to(op.args[0], op.args[1:])
- return self.codef.format(sent.assign_to(op.result))
def format_number_op(self, op, ptype, opname):
- message = Message(self.number_ops[opname])
- sent_message = message.send_to(op.args[0], op.args[1:])
+ messages = self.number_ops[opname].split()
+ msg = Message(messages[0])
+ sent_message = msg.send_to(op.args[0], op.args[1:])
+ for add_message in messages[1:]:
+ sent_message = Message(add_message).send_to(sent_message, [])
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)
- sent_message = helper.apply([sent_message])
- self.gen.schedule_node(helper)
+ sent_message = self.apply_mask_helper(sent_message, ptype)
return self.codef.format(sent_message.assign_to(op.result))
+ def apply_mask_helper(self, receiver, mask_type_name):
+ # XXX how do i get rid of this import?
+ from pypy.translator.squeak.node import HelperNode
+ mask_name, mask_code = self.int_masks[mask_type_name]
+ helper = HelperNode(self.gen, Message(mask_name), mask_code)
+ result = helper.apply([receiver])
+ self.gen.schedule_node(helper)
+ return result
+
def op_oosend(self, op):
message_name = op.args[0].value
message_name = self.gen.unique_method_name(
@@ -150,10 +164,16 @@
msg = Message(function_name).send_to(FunctionNode.FUNCTIONS, op.args[1:])
return msg.assign_to(op.result)
- def op_cast_bool_to_int(self, op):
- msg = Message("ifTrue: [1] ifFalse: [0]")
+ def cast_bool(self, op, true_repr, false_repr):
+ msg = Message("ifTrue: [%s] ifFalse: [%s]" % (true_repr, false_repr))
return msg.send_to(op.args[0], []).assign_to(op.result)
+ def op_cast_bool_to_int(self, op):
+ return self.cast_bool(op, "1", "0")
+
+ def op_cast_bool_to_float(self, op):
+ return self.cast_bool(op, "1.0", "0.0")
+
op_cast_bool_to_uint = op_cast_bool_to_int
op_cast_char_to_int = noop
@@ -163,14 +183,9 @@
op_cast_int_to_char = noop
op_cast_int_to_unichar = noop
op_cast_int_to_longlong = noop
- # XXX to_float missing
def masking_cast(self, op, mask):
- from pypy.translator.squeak.node import HelperNode
- mask_name, mask_code = self.int_masks[mask]
- helper = HelperNode(self.gen, Message(mask_name), mask_code)
- cast = helper.apply([op.args[0]])
- self.gen.schedule_node(helper)
+ cast = self.apply_mask_helper(op.args[0], mask)
return Assignment(op.result, cast)
def op_cast_int_to_uint(self, op):
@@ -181,3 +196,7 @@
op_truncate_longlong_to_int = noop
+ def op_cast_float_to_uint(self, op):
+ truncated = Message("truncated").send_to(op.args[0], [])
+ return Assignment(op.result, self.apply_mask_helper(truncated, "uint"))
+
Modified: pypy/dist/pypy/translator/squeak/test/test_llops.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/test/test_llops.py (original)
+++ pypy/dist/pypy/translator/squeak/test/test_llops.py Mon Mar 20 14:43:26 2006
@@ -4,7 +4,7 @@
from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Char, UniChar
-from pypy.rpython.lltypesystem.lltype import SignedLongLong, UnsignedLongLong
+from pypy.rpython.lltypesystem.lltype import SignedLongLong, UnsignedLongLong, Float
from pypy.rpython.test.test_llinterp import interpret
def optest(testcase):
@@ -61,6 +61,7 @@
("div", Signed, 7, 3),
("floordiv", Signed, 7, 3), # XXX what about division by zero?
("floordiv", Signed, -7, 3),
+ ("truediv", Float, 7, 4),
("mod", Signed, 9, 4),
("mod", Signed, 9, -4),
("eq", Bool, 1, 1),
@@ -120,6 +121,36 @@
for t in tests:
yield optest, t
+def test_floatoperations_unary():
+ for llopname in "abs", "neg", "floor":
+ exec """def lloptest():
+ return llop.float_%s(Float, -1.5)""" % llopname
+ expected_res = llinterpret(lloptest, ())
+ res = sqinterpret(lloptest, ())
+ assert expected_res == float(res) # because floor might return a squeak int
+
+def test_floatoperations_is_true():
+ def istrue():
+ return llop.float_is_true(Bool, 0.0)
+ llfunctest(istrue, ())
+
+def test_floatoperations_binary():
+ for llopname in "add", "sub", "mul", "div", "mod", "fmod", \
+ "floordiv", "truediv":
+ exec """def lloptest(i):
+ f = llop.cast_int_to_float(Float, i)
+ return llop.float_%s(Float, f, 1.25)""" % llopname
+ expected_res = llinterpret(lloptest, (3,))
+ res = sqinterpret(lloptest, (3,))
+ assert expected_res == float(res) # because of floordiv
+
+def test_floatoperations_binary_bool():
+ for llopname in "eq", "ne", "gt", "lt", "ge", "le":
+ exec """def lloptest(i):
+ f = llop.cast_int_to_float(Float, i)
+ return llop.float_%s(Bool, f, 1.25)""" % llopname
+ yield llfunctest, lloptest, (3,)
+
def test_booloperations():
def bool_not(i):
if i == 1:
@@ -146,7 +177,7 @@
yield llfunctest, lloptest, (1, 2)
def test_cast_bool():
- tests = ("int", Signed), ("uint", Unsigned) # XXX missing float
+ tests = ("int", Signed), ("uint", Unsigned), ("float", Float)
for target_name, target_type in tests:
exec """def lloptest(i):
b = llop.int_is_true(Bool, i)
@@ -168,7 +199,7 @@
yield llfunctest, lloptest, (1,)
def test_cast_int():
- tests = [("char", Char), ("unichar", UniChar),
+ tests = [("char", Char), ("unichar", UniChar), ("float", Float),
("longlong", SignedLongLong), ("uint", Unsigned)]
for target_name, target_type in tests:
exec """def lloptest(i):
@@ -176,9 +207,11 @@
% (target_name, target_type._name)
args = (2,)
expected_res = llinterpret(lloptest, args)
- res = int(sqinterpret(lloptest, args))
+ res = sqinterpret(lloptest, args)
if isinstance(expected_res, (str, unicode)):
- res = chr(res)
+ res = chr(int(res))
+ else:
+ expected_res = str(expected_res)
assert expected_res == res
def test_cast_int_to_uint():
@@ -191,3 +224,11 @@
return llop.cast_uint_to_int(Signed, i)
llfunctest(lloptest, (r_uint(sys.maxint + 1),))
+def test_cast_float():
+ tests = [("int", Signed), ("uint", Unsigned)]
+ for target_name, target_type in tests:
+ exec """def lloptest():
+ return llop.cast_float_to_%s(%s, -1.5)""" \
+ % (target_name, target_type._name)
+ yield llfunctest, lloptest, ()
+
More information about the Pypy-commit
mailing list