This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

94 lines
2.6 KiB

  1. from utils import inline_args
  2. class Tree(object):
  3. def __init__(self, data, children):
  4. self.data = data
  5. self.children = list(children)
  6. def __repr__(self):
  7. return 'Tree(%s, %s)' % (self.data, self.children)
  8. def _pretty(self, level, indent_str):
  9. if len(self.children) == 1 and not isinstance(self.children[0], Tree):
  10. return [ indent_str*level, self.data, '\t', '%s' % self.children[0], '\n']
  11. l = [ indent_str*level, self.data, '\n' ]
  12. for n in self.children:
  13. if isinstance(n, Tree):
  14. l += n._pretty(level+1, indent_str)
  15. else:
  16. l += [ indent_str*(level+1), '%s' % n, '\n' ]
  17. return l
  18. def pretty(self, indent_str=' '):
  19. return ''.join(self._pretty(0, indent_str))
  20. def expand_kids_by_index(self, *indices):
  21. for i in sorted(indices, reverse=True): # reverse so that changing tail won't affect indices
  22. kid = self.children[i]
  23. self.children[i:i+1] = kid.children
  24. # def find_path(self, pred):
  25. # if pred(self):
  26. # yield []
  27. # else:
  28. # for i, c in enumerate(self.children):
  29. # if isinstance(c, Tree):
  30. # for path in c.find_path(pred):
  31. # yield [i] + path
  32. # def follow_path(self, path):
  33. # x = self
  34. # for step in path:
  35. # x = x.children[step]
  36. # return x
  37. # def set_at_path(self, path, value):
  38. # x = self.follow_path(path[:-1])
  39. # x.children[path[-1]] = value
  40. def clone(self):
  41. return Tree(self.data, [c.clone() if isinstance(c, Tree) else c for c in self.children])
  42. class Transformer(object):
  43. def _get_func(self, name):
  44. return getattr(self, name)
  45. def transform(self, tree):
  46. items = [self.transform(c) if isinstance(c, Tree) else c for c in tree.children]
  47. try:
  48. f = self._get_func(tree.data)
  49. except AttributeError:
  50. return self.__default__(tree.data, items)
  51. else:
  52. return f(items)
  53. def __default__(self, data, children):
  54. return Tree(data, children)
  55. class InlineTransformer(Transformer):
  56. def _get_func(self, name):
  57. return inline_args(getattr(self, name)).__get__(self)
  58. class Visitor(object):
  59. def visit(self, tree):
  60. for child in tree.children:
  61. if isinstance(child, Tree):
  62. self.visit(child)
  63. f = getattr(self, tree.data, self.__default__)
  64. f(tree)
  65. return tree
  66. def __default__(self, tree):
  67. pass