From 69f896ca6960419133bf9a5ecc231f7aa934ac56 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Fri, 14 Nov 2025 18:23:38 +0800 Subject: Fixed issue #223. --- src/yuescript/yue_ast.h | 2 +- src/yuescript/yue_compiler.cpp | 47 +++++++++++++++++++++++++++++------------- src/yuescript/yue_parser.cpp | 2 +- 3 files changed, 35 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index b1a369b..0008fd6 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h @@ -443,7 +443,7 @@ AST_END(CompInner) AST_NODE(Assign) ast_ptr sep; - ast_sel_list values; + ast_sel_list values; AST_MEMBER(Assign, &sep, &values) AST_END(Assign) diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index ed0a587..8c28e61 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -78,7 +78,7 @@ static std::unordered_set Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.29.7"sv; +const std::string_view version = "0.29.8"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -2321,15 +2321,27 @@ private: transformAssignment(newAssignment, temp); varName = objVar; } - auto newAssignment = x->new_ptr(); - newAssignment->expList.set(toAst(varName + "[#"s + varName + "+1]"s, x)); - auto assign = x->new_ptr(); - if (vit == values.end()) { - throw CompileError("right value missing"sv, values.front()); + if (auto spread = ast_cast(*vit)) { + auto lenVar = getUnusedName("_len_"sv); + forceAddToScope(lenVar); + temp.push_back(indent() + "local "s + lenVar + " = #"s + varName + " + 1"s + nll(spread)); + auto elmVar = getUnusedName("_elm_"sv); + _buf << varName << '[' << lenVar << "],"s << lenVar << "="s << elmVar << ',' << lenVar << "+1 for "s << elmVar << " in *nil"s; + auto stmt = toAst(clearBuf(), spread); + auto comp = stmt->appendix->item.to(); + ast_to(comp->items.front())->loopValue.to()->value.set(spread->exp); + transformStatement(stmt, temp); + } else { + auto newAssignment = x->new_ptr(); + newAssignment->expList.set(toAst(varName + "[#"s + varName + "+1]"s, x)); + auto assign = x->new_ptr(); + if (vit == values.end()) { + throw CompileError("right value missing"sv, values.front()); + } + assign->values.push_back(*vit); + newAssignment->action.set(assign); + transformAssignment(newAssignment, temp); } - assign->values.push_back(*vit); - newAssignment->action.set(assign); - transformAssignment(newAssignment, temp); if (extraScoped) { popScope(); temp.push_back(indent() + "end"s + nlr(x)); @@ -2848,6 +2860,7 @@ private: case id(): transformSwitch(static_cast(value), out, ExpUsage::Closure); break; case id(): transformTableBlock(static_cast(value), out); break; case id(): transformExp(static_cast(value), out, ExpUsage::Closure); break; + case id(): throw CompileError("can only be used for ranged table append assignments"sv, value); break; default: YUEE("AST node mismatch", value); break; } } @@ -8268,9 +8281,16 @@ private: } return; } - auto def = ast_cast(comp->items.front()); - if (!def || def->defVal) { - throw CompileError("invalid comprehension expression", comp->items.front()); + ast_node* value = nullptr; + bool isSpread = ast_is(comp->items.front()); + if (isSpread) { + value = comp->items.front(); + } else { + auto def = ast_cast(comp->items.front()); + if (!def || def->defVal) { + throw CompileError("invalid comprehension expression", comp->items.front()); + } + value = def->item.get(); } bool extraScope = false; switch (usage) { @@ -8294,7 +8314,6 @@ private: default: break; } - auto value = def->item.get(); auto compInner = static_cast(comp->items.back()); str_list temp; std::string accumVar = getUnusedName("_accum_"sv); @@ -8318,7 +8337,7 @@ private: } } { - auto assignLeft = toAst(accumVar + '[' + lenVar + ']', x); + auto assignLeft = toAst(accumVar + '[' + lenVar + (isSpread ? "][]"s : "]"s), x); auto assign = x->new_ptr(); assign->values.push_back(value); auto assignment = x->new_ptr(); diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 44baced..fccb6fb 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -547,7 +547,7 @@ YueParser::YueParser() { Assign = '=' >> space >> Seperator >> ( With | If | Switch | TableBlock | - Exp >> *(space >> set(",;") >> space >> Exp) + (SpreadListExp | Exp) >> *(space >> set(",;") >> space >> (SpreadListExp | Exp)) ); UpdateOp = -- cgit v1.2.3-55-g6feb