You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.6 KiB

module Lox
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)
def visit_print(expr) = parenthesize("print", expr.expr)
def visit_var(expr)
exprs = [expr.initializer].reject(&:nil?)
parenthesize("var #{expr.name.lexeme}", *exprs)
end
def visit_variable(expr)
"(var #{expr.name.lexeme})"
end
def visit_assign(expr)
parenthesize("assign #{expr.name.lexeme}", expr.value)
end
def visit_block(expr)
parenthesize("block", *expr.stmts)
end
def visit_if(stmt)
exprs = [stmt.cond, stmt.then]
exprs << stmt.else if stmt.else
parenthesize("if", *exprs)
end
def visit_expr(expr)
expr.expr.accept(self)
end
def visit_call(call)
parenthesize(call.callee.accept(self), *call.args)
end
def visit_return(stmt)
exprs = stmt.value ? [stmt.value] : []
parenthesize("return", *exprs)
end
def visit_while(stmt)
parenthesize("while", stmt.cond, stmt.body)
end
def visit_class(stmt)
parenthesize("class #{stmt.name.lexeme}", *stmt.methods)
end
def visit_function(stmt)
parenthesize("function #{stmt.name.lexeme}", *stmt.body)
end
private
def parenthesize(name, *exprs)
"(#{[name, *exprs.map { _1.accept(self) }].join(" ")})"
end
end
end