From d3e42d3a22f5dabdcc59845354a9a48d7082e777 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Wed, 1 Oct 2008 11:24:30 -0700 Subject: [PATCH] cython.cast, cython.sizeof, and cython.compiled for pure Python mode --- Cython/Compiler/ExprNodes.py | 10 +++--- Cython/Compiler/ParseTreeTransforms.py | 50 +++++++++++++++++++++++++- Cython/Compiler/PyrexTypes.py | 4 ++- Cython/Shadow.py | 6 ++++ 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index a5685b1a..6552b67b 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -3166,11 +3166,12 @@ class SizeofTypeNode(SizeofNode): # 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: @@ -3182,9 +3183,10 @@ class SizeofTypeNode(SizeofNode): 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): diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index ee3d7725..19894538 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -282,6 +282,7 @@ class InterpretCompilerDirectives(CythonTransform): 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. @@ -637,8 +638,29 @@ class EnvTransform(CythonTransform): 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 @@ -647,4 +669,30 @@ class TransformBuiltinMethods(EnvTransform): 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 diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 8175b744..f0027b6b 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -1168,7 +1168,6 @@ modifiers_and_name_to_type = { (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, @@ -1181,6 +1180,9 @@ modifiers_and_name_to_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): diff --git a/Cython/Shadow.py b/Cython/Shadow.py index 976e3f8e..cc1f07ad 100644 --- a/Cython/Shadow.py +++ b/Cython/Shadow.py @@ -1,3 +1,5 @@ +compiled = False + def empty_decorator(x): return x @@ -8,6 +10,10 @@ def cast(type, arg): # can/should we emulate anything here? return arg +def sizeof(arg): + # can/should we emulate anything here? + return 1 + py_int = int py_long = long py_float = float -- 2.26.2