Commit 8da8ec52 authored by Robert Bradshaw's avatar Robert Bradshaw

cython.typeof special method

parent 578d94c5
......@@ -4245,6 +4245,24 @@ class SizeofVarNode(SizeofNode):
def generate_result_code(self, code):
pass
class TypeofNode(StringNode):
# Compile-time type of an expression, as a string.
#
# operand ExprNode
subexprs = ['operand']
def analyse_types(self, env):
self.operand.analyse_types(env)
from StringEncoding import EncodedString
self.value = EncodedString(str(self.operand.type))
StringNode.analyse_types(self, env)
def analyse_as_type(self, env):
return None
def generate_evaluation_code(self, code):
self.generate_result_code(code)
#-------------------------------------------------------------------
#
......@@ -4850,9 +4868,6 @@ class CondExprNode(ExprNode):
def infer_type(self, env):
return self.compute_result_type(self.true_val.infer_type(env),
self.false_val.infer_type(env))
def infer_types(self, env):
return self.compute_result_type(self.true_val.infer_types(env),
self.false_val.infer_types(env))
def calculate_constant_result(self):
if self.test.constant_result:
......
......@@ -328,7 +328,7 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
duplication of functionality has to occur: We manually track cimports
and which names the "cython" module may have been imported to.
"""
special_methods = set(['declare', 'union', 'struct', 'typedef', 'sizeof', 'cast', 'address', 'pointer', 'compiled', 'NULL'])
special_methods = set(['declare', 'union', 'struct', 'typedef', 'sizeof', 'typeof', 'cast', 'address', 'pointer', 'compiled', 'NULL'])
def __init__(self, context, compilation_option_overrides):
super(InterpretCompilerDirectives, self).__init__(context)
......@@ -1009,6 +1009,11 @@ class TransformBuiltinMethods(EnvTransform):
node = SizeofTypeNode(node.function.pos, arg_type=type)
else:
node = SizeofVarNode(node.function.pos, operand=node.args[0])
elif function == 'typeof':
if len(node.args) != 1:
error(node.function.pos, u"sizeof takes exactly one argument" % function)
else:
node = TypeofNode(node.function.pos, operand=node.args[0])
elif function == 'address':
if len(node.args) != 1:
error(node.function.pos, u"sizeof takes exactly one argument" % function)
......
......@@ -30,6 +30,9 @@ def cast(type, arg):
def sizeof(arg):
return 1
def typeof(arg):
return type(arg)
def address(arg):
return pointer(type(arg))([arg])
......
__doc__ = u"""
>>> simple()
int
long
long long
int *
int **
A
B
X
Python object
>>> expression()
double
double complex
int
unsigned int
"""
from cython cimport typeof
cdef class A:
pass
cdef class B(A):
pass
cdef struct X:
double a
double complex b
def simple():
cdef int i
cdef long l
cdef long long ll
cdef int* iptr
cdef int** iptrptr
cdef A a
cdef B b
cdef X x
print typeof(i)
print typeof(l)
print typeof(ll)
print typeof(iptr)
print typeof(iptrptr)
print typeof(a)
print typeof(b)
print typeof(x)
print typeof(None)
def expression():
cdef X x
cdef X *xptr
cdef short s
cdef int i
cdef unsigned int ui
print typeof(x.a)
print typeof(xptr.b)
print typeof(s + i)
print typeof(i + ui)
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