cython-devel

changeset 834:4695bbb3a785

Better integer literal parsing.

Now accepts U and LL suffixes, and large integer literals are longs rather than being truncated as Python objects.
author Robert Bradshaw <robertwb@math.washington.edu>
date Thu Jul 31 00:55:14 2008 -0700 (4 years ago)
parents f1cc08ccb0b3
children ca2c9d684eaa
files Cython/Compiler/ExprNodes.py Cython/Compiler/Lexicon.py Cython/Compiler/ModuleNode.py Cython/Compiler/Parsing.py Cython/Compiler/Symtab.py Cython/Utils.py tests/run/int_literals.pyx
line diff
1.1 --- a/Cython/Compiler/ExprNodes.py Wed Jul 23 23:02:37 2008 -0700 1.2 +++ b/Cython/Compiler/ExprNodes.py Thu Jul 31 00:55:14 2008 -0700 1.3 @@ -646,13 +646,19 @@ 1.4 1.5 1.6 class IntNode(ConstNode): 1.7 + 1.8 + # unsigned "" or "U" 1.9 + # longness "" or "L" or "LL" 1.10 + 1.11 + unsigned = "" 1.12 + longness = "" 1.13 type = PyrexTypes.c_long_type 1.14 1.15 def coerce_to(self, dst_type, env): 1.16 # Arrange for a Python version of the string to be pre-allocated 1.17 # when coercing to a Python type. 1.18 if dst_type.is_pyobject: 1.19 - self.entry = env.get_py_num(self.value) 1.20 + self.entry = env.get_py_num(self.value, self.longness) 1.21 self.type = PyrexTypes.py_object_type 1.22 # We still need to perform normal coerce_to processing on the 1.23 # result, because we might be coercing to an extension type, 1.24 @@ -663,7 +669,7 @@ 1.25 if self.type.is_pyobject: 1.26 return self.entry.cname 1.27 else: 1.28 - return str(self.value) 1.29 + return str(self.value) + self.unsigned + self.longness 1.30 1.31 def compile_time_value(self, denv): 1.32 return int(self.value, 0)
2.1 --- a/Cython/Compiler/Lexicon.py Wed Jul 23 23:02:37 2008 -0700 2.2 +++ b/Cython/Compiler/Lexicon.py Thu Jul 31 00:55:14 2008 -0700 2.3 @@ -27,7 +27,8 @@ 2.4 2.5 name = letter + Rep(letter | digit) 2.6 intconst = decimal | (Str("0x") + Rep1(hexdigit)) 2.7 - longconst = intconst + Str("L") 2.8 + intsuffix = (Opt(Any("Uu")) + Opt(Any("Ll")) + Opt(Any("Ll"))) | (Opt(Any("Ll")) + Opt(Any("Ll")) + Opt(Any("Uu"))) 2.9 + intliteral = intconst + intsuffix 2.10 fltconst = (decimal_fract + Opt(exponent)) | (decimal + exponent) 2.11 imagconst = (intconst | fltconst) + Any("jJ") 2.12 2.13 @@ -79,8 +80,7 @@ 2.14 2.15 return Lexicon([ 2.16 (name, 'IDENT'), 2.17 - (intconst, 'INT'), 2.18 - (longconst, 'LONG'), 2.19 + (intliteral, 'INT'), 2.20 (fltconst, 'FLOAT'), 2.21 (imagconst, 'IMAG'), 2.22 (deco, 'DECORATOR'),
3.1 --- a/Cython/Compiler/ModuleNode.py Wed Jul 23 23:02:37 2008 -0700 3.2 +++ b/Cython/Compiler/ModuleNode.py Thu Jul 31 00:55:14 2008 -0700 3.3 @@ -1718,10 +1718,16 @@ 3.4 3.5 def generate_intern_code(self, env, code): 3.6 for entry in env.pynum_entries: 3.7 - code.putln("%s = PyInt_FromLong(%s); %s;" % ( 3.8 - entry.cname, 3.9 - entry.init, 3.10 - code.error_goto_if_null(entry.cname, self.pos))) 3.11 + if entry.init[-1] == "L": 3.12 + code.putln('%s = PyLong_FromString("%s", 0, 0); %s;' % ( 3.13 + entry.cname, 3.14 + entry.init, 3.15 + code.error_goto_if_null(entry.cname, self.pos))) 3.16 + else: 3.17 + code.putln("%s = PyInt_FromLong(%s); %s;" % ( 3.18 + entry.cname, 3.19 + entry.init, 3.20 + code.error_goto_if_null(entry.cname, self.pos))) 3.21 3.22 def generate_string_init_code(self, env, code): 3.23 if env.all_pystring_entries:
4.1 --- a/Cython/Compiler/Parsing.py Wed Jul 23 23:02:37 2008 -0700 4.2 +++ b/Cython/Compiler/Parsing.py Thu Jul 31 00:55:14 2008 -0700 4.3 @@ -466,11 +466,18 @@ 4.4 elif sy == 'INT': 4.5 value = s.systring 4.6 s.next() 4.7 - return ExprNodes.IntNode(pos, value = value) 4.8 - elif sy == 'LONG': 4.9 - value = s.systring 4.10 - s.next() 4.11 - return ExprNodes.LongNode(pos, value = value) 4.12 + unsigned = "" 4.13 + longness = "" 4.14 + while value[-1] in "UuLl": 4.15 + if value[-1] in "Ll": 4.16 + longness += "L" 4.17 + else: 4.18 + unsigned += "U" 4.19 + value = value[:-1] 4.20 + return ExprNodes.IntNode(pos, 4.21 + value = value, 4.22 + unsigned = unsigned, 4.23 + longness = longness) 4.24 elif sy == 'FLOAT': 4.25 value = s.systring 4.26 s.next() 4.27 @@ -516,7 +523,7 @@ 4.28 elif isinstance(value, int): 4.29 return ExprNodes.IntNode(pos, value = rep) 4.30 elif isinstance(value, long): 4.31 - return ExprNodes.LongNode(pos, value = rep) 4.32 + return ExprNodes.IntNode(pos, value = rep, longness = "L") 4.33 elif isinstance(value, float): 4.34 return ExprNodes.FloatNode(pos, value = rep) 4.35 elif isinstance(value, unicode):
5.1 --- a/Cython/Compiler/Symtab.py Wed Jul 23 23:02:37 2008 -0700 5.2 +++ b/Cython/Compiler/Symtab.py Thu Jul 31 00:55:14 2008 -0700 5.3 @@ -544,9 +544,11 @@ 5.4 self.interned_nums.append(entry) 5.5 return entry 5.6 5.7 - def get_py_num(self, value): 5.8 + def get_py_num(self, value, longness): 5.9 # Get entry for int constant. Returns an existing 5.10 # one if possible, otherwise creates a new one. 5.11 + if longness or Utils.long_literal(value): 5.12 + value += "L" 5.13 genv = self.global_scope() 5.14 entry = genv.num_to_entry.get(value) 5.15 if not entry:
6.1 --- a/Cython/Utils.py Wed Jul 23 23:02:37 2008 -0700 6.2 +++ b/Cython/Utils.py Thu Jul 31 00:55:14 2008 -0700 6.3 @@ -115,3 +115,13 @@ 6.4 else: 6.5 append(c) 6.6 return ''.join(l) 6.7 + 6.8 +def long_literal(value): 6.9 + if isinstance(value, basestring): 6.10 + if len(value) < 2: 6.11 + value = int(value) 6.12 + elif value[0] == 0: 6.13 + return int(value, 8) 6.14 + elif value[1] in 'xX': 6.15 + return int(value[2:], 16) 6.16 + return not -2**31 <= value < 2**31
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/tests/run/int_literals.pyx Thu Jul 31 00:55:14 2008 -0700 7.3 @@ -0,0 +1,17 @@ 7.4 +__doc__ = """ 7.5 + >>> c_longs() 7.6 + (1, 1L, -1L, 18446744073709551615L) 7.7 + >>> py_longs() 7.8 + (1, 1L, 100000000000000000000000000000000L, -100000000000000000000000000000000L) 7.9 +""" 7.10 + 7.11 +def c_longs(): 7.12 + cdef long a = 1L 7.13 + cdef unsigned long ua = 1UL 7.14 + cdef long long aa = 0xFFFFFFFFFFFFFFFFLL 7.15 + cdef unsigned long long uaa = 0xFFFFFFFFFFFFFFFFULL 7.16 + 7.17 + return a, ua, aa, uaa 7.18 + 7.19 +def py_longs(): 7.20 + return 1, 1L, 100000000000000000000000000000000, -100000000000000000000000000000000