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.
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
