From 55149f8864c6c3e1c1fff9268384f8302dc5488d Mon Sep 17 00:00:00 2001 From: Li Jin Date: Mon, 15 Sep 2025 18:20:15 +0800 Subject: Fixed issue for reversed indexing. --- src/yuescript/yue_compiler.cpp | 83 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 33161a7..d7d117a 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.4"sv; +const std::string_view version = "0.29.5"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -1445,6 +1445,7 @@ private: case id(): case id(): case id(): + case id(): return true; } } @@ -2254,7 +2255,8 @@ private: BREAK_IF(!value); auto chainValue = value->item.as(); BREAK_IF(!chainValue); - if (auto dot = ast_cast(chainValue->items.back())) { + auto last = chainValue->items.back(); + if (auto dot = ast_cast(last)) { BREAK_IF(!dot->name.is()); str_list temp; auto [beforeAssignment, afterAssignment] = splitAssignment(); @@ -2285,7 +2287,7 @@ private: } out.push_back(join(temp)); return false; - } else if (ast_is(chainValue->items.back())) { + } else if (ast_is(last)) { str_list temp; auto [beforeAssignment, afterAssignment] = splitAssignment(); if (!beforeAssignment->expList->exprs.empty()) { @@ -2337,6 +2339,44 @@ private: } out.push_back(join(temp)); return false; + } else if (ast_is(last)) { + if (chainValue->items.size() == 1) { + if (_withVars.empty()) { + throw CompileError("short dot/colon syntax must be called within a with block"sv, x); + } else { + break; + } + } + auto tmpChain = chainValue->new_ptr(); + tmpChain->items.dup(chainValue->items); + tmpChain->items.pop_back(); + auto tmpLeft = newExp(tmpChain, tmpChain); + auto leftVar = singleVariableFrom(tmpLeft, AccessType::Read); + if (!leftVar.empty() && isLocal(leftVar)) { + break; + } + leftVar = getUnusedName("_obj_"sv); + auto tmpAsmt = assignmentFrom(toAst(leftVar, tmpLeft), tmpLeft, tmpLeft); + str_list temp; + transformAssignment(tmpAsmt, temp); + auto [beforeAssignment, afterAssignment] = splitAssignment(); + if (!beforeAssignment->expList->exprs.empty()) { + transformAssignment(beforeAssignment, temp); + } + if (vit == values.end()) { + throw CompileError("right value missing"sv, values.front()); + } + auto newChain = chainValue->new_ptr(); + newChain->items.push_back(toAst(leftVar, newChain)); + newChain->items.push_back(chainValue->items.back()); + auto newLeft = newExp(newChain, newChain); + auto newAsmt = assignmentFrom(newLeft, *vit, newLeft); + transformAssignment(newAsmt, temp); + if (!afterAssignment->expList->exprs.empty()) { + transformAssignment(afterAssignment, temp); + } + out.push_back(join(temp)); + return false; } else { break; } @@ -6608,11 +6648,6 @@ private: indexNode->nilCoalesed.set(rIndex->modifier->nilCoalesed); } newChain->items.push_back(indexNode); - auto next = current; - ++next; - for (auto i = next; i != chainList.end(); ++i) { - newChain->items.push_back(*i); - } auto expList = x->new_ptr(); expList->exprs.push_back(newExp(newChain, x)); auto expListAssign = x->new_ptr(); @@ -6627,6 +6662,11 @@ private: auto doNode = x->new_ptr(); doNode->body.set(body); if (usage == ExpUsage::Assignment) { + auto next = current; + ++next; + for (auto i = next; i != chainList.end(); ++i) { + newChain->items.push_back(*i); + } auto assignment = x->new_ptr(); assignment->expList.set(assignList); auto assign = x->new_ptr(); @@ -6637,6 +6677,33 @@ private: transformAssignment(assignment, out); return; } + if (usage == ExpUsage::Closure) { + auto next = current; + ++next; + if (next != chainList.end()) { + doNode->new_ptr(); + auto dVal = doNode->new_ptr(); + dVal->value.set(doNode); + auto dExp = newExp(dVal, dVal); + auto dParen = dExp->new_ptr(); + dParen->extra = true; + dParen->expr.set(dExp); + auto dCallable = dExp->new_ptr(); + dCallable->item.set(dParen); + auto dChain = doNode->new_ptr(); + dChain->items.push_back(dCallable); + for (auto i = next; i != chainList.end(); ++i) { + dChain->items.push_back(*i); + } + transformExp(newExp(dChain, dExp), out, usage); + return; + } + } + auto next = current; + ++next; + for (auto i = next; i != chainList.end(); ++i) { + newChain->items.push_back(*i); + } transformDo(doNode, out, usage); return; } -- cgit v1.2.3-55-g6feb