From 7a6123d1e4037cea474a59e2e528f27e3a9db819 Mon Sep 17 00:00:00 2001 From: Tim Vieira Date: Fri, 2 Aug 2013 10:00:16 -0400 Subject: [PATCH] Misc. - Use IPython's external dependency on path.py in order to avoid the extra dep. - Added command to REPL for pasting mulitline rules. Related to issue #22. --- src/Dyna/Backend/Python/chart.py | 2 +- src/Dyna/Backend/Python/config.py | 2 +- src/Dyna/Backend/Python/debug.py | 2 +- src/Dyna/Backend/Python/interpreter.py | 2 +- src/Dyna/Backend/Python/load/matrix.py | 3 ++- src/Dyna/Backend/Python/load/pickled.py | 3 ++- src/Dyna/Backend/Python/load/sexpr.py | 3 ++- src/Dyna/Backend/Python/load/tsv.py | 3 ++- src/Dyna/Backend/Python/main.py | 2 +- src/Dyna/Backend/Python/post/trace.py | 10 +-------- src/Dyna/Backend/Python/repl.py | 17 ++++++++++++++- src/Dyna/Backend/Python/stdlib.py | 2 +- src/Dyna/Backend/Python/term.py | 5 ++++- src/Dyna/Backend/Python/utils.py | 28 ++++++++++++++++++------- 14 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/Dyna/Backend/Python/chart.py b/src/Dyna/Backend/Python/chart.py index 84cc669..1c09ea1 100644 --- a/src/Dyna/Backend/Python/chart.py +++ b/src/Dyna/Backend/Python/chart.py @@ -19,7 +19,7 @@ class Chart(object): def set_aggregator(self, agg): self.agg_name = agg for item in self.intern.values(): - assert item.value is None # shouldn't aggregator when non-null. + assert item.value is None # shouldn't change aggregator when non-null. item.aggregator = self.new_aggregator(item) def __repr__(self): diff --git a/src/Dyna/Backend/Python/config.py b/src/Dyna/Backend/Python/config.py index 7b67212..4695c0a 100644 --- a/src/Dyna/Backend/Python/config.py +++ b/src/Dyna/Backend/Python/config.py @@ -1,5 +1,5 @@ import os -from path import path +from IPython.external.path import path dotdynadir = path('~/.dyna').expand() if not dotdynadir.exists(): diff --git a/src/Dyna/Backend/Python/debug.py b/src/Dyna/Backend/Python/debug.py index 715509a..8075c0c 100644 --- a/src/Dyna/Backend/Python/debug.py +++ b/src/Dyna/Backend/Python/debug.py @@ -8,7 +8,7 @@ import re, os, shutil, webbrowser from collections import defaultdict from utils import dynac, read_anf from config import dynahome -from path import path +from IPython.external.path import path from warnings import warn try: diff --git a/src/Dyna/Backend/Python/interpreter.py b/src/Dyna/Backend/Python/interpreter.py index 4eef6dc..4f2fdda 100644 --- a/src/Dyna/Backend/Python/interpreter.py +++ b/src/Dyna/Backend/Python/interpreter.py @@ -3,7 +3,7 @@ import re, os, sys, imp, traceback from collections import defaultdict from hashlib import sha1 -from path import path +from IPython.external.path import path from term import Term, Cons, Nil, MapsTo, Error from chart import Chart diff --git a/src/Dyna/Backend/Python/load/matrix.py b/src/Dyna/Backend/Python/load/matrix.py index 4162804..4b28443 100644 --- a/src/Dyna/Backend/Python/load/matrix.py +++ b/src/Dyna/Backend/Python/load/matrix.py @@ -1,5 +1,6 @@ import re -from path import path +from IPython.external.path import path + class matrix(object): """ diff --git a/src/Dyna/Backend/Python/load/pickled.py b/src/Dyna/Backend/Python/load/pickled.py index 7104922..d7f8f28 100644 --- a/src/Dyna/Backend/Python/load/pickled.py +++ b/src/Dyna/Backend/Python/load/pickled.py @@ -7,7 +7,8 @@ TODO: Can we merge a pickled interpreter into an existing one? """ import cPickle -from path import path +from IPython.external.path import path + class pickled(object): diff --git a/src/Dyna/Backend/Python/load/sexpr.py b/src/Dyna/Backend/Python/load/sexpr.py index 5379db2..f701ffa 100644 --- a/src/Dyna/Backend/Python/load/sexpr.py +++ b/src/Dyna/Backend/Python/load/sexpr.py @@ -1,7 +1,8 @@ from cStringIO import StringIO from utils import parse_sexpr from stdlib import todyna -from path import path +from IPython.external.path import path + class sexpr(object): """ diff --git a/src/Dyna/Backend/Python/load/tsv.py b/src/Dyna/Backend/Python/load/tsv.py index 13b59ec..761385a 100644 --- a/src/Dyna/Backend/Python/load/tsv.py +++ b/src/Dyna/Backend/Python/load/tsv.py @@ -5,7 +5,8 @@ TODO: option for strict number of columns. import re from utils import true -from path import path +from IPython.external.path import path + class tsv(object): """ diff --git a/src/Dyna/Backend/Python/main.py b/src/Dyna/Backend/Python/main.py index 31bcbb5..e2949db 100644 --- a/src/Dyna/Backend/Python/main.py +++ b/src/Dyna/Backend/Python/main.py @@ -1,5 +1,5 @@ import argparse -from path import path +from IPython.external.path import path from errors import DynaCompilerError from errors import crash_handler from interpreter import Interpreter diff --git a/src/Dyna/Backend/Python/post/trace.py b/src/Dyna/Backend/Python/post/trace.py index 9444553..cfeeaa6 100644 --- a/src/Dyna/Backend/Python/post/trace.py +++ b/src/Dyna/Backend/Python/post/trace.py @@ -1,11 +1,10 @@ # -*- coding: utf-8 -*- import re -from collections import defaultdict import debug from draw_circuit import infer_edges -from utils import yellow, green, cyan, red, _repr +from utils import yellow, green, cyan, red, _repr, groupby class trace(object): @@ -49,13 +48,6 @@ class Tracer(object): depth_limit = depth_limit)) -def groupby(key, data): - g = defaultdict(list) - for x in data: - g[key(x)].append(x) - return dict(g) - - def dig(head, visited, tail, groups, interp, depth_limit=-1): if depth_limit >= 0 and len(tail) >= depth_limit: diff --git a/src/Dyna/Backend/Python/repl.py b/src/Dyna/Backend/Python/repl.py index 37ceac8..54a42c2 100644 --- a/src/Dyna/Backend/Python/repl.py +++ b/src/Dyna/Backend/Python/repl.py @@ -575,6 +575,21 @@ class REPL(cmd.Cmd, object): # query must have failed. pass - do_load.__doc__ = do_load.__doc__.format(load=', '.join(load.available)) do_post.__doc__ = do_post.__doc__.format(post=', '.join(post.available)) + + def do_paste(self, _): + """ + Add a new rule to program by pasting from clipboard. The advantage of + using this paste` command is that newlines within will not break a rule + definition. + + TODO: support execution of other commands, e.g. 'load' or 'sol'. + """ + from IPython.core.hooks import clipboard_get + x = clipboard_get(None) + print x + if raw_input('%s ok? [Y/n] ' % yellow % '>>>') == 'n': # control-c works too + pass + else: + self.default(x) diff --git a/src/Dyna/Backend/Python/stdlib.py b/src/Dyna/Backend/Python/stdlib.py index 94f3916..d74ee38 100644 --- a/src/Dyna/Backend/Python/stdlib.py +++ b/src/Dyna/Backend/Python/stdlib.py @@ -1,4 +1,4 @@ -import re +import re, os from term import Term, Cons, Nil, MapsTo from collections import Counter from utils import pretty, pretty_print, true, false, null, isbool diff --git a/src/Dyna/Backend/Python/term.py b/src/Dyna/Backend/Python/term.py index 84f46ab..404a0ce 100644 --- a/src/Dyna/Backend/Python/term.py +++ b/src/Dyna/Backend/Python/term.py @@ -20,7 +20,10 @@ class Term(object): if self is other: return 0 try: - return cmp((self.fn, self.args), (other.fn, other.args)) + if self.fn == other.fn: + return cmp(self.args, other.args) + else: + return cmp(self.fn, other.fn) except AttributeError: return 1 diff --git a/src/Dyna/Backend/Python/utils.py b/src/Dyna/Backend/Python/utils.py index 1559f56..47fa5a5 100644 --- a/src/Dyna/Backend/Python/utils.py +++ b/src/Dyna/Backend/Python/utils.py @@ -1,12 +1,19 @@ import re from IPython.frontend.terminal.embed import InteractiveShellEmbed -from path import path +from IPython.external.path import path from subprocess import Popen, PIPE from config import dynahome, dotdynadir -from collections import namedtuple +from collections import namedtuple, defaultdict from cStringIO import StringIO +def groupby(key, data): + g = defaultdict(list) + for x in data: + g[key(x)].append(x) + return dict(g) + + # TODO: This is pretty hacking we should have the codegen produce something # easier to serialize/modify/unserialize. XREF:parser-state def parse_parser_state(parser_state): @@ -103,11 +110,15 @@ def get_module(cmd, sub): return m -black, red, green, yellow, blue, magenta, cyan, white = \ - map('\033[3%sm%%s\033[0m'.__mod__, range(8)) +red, green, yellow, blue, magenta, cyan, white = \ + map('\033[3%sm%%s\033[0m'.__mod__, range(1,8)) bold = '\033[1m%s\033[0m' +# TODO: use fabulous colors +#from fabulous.color import red, green, yellow, blue, magenta, cyan, white, bold, underline + + _comments = re.compile('%.*$', re.MULTILINE) def strip_comments(src): return _comments.sub('', src).strip() @@ -139,7 +150,7 @@ def dynac(f, out, anf=None, compiler_args=()): stdout, stderr = p.communicate() if p.returncode: assert not stdout.strip(), [stdout, stderr] - stderr = hide_ugly_filename(stderr, lambda m: '\n %s\n' % rule_source(m.group(0))) + stderr = hide_ugly_filename(stderr, lambda m: '\n %s\n' % span_to_src(m.group(0))) raise DynaCompilerError(stderr, f) @@ -297,13 +308,14 @@ def read_anf(e): def parse_attrs(fn): attrs = dict(re.findall('\s*(\S+):\s*(.*)\s*\n', fn.__doc__.strip())) if 'Span' in attrs: - attrs['rule'] = rule_source(attrs['Span']).strip() + attrs['rule'] = span_to_src(attrs['Span']).strip() return attrs -def rule_source(span, src=None): +def span_to_src(span, src=None): """ - Utility for retrieving source code for Parsec error message. + Utility for retrieving source code for Parsec error message (there is + nothing specific about rules) """ try: [(filename, bl, bc, el, ec)] = re.findall(r'(.*):(\d+):(\d+)-\1:(\d+):(\d+)', span) -- 2.50.1