summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2021-05-13 10:38:31 +0800
committerLi Jin <dragon-fly@qq.com>2021-05-13 10:38:31 +0800
commit4d61a00ebc5b956da72525de0e180de28a1e8ac6 (patch)
tree02c6967a1966078563f5fcfdca8cdcc1b58e9864
parent4c9209b131936ad97c73a7c0e71042fe24369a8e (diff)
downloadyuescript-4d61a00ebc5b956da72525de0e180de28a1e8ac6.tar.gz
yuescript-4d61a00ebc5b956da72525de0e180de28a1e8ac6.tar.bz2
yuescript-4d61a00ebc5b956da72525de0e180de28a1e8ac6.zip
fix issue #52, add until statement.
-rw-r--r--spec/inputs/loops.yue16
-rw-r--r--src/yuescript/yue_ast.h19
-rw-r--r--src/yuescript/yue_compiler.cpp88
-rw-r--r--src/yuescript/yue_parser.cpp9
-rw-r--r--src/yuescript/yue_parser.h3
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
110until a == 10 110until a == 10
111 111
112a = 3
113until a == 0
114 a -= 1
115done = false
116until done do done = true
117repeat
118 print "hello"
119until true
120until done
121 x = 10
122 repeat
123 x -= 1
124 until x == 0
125until cond
126 print "okay"
127
112for x=1,10 128for 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)
257AST_END(IfCond) 257AST_END(IfCond)
258 258
259AST_LEAF(IfType)
260AST_END(IfType)
261
259AST_NODE(If) 262AST_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)
263AST_END(If) 266AST_END(If)
264 267
265AST_NODE(Unless) 268AST_LEAF(WhileType)
266 ast_ptr<true, Seperator_t> sep; 269AST_END(WhileType)
267 ast_sel_list<true, IfCond_t, Block_t, Statement_t> nodes;
268 AST_MEMBER(Unless, &sep, &nodes)
269AST_END(Unless)
270 270
271AST_NODE(While) 271AST_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)
275AST_END(While) 276AST_END(While)
276 277
277class Body_t; 278class Body_t;
@@ -451,7 +452,7 @@ class FunLit_t;
451 452
452AST_NODE(SimpleValue) 453AST_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
62const std::string_view version = "0.7.13"sv; 62const std::string_view version = "0.7.14"sv;
63const std::string_view extension = "yue"sv; 63const std::string_view extension = "yue"sv;
64 64
65class YueCompilerImpl { 65class 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)