diff options
Diffstat (limited to '')
| -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; |
