aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2023-06-07 09:42:50 +0800
committerLi Jin <dragon-fly@qq.com>2023-06-07 09:42:50 +0800
commit2a3e50752ade96c3b5d6b1103937bef0f6b31157 (patch)
treef7ae2654ac96009a9e5dbe9667e480cc920a2868
parent738154d37dd4ec20b09acd0f9f81601d0dc069ba (diff)
downloadyuescript-2a3e50752ade96c3b5d6b1103937bef0f6b31157.tar.gz
yuescript-2a3e50752ade96c3b5d6b1103937bef0f6b31157.tar.bz2
yuescript-2a3e50752ade96c3b5d6b1103937bef0f6b31157.zip
add new syntax of in-expression.
-rw-r--r--spec/inputs/in_expression.yue26
-rw-r--r--spec/outputs/in_expression.lua36
-rw-r--r--src/.clang-format39
-rw-r--r--src/yuescript/ast.hpp3
-rw-r--r--src/yuescript/yue_ast.h138
-rw-r--r--src/yuescript/yue_compiler.cpp188
-rw-r--r--src/yuescript/yue_parser.cpp21
-rw-r--r--src/yuescript/yue_parser.h10
8 files changed, 351 insertions, 110 deletions
diff --git a/spec/inputs/in_expression.yue b/spec/inputs/in_expression.yue
new file mode 100644
index 0000000..2756fe8
--- /dev/null
+++ b/spec/inputs/in_expression.yue
@@ -0,0 +1,26 @@
1-a^2 in {1, 2, 3} |> f
2
3a, b = x(...) not in [1, 3], 2
4
5d = (tb.x.y ...) not in [1, 3]
6
7if a in {1} and b in {2, 3, 4} or c in [1, 10]
8 print a, b, c
9
10switch val
11 when 1, 2, 3
12 print "1, 2, 3"
13
14 when not in (0, 100]
15 print "not (0 < val <= 100)"
16
17 when in [200, 300)
18 print "200 <= val < 300)"
19
20 when not in {333, 444, 555}
21 print "not 333, 444 or 555"
22
23do return y not in (a, b)
24
25nil
26
diff --git a/spec/outputs/in_expression.lua b/spec/outputs/in_expression.lua
new file mode 100644
index 0000000..061431f
--- /dev/null
+++ b/spec/outputs/in_expression.lua
@@ -0,0 +1,36 @@
1f((function()
2 local _val_0 = -a ^ 2
3 return 1 == _val_0 or 2 == _val_0 or 3 == _val_0
4end)())
5local a, b = (function(...)
6 local _val_0 = x(...)
7 return not (1 <= _val_0 and _val_0 <= 3)
8end)(...), 2
9local d
10do
11 local _val_0 = (tb.x.y(...))
12 d = not (1 <= _val_0 and _val_0 <= 3)
13end
14if (1 == a) and (2 == b or 3 == b or 4 == b) or (function()
15 local _val_0 = c
16 return 1 <= _val_0 and _val_0 <= 10
17end)() then
18 print(a, b, c)
19end
20do
21 local _exp_0 = val
22 if 1 == _exp_0 or 2 == _exp_0 or 3 == _exp_0 then
23 print("1, 2, 3")
24 elseif not (0 < _exp_0 and _exp_0 <= 100) then
25 print("not (0 < val <= 100)")
26 elseif (200 <= _exp_0 and _exp_0 < 300) then
27 print("200 <= val < 300)")
28 elseif not (333 == _exp_0 or 444 == _exp_0 or 555 == _exp_0) then
29 print("not 333, 444 or 555")
30 end
31end
32do
33 local _val_0 = y
34 return not (a < _val_0 and _val_0 < b)
35end
36return nil
diff --git a/src/.clang-format b/src/.clang-format
index 5d305ae..6b3ad7b 100644
--- a/src/.clang-format
+++ b/src/.clang-format
@@ -1,17 +1,24 @@
1# Format Style Options - Created with Clang Power Tools 1# Format Style Options - Created with Clang Power Tools
2--- 2---
3BasedOnStyle: WebKit 3BasedOnStyle: WebKit
4AllowShortCaseLabelsOnASingleLine: true 4AllowShortCaseLabelsOnASingleLine: true
5AllowShortIfStatementsOnASingleLine: WithoutElse 5AllowShortIfStatementsOnASingleLine: WithoutElse
6AllowShortLoopsOnASingleLine: true 6AllowShortLoopsOnASingleLine: true
7BreakBeforeBraces: Attach 7BreakBeforeBraces: Attach
8Cpp11BracedListStyle: true 8Cpp11BracedListStyle: true
9IndentCaseLabels: true 9IndentCaseLabels: true
10NamespaceIndentation: None 10NamespaceIndentation: None
11SpaceBeforeCpp11BracedList: false 11SpaceBeforeCpp11BracedList: false
12TabWidth: 4 12TabWidth: 4
13AlignEscapedNewlines: DontAlign 13AlignEscapedNewlines: DontAlign
14AlwaysBreakBeforeMultilineStrings: true 14AlwaysBreakBeforeMultilineStrings: true
15FixNamespaceComments: true 15FixNamespaceComments: true
16UseTab: Always 16UseTab: Always
17... 17AlignOperands: AlignAfterOperator
18AllowShortLambdasOnASingleLine: Empty
19LambdaBodyIndentation: Signature
20AlignAfterOpenBracket: DontAlign
21ContinuationIndentWidth: 4
22ObjCBlockIndentWidth: 4
23ConstructorInitializerIndentWidth: 4
24...
diff --git a/src/yuescript/ast.hpp b/src/yuescript/ast.hpp
index 3443c7f..c6da312 100644
--- a/src/yuescript/ast.hpp
+++ b/src/yuescript/ast.hpp
@@ -21,6 +21,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 21
22namespace parserlib { 22namespace parserlib {
23 23
24using namespace std::string_view_literals;
25
24class ast_node; 26class ast_node;
25template <bool Required, class T> 27template <bool Required, class T>
26class ast_ptr; 28class ast_ptr;
@@ -50,7 +52,6 @@ struct Counter<0> {
50 enum { value = Counter<__LINE__ - 1>::value + 1 }; \ 52 enum { value = Counter<__LINE__ - 1>::value + 1 }; \
51 } 53 }
52 54
53class ast_node;
54template <class T> 55template <class T>
55constexpr typename std::enable_if<std::is_base_of<ast_node, T>::value, int>::type 56constexpr typename std::enable_if<std::is_base_of<ast_node, T>::value, int>::type
56id(); 57id();
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index 65008fb..acb7221 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -11,16 +11,17 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
11#include "yuescript/ast.hpp" 11#include "yuescript/ast.hpp"
12 12
13namespace parserlib { 13namespace parserlib {
14using namespace std::string_view_literals;
15 14
16#define AST_LEAF(type) \ 15#define AST_LEAF(type) \
17 COUNTER_INC; \ 16 COUNTER_INC; \
17 namespace yue { \
18 class type##_t : public ast_node { \ 18 class type##_t : public ast_node { \
19 public: \ 19 public: \
20 virtual int getId() const override { return COUNTER_READ; } 20 virtual int getId() const override { return COUNTER_READ; }
21 21
22#define AST_NODE(type) \ 22#define AST_NODE(type) \
23 COUNTER_INC; \ 23 COUNTER_INC; \
24 namespace yue { \
24 class type##_t : public ast_container { \ 25 class type##_t : public ast_container { \
25 public: \ 26 public: \
26 virtual int getId() const override { return COUNTER_READ; } 27 virtual int getId() const override { return COUNTER_READ; }
@@ -34,11 +35,49 @@ using namespace std::string_view_literals;
34 virtual const std::string_view getName() const override { return name; } \ 35 virtual const std::string_view getName() const override { return name; } \
35 } \ 36 } \
36 ; \ 37 ; \
38 } \
37 template <> \ 39 template <> \
38 constexpr int id<type##_t>() { return COUNTER_READ; } 40 constexpr int id<yue::type##_t>() { return COUNTER_READ; }
39 41
40// clang-format off 42// clang-format off
41 43
44namespace yue {
45class ExpListLow_t;
46class TableBlock_t;
47class Attrib_t;
48class SimpleTable_t;
49class TableLit_t;
50class Assign_t;
51class Exp_t;
52class VariablePair_t;
53class NormalPair_t;
54class MetaVariablePair_t;
55class MetaNormalPair_t;
56class FnArgsDef_t;
57class ChainValue_t;
58class ExistentialOp_t;
59class Block_t;
60class Statement_t;
61class Body_t;
62class AssignableNameList_t;
63class StarExp_t;
64class CompInner_t;
65class AssignableChain_t;
66class UnaryExp_t;
67class Parens_t;
68class MacroName_t;
69class String_t;
70class ConstValue_t;
71class ClassDecl_t;
72class UnaryValue_t;
73class FunLit_t;
74class DefaultValue_t;
75class InvokeArgs_t;
76class TableBlockIndent_t;
77class Macro_t;
78class In_t;
79} // namespace yue
80
42AST_LEAF(Num) 81AST_LEAF(Num)
43AST_END(Num, "num"sv) 82AST_END(Num, "num"sv)
44 83
@@ -101,10 +140,6 @@ AST_NODE(NameList)
101 AST_MEMBER(NameList, &sep, &names) 140 AST_MEMBER(NameList, &sep, &names)
102AST_END(NameList, "name_list"sv) 141AST_END(NameList, "name_list"sv)
103 142
104class ExpListLow_t;
105class TableBlock_t;
106class Attrib_t;
107
108AST_NODE(LocalValues) 143AST_NODE(LocalValues)
109 ast_ptr<true, NameList_t> nameList; 144 ast_ptr<true, NameList_t> nameList;
110 ast_sel<false, TableBlock_t, ExpListLow_t> valueList; 145 ast_sel<false, TableBlock_t, ExpListLow_t> valueList;
@@ -126,10 +161,6 @@ AST_END(ConstAttrib, "const"sv)
126AST_LEAF(CloseAttrib) 161AST_LEAF(CloseAttrib)
127AST_END(CloseAttrib, "close"sv) 162AST_END(CloseAttrib, "close"sv)
128 163
129class SimpleTable_t;
130class TableLit_t;
131class Assign_t;
132
133AST_NODE(LocalAttrib) 164AST_NODE(LocalAttrib)
134 ast_sel<true, ConstAttrib_t, CloseAttrib_t> attrib; 165 ast_sel<true, ConstAttrib_t, CloseAttrib_t> attrib;
135 ast_ptr<true, Seperator_t> sep; 166 ast_ptr<true, Seperator_t> sep;
@@ -152,8 +183,6 @@ AST_NODE(ImportLiteral)
152 AST_MEMBER(ImportLiteral, &sep, &inners) 183 AST_MEMBER(ImportLiteral, &sep, &inners)
153AST_END(ImportLiteral, "import_literal"sv) 184AST_END(ImportLiteral, "import_literal"sv)
154 185
155class Exp_t;
156
157AST_NODE(ImportFrom) 186AST_NODE(ImportFrom)
158 ast_ptr<true, Seperator_t> sep; 187 ast_ptr<true, Seperator_t> sep;
159 ast_sel_list<true, ColonImportName_t, Variable_t> names; 188 ast_sel_list<true, ColonImportName_t, Variable_t> names;
@@ -161,8 +190,6 @@ AST_NODE(ImportFrom)
161 AST_MEMBER(ImportFrom, &sep, &names, &exp) 190 AST_MEMBER(ImportFrom, &sep, &names, &exp)
162AST_END(ImportFrom, "import_from"sv) 191AST_END(ImportFrom, "import_from"sv)
163 192
164class MacroName_t;
165
166AST_NODE(MacroNamePair) 193AST_NODE(MacroNamePair)
167 ast_ptr<true, MacroName_t> key; 194 ast_ptr<true, MacroName_t> key;
168 ast_ptr<true, MacroName_t> value; 195 ast_ptr<true, MacroName_t> value;
@@ -172,11 +199,6 @@ AST_END(MacroNamePair, "macro_name_pair"sv)
172AST_LEAF(ImportAllMacro) 199AST_LEAF(ImportAllMacro)
173AST_END(ImportAllMacro, "import_all_macro"sv) 200AST_END(ImportAllMacro, "import_all_macro"sv)
174 201
175class VariablePair_t;
176class NormalPair_t;
177class MetaVariablePair_t;
178class MetaNormalPair_t;
179
180AST_NODE(ImportTabLit) 202AST_NODE(ImportTabLit)
181 ast_ptr<true, Seperator_t> sep; 203 ast_ptr<true, Seperator_t> sep;
182 ast_sel_list<false, VariablePair_t, NormalPair_t, MacroName_t, MacroNamePair_t, ImportAllMacro_t, Exp_t, MetaVariablePair_t, MetaNormalPair_t> items; 204 ast_sel_list<false, VariablePair_t, NormalPair_t, MacroName_t, MacroNamePair_t, ImportAllMacro_t, Exp_t, MetaVariablePair_t, MetaNormalPair_t> items;
@@ -209,13 +231,9 @@ AST_NODE(ShortTabAppending)
209 AST_MEMBER(ShortTabAppending, &assign) 231 AST_MEMBER(ShortTabAppending, &assign)
210AST_END(ShortTabAppending, "short_table_appending"sv) 232AST_END(ShortTabAppending, "short_table_appending"sv)
211 233
212class FnArgsDef_t;
213
214AST_LEAF(FnArrowBack) 234AST_LEAF(FnArrowBack)
215AST_END(FnArrowBack, "fn_arrow_back"sv) 235AST_END(FnArrowBack, "fn_arrow_back"sv)
216 236
217class ChainValue_t;
218
219AST_NODE(Backcall) 237AST_NODE(Backcall)
220 ast_ptr<false, FnArgsDef_t> argsDef; 238 ast_ptr<false, FnArgsDef_t> argsDef;
221 ast_ptr<true, FnArrowBack_t> arrow; 239 ast_ptr<true, FnArrowBack_t> arrow;
@@ -235,19 +253,12 @@ AST_NODE(ExpList)
235 AST_MEMBER(ExpList, &sep, &exprs) 253 AST_MEMBER(ExpList, &sep, &exprs)
236AST_END(ExpList, "exp_list"sv) 254AST_END(ExpList, "exp_list"sv)
237 255
238class TableBlock_t;
239
240AST_NODE(Return) 256AST_NODE(Return)
241 bool allowBlockMacroReturn = false; 257 bool allowBlockMacroReturn = false;
242 ast_sel<false, TableBlock_t, ExpListLow_t> valueList; 258 ast_sel<false, TableBlock_t, ExpListLow_t> valueList;
243 AST_MEMBER(Return, &valueList) 259 AST_MEMBER(Return, &valueList)
244AST_END(Return, "return"sv) 260AST_END(Return, "return"sv)
245 261
246class ExistentialOp_t;
247class Assign_t;
248class Block_t;
249class Statement_t;
250
251AST_NODE(With) 262AST_NODE(With)
252 ast_ptr<false, ExistentialOp_t> eop; 263 ast_ptr<false, ExistentialOp_t> eop;
253 ast_ptr<true, ExpList_t> valueList; 264 ast_ptr<true, ExpList_t> valueList;
@@ -263,9 +274,9 @@ AST_NODE(SwitchList)
263AST_END(SwitchList, "switch_list"sv) 274AST_END(SwitchList, "switch_list"sv)
264 275
265AST_NODE(SwitchCase) 276AST_NODE(SwitchCase)
266 ast_ptr<true, SwitchList_t> valueList; 277 ast_sel<true, SwitchList_t, In_t> condition;
267 ast_sel<true, Block_t, Statement_t> body; 278 ast_sel<true, Block_t, Statement_t> body;
268 AST_MEMBER(SwitchCase, &valueList, &body) 279 AST_MEMBER(SwitchCase, &condition, &body)
269AST_END(SwitchCase, "switch_case"sv) 280AST_END(SwitchCase, "switch_case"sv)
270 281
271AST_NODE(Switch) 282AST_NODE(Switch)
@@ -306,8 +317,6 @@ AST_NODE(While)
306 AST_MEMBER(While, &type, &condition, &body) 317 AST_MEMBER(While, &type, &condition, &body)
307AST_END(While, "while"sv) 318AST_END(While, "while"sv)
308 319
309class Body_t;
310
311AST_NODE(Repeat) 320AST_NODE(Repeat)
312 ast_ptr<true, Body_t> body; 321 ast_ptr<true, Body_t> body;
313 ast_ptr<true, Exp_t> condition; 322 ast_ptr<true, Exp_t> condition;
@@ -328,9 +337,6 @@ AST_NODE(For)
328 AST_MEMBER(For, &varName, &startValue, &stopValue, &stepValue, &body) 337 AST_MEMBER(For, &varName, &startValue, &stopValue, &stepValue, &body)
329AST_END(For, "for"sv) 338AST_END(For, "for"sv)
330 339
331class AssignableNameList_t;
332class StarExp_t;
333
334AST_NODE(ForEach) 340AST_NODE(ForEach)
335 ast_ptr<true, AssignableNameList_t> nameList; 341 ast_ptr<true, AssignableNameList_t> nameList;
336 ast_sel<true, StarExp_t, ExpList_t> loopValue; 342 ast_sel<true, StarExp_t, ExpList_t> loopValue;
@@ -355,8 +361,6 @@ AST_NODE(Try)
355 AST_MEMBER(Try, &func, &catchBlock) 361 AST_MEMBER(Try, &func, &catchBlock)
356AST_END(Try, "try"sv) 362AST_END(Try, "try"sv)
357 363
358class CompInner_t;
359
360AST_NODE(Comprehension) 364AST_NODE(Comprehension)
361 ast_sel<true, Exp_t, Statement_t> value; 365 ast_sel<true, Exp_t, Statement_t> value;
362 ast_ptr<true, CompInner_t> forLoop; 366 ast_ptr<true, CompInner_t> forLoop;
@@ -400,8 +404,6 @@ AST_NODE(CompInner)
400 AST_MEMBER(CompInner, &sep, &items) 404 AST_MEMBER(CompInner, &sep, &items)
401AST_END(CompInner, "comp_inner"sv) 405AST_END(CompInner, "comp_inner"sv)
402 406
403class TableBlock_t;
404
405AST_NODE(Assign) 407AST_NODE(Assign)
406 ast_ptr<true, Seperator_t> sep; 408 ast_ptr<true, Seperator_t> sep;
407 ast_sel_list<true, With_t, If_t, Switch_t, TableBlock_t, Exp_t> values; 409 ast_sel_list<true, With_t, If_t, Switch_t, TableBlock_t, Exp_t> values;
@@ -423,15 +425,40 @@ AST_END(BinaryOperator, "binary_op"sv)
423AST_LEAF(UnaryOperator) 425AST_LEAF(UnaryOperator)
424AST_END(UnaryOperator, "unary_op"sv) 426AST_END(UnaryOperator, "unary_op"sv)
425 427
426class AssignableChain_t; 428AST_LEAF(InRangeOpen)
429AST_END(InRangeOpen, "in_range_open"sv)
430
431AST_LEAF(InRangeClose)
432AST_END(InRangeClose, "in_range_close"sv)
433
434AST_LEAF(NotIn)
435AST_END(NotIn, "not_in"sv)
436
437AST_NODE(InRange)
438 ast_sel<true, InRangeOpen_t, InRangeClose_t> open;
439 ast_ptr<true, Exp_t> openValue;
440 ast_ptr<true, Exp_t> closeValue;
441 ast_sel<true, InRangeOpen_t, InRangeClose_t> close;
442 AST_MEMBER(InRange, &open, &openValue, &closeValue, &close)
443AST_END(InRange, "in_range"sv)
444
445AST_NODE(InDiscrete)
446 ast_ptr<true, Seperator_t> sep;
447 ast_list<true, Exp_t> values;
448 AST_MEMBER(InDiscrete, &sep, &values)
449AST_END(InDiscrete, "in_discrete"sv)
450
451AST_NODE(In)
452 ast_ptr<false, NotIn_t> not_;
453 ast_sel<true, InRange_t, InDiscrete_t> item;
454 AST_MEMBER(In, &not_, &item)
455AST_END(In, "in"sv)
427 456
428AST_NODE(Assignable) 457AST_NODE(Assignable)
429 ast_sel<true, AssignableChain_t, Variable_t, SelfItem_t> item; 458 ast_sel<true, AssignableChain_t, Variable_t, SelfItem_t> item;
430 AST_MEMBER(Assignable, &item) 459 AST_MEMBER(Assignable, &item)
431AST_END(Assignable, "assignable"sv) 460AST_END(Assignable, "assignable"sv)
432 461
433class UnaryExp_t;
434
435AST_NODE(ExpOpValue) 462AST_NODE(ExpOpValue)
436 ast_ptr<true, BinaryOperator_t> op; 463 ast_ptr<true, BinaryOperator_t> op;
437 ast_list<true, UnaryExp_t> pipeExprs; 464 ast_list<true, UnaryExp_t> pipeExprs;
@@ -446,9 +473,6 @@ AST_NODE(Exp)
446 AST_MEMBER(Exp, &sep, &pipeExprs, &opValues, &nilCoalesed) 473 AST_MEMBER(Exp, &sep, &pipeExprs, &opValues, &nilCoalesed)
447AST_END(Exp, "exp"sv) 474AST_END(Exp, "exp"sv)
448 475
449class Parens_t;
450class MacroName_t;
451
452AST_NODE(Callable) 476AST_NODE(Callable)
453 ast_sel<true, Variable_t, SelfItem_t, Parens_t, MacroName_t> item; 477 ast_sel<true, Variable_t, SelfItem_t, Parens_t, MacroName_t> item;
454 AST_MEMBER(Callable, &item) 478 AST_MEMBER(Callable, &item)
@@ -465,8 +489,6 @@ AST_NODE(VariablePairDef)
465 AST_MEMBER(VariablePairDef, &pair, &defVal) 489 AST_MEMBER(VariablePairDef, &pair, &defVal)
466AST_END(VariablePairDef, "variable_pair_def"sv) 490AST_END(VariablePairDef, "variable_pair_def"sv)
467 491
468class String_t;
469
470AST_NODE(NormalPair) 492AST_NODE(NormalPair)
471 ast_sel<true, KeyName_t, Exp_t, String_t> key; 493 ast_sel<true, KeyName_t, Exp_t, String_t> key;
472 ast_sel<true, Exp_t, TableBlock_t> value; 494 ast_sel<true, Exp_t, TableBlock_t> value;
@@ -515,11 +537,6 @@ AST_NODE(SimpleTable)
515 AST_MEMBER(SimpleTable, &sep, &pairs) 537 AST_MEMBER(SimpleTable, &sep, &pairs)
516AST_END(SimpleTable, "simple_table"sv) 538AST_END(SimpleTable, "simple_table"sv)
517 539
518class ConstValue_t;
519class ClassDecl_t;
520class UnaryValue_t;
521class FunLit_t;
522
523AST_NODE(SimpleValue) 540AST_NODE(SimpleValue)
524 ast_sel<true, 541 ast_sel<true,
525 TableLit_t, ConstValue_t, 542 TableLit_t, ConstValue_t,
@@ -588,8 +605,6 @@ AST_NODE(ColonChainItem)
588 AST_MEMBER(ColonChainItem, &name) 605 AST_MEMBER(ColonChainItem, &name)
589AST_END(ColonChainItem, "colon_chain_item"sv) 606AST_END(ColonChainItem, "colon_chain_item"sv)
590 607
591class DefaultValue_t;
592
593AST_NODE(Slice) 608AST_NODE(Slice)
594 ast_sel<true, Exp_t, DefaultValue_t> startValue; 609 ast_sel<true, Exp_t, DefaultValue_t> startValue;
595 ast_sel<true, Exp_t, DefaultValue_t> stopValue; 610 ast_sel<true, Exp_t, DefaultValue_t> stopValue;
@@ -614,8 +629,6 @@ AST_END(ExistentialOp, "existential_op"sv)
614AST_LEAF(TableAppendingOp) 629AST_LEAF(TableAppendingOp)
615AST_END(TableAppendingOp, "table_appending_op"sv) 630AST_END(TableAppendingOp, "table_appending_op"sv)
616 631
617class InvokeArgs_t;
618
619AST_NODE(ChainValue) 632AST_NODE(ChainValue)
620 ast_ptr<true, Seperator_t> sep; 633 ast_ptr<true, Seperator_t> sep;
621 ast_sel_list<true, Callable_t, Invoke_t, DotChainItem_t, ColonChainItem_t, Slice_t, Exp_t, String_t, InvokeArgs_t, ExistentialOp_t, TableAppendingOp_t> items; 634 ast_sel_list<true, Callable_t, Invoke_t, DotChainItem_t, ColonChainItem_t, Slice_t, Exp_t, String_t, InvokeArgs_t, ExistentialOp_t, TableAppendingOp_t> items;
@@ -641,8 +654,6 @@ AST_NODE(SpreadExp)
641 AST_MEMBER(SpreadExp, &exp) 654 AST_MEMBER(SpreadExp, &exp)
642AST_END(SpreadExp, "spread_exp"sv) 655AST_END(SpreadExp, "spread_exp"sv)
643 656
644class TableBlockIndent_t;
645
646AST_NODE(TableLit) 657AST_NODE(TableLit)
647 ast_ptr<true, Seperator_t> sep; 658 ast_ptr<true, Seperator_t> sep;
648 ast_sel_list<false, 659 ast_sel_list<false,
@@ -704,8 +715,6 @@ AST_END(Global, "global"sv)
704AST_LEAF(ExportDefault) 715AST_LEAF(ExportDefault)
705AST_END(ExportDefault, "export_default"sv) 716AST_END(ExportDefault, "export_default"sv)
706 717
707class Macro_t;
708
709AST_NODE(Export) 718AST_NODE(Export)
710 ast_ptr<false, ExportDefault_t> def; 719 ast_ptr<false, ExportDefault_t> def;
711 ast_sel<true, ExpList_t, Exp_t, Macro_t, DotChainItem_t> target; 720 ast_sel<true, ExpList_t, Exp_t, Macro_t, DotChainItem_t> target;
@@ -799,7 +808,8 @@ AST_END(UnaryValue, "unary_value"sv)
799AST_NODE(UnaryExp) 808AST_NODE(UnaryExp)
800 ast_list<false, UnaryOperator_t> ops; 809 ast_list<false, UnaryOperator_t> ops;
801 ast_list<true, Value_t> expos; 810 ast_list<true, Value_t> expos;
802 AST_MEMBER(UnaryExp, &ops, &expos) 811 ast_ptr<false, In_t> inExp;
812 AST_MEMBER(UnaryExp, &ops, &expos, &inExp)
803AST_END(UnaryExp, "unary_exp"sv) 813AST_END(UnaryExp, "unary_exp"sv)
804 814
805AST_NODE(ExpListAssign) 815AST_NODE(ExpListAssign)
@@ -869,8 +879,6 @@ AST_NODE(Statement)
869 AST_MEMBER(Statement, &sep, &comments, &content, &appendix, &needSep) 879 AST_MEMBER(Statement, &sep, &comments, &content, &appendix, &needSep)
870AST_END(Statement, "statement"sv) 880AST_END(Statement, "statement"sv)
871 881
872class Block_t;
873
874AST_NODE(Body) 882AST_NODE(Body)
875 ast_sel<true, Block_t, Statement_t> content; 883 ast_sel<true, Block_t, Statement_t> content;
876 AST_MEMBER(Body, &content) 884 AST_MEMBER(Body, &content)
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index e0ff9e9..98d19a7 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -72,7 +72,7 @@ static std::unordered_set<std::string> Metamethods = {
72 "close"s // Lua 5.4 72 "close"s // Lua 5.4
73}; 73};
74 74
75const std::string_view version = "0.16.8"sv; 75const std::string_view version = "0.17.0"sv;
76const std::string_view extension = "yue"sv; 76const std::string_view extension = "yue"sv;
77 77
78class CompileError : public std::logic_error { 78class CompileError : public std::logic_error {
@@ -761,7 +761,7 @@ private:
761 } 761 }
762 case id<UnaryExp_t>(): { 762 case id<UnaryExp_t>(): {
763 auto unary = static_cast<UnaryExp_t*>(item); 763 auto unary = static_cast<UnaryExp_t*>(item);
764 if (unary->expos.size() == 1) { 764 if (unary->expos.size() == 1 && !unary->inExp) {
765 return unary; 765 return unary;
766 } 766 }
767 return nullptr; 767 return nullptr;
@@ -774,7 +774,7 @@ private:
774 BREAK_IF(!exp->opValues.empty()); 774 BREAK_IF(!exp->opValues.empty());
775 BREAK_IF(exp->pipeExprs.size() != 1); 775 BREAK_IF(exp->pipeExprs.size() != 1);
776 auto unary = static_cast<UnaryExp_t*>(exp->pipeExprs.back()); 776 auto unary = static_cast<UnaryExp_t*>(exp->pipeExprs.back());
777 BREAK_IF(unary->expos.size() != 1); 777 BREAK_IF(unary->expos.size() != 1 || unary->inExp);
778 return unary; 778 return unary;
779 BLOCK_END 779 BLOCK_END
780 return nullptr; 780 return nullptr;
@@ -1028,9 +1028,12 @@ private:
1028 } 1028 }
1029 1029
1030 std::string singleVariableFrom(ast_node* expList, bool accessing) { 1030 std::string singleVariableFrom(ast_node* expList, bool accessing) {
1031 if (!ast_is<Exp_t, ExpList_t>(expList)) return Empty; 1031 if (!ast_is<Exp_t, ExpList_t, Value_t>(expList)) return Empty;
1032 BLOCK_START 1032 BLOCK_START
1033 auto value = singleValueFrom(expList); 1033 auto value = ast_cast<Value_t>(expList);
1034 if (!value) {
1035 value = singleValueFrom(expList);
1036 }
1034 BREAK_IF(!value); 1037 BREAK_IF(!value);
1035 auto chainValue = value->item.as<ChainValue_t>(); 1038 auto chainValue = value->item.as<ChainValue_t>();
1036 BREAK_IF(!chainValue); 1039 BREAK_IF(!chainValue);
@@ -1157,6 +1160,24 @@ private:
1157 return false; 1160 return false;
1158 } 1161 }
1159 1162
1163 UnaryExp_t* unaryGeneratingAnonFunc(Exp_t* exp) {
1164 if (!exp) return nullptr;
1165 BLOCK_START
1166 BREAK_IF(exp->nilCoalesed);
1167 BREAK_IF(!exp->opValues.empty());
1168 BREAK_IF(exp->pipeExprs.size() != 1);
1169 auto unary = static_cast<UnaryExp_t*>(exp->pipeExprs.back());
1170 BREAK_IF(unary->expos.size() != 1);
1171 BREAK_IF(!unary->inExp);
1172 auto value = static_cast<Value_t*>(unary->expos.back());
1173 auto varName = singleVariableFrom(value, false);
1174 if (varName.empty() || !isLocal(varName)) {
1175 return unary;
1176 }
1177 BLOCK_END
1178 return nullptr;
1179 }
1180
1160 void pushFunctionScope() { 1181 void pushFunctionScope() {
1161 _enableReturn.push(true); 1182 _enableReturn.push(true);
1162 _enableBreakLoop.push(false); 1183 _enableBreakLoop.push(false);
@@ -1971,6 +1992,12 @@ private:
1971 auto expList = assignment->expList.get(); 1992 auto expList = assignment->expList.get();
1972 transformNilCoalesedExp(exp, out, ExpUsage::Assignment, expList); 1993 transformNilCoalesedExp(exp, out, ExpUsage::Assignment, expList);
1973 return; 1994 return;
1995 } else if (auto unary = unaryGeneratingAnonFunc(exp)) {
1996 std::string preDefine = getPreDefineLine(assignment);
1997 auto expList = assignment->expList.get();
1998 transformUnaryExp(unary, out, ExpUsage::Assignment, expList);
1999 out.back().insert(0, preDefine);
2000 return;
1974 } 2001 }
1975 auto singleVal = singleValueFrom(exp); 2002 auto singleVal = singleValueFrom(exp);
1976 BREAK_IF(!singleVal); 2003 BREAK_IF(!singleVal);
@@ -3134,7 +3161,7 @@ private:
3134 3161
3135 void transform_pipe_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 3162 void transform_pipe_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
3136 if (values.size() == 1 && usage == ExpUsage::Closure) { 3163 if (values.size() == 1 && usage == ExpUsage::Closure) {
3137 transform_unary_exp(static_cast<UnaryExp_t*>(values.front()), out); 3164 transformUnaryExp(static_cast<UnaryExp_t*>(values.front()), out, ExpUsage::Closure);
3138 } else { 3165 } else {
3139 auto x = values.front(); 3166 auto x = values.front();
3140 auto arg = newExp(static_cast<UnaryExp_t*>(x), x); 3167 auto arg = newExp(static_cast<UnaryExp_t*>(x), x);
@@ -3404,7 +3431,7 @@ private:
3404 void transformSimpleValue(SimpleValue_t* simpleValue, str_list& out) { 3431 void transformSimpleValue(SimpleValue_t* simpleValue, str_list& out) {
3405 auto value = simpleValue->value.get(); 3432 auto value = simpleValue->value.get();
3406 switch (value->getId()) { 3433 switch (value->getId()) {
3407 case id<ConstValue_t>(): transform_const_value(static_cast<ConstValue_t*>(value), out); break; 3434 case id<ConstValue_t>(): transformConstValue(static_cast<ConstValue_t*>(value), out); break;
3408 case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break; 3435 case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break;
3409 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break; 3436 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break;
3410 case id<With_t>(): transformWithClosure(static_cast<With_t*>(value), out); break; 3437 case id<With_t>(): transformWithClosure(static_cast<With_t*>(value), out); break;
@@ -3414,7 +3441,7 @@ private:
3414 case id<While_t>(): transformWhileClosure(static_cast<While_t*>(value), out); break; 3441 case id<While_t>(): transformWhileClosure(static_cast<While_t*>(value), out); break;
3415 case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Closure); break; 3442 case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Closure); break;
3416 case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Closure); break; 3443 case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Closure); break;
3417 case id<UnaryValue_t>(): transform_unary_value(static_cast<UnaryValue_t*>(value), out); break; 3444 case id<UnaryValue_t>(): transformUnaryValue(static_cast<UnaryValue_t*>(value), out); break;
3418 case id<TblComprehension_t>(): transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Closure); break; 3445 case id<TblComprehension_t>(): transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Closure); break;
3419 case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(value), out); break; 3446 case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(value), out); break;
3420 case id<Comprehension_t>(): transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Closure); break; 3447 case id<Comprehension_t>(): transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Closure); break;
@@ -4050,6 +4077,9 @@ private:
4050 } else if (isPureNilCoalesed(exp)) { 4077 } else if (isPureNilCoalesed(exp)) {
4051 transformNilCoalesedExp(exp, out, ExpUsage::Return); 4078 transformNilCoalesedExp(exp, out, ExpUsage::Return);
4052 return; 4079 return;
4080 } else if (auto unary = unaryGeneratingAnonFunc(exp)) {
4081 transformUnaryExp(unary, out, ExpUsage::Return);
4082 return;
4053 } 4083 }
4054 } 4084 }
4055 if (auto singleValue = singleValueFrom(valueList)) { 4085 if (auto singleValue = singleValueFrom(valueList)) {
@@ -5363,7 +5393,7 @@ private:
5363 out.push_back('(' + join(temp, ", "sv) + ')'); 5393 out.push_back('(' + join(temp, ", "sv) + ')');
5364 } 5394 }
5365 5395
5366 void transform_unary_value(UnaryValue_t* unary_value, str_list& out) { 5396 void transformUnaryValue(UnaryValue_t* unary_value, str_list& out) {
5367 str_list temp; 5397 str_list temp;
5368 for (auto _op : unary_value->ops.objects()) { 5398 for (auto _op : unary_value->ops.objects()) {
5369 std::string op = _parser.toString(_op); 5399 std::string op = _parser.toString(_op);
@@ -5376,7 +5406,124 @@ private:
5376 out.push_back(join(temp)); 5406 out.push_back(join(temp));
5377 } 5407 }
5378 5408
5379 void transform_unary_exp(UnaryExp_t* unary_exp, str_list& out) { 5409 void transformUnaryExp(UnaryExp_t* unary_exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
5410 auto x = unary_exp;
5411 if (unary_exp->inExp) {
5412 std::string varName;
5413 if (unary_exp->ops.empty() && unary_exp->expos.size() == 1) {
5414 auto value = static_cast<Value_t*>(unary_exp->expos.back());
5415 varName = singleVariableFrom(value, false);
5416 if (!isLocal(varName)) {
5417 varName.clear();
5418 }
5419 }
5420 if (varName.empty()) {
5421 str_list temp;
5422 if (usage == ExpUsage::Closure) {
5423 pushFunctionScope();
5424 pushAnonVarArg();
5425 pushScope();
5426 } else if (usage == ExpUsage::Assignment) {
5427 temp.push_back(indent() + "do"s + nll(x));
5428 pushScope();
5429 }
5430 auto newUnaryExp = x->new_ptr<UnaryExp_t>();
5431 newUnaryExp->ops.dup(unary_exp->ops);
5432 newUnaryExp->expos.dup(unary_exp->expos);
5433 auto exp = newExp(newUnaryExp, x);
5434 auto newVar = getUnusedName("_val_"sv);
5435 auto assignExp = toAst<Exp_t>(newVar, x);
5436 auto assignment = assignmentFrom(assignExp, exp, x);
5437 transformAssignment(assignment, temp);
5438 if (auto range = unary_exp->inExp->item.as<InRange_t>()) {
5439 str_list tmp;
5440 transformExp(range->openValue, tmp, ExpUsage::Closure);
5441 transformExp(range->closeValue, tmp, ExpUsage::Closure);
5442 if (usage == ExpUsage::Assignment) {
5443 str_list tmpList;
5444 transformExp(static_cast<Exp_t*>(assignList->exprs.front()), tmpList, ExpUsage::Closure);
5445 _buf << indent() << tmpList.back() << " = "sv;
5446 } else {
5447 _buf << indent() << "return "sv;
5448 }
5449 if (unary_exp->inExp->not_) {
5450 _buf << "not ("sv;
5451 }
5452 _buf << tmp.front() << (range->open.is<InRangeOpen_t>() ? " < "sv : " <= "sv) << newVar << " and "sv << newVar << (range->close.is<InRangeOpen_t>() ? " < "sv : " <= "sv) << tmp.back();
5453 if (unary_exp->inExp->not_) {
5454 _buf << ")"sv;
5455 }
5456 _buf << nll(x);
5457 temp.push_back(clearBuf());
5458 } else {
5459 auto discrete = unary_exp->inExp->item.to<InDiscrete_t>();
5460 str_list tmp;
5461 for (auto exp : discrete->values.objects()) {
5462 transformExp(static_cast<Exp_t*>(exp), tmp, ExpUsage::Closure);
5463 }
5464 _buf << indent() << "return "sv;
5465 if (unary_exp->inExp->not_) {
5466 _buf << "not ("sv;
5467 }
5468 for (const auto& exp : tmp) {
5469 _buf << exp << " == "sv << newVar;
5470 if (exp != tmp.back()) {
5471 _buf << " or "sv;
5472 }
5473 }
5474 if (unary_exp->inExp->not_) {
5475 _buf << ")"sv;
5476 }
5477 _buf << nll(x);
5478 temp.push_back(clearBuf());
5479 }
5480 if (usage == ExpUsage::Closure) {
5481 temp.push_front(anonFuncStart() + nll(x));
5482 popScope();
5483 temp.push_back(indent() + anonFuncEnd());
5484 out.push_back(join(temp));
5485 popAnonVarArg();
5486 popFunctionScope();
5487 } else if (usage == ExpUsage::Assignment) {
5488 popScope();
5489 temp.push_back(indent() + "end"s + nll(x));
5490 out.push_back(join(temp));
5491 } else {
5492 out.push_back(join(temp));
5493 }
5494 } else {
5495 if (auto range = unary_exp->inExp->item.as<InRange_t>()) {
5496 str_list tmp;
5497 transformExp(range->openValue, tmp, ExpUsage::Closure);
5498 transformExp(range->closeValue, tmp, ExpUsage::Closure);
5499 if (unary_exp->inExp->not_) {
5500 _buf << "not "sv;
5501 }
5502 _buf << '(' << tmp.front() << (range->open.is<InRangeOpen_t>() ? " < "sv : " <= "sv) << varName << " and "sv << varName << (range->close.is<InRangeOpen_t>() ? " < "sv : " <= "sv) << tmp.back();
5503 _buf << ')';
5504 out.push_back(clearBuf());
5505 } else {
5506 auto discrete = unary_exp->inExp->item.to<InDiscrete_t>();
5507 str_list tmp;
5508 for (auto exp : discrete->values.objects()) {
5509 transformExp(static_cast<Exp_t*>(exp), tmp, ExpUsage::Closure);
5510 }
5511 if (unary_exp->inExp->not_) {
5512 _buf << "not "sv;
5513 }
5514 _buf << '(';
5515 for (const auto& exp : tmp) {
5516 _buf << exp << " == "sv << varName;
5517 if (exp != tmp.back()) {
5518 _buf << " or "sv;
5519 }
5520 }
5521 _buf << ')';
5522 out.push_back(clearBuf());
5523 }
5524 }
5525 return;
5526 }
5380 if (unary_exp->ops.empty() && unary_exp->expos.size() == 1) { 5527 if (unary_exp->ops.empty() && unary_exp->expos.size() == 1) {
5381 transformValue(static_cast<Value_t*>(unary_exp->expos.back()), out); 5528 transformValue(static_cast<Value_t*>(unary_exp->expos.back()), out);
5382 return; 5529 return;
@@ -7322,7 +7469,7 @@ private:
7322 out.push_back(join(temp)); 7469 out.push_back(join(temp));
7323 } 7470 }
7324 7471
7325 void transform_const_value(ConstValue_t* const_value, str_list& out) { 7472 void transformConstValue(ConstValue_t* const_value, str_list& out) {
7326 out.push_back(_parser.toString(const_value)); 7473 out.push_back(_parser.toString(const_value));
7327 } 7474 }
7328 7475
@@ -8216,7 +8363,20 @@ private:
8216 std::string tabCheckVar; 8363 std::string tabCheckVar;
8217 for (auto branch_ : branches) { 8364 for (auto branch_ : branches) {
8218 auto branch = static_cast<SwitchCase_t*>(branch_); 8365 auto branch = static_cast<SwitchCase_t*>(branch_);
8219 if (auto value = singleValueFrom(branch->valueList); 8366 if (auto inExp = branch->condition.as<In_t>()) {
8367 auto unary = branch->new_ptr<UnaryExp_t>();
8368 unary->expos.push_back(toAst<Value_t>(objVar, branch));
8369 unary->inExp.set(inExp);
8370 transformUnaryExp(unary, temp, ExpUsage::Closure);
8371 temp.back() = indent() + (firstBranch ? "if "s : "elseif "s) + temp.back() + " then"s + nll(branch);
8372 pushScope();
8373 transform_plain_body(branch->body, temp, usage, assignList);
8374 popScope();
8375 firstBranch = false;
8376 continue;
8377 }
8378 auto valueList = branch->condition.to<SwitchList_t>();
8379 if (auto value = singleValueFrom(valueList);
8220 value && (value->item.is<SimpleTable_t>() || value->getByPath<SimpleValue_t, TableLit_t>())) { 8380 value && (value->item.is<SimpleTable_t>() || value->getByPath<SimpleValue_t, TableLit_t>())) {
8221 if (!firstBranch) { 8381 if (!firstBranch) {
8222 temp.push_back(indent() + "else"s + nll(branch)); 8382 temp.push_back(indent() + "else"s + nll(branch));
@@ -8245,7 +8405,7 @@ private:
8245 } 8405 }
8246 temp.back().append(indent() + "if "s + tabCheckVar + " then"s + nll(branch)); 8406 temp.back().append(indent() + "if "s + tabCheckVar + " then"s + nll(branch));
8247 pushScope(); 8407 pushScope();
8248 auto assignment = assignmentFrom(static_cast<Exp_t*>(branch->valueList->exprs.front()), toAst<Exp_t>(objVar, branch), branch); 8408 auto assignment = assignmentFrom(static_cast<Exp_t*>(valueList->exprs.front()), toAst<Exp_t>(objVar, branch), branch);
8249 auto info = extractDestructureInfo(assignment, true, false); 8409 auto info = extractDestructureInfo(assignment, true, false);
8250 transformAssignment(assignment, temp, true); 8410 transformAssignment(assignment, temp, true);
8251 str_list conds; 8411 str_list conds;
@@ -8283,7 +8443,7 @@ private:
8283 temp.push_back(indent() + (firstBranch ? "if"s : "elseif"s)); 8443 temp.push_back(indent() + (firstBranch ? "if"s : "elseif"s));
8284 firstBranch = false; 8444 firstBranch = false;
8285 str_list tmp; 8445 str_list tmp;
8286 const auto& exprs = branch->valueList->exprs.objects(); 8446 const auto& exprs = valueList->exprs.objects();
8287 for (auto exp_ : exprs) { 8447 for (auto exp_ : exprs) {
8288 auto exp = static_cast<Exp_t*>(exp_); 8448 auto exp = static_cast<Exp_t*>(exp_);
8289 transformExp(exp, tmp, ExpUsage::Closure); 8449 transformExp(exp, tmp, ExpUsage::Closure);
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index dffdbe1..f383275 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -317,7 +317,7 @@ YueParser::YueParser() {
317 with_exp = ExpList >> -(space >> Assign); 317 with_exp = ExpList >> -(space >> Assign);
318 318
319 With = key("with") >> -ExistentialOp >> space >> disable_do_chain_arg_table_block_rule(with_exp) >> space >> body_with("do"); 319 With = key("with") >> -ExistentialOp >> space >> disable_do_chain_arg_table_block_rule(with_exp) >> space >> body_with("do");
320 SwitchCase = key("when") >> disable_chain_rule(disable_arg_table_block_rule(SwitchList)) >> space >> body_with("then"); 320 SwitchCase = key("when") >> (disable_chain_rule(disable_arg_table_block_rule(SwitchList)) | space >> In) >> space >> body_with("then");
321 switch_else = key("else") >> space >> body; 321 switch_else = key("else") >> space >> body;
322 322
323 switch_block = 323 switch_block =
@@ -454,12 +454,19 @@ YueParser::YueParser() {
454 expo_value = exponential_operator >> *space_break >> space >> Value; 454 expo_value = exponential_operator >> *space_break >> space >> Value;
455 expo_exp = Value >> *(space >> expo_value); 455 expo_exp = Value >> *(space >> expo_value);
456 456
457 InRangeOpen = true_();
458 InRangeClose = true_();
459 NotIn = true_();
460 InRange = ('(' >> InRangeOpen | '[' >> InRangeClose) >> space >> Exp >> space >> ',' >> space >> Exp >> space >> (')' >> InRangeOpen | ']' >> InRangeClose);
461 InDiscrete = '{' >> Seperator >> space >> Exp >> *(space >> ',' >> space >> Exp) >> space >> '}';
462 In = -(key("not") >> NotIn >> space) >> key("in") >> space >> (InRange | InDiscrete);
463
457 UnaryOperator = 464 UnaryOperator =
458 '-' >> not_(set(">=") | space_one) | 465 '-' >> not_(set(">=") | space_one) |
459 '#' | 466 '#' |
460 '~' >> not_('=' | space_one) | 467 '~' >> not_('=' | space_one) |
461 key("not"); 468 key("not");
462 UnaryExp = *(UnaryOperator >> space) >> expo_exp; 469 UnaryExp = *(UnaryOperator >> space) >> expo_exp >> -(space >> In);
463 470
464 pipe_operator = "|>"; 471 pipe_operator = "|>";
465 pipe_value = pipe_operator >> *space_break >> space >> UnaryExp; 472 pipe_value = pipe_operator >> *space_break >> space >> UnaryExp;
@@ -916,7 +923,7 @@ ParseInfo YueParser::parse(std::string_view codes, rule& r) {
916 error_list errors; 923 error_list errors;
917 try { 924 try {
918 State state; 925 State state;
919 res.node.set(pl::parse(*(res.codes), r, errors, &state)); 926 res.node.set(::yue::parse(*(res.codes), r, errors, &state));
920 if (state.exportCount > 0) { 927 if (state.exportCount > 0) {
921 res.moduleName = std::move(state.moduleName); 928 res.moduleName = std::move(state.moduleName);
922 res.exportDefault = state.exportDefault; 929 res.exportDefault = state.exportDefault;
@@ -952,14 +959,6 @@ std::string YueParser::toString(input::iterator begin, input::iterator end) {
952 return _converter.to_bytes(std::wstring(begin, end)); 959 return _converter.to_bytes(std::wstring(begin, end));
953} 960}
954 961
955input YueParser::encode(std::string_view codes) {
956 return _converter.from_bytes(&codes.front(), &codes.back() + 1);
957}
958
959std::string YueParser::decode(const input& codes) {
960 return _converter.to_bytes(codes);
961}
962
963namespace Utils { 962namespace Utils {
964void replace(std::string& str, std::string_view from, std::string_view to) { 963void replace(std::string& str, std::string_view from, std::string_view to) {
965 size_t start_pos = 0; 964 size_t start_pos = 0;
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index 3be50a7..d4f66eb 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -25,6 +25,7 @@ namespace yue {
25using namespace std::string_view_literals; 25using namespace std::string_view_literals;
26using namespace std::string_literals; 26using namespace std::string_literals;
27using namespace parserlib; 27using namespace parserlib;
28using namespace parserlib::yue;
28 29
29struct ParseInfo { 30struct ParseInfo {
30 struct Error { 31 struct Error {
@@ -86,9 +87,6 @@ public:
86 std::string toString(ast_node* node); 87 std::string toString(ast_node* node);
87 std::string toString(input::iterator begin, input::iterator end); 88 std::string toString(input::iterator begin, input::iterator end);
88 89
89 input encode(std::string_view input);
90 std::string decode(const input& input);
91
92protected: 90protected:
93 ParseInfo parse(std::string_view codes, rule& r); 91 ParseInfo parse(std::string_view codes, rule& r);
94 92
@@ -378,6 +376,12 @@ private:
378 AST_RULE(ConstValue) 376 AST_RULE(ConstValue)
379 AST_RULE(UnaryValue) 377 AST_RULE(UnaryValue)
380 AST_RULE(UnaryExp) 378 AST_RULE(UnaryExp)
379 AST_RULE(InRangeOpen)
380 AST_RULE(InRangeClose)
381 AST_RULE(NotIn)
382 AST_RULE(InRange)
383 AST_RULE(InDiscrete)
384 AST_RULE(In)
381 AST_RULE(ExpListAssign) 385 AST_RULE(ExpListAssign)
382 AST_RULE(IfLine) 386 AST_RULE(IfLine)
383 AST_RULE(WhileLine) 387 AST_RULE(WhileLine)