aboutsummaryrefslogtreecommitdiff
path: root/src/yuescript/yue_compiler.cpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2023-01-29 10:29:19 +0800
committerLi Jin <dragon-fly@qq.com>2023-01-29 10:29:19 +0800
commite10b1b163a9a173f32b956bf1fb9be00194352b5 (patch)
tree4692fe729bbb588c0565ce78426c932e8b360f22 /src/yuescript/yue_compiler.cpp
parent32f2a579ec15e6204e44d67ab2b8b4a1796e9a84 (diff)
downloadyuescript-e10b1b163a9a173f32b956bf1fb9be00194352b5.tar.gz
yuescript-e10b1b163a9a173f32b956bf1fb9be00194352b5.tar.bz2
yuescript-e10b1b163a9a173f32b956bf1fb9be00194352b5.zip
fix cases from issue #120.
Diffstat (limited to '')
-rw-r--r--src/yuescript/yue_compiler.cpp54
1 files changed, 32 insertions, 22 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 5443c61..c7f0f27 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -71,7 +71,7 @@ static std::unordered_set<std::string> Metamethods = {
71 "close"s // Lua 5.4 71 "close"s // Lua 5.4
72}; 72};
73 73
74const std::string_view version = "0.15.23"sv; 74const std::string_view version = "0.15.24"sv;
75const std::string_view extension = "yue"sv; 75const std::string_view extension = "yue"sv;
76 76
77class YueCompilerImpl { 77class YueCompilerImpl {
@@ -1224,6 +1224,8 @@ private:
1224 } 1224 }
1225 default: YUEE("AST node mismatch", appendix->item.get()); break; 1225 default: YUEE("AST node mismatch", appendix->item.get()); break;
1226 } 1226 }
1227 } else if (statement->content.is<Return_t>() && !statement->appendix->item.is<IfLine_t>()) {
1228 throw std::logic_error(_info.errorMessage("loop line decorator can not be used in a return statement"sv, statement->appendix->item));
1227 } 1229 }
1228 auto appendix = statement->appendix.get(); 1230 auto appendix = statement->appendix.get();
1229 switch (appendix->item->getId()) { 1231 switch (appendix->item->getId()) {
@@ -1357,7 +1359,7 @@ private:
1357 break; 1359 break;
1358 } 1360 }
1359 } 1361 }
1360 throw std::logic_error(_info.errorMessage("expression list is not supported here"sv, expList)); 1362 throw std::logic_error(_info.errorMessage("unexpected expression"sv, expList));
1361 } 1363 }
1362 break; 1364 break;
1363 } 1365 }
@@ -3029,7 +3031,7 @@ private:
3029 auto unary = static_cast<UnaryExp_t*>(*it); 3031 auto unary = static_cast<UnaryExp_t*>(*it);
3030 auto value = static_cast<Value_t*>(singleUnaryExpFrom(unary) ? unary->expos.back() : nullptr); 3032 auto value = static_cast<Value_t*>(singleUnaryExpFrom(unary) ? unary->expos.back() : nullptr);
3031 if (values.back() == *it && !unary->ops.empty() && usage == ExpUsage::Common) { 3033 if (values.back() == *it && !unary->ops.empty() && usage == ExpUsage::Common) {
3032 throw std::logic_error(_info.errorMessage("expression list is not supported here"sv, x)); 3034 throw std::logic_error(_info.errorMessage("unexpected expression"sv, x));
3033 } 3035 }
3034 if (!value) throw std::logic_error(_info.errorMessage("pipe operator must be followed by chain value"sv, *it)); 3036 if (!value) throw std::logic_error(_info.errorMessage("pipe operator must be followed by chain value"sv, *it));
3035 if (auto chainValue = value->item.as<ChainValue_t>()) { 3037 if (auto chainValue = value->item.as<ChainValue_t>()) {
@@ -3275,13 +3277,6 @@ private:
3275 globalVar("self"sv, item); 3277 globalVar("self"sv, item);
3276 break; 3278 break;
3277 } 3279 }
3278 case id<VarArg_t>():
3279 if (_varArgs.empty() || !_varArgs.top().hasVar) {
3280 throw std::logic_error(_info.errorMessage("cannot use '...' outside a vararg function near '...'"sv, item));
3281 }
3282 _varArgs.top().usedVar = true;
3283 out.push_back("..."s);
3284 break;
3285 case id<Parens_t>(): transformParens(static_cast<Parens_t*>(item), out); break; 3280 case id<Parens_t>(): transformParens(static_cast<Parens_t*>(item), out); break;
3286 default: YUEE("AST node mismatch", item); break; 3281 default: YUEE("AST node mismatch", item); break;
3287 } 3282 }
@@ -3312,6 +3307,7 @@ private:
3312 case id<Comprehension_t>(): transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Closure); break; 3307 case id<Comprehension_t>(): transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Closure); break;
3313 case id<FunLit_t>(): transformFunLit(static_cast<FunLit_t*>(value), out); break; 3308 case id<FunLit_t>(): transformFunLit(static_cast<FunLit_t*>(value), out); break;
3314 case id<Num_t>(): transformNum(static_cast<Num_t*>(value), out); break; 3309 case id<Num_t>(): transformNum(static_cast<Num_t*>(value), out); break;
3310 case id<VarArg_t>(): transformVarArg(static_cast<VarArg_t*>(value), out); break;
3315 default: YUEE("AST node mismatch", value); break; 3311 default: YUEE("AST node mismatch", value); break;
3316 } 3312 }
3317 } 3313 }
@@ -3638,8 +3634,19 @@ private:
3638 } 3634 }
3639 case ExpUsage::Assignment: { 3635 case ExpUsage::Assignment: {
3640 auto last = lastStatementFrom(block); 3636 auto last = lastStatementFrom(block);
3641 if (!last) return; 3637 if (!last) throw std::logic_error(_info.errorMessage("block is not assignable"sv, block));
3642 bool lastAssignable = expListFrom(last) || ast_is<For_t, ForEach_t, While_t>(last->content); 3638 if (last->appendix) {
3639 auto appendix = last->appendix->item.get();
3640 switch (appendix->getId()) {
3641 case id<WhileLine_t>():
3642 throw std::logic_error(_info.errorMessage("while-loop line decorator is not supported here"sv, appendix));
3643 break;
3644 case id<CompFor_t>():
3645 throw std::logic_error(_info.errorMessage("for-loop line decorator is not supported here"sv, appendix));
3646 break;
3647 }
3648 }
3649 bool lastAssignable = (expListFrom(last) || ast_is<For_t, ForEach_t, While_t>(last->content));
3643 if (lastAssignable) { 3650 if (lastAssignable) {
3644 auto x = last; 3651 auto x = last;
3645 auto newAssignment = x->new_ptr<ExpListAssign_t>(); 3652 auto newAssignment = x->new_ptr<ExpListAssign_t>();
@@ -3660,6 +3667,8 @@ private:
3660 if (bLast != nodes.rend()) { 3667 if (bLast != nodes.rend()) {
3661 static_cast<Statement_t*>(*bLast)->needSep.set(nullptr); 3668 static_cast<Statement_t*>(*bLast)->needSep.set(nullptr);
3662 } 3669 }
3670 } else if (!last->content.is<BreakLoop_t>()) {
3671 throw std::logic_error(_info.errorMessage("expecting assignable statement or break loop"sv, last));
3663 } 3672 }
3664 break; 3673 break;
3665 } 3674 }
@@ -4627,12 +4636,6 @@ private:
4627 4636
4628 void transformChainList(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 4637 void transformChainList(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
4629 auto x = chainList.front(); 4638 auto x = chainList.front();
4630 if (chainList.size() > 1) {
4631 auto callable = ast_cast<Callable_t>(x);
4632 if (callable && callable->item.is<VarArg_t>()) {
4633 throw std::logic_error(_info.errorMessage("can not access variadic arguments directly"sv, x));
4634 }
4635 }
4636 str_list temp; 4639 str_list temp;
4637 switch (x->getId()) { 4640 switch (x->getId()) {
4638 case id<DotChainItem_t>(): 4641 case id<DotChainItem_t>():
@@ -5277,6 +5280,14 @@ private:
5277 out.push_back(numStr); 5280 out.push_back(numStr);
5278 } 5281 }
5279 5282
5283 void transformVarArg(VarArg_t* varArg, str_list& out) {
5284 if (_varArgs.empty() || !_varArgs.top().hasVar) {
5285 throw std::logic_error(_info.errorMessage("cannot use '...' outside a vararg function near '...'"sv, varArg));
5286 }
5287 _varArgs.top().usedVar = true;
5288 out.push_back("..."s);
5289 }
5290
5280 bool hasSpreadExp(const node_container& items) { 5291 bool hasSpreadExp(const node_container& items) {
5281 for (auto item : items) { 5292 for (auto item : items) {
5282 if (ast_is<SpreadExp_t>(item)) return true; 5293 if (ast_is<SpreadExp_t>(item)) return true;
@@ -5420,10 +5431,9 @@ private:
5420 BREAK_IF(current != values.back()); 5431 BREAK_IF(current != values.back());
5421 auto value = singleValueFrom(item); 5432 auto value = singleValueFrom(item);
5422 BREAK_IF(!value); 5433 BREAK_IF(!value);
5423 auto chainValue = value->item.as<ChainValue_t>(); 5434 auto simpleValue = value->item.as<SimpleValue_t>();
5424 BREAK_IF(!chainValue); 5435 BREAK_IF(!simpleValue);
5425 BREAK_IF(chainValue->items.size() != 1); 5436 BREAK_IF(!simpleValue->value.is<VarArg_t>());
5426 BREAK_IF((!chainValue->getByPath<Callable_t, VarArg_t>()));
5427 auto indexVar = getUnusedName("_index_"); 5437 auto indexVar = getUnusedName("_index_");
5428 _buf << "for "sv << indexVar << "=1,select '#',...\n\t"sv << tableVar << "[]= select "sv << indexVar << ",..."sv; 5438 _buf << "for "sv << indexVar << "=1,select '#',...\n\t"sv << tableVar << "[]= select "sv << indexVar << ",..."sv;
5429 transformFor(toAst<For_t>(clearBuf(), item), temp); 5439 transformFor(toAst<For_t>(clearBuf(), item), temp);