#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cmath>
#include <stack>
#include <functional>
#include <set>
#include <queue>
#include <string>
#include <memory>
#include <map>
#include <iomanip>
#include <sstream>
#include <cassert>
using std::string;
using std::vector;
using std::stringstream;
class FormatVisitor : public BaseVisitor {
vector<string> res;
stringstream s;
public:
void Visit(const BaseNode* node) override {
node->Visit(this);
};
void Visit(const ClassDeclarationNode* node) override {
string shift = s.str();
s << "class " << node->ClassName() << " {";
res.push_back(s.str());
s.str("");
const vector<BaseNode*>& pub = node->PublicFields();
size_t len = pub.size();
if (len > 0) {
s << shift << " public:";
res.push_back(s.str());
s.str("");
for (int i = 0; i < len; ++i) {
s << " " << shift;
Visit(pub[i]);
s << ";";
res.push_back(s.str());
s.str("");
}
}
const vector<BaseNode*>& prot = node->ProtectedFields();
len = prot.size();
if (len > 0) {
res.push_back(s.str());
s.str("");
s << shift << " protected:";
res.push_back(s.str());
s.str("");
for (int i = 0; i < len; ++i) {
s << " " << shift;
Visit(prot[i]);
s << ";";
res.push_back(s.str());
s.str("");
}
}
const vector<BaseNode*>& priv = node->PrivateFields();
len = priv.size();
if (len > 0) {
res.push_back(s.str());
s.str("");
s << shift << " private:";
res.push_back(s.str());
s.str("");
for (int i = 0; i < len; ++i) {
s << " " << shift;
Visit(priv[i]);
s << ";";
res.push_back(s.str());
s.str("");
}
}
s << shift << "}";
};
void Visit(const VarDeclarationNode* node) override {
s << node->TypeName() << " " << node->VarName();
};
void Visit(const MethodDeclarationNode* node) override {
s << node->ReturnTypeName() << " " << node->MethodName() << "(";
const vector<BaseNode*>& arguments = node->Arguments();
size_t arguments_length = arguments.size();
if (arguments_length > 0) {
for (int i = 0; i < arguments_length - 1; ++i) {
Visit(arguments[i]);
s << ", ";
}
Visit(arguments[arguments_length - 1]);
}
s << ")";
}
const vector<string>& GetFormattedCode() {
s << ";";
res.push_back(s.str());
return res;
}
};