54 lines
1.5 KiB
C++
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();
|
|
}
|