changeset 328:f013a84050ac experimental-compiler

better system for def's to work; doing a little benchmarking.
author zzzeek
date Sun, 05 Nov 2006 01:25:43 +0000
parents c72243905470
children d81532240de7
files genshi/codegen/generator.py genshi/codegen/interp.py genshi/codegen/tests/test_generator.py
diffstat 3 files changed, 36 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/codegen/generator.py
+++ b/genshi/codegen/generator.py
@@ -72,6 +72,7 @@
     __directive__ = template.DefDirective
     def produce_directive(self, gencontext, directive, event, substream):
         sig = directive.signature
+        gencontext.defs.add(directive.name)
         if not re.search(r'\(.*\)$', sig):
             gencontext.defs_without_params.add(sig)
             sig += '()'
@@ -128,6 +129,7 @@
         self.stream = stream
         self.serializer = serializer
         self.defs_without_params = sets.Set()
+        self.defs = sets.Set()
     def generate(self):
         for evt in self.start():
             yield evt
@@ -183,6 +185,7 @@
             "from genshi.core import START, END, START_NS, END_NS, TEXT, COMMENT, DOCTYPE, QName, Stream",
             "from genshi.template import Context, Template",
             "from genshi.path import Path",
+            "from genshi.codegen import interp",
             "EXPR = Template.EXPR"
         ]:
             yield (PYTHON_LINE, line)
@@ -216,10 +219,12 @@
         if expr is None:
             expr = event[1]
         if expr.source in self.defs_without_params:
-            yield (PYTHON_LINE, "_expr = %s()" % (expr.source))
+            yield (PYTHON_LINE, "for _evt in interp.evaluate(%s(), %s):" % (expr.source, repr(event[2])))
         else:
-            yield (PYTHON_LINE, "_expr = %s" % (expr.source))
-        yield (PYTHON_LINE, "yield (EXPR, _expr, %s, unicode(_expr))" % (repr(event[2])))
+            yield (PYTHON_LINE, "for _evt in interp.evaluate(%s, %s):" % (expr.source, repr(event[2])))
+        yield (PYTHON_LINE, "yield _evt")
+        yield (PYTHON_LINE, "")
+        
     def produce_text_event(self, event):
         yield (PYTHON_LINE, "yield (TEXT, (%s), %s, %s)" % (
             repr(unicode(event[1])),
--- a/genshi/codegen/interp.py
+++ b/genshi/codegen/interp.py
@@ -72,6 +72,16 @@
         else:
             yield event
 
+def evaluate(result, pos):
+    if result is not None:
+        if isinstance(result, basestring):
+            yield TEXT, result, pos, result
+        elif hasattr(result, '__iter__'):
+            for event in result:
+                yield event
+        else:
+            yield TEXT, unicode(result), pos, result
+
 def run_inlined(module, data):
     context = Context(**data)
     for item in _match(module.go(context), context):
--- a/genshi/codegen/tests/test_generator.py
+++ b/genshi/codegen/tests/test_generator.py
@@ -15,6 +15,7 @@
 from genshi.output import HTMLSerializer
 from genshi.codegen import generator, interp
 from genshi.codegen.serialize import HTMLSerializeFilter
+import time, sys
 
 text = """<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
@@ -27,7 +28,7 @@
     <div py:for="item in items()">
         ${lala + 'hi'}
         <div py:for="x in foo">
-        i am a greeting, ${item}
+        i am a greeting, ${item}, ${x}
         
         now heres replace
         <span py:replace="item">Hey Ho</span>
@@ -54,6 +55,8 @@
 data = {'lala':'hi', 'items':items, 'foo':['f1', 'f2', 'f3']}
     
 t = MarkupTemplate(text)
+print u''.join(HTMLSerializer()(t.generate(**data)))
+
 g = generator.Generator(t)
 pycode =  u''.join(g.generate_stream(HTMLSerializeFilter()))
 print pycode
@@ -62,3 +65,17 @@
 module = g.generate_module(HTMLSerializeFilter())
 print u''.join(interp.run_inlined(module, data))
 
+print "Running MarkupTemplate.generate()/HTMLSerializer..."
+now = time.time()
+for x in range(1,1000):
+    stream = t.generate(**data)
+    serializer = HTMLSerializer()
+    list(serializer(stream))
+print "MarkupTemplate.generate()/HTMLSerializer totaltime: %f" % (time.time() - now)
+
+# inline
+print "Running inlined module..."
+now = time.time()
+for x in range(1,1000):
+    list(interp.run_inlined(module, data))
+print "Inlined module totaltime: %f" % (time.time() - now)
Copyright (C) 2012-2017 Edgewall Software