aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/yuescript/parser.cpp10
-rw-r--r--src/yuescript/parser.hpp11
-rw-r--r--src/yuescript/yue_compiler.cpp247
3 files changed, 184 insertions, 84 deletions
diff --git a/src/yuescript/parser.cpp b/src/yuescript/parser.cpp
index 5e4caa2..5d0773c 100644
--- a/src/yuescript/parser.cpp
+++ b/src/yuescript/parser.cpp
@@ -15,15 +15,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15#include <stdexcept> 15#include <stdexcept>
16#include <unordered_map> 16#include <unordered_map>
17#include <unordered_set> 17#include <unordered_set>
18#include <memory>
19 18
20#include "yuescript/parser.hpp" 19#include "yuescript/parser.hpp"
21 20
22#define _DEFER(code, line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto) { \
23 code; \
24})
25#define DEFER(code) _DEFER(code, __LINE__)
26
27namespace parserlib { 21namespace parserlib {
28 22
29// internal private class that manages access to the public classes' internals. 23// internal private class that manages access to the public classes' internals.
@@ -914,7 +908,7 @@ bool _context::parse_non_term(rule& r) {
914 // save the state of the rule 908 // save the state of the rule
915 rule::_state old_state = r.m_state; 909 rule::_state old_state = r.m_state;
916 // restore the rule's state 910 // restore the rule's state
917 DEFER(r.m_state = old_state); 911 rule::_state_guard quard(old_state, &r.m_state);
918 912
919 // success/failure result 913 // success/failure result
920 bool ok = false; 914 bool ok = false;
@@ -1008,7 +1002,7 @@ bool _context::parse_term(rule& r) {
1008 // save the state of the rule 1002 // save the state of the rule
1009 rule::_state old_state = r.m_state; 1003 rule::_state old_state = r.m_state;
1010 // restore the rule's state 1004 // restore the rule's state
1011 DEFER(r.m_state = old_state); 1005 rule::_state_guard quard(old_state, &r.m_state);
1012 1006
1013 // success/failure result 1007 // success/failure result
1014 bool ok = false; 1008 bool ok = false;
diff --git a/src/yuescript/parser.hpp b/src/yuescript/parser.hpp
index 71bbc1a..5ab327f 100644
--- a/src/yuescript/parser.hpp
+++ b/src/yuescript/parser.hpp
@@ -294,6 +294,17 @@ private:
294 , m_mode(mode) { } 294 , m_mode(mode) { }
295 }; 295 };
296 296
297 struct _state_guard {
298 _state m_old_state;
299 _state* m_current_state;
300 _state_guard(const _state& old, _state* new_)
301 : m_old_state(old)
302 , m_current_state(new_) { }
303 ~_state_guard() {
304 *m_current_state = m_old_state;
305 }
306 };
307
297 // internal expression 308 // internal expression
298 _expr* m_expr; 309 _expr* m_expr;
299 310
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 32db488..cbb5f81 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = {
75 "close"s // Lua 5.4 75 "close"s // Lua 5.4
76}; 76};
77 77
78const std::string_view version = "0.24.1"sv; 78const std::string_view version = "0.25.0"sv;
79const std::string_view extension = "yue"sv; 79const std::string_view extension = "yue"sv;
80 80
81class CompileError : public std::logic_error { 81class CompileError : public std::logic_error {
@@ -1943,16 +1943,26 @@ private:
1943 1943
1944 std::string getDestrucureDefine(ExpListAssign_t* assignment) { 1944 std::string getDestrucureDefine(ExpListAssign_t* assignment) {
1945 auto info = extractDestructureInfo(assignment, true, false); 1945 auto info = extractDestructureInfo(assignment, true, false);
1946 if (info.assignment) {
1947 _buf << getPreDefineLine(info.assignment);
1948 }
1949 if (!info.destructures.empty()) { 1946 if (!info.destructures.empty()) {
1950 str_list defs; 1947 str_list defs;
1951 for (const auto& destruct : info.destructures) { 1948 for (const auto& des : info.destructures) {
1952 for (const auto& item : destruct.items) { 1949 if (std::holds_alternative<Destructure>(des)) {
1953 if (!item.targetVar.empty()) { 1950 const auto& destruct = std::get<Destructure>(des);
1954 if (addToScope(item.targetVar)) { 1951 for (const auto& item : destruct.items) {
1955 defs.push_back(item.targetVar); 1952 if (!item.targetVar.empty()) {
1953 if (addToScope(item.targetVar)) {
1954 defs.push_back(item.targetVar);
1955 }
1956 }
1957 }
1958 } else {
1959 const auto& assignment = std::get<AssignmentPtr>(des);
1960 if (!assignment.extraAssignment) {
1961 auto names = transformAssignDefs(assignment.ptr->expList, DefOp::Get);
1962 for (const auto& name : names) {
1963 if (addToScope(name.first)) {
1964 defs.push_back(name.first);
1965 }
1956 } 1966 }
1957 } 1967 }
1958 } 1968 }
@@ -2007,12 +2017,15 @@ private:
2007 2017
2008 void markDestructureConst(ExpListAssign_t* assignment) { 2018 void markDestructureConst(ExpListAssign_t* assignment) {
2009 auto info = extractDestructureInfo(assignment, true, false); 2019 auto info = extractDestructureInfo(assignment, true, false);
2010 for (auto& destruct : info.destructures) { 2020 for (const auto& des : info.destructures) {
2011 for (auto& item : destruct.items) { 2021 if (std::holds_alternative<Destructure>(des)) {
2012 if (item.targetVar.empty()) { 2022 const auto& destruct = std::get<Destructure>(des);
2013 throw CompileError("can only declare variable as const"sv, item.target); 2023 for (const auto& item : destruct.items) {
2024 if (item.targetVar.empty()) {
2025 throw CompileError("can only declare variable as const"sv, item.target);
2026 }
2027 markVarConst(item.targetVar);
2014 } 2028 }
2015 markVarConst(item.targetVar);
2016 } 2029 }
2017 } 2030 }
2018 } 2031 }
@@ -2079,7 +2092,7 @@ private:
2079 BLOCK_START 2092 BLOCK_START
2080 auto value = singleValueFrom(*it); 2093 auto value = singleValueFrom(*it);
2081 BREAK_IF(!value); 2094 BREAK_IF(!value);
2082 if (value->item.is<SimpleTable_t>() || value->get_by_path<SimpleValue_t, TableLit_t>()) { 2095 if (value->item.is<SimpleTable_t>() || value->get_by_path<SimpleValue_t, TableLit_t>() || value->get_by_path<SimpleValue_t, Comprehension_t>()) {
2083 holdItem = true; 2096 holdItem = true;
2084 break; 2097 break;
2085 } 2098 }
@@ -2404,11 +2417,24 @@ private:
2404 bool extraScope = false; 2417 bool extraScope = false;
2405 if (info.extraScope) { 2418 if (info.extraScope) {
2406 str_list defs; 2419 str_list defs;
2407 for (auto& destruct : info.destructures) { 2420 for (const auto& des : info.destructures) {
2408 for (auto& item : destruct.items) { 2421 if (std::holds_alternative<Destructure>(des)) {
2409 if (!item.targetVar.empty()) { 2422 const auto& destruct = std::get<Destructure>(des);
2410 if (!isDefined(item.targetVar)) { 2423 for (auto& item : destruct.items) {
2411 defs.push_back(item.targetVar); 2424 if (!item.targetVar.empty()) {
2425 if (!isDefined(item.targetVar)) {
2426 defs.push_back(item.targetVar);
2427 }
2428 }
2429 }
2430 } else {
2431 const auto& assignment = std::get<AssignmentPtr>(des);
2432 if (!assignment.extraAssignment) {
2433 auto names = transformAssignDefs(assignment.ptr->expList, DefOp::Get);
2434 for (const auto& name : names) {
2435 if (addToScope(name.first)) {
2436 defs.push_back(name.first);
2437 }
2412 } 2438 }
2413 } 2439 }
2414 } 2440 }
@@ -2426,10 +2452,13 @@ private:
2426 pushScope(); 2452 pushScope();
2427 } 2453 }
2428 } 2454 }
2429 if (info.assignment) { 2455 for (auto& des : info.destructures) {
2430 transformAssignmentCommon(info.assignment, temp); 2456 if (std::holds_alternative<AssignmentPtr>(des)) {
2431 } 2457 auto assignment = std::get<AssignmentPtr>(des).ptr.get();
2432 for (auto& destruct : info.destructures) { 2458 transformAssignment(assignment, temp);
2459 continue;
2460 }
2461 auto& destruct = std::get<Destructure>(des);
2433 std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs; 2462 std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs;
2434 bool extraScope = false; 2463 bool extraScope = false;
2435 if (!destruct.inlineAssignment && destruct.items.size() == 1) { 2464 if (!destruct.inlineAssignment && destruct.items.size() == 1) {
@@ -2931,17 +2960,21 @@ private:
2931 return pairs; 2960 return pairs;
2932 } 2961 }
2933 2962
2963 struct AssignmentPtr {
2964 ast_ptr<false, ExpListAssign_t> ptr;
2965 bool extraAssignment = false;
2966 };
2967
2934 struct DestructureInfo { 2968 struct DestructureInfo {
2935 std::list<Destructure> destructures; 2969 std::list<std::variant<Destructure, AssignmentPtr>> destructures;
2936 ast_ptr<false, ExpListAssign_t> assignment;
2937 bool extraScope = false; 2970 bool extraScope = false;
2938 }; 2971 };
2939 2972
2940 DestructureInfo extractDestructureInfo(ExpListAssign_t* assignment, bool varDefOnly, bool optional) { 2973 DestructureInfo extractDestructureInfo(ExpListAssign_t* assignment, bool varDefOnly, bool optional) {
2974 if (!assignment->action.is<Assign_t>()) return {};
2941 auto x = assignment; 2975 auto x = assignment;
2942 bool extraScope = false; 2976 bool extraScope = false;
2943 std::list<Destructure> destructs; 2977 std::list<std::variant<Destructure, AssignmentPtr>> destructs;
2944 if (!assignment->action.is<Assign_t>()) return {destructs, nullptr};
2945 auto exprs = assignment->expList->exprs.objects(); 2978 auto exprs = assignment->expList->exprs.objects();
2946 auto values = assignment->action.to<Assign_t>()->values.objects(); 2979 auto values = assignment->action.to<Assign_t>()->values.objects();
2947 size_t size = std::max(exprs.size(), values.size()); 2980 size_t size = std::max(exprs.size(), values.size());
@@ -2951,10 +2984,26 @@ private:
2951 while (values.size() < size) values.emplace_back(nil); 2984 while (values.size() < size) values.emplace_back(nil);
2952 } 2985 }
2953 using iter = node_container::iterator; 2986 using iter = node_container::iterator;
2954 std::vector<std::pair<iter, iter>> destructPairs; 2987 std::vector<std::pair<iter, iter>> assignPairs;
2955 ast_list<false, ast_node> valueItems; 2988 ast_list<false, ast_node> valueItems;
2956 str_list temp; 2989 str_list temp;
2957 pushScope(); 2990 pushScope();
2991 auto checkCommonAssignment = [&]() {
2992 if (!assignPairs.empty()) {
2993 auto expList = x->new_ptr<ExpList_t>();
2994 auto newAssign = x->new_ptr<ExpListAssign_t>();
2995 newAssign->expList.set(expList);
2996 auto assign = x->new_ptr<Assign_t>();
2997 newAssign->action.set(assign);
2998 for (const auto& pair : assignPairs) {
2999 expList->exprs.push_back(*pair.first);
3000 assign->values.push_back(*pair.second);
3001 }
3002 assignPairs.clear();
3003 destructs.push_back(AssignmentPtr{newAssign, false});
3004 }
3005 };
3006 bool hasDestructuring = false;
2958 for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) { 3007 for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) {
2959 auto expr = *i; 3008 auto expr = *i;
2960 auto value = singleValueFrom(expr); 3009 auto value = singleValueFrom(expr);
@@ -2974,6 +3023,8 @@ private:
2974 } 3023 }
2975 } 3024 }
2976 if (destructNode) { 3025 if (destructNode) {
3026 hasDestructuring = true;
3027 checkCommonAssignment();
2977 if (*j != nil) { 3028 if (*j != nil) {
2978 if (auto ssVal = simpleSingleValueFrom(*j)) { 3029 if (auto ssVal = simpleSingleValueFrom(*j)) {
2979 switch (ssVal->value->get_id()) { 3030 switch (ssVal->value->get_id()) {
@@ -2989,7 +3040,6 @@ private:
2989 } 3040 }
2990 } 3041 }
2991 } 3042 }
2992 destructPairs.push_back({i, j});
2993 auto subDestruct = destructNode->new_ptr<TableLit_t>(); 3043 auto subDestruct = destructNode->new_ptr<TableLit_t>();
2994 auto subMetaDestruct = destructNode->new_ptr<TableLit_t>(); 3044 auto subMetaDestruct = destructNode->new_ptr<TableLit_t>();
2995 const node_container* dlist = nullptr; 3045 const node_container* dlist = nullptr;
@@ -3113,19 +3163,26 @@ private:
3113 if (!varDefOnly && !subDestruct->values.empty() && !subMetaDestruct->values.empty()) { 3163 if (!varDefOnly && !subDestruct->values.empty() && !subMetaDestruct->values.empty()) {
3114 auto var = singleVariableFrom(*j, AccessType::None); 3164 auto var = singleVariableFrom(*j, AccessType::None);
3115 if (var.empty() || !isLocal(var)) { 3165 if (var.empty() || !isLocal(var)) {
3166 checkCommonAssignment();
3116 auto objVar = getUnusedName("_obj_"sv); 3167 auto objVar = getUnusedName("_obj_"sv);
3117 addToScope(objVar); 3168 addToScope(objVar);
3118 valueItems.pop_back(); 3169 valueItems.pop_back();
3119 valueItems.push_back(toAst<Exp_t>(objVar, *j)); 3170 valueItems.push_back(toAst<Exp_t>(objVar, *j));
3120 exprs.push_back(valueItems.back()); 3171 auto expList = x->new_ptr<ExpList_t>();
3121 values.push_back(*j); 3172 auto newAssign = x->new_ptr<ExpListAssign_t>();
3173 newAssign->expList.set(expList);
3174 auto assign = x->new_ptr<Assign_t>();
3175 newAssign->action.set(assign);
3176 expList->exprs.push_back(valueItems.back());
3177 assign->values.push_back(*j);
3178 destructs.push_back(AssignmentPtr{newAssign, true});
3122 extraScope = true; 3179 extraScope = true;
3123 } 3180 }
3124 } 3181 }
3125 TableLit_t* tabs[] = {subDestruct.get(), subMetaDestruct.get()}; 3182 TableLit_t* tabs[] = {subDestruct.get(), subMetaDestruct.get()};
3126 for (auto tab : tabs) { 3183 for (auto tab : tabs) {
3127 if (!tab->values.empty()) { 3184 if (!tab->values.empty()) {
3128 auto& destruct = destructs.emplace_back(); 3185 Destructure destruct;
3129 if (!varDefOnly) { 3186 if (!varDefOnly) {
3130 destruct.value = valueItems.back(); 3187 destruct.value = valueItems.back();
3131 destruct.valueVar = singleVariableFrom(destruct.value, AccessType::None); 3188 destruct.valueVar = singleVariableFrom(destruct.value, AccessType::None);
@@ -3172,29 +3229,28 @@ private:
3172 destruct.valueVar.clear(); 3229 destruct.valueVar.clear();
3173 } 3230 }
3174 } 3231 }
3232 destructs.push_back(destruct);
3175 } 3233 }
3176 } 3234 }
3235 } else {
3236 assignPairs.push_back({i, j});
3177 } 3237 }
3178 } 3238 }
3179 for (const auto& p : destructPairs) { 3239 if (!hasDestructuring) {
3180 exprs.erase(p.first); 3240 popScope();
3181 values.erase(p.second); 3241 return {};
3182 }
3183 ast_ptr<false, ExpListAssign_t> newAssignment;
3184 if (!destructPairs.empty() && !exprs.empty()) {
3185 auto x = assignment;
3186 auto expList = x->new_ptr<ExpList_t>();
3187 auto newAssign = x->new_ptr<ExpListAssign_t>();
3188 newAssign->expList.set(expList);
3189 for (auto expr : exprs) expList->exprs.push_back(expr);
3190 auto assign = x->new_ptr<Assign_t>();
3191 for (auto value : values) assign->values.push_back(value);
3192 newAssign->action.set(assign);
3193 newAssignment = newAssign;
3194 } 3242 }
3243 checkCommonAssignment();
3195 if (!varDefOnly) { 3244 if (!varDefOnly) {
3196 for (auto& des : destructs) { 3245 for (auto& d : destructs) {
3246 if (std::holds_alternative<AssignmentPtr>(d)) {
3247 continue;
3248 }
3249 auto& des = std::get<Destructure>(d);
3197 for (const auto& item : des.items) { 3250 for (const auto& item : des.items) {
3251 if (!item.structure) {
3252 continue;
3253 }
3198 for (auto node : item.structure->items.objects()) { 3254 for (auto node : item.structure->items.objects()) {
3199 if (auto exp = ast_cast<Exp_t>(node)) { 3255 if (auto exp = ast_cast<Exp_t>(node)) {
3200 if (auto value = simpleSingleValueFrom(node)) { 3256 if (auto value = simpleSingleValueFrom(node)) {
@@ -3236,7 +3292,7 @@ private:
3236 } 3292 }
3237 } 3293 }
3238 popScope(); 3294 popScope();
3239 return {std::move(destructs), newAssignment, extraScope}; 3295 return {std::move(destructs), extraScope};
3240 } 3296 }
3241 3297
3242 void transformAssignmentCommon(ExpListAssign_t* assignment, str_list& out) { 3298 void transformAssignmentCommon(ExpListAssign_t* assignment, str_list& out) {
@@ -4746,23 +4802,30 @@ private:
4746 } 4802 }
4747 auto info = extractDestructureInfo(assignment, true, false); 4803 auto info = extractDestructureInfo(assignment, true, false);
4748 if (!info.destructures.empty()) { 4804 if (!info.destructures.empty()) {
4749 for (const auto& destruct : info.destructures) 4805 for (const auto& des : info.destructures) {
4750 for (const auto& item : destruct.items) 4806 if (std::holds_alternative<Destructure>(des)) {
4751 if (!item.targetVar.empty()) { 4807 const auto& destruct = std::get<Destructure>(des);
4752 if (std::isupper(item.targetVar[0]) && capital) { 4808 for (const auto& item : destruct.items) {
4753 capital->decls.push_back(item.targetVar); 4809 if (!item.targetVar.empty()) {
4754 } else if (any) { 4810 if (std::isupper(item.targetVar[0]) && capital) {
4755 any->decls.push_back(item.targetVar); 4811 capital->decls.push_back(item.targetVar);
4812 } else if (any) {
4813 any->decls.push_back(item.targetVar);
4814 }
4815 }
4816 }
4817 } else {
4818 const auto& assignment = std::get<AssignmentPtr>(des);
4819 if (!assignment.extraAssignment) {
4820 auto defs = transformAssignDefs(assignment.ptr->expList, DefOp::Get);
4821 for (const auto& def : defs) {
4822 if (std::isupper(def.first[0]) && capital) {
4823 capital->decls.push_back(def.first);
4824 } else if (any) {
4825 any->decls.push_back(def.first);
4826 }
4756 } 4827 }
4757 } 4828 }
4758 }
4759 if (info.assignment) {
4760 auto defs = transformAssignDefs(info.assignment->expList, DefOp::Get);
4761 for (const auto& def : defs) {
4762 if (std::isupper(def.first[0]) && capital) {
4763 capital->decls.push_back(def.first);
4764 } else if (any) {
4765 any->decls.push_back(def.first);
4766 } 4829 }
4767 } 4830 }
4768 } 4831 }
@@ -8551,10 +8614,17 @@ private:
8551 } 8614 }
8552 auto info = extractDestructureInfo(assignment, true, false); 8615 auto info = extractDestructureInfo(assignment, true, false);
8553 if (!info.destructures.empty()) { 8616 if (!info.destructures.empty()) {
8554 for (const auto& destruct : info.destructures) 8617 for (const auto& des : info.destructures) {
8555 for (const auto& item : destruct.items) 8618 if (std::holds_alternative<AssignmentPtr>(des)) {
8556 if (!item.targetVar.empty() && addToScope(item.targetVar)) 8619 continue;
8620 }
8621 const auto& destruct = std::get<Destructure>(des);
8622 for (const auto& item : destruct.items) {
8623 if (!item.targetVar.empty() && addToScope(item.targetVar)) {
8557 varDefs.push_back(item.targetVar); 8624 varDefs.push_back(item.targetVar);
8625 }
8626 }
8627 }
8558 } 8628 }
8559 BLOCK_START 8629 BLOCK_START
8560 auto assign = assignment->action.as<Assign_t>(); 8630 auto assign = assignment->action.as<Assign_t>();
@@ -9006,10 +9076,17 @@ private:
9006 } 9076 }
9007 auto info = extractDestructureInfo(assignment, true, false); 9077 auto info = extractDestructureInfo(assignment, true, false);
9008 if (!info.destructures.empty()) { 9078 if (!info.destructures.empty()) {
9009 for (const auto& destruct : info.destructures) 9079 for (const auto& des : info.destructures) {
9010 for (const auto& item : destruct.items) 9080 if (std::holds_alternative<AssignmentPtr>(des)) {
9011 if (!item.targetVar.empty() && !isDefined(item.targetVar)) 9081 continue;
9082 }
9083 const auto& destruct = std::get<Destructure>(des);
9084 for (const auto& item : destruct.items) {
9085 if (!item.targetVar.empty() && !isDefined(item.targetVar)) {
9012 return traversal::Stop; 9086 return traversal::Stop;
9087 }
9088 }
9089 }
9013 } 9090 }
9014 BLOCK_START 9091 BLOCK_START
9015 auto assign = assignment->action.as<Assign_t>(); 9092 auto assign = assignment->action.as<Assign_t>();
@@ -9248,13 +9325,19 @@ private:
9248 auto names = transformAssignDefs(expList, DefOp::Get); 9325 auto names = transformAssignDefs(expList, DefOp::Get);
9249 auto info = extractDestructureInfo(assignment, true, false); 9326 auto info = extractDestructureInfo(assignment, true, false);
9250 if (!info.destructures.empty()) { 9327 if (!info.destructures.empty()) {
9251 for (const auto& destruct : info.destructures) 9328 for (const auto& des : info.destructures) {
9252 for (const auto& item : destruct.items) 9329 if (std::holds_alternative<AssignmentPtr>(des)) {
9330 continue;
9331 }
9332 const auto& destruct = std::get<Destructure>(des);
9333 for (const auto& item : destruct.items) {
9253 if (!item.targetVar.empty()) { 9334 if (!item.targetVar.empty()) {
9254 auto dot = ast_cast<DotChainItem_t>(item.structure->items.back()); 9335 auto dot = ast_cast<DotChainItem_t>(item.structure->items.back());
9255 auto uname = dot->name.as<UnicodeName_t>(); 9336 auto uname = dot->name.as<UnicodeName_t>();
9256 names.emplace_back(item.targetVar, uname ? _parser.toString(uname) : Empty); 9337 names.emplace_back(item.targetVar, uname ? _parser.toString(uname) : Empty);
9257 } 9338 }
9339 }
9340 }
9258 } 9341 }
9259 if (_info.exportDefault) { 9342 if (_info.exportDefault) {
9260 out.back().append(indent() + _info.moduleName + " = "s + names.back().first + nlr(exportNode)); 9343 out.back().append(indent() + _info.moduleName + " = "s + names.back().first + nlr(exportNode));
@@ -10213,7 +10296,11 @@ private:
10213 auto info = extractDestructureInfo(assignment, true, false); 10296 auto info = extractDestructureInfo(assignment, true, false);
10214 transformAssignment(assignment, temp, true); 10297 transformAssignment(assignment, temp, true);
10215 str_list conds; 10298 str_list conds;
10216 for (const auto& destruct : info.destructures) { 10299 for (const auto& des : info.destructures) {
10300 if (std::holds_alternative<AssignmentPtr>(des)) {
10301 continue;
10302 }
10303 const auto& destruct = std::get<Destructure>(des);
10217 for (const auto& item : destruct.items) { 10304 for (const auto& item : destruct.items) {
10218 if (!item.defVal) { 10305 if (!item.defVal) {
10219 transformExp(item.target, conds, ExpUsage::Closure); 10306 transformExp(item.target, conds, ExpUsage::Closure);
@@ -10475,7 +10562,11 @@ private:
10475 assignment->expList.set(leftList); 10562 assignment->expList.set(leftList);
10476 assignment->action.set(assign); 10563 assignment->action.set(assign);
10477 auto info = extractDestructureInfo(assignment, true, false); 10564 auto info = extractDestructureInfo(assignment, true, false);
10478 for (auto& destruct : info.destructures) { 10565 for (const auto& des : info.destructures) {
10566 if (std::holds_alternative<AssignmentPtr>(des)) {
10567 continue;
10568 }
10569 const auto& destruct = std::get<Destructure>(des);
10479 for (auto& item : destruct.items) { 10570 for (auto& item : destruct.items) {
10480 if (item.targetVar.empty()) { 10571 if (item.targetVar.empty()) {
10481 throw CompileError("can only declare variable as const"sv, item.target); 10572 throw CompileError("can only declare variable as const"sv, item.target);
@@ -10569,7 +10660,11 @@ private:
10569 assignment->action.set(assignB); 10660 assignment->action.set(assignB);
10570 auto info = extractDestructureInfo(assignment, true, false); 10661 auto info = extractDestructureInfo(assignment, true, false);
10571 str_list vars; 10662 str_list vars;
10572 for (auto& destruct : info.destructures) { 10663 for (auto& des : info.destructures) {
10664 if (std::holds_alternative<AssignmentPtr>(des)) {
10665 continue;
10666 }
10667 const auto& destruct = std::get<Destructure>(des);
10573 for (auto& item : destruct.items) { 10668 for (auto& item : destruct.items) {
10574 if (item.targetVar.empty()) { 10669 if (item.targetVar.empty()) {
10575 throw CompileError("can only declare variable as const"sv, item.target); 10670 throw CompileError("can only declare variable as const"sv, item.target);