aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
parentfe6d146bc4454d8096ddd0543d7142db3da5da5b (diff)
downloadyuescript-249e1de1d32dda2b60b9116c5a4e538475de0192.tar.gz
yuescript-249e1de1d32dda2b60b9116c5a4e538475de0192.tar.bz2
yuescript-249e1de1d32dda2b60b9116c5a4e538475de0192.zip
add support for the Fill Operator. fix issue #39.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp326
1 files changed, 168 insertions, 158 deletions
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