aboutsummaryrefslogtreecommitdiff
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
parenta66ec0d18eba6b38fad25cc88c82f7532d689670 (diff)
downloadyuescript-09fc831f540ce3966aeff679164f37e7d40457c9.tar.gz
yuescript-09fc831f540ce3966aeff679164f37e7d40457c9.tar.bz2
yuescript-09fc831f540ce3966aeff679164f37e7d40457c9.zip
add Lua table appending idiom: tb #= 123
-rw-r--r--spec/inputs/syntax.yue13
-rw-r--r--spec/outputs/syntax.lua18
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp66
-rwxr-xr-xsrc/yuescript/yue_parser.cpp3
4 files changed, 77 insertions, 23 deletions
diff --git a/spec/inputs/syntax.yue b/spec/inputs/syntax.yue
index cb947e1..67d3a27 100644
--- a/spec/inputs/syntax.yue
+++ b/spec/inputs/syntax.yue
@@ -184,10 +184,21 @@ a["hello#{tostring ff}"] += 10
184a[four].x += 10 184a[four].x += 10
185 185
186a.b += 1 186a.b += 1
187a.b[1].c[2+3] += 1 187a.b[1].c[2 + 3] += 1
188with tb 188with tb
189 .a.c += 1 189 .a.c += 1
190 190
191tb #= 10
192a.b.c #= 1
193x #= if v
194 1
195else
196 2
197with tb
198 .b.c #= with vec
199 .x = 1
200 .y = 2
201
191x = 0 202x = 0
192_ = (if ntype(v) == "fndef" then x += 1) for v in *values 203_ = (if ntype(v) == "fndef" then x += 1) for v in *values
193 204
diff --git a/spec/outputs/syntax.lua b/spec/outputs/syntax.lua
index ed8ed39..4596a29 100644
--- a/spec/outputs/syntax.lua
+++ b/spec/outputs/syntax.lua
@@ -195,6 +195,24 @@ do
195 local _obj_2 = _with_0.a 195 local _obj_2 = _with_0.a
196 _obj_2.c = _obj_2.c + 1 196 _obj_2.c = _obj_2.c + 1
197end 197end
198tb[#tb + 1] = 10
199local _obj_2 = a.b.c
200_obj_2[#_obj_2 + 1] = 1
201if v then
202 x[#x + 1] = 1
203else
204 x[#x + 1] = 2
205end
206do
207 local _with_0 = tb
208 local _obj_3 = _with_0.b.c
209 do
210 local _with_1 = vec
211 _with_1.x = 1
212 _with_1.y = 2
213 _obj_3[#_obj_3 + 1] = _with_1
214 end
215end
198x = 0 216x = 0
199local _list_0 = values 217local _list_0 = values
200for _index_0 = 1, #_list_0 do 218for _index_0 = 1, #_list_0 do
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