#include "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> binary = std::get>(expr.value); assert(binary != nullptr); return parenthesize(binary->op.lexeme, {&binary->left, &binary->right}); } case ExprType::GROUPING: { std::shared_ptr<_Grouping> group = std::get>(expr.value); assert(group != nullptr); return parenthesize("group", {&group->expr}); } case ExprType::LITERAL: { std::shared_ptr<_Literal> literal = std::get>(expr.value); assert(literal != nullptr); switch (literal->value.type) { case ObjectType::NIL: return "nil"; case ObjectType::BOOL: { bool value = std::get(literal->value.value); return (value ? "true" : "false"); } case ObjectType::IDENTIFIER: case ObjectType::STRING_LIT: { std::string value = std::get(literal->value.value); return value; } case ObjectType::NUMBER: { double value = std::get(literal->value.value); return std::to_string(value); } } } case ExprType::UNARY: { std::shared_ptr<_Unary> unary = std::get>(expr.value); assert(unary != nullptr); return parenthesize(unary->op.lexeme, {&unary->right}); } } } 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(); }