aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/yuescript/yue_ast.cpp115
-rw-r--r--src/yuescript/yue_ast.h9
-rw-r--r--src/yuescript/yue_compiler.cpp70
-rw-r--r--src/yuescript/yue_parser.cpp8
-rw-r--r--src/yuescript/yue_parser.h1
-rw-r--r--src/yuescript/yuescript.cpp1
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 {
167std::string TableAppendingOp_t::to_string(void*) const { 167std::string TableAppendingOp_t::to_string(void*) const {
168 return "[]"s; 168 return "[]"s;
169} 169}
170std::string PlainItem_t::to_string(void *) const { 170std::string PlainItem_t::to_string(void*) const {
171 return {}; 171 return {};
172} 172}
173std::string GlobalOp_t::to_string(void*) const { 173std::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}
999std::string YAMLIndent_t::to_string(void* ud) const {
1000 auto info = reinterpret_cast<YueFormat*>(ud);
1001 return info->convert(this);
1002}
965std::string YAMLLineInner_t::to_string(void* ud) const { 1003std::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}
982std::string YAMLMultiline_t::to_string(void* ud) const { 1020std::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}
989std::string String_t::to_string(void* ud) const { 1044std::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)
592AST_END(DoubleString) 592AST_END(DoubleString)
593 593
594AST_LEAF(YAMLIndent)
595AST_END(YAMLIndent)
596
594AST_LEAF(YAMLLineInner) 597AST_LEAF(YAMLLineInner)
595AST_END(YAMLLineInner) 598AST_END(YAMLLineInner)
596 599
@@ -600,9 +603,9 @@ AST_NODE(YAMLLineContent)
600AST_END(YAMLLineContent) 603AST_END(YAMLLineContent)
601 604
602AST_NODE(YAMLLine) 605AST_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)
606AST_END(YAMLLine) 609AST_END(YAMLLine)
607 610
608AST_NODE(YAMLMultiline) 611AST_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}