Skip to content

Commit

Permalink
Add a read-only visitor pattern.
Browse files Browse the repository at this point in the history
This includes some performance tests to compare the visitor and a
traversal. Locally, the visitor is twice as fast.

This is the most basic Visitor pattern. I've had versions that were
more generic, and performance gains vanished quickly. In particular
optionally collecting results on exit halfed the performance benefits.

If we want to factor that in, we should have an independent base class
for that.
  • Loading branch information
Pike committed Feb 7, 2019
1 parent cf4d4b0 commit f3f9053
Show file tree
Hide file tree
Showing 3 changed files with 524 additions and 0 deletions.
30 changes: 30 additions & 0 deletions fluent.syntax/fluent/syntax/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
import json


class Visitor(object):
'''Read-only visitor pattern.
Subclass this to gather information from an AST.
To generally define which nodes not to descend in to, overload
`generic_visit`.
To handle specific node types, add methods like `visit_Pattern`.
The boolean value of the returned value determines if the visitor
descends into the children of the given AST node.
'''
def visit(self, value):
if isinstance(value, BaseNode):
self.visit_node(value)
if isinstance(value, list):
for node in value:
self.visit(node)

def visit_node(self, node):
nodename = type(node).__name__
visit = getattr(self, 'visit_{}'.format(nodename), self.generic_visit)
should_descend = visit(node)
if not should_descend:
return
for propname, propvalue in vars(node).items():
self.visit(propvalue)

def generic_visit(self, node):
return True


def to_json(value, fn=None):
if isinstance(value, BaseNode):
return value.to_json(fn)
Expand Down
Loading

0 comments on commit f3f9053

Please sign in to comment.