aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdoc/package.json4
-rw-r--r--spec/inputs/in_expression.yue9
-rw-r--r--spec/outputs/in_expression.lua74
-rw-r--r--src/yuescript/yue_compiler.cpp66
4 files changed, 115 insertions, 38 deletions
diff --git a/doc/package.json b/doc/package.json
index 0784500..f9e5ebf 100755
--- a/doc/package.json
+++ b/doc/package.json
@@ -9,8 +9,8 @@
9 }, 9 },
10 "repository": "https://github.com/pigpigyyy/Yuescript/doc", 10 "repository": "https://github.com/pigpigyyy/Yuescript/doc",
11 "scripts": { 11 "scripts": {
12 "dev": "vuepress dev docs", 12 "dev": "export NODE_OPTIONS=--openssl-legacy-provider && vuepress dev docs",
13 "build": "vuepress build docs" 13 "build": "export NODE_OPTIONS=--openssl-legacy-provider && vuepress build docs"
14 }, 14 },
15 "license": "MIT", 15 "license": "MIT",
16 "devDependencies": { 16 "devDependencies": {
diff --git a/spec/inputs/in_expression.yue b/spec/inputs/in_expression.yue
index 4080016..6e923e1 100644
--- a/spec/inputs/in_expression.yue
+++ b/spec/inputs/in_expression.yue
@@ -39,7 +39,14 @@ do
39 not_exist = item not in list 39 not_exist = item not in list
40 check item in list 40 check item in list
41 check item in {1, 2, 3} 41 check item in {1, 2, 3}
42 check item in {[1]: 1, [2]: 2, [3]: 3} 42 check item(...) in {[1]: 1, [2]: 2, [3]: 3}
43
44do
45 check -> x in tb
46 check -> x not in tb
47 local x, tb
48 check -> return x in tb
49 check -> x not in tb
43 50
44nil 51nil
45 52
diff --git a/spec/outputs/in_expression.lua b/spec/outputs/in_expression.lua
index ccc5fd0..ddba69a 100644
--- a/spec/outputs/in_expression.lua
+++ b/spec/outputs/in_expression.lua
@@ -66,15 +66,19 @@ do
66end 66end
67do 67do
68 local item = get() 68 local item = get()
69 local exist = (function() 69 local exist
70 do
70 local _check_0 = list 71 local _check_0 = list
72 local _find_0 = false
71 for _index_0 = 1, #_check_0 do 73 for _index_0 = 1, #_check_0 do
72 if _check_0[_index_0] == item then 74 local _item_0 = _check_0[_index_0]
73 return true 75 if _item_0 == item then
76 _find_0 = true
77 break
74 end 78 end
75 end 79 end
76 return false 80 exist = _find_0
77 end)() 81 end
78 check((function() 82 check((function()
79 local _check_0 = list 83 local _check_0 = list
80 for _index_0 = 1, #_check_0 do 84 for _index_0 = 1, #_check_0 do
@@ -92,14 +96,18 @@ do
92 2, 96 2,
93 3 97 3
94 } 98 }
95 local not_exist = not (#list > 0 and (function() 99 local not_exist
100 do
101 local _find_0 = false
96 for _index_0 = 1, #list do 102 for _index_0 = 1, #list do
97 if list[_index_0] == item then 103 local _item_0 = list[_index_0]
98 return true 104 if _item_0 == item then
105 _find_0 = true
106 break
99 end 107 end
100 end 108 end
101 return false 109 not_exist = not _find_0
102 end)()) 110 end
103 check((#list > 0 and (function() 111 check((#list > 0 and (function()
104 for _index_0 = 1, #list do 112 for _index_0 = 1, #list do
105 if list[_index_0] == item then 113 if list[_index_0] == item then
@@ -109,18 +117,58 @@ do
109 return false 117 return false
110 end)())) 118 end)()))
111 check((1 == item or 2 == item or 3 == item)) 119 check((1 == item or 2 == item or 3 == item))
112 check((function() 120 check((function(...)
113 local _check_0 = { 121 local _check_0 = {
114 [1] = 1, 122 [1] = 1,
115 [2] = 2, 123 [2] = 2,
116 [3] = 3 124 [3] = 3
117 } 125 }
126 local _val_0 = item(...)
118 for _index_0 = 1, #_check_0 do 127 for _index_0 = 1, #_check_0 do
119 if _check_0[_index_0] == item then 128 if _check_0[_index_0] == _val_0 then
120 return true 129 return true
121 end 130 end
122 end 131 end
123 return false 132 return false
124 end)()) 133 end)(...))
134end
135do
136 check(function()
137 local _check_0 = tb
138 local _val_0 = x
139 for _index_0 = 1, #_check_0 do
140 if _check_0[_index_0] == _val_0 then
141 return true
142 end
143 end
144 return false
145 end)
146 check(function()
147 local _check_0 = tb
148 local _val_0 = x
149 for _index_0 = 1, #_check_0 do
150 if _check_0[_index_0] == _val_0 then
151 return false
152 end
153 end
154 return true
155 end)
156 local x, tb
157 check(function()
158 for _index_0 = 1, #tb do
159 if tb[_index_0] == x then
160 return true
161 end
162 end
163 return false
164 end)
165 check(function()
166 for _index_0 = 1, #tb do
167 if tb[_index_0] == x then
168 return false
169 end
170 end
171 return true
172 end)
125end 173end
126return nil 174return nil
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index bb715d2..09da047 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.17.7"sv; 75const std::string_view version = "0.17.8"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 {
@@ -1161,6 +1161,9 @@ private:
1161 auto unary = static_cast<UnaryExp_t*>(exp->pipeExprs.back()); 1161 auto unary = static_cast<UnaryExp_t*>(exp->pipeExprs.back());
1162 BREAK_IF(unary->expos.size() != 1); 1162 BREAK_IF(unary->expos.size() != 1);
1163 BREAK_IF(!unary->inExp); 1163 BREAK_IF(!unary->inExp);
1164 if (unary->inExp->item.is<Exp_t>()) {
1165 return unary;
1166 }
1164 auto value = static_cast<Value_t*>(unary->expos.back()); 1167 auto value = static_cast<Value_t*>(unary->expos.back());
1165 auto varName = singleVariableFrom(value, false); 1168 auto varName = singleVariableFrom(value, false);
1166 if (varName.empty() || !isLocal(varName)) { 1169 if (varName.empty() || !isLocal(varName)) {
@@ -5416,7 +5419,11 @@ private:
5416 _buf << "\tif "sv << itemVar << "=="sv << varName << '\n'; 5419 _buf << "\tif "sv << itemVar << "=="sv << varName << '\n';
5417 _buf << "\t\t"sv << findVar << "=true\n"sv; 5420 _buf << "\t\t"sv << findVar << "=true\n"sv;
5418 _buf << "\t\tbreak\n"sv; 5421 _buf << "\t\tbreak\n"sv;
5419 _buf << findVar; 5422 if (unary_exp->inExp->not_) {
5423 _buf << "not "sv << findVar;
5424 } else {
5425 _buf << findVar;
5426 }
5420 auto blockStr = clearBuf(); 5427 auto blockStr = clearBuf();
5421 auto checkBlock = toAst<Block_t>(blockStr, inExp); 5428 auto checkBlock = toAst<Block_t>(blockStr, inExp);
5422 block->statements.dup(checkBlock->statements); 5429 block->statements.dup(checkBlock->statements);
@@ -5437,30 +5444,44 @@ private:
5437 out.push_back(join(temp)); 5444 out.push_back(join(temp));
5438 return; 5445 return;
5439 } else { 5446 } else {
5440 pushFunctionScope(); 5447 auto arrayCheck = [&](bool exist) {
5441 pushAnonVarArg();
5442 pushScope();
5443 auto arrayCheck = [&]() {
5444 auto indexVar = getUnusedName("_index_"); 5448 auto indexVar = getUnusedName("_index_");
5445 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << checkVar << " do"sv << nll(x); 5449 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << checkVar << " do"sv << nll(x);
5446 incIndentOffset(); 5450 incIndentOffset();
5447 _buf << indent() << "if "sv << checkVar << '[' << indexVar << "] == "sv << varName << " then"sv << nll(x); 5451 _buf << indent() << "if "sv << checkVar << '[' << indexVar << "] == "sv << varName << " then"sv << nll(x);
5448 incIndentOffset(); 5452 incIndentOffset();
5449 _buf << indent() << "return true"sv << nll(x); 5453 _buf << indent() << "return "sv << (exist ? "true"sv : "false"sv) << nll(x);
5450 decIndentOffset(); 5454 decIndentOffset();
5451 _buf << indent() << "end"sv << nll(x); 5455 _buf << indent() << "end"sv << nll(x);
5452 decIndentOffset(); 5456 decIndentOffset();
5453 _buf << indent() << "end"sv << nll(x); 5457 _buf << indent() << "end"sv << nll(x);
5454 _buf << indent() << "return false"sv << nll(x); 5458 _buf << indent() << "return "sv << (exist ? "false"sv : "true"sv) << nll(x);
5455 temp.push_back(clearBuf()); 5459 temp.push_back(clearBuf());
5456 }; 5460 };
5457 bool useShortCheck = !varName.empty() && !checkVar.empty() && isLocal(checkVar); 5461 bool useShortCheck = (usage == ExpUsage::Closure) && !varName.empty() && !checkVar.empty() && isLocal(checkVar);
5458 if (useShortCheck) { 5462 if (useShortCheck) {
5459 arrayCheck(); 5463 if (usage == ExpUsage::Return) {
5460 temp.push_front("(#"s + checkVar + " > 0 and "s + anonFuncStart() + nll(x)); 5464 arrayCheck(!unary_exp->inExp->not_);
5461 popScope(); 5465 } else {
5462 temp.push_back(indent() + anonFuncEnd() + ')'); 5466 pushFunctionScope();
5467 pushAnonVarArg();
5468 pushScope();
5469 arrayCheck(true);
5470 temp.push_front("(#"s + checkVar + " > 0 and "s + anonFuncStart() + nll(x));
5471 popScope();
5472 temp.push_back(indent() + anonFuncEnd() + ')');
5473 if (unary_exp->inExp->not_) {
5474 temp.front().insert(0, "not "s);
5475 }
5476 popAnonVarArg();
5477 popFunctionScope();
5478 }
5463 } else { 5479 } else {
5480 if (usage == ExpUsage::Closure) {
5481 pushFunctionScope();
5482 pushAnonVarArg();
5483 pushScope();
5484 }
5464 if (checkVar.empty() || !isLocal(checkVar)) { 5485 if (checkVar.empty() || !isLocal(checkVar)) {
5465 checkVar = getUnusedName("_check_"sv); 5486 checkVar = getUnusedName("_check_"sv);
5466 auto assignment = assignmentFrom(toAst<Exp_t>(checkVar, inExp), inExp, inExp); 5487 auto assignment = assignmentFrom(toAst<Exp_t>(checkVar, inExp), inExp, inExp);
@@ -5476,15 +5497,16 @@ private:
5476 auto assignment = assignmentFrom(assignExp, exp, x); 5497 auto assignment = assignmentFrom(assignExp, exp, x);
5477 transformAssignment(assignment, temp); 5498 transformAssignment(assignment, temp);
5478 } 5499 }
5479 arrayCheck(); 5500 if (usage == ExpUsage::Return) {
5480 temp.push_front(anonFuncStart() + nll(x)); 5501 arrayCheck(!unary_exp->inExp->not_);
5481 popScope(); 5502 } else {
5482 temp.push_back(indent() + anonFuncEnd()); 5503 arrayCheck(!unary_exp->inExp->not_);
5483 } 5504 temp.push_front(anonFuncStart() + nll(x));
5484 popAnonVarArg(); 5505 popScope();
5485 popFunctionScope(); 5506 temp.push_back(indent() + anonFuncEnd());
5486 if (unary_exp->inExp->not_) { 5507 popAnonVarArg();
5487 temp.front().insert(0, "not "s); 5508 popFunctionScope();
5509 }
5488 } 5510 }
5489 out.push_back(join(temp)); 5511 out.push_back(join(temp));
5490 return; 5512 return;