diff options
author | Li Jin <dragon-fly@qq.com> | 2019-09-08 00:28:49 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2019-09-08 00:28:49 +0800 |
commit | fabc309a0a0a6f210a8a7ed8f0d1f8498971f409 (patch) | |
tree | 0187faf6b0caf17d1767b5a01ea174704742ab6f /MoonParser/ast.cpp | |
parent | 5e3d082dd2ea31acf0cc722c19b78aa4ef6e6077 (diff) | |
download | yuescript-fabc309a0a0a6f210a8a7ed8f0d1f8498971f409.tar.gz yuescript-fabc309a0a0a6f210a8a7ed8f0d1f8498971f409.tar.bz2 yuescript-fabc309a0a0a6f210a8a7ed8f0d1f8498971f409.zip |
completing moonscript compiler with c++.
Diffstat (limited to '')
-rw-r--r-- | MoonParser/ast.cpp | 127 |
1 files changed, 114 insertions, 13 deletions
diff --git a/MoonParser/ast.cpp b/MoonParser/ast.cpp index 739e02c..6217f3e 100644 --- a/MoonParser/ast.cpp +++ b/MoonParser/ast.cpp | |||
@@ -10,13 +10,19 @@ static ast_container *_current = 0; | |||
10 | 10 | ||
11 | int ast_type_id = 0; | 11 | int ast_type_id = 0; |
12 | 12 | ||
13 | traversal ast_node::traverse(const std::function<traversal (ast_node*)>& func) { | ||
14 | return func(this); | ||
15 | } | ||
13 | 16 | ||
14 | bool ast_node::visit(const std::function<bool (ast_node*)>& begin, | 17 | ast_node* ast_node::getByPath(std::initializer_list<std::size_t>) { |
15 | const std::function<bool (ast_node*)>& end) | 18 | return nullptr; |
16 | { | ||
17 | return begin(this) || end(this); | ||
18 | } | 19 | } |
19 | 20 | ||
21 | void ast_node::eachChild(const std::function<void (ast_node*)>&) { } | ||
22 | |||
23 | bool ast_node::visitChild(const std::function<bool (ast_node*)>&) { | ||
24 | return false; | ||
25 | } | ||
20 | 26 | ||
21 | /** sets the container under construction to be this. | 27 | /** sets the container under construction to be this. |
22 | */ | 28 | */ |
@@ -48,28 +54,123 @@ void ast_container::construct(ast_stack &st) { | |||
48 | } | 54 | } |
49 | } | 55 | } |
50 | 56 | ||
51 | bool ast_container::visit(const std::function<bool (ast_node*)>& begin, | 57 | traversal ast_container::traverse(const std::function<traversal (ast_node*)>& func) { |
52 | const std::function<bool (ast_node*)>& end) | 58 | traversal action = func(this); |
53 | { | 59 | switch (action) { |
54 | bool result = begin(this); | 60 | case traversal::Stop: return traversal::Stop; |
55 | if (result) return true; | 61 | case traversal::Return: return traversal::Continue; |
62 | default: break; | ||
63 | } | ||
56 | const auto& members = this->members(); | 64 | const auto& members = this->members(); |
57 | for (auto member : members) { | 65 | for (auto member : members) { |
58 | if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { | 66 | if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { |
59 | if (ptr->get() && ptr->get()->visit(begin, end)) { | 67 | if (ptr->get() && ptr->get()->traverse(func) == traversal::Stop) { |
68 | return traversal::Stop; | ||
69 | } | ||
70 | } else if (_ast_list* list = ast_cast<_ast_list>(member)) { | ||
71 | for (auto obj : list->objects()) { | ||
72 | if (obj->traverse(func) == traversal::Stop) { | ||
73 | return traversal::Stop; | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | return traversal::Continue; | ||
79 | } | ||
80 | |||
81 | ast_node* ast_container::getByPath(std::initializer_list<std::size_t> paths) { | ||
82 | ast_node* current = this; | ||
83 | auto it = paths.begin(); | ||
84 | while (it != paths.end()) { | ||
85 | ast_node* findNode = nullptr; | ||
86 | current->visitChild([&](ast_node* node) { | ||
87 | if (node->getId() == *it) { | ||
88 | findNode = node; | ||
60 | return true; | 89 | return true; |
61 | } | 90 | } |
91 | return false; | ||
92 | }); | ||
93 | if (findNode) { | ||
94 | current = findNode; | ||
95 | } else { | ||
96 | current = nullptr; | ||
97 | break; | ||
98 | } | ||
99 | ++it; | ||
100 | } | ||
101 | return current; | ||
102 | } | ||
103 | |||
104 | void ast_container::eachChild(const std::function<void (ast_node*)>& func) { | ||
105 | const auto& members = this->members(); | ||
106 | for (auto member : members) { | ||
107 | if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { | ||
108 | if (ptr->get()) { | ||
109 | func(ptr->get()); | ||
110 | } | ||
111 | } else if (_ast_list* list = ast_cast<_ast_list>(member)) { | ||
112 | for (auto obj : list->objects()) { | ||
113 | if (obj) { | ||
114 | func(obj); | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | |||
121 | bool ast_container::visitChild(const std::function<bool (ast_node*)>& func) { | ||
122 | const auto& members = this->members(); | ||
123 | for (auto member : members) { | ||
124 | if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { | ||
125 | if (ptr->get()) { | ||
126 | if (func(ptr->get())) return true; | ||
127 | } | ||
62 | } else if (_ast_list* list = ast_cast<_ast_list>(member)) { | 128 | } else if (_ast_list* list = ast_cast<_ast_list>(member)) { |
63 | for (auto obj : list->objects()) { | 129 | for (auto obj : list->objects()) { |
64 | if (obj->visit(begin, end)) { | 130 | if (obj) { |
65 | return true; | 131 | if (func(obj)) return true; |
66 | } | 132 | } |
67 | } | 133 | } |
68 | } | 134 | } |
69 | } | 135 | } |
70 | return end(this); | 136 | return false; |
71 | } | 137 | } |
72 | 138 | ||
139 | ast_node* ast_container::getChild(int index) const { | ||
140 | int i = 0; | ||
141 | const auto& members = this->members(); | ||
142 | for (auto member : members) { | ||
143 | if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { | ||
144 | if (ptr->get()) { | ||
145 | if (i == index) return ptr->get(); | ||
146 | i++; | ||
147 | } | ||
148 | } else if (_ast_list* list = ast_cast<_ast_list>(member)) { | ||
149 | for (auto obj : list->objects()) { | ||
150 | if (obj) { | ||
151 | if (i == index) return obj; | ||
152 | i++; | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | return nullptr; | ||
158 | } | ||
159 | |||
160 | int ast_container::getChildCount() const { | ||
161 | int count = 0; | ||
162 | const auto& members = this->members(); | ||
163 | for (auto member : members) { | ||
164 | if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { | ||
165 | if (ptr->get()) count++; | ||
166 | } else if (_ast_list* list = ast_cast<_ast_list>(member)) { | ||
167 | for (auto obj : list->objects()) { | ||
168 | if (obj) count++; | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | return count; | ||
173 | } | ||
73 | 174 | ||
74 | //register the AST member to the current container. | 175 | //register the AST member to the current container. |
75 | void ast_member::_init() { | 176 | void ast_member::_init() { |