Commit 7d18de21 authored by Robert Bradshaw's avatar Robert Bradshaw

Merge branch 'feat/casts' of git://github.com/memeplex/cython

parents 92f57792 6d55fd18
...@@ -9625,8 +9625,7 @@ class TypecastNode(ExprNode): ...@@ -9625,8 +9625,7 @@ class TypecastNode(ExprNode):
return CoerceIntToBytesNode(self.operand, env) return CoerceIntToBytesNode(self.operand, env)
elif self.operand.type.can_coerce_to_pyobject(env): elif self.operand.type.can_coerce_to_pyobject(env):
self.result_ctype = py_object_type self.result_ctype = py_object_type
base_type = self.base_type.analyse(env) self.operand = self.operand.coerce_to(self.type, env)
self.operand = self.operand.coerce_to(base_type, env)
else: else:
if self.operand.type.is_ptr: if self.operand.type.is_ptr:
if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct): if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
......
...@@ -2703,11 +2703,13 @@ class TransformBuiltinMethods(EnvTransform): ...@@ -2703,11 +2703,13 @@ class TransformBuiltinMethods(EnvTransform):
node.function.pos, operand1=node.args[0], operand2=node.args[1]) node.function.pos, operand1=node.args[0], operand2=node.args[1])
elif function == u'cast': elif function == u'cast':
if len(node.args) != 2: if len(node.args) != 2:
error(node.function.pos, u"cast() takes exactly two arguments") error(node.function.pos,
u"cast() takes exactly two arguments and an optional typecheck keyword")
else: else:
type = node.args[0].analyse_as_type(self.current_env()) type = node.args[0].analyse_as_type(self.current_env())
if type: if type:
node = ExprNodes.TypecastNode(node.function.pos, type=type, operand=node.args[1]) node = ExprNodes.TypecastNode(
node.function.pos, type=type, operand=node.args[1], typecheck=False)
else: else:
error(node.args[0].pos, "Not a type") error(node.args[0].pos, "Not a type")
elif function == u'sizeof': elif function == u'sizeof':
...@@ -2753,6 +2755,26 @@ class TransformBuiltinMethods(EnvTransform): ...@@ -2753,6 +2755,26 @@ class TransformBuiltinMethods(EnvTransform):
return self._inject_super(node, func_name) return self._inject_super(node, func_name)
return node return node
def visit_GeneralCallNode(self, node):
function = node.function.as_cython_attribute()
if function:
args = node.positional_args.args
kwargs = node.keyword_args.compile_time_value(None)
if function == u'cast':
if (len(args) != 2 or len(kwargs) > 1 or
(len(kwargs) == 1 and 'typecheck' not in kwargs)):
error(node.function.pos,
u"cast() takes exactly two arguments and an optional typecheck keyword")
else:
type = args[0].analyse_as_type(self.current_env())
if type:
typecheck = kwargs.get('typecheck', False)
node = ExprNodes.TypecastNode(
node.function.pos, type=type, operand=args[1], typecheck=typecheck)
else:
error(args[0].pos, "Not a type")
return node
class ReplaceFusedTypeChecks(VisitorTransform): class ReplaceFusedTypeChecks(VisitorTransform):
""" """
......
...@@ -148,7 +148,9 @@ def cmod(a, b): ...@@ -148,7 +148,9 @@ def cmod(a, b):
# Emulated language constructs # Emulated language constructs
def cast(type, *args): def cast(type, *args, **kwargs):
kwargs.pop('typecheck', None)
assert not kwargs
if hasattr(type, '__call__'): if hasattr(type, '__call__'):
return type(*args) return type(*args)
else: else:
......
...@@ -287,6 +287,15 @@ Further Cython functions and declarations ...@@ -287,6 +287,15 @@ Further Cython functions and declarations
T = cython.typedef(cython.p_int) # ctypedef int* T T = cython.typedef(cython.p_int) # ctypedef int* T
* ``cast`` will (unsafely) reinterpret an expression type. ``cython.cast(T, t)``
is equivalent to ``<T>t``. The first attribute must be a type, the second is
the expression to cast. Specifying the optional keyword argument
``typecheck=True`` has the semantics of ``<T?>t``.
::
t1 = cython.cast(T, t)
t2 = cython.cast(T, t, typecheck=True)
.. _magic_attributes_pxd: .. _magic_attributes_pxd:
......
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