From 8e02ec2eefc700b0ef307f24596e7c36bdd84a4f Mon Sep 17 00:00:00 2001 From: Li Jin Date: Tue, 7 Sep 2021 10:28:44 +0800 Subject: small fixes. --- src/yuescript/yue_ast.h | 8 ++- src/yuescript/yue_compiler.cpp | 116 +++++++++++++++++++++++------------------ src/yuescript/yue_parser.cpp | 19 +++---- 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) class ExpListLow_t; class TableBlock_t; +class Attrib_t; AST_NODE(local_values) ast_ptr nameList; @@ -117,8 +118,11 @@ AST_END(Local) class Assign_t; +AST_LEAF(Attrib) +AST_END(Attrib) + AST_NODE(LocalAttrib) - ast_ptr attrib; + ast_ptr attrib; ast_ptr nameList; ast_ptr assign; AST_MEMBER(LocalAttrib, &attrib, &nameList, &assign) @@ -795,7 +799,7 @@ AST_NODE(BlockEnd) AST_END(BlockEnd) AST_NODE(File) - ast_ptr block; + ast_ptr block; AST_MEMBER(File, &block) AST_END(File) 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; typedef std::list str_list; -const std::string_view version = "0.8.2"sv; +const std::string_view version = "0.8.3"sv; const std::string_view extension = "yue"sv; class YueCompilerImpl { @@ -1079,7 +1079,7 @@ private: if (ind != std::string::npos) { ending = ending.substr(ind + 1); } - if (Keywords.find(ending) == Keywords.end()) { + if (LuaKeywords.find(ending) == LuaKeywords.end()) { out.back().insert(index, ";"sv); } } @@ -1213,7 +1213,15 @@ private: if (specialChainValue(chainValue) == ChainType::Metatable) { str_list args; chainValue->items.pop_back(); - transformExp(static_cast(*it), args, ExpUsage::Closure); + if (chainValue->items.empty()) { + if (_withVars.empty()) { + throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, x)); + } else { + args.push_back(_withVars.top()); + } + } else { + transformExp(static_cast(*it), args, ExpUsage::Closure); + } if (vit != values.end()) transformAssignItem(*vit, args); else args.push_back("nil"s); _buf << indent() << globalVar("setmetatable"sv, x) << '(' << join(args, ", "sv) << ')' << nll(x); @@ -1589,7 +1597,7 @@ private: case id(): { auto vp = static_cast(pair); auto name = _parser.toString(vp->name); - if (Keywords.find(name) != Keywords.end()) { + if (LuaKeywords.find(name) != LuaKeywords.end()) { pairs.push_back({true, name, "[\""s + name + "\"]"s, nullptr}); } else { pairs.push_back({true, name, '.' + name, nullptr}); @@ -1603,7 +1611,7 @@ private: auto key = np->key->getByPath(); if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, np)); keyName = _parser.toString(key); - if (Keywords.find(keyName) != Keywords.end()) { + if (LuaKeywords.find(keyName) != LuaKeywords.end()) { keyName = "[\""s + keyName + "\"]"s; } else { keyName = "."s + keyName; @@ -1711,7 +1719,7 @@ private: if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, dp)); keyName = _parser.toString(key); if (!dp->value) valueStr = keyName; - if (Keywords.find(keyName) != Keywords.end()) { + if (LuaKeywords.find(keyName) != LuaKeywords.end()) { keyName = "[\""s + keyName + "\"]"s; } else { keyName = "."s + keyName; @@ -1941,7 +1949,7 @@ private: auto& destruct = destructs.emplace_back(); if (!varDefOnly) { transformAssignItem(valueItems.back(), temp); - destruct.value = temp.back(); + destruct.value = std::move(temp.back()); temp.pop_back(); } auto simpleValue = tab->new_ptr(); @@ -2045,8 +2053,9 @@ private: break; } case id(): { - bool oneLined = true; auto assign = static_cast(action); + auto defs = transformAssignDefs(expList, DefOp::Check); + bool oneLined = defs.size() == expList->exprs.objects().size(); for (auto val : assign->values.objects()) { if (auto value = singleValueFrom(val)) { if (auto spValue = value->item.as()) { @@ -2057,8 +2066,7 @@ private: } } } - auto defs = transformAssignDefs(expList, DefOp::Check); - if (oneLined && defs.size() == expList->exprs.objects().size()) { + if (oneLined) { for (auto value : assign->values.objects()) { transformAssignItem(value, temp); } @@ -2080,7 +2088,7 @@ private: addToScope(def); } transformExpList(expList, temp); - std::string left = temp.back(); + std::string left = std::move(temp.back()); temp.pop_back(); for (auto value : assign->values.objects()) { transformAssignItem(value, temp); @@ -2455,12 +2463,12 @@ private: void transformFunLit(FunLit_t* funLit, str_list& out) { _enableReturn.push(true); _varArgs.push({false, false}); - str_list temp; bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; pushScope(); if (isFatArrow) { forceAddToScope("self"s); } + str_list temp; if (auto argsDef = funLit->argsDef.get()) { transformFnArgsDef(argsDef, temp); if (funLit->body) { @@ -2522,6 +2530,10 @@ private: } void transformBlock(Block_t* block, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr, bool isRoot = false) { + if (!block) { + out.push_back(Empty); + return; + } const auto& nodes = block->statements.objects(); LocalMode mode = LocalMode::None; Local_t* any = nullptr, *capital = nullptr; @@ -2641,7 +2653,7 @@ private: local->collected = true; switch (local->item->getId()) { case id(): { - auto flag = local->item.to(); + auto flag = static_cast(local->item.get()); LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; if (int(newMode) > int(mode)) { mode = newMode; @@ -2661,6 +2673,7 @@ private: } break; } + default: YUEE("AST node mismatch", local->item); break; } } } else if (mode != LocalMode::None) { @@ -4133,7 +4146,7 @@ private: void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) { auto name = _parser.toString(dotChainItem->name); - if (Keywords.find(name) != Keywords.end()) { + if (LuaKeywords.find(name) != LuaKeywords.end()) { out.push_back("[\""s + name + "\"]"s); } else { out.push_back('.' + name); @@ -4235,7 +4248,7 @@ private: statement->content.set(expListAssign); transformStatement(statement, temp); } - auto value = temp.back(); + auto value = std::move(temp.back()); temp.pop_back(); _buf << join(temp) << value; for (size_t i = 0; i < compInner->items.objects().size(); ++i) { @@ -4290,7 +4303,7 @@ private: assignment->action.set(assign); transformAssignment(assignment, temp); } - auto assignStr = temp.back(); + auto assignStr = std::move(temp.back()); temp.pop_back(); for (size_t i = 0; i < compInner->items.objects().size(); ++i) { popScope(); @@ -4393,19 +4406,19 @@ private: std::string startValue("1"sv); if (auto exp = slice->startValue.as()) { transformExp(exp, temp, ExpUsage::Closure); - startValue = temp.back(); + startValue = std::move(temp.back()); temp.pop_back(); } std::string stopValue; if (auto exp = slice->stopValue.as()) { transformExp(exp, temp, ExpUsage::Closure); - stopValue = temp.back(); + stopValue = std::move(temp.back()); temp.pop_back(); } std::string stepValue; if (auto exp = slice->stepValue.as()) { transformExp(exp, temp, ExpUsage::Closure); - stepValue = temp.back(); + stepValue = std::move(temp.back()); temp.pop_back(); } if (listVar.empty()) { @@ -4902,7 +4915,7 @@ private: } else if (auto index = ast_cast(chain->items.back())) { if (auto name = index->getByPath()) { transformString(name, temp); - className = temp.back(); + className = std::move(temp.back()); temp.pop_back(); } } @@ -4913,7 +4926,7 @@ private: pushScope(); transformAssignable(assignable, temp); popScope(); - assignItem = temp.back(); + assignItem = std::move(temp.back()); temp.pop_back(); } else if (expList) { auto name = singleVariableFrom(expList); @@ -4971,7 +4984,7 @@ private: parentVar = getUnusedName("_parent_"sv); addToScope(parentVar); transformExp(extend, temp, ExpUsage::Closure); - parent = temp.back(); + parent = std::move(temp.back()); temp.pop_back(); temp.push_back(indent() + "local "s + parentVar + " = "s + parent + nll(classDecl)); } @@ -5081,7 +5094,7 @@ private: pushScope(); auto selfVar = getUnusedName("_self_"sv); addToScope(selfVar); - _buf << indent(1) << "local "sv << selfVar << " = setmetatable({}, "sv << baseVar << ")"sv << nll(classDecl); + _buf << indent(1) << "local "sv << selfVar << " = setmetatable({ }, "sv << baseVar << ")"sv << nll(classDecl); _buf << indent(1) << "cls.__init("sv << selfVar << ", ...)"sv << nll(classDecl); _buf << indent(1) << "return "sv << selfVar << nll(classDecl); popScope(); @@ -6220,32 +6233,38 @@ private: local->defined = true; transformLocalDef(local, temp); } - if (auto values = local->item.as()) { - if (values->valueList) { - auto x = local; - auto expList = x->new_ptr(); - for (auto name : values->nameList->names.objects()) { - auto callable = x->new_ptr(); - callable->item.set(name); - auto chainValue = x->new_ptr(); - chainValue->items.push_back(callable); - auto value = x->new_ptr(); - value->item.set(chainValue); - auto exp = newExp(value, x); - expList->exprs.push_back(exp); - } - auto assignment = x->new_ptr(); - assignment->expList.set(expList); - auto assign = x->new_ptr(); - if (auto expListLow = values->valueList.as()) { - assign->values.dup(expListLow->exprs); - } else { - auto tableBlock = values->valueList.to(); - assign->values.push_back(tableBlock); + switch (local->item->getId()) { + case id(): { + auto values = static_cast(local->item.get()); + if (values->valueList) { + auto x = local; + auto expList = x->new_ptr(); + for (auto name : values->nameList->names.objects()) { + auto callable = x->new_ptr(); + callable->item.set(name); + auto chainValue = x->new_ptr(); + chainValue->items.push_back(callable); + auto value = x->new_ptr(); + value->item.set(chainValue); + auto exp = newExp(value, x); + expList->exprs.push_back(exp); + } + auto assignment = x->new_ptr(); + assignment->expList.set(expList); + auto assign = x->new_ptr(); + if (auto expListLow = values->valueList.as()) { + assign->values.dup(expListLow->exprs); + } else { + auto tableBlock = values->valueList.to(); + assign->values.push_back(tableBlock); + } + assignment->action.set(assign); + transformAssignment(assignment, temp); } - assignment->action.set(assign); - transformAssignment(assignment, temp); + break; } + case id(): break; + default: YUEE("AST node mismatch", local->item); break; } out.push_back(join(temp)); } @@ -6253,9 +6272,6 @@ private: void transformLocalAttrib(LocalAttrib_t* localAttrib, str_list& out) { auto x = localAttrib; auto attrib = _parser.toString(localAttrib->attrib); - if (attrib != "close"sv && attrib != "const"sv) { - throw std::logic_error(_info.errorMessage("unknown attribute '"s + attrib + '\'', localAttrib->attrib)); - } str_list vars; for (auto name : localAttrib->nameList->names.objects()) { 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 Keywords = { "or", "repeat", "return", "then", "true", "until", "while", // Lua keywords "as", "class", "continue", "export", "extends", - "from", "global", "import", "macro", "switch", - "unless", "using", "when", "with" // Yue keywords + "from", "global", "import", "is", "macro", + "switch", "unless", "using", "when", "with" // Yue keywords }; YueParser::YueParser() { @@ -179,15 +179,10 @@ YueParser::YueParser() { local_flag = expr('*') | expr('^'); local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); + Attrib = (expr("const") | expr("close")) >> not_(AlphaNum); Local = key("local") >> (Space >> local_flag | local_values); - LocalAttrib = and_(key(pl::user(Name, [](const item_t& item) { - State* st = reinterpret_cast(item.user_data); - for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast(*it); - auto it = Keywords.find(st->buffer); - st->buffer.clear(); - return it == Keywords.end(); - })) >> NameList >> sym('=') >> not_('=')) >> Space >> Name >> NameList >> Assign; + LocalAttrib = Space >> Attrib >> NameList >> Assign; colon_import_name = sym('\\') >> Space >> Variable; ImportName = colon_import_name | Space >> Variable; @@ -626,8 +621,8 @@ YueParser::YueParser() { Statement = ( Import | While | Repeat | For | ForEach | Return | Local | Global | Export | Macro | - Space >> BreakLoop | Label | Goto | Backcall | - LocalAttrib | PipeBody | ExpListAssign + Space >> BreakLoop | Label | Goto | LocalAttrib | + Backcall | PipeBody | ExpListAssign ) >> Space >> -statement_appendix >> -statement_sep; @@ -639,7 +634,7 @@ YueParser::YueParser() { Shebang = expr("#!") >> *(not_(Stop) >> Any); BlockEnd = Block >> -(+Break >> Space >> and_(Stop)) >> Stop; - File = White >> -Shebang >> Block >> -(+Break >> Space >> and_(eof())) >> eof(); + File = White >> -Shebang >> -Block >> White >> eof(); } 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: AST_RULE(NameList) AST_RULE(local_flag) AST_RULE(local_values) + AST_RULE(Attrib) AST_RULE(Local) AST_RULE(LocalAttrib); AST_RULE(colon_import_name) -- cgit v1.2.3-55-g6feb