diff options
| author | Li Jin <dragon-fly@qq.com> | 2022-04-24 11:26:46 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2022-04-24 11:26:46 +0800 |
| commit | fe6d146bc4454d8096ddd0543d7142db3da5da5b (patch) | |
| tree | dcdc4d08a8934b1b306e60f9f802ff11f22ce22b | |
| parent | 84b93d0e43e7248fd00df6957d55a954c48628d7 (diff) | |
| download | yuescript-fe6d146bc4454d8096ddd0543d7142db3da5da5b.tar.gz yuescript-fe6d146bc4454d8096ddd0543d7142db3da5da5b.tar.bz2 yuescript-fe6d146bc4454d8096ddd0543d7142db3da5da5b.zip | |
fix spreading syntax behavior.
Diffstat (limited to '')
| -rw-r--r-- | spec/inputs/tables.yue | 25 | ||||
| -rw-r--r-- | spec/outputs/tables.lua | 102 | ||||
| -rwxr-xr-x | 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 = | |||
| 237 | click: -> | 237 | click: -> |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | tb = {...other} | ||
| 241 | |||
| 242 | tbMix = { | ||
| 243 | 1, 2, 3 | ||
| 244 | ... with item | ||
| 245 | .x = 1 | ||
| 246 | \func! | ||
| 247 | "a", "b", "c" | ||
| 248 | ...func?! | ||
| 249 | key: "value" | ||
| 250 | ... -- perform the Lua table behavior here | ||
| 251 | } | ||
| 252 | |||
| 253 | tbMixA = { | ||
| 254 | ...[i for i = 1, 10] | ||
| 255 | 11 | ||
| 256 | } | ||
| 257 | |||
| 258 | tbMixB = { | ||
| 259 | ... ... -- only the first item in vararg been accessed here | ||
| 260 | ... {...} | ||
| 261 | ... {......} | ||
| 262 | 1, 2, 3 | ||
| 263 | } | ||
| 264 | |||
| 240 | nil | 265 | nil |
| 241 | 266 | ||
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 = { | |||
| 348 | } | 348 | } |
| 349 | } | 349 | } |
| 350 | } | 350 | } |
| 351 | local tb | ||
| 352 | do | ||
| 353 | local _tab_0 = { } | ||
| 354 | local _list_0 = other | ||
| 355 | for _index_0 = 1, #_list_0 do | ||
| 356 | local _value_0 = _list_0[_index_0] | ||
| 357 | _tab_0[#_tab_0 + 1] = _value_0 | ||
| 358 | end | ||
| 359 | tb = _tab_0 | ||
| 360 | end | ||
| 361 | local tbMix | ||
| 362 | do | ||
| 363 | local _tab_0 = { | ||
| 364 | 1, | ||
| 365 | 2, | ||
| 366 | 3 | ||
| 367 | } | ||
| 368 | local _obj_0 | ||
| 369 | do | ||
| 370 | local _with_0 = item | ||
| 371 | _with_0.x = 1 | ||
| 372 | _with_0:func() | ||
| 373 | _obj_0 = _with_0 | ||
| 374 | end | ||
| 375 | for _index_0 = 1, #_obj_0 do | ||
| 376 | local _value_0 = _obj_0[_index_0] | ||
| 377 | _tab_0[#_tab_0 + 1] = _value_0 | ||
| 378 | end | ||
| 379 | _tab_0[#_tab_0 + 1] = "a" | ||
| 380 | _tab_0[#_tab_0 + 1] = "b" | ||
| 381 | _tab_0[#_tab_0 + 1] = "c" | ||
| 382 | local _obj_1 | ||
| 383 | do | ||
| 384 | local _obj_2 = func | ||
| 385 | if _obj_2 ~= nil then | ||
| 386 | _obj_1 = _obj_2() | ||
| 387 | end | ||
| 388 | end | ||
| 389 | for _index_0 = 1, #_obj_1 do | ||
| 390 | local _value_0 = _obj_1[_index_0] | ||
| 391 | _tab_0[#_tab_0 + 1] = _value_0 | ||
| 392 | end | ||
| 393 | _tab_0.key = "value" | ||
| 394 | for _index_0 = 1, select('#', ...) do | ||
| 395 | _tab_0[#_tab_0 + 1] = select(_index_0, ...) | ||
| 396 | end | ||
| 397 | tbMix = _tab_0 | ||
| 398 | end | ||
| 399 | local tbMixA | ||
| 400 | do | ||
| 401 | local _tab_0 = { } | ||
| 402 | local _obj_0 | ||
| 403 | do | ||
| 404 | local _accum_0 = { } | ||
| 405 | local _len_0 = 1 | ||
| 406 | for i = 1, 10 do | ||
| 407 | _accum_0[_len_0] = i | ||
| 408 | _len_0 = _len_0 + 1 | ||
| 409 | end | ||
| 410 | _obj_0 = _accum_0 | ||
| 411 | end | ||
| 412 | for _index_0 = 1, #_obj_0 do | ||
| 413 | local _value_0 = _obj_0[_index_0] | ||
| 414 | _tab_0[#_tab_0 + 1] = _value_0 | ||
| 415 | end | ||
| 416 | _tab_0[#_tab_0 + 1] = 11 | ||
| 417 | tbMixA = _tab_0 | ||
| 418 | end | ||
| 419 | local tbMixB | ||
| 420 | do | ||
| 421 | local _tab_0 = { } | ||
| 422 | local _obj_0 = ... | ||
| 423 | for _index_0 = 1, #_obj_0 do | ||
| 424 | local _value_0 = _obj_0[_index_0] | ||
| 425 | _tab_0[#_tab_0 + 1] = _value_0 | ||
| 426 | end | ||
| 427 | local _obj_1 = { | ||
| 428 | ... | ||
| 429 | } | ||
| 430 | for _index_0 = 1, #_obj_1 do | ||
| 431 | local _value_0 = _obj_1[_index_0] | ||
| 432 | _tab_0[#_tab_0 + 1] = _value_0 | ||
| 433 | end | ||
| 434 | local _obj_2 | ||
| 435 | do | ||
| 436 | local _tab_1 = { } | ||
| 437 | local _obj_3 = ... | ||
| 438 | for _index_0 = 1, #_obj_3 do | ||
| 439 | local _value_0 = _obj_3[_index_0] | ||
| 440 | _tab_1[#_tab_1 + 1] = _value_0 | ||
| 441 | end | ||
| 442 | _obj_2 = _tab_1 | ||
| 443 | end | ||
| 444 | for _index_0 = 1, #_obj_2 do | ||
| 445 | local _value_0 = _obj_2[_index_0] | ||
| 446 | _tab_0[#_tab_0 + 1] = _value_0 | ||
| 447 | end | ||
| 448 | _tab_0[#_tab_0 + 1] = 1 | ||
| 449 | _tab_0[#_tab_0 + 1] = 2 | ||
| 450 | _tab_0[#_tab_0 + 1] = 3 | ||
| 451 | tbMixB = _tab_0 | ||
| 452 | end | ||
| 351 | return nil | 453 | 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: | |||
| 4537 | switch (item->getId()) { | 4537 | switch (item->getId()) { |
| 4538 | case id<SpreadExp_t>(): { | 4538 | case id<SpreadExp_t>(): { |
| 4539 | auto spread = static_cast<SpreadExp_t*>(item); | 4539 | auto spread = static_cast<SpreadExp_t*>(item); |
| 4540 | std::string keyVar = getUnusedName("_key_"sv); | ||
| 4541 | std::string valueVar = getUnusedName("_value_"sv); | 4540 | std::string valueVar = getUnusedName("_value_"sv); |
| 4542 | auto targetStr = _parser.toString(spread->exp); | 4541 | auto objVar = singleVariableFrom(spread->exp); |
| 4543 | _buf << "for "sv << keyVar << ',' << valueVar | 4542 | if (objVar.empty()) { |
| 4544 | << " in pairs! do "sv | 4543 | objVar = getUnusedName("_obj_"); |
| 4545 | << tableVar << '[' << keyVar << "]="sv << valueVar; | 4544 | auto assignment = toAst<ExpListAssign_t>(objVar + "=nil"s, spread); |
| 4545 | auto assign = assignment->action.to<Assign_t>(); | ||
| 4546 | assign->values.clear(); | ||
| 4547 | assign->values.push_back(spread->exp); | ||
| 4548 | transformAssignment(assignment, temp); | ||
| 4549 | } | ||
| 4550 | _buf << "for "sv << valueVar | ||
| 4551 | << " in *"sv << objVar << " do "sv | ||
| 4552 | << tableVar << "[]="sv << valueVar; | ||
| 4546 | auto forEach = toAst<ForEach_t>(clearBuf(), spread); | 4553 | auto forEach = toAst<ForEach_t>(clearBuf(), spread); |
| 4547 | auto chainValue = singleValueFrom(forEach->loopValue.to<ExpList_t>())->item.to<ChainValue_t>(); | ||
| 4548 | ast_to<Invoke_t>(*(++chainValue->items.objects().begin()))->args.push_back(spread->exp); | ||
| 4549 | transformForEach(forEach, temp); | 4554 | transformForEach(forEach, temp); |
| 4550 | break; | 4555 | break; |
| 4551 | } | 4556 | } |
| @@ -4603,11 +4608,27 @@ private: | |||
| 4603 | break; | 4608 | break; |
| 4604 | } | 4609 | } |
| 4605 | case id<Exp_t>(): { | 4610 | case id<Exp_t>(): { |
| 4606 | auto assignment = toAst<ExpListAssign_t>(tableVar + "[]=nil"s, item); | 4611 | bool lastVarArg = false; |
| 4607 | auto assign = assignment->action.to<Assign_t>(); | 4612 | BLOCK_START |
| 4608 | assign->values.clear(); | 4613 | BREAK_IF(item != table->values.back()); |
| 4609 | assign->values.push_back(item); | 4614 | auto value = singleValueFrom(item); |
| 4610 | transformAssignment(assignment, temp); | 4615 | BREAK_IF(!value); |
| 4616 | auto chainValue = value->item.as<ChainValue_t>(); | ||
| 4617 | BREAK_IF(!chainValue); | ||
| 4618 | BREAK_IF(chainValue->items.size() != 1); | ||
| 4619 | BREAK_IF((!chainValue->getByPath<Callable_t,VarArg_t>())); | ||
| 4620 | auto indexVar = getUnusedName("_index_"); | ||
| 4621 | _buf << "for "sv << indexVar << "=1,select '#',...\n\t"sv << tableVar << "[]= select "sv << indexVar << ",..."sv; | ||
| 4622 | transformFor(toAst<For_t>(clearBuf(), item), temp); | ||
| 4623 | lastVarArg = true; | ||
| 4624 | BLOCK_END | ||
| 4625 | if (!lastVarArg) { | ||
| 4626 | auto assignment = toAst<ExpListAssign_t>(tableVar + "[]=nil"s, item); | ||
| 4627 | auto assign = assignment->action.to<Assign_t>(); | ||
| 4628 | assign->values.clear(); | ||
| 4629 | assign->values.push_back(item); | ||
| 4630 | transformAssignment(assignment, temp); | ||
| 4631 | } | ||
| 4611 | break; | 4632 | break; |
| 4612 | } | 4633 | } |
| 4613 | default: YUEE("AST node mismatch", item); break; | 4634 | default: YUEE("AST node mismatch", item); break; |
