]> hydra-www.ietfng.org Git - dyna2/commitdiff
Put "call" indirection table and aggregator definitions in defn ("definitions")
authortimv <tim.f.vieira@gmail.com>
Wed, 12 Dec 2012 20:00:26 +0000 (15:00 -0500)
committertimv <tim.f.vieira@gmail.com>
Wed, 12 Dec 2012 20:00:26 +0000 (15:00 -0500)
module.

bin/defn.py [new file with mode: 0644]
bin/stdlib.py
src/Dyna/Backend/Python.hs

diff --git a/bin/defn.py b/bin/defn.py
new file mode 100644 (file)
index 0000000..4f596d0
--- /dev/null
@@ -0,0 +1,78 @@
+import math, operator
+
+# Call indirection tables defines mathematical operators and the like.
+call = {'*/2': operator.mul,
+        '//2': operator.div,
+        '-/2': operator.sub,
+        '+/2': operator.add,
+
+        '-/1': operator.neg,
+
+#        '~/1': operator.inv,   # differs
+#        '|/1': operator.or_,
+#        '&/2': operator.and_,
+
+        # comparisons
+        '</2': operator.lt,
+        '<=/2': operator.le,
+        '>/2': operator.gt,
+        '>=/2': operator.ge,
+        '!=/2': operator.ne,
+        '==/2': operator.eq,
+
+#        '<</2': operator.lshift,
+#        '>>/2': operator.rshift,
+
+        'mod/1': operator.mod,
+        'abs/1': operator.abs,
+        'log': math.log,
+        'exp': math.exp,
+
+        '**/2': math.pow,
+        '^/2': math.pow}   # differs from python
+
+
+def agg_bind(agg_decl, table):
+    """
+    Bind declarations (map functor->string) to table (storing values) and
+    aggregator definition (the fold funciton, which gets executed).
+    """
+
+    def max_equals(item):
+        return max(k for k, m in table[item].iteritems() if m > 0)
+
+    def min_equals(item):
+        return min(k for k, m in table[item].iteritems() if m > 0)
+
+    def plus_equals(item):
+        return reduce(operator.add,
+                      [k*m for k, m in table[item].iteritems()])
+
+    def times_equals(item):
+        return reduce(operator.mul,
+                      [k**m for k, m in table[item].iteritems()])
+
+    def and_equals(item):
+        return reduce(operator.and_,
+                      [k for k, m in table[item].iteritems() if m > 0])
+
+    def or_equals(item):
+        return reduce(operator.or_,
+                      [k for k, m in table[item].iteritems() if m > 0])
+
+    # map names to functions
+    agg_defs = {
+        'max=': max_equals,
+        'min=': min_equals,
+        '+=': plus_equals,
+        '*=': times_equals,
+        '&=': and_equals,
+        '|=': or_equals,
+    }
+
+    # commit functors to an aggregator definition to avoid unnecessary lookups.
+    agg = {}
+    for fn in agg_decl:
+        agg[fn] = agg_defs[agg_decl[fn]]
+
+    return agg
index 42afa89900ca8ce859cc0a980ab011ce84498ba6..11073b4943ff2c96426a69e46ff76c6ca30e345c 100644 (file)
@@ -25,44 +25,14 @@ Call indirection
 
 """
 
-from debug import ultraTB2; ultraTB2.enable()
+#from debug import ultraTB2; ultraTB2.enable()
 #from debug import saverr; saverr.enable(editor=True)
 
-import os, sys, math, operator
+import os, sys
 from collections import defaultdict, Counter
 from utils import red, green, blue, magenta
 
-
-# Call indirection tables defines mathematical operators and the like.
-call = {'*/2': operator.mul,
-        '//2': operator.div,
-        '-/2': operator.sub,
-        '+/2': operator.add,
-
-        '-/1': operator.neg,
-
-#        '~/1': operator.inv,   # differs
-#        '|/1': operator.or_,
-#        '&/2': operator.and_,
-
-        # comparisons
-        '</2': operator.lt,
-        '<=/2': operator.le,
-        '>/2': operator.gt,
-        '>=/2': operator.ge,
-        '!=/2': operator.ne,
-        '==/2': operator.eq,
-
-#        '<</2': operator.lshift,
-#        '>>/2': operator.rshift,
-
-        'mod/1': operator.mod,
-        'abs/1': operator.abs,
-        'log': math.log,
-        'exp': math.exp,
-
-        '**/2': math.pow,
-        '^/2': math.pow}   # differs from python
+from defn import agg_bind, call
 
 
 # TODO: as soon as we have safe names for these things we can get rid of this.
@@ -254,6 +224,22 @@ def emit(item, val):
 
 
 aggregator = defaultdict(Counter)
+
+def aggregate(item):
+    (fn, _) = item
+    return agg[fn](item)   # agg is defined after updates are loaded
+
+
+def delete(item, val):
+    # XXX: very ugly handling of deletion by global variable; should probably
+    # target only handler at a time, because this will get called more times
+    # than it should.
+    global _delete
+    _delete = True
+    update_dispatcher(item, val)
+    _delete = False
+
+
 agenda = set()
 
 
@@ -283,76 +269,37 @@ def run_agenda():
         update_dispatcher(item, now)
 
 
-agg = {}
-
-def aggregate(item):
-    (fn, _) = item
-    return aggr[agg[fn]](item)
-
-
-def max_equals(item):
-    return max(k for k, m in aggregator[item].iteritems() if m > 0)
-
-def min_equals(item):
-    return min(k for k, m in aggregator[item].iteritems() if m > 0)
-
-def plus_equals(item):
-    return reduce(operator.add,
-                  [k*m for k, m in aggregator[item].iteritems()])
-
-def times_equals(item):
-    return reduce(operator.mul,
-                  [k**m for k, m in aggregator[item].iteritems()])
-
-def and_equals(item):
-    return reduce(operator.and_,
-                  [k for k, m in aggregator[item].iteritems() if m > 0])
-
-def or_equals(item):
-    return reduce(operator.or_,
-                  [k for k, m in aggregator[item].iteritems() if m > 0])
-
-
-aggr = {
-    'max=': max_equals,
-    'min=': min_equals,
-    '+=': plus_equals,
-    '*=': times_equals,
-    '&=': and_equals,
-    '|=': or_equals,
-}
-
-
-def delete(item, val):
-    # XXX: very ugly handling of deletion by global variable; should probably
-    # target only handler at a time, because this will get called more times
-    # than it should.
-    global _delete
-    _delete = True
-    update_dispatcher(item, val)
-    _delete = False
+def run():
+    try:
+        run_agenda()
+    except KeyboardInterrupt:
+        pass
+    finally:
+        dump_charts()
 
 
 # Example of reactivity
 #  >>> emit(('rewrite/3', 5), -1000)
 #  >>> run_agenda()
 
+
 [dyna] = sys.argv[1:]
 
 cmd = """ghc -isrc Dyna.Backend.Python -e 'processFile "%s"' """ % dyna
 assert 0 == os.system(cmd), 'command failed:\n\t' + cmd
 
+agg_decl = None # filled in after exec, this only here to satisfy lint checker.
+
+
 execfile(dyna + '.plan')
 
-for xxx in initializer.handlers:
-    xxx()
 
-def run():
-    try:
-        run_agenda()
-    except KeyboardInterrupt:
-        pass
-    finally:
-        dump_charts()
+# bind aggregators to definitions
+agg = agg_bind(agg_decl, aggregator)
+
+# run initializers
+for init in initializer.handlers:
+    init()
 
+# start running the agenda
 run()
index 02d36255a81e427ccea275a1c52a74ddacda5543..e28fd7648b731d5e94e64b36a123b80ca94b98ad 100644 (file)
@@ -206,9 +206,9 @@ processFile_ fileName fh = do
                    Left e -> throw $ TLEAggPlan e
                    Right x -> return x
 
-         hPutStrLn fh $ "agg = {}"
+         hPutStrLn fh $ "agg_decl = {}"
          forM (M.toList aggm) $ \((f,a),v) -> do {
-             hPutStrLn fh $ show $ "agg" <> brackets (dquotes $ pretty f <> "/" <> pretty a)
+             hPutStrLn fh $ show $ "agg_decl" <> brackets (dquotes $ pretty f <> "/" <> pretty a)
                 <+> equals <+> (dquotes $ pretty v)
            }