1671 lines
43 KiB
C++
1671 lines
43 KiB
C++
#include <sstream>
|
|
#include "./debug_printer.hpp"
|
|
|
|
namespace lsp::language::ast
|
|
{
|
|
void DebugPrinter::PrintIndent()
|
|
{
|
|
os_ << GetIndent();
|
|
}
|
|
|
|
std::string DebugPrinter::GetIndent() const
|
|
{
|
|
return std::string(current_indent_, ' ');
|
|
}
|
|
|
|
void DebugPrinter::PrintLocation(const Location& loc)
|
|
{
|
|
os_ << "[" << loc.start_line << ":" << loc.start_column
|
|
<< "-" << loc.end_line << ":" << loc.end_column << "]";
|
|
}
|
|
|
|
void DebugPrinter::PrintNodeHeader(const std::string& type_name, const Location& loc)
|
|
{
|
|
PrintIndent();
|
|
os_ << type_name << " ";
|
|
PrintLocation(loc);
|
|
os_ << "\n";
|
|
}
|
|
|
|
void DebugPrinter::PrintExpression(const Expression* expr)
|
|
{
|
|
if (!expr)
|
|
{
|
|
os_ << "(null)";
|
|
return;
|
|
}
|
|
const_cast<Expression*>(expr)->Accept(*this);
|
|
}
|
|
|
|
void DebugPrinter::PrintParameter(const Parameter& param)
|
|
{
|
|
PrintIndent();
|
|
os_ << "parameter: " << param.name;
|
|
if (param.is_var)
|
|
os_ << " [var]";
|
|
if (param.is_out)
|
|
os_ << " [out]";
|
|
os_ << " ";
|
|
PrintLocation(param.location);
|
|
os_ << "\n";
|
|
|
|
if (param.type_name)
|
|
{
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "type: " << *param.type_name << "\n";
|
|
DecreaseIndent();
|
|
}
|
|
|
|
if (param.default_value)
|
|
{
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "default: ";
|
|
PrintExpression(param.default_value.get());
|
|
os_ << "\n";
|
|
DecreaseIndent();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintSignature(const Signature& sig)
|
|
{
|
|
if (!sig.parameters.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "parameters:\n";
|
|
IncreaseIndent();
|
|
for (const auto& param : sig.parameters)
|
|
PrintParameter(param);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
if (sig.return_type)
|
|
{
|
|
PrintIndent();
|
|
os_ << "return_type: " << *sig.return_type << "\n";
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintLeftHandSide(const LeftHandSide& lhs)
|
|
{
|
|
std::visit([this](auto&& arg) {
|
|
using T = std::decay_t<decltype(arg)>;
|
|
if constexpr (std::is_same_v<T, std::unique_ptr<Identifier>>)
|
|
{
|
|
if (arg)
|
|
arg->Accept(*this);
|
|
}
|
|
else if constexpr (std::is_same_v<T, std::unique_ptr<AttributeExpression>>)
|
|
{
|
|
if (arg)
|
|
arg->Accept(*this);
|
|
}
|
|
else if constexpr (std::is_same_v<T, std::unique_ptr<SubscriptExpression>>)
|
|
{
|
|
if (arg)
|
|
arg->Accept(*this);
|
|
}
|
|
else if constexpr (std::is_same_v<T, std::unique_ptr<UnpackPattern>>)
|
|
{
|
|
if (arg)
|
|
arg->Accept(*this);
|
|
}
|
|
else if constexpr (std::is_same_v<T, std::unique_ptr<VarDeclaration>>)
|
|
{
|
|
if (arg)
|
|
arg->Accept(*this);
|
|
}
|
|
else if constexpr (std::is_same_v<T, std::unique_ptr<StaticDeclaration>>)
|
|
{
|
|
if (arg)
|
|
arg->Accept(*this);
|
|
}
|
|
else if constexpr (std::is_same_v<T, std::unique_ptr<GlobalDeclaration>>)
|
|
{
|
|
if (arg)
|
|
arg->Accept(*this);
|
|
}
|
|
else if constexpr (std::is_same_v<T, std::unique_ptr<FieldDeclaration>>)
|
|
{
|
|
if (arg)
|
|
arg->Accept(*this);
|
|
}
|
|
},
|
|
lhs);
|
|
}
|
|
|
|
void DebugPrinter::PrintOperator(BinaryOperator op)
|
|
{
|
|
os_ << GetBinaryOperatorSymbol(op);
|
|
}
|
|
|
|
void DebugPrinter::PrintReferenceModifier(ReferenceModifier modifier)
|
|
{
|
|
switch (modifier)
|
|
{
|
|
case ReferenceModifier::kNone:
|
|
os_ << "none";
|
|
break;
|
|
case ReferenceModifier::kWeakRef:
|
|
os_ << "weakref";
|
|
break;
|
|
case ReferenceModifier::kAutoRef:
|
|
os_ << "autoref";
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintOperator(UnaryOperator op)
|
|
{
|
|
switch (op)
|
|
{
|
|
case UnaryOperator::kPlus:
|
|
os_ << "+";
|
|
break;
|
|
case UnaryOperator::kMinus:
|
|
os_ << "-";
|
|
break;
|
|
case UnaryOperator::kNot:
|
|
os_ << "not";
|
|
break;
|
|
case UnaryOperator::kBitwiseNot:
|
|
os_ << ".!";
|
|
break;
|
|
case UnaryOperator::kDotNot:
|
|
os_ << ".!!";
|
|
break;
|
|
case UnaryOperator::kMatrixTranspose:
|
|
os_ << "`";
|
|
break;
|
|
case UnaryOperator::kDerivative:
|
|
os_ << "!";
|
|
break;
|
|
case UnaryOperator::kExprAt:
|
|
os_ << "@";
|
|
break;
|
|
case UnaryOperator::kExprRef:
|
|
os_ << "&";
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintOperator(AssignmentOperator op)
|
|
{
|
|
os_ << GetAssignmentOperatorSymbol(op);
|
|
}
|
|
|
|
void DebugPrinter::PrintLiteralKind(LiteralKind kind)
|
|
{
|
|
switch (kind)
|
|
{
|
|
case LiteralKind::kNumber:
|
|
os_ << "number";
|
|
break;
|
|
case LiteralKind::kString:
|
|
os_ << "string";
|
|
break;
|
|
case LiteralKind::kBoolean:
|
|
os_ << "boolean";
|
|
break;
|
|
case LiteralKind::kNil:
|
|
os_ << "nil";
|
|
break;
|
|
case LiteralKind::kInfinity:
|
|
os_ << "infinity";
|
|
break;
|
|
case LiteralKind::kEllipsis:
|
|
os_ << "ellipsis";
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::VisitIdentifier(Identifier& node)
|
|
{
|
|
PrintNodeHeader("Identifier", node.location);
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "name: " << node.name << "\n";
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitLiteral(Literal& node)
|
|
{
|
|
PrintNodeHeader("Literal", node.location);
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "kind: ";
|
|
PrintLiteralKind(node.literal_kind);
|
|
os_ << "\n";
|
|
PrintIndent();
|
|
os_ << "value: " << node.value << "\n";
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitBinaryExpression(BinaryExpression& node)
|
|
{
|
|
PrintNodeHeader("BinaryExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "operator: ";
|
|
PrintOperator(node.op);
|
|
os_ << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "left:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.left.get());
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "right:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.right.get());
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitComparisonExpression(ComparisonExpression& node)
|
|
{
|
|
PrintNodeHeader("ComparisonExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "left:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.left.get());
|
|
DecreaseIndent();
|
|
|
|
if (!node.comparisons.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "comparisons:\n";
|
|
IncreaseIndent();
|
|
for (size_t i = 0; i < node.comparisons.size(); ++i)
|
|
{
|
|
const auto& comp = node.comparisons[i];
|
|
PrintIndent();
|
|
os_ << "[" << i << "] operator: ";
|
|
PrintOperator(comp.op);
|
|
os_ << "\n";
|
|
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "right:\n";
|
|
IncreaseIndent();
|
|
if (comp.right)
|
|
PrintExpression(comp.right.get());
|
|
else
|
|
os_ << "(null)\n";
|
|
DecreaseIndent();
|
|
DecreaseIndent();
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitUnaryExpression(UnaryExpression& node)
|
|
{
|
|
PrintNodeHeader("UnaryExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "operator: ";
|
|
PrintOperator(node.op);
|
|
os_ << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "argument:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get());
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitTernaryExpression(TernaryExpression& node)
|
|
{
|
|
PrintNodeHeader("TernaryExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "condition:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.condition.get());
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "consequence:\n";
|
|
IncreaseIndent();
|
|
if (node.consequence)
|
|
PrintExpression(node.consequence.get());
|
|
else
|
|
os_ << "(null)\n";
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "alternative:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.alternative.get());
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitCallExpression(CallExpression& node)
|
|
{
|
|
PrintNodeHeader("CallExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "callee:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.callee.get());
|
|
DecreaseIndent();
|
|
|
|
if (!node.arguments.empty())
|
|
{
|
|
for (const auto& arg : node.arguments)
|
|
{
|
|
PrintIndent();
|
|
os_ << "argument:\n";
|
|
if (arg.name)
|
|
{
|
|
IncreaseIndent();
|
|
os_ << "named(" << &arg.name << "): ";
|
|
DecreaseIndent();
|
|
os_ << "\n";
|
|
}
|
|
if (arg.value)
|
|
{
|
|
IncreaseIndent();
|
|
PrintExpression(arg.value.get());
|
|
DecreaseIndent();
|
|
}
|
|
else
|
|
{
|
|
os_ << "(null)\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitAttributeExpression(AttributeExpression& node)
|
|
{
|
|
PrintNodeHeader("AttributeExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "object:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.object.get());
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "attribute: " << node.attribute << "\n";
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitSubscriptExpression(SubscriptExpression& node)
|
|
{
|
|
PrintNodeHeader("SubscriptExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "value:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.value.get());
|
|
DecreaseIndent();
|
|
|
|
if (!node.indices.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "indices:\n";
|
|
IncreaseIndent();
|
|
for (size_t i = 0; i < node.indices.size(); ++i)
|
|
{
|
|
const auto& idx = node.indices[i];
|
|
PrintIndent();
|
|
os_ << "[" << i << "] ";
|
|
|
|
if (idx.is_empty_slice)
|
|
{
|
|
os_ << "empty_slice\n";
|
|
}
|
|
else if (idx.is_slice)
|
|
{
|
|
os_ << "slice:\n";
|
|
IncreaseIndent();
|
|
if (idx.start)
|
|
{
|
|
PrintIndent();
|
|
os_ << "start:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(idx.start.get());
|
|
DecreaseIndent();
|
|
}
|
|
if (idx.end)
|
|
{
|
|
PrintIndent();
|
|
os_ << "end:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(idx.end.get());
|
|
DecreaseIndent();
|
|
}
|
|
if (idx.step)
|
|
{
|
|
PrintIndent();
|
|
os_ << "step:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(idx.step.get());
|
|
DecreaseIndent();
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
else if (idx.start)
|
|
{
|
|
os_ << "index:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(idx.start.get());
|
|
DecreaseIndent();
|
|
}
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitArrayExpression(ArrayExpression& node)
|
|
{
|
|
PrintNodeHeader("ArrayExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
if (!node.elements.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "elements:\n";
|
|
IncreaseIndent();
|
|
for (size_t i = 0; i < node.elements.size(); ++i)
|
|
{
|
|
const auto& elem = node.elements[i];
|
|
PrintIndent();
|
|
os_ << "[" << i << "] ";
|
|
|
|
if (elem.is_nested)
|
|
{
|
|
os_ << "nested:\n";
|
|
IncreaseIndent();
|
|
if (elem.value)
|
|
PrintExpression(elem.value.get());
|
|
DecreaseIndent();
|
|
}
|
|
else if (elem.key)
|
|
{
|
|
os_ << "key_value:\n";
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "key:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(elem.key.get());
|
|
DecreaseIndent();
|
|
PrintIndent();
|
|
os_ << "value:\n";
|
|
IncreaseIndent();
|
|
if (elem.value)
|
|
PrintExpression(elem.value.get());
|
|
DecreaseIndent();
|
|
DecreaseIndent();
|
|
}
|
|
else if (elem.value)
|
|
{
|
|
os_ << "value:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(elem.value.get());
|
|
DecreaseIndent();
|
|
}
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitAnonymousFunctionExpression(AnonymousFunctionExpression& node)
|
|
{
|
|
PrintNodeHeader("AnonymousFunctionExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintSignature(node.signature);
|
|
|
|
if (node.body)
|
|
{
|
|
PrintIndent();
|
|
os_ << "body:\n";
|
|
IncreaseIndent();
|
|
node.body->Accept(*this);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPrefixIncrementExpression(PrefixIncrementExpression& node)
|
|
{
|
|
PrintNodeHeader("PrefixIncrementExpression", node.location);
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "argument:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get());
|
|
DecreaseIndent();
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPrefixDecrementExpression(PrefixDecrementExpression& node)
|
|
{
|
|
PrintNodeHeader("PrefixDecrementExpression", node.location);
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "argument:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get());
|
|
DecreaseIndent();
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPostfixIncrementExpression(PostfixIncrementExpression& node)
|
|
{
|
|
PrintNodeHeader("PostfixIncrementExpression", node.location);
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "argument:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get());
|
|
DecreaseIndent();
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPostfixDecrementExpression(PostfixDecrementExpression& node)
|
|
{
|
|
PrintNodeHeader("PostfixDecrementExpression", node.location);
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "argument:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get());
|
|
DecreaseIndent();
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitFunctionPointerExpression(FunctionPointerExpression& node)
|
|
{
|
|
PrintNodeHeader("FunctionPointerExpression", node.location);
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "argument:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.argument.get());
|
|
DecreaseIndent();
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitAssignmentExpression(AssignmentExpression& node)
|
|
{
|
|
PrintNodeHeader("AssignmentExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "operator: ";
|
|
PrintOperator(node.op);
|
|
os_ << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "left:\n";
|
|
IncreaseIndent();
|
|
PrintLeftHandSide(node.left);
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "right:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.right.get());
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitExpressionStatement(ExpressionStatement& node)
|
|
{
|
|
PrintNodeHeader("ExpressionStatement", node.location);
|
|
IncreaseIndent();
|
|
if (node.expression)
|
|
PrintExpression(node.expression.get());
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitVarStatement(VarStatement& node)
|
|
{
|
|
PrintNodeHeader("VarStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
if (!node.declarations.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "declarations:\n";
|
|
IncreaseIndent();
|
|
for (const auto& decl : node.declarations)
|
|
{
|
|
if (decl)
|
|
decl->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitStaticStatement(StaticStatement& node)
|
|
{
|
|
PrintNodeHeader("StaticStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
if (!node.declarations.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "declarations:\n";
|
|
IncreaseIndent();
|
|
for (const auto& decl : node.declarations)
|
|
{
|
|
if (decl)
|
|
decl->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitGlobalStatement(GlobalStatement& node)
|
|
{
|
|
PrintNodeHeader("GlobalStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
if (!node.declarations.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "declarations:\n";
|
|
IncreaseIndent();
|
|
for (const auto& decl : node.declarations)
|
|
{
|
|
if (decl)
|
|
decl->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitConstStatement(ConstStatement& node)
|
|
{
|
|
PrintNodeHeader("ConstStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name << "\n";
|
|
|
|
if (node.type_name)
|
|
{
|
|
PrintIndent();
|
|
os_ << "type: " << *node.type_name << "\n";
|
|
}
|
|
|
|
PrintIndent();
|
|
os_ << "value:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.value.get());
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitAssignmentStatement(AssignmentStatement& node)
|
|
{
|
|
PrintNodeHeader("AssignmentStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "operator: ";
|
|
PrintOperator(node.op);
|
|
os_ << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "left:\n";
|
|
IncreaseIndent();
|
|
PrintLeftHandSide(node.left);
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "right:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.right.get());
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitBlockStatement(BlockStatement& node)
|
|
{
|
|
PrintNodeHeader("BlockStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
if (!node.statements.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "statements: (" << node.statements.size() << ")\n";
|
|
IncreaseIndent();
|
|
for (const auto& stmt : node.statements)
|
|
{
|
|
if (stmt)
|
|
stmt->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
else
|
|
{
|
|
PrintIndent();
|
|
os_ << "(empty block)\n";
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitIfStatement(IfStatement& node)
|
|
{
|
|
PrintNodeHeader("IfStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
for (size_t i = 0; i < node.branches.size(); ++i)
|
|
{
|
|
const auto& branch = node.branches[i];
|
|
|
|
PrintIndent();
|
|
if (i == 0)
|
|
os_ << "if branch:\n";
|
|
else if (branch.condition)
|
|
os_ << "else if branch:\n";
|
|
else
|
|
os_ << "else branch:\n";
|
|
|
|
IncreaseIndent();
|
|
|
|
if (branch.condition)
|
|
{
|
|
PrintIndent();
|
|
os_ << "condition:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(branch.condition.get());
|
|
DecreaseIndent();
|
|
}
|
|
|
|
PrintIndent();
|
|
os_ << "body:\n";
|
|
IncreaseIndent();
|
|
if (branch.body)
|
|
branch.body->Accept(*this);
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitForInStatement(ForInStatement& node)
|
|
{
|
|
PrintNodeHeader("ForInStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "key: " << node.key << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "value: " << node.value << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "collection:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.collection.get());
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "body:\n";
|
|
IncreaseIndent();
|
|
if (node.body)
|
|
node.body->Accept(*this);
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitForToStatement(ForToStatement& node)
|
|
{
|
|
PrintNodeHeader("ForToStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "counter: " << node.counter << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "direction: " << (node.is_downto ? "downto" : "to") << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "start:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.start.get());
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "end:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.end.get());
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "body:\n";
|
|
IncreaseIndent();
|
|
if (node.body)
|
|
node.body->Accept(*this);
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitWhileStatement(WhileStatement& node)
|
|
{
|
|
PrintNodeHeader("WhileStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "condition:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.condition.get());
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "body:\n";
|
|
IncreaseIndent();
|
|
if (node.body)
|
|
node.body->Accept(*this);
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitRepeatStatement(RepeatStatement& node)
|
|
{
|
|
PrintNodeHeader("RepeatStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "body: (" << node.body.size() << " statements)\n";
|
|
IncreaseIndent();
|
|
for (const auto& stmt : node.body)
|
|
{
|
|
if (stmt)
|
|
stmt->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "condition:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.condition.get());
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitCaseStatement(CaseStatement& node)
|
|
{
|
|
PrintNodeHeader("CaseStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "discriminant:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.discriminant.get());
|
|
DecreaseIndent();
|
|
|
|
if (!node.branches.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "branches:\n";
|
|
IncreaseIndent();
|
|
for (size_t i = 0; i < node.branches.size(); ++i)
|
|
{
|
|
const auto& branch = node.branches[i];
|
|
PrintIndent();
|
|
os_ << "branch " << i << ":\n";
|
|
IncreaseIndent();
|
|
|
|
if (!branch.values.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "values:\n";
|
|
IncreaseIndent();
|
|
for (const auto& val : branch.values)
|
|
{
|
|
PrintExpression(val.get());
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
PrintIndent();
|
|
os_ << "body:\n";
|
|
IncreaseIndent();
|
|
if (branch.body)
|
|
branch.body->Accept(*this);
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
if (node.default_case)
|
|
{
|
|
PrintIndent();
|
|
os_ << "default:\n";
|
|
IncreaseIndent();
|
|
node.default_case->Accept(*this);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitTryStatement(TryStatement& node)
|
|
{
|
|
PrintNodeHeader("TryStatement", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "try:\n";
|
|
IncreaseIndent();
|
|
if (node.try_body)
|
|
node.try_body->Accept(*this);
|
|
DecreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "except:\n";
|
|
IncreaseIndent();
|
|
if (node.except_body)
|
|
node.except_body->Accept(*this);
|
|
DecreaseIndent();
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitBreakStatement(BreakStatement& node)
|
|
{
|
|
PrintNodeHeader("BreakStatement", node.location);
|
|
}
|
|
|
|
void DebugPrinter::VisitContinueStatement(ContinueStatement& node)
|
|
{
|
|
PrintNodeHeader("ContinueStatement", node.location);
|
|
}
|
|
|
|
void DebugPrinter::VisitReturnStatement(ReturnStatement& node)
|
|
{
|
|
PrintNodeHeader("ReturnStatement", node.location);
|
|
|
|
if (node.value)
|
|
{
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "value:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.value.get());
|
|
DecreaseIndent();
|
|
DecreaseIndent();
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::VisitUsesStatement(UsesStatement& node)
|
|
{
|
|
PrintNodeHeader("UsesStatement", node.location);
|
|
IncreaseIndent();
|
|
PrintIndent();
|
|
os_ << "module: [";
|
|
for (size_t i = 0; i < node.modules.size(); i++)
|
|
{
|
|
if (i > 0)
|
|
os_ << ", ";
|
|
os_ << node.modules[i];
|
|
}
|
|
os_ << "]\n";
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitFunctionDefinition(FunctionDefinition& node)
|
|
{
|
|
PrintNodeHeader("FunctionDefinition", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name;
|
|
if (node.is_overload)
|
|
os_ << " [overload]";
|
|
os_ << "\n";
|
|
|
|
PrintSignature(node.signature);
|
|
|
|
if (node.body)
|
|
{
|
|
PrintIndent();
|
|
os_ << "body:\n";
|
|
IncreaseIndent();
|
|
node.body->Accept(*this);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitFunctionDeclaration(FunctionDeclaration& node)
|
|
{
|
|
PrintNodeHeader("FunctionDeclaration", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name;
|
|
if (node.is_overload)
|
|
os_ << " [overload]";
|
|
os_ << "\n";
|
|
PrintSignature(node.signature);
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitVarDeclaration(VarDeclaration& node)
|
|
{
|
|
PrintNodeHeader("VarDeclaration", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name << "\n";
|
|
|
|
if (node.type_name)
|
|
{
|
|
PrintIndent();
|
|
os_ << "type: " << *node.type_name << "\n"; // 修正:使用 * 而不是 &
|
|
}
|
|
|
|
if (node.initial_value)
|
|
{
|
|
PrintIndent();
|
|
os_ << "initial_value:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.initial_value.get());
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitStaticDeclaration(StaticDeclaration& node)
|
|
{
|
|
PrintNodeHeader("StaticDeclaration", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name << "\n";
|
|
|
|
// 添加引用修饰符打印
|
|
if (node.reference_modifier != ReferenceModifier::kNone)
|
|
{
|
|
PrintIndent();
|
|
os_ << "reference_modifier: ";
|
|
PrintReferenceModifier(node.reference_modifier);
|
|
os_ << "\n";
|
|
}
|
|
|
|
if (node.type_name)
|
|
{
|
|
PrintIndent();
|
|
os_ << "type: " << *node.type_name << "\n"; // 修正:使用 * 而不是 &
|
|
}
|
|
|
|
if (node.initial_value)
|
|
{
|
|
PrintIndent();
|
|
os_ << "initial_value:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.initial_value.get());
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitGlobalDeclaration(GlobalDeclaration& node)
|
|
{
|
|
PrintNodeHeader("GlobalDeclaration", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name << "\n";
|
|
|
|
if (node.type_name)
|
|
{
|
|
PrintIndent();
|
|
os_ << "type: " << *node.type_name << "\n";
|
|
}
|
|
|
|
if (node.initial_value)
|
|
{
|
|
PrintIndent();
|
|
os_ << "initial_value:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.initial_value.get());
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitFieldDeclaration(FieldDeclaration& node)
|
|
{
|
|
PrintNodeHeader("FieldDeclaration", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name << "\n";
|
|
|
|
// 添加引用修饰符打印
|
|
if (node.reference_modifier != ReferenceModifier::kNone)
|
|
{
|
|
PrintIndent();
|
|
os_ << "reference_modifier: ";
|
|
PrintReferenceModifier(node.reference_modifier);
|
|
os_ << "\n";
|
|
}
|
|
|
|
if (node.type_name)
|
|
{
|
|
PrintIndent();
|
|
os_ << "type: " << *node.type_name << "\n"; // 修正:使用 * 而不是 &
|
|
}
|
|
|
|
if (node.initial_value)
|
|
{
|
|
PrintIndent();
|
|
os_ << "initial_value:\n";
|
|
IncreaseIndent();
|
|
PrintExpression(node.initial_value.get());
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitUnpackPattern(UnpackPattern& node)
|
|
{
|
|
PrintNodeHeader("UnpackPattern", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "names: [";
|
|
for (size_t i = 0; i < node.names.size(); ++i)
|
|
{
|
|
if (i > 0)
|
|
os_ << ", ";
|
|
os_ << node.names[i];
|
|
}
|
|
os_ << "]\n";
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitTSSQLExpression(TSSQLExpression& node)
|
|
{
|
|
PrintNodeHeader("TSSQLExpression", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "sql_type: ";
|
|
switch (node.sql_type)
|
|
{
|
|
case TSSQLExpressionType::kSelect:
|
|
os_ << "SELECT";
|
|
break;
|
|
case TSSQLExpressionType::kSSelect:
|
|
os_ << "SSELECT";
|
|
break;
|
|
case TSSQLExpressionType::kVSelect:
|
|
os_ << "VSELECT";
|
|
break;
|
|
case TSSQLExpressionType::kMSelect:
|
|
os_ << "MSELECT";
|
|
break;
|
|
case TSSQLExpressionType::kUpdate:
|
|
os_ << "UPDATE";
|
|
break;
|
|
case TSSQLExpressionType::kDelete:
|
|
os_ << "DELETE";
|
|
break;
|
|
case TSSQLExpressionType::kInsert:
|
|
os_ << "INSERT";
|
|
break;
|
|
}
|
|
os_ << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "raw_sql: " << node.raw_sql << "\n";
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::PrintError(const ParseError& error)
|
|
{
|
|
PrintIndent();
|
|
os_ << "ERROR ";
|
|
PrintLocation(error.location);
|
|
os_ << " [" << error.node_type << "]: " << error.message << "\n";
|
|
}
|
|
|
|
void DebugPrinter::Print(const ASTNode* node)
|
|
{
|
|
if (!node)
|
|
{
|
|
PrintIndent();
|
|
os_ << "(null node)\n";
|
|
return;
|
|
}
|
|
|
|
const_cast<ASTNode&>(*node).Accept(*this);
|
|
}
|
|
|
|
void DebugPrinter::PrintStatements(const std::vector<StatementPtr>& statements)
|
|
{
|
|
for (const auto& stmt : statements)
|
|
{
|
|
if (stmt)
|
|
Print(stmt.get());
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintParseResult(const ParseResult& result)
|
|
{
|
|
os_ << "==================== Parse Result ====================\n";
|
|
os_ << "Total Statements: " << result.statements.size() << "\n";
|
|
os_ << "Total Errors: " << result.errors.size() << "\n";
|
|
os_ << "\n";
|
|
|
|
if (!result.errors.empty())
|
|
{
|
|
os_ << "Errors:\n";
|
|
IncreaseIndent();
|
|
for (const auto& error : result.errors)
|
|
{
|
|
PrintError(error);
|
|
}
|
|
DecreaseIndent();
|
|
os_ << "\n";
|
|
}
|
|
|
|
if (!result.statements.empty())
|
|
{
|
|
os_ << "AST Statements:\n";
|
|
IncreaseIndent();
|
|
PrintStatements(result.statements);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
os_ << "==================== End ====================\n";
|
|
}
|
|
|
|
void DebugPrinter::VisitUnitDefinition(UnitDefinition& node)
|
|
{
|
|
PrintNodeHeader("UnitDefinition", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name << "\n";
|
|
|
|
if (!node.interface_statements.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "interface: (" << node.interface_statements.size() << " statements)\n";
|
|
IncreaseIndent();
|
|
for (const auto& stmt : node.interface_statements)
|
|
{
|
|
if (stmt)
|
|
stmt->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
else
|
|
{
|
|
PrintIndent();
|
|
os_ << "interface: (empty)\n";
|
|
}
|
|
|
|
if (!node.implementation_statements.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "implementation: (" << node.implementation_statements.size() << " statements)\n";
|
|
IncreaseIndent();
|
|
for (const auto& stmt : node.implementation_statements)
|
|
{
|
|
if (stmt)
|
|
stmt->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
else
|
|
{
|
|
PrintIndent();
|
|
os_ << "implementation: (empty)\n";
|
|
}
|
|
|
|
if (!node.initialization_statements.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "initialization: (" << node.initialization_statements.size() << " statements)\n";
|
|
IncreaseIndent();
|
|
for (const auto& stmt : node.initialization_statements)
|
|
{
|
|
if (stmt)
|
|
stmt->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
if (!node.finalization_statements.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "finalization: (" << node.finalization_statements.size() << " statements)\n";
|
|
IncreaseIndent();
|
|
for (const auto& stmt : node.finalization_statements)
|
|
{
|
|
if (stmt)
|
|
stmt->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitClassDefinition(ClassDefinition& node)
|
|
{
|
|
PrintNodeHeader("ClassDefinition", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name << "\n";
|
|
|
|
if (!node.parent_classes.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "parents: [";
|
|
for (size_t i = 0; i < node.parent_classes.size(); ++i)
|
|
{
|
|
if (i > 0)
|
|
os_ << ", ";
|
|
os_ << node.parent_classes[i];
|
|
}
|
|
os_ << "]\n";
|
|
}
|
|
|
|
if (!node.members.empty())
|
|
{
|
|
PrintIndent();
|
|
os_ << "members: (" << node.members.size() << ")\n";
|
|
IncreaseIndent();
|
|
for (const auto& member : node.members)
|
|
{
|
|
if (member)
|
|
member->Accept(*this);
|
|
}
|
|
DecreaseIndent();
|
|
}
|
|
else
|
|
{
|
|
PrintIndent();
|
|
os_ << "members: (empty)\n";
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitClassMember(ClassMember& node)
|
|
{
|
|
PrintNodeHeader("ClassMember", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "access: ";
|
|
PrintAccessModifier(node.access_modifier);
|
|
os_ << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "member:\n";
|
|
IncreaseIndent();
|
|
|
|
std::visit([this](auto&& member) {
|
|
if (member)
|
|
{
|
|
member->Accept(*this);
|
|
}
|
|
else
|
|
{
|
|
PrintIndent();
|
|
os_ << "(null member)\n";
|
|
}
|
|
},
|
|
node.member);
|
|
|
|
DecreaseIndent();
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitMethodDeclaration(MethodDeclaration& node)
|
|
{
|
|
PrintNodeHeader("MethodDeclaration", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name;
|
|
|
|
if (node.method_type == MethodType::kConstructor)
|
|
os_ << " [constructor]";
|
|
else if (node.method_type == MethodType::kDestructor)
|
|
os_ << " [destructor]";
|
|
|
|
if (node.is_class_method)
|
|
os_ << " [class]";
|
|
if (node.is_operator_overload)
|
|
os_ << " [operator: " << node.operator_symbol << "]";
|
|
os_ << "\n";
|
|
|
|
if (node.modifier != MethodModifier::kNone)
|
|
{
|
|
PrintIndent();
|
|
os_ << "modifier: ";
|
|
PrintMethodModifier(node.modifier);
|
|
os_ << "\n";
|
|
}
|
|
|
|
PrintSignature(node.signature);
|
|
|
|
if (node.body)
|
|
{
|
|
PrintIndent();
|
|
os_ << "body:\n";
|
|
IncreaseIndent();
|
|
node.body->Accept(*this);
|
|
DecreaseIndent();
|
|
}
|
|
else
|
|
{
|
|
PrintIndent();
|
|
os_ << "body: (none - declaration only)\n";
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitPropertyDeclaration(PropertyDeclaration& node)
|
|
{
|
|
PrintNodeHeader("PropertyDeclaration", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "name: " << node.name << "\n";
|
|
|
|
if (node.type_name)
|
|
{
|
|
PrintIndent();
|
|
os_ << "type: " << *node.type_name << "\n";
|
|
}
|
|
|
|
if (node.index_value)
|
|
{
|
|
PrintIndent();
|
|
os_ << "index: " << *node.index_value << "\n";
|
|
}
|
|
|
|
if (node.read_accessor)
|
|
{
|
|
PrintIndent();
|
|
os_ << "read: " << *node.read_accessor << "\n";
|
|
}
|
|
|
|
if (node.write_accessor)
|
|
{
|
|
PrintIndent();
|
|
os_ << "write: " << *node.write_accessor << "\n";
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::VisitExternalMethodDefinition(ExternalMethodDefinition& node)
|
|
{
|
|
PrintNodeHeader("ExternalMethodDefinition", node.location);
|
|
IncreaseIndent();
|
|
|
|
PrintIndent();
|
|
os_ << "class: " << node.owner_class << "\n";
|
|
|
|
PrintIndent();
|
|
os_ << "method: " << node.name;
|
|
|
|
if (node.method_type == MethodType::kConstructor)
|
|
os_ << " [constructor]";
|
|
else if (node.method_type == MethodType::kDestructor)
|
|
os_ << " [destructor]";
|
|
if (node.is_class_method)
|
|
os_ << " [class]";
|
|
if (node.is_operator_overload)
|
|
os_ << " [operator: " << node.operator_symbol << "]";
|
|
os_ << "\n";
|
|
|
|
if (node.modifier != MethodModifier::kNone)
|
|
{
|
|
PrintIndent();
|
|
os_ << "modifier: ";
|
|
PrintMethodModifier(node.modifier);
|
|
os_ << "\n";
|
|
}
|
|
|
|
PrintSignature(node.signature);
|
|
|
|
if (node.body)
|
|
{
|
|
PrintIndent();
|
|
os_ << "body:\n";
|
|
IncreaseIndent();
|
|
node.body->Accept(*this);
|
|
DecreaseIndent();
|
|
}
|
|
|
|
DecreaseIndent();
|
|
}
|
|
|
|
void DebugPrinter::PrintAccessModifier(AccessModifier modifier)
|
|
{
|
|
switch (modifier)
|
|
{
|
|
case AccessModifier::kPublic:
|
|
os_ << "public";
|
|
break;
|
|
case AccessModifier::kProtected:
|
|
os_ << "protected";
|
|
break;
|
|
case AccessModifier::kPrivate:
|
|
os_ << "private";
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DebugPrinter::PrintMethodModifier(MethodModifier modifier)
|
|
{
|
|
switch (modifier)
|
|
{
|
|
case MethodModifier::kNone:
|
|
os_ << "none";
|
|
break;
|
|
case MethodModifier::kVirtual:
|
|
os_ << "virtual";
|
|
break;
|
|
case MethodModifier::kOverride:
|
|
os_ << "override";
|
|
break;
|
|
case MethodModifier::kOverload:
|
|
os_ << "overload";
|
|
break;
|
|
}
|
|
}
|
|
|
|
std::string DebugString(const ASTNode* node)
|
|
{
|
|
std::ostringstream oss;
|
|
DebugPrinter printer(oss);
|
|
printer.Print(node);
|
|
return oss.str();
|
|
}
|
|
|
|
std::string DebugString(const ParseResult& result)
|
|
{
|
|
std::ostringstream oss;
|
|
DebugPrinter printer(oss);
|
|
printer.PrintParseResult(result);
|
|
return oss.str();
|
|
}
|
|
|
|
void DebugPrint(const ASTNode* node)
|
|
{
|
|
DebugPrinter printer(std::cout);
|
|
printer.Print(node);
|
|
}
|
|
|
|
void DebugPrint(const ParseResult& result)
|
|
{
|
|
DebugPrinter printer(std::cout);
|
|
printer.PrintParseResult(result);
|
|
}
|
|
}
|