Added a bint c type, which is a c int that coerces to and from python objects via...
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 26 Apr 2007 02:54:15 +0000 (19:54 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 26 Apr 2007 02:54:15 +0000 (19:54 -0700)
The purpose of this type is to free the coder from having to use
bool() when retrieving and returning semantically "boolean" values
(e.g. the result of a compare).

The bint type is a subclass of the int type, and the only difference
is that it uses PyBool_FromLong and PyObject_IsTrue rather than
PyInt_FromLong and PyInt_AsLong. Arithmatic on bints will return ints.

Where it makes sense, several builtin functions have been re-declared
to return bints, as well as comparisons and the boolean operations
or, and, and not.

Cython/Compiler/ExprNodes.py
Cython/Compiler/Parsing.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py

index 674a0392085160ee59243c7993a7b3b58d3ca5ae..bb566a9828223dac86b956e1a95beee22a01be59 100644 (file)
@@ -2186,7 +2186,7 @@ class NotNode(ExprNode):
     def analyse_types(self, env):
         self.operand.analyse_types(env)
         self.operand = self.operand.coerce_to_boolean(env)
-        self.type = PyrexTypes.c_int_type
+        self.type = PyrexTypes.c_bint_type
     
     def calculate_result_code(self):
         return "(!%s)" % self.operand.result_code
@@ -2623,13 +2623,12 @@ class BoolBinopNode(ExprNode):
                 self.operand2.type.is_pyobject:
             self.operand1 = self.operand1.coerce_to_pyobject(env)
             self.operand2 = self.operand2.coerce_to_pyobject(env)
-            self.temp_bool = TempNode(self.pos,
-                PyrexTypes.c_int_type, env)
+            self.temp_bool = TempNode(self.pos, PyrexTypes.c_bint_type, env)
             self.type = py_object_type
         else:
             self.operand1 = self.operand1.coerce_to_boolean(env)
             self.operand2 = self.operand2.coerce_to_boolean(env)
-            self.type = PyrexTypes.c_int_type
+            self.type = PyrexTypes.c_bint_type
         # For what we're about to do, it's vital that
         # both operands be temp nodes.
         self.operand1 = self.operand1.coerce_to_temp(env) #CTT
@@ -2886,7 +2885,7 @@ class PrimaryCmpNode(ExprNode, CmpNode):
             self.operand2 = self.operand2.coerce_to_simple(env)
             self.cascade.coerce_cascaded_operands_to_temp(env)
         self.check_operand_types(env)
-        self.type = PyrexTypes.c_int_type
+        self.type = PyrexTypes.c_bint_type
         if self.is_pycmp or self.cascade:
             self.is_temp = 1
     
@@ -3167,7 +3166,7 @@ class CoerceToBooleanNode(CoercionNode):
     
     def __init__(self, arg, env):
         CoercionNode.__init__(self, arg)
-        self.type = PyrexTypes.c_int_type
+        self.type = PyrexTypes.c_bint_type
         if arg.type.is_pyobject:
             self.is_temp = 1
     
index d4cd052a2df289483c8080a5d726eab064514756..a88e92367414abece6b9c6371300c6bace886adc 100644 (file)
@@ -1348,7 +1348,7 @@ def looking_at_dotted_name(s):
 #      "void", "signed", "unsigned"
 #)
 
-basic_c_type_names = ("void", "char", "int", "float", "double", "Py_ssize_t")
+basic_c_type_names = ("void", "char", "int", "float", "double", "Py_ssize_t", "bint")
 
 sign_and_longness_words = ("short", "long", "signed", "unsigned")
 
index 1b05ed59622f55bdf20008608a1a9fb46c52bc82..267e637d1f3aedc56024bec4e415d62af06c385b 100644 (file)
@@ -341,7 +341,13 @@ class CIntType(CNumericType):
     def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
         CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
         self.is_returncode = is_returncode
+        
 
+class CBIntType(CIntType):
+    
+    to_py_function = "PyBool_FromLong"
+    from_py_function = "PyObject_IsTrue"
+    
 
 class CPySSizeTType(CIntType):
 
@@ -710,6 +716,8 @@ c_long_type =     CIntType(3, 1, "T_LONG")
 c_longlong_type = CLongLongType(4, 1, "T_LONGLONG")
 c_py_ssize_t_type = CPySSizeTType(5, 1)
 
+c_bint_type =      CBIntType(2, 1, "T_INT")
+
 c_uchar_type =     CIntType(0, 0, "T_UBYTE")
 c_ushort_type =    CIntType(1, 0, "T_USHORT")
 c_uint_type =      CUIntType(2, 0, "T_UINT")
@@ -768,8 +776,8 @@ modifiers_and_name_to_type = {
     (0, 0, "char"): c_uchar_type, 
     (0, -1, "int"): c_ushort_type, 
     (0, 0, "int"): c_uint_type, 
-  (0, 1, "int"): c_ulong_type,
-  (0, 2, "int"): c_ulonglong_type,
+    (0, 1, "int"): c_ulong_type,
+    (0, 2, "int"): c_ulonglong_type,
     (1, 0, "void"): c_void_type,
     (1, 0, "char"): c_char_type, 
     (1, -1, "int"): c_short_type, 
@@ -781,6 +789,8 @@ modifiers_and_name_to_type = {
     (1, 0, "double"): c_double_type,
     (1, 1, "double"): c_longdouble_type,
     (1, 0, "object"): py_object_type,
+
+    (1, 0, "bint"): c_bint_type, 
 }
 
 def widest_numeric_type(type1, type2):
index 9ef944fac5ba9af365ad1ae923d3def4c45277fd..c1e57b394e4f71724f726e1f099ad1a949c7bdbc 100644 (file)
@@ -476,12 +476,12 @@ class BuiltinScope(Scope):
     # TODO: built in functions conflict with built in types of same name...
     
     builtin_functions = {
-      "hasattr": ["PyObject_HasAttrString", c_int_type, (py_object_type, c_char_ptr_type)],
+      "hasattr": ["PyObject_HasAttrString", c_bint_type, (py_object_type, c_char_ptr_type)],
       "cmp":     ["PyObject_Compare", c_int_type, (py_object_type, py_object_type), None, True],
       "repr":    ["PyObject_Repr", py_object_type, (py_object_type, ), 0],
 #      "str":     ["PyObject_Str", py_object_type, (py_object_type, ), 0],
       "unicode": ["PyObject_Unicode", py_object_type, (py_object_type, ), 0],
-      "isinstance": ["PyObject_IsInstance", c_int_type, (py_object_type, py_object_type), -1],
+      "isinstance": ["PyObject_IsInstance", c_bint_type, (py_object_type, py_object_type), -1],
       "hash":    ["PyObject_Hash", c_long_type, (py_object_type, ), -1, True],
       "type":    ["PyObject_Type", py_object_type, (py_object_type, ), 0],
       "len":     ["PyObject_Size", c_py_ssize_t_type, (py_object_type, ), -1],