diff options
author | Li Jin <dragon-fly@qq.com> | 2022-05-16 15:26:47 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2022-05-16 15:27:01 +0800 |
commit | ac2f4ff4cdd3286ecaf31aec47d9d8aadfa75b0f (patch) | |
tree | cfa3acb4bf1e4eb04f1596f68444c9189102770e | |
parent | de91fff7af15ae9c4a27d34b5b9266f900412a29 (diff) | |
download | yuescript-ac2f4ff4cdd3286ecaf31aec47d9d8aadfa75b0f.tar.gz yuescript-ac2f4ff4cdd3286ecaf31aec47d9d8aadfa75b0f.tar.bz2 yuescript-ac2f4ff4cdd3286ecaf31aec47d9d8aadfa75b0f.zip |
fixing #102 by adding extra condition assignment while continue skip the loop.
-rw-r--r-- | spec/outputs/loops.lua | 2 | ||||
-rwxr-xr-x | src/yuescript/yue_compiler.cpp | 41 |
2 files changed, 29 insertions, 14 deletions
diff --git a/spec/outputs/loops.lua b/spec/outputs/loops.lua index 7f87b2d..e5c189e 100644 --- a/spec/outputs/loops.lua +++ b/spec/outputs/loops.lua | |||
@@ -192,6 +192,7 @@ repeat | |||
192 | repeat | 192 | repeat |
193 | a = a + 1 | 193 | a = a + 1 |
194 | if a == 5 then | 194 | if a == 5 then |
195 | _cond_0 = a == 10 | ||
195 | _continue_0 = true | 196 | _continue_0 = true |
196 | break | 197 | break |
197 | end | 198 | end |
@@ -214,6 +215,7 @@ repeat | |||
214 | x = x + 1 | 215 | x = x + 1 |
215 | y = x | 216 | y = x |
216 | if x < 5 then | 217 | if x < 5 then |
218 | _cond_0 = y == 10 | ||
217 | _continue_0 = true | 219 | _continue_0 = true |
218 | break | 220 | break |
219 | end | 221 | end |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 51ece7c..d87ee3f 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -60,7 +60,7 @@ using namespace parserlib; | |||
60 | 60 | ||
61 | typedef std::list<std::string> str_list; | 61 | typedef std::list<std::string> str_list; |
62 | 62 | ||
63 | const std::string_view version = "0.10.22"sv; | 63 | const std::string_view version = "0.10.23"sv; |
64 | const std::string_view extension = "yue"sv; | 64 | const std::string_view extension = "yue"sv; |
65 | 65 | ||
66 | class YueCompilerImpl { | 66 | class YueCompilerImpl { |
@@ -202,7 +202,12 @@ private: | |||
202 | std::stack<VarArgState> _varArgs; | 202 | std::stack<VarArgState> _varArgs; |
203 | std::stack<bool> _enableReturn; | 203 | std::stack<bool> _enableReturn; |
204 | std::stack<std::string> _withVars; | 204 | std::stack<std::string> _withVars; |
205 | std::stack<std::string> _continueVars; | 205 | struct ContinueVar |
206 | { | ||
207 | std::string var; | ||
208 | ast_ptr<false, ExpListAssign_t> condAssign; | ||
209 | }; | ||
210 | std::stack<ContinueVar> _continueVars; | ||
206 | std::list<std::unique_ptr<input>> _codeCache; | 211 | std::list<std::unique_ptr<input>> _codeCache; |
207 | std::unordered_map<std::string,std::pair<int,int>> _globals; | 212 | std::unordered_map<std::string,std::pair<int,int>> _globals; |
208 | std::ostringstream _buf; | 213 | std::ostringstream _buf; |
@@ -5352,7 +5357,7 @@ private: | |||
5352 | } | 5357 | } |
5353 | auto continueVar = getUnusedName("_continue_"sv); | 5358 | auto continueVar = getUnusedName("_continue_"sv); |
5354 | addToScope(continueVar); | 5359 | addToScope(continueVar); |
5355 | _continueVars.push(continueVar); | 5360 | _continueVars.push({continueVar, nullptr}); |
5356 | _buf << indent() << "local "sv << continueVar << " = false"sv << nll(body); | 5361 | _buf << indent() << "local "sv << continueVar << " = false"sv << nll(body); |
5357 | _buf << indent() << "repeat"sv << nll(body); | 5362 | _buf << indent() << "repeat"sv << nll(body); |
5358 | pushScope(); | 5363 | pushScope(); |
@@ -5371,10 +5376,10 @@ private: | |||
5371 | if (!appendContent.empty()) { | 5376 | if (!appendContent.empty()) { |
5372 | _buf << indent() << appendContent; | 5377 | _buf << indent() << appendContent; |
5373 | } | 5378 | } |
5374 | _buf << indent() << _continueVars.top() << " = true"sv << nll(body); | 5379 | _buf << indent() << _continueVars.top().var << " = true"sv << nll(body); |
5375 | popScope(); | 5380 | popScope(); |
5376 | _buf << indent() << "until true"sv << nlr(body); | 5381 | _buf << indent() << "until true"sv << nlr(body); |
5377 | _buf << indent() << "if not "sv << _continueVars.top() << " then"sv << nlr(body); | 5382 | _buf << indent() << "if not "sv << _continueVars.top().var << " then"sv << nlr(body); |
5378 | _buf << indent(1) << "break"sv << nlr(body); | 5383 | _buf << indent(1) << "break"sv << nlr(body); |
5379 | _buf << indent() << "end"sv << nlr(body); | 5384 | _buf << indent() << "end"sv << nlr(body); |
5380 | temp.push_back(clearBuf()); | 5385 | temp.push_back(clearBuf()); |
@@ -5404,7 +5409,13 @@ private: | |||
5404 | forceAddToScope(conditionVar); | 5409 | forceAddToScope(conditionVar); |
5405 | auto continueVar = getUnusedName("_continue_"sv); | 5410 | auto continueVar = getUnusedName("_continue_"sv); |
5406 | forceAddToScope(continueVar); | 5411 | forceAddToScope(continueVar); |
5407 | _continueVars.push(continueVar); | 5412 | { |
5413 | auto assignment = toAst<ExpListAssign_t>(conditionVar + "=nil"s, repeatNode->condition); | ||
5414 | auto assign = assignment->action.to<Assign_t>(); | ||
5415 | assign->values.clear(); | ||
5416 | assign->values.push_back(repeatNode->condition); | ||
5417 | _continueVars.push({continueVar, assignment.get()}); | ||
5418 | } | ||
5408 | _buf << indent() << "local "sv << conditionVar << " = false"sv << nll(body); | 5419 | _buf << indent() << "local "sv << conditionVar << " = false"sv << nll(body); |
5409 | _buf << indent() << "local "sv << continueVar << " = false"sv << nll(body); | 5420 | _buf << indent() << "local "sv << continueVar << " = false"sv << nll(body); |
5410 | _buf << indent() << "repeat"sv << nll(body); | 5421 | _buf << indent() << "repeat"sv << nll(body); |
@@ -5418,11 +5429,7 @@ private: | |||
5418 | transform_plain_body(body, temp, ExpUsage::Common); | 5429 | transform_plain_body(body, temp, ExpUsage::Common); |
5419 | if (withContinue) { | 5430 | if (withContinue) { |
5420 | { | 5431 | { |
5421 | auto assignment = toAst<ExpListAssign_t>(conditionVar + "=nil"s, body); | 5432 | transformAssignment(_continueVars.top().condAssign, temp); |
5422 | auto assign = assignment->action.to<Assign_t>(); | ||
5423 | assign->values.clear(); | ||
5424 | assign->values.push_back(repeatNode->condition); | ||
5425 | transformAssignment(assignment, temp); | ||
5426 | auto assignCond = std::move(temp.back()); | 5433 | auto assignCond = std::move(temp.back()); |
5427 | temp.pop_back(); | 5434 | temp.pop_back(); |
5428 | temp.back().append(assignCond); | 5435 | temp.back().append(assignCond); |
@@ -5431,10 +5438,10 @@ private: | |||
5431 | popScope(); | 5438 | popScope(); |
5432 | _buf << indent() << "end"sv << nll(body); | 5439 | _buf << indent() << "end"sv << nll(body); |
5433 | } | 5440 | } |
5434 | _buf << indent() << _continueVars.top() << " = true"sv << nll(body); | 5441 | _buf << indent() << _continueVars.top().var << " = true"sv << nll(body); |
5435 | popScope(); | 5442 | popScope(); |
5436 | _buf << indent() << "until true"sv << nlr(body); | 5443 | _buf << indent() << "until true"sv << nlr(body); |
5437 | _buf << indent() << "if not "sv << _continueVars.top() << " then"sv << nlr(body); | 5444 | _buf << indent() << "if not "sv << _continueVars.top().var << " then"sv << nlr(body); |
5438 | _buf << indent(1) << "break"sv << nlr(body); | 5445 | _buf << indent(1) << "break"sv << nlr(body); |
5439 | _buf << indent() << "end"sv << nlr(body); | 5446 | _buf << indent() << "end"sv << nlr(body); |
5440 | temp.push_back(clearBuf()); | 5447 | temp.push_back(clearBuf()); |
@@ -7176,7 +7183,13 @@ private: | |||
7176 | return; | 7183 | return; |
7177 | } | 7184 | } |
7178 | if (_continueVars.empty()) throw std::logic_error(_info.errorMessage("continue is not inside a loop"sv, breakLoop)); | 7185 | if (_continueVars.empty()) throw std::logic_error(_info.errorMessage("continue is not inside a loop"sv, breakLoop)); |
7179 | _buf << indent() << _continueVars.top() << " = true"sv << nll(breakLoop); | 7186 | auto& item = _continueVars.top(); |
7187 | if (item.condAssign) { | ||
7188 | str_list temp; | ||
7189 | transformAssignment(item.condAssign, temp); | ||
7190 | _buf << temp.back(); | ||
7191 | } | ||
7192 | _buf << indent() << item.var << " = true"sv << nll(breakLoop); | ||
7180 | _buf << indent() << "break"sv << nll(breakLoop); | 7193 | _buf << indent() << "break"sv << nll(breakLoop); |
7181 | out.push_back(clearBuf()); | 7194 | out.push_back(clearBuf()); |
7182 | } | 7195 | } |