diff options
Diffstat (limited to 'src')
| -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) |
