cython.cast, cython.sizeof, and cython.compiled for pure Python mode
authorRobert Bradshaw <robertwb@math.washington.edu>
Wed, 1 Oct 2008 18:24:30 +0000 (11:24 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Wed, 1 Oct 2008 18:24:30 +0000 (11:24 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/PyrexTypes.py
Cython/Shadow.py

index a5685b1aa9782cde67da055ff3bcf1ac5bc5c5f1..6552b67b59cb23a10ce2096fc97d01e0da9c89bc 100644 (file)
@@ -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):
index ee3d77254a2ea5a8bf586c7989bd6bcb9ca06e2e..19894538e08dc4edd243aa908a86e9c77656f151 100644 (file)
@@ -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
index 8175b7441211378e35de9f4bed109231cfe8a3e4..f0027b6b302091004e2313428541ce2deabfce9f 100644 (file)
@@ -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):
index 976e3f8e379eaf6286f1a9bc8dacd292efa70b2a..cc1f07adaa37a38cc28020ea8315c19b4cdf6711 100644 (file)
@@ -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