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