#include <vector>
#include <string>
#include <utility>
using std::vector;
using std::string;
class FormatVisitor
:
public BaseVisitor{
private:
vector < string > code_{};
uint32_t cur_pad{};
uint32_t cur_str{};
int const classSpace = 0;
int const classPadding = 4;
string startDeclaration(const string& type, const string& name) {
string
str(type + " " + name);
return str;
}
string stringWithPadd(const string& sourceStr, uint32_t param1,
const string& param2, char param3) {
string str = sourceStr;
int const start = 0;
str.insert(param1, param2, param3);
return str;
}
public:
void Visit(const BaseNode* node) override {
node->Visit(this);
}
void Visit(const ClassDeclarationNode* node) override {
auto tmp = startDeclaration("class", node->ClassName()) + " {";
code_[cur_str] += tmp;
tmp = stringWithPadd(" public:", 0, cur_pad, ' ');
code_.push_back(std::move(tmp));
cur_str += classSpace;
cur_pad += classPadding;
for (auto field : node->PublicFields()) {
cur_str++;
auto ss = stringWithPadd(string(""), 0, cur_pad, ' ');
code_.push_back(std::move(ss));
Visit(field);
code_[cur_str].push_back(';');
}
if (!node->ProtectedFields().empty()) {
code_.push_back("");
code_.push_back(" protected:");
cur_str += 2;
for (auto field : node->ProtectedFields()) {
cur_str++;
auto ss = stringWithPadd(string(""), 0, cur_pad, ' ');
code_.push_back(std::move(ss));
Visit(field);
code_[cur_str].push_back(';');
}
}
if (node->PrivateFields().size() != 0) {
code_.push_back("");
code_.push_back(" private:");
cur_str++;
cur_str++;
for (auto field : node->PrivateFields()) {
cur_str++;
auto ss = stringWithPadd(string(""), 0, cur_pad, ' ');
code_.push_back(std::move(ss));
Visit(field);
code_[cur_str].push_back(';');
}
}
cur_pad -= classPadding;
auto ss = stringWithPadd(string("}"), 0, cur_pad, ' ');
code_.push_back(std::move(ss))
cur_str++;
if (0 == cur_pad)
code_[cur_str].push_back(';');
};
void Visit(const VarDeclarationNode* node) override {
code_[cur_str] += startDeclaration(node->TypeName(), node->VarName());
};
void Visit(const MethodDeclarationNode* node) override {
string tmp = startDeclaration(node->ReturnTypeName(), node->MethodName());
tmp += "(";
code_[cur_str] += tmp;
for (auto*args : node->Arguments()) {
Visit(args);
code_[cur_str] += ", ";
}
if (!node->Arguments().empty()) {
code_[cur_str].pop_back();
code_[cur_str].pop_back();
}
code_[cur_str].push_back(')');
};
const std::vector<std::string>& GetFormattedCode() const {
return code_;
}
};