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