aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-02-11 10:37:35 +0800
committerLi Jin <dragon-fly@qq.com>2022-02-11 10:37:35 +0800
commit09fc831f540ce3966aeff679164f37e7d40457c9 (patch)
treeea56f0fa897af3089e1289bdfa7676a62198dc13 /src
parenta66ec0d18eba6b38fad25cc88c82f7532d689670 (diff)
downloadyuescript-09fc831f540ce3966aeff679164f37e7d40457c9.tar.gz
yuescript-09fc831f540ce3966aeff679164f37e7d40457c9.tar.bz2
yuescript-09fc831f540ce3966aeff679164f37e7d40457c9.zip
add Lua table appending idiom: tb #= 123
Diffstat (limited to 'src')
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp66
-rwxr-xr-xsrc/yuescript/yue_parser.cpp3
2 files changed, 47 insertions, 22 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
61typedef std::list<std::string> str_list; 61typedef std::list<std::string> str_list;
62 62
63const std::string_view version = "0.9.8"sv; 63const std::string_view version = "0.9.9"sv;
64const std::string_view extension = "yue"sv; 64const std::string_view extension = "yue"sv;
65 65
66class YueCompilerImpl { 66class 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);
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index e171f3f..772ae08 100755
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -324,7 +324,8 @@ YueParser::YueParser() {
324 expr("|") | 324 expr("|") |
325 expr(">>") | 325 expr(">>") |
326 expr("<<") | 326 expr("<<") |
327 expr("??"); 327 expr("??") |
328 expr("#");
328 329
329 Update = Space >> update_op >> expr("=") >> Exp; 330 Update = Space >> update_op >> expr("=") >> Exp;
330 331