Commit 01e9ff88 authored by Robert Bradshaw's avatar Robert Bradshaw

Allow typeof(...) to be used in a type context.

parent 6501e274
...@@ -5267,6 +5267,11 @@ class SimpleCallNode(CallNode): ...@@ -5267,6 +5267,11 @@ class SimpleCallNode(CallNode):
error(self.args[0].pos, "Unknown type") error(self.args[0].pos, "Unknown type")
else: else:
return PyrexTypes.CPtrType(type) return PyrexTypes.CPtrType(type)
elif attr == 'typeof':
if len(self.args) != 1:
error(self.args.pos, "only one type allowed.")
operand = self.args[0].analyse_types(env)
return operand.type
def explicit_args_kwds(self): def explicit_args_kwds(self):
return self.args, None return self.args, None
...@@ -10683,6 +10688,10 @@ class TypeofNode(ExprNode): ...@@ -10683,6 +10688,10 @@ class TypeofNode(ExprNode):
self.literal = literal.coerce_to_pyobject(env) self.literal = literal.coerce_to_pyobject(env)
return self return self
def analyse_as_type(env):
self.operand = self.operand.analyse_types(env)
return self.operand.type
def may_be_none(self): def may_be_none(self):
return False return False
......
...@@ -15,6 +15,7 @@ from . import ExprNodes ...@@ -15,6 +15,7 @@ from . import ExprNodes
from . import Nodes from . import Nodes
from . import Options from . import Options
from . import Builtin from . import Builtin
from . import Errors
from .Visitor import VisitorTransform, TreeVisitor from .Visitor import VisitorTransform, TreeVisitor
from .Visitor import CythonTransform, EnvTransform, ScopeTrackingTransform from .Visitor import CythonTransform, EnvTransform, ScopeTrackingTransform
...@@ -3157,8 +3158,9 @@ class ReplaceFusedTypeChecks(VisitorTransform): ...@@ -3157,8 +3158,9 @@ class ReplaceFusedTypeChecks(VisitorTransform):
return self.transform(node) return self.transform(node)
def visit_PrimaryCmpNode(self, node): def visit_PrimaryCmpNode(self, node):
type1 = node.operand1.analyse_as_type(self.local_scope) with Errors.local_errors(ignore=True):
type2 = node.operand2.analyse_as_type(self.local_scope) type1 = node.operand1.analyse_as_type(self.local_scope)
type2 = node.operand2.analyse_as_type(self.local_scope)
if type1 and type2: if type1 and type2:
false_node = ExprNodes.BoolNode(node.pos, value=False) false_node = ExprNodes.BoolNode(node.pos, value=False)
......
...@@ -131,6 +131,19 @@ def test_func_ptr(double x): ...@@ -131,6 +131,19 @@ def test_func_ptr(double x):
finally: finally:
del w del w
def test_typeof(double x):
"""
>>> test_func_ptr(3)
9.0
>>> test_func_ptr(-1.5)
2.25
"""
try:
w = new Wrap[cython.typeof(&f)](&f)
return w.get()(x)
finally:
del w
def test_cast_template_pointer(): def test_cast_template_pointer():
""" """
>>> test_cast_template_pointer() >>> test_cast_template_pointer()
......
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