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:
+ widest_type = PyrexTypes.py_object_type
+ target_class = self._widest_node_class(node.operand1, node.operand2)
+ if target_class is None:
+ return node
+ 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:
- 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
- if isinstance(node, ExprNodes.BoolNode):
- new_node.value = node.constant_result
+ new_node.type = PyrexTypes.widest_numeric_type(widest_type, new_node.type)
else:
- new_node.value = str(node.constant_result)
+ if isinstance(node, ExprNodes.BoolNode):
+ node_value = node.constant_result
+ else:
+ 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):
(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'')
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