Commit d3e42d3a authored by Robert Bradshaw's avatar Robert Bradshaw

cython.cast, cython.sizeof, and cython.compiled for pure Python mode

parent 7771e204
...@@ -3166,11 +3166,12 @@ class SizeofTypeNode(SizeofNode): ...@@ -3166,11 +3166,12 @@ class SizeofTypeNode(SizeofNode):
# declarator CDeclaratorNode # declarator CDeclaratorNode
subexprs = [] subexprs = []
arg_type = None
def analyse_types(self, env): def analyse_types(self, env):
# we may have incorrectly interpreted a dotted name as a type rather than an attribute # 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 # 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 path = self.base_type.module_path
obj = env.lookup(path[0]) obj = env.lookup(path[0])
if obj.as_module is None: if obj.as_module is None:
...@@ -3182,9 +3183,10 @@ class SizeofTypeNode(SizeofNode): ...@@ -3182,9 +3183,10 @@ class SizeofTypeNode(SizeofNode):
self.__class__ = SizeofVarNode self.__class__ = SizeofVarNode
self.analyse_types(env) self.analyse_types(env)
return return
base_type = self.base_type.analyse(env) if self.arg_type is None:
_, arg_type = self.declarator.analyse(base_type, env) base_type = self.base_type.analyse(env)
self.arg_type = arg_type _, arg_type = self.declarator.analyse(base_type, env)
self.arg_type = arg_type
self.check_type() self.check_type()
def check_type(self): def check_type(self):
......
...@@ -282,6 +282,7 @@ class InterpretCompilerDirectives(CythonTransform): ...@@ -282,6 +282,7 @@ class InterpretCompilerDirectives(CythonTransform):
self.options = options self.options = options
node.directives = options node.directives = options
self.visitchildren(node) self.visitchildren(node)
node.cython_module_names = self.cython_module_names
return node return node
# Track cimports of the cython module. # Track cimports of the cython module.
...@@ -637,8 +638,29 @@ class EnvTransform(CythonTransform): ...@@ -637,8 +638,29 @@ class EnvTransform(CythonTransform):
class TransformBuiltinMethods(EnvTransform): 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) 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 isinstance(node.function, ExprNodes.NameNode):
if node.function.name == 'locals': if node.function.name == 'locals':
pos = node.pos pos = node.pos
...@@ -647,4 +669,30 @@ class TransformBuiltinMethods(EnvTransform): ...@@ -647,4 +669,30 @@ class TransformBuiltinMethods(EnvTransform):
key=ExprNodes.IdentifierStringNode(pos, value=var), key=ExprNodes.IdentifierStringNode(pos, value=var),
value=ExprNodes.NameNode(pos, name=var)) for var in lenv.entries] value=ExprNodes.NameNode(pos, name=var)) for var in lenv.entries]
return ExprNodes.DictNode(pos, key_value_pairs=items) 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 return node
...@@ -1168,7 +1168,6 @@ modifiers_and_name_to_type = { ...@@ -1168,7 +1168,6 @@ modifiers_and_name_to_type = {
(1, 0, "int"): c_int_type, (1, 0, "int"): c_int_type,
(1, 1, "int"): c_long_type, (1, 1, "int"): c_long_type,
(1, 2, "int"): c_longlong_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, "Py_ssize_t"): c_py_ssize_t_type,
(1, 0, "float"): c_float_type, (1, 0, "float"): c_float_type,
(1, 0, "double"): c_double_type, (1, 0, "double"): c_double_type,
...@@ -1181,6 +1180,9 @@ modifiers_and_name_to_type = { ...@@ -1181,6 +1180,9 @@ modifiers_and_name_to_type = {
(2, 1, "int"): c_slong_type, (2, 1, "int"): c_slong_type,
(2, 2, "int"): c_slonglong_type, (2, 2, "int"): c_slonglong_type,
(2, 0, "Py_ssize_t"): c_py_ssize_t_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): def widest_numeric_type(type1, type2):
......
compiled = False
def empty_decorator(x): def empty_decorator(x):
return x return x
...@@ -8,6 +10,10 @@ def cast(type, arg): ...@@ -8,6 +10,10 @@ def cast(type, arg):
# can/should we emulate anything here? # can/should we emulate anything here?
return arg return arg
def sizeof(arg):
# can/should we emulate anything here?
return 1
py_int = int py_int = int
py_long = long py_long = long
py_float = float py_float = float
......
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