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): ...@@ -2186,7 +2186,7 @@ class NotNode(ExprNode):
def analyse_types(self, env): def analyse_types(self, env):
self.operand.analyse_types(env) self.operand.analyse_types(env)
self.operand = self.operand.coerce_to_boolean(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): def calculate_result_code(self):
return "(!%s)" % self.operand.result_code return "(!%s)" % self.operand.result_code
...@@ -2623,13 +2623,12 @@ class BoolBinopNode(ExprNode): ...@@ -2623,13 +2623,12 @@ class BoolBinopNode(ExprNode):
self.operand2.type.is_pyobject: self.operand2.type.is_pyobject:
self.operand1 = self.operand1.coerce_to_pyobject(env) self.operand1 = self.operand1.coerce_to_pyobject(env)
self.operand2 = self.operand2.coerce_to_pyobject(env) self.operand2 = self.operand2.coerce_to_pyobject(env)
self.temp_bool = TempNode(self.pos, self.temp_bool = TempNode(self.pos, PyrexTypes.c_bint_type, env)
PyrexTypes.c_int_type, env)
self.type = py_object_type self.type = py_object_type
else: else:
self.operand1 = self.operand1.coerce_to_boolean(env) self.operand1 = self.operand1.coerce_to_boolean(env)
self.operand2 = self.operand2.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 # For what we're about to do, it's vital that
# both operands be temp nodes. # both operands be temp nodes.
self.operand1 = self.operand1.coerce_to_temp(env) #CTT self.operand1 = self.operand1.coerce_to_temp(env) #CTT
...@@ -2886,7 +2885,7 @@ class PrimaryCmpNode(ExprNode, CmpNode): ...@@ -2886,7 +2885,7 @@ class PrimaryCmpNode(ExprNode, CmpNode):
self.operand2 = self.operand2.coerce_to_simple(env) self.operand2 = self.operand2.coerce_to_simple(env)
self.cascade.coerce_cascaded_operands_to_temp(env) self.cascade.coerce_cascaded_operands_to_temp(env)
self.check_operand_types(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: if self.is_pycmp or self.cascade:
self.is_temp = 1 self.is_temp = 1
...@@ -3167,7 +3166,7 @@ class CoerceToBooleanNode(CoercionNode): ...@@ -3167,7 +3166,7 @@ class CoerceToBooleanNode(CoercionNode):
def __init__(self, arg, env): def __init__(self, arg, env):
CoercionNode.__init__(self, arg) CoercionNode.__init__(self, arg)
self.type = PyrexTypes.c_int_type self.type = PyrexTypes.c_bint_type
if arg.type.is_pyobject: if arg.type.is_pyobject:
self.is_temp = 1 self.is_temp = 1
......
...@@ -1348,7 +1348,7 @@ def looking_at_dotted_name(s): ...@@ -1348,7 +1348,7 @@ def looking_at_dotted_name(s):
# "void", "signed", "unsigned" # "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") sign_and_longness_words = ("short", "long", "signed", "unsigned")
......
...@@ -343,6 +343,12 @@ class CIntType(CNumericType): ...@@ -343,6 +343,12 @@ class CIntType(CNumericType):
self.is_returncode = is_returncode self.is_returncode = is_returncode
class CBIntType(CIntType):
to_py_function = "PyBool_FromLong"
from_py_function = "PyObject_IsTrue"
class CPySSizeTType(CIntType): class CPySSizeTType(CIntType):
to_py_function = "PyInt_FromSsize_t" to_py_function = "PyInt_FromSsize_t"
...@@ -710,6 +716,8 @@ c_long_type = CIntType(3, 1, "T_LONG") ...@@ -710,6 +716,8 @@ c_long_type = CIntType(3, 1, "T_LONG")
c_longlong_type = CLongLongType(4, 1, "T_LONGLONG") c_longlong_type = CLongLongType(4, 1, "T_LONGLONG")
c_py_ssize_t_type = CPySSizeTType(5, 1) 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_uchar_type = CIntType(0, 0, "T_UBYTE")
c_ushort_type = CIntType(1, 0, "T_USHORT") c_ushort_type = CIntType(1, 0, "T_USHORT")
c_uint_type = CUIntType(2, 0, "T_UINT") c_uint_type = CUIntType(2, 0, "T_UINT")
...@@ -781,6 +789,8 @@ modifiers_and_name_to_type = { ...@@ -781,6 +789,8 @@ modifiers_and_name_to_type = {
(1, 0, "double"): c_double_type, (1, 0, "double"): c_double_type,
(1, 1, "double"): c_longdouble_type, (1, 1, "double"): c_longdouble_type,
(1, 0, "object"): py_object_type, (1, 0, "object"): py_object_type,
(1, 0, "bint"): c_bint_type,
} }
def widest_numeric_type(type1, type2): def widest_numeric_type(type1, type2):
......
...@@ -476,12 +476,12 @@ class BuiltinScope(Scope): ...@@ -476,12 +476,12 @@ class BuiltinScope(Scope):
# TODO: built in functions conflict with built in types of same name... # TODO: built in functions conflict with built in types of same name...
builtin_functions = { 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], "cmp": ["PyObject_Compare", c_int_type, (py_object_type, py_object_type), None, True],
"repr": ["PyObject_Repr", py_object_type, (py_object_type, ), 0], "repr": ["PyObject_Repr", py_object_type, (py_object_type, ), 0],
# "str": ["PyObject_Str", 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], "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], "hash": ["PyObject_Hash", c_long_type, (py_object_type, ), -1, True],
"type": ["PyObject_Type", py_object_type, (py_object_type, ), 0], "type": ["PyObject_Type", py_object_type, (py_object_type, ), 0],
"len": ["PyObject_Size", c_py_ssize_t_type, (py_object_type, ), -1], "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