aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-04-24 15:35:53 +0800
committerLi Jin <dragon-fly@qq.com>2022-04-24 15:35:53 +0800
commit249e1de1d32dda2b60b9116c5a4e538475de0192 (patch)
treed62b95ba79cd8b226fe2f8ae172bf646c12bff91
parentfe6d146bc4454d8096ddd0543d7142db3da5da5b (diff)
downloadyuescript-249e1de1d32dda2b60b9116c5a4e538475de0192.tar.gz
yuescript-249e1de1d32dda2b60b9116c5a4e538475de0192.tar.bz2
yuescript-249e1de1d32dda2b60b9116c5a4e538475de0192.zip
add support for the Fill Operator. fix issue #39.
-rw-r--r--spec/inputs/tables.yue19
-rw-r--r--spec/outputs/tables.lua127
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp326
3 files changed, 289 insertions, 183 deletions
diff --git a/spec/inputs/tables.yue b/spec/inputs/tables.yue
index 649c1dc..3a245a7 100644
--- a/spec/inputs/tables.yue
+++ b/spec/inputs/tables.yue
@@ -262,5 +262,24 @@ tbMixB = {
262 1, 2, 3 262 1, 2, 3
263} 263}
264 264
265const template = {
266 foo: "Hello"
267 bar: "World"
268 baz: "!"
269}
270
271const specialized = {
272 ...template
273 bar: "Bob"
274}
275
276specializedB = {
277 function: ->
278 ...template
279 end: ->
280 if: true
281 else: false
282}
283
265nil 284nil
266 285
diff --git a/spec/outputs/tables.lua b/spec/outputs/tables.lua
index b820122..165706d 100644
--- a/spec/outputs/tables.lua
+++ b/spec/outputs/tables.lua
@@ -351,10 +351,14 @@ local menus = {
351local tb 351local tb
352do 352do
353 local _tab_0 = { } 353 local _tab_0 = { }
354 local _list_0 = other 354 local _idx_0 = 1
355 for _index_0 = 1, #_list_0 do 355 for _key_0, _value_0 in pairs(other) do
356 local _value_0 = _list_0[_index_0] 356 if _idx_0 == _key_0 then
357 _tab_0[#_tab_0 + 1] = _value_0 357 _tab_0[#_tab_0 + 1] = _value_0
358 _idx_0 = _idx_0 + 1
359 else
360 _tab_0[_key_0] = _value_0
361 end
358 end 362 end
359 tb = _tab_0 363 tb = _tab_0
360end 364end
@@ -372,9 +376,14 @@ do
372 _with_0:func() 376 _with_0:func()
373 _obj_0 = _with_0 377 _obj_0 = _with_0
374 end 378 end
375 for _index_0 = 1, #_obj_0 do 379 local _idx_0 = 1
376 local _value_0 = _obj_0[_index_0] 380 for _key_0, _value_0 in pairs(_obj_0) do
377 _tab_0[#_tab_0 + 1] = _value_0 381 if _idx_0 == _key_0 then
382 _tab_0[#_tab_0 + 1] = _value_0
383 _idx_0 = _idx_0 + 1
384 else
385 _tab_0[_key_0] = _value_0
386 end
378 end 387 end
379 _tab_0[#_tab_0 + 1] = "a" 388 _tab_0[#_tab_0 + 1] = "a"
380 _tab_0[#_tab_0 + 1] = "b" 389 _tab_0[#_tab_0 + 1] = "b"
@@ -386,9 +395,14 @@ do
386 _obj_1 = _obj_2() 395 _obj_1 = _obj_2()
387 end 396 end
388 end 397 end
389 for _index_0 = 1, #_obj_1 do 398 local _idx_1 = 1
390 local _value_0 = _obj_1[_index_0] 399 for _key_0, _value_0 in pairs(_obj_1) do
391 _tab_0[#_tab_0 + 1] = _value_0 400 if _idx_1 == _key_0 then
401 _tab_0[#_tab_0 + 1] = _value_0
402 _idx_1 = _idx_1 + 1
403 else
404 _tab_0[_key_0] = _value_0
405 end
392 end 406 end
393 _tab_0.key = "value" 407 _tab_0.key = "value"
394 for _index_0 = 1, select('#', ...) do 408 for _index_0 = 1, select('#', ...) do
@@ -409,9 +423,14 @@ do
409 end 423 end
410 _obj_0 = _accum_0 424 _obj_0 = _accum_0
411 end 425 end
412 for _index_0 = 1, #_obj_0 do 426 local _idx_0 = 1
413 local _value_0 = _obj_0[_index_0] 427 for _key_0, _value_0 in pairs(_obj_0) do
414 _tab_0[#_tab_0 + 1] = _value_0 428 if _idx_0 == _key_0 then
429 _tab_0[#_tab_0 + 1] = _value_0
430 _idx_0 = _idx_0 + 1
431 else
432 _tab_0[_key_0] = _value_0
433 end
415 end 434 end
416 _tab_0[#_tab_0 + 1] = 11 435 _tab_0[#_tab_0 + 1] = 11
417 tbMixA = _tab_0 436 tbMixA = _tab_0
@@ -420,34 +439,92 @@ local tbMixB
420do 439do
421 local _tab_0 = { } 440 local _tab_0 = { }
422 local _obj_0 = ... 441 local _obj_0 = ...
423 for _index_0 = 1, #_obj_0 do 442 local _idx_0 = 1
424 local _value_0 = _obj_0[_index_0] 443 for _key_0, _value_0 in pairs(_obj_0) do
425 _tab_0[#_tab_0 + 1] = _value_0 444 if _idx_0 == _key_0 then
445 _tab_0[#_tab_0 + 1] = _value_0
446 _idx_0 = _idx_0 + 1
447 else
448 _tab_0[_key_0] = _value_0
449 end
426 end 450 end
427 local _obj_1 = { 451 local _obj_1 = {
428 ... 452 ...
429 } 453 }
430 for _index_0 = 1, #_obj_1 do 454 local _idx_1 = 1
431 local _value_0 = _obj_1[_index_0] 455 for _key_0, _value_0 in pairs(_obj_1) do
432 _tab_0[#_tab_0 + 1] = _value_0 456 if _idx_1 == _key_0 then
457 _tab_0[#_tab_0 + 1] = _value_0
458 _idx_1 = _idx_1 + 1
459 else
460 _tab_0[_key_0] = _value_0
461 end
433 end 462 end
434 local _obj_2 463 local _obj_2
435 do 464 do
436 local _tab_1 = { } 465 local _tab_1 = { }
437 local _obj_3 = ... 466 local _obj_3 = ...
438 for _index_0 = 1, #_obj_3 do 467 local _idx_2 = 1
439 local _value_0 = _obj_3[_index_0] 468 for _key_0, _value_0 in pairs(_obj_3) do
440 _tab_1[#_tab_1 + 1] = _value_0 469 if _idx_2 == _key_0 then
470 _tab_1[#_tab_1 + 1] = _value_0
471 _idx_2 = _idx_2 + 1
472 else
473 _tab_1[_key_0] = _value_0
474 end
441 end 475 end
442 _obj_2 = _tab_1 476 _obj_2 = _tab_1
443 end 477 end
444 for _index_0 = 1, #_obj_2 do 478 local _idx_2 = 1
445 local _value_0 = _obj_2[_index_0] 479 for _key_0, _value_0 in pairs(_obj_2) do
446 _tab_0[#_tab_0 + 1] = _value_0 480 if _idx_2 == _key_0 then
481 _tab_0[#_tab_0 + 1] = _value_0
482 _idx_2 = _idx_2 + 1
483 else
484 _tab_0[_key_0] = _value_0
485 end
447 end 486 end
448 _tab_0[#_tab_0 + 1] = 1 487 _tab_0[#_tab_0 + 1] = 1
449 _tab_0[#_tab_0 + 1] = 2 488 _tab_0[#_tab_0 + 1] = 2
450 _tab_0[#_tab_0 + 1] = 3 489 _tab_0[#_tab_0 + 1] = 3
451 tbMixB = _tab_0 490 tbMixB = _tab_0
452end 491end
492local template <const> = {
493 foo = "Hello",
494 bar = "World",
495 baz = "!"
496}
497local specialized <const> = (function()
498 local _tab_0 = { }
499 local _idx_0 = 1
500 for _key_0, _value_0 in pairs(template) do
501 if _idx_0 == _key_0 then
502 _tab_0[#_tab_0 + 1] = _value_0
503 _idx_0 = _idx_0 + 1
504 else
505 _tab_0[_key_0] = _value_0
506 end
507 end
508 _tab_0.bar = "Bob"
509 return _tab_0
510end)()
511local specializedB
512do
513 local _tab_0 = {
514 ["function"] = function() end
515 }
516 local _idx_0 = 1
517 for _key_0, _value_0 in pairs(template) do
518 if _idx_0 == _key_0 then
519 _tab_0[#_tab_0 + 1] = _value_0
520 _idx_0 = _idx_0 + 1
521 else
522 _tab_0[_key_0] = _value_0
523 end
524 end
525 _tab_0["end"] = function() end
526 _tab_0["if"] = true
527 _tab_0["else"] = false
528 specializedB = _tab_0
529end
453return nil 530return nil
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 4dacf42..6a0fba6 100755
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -1358,7 +1358,7 @@ private:
1358 if (hasSpreadExp(tableLit)) { 1358 if (hasSpreadExp(tableLit)) {
1359 auto expList = assignment->expList.get(); 1359 auto expList = assignment->expList.get();
1360 std::string preDefine = getPredefine(assignment); 1360 std::string preDefine = getPredefine(assignment);
1361 transformTableLit(tableLit, out, true, ExpUsage::Assignment, expList); 1361 transformSpreadTableLit(tableLit, out, ExpUsage::Assignment, expList);
1362 out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); 1362 out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment));
1363 return; 1363 return;
1364 } 1364 }
@@ -2675,7 +2675,7 @@ private:
2675 case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Closure); break; 2675 case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Closure); break;
2676 case id<unary_value_t>(): transform_unary_value(static_cast<unary_value_t*>(value), out); break; 2676 case id<unary_value_t>(): transform_unary_value(static_cast<unary_value_t*>(value), out); break;
2677 case id<TblComprehension_t>(): transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Closure); break; 2677 case id<TblComprehension_t>(): transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Closure); break;
2678 case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(value), out, false, ExpUsage::Closure); break; 2678 case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(value), out); break;
2679 case id<Comprehension_t>(): transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Closure); break; 2679 case id<Comprehension_t>(): transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Closure); break;
2680 case id<FunLit_t>(): transformFunLit(static_cast<FunLit_t*>(value), out); break; 2680 case id<FunLit_t>(): transformFunLit(static_cast<FunLit_t*>(value), out); break;
2681 case id<Num_t>(): transformNum(static_cast<Num_t*>(value), out); break; 2681 case id<Num_t>(): transformNum(static_cast<Num_t*>(value), out); break;
@@ -3287,7 +3287,7 @@ private:
3287 case id<TableLit_t>(): { 3287 case id<TableLit_t>(): {
3288 auto tableLit = static_cast<TableLit_t*>(value); 3288 auto tableLit = static_cast<TableLit_t*>(value);
3289 if (hasSpreadExp(tableLit)) { 3289 if (hasSpreadExp(tableLit)) {
3290 transformTableLit(tableLit, out, true, ExpUsage::Return); 3290 transformSpreadTableLit(tableLit, out, ExpUsage::Return);
3291 return; 3291 return;
3292 } 3292 }
3293 } 3293 }
@@ -4452,7 +4452,7 @@ private:
4452 case id<SingleString_t>(): transformSingleString(static_cast<SingleString_t*>(arg), temp); break; 4452 case id<SingleString_t>(): transformSingleString(static_cast<SingleString_t*>(arg), temp); break;
4453 case id<DoubleString_t>(): transformDoubleString(static_cast<DoubleString_t*>(arg), temp); break; 4453 case id<DoubleString_t>(): transformDoubleString(static_cast<DoubleString_t*>(arg), temp); break;
4454 case id<LuaString_t>(): transformLuaString(static_cast<LuaString_t*>(arg), temp); break; 4454 case id<LuaString_t>(): transformLuaString(static_cast<LuaString_t*>(arg), temp); break;
4455 case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(arg), temp, false, ExpUsage::Closure); break; 4455 case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(arg), temp); break;
4456 default: YUEE("AST node mismatch", arg); break; 4456 default: YUEE("AST node mismatch", arg); break;
4457 } 4457 }
4458 } 4458 }
@@ -4502,173 +4502,183 @@ private:
4502 return false; 4502 return false;
4503 } 4503 }
4504 4504
4505 void transformTableLit(TableLit_t* table, str_list& out, bool spreading, ExpUsage usage, ExpList_t* assignList = nullptr) { 4505 void transformTableLit(TableLit_t* table, str_list& out) {
4506 if (spreading) { 4506 if (hasSpreadExp(table)) {
4507 auto x = table; 4507 transformSpreadTableLit(table, out, ExpUsage::Closure);
4508 switch (usage) { 4508 } else {
4509 case ExpUsage::Closure: 4509 transformTable(table, table->values.objects(), out);
4510 _enableReturn.push(true); 4510 }
4511 pushAnonVarArg(); 4511 }
4512 pushScope(); 4512
4513 break; 4513 void transformSpreadTableLit(TableLit_t* table, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
4514 case ExpUsage::Assignment: 4514 auto x = table;
4515 pushScope(); 4515 switch (usage) {
4516 break; 4516 case ExpUsage::Closure:
4517 default: 4517 _enableReturn.push(true);
4518 break; 4518 pushAnonVarArg();
4519 pushScope();
4520 break;
4521 case ExpUsage::Assignment:
4522 pushScope();
4523 break;
4524 default:
4525 break;
4526 }
4527 str_list temp;
4528 std::string tableVar = getUnusedName("_tab_"sv);
4529 forceAddToScope(tableVar);
4530 auto it = table->values.objects().begin();
4531 if (ast_is<SpreadExp_t>(*it)) {
4532 temp.push_back(indent() + "local "s + tableVar + " = { }"s + nll(x));
4533 } else {
4534 auto initialTab = x->new_ptr<TableLit_t>();
4535 while (it != table->values.objects().end() && !ast_is<SpreadExp_t>(*it)) {
4536 initialTab->values.push_back(*it);
4537 ++it;
4519 } 4538 }
4520 str_list temp; 4539 transformTable(table, initialTab->values.objects(), temp);
4521 std::string tableVar = getUnusedName("_tab_"sv); 4540 temp.back() = indent() + "local "s + tableVar + " = "s + temp.back() + nll(*it);
4522 forceAddToScope(tableVar); 4541 }
4523 auto it = table->values.objects().begin(); 4542 for (; it != table->values.objects().end(); ++it) {
4524 if (ast_is<SpreadExp_t>(*it)) { 4543 auto item = *it;
4525 temp.push_back(indent() + "local "s + tableVar + " = { }"s + nll(x)); 4544 switch (item->getId()) {
4526 } else { 4545 case id<SpreadExp_t>(): {
4527 auto initialTab = x->new_ptr<TableLit_t>(); 4546 auto spread = static_cast<SpreadExp_t*>(item);
4528 while (it != table->values.objects().end() && !ast_is<SpreadExp_t>(*it)) { 4547 std::string indexVar = getUnusedName("_idx_"sv);
4529 initialTab->values.push_back(*it); 4548 std::string keyVar = getUnusedName("_key_"sv);
4530 ++it; 4549 std::string valueVar = getUnusedName("_value_"sv);
4531 } 4550 auto objVar = singleVariableFrom(spread->exp);
4532 transformTableLit(initialTab, temp, false, ExpUsage::Closure); 4551 if (objVar.empty()) {
4533 temp.back() = indent() + "local "s + tableVar + " = "s + temp.back() + nll(*it); 4552 objVar = getUnusedName("_obj_");
4534 } 4553 auto assignment = toAst<ExpListAssign_t>(objVar + "=nil"s, item);
4535 for (; it != table->values.objects().end(); ++it) {
4536 auto item = *it;
4537 switch (item->getId()) {
4538 case id<SpreadExp_t>(): {
4539 auto spread = static_cast<SpreadExp_t*>(item);
4540 std::string valueVar = getUnusedName("_value_"sv);
4541 auto objVar = singleVariableFrom(spread->exp);
4542 if (objVar.empty()) {
4543 objVar = getUnusedName("_obj_");
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;
4553 auto forEach = toAst<ForEach_t>(clearBuf(), spread);
4554 transformForEach(forEach, temp);
4555 break;
4556 }
4557 case id<variable_pair_t>(): {
4558 auto variablePair = static_cast<variable_pair_t*>(item);
4559 auto nameStr = _parser.toString(variablePair->name);
4560 auto assignment = toAst<ExpListAssign_t>(tableVar + '.' + nameStr + '=' + nameStr, item);
4561 transformAssignment(assignment, temp);
4562 break;
4563 }
4564 case id<normal_pair_t>(): {
4565 auto normalPair = static_cast<normal_pair_t*>(item);
4566 auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item);
4567 auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>();
4568 auto key = normalPair->key.get();
4569 switch (key->getId()) {
4570 case id<KeyName_t>(): {
4571 auto keyName = static_cast<KeyName_t*>(key);
4572 ast_ptr<false, ast_node> chainItem;
4573 if (auto name = keyName->name.as<Name_t>()) {
4574 auto dotItem = x->new_ptr<DotChainItem_t>();
4575 dotItem->name.set(name);
4576 chainItem = dotItem.get();
4577 } else {
4578 auto selfName = keyName->name.to<SelfName_t>();
4579 auto callable = x->new_ptr<Callable_t>();
4580 callable->item.set(selfName);
4581 auto chainValue = x->new_ptr<ChainValue_t>();
4582 chainValue->items.push_back(callable);
4583 auto value = x->new_ptr<Value_t>();
4584 value->item.set(chainValue);
4585 auto exp = newExp(value, key);
4586 chainItem = exp.get();
4587 }
4588 chainValue->items.push_back(chainItem);
4589 break;
4590 }
4591 case id<Exp_t>():
4592 chainValue->items.push_back(key);
4593 break;
4594 case id<DoubleString_t>():
4595 case id<SingleString_t>():
4596 case id<LuaString_t>(): {
4597 auto strNode = x->new_ptr<String_t>();
4598 strNode->str.set(key);
4599 chainValue->items.push_back(strNode);
4600 break;
4601 }
4602 default: YUEE("AST node mismatch", key); break;
4603 }
4604 auto assign = assignment->action.to<Assign_t>(); 4554 auto assign = assignment->action.to<Assign_t>();
4605 assign->values.clear(); 4555 assign->values.clear();
4606 assign->values.push_back(normalPair->value); 4556 assign->values.push_back(spread->exp);
4607 transformAssignment(assignment, temp); 4557 transformAssignment(assignment, temp);
4608 break;
4609 }
4610 case id<Exp_t>(): {
4611 bool lastVarArg = false;
4612 BLOCK_START
4613 BREAK_IF(item != table->values.back());
4614 auto value = singleValueFrom(item);
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 }
4632 break;
4633 } 4558 }
4634 default: YUEE("AST node mismatch", item); break; 4559 forceAddToScope(indexVar);
4635 } 4560 temp.push_back(indent() + "local "s + indexVar + " = 1"s + nll(item));
4636 } 4561 _buf << "for "sv << keyVar << ',' << valueVar << " in pairs "sv << objVar
4637 switch (usage) { 4562 << "\n\tif "sv << indexVar << "=="sv << keyVar
4638 case ExpUsage::Common: 4563 << "\n\t\t"sv << tableVar << "[]="sv << valueVar
4639 break; 4564 << "\n\t\t"sv << indexVar << "+=1"sv
4640 case ExpUsage::Closure: { 4565 << "\n\telse "sv << tableVar << '[' << keyVar << "]="sv << valueVar;
4641 out.push_back(join(temp)); 4566 auto forEach = toAst<ForEach_t>(clearBuf(), item);
4642 out.back().append(indent() + "return "s + tableVar + nlr(x)); 4567 transformForEach(forEach, temp);
4643 popScope();
4644 out.back().insert(0, anonFuncStart() + nll(x));
4645 out.back().append(indent() + anonFuncEnd());
4646 popAnonVarArg();
4647 _enableReturn.pop();
4648 break; 4568 break;
4649 } 4569 }
4650 case ExpUsage::Assignment: { 4570 case id<variable_pair_t>(): {
4651 auto assign = x->new_ptr<Assign_t>(); 4571 auto variablePair = static_cast<variable_pair_t*>(item);
4652 assign->values.push_back(toAst<Exp_t>(tableVar, x)); 4572 auto nameStr = _parser.toString(variablePair->name);
4653 auto assignment = x->new_ptr<ExpListAssign_t>(); 4573 auto assignment = toAst<ExpListAssign_t>(tableVar + '.' + nameStr + '=' + nameStr, item);
4654 assignment->expList.set(assignList);
4655 assignment->action.set(assign);
4656 transformAssignment(assignment, temp); 4574 transformAssignment(assignment, temp);
4657 popScope();
4658 out.push_back(join(temp));
4659 out.back() = indent() + "do"s + nll(x) +
4660 out.back() + indent() + "end"s + nlr(x);
4661 break; 4575 break;
4662 } 4576 }
4663 case ExpUsage::Return: 4577 case id<normal_pair_t>(): {
4664 out.push_back(join(temp)); 4578 auto normalPair = static_cast<normal_pair_t*>(item);
4665 out.back().append(indent() + "return "s + tableVar + nlr(x)); 4579 auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item);
4580 auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>();
4581 auto key = normalPair->key.get();
4582 switch (key->getId()) {
4583 case id<KeyName_t>(): {
4584 auto keyName = static_cast<KeyName_t*>(key);
4585 ast_ptr<false, ast_node> chainItem;
4586 if (auto name = keyName->name.as<Name_t>()) {
4587 auto dotItem = x->new_ptr<DotChainItem_t>();
4588 dotItem->name.set(name);
4589 chainItem = dotItem.get();
4590 } else {
4591 auto selfName = keyName->name.to<SelfName_t>();
4592 auto callable = x->new_ptr<Callable_t>();
4593 callable->item.set(selfName);
4594 auto chainValue = x->new_ptr<ChainValue_t>();
4595 chainValue->items.push_back(callable);
4596 auto value = x->new_ptr<Value_t>();
4597 value->item.set(chainValue);
4598 auto exp = newExp(value, key);
4599 chainItem = exp.get();
4600 }
4601 chainValue->items.push_back(chainItem);
4602 break;
4603 }
4604 case id<Exp_t>():
4605 chainValue->items.push_back(key);
4606 break;
4607 case id<DoubleString_t>():
4608 case id<SingleString_t>():
4609 case id<LuaString_t>(): {
4610 auto strNode = x->new_ptr<String_t>();
4611 strNode->str.set(key);
4612 chainValue->items.push_back(strNode);
4613 break;
4614 }
4615 default: YUEE("AST node mismatch", key); break;
4616 }
4617 auto assign = assignment->action.to<Assign_t>();
4618 assign->values.clear();
4619 assign->values.push_back(normalPair->value);
4620 transformAssignment(assignment, temp);
4666 break; 4621 break;
4667 default: 4622 }
4623 case id<Exp_t>(): {
4624 bool lastVarArg = false;
4625 BLOCK_START
4626 BREAK_IF(item != table->values.back());
4627 auto value = singleValueFrom(item);
4628 BREAK_IF(!value);
4629 auto chainValue = value->item.as<ChainValue_t>();
4630 BREAK_IF(!chainValue);
4631 BREAK_IF(chainValue->items.size() != 1);
4632 BREAK_IF((!chainValue->getByPath<Callable_t,VarArg_t>()));
4633 auto indexVar = getUnusedName("_index_");
4634 _buf << "for "sv << indexVar << "=1,select '#',...\n\t"sv << tableVar << "[]= select "sv << indexVar << ",..."sv;
4635 transformFor(toAst<For_t>(clearBuf(), item), temp);
4636 lastVarArg = true;
4637 BLOCK_END
4638 if (!lastVarArg) {
4639 auto assignment = toAst<ExpListAssign_t>(tableVar + "[]=nil"s, item);
4640 auto assign = assignment->action.to<Assign_t>();
4641 assign->values.clear();
4642 assign->values.push_back(item);
4643 transformAssignment(assignment, temp);
4644 }
4668 break; 4645 break;
4646 }
4647 default: YUEE("AST node mismatch", item); break;
4669 } 4648 }
4670 } else { 4649 }
4671 transformTable(table, table->values.objects(), out); 4650 switch (usage) {
4651 case ExpUsage::Common:
4652 break;
4653 case ExpUsage::Closure: {
4654 out.push_back(join(temp));
4655 out.back().append(indent() + "return "s + tableVar + nlr(x));
4656 popScope();
4657 out.back().insert(0, anonFuncStart() + nll(x));
4658 out.back().append(indent() + anonFuncEnd());
4659 popAnonVarArg();
4660 _enableReturn.pop();
4661 break;
4662 }
4663 case ExpUsage::Assignment: {
4664 auto assign = x->new_ptr<Assign_t>();
4665 assign->values.push_back(toAst<Exp_t>(tableVar, x));
4666 auto assignment = x->new_ptr<ExpListAssign_t>();
4667 assignment->expList.set(assignList);
4668 assignment->action.set(assign);
4669 transformAssignment(assignment, temp);
4670 popScope();
4671 out.push_back(join(temp));
4672 out.back() = indent() + "do"s + nll(x) +
4673 out.back() + indent() + "end"s + nlr(x);
4674 break;
4675 }
4676 case ExpUsage::Return:
4677 out.push_back(join(temp));
4678 out.back().append(indent() + "return "s + tableVar + nlr(x));
4679 break;
4680 default:
4681 break;
4672 } 4682 }
4673 } 4683 }
4674 4684