diff options
-rw-r--r-- | spec/inputs/in_expression.yue | 39 | ||||
-rw-r--r-- | spec/outputs/in_expression.lua | 49 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 62 |
3 files changed, 148 insertions, 2 deletions
diff --git a/spec/inputs/in_expression.yue b/spec/inputs/in_expression.yue index 6faff4e..7ee0816 100644 --- a/spec/inputs/in_expression.yue +++ b/spec/inputs/in_expression.yue | |||
@@ -35,5 +35,44 @@ do | |||
35 | check -> return x in tb | 35 | check -> return x in tb |
36 | check -> x not in tb | 36 | check -> x not in tb |
37 | 37 | ||
38 | do | ||
39 | f1 = -> | ||
40 | a = 2 | ||
41 | a in [ | ||
42 | 1 | ||
43 | 2 | ||
44 | 3 | ||
45 | 4 | ||
46 | ] | ||
47 | f2 = -> | ||
48 | a not in [ | ||
49 | 1 | ||
50 | 2 | ||
51 | 3 | ||
52 | 4 | ||
53 | ] | ||
54 | f3 = -> | ||
55 | a = 2 | ||
56 | a in { b, c, d | ||
57 | e, f | ||
58 | g | ||
59 | } | ||
60 | f4 = -> | ||
61 | a = 2 | ||
62 | b = a in [ 1, 2 | ||
63 | 3, 4 | ||
64 | ] | ||
65 | f5 = -> | ||
66 | a = 2 | ||
67 | return a in [ 1, 2 | ||
68 | 3, 4 | ||
69 | ] | ||
70 | f6 = -> | ||
71 | b = a not in { | ||
72 | 1 | ||
73 | 2 | ||
74 | x: 3 | ||
75 | } | ||
76 | |||
38 | nil | 77 | nil |
39 | 78 | ||
diff --git a/spec/outputs/in_expression.lua b/spec/outputs/in_expression.lua index 04c08e7..afcc030 100644 --- a/spec/outputs/in_expression.lua +++ b/spec/outputs/in_expression.lua | |||
@@ -162,4 +162,53 @@ do | |||
162 | return true | 162 | return true |
163 | end) | 163 | end) |
164 | end | 164 | end |
165 | do | ||
166 | local f1 | ||
167 | f1 = function() | ||
168 | local a = 2 | ||
169 | return (1 == a or 2 == a or 3 == a or 4 == a) | ||
170 | end | ||
171 | local f2 | ||
172 | f2 = function() | ||
173 | local _val_0 = a | ||
174 | return not (1 == _val_0 or 2 == _val_0 or 3 == _val_0 or 4 == _val_0) | ||
175 | end | ||
176 | local f3 | ||
177 | f3 = function() | ||
178 | local a = 2 | ||
179 | return (b == a or c == a or d == a or e == a or f == a or g == a) | ||
180 | end | ||
181 | local f4 | ||
182 | f4 = function() | ||
183 | local a = 2 | ||
184 | local b | ||
185 | b = (1 == a or 2 == a or 3 == a or 4 == a) | ||
186 | end | ||
187 | local f5 | ||
188 | f5 = function() | ||
189 | local a = 2 | ||
190 | return (1 == a or 2 == a or 3 == a or 4 == a) | ||
191 | end | ||
192 | local f6 | ||
193 | f6 = function() | ||
194 | local b | ||
195 | do | ||
196 | local _check_0 = { | ||
197 | 1, | ||
198 | 2, | ||
199 | x = 3 | ||
200 | } | ||
201 | local _val_0 = a | ||
202 | local _find_0 = false | ||
203 | for _index_0 = 1, #_check_0 do | ||
204 | local _item_0 = _check_0[_index_0] | ||
205 | if _item_0 == _val_0 then | ||
206 | _find_0 = true | ||
207 | break | ||
208 | end | ||
209 | end | ||
210 | b = not _find_0 | ||
211 | end | ||
212 | end | ||
213 | end | ||
165 | return nil | 214 | return nil |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index ba74d91..3892d72 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
75 | "close"s // Lua 5.4 | 75 | "close"s // Lua 5.4 |
76 | }; | 76 | }; |
77 | 77 | ||
78 | const std::string_view version = "0.21.6"sv; | 78 | const std::string_view version = "0.21.7"sv; |
79 | const std::string_view extension = "yue"sv; | 79 | const std::string_view extension = "yue"sv; |
80 | 80 | ||
81 | class CompileError : public std::logic_error { | 81 | class CompileError : public std::logic_error { |
@@ -5946,7 +5946,52 @@ private: | |||
5946 | varName.clear(); | 5946 | varName.clear(); |
5947 | } | 5947 | } |
5948 | } | 5948 | } |
5949 | ast_ptr<false, InDiscrete_t> discrete; | ||
5949 | if (auto inExp = unary_exp->inExp->item.as<Exp_t>()) { | 5950 | if (auto inExp = unary_exp->inExp->item.as<Exp_t>()) { |
5951 | BLOCK_START | ||
5952 | auto value = singleValueFrom(inExp); | ||
5953 | BREAK_IF(!value); | ||
5954 | auto sval = value->item.as<SimpleValue_t>(); | ||
5955 | BREAK_IF(!sval); | ||
5956 | if (auto table = sval->value.as<TableLit_t>()) { | ||
5957 | discrete = inExp->new_ptr<InDiscrete_t>(); | ||
5958 | for (ast_node* val : table->values.objects()) { | ||
5959 | if (auto def = ast_cast<NormalDef_t>(val)) { | ||
5960 | if (def->defVal) { | ||
5961 | discrete = nullptr; | ||
5962 | break; | ||
5963 | } else { | ||
5964 | discrete->values.push_back(def->item); | ||
5965 | } | ||
5966 | } else if (ast_is<Exp_t>(val)) { | ||
5967 | discrete->values.push_back(val); | ||
5968 | } else { | ||
5969 | discrete = nullptr; | ||
5970 | break; | ||
5971 | } | ||
5972 | } | ||
5973 | } else if (auto comp = sval->value.as<Comprehension_t>()) { | ||
5974 | if (comp->items.size() != 2 || !ast_is<CompInner_t>(comp->items.back())) { | ||
5975 | discrete = inExp->new_ptr<InDiscrete_t>(); | ||
5976 | for (ast_node* val : comp->items.objects()) { | ||
5977 | if (auto def = ast_cast<NormalDef_t>(val)) { | ||
5978 | if (def->defVal) { | ||
5979 | discrete = nullptr; | ||
5980 | break; | ||
5981 | } else { | ||
5982 | discrete->values.push_back(def->item); | ||
5983 | } | ||
5984 | } else { | ||
5985 | discrete = nullptr; | ||
5986 | break; | ||
5987 | } | ||
5988 | } | ||
5989 | } | ||
5990 | } | ||
5991 | BLOCK_END | ||
5992 | |||
5993 | BLOCK_START | ||
5994 | BREAK_IF(discrete); | ||
5950 | str_list temp; | 5995 | str_list temp; |
5951 | auto checkVar = singleVariableFrom(inExp, false); | 5996 | auto checkVar = singleVariableFrom(inExp, false); |
5952 | if (usage == ExpUsage::Assignment) { | 5997 | if (usage == ExpUsage::Assignment) { |
@@ -6069,8 +6114,11 @@ private: | |||
6069 | out.push_back(join(temp)); | 6114 | out.push_back(join(temp)); |
6070 | return; | 6115 | return; |
6071 | } | 6116 | } |
6117 | BLOCK_END | ||
6118 | } | ||
6119 | if (!discrete) { | ||
6120 | discrete = unary_exp->inExp->item.to<InDiscrete_t>(); | ||
6072 | } | 6121 | } |
6073 | auto discrete = unary_exp->inExp->item.to<InDiscrete_t>(); | ||
6074 | if (usage == ExpUsage::Closure && discrete->values.size() == 1) { | 6122 | if (usage == ExpUsage::Closure && discrete->values.size() == 1) { |
6075 | str_list tmp; | 6123 | str_list tmp; |
6076 | transformExp(static_cast<Exp_t*>(discrete->values.front()), tmp, ExpUsage::Closure); | 6124 | transformExp(static_cast<Exp_t*>(discrete->values.front()), tmp, ExpUsage::Closure); |
@@ -6151,6 +6199,13 @@ private: | |||
6151 | for (auto exp : discrete->values.objects()) { | 6199 | for (auto exp : discrete->values.objects()) { |
6152 | transformExp(static_cast<Exp_t*>(exp), tmp, ExpUsage::Closure); | 6200 | transformExp(static_cast<Exp_t*>(exp), tmp, ExpUsage::Closure); |
6153 | } | 6201 | } |
6202 | if (usage == ExpUsage::Assignment) { | ||
6203 | str_list tmpList; | ||
6204 | transformExp(static_cast<Exp_t*>(assignList->exprs.front()), tmpList, ExpUsage::Closure); | ||
6205 | _buf << indent() << tmpList.back() << " = "sv; | ||
6206 | } else if (usage == ExpUsage::Return) { | ||
6207 | _buf << indent() << "return "sv; | ||
6208 | } | ||
6154 | if (unary_exp->inExp->not_) { | 6209 | if (unary_exp->inExp->not_) { |
6155 | _buf << "not "sv; | 6210 | _buf << "not "sv; |
6156 | } | 6211 | } |
@@ -6162,6 +6217,9 @@ private: | |||
6162 | } | 6217 | } |
6163 | } | 6218 | } |
6164 | _buf << ')'; | 6219 | _buf << ')'; |
6220 | if (usage == ExpUsage::Assignment || usage == ExpUsage::Return) { | ||
6221 | _buf << nll(discrete); | ||
6222 | } | ||
6165 | out.push_back(clearBuf()); | 6223 | out.push_back(clearBuf()); |
6166 | } | 6224 | } |
6167 | return; | 6225 | return; |