Improvements to TempsBlockNode interface
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Thu, 25 Sep 2008 21:33:10 +0000 (23:33 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Thu, 25 Sep 2008 21:33:10 +0000 (23:33 +0200)
Cython/CodeWriter.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/TreeFragment.py
Cython/Compiler/UtilNodes.py

index cbe91aaba254fa6d9257e5ebf3f12d4a03132a2c..7bfea536fdf6d90d6e03437beb707e0b6dd6abc6 100644 (file)
@@ -314,7 +314,7 @@ class CodeWriter(TreeVisitor):
         of the temporary which that block allocates.
         """
         idx = 0
-        for handle in node.handles:
+        for handle in node.temps:
             self.tempnames[handle] = "$%d_%d" % (self.tempblockindex, idx)
             idx += 1
         self.tempblockindex += 1
index ffd136de1c599430466aedbc0a865de19536077a..4d05361fab332853b8485f2203301df3c008fba1 100644 (file)
@@ -433,29 +433,28 @@ class WithTransform(CythonTransform):
     pipeline=[NormalizeTree(None)])
 
     def visit_WithStatNode(self, node):
-        excinfo_tempblock = TempsBlockNode(node.pos, [PyrexTypes.py_object_type], None)
+        excinfo_temp = TempHandle(PyrexTypes.py_object_type)
         if node.target is not None:
             result = self.template_with_target.substitute({
                 u'EXPR' : node.manager,
                 u'BODY' : node.body,
                 u'TARGET' : node.target,
-                u'EXCINFO' : excinfo_tempblock.new_ref_node(0, node.pos)
+                u'EXCINFO' : excinfo_temp.ref(node.pos)
                 }, pos=node.pos)
             # Set except excinfo target to EXCINFO
             result.body.stats[4].body.stats[0].except_clauses[0].excinfo_target = (
-             excinfo_tempblock.new_ref_node(0, node.pos))
+                excinfo_temp.ref(node.pos))
         else:
             result = self.template_without_target.substitute({
                 u'EXPR' : node.manager,
                 u'BODY' : node.body,
-                u'EXCINFO' : excinfo_tempblock.new_ref_node(0, node.pos)
+                u'EXCINFO' : excinfo_temp.ref(node.pos)
                 }, pos=node.pos)
             # Set except excinfo target to EXCINFO
             result.body.stats[4].body.stats[0].except_clauses[0].excinfo_target = (
-                excinfo_tempblock.new_ref_node(0, node.pos))
+                excinfo_temp.ref(node.pos))
 
-        excinfo_tempblock.body = result
-        return excinfo_tempblock
+        return TempsBlockNode(node.pos, temps=[excinfo_temp], body=result)
 
 class DecoratorTransform(CythonTransform):
 
index fcbc81e055d5ad49dd9e640198c633f2a2b7be92..d1b1d574e8220f4dab70dffec3f691b3bb19d991 100644 (file)
@@ -113,17 +113,19 @@ class TemplateTransform(VisitorTransform):
     def __call__(self, node, substitutions, temps, pos):
         self.substitutions = substitutions
         self.pos = pos
-
-
-        self.temps = temps
-        if len(temps) > 0:
-            self.tempblock = UtilNodes.TempsBlockNode(self.get_pos(node),
-                                                      [PyrexTypes.py_object_type for x in temps],
-                                                      body=None)
-            self.tempblock.body = super(TemplateTransform, self).__call__(node)
-            return self.tempblock
-        else:
-            return super(TemplateTransform, self).__call__(node)
+        tempmap = {}
+        temphandles = []
+        for temp in temps:
+            handle = UtilNodes.TempHandle(PyrexTypes.py_object_type)
+            tempmap[temp] = handle
+            temphandles.append(handle)
+        self.tempmap = tempmap
+        result = super(TemplateTransform, self).__call__(node)
+        if temps:
+            result = UtilNodes.TempsBlockNode(self.get_pos(node),
+                                              temps=temphandles,
+                                              body=result)
+        return result
 
     def get_pos(self, node):
         if self.pos:
@@ -150,15 +152,13 @@ class TemplateTransform(VisitorTransform):
         else:
             return self.visit_Node(node) # make copy as usual
             
-    
     def visit_NameNode(self, node):
-        try:
-            tmpidx = self.temps.index(node.name)
-        except:
-            return self.try_substitution(node, node.name)
-        else:
+        temphandle = self.tempmap.get(node.name)
+        if temphandle:
             # Replace name with temporary
-            return self.tempblock.new_ref_node(tmpidx, self.get_pos(node))
+            return temphandle.ref(self.get_pos(node))
+        else:
+            return self.try_substitution(node, node.name)
 
     def visit_ExprStatNode(self, node):
         # If an expression-as-statement consists of only a replaceable
index 9a217ea7e15885e52741c405bef8f6d62c5c838e..7a624fb5e9b035e4a652ee38ccc33bfd8e926911 100644 (file)
@@ -14,6 +14,9 @@ class TempHandle(object):
     def __init__(self, type):
         self.type = type
 
+    def ref(self, pos):
+        return TempRefNode(pos, handle=self, type=self.type)
+
 class TempRefNode(ExprNode):
     # handle   TempHandle
     subexprs = []
@@ -52,29 +55,17 @@ class TempsBlockNode(Node):
     The variables can be referred to using a TempRefNode
     (which can be constructed by calling get_ref_node).
     """
-    child_attrs = ["body"]
-
-    def __init__(self, pos, types, body):
-        self.handles = [TempHandle(t) for t in types]
-        Node.__init__(self, pos, body=body)
 
-    def new_ref_node(self, index, pos):
-        handle = self.handles[index]
-        return TempRefNode(pos, handle=handle, type=handle.type)
-
-    def append_temp(self, type, pos):
-        """
-        Appends a new temporary which this block manages, and returns
-        its index.
-        """
-        self.handle.append(TempHandle(type))
-        return len(self.handle) - 1
+    # temps   [TempHandle]
+    # body    StatNode
+    
+    child_attrs = ["body"]
 
     def generate_execution_code(self, code):
-        for handle in self.handles:
+        for handle in self.temps:
             handle.temp = code.funcstate.allocate_temp(handle.type)
         self.body.generate_execution_code(code)
-        for handle in self.handles:
+        for handle in self.temps:
             code.funcstate.release_temp(handle.temp)
 
     def analyse_control_flow(self, env):