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