aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdoc/docs/doc/README.md43
-rwxr-xr-xdoc/docs/zh/doc/README.md51
-rw-r--r--spec/inputs/test/format_spec.yue2
-rw-r--r--spec/outputs/test/format_spec.lua2
-rw-r--r--src/yuescript/yue_ast.cpp64
-rw-r--r--src/yuescript/yue_ast.h21
-rw-r--r--src/yuescript/yue_compiler.cpp884
-rw-r--r--src/yuescript/yue_parser.cpp49
-rw-r--r--src/yuescript/yue_parser.h6
-rw-r--r--src/yuescript/yuescript.cpp22
10 files changed, 635 insertions, 509 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md
index 07e35e7..11c9427 100755
--- a/doc/docs/doc/README.md
+++ b/doc/docs/doc/README.md
@@ -4729,7 +4729,7 @@ Converts the code to the AST.
4729 4729
4730**Signature:** 4730**Signature:**
4731```lua 4731```lua
4732to_ast: function(code: string, flattenLevel?: number, astName?: string): 4732to_ast: function(code: string, flattenLevel?: number, astName?: string, reserveComment?: boolean):
4733 --[[AST]] AST | nil, 4733 --[[AST]] AST | nil,
4734 --[[error]] nil | string 4734 --[[error]] nil | string
4735``` 4735```
@@ -4741,6 +4741,7 @@ to_ast: function(code: string, flattenLevel?: number, astName?: string):
4741| code | string | The code. | 4741| code | string | The code. |
4742| flattenLevel | integer | [Optional] The flatten level. Higher level means more flattening. Default is 0. Maximum is 2. | 4742| flattenLevel | integer | [Optional] The flatten level. Higher level means more flattening. Default is 0. Maximum is 2. |
4743| astName | string | [Optional] The AST name. Default is "File". | 4743| astName | string | [Optional] The AST name. Default is "File". |
4744| reserveComment | boolean | [Optional] Whether to reserve the original comments. Default is false. |
4744 4745
4745**Returns:** 4746**Returns:**
4746 4747
@@ -4749,6 +4750,33 @@ to_ast: function(code: string, flattenLevel?: number, astName?: string):
4749| AST \| nil | The AST, or nil if the conversion failed. | 4750| AST \| nil | The AST, or nil if the conversion failed. |
4750| string \| nil | The error message, or nil if the conversion succeeded. | 4751| string \| nil | The error message, or nil if the conversion succeeded. |
4751 4752
4753#### format
4754
4755**Type:** Function.
4756
4757**Description:**
4758
4759Formats the YueScript code.
4760
4761**Signature:**
4762```lua
4763format: function(code: string, tabSize?: number, reserveComment?: boolean): string
4764```
4765
4766**Parameters:**
4767
4768| Parameter | Type | Description |
4769| --- | --- | --- |
4770| code | string | The code. |
4771| tabSize | integer | [Optional] The tab size. Default is 4. |
4772| reserveComment | boolean | [Optional] Whether to reserve the original comments. Default is true. |
4773
4774**Returns:**
4775
4776| Return Type | Description |
4777| --- | --- |
4778| string | The formatted code. |
4779
4752#### __call 4780#### __call
4753 4781
4754**Type:** Metamethod. 4782**Type:** Metamethod.
@@ -4820,6 +4848,19 @@ Whether the compiler should reserve the original line number in the compiled cod
4820reserve_line_number: boolean 4848reserve_line_number: boolean
4821``` 4849```
4822 4850
4851#### reserve_comment
4852
4853**Type:** Field.
4854
4855**Description:**
4856
4857Whether the compiler should reserve the original comments in the compiled code.
4858
4859**Signature:**
4860```lua
4861reserve_comment: boolean
4862```
4863
4823#### space_over_tab 4864#### space_over_tab
4824 4865
4825**Type:** Field. 4866**Type:** Field.
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md
index afef94e..da69e22 100755
--- a/doc/docs/zh/doc/README.md
+++ b/doc/docs/zh/doc/README.md
@@ -4686,7 +4686,7 @@ type AST = {string, integer, integer, any}
4686 4686
4687**签名:** 4687**签名:**
4688```lua 4688```lua
4689to_ast: function(code: string, flattenLevel?: number, astName?: string): 4689to_ast: function(code: string, flattenLevel?: number, astName?: string, reserveComment?: boolean):
4690 --[[AST]] AST | nil, 4690 --[[AST]] AST | nil,
4691 --[[error]] nil | string 4691 --[[error]] nil | string
4692``` 4692```
@@ -4697,6 +4697,42 @@ to_ast: function(code: string, flattenLevel?: number, astName?: string):
4697| --- | --- | --- | 4697| --- | --- | --- |
4698| code | string | 代码。 | 4698| code | string | 代码。 |
4699| flattenLevel | integer | [可选] 扁平化级别。级别越高,会消除更多的 AST 结构的嵌套。默认为 0。最大为 2。 | 4699| flattenLevel | integer | [可选] 扁平化级别。级别越高,会消除更多的 AST 结构的嵌套。默认为 0。最大为 2。 |
4700| astName | string | [可选] AST 名称。默认为 "File"。 |
4701| reserveComment | boolean | [可选] 是否保留原始注释。默认为 false。 |
4702
4703**返回值:**
4704
4705| 返回类型 | 描述 |
4706| --- | --- |
4707| AST \| nil | AST,如果转换失败则为 nil。 |
4708| string \| nil | 错误消息,如果转换成功则为 nil。 |
4709
4710#### format
4711
4712**类型:** 函数。
4713
4714**描述:**
4715
4716格式化 YueScript 代码。
4717
4718**签名:**
4719```lua
4720format: function(code: string, tabSize?: number, reserveComment?: boolean): string
4721```
4722
4723**参数:**
4724
4725| 参数名 | 类型 | 描述 |
4726| --- | --- | --- |
4727| code | string | 代码。 |
4728| tabSize | integer | [可选] 制表符大小。默认为 4。 |
4729| reserveComment | boolean | [可选] 是否保留原始注释。默认为 true。 |
4730
4731**返回值:**
4732
4733| 返回类型 | 描述 |
4734| --- | --- |
4735| string | 格式化后的代码。 |
4700 4736
4701#### __call 4737#### __call
4702 4738
@@ -4769,6 +4805,19 @@ implicit_return_root: boolean
4769reserve_line_number: boolean 4805reserve_line_number: boolean
4770``` 4806```
4771 4807
4808#### reserve_comment
4809
4810**类型:** 成员变量。
4811
4812**描述:**
4813
4814编译器是否应该在编译后的代码中保留原始注释。
4815
4816**签名:**
4817```lua
4818reserve_comment: boolean
4819```
4820
4772#### space_over_tab 4821#### space_over_tab
4773 4822
4774**类型:** 成员变量。 4823**类型:** 成员变量。
diff --git a/spec/inputs/test/format_spec.yue b/spec/inputs/test/format_spec.yue
index cbd9d22..3ad2c7f 100644
--- a/spec/inputs/test/format_spec.yue
+++ b/spec/inputs/test/format_spec.yue
@@ -119,7 +119,7 @@ for file in *files
119 original_ast = yue.to_ast code 119 original_ast = yue.to_ast code
120 assert.is_not_nil original_ast 120 assert.is_not_nil original_ast
121 rewriteLineCol original_ast 121 rewriteLineCol original_ast
122 formated = yue.format code 122 formated = yue.format code, 0, false
123 ast = yue.to_ast formated 123 ast = yue.to_ast formated
124 assert.is_not_nil ast 124 assert.is_not_nil ast
125 rewriteLineCol ast 125 rewriteLineCol ast
diff --git a/spec/outputs/test/format_spec.lua b/spec/outputs/test/format_spec.lua
index ed0fbee..7aa85cd 100644
--- a/spec/outputs/test/format_spec.lua
+++ b/spec/outputs/test/format_spec.lua
@@ -122,7 +122,7 @@ return describe("format", function()
122 local original_ast = yue.to_ast(code) 122 local original_ast = yue.to_ast(code)
123 assert.is_not_nil(original_ast) 123 assert.is_not_nil(original_ast)
124 rewriteLineCol(original_ast) 124 rewriteLineCol(original_ast)
125 local formated = yue.format(code) 125 local formated = yue.format(code, 0, false)
126 local ast = yue.to_ast(formated) 126 local ast = yue.to_ast(formated)
127 assert.is_not_nil(ast) 127 assert.is_not_nil(ast)
128 rewriteLineCol(ast) 128 rewriteLineCol(ast)
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp
index 278d992..7574b06 100644
--- a/src/yuescript/yue_ast.cpp
+++ b/src/yuescript/yue_ast.cpp
@@ -203,9 +203,16 @@ std::string YueLineComment_t::to_string(void* ud) const {
203 auto info = reinterpret_cast<YueFormat*>(ud); 203 auto info = reinterpret_cast<YueFormat*>(ud);
204 return "--"s + info->convert(this); 204 return "--"s + info->convert(this);
205} 205}
206std::string MultilineCommentInner_t::to_string(void* ud) const { 206std::string YueMultilineComment_t::to_string(void* ud) const {
207 auto info = reinterpret_cast<YueFormat*>(ud); 207 auto info = reinterpret_cast<YueFormat*>(ud);
208 return info->convert(this); 208 return "--[["s + info->convert(this) + "]]"s;
209}
210std::string YueComment_t::to_string(void* ud) const {
211 if (comment) {
212 return comment->to_string(ud);
213 } else {
214 return {};
215 }
209} 216}
210std::string Variable_t::to_string(void* ud) const { 217std::string Variable_t::to_string(void* ud) const {
211 return name->to_string(ud); 218 return name->to_string(ud);
@@ -1596,38 +1603,15 @@ std::string StatementAppendix_t::to_string(void* ud) const {
1596 return item->to_string(ud); 1603 return item->to_string(ud);
1597} 1604}
1598std::string Statement_t::to_string(void* ud) const { 1605std::string Statement_t::to_string(void* ud) const {
1599 std::string line; 1606 if (appendix) {
1600 if (!comments.empty()) { 1607 return content->to_string(ud) + ' ' + appendix->to_string(ud);
1601 auto info = reinterpret_cast<YueFormat*>(ud);
1602 str_list temp;
1603 for (ast_node* comment : comments.objects()) {
1604 if (comment == comments.front()) {
1605 temp.push_back(comment->to_string(ud));
1606 } else {
1607 temp.push_back(info->ind() + comment->to_string(ud));
1608 }
1609 }
1610 if (appendix) {
1611 temp.push_back(info->ind() + content->to_string(ud) + ' ' + appendix->to_string(ud));
1612 return join(temp, "\n"sv);
1613 } else {
1614 temp.push_back(info->ind() + content->to_string(ud));
1615 return join(temp, "\n"sv);
1616 }
1617 } else { 1608 } else {
1618 if (appendix) { 1609 return content->to_string(ud);
1619 return content->to_string(ud) + ' ' + appendix->to_string(ud);
1620 } else {
1621 return content->to_string(ud);
1622 }
1623 } 1610 }
1624} 1611}
1625std::string StatementSep_t::to_string(void*) const { 1612std::string StatementSep_t::to_string(void*) const {
1626 return {}; 1613 return {};
1627} 1614}
1628std::string YueMultilineComment_t::to_string(void* ud) const {
1629 return "--[["s + inner->to_string(ud) + "]]"s;
1630}
1631std::string ChainAssign_t::to_string(void* ud) const { 1615std::string ChainAssign_t::to_string(void* ud) const {
1632 str_list temp; 1616 str_list temp;
1633 for (auto exp : exprs.objects()) { 1617 for (auto exp : exprs.objects()) {
@@ -1641,14 +1625,22 @@ std::string Body_t::to_string(void* ud) const {
1641std::string Block_t::to_string(void* ud) const { 1625std::string Block_t::to_string(void* ud) const {
1642 auto info = reinterpret_cast<YueFormat*>(ud); 1626 auto info = reinterpret_cast<YueFormat*>(ud);
1643 str_list temp; 1627 str_list temp;
1644 for (auto stmt_ : statements.objects()) { 1628 for (auto stmt_ : statementOrComments.objects()) {
1645 auto stmt = static_cast<Statement_t*>(stmt_); 1629 if (auto stmt = ast_cast<Statement_t>(stmt_)) {
1646 if (stmt->content.is<PipeBody_t>()) { 1630 if (stmt->content.is<PipeBody_t>()) {
1647 info->pushScope(); 1631 info->pushScope();
1648 temp.emplace_back(stmt->to_string(ud)); 1632 temp.emplace_back(stmt->to_string(ud));
1649 info->popScope(); 1633 info->popScope();
1650 } else { 1634 } else {
1651 temp.emplace_back(info->ind() + stmt->to_string(ud)); 1635 temp.emplace_back(info->ind() + stmt->to_string(ud));
1636 }
1637 } else if (info->reserveComment) {
1638 auto comment = ast_to<YueComment_t>(stmt_);
1639 if (comment->comment) {
1640 temp.emplace_back(info->ind() + comment->to_string(ud));
1641 } else {
1642 temp.emplace_back(comment->to_string(ud));
1643 }
1652 } 1644 }
1653 } 1645 }
1654 return join(temp, "\n"sv); 1646 return join(temp, "\n"sv);
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index 3aca702..df852bd 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -929,14 +929,14 @@ AST_END(StatementSep)
929AST_LEAF(YueLineComment) 929AST_LEAF(YueLineComment)
930AST_END(YueLineComment) 930AST_END(YueLineComment)
931 931
932AST_LEAF(MultilineCommentInner) 932AST_LEAF(YueMultilineComment)
933AST_END(MultilineCommentInner)
934
935AST_NODE(YueMultilineComment)
936 ast_ptr<true, MultilineCommentInner_t> inner;
937 AST_MEMBER(YueMultilineComment, &inner)
938AST_END(YueMultilineComment) 933AST_END(YueMultilineComment)
939 934
935AST_NODE(YueComment)
936 ast_sel<false, YueLineComment_t, YueMultilineComment_t> comment;
937 AST_MEMBER(YueComment, &comment)
938AST_END(YueComment)
939
940AST_NODE(ChainAssign) 940AST_NODE(ChainAssign)
941 ast_ptr<true, Seperator_t> sep; 941 ast_ptr<true, Seperator_t> sep;
942 ast_list<true, Exp_t> exprs; 942 ast_list<true, Exp_t> exprs;
@@ -945,8 +945,6 @@ AST_NODE(ChainAssign)
945AST_END(ChainAssign) 945AST_END(ChainAssign)
946 946
947AST_NODE(Statement) 947AST_NODE(Statement)
948 ast_ptr<true, Seperator_t> sep;
949 ast_sel_list<false, YueLineComment_t, YueMultilineComment_t> comments;
950 ast_sel<true, 948 ast_sel<true,
951 Import_t, While_t, Repeat_t, For_t, ForEach_t, 949 Import_t, While_t, Repeat_t, For_t, ForEach_t,
952 Return_t, Local_t, Global_t, Export_t, Macro_t, MacroInPlace_t, 950 Return_t, Local_t, Global_t, Export_t, Macro_t, MacroInPlace_t,
@@ -954,7 +952,7 @@ AST_NODE(Statement)
954 Backcall_t, LocalAttrib_t, PipeBody_t, ExpListAssign_t, ChainAssign_t 952 Backcall_t, LocalAttrib_t, PipeBody_t, ExpListAssign_t, ChainAssign_t
955 > content; 953 > content;
956 ast_ptr<false, StatementAppendix_t> appendix; 954 ast_ptr<false, StatementAppendix_t> appendix;
957 AST_MEMBER(Statement, &sep, &comments, &content, &appendix) 955 AST_MEMBER(Statement, &content, &appendix)
958AST_END(Statement) 956AST_END(Statement)
959 957
960AST_NODE(Body) 958AST_NODE(Body)
@@ -964,8 +962,8 @@ AST_END(Body)
964 962
965AST_NODE(Block) 963AST_NODE(Block)
966 ast_ptr<true, Seperator_t> sep; 964 ast_ptr<true, Seperator_t> sep;
967 ast_list<false, Statement_t> statements; 965 ast_sel_list<false, Statement_t, YueComment_t> statementOrComments;
968 AST_MEMBER(Block, &sep, &statements) 966 AST_MEMBER(Block, &sep, &statementOrComments)
969AST_END(Block) 967AST_END(Block)
970 968
971AST_NODE(BlockEnd) 969AST_NODE(BlockEnd)
@@ -984,6 +982,7 @@ struct YueFormat {
984 int indent = 0; 982 int indent = 0;
985 bool spaceOverTab = false; 983 bool spaceOverTab = false;
986 int tabSpaces = 4; 984 int tabSpaces = 4;
985 bool reserveComment = true;
987 std::string toString(ast_node* node); 986 std::string toString(ast_node* node);
988 987
989 void pushScope(); 988 void pushScope();
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 84b990f..8d3899f 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = {
78 "close"s // Lua 5.4 78 "close"s // Lua 5.4
79}; 79};
80 80
81const std::string_view version = "0.30.0"sv; 81const std::string_view version = "0.30.1"sv;
82const std::string_view extension = "yue"sv; 82const std::string_view extension = "yue"sv;
83 83
84class CompileError : public std::logic_error { 84class CompileError : public std::logic_error {
@@ -182,8 +182,9 @@ public:
182 try { 182 try {
183 auto block = _info.node.to<File_t>()->block.get(); 183 auto block = _info.node.to<File_t>()->block.get();
184 if (_info.exportMacro) { 184 if (_info.exportMacro) {
185 for (auto stmt_ : block->statements.objects()) { 185 for (auto stmt_ : block->statementOrComments.objects()) {
186 auto stmt = static_cast<Statement_t*>(stmt_); 186 auto stmt = ast_cast<Statement_t>(stmt_);
187 if (!stmt) continue;
187 switch (stmt->content->get_id()) { 188 switch (stmt->content->get_id()) {
188 case id<MacroInPlace_t>(): 189 case id<MacroInPlace_t>():
189 case id<Macro_t>(): 190 case id<Macro_t>():
@@ -967,7 +968,7 @@ private:
967 } 968 }
968 } 969 }
969 970
970 const std::string nll(ast_node* node) const { 971 const std::string nl(ast_node* node) const {
971 if (_config.reserveLineNumber) { 972 if (_config.reserveLineNumber) {
972 return " -- "s + std::to_string(node->m_begin.m_line + _config.lineOffset) + _newLine; 973 return " -- "s + std::to_string(node->m_begin.m_line + _config.lineOffset) + _newLine;
973 } else { 974 } else {
@@ -975,14 +976,6 @@ private:
975 } 976 }
976 } 977 }
977 978
978 const std::string nlr(ast_node* node) const {
979 if (_config.reserveLineNumber) {
980 return " -- "s + std::to_string(node->m_end.m_line + _config.lineOffset) + _newLine;
981 } else {
982 return _newLine;
983 }
984 }
985
986 void incIndentOffset() { 979 void incIndentOffset() {
987 _indentOffset++; 980 _indentOffset++;
988 } 981 }
@@ -1169,14 +1162,22 @@ private:
1169 return nullptr; 1162 return nullptr;
1170 } 1163 }
1171 1164
1172 Statement_t* lastStatementFrom(const node_container& stmts) const { 1165 Statement_t* lastStatementFrom(const node_container& statementOrComments) const {
1173 if (!stmts.empty()) { 1166 if (!statementOrComments.empty()) {
1174 auto it = stmts.end(); 1167 for (auto it = statementOrComments.rbegin(); it != statementOrComments.rend(); ++it) {
1175 --it; 1168 if (auto stmt = ast_cast<Statement_t>(*it)) {
1176 while (!static_cast<Statement_t*>(*it)->content && it != stmts.begin()) { 1169 return stmt;
1177 --it; 1170 }
1171 }
1172 }
1173 return nullptr;
1174 }
1175
1176 Statement_t* firstStatementFrom(Block_t* block) const {
1177 for (auto stmt_ : block->statementOrComments.objects()) {
1178 if (auto stmt = ast_cast<Statement_t>(stmt_)) {
1179 return stmt;
1178 } 1180 }
1179 return static_cast<Statement_t*>(*it);
1180 } 1181 }
1181 return nullptr; 1182 return nullptr;
1182 } 1183 }
@@ -1185,16 +1186,26 @@ private:
1185 if (auto stmt = body->content.as<Statement_t>()) { 1186 if (auto stmt = body->content.as<Statement_t>()) {
1186 return stmt; 1187 return stmt;
1187 } else { 1188 } else {
1188 const auto& stmts = body->content.to<Block_t>()->statements.objects(); 1189 const auto& stmts = body->content.to<Block_t>()->statementOrComments.objects();
1189 return lastStatementFrom(stmts); 1190 return lastStatementFrom(stmts);
1190 } 1191 }
1191 } 1192 }
1192 1193
1193 Statement_t* lastStatementFrom(Block_t* block) const { 1194 Statement_t* lastStatementFrom(Block_t* block) const {
1194 const auto& stmts = block->statements.objects(); 1195 const auto& stmts = block->statementOrComments.objects();
1195 return lastStatementFrom(stmts); 1196 return lastStatementFrom(stmts);
1196 } 1197 }
1197 1198
1199 int countStatementFrom(Block_t* block) const {
1200 int count = 0;
1201 for (auto stmt_ : block->statementOrComments.objects()) {
1202 if (ast_is<Statement_t>(stmt_)) {
1203 count++;
1204 }
1205 }
1206 return count;
1207 }
1208
1198 Exp_t* lastExpFromAssign(ast_node* action) { 1209 Exp_t* lastExpFromAssign(ast_node* action) {
1199 switch (action->get_id()) { 1210 switch (action->get_id()) {
1200 case id<Update_t>(): { 1211 case id<Update_t>(): {
@@ -1646,24 +1657,31 @@ private:
1646 return; 1657 return;
1647 } 1658 }
1648 1659
1649 void transformStatement(Statement_t* statement, str_list& out) { 1660 void transformComment(YueComment_t* comment, str_list& out) {
1650 auto x = statement; 1661 if (!_config.reserveComment) {
1651 if (_config.reserveComment && !x->comments.empty()) { 1662 return;
1652 for (ast_node* node : x->comments.objects()) { 1663 }
1653 switch (node->get_id()) { 1664 auto node = comment->comment.get();
1654 case id<YueLineComment_t>(): { 1665 if (!node) {
1655 auto comment = ast_cast<YueLineComment_t>(node); 1666 out.push_back("\n"s);
1656 out.push_back(indent() + "--"s + _parser.toString(comment) + '\n'); 1667 return;
1657 break; 1668 }
1658 } 1669 switch (node->get_id()) {
1659 case id<YueMultilineComment_t>(): { 1670 case id<YueLineComment_t>(): {
1660 auto comment = ast_cast<YueMultilineComment_t>(node); 1671 auto content = static_cast<YueLineComment_t*>(node);
1661 out.push_back(indent() + _parser.toString(comment) + '\n'); 1672 out.push_back(indent() + "--"s + _parser.toString(content) + '\n');
1662 break; 1673 break;
1663 } 1674 }
1664 } 1675 case id<YueMultilineComment_t>(): {
1676 auto content = static_cast<YueMultilineComment_t*>(node);
1677 out.push_back(indent() + "--[["s + _parser.toString(content) + "]]\n"s);
1678 break;
1665 } 1679 }
1666 } 1680 }
1681 }
1682
1683 void transformStatement(Statement_t* statement, str_list& out) {
1684 auto x = statement;
1667 if (statement->appendix) { 1685 if (statement->appendix) {
1668 if (auto assignment = assignmentFrom(statement)) { 1686 if (auto assignment = assignmentFrom(statement)) {
1669 auto preDefine = getPreDefineLine(assignment); 1687 auto preDefine = getPreDefineLine(assignment);
@@ -2047,7 +2065,7 @@ private:
2047 2065
2048 std::string getPreDefineLine(ExpListAssign_t* assignment) { 2066 std::string getPreDefineLine(ExpListAssign_t* assignment) {
2049 auto preDefine = getPreDefine(assignment); 2067 auto preDefine = getPreDefine(assignment);
2050 if (!preDefine.empty()) preDefine += nll(assignment); 2068 if (!preDefine.empty()) preDefine += nl(assignment);
2051 return preDefine; 2069 return preDefine;
2052 } 2070 }
2053 2071
@@ -2203,14 +2221,14 @@ private:
2203 temp.push_back(getPreDefineLine(assignment)); 2221 temp.push_back(getPreDefineLine(assignment));
2204 bool needScope = !currentScope().lastStatement; 2222 bool needScope = !currentScope().lastStatement;
2205 if (needScope) { 2223 if (needScope) {
2206 temp.push_back(indent() + "do"s + nll(assignment)); 2224 temp.push_back(indent() + "do"s + nl(assignment));
2207 pushScope(); 2225 pushScope();
2208 } 2226 }
2209 transformAssignment(preAssignment, temp); 2227 transformAssignment(preAssignment, temp);
2210 transformAssignment(assignment, temp); 2228 transformAssignment(assignment, temp);
2211 if (needScope) { 2229 if (needScope) {
2212 popScope(); 2230 popScope();
2213 temp.push_back(indent() + "end"s + nll(assignment)); 2231 temp.push_back(indent() + "end"s + nl(assignment));
2214 } 2232 }
2215 out.push_back(join(temp)); 2233 out.push_back(join(temp));
2216 return false; 2234 return false;
@@ -2280,7 +2298,7 @@ private:
2280 throw CompileError("right value missing"sv, values.front()); 2298 throw CompileError("right value missing"sv, values.front());
2281 } 2299 }
2282 transformAssignItem(*vit, args); 2300 transformAssignItem(*vit, args);
2283 _buf << indent() << globalVar("setmetatable"sv, x, AccessType::Read) << '(' << join(args, ", "sv) << ')' << nll(x); 2301 _buf << indent() << globalVar("setmetatable"sv, x, AccessType::Read) << '(' << join(args, ", "sv) << ')' << nl(x);
2284 temp.push_back(clearBuf()); 2302 temp.push_back(clearBuf());
2285 if (!afterAssignment->expList->exprs.empty()) { 2303 if (!afterAssignment->expList->exprs.empty()) {
2286 transformAssignment(afterAssignment, temp); 2304 transformAssignment(afterAssignment, temp);
@@ -2309,7 +2327,7 @@ private:
2309 if (varName.empty() || !isLocal(varName)) { 2327 if (varName.empty() || !isLocal(varName)) {
2310 if (needScope) { 2328 if (needScope) {
2311 extraScoped = true; 2329 extraScoped = true;
2312 temp.push_back(indent() + "do"s + nll(x)); 2330 temp.push_back(indent() + "do"s + nl(x));
2313 pushScope(); 2331 pushScope();
2314 } 2332 }
2315 auto objVar = getUnusedName("_obj_"sv); 2333 auto objVar = getUnusedName("_obj_"sv);
@@ -2324,7 +2342,7 @@ private:
2324 if (auto spread = ast_cast<SpreadListExp_t>(*vit)) { 2342 if (auto spread = ast_cast<SpreadListExp_t>(*vit)) {
2325 auto lenVar = getUnusedName("_len_"sv); 2343 auto lenVar = getUnusedName("_len_"sv);
2326 forceAddToScope(lenVar); 2344 forceAddToScope(lenVar);
2327 temp.push_back(indent() + "local "s + lenVar + " = #"s + varName + " + 1"s + nll(spread)); 2345 temp.push_back(indent() + "local "s + lenVar + " = #"s + varName + " + 1"s + nl(spread));
2328 auto elmVar = getUnusedName("_elm_"sv); 2346 auto elmVar = getUnusedName("_elm_"sv);
2329 _buf << varName << '[' << lenVar << "],"s << lenVar << "="s << elmVar << ',' << lenVar << "+1 for "s << elmVar << " in *nil"s; 2347 _buf << varName << '[' << lenVar << "],"s << lenVar << "="s << elmVar << ',' << lenVar << "+1 for "s << elmVar << " in *nil"s;
2330 auto stmt = toAst<Statement_t>(clearBuf(), spread); 2348 auto stmt = toAst<Statement_t>(clearBuf(), spread);
@@ -2344,7 +2362,7 @@ private:
2344 } 2362 }
2345 if (extraScoped) { 2363 if (extraScoped) {
2346 popScope(); 2364 popScope();
2347 temp.push_back(indent() + "end"s + nlr(x)); 2365 temp.push_back(indent() + "end"s + nl(x));
2348 } 2366 }
2349 if (!afterAssignment->expList->exprs.empty()) { 2367 if (!afterAssignment->expList->exprs.empty()) {
2350 transformAssignment(afterAssignment, temp); 2368 transformAssignment(afterAssignment, temp);
@@ -2615,11 +2633,11 @@ private:
2615 checkConst(def, x); 2633 checkConst(def, x);
2616 addToScope(def); 2634 addToScope(def);
2617 } 2635 }
2618 temp.push_back(indent() + "local "s + join(defs, ", "sv) + nll(x)); 2636 temp.push_back(indent() + "local "s + join(defs, ", "sv) + nl(x));
2619 } 2637 }
2620 if (needScope) { 2638 if (needScope) {
2621 extraScope = true; 2639 extraScope = true;
2622 temp.push_back(indent() + "do"s + nll(x)); 2640 temp.push_back(indent() + "do"s + nl(x));
2623 pushScope(); 2641 pushScope();
2624 } 2642 }
2625 } 2643 }
@@ -2671,13 +2689,13 @@ private:
2671 continue; 2689 continue;
2672 } 2690 }
2673 if (extraScope) { 2691 if (extraScope) {
2674 temp.push_back(indent() + "do"s + nll(x)); 2692 temp.push_back(indent() + "do"s + nl(x));
2675 pushScope(); 2693 pushScope();
2676 } 2694 }
2677 if (!pair.targetVar.empty()) { 2695 if (!pair.targetVar.empty()) {
2678 checkConst(pair.targetVar, x); 2696 checkConst(pair.targetVar, x);
2679 if (addToScope(pair.targetVar)) { 2697 if (addToScope(pair.targetVar)) {
2680 _buf << indent() << "local "sv << pair.targetVar << nll(x); 2698 _buf << indent() << "local "sv << pair.targetVar << nl(x);
2681 temp.push_back(clearBuf()); 2699 temp.push_back(clearBuf());
2682 } 2700 }
2683 } 2701 }
@@ -2687,7 +2705,7 @@ private:
2687 objVar = destruct.valueVar; 2705 objVar = destruct.valueVar;
2688 } else { 2706 } else {
2689 if (needScope) { 2707 if (needScope) {
2690 temp.push_back(indent() + "do"s + nll(x)); 2708 temp.push_back(indent() + "do"s + nl(x));
2691 pushScope(); 2709 pushScope();
2692 } 2710 }
2693 objVar = getUnusedName("_obj_"sv); 2711 objVar = getUnusedName("_obj_"sv);
@@ -2703,7 +2721,7 @@ private:
2703 if (!isLocalValue) { 2721 if (!isLocalValue) {
2704 if (needScope) { 2722 if (needScope) {
2705 popScope(); 2723 popScope();
2706 _buf << indent() << "end"sv << nlr(x); 2724 _buf << indent() << "end"sv << nl(x);
2707 temp.push_back(clearBuf()); 2725 temp.push_back(clearBuf());
2708 } 2726 }
2709 } 2727 }
@@ -2741,9 +2759,9 @@ private:
2741 checkConst(def, x); 2759 checkConst(def, x);
2742 addToScope(def); 2760 addToScope(def);
2743 } 2761 }
2744 temp.push_back(indent() + "local "s + join(defs, ", "sv) + nll(x)); 2762 temp.push_back(indent() + "local "s + join(defs, ", "sv) + nl(x));
2745 } 2763 }
2746 temp.push_back(indent() + "do"s + nll(x)); 2764 temp.push_back(indent() + "do"s + nl(x));
2747 pushScope(); 2765 pushScope();
2748 } 2766 }
2749 } else { 2767 } else {
@@ -2752,11 +2770,11 @@ private:
2752 checkConst(def, x); 2770 checkConst(def, x);
2753 addToScope(def); 2771 addToScope(def);
2754 } 2772 }
2755 temp.push_back(indent() + "local "s + join(defs, ", "sv) + nll(x)); 2773 temp.push_back(indent() + "local "s + join(defs, ", "sv) + nl(x));
2756 } 2774 }
2757 if (needScope) { 2775 if (needScope) {
2758 extraScope = true; 2776 extraScope = true;
2759 temp.push_back(indent() + "do"s + nll(x)); 2777 temp.push_back(indent() + "do"s + nl(x));
2760 pushScope(); 2778 pushScope();
2761 } 2779 }
2762 auto valVar = getUnusedName("_obj_"sv); 2780 auto valVar = getUnusedName("_obj_"sv);
@@ -2771,7 +2789,7 @@ private:
2771 if (destruct.inlineAssignment) { 2789 if (destruct.inlineAssignment) {
2772 if (needScope && !extraScope) { 2790 if (needScope && !extraScope) {
2773 extraScope = true; 2791 extraScope = true;
2774 temp.push_back(indent() + "do"s + nll(x)); 2792 temp.push_back(indent() + "do"s + nl(x));
2775 pushScope(); 2793 pushScope();
2776 } 2794 }
2777 transformAssignment(destruct.inlineAssignment, temp); 2795 transformAssignment(destruct.inlineAssignment, temp);
@@ -2836,13 +2854,13 @@ private:
2836 } 2854 }
2837 if (extraScope) { 2855 if (extraScope) {
2838 popScope(); 2856 popScope();
2839 _buf << indent() << "end"sv << nlr(x); 2857 _buf << indent() << "end"sv << nl(x);
2840 temp.push_back(clearBuf()); 2858 temp.push_back(clearBuf());
2841 } 2859 }
2842 } 2860 }
2843 if (extraScope) { 2861 if (extraScope) {
2844 popScope(); 2862 popScope();
2845 temp.push_back(indent() + "end"s + nlr(x)); 2863 temp.push_back(indent() + "end"s + nl(x));
2846 } 2864 }
2847 out.push_back(join(temp)); 2865 out.push_back(join(temp));
2848 if (assignment->expList->followStmt) { 2866 if (assignment->expList->followStmt) {
@@ -3664,7 +3682,7 @@ private:
3664 _buf << defs; 3682 _buf << defs;
3665 else 3683 else
3666 _buf << indent() << left; 3684 _buf << indent() << left;
3667 _buf << " = "sv << left << ' ' << op << ' ' << right << nll(assignment); 3685 _buf << " = "sv << left << ' ' << op << ' ' << right << nl(assignment);
3668 out.push_back(clearBuf()); 3686 out.push_back(clearBuf());
3669 break; 3687 break;
3670 } 3688 }
@@ -3711,9 +3729,9 @@ private:
3711 transformExpList(expList, temp); 3729 transformExpList(expList, temp);
3712 std::string left = std::move(temp.back()); 3730 std::string left = std::move(temp.back());
3713 temp.pop_back(); 3731 temp.pop_back();
3714 out.push_back(indent() + left + " = "s + join(temp, ", "sv) + nll(assignment)); 3732 out.push_back(indent() + left + " = "s + join(temp, ", "sv) + nl(assignment));
3715 } else { 3733 } else {
3716 out.push_back(preDefine + " = "s + join(temp, ", "sv) + nll(assignment)); 3734 out.push_back(preDefine + " = "s + join(temp, ", "sv) + nl(assignment));
3717 } 3735 }
3718 } else { 3736 } else {
3719 std::string preDefine = toLocalDecl(defs); 3737 std::string preDefine = toLocalDecl(defs);
@@ -3729,7 +3747,7 @@ private:
3729 for (auto value : assign->values.objects()) { 3747 for (auto value : assign->values.objects()) {
3730 transformAssignItem(value, temp); 3748 transformAssignItem(value, temp);
3731 } 3749 }
3732 out.push_back((preDefine.empty() ? Empty : preDefine + nll(assignment)) + indent() + left + " = "s + join(temp, ", "sv) + nll(assignment)); 3750 out.push_back((preDefine.empty() ? Empty : preDefine + nl(assignment)) + indent() + left + " = "s + join(temp, ", "sv) + nl(assignment));
3733 } 3751 }
3734 break; 3752 break;
3735 } 3753 }
@@ -3830,7 +3848,7 @@ private:
3830 if (usage != ExpUsage::Closure) { 3848 if (usage != ExpUsage::Closure) {
3831 if (!currentScope().lastStatement) { 3849 if (!currentScope().lastStatement) {
3832 extraScope = true; 3850 extraScope = true;
3833 temp.push_back(indent() + "do"s + nll(asmt)); 3851 temp.push_back(indent() + "do"s + nl(asmt));
3834 pushScope(); 3852 pushScope();
3835 } 3853 }
3836 } 3854 }
@@ -3863,7 +3881,7 @@ private:
3863 if (usage != ExpUsage::Closure) { 3881 if (usage != ExpUsage::Closure) {
3864 if (!currentScope().lastStatement) { 3882 if (!currentScope().lastStatement) {
3865 extraScope = true; 3883 extraScope = true;
3866 temp.push_back(indent() + "do"s + nll(asmt)); 3884 temp.push_back(indent() + "do"s + nl(asmt));
3867 pushScope(); 3885 pushScope();
3868 } 3886 }
3869 } 3887 }
@@ -3892,12 +3910,12 @@ private:
3892 if (pair != ifCondPairs.front()) { 3910 if (pair != ifCondPairs.front()) {
3893 _buf << "else"sv; 3911 _buf << "else"sv;
3894 } 3912 }
3895 _buf << "if "sv << condStr << " then"sv << nll(condition); 3913 _buf << "if "sv << condStr << " then"sv << nl(condition);
3896 temp.push_back(clearBuf()); 3914 temp.push_back(clearBuf());
3897 } 3915 }
3898 if (pair.second) { 3916 if (pair.second) {
3899 if (!pair.first) { 3917 if (!pair.first) {
3900 temp.push_back(indent() + "else"s + nll(pair.second)); 3918 temp.push_back(indent() + "else"s + nl(pair.second));
3901 } 3919 }
3902 pushScope(); 3920 pushScope();
3903 if (pair == ifCondPairs.front() && extraAssignment) { 3921 if (pair == ifCondPairs.front() && extraAssignment) {
@@ -3907,17 +3925,17 @@ private:
3907 popScope(); 3925 popScope();
3908 } 3926 }
3909 if (!pair.first) { 3927 if (!pair.first) {
3910 temp.push_back(indent() + "end"s + nll(nodes.front())); 3928 temp.push_back(indent() + "end"s + nl(nodes.front()));
3911 break; 3929 break;
3912 } 3930 }
3913 } 3931 }
3914 if (extraScope) { 3932 if (extraScope) {
3915 popScope(); 3933 popScope();
3916 temp.push_back(indent() + "end"s + nlr(nodes.front())); 3934 temp.push_back(indent() + "end"s + nl(nodes.front()));
3917 } 3935 }
3918 if (usage == ExpUsage::Closure) { 3936 if (usage == ExpUsage::Closure) {
3919 popScope(); 3937 popScope();
3920 *funcStart = anonFuncStart() + nll(nodes.front()); 3938 *funcStart = anonFuncStart() + nl(nodes.front());
3921 temp.push_back(indent() + anonFuncEnd()); 3939 temp.push_back(indent() + anonFuncEnd());
3922 popAnonVarArg(); 3940 popAnonVarArg();
3923 popFunctionScope(); 3941 popFunctionScope();
@@ -4012,7 +4030,7 @@ private:
4012 } else { 4030 } else {
4013 transformExp(arg, out, ExpUsage::Closure); 4031 transformExp(arg, out, ExpUsage::Closure);
4014 out.back().insert(0, indent()); 4032 out.back().insert(0, indent());
4015 out.back().append(nlr(x)); 4033 out.back().append(nl(x));
4016 } 4034 }
4017 return; 4035 return;
4018 } 4036 }
@@ -4136,7 +4154,7 @@ private:
4136 auto stmt = exp->new_ptr<Statement_t>(); 4154 auto stmt = exp->new_ptr<Statement_t>();
4137 stmt->content.set(preDefine); 4155 stmt->content.set(preDefine);
4138 preDefine.set(nullptr); 4156 preDefine.set(nullptr);
4139 block->statements.push_back(stmt); 4157 block->statementOrComments.push_back(stmt);
4140 auto simpleValue = exp->new_ptr<SimpleValue_t>(); 4158 auto simpleValue = exp->new_ptr<SimpleValue_t>();
4141 simpleValue->value.set(ifNode); 4159 simpleValue->value.set(ifNode);
4142 auto explist = exp->new_ptr<ExpList_t>(); 4160 auto explist = exp->new_ptr<ExpList_t>();
@@ -4145,7 +4163,7 @@ private:
4145 expListAssign->expList.set(explist); 4163 expListAssign->expList.set(explist);
4146 stmt = exp->new_ptr<Statement_t>(); 4164 stmt = exp->new_ptr<Statement_t>();
4147 stmt->content.set(expListAssign); 4165 stmt->content.set(expListAssign);
4148 block->statements.push_back(stmt); 4166 block->statementOrComments.push_back(stmt);
4149 nodes->push_back(block); 4167 nodes->push_back(block);
4150 nodes = &ifNode->nodes; 4168 nodes = &ifNode->nodes;
4151 } else { 4169 } else {
@@ -4153,7 +4171,7 @@ private:
4153 auto stmt = exp->new_ptr<Statement_t>(); 4171 auto stmt = exp->new_ptr<Statement_t>();
4154 stmt->content.set(preDefine); 4172 stmt->content.set(preDefine);
4155 preDefine.set(nullptr); 4173 preDefine.set(nullptr);
4156 block->statements.push_back(stmt); 4174 block->statementOrComments.push_back(stmt);
4157 auto simpleValue = exp->new_ptr<SimpleValue_t>(); 4175 auto simpleValue = exp->new_ptr<SimpleValue_t>();
4158 simpleValue->value.set(ifNode); 4176 simpleValue->value.set(ifNode);
4159 auto explist = exp->new_ptr<ExpList_t>(); 4177 auto explist = exp->new_ptr<ExpList_t>();
@@ -4162,7 +4180,7 @@ private:
4162 expListAssign->expList.set(explist); 4180 expListAssign->expList.set(explist);
4163 stmt = exp->new_ptr<Statement_t>(); 4181 stmt = exp->new_ptr<Statement_t>();
4164 stmt->content.set(expListAssign); 4182 stmt->content.set(expListAssign);
4165 block->statements.push_back(stmt); 4183 block->statementOrComments.push_back(stmt);
4166 auto body = exp->new_ptr<Body_t>(); 4184 auto body = exp->new_ptr<Body_t>();
4167 body->content.set(block); 4185 body->content.set(block);
4168 auto doNode = exp->new_ptr<Do_t>(); 4186 auto doNode = exp->new_ptr<Do_t>();
@@ -4324,7 +4342,7 @@ private:
4324 auto stmt = x->new_ptr<Statement_t>(); 4342 auto stmt = x->new_ptr<Statement_t>();
4325 stmt->content.set(expListAssign); 4343 stmt->content.set(expListAssign);
4326 auto blk = x->new_ptr<Block_t>(); 4344 auto blk = x->new_ptr<Block_t>();
4327 blk->statements.push_back(stmt); 4345 blk->statementOrComments.push_back(stmt);
4328 newBlock.set(blk); 4346 newBlock.set(blk);
4329 } 4347 }
4330 if (!globals.empty()) { 4348 if (!globals.empty()) {
@@ -4420,9 +4438,9 @@ private:
4420 if (auto sVal = simpleSingleValueFrom(exp)) { 4438 if (auto sVal = simpleSingleValueFrom(exp)) {
4421 if (auto doNode = sVal->value.as<Do_t>()) { 4439 if (auto doNode = sVal->value.as<Do_t>()) {
4422 if (auto blk = doNode->body->content.as<Block_t>()) { 4440 if (auto blk = doNode->body->content.as<Block_t>()) {
4423 block->statements.dup(blk->statements); 4441 block->statementOrComments.dup(blk->statementOrComments);
4424 } else { 4442 } else {
4425 block->statements.push_back(doNode->body->content.to<Statement_t>()); 4443 block->statementOrComments.push_back(doNode->body->content.to<Statement_t>());
4426 } 4444 }
4427 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite); 4445 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite);
4428 } 4446 }
@@ -4434,7 +4452,7 @@ private:
4434 returnNode->valueList.set(returnList); 4452 returnNode->valueList.set(returnList);
4435 auto stmt = exp->new_ptr<Statement_t>(); 4453 auto stmt = exp->new_ptr<Statement_t>();
4436 stmt->content.set(returnNode); 4454 stmt->content.set(returnNode);
4437 block->statements.push_back(stmt); 4455 block->statementOrComments.push_back(stmt);
4438 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite); 4456 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite);
4439 } 4457 }
4440 return std::nullopt; 4458 return std::nullopt;
@@ -4491,7 +4509,7 @@ private:
4491 bool extraScope = !currentScope().lastStatement; 4509 bool extraScope = !currentScope().lastStatement;
4492 if (forAssignment) { 4510 if (forAssignment) {
4493 if (extraScope) { 4511 if (extraScope) {
4494 temp.push_back(indent() + "do"s + nll(x)); 4512 temp.push_back(indent() + "do"s + nl(x));
4495 pushScope(); 4513 pushScope();
4496 } 4514 }
4497 } 4515 }
@@ -4514,9 +4532,9 @@ private:
4514 case ExpUsage::Return: 4532 case ExpUsage::Return:
4515 case ExpUsage::Closure: { 4533 case ExpUsage::Closure: {
4516 prepareValue(); 4534 prepareValue();
4517 _buf << indent() << "if "sv << objVar << " ~= nil then"sv << nll(x); 4535 _buf << indent() << "if "sv << objVar << " ~= nil then"sv << nl(x);
4518 _buf << indent(1) << "return "s << objVar << nll(x); 4536 _buf << indent(1) << "return "s << objVar << nl(x);
4519 _buf << indent() << "else"s << nll(x); 4537 _buf << indent() << "else"s << nl(x);
4520 temp.push_back(clearBuf()); 4538 temp.push_back(clearBuf());
4521 auto ret = x->new_ptr<Return_t>(); 4539 auto ret = x->new_ptr<Return_t>();
4522 ret->explicitReturn = false; 4540 ret->explicitReturn = false;
@@ -4526,10 +4544,10 @@ private:
4526 incIndentOffset(); 4544 incIndentOffset();
4527 transformReturn(ret, temp); 4545 transformReturn(ret, temp);
4528 decIndentOffset(); 4546 decIndentOffset();
4529 temp.push_back(indent() + "end"s + nll(x)); 4547 temp.push_back(indent() + "end"s + nl(x));
4530 if (usage == ExpUsage::Closure) { 4548 if (usage == ExpUsage::Closure) {
4531 popScope(); 4549 popScope();
4532 *funcStart = anonFuncStart() + nll(x); 4550 *funcStart = anonFuncStart() + nl(x);
4533 temp.push_back(indent() + anonFuncEnd()); 4551 temp.push_back(indent() + anonFuncEnd());
4534 popAnonVarArg(); 4552 popAnonVarArg();
4535 popFunctionScope(); 4553 popFunctionScope();
@@ -4546,14 +4564,14 @@ private:
4546 assign->values.push_back(exp); 4564 assign->values.push_back(exp);
4547 temp.push_back(getPreDefineLine(assignment)); 4565 temp.push_back(getPreDefineLine(assignment));
4548 extraScope = prepareValue(true); 4566 extraScope = prepareValue(true);
4549 _buf << indent() << "if "sv << objVar << " ~= nil then"sv << nll(x); 4567 _buf << indent() << "if "sv << objVar << " ~= nil then"sv << nl(x);
4550 temp.push_back(clearBuf()); 4568 temp.push_back(clearBuf());
4551 pushScope(); 4569 pushScope();
4552 assign->values.clear(); 4570 assign->values.clear();
4553 assign->values.push_back(toAst<Exp_t>(objVar, x)); 4571 assign->values.push_back(toAst<Exp_t>(objVar, x));
4554 transformAssignment(assignment, temp); 4572 transformAssignment(assignment, temp);
4555 popScope(); 4573 popScope();
4556 temp.push_back(indent() + "else"s + nll(x)); 4574 temp.push_back(indent() + "else"s + nl(x));
4557 assign->values.clear(); 4575 assign->values.clear();
4558 assign->values.push_back(exp->nilCoalesed); 4576 assign->values.push_back(exp->nilCoalesed);
4559 } else { 4577 } else {
@@ -4561,17 +4579,17 @@ private:
4561 assign->values.push_back(exp->nilCoalesed); 4579 assign->values.push_back(exp->nilCoalesed);
4562 temp.push_back(getPreDefineLine(assignment)); 4580 temp.push_back(getPreDefineLine(assignment));
4563 transformExp(left, temp, ExpUsage::Closure); 4581 transformExp(left, temp, ExpUsage::Closure);
4564 _buf << indent() << "if "sv << temp.back() << " == nil then"sv << nll(x); 4582 _buf << indent() << "if "sv << temp.back() << " == nil then"sv << nl(x);
4565 temp.pop_back(); 4583 temp.pop_back();
4566 temp.push_back(clearBuf()); 4584 temp.push_back(clearBuf());
4567 } 4585 }
4568 pushScope(); 4586 pushScope();
4569 transformAssignment(assignment, temp); 4587 transformAssignment(assignment, temp);
4570 popScope(); 4588 popScope();
4571 temp.push_back(indent() + "end"s + nlr(x)); 4589 temp.push_back(indent() + "end"s + nl(x));
4572 if (extraScope) { 4590 if (extraScope) {
4573 popScope(); 4591 popScope();
4574 temp.push_back(indent() + "end"s + nlr(x)); 4592 temp.push_back(indent() + "end"s + nl(x));
4575 } 4593 }
4576 break; 4594 break;
4577 } 4595 }
@@ -4670,11 +4688,11 @@ private:
4670 switch (content->get_id()) { 4688 switch (content->get_id()) {
4671 case id<Block_t>(): { 4689 case id<Block_t>(): {
4672 auto block = static_cast<Block_t*>(content); 4690 auto block = static_cast<Block_t*>(content);
4673 newBlock->statements.dup(block->statements); 4691 newBlock->statementOrComments.dup(block->statementOrComments);
4674 break; 4692 break;
4675 } 4693 }
4676 case id<Statement_t>(): { 4694 case id<Statement_t>(): {
4677 newBlock->statements.push_back(content); 4695 newBlock->statementOrComments.push_back(content);
4678 break; 4696 break;
4679 } 4697 }
4680 default: YUEE("AST node mismatch", content); break; 4698 default: YUEE("AST node mismatch", content); break;
@@ -4686,7 +4704,7 @@ private:
4686 returnNode->valueList.set(funLit->defaultReturn); 4704 returnNode->valueList.set(funLit->defaultReturn);
4687 auto stmt = newBlock->new_ptr<Statement_t>(); 4705 auto stmt = newBlock->new_ptr<Statement_t>();
4688 stmt->content.set(returnNode); 4706 stmt->content.set(returnNode);
4689 newBlock->statements.push_back(stmt); 4707 newBlock->statementOrComments.push_back(stmt);
4690 } 4708 }
4691 transformBlock(newBlock, temp, ExpUsage::Common); 4709 transformBlock(newBlock, temp, ExpUsage::Common);
4692 } else { 4710 } else {
@@ -4708,7 +4726,7 @@ private:
4708 } 4726 }
4709 _buf << args << ')'; 4727 _buf << args << ')';
4710 if (!initArgs.empty() || !bodyCodes.empty()) { 4728 if (!initArgs.empty() || !bodyCodes.empty()) {
4711 _buf << nlr(argsDef) << initArgs << bodyCodes; 4729 _buf << nl(argsDef) << initArgs << bodyCodes;
4712 popScope(); 4730 popScope();
4713 _buf << indent() << "end"sv; 4731 _buf << indent() << "end"sv;
4714 } else { 4732 } else {
@@ -4719,7 +4737,7 @@ private:
4719 auto& bodyCodes = temp.back(); 4737 auto& bodyCodes = temp.back();
4720 _buf << "function("sv << (isFatArrow ? "self"s : Empty) << ')'; 4738 _buf << "function("sv << (isFatArrow ? "self"s : Empty) << ')';
4721 if (!bodyCodes.empty()) { 4739 if (!bodyCodes.empty()) {
4722 _buf << nll(funLit) << bodyCodes; 4740 _buf << nl(funLit) << bodyCodes;
4723 popScope(); 4741 popScope();
4724 _buf << indent() << "end"sv; 4742 _buf << indent() << "end"sv;
4725 } else { 4743 } else {
@@ -4736,7 +4754,7 @@ private:
4736 auto x = body; 4754 auto x = body;
4737 if (auto stmt = body->content.as<Statement_t>()) { 4755 if (auto stmt = body->content.as<Statement_t>()) {
4738 auto block = x->new_ptr<Block_t>(); 4756 auto block = x->new_ptr<Block_t>();
4739 block->statements.push_back(stmt); 4757 block->statementOrComments.push_back(stmt);
4740 transformBlock(block, out, usage, assignList); 4758 transformBlock(block, out, usage, assignList);
4741 } else { 4759 } else {
4742 transformBlock(body->content.to<Block_t>(), out, usage, assignList); 4760 transformBlock(body->content.to<Block_t>(), out, usage, assignList);
@@ -4748,13 +4766,15 @@ private:
4748 out.push_back(Empty); 4766 out.push_back(Empty);
4749 return; 4767 return;
4750 } 4768 }
4751 const auto& nodes = block->statements.objects(); 4769 const auto& nodes = block->statementOrComments.objects();
4770 auto lastStmt = lastStatementFrom(nodes);
4752 LocalMode mode = LocalMode::None; 4771 LocalMode mode = LocalMode::None;
4753 Local_t *any = nullptr, *capital = nullptr; 4772 Local_t *any = nullptr, *capital = nullptr;
4754 for (auto it = nodes.begin(); it != nodes.end(); ++it) { 4773 for (auto it = nodes.begin(); it != nodes.end(); ++it) {
4755 auto node = *it; 4774 auto node = *it;
4756 auto stmt = static_cast<Statement_t*>(node); 4775 auto stmt = ast_cast<Statement_t>(node);
4757 if (!stmt->appendix && stmt->content.is<Return_t>() && stmt != nodes.back()) { 4776 if (!stmt) continue;
4777 if (!stmt->appendix && stmt->content.is<Return_t>() && stmt != lastStmt) {
4758 throw CompileError("'return' statement must be the last line in the block"sv, stmt->content); 4778 throw CompileError("'return' statement must be the last line in the block"sv, stmt->content);
4759 } else if (auto pipeBody = stmt->content.as<PipeBody_t>()) { 4779 } else if (auto pipeBody = stmt->content.as<PipeBody_t>()) {
4760 auto x = stmt; 4780 auto x = stmt;
@@ -4763,6 +4783,16 @@ private:
4763 BREAK_IF(it == nodes.begin()); 4783 BREAK_IF(it == nodes.begin());
4764 auto last = it; 4784 auto last = it;
4765 --last; 4785 --last;
4786 bool found = true;
4787 while (!ast_is<Statement_t>(*last)) {
4788 if (last == nodes.begin()) {
4789 found = false;
4790 break;
4791 } else {
4792 --last;
4793 }
4794 }
4795 BREAK_IF(!found);
4766 auto lst = static_cast<Statement_t*>(*last); 4796 auto lst = static_cast<Statement_t*>(*last);
4767 if (lst->appendix) { 4797 if (lst->appendix) {
4768 throw CompileError("statement decorator must be placed at the end of pipe chain"sv, lst->appendix.get()); 4798 throw CompileError("statement decorator must be placed at the end of pipe chain"sv, lst->appendix.get());
@@ -4780,9 +4810,17 @@ private:
4780 stmt->content.set(nullptr); 4810 stmt->content.set(nullptr);
4781 auto next = it; 4811 auto next = it;
4782 ++next; 4812 ++next;
4813 Statement_t* nextStmt = nullptr;
4814 while (next != nodes.end()) {
4815 nextStmt = ast_cast<Statement_t>(*next);
4816 if (nextStmt) {
4817 break;
4818 }
4819 ++next;
4820 }
4783 BLOCK_START 4821 BLOCK_START
4784 BREAK_IF(next == nodes.end()); 4822 BREAK_IF(!nextStmt);
4785 BREAK_IF(!static_cast<Statement_t*>(*next)->content.as<PipeBody_t>()); 4823 BREAK_IF(!nextStmt->content.as<PipeBody_t>());
4786 throw CompileError("indent mismatch in pipe chain"sv, *next); 4824 throw CompileError("indent mismatch in pipe chain"sv, *next);
4787 BLOCK_END 4825 BLOCK_END
4788 } else if (auto backcall = stmt->content.as<Backcall_t>()) { 4826 } else if (auto backcall = stmt->content.as<Backcall_t>()) {
@@ -4790,7 +4828,7 @@ private:
4790 auto newBlock = x->new_ptr<Block_t>(); 4828 auto newBlock = x->new_ptr<Block_t>();
4791 if (it != nodes.begin()) { 4829 if (it != nodes.begin()) {
4792 for (auto i = nodes.begin(); i != it; ++i) { 4830 for (auto i = nodes.begin(); i != it; ++i) {
4793 newBlock->statements.push_back(*i); 4831 newBlock->statementOrComments.push_back(*i);
4794 } 4832 }
4795 } 4833 }
4796 x = backcall; 4834 x = backcall;
@@ -4801,7 +4839,7 @@ private:
4801 ++next; 4839 ++next;
4802 if (next != nodes.end()) { 4840 if (next != nodes.end()) {
4803 for (auto i = next; i != nodes.end(); ++i) { 4841 for (auto i = next; i != nodes.end(); ++i) {
4804 block->statements.push_back(*i); 4842 block->statementOrComments.push_back(*i);
4805 } 4843 }
4806 } 4844 }
4807 auto body = x->new_ptr<Body_t>(); 4845 auto body = x->new_ptr<Body_t>();
@@ -4853,7 +4891,7 @@ private:
4853 expListAssign->expList.set(expList); 4891 expListAssign->expList.set(expList);
4854 newStmt->content.set(expListAssign); 4892 newStmt->content.set(expListAssign);
4855 newStmt->appendix.set(stmt->appendix); 4893 newStmt->appendix.set(stmt->appendix);
4856 newBlock->statements.push_back(newStmt); 4894 newBlock->statementOrComments.push_back(newStmt);
4857 } 4895 }
4858 transformBlock(newBlock, out, usage, assignList, isRoot); 4896 transformBlock(newBlock, out, usage, assignList, isRoot);
4859 return; 4897 return;
@@ -4909,7 +4947,7 @@ private:
4909 auto newBlock = x->new_ptr<Block_t>(); 4947 auto newBlock = x->new_ptr<Block_t>();
4910 if (it != nodes.begin()) { 4948 if (it != nodes.begin()) {
4911 for (auto i = nodes.begin(); i != it; ++i) { 4949 for (auto i = nodes.begin(); i != it; ++i) {
4912 newBlock->statements.push_back(*i); 4950 newBlock->statementOrComments.push_back(*i);
4913 } 4951 }
4914 } 4952 }
4915 x = expListAssign; 4953 x = expListAssign;
@@ -4919,7 +4957,7 @@ private:
4919 ++next; 4957 ++next;
4920 if (next != nodes.end()) { 4958 if (next != nodes.end()) {
4921 for (auto i = next; i != nodes.end(); ++i) { 4959 for (auto i = next; i != nodes.end(); ++i) {
4922 followingBlock->statements.push_back(*i); 4960 followingBlock->statementOrComments.push_back(*i);
4923 } 4961 }
4924 } 4962 }
4925 } 4963 }
@@ -4947,7 +4985,7 @@ private:
4947 newAssignment->action.set(newAssign); 4985 newAssignment->action.set(newAssign);
4948 auto newStatement = x->new_ptr<Statement_t>(); 4986 auto newStatement = x->new_ptr<Statement_t>();
4949 newStatement->content.set(newAssignment); 4987 newStatement->content.set(newAssignment);
4950 followingBlock->statements.push_front(newStatement); 4988 followingBlock->statementOrComments.push_front(newStatement);
4951 } 4989 }
4952 argNames.push_back("..."s); 4990 argNames.push_back("..."s);
4953 auto newBody = x->new_ptr<Body_t>(); 4991 auto newBody = x->new_ptr<Body_t>();
@@ -4961,8 +4999,9 @@ private:
4961 finalArgs.push_back(arg); 4999 finalArgs.push_back(arg);
4962 } 5000 }
4963 } 5001 }
4964 newBlock->statements.push_back(toAst<Statement_t>(funcName + ' ' + (finalArgs.empty() ? "nil"s : join(finalArgs, ","sv)), x)); 5002 auto lastNewStmt = toAst<Statement_t>(funcName + ' ' + (finalArgs.empty() ? "nil"s : join(finalArgs, ","sv)), x);
4965 auto sVal = singleValueFrom(static_cast<Statement_t*>(newBlock->statements.back())->content.to<ExpListAssign_t>()->expList); 5003 newBlock->statementOrComments.push_back(lastNewStmt);
5004 auto sVal = singleValueFrom(lastNewStmt->content.to<ExpListAssign_t>()->expList);
4966 auto invokArgs = ast_to<InvokeArgs_t>(sVal->item.to<ChainValue_t>()->items.back()); 5005 auto invokArgs = ast_to<InvokeArgs_t>(sVal->item.to<ChainValue_t>()->items.back());
4967 if (finalArgs.empty()) { 5006 if (finalArgs.empty()) {
4968 invokArgs->args.clear(); 5007 invokArgs->args.clear();
@@ -4992,7 +5031,7 @@ private:
4992 newItemListAssign->expList.set(newItemList); 5031 newItemListAssign->expList.set(newItemList);
4993 auto newItemStatement = x->new_ptr<Statement_t>(); 5032 auto newItemStatement = x->new_ptr<Statement_t>();
4994 newItemStatement->content.set(newItemListAssign); 5033 newItemStatement->content.set(newItemListAssign);
4995 newBlock->statements.push_back(newItemStatement); 5034 newBlock->statementOrComments.push_back(newItemStatement);
4996 transformBlock(newBlock, out, usage, assignList, isRoot); 5035 transformBlock(newBlock, out, usage, assignList, isRoot);
4997 return; 5036 return;
4998 BLOCK_END 5037 BLOCK_END
@@ -5001,11 +5040,11 @@ private:
5001 auto newBlock = x->new_ptr<Block_t>(); 5040 auto newBlock = x->new_ptr<Block_t>();
5002 if (it != nodes.begin()) { 5041 if (it != nodes.begin()) {
5003 for (auto i = nodes.begin(); i != it; ++i) { 5042 for (auto i = nodes.begin(); i != it; ++i) {
5004 newBlock->statements.push_back(*i); 5043 newBlock->statementOrComments.push_back(*i);
5005 } 5044 }
5006 } 5045 }
5007 localAttrib->attrib.set(localAttrib->new_ptr<ConstAttrib_t>()); 5046 localAttrib->attrib.set(localAttrib->new_ptr<ConstAttrib_t>());
5008 newBlock->statements.push_back(*it); 5047 newBlock->statementOrComments.push_back(*it);
5009 x = localAttrib; 5048 x = localAttrib;
5010 auto followingBlock = x->new_ptr<Block_t>(); 5049 auto followingBlock = x->new_ptr<Block_t>();
5011 { 5050 {
@@ -5013,7 +5052,7 @@ private:
5013 ++next; 5052 ++next;
5014 if (next != nodes.end()) { 5053 if (next != nodes.end()) {
5015 for (auto i = next; i != nodes.end(); ++i) { 5054 for (auto i = next; i != nodes.end(); ++i) {
5016 followingBlock->statements.push_back(*i); 5055 followingBlock->statementOrComments.push_back(*i);
5017 } 5056 }
5018 } 5057 }
5019 } 5058 }
@@ -5035,13 +5074,13 @@ private:
5035 auto value = singleValueFrom(pCallExp); 5074 auto value = singleValueFrom(pCallExp);
5036 value->item.to<SimpleValue_t>()->value.to<Try_t>()->func.set(followingBlock); 5075 value->item.to<SimpleValue_t>()->value.to<Try_t>()->func.set(followingBlock);
5037 for (const auto& stmt : getCloses) { 5076 for (const auto& stmt : getCloses) {
5038 newBlock->statements.push_back(toAst<Statement_t>(stmt, x)); 5077 newBlock->statementOrComments.push_back(toAst<Statement_t>(stmt, x));
5039 } 5078 }
5040 newBlock->statements.push_back(pCallStmt); 5079 newBlock->statementOrComments.push_back(pCallStmt);
5041 for (const auto& stmt : doCloses) { 5080 for (const auto& stmt : doCloses) {
5042 newBlock->statements.push_back(toAst<Statement_t>(stmt, x)); 5081 newBlock->statementOrComments.push_back(toAst<Statement_t>(stmt, x));
5043 } 5082 }
5044 newBlock->statements.push_back(toAst<Statement_t>("if "s + okVar + " then return ... else error ..."s, x)); 5083 newBlock->statementOrComments.push_back(toAst<Statement_t>("if "s + okVar + " then return ... else error ..."s, x));
5045 transformBlock(newBlock, out, usage, assignList, isRoot); 5084 transformBlock(newBlock, out, usage, assignList, isRoot);
5046 return; 5085 return;
5047 } else if (auto expListAssign = stmt->content.as<ExpListAssign_t>(); 5086 } else if (auto expListAssign = stmt->content.as<ExpListAssign_t>();
@@ -5050,7 +5089,7 @@ private:
5050 auto newBlock = x->new_ptr<Block_t>(); 5089 auto newBlock = x->new_ptr<Block_t>();
5051 if (it != nodes.begin()) { 5090 if (it != nodes.begin()) {
5052 for (auto i = nodes.begin(); i != it; ++i) { 5091 for (auto i = nodes.begin(); i != it; ++i) {
5053 newBlock->statements.push_back(*i); 5092 newBlock->statementOrComments.push_back(*i);
5054 } 5093 }
5055 } 5094 }
5056 auto doBackcall = static_cast<SubBackcall_t*>(expListAssign->action.get()); 5095 auto doBackcall = static_cast<SubBackcall_t*>(expListAssign->action.get());
@@ -5067,12 +5106,11 @@ private:
5067 backcall->value.set(doBackcall->value); 5106 backcall->value.set(doBackcall->value);
5068 auto newStmt = backcall->new_ptr<Statement_t>(); 5107 auto newStmt = backcall->new_ptr<Statement_t>();
5069 newStmt->content.set(backcall); 5108 newStmt->content.set(backcall);
5070 newStmt->comments.dup(stmt->comments);
5071 newStmt->appendix.set(stmt->appendix); 5109 newStmt->appendix.set(stmt->appendix);
5072 newBlock->statements.push_back(newStmt); 5110 newBlock->statementOrComments.push_back(newStmt);
5073 auto ait = it; 5111 auto ait = it;
5074 for (auto i = ++ait; i != nodes.end(); ++i) { 5112 for (auto i = ++ait; i != nodes.end(); ++i) {
5075 newBlock->statements.push_back(*i); 5113 newBlock->statementOrComments.push_back(*i);
5076 } 5114 }
5077 transformBlock(newBlock, out, usage, assignList, isRoot); 5115 transformBlock(newBlock, out, usage, assignList, isRoot);
5078 return; 5116 return;
@@ -5184,7 +5222,7 @@ private:
5184 } 5222 }
5185 } 5223 }
5186 if (isRoot && !_info.moduleName.empty() && !_info.exportMacro) { 5224 if (isRoot && !_info.moduleName.empty() && !_info.exportMacro) {
5187 block->statements.push_front(toAst<Statement_t>(_info.moduleName + (_info.exportDefault ? "=nil"s : (_info.exportMetatable ? "=<>:{}"s : "={}"s)), block)); 5225 block->statementOrComments.push_front(toAst<Statement_t>(_info.moduleName + (_info.exportDefault ? "=nil"s : (_info.exportMetatable ? "=<>:{}"s : "={}"s)), block));
5188 } 5226 }
5189 switch (usage) { 5227 switch (usage) {
5190 case ExpUsage::Closure: 5228 case ExpUsage::Closure:
@@ -5246,9 +5284,14 @@ private:
5246 } 5284 }
5247 if (!nodes.empty()) { 5285 if (!nodes.empty()) {
5248 str_list temp; 5286 str_list temp;
5287 auto lastStmt = lastStatementFrom(nodes);
5249 for (auto node : nodes) { 5288 for (auto node : nodes) {
5289 if (auto comment = ast_cast<YueComment_t>(node)) {
5290 transformComment(comment, temp);
5291 continue;
5292 }
5250 auto transformNode = [&]() { 5293 auto transformNode = [&]() {
5251 currentScope().lastStatement = (node == nodes.back()) && currentScope().mode == GlobalMode::None; 5294 currentScope().lastStatement = (node == lastStmt) && currentScope().mode == GlobalMode::None;
5252 transformStatement(static_cast<Statement_t*>(node), temp); 5295 transformStatement(static_cast<Statement_t*>(node), temp);
5253 if (isRoot && !_rootDefs.empty()) { 5296 if (isRoot && !_rootDefs.empty()) {
5254 auto last = std::move(temp.back()); 5297 auto last = std::move(temp.back());
@@ -5293,7 +5336,7 @@ private:
5293 out.push_back(Empty); 5336 out.push_back(Empty);
5294 } 5337 }
5295 if (isRoot && !_info.moduleName.empty() && !_info.exportMacro) { 5338 if (isRoot && !_info.moduleName.empty() && !_info.exportMacro) {
5296 out.back().append(indent() + "return "s + _info.moduleName + nlr(block)); 5339 out.back().append(indent() + "return "s + _info.moduleName + nl(block));
5297 } 5340 }
5298 } 5341 }
5299 5342
@@ -5681,12 +5724,12 @@ private:
5681 } 5724 }
5682 } 5725 }
5683 transformValue(singleValue, out); 5726 transformValue(singleValue, out);
5684 out.back() = indent() + "return "s + out.back() + nlr(returnNode); 5727 out.back() = indent() + "return "s + out.back() + nl(returnNode);
5685 return; 5728 return;
5686 } else { 5729 } else {
5687 str_list temp; 5730 str_list temp;
5688 transformExpListLow(valueList, temp); 5731 transformExpListLow(valueList, temp);
5689 out.push_back(indent() + "return "s + temp.back() + nlr(returnNode)); 5732 out.push_back(indent() + "return "s + temp.back() + nl(returnNode));
5690 } 5733 }
5691 } else if (auto tableBlock = returnNode->valueList.as<TableBlock_t>()) { 5734 } else if (auto tableBlock = returnNode->valueList.as<TableBlock_t>()) {
5692 const auto& values = tableBlock->values.objects(); 5735 const auto& values = tableBlock->values.objects();
@@ -5694,10 +5737,10 @@ private:
5694 transformSpreadTable(values, out, ExpUsage::Return, nullptr, false); 5737 transformSpreadTable(values, out, ExpUsage::Return, nullptr, false);
5695 } else { 5738 } else {
5696 transformTable(values, out); 5739 transformTable(values, out);
5697 out.back() = indent() + "return "s + out.back() + nlr(returnNode); 5740 out.back() = indent() + "return "s + out.back() + nl(returnNode);
5698 } 5741 }
5699 } else { 5742 } else {
5700 out.push_back(indent() + "return"s + nll(returnNode)); 5743 out.push_back(indent() + "return"s + nl(returnNode));
5701 } 5744 }
5702 } 5745 }
5703 5746
@@ -5812,9 +5855,9 @@ private:
5812 assignment->action.set(assign); 5855 assignment->action.set(assign);
5813 transformAssignment(assignment, temp); 5856 transformAssignment(assignment, temp);
5814 popScope(); 5857 popScope();
5815 _buf << indent() << "if "sv << arg.name << " == nil then"sv << nll(def); 5858 _buf << indent() << "if "sv << arg.name << " == nil then"sv << nl(def);
5816 _buf << temp.back(); 5859 _buf << temp.back();
5817 _buf << indent() << "end"sv << nll(def); 5860 _buf << indent() << "end"sv << nl(def);
5818 temp.back() = clearBuf(); 5861 temp.back() = clearBuf();
5819 } 5862 }
5820 if (arg.assignment) { 5863 if (arg.assignment) {
@@ -5822,7 +5865,7 @@ private:
5822 for (const auto& name : names) { 5865 for (const auto& name : names) {
5823 forceAddToScope(name); 5866 forceAddToScope(name);
5824 } 5867 }
5825 temp.emplace_back(indent() + "local "s + join(names, ", "sv) + nll(def)); 5868 temp.emplace_back(indent() + "local "s + join(names, ", "sv) + nl(def));
5826 transformAssignment(arg.assignment, temp); 5869 transformAssignment(arg.assignment, temp);
5827 } 5870 }
5828 if (varNames.empty()) 5871 if (varNames.empty())
@@ -5978,7 +6021,7 @@ private:
5978 case ExpUsage::Return: 6021 case ExpUsage::Return:
5979 transformParens(parens, out); 6022 transformParens(parens, out);
5980 out.back().insert(0, indent() + "return "s); 6023 out.back().insert(0, indent() + "return "s);
5981 out.back().append(nlr(x)); 6024 out.back().append(nl(x));
5982 break; 6025 break;
5983 default: 6026 default:
5984 transformParens(parens, out); 6027 transformParens(parens, out);
@@ -6049,7 +6092,7 @@ private:
6049 } 6092 }
6050 } 6093 }
6051 if (isScoped) { 6094 if (isScoped) {
6052 temp.push_back(indent() + "do"s + nll(x)); 6095 temp.push_back(indent() + "do"s + nl(x));
6053 pushScope(); 6096 pushScope();
6054 } 6097 }
6055 objVar = getUnusedName("_obj_"sv); 6098 objVar = getUnusedName("_obj_"sv);
@@ -6109,9 +6152,9 @@ private:
6109 _buf << typeVar << "=type "sv << objVar; 6152 _buf << typeVar << "=type "sv << objVar;
6110 auto typeAssign = toAst<ExpListAssign_t>(clearBuf(), partOne); 6153 auto typeAssign = toAst<ExpListAssign_t>(clearBuf(), partOne);
6111 transformAssignment(typeAssign, temp); 6154 transformAssignment(typeAssign, temp);
6112 _buf << indent() << "if \"table\" == " << typeVar << " or \"userdata\" == "sv << typeVar << " then"sv << nll(x); 6155 _buf << indent() << "if \"table\" == " << typeVar << " or \"userdata\" == "sv << typeVar << " then"sv << nl(x);
6113 } else { 6156 } else {
6114 _buf << indent() << "if "sv << objVar << " ~= nil then"sv << nll(x); 6157 _buf << indent() << "if "sv << objVar << " ~= nil then"sv << nl(x);
6115 } 6158 }
6116 temp.push_back(clearBuf()); 6159 temp.push_back(clearBuf());
6117 pushScope(); 6160 pushScope();
@@ -6147,15 +6190,15 @@ private:
6147 } 6190 }
6148 } 6191 }
6149 popScope(); 6192 popScope();
6150 temp.push_back(indent() + "end"s + nlr(x)); 6193 temp.push_back(indent() + "end"s + nl(x));
6151 switch (usage) { 6194 switch (usage) {
6152 case ExpUsage::Return: 6195 case ExpUsage::Return:
6153 temp.push_back(indent() + "return nil"s + nlr(x)); 6196 temp.push_back(indent() + "return nil"s + nl(x));
6154 break; 6197 break;
6155 case ExpUsage::Closure: 6198 case ExpUsage::Closure:
6156 temp.push_back(indent() + "return nil"s + nlr(x)); 6199 temp.push_back(indent() + "return nil"s + nl(x));
6157 popScope(); 6200 popScope();
6158 *funcStart = anonFuncStart() + nll(x); 6201 *funcStart = anonFuncStart() + nl(x);
6159 temp.push_back(indent() + anonFuncEnd()); 6202 temp.push_back(indent() + anonFuncEnd());
6160 popAnonVarArg(); 6203 popAnonVarArg();
6161 popFunctionScope(); 6204 popFunctionScope();
@@ -6165,7 +6208,7 @@ private:
6165 } 6208 }
6166 if (isScoped) { 6209 if (isScoped) {
6167 popScope(); 6210 popScope();
6168 temp.push_back(indent() + "end"s + nlr(x)); 6211 temp.push_back(indent() + "end"s + nl(x));
6169 } 6212 }
6170 out.push_back(join(temp)); 6213 out.push_back(join(temp));
6171 return true; 6214 return true;
@@ -6182,7 +6225,7 @@ private:
6182 switch (usage) { 6225 switch (usage) {
6183 case ExpUsage::Assignment: 6226 case ExpUsage::Assignment:
6184 if (isScoped) { 6227 if (isScoped) {
6185 temp.push_back(indent() + "do"s + nll(x)); 6228 temp.push_back(indent() + "do"s + nl(x));
6186 pushScope(); 6229 pushScope();
6187 } 6230 }
6188 break; 6231 break;
@@ -6260,12 +6303,12 @@ private:
6260 case ExpUsage::Assignment: 6303 case ExpUsage::Assignment:
6261 if (isScoped) { 6304 if (isScoped) {
6262 popScope(); 6305 popScope();
6263 temp.push_back(indent() + "end"s + nlr(x)); 6306 temp.push_back(indent() + "end"s + nl(x));
6264 } 6307 }
6265 break; 6308 break;
6266 case ExpUsage::Closure: 6309 case ExpUsage::Closure:
6267 popScope(); 6310 popScope();
6268 *funcStart = anonFuncStart() + nll(x); 6311 *funcStart = anonFuncStart() + nl(x);
6269 temp.push_back(indent() + anonFuncEnd()); 6312 temp.push_back(indent() + anonFuncEnd());
6270 popAnonVarArg(); 6313 popAnonVarArg();
6271 popFunctionScope(); 6314 popFunctionScope();
@@ -6341,7 +6384,7 @@ private:
6341 pushScope(); 6384 pushScope();
6342 } else if (usage != ExpUsage::Return) { 6385 } else if (usage != ExpUsage::Return) {
6343 if (isScoped) { 6386 if (isScoped) {
6344 temp.push_back(indent() + "do"s + nll(x)); 6387 temp.push_back(indent() + "do"s + nl(x));
6345 pushScope(); 6388 pushScope();
6346 } 6389 }
6347 } 6390 }
@@ -6378,7 +6421,7 @@ private:
6378 returnNode->valueList.set(values); 6421 returnNode->valueList.set(values);
6379 transformReturn(returnNode, temp); 6422 transformReturn(returnNode, temp);
6380 popScope(); 6423 popScope();
6381 *funcStart = anonFuncStart() + nll(x); 6424 *funcStart = anonFuncStart() + nl(x);
6382 temp.push_back(indent() + anonFuncEnd()); 6425 temp.push_back(indent() + anonFuncEnd());
6383 popAnonVarArg(); 6426 popAnonVarArg();
6384 popFunctionScope(); 6427 popFunctionScope();
@@ -6402,7 +6445,7 @@ private:
6402 transformAssignment(assignment, temp); 6445 transformAssignment(assignment, temp);
6403 if (isScoped) { 6446 if (isScoped) {
6404 popScope(); 6447 popScope();
6405 temp.push_back(indent() + "end"s + nlr(x)); 6448 temp.push_back(indent() + "end"s + nl(x));
6406 } 6449 }
6407 break; 6450 break;
6408 } 6451 }
@@ -6410,7 +6453,7 @@ private:
6410 transformExp(newChainExp, temp, usage); 6453 transformExp(newChainExp, temp, usage);
6411 if (isScoped) { 6454 if (isScoped) {
6412 popScope(); 6455 popScope();
6413 temp.push_back(indent() + "end"s + nlr(x)); 6456 temp.push_back(indent() + "end"s + nl(x));
6414 } 6457 }
6415 break; 6458 break;
6416 } 6459 }
@@ -6515,7 +6558,7 @@ private:
6515 assignment->action.set(assign); 6558 assignment->action.set(assign);
6516 auto stmt = x->new_ptr<Statement_t>(); 6559 auto stmt = x->new_ptr<Statement_t>();
6517 stmt->content.set(assignment); 6560 stmt->content.set(assignment);
6518 block->statements.push_back(stmt); 6561 block->statementOrComments.push_back(stmt);
6519 } 6562 }
6520 } 6563 }
6521 ast_ptr<false, Exp_t> nexp; 6564 ast_ptr<false, Exp_t> nexp;
@@ -6561,7 +6604,7 @@ private:
6561 expListAssign->expList.set(expList); 6604 expListAssign->expList.set(expList);
6562 auto stmt = x->new_ptr<Statement_t>(); 6605 auto stmt = x->new_ptr<Statement_t>();
6563 stmt->content.set(expListAssign); 6606 stmt->content.set(expListAssign);
6564 block->statements.push_back(stmt); 6607 block->statementOrComments.push_back(stmt);
6565 } 6608 }
6566 switch (usage) { 6609 switch (usage) {
6567 case ExpUsage::Common: 6610 case ExpUsage::Common:
@@ -6575,7 +6618,7 @@ private:
6575 default: 6618 default:
6576 break; 6619 break;
6577 } 6620 }
6578 if (block->statements.size() == 1) { 6621 if (block->statementOrComments.size() == 1) {
6579 transformExp(nexp, out, usage, assignList); 6622 transformExp(nexp, out, usage, assignList);
6580 } else { 6623 } else {
6581 auto body = x->new_ptr<Body_t>(); 6624 auto body = x->new_ptr<Body_t>();
@@ -6668,8 +6711,8 @@ private:
6668 auto stmt2 = x->new_ptr<Statement_t>(); 6711 auto stmt2 = x->new_ptr<Statement_t>();
6669 stmt2->content.set(expListAssign); 6712 stmt2->content.set(expListAssign);
6670 auto block = x->new_ptr<Block_t>(); 6713 auto block = x->new_ptr<Block_t>();
6671 block->statements.push_back(stmt1); 6714 block->statementOrComments.push_back(stmt1);
6672 block->statements.push_back(stmt2); 6715 block->statementOrComments.push_back(stmt2);
6673 auto body = x->new_ptr<Body_t>(); 6716 auto body = x->new_ptr<Body_t>();
6674 body->content.set(block); 6717 body->content.set(block);
6675 auto doNode = x->new_ptr<Do_t>(); 6718 auto doNode = x->new_ptr<Do_t>();
@@ -6770,10 +6813,10 @@ private:
6770 } 6813 }
6771 switch (usage) { 6814 switch (usage) {
6772 case ExpUsage::Common: 6815 case ExpUsage::Common:
6773 out.push_back(indent() + join(temp) + nll(x)); 6816 out.push_back(indent() + join(temp) + nl(x));
6774 break; 6817 break;
6775 case ExpUsage::Return: 6818 case ExpUsage::Return:
6776 out.push_back(indent() + "return "s + join(temp) + nll(x)); 6819 out.push_back(indent() + "return "s + join(temp) + nl(x));
6777 break; 6820 break;
6778 case ExpUsage::Assignment: YUEE("invalid expression usage", x); break; 6821 case ExpUsage::Assignment: YUEE("invalid expression usage", x); break;
6779 default: 6822 default:
@@ -7099,8 +7142,8 @@ private:
7099 throw CompileError("lua macro is not expanding to valid block\n"s + err, x); 7142 throw CompileError("lua macro is not expanding to valid block\n"s + err, x);
7100 } 7143 }
7101 if (!codes.empty()) { 7144 if (!codes.empty()) {
7102 codes.insert(0, indent() + "do"s + nll(chainValue)); 7145 codes.insert(0, indent() + "do"s + nl(chainValue));
7103 codes.append(_newLine + indent() + "end"s + nlr(chainValue)); 7146 codes.append(_newLine + indent() + "end"s + nl(chainValue));
7104 } 7147 }
7105 return {nullptr, nullptr, std::move(codes), std::move(localVars)}; 7148 return {nullptr, nullptr, std::move(codes), std::move(localVars)};
7106 } else { 7149 } else {
@@ -7189,7 +7232,7 @@ private:
7189 auto stmt = x->new_ptr<Statement_t>(); 7232 auto stmt = x->new_ptr<Statement_t>();
7190 stmt->content.set(exps); 7233 stmt->content.set(exps);
7191 auto block = x->new_ptr<Block_t>(); 7234 auto block = x->new_ptr<Block_t>();
7192 block->statements.push_back(stmt); 7235 block->statementOrComments.push_back(stmt);
7193 info.node.set(block); 7236 info.node.set(block);
7194 } else { 7237 } else {
7195 info.node.set(exp); 7238 info.node.set(exp);
@@ -7226,7 +7269,7 @@ private:
7226 return; 7269 return;
7227 } 7270 }
7228 if (usage == ExpUsage::Common || (usage == ExpUsage::Return && node.is<Block_t>())) { 7271 if (usage == ExpUsage::Common || (usage == ExpUsage::Return && node.is<Block_t>())) {
7229 if (node.to<Block_t>()->statements.empty()) { 7272 if (node.to<Block_t>()->statementOrComments.empty()) {
7230 out.push_back(Empty); 7273 out.push_back(Empty);
7231 } else { 7274 } else {
7232 auto doBody = node->new_ptr<Body_t>(); 7275 auto doBody = node->new_ptr<Body_t>();
@@ -7408,7 +7451,7 @@ private:
7408 auto assignment = assignmentFrom(toAst<Exp_t>(checkVar, inExp), newExp(inExp, inExp), inExp); 7451 auto assignment = assignmentFrom(toAst<Exp_t>(checkVar, inExp), newExp(inExp, inExp), inExp);
7409 auto stmt = x->new_ptr<Statement_t>(); 7452 auto stmt = x->new_ptr<Statement_t>();
7410 stmt->content.set(assignment); 7453 stmt->content.set(assignment);
7411 block->statements.push_back(stmt); 7454 block->statementOrComments.push_back(stmt);
7412 } 7455 }
7413 if (varName.empty()) { 7456 if (varName.empty()) {
7414 auto newUnaryExp = x->new_ptr<UnaryExp_t>(); 7457 auto newUnaryExp = x->new_ptr<UnaryExp_t>();
@@ -7420,7 +7463,7 @@ private:
7420 auto assignment = assignmentFrom(assignExp, exp, x); 7463 auto assignment = assignmentFrom(assignExp, exp, x);
7421 auto stmt = x->new_ptr<Statement_t>(); 7464 auto stmt = x->new_ptr<Statement_t>();
7422 stmt->content.set(assignment); 7465 stmt->content.set(assignment);
7423 block->statements.push_back(stmt); 7466 block->statementOrComments.push_back(stmt);
7424 } 7467 }
7425 auto findVar = getUnusedName("_find_"); 7468 auto findVar = getUnusedName("_find_");
7426 auto itemVar = getUnusedName("_item_"); 7469 auto itemVar = getUnusedName("_item_");
@@ -7436,7 +7479,7 @@ private:
7436 } 7479 }
7437 auto blockStr = clearBuf(); 7480 auto blockStr = clearBuf();
7438 auto checkBlock = toAst<Block_t>(blockStr, inExp); 7481 auto checkBlock = toAst<Block_t>(blockStr, inExp);
7439 block->statements.dup(checkBlock->statements); 7482 block->statementOrComments.dup(checkBlock->statementOrComments);
7440 auto body = x->new_ptr<Body_t>(); 7483 auto body = x->new_ptr<Body_t>();
7441 body->content.set(block); 7484 body->content.set(block);
7442 auto doNode = x->new_ptr<Do_t>(); 7485 auto doNode = x->new_ptr<Do_t>();
@@ -7456,16 +7499,16 @@ private:
7456 } else { 7499 } else {
7457 auto arrayCheck = [&](bool exist) { 7500 auto arrayCheck = [&](bool exist) {
7458 auto indexVar = getUnusedName("_index_"); 7501 auto indexVar = getUnusedName("_index_");
7459 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << checkVar << " do"sv << nll(x); 7502 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << checkVar << " do"sv << nl(x);
7460 incIndentOffset(); 7503 incIndentOffset();
7461 _buf << indent() << "if "sv << checkVar << '[' << indexVar << "] == "sv << varName << " then"sv << nll(x); 7504 _buf << indent() << "if "sv << checkVar << '[' << indexVar << "] == "sv << varName << " then"sv << nl(x);
7462 incIndentOffset(); 7505 incIndentOffset();
7463 _buf << indent() << "return "sv << (exist ? "true"sv : "false"sv) << nll(x); 7506 _buf << indent() << "return "sv << (exist ? "true"sv : "false"sv) << nl(x);
7464 decIndentOffset(); 7507 decIndentOffset();
7465 _buf << indent() << "end"sv << nll(x); 7508 _buf << indent() << "end"sv << nl(x);
7466 decIndentOffset(); 7509 decIndentOffset();
7467 _buf << indent() << "end"sv << nll(x); 7510 _buf << indent() << "end"sv << nl(x);
7468 _buf << indent() << "return "sv << (exist ? "false"sv : "true"sv) << nll(x); 7511 _buf << indent() << "return "sv << (exist ? "false"sv : "true"sv) << nl(x);
7469 temp.push_back(clearBuf()); 7512 temp.push_back(clearBuf());
7470 }; 7513 };
7471 bool useShortCheck = (usage == ExpUsage::Closure) && !varName.empty() && !checkVar.empty() && isLocal(checkVar); 7514 bool useShortCheck = (usage == ExpUsage::Closure) && !varName.empty() && !checkVar.empty() && isLocal(checkVar);
@@ -7481,7 +7524,7 @@ private:
7481 pushAnonVarArg(); 7524 pushAnonVarArg();
7482 pushScope(); 7525 pushScope();
7483 arrayCheck(true); 7526 arrayCheck(true);
7484 temp.push_front("(#"s + checkVar + " > 0 and "s + anonFuncStart() + nll(x)); 7527 temp.push_front("(#"s + checkVar + " > 0 and "s + anonFuncStart() + nl(x));
7485 popScope(); 7528 popScope();
7486 temp.push_back(indent() + anonFuncEnd() + ')'); 7529 temp.push_back(indent() + anonFuncEnd() + ')');
7487 if (unary_exp->inExp->not_) { 7530 if (unary_exp->inExp->not_) {
@@ -7518,7 +7561,7 @@ private:
7518 arrayCheck(!unary_exp->inExp->not_); 7561 arrayCheck(!unary_exp->inExp->not_);
7519 } else { 7562 } else {
7520 arrayCheck(!unary_exp->inExp->not_); 7563 arrayCheck(!unary_exp->inExp->not_);
7521 temp.push_front(anonFuncStart() + nll(x)); 7564 temp.push_front(anonFuncStart() + nl(x));
7522 popScope(); 7565 popScope();
7523 temp.push_back(indent() + anonFuncEnd()); 7566 temp.push_back(indent() + anonFuncEnd());
7524 popAnonVarArg(); 7567 popAnonVarArg();
@@ -7558,7 +7601,7 @@ private:
7558 pushScope(); 7601 pushScope();
7559 } else if (usage == ExpUsage::Assignment) { 7602 } else if (usage == ExpUsage::Assignment) {
7560 if (isScoped) { 7603 if (isScoped) {
7561 temp.push_back(indent() + "do"s + nll(x)); 7604 temp.push_back(indent() + "do"s + nl(x));
7562 pushScope(); 7605 pushScope();
7563 } 7606 }
7564 } 7607 }
@@ -7598,10 +7641,10 @@ private:
7598 if (unary_exp->inExp->not_) { 7641 if (unary_exp->inExp->not_) {
7599 _buf << ")"sv; 7642 _buf << ")"sv;
7600 } 7643 }
7601 _buf << nll(x); 7644 _buf << nl(x);
7602 temp.push_back(clearBuf()); 7645 temp.push_back(clearBuf());
7603 if (usage == ExpUsage::Closure) { 7646 if (usage == ExpUsage::Closure) {
7604 temp.push_front(anonFuncStart() + nll(x)); 7647 temp.push_front(anonFuncStart() + nl(x));
7605 popScope(); 7648 popScope();
7606 temp.push_back(indent() + anonFuncEnd()); 7649 temp.push_back(indent() + anonFuncEnd());
7607 out.push_back(join(temp)); 7650 out.push_back(join(temp));
@@ -7610,7 +7653,7 @@ private:
7610 } else if (usage == ExpUsage::Assignment) { 7653 } else if (usage == ExpUsage::Assignment) {
7611 if (isScoped) { 7654 if (isScoped) {
7612 popScope(); 7655 popScope();
7613 temp.push_back(indent() + "end"s + nll(x)); 7656 temp.push_back(indent() + "end"s + nl(x));
7614 } 7657 }
7615 out.push_back(join(temp)); 7658 out.push_back(join(temp));
7616 } else { 7659 } else {
@@ -7644,7 +7687,7 @@ private:
7644 } 7687 }
7645 _buf << ')'; 7688 _buf << ')';
7646 if (usage == ExpUsage::Assignment || usage == ExpUsage::Return) { 7689 if (usage == ExpUsage::Assignment || usage == ExpUsage::Return) {
7647 _buf << nll(discrete); 7690 _buf << nl(discrete);
7648 } 7691 }
7649 out.push_back(clearBuf()); 7692 out.push_back(clearBuf());
7650 } 7693 }
@@ -7764,7 +7807,7 @@ private:
7764 forceAddToScope(tableVar); 7807 forceAddToScope(tableVar);
7765 auto it = values.begin(); 7808 auto it = values.begin();
7766 if (ast_is<SpreadExp_t, SpreadListExp_t>(*it)) { 7809 if (ast_is<SpreadExp_t, SpreadListExp_t>(*it)) {
7767 temp.push_back(indent() + "local "s + tableVar + " = { }"s + nll(x)); 7810 temp.push_back(indent() + "local "s + tableVar + " = { }"s + nl(x));
7768 } else { 7811 } else {
7769 auto initialTab = x->new_ptr<TableLit_t>(); 7812 auto initialTab = x->new_ptr<TableLit_t>();
7770 while (it != values.end() && !ast_is<SpreadExp_t, SpreadListExp_t>(*it)) { 7813 while (it != values.end() && !ast_is<SpreadExp_t, SpreadListExp_t>(*it)) {
@@ -7772,7 +7815,7 @@ private:
7772 ++it; 7815 ++it;
7773 } 7816 }
7774 transformTable(initialTab->values.objects(), temp); 7817 transformTable(initialTab->values.objects(), temp);
7775 temp.back() = indent() + "local "s + tableVar + " = "s + temp.back() + nll(*it); 7818 temp.back() = indent() + "local "s + tableVar + " = "s + temp.back() + nl(*it);
7776 } 7819 }
7777 for (; it != values.end(); ++it) { 7820 for (; it != values.end(); ++it) {
7778 auto item = *it; 7821 auto item = *it;
@@ -7792,7 +7835,7 @@ private:
7792 transformAssignment(assignment, temp); 7835 transformAssignment(assignment, temp);
7793 } 7836 }
7794 forceAddToScope(indexVar); 7837 forceAddToScope(indexVar);
7795 temp.push_back(indent() + "local "s + indexVar + " = 1"s + nll(item)); 7838 temp.push_back(indent() + "local "s + indexVar + " = 1"s + nl(item));
7796 _buf << "for "sv << keyVar << ',' << valueVar << " in pairs "sv << objVar 7839 _buf << "for "sv << keyVar << ',' << valueVar << " in pairs "sv << objVar
7797 << "\n\tif "sv << indexVar << "=="sv << keyVar 7840 << "\n\tif "sv << indexVar << "=="sv << keyVar
7798 << "\n\t\t"sv << tableVar << "[]="sv << valueVar 7841 << "\n\t\t"sv << tableVar << "[]="sv << valueVar
@@ -7816,7 +7859,7 @@ private:
7816 transformAssignment(assignment, temp); 7859 transformAssignment(assignment, temp);
7817 } 7860 }
7818 forceAddToScope(indexVar); 7861 forceAddToScope(indexVar);
7819 temp.push_back(indent() + "local "s + indexVar + " = #"s + tableVar + " + 1"s + nll(item)); 7862 temp.push_back(indent() + "local "s + indexVar + " = #"s + tableVar + " + 1"s + nl(item));
7820 _buf << "for "sv << valueVar << " in *"sv << objVar 7863 _buf << "for "sv << valueVar << " in *"sv << objVar
7821 << "\n\t"sv << tableVar << '[' << indexVar << "]="sv << valueVar 7864 << "\n\t"sv << tableVar << '[' << indexVar << "]="sv << valueVar
7822 << "\n\t"sv << indexVar << "+=1"sv; 7865 << "\n\t"sv << indexVar << "+=1"sv;
@@ -7999,9 +8042,9 @@ private:
7999 break; 8042 break;
8000 case ExpUsage::Closure: { 8043 case ExpUsage::Closure: {
8001 out.push_back(join(temp)); 8044 out.push_back(join(temp));
8002 out.back().append(indent() + "return "s + tableVar + nlr(x)); 8045 out.back().append(indent() + "return "s + tableVar + nl(x));
8003 popScope(); 8046 popScope();
8004 out.back().insert(0, anonFuncStart() + nll(x)); 8047 out.back().insert(0, anonFuncStart() + nl(x));
8005 out.back().append(indent() + anonFuncEnd()); 8048 out.back().append(indent() + anonFuncEnd());
8006 popAnonVarArg(); 8049 popAnonVarArg();
8007 popFunctionScope(); 8050 popFunctionScope();
@@ -8017,13 +8060,13 @@ private:
8017 if (extraScope) popScope(); 8060 if (extraScope) popScope();
8018 out.push_back(join(temp)); 8061 out.push_back(join(temp));
8019 if (extraScope) { 8062 if (extraScope) {
8020 out.back() = indent() + "do"s + nll(x) + out.back() + indent() + "end"s + nlr(x); 8063 out.back() = indent() + "do"s + nl(x) + out.back() + indent() + "end"s + nl(x);
8021 } 8064 }
8022 break; 8065 break;
8023 } 8066 }
8024 case ExpUsage::Return: 8067 case ExpUsage::Return:
8025 out.push_back(join(temp)); 8068 out.push_back(join(temp));
8026 out.back().append(indent() + "return "s + tableVar + nlr(x)); 8069 out.back().append(indent() + "return "s + tableVar + nl(x));
8027 break; 8070 break;
8028 default: 8071 default:
8029 break; 8072 break;
@@ -8144,11 +8187,11 @@ private:
8144 default: YUEE("AST node mismatch", item); break; 8187 default: YUEE("AST node mismatch", item); break;
8145 } 8188 }
8146 if (!isMetamethod) { 8189 if (!isMetamethod) {
8147 temp.back() = indent() + (value == values.back() ? temp.back() : temp.back() + ',') + nll(value); 8190 temp.back() = indent() + (value == values.back() ? temp.back() : temp.back() + ',') + nl(value);
8148 } 8191 }
8149 } 8192 }
8150 if (metatable->pairs.empty() && !metatableItem) { 8193 if (metatable->pairs.empty() && !metatableItem) {
8151 out.push_back('{' + nll(x) + join(temp)); 8194 out.push_back('{' + nl(x) + join(temp));
8152 decIndentOffset(); 8195 decIndentOffset();
8153 out.back() += (indent() + '}'); 8196 out.back() += (indent() + '}');
8154 } else { 8197 } else {
@@ -8158,7 +8201,7 @@ private:
8158 decIndentOffset(); 8201 decIndentOffset();
8159 tabStr += "{ }"sv; 8202 tabStr += "{ }"sv;
8160 } else { 8203 } else {
8161 tabStr += ('{' + nll(x) + join(temp)); 8204 tabStr += ('{' + nl(x) + join(temp));
8162 decIndentOffset(); 8205 decIndentOffset();
8163 tabStr += (indent() + '}'); 8206 tabStr += (indent() + '}');
8164 } 8207 }
@@ -8213,7 +8256,7 @@ private:
8213 break; 8256 break;
8214 case id<Exp_t>(): 8257 case id<Exp_t>():
8215 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); 8258 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure);
8216 temp.back() = indent() + "if "s + temp.back() + " then"s + nll(item); 8259 temp.back() = indent() + "if "s + temp.back() + " then"s + nl(item);
8217 pushScope(); 8260 pushScope();
8218 break; 8261 break;
8219 default: YUEE("AST node mismatch", item); break; 8262 default: YUEE("AST node mismatch", item); break;
@@ -8235,7 +8278,7 @@ private:
8235 _buf << join(temp) << value; 8278 _buf << join(temp) << value;
8236 for (size_t i = 0; i < compInner->items.objects().size(); ++i) { 8279 for (size_t i = 0; i < compInner->items.objects().size(); ++i) {
8237 popScope(); 8280 popScope();
8238 _buf << indent() << "end"sv << nll(comp); 8281 _buf << indent() << "end"sv << nl(comp);
8239 } 8282 }
8240 out.push_back(clearBuf()); 8283 out.push_back(clearBuf());
8241 } 8284 }
@@ -8333,7 +8376,7 @@ private:
8333 break; 8376 break;
8334 case id<Exp_t>(): 8377 case id<Exp_t>():
8335 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); 8378 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure);
8336 temp.back() = indent() + "if "s + temp.back() + " then"s + nll(item); 8379 temp.back() = indent() + "if "s + temp.back() + " then"s + nl(item);
8337 pushScope(); 8380 pushScope();
8338 break; 8381 break;
8339 default: YUEE("AST node mismatch", item); break; 8382 default: YUEE("AST node mismatch", item); break;
@@ -8353,27 +8396,27 @@ private:
8353 for (size_t i = 0; i < compInner->items.objects().size(); ++i) { 8396 for (size_t i = 0; i < compInner->items.objects().size(); ++i) {
8354 popScope(); 8397 popScope();
8355 } 8398 }
8356 _buf << indent() << "local "sv << accumVar << " = { }"sv << nll(comp); 8399 _buf << indent() << "local "sv << accumVar << " = { }"sv << nl(comp);
8357 if (isSpread) { 8400 if (isSpread) {
8358 _buf << join(temp); 8401 _buf << join(temp);
8359 _buf << assignStr; 8402 _buf << assignStr;
8360 } else { 8403 } else {
8361 _buf << indent() << "local "sv << lenVar << " = 1"sv << nll(comp); 8404 _buf << indent() << "local "sv << lenVar << " = 1"sv << nl(comp);
8362 _buf << join(temp); 8405 _buf << join(temp);
8363 _buf << assignStr; 8406 _buf << assignStr;
8364 _buf << indent(int(temp.size())) << lenVar << " = "sv << lenVar << " + 1"sv << nll(comp); 8407 _buf << indent(int(temp.size())) << lenVar << " = "sv << lenVar << " + 1"sv << nl(comp);
8365 } 8408 }
8366 for (int ind = int(temp.size()) - 1; ind > -1; --ind) { 8409 for (int ind = int(temp.size()) - 1; ind > -1; --ind) {
8367 _buf << indent(ind) << "end"sv << nll(comp); 8410 _buf << indent(ind) << "end"sv << nl(comp);
8368 } 8411 }
8369 switch (usage) { 8412 switch (usage) {
8370 case ExpUsage::Common: 8413 case ExpUsage::Common:
8371 break; 8414 break;
8372 case ExpUsage::Closure: { 8415 case ExpUsage::Closure: {
8373 out.push_back(clearBuf()); 8416 out.push_back(clearBuf());
8374 out.back().append(indent() + "return "s + accumVar + nlr(comp)); 8417 out.back().append(indent() + "return "s + accumVar + nl(comp));
8375 popScope(); 8418 popScope();
8376 out.back().insert(0, anonFuncStart() + nll(comp)); 8419 out.back().insert(0, anonFuncStart() + nl(comp));
8377 out.back().append(indent() + anonFuncEnd()); 8420 out.back().append(indent() + anonFuncEnd());
8378 popAnonVarArg(); 8421 popAnonVarArg();
8379 popFunctionScope(); 8422 popFunctionScope();
@@ -8390,13 +8433,13 @@ private:
8390 out.back().append(temp.back()); 8433 out.back().append(temp.back());
8391 if (extraScope) { 8434 if (extraScope) {
8392 popScope(); 8435 popScope();
8393 out.back() = indent() + "do"s + nll(comp) + out.back() + indent() + "end"s + nlr(comp); 8436 out.back() = indent() + "do"s + nl(comp) + out.back() + indent() + "end"s + nl(comp);
8394 } 8437 }
8395 break; 8438 break;
8396 } 8439 }
8397 case ExpUsage::Return: 8440 case ExpUsage::Return:
8398 out.push_back(clearBuf()); 8441 out.push_back(clearBuf());
8399 out.back().append(indent() + "return "s + accumVar + nlr(comp)); 8442 out.back().append(indent() + "return "s + accumVar + nl(comp));
8400 break; 8443 break;
8401 default: 8444 default:
8402 break; 8445 break;
@@ -8512,13 +8555,13 @@ private:
8512 std::string prefix; 8555 std::string prefix;
8513 if (!inClosure && needScope) { 8556 if (!inClosure && needScope) {
8514 extraScope = true; 8557 extraScope = true;
8515 prefix = indent() + "do"s + nll(x); 8558 prefix = indent() + "do"s + nl(x);
8516 pushScope(); 8559 pushScope();
8517 } 8560 }
8518 listVar = getUnusedName("_list_"sv); 8561 listVar = getUnusedName("_list_"sv);
8519 varBefore.push_back(listVar); 8562 varBefore.push_back(listVar);
8520 transformChainValue(chain, temp, ExpUsage::Closure); 8563 transformChainValue(chain, temp, ExpUsage::Closure);
8521 _buf << prefix << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); 8564 _buf << prefix << indent() << "local "sv << listVar << " = "sv << temp.back() << nl(nameList);
8522 } 8565 }
8523 if (startValue.empty()) { 8566 if (startValue.empty()) {
8524 startValue = "1"s; 8567 startValue = "1"s;
@@ -8529,15 +8572,15 @@ private:
8529 std::string prefix; 8572 std::string prefix;
8530 if (!extraScope && !inClosure && needScope) { 8573 if (!extraScope && !inClosure && needScope) {
8531 extraScope = true; 8574 extraScope = true;
8532 prefix = indent() + "do"s + nll(x); 8575 prefix = indent() + "do"s + nl(x);
8533 pushScope(); 8576 pushScope();
8534 } 8577 }
8535 minVar = getUnusedName("_min_"sv); 8578 minVar = getUnusedName("_min_"sv);
8536 varBefore.push_back(minVar); 8579 varBefore.push_back(minVar);
8537 if (startStatus == NumState::Negtive) { 8580 if (startStatus == NumState::Negtive) {
8538 _buf << prefix << indent() << "local "sv << minVar << " = "sv << "#"sv << listVar << " + "sv << startValue << " + 1"sv << nll(nameList); 8581 _buf << prefix << indent() << "local "sv << minVar << " = "sv << "#"sv << listVar << " + "sv << startValue << " + 1"sv << nl(nameList);
8539 } else { 8582 } else {
8540 _buf << prefix << indent() << "local "sv << minVar << " = "sv << startValue << nll(nameList); 8583 _buf << prefix << indent() << "local "sv << minVar << " = "sv << startValue << nl(nameList);
8541 } 8584 }
8542 } 8585 }
8543 bool defaultStop = false; 8586 bool defaultStop = false;
@@ -8550,22 +8593,22 @@ private:
8550 std::string prefix; 8593 std::string prefix;
8551 if (!extraScope && !inClosure && needScope) { 8594 if (!extraScope && !inClosure && needScope) {
8552 extraScope = true; 8595 extraScope = true;
8553 prefix = indent() + "do"s + nll(x); 8596 prefix = indent() + "do"s + nl(x);
8554 pushScope(); 8597 pushScope();
8555 } 8598 }
8556 maxVar = getUnusedName("_max_"sv); 8599 maxVar = getUnusedName("_max_"sv);
8557 varBefore.push_back(maxVar); 8600 varBefore.push_back(maxVar);
8558 if (stopStatus == NumState::Negtive) { 8601 if (stopStatus == NumState::Negtive) {
8559 _buf << indent() << "local "sv << maxVar << " = "sv << "#"sv << listVar << " + "sv << stopValue << " + 1"sv << nll(nameList); 8602 _buf << indent() << "local "sv << maxVar << " = "sv << "#"sv << listVar << " + "sv << stopValue << " + 1"sv << nl(nameList);
8560 } else { 8603 } else {
8561 _buf << prefix << indent() << "local "sv << maxVar << " = "sv << stopValue << nll(nameList); 8604 _buf << prefix << indent() << "local "sv << maxVar << " = "sv << stopValue << nl(nameList);
8562 } 8605 }
8563 } 8606 }
8564 if (startStatus == NumState::Unknown) { 8607 if (startStatus == NumState::Unknown) {
8565 _buf << indent() << minVar << " = "sv << minVar << " < 0 and #"sv << listVar << " + "sv << minVar << " + 1 or "sv << minVar << nll(nameList); 8608 _buf << indent() << minVar << " = "sv << minVar << " < 0 and #"sv << listVar << " + "sv << minVar << " + 1 or "sv << minVar << nl(nameList);
8566 } 8609 }
8567 if (!defaultStop && stopStatus == NumState::Unknown) { 8610 if (!defaultStop && stopStatus == NumState::Unknown) {
8568 _buf << indent() << maxVar << " = "sv << maxVar << " < 0 and #"sv << listVar << " + "sv << maxVar << " + 1 or "sv << maxVar << nll(nameList); 8611 _buf << indent() << maxVar << " = "sv << maxVar << " < 0 and #"sv << listVar << " + "sv << maxVar << " + 1 or "sv << maxVar << nl(nameList);
8569 } 8612 }
8570 _buf << indent() << "for "sv << indexVar << " = "sv; 8613 _buf << indent() << "for "sv << indexVar << " = "sv;
8571 if (startValue.empty()) { 8614 if (startValue.empty()) {
@@ -8598,8 +8641,8 @@ private:
8598 if (!stepValue.empty()) { 8641 if (!stepValue.empty()) {
8599 _buf << ", "sv << stepValue; 8642 _buf << ", "sv << stepValue;
8600 } 8643 }
8601 _buf << " do"sv << nlr(loopTarget); 8644 _buf << " do"sv << nl(loopTarget);
8602 _buf << indent(1) << "local "sv << join(vars, ", "sv) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList); 8645 _buf << indent(1) << "local "sv << join(vars, ", "sv) << " = "sv << listVar << "["sv << indexVar << "]"sv << nl(nameList);
8603 out.push_back(clearBuf()); 8646 out.push_back(clearBuf());
8604 BLOCK_END 8647 BLOCK_END
8605 bool newListVal = false; 8648 bool newListVal = false;
@@ -8610,21 +8653,21 @@ private:
8610 } 8653 }
8611 if (!endWithSlice) { 8654 if (!endWithSlice) {
8612 transformExp(star_exp->value, temp, ExpUsage::Closure); 8655 transformExp(star_exp->value, temp, ExpUsage::Closure);
8613 if (newListVal) _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); 8656 if (newListVal) _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nl(nameList);
8614 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << listVar << " do"sv << nlr(loopTarget); 8657 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << listVar << " do"sv << nl(loopTarget);
8615 _buf << indent(1) << "local "sv << join(vars, ", "sv) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList); 8658 _buf << indent(1) << "local "sv << join(vars, ", "sv) << " = "sv << listVar << "["sv << indexVar << "]"sv << nl(nameList);
8616 out.push_back(clearBuf()); 8659 out.push_back(clearBuf());
8617 } 8660 }
8618 break; 8661 break;
8619 } 8662 }
8620 case id<Exp_t>(): 8663 case id<Exp_t>():
8621 transformExp(static_cast<Exp_t*>(loopTarget), temp, ExpUsage::Closure); 8664 transformExp(static_cast<Exp_t*>(loopTarget), temp, ExpUsage::Closure);
8622 _buf << indent() << "for "sv << join(vars, ", "sv) << " in "sv << temp.back() << " do"sv << nlr(loopTarget); 8665 _buf << indent() << "for "sv << join(vars, ", "sv) << " in "sv << temp.back() << " do"sv << nl(loopTarget);
8623 out.push_back(clearBuf()); 8666 out.push_back(clearBuf());
8624 break; 8667 break;
8625 case id<ExpList_t>(): 8668 case id<ExpList_t>():
8626 transformExpList(static_cast<ExpList_t*>(loopTarget), temp); 8669 transformExpList(static_cast<ExpList_t*>(loopTarget), temp);
8627 _buf << indent() << "for "sv << join(vars, ", "sv) << " in "sv << temp.back() << " do"sv << nlr(loopTarget); 8670 _buf << indent() << "for "sv << join(vars, ", "sv) << " in "sv << temp.back() << " do"sv << nl(loopTarget);
8628 out.push_back(clearBuf()); 8671 out.push_back(clearBuf());
8629 break; 8672 break;
8630 default: YUEE("AST node mismatch", loopTarget); break; 8673 default: YUEE("AST node mismatch", loopTarget); break;
@@ -8722,7 +8765,7 @@ private:
8722 const auto& start = *it; 8765 const auto& start = *it;
8723 const auto& stop = *(++it); 8766 const auto& stop = *(++it);
8724 const auto& step = *(++it); 8767 const auto& step = *(++it);
8725 _buf << indent() << "for "sv << varName << " = "sv << start << ", "sv << stop << (step.empty() ? Empty : ", "s + step) << " do"sv << nll(var); 8768 _buf << indent() << "for "sv << varName << " = "sv << start << ", "sv << stop << (step.empty() ? Empty : ", "s + step) << " do"sv << nl(var);
8726 pushScope(); 8769 pushScope();
8727 forceAddToScope(varName); 8770 forceAddToScope(varName);
8728 markVarLocalConst(varName); 8771 markVarLocalConst(varName);
@@ -8740,7 +8783,7 @@ private:
8740 break; 8783 break;
8741 case id<Statement_t>(): { 8784 case id<Statement_t>(): {
8742 auto newBlock = bodyOrStmt->new_ptr<Block_t>(); 8785 auto newBlock = bodyOrStmt->new_ptr<Block_t>();
8743 newBlock->statements.push_back(bodyOrStmt); 8786 newBlock->statementOrComments.push_back(bodyOrStmt);
8744 transformBlock(newBlock, out, usage, assignList); 8787 transformBlock(newBlock, out, usage, assignList);
8745 break; 8788 break;
8746 } 8789 }
@@ -8837,9 +8880,9 @@ private:
8837 } 8880 }
8838 8881
8839 void addDoToLastLineReturn(ast_node* body) { 8882 void addDoToLastLineReturn(ast_node* body) {
8840 if (auto block = ast_cast<Block_t>(body); block && !block->statements.empty()) { 8883 if (auto block = ast_cast<Block_t>(body); block && !block->statementOrComments.empty()) {
8841 auto last = static_cast<Statement_t*>(block->statements.back()); 8884 auto last = lastStatementFrom(block);
8842 if (last->content.is<Return_t>()) { 8885 if (last && last->content.is<Return_t>()) {
8843 auto doNode = last->new_ptr<Do_t>(); 8886 auto doNode = last->new_ptr<Do_t>();
8844 auto newBody = last->new_ptr<Body_t>(); 8887 auto newBody = last->new_ptr<Body_t>();
8845 auto newStmt = last->new_ptr<Statement_t>(); 8888 auto newStmt = last->new_ptr<Statement_t>();
@@ -8866,8 +8909,8 @@ private:
8866 if (withContinue) { 8909 if (withContinue) {
8867 if (target < 502) { 8910 if (target < 502) {
8868 if (auto block = ast_cast<Block_t>(body)) { 8911 if (auto block = ast_cast<Block_t>(body)) {
8869 if (!block->statements.empty()) { 8912 if (!block->statementOrComments.empty()) {
8870 auto stmt = static_cast<Statement_t*>(block->statements.back()); 8913 auto stmt = lastStatementFrom(block);
8871 if (auto breakLoop = ast_cast<BreakLoop_t>(stmt->content)) { 8914 if (auto breakLoop = ast_cast<BreakLoop_t>(stmt->content)) {
8872 extraDo = breakLoop->type.is<Break_t>(); 8915 extraDo = breakLoop->type.is<Break_t>();
8873 } 8916 }
@@ -8876,11 +8919,11 @@ private:
8876 auto continueVar = getUnusedName("_continue_"sv); 8919 auto continueVar = getUnusedName("_continue_"sv);
8877 addToScope(continueVar); 8920 addToScope(continueVar);
8878 _continueVars.push({continueVar, nullptr}); 8921 _continueVars.push({continueVar, nullptr});
8879 _buf << indent() << "local "sv << continueVar << " = false"sv << nll(body); 8922 _buf << indent() << "local "sv << continueVar << " = false"sv << nl(body);
8880 _buf << indent() << "repeat"sv << nll(body); 8923 _buf << indent() << "repeat"sv << nl(body);
8881 pushScope(); 8924 pushScope();
8882 if (extraDo) { 8925 if (extraDo) {
8883 _buf << indent() << "do"sv << nll(body); 8926 _buf << indent() << "do"sv << nl(body);
8884 pushScope(); 8927 pushScope();
8885 } 8928 }
8886 temp.push_back(clearBuf()); 8929 temp.push_back(clearBuf());
@@ -8900,14 +8943,14 @@ private:
8900 if (target < 502) { 8943 if (target < 502) {
8901 if (extraDo) { 8944 if (extraDo) {
8902 popScope(); 8945 popScope();
8903 _buf << indent() << "end"sv << nll(body); 8946 _buf << indent() << "end"sv << nl(body);
8904 } 8947 }
8905 _buf << indent() << _continueVars.top().var << " = true"sv << nll(body); 8948 _buf << indent() << _continueVars.top().var << " = true"sv << nl(body);
8906 popScope(); 8949 popScope();
8907 _buf << indent() << "until true"sv << nlr(body); 8950 _buf << indent() << "until true"sv << nl(body);
8908 _buf << indent() << "if not "sv << _continueVars.top().var << " then"sv << nlr(body); 8951 _buf << indent() << "if not "sv << _continueVars.top().var << " then"sv << nl(body);
8909 _buf << indent(1) << "break"sv << nlr(body); 8952 _buf << indent(1) << "break"sv << nl(body);
8910 _buf << indent() << "end"sv << nlr(body); 8953 _buf << indent() << "end"sv << nl(body);
8911 temp.push_back(clearBuf()); 8954 temp.push_back(clearBuf());
8912 _continueVars.pop(); 8955 _continueVars.pop();
8913 } else { 8956 } else {
@@ -8931,8 +8974,8 @@ private:
8931 if (withContinue) { 8974 if (withContinue) {
8932 if (target < 502) { 8975 if (target < 502) {
8933 if (auto block = ast_cast<Block_t>(body)) { 8976 if (auto block = ast_cast<Block_t>(body)) {
8934 if (!block->statements.empty()) { 8977 if (!block->statementOrComments.empty()) {
8935 auto stmt = static_cast<Statement_t*>(block->statements.back()); 8978 auto stmt = lastStatementFrom(block);
8936 if (auto breakLoop = ast_cast<BreakLoop_t>(stmt->content)) { 8979 if (auto breakLoop = ast_cast<BreakLoop_t>(stmt->content)) {
8937 extraDo = breakLoop->type.is<Break_t>(); 8980 extraDo = breakLoop->type.is<Break_t>();
8938 } 8981 }
@@ -8949,12 +8992,12 @@ private:
8949 assign->values.push_back(repeatNode->condition); 8992 assign->values.push_back(repeatNode->condition);
8950 _continueVars.push({continueVar, assignment.get()}); 8993 _continueVars.push({continueVar, assignment.get()});
8951 } 8994 }
8952 _buf << indent() << "local "sv << conditionVar << " = false"sv << nll(body); 8995 _buf << indent() << "local "sv << conditionVar << " = false"sv << nl(body);
8953 _buf << indent() << "local "sv << continueVar << " = false"sv << nll(body); 8996 _buf << indent() << "local "sv << continueVar << " = false"sv << nl(body);
8954 _buf << indent() << "repeat"sv << nll(body); 8997 _buf << indent() << "repeat"sv << nl(body);
8955 pushScope(); 8998 pushScope();
8956 if (extraDo) { 8999 if (extraDo) {
8957 _buf << indent() << "do"sv << nll(body); 9000 _buf << indent() << "do"sv << nl(body);
8958 pushScope(); 9001 pushScope();
8959 } 9002 }
8960 temp.push_back(clearBuf()); 9003 temp.push_back(clearBuf());
@@ -8975,14 +9018,14 @@ private:
8975 transformAssignment(_continueVars.top().condAssign, temp); 9018 transformAssignment(_continueVars.top().condAssign, temp);
8976 if (extraDo) { 9019 if (extraDo) {
8977 popScope(); 9020 popScope();
8978 _buf << indent() << "end"sv << nll(body); 9021 _buf << indent() << "end"sv << nl(body);
8979 } 9022 }
8980 _buf << indent() << _continueVars.top().var << " = true"sv << nll(body); 9023 _buf << indent() << _continueVars.top().var << " = true"sv << nl(body);
8981 popScope(); 9024 popScope();
8982 _buf << indent() << "until true"sv << nlr(body); 9025 _buf << indent() << "until true"sv << nl(body);
8983 _buf << indent() << "if not "sv << _continueVars.top().var << " then"sv << nlr(body); 9026 _buf << indent() << "if not "sv << _continueVars.top().var << " then"sv << nl(body);
8984 _buf << indent(1) << "break"sv << nlr(body); 9027 _buf << indent(1) << "break"sv << nl(body);
8985 _buf << indent() << "end"sv << nlr(body); 9028 _buf << indent() << "end"sv << nl(body);
8986 temp.push_back(clearBuf()); 9029 temp.push_back(clearBuf());
8987 _continueVars.pop(); 9030 _continueVars.pop();
8988 } else { 9031 } else {
@@ -9000,7 +9043,7 @@ private:
9000 auto breakLoopType = getBreakLoopType(forNode->body, Empty); 9043 auto breakLoopType = getBreakLoopType(forNode->body, Empty);
9001 transformLoopBody(forNode->body, temp, breakLoopType, ExpUsage::Common); 9044 transformLoopBody(forNode->body, temp, breakLoopType, ExpUsage::Common);
9002 popScope(); 9045 popScope();
9003 out.push_back(join(temp) + indent() + "end"s + nlr(forNode)); 9046 out.push_back(join(temp) + indent() + "end"s + nl(forNode));
9004 } 9047 }
9005 9048
9006 std::string transformForInner(For_t* forNode, str_list& out) { 9049 std::string transformForInner(For_t* forNode, str_list& out) {
@@ -9010,9 +9053,9 @@ private:
9010 std::string len = getUnusedName("_len_"sv); 9053 std::string len = getUnusedName("_len_"sv);
9011 addToScope(len); 9054 addToScope(len);
9012 auto breakLoopType = getBreakLoopType(forNode->body, accum); 9055 auto breakLoopType = getBreakLoopType(forNode->body, accum);
9013 _buf << indent() << "local "sv << accum << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nll(forNode); 9056 _buf << indent() << "local "sv << accum << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nl(forNode);
9014 out.emplace_back(clearBuf()); 9057 out.emplace_back(clearBuf());
9015 _buf << indent() << "local "sv << len << " = 1"sv << nll(forNode); 9058 _buf << indent() << "local "sv << len << " = 1"sv << nl(forNode);
9016 auto& lenAssign = out.emplace_back(clearBuf()); 9059 auto& lenAssign = out.emplace_back(clearBuf());
9017 transformForHead(forNode, out); 9060 transformForHead(forNode, out);
9018 if (hasBreakWithValue(breakLoopType)) { 9061 if (hasBreakWithValue(breakLoopType)) {
@@ -9028,7 +9071,7 @@ private:
9028 } 9071 }
9029 } 9072 }
9030 popScope(); 9073 popScope();
9031 out.push_back(indent() + "end"s + nlr(forNode)); 9074 out.push_back(indent() + "end"s + nl(forNode));
9032 return accum; 9075 return accum;
9033 } 9076 }
9034 9077
@@ -9044,9 +9087,9 @@ private:
9044 std::string& funcStart = temp.emplace_back(); 9087 std::string& funcStart = temp.emplace_back();
9045 pushScope(); 9088 pushScope();
9046 auto accum = transformForInner(forNode, temp); 9089 auto accum = transformForInner(forNode, temp);
9047 temp.push_back(indent() + "return "s + accum + nlr(forNode)); 9090 temp.push_back(indent() + "return "s + accum + nl(forNode));
9048 popScope(); 9091 popScope();
9049 funcStart = anonFuncStart() + nll(forNode); 9092 funcStart = anonFuncStart() + nl(forNode);
9050 temp.push_back(indent() + anonFuncEnd()); 9093 temp.push_back(indent() + anonFuncEnd());
9051 popAnonVarArg(); 9094 popAnonVarArg();
9052 popFunctionScope(); 9095 popFunctionScope();
@@ -9059,7 +9102,7 @@ private:
9059 bool isScoped = !currentScope().lastStatement; 9102 bool isScoped = !currentScope().lastStatement;
9060 if (assignExpList) { 9103 if (assignExpList) {
9061 if (isScoped) { 9104 if (isScoped) {
9062 _buf << indent() << "do"sv << nll(forNode); 9105 _buf << indent() << "do"sv << nl(forNode);
9063 pushScope(); 9106 pushScope();
9064 } 9107 }
9065 auto accum = transformForInner(forNode, temp); 9108 auto accum = transformForInner(forNode, temp);
@@ -9071,7 +9114,7 @@ private:
9071 transformAssignment(assignment, temp); 9114 transformAssignment(assignment, temp);
9072 if (isScoped) { 9115 if (isScoped) {
9073 popScope(); 9116 popScope();
9074 temp.push_back(indent() + "end"s + nlr(forNode)); 9117 temp.push_back(indent() + "end"s + nl(forNode));
9075 } 9118 }
9076 } else { 9119 } else {
9077 auto accum = transformForInner(forNode, temp); 9120 auto accum = transformForInner(forNode, temp);
@@ -9108,10 +9151,10 @@ private:
9108 auto breakLoopType = getBreakLoopType(forEach->body, Empty); 9151 auto breakLoopType = getBreakLoopType(forEach->body, Empty);
9109 transformLoopBody(forEach->body, temp, breakLoopType, ExpUsage::Common); 9152 transformLoopBody(forEach->body, temp, breakLoopType, ExpUsage::Common);
9110 popScope(); 9153 popScope();
9111 out.push_back(temp.front() + temp.back() + indent() + "end"s + nlr(forEach)); 9154 out.push_back(temp.front() + temp.back() + indent() + "end"s + nl(forEach));
9112 if (extraScoped) { 9155 if (extraScoped) {
9113 popScope(); 9156 popScope();
9114 out.back().append(indent() + "end"s + nlr(forEach)); 9157 out.back().append(indent() + "end"s + nl(forEach));
9115 } 9158 }
9116 } 9159 }
9117 9160
@@ -9122,9 +9165,9 @@ private:
9122 std::string len = getUnusedName("_len_"sv); 9165 std::string len = getUnusedName("_len_"sv);
9123 addToScope(len); 9166 addToScope(len);
9124 auto breakLoopType = getBreakLoopType(forEach->body, accum); 9167 auto breakLoopType = getBreakLoopType(forEach->body, accum);
9125 _buf << indent() << "local "sv << accum << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nll(forEach); 9168 _buf << indent() << "local "sv << accum << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nl(forEach);
9126 out.emplace_back(clearBuf()); 9169 out.emplace_back(clearBuf());
9127 _buf << indent() << "local "sv << len << " = 1"sv << nll(forEach); 9170 _buf << indent() << "local "sv << len << " = 1"sv << nl(forEach);
9128 auto& lenAssign = out.emplace_back(clearBuf()); 9171 auto& lenAssign = out.emplace_back(clearBuf());
9129 transformForEachHead(forEach->nameList, forEach->loopValue, out, true); 9172 transformForEachHead(forEach->nameList, forEach->loopValue, out, true);
9130 if (hasBreakWithValue(breakLoopType)) { 9173 if (hasBreakWithValue(breakLoopType)) {
@@ -9140,7 +9183,7 @@ private:
9140 } 9183 }
9141 } 9184 }
9142 popScope(); 9185 popScope();
9143 out.push_back(indent() + "end"s + nlr(forEach)); 9186 out.push_back(indent() + "end"s + nl(forEach));
9144 return accum; 9187 return accum;
9145 } 9188 }
9146 9189
@@ -9156,9 +9199,9 @@ private:
9156 std::string& funcStart = temp.emplace_back(); 9199 std::string& funcStart = temp.emplace_back();
9157 pushScope(); 9200 pushScope();
9158 auto accum = transformForEachInner(forEach, temp); 9201 auto accum = transformForEachInner(forEach, temp);
9159 temp.push_back(indent() + "return "s + accum + nlr(forEach)); 9202 temp.push_back(indent() + "return "s + accum + nl(forEach));
9160 popScope(); 9203 popScope();
9161 funcStart = anonFuncStart() + nll(forEach); 9204 funcStart = anonFuncStart() + nl(forEach);
9162 temp.push_back(indent() + anonFuncEnd()); 9205 temp.push_back(indent() + anonFuncEnd());
9163 popAnonVarArg(); 9206 popAnonVarArg();
9164 popFunctionScope(); 9207 popFunctionScope();
@@ -9171,7 +9214,7 @@ private:
9171 bool isScoped = !currentScope().lastStatement; 9214 bool isScoped = !currentScope().lastStatement;
9172 if (assignExpList) { 9215 if (assignExpList) {
9173 if (isScoped) { 9216 if (isScoped) {
9174 _buf << indent() << "do"sv << nll(forEach); 9217 _buf << indent() << "do"sv << nl(forEach);
9175 pushScope(); 9218 pushScope();
9176 } 9219 }
9177 auto accum = transformForEachInner(forEach, temp); 9220 auto accum = transformForEachInner(forEach, temp);
@@ -9183,7 +9226,7 @@ private:
9183 transformAssignment(assignment, temp); 9226 transformAssignment(assignment, temp);
9184 if (isScoped) { 9227 if (isScoped) {
9185 popScope(); 9228 popScope();
9186 temp.push_back(indent() + "end"s + nlr(forEach)); 9229 temp.push_back(indent() + "end"s + nl(forEach));
9187 } 9230 }
9188 } else { 9231 } else {
9189 auto accum = transformForEachInner(forEach, temp); 9232 auto accum = transformForEachInner(forEach, temp);
@@ -9410,7 +9453,7 @@ private:
9410 pushScope(); 9453 pushScope();
9411 transformClassDecl(classDecl, temp, ExpUsage::Return); 9454 transformClassDecl(classDecl, temp, ExpUsage::Return);
9412 popScope(); 9455 popScope();
9413 funcStart = anonFuncStart() + nll(classDecl); 9456 funcStart = anonFuncStart() + nl(classDecl);
9414 temp.push_back(indent() + anonFuncEnd()); 9457 temp.push_back(indent() + anonFuncEnd());
9415 popAnonVarArg(); 9458 popAnonVarArg();
9416 popFunctionScope(); 9459 popFunctionScope();
@@ -9434,7 +9477,7 @@ private:
9434 bool newDefined = false; 9477 bool newDefined = false;
9435 std::tie(className, newDefined, classTextName) = defineClassVariable(assignable); 9478 std::tie(className, newDefined, classTextName) = defineClassVariable(assignable);
9436 if (newDefined) { 9479 if (newDefined) {
9437 temp.push_back(indent() + "local "s + className + nll(classDecl)); 9480 temp.push_back(indent() + "local "s + className + nl(classDecl));
9438 } 9481 }
9439 if (classTextName.empty()) { 9482 if (classTextName.empty()) {
9440 if (auto chain = ast_cast<AssignableChain_t>(assignable->item)) { 9483 if (auto chain = ast_cast<AssignableChain_t>(assignable->item)) {
@@ -9471,12 +9514,12 @@ private:
9471 } 9514 }
9472 } 9515 }
9473 if (isScoped) { 9516 if (isScoped) {
9474 temp.push_back(indent() + "do"s + nll(classDecl)); 9517 temp.push_back(indent() + "do"s + nl(classDecl));
9475 pushScope(); 9518 pushScope();
9476 } 9519 }
9477 auto classVar = getUnusedName("_class_"sv); 9520 auto classVar = getUnusedName("_class_"sv);
9478 addToScope(classVar); 9521 addToScope(classVar);
9479 temp.push_back(indent() + "local "s + classVar + nll(classDecl)); 9522 temp.push_back(indent() + "local "s + classVar + nl(classDecl));
9480 auto block = classDecl->new_ptr<Block_t>(); 9523 auto block = classDecl->new_ptr<Block_t>();
9481 str_list classConstVars; 9524 str_list classConstVars;
9482 if (body) { 9525 if (body) {
@@ -9485,7 +9528,7 @@ private:
9485 if (auto statement = ast_cast<Statement_t>(item)) { 9528 if (auto statement = ast_cast<Statement_t>(item)) {
9486 ClassDecl_t* clsDecl = nullptr; 9529 ClassDecl_t* clsDecl = nullptr;
9487 if (auto assignment = assignmentFrom(statement)) { 9530 if (auto assignment = assignmentFrom(statement)) {
9488 block->statements.push_back(statement); 9531 block->statementOrComments.push_back(statement);
9489 auto names = transformAssignDefs(assignment->expList.get(), DefOp::Mark); 9532 auto names = transformAssignDefs(assignment->expList.get(), DefOp::Mark);
9490 for (const auto& name : names) { 9533 for (const auto& name : names) {
9491 varDefs.push_back(name.first); 9534 varDefs.push_back(name.first);
@@ -9515,12 +9558,12 @@ private:
9515 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>(); 9558 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>();
9516 BLOCK_END 9559 BLOCK_END
9517 } else if (auto expList = expListFrom(statement)) { 9560 } else if (auto expList = expListFrom(statement)) {
9518 block->statements.push_back(statement); 9561 block->statementOrComments.push_back(statement);
9519 if (auto value = singleValueFrom(expList)) { 9562 if (auto value = singleValueFrom(expList)) {
9520 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>(); 9563 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>();
9521 } 9564 }
9522 } else if (auto local = statement->content.as<Local_t>()) { 9565 } else if (auto local = statement->content.as<Local_t>()) {
9523 block->statements.push_back(statement); 9566 block->statementOrComments.push_back(statement);
9524 if (auto values = local->item.as<LocalValues_t>()) { 9567 if (auto values = local->item.as<LocalValues_t>()) {
9525 for (auto name : values->nameList->names.objects()) { 9568 for (auto name : values->nameList->names.objects()) {
9526 auto varName = variableToString(static_cast<Variable_t*>(name)); 9569 auto varName = variableToString(static_cast<Variable_t*>(name));
@@ -9583,7 +9626,6 @@ private:
9583 } 9626 }
9584 } 9627 }
9585 auto stmt = statement->new_ptr<Statement_t>(); 9628 auto stmt = statement->new_ptr<Statement_t>();
9586 stmt->comments.dup(statement->comments);
9587 auto newAttrib = localAttrib->new_ptr<LocalAttrib_t>(); 9629 auto newAttrib = localAttrib->new_ptr<LocalAttrib_t>();
9588 newAttrib->attrib.set(localAttrib->attrib); 9630 newAttrib->attrib.set(localAttrib->attrib);
9589 newAttrib->leftList.dup(localAttrib->leftList); 9631 newAttrib->leftList.dup(localAttrib->leftList);
@@ -9591,7 +9633,7 @@ private:
9591 newAttrib->forceLocal = false; 9633 newAttrib->forceLocal = false;
9592 stmt->content.set(newAttrib); 9634 stmt->content.set(newAttrib);
9593 stmt->appendix.set(statement->appendix); 9635 stmt->appendix.set(statement->appendix);
9594 block->statements.push_back(stmt); 9636 block->statementOrComments.push_back(stmt);
9595 } else if (statement->content.is<Global_t>()) { 9637 } else if (statement->content.is<Global_t>()) {
9596 throw CompileError("global statement is not allowed here"sv, statement->content); 9638 throw CompileError("global statement is not allowed here"sv, statement->content);
9597 } 9639 }
@@ -9605,7 +9647,7 @@ private:
9605 } 9647 }
9606 } 9648 }
9607 if (!varDefs.empty()) { 9649 if (!varDefs.empty()) {
9608 temp.push_back(indent() + "local "s + join(varDefs, ", "sv) + nll(body)); 9650 temp.push_back(indent() + "local "s + join(varDefs, ", "sv) + nl(body));
9609 } 9651 }
9610 } 9652 }
9611 std::string parent, parentVar; 9653 std::string parent, parentVar;
@@ -9615,7 +9657,7 @@ private:
9615 transformExp(extend, temp, ExpUsage::Closure); 9657 transformExp(extend, temp, ExpUsage::Closure);
9616 parent = std::move(temp.back()); 9658 parent = std::move(temp.back());
9617 temp.pop_back(); 9659 temp.pop_back();
9618 temp.push_back(indent() + "local "s + parentVar + " = "s + parent + nll(classDecl)); 9660 temp.push_back(indent() + "local "s + parentVar + " = "s + parent + nl(classDecl));
9619 } 9661 }
9620 auto baseVar = getUnusedName("_base_"sv); 9662 auto baseVar = getUnusedName("_base_"sv);
9621 addToScope(baseVar); 9663 addToScope(baseVar);
@@ -9634,7 +9676,7 @@ private:
9634 for (; it != members.end(); ++it) { 9676 for (; it != members.end(); ++it) {
9635 auto& member = *it; 9677 auto& member = *it;
9636 if (member.type == MemType::Property) { 9678 if (member.type == MemType::Property) {
9637 statements.push_back(indent() + member.item + nll(content)); 9679 statements.push_back(indent() + member.item + nl(content));
9638 } else { 9680 } else {
9639 member.item = indent(1) + member.item; 9681 member.item = indent(1) + member.item;
9640 } 9682 }
@@ -9646,32 +9688,34 @@ private:
9646 } 9688 }
9647 } 9689 }
9648 for (const auto& classVar : classConstVars) { 9690 for (const auto& classVar : classConstVars) {
9649 auto& scope = _scopes.back(); 9691 forceAddToScope(classVar);
9650 scope.vars->insert_or_assign(classVar, VarType::Local);
9651 } 9692 }
9652 for (auto stmt_ : block->statements.objects()) { 9693 forceAddToScope("self"s);
9653 transformStatement(static_cast<Statement_t*>(stmt_), statements); 9694 for (auto stmt_ : block->statementOrComments.objects()) {
9695 if (auto stmt = ast_cast<Statement_t>(stmt_)) {
9696 transformStatement(stmt, statements);
9697 }
9654 } 9698 }
9655 for (auto& member : members) { 9699 for (auto& member : members) {
9656 switch (member.type) { 9700 switch (member.type) {
9657 case MemType::Common: 9701 case MemType::Common:
9658 commons.push_back((commons.empty() ? Empty : ',' + nll(member.node)) + member.item); 9702 commons.push_back((commons.empty() ? Empty : ',' + nl(member.node)) + member.item);
9659 break; 9703 break;
9660 case MemType::Builtin: 9704 case MemType::Builtin:
9661 builtins.push_back((builtins.empty() ? Empty : ',' + nll(member.node)) + member.item); 9705 builtins.push_back((builtins.empty() ? Empty : ',' + nl(member.node)) + member.item);
9662 break; 9706 break;
9663 default: break; 9707 default: break;
9664 } 9708 }
9665 } 9709 }
9666 if (!commons.empty()) { 9710 if (!commons.empty()) {
9667 temp.back() += '{' + nll(body); 9711 temp.back() += '{' + nl(body);
9668 temp.push_back(join(commons) + nll(body)); 9712 temp.push_back(join(commons) + nl(body));
9669 temp.push_back(indent() + '}' + nll(body)); 9713 temp.push_back(indent() + '}' + nl(body));
9670 } else { 9714 } else {
9671 temp.back() += "{ }"s + nll(body); 9715 temp.back() += "{ }"s + nl(body);
9672 } 9716 }
9673 } else { 9717 } else {
9674 temp.back() += "{ }"s + nll(classDecl); 9718 temp.back() += "{ }"s + nl(classDecl);
9675 } 9719 }
9676 if (classDecl->mixes) { 9720 if (classDecl->mixes) {
9677 auto item = getUnusedName("_item_"sv); 9721 auto item = getUnusedName("_item_"sv);
@@ -9704,72 +9748,72 @@ private:
9704 transformAssignment(assignment, tmp); 9748 transformAssignment(assignment, tmp);
9705 } 9749 }
9706 if (extend) { 9750 if (extend) {
9707 _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl); 9751 _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nl(classDecl);
9708 } 9752 }
9709 _buf << indent() << classVar << " = "sv << globalVar("setmetatable"sv, classDecl, AccessType::Read) << "({"sv << nll(classDecl); 9753 _buf << indent() << classVar << " = "sv << globalVar("setmetatable"sv, classDecl, AccessType::Read) << "({"sv << nl(classDecl);
9710 if (!builtins.empty()) { 9754 if (!builtins.empty()) {
9711 _buf << join(builtins) << ',' << nll(classDecl); 9755 _buf << join(builtins) << ',' << nl(classDecl);
9712 } else { 9756 } else {
9713 if (extend) { 9757 if (extend) {
9714 _buf << indent(1) << "__init = function(self, ...)"sv << nll(classDecl); 9758 _buf << indent(1) << "__init = function(self, ...)"sv << nl(classDecl);
9715 _buf << indent(2) << "return "sv << classVar << ".__parent.__init(self, ...)"sv << nll(classDecl); 9759 _buf << indent(2) << "return "sv << classVar << ".__parent.__init(self, ...)"sv << nl(classDecl);
9716 _buf << indent(1) << "end,"sv << nll(classDecl); 9760 _buf << indent(1) << "end,"sv << nl(classDecl);
9717 } else { 9761 } else {
9718 _buf << indent(1) << "__init = function() end,"sv << nll(classDecl); 9762 _buf << indent(1) << "__init = function() end,"sv << nl(classDecl);
9719 } 9763 }
9720 } 9764 }
9721 _buf << indent(1) << "__base = "sv << baseVar; 9765 _buf << indent(1) << "__base = "sv << baseVar;
9722 if (!classTextName.empty()) { 9766 if (!classTextName.empty()) {
9723 _buf << ","sv << nll(classDecl); 9767 _buf << ","sv << nl(classDecl);
9724 _buf << indent(1) << "__name = "sv << classTextName; 9768 _buf << indent(1) << "__name = "sv << classTextName;
9725 } 9769 }
9726 if (extend) { 9770 if (extend) {
9727 _buf << ","sv << nll(classDecl); 9771 _buf << ","sv << nl(classDecl);
9728 _buf << indent(1) << "__parent = "sv << parentVar; 9772 _buf << indent(1) << "__parent = "sv << parentVar;
9729 } 9773 }
9730 _buf << nll(classDecl); 9774 _buf << nl(classDecl);
9731 _buf << indent() << "}, {"sv << nll(classDecl); 9775 _buf << indent() << "}, {"sv << nl(classDecl);
9732 if (extend) { 9776 if (extend) {
9733 _buf << indent(1) << "__index = function(cls, name)"sv << nll(classDecl); 9777 _buf << indent(1) << "__index = function(cls, name)"sv << nl(classDecl);
9734 _buf << indent(2) << "local val = rawget("sv << baseVar << ", name)"sv << nll(classDecl); 9778 _buf << indent(2) << "local val = rawget("sv << baseVar << ", name)"sv << nl(classDecl);
9735 _buf << indent(2) << "if val == nil then"sv << nll(classDecl); 9779 _buf << indent(2) << "if val == nil then"sv << nl(classDecl);
9736 _buf << indent(3) << "local parent = rawget(cls, \"__parent\")"sv << nll(classDecl); 9780 _buf << indent(3) << "local parent = rawget(cls, \"__parent\")"sv << nl(classDecl);
9737 _buf << indent(3) << "if parent then"sv << nll(classDecl); 9781 _buf << indent(3) << "if parent then"sv << nl(classDecl);
9738 _buf << indent(4) << "return parent[name]"sv << nll(classDecl); 9782 _buf << indent(4) << "return parent[name]"sv << nl(classDecl);
9739 _buf << indent(3) << "end"sv << nll(classDecl); 9783 _buf << indent(3) << "end"sv << nl(classDecl);
9740 _buf << indent(2) << "else"sv << nll(classDecl); 9784 _buf << indent(2) << "else"sv << nl(classDecl);
9741 _buf << indent(3) << "return val"sv << nll(classDecl); 9785 _buf << indent(3) << "return val"sv << nl(classDecl);
9742 _buf << indent(2) << "end"sv << nll(classDecl); 9786 _buf << indent(2) << "end"sv << nl(classDecl);
9743 _buf << indent(1) << "end,"sv << nll(classDecl); 9787 _buf << indent(1) << "end,"sv << nl(classDecl);
9744 } else { 9788 } else {
9745 _buf << indent(1) << "__index = "sv << baseVar << ","sv << nll(classDecl); 9789 _buf << indent(1) << "__index = "sv << baseVar << ","sv << nl(classDecl);
9746 } 9790 }
9747 _buf << indent(1) << "__call = function(cls, ...)"sv << nll(classDecl); 9791 _buf << indent(1) << "__call = function(cls, ...)"sv << nl(classDecl);
9748 pushScope(); 9792 pushScope();
9749 auto selfVar = getUnusedName("_self_"sv); 9793 auto selfVar = getUnusedName("_self_"sv);
9750 addToScope(selfVar); 9794 addToScope(selfVar);
9751 _buf << indent(1) << "local "sv << selfVar << " = setmetatable({ }, "sv << baseVar << ")"sv << nll(classDecl); 9795 _buf << indent(1) << "local "sv << selfVar << " = setmetatable({ }, "sv << baseVar << ")"sv << nl(classDecl);
9752 _buf << indent(1) << "cls.__init("sv << selfVar << ", ...)"sv << nll(classDecl); 9796 _buf << indent(1) << "cls.__init("sv << selfVar << ", ...)"sv << nl(classDecl);
9753 _buf << indent(1) << "return "sv << selfVar << nll(classDecl); 9797 _buf << indent(1) << "return "sv << selfVar << nl(classDecl);
9754 popScope(); 9798 popScope();
9755 _buf << indent(1) << "end"sv << nll(classDecl); 9799 _buf << indent(1) << "end"sv << nl(classDecl);
9756 _buf << indent() << "})"sv << nll(classDecl); 9800 _buf << indent() << "})"sv << nl(classDecl);
9757 _buf << indent() << baseVar << ".__class = "sv << classVar << nll(classDecl); 9801 _buf << indent() << baseVar << ".__class = "sv << classVar << nl(classDecl);
9758 if (!statements.empty()) { 9802 if (!statements.empty()) {
9759 _buf << indent() << "local self = "sv << classVar << ';' << nll(classDecl); 9803 _buf << indent() << "local self = "sv << classVar << ';' << nl(classDecl);
9760 } 9804 }
9761 _buf << join(statements); 9805 _buf << join(statements);
9762 if (extend) { 9806 if (extend) {
9763 _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nll(classDecl); 9807 _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nl(classDecl);
9764 _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nll(classDecl); 9808 _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nl(classDecl);
9765 _buf << indent() << "end"sv << nll(classDecl); 9809 _buf << indent() << "end"sv << nl(classDecl);
9766 } 9810 }
9767 if (!assignItem.empty()) { 9811 if (!assignItem.empty()) {
9768 _buf << indent() << assignItem << " = "sv << classVar << nll(classDecl); 9812 _buf << indent() << assignItem << " = "sv << classVar << nl(classDecl);
9769 } 9813 }
9770 switch (usage) { 9814 switch (usage) {
9771 case ExpUsage::Return: { 9815 case ExpUsage::Return: {
9772 _buf << indent() << "return "sv << classVar << nlr(classDecl); 9816 _buf << indent() << "return "sv << classVar << nl(classDecl);
9773 break; 9817 break;
9774 } 9818 }
9775 case ExpUsage::Assignment: { 9819 case ExpUsage::Assignment: {
@@ -9781,7 +9825,7 @@ private:
9781 temp.push_back(clearBuf()); 9825 temp.push_back(clearBuf());
9782 if (isScoped) { 9826 if (isScoped) {
9783 popScope(); 9827 popScope();
9784 temp.push_back(indent() + "end"s + nlr(classDecl)); 9828 temp.push_back(indent() + "end"s + nl(classDecl));
9785 } 9829 }
9786 out.push_back(join(temp)); 9830 out.push_back(join(temp));
9787 } 9831 }
@@ -9944,7 +9988,7 @@ private:
9944 pushScope(); 9988 pushScope();
9945 transformWith(with, temp, nullptr, true); 9989 transformWith(with, temp, nullptr, true);
9946 popScope(); 9990 popScope();
9947 funcStart = anonFuncStart() + nll(with); 9991 funcStart = anonFuncStart() + nl(with);
9948 temp.push_back(indent() + anonFuncEnd()); 9992 temp.push_back(indent() + anonFuncEnd());
9949 popAnonVarArg(); 9993 popAnonVarArg();
9950 popFunctionScope(); 9994 popFunctionScope();
@@ -9975,7 +10019,7 @@ private:
9975 assignment->action.set(assign); 10019 assignment->action.set(assign);
9976 if (needScope) { 10020 if (needScope) {
9977 extraScope = true; 10021 extraScope = true;
9978 temp.push_back(indent() + "do"s + nll(with)); 10022 temp.push_back(indent() + "do"s + nl(with));
9979 pushScope(); 10023 pushScope();
9980 } 10024 }
9981 transformAssignment(assignment, temp); 10025 transformAssignment(assignment, temp);
@@ -10001,7 +10045,7 @@ private:
10001 assignment->action.set(with->assign); 10045 assignment->action.set(with->assign);
10002 if (needScope) { 10046 if (needScope) {
10003 extraScope = true; 10047 extraScope = true;
10004 temp.push_back(indent() + "do"s + nll(with)); 10048 temp.push_back(indent() + "do"s + nl(with));
10005 pushScope(); 10049 pushScope();
10006 } 10050 }
10007 transformAssignment(assignment, temp); 10051 transformAssignment(assignment, temp);
@@ -10017,7 +10061,7 @@ private:
10017 assignment->action.set(assign); 10061 assignment->action.set(assign);
10018 if (needScope) { 10062 if (needScope) {
10019 extraScope = true; 10063 extraScope = true;
10020 temp.push_back(indent() + "do"s + nll(with)); 10064 temp.push_back(indent() + "do"s + nl(with));
10021 pushScope(); 10065 pushScope();
10022 } 10066 }
10023 transformAssignment(assignment, temp); 10067 transformAssignment(assignment, temp);
@@ -10071,7 +10115,7 @@ private:
10071 }); 10115 });
10072 popScope(); 10116 popScope();
10073 if (extraScope) { 10117 if (extraScope) {
10074 temp.push_back(indent() + "do"s + nll(with)); 10118 temp.push_back(indent() + "do"s + nl(with));
10075 pushScope(); 10119 pushScope();
10076 } 10120 }
10077 } 10121 }
@@ -10102,7 +10146,7 @@ private:
10102 stmt->content.set(expListAssign); 10146 stmt->content.set(expListAssign);
10103 auto repeatNode = toAst<Repeat_t>("repeat\n\t--\nuntil true"s, x); 10147 auto repeatNode = toAst<Repeat_t>("repeat\n\t--\nuntil true"s, x);
10104 auto block = x->new_ptr<Block_t>(); 10148 auto block = x->new_ptr<Block_t>();
10105 block->statements.push_back(stmt); 10149 block->statementOrComments.push_back(stmt);
10106 repeatNode->body.set(block); 10150 repeatNode->body.set(block);
10107 auto sVal = x->new_ptr<SimpleValue_t>(); 10151 auto sVal = x->new_ptr<SimpleValue_t>();
10108 sVal->value.set(repeatNode); 10152 sVal->value.set(repeatNode);
@@ -10115,10 +10159,10 @@ private:
10115 auto repeatNode = toAst<Repeat_t>("repeat\n\t--\nuntil true"s, x); 10159 auto repeatNode = toAst<Repeat_t>("repeat\n\t--\nuntil true"s, x);
10116 auto block = x->new_ptr<Block_t>(); 10160 auto block = x->new_ptr<Block_t>();
10117 if (auto blk = with->body.as<Block_t>()) { 10161 if (auto blk = with->body.as<Block_t>()) {
10118 block->statements.dup(blk->statements); 10162 block->statementOrComments.dup(blk->statementOrComments);
10119 } else { 10163 } else {
10120 auto stmt = with->body.to<Statement_t>(); 10164 auto stmt = with->body.to<Statement_t>();
10121 block->statements.push_back(stmt); 10165 block->statementOrComments.push_back(stmt);
10122 } 10166 }
10123 repeatNode->body.set(block); 10167 repeatNode->body.set(block);
10124 auto sVal = x->new_ptr<SimpleValue_t>(); 10168 auto sVal = x->new_ptr<SimpleValue_t>();
@@ -10128,12 +10172,12 @@ private:
10128 transformed = true; 10172 transformed = true;
10129 } else if (!extraScope && assignList) { 10173 } else if (!extraScope && assignList) {
10130 if (auto block = with->body.as<Block_t>()) { 10174 if (auto block = with->body.as<Block_t>()) {
10131 if (!block->statements.empty()) { 10175 if (!block->statementOrComments.empty()) {
10132 Statement_t* stmt = static_cast<Statement_t*>(block->statements.back()); 10176 Statement_t* stmt = lastStatementFrom(block);
10133 if (stmt->content.is<Return_t>()) { 10177 if (stmt && stmt->content.is<Return_t>()) {
10134 auto newBlock = with->body->new_ptr<Block_t>(); 10178 auto newBlock = with->body->new_ptr<Block_t>();
10135 newBlock->statements.dup(block->statements); 10179 newBlock->statementOrComments.dup(block->statementOrComments);
10136 newBlock->statements.pop_back(); 10180 newBlock->statementOrComments.pop_back();
10137 transform_plain_body(newBlock, temp, ExpUsage::Common); 10181 transform_plain_body(newBlock, temp, ExpUsage::Common);
10138 auto newBody = stmt->new_ptr<Body_t>(); 10182 auto newBody = stmt->new_ptr<Body_t>();
10139 newBody->content.set(stmt); 10183 newBody->content.set(stmt);
@@ -10171,12 +10215,12 @@ private:
10171 if (returnValue) { 10215 if (returnValue) {
10172 auto last = lastStatementFrom(with->body); 10216 auto last = lastStatementFrom(with->body);
10173 if (last && !last->content.is<Return_t>()) { 10217 if (last && !last->content.is<Return_t>()) {
10174 temp.push_back(indent() + "return "s + withVar + nll(with)); 10218 temp.push_back(indent() + "return "s + withVar + nl(with));
10175 } 10219 }
10176 } 10220 }
10177 if (extraScope) { 10221 if (extraScope) {
10178 popScope(); 10222 popScope();
10179 temp.push_back(indent() + "end"s + nll(with)); 10223 temp.push_back(indent() + "end"s + nl(with));
10180 } 10224 }
10181 out.push_back(join(temp)); 10225 out.push_back(join(temp));
10182 } 10226 }
@@ -10386,7 +10430,7 @@ private:
10386 } 10430 }
10387 } 10431 }
10388 if (_info.exportDefault) { 10432 if (_info.exportDefault) {
10389 out.back().append(indent() + _info.moduleName + " = "s + names.back().first + nlr(exportNode)); 10433 out.back().append(indent() + _info.moduleName + " = "s + names.back().first + nl(exportNode));
10390 } else { 10434 } else {
10391 str_list lefts, rights; 10435 str_list lefts, rights;
10392 for (const auto& name : names) { 10436 for (const auto& name : names) {
@@ -10399,7 +10443,7 @@ private:
10399 lefts.push_back(_info.moduleName + "[\""s + realName + "\"]"s); 10443 lefts.push_back(_info.moduleName + "[\""s + realName + "\"]"s);
10400 rights.push_back(name.first); 10444 rights.push_back(name.first);
10401 } 10445 }
10402 out.back().append(indent() + join(lefts, ", "sv) + " = "s + join(rights, ", "sv) + nlr(exportNode)); 10446 out.back().append(indent() + join(lefts, ", "sv) + " = "s + join(rights, ", "sv) + nl(exportNode));
10403 } 10447 }
10404 } 10448 }
10405 } else { 10449 } else {
@@ -10488,7 +10532,7 @@ private:
10488 break; 10532 break;
10489 case id<Exp_t>(): 10533 case id<Exp_t>():
10490 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); 10534 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure);
10491 temp.back() = indent() + "if "s + temp.back() + " then"s + nll(item); 10535 temp.back() = indent() + "if "s + temp.back() + " then"s + nl(item);
10492 pushScope(); 10536 pushScope();
10493 break; 10537 break;
10494 default: YUEE("AST node mismatch", item); break; 10538 default: YUEE("AST node mismatch", item); break;
@@ -10501,27 +10545,27 @@ private:
10501 for (size_t i = 0; i < compInner->items.objects().size(); ++i) { 10545 for (size_t i = 0; i < compInner->items.objects().size(); ++i) {
10502 popScope(); 10546 popScope();
10503 } 10547 }
10504 _buf << indent() << "local "sv << tbl << " = { }"sv << nll(comp); 10548 _buf << indent() << "local "sv << tbl << " = { }"sv << nl(comp);
10505 _buf << join(temp); 10549 _buf << join(temp);
10506 pushScope(); 10550 pushScope();
10507 if (!comp->value) { 10551 if (!comp->value) {
10508 auto keyVar = getUnusedName("_key_"sv); 10552 auto keyVar = getUnusedName("_key_"sv);
10509 auto valVar = getUnusedName("_val_"sv); 10553 auto valVar = getUnusedName("_val_"sv);
10510 _buf << indent(int(temp.size()) - 1) << "local "sv << keyVar << ", "sv << valVar << " = "sv << kv.front() << nll(comp); 10554 _buf << indent(int(temp.size()) - 1) << "local "sv << keyVar << ", "sv << valVar << " = "sv << kv.front() << nl(comp);
10511 kv.front() = keyVar; 10555 kv.front() = keyVar;
10512 kv.push_back(valVar); 10556 kv.push_back(valVar);
10513 } 10557 }
10514 _buf << indent(int(temp.size()) - 1) << tbl << "["sv << kv.front() << "] = "sv << kv.back() << nll(comp); 10558 _buf << indent(int(temp.size()) - 1) << tbl << "["sv << kv.front() << "] = "sv << kv.back() << nl(comp);
10515 for (int ind = int(temp.size()) - 2; ind > -1; --ind) { 10559 for (int ind = int(temp.size()) - 2; ind > -1; --ind) {
10516 _buf << indent(ind) << "end"sv << nll(comp); 10560 _buf << indent(ind) << "end"sv << nl(comp);
10517 } 10561 }
10518 popScope(); 10562 popScope();
10519 _buf << indent() << "end"sv << nll(comp); 10563 _buf << indent() << "end"sv << nl(comp);
10520 switch (usage) { 10564 switch (usage) {
10521 case ExpUsage::Closure: 10565 case ExpUsage::Closure:
10522 out.push_back(clearBuf() + indent() + "return "s + tbl + nlr(comp)); 10566 out.push_back(clearBuf() + indent() + "return "s + tbl + nl(comp));
10523 popScope(); 10567 popScope();
10524 out.back().insert(0, anonFuncStart() + nll(comp)); 10568 out.back().insert(0, anonFuncStart() + nl(comp));
10525 out.back().append(indent() + anonFuncEnd()); 10569 out.back().append(indent() + anonFuncEnd());
10526 popAnonVarArg(); 10570 popAnonVarArg();
10527 popFunctionScope(); 10571 popFunctionScope();
@@ -10537,13 +10581,13 @@ private:
10537 out.back().append(temp.back()); 10581 out.back().append(temp.back());
10538 if (extraScope) { 10582 if (extraScope) {
10539 popScope(); 10583 popScope();
10540 out.back().insert(0, indent() + "do"s + nll(comp)); 10584 out.back().insert(0, indent() + "do"s + nl(comp));
10541 out.back().append(indent() + "end"s + nlr(comp)); 10585 out.back().append(indent() + "end"s + nl(comp));
10542 } 10586 }
10543 break; 10587 break;
10544 } 10588 }
10545 case ExpUsage::Return: 10589 case ExpUsage::Return:
10546 out.push_back(clearBuf() + indent() + "return "s + tbl + nlr(comp)); 10590 out.push_back(clearBuf() + indent() + "return "s + tbl + nl(comp));
10547 break; 10591 break;
10548 default: 10592 default:
10549 break; 10593 break;
@@ -10581,19 +10625,19 @@ private:
10581 funcStart = &temp.emplace_back(); 10625 funcStart = &temp.emplace_back();
10582 pushScope(); 10626 pushScope();
10583 } else { 10627 } else {
10584 temp.push_back(indent() + "do"s + nll(doNode)); 10628 temp.push_back(indent() + "do"s + nl(doNode));
10585 pushScope(); 10629 pushScope();
10586 } 10630 }
10587 transformBody(doNode->body, temp, usage, assignList); 10631 transformBody(doNode->body, temp, usage, assignList);
10588 if (usage == ExpUsage::Closure) { 10632 if (usage == ExpUsage::Closure) {
10589 popScope(); 10633 popScope();
10590 *funcStart = anonFuncStart() + nll(doNode); 10634 *funcStart = anonFuncStart() + nl(doNode);
10591 temp.push_back(indent() + anonFuncEnd()); 10635 temp.push_back(indent() + anonFuncEnd());
10592 popAnonVarArg(); 10636 popAnonVarArg();
10593 popFunctionScope(); 10637 popFunctionScope();
10594 } else { 10638 } else {
10595 popScope(); 10639 popScope();
10596 temp.push_back(indent() + "end"s + nlr(doNode)); 10640 temp.push_back(indent() + "end"s + nl(doNode));
10597 } 10641 }
10598 out.push_back(join(temp)); 10642 out.push_back(join(temp));
10599 } 10643 }
@@ -10630,7 +10674,7 @@ private:
10630 auto code = "do\n\t"s + okVar + ", ... = try nil\n\t... if "s + okVar; 10674 auto code = "do\n\t"s + okVar + ", ... = try nil\n\t... if "s + okVar;
10631 auto doNode = toAst<Do_t>(code, x); 10675 auto doNode = toAst<Do_t>(code, x);
10632 auto block = doNode->body->content.to<Block_t>(); 10676 auto block = doNode->body->content.to<Block_t>();
10633 auto asmt = static_cast<Statement_t*>(block->statements.front())->content.to<ExpListAssign_t>(); 10677 auto asmt = static_cast<Statement_t*>(block->statementOrComments.front())->content.to<ExpListAssign_t>();
10634 auto assign = asmt->action.to<Assign_t>(); 10678 auto assign = asmt->action.to<Assign_t>();
10635 auto sVal = simpleSingleValueFrom(assign->values.back()); 10679 auto sVal = simpleSingleValueFrom(assign->values.back());
10636 auto newTry = sVal->value.to<Try_t>(); 10680 auto newTry = sVal->value.to<Try_t>();
@@ -10654,8 +10698,8 @@ private:
10654 tryFunc.set(tryNode->func); 10698 tryFunc.set(tryNode->func);
10655 if (auto tryBlock = tryFunc.as<Block_t>()) { 10699 if (auto tryBlock = tryFunc.as<Block_t>()) {
10656 BLOCK_START 10700 BLOCK_START
10657 BREAK_IF(tryBlock->statements.size() != 1); 10701 BREAK_IF(countStatementFrom(tryBlock) != 1);
10658 auto stmt = static_cast<Statement_t*>(tryBlock->statements.front()); 10702 auto stmt = firstStatementFrom(tryBlock);
10659 auto expListAssign = stmt->content.as<ExpListAssign_t>(); 10703 auto expListAssign = stmt->content.as<ExpListAssign_t>();
10660 BREAK_IF(!expListAssign); 10704 BREAK_IF(!expListAssign);
10661 BREAK_IF(expListAssign->action); 10705 BREAK_IF(expListAssign->action);
@@ -10719,7 +10763,7 @@ private:
10719 auto stmt = x->new_ptr<Statement_t>(); 10763 auto stmt = x->new_ptr<Statement_t>();
10720 stmt->content.set(expListAssign); 10764 stmt->content.set(expListAssign);
10721 auto block = x->new_ptr<Block_t>(); 10765 auto block = x->new_ptr<Block_t>();
10722 block->statements.push_back(stmt); 10766 block->statementOrComments.push_back(stmt);
10723 tryFunc.set(block); 10767 tryFunc.set(block);
10724 } 10768 }
10725 } 10769 }
@@ -10747,7 +10791,7 @@ private:
10747 } 10791 }
10748 if (usage == ExpUsage::Common) { 10792 if (usage == ExpUsage::Common) {
10749 out.back().insert(0, indent()); 10793 out.back().insert(0, indent());
10750 out.back().append(nlr(x)); 10794 out.back().append(nl(x));
10751 } 10795 }
10752 return; 10796 return;
10753 } 10797 }
@@ -10772,7 +10816,7 @@ private:
10772 } 10816 }
10773 if (usage == ExpUsage::Common) { 10817 if (usage == ExpUsage::Common) {
10774 out.back().insert(0, indent()); 10818 out.back().insert(0, indent());
10775 out.back().append(nlr(x)); 10819 out.back().append(nl(x));
10776 } 10820 }
10777 return; 10821 return;
10778 } else if (auto value = singleValueFrom(tryFunc)) { 10822 } else if (auto value = singleValueFrom(tryFunc)) {
@@ -10833,7 +10877,7 @@ private:
10833 } 10877 }
10834 if (usage == ExpUsage::Common) { 10878 if (usage == ExpUsage::Common) {
10835 out.back().insert(0, indent()); 10879 out.back().insert(0, indent());
10836 out.back().append(nlr(x)); 10880 out.back().append(nl(x));
10837 } 10881 }
10838 return; 10882 return;
10839 BLOCK_END 10883 BLOCK_END
@@ -10852,7 +10896,7 @@ private:
10852 } 10896 }
10853 if (usage == ExpUsage::Common) { 10897 if (usage == ExpUsage::Common) {
10854 out.back().insert(0, indent()); 10898 out.back().insert(0, indent());
10855 out.back().append(nlr(x)); 10899 out.back().append(nl(x));
10856 } 10900 }
10857 } 10901 }
10858 10902
@@ -10928,11 +10972,11 @@ private:
10928 if (objAssign) { 10972 if (objAssign) {
10929 auto preDef = toLocalDecl(transformAssignDefs(expList, DefOp::Mark)); 10973 auto preDef = toLocalDecl(transformAssignDefs(expList, DefOp::Mark));
10930 if (!preDef.empty()) { 10974 if (!preDef.empty()) {
10931 temp.push_back(preDef + nll(importNode)); 10975 temp.push_back(preDef + nl(importNode));
10932 } 10976 }
10933 if (!currentScope().lastStatement) { 10977 if (!currentScope().lastStatement) {
10934 extraScope = true; 10978 extraScope = true;
10935 temp.push_back(indent() + "do"s + nll(importNode)); 10979 temp.push_back(indent() + "do"s + nl(importNode));
10936 pushScope(); 10980 pushScope();
10937 } 10981 }
10938 transformAssignment(objAssign, temp); 10982 transformAssignment(objAssign, temp);
@@ -10944,7 +10988,7 @@ private:
10944 if (objAssign) { 10988 if (objAssign) {
10945 if (extraScope) { 10989 if (extraScope) {
10946 popScope(); 10990 popScope();
10947 temp.push_back(indent() + "end"s + nlr(importNode)); 10991 temp.push_back(indent() + "end"s + nl(importNode));
10948 } 10992 }
10949 } 10993 }
10950 out.push_back(join(temp)); 10994 out.push_back(join(temp));
@@ -11234,7 +11278,7 @@ private:
11234 if (expList) { 11278 if (expList) {
11235 if (!currentScope().lastStatement) { 11279 if (!currentScope().lastStatement) {
11236 extraScope = true; 11280 extraScope = true;
11237 temp.push_back(indent() + "do"s + nll(whileNode)); 11281 temp.push_back(indent() + "do"s + nl(whileNode));
11238 pushScope(); 11282 pushScope();
11239 } 11283 }
11240 } 11284 }
@@ -11243,13 +11287,13 @@ private:
11243 auto lenVar = getUnusedName("_len_"sv); 11287 auto lenVar = getUnusedName("_len_"sv);
11244 addToScope(lenVar); 11288 addToScope(lenVar);
11245 auto breakLoopType = getBreakLoopType(whileNode->body, accumVar); 11289 auto breakLoopType = getBreakLoopType(whileNode->body, accumVar);
11246 _buf << indent() << "local "sv << accumVar << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nll(whileNode); 11290 _buf << indent() << "local "sv << accumVar << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nl(whileNode);
11247 temp.emplace_back(clearBuf()); 11291 temp.emplace_back(clearBuf());
11248 _buf << indent() << "local "s << lenVar << " = 1"s << nll(whileNode); 11292 _buf << indent() << "local "s << lenVar << " = 1"s << nl(whileNode);
11249 auto& lenAssign = temp.emplace_back(clearBuf()); 11293 auto& lenAssign = temp.emplace_back(clearBuf());
11250 bool isUntil = _parser.toString(whileNode->type) == "until"sv; 11294 bool isUntil = _parser.toString(whileNode->type) == "until"sv;
11251 auto condStr = transformCondExp(whileNode->condition, isUntil); 11295 auto condStr = transformCondExp(whileNode->condition, isUntil);
11252 temp.push_back(indent() + "while "s + condStr + " do"s + nll(whileNode)); 11296 temp.push_back(indent() + "while "s + condStr + " do"s + nl(whileNode));
11253 pushScope(); 11297 pushScope();
11254 if (hasBreakWithValue(breakLoopType)) { 11298 if (hasBreakWithValue(breakLoopType)) {
11255 lenAssign.clear(); 11299 lenAssign.clear();
@@ -11264,7 +11308,7 @@ private:
11264 } 11308 }
11265 } 11309 }
11266 popScope(); 11310 popScope();
11267 temp.push_back(indent() + "end"s + nlr(whileNode)); 11311 temp.push_back(indent() + "end"s + nl(whileNode));
11268 if (expList) { 11312 if (expList) {
11269 auto assign = x->new_ptr<Assign_t>(); 11313 auto assign = x->new_ptr<Assign_t>();
11270 assign->values.push_back(toAst<Exp_t>(accumVar, x)); 11314 assign->values.push_back(toAst<Exp_t>(accumVar, x));
@@ -11274,10 +11318,10 @@ private:
11274 transformAssignment(assignment, temp); 11318 transformAssignment(assignment, temp);
11275 if (extraScope) popScope(); 11319 if (extraScope) popScope();
11276 } else { 11320 } else {
11277 temp.push_back(indent() + "return "s + accumVar + nlr(whileNode)); 11321 temp.push_back(indent() + "return "s + accumVar + nl(whileNode));
11278 } 11322 }
11279 if (expList && extraScope) { 11323 if (expList && extraScope) {
11280 temp.push_back(indent() + "end"s + nlr(whileNode)); 11324 temp.push_back(indent() + "end"s + nl(whileNode));
11281 } 11325 }
11282 out.push_back(join(temp)); 11326 out.push_back(join(temp));
11283 } 11327 }
@@ -11299,12 +11343,12 @@ private:
11299 auto lenVar = getUnusedName("_len_"sv); 11343 auto lenVar = getUnusedName("_len_"sv);
11300 addToScope(lenVar); 11344 addToScope(lenVar);
11301 auto breakLoopType = getBreakLoopType(whileNode->body, accumVar); 11345 auto breakLoopType = getBreakLoopType(whileNode->body, accumVar);
11302 _buf << indent() << "local "sv << accumVar << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nll(whileNode); 11346 _buf << indent() << "local "sv << accumVar << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nl(whileNode);
11303 temp.emplace_back(clearBuf()); 11347 temp.emplace_back(clearBuf());
11304 auto& lenAssign = temp.emplace_back(indent() + "local "s + lenVar + " = 1"s + nll(whileNode)); 11348 auto& lenAssign = temp.emplace_back(indent() + "local "s + lenVar + " = 1"s + nl(whileNode));
11305 bool isUntil = _parser.toString(whileNode->type) == "until"sv; 11349 bool isUntil = _parser.toString(whileNode->type) == "until"sv;
11306 auto condStr = transformCondExp(whileNode->condition, isUntil); 11350 auto condStr = transformCondExp(whileNode->condition, isUntil);
11307 temp.push_back(indent() + "while "s + condStr + " do"s + nll(whileNode)); 11351 temp.push_back(indent() + "while "s + condStr + " do"s + nl(whileNode));
11308 pushScope(); 11352 pushScope();
11309 if (hasBreakWithValue(breakLoopType)) { 11353 if (hasBreakWithValue(breakLoopType)) {
11310 lenAssign.clear(); 11354 lenAssign.clear();
@@ -11319,10 +11363,10 @@ private:
11319 } 11363 }
11320 } 11364 }
11321 popScope(); 11365 popScope();
11322 temp.push_back(indent() + "end"s + nlr(whileNode)); 11366 temp.push_back(indent() + "end"s + nl(whileNode));
11323 temp.push_back(indent() + "return "s + accumVar + nlr(whileNode)); 11367 temp.push_back(indent() + "return "s + accumVar + nl(whileNode));
11324 popScope(); 11368 popScope();
11325 funcStart = anonFuncStart() + nll(whileNode); 11369 funcStart = anonFuncStart() + nl(whileNode);
11326 temp.push_back(indent() + anonFuncEnd()); 11370 temp.push_back(indent() + anonFuncEnd());
11327 popAnonVarArg(); 11371 popAnonVarArg();
11328 popFunctionScope(); 11372 popFunctionScope();
@@ -11363,9 +11407,9 @@ private:
11363 auto breakLoopType = getBreakLoopType(whileNode->body, Empty); 11407 auto breakLoopType = getBreakLoopType(whileNode->body, Empty);
11364 transformLoopBody(whileNode->body, temp, breakLoopType, ExpUsage::Common); 11408 transformLoopBody(whileNode->body, temp, breakLoopType, ExpUsage::Common);
11365 popScope(); 11409 popScope();
11366 _buf << indent() << "while "sv << condStr << " do"sv << nll(whileNode); 11410 _buf << indent() << "while "sv << condStr << " do"sv << nl(whileNode);
11367 _buf << temp.back(); 11411 _buf << temp.back();
11368 _buf << indent() << "end"sv << nlr(whileNode); 11412 _buf << indent() << "end"sv << nl(whileNode);
11369 out.push_back(clearBuf()); 11413 out.push_back(clearBuf());
11370 } 11414 }
11371 11415
@@ -11376,7 +11420,7 @@ private:
11376 if (expList) { 11420 if (expList) {
11377 if (!currentScope().lastStatement) { 11421 if (!currentScope().lastStatement) {
11378 extraScope = true; 11422 extraScope = true;
11379 temp.push_back(indent() + "do"s + nll(repeatNode)); 11423 temp.push_back(indent() + "do"s + nl(repeatNode));
11380 pushScope(); 11424 pushScope();
11381 } 11425 }
11382 } 11426 }
@@ -11385,12 +11429,12 @@ private:
11385 auto lenVar = getUnusedName("_len_"sv); 11429 auto lenVar = getUnusedName("_len_"sv);
11386 addToScope(lenVar); 11430 addToScope(lenVar);
11387 auto breakLoopType = getBreakLoopType(repeatNode->body, accumVar); 11431 auto breakLoopType = getBreakLoopType(repeatNode->body, accumVar);
11388 _buf << indent() << "local "sv << accumVar << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nll(repeatNode); 11432 _buf << indent() << "local "sv << accumVar << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nl(repeatNode);
11389 temp.emplace_back(clearBuf()); 11433 temp.emplace_back(clearBuf());
11390 _buf << indent() << "local "s << lenVar << " = 1"s << nll(repeatNode); 11434 _buf << indent() << "local "s << lenVar << " = 1"s << nl(repeatNode);
11391 auto& lenAssign = temp.emplace_back(clearBuf()); 11435 auto& lenAssign = temp.emplace_back(clearBuf());
11392 auto condStr = transformCondExp(repeatNode->condition, false); 11436 auto condStr = transformCondExp(repeatNode->condition, false);
11393 temp.push_back(indent() + "repeat"s + nll(repeatNode)); 11437 temp.push_back(indent() + "repeat"s + nl(repeatNode));
11394 pushScope(); 11438 pushScope();
11395 if (hasBreakWithValue(breakLoopType)) { 11439 if (hasBreakWithValue(breakLoopType)) {
11396 lenAssign.clear(); 11440 lenAssign.clear();
@@ -11405,7 +11449,7 @@ private:
11405 } 11449 }
11406 } 11450 }
11407 popScope(); 11451 popScope();
11408 temp.push_back(indent() + "until "s + condStr + nlr(repeatNode)); 11452 temp.push_back(indent() + "until "s + condStr + nl(repeatNode));
11409 if (expList) { 11453 if (expList) {
11410 auto assign = x->new_ptr<Assign_t>(); 11454 auto assign = x->new_ptr<Assign_t>();
11411 assign->values.push_back(toAst<Exp_t>(accumVar, x)); 11455 assign->values.push_back(toAst<Exp_t>(accumVar, x));
@@ -11415,10 +11459,10 @@ private:
11415 transformAssignment(assignment, temp); 11459 transformAssignment(assignment, temp);
11416 if (extraScope) popScope(); 11460 if (extraScope) popScope();
11417 } else { 11461 } else {
11418 temp.push_back(indent() + "return "s + accumVar + nlr(repeatNode)); 11462 temp.push_back(indent() + "return "s + accumVar + nl(repeatNode));
11419 } 11463 }
11420 if (expList && extraScope) { 11464 if (expList && extraScope) {
11421 temp.push_back(indent() + "end"s + nlr(repeatNode)); 11465 temp.push_back(indent() + "end"s + nl(repeatNode));
11422 } 11466 }
11423 out.push_back(join(temp)); 11467 out.push_back(join(temp));
11424 } 11468 }
@@ -11440,11 +11484,11 @@ private:
11440 auto lenVar = getUnusedName("_len_"sv); 11484 auto lenVar = getUnusedName("_len_"sv);
11441 addToScope(lenVar); 11485 addToScope(lenVar);
11442 auto breakLoopType = getBreakLoopType(repeatNode->body, accumVar); 11486 auto breakLoopType = getBreakLoopType(repeatNode->body, accumVar);
11443 _buf << indent() << "local "sv << accumVar << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nll(repeatNode); 11487 _buf << indent() << "local "sv << accumVar << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nl(repeatNode);
11444 temp.emplace_back(clearBuf()); 11488 temp.emplace_back(clearBuf());
11445 auto& lenAssign = temp.emplace_back(indent() + "local "s + lenVar + " = 1"s + nll(repeatNode)); 11489 auto& lenAssign = temp.emplace_back(indent() + "local "s + lenVar + " = 1"s + nl(repeatNode));
11446 auto condStr = transformCondExp(repeatNode->condition, false); 11490 auto condStr = transformCondExp(repeatNode->condition, false);
11447 temp.push_back(indent() + "repeat"s + nll(repeatNode)); 11491 temp.push_back(indent() + "repeat"s + nl(repeatNode));
11448 pushScope(); 11492 pushScope();
11449 if (hasBreakWithValue(breakLoopType)) { 11493 if (hasBreakWithValue(breakLoopType)) {
11450 lenAssign.clear(); 11494 lenAssign.clear();
@@ -11459,10 +11503,10 @@ private:
11459 } 11503 }
11460 } 11504 }
11461 popScope(); 11505 popScope();
11462 temp.push_back(indent() + "until "s + condStr + nlr(repeatNode)); 11506 temp.push_back(indent() + "until "s + condStr + nl(repeatNode));
11463 temp.push_back(indent() + "return "s + accumVar + nlr(repeatNode)); 11507 temp.push_back(indent() + "return "s + accumVar + nl(repeatNode));
11464 popScope(); 11508 popScope();
11465 funcStart = anonFuncStart() + nll(repeatNode); 11509 funcStart = anonFuncStart() + nl(repeatNode);
11466 temp.push_back(indent() + anonFuncEnd()); 11510 temp.push_back(indent() + anonFuncEnd());
11467 popAnonVarArg(); 11511 popAnonVarArg();
11468 popFunctionScope(); 11512 popFunctionScope();
@@ -11479,9 +11523,9 @@ private:
11479 temp.push_back(condVar); 11523 temp.push_back(condVar);
11480 } 11524 }
11481 popScope(); 11525 popScope();
11482 _buf << indent() << "repeat"sv << nll(repeat); 11526 _buf << indent() << "repeat"sv << nl(repeat);
11483 _buf << temp.front(); 11527 _buf << temp.front();
11484 _buf << indent() << "until "sv << temp.back() << nlr(repeat); 11528 _buf << indent() << "until "sv << temp.back() << nl(repeat);
11485 out.push_back(clearBuf()); 11529 out.push_back(clearBuf());
11486 } 11530 }
11487 11531
@@ -11505,7 +11549,7 @@ private:
11505 if (switchNode->assignment) { 11549 if (switchNode->assignment) {
11506 if (needScope) { 11550 if (needScope) {
11507 extraScope = true; 11551 extraScope = true;
11508 temp.push_back(indent() + "do"s + nll(x)); 11552 temp.push_back(indent() + "do"s + nl(x));
11509 pushScope(); 11553 pushScope();
11510 } 11554 }
11511 auto asmt = x->new_ptr<ExpListAssign_t>(); 11555 auto asmt = x->new_ptr<ExpListAssign_t>();
@@ -11523,7 +11567,7 @@ private:
11523 if (usage == ExpUsage::Common || usage == ExpUsage::Assignment) { 11567 if (usage == ExpUsage::Common || usage == ExpUsage::Assignment) {
11524 if (needScope && !extraScope) { 11568 if (needScope && !extraScope) {
11525 extraScope = true; 11569 extraScope = true;
11526 temp.push_back(indent() + "do"s + nll(x)); 11570 temp.push_back(indent() + "do"s + nl(x));
11527 pushScope(); 11571 pushScope();
11528 } 11572 }
11529 } 11573 }
@@ -11553,13 +11597,13 @@ private:
11553 } 11597 }
11554 if (tableMatching) { 11598 if (tableMatching) {
11555 if (!firstBranch) { 11599 if (!firstBranch) {
11556 temp.push_back(indent() + "else"s + nll(branch)); 11600 temp.push_back(indent() + "else"s + nl(branch));
11557 pushScope(); 11601 pushScope();
11558 addScope++; 11602 addScope++;
11559 } 11603 }
11560 if (tabCheckVar.empty()) { 11604 if (tabCheckVar.empty()) {
11561 if (!extraScope && needScope) { 11605 if (!extraScope && needScope) {
11562 temp.push_back(indent() + "do"s + nll(branch)); 11606 temp.push_back(indent() + "do"s + nl(branch));
11563 pushScope(); 11607 pushScope();
11564 extraScope = true; 11608 extraScope = true;
11565 } 11609 }
@@ -11567,17 +11611,17 @@ private:
11567 forceAddToScope(typeVar); 11611 forceAddToScope(typeVar);
11568 tabCheckVar = getUnusedName("_tab_"sv); 11612 tabCheckVar = getUnusedName("_tab_"sv);
11569 forceAddToScope(tabCheckVar); 11613 forceAddToScope(tabCheckVar);
11570 temp.push_back(indent() + "local "s + typeVar + " = "s + globalVar("type"sv, branch, AccessType::Read) + '(' + objVar + ')' + nll(branch)); 11614 temp.push_back(indent() + "local "s + typeVar + " = "s + globalVar("type"sv, branch, AccessType::Read) + '(' + objVar + ')' + nl(branch));
11571 temp.push_back(indent() + "local "s + tabCheckVar + " = \"table\" == "s + typeVar + " or \"userdata\" == "s + typeVar + nll(branch)); 11615 temp.push_back(indent() + "local "s + tabCheckVar + " = \"table\" == "s + typeVar + " or \"userdata\" == "s + typeVar + nl(branch));
11572 } 11616 }
11573 std::string matchVar; 11617 std::string matchVar;
11574 bool lastBranch = branches.back() == branch_ && !switchNode->lastBranch; 11618 bool lastBranch = branches.back() == branch_ && !switchNode->lastBranch;
11575 if (!lastBranch) { 11619 if (!lastBranch) {
11576 matchVar = getUnusedName("_match_"sv); 11620 matchVar = getUnusedName("_match_"sv);
11577 forceAddToScope(matchVar); 11621 forceAddToScope(matchVar);
11578 temp.push_back(indent() + "local "s + matchVar + " = false"s + nll(branch)); 11622 temp.push_back(indent() + "local "s + matchVar + " = false"s + nl(branch));
11579 } 11623 }
11580 temp.back().append(indent() + "if "s + tabCheckVar + " then"s + nll(branch)); 11624 temp.back().append(indent() + "if "s + tabCheckVar + " then"s + nl(branch));
11581 pushScope(); 11625 pushScope();
11582 auto chainValue = toAst<ChainValue_t>(objVar, branch); 11626 auto chainValue = toAst<ChainValue_t>(objVar, branch);
11583 auto assignment = assignmentFrom(static_cast<Exp_t*>(valueList->exprs.front()), newExp(chainValue, branch), branch); 11627 auto assignment = assignmentFrom(static_cast<Exp_t*>(valueList->exprs.front()), newExp(chainValue, branch), branch);
@@ -11620,21 +11664,21 @@ private:
11620 } 11664 }
11621 } 11665 }
11622 if (!conds.empty()) { 11666 if (!conds.empty()) {
11623 temp.push_back(indent() + "if "s + join(conds, " and "sv) + " then"s + nll(branch)); 11667 temp.push_back(indent() + "if "s + join(conds, " and "sv) + " then"s + nl(branch));
11624 pushScope(); 11668 pushScope();
11625 } 11669 }
11626 if (!lastBranch) { 11670 if (!lastBranch) {
11627 temp.push_back(indent() + matchVar + " = true"s + nll(branch)); 11671 temp.push_back(indent() + matchVar + " = true"s + nl(branch));
11628 } 11672 }
11629 transform_plain_body(branch->body, temp, usage, assignList); 11673 transform_plain_body(branch->body, temp, usage, assignList);
11630 if (!conds.empty()) { 11674 if (!conds.empty()) {
11631 popScope(); 11675 popScope();
11632 temp.push_back(indent() + "end"s + nll(branch)); 11676 temp.push_back(indent() + "end"s + nl(branch));
11633 } 11677 }
11634 if (!lastBranch) { 11678 if (!lastBranch) {
11635 popScope(); 11679 popScope();
11636 temp.push_back(indent() + "end"s + nll(branch)); 11680 temp.push_back(indent() + "end"s + nl(branch));
11637 temp.push_back(indent() + "if not "s + matchVar + " then"s + nll(branch)); 11681 temp.push_back(indent() + "if not "s + matchVar + " then"s + nl(branch));
11638 pushScope(); 11682 pushScope();
11639 addScope++; 11683 addScope++;
11640 } else { 11684 } else {
@@ -11654,7 +11698,7 @@ private:
11654 } 11698 }
11655 temp.back().append(' ' + tmp.back() + " == "s + (exp == exprs.back() ? objVar : objVar + " or"s)); 11699 temp.back().append(' ' + tmp.back() + " == "s + (exp == exprs.back() ? objVar : objVar + " or"s));
11656 } 11700 }
11657 temp.back().append(" then"s + nll(branch)); 11701 temp.back().append(" then"s + nl(branch));
11658 pushScope(); 11702 pushScope();
11659 transform_plain_body(branch->body, temp, usage, assignList); 11703 transform_plain_body(branch->body, temp, usage, assignList);
11660 popScope(); 11704 popScope();
@@ -11662,7 +11706,7 @@ private:
11662 } 11706 }
11663 if (switchNode->lastBranch) { 11707 if (switchNode->lastBranch) {
11664 if (!firstBranch) { 11708 if (!firstBranch) {
11665 temp.push_back(indent() + "else"s + nll(switchNode->lastBranch)); 11709 temp.push_back(indent() + "else"s + nl(switchNode->lastBranch));
11666 pushScope(); 11710 pushScope();
11667 } else { 11711 } else {
11668 addScope--; 11712 addScope--;
@@ -11672,20 +11716,20 @@ private:
11672 } 11716 }
11673 while (addScope > 0) { 11717 while (addScope > 0) {
11674 addScope--; 11718 addScope--;
11675 temp.push_back(indent() + "end"s + nlr(switchNode)); 11719 temp.push_back(indent() + "end"s + nl(switchNode));
11676 popScope(); 11720 popScope();
11677 } 11721 }
11678 temp.push_back(indent() + "end"s + nlr(switchNode)); 11722 temp.push_back(indent() + "end"s + nl(switchNode));
11679 if (usage == ExpUsage::Closure) { 11723 if (usage == ExpUsage::Closure) {
11680 popFunctionScope(); 11724 popFunctionScope();
11681 popScope(); 11725 popScope();
11682 *funcStart = anonFuncStart() + nll(switchNode); 11726 *funcStart = anonFuncStart() + nl(switchNode);
11683 temp.push_back(indent() + anonFuncEnd()); 11727 temp.push_back(indent() + anonFuncEnd());
11684 popAnonVarArg(); 11728 popAnonVarArg();
11685 } 11729 }
11686 if (extraScope) { 11730 if (extraScope) {
11687 popScope(); 11731 popScope();
11688 temp.push_back(indent() + "end"s + nlr(switchNode)); 11732 temp.push_back(indent() + "end"s + nl(switchNode));
11689 } 11733 }
11690 out.push_back(join(temp)); 11734 out.push_back(join(temp));
11691 } 11735 }
@@ -11704,7 +11748,7 @@ private:
11704 } 11748 }
11705 auto preDefine = toLocalDecl(defs); 11749 auto preDefine = toLocalDecl(defs);
11706 if (!preDefine.empty()) { 11750 if (!preDefine.empty()) {
11707 out.push_back(preDefine + nll(local)); 11751 out.push_back(preDefine + nl(local));
11708 } 11752 }
11709 } 11753 }
11710 } 11754 }
@@ -11909,7 +11953,7 @@ private:
11909 } 11953 }
11910 str_list temp; 11954 str_list temp;
11911 if (localAttrib->forceLocal) { 11955 if (localAttrib->forceLocal) {
11912 temp.push_back(indent() + "local "s + join(vars, ", "sv) + nll(x)); 11956 temp.push_back(indent() + "local "s + join(vars, ", "sv) + nl(x));
11913 } 11957 }
11914 transformAssignment(assignment, temp); 11958 transformAssignment(assignment, temp);
11915 for (const auto& name : vars) { 11959 for (const auto& name : vars) {
@@ -11955,13 +11999,13 @@ private:
11955 auto rit = items.begin(); 11999 auto rit = items.begin();
11956 str_list tmp; 12000 str_list tmp;
11957 while (lit != vars.end()) { 12001 while (lit != vars.end()) {
11958 tmp.push_back(indent() + "local "s + *lit + (target >= 504 ? " <close> = "s : " = "s) + *rit + nll(x)); 12002 tmp.push_back(indent() + "local "s + *lit + (target >= 504 ? " <close> = "s : " = "s) + *rit + nl(x));
11959 lit++; 12003 lit++;
11960 rit++; 12004 rit++;
11961 } 12005 }
11962 temp.push_back(join(tmp)); 12006 temp.push_back(join(tmp));
11963 } else { 12007 } else {
11964 temp.push_back(indent() + "local "s + join(vars, ", "sv) + " = "s + join(items, ", "sv) + nll(x)); 12008 temp.push_back(indent() + "local "s + join(vars, ", "sv) + " = "s + join(items, ", "sv) + nl(x));
11965 str_list leftVars; 12009 str_list leftVars;
11966 pushScope(); 12010 pushScope();
11967 for (size_t i = 0; i < vars.size(); i++) { 12011 for (size_t i = 0; i < vars.size(); i++) {
@@ -11982,7 +12026,7 @@ private:
11982 for (auto item : assignA->values.objects()) { 12026 for (auto item : assignA->values.objects()) {
11983 transformAssignItem(item, items); 12027 transformAssignItem(item, items);
11984 } 12028 }
11985 temp.push_back(indent() + "local "s + join(leftVars, ", "sv) + " = "s + join(items, ", "sv) + nll(x)); 12029 temp.push_back(indent() + "local "s + join(leftVars, ", "sv) + " = "s + join(items, ", "sv) + nl(x));
11986 } 12030 }
11987 for (const auto& var : vars) { 12031 for (const auto& var : vars) {
11988 markVarLocalConst(var); 12032 markVarLocalConst(var);
@@ -12007,7 +12051,7 @@ private:
12007 vars.push_back(item.targetVar); 12051 vars.push_back(item.targetVar);
12008 } 12052 }
12009 } 12053 }
12010 temp.push_back(indent() + "local "s + join(vars, ", "sv) + nll(x)); 12054 temp.push_back(indent() + "local "s + join(vars, ", "sv) + nl(x));
12011 transformAssignment(assignment, temp); 12055 transformAssignment(assignment, temp);
12012 for (const auto& name : vars) { 12056 for (const auto& name : vars) {
12013 markVarLocalConst(name); 12057 markVarLocalConst(name);
@@ -12028,7 +12072,7 @@ private:
12028 auto assignment = assignmentFrom(exp, breakLoop->value, breakLoop); 12072 auto assignment = assignmentFrom(exp, breakLoop->value, breakLoop);
12029 transformAssignment(assignment, out); 12073 transformAssignment(assignment, out);
12030 } 12074 }
12031 out.push_back(indent() + keyword + nll(breakLoop)); 12075 out.push_back(indent() + keyword + nl(breakLoop));
12032 return; 12076 return;
12033 } 12077 }
12034 if (_continueVars.empty()) throw CompileError("continue is not inside a loop"sv, breakLoop); 12078 if (_continueVars.empty()) throw CompileError("continue is not inside a loop"sv, breakLoop);
@@ -12041,8 +12085,8 @@ private:
12041 if (!temp.empty()) { 12085 if (!temp.empty()) {
12042 _buf << temp.back(); 12086 _buf << temp.back();
12043 } 12087 }
12044 _buf << indent() << item.var << " = true"sv << nll(breakLoop); 12088 _buf << indent() << item.var << " = true"sv << nl(breakLoop);
12045 _buf << indent() << "break"sv << nll(breakLoop); 12089 _buf << indent() << "break"sv << nl(breakLoop);
12046 out.push_back(clearBuf()); 12090 out.push_back(clearBuf());
12047 } else { 12091 } else {
12048 transformGoto(toAst<Goto_t>("goto "s + item.var, breakLoop), temp); 12092 transformGoto(toAst<Goto_t>("goto "s + item.var, breakLoop), temp);
@@ -12068,7 +12112,7 @@ private:
12068 throw CompileError("label '"s + labelStr + "' already defined at line "s + std::to_string(it->second.line), label); 12112 throw CompileError("label '"s + labelStr + "' already defined at line "s + std::to_string(it->second.line), label);
12069 } 12113 }
12070 scope[labelStr] = {label->m_begin.m_line, static_cast<int>(_scopes.size())}; 12114 scope[labelStr] = {label->m_begin.m_line, static_cast<int>(_scopes.size())};
12071 out.push_back(indent() + "::"s + labelStr + "::"s + nll(label)); 12115 out.push_back(indent() + "::"s + labelStr + "::"s + nl(label));
12072 } 12116 }
12073 12117
12074 void transformGoto(Goto_t* gotoNode, str_list& out) { 12118 void transformGoto(Goto_t* gotoNode, str_list& out) {
@@ -12077,7 +12121,7 @@ private:
12077 } 12121 }
12078 auto labelStr = unicodeVariableFrom(gotoNode->label); 12122 auto labelStr = unicodeVariableFrom(gotoNode->label);
12079 gotos.push_back({gotoNode, labelStr, _gotoScopes.top(), static_cast<int>(_scopes.size())}); 12123 gotos.push_back({gotoNode, labelStr, _gotoScopes.top(), static_cast<int>(_scopes.size())});
12080 out.push_back(indent() + "goto "s + labelStr + nll(gotoNode)); 12124 out.push_back(indent() + "goto "s + labelStr + nl(gotoNode));
12081 } 12125 }
12082 12126
12083 void transformShortTabAppending(ShortTabAppending_t* tab, str_list& out) { 12127 void transformShortTabAppending(ShortTabAppending_t* tab, str_list& out) {
@@ -12141,13 +12185,13 @@ private:
12141 temp.push_back(getPreDefineLine(assignment)); 12185 temp.push_back(getPreDefineLine(assignment));
12142 } 12186 }
12143 assignments.push_front(assignmentFrom(newValue, value, value)); 12187 assignments.push_front(assignmentFrom(newValue, value, value));
12144 temp.push_back(indent() + "do"s + nll(x)); 12188 temp.push_back(indent() + "do"s + nl(x));
12145 pushScope(); 12189 pushScope();
12146 for (auto item : assignments.objects()) { 12190 for (auto item : assignments.objects()) {
12147 transformAssignment(static_cast<ExpListAssign_t*>(item), temp); 12191 transformAssignment(static_cast<ExpListAssign_t*>(item), temp);
12148 } 12192 }
12149 popScope(); 12193 popScope();
12150 temp.push_back(indent() + "end"s + nll(x)); 12194 temp.push_back(indent() + "end"s + nl(x));
12151 out.push_back(join(temp)); 12195 out.push_back(join(temp));
12152 } 12196 }
12153}; 12197};
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index 5a54690..cacfebe 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -1082,48 +1082,35 @@ YueParser::YueParser() {
1082 IfLine = IfType >> space >> IfCond; 1082 IfLine = IfType >> space >> IfCond;
1083 WhileLine = WhileType >> space >> Exp; 1083 WhileLine = WhileType >> space >> Exp;
1084 1084
1085 YueLineComment = *(not_(set("\r\n")) >> any_char);
1086 yue_line_comment = "--" >> YueLineComment >> and_(stop);
1087 MultilineCommentInner = multi_line_content;
1088 YueMultilineComment = multi_line_open >> MultilineCommentInner >> multi_line_close;
1089 yue_comment = check_indent >> (
1090 (
1091 YueMultilineComment >>
1092 *(set(" \t") | YueMultilineComment) >>
1093 -yue_line_comment
1094 ) | yue_line_comment
1095 ) >> and_(line_break);
1096
1097 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; 1085 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign;
1098 1086
1099 StatementAppendix = (IfLine | WhileLine | CompInner) >> space; 1087 StatementAppendix = (IfLine | WhileLine | CompInner) >> space;
1100 Statement = 1088 Statement =
1101 Seperator >> 1089 (
1102 -(
1103 yue_comment >>
1104 *(line_break >> yue_comment) >>
1105 line_break >>
1106 check_indent_match
1107 ) >>
1108 space >> (
1109 Import | While | Repeat | For | ForEach | 1090 Import | While | Repeat | For | ForEach |
1110 Return | Local | Global | Export | Macro | 1091 Return | Local | Global | Export | Macro |
1111 MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | 1092 MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending |
1112 LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | 1093 LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign |
1113 StatementAppendix >> empty_block_error | 1094 StatementAppendix >> empty_block_error |
1114 and_(key("else") | key("elseif") | key("when")) >> dangling_clause_error 1095 and_(key("else") | key("elseif") | key("when")) >> dangling_clause_error
1115 ) >> 1096 ) >> space >>
1116 space >>
1117 -StatementAppendix; 1097 -StatementAppendix;
1118 1098
1119 StatementSep = white >> (set("('\"") | "[[" | "[="); 1099 StatementSep = white >> (set("('\"") | "[[" | "[=");
1120 1100
1121 Body = in_block | Statement; 1101 Body = in_block | Statement;
1122 1102
1123 empty_line_break = 1103 YueLineComment = *(not_(set("\r\n")) >> any_char);
1124 check_indent >> (multi_line_comment >> space | comment) >> and_(stop) | 1104 yue_line_comment = "--" >> YueLineComment >> and_(stop);
1125 advance >> ensure(multi_line_comment >> space | comment, pop_indent) >> and_(stop) | 1105 YueMultilineComment = multi_line_content;
1126 plain_space >> and_(line_break); 1106 yue_multiline_comment = multi_line_open >> YueMultilineComment >> multi_line_close;
1107 comment_line =
1108 yue_multiline_comment >> *(set(" \t") | yue_multiline_comment) >> plain_space >> -yue_line_comment |
1109 yue_line_comment;
1110 YueComment =
1111 check_indent >> comment_line >> and_(stop) |
1112 advance >> ensure(comment_line, pop_indent) >> and_(stop) |
1113 plain_space >> and_(stop);
1127 1114
1128 indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) { 1115 indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) {
1129 RaiseError("unexpected indent"sv, item); 1116 RaiseError("unexpected indent"sv, item);
@@ -1131,18 +1118,18 @@ YueParser::YueParser() {
1131 }); 1118 });
1132 1119
1133 line = ( 1120 line = (
1134 check_indent_match >> Statement | 1121 check_indent_match >> space >> Statement |
1135 empty_line_break | 1122 YueComment |
1136 advance_match >> ensure(space >> (indentation_error | Statement), pop_indent) 1123 advance_match >> ensure(space >> (indentation_error | Statement), pop_indent)
1137 ); 1124 );
1138 Block = Seperator >> (pl::user(true_(), [](const item_t& item) { 1125 Block = Seperator >> (pl::user(true_(), [](const item_t& item) {
1139 State* st = reinterpret_cast<State*>(item.user_data); 1126 State* st = reinterpret_cast<State*>(item.user_data);
1140 return st->lax; 1127 return st->lax;
1141 }) >> lax_line >> *(+line_break >> lax_line) | line >> *(+line_break >> line)); 1128 }) >> lax_line >> *(line_break >> lax_line) | line >> *(line_break >> line));
1142 1129
1143 shebang = "#!" >> *(not_(stop) >> any_char); 1130 shebang = "#!" >> *(not_(stop) >> any_char);
1144 BlockEnd = Block >> white >> stop; 1131 BlockEnd = Block >> stop;
1145 File = -shebang >> -Block >> white >> stop; 1132 File = -shebang >> -Block >> stop;
1146 1133
1147 lax_line = advance_match >> ensure(*(not_(stop) >> any()), pop_indent) | line >> and_(stop) | check_indent_match >> *(not_(stop) >> any()); 1134 lax_line = advance_match >> ensure(*(not_(stop) >> any()), pop_indent) | line >> and_(stop) | check_indent_match >> *(not_(stop) >> any());
1148} 1135}
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index 3aca4ef..3b1cd61 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -308,9 +308,9 @@ private:
308 NONE_AST_RULE(must_exp); 308 NONE_AST_RULE(must_exp);
309 NONE_AST_RULE(must_unary_exp); 309 NONE_AST_RULE(must_unary_exp);
310 NONE_AST_RULE(local_const_item); 310 NONE_AST_RULE(local_const_item);
311 NONE_AST_RULE(empty_line_break); 311 NONE_AST_RULE(comment_line);
312 NONE_AST_RULE(yue_comment);
313 NONE_AST_RULE(yue_line_comment); 312 NONE_AST_RULE(yue_line_comment);
313 NONE_AST_RULE(yue_multiline_comment);
314 NONE_AST_RULE(line); 314 NONE_AST_RULE(line);
315 NONE_AST_RULE(shebang); 315 NONE_AST_RULE(shebang);
316 NONE_AST_RULE(lax_line); 316 NONE_AST_RULE(lax_line);
@@ -471,8 +471,8 @@ private:
471 AST_RULE(Statement); 471 AST_RULE(Statement);
472 AST_RULE(StatementSep); 472 AST_RULE(StatementSep);
473 AST_RULE(YueLineComment); 473 AST_RULE(YueLineComment);
474 AST_RULE(MultilineCommentInner);
475 AST_RULE(YueMultilineComment); 474 AST_RULE(YueMultilineComment);
475 AST_RULE(YueComment);
476 AST_RULE(ChainAssign); 476 AST_RULE(ChainAssign);
477 AST_RULE(Body); 477 AST_RULE(Body);
478 AST_RULE(Block); 478 AST_RULE(Block);
diff --git a/src/yuescript/yuescript.cpp b/src/yuescript/yuescript.cpp
index 52236bf..6089894 100644
--- a/src/yuescript/yuescript.cpp
+++ b/src/yuescript/yuescript.cpp
@@ -185,6 +185,11 @@ static int yueformat(lua_State* L) {
185 if (!lua_isnoneornil(L, 2)) { 185 if (!lua_isnoneornil(L, 2)) {
186 tabSize = static_cast<int>(luaL_checkinteger(L, 2)); 186 tabSize = static_cast<int>(luaL_checkinteger(L, 2));
187 } 187 }
188 bool reserveComment = true;
189 if (!lua_isnoneornil(L, 3)) {
190 luaL_checktype(L, 3, LUA_TBOOLEAN);
191 reserveComment = lua_toboolean(L, 3) != 0;
192 }
188 std::string_view codes(input, len); 193 std::string_view codes(input, len);
189 auto info = yue::YueParser::shared().parse<yue::File_t>(codes, false); 194 auto info = yue::YueParser::shared().parse<yue::File_t>(codes, false);
190 if (info.error) { 195 if (info.error) {
@@ -206,8 +211,11 @@ static int yueformat(lua_State* L) {
206 } else { 211 } else {
207 formatter.spaceOverTab = false; 212 formatter.spaceOverTab = false;
208 } 213 }
214 formatter.reserveComment = reserveComment;
209 auto result = formatter.toString(info.node.get()); 215 auto result = formatter.toString(info.node.get());
210 yue::Utils::replace(result, "\n\n", "\n"); 216 if (!formatter.reserveComment) {
217 yue::Utils::replace(result, "\n\n", "\n");
218 }
211 lua_pushlstring(L, result.c_str(), result.size()); 219 lua_pushlstring(L, result.c_str(), result.size());
212 return 1; 220 return 1;
213} 221}
@@ -295,6 +303,11 @@ static int yuetoast(lua_State* L) {
295 luaL_checktype(L, 4, LUA_TBOOLEAN); 303 luaL_checktype(L, 4, LUA_TBOOLEAN);
296 lax = lua_toboolean(L, 4) != 0; 304 lax = lua_toboolean(L, 4) != 0;
297 } 305 }
306 bool reserveComment = false;
307 if (!lua_isnoneornil(L, 5)) {
308 luaL_checktype(L, 5, LUA_TBOOLEAN);
309 reserveComment = lua_toboolean(L, 5) != 0;
310 }
298 auto& yueParser = yue::YueParser::shared(); 311 auto& yueParser = yue::YueParser::shared();
299 auto info = ruleName.empty() ? yueParser.parse<yue::File_t>({input, size}, lax) : yueParser.parse(ruleName, {input, size}, lax); 312 auto info = ruleName.empty() ? yueParser.parse<yue::File_t>({input, size}, lax) : yueParser.parse(ruleName, {input, size}, lax);
300 if (!info.error) { 313 if (!info.error) {
@@ -322,13 +335,11 @@ static int yuetoast(lua_State* L) {
322 }; 335 };
323 do_call(info.node); 336 do_call(info.node);
324 yue::YueFormat formatter{}; 337 yue::YueFormat formatter{};
338 formatter.reserveComment = reserveComment;
325 while (!stack.empty()) { 339 while (!stack.empty()) {
326 auto& current = stack.top(); 340 auto& current = stack.top();
327 int continuation = current.continuation; 341 int continuation = current.continuation;
328 auto node = current.node; 342 auto node = current.node;
329 if (auto comment = yue::ast_cast<yue::YueMultilineComment_t>(node)) {
330 node = comment->inner.get();
331 }
332 switch (continuation) { 343 switch (continuation) {
333 case 0: { 344 case 0: {
334 if (!current.children) { 345 if (!current.children) {
@@ -337,6 +348,9 @@ static int yuetoast(lua_State* L) {
337 current.hasSep = true; 348 current.hasSep = true;
338 return false; 349 return false;
339 } 350 }
351 if (!reserveComment && yue::ast_is<yue::YueComment_t>(child)) {
352 return false;
353 }
340 if (!current.children) { 354 if (!current.children) {
341 current.children = std::make_unique<std::vector<yue::ast_node*>>(); 355 current.children = std::make_unique<std::vector<yue::ast_node*>>();
342 } 356 }