diff options
author | Li Jin <dragon-fly@qq.com> | 2024-03-04 11:13:18 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2024-03-04 11:13:18 +0800 |
commit | 4e9a508a11c16db9aeff44b27e88713ab413bff7 (patch) | |
tree | 2ef6f1e4904e32379e67b1c35b7bc8031685088a /src | |
parent | 412bc3d7606cb0d07c39861c7ae4e89c7139da31 (diff) | |
download | yuescript-4e9a508a11c16db9aeff44b27e88713ab413bff7.tar.gz yuescript-4e9a508a11c16db9aeff44b27e88713ab413bff7.tar.bz2 yuescript-4e9a508a11c16db9aeff44b27e88713ab413bff7.zip |
add default return declaration for function literal.v0.22.2
Diffstat (limited to 'src')
-rw-r--r-- | src/yuescript/yue_ast.cpp | 14 | ||||
-rw-r--r-- | src/yuescript/yue_ast.h | 3 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 40 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 21 | ||||
-rw-r--r-- | src/yuescript/yue_parser.h | 3 |
5 files changed, 71 insertions, 10 deletions
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index faa175d..fbf7a63 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
@@ -1279,6 +1279,16 @@ std::string FunLit_t::to_string(void* ud) const { | |||
1279 | if (argsDef) { | 1279 | if (argsDef) { |
1280 | line = argsDef->to_string(ud); | 1280 | line = argsDef->to_string(ud); |
1281 | } | 1281 | } |
1282 | if (defaultReturn) { | ||
1283 | if (defaultReturn.is<DefaultValue_t>()) { | ||
1284 | line += ':'; | ||
1285 | } else { | ||
1286 | line += ": "s + defaultReturn->to_string(ud); | ||
1287 | } | ||
1288 | } | ||
1289 | if (!line.empty()) { | ||
1290 | line += ' '; | ||
1291 | } | ||
1282 | line += arrow->to_string(ud); | 1292 | line += arrow->to_string(ud); |
1283 | if (body) { | 1293 | if (body) { |
1284 | if (body->content.is<Statement_t>()) { | 1294 | if (body->content.is<Statement_t>()) { |
@@ -1302,7 +1312,7 @@ std::string MacroLit_t::to_string(void* ud) const { | |||
1302 | auto info = reinterpret_cast<YueFormat*>(ud); | 1312 | auto info = reinterpret_cast<YueFormat*>(ud); |
1303 | std::string line; | 1313 | std::string line; |
1304 | if (argsDef) { | 1314 | if (argsDef) { |
1305 | line = '(' + argsDef->to_string(ud) + ')'; | 1315 | line = '(' + argsDef->to_string(ud) + ") "s; |
1306 | } | 1316 | } |
1307 | line += "->"s; | 1317 | line += "->"s; |
1308 | if (body->content.is<Statement_t>()) { | 1318 | if (body->content.is<Statement_t>()) { |
@@ -1323,7 +1333,7 @@ std::string Macro_t::to_string(void* ud) const { | |||
1323 | } | 1333 | } |
1324 | std::string MacroInPlace_t::to_string(void* ud) const { | 1334 | std::string MacroInPlace_t::to_string(void* ud) const { |
1325 | auto info = reinterpret_cast<YueFormat*>(ud); | 1335 | auto info = reinterpret_cast<YueFormat*>(ud); |
1326 | auto line = "$->"s; | 1336 | auto line = "$ ->"s; |
1327 | if (body->content.is<Statement_t>()) { | 1337 | if (body->content.is<Statement_t>()) { |
1328 | line += ' ' + body->to_string(ud); | 1338 | line += ' ' + body->to_string(ud); |
1329 | } else { | 1339 | } else { |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 90dce7a..73ffc9a 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -756,9 +756,10 @@ AST_END(FnArrow, "fn_arrow"sv) | |||
756 | 756 | ||
757 | AST_NODE(FunLit) | 757 | AST_NODE(FunLit) |
758 | ast_ptr<false, FnArgsDef_t> argsDef; | 758 | ast_ptr<false, FnArgsDef_t> argsDef; |
759 | ast_sel<false, ExpListLow_t, DefaultValue_t> defaultReturn; | ||
759 | ast_ptr<true, FnArrow_t> arrow; | 760 | ast_ptr<true, FnArrow_t> arrow; |
760 | ast_ptr<false, Body_t> body; | 761 | ast_ptr<false, Body_t> body; |
761 | AST_MEMBER(FunLit, &argsDef, &arrow, &body) | 762 | AST_MEMBER(FunLit, &argsDef, &defaultReturn, &arrow, &body) |
762 | AST_END(FunLit, "fun_lit"sv) | 763 | AST_END(FunLit, "fun_lit"sv) |
763 | 764 | ||
764 | AST_NODE(MacroName) | 765 | AST_NODE(MacroName) |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 0d38fa5..f23d5f0 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.22.1"sv; | 78 | const std::string_view version = "0.22.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 { |
@@ -3787,11 +3787,44 @@ private: | |||
3787 | str_list temp; | 3787 | str_list temp; |
3788 | if (auto argsDef = funLit->argsDef.get()) { | 3788 | if (auto argsDef = funLit->argsDef.get()) { |
3789 | transformFnArgsDef(argsDef, temp); | 3789 | transformFnArgsDef(argsDef, temp); |
3790 | } | ||
3791 | if (funLit->defaultReturn) { | ||
3792 | auto newBlock = funLit->new_ptr<Block_t>(); | ||
3793 | if (funLit->body) { | ||
3794 | auto last = lastStatementFrom(funLit->body); | ||
3795 | if (!last->appendix && last->content.is<Return_t>() && !funLit->defaultReturn.is<DefaultValue_t>()) { | ||
3796 | throw CompileError("duplicated return statement", last->content); | ||
3797 | } | ||
3798 | auto content = funLit->body->content.get(); | ||
3799 | switch (content->get_id()) { | ||
3800 | case id<Block_t>(): { | ||
3801 | auto block = static_cast<Block_t*>(content); | ||
3802 | newBlock->statements.dup(block->statements); | ||
3803 | break; | ||
3804 | } | ||
3805 | case id<Statement_t>(): { | ||
3806 | newBlock->statements.push_back(content); | ||
3807 | break; | ||
3808 | } | ||
3809 | default: YUEE("AST node mismatch", content); break; | ||
3810 | } | ||
3811 | } | ||
3812 | if (funLit->defaultReturn.is<ExpListLow_t>()) { | ||
3813 | auto returnNode = newBlock->new_ptr<Return_t>(); | ||
3814 | returnNode->valueList.set(funLit->defaultReturn); | ||
3815 | auto stmt = newBlock->new_ptr<Statement_t>(); | ||
3816 | stmt->content.set(returnNode); | ||
3817 | newBlock->statements.push_back(stmt); | ||
3818 | } | ||
3819 | transformBlock(newBlock, temp, ExpUsage::Common); | ||
3820 | } else { | ||
3790 | if (funLit->body) { | 3821 | if (funLit->body) { |
3791 | transformBody(funLit->body, temp, ExpUsage::Return); | 3822 | transformBody(funLit->body, temp, ExpUsage::Return); |
3792 | } else { | 3823 | } else { |
3793 | temp.push_back(Empty); | 3824 | temp.push_back(Empty); |
3794 | } | 3825 | } |
3826 | } | ||
3827 | if (auto argsDef = funLit->argsDef.get()) { | ||
3795 | auto it = temp.begin(); | 3828 | auto it = temp.begin(); |
3796 | auto& args = *it; | 3829 | auto& args = *it; |
3797 | auto& initArgs = *(++it); | 3830 | auto& initArgs = *(++it); |
@@ -3811,11 +3844,6 @@ private: | |||
3811 | _buf << " end"sv; | 3844 | _buf << " end"sv; |
3812 | } | 3845 | } |
3813 | } else { | 3846 | } else { |
3814 | if (funLit->body) { | ||
3815 | transformBody(funLit->body, temp, ExpUsage::Return); | ||
3816 | } else { | ||
3817 | temp.push_back(Empty); | ||
3818 | } | ||
3819 | auto& bodyCodes = temp.back(); | 3847 | auto& bodyCodes = temp.back(); |
3820 | _buf << "function("sv << (isFatArrow ? "self"s : Empty) << ')'; | 3848 | _buf << "function("sv << (isFatArrow ? "self"s : Empty) << ')'; |
3821 | if (!bodyCodes.empty()) { | 3849 | if (!bodyCodes.empty()) { |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index d138979..3ffaf18 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -416,6 +416,18 @@ YueParser::YueParser() { | |||
416 | return true; | 416 | return true; |
417 | }); | 417 | }); |
418 | 418 | ||
419 | disable_fun_lit = pl::user(true_(), [](const item_t& item) { | ||
420 | State* st = reinterpret_cast<State*>(item.user_data); | ||
421 | st->fnArrowAvailable = false; | ||
422 | return true; | ||
423 | }); | ||
424 | |||
425 | enable_fun_lit = pl::user(true_(), [](const item_t& item) { | ||
426 | State* st = reinterpret_cast<State*>(item.user_data); | ||
427 | st->fnArrowAvailable = true; | ||
428 | return true; | ||
429 | }); | ||
430 | |||
419 | disable_do_chain_arg_table_block = pl::user(true_(), [](const item_t& item) { | 431 | disable_do_chain_arg_table_block = pl::user(true_(), [](const item_t& item) { |
420 | State* st = reinterpret_cast<State*>(item.user_data); | 432 | State* st = reinterpret_cast<State*>(item.user_data); |
421 | st->noDoStack.push(true); | 433 | st->noDoStack.push(true); |
@@ -846,7 +858,14 @@ YueParser::YueParser() { | |||
846 | 858 | ||
847 | FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> ')'; | 859 | FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> ')'; |
848 | FnArrow = expr("->") | "=>"; | 860 | FnArrow = expr("->") | "=>"; |
849 | FunLit = -FnArgsDef >> space >> FnArrow >> -(space >> Body); | 861 | FunLit = pl::user(true_(), [](const item_t& item) { |
862 | State* st = reinterpret_cast<State*>(item.user_data); | ||
863 | return st->fnArrowAvailable; | ||
864 | }) >> -(FnArgsDef >> | ||
865 | -(':' >> space >> | ||
866 | disable_fun_lit >> ensure(ExpListLow | DefaultValue, enable_fun_lit) | ||
867 | ) | ||
868 | ) >> space >> FnArrow >> -(space >> Body); | ||
850 | 869 | ||
851 | MacroName = '$' >> UnicodeName; | 870 | MacroName = '$' >> UnicodeName; |
852 | macro_args_def = '(' >> white >> -FnArgDefList >> white >> ')'; | 871 | macro_args_def = '(' >> white >> -FnArgDefList >> white >> ')'; |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 39b7cce..05aa9e6 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
@@ -105,6 +105,7 @@ protected: | |||
105 | bool exportMacro = false; | 105 | bool exportMacro = false; |
106 | bool exportMetatable = false; | 106 | bool exportMetatable = false; |
107 | bool exportMetamethod = false; | 107 | bool exportMetamethod = false; |
108 | bool fnArrowAvailable = true; | ||
108 | int exportCount = 0; | 109 | int exportCount = 0; |
109 | int expLevel = 0; | 110 | int expLevel = 0; |
110 | size_t stringOpen = 0; | 111 | size_t stringOpen = 0; |
@@ -198,6 +199,8 @@ private: | |||
198 | NONE_AST_RULE(enable_arg_table_block); | 199 | NONE_AST_RULE(enable_arg_table_block); |
199 | NONE_AST_RULE(disable_for); | 200 | NONE_AST_RULE(disable_for); |
200 | NONE_AST_RULE(enable_for); | 201 | NONE_AST_RULE(enable_for); |
202 | NONE_AST_RULE(enable_fun_lit); | ||
203 | NONE_AST_RULE(disable_fun_lit); | ||
201 | NONE_AST_RULE(switch_else); | 204 | NONE_AST_RULE(switch_else); |
202 | NONE_AST_RULE(switch_block); | 205 | NONE_AST_RULE(switch_block); |
203 | NONE_AST_RULE(if_else_if); | 206 | NONE_AST_RULE(if_else_if); |