diff options
author | Li Jin <dragon-fly@qq.com> | 2025-06-04 16:07:06 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2025-06-04 16:07:06 +0800 |
commit | 0e72454a11f65d9ac800dedb698ddfcc15933785 (patch) | |
tree | 6cded6335c22c4dd204f7d3bc66efa0f76a41ef0 /src | |
parent | 548ab1d9ff5b831050f14f1355a3314a41163ad6 (diff) | |
download | yuescript-0e72454a11f65d9ac800dedb698ddfcc15933785.tar.gz yuescript-0e72454a11f65d9ac800dedb698ddfcc15933785.tar.bz2 yuescript-0e72454a11f65d9ac800dedb698ddfcc15933785.zip |
Added more reversed index support for slice. [skip CI]
Diffstat (limited to 'src')
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 91 |
1 files changed, 86 insertions, 5 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index cbf976f..9f5a41e 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -8180,6 +8180,11 @@ private: | |||
8180 | } | 8180 | } |
8181 | 8181 | ||
8182 | bool transformForEachHead(AssignableNameList_t* nameList, ast_node* loopTarget, str_list& out, bool inClosure) { | 8182 | bool transformForEachHead(AssignableNameList_t* nameList, ast_node* loopTarget, str_list& out, bool inClosure) { |
8183 | enum class NumState { | ||
8184 | Unknown, | ||
8185 | Positive, | ||
8186 | Negtive | ||
8187 | }; | ||
8183 | auto x = nameList; | 8188 | auto x = nameList; |
8184 | str_list temp; | 8189 | str_list temp; |
8185 | str_list vars; | 8190 | str_list vars; |
@@ -8246,15 +8251,35 @@ private: | |||
8246 | for (auto item : chainList) { | 8251 | for (auto item : chainList) { |
8247 | chain->items.push_back(item); | 8252 | chain->items.push_back(item); |
8248 | } | 8253 | } |
8249 | std::string startValue("1"sv); | 8254 | std::string startValue; |
8255 | NumState startStatus = NumState::Unknown; | ||
8250 | if (auto exp = slice->startValue.as<Exp_t>()) { | 8256 | if (auto exp = slice->startValue.as<Exp_t>()) { |
8251 | transformExp(exp, temp, ExpUsage::Closure); | 8257 | transformExp(exp, temp, ExpUsage::Closure); |
8258 | if (temp.back().at(0) == '-') { | ||
8259 | if (_parser.match<Num_t>(temp.back().substr(1))) { | ||
8260 | startStatus = NumState::Negtive; | ||
8261 | } | ||
8262 | } else { | ||
8263 | if (_parser.match<Num_t>(temp.back())) { | ||
8264 | startStatus = NumState::Positive; | ||
8265 | } | ||
8266 | } | ||
8252 | startValue = std::move(temp.back()); | 8267 | startValue = std::move(temp.back()); |
8253 | temp.pop_back(); | 8268 | temp.pop_back(); |
8254 | } | 8269 | } |
8255 | std::string stopValue; | 8270 | std::string stopValue; |
8271 | NumState stopStatus = NumState::Unknown; | ||
8256 | if (auto exp = slice->stopValue.as<Exp_t>()) { | 8272 | if (auto exp = slice->stopValue.as<Exp_t>()) { |
8257 | transformExp(exp, temp, ExpUsage::Closure); | 8273 | transformExp(exp, temp, ExpUsage::Closure); |
8274 | if (temp.back().at(0) == '-') { | ||
8275 | if (_parser.match<Num_t>(temp.back().substr(1))) { | ||
8276 | stopStatus = NumState::Negtive; | ||
8277 | } | ||
8278 | } else { | ||
8279 | if (_parser.match<Num_t>(temp.back())) { | ||
8280 | stopStatus = NumState::Positive; | ||
8281 | } | ||
8282 | } | ||
8258 | stopValue = std::move(temp.back()); | 8283 | stopValue = std::move(temp.back()); |
8259 | temp.pop_back(); | 8284 | temp.pop_back(); |
8260 | } | 8285 | } |
@@ -8276,8 +8301,33 @@ private: | |||
8276 | transformChainValue(chain, temp, ExpUsage::Closure); | 8301 | transformChainValue(chain, temp, ExpUsage::Closure); |
8277 | _buf << prefix << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); | 8302 | _buf << prefix << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); |
8278 | } | 8303 | } |
8304 | if (startValue.empty()) { | ||
8305 | startValue = "1"s; | ||
8306 | startStatus = NumState::Positive; | ||
8307 | } | ||
8308 | std::string minVar; | ||
8309 | if (startStatus != NumState::Positive) { | ||
8310 | std::string prefix; | ||
8311 | if (!extraScope && !inClosure && needScope) { | ||
8312 | extraScope = true; | ||
8313 | prefix = indent() + "do"s + nll(x); | ||
8314 | pushScope(); | ||
8315 | } | ||
8316 | minVar = getUnusedName("_min_"sv); | ||
8317 | varBefore.push_back(minVar); | ||
8318 | if (startStatus == NumState::Negtive) { | ||
8319 | _buf << prefix << indent() << "local "sv << minVar << " = "sv << "#"sv << listVar << " + "sv << startValue << " + 1"sv << nll(nameList); | ||
8320 | } else { | ||
8321 | _buf << prefix << indent() << "local "sv << minVar << " = "sv << startValue << nll(nameList); | ||
8322 | } | ||
8323 | } | ||
8324 | bool defaultStop = false; | ||
8325 | if (stopValue.empty()) { | ||
8326 | stopValue = "#"s + listVar; | ||
8327 | defaultStop = true; | ||
8328 | } | ||
8279 | std::string maxVar; | 8329 | std::string maxVar; |
8280 | if (!stopValue.empty()) { | 8330 | if (stopStatus != NumState::Positive) { |
8281 | std::string prefix; | 8331 | std::string prefix; |
8282 | if (!extraScope && !inClosure && needScope) { | 8332 | if (!extraScope && !inClosure && needScope) { |
8283 | extraScope = true; | 8333 | extraScope = true; |
@@ -8286,14 +8336,45 @@ private: | |||
8286 | } | 8336 | } |
8287 | maxVar = getUnusedName("_max_"sv); | 8337 | maxVar = getUnusedName("_max_"sv); |
8288 | varBefore.push_back(maxVar); | 8338 | varBefore.push_back(maxVar); |
8289 | _buf << prefix << indent() << "local "sv << maxVar << " = "sv << stopValue << nll(nameList); | 8339 | if (stopStatus == NumState::Negtive) { |
8340 | _buf << indent() << "local "sv << maxVar << " = "sv << "#"sv << listVar << " + "sv << stopValue << " + 1"sv << nll(nameList); | ||
8341 | } else { | ||
8342 | _buf << prefix << indent() << "local "sv << maxVar << " = "sv << stopValue << nll(nameList); | ||
8343 | } | ||
8344 | } | ||
8345 | if (startStatus == NumState::Unknown) { | ||
8346 | _buf << indent() << minVar << " = "sv << minVar << " < 0 and #"sv << listVar << " + "sv << minVar << " + 1 or "sv << minVar << nll(nameList); | ||
8347 | } | ||
8348 | if (!defaultStop && stopStatus == NumState::Unknown) { | ||
8349 | _buf << indent() << maxVar << " = "sv << maxVar << " < 0 and #"sv << listVar << " + "sv << maxVar << " + 1 or "sv << maxVar << nll(nameList); | ||
8290 | } | 8350 | } |
8291 | _buf << indent() << "for "sv << indexVar << " = "sv; | 8351 | _buf << indent() << "for "sv << indexVar << " = "sv; |
8292 | _buf << startValue << ", "sv; | 8352 | if (startValue.empty()) { |
8353 | _buf << "1"sv; | ||
8354 | } else { | ||
8355 | switch (startStatus) { | ||
8356 | case NumState::Unknown: | ||
8357 | case NumState::Negtive: | ||
8358 | _buf << minVar; | ||
8359 | break; | ||
8360 | case NumState::Positive: | ||
8361 | _buf << startValue; | ||
8362 | break; | ||
8363 | } | ||
8364 | } | ||
8365 | _buf << ", "sv; | ||
8293 | if (stopValue.empty()) { | 8366 | if (stopValue.empty()) { |
8294 | _buf << "#"sv << listVar; | 8367 | _buf << "#"sv << listVar; |
8295 | } else { | 8368 | } else { |
8296 | _buf << maxVar << " < 0 and #"sv << listVar << " + "sv << maxVar << " + 1 or "sv << maxVar; | 8369 | switch (stopStatus) { |
8370 | case NumState::Unknown: | ||
8371 | case NumState::Negtive: | ||
8372 | _buf << maxVar; | ||
8373 | break; | ||
8374 | case NumState::Positive: | ||
8375 | _buf << stopValue; | ||
8376 | break; | ||
8377 | } | ||
8297 | } | 8378 | } |
8298 | if (!stepValue.empty()) { | 8379 | if (!stepValue.empty()) { |
8299 | _buf << ", "sv << stepValue; | 8380 | _buf << ", "sv << stepValue; |