From 2b37b2a4fb120cd31dcc125291a27b4548b06046 Mon Sep 17 00:00:00 2001 From: timv Date: Wed, 12 Dec 2012 15:00:26 -0500 Subject: [PATCH] Put "call" indirection table and aggregator definitions in defn ("definitions") module. --- bin/defn.py | 78 +++++++++++++++++++++++ bin/stdlib.py | 127 +++++++++++-------------------------- src/Dyna/Backend/Python.hs | 4 +- 3 files changed, 117 insertions(+), 92 deletions(-) create mode 100644 bin/defn.py diff --git a/bin/defn.py b/bin/defn.py new file mode 100644 index 0000000..4f596d0 --- /dev/null +++ b/bin/defn.py @@ -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.gt, + '>=/2': operator.ge, + '!=/2': operator.ne, + '==/2': operator.eq, + +# '<>/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 diff --git a/bin/stdlib.py b/bin/stdlib.py index 42afa89..11073b4 100644 --- a/bin/stdlib.py +++ b/bin/stdlib.py @@ -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.gt, - '>=/2': operator.ge, - '!=/2': operator.ne, - '==/2': operator.eq, - -# '<>/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() diff --git a/src/Dyna/Backend/Python.hs b/src/Dyna/Backend/Python.hs index 02d3625..e28fd76 100644 --- a/src/Dyna/Backend/Python.hs +++ b/src/Dyna/Backend/Python.hs @@ -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) } -- 2.50.1