#pragma once
#include <vector>
#include <string>
class FormatVisitor : public BaseVisitor {
public:
void Visit(const BaseNode* node) override {
node->Visit(this);
}
void Visit(const ClassDeclarationNode* node) override {
if (!formatted_code.size()) {
formatted_code.push_back("class " + node->ClassName() + " {");
} else {
std::string spaces;
bool flag = true;
std::string word;
reverse(formatted_code.back().begin(),
formatted_code.back().end());
for (const auto& letter
: formatted_code[formatted_code.size() - 2]) {
if (letter != ' ') {
flag = false;
word += letter;
} else if (flag) {
spaces+=' ';
} else {
break;
}
}
if (word == "private:" ||
word == "public:" ||
word == "protected:") {
formatted_code.back() += spaces + " ";
} else {
formatted_code.back() += spaces;
}
reverse(formatted_code.back().begin(),
formatted_code.back().end());
formatted_code.back() += "class " + node->ClassName() + " {";
}
if (node->PublicFields().size()) {
formatted_code.push_back("public:");
reverse(formatted_code.back().begin(),
formatted_code.back().end());
formatted_code.back() += findWord() + " ";
reverse(formatted_code.back().begin(),
formatted_code.back().end());
for (const auto& fields : node->PublicFields()) {
formatted_code.push_back("");
Visit(fields);
if (formatted_code.back().back() != ';')
formatted_code.back() += ";";
std::string spaces;
bool flag = true;
std::string word;
std::reverse(formatted_code.back().begin(),
formatted_code.back().end());
for (const auto& letter
: formatted_code[formatted_code.size() - 2]) {
if (letter != ' ') {
flag = false;
word += letter;
} else if (flag) {
spaces += ' ';
} else {
break;
}
}
if (word == "private:" ||
word == "public:" ||
word == "protected:") {
formatted_code.back() += spaces + " ";
} else {
formatted_code.back() += spaces;
}
reverse(formatted_code.back().begin(),
formatted_code.back().end());
}
if (node->ProtectedFields().size() || node->PrivateFields().size())
formatted_code.push_back("");
}
if (node->ProtectedFields().size()) {
formatted_code.push_back("protected:");
reverse(formatted_code.back().begin(),
formatted_code.back().end());
formatted_code.back() += findWord() + " ";
reverse(formatted_code.back().begin(),
formatted_code.back().end());
for (const auto& fields : node->ProtectedFields()) {
formatted_code.push_back("");
Visit(fields);
if (formatted_code.back().back() != ';')
formatted_code.back() += ";";
std::string spaces;
bool flag = true;
std::string word;
reverse(formatted_code.back().begin(),
formatted_code.back().end());
for (const auto& letter
: formatted_code[formatted_code.size() - 2]) {
if (letter != ' ') {
flag = false;
word += letter;
} else if (flag) {
spaces += ' ';
} else {
break;
}
}
if (word == "private:" ||
word == "public:" ||
word == "protected:") {
formatted_code.back() += spaces + " ";
} else {
formatted_code.back() += spaces;
}
std::reverse(formatted_code.back().begin(),
formatted_code.back().end());
}
if (node->PrivateFields().size())
formatted_code.push_back("");
}
if (node->PrivateFields().size()) {
formatted_code.push_back("private:");
reverse(formatted_code.back().begin(),
formatted_code.back().end());
formatted_code.back() += findWord() + " ";
reverse(formatted_code.back().begin(),
formatted_code.back().end());
for (const auto& fields : node->PrivateFields()) {
formatted_code.push_back("");
Visit(fields);
if (formatted_code.back().back() != ';')
formatted_code.back() += ";";
reverse(formatted_code.back().begin(),
formatted_code.back().end());
if (formatted_code.back()[1] != '}') {
reverse(formatted_code.back().begin(),
formatted_code.back().end());
std::string spaces;
bool flag = true;
std::string word;
reverse(formatted_code.back().begin(),
formatted_code.back().end());
for (const auto& letter
: formatted_code[formatted_code.size() - 2]) {
if (letter != ' ') {
flag = false;
word += letter;
} else if (flag) {
spaces += ' ';
} else {
break;
}
}
if (word == "private:" ||
word == "public:" ||
word == "protected") {
formatted_code.back() += spaces + " ";
} else {
formatted_code.back() += spaces;
}
}
reverse(formatted_code.back().begin(),
formatted_code.back().end());
}
}
formatted_code.push_back("");
formatted_code.back() += (findWordAnother());
formatted_code.back() += "};";
counter++;
}
void Visit(const VarDeclarationNode* node) override {
formatted_code.back() += node->TypeName() + " " + node->VarName();
}
void Visit(const MethodDeclarationNode* node) override {
formatted_code.back() += node->ReturnTypeName()
+ " "
+ node->MethodName()
+ "(";
for (std::uint32_t i = 0; i < node->Arguments().size()-1
&& node->Arguments().size(); ++i) {
Visit(node->Arguments()[i]);
formatted_code.back() += ", ";
}
if (node->Arguments().size()) {
Visit(node->Arguments().back());
}
formatted_code.back() += ")";
}
std::string findWord() {
std::string word;
reverse(formatted_code.begin(), formatted_code.end());
for (const auto& word_ : formatted_code) {
std::string true_word, word = "";
std::uint16_t j = 0;
while (word_[j] == ' ') {
j++;
word += " ";
}
if (word_.size() > j + 5) {
for (std::uint32_t i = j; i < j + 5; ++i) {
true_word += word_[i];
}
if (true_word == "class") {
std::reverse(formatted_code.begin(), formatted_code.end());
return word;
}
}
}
reverse(formatted_code.begin(), formatted_code.end());
return word + " ";
}
std::string findWordAnother() {
std::string word;
std::uint32_t counter_copy = 0;
reverse(formatted_code.begin(), formatted_code.end());
for (const auto& word_ : formatted_code) {
std::string true_word, word = "";
std::uint16_t j = 0;
while (word_[j] == ' ') {
j++;
word += " ";
}
if (word_.size() > j + 5) {
for (std::uint32_t i = j; i < j + 5; ++i) {
true_word += word_[i];
}
if (true_word == "class") {
if (counter_copy == counter) {
reverse(formatted_code.begin(),
formatted_code.end());
return word;
}
counter_copy++;
}
}
}
reverse(formatted_code.begin(), formatted_code.end());
return word;
}
const std::vector<std::string>& GetFormattedCode() const {
return formatted_code;
}
private:
std::vector<std::string> formatted_code;
std::uint32_t counter = 0;
};