#pragma once #include #include #include #include #include using namespace Fig; using namespace Fig::Ast; class AstPrinter { public: void print(const AstBase &node, int indent = 0) { if (!node) return; switch (node->getType()) { case AstType::BinaryExpr: printBinaryExpr(std::static_pointer_cast(node), indent); break; case AstType::UnaryExpr: printUnaryExpr(std::static_pointer_cast(node), indent); break; case AstType::ValueExpr: printValueExpr(std::static_pointer_cast(node), indent); break; case AstType::VarDefSt: printVarDef(std::static_pointer_cast(node), indent); break; case AstType::VarExpr: printVarExpr(std::static_pointer_cast(node), indent); break; case AstType::BlockStatement: printBlockStatement(std::static_pointer_cast(node), indent); break; case AstType::FunctionCall: printFunctionCall(std::static_pointer_cast(node), indent); break; case AstType::FunctionDefSt: printFunctionSt(std::static_pointer_cast(node), indent); break; case AstType::IfSt: printIfSt(std::static_pointer_cast(node), indent); break; case AstType::TernaryExpr: printTernaryExpr(std::static_pointer_cast(node), indent); break; default: printIndent(indent); std::cout << "Unknown AST Node\n"; } } private: void printIndent(int indent) { std::cout << std::string(indent, ' '); } void printFString(const Fig::FString &fstr, int indent) { printIndent(indent); std::cout << "FString: \""; std::cout.write(reinterpret_cast(fstr.data()), fstr.size()); std::cout << "\"\n"; } template void printEnum(const EnumT &value, int indent) { printIndent(indent); std::cout << "Enum: " << magic_enum::enum_name(value) << "\n"; } void printBinaryExpr(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "BinaryExpr\n"; printEnum(node->op, indent + 2); printIndent(indent + 2); std::cout << "Left:\n"; print(node->lexp, indent + 4); printIndent(indent + 2); std::cout << "Right:\n"; print(node->rexp, indent + 4); } void printUnaryExpr(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "UnaryExpr\n"; printEnum(node->op, indent + 2); printIndent(indent + 2); std::cout << "Expr:\n"; print(node->exp, indent + 4); } void printValueExpr(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "ValueExpr\n"; printFString(node->val.toString(), indent + 2); } void printVarDef(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "VarDef\n"; printIndent(indent + 2); std::cout << "Name: "; printFString(node->name, 0); printIndent(indent + 2); std::cout << "Type: "; printFString(node->typeName, 0); if (node->expr) { printIndent(indent + 2); std::cout << "InitExpr:\n"; print(node->expr, indent + 4); } } void printVarExpr(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "VarExpr\n"; printIndent(indent + 2); std::cout << "Name: "; printFString(node->name, 0); } void printBlockStatement(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "BlockStatement\n"; for (const auto &stmt : node->stmts) { print(stmt, indent + 2); } } void printFunctionCall(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "FunctionCall\n"; printIndent(indent + 2); printIndent(indent + 2); } void printFunctionSt(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "FunctionSt\n"; printIndent(indent + 2); std::cout << "Name: "; printFString(node->name, 0); printIndent(indent + 2); printIndent(indent + 2); std::cout << "Body:\n"; print(node->body, indent + 4); } void printIfSt(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "IfSt\n"; printIndent(indent + 2); std::cout << "Condition:\n"; print(node->condition, indent + 4); printIndent(indent + 2); } void printTernaryExpr(const std::shared_ptr &node, int indent) { printIndent(indent); std::cout << "TernaryExpr\n"; printIndent(indent + 2); std::cout << "Condition:\n"; print(node->condition, indent + 4); printIndent(indent + 2); std::cout << "TrueExpr:\n"; print(node->valueT, indent + 4); printIndent(indent + 2); std::cout << "FalseExpr:\n"; print(node->valueF, indent + 4); } };