Commit 3c76cb39 authored by Stefan Behnel's avatar Stefan Behnel

Merge branch '0.23.x'

parents 12952d34 a8fbae1d
......@@ -140,7 +140,7 @@ def cython_inline(code,
elif symbol in globals:
kwds[symbol] = globals[symbol]
else:
print("Couldn't find ", symbol)
print("Couldn't find %r" % symbol)
except AssertionError:
if not quiet:
# Parsing from strings not fully supported (e.g. cimports).
......
......@@ -1175,7 +1175,7 @@ class IntNode(ConstNode):
# we ignore 'is_c_literal = True' and instead map signed 32bit
# integers as C long values
if self.is_c_literal or \
self.constant_result in (constant_value_not_set, not_a_constant) or \
not self.has_constant_result() or \
self.unsigned or self.longness == 'LL':
# clearly a C literal
rank = (self.longness == 'LL') and 2 or 1
......@@ -1242,19 +1242,31 @@ class IntNode(ConstNode):
def value_as_c_integer_string(self):
value = self.value
if len(value) > 2:
if value[0] == '0':
literal_type = value[1] # 0'o' - 0'b' - 0'x'
# 0x123 hex literals and 0123 octal literals work nicely in C
# but convert C-incompatible Py3 oct/bin notations
if literal_type in 'oO':
value = '0' + value[2:] # '0o123' => '0123'
elif literal_type in 'bB':
value = int(value[2:], 2)
elif value.isdigit() and not self.unsigned and not self.longness:
# C compilers do not consider unsigned types for decimal literals, but they do for hex
if len(value) <= 2:
# too short to go wrong (and simplifies code below)
return value
neg_sign = ''
if value[0] == '-':
neg_sign = '-'
value = value[1:]
if value[0] == '0':
literal_type = value[1] # 0'o' - 0'b' - 0'x'
# 0x123 hex literals and 0123 octal literals work nicely in C
# but C-incompatible Py3 oct/bin notations need conversion
if neg_sign and literal_type in 'oOxX0123456789' and value[2:].isdigit():
# negative hex/octal literal => prevent C compiler from using
# unsigned integer types by converting to decimal (see C standard 6.4.4.1)
value = str(Utils.str_to_number(value))
elif literal_type in 'oO':
value = '0' + value[2:] # '0o123' => '0123'
elif literal_type in 'bB':
value = str(int(value[2:], 2))
elif value.isdigit() and not self.unsigned and not self.longness:
if not neg_sign:
# C compilers do not consider unsigned types for decimal literals,
# but they do for hex (see C standard 6.4.4.1)
value = '0x%X' % int(value)
return str(value)
return neg_sign + value
def calculate_result_code(self):
return self.result_code
......
......@@ -292,17 +292,22 @@ def open_source_from_loader(loader,
def str_to_number(value):
# note: this expects a string as input that was accepted by the
# parser already
# parser already, with an optional "-" sign in front
is_neg = False
if value[:1] == '-':
is_neg = True
value = value[1:]
if len(value) < 2:
value = int(value, 0)
elif value[0] == '0':
if value[1] in 'xX':
literal_type = value[1] # 0'o' - 0'b' - 0'x'
if literal_type in 'xX':
# hex notation ('0x1AF')
value = int(value[2:], 16)
elif value[1] in 'oO':
elif literal_type in 'oO':
# Py3 octal notation ('0o136')
value = int(value[2:], 8)
elif value[1] in 'bB':
elif literal_type in 'bB':
# Py3 binary notation ('0b101')
value = int(value[2:], 2)
else:
......@@ -310,7 +315,7 @@ def str_to_number(value):
value = int(value, 8)
else:
value = int(value, 0)
return value
return -value if is_neg else value
def long_literal(value):
......
# mode: run
def foo():
"""
>>> foo()
"""
a = 42
a1 = 0123
an1 = -0123
assert a1 == -an1
a2 = 0xabc
an2 = -0xabc
assert a2 == -an2
a3 = 0xDEF
an3 = -0xDEF
assert a3 == -an3
a4 = 1234567890L
an4 = -1234567890L
assert a4 == -an4
a5 = 0o123
an5 = -0o123
assert a5 == -an5
assert a5 == a1
a6 = 0b101
an6 = -0b101
assert a6 == -an6 == 5
b = 42.88e17
b0a = 1.
b0b = .1
......@@ -16,8 +34,10 @@ def foo():
b0f = 1.1e1
b0g = 1.1e-1
b0h = 1e1
b1 = 3j
b2 = 3.1415J
b3 = c'X'
c = "spanish inquisition"
d = "this" "parrot" "is" "resting"
......
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