diff options
-rw-r--r-- | MoonParser/ast.hpp | 46 | ||||
-rw-r--r-- | MoonParser/moon_ast.cpp | 1089 | ||||
-rw-r--r-- | MoonParser/moon_ast.h | 15 | ||||
-rw-r--r-- | MoonParser/moon_parser.cpp | 4 |
4 files changed, 671 insertions, 483 deletions
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp index 63dccba..480f9b3 100644 --- a/MoonParser/ast.hpp +++ b/MoonParser/ast.hpp | |||
@@ -230,13 +230,19 @@ public: | |||
230 | return static_cast<T*>(m_ptr); | 230 | return static_cast<T*>(m_ptr); |
231 | } | 231 | } |
232 | 232 | ||
233 | template <class T> | ||
234 | bool is() const { | ||
235 | return m_ptr->get_type() == ast_type<T>(); | ||
236 | } | ||
237 | |||
233 | void set(ast_node* node) { | 238 | void set(ast_node* node) { |
234 | if (node == m_ptr) return; | 239 | if (node == m_ptr) { |
235 | else if (!node) { | 240 | return; |
241 | } else if (!node) { | ||
236 | if (m_ptr) m_ptr->release(); | 242 | if (m_ptr) m_ptr->release(); |
237 | m_ptr = nullptr; | 243 | m_ptr = nullptr; |
238 | } | 244 | } else { |
239 | else if (accept(node)) { | 245 | assert(accept(node)); |
240 | if (m_ptr) m_ptr->release(); | 246 | if (m_ptr) m_ptr->release(); |
241 | m_ptr = node; | 247 | m_ptr = node; |
242 | node->retain(); | 248 | node->retain(); |
@@ -383,33 +389,29 @@ public: | |||
383 | } | 389 | } |
384 | 390 | ||
385 | void push_back(ast_node* node) { | 391 | void push_back(ast_node* node) { |
386 | if (accept(node)) { | 392 | assert(node && accept(node)); |
387 | m_objects.push_back(node); | 393 | m_objects.push_back(node); |
388 | node->retain(); | 394 | node->retain(); |
389 | } | ||
390 | } | 395 | } |
391 | 396 | ||
392 | void push_front(ast_node* node) { | 397 | void push_front(ast_node* node) { |
393 | if (accept(node)) { | 398 | assert(node && accept(node)); |
394 | m_objects.push_front(node); | 399 | m_objects.push_front(node); |
395 | node->retain(); | 400 | node->retain(); |
396 | } | ||
397 | } | 401 | } |
398 | 402 | ||
399 | void set_front(ast_node* node) { | 403 | void set_front(ast_node* node) { |
400 | if (accept(node)) { | 404 | assert(node && accept(node)); |
401 | m_objects.front()->release(); | 405 | m_objects.front()->release(); |
402 | m_objects.front() = node; | 406 | m_objects.front() = node; |
403 | node->retain(); | 407 | node->retain(); |
404 | } | ||
405 | } | 408 | } |
406 | 409 | ||
407 | void set_back(ast_node* node) { | 410 | void set_back(ast_node* node) { |
408 | if (accept(node)) { | 411 | assert(node && accept(node)); |
409 | m_objects.back()->release(); | 412 | m_objects.back()->release(); |
410 | m_objects.back() = node; | 413 | m_objects.back() = node; |
411 | node->retain(); | 414 | node->retain(); |
412 | } | ||
413 | } | 415 | } |
414 | 416 | ||
415 | const container& objects() const { | 417 | const container& objects() const { |
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index 103eb8e..217f2b5 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp | |||
@@ -45,7 +45,6 @@ AST_IMPL(With) | |||
45 | AST_IMPL(SwitchCase) | 45 | AST_IMPL(SwitchCase) |
46 | AST_IMPL(Switch) | 46 | AST_IMPL(Switch) |
47 | AST_IMPL(IfCond) | 47 | AST_IMPL(IfCond) |
48 | AST_IMPL(IfElseIf) | ||
49 | AST_IMPL(If) | 48 | AST_IMPL(If) |
50 | AST_IMPL(Unless) | 49 | AST_IMPL(Unless) |
51 | AST_IMPL(While) | 50 | AST_IMPL(While) |
@@ -121,11 +120,6 @@ AST_IMPL(BlockEnd) | |||
121 | 120 | ||
122 | #include <iostream> | 121 | #include <iostream> |
123 | 122 | ||
124 | template<class T, class... Args> | ||
125 | inline std::unique_ptr<T> MakeUnique(Args&&... args) { | ||
126 | return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | ||
127 | } | ||
128 | |||
129 | inline std::string s(std::string_view sv) { | 123 | inline std::string s(std::string_view sv) { |
130 | return std::string(sv); | 124 | return std::string(sv); |
131 | } | 125 | } |
@@ -179,9 +173,43 @@ private: | |||
179 | std::list<Scope> _scopes; | 173 | std::list<Scope> _scopes; |
180 | static const std::string Empty; | 174 | static const std::string Empty; |
181 | 175 | ||
176 | enum class MemType { | ||
177 | Builtin, | ||
178 | Common, | ||
179 | Property | ||
180 | }; | ||
181 | |||
182 | struct ClassMember { | ||
183 | std::string item; | ||
184 | MemType type; | ||
185 | ast_node* node; | ||
186 | }; | ||
187 | |||
188 | struct DestructItem { | ||
189 | std::string name; | ||
190 | std::string structure; | ||
191 | }; | ||
192 | |||
193 | struct Destructure { | ||
194 | std::string value; | ||
195 | std::list<DestructItem> items; | ||
196 | }; | ||
197 | |||
198 | enum class ExpUsage { | ||
199 | Return, | ||
200 | Assignment, | ||
201 | Common | ||
202 | }; | ||
203 | |||
204 | enum class IfUsage { | ||
205 | Return, | ||
206 | Closure, | ||
207 | Common | ||
208 | }; | ||
209 | |||
182 | void pushScope() { | 210 | void pushScope() { |
183 | _scopes.emplace_back(); | 211 | _scopes.emplace_back(); |
184 | _scopes.back().vars = MakeUnique<std::unordered_set<std::string>>(); | 212 | _scopes.back().vars = std::make_unique<std::unordered_set<std::string>>(); |
185 | } | 213 | } |
186 | 214 | ||
187 | void popScope() { | 215 | void popScope() { |
@@ -227,14 +255,14 @@ private: | |||
227 | 255 | ||
228 | void markVarShadowed() { | 256 | void markVarShadowed() { |
229 | auto& scope = _scopes.back(); | 257 | auto& scope = _scopes.back(); |
230 | scope.allows = MakeUnique<std::unordered_set<std::string>>(); | 258 | scope.allows = std::make_unique<std::unordered_set<std::string>>(); |
231 | } | 259 | } |
232 | 260 | ||
233 | void markVarExported(ExportMode mode, bool specified) { | 261 | void markVarExported(ExportMode mode, bool specified) { |
234 | auto& scope = _scopes.back(); | 262 | auto& scope = _scopes.back(); |
235 | scope.mode = mode; | 263 | scope.mode = mode; |
236 | if (specified && !scope.exports) { | 264 | if (specified && !scope.exports) { |
237 | scope.exports = MakeUnique<std::unordered_set<std::string>>(); | 265 | scope.exports = std::make_unique<std::unordered_set<std::string>>(); |
238 | } | 266 | } |
239 | } | 267 | } |
240 | 268 | ||
@@ -355,6 +383,14 @@ private: | |||
355 | return static_cast<Value_t*>(singleValue); | 383 | return static_cast<Value_t*>(singleValue); |
356 | } | 384 | } |
357 | 385 | ||
386 | SimpleValue_t* simpleSingleValueFrom(ast_node* expList) { | ||
387 | auto value = singleValueFrom(expList); | ||
388 | if (value && value->item.is<SimpleValue_t>()) { | ||
389 | return static_cast<SimpleValue_t*>(value->item.get()); | ||
390 | } | ||
391 | return nullptr; | ||
392 | } | ||
393 | |||
358 | Value_t* firstValueFrom(ast_node* expList) { | 394 | Value_t* firstValueFrom(ast_node* expList) { |
359 | Value_t* firstValue = nullptr; | 395 | Value_t* firstValue = nullptr; |
360 | expList->traverse([&](ast_node* n) { | 396 | expList->traverse([&](ast_node* n) { |
@@ -400,6 +436,14 @@ private: | |||
400 | return parse<T>(_codeCache.back(), r, el, &st); | 436 | return parse<T>(_codeCache.back(), r, el, &st); |
401 | } | 437 | } |
402 | 438 | ||
439 | template <class T> | ||
440 | bool matchAst(std::string_view codes, rule& r) { | ||
441 | error_list el; | ||
442 | State st; | ||
443 | input i = _converter.from_bytes(s(codes)); | ||
444 | return parse<T>(i, r, el, &st); | ||
445 | } | ||
446 | |||
403 | bool isChainValueCall(ChainValue_t* chainValue) { | 447 | bool isChainValueCall(ChainValue_t* chainValue) { |
404 | if (chainValue->arguments) return true; | 448 | if (chainValue->arguments) return true; |
405 | if (auto chain = chainValue->caller.as<Chain_t>()) { | 449 | if (auto chain = chainValue->caller.as<Chain_t>()) { |
@@ -437,15 +481,19 @@ private: | |||
437 | 481 | ||
438 | void transformStatement(Statement_t* statement, std::vector<std::string>& out) { | 482 | void transformStatement(Statement_t* statement, std::vector<std::string>& out) { |
439 | if (statement->appendix) { | 483 | if (statement->appendix) { |
440 | auto appendix = statement->appendix; | 484 | if (auto assignment = statement->content.as<Assignment_t>()) { |
485 | auto preDefine = getPredefine(transformAssignDefs(assignment->assignable)); | ||
486 | if (!preDefine.empty()) out.push_back(preDefine + nll(statement)); | ||
487 | } | ||
488 | auto appendix = statement->appendix.get(); | ||
441 | switch (appendix->item->getId()) { | 489 | switch (appendix->item->getId()) { |
442 | case "if_else_line"_id: { | 490 | case "if_else_line"_id: { |
443 | auto if_else_line = static_cast<if_else_line_t*>(appendix->item.get()); | 491 | auto if_else_line = appendix->item.to<if_else_line_t>(); |
444 | auto ifNode = new_ptr<If_t>(); | 492 | auto ifNode = new_ptr<If_t>(); |
445 | 493 | ||
446 | auto ifCond = new_ptr<IfCond_t>(); | 494 | auto ifCond = new_ptr<IfCond_t>(); |
447 | ifCond->condition.set(if_else_line->condition); | 495 | ifCond->condition.set(if_else_line->condition); |
448 | ifNode->firstCondition.set(ifCond); | 496 | ifNode->nodes.push_back(ifCond); |
449 | 497 | ||
450 | if (!ast_is<default_value_t>(if_else_line->elseExpr)) { | 498 | if (!ast_is<default_value_t>(if_else_line->elseExpr)) { |
451 | auto exprList = new_ptr<ExpList_t>(); | 499 | auto exprList = new_ptr<ExpList_t>(); |
@@ -454,13 +502,13 @@ private: | |||
454 | stmt->content.set(exprList); | 502 | stmt->content.set(exprList); |
455 | auto body = new_ptr<Body_t>(); | 503 | auto body = new_ptr<Body_t>(); |
456 | body->content.set(stmt); | 504 | body->content.set(stmt); |
457 | ifNode->lastBranch.set(body); | 505 | ifNode->nodes.push_back(body); |
458 | } | 506 | } |
459 | auto stmt = new_ptr<Statement_t>(); | 507 | auto stmt = new_ptr<Statement_t>(); |
460 | stmt->content.set(statement->content); | 508 | stmt->content.set(statement->content); |
461 | auto body = new_ptr<Body_t>(); | 509 | auto body = new_ptr<Body_t>(); |
462 | body->content.set(stmt); | 510 | body->content.set(stmt); |
463 | ifNode->firstBody.set(body); | 511 | ifNode->nodes.push_back(body); |
464 | 512 | ||
465 | statement->appendix.set(nullptr); | 513 | statement->appendix.set(nullptr); |
466 | auto simpleValue = new_ptr<SimpleValue_t>(); | 514 | auto simpleValue = new_ptr<SimpleValue_t>(); |
@@ -475,9 +523,66 @@ private: | |||
475 | break; | 523 | break; |
476 | } | 524 | } |
477 | case "unless_line"_id: { | 525 | case "unless_line"_id: { |
526 | auto unless_line = appendix->item.to<unless_line_t>(); | ||
527 | auto unless = new_ptr<Unless_t>(); | ||
528 | |||
529 | auto ifCond = new_ptr<IfCond_t>(); | ||
530 | ifCond->condition.set(unless_line->condition); | ||
531 | unless->nodes.push_back(ifCond); | ||
532 | |||
533 | auto stmt = new_ptr<Statement_t>(); | ||
534 | stmt->content.set(statement->content); | ||
535 | auto body = new_ptr<Body_t>(); | ||
536 | body->content.set(stmt); | ||
537 | unless->nodes.push_back(body); | ||
538 | |||
539 | statement->appendix.set(nullptr); | ||
540 | auto simpleValue = new_ptr<SimpleValue_t>(); | ||
541 | simpleValue->value.set(unless); | ||
542 | auto value = new_ptr<Value_t>(); | ||
543 | value->item.set(simpleValue); | ||
544 | auto exp = new_ptr<Exp_t>(); | ||
545 | exp->value.set(value); | ||
546 | auto exprList = new_ptr<ExpList_t>(); | ||
547 | exprList->exprs.push_back(exp); | ||
548 | statement->content.set(exprList); | ||
478 | break; | 549 | break; |
479 | } | 550 | } |
480 | case "CompInner"_id: { | 551 | case "CompInner"_id: { |
552 | auto compInner = appendix->item.to<CompInner_t>(); | ||
553 | switch (compInner->compFor->getId()) { | ||
554 | case "CompFor"_id: { | ||
555 | auto compFor = compInner->compFor.to<CompFor_t>(); | ||
556 | auto forNode = new_ptr<For_t>(); | ||
557 | forNode->startValue.set(compFor->startValue); | ||
558 | forNode->stopValue.set(compFor->stopValue); | ||
559 | forNode->stepValue.set(compFor->stepValue); | ||
560 | forNode->varName.set(compFor->varName); | ||
561 | auto stmt = new_ptr<Statement_t>(); | ||
562 | stmt->content.set(statement->content); | ||
563 | auto body = new_ptr<Body_t>(); | ||
564 | body->content.set(stmt); | ||
565 | forNode->body.set(body); | ||
566 | statement->appendix.set(nullptr); | ||
567 | statement->content.set(forNode); | ||
568 | break; | ||
569 | } | ||
570 | case "CompForEach"_id: { | ||
571 | auto compForEach = compInner->compFor.to<CompForEach_t>(); | ||
572 | auto forEach = new_ptr<ForEach_t>(); | ||
573 | forEach->nameList.set(compForEach->nameList); | ||
574 | forEach->loopValue.set(compForEach->loopValue); | ||
575 | auto stmt = new_ptr<Statement_t>(); | ||
576 | stmt->content.set(statement->content); | ||
577 | auto body = new_ptr<Body_t>(); | ||
578 | body->content.set(stmt); | ||
579 | forEach->body.set(body); | ||
580 | statement->appendix.set(nullptr); | ||
581 | statement->content.set(forEach); | ||
582 | break; | ||
583 | } | ||
584 | default: break; | ||
585 | } | ||
481 | break; | 586 | break; |
482 | } | 587 | } |
483 | default: break; | 588 | default: break; |
@@ -531,25 +636,15 @@ private: | |||
531 | transformValue(singleValue, out); | 636 | transformValue(singleValue, out); |
532 | out.back() = indent() + out.back() + nlr(singleValue); | 637 | out.back() = indent() + out.back() + nlr(singleValue); |
533 | break; | 638 | break; |
534 | } else if (isColonChain(chainValue)){ | ||
535 | std::string preDefine; | ||
536 | if (addToScope(s("_"sv))) { | ||
537 | preDefine = indent() + s("local _"sv) + nll(chainValue); | ||
538 | } | ||
539 | transformColonChain(chainValue, out); | ||
540 | out.back().insert(0, preDefine); | ||
541 | break; | ||
542 | } | 639 | } |
543 | } | 640 | } |
544 | } | 641 | } |
545 | std::string preDefine; | 642 | auto assign = new_ptr<Assign_t>(); |
546 | if (addToScope(s("_"sv))) { | 643 | assign->values.dup(expList->exprs); |
547 | preDefine = indent() + s("local _"sv) + nll(expList); | 644 | auto assignment = new_ptr<Assignment_t>(); |
548 | } | 645 | assignment->assignable.set(toAst<ExpList_t>("_", ExpList)); |
549 | preDefine.append(indent() + s("_ = "sv)); | 646 | assignment->target.set(assign); |
550 | std::vector<std::string> temp; | 647 | transformAssignment(assignment, out); |
551 | transformExpList(expList, temp); | ||
552 | out.push_back(preDefine + temp.back() + nlr(expList)); | ||
553 | break; | 648 | break; |
554 | } | 649 | } |
555 | default: break; | 650 | default: break; |
@@ -602,126 +697,131 @@ private: | |||
602 | return indent() + s("local "sv) + join(defs, ", "sv); | 697 | return indent() + s("local "sv) + join(defs, ", "sv); |
603 | } | 698 | } |
604 | 699 | ||
605 | struct DestructItem { | ||
606 | std::string name; | ||
607 | std::string structure; | ||
608 | }; | ||
609 | |||
610 | struct Destructure { | ||
611 | std::string value; | ||
612 | std::list<DestructItem> items; | ||
613 | }; | ||
614 | |||
615 | void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) { | 700 | void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) { |
616 | auto assign = ast_cast<Assign_t>(assignment->target); | 701 | auto assign = ast_cast<Assign_t>(assignment->target); |
617 | if (assign && assign->values.objects().size() == 1) { | 702 | do { |
618 | if (auto ifNode = assign->getByPath<If_t>()) { | 703 | if (!assign || assign->values.objects().size() != 1) break; |
704 | auto value = assign->values.objects().front(); | ||
705 | ast_node* item = nullptr; | ||
706 | if (ast_is<If_t>(value)) { | ||
707 | item = value; | ||
708 | } else if (auto val = simpleSingleValueFrom(value)) { | ||
709 | if (ast_is<If_t,Unless_t>(val->value)) { | ||
710 | item = val->value; | ||
711 | } | ||
712 | } | ||
713 | if (item) { | ||
619 | auto expList = assignment->assignable.get(); | 714 | auto expList = assignment->assignable.get(); |
620 | std::vector<std::string> temp; | 715 | std::vector<std::string> temp; |
621 | std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs; | ||
622 | ifCondPairs.emplace_back(); | ||
623 | auto defs = transformAssignDefs(expList); | 716 | auto defs = transformAssignDefs(expList); |
624 | if (!defs.empty()) temp.push_back(getPredefine(defs) + nll(expList)); | 717 | if (!defs.empty()) temp.push_back(getPredefine(defs) + nll(expList)); |
625 | ifNode->traverse([&](ast_node* node) { | 718 | item->traverse([&](ast_node* node) { |
626 | switch (node->getId()) { | 719 | switch (node->getId()) { |
627 | case "IfCond"_id: | 720 | case "IfCond"_id: return traversal::Return; |
628 | ifCondPairs.back().first = static_cast<IfCond_t*>(node); | 721 | case "Body"_id: { |
629 | return traversal::Return; | 722 | auto body = static_cast<Body_t*>(node); |
630 | case "Body"_id: | 723 | auto last = lastStatementFrom(body); |
631 | ifCondPairs.back().second = static_cast<Body_t*>(node); | 724 | auto valueList = last ? last->content.as<ExpList_t>() : nullptr; |
632 | ifCondPairs.emplace_back(); | 725 | if (last && valueList) { |
726 | auto newAssignment = new_ptr<Assignment_t>(); | ||
727 | newAssignment->assignable.set(expList); | ||
728 | auto assign = new_ptr<Assign_t>(); | ||
729 | assign->values.dup(valueList->exprs); | ||
730 | newAssignment->target.set(assign); | ||
731 | last->content.set(newAssignment); | ||
732 | } | ||
633 | return traversal::Return; | 733 | return traversal::Return; |
734 | } | ||
634 | default: return traversal::Continue; | 735 | default: return traversal::Continue; |
635 | } | 736 | } |
636 | }); | 737 | }); |
637 | for (const auto& pair : ifCondPairs) { | 738 | switch (item->getId()) { |
638 | if (pair.first) { | 739 | case "If"_id: transformIf(static_cast<If_t*>(item), temp); break; |
639 | std::vector<std::string> tmp; | 740 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(item), temp); break; |
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 | } | ||
667 | } | 741 | } |
668 | out.push_back(join(temp)); | 742 | out.push_back(join(temp)); |
669 | return; | 743 | return; |
670 | } | 744 | } |
671 | auto exp = ast_cast<Exp_t>(assign->values.objects().front()); | 745 | auto exp = ast_cast<Exp_t>(value); |
672 | if (exp && exp->opValues.objects().empty()) { | 746 | if (!exp) break; |
673 | if (auto simpleVal = exp->value->item.as<SimpleValue_t>()) { | 747 | auto simpleVal = exp->value->item.as<SimpleValue_t>(); |
674 | auto valueItem = simpleVal->value.get(); | 748 | if (!simpleVal) break; |
675 | switch (valueItem->getId()) { | 749 | auto valueItem = simpleVal->value.get(); |
676 | case "Comprehension"_id: { | 750 | switch (valueItem->getId()) { |
677 | std::vector<std::string> temp; | 751 | case "Do"_id: { |
678 | auto expList = assignment->assignable.get(); | 752 | auto expList = assignment->assignable.get(); |
679 | transformExpList(expList, temp); | 753 | auto doNode = static_cast<Do_t*>(valueItem); |
680 | transformCompInPlace(static_cast<Comprehension_t*>(valueItem), temp.front(), temp); | 754 | auto last = lastStatementFrom(doNode->body); |
681 | std::string preDefine = getPredefine(transformAssignDefs(expList)); | 755 | auto valueList = last ? last->content.as<ExpList_t>() : nullptr; |
682 | out.push_back(preDefine + nll(assignment) + temp.back()); | 756 | if (last && valueList) { |
683 | return; | 757 | auto newAssignment = new_ptr<Assignment_t>(); |
684 | } | 758 | newAssignment->assignable.set(expList); |
685 | case "For"_id: { | 759 | auto assign = new_ptr<Assign_t>(); |
686 | std::vector<std::string> temp; | 760 | assign->values.dup(valueList->exprs); |
687 | auto expList = assignment->assignable.get(); | 761 | newAssignment->target.set(assign); |
688 | std::string preDefine = getPredefine(transformAssignDefs(expList)); | 762 | last->content.set(newAssignment); |
689 | transformForInPlace(static_cast<For_t*>(valueItem), temp, expList); | 763 | std::string preDefine = getPredefine(transformAssignDefs(expList)); |
690 | auto nl = preDefine.empty() ? Empty : nll(assignment); | 764 | auto nl = preDefine.empty() ? Empty : nll(assignment); |
691 | out.push_back(preDefine + nl + temp.front()); | 765 | transformDo(doNode, out); |
692 | return; | 766 | out.back() = preDefine + nl + out.back(); |
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 | } | 767 | } |
768 | return; | ||
713 | } | 769 | } |
714 | if (auto chainValue = exp->value->item.as<ChainValue_t>()) { | 770 | case "Comprehension"_id: { |
715 | if (isColonChain(chainValue)) { | 771 | auto expList = assignment->assignable.get(); |
716 | auto assignable = assignment->assignable.get(); | 772 | std::string preDefine = getPredefine(transformAssignDefs(expList)); |
717 | std::string preDefine = getPredefine(transformAssignDefs(assignable)); | 773 | auto nl = preDefine.empty() ? Empty : nll(assignment); |
718 | transformColonChain(chainValue, out, ExpUsage::Assignment, static_cast<ExpList_t*>(assignable)); | 774 | transformCompInPlace(static_cast<Comprehension_t*>(valueItem), expList, out); |
719 | if (!preDefine.empty()) out.back() = preDefine + nll(chainValue) + out.back(); | 775 | out.back() = preDefine + nl + out.back(); |
720 | return; | 776 | return; |
721 | } | 777 | } |
778 | case "TblComprehension"_id: { | ||
779 | auto expList = assignment->assignable.get(); | ||
780 | std::string preDefine = getPredefine(transformAssignDefs(expList)); | ||
781 | auto nl = preDefine.empty() ? Empty : nll(assignment); | ||
782 | transformTblCompInPlace(static_cast<TblComprehension_t*>(valueItem), expList, out); | ||
783 | out.back() = preDefine + nl + out.back(); | ||
784 | return; | ||
785 | } | ||
786 | case "For"_id: { | ||
787 | std::vector<std::string> temp; | ||
788 | auto expList = assignment->assignable.get(); | ||
789 | std::string preDefine = getPredefine(transformAssignDefs(expList)); | ||
790 | auto nl = preDefine.empty() ? Empty : nll(assignment); | ||
791 | transformForInPlace(static_cast<For_t*>(valueItem), temp, expList); | ||
792 | out.push_back(preDefine + nl + temp.front()); | ||
793 | return; | ||
794 | } | ||
795 | case "ForEach"_id: { | ||
796 | std::vector<std::string> temp; | ||
797 | auto expList = assignment->assignable.get(); | ||
798 | std::string preDefine = getPredefine(transformAssignDefs(expList)); | ||
799 | transformForEachInPlace(static_cast<ForEach_t*>(valueItem), temp, expList); | ||
800 | auto nl = preDefine.empty() ? Empty : nll(assignment); | ||
801 | out.push_back(preDefine + nl + temp.front()); | ||
802 | return; | ||
803 | } | ||
804 | case "ClassDecl"_id: { | ||
805 | std::vector<std::string> temp; | ||
806 | auto expList = assignment->assignable.get(); | ||
807 | std::string preDefine = getPredefine(transformAssignDefs(expList)); | ||
808 | transformClassDecl(static_cast<ClassDecl_t*>(valueItem), temp, ExpUsage::Assignment, expList); | ||
809 | auto nl = preDefine.empty() ? Empty : nll(assignment); | ||
810 | out.push_back(preDefine + nl + temp.front()); | ||
811 | return; | ||
722 | } | 812 | } |
723 | } | 813 | } |
724 | } | 814 | if (auto chainValue = exp->value->item.as<ChainValue_t>()) { |
815 | if (isColonChain(chainValue)) { | ||
816 | auto assignable = assignment->assignable.get(); | ||
817 | std::string preDefine = getPredefine(transformAssignDefs(assignable)); | ||
818 | transformColonChain(chainValue, out, ExpUsage::Assignment, static_cast<ExpList_t*>(assignable)); | ||
819 | auto nl = preDefine.empty() ? Empty : nll(chainValue); | ||
820 | if (!preDefine.empty()) out.back() = preDefine + nl + out.back(); | ||
821 | return; | ||
822 | } | ||
823 | } | ||
824 | } while (false); | ||
725 | auto info = extractDestructureInfo(assignment); | 825 | auto info = extractDestructureInfo(assignment); |
726 | if (info.first.empty()) { | 826 | if (info.first.empty()) { |
727 | transformAssignmentCommon(assignment, out); | 827 | transformAssignmentCommon(assignment, out); |
@@ -736,6 +836,19 @@ private: | |||
736 | } | 836 | } |
737 | _buf << pair.name << " = "sv << info.first.front().value << pair.structure << nll(assignment); | 837 | _buf << pair.name << " = "sv << info.first.front().value << pair.structure << nll(assignment); |
738 | temp.push_back(clearBuf()); | 838 | temp.push_back(clearBuf()); |
839 | } else if (matchAst<Name_t>(destruct.value, Name)) { | ||
840 | std::vector<std::string> defs, names, values; | ||
841 | for (const auto& item : destruct.items) { | ||
842 | if (addToScope(item.name)) { | ||
843 | defs.push_back(item.name); | ||
844 | } | ||
845 | names.push_back(item.name); | ||
846 | values.push_back(item.structure); | ||
847 | } | ||
848 | if (!defs.empty()) _buf << indent() << "local "sv << join(defs,", "sv) << nll(assignment); | ||
849 | for (auto& v : values) v.insert(0, destruct.value); | ||
850 | _buf << indent() << join(names, ", "sv) << " = "sv << join(values, ", "sv) << nll(assignment); | ||
851 | temp.push_back(clearBuf()); | ||
739 | } else { | 852 | } else { |
740 | std::vector<std::string> defs, names, values; | 853 | std::vector<std::string> defs, names, values; |
741 | for (const auto& item : destruct.items) { | 854 | for (const auto& item : destruct.items) { |
@@ -745,7 +858,7 @@ private: | |||
745 | names.push_back(item.name); | 858 | names.push_back(item.name); |
746 | values.push_back(item.structure); | 859 | values.push_back(item.structure); |
747 | } | 860 | } |
748 | if (!defs.empty()) _buf << indent() << "local "sv << join(defs) << nll(assignment); | 861 | if (!defs.empty()) _buf << indent() << "local "sv << join(defs,", "sv) << nll(assignment); |
749 | _buf << indent() << "do"sv << nll(assignment); | 862 | _buf << indent() << "do"sv << nll(assignment); |
750 | pushScope(); | 863 | pushScope(); |
751 | auto objVar = getUnusedName("_obj_"); | 864 | auto objVar = getUnusedName("_obj_"); |
@@ -766,11 +879,11 @@ private: | |||
766 | 879 | ||
767 | void transformAssignItem(ast_node* value, std::vector<std::string>& out) { | 880 | void transformAssignItem(ast_node* value, std::vector<std::string>& out) { |
768 | switch (value->getId()) { | 881 | switch (value->getId()) { |
769 | case "With"_id: transformWith(ast_to<With_t>(value), out); break; | 882 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; |
770 | case "If"_id: transformIfClosure(ast_to<If_t>(value), out); break; | 883 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; |
771 | case "Switch"_id: transformSwitch(value, out); break; | 884 | case "Switch"_id: transformSwitch(value, out); break; |
772 | case "TableBlock"_id: transformTableBlock(value, out); break; | 885 | case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), out); break; |
773 | case "Exp"_id: transformExp(ast_to<Exp_t>(value), out); break; | 886 | case "Exp"_id: transformExp(static_cast<Exp_t*>(value), out); break; |
774 | default: break; | 887 | default: break; |
775 | } | 888 | } |
776 | } | 889 | } |
@@ -796,7 +909,7 @@ private: | |||
796 | switch (pair->getId()) { | 909 | switch (pair->getId()) { |
797 | case "Exp"_id: { | 910 | case "Exp"_id: { |
798 | ++index; | 911 | ++index; |
799 | auto item = singleValueFrom(node)->item.get(); | 912 | auto item = singleValueFrom(pair)->item.get(); |
800 | if (!item) throw std::logic_error("Invalid destructure value"); | 913 | if (!item) throw std::logic_error("Invalid destructure value"); |
801 | if (auto value = item->getByPath<Callable_t, Variable_t>()) { | 914 | if (auto value = item->getByPath<Callable_t, Variable_t>()) { |
802 | auto name = toString(value); | 915 | auto name = toString(value); |
@@ -859,9 +972,16 @@ private: | |||
859 | auto exprs = assignment->assignable->exprs.objects(); | 972 | auto exprs = assignment->assignable->exprs.objects(); |
860 | auto values = assignment->target.to<Assign_t>()->values.objects(); | 973 | auto values = assignment->target.to<Assign_t>()->values.objects(); |
861 | size_t size = std::max(exprs.size(),values.size()); | 974 | size_t size = std::max(exprs.size(),values.size()); |
862 | auto nullNode = toAst<Exp_t>("nil"sv, Exp); | 975 | ast_ptr<Exp_t, false, false> var; |
863 | while (exprs.size() < size) exprs.emplace_back(); | 976 | if (exprs.size() < size) { |
864 | while (values.size() < size) values.emplace_back(nullNode); | 977 | var = toAst<Exp_t>("_"sv, Exp); |
978 | while (exprs.size() < size) exprs.emplace_back(var); | ||
979 | } | ||
980 | ast_ptr<Exp_t, false, false> nullNode; | ||
981 | if (values.size() < size) { | ||
982 | nullNode = toAst<Exp_t>("nil"sv, Exp); | ||
983 | while (values.size() < size) values.emplace_back(nullNode); | ||
984 | } | ||
865 | using iter = std::list<ast_node*>::iterator; | 985 | using iter = std::list<ast_node*>::iterator; |
866 | std::vector<std::pair<iter, iter>> destructPairs; | 986 | std::vector<std::pair<iter, iter>> destructPairs; |
867 | std::vector<std::string> temp; | 987 | std::vector<std::string> temp; |
@@ -940,33 +1060,81 @@ private: | |||
940 | } | 1060 | } |
941 | } | 1061 | } |
942 | 1062 | ||
943 | void transformIf(If_t* ifNode, std::vector<std::string>& out, bool withClosure = false) { | 1063 | void transformCond(const std::list<ast_node*>& nodes, std::vector<std::string>& out, IfUsage usage = IfUsage::Common, bool unless = false) { |
1064 | std::vector<ast_ptr<ast_node, false, false>> ns; | ||
1065 | for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { | ||
1066 | ns.push_back(*it); | ||
1067 | if (auto cond = ast_cast<IfCond_t>(*it)) { | ||
1068 | if (*it != nodes.front() && cond->assign) { | ||
1069 | auto newIf = new_ptr<If_t>(); | ||
1070 | for (auto j = ns.rbegin(); j != ns.rend(); ++j) { | ||
1071 | newIf->nodes.push_back(*j); | ||
1072 | } | ||
1073 | ns.clear(); | ||
1074 | auto simpleValue = new_ptr<SimpleValue_t>(); | ||
1075 | simpleValue->value.set(newIf); | ||
1076 | auto value = new_ptr<Value_t>(); | ||
1077 | value->item.set(simpleValue); | ||
1078 | auto exp = new_ptr<Exp_t>(); | ||
1079 | exp->value.set(value); | ||
1080 | auto expList = new_ptr<ExpList_t>(); | ||
1081 | expList->exprs.push_back(exp); | ||
1082 | auto stmt = new_ptr<Statement_t>(); | ||
1083 | stmt->content.set(expList); | ||
1084 | auto body = new_ptr<Body_t>(); | ||
1085 | body->content.set(stmt); | ||
1086 | ns.push_back(body.get()); | ||
1087 | } | ||
1088 | } | ||
1089 | } | ||
1090 | if (nodes.size() != ns.size()) { | ||
1091 | auto newIf = new_ptr<If_t>(); | ||
1092 | for (auto j = ns.rbegin(); j != ns.rend(); ++j) { | ||
1093 | newIf->nodes.push_back(*j); | ||
1094 | } | ||
1095 | transformCond(newIf->nodes.objects(), out, usage, unless); | ||
1096 | return; | ||
1097 | } | ||
944 | std::vector<std::string> temp; | 1098 | std::vector<std::string> temp; |
945 | if (withClosure) { | 1099 | if (usage == IfUsage::Closure) { |
946 | temp.push_back(s("(function()"sv) + nll(ifNode)); | 1100 | temp.push_back(s("(function()"sv) + nll(nodes.front())); |
947 | pushScope(); | 1101 | pushScope(); |
948 | } | 1102 | } |
949 | std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs; | 1103 | std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs; |
950 | ifCondPairs.emplace_back(); | 1104 | ifCondPairs.emplace_back(); |
951 | ifNode->traverse([&](ast_node* node) { | 1105 | for (auto node : nodes) { |
952 | switch (node->getId()) { | 1106 | switch (node->getId()) { |
953 | case "IfCond"_id: | 1107 | case "IfCond"_id: |
954 | ifCondPairs.back().first = static_cast<IfCond_t*>(node); | 1108 | ifCondPairs.back().first = static_cast<IfCond_t*>(node); |
955 | return traversal::Return; | 1109 | break; |
956 | case "Body"_id: | 1110 | case "Body"_id: |
957 | ifCondPairs.back().second = static_cast<Body_t*>(node); | 1111 | ifCondPairs.back().second = static_cast<Body_t*>(node); |
958 | ifCondPairs.emplace_back(); | 1112 | ifCondPairs.emplace_back(); |
959 | return traversal::Return; | 1113 | break; |
960 | default: return traversal::Continue; | 1114 | default: break; |
961 | } | 1115 | } |
962 | }); | 1116 | } |
1117 | auto assign = ifCondPairs.front().first->assign.get(); | ||
1118 | if (assign) { | ||
1119 | auto exp = ifCondPairs.front().first->condition.get(); | ||
1120 | auto expList = new_ptr<ExpList_t>(); | ||
1121 | expList->exprs.push_back(exp); | ||
1122 | auto assignment = new_ptr<Assignment_t>(); | ||
1123 | assignment->assignable.set(expList); | ||
1124 | assignment->target.set(assign); | ||
1125 | if (usage != IfUsage::Closure) { | ||
1126 | temp.push_back(indent() + s("do"sv) + nll(assign)); | ||
1127 | pushScope(); | ||
1128 | } | ||
1129 | transformAssignment(assignment, temp); | ||
1130 | } | ||
963 | for (const auto& pair : ifCondPairs) { | 1131 | for (const auto& pair : ifCondPairs) { |
964 | if (pair.first) { | 1132 | if (pair.first) { |
965 | std::vector<std::string> tmp; | 1133 | std::vector<std::string> tmp; |
966 | auto condition = pair.first->condition.get(); | 1134 | auto condition = pair.first->condition.get(); |
967 | transformExp(condition, tmp); | 1135 | transformExp(condition, tmp); |
968 | _buf << indent() << (pair == ifCondPairs.front() ? ""sv : "else"sv) << | 1136 | _buf << indent() << (pair == ifCondPairs.front() ? ""sv : "else"sv) << |
969 | "if "sv << tmp.front() << " then"sv << nll(condition); | 1137 | "if "sv << (unless ? "not ("sv : ""sv) << tmp.front() << (unless ? ") then"sv : " then"sv) << nll(condition); |
970 | temp.push_back(clearBuf()); | 1138 | temp.push_back(clearBuf()); |
971 | } | 1139 | } |
972 | if (pair.second) { | 1140 | if (pair.second) { |
@@ -974,23 +1142,31 @@ private: | |||
974 | temp.push_back(indent() + s("else"sv) + nll(pair.second)); | 1142 | temp.push_back(indent() + s("else"sv) + nll(pair.second)); |
975 | } | 1143 | } |
976 | pushScope(); | 1144 | pushScope(); |
977 | transformBody(pair.second, temp, withClosure); | 1145 | transformBody(pair.second, temp, usage != IfUsage::Common); |
978 | popScope(); | 1146 | popScope(); |
979 | } | 1147 | } |
980 | if (!pair.first) { | 1148 | if (!pair.first) { |
981 | temp.push_back(indent() + s("end"sv) + nll(ifNode)); | 1149 | temp.push_back(indent() + s("end"sv) + nll(nodes.front())); |
982 | break; | 1150 | break; |
983 | } | 1151 | } |
984 | } | 1152 | } |
985 | if (withClosure) { | 1153 | if (assign && usage != IfUsage::Closure) { |
1154 | popScope(); | ||
1155 | temp.push_back(indent() + s("end"sv) + nlr(nodes.front())); | ||
1156 | } | ||
1157 | if (usage == IfUsage::Closure) { | ||
986 | popScope(); | 1158 | popScope(); |
987 | temp.push_back(indent() + s("end)()"sv)); | 1159 | temp.push_back(indent() + s("end)()"sv)); |
988 | } | 1160 | } |
989 | out.push_back(join(temp)); | 1161 | out.push_back(join(temp)); |
990 | } | 1162 | } |
991 | 1163 | ||
992 | void transformIfClosure(If_t* ifNode, std::vector<std::string>& out) { | 1164 | void transformIf(If_t* ifNode, std::vector<std::string>& out, IfUsage usage = IfUsage::Common) { |
993 | transformIf(ifNode, out, true); | 1165 | transformCond(ifNode->nodes.objects(), out, usage); |
1166 | } | ||
1167 | |||
1168 | void transformUnless(Unless_t* unless, std::vector<std::string>& out, IfUsage usage = IfUsage::Common) { | ||
1169 | transformCond(unless->nodes.objects(), out, usage, true); | ||
994 | } | 1170 | } |
995 | 1171 | ||
996 | void transformExpList(ExpList_t* expList, std::vector<std::string>& out) { | 1172 | void transformExpList(ExpList_t* expList, std::vector<std::string>& out) { |
@@ -1077,18 +1253,19 @@ private: | |||
1077 | auto value = simpleValue->value.get(); | 1253 | auto value = simpleValue->value.get(); |
1078 | switch (value->getId()) { | 1254 | switch (value->getId()) { |
1079 | case "const_value"_id: transform_const_value(static_cast<const_value_t*>(value), out); break; | 1255 | case "const_value"_id: transform_const_value(static_cast<const_value_t*>(value), out); break; |
1080 | case "If"_id: transformIfClosure(static_cast<If_t*>(value), out); break; | 1256 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; |
1257 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), out, IfUsage::Closure); break; | ||
1081 | case "Switch"_id: transformSwitch(value, out); break; | 1258 | case "Switch"_id: transformSwitch(value, out); break; |
1082 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; | 1259 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; |
1083 | case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; | 1260 | case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; |
1084 | case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break; | 1261 | case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break; |
1085 | case "For"_id: transformForClosure(static_cast<For_t*>(value), out); break; | 1262 | case "For"_id: transformForClosure(static_cast<For_t*>(value), out); break; |
1086 | case "While"_id: transformWhile(value, out); break; | 1263 | case "While"_id: transformWhile(value, out); break; |
1087 | case "Do"_id: transformDo(value, out); break; | 1264 | case "Do"_id: transformDoClosure(static_cast<Do_t*>(value), out); break; |
1088 | case "unary_exp"_id: transform_unary_exp(static_cast<unary_exp_t*>(value), out); break; | 1265 | case "unary_exp"_id: transform_unary_exp(static_cast<unary_exp_t*>(value), out); break; |
1089 | case "TblComprehension"_id: transformTblComprehension(value, out); break; | 1266 | case "TblComprehension"_id: transformTblCompClosure(static_cast<TblComprehension_t*>(value), out); break; |
1090 | case "TableLit"_id: transformTableLit(static_cast<TableLit_t*>(value), out); break; | 1267 | case "TableLit"_id: transformTableLit(static_cast<TableLit_t*>(value), out); break; |
1091 | case "Comprehension"_id: transformComprehension(static_cast<Comprehension_t*>(value), out); break; | 1268 | case "Comprehension"_id: transformCompClosure(static_cast<Comprehension_t*>(value), out); break; |
1092 | case "FunLit"_id: transformFunLit(static_cast<FunLit_t*>(value), out); break; | 1269 | case "FunLit"_id: transformFunLit(static_cast<FunLit_t*>(value), out); break; |
1093 | case "Num"_id: transformNum(static_cast<Num_t*>(value), out); break; | 1270 | case "Num"_id: transformNum(static_cast<Num_t*>(value), out); break; |
1094 | default: break; | 1271 | default: break; |
@@ -1145,7 +1322,8 @@ private: | |||
1145 | void transformCodes(ast_node* nodes, std::vector<std::string>& out, bool implicitReturn) { | 1322 | void transformCodes(ast_node* nodes, std::vector<std::string>& out, bool implicitReturn) { |
1146 | if (implicitReturn) { | 1323 | if (implicitReturn) { |
1147 | auto last = lastStatementFrom(nodes); | 1324 | auto last = lastStatementFrom(nodes); |
1148 | if (ast_is<ExpList_t>(last->content)) { | 1325 | if (ast_is<ExpList_t>(last->content) && (!last->appendix || |
1326 | !last->appendix->item.is<CompInner_t>())) { | ||
1149 | auto expList = static_cast<ExpList_t*>(last->content.get()); | 1327 | auto expList = static_cast<ExpList_t*>(last->content.get()); |
1150 | auto expListLow = new_ptr<ExpListLow_t>(); | 1328 | auto expListLow = new_ptr<ExpListLow_t>(); |
1151 | expListLow->exprs = expList->exprs; | 1329 | expListLow->exprs = expList->exprs; |
@@ -1182,16 +1360,28 @@ private: | |||
1182 | transformCompReturn(comp, out); | 1360 | transformCompReturn(comp, out); |
1183 | return; | 1361 | return; |
1184 | } | 1362 | } |
1363 | if (auto comp = singleValue->getByPath<SimpleValue_t, TblComprehension_t>()) { | ||
1364 | transformTblCompReturn(comp, out); | ||
1365 | return; | ||
1366 | } | ||
1185 | if (auto classDecl = singleValue->getByPath<SimpleValue_t, ClassDecl_t>()) { | 1367 | if (auto classDecl = singleValue->getByPath<SimpleValue_t, ClassDecl_t>()) { |
1186 | transformClassDecl(classDecl, out, ExpUsage::Return); | 1368 | transformClassDecl(classDecl, out, ExpUsage::Return); |
1187 | return; | 1369 | return; |
1188 | } | 1370 | } |
1371 | if (auto doNode = singleValue->getByPath<SimpleValue_t, Do_t>()) { | ||
1372 | transformDo(doNode, out, true); | ||
1373 | return; | ||
1374 | } | ||
1189 | if (auto chainValue = singleValue->getByPath<ChainValue_t>()) { | 1375 | if (auto chainValue = singleValue->getByPath<ChainValue_t>()) { |
1190 | if (isColonChain(chainValue)) { | 1376 | if (isColonChain(chainValue)) { |
1191 | transformColonChain(chainValue, out, ExpUsage::Return); | 1377 | transformColonChain(chainValue, out, ExpUsage::Return); |
1192 | return; | 1378 | return; |
1193 | } | 1379 | } |
1194 | } | 1380 | } |
1381 | if (auto ifNode = singleValue->getByPath<SimpleValue_t, If_t>()) { | ||
1382 | transformIf(ifNode, out, IfUsage::Return); | ||
1383 | return; | ||
1384 | } | ||
1195 | transformValue(singleValue, out); | 1385 | transformValue(singleValue, out); |
1196 | out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); | 1386 | out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); |
1197 | return; | 1387 | return; |
@@ -1318,12 +1508,6 @@ private: | |||
1318 | } | 1508 | } |
1319 | } | 1509 | } |
1320 | 1510 | ||
1321 | enum class ExpUsage { | ||
1322 | Return, | ||
1323 | Assignment, | ||
1324 | Common | ||
1325 | }; | ||
1326 | |||
1327 | void transformColonChainClosure(ChainValue_t* chainValue, std::vector<std::string>& out) { | 1511 | void transformColonChainClosure(ChainValue_t* chainValue, std::vector<std::string>& out) { |
1328 | std::vector<std::string> temp; | 1512 | std::vector<std::string> temp; |
1329 | temp.push_back(s("(function()"sv) + nll(chainValue)); | 1513 | temp.push_back(s("(function()"sv) + nll(chainValue)); |
@@ -1454,7 +1638,7 @@ private: | |||
1454 | } | 1638 | } |
1455 | 1639 | ||
1456 | void transformSlice(Slice_t* slice, std::vector<std::string>& out) { | 1640 | void transformSlice(Slice_t* slice, std::vector<std::string>& out) { |
1457 | noop(slice, out); | 1641 | throw std::logic_error("Slice syntax not supported here"); |
1458 | } | 1642 | } |
1459 | 1643 | ||
1460 | void transformInvoke(Invoke_t* invoke, std::vector<std::string>& out) { | 1644 | void transformInvoke(Invoke_t* invoke, std::vector<std::string>& out) { |
@@ -1516,14 +1700,14 @@ private: | |||
1516 | std::string len = getUnusedName("_len_"); | 1700 | std::string len = getUnusedName("_len_"); |
1517 | addToScope(accum); | 1701 | addToScope(accum); |
1518 | addToScope(len); | 1702 | addToScope(len); |
1519 | transformExp(comp->value, temp); | ||
1520 | auto compInner = comp->forLoop.get(); | 1703 | auto compInner = comp->forLoop.get(); |
1521 | switch (compInner->compFor->getId()) { | 1704 | switch (compInner->compFor->getId()) { |
1522 | case "CompForEach"_id: | 1705 | case "CompForEach"_id: |
1523 | transformCompForEach( | 1706 | transformCompForEach(compInner->compFor.to<CompForEach_t>(), temp); |
1524 | static_cast<CompForEach_t*>(compInner->compFor.get()), temp); | 1707 | break; |
1708 | case "CompFor"_id: | ||
1709 | transformCompFor(compInner->compFor.to<CompFor_t>(), temp); | ||
1525 | break; | 1710 | break; |
1526 | case "CompFor"_id: transformCompFor(compInner->compFor, temp); break; | ||
1527 | default: break; | 1711 | default: break; |
1528 | } | 1712 | } |
1529 | std::vector<std::string> clauseCodes; | 1713 | std::vector<std::string> clauseCodes; |
@@ -1534,7 +1718,7 @@ private: | |||
1534 | case "CompForEach"_id: | 1718 | case "CompForEach"_id: |
1535 | transformCompForEach(static_cast<CompForEach_t*>(child), clauseCodes); | 1719 | transformCompForEach(static_cast<CompForEach_t*>(child), clauseCodes); |
1536 | break; | 1720 | break; |
1537 | case "CompFor"_id: transformCompFor(child, clauseCodes); break; | 1721 | case "CompFor"_id: transformCompFor(static_cast<CompFor_t*>(child), clauseCodes); break; |
1538 | case "Exp"_id: | 1722 | case "Exp"_id: |
1539 | transformExp(static_cast<Exp_t*>(child), clauseCodes); | 1723 | transformExp(static_cast<Exp_t*>(child), clauseCodes); |
1540 | clauseCodes.back() = indent() + s("if "sv) + clauseCodes.back() + s(" then"sv) + nll(clause); | 1724 | clauseCodes.back() = indent() + s("if "sv) + clauseCodes.back() + s(" then"sv) + nll(clause); |
@@ -1542,6 +1726,11 @@ private: | |||
1542 | default: break; | 1726 | default: break; |
1543 | } | 1727 | } |
1544 | } | 1728 | } |
1729 | pushScope(); | ||
1730 | transformExp(comp->value, temp); | ||
1731 | popScope(); | ||
1732 | auto value = temp.back(); | ||
1733 | temp.pop_back(); | ||
1545 | for (size_t i = 0; i < compInner->clauses.objects().size(); ++i) { | 1734 | for (size_t i = 0; i < compInner->clauses.objects().size(); ++i) { |
1546 | popScope(); | 1735 | popScope(); |
1547 | } | 1736 | } |
@@ -1550,11 +1739,11 @@ private: | |||
1550 | _buf << temp.back(); | 1739 | _buf << temp.back(); |
1551 | pushScope(); | 1740 | pushScope(); |
1552 | if (clauseCodes.empty()) { | 1741 | if (clauseCodes.empty()) { |
1553 | _buf << indent() << accum << "["sv << len << "] = "sv << temp.front() << nll(comp); | 1742 | _buf << indent() << accum << "["sv << len << "] = "sv << value << nll(comp); |
1554 | _buf << indent() << len << " = "sv << len << " + 1"sv << nll(comp); | 1743 | _buf << indent() << len << " = "sv << len << " + 1"sv << nll(comp); |
1555 | } else { | 1744 | } else { |
1556 | _buf << join(clauseCodes); | 1745 | _buf << join(clauseCodes); |
1557 | _buf << indent(int(clauseCodes.size())) << accum << "["sv << len << "] = "sv << temp.front() << nll(comp); | 1746 | _buf << indent(int(clauseCodes.size())) << accum << "["sv << len << "] = "sv << value << nll(comp); |
1558 | _buf << indent(int(clauseCodes.size())) << len << " = "sv << len << " + 1"sv << nll(comp); | 1747 | _buf << indent(int(clauseCodes.size())) << len << " = "sv << len << " + 1"sv << nll(comp); |
1559 | for (int ind = int(clauseCodes.size()) - 1; ind > -1 ; --ind) { | 1748 | for (int ind = int(clauseCodes.size()) - 1; ind > -1 ; --ind) { |
1560 | _buf << indent(ind) << "end"sv << nll(comp); | 1749 | _buf << indent(ind) << "end"sv << nll(comp); |
@@ -1566,14 +1755,15 @@ private: | |||
1566 | out.push_back(clearBuf()); | 1755 | out.push_back(clearBuf()); |
1567 | } | 1756 | } |
1568 | 1757 | ||
1569 | void transformCompInPlace(Comprehension_t* comp, const std::string& expStr, std::vector<std::string>& out) { | 1758 | void transformCompInPlace(Comprehension_t* comp, ExpList_t* expList, std::vector<std::string>& out) { |
1570 | std::vector<std::string> temp; | 1759 | std::vector<std::string> temp; |
1571 | pushScope(); | 1760 | pushScope(); |
1572 | transformComprehension(comp, temp); | 1761 | transformComprehension(comp, temp); |
1762 | transformExpList(expList, temp); | ||
1573 | out.push_back( | 1763 | out.push_back( |
1574 | s("do"sv) + nll(comp) + | 1764 | s("do"sv) + nll(comp) + |
1575 | temp.back() + | 1765 | temp[1] + |
1576 | indent() + expStr + s(" = "sv) + temp.front() + nll(comp)); | 1766 | indent() + temp.back() + s(" = "sv) + temp.front() + nll(comp)); |
1577 | popScope(); | 1767 | popScope(); |
1578 | out.back() = out.back() + indent() + s("end"sv) + nlr(comp); | 1768 | out.back() = out.back() + indent() + s("end"sv) + nlr(comp); |
1579 | } | 1769 | } |
@@ -1599,62 +1789,140 @@ private: | |||
1599 | 1789 | ||
1600 | void transformForEachHead(AssignableNameList_t* nameList, ast_node* loopTarget, std::vector<std::string>& out) { | 1790 | void transformForEachHead(AssignableNameList_t* nameList, ast_node* loopTarget, std::vector<std::string>& out) { |
1601 | std::vector<std::string> temp; | 1791 | std::vector<std::string> temp; |
1602 | transformAssignableNameList(nameList, temp); | 1792 | std::vector<std::string> vars; |
1793 | std::list<std::pair<ast_node*, ast_ptr<ast_node,false,false>>> destructPairs; | ||
1794 | for (auto _item : nameList->items.objects()) { | ||
1795 | auto item = static_cast<NameOrDestructure_t*>(_item)->item.get(); | ||
1796 | switch (item->getId()) { | ||
1797 | case "Variable"_id: | ||
1798 | transformVariable(static_cast<Variable_t*>(item), vars); | ||
1799 | break; | ||
1800 | case "TableLit"_id: { | ||
1801 | auto desVar = getUnusedName("_des_"sv); | ||
1802 | destructPairs.emplace_back(item, toAst<Exp_t>(desVar, Exp)); | ||
1803 | vars.push_back(desVar); | ||
1804 | break; | ||
1805 | } | ||
1806 | default: break; | ||
1807 | } | ||
1808 | } | ||
1603 | switch (loopTarget->getId()) { | 1809 | switch (loopTarget->getId()) { |
1604 | case "star_exp"_id: { | 1810 | case "star_exp"_id: { |
1605 | auto star_exp = static_cast<star_exp_t*>(loopTarget); | 1811 | auto star_exp = static_cast<star_exp_t*>(loopTarget); |
1606 | auto listName = getUnusedName("_list_"); | 1812 | auto listVar = getUnusedName("_list_"); |
1607 | auto indexName = getUnusedName("_index_"); | 1813 | auto indexVar = getUnusedName("_index_"); |
1608 | addToScope(listName); | 1814 | addToScope(listVar); |
1609 | addToScope(indexName); | 1815 | addToScope(indexVar); |
1610 | transformExp(star_exp->value, temp); | 1816 | auto value = singleValueFrom(star_exp->value); |
1611 | _buf << indent() << "local "sv << listName << " = "sv << temp.back() << nll(nameList); | 1817 | if (!value) throw std::logic_error("Invalid star syntax"); |
1612 | _buf << indent() << "for "sv << indexName << " = 1, #"sv << listName << " do"sv << nlr(loopTarget); | 1818 | bool endWithSlice = false; |
1613 | _buf << indent(1) << "local "sv << temp.front() << " = "sv << listName << "["sv << indexName << "]"sv << nll(nameList); | 1819 | do { |
1614 | out.push_back(clearBuf()); | 1820 | auto chainValue = value->item.as<ChainValue_t>(); |
1821 | if (!chainValue) break; | ||
1822 | auto chainList = getChainList(chainValue); | ||
1823 | auto slice = ast_cast<Slice_t>(chainList.back()); | ||
1824 | if (!slice) break; | ||
1825 | endWithSlice = true; | ||
1826 | chainList.pop_back(); | ||
1827 | auto chain = new_ptr<Chain_t>(); | ||
1828 | for (auto item : chainList) { | ||
1829 | chain->items.push_back(item); | ||
1830 | } | ||
1831 | std::string startValue("1"sv); | ||
1832 | if (auto exp = slice->startValue.as<Exp_t>()) { | ||
1833 | transformExp(exp, temp); | ||
1834 | startValue = temp.back(); | ||
1835 | temp.pop_back(); | ||
1836 | } | ||
1837 | std::string stopValue; | ||
1838 | if (auto exp = slice->stopValue.as<Exp_t>()) { | ||
1839 | transformExp(exp, temp); | ||
1840 | stopValue = temp.back(); | ||
1841 | temp.pop_back(); | ||
1842 | } | ||
1843 | std::string stepValue; | ||
1844 | if (auto exp = slice->stepValue.as<Exp_t>()) { | ||
1845 | transformExp(exp, temp); | ||
1846 | stepValue = temp.back(); | ||
1847 | temp.pop_back(); | ||
1848 | } | ||
1849 | transformChain(chain, temp); | ||
1850 | _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); | ||
1851 | std::string maxVar; | ||
1852 | if (!stopValue.empty()) { | ||
1853 | maxVar = getUnusedName("_max_"); | ||
1854 | addToScope(maxVar); | ||
1855 | _buf << indent() << "local "sv << maxVar << " = "sv << stopValue << nll(nameList); | ||
1856 | } | ||
1857 | _buf << indent() << "for "sv << indexVar << " = "sv; | ||
1858 | _buf << startValue << ", "sv; | ||
1859 | if (stopValue.empty()) { | ||
1860 | _buf << "#"sv << listVar; | ||
1861 | } else { | ||
1862 | _buf << maxVar << " < 0 and #"sv << listVar <<" + " << maxVar << " or "sv << maxVar; | ||
1863 | } | ||
1864 | if (!stepValue.empty()) { | ||
1865 | _buf << ", "sv << stepValue; | ||
1866 | } | ||
1867 | _buf << " do"sv << nlr(loopTarget); | ||
1868 | _buf << indent(1) << "local "sv << join(vars, ", "sv) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList); | ||
1869 | out.push_back(clearBuf()); | ||
1870 | } while (false); | ||
1871 | if (!endWithSlice) { | ||
1872 | transformExp(star_exp->value, temp); | ||
1873 | _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); | ||
1874 | _buf << indent() << "for "sv << indexVar << " = 1, #"sv << listVar << " do"sv << nlr(loopTarget); | ||
1875 | _buf << indent(1) << "local "sv << join(vars) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList); | ||
1876 | out.push_back(clearBuf()); | ||
1877 | } | ||
1615 | break; | 1878 | break; |
1616 | } | 1879 | } |
1617 | case "Exp"_id: | 1880 | case "Exp"_id: |
1618 | transformExp(static_cast<Exp_t*>(loopTarget), temp); | 1881 | transformExp(static_cast<Exp_t*>(loopTarget), temp); |
1619 | _buf << indent() << "for "sv << temp.front() << " in "sv << temp.back() << " do"sv << nlr(loopTarget); | 1882 | _buf << indent() << "for "sv << join(vars, ", "sv) << " in "sv << temp.back() << " do"sv << nlr(loopTarget); |
1620 | out.push_back(clearBuf()); | 1883 | out.push_back(clearBuf()); |
1621 | break; | 1884 | break; |
1622 | case "ExpList"_id: | 1885 | case "ExpList"_id: |
1623 | transformExpList(static_cast<ExpList_t*>(loopTarget), temp); | 1886 | transformExpList(static_cast<ExpList_t*>(loopTarget), temp); |
1624 | _buf << indent() << "for "sv << temp.front() << " in "sv << temp.back() << " do"sv << nlr(loopTarget); | 1887 | _buf << indent() << "for "sv << join(vars, ", "sv) << " in "sv << temp.back() << " do"sv << nlr(loopTarget); |
1625 | out.push_back(clearBuf()); | 1888 | out.push_back(clearBuf()); |
1626 | break; | 1889 | break; |
1627 | default: break; | 1890 | default: break; |
1628 | } | 1891 | } |
1892 | if (!destructPairs.empty()) { | ||
1893 | temp.clear(); | ||
1894 | pushScope(); | ||
1895 | for (auto& pair : destructPairs) { | ||
1896 | auto sValue = new_ptr<SimpleValue_t>(); | ||
1897 | sValue->value.set(pair.first); | ||
1898 | auto value = new_ptr<Value_t>(); | ||
1899 | value->item.set(sValue); | ||
1900 | auto exp = new_ptr<Exp_t>(); | ||
1901 | exp->value.set(value); | ||
1902 | auto expList = new_ptr<ExpList_t>(); | ||
1903 | expList->exprs.push_back(exp); | ||
1904 | auto assign = new_ptr<Assign_t>(); | ||
1905 | assign->values.push_back(pair.second); | ||
1906 | auto assignment = new_ptr<Assignment_t>(); | ||
1907 | assignment->assignable.set(expList); | ||
1908 | assignment->target.set(assign); | ||
1909 | transformAssignment(assignment, temp); | ||
1910 | } | ||
1911 | out.back().append(join(temp)); | ||
1912 | popScope(); | ||
1913 | } | ||
1629 | } | 1914 | } |
1630 | 1915 | ||
1631 | void transformCompForEach(CompForEach_t* comp, std::vector<std::string>& out) { | 1916 | void transformCompForEach(CompForEach_t* comp, std::vector<std::string>& out) { |
1632 | transformForEachHead(comp->nameList, comp->loopValue, out); | 1917 | transformForEachHead(comp->nameList, comp->loopValue, out); |
1633 | } | 1918 | } |
1634 | 1919 | ||
1635 | void transformAssignableNameList(AssignableNameList_t* nameList, std::vector<std::string>& out) { | ||
1636 | std::vector<std::string> temp; | ||
1637 | for (auto _item : nameList->items.objects()) { | ||
1638 | auto item = static_cast<NameOrDestructure_t*>(_item)->item.get(); | ||
1639 | switch (item->getId()) { | ||
1640 | case "Variable"_id: | ||
1641 | transformVariable(static_cast<Variable_t*>(item), temp); | ||
1642 | break; | ||
1643 | case "TableLit"_id: | ||
1644 | transformTableLit(static_cast<TableLit_t*>(item), temp); | ||
1645 | break; | ||
1646 | default: break; | ||
1647 | } | ||
1648 | } | ||
1649 | out.push_back(join(temp, ", "sv)); | ||
1650 | } | ||
1651 | |||
1652 | void transformInvokeArgs(InvokeArgs_t* invokeArgs, std::vector<std::string>& out) { | 1920 | void transformInvokeArgs(InvokeArgs_t* invokeArgs, std::vector<std::string>& out) { |
1653 | std::vector<std::string> temp; | 1921 | std::vector<std::string> temp; |
1654 | for (auto arg : invokeArgs->args.objects()) { | 1922 | for (auto arg : invokeArgs->args.objects()) { |
1655 | switch (arg->getId()) { | 1923 | switch (arg->getId()) { |
1656 | case "Exp"_id: transformExp(static_cast<Exp_t*>(arg), temp); break; | 1924 | case "Exp"_id: transformExp(static_cast<Exp_t*>(arg), temp); break; |
1657 | case "TableBlock"_id: transformTableBlock(arg, temp); break; | 1925 | case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(arg), temp); break; |
1658 | default: break; | 1926 | default: break; |
1659 | } | 1927 | } |
1660 | } | 1928 | } |
@@ -1715,7 +1983,7 @@ private: | |||
1715 | popScope(); | 1983 | popScope(); |
1716 | temp.push_back(indent() + s("end"sv) + nlr(forNode) + indent() + s("return "sv) + accum + nlr(forNode)); | 1984 | temp.push_back(indent() + s("end"sv) + nlr(forNode) + indent() + s("return "sv) + accum + nlr(forNode)); |
1717 | popScope(); | 1985 | popScope(); |
1718 | temp.push_back(indent() + s("end)()"sv) + nlr(forNode)); | 1986 | temp.push_back(indent() + s("end)()"sv)); |
1719 | out.push_back(join(temp)); | 1987 | out.push_back(join(temp)); |
1720 | } | 1988 | } |
1721 | 1989 | ||
@@ -1757,7 +2025,8 @@ private: | |||
1757 | } | 2025 | } |
1758 | 2026 | ||
1759 | void transformBinaryOperator(BinaryOperator_t* node, std::vector<std::string>& out) { | 2027 | void transformBinaryOperator(BinaryOperator_t* node, std::vector<std::string>& out) { |
1760 | out.push_back(toString(node)); | 2028 | auto op = toString(node); |
2029 | out.push_back(op == "!="sv ? s("~="sv) : op); | ||
1761 | } | 2030 | } |
1762 | 2031 | ||
1763 | void transformForEach(ForEach_t* forEach, std::vector<std::string>& out) { | 2032 | void transformForEach(ForEach_t* forEach, std::vector<std::string>& out) { |
@@ -1800,7 +2069,7 @@ private: | |||
1800 | popScope(); | 2069 | popScope(); |
1801 | temp.push_back(indent() + s("end"sv) + nlr(forEach) + indent() + s("return "sv) + accum + nlr(forEach)); | 2070 | temp.push_back(indent() + s("end"sv) + nlr(forEach) + indent() + s("return "sv) + accum + nlr(forEach)); |
1802 | popScope(); | 2071 | popScope(); |
1803 | temp.push_back(indent() + s("end)()"sv) + nlr(forEach)); | 2072 | temp.push_back(indent() + s("end)()"sv)); |
1804 | out.push_back(join(temp)); | 2073 | out.push_back(join(temp)); |
1805 | } | 2074 | } |
1806 | 2075 | ||
@@ -1944,18 +2213,6 @@ private: | |||
1944 | out.push_back(join(temp)); | 2213 | out.push_back(join(temp)); |
1945 | } | 2214 | } |
1946 | 2215 | ||
1947 | enum class MemType { | ||
1948 | Builtin, | ||
1949 | Common, | ||
1950 | Property | ||
1951 | }; | ||
1952 | |||
1953 | struct ClassMember { | ||
1954 | std::string item; | ||
1955 | MemType type; | ||
1956 | ast_node* node; | ||
1957 | }; | ||
1958 | |||
1959 | void transformClassDecl(ClassDecl_t* classDecl, std::vector<std::string>& out, ExpUsage usage = ExpUsage::Common, ExpList_t* expList = nullptr) { | 2216 | void transformClassDecl(ClassDecl_t* classDecl, std::vector<std::string>& out, ExpUsage usage = ExpUsage::Common, ExpList_t* expList = nullptr) { |
1960 | std::vector<std::string> temp; | 2217 | std::vector<std::string> temp; |
1961 | auto body = classDecl->body.get(); | 2218 | auto body = classDecl->body.get(); |
@@ -2397,256 +2654,196 @@ private: | |||
2397 | void transform_simple_table(simple_table_t* table, std::vector<std::string>& out) { | 2654 | void transform_simple_table(simple_table_t* table, std::vector<std::string>& out) { |
2398 | std::vector<std::string> temp; | 2655 | std::vector<std::string> temp; |
2399 | pushScope(); | 2656 | pushScope(); |
2400 | for (auto pair : table->pairs.objects()) { | 2657 | const auto& pairs = table->pairs.objects(); |
2658 | for (auto pair : pairs) { | ||
2401 | switch (pair->getId()) { | 2659 | switch (pair->getId()) { |
2402 | case "variable_pair"_id: | 2660 | case "variable_pair"_id: transform_variable_pair(static_cast<variable_pair_t*>(pair), temp); break; |
2403 | transform_variable_pair(static_cast<variable_pair_t*>(pair), temp); | 2661 | case "normal_pair"_id: transform_normal_pair(static_cast<normal_pair_t*>(pair), temp); break; |
2404 | temp.back() = indent() + temp.back() + nll(pair); | 2662 | } |
2663 | temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair); | ||
2664 | } | ||
2665 | popScope(); | ||
2666 | out.push_back(s("{"sv) + nll(table) + join(temp) + s("}"sv)); | ||
2667 | } | ||
2668 | |||
2669 | void transformTblComprehension(TblComprehension_t* comp, std::vector<std::string>& out) { | ||
2670 | std::vector<std::string> kv; | ||
2671 | std::string tbl = getUnusedName("_tbl_"); | ||
2672 | addToScope(tbl); | ||
2673 | std::vector<std::string> temp; | ||
2674 | auto compInner = comp->forLoop.get(); | ||
2675 | switch (compInner->compFor->getId()) { | ||
2676 | case "CompForEach"_id: | ||
2677 | transformCompForEach(compInner->compFor.to<CompForEach_t>(), temp); | ||
2678 | break; | ||
2679 | case "CompFor"_id: | ||
2680 | transformCompFor(compInner->compFor.to<CompFor_t>(), temp); | ||
2681 | break; | ||
2682 | default: break; | ||
2683 | } | ||
2684 | std::vector<std::string> clauseCodes; | ||
2685 | for (auto clause : compInner->clauses.objects()) { | ||
2686 | pushScope(); | ||
2687 | auto child = clause->getFirstChild(); | ||
2688 | switch (child->getId()) { | ||
2689 | case "CompForEach"_id: | ||
2690 | transformCompForEach(static_cast<CompForEach_t*>(child), clauseCodes); | ||
2405 | break; | 2691 | break; |
2406 | case "normal_pair"_id: | 2692 | case "CompFor"_id: |
2407 | transform_normal_pair(static_cast<normal_pair_t*>(pair), temp); | 2693 | transformCompFor(static_cast<CompFor_t*>(child), clauseCodes); |
2408 | temp.back() = indent() + temp.back() + nll(pair); | 2694 | break; |
2695 | case "Exp"_id: | ||
2696 | transformExp(static_cast<Exp_t*>(child), clauseCodes); | ||
2697 | clauseCodes.back() = indent() + s("if "sv) + clauseCodes.back() + s(" then"sv) + nll(clause); | ||
2409 | break; | 2698 | break; |
2699 | default: break; | ||
2700 | } | ||
2701 | } | ||
2702 | pushScope(); | ||
2703 | transformExp(comp->key, kv); | ||
2704 | popScope(); | ||
2705 | if (comp->value) { | ||
2706 | transformExp(comp->value->value, kv); | ||
2707 | } | ||
2708 | for (size_t i = 0; i < compInner->clauses.objects().size(); ++i) { | ||
2709 | popScope(); | ||
2710 | } | ||
2711 | _buf << indent() << "local "sv << tbl << " = { }"sv << nll(comp); | ||
2712 | _buf << temp.back(); | ||
2713 | pushScope(); | ||
2714 | if (!comp->value) { | ||
2715 | auto keyVar = getUnusedName("_key_"); | ||
2716 | auto valVar = getUnusedName("_val_"); | ||
2717 | _buf << indent() << "local "sv << keyVar << ", "sv << valVar << " = "sv << kv.front() << nll(comp); | ||
2718 | kv.front() = keyVar; | ||
2719 | kv.push_back(valVar); | ||
2720 | } | ||
2721 | if (clauseCodes.empty()) { | ||
2722 | _buf << indent() << tbl << "["sv << kv.front() << "] = "sv << kv.back() << nll(comp); | ||
2723 | } else { | ||
2724 | _buf << join(clauseCodes); | ||
2725 | _buf << indent(int(clauseCodes.size())) << tbl << "["sv << kv.front() << "] = "sv << kv.back() << nll(comp); | ||
2726 | for (int ind = int(clauseCodes.size()) - 1; ind > -1 ; --ind) { | ||
2727 | _buf << indent(ind) << "end"sv << nll(comp); | ||
2410 | } | 2728 | } |
2411 | } | 2729 | } |
2412 | popScope(); | 2730 | popScope(); |
2731 | _buf << indent() << "end"sv << nll(comp); | ||
2732 | out.push_back(tbl); | ||
2733 | out.push_back(clearBuf()); | ||
2734 | } | ||
2735 | |||
2736 | void transformTblCompInPlace(TblComprehension_t* comp, ExpList_t* expList, std::vector<std::string>& out) { | ||
2737 | std::vector<std::string> temp; | ||
2738 | pushScope(); | ||
2739 | transformTblComprehension(comp, temp); | ||
2740 | const auto& tbVar = temp.front(); | ||
2741 | const auto& compBody = temp.back(); | ||
2742 | transformExpList(expList, temp); | ||
2743 | const auto& assignLeft = temp.back(); | ||
2744 | out.push_back( | ||
2745 | s("do"sv) + nll(comp) + | ||
2746 | compBody + | ||
2747 | indent() + assignLeft + s(" = "sv) + tbVar + nll(comp)); | ||
2748 | popScope(); | ||
2749 | out.back() = out.back() + indent() + s("end"sv) + nlr(comp); | ||
2750 | } | ||
2751 | |||
2752 | void transformTblCompReturn(TblComprehension_t* comp, std::vector<std::string>& out) { | ||
2753 | std::vector<std::string> temp; | ||
2754 | transformTblComprehension(comp, temp); | ||
2755 | out.push_back(temp.back() + indent() + s("return "sv) + temp.front() + nlr(comp)); | ||
2756 | } | ||
2757 | |||
2758 | void transformTblCompClosure(TblComprehension_t* comp, std::vector<std::string>& out) { | ||
2759 | std::vector<std::string> temp; | ||
2760 | std::string before = s("(function()"sv) + nll(comp); | ||
2761 | pushScope(); | ||
2762 | transformTblComprehension(comp, temp); | ||
2763 | const auto& tbVar = temp.front(); | ||
2764 | const auto& compBody = temp.back(); | ||
2765 | out.push_back( | ||
2766 | before + | ||
2767 | compBody + | ||
2768 | indent() + s("return "sv) + tbVar + nlr(comp)); | ||
2769 | popScope(); | ||
2770 | out.back() = out.back() + indent() + s("end)()"sv); | ||
2771 | } | ||
2772 | |||
2773 | void transformCompFor(CompFor_t* comp, std::vector<std::string>& out) { | ||
2774 | std::vector<std::string> temp; | ||
2775 | std::string varName = toString(comp->varName); | ||
2776 | transformExp(comp->startValue, temp); | ||
2777 | transformExp(comp->stopValue, temp); | ||
2778 | if (comp->stepValue) { | ||
2779 | transformExp(comp->stepValue->value, temp); | ||
2780 | } else { | ||
2781 | temp.emplace_back(); | ||
2782 | } | ||
2783 | _buf << indent() << "for "sv << varName << " = "sv << temp[0] << ", "sv << temp[1] << (temp[2].empty() ? Empty : s(", "sv) + temp[2]) << " do"sv << nll(comp); | ||
2784 | out.push_back(clearBuf()); | ||
2785 | } | ||
2786 | |||
2787 | void transformTableBlock(TableBlock_t* table, std::vector<std::string>& out) { | ||
2788 | std::vector<std::string> temp; | ||
2789 | pushScope(); | ||
2790 | const auto& pairs = table->values.objects(); | ||
2791 | for (auto pair : pairs) { | ||
2792 | switch (pair->getId()) { | ||
2793 | case "Exp"_id: transformExp(static_cast<Exp_t*>(pair), temp); break; | ||
2794 | case "variable_pair"_id: transform_variable_pair(static_cast<variable_pair_t*>(pair), temp); break; | ||
2795 | case "normal_pair"_id: transform_normal_pair(static_cast<normal_pair_t*>(pair), temp); break; | ||
2796 | } | ||
2797 | temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair); | ||
2798 | } | ||
2799 | popScope(); | ||
2413 | out.push_back(s("{"sv) + nll(table) + join(temp) + s("}"sv)); | 2800 | out.push_back(s("{"sv) + nll(table) + join(temp) + s("}"sv)); |
2414 | } | 2801 | } |
2415 | 2802 | ||
2803 | void transformDo(Do_t* doNode, std::vector<std::string>& out, bool implicitReturn = false) { | ||
2804 | std::vector<std::string> temp; | ||
2805 | temp.push_back(indent() + s("do"sv) + nll(doNode)); | ||
2806 | pushScope(); | ||
2807 | transformBody(doNode->body, temp, implicitReturn); | ||
2808 | popScope(); | ||
2809 | temp.push_back(indent() + s("end"sv) + nlr(doNode)); | ||
2810 | out.push_back(join(temp)); | ||
2811 | } | ||
2812 | |||
2813 | void transformDoClosure(Do_t* doNode, std::vector<std::string>& out) { | ||
2814 | std::vector<std::string> temp; | ||
2815 | temp.push_back(s("(function()"sv) + nll(doNode)); | ||
2816 | pushScope(); | ||
2817 | transformBody(doNode->body, temp, true); | ||
2818 | popScope(); | ||
2819 | temp.push_back(indent() + s("end)()"sv)); | ||
2820 | out.push_back(join(temp)); | ||
2821 | } | ||
2822 | |||
2416 | void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);} | 2823 | void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);} |
2417 | void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} | 2824 | void transformImport(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);} | 2825 | void transformWhile(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);} | 2826 | void transformSwitch(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);} | ||
2421 | void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} | 2827 | void transformLocal(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);} | 2828 | void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} |
2423 | void transform_unless_line(ast_node* node, std::vector<std::string>& out) {noop(node, out);} | 2829 | void transform_unless_line(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);} | ||
2425 | void transformTblComprehension(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);} | ||
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);} | ||
2429 | }; | 2830 | }; |
2430 | 2831 | ||
2431 | const std::string MoonCompliler::Empty; | 2832 | const std::string MoonCompliler::Empty; |
2432 | 2833 | ||
2433 | int main() | 2834 | int main() |
2434 | { | 2835 | { |
2435 | std::string s = R"TestCodesHere( | 2836 | std::string s = R"TestCodesHere(a = 1 + do |
2436 | class Hello | 2837 | 123 |
2437 | new: (@test, @world) => | ||
2438 | print "creating object.." | ||
2439 | hello: => | ||
2440 | print @test, @world | ||
2441 | __tostring: => "hello world" | ||
2442 | |||
2443 | x = Hello 1,2 | ||
2444 | x\hello() | ||
2445 | |||
2446 | print x | ||
2447 | |||
2448 | class Simple | ||
2449 | cool: => print "cool" | ||
2450 | |||
2451 | class Yikes extends Simple | ||
2452 | new: => print "created hello" | ||
2453 | |||
2454 | x = Yikes() | ||
2455 | x\cool() | ||
2456 | |||
2457 | |||
2458 | class Hi | ||
2459 | new: (arg) => | ||
2460 | print "init arg", arg | ||
2461 | |||
2462 | cool: (num) => | ||
2463 | print "num", num | ||
2464 | |||
2465 | |||
2466 | class Simple extends Hi | ||
2467 | new: => super "man" | ||
2468 | cool: => super 120302 | ||
2469 | |||
2470 | x = Simple() | ||
2471 | x\cool() | ||
2472 | |||
2473 | print x.__class == Simple | ||
2474 | |||
2475 | |||
2476 | class Okay | ||
2477 | -- what is going on | ||
2478 | something: 20323 | ||
2479 | -- yeaha | ||
2480 | |||
2481 | |||
2482 | class 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 | |||
2489 | class Yeah | ||
2490 | okay: => | ||
2491 | super\something 1,2,3,4 | ||
2492 | |||
2493 | 2838 | ||
2494 | class What | 2839 | a = do |
2495 | something: => print "val:", @val | 2840 | 123 |
2496 | 2841 | ||
2497 | class Hello extends What | 2842 | do |
2498 | val: 2323 | 2843 | 123 |
2499 | something: => super\something | ||
2500 | 2844 | ||
2501 | with Hello! | 2845 | do |
2502 | x = \something! | 2846 | 123)TestCodesHere"; |
2503 | print x | ||
2504 | x! | ||
2505 | |||
2506 | class 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 | ||
2519 | x = @hello | ||
2520 | x = @@hello | ||
2521 | |||
2522 | @hello "world" | ||
2523 | @@hello "world" | ||
2524 | |||
2525 | @@one @@two(4,5) @three, @four | ||
2526 | |||
2527 | xx = (@hello, @@world, cool) -> | ||
2528 | |||
2529 | |||
2530 | -- class properties | ||
2531 | class ClassMan | ||
2532 | @yeah: 343 | ||
2533 | blue: => | ||
2534 | @hello: 3434, @world: 23423 | ||
2535 | green: => | ||
2536 | @red: => | ||
2537 | |||
2538 | |||
2539 | x = @ | ||
2540 | y = @@ | ||
2541 | |||
2542 | @ something | ||
2543 | |||
2544 | @@ something | ||
2545 | |||
2546 | @ = @ + @ / @ | ||
2547 | |||
2548 | @ = 343 | ||
2549 | @.hello 2,3,4 | ||
2550 | |||
2551 | hello[@].world | ||
2552 | |||
2553 | |||
2554 | class 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 | |||
2565 | print "hello" | ||
2566 | |||
2567 | yyy = -> | ||
2568 | class Cool | ||
2569 | nil | ||
2570 | |||
2571 | |||
2572 | -- | ||
2573 | |||
2574 | class a.b.c.D | ||
2575 | nil | ||
2576 | |||
2577 | |||
2578 | class a.b["hello"] | ||
2579 | nil | ||
2580 | |||
2581 | class (-> require "moon")!.Something extends Hello.World | ||
2582 | nil | ||
2583 | |||
2584 | -- | ||
2585 | |||
2586 | a = class | ||
2587 | b = class Something | ||
2588 | c = class Something extends Hello | ||
2589 | d = class extends World | ||
2590 | |||
2591 | print (class WhatsUp).__name | ||
2592 | |||
2593 | -- | ||
2594 | |||
2595 | export ^ | ||
2596 | class Something | ||
2597 | nil | ||
2598 | |||
2599 | |||
2600 | -- | ||
2601 | |||
2602 | -- hoisting | ||
2603 | class Something | ||
2604 | val = 23 | ||
2605 | {:insert} = table | ||
2606 | new: => print insert, val -- prints nil 23 | ||
2607 | |||
2608 | -- | ||
2609 | |||
2610 | class X | ||
2611 | new: hi | ||
2612 | |||
2613 | |||
2614 | -- | ||
2615 | |||
2616 | class Cool extends Thing | ||
2617 | dang: => | ||
2618 | { | ||
2619 | hello: -> super! | ||
2620 | world: -> super.one | ||
2621 | } | ||
2622 | |||
2623 | -- | ||
2624 | |||
2625 | class Whack extends Thing | ||
2626 | dang: do_something => | ||
2627 | super! | ||
2628 | |||
2629 | --- | ||
2630 | |||
2631 | class 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 | |||
2647 | nil | ||
2648 | )TestCodesHere"; | ||
2649 | MoonCompliler{}.complile(s); | 2847 | MoonCompliler{}.complile(s); |
2650 | |||
2651 | return 0; | 2848 | return 0; |
2652 | } | 2849 | } |
diff --git a/MoonParser/moon_ast.h b/MoonParser/moon_ast.h index 5d38905..4f6dc92 100644 --- a/MoonParser/moon_ast.h +++ b/MoonParser/moon_ast.h | |||
@@ -151,25 +151,14 @@ AST_NODE(IfCond, "IfCond"_id) | |||
151 | ast_ptr<Assign_t, true> assign; | 151 | ast_ptr<Assign_t, true> assign; |
152 | AST_END(IfCond) | 152 | AST_END(IfCond) |
153 | 153 | ||
154 | AST_NODE(IfElseIf, "IfElseIf"_id) | ||
155 | ast_ptr<IfCond_t> condition; | ||
156 | ast_ptr<Body_t> body; | ||
157 | AST_END(IfElseIf) | ||
158 | |||
159 | AST_NODE(If, "If"_id) | 154 | AST_NODE(If, "If"_id) |
160 | ast_ptr<IfCond_t> firstCondition; | ||
161 | ast_ptr<Body_t> firstBody; | ||
162 | ast_ptr<Seperator_t> sep; | 155 | ast_ptr<Seperator_t> sep; |
163 | ast_list<IfElseIf_t> branches; | 156 | ast_sel_list<IfCond_t, Body_t> nodes; |
164 | ast_ptr<Body_t, true> lastBranch; | ||
165 | AST_END(If) | 157 | AST_END(If) |
166 | 158 | ||
167 | AST_NODE(Unless, "Unless"_id) | 159 | AST_NODE(Unless, "Unless"_id) |
168 | ast_ptr<IfCond_t> firstCondition; | ||
169 | ast_ptr<Body_t> firstBody; | ||
170 | ast_ptr<Seperator_t> sep; | 160 | ast_ptr<Seperator_t> sep; |
171 | ast_list<IfElseIf_t> branches; | 161 | ast_sel_list<IfCond_t, Body_t> nodes; |
172 | ast_ptr<Body_t, true> lastBranch; | ||
173 | AST_END(Unless) | 162 | AST_END(Unless) |
174 | 163 | ||
175 | AST_NODE(While, "While"_id) | 164 | AST_NODE(While, "While"_id) |
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp index 116c9de..99cf1a1 100644 --- a/MoonParser/moon_parser.cpp +++ b/MoonParser/moon_parser.cpp | |||
@@ -162,8 +162,8 @@ rule Switch = key("switch") >> | |||
162 | rule IfCond = Exp >> -Assign; | 162 | rule IfCond = Exp >> -Assign; |
163 | rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; | 163 | rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; |
164 | rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; | 164 | rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; |
165 | rule If = key("if") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; | 165 | rule If = key("if") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; |
166 | rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; | 166 | rule Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; |
167 | 167 | ||
168 | rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; | 168 | rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; |
169 | 169 | ||