# declarator CDeclaratorNode
subexprs = []
+ arg_type = None
def analyse_types(self, env):
# we may have incorrectly interpreted a dotted name as a type rather than an attribute
# this could be better handled by more uniformly treating types as runtime-available objects
- if self.base_type.module_path and 0:
+ if 0 and self.base_type.module_path:
path = self.base_type.module_path
obj = env.lookup(path[0])
if obj.as_module is None:
self.__class__ = SizeofVarNode
self.analyse_types(env)
return
- base_type = self.base_type.analyse(env)
- _, arg_type = self.declarator.analyse(base_type, env)
- self.arg_type = arg_type
+ if self.arg_type is None:
+ base_type = self.base_type.analyse(env)
+ _, arg_type = self.declarator.analyse(base_type, env)
+ self.arg_type = arg_type
self.check_type()
def check_type(self):
self.options = options
node.directives = options
self.visitchildren(node)
+ node.cython_module_names = self.cython_module_names
return node
# Track cimports of the cython module.
class TransformBuiltinMethods(EnvTransform):
- def visit_SimpleCallNode(self, node):
+ def cython_attribute(self, node):
+ if (isinstance(node, AttributeNode) and
+ isinstance(node.obj, NameNode) and
+ node.obj.name in self.cython_module_names):
+ return node.attribute
+
+ def visit_ModuleNode(self, node):
+ self.cython_module_names = node.cython_module_names
self.visitchildren(node)
+ return node
+
+ def visit_AttributeNode(self, node):
+ attribute = self.cython_attribute(node)
+ if attribute:
+ if attribute == u'compiled':
+ node = BoolNode(node.pos, value=True)
+ else:
+ error(node.function.pos, u"'%s' not a valid cython attribute" % function)
+ return node
+
+ def visit_SimpleCallNode(self, node):
+
+ # locals
if isinstance(node.function, ExprNodes.NameNode):
if node.function.name == 'locals':
pos = node.pos
key=ExprNodes.IdentifierStringNode(pos, value=var),
value=ExprNodes.NameNode(pos, name=var)) for var in lenv.entries]
return ExprNodes.DictNode(pos, key_value_pairs=items)
+
+ # cython.foo
+ function = self.cython_attribute(node.function)
+ if function:
+ if function == u'cast':
+ if len(node.args) != 2:
+ error(node.function.pos, u"cast takes exactly two arguments" % function)
+ else:
+ type = node.args[0].analyse_as_type(self.env_stack[-1])
+ if type:
+ node = TypecastNode(node.function.pos, type=type, operand=node.args[1])
+ else:
+ error(node.args[0].pos, "Not a type")
+ elif function == u'sizeof':
+ if len(node.args) != 1:
+ error(node.function.pos, u"sizeof takes exactly one argument" % function)
+ else:
+ type = node.args[0].analyse_as_type(self.env_stack[-1])
+ if type:
+ node = SizeofTypeNode(node.function.pos, arg_type=type)
+ else:
+ node = SizeofVarNode(node.function.pos, operand=node.args[0])
+ else:
+ error(node.function.pos, u"'%s' not a valid cython language construct" % function)
+
+ self.visitchildren(node)
return node
(1, 0, "int"): c_int_type,
(1, 1, "int"): c_long_type,
(1, 2, "int"): c_longlong_type,
- (1, 0, "long"): c_long_type,
(1, 0, "Py_ssize_t"): c_py_ssize_t_type,
(1, 0, "float"): c_float_type,
(1, 0, "double"): c_double_type,
(2, 1, "int"): c_slong_type,
(2, 2, "int"): c_slonglong_type,
(2, 0, "Py_ssize_t"): c_py_ssize_t_type,
+
+ (1, 0, "long"): c_long_type,
+ (1, 0, "bint"): c_bint_type,
}
def widest_numeric_type(type1, type2):