diff options
author | Li Jin <dragon-fly@qq.com> | 2023-12-13 17:32:53 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2023-12-13 17:33:13 +0800 |
commit | 3c4cbff4d88892f153b70ccbbc69d1087ecbcc49 (patch) | |
tree | 0d9f1db9552bfb4106e424b33b51062cf96f8a02 /src | |
parent | de5fdb3e3f739582e40500cca9ff4bf6a4fc192f (diff) | |
download | yuescript-3c4cbff4d88892f153b70ccbbc69d1087ecbcc49.tar.gz yuescript-3c4cbff4d88892f153b70ccbbc69d1087ecbcc49.tar.bz2 yuescript-3c4cbff4d88892f153b70ccbbc69d1087ecbcc49.zip |
add yue.format() function. fix yue ast to code function issues.
Diffstat (limited to 'src')
-rw-r--r-- | src/yue_wasm.cpp | 2 | ||||
-rw-r--r-- | src/yuescript/yue_ast.cpp | 260 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 2 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 42 | ||||
-rw-r--r-- | src/yuescript/yue_parser.h | 3 | ||||
-rw-r--r-- | src/yuescript/yuescript.cpp | 43 |
6 files changed, 276 insertions, 76 deletions
diff --git a/src/yue_wasm.cpp b/src/yue_wasm.cpp index 4a054e6..daa5757 100644 --- a/src/yue_wasm.cpp +++ b/src/yue_wasm.cpp | |||
@@ -138,7 +138,7 @@ std::string exec(const std::string& codes) { | |||
138 | }; | 138 | }; |
139 | 139 | ||
140 | execStr(R"yuescript( | 140 | execStr(R"yuescript( |
141 | _G.__output = {} | 141 | _G.__output = [] |
142 | _G.print = (...)-> | 142 | _G.print = (...)-> |
143 | _G.__output[] = table.concat [tostring select i, ... for i = 1, select "#", ...], " " | 143 | _G.__output[] = table.concat [tostring select i, ... for i = 1, select "#", ...], " " |
144 | _G.__output[] = "\n" | 144 | _G.__output[] = "\n" |
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index 6126f71..6b2c96d 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
@@ -230,7 +230,7 @@ std::string LocalValues_t::to_string(void* ud) const { | |||
230 | temp.emplace_back(nameList->to_string(ud)); | 230 | temp.emplace_back(nameList->to_string(ud)); |
231 | if (valueList) { | 231 | if (valueList) { |
232 | if (valueList.is<TableBlock_t>()) { | 232 | if (valueList.is<TableBlock_t>()) { |
233 | temp.emplace_back("="s + valueList->to_string(ud)); | 233 | temp.emplace_back("=\n"s + valueList->to_string(ud)); |
234 | } else { | 234 | } else { |
235 | temp.emplace_back("="s); | 235 | temp.emplace_back("="s); |
236 | temp.emplace_back(valueList->to_string(ud)); | 236 | temp.emplace_back(valueList->to_string(ud)); |
@@ -312,7 +312,10 @@ std::string ShortTabAppending_t::to_string(void* ud) const { | |||
312 | std::string Backcall_t::to_string(void* ud) const { | 312 | std::string Backcall_t::to_string(void* ud) const { |
313 | str_list temp; | 313 | str_list temp; |
314 | if (argsDef) { | 314 | if (argsDef) { |
315 | temp.emplace_back(argsDef->to_string(ud)); | 315 | auto def = argsDef->to_string(ud); |
316 | if (!def.empty()) { | ||
317 | temp.emplace_back(def); | ||
318 | } | ||
316 | } | 319 | } |
317 | temp.emplace_back(arrow->to_string(ud)); | 320 | temp.emplace_back(arrow->to_string(ud)); |
318 | temp.emplace_back(value->to_string(ud)); | 321 | temp.emplace_back(value->to_string(ud)); |
@@ -343,7 +346,7 @@ std::string ExpList_t::to_string(void* ud) const { | |||
343 | std::string Return_t::to_string(void* ud) const { | 346 | std::string Return_t::to_string(void* ud) const { |
344 | str_list temp{"return"s}; | 347 | str_list temp{"return"s}; |
345 | if (valueList) { | 348 | if (valueList) { |
346 | temp.emplace_back(valueList.is<TableBlock_t>() ? ""s : " "s); | 349 | temp.emplace_back(valueList.is<TableBlock_t>() ? "\n"s : " "s); |
347 | temp.emplace_back(valueList->to_string(ud)); | 350 | temp.emplace_back(valueList->to_string(ud)); |
348 | } | 351 | } |
349 | return join(temp); | 352 | return join(temp); |
@@ -365,6 +368,9 @@ std::string With_t::to_string(void* ud) const { | |||
365 | } | 368 | } |
366 | info->pushScope(); | 369 | info->pushScope(); |
367 | auto code = body->to_string(ud); | 370 | auto code = body->to_string(ud); |
371 | if (code.empty()) { | ||
372 | code = info->ind() + "--"s; | ||
373 | } | ||
368 | info->popScope(); | 374 | info->popScope(); |
369 | return line + '\n' + code; | 375 | return line + '\n' + code; |
370 | } | 376 | } |
@@ -383,6 +389,9 @@ std::string SwitchCase_t::to_string(void* ud) const { | |||
383 | } else { | 389 | } else { |
384 | info->pushScope(); | 390 | info->pushScope(); |
385 | auto block = body->to_string(ud); | 391 | auto block = body->to_string(ud); |
392 | if (block.empty()) { | ||
393 | block = info->ind() + "--"s; | ||
394 | } | ||
386 | info->popScope(); | 395 | info->popScope(); |
387 | auto line = "when "s + condition->to_string(ud); | 396 | auto line = "when "s + condition->to_string(ud); |
388 | if (line.find('\n') != std::string::npos) { | 397 | if (line.find('\n') != std::string::npos) { |
@@ -405,6 +414,9 @@ std::string Switch_t::to_string(void* ud) const { | |||
405 | temp.emplace_back(info->ind() + "else"s); | 414 | temp.emplace_back(info->ind() + "else"s); |
406 | info->pushScope(); | 415 | info->pushScope(); |
407 | temp.emplace_back(lastBranch->to_string(ud)); | 416 | temp.emplace_back(lastBranch->to_string(ud)); |
417 | if (temp.back().empty()) { | ||
418 | temp.back() = info->ind() + "--"s; | ||
419 | } | ||
408 | info->popScope(); | 420 | info->popScope(); |
409 | } | 421 | } |
410 | } | 422 | } |
@@ -412,10 +424,18 @@ std::string Switch_t::to_string(void* ud) const { | |||
412 | return join(temp, "\n"sv); | 424 | return join(temp, "\n"sv); |
413 | } | 425 | } |
414 | std::string Assignment_t::to_string(void* ud) const { | 426 | std::string Assignment_t::to_string(void* ud) const { |
415 | return expList->to_string(ud) + ' ' + assign->to_string(ud); | 427 | if (expList) { |
428 | return ", "s + expList->to_string(ud) + " :"s + assign->to_string(ud); | ||
429 | } else { | ||
430 | return " :"s + assign->to_string(ud); | ||
431 | } | ||
416 | } | 432 | } |
417 | std::string IfCond_t::to_string(void* ud) const { | 433 | std::string IfCond_t::to_string(void* ud) const { |
418 | return condition->to_string(ud); | 434 | if (assignment) { |
435 | return condition->to_string(ud) + assignment->to_string(ud); | ||
436 | } else { | ||
437 | return condition->to_string(ud); | ||
438 | } | ||
419 | } | 439 | } |
420 | std::string If_t::to_string(void* ud) const { | 440 | std::string If_t::to_string(void* ud) const { |
421 | auto info = reinterpret_cast<YueFormat*>(ud); | 441 | auto info = reinterpret_cast<YueFormat*>(ud); |
@@ -447,11 +467,17 @@ std::string If_t::to_string(void* ud) const { | |||
447 | if (condition) { | 467 | if (condition) { |
448 | info->pushScope(); | 468 | info->pushScope(); |
449 | temp.emplace_back(node->to_string(ud)); | 469 | temp.emplace_back(node->to_string(ud)); |
470 | if (temp.back().empty()) { | ||
471 | temp.back() = info->ind() + "--"s; | ||
472 | } | ||
450 | info->popScope(); | 473 | info->popScope(); |
451 | } else { | 474 | } else { |
452 | temp.emplace_back(info->ind() + "else"s); | 475 | temp.emplace_back(info->ind() + "else"s); |
453 | info->pushScope(); | 476 | info->pushScope(); |
454 | temp.emplace_back(node->to_string(ud)); | 477 | temp.emplace_back(node->to_string(ud)); |
478 | if (temp.back().empty()) { | ||
479 | temp.back() = info->ind() + "--"s; | ||
480 | } | ||
455 | info->popScope(); | 481 | info->popScope(); |
456 | } | 482 | } |
457 | condition = false; | 483 | condition = false; |
@@ -473,6 +499,9 @@ std::string While_t::to_string(void* ud) const { | |||
473 | } | 499 | } |
474 | info->pushScope(); | 500 | info->pushScope(); |
475 | temp.emplace_back(body->to_string(ud)); | 501 | temp.emplace_back(body->to_string(ud)); |
502 | if (temp.back().empty()) { | ||
503 | temp.back() = info->ind() + "--"s; | ||
504 | } | ||
476 | info->popScope(); | 505 | info->popScope(); |
477 | } | 506 | } |
478 | return join(temp, "\n"sv); | 507 | return join(temp, "\n"sv); |
@@ -486,6 +515,9 @@ std::string Repeat_t::to_string(void* ud) const { | |||
486 | temp.emplace_back("repeat"s); | 515 | temp.emplace_back("repeat"s); |
487 | info->pushScope(); | 516 | info->pushScope(); |
488 | temp.emplace_back(body->to_string(ud)); | 517 | temp.emplace_back(body->to_string(ud)); |
518 | if (temp.back().empty()) { | ||
519 | temp.back() = info->ind() + "--"s; | ||
520 | } | ||
489 | info->popScope(); | 521 | info->popScope(); |
490 | } | 522 | } |
491 | temp.emplace_back(info->ind() + "until "s + condition->to_string(ud)); | 523 | temp.emplace_back(info->ind() + "until "s + condition->to_string(ud)); |
@@ -508,6 +540,9 @@ std::string For_t::to_string(void* ud) const { | |||
508 | } | 540 | } |
509 | info->pushScope(); | 541 | info->pushScope(); |
510 | auto block = body->to_string(ud); | 542 | auto block = body->to_string(ud); |
543 | if (block.empty()) { | ||
544 | block = info->ind() + "--"s; | ||
545 | } | ||
511 | info->popScope(); | 546 | info->popScope(); |
512 | return line + '\n' + block; | 547 | return line + '\n' + block; |
513 | } | 548 | } |
@@ -523,6 +558,9 @@ std::string ForEach_t::to_string(void* ud) const { | |||
523 | } | 558 | } |
524 | info->pushScope(); | 559 | info->pushScope(); |
525 | auto block = body->to_string(ud); | 560 | auto block = body->to_string(ud); |
561 | if (block.empty()) { | ||
562 | block = info->ind() + "--"s; | ||
563 | } | ||
526 | info->popScope(); | 564 | info->popScope(); |
527 | return line + '\n' + block; | 565 | return line + '\n' + block; |
528 | } | 566 | } |
@@ -534,6 +572,9 @@ std::string Do_t::to_string(void* ud) const { | |||
534 | } else { | 572 | } else { |
535 | info->pushScope(); | 573 | info->pushScope(); |
536 | auto block = body->to_string(ud); | 574 | auto block = body->to_string(ud); |
575 | if (block.empty()) { | ||
576 | block = info->ind() + "--"s; | ||
577 | } | ||
537 | info->popScope(); | 578 | info->popScope(); |
538 | return "do\n"s + block; | 579 | return "do\n"s + block; |
539 | } | 580 | } |
@@ -543,6 +584,9 @@ std::string CatchBlock_t::to_string(void* ud) const { | |||
543 | auto line = "catch "s + err->to_string(ud); | 584 | auto line = "catch "s + err->to_string(ud); |
544 | info->pushScope(); | 585 | info->pushScope(); |
545 | auto block = body->to_string(ud); | 586 | auto block = body->to_string(ud); |
587 | if (block.empty()) { | ||
588 | block = info->ind() + "--"s; | ||
589 | } | ||
546 | info->popScope(); | 590 | info->popScope(); |
547 | return line + '\n' + block; | 591 | return line + '\n' + block; |
548 | } | 592 | } |
@@ -555,6 +599,9 @@ std::string Try_t::to_string(void* ud) const { | |||
555 | temp.emplace_back("try"s); | 599 | temp.emplace_back("try"s); |
556 | info->pushScope(); | 600 | info->pushScope(); |
557 | temp.emplace_back(func->to_string(ud)); | 601 | temp.emplace_back(func->to_string(ud)); |
602 | if (temp.back().empty()) { | ||
603 | temp.back() = info->ind() + "--"s; | ||
604 | } | ||
558 | info->popScope(); | 605 | info->popScope(); |
559 | } | 606 | } |
560 | if (catchBlock) { | 607 | if (catchBlock) { |
@@ -571,7 +618,11 @@ std::string Comprehension_t::to_string(void* ud) const { | |||
571 | temp.front().insert(0, temp.front()[0] == '[' ? " "s : ""s); | 618 | temp.front().insert(0, temp.front()[0] == '[' ? " "s : ""s); |
572 | } | 619 | } |
573 | if (items.size() != 2 || !ast_is<CompInner_t>(items.back())) { | 620 | if (items.size() != 2 || !ast_is<CompInner_t>(items.back())) { |
574 | return '[' + join(temp, ", "sv) + ']'; | 621 | if (items.size() == 1) { |
622 | return '[' + join(temp, ", "sv) + ",]"s; | ||
623 | } else { | ||
624 | return '[' + join(temp, ", "sv) + ']'; | ||
625 | } | ||
575 | } else { | 626 | } else { |
576 | return '[' + join(temp, " "sv) + ']'; | 627 | return '[' + join(temp, " "sv) + ']'; |
577 | } | 628 | } |
@@ -613,7 +664,7 @@ std::string CompInner_t::to_string(void* ud) const { | |||
613 | std::string Assign_t::to_string(void* ud) const { | 664 | std::string Assign_t::to_string(void* ud) const { |
614 | str_list temp; | 665 | str_list temp; |
615 | if (values.size() == 1 && ast_is<TableBlock_t>(values.front())) { | 666 | if (values.size() == 1 && ast_is<TableBlock_t>(values.front())) { |
616 | return '=' + values.front()->to_string(ud); | 667 | return "=\n"s + values.front()->to_string(ud); |
617 | } | 668 | } |
618 | for (auto value : values.objects()) { | 669 | for (auto value : values.objects()) { |
619 | temp.emplace_back(value->to_string(ud)); | 670 | temp.emplace_back(value->to_string(ud)); |
@@ -790,7 +841,13 @@ static bool isInBlockExp(ast_node* node) { | |||
790 | TblComprehension_t, Comprehension_t>(simpleValue->value)) { | 841 | TblComprehension_t, Comprehension_t>(simpleValue->value)) { |
791 | return true; | 842 | return true; |
792 | } | 843 | } |
844 | } else if (auto chainValue = value->item.as<ChainValue_t>()) { | ||
845 | if (ast_is<InvokeArgs_t>(chainValue->items.back())) { | ||
846 | return true; | ||
847 | } | ||
793 | } | 848 | } |
849 | } else if (ast_is<TableBlock_t>(node)) { | ||
850 | return true; | ||
794 | } | 851 | } |
795 | return false; | 852 | return false; |
796 | } | 853 | } |
@@ -863,7 +920,7 @@ std::string TableBlock_t::to_string(void* ud) const { | |||
863 | temp.emplace_back(info->ind() + "* "s + value->to_string(ud)); | 920 | temp.emplace_back(info->ind() + "* "s + value->to_string(ud)); |
864 | break; | 921 | break; |
865 | case id<TableBlock_t>(): | 922 | case id<TableBlock_t>(): |
866 | temp.emplace_back(info->ind() + "*"s + value->to_string(ud)); | 923 | temp.emplace_back(info->ind() + "*\n"s + value->to_string(ud)); |
867 | break; | 924 | break; |
868 | default: | 925 | default: |
869 | temp.emplace_back(info->ind() + value->to_string(ud)); | 926 | temp.emplace_back(info->ind() + value->to_string(ud)); |
@@ -871,21 +928,25 @@ std::string TableBlock_t::to_string(void* ud) const { | |||
871 | } | 928 | } |
872 | } | 929 | } |
873 | info->popScope(); | 930 | info->popScope(); |
874 | return '\n' + join(temp, "\n"sv); | 931 | return join(temp, "\n"sv); |
875 | } | 932 | } |
876 | std::string TableBlockIndent_t::to_string(void* ud) const { | 933 | std::string TableBlockIndent_t::to_string(void* ud) const { |
877 | auto info = reinterpret_cast<YueFormat*>(ud); | 934 | auto info = reinterpret_cast<YueFormat*>(ud); |
878 | str_list temp; | 935 | str_list temp; |
879 | info->pushScope(); | 936 | info->pushScope(); |
880 | for (auto value : values.objects()) { | 937 | for (auto value : values.objects()) { |
881 | if (value == values.front()) { | 938 | if (ast_is<TableBlockIndent_t>(value)) { |
882 | temp.emplace_back("* "s + value->to_string(ud)); | 939 | temp.emplace_back("\n"s + value->to_string(ud)); |
883 | } else { | 940 | } else { |
884 | temp.emplace_back(info->ind() + value->to_string(ud)); | 941 | if (value == values.front()) { |
942 | temp.emplace_back(" "s + value->to_string(ud)); | ||
943 | } else { | ||
944 | temp.emplace_back(info->ind() + value->to_string(ud)); | ||
945 | } | ||
885 | } | 946 | } |
886 | } | 947 | } |
887 | info->popScope(); | 948 | info->popScope(); |
888 | return join(temp, "\n"sv); | 949 | return "*"s + join(temp, "\n"sv); |
889 | } | 950 | } |
890 | std::string ClassMemberList_t::to_string(void* ud) const { | 951 | std::string ClassMemberList_t::to_string(void* ud) const { |
891 | auto info = reinterpret_cast<YueFormat*>(ud); | 952 | auto info = reinterpret_cast<YueFormat*>(ud); |
@@ -893,7 +954,7 @@ std::string ClassMemberList_t::to_string(void* ud) const { | |||
893 | for (auto value : values.objects()) { | 954 | for (auto value : values.objects()) { |
894 | temp.emplace_back(info->ind() + value->to_string(ud)); | 955 | temp.emplace_back(info->ind() + value->to_string(ud)); |
895 | } | 956 | } |
896 | return join(temp, "\n"sv); | 957 | return join(temp, ", "sv); |
897 | } | 958 | } |
898 | std::string ClassBlock_t::to_string(void* ud) const { | 959 | std::string ClassBlock_t::to_string(void* ud) const { |
899 | auto info = reinterpret_cast<YueFormat*>(ud); | 960 | auto info = reinterpret_cast<YueFormat*>(ud); |
@@ -929,7 +990,7 @@ std::string GlobalValues_t::to_string(void* ud) const { | |||
929 | auto line = nameList->to_string(ud); | 990 | auto line = nameList->to_string(ud); |
930 | if (valueList) { | 991 | if (valueList) { |
931 | if (valueList.is<TableBlock_t>()) { | 992 | if (valueList.is<TableBlock_t>()) { |
932 | line += " ="s + valueList->to_string(ud); | 993 | line += " =\n"s + valueList->to_string(ud); |
933 | } else { | 994 | } else { |
934 | line += " = "s + valueList->to_string(ud); | 995 | line += " = "s + valueList->to_string(ud); |
935 | } | 996 | } |
@@ -949,8 +1010,12 @@ std::string Export_t::to_string(void* ud) const { | |||
949 | line += target->to_string(ud); | 1010 | line += target->to_string(ud); |
950 | break; | 1011 | break; |
951 | case id<Exp_t>(): { | 1012 | case id<Exp_t>(): { |
952 | auto valueStr = target->to_string(ud); | 1013 | if (def) { |
953 | line += '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']'; | 1014 | line += target->to_string(ud); |
1015 | } else { | ||
1016 | auto valueStr = target->to_string(ud); | ||
1017 | line += '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']'; | ||
1018 | } | ||
954 | break; | 1019 | break; |
955 | } | 1020 | } |
956 | default: | 1021 | default: |
@@ -973,7 +1038,7 @@ std::string NormalPair_t::to_string(void* ud) const { | |||
973 | } else { | 1038 | } else { |
974 | line = key->to_string(ud) + ":"s; | 1039 | line = key->to_string(ud) + ":"s; |
975 | } | 1040 | } |
976 | line += (value.is<TableBlock_t>() ? ""s : " "s) + value->to_string(ud); | 1041 | line += (value.is<TableBlock_t>() ? "\n"s : " "s) + value->to_string(ud); |
977 | return line; | 1042 | return line; |
978 | } | 1043 | } |
979 | std::string MetaVariablePair_t::to_string(void* ud) const { | 1044 | std::string MetaVariablePair_t::to_string(void* ud) const { |
@@ -989,7 +1054,7 @@ std::string MetaNormalPair_t::to_string(void* ud) const { | |||
989 | } else { | 1054 | } else { |
990 | line = '<' + key->to_string(ud) + ">:"s; | 1055 | line = '<' + key->to_string(ud) + ">:"s; |
991 | } | 1056 | } |
992 | line += (value.is<TableBlock_t>() ? ""s : " "s) + value->to_string(ud); | 1057 | line += (value.is<TableBlock_t>() ? "\n"s : " "s) + value->to_string(ud); |
993 | return line; | 1058 | return line; |
994 | } | 1059 | } |
995 | std::string VariablePairDef_t::to_string(void* ud) const { | 1060 | std::string VariablePairDef_t::to_string(void* ud) const { |
@@ -1033,23 +1098,38 @@ std::string FnArgDef_t::to_string(void* ud) const { | |||
1033 | line += op->to_string(ud); | 1098 | line += op->to_string(ud); |
1034 | } | 1099 | } |
1035 | if (defaultValue) { | 1100 | if (defaultValue) { |
1036 | if (isInBlockExp(defaultValue)) { | 1101 | line += " = "s + defaultValue->to_string(ud); |
1037 | line += " = ("s + defaultValue->to_string(ud) + ')'; | ||
1038 | } else { | ||
1039 | line += " = "s + defaultValue->to_string(ud); | ||
1040 | } | ||
1041 | } | 1102 | } |
1042 | return line; | 1103 | return line; |
1043 | } | 1104 | } |
1044 | std::string FnArgDefList_t::to_string(void* ud) const { | 1105 | std::string FnArgDefList_t::to_string(void* ud) const { |
1106 | auto info = reinterpret_cast<YueFormat*>(ud); | ||
1045 | str_list temp; | 1107 | str_list temp; |
1108 | bool hasInBlockExp = false; | ||
1046 | for (auto def : definitions.objects()) { | 1109 | for (auto def : definitions.objects()) { |
1047 | temp.emplace_back(def->to_string(ud)); | 1110 | auto argDef = static_cast<FnArgDef_t*>(def); |
1111 | if (argDef->defaultValue && isInBlockExp(argDef->defaultValue)) { | ||
1112 | hasInBlockExp = true; | ||
1113 | break; | ||
1114 | } | ||
1048 | } | 1115 | } |
1049 | if (varArg) { | 1116 | if (hasInBlockExp) { |
1050 | temp.emplace_back(varArg->to_string(ud)); | 1117 | for (auto def : definitions.objects()) { |
1118 | temp.emplace_back(info->ind() + def->to_string(ud)); | ||
1119 | } | ||
1120 | if (varArg) { | ||
1121 | temp.emplace_back(info->ind() + varArg->to_string(ud)); | ||
1122 | } | ||
1123 | return join(temp, "\n"sv); | ||
1124 | } else { | ||
1125 | for (auto def : definitions.objects()) { | ||
1126 | temp.emplace_back(def->to_string(ud)); | ||
1127 | } | ||
1128 | if (varArg) { | ||
1129 | temp.emplace_back(varArg->to_string(ud)); | ||
1130 | } | ||
1131 | return join(temp, ", "sv); | ||
1051 | } | 1132 | } |
1052 | return join(temp, ", "sv); | ||
1053 | } | 1133 | } |
1054 | std::string OuterVarShadow_t::to_string(void* ud) const { | 1134 | std::string OuterVarShadow_t::to_string(void* ud) const { |
1055 | if (varList) { | 1135 | if (varList) { |
@@ -1059,14 +1139,38 @@ std::string OuterVarShadow_t::to_string(void* ud) const { | |||
1059 | } | 1139 | } |
1060 | } | 1140 | } |
1061 | std::string FnArgsDef_t::to_string(void* ud) const { | 1141 | std::string FnArgsDef_t::to_string(void* ud) const { |
1062 | std::string line; | 1142 | auto info = reinterpret_cast<YueFormat*>(ud); |
1143 | bool hasInBlockExp = false; | ||
1063 | if (defList) { | 1144 | if (defList) { |
1064 | line += defList->to_string(ud); | 1145 | for (auto def : defList->definitions.objects()) { |
1146 | auto argDef = static_cast<FnArgDef_t*>(def); | ||
1147 | if (argDef->defaultValue && isInBlockExp(argDef->defaultValue)) { | ||
1148 | hasInBlockExp = true; | ||
1149 | break; | ||
1150 | } | ||
1151 | } | ||
1065 | } | 1152 | } |
1066 | if (shadowOption) { | 1153 | if (hasInBlockExp) { |
1067 | line += (line.empty() ? ""s : " "s) + shadowOption->to_string(ud); | 1154 | str_list temp; |
1155 | info->pushScope(); | ||
1156 | if (defList) { | ||
1157 | temp.push_back(defList->to_string(ud)); | ||
1158 | } | ||
1159 | if (shadowOption) { | ||
1160 | temp.push_back(info->ind() + shadowOption->to_string(ud)); | ||
1161 | } | ||
1162 | info->popScope(); | ||
1163 | return "(\n" + join(temp, "\n"sv) + '\n' + info->ind() + ')'; | ||
1164 | } else { | ||
1165 | std::string line; | ||
1166 | if (defList) { | ||
1167 | line += defList->to_string(ud); | ||
1168 | } | ||
1169 | if (shadowOption) { | ||
1170 | line += (line.empty() ? ""s : " "s) + shadowOption->to_string(ud); | ||
1171 | } | ||
1172 | return line.empty() ? (defList ? "()"s : ""s) : '(' + line + ')'; | ||
1068 | } | 1173 | } |
1069 | return line.empty() ? ""s : '(' + line + ')'; | ||
1070 | } | 1174 | } |
1071 | std::string FunLit_t::to_string(void* ud) const { | 1175 | std::string FunLit_t::to_string(void* ud) const { |
1072 | auto info = reinterpret_cast<YueFormat*>(ud); | 1176 | auto info = reinterpret_cast<YueFormat*>(ud); |
@@ -1080,7 +1184,11 @@ std::string FunLit_t::to_string(void* ud) const { | |||
1080 | line += ' ' + body->to_string(ud); | 1184 | line += ' ' + body->to_string(ud); |
1081 | } else { | 1185 | } else { |
1082 | info->pushScope(); | 1186 | info->pushScope(); |
1083 | line += '\n' + body->to_string(ud); | 1187 | auto bodyStr = body->to_string(ud); |
1188 | if (bodyStr.empty()) { | ||
1189 | bodyStr = info->ind() + "--"s; | ||
1190 | } | ||
1191 | line += '\n' + bodyStr; | ||
1084 | info->popScope(); | 1192 | info->popScope(); |
1085 | } | 1193 | } |
1086 | } | 1194 | } |
@@ -1096,14 +1204,16 @@ std::string MacroLit_t::to_string(void* ud) const { | |||
1096 | line = '(' + argsDef->to_string(ud) + ')'; | 1204 | line = '(' + argsDef->to_string(ud) + ')'; |
1097 | } | 1205 | } |
1098 | line += "->"s; | 1206 | line += "->"s; |
1099 | if (body) { | 1207 | if (body->content.is<Statement_t>()) { |
1100 | if (body->content.is<Statement_t>()) { | 1208 | line += ' ' + body->to_string(ud); |
1101 | line += ' ' + body->to_string(ud); | 1209 | } else { |
1102 | } else { | 1210 | info->pushScope(); |
1103 | info->pushScope(); | 1211 | auto bodyStr = body->to_string(ud); |
1104 | line += '\n' + body->to_string(ud); | 1212 | if (bodyStr.empty()) { |
1105 | info->popScope(); | 1213 | bodyStr = info->ind() + "--"s; |
1106 | } | 1214 | } |
1215 | line += '\n' + bodyStr; | ||
1216 | info->popScope(); | ||
1107 | } | 1217 | } |
1108 | return line; | 1218 | return line; |
1109 | } | 1219 | } |
@@ -1113,14 +1223,16 @@ std::string Macro_t::to_string(void* ud) const { | |||
1113 | std::string MacroInPlace_t::to_string(void* ud) const { | 1223 | std::string MacroInPlace_t::to_string(void* ud) const { |
1114 | auto info = reinterpret_cast<YueFormat*>(ud); | 1224 | auto info = reinterpret_cast<YueFormat*>(ud); |
1115 | auto line = "$->"s; | 1225 | auto line = "$->"s; |
1116 | if (body) { | 1226 | if (body->content.is<Statement_t>()) { |
1117 | if (body->content.is<Statement_t>()) { | 1227 | line += ' ' + body->to_string(ud); |
1118 | line += ' ' + body->to_string(ud); | 1228 | } else { |
1119 | } else { | 1229 | info->pushScope(); |
1120 | info->pushScope(); | 1230 | auto bodyStr = body->to_string(ud); |
1121 | line += '\n' + body->to_string(ud); | 1231 | if (bodyStr.empty()) { |
1122 | info->popScope(); | 1232 | bodyStr = info->ind() + "--"s; |
1123 | } | 1233 | } |
1234 | line += '\n' + bodyStr; | ||
1235 | info->popScope(); | ||
1124 | } | 1236 | } |
1125 | return line; | 1237 | return line; |
1126 | } | 1238 | } |
@@ -1135,15 +1247,32 @@ std::string AssignableNameList_t::to_string(void* ud) const { | |||
1135 | return join(temp, ", "sv); | 1247 | return join(temp, ", "sv); |
1136 | } | 1248 | } |
1137 | std::string InvokeArgs_t::to_string(void* ud) const { | 1249 | std::string InvokeArgs_t::to_string(void* ud) const { |
1138 | if (!args.empty() && ast_is<TableBlock_t>(args.back())) { | 1250 | auto info = reinterpret_cast<YueFormat*>(ud); |
1251 | bool hasInBlockExp = false; | ||
1252 | for (auto arg : args.objects()) { | ||
1253 | if (isInBlockExp(arg)) { | ||
1254 | hasInBlockExp = true; | ||
1255 | break; | ||
1256 | } | ||
1257 | } | ||
1258 | if (hasInBlockExp) { | ||
1139 | str_list temp; | 1259 | str_list temp; |
1260 | bool newLine = false; | ||
1140 | for (auto arg : args.objects()) { | 1261 | for (auto arg : args.objects()) { |
1141 | if (arg != args.back()) { | 1262 | if (arg == args.front()) { |
1142 | temp.emplace_back(arg->to_string(ud)); | 1263 | if (ast_is<TableBlock_t>(arg)) { |
1264 | newLine = true; | ||
1265 | } | ||
1266 | temp.push_back(arg->to_string(ud)); | ||
1267 | info->pushScope(); | ||
1268 | } else if (ast_is<TableBlock_t>(arg)) { | ||
1269 | temp.push_back(arg->to_string(ud)); | ||
1270 | } else { | ||
1271 | temp.push_back(info->ind() + arg->to_string(ud)); | ||
1143 | } | 1272 | } |
1144 | } | 1273 | } |
1145 | auto list = join(temp, ", "sv); | 1274 | info->popScope(); |
1146 | return ' ' + list + (list.empty() ? ""s : ","s) + args.back()->to_string(ud); | 1275 | return (newLine ? '\n' : ' ') + join(temp, ",\n"sv); |
1147 | } else { | 1276 | } else { |
1148 | str_list temp; | 1277 | str_list temp; |
1149 | for (auto arg : args.objects()) { | 1278 | for (auto arg : args.objects()) { |
@@ -1203,10 +1332,29 @@ std::string StatementAppendix_t::to_string(void* ud) const { | |||
1203 | } | 1332 | } |
1204 | std::string Statement_t::to_string(void* ud) const { | 1333 | std::string Statement_t::to_string(void* ud) const { |
1205 | std::string line; | 1334 | std::string line; |
1206 | if (appendix) { | 1335 | if (!comments.empty()) { |
1207 | return content->to_string(ud) + ' ' + appendix->to_string(ud); | 1336 | auto info = reinterpret_cast<YueFormat*>(ud); |
1337 | str_list temp; | ||
1338 | for (ast_node* comment : comments.objects()) { | ||
1339 | if (comment == comments.front()) { | ||
1340 | temp.push_back(comment->to_string(ud)); | ||
1341 | } else { | ||
1342 | temp.push_back(info->ind() + comment->to_string(ud)); | ||
1343 | } | ||
1344 | } | ||
1345 | if (appendix) { | ||
1346 | temp.push_back(info->ind() + content->to_string(ud) + ' ' + appendix->to_string(ud)); | ||
1347 | return join(temp, "\n"sv); | ||
1348 | } else { | ||
1349 | temp.push_back(info->ind() + content->to_string(ud)); | ||
1350 | return join(temp, "\n"sv); | ||
1351 | } | ||
1208 | } else { | 1352 | } else { |
1209 | return content->to_string(ud); | 1353 | if (appendix) { |
1354 | return content->to_string(ud) + ' ' + appendix->to_string(ud); | ||
1355 | } else { | ||
1356 | return content->to_string(ud); | ||
1357 | } | ||
1210 | } | 1358 | } |
1211 | } | 1359 | } |
1212 | std::string StatementSep_t::to_string(void*) const { | 1360 | std::string StatementSep_t::to_string(void*) const { |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 3e60556..59f6d4b 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
75 | "close"s // Lua 5.4 | 75 | "close"s // Lua 5.4 |
76 | }; | 76 | }; |
77 | 77 | ||
78 | const std::string_view version = "0.21.1"sv; | 78 | const std::string_view version = "0.21.2"sv; |
79 | const std::string_view extension = "yue"sv; | 79 | const std::string_view extension = "yue"sv; |
80 | 80 | ||
81 | class CompileError : public std::logic_error { | 81 | class CompileError : public std::logic_error { |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 4b865f5..89791d6 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -477,7 +477,7 @@ YueParser::YueParser() { | |||
477 | space | 477 | space |
478 | ); | 478 | ); |
479 | 479 | ||
480 | list_lit_lines = space_break >> list_lit_line >> *(-(space >> ',') >> space_break >> list_lit_line) >> -(space >> ','); | 480 | list_lit_lines = +space_break >> list_lit_line >> *(-(space >> ',') >> space_break >> list_lit_line) >> -(space >> ','); |
481 | 481 | ||
482 | Comprehension = '[' >> not_('[') >> | 482 | Comprehension = '[' >> not_('[') >> |
483 | Seperator >> space >> ( | 483 | Seperator >> space >> ( |
@@ -489,7 +489,6 @@ YueParser::YueParser() { | |||
489 | white >> ']' >> not_(space >> '=') | 489 | white >> ']' >> not_(space >> '=') |
490 | ); | 490 | ); |
491 | 491 | ||
492 | (space >> disable_for_rule(Exp) >> space >> CompInner >> space >> ']'); | ||
493 | CompValue = ',' >> space >> Exp; | 492 | CompValue = ',' >> space >> Exp; |
494 | TblComprehension = and_('{') >> ('{' >> space >> disable_for_rule(Exp >> space >> -(CompValue >> space)) >> CompInner >> space >> '}' | braces_expression_error); | 493 | TblComprehension = and_('{') >> ('{' >> space >> disable_for_rule(Exp >> space >> -(CompValue >> space)) >> CompInner >> space >> '}' | braces_expression_error); |
495 | 494 | ||
@@ -829,17 +828,26 @@ YueParser::YueParser() { | |||
829 | '*' >> space >> (SpreadExp | Exp | TableBlock) | 828 | '*' >> space >> (SpreadExp | Exp | TableBlock) |
830 | ); | 829 | ); |
831 | 830 | ||
831 | fn_arg_def_list = FnArgDef >> *(space >> ',' >> space >> FnArgDef); | ||
832 | |||
833 | fn_arg_def_lit_line = ( | ||
834 | push_indent_match >> (space >> fn_arg_def_list >> pop_indent | pop_indent) | ||
835 | ) | ( | ||
836 | space | ||
837 | ); | ||
838 | |||
839 | fn_arg_def_lit_lines = fn_arg_def_lit_line >> *(-(space >> ',') >> space_break >> fn_arg_def_lit_line); | ||
840 | |||
832 | FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '=' >> space >> Exp); | 841 | FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '=' >> space >> Exp); |
833 | 842 | ||
834 | FnArgDefList = Seperator >> (( | 843 | FnArgDefList = Seperator >> ( |
835 | FnArgDef >> | 844 | fn_arg_def_lit_lines >> -(-(space >> ',') >> white >> VarArg) | |
836 | *(space >> (',' | line_break) >> white >> FnArgDef) >> | 845 | white >> VarArg |
837 | -(space >> (',' | line_break) >> white >> VarArg) | 846 | ); |
838 | ) | VarArg); | ||
839 | 847 | ||
840 | OuterVarShadow = key("using") >> space >> (NameList | key("nil")); | 848 | OuterVarShadow = key("using") >> space >> (NameList | key("nil")); |
841 | 849 | ||
842 | FnArgsDef = '(' >> white >> -FnArgDefList >> -(space >> OuterVarShadow) >> white >> ')'; | 850 | FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> ')'; |
843 | FnArrow = expr("->") | "=>"; | 851 | FnArrow = expr("->") | "=>"; |
844 | FunLit = -FnArgsDef >> space >> FnArrow >> -(space >> Body); | 852 | FunLit = -FnArgsDef >> space >> FnArrow >> -(space >> Body); |
845 | 853 | ||
@@ -873,8 +881,8 @@ YueParser::YueParser() { | |||
873 | 881 | ||
874 | invoke_args_with_table = | 882 | invoke_args_with_table = |
875 | ',' >> ( | 883 | ',' >> ( |
876 | TableBlock | | 884 | arg_table_block | |
877 | space_break >> advance_match >> arg_block >> -arg_table_block | 885 | space_break >> advance_match >> arg_block >> -(-(space >> ',') >> arg_table_block) |
878 | ) | arg_table_block; | 886 | ) | arg_table_block; |
879 | 887 | ||
880 | leading_spaces_error = pl::user(+space_one >> '(' >> space >> Exp >> +(space >> ',' >> space >> Exp) >> space >> ')', [](const item_t& item) { | 888 | leading_spaces_error = pl::user(+space_one >> '(' >> space >> Exp >> +(space >> ',' >> space >> Exp) >> space >> ')', [](const item_t& item) { |
@@ -954,11 +962,10 @@ YueParser::YueParser() { | |||
954 | 962 | ||
955 | Body = in_block | Statement; | 963 | Body = in_block | Statement; |
956 | 964 | ||
957 | empty_line_break = ( | 965 | empty_line_break = |
958 | check_indent >> (multi_line_comment >> space | comment) | | 966 | check_indent >> (multi_line_comment >> space | comment) >> and_(stop) | |
959 | advance >> ensure(multi_line_comment >> space | comment, pop_indent) | | 967 | advance >> ensure(multi_line_comment >> space | comment, pop_indent) >> and_(stop) | |
960 | plain_space | 968 | plain_space >> and_(line_break); |
961 | ) >> and_(stop); | ||
962 | 969 | ||
963 | indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) { | 970 | indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) { |
964 | throw ParserError("unexpected indent"sv, item.begin); | 971 | throw ParserError("unexpected indent"sv, item.begin); |
@@ -1084,6 +1091,11 @@ void trim(std::string& str) { | |||
1084 | } // namespace Utils | 1091 | } // namespace Utils |
1085 | 1092 | ||
1086 | std::string ParseInfo::errorMessage(std::string_view msg, int errLine, int errCol, int lineOffset) const { | 1093 | std::string ParseInfo::errorMessage(std::string_view msg, int errLine, int errCol, int lineOffset) const { |
1094 | if (!codes) { | ||
1095 | std::ostringstream buf; | ||
1096 | buf << errLine + lineOffset << ": "sv << msg; | ||
1097 | return buf.str(); | ||
1098 | } | ||
1087 | const int ASCII = 255; | 1099 | const int ASCII = 255; |
1088 | int length = errLine; | 1100 | int length = errLine; |
1089 | auto begin = codes->begin(); | 1101 | auto begin = codes->begin(); |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index c3d5d7d..e183bf2 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
@@ -222,6 +222,9 @@ private: | |||
222 | NONE_AST_RULE(fn_args_lit_line); | 222 | NONE_AST_RULE(fn_args_lit_line); |
223 | NONE_AST_RULE(fn_args_lit_lines); | 223 | NONE_AST_RULE(fn_args_lit_lines); |
224 | NONE_AST_RULE(fn_args); | 224 | NONE_AST_RULE(fn_args); |
225 | NONE_AST_RULE(fn_arg_def_list); | ||
226 | NONE_AST_RULE(fn_arg_def_lit_line); | ||
227 | NONE_AST_RULE(fn_arg_def_lit_lines); | ||
225 | NONE_AST_RULE(destruct_def); | 228 | NONE_AST_RULE(destruct_def); |
226 | NONE_AST_RULE(macro_args_def); | 229 | NONE_AST_RULE(macro_args_def); |
227 | NONE_AST_RULE(chain_call); | 230 | NONE_AST_RULE(chain_call); |
diff --git a/src/yuescript/yuescript.cpp b/src/yuescript/yuescript.cpp index 856d8f3..dbaa287 100644 --- a/src/yuescript/yuescript.cpp +++ b/src/yuescript/yuescript.cpp | |||
@@ -172,6 +172,39 @@ static int yuetolua(lua_State* L) { | |||
172 | return 3; | 172 | return 3; |
173 | } | 173 | } |
174 | 174 | ||
175 | static int yueformat(lua_State* L) { | ||
176 | size_t len = 0; | ||
177 | auto input = luaL_checklstring(L, 1, &len); | ||
178 | int tabSize = 0; | ||
179 | if (!lua_isnoneornil(L, 2)) { | ||
180 | tabSize = static_cast<int>(luaL_checkinteger(L, 2)); | ||
181 | } | ||
182 | std::string_view codes(input, len); | ||
183 | auto info = yue::YueParser{}.parse<yue::File_t>(codes); | ||
184 | if (info.error) { | ||
185 | const auto& error = info.error.value(); | ||
186 | if (!info.codes) { | ||
187 | lua_pushnil(L); | ||
188 | lua_pushlstring(L, error.msg.c_str(), error.msg.size()); | ||
189 | return 2; | ||
190 | } | ||
191 | auto displayMessage = info.errorMessage(error.msg, error.line, error.col, 0); | ||
192 | lua_pushnil(L); | ||
193 | lua_pushlstring(L, displayMessage.c_str(), displayMessage.size()); | ||
194 | return 2; | ||
195 | } | ||
196 | yue::YueFormat formatter{}; | ||
197 | if (tabSize > 0) { | ||
198 | formatter.spaceOverTab = true; | ||
199 | formatter.tabSpaces = tabSize; | ||
200 | } else { | ||
201 | formatter.spaceOverTab = false; | ||
202 | } | ||
203 | auto result = formatter.toString(info.node.get()); | ||
204 | lua_pushlstring(L, result.c_str(), result.size()); | ||
205 | return 1; | ||
206 | } | ||
207 | |||
175 | static int yuecheck(lua_State* L) { | 208 | static int yuecheck(lua_State* L) { |
176 | size_t len = 0; | 209 | size_t len = 0; |
177 | auto input = luaL_checklstring(L, 1, &len); | 210 | auto input = luaL_checklstring(L, 1, &len); |
@@ -268,6 +301,7 @@ static int yuetoast(lua_State* L) { | |||
268 | stack.pop(); | 301 | stack.pop(); |
269 | }; | 302 | }; |
270 | do_call(info.node); | 303 | do_call(info.node); |
304 | yue::YueFormat formatter{}; | ||
271 | while (!stack.empty()) { | 305 | while (!stack.empty()) { |
272 | auto& current = stack.top(); | 306 | auto& current = stack.top(); |
273 | int continuation = current.continuation; | 307 | int continuation = current.continuation; |
@@ -319,7 +353,8 @@ static int yuetoast(lua_State* L) { | |||
319 | lua_rawseti(L, -2, 2); | 353 | lua_rawseti(L, -2, 2); |
320 | lua_pushinteger(L, node->m_begin.m_col); | 354 | lua_pushinteger(L, node->m_begin.m_col); |
321 | lua_rawseti(L, -2, 3); | 355 | lua_rawseti(L, -2, 3); |
322 | auto str = parser.toString(node); | 356 | formatter.indent = 0; |
357 | auto str = node->to_string(&formatter); | ||
323 | yue::Utils::trim(str); | 358 | yue::Utils::trim(str); |
324 | lua_pushlstring(L, str.c_str(), str.length()); | 359 | lua_pushlstring(L, str.c_str(), str.length()); |
325 | lua_rawseti(L, -2, 4); | 360 | lua_rawseti(L, -2, 4); |
@@ -371,8 +406,9 @@ static int yuetoast(lua_State* L) { | |||
371 | return 1; | 406 | return 1; |
372 | } else { | 407 | } else { |
373 | lua_pushnil(L); | 408 | lua_pushnil(L); |
374 | const auto& msg = info.error.value().msg; | 409 | const auto& err = info.error.value(); |
375 | lua_pushlstring(L, msg.c_str(), msg.length()); | 410 | auto displayMessage = info.errorMessage(err.msg, err.line, err.col); |
411 | lua_pushlstring(L, displayMessage.c_str(), displayMessage.length()); | ||
376 | return 2; | 412 | return 2; |
377 | } | 413 | } |
378 | } | 414 | } |
@@ -381,6 +417,7 @@ static const luaL_Reg yuelib[] = { | |||
381 | {"to_lua", yuetolua}, | 417 | {"to_lua", yuetolua}, |
382 | {"to_ast", yuetoast}, | 418 | {"to_ast", yuetoast}, |
383 | {"check", yuecheck}, | 419 | {"check", yuecheck}, |
420 | {"format", yueformat}, | ||
384 | {"version", nullptr}, | 421 | {"version", nullptr}, |
385 | {"options", nullptr}, | 422 | {"options", nullptr}, |
386 | {"load_stacktraceplus", nullptr}, | 423 | {"load_stacktraceplus", nullptr}, |