diff options
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 | } |