aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-05-16 01:03:05 +0800
committerLi Jin <dragon-fly@qq.com>2022-05-16 01:03:05 +0800
commitc4935826eea8df7a161b2b4ba9262dce66d9d366 (patch)
tree12f7fe952a777b98244253c5ecd3e0d0a73e8de8 /src
parente9926f70a53639c09a5605f71a34ec370395f5a9 (diff)
downloadyuescript-c4935826eea8df7a161b2b4ba9262dce66d9d366.tar.gz
yuescript-c4935826eea8df7a161b2b4ba9262dce66d9d366.tar.bz2
yuescript-c4935826eea8df7a161b2b4ba9262dce66d9d366.zip
fix issue #102. fix `continue` statement locating issue.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp84
1 files changed, 78 insertions, 6 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 469dfea..6f641d9 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.19"sv; 63const std::string_view version = "0.10.20"sv;
64const std::string_view extension = "yue"sv; 64const std::string_view extension = "yue"sv;
65 65
66class YueCompilerImpl { 66class YueCompilerImpl {
@@ -5257,9 +5257,8 @@ private:
5257 } 5257 }
5258 } 5258 }
5259 5259
5260 void transformLoopBody(ast_node* body, str_list& out, const std::string& appendContent, ExpUsage usage, ExpList_t* assignList = nullptr) { 5260 bool hasContinueStatement(ast_node* body) {
5261 str_list temp; 5261 return traversal::Stop == body->traverse([&](ast_node* node) {
5262 bool withContinue = traversal::Stop == body->traverse([&](ast_node* node) {
5263 if (auto stmt = ast_cast<Statement_t>(node)) { 5262 if (auto stmt = ast_cast<Statement_t>(node)) {
5264 if (stmt->content.is<BreakLoop_t>()) { 5263 if (stmt->content.is<BreakLoop_t>()) {
5265 return _parser.toString(stmt->content) == "continue"sv ? 5264 return _parser.toString(stmt->content) == "continue"sv ?
@@ -5268,10 +5267,20 @@ private:
5268 return traversal::Continue; 5267 return traversal::Continue;
5269 } 5268 }
5270 return traversal::Return; 5269 return traversal::Return;
5270 } else switch (node->getId()) {
5271 case id<FunLit_t>():
5272 case id<Invoke_t>():
5273 case id<InvokeArgs_t>():
5274 return traversal::Return;
5271 } 5275 }
5272 return traversal::Continue; 5276 return traversal::Continue;
5273 }); 5277 });
5278 }
5279
5280 void transformLoopBody(ast_node* body, str_list& out, const std::string& appendContent, ExpUsage usage, ExpList_t* assignList = nullptr) {
5281 str_list temp;
5274 bool extraDo = false; 5282 bool extraDo = false;
5283 bool withContinue = hasContinueStatement(body);
5275 if (withContinue) { 5284 if (withContinue) {
5276 if (auto block = ast_cast<Block_t>(body)) { 5285 if (auto block = ast_cast<Block_t>(body)) {
5277 if (!block->statements.empty()) { 5286 if (!block->statements.empty()) {
@@ -5316,6 +5325,65 @@ private:
5316 out.push_back(join(temp)); 5325 out.push_back(join(temp));
5317 } 5326 }
5318 5327
5328 std::string transformRepeatBody(Repeat_t* repeatNode, str_list& out) {
5329 str_list temp;
5330 bool extraDo = false;
5331 auto body = repeatNode->body->content.get();
5332 bool withContinue = hasContinueStatement(body);
5333 std::string conditionVar;
5334 if (withContinue) {
5335 if (auto block = ast_cast<Block_t>(body)) {
5336 if (!block->statements.empty()) {
5337 auto stmt = static_cast<Statement_t*>(block->statements.back());
5338 if (auto breakLoop = ast_cast<BreakLoop_t>(stmt->content)) {
5339 extraDo = _parser.toString(breakLoop) == "break"sv;
5340 }
5341 }
5342 }
5343 conditionVar = getUnusedName("_cond_");
5344 forceAddToScope(conditionVar);
5345 auto continueVar = getUnusedName("_continue_"sv);
5346 forceAddToScope(continueVar);
5347 _continueVars.push(continueVar);
5348 _buf << indent() << "local "sv << conditionVar << nll(body);
5349 _buf << indent() << "local "sv << continueVar << " = false"sv << nll(body);
5350 _buf << indent() << "repeat"sv << nll(body);
5351 pushScope();
5352 if (extraDo) {
5353 _buf << indent() << "do"sv << nll(body);
5354 pushScope();
5355 }
5356 temp.push_back(clearBuf());
5357 }
5358 transform_plain_body(body, temp, ExpUsage::Common);
5359 if (withContinue) {
5360 {
5361 auto assignment = toAst<ExpListAssign_t>(conditionVar + "=nil"s, body);
5362 auto assign = assignment->action.to<Assign_t>();
5363 assign->values.clear();
5364 assign->values.push_back(repeatNode->condition);
5365 transformAssignment(assignment, temp);
5366 auto assignCond = std::move(temp.back());
5367 temp.pop_back();
5368 temp.back().append(assignCond);
5369 }
5370 if (extraDo) {
5371 popScope();
5372 _buf << indent() << "end"sv << nll(body);
5373 }
5374 _buf << indent() << _continueVars.top() << " = true"sv << nll(body);
5375 popScope();
5376 _buf << indent() << "until true"sv << nlr(body);
5377 _buf << indent() << "if not "sv << _continueVars.top() << " then"sv << nlr(body);
5378 _buf << indent(1) << "break"sv << nlr(body);
5379 _buf << indent() << "end"sv << nlr(body);
5380 temp.push_back(clearBuf());
5381 _continueVars.pop();
5382 }
5383 out.push_back(join(temp));
5384 return conditionVar;
5385 }
5386
5319 void transformFor(For_t* forNode, str_list& out) { 5387 void transformFor(For_t* forNode, str_list& out) {
5320 str_list temp; 5388 str_list temp;
5321 transformForHead(forNode, temp); 5389 transformForHead(forNode, temp);
@@ -6838,8 +6906,12 @@ private:
6838 void transformRepeat(Repeat_t* repeat, str_list& out) { 6906 void transformRepeat(Repeat_t* repeat, str_list& out) {
6839 str_list temp; 6907 str_list temp;
6840 pushScope(); 6908 pushScope();
6841 transformLoopBody(repeat->body->content, temp, Empty, ExpUsage::Common); 6909 auto condVar = transformRepeatBody(repeat, temp);
6842 transformExp(repeat->condition, temp, ExpUsage::Closure); 6910 if (condVar.empty()) {
6911 transformExp(repeat->condition, temp, ExpUsage::Closure);
6912 } else {
6913 temp.push_back(condVar);
6914 }
6843 popScope(); 6915 popScope();
6844 _buf << indent() << "repeat"sv << nll(repeat); 6916 _buf << indent() << "repeat"sv << nll(repeat);
6845 _buf << temp.front(); 6917 _buf << temp.front();