Commit 0d5437f8 authored by Lisandro Dalcin's avatar Lisandro Dalcin

reworked type promotion rules, nearly identical to the one in Pyrex

parent fdf00273
......@@ -2327,25 +2327,27 @@ def widest_numeric_type(type1, type2):
# Given two numeric types, return the narrowest type
# encompassing both of them.
if type1 == type2:
return type1
if type1.is_complex:
if type2.is_complex:
return CComplexType(widest_numeric_type(type1.real_type, type2.real_type))
else:
return CComplexType(widest_numeric_type(type1.real_type, type2))
elif type2.is_complex:
return CComplexType(widest_numeric_type(type1, type2.real_type))
if type1.is_enum and type2.is_enum:
return c_int_type
elif type1 is type2:
return type1
elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
if type2.rank > type1.rank:
return type2
else:
return type1
widest_type = type1
elif type1.is_complex or type2.is_complex:
def real_type(ntype):
if ntype.is_complex:
return ntype.real_type
return ntype
widest_type = CComplexType(
widest_numeric_type(
real_type(type1),
real_type(type2)))
elif type1.is_enum and type2.is_enum:
widest_type = c_int_type
elif type1.rank < type2.rank:
widest_type = type2
elif type1.rank > type2.rank:
widest_type = type1
elif type1.signed < type2.signed:
widest_type = type1
else:
return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
widest_type = type2
return widest_type
def spanning_type(type1, type2):
# Return a type assignable from both type1 and type2.
......
import sys
if sys.version_info[0] >= 3:
__doc__ = u"""
>>> test_signed()
3 <class 'int'>
9 <class 'int'>
6 <class 'int'>
12 <class 'int'>
"""
else:
__doc__ = u"""
>>> test_signed()
3 <type 'int'>
9 <type 'long'>
6 <type 'long'>
12 <type 'long'>
"""
cdef int i = 1
cdef long l = 2
cdef unsigned int ui = 4
cdef unsigned long ul = 8
def test_signed():
print i + l, type(i+l)
print i + ul, type(i+ul)
print ui + l, type(ui+l)
print ui + ul, type(ui+ul)
def test_add():
"""
>>> test_add()
3
9
6
12
"""
print i + l
print i + ul
print ui + l
print ui + ul
def test_add_sshort_ulong(signed short a, unsigned long b):
"""
>>> test_add_sshort_ulong(1, 1) == 2
True
>>> test_add_sshort_ulong(-1, 1) == 0
True
>>> test_add_sshort_ulong(-2, 1) == -1
False
"""
return a + b
def test_add_ushort_slonglong(unsigned short a, signed long long b):
"""
>>> test_add_ushort_slonglong(1, 1) == 2
True
>>> test_add_ushort_slonglong(1, -1) == 0
True
>>> test_add_ushort_slonglong(1, -2) == -1
True
"""
return a + b
def test_add_slong_ulong(signed long a, unsigned long b):
"""
>>> test_add_slong_ulong(1, 1) == 2
True
>>> test_add_slong_ulong(-1, 1) == 0
True
>>> test_add_slong_ulong(-2, 1) == -1
False
"""
return a + b
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