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 | |
| 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 '')
| -rw-r--r-- | spec/inputs/test/format_spec.yue | 126 | ||||
| -rw-r--r-- | spec/outputs/test/format_spec.lua | 133 | ||||
| -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 |
8 files changed, 535 insertions, 76 deletions
diff --git a/spec/inputs/test/format_spec.yue b/spec/inputs/test/format_spec.yue new file mode 100644 index 0000000..5076445 --- /dev/null +++ b/spec/inputs/test/format_spec.yue | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | files = [ | ||
| 2 | "spec/inputs/macro_export.yue" | ||
| 3 | "spec/inputs/attrib.yue" | ||
| 4 | "spec/inputs/macro.yue" | ||
| 5 | "spec/inputs/using.yue" | ||
| 6 | "spec/inputs/whitespace.yue" | ||
| 7 | "spec/inputs/nil_coalescing.yue" | ||
| 8 | "spec/inputs/stub.yue" | ||
| 9 | "spec/inputs/pipe.yue" | ||
| 10 | "spec/inputs/teal_lang.yue" | ||
| 11 | "spec/inputs/string.yue" | ||
| 12 | "spec/inputs/local.yue" | ||
| 13 | "spec/inputs/tables.yue" | ||
| 14 | "spec/inputs/operators.yue" | ||
| 15 | "spec/inputs/lists.yue" | ||
| 16 | "spec/inputs/compile_doc.yue" | ||
| 17 | "spec/inputs/switch.yue" | ||
| 18 | "spec/inputs/multiline_chain.yue" | ||
| 19 | "spec/inputs/existential.yue" | ||
| 20 | "spec/inputs/export_default.yue" | ||
| 21 | "spec/inputs/assign.yue" | ||
| 22 | "spec/inputs/literals.yue" | ||
| 23 | "spec/inputs/luarocks_upload.yue" | ||
| 24 | "spec/inputs/ambiguous.yue" | ||
| 25 | "spec/inputs/bubbling.yue" | ||
| 26 | "spec/inputs/try_catch.yue" | ||
| 27 | "spec/inputs/funcs.yue" | ||
| 28 | "spec/inputs/do.yue" | ||
| 29 | "spec/inputs/with.yue" | ||
| 30 | "spec/inputs/export.yue" | ||
| 31 | "spec/inputs/macro_todo.yue" | ||
| 32 | "spec/inputs/backcall.yue" | ||
| 33 | "spec/inputs/cond.yue" | ||
| 34 | "spec/inputs/in_expression.yue" | ||
| 35 | "spec/inputs/comprehension.yue" | ||
| 36 | "spec/inputs/macro_teal.yue" | ||
| 37 | "spec/inputs/import.yue" | ||
| 38 | "spec/inputs/unless_else.yue" | ||
| 39 | "spec/inputs/destructure.yue" | ||
| 40 | "spec/inputs/return.yue" | ||
| 41 | "spec/inputs/loops.yue" | ||
| 42 | "spec/inputs/class.yue" | ||
| 43 | "spec/inputs/vararg.yue" | ||
| 44 | "spec/inputs/goto.yue" | ||
| 45 | "spec/inputs/metatable.yue" | ||
| 46 | "spec/inputs/syntax.yue" | ||
| 47 | "spec/inputs/global.yue" | ||
| 48 | "spec/inputs/plus.yue" | ||
| 49 | "spec/inputs/test/class_spec.yue" | ||
| 50 | "spec/inputs/test/table_spreading_spec.yue" | ||
| 51 | "spec/inputs/test/loops_spec.yue" | ||
| 52 | "spec/inputs/test/format_spec.yue" | ||
| 53 | "spec/inputs/unicode/macro_export.yue" | ||
| 54 | "spec/inputs/unicode/attrib.yue" | ||
| 55 | "spec/inputs/unicode/macro.yue" | ||
| 56 | "spec/inputs/unicode/using.yue" | ||
| 57 | "spec/inputs/unicode/whitespace.yue" | ||
| 58 | "spec/inputs/unicode/nil_coalescing.yue" | ||
| 59 | "spec/inputs/unicode/stub.yue" | ||
| 60 | "spec/inputs/unicode/pipe.yue" | ||
| 61 | "spec/inputs/unicode/string.yue" | ||
| 62 | "spec/inputs/unicode/local.yue" | ||
| 63 | "spec/inputs/unicode/tables.yue" | ||
| 64 | "spec/inputs/unicode/operators.yue" | ||
| 65 | "spec/inputs/unicode/lists.yue" | ||
| 66 | "spec/inputs/unicode/switch.yue" | ||
| 67 | "spec/inputs/unicode/multiline_chain.yue" | ||
| 68 | "spec/inputs/unicode/existential.yue" | ||
| 69 | "spec/inputs/unicode/export_default.yue" | ||
| 70 | "spec/inputs/unicode/assign.yue" | ||
| 71 | "spec/inputs/unicode/literals.yue" | ||
| 72 | "spec/inputs/unicode/ambiguous.yue" | ||
| 73 | "spec/inputs/unicode/bubbling.yue" | ||
| 74 | "spec/inputs/unicode/try_catch.yue" | ||
| 75 | "spec/inputs/unicode/funcs.yue" | ||
| 76 | "spec/inputs/unicode/do.yue" | ||
| 77 | "spec/inputs/unicode/with.yue" | ||
| 78 | "spec/inputs/unicode/export.yue" | ||
| 79 | "spec/inputs/unicode/macro_todo.yue" | ||
| 80 | "spec/inputs/unicode/backcall.yue" | ||
| 81 | "spec/inputs/unicode/cond.yue" | ||
| 82 | "spec/inputs/unicode/in_expression.yue" | ||
| 83 | "spec/inputs/unicode/comprehension.yue" | ||
| 84 | "spec/inputs/unicode/import.yue" | ||
| 85 | "spec/inputs/unicode/unless_else.yue" | ||
| 86 | "spec/inputs/unicode/destructure.yue" | ||
| 87 | "spec/inputs/unicode/return.yue" | ||
| 88 | "spec/inputs/unicode/loops.yue" | ||
| 89 | "spec/inputs/unicode/class.yue" | ||
| 90 | "spec/inputs/unicode/vararg.yue" | ||
| 91 | "spec/inputs/unicode/goto.yue" | ||
| 92 | "spec/inputs/unicode/metatable.yue" | ||
| 93 | "spec/inputs/unicode/syntax.yue" | ||
| 94 | "spec/inputs/unicode/global.yue" | ||
| 95 | "spec/inputs/unicode/plus.yue" | ||
| 96 | ] | ||
| 97 | |||
| 98 | import "yue" | ||
| 99 | |||
| 100 | rewriteLineCol = (item)-> | ||
| 101 | item[2] = 0 | ||
| 102 | item[3] = 0 | ||
| 103 | for i = 4, #item | ||
| 104 | switch type item[i] when "table" | ||
| 105 | if item[i][1] == "comment" | ||
| 106 | table.remove item, i | ||
| 107 | rewriteLineCol item | ||
| 108 | return | ||
| 109 | rewriteLineCol item[i] | ||
| 110 | |||
| 111 | <- describe "format" | ||
| 112 | for file in *files | ||
| 113 | <- it file | ||
| 114 | f = io.open file | ||
| 115 | code = f\read "a*" | ||
| 116 | f\close! | ||
| 117 | |||
| 118 | original_ast = yue.to_ast code | ||
| 119 | assert.is_not_nil original_ast | ||
| 120 | rewriteLineCol original_ast | ||
| 121 | formated = yue.format code | ||
| 122 | ast = yue.to_ast formated | ||
| 123 | assert.is_not_nil ast | ||
| 124 | rewriteLineCol ast | ||
| 125 | assert.same original_ast, ast | ||
| 126 | |||
diff --git a/spec/outputs/test/format_spec.lua b/spec/outputs/test/format_spec.lua new file mode 100644 index 0000000..b12fb04 --- /dev/null +++ b/spec/outputs/test/format_spec.lua | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | local files = { | ||
| 2 | "spec/inputs/macro_export.yue", | ||
| 3 | "spec/inputs/attrib.yue", | ||
| 4 | "spec/inputs/macro.yue", | ||
| 5 | "spec/inputs/using.yue", | ||
| 6 | "spec/inputs/whitespace.yue", | ||
| 7 | "spec/inputs/nil_coalescing.yue", | ||
| 8 | "spec/inputs/stub.yue", | ||
| 9 | "spec/inputs/pipe.yue", | ||
| 10 | "spec/inputs/teal_lang.yue", | ||
| 11 | "spec/inputs/string.yue", | ||
| 12 | "spec/inputs/local.yue", | ||
| 13 | "spec/inputs/tables.yue", | ||
| 14 | "spec/inputs/operators.yue", | ||
| 15 | "spec/inputs/lists.yue", | ||
| 16 | "spec/inputs/compile_doc.yue", | ||
| 17 | "spec/inputs/switch.yue", | ||
| 18 | "spec/inputs/multiline_chain.yue", | ||
| 19 | "spec/inputs/existential.yue", | ||
| 20 | "spec/inputs/export_default.yue", | ||
| 21 | "spec/inputs/assign.yue", | ||
| 22 | "spec/inputs/literals.yue", | ||
| 23 | "spec/inputs/luarocks_upload.yue", | ||
| 24 | "spec/inputs/ambiguous.yue", | ||
| 25 | "spec/inputs/bubbling.yue", | ||
| 26 | "spec/inputs/try_catch.yue", | ||
| 27 | "spec/inputs/funcs.yue", | ||
| 28 | "spec/inputs/do.yue", | ||
| 29 | "spec/inputs/with.yue", | ||
| 30 | "spec/inputs/export.yue", | ||
| 31 | "spec/inputs/macro_todo.yue", | ||
| 32 | "spec/inputs/backcall.yue", | ||
| 33 | "spec/inputs/cond.yue", | ||
| 34 | "spec/inputs/in_expression.yue", | ||
| 35 | "spec/inputs/comprehension.yue", | ||
| 36 | "spec/inputs/macro_teal.yue", | ||
| 37 | "spec/inputs/import.yue", | ||
| 38 | "spec/inputs/unless_else.yue", | ||
| 39 | "spec/inputs/destructure.yue", | ||
| 40 | "spec/inputs/return.yue", | ||
| 41 | "spec/inputs/loops.yue", | ||
| 42 | "spec/inputs/class.yue", | ||
| 43 | "spec/inputs/vararg.yue", | ||
| 44 | "spec/inputs/goto.yue", | ||
| 45 | "spec/inputs/metatable.yue", | ||
| 46 | "spec/inputs/syntax.yue", | ||
| 47 | "spec/inputs/global.yue", | ||
| 48 | "spec/inputs/plus.yue", | ||
| 49 | "spec/inputs/test/class_spec.yue", | ||
| 50 | "spec/inputs/test/table_spreading_spec.yue", | ||
| 51 | "spec/inputs/test/loops_spec.yue", | ||
| 52 | "spec/inputs/test/format_spec.yue", | ||
| 53 | "spec/inputs/unicode/macro_export.yue", | ||
| 54 | "spec/inputs/unicode/attrib.yue", | ||
| 55 | "spec/inputs/unicode/macro.yue", | ||
| 56 | "spec/inputs/unicode/using.yue", | ||
| 57 | "spec/inputs/unicode/whitespace.yue", | ||
| 58 | "spec/inputs/unicode/nil_coalescing.yue", | ||
| 59 | "spec/inputs/unicode/stub.yue", | ||
| 60 | "spec/inputs/unicode/pipe.yue", | ||
| 61 | "spec/inputs/unicode/string.yue", | ||
| 62 | "spec/inputs/unicode/local.yue", | ||
| 63 | "spec/inputs/unicode/tables.yue", | ||
| 64 | "spec/inputs/unicode/operators.yue", | ||
| 65 | "spec/inputs/unicode/lists.yue", | ||
| 66 | "spec/inputs/unicode/switch.yue", | ||
| 67 | "spec/inputs/unicode/multiline_chain.yue", | ||
| 68 | "spec/inputs/unicode/existential.yue", | ||
| 69 | "spec/inputs/unicode/export_default.yue", | ||
| 70 | "spec/inputs/unicode/assign.yue", | ||
| 71 | "spec/inputs/unicode/literals.yue", | ||
| 72 | "spec/inputs/unicode/ambiguous.yue", | ||
| 73 | "spec/inputs/unicode/bubbling.yue", | ||
| 74 | "spec/inputs/unicode/try_catch.yue", | ||
| 75 | "spec/inputs/unicode/funcs.yue", | ||
| 76 | "spec/inputs/unicode/do.yue", | ||
| 77 | "spec/inputs/unicode/with.yue", | ||
| 78 | "spec/inputs/unicode/export.yue", | ||
| 79 | "spec/inputs/unicode/macro_todo.yue", | ||
| 80 | "spec/inputs/unicode/backcall.yue", | ||
| 81 | "spec/inputs/unicode/cond.yue", | ||
| 82 | "spec/inputs/unicode/in_expression.yue", | ||
| 83 | "spec/inputs/unicode/comprehension.yue", | ||
| 84 | "spec/inputs/unicode/import.yue", | ||
| 85 | "spec/inputs/unicode/unless_else.yue", | ||
| 86 | "spec/inputs/unicode/destructure.yue", | ||
| 87 | "spec/inputs/unicode/return.yue", | ||
| 88 | "spec/inputs/unicode/loops.yue", | ||
| 89 | "spec/inputs/unicode/class.yue", | ||
| 90 | "spec/inputs/unicode/vararg.yue", | ||
| 91 | "spec/inputs/unicode/goto.yue", | ||
| 92 | "spec/inputs/unicode/metatable.yue", | ||
| 93 | "spec/inputs/unicode/syntax.yue", | ||
| 94 | "spec/inputs/unicode/global.yue", | ||
| 95 | "spec/inputs/unicode/plus.yue" | ||
| 96 | } | ||
| 97 | local yue = require("yue") | ||
| 98 | local rewriteLineCol | ||
| 99 | rewriteLineCol = function(item) | ||
| 100 | item[2] = 0 | ||
| 101 | item[3] = 0 | ||
| 102 | for i = 4, #item do | ||
| 103 | do | ||
| 104 | local _exp_0 = type(item[i]) | ||
| 105 | if "table" == _exp_0 then | ||
| 106 | if item[i][1] == "comment" then | ||
| 107 | table.remove(item, i) | ||
| 108 | rewriteLineCol(item) | ||
| 109 | return | ||
| 110 | end | ||
| 111 | rewriteLineCol(item[i]) | ||
| 112 | end | ||
| 113 | end | ||
| 114 | end | ||
| 115 | end | ||
| 116 | return describe("format", function() | ||
| 117 | for _index_0 = 1, #files do | ||
| 118 | local file = files[_index_0] | ||
| 119 | it(file, function() | ||
| 120 | local f = io.open(file) | ||
| 121 | local code = f:read("a*") | ||
| 122 | f:close() | ||
| 123 | local original_ast = yue.to_ast(code) | ||
| 124 | assert.is_not_nil(original_ast) | ||
| 125 | rewriteLineCol(original_ast) | ||
| 126 | local formated = yue.format(code) | ||
| 127 | local ast = yue.to_ast(formated) | ||
| 128 | assert.is_not_nil(ast) | ||
| 129 | rewriteLineCol(ast) | ||
| 130 | return assert.same(original_ast, ast) | ||
| 131 | end) | ||
| 132 | end | ||
| 133 | end) | ||
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}, |
