42 lines
1.3 KiB
C++
42 lines
1.3 KiB
C++
#include "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();
|
|
}
|