diff --git a/spec/outputs/lists.lua b/spec/outputs/lists.lua index e6f306d..e2d512d 100644 --- a/spec/outputs/lists.lua +++ b/spec/outputs/lists.lua @@ -313,20 +313,7 @@ do end c = (1 == a) c = (1 == a) - do - local _check_0 = { - 1 - } - local _find_0 = false - for _index_0 = 1, #_check_0 do - local _item_0 = _check_0[_index_0] - if _item_0 == a then - _find_0 = true - break - end - end - c = _find_0 - end + c = (1 == a) end do a, b = hello[1], hello[2] diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index 6b2c96d..69695a0 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp @@ -822,9 +822,11 @@ std::string Slice_t::to_string(void* ud) const { if (startValue.is()) { temp.emplace_back(startValue->to_string(ud)); } - temp.emplace_back(", "s); if (stopValue.is()) { - temp.emplace_back(stopValue->to_string(ud)); + temp.emplace_back(); + temp.emplace_back(", "s + stopValue->to_string(ud)); + } else { + temp.emplace_back(","s); } if (stepValue.is()) { temp.emplace_back(", "s + stepValue->to_string(ud)); @@ -832,10 +834,15 @@ std::string Slice_t::to_string(void* ud) const { auto valueStr = join(temp); return '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']'; } -static bool isInBlockExp(ast_node* node) { +static bool isInBlockExp(ast_node* node, bool last = false) { if (auto exp = ast_cast(node)) { - auto unaryExp = static_cast(exp->pipeExprs.front()); - auto value = static_cast(unaryExp->expos.front()); + UnaryExp_t* unaryExp = nullptr; + if (exp->opValues.empty()) { + unaryExp = static_cast(exp->pipeExprs.back()); + } else { + unaryExp = static_cast(static_cast(exp->opValues.back())->pipeExprs.back()); + } + auto value = static_cast(unaryExp->expos.back()); if (auto simpleValue = value->item.as()) { if (!ast_is(simpleValue->value)) { @@ -845,9 +852,76 @@ static bool isInBlockExp(ast_node* node) { if (ast_is(chainValue->items.back())) { return true; } + } else if (!last && value->item.is()) { + return true; } } else if (ast_is(node)) { return true; + } else { + switch (node->get_id()) { + case id(): { + auto pair = static_cast(node); + if (pair->defVal) { + return true; + } + return false; + } + case id(): { + auto pair = static_cast(node); + if (pair->defVal) { + return true; + } + return isInBlockExp(pair->pair->value); + } + case id(): { + auto pair = static_cast(node); + return isInBlockExp(pair->exp); + } + case id(): { + auto pair = static_cast(node); + if (pair->defVal) { + return true; + } + return isInBlockExp(pair->item); + } + case id(): { + auto pair = static_cast(node); + if (pair->defVal) { + return true; + } + return false; + } + case id(): { + auto pair = static_cast(node); + if (pair->defVal) { + return true; + } + return isInBlockExp(pair->pair->value); + } + case id(): { + return false; + } + case id(): { + auto pair = static_cast(node); + return isInBlockExp(pair->value); + } + case id(): { + return false; + } + case id(): { + auto pair = static_cast(node); + return isInBlockExp(pair->value); + } + case id(): { + return true; + } + case id(): { + auto pair = static_cast(node); + return isInBlockExp(pair->exp); + } + default: + return false; + } } return false; } @@ -865,7 +939,7 @@ std::string Invoke_t::to_string(void* ud) const { auto info = reinterpret_cast(ud); bool hasInBlockExp = false; for (auto arg : args.objects()) { - if (arg != args.back() && isInBlockExp(arg)) { + if (isInBlockExp(arg, arg == args.back())) { hasInBlockExp = true; break; } @@ -899,15 +973,30 @@ std::string TableLit_t::to_string(void* ud) const { if (values.empty()) { return "{ }"s; } - str_list temp; - temp.emplace_back("{"s); - info->pushScope(); + bool hasInBlockExp = false; for (auto value : values.objects()) { - temp.emplace_back(info->ind() + value->to_string(ud)); + if (isInBlockExp(value, value == values.back())) { + hasInBlockExp = true; + break; + } + } + if (hasInBlockExp) { + str_list temp; + temp.emplace_back("{"s); + info->pushScope(); + for (auto value : values.objects()) { + temp.emplace_back(info->ind() + value->to_string(ud)); + } + info->popScope(); + temp.emplace_back(info->ind() + '}'); + return join(temp, "\n"sv); + } else { + str_list temp; + for (auto value : values.objects()) { + temp.emplace_back(value->to_string(ud)); + } + return '{' + join(temp, ", "sv) + '}'; } - info->popScope(); - temp.emplace_back(info->ind() + '}'); - return join(temp, "\n"sv); } std::string TableBlock_t::to_string(void* ud) const { auto info = reinterpret_cast(ud); @@ -1108,7 +1197,7 @@ std::string FnArgDefList_t::to_string(void* ud) const { bool hasInBlockExp = false; for (auto def : definitions.objects()) { auto argDef = static_cast(def); - if (argDef->defaultValue && isInBlockExp(argDef->defaultValue)) { + if (argDef->defaultValue && isInBlockExp(argDef->defaultValue, argDef == definitions.back())) { hasInBlockExp = true; break; } @@ -1144,7 +1233,7 @@ std::string FnArgsDef_t::to_string(void* ud) const { if (defList) { for (auto def : defList->definitions.objects()) { auto argDef = static_cast(def); - if (argDef->defaultValue && isInBlockExp(argDef->defaultValue)) { + if (argDef->defaultValue && isInBlockExp(argDef->defaultValue, argDef == defList->definitions.back())) { hasInBlockExp = true; break; } @@ -1250,7 +1339,7 @@ std::string InvokeArgs_t::to_string(void* ud) const { auto info = reinterpret_cast(ud); bool hasInBlockExp = false; for (auto arg : args.objects()) { - if (isInBlockExp(arg)) { + if (isInBlockExp(arg, arg == args.back())) { hasInBlockExp = true; break; } @@ -1309,7 +1398,7 @@ std::string InDiscrete_t::to_string(void* ud) const { for (auto value : values.objects()) { temp.emplace_back(value->to_string(ud)); } - return '{' + join(temp, ", "sv) + '}'; + return '[' + join(temp, ", "sv) + (temp.size() == 1 ? ",]"s : "]"s); } std::string In_t::to_string(void* ud) const { return (not_ ? "not "s : ""s) + "in "s + item->to_string(ud); diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 59f6d4b..044ee91 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -75,7 +75,7 @@ static std::unordered_set Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.21.2"sv; +const std::string_view version = "0.21.3"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -7713,8 +7713,9 @@ class YueCompilerImpl { clsDecl = value->get_by_path(); BLOCK_END } else if (auto expList = expListFrom(statement)) { - auto value = singleValueFrom(expList); - clsDecl = value->get_by_path(); + if (auto value = singleValueFrom(expList)) { + clsDecl = value->get_by_path(); + } } if (clsDecl) { std::string clsName; diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 89791d6..3557534 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -521,7 +521,7 @@ YueParser::YueParser() { NotIn = true_(); InDiscrete = '[' >> Seperator >> space >> exp_not_tab >> (+(space >> ',' >> space >> exp_not_tab) | space >> ',') >> space >> ']' | - '{' >> Seperator >> space >> exp_not_tab >> *(space >> ',' >> space >> exp_not_tab) >> space >> '}'; + '{' >> Seperator >> space >> exp_not_tab >> *(space >> ',' >> space >> exp_not_tab | space >> ',') >> space >> '}'; In = -(key("not") >> NotIn >> space) >> key("in") >> space >> (InDiscrete | and_(key("not")) >> confusing_unary_not_error | Exp); UnaryOperator =