aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2023-08-08 18:12:06 +0800
committerLi Jin <dragon-fly@qq.com>2023-08-08 18:12:16 +0800
commit60774555568dbc64866d088cb51e45f9434c0f89 (patch)
treef38b9eb54e1b647e9d222dcba0e5ff3716016424
parent878111166eb4cfe4ddbc05f60e797ee16356e71a (diff)
downloadyuescript-60774555568dbc64866d088cb51e45f9434c0f89.tar.gz
yuescript-60774555568dbc64866d088cb51e45f9434c0f89.tar.bz2
yuescript-60774555568dbc64866d088cb51e45f9434c0f89.zip
make vararg assignment work with line decorator.
-rw-r--r--spec/inputs/vararg.yue22
-rw-r--r--spec/outputs/vararg.lua45
-rw-r--r--src/yuescript/yue_compiler.cpp82
3 files changed, 141 insertions, 8 deletions
diff --git a/spec/inputs/vararg.yue b/spec/inputs/vararg.yue
index c7b8ebf..466a4a6 100644
--- a/spec/inputs/vararg.yue
+++ b/spec/inputs/vararg.yue
@@ -52,5 +52,27 @@ join = (...) ->
52 f_colon f!\func 52 f_colon f!\func
53 f_colon f(...)\func 53 f_colon f(...)\func
54 54
55 _ = ->
56 list = {1, 2, 3, 4, 5}
57 fn = (ok) ->
58 ok, table.unpack list
59 ok, ... = fn true
60 print ok, ...
61
62 fn_many_args = ->
63 10, nil, 20, nil, 30
64
65 ... = fn_many_args!
66 print select "#", ...
67 print ...
68
69 do
70 ... = 1, 2 if true
71 print ...
72
73 do
74 a, ... = 1, 2 unless true
75 print a, select '#', ...
76
55 nil 77 nil
56 78
diff --git a/spec/outputs/vararg.lua b/spec/outputs/vararg.lua
index 56e2011..6cfaccb 100644
--- a/spec/outputs/vararg.lua
+++ b/spec/outputs/vararg.lua
@@ -220,5 +220,50 @@ join = function(...)
220 return _fn_0(_base_0, ...) 220 return _fn_0(_base_0, ...)
221 end 221 end
222 end)(...)) 222 end)(...))
223 local _
224 _ = function()
225 local list = {
226 1,
227 2,
228 3,
229 4,
230 5
231 }
232 local fn
233 fn = function(ok)
234 return ok, table.unpack(list)
235 end
236 return (function(_arg_0, ...)
237 local ok = _arg_0
238 print(ok, ...)
239 local fn_many_args
240 fn_many_args = function()
241 return 10, nil, 20, nil, 30
242 end
243 return (function(...)
244 print(select("#", ...))
245 return print(...)
246 end)(fn_many_args())
247 end)(fn(true))
248 end
249 do
250 (function(...)
251 return print(...)
252 end)((function()
253 if true then
254 return 1, 2
255 end
256 end)())
257 end
258 do
259 (function(_arg_0, ...)
260 local a = _arg_0
261 return print(a, select('#', ...))
262 end)((function()
263 if not true then
264 return 1, 2
265 end
266 end)())
267 end
223 return nil 268 return nil
224end 269end
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 9384214..6644ca5 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -3619,14 +3619,82 @@ private:
3619 auto varArg = simpleValue->value.as<VarArg_t>(); 3619 auto varArg = simpleValue->value.as<VarArg_t>();
3620 BREAK_IF(!varArg); 3620 BREAK_IF(!varArg);
3621 auto assignAction = static_cast<Assign_t*>(expListAssign->action.get()); 3621 auto assignAction = static_cast<Assign_t*>(expListAssign->action.get());
3622 bool isExps = true; 3622 auto newInvoke = assignAction->new_ptr<InvokeArgs_t>();
3623 for (auto item : assignAction->values.objects()) { 3623 if (auto appendix = stmt->appendix.get()) {
3624 if (!ast_is<Exp_t, TableBlock_t>(item)) { 3624 switch (appendix->item->get_id()) {
3625 isExps = false; 3625 case id<IfLine_t>(): {
3626 break; 3626 auto if_line = static_cast<IfLine_t*>(appendix->item.get());
3627 auto ifNode = appendix->new_ptr<If_t>();
3628 ifNode->type.set(if_line->type);
3629 ifNode->nodes.push_back(if_line->condition);
3630 auto expList = appendix->new_ptr<ExpList_t>();
3631 for (auto val : assignAction->values.objects()) {
3632 switch (val->get_id()) {
3633 case id<If_t>():
3634 case id<Switch_t>():
3635 case id<With_t>(): {
3636 auto simpleValue = val->new_ptr<SimpleValue_t>();
3637 simpleValue->value.set(val);
3638 auto exp = newExp(simpleValue, val);
3639 expList->exprs.push_back(exp);
3640 break;
3641 }
3642 case id<TableBlock_t>(): {
3643 auto tableBlock = static_cast<TableBlock_t*>(val);
3644 auto tabLit = val->new_ptr<TableLit_t>();
3645 tabLit->values.dup(tableBlock->values);
3646 auto simpleValue = val->new_ptr<SimpleValue_t>();
3647 simpleValue->value.set(tabLit);
3648 auto exp = newExp(simpleValue, val);
3649 expList->exprs.push_back(exp);
3650 break;
3651 }
3652 case id<Exp_t>(): {
3653 expList->exprs.push_back(val);
3654 break;
3655 }
3656 default: YUEE("AST node mismatch", val); break;
3657 }
3658 }
3659 auto newExpListAssign = assignAction->new_ptr<ExpListAssign_t>();
3660 newExpListAssign->expList.set(expList);
3661 auto newStmt = assignAction->new_ptr<Statement_t>();
3662 newStmt->content.set(newExpListAssign);
3663 ifNode->nodes.push_back(newStmt);
3664 auto newSVal = ifNode->new_ptr<SimpleValue_t>();
3665 newSVal->value.set(ifNode);
3666 newInvoke->args.push_back(newExp(newSVal, newSVal));
3667 break;
3668 }
3669 case id<WhileLine_t>(): {
3670 throw CompileError("while-loop line decorator is not supported here"sv, appendix->item.get());
3671 break;
3672 }
3673 case id<CompInner_t>(): {
3674 throw CompileError("for-loop line decorator is not supported here"sv, appendix->item.get());
3675 break;
3676 }
3677 default: YUEE("AST node mismatch", appendix->item.get()); break;
3678 }
3679 }
3680 if (newInvoke->args.empty()) {
3681 for (auto item : assignAction->values.objects()) {
3682 switch (item->get_id()) {
3683 case id<With_t>():
3684 case id<If_t>():
3685 case id<Switch_t>(): {
3686 auto sVal = item->new_ptr<SimpleValue_t>();
3687 sVal->value.set(item);
3688 newInvoke->args.push_back(newExp(sVal, item));
3689 break;
3690 }
3691 case id<TableBlock_t>():
3692 case id<Exp_t>():
3693 newInvoke->args.push_back(item);
3694 break;
3695 }
3627 } 3696 }
3628 } 3697 }
3629 BREAK_IF(!isExps);
3630 auto x = *nodes.begin(); 3698 auto x = *nodes.begin();
3631 auto newBlock = x->new_ptr<Block_t>(); 3699 auto newBlock = x->new_ptr<Block_t>();
3632 if (it != nodes.begin()) { 3700 if (it != nodes.begin()) {
@@ -3685,8 +3753,6 @@ private:
3685 newCallable->item.set(newParens); 3753 newCallable->item.set(newParens);
3686 auto newChainValue = x->new_ptr<ChainValue_t>(); 3754 auto newChainValue = x->new_ptr<ChainValue_t>();
3687 newChainValue->items.push_back(newCallable); 3755 newChainValue->items.push_back(newCallable);
3688 auto newInvoke = x->new_ptr<InvokeArgs_t>();
3689 newInvoke->args.dup(assignAction->values);
3690 newChainValue->items.push_back(newInvoke); 3756 newChainValue->items.push_back(newInvoke);
3691 auto newItem = newExp(newChainValue, x); 3757 auto newItem = newExp(newChainValue, x);
3692 auto newItemList = x->new_ptr<ExpList_t>(); 3758 auto newItemList = x->new_ptr<ExpList_t>();