52 lines
1.6 KiB
C++
52 lines
1.6 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> ptr = std::get<std::shared_ptr<_Binary>>(expr.value);
|
|
assert(ptr != nullptr);
|
|
return parenthesize(ptr->op.lexeme, {&ptr->left, &ptr->right});
|
|
}
|
|
case ExprType::GROUPING: {
|
|
std::shared_ptr<_Grouping> ptr = std::get<std::shared_ptr<_Grouping>>(expr.value);
|
|
assert(ptr != nullptr);
|
|
return parenthesize("group", {&ptr->expr});
|
|
}
|
|
case ExprType::LITERAL: {
|
|
std::shared_ptr<_Literal> ptr = std::get<std::shared_ptr<_Literal>>(expr.value);
|
|
assert(ptr != nullptr);
|
|
return ptr->value.to_string();
|
|
}
|
|
case ExprType::UNARY: {
|
|
std::shared_ptr<_Unary> ptr = std::get<std::shared_ptr<_Unary>>(expr.value);
|
|
assert(ptr != nullptr);
|
|
return parenthesize(ptr->op.lexeme, {&ptr->right});
|
|
}
|
|
case ExprType::VARIABLE: {
|
|
std::shared_ptr<_Variable> ptr = std::get<std::shared_ptr<_Variable>>(expr.value);
|
|
assert(ptr != nullptr);
|
|
return ptr->name.lexeme;
|
|
}
|
|
case ExprType::ASSIGN: {
|
|
std::shared_ptr<_Assign> ptr = std::get<std::shared_ptr<_Assign>>(expr.value);
|
|
assert(ptr != nullptr);
|
|
return ptr->name.lexeme;
|
|
}
|
|
}
|
|
}
|
|
|
|
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();
|
|
}
|