aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--spec/inputs/destructure.yue10
-rw-r--r--spec/inputs/funcs.yue4
-rw-r--r--spec/inputs/string.yue4
-rw-r--r--spec/inputs/unicode/funcs.yue2
-rw-r--r--spec/inputs/unicode/vararg.yue4
-rw-r--r--spec/inputs/vararg.yue4
-rw-r--r--spec/inputs/with.yue4
-rw-r--r--spec/outputs/destructure.lua20
-rw-r--r--spec/outputs/string.lua2
-rw-r--r--src/yuescript/yue_ast.h2
-rw-r--r--src/yuescript/yue_compiler.cpp26
-rw-r--r--src/yuescript/yue_parser.cpp46
-rw-r--r--src/yuescript/yue_parser.h1
13 files changed, 89 insertions, 40 deletions
diff --git a/spec/inputs/destructure.yue b/spec/inputs/destructure.yue
index b6250d0..179056c 100644
--- a/spec/inputs/destructure.yue
+++ b/spec/inputs/destructure.yue
@@ -278,5 +278,15 @@ do
278do 278do
279 {a, :abc, b, :def, ...sub, d, e} = tb 279 {a, :abc, b, :def, ...sub, d, e} = tb
280 280
281do
282 for {:a, :b} in *items
283 print a, b
284
285 for :a, :b in *items
286 print a, b
287
288 for :body in pairs data
289 print body if body
290
281nil 291nil
282 292
diff --git a/spec/inputs/funcs.yue b/spec/inputs/funcs.yue
index 6b1669b..d19c2d1 100644
--- a/spec/inputs/funcs.yue
+++ b/spec/inputs/funcs.yue
@@ -98,7 +98,7 @@ f(
98 98
99x = (a, 99x = (a,
100 b) -> 100 b) ->
101 print "what" 101 print "what"
102 102
103 103
104y = (a="hi", 104y = (a="hi",
@@ -211,7 +211,7 @@ do
211 print "kv:", k, v 211 print "kv:", k, v
212 print "rest count:", select "#", ... 212 print "rest count:", select "#", ...
213 macro gen = (fname) -> | 213 macro gen = (fname) -> |
214 #{fname} = ({:a, :b = 0}) -> print a, b 214 #{fname} = ({:a, :b = 0}) -> print a, b
215 $gen foo 215 $gen foo
216 t1 = (:a, x) -> print a, x 216 t1 = (:a, x) -> print a, x
217 t2 = (:a) -> print a 217 t2 = (:a) -> print a
diff --git a/spec/inputs/string.yue b/spec/inputs/string.yue
index 1f0fba8..611205d 100644
--- a/spec/inputs/string.yue
+++ b/spec/inputs/string.yue
@@ -100,8 +100,8 @@ do
100 next: 123 100 next: 123
101 str = | 101 str = |
102 list: 102 list:
103 - "one" 103 - "one"
104 - "two" 104 - "two"
105 str = | 105 str = |
106 -- comment 106 -- comment
107 content text 107 content text
diff --git a/spec/inputs/unicode/funcs.yue b/spec/inputs/unicode/funcs.yue
index c563356..cb35500 100644
--- a/spec/inputs/unicode/funcs.yue
+++ b/spec/inputs/unicode/funcs.yue
@@ -98,7 +98,7 @@ _无效变量 = -> 真名 if 某物
98 98
99变量x = (参数a, 99变量x = (参数a,
100 参数b) -> 100 参数b) ->
101 打印 "什么" 101 打印 "什么"
102 102
103 103
104变量y = (参数a="hi", 104变量y = (参数a="hi",
diff --git a/spec/inputs/unicode/vararg.yue b/spec/inputs/unicode/vararg.yue
index e59e114..b508fbb 100644
--- a/spec/inputs/unicode/vararg.yue
+++ b/spec/inputs/unicode/vararg.yue
@@ -55,12 +55,12 @@
55 _ = -> 55 _ = ->
56 列表 = {1, 2, 3, 4, 5} 56 列表 = {1, 2, 3, 4, 5}
57 函数名 = (确定) -> 57 函数名 = (确定) ->
58 确定, table.unpack 列表 58 确定, table.unpack 列表
59 确定, ... = 函数名 true 59 确定, ... = 函数名 true
60 打印 确定, ... 60 打印 确定, ...
61 61
62 多参数函数 = -> 62 多参数函数 = ->
63 10, nil, 20, nil, 30 63 10, nil, 20, nil, 30
64 64
65 ... = 多参数函数! 65 ... = 多参数函数!
66 打印 select "#", ... 66 打印 select "#", ...
diff --git a/spec/inputs/vararg.yue b/spec/inputs/vararg.yue
index 941cd97..6100250 100644
--- a/spec/inputs/vararg.yue
+++ b/spec/inputs/vararg.yue
@@ -55,12 +55,12 @@ join = (...) ->
55 _ = -> 55 _ = ->
56 list = {1, 2, 3, 4, 5} 56 list = {1, 2, 3, 4, 5}
57 fn = (ok) -> 57 fn = (ok) ->
58 ok, table.unpack list 58 ok, table.unpack list
59 ok, ... = fn true 59 ok, ... = fn true
60 print ok, ... 60 print ok, ...
61 61
62 fn_many_args = -> 62 fn_many_args = ->
63 10, nil, 20, nil, 30 63 10, nil, 20, nil, 30
64 64
65 ... = fn_many_args! 65 ... = fn_many_args!
66 print select "#", ... 66 print select "#", ...
diff --git a/spec/inputs/with.yue b/spec/inputs/with.yue
index 2256833..19ed2a7 100644
--- a/spec/inputs/with.yue
+++ b/spec/inputs/with.yue
@@ -167,7 +167,7 @@ do
167 167
168do 168do
169 a = for i = 1, 100 169 a = for i = 1, 100
170 with? x := tb[i] 170 with? x := tb[i]
171 break x if .id := 1 171 break x if .id := 1
172 172
173nil 173nil
diff --git a/spec/outputs/destructure.lua b/spec/outputs/destructure.lua
index ba216b5..4e19aca 100644
--- a/spec/outputs/destructure.lua
+++ b/spec/outputs/destructure.lua
@@ -711,4 +711,24 @@ do
711 return _accum_0 711 return _accum_0
712 end)(), _obj_0[#_obj_0 - 1], _obj_0[#_obj_0] 712 end)(), _obj_0[#_obj_0 - 1], _obj_0[#_obj_0]
713end 713end
714do
715 local _list_0 = items
716 for _index_0 = 1, #_list_0 do
717 local _des_0 = _list_0[_index_0]
718 local a, b = _des_0.a, _des_0.b
719 print(a, b)
720 end
721 local _list_1 = items
722 for _index_0 = 1, #_list_1 do
723 local _des_0 = _list_1[_index_0]
724 local a, b = _des_0.a, _des_0.b
725 print(a, b)
726 end
727 for _des_0 in pairs(data) do
728 local body = _des_0.body
729 if body then
730 print(body)
731 end
732 end
733end
714return nil 734return nil
diff --git a/spec/outputs/string.lua b/spec/outputs/string.lua
index b536e6d..bdfd676 100644
--- a/spec/outputs/string.lua
+++ b/spec/outputs/string.lua
@@ -52,7 +52,7 @@ do
52 str = "user: " .. tostring(name) .. "\nid: " .. tostring(id) 52 str = "user: " .. tostring(name) .. "\nid: " .. tostring(id)
53 str = "path: \"C:\\\\Program Files\\\\App\"\ndesc: 'single \"quote\" test'" 53 str = "path: \"C:\\\\Program Files\\\\App\"\ndesc: 'single \"quote\" test'"
54 str = "key: value \nnext: 123 " 54 str = "key: value \nnext: 123 "
55 str = "list:\n - \"one\"\n - \"two\"" 55 str = "list:\n\t- \"one\"\n\t- \"two\""
56 str = "-- comment\ncontent text\n-- comment" 56 str = "-- comment\ncontent text\n-- comment"
57 str = tostring(1 + 2) .. '\n' .. tostring(2 + 3) .. '\n' .. tostring("a" .. "b") 57 str = tostring(1 + 2) .. '\n' .. tostring(2 + 3) .. '\n' .. tostring("a" .. "b")
58 local obj = { 58 local obj = {
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index 0008fd6..5f04fa0 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -848,7 +848,7 @@ AST_NODE(Macro)
848AST_END(Macro) 848AST_END(Macro)
849 849
850AST_NODE(NameOrDestructure) 850AST_NODE(NameOrDestructure)
851 ast_sel<true, Variable_t, TableLit_t, Comprehension_t> item; 851 ast_sel<true, Variable_t, SimpleTable_t, TableLit_t, Comprehension_t> item;
852 AST_MEMBER(NameOrDestructure, &item) 852 AST_MEMBER(NameOrDestructure, &item)
853AST_END(NameOrDestructure) 853AST_END(NameOrDestructure)
854 854
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index d6db3fc..55ab4ec 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = {
78 "close"s // Lua 5.4 78 "close"s // Lua 5.4
79}; 79};
80 80
81const std::string_view version = "0.29.8"sv; 81const std::string_view version = "0.29.9"sv;
82const std::string_view extension = "yue"sv; 82const std::string_view extension = "yue"sv;
83 83
84class CompileError : public std::logic_error { 84class CompileError : public std::logic_error {
@@ -8427,13 +8427,8 @@ private:
8427 varConstAfter = vars.back(); 8427 varConstAfter = vars.back();
8428 } 8428 }
8429 break; 8429 break;
8430 case id<TableLit_t>(): { 8430 case id<SimpleTable_t>():
8431 auto desVar = getUnusedName("_des_"sv); 8431 case id<TableLit_t>():
8432 destructPairs.emplace_back(item, toAst<Exp_t>(desVar, x));
8433 vars.push_back(desVar);
8434 varAfter.push_back(desVar);
8435 break;
8436 }
8437 case id<Comprehension_t>(): { 8432 case id<Comprehension_t>(): {
8438 auto desVar = getUnusedName("_des_"sv); 8433 auto desVar = getUnusedName("_des_"sv);
8439 destructPairs.emplace_back(item, toAst<Exp_t>(desVar, x)); 8434 destructPairs.emplace_back(item, toAst<Exp_t>(desVar, x));
@@ -8642,11 +8637,18 @@ private:
8642 if (!destructPairs.empty()) { 8637 if (!destructPairs.empty()) {
8643 temp.clear(); 8638 temp.clear();
8644 for (auto& pair : destructPairs) { 8639 for (auto& pair : destructPairs) {
8645 auto sValue = x->new_ptr<SimpleValue_t>();
8646 sValue->value.set(pair.first);
8647 auto exp = newExp(sValue, x);
8648 auto expList = x->new_ptr<ExpList_t>(); 8640 auto expList = x->new_ptr<ExpList_t>();
8649 expList->exprs.push_back(exp); 8641 if (ast_is<SimpleTable_t>(pair.first)) {
8642 auto value = x->new_ptr<Value_t>();
8643 value->item.set(pair.first);
8644 auto exp = newExp(value, x);
8645 expList->exprs.push_back(exp);
8646 } else {
8647 auto sValue = x->new_ptr<SimpleValue_t>();
8648 sValue->value.set(pair.first);
8649 auto exp = newExp(sValue, x);
8650 expList->exprs.push_back(exp);
8651 }
8650 auto assign = x->new_ptr<Assign_t>(); 8652 auto assign = x->new_ptr<Assign_t>();
8651 assign->values.push_back(pair.second); 8653 assign->values.push_back(pair.second);
8652 auto assignment = x->new_ptr<ExpListAssign_t>(); 8654 auto assignment = x->new_ptr<ExpListAssign_t>();
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index fccb6fb..cbba115 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -232,27 +232,43 @@ YueParser::YueParser() {
232 KeyName = SelfItem | Name | UnicodeName; 232 KeyName = SelfItem | Name | UnicodeName;
233 VarArg = "..."; 233 VarArg = "...";
234 234
235 check_indent = pl::user(plain_space, [](const item_t& item) { 235 auto getIndent = [](const item_t& item) -> int {
236 if (item.begin->m_it == item.end->m_it) return 0;
237 State* st = reinterpret_cast<State*>(item.user_data);
238 bool useTab = false;
239 if (st->useTab) {
240 useTab = st->useTab.value();
241 } else {
242 useTab = *item.begin->m_it == '\t';
243 st->useTab = useTab;
244 }
236 int indent = 0; 245 int indent = 0;
237 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { 246 if (useTab) {
238 switch (*i) { 247 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
239 case ' ': indent++; break; 248 switch (*i) {
240 case '\t': indent += 4; break; 249 case '\t': indent += 4; break;
250 default: throw ParserError("can not mix the use of tabs and spaces as indents"sv, item.begin); break;
251 }
252 }
253 } else {
254 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
255 switch (*i) {
256 case ' ': indent++; break;
257 default: throw ParserError("can not mix the use of tabs and spaces as indents"sv, item.begin); break;
258 }
241 } 259 }
242 } 260 }
261 return indent;
262 };
263
264 check_indent = pl::user(plain_space, [getIndent](const item_t& item) {
243 State* st = reinterpret_cast<State*>(item.user_data); 265 State* st = reinterpret_cast<State*>(item.user_data);
244 return st->indents.top() == indent; 266 return st->indents.top() == getIndent(item);
245 }); 267 });
246 check_indent_match = and_(check_indent); 268 check_indent_match = and_(check_indent);
247 269
248 advance = pl::user(plain_space, [](const item_t& item) { 270 advance = pl::user(plain_space, [getIndent](const item_t& item) {
249 int indent = 0; 271 int indent = getIndent(item);
250 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
251 switch (*i) {
252 case ' ': indent++; break;
253 case '\t': indent += 4; break;
254 }
255 }
256 State* st = reinterpret_cast<State*>(item.user_data); 272 State* st = reinterpret_cast<State*>(item.user_data);
257 int top = st->indents.top(); 273 int top = st->indents.top();
258 if (top != -1 && indent > top) { 274 if (top != -1 && indent > top) {
@@ -921,7 +937,7 @@ YueParser::YueParser() {
921 MacroInPlace = '$' >> space >> "->" >> space >> Body; 937 MacroInPlace = '$' >> space >> "->" >> space >> Body;
922 938
923 NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable); 939 NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable);
924 NameOrDestructure = Variable | TableLit | Comprehension; 940 NameOrDestructure = Variable | TableLit | Comprehension | SimpleTable;
925 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure); 941 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure);
926 942
927 FnArrowBack = '<' >> set("-="); 943 FnArrowBack = '<' >> set("-=");
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index 4c546b1..d5c37e2 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -119,6 +119,7 @@ protected:
119 int expLevel = 0; 119 int expLevel = 0;
120 size_t stringOpen = 0; 120 size_t stringOpen = 0;
121 std::string buffer; 121 std::string buffer;
122 std::optional<bool> useTab;
122 std::stack<int> indents; 123 std::stack<int> indents;
123 std::vector<bool> noDoStack; 124 std::vector<bool> noDoStack;
124 std::vector<bool> noChainBlockStack; 125 std::vector<bool> noChainBlockStack;