aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MoonParser/ast.hpp46
-rw-r--r--MoonParser/moon_ast.cpp1089
-rw-r--r--MoonParser/moon_ast.h15
-rw-r--r--MoonParser/moon_parser.cpp4
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)
45AST_IMPL(SwitchCase) 45AST_IMPL(SwitchCase)
46AST_IMPL(Switch) 46AST_IMPL(Switch)
47AST_IMPL(IfCond) 47AST_IMPL(IfCond)
48AST_IMPL(IfElseIf)
49AST_IMPL(If) 48AST_IMPL(If)
50AST_IMPL(Unless) 49AST_IMPL(Unless)
51AST_IMPL(While) 50AST_IMPL(While)
@@ -121,11 +120,6 @@ AST_IMPL(BlockEnd)
121 120
122#include <iostream> 121#include <iostream>
123 122
124template<class T, class... Args>
125inline std::unique_ptr<T> MakeUnique(Args&&... args) {
126 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
127}
128
129inline std::string s(std::string_view sv) { 123inline 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
2431const std::string MoonCompliler::Empty; 2832const std::string MoonCompliler::Empty;
2432 2833
2433int main() 2834int main()
2434{ 2835{
2435 std::string s = R"TestCodesHere( 2836 std::string s = R"TestCodesHere(a = 1 + do
2436class Hello 2837 123
2437 new: (@test, @world) =>
2438 print "creating object.."
2439 hello: =>
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 2838
2494class What 2839a = do
2495 something: => print "val:", @val 2840 123
2496 2841
2497class Hello extends What 2842do
2498 val: 2323 2843 123
2499 something: => super\something
2500 2844
2501with Hello! 2845do
2502 x = \something! 2846 123)TestCodesHere";
2503 print x
2504 x!
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";
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;
152AST_END(IfCond) 152AST_END(IfCond)
153 153
154AST_NODE(IfElseIf, "IfElseIf"_id)
155 ast_ptr<IfCond_t> condition;
156 ast_ptr<Body_t> body;
157AST_END(IfElseIf)
158
159AST_NODE(If, "If"_id) 154AST_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;
165AST_END(If) 157AST_END(If)
166 158
167AST_NODE(Unless, "Unless"_id) 159AST_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;
173AST_END(Unless) 162AST_END(Unless)
174 163
175AST_NODE(While, "While"_id) 164AST_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") >>
162rule IfCond = Exp >> -Assign; 162rule IfCond = Exp >> -Assign;
163rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; 163rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body;
164rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; 164rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body;
165rule If = key("if") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; 165rule If = key("if") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
166rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; 166rule Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
167 167
168rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; 168rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body;
169 169