Type inference testing.
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 4 Oct 2009 05:37:02 +0000 (22:37 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 4 Oct 2009 05:37:02 +0000 (22:37 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/TypeInference.py
Demos/embed/main.c [deleted file]
tests/compile/cassign.pyx
tests/run/pycmp.pyx

index 7eb42ec14d5dc82a180f9f2088c949af9708f1d7..a1a36cf801373ad73a8b661c09159446efb9b5a8 100644 (file)
@@ -4245,24 +4245,29 @@ class SizeofVarNode(SizeofNode):
     def generate_result_code(self, code):
         pass
 
-class TypeofNode(StringNode):
+class TypeofNode(ExprNode):
     #  Compile-time type of an expression, as a string.
     #
     #  operand   ExprNode
+    #  literal   StringNode # internal
     
-    subexprs = ['operand']
+    literal = None
+    type = py_object_type
+    
+    subexprs = ['operand', 'literal']
     
     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
+        self.literal = StringNode(self.pos, value=EncodedString(str(self.operand.type)))
+        self.literal.analyse_types(env)
+        self.literal = self.literal.coerce_to_pyobject(env)
     
     def generate_evaluation_code(self, code):
-        self.generate_result_code(code)
+        self.literal.generate_evaluation_code(code)
+    
+    def calculate_result_code(self):
+        return self.literal.calculate_result_code()
 
 #-------------------------------------------------------------------
 #
index 82e211a42fca5fc7ab78ace9afd2df379a9ea932..1b40e84e2a7484d4ddcdb4c5a0fa90a879afc08f 100644 (file)
@@ -4,6 +4,12 @@
 
 import sys, os, time, copy
 
+try:
+    set
+except NameError:
+    # Python 2.3
+    from sets import Set as set
+
 import Code
 import Builtin
 from Errors import error, warning, InternalError
index f48544411250eb98479bae8e4df8b5e7ed7279ea..6f71360f87e76fedc26d2fe53f1949040aa9f0f1 100644 (file)
@@ -1801,10 +1801,14 @@ def widest_numeric_type(type1, type2):
 
 def spanning_type(type1, type2):
     # Return a type assignable from both type1 and type2.
-    if type1 == type2:
+    if type1 is py_object_type or type2 is py_object_type:
+        return py_object_type
+    elif type1 == type2:
         return type1
     elif type1.is_numeric and type2.is_numeric:
         return widest_numeric_type(type1, type2)
+    elif type1.is_pyobject ^ type2.is_pyobject:
+        return py_object_type
     elif type1.assignable_from(type2):
         return type1
     elif type2.assignable_from(type1):
@@ -1812,7 +1816,6 @@ def spanning_type(type1, type2):
     else:
         return py_object_type
     
-
 def simple_c_type(signed, longness, name):
     # Find type descriptor for simple type given name and modifiers.
     # Returns None if arguments don't make sense.
index 4b8763887cc186ee03f4cb5247660c20843e813d..0d9b2753b9a10cfa41adc842a2765c3320707b11 100644 (file)
@@ -50,12 +50,14 @@ class MarkAssignments(CythonTransform):
 
     def visit_ForInStatNode(self, node):
         # TODO: Remove redundancy with range optimization...
+        is_range = False
         sequence = node.iterator.sequence
         if isinstance(sequence, ExprNodes.SimpleCallNode):
             function = sequence.function
             if sequence.self is None and \
                     isinstance(function, ExprNodes.NameNode) and \
                     function.name in ('range', 'xrange'):
+                is_range = True
                 self.mark_assignment(node.target, sequence.args[0])
                 if len(sequence.args) > 1:
                     self.mark_assignment(node.target, sequence.args[1])
@@ -65,7 +67,7 @@ class MarkAssignments(CythonTransform):
                                                       '+',
                                                       sequence.args[0],
                                                       sequence.args[2]))
-        else:
+        if not is_range:
             self.mark_assignment(node.target, object_expr)
         self.visitchildren(node)
         return node
@@ -143,7 +145,7 @@ class SimpleAssignmentTypeInferer:
                         del dependancies_by_entry[entry]
                         ready_to_infer.append(entry)
         # Try to infer things in order...
-        while ready_to_infer:
+        while True:
             while ready_to_infer:
                 entry = ready_to_infer.pop()
                 types = [expr.infer_type(scope) for expr in entry.assignments]
@@ -165,6 +167,8 @@ class SimpleAssignmentTypeInferer:
                         del dependancies_by_entry[entry]
                         if ready_to_infer:
                             break
+            if not ready_to_infer:
+                break
                     
         # We can't figure out the rest with this algorithm, let them be objects.
         for entry in dependancies_by_entry:
diff --git a/Demos/embed/main.c b/Demos/embed/main.c
deleted file mode 100644 (file)
index 3e089ab..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "Python.h"
-#include "embedded.h"
-
-int main(int argc, char *argv) {
-  Py_Initialize();
-  initembedded();
-  spam();
-  Py_Finalize();
-}
index d51194708ec2a694ce506dd1970f61f20a2e3d83..e3e26089dab4b619b0c903bb8aa1f09cfd418d4b 100644 (file)
@@ -2,6 +2,7 @@ cdef void foo():
     cdef int i1, i2=0
     cdef char c1=0, c2
     cdef char *p1, *p2=NULL
+    cdef object obj1
     i1 = i2
     i1 = c1
     p1 = p2
index ec4334b575babb5571c0e8f5af0d70b4dd2003b2..a6916422baa95fc4c12a4d4fcdc2a438a6ed06b8 100644 (file)
@@ -5,6 +5,7 @@ __doc__ = u"""
 
 def f():
     cdef int bool, int1, int2
+    cdef object obj1, obj2
     int1 = 0
     int2 = 0
     obj1 = 1