webbrowser.open(html.name)
-def hypergraph(interpreter):
- # collect edges
- interpreter.collect_edges()
- # create hypergraph object
- g = Hypergraph()
- for c in interpreter.chart.values():
- for x in c.intern.values():
- for e in interpreter.edges[x]:
- label, body = e
- g.edge(str(x), str(label), map(str, body))
- return g
-
-
-def draw(interpreter):
- g = hypergraph(interpreter)
- with file('/tmp/state.html', 'wb') as f:
- print >> f, """
- <html>
- <head>
- <style>
- body {
- background-color: black;
- color: white;
- }
- </style>
- </head>
- <body>
- """
-
- x = StringIO()
- interpreter.dump_charts(x)
-
- print >> f, '<div style="position:absolute;">%s</div>' \
- % '<h1>Charts</h1>%s' \
- % '<pre style="width: 500px;">%s</pre>' \
- % x.getvalue()
-
- print >> f, """
- <div style="width: 800px; position:absolute; left: 550px">
- <h1>Hypergraph</h1>
- %s
- </div>
- """ % g.render('/tmp/hypergraph')
-
- print >> f, '</body></html>'
-
- webbrowser.open(f.name)
-
-
if __name__ == '__main__':
from argparse import ArgumentParser
--- /dev/null
+"""
+Crude visualization of circuit pertaining to state of the interpreter.
+"""
+
+import webbrowser
+from debug import Hypergraph
+from cStringIO import StringIO
+
+def circuit(edges):
+ # create hypergraph object
+ g = Hypergraph()
+ for e in edges:
+ head, label, body = e
+ g.edge(str(head), str(label), map(str, body))
+ return g
+
+
+def infer_edges(interp):
+ edges = set()
+
+ # Use rule initializers to find all active hyperedges in the current Chart.
+ def _emit(item, _, ruleix, variables):
+ b = variables['nodes']
+ b.sort()
+ b = tuple(b)
+ edges.add((item, ruleix, b))
+
+ for r in interp.rules.values():
+ r.init(emit=_emit)
+
+ return edges
+
+
+def main(interp):
+ es = infer_edges(interp)
+ c = circuit(es)
+
+ with file('/tmp/state.html', 'wb') as f:
+ print >> f, """
+ <html>
+ <head>
+ <style>
+ body {
+ background-color: black;
+ color: white;
+ }
+ </style>
+ </head>
+ <body>
+ """
+
+ x = StringIO()
+ interp.dump_charts(x)
+
+ print >> f, '<div style="position:absolute;">%s</div>' \
+ % '<h1>Charts</h1>%s' \
+ % '<pre style="width: 500px;">%s</pre>' \
+ % x.getvalue()
+
+ print >> f, """
+ <div style="width: 800px; position:absolute; left: 550px">
+ <h1>Hypergraph</h1>
+ %s
+ </div>
+ """ % c.render('circuit')
+
+ print >> f, '</body></html>'
+
+ webbrowser.open(f.name)
"""
from __future__ import division
-import os, sys, imp
+import os, sys, imp, argparse
from collections import defaultdict
-from argparse import ArgumentParser
from hashlib import sha1
def __init__(self):
# declarations
self.agg_name = defaultdict(none)
- self.edges = defaultdict(set) # TODO: finding HG should be a post-processor
self.updaters = defaultdict(list)
# data structures
self.agenda = prioritydict()
self.chart = foo(self.agg_name)
self.rules = ddict(Rule)
- self.errors = {}
+ self.error = {}
def __getstate__(self):
return ((self.chart,
self.agenda,
- self.errors,
+ self.error,
self.agg_name,
self.parser_state),
'\n'.join(self.rules[i].src for i in sorted(self.rules)))
def __setstate__(self, state):
- ((self.chart, self.agenda, self.errors, self.agg_name, self.parser_state), code) = state
+ ((self.chart, self.agenda, self.error, self.agg_name, self.parser_state), code) = state
self.edges = defaultdict(set)
self.updaters = defaultdict(list)
self.rules = ddict(Rule)
assert self.agg_name[fn] == agg, (fn, self.agg_name[fn], agg)
- def collect_edges(self):
- """
- Use rule initializers to find all active hyperedges in the current
- Chart.
- """
- edges = self.edges
- def _emit(item, _, ruleix, variables):
- b = variables['nodes']
- b.sort()
- b = tuple(b)
- edges[item].add((ruleix, b))
- for r in self.rules.values():
- r.init(emit=_emit)
-
def dump_charts(self, out=sys.stdout):
print >> out
print >> out, 'Charts'
def dump_errors(self, out=sys.stdout):
# We only dump the error chart if it's non empty.
- if not self.errors:
+ if not self.error:
return
print >> out
print >> out, 'Errors'
print >> out, '============'
- for item, (val, es) in self.errors.items():
+ for item, (val, es) in self.error.items():
print >> out, 'because %r is %s:' % (item, _repr(val))
for e, h in es:
if h is not None:
"the main loop"
changed = {}
agenda = self.agenda
- errors = self.errors
+ error = self.error
while agenda:
item = agenda.pop_smallest()
was = item.value
try:
now = item.aggregator.fold()
except (ZeroDivisionError, TypeError, KeyboardInterrupt, NotImplementedError) as e:
- errors[item] = ('failed to aggregate %r' % item.aggregator, [(e, None)])
+ error[item] = ('failed to aggregate %r' % item.aggregator, [(e, None)])
continue
if was == now:
continue
was_error = False
- if item in errors: # clear error
+ if item in error: # clear error
was_error = True
- del errors[item]
+ del error[item]
# TODO: handle `was` and `now` at the same time to avoid the two passes.
# TODO: will need to propagate was=None when we have question mark
if was is not None and not was_error:
t_emit = lambda item, val, ruleix, variables: \
emittiers.append((item, val, ruleix, variables, delete))
- errors = []
+ error = []
for handler in self.updaters[item.fn]:
try:
handler(item, val, emit=t_emit)
except (TypeError, ZeroDivisionError, KeyboardInterrupt, OverflowError) as e:
- errors.append((e, handler))
+ error.append((e, handler))
- if errors:
- self.errors[item] = (val, errors)
+ if error:
+ self.error[item] = (val, error)
return
# no exception, accept emissions.
else:
- # TODO: how do I make this transactional? what it the user hits ^C
+ # TODO: how do I make this transactional? what if the user hits ^C
# in the middle of the following blocK?
#
# - maybe transaction isn't want I mean. Maybe all I want (for now
return self.go()
- def draw(self):
- debug.draw(self)
-
def dynac_code(self, code):
"""
Compile a string of dyna code.
def main():
-
- parser = ArgumentParser(description="The dyna interpreter!")
- parser.add_argument('source', help='Path to Dyna source file (or plan if --plan=true).', nargs='?')
- parser.add_argument('--plan', action='store_true', default=False,
+ parser = argparse.ArgumentParser(description="The dyna interpreter!")
+ parser.add_argument('source',
+ help='Path to Dyna source file (or plan if --plan=true).', nargs='?')
+ parser.add_argument('--plan', action='store_true',
help='`source` specifies output of the compiler instead of dyna source code.')
- parser.add_argument('-i', dest='interactive', action='store_true', help='Fire-up an IPython shell.')
- parser.add_argument('-o', dest='output', help='Output chart.')
- parser.add_argument('--draw', action='store_true',
- help='Output html page with hypergraph and chart.')
- parser.add_argument('--post-process', help='run post-processing script.')
-
+ parser.add_argument('-i', dest='interactive', action='store_true',
+ help='Fire-up an IPython shell.')
+ parser.add_argument('-o', dest='output',
+ type=argparse.FileType('wb'),
+ help='Output chart.')
+ parser.add_argument('--post-process',
+ help='run post-processing script.')
parser.add_argument('--profile', action='store_true',
help='run profiler.')
enable_crash_handler()
-
if args.profile:
# When profiling, its common practice to disable the garbage collector.
import gc
interp.do(plan)
- if args.output:
- if args.output == "-":
- interp.dump_charts(sys.stdout)
- else:
- with file(args.output, 'wb') as f:
- interp.dump_charts(f)
- else:
- interp.dump_charts()
+ interp.dump_charts(args.output)
if args.interactive:
interp.repl(hist = args.source + '.hist')
else:
interp.repl()
- if args.draw:
- interp.draw()
-
if args.post_process is not None:
pp.main(interp)