58 lines
1.7 KiB
Python
58 lines
1.7 KiB
Python
"""
|
|
Generic AST transformation classes.
|
|
"""
|
|
|
|
|
|
class Transformer:
|
|
"""
|
|
Base class for AST transformers.
|
|
"""
|
|
def transform(self, ast):
|
|
"""
|
|
Transform the given AST and return the resulting AST.
|
|
|
|
:param ast: The AST to transform
|
|
:return: A 2-tuple: the transformed AST and a boolean indicating whether
|
|
the transformation actually changed anything. The change detection
|
|
is useful in situations where a transformation needs to be repeated
|
|
until the AST stops changing.
|
|
"""
|
|
raise NotImplementedError("transform")
|
|
|
|
|
|
class ChainTransformer(Transformer):
|
|
"""
|
|
A composite transformer which consists of a sequence of sub-transformers.
|
|
Applying this transformer applies all sub-transformers in sequence, as
|
|
a group.
|
|
"""
|
|
def __init__(self, *transformers):
|
|
self.__transformers = transformers
|
|
|
|
def transform(self, ast):
|
|
changed = False
|
|
for transformer in self.__transformers:
|
|
ast, this_changed = transformer.transform(ast)
|
|
if this_changed:
|
|
changed = True
|
|
|
|
return ast, changed
|
|
|
|
|
|
class SettleTransformer(Transformer):
|
|
"""
|
|
A transformer that repeatedly performs a transformation until that
|
|
transformation no longer changes the AST. I.e. the AST has "settled".
|
|
"""
|
|
def __init__(self, transform):
|
|
self.__transformer = transform
|
|
|
|
def transform(self, ast):
|
|
changed = False
|
|
ast, this_changed = self.__transformer.transform(ast)
|
|
while this_changed:
|
|
changed = True
|
|
ast, this_changed = self.__transformer.transform(ast)
|
|
|
|
return ast, changed
|