[Checkins] SVN: z3c.pt/trunk/ Added a second variation of the repeat clause, using a simple for loop. It doesn't support the repeatdict, though and is therefor not used yet. Also began work to add introspection facilities to clauses about the variables being used in them.

Hanno Schlichting plone at hannosch.info
Sun Jul 6 05:37:43 EDT 2008


Log message for revision 88061:
  Added a second variation of the repeat clause, using a simple for loop. It doesn't support the repeatdict, though and is therefor not used yet. Also began work to add introspection facilities to clauses about the variables being used in them.
  The simpler loop causes the benchmarks to go up to a 10.5 (old 9.5) for path expressions and 14.5 (12.5) for python expressions. So the next step is to introduce an optimization phase, that can decide which variant of the loops to use.
  

Changed:
  U   z3c.pt/trunk/docs/HISTORY.txt
  U   z3c.pt/trunk/src/z3c/pt/clauses.py
  U   z3c.pt/trunk/src/z3c/pt/translation.txt

-=-
Modified: z3c.pt/trunk/docs/HISTORY.txt
===================================================================
--- z3c.pt/trunk/docs/HISTORY.txt	2008-07-06 06:40:13 UTC (rev 88060)
+++ z3c.pt/trunk/docs/HISTORY.txt	2008-07-06 09:37:42 UTC (rev 88061)
@@ -4,6 +4,14 @@
 Version 0.8.x
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+- Added a second variation of the repeat clause, using a simple for loop. It
+  doesn't support the repeatdict, though and is therefor not used yet. Also
+  began work to add introspection facilities to clauses about the variables
+  being used in them. The simpler loop causes the benchmarks to go up to a
+  10.5 (old 9.5) for path expressions and 14.5 (12.5) for python expressions.
+  So the next step is to introduce an optimization phase, that can decide
+  which variant of the loops to use.
+
 - Made the debug mode independent from the Python debug mode. You can now
   specify an environment variable called `Z3C_PT_DEBUG` to enable it.
 

Modified: z3c.pt/trunk/src/z3c/pt/clauses.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/clauses.py	2008-07-06 06:40:13 UTC (rev 88060)
+++ z3c.pt/trunk/src/z3c/pt/clauses.py	2008-07-06 09:37:42 UTC (rev 88061)
@@ -146,7 +146,10 @@
         
     def end(self, stream):
         pass
-        
+
+    def uses_variable(self, var):
+        return var in repr(self.parts)
+
 class Define(object):
     """
       >>> from z3c.pt.generation import CodeIO; stream = CodeIO()
@@ -294,6 +297,9 @@
                 else:
                     stream.write("del %s" % var)
 
+    def uses_variable(self, var):
+        return self.assign.uses_variable(var)
+
 class Condition(object):
     """
       >>> from z3c.pt.generation import CodeIO
@@ -378,6 +384,9 @@
             stream.outdent()
         self.assign.end(stream)
 
+    def uses_variable(self, var):
+        return self.assign.uses_variable(var)
+
 class Else(object):
     def __init__(self, clauses=None):
         self.clauses = clauses
@@ -396,6 +405,9 @@
         if not self.clauses:
             stream.outdent()
 
+    def uses_variable(self, var):
+        return False
+
 class Group(object):
     def __init__(self, clauses):
         self.clauses = clauses
@@ -405,10 +417,13 @@
             clause.begin(stream)
         for clause in reversed(self.clauses):
             clause.end(stream)
-        
+
     def end(self, stream):
         pass
-    
+
+    def uses_variable(self, var):
+        return False
+
 class Tag(object):
     """
       >>> from z3c.pt.generation import CodeIO
@@ -517,6 +532,14 @@
         if not self.selfclosing:
             stream.out('</%s>' % self.tag)
 
+    def uses_variable(self, var):
+        values = self.attributes.values()
+        for value in values:
+            if isinstance(value, types.expression):
+                if var in repr(value):
+                    return True
+        return False
+
 class Repeat(object):
     """
       >>> from z3c.pt.generation import CodeIO
@@ -544,55 +567,82 @@
       >>> _repeat.end(stream)
 
     A repeat over an empty set.
-    
+
       >>> stream = CodeIO()
       >>> _repeat = Repeat("j", pyexp("range(0)"))
       >>> _repeat.begin(stream)
       >>> _repeat.end(stream)
       >>> exec stream.getvalue()
 
+    Simple for loop:
+
+      >>> stream = CodeIO()
+      >>> _for = Repeat("i", pyexp("range(3)"), repeatdict=False)
+      >>> _for.begin(stream)
+      >>> stream.write("print i")
+      >>> _for.end(stream)
+      >>> exec stream.getvalue()
+      0
+      1
+      2
+      >>> _for.end(stream)
+
     """
-        
-    def __init__(self, v, e, scope=()):
+
+    def __init__(self, v, e, scope=(), repeatdict=True):
         self.variable = v
+        self.expression = e
         self.define = Define(v, types.value("None"))
         self.assign = Assign(e)
+        self.repeatdict = repeatdict
 
     def begin(self, stream):
         variable = self.variable
-        iterator = stream.save()
 
-        # assign iterator
-        self.assign.begin(stream, iterator)
+        if self.repeatdict:
+            iterator = stream.save()
 
-        # initialize variable scope
-        self.define.begin(stream)
+            # assign iterator
+            self.assign.begin(stream, iterator)
 
-        # initialize iterator
-        stream.write("%s = repeat.insert('%s', %s)" % (iterator, variable, iterator))
-        
-        # loop
-        stream.write("try:")
-        stream.indent()
-        stream.write("while True:")
-        stream.indent()
-        stream.write("%s = %s.next()" % (variable, iterator))
-        
+            # initialize variable scope
+            self.define.begin(stream)
+
+            # initialize iterator
+            stream.write("%s = repeat.insert('%s', %s)" % (
+                iterator, variable, iterator))
+
+            # loop
+            stream.write("try:")
+            stream.indent()
+            stream.write("while True:")
+            stream.indent()
+            stream.write("%s = %s.next()" % (variable, iterator))
+        else:
+            stream.write("for %s in %s:" % (variable, self.expression))
+            stream.indent()
+
     def end(self, stream):
         # cook before leaving loop
         stream.cook()
-        
         stream.outdent()
-        stream.outdent()
-        stream.write("except StopIteration:")
-        stream.indent()
-        stream.write("pass")
-        stream.outdent()
-        
-        self.define.end(stream)
-        self.assign.end(stream)
-        stream.restore()
 
+        if self.repeatdict:
+            stream.outdent()
+            stream.write("except StopIteration:")
+            stream.indent()
+            stream.write("pass")
+            stream.outdent()
+
+            self.define.end(stream)
+            self.assign.end(stream)
+            stream.restore()
+
+    def uses_variable(self, var):
+        if var in (self.variable, 'repeat'):
+            return True
+        return False
+
 class Write(object):
     """
     >>> from z3c.pt.generation import CodeIO
@@ -678,6 +728,11 @@
             self.assign.end(stream)
         stream.restore()
 
+    def uses_variable(self, var):
+        if self.assign:
+            return self.assign.uses_variable(var)
+        return False
+
 class UnicodeWrite(Write):
     """
     >>> from z3c.pt.generation import CodeIO
@@ -752,6 +807,9 @@
         if self.defer:
             stream.out(self.string)
 
+    def uses_variable(self, var):
+        return False
+
 class Translate(object):
     """
     The translate clause works retrospectively.
@@ -762,3 +820,6 @@
 
     def end(self, stream):
         raise
+
+    def uses_variable(self, var):
+        return False

Modified: z3c.pt/trunk/src/z3c/pt/translation.txt
===================================================================
--- z3c.pt/trunk/src/z3c/pt/translation.txt	2008-07-06 06:40:13 UTC (rev 88060)
+++ z3c.pt/trunk/src/z3c/pt/translation.txt	2008-07-06 09:37:42 UTC (rev 88061)
@@ -56,6 +56,23 @@
   ... <div xmlns="http://www.w3.org/1999/xhtml"
   ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
   ...   <ul>
+  ...     <li tal:repeat="i range(5)"><span tal:replace="str(i) + ' ' + str(repeat['i'].even())" /></li>
+  ...   </ul>
+  ... </div>""", translate_xml)
+    <div>
+      <ul>
+        <li>0 True</li>
+        <li>1 False</li>
+        <li>2 True</li>
+        <li>3 False</li>
+        <li>4 True</li>
+      </ul>
+    </div>
+
+  >>> print render("""\
+  ... <div xmlns="http://www.w3.org/1999/xhtml"
+  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
+  ...   <ul>
   ...     <li tal:repeat="i range(5)"><span tal:replace="'Item ' + str(i) + ')'" /></li>
   ...   </ul>
   ... </div>""", translate_xml)



More information about the Checkins mailing list