I am trying to build a simple interpreter using the Visitor pattern. I'm having a difficult time trying to understand how a task such as pretty-printing the tree can be implemented using this pattern.
The result I am trying to obtain is printing the AST with proper indentation:
Expr
'---Abstr
|---Id
'---Expr
'---App
'---Atom
'---Id
I have defined a number of classes representing nodes in the AST:
class ASTNode
attr_reader :children, :pos
def initialize(children, pos)
@children = children
@pos = pos
end
def accept(visitor)
visitor.visit(self)
@children.each { |child| child.accept(visitor) } unless @children.nil?
end
end
class ExprNode < ASTNode
def initialize(children, pos)
super(children, pos)
end
end
...
and a base visitor class performing double dispatch:
class Visitor
def visit(subject)
method_name = "visit_#{subject.class}".intern
send(method_name, subject)
end
end
Finally, the visitor for printing the AST:
class PrintVisitor < Visitor
def visit_ExprNode(subject)
end
def visit_AbstrNode(subject)
end
...
end
visit_*Node(subject)
methods ofPrintVisitor
- doing the indenting there is not possible. My understanding of visitor is quite limited and I don't know whether my use of the pattern is correct or not. – Jan Parzydło