unparse: string-based API

This commit is contained in:
Sebastien Bourdeauducq 2014-11-03 18:14:33 +08:00
parent e9e12adceb
commit 9b93b0cedf
2 changed files with 30 additions and 27 deletions

View File

@ -8,13 +8,13 @@ from artiq.transforms.remove_dead_code import remove_dead_code
from artiq.transforms.unroll_loops import unroll_loops from artiq.transforms.unroll_loops import unroll_loops
from artiq.transforms.interleave import interleave from artiq.transforms.interleave import interleave
from artiq.transforms.lower_time import lower_time from artiq.transforms.lower_time import lower_time
from artiq.transforms.unparse import Unparser from artiq.transforms.unparse import unparse
from artiq.py2llvm import get_runtime_binary from artiq.py2llvm import get_runtime_binary
def _unparse(label, node): def _announce_unparse(label, node):
print("*** Unparsing: "+label) print("*** Unparsing: "+label)
Unparser(node) print(unparse(node))
def _make_debug_unparse(final): def _make_debug_unparse(final):
@ -24,14 +24,14 @@ def _make_debug_unparse(final):
env = "" env = ""
selected_labels = set(env.split()) selected_labels = set(env.split())
if "all" in selected_labels: if "all" in selected_labels:
return _unparse return _announce_unparse
else: else:
if "final" in selected_labels: if "final" in selected_labels:
selected_labels.add(final) selected_labels.add(final)
def _filtered_unparse(label, node): def _filtered_unparse(label, node):
if label in selected_labels: if label in selected_labels:
_unparse(label, node) _announce_unparse(label, node)
return _filtered_unparse return _filtered_unparse

View File

@ -7,7 +7,7 @@ import ast
INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1) INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)
def interleave(inter, f, seq): def _interleave(inter, f, seq):
"""Call f on each item in seq, calling inter() in between. """Call f on each item in seq, calling inter() in between.
""" """
seq = iter(seq) seq = iter(seq)
@ -21,27 +21,25 @@ def interleave(inter, f, seq):
f(x) f(x)
class Unparser: class _Unparser:
"""Methods in this class recursively traverse an AST and """Methods in this class recursively traverse an AST and
output source code for the abstract syntax; original formatting output source code for the abstract syntax; original formatting
is disregarded. """ is disregarded. """
def __init__(self, tree, file=sys.stdout): def __init__(self, tree):
"""Unparser(tree, file=sys.stdout) -> None. """Print the source for tree to the "result" string."""
Print the source for tree to file.""" self.result = ""
self.f = file
self._indent = 0 self._indent = 0
self.dispatch(tree) self.dispatch(tree)
print("", file=self.f) self.result += "\n"
self.f.flush()
def fill(self, text=""): def fill(self, text=""):
"Indent a piece of text, according to the current indentation level" "Indent a piece of text, according to the current indentation level"
self.f.write("\n"+" "*self._indent + text) self.result += "\n"+" "*self._indent + text
def write(self, text): def write(self, text):
"Append a piece of text to the current line." "Append a piece of text to the current line."
self.f.write(text) self.result += text
def enter(self): def enter(self):
"Print ':', and increase the indentation." "Print ':', and increase the indentation."
@ -79,7 +77,7 @@ class Unparser:
def _Import(self, t): def _Import(self, t):
self.fill("import ") self.fill("import ")
interleave(lambda: self.write(", "), self.dispatch, t.names) _interleave(lambda: self.write(", "), self.dispatch, t.names)
def _ImportFrom(self, t): def _ImportFrom(self, t):
self.fill("from ") self.fill("from ")
@ -87,7 +85,7 @@ class Unparser:
if t.module: if t.module:
self.write(t.module) self.write(t.module)
self.write(" import ") self.write(" import ")
interleave(lambda: self.write(", "), self.dispatch, t.names) _interleave(lambda: self.write(", "), self.dispatch, t.names)
def _Assign(self, t): def _Assign(self, t):
self.fill() self.fill()
@ -119,7 +117,7 @@ class Unparser:
def _Delete(self, t): def _Delete(self, t):
self.fill("del ") self.fill("del ")
interleave(lambda: self.write(", "), self.dispatch, t.targets) _interleave(lambda: self.write(", "), self.dispatch, t.targets)
def _Assert(self, t): def _Assert(self, t):
self.fill("assert ") self.fill("assert ")
@ -130,11 +128,11 @@ class Unparser:
def _Global(self, t): def _Global(self, t):
self.fill("global ") self.fill("global ")
interleave(lambda: self.write(", "), self.write, t.names) _interleave(lambda: self.write(", "), self.write, t.names)
def _Nonlocal(self, t): def _Nonlocal(self, t):
self.fill("nonlocal ") self.fill("nonlocal ")
interleave(lambda: self.write(", "), self.write, t.names) _interleave(lambda: self.write(", "), self.write, t.names)
def _Yield(self, t): def _Yield(self, t):
self.write("(") self.write("(")
@ -298,7 +296,7 @@ class Unparser:
def _With(self, t): def _With(self, t):
self.fill("with ") self.fill("with ")
interleave(lambda: self.write(", "), self.dispatch, t.items) _interleave(lambda: self.write(", "), self.dispatch, t.items)
self.enter() self.enter()
self.dispatch(t.body) self.dispatch(t.body)
self.leave() self.leave()
@ -322,7 +320,7 @@ class Unparser:
def _List(self, t): def _List(self, t):
self.write("[") self.write("[")
interleave(lambda: self.write(", "), self.dispatch, t.elts) _interleave(lambda: self.write(", "), self.dispatch, t.elts)
self.write("]") self.write("]")
def _ListComp(self, t): def _ListComp(self, t):
@ -376,7 +374,7 @@ class Unparser:
def _Set(self, t): def _Set(self, t):
assert(t.elts) # should be at least one element assert(t.elts) # should be at least one element
self.write("{") self.write("{")
interleave(lambda: self.write(", "), self.dispatch, t.elts) _interleave(lambda: self.write(", "), self.dispatch, t.elts)
self.write("}") self.write("}")
def _Dict(self, t): def _Dict(self, t):
@ -387,7 +385,7 @@ class Unparser:
self.dispatch(k) self.dispatch(k)
self.write(": ") self.write(": ")
self.dispatch(v) self.dispatch(v)
interleave(lambda: self.write(", "), write_pair, zip(t.keys, t.values)) _interleave(lambda: self.write(", "), write_pair, zip(t.keys, t.values))
self.write("}") self.write("}")
def _Tuple(self, t): def _Tuple(self, t):
@ -397,7 +395,7 @@ class Unparser:
self.dispatch(elt) self.dispatch(elt)
self.write(",") self.write(",")
else: else:
interleave(lambda: self.write(", "), self.dispatch, t.elts) _interleave(lambda: self.write(", "), self.dispatch, t.elts)
self.write(")") self.write(")")
unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"} unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"}
@ -438,7 +436,7 @@ class Unparser:
def _BoolOp(self, t): def _BoolOp(self, t):
self.write("(") self.write("(")
s = " %s " % self.boolops[t.op.__class__] s = " %s " % self.boolops[t.op.__class__]
interleave(lambda: self.write(s), self.dispatch, t.values) _interleave(lambda: self.write(s), self.dispatch, t.values)
self.write(")") self.write(")")
def _Attribute(self, t): def _Attribute(self, t):
@ -511,7 +509,7 @@ class Unparser:
self.dispatch(t.step) self.dispatch(t.step)
def _ExtSlice(self, t): def _ExtSlice(self, t):
interleave(lambda: self.write(', '), self.dispatch, t.dims) _interleave(lambda: self.write(', '), self.dispatch, t.dims)
# argument # argument
def _arg(self, t): def _arg(self, t):
@ -594,3 +592,8 @@ class Unparser:
if t.optional_vars: if t.optional_vars:
self.write(" as ") self.write(" as ")
self.dispatch(t.optional_vars) self.dispatch(t.optional_vars)
def unparse(tree):
unparser = _Unparser(tree)
return unparser.result