From fe6d146bc4454d8096ddd0543d7142db3da5da5b Mon Sep 17 00:00:00 2001 From: Li Jin Date: Sun, 24 Apr 2022 11:26:46 +0800 Subject: fix spreading syntax behavior. --- spec/inputs/tables.yue | 25 ++++++++++ spec/outputs/tables.lua | 102 +++++++++++++++++++++++++++++++++++++++++ src/yuescript/yue_compiler.cpp | 45 +++++++++++++----- 3 files changed, 160 insertions(+), 12 deletions(-) diff --git a/spec/inputs/tables.yue b/spec/inputs/tables.yue index 4cd9b4d..649c1dc 100644 --- a/spec/inputs/tables.yue +++ b/spec/inputs/tables.yue @@ -237,5 +237,30 @@ menus = click: -> } +tb = {...other} + +tbMix = { + 1, 2, 3 + ... with item + .x = 1 + \func! + "a", "b", "c" + ...func?! + key: "value" + ... -- perform the Lua table behavior here +} + +tbMixA = { + ...[i for i = 1, 10] + 11 +} + +tbMixB = { + ... ... -- only the first item in vararg been accessed here + ... {...} + ... {......} + 1, 2, 3 +} + nil diff --git a/spec/outputs/tables.lua b/spec/outputs/tables.lua index 086e8b3..b820122 100644 --- a/spec/outputs/tables.lua +++ b/spec/outputs/tables.lua @@ -348,4 +348,106 @@ local menus = { } } } +local tb +do + local _tab_0 = { } + local _list_0 = other + for _index_0 = 1, #_list_0 do + local _value_0 = _list_0[_index_0] + _tab_0[#_tab_0 + 1] = _value_0 + end + tb = _tab_0 +end +local tbMix +do + local _tab_0 = { + 1, + 2, + 3 + } + local _obj_0 + do + local _with_0 = item + _with_0.x = 1 + _with_0:func() + _obj_0 = _with_0 + end + for _index_0 = 1, #_obj_0 do + local _value_0 = _obj_0[_index_0] + _tab_0[#_tab_0 + 1] = _value_0 + end + _tab_0[#_tab_0 + 1] = "a" + _tab_0[#_tab_0 + 1] = "b" + _tab_0[#_tab_0 + 1] = "c" + local _obj_1 + do + local _obj_2 = func + if _obj_2 ~= nil then + _obj_1 = _obj_2() + end + end + for _index_0 = 1, #_obj_1 do + local _value_0 = _obj_1[_index_0] + _tab_0[#_tab_0 + 1] = _value_0 + end + _tab_0.key = "value" + for _index_0 = 1, select('#', ...) do + _tab_0[#_tab_0 + 1] = select(_index_0, ...) + end + tbMix = _tab_0 +end +local tbMixA +do + local _tab_0 = { } + local _obj_0 + do + local _accum_0 = { } + local _len_0 = 1 + for i = 1, 10 do + _accum_0[_len_0] = i + _len_0 = _len_0 + 1 + end + _obj_0 = _accum_0 + end + for _index_0 = 1, #_obj_0 do + local _value_0 = _obj_0[_index_0] + _tab_0[#_tab_0 + 1] = _value_0 + end + _tab_0[#_tab_0 + 1] = 11 + tbMixA = _tab_0 +end +local tbMixB +do + local _tab_0 = { } + local _obj_0 = ... + for _index_0 = 1, #_obj_0 do + local _value_0 = _obj_0[_index_0] + _tab_0[#_tab_0 + 1] = _value_0 + end + local _obj_1 = { + ... + } + for _index_0 = 1, #_obj_1 do + local _value_0 = _obj_1[_index_0] + _tab_0[#_tab_0 + 1] = _value_0 + end + local _obj_2 + do + local _tab_1 = { } + local _obj_3 = ... + for _index_0 = 1, #_obj_3 do + local _value_0 = _obj_3[_index_0] + _tab_1[#_tab_1 + 1] = _value_0 + end + _obj_2 = _tab_1 + end + for _index_0 = 1, #_obj_2 do + local _value_0 = _obj_2[_index_0] + _tab_0[#_tab_0 + 1] = _value_0 + end + _tab_0[#_tab_0 + 1] = 1 + _tab_0[#_tab_0 + 1] = 2 + _tab_0[#_tab_0 + 1] = 3 + tbMixB = _tab_0 +end return nil diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 4fb14b6..4dacf42 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -4537,15 +4537,20 @@ private: switch (item->getId()) { case id(): { auto spread = static_cast(item); - std::string keyVar = getUnusedName("_key_"sv); std::string valueVar = getUnusedName("_value_"sv); - auto targetStr = _parser.toString(spread->exp); - _buf << "for "sv << keyVar << ',' << valueVar - << " in pairs! do "sv - << tableVar << '[' << keyVar << "]="sv << valueVar; + auto objVar = singleVariableFrom(spread->exp); + if (objVar.empty()) { + objVar = getUnusedName("_obj_"); + auto assignment = toAst(objVar + "=nil"s, spread); + auto assign = assignment->action.to(); + assign->values.clear(); + assign->values.push_back(spread->exp); + transformAssignment(assignment, temp); + } + _buf << "for "sv << valueVar + << " in *"sv << objVar << " do "sv + << tableVar << "[]="sv << valueVar; auto forEach = toAst(clearBuf(), spread); - auto chainValue = singleValueFrom(forEach->loopValue.to())->item.to(); - ast_to(*(++chainValue->items.objects().begin()))->args.push_back(spread->exp); transformForEach(forEach, temp); break; } @@ -4603,11 +4608,27 @@ private: break; } case id(): { - auto assignment = toAst(tableVar + "[]=nil"s, item); - auto assign = assignment->action.to(); - assign->values.clear(); - assign->values.push_back(item); - transformAssignment(assignment, temp); + bool lastVarArg = false; + BLOCK_START + BREAK_IF(item != table->values.back()); + auto value = singleValueFrom(item); + BREAK_IF(!value); + auto chainValue = value->item.as(); + BREAK_IF(!chainValue); + BREAK_IF(chainValue->items.size() != 1); + BREAK_IF((!chainValue->getByPath())); + auto indexVar = getUnusedName("_index_"); + _buf << "for "sv << indexVar << "=1,select '#',...\n\t"sv << tableVar << "[]= select "sv << indexVar << ",..."sv; + transformFor(toAst(clearBuf(), item), temp); + lastVarArg = true; + BLOCK_END + if (!lastVarArg) { + auto assignment = toAst(tableVar + "[]=nil"s, item); + auto assign = assignment->action.to(); + assign->values.clear(); + assign->values.push_back(item); + transformAssignment(assignment, temp); + } break; } default: YUEE("AST node mismatch", item); break; -- cgit v1.2.3-55-g6feb