diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 83 |
1 files changed, 75 insertions, 8 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 33161a7..d7d117a 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 78 | "close"s // Lua 5.4 | 78 | "close"s // Lua 5.4 |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | const std::string_view version = "0.29.4"sv; | 81 | const std::string_view version = "0.29.5"sv; |
| 82 | const std::string_view extension = "yue"sv; | 82 | const std::string_view extension = "yue"sv; |
| 83 | 83 | ||
| 84 | class CompileError : public std::logic_error { | 84 | class CompileError : public std::logic_error { |
| @@ -1445,6 +1445,7 @@ private: | |||
| 1445 | case id<DotChainItem_t>(): | 1445 | case id<DotChainItem_t>(): |
| 1446 | case id<Exp_t>(): | 1446 | case id<Exp_t>(): |
| 1447 | case id<TableAppendingOp_t>(): | 1447 | case id<TableAppendingOp_t>(): |
| 1448 | case id<ReversedIndex_t>(): | ||
| 1448 | return true; | 1449 | return true; |
| 1449 | } | 1450 | } |
| 1450 | } | 1451 | } |
| @@ -2254,7 +2255,8 @@ private: | |||
| 2254 | BREAK_IF(!value); | 2255 | BREAK_IF(!value); |
| 2255 | auto chainValue = value->item.as<ChainValue_t>(); | 2256 | auto chainValue = value->item.as<ChainValue_t>(); |
| 2256 | BREAK_IF(!chainValue); | 2257 | BREAK_IF(!chainValue); |
| 2257 | if (auto dot = ast_cast<DotChainItem_t>(chainValue->items.back())) { | 2258 | auto last = chainValue->items.back(); |
| 2259 | if (auto dot = ast_cast<DotChainItem_t>(last)) { | ||
| 2258 | BREAK_IF(!dot->name.is<Metatable_t>()); | 2260 | BREAK_IF(!dot->name.is<Metatable_t>()); |
| 2259 | str_list temp; | 2261 | str_list temp; |
| 2260 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | 2262 | auto [beforeAssignment, afterAssignment] = splitAssignment(); |
| @@ -2285,7 +2287,7 @@ private: | |||
| 2285 | } | 2287 | } |
| 2286 | out.push_back(join(temp)); | 2288 | out.push_back(join(temp)); |
| 2287 | return false; | 2289 | return false; |
| 2288 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { | 2290 | } else if (ast_is<TableAppendingOp_t>(last)) { |
| 2289 | str_list temp; | 2291 | str_list temp; |
| 2290 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | 2292 | auto [beforeAssignment, afterAssignment] = splitAssignment(); |
| 2291 | if (!beforeAssignment->expList->exprs.empty()) { | 2293 | if (!beforeAssignment->expList->exprs.empty()) { |
| @@ -2337,6 +2339,44 @@ private: | |||
| 2337 | } | 2339 | } |
| 2338 | out.push_back(join(temp)); | 2340 | out.push_back(join(temp)); |
| 2339 | return false; | 2341 | return false; |
| 2342 | } else if (ast_is<ReversedIndex_t>(last)) { | ||
| 2343 | if (chainValue->items.size() == 1) { | ||
| 2344 | if (_withVars.empty()) { | ||
| 2345 | throw CompileError("short dot/colon syntax must be called within a with block"sv, x); | ||
| 2346 | } else { | ||
| 2347 | break; | ||
| 2348 | } | ||
| 2349 | } | ||
| 2350 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); | ||
| 2351 | tmpChain->items.dup(chainValue->items); | ||
| 2352 | tmpChain->items.pop_back(); | ||
| 2353 | auto tmpLeft = newExp(tmpChain, tmpChain); | ||
| 2354 | auto leftVar = singleVariableFrom(tmpLeft, AccessType::Read); | ||
| 2355 | if (!leftVar.empty() && isLocal(leftVar)) { | ||
| 2356 | break; | ||
| 2357 | } | ||
| 2358 | leftVar = getUnusedName("_obj_"sv); | ||
| 2359 | auto tmpAsmt = assignmentFrom(toAst<Exp_t>(leftVar, tmpLeft), tmpLeft, tmpLeft); | ||
| 2360 | str_list temp; | ||
| 2361 | transformAssignment(tmpAsmt, temp); | ||
| 2362 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | ||
| 2363 | if (!beforeAssignment->expList->exprs.empty()) { | ||
| 2364 | transformAssignment(beforeAssignment, temp); | ||
| 2365 | } | ||
| 2366 | if (vit == values.end()) { | ||
| 2367 | throw CompileError("right value missing"sv, values.front()); | ||
| 2368 | } | ||
| 2369 | auto newChain = chainValue->new_ptr<ChainValue_t>(); | ||
| 2370 | newChain->items.push_back(toAst<Callable_t>(leftVar, newChain)); | ||
| 2371 | newChain->items.push_back(chainValue->items.back()); | ||
| 2372 | auto newLeft = newExp(newChain, newChain); | ||
| 2373 | auto newAsmt = assignmentFrom(newLeft, *vit, newLeft); | ||
| 2374 | transformAssignment(newAsmt, temp); | ||
| 2375 | if (!afterAssignment->expList->exprs.empty()) { | ||
| 2376 | transformAssignment(afterAssignment, temp); | ||
| 2377 | } | ||
| 2378 | out.push_back(join(temp)); | ||
| 2379 | return false; | ||
| 2340 | } else { | 2380 | } else { |
| 2341 | break; | 2381 | break; |
| 2342 | } | 2382 | } |
| @@ -6608,11 +6648,6 @@ private: | |||
| 6608 | indexNode->nilCoalesed.set(rIndex->modifier->nilCoalesed); | 6648 | indexNode->nilCoalesed.set(rIndex->modifier->nilCoalesed); |
| 6609 | } | 6649 | } |
| 6610 | newChain->items.push_back(indexNode); | 6650 | newChain->items.push_back(indexNode); |
| 6611 | auto next = current; | ||
| 6612 | ++next; | ||
| 6613 | for (auto i = next; i != chainList.end(); ++i) { | ||
| 6614 | newChain->items.push_back(*i); | ||
| 6615 | } | ||
| 6616 | auto expList = x->new_ptr<ExpList_t>(); | 6651 | auto expList = x->new_ptr<ExpList_t>(); |
| 6617 | expList->exprs.push_back(newExp(newChain, x)); | 6652 | expList->exprs.push_back(newExp(newChain, x)); |
| 6618 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 6653 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
| @@ -6627,6 +6662,11 @@ private: | |||
| 6627 | auto doNode = x->new_ptr<Do_t>(); | 6662 | auto doNode = x->new_ptr<Do_t>(); |
| 6628 | doNode->body.set(body); | 6663 | doNode->body.set(body); |
| 6629 | if (usage == ExpUsage::Assignment) { | 6664 | if (usage == ExpUsage::Assignment) { |
| 6665 | auto next = current; | ||
| 6666 | ++next; | ||
| 6667 | for (auto i = next; i != chainList.end(); ++i) { | ||
| 6668 | newChain->items.push_back(*i); | ||
| 6669 | } | ||
| 6630 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 6670 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 6631 | assignment->expList.set(assignList); | 6671 | assignment->expList.set(assignList); |
| 6632 | auto assign = x->new_ptr<Assign_t>(); | 6672 | auto assign = x->new_ptr<Assign_t>(); |
| @@ -6637,6 +6677,33 @@ private: | |||
| 6637 | transformAssignment(assignment, out); | 6677 | transformAssignment(assignment, out); |
| 6638 | return; | 6678 | return; |
| 6639 | } | 6679 | } |
| 6680 | if (usage == ExpUsage::Closure) { | ||
| 6681 | auto next = current; | ||
| 6682 | ++next; | ||
| 6683 | if (next != chainList.end()) { | ||
| 6684 | doNode->new_ptr<ChainValue_t>(); | ||
| 6685 | auto dVal = doNode->new_ptr<SimpleValue_t>(); | ||
| 6686 | dVal->value.set(doNode); | ||
| 6687 | auto dExp = newExp(dVal, dVal); | ||
| 6688 | auto dParen = dExp->new_ptr<Parens_t>(); | ||
| 6689 | dParen->extra = true; | ||
| 6690 | dParen->expr.set(dExp); | ||
| 6691 | auto dCallable = dExp->new_ptr<Callable_t>(); | ||
| 6692 | dCallable->item.set(dParen); | ||
| 6693 | auto dChain = doNode->new_ptr<ChainValue_t>(); | ||
| 6694 | dChain->items.push_back(dCallable); | ||
| 6695 | for (auto i = next; i != chainList.end(); ++i) { | ||
| 6696 | dChain->items.push_back(*i); | ||
| 6697 | } | ||
| 6698 | transformExp(newExp(dChain, dExp), out, usage); | ||
| 6699 | return; | ||
| 6700 | } | ||
| 6701 | } | ||
| 6702 | auto next = current; | ||
| 6703 | ++next; | ||
| 6704 | for (auto i = next; i != chainList.end(); ++i) { | ||
| 6705 | newChain->items.push_back(*i); | ||
| 6706 | } | ||
| 6640 | transformDo(doNode, out, usage); | 6707 | transformDo(doNode, out, usage); |
| 6641 | return; | 6708 | return; |
| 6642 | } | 6709 | } |
