42 lines
1.3 KiB
C++

#include "ast_printer.hh"
#include "expr.hh"
#include <cassert>
#include <string>
#include <sstream>
std::string AstPrinter::print(const Expr &expr) {
switch (expr.type) {
case ExprType::BINARY: {
std::shared_ptr<_Binary> binary = std::get<std::shared_ptr<_Binary>>(expr.value);
assert(binary != nullptr);
return parenthesize(binary->op.lexeme, {&binary->left, &binary->right});
}
case ExprType::GROUPING: {
std::shared_ptr<_Grouping> group = std::get<std::shared_ptr<_Grouping>>(expr.value);
assert(group != nullptr);
return parenthesize("group", {&group->expr});
}
case ExprType::LITERAL: {
std::shared_ptr<_Literal> literal = std::get<std::shared_ptr<_Literal>>(expr.value);
assert(literal != nullptr);
return literal->value.to_string();
}
case ExprType::UNARY: {
std::shared_ptr<_Unary> unary = std::get<std::shared_ptr<_Unary>>(expr.value);
assert(unary != nullptr);
return parenthesize(unary->op.lexeme, {&unary->right});
}
}
}
std::string AstPrinter::parenthesize(const std::string &name, std::vector<const Expr *> exprs) {
std::stringstream ss{};
ss << '(' << name;
for (const Expr *expr : exprs) {
ss << ' ' << print(*expr);
}
ss << ')';
return ss.str();
}