From 7575fe00aad91e0ba943e877ddcd838f76e095c0 Mon Sep 17 00:00:00 2001 From: Li Jin <dragon-fly@qq.com> Date: Thu, 26 Sep 2024 22:11:13 +0800 Subject: Fixed a few issues. * Fixed a `with` block with return statement issue. * Fixed a switch-when indentation issue. * Added error reporting for `return` statement not appearing in last block line. --- spec/inputs/syntax.yue | 4 ++-- spec/inputs/unicode/syntax.yue | 4 ++-- spec/outputs/syntax.lua | 14 +++++++++----- spec/outputs/unicode/syntax.lua | 14 +++++++++----- spec/outputs/unicode/with.lua | 4 +++- spec/outputs/with.lua | 4 +++- src/yuescript/yue_compiler.cpp | 39 ++++++++++++++++++++++++++++++++++++--- src/yuescript/yue_parser.cpp | 4 ++-- 8 files changed, 66 insertions(+), 21 deletions(-) diff --git a/spec/inputs/syntax.yue b/spec/inputs/syntax.yue index 271f43f..a414d6f 100644 --- a/spec/inputs/syntax.yue +++ b/spec/inputs/syntax.yue @@ -52,9 +52,9 @@ _ = -> _ = -> 1,2,34 -return 5 + () -> 4 + 2 +do return 5 + () -> 4 + 2 -return 5 + (() -> 4) + 2 +do return 5 + (() -> 4) + 2 print 5 + () -> _ = 34 diff --git a/spec/inputs/unicode/syntax.yue b/spec/inputs/unicode/syntax.yue index f382688..8a98416 100644 --- a/spec/inputs/unicode/syntax.yue +++ b/spec/inputs/unicode/syntax.yue @@ -51,9 +51,9 @@ _ = -> _ = -> 1,2,34 -return 5 + () -> 4 + 2 +do return 5 + () -> 4 + 2 -return 5 + (() -> 4) + 2 +do return 5 + (() -> 4) + 2 打印 5 + () -> _ = 34 diff --git a/spec/outputs/syntax.lua b/spec/outputs/syntax.lua index cfe63eb..5fd1821 100644 --- a/spec/outputs/syntax.lua +++ b/spec/outputs/syntax.lua @@ -40,12 +40,16 @@ end _ = function() return 1, 2, 34 end -return 5 + function() - return 4 + 2 +do + return 5 + function() + return 4 + 2 + end +end +do + return 5 + (function() + return 4 + end) + 2 end -return 5 + (function() - return 4 -end) + 2 print(5 + function() _ = 34 return good(nads) diff --git a/spec/outputs/unicode/syntax.lua b/spec/outputs/unicode/syntax.lua index 9ea8f68..ea97bb9 100644 --- a/spec/outputs/unicode/syntax.lua +++ b/spec/outputs/unicode/syntax.lua @@ -40,12 +40,16 @@ end _ = function() return 1, 2, 34 end -return 5 + function() - return 4 + 2 +do + return 5 + function() + return 4 + 2 + end +end +do + return 5 + (function() + return 4 + end) + 2 end -return 5 + (function() - return 4 -end) + 2 _u6253_u5370(5 + function() _ = 34 return _u597d(_u7403) diff --git a/spec/outputs/unicode/with.lua b/spec/outputs/unicode/with.lua index 7a5ba00..cfad264 100644 --- a/spec/outputs/unicode/with.lua +++ b/spec/outputs/unicode/with.lua @@ -123,7 +123,9 @@ do local _ _ = function() local _with_0 = _u55e8 - return _with_0.a, _with_0.b + do + return _with_0.a, _with_0.b + end end end do diff --git a/spec/outputs/with.lua b/spec/outputs/with.lua index b2a1c3b..d880d1e 100644 --- a/spec/outputs/with.lua +++ b/spec/outputs/with.lua @@ -121,7 +121,9 @@ do local _ _ = function() local _with_0 = hi - return _with_0.a, _with_0.b + do + return _with_0.a, _with_0.b + end end end do diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 5d031db..c346891 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.25.1"sv; +const std::string_view version = "0.25.2"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -4490,7 +4490,9 @@ private: for (auto it = nodes.begin(); it != nodes.end(); ++it) { auto node = *it; auto stmt = static_cast<Statement_t*>(node); - if (auto pipeBody = stmt->content.as<PipeBody_t>()) { + if (!stmt->appendix && stmt->content.is<Return_t>() && stmt != nodes.back()) { + throw CompileError("'return' statement must be the last line in the block"sv, stmt->content); + } else if (auto pipeBody = stmt->content.as<PipeBody_t>()) { auto x = stmt; bool cond = false; BLOCK_START @@ -9151,7 +9153,38 @@ private: ifNode->nodes.push_back(with->body); transformIf(ifNode, temp, ExpUsage::Common); } else { - transform_plain_body(with->body, temp, ExpUsage::Common); + bool transformed = false; + if (auto block = with->body.as<Block_t>()) { + if (!block->statements.empty()) { + Statement_t* stmt = static_cast<Statement_t*>(block->statements.back()); + if (stmt->content.is<Return_t>()) { + auto newBlock = with->body->new_ptr<Block_t>(); + newBlock->statements.dup(block->statements); + newBlock->statements.pop_back(); + transform_plain_body(newBlock, temp, ExpUsage::Common); + auto newBody = stmt->new_ptr<Body_t>(); + newBody->content.set(stmt); + auto doNode = stmt->new_ptr<Do_t>(); + doNode->body.set(newBody); + transformDo(doNode, temp, ExpUsage::Common); + transformed = true; + } + } + } else { + auto stmt = with->body.to<Statement_t>(); + if (stmt->content.is<Return_t>()) { + auto newBody = stmt->new_ptr<Body_t>(); + newBody->content.set(stmt); + auto doNode = stmt->new_ptr<Do_t>(); + doNode->body.set(newBody); + transformDo(doNode, temp, ExpUsage::Common); + temp.back().insert(0, indent()); + transformed = true; + } + } + if (!transformed) { + transform_plain_body(with->body, temp, ExpUsage::Common); + } } _withVars.pop(); if (assignList) { diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index e5337b0..93787cd 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -369,11 +369,11 @@ YueParser::YueParser() { Switch = key("switch") >> space >> Exp >> space >> Seperator >> ( SwitchCase >> space >> ( - line_break >> *space_break >> check_indent_match >> space >> SwitchCase >> switch_block | + switch_block | *(space >> SwitchCase) >> -(space >> switch_else) ) | +space_break >> advance_match >> space >> SwitchCase >> switch_block >> pop_indent - ) >> switch_block; + ); Assignment = -(',' >> space >> ExpList >> space) >> (':' >> Assign | and_('=') >> if_assignment_syntax_error); IfCond = disable_chain_rule(disable_arg_table_block_rule(Exp >> -(space >> Assignment))); -- cgit v1.2.3-55-g6feb