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): ...@@ -2327,25 +2327,27 @@ def widest_numeric_type(type1, type2):
# Given two numeric types, return the narrowest type # Given two numeric types, return the narrowest type
# encompassing both of them. # encompassing both of them.
if type1 == type2: if type1 == type2:
return type1 widest_type = type1
if type1.is_complex: elif type1.is_complex or type2.is_complex:
if type2.is_complex: def real_type(ntype):
return CComplexType(widest_numeric_type(type1.real_type, type2.real_type)) if ntype.is_complex:
else: return ntype.real_type
return CComplexType(widest_numeric_type(type1.real_type, type2)) return ntype
elif type2.is_complex: widest_type = CComplexType(
return CComplexType(widest_numeric_type(type1, type2.real_type)) widest_numeric_type(
if type1.is_enum and type2.is_enum: real_type(type1),
return c_int_type real_type(type2)))
elif type1 is type2: elif type1.is_enum and type2.is_enum:
return type1 widest_type = c_int_type
elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed): elif type1.rank < type2.rank:
if type2.rank > type1.rank: widest_type = type2
return type2 elif type1.rank > type2.rank:
else: widest_type = type1
return type1 elif type1.signed < type2.signed:
widest_type = type1
else: 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): def spanning_type(type1, type2):
# Return a type assignable from both type1 and 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 int i = 1
cdef long l = 2 cdef long l = 2
cdef unsigned int ui = 4 cdef unsigned int ui = 4
cdef unsigned long ul = 8 cdef unsigned long ul = 8
def test_signed(): def test_add():
print i + l, type(i+l) """
print i + ul, type(i+ul) >>> test_add()
print ui + l, type(ui+l) 3
print ui + ul, type(ui+ul) 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