Commit eb232ced authored by Robert Bradshaw's avatar Robert Bradshaw

Added a bint c type, which is a c int that coerces to and from python objects...

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.
parent 6fd9a195
......@@ -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
......
......@@ -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")
......
......@@ -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):
......
......@@ -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],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment