aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2019-09-19 01:01:11 +0800
committerLi Jin <dragon-fly@qq.com>2019-09-19 01:01:11 +0800
commit42485c6f26b16900b228aeb73907fdbdd9ed17e0 (patch)
tree4ff846bf7159cd544c5a0ec177d5355a0b916871
parentad0b9c911095b402159f51abe4d98a56d2335973 (diff)
downloadyuescript-42485c6f26b16900b228aeb73907fdbdd9ed17e0.tar.gz
yuescript-42485c6f26b16900b228aeb73907fdbdd9ed17e0.tar.bz2
yuescript-42485c6f26b16900b228aeb73907fdbdd9ed17e0.zip
spec/class.moon is done.
-rw-r--r--MoonParser/ast.cpp48
-rw-r--r--MoonParser/ast.hpp44
-rw-r--r--MoonParser/moon_ast.cpp1401
-rw-r--r--MoonParser/moon_ast.h3
-rw-r--r--MoonParser/moon_parser.cpp2
5 files changed, 1141 insertions, 357 deletions
diff --git a/MoonParser/ast.cpp b/MoonParser/ast.cpp
index 852593b..7f46bd0 100644
--- a/MoonParser/ast.cpp
+++ b/MoonParser/ast.cpp
@@ -14,8 +14,28 @@ traversal ast_node::traverse(const std::function<traversal (ast_node*)>& func) {
14 return func(this); 14 return func(this);
15} 15}
16 16
17ast_node* ast_node::getByPath(std::initializer_list<size_t>) { 17ast_node* ast_node::getByTypeIds(int* begin, int* end) {
18 return nullptr; 18 ast_node* current = this;
19 auto it = begin;
20 while (it != end) {
21 ast_node* findNode = nullptr;
22 int type = *it;
23 current->visitChild([&](ast_node* node) {
24 if (node->get_type() == type) {
25 findNode = node;
26 return true;
27 }
28 return false;
29 });
30 if (findNode) {
31 current = findNode;
32 } else {
33 current = nullptr;
34 break;
35 }
36 ++it;
37 }
38 return current;
19} 39}
20 40
21bool ast_node::visitChild(const std::function<bool (ast_node*)>&) { 41bool ast_node::visitChild(const std::function<bool (ast_node*)>&) {
@@ -68,30 +88,6 @@ traversal ast_container::traverse(const std::function<traversal (ast_node*)>& fu
68 return traversal::Continue; 88 return traversal::Continue;
69} 89}
70 90
71ast_node* ast_container::getByPath(std::initializer_list<size_t> paths) {
72 ast_node* current = this;
73 auto it = paths.begin();
74 while (it != paths.end()) {
75 ast_node* findNode = nullptr;
76 size_t id = *it;
77 current->visitChild([&](ast_node* node) {
78 if (node->getId() == id) {
79 findNode = node;
80 return true;
81 }
82 return false;
83 });
84 if (findNode) {
85 current = findNode;
86 } else {
87 current = nullptr;
88 break;
89 }
90 ++it;
91 }
92 return current;
93}
94
95bool ast_container::visitChild(const std::function<bool (ast_node*)>& func) { 91bool ast_container::visitChild(const std::function<bool (ast_node*)>& func) {
96 const auto& members = this->members(); 92 const auto& members = this->members();
97 for (auto member : members) { 93 for (auto member : members) {
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp
index 1077f5d..63dccba 100644
--- a/MoonParser/ast.hpp
+++ b/MoonParser/ast.hpp
@@ -63,7 +63,18 @@ public:
63 */ 63 */
64 virtual traversal traverse(const std::function<traversal (ast_node*)>& func); 64 virtual traversal traverse(const std::function<traversal (ast_node*)>& func);
65 65
66 virtual ast_node* getByPath(std::initializer_list<size_t> paths); 66 template <typename... Ts>
67 struct select_last {
68 using type = typename decltype((std::enable_if<true,Ts>{}, ...))::type;
69 };
70 template <typename... Ts>
71 using select_last_t = typename select_last<Ts...>::type;
72
73 template <class ...Args>
74 select_last_t<Args...>* getByPath() {
75 int types[] = {ast_type<Args>()...};
76 return static_cast<select_last_t<Args...>*>(getByTypeIds(std::begin(types), std::end(types)));
77 }
67 78
68 virtual bool visitChild(const std::function<bool (ast_node*)>& func); 79 virtual bool visitChild(const std::function<bool (ast_node*)>& func);
69 80
@@ -82,6 +93,7 @@ public:
82 virtual int get_type() { return ast_type<ast_node>(); } 93 virtual int get_type() { return ast_type<ast_node>(); }
83private: 94private:
84 int _ref; 95 int _ref;
96 ast_node* getByTypeIds(int* begin, int* end);
85 template <class T, bool OPT, bool MEM> friend class ast_ptr; 97 template <class T, bool OPT, bool MEM> friend class ast_ptr;
86 template <class ...Args> friend class ast_choice; 98 template <class ...Args> friend class ast_choice;
87 template <class T> friend class ast_list; 99 template <class T> friend class ast_list;
@@ -89,10 +101,16 @@ private:
89}; 101};
90 102
91template<class T> 103template<class T>
92T* ast_cast(ast_node *node) { 104T* ast_cast(ast_node* node) {
93 return node && ast_type<T>() == node->get_type() ? static_cast<T*>(node) : nullptr; 105 return node && ast_type<T>() == node->get_type() ? static_cast<T*>(node) : nullptr;
94} 106}
95 107
108template<class T>
109T* ast_to(ast_node* node) {
110 assert(node->get_type() == ast_type<T>());
111 return static_cast<T*>(node);
112}
113
96template <class ...Args> 114template <class ...Args>
97bool ast_is(ast_node* node) { 115bool ast_is(ast_node* node) {
98 if (!node) return false; 116 if (!node) return false;
@@ -132,8 +150,6 @@ public:
132 */ 150 */
133 virtual void construct(ast_stack& st) override; 151 virtual void construct(ast_stack& st) override;
134 152
135 virtual ast_node* getByPath(std::initializer_list<size_t> paths) override;
136
137 virtual traversal traverse(const std::function<traversal (ast_node*)>& func) override; 153 virtual traversal traverse(const std::function<traversal (ast_node*)>& func) override;
138 154
139 virtual bool visitChild(const std::function<bool (ast_node*)>& func) override; 155 virtual bool visitChild(const std::function<bool (ast_node*)>& func) override;
@@ -210,7 +226,7 @@ public:
210 226
211 template <class T> 227 template <class T>
212 T* to() const { 228 T* to() const {
213 assert(m_ptr->getId() != ast_type<T>()); 229 assert(m_ptr->get_type() == ast_type<T>());
214 return static_cast<T*>(m_ptr); 230 return static_cast<T*>(m_ptr);
215 } 231 }
216 232
@@ -380,6 +396,22 @@ public:
380 } 396 }
381 } 397 }
382 398
399 void set_front(ast_node* node) {
400 if (accept(node)) {
401 m_objects.front()->release();
402 m_objects.front() = node;
403 node->retain();
404 }
405 }
406
407 void set_back(ast_node* node) {
408 if (accept(node)) {
409 m_objects.back()->release();
410 m_objects.back() = node;
411 node->retain();
412 }
413 }
414
383 const container& objects() const { 415 const container& objects() const {
384 return m_objects; 416 return m_objects;
385 } 417 }
@@ -410,7 +442,6 @@ protected:
410 */ 442 */
411template <class T> class ast_list : public _ast_list { 443template <class T> class ast_list : public _ast_list {
412public: 444public:
413 ///the default constructor.
414 ast_list() {} 445 ast_list() {}
415 446
416 ast_list(const ast_list<T>& other) { 447 ast_list(const ast_list<T>& other) {
@@ -450,7 +481,6 @@ private:
450 481
451template <class ...Args> class ast_sel_list : public _ast_list { 482template <class ...Args> class ast_sel_list : public _ast_list {
452public: 483public:
453 ///the default constructor.
454 ast_sel_list() {} 484 ast_sel_list() {}
455 485
456 ast_sel_list(const ast_sel_list<Args...>& other) { 486 ast_sel_list(const ast_sel_list<Args...>& other) {
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp
index f7dcae6..103eb8e 100644
--- a/MoonParser/moon_ast.cpp
+++ b/MoonParser/moon_ast.cpp
@@ -5,7 +5,6 @@
5#include <vector> 5#include <vector>
6#include <numeric> 6#include <numeric>
7#include <memory> 7#include <memory>
8#include <array>
9#include <sstream> 8#include <sstream>
10#include <string_view> 9#include <string_view>
11using namespace std::string_view_literals; 10using namespace std::string_view_literals;
@@ -155,18 +154,29 @@ public:
155 } 154 }
156 } 155 }
157 _codeCache.clear(); 156 _codeCache.clear();
157 std::stack<std::string> empty;
158 _withVars.swap(empty);
158 } 159 }
159private: 160private:
161 int _indentOffset = 0;
160 Converter _converter; 162 Converter _converter;
161 std::vector<input> _codeCache; 163 std::vector<input> _codeCache;
164 std::stack<std::string> _withVars;
162 std::ostringstream _buf; 165 std::ostringstream _buf;
163 std::string _newLine = "\n"; 166 std::string _newLine = "\n";
164 std::vector<int> _lineTable; 167 std::vector<int> _lineTable;
168 enum class ExportMode {
169 None = 0,
170 Capital = 1,
171 Any = 2
172 };
165 struct Scope { 173 struct Scope {
174 ExportMode mode = ExportMode::None;
166 std::unique_ptr<std::unordered_set<std::string>> vars; 175 std::unique_ptr<std::unordered_set<std::string>> vars;
167 std::unique_ptr<std::unordered_set<std::string>> allows; 176 std::unique_ptr<std::unordered_set<std::string>> allows;
177 std::unique_ptr<std::unordered_set<std::string>> exports;
168 }; 178 };
169 std::vector<Scope> _scopes; 179 std::list<Scope> _scopes;
170 static const std::string Empty; 180 static const std::string Empty;
171 181
172 void pushScope() { 182 void pushScope() {
@@ -180,7 +190,19 @@ private:
180 190
181 bool isDefined(const std::string& name, bool checkShadowScopeOnly = false) { 191 bool isDefined(const std::string& name, bool checkShadowScopeOnly = false) {
182 bool isDefined = false; 192 bool isDefined = false;
193 int mode = int(std::isupper(name[0]) ? ExportMode::Capital : ExportMode::Any);
183 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { 194 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
195 if (int(it->mode) >= mode) {
196 if (it->exports) {
197 if (it->exports->find(name) != it->exports->end()) {
198 isDefined = true;
199 break;
200 }
201 } else {
202 isDefined = true;
203 break;
204 }
205 }
184 auto vars = it->vars.get(); 206 auto vars = it->vars.get();
185 if (vars->find(name) != vars->end()) { 207 if (vars->find(name) != vars->end()) {
186 isDefined = true; 208 isDefined = true;
@@ -191,11 +213,36 @@ private:
191 return isDefined; 213 return isDefined;
192 } 214 }
193 215
216 bool isSolidDefined(const std::string& name) {
217 bool isDefined = false;
218 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
219 auto vars = it->vars.get();
220 if (vars->find(name) != vars->end()) {
221 isDefined = true;
222 break;
223 }
224 }
225 return isDefined;
226 }
227
194 void markVarShadowed() { 228 void markVarShadowed() {
195 auto& scope = _scopes.back(); 229 auto& scope = _scopes.back();
196 scope.allows = MakeUnique<std::unordered_set<std::string>>(); 230 scope.allows = MakeUnique<std::unordered_set<std::string>>();
197 } 231 }
198 232
233 void markVarExported(ExportMode mode, bool specified) {
234 auto& scope = _scopes.back();
235 scope.mode = mode;
236 if (specified && !scope.exports) {
237 scope.exports = MakeUnique<std::unordered_set<std::string>>();
238 }
239 }
240
241 void addExportedVar(const std::string& name) {
242 auto& scope = _scopes.back();
243 scope.exports->insert(name);
244 }
245
199 void addToAllowList(const std::string& name) { 246 void addToAllowList(const std::string& name) {
200 auto& scope = _scopes.back(); 247 auto& scope = _scopes.back();
201 scope.allows->insert(name); 248 scope.allows->insert(name);
@@ -206,6 +253,10 @@ private:
206 scope.vars->insert(name); 253 scope.vars->insert(name);
207 } 254 }
208 255
256 Scope& currentScope() {
257 return _scopes.back();
258 }
259
209 bool addToScope(const std::string& name) { 260 bool addToScope(const std::string& name) {
210 bool defined = false; 261 bool defined = false;
211 auto& scope = _scopes.back(); 262 auto& scope = _scopes.back();
@@ -227,29 +278,34 @@ private:
227 int index = 0; 278 int index = 0;
228 std::string newName; 279 std::string newName;
229 do { 280 do {
230 _buf << name << index; 281 newName = s(name) + std::to_string(index);
231 newName = clearBuf();
232 index++; 282 index++;
233 } while (isDefined(newName)); 283 } while (isSolidDefined(newName));
234 return newName; 284 return newName;
235 } 285 }
236 286
237 const std::string nll(ast_node* node) { 287 const std::string nll(ast_node* node) {
288 // return s(" -- "sv) + std::to_string(node->m_begin.m_line) + _newLine;
238 _lineTable.push_back(node->m_begin.m_line); 289 _lineTable.push_back(node->m_begin.m_line);
239 return _newLine; 290 return _newLine;
240 } 291 }
241 292
242 const std::string nlr(ast_node* node) { 293 const std::string nlr(ast_node* node) {
294 // return s(" -- "sv) + std::to_string(node->m_end.m_line) + _newLine;
243 _lineTable.push_back(node->m_end.m_line); 295 _lineTable.push_back(node->m_end.m_line);
244 return _newLine; 296 return _newLine;
245 } 297 }
246 298
299 void setIndentOffset(int offset) {
300 _indentOffset = offset;
301 }
302
247 std::string indent() { 303 std::string indent() {
248 return std::string((_scopes.size() - 1) * 2, ' '); 304 return std::string((_scopes.size() - 1 + _indentOffset) * 2, ' ');
249 } 305 }
250 306
251 std::string indent(int offset) { 307 std::string indent(int offset) {
252 return std::string((_scopes.size() - 1 + offset) * 2, ' '); 308 return std::string((_scopes.size() - 1 + _indentOffset + offset) * 2, ' ');
253 } 309 }
254 310
255 std::string clearBuf() { 311 std::string clearBuf() {
@@ -282,18 +338,6 @@ private:
282 return _converter.to_bytes(std::wstring(begin, end)); 338 return _converter.to_bytes(std::wstring(begin, end));
283 } 339 }
284 340
285 void noop(ast_node* node, std::vector<std::string>& out) {
286 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
287 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str));
288 // out.push_back(trim(str));
289 }
290
291 void noopnl(ast_node* node, std::vector<std::string>& out) {
292 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
293 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str) + nll(node));
294 // out.push_back(trim(str) + nll(node));
295 }
296
297 Value_t* singleValueFrom(ast_node* expList) { 341 Value_t* singleValueFrom(ast_node* expList) {
298 ast_node* singleValue = nullptr; 342 ast_node* singleValue = nullptr;
299 expList->traverse([&](ast_node* n) { 343 expList->traverse([&](ast_node* n) {
@@ -311,6 +355,30 @@ private:
311 return static_cast<Value_t*>(singleValue); 355 return static_cast<Value_t*>(singleValue);
312 } 356 }
313 357
358 Value_t* firstValueFrom(ast_node* expList) {
359 Value_t* firstValue = nullptr;
360 expList->traverse([&](ast_node* n) {
361 if (n->getId() == "Value"_id) {
362 firstValue = static_cast<Value_t*>(n);
363 return traversal::Stop;
364 }
365 return traversal::Continue;
366 });
367 return firstValue;
368 }
369
370 void noop(ast_node* node, std::vector<std::string>& out) {
371 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
372 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str));
373 // out.push_back(trim(str));
374 }
375
376 void noopnl(ast_node* node, std::vector<std::string>& out) {
377 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
378 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str) + nll(node));
379 // out.push_back(trim(str) + nll(node));
380 }
381
314 Statement_t* lastStatementFrom(ast_node* body) { 382 Statement_t* lastStatementFrom(ast_node* body) {
315 ast_node* last = nullptr; 383 ast_node* last = nullptr;
316 body->traverse([&](ast_node* n) { 384 body->traverse([&](ast_node* n) {
@@ -332,49 +400,21 @@ private:
332 return parse<T>(_codeCache.back(), r, el, &st); 400 return parse<T>(_codeCache.back(), r, el, &st);
333 } 401 }
334 402
335 Invoke_t* startWithInvoke(ast_node* chain) { 403 bool isChainValueCall(ChainValue_t* chainValue) {
336 ast_node* invoke = nullptr; 404 if (chainValue->arguments) return true;
337 chain->traverse([&](ast_node* node) { 405 if (auto chain = chainValue->caller.as<Chain_t>()) {
338 switch (node->getId()) { 406 ast_node* last = chain->items.objects().back();
339 case "Invoke"_id: 407 return last->getId() == "Invoke"_id;
340 invoke = node; 408 }
341 return traversal::Stop; 409 return false;
342 case "DotChainItem"_id:
343 case "ColonChainItem"_id:
344 case "Slice"_id:
345 case "Exp"_id:
346 case "Callable"_id:
347 case "String"_id:
348 return traversal::Stop;
349 default:
350 return traversal::Continue;
351 }
352 });
353 return static_cast<Invoke_t*>(invoke);
354 } 410 }
355 411
356 Invoke_t* endWithInvoke(Chain_t* chain) { 412 bool isColonChain(ChainValue_t* chainValue) {
357 ast_node* last = nullptr; 413 if (chainValue->arguments) return false;
358 chain->traverse([&](ast_node* node) { 414 if (auto chain = chainValue->caller.as<Chain_t>()) {
359 switch (node->getId()) { 415 return chain->items.objects().back()->getId() == "ColonChainItem"_id;
360 case "Invoke"_id:
361 case "DotChainItem"_id:
362 case "ColonChainItem"_id:
363 case "Slice"_id:
364 case "Exp"_id:
365 case "Callable"_id:
366 case "String"_id:
367 last = node;
368 return traversal::Return;
369 default:
370 return traversal::Continue;
371 }
372 });
373 if (last && last->getId() == "Invoke"_id) {
374 return static_cast<Invoke_t*>(last);
375 } else {
376 return nullptr;
377 } 416 }
417 return false;
378 } 418 }
379 419
380 std::vector<ast_node*> getChainList(ChainValue_t* chainValue) { 420 std::vector<ast_node*> getChainList(ChainValue_t* chainValue) {
@@ -401,26 +441,26 @@ private:
401 switch (appendix->item->getId()) { 441 switch (appendix->item->getId()) {
402 case "if_else_line"_id: { 442 case "if_else_line"_id: {
403 auto if_else_line = static_cast<if_else_line_t*>(appendix->item.get()); 443 auto if_else_line = static_cast<if_else_line_t*>(appendix->item.get());
444 auto ifNode = new_ptr<If_t>();
445
404 auto ifCond = new_ptr<IfCond_t>(); 446 auto ifCond = new_ptr<IfCond_t>();
405 ifCond->condition = if_else_line->condition; 447 ifCond->condition.set(if_else_line->condition);
448 ifNode->firstCondition.set(ifCond);
406 449
407 auto exprList = new_ptr<ExpList_t>(); 450 if (!ast_is<default_value_t>(if_else_line->elseExpr)) {
408 exprList->exprs.push_back(if_else_line->elseExpr); 451 auto exprList = new_ptr<ExpList_t>();
452 exprList->exprs.push_back(if_else_line->elseExpr);
453 auto stmt = new_ptr<Statement_t>();
454 stmt->content.set(exprList);
455 auto body = new_ptr<Body_t>();
456 body->content.set(stmt);
457 ifNode->lastBranch.set(body);
458 }
409 auto stmt = new_ptr<Statement_t>(); 459 auto stmt = new_ptr<Statement_t>();
410 stmt->content.set(exprList);
411 auto body = new_ptr<Body_t>();
412 body->content.set(stmt);
413 auto ifElseIf = new_ptr<IfElseIf_t>();
414 ifElseIf->body.set(body);
415
416 stmt = new_ptr<Statement_t>();
417 stmt->content.set(statement->content); 460 stmt->content.set(statement->content);
418 body = new_ptr<Body_t>(); 461 auto body = new_ptr<Body_t>();
419 body->content.set(stmt); 462 body->content.set(stmt);
420 auto ifNode = new_ptr<If_t>();
421 ifNode->firstCondition.set(ifCond);
422 ifNode->firstBody.set(body); 463 ifNode->firstBody.set(body);
423 ifNode->branches.push_back(ifElseIf);
424 464
425 statement->appendix.set(nullptr); 465 statement->appendix.set(nullptr);
426 auto simpleValue = new_ptr<SimpleValue_t>(); 466 auto simpleValue = new_ptr<SimpleValue_t>();
@@ -429,7 +469,7 @@ private:
429 value->item.set(simpleValue); 469 value->item.set(simpleValue);
430 auto exp = new_ptr<Exp_t>(); 470 auto exp = new_ptr<Exp_t>();
431 exp->value.set(value); 471 exp->value.set(value);
432 exprList = new_ptr<ExpList_t>(); 472 auto exprList = new_ptr<ExpList_t>();
433 exprList->exprs.push_back(exp); 473 exprList->exprs.push_back(exp);
434 statement->content.set(exprList); 474 statement->content.set(exprList);
435 break; 475 break;
@@ -451,15 +491,15 @@ private:
451 switch (content->getId()) { 491 switch (content->getId()) {
452 case "Import"_id: transformImport(content, out); break; 492 case "Import"_id: transformImport(content, out); break;
453 case "While"_id: transformWhile(content, out); break; 493 case "While"_id: transformWhile(content, out); break;
454 case "With"_id: transformWith(content, out); break; 494 case "With"_id: transformWith(static_cast<With_t*>(content), out); break;
455 case "For"_id: transformFor(static_cast<For_t*>(content), out); break; 495 case "For"_id: transformFor(static_cast<For_t*>(content), out); break;
456 case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(content), out); break; 496 case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(content), out); break;
457 case "Switch"_id: transformSwitch(content, out); break; 497 case "Switch"_id: transformSwitch(content, out); break;
458 case "Return"_id: transformReturn(static_cast<Return_t*>(content), out); break; 498 case "Return"_id: transformReturn(static_cast<Return_t*>(content), out); break;
459 case "Local"_id: transformLocal(content, out); break; 499 case "Local"_id: transformLocal(content, out); break;
460 case "Export"_id: transformExport(content, out); break; 500 case "Export"_id: transformExport(static_cast<Export_t*>(content), out); break;
461 case "BreakLoop"_id: transformBreakLoop(content, out); break; 501 case "BreakLoop"_id: transformBreakLoop(content, out); break;
462 case "Assignment"_id: transformStatementAssign(statement, out); break; 502 case "Assignment"_id: transformAssignment(static_cast<Assignment_t*>(content), out); break;
463 case "ExpList"_id: { 503 case "ExpList"_id: {
464 auto expList = static_cast<ExpList_t*>(content); 504 auto expList = static_cast<ExpList_t*>(content);
465 if (expList->exprs.objects().empty()) { 505 if (expList->exprs.objects().empty()) {
@@ -467,8 +507,8 @@ private:
467 break; 507 break;
468 } 508 }
469 if (auto singleValue = singleValueFrom(expList)) { 509 if (auto singleValue = singleValueFrom(expList)) {
470 if (auto simpleValue = static_cast<SimpleValue_t*>(singleValue->getByPath({"SimpleValue"_id}))) { 510 if (auto simpleValue = singleValue->item.as<SimpleValue_t>()) {
471 auto value = simpleValue->getFirstChild(); 511 auto value = simpleValue->value.get();
472 bool specialSingleValue = true; 512 bool specialSingleValue = true;
473 switch (value->getId()) { 513 switch (value->getId()) {
474 case "If"_id: transformIf(static_cast<If_t*>(value), out); break; 514 case "If"_id: transformIf(static_cast<If_t*>(value), out); break;
@@ -486,18 +526,19 @@ private:
486 break; 526 break;
487 } 527 }
488 } 528 }
489 if (auto chainValue = static_cast<ChainValue_t*>(singleValue->getByPath({"ChainValue"_id}))) { 529 if (auto chainValue = singleValue->item.as<ChainValue_t>()) {
490 if (chainValue->arguments) { 530 if (isChainValueCall(chainValue)) {
491 transformValue(singleValue, out); 531 transformValue(singleValue, out);
492 out.back() = indent() + out.back() + nlr(singleValue); 532 out.back() = indent() + out.back() + nlr(singleValue);
493 break; 533 break;
494 } else { 534 } else if (isColonChain(chainValue)){
495 auto chain = static_cast<Chain_t*>(chainValue->getByPath({"Chain"_id})); 535 std::string preDefine;
496 if (chain && endWithInvoke(chain)) { 536 if (addToScope(s("_"sv))) {
497 transformValue(singleValue, out); 537 preDefine = indent() + s("local _"sv) + nll(chainValue);
498 out.back() = indent() + out.back() + nlr(singleValue);
499 break;
500 } 538 }
539 transformColonChain(chainValue, out);
540 out.back().insert(0, preDefine);
541 break;
501 } 542 }
502 } 543 }
503 } 544 }
@@ -515,183 +556,387 @@ private:
515 } 556 }
516 } 557 }
517 558
518 std::string transformAssignDefs(ExpList_t* expList) { 559 std::vector<std::string> getAssignVars(ExpList_t* expList) {
519 std::vector<std::string> preDefs; 560 std::vector<std::string> vars;
520 std::vector<ast_node*> values;
521 expList->traverse([&](ast_node* child) { 561 expList->traverse([&](ast_node* child) {
522 if (child->getId() == "Value"_id) { 562 if (child->getId() == "Value"_id) {
523 auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Variable"_id}); 563 if (auto target = child->getByPath<ChainValue_t, Callable_t, Variable_t>()) {
524 if (target) {
525 auto name = toString(target); 564 auto name = toString(target);
526 if (addToScope(name)) { 565 vars.push_back(name);
527 preDefs.push_back(name); 566 } else {
567 vars.push_back(Empty);
568 }
569 return traversal::Return;
570 }
571 return traversal::Continue;
572 });
573 return vars;
574 }
575
576 std::vector<std::string> transformAssignDefs(ExpList_t* expList) {
577 std::vector<std::string> preDefs;
578 expList->traverse([&](ast_node* child) {
579 if (child->getId() == "Value"_id) {
580 if (auto callable = child->getByPath<ChainValue_t, Callable_t>()) {
581 if (ast_is<Variable_t>(callable->item)) {
582 auto name = toString(callable->item);
583 if (addToScope(name)) {
584 preDefs.push_back(name);
585 }
586 } else if (callable->getByPath<SelfName_t, self_t>()) {
587 auto self = s("self"sv);
588 if (addToScope(self)) {
589 preDefs.push_back(self);
590 }
528 } 591 }
529 } 592 }
530 return traversal::Return; 593 return traversal::Return;
531 } 594 }
532 return traversal::Continue; 595 return traversal::Continue;
533 }); 596 });
534 if (!preDefs.empty()) { 597 return preDefs;
535 return indent() + s("local "sv) + join(preDefs, ", "sv);
536 }
537 return std::string();
538 } 598 }
539 599
540 void transformStatementAssign(Statement_t* statement, std::vector<std::string>& out) { 600 std::string getPredefine(const std::vector<std::string>& defs) {
541 auto assignment = static_cast<Assignment_t*>(statement->content.get()); 601 if (defs.empty()) return Empty;
542 if (auto ifNode = assignment->getByPath({"Assign"_id, "If"_id})) { 602 return indent() + s("local "sv) + join(defs, ", "sv);
543 auto expList = assignment->assignable.get(); 603 }
544 std::vector<std::string> temp; 604
545 std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs; 605 struct DestructItem {
546 ifCondPairs.emplace_back(); 606 std::string name;
547 std::string preDefine = transformAssignDefs(expList); 607 std::string structure;
548 if (!preDefine.empty()) temp.push_back(preDefine + nll(expList)); 608 };
549 ifNode->traverse([&](ast_node* node) { 609
550 switch (node->getId()) { 610 struct Destructure {
551 case "IfCond"_id: 611 std::string value;
552 ifCondPairs.back().first = static_cast<IfCond_t*>(node); 612 std::list<DestructItem> items;
553 return traversal::Return; 613 };
554 case "Body"_id: 614
555 ifCondPairs.back().second = static_cast<Body_t*>(node); 615 void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) {
556 ifCondPairs.emplace_back(); 616 auto assign = ast_cast<Assign_t>(assignment->target);
557 return traversal::Return; 617 if (assign && assign->values.objects().size() == 1) {
558 default: return traversal::Continue; 618 if (auto ifNode = assign->getByPath<If_t>()) {
619 auto expList = assignment->assignable.get();
620 std::vector<std::string> temp;
621 std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs;
622 ifCondPairs.emplace_back();
623 auto defs = transformAssignDefs(expList);
624 if (!defs.empty()) temp.push_back(getPredefine(defs) + nll(expList));
625 ifNode->traverse([&](ast_node* node) {
626 switch (node->getId()) {
627 case "IfCond"_id:
628 ifCondPairs.back().first = static_cast<IfCond_t*>(node);
629 return traversal::Return;
630 case "Body"_id:
631 ifCondPairs.back().second = static_cast<Body_t*>(node);
632 ifCondPairs.emplace_back();
633 return traversal::Return;
634 default: return traversal::Continue;
635 }
636 });
637 for (const auto& pair : ifCondPairs) {
638 if (pair.first) {
639 std::vector<std::string> tmp;
640 auto condition = pair.first->condition.get();
641 transformExp(condition, tmp);
642 _buf << indent() << (pair == ifCondPairs.front() ? ""sv : "else"sv) <<
643 "if "sv << tmp.front() << " then"sv << nll(condition);
644 temp.push_back(clearBuf());
645 }
646 if (pair.second) {
647 if (!pair.first) {
648 temp.push_back(indent() + s("else"sv) + nll(pair.second));
649 }
650 auto last = lastStatementFrom(pair.second);
651 auto valueList = last ? last->content.as<ExpList_t>() : nullptr;
652 if (last && valueList) {
653 auto newAssignment = new_ptr<Assignment_t>();
654 newAssignment->assignable.set(expList);
655 auto assign = new_ptr<Assign_t>();
656 assign->values.dup(valueList->exprs);
657 newAssignment->target.set(assign);
658 last->content.set(newAssignment);
659 }
660 pushScope();
661 transformBody(pair.second, temp);
662 popScope();
663 if (!pair.first) {
664 temp.push_back(indent() + s("end"sv) + nll(pair.second));
665 }
666 }
559 } 667 }
560 }); 668 out.push_back(join(temp));
561 for (const auto& pair : ifCondPairs) { 669 return;
562 if (pair.first) { 670 }
563 std::vector<std::string> tmp; 671 auto exp = ast_cast<Exp_t>(assign->values.objects().front());
564 auto condition = pair.first->condition.get(); 672 if (exp && exp->opValues.objects().empty()) {
565 transformExp(condition, tmp); 673 if (auto simpleVal = exp->value->item.as<SimpleValue_t>()) {
566 _buf << indent() << (pair == ifCondPairs.front() ? ""sv : "else"sv) << 674 auto valueItem = simpleVal->value.get();
567 "if "sv << tmp.front() << " then"sv << nll(condition); 675 switch (valueItem->getId()) {
568 temp.push_back(clearBuf()); 676 case "Comprehension"_id: {
677 std::vector<std::string> temp;
678 auto expList = assignment->assignable.get();
679 transformExpList(expList, temp);
680 transformCompInPlace(static_cast<Comprehension_t*>(valueItem), temp.front(), temp);
681 std::string preDefine = getPredefine(transformAssignDefs(expList));
682 out.push_back(preDefine + nll(assignment) + temp.back());
683 return;
684 }
685 case "For"_id: {
686 std::vector<std::string> temp;
687 auto expList = assignment->assignable.get();
688 std::string preDefine = getPredefine(transformAssignDefs(expList));
689 transformForInPlace(static_cast<For_t*>(valueItem), temp, expList);
690 auto nl = preDefine.empty() ? Empty : nll(assignment);
691 out.push_back(preDefine + nl + temp.front());
692 return;
693 }
694 case "ForEach"_id: {
695 std::vector<std::string> temp;
696 auto expList = assignment->assignable.get();
697 std::string preDefine = getPredefine(transformAssignDefs(expList));
698 transformForEachInPlace(static_cast<ForEach_t*>(valueItem), temp, expList);
699 auto nl = preDefine.empty() ? Empty : nll(assignment);
700 out.push_back(preDefine + nl + temp.front());
701 return;
702 }
703 case "ClassDecl"_id: {
704 std::vector<std::string> temp;
705 auto expList = assignment->assignable.get();
706 std::string preDefine = getPredefine(transformAssignDefs(expList));
707 transformClassDecl(static_cast<ClassDecl_t*>(valueItem), temp, ExpUsage::Assignment, expList);
708 auto nl = preDefine.empty() ? Empty : nll(assignment);
709 out.push_back(preDefine + nl + temp.front());
710 return;
711 }
712 }
569 } 713 }
570 if (pair.second) { 714 if (auto chainValue = exp->value->item.as<ChainValue_t>()) {
571 if (!pair.first) { 715 if (isColonChain(chainValue)) {
572 temp.push_back(indent() + s("else"sv) + nll(pair.second)); 716 auto assignable = assignment->assignable.get();
717 std::string preDefine = getPredefine(transformAssignDefs(assignable));
718 transformColonChain(chainValue, out, ExpUsage::Assignment, static_cast<ExpList_t*>(assignable));
719 if (!preDefine.empty()) out.back() = preDefine + nll(chainValue) + out.back();
720 return;
573 } 721 }
574 auto last = lastStatementFrom(pair.second); 722 }
575 auto valueList = last ? last->content.as<ExpList_t>() : nullptr; 723 }
576 if (last && valueList) { 724 }
577 auto newAssignment = new_ptr<Assignment_t>(); 725 auto info = extractDestructureInfo(assignment);
578 newAssignment->assignable.set(expList); 726 if (info.first.empty()) {
579 auto assign = new_ptr<Assign_t>(); 727 transformAssignmentCommon(assignment, out);
580 if (valueList->getChildCount() == 2) { 728 } else {
581 if (auto subIfNode = valueList->getByPath({ 729 std::vector<std::string> temp;
582 "Exp"_id, "Value"_id, "SimpleValue"_id, "If"_id})) { 730 for (const auto& destruct : info.first) {
583 assign->value.set(subIfNode); 731 if (destruct.items.size() == 1) {
584 } 732 auto& pair = destruct.items.front();
585 } 733 _buf << indent();
586 if (!assign->value) { 734 if (addToScope(pair.name)) {
587 auto expListLow = new_ptr<ExpListLow_t>(); 735 _buf << s("local "sv);
588 expListLow->exprs = valueList->exprs; 736 }
589 assign->value.set(expListLow); 737 _buf << pair.name << " = "sv << info.first.front().value << pair.structure << nll(assignment);
738 temp.push_back(clearBuf());
739 } else {
740 std::vector<std::string> defs, names, values;
741 for (const auto& item : destruct.items) {
742 if (addToScope(item.name)) {
743 defs.push_back(item.name);
590 } 744 }
591 newAssignment->target.set(assign); 745 names.push_back(item.name);
592 last->content.set(newAssignment); 746 values.push_back(item.structure);
593 } 747 }
748 if (!defs.empty()) _buf << indent() << "local "sv << join(defs) << nll(assignment);
749 _buf << indent() << "do"sv << nll(assignment);
594 pushScope(); 750 pushScope();
595 transformBody(pair.second, temp); 751 auto objVar = getUnusedName("_obj_");
752 for (auto& v : values) v.insert(0, objVar);
753 _buf << indent() << "local "sv << objVar << " = "sv << destruct.value << nll(assignment);
754 _buf << indent() << join(names, ", "sv) << " = "sv << join(values, ", "sv) << nll(assignment);
596 popScope(); 755 popScope();
597 if (!pair.first) { 756 _buf << indent() << "end"sv << nll(assignment);
598 temp.push_back(indent() + s("end"sv) + nll(pair.second)); 757 temp.push_back(clearBuf());
599 }
600 } 758 }
601 } 759 }
760 if (info.second) {
761 transformAssignmentCommon(info.second, temp);
762 }
602 out.push_back(join(temp)); 763 out.push_back(join(temp));
603 return;
604 } 764 }
605 if (auto expList = assignment->getByPath({"Assign"_id, "ExpListLow"_id})) { 765 }
606 auto singleValue = singleValueFrom(expList); 766
607 if (singleValue && singleValue->item->getId() == "SimpleValue"_id) { 767 void transformAssignItem(ast_node* value, std::vector<std::string>& out) {
608 auto valueItem = singleValue->item->getFirstChild(); 768 switch (value->getId()) {
609 switch (valueItem->getId()) { 769 case "With"_id: transformWith(ast_to<With_t>(value), out); break;
610 case "Comprehension"_id: { 770 case "If"_id: transformIfClosure(ast_to<If_t>(value), out); break;
611 std::vector<std::string> temp; 771 case "Switch"_id: transformSwitch(value, out); break;
612 auto expList = assignment->assignable.get(); 772 case "TableBlock"_id: transformTableBlock(value, out); break;
613 transformExpList(expList, temp); 773 case "Exp"_id: transformExp(ast_to<Exp_t>(value), out); break;
614 transformCompInPlace(static_cast<Comprehension_t*>(valueItem), temp.front(), temp); 774 default: break;
615 std::string preDefine = transformAssignDefs(expList); 775 }
616 out.push_back(preDefine + nll(statement) + temp.back()); 776 }
617 return; 777
778 std::list<std::pair<std::string, std::string>> destructFromExp(ast_node* node) {
779 const std::list<ast_node*>* tableItems = nullptr;
780 if (ast_cast<Exp_t>(node)) {
781 auto item = singleValueFrom(node)->item.get();
782 if (!item) throw std::logic_error("Invalid destructure value");
783 auto tbA = item->getByPath<TableLit_t>();
784 if (tbA) {
785 tableItems = &tbA->values.objects();
786 } else {
787 auto tbB = ast_cast<simple_table_t>(item);
788 if (tbB) tableItems = &tbB->pairs.objects();
789 }
790 } else if (auto table = ast_cast<TableBlock_t>(node)) {
791 tableItems = &table->values.objects();
792 }
793 std::list<std::pair<std::string, std::string>> pairs;
794 int index = 0;
795 for (auto pair : *tableItems) {
796 switch (pair->getId()) {
797 case "Exp"_id: {
798 ++index;
799 auto item = singleValueFrom(node)->item.get();
800 if (!item) throw std::logic_error("Invalid destructure value");
801 if (auto value = item->getByPath<Callable_t, Variable_t>()) {
802 auto name = toString(value);
803 //"Can't destructure value of type: parens"
804 pairs.push_back({name, s("["sv) + std::to_string(index) + s("]"sv)});
805 break;
618 } 806 }
619 case "For"_id: { 807 if (ast_cast<simple_table_t>(item) ||
620 std::vector<std::string> temp; 808 item->getByPath<TableLit_t>()) {
621 auto expList = assignment->assignable.get(); 809 auto subPairs = destructFromExp(pair);
622 std::string preDefine = transformAssignDefs(expList); 810 for (auto& p : subPairs) {
623 transformForInPlace(static_cast<For_t*>(valueItem), temp, expList); 811 pairs.push_back({p.first, s("["sv) + std::to_string(index) + s("]"sv) + p.second});
624 out.push_back(preDefine + nll(statement) + temp.front()); 812 }
625 return; 813 break;
626 } 814 }
627 case "ForEach"_id: { 815 break;
628 std::vector<std::string> temp; 816 }
629 auto expList = assignment->assignable.get(); 817 case "variable_pair"_id: {
630 std::string preDefine = transformAssignDefs(expList); 818 auto vp = static_cast<variable_pair_t*>(pair);
631 transformForEachInPlace(static_cast<ForEach_t*>(valueItem), temp, expList); 819 auto name = toString(vp->name);
632 out.push_back(preDefine + nll(statement) + temp.front()); 820 pairs.push_back({name, s("."sv) + name});
633 return; 821 break;
822 }
823 case "normal_pair"_id: {
824 auto np = static_cast<normal_pair_t*>(pair);
825 auto key = np->key->getByPath<Name_t>();
826 if (!key) throw std::logic_error("Invalid key for destructure");
827 if (auto exp = np->value.as<Exp_t>()) {
828 auto item = singleValueFrom(exp)->item.get();
829 if (!item) throw std::logic_error("Invalid destructure value");
830 if (auto var = item->getByPath<Callable_t, Variable_t>()) {
831 pairs.push_back({toString(var), s("."sv) + toString(key)});
832 break;
833 }
834 if (ast_cast<simple_table_t>(item) ||
835 item->getByPath<TableLit_t>()) {
836 auto subPairs = destructFromExp(exp);
837 for (auto& p : subPairs) {
838 pairs.push_back({p.first, s("."sv) + toString(key) + p.second});
839 }
840 break;
841 }
634 } 842 }
635 case "ClassDecl"_id: { 843 if (np->value.as<TableBlock_t>()) {
636 std::vector<std::string> temp; 844 auto subPairs = destructFromExp(pair);
637 auto expList = assignment->assignable.get(); 845 for (auto& p : subPairs) {
638 std::string preDefine = transformAssignDefs(expList); 846 pairs.push_back({p.first, s("."sv) + toString(key) + p.second});
639 transformClassDecl(static_cast<ClassDecl_t*>(valueItem), temp, ClassDeclUsage::Assignment, expList); 847 }
640 out.push_back(preDefine + nll(statement) + temp.front());
641 return;
642 } 848 }
849 break;
643 } 850 }
644 } 851 }
645 } 852 }
646 transformAssignment(assignment, out); 853 return pairs;
647 } 854 }
648 855
649 void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) { 856 std::pair<std::list<Destructure>, ast_ptr<Assignment_t, false, false>>
857 extractDestructureInfo(Assignment_t* assignment) {
858 std::list<Destructure> destructs;
859 auto exprs = assignment->assignable->exprs.objects();
860 auto values = assignment->target.to<Assign_t>()->values.objects();
861 size_t size = std::max(exprs.size(),values.size());
862 auto nullNode = toAst<Exp_t>("nil"sv, Exp);
863 while (exprs.size() < size) exprs.emplace_back();
864 while (values.size() < size) values.emplace_back(nullNode);
865 using iter = std::list<ast_node*>::iterator;
866 std::vector<std::pair<iter, iter>> destructPairs;
867 std::vector<std::string> temp;
868 for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) {
869 auto expr = *i;
870 ast_node* destructNode = expr->getByPath<Value_t, SimpleValue_t, TableLit_t>();
871 if (destructNode || (destructNode = expr->getByPath<Value_t, simple_table_t>())) {
872 destructPairs.push_back({i,j});
873 transformAssignItem(*j, temp);
874 auto& destruct = destructs.emplace_back();
875 destruct.value = temp.back();
876 temp.pop_back();
877 auto pairs = destructFromExp(expr);
878 for (auto& pair : pairs) {
879 auto& item = destruct.items.emplace_back();
880 item.name = std::move(pair.first);
881 item.structure = std::move(pair.second);
882 }
883 }
884 }
885 for (const auto& p : destructPairs) {
886 exprs.erase(p.first);
887 values.erase(p.second);
888 }
889 ast_ptr<Assignment_t, false, false> newAssignment;
890 if (!destructPairs.empty() && !exprs.empty()) {
891 auto expList = new_ptr<ExpList_t>();
892 auto newAssign = new_ptr<Assignment_t>();
893 newAssign->assignable.set(expList);
894 for (auto expr : exprs) expList->exprs.push_back(expr);
895 auto assign = new_ptr<Assign_t>();
896 for (auto value : values) assign->values.push_back(value);
897 newAssign->target.set(assign);
898 newAssignment = newAssign;
899 }
900 return {std::move(destructs), newAssignment};
901 }
902
903 void transformAssignmentCommon(Assignment_t* assignment, std::vector<std::string>& out) {
650 std::vector<std::string> temp; 904 std::vector<std::string> temp;
651 auto expList = assignment->assignable.get(); 905 auto expList = assignment->assignable.get();
652 auto action = assignment->target.get(); 906 auto action = assignment->target.get();
653 std::string preDefine = transformAssignDefs(expList); 907 auto defs = transformAssignDefs(expList);
654 transformExpList(expList, temp); 908 std::string preDefine = getPredefine(defs);
655 bool oneLined = expList->getChildCount() == 2 && 909 bool oneLined = defs.size() == expList->exprs.objects().size() &&
656 traversal::Stop != action->traverse([&](ast_node* node) { 910 traversal::Stop != action->traverse([&](ast_node* n) {
657 if (node->getId() == "FunLit"_id) { 911 if (n->getId() == "Callable"_id) {
658 if (auto body = node->getByPath({"Body"_id})) { 912 if (auto name = n->getByPath<Variable_t>()) {
659 if (traversal::Stop == body->traverse([&](ast_node* n) { 913 for (const auto& def : defs) {
660 if (n->getId() == "Callable"_id) { 914 if (def ==toString(name)) {
661 if (auto name = n->getByPath({"Variable"_id})) { 915 return traversal::Stop;
662 if (temp.front() ==toString(name)) {
663 return traversal::Stop;
664 }
665 }
666 } 916 }
667 return traversal::Continue;
668 })) {
669 return traversal::Stop;
670 } 917 }
671 } 918 }
672 } 919 }
673 return traversal::Continue; 920 return traversal::Continue;
674 }); 921 });
922 transformExpList(expList, temp);
923 std::string left = temp.back();
924 temp.clear();
675 switch (action->getId()) { 925 switch (action->getId()) {
676 case "Update"_id: transformUpdate(action, temp); break; 926 case "Update"_id: transformUpdate(action, temp); break;
677 case "Assign"_id: { 927 case "Assign"_id: {
678 auto child = action->getFirstChild(); 928 auto assign = static_cast<Assign_t*>(action);
679 switch (child->getId()) { 929 for (auto value : assign->values.objects()) {
680 case "With"_id: transformWith(child, temp); break; 930 transformAssignItem(value, temp);
681 case "If"_id: transformIfClosure(static_cast<If_t*>(child), temp); break;
682 case "Switch"_id: transformSwitch(child, temp); break;
683 case "TableBlock"_id: transformTableBlock(child, temp); break;
684 case "ExpListLow"_id: transformExpListLow(static_cast<ExpListLow_t*>(child), temp); break;
685 default: break;
686 } 931 }
687 break; 932 break;
688 } 933 }
689 default: break; 934 default: break;
690 } 935 }
691 if (oneLined) { 936 if (oneLined) {
692 out.push_back((preDefine.empty() ? indent() + temp[0] : preDefine) + s(" = "sv) + temp[1] + nll(assignment)); 937 out.push_back((preDefine.empty() ? indent() + left : preDefine) + s(" = "sv) + join(temp, ", "sv) + nll(assignment));
693 } else { 938 } else {
694 out.push_back((preDefine.empty() ? Empty : preDefine + nll(assignment)) + indent() + temp[0] + s(" = "sv) + temp[1] + nll(assignment)); 939 out.push_back((preDefine.empty() ? Empty : preDefine + nll(assignment)) + indent() + left + s(" = "sv) + join(temp, ", "sv) + nll(assignment));
695 } 940 }
696 } 941 }
697 942
@@ -731,9 +976,10 @@ private:
731 pushScope(); 976 pushScope();
732 transformBody(pair.second, temp, withClosure); 977 transformBody(pair.second, temp, withClosure);
733 popScope(); 978 popScope();
734 if (!pair.first) { 979 }
735 temp.push_back(indent() + s("end"sv) + nll(pair.second)); 980 if (!pair.first) {
736 } 981 temp.push_back(indent() + s("end"sv) + nll(ifNode));
982 break;
737 } 983 }
738 } 984 }
739 if (withClosure) { 985 if (withClosure) {
@@ -778,8 +1024,16 @@ private:
778 auto item = value->item.get(); 1024 auto item = value->item.get();
779 switch (item->getId()) { 1025 switch (item->getId()) {
780 case "SimpleValue"_id: transformSimpleValue(static_cast<SimpleValue_t*>(item), out); break; 1026 case "SimpleValue"_id: transformSimpleValue(static_cast<SimpleValue_t*>(item), out); break;
781 case "simple_table"_id: transform_simple_table(item, out); break; 1027 case "simple_table"_id: transform_simple_table(static_cast<simple_table_t*>(item), out); break;
782 case "ChainValue"_id: transformChainValue(static_cast<ChainValue_t*>(item), out); break; 1028 case "ChainValue"_id: {
1029 auto chainValue = static_cast<ChainValue_t*>(item);
1030 if (isColonChain(chainValue)) {
1031 transformColonChainClosure(chainValue, out);
1032 } else {
1033 transformChainValue(chainValue, out);
1034 }
1035 break;
1036 }
783 case "String"_id: transformString(static_cast<String_t*>(item), out); break; 1037 case "String"_id: transformString(static_cast<String_t*>(item), out); break;
784 default: break; 1038 default: break;
785 } 1039 }
@@ -788,12 +1042,13 @@ private:
788 void transformChainValue(ChainValue_t* chainValue, std::vector<std::string>& out) { 1042 void transformChainValue(ChainValue_t* chainValue, std::vector<std::string>& out) {
789 std::vector<std::string> temp; 1043 std::vector<std::string> temp;
790 auto caller = chainValue->caller.get(); 1044 auto caller = chainValue->caller.get();
1045 bool hasArgs = chainValue->arguments;
791 switch (caller->getId()) { 1046 switch (caller->getId()) {
792 case "Chain"_id: transformChain(static_cast<Chain_t*>(caller), temp); break; 1047 case "Chain"_id: transformChain(static_cast<Chain_t*>(caller), temp); break;
793 case "Callable"_id: transformCallable(static_cast<Callable_t*>(caller), temp, chainValue->arguments); break; 1048 case "Callable"_id: transformCallable(static_cast<Callable_t*>(caller), temp, hasArgs); break;
794 default: break; 1049 default: break;
795 } 1050 }
796 if (chainValue->arguments) { 1051 if (hasArgs) {
797 transformInvokeArgs(chainValue->arguments, temp); 1052 transformInvokeArgs(chainValue->arguments, temp);
798 out.push_back(temp[0] + s("("sv) + temp[1] + s(")"sv)); 1053 out.push_back(temp[0] + s("("sv) + temp[1] + s(")"sv));
799 } else { 1054 } else {
@@ -821,10 +1076,10 @@ private:
821 void transformSimpleValue(SimpleValue_t* simpleValue, std::vector<std::string>& out) { 1076 void transformSimpleValue(SimpleValue_t* simpleValue, std::vector<std::string>& out) {
822 auto value = simpleValue->value.get(); 1077 auto value = simpleValue->value.get();
823 switch (value->getId()) { 1078 switch (value->getId()) {
824 case "const_value"_id: transform_const_value(value, out); break; 1079 case "const_value"_id: transform_const_value(static_cast<const_value_t*>(value), out); break;
825 case "If"_id: transformIfClosure(static_cast<If_t*>(value), out); break; 1080 case "If"_id: transformIfClosure(static_cast<If_t*>(value), out); break;
826 case "Switch"_id: transformSwitch(value, out); break; 1081 case "Switch"_id: transformSwitch(value, out); break;
827 case "With"_id: transformWith(value, out); break; 1082 case "With"_id: transformWith(static_cast<With_t*>(value), out); break;
828 case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; 1083 case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break;
829 case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break; 1084 case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break;
830 case "For"_id: transformForClosure(static_cast<For_t*>(value), out); break; 1085 case "For"_id: transformForClosure(static_cast<For_t*>(value), out); break;
@@ -856,8 +1111,15 @@ private:
856 auto& bodyCodes = temp[2]; 1111 auto& bodyCodes = temp[2];
857 _buf << "function("sv << 1112 _buf << "function("sv <<
858 (isFatArrow ? s("self, "sv) : Empty) << 1113 (isFatArrow ? s("self, "sv) : Empty) <<
859 args << ')' << nlr(argsDef) << 1114 args << ')';
860 initArgs << bodyCodes; 1115 if (!initArgs.empty() || !bodyCodes.empty()) {
1116 _buf << nlr(argsDef) << initArgs << bodyCodes;
1117 popScope();
1118 _buf << indent() << "end"sv;
1119 } else {
1120 _buf << " end"sv;
1121 popScope();
1122 }
861 } else { 1123 } else {
862 if (funLit->body) { 1124 if (funLit->body) {
863 transformBody(funLit->body, temp, true); 1125 transformBody(funLit->body, temp, true);
@@ -867,10 +1129,16 @@ private:
867 auto& bodyCodes = temp.back(); 1129 auto& bodyCodes = temp.back();
868 _buf << "function("sv << 1130 _buf << "function("sv <<
869 (isFatArrow ? s("self"sv) : Empty) << 1131 (isFatArrow ? s("self"sv) : Empty) <<
870 ')' << nll(funLit) << bodyCodes; 1132 ')';
1133 if (!bodyCodes.empty()) {
1134 _buf << nll(funLit) << bodyCodes;
1135 popScope();
1136 _buf << indent() << "end"sv;
1137 } else {
1138 _buf << " end"sv;
1139 popScope();
1140 }
871 } 1141 }
872 popScope();
873 _buf << indent() << "end"sv;
874 out.push_back(clearBuf()); 1142 out.push_back(clearBuf());
875 } 1143 }
876 1144
@@ -910,18 +1178,27 @@ private:
910 void transformReturn(Return_t* returnNode, std::vector<std::string>& out) { 1178 void transformReturn(Return_t* returnNode, std::vector<std::string>& out) {
911 if (auto valueList = returnNode->valueList.get()) { 1179 if (auto valueList = returnNode->valueList.get()) {
912 if (auto singleValue = singleValueFrom(valueList)) { 1180 if (auto singleValue = singleValueFrom(valueList)) {
913 if (auto comp = singleValue->getByPath({"SimpleValue"_id, "Comprehension"_id})) { 1181 if (auto comp = singleValue->getByPath<SimpleValue_t, Comprehension_t>()) {
914 transformCompReturn(static_cast<Comprehension_t*>(comp), out); 1182 transformCompReturn(comp, out);
915 } else if (auto classDecl = singleValue->getByPath({"SimpleValue"_id, "ClassDecl"_id})) { 1183 return;
916 transformClassDecl(static_cast<ClassDecl_t*>(classDecl), out, ClassDeclUsage::Return); 1184 }
917 } else { 1185 if (auto classDecl = singleValue->getByPath<SimpleValue_t, ClassDecl_t>()) {
918 transformValue(singleValue, out); 1186 transformClassDecl(classDecl, out, ExpUsage::Return);
919 out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); 1187 return;
1188 }
1189 if (auto chainValue = singleValue->getByPath<ChainValue_t>()) {
1190 if (isColonChain(chainValue)) {
1191 transformColonChain(chainValue, out, ExpUsage::Return);
1192 return;
1193 }
920 } 1194 }
1195 transformValue(singleValue, out);
1196 out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode);
1197 return;
921 } else { 1198 } else {
922 std::vector<std::string> temp; 1199 std::vector<std::string> temp;
923 transformExpListLow(valueList, temp); 1200 transformExpListLow(valueList, temp);
924 out.push_back(indent() + s("return "sv) + temp.front() + nlr(returnNode)); 1201 out.push_back(indent() + s("return "sv) + temp.back() + nlr(returnNode));
925 } 1202 }
926 } else { 1203 } else {
927 out.push_back(s("return"sv) + nll(returnNode)); 1204 out.push_back(s("return"sv) + nll(returnNode));
@@ -1027,7 +1304,7 @@ private:
1027 auto name = selfName->name.get(); 1304 auto name = selfName->name.get();
1028 switch (name->getId()) { 1305 switch (name->getId()) {
1029 case "self_class_name"_id: 1306 case "self_class_name"_id:
1030 out.push_back(s("self.__class."sv) + toString(name->getFirstChild())); 1307 out.push_back(s("self.__class"sv) + s(invoke ? ":"sv : "."sv) + toString(name->getFirstChild()));
1031 break; 1308 break;
1032 case "self_class"_id: 1309 case "self_class"_id:
1033 out.push_back(s("self.__class"sv)); 1310 out.push_back(s("self.__class"sv));
@@ -1041,11 +1318,104 @@ private:
1041 } 1318 }
1042 } 1319 }
1043 1320
1044 void transformChain(Chain_t* chain, std::vector<std::string>& out, bool argsFollowed = false) { 1321 enum class ExpUsage {
1322 Return,
1323 Assignment,
1324 Common
1325 };
1326
1327 void transformColonChainClosure(ChainValue_t* chainValue, std::vector<std::string>& out) {
1328 std::vector<std::string> temp;
1329 temp.push_back(s("(function()"sv) + nll(chainValue));
1330 pushScope();
1331 transformColonChain(chainValue, temp, ExpUsage::Return);
1332 popScope();
1333 temp.push_back(s("end)()"sv));
1334 out.push_back(join(temp));
1335 }
1336
1337 void transformColonChain(ChainValue_t* chainValue, std::vector<std::string>& out, ExpUsage usage = ExpUsage::Common, ExpList_t* expList = nullptr) {
1045 std::vector<std::string> temp; 1338 std::vector<std::string> temp;
1339 auto chain = chainValue->caller.to<Chain_t>();
1046 const auto& chainList = chain->items.objects(); 1340 const auto& chainList = chain->items.objects();
1047 if (!argsFollowed && chainList.size() == 2 && chainList.back()->getId() == "ColonChainItem"_id) { 1341 auto end = --chainList.end();
1342 for (auto it = chainList.begin(); it != end; ++it) {
1343 auto item = *it;
1344 switch (item->getId()) {
1345 case "Invoke"_id: transformInvoke(static_cast<Invoke_t*>(item), temp); break;
1346 case "DotChainItem"_id: transformDotChainItem(static_cast<DotChainItem_t*>(item), temp); break;
1347 case "ColonChainItem"_id: transformColonChainItem(static_cast<ColonChainItem_t*>(item), temp); break;
1348 case "Slice"_id: transformSlice(static_cast<Slice_t*>(item), temp); break;
1349 case "Callable"_id: {
1350 auto next = it; ++next;
1351 auto followItem = next != chainList.end() ? *next : nullptr;
1352 transformCallable(static_cast<Callable_t*>(item), temp,
1353 followItem && followItem->getId() == "Invoke"_id);
1354 break;
1355 }
1356 case "String"_id:
1357 transformString(static_cast<String_t*>(item), temp);
1358 temp.back() = s("("sv) + temp.back() + s(")"sv);
1359 break;
1360 case "Exp"_id:
1361 transformExp(static_cast<Exp_t*>(item), temp);
1362 temp.back() = s("["sv) + temp.back() + s("]"sv);
1363 break;
1364 default: break;
1365 }
1366 }
1367 auto caller = join(temp);
1368 auto colonChainItem = static_cast<ColonChainItem_t*>(chainList.back());
1369 auto funcName = toString(colonChainItem->name);
1370 std::string assignList;
1371 if (expList) {
1372 std::vector<std::string> tmp;
1373 transformExpList(expList, tmp);
1374 assignList = tmp.back();
1375 }
1376 if (usage != ExpUsage::Return) pushScope();
1377 auto baseVar = getUnusedName("_base_"sv);
1378 addToScope(baseVar);
1379 auto fnVar = getUnusedName("_fn_"sv);
1380 addToScope(fnVar);
1381 if (usage != ExpUsage::Return) {
1382 _buf << indent(-1) << "do"sv << nll(chain);
1383 }
1384 _buf << indent() << "local "sv << baseVar << " = "sv << caller << nll(chain);
1385 _buf << indent() << "local "sv << fnVar << " = "sv << baseVar << "."sv << funcName << nll(chain);
1386 switch (usage) {
1387 case ExpUsage::Return:
1388 _buf << indent() << "return function(...)" << nll(chain);
1389 break;
1390 case ExpUsage::Assignment:
1391 _buf << indent() << assignList << " = function(...)"sv << nll(chain);
1392 break;
1393 case ExpUsage::Common:
1394 _buf << indent() << "_ = function(...)" << nll(chain);
1395 break;
1396 default: break;
1397 }
1398 _buf << indent(1) << "return "sv << fnVar << "("sv << baseVar << ", ...)"sv << nll(chain);
1399 _buf << indent() << "end"sv << nll(chain);
1400 if (usage != ExpUsage::Return) {
1401 popScope();
1402 _buf << indent() << "end"sv << nll(chain);
1403 }
1404 out.push_back(clearBuf());
1405 }
1048 1406
1407 void transformChain(Chain_t* chain, std::vector<std::string>& out) {
1408 std::vector<std::string> temp;
1409 const auto& chainList = chain->items.objects();
1410 switch (chainList.front()->getId()) {
1411 case "DotChainItem"_id:
1412 case "ColonChainItem"_id:
1413 if (_withVars.empty()) {
1414 throw std::logic_error("Short-dot syntax must be called within a with block.");
1415 } else {
1416 temp.push_back(_withVars.top());
1417 }
1418 break;
1049 } 1419 }
1050 for (auto it = chainList.begin(); it != chainList.end(); ++it) { 1420 for (auto it = chainList.begin(); it != chainList.end(); ++it) {
1051 auto item = *it; 1421 auto item = *it;
@@ -1128,7 +1498,9 @@ private:
1128 transform_normal_pair(static_cast<normal_pair_t*>(value), temp); 1498 transform_normal_pair(static_cast<normal_pair_t*>(value), temp);
1129 break; 1499 break;
1130 case "Exp"_id: 1500 case "Exp"_id:
1501 pushScope();
1131 transformExp(static_cast<Exp_t*>(value), temp); 1502 transformExp(static_cast<Exp_t*>(value), temp);
1503 popScope();
1132 break; 1504 break;
1133 default: break; 1505 default: break;
1134 } 1506 }
@@ -1332,10 +1704,8 @@ private:
1332 auto expList = toAst<ExpList_t>(assignLeft, ExpList); 1704 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1333 auto assignment = new_ptr<Assignment_t>(); 1705 auto assignment = new_ptr<Assignment_t>();
1334 assignment->assignable.set(expList); 1706 assignment->assignable.set(expList);
1335 auto expListLow = new_ptr<ExpListLow_t>();
1336 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1337 auto assign = new_ptr<Assign_t>(); 1707 auto assign = new_ptr<Assign_t>();
1338 assign->value.set(expListLow); 1708 assign->values.dup(ast_cast<ExpList_t>(last->content)->exprs);
1339 assignment->target.set(assign); 1709 assignment->target.set(assign);
1340 last->content.set(assignment); 1710 last->content.set(assignment);
1341 } 1711 }
@@ -1369,10 +1739,8 @@ private:
1369 auto expList = toAst<ExpList_t>(assignLeft, ExpList); 1739 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1370 auto assignment = new_ptr<Assignment_t>(); 1740 auto assignment = new_ptr<Assignment_t>();
1371 assignment->assignable.set(expList); 1741 assignment->assignable.set(expList);
1372 auto expListLow = new_ptr<ExpListLow_t>();
1373 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1374 auto assign = new_ptr<Assign_t>(); 1742 auto assign = new_ptr<Assign_t>();
1375 assign->value.set(expListLow); 1743 assign->values.dup(ast_cast<ExpList_t>(last->content)->exprs);
1376 assignment->target.set(assign); 1744 assignment->target.set(assign);
1377 last->content.set(assignment); 1745 last->content.set(assignment);
1378 } 1746 }
@@ -1421,10 +1789,8 @@ private:
1421 auto expList = toAst<ExpList_t>(assignLeft, ExpList); 1789 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1422 auto assignment = new_ptr<Assignment_t>(); 1790 auto assignment = new_ptr<Assignment_t>();
1423 assignment->assignable.set(expList); 1791 assignment->assignable.set(expList);
1424 auto expListLow = new_ptr<ExpListLow_t>();
1425 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1426 auto assign = new_ptr<Assign_t>(); 1792 auto assign = new_ptr<Assign_t>();
1427 assign->value.set(expListLow); 1793 assign->values.dup(ast_cast<ExpList_t>(last->content)->exprs);
1428 assignment->target.set(assign); 1794 assignment->target.set(assign);
1429 last->content.set(assignment); 1795 last->content.set(assignment);
1430 } 1796 }
@@ -1458,10 +1824,8 @@ private:
1458 auto expList = toAst<ExpList_t>(assignLeft, ExpList); 1824 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1459 auto assignment = new_ptr<Assignment_t>(); 1825 auto assignment = new_ptr<Assignment_t>();
1460 assignment->assignable.set(expList); 1826 assignment->assignable.set(expList);
1461 auto expListLow = new_ptr<ExpListLow_t>();
1462 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1463 auto assign = new_ptr<Assign_t>(); 1827 auto assign = new_ptr<Assign_t>();
1464 assign->value.set(expListLow); 1828 assign->values.dup(ast_cast<ExpList_t>(last->content)->exprs);
1465 assignment->target.set(assign); 1829 assignment->target.set(assign);
1466 last->content.set(assignment); 1830 last->content.set(assignment);
1467 } 1831 }
@@ -1478,10 +1842,12 @@ private:
1478 } 1842 }
1479 1843
1480 void transform_variable_pair(variable_pair_t* pair, std::vector<std::string>& out) { 1844 void transform_variable_pair(variable_pair_t* pair, std::vector<std::string>& out) {
1481 out.push_back(toString(pair->name)); 1845 auto name = toString(pair->name);
1846 out.push_back(name + s(" = "sv) + name);
1482 } 1847 }
1483 1848
1484 void transform_normal_pair(normal_pair_t* pair, std::vector<std::string>& out) { 1849 void transform_normal_pair(normal_pair_t* pair, std::vector<std::string>& out) {
1850 pushScope();
1485 auto key = pair->key.get(); 1851 auto key = pair->key.get();
1486 std::vector<std::string> temp; 1852 std::vector<std::string> temp;
1487 switch (key->getId()) { 1853 switch (key->getId()) {
@@ -1506,6 +1872,7 @@ private:
1506 default: break; 1872 default: break;
1507 } 1873 }
1508 out.push_back(temp[0] + s(" = "sv) + temp[1]); 1874 out.push_back(temp[0] + s(" = "sv) + temp[1]);
1875 popScope();
1509 } 1876 }
1510 1877
1511 void transformKeyName(KeyName_t* keyName, std::vector<std::string>& out) { 1878 void transformKeyName(KeyName_t* keyName, std::vector<std::string>& out) {
@@ -1567,40 +1934,66 @@ private:
1567 return {Empty, false}; 1934 return {Empty, false};
1568 } 1935 }
1569 1936
1570 enum class ClassDeclUsage {
1571 Return,
1572 Assignment,
1573 Common
1574 };
1575
1576 void transformClassDeclClosure(ClassDecl_t* classDecl, std::vector<std::string>& out) { 1937 void transformClassDeclClosure(ClassDecl_t* classDecl, std::vector<std::string>& out) {
1577 std::vector<std::string> temp; 1938 std::vector<std::string> temp;
1578 temp.push_back(s("(function()"sv) + nll(classDecl)); 1939 temp.push_back(s("(function()"sv) + nll(classDecl));
1579 pushScope(); 1940 pushScope();
1580 transformClassDecl(classDecl, temp, ClassDeclUsage::Return); 1941 transformClassDecl(classDecl, temp, ExpUsage::Return);
1581 popScope(); 1942 popScope();
1582 temp.push_back(s("end)()"sv)); 1943 temp.push_back(s("end)()"sv));
1583 out.push_back(join(temp)); 1944 out.push_back(join(temp));
1584 } 1945 }
1585 1946
1947 enum class MemType {
1948 Builtin,
1949 Common,
1950 Property
1951 };
1952
1586 struct ClassMember { 1953 struct ClassMember {
1587 std::string key; 1954 std::string item;
1588 bool isBuiltin; 1955 MemType type;
1589 ast_node* node; 1956 ast_node* node;
1590 }; 1957 };
1591 1958
1592 void transformClassDecl(ClassDecl_t* classDecl, std::vector<std::string>& out, ClassDeclUsage usage = ClassDeclUsage::Common, ExpList_t* expList = nullptr) { 1959 void transformClassDecl(ClassDecl_t* classDecl, std::vector<std::string>& out, ExpUsage usage = ExpUsage::Common, ExpList_t* expList = nullptr) {
1593 std::vector<std::string> temp; 1960 std::vector<std::string> temp;
1594 auto body = classDecl->body.get(); 1961 auto body = classDecl->body.get();
1595 auto assignable = classDecl->name.get(); 1962 auto assignable = classDecl->name.get();
1596 auto extend = classDecl->extend.get(); 1963 auto extend = classDecl->extend.get();
1597 std::string className; 1964 std::string className;
1965 std::string assignItem;
1598 if (assignable) { 1966 if (assignable) {
1599 bool newDefined = false; 1967 bool newDefined = false;
1600 std::tie(className, newDefined) = defineClassVariable(assignable); 1968 std::tie(className, newDefined) = defineClassVariable(assignable);
1601 if (newDefined) { 1969 if (newDefined) {
1602 temp.push_back(indent() + s("local "sv) + className + nll(classDecl)); 1970 temp.push_back(indent() + s("local "sv) + className + nll(classDecl));
1603 } 1971 }
1972 if (className.empty()) {
1973 if (auto chain = ast_cast<Chain_t>(assignable->item)) {
1974 if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.objects().back())) {
1975 className = s("\""sv) + toString(dotChain->name) + s("\""sv);
1976 } else if (auto index = ast_cast<Exp_t>(chain->items.objects().back())) {
1977 if (auto name = index->getByPath<Value_t, String_t>()) {
1978 transformString(name, temp);
1979 className = temp.back();
1980 temp.pop_back();
1981 }
1982 }
1983 }
1984 } else {
1985 className = s("\""sv) + className + s("\""sv);
1986 }
1987 pushScope();
1988 transformAssignable(assignable, temp);
1989 popScope();
1990 assignItem = temp.back();
1991 temp.pop_back();
1992 } else if (expList) {
1993 auto firstValue = firstValueFrom(expList);
1994 if (auto name = firstValue->getByPath<ChainValue_t, Callable_t, Variable_t>()) {
1995 className = s("\""sv) + toString(name) + s("\""sv);
1996 }
1604 } 1997 }
1605 temp.push_back(indent() + s("do"sv) + nll(classDecl)); 1998 temp.push_back(indent() + s("do"sv) + nll(classDecl));
1606 pushScope(); 1999 pushScope();
@@ -1608,16 +2001,27 @@ private:
1608 addToScope(classVar); 2001 addToScope(classVar);
1609 temp.push_back(indent() + s("local "sv) + classVar + nll(classDecl)); 2002 temp.push_back(indent() + s("local "sv) + classVar + nll(classDecl));
1610 if (body) { 2003 if (body) {
2004 std::vector<std::string> varDefs;
1611 body->traverse([&](ast_node* node) { 2005 body->traverse([&](ast_node* node) {
1612 if (node->getId() == "Statement"_id) { 2006 if (node->getId() == "Statement"_id) {
1613 if (auto assignment = static_cast<Assignment_t*>(node->getByPath({"Assignment"_id}))) { 2007 if (auto assignment = node->getByPath<Assignment_t>()) {
1614 std::string preDefine = transformAssignDefs(assignment->assignable.get()); 2008 auto names = transformAssignDefs(assignment->assignable.get());
1615 if (!preDefine.empty()) temp.push_back(preDefine + nll(assignment)); 2009 varDefs.insert(varDefs.end(), names.begin(), names.end());
2010 auto info = extractDestructureInfo(assignment);
2011 if (!info.first.empty()) {
2012 for (const auto& destruct : info.first)
2013 for (const auto& item : destruct.items)
2014 if (addToScope(item.name))
2015 varDefs.push_back(item.name);
2016 }
1616 } 2017 }
1617 return traversal::Return; 2018 return traversal::Return;
1618 } 2019 }
1619 return traversal::Continue; 2020 return traversal::Continue;
1620 }); 2021 });
2022 if (!varDefs.empty()) {
2023 temp.push_back(indent() + s("local ") + join(varDefs, ", "sv) + nll(body));
2024 }
1621 } 2025 }
1622 std::string parent, parentVar; 2026 std::string parent, parentVar;
1623 if (extend) { 2027 if (extend) {
@@ -1634,7 +2038,7 @@ private:
1634 addToScope(selfVar); 2038 addToScope(selfVar);
1635 temp.push_back(indent() + s("local "sv) + baseVar + s(" = "sv)); 2039 temp.push_back(indent() + s("local "sv) + baseVar + s(" = "sv));
1636 std::vector<std::string> builtins; 2040 std::vector<std::string> builtins;
1637 std::vector<std::string> customs; 2041 std::vector<std::string> commons;
1638 std::vector<std::string> statements; 2042 std::vector<std::string> statements;
1639 if (body) { 2043 if (body) {
1640 std::list<ClassMember> members; 2044 std::list<ClassMember> members;
@@ -1642,12 +2046,20 @@ private:
1642 auto classLine = static_cast<ClassLine_t*>(_classLine); 2046 auto classLine = static_cast<ClassLine_t*>(_classLine);
1643 auto content = classLine->content.get(); 2047 auto content = classLine->content.get();
1644 switch (content->getId()) { 2048 switch (content->getId()) {
1645 case "class_member_list"_id: 2049 case "class_member_list"_id: {
1646 pushScope(); 2050 size_t inc = transform_class_member_list(static_cast<class_member_list_t*>(content), members, classVar);
1647 transform_class_member_list(static_cast<class_member_list_t*>(content), members, classVar); 2051 auto it = members.end();
1648 popScope(); 2052 for (size_t i = 0; i < inc; ++i, --it);
1649 members.back().key = indent(1) + members.back().key; 2053 for (; it != members.end(); ++it) {
2054 auto& member = *it;
2055 if (member.type == MemType::Property) {
2056 statements.push_back(indent() + member.item + nll(content));
2057 } else {
2058 member.item = indent(1) + member.item;
2059 }
2060 }
1650 break; 2061 break;
2062 }
1651 case "Statement"_id: 2063 case "Statement"_id:
1652 transformStatement(static_cast<Statement_t*>(content), statements); 2064 transformStatement(static_cast<Statement_t*>(content), statements);
1653 break; 2065 break;
@@ -1655,23 +2067,27 @@ private:
1655 } 2067 }
1656 } 2068 }
1657 for (auto& member : members) { 2069 for (auto& member : members) {
1658 if (member.isBuiltin) { 2070 switch (member.type) {
1659 builtins.push_back((builtins.empty() ? Empty : s(","sv) + nll(member.node)) + member.key); 2071 case MemType::Common:
1660 } else { 2072 commons.push_back((commons.empty() ? Empty : s(","sv) + nll(member.node)) + member.item);
1661 customs.push_back((customs.empty() ? Empty : s(","sv) + nll(member.node)) + member.key); 2073 break;
2074 case MemType::Builtin:
2075 builtins.push_back((builtins.empty() ? Empty : s(","sv) + nll(member.node)) + member.item);
2076 break;
2077 default: break;
1662 } 2078 }
1663 } 2079 }
1664 if (!customs.empty()) { 2080 if (!commons.empty()) {
1665 temp.back() += s("{"sv) + nll(body); 2081 temp.back() += s("{"sv) + nll(body);
1666 temp.push_back(join(customs) + nll(body)); 2082 temp.push_back(join(commons) + nll(body));
1667 temp.push_back(indent() + s("}"sv) + nll(body)); 2083 temp.push_back(indent() + s("}"sv) + nll(body));
1668 } else { 2084 } else {
1669 temp.back() += s("{ }"sv) + nll(body); 2085 temp.back() += s("{ }"sv) + nll(body);
1670 } 2086 }
1671 temp.push_back(indent() + baseVar + s(".__index = "sv) + baseVar + nll(classDecl));
1672 } else { 2087 } else {
1673 temp.back() += s("{ }"sv) + nll(classDecl); 2088 temp.back() += s("{ }"sv) + nll(classDecl);
1674 } 2089 }
2090 temp.push_back(indent() + baseVar + s(".__index = "sv) + baseVar + nll(classDecl));
1675 if (extend) { 2091 if (extend) {
1676 _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl); 2092 _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl);
1677 } 2093 }
@@ -1689,7 +2105,7 @@ private:
1689 } 2105 }
1690 _buf << indent(1) << "__base = "sv << baseVar; 2106 _buf << indent(1) << "__base = "sv << baseVar;
1691 if (!className.empty()) { 2107 if (!className.empty()) {
1692 _buf << ","sv << nll(classDecl) << indent(1) << "__name = \""sv << className << "\""sv << (extend ? s(","sv) : Empty) << nll(classDecl); 2108 _buf << ","sv << nll(classDecl) << indent(1) << "__name = "sv << className << (extend ? s(","sv) : Empty) << nll(classDecl);
1693 } else { 2109 } else {
1694 _buf << nll(classDecl); 2110 _buf << nll(classDecl);
1695 } 2111 }
@@ -1719,20 +2135,22 @@ private:
1719 _buf << indent(1) << "end"sv << nll(classDecl); 2135 _buf << indent(1) << "end"sv << nll(classDecl);
1720 _buf << indent() << "})"sv << nll(classDecl); 2136 _buf << indent() << "})"sv << nll(classDecl);
1721 _buf << indent() << baseVar << ".__class = "sv << classVar << nll(classDecl); 2137 _buf << indent() << baseVar << ".__class = "sv << classVar << nll(classDecl);
2138 if (!statements.empty()) _buf << indent() << "local self = "sv << classVar << nll(classDecl);
2139 _buf << join(statements);
1722 if (extend) { 2140 if (extend) {
1723 _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nll(classDecl); 2141 _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nll(classDecl);
1724 _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nll(classDecl); 2142 _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nll(classDecl);
1725 _buf << indent() << "end"sv << nll(classDecl); 2143 _buf << indent() << "end"sv << nll(classDecl);
1726 } 2144 }
1727 if (!statements.empty()) _buf << indent() << "local self = "sv << classVar << nll(classDecl); 2145 if (!assignItem.empty()) {
1728 _buf << join(statements); 2146 _buf << indent() << assignItem << " = "sv << classVar << nll(classDecl);
1729 if (!className.empty()) _buf << indent() << className << " = "sv << classVar << nll(classDecl); 2147 }
1730 switch (usage) { 2148 switch (usage) {
1731 case ClassDeclUsage::Return: { 2149 case ExpUsage::Return: {
1732 _buf << indent() << "return "sv << classVar << nlr(classDecl); 2150 _buf << indent() << "return "sv << classVar << nlr(classDecl);
1733 break; 2151 break;
1734 } 2152 }
1735 case ClassDeclUsage::Assignment: { 2153 case ExpUsage::Assignment: {
1736 std::vector<std::string> tmp; 2154 std::vector<std::string> tmp;
1737 transformExpList(expList, tmp); 2155 transformExpList(expList, tmp);
1738 _buf << indent() << tmp.back() << " = "sv << classVar << nlr(classDecl); 2156 _buf << indent() << tmp.back() << " = "sv << classVar << nlr(classDecl);
@@ -1746,30 +2164,39 @@ private:
1746 out.push_back(join(temp)); 2164 out.push_back(join(temp));
1747 } 2165 }
1748 2166
1749 void transform_class_member_list(class_member_list_t* class_member_list, std::list<ClassMember>& out, const std::string& classVar) { 2167 size_t transform_class_member_list(class_member_list_t* class_member_list, std::list<ClassMember>& out, const std::string& classVar) {
1750 std::vector<std::string> temp; 2168 std::vector<std::string> temp;
2169 size_t count = 0;
1751 for (auto keyValue : class_member_list->values.objects()) { 2170 for (auto keyValue : class_member_list->values.objects()) {
1752 bool isBuiltin = false; 2171 MemType type = MemType::Common;
1753 do { 2172 do {
1754 auto normal_pair = ast_cast<normal_pair_t>(keyValue); 2173 auto normal_pair = ast_cast<normal_pair_t>(keyValue);
1755 if (!normal_pair) break; 2174 if (!normal_pair) break;
1756 auto keyName = normal_pair->key.as<KeyName_t>(); 2175 auto keyName = normal_pair->key.as<KeyName_t>();
1757 if (!keyName) break; 2176 if (!keyName) break;
1758 auto nameNode = keyName->name.as<Name_t>();
1759 if (!nameNode) break;
1760 auto name = toString(nameNode);
1761 input newSuperCall; 2177 input newSuperCall;
1762 isBuiltin = name == "new"sv; 2178 auto selfName = keyName->name.as<SelfName_t>();
1763 if (isBuiltin) { 2179 if (selfName) {
1764 keyName->name.set(toAst<Name_t>("__init"sv, Name)); 2180 type = MemType::Property;
1765 newSuperCall = _converter.from_bytes(classVar) + L".__parent.__init"; 2181 auto name = ast_cast<self_name_t>(selfName->name);
2182 if (!name) throw std::logic_error("Invalid class poperty name");
2183 newSuperCall = _converter.from_bytes(classVar) + L".__parent." + _converter.from_bytes(toString(name->name));
1766 } else { 2184 } else {
1767 newSuperCall = _converter.from_bytes(classVar) + L".__parent.__base." + _converter.from_bytes(name); 2185 auto nameNode = keyName->name.as<Name_t>();
2186 if (!nameNode) break;
2187 auto name = toString(nameNode);
2188 if (name == "new"sv) {
2189 type = MemType::Builtin;
2190 keyName->name.set(toAst<Name_t>("__init"sv, Name));
2191 newSuperCall = _converter.from_bytes(classVar) + L".__parent.__init";
2192 } else {
2193 newSuperCall = _converter.from_bytes(classVar) + L".__parent.__base." + _converter.from_bytes(name);
2194 }
1768 } 2195 }
1769 normal_pair->value->traverse([&](ast_node* node) { 2196 normal_pair->value->traverse([&](ast_node* node) {
1770 if (node->getId() == "ClassDecl"_id) return traversal::Return; 2197 if (node->getId() == "ClassDecl"_id) return traversal::Return;
1771 if (auto chainValue = ast_cast<ChainValue_t>(node)) { 2198 if (auto chainValue = ast_cast<ChainValue_t>(node)) {
1772 if (auto var = chainValue->caller->getByPath({"Variable"_id})) { 2199 if (auto var = chainValue->caller->getByPath<Variable_t>()) {
1773 if (toString(var) == "super"sv) { 2200 if (toString(var) == "super"sv) {
1774 if (chainValue->arguments) { 2201 if (chainValue->arguments) {
1775 chainValue->arguments->args.push_front(toAst<Exp_t>("self"sv, Exp)); 2202 chainValue->arguments->args.push_front(toAst<Exp_t>("self"sv, Exp));
@@ -1782,7 +2209,7 @@ private:
1782 var->m_end.m_it = _codeCache.back().end(); 2209 var->m_end.m_it = _codeCache.back().end();
1783 } 2210 }
1784 } 2211 }
1785 } else if (auto var = chainValue->caller->getByPath({"Callable"_id, "Variable"_id})) { 2212 } else if (auto var = chainValue->caller->getByPath<Callable_t, Variable_t>()) {
1786 if (toString(var) == "super"sv) { 2213 if (toString(var) == "super"sv) {
1787 auto insertSelfToArguments = [&](ast_node* item) { 2214 auto insertSelfToArguments = [&](ast_node* item) {
1788 switch (item->getId()) { 2215 switch (item->getId()) {
@@ -1801,23 +2228,19 @@ private:
1801 } 2228 }
1802 }; 2229 };
1803 auto chainList = getChainList(chainValue); 2230 auto chainList = getChainList(chainValue);
1804 if (chainList.size() == 2) { 2231 if (chainList.size() >= 2) {
1805 if (insertSelfToArguments(chainList.back())) { 2232 if (insertSelfToArguments(chainList[1])) {
1806 _codeCache.push_back(newSuperCall); 2233 _codeCache.push_back(newSuperCall);
1807 } else { 2234 } else {
2235 if (auto colonChainItem = ast_cast<ColonChainItem_t>(chainList[1])) {
2236 if (chainList.size() > 2 && insertSelfToArguments(chainList[2])) {
2237 colonChainItem->switchToDot = true;
2238 }
2239 }
1808 _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent"); 2240 _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent");
1809 } 2241 }
1810 var->m_begin.m_it = _codeCache.back().begin(); 2242 var->m_begin.m_it = _codeCache.back().begin();
1811 var->m_end.m_it = _codeCache.back().end(); 2243 var->m_end.m_it = _codeCache.back().end();
1812 } else if (chainList.size() > 2) {
1813 _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent");
1814 var->m_begin.m_it = _codeCache.back().begin();
1815 var->m_end.m_it = _codeCache.back().end();
1816 if (auto colonChainItem = ast_cast<ColonChainItem_t>(chainList[1])) {
1817 colonChainItem->switchToDot = true;
1818 auto item = chainList[2];
1819 insertSelfToArguments(item);
1820 }
1821 } else { 2244 } else {
1822 _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent"); 2245 _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent");
1823 var->m_begin.m_it = _codeCache.back().begin(); 2246 var->m_begin.m_it = _codeCache.back().begin();
@@ -1829,6 +2252,9 @@ private:
1829 return traversal::Continue; 2252 return traversal::Continue;
1830 }); 2253 });
1831 } while (false); 2254 } while (false);
2255 if (type == MemType::Property) {
2256 setIndentOffset(-1);
2257 }
1832 switch (keyValue->getId()) { 2258 switch (keyValue->getId()) {
1833 case "variable_pair"_id: 2259 case "variable_pair"_id:
1834 transform_variable_pair(static_cast<variable_pair_t*>(keyValue), temp); 2260 transform_variable_pair(static_cast<variable_pair_t*>(keyValue), temp);
@@ -1837,9 +2263,14 @@ private:
1837 transform_normal_pair(static_cast<normal_pair_t*>(keyValue), temp); 2263 transform_normal_pair(static_cast<normal_pair_t*>(keyValue), temp);
1838 break; 2264 break;
1839 } 2265 }
1840 out.push_back({temp.back(), isBuiltin, keyValue}); 2266 if (type == MemType::Property) {
2267 setIndentOffset(0);
2268 }
2269 out.push_back({temp.back(), type, keyValue});
1841 temp.clear(); 2270 temp.clear();
2271 ++count;
1842 } 2272 }
2273 return count;
1843 } 2274 }
1844 2275
1845 void transformAssignable(Assignable_t* assignable, std::vector<std::string>& out) { 2276 void transformAssignable(Assignable_t* assignable, std::vector<std::string>& out) {
@@ -1852,43 +2283,369 @@ private:
1852 } 2283 }
1853 } 2284 }
1854 2285
2286 void transformWith(With_t* with, std::vector<std::string>& out) {
2287 std::vector<std::string> temp;
2288 temp.push_back(indent() + s("do"sv) + nll(with));
2289 pushScope();
2290 std::string withVar;
2291 if (with->assigns) {
2292 auto vars = getAssignVars(with->valueList);
2293 if (vars.front().empty()) {
2294 withVar = getUnusedName("_with_");
2295 {
2296 auto assignment = new_ptr<Assignment_t>();
2297 assignment->assignable.set(toAst<ExpList_t>(withVar, ExpList));
2298 auto assign = new_ptr<Assign_t>();
2299 assign->values.push_back(with->assigns->values.objects().front());
2300 assignment->target.set(assign);
2301 transformAssignment(assignment, temp);
2302 }
2303 {
2304 auto assignment = new_ptr<Assignment_t>();
2305 assignment->assignable.set(with->valueList);
2306 auto assign = new_ptr<Assign_t>();
2307 assign->values.push_back(toAst<Exp_t>(withVar, Exp));
2308 bool skipFirst = true;
2309 for (auto value : with->assigns->values.objects()) {
2310 if (skipFirst) {
2311 skipFirst = false;
2312 continue;
2313 }
2314 assign->values.push_back(value);
2315 }
2316 assignment->target.set(assign);
2317 transformAssignment(assignment, temp);
2318 }
2319 } else {
2320 withVar = vars.front();
2321 auto assignment = new_ptr<Assignment_t>();
2322 assignment->assignable.set(with->valueList);
2323 assignment->target.set(with->assigns);
2324 transformAssignment(assignment, temp);
2325 }
2326 } else {
2327 withVar = getUnusedName("_with_");
2328 auto assignment = new_ptr<Assignment_t>();
2329 assignment->assignable.set(toAst<ExpList_t>(withVar, ExpList));
2330 auto assign = new_ptr<Assign_t>();
2331 assign->values.dup(with->valueList->exprs);
2332 assignment->target.set(assign);
2333 transformAssignment(assignment, temp);
2334 }
2335 _withVars.push(withVar);
2336 transformBody(with->body, temp);
2337 _withVars.pop();
2338 popScope();
2339 temp.push_back(indent() + s("end"sv) + nll(with));
2340 out.push_back(join(temp));
2341 }
2342
2343 void transform_const_value(const_value_t* const_value, std::vector<std::string>& out) {
2344 out.push_back(toString(const_value));
2345 }
2346
2347 void transformExport(Export_t* exportNode, std::vector<std::string>& out) {
2348 auto item = exportNode->item.get();
2349 switch (item->getId()) {
2350 case "ClassDecl"_id: {
2351 auto classDecl = static_cast<ClassDecl_t*>(item);
2352 if (classDecl->name && classDecl->name->item->getId() == "Variable"_id) {
2353 markVarExported(ExportMode::Any, true);
2354 addExportedVar(toString(classDecl->name->item));
2355 }
2356 transformClassDecl(classDecl, out);
2357 break;
2358 }
2359 case "export_op"_id:
2360 if (toString(item) == "*"sv) {
2361 markVarExported(ExportMode::Any, false);
2362 } else {
2363 markVarExported(ExportMode::Capital, false);
2364 }
2365 break;
2366 case "export_values"_id: {
2367 markVarExported(ExportMode::Any, true);
2368 auto values = exportNode->item.to<export_values_t>();
2369 if (values->valueList) {
2370 auto expList = new_ptr<ExpList_t>();
2371 for (auto name : values->nameList->names.objects()) {
2372 addExportedVar(toString(name));
2373 auto callable = new_ptr<Callable_t>();
2374 callable->item.set(name);
2375 auto chainValue = new_ptr<ChainValue_t>();
2376 chainValue->caller.set(callable);
2377 auto value = new_ptr<Value_t>();
2378 value->item.set(chainValue);
2379 auto exp = new_ptr<Exp_t>();
2380 exp->value.set(value);
2381 expList->exprs.push_back(exp);
2382 }
2383 auto assignment = new_ptr<Assignment_t>();
2384 assignment->assignable.set(expList);
2385 auto assign = new_ptr<Assign_t>();
2386 assign->values.dup(values->valueList->exprs);
2387 assignment->target.set(assign);
2388 transformAssignment(assignment, out);
2389 }
2390 break;
2391 }
2392 default:
2393 break;
2394 }
2395 }
2396
2397 void transform_simple_table(simple_table_t* table, std::vector<std::string>& out) {
2398 std::vector<std::string> temp;
2399 pushScope();
2400 for (auto pair : table->pairs.objects()) {
2401 switch (pair->getId()) {
2402 case "variable_pair"_id:
2403 transform_variable_pair(static_cast<variable_pair_t*>(pair), temp);
2404 temp.back() = indent() + temp.back() + nll(pair);
2405 break;
2406 case "normal_pair"_id:
2407 transform_normal_pair(static_cast<normal_pair_t*>(pair), temp);
2408 temp.back() = indent() + temp.back() + nll(pair);
2409 break;
2410 }
2411 }
2412 popScope();
2413 out.push_back(s("{"sv) + nll(table) + join(temp) + s("}"sv));
2414 }
2415
1855 void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 2416 void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1856 void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 2417 void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
1857 void transformWhile(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 2418 void transformWhile(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
1858 void transformWith(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
1859 void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 2419 void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
1860 void transformTableBlock(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 2420 void transformTableBlock(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
1861 void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 2421 void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
1862 void transformExport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
1863 void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 2422 void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
1864 void transform_unless_line(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 2423 void transform_unless_line(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1865 void transform_simple_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1866 void transform_const_value(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1867 void transformDo(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 2424 void transformDo(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1868 void transformTblComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 2425 void transformTblComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1869 void transformSlice(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 2426 void transformSlice(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1870 void transformCompFor(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1871 void transformCompClause(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1872 void transform_invoke_args_with_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1873 void transformUnless(Unless_t* node, std::vector<std::string>& out) {noop(node, out);} 2427 void transformUnless(Unless_t* node, std::vector<std::string>& out) {noop(node, out);}
2428 void transformCompFor(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
1874}; 2429};
1875 2430
1876const std::string MoonCompliler::Empty; 2431const std::string MoonCompliler::Empty;
1877 2432
1878int main() 2433int main()
1879{ 2434{
1880 std::string s = R"TestCodesHere(my_func 5,6,7, 2435 std::string s = R"TestCodesHere(
1881 6, another_func 6,7,8, 2436class Hello
1882 9,1,2, 2437 new: (@test, @world) =>
1883 5,4, :name, :value)TestCodesHere"; 2438 print "creating object.."
1884/* 2439 hello: =>
1885return my_func(5, 6, 7, 6, another_func(6, 7, 8, 9, 1, 2), 5, 4) 2440 print @test, @world
2441 __tostring: => "hello world"
2442
2443x = Hello 1,2
2444x\hello()
2445
2446print x
2447
2448class Simple
2449 cool: => print "cool"
2450
2451class Yikes extends Simple
2452 new: => print "created hello"
2453
2454x = Yikes()
2455x\cool()
2456
2457
2458class Hi
2459 new: (arg) =>
2460 print "init arg", arg
2461
2462 cool: (num) =>
2463 print "num", num
2464
2465
2466class Simple extends Hi
2467 new: => super "man"
2468 cool: => super 120302
2469
2470x = Simple()
2471x\cool()
2472
2473print x.__class == Simple
2474
2475
2476class Okay
2477 -- what is going on
2478 something: 20323
2479 -- yeaha
2480
2481
2482class Biggie extends Okay
2483 something: =>
2484 super 1,2,3,4
2485 super.something another_self, 1,2,3,4
2486 assert super == Okay
2487
2488
2489class Yeah
2490 okay: =>
2491 super\something 1,2,3,4
2492
2493
2494class What
2495 something: => print "val:", @val
2496
2497class Hello extends What
2498 val: 2323
2499 something: => super\something
1886 2500
1887with Hello! 2501with Hello!
1888 x = \something! 2502 x = \something!
1889 print x 2503 print x
1890 x! 2504 x!
1891*/ 2505
2506class CoolSuper
2507 hi: =>
2508 super(1,2,3,4) 1,2,3,4
2509 super.something 1,2,3,4
2510 super.something(1,2,3,4).world
2511 super\yeah"world".okay hi, hi, hi
2512 something.super
2513 super.super.super.super
2514 super\hello
2515 nil
2516
2517
2518-- selfing
2519x = @hello
2520x = @@hello
2521
2522@hello "world"
2523@@hello "world"
2524
2525@@one @@two(4,5) @three, @four
2526
2527xx = (@hello, @@world, cool) ->
2528
2529
2530-- class properties
2531class ClassMan
2532 @yeah: 343
2533 blue: =>
2534 @hello: 3434, @world: 23423
2535 green: =>
2536 @red: =>
2537
2538
2539x = @
2540y = @@
2541
2542@ something
2543
2544@@ something
2545
2546@ = @ + @ / @
2547
2548@ = 343
2549@.hello 2,3,4
2550
2551hello[@].world
2552
2553
2554class Whacko
2555 @hello
2556 if something
2557 print "hello world"
2558
2559 hello = "world"
2560 @another = "day"
2561
2562 print "yeah" if something -- this is briken
2563
2564
2565print "hello"
2566
2567yyy = ->
2568 class Cool
2569 nil
2570
2571
2572--
2573
2574class a.b.c.D
2575 nil
2576
2577
2578class a.b["hello"]
2579 nil
2580
2581class (-> require "moon")!.Something extends Hello.World
2582 nil
2583
2584--
2585
2586a = class
2587b = class Something
2588c = class Something extends Hello
2589d = class extends World
2590
2591print (class WhatsUp).__name
2592
2593--
2594
2595export ^
2596class Something
2597 nil
2598
2599
2600--
2601
2602-- hoisting
2603class Something
2604 val = 23
2605 {:insert} = table
2606 new: => print insert, val -- prints nil 23
2607
2608--
2609
2610class X
2611 new: hi
2612
2613
2614--
2615
2616class Cool extends Thing
2617 dang: =>
2618 {
2619 hello: -> super!
2620 world: -> super.one
2621 }
2622
2623--
2624
2625class Whack extends Thing
2626 dang: do_something =>
2627 super!
2628
2629---
2630
2631class Wowha extends Thing
2632 @butt: ->
2633 super!
2634 super.hello
2635 super\hello!
2636 super\hello
2637
2638
2639 @zone: cool {
2640 ->
2641 super!
2642 super.hello
2643 super\hello!
2644 super\hello
2645 }
2646
2647nil
2648)TestCodesHere";
1892 MoonCompliler{}.complile(s); 2649 MoonCompliler{}.complile(s);
1893 2650
1894 return 0; 2651 return 0;
diff --git a/MoonParser/moon_ast.h b/MoonParser/moon_ast.h
index c4f20c3..5d38905 100644
--- a/MoonParser/moon_ast.h
+++ b/MoonParser/moon_ast.h
@@ -247,7 +247,8 @@ AST_END(CompInner)
247class TableBlock_t; 247class TableBlock_t;
248 248
249AST_NODE(Assign, "Assign"_id) 249AST_NODE(Assign, "Assign"_id)
250 ast_ptr<ast_node> value; // With_t | If_t | Switch_t | TableBlock_t | ExpListLow_t 250 ast_ptr<Seperator_t> sep;
251 ast_sel_list<With_t, If_t, Switch_t, TableBlock_t, Exp_t> values;
251AST_END(Assign) 252AST_END(Assign)
252 253
253AST_LEAF(update_op, "update_op"_id) 254AST_LEAF(update_op, "update_op"_id)
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp
index 8917e58..116c9de 100644
--- a/MoonParser/moon_parser.cpp
+++ b/MoonParser/moon_parser.cpp
@@ -220,7 +220,7 @@ rule CompClause = CompFor | CompForEach | key("when") >> Exp;
220 220
221extern rule TableBlock; 221extern rule TableBlock;
222 222
223rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow); 223rule Assign = sym('=') >> Seperator >> (With | If | Switch | TableBlock | Exp >> *((sym(',') | sym(';')) >> Exp));
224 224
225rule update_op = 225rule update_op =
226 expr("..=") | 226 expr("..=") |