aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/yuescript/yue_ast.h8
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp116
-rwxr-xr-xsrc/yuescript/yue_parser.cpp19
-rwxr-xr-xsrc/yuescript/yue_parser.h1
4 files changed, 80 insertions, 64 deletions
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index 3efc0dc..6c9953c 100755
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -99,6 +99,7 @@ AST_END(NameList)
99 99
100class ExpListLow_t; 100class ExpListLow_t;
101class TableBlock_t; 101class TableBlock_t;
102class Attrib_t;
102 103
103AST_NODE(local_values) 104AST_NODE(local_values)
104 ast_ptr<true, NameList_t> nameList; 105 ast_ptr<true, NameList_t> nameList;
@@ -117,8 +118,11 @@ AST_END(Local)
117 118
118class Assign_t; 119class Assign_t;
119 120
121AST_LEAF(Attrib)
122AST_END(Attrib)
123
120AST_NODE(LocalAttrib) 124AST_NODE(LocalAttrib)
121 ast_ptr<true, Name_t> attrib; 125 ast_ptr<true, Attrib_t> attrib;
122 ast_ptr<true, NameList_t> nameList; 126 ast_ptr<true, NameList_t> nameList;
123 ast_ptr<true, Assign_t> assign; 127 ast_ptr<true, Assign_t> assign;
124 AST_MEMBER(LocalAttrib, &attrib, &nameList, &assign) 128 AST_MEMBER(LocalAttrib, &attrib, &nameList, &assign)
@@ -795,7 +799,7 @@ AST_NODE(BlockEnd)
795AST_END(BlockEnd) 799AST_END(BlockEnd)
796 800
797AST_NODE(File) 801AST_NODE(File)
798 ast_ptr<true, Block_t> block; 802 ast_ptr<false, Block_t> block;
799 AST_MEMBER(File, &block) 803 AST_MEMBER(File, &block)
800AST_END(File) 804AST_END(File)
801 805
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index e812960..71efa3c 100755
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -60,7 +60,7 @@ using namespace parserlib;
60 60
61typedef std::list<std::string> str_list; 61typedef std::list<std::string> str_list;
62 62
63const std::string_view version = "0.8.2"sv; 63const std::string_view version = "0.8.3"sv;
64const std::string_view extension = "yue"sv; 64const std::string_view extension = "yue"sv;
65 65
66class YueCompilerImpl { 66class YueCompilerImpl {
@@ -1079,7 +1079,7 @@ private:
1079 if (ind != std::string::npos) { 1079 if (ind != std::string::npos) {
1080 ending = ending.substr(ind + 1); 1080 ending = ending.substr(ind + 1);
1081 } 1081 }
1082 if (Keywords.find(ending) == Keywords.end()) { 1082 if (LuaKeywords.find(ending) == LuaKeywords.end()) {
1083 out.back().insert(index, ";"sv); 1083 out.back().insert(index, ";"sv);
1084 } 1084 }
1085 } 1085 }
@@ -1213,7 +1213,15 @@ private:
1213 if (specialChainValue(chainValue) == ChainType::Metatable) { 1213 if (specialChainValue(chainValue) == ChainType::Metatable) {
1214 str_list args; 1214 str_list args;
1215 chainValue->items.pop_back(); 1215 chainValue->items.pop_back();
1216 transformExp(static_cast<Exp_t*>(*it), args, ExpUsage::Closure); 1216 if (chainValue->items.empty()) {
1217 if (_withVars.empty()) {
1218 throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, x));
1219 } else {
1220 args.push_back(_withVars.top());
1221 }
1222 } else {
1223 transformExp(static_cast<Exp_t*>(*it), args, ExpUsage::Closure);
1224 }
1217 if (vit != values.end()) transformAssignItem(*vit, args); 1225 if (vit != values.end()) transformAssignItem(*vit, args);
1218 else args.push_back("nil"s); 1226 else args.push_back("nil"s);
1219 _buf << indent() << globalVar("setmetatable"sv, x) << '(' << join(args, ", "sv) << ')' << nll(x); 1227 _buf << indent() << globalVar("setmetatable"sv, x) << '(' << join(args, ", "sv) << ')' << nll(x);
@@ -1589,7 +1597,7 @@ private:
1589 case id<variable_pair_t>(): { 1597 case id<variable_pair_t>(): {
1590 auto vp = static_cast<variable_pair_t*>(pair); 1598 auto vp = static_cast<variable_pair_t*>(pair);
1591 auto name = _parser.toString(vp->name); 1599 auto name = _parser.toString(vp->name);
1592 if (Keywords.find(name) != Keywords.end()) { 1600 if (LuaKeywords.find(name) != LuaKeywords.end()) {
1593 pairs.push_back({true, name, "[\""s + name + "\"]"s, nullptr}); 1601 pairs.push_back({true, name, "[\""s + name + "\"]"s, nullptr});
1594 } else { 1602 } else {
1595 pairs.push_back({true, name, '.' + name, nullptr}); 1603 pairs.push_back({true, name, '.' + name, nullptr});
@@ -1603,7 +1611,7 @@ private:
1603 auto key = np->key->getByPath<Name_t>(); 1611 auto key = np->key->getByPath<Name_t>();
1604 if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, np)); 1612 if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, np));
1605 keyName = _parser.toString(key); 1613 keyName = _parser.toString(key);
1606 if (Keywords.find(keyName) != Keywords.end()) { 1614 if (LuaKeywords.find(keyName) != LuaKeywords.end()) {
1607 keyName = "[\""s + keyName + "\"]"s; 1615 keyName = "[\""s + keyName + "\"]"s;
1608 } else { 1616 } else {
1609 keyName = "."s + keyName; 1617 keyName = "."s + keyName;
@@ -1711,7 +1719,7 @@ private:
1711 if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, dp)); 1719 if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, dp));
1712 keyName = _parser.toString(key); 1720 keyName = _parser.toString(key);
1713 if (!dp->value) valueStr = keyName; 1721 if (!dp->value) valueStr = keyName;
1714 if (Keywords.find(keyName) != Keywords.end()) { 1722 if (LuaKeywords.find(keyName) != LuaKeywords.end()) {
1715 keyName = "[\""s + keyName + "\"]"s; 1723 keyName = "[\""s + keyName + "\"]"s;
1716 } else { 1724 } else {
1717 keyName = "."s + keyName; 1725 keyName = "."s + keyName;
@@ -1941,7 +1949,7 @@ private:
1941 auto& destruct = destructs.emplace_back(); 1949 auto& destruct = destructs.emplace_back();
1942 if (!varDefOnly) { 1950 if (!varDefOnly) {
1943 transformAssignItem(valueItems.back(), temp); 1951 transformAssignItem(valueItems.back(), temp);
1944 destruct.value = temp.back(); 1952 destruct.value = std::move(temp.back());
1945 temp.pop_back(); 1953 temp.pop_back();
1946 } 1954 }
1947 auto simpleValue = tab->new_ptr<SimpleValue_t>(); 1955 auto simpleValue = tab->new_ptr<SimpleValue_t>();
@@ -2045,8 +2053,9 @@ private:
2045 break; 2053 break;
2046 } 2054 }
2047 case id<Assign_t>(): { 2055 case id<Assign_t>(): {
2048 bool oneLined = true;
2049 auto assign = static_cast<Assign_t*>(action); 2056 auto assign = static_cast<Assign_t*>(action);
2057 auto defs = transformAssignDefs(expList, DefOp::Check);
2058 bool oneLined = defs.size() == expList->exprs.objects().size();
2050 for (auto val : assign->values.objects()) { 2059 for (auto val : assign->values.objects()) {
2051 if (auto value = singleValueFrom(val)) { 2060 if (auto value = singleValueFrom(val)) {
2052 if (auto spValue = value->item.as<SimpleValue_t>()) { 2061 if (auto spValue = value->item.as<SimpleValue_t>()) {
@@ -2057,8 +2066,7 @@ private:
2057 } 2066 }
2058 } 2067 }
2059 } 2068 }
2060 auto defs = transformAssignDefs(expList, DefOp::Check); 2069 if (oneLined) {
2061 if (oneLined && defs.size() == expList->exprs.objects().size()) {
2062 for (auto value : assign->values.objects()) { 2070 for (auto value : assign->values.objects()) {
2063 transformAssignItem(value, temp); 2071 transformAssignItem(value, temp);
2064 } 2072 }
@@ -2080,7 +2088,7 @@ private:
2080 addToScope(def); 2088 addToScope(def);
2081 } 2089 }
2082 transformExpList(expList, temp); 2090 transformExpList(expList, temp);
2083 std::string left = temp.back(); 2091 std::string left = std::move(temp.back());
2084 temp.pop_back(); 2092 temp.pop_back();
2085 for (auto value : assign->values.objects()) { 2093 for (auto value : assign->values.objects()) {
2086 transformAssignItem(value, temp); 2094 transformAssignItem(value, temp);
@@ -2455,12 +2463,12 @@ private:
2455 void transformFunLit(FunLit_t* funLit, str_list& out) { 2463 void transformFunLit(FunLit_t* funLit, str_list& out) {
2456 _enableReturn.push(true); 2464 _enableReturn.push(true);
2457 _varArgs.push({false, false}); 2465 _varArgs.push({false, false});
2458 str_list temp;
2459 bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; 2466 bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv;
2460 pushScope(); 2467 pushScope();
2461 if (isFatArrow) { 2468 if (isFatArrow) {
2462 forceAddToScope("self"s); 2469 forceAddToScope("self"s);
2463 } 2470 }
2471 str_list temp;
2464 if (auto argsDef = funLit->argsDef.get()) { 2472 if (auto argsDef = funLit->argsDef.get()) {
2465 transformFnArgsDef(argsDef, temp); 2473 transformFnArgsDef(argsDef, temp);
2466 if (funLit->body) { 2474 if (funLit->body) {
@@ -2522,6 +2530,10 @@ private:
2522 } 2530 }
2523 2531
2524 void transformBlock(Block_t* block, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr, bool isRoot = false) { 2532 void transformBlock(Block_t* block, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr, bool isRoot = false) {
2533 if (!block) {
2534 out.push_back(Empty);
2535 return;
2536 }
2525 const auto& nodes = block->statements.objects(); 2537 const auto& nodes = block->statements.objects();
2526 LocalMode mode = LocalMode::None; 2538 LocalMode mode = LocalMode::None;
2527 Local_t* any = nullptr, *capital = nullptr; 2539 Local_t* any = nullptr, *capital = nullptr;
@@ -2641,7 +2653,7 @@ private:
2641 local->collected = true; 2653 local->collected = true;
2642 switch (local->item->getId()) { 2654 switch (local->item->getId()) {
2643 case id<local_flag_t>(): { 2655 case id<local_flag_t>(): {
2644 auto flag = local->item.to<local_flag_t>(); 2656 auto flag = static_cast<local_flag_t*>(local->item.get());
2645 LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; 2657 LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital;
2646 if (int(newMode) > int(mode)) { 2658 if (int(newMode) > int(mode)) {
2647 mode = newMode; 2659 mode = newMode;
@@ -2661,6 +2673,7 @@ private:
2661 } 2673 }
2662 break; 2674 break;
2663 } 2675 }
2676 default: YUEE("AST node mismatch", local->item); break;
2664 } 2677 }
2665 } 2678 }
2666 } else if (mode != LocalMode::None) { 2679 } else if (mode != LocalMode::None) {
@@ -4133,7 +4146,7 @@ private:
4133 4146
4134 void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) { 4147 void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) {
4135 auto name = _parser.toString(dotChainItem->name); 4148 auto name = _parser.toString(dotChainItem->name);
4136 if (Keywords.find(name) != Keywords.end()) { 4149 if (LuaKeywords.find(name) != LuaKeywords.end()) {
4137 out.push_back("[\""s + name + "\"]"s); 4150 out.push_back("[\""s + name + "\"]"s);
4138 } else { 4151 } else {
4139 out.push_back('.' + name); 4152 out.push_back('.' + name);
@@ -4235,7 +4248,7 @@ private:
4235 statement->content.set(expListAssign); 4248 statement->content.set(expListAssign);
4236 transformStatement(statement, temp); 4249 transformStatement(statement, temp);
4237 } 4250 }
4238 auto value = temp.back(); 4251 auto value = std::move(temp.back());
4239 temp.pop_back(); 4252 temp.pop_back();
4240 _buf << join(temp) << value; 4253 _buf << join(temp) << value;
4241 for (size_t i = 0; i < compInner->items.objects().size(); ++i) { 4254 for (size_t i = 0; i < compInner->items.objects().size(); ++i) {
@@ -4290,7 +4303,7 @@ private:
4290 assignment->action.set(assign); 4303 assignment->action.set(assign);
4291 transformAssignment(assignment, temp); 4304 transformAssignment(assignment, temp);
4292 } 4305 }
4293 auto assignStr = temp.back(); 4306 auto assignStr = std::move(temp.back());
4294 temp.pop_back(); 4307 temp.pop_back();
4295 for (size_t i = 0; i < compInner->items.objects().size(); ++i) { 4308 for (size_t i = 0; i < compInner->items.objects().size(); ++i) {
4296 popScope(); 4309 popScope();
@@ -4393,19 +4406,19 @@ private:
4393 std::string startValue("1"sv); 4406 std::string startValue("1"sv);
4394 if (auto exp = slice->startValue.as<Exp_t>()) { 4407 if (auto exp = slice->startValue.as<Exp_t>()) {
4395 transformExp(exp, temp, ExpUsage::Closure); 4408 transformExp(exp, temp, ExpUsage::Closure);
4396 startValue = temp.back(); 4409 startValue = std::move(temp.back());
4397 temp.pop_back(); 4410 temp.pop_back();
4398 } 4411 }
4399 std::string stopValue; 4412 std::string stopValue;
4400 if (auto exp = slice->stopValue.as<Exp_t>()) { 4413 if (auto exp = slice->stopValue.as<Exp_t>()) {
4401 transformExp(exp, temp, ExpUsage::Closure); 4414 transformExp(exp, temp, ExpUsage::Closure);
4402 stopValue = temp.back(); 4415 stopValue = std::move(temp.back());
4403 temp.pop_back(); 4416 temp.pop_back();
4404 } 4417 }
4405 std::string stepValue; 4418 std::string stepValue;
4406 if (auto exp = slice->stepValue.as<Exp_t>()) { 4419 if (auto exp = slice->stepValue.as<Exp_t>()) {
4407 transformExp(exp, temp, ExpUsage::Closure); 4420 transformExp(exp, temp, ExpUsage::Closure);
4408 stepValue = temp.back(); 4421 stepValue = std::move(temp.back());
4409 temp.pop_back(); 4422 temp.pop_back();
4410 } 4423 }
4411 if (listVar.empty()) { 4424 if (listVar.empty()) {
@@ -4902,7 +4915,7 @@ private:
4902 } else if (auto index = ast_cast<Exp_t>(chain->items.back())) { 4915 } else if (auto index = ast_cast<Exp_t>(chain->items.back())) {
4903 if (auto name = index->getByPath<unary_exp_t, Value_t, String_t>()) { 4916 if (auto name = index->getByPath<unary_exp_t, Value_t, String_t>()) {
4904 transformString(name, temp); 4917 transformString(name, temp);
4905 className = temp.back(); 4918 className = std::move(temp.back());
4906 temp.pop_back(); 4919 temp.pop_back();
4907 } 4920 }
4908 } 4921 }
@@ -4913,7 +4926,7 @@ private:
4913 pushScope(); 4926 pushScope();
4914 transformAssignable(assignable, temp); 4927 transformAssignable(assignable, temp);
4915 popScope(); 4928 popScope();
4916 assignItem = temp.back(); 4929 assignItem = std::move(temp.back());
4917 temp.pop_back(); 4930 temp.pop_back();
4918 } else if (expList) { 4931 } else if (expList) {
4919 auto name = singleVariableFrom(expList); 4932 auto name = singleVariableFrom(expList);
@@ -4971,7 +4984,7 @@ private:
4971 parentVar = getUnusedName("_parent_"sv); 4984 parentVar = getUnusedName("_parent_"sv);
4972 addToScope(parentVar); 4985 addToScope(parentVar);
4973 transformExp(extend, temp, ExpUsage::Closure); 4986 transformExp(extend, temp, ExpUsage::Closure);
4974 parent = temp.back(); 4987 parent = std::move(temp.back());
4975 temp.pop_back(); 4988 temp.pop_back();
4976 temp.push_back(indent() + "local "s + parentVar + " = "s + parent + nll(classDecl)); 4989 temp.push_back(indent() + "local "s + parentVar + " = "s + parent + nll(classDecl));
4977 } 4990 }
@@ -5081,7 +5094,7 @@ private:
5081 pushScope(); 5094 pushScope();
5082 auto selfVar = getUnusedName("_self_"sv); 5095 auto selfVar = getUnusedName("_self_"sv);
5083 addToScope(selfVar); 5096 addToScope(selfVar);
5084 _buf << indent(1) << "local "sv << selfVar << " = setmetatable({}, "sv << baseVar << ")"sv << nll(classDecl); 5097 _buf << indent(1) << "local "sv << selfVar << " = setmetatable({ }, "sv << baseVar << ")"sv << nll(classDecl);
5085 _buf << indent(1) << "cls.__init("sv << selfVar << ", ...)"sv << nll(classDecl); 5098 _buf << indent(1) << "cls.__init("sv << selfVar << ", ...)"sv << nll(classDecl);
5086 _buf << indent(1) << "return "sv << selfVar << nll(classDecl); 5099 _buf << indent(1) << "return "sv << selfVar << nll(classDecl);
5087 popScope(); 5100 popScope();
@@ -6220,32 +6233,38 @@ private:
6220 local->defined = true; 6233 local->defined = true;
6221 transformLocalDef(local, temp); 6234 transformLocalDef(local, temp);
6222 } 6235 }
6223 if (auto values = local->item.as<local_values_t>()) { 6236 switch (local->item->getId()) {
6224 if (values->valueList) { 6237 case id<local_values_t>(): {
6225 auto x = local; 6238 auto values = static_cast<local_values_t*>(local->item.get());
6226 auto expList = x->new_ptr<ExpList_t>(); 6239 if (values->valueList) {
6227 for (auto name : values->nameList->names.objects()) { 6240 auto x = local;
6228 auto callable = x->new_ptr<Callable_t>(); 6241 auto expList = x->new_ptr<ExpList_t>();
6229 callable->item.set(name); 6242 for (auto name : values->nameList->names.objects()) {
6230 auto chainValue = x->new_ptr<ChainValue_t>(); 6243 auto callable = x->new_ptr<Callable_t>();
6231 chainValue->items.push_back(callable); 6244 callable->item.set(name);
6232 auto value = x->new_ptr<Value_t>(); 6245 auto chainValue = x->new_ptr<ChainValue_t>();
6233 value->item.set(chainValue); 6246 chainValue->items.push_back(callable);
6234 auto exp = newExp(value, x); 6247 auto value = x->new_ptr<Value_t>();
6235 expList->exprs.push_back(exp); 6248 value->item.set(chainValue);
6236 } 6249 auto exp = newExp(value, x);
6237 auto assignment = x->new_ptr<ExpListAssign_t>(); 6250 expList->exprs.push_back(exp);
6238 assignment->expList.set(expList); 6251 }
6239 auto assign = x->new_ptr<Assign_t>(); 6252 auto assignment = x->new_ptr<ExpListAssign_t>();
6240 if (auto expListLow = values->valueList.as<ExpListLow_t>()) { 6253 assignment->expList.set(expList);
6241 assign->values.dup(expListLow->exprs); 6254 auto assign = x->new_ptr<Assign_t>();
6242 } else { 6255 if (auto expListLow = values->valueList.as<ExpListLow_t>()) {
6243 auto tableBlock = values->valueList.to<TableBlock_t>(); 6256 assign->values.dup(expListLow->exprs);
6244 assign->values.push_back(tableBlock); 6257 } else {
6258 auto tableBlock = values->valueList.to<TableBlock_t>();
6259 assign->values.push_back(tableBlock);
6260 }
6261 assignment->action.set(assign);
6262 transformAssignment(assignment, temp);
6245 } 6263 }
6246 assignment->action.set(assign); 6264 break;
6247 transformAssignment(assignment, temp);
6248 } 6265 }
6266 case id<local_flag_t>(): break;
6267 default: YUEE("AST node mismatch", local->item); break;
6249 } 6268 }
6250 out.push_back(join(temp)); 6269 out.push_back(join(temp));
6251 } 6270 }
@@ -6253,9 +6272,6 @@ private:
6253 void transformLocalAttrib(LocalAttrib_t* localAttrib, str_list& out) { 6272 void transformLocalAttrib(LocalAttrib_t* localAttrib, str_list& out) {
6254 auto x = localAttrib; 6273 auto x = localAttrib;
6255 auto attrib = _parser.toString(localAttrib->attrib); 6274 auto attrib = _parser.toString(localAttrib->attrib);
6256 if (attrib != "close"sv && attrib != "const"sv) {
6257 throw std::logic_error(_info.errorMessage("unknown attribute '"s + attrib + '\'', localAttrib->attrib));
6258 }
6259 str_list vars; 6275 str_list vars;
6260 for (auto name : localAttrib->nameList->names.objects()) { 6276 for (auto name : localAttrib->nameList->names.objects()) {
6261 auto var = _parser.toString(name); 6277 auto var = _parser.toString(name);
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index d6e8c67..0b7f79e 100755
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -28,8 +28,8 @@ std::unordered_set<std::string> Keywords = {
28 "or", "repeat", "return", "then", "true", 28 "or", "repeat", "return", "then", "true",
29 "until", "while", // Lua keywords 29 "until", "while", // Lua keywords
30 "as", "class", "continue", "export", "extends", 30 "as", "class", "continue", "export", "extends",
31 "from", "global", "import", "macro", "switch", 31 "from", "global", "import", "is", "macro",
32 "unless", "using", "when", "with" // Yue keywords 32 "switch", "unless", "using", "when", "with" // Yue keywords
33}; 33};
34 34
35YueParser::YueParser() { 35YueParser::YueParser() {
@@ -179,15 +179,10 @@ YueParser::YueParser() {
179 179
180 local_flag = expr('*') | expr('^'); 180 local_flag = expr('*') | expr('^');
181 local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); 181 local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow));
182 Attrib = (expr("const") | expr("close")) >> not_(AlphaNum);
182 Local = key("local") >> (Space >> local_flag | local_values); 183 Local = key("local") >> (Space >> local_flag | local_values);
183 184
184 LocalAttrib = and_(key(pl::user(Name, [](const item_t& item) { 185 LocalAttrib = Space >> Attrib >> NameList >> Assign;
185 State* st = reinterpret_cast<State*>(item.user_data);
186 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it);
187 auto it = Keywords.find(st->buffer);
188 st->buffer.clear();
189 return it == Keywords.end();
190 })) >> NameList >> sym('=') >> not_('=')) >> Space >> Name >> NameList >> Assign;
191 186
192 colon_import_name = sym('\\') >> Space >> Variable; 187 colon_import_name = sym('\\') >> Space >> Variable;
193 ImportName = colon_import_name | Space >> Variable; 188 ImportName = colon_import_name | Space >> Variable;
@@ -626,8 +621,8 @@ YueParser::YueParser() {
626 Statement = ( 621 Statement = (
627 Import | While | Repeat | For | ForEach | 622 Import | While | Repeat | For | ForEach |
628 Return | Local | Global | Export | Macro | 623 Return | Local | Global | Export | Macro |
629 Space >> BreakLoop | Label | Goto | Backcall | 624 Space >> BreakLoop | Label | Goto | LocalAttrib |
630 LocalAttrib | PipeBody | ExpListAssign 625 Backcall | PipeBody | ExpListAssign
631 ) >> Space >> 626 ) >> Space >>
632 -statement_appendix >> -statement_sep; 627 -statement_appendix >> -statement_sep;
633 628
@@ -639,7 +634,7 @@ YueParser::YueParser() {
639 634
640 Shebang = expr("#!") >> *(not_(Stop) >> Any); 635 Shebang = expr("#!") >> *(not_(Stop) >> Any);
641 BlockEnd = Block >> -(+Break >> Space >> and_(Stop)) >> Stop; 636 BlockEnd = Block >> -(+Break >> Space >> and_(Stop)) >> Stop;
642 File = White >> -Shebang >> Block >> -(+Break >> Space >> and_(eof())) >> eof(); 637 File = White >> -Shebang >> -Block >> White >> eof();
643} 638}
644 639
645ParseInfo YueParser::parse(std::string_view codes, rule& r) { 640ParseInfo YueParser::parse(std::string_view codes, rule& r) {
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index c80e622..22527d9 100755
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -205,6 +205,7 @@ private:
205 AST_RULE(NameList) 205 AST_RULE(NameList)
206 AST_RULE(local_flag) 206 AST_RULE(local_flag)
207 AST_RULE(local_values) 207 AST_RULE(local_values)
208 AST_RULE(Attrib)
208 AST_RULE(Local) 209 AST_RULE(Local)
209 AST_RULE(LocalAttrib); 210 AST_RULE(LocalAttrib);
210 AST_RULE(colon_import_name) 211 AST_RULE(colon_import_name)