aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-04-24 11:26:46 +0800
committerLi Jin <dragon-fly@qq.com>2022-04-24 11:26:46 +0800
commitfe6d146bc4454d8096ddd0543d7142db3da5da5b (patch)
treedcdc4d08a8934b1b306e60f9f802ff11f22ce22b /src
parent84b93d0e43e7248fd00df6957d55a954c48628d7 (diff)
downloadyuescript-fe6d146bc4454d8096ddd0543d7142db3da5da5b.tar.gz
yuescript-fe6d146bc4454d8096ddd0543d7142db3da5da5b.tar.bz2
yuescript-fe6d146bc4454d8096ddd0543d7142db3da5da5b.zip
fix spreading syntax behavior.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp45
1 files changed, 33 insertions, 12 deletions
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;