# unsigned "" or "U"
# longness "" or "L" or "LL"
+ # is_c_literal True/False/None creator considers this a C integer literal
unsigned = ""
longness = ""
+ is_c_literal = None # unknown
def __init__(self, pos, **kwds):
ExprNode.__init__(self, pos, **kwds)
self.calculate_constant_result()
except ValueError:
pass
- if self.constant_result in (constant_value_not_set, not_a_constant) or \
+ # 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 \
self.unsigned or self.longness == 'LL':
# clearly a C literal
rank = (self.longness == 'LL') and 2 or 1
else:
return FloatNode(self.pos, value=self.value, type=dst_type,
constant_result=not_a_constant)
- node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
- type = dst_type, unsigned=self.unsigned, longness=self.longness)
if dst_type.is_numeric and not dst_type.is_complex:
node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
- type = dst_type, unsigned=self.unsigned, longness=self.longness)
+ type = dst_type, is_c_literal = True,
+ unsigned=self.unsigned, longness=self.longness)
return node
elif dst_type.is_pyobject:
node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
- type = PyrexTypes.py_object_type, unsigned=self.unsigned, longness=self.longness)
+ type = PyrexTypes.py_object_type, is_c_literal = False,
+ unsigned=self.unsigned, longness=self.longness)
else:
- # not setting the type here!
+ # FIXME: not setting the type here to keep it working with
+ # complex numbers. Should they be special cased?
node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
unsigned=self.unsigned, longness=self.longness)
# We still need to perform normal coerce_to processing on the
# We declare all of these here to type the first argument.
+cimport cython
from Cython.Compiler.Scanning cimport PyrexScanner
cpdef make_slice_nodes(pos, subscripts)
cpdef make_slice_node(pos, start, stop = *, step = *)
cpdef p_atom(PyrexScanner s)
+@cython.locals(value=unicode)
+cpdef p_int_literal(PyrexScanner s)
cpdef p_name(PyrexScanner s, name)
cpdef p_cat_string_literal(PyrexScanner s)
cpdef p_opt_string_literal(PyrexScanner s, required_type=*)
expect_ellipsis(s)
return ExprNodes.EllipsisNode(pos)
elif sy == 'INT':
- value = s.systring
- s.next()
- unsigned = ""
- longness = ""
- while value[-1] in "UuLl":
- if value[-1] in "Ll":
- longness += "L"
- else:
- unsigned += "U"
- value = value[:-1]
- return ExprNodes.IntNode(pos,
- value = value,
- unsigned = unsigned,
- longness = longness)
+ return p_int_literal(s)
elif sy == 'FLOAT':
value = s.systring
s.next()
else:
s.error("Expected an identifier or literal")
+def p_int_literal(s):
+ pos = s.position()
+ value = s.systring
+ s.next()
+ unsigned = ""
+ longness = ""
+ while value[-1] in u"UuLl":
+ if value[-1] in u"Ll":
+ longness += "L"
+ else:
+ unsigned += "U"
+ value = value[:-1]
+ # '3L' is ambiguous in Py2 but not in Py3. '3U' and '3LL' are
+ # illegal in Py2 Python files. All suffixes are illegal in Py3
+ # Python files.
+ is_c_literal = None
+ if unsigned:
+ is_c_literal = True
+ elif longness:
+ if longness == 'LL' or s.context.language_level >= 3:
+ is_c_literal = True
+ if s.in_python_file:
+ if is_c_literal:
+ error(pos, "illegal integer literal syntax in Python source file")
+ is_c_literal = False
+ return ExprNodes.IntNode(pos,
+ is_c_literal = is_c_literal,
+ value = value,
+ unsigned = unsigned,
+ longness = longness)
+
def p_name(s, name):
pos = s.position()
if not s.compile_time_expr and name in s.compile_time_env: