aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/yuescript/yue_compiler.cpp66
1 files changed, 44 insertions, 22 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index bb715d2..09da047 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -72,7 +72,7 @@ static std::unordered_set<std::string> Metamethods = {
72 "close"s // Lua 5.4 72 "close"s // Lua 5.4
73}; 73};
74 74
75const std::string_view version = "0.17.7"sv; 75const std::string_view version = "0.17.8"sv;
76const std::string_view extension = "yue"sv; 76const std::string_view extension = "yue"sv;
77 77
78class CompileError : public std::logic_error { 78class CompileError : public std::logic_error {
@@ -1161,6 +1161,9 @@ private:
1161 auto unary = static_cast<UnaryExp_t*>(exp->pipeExprs.back()); 1161 auto unary = static_cast<UnaryExp_t*>(exp->pipeExprs.back());
1162 BREAK_IF(unary->expos.size() != 1); 1162 BREAK_IF(unary->expos.size() != 1);
1163 BREAK_IF(!unary->inExp); 1163 BREAK_IF(!unary->inExp);
1164 if (unary->inExp->item.is<Exp_t>()) {
1165 return unary;
1166 }
1164 auto value = static_cast<Value_t*>(unary->expos.back()); 1167 auto value = static_cast<Value_t*>(unary->expos.back());
1165 auto varName = singleVariableFrom(value, false); 1168 auto varName = singleVariableFrom(value, false);
1166 if (varName.empty() || !isLocal(varName)) { 1169 if (varName.empty() || !isLocal(varName)) {
@@ -5416,7 +5419,11 @@ private:
5416 _buf << "\tif "sv << itemVar << "=="sv << varName << '\n'; 5419 _buf << "\tif "sv << itemVar << "=="sv << varName << '\n';
5417 _buf << "\t\t"sv << findVar << "=true\n"sv; 5420 _buf << "\t\t"sv << findVar << "=true\n"sv;
5418 _buf << "\t\tbreak\n"sv; 5421 _buf << "\t\tbreak\n"sv;
5419 _buf << findVar; 5422 if (unary_exp->inExp->not_) {
5423 _buf << "not "sv << findVar;
5424 } else {
5425 _buf << findVar;
5426 }
5420 auto blockStr = clearBuf(); 5427 auto blockStr = clearBuf();
5421 auto checkBlock = toAst<Block_t>(blockStr, inExp); 5428 auto checkBlock = toAst<Block_t>(blockStr, inExp);
5422 block->statements.dup(checkBlock->statements); 5429 block->statements.dup(checkBlock->statements);
@@ -5437,30 +5444,44 @@ private:
5437 out.push_back(join(temp)); 5444 out.push_back(join(temp));
5438 return; 5445 return;
5439 } else { 5446 } else {
5440 pushFunctionScope(); 5447 auto arrayCheck = [&](bool exist) {
5441 pushAnonVarArg();
5442 pushScope();
5443 auto arrayCheck = [&]() {
5444 auto indexVar = getUnusedName("_index_"); 5448 auto indexVar = getUnusedName("_index_");
5445 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << checkVar << " do"sv << nll(x); 5449 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << checkVar << " do"sv << nll(x);
5446 incIndentOffset(); 5450 incIndentOffset();
5447 _buf << indent() << "if "sv << checkVar << '[' << indexVar << "] == "sv << varName << " then"sv << nll(x); 5451 _buf << indent() << "if "sv << checkVar << '[' << indexVar << "] == "sv << varName << " then"sv << nll(x);
5448 incIndentOffset(); 5452 incIndentOffset();
5449 _buf << indent() << "return true"sv << nll(x); 5453 _buf << indent() << "return "sv << (exist ? "true"sv : "false"sv) << nll(x);
5450 decIndentOffset(); 5454 decIndentOffset();
5451 _buf << indent() << "end"sv << nll(x); 5455 _buf << indent() << "end"sv << nll(x);
5452 decIndentOffset(); 5456 decIndentOffset();
5453 _buf << indent() << "end"sv << nll(x); 5457 _buf << indent() << "end"sv << nll(x);
5454 _buf << indent() << "return false"sv << nll(x); 5458 _buf << indent() << "return "sv << (exist ? "false"sv : "true"sv) << nll(x);
5455 temp.push_back(clearBuf()); 5459 temp.push_back(clearBuf());
5456 }; 5460 };
5457 bool useShortCheck = !varName.empty() && !checkVar.empty() && isLocal(checkVar); 5461 bool useShortCheck = (usage == ExpUsage::Closure) && !varName.empty() && !checkVar.empty() && isLocal(checkVar);
5458 if (useShortCheck) { 5462 if (useShortCheck) {
5459 arrayCheck(); 5463 if (usage == ExpUsage::Return) {
5460 temp.push_front("(#"s + checkVar + " > 0 and "s + anonFuncStart() + nll(x)); 5464 arrayCheck(!unary_exp->inExp->not_);
5461 popScope(); 5465 } else {
5462 temp.push_back(indent() + anonFuncEnd() + ')'); 5466 pushFunctionScope();
5467 pushAnonVarArg();
5468 pushScope();
5469 arrayCheck(true);
5470 temp.push_front("(#"s + checkVar + " > 0 and "s + anonFuncStart() + nll(x));
5471 popScope();
5472 temp.push_back(indent() + anonFuncEnd() + ')');
5473 if (unary_exp->inExp->not_) {
5474 temp.front().insert(0, "not "s);
5475 }
5476 popAnonVarArg();
5477 popFunctionScope();
5478 }
5463 } else { 5479 } else {
5480 if (usage == ExpUsage::Closure) {
5481 pushFunctionScope();
5482 pushAnonVarArg();
5483 pushScope();
5484 }
5464 if (checkVar.empty() || !isLocal(checkVar)) { 5485 if (checkVar.empty() || !isLocal(checkVar)) {
5465 checkVar = getUnusedName("_check_"sv); 5486 checkVar = getUnusedName("_check_"sv);
5466 auto assignment = assignmentFrom(toAst<Exp_t>(checkVar, inExp), inExp, inExp); 5487 auto assignment = assignmentFrom(toAst<Exp_t>(checkVar, inExp), inExp, inExp);
@@ -5476,15 +5497,16 @@ private:
5476 auto assignment = assignmentFrom(assignExp, exp, x); 5497 auto assignment = assignmentFrom(assignExp, exp, x);
5477 transformAssignment(assignment, temp); 5498 transformAssignment(assignment, temp);
5478 } 5499 }
5479 arrayCheck(); 5500 if (usage == ExpUsage::Return) {
5480 temp.push_front(anonFuncStart() + nll(x)); 5501 arrayCheck(!unary_exp->inExp->not_);
5481 popScope(); 5502 } else {
5482 temp.push_back(indent() + anonFuncEnd()); 5503 arrayCheck(!unary_exp->inExp->not_);
5483 } 5504 temp.push_front(anonFuncStart() + nll(x));
5484 popAnonVarArg(); 5505 popScope();
5485 popFunctionScope(); 5506 temp.push_back(indent() + anonFuncEnd());
5486 if (unary_exp->inExp->not_) { 5507 popAnonVarArg();
5487 temp.front().insert(0, "not "s); 5508 popFunctionScope();
5509 }
5488 } 5510 }
5489 out.push_back(join(temp)); 5511 out.push_back(join(temp));
5490 return; 5512 return;