2025-06-20 23:25:12 +01:00

54 lines
1.5 KiB
C++

#include "expr.hh"
#include "../tokenizer.hh"
#include <cassert>
#include <string>
#include <vector>
#include <sstream>
std::string AstPrinter::print(const Expr &expr) {
switch (expr.type) {
case ExprType::BINARY: {
_Binary node = std::get<_Binary>(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<_Grouping>(expr.value);
assert(node.expression != NULL);
return parenthesize("group", {*node.expression});
}
case ExprType::LITERAL: {
_Literal node = std::get<_Literal>(expr.value);
switch (node.value.type) {
case ObjectType::NIL:
return "nil";
case ObjectType::IDENTIFIER:
case ObjectType::STRING_LIT: {
std::string value = std::get<std::string>(node.value.value);
return value;
}
case ObjectType::NUMBER: {
double value = std::get<double>(node.value.value);
return std::to_string(value);
}
}
}
case ExprType::UNARY: {
_Unary node = std::get<_Unary>(expr.value);
assert(node.right != NULL);
return parenthesize(node.op.lexeme, {*node.right});
}
}
}
std::string AstPrinter::parenthesize(const std::string &name, std::vector<Expr> exprs) {
std::stringstream ss{};
ss << '(' << name;
for (auto &expr : exprs) {
ss << ' ' << print(expr);
}
ss << ')';
return ss.str();
}