#include "expr.hh" #include "../tokenizer.hh" #include #include #include #include template <> Expr make_expr(Binary value) { return Expr(ExprType::BINARY, value); } template <> Expr make_expr(Grouping value) { return Expr(ExprType::GROUPING, value); } template <> Expr make_expr(Literal value) { return Expr(ExprType::LITERAL, value); } template <> Expr make_expr(Unary value) { return Expr(ExprType::UNARY, value); } std::string AstPrinter::print(const Expr &expr) { switch (expr.type) { case ExprType::BINARY: { Binary node = std::get(expr.value); assert(node.left != NULL && node.right != NULL); return parenthesize(node.op.lexeme, {*node.left, *node.right}); } case ExprType::GROUPING: { Grouping node = std::get(expr.value); assert(node.expression != NULL); return parenthesize("group", {*node.expression}); } case ExprType::LITERAL: { Literal node = std::get(expr.value); switch (node.value.type) { case ObjectType::NIL: return "nil"; case ObjectType::IDENTIFIER: case ObjectType::STRING_LIT: { std::string value = std::get(node.value.value); return value; } case ObjectType::NUMBER: { double value = std::get(node.value.value); return std::to_string(value); } } } case ExprType::UNARY: { Unary node = std::get(expr.value); assert(node.right != NULL); return parenthesize(node.op.lexeme, {*node.right}); } } } std::string AstPrinter::parenthesize(const std::string &name, std::vector exprs) { std::stringstream ss{}; ss << '(' << name; for (auto &expr : exprs) { ss << ' ' << print(expr); } ss << ')'; return ss.str(); }