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 | ||
