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.
Diffstat (limited to '')
| -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; |
