#include #include #include 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; 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& GetFormattedCode() const { return code_; } };