docstrings on the mangle

This commit is contained in:
Paul R. Tagliamonte 2013-04-18 22:44:03 -04:00
parent 049c019791
commit 23773a5117

View File

@ -35,38 +35,55 @@ class Mangle(object):
"""
class TreeChanged(Exception):
"""
This exception gets raised whenver any code alters the tree. This is
to let the handling code re-normalize parents, etc, and make sure we
re-enter the current position in order.
"""
pass
def _mangle(self, tree):
# Things that force a scope push to go into:
#
# - Functions
# - If
scopable = ["fn", "if"]
scoped = False
"""
Main function of self.mangle, which is called over and over. This
is used to beat the tree until it stops moving.
"""
scopable = ["fn", "if"]
# Not actually scope, more like code branch.
scoped = False
self.push_stack(tree)
if isinstance(tree, HyExpression):
# If it's an expression, let's make sure we reset the "scope"
# (code branch) if it's a scopable object.
what = tree[0]
if what in scopable:
self.push_scope(tree)
scoped = True
if isinstance(tree, list):
# If it's a list, let's mangle all the elements of the list.
for i, element in enumerate(tree):
nel = self.visit(element)
if nel:
# if the subclass returned an object, we replace the
# current node.
tree[i] = nel
self.tree_changed()
self._mangle(element)
self.tree_changed() # auto-raise a changed notice.
self._mangle(element) # recurse down, unwind on change.
if scoped:
self.pop_scope()
self.pop_stack()
def hoist(self, what):
"""
Take a thing (what), and move it before whichever ancestor is in the
"scope" (code branch). This will hoist it *all* the way out of a deeply
nested statement in one pass. If it's still "invalid" (which it
shouldn't be), it'll just hoist again anyway.
"""
scope = self.scope
for point, el in enumerate(scope):
if el in self.stack:
@ -77,6 +94,7 @@ class Mangle(object):
return self.scopes[0]
def tree_changed(self):
""" Invoke this if you alter the tree in any way """
raise self.TreeChanged()
@property
@ -96,6 +114,12 @@ class Mangle(object):
return self.stack.pop(0)
def mangle(self, tree):
"""
Magic external entry point.
We mangle until the tree stops moving (we don't get a TreeChanged
Exception during mangle)
"""
unfinished = True
while unfinished:
self.root = tree