aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/ast.cpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2019-09-08 00:28:49 +0800
committerLi Jin <dragon-fly@qq.com>2019-09-08 00:28:49 +0800
commitfabc309a0a0a6f210a8a7ed8f0d1f8498971f409 (patch)
tree0187faf6b0caf17d1767b5a01ea174704742ab6f /MoonParser/ast.cpp
parent5e3d082dd2ea31acf0cc722c19b78aa4ef6e6077 (diff)
downloadyuescript-fabc309a0a0a6f210a8a7ed8f0d1f8498971f409.tar.gz
yuescript-fabc309a0a0a6f210a8a7ed8f0d1f8498971f409.tar.bz2
yuescript-fabc309a0a0a6f210a8a7ed8f0d1f8498971f409.zip
completing moonscript compiler with c++.
Diffstat (limited to '')
-rw-r--r--MoonParser/ast.cpp127
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
11int ast_type_id = 0; 11int ast_type_id = 0;
12 12
13traversal ast_node::traverse(const std::function<traversal (ast_node*)>& func) {
14 return func(this);
15}
13 16
14bool ast_node::visit(const std::function<bool (ast_node*)>& begin, 17ast_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
21void ast_node::eachChild(const std::function<void (ast_node*)>&) { }
22
23bool 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
51bool ast_container::visit(const std::function<bool (ast_node*)>& begin, 57traversal 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
81ast_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
104void 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
121bool 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
139ast_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
160int 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.
75void ast_member::_init() { 176void ast_member::_init() {