docstrings on the mangle
This commit is contained in:
parent
049c019791
commit
23773a5117
42
hy/mangle.py
42
hy/mangle.py
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user