aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/outputs/5.1/attrib.lua15
-rw-r--r--spec/outputs/upvalue_func.lua16
-rw-r--r--src/yuescript/yue_compiler.cpp85
3 files changed, 63 insertions, 53 deletions
diff --git a/spec/outputs/5.1/attrib.lua b/spec/outputs/5.1/attrib.lua
index af3f6cc..0edaf0e 100644
--- a/spec/outputs/5.1/attrib.lua
+++ b/spec/outputs/5.1/attrib.lua
@@ -62,10 +62,7 @@ local _anon_func_1 = function(io)
62 _with_0:write("Hello") 62 _with_0:write("Hello")
63 return _with_0 63 return _with_0
64end 64end
65local _anon_func_2 = function() 65local _anon_func_2 = function() end
66 do
67 end
68end
69do 66do
70 local v = (function() 67 local v = (function()
71 if flag then 68 if flag then
@@ -123,10 +120,7 @@ local _anon_func_5 = function(a, b)
123 } 120 }
124 end 121 end
125end 122end
126local _anon_func_7 = function() 123local _anon_func_7 = function() end
127 do
128 end
129end
130do 124do
131 local a = (function() 125 local a = (function()
132 if true then 126 if true then
@@ -244,10 +238,7 @@ local _anon_func_11 = function(_, _close_2, error, _arg_0, ...)
244 end 238 end
245 end 239 end
246end 240end
247local _anon_func_12 = function() 241local _anon_func_12 = function() end
248 do
249 end
250end
251do 242do
252 local _ = def(function() 243 local _ = def(function()
253 return print(3) 244 return print(3)
diff --git a/spec/outputs/upvalue_func.lua b/spec/outputs/upvalue_func.lua
index 14fe400..5113692 100644
--- a/spec/outputs/upvalue_func.lua
+++ b/spec/outputs/upvalue_func.lua
@@ -368,11 +368,9 @@ local _anon_func_18 = function(print, select, _arg_0, ...)
368 end 368 end
369end 369end
370local _anon_func_19 = function(print) 370local _anon_func_19 = function(print)
371 do 371 local a = 1
372 local a = 1 372 print(a + nil)
373 print(a + nil) 373 return 1, 2, 3
374 return 1, 2, 3
375 end
376end 374end
377local _anon_func_20 = function(cond, i) 375local _anon_func_20 = function(cond, i)
378 local _accum_0 = { } 376 local _accum_0 = { }
@@ -516,11 +514,9 @@ local _anon_func_29 = function(os, _arg_0, ...)
516 end 514 end
517end 515end
518local _anon_func_30 = function(debug_env_after, debug_env_before, env, func) 516local _anon_func_30 = function(debug_env_after, debug_env_before, env, func)
519 do 517 debug_env_before(env)
520 debug_env_before(env) 518 func(env)
521 func(env) 519 return debug_env_after(env)
522 return debug_env_after(env)
523 end
524end 520end
525do 521do
526 local buff_strength 522 local buff_strength
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index ae6c0e4..14cb3e6 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
78const std::string_view version = "0.23.1"sv; 78const std::string_view version = "0.23.2"sv;
79const std::string_view extension = "yue"sv; 79const std::string_view extension = "yue"sv;
80 80
81class CompileError : public std::logic_error { 81class CompileError : public std::logic_error {
@@ -3674,9 +3674,20 @@ private:
3674 } 3674 }
3675 } 3675 }
3676 3676
3677 std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Exp_t* exp, str_list* ensureArgListInTheEnd = nullptr) { 3677 bool checkUpValueFuncAvailable(ast_node* node) {
3678 if (_funcLevel <= 1) return false;
3679 return node->traverse([&](ast_node* n) {
3680 switch (n->get_id()) {
3681 case id<MacroName_t>():
3682 return traversal::Stop;
3683 }
3684 return traversal::Continue;
3685 }) != traversal::Stop;
3686 }
3687
3688 std::optional<std::pair<std::string, str_list>> getUpValueFuncFromBlock(Block_t* block, str_list* ensureArgListInTheEnd) {
3678 if (_funcLevel <= 1) return std::nullopt; 3689 if (_funcLevel <= 1) return std::nullopt;
3679 auto result = exp->traverse([&](ast_node* node) { 3690 auto result = block->traverse([&](ast_node* node) {
3680 switch (node->get_id()) { 3691 switch (node->get_id()) {
3681 case id<MacroName_t>(): 3692 case id<MacroName_t>():
3682 return traversal::Stop; 3693 return traversal::Stop;
@@ -3687,7 +3698,8 @@ private:
3687 str_list args; 3698 str_list args;
3688 bool upVarsAssignedOrCaptured = false; 3699 bool upVarsAssignedOrCaptured = false;
3689 bool usedVar = false; 3700 bool usedVar = false;
3690 ast_ptr<false, Statement_t> stmt; 3701 auto x = block;
3702 ast_ptr<false, Block_t> newBlock(block);
3691 { 3703 {
3692 str_list globals; 3704 str_list globals;
3693 for (const auto& scope : _scopes) { 3705 for (const auto& scope : _scopes) {
@@ -3697,31 +3709,26 @@ private:
3697 } 3709 }
3698 } 3710 }
3699 } 3711 }
3700 auto returnNode = exp->new_ptr<Return_t>();
3701 auto returnList = exp->new_ptr<ExpListLow_t>();
3702 returnList->exprs.push_back(exp);
3703 returnNode->valueList.set(returnList);
3704 std::string codes; 3712 std::string codes;
3705 if (_withVars.empty()) { 3713 if (_withVars.empty()) {
3706 codes = YueFormat{}.toString(returnNode); 3714 codes = YueFormat{}.toString(block);
3707 stmt = exp->new_ptr<Statement_t>();
3708 stmt->content.set(returnNode);
3709 } else { 3715 } else {
3710 auto withNode = exp->new_ptr<With_t>(); 3716 auto withNode = block->new_ptr<With_t>();
3711 withNode->valueList.set(toAst<ExpList_t>(_withVars.top(), exp)); 3717 withNode->valueList.set(toAst<ExpList_t>(_withVars.top(), x));
3712 auto returnStmt = exp->new_ptr<Statement_t>(); 3718 withNode->body.set(block);
3713 returnStmt->content.set(returnNode);
3714 withNode->body.set(returnStmt);
3715 codes = YueFormat{}.toString(withNode); 3719 codes = YueFormat{}.toString(withNode);
3716 stmt = exp->new_ptr<Statement_t>(); 3720 auto simpleValue = x->new_ptr<SimpleValue_t>();
3717 auto simpleValue = exp->new_ptr<SimpleValue_t>();
3718 simpleValue->value.set(withNode); 3721 simpleValue->value.set(withNode);
3719 auto newExpr = newExp(simpleValue, exp); 3722 auto newExpr = newExp(simpleValue, x);
3720 auto explist = exp->new_ptr<ExpList_t>(); 3723 auto explist = x->new_ptr<ExpList_t>();
3721 explist->exprs.push_back(newExpr); 3724 explist->exprs.push_back(newExpr);
3722 auto expListAssign = exp->new_ptr<ExpListAssign_t>(); 3725 auto expListAssign = x->new_ptr<ExpListAssign_t>();
3723 expListAssign->expList.set(explist); 3726 expListAssign->expList.set(explist);
3727 auto stmt = x->new_ptr<Statement_t>();
3724 stmt->content.set(expListAssign); 3728 stmt->content.set(expListAssign);
3729 auto blk = x->new_ptr<Block_t>();
3730 blk->statements.push_back(stmt);
3731 newBlock.set(blk);
3725 } 3732 }
3726 if (!globals.empty()) { 3733 if (!globals.empty()) {
3727 codes.insert(0, "global "s + join(globals, ","sv) + '\n'); 3734 codes.insert(0, "global "s + join(globals, ","sv) + '\n');
@@ -3730,7 +3737,7 @@ private:
3730 config.lintGlobalVariable = true; 3737 config.lintGlobalVariable = true;
3731 auto result = YueCompiler{L, _luaOpen, true}.compile(codes, config); 3738 auto result = YueCompiler{L, _luaOpen, true}.compile(codes, config);
3732 if (result.error) { 3739 if (result.error) {
3733 YUEE("failed to compile dues to Yue formatter", exp); 3740 YUEE("failed to compile dues to Yue formatter", x);
3734 } 3741 }
3735 usedVar = result.usedVar; 3742 usedVar = result.usedVar;
3736 if (result.globals) { 3743 if (result.globals) {
@@ -3745,7 +3752,6 @@ private:
3745 } 3752 }
3746 } 3753 }
3747 if (!upVarsAssignedOrCaptured) { 3754 if (!upVarsAssignedOrCaptured) {
3748 auto x = exp;
3749 if (ensureArgListInTheEnd) { 3755 if (ensureArgListInTheEnd) {
3750 std::unordered_set<std::string> vars; 3756 std::unordered_set<std::string> vars;
3751 for (const auto& arg : args) { 3757 for (const auto& arg : args) {
@@ -3775,7 +3781,7 @@ private:
3775 } 3781 }
3776 } 3782 }
3777 auto funLit = toAst<FunLit_t>("("s + join(args, ","sv) + ")-> nil"s, x); 3783 auto funLit = toAst<FunLit_t>("("s + join(args, ","sv) + ")-> nil"s, x);
3778 funLit->body->content.set(stmt.get()); 3784 funLit->body->content.set(newBlock);
3779 funLit->noRecursion = true; 3785 funLit->noRecursion = true;
3780 auto simpleValue = x->new_ptr<SimpleValue_t>(); 3786 auto simpleValue = x->new_ptr<SimpleValue_t>();
3781 simpleValue->value.set(funLit); 3787 simpleValue->value.set(funLit);
@@ -3796,6 +3802,29 @@ private:
3796 return std::nullopt; 3802 return std::nullopt;
3797 } 3803 }
3798 3804
3805
3806 std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Block_t* block, str_list* ensureArgListInTheEnd = nullptr) {
3807 if (checkUpValueFuncAvailable(block)) {
3808 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd);
3809 }
3810 return std::nullopt;
3811 }
3812
3813 std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Exp_t* exp, str_list* ensureArgListInTheEnd = nullptr) {
3814 if (checkUpValueFuncAvailable(exp)) {
3815 auto returnNode = exp->new_ptr<Return_t>();
3816 auto returnList = exp->new_ptr<ExpListLow_t>();
3817 returnList->exprs.push_back(exp);
3818 returnNode->valueList.set(returnList);
3819 auto block = exp->new_ptr<Block_t>();
3820 auto stmt = exp->new_ptr<Statement_t>();
3821 stmt->content.set(returnNode);
3822 block->statements.push_back(stmt);
3823 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd);
3824 }
3825 return std::nullopt;
3826 }
3827
3799 bool transformAsUpValueFunc(Exp_t* exp, str_list& out) { 3828 bool transformAsUpValueFunc(Exp_t* exp, str_list& out) {
3800 auto result = upValueFuncFrom(exp); 3829 auto result = upValueFuncFrom(exp);
3801 if (result) { 3830 if (result) {
@@ -9091,13 +9120,7 @@ private:
9091 } 9120 }
9092 if (auto tryBlock = tryNode->func.as<Block_t>()) { 9121 if (auto tryBlock = tryNode->func.as<Block_t>()) {
9093 { 9122 {
9094 auto body = tryBlock->new_ptr<Body_t>(); 9123 if (auto result = upValueFuncFrom(tryBlock)) {
9095 body->content.set(tryBlock);
9096 auto doNode = tryBlock->new_ptr<Do_t>();
9097 doNode->body.set(body);
9098 auto simpleValue = tryBlock->new_ptr<SimpleValue_t>();
9099 simpleValue->value.set(doNode);
9100 if (auto result = upValueFuncFrom(newExp(simpleValue, tryBlock))) {
9101 auto [funcName, args] = std::move(*result); 9124 auto [funcName, args] = std::move(*result);
9102 if (errHandler) { 9125 if (errHandler) {
9103 auto xpcall = toAst<ChainValue_t>("xpcall()", x); 9126 auto xpcall = toAst<ChainValue_t>("xpcall()", x);