54 lines
1.6 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);
switch (literal->value.type) {
case ObjectType::NIL:
return "nil";
case ObjectType::IDENTIFIER:
case ObjectType::STRING_LIT: {
std::string value = std::get<std::string>(literal->value.value);
return value;
}
case ObjectType::NUMBER: {
double value = std::get<double>(literal->value.value);
return std::to_string(value);
}
}
}
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();
}