unparse.py can now unparse itself.

This commit is contained in:
Martin v. Löwis 2006-02-28 21:41:30 +00:00
parent cd8ca8092f
commit 87a8b4fee5
1 changed files with 139 additions and 2 deletions

View File

@ -12,6 +12,7 @@ class Unparser:
self.f = file
self._indent = 0
self.dispatch(tree)
print >>self.f,""
self.f.flush()
def fill(self, text = ""):
@ -76,6 +77,31 @@ class Unparser:
self.write(" = ")
self.dispatch(t.value)
def _AugAssign(self, t):
self.fill()
self.dispatch(t.target)
self.write(" "+self.binop[t.op.__class__.__name__]+"= ")
self.dispatch(t.value)
def _Return(self, t):
self.fill("return ")
if t.value:
self.dispatch(t.value)
def _Print(self, t):
self.fill("print ")
do_comma = False
if t.dest:
self.write(">>")
self.dispatch(t.dest)
do_comma = True
for e in t.values:
if do_comma:self.write(", ")
else:do_comma=True
self.dispatch(e)
if not t.nl:
self.write(",")
def _ClassDef(self, t):
self.write("\n")
self.fill("class "+t.name)
@ -110,6 +136,20 @@ class Unparser:
self.dispatch(t.orelse)
self.leave()
def _For(self, t):
self.fill("for ")
self.dispatch(t.target)
self.write(" in ")
self.dispatch(t.iter)
self.enter()
self.dispatch(t.body)
self.leave()
if t.orelse:
self.fill("else")
self.enter()
self.dispatch(t.orelse)
self.leave
# expr
def _Str(self, tree):
self.write(repr(tree.s))
@ -117,6 +157,9 @@ class Unparser:
def _Name(self, t):
self.write(t.id)
def _Num(self, t):
self.write(repr(t.n))
def _List(self, t):
self.write("[")
for e in t.elts:
@ -124,6 +167,25 @@ class Unparser:
self.write(", ")
self.write("]")
def _Dict(self, t):
self.write("{")
for k,v in zip(t.keys, t.values):
self.dispatch(k)
self.write(" : ")
self.dispatch(v)
self.write(", ")
self.write("}")
def _Tuple(self, t):
if not t.elts:
self.write("()")
return
self.write("(")
for e in t.elts:
self.dispatch(e)
self.write(", ")
self.write(")")
unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
def _UnaryOp(self, t):
self.write(self.unop[t.op.__class__.__name__])
@ -131,14 +193,89 @@ class Unparser:
self.dispatch(t.operand)
self.write(")")
binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%",
"RShift":"<<", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
"FloorDiv":"//"}
def _BinOp(self, t):
self.write("(")
self.dispatch(t.left)
self.write(")" + self.binop[t.op.__class__.__name__] + "(")
self.dispatch(t.right)
self.write(")")
cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=",
"Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"}
def _Compare(self, t):
self.write("(")
self.dispatch(t.left)
for o, e in zip(t.ops, t.comparators):
self.write(") " +self.cmpops[o.__class__.__name__] + " (")
self.dispatch(e)
self.write(")")
def _Attribute(self,t):
self.dispatch(t.value)
self.write(".")
self.write(t.attr)
def _Call(self, t):
self.dispatch(t.func)
self.write("(")
comma = False
for e in t.args:
if comma: self.write(", ")
else: comma = True
self.dispatch(e)
for e in t.keywords:
if comma: self.write(", ")
else: comma = True
self.dispatch(e)
if t.starargs:
if comma: self.write(", ")
else: comma = True
self.write("*")
self.dispatch(t.stararg)
if t.kwargs:
if comma: self.write(", ")
else: comma = True
self.write("**")
self.dispatch(t.stararg)
self.write(")")
def _Subscript(self, t):
self.dispatch(t.value)
self.write("[")
self.dispatch(t.slice)
self.write("]")
# slice
def _Index(self, t):
self.dispatch(t.value)
def _Slice(self, t):
if t.lower:
self.dispatch(t.lower)
self.write(":")
if t.upper:
self.dispatch(t.upper)
if t.step:
self.write(":")
self.dispatch(t.step)
# others
def _arguments(self, t):
first = True
# XXX t.defaults
for a in t.args:
nonDef = len(t.args)-len(t.defaults)
for a in t.args[0:nonDef]:
if first:first = False
else: self.write(", ")
self.dispatch(a)
for a,d in zip(t.args[nonDef:], t.defaults):
if first:first = False
else: self.write(", ")
self.dispatch(a),
self.write("=")
self.dispatch(d)
if t.vararg:
if first:first = False
else: self.write(", ")