fix octal literals as Python constants, convert octal/binary/hex integer literals...
authorStefan Behnel <scoder@users.berlios.de>
Tue, 2 Nov 2010 17:14:29 +0000 (18:14 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Tue, 2 Nov 2010 17:14:29 +0000 (18:14 +0100)
Cython/Compiler/ExprNodes.py
tests/run/int_literals.pyx

index 72e7b5e3b58ad9377ee1fd23a1ff5d5ed11d5e8d..4d8f3ed17af790a538e6df16231b6a614816be16 100755 (executable)
@@ -833,19 +833,28 @@ class IntNode(ConstNode):
     def generate_evaluation_code(self, code):
         if self.type.is_pyobject:
             # pre-allocate a Python version of the number
-            self.result_code = code.get_py_num(self.value, self.longness)
+            plain_integer_string = self.value_as_c_integer_string(plain_digits=True)
+            self.result_code = code.get_py_num(plain_integer_string, self.longness)
         else:
             self.result_code = self.get_constant_c_result_code()
     
     def get_constant_c_result_code(self):
+        return self.value_as_c_integer_string() + self.unsigned + self.longness
+
+    def value_as_c_integer_string(self, plain_digits=False):
         value = self.value
         if isinstance(value, basestring) and len(value) > 2:
             # must convert C-incompatible Py3 oct/bin notations
             if value[1] in 'oO':
-                value = value[0] + value[2:] # '0o123' => '0123'
+                if plain_digits:
+                    value = int(value[2:], 8)
+                else:
+                    value = value[0] + value[2:] # '0o123' => '0123'
             elif value[1] in 'bB':
                 value = int(value[2:], 2)
-        return str(value) + self.unsigned + self.longness
+            elif plain_digits and value[1] in 'xX':
+                value = int(value[2:], 16)
+        return str(value)
 
     def calculate_result_code(self):
         return self.result_code
index 2e38b0cf5835ff4dff10684003addcc55d35c78d..2ff8351bde84a44e11c6d5ee0376c82c5e057bd2 100644 (file)
@@ -53,3 +53,56 @@ def c_long_types():
     print typeof(1U)
     print typeof(1UL)
     print typeof(1ULL)
+
+# different ways to write an integer in Python
+
+def c_oct():
+    """
+    >>> c_oct()
+    (1, 17, 63)
+    """
+    cdef int a = 0o01
+    cdef int b = 0o21
+    cdef int c = 0o77
+    return a,b,c
+
+def py_oct():
+    """
+    >>> py_oct()
+    (1, 17, 63)
+    """
+    return 0o01, 0o21, 0o77
+
+def c_hex():
+    """
+    >>> c_hex()
+    (1, 33, 255)
+    """
+    cdef int a = 0x01
+    cdef int b = 0x21
+    cdef int c = 0xFF
+    return a,b,c
+
+def py_hex():
+    """
+    >>> py_hex()
+    (1, 33, 255)
+    """
+    return 0x01, 0x21, 0xFF
+
+def c_bin():
+    """
+    >>> c_bin()
+    (1, 2, 15)
+    """
+    cdef int a = 0b01
+    cdef int b = 0b10
+    cdef int c = 0b1111
+    return a,b,c
+
+def py_bin():
+    """
+    >>> py_bin()
+    (1, 2, 15)
+    """
+    return 0b01, 0b10, 0b1111