diff options
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; |
