diff options
| author | Li Jin <dragon-fly@qq.com> | 2025-07-18 16:13:02 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2025-07-18 16:13:02 +0800 |
| commit | a092802f958780282ae34f3cccc3cc8ce2263ac9 (patch) | |
| tree | 1474dd929308ac8f99fe6bb22ac6e3eb733b8f01 /src | |
| parent | 9d3d8ef2be15dfbf279de71241ff747a568e2c49 (diff) | |
| download | yuescript-a092802f958780282ae34f3cccc3cc8ce2263ac9.tar.gz yuescript-a092802f958780282ae34f3cccc3cc8ce2263ac9.tar.bz2 yuescript-a092802f958780282ae34f3cccc3cc8ce2263ac9.zip | |
Fixes.v0.29.1
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuescript/yue_ast.cpp | 115 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.h | 9 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 70 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 8 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 1 | ||||
| -rw-r--r-- | src/yuescript/yuescript.cpp | 1 |
6 files changed, 135 insertions, 69 deletions
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 { | |||
| 167 | std::string TableAppendingOp_t::to_string(void*) const { | 167 | std::string TableAppendingOp_t::to_string(void*) const { |
| 168 | return "[]"s; | 168 | return "[]"s; |
| 169 | } | 169 | } |
| 170 | std::string PlainItem_t::to_string(void *) const { | 170 | std::string PlainItem_t::to_string(void*) const { |
| 171 | return {}; | 171 | return {}; |
| 172 | } | 172 | } |
| 173 | std::string GlobalOp_t::to_string(void*) const { | 173 | std::string GlobalOp_t::to_string(void*) const { |
| @@ -465,41 +465,75 @@ std::string If_t::to_string(void* ud) const { | |||
| 465 | temp.back() += " then"s; | 465 | temp.back() += " then"s; |
| 466 | } | 466 | } |
| 467 | ++it; | 467 | ++it; |
| 468 | bool condition = true; | 468 | enum class NType { |
| 469 | Cond, | ||
| 470 | Stat, | ||
| 471 | Block | ||
| 472 | }; | ||
| 473 | NType lastType = NType::Cond; | ||
| 469 | for (; it != nodes.objects().end(); ++it) { | 474 | for (; it != nodes.objects().end(); ++it) { |
| 470 | auto node = *it; | 475 | auto node = *it; |
| 471 | switch (node->get_id()) { | 476 | switch (node->get_id()) { |
| 472 | case id<IfCond_t>(): | 477 | case id<IfCond_t>(): |
| 473 | temp.emplace_back(info->ind() + "elseif "s + node->to_string(ud)); | 478 | temp.emplace_back(info->ind() + "elseif "s + node->to_string(ud)); |
| 474 | condition = true; | 479 | lastType = NType::Cond; |
| 475 | break; | 480 | break; |
| 476 | case id<Statement_t>(): { | 481 | case id<Statement_t>(): { |
| 477 | if (condition) { | 482 | switch (lastType) { |
| 478 | temp.back() += " then "s + node->to_string(ud); | 483 | case NType::Cond: |
| 479 | } else { | 484 | temp.back() += " then "s + node->to_string(ud); |
| 480 | temp.emplace_back(info->ind() + "else "s + node->to_string(ud)); | 485 | break; |
| 486 | case NType::Stat: | ||
| 487 | if (temp.back().back() == '\n') { | ||
| 488 | temp.emplace_back(info->ind() + "else "s + node->to_string(ud)); | ||
| 489 | } else { | ||
| 490 | temp.back() += " else "s + node->to_string(ud); | ||
| 491 | } | ||
| 492 | break; | ||
| 493 | case NType::Block: | ||
| 494 | temp.emplace_back(info->ind() + "else "s + node->to_string(ud)); | ||
| 495 | break; | ||
| 481 | } | 496 | } |
| 482 | condition = false; | 497 | lastType = NType::Stat; |
| 483 | break; | 498 | break; |
| 484 | } | 499 | } |
| 485 | case id<Block_t>(): { | 500 | case id<Block_t>(): { |
| 486 | if (condition) { | 501 | switch (lastType) { |
| 487 | info->pushScope(); | 502 | case NType::Cond: { |
| 488 | temp.emplace_back(node->to_string(ud)); | 503 | info->pushScope(); |
| 489 | if (temp.back().empty()) { | 504 | temp.emplace_back(node->to_string(ud)); |
| 490 | temp.back() = info->ind() + "--"s; | 505 | if (temp.back().empty()) { |
| 506 | temp.back() = info->ind() + "--"s; | ||
| 507 | } | ||
| 508 | info->popScope(); | ||
| 509 | break; | ||
| 491 | } | 510 | } |
| 492 | info->popScope(); | 511 | case NType::Stat: { |
| 493 | } else { | 512 | if (temp.back().back() == '\n') { |
| 494 | temp.emplace_back(info->ind() + "else"s); | 513 | temp.emplace_back(info->ind() + "else"s); |
| 495 | info->pushScope(); | 514 | } else { |
| 496 | temp.emplace_back(node->to_string(ud)); | 515 | temp.back() += " else"s; |
| 497 | if (temp.back().empty()) { | 516 | } |
| 498 | temp.back() = info->ind() + "--"s; | 517 | info->pushScope(); |
| 518 | temp.emplace_back(node->to_string(ud)); | ||
| 519 | if (temp.back().empty()) { | ||
| 520 | temp.back() = info->ind() + "--"s; | ||
| 521 | } | ||
| 522 | info->popScope(); | ||
| 523 | break; | ||
| 524 | } | ||
| 525 | case NType::Block: { | ||
| 526 | temp.emplace_back(info->ind() + "else"s); | ||
| 527 | info->pushScope(); | ||
| 528 | temp.emplace_back(node->to_string(ud)); | ||
| 529 | if (temp.back().empty()) { | ||
| 530 | temp.back() = info->ind() + "--"s; | ||
| 531 | } | ||
| 532 | info->popScope(); | ||
| 533 | break; | ||
| 499 | } | 534 | } |
| 500 | info->popScope(); | ||
| 501 | } | 535 | } |
| 502 | condition = false; | 536 | lastType = NType::Block; |
| 503 | break; | 537 | break; |
| 504 | } | 538 | } |
| 505 | } | 539 | } |
| @@ -962,6 +996,10 @@ std::string DoubleString_t::to_string(void* ud) const { | |||
| 962 | } | 996 | } |
| 963 | return '"' + join(temp) + '"'; | 997 | return '"' + join(temp) + '"'; |
| 964 | } | 998 | } |
| 999 | std::string YAMLIndent_t::to_string(void* ud) const { | ||
| 1000 | auto info = reinterpret_cast<YueFormat*>(ud); | ||
| 1001 | return info->convert(this); | ||
| 1002 | } | ||
| 965 | std::string YAMLLineInner_t::to_string(void* ud) const { | 1003 | std::string YAMLLineInner_t::to_string(void* ud) const { |
| 966 | auto info = reinterpret_cast<YueFormat*>(ud); | 1004 | auto info = reinterpret_cast<YueFormat*>(ud); |
| 967 | return info->convert(this); | 1005 | return info->convert(this); |
| @@ -980,11 +1018,28 @@ std::string YAMLLine_t::to_string(void* ud) const { | |||
| 980 | return join(temp); | 1018 | return join(temp); |
| 981 | } | 1019 | } |
| 982 | std::string YAMLMultiline_t::to_string(void* ud) const { | 1020 | std::string YAMLMultiline_t::to_string(void* ud) const { |
| 1021 | auto info = reinterpret_cast<YueFormat*>(ud); | ||
| 1022 | int currentIndent = info->indent; | ||
| 983 | str_list temp; | 1023 | str_list temp; |
| 984 | for (auto seg : lines.objects()) { | 1024 | int lastIndent = -1; |
| 985 | temp.emplace_back(seg->to_string(ud)); | 1025 | for (auto line_ : lines.objects()) { |
| 1026 | auto line = static_cast<YAMLLine_t*>(line_); | ||
| 1027 | auto indent = line->indent->to_string(ud); | ||
| 1028 | int ind = 0; | ||
| 1029 | for (auto c : indent) { | ||
| 1030 | if (c == ' ') ind++; | ||
| 1031 | if (c == '\t') ind += 4; | ||
| 1032 | } | ||
| 1033 | if (lastIndent < ind) { | ||
| 1034 | info->pushScope(); | ||
| 1035 | } else if (lastIndent > ind) { | ||
| 1036 | info->popScope(); | ||
| 1037 | } | ||
| 1038 | lastIndent = ind; | ||
| 1039 | temp.emplace_back(indent + line->to_string(ud)); | ||
| 986 | } | 1040 | } |
| 987 | return "|\n" + join(temp, "\n"sv); | 1041 | info->indent = currentIndent; |
| 1042 | return "|\n" + join(temp, "\n"sv) + '\n'; | ||
| 988 | } | 1043 | } |
| 989 | std::string String_t::to_string(void* ud) const { | 1044 | std::string String_t::to_string(void* ud) const { |
| 990 | return str->to_string(ud); | 1045 | return str->to_string(ud); |
| @@ -1284,6 +1339,9 @@ std::string FnArgDef_t::to_string(void* ud) const { | |||
| 1284 | if (op) { | 1339 | if (op) { |
| 1285 | line += op->to_string(ud); | 1340 | line += op->to_string(ud); |
| 1286 | } | 1341 | } |
| 1342 | if (label) { | ||
| 1343 | line += '`' + label->to_string(ud); | ||
| 1344 | } | ||
| 1287 | if (defaultValue) { | 1345 | if (defaultValue) { |
| 1288 | line += " = "s + defaultValue->to_string(ud); | 1346 | line += " = "s + defaultValue->to_string(ud); |
| 1289 | } | 1347 | } |
| @@ -1306,6 +1364,9 @@ std::string FnArgDefList_t::to_string(void* ud) const { | |||
| 1306 | } | 1364 | } |
| 1307 | if (varArg) { | 1365 | if (varArg) { |
| 1308 | temp.emplace_back(info->ind() + varArg->to_string(ud)); | 1366 | temp.emplace_back(info->ind() + varArg->to_string(ud)); |
| 1367 | if (label) { | ||
| 1368 | temp.back().append('`' + label->to_string(ud)); | ||
| 1369 | } | ||
| 1309 | } | 1370 | } |
| 1310 | return join(temp, "\n"sv); | 1371 | return join(temp, "\n"sv); |
| 1311 | } else { | 1372 | } else { |
| @@ -1314,6 +1375,9 @@ std::string FnArgDefList_t::to_string(void* ud) const { | |||
| 1314 | } | 1375 | } |
| 1315 | if (varArg) { | 1376 | if (varArg) { |
| 1316 | temp.emplace_back(varArg->to_string(ud)); | 1377 | temp.emplace_back(varArg->to_string(ud)); |
| 1378 | if (label) { | ||
| 1379 | temp.back().append('`' + label->to_string(ud)); | ||
| 1380 | } | ||
| 1317 | } | 1381 | } |
| 1318 | return join(temp, ", "sv); | 1382 | return join(temp, ", "sv); |
| 1319 | } | 1383 | } |
| @@ -1595,3 +1659,4 @@ std::string File_t::to_string(void* ud) const { | |||
| 1595 | } // namespace yue | 1659 | } // namespace yue |
| 1596 | 1660 | ||
| 1597 | } // namespace parserlib | 1661 | } // namespace parserlib |
| 1662 | |||
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) | |||
| 591 | AST_MEMBER(DoubleString, &sep, &segments) | 591 | AST_MEMBER(DoubleString, &sep, &segments) |
| 592 | AST_END(DoubleString) | 592 | AST_END(DoubleString) |
| 593 | 593 | ||
| 594 | AST_LEAF(YAMLIndent) | ||
| 595 | AST_END(YAMLIndent) | ||
| 596 | |||
| 594 | AST_LEAF(YAMLLineInner) | 597 | AST_LEAF(YAMLLineInner) |
| 595 | AST_END(YAMLLineInner) | 598 | AST_END(YAMLLineInner) |
| 596 | 599 | ||
| @@ -600,9 +603,9 @@ AST_NODE(YAMLLineContent) | |||
| 600 | AST_END(YAMLLineContent) | 603 | AST_END(YAMLLineContent) |
| 601 | 604 | ||
| 602 | AST_NODE(YAMLLine) | 605 | AST_NODE(YAMLLine) |
| 603 | ast_ptr<true, Seperator_t> sep; | 606 | ast_ptr<true, YAMLIndent_t> indent; |
| 604 | ast_list<false, YAMLLineContent_t> segments; | 607 | ast_list<true, YAMLLineContent_t> segments; |
| 605 | AST_MEMBER(YAMLLine, &sep, &segments) | 608 | AST_MEMBER(YAMLLine, &indent, &segments) |
| 606 | AST_END(YAMLLine) | 609 | AST_END(YAMLLine) |
| 607 | 610 | ||
| 608 | AST_NODE(YAMLMultiline) | 611 | 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: | |||
| 9183 | str_list temp; | 9183 | str_list temp; |
| 9184 | for (auto line_ : multiline->lines.objects()) { | 9184 | for (auto line_ : multiline->lines.objects()) { |
| 9185 | auto line = static_cast<YAMLLine_t*>(line_); | 9185 | auto line = static_cast<YAMLLine_t*>(line_); |
| 9186 | if (!line->segments.empty()) { | 9186 | auto indentStr = _parser.toString(line->indent); |
| 9187 | str_list segs; | 9187 | if (!indent) { |
| 9188 | bool firstSeg = true; | 9188 | indent = indentStr; |
| 9189 | for (auto seg_ : line->segments.objects()) { | 9189 | } |
| 9190 | auto content = static_cast<YAMLLineContent_t*>(seg_)->content.get(); | 9190 | if (std::string_view{indentStr.c_str(), indent.value().size()} != indent.value()) { |
| 9191 | switch (content->get_id()) { | 9191 | throw CompileError("inconsistent indent"sv, line); |
| 9192 | case id<YAMLLineInner_t>(): { | 9192 | } |
| 9193 | auto seg = _parser.toString(content); | 9193 | indentStr = indentStr.substr(indent.value().size()); |
| 9194 | if (!indent) { | 9194 | str_list segs; |
| 9195 | auto pos = seg.find_first_not_of("\t "sv); | 9195 | bool firstSeg = true; |
| 9196 | if (pos == std::string::npos) { | 9196 | for (auto seg_ : line->segments.objects()) { |
| 9197 | indent = seg; | 9197 | auto content = static_cast<YAMLLineContent_t*>(seg_)->content.get(); |
| 9198 | firstSeg = false; | 9198 | switch (content->get_id()) { |
| 9199 | continue; | 9199 | case id<YAMLLineInner_t>(): { |
| 9200 | } else { | 9200 | auto seqStr = _parser.toString(content); |
| 9201 | indent = std::string{seg.c_str(), pos}; | 9201 | Utils::replace(seqStr, "\\#"sv, "#"sv); |
| 9202 | } | 9202 | if (firstSeg) { |
| 9203 | } | 9203 | firstSeg = false; |
| 9204 | if (firstSeg) { | 9204 | seqStr.insert(0, indentStr); |
| 9205 | firstSeg = false; | 9205 | } |
| 9206 | if (std::string_view{seg}.substr(0, indent.value().size()) != indent.value()) { | 9206 | segs.push_back(Utils::toLuaDoubleString(seqStr)); |
| 9207 | throw CompileError("inconsistent indent"sv, line); | 9207 | break; |
| 9208 | } | 9208 | } |
| 9209 | auto seqStr = seg.substr(indent.value().size()); | 9209 | case id<Exp_t>(): { |
| 9210 | if (!seqStr.empty()) { | 9210 | if (firstSeg) { |
| 9211 | segs.push_back(Utils::toLuaDoubleString(seqStr)); | 9211 | firstSeg = false; |
| 9212 | } | 9212 | if (!indentStr.empty()) { |
| 9213 | } else { | 9213 | segs.push_back(Utils::toLuaDoubleString(indentStr)); |
| 9214 | segs.push_back(Utils::toLuaDoubleString(seg)); | ||
| 9215 | } | 9214 | } |
| 9216 | break; | ||
| 9217 | } | ||
| 9218 | case id<Exp_t>(): { | ||
| 9219 | transformExp(static_cast<Exp_t*>(content), segs, ExpUsage::Closure); | ||
| 9220 | segs.back() = globalVar("tostring"sv, content, AccessType::Read) + '(' + segs.back() + ')'; | ||
| 9221 | break; | ||
| 9222 | } | 9215 | } |
| 9223 | default: YUEE("AST node mismatch", content); break; | 9216 | transformExp(static_cast<Exp_t*>(content), segs, ExpUsage::Closure); |
| 9217 | segs.back() = globalVar("tostring"sv, content, AccessType::Read) + '(' + segs.back() + ')'; | ||
| 9218 | break; | ||
| 9224 | } | 9219 | } |
| 9220 | default: YUEE("AST node mismatch", content); break; | ||
| 9225 | } | 9221 | } |
| 9226 | temp.push_back(join(segs, " .. "sv)); | ||
| 9227 | } | 9222 | } |
| 9223 | temp.push_back(join(segs, " .. "sv)); | ||
| 9228 | } | 9224 | } |
| 9229 | auto str = join(temp, " .. '\\n' .. "sv); | 9225 | auto str = join(temp, " .. '\\n' .. "sv); |
| 9230 | Utils::replace(str, "\" .. '\\n' .. \""sv, "\\n"sv); | 9226 | 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() { | |||
| 640 | DoubleStringContent = DoubleStringInner | interp; | 640 | DoubleStringContent = DoubleStringInner | interp; |
| 641 | DoubleString = '"' >> Seperator >> *DoubleStringContent >> '"'; | 641 | DoubleString = '"' >> Seperator >> *DoubleStringContent >> '"'; |
| 642 | 642 | ||
| 643 | YAMLIndent = +set(" \t"); | ||
| 643 | YAMLLineInner = +('\\' >> set("\"\\#") | not_("#{" | stop) >> any_char); | 644 | YAMLLineInner = +('\\' >> set("\"\\#") | not_("#{" | stop) >> any_char); |
| 644 | YAMLLineContent = YAMLLineInner | interp; | 645 | YAMLLineContent = YAMLLineInner | interp; |
| 645 | YAMLLine = check_indent_match >> Seperator >> +YAMLLineContent | | 646 | YAMLLine = check_indent_match >> YAMLIndent >> +(YAMLLineContent) | |
| 646 | advance_match >> Seperator >> ensure(+YAMLLineContent, pop_indent) | | 647 | advance_match >> YAMLIndent >> ensure(+YAMLLineContent, pop_indent); |
| 647 | Seperator >> *set(" \t") >> and_(line_break); | 648 | YAMLMultiline = '|' >> space >> Seperator >> +(*set(" \t") >> line_break) >> advance_match >> ensure(YAMLLine >> *(+(*set(" \t") >> line_break) >> YAMLLine), pop_indent); |
| 648 | YAMLMultiline = '|' >> space >> Seperator >> +(*set(" \t") >> line_break) >> advance_match >> ensure(YAMLLine >> *(*set(" \t") >> line_break >> YAMLLine), pop_indent); | ||
| 649 | 649 | ||
| 650 | String = DoubleString | SingleString | LuaString | YAMLMultiline; | 650 | String = DoubleString | SingleString | LuaString | YAMLMultiline; |
| 651 | 651 | ||
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: | |||
| 378 | AST_RULE(DoubleStringInner); | 378 | AST_RULE(DoubleStringInner); |
| 379 | AST_RULE(DoubleStringContent); | 379 | AST_RULE(DoubleStringContent); |
| 380 | AST_RULE(DoubleString); | 380 | AST_RULE(DoubleString); |
| 381 | AST_RULE(YAMLIndent); | ||
| 381 | AST_RULE(YAMLLineInner); | 382 | AST_RULE(YAMLLineInner); |
| 382 | AST_RULE(YAMLLineContent); | 383 | AST_RULE(YAMLLineContent); |
| 383 | AST_RULE(YAMLLine); | 384 | 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) { | |||
| 207 | formatter.spaceOverTab = false; | 207 | formatter.spaceOverTab = false; |
| 208 | } | 208 | } |
| 209 | auto result = formatter.toString(info.node.get()); | 209 | auto result = formatter.toString(info.node.get()); |
| 210 | yue::Utils::replace(result, "\n\n", "\n"); | ||
| 210 | lua_pushlstring(L, result.c_str(), result.size()); | 211 | lua_pushlstring(L, result.c_str(), result.size()); |
| 211 | return 1; | 212 | return 1; |
| 212 | } | 213 | } |
