#include <vector>
#include <utility>
#include <string>
using std::vector;
using std::string;
class FormatVisitor
:
public BaseVisitor{
private:
vector < string > code_{ "" };
uint32_t padding_{};
uint32_t workingStr_{};
int const classSpace = 1;
int const fieldSpace = 2;
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,
uint32_t const& param2, char param3) {
string str = sourceStr;
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_[workingStr_] += tmp;
tmp = stringWithPadd(string(" public:"), 0, padding_, ' ');
code_.push_back(std::move(tmp));
workingStr_ += classSpace;
padding_ += classPadding;
for (auto field : node->PublicFields()) {
workingStr_++;
code_.push_back(string("").insert(0, padding_, ' '));
Visit(field);
code_[workingStr_].push_back(';');
}
if (!node->ProtectedFields().empty()) {
code_.push_back("");
code_.push_back(" protected:");
workingStr_ += fieldSpace;
for (auto field : node->ProtectedFields()) {
workingStr_++;
auto ss = stringWithPadd(string(""), 0, padding_, ' ');
code_.push_back(std::move(ss));
Visit(field);
code_[workingStr_].push_back(';');
}
}
if (node->PrivateFields().size() != 0) {
code_.push_back("");
code_.push_back(" private:");
workingStr_ += fieldSpace;
for (auto field : node->PrivateFields()) {
workingStr_++;
auto ss = stringWithPadd(string(""), 0, padding_, ' ');
code_.push_back(std::move(ss));
Visit(field);
code_[workingStr_].push_back(';');
}
}
padding_ -= classPadding;
auto ss = stringWithPadd(string("}"), 0, padding_, ' ');
code_.push_back(std::move(ss));
workingStr_++;
if (0 == padding_)
code_[workingStr_].push_back(';');
};
void Visit(const VarDeclarationNode* node) override {
code_[workingStr_] += startDeclaration(node->TypeName(), node->VarName());
};
void Visit(const MethodDeclarationNode* node) override {
string tmp = startDeclaration(node->ReturnTypeName(), node->MethodName());
tmp += "(";
code_[workingStr_] += tmp;
for (auto args : node->Arguments()) {
Visit(args);
code_[workingStr_] += ", ";
}
if (!node->Arguments().empty()) {
code_[workingStr_].pop_back();
code_[workingStr_].pop_back();
}
code_[workingStr_].push_back(')');
};
const std::vector<std::string>& GetFormattedCode() const {
return code_;
}
};