Commit 6d55fd18 authored by memeplex's avatar memeplex

Add typecheck keyword.

parent c1b040db
...@@ -2703,7 +2703,8 @@ class TransformBuiltinMethods(EnvTransform): ...@@ -2703,7 +2703,8 @@ 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:
...@@ -2754,6 +2755,26 @@ class TransformBuiltinMethods(EnvTransform): ...@@ -2754,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):
""" """
......
...@@ -136,7 +136,9 @@ def cmod(a, b): ...@@ -136,7 +136,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