#include <iostream>
#include <cassert>
#include <string>
#include <memory>
#include <vector>
#include <fstream>
#include <sstream>
class FormatVisitor : public BaseVisitor {
public:
void Visit(const BaseNode* node) override {
node->Visit(this);
}
void Visit(const ClassDeclarationNode* node) override {
std::ostringstream line;
line << getCurrentIdent() << "class " << node->ClassName() << " {";
cachedCode.emplace_back(line.str());
ident_++;
if (!node->PublicFields().empty()) {
cachedCode.emplace_back(getCurrentIdent() + "public:");
ident_++;
for (auto field : node->PublicFields())
Visit(field);
ident_--;
}
if (!node->ProtectedFields().empty()) {
runThroughBlock("protected:", node->ProtectedFields());
cachedCode.emplace_back(getCurrentIdent() + "protected:");
ident_++;
for (auto field : node->ProtectedFields())
Visit(field);
ident_--;
}
if (!node->PrivateFields().empty()) {
cachedCode.emplace_back("");
cachedCode.emplace_back(getCurrentIdent() + "private:");
ident_++;
for (auto field : node->PrivateFields())
Visit(field);
ident_--;
}
ident_--;
cachedCode.emplace_back(getCurrentIdent() + "};");
};
void Visit(const VarDeclarationNode* node) override {
cachedCode.emplace_back(getCurrentIdent() + node->TypeName()
+ ' ' + node->VarName() + ';');
};
void Visit(const MethodDeclarationNode* node) override {
std::ostringstream line;
line << getCurrentIdent() << node->ReturnTypeName() << ' '
<< node->MethodName() << '(';
for (uint i = 0; i < node->Arguments().size(); ++i) {
if (i != 0) line << ", ";
auto arg = reinterpret_cast<VarDeclarationNode*>
(node->Arguments()[i]);
line << arg->TypeName() << ' ' << arg->VarName();
}
line << ");";
cachedCode.emplace_back(line.str());
};
const std::vector<std::string>& GetFormattedCode() const {
return cachedCode;
}
private:
int ident_ = 0;
std::string getCurrentIdent() const {
std::ostringstream res;
for (int i = 0; i < ident_; ++i)
res << " ";
return res.str();
}
std::vector<std::string> cachedCode = std::vector<std::string>();
};