class Doc: # base class
def __mod__(self, other):
other = self.mod.getdoc(other)
return self.mapchildren(lambda x: x % other)
def __rmod__(self, other):
return self.mod.getdoc(other) % self
def __str__(self):
return self.getstr()
def __eq__(self, other):
if not isinstance(other, self.__class__):
return 0
return str(self) == str(other)
def __hash__(self):
return hash(str(self))
def shortest(self):
return self.mapchildren(lambda x: x.shortest())
class Anon(Doc):
def __init__(self, mod, obj):
self.mod = mod
self.obj = obj
def getstr(self):
return repr(self.obj)
def mapchildren(self, f):
return self
class Source(Doc):
def __init__(self, mod, text):
self.mod = mod
self.text = text
def getstr(self):
return self.text
def mapchildren(self, f):
return self
class Attribute(Doc):
def __init__(self, mod, obj, name):
self.mod = mod
self.obj = obj
self.name = name
def __mod__(self, other):
if self.obj is other:
return self.mod.rootattribute(other, self.name)
return self.mapchildren(lambda x: x % other)
def getstr(self):
return '%s.%s' % (self.obj.getstr(), self.name)
def mapchildren(self, f):
return self.__class__(self.mod, f(self.obj), self.name)
class RootAttribute(Doc):
def __init__(self, mod, obj, name):
self.mod = mod
self.obj = obj
self.name = name
def getstr(self):
return '%s' % (self.name,)
def mapchildren(self, f):
return self
class BinaryOp(Doc):
table = {
'and': '&',
'or': '|',
'sub': '-',
'mul': '*',
'pow': '**',
'lshift': '<<',
'rshift': '>>',
}
def __init__(self, mod, op, a, b):
self.mod = mod
self.op = op
self.a = a
self.b = b
def getstr(self):
return '%s %s %s' % (self.a.getstr(),
self.table[self.op],
self.b.getstr())
def mapchildren(self, f):
return self.__class__(self.mod, self.op, f(self.a), f(self.b))
class UnaryOp(Doc):
table = {
'invert': '~',
'neg': '-',
'pos': '+',
}
def __init__(self, mod, op, a):
self.mod = mod
self.op = op
self.a = a
def getstr(self):
return '%s %s' % (self.table[self.op], self.a.getstr())
def mapchildren(self, f):
return self.__class__(self.mod, self.op, f(self.a))
class CallFunc(Doc):
def __init__(self, mod, obj, *args, **kwds):
self.mod = mod
self.obj = obj
self.args = args
self.kwds = kwds
def getstr(self):
return '%s(%s%s)' % (
self.obj.getstr(),
', '.join([x.getstr() for x in self.args]),
', '.join(['%s=%s' % (k, v.getstr()) for k, v in list(self.kwds.items())]))
def mapchildren(self, f):
obj = f(self.obj)
args = [f(a) for a in self.args]
kwds = dict([(k, f(v)) for (k, v) in list(self.kwds.items())])
return self.__class__(self.mod, obj, *args, **kwds)
class Multi(Doc):
def __init__(self, mod, set):
self.mod = mod
self.str = '{%s}' % ', '.join([x.getstr() for x in set])
self.set = set
def getstr(self):
return self.str
def mapchildren(self, f):
return self.__class__(self.mod, dict([(f(x), 1) for x in self.set]))
def shortest(self):
ls = None
for a in self.set:
a = a.shortest()
l = len(a.getstr())
if ls is None or l < ls:
ls = l
st = a
return st
class Root(Doc):
def __init__(self, mod, name='