diff options
author | Li Jin <dragon-fly@qq.com> | 2023-08-08 18:12:06 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2023-08-08 18:12:16 +0800 |
commit | 60774555568dbc64866d088cb51e45f9434c0f89 (patch) | |
tree | f38b9eb54e1b647e9d222dcba0e5ff3716016424 | |
parent | 878111166eb4cfe4ddbc05f60e797ee16356e71a (diff) | |
download | yuescript-60774555568dbc64866d088cb51e45f9434c0f89.tar.gz yuescript-60774555568dbc64866d088cb51e45f9434c0f89.tar.bz2 yuescript-60774555568dbc64866d088cb51e45f9434c0f89.zip |
make vararg assignment work with line decorator.
-rw-r--r-- | spec/inputs/vararg.yue | 22 | ||||
-rw-r--r-- | spec/outputs/vararg.lua | 45 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 82 |
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 |
224 | end | 269 | end |
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>(); |