summaryrefslogtreecommitdiff
path: root/src/yuescript/yue_compiler.cpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2021-08-15 01:35:20 +0800
committerLi Jin <dragon-fly@qq.com>2021-08-15 01:35:20 +0800
commit7295e9efe092fca4ab6eebf6408af93d5f56dd80 (patch)
treea84ae20259c370aff3d65195152758d32eee52d7 /src/yuescript/yue_compiler.cpp
parent2511572a2c9f9cc8c79fa42163717ed840767545 (diff)
downloadyuescript-7295e9efe092fca4ab6eebf6408af93d5f56dd80.tar.gz
yuescript-7295e9efe092fca4ab6eebf6408af93d5f56dd80.tar.bz2
yuescript-7295e9efe092fca4ab6eebf6408af93d5f56dd80.zip
fix vararg issues. add new spec.
Diffstat (limited to '')
-rw-r--r--src/yuescript/yue_compiler.cpp134
1 files changed, 100 insertions, 34 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index f1b6253..ca846a5 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -56,7 +56,7 @@ using namespace parserlib;
56 56
57typedef std::list<std::string> str_list; 57typedef std::list<std::string> str_list;
58 58
59const std::string_view version = "0.7.16"sv; 59const std::string_view version = "0.7.17"sv;
60const std::string_view extension = "yue"sv; 60const std::string_view extension = "yue"sv;
61 61
62class YueCompilerImpl { 62class YueCompilerImpl {
@@ -109,7 +109,7 @@ public:
109 str_list out; 109 str_list out;
110 pushScope(); 110 pushScope();
111 _enableReturn.push(_info.moduleName.empty()); 111 _enableReturn.push(_info.moduleName.empty());
112 _varArgs.push(true); 112 _varArgs.push({true, false});
113 transformBlock(_info.node.to<File_t>()->block, out, 113 transformBlock(_info.node.to<File_t>()->block, out,
114 config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common, 114 config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common,
115 nullptr, true); 115 nullptr, true);
@@ -192,7 +192,12 @@ private:
192 YueParser _parser; 192 YueParser _parser;
193 ParseInfo _info; 193 ParseInfo _info;
194 int _indentOffset = 0; 194 int _indentOffset = 0;
195 std::stack<bool> _varArgs; 195 struct VarArgState
196 {
197 bool hasVar;
198 bool usedVar;
199 };
200 std::stack<VarArgState> _varArgs;
196 std::stack<bool> _enableReturn; 201 std::stack<bool> _enableReturn;
197 std::stack<std::string> _withVars; 202 std::stack<std::string> _withVars;
198 std::stack<std::string> _continueVars; 203 std::stack<std::string> _continueVars;
@@ -860,6 +865,26 @@ private:
860 return false; 865 return false;
861 } 866 }
862 867
868 void pushAnonVarArg() {
869 if (!_varArgs.empty() && _varArgs.top().hasVar) {
870 _varArgs.push({true, false});
871 } else {
872 _varArgs.push({false, false});
873 }
874 }
875
876 void popAnonVarArg() {
877 _varArgs.pop();
878 }
879
880 std::string anonFuncStart() const {
881 return !_varArgs.empty() && _varArgs.top().hasVar && _varArgs.top().usedVar ? "(function(...)"s : "(function()"s;
882 }
883
884 std::string anonFuncEnd() const {
885 return !_varArgs.empty() && _varArgs.top().usedVar ? "end)(...)"s : "end)()"s;
886 }
887
863 std::string globalVar(std::string_view var, ast_node* x) { 888 std::string globalVar(std::string_view var, ast_node* x) {
864 std::string str(var); 889 std::string str(var);
865 if (_config.lintGlobalVariable) { 890 if (_config.lintGlobalVariable) {
@@ -1854,8 +1879,10 @@ private:
1854 return; 1879 return;
1855 } 1880 }
1856 str_list temp; 1881 str_list temp;
1882 std::string* funcStart = nullptr;
1857 if (usage == ExpUsage::Closure) { 1883 if (usage == ExpUsage::Closure) {
1858 temp.push_back("(function()"s + nll(nodes.front())); 1884 pushAnonVarArg();
1885 funcStart = &temp.emplace_back();
1859 pushScope(); 1886 pushScope();
1860 _enableReturn.push(true); 1887 _enableReturn.push(true);
1861 } 1888 }
@@ -1969,7 +1996,9 @@ private:
1969 if (usage == ExpUsage::Closure) { 1996 if (usage == ExpUsage::Closure) {
1970 _enableReturn.pop(); 1997 _enableReturn.pop();
1971 popScope(); 1998 popScope();
1972 temp.push_back(indent() + "end)()"s); 1999 *funcStart = anonFuncStart() + nll(nodes.front());
2000 temp.push_back(indent() + anonFuncEnd());
2001 popAnonVarArg();
1973 } 2002 }
1974 out.push_back(join(temp)); 2003 out.push_back(join(temp));
1975 } 2004 }
@@ -2131,9 +2160,10 @@ private:
2131 break; 2160 break;
2132 } 2161 }
2133 case id<VarArg_t>(): 2162 case id<VarArg_t>():
2134 if (_varArgs.empty() || !_varArgs.top()) { 2163 if (_varArgs.empty() || !_varArgs.top().hasVar) {
2135 throw std::logic_error(_info.errorMessage("cannot use '...' outside a vararg function near '...'"sv, item)); 2164 throw std::logic_error(_info.errorMessage("cannot use '...' outside a vararg function near '...'"sv, item));
2136 } 2165 }
2166 _varArgs.top().usedVar = true;
2137 out.push_back("..."s); 2167 out.push_back("..."s);
2138 break; 2168 break;
2139 case id<Parens_t>(): transformParens(static_cast<Parens_t*>(item), out); break; 2169 case id<Parens_t>(): transformParens(static_cast<Parens_t*>(item), out); break;
@@ -2171,7 +2201,7 @@ private:
2171 2201
2172 void transformFunLit(FunLit_t* funLit, str_list& out) { 2202 void transformFunLit(FunLit_t* funLit, str_list& out) {
2173 _enableReturn.push(true); 2203 _enableReturn.push(true);
2174 _varArgs.push(false); 2204 _varArgs.push({false, false});
2175 str_list temp; 2205 str_list temp;
2176 bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; 2206 bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv;
2177 pushScope(); 2207 pushScope();
@@ -2877,7 +2907,7 @@ private:
2877 arg.name = "..."sv; 2907 arg.name = "..."sv;
2878 if (varNames.empty()) varNames = arg.name; 2908 if (varNames.empty()) varNames = arg.name;
2879 else varNames.append(", "s + arg.name); 2909 else varNames.append(", "s + arg.name);
2880 _varArgs.top() = true; 2910 _varArgs.top().hasVar = true;
2881 } 2911 }
2882 if (assignSelf) { 2912 if (assignSelf) {
2883 for (const auto& item : argItems) { 2913 for (const auto& item : argItems) {
@@ -2996,8 +3026,10 @@ private:
2996 if (opIt != chainList.end()) { 3026 if (opIt != chainList.end()) {
2997 auto x = chainList.front(); 3027 auto x = chainList.front();
2998 str_list temp; 3028 str_list temp;
3029 std::string* funcStart = nullptr;
2999 if (usage == ExpUsage::Closure) { 3030 if (usage == ExpUsage::Closure) {
3000 temp.push_back("(function()"s + nll(x)); 3031 pushAnonVarArg();
3032 funcStart = &temp.emplace_back();
3001 pushScope(); 3033 pushScope();
3002 _enableReturn.push(true); 3034 _enableReturn.push(true);
3003 } 3035 }
@@ -3132,7 +3164,9 @@ private:
3132 temp.push_back(indent() + "return nil"s + nlr(x)); 3164 temp.push_back(indent() + "return nil"s + nlr(x));
3133 _enableReturn.pop(); 3165 _enableReturn.pop();
3134 popScope(); 3166 popScope();
3135 temp.push_back(indent() + "end)()"s); 3167 *funcStart = anonFuncStart() + nll(x);
3168 temp.push_back(indent() + anonFuncEnd());
3169 popAnonVarArg();
3136 break; 3170 break;
3137 default: 3171 default:
3138 break; 3172 break;
@@ -3147,13 +3181,15 @@ private:
3147 if (ast_is<ColonChainItem_t>(chainList.back())) { 3181 if (ast_is<ColonChainItem_t>(chainList.back())) {
3148 auto x = chainList.front(); 3182 auto x = chainList.front();
3149 str_list temp; 3183 str_list temp;
3184 std::string* funcStart = nullptr;
3150 switch (usage) { 3185 switch (usage) {
3151 case ExpUsage::Assignment: 3186 case ExpUsage::Assignment:
3152 temp.push_back(indent() + "do"s + nll(x)); 3187 temp.push_back(indent() + "do"s + nll(x));
3153 pushScope(); 3188 pushScope();
3154 break; 3189 break;
3155 case ExpUsage::Closure: 3190 case ExpUsage::Closure:
3156 temp.push_back("(function()"s + nll(x)); 3191 pushAnonVarArg();
3192 funcStart = &temp.emplace_back();
3157 pushScope(); 3193 pushScope();
3158 _enableReturn.push(true); 3194 _enableReturn.push(true);
3159 break; 3195 break;
@@ -3229,7 +3265,9 @@ private:
3229 case ExpUsage::Closure: 3265 case ExpUsage::Closure:
3230 _enableReturn.pop(); 3266 _enableReturn.pop();
3231 popScope(); 3267 popScope();
3232 temp.push_back(indent() + "end)()"s); 3268 *funcStart = anonFuncStart() + nll(x);
3269 temp.push_back(indent() + anonFuncEnd());
3270 popAnonVarArg();
3233 break; 3271 break;
3234 default: 3272 default:
3235 break; 3273 break;
@@ -3960,6 +3998,7 @@ private:
3960 case ExpUsage::Closure: 3998 case ExpUsage::Closure:
3961 _enableReturn.push(true); 3999 _enableReturn.push(true);
3962 pushScope(); 4000 pushScope();
4001 pushAnonVarArg();
3963 break; 4002 break;
3964 case ExpUsage::Assignment: 4003 case ExpUsage::Assignment:
3965 pushScope(); 4004 pushScope();
@@ -4019,8 +4058,9 @@ private:
4019 out.push_back(clearBuf()); 4058 out.push_back(clearBuf());
4020 out.back().append(indent() + "return "s + accumVar + nlr(comp)); 4059 out.back().append(indent() + "return "s + accumVar + nlr(comp));
4021 popScope(); 4060 popScope();
4022 out.back().insert(0, "(function()"s + nll(comp)); 4061 out.back().insert(0, anonFuncStart() + nll(comp));
4023 out.back().append(indent() + "end)()"s); 4062 out.back().append(indent() + anonFuncEnd());
4063 popAnonVarArg();
4024 break; 4064 break;
4025 } 4065 }
4026 case ExpUsage::Assignment: { 4066 case ExpUsage::Assignment: {
@@ -4345,14 +4385,17 @@ private:
4345 4385
4346 void transformForClosure(For_t* forNode, str_list& out) { 4386 void transformForClosure(For_t* forNode, str_list& out) {
4347 str_list temp; 4387 str_list temp;
4348 _buf << "(function()"sv << nll(forNode); 4388 pushAnonVarArg();
4389 std::string& funcStart = temp.emplace_back();
4349 pushScope(); 4390 pushScope();
4350 _enableReturn.push(true); 4391 _enableReturn.push(true);
4351 auto accum = transformForInner(forNode, temp); 4392 auto accum = transformForInner(forNode, temp);
4352 temp.push_back(indent() + "return "s + accum + nlr(forNode)); 4393 temp.push_back(indent() + "return "s + accum + nlr(forNode));
4353 _enableReturn.pop(); 4394 _enableReturn.pop();
4354 popScope(); 4395 popScope();
4355 temp.push_back(indent() + "end)()"s); 4396 funcStart = anonFuncStart() + nll(forNode);
4397 temp.push_back(indent() + anonFuncEnd());
4398 popAnonVarArg();
4356 out.push_back(join(temp)); 4399 out.push_back(join(temp));
4357 } 4400 }
4358 4401
@@ -4414,14 +4457,17 @@ private:
4414 4457
4415 void transformForEachClosure(ForEach_t* forEach, str_list& out) { 4458 void transformForEachClosure(ForEach_t* forEach, str_list& out) {
4416 str_list temp; 4459 str_list temp;
4417 _buf << "(function()"sv << nll(forEach); 4460 pushAnonVarArg();
4461 std::string& funcStart = temp.emplace_back();
4418 pushScope(); 4462 pushScope();
4419 _enableReturn.push(true); 4463 _enableReturn.push(true);
4420 auto accum = transformForEachInner(forEach, temp); 4464 auto accum = transformForEachInner(forEach, temp);
4421 temp.push_back(indent() + "return "s + accum + nlr(forEach)); 4465 temp.push_back(indent() + "return "s + accum + nlr(forEach));
4422 _enableReturn.pop(); 4466 _enableReturn.pop();
4423 popScope(); 4467 popScope();
4424 temp.push_back(indent() + "end)()"s); 4468 funcStart = anonFuncStart() + nll(forEach);
4469 temp.push_back(indent() + anonFuncEnd());
4470 popAnonVarArg();
4425 out.push_back(join(temp)); 4471 out.push_back(join(temp));
4426 } 4472 }
4427 4473
@@ -4566,13 +4612,16 @@ private:
4566 4612
4567 void transformClassDeclClosure(ClassDecl_t* classDecl, str_list& out) { 4613 void transformClassDeclClosure(ClassDecl_t* classDecl, str_list& out) {
4568 str_list temp; 4614 str_list temp;
4569 temp.push_back("(function()"s + nll(classDecl)); 4615 pushAnonVarArg();
4616 std::string& funcStart = temp.emplace_back();
4570 pushScope(); 4617 pushScope();
4571 _enableReturn.push(true); 4618 _enableReturn.push(true);
4572 transformClassDecl(classDecl, temp, ExpUsage::Return); 4619 transformClassDecl(classDecl, temp, ExpUsage::Return);
4573 _enableReturn.pop(); 4620 _enableReturn.pop();
4574 popScope(); 4621 popScope();
4575 temp.push_back("end)()"s); 4622 funcStart = anonFuncStart() + nll(classDecl);
4623 temp.push_back(indent() + anonFuncEnd());
4624 popAnonVarArg();
4576 out.push_back(join(temp)); 4625 out.push_back(join(temp));
4577 } 4626 }
4578 4627
@@ -4744,15 +4793,15 @@ private:
4744 if (extend) { 4793 if (extend) {
4745 _buf << indent(1) << "__init = function(self, ...)"sv << nll(classDecl); 4794 _buf << indent(1) << "__init = function(self, ...)"sv << nll(classDecl);
4746 _buf << indent(2) << "return _class_0.__parent.__init(self, ...)"sv << nll(classDecl); 4795 _buf << indent(2) << "return _class_0.__parent.__init(self, ...)"sv << nll(classDecl);
4747 _buf << indent(1) << "end,"sv << nll(classDecl); 4796 _buf << indent(1) << "end,"sv << nll(classDecl);
4748 } else { 4797 } else {
4749 _buf << indent(1) << "__init = function() end,"sv << nll(classDecl); 4798 _buf << indent(1) << "__init = function() end,"sv << nll(classDecl);
4750 } 4799 }
4751 } 4800 }
4752 _buf << indent(1) << "__base = "sv << baseVar; 4801 _buf << indent(1) << "__base = "sv << baseVar;
4753 if (!className.empty()) { 4802 if (!className.empty()) {
4754 _buf << ","sv << nll(classDecl); 4803 _buf << ","sv << nll(classDecl);
4755 _buf << indent(1) << "__name = "sv << className; 4804 _buf << indent(1) << "__name = "sv << className;
4756 } 4805 }
4757 if (extend) { 4806 if (extend) {
4758 _buf << ","sv << nll(classDecl); 4807 _buf << ","sv << nll(classDecl);
@@ -4931,13 +4980,16 @@ private:
4931 4980
4932 void transformWithClosure(With_t* with, str_list& out) { 4981 void transformWithClosure(With_t* with, str_list& out) {
4933 str_list temp; 4982 str_list temp;
4934 temp.push_back("(function()"s + nll(with)); 4983 pushAnonVarArg();
4984 std::string& funcStart = temp.emplace_back();
4935 pushScope(); 4985 pushScope();
4936 _enableReturn.push(true); 4986 _enableReturn.push(true);
4937 transformWith(with, temp, nullptr, true); 4987 transformWith(with, temp, nullptr, true);
4938 _enableReturn.pop(); 4988 _enableReturn.pop();
4939 popScope(); 4989 popScope();
4940 temp.push_back(indent() + "end)()"s); 4990 funcStart = anonFuncStart() + nll(with);
4991 temp.push_back(indent() + anonFuncEnd());
4992 popAnonVarArg();
4941 out.push_back(join(temp)); 4993 out.push_back(join(temp));
4942 } 4994 }
4943 4995
@@ -5340,6 +5392,7 @@ private:
5340 case ExpUsage::Closure: 5392 case ExpUsage::Closure:
5341 pushScope(); 5393 pushScope();
5342 _enableReturn.push(true); 5394 _enableReturn.push(true);
5395 pushAnonVarArg();
5343 break; 5396 break;
5344 case ExpUsage::Assignment: 5397 case ExpUsage::Assignment:
5345 pushScope(); 5398 pushScope();
@@ -5397,8 +5450,9 @@ private:
5397 out.push_back(clearBuf() + indent() + "return "s + tbl + nlr(comp)); 5450 out.push_back(clearBuf() + indent() + "return "s + tbl + nlr(comp));
5398 popScope(); 5451 popScope();
5399 _enableReturn.pop(); 5452 _enableReturn.pop();
5400 out.back().insert(0, "(function()"s + nll(comp)); 5453 out.back().insert(0, anonFuncStart() + nll(comp));
5401 out.back().append(indent() + "end)()"s); 5454 out.back().append(indent() + anonFuncEnd());
5455 popAnonVarArg();
5402 break; 5456 break;
5403 case ExpUsage::Assignment: { 5457 case ExpUsage::Assignment: {
5404 out.push_back(clearBuf()); 5458 out.push_back(clearBuf());
@@ -5452,9 +5506,11 @@ private:
5452 5506
5453 void transformDo(Do_t* doNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 5507 void transformDo(Do_t* doNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
5454 str_list temp; 5508 str_list temp;
5509 std::string* funcStart = nullptr;
5455 if (usage == ExpUsage::Closure) { 5510 if (usage == ExpUsage::Closure) {
5456 temp.push_back("(function()"s + nll(doNode));
5457 _enableReturn.push(true); 5511 _enableReturn.push(true);
5512 pushAnonVarArg();
5513 funcStart = &temp.emplace_back();
5458 } else { 5514 } else {
5459 temp.push_back(indent() + "do"s + nll(doNode)); 5515 temp.push_back(indent() + "do"s + nll(doNode));
5460 } 5516 }
@@ -5463,7 +5519,9 @@ private:
5463 popScope(); 5519 popScope();
5464 if (usage == ExpUsage::Closure) { 5520 if (usage == ExpUsage::Closure) {
5465 _enableReturn.pop(); 5521 _enableReturn.pop();
5466 temp.push_back(indent() + "end)()"s); 5522 *funcStart = anonFuncStart() + nll(doNode);
5523 temp.push_back(indent() + anonFuncEnd());
5524 popAnonVarArg();
5467 } else { 5525 } else {
5468 temp.push_back(indent() + "end"s + nlr(doNode)); 5526 temp.push_back(indent() + "end"s + nlr(doNode));
5469 } 5527 }
@@ -5769,7 +5827,8 @@ private:
5769 void transformWhileClosure(While_t* whileNode, str_list& out) { 5827 void transformWhileClosure(While_t* whileNode, str_list& out) {
5770 auto x = whileNode; 5828 auto x = whileNode;
5771 str_list temp; 5829 str_list temp;
5772 temp.push_back("(function() "s + nll(whileNode)); 5830 pushAnonVarArg();
5831 std::string& funcStart = temp.emplace_back();
5773 pushScope(); 5832 pushScope();
5774 _enableReturn.push(true); 5833 _enableReturn.push(true);
5775 auto accumVar = getUnusedName("_accum_"sv); 5834 auto accumVar = getUnusedName("_accum_"sv);
@@ -5790,7 +5849,9 @@ private:
5790 temp.push_back(indent() + "return "s + accumVar + nlr(whileNode)); 5849 temp.push_back(indent() + "return "s + accumVar + nlr(whileNode));
5791 _enableReturn.pop(); 5850 _enableReturn.pop();
5792 popScope(); 5851 popScope();
5793 temp.push_back(indent() + "end)()"s); 5852 funcStart = anonFuncStart() + nll(whileNode);
5853 temp.push_back(indent() + anonFuncEnd());
5854 popAnonVarArg();
5794 out.push_back(join(temp)); 5855 out.push_back(join(temp));
5795 } 5856 }
5796 5857
@@ -5821,8 +5882,10 @@ private:
5821 5882
5822 void transformSwitch(Switch_t* switchNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 5883 void transformSwitch(Switch_t* switchNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
5823 str_list temp; 5884 str_list temp;
5885 std::string* funcStart = nullptr;
5824 if (usage == ExpUsage::Closure) { 5886 if (usage == ExpUsage::Closure) {
5825 temp.push_back("(function()"s + nll(switchNode)); 5887 pushAnonVarArg();
5888 funcStart = &temp.emplace_back();
5826 pushScope(); 5889 pushScope();
5827 _enableReturn.push(true); 5890 _enableReturn.push(true);
5828 } 5891 }
@@ -5864,7 +5927,9 @@ private:
5864 if (usage == ExpUsage::Closure) { 5927 if (usage == ExpUsage::Closure) {
5865 _enableReturn.pop(); 5928 _enableReturn.pop();
5866 popScope(); 5929 popScope();
5867 temp.push_back(indent() + "end)()"s); 5930 *funcStart = anonFuncStart() + nll(switchNode);
5931 temp.push_back(indent() + anonFuncEnd());
5932 popAnonVarArg();
5868 } 5933 }
5869 out.push_back(join(temp)); 5934 out.push_back(join(temp));
5870 } 5935 }
@@ -6027,3 +6092,4 @@ CompileInfo YueCompiler::compile(std::string_view codes, const YueConfig& config
6027} 6092}
6028 6093
6029} // namespace yue 6094} // namespace yue
6095