implement AstPrinter

FossilOrigin-Name: ed84fb6a6150359d3756c8636af19f487cb4da6fc2f21a6147b335751416a06f
private
alpha 2 years ago
parent 3330fe5d62
commit 2e4377b600

@ -195,6 +195,39 @@ module Lox
"#{type} #{lexeme} #{literal}" "#{type} #{lexeme} #{literal}"
end end
end end
module Expr
Binary = Struct.new(:left, :op, :right) do
def accept(visitor) = visitor.visit_binary(self)
end
Grouping = Struct.new(:expr) do
def accept(visitor) = visitor.visit_grouping(self)
end
Literal = Struct.new(:value) do
def accept(visitor) = visitor.visit_literal(self)
end
Unary = Struct.new(:op, :right) do
def accept(visitor) = visitor.visit_unary(self)
end
end
class AstPrinter
def print(expr) = expr.accept(self)
def visit_binary(expr) = parenthesize(expr.op.lexeme, expr.left, expr.right)
def visit_grouping(expr) = parenthesize("group", expr.expr)
def visit_literal(expr) = expr.value&.to_s || "nil"
def visit_unary(expr) = parenthesize(expr.op.lexeme, expr.right)
private
def parenthesize(name, *exprs)
"(#{name} #{exprs.map {|expr| expr.accept(self) }.join(" ")})"
end
end
end end
if __FILE__ == $0 if __FILE__ == $0

@ -137,3 +137,20 @@ class TestScanner < Minitest::Test
end end
end end
end end
class TestAstPrinter < Minitest::Test
def test_ast_printer
expr = Expr::Binary.new(
Expr::Unary.new(
Token.new(:MINUS, ?-, nil, 1),
Expr::Literal.new(123),
),
Token.new(:STAR, ?*, nil, 1),
Expr::Grouping.new(
Expr::Literal.new(45.67),
),
)
assert_equal "(* (- 123) (group 45.67))", AstPrinter.new.print(expr)
end
end

Loading…
Cancel
Save