aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-02-18 00:43:07 +0800
committerLi Jin <dragon-fly@qq.com>2020-02-18 00:43:07 +0800
commitadfea5f0eee289fe729c2bcc68105417d77a8407 (patch)
tree9ec34e380c7157f0ed14a80ef4e2ab30876942fd
parent27e0f69843f412f25703c2c9165dbc1a0c6d6218 (diff)
downloadyuescript-adfea5f0eee289fe729c2bcc68105417d77a8407.tar.gz
yuescript-adfea5f0eee289fe729c2bcc68105417d77a8407.tar.bz2
yuescript-adfea5f0eee289fe729c2bcc68105417d77a8407.zip
remove the extra type id system.
-rw-r--r--src/MoonP/ast.cpp48
-rw-r--r--src/MoonP/ast.hpp63
-rw-r--r--src/MoonP/moon_ast.h24
-rw-r--r--src/MoonP/moon_compiler.cpp5
-rw-r--r--src/MoonP/moon_parser.cpp1
-rw-r--r--src/MoonP/moon_parser.h5
-rw-r--r--src/moonp.cpp14
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
10THIS 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.*/ 10THIS 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.*/
11 11
12#include <cassert> 12#include <cassert>
13
13#include "MoonP/ast.hpp" 14#include "MoonP/ast.hpp"
14 15
15 16
16namespace parserlib { 17namespace parserlib {
17 18
18int ast_type_id = 0;
19 19
20traversal ast_node::traverse(const std::function<traversal (ast_node*)>& func) { 20traversal ast_node::traverse(const std::function<traversal (ast_node*)>& func) {
21 return func(this); 21 return func(this);
@@ -26,9 +26,9 @@ ast_node* ast_node::getByTypeIds(int* begin, int* end) {
26 auto it = begin; 26 auto it = begin;
27 while (it != end) { 27 while (it != end) {
28 ast_node* findNode = nullptr; 28 ast_node* findNode = nullptr;
29 int type = *it; 29 int i = *it;
30 current->visitChild([&](ast_node* node) { 30 current->visitChild([&](ast_node* node) {
31 if (node->get_type() == type) { 31 if (node->getId() == i) {
32 findNode = node; 32 findNode = node;
33 return true; 33 return true;
34 } 34 }
@@ -74,15 +74,22 @@ traversal ast_container::traverse(const std::function<traversal (ast_node*)>& fu
74 } 74 }
75 const auto& members = this->members(); 75 const auto& members = this->members();
76 for (auto member : members) { 76 for (auto member : members) {
77 if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { 77 switch (member->get_type()) {
78 if (ptr->get() && ptr->get()->traverse(func) == traversal::Stop) { 78 case ast_holder_type::Pointer: {
79 return traversal::Stop; 79 _ast_ptr* ptr = static_cast<_ast_ptr*>(member);
80 } 80 if (ptr->get() && ptr->get()->traverse(func) == traversal::Stop) {
81 } else if (_ast_list* list = ast_cast<_ast_list>(member)) {
82 for (auto obj : list->objects()) {
83 if (obj->traverse(func) == traversal::Stop) {
84 return traversal::Stop; 81 return traversal::Stop;
85 } 82 }
83 break;
84 }
85 case ast_holder_type::List: {
86 _ast_list* list = static_cast<_ast_list*>(member);
87 for (auto obj : list->objects()) {
88 if (obj->traverse(func) == traversal::Stop) {
89 return traversal::Stop;
90 }
91 }
92 break;
86 } 93 }
87 } 94 }
88 } 95 }
@@ -92,15 +99,22 @@ traversal ast_container::traverse(const std::function<traversal (ast_node*)>& fu
92bool ast_container::visitChild(const std::function<bool (ast_node*)>& func) { 99bool ast_container::visitChild(const std::function<bool (ast_node*)>& func) {
93 const auto& members = this->members(); 100 const auto& members = this->members();
94 for (auto member : members) { 101 for (auto member : members) {
95 if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { 102 switch (member->get_type()) {
96 if (ptr->get()) { 103 case ast_holder_type::Pointer: {
97 if (func(ptr->get())) return true; 104 _ast_ptr* ptr = static_cast<_ast_ptr*>(member);
105 if (ptr->get()) {
106 if (func(ptr->get())) return true;
107 }
108 break;
98 } 109 }
99 } else if (_ast_list* list = ast_cast<_ast_list>(member)) { 110 case ast_holder_type::List: {
100 for (auto obj : list->objects()) { 111 _ast_list* list = static_cast<_ast_list*>(member);
101 if (obj) { 112 for (auto obj : list->objects()) {
102 if (func(obj)) return true; 113 if (obj) {
114 if (func(obj)) return true;
115 }
103 } 116 }
117 break;
104 } 118 }
105 } 119 }
106 } 120 }
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
16#include <list> 16#include <list>
17#include <stdexcept> 17#include <stdexcept>
18#include <type_traits> 18#include <type_traits>
19
19#include "MoonP/parser.hpp" 20#include "MoonP/parser.hpp"
20 21
21 22
@@ -33,13 +34,17 @@ template <class T> class ast;
33typedef std::vector<ast_node*> ast_stack; 34typedef std::vector<ast_node*> ast_stack;
34typedef std::list<ast_node*> node_container; 35typedef std::list<ast_node*> node_container;
35 36
36extern int ast_type_id;
37 37
38template<size_t Num> struct Counter { enum { value = Counter<Num-1>::value }; };
39template<> struct Counter<0> { enum { value = 0 }; };
40
41#define COUNTER_READ Counter<__LINE__>::value
42#define COUNTER_INC template<> struct Counter<__LINE__> { enum { value = Counter<__LINE__-1>::value + 1}; }
43
44class ast_node;
38template<class T> 45template<class T>
39int ast_type() { 46constexpr typename std::enable_if<std::is_base_of<ast_node,T>::value,int>::type
40 static int type = ast_type_id++; 47id();
41 return type;
42}
43 48
44enum class traversal { 49enum class traversal {
45 Continue, 50 Continue,
@@ -83,15 +88,13 @@ public:
83 88
84 template <class ...Args> 89 template <class ...Args>
85 select_last_t<Args...>* getByPath() { 90 select_last_t<Args...>* getByPath() {
86 int types[] = {ast_type<Args>()...}; 91 int types[] = {id<Args>()...};
87 return static_cast<select_last_t<Args...>*>(getByTypeIds(std::begin(types), std::end(types))); 92 return static_cast<select_last_t<Args...>*>(getByTypeIds(std::begin(types), std::end(types)));
88 } 93 }
89 94
90 virtual bool visitChild(const std::function<bool (ast_node*)>& func); 95 virtual bool visitChild(const std::function<bool (ast_node*)>& func);
91 96
92 virtual size_t getId() const = 0; 97 virtual int getId() const = 0;
93
94 virtual int get_type() = 0;
95 98
96 template<class T> 99 template<class T>
97 inline ast_ptr<false, T> new_ptr() { 100 inline ast_ptr<false, T> new_ptr() {
@@ -106,13 +109,17 @@ private:
106}; 109};
107 110
108template<class T> 111template<class T>
112constexpr typename std::enable_if<std::is_base_of<ast_node,T>::value,int>::type
113id() { return 0; }
114
115template<class T>
109T* ast_cast(ast_node* node) { 116T* ast_cast(ast_node* node) {
110 return node && ast_type<T>() == node->get_type() ? static_cast<T*>(node) : nullptr; 117 return node && id<T>() == node->getId() ? static_cast<T*>(node) : nullptr;
111} 118}
112 119
113template<class T> 120template<class T>
114T* ast_to(ast_node* node) { 121T* ast_to(ast_node* node) {
115 assert(node->get_type() == ast_type<T>()); 122 assert(node->getId() == id<T>());
116 return static_cast<T*>(node); 123 return static_cast<T*>(node);
117} 124}
118 125
@@ -120,9 +127,9 @@ template <class ...Args>
120bool ast_is(ast_node* node) { 127bool ast_is(ast_node* node) {
121 if (!node) return false; 128 if (!node) return false;
122 bool result = false; 129 bool result = false;
123 int type = node->get_type(); 130 int i = node->getId();
124 using swallow = bool[]; 131 using swallow = bool[];
125 (void)swallow{result || (result = ast_type<Args>() == type)...}; 132 (void)swallow{result || (result = id<Args>() == i)...};
126 return result; 133 return result;
127} 134}
128 135
@@ -166,6 +173,10 @@ private:
166 friend class ast_member; 173 friend class ast_member;
167}; 174};
168 175
176enum class ast_holder_type {
177 Pointer,
178 List
179};
169 180
170/** Base class for children of ast_container. 181/** Base class for children of ast_container.
171*/ 182*/
@@ -180,13 +191,9 @@ public:
180 191
181 virtual bool accept(ast_node* node) = 0; 192 virtual bool accept(ast_node* node) = 0;
182 193
183 virtual int get_type() { return ast_type<ast_member>(); } 194 virtual ast_holder_type get_type() const = 0;
184}; 195};
185 196
186template<class T>
187T* ast_cast(ast_member* member) {
188 return member && ast_type<T>() == member->get_type() ? static_cast<T*>(member) : nullptr;
189}
190 197
191class _ast_ptr : public ast_member { 198class _ast_ptr : public ast_member {
192public: 199public:
@@ -212,13 +219,13 @@ public:
212 219
213 template <class T> 220 template <class T>
214 T* to() const { 221 T* to() const {
215 assert(m_ptr && m_ptr->get_type() == ast_type<T>()); 222 assert(m_ptr && m_ptr->getId() == id<T>());
216 return static_cast<T*>(m_ptr); 223 return static_cast<T*>(m_ptr);
217 } 224 }
218 225
219 template <class T> 226 template <class T>
220 bool is() const { 227 bool is() const {
221 return m_ptr && m_ptr->get_type() == ast_type<T>(); 228 return m_ptr && m_ptr->getId() == id<T>();
222 } 229 }
223 230
224 void set(ast_node* node) { 231 void set(ast_node* node) {
@@ -235,8 +242,8 @@ public:
235 } 242 }
236 } 243 }
237 244
238 virtual int get_type() override { 245 virtual ast_holder_type get_type() const override {
239 return ast_type<_ast_ptr>(); 246 return ast_holder_type::Pointer;
240 } 247 }
241protected: 248protected:
242 ast_node* m_ptr; 249 ast_node* m_ptr;
@@ -305,7 +312,7 @@ public:
305 } 312 }
306private: 313private:
307 virtual bool accept(ast_node* node) override { 314 virtual bool accept(ast_node* node) override {
308 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type()); 315 return node && (std::is_same<ast_node,T>() || id<T>() == node->getId());
309 } 316 }
310}; 317};
311 318
@@ -348,7 +355,7 @@ private:
348 if (!node) return false; 355 if (!node) return false;
349 using swallow = bool[]; 356 using swallow = bool[];
350 bool result = false; 357 bool result = false;
351 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...}; 358 (void)swallow{result || (result = id<Args>() == node->getId())...};
352 return result; 359 return result;
353 } 360 }
354}; 361};
@@ -429,7 +436,9 @@ public:
429 } 436 }
430 } 437 }
431 438
432 virtual int get_type() override { return ast_type<_ast_list>(); } 439 virtual ast_holder_type get_type() const override {
440 return ast_holder_type::List;
441 }
433protected: 442protected:
434 node_container m_objects; 443 node_container m_objects;
435}; 444};
@@ -479,7 +488,7 @@ public:
479 } 488 }
480private: 489private:
481 virtual bool accept(ast_node* node) override { 490 virtual bool accept(ast_node* node) override {
482 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type()); 491 return node && (std::is_same<ast_node,T>() || id<T>() == node->getId());
483 } 492 }
484}; 493};
485 494
@@ -519,7 +528,7 @@ private:
519 if (!node) return false; 528 if (!node) return false;
520 using swallow = bool[]; 529 using swallow = bool[];
521 bool result = false; 530 bool result = false;
522 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...}; 531 (void)swallow{result || (result = id<Args>() == node->getId())...};
523 return result; 532 return result;
524 } 533 }
525}; 534};
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
9#pragma once 9#pragma once
10 10
11#include "MoonP/ast.hpp" 11#include "MoonP/ast.hpp"
12using namespace parserlib;
13 12
14namespace MoonP { 13namespace parserlib {
15
16template<size_t NUM> struct Counter { enum { value = Counter<NUM-1>::value }; };
17template<> struct Counter<0> { enum { value = 0 }; };
18
19#define COUNTER_READ Counter<__LINE__>::value
20#define COUNTER_INC template<> struct Counter<__LINE__> { enum { value = Counter<__LINE__-1>::value + 1}; }
21
22template<class T>
23constexpr typename std::enable_if<std::is_base_of<ast_node,T>::value,size_t>::type
24id() { return 0; }
25 14
26#define AST_LEAF(type) \ 15#define AST_LEAF(type) \
27COUNTER_INC;\ 16COUNTER_INC;\
28class type##_t : public ast_node \ 17class type##_t : public ast_node \
29{ \ 18{ \
30public: \ 19public: \
31 virtual int get_type() override { return ast_type<type##_t>(); } \ 20 virtual int getId() const override { return COUNTER_READ; }
32 virtual size_t getId() const override { return COUNTER_READ; }
33 21
34#define AST_NODE(type) \ 22#define AST_NODE(type) \
35COUNTER_INC;\ 23COUNTER_INC;\
36class type##_t : public ast_container \ 24class type##_t : public ast_container \
37{ \ 25{ \
38public: \ 26public: \
39 virtual int get_type() override { return ast_type<type##_t>(); } \ 27 virtual int getId() const override { return COUNTER_READ; } \
40 virtual size_t getId() const override { return COUNTER_READ; } \
41 28
42#define AST_MEMBER(type, ...) \ 29#define AST_MEMBER(type, ...) \
43 type##_t() { \ 30 type##_t() { \
@@ -46,7 +33,7 @@ public: \
46 33
47#define AST_END(type) \ 34#define AST_END(type) \
48}; \ 35}; \
49template<> constexpr size_t id<type##_t>() { return COUNTER_READ; } 36template<> constexpr int id<type##_t>() { return COUNTER_READ; }
50 37
51AST_LEAF(Num) 38AST_LEAF(Num)
52AST_END(Num) 39AST_END(Num)
@@ -633,5 +620,4 @@ AST_NODE(File)
633 AST_MEMBER(File, &block) 620 AST_MEMBER(File, &block)
634AST_END(File) 621AST_END(File)
635 622
636} // namespace MoonP 623} // namespace parserlib
637
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
11#include <unordered_map> 11#include <unordered_map>
12#include <stack> 12#include <stack>
13#include <vector> 13#include <vector>
14#include <numeric>
15#include <memory> 14#include <memory>
15#include <cassert>
16
16#include "MoonP/moon_parser.h" 17#include "MoonP/moon_parser.h"
17#include "MoonP/moon_compiler.h" 18#include "MoonP/moon_compiler.h"
18 19
19namespace MoonP { 20namespace MoonP {
21using namespace std::string_view_literals;
22using namespace parserlib;
20 23
21#define BLOCK_START do { 24#define BLOCK_START do {
22#define BLOCK_END } while (false); 25#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
11namespace pl = parserlib; 11namespace pl = parserlib;
12 12
13namespace MoonP { 13namespace MoonP {
14using namespace std::string_view_literals;
14 15
15std::unordered_set<std::string> LuaKeywords = { 16std::unordered_set<std::string> LuaKeywords = {
16 "and", "break", "do", "else", "elseif", 17 "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
15#include <vector> 15#include <vector>
16#include <sstream> 16#include <sstream>
17#include <string_view> 17#include <string_view>
18using namespace std::string_view_literals; 18
19#include "MoonP/ast.hpp" 19#include "MoonP/ast.hpp"
20#include "MoonP/moon_ast.h" 20#include "MoonP/moon_ast.h"
21 21
22namespace MoonP { 22namespace MoonP {
23using namespace parserlib;
23 24
24struct ParseInfo { 25struct ParseInfo {
25 ast_ptr<false,ast_node> node; 26 ast_ptr<false, ast_node> node;
26 std::string error; 27 std::string error;
27 std::unique_ptr<input> codes; 28 std::unique_ptr<input> codes;
28 std::string errorMessage(std::string_view msg, const input_range* loc) const; 29 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) {
38 std::list<std::string> files; 38 std::list<std::string> files;
39 for (int i = 1; i < narg; ++i) { 39 for (int i = 1; i < narg; ++i) {
40 std::string arg = args[i]; 40 std::string arg = args[i];
41 if (arg == "-l"sv) { 41 if (arg == "-l") {
42 config.reserveLineNumber = true; 42 config.reserveLineNumber = true;
43 } else if (arg == "-p"sv) { 43 } else if (arg == "-p") {
44 writeToFile = false; 44 writeToFile = false;
45 } else if (arg == "-t"sv) { 45 } else if (arg == "-t") {
46 ++i; 46 ++i;
47 if (i < narg) { 47 if (i < narg) {
48 targetPath = args[i]; 48 targetPath = args[i];
@@ -50,15 +50,15 @@ int main(int narg, const char** args) {
50 std::cout << help; 50 std::cout << help;
51 return 1; 51 return 1;
52 } 52 }
53 } else if (arg == "-b"sv) { 53 } else if (arg == "-b") {
54 dumpCompileTime = true; 54 dumpCompileTime = true;
55 } else if (arg == "-h"sv) { 55 } else if (arg == "-h") {
56 std::cout << help; 56 std::cout << help;
57 return 0; 57 return 0;
58 } else if (arg == "-v"sv) { 58 } else if (arg == "-v") {
59 std::cout << "Moonscript version: " << MoonP::moonScriptVersion() << '\n'; 59 std::cout << "Moonscript version: " << MoonP::moonScriptVersion() << '\n';
60 return 0; 60 return 0;
61 } else if (arg == "-o"sv) { 61 } else if (arg == "-o") {
62 ++i; 62 ++i;
63 if (i < narg) { 63 if (i < narg) {
64 resultFile = args[i]; 64 resultFile = args[i];