From adfea5f0eee289fe729c2bcc68105417d77a8407 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Tue, 18 Feb 2020 00:43:07 +0800 Subject: remove the extra type id system. --- src/MoonP/ast.cpp | 48 ++++++++++++++++++++++------------ src/MoonP/ast.hpp | 63 ++++++++++++++++++++++++++------------------- src/MoonP/moon_ast.h | 24 ++++------------- src/MoonP/moon_compiler.cpp | 5 +++- src/MoonP/moon_parser.cpp | 1 + src/MoonP/moon_parser.h | 5 ++-- src/moonp.cpp | 14 +++++----- 7 files changed, 87 insertions(+), 73 deletions(-) diff --git a/src/MoonP/ast.cpp b/src/MoonP/ast.cpp index 71c90c5..4929021 100644 --- a/src/MoonP/ast.cpp +++ b/src/MoonP/ast.cpp @@ -10,12 +10,12 @@ Redistributions in binary form must reproduce the above copyright notice, this l THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ #include + #include "MoonP/ast.hpp" namespace parserlib { -int ast_type_id = 0; traversal ast_node::traverse(const std::function& func) { return func(this); @@ -26,9 +26,9 @@ ast_node* ast_node::getByTypeIds(int* begin, int* end) { auto it = begin; while (it != end) { ast_node* findNode = nullptr; - int type = *it; + int i = *it; current->visitChild([&](ast_node* node) { - if (node->get_type() == type) { + if (node->getId() == i) { findNode = node; return true; } @@ -74,15 +74,22 @@ traversal ast_container::traverse(const std::function& fu } const auto& members = this->members(); for (auto member : members) { - if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { - if (ptr->get() && ptr->get()->traverse(func) == traversal::Stop) { - return traversal::Stop; - } - } else if (_ast_list* list = ast_cast<_ast_list>(member)) { - for (auto obj : list->objects()) { - if (obj->traverse(func) == traversal::Stop) { + switch (member->get_type()) { + case ast_holder_type::Pointer: { + _ast_ptr* ptr = static_cast<_ast_ptr*>(member); + if (ptr->get() && ptr->get()->traverse(func) == traversal::Stop) { return traversal::Stop; } + break; + } + case ast_holder_type::List: { + _ast_list* list = static_cast<_ast_list*>(member); + for (auto obj : list->objects()) { + if (obj->traverse(func) == traversal::Stop) { + return traversal::Stop; + } + } + break; } } } @@ -92,15 +99,22 @@ traversal ast_container::traverse(const std::function& fu bool ast_container::visitChild(const std::function& func) { const auto& members = this->members(); for (auto member : members) { - if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { - if (ptr->get()) { - if (func(ptr->get())) return true; + switch (member->get_type()) { + case ast_holder_type::Pointer: { + _ast_ptr* ptr = static_cast<_ast_ptr*>(member); + if (ptr->get()) { + if (func(ptr->get())) return true; + } + break; } - } else if (_ast_list* list = ast_cast<_ast_list>(member)) { - for (auto obj : list->objects()) { - if (obj) { - if (func(obj)) return true; + case ast_holder_type::List: { + _ast_list* list = static_cast<_ast_list*>(member); + for (auto obj : list->objects()) { + if (obj) { + if (func(obj)) return true; + } } + break; } } } diff --git a/src/MoonP/ast.hpp b/src/MoonP/ast.hpp index b56cfde..d576395 100644 --- a/src/MoonP/ast.hpp +++ b/src/MoonP/ast.hpp @@ -16,6 +16,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #include #include #include + #include "MoonP/parser.hpp" @@ -33,13 +34,17 @@ template class ast; typedef std::vector ast_stack; typedef std::list node_container; -extern int ast_type_id; +template struct Counter { enum { value = Counter::value }; }; +template<> struct Counter<0> { enum { value = 0 }; }; + +#define COUNTER_READ Counter<__LINE__>::value +#define COUNTER_INC template<> struct Counter<__LINE__> { enum { value = Counter<__LINE__-1>::value + 1}; } + +class ast_node; template -int ast_type() { - static int type = ast_type_id++; - return type; -} +constexpr typename std::enable_if::value,int>::type +id(); enum class traversal { Continue, @@ -83,15 +88,13 @@ public: template select_last_t* getByPath() { - int types[] = {ast_type()...}; + int types[] = {id()...}; return static_cast*>(getByTypeIds(std::begin(types), std::end(types))); } virtual bool visitChild(const std::function& func); - virtual size_t getId() const = 0; - - virtual int get_type() = 0; + virtual int getId() const = 0; template inline ast_ptr new_ptr() { @@ -105,14 +108,18 @@ private: ast_node* getByTypeIds(int* begin, int* end); }; +template +constexpr typename std::enable_if::value,int>::type +id() { return 0; } + template T* ast_cast(ast_node* node) { - return node && ast_type() == node->get_type() ? static_cast(node) : nullptr; + return node && id() == node->getId() ? static_cast(node) : nullptr; } template T* ast_to(ast_node* node) { - assert(node->get_type() == ast_type()); + assert(node->getId() == id()); return static_cast(node); } @@ -120,9 +127,9 @@ template bool ast_is(ast_node* node) { if (!node) return false; bool result = false; - int type = node->get_type(); + int i = node->getId(); using swallow = bool[]; - (void)swallow{result || (result = ast_type() == type)...}; + (void)swallow{result || (result = id() == i)...}; return result; } @@ -166,6 +173,10 @@ private: friend class ast_member; }; +enum class ast_holder_type { + Pointer, + List +}; /** Base class for children of ast_container. */ @@ -180,13 +191,9 @@ public: virtual bool accept(ast_node* node) = 0; - virtual int get_type() { return ast_type(); } + virtual ast_holder_type get_type() const = 0; }; -template -T* ast_cast(ast_member* member) { - return member && ast_type() == member->get_type() ? static_cast(member) : nullptr; -} class _ast_ptr : public ast_member { public: @@ -212,13 +219,13 @@ public: template T* to() const { - assert(m_ptr && m_ptr->get_type() == ast_type()); + assert(m_ptr && m_ptr->getId() == id()); return static_cast(m_ptr); } template bool is() const { - return m_ptr && m_ptr->get_type() == ast_type(); + return m_ptr && m_ptr->getId() == id(); } void set(ast_node* node) { @@ -235,8 +242,8 @@ public: } } - virtual int get_type() override { - return ast_type<_ast_ptr>(); + virtual ast_holder_type get_type() const override { + return ast_holder_type::Pointer; } protected: ast_node* m_ptr; @@ -305,7 +312,7 @@ public: } private: virtual bool accept(ast_node* node) override { - return node && (std::is_same() || ast_type() == node->get_type()); + return node && (std::is_same() || id() == node->getId()); } }; @@ -348,7 +355,7 @@ private: if (!node) return false; using swallow = bool[]; bool result = false; - (void)swallow{result || (result = ast_type() == node->get_type())...}; + (void)swallow{result || (result = id() == node->getId())...}; return result; } }; @@ -429,7 +436,9 @@ public: } } - virtual int get_type() override { return ast_type<_ast_list>(); } + virtual ast_holder_type get_type() const override { + return ast_holder_type::List; + } protected: node_container m_objects; }; @@ -479,7 +488,7 @@ public: } private: virtual bool accept(ast_node* node) override { - return node && (std::is_same() || ast_type() == node->get_type()); + return node && (std::is_same() || id() == node->getId()); } }; @@ -519,7 +528,7 @@ private: if (!node) return false; using swallow = bool[]; bool result = false; - (void)swallow{result || (result = ast_type() == node->get_type())...}; + (void)swallow{result || (result = id() == node->getId())...}; return result; } }; diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index 0b572b5..26accbf 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h @@ -9,35 +9,22 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #pragma once #include "MoonP/ast.hpp" -using namespace parserlib; -namespace MoonP { - -template struct Counter { enum { value = Counter::value }; }; -template<> struct Counter<0> { enum { value = 0 }; }; - -#define COUNTER_READ Counter<__LINE__>::value -#define COUNTER_INC template<> struct Counter<__LINE__> { enum { value = Counter<__LINE__-1>::value + 1}; } - -template -constexpr typename std::enable_if::value,size_t>::type -id() { return 0; } +namespace parserlib { #define AST_LEAF(type) \ COUNTER_INC;\ class type##_t : public ast_node \ { \ public: \ - virtual int get_type() override { return ast_type(); } \ - virtual size_t getId() const override { return COUNTER_READ; } + virtual int getId() const override { return COUNTER_READ; } #define AST_NODE(type) \ COUNTER_INC;\ class type##_t : public ast_container \ { \ public: \ - virtual int get_type() override { return ast_type(); } \ - virtual size_t getId() const override { return COUNTER_READ; } \ + virtual int getId() const override { return COUNTER_READ; } \ #define AST_MEMBER(type, ...) \ type##_t() { \ @@ -46,7 +33,7 @@ public: \ #define AST_END(type) \ }; \ -template<> constexpr size_t id() { return COUNTER_READ; } +template<> constexpr int id() { return COUNTER_READ; } AST_LEAF(Num) AST_END(Num) @@ -633,5 +620,4 @@ AST_NODE(File) AST_MEMBER(File, &block) AST_END(File) -} // namespace MoonP - +} // namespace parserlib diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index fa55496..23ce6ce 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp @@ -11,12 +11,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include #include +#include + #include "MoonP/moon_parser.h" #include "MoonP/moon_compiler.h" namespace MoonP { +using namespace std::string_view_literals; +using namespace parserlib; #define BLOCK_START do { #define BLOCK_END } while (false); diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 0ea6e12..1ba8ad3 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp @@ -11,6 +11,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI namespace pl = parserlib; namespace MoonP { +using namespace std::string_view_literals; std::unordered_set LuaKeywords = { "and", "break", "do", "else", "elseif", diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h index 2b6e2ae..7a1a8a9 100644 --- a/src/MoonP/moon_parser.h +++ b/src/MoonP/moon_parser.h @@ -15,14 +15,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -using namespace std::string_view_literals; + #include "MoonP/ast.hpp" #include "MoonP/moon_ast.h" namespace MoonP { +using namespace parserlib; struct ParseInfo { - ast_ptr node; + ast_ptr node; std::string error; std::unique_ptr codes; std::string errorMessage(std::string_view msg, const input_range* loc) const; diff --git a/src/moonp.cpp b/src/moonp.cpp index 32d85ed..be5f536 100644 --- a/src/moonp.cpp +++ b/src/moonp.cpp @@ -38,11 +38,11 @@ int main(int narg, const char** args) { std::list files; for (int i = 1; i < narg; ++i) { std::string arg = args[i]; - if (arg == "-l"sv) { + if (arg == "-l") { config.reserveLineNumber = true; - } else if (arg == "-p"sv) { + } else if (arg == "-p") { writeToFile = false; - } else if (arg == "-t"sv) { + } else if (arg == "-t") { ++i; if (i < narg) { targetPath = args[i]; @@ -50,15 +50,15 @@ int main(int narg, const char** args) { std::cout << help; return 1; } - } else if (arg == "-b"sv) { + } else if (arg == "-b") { dumpCompileTime = true; - } else if (arg == "-h"sv) { + } else if (arg == "-h") { std::cout << help; return 0; - } else if (arg == "-v"sv) { + } else if (arg == "-v") { std::cout << "Moonscript version: " << MoonP::moonScriptVersion() << '\n'; return 0; - } else if (arg == "-o"sv) { + } else if (arg == "-o") { ++i; if (i < narg) { resultFile = args[i]; -- cgit v1.2.3-55-g6feb