diff options
| author | Li Jin <dragon-fly@qq.com> | 2021-02-10 23:36:22 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2021-02-10 23:36:22 +0800 |
| commit | c3a389e2f9f53fb3e3e70a325bf42c8ce02a0b82 (patch) | |
| tree | 6d3cf006c85728e16546d74afabb89960a838490 /src | |
| parent | 90e5ee7ee432f558b3c55d79fba1fcb2a8ce502f (diff) | |
| download | yuescript-c3a389e2f9f53fb3e3e70a325bf42c8ce02a0b82.tar.gz yuescript-c3a389e2f9f53fb3e3e70a325bf42c8ce02a0b82.tar.bz2 yuescript-c3a389e2f9f53fb3e3e70a325bf42c8ce02a0b82.zip | |
fix local statement used with line decorator issue.
Diffstat (limited to 'src')
| -rw-r--r-- | src/MoonP/moon_ast.h | 2 | ||||
| -rw-r--r-- | src/MoonP/moon_compiler.cpp | 87 |
2 files changed, 62 insertions, 27 deletions
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index 2f5123b..e2f54de 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h | |||
| @@ -110,6 +110,8 @@ AST_NODE(Local) | |||
| 110 | ast_sel<true, local_flag_t, local_values_t> item; | 110 | ast_sel<true, local_flag_t, local_values_t> item; |
| 111 | std::list<std::string> forceDecls; | 111 | std::list<std::string> forceDecls; |
| 112 | std::list<std::string> decls; | 112 | std::list<std::string> decls; |
| 113 | bool collected = false; | ||
| 114 | bool defined = false; | ||
| 113 | AST_MEMBER(Local, &item) | 115 | AST_MEMBER(Local, &item) |
| 114 | AST_END(Local) | 116 | AST_END(Local) |
| 115 | 117 | ||
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 2ed153e..6b721f1 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
| @@ -53,7 +53,7 @@ inline std::string s(std::string_view sv) { | |||
| 53 | return std::string(sv); | 53 | return std::string(sv); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | const std::string_view version = "0.6.1"sv; | 56 | const std::string_view version = "0.6.2"sv; |
| 57 | const std::string_view extension = "mp"sv; | 57 | const std::string_view extension = "mp"sv; |
| 58 | 58 | ||
| 59 | class MoonCompilerImpl { | 59 | class MoonCompilerImpl { |
| @@ -516,18 +516,29 @@ private: | |||
| 516 | return nullptr; | 516 | return nullptr; |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | Statement_t* lastStatementFrom(const node_container& stmts) const { | ||
| 520 | if (!stmts.empty()) { | ||
| 521 | auto it = stmts.end(); --it; | ||
| 522 | while (!static_cast<Statement_t*>(*it)->content && it != stmts.begin()) { | ||
| 523 | --it; | ||
| 524 | } | ||
| 525 | return static_cast<Statement_t*>(*it); | ||
| 526 | } | ||
| 527 | return nullptr; | ||
| 528 | } | ||
| 529 | |||
| 519 | Statement_t* lastStatementFrom(Body_t* body) const { | 530 | Statement_t* lastStatementFrom(Body_t* body) const { |
| 520 | if (auto stmt = body->content.as<Statement_t>()) { | 531 | if (auto stmt = body->content.as<Statement_t>()) { |
| 521 | return stmt; | 532 | return stmt; |
| 522 | } else { | 533 | } else { |
| 523 | const auto& stmts = body->content.to<Block_t>()->statements.objects(); | 534 | const auto& stmts = body->content.to<Block_t>()->statements.objects(); |
| 524 | return stmts.empty() ? nullptr : static_cast<Statement_t*>(stmts.back()); | 535 | return lastStatementFrom(stmts); |
| 525 | } | 536 | } |
| 526 | } | 537 | } |
| 527 | 538 | ||
| 528 | Statement_t* lastStatementFrom(Block_t* block) const { | 539 | Statement_t* lastStatementFrom(Block_t* block) const { |
| 529 | const auto& stmts = block->statements.objects(); | 540 | const auto& stmts = block->statements.objects(); |
| 530 | return stmts.empty() ? nullptr : static_cast<Statement_t*>(stmts.back()); | 541 | return lastStatementFrom(stmts); |
| 531 | } | 542 | } |
| 532 | 543 | ||
| 533 | Exp_t* lastExpFromAssign(ast_node* action) { | 544 | Exp_t* lastExpFromAssign(ast_node* action) { |
| @@ -773,6 +784,11 @@ private: | |||
| 773 | if (auto assignment = assignmentFrom(statement)) { | 784 | if (auto assignment = assignmentFrom(statement)) { |
| 774 | auto preDefine = getPredefine(assignment); | 785 | auto preDefine = getPredefine(assignment); |
| 775 | if (!preDefine.empty()) out.push_back(preDefine + nll(statement)); | 786 | if (!preDefine.empty()) out.push_back(preDefine + nll(statement)); |
| 787 | } else if (auto local = statement->content.as<Local_t>()) { | ||
| 788 | if (!local->defined) { | ||
| 789 | local->defined = true; | ||
| 790 | transformLocalDef(local, out); | ||
| 791 | } | ||
| 776 | } | 792 | } |
| 777 | auto appendix = statement->appendix.get(); | 793 | auto appendix = statement->appendix.get(); |
| 778 | switch (appendix->item->getId()) { | 794 | switch (appendix->item->getId()) { |
| @@ -2009,6 +2025,13 @@ private: | |||
| 2009 | BREAK_IF(it == nodes.begin()); | 2025 | BREAK_IF(it == nodes.begin()); |
| 2010 | auto last = it; --last; | 2026 | auto last = it; --last; |
| 2011 | auto lst = static_cast<Statement_t*>(*last); | 2027 | auto lst = static_cast<Statement_t*>(*last); |
| 2028 | if (lst->appendix) { | ||
| 2029 | throw std::logic_error(_info.errorMessage("statement decorator must be placed at the end of backcall chain"sv, lst->appendix.get())); | ||
| 2030 | } | ||
| 2031 | lst->appendix.set(stmt->appendix); | ||
| 2032 | stmt->appendix.set(nullptr); | ||
| 2033 | lst->needSep.set(stmt->needSep); | ||
| 2034 | stmt->needSep.set(nullptr); | ||
| 2012 | auto exp = lastExpFromStatement(lst); | 2035 | auto exp = lastExpFromStatement(lst); |
| 2013 | BREAK_IF(!exp); | 2036 | BREAK_IF(!exp); |
| 2014 | for (auto val : backcallBody->values.objects()) { | 2037 | for (auto val : backcallBody->values.objects()) { |
| @@ -2104,27 +2127,30 @@ private: | |||
| 2104 | return; | 2127 | return; |
| 2105 | } | 2128 | } |
| 2106 | if (auto local = stmt->content.as<Local_t>()) { | 2129 | if (auto local = stmt->content.as<Local_t>()) { |
| 2107 | switch (local->item->getId()) { | 2130 | if (!local->collected) { |
| 2108 | case id<local_flag_t>(): { | 2131 | local->collected = true; |
| 2109 | auto flag = local->item.to<local_flag_t>(); | 2132 | switch (local->item->getId()) { |
| 2110 | LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; | 2133 | case id<local_flag_t>(): { |
| 2111 | if (int(newMode) > int(mode)) { | 2134 | auto flag = local->item.to<local_flag_t>(); |
| 2112 | mode = newMode; | 2135 | LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; |
| 2113 | } | 2136 | if (int(newMode) > int(mode)) { |
| 2114 | if (mode == LocalMode::Any) { | 2137 | mode = newMode; |
| 2115 | if (!any) any = local; | 2138 | } |
| 2116 | if (!capital) capital = local; | 2139 | if (mode == LocalMode::Any) { |
| 2117 | } else { | 2140 | if (!any) any = local; |
| 2118 | if (!capital) capital = local; | 2141 | if (!capital) capital = local; |
| 2142 | } else { | ||
| 2143 | if (!capital) capital = local; | ||
| 2144 | } | ||
| 2145 | break; | ||
| 2119 | } | 2146 | } |
| 2120 | break; | 2147 | case id<local_values_t>(): { |
| 2121 | } | 2148 | auto values = local->item.to<local_values_t>(); |
| 2122 | case id<local_values_t>(): { | 2149 | for (auto name : values->nameList->names.objects()) { |
| 2123 | auto values = local->item.to<local_values_t>(); | 2150 | local->forceDecls.push_back(_parser.toString(name)); |
| 2124 | for (auto name : values->nameList->names.objects()) { | 2151 | } |
| 2125 | local->forceDecls.push_back(_parser.toString(name)); | 2152 | break; |
| 2126 | } | 2153 | } |
| 2127 | break; | ||
| 2128 | } | 2154 | } |
| 2129 | } | 2155 | } |
| 2130 | } else if (mode != LocalMode::None) { | 2156 | } else if (mode != LocalMode::None) { |
| @@ -2194,8 +2220,8 @@ private: | |||
| 2194 | case ExpUsage::Return: { | 2220 | case ExpUsage::Return: { |
| 2195 | BLOCK_START | 2221 | BLOCK_START |
| 2196 | BREAK_IF(isRoot && !_info.moduleName.empty()); | 2222 | BREAK_IF(isRoot && !_info.moduleName.empty()); |
| 2197 | BREAK_IF(nodes.empty()); | 2223 | auto last = lastStatementFrom(nodes); |
| 2198 | auto last = static_cast<Statement_t*>(nodes.back()); | 2224 | BREAK_IF(!last); |
| 2199 | auto x = last; | 2225 | auto x = last; |
| 2200 | auto expList = expListFrom(last); | 2226 | auto expList = expListFrom(last); |
| 2201 | BREAK_IF(!expList || | 2227 | BREAK_IF(!expList || |
| @@ -5434,8 +5460,7 @@ private: | |||
| 5434 | out.push_back(join(temp)); | 5460 | out.push_back(join(temp)); |
| 5435 | } | 5461 | } |
| 5436 | 5462 | ||
| 5437 | void transformLocal(Local_t* local, str_list& out) { | 5463 | void transformLocalDef(Local_t* local, str_list& out) { |
| 5438 | str_list temp; | ||
| 5439 | if (!local->forceDecls.empty() || !local->decls.empty()) { | 5464 | if (!local->forceDecls.empty() || !local->decls.empty()) { |
| 5440 | str_list defs; | 5465 | str_list defs; |
| 5441 | for (const auto& decl : local->forceDecls) { | 5466 | for (const auto& decl : local->forceDecls) { |
| @@ -5449,9 +5474,17 @@ private: | |||
| 5449 | } | 5474 | } |
| 5450 | auto preDefine = getPredefine(defs); | 5475 | auto preDefine = getPredefine(defs); |
| 5451 | if (!preDefine.empty()) { | 5476 | if (!preDefine.empty()) { |
| 5452 | temp.push_back(preDefine + nll(local)); | 5477 | out.push_back(preDefine + nll(local)); |
| 5453 | } | 5478 | } |
| 5454 | } | 5479 | } |
| 5480 | } | ||
| 5481 | |||
| 5482 | void transformLocal(Local_t* local, str_list& out) { | ||
| 5483 | str_list temp; | ||
| 5484 | if (!local->defined) { | ||
| 5485 | local->defined = true; | ||
| 5486 | transformLocalDef(local, temp); | ||
| 5487 | } | ||
| 5455 | if (auto values = local->item.as<local_values_t>()) { | 5488 | if (auto values = local->item.as<local_values_t>()) { |
| 5456 | if (values->valueList) { | 5489 | if (values->valueList) { |
| 5457 | auto x = local; | 5490 | auto x = local; |
