summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2019-09-12 16:12:20 +0800
committerLi Jin <dragon-fly@qq.com>2019-09-12 16:12:20 +0800
commit50353c1456324e7bd3c130fceaf400aed7880a41 (patch)
tree0afe5823040dc9fc9ab39a9d7f4af647c061d7c1
parent4e6f4e8124316866a08f9ddf3322fde87abc3c21 (diff)
downloadyuescript-50353c1456324e7bd3c130fceaf400aed7880a41.tar.gz
yuescript-50353c1456324e7bd3c130fceaf400aed7880a41.tar.bz2
yuescript-50353c1456324e7bd3c130fceaf400aed7880a41.zip
spec/assign.moon and spec/bubbling.moon compiled
-rw-r--r--MoonParser/ast.cpp72
-rw-r--r--MoonParser/ast.hpp471
-rw-r--r--MoonParser/moon_ast.cpp1556
-rw-r--r--MoonParser/moon_parser.cpp12
-rw-r--r--MoonParser/moon_parser.h8
-rw-r--r--MoonParser/parser.cpp12
-rw-r--r--MoonParser/parser.hpp15
7 files changed, 1367 insertions, 779 deletions
diff --git a/MoonParser/ast.cpp b/MoonParser/ast.cpp
index 6217f3e..dbf5d17 100644
--- a/MoonParser/ast.cpp
+++ b/MoonParser/ast.cpp
@@ -6,7 +6,7 @@ namespace parserlib {
6 6
7 7
8//current AST container. 8//current AST container.
9static ast_container *_current = 0; 9static ast_container* _current = 0;
10 10
11int ast_type_id = 0; 11int ast_type_id = 0;
12 12
@@ -30,14 +30,6 @@ ast_container::ast_container() {
30 _current = this; 30 _current = this;
31} 31}
32 32
33
34/** sets the container under construction to be this.
35 @param src source object.
36 */
37ast_container::ast_container(const ast_container &src) {
38 _current = this;
39}
40
41 33
42/** Asks all members to construct themselves from the stack. 34/** Asks all members to construct themselves from the stack.
43 The members are asked to construct themselves in reverse order. 35 The members are asked to construct themselves in reverse order.
@@ -49,7 +41,7 @@ void ast_container::construct(ast_stack &st) {
49 it != m_members.rend(); 41 it != m_members.rend();
50 ++it) 42 ++it)
51 { 43 {
52 ast_member *member = *it; 44 ast_member* member = *it;
53 member->construct(st); 45 member->construct(st);
54 } 46 }
55} 47}
@@ -141,42 +133,64 @@ ast_node* ast_container::getChild(int index) const {
141 const auto& members = this->members(); 133 const auto& members = this->members();
142 for (auto member : members) { 134 for (auto member : members) {
143 if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { 135 if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) {
144 if (ptr->get()) { 136 if (i == index) return ptr->get();
145 if (i == index) return ptr->get();
146 i++;
147 }
148 } else if (_ast_list* list = ast_cast<_ast_list>(member)) { 137 } else if (_ast_list* list = ast_cast<_ast_list>(member)) {
149 for (auto obj : list->objects()) { 138 for (auto obj : list->objects()) {
150 if (obj) { 139 if (i == index) return obj;
151 if (i == index) return obj;
152 i++;
153 }
154 } 140 }
155 } 141 }
142 i++;
156 } 143 }
157 return nullptr; 144 return nullptr;
158} 145}
159 146
160int ast_container::getChildCount() const { 147ast_node* ast_container::getFirstChild() const {
161 int count = 0;
162 const auto& members = this->members(); 148 const auto& members = this->members();
163 for (auto member : members) { 149 if (!members.empty()) {
150 auto member = members.front();
164 if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) { 151 if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) {
165 if (ptr->get()) count++; 152 return ptr->get();
166 } else if (_ast_list* list = ast_cast<_ast_list>(member)) { 153 } else if (_ast_list* list = ast_cast<_ast_list>(member)) {
167 for (auto obj : list->objects()) { 154 if (!list->objects().empty()) {
168 if (obj) count++; 155 return list->objects().front();
156 }
157 }
158 }
159 return nullptr;
160}
161
162ast_node* ast_container::getLastChild() const {
163 const auto& members = this->members();
164 if (!members.empty()) {
165 auto member = members.back();
166 if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) {
167 return ptr->get();
168 } else if (_ast_list* list = ast_cast<_ast_list>(member)) {
169 if (!list->objects().empty()) {
170 return list->objects().front();
169 } 171 }
170 } 172 }
171 } 173 }
174 return nullptr;
175}
176
177size_t ast_container::getChildCount() const {
178 size_t count = 0;
179 const auto& members = this->members();
180 for (auto member : members) {
181 if (_ast_ptr* ptr = ast_cast<_ast_ptr>(member)) {
182 count += 1;
183 } else if (_ast_list* list = ast_cast<_ast_list>(member)) {
184 count += list->objects().size();
185 }
186 }
172 return count; 187 return count;
173} 188}
174 189
175//register the AST member to the current container. 190//register the AST member to the current container.
176void ast_member::_init() { 191void ast_member::add_to_owner() {
177 assert(_current); 192 assert(_current);
178 m_container = _current; 193 _current->m_members.push_back(this);
179 _current->m_members.push_back(this);
180} 194}
181 195
182 196
@@ -188,7 +202,7 @@ void ast_member::_init() {
188 @return pointer to ast node created, or null if there was an error. 202 @return pointer to ast node created, or null if there was an error.
189 The return object must be deleted by the caller. 203 The return object must be deleted by the caller.
190 */ 204 */
191ast_node *parse(input &i, rule &g, error_list &el, void* ud) { 205ast_node* _parse(input &i, rule &g, error_list &el, void* ud) {
192 ast_stack st; 206 ast_stack st;
193 if (!parse(i, g, el, &st, ud)) return 0; 207 if (!parse(i, g, el, &st, ud)) return 0;
194 assert(st.size() == 1); 208 assert(st.size() == 1);
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp
index 4d52dfc..982eea8 100644
--- a/MoonParser/ast.hpp
+++ b/MoonParser/ast.hpp
@@ -13,14 +13,14 @@ namespace parserlib {
13 13
14 14
15class ast_node; 15class ast_node;
16template <class T, bool OPT> class ast_ptr; 16template <class T, bool OPT, bool MEM> class ast_ptr;
17template <class T> class ast_list; 17template <class T> class ast_list;
18template <class T> class ast; 18template <class T> class ast;
19 19
20 20
21/** type of AST node stack. 21/** type of AST node stack.
22 */ 22 */
23typedef std::vector<ast_node *> ast_stack; 23typedef std::vector<ast_node*> ast_stack;
24 24
25extern int ast_type_id; 25extern int ast_type_id;
26 26
@@ -41,33 +41,24 @@ enum class traversal {
41 */ 41 */
42class ast_node : public input_range { 42class ast_node : public input_range {
43public: 43public:
44 ///constructor. 44 ast_node() : _ref(0) {}
45 ast_node() : m_parent(nullptr) {} 45
46 46 void retain() {
47 /** copy constructor. 47 ++_ref;
48 @param n source object. 48 }
49 */ 49
50 ast_node(const ast_node &n) : m_parent(nullptr) {} 50 void release() {
51 51 --_ref;
52 ///destructor. 52 if (_ref == 0) {
53 virtual ~ast_node() {} 53 delete this;
54 54 }
55 /** assignment operator. 55 }
56 @param n source object. 56
57 @return reference to this.
58 */
59 ast_node &operator = (const ast_node &n) { return *this; }
60
61 /** get the parent node.
62 @return the parent node, if there is one.
63 */
64 ast_node *parent() const { return m_parent; }
65
66 /** interface for filling the contents of the node 57 /** interface for filling the contents of the node
67 from a node stack. 58 from a node stack.
68 @param st stack. 59 @param st stack.
69 */ 60 */
70 virtual void construct(ast_stack &st) {} 61 virtual void construct(ast_stack& st) {}
71 62
72 /** interface for visiting AST tree use. 63 /** interface for visiting AST tree use.
73 */ 64 */
@@ -81,7 +72,11 @@ public:
81 72
82 virtual ast_node* getChild(int) const { return nullptr; } 73 virtual ast_node* getChild(int) const { return nullptr; }
83 74
84 virtual int getChildCount() const { return 0; } 75 virtual size_t getChildCount() const { return 0; }
76
77 virtual ast_node* getFirstChild() const { return nullptr; }
78
79 virtual ast_node* getLastChild() const { return nullptr; }
85 80
86 virtual size_t getId() const { return "ast_node"_id; } 81 virtual size_t getId() const { return "ast_node"_id; }
87 82
@@ -89,10 +84,8 @@ public:
89 84
90 virtual int get_type() { return ast_type<ast_node>(); } 85 virtual int get_type() { return ast_type<ast_node>(); }
91private: 86private:
92 //parent 87 int _ref;
93 ast_node *m_parent; 88 template <class T, bool OPT, bool MEM> friend class ast_ptr;
94
95 template <class T, bool OPT> friend class ast_ptr;
96 template <class ...Args> friend class ast_choice; 89 template <class ...Args> friend class ast_choice;
97 template <class T> friend class ast_list; 90 template <class T> friend class ast_list;
98 template <class T> friend class ast; 91 template <class T> friend class ast;
@@ -117,7 +110,7 @@ class ast_member;
117 110
118/** type of ast member vector. 111/** type of ast member vector.
119 */ 112 */
120typedef std::vector<ast_member *> ast_member_vector; 113typedef std::vector<ast_member*> ast_member_vector;
121 114
122 115
123/** base class for AST nodes with children. 116/** base class for AST nodes with children.
@@ -128,25 +121,10 @@ public:
128 */ 121 */
129 ast_container(); 122 ast_container();
130 123
131 /** sets the container under construction to be this.
132 Members are not copied.
133 @param src source object.
134 */
135 ast_container(const ast_container &src);
136
137 /** the assignment operator.
138 The members are not copied.
139 @param src source object.
140 @return reference to this.
141 */
142 ast_container &operator = (const ast_container &src) {
143 return *this;
144 }
145
146 /** returns the vector of AST members. 124 /** returns the vector of AST members.
147 @return the vector of AST members. 125 @return the vector of AST members.
148 */ 126 */
149 const ast_member_vector &members() const { 127 const ast_member_vector& members() const {
150 return m_members; 128 return m_members;
151 } 129 }
152 130
@@ -155,7 +133,7 @@ public:
155 from a node stack. 133 from a node stack.
156 @param st stack. 134 @param st stack.
157 */ 135 */
158 virtual void construct(ast_stack &st) override; 136 virtual void construct(ast_stack& st) override;
159 137
160 virtual ast_node* getByPath(std::initializer_list<std::size_t> paths) override; 138 virtual ast_node* getByPath(std::initializer_list<std::size_t> paths) override;
161 139
@@ -167,7 +145,11 @@ public:
167 145
168 virtual ast_node* getChild(int index) const override; 146 virtual ast_node* getChild(int index) const override;
169 147
170 virtual int getChildCount() const override; 148 virtual size_t getChildCount() const override;
149
150 virtual ast_node* getFirstChild() const override;
151
152 virtual ast_node* getLastChild() const override;
171 153
172 virtual size_t getId() const override { return "ast_container"_id; } 154 virtual size_t getId() const override { return "ast_container"_id; }
173 155
@@ -185,58 +167,76 @@ class ast_member {
185public: 167public:
186 /** automatically registers itself to the container under construction. 168 /** automatically registers itself to the container under construction.
187 */ 169 */
188 ast_member() { _init(); } 170 ast_member(bool is_member) {
171 if (is_member) add_to_owner();
172 }
189 173
190 /** automatically registers itself to the container under construction. 174 virtual ~ast_member() {}
191 @param src source object.
192 */
193 ast_member(const ast_member &src) { _init(); }
194
195 /** the assignment operator.
196 @param src source object.
197 @return reference to this.
198 */
199 ast_member &operator = (const ast_member &src) {
200 return *this;
201 }
202
203 /** returns the container this belongs to.
204 @return the container this belongs to.
205 */
206 ast_container *container() const { return m_container; }
207 175
208 /** interface for filling the the member from a node stack. 176 /** interface for filling the the member from a node stack.
209 @param st stack. 177 @param st stack.
210 */ 178 */
211 virtual void construct(ast_stack &st) = 0; 179 virtual void construct(ast_stack& st) = 0;
180
181 virtual bool accept(ast_node* node) = 0;
212 182
213 virtual int get_type() { return ast_type<ast_member>(); } 183 virtual int get_type() { return ast_type<ast_member>(); }
214private: 184private:
215 //the container this belongs to.
216 ast_container *m_container;
217
218 //register the AST member to the current container. 185 //register the AST member to the current container.
219 void _init(); 186 void add_to_owner();
220}; 187};
221 188
222template<class T> 189template<class T>
223T* ast_cast(ast_member *member) { 190T* ast_cast(ast_member* member) {
224 return member && ast_type<T>() == member->get_type() ? static_cast<T*>(member) : nullptr; 191 return member && ast_type<T>() == member->get_type() ? static_cast<T*>(member) : nullptr;
225} 192}
226 193
227class _ast_ptr : public ast_member { 194class _ast_ptr : public ast_member {
228public: 195public:
229 _ast_ptr(ast_node *node): m_ptr(node) {} 196 _ast_ptr(ast_node* node, bool is_member) : ast_member(is_member), m_ptr(node) {
197 if (node) node->retain();
198 }
199
200 virtual ~_ast_ptr() {
201 if (m_ptr) {
202 m_ptr->release();
203 m_ptr = nullptr;
204 }
205 }
230 206
231 ast_node* get() const { 207 ast_node* get() const {
232 return m_ptr; 208 return m_ptr;
233 } 209 }
234 210
211 template <class T>
212 T* as() const {
213 return ast_cast<T>(m_ptr);
214 }
215
216 template <class T>
217 T* to() const {
218 assert(m_ptr->getId() == ast_type<T>());
219 return static_cast<T*>(m_ptr);
220 }
221
222 void set(ast_node* node) {
223 if (node == m_ptr) return;
224 else if (!node) {
225 if (m_ptr) m_ptr->release();
226 m_ptr = nullptr;
227 }
228 else if (accept(node)) {
229 if (m_ptr) m_ptr->release();
230 m_ptr = node;
231 node->retain();
232 }
233 }
234
235 virtual int get_type() override { 235 virtual int get_type() override {
236 return ast_type<_ast_ptr>(); 236 return ast_type<_ast_ptr>();
237 } 237 }
238protected: 238protected:
239 ast_node *m_ptr; 239 ast_node* m_ptr;
240}; 240};
241 241
242/** pointer to an AST object. 242/** pointer to an AST object.
@@ -245,75 +245,37 @@ protected:
245 @tparam T type of object to control. 245 @tparam T type of object to control.
246 @tparam OPT if true, the object becomes optional. 246 @tparam OPT if true, the object becomes optional.
247 */ 247 */
248template <class T, bool OPT = false> class ast_ptr : public _ast_ptr { 248template <class T, bool OPT = false, bool MEM = true> class ast_ptr : public _ast_ptr {
249public: 249public:
250 /** the default constructor. 250 ast_ptr(T* node = nullptr) : _ast_ptr(node, MEM) {}
251 @param obj object.
252 */
253 ast_ptr(T *obj = nullptr) : _ast_ptr(obj) {
254 _set_parent();
255 }
256
257 /** the copy constructor.
258 It duplicates the underlying object.
259 @param src source object.
260 */
261 ast_ptr(const ast_ptr<T, OPT> &src) :
262 _ast_ptr(src.m_ptr ? new T(*src.m_ptr) : nullptr)
263 {
264 _set_parent();
265 }
266 251
267 /** deletes the underlying object. 252 ast_ptr(const ast_ptr<T, OPT, MEM>& other) : _ast_ptr(other.get(), MEM) {}
268 */
269 ~ast_ptr() {
270 delete m_ptr;
271 }
272 253
273 /** copies the given object. 254 ast_ptr<T, OPT, MEM>& operator=(const ast_ptr<T, OPT, MEM>& other) {
274 The old object is deleted. 255 set(other.get());
275 @param obj new object. 256 return *this;
276 @return reference to this. 257 }
277 */
278 ast_ptr<T, OPT> &operator = (const T *obj) {
279 delete m_ptr;
280 m_ptr = obj ? new T(*obj) : nullptr;
281 _set_parent();
282 return *this;
283 }
284
285 /** copies the underlying object.
286 The old object is deleted.
287 @param src source object.
288 @return reference to this.
289 */
290 ast_ptr<T, OPT> &operator = (const ast_ptr<T, OPT> &src) {
291 delete m_ptr;
292 m_ptr = src.m_ptr ? new T(*src.m_ptr) : nullptr;
293 _set_parent();
294 return *this;
295 }
296 258
297 /** gets the underlying ptr value. 259 /** gets the underlying ptr value.
298 @return the underlying ptr value. 260 @return the underlying ptr value.
299 */ 261 */
300 T *get() const { 262 T* get() const {
301 return static_cast<T*>(m_ptr); 263 return static_cast<T*>(m_ptr);
302 } 264 }
303 265
304 /** auto conversion to the underlying object ptr. 266 /** auto conversion to the underlying object ptr.
305 @return the underlying ptr value. 267 @return the underlying ptr value.
306 */ 268 */
307 operator T *() const { 269 operator T*() const {
308 return static_cast<T*>(m_ptr); 270 return static_cast<T*>(m_ptr);
309 } 271 }
310 272
311 /** member access. 273 /** member access.
312 @return the underlying ptr value. 274 @return the underlying ptr value.
313 */ 275 */
314 T *operator ->() const { 276 T* operator->() const {
315 assert(m_ptr); 277 assert(m_ptr);
316 return m_ptr; 278 return static_cast<T*>(m_ptr);
317 } 279 }
318 280
319 /** Pops a node from the stack. 281 /** Pops a node from the stack.
@@ -321,118 +283,120 @@ public:
321 @exception std::logic_error thrown if the node is not of the appropriate type; 283 @exception std::logic_error thrown if the node is not of the appropriate type;
322 thrown only if OPT == false or if the stack is empty. 284 thrown only if OPT == false or if the stack is empty.
323 */ 285 */
324 virtual void construct(ast_stack &st) { 286 virtual void construct(ast_stack& st) override {
325 //check the stack node 287 //check the stack node
326 if (st.empty()) { 288 if (st.empty()) {
327 if (OPT) return; 289 if (OPT) return;
328 else throw std::logic_error("invalid AST stack"); 290 else throw std::logic_error("invalid AST stack");
329 } 291 }
330 292
331 //get the node 293 ast_node* node = st.back();
332 ast_node *node = st.back(); 294
333 295 if (!ast_ptr::accept(node)) {
334 //get the object 296 //if the object is optional, simply return
335 T *obj = std::is_same<T, ast_node>() ? static_cast<T*>(node) : ast_cast<T>(node); 297 if (OPT) {
336 298 return;
337 //if the object is optional, simply return 299 } else { //else if the object is mandatory, throw an exception
338 if (OPT) { 300 throw std::logic_error("invalid AST node");
339 if (!obj) return; 301 }
340 } 302 }
341 303
342 //else if the object is mandatory, throw an exception
343 else {
344 if (!obj) throw std::logic_error("invalid AST node");
345 }
346
347 //pop the node from the stack
348 st.pop_back(); 304 st.pop_back();
349 305
350 //set the new object 306 m_ptr = node;
351 delete m_ptr; 307 node->retain();
352 m_ptr = obj;
353 _set_parent();
354 } 308 }
355private: 309private:
356 //set parent of object 310 virtual bool accept(ast_node* node) override {
357 void _set_parent() { 311 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type());
358 if (m_ptr) m_ptr->m_parent = container(); 312 }
359 }
360}; 313};
361 314
315template<class T>
316inline ast_ptr<T, false, false> new_ptr() {
317 return ast_ptr<T, false, false>(new T);
318}
319
362template <class ...Args> class ast_choice : public _ast_ptr { 320template <class ...Args> class ast_choice : public _ast_ptr {
363public: 321public:
364 ast_choice(ast_node *obj = nullptr) : _ast_ptr(obj) { 322 ast_choice() : _ast_ptr(nullptr, true) {}
365 _set_parent();
366 }
367
368 ast_choice(const ast_choice<Args...> &src) :
369 _ast_ptr(src.m_ptr ? new ast_node(*src.m_ptr) : nullptr)
370 {
371 _set_parent();
372 }
373 323
374 ~ast_choice() { 324 ast_choice(const ast_choice<Args...>& other) : _ast_ptr(other.get(), true) {}
375 delete m_ptr;
376 }
377
378 ast_choice<Args...> &operator = (const ast_node *obj) {
379 delete m_ptr;
380 m_ptr = obj ? new ast_node(*obj) : nullptr;
381 _set_parent();
382 return *this;
383 }
384 325
385 ast_choice<Args...> &operator = (const ast_choice<Args...> &src) { 326 ast_choice<Args...>& operator=(const ast_choice<Args...>& other) {
386 delete m_ptr; 327 set(other.get());
387 m_ptr = src.m_ptr ? new ast_node(*src.m_ptr) : nullptr; 328 return *this;
388 _set_parent(); 329 }
389 return *this;
390 }
391 330
392 operator ast_node *() const { 331 operator ast_node*() const {
393 return m_ptr; 332 return m_ptr;
394 } 333 }
395 334
396 ast_node *operator ->() const { 335 ast_node* operator->() const {
397 assert(m_ptr); 336 assert(m_ptr);
398 return m_ptr; 337 return m_ptr;
399 } 338 }
400 339
401 virtual void construct(ast_stack &st) { 340 virtual void construct(ast_stack& st) override {
402 if (st.empty()) { 341 if (st.empty()) {
403 throw std::logic_error("invalid AST stack"); 342 throw std::logic_error("invalid AST stack");
404 } 343 }
405 344
406 ast_node *node = st.back(); 345 ast_node* node = st.back();
407 ast_node *obj = nullptr;
408
409 using swallow = bool[];
410 (void)swallow{obj || (obj = std::is_same<Args, ast_node>() ? node : ast_cast<Args>(node))...};
411 346
412 if (!obj) throw std::logic_error("invalid AST node"); 347 if (!ast_choice::accept(node)) throw std::logic_error("invalid AST node");
413 348
414 st.pop_back(); 349 st.pop_back();
415 350
416 delete m_ptr; 351 m_ptr = node;
417 m_ptr = obj; 352 node->retain();
418 _set_parent();
419 } 353 }
420private: 354private:
421 void _set_parent() { 355 virtual bool accept(ast_node* node) override {
422 if (m_ptr) m_ptr->m_parent = container(); 356 if (!node) return false;
423 } 357 using swallow = bool[];
358 bool* result = nullptr;
359 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...};
360 return result;
361 }
424}; 362};
425 363
426class _ast_list : public ast_member { 364class _ast_list : public ast_member {
427public: 365public:
428 ///list type. 366 typedef std::list<ast_node*> container;
429 typedef std::list<ast_node *> container;
430 367
431 virtual int get_type() override { return ast_type<_ast_list>(); } 368 _ast_list() : ast_member(true) {}
369
370 ~_ast_list() {
371 clear();
372 }
373
374 void add(ast_node* node) {
375 if (accept(node)) {
376 m_objects.push_back(node);
377 node->retain();
378 }
379 }
432 380
433 const container &objects() const { 381 const container& objects() const {
434 return m_objects; 382 return m_objects;
435 } 383 }
384
385 void clear() {
386 for(ast_node* obj : m_objects) {
387 if (obj) obj->release();
388 }
389 m_objects.clear();
390 }
391
392 void dup(const _ast_list& src) {
393 for(ast_node* obj : src.m_objects) {
394 m_objects.push_back(obj);
395 obj->retain();
396 }
397 }
398
399 virtual int get_type() override { return ast_type<_ast_list>(); }
436protected: 400protected:
437 container m_objects; 401 container m_objects;
438}; 402};
@@ -447,86 +411,39 @@ public:
447 ///the default constructor. 411 ///the default constructor.
448 ast_list() {} 412 ast_list() {}
449 413
450 /** duplicates the objects of the given list. 414 ast_list(const ast_list<T>& other) {
451 @param src source object. 415 clear();
452 */ 416 dup(other);
453 ast_list(const ast_list<T> &src) { 417 }
454 _dup(src);
455 }
456
457 /** deletes the objects.
458 */
459 ~ast_list() {
460 _clear();
461 }
462
463 /** deletes the objects of this list and duplicates the given one.
464 @param src source object.
465 @return reference to this.
466 */
467 ast_list<T> &operator = (const ast_list<T> &src) {
468 if (&src != this) {
469 _clear();
470 _dup(src);
471 }
472 return *this;
473 }
474 418
475 /** returns the container of objects. 419 ast_list<T>& operator=(const ast_list<T>& other) {
476 @return the container of objects. 420 clear();
477 */ 421 dup(other);
478 const container &objects() const { 422 return *this;
479 return m_objects; 423 }
480 }
481 424
482 /** Pops objects of type T from the stack until no more objects can be popped. 425 /** Pops objects of type T from the stack until no more objects can be popped.
483 @param st stack. 426 @param st stack.
484 */ 427 */
485 virtual void construct(ast_stack &st) override { 428 virtual void construct(ast_stack &st) override {
486 for(;;) { 429 while (!st.empty()) {
487 //if the stack is empty 430 ast_node* node = st.back();
488 if (st.empty()) break; 431
489
490 //get the node
491 ast_node *node = st.back();
492
493 //get the object
494 T *obj = std::is_same<T, ast_node>() ? static_cast<T*>(node) : ast_cast<T>(node);
495
496 //if the object was not not of the appropriate type, 432 //if the object was not not of the appropriate type,
497 //end the list parsing 433 //end the list parsing
498 if (!obj) return; 434 if (!ast_list::accept(node)) return;
499 435
500 //remove the node from the stack
501 st.pop_back(); 436 st.pop_back();
502 437
503 //insert the object in the list, in reverse order 438 //insert the object in the list, in reverse order
504 m_objects.push_front(obj); 439 m_objects.push_front(node);
505 440 node->retain();
506 //set the object's parent
507 obj->m_parent = ast_member::container();
508 } 441 }
509 } 442 }
510private: 443private:
511 //deletes the objects of this list. 444 virtual bool accept(ast_node* node) override {
512 void _clear() { 445 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type());
513 while (!m_objects.empty()) { 446 }
514 delete m_objects.back();
515 m_objects.pop_back();
516 }
517 }
518
519 //duplicate the given list.
520 void _dup(const ast_list<T> &src) {
521 for(typename container::const_iterator it = src.m_objects.begin();
522 it != src.m_objects.end();
523 ++it)
524 {
525 T *obj = new T(*it);
526 m_objects.push_back(obj);
527 obj->m_parent = ast_member::container();
528 }
529 }
530}; 447};
531 448
532 449
@@ -538,15 +455,15 @@ public:
538 /** constructor. 455 /** constructor.
539 @param r rule to attach the AST function to. 456 @param r rule to attach the AST function to.
540 */ 457 */
541 ast(rule &r) { 458 ast(rule& r) {
542 r.set_parse_proc(&_parse_proc); 459 r.set_parse_proc(&_parse_proc);
543 } 460 }
544 461
545private: 462private:
546 //parse proc 463 //parse proc
547 static void _parse_proc(const pos &b, const pos &e, void *d) { 464 static void _parse_proc(const pos& b, const pos& e, void* d) {
548 ast_stack *st = reinterpret_cast<ast_stack *>(d); 465 ast_stack* st = reinterpret_cast<ast_stack*>(d);
549 T *obj = new T; 466 T* obj = new T;
550 obj->m_begin = b; 467 obj->m_begin = b;
551 obj->m_end = e; 468 obj->m_end = e;
552 obj->construct(*st); 469 obj->construct(*st);
@@ -563,23 +480,27 @@ private:
563 @return pointer to ast node created, or null if there was an error. 480 @return pointer to ast node created, or null if there was an error.
564 The return object must be deleted by the caller. 481 The return object must be deleted by the caller.
565 */ 482 */
566ast_node *parse(input &i, rule &g, error_list &el, void* ud); 483ast_node* _parse(input &i, rule &g, error_list &el, void* ud);
567 484
568 485
569/** parses the given input. 486/** parses the given input.
570 @param i input. 487 @param i input.
571 @param g root rule of grammar. 488 @param g root rule of grammar.
572 @param el list of errors. 489 @param el list of errors.
573 @param ast result pointer to created ast.
574 @param ud user data, passed to the parse procedures. 490 @param ud user data, passed to the parse procedures.
575 @return true on success, false on error. 491 @return ast nodes.
576 */ 492 */
577template <class T> bool parse(input &i, rule &g, error_list &el, T *&ast, void* ud = nullptr) { 493template <class T> ast_ptr<T, false, false> parse(input &i, rule &g, error_list &el, void* ud = nullptr) {
578 ast_node *node = parse(i, g, el, ud); 494 ast_node* node = _parse(i, g, el, ud);
579 ast = ast_cast<T>(node); 495 T* ast = ast_cast<T>(node);
580 if (ast) return true; 496 ast_ptr<T, false, false> ptr;
581 delete node; 497 if (ast) {
582 return false; 498 ast_stack st{node};
499 ptr.construct(st);
500 } else if (node) {
501 delete node;
502 }
503 return ptr;
583} 504}
584 505
585 506
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp
index a98e75e..3c433ae 100644
--- a/MoonParser/moon_ast.cpp
+++ b/MoonParser/moon_ast.cpp
@@ -151,16 +151,16 @@ public:
151 void complile(const std::string& codes) { 151 void complile(const std::string& codes) {
152 input input = _converter.from_bytes(codes); 152 input input = _converter.from_bytes(codes);
153 error_list el; 153 error_list el;
154 BlockEnd_t* root = nullptr;
155 State st; 154 State st;
156 if (parse(input, BlockEnd, el, root, &st)) { 155 auto root = parse<BlockEnd_t>(input, BlockEnd, el, &st);
157 std::cout << "matched!\n"; 156 if (root) {
157 std::cout << "compiled!\n\n";
158 std::vector<std::string> out; 158 std::vector<std::string> out;
159 root->eachChild([&](ast_node* node) { 159 root->eachChild([&](ast_node* node) {
160 switch (node->getId()) { 160 switch (node->getId()) {
161 case "Block"_id: 161 case "Block"_id:
162 pushScope(); 162 pushScope();
163 transformBody(node, out); 163 transformBody(static_cast<Body_t*>(node), out, true);
164 popScope(); 164 popScope();
165 break; 165 break;
166 default: break; 166 default: break;
@@ -170,20 +170,21 @@ public:
170 if (out.size() == 1) { 170 if (out.size() == 1) {
171 result = std::move(out.front()); 171 result = std::move(out.front());
172 } else if (out.size() > 1) { 172 } else if (out.size() > 1) {
173 result = join(out, "\n"); 173 result = join(out, "\n"sv);
174 } 174 }
175 std::cout << result << '\n'; 175 std::cout << result << '\n';
176 } else { 176 } else {
177 std::cout << "not matched!\n"; 177 std::cout << "compile failed!\n";
178 for (error_list::iterator it = el.begin(); it != el.end(); ++it) { 178 for (error_list::iterator it = el.begin(); it != el.end(); ++it) {
179 const error& err = *it; 179 const error& err = *it;
180 std::cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n"; 180 std::cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n";
181 } 181 }
182 } 182 }
183 _codeCache.clear();
183 } 184 }
184
185private: 185private:
186 Converter _converter; 186 Converter _converter;
187 std::vector<input> _codeCache;
187 std::ostringstream _buf; 188 std::ostringstream _buf;
188 std::string _newLine = "\n"; 189 std::string _newLine = "\n";
189 std::vector<int> _lineTable; 190 std::vector<int> _lineTable;
@@ -199,7 +200,11 @@ private:
199 _scopes.back().vars = MakeUnique<std::unordered_set<std::string>>(); 200 _scopes.back().vars = MakeUnique<std::unordered_set<std::string>>();
200 } 201 }
201 202
202 bool isDefined(const std::string& name, bool checkShadowScope = false) { 203 void popScope() {
204 _scopes.pop_back();
205 }
206
207 bool isDefined(const std::string& name, bool checkShadowScopeOnly = false) {
203 bool isDefined = false; 208 bool isDefined = false;
204 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { 209 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
205 auto vars = it->vars.get(); 210 auto vars = it->vars.get();
@@ -207,7 +212,7 @@ private:
207 isDefined = true; 212 isDefined = true;
208 break; 213 break;
209 } 214 }
210 if (checkShadowScope && it->allows) break; 215 if (checkShadowScopeOnly && it->allows) break;
211 } 216 }
212 return isDefined; 217 return isDefined;
213 } 218 }
@@ -244,8 +249,15 @@ private:
244 return !defined; 249 return !defined;
245 } 250 }
246 251
247 void popScope() { 252 std::string getValidName(std::string_view name) {
248 _scopes.pop_back(); 253 int index = 0;
254 std::string newName;
255 do {
256 _buf << name << index;
257 newName = clearBuf();
258 index++;
259 } while (isDefined(newName));
260 return newName;
249 } 261 }
250 262
251 const std::string nll(ast_node* node) { 263 const std::string nll(ast_node* node) {
@@ -259,7 +271,11 @@ private:
259 } 271 }
260 272
261 std::string indent() { 273 std::string indent() {
262 return std::string(_scopes.size() - 1, '\t'); 274 return std::string((_scopes.size() - 1) * 2, ' ');
275 }
276
277 std::string indent(int offset) {
278 return std::string((_scopes.size() - 1 + offset) * 2, ' ');
263 } 279 }
264 280
265 std::string clearBuf() { 281 std::string clearBuf() {
@@ -285,335 +301,530 @@ private:
285 } 301 }
286 302
287 std::string toString(ast_node* node) { 303 std::string toString(ast_node* node) {
288 auto str = _converter.to_bytes(std::u32string(node->m_begin.m_it, node->m_end.m_it)); 304 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
305 return trim(str);
306 }
307
308 std::string toString(input::iterator begin, input::iterator end) {
309 auto str = _converter.to_bytes(std::wstring(begin, end));
289 return trim(str); 310 return trim(str);
290 } 311 }
291 312
292 void noop(ast_node* node, std::vector<std::string>& out) { 313 void noop(ast_node* node, std::vector<std::string>& out) {
293 auto str = _converter.to_bytes(std::u32string(node->m_begin.m_it, node->m_end.m_it)); 314 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
294 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str)); 315 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str));
295 // out.push_back(trim(str)); 316 // out.push_back(trim(str));
296 } 317 }
297 318
298 void noopnl(ast_node* node, std::vector<std::string>& out) { 319 void noopnl(ast_node* node, std::vector<std::string>& out) {
299 auto str = _converter.to_bytes(std::u32string(node->m_begin.m_it, node->m_end.m_it)); 320 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
300 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str) + nll(node)); 321 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str) + nll(node));
301 // out.push_back(trim(str) + nll(node)); 322 // out.push_back(trim(str) + nll(node));
302 } 323 }
303 324
304 void transformStatement(ast_node* statement, std::vector<std::string>& out) { 325 Value_t* singleValueFrom(ast_node* expList) {
305 std::vector<std::string> temp; 326 ast_node* singleValue = nullptr;
306 auto transformContent = [&](ast_node* node, std::vector<std::string>& out) { 327 expList->traverse([&](ast_node* n) {
307 switch (node->getId()) { 328 if (n->getId() == "Value"_id) {
308 case "Import"_id: transformImport(node, temp); break; 329 if (!singleValue) {
309 case "While"_id: transformWhile(node, temp); break; 330 singleValue = n;
310 case "With"_id: transformWith(node, temp); break; 331 return traversal::Return;
311 case "For"_id: transformFor(node, temp); break; 332 } else {
312 case "ForEach"_id: transformForEach(node, temp); break; 333 singleValue = nullptr;
313 case "Switch"_id: transformSwitch(node, temp); break; 334 return traversal::Stop;
314 case "Return"_id: transformReturn(node, temp); break; 335 }
315 case "Local"_id: transformLocal(node, temp); break; 336 }
316 case "Export"_id: transformExport(node, temp); break; 337 return traversal::Continue;
317 case "BreakLoop"_id: transformBreakLoop(node, temp); break; 338 });
318 case "Assignment"_id: transformAssignment(node, temp); break; 339 return static_cast<Value_t*>(singleValue);
319 case "ExpList"_id: 340 }
320 transformExpList(node, temp); 341
321 temp.back() = indent() + temp.back() + nll(node); 342 Statement_t* lastStatementFrom(ast_node* body) {
343 ast_node* last = nullptr;
344 body->traverse([&](ast_node* n) {
345 switch (n->getId()) {
346 case "Statement"_id:
347 last = n;
348 return traversal::Return;
349 default: return traversal::Continue;
350 }
351 });
352 return static_cast<Statement_t*>(last);
353 }
354
355 template <class T>
356 ast_ptr<T, false, false> toAst(std::string_view codes, rule& r) {
357 _codeCache.push_back(_converter.from_bytes(s(codes)));
358 error_list el;
359 State st;
360 return parse<T>(_codeCache.back(), r, el, &st);
361 }
362
363 void transformStatement(Statement_t* statement, std::vector<std::string>& out) {
364 if (statement->appendix) {
365 auto appendix = statement->appendix;
366 switch (appendix->item->getId()) {
367 case "if_else_line"_id: {
368 auto if_else_line = static_cast<if_else_line_t*>(appendix->item.get());
369 auto ifCond = new_ptr<IfCond_t>();
370 ifCond->condition = if_else_line->condition;
371
372 auto exprList = new_ptr<ExpList_t>();
373 exprList->exprs.add(if_else_line->elseExpr);
374 auto stmt = new_ptr<Statement_t>();
375 stmt->content.set(exprList);
376 auto body = new_ptr<Body_t>();
377 body->content.set(stmt);
378 auto ifElseIf = new_ptr<IfElseIf_t>();
379 ifElseIf->body.set(body);
380
381 stmt = new_ptr<Statement_t>();
382 stmt->content.set(statement->content);
383 body = new_ptr<Body_t>();
384 body->content.set(stmt);
385 auto ifNode = new_ptr<If_t>();
386 ifNode->firstCondition.set(ifCond);
387 ifNode->firstBody.set(body);
388 ifNode->branches.add(ifElseIf);
389
390 statement->appendix.set(nullptr);
391 auto simpleValue = new_ptr<SimpleValue_t>();
392 simpleValue->value.set(ifNode);
393 auto value = new_ptr<Value_t>();
394 value->item.set(simpleValue);
395 auto exp = new_ptr<Exp_t>();
396 exp->value.set(value);
397 exprList = new_ptr<ExpList_t>();
398 exprList->exprs.add(exp);
399 statement->content.set(exprList);
322 break; 400 break;
401 }
402 case "unless_line"_id: {
403 break;
404 }
405 case "CompInner"_id: {
406 break;
407 }
323 default: break; 408 default: break;
324 } 409 }
325 };
326 if (statement->getChildCount() > 1) {
327 pushScope();
328 transformContent(statement->getChild(0), out);
329 popScope();
330 transform_statement_appendix(statement->getChild(1), temp);
331 } else {
332 transformContent(statement->getChild(0), out);
333 } 410 }
334 switch (temp.size()) { 411 auto node = statement->content.get();
335 case 1: // body 412 if (!node) {
336 out.push_back(std::move(temp.front())); 413 out.push_back(Empty);
337 break; 414 return;
338 case 2: // body, if 415 }
339 out.push_back(join({std::move(temp[1]), std::move(temp[0]), s("end"sv) + nlr(statement)})); 416 switch (node->getId()) {
340 break; 417 case "Import"_id: transformImport(node, out); break;
341 case 3: // body, if, else 418 case "While"_id: transformWhile(node, out); break;
342 out.push_back(join({std::move(temp[1]), std::move(temp[0]), std::move(temp[2]), s("end"sv) + nlr(statement)})); 419 case "With"_id: transformWith(node, out); break;
420 case "For"_id: transformFor(static_cast<For_t*>(node), out); break;
421 case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(node), out); break;
422 case "Switch"_id: transformSwitch(node, out); break;
423 case "Return"_id: transformReturn(static_cast<Return_t*>(node), out); break;
424 case "Local"_id: transformLocal(node, out); break;
425 case "Export"_id: transformExport(node, out); break;
426 case "BreakLoop"_id: transformBreakLoop(node, out); break;
427 case "Assignment"_id: transformStatementAssign(statement, out); break;
428 case "ExpList"_id: {
429 auto expList = static_cast<ExpList_t*>(node);
430 if (expList->exprs.objects().empty()) {
431 out.push_back(Empty);
432 break;
433 }
434 if (auto singleValue = singleValueFrom(expList)) {
435 if (auto ifNode = static_cast<If_t*>(singleValue->getByPath({"SimpleValue"_id, "If"_id}))) {
436 transformIf(ifNode, out);
437 break;
438 }
439 if (singleValue->getByPath({"ChainValue"_id, "InvokeArgs"_id})) {
440 transformValue(singleValue, out);
441 out.back() = indent() + out.back() + nlr(singleValue);
442 break;
443 }
444 }
445 std::string preDefine;
446 if (addToScope(s("_"sv))) {
447 preDefine = indent() + s("local _"sv) + nll(expList);
448 }
449 preDefine.append(indent() + s("_ = "sv));
450 std::vector<std::string> temp;
451 transformExpList(expList, temp);
452 out.push_back(preDefine + temp.back() + nlr(expList));
343 break; 453 break;
454 }
455 default: break;
344 } 456 }
345 } 457 }
346 458
347 void transform_statement_appendix(ast_node* appendix, std::vector<std::string>& out) { 459 std::string transformAssignDefs(ExpList_t* expList) {
348 appendix->eachChild([&](ast_node* node) { 460 std::vector<std::string> preDefs;
349 switch (node->getId()) { 461 std::vector<ast_node*> values;
350 case "if_else_line"_id: transform_if_else_line(node, out); break; 462 expList->traverse([&](ast_node* child) {
351 case "unless_line"_id: transform_unless_line(node, out); break; 463 if (child->getId() == "Value"_id) {
352 case "CompInner"_id: transformCompInner(node, out); break; 464 auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Name"_id});
353 default: break; 465 if (target) {
466 auto name = toString(target);
467 if (addToScope(name)) {
468 preDefs.push_back(name);
469 }
470 }
471 return traversal::Return;
354 } 472 }
473 return traversal::Continue;
355 }); 474 });
475 if (!preDefs.empty()) {
476 return indent() + s("local "sv) + join(preDefs, ", "sv);
477 }
478 return std::string();
356 } 479 }
357 480
358 void transform_if_else_line(ast_node* if_else_line, std::vector<std::string>& out) { 481 void transformStatementAssign(Statement_t* statement, std::vector<std::string>& out) {
359 std::vector<std::string> temp; 482 auto assignment = static_cast<Assignment_t*>(statement->content.get());
360 if_else_line->eachChild([&](ast_node* node) { 483 if (auto ifNode = assignment->getByPath({"Assign"_id, "If"_id})) {
361 switch (node->getId()) { 484 auto expList = assignment->assignable.get();
362 case "Exp"_id: 485 std::vector<std::string> temp;
486 std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs;
487 ifCondPairs.emplace_back();
488 std::string preDefine = transformAssignDefs(expList);
489 if (!preDefine.empty()) temp.push_back(preDefine + nll(expList));
490 ifNode->traverse([&](ast_node* node) {
491 switch (node->getId()) {
492 case "IfCond"_id:
493 ifCondPairs.back().first = static_cast<IfCond_t*>(node);
494 return traversal::Return;
495 case "Body"_id:
496 ifCondPairs.back().second = static_cast<Body_t*>(node);
497 ifCondPairs.emplace_back();
498 return traversal::Return;
499 default: return traversal::Continue;
500 }
501 });
502 for (const auto& pair : ifCondPairs) {
503 if (pair.first) {
504 std::vector<std::string> tmp;
505 auto condition = pair.first->condition.get();
506 transformExp(condition, tmp);
507 _buf << indent() << (pair == ifCondPairs.front() ? ""sv : "else"sv) <<
508 "if "sv << tmp.front() << " then"sv << nll(condition);
509 temp.push_back(clearBuf());
510 }
511 if (pair.second) {
512 if (!pair.first) {
513 temp.push_back(indent() + s("else"sv) + nll(pair.second));
514 }
515 auto last = lastStatementFrom(pair.second);
516 auto valueList = last ? last->content.as<ExpList_t>() : nullptr;
517 if (last && valueList) {
518 auto newAssignment = new_ptr<Assignment_t>();
519 newAssignment->assignable.set(expList);
520 auto assign = new_ptr<Assign_t>();
521 if (valueList->getChildCount() == 2) {
522 if (auto subIfNode = valueList->getByPath({
523 "Exp"_id, "Value"_id, "SimpleValue"_id, "If"_id})) {
524 assign->value.set(subIfNode);
525 }
526 }
527 if (!assign->value) {
528 auto expListLow = new_ptr<ExpListLow_t>();
529 expListLow->exprs = valueList->exprs;
530 assign->value.set(expListLow);
531 }
532 newAssignment->target.set(assign);
533 last->content.set(newAssignment);
534 }
363 pushScope(); 535 pushScope();
364 transformExp(node, temp); 536 transformBody(pair.second, temp);
365 popScope(); 537 popScope();
366 break; 538 if (!pair.first) {
367 default: break; 539 temp.push_back(indent() + s("end"sv) + nll(pair.second));
540 }
541 }
368 } 542 }
369 }); 543 out.push_back(join(temp));
370 out.push_back(indent() + s("if "sv) + temp[0] + s(" then"sv) + nll(if_else_line)); 544 return;
371 out.push_back(indent() + s("else "sv) + nll(if_else_line) + indent() + '\t' + temp[1] + nll(if_else_line)); 545 }
546 if (auto expList = assignment->getByPath({"Assign"_id, "ExpListLow"_id})) {
547 auto singleValue = singleValueFrom(expList);
548 if (singleValue && singleValue->item->getId() == "SimpleValue"_id) {
549 auto valueItem = singleValue->item->getFirstChild();
550 switch (valueItem->getId()) {
551 case "Comprehension"_id: {
552 std::vector<std::string> temp;
553 auto expList = assignment->assignable.get();
554 transformExpList(expList, temp);
555 transformCompInPlace(static_cast<Comprehension_t*>(valueItem), temp.front(), temp);
556 std::string preDefine = transformAssignDefs(expList);
557 out.push_back(preDefine + nll(statement) + temp.back());
558 return;
559 }
560 case "For"_id: {
561 std::vector<std::string> temp;
562 auto expList = assignment->assignable.get();
563 std::string preDefine = transformAssignDefs(expList);
564 transformForInPlace(static_cast<For_t*>(valueItem), temp, expList);
565 out.push_back(preDefine + nll(statement) + temp.front());
566 return;
567 }
568 case "ForEach"_id: {
569 std::vector<std::string> temp;
570 auto expList = assignment->assignable.get();
571 std::string preDefine = transformAssignDefs(expList);
572 transformForEachInPlace(static_cast<ForEach_t*>(valueItem), temp, expList);
573 out.push_back(preDefine + nll(statement) + temp.front());
574 return;
575 }
576 }
577 }
578 }
579 transformAssignment(assignment, out);
372 } 580 }
373 581
374 void transformAssignment(ast_node* assignment, std::vector<std::string>& out) { 582 void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) {
375 std::vector<std::string> temp; 583 std::vector<std::string> temp;
376 std::string preDefined; 584 auto expList = assignment->assignable.get();
377 assignment->eachChild([&](ast_node* node) { 585 auto action = assignment->target.get();
378 switch (node->getId()) { 586 std::string preDefine = transformAssignDefs(expList);
379 case "ExpList"_id: { 587 transformExpList(expList, temp);
380 std::vector<std::string> preDefs; 588 bool oneLined = expList->getChildCount() == 2 &&
381 std::vector<ast_node*> values; 589 traversal::Stop != action->traverse([&](ast_node* node) {
382 node->traverse([&](ast_node* child) { 590 if (node->getId() == "FunLit"_id) {
383 if (child->getId() == "Value"_id) { 591 if (auto body = node->getByPath({"Body"_id})) {
384 auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Name"_id}); 592 if (traversal::Stop == body->traverse([&](ast_node* n) {
385 if (target) { 593 if (n->getId() == "Callable"_id) {
386 auto name = toString(target); 594 if (auto name = n->getByPath({"Name"_id})) {
387 if (addToScope(name)) { 595 if (temp.front() ==toString(name)) {
388 preDefs.push_back(name); 596 return traversal::Stop;
597 }
389 } 598 }
390 } 599 }
391 return traversal::Return; 600 return traversal::Continue;
601 })) {
602 return traversal::Stop;
392 } 603 }
393 return traversal::Continue;
394 });
395 if (!preDefs.empty()) {
396 preDefined = indent() + s("local "sv) + join(preDefs, ", "sv) + nll(node);
397 } 604 }
398 transformExpList(node, temp);
399 break;
400 } 605 }
401 case "Update"_id: transformUpdate(node, temp); break; 606 return traversal::Continue;
402 case "Assign"_id: { 607 });
403 auto child = node->getChild(0); 608 switch (action->getId()) {
404 switch (child->getId()) { 609 case "Update"_id: transformUpdate(action, temp); break;
405 case "With"_id: transformWith(child, temp); break; 610 case "Assign"_id: {
406 case "If"_id: 611 auto child = action->getFirstChild();
407 transformIfClosure(child, temp); 612 switch (child->getId()) {
408 break; 613 case "With"_id: transformWith(child, temp); break;
409 case "Switch"_id: transformSwitch(child, temp); break; 614 case "If"_id: transformIfClosure(static_cast<If_t*>(child), temp); break;
410 case "TableBlock"_id: transformTableBlock(child, temp); break; 615 case "Switch"_id: transformSwitch(child, temp); break;
411 case "ExpListLow"_id: 616 case "TableBlock"_id: transformTableBlock(child, temp); break;
412 transformExpListLow(child, temp); 617 case "ExpListLow"_id: transformExpListLow(static_cast<ExpListLow_t*>(child), temp); break;
413 break; 618 default: break;
414 default: break;
415 }
416 break;
417 } 619 }
418 default: break; 620 break;
419 } 621 }
420 }); 622 default: break;
421 out.push_back(preDefined + indent() + temp[0] + s(" = "sv) + temp[1] + nll(assignment)); 623 }
624 if (oneLined) {
625 out.push_back((preDefine.empty() ? indent() + temp[0] : preDefine) + s(" = "sv) + temp[1] + nll(assignment));
626 } else {
627 out.push_back((preDefine.empty() ? Empty : preDefine + nll(assignment)) + indent() + temp[0] + s(" = "sv) + temp[1] + nll(assignment));
628 }
422 } 629 }
423 void transformIfClosure(ast_node* ifNode, std::vector<std::string>& out) { 630
631 void transformIf(If_t* ifNode, std::vector<std::string>& out, bool withClosure = false) {
424 std::vector<std::string> temp; 632 std::vector<std::string> temp;
425 temp.push_back(s("(function()"sv) + nll(ifNode)); 633 if (withClosure) {
426 pushScope(); 634 temp.push_back(s("(function()"sv) + nll(ifNode));
635 pushScope();
636 }
637 std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs;
638 ifCondPairs.emplace_back();
427 ifNode->traverse([&](ast_node* node) { 639 ifNode->traverse([&](ast_node* node) {
428 switch (node->getId()) { 640 switch (node->getId()) {
429 case "IfCond"_id: { 641 case "IfCond"_id:
430 std::vector<std::string> tmp; 642 ifCondPairs.back().first = static_cast<IfCond_t*>(node);
431 auto exp = node->getChild(0);
432 transformExp(exp, tmp);
433 _buf << indent() << "if "sv << tmp.front() << " then"sv << nll(exp);
434 temp.push_back(clearBuf());
435 return traversal::Return; 643 return traversal::Return;
436 }
437 case "Body"_id: 644 case "Body"_id:
438 transformBody(node, temp); 645 ifCondPairs.back().second = static_cast<Body_t*>(node);
646 ifCondPairs.emplace_back();
439 return traversal::Return; 647 return traversal::Return;
440 default: return traversal::Continue; 648 default: return traversal::Continue;
441 } 649 }
442 }); 650 });
443 popScope(); 651 for (const auto& pair : ifCondPairs) {
444 temp.push_back(indent() + s("end)()"sv)); 652 if (pair.first) {
653 std::vector<std::string> tmp;
654 auto condition = pair.first->condition.get();
655 transformExp(condition, tmp);
656 _buf << indent() << (pair == ifCondPairs.front() ? ""sv : "else"sv) <<
657 "if "sv << tmp.front() << " then"sv << nll(condition);
658 temp.push_back(clearBuf());
659 }
660 if (pair.second) {
661 if (!pair.first) {
662 temp.push_back(indent() + s("else"sv) + nll(pair.second));
663 }
664 pushScope();
665 transformBody(pair.second, temp, withClosure);
666 popScope();
667 if (!pair.first) {
668 temp.push_back(indent() + s("end"sv) + nll(pair.second));
669 }
670 }
671 }
672 if (withClosure) {
673 popScope();
674 temp.push_back(indent() + s("end)()"sv));
675 }
445 out.push_back(join(temp)); 676 out.push_back(join(temp));
446 } 677 }
447 678
448 void transformExpList(ast_node* expList, std::vector<std::string>& out) { 679 void transformIfClosure(If_t* ifNode, std::vector<std::string>& out) {
680 transformIf(ifNode, out, true);
681 }
682
683 void transformExpList(ExpList_t* expList, std::vector<std::string>& out) {
449 std::vector<std::string> temp; 684 std::vector<std::string> temp;
450 expList->eachChild([&](ast_node* node) { 685 for (auto exp : expList->exprs.objects()) {
451 switch (node->getId()) { 686 transformExp(static_cast<Exp_t*>(exp), temp);
452 case "Exp"_id: transformExp(node, temp); break; 687 }
453 default: break;
454 }
455 });
456 out.push_back(join(temp, ", "sv)); 688 out.push_back(join(temp, ", "sv));
457 } 689 }
458 690
459 void transformExpListLow(ast_node* expListLow, std::vector<std::string>& out) { 691 void transformExpListLow(ExpListLow_t* expListLow, std::vector<std::string>& out) {
460 std::vector<std::string> temp; 692 std::vector<std::string> temp;
461 expListLow->eachChild([&](ast_node* node) { 693 for (auto exp : expListLow->exprs.objects()) {
462 switch (node->getId()) { 694 transformExp(static_cast<Exp_t*>(exp), temp);
463 case "Exp"_id: transformExp(node, temp); break; 695 }
464 default: break;
465 }
466 });
467 out.push_back(join(temp, ", "sv)); 696 out.push_back(join(temp, ", "sv));
468 } 697 }
469 698
470 void transformExp(ast_node* exp, std::vector<std::string>& out) { 699 void transformExp(Exp_t* exp, std::vector<std::string>& out) {
471 std::vector<std::string> temp; 700 std::vector<std::string> temp;
472 exp->eachChild([&](ast_node* node) { 701 transformValue(exp->value, temp);
473 switch (node->getId()) { 702 for (auto _opValue : exp->opValues.objects()) {
474 case "Value"_id: transformValue(node, temp); break; 703 auto opValue = static_cast<exp_op_value_t*>(_opValue);
475 case "exp_op_value"_id: transform_exp_op_value(node, temp); break; 704 transformBinaryOperator(opValue->op, temp);
476 default: break; 705 transformValue(opValue->value, temp);
477 } 706 }
478 });
479 out.push_back(join(temp, " "sv)); 707 out.push_back(join(temp, " "sv));
480 } 708 }
481 709
482 void transform_exp_op_value(ast_node* exp_op_value, std::vector<std::string>& out) { 710 void transformValue(Value_t* value, std::vector<std::string>& out) {
483 exp_op_value->eachChild([&](ast_node* node) { 711 auto item = value->item.get();
484 switch (node->getId()) { 712 switch (item->getId()) {
485 case "BinaryOperator"_id: transformBinaryOperator(node, out); break; 713 case "SimpleValue"_id: transformSimpleValue(static_cast<SimpleValue_t*>(item), out); break;
486 case "Value"_id: transformValue(node, out); break; 714 case "simple_table"_id: transform_simple_table(item, out); break;
487 default: break; 715 case "ChainValue"_id: transformChainValue(static_cast<ChainValue_t*>(item), out); break;
488 } 716 case "String"_id: transformString(static_cast<String_t*>(item), out); break;
489 }); 717 default: break;
490 } 718 }
491
492 void transformValue(ast_node* value, std::vector<std::string>& out) {
493 value->eachChild([&](ast_node* node) {
494 switch (node->getId()) {
495 case "SimpleValue"_id: transformSimpleValue(node, out); break;
496 case "simple_table"_id: transform_simple_table(node, out); break;
497 case "ChainValue"_id: transformChainValue(node, out); break;
498 case "String"_id: transformString(node, out); break;
499 default: break;
500 }
501 });
502 } 719 }
503 720
504 void transformChainValue(ast_node* chainValue, std::vector<std::string>& out) { 721 void transformChainValue(ChainValue_t* chainValue, std::vector<std::string>& out) {
505 std::vector<std::string> temp; 722 std::vector<std::string> temp;
506 bool hasInvokeArgs = false; 723 auto caller = chainValue->caller.get();
507 chainValue->eachChild([&](ast_node* node) { 724 switch (caller->getId()) {
508 switch (node->getId()) { 725 case "Chain"_id: transformChain(static_cast<Chain_t*>(caller), temp); break;
509 case "Chain"_id: transformChain(node, temp); break; 726 case "Callable"_id: transformCallable(static_cast<Callable_t*>(caller), temp, chainValue->arguments); break;
510 case "Callable"_id: transformCallable(node, temp); break; 727 default: break;
511 case "InvokeArgs"_id: 728 }
512 hasInvokeArgs = true; 729 if (chainValue->arguments) {
513 transformInvokeArgs(node, temp); 730 transformInvokeArgs(chainValue->arguments, temp);
514 break; 731 out.push_back(temp[0] + s("("sv) + temp[1] + s(")"sv));
515 default: break; 732 } else {
516 } 733 out.push_back(temp[0]);
517 }); 734 }
518 out.push_back(hasInvokeArgs ? (temp[0] + s("("sv) + temp[1] + s(")"sv)) : temp[0]);
519 } 735 }
520 736
521 void transformCallable(ast_node* callable, std::vector<std::string>& out) { 737 void transformCallable(Callable_t* callable, std::vector<std::string>& out, bool invoke) {
522 callable->eachChild([&](ast_node* node) { 738 auto item = callable->item.get();
523 switch (node->getId()) { 739 switch (item->getId()) {
524 case "Name"_id: transformName(node, out); break; 740 case "Name"_id: transformName(static_cast<Name_t*>(item), out); break;
525 case "SelfName"_id: transformSelfName(node, out); break; 741 case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(item), out, invoke); break;
526 case "VarArg"_id: transformVarArg(node, out); break; 742 case "VarArg"_id: out.push_back(s("..."sv)); break;
527 case "Parens"_id: transformParens(node, out); break; 743 case "Parens"_id: transformParens(static_cast<Parens_t*>(item), out); break;
528 default: break; 744 default: break;
529 } 745 }
530 });
531 } 746 }
532 747
533 void transformParens(ast_node* parans, std::vector<std::string>& out) { 748 void transformParens(Parens_t* parans, std::vector<std::string>& out) {
534 std::vector<std::string> temp; 749 std::vector<std::string> temp;
535 parans->eachChild([&](ast_node* node) { 750 transformExp(parans->expr, temp);
536 switch (node->getId()) {
537 case "Exp"_id: transformExp(node, temp); break;
538 default: break;
539 }
540 });
541 out.push_back(s("("sv) + temp.front() + s(")"sv)); 751 out.push_back(s("("sv) + temp.front() + s(")"sv));
542 } 752 }
543 753
544 void transformSimpleValue(ast_node* simpleValue, std::vector<std::string>& out) { 754 void transformSimpleValue(SimpleValue_t* simpleValue, std::vector<std::string>& out) {
545 simpleValue->eachChild([&](ast_node* node) { 755 auto node = simpleValue->value.get();
546 switch (node->getId()) { 756 switch (node->getId()) {
547 case "const_value"_id: transform_const_value(node, out); break; 757 case "const_value"_id: transform_const_value(node, out); break;
548 case "If"_id: transformIf(node, out); break; 758 case "If"_id: transformIfClosure(static_cast<If_t*>(node), out); break;
549 case "Switch"_id: transformSwitch(node, out); break; 759 case "Switch"_id: transformSwitch(node, out); break;
550 case "With"_id: transformWith(node, out); break; 760 case "With"_id: transformWith(node, out); break;
551 case "ClassDecl"_id: transformClassDecl(node, out); break; 761 case "ClassDecl"_id: transformClassDecl(node, out); break;
552 case "ForEach"_id: transformForEach(node, out); break; 762 case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(node), out); break;
553 case "For"_id: transformFor(node, out); break; 763 case "For"_id: transformForClosure(static_cast<For_t*>(node), out); break;
554 case "While"_id: transformWhile(node, out); break; 764 case "While"_id: transformWhile(node, out); break;
555 case "Do"_id: transformDo(node, out); break; 765 case "Do"_id: transformDo(node, out); break;
556 case "unary_exp"_id: transform_unary_exp(node, out); break; 766 case "unary_exp"_id: transform_unary_exp(static_cast<unary_exp_t*>(node), out); break;
557 case "TblComprehension"_id: transformTblComprehension(node, out); break; 767 case "TblComprehension"_id: transformTblComprehension(node, out); break;
558 case "TableLit"_id: transformTableLit(node, out); break; 768 case "TableLit"_id: transformTableLit(static_cast<TableLit_t*>(node), out); break;
559 case "Comprehension"_id: transformComprehension(node, out); break; 769 case "Comprehension"_id: transformComprehension(static_cast<Comprehension_t*>(node), out); break;
560 case "FunLit"_id: transformFunLit(node, out); break; 770 case "FunLit"_id: transformFunLit(static_cast<FunLit_t*>(node), out); break;
561 case "Num"_id: transformNum(node, out); break; 771 case "Num"_id: transformNum(static_cast<Num_t*>(node), out); break;
562 default: break; 772 default: break;
563 } 773 }
564 });
565 } 774 }
566 775
567 void transformFunLit(ast_node* funLit, std::vector<std::string>& out) { 776 void transformFunLit(FunLit_t* funLit, std::vector<std::string>& out) {
568 std::vector<std::string> temp; 777 std::vector<std::string> temp;
569 bool isFatArrow = false; 778 bool isFatArrow = toString(funLit->arrow) == "=>"sv;
570 bool hasArgsDef = false;
571 ast_node* body = nullptr;
572 pushScope(); 779 pushScope();
573 funLit->eachChild([&](ast_node* node) { 780 if (auto argsDef = funLit->argsDef.get()) {
574 switch (node->getId()) { 781 transformFnArgsDef(argsDef, temp);
575 case "FnArgsDef"_id: 782 if (funLit->body) {
576 hasArgsDef = true; 783 transformBody(funLit->body, temp, true);
577 transformFnArgsDef(node, temp); 784 } else {
578 break; 785 temp.push_back(Empty);
579 case "fn_arrow"_id:
580 isFatArrow = toString(node) == "=>"sv;
581 break;
582 case "Body"_id:
583 transformBody(node, temp);
584 body = node;
585 break;
586 default: break;
587 } 786 }
588 });
589 popScope();
590 if (hasArgsDef) {
591 auto& args = temp[0]; 787 auto& args = temp[0];
592 auto& initArgs = temp[1]; 788 auto& initArgs = temp[1];
593 auto& bodyCodes = temp[2]; 789 auto& bodyCodes = temp[2];
594 _buf << "function("sv << 790 _buf << "function("sv <<
595 (isFatArrow ? s("self"sv) + s(args.empty() ? ""sv : ", "sv) : Empty) << 791 (isFatArrow ? s("self, "sv) : Empty) <<
596 args << ')' << nll(funLit) << 792 args << ')' << nlr(argsDef) <<
597 (initArgs.empty() ? Empty : initArgs) << 793 initArgs << bodyCodes;
598 (body ? bodyCodes : Empty) <<
599 indent() << "end"sv;
600 out.push_back(clearBuf());
601 } else { 794 } else {
602 auto& bodyCodes = temp[0]; 795 if (funLit->body) {
603 out.push_back( 796 transformBody(funLit->body, temp, true);
604 s("function()"sv) + nll(funLit) + 797 } else {
605 (body ? bodyCodes : Empty) + 798 temp.push_back(Empty);
606 indent() + s("end"sv) 799 }
607 ); 800 auto& bodyCodes = temp.back();
801 _buf << "function("sv <<
802 (isFatArrow ? s("self"sv) : Empty) <<
803 ')' << nll(funLit) << bodyCodes;
608 } 804 }
805 popScope();
806 _buf << indent() << "end"sv;
807 out.push_back(clearBuf());
609 } 808 }
610 809
611 void transformBody(ast_node* body, std::vector<std::string>& out) { 810 void transformBody(Body_t* body, std::vector<std::string>& out, bool implicitReturn = false) {
811 if (implicitReturn) {
812 auto last = lastStatementFrom(body);
813 if (ast_is<ExpList_t>(last->content)) {
814 auto expList = static_cast<ExpList_t*>(last->content.get());
815 auto expListLow = new_ptr<ExpListLow_t>();
816 expListLow->exprs = expList->exprs;
817 auto returnNode = new_ptr<Return_t>();
818 returnNode->valueList.set(expListLow);
819 auto statement = ast_cast<Statement_t>(last);
820 statement->content.set(returnNode);
821 }
822 }
612 std::vector<std::string> temp; 823 std::vector<std::string> temp;
613 body->traverse([&](ast_node* node) { 824 body->traverse([&](ast_node* node) {
614 switch (node->getId()) { 825 switch (node->getId()) {
615 case "Statement"_id: 826 case "Statement"_id:
616 transformStatement(node, temp); 827 transformStatement(static_cast<Statement_t*>(node), temp);
617 return traversal::Return; 828 return traversal::Return;
618 default: return traversal::Continue; 829 default: return traversal::Continue;
619 } 830 }
@@ -621,290 +832,739 @@ private:
621 out.push_back(join(temp)); 832 out.push_back(join(temp));
622 } 833 }
623 834
624 void transformFnArgsDef(ast_node* argsDef, std::vector<std::string>& out) { 835 void transformReturn(Return_t* returnNode, std::vector<std::string>& out) {
625 argsDef->eachChild([&](ast_node* node) { 836 if (auto valueList = returnNode->valueList.get()) {
626 switch (node->getId()) { 837 if (auto singleValue = singleValueFrom(valueList)) {
627 case "FnArgDefList"_id: transformFnArgDefList(node, out); break; 838 if (auto comp = singleValue->getByPath({"SimpleValue"_id, "Comprehension"_id})) {
628 case "outer_var_shadow"_id: transform_outer_var_shadow(node, out); break; 839 transformCompReturn(static_cast<Comprehension_t*>(comp), out);
629 default: break; 840 } else {
841 transformValue(singleValue, out);
842 out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode);
843 }
844 } else {
845 std::vector<std::string> temp;
846 transformExpListLow(valueList, temp);
847 out.push_back(indent() + s("return "sv) + temp.front() + nlr(returnNode));
630 } 848 }
631 }); 849 } else {
850 out.push_back(s("return"sv) + nll(returnNode));
851 }
632 } 852 }
633 853
634 void transform_outer_var_shadow(ast_node* shadow, std::vector<std::string>& out) { 854 void transformFnArgsDef(FnArgsDef_t* argsDef, std::vector<std::string>& out) {
855 if (!argsDef->defList) {
856 out.push_back(Empty);
857 return;
858 }
859 transformFnArgDefList(argsDef->defList, out);
860 if (argsDef->shadowOption) {
861 transform_outer_var_shadow(argsDef->shadowOption, out);
862 }
863 }
864
865 void transform_outer_var_shadow(outer_var_shadow_t* shadow, std::vector<std::string>& out) {
635 markVarShadowed(); 866 markVarShadowed();
636 shadow->eachChild([&](ast_node* node) { 867 if (shadow->varList) {
637 switch (node->getId()) { 868 for (auto name : shadow->varList->names.objects()) {
638 case "NameList"_id: 869 addToAllowList(toString(name));
639 node->eachChild([&](ast_node* child) {
640 if (child->getId() == "Name"_id) {
641 this->addToAllowList(toString(child));
642 }
643 });
644 break;
645 default: break;
646 } 870 }
647 }); 871 }
648 } 872 }
649 873
650 void transformFnArgDefList(ast_node* argDefList, std::vector<std::string>& out) { 874 void transformFnArgDefList(FnArgDefList_t* argDefList, std::vector<std::string>& out) {
651 std::vector<std::vector<std::string>> argItems; 875 struct ArgItem {
652 const int Name = 0; 876 std::string name;
653 const int AssignSelf = 1; 877 std::string assignSelf;
654 const int DefaultVal = 2; 878 std::string defaultVal;
655 argDefList->eachChild([&](ast_node* node) { 879 };
656 switch (node->getId()) { 880 std::list<ArgItem> argItems;
657 case "FnArgDef"_id: { 881 std::vector<std::string> temp;
658 argItems.emplace_back(2); 882 std::string varNames;
659 auto& arg = argItems.back(); 883 bool assignSelf = false;
660 node->eachChild([&](ast_node* child) { 884 for (auto _def : argDefList->definitions.objects()) {
661 switch (child->getId()) { 885 auto def = static_cast<FnArgDef_t*>(_def);
662 case "Name"_id: arg[Name] = toString(child); break; 886 auto& arg = argItems.emplace_back();
663 case "SelfName"_id: 887 switch (def->name->getId()) {
664 child->eachChild([&](ast_node* inner) { 888 case "Name"_id: arg.name = toString(def->name); break;
665 switch (inner->getId()) { 889 case "SelfName"_id: {
666 case "self_class_name"_id: 890 assignSelf = true;
667 arg[Name] = toString(inner->getChild(0)); 891 auto selfName = static_cast<SelfName_t*>(def->name.get());
668 arg[AssignSelf] = s("self.__class."sv) + arg.front(); 892 switch (selfName->name->getId()) {
669 break; 893 case "self_class_name"_id:
670 case "self_class"_id: 894 arg.name = toString(selfName->name->getFirstChild());
671 arg[Name] = "self.__class"sv; 895 arg.assignSelf = s("self.__class."sv) + arg.name;
672 break; 896 break;
673 case "self_name"_id: 897 case "self_class"_id:
674 arg[Name] = toString(inner->getChild(0)); 898 arg.name = "self.__class"sv;
675 arg[AssignSelf] = s("self."sv) + arg.front(); 899 break;
676 break; 900 case "self_name"_id:
677 case "self"_id: 901 arg.name = toString(selfName->name->getFirstChild());
678 arg[Name] = "self"sv; 902 arg.assignSelf = s("self."sv) + arg.name;
679 break; 903 break;
680 } 904 case "self"_id:
681 }); 905 arg.name = "self"sv;
682 break; 906 break;
683 case "Exp"_id: transformExp(child, arg); break; 907 default: break;
684 default: break; 908 }
685 }
686 });
687 break; 909 break;
688 } 910 }
689 case "VarArg"_id:
690 argItems.emplace_back(2);
691 argItems.back()[Name] = "..."sv;
692 break;
693 default: break;
694 } 911 }
695 }); 912 if (def->defaultValue) {
696 std::string varNames; 913 transformExp(static_cast<Exp_t*>(def->defaultValue.get()), temp);
697 for (const auto& item : argItems) { 914 arg.defaultVal = temp.front();
698 if (varNames.empty()) { 915 temp.clear();
699 varNames = item[Name]; 916 _buf << indent() << "if "sv << arg.name << " == nil then"sv << nll(def) <<
700 } else { 917 indent(1) << arg.name << " = "sv << arg.defaultVal << nll(def) <<
701 varNames.append(s(", "sv) + item[Name]); 918 indent() << "end"sv << nll(def);
702 } 919 }
703 forceAddToScope(item[Name]); 920 if (varNames.empty()) varNames = arg.name;
921 else varNames.append(s(", "sv) + arg.name);
922 forceAddToScope(arg.name);
704 } 923 }
705 for (const auto& item : argItems) { 924 if (argDefList->varArg) {
706 if (item.size() == 3 && !item[DefaultVal].empty()) { 925 auto& arg = argItems.emplace_back();
707 _buf << indent() << "if "sv << item[Name] << " == nil then"sv << nll(argDefList) << 926 arg.name = "..."sv;
708 indent() << '\t' << item[Name] << " = "sv << item[DefaultVal] << nll(argDefList) << 927 if (varNames.empty()) varNames = arg.name;
709 indent() << "end"sv << nll(argDefList); 928 else varNames.append(s(", "sv) + arg.name);
710 }
711 } 929 }
712 std::string initCodes = clearBuf(); 930 std::string initCodes = clearBuf();
713 std::vector<std::array<const std::string*, 2>> assignSelfVars; 931 if (assignSelf) {
714 for (const auto& item : argItems) { 932 auto sjoin = [](const decltype(argItems)& items, int index) {
715 if (!item[AssignSelf].empty()) { 933 std::string result;
716 assignSelfVars.push_back({&item[AssignSelf], &item[Name]}); 934 for (auto it = items.begin(); it != items.end(); ++it) {
717 } 935 if (it->assignSelf.empty()) continue;
718 } 936 if (result.empty()) result = (&it->name)[index];
719 auto sjoin = [](const decltype(assignSelfVars)& items, int index) { 937 else result.append(s(", "sv) + (&it->name)[index]);
720 std::string result; 938 }
721 for (auto it = items.begin(); it != items.end(); ++it) { 939 return result;
722 if (result.empty()) result = *((*it)[index]); 940 };
723 else result.append(s(", "sv) + *((*it)[index])); 941 std::string sleft = sjoin(argItems, 1);
724 } 942 std::string sright = sjoin(argItems, 0);
725 return result; 943 initCodes.append(indent() + sleft + s(" = "sv) + sright + nll(argDefList));
726 };
727 std::string sleft = sjoin(assignSelfVars, 0);
728 std::string sright = sjoin(assignSelfVars, 1);
729 if (!assignSelfVars.empty()) {
730 initCodes.append(sleft + s(" = "sv) + sright + nll(argDefList));
731 } 944 }
732 out.push_back(varNames); 945 out.push_back(varNames);
733 out.push_back(initCodes); 946 out.push_back(initCodes);
734 } 947 }
735 948
736 void transformChain(ast_node* chain, std::vector<std::string>& out) { 949 void transformSelfName(SelfName_t* selfName, std::vector<std::string>& out, bool invoke) {
737 chain->eachChild([&](ast_node* node) { 950 auto name = selfName->name.get();
738 switch (node->getId()) { 951 switch (name->getId()) {
739 case "chain_call"_id: transform_chain_call(node, out); break; 952 case "self_class_name"_id:
740 case "chain_item"_id: transform_chain_item(node, out); break; 953 out.push_back(s("self.__class."sv) + toString(name->getFirstChild()));
741 case "chain_dot_chain"_id: transform_chain_dot_chain(node, out); break; 954 break;
742 case "ColonChain"_id: transformColonChain(node, out); break; 955 case "self_class"_id:
743 default: break; 956 out.push_back(s("self.__class"sv));
744 } 957 break;
745 }); 958 case "self_name"_id:
959 out.push_back(s("self"sv) + s(invoke ? ":"sv : "."sv) + toString(name->getFirstChild()));
960 break;
961 case "self"_id:
962 out.push_back(s("self"sv));
963 break;
964 }
965 }
966
967 void transformChain(Chain_t* chain, std::vector<std::string>& out) {
968 auto item = chain->item.get();
969 switch (item->getId()) {
970 case "chain_call"_id: transform_chain_call(static_cast<chain_call_t*>(item), out); break;
971 case "chain_item"_id: transformChainItems(static_cast<chain_item_t*>(item)->chain, out); break;
972 case "chain_dot_chain"_id: transform_chain_dot_chain(item, out); break;
973 case "ColonChain"_id: transformColonChain(static_cast<ColonChain_t*>(item), out); break;
974 default: break;
975 }
746 } 976 }
747 977
748 void transform_chain_call(ast_node* chain_call, std::vector<std::string>& out) { 978 void transform_chain_call(chain_call_t* chain_call, std::vector<std::string>& out) {
749 std::vector<std::string> temp; 979 std::vector<std::string> temp;
750 chain_call->eachChild([&](ast_node* node) { 980 auto caller = chain_call->caller.get();
751 switch (node->getId()) { 981 switch (caller->getId()) {
752 case "Callable"_id: transformCallable(node, temp); break; 982 case "Callable"_id: transformCallable(static_cast<Callable_t*>(caller), temp, true); break;
753 case "String"_id: transformString(node, temp); break; 983 case "String"_id: transformString(static_cast<String_t*>(caller), temp); break;
754 case "ChainItems"_id: transformChainItems(node, temp); break; 984 default: break;
755 default: break; 985 }
756 } 986 transformChainItems(chain_call->chain, temp);
757 });
758 out.push_back(join(temp)); 987 out.push_back(join(temp));
759 } 988 }
760 989
761 void transformChainItems(ast_node* chainItems, std::vector<std::string>& out) { 990 void transformChainItems(ChainItems_t* chainItems, std::vector<std::string>& out) {
762 std::vector<std::string> temp; 991 std::vector<std::string> temp;
763 chainItems->eachChild([&](ast_node* node) { 992 for (auto _chainItem : chainItems->simpleChain.objects()) {
764 switch (node->getId()) { 993 auto chainItem = static_cast<ChainItem_t*>(_chainItem);
765 case "ChainItem"_id: transformChainItem(node, temp); break; 994 transformChainItem(chainItem, temp);
766 case "ColonChain"_id: transformColonChain(node, temp); break; 995 }
767 default: break; 996 if (chainItems->colonChain) {
768 } 997 transformColonChain(chainItems->colonChain, temp);
769 }); 998 }
770 out.push_back(join(temp)); 999 out.push_back(join(temp));
771 } 1000 }
772 1001
773 void transformChainItem(ast_node* chainItem, std::vector<std::string>& out) { 1002 void transformChainItem(ChainItem_t* chainItem, std::vector<std::string>& out) {
774 chainItem->eachChild([&](ast_node* node) { 1003 auto item = chainItem->item.get();
775 switch (node->getId()) { 1004 switch (item->getId()) {
776 case "Invoke"_id: transformInvoke(node, out); break; 1005 case "Invoke"_id: transformInvoke(static_cast<Invoke_t*>(item), out); break;
777 case "DotChainItem"_id: 1006 case "DotChainItem"_id:
778 out.push_back(s("."sv) + toString(node->getChild(0))); 1007 out.push_back(s("."sv) + toString(item->getFirstChild()));
779 break; 1008 break;
780 case "Slice"_id: transformSlice(node, out); break; 1009 case "Slice"_id: transformSlice(item, out); break;
1010 case "Exp"_id:
1011 transformExp(static_cast<Exp_t*>(item), out);
1012 out.back() = s("["sv) + out.back() + s("]"sv);
1013 break;
1014 default: break;
1015 }
1016 }
1017
1018 void transformInvoke(Invoke_t* invoke, std::vector<std::string>& out) {
1019 auto argument = invoke->argument.get();
1020 switch (argument->getId()) {
1021 case "FnArgs"_id: transformFnArgs(static_cast<FnArgs_t*>(argument), out); break;
1022 case "SingleString"_id: transformSingleString(static_cast<SingleString_t*>(argument), out); break;
1023 case "DoubleString"_id: transformDoubleString(static_cast<DoubleString_t*>(argument), out); break;
1024 case "LuaString"_id: transformLuaString(static_cast<LuaString_t*>(argument), out); break;
1025 default: break;
1026 }
1027 }
1028
1029 void transformFnArgs(FnArgs_t* fnArgs, std::vector<std::string>& out) {
1030 std::vector<std::string> temp;
1031 for (auto node : fnArgs->args.objects()) {
1032 transformExp(static_cast<Exp_t*>(node), temp);
1033 }
1034 std::string args = join(temp, ", "sv);
1035 out.push_back(args.empty() ? s("()"sv) : s("("sv) + args + s(")"sv));
1036 }
1037
1038 void transformColonChain(ColonChain_t* colonChain, std::vector<std::string>& out) {
1039 std::vector<std::string> temp;
1040 temp.push_back(s(":"sv) + toString(colonChain->colonChain->name));
1041 if (colonChain->invokeChain) {
1042 transform_invoke_chain(colonChain->invokeChain, temp);
1043 }
1044 out.push_back(join(temp));
1045 }
1046
1047 void transform_invoke_chain(invoke_chain_t* invoke_chain, std::vector<std::string>& out) {
1048 std::vector<std::string> temp;
1049 transformInvoke(invoke_chain->invoke, temp);
1050 if (invoke_chain->chain) {
1051 transformChainItems(invoke_chain->chain, temp);
1052 }
1053 out.push_back(join(temp));
1054 }
1055
1056 void transform_unary_exp(unary_exp_t* unary_exp, std::vector<std::string>& out) {
1057 std::string op = toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it);
1058 std::vector<std::string> temp{op + (op == "not"sv ? op + " " : Empty)};
1059 transformExp(unary_exp->item, temp);
1060 out.push_back(join(temp));
1061 }
1062
1063 void transformName(Name_t* name, std::vector<std::string>& out) {
1064 out.push_back(toString(name));
1065 }
1066
1067 void transformNum(Num_t* num, std::vector<std::string>& out) {
1068 out.push_back(toString(num));
1069 }
1070
1071 void transformTableLit(TableLit_t* tableLit, std::vector<std::string>& out) {
1072 std::vector<std::string> temp;
1073 ast_node* lastNode = nullptr;
1074 for (auto _tableValue : tableLit->values.objects()) {
1075 auto tableValue = static_cast<TableValue_t*>(_tableValue);
1076 auto value = tableValue->value.get();
1077 switch (value->getId()) {
1078 case "KeyValue"_id:
781 case "Exp"_id: 1079 case "Exp"_id:
782 transformExp(node, out); 1080 if (value->getId() == "Exp"_id) {
783 out.back() = s("["sv) + out.back() + s("]"sv); 1081 transformExp(static_cast<Exp_t*>(value), temp);
1082 } else {
1083 transformKeyValue(static_cast<KeyValue_t*>(value), temp);
1084 }
1085 temp.back() = (lastNode ? s(","sv) + nll(lastNode) : Empty) + indent(1) + temp.back();
1086 lastNode = value;
784 break; 1087 break;
785 default: break; 1088 default: break;
786 } 1089 }
787 }); 1090 }
1091 out.push_back(s("{"sv) + nll(tableLit) + join(temp) + nlr(tableLit) + indent() + s("}"sv));
788 } 1092 }
789 1093
790 void transformInvoke(ast_node* invoke, std::vector<std::string>& out) { 1094 void transformComprehension(Comprehension_t* comp, std::vector<std::string>& out) {
791 invoke->eachChild([&](ast_node* node) { 1095 std::vector<std::string> temp;
792 switch (node->getId()) { 1096 std::string accum = getValidName("_accum_");
793 case "FnArgs"_id: transformFnArgs(node, out); break; 1097 std::string len = getValidName("_len_");
794 case "SingleString"_id: transformSingleString(node, out); break; 1098 addToScope(accum);
795 case "DoubleString"_id: transformDoubleString(node, out); break; 1099 addToScope(len);
796 case "LuaString"_id: transformLuaString(node, out); break; 1100 transformExp(comp->value, temp);
1101 auto compInner = comp->forLoop.get();
1102 switch (compInner->compFor->getId()) {
1103 case "CompForEach"_id:
1104 transformCompForEach(
1105 static_cast<CompForEach_t*>(compInner->compFor.get()), temp);
1106 break;
1107 case "CompFor"_id: transformCompFor(compInner->compFor, temp); break;
1108 default: break;
1109 }
1110 std::vector<std::string> clauseCodes;
1111 for (auto clause : compInner->clauses.objects()) {
1112 pushScope();
1113 auto child = clause->getFirstChild();
1114 switch (child->getId()) {
1115 case "CompForEach"_id:
1116 transformCompForEach(static_cast<CompForEach_t*>(child), clauseCodes);
1117 break;
1118 case "CompFor"_id: transformCompFor(child, clauseCodes); break;
1119 case "Exp"_id:
1120 transformExp(static_cast<Exp_t*>(child), clauseCodes);
1121 clauseCodes.back() = indent() + s("if "sv) + clauseCodes.back() + s(" then"sv) + nll(clause);
1122 break;
797 default: break; 1123 default: break;
798 } 1124 }
799 }); 1125 }
1126 for (size_t i = 0; i < compInner->clauses.objects().size(); ++i) {
1127 popScope();
1128 }
1129 _buf << indent() << "local "sv << accum << " = { }"sv << nll(comp);
1130 _buf << indent() << "local "sv << len << " = 1"sv << nll(comp);
1131 _buf << temp.back();
1132 pushScope();
1133 if (clauseCodes.empty()) {
1134 _buf << indent() << accum << "["sv << len << "] = "sv << temp.front() << nll(comp);
1135 _buf << indent() << len << " = "sv << len << " + 1"sv << nll(comp);
1136 } else {
1137 _buf << join(clauseCodes);
1138 _buf << indent(int(clauseCodes.size())) << accum << "["sv << len << "] = "sv << temp.front() << nll(comp);
1139 _buf << indent(int(clauseCodes.size())) << len << " = "sv << len << " + 1"sv << nll(comp);
1140 for (int ind = int(clauseCodes.size()) - 1; ind > -1 ; --ind) {
1141 _buf << indent(ind) << "end"sv << nll(comp);
1142 }
1143 }
1144 popScope();
1145 _buf << indent() << "end"sv << nll(comp);
1146 out.push_back(accum);
1147 out.push_back(clearBuf());
800 } 1148 }
801 1149
802 void transformFnArgs(ast_node* fnArgs, std::vector<std::string>& out) { 1150 void transformCompInPlace(Comprehension_t* comp, const std::string& expStr, std::vector<std::string>& out) {
803 std::vector<std::string> temp; 1151 std::vector<std::string> temp;
804 fnArgs->eachChild([&](ast_node* node) { 1152 pushScope();
805 switch (node->getId()) { 1153 transformComprehension(comp, temp);
806 case "Exp"_id: transformExp(node, temp); break; 1154 out.push_back(
807 default: break; 1155 s("do"sv) + nll(comp) +
1156 temp.back() +
1157 indent() + expStr + s(" = "sv) + temp.front() + nll(comp));
1158 popScope();
1159 out.back() = out.back() + indent() + s("end"sv) + nlr(comp);
1160 }
1161
1162 void transformCompReturn(Comprehension_t* comp, std::vector<std::string>& out) {
1163 std::vector<std::string> temp;
1164 transformComprehension(comp, temp);
1165 out.push_back(temp.back() + indent() + s("return "sv) + temp.front() + nlr(comp));
1166 }
1167
1168 void transformCompClosure(Comprehension_t* comp, std::vector<std::string>& out) {
1169 std::vector<std::string> temp;
1170 std::string before = s("(function()"sv) + nll(comp);
1171 pushScope();
1172 transformComprehension(comp, temp);
1173 out.push_back(
1174 before +
1175 temp.back() +
1176 indent() + s("return "sv) + temp.front() + nlr(comp));
1177 popScope();
1178 out.back() = out.back() + indent() + s("end)()"sv);
1179 }
1180
1181 void transformForEachHead(AssignableNameList_t* nameList, ast_node* loopTarget, std::vector<std::string>& out) {
1182 std::vector<std::string> temp;
1183 transformAssignableNameList(nameList, temp);
1184 switch (loopTarget->getId()) {
1185 case "star_exp"_id: {
1186 auto star_exp = static_cast<star_exp_t*>(loopTarget);
1187 auto listName = getValidName("_list_");
1188 auto indexName = getValidName("_index_");
1189 addToScope(listName);
1190 addToScope(indexName);
1191 transformExp(star_exp->value, temp);
1192 _buf << indent() << "local "sv << listName << " = "sv << temp.back() << nll(nameList);
1193 _buf << indent() << "for "sv << indexName << " = 1, #"sv << listName << " do"sv << nlr(loopTarget);
1194 _buf << indent(1) << "local "sv << temp.front() << " = "sv << listName << "["sv << indexName << "]"sv << nll(nameList);
1195 out.push_back(clearBuf());
1196 break;
808 } 1197 }
809 }); 1198 case "Exp"_id:
810 std::string args = join(temp, ", "sv); 1199 transformExp(static_cast<Exp_t*>(loopTarget), temp);
811 out.push_back(args.empty() ? s("()"sv) : s("("sv) + args + s(")"sv)); 1200 _buf << indent() << "for "sv << temp.front() << " in "sv << temp.back() << " do"sv << nlr(loopTarget);
1201 out.push_back(clearBuf());
1202 break;
1203 case "ExpList"_id:
1204 transformExpList(static_cast<ExpList_t*>(loopTarget), temp);
1205 _buf << indent() << "for "sv << temp.front() << " in "sv << temp.back() << " do"sv << nlr(loopTarget);
1206 out.push_back(clearBuf());
1207 break;
1208 default: break;
1209 }
812 } 1210 }
813 1211
814 void transformColonChain(ast_node* colonChain, std::vector<std::string>& out) { 1212 void transformCompForEach(CompForEach_t* comp, std::vector<std::string>& out) {
1213 transformForEachHead(comp->nameList, comp->loopValue, out);
1214 }
1215
1216 void transformAssignableNameList(AssignableNameList_t* nameList, std::vector<std::string>& out) {
815 std::vector<std::string> temp; 1217 std::vector<std::string> temp;
816 colonChain->eachChild([&](ast_node* node) { 1218 for (auto node : nameList->items.objects()) {
817 switch (node->getId()) { 1219 switch (node->getId()) {
818 case "ColonChainItem"_id: 1220 case "Name"_id:
819 temp.push_back(s(":"sv) + toString(node->getChild(0))); 1221 transformName(static_cast<Name_t*>(node), temp);
1222 break;
1223 case "TableLit"_id:
1224 transformTableLit(static_cast<TableLit_t*>(node), temp);
820 break; 1225 break;
821 case "invoke_chain"_id: transform_invoke_chain(node, temp); break;
822 default: break; 1226 default: break;
823 } 1227 }
824 }); 1228 }
1229 out.push_back(join(temp, ", "sv));
1230 }
1231
1232 void transformInvokeArgs(InvokeArgs_t* invokeArgs, std::vector<std::string>& out) {
1233 std::vector<std::string> temp;
1234 if (invokeArgs->argsList) {
1235 transformExpList(invokeArgs->argsList, temp);
1236 }
1237 if (invokeArgs->argsTableBlock) {
1238 transform_invoke_args_with_table(invokeArgs->argsTableBlock, temp);
1239 }
1240 if (invokeArgs->tableBlock) {
1241 transformTableBlock(invokeArgs->tableBlock, temp);
1242 }
1243 out.push_back(join(temp, ", "sv));
1244 }
1245
1246 void transformForHead(For_t* forNode, std::vector<std::string>& out) {
1247 std::vector<std::string> temp;
1248 std::string varName = toString(forNode->varName);
1249 transformExp(forNode->startValue, temp);
1250 transformExp(forNode->stopValue, temp);
1251 if (forNode->stepValue) {
1252 transformExp(forNode->stepValue->value, temp);
1253 } else {
1254 temp.emplace_back();
1255 }
1256 _buf << indent() << "for "sv << varName << " = "sv << temp[0] << ", "sv << temp[1] << (temp[2].empty() ? Empty : s(", "sv) + temp[2]) << " do"sv << nll(forNode);
1257 out.push_back(clearBuf());
1258 }
1259
1260 void transformFor(For_t* forNode, std::vector<std::string>& out) {
1261 std::vector<std::string> temp;
1262 transformForHead(forNode, temp);
1263 pushScope();
1264 transformBody(forNode->body, temp);
1265 popScope();
1266 out.push_back(temp[0] + temp[1] + indent() + s("end"sv) + nlr(forNode));
1267 }
1268
1269 void transformForClosure(For_t* forNode, std::vector<std::string>& out) {
1270 std::vector<std::string> temp;
1271 std::string accum = getValidName("_accum_");
1272 std::string len = getValidName("_len_");
1273 addToScope(accum);
1274 addToScope(len);
1275 _buf << "(function()"sv << nll(forNode);
1276 pushScope();
1277 _buf << indent() << "local "sv << accum << " = { }"sv << nll(forNode);
1278 _buf << indent() << "local "sv << len << " = 1"sv << nll(forNode);
1279 temp.push_back(clearBuf());
1280 transformForHead(forNode, temp);
1281 auto last = lastStatementFrom(forNode->body);
1282 bool hasTableItem = ast_is<ExpList_t>(last->content);
1283 if (hasTableItem) {
1284 _buf << accum << "["sv << len << "]"sv;
1285 std::string assignLeft = clearBuf();
1286 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1287 auto assignment = new_ptr<Assignment_t>();
1288 assignment->assignable.set(expList);
1289 auto expListLow = new_ptr<ExpListLow_t>();
1290 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1291 auto assign = new_ptr<Assign_t>();
1292 assign->value.set(expListLow);
1293 assignment->target.set(assign);
1294 last->content.set(assignment);
1295 }
1296 pushScope();
1297 transformBody(forNode->body, temp);
1298 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forNode->body));
1299 popScope();
1300 temp.push_back(indent() + s("end"sv) + nlr(forNode) + indent() + s("return "sv) + accum + nlr(forNode));
1301 popScope();
1302 temp.push_back(indent() + s("end)()"sv) + nlr(forNode));
825 out.push_back(join(temp)); 1303 out.push_back(join(temp));
826 } 1304 }
827 1305
828 void transform_invoke_chain(ast_node* invoke_chain, std::vector<std::string>& out) { 1306 void transformForInPlace(For_t* forNode, std::vector<std::string>& out, ExpList_t* assignExpList) {
829 std::vector<std::string> temp; 1307 std::vector<std::string> temp;
830 invoke_chain->eachChild([&](ast_node* node) { 1308 std::string accum = getValidName("_accum_");
831 switch (node->getId()) { 1309 std::string len = getValidName("_len_");
832 case "Invoke"_id: transformInvoke(node, temp); break; 1310 _buf << indent() << "do"sv << nll(forNode);
833 case "ChainItems"_id: transformChainItems(node, temp); break; 1311 pushScope();
1312 addToScope(accum);
1313 addToScope(len);
1314 _buf << indent() << "local "sv << accum << " = { }"sv << nll(forNode);
1315 _buf << indent() << "local "sv << len << " = 1"sv << nll(forNode);
1316 temp.push_back(clearBuf());
1317 transformForHead(forNode, temp);
1318 auto last = lastStatementFrom(forNode->body);
1319 bool hasTableItem = ast_is<ExpList_t>(last->content);
1320 if (hasTableItem) {
1321 _buf << accum << "["sv << len << "]"sv;
1322 std::string assignLeft = clearBuf();
1323 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1324 auto assignment = new_ptr<Assignment_t>();
1325 assignment->assignable.set(expList);
1326 auto expListLow = new_ptr<ExpListLow_t>();
1327 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1328 auto assign = new_ptr<Assign_t>();
1329 assign->value.set(expListLow);
1330 assignment->target.set(assign);
1331 last->content.set(assignment);
1332 }
1333 pushScope();
1334 transformBody(forNode->body, temp);
1335 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forNode->body));
1336 popScope();
1337 temp.push_back(indent() + s("end"sv) + nlr(forNode));
1338 transformExpList(assignExpList, temp);
1339 temp.back() = indent() + temp.back() + s(" = "sv) + accum + nlr(forNode);
1340 popScope();
1341 temp.push_back(indent() + s("end"sv) + nlr(forNode));
1342 out.push_back(join(temp));
1343 }
1344
1345 void transformBinaryOperator(BinaryOperator_t* node, std::vector<std::string>& out) {
1346 out.push_back(toString(node));
1347 }
1348
1349 void transformForEach(ForEach_t* forEach, std::vector<std::string>& out) {
1350 std::vector<std::string> temp;
1351 transformForEachHead(forEach->nameList, forEach->loopValue, temp);
1352 pushScope();
1353 transformBody(forEach->body, temp);
1354 popScope();
1355 out.push_back(temp[0] + temp[1] + indent() + s("end"sv) + nlr(forEach));
1356 }
1357
1358 void transformForEachClosure(ForEach_t* forEach, std::vector<std::string>& out) {
1359 std::vector<std::string> temp;
1360 std::string accum = getValidName("_accum_");
1361 std::string len = getValidName("_len_");
1362 addToScope(accum);
1363 addToScope(len);
1364 _buf << "(function()"sv << nll(forEach);
1365 pushScope();
1366 _buf << indent() << "local "sv << accum << " = { }"sv << nll(forEach);
1367 _buf << indent() << "local "sv << len << " = 1"sv << nll(forEach);
1368 temp.push_back(clearBuf());
1369 transformForEachHead(forEach->nameList, forEach->loopValue, temp);
1370 auto last = lastStatementFrom(forEach->body);
1371 bool hasTableItem = ast_is<ExpList_t>(last->content);
1372 if (hasTableItem) {
1373 _buf << accum << "["sv << len << "]"sv;
1374 std::string assignLeft = clearBuf();
1375 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1376 auto assignment = new_ptr<Assignment_t>();
1377 assignment->assignable.set(expList);
1378 auto expListLow = new_ptr<ExpListLow_t>();
1379 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1380 auto assign = new_ptr<Assign_t>();
1381 assign->value.set(expListLow);
1382 assignment->target.set(assign);
1383 last->content.set(assignment);
1384 }
1385 pushScope();
1386 transformBody(forEach->body, temp);
1387 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forEach->body));
1388 popScope();
1389 temp.push_back(indent() + s("end"sv) + nlr(forEach) + indent() + s("return "sv) + accum + nlr(forEach));
1390 popScope();
1391 temp.push_back(indent() + s("end)()"sv) + nlr(forEach));
1392 out.push_back(join(temp));
1393 }
1394
1395 void transformForEachInPlace(ForEach_t* forEach, std::vector<std::string>& out, ExpList_t* assignExpList) {
1396 std::vector<std::string> temp;
1397 std::string accum = getValidName("_accum_");
1398 std::string len = getValidName("_len_");
1399 _buf << indent() << "do"sv << nll(forEach);
1400 pushScope();
1401 addToScope(accum);
1402 addToScope(len);
1403 _buf << indent() << "local "sv << accum << " = { }"sv << nll(forEach);
1404 _buf << indent() << "local "sv << len << " = 1"sv << nll(forEach);
1405 temp.push_back(clearBuf());
1406 transformForEachHead(forEach->nameList, forEach->loopValue, temp);
1407 auto last = lastStatementFrom(forEach->body);
1408 bool hasTableItem = ast_is<ExpList_t>(last->content);
1409 if (hasTableItem) {
1410 _buf << accum << "["sv << len << "]"sv;
1411 std::string assignLeft = clearBuf();
1412 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1413 auto assignment = new_ptr<Assignment_t>();
1414 assignment->assignable.set(expList);
1415 auto expListLow = new_ptr<ExpListLow_t>();
1416 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1417 auto assign = new_ptr<Assign_t>();
1418 assign->value.set(expListLow);
1419 assignment->target.set(assign);
1420 last->content.set(assignment);
1421 }
1422 pushScope();
1423 transformBody(forEach->body, temp);
1424 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forEach->body));
1425 popScope();
1426 temp.push_back(indent() + s("end"sv) + nlr(forEach));
1427 transformExpList(assignExpList, temp);
1428 temp.back() = indent() + temp.back() + s(" = "sv) + accum + nlr(forEach);
1429 popScope();
1430 temp.push_back(indent() + s("end"sv) + nlr(forEach));
1431 out.push_back(join(temp));
1432 }
1433
1434 void transformKeyValue(KeyValue_t* keyValue, std::vector<std::string>& out) {
1435 auto item = keyValue->item.get();
1436 switch (item->getId()) {
1437 case "variable_pair"_id:
1438 out.push_back(toString(static_cast<variable_pair_t*>(item)->name));
1439 break;
1440 case "normal_pair"_id: {
1441 auto pair = static_cast<normal_pair_t*>(item);
1442 auto key = pair->key.get();
1443 std::vector<std::string> temp;
1444 switch (key->getId()) {
1445 case "KeyName"_id: transformKeyName(static_cast<KeyName_t*>(key), temp); break;
1446 case "Exp"_id:
1447 transformExp(static_cast<Exp_t*>(key), temp);
1448 temp.back() = s("["sv) + temp.back() + s("]"sv);
1449 break;
1450 case "DoubleString"_id: transformDoubleString(static_cast<DoubleString_t*>(key), temp); break;
1451 case "SingleString"_id: transformSingleString(static_cast<SingleString_t*>(key), temp); break;
1452 default: break;
1453 }
1454 auto value = pair->value.get();
1455 switch (value->getId()) {
1456 case "Exp"_id: transformExp(static_cast<Exp_t*>(value), temp); break;
1457 case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), temp); break;
1458 default: break;
1459 }
1460 out.push_back(temp[0] + s(" = "sv) + temp[1]);
1461 break;
1462 }
1463 default: break;
1464 }
1465 }
1466
1467 void transformKeyName(KeyName_t* keyName, std::vector<std::string>& out) {
1468 auto name = keyName->name.get();
1469 switch (name->getId()) {
1470 case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(name), out, false); break;
1471 case "_Name"_id: out.push_back(toString(name)); break;
1472 default: break;
1473 }
1474 }
1475
1476 void transformLuaString(LuaString_t* luaString, std::vector<std::string>& out) {
1477 out.push_back(toString(luaString));
1478 }
1479
1480 void transformSingleString(SingleString_t* singleString, std::vector<std::string>& out) {
1481 out.push_back(toString(singleString));
1482 }
1483
1484 void transformDoubleString(DoubleString_t* doubleString, std::vector<std::string>& out) {
1485 std::vector<std::string> temp;
1486 for (auto _seg : doubleString->segments.objects()) {
1487 auto seg = static_cast<double_string_content_t*>(_seg);
1488 auto content = seg->content.get();
1489 switch (content->getId()) {
1490 case "double_string_inner"_id:
1491 temp.push_back(s("\""sv) + toString(content) + s("\""sv));
1492 break;
1493 case "Exp"_id:
1494 transformExp(static_cast<Exp_t*>(content), temp);
1495 temp.back() = s("tostring("sv) + temp.back() + s(")"sv);
1496 break;
834 default: break; 1497 default: break;
835 } 1498 }
836 }); 1499 }
837 out.push_back(join(temp)); 1500 out.push_back(join(temp, " .. "sv));
838 } 1501 }
839 1502
840 void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1503 void transformString(String_t* string, std::vector<std::string>& out) {
1504 auto str = string->str.get();
1505 switch (str->getId()) {
1506 case "SingleString"_id: transformSingleString(static_cast<SingleString_t*>(str), out); break;
1507 case "DoubleString"_id: transformDoubleString(static_cast<DoubleString_t*>(str), out); break;
1508 case "LuaString"_id: transformLuaString(static_cast<LuaString_t*>(str), out); break;
1509 default: break;
1510 }
1511 }
841 1512
1513 void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
842 void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1514 void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
843 void transformWhile(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1515 void transformWhile(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
844 void transformWith(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1516 void transformWith(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
845 void transformFor(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
846 void transformIf(ast_node* node, std::vector<std::string>& out) { noopnl(node, out); }
847 void transformForEach(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
848 void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1517 void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
849 void transformReturn(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
850 void transformTableBlock(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1518 void transformTableBlock(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
851 void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1519 void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
852 void transformExport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1520 void transformExport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
853 void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1521 void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
854 void transform_unless_line(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1522 void transform_unless_line(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
855 void transformCompInner(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
856 void transform_simple_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1523 void transform_simple_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
857 void transformString(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
858 void transformInvokeArgs(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
859 void transformName(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
860 void transformSelfName(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
861 void transform_const_value(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1524 void transform_const_value(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
862 void transformClassDecl(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1525 void transformClassDecl(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
863 void transformDo(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1526 void transformDo(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
864 void transform_unary_exp(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
865 void transformTblComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1527 void transformTblComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
866 void transformTableLit(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
867 void transformComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
868 void transformNum(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
869 void transformVarArg(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
870 void transformBinaryOperator(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
871 void transform_chain_item(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
872 void transform_chain_dot_chain(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1528 void transform_chain_dot_chain(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
873 void transformSlice(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1529 void transformSlice(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
874 void transformSingleString(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1530 void transformCompFor(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
875 void transformDoubleString(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1531 void transformCompClause(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
876 void transformLuaString(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1532 void transform_invoke_args_with_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
877}; 1533};
878 1534
879const std::string MoonCompliler::Empty; 1535const std::string MoonCompliler::Empty;
880 1536
881int main() 1537int main()
882{ 1538{
883 std::string s = R"TestCodesHere(a = 998 1539 std::string s = R"TestCodesHere(
884f, d = (-> 1540-- vararg bubbling
885 joop = 2302 + 567 1541f = (...) -> #{...}
1542
1543dont_bubble = ->
1544 [x for x in ((...)-> print ...)("hello")]
1545
1546k = [x for x in ((...)-> print ...)("hello")]
1547
1548j = for i=1,10
1549 (...) -> print ...
1550
1551-- bubble me
886 1552
887 (hi, a, b = Vec2(100,200), c, d, ... using nil) -> 1553m = (...) ->
888 d = "中文" 1554 [x for x in *{...} when f(...) > 4]
889 hi = 1021
890 1555
891 a,b,c,d = 1,2,3,4 1556x = for i in *{...} do i
1557y = [x for x in *{...}]
1558z = [x for x in hallo when f(...) > 4]
892 1559
893 hello[232], (5+5)[121], hello, x[99] = 100, 200, 300
894 1560
895 joop = 12), 123 if true else print("a",1,2)\abc(998).x 1561a = for i=1,10 do ...
896 1562
897a, b = if hello 1563b = for i=1,10
898 "hello" 1564 -> print ...
899else
900 "nothing", "yeah"
901 1565
902 1566
903a, b = if hello 1567)TestCodesHere";
904 if yeah then "one", "two" else "mmhh"
905else
906 print "the other"
907 "nothing", "yeah")TestCodesHere";
908 1568
909 MoonCompliler{}.complile(s); 1569 MoonCompliler{}.complile(s);
910 1570
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp
index 7731513..ae8c53d 100644
--- a/MoonParser/moon_parser.cpp
+++ b/MoonParser/moon_parser.cpp
@@ -1,5 +1,13 @@
1#include "moon_parser.h" 1#include "moon_parser.h"
2 2
3std::unordered_set<std::string> State::keywords = {
4 "and", "while", "else", "using", "continue",
5 "local", "not", "then", "return", "from",
6 "extends", "for", "do", "or", "export",
7 "class", "in", "unless", "when", "elseif",
8 "switch", "break", "if", "with", "import", "true", "false", "nil"
9};
10
3rule plain_space = *set(" \t"); 11rule plain_space = *set(" \t");
4rule Break = nl(-expr('\r') >> '\n'); 12rule Break = nl(-expr('\r') >> '\n');
5rule Any = Break | any(); 13rule Any = Break | any();
@@ -185,7 +193,9 @@ rule For = key("for") >> DisableDo >>
185 193
186extern rule AssignableNameList; 194extern rule AssignableNameList;
187 195
188rule for_in = sym('*') >> Exp | ExpList; 196extern rule star_exp;
197
198rule for_in = star_exp | ExpList;
189 199
190rule ForEach = key("for") >> AssignableNameList >> key("in") >> 200rule ForEach = key("for") >> AssignableNameList >> key("in") >>
191 DisableDo >> ensure(for_in, PopDo) >> 201 DisableDo >> ensure(for_in, PopDo) >>
diff --git a/MoonParser/moon_parser.h b/MoonParser/moon_parser.h
index bf618aa..6f9ef8f 100644
--- a/MoonParser/moon_parser.h
+++ b/MoonParser/moon_parser.h
@@ -21,11 +21,5 @@ struct State
21 size_t stringOpen; 21 size_t stringOpen;
22 std::stack<int> indents; 22 std::stack<int> indents;
23 std::stack<bool> doStack; 23 std::stack<bool> doStack;
24 std::unordered_set<std::string> keywords = { 24 static std::unordered_set<std::string> keywords;
25 "and", "while", "else", "using", "continue",
26 "local", "not", "then", "return", "from",
27 "extends", "for", "do", "or", "export",
28 "class", "in", "unless", "when", "elseif",
29 "switch", "break", "if", "with", "import", "true", "false", "nil"
30 };
31}; 25};
diff --git a/MoonParser/parser.cpp b/MoonParser/parser.cpp
index 2378abe..03857c6 100644
--- a/MoonParser/parser.cpp
+++ b/MoonParser/parser.cpp
@@ -1143,10 +1143,8 @@ expr expr::operator !() const {
1143 @param e end position. 1143 @param e end position.
1144 */ 1144 */
1145input_range::input_range(const pos &b, const pos &e) : 1145input_range::input_range(const pos &b, const pos &e) :
1146 m_begin(b), 1146m_begin(b),
1147 m_end(e) 1147m_end(e) {}
1148{
1149}
1150 1148
1151 1149
1152/** constructor. 1150/** constructor.
@@ -1155,10 +1153,8 @@ input_range::input_range(const pos &b, const pos &e) :
1155 @param t error type. 1153 @param t error type.
1156 */ 1154 */
1157error::error(const pos &b, const pos &e, int t) : 1155error::error(const pos &b, const pos &e, int t) :
1158 input_range(b, e), 1156input_range(b, e),
1159 m_type(t) 1157m_type(t) {}
1160{
1161}
1162 1158
1163 1159
1164/** compare on begin position. 1160/** compare on begin position.
diff --git a/MoonParser/parser.hpp b/MoonParser/parser.hpp
index cbabf06..ae83215 100644
--- a/MoonParser/parser.hpp
+++ b/MoonParser/parser.hpp
@@ -31,17 +31,9 @@ inline std::size_t constexpr operator"" _id(const char* s, size_t)
31} 31}
32 32
33///type of the parser's input. 33///type of the parser's input.
34typedef std::basic_string<char32_t> input; 34typedef std::basic_string<wchar_t> input;
35typedef input::iterator input_it; 35typedef input::iterator input_it;
36 36typedef std::wstring_convert<std::codecvt_utf8<input::value_type>> Converter;
37template<class Facet>
38struct deletable_facet : Facet
39{
40 template<class ...Args>
41 deletable_facet(Args&& ...args): Facet(std::forward<Args>(args)...) {}
42 ~deletable_facet() {}
43};
44typedef std::wstring_convert<deletable_facet<std::codecvt<input::value_type, char, std::mbstate_t>>, input::value_type> Converter;
45 37
46namespace parserlib { 38namespace parserlib {
47 39
@@ -152,6 +144,8 @@ typedef void (*parse_proc)(const pos &b, const pos &e, void *d);
152///input range. 144///input range.
153class input_range { 145class input_range {
154public: 146public:
147 virtual ~input_range() {}
148
155 ///begin position. 149 ///begin position.
156 pos m_begin; 150 pos m_begin;
157 151
@@ -160,7 +154,6 @@ public:
160 154
161 ///empty constructor. 155 ///empty constructor.
162 input_range() {} 156 input_range() {}
163 virtual ~input_range() {}
164 157
165 /** constructor. 158 /** constructor.
166 @param b begin position. 159 @param b begin position.