From fcb480618f162817572947cfed96b1ba0d6c5a44 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Thu, 20 Jul 2023 18:25:10 +0800 Subject: fix wrong codes generation for in-expression. --- src/yuescript/yue_compiler.cpp | 66 ++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 22 deletions(-) (limited to 'src') 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 Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.17.7"sv; +const std::string_view version = "0.17.8"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -1161,6 +1161,9 @@ private: auto unary = static_cast(exp->pipeExprs.back()); BREAK_IF(unary->expos.size() != 1); BREAK_IF(!unary->inExp); + if (unary->inExp->item.is()) { + return unary; + } auto value = static_cast(unary->expos.back()); auto varName = singleVariableFrom(value, false); if (varName.empty() || !isLocal(varName)) { @@ -5416,7 +5419,11 @@ private: _buf << "\tif "sv << itemVar << "=="sv << varName << '\n'; _buf << "\t\t"sv << findVar << "=true\n"sv; _buf << "\t\tbreak\n"sv; - _buf << findVar; + if (unary_exp->inExp->not_) { + _buf << "not "sv << findVar; + } else { + _buf << findVar; + } auto blockStr = clearBuf(); auto checkBlock = toAst(blockStr, inExp); block->statements.dup(checkBlock->statements); @@ -5437,30 +5444,44 @@ private: out.push_back(join(temp)); return; } else { - pushFunctionScope(); - pushAnonVarArg(); - pushScope(); - auto arrayCheck = [&]() { + auto arrayCheck = [&](bool exist) { auto indexVar = getUnusedName("_index_"); _buf << indent() << "for "sv << indexVar << " = 1, #"sv << checkVar << " do"sv << nll(x); incIndentOffset(); _buf << indent() << "if "sv << checkVar << '[' << indexVar << "] == "sv << varName << " then"sv << nll(x); incIndentOffset(); - _buf << indent() << "return true"sv << nll(x); + _buf << indent() << "return "sv << (exist ? "true"sv : "false"sv) << nll(x); decIndentOffset(); _buf << indent() << "end"sv << nll(x); decIndentOffset(); _buf << indent() << "end"sv << nll(x); - _buf << indent() << "return false"sv << nll(x); + _buf << indent() << "return "sv << (exist ? "false"sv : "true"sv) << nll(x); temp.push_back(clearBuf()); }; - bool useShortCheck = !varName.empty() && !checkVar.empty() && isLocal(checkVar); + bool useShortCheck = (usage == ExpUsage::Closure) && !varName.empty() && !checkVar.empty() && isLocal(checkVar); if (useShortCheck) { - arrayCheck(); - temp.push_front("(#"s + checkVar + " > 0 and "s + anonFuncStart() + nll(x)); - popScope(); - temp.push_back(indent() + anonFuncEnd() + ')'); + if (usage == ExpUsage::Return) { + arrayCheck(!unary_exp->inExp->not_); + } else { + pushFunctionScope(); + pushAnonVarArg(); + pushScope(); + arrayCheck(true); + temp.push_front("(#"s + checkVar + " > 0 and "s + anonFuncStart() + nll(x)); + popScope(); + temp.push_back(indent() + anonFuncEnd() + ')'); + if (unary_exp->inExp->not_) { + temp.front().insert(0, "not "s); + } + popAnonVarArg(); + popFunctionScope(); + } } else { + if (usage == ExpUsage::Closure) { + pushFunctionScope(); + pushAnonVarArg(); + pushScope(); + } if (checkVar.empty() || !isLocal(checkVar)) { checkVar = getUnusedName("_check_"sv); auto assignment = assignmentFrom(toAst(checkVar, inExp), inExp, inExp); @@ -5476,15 +5497,16 @@ private: auto assignment = assignmentFrom(assignExp, exp, x); transformAssignment(assignment, temp); } - arrayCheck(); - temp.push_front(anonFuncStart() + nll(x)); - popScope(); - temp.push_back(indent() + anonFuncEnd()); - } - popAnonVarArg(); - popFunctionScope(); - if (unary_exp->inExp->not_) { - temp.front().insert(0, "not "s); + if (usage == ExpUsage::Return) { + arrayCheck(!unary_exp->inExp->not_); + } else { + arrayCheck(!unary_exp->inExp->not_); + temp.push_front(anonFuncStart() + nll(x)); + popScope(); + temp.push_back(indent() + anonFuncEnd()); + popAnonVarArg(); + popFunctionScope(); + } } out.push_back(join(temp)); return; -- cgit v1.2.3-55-g6feb