From 7575fe00aad91e0ba943e877ddcd838f76e095c0 Mon Sep 17 00:00:00 2001 From: Li Jin 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. --- src/yuescript/yue_compiler.cpp | 39 ++++++++++++++++++++++++++++++++++++--- src/yuescript/yue_parser.cpp | 4 ++-- 2 files changed, 38 insertions(+), 5 deletions(-) (limited to 'src') 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 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(node); - if (auto pipeBody = stmt->content.as()) { + if (!stmt->appendix && stmt->content.is() && 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()) { 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()) { + if (!block->statements.empty()) { + Statement_t* stmt = static_cast(block->statements.back()); + if (stmt->content.is()) { + auto newBlock = with->body->new_ptr(); + newBlock->statements.dup(block->statements); + newBlock->statements.pop_back(); + transform_plain_body(newBlock, temp, ExpUsage::Common); + auto newBody = stmt->new_ptr(); + newBody->content.set(stmt); + auto doNode = stmt->new_ptr(); + doNode->body.set(newBody); + transformDo(doNode, temp, ExpUsage::Common); + transformed = true; + } + } + } else { + auto stmt = with->body.to(); + if (stmt->content.is()) { + auto newBody = stmt->new_ptr(); + newBody->content.set(stmt); + auto doNode = stmt->new_ptr(); + 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