From: Robert Bradshaw Date: Thu, 26 Apr 2007 02:54:15 +0000 (-0700) Subject: Added a bint c type, which is a c int that coerces to and from python objects via... X-Git-Tag: 0.9.6.14~29^2~189 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=eb232cedf0fce41930af559b1b31ce770cb87a46;p=cython.git Added a bint c type, which is a c int that coerces to and from python objects via the boolean routines. 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. --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 674a0392..bb566a98 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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 diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index d4cd052a..a88e9236 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -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") diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 1b05ed59..267e637d 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -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): diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 9ef944fa..c1e57b39 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -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],