diff options
author | Li Jin <dragon-fly@qq.com> | 2022-02-09 10:14:25 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2022-02-09 10:14:25 +0800 |
commit | 07a64933f8d956a8bba401db2200e6f7d8244dc9 (patch) | |
tree | 0a7da8fa2932fa89e317431b51fa1a3b19d97832 | |
parent | a6744ed09b49b740dfc2852d655f5ed6dd471cbf (diff) | |
download | yuescript-07a64933f8d956a8bba401db2200e6f7d8244dc9.tar.gz yuescript-07a64933f8d956a8bba401db2200e6f7d8244dc9.tar.bz2 yuescript-07a64933f8d956a8bba401db2200e6f7d8244dc9.zip |
fix the way update assignment is implemented.
-rw-r--r-- | spec/inputs/syntax.yue | 5 | ||||
-rw-r--r-- | spec/outputs/syntax.lua | 12 | ||||
-rwxr-xr-x | src/yuescript/yue_compiler.cpp | 35 |
3 files changed, 50 insertions, 2 deletions
diff --git a/spec/inputs/syntax.yue b/spec/inputs/syntax.yue index aed4144..cb947e1 100644 --- a/spec/inputs/syntax.yue +++ b/spec/inputs/syntax.yue | |||
@@ -183,6 +183,11 @@ a["hello"] += 10 | |||
183 | a["hello#{tostring ff}"] += 10 | 183 | a["hello#{tostring ff}"] += 10 |
184 | a[four].x += 10 | 184 | a[four].x += 10 |
185 | 185 | ||
186 | a.b += 1 | ||
187 | a.b[1].c[2+3] += 1 | ||
188 | with tb | ||
189 | .a.c += 1 | ||
190 | |||
186 | x = 0 | 191 | x = 0 |
187 | _ = (if ntype(v) == "fndef" then x += 1) for v in *values | 192 | _ = (if ntype(v) == "fndef" then x += 1) for v in *values |
188 | 193 | ||
diff --git a/spec/outputs/syntax.lua b/spec/outputs/syntax.lua index 3187898..ed8ed39 100644 --- a/spec/outputs/syntax.lua +++ b/spec/outputs/syntax.lua | |||
@@ -184,7 +184,17 @@ local _update_0 = "hello" | |||
184 | a[_update_0] = a[_update_0] + 10 | 184 | a[_update_0] = a[_update_0] + 10 |
185 | local _update_1 = "hello" .. tostring(tostring(ff)) | 185 | local _update_1 = "hello" .. tostring(tostring(ff)) |
186 | a[_update_1] = a[_update_1] + 10 | 186 | a[_update_1] = a[_update_1] + 10 |
187 | a[four].x = a[four].x + 10 | 187 | local _obj_0 = a[four] |
188 | _obj_0.x = _obj_0.x + 10 | ||
189 | a.b = a.b + 1 | ||
190 | local _obj_1 = a.b[1].c | ||
191 | local _update_2 = 2 + 3 | ||
192 | _obj_1[_update_2] = _obj_1[_update_2] + 1 | ||
193 | do | ||
194 | local _with_0 = tb | ||
195 | local _obj_2 = _with_0.a | ||
196 | _obj_2.c = _obj_2.c + 1 | ||
197 | end | ||
188 | x = 0 | 198 | x = 0 |
189 | local _list_0 = values | 199 | local _list_0 = values |
190 | for _index_0 = 1, #_list_0 do | 200 | for _index_0 = 1, #_list_0 do |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 17822c6..852a0f4 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -2015,9 +2015,42 @@ private: | |||
2015 | auto leftValue = singleValueFrom(leftExp); | 2015 | auto leftValue = singleValueFrom(leftExp); |
2016 | if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp)); | 2016 | if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp)); |
2017 | if (auto chain = leftValue->item.as<ChainValue_t>()) { | 2017 | if (auto chain = leftValue->item.as<ChainValue_t>()) { |
2018 | if (specialChainValue(chain) == ChainType::Metatable) { | 2018 | auto dot = ast_cast<DotChainItem_t>(chain->items.back()); |
2019 | if (dot && dot->name.is<Metatable_t>()) { | ||
2019 | throw std::logic_error(_info.errorMessage("can not apply update to a metatable"sv, leftExp)); | 2020 | throw std::logic_error(_info.errorMessage("can not apply update to a metatable"sv, leftExp)); |
2020 | } | 2021 | } |
2022 | BLOCK_START | ||
2023 | BREAK_IF(chain->items.size() < 2); | ||
2024 | if (chain->items.size() == 2) { | ||
2025 | if (auto callable = ast_cast<Callable_t>(chain->items.front())) { | ||
2026 | ast_node* var = callable->item.as<Variable_t>(); | ||
2027 | if (auto self = callable->item.as<SelfName_t>()) { | ||
2028 | var = self->name.as<self_t>(); | ||
2029 | } | ||
2030 | BREAK_IF(var); | ||
2031 | } | ||
2032 | } | ||
2033 | auto tmpChain = x->new_ptr<ChainValue_t>(); | ||
2034 | ast_ptr<false, ast_node> ptr(chain->items.back()); | ||
2035 | for (auto item : chain->items.objects()) { | ||
2036 | if (item != ptr) { | ||
2037 | tmpChain->items.push_back(item); | ||
2038 | } | ||
2039 | } | ||
2040 | auto value = x->new_ptr<Value_t>(); | ||
2041 | value->item.set(tmpChain); | ||
2042 | auto exp = newExp(value, x); | ||
2043 | auto objVar = getUnusedName("_obj_"sv); | ||
2044 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | ||
2045 | newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); | ||
2046 | auto assign = x->new_ptr<Assign_t>(); | ||
2047 | assign->values.push_back(exp); | ||
2048 | newAssignment->action.set(assign); | ||
2049 | transformAssignment(newAssignment, temp); | ||
2050 | chain->items.clear(); | ||
2051 | chain->items.push_back(toAst<Callable_t>(objVar, x)); | ||
2052 | chain->items.push_back(ptr); | ||
2053 | BLOCK_END | ||
2021 | auto tmpChain = x->new_ptr<ChainValue_t>(); | 2054 | auto tmpChain = x->new_ptr<ChainValue_t>(); |
2022 | for (auto item : chain->items.objects()) { | 2055 | for (auto item : chain->items.objects()) { |
2023 | bool itemAdded = false; | 2056 | bool itemAdded = false; |