some profiler guided streamlining in compiler output writers
authorStefan Behnel <scoder@users.berlios.de>
Sat, 20 Dec 2008 18:10:23 +0000 (19:10 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Sat, 20 Dec 2008 18:10:23 +0000 (19:10 +0100)
Cython/Compiler/Code.py
Cython/Compiler/Nodes.py
Cython/StringIOTree.py

index d173acaf766b44ffdca19aa5dc79d4d500ec3169..0204e9959fad4634e6fa3cd916af4e779620d2f7 100644 (file)
@@ -603,12 +603,18 @@ class CCodeWriter(object):
 
     def put(self, code):
         fix_indent = False
-        dl = code.count("{") - code.count("}")
-        if dl < 0:
-            self.level += dl
-        elif dl == 0 and code.startswith('}'):
-            fix_indent = True
-            self.level -= 1
+        if "{" in code:
+            dl = code.count("{")
+        else:
+            dl = 0
+        if "}" in code:
+            dl -= code.count("}")
+            if dl < 0:
+                self.level += dl
+            elif dl == 0 and code[0] == "}":
+                # special cases like "} else {" need a temporary dedent
+                fix_indent = True
+                self.level -= 1
         if self.bol:
             self.indent()
         self.write(code)
index 633e1aae662cfdb4715b338d0ee03911fe031d07..dc0255b4c767b61ae8c25e76e7a1e34a9b26db15 100644 (file)
@@ -156,12 +156,13 @@ class Node(object):
             self.body.annotate(code)
             
     def end_pos(self):
-        if not self.child_attrs:
-            return self.pos
         try:
             return self._end_pos
         except AttributeError:
             pos = self.pos
+            if not self.child_attrs:
+                self._end_pos = pos
+                return pos
             for attr in self.child_attrs:
                 child = getattr(self, attr)
                 # Sometimes lists, sometimes nodes
index 5d07a5c8faa8966d64c4977ae2b40e98e5e271ee..b702cfbf266c02867a72ca1db9c433884c3d21fd 100644 (file)
@@ -7,31 +7,32 @@ class StringIOTree(object):
 
     def __init__(self, stream=None):
         self.prepended_children = []
-        self.stream = stream # if set to None, it will be constructed on first write
+        if stream is None:
+            stream = StringIO()
+        self.stream = stream
+        self.write = stream.write
 
     def getvalue(self):
-        return ("".join([x.getvalue() for x in self.prepended_children]) +
-                self.stream.getvalue())
+        content = [x.getvalue() for x in self.prepended_children]
+        content.append(self.stream.getvalue())
+        return "".join(content)
 
     def copyto(self, target):
         """Potentially cheaper than getvalue as no string concatenation
         needs to happen."""
         for child in self.prepended_children:
             child.copyto(target)
-        if self.stream:
-            target.write(self.stream.getvalue())
-
-    def write(self, what):
-        if not self.stream:
-            self.stream = StringIO()
-        self.stream.write(what)
+        stream_content = self.stream.getvalue()
+        if stream_content:
+            target.write(stream_content)
 
     def commit(self):
         # Save what we have written until now so that the buffer
         # itself is empty -- this makes it ready for insertion
-        if self.stream:
+        if self.stream.tell():
             self.prepended_children.append(StringIOTree(self.stream))
-            self.stream = None
+            self.stream = StringIO()
+            self.write = self.stream.write
 
     def insert(self, iotree):
         """
@@ -87,4 +88,4 @@ EXAMPLE:
 >>> a.copyto(out)
 >>> out.getvalue().split()
 ['first', 'second', 'alpha', 'inserted', 'beta', 'gamma', 'third']
-"""
\ No newline at end of file
+"""