Cloneable buffer IndexNode (preparations for buffer inplace operators)
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 15 Aug 2008 18:00:02 +0000 (20:00 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 15 Aug 2008 18:00:02 +0000 (20:00 +0200)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py

index a1b7982e416dcd840ae3f24867cace5a2123ca63..b7e2b40645410af5a14bbc0db46dea44452e9334 100644 (file)
@@ -1369,6 +1369,10 @@ class IndexNode(ExprNode):
         # Note: This might be cleaned up by having IndexNode
         # parsed in a saner way and only construct the tuple if
         # needed.
+
+        # Note that this function must leave IndexNode in a cloneable state.
+        # For buffers, self.index is packed out on the initial analysis, and
+        # when cloning self.indices is copied.
         self.is_buffer_access = False
 
         self.base.analyse_types(env)
@@ -1379,11 +1383,16 @@ class IndexNode(ExprNode):
         skip_child_analysis = False
         buffer_access = False
         if self.base.type.is_buffer:
-            assert isinstance(self.base, NameNode)
-            if isinstance(self.index, TupleNode):
-                indices = self.index.args
+            assert hasattr(self.base, "entry") # Must be a NameNode-like node
+            if self.indices:
+                indices = self.indices
             else:
-                indices = [self.index]
+                # On cloning, indices is cloned. Otherwise, unpack index into indices
+                assert not isinstance(self.index, CloneNode)
+                if isinstance(self.index, TupleNode):
+                    indices = self.index.args
+                else:
+                    indices = [self.index]
             if len(indices) == self.base.type.ndim:
                 buffer_access = True
                 skip_child_analysis = True
@@ -1469,7 +1478,7 @@ class IndexNode(ExprNode):
 
     def generate_subexpr_evaluation_code(self, code):
         self.base.generate_evaluation_code(code)
-        if self.index is not None:
+        if not self.indices:
             self.index.generate_evaluation_code(code)
         else:
             for i in self.indices:
@@ -1477,7 +1486,7 @@ class IndexNode(ExprNode):
         
     def generate_subexpr_disposal_code(self, code):
         self.base.generate_disposal_code(code)
-        if self.index is not None:
+        if not self.indices:
             self.index.generate_disposal_code(code)
         else:
             for i in self.indices:
index f10d278dd61ba034367e8b4380d1068e7c720f75..246b7e5dfe000b4998051549c2972acd57a0a7c8 100644 (file)
@@ -2555,11 +2555,29 @@ class InPlaceAssignmentNode(AssignmentNode):
         self.dup = self.lhs
         self.dup.analyse_types(env)
         if isinstance(self.lhs, ExprNodes.NameNode):
-            target_lhs = ExprNodes.NameNode(self.dup.pos, name = self.dup.name, is_temp = self.dup.is_temp, entry = self.dup.entry)
+            target_lhs = ExprNodes.NameNode(self.dup.pos,
+                                            name = self.dup.name,
+                                            is_temp = self.dup.is_temp,
+                                            entry = self.dup.entry)
         elif isinstance(self.lhs, ExprNodes.AttributeNode):
-            target_lhs = ExprNodes.AttributeNode(self.dup.pos, obj = ExprNodes.CloneNode(self.lhs.obj), attribute = self.dup.attribute, is_temp = self.dup.is_temp)
+            target_lhs = ExprNodes.AttributeNode(self.dup.pos,
+                                                 obj = ExprNodes.CloneNode(self.lhs.obj),
+                                                 attribute = self.dup.attribute,
+                                                 is_temp = self.dup.is_temp)
         elif isinstance(self.lhs, ExprNodes.IndexNode):
-            target_lhs = ExprNodes.IndexNode(self.dup.pos, base = ExprNodes.CloneNode(self.dup.base), index = ExprNodes.CloneNode(self.lhs.index), is_temp = self.dup.is_temp)
+            if self.lhs.index:
+                index = ExprNodes.CloneNode(self.lhs.index)
+            else:
+                index = None
+            if self.lhs.indices:
+                indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
+            else:
+                indices = []
+            target_lhs = ExprNodes.IndexNode(self.dup.pos,
+                                             base = ExprNodes.CloneNode(self.dup.base),
+                                             index = index,
+                                             indices = indices,
+                                             is_temp = self.dup.is_temp)
         self.lhs = target_lhs
         return self.dup