From a092802f958780282ae34f3cccc3cc8ce2263ac9 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Fri, 18 Jul 2025 16:13:02 +0800 Subject: Fixes. --- src/yuescript/yue_ast.cpp | 115 ++++++++++++++++++++++++++++++++--------- src/yuescript/yue_ast.h | 9 ++-- src/yuescript/yue_compiler.cpp | 70 ++++++++++++------------- src/yuescript/yue_parser.cpp | 8 +-- src/yuescript/yue_parser.h | 1 + src/yuescript/yuescript.cpp | 1 + 6 files changed, 135 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index bacdc01..0ad581b 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp @@ -167,7 +167,7 @@ std::string ExistentialOp_t::to_string(void*) const { std::string TableAppendingOp_t::to_string(void*) const { return "[]"s; } -std::string PlainItem_t::to_string(void *) const { +std::string PlainItem_t::to_string(void*) const { return {}; } std::string GlobalOp_t::to_string(void*) const { @@ -465,41 +465,75 @@ std::string If_t::to_string(void* ud) const { temp.back() += " then"s; } ++it; - bool condition = true; + enum class NType { + Cond, + Stat, + Block + }; + NType lastType = NType::Cond; for (; it != nodes.objects().end(); ++it) { auto node = *it; switch (node->get_id()) { case id(): temp.emplace_back(info->ind() + "elseif "s + node->to_string(ud)); - condition = true; + lastType = NType::Cond; break; case id(): { - if (condition) { - temp.back() += " then "s + node->to_string(ud); - } else { - temp.emplace_back(info->ind() + "else "s + node->to_string(ud)); + switch (lastType) { + case NType::Cond: + temp.back() += " then "s + node->to_string(ud); + break; + case NType::Stat: + if (temp.back().back() == '\n') { + temp.emplace_back(info->ind() + "else "s + node->to_string(ud)); + } else { + temp.back() += " else "s + node->to_string(ud); + } + break; + case NType::Block: + temp.emplace_back(info->ind() + "else "s + node->to_string(ud)); + break; } - condition = false; + lastType = NType::Stat; break; } case id(): { - if (condition) { - info->pushScope(); - temp.emplace_back(node->to_string(ud)); - if (temp.back().empty()) { - temp.back() = info->ind() + "--"s; + switch (lastType) { + case NType::Cond: { + info->pushScope(); + temp.emplace_back(node->to_string(ud)); + if (temp.back().empty()) { + temp.back() = info->ind() + "--"s; + } + info->popScope(); + break; } - info->popScope(); - } else { - temp.emplace_back(info->ind() + "else"s); - info->pushScope(); - temp.emplace_back(node->to_string(ud)); - if (temp.back().empty()) { - temp.back() = info->ind() + "--"s; + case NType::Stat: { + if (temp.back().back() == '\n') { + temp.emplace_back(info->ind() + "else"s); + } else { + temp.back() += " else"s; + } + info->pushScope(); + temp.emplace_back(node->to_string(ud)); + if (temp.back().empty()) { + temp.back() = info->ind() + "--"s; + } + info->popScope(); + break; + } + case NType::Block: { + temp.emplace_back(info->ind() + "else"s); + info->pushScope(); + temp.emplace_back(node->to_string(ud)); + if (temp.back().empty()) { + temp.back() = info->ind() + "--"s; + } + info->popScope(); + break; } - info->popScope(); } - condition = false; + lastType = NType::Block; break; } } @@ -962,6 +996,10 @@ std::string DoubleString_t::to_string(void* ud) const { } return '"' + join(temp) + '"'; } +std::string YAMLIndent_t::to_string(void* ud) const { + auto info = reinterpret_cast(ud); + return info->convert(this); +} std::string YAMLLineInner_t::to_string(void* ud) const { auto info = reinterpret_cast(ud); return info->convert(this); @@ -980,11 +1018,28 @@ std::string YAMLLine_t::to_string(void* ud) const { return join(temp); } std::string YAMLMultiline_t::to_string(void* ud) const { + auto info = reinterpret_cast(ud); + int currentIndent = info->indent; str_list temp; - for (auto seg : lines.objects()) { - temp.emplace_back(seg->to_string(ud)); + int lastIndent = -1; + for (auto line_ : lines.objects()) { + auto line = static_cast(line_); + auto indent = line->indent->to_string(ud); + int ind = 0; + for (auto c : indent) { + if (c == ' ') ind++; + if (c == '\t') ind += 4; + } + if (lastIndent < ind) { + info->pushScope(); + } else if (lastIndent > ind) { + info->popScope(); + } + lastIndent = ind; + temp.emplace_back(indent + line->to_string(ud)); } - return "|\n" + join(temp, "\n"sv); + info->indent = currentIndent; + return "|\n" + join(temp, "\n"sv) + '\n'; } std::string String_t::to_string(void* ud) const { return str->to_string(ud); @@ -1284,6 +1339,9 @@ std::string FnArgDef_t::to_string(void* ud) const { if (op) { line += op->to_string(ud); } + if (label) { + line += '`' + label->to_string(ud); + } if (defaultValue) { line += " = "s + defaultValue->to_string(ud); } @@ -1306,6 +1364,9 @@ std::string FnArgDefList_t::to_string(void* ud) const { } if (varArg) { temp.emplace_back(info->ind() + varArg->to_string(ud)); + if (label) { + temp.back().append('`' + label->to_string(ud)); + } } return join(temp, "\n"sv); } else { @@ -1314,6 +1375,9 @@ std::string FnArgDefList_t::to_string(void* ud) const { } if (varArg) { temp.emplace_back(varArg->to_string(ud)); + if (label) { + temp.back().append('`' + label->to_string(ud)); + } } return join(temp, ", "sv); } @@ -1595,3 +1659,4 @@ std::string File_t::to_string(void* ud) const { } // namespace yue } // namespace parserlib + diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index c529f34..388bc85 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h @@ -591,6 +591,9 @@ AST_NODE(DoubleString) AST_MEMBER(DoubleString, &sep, &segments) AST_END(DoubleString) +AST_LEAF(YAMLIndent) +AST_END(YAMLIndent) + AST_LEAF(YAMLLineInner) AST_END(YAMLLineInner) @@ -600,9 +603,9 @@ AST_NODE(YAMLLineContent) AST_END(YAMLLineContent) AST_NODE(YAMLLine) - ast_ptr sep; - ast_list segments; - AST_MEMBER(YAMLLine, &sep, &segments) + ast_ptr indent; + ast_list segments; + AST_MEMBER(YAMLLine, &indent, &segments) AST_END(YAMLLine) AST_NODE(YAMLMultiline) diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index a8d222d..b01465f 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -9183,48 +9183,44 @@ private: str_list temp; for (auto line_ : multiline->lines.objects()) { auto line = static_cast(line_); - if (!line->segments.empty()) { - str_list segs; - bool firstSeg = true; - for (auto seg_ : line->segments.objects()) { - auto content = static_cast(seg_)->content.get(); - switch (content->get_id()) { - case id(): { - auto seg = _parser.toString(content); - if (!indent) { - auto pos = seg.find_first_not_of("\t "sv); - if (pos == std::string::npos) { - indent = seg; - firstSeg = false; - continue; - } else { - indent = std::string{seg.c_str(), pos}; - } - } - if (firstSeg) { - firstSeg = false; - if (std::string_view{seg}.substr(0, indent.value().size()) != indent.value()) { - throw CompileError("inconsistent indent"sv, line); - } - auto seqStr = seg.substr(indent.value().size()); - if (!seqStr.empty()) { - segs.push_back(Utils::toLuaDoubleString(seqStr)); - } - } else { - segs.push_back(Utils::toLuaDoubleString(seg)); + auto indentStr = _parser.toString(line->indent); + if (!indent) { + indent = indentStr; + } + if (std::string_view{indentStr.c_str(), indent.value().size()} != indent.value()) { + throw CompileError("inconsistent indent"sv, line); + } + indentStr = indentStr.substr(indent.value().size()); + str_list segs; + bool firstSeg = true; + for (auto seg_ : line->segments.objects()) { + auto content = static_cast(seg_)->content.get(); + switch (content->get_id()) { + case id(): { + auto seqStr = _parser.toString(content); + Utils::replace(seqStr, "\\#"sv, "#"sv); + if (firstSeg) { + firstSeg = false; + seqStr.insert(0, indentStr); + } + segs.push_back(Utils::toLuaDoubleString(seqStr)); + break; + } + case id(): { + if (firstSeg) { + firstSeg = false; + if (!indentStr.empty()) { + segs.push_back(Utils::toLuaDoubleString(indentStr)); } - break; - } - case id(): { - transformExp(static_cast(content), segs, ExpUsage::Closure); - segs.back() = globalVar("tostring"sv, content, AccessType::Read) + '(' + segs.back() + ')'; - break; } - default: YUEE("AST node mismatch", content); break; + transformExp(static_cast(content), segs, ExpUsage::Closure); + segs.back() = globalVar("tostring"sv, content, AccessType::Read) + '(' + segs.back() + ')'; + break; } + default: YUEE("AST node mismatch", content); break; } - temp.push_back(join(segs, " .. "sv)); } + temp.push_back(join(segs, " .. "sv)); } auto str = join(temp, " .. '\\n' .. "sv); Utils::replace(str, "\" .. '\\n' .. \""sv, "\\n"sv); diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 2e21a52..aefa350 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -640,12 +640,12 @@ YueParser::YueParser() { DoubleStringContent = DoubleStringInner | interp; DoubleString = '"' >> Seperator >> *DoubleStringContent >> '"'; + YAMLIndent = +set(" \t"); YAMLLineInner = +('\\' >> set("\"\\#") | not_("#{" | stop) >> any_char); YAMLLineContent = YAMLLineInner | interp; - YAMLLine = check_indent_match >> Seperator >> +YAMLLineContent | - advance_match >> Seperator >> ensure(+YAMLLineContent, pop_indent) | - Seperator >> *set(" \t") >> and_(line_break); - YAMLMultiline = '|' >> space >> Seperator >> +(*set(" \t") >> line_break) >> advance_match >> ensure(YAMLLine >> *(*set(" \t") >> line_break >> YAMLLine), pop_indent); + YAMLLine = check_indent_match >> YAMLIndent >> +(YAMLLineContent) | + advance_match >> YAMLIndent >> ensure(+YAMLLineContent, pop_indent); + YAMLMultiline = '|' >> space >> Seperator >> +(*set(" \t") >> line_break) >> advance_match >> ensure(YAMLLine >> *(+(*set(" \t") >> line_break) >> YAMLLine), pop_indent); String = DoubleString | SingleString | LuaString | YAMLMultiline; diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index f4e0ab1..e905840 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h @@ -378,6 +378,7 @@ private: AST_RULE(DoubleStringInner); AST_RULE(DoubleStringContent); AST_RULE(DoubleString); + AST_RULE(YAMLIndent); AST_RULE(YAMLLineInner); AST_RULE(YAMLLineContent); AST_RULE(YAMLLine); diff --git a/src/yuescript/yuescript.cpp b/src/yuescript/yuescript.cpp index aa19b70..61e3949 100644 --- a/src/yuescript/yuescript.cpp +++ b/src/yuescript/yuescript.cpp @@ -207,6 +207,7 @@ static int yueformat(lua_State* L) { formatter.spaceOverTab = false; } auto result = formatter.toString(info.node.get()); + yue::Utils::replace(result, "\n\n", "\n"); lua_pushlstring(L, result.c_str(), result.size()); return 1; } -- cgit v1.2.3-55-g6feb