diff options
author | Li Jin <dragon-fly@qq.com> | 2021-05-13 10:38:31 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2021-05-13 10:38:31 +0800 |
commit | 4d61a00ebc5b956da72525de0e180de28a1e8ac6 (patch) | |
tree | 02c6967a1966078563f5fcfdca8cdcc1b58e9864 | |
parent | 4c9209b131936ad97c73a7c0e71042fe24369a8e (diff) | |
download | yuescript-4d61a00ebc5b956da72525de0e180de28a1e8ac6.tar.gz yuescript-4d61a00ebc5b956da72525de0e180de28a1e8ac6.tar.bz2 yuescript-4d61a00ebc5b956da72525de0e180de28a1e8ac6.zip |
fix issue #52, add until statement.
-rw-r--r-- | spec/inputs/loops.yue | 16 | ||||
-rw-r--r-- | src/yuescript/yue_ast.h | 19 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 88 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 9 | ||||
-rw-r--r-- | src/yuescript/yue_parser.h | 3 |
5 files changed, 79 insertions, 56 deletions
diff --git a/spec/inputs/loops.yue b/spec/inputs/loops.yue index 5708809..3191000 100644 --- a/spec/inputs/loops.yue +++ b/spec/inputs/loops.yue | |||
@@ -109,6 +109,22 @@ repeat | |||
109 | print a | 109 | print a |
110 | until a == 10 | 110 | until a == 10 |
111 | 111 | ||
112 | a = 3 | ||
113 | until a == 0 | ||
114 | a -= 1 | ||
115 | done = false | ||
116 | until done do done = true | ||
117 | repeat | ||
118 | print "hello" | ||
119 | until true | ||
120 | until done | ||
121 | x = 10 | ||
122 | repeat | ||
123 | x -= 1 | ||
124 | until x == 0 | ||
125 | until cond | ||
126 | print "okay" | ||
127 | |||
112 | for x=1,10 | 128 | for x=1,10 |
113 | continue if x > 3 and x < 7 | 129 | continue if x > 3 and x < 7 |
114 | print x | 130 | print x |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 1e95d11..695fbe1 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -256,22 +256,23 @@ AST_NODE(IfCond) | |||
256 | AST_MEMBER(IfCond, &condition, &assign) | 256 | AST_MEMBER(IfCond, &condition, &assign) |
257 | AST_END(IfCond) | 257 | AST_END(IfCond) |
258 | 258 | ||
259 | AST_LEAF(IfType) | ||
260 | AST_END(IfType) | ||
261 | |||
259 | AST_NODE(If) | 262 | AST_NODE(If) |
260 | ast_ptr<true, Seperator_t> sep; | 263 | ast_ptr<true, IfType_t> type; |
261 | ast_sel_list<true, IfCond_t, Block_t, Statement_t> nodes; | 264 | ast_sel_list<true, IfCond_t, Block_t, Statement_t> nodes; |
262 | AST_MEMBER(If, &sep, &nodes) | 265 | AST_MEMBER(If, &type, &nodes) |
263 | AST_END(If) | 266 | AST_END(If) |
264 | 267 | ||
265 | AST_NODE(Unless) | 268 | AST_LEAF(WhileType) |
266 | ast_ptr<true, Seperator_t> sep; | 269 | AST_END(WhileType) |
267 | ast_sel_list<true, IfCond_t, Block_t, Statement_t> nodes; | ||
268 | AST_MEMBER(Unless, &sep, &nodes) | ||
269 | AST_END(Unless) | ||
270 | 270 | ||
271 | AST_NODE(While) | 271 | AST_NODE(While) |
272 | ast_ptr<true, WhileType_t> type; | ||
272 | ast_ptr<true, Exp_t> condition; | 273 | ast_ptr<true, Exp_t> condition; |
273 | ast_sel<true, Block_t, Statement_t> body; | 274 | ast_sel<true, Block_t, Statement_t> body; |
274 | AST_MEMBER(While, &condition, &body) | 275 | AST_MEMBER(While, &type, &condition, &body) |
275 | AST_END(While) | 276 | AST_END(While) |
276 | 277 | ||
277 | class Body_t; | 278 | class Body_t; |
@@ -451,7 +452,7 @@ class FunLit_t; | |||
451 | 452 | ||
452 | AST_NODE(SimpleValue) | 453 | AST_NODE(SimpleValue) |
453 | ast_sel<true, const_value_t, | 454 | ast_sel<true, const_value_t, |
454 | If_t, Unless_t, Switch_t, With_t, ClassDecl_t, | 455 | If_t, Switch_t, With_t, ClassDecl_t, |
455 | ForEach_t, For_t, While_t, Do_t, | 456 | ForEach_t, For_t, While_t, Do_t, |
456 | unary_value_t, | 457 | unary_value_t, |
457 | TblComprehension_t, TableLit_t, Comprehension_t, | 458 | TblComprehension_t, TableLit_t, Comprehension_t, |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 4646288..0c71806 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -59,7 +59,7 @@ inline std::string s(std::string_view sv) { | |||
59 | return std::string(sv); | 59 | return std::string(sv); |
60 | } | 60 | } |
61 | 61 | ||
62 | const std::string_view version = "0.7.13"sv; | 62 | const std::string_view version = "0.7.14"sv; |
63 | const std::string_view extension = "yue"sv; | 63 | const std::string_view extension = "yue"sv; |
64 | 64 | ||
65 | class YueCompilerImpl { | 65 | class YueCompilerImpl { |
@@ -401,6 +401,22 @@ private: | |||
401 | return newName; | 401 | return newName; |
402 | } | 402 | } |
403 | 403 | ||
404 | std::string transformCondExp(Exp_t* cond, bool unless) { | ||
405 | str_list tmp; | ||
406 | if (unless) { | ||
407 | if (auto value = singleValueFrom(cond)) { | ||
408 | transformValue(value, tmp); | ||
409 | } else { | ||
410 | transformExp(cond, tmp, ExpUsage::Closure); | ||
411 | tmp.back() = s("("sv) + tmp.back() + s(")"sv); | ||
412 | } | ||
413 | return s("not "sv) + tmp.back(); | ||
414 | } else { | ||
415 | transformExp(cond, tmp, ExpUsage::Closure); | ||
416 | return tmp.back(); | ||
417 | } | ||
418 | } | ||
419 | |||
404 | const std::string nll(ast_node* node) const { | 420 | const std::string nll(ast_node* node) const { |
405 | if (_config.reserveLineNumber) { | 421 | if (_config.reserveLineNumber) { |
406 | return s(" -- "sv) + std::to_string(node->m_begin.m_line + _config.lineOffset) + _newLine; | 422 | return s(" -- "sv) + std::to_string(node->m_begin.m_line + _config.lineOffset) + _newLine; |
@@ -874,8 +890,10 @@ private: | |||
874 | auto appendix = statement->appendix.get(); | 890 | auto appendix = statement->appendix.get(); |
875 | switch (appendix->item->getId()) { | 891 | switch (appendix->item->getId()) { |
876 | case id<if_line_t>(): { | 892 | case id<if_line_t>(): { |
877 | auto if_line = appendix->item.to<if_line_t>(); | 893 | auto if_line = static_cast<if_line_t*>(appendix->item.get()); |
878 | auto ifNode = x->new_ptr<If_t>(); | 894 | auto ifNode = x->new_ptr<If_t>(); |
895 | auto ifType = toAst<IfType_t>("if"sv, x); | ||
896 | ifNode->type.set(ifType); | ||
879 | 897 | ||
880 | auto ifCond = x->new_ptr<IfCond_t>(); | 898 | auto ifCond = x->new_ptr<IfCond_t>(); |
881 | ifCond->condition.set(if_line->condition); | 899 | ifCond->condition.set(if_line->condition); |
@@ -900,20 +918,22 @@ private: | |||
900 | break; | 918 | break; |
901 | } | 919 | } |
902 | case id<unless_line_t>(): { | 920 | case id<unless_line_t>(): { |
903 | auto unless_line = appendix->item.to<unless_line_t>(); | 921 | auto unless_line = static_cast<unless_line_t*>(appendix->item.get()); |
904 | auto unless = x->new_ptr<Unless_t>(); | 922 | auto ifNode = x->new_ptr<If_t>(); |
923 | auto ifType = toAst<IfType_t>("unless"sv, x); | ||
924 | ifNode->type.set(ifType); | ||
905 | 925 | ||
906 | auto ifCond = x->new_ptr<IfCond_t>(); | 926 | auto ifCond = x->new_ptr<IfCond_t>(); |
907 | ifCond->condition.set(unless_line->condition); | 927 | ifCond->condition.set(unless_line->condition); |
908 | unless->nodes.push_back(ifCond); | 928 | ifNode->nodes.push_back(ifCond); |
909 | 929 | ||
910 | auto stmt = x->new_ptr<Statement_t>(); | 930 | auto stmt = x->new_ptr<Statement_t>(); |
911 | stmt->content.set(statement->content); | 931 | stmt->content.set(statement->content); |
912 | unless->nodes.push_back(stmt); | 932 | ifNode->nodes.push_back(stmt); |
913 | 933 | ||
914 | statement->appendix.set(nullptr); | 934 | statement->appendix.set(nullptr); |
915 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 935 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
916 | simpleValue->value.set(unless); | 936 | simpleValue->value.set(ifNode); |
917 | auto value = x->new_ptr<Value_t>(); | 937 | auto value = x->new_ptr<Value_t>(); |
918 | value->item.set(simpleValue); | 938 | value->item.set(simpleValue); |
919 | auto exp = newExp(value, x); | 939 | auto exp = newExp(value, x); |
@@ -985,7 +1005,6 @@ private: | |||
985 | switch (value->getId()) { | 1005 | switch (value->getId()) { |
986 | case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Common); break; | 1006 | case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Common); break; |
987 | case id<ClassDecl_t>(): transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Common); break; | 1007 | case id<ClassDecl_t>(): transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Common); break; |
988 | case id<Unless_t>(): transformUnless(static_cast<Unless_t*>(value), out, ExpUsage::Common); break; | ||
989 | case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Common); break; | 1008 | case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Common); break; |
990 | case id<With_t>(): transformWith(static_cast<With_t*>(value), out); break; | 1009 | case id<With_t>(): transformWith(static_cast<With_t*>(value), out); break; |
991 | case id<ForEach_t>(): transformForEach(static_cast<ForEach_t*>(value), out); break; | 1010 | case id<ForEach_t>(): transformForEach(static_cast<ForEach_t*>(value), out); break; |
@@ -1208,16 +1227,12 @@ private: | |||
1208 | } | 1227 | } |
1209 | } | 1228 | } |
1210 | switch (value->getId()) { | 1229 | switch (value->getId()) { |
1211 | case id<If_t>(): | 1230 | case id<If_t>(): { |
1212 | case id<Unless_t>(): { | ||
1213 | auto expList = assignment->expList.get(); | 1231 | auto expList = assignment->expList.get(); |
1214 | str_list temp; | 1232 | str_list temp; |
1215 | auto defs = transformAssignDefs(expList, DefOp::Mark); | 1233 | auto defs = transformAssignDefs(expList, DefOp::Mark); |
1216 | if (!defs.empty()) temp.push_back(getPredefine(defs) + nll(expList)); | 1234 | if (!defs.empty()) temp.push_back(getPredefine(defs) + nll(expList)); |
1217 | switch (value->getId()) { | 1235 | transformIf(static_cast<If_t*>(value), temp, ExpUsage::Assignment, expList); |
1218 | case id<If_t>(): transformIf(static_cast<If_t*>(value), temp, ExpUsage::Assignment, expList); break; | ||
1219 | case id<Unless_t>(): transformUnless(static_cast<Unless_t*>(value), temp, ExpUsage::Assignment, expList); break; | ||
1220 | } | ||
1221 | out.push_back(join(temp)); | 1236 | out.push_back(join(temp)); |
1222 | return; | 1237 | return; |
1223 | } | 1238 | } |
@@ -1806,6 +1821,7 @@ private: | |||
1806 | if (*it != nodes.front() && cond->assign) { | 1821 | if (*it != nodes.front() && cond->assign) { |
1807 | auto x = *it; | 1822 | auto x = *it; |
1808 | auto newIf = x->new_ptr<If_t>(); | 1823 | auto newIf = x->new_ptr<If_t>(); |
1824 | newIf->type.set(toAst<IfType_t>("if"sv, x)); | ||
1809 | for (auto j = ns.rbegin(); j != ns.rend(); ++j) { | 1825 | for (auto j = ns.rbegin(); j != ns.rend(); ++j) { |
1810 | newIf->nodes.push_back(*j); | 1826 | newIf->nodes.push_back(*j); |
1811 | } | 1827 | } |
@@ -1828,6 +1844,7 @@ private: | |||
1828 | if (nodes.size() != ns.size()) { | 1844 | if (nodes.size() != ns.size()) { |
1829 | auto x = ns.back(); | 1845 | auto x = ns.back(); |
1830 | auto newIf = x->new_ptr<If_t>(); | 1846 | auto newIf = x->new_ptr<If_t>(); |
1847 | newIf->type.set(toAst<IfType_t>("if"sv, x)); | ||
1831 | for (auto j = ns.rbegin(); j != ns.rend(); ++j) { | 1848 | for (auto j = ns.rbegin(); j != ns.rend(); ++j) { |
1832 | newIf->nodes.push_back(*j); | 1849 | newIf->nodes.push_back(*j); |
1833 | } | 1850 | } |
@@ -1918,23 +1935,13 @@ private: | |||
1918 | if (pair.first) { | 1935 | if (pair.first) { |
1919 | str_list tmp; | 1936 | str_list tmp; |
1920 | auto condition = pair.first->condition.get(); | 1937 | auto condition = pair.first->condition.get(); |
1921 | if (unless) { | 1938 | auto condStr = transformCondExp(condition, unless); |
1922 | if (auto value = singleValueFrom(condition)) { | 1939 | if (unless) unless = false; |
1923 | transformValue(value, tmp); | ||
1924 | } else { | ||
1925 | transformExp(condition, tmp, ExpUsage::Closure); | ||
1926 | tmp.back() = s("("sv) + tmp.back() + s(")"sv); | ||
1927 | } | ||
1928 | tmp.back().insert(0, s("not "sv)); | ||
1929 | unless = false; | ||
1930 | } else { | ||
1931 | transformExp(condition, tmp, ExpUsage::Closure); | ||
1932 | } | ||
1933 | _buf << indent(); | 1940 | _buf << indent(); |
1934 | if (pair != ifCondPairs.front()) { | 1941 | if (pair != ifCondPairs.front()) { |
1935 | _buf << "else"sv; | 1942 | _buf << "else"sv; |
1936 | } | 1943 | } |
1937 | _buf << "if "sv << tmp.back() << " then"sv << nll(condition); | 1944 | _buf << "if "sv << condStr << " then"sv << nll(condition); |
1938 | temp.push_back(clearBuf()); | 1945 | temp.push_back(clearBuf()); |
1939 | } | 1946 | } |
1940 | if (pair.second) { | 1947 | if (pair.second) { |
@@ -1966,11 +1973,8 @@ private: | |||
1966 | } | 1973 | } |
1967 | 1974 | ||
1968 | void transformIf(If_t* ifNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 1975 | void transformIf(If_t* ifNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
1969 | transformCond(ifNode->nodes.objects(), out, usage, false, assignList); | 1976 | bool unless = _parser.toString(ifNode->type) == "unless"sv; |
1970 | } | 1977 | transformCond(ifNode->nodes.objects(), out, usage, unless, assignList); |
1971 | |||
1972 | void transformUnless(Unless_t* unless, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | ||
1973 | transformCond(unless->nodes.objects(), out, usage, true, assignList); | ||
1974 | } | 1978 | } |
1975 | 1979 | ||
1976 | void transformExpList(ExpList_t* expList, str_list& out) { | 1980 | void transformExpList(ExpList_t* expList, str_list& out) { |
@@ -2146,7 +2150,6 @@ private: | |||
2146 | switch (value->getId()) { | 2150 | switch (value->getId()) { |
2147 | case id<const_value_t>(): transform_const_value(static_cast<const_value_t*>(value), out); break; | 2151 | case id<const_value_t>(): transform_const_value(static_cast<const_value_t*>(value), out); break; |
2148 | case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break; | 2152 | case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break; |
2149 | case id<Unless_t>(): transformUnless(static_cast<Unless_t*>(value), out, ExpUsage::Closure); break; | ||
2150 | case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break; | 2153 | case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break; |
2151 | case id<With_t>(): transformWithClosure(static_cast<With_t*>(value), out); break; | 2154 | case id<With_t>(): transformWithClosure(static_cast<With_t*>(value), out); break; |
2152 | case id<ClassDecl_t>(): transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; | 2155 | case id<ClassDecl_t>(): transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; |
@@ -2757,9 +2760,6 @@ private: | |||
2757 | case id<If_t>(): | 2760 | case id<If_t>(): |
2758 | transformIf(static_cast<If_t*>(value), out, ExpUsage::Return); | 2761 | transformIf(static_cast<If_t*>(value), out, ExpUsage::Return); |
2759 | return; | 2762 | return; |
2760 | case id<Unless_t>(): | ||
2761 | transformUnless(static_cast<Unless_t*>(value), out, ExpUsage::Return); | ||
2762 | return; | ||
2763 | } | 2763 | } |
2764 | } else if (auto chainValue = singleValue->item.as<ChainValue_t>()) { | 2764 | } else if (auto chainValue = singleValue->item.as<ChainValue_t>()) { |
2765 | if (specialChainValue(chainValue) != ChainType::Common) { | 2765 | if (specialChainValue(chainValue) != ChainType::Common) { |
@@ -5054,6 +5054,7 @@ private: | |||
5054 | _withVars.push(withVar); | 5054 | _withVars.push(withVar); |
5055 | if (with->eop) { | 5055 | if (with->eop) { |
5056 | auto ifNode = x->new_ptr<If_t>(); | 5056 | auto ifNode = x->new_ptr<If_t>(); |
5057 | ifNode->type.set(toAst<IfType_t>("if"sv, x)); | ||
5057 | ifNode->nodes.push_back(toAst<IfCond_t>(withVar + s("~=nil"sv), x)); | 5058 | ifNode->nodes.push_back(toAst<IfCond_t>(withVar + s("~=nil"sv), x)); |
5058 | ifNode->nodes.push_back(with->body); | 5059 | ifNode->nodes.push_back(with->body); |
5059 | transformIf(ifNode, temp, ExpUsage::Common); | 5060 | transformIf(ifNode, temp, ExpUsage::Common); |
@@ -5733,8 +5734,9 @@ private: | |||
5733 | addToScope(lenVar); | 5734 | addToScope(lenVar); |
5734 | temp.push_back(indent() + s("local "sv) + accumVar + s(" = { }"sv) + nll(whileNode)); | 5735 | temp.push_back(indent() + s("local "sv) + accumVar + s(" = { }"sv) + nll(whileNode)); |
5735 | temp.push_back(indent() + s("local "sv) + lenVar + s(" = 1"sv) + nll(whileNode)); | 5736 | temp.push_back(indent() + s("local "sv) + lenVar + s(" = 1"sv) + nll(whileNode)); |
5736 | transformExp(whileNode->condition, temp, ExpUsage::Closure); | 5737 | bool isUntil = _parser.toString(whileNode->type) == "until"sv; |
5737 | temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode); | 5738 | auto condStr = transformCondExp(whileNode->condition, isUntil); |
5739 | temp.push_back(indent() + s("while "sv) + condStr + s(" do"sv) + nll(whileNode)); | ||
5738 | pushScope(); | 5740 | pushScope(); |
5739 | auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), x); | 5741 | auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), x); |
5740 | auto lenLine = lenVar + s(" = "sv) + lenVar + s(" + 1"sv) + nlr(whileNode); | 5742 | auto lenLine = lenVar + s(" = "sv) + lenVar + s(" + 1"sv) + nlr(whileNode); |
@@ -5770,8 +5772,9 @@ private: | |||
5770 | addToScope(lenVar); | 5772 | addToScope(lenVar); |
5771 | temp.push_back(indent() + s("local "sv) + accumVar + s(" = { }"sv) + nll(whileNode)); | 5773 | temp.push_back(indent() + s("local "sv) + accumVar + s(" = { }"sv) + nll(whileNode)); |
5772 | temp.push_back(indent() + s("local "sv) + lenVar + s(" = 1"sv) + nll(whileNode)); | 5774 | temp.push_back(indent() + s("local "sv) + lenVar + s(" = 1"sv) + nll(whileNode)); |
5773 | transformExp(whileNode->condition, temp, ExpUsage::Closure); | 5775 | bool isUntil = _parser.toString(whileNode->type) == "until"sv; |
5774 | temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode); | 5776 | auto condStr = transformCondExp(whileNode->condition, isUntil); |
5777 | temp.push_back(indent() + s("while "sv) + condStr + s(" do"sv) + nll(whileNode)); | ||
5775 | pushScope(); | 5778 | pushScope(); |
5776 | auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), x); | 5779 | auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), x); |
5777 | auto lenLine = lenVar + s(" = "sv) + lenVar + s(" + 1"sv) + nlr(whileNode); | 5780 | auto lenLine = lenVar + s(" = "sv) + lenVar + s(" + 1"sv) + nlr(whileNode); |
@@ -5788,10 +5791,11 @@ private: | |||
5788 | void transformWhile(While_t* whileNode, str_list& out) { | 5791 | void transformWhile(While_t* whileNode, str_list& out) { |
5789 | str_list temp; | 5792 | str_list temp; |
5790 | pushScope(); | 5793 | pushScope(); |
5791 | transformExp(whileNode->condition, temp, ExpUsage::Closure); | 5794 | bool isUntil = _parser.toString(whileNode->type) == "until"sv; |
5795 | auto condStr = transformCondExp(whileNode->condition, isUntil); | ||
5792 | transformLoopBody(whileNode->body, temp, Empty, ExpUsage::Common); | 5796 | transformLoopBody(whileNode->body, temp, Empty, ExpUsage::Common); |
5793 | popScope(); | 5797 | popScope(); |
5794 | _buf << indent() << "while "sv << temp.front() << " do"sv << nll(whileNode); | 5798 | _buf << indent() << "while "sv << condStr << " do"sv << nll(whileNode); |
5795 | _buf << temp.back(); | 5799 | _buf << temp.back(); |
5796 | _buf << indent() << "end"sv << nlr(whileNode); | 5800 | _buf << indent() << "end"sv << nlr(whileNode); |
5797 | out.push_back(clearBuf()); | 5801 | out.push_back(clearBuf()); |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 607edc9..255469d 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -244,10 +244,11 @@ YueParser::YueParser() { | |||
244 | IfCond = disable_chain(Exp >> -Assign); | 244 | IfCond = disable_chain(Exp >> -Assign); |
245 | IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> plain_body_with("then"); | 245 | IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> plain_body_with("then"); |
246 | IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> plain_body; | 246 | IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> plain_body; |
247 | If = key("if") >> Seperator >> IfCond >> plain_body_with("then") >> *IfElseIf >> -IfElse; | 247 | IfType = (expr("if") | expr("unless")) >> not_(AlphaNum); |
248 | Unless = key("unless") >> Seperator >> IfCond >> plain_body_with("then") >> *IfElseIf >> -IfElse; | 248 | If = Space >> IfType >> IfCond >> plain_body_with("then") >> *IfElseIf >> -IfElse; |
249 | 249 | ||
250 | While = key("while") >> disable_do_chain(Exp) >> plain_body_with("do"); | 250 | WhileType = (expr("while") | expr("until")) >> not_(AlphaNum); |
251 | While = Space >> WhileType >> disable_do_chain(Exp) >> plain_body_with("do"); | ||
251 | Repeat = key("repeat") >> Body >> Break >> *EmptyLine >> CheckIndent >> key("until") >> Exp; | 252 | Repeat = key("repeat") >> Body >> Break >> *EmptyLine >> CheckIndent >> key("until") >> Exp; |
252 | 253 | ||
253 | for_step_value = sym(',') >> Exp; | 254 | for_step_value = sym(',') >> Exp; |
@@ -607,7 +608,7 @@ YueParser::YueParser() { | |||
607 | 608 | ||
608 | SimpleValue = | 609 | SimpleValue = |
609 | (Space >> const_value) | | 610 | (Space >> const_value) | |
610 | If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | | 611 | If | Switch | With | ClassDecl | ForEach | For | While | Do | |
611 | (Space >> unary_value) | | 612 | (Space >> unary_value) | |
612 | TblComprehension | TableLit | Comprehension | FunLit | | 613 | TblComprehension | TableLit | Comprehension | FunLit | |
613 | (Space >> Num); | 614 | (Space >> Num); |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index b3c311a..2a3c1e4 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
@@ -228,8 +228,9 @@ private: | |||
228 | AST_RULE(SwitchCase) | 228 | AST_RULE(SwitchCase) |
229 | AST_RULE(Switch) | 229 | AST_RULE(Switch) |
230 | AST_RULE(IfCond) | 230 | AST_RULE(IfCond) |
231 | AST_RULE(IfType) | ||
231 | AST_RULE(If) | 232 | AST_RULE(If) |
232 | AST_RULE(Unless) | 233 | AST_RULE(WhileType) |
233 | AST_RULE(While) | 234 | AST_RULE(While) |
234 | AST_RULE(Repeat) | 235 | AST_RULE(Repeat) |
235 | AST_RULE(for_step_value) | 236 | AST_RULE(for_step_value) |