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