diff options
| author | Li Jin <dragon-fly@qq.com> | 2022-02-11 10:37:35 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2022-02-11 10:37:35 +0800 |
| commit | 09fc831f540ce3966aeff679164f37e7d40457c9 (patch) | |
| tree | ea56f0fa897af3089e1289bdfa7676a62198dc13 /src/yuescript/yue_compiler.cpp | |
| parent | a66ec0d18eba6b38fad25cc88c82f7532d689670 (diff) | |
| download | yuescript-09fc831f540ce3966aeff679164f37e7d40457c9.tar.gz yuescript-09fc831f540ce3966aeff679164f37e7d40457c9.tar.bz2 yuescript-09fc831f540ce3966aeff679164f37e7d40457c9.zip | |
add Lua table appending idiom: tb #= 123
Diffstat (limited to '')
| -rwxr-xr-x | src/yuescript/yue_compiler.cpp | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index db225f6..33d4dcb 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -60,7 +60,7 @@ using namespace parserlib; | |||
| 60 | 60 | ||
| 61 | typedef std::list<std::string> str_list; | 61 | typedef std::list<std::string> str_list; |
| 62 | 62 | ||
| 63 | const std::string_view version = "0.9.8"sv; | 63 | const std::string_view version = "0.9.9"sv; |
| 64 | const std::string_view extension = "yue"sv; | 64 | const std::string_view extension = "yue"sv; |
| 65 | 65 | ||
| 66 | class YueCompilerImpl { | 66 | class YueCompilerImpl { |
| @@ -2014,7 +2014,10 @@ private: | |||
| 2014 | auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front()); | 2014 | auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front()); |
| 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 | auto chain = leftValue->item.as<ChainValue_t>(); |
| 2018 | if (!chain) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, chain)); | ||
| 2019 | auto op = _parser.toString(update->op); | ||
| 2020 | { | ||
| 2018 | auto dot = ast_cast<DotChainItem_t>(chain->items.back()); | 2021 | auto dot = ast_cast<DotChainItem_t>(chain->items.back()); |
| 2019 | if (dot && dot->name.is<Metatable_t>()) { | 2022 | if (dot && dot->name.is<Metatable_t>()) { |
| 2020 | throw std::logic_error(_info.errorMessage("can not apply update to a metatable"sv, leftExp)); | 2023 | throw std::logic_error(_info.errorMessage("can not apply update to a metatable"sv, leftExp)); |
| @@ -2030,26 +2033,38 @@ private: | |||
| 2030 | BREAK_IF(var); | 2033 | BREAK_IF(var); |
| 2031 | } | 2034 | } |
| 2032 | } | 2035 | } |
| 2033 | auto tmpChain = x->new_ptr<ChainValue_t>(); | 2036 | if (op == "#"sv) { |
| 2034 | ast_ptr<false, ast_node> ptr(chain->items.back()); | 2037 | auto objVar = getUnusedName("_obj_"sv); |
| 2035 | for (auto item : chain->items.objects()) { | 2038 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
| 2036 | if (item != ptr) { | 2039 | newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); |
| 2037 | tmpChain->items.push_back(item); | 2040 | auto assign = x->new_ptr<Assign_t>(); |
| 2041 | assign->values.push_back(leftExp); | ||
| 2042 | newAssignment->action.set(assign); | ||
| 2043 | transformAssignment(newAssignment, temp); | ||
| 2044 | chain->items.clear(); | ||
| 2045 | chain->items.push_back(toAst<Callable_t>(objVar, x)); | ||
| 2046 | } else { | ||
| 2047 | auto tmpChain = x->new_ptr<ChainValue_t>(); | ||
| 2048 | ast_ptr<false, ast_node> ptr(chain->items.back()); | ||
| 2049 | for (auto item : chain->items.objects()) { | ||
| 2050 | if (item != ptr) { | ||
| 2051 | tmpChain->items.push_back(item); | ||
| 2052 | } | ||
| 2038 | } | 2053 | } |
| 2054 | auto value = x->new_ptr<Value_t>(); | ||
| 2055 | value->item.set(tmpChain); | ||
| 2056 | auto exp = newExp(value, x); | ||
| 2057 | auto objVar = getUnusedName("_obj_"sv); | ||
| 2058 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | ||
| 2059 | newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); | ||
| 2060 | auto assign = x->new_ptr<Assign_t>(); | ||
| 2061 | assign->values.push_back(exp); | ||
| 2062 | newAssignment->action.set(assign); | ||
| 2063 | transformAssignment(newAssignment, temp); | ||
| 2064 | chain->items.clear(); | ||
| 2065 | chain->items.push_back(toAst<Callable_t>(objVar, x)); | ||
| 2066 | chain->items.push_back(ptr); | ||
| 2039 | } | 2067 | } |
| 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 | 2068 | BLOCK_END |
| 2054 | auto tmpChain = x->new_ptr<ChainValue_t>(); | 2069 | auto tmpChain = x->new_ptr<ChainValue_t>(); |
| 2055 | for (auto item : chain->items.objects()) { | 2070 | for (auto item : chain->items.objects()) { |
| @@ -2074,7 +2089,6 @@ private: | |||
| 2074 | chain->items.clear(); | 2089 | chain->items.clear(); |
| 2075 | chain->items.dup(tmpChain->items); | 2090 | chain->items.dup(tmpChain->items); |
| 2076 | } | 2091 | } |
| 2077 | auto op = _parser.toString(update->op); | ||
| 2078 | if (op == "??"sv) { | 2092 | if (op == "??"sv) { |
| 2079 | auto defs = getPredefine(assignment); | 2093 | auto defs = getPredefine(assignment); |
| 2080 | auto rightExp = x->new_ptr<Exp_t>(); | 2094 | auto rightExp = x->new_ptr<Exp_t>(); |
| @@ -2085,6 +2099,16 @@ private: | |||
| 2085 | if (!defs.empty()) temp.back().insert(0, defs + nll(x)); | 2099 | if (!defs.empty()) temp.back().insert(0, defs + nll(x)); |
| 2086 | out.push_back(join(temp)); | 2100 | out.push_back(join(temp)); |
| 2087 | return; | 2101 | return; |
| 2102 | } else if (op == "#"sv) { | ||
| 2103 | auto left = _parser.toString(chain->items.front()); | ||
| 2104 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | ||
| 2105 | newAssignment->expList.set(toAst<ExpList_t>(left + "[#"s + left + "+1]"s, x)); | ||
| 2106 | auto assign = x->new_ptr<Assign_t>(); | ||
| 2107 | assign->values.push_back(update->value); | ||
| 2108 | newAssignment->action.set(assign); | ||
| 2109 | transformAssignment(newAssignment, temp); | ||
| 2110 | out.push_back(join(temp)); | ||
| 2111 | return; | ||
| 2088 | } | 2112 | } |
| 2089 | auto defs = getPredefine(assignment); | 2113 | auto defs = getPredefine(assignment); |
| 2090 | transformValue(leftValue, temp); | 2114 | transformValue(leftValue, temp); |
