aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/inputs/in_expression.yue39
-rw-r--r--spec/outputs/in_expression.lua49
-rw-r--r--src/yuescript/yue_compiler.cpp62
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
38do
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
38nil 77nil
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)
164end 164end
165do
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
213end
165return nil 214return 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
78const std::string_view version = "0.21.6"sv; 78const std::string_view version = "0.21.7"sv;
79const std::string_view extension = "yue"sv; 79const std::string_view extension = "yue"sv;
80 80
81class CompileError : public std::logic_error { 81class 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;