Commit 034db9bb authored by Stefan Behnel's avatar Stefan Behnel

better integer handling in constant folding, including type promotion

parent eccbee09
......@@ -2984,29 +2984,36 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
except AttributeError:
return node
if type1 is type2:
new_node = node.operand1
else:
if type1.is_numeric and type2.is_numeric:
widest_type = PyrexTypes.widest_numeric_type(type1, type2)
if type(node.operand1) is type(node.operand2):
new_node = node.operand1
new_node.type = widest_type
elif type1 is widest_type:
new_node = node.operand1
elif type2 is widest_type:
new_node = node.operand2
else:
target_class = self._widest_node_class(
node.operand1, node.operand2)
else:
widest_type = PyrexTypes.py_object_type
target_class = self._widest_node_class(node.operand1, node.operand2)
if target_class is None:
return node
new_node = target_class(pos=node.pos, type = widest_type)
new_node.constant_result = node.constant_result
elif target_class is ExprNodes.IntNode:
unsigned = getattr(node.operand1, 'unsigned', '') and \
getattr(node.operand2, 'unsigned', '')
longness = "LL"[:max(len(getattr(node.operand1, 'longness', '')),
len(getattr(node.operand2, 'longness', '')))]
new_node = ExprNodes.IntNode(pos=node.pos,
unsigned = unsigned, longness = longness,
value = str(node.constant_result),
constant_result = node.constant_result)
# IntNode is smart about the type it chooses, so we just
# make sure we were not smarter this time
if widest_type.is_pyobject or new_node.type.is_pyobject:
new_node.type = PyrexTypes.py_object_type
else:
new_node.type = PyrexTypes.widest_numeric_type(widest_type, new_node.type)
else:
if isinstance(node, ExprNodes.BoolNode):
new_node.value = node.constant_result
node_value = node.constant_result
else:
new_node.value = str(node.constant_result)
node_value = str(node.constant_result)
new_node = target_class(pos=node.pos, type = widest_type,
value = node_value,
constant_result = node.constant_result)
return new_node
def visit_PrimaryCmpNode(self, node):
......
......@@ -3,11 +3,18 @@ __doc__ = u"""
(1, 1L, -1L, 18446744073709551615L)
>>> py_longs()
(1, 1L, 100000000000000000000000000000000L, -100000000000000000000000000000000L)
>>> py_huge_calculated_long()
1606938044258990275541962092341162602522202993782792835301376L
>>> py_huge_computation_small_result_neg()
(-2535301200456458802993406410752L, -2535301200456458802993406410752L)
"""
import sys
cimport cython
from cython cimport typeof
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u'L', u'')
......@@ -27,6 +34,25 @@ def c_longs():
def py_longs():
return 1, 1L, 100000000000000000000000000000000, -100000000000000000000000000000000
@cython.test_fail_if_path_exists("//NumBinopNode", "//IntBinopNode")
@cython.test_assert_path_exists("//ReturnStatNode/IntNode")
def py_huge_calculated_long():
return 1 << 200
@cython.test_fail_if_path_exists("//NumBinopNode", "//IntBinopNode")
@cython.test_assert_path_exists("//ReturnStatNode/IntNode")
def py_huge_computation_small_result():
"""
>>> py_huge_computation_small_result()
2
"""
return (1 << 200) >> 199
@cython.test_fail_if_path_exists("//NumBinopNode", "//IntBinopNode")
#@cython.test_assert_path_exists("//ReturnStatNode/IntNode")
def py_huge_computation_small_result_neg():
return -(2 ** 101), (-2) ** 101
def large_literal():
"""
>>> type(large_literal()) is int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment