aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-05-16 15:26:47 +0800
committerLi Jin <dragon-fly@qq.com>2022-05-16 15:27:01 +0800
commitac2f4ff4cdd3286ecaf31aec47d9d8aadfa75b0f (patch)
treecfa3acb4bf1e4eb04f1596f68444c9189102770e
parentde91fff7af15ae9c4a27d34b5b9266f900412a29 (diff)
downloadyuescript-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.lua2
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp41
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
61typedef std::list<std::string> str_list; 61typedef std::list<std::string> str_list;
62 62
63const std::string_view version = "0.10.22"sv; 63const std::string_view version = "0.10.23"sv;
64const std::string_view extension = "yue"sv; 64const std::string_view extension = "yue"sv;
65 65
66class YueCompilerImpl { 66class 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 }