diff options
-rwxr-xr-x | src/yuescript/yue_ast.h | 8 | ||||
-rwxr-xr-x | src/yuescript/yue_compiler.cpp | 116 | ||||
-rwxr-xr-x | src/yuescript/yue_parser.cpp | 19 | ||||
-rwxr-xr-x | src/yuescript/yue_parser.h | 1 |
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 | ||
100 | class ExpListLow_t; | 100 | class ExpListLow_t; |
101 | class TableBlock_t; | 101 | class TableBlock_t; |
102 | class Attrib_t; | ||
102 | 103 | ||
103 | AST_NODE(local_values) | 104 | AST_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 | ||
118 | class Assign_t; | 119 | class Assign_t; |
119 | 120 | ||
121 | AST_LEAF(Attrib) | ||
122 | AST_END(Attrib) | ||
123 | |||
120 | AST_NODE(LocalAttrib) | 124 | AST_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) | |||
795 | AST_END(BlockEnd) | 799 | AST_END(BlockEnd) |
796 | 800 | ||
797 | AST_NODE(File) | 801 | AST_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) |
800 | AST_END(File) | 804 | AST_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 | ||
61 | typedef std::list<std::string> str_list; | 61 | typedef std::list<std::string> str_list; |
62 | 62 | ||
63 | const std::string_view version = "0.8.2"sv; | 63 | const std::string_view version = "0.8.3"sv; |
64 | const std::string_view extension = "yue"sv; | 64 | const std::string_view extension = "yue"sv; |
65 | 65 | ||
66 | class YueCompilerImpl { | 66 | class 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 | ||
35 | YueParser::YueParser() { | 35 | YueParser::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 | ||
645 | ParseInfo YueParser::parse(std::string_view codes, rule& r) { | 640 | ParseInfo 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) |