From 055fcb596781a8488afeb0030e9ef4295e3d7017 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Sun, 6 Oct 2019 17:30:11 +0800 Subject: updating --- MoonParser/ast.hpp | 16 ++ MoonParser/moon_ast.cpp | 491 +++++++++++++++++++-------------------------- MoonParser/moon_ast.h | 42 ++-- MoonParser/moon_parser.cpp | 47 +++-- MoonParser/moon_parser.h | 4 +- 5 files changed, 273 insertions(+), 327 deletions(-) diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp index 480f9b3..8d28177 100644 --- a/MoonParser/ast.hpp +++ b/MoonParser/ast.hpp @@ -388,6 +388,22 @@ public: clear(); } + inline ast_node* back() const { + return m_objects.back(); + } + + inline ast_node* front() const { + return m_objects.front(); + } + + inline size_t size() const { + return m_objects.size(); + } + + inline bool empty() const { + return m_objects.empty(); + } + void push_back(ast_node* node) { assert(node && accept(node)); m_objects.push_back(node); diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index 61b997b..52fbd68 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp @@ -65,14 +65,17 @@ AST_IMPL(update_op) AST_IMPL(Update) AST_IMPL(BinaryOperator) AST_IMPL(Assignable) +AST_IMPL(AssignableChain) AST_IMPL(exp_op_value) AST_IMPL(Exp) AST_IMPL(Callable) AST_IMPL(ChainValue) AST_IMPL(simple_table) AST_IMPL(SimpleValue) -AST_IMPL(Chain) AST_IMPL(Value) +AST_IMPL(LuaStringOpen); +AST_IMPL(LuaStringContent); +AST_IMPL(LuaStringClose); AST_IMPL(LuaString) AST_IMPL(SingleString) AST_IMPL(double_string_inner) @@ -114,7 +117,7 @@ AST_IMPL(BreakLoop) AST_IMPL(Statement) AST_IMPL(Body) AST_IMPL(Block) -AST_IMPL(BlockEnd) +AST_IMPL(File) #include @@ -129,7 +132,7 @@ public: input input = _converter.from_bytes(codes); error_list el; State st; - auto root = parse(input, BlockEnd, el, &st); + auto root = parse(input, File, el, &st); if (root) { std::cout << "compiled!\n\n"; str_list out; @@ -460,20 +463,15 @@ private: } bool isChainValueCall(ChainValue_t* chainValue) { - if (chainValue->arguments) return true; - if (auto chain = chainValue->caller.as()) { - ast_node* last = chain->items.objects().back(); - return last->getId() == "Invoke"_id; - } - return false; + return ast_is(chainValue->items.back()); } std::string variableFrom(ast_node* expList) { if (!ast_is(expList)) return Empty; if (auto value = singleValueFrom(expList)) { if (auto chainValue = value->getByPath()) { - if (!chainValue->arguments) { - if (auto callable = chainValue->caller.as()) { + if (chainValue->items.size() == 1) { + if (auto callable = ast_cast(chainValue->items.front())) { return toString(callable->item); } } @@ -483,29 +481,7 @@ private: } bool isColonChain(ChainValue_t* chainValue) { - if (chainValue->arguments) return false; - if (auto chain = chainValue->caller.as()) { - return chain->items.objects().back()->getId() == "ColonChainItem"_id; - } - return false; - } - - std::vector getChainList(ChainValue_t* chainValue) { - std::vector temp; - switch (chainValue->caller->getId()) { - case "Callable"_id: - temp.push_back(chainValue->caller); - break; - case "Chain"_id: - const auto& items = chainValue->caller.to()->items.objects(); - temp.resize(items.size()); - std::copy(items.begin(), items.end(), temp.begin()); - break; - } - if (chainValue->arguments) { - temp.push_back(chainValue->arguments); - } - return temp; + return ast_is(chainValue->items.back()); } void transformStatement(Statement_t* statement, str_list& out) { @@ -524,6 +500,12 @@ private: ifCond->condition.set(if_else_line->condition); ifNode->nodes.push_back(ifCond); + auto stmt = new_ptr(); + stmt->content.set(statement->content); + auto body = new_ptr(); + body->content.set(stmt); + ifNode->nodes.push_back(body); + if (!ast_is(if_else_line->elseExpr)) { auto exprList = new_ptr(); exprList->exprs.push_back(if_else_line->elseExpr); @@ -533,11 +515,6 @@ private: body->content.set(stmt); ifNode->nodes.push_back(body); } - auto stmt = new_ptr(); - stmt->content.set(statement->content); - auto body = new_ptr(); - body->content.set(stmt); - ifNode->nodes.push_back(body); statement->appendix.set(nullptr); auto simpleValue = new_ptr(); @@ -795,6 +772,14 @@ private: if (auto simpleVal = exp->value->item.as()) { auto valueItem = simpleVal->value.get(); switch (valueItem->getId()) { + case "With"_id: { + str_list temp; + auto expList = assignment->assignable.get(); + std::string preDefine = getPredefine(assignment); + transformWith(static_cast(valueItem), temp, expList); + out.push_back(preDefine + temp.front()); + return; + } case "Do"_id: { auto doNode = static_cast(valueItem); auto expList = assignment->assignable.get(); @@ -856,7 +841,7 @@ private: if (isColonChain(chainValue)) { auto assignable = assignment->assignable.get(); std::string preDefine = getPredefine(transformAssignDefs(assignable)); - transformColonChain(chainValue, out, ExpUsage::Assignment, static_cast(assignable)); + transformColonChain(chainValue, out, ExpUsage::Assignment, assignable); auto nl = preDefine.empty() ? Empty : nll(chainValue); if (!preDefine.empty()) out.back() = preDefine + nl + out.back(); return; @@ -1082,10 +1067,44 @@ private: switch (action->getId()) { case "Update"_id: { auto update = static_cast(action); - transformExpList(expList, temp); + auto leftExp = static_cast(expList->exprs.objects().front()); + auto leftValue = singleValueFrom(leftExp); + if (!leftValue) throw std::logic_error("left hand expression is not assignable"); + if (auto chain = leftValue->getByPath()) { + auto tmpChain = new_ptr(); + for (auto item : chain->items.objects()) { + bool itemAdded = false; + do { + auto exp = ast_cast(item); + if (!exp) break; + auto var = variableFrom(exp); + if (!var.empty()) break; + auto upVar = getUnusedName("_update_"); + auto assignment = new_ptr(); + assignment->assignable.set(toAst(upVar, ExpList)); + auto assign = new_ptr(); + assign->values.push_back(exp); + assignment->target.set(assign); + transformAssignment(assignment, temp); + tmpChain->items.push_back(toAst(upVar, Exp)); + itemAdded = true; + } while (false); + if (!itemAdded) tmpChain->items.push_back(item); + } + chain->items.clear(); + chain->items.dup(tmpChain->items); + } + transformValue(leftValue, temp); + auto left = std::move(temp.back()); + temp.pop_back(); transformExp(update->value, temp); - _buf << indent() << temp.front() << " = "sv << temp.front() << - " "sv << toString(update->op) << " "sv << temp.back() << nll(assignment); + auto right = std::move(temp.back()); + temp.pop_back(); + if (!singleValueFrom(update->value)) { + right = s("("sv) + right + s(")"sv); + } + _buf << join(temp) << indent() << left << " = "sv << left << + " "sv << toString(update->op) << " "sv << right << nll(assignment); out.push_back(clearBuf()); break; } @@ -1312,23 +1331,6 @@ private: } } - void transformChainValue(ChainValue_t* chainValue, str_list& out) { - str_list temp; - auto caller = chainValue->caller.get(); - bool hasArgs = chainValue->arguments; - switch (caller->getId()) { - case "Chain"_id: transformChain(static_cast(caller), temp); break; - case "Callable"_id: transformCallable(static_cast(caller), temp, hasArgs); break; - default: break; - } - if (hasArgs) { - transformInvokeArgs(chainValue->arguments, temp); - out.push_back(temp.front() + s("("sv) + temp.back() + s(")"sv)); - } else { - out.push_back(temp.front()); - } - } - void transformCallable(Callable_t* callable, str_list& out, bool invoke) { auto item = callable->item.get(); switch (item->getId()) { @@ -1524,36 +1526,42 @@ private: void transformReturn(Return_t* returnNode, str_list& out) { if (auto valueList = returnNode->valueList.get()) { if (auto singleValue = singleValueFrom(valueList)) { - if (auto comp = singleValue->getByPath()) { - transformCompReturn(comp, out); - return; - } - if (auto comp = singleValue->getByPath()) { - transformTblCompReturn(comp, out); - return; - } - if (auto classDecl = singleValue->getByPath()) { - transformClassDecl(classDecl, out, ExpUsage::Return); - return; - } - if (auto doNode = singleValue->getByPath()) { - transformDo(doNode, out, true); - return; - } - if (auto switchNode = singleValue->getByPath()) { - transformSwitch(switchNode, out, true); - return; + if (auto simpleValue = singleValue->item.as()) { + if (auto comp = simpleValue->value.as()) { + transformCompReturn(comp, out); + return; + } + if (auto comp = simpleValue->value.as()) { + transformTblCompReturn(comp, out); + return; + } + if (auto classDecl = simpleValue->value.as()) { + transformClassDecl(classDecl, out, ExpUsage::Return); + return; + } + if (auto doNode = simpleValue->value.as()) { + transformDo(doNode, out, true); + return; + } + if (auto switchNode = simpleValue->value.as()) { + transformSwitch(switchNode, out, true); + return; + } + if (auto ifNode = simpleValue->value.as()) { + transformIf(ifNode, out, IfUsage::Return); + return; + } + if (auto unlessNode = simpleValue->value.as()) { + transformUnless(unlessNode, out, IfUsage::Return); + return; + } } - if (auto chainValue = singleValue->getByPath()) { + if (auto chainValue = singleValue->item.as()) { if (isColonChain(chainValue)) { transformColonChain(chainValue, out, ExpUsage::Return); return; } } - if (auto ifNode = singleValue->getByPath()) { - transformIf(ifNode, out, IfUsage::Return); - return; - } transformValue(singleValue, out); out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); return; @@ -1699,8 +1707,7 @@ private: void transformColonChain(ChainValue_t* chainValue, str_list& out, ExpUsage usage = ExpUsage::Common, ExpList_t* expList = nullptr) { str_list temp; - auto chain = chainValue->caller.to(); - const auto& chainList = chain->items.objects(); + const auto& chainList = chainValue->items.objects(); auto end = --chainList.end(); for (auto it = chainList.begin(); it != end; ++it) { auto item = *it; @@ -1713,7 +1720,7 @@ private: auto next = it; ++next; auto followItem = next != chainList.end() ? *next : nullptr; transformCallable(static_cast(item), temp, - followItem && followItem->getId() == "Invoke"_id); + followItem && ast_is(followItem)); break; } case "String"_id: @@ -1742,34 +1749,33 @@ private: auto fnVar = getUnusedName("_fn_"sv); addToScope(fnVar); if (usage != ExpUsage::Return) { - _buf << indent(-1) << "do"sv << nll(chain); + _buf << indent(-1) << "do"sv << nll(chainValue); } - _buf << indent() << "local "sv << baseVar << " = "sv << caller << nll(chain); - _buf << indent() << "local "sv << fnVar << " = "sv << baseVar << "."sv << funcName << nll(chain); + _buf << indent() << "local "sv << baseVar << " = "sv << caller << nll(chainValue); + _buf << indent() << "local "sv << fnVar << " = "sv << baseVar << "."sv << funcName << nll(chainValue); switch (usage) { case ExpUsage::Return: - _buf << indent() << "return function(...)" << nll(chain); + _buf << indent() << "return function(...)" << nll(chainValue); break; case ExpUsage::Assignment: - _buf << indent() << assignList << " = function(...)"sv << nll(chain); + _buf << indent() << assignList << " = function(...)"sv << nll(chainValue); break; case ExpUsage::Common: - _buf << indent() << "_ = function(...)" << nll(chain); + _buf << indent() << "_ = function(...)" << nll(chainValue); break; default: break; } - _buf << indent(1) << "return "sv << fnVar << "("sv << baseVar << ", ...)"sv << nll(chain); - _buf << indent() << "end"sv << nll(chain); + _buf << indent(1) << "return "sv << fnVar << "("sv << baseVar << ", ...)"sv << nll(chainValue); + _buf << indent() << "end"sv << nll(chainValue); if (usage != ExpUsage::Return) { popScope(); - _buf << indent() << "end"sv << nll(chain); + _buf << indent() << "end"sv << nll(chainValue); } out.push_back(clearBuf()); } - void transformChain(Chain_t* chain, str_list& out) { + void transformChainList(const std::list& chainList, str_list& out) { str_list temp; - const auto& chainList = chain->items.objects(); switch (chainList.front()->getId()) { case "DotChainItem"_id: case "ColonChainItem"_id: @@ -1783,15 +1789,23 @@ private: for (auto it = chainList.begin(); it != chainList.end(); ++it) { auto item = *it; switch (item->getId()) { - case "Invoke"_id: transformInvoke(static_cast(item), temp); break; - case "DotChainItem"_id: transformDotChainItem(static_cast(item), temp); break; - case "ColonChainItem"_id: transformColonChainItem(static_cast(item), temp); break; - case "Slice"_id: transformSlice(static_cast(item), temp); break; + case "Invoke"_id: + transformInvoke(static_cast(item), temp); + break; + case "DotChainItem"_id: + transformDotChainItem(static_cast(item), temp); + break; + case "ColonChainItem"_id: + transformColonChainItem(static_cast(item), temp); + break; + case "Slice"_id: + transformSlice(static_cast(item), temp); + break; case "Callable"_id: { auto next = it; ++next; auto followItem = next != chainList.end() ? *next : nullptr; transformCallable(static_cast(item), temp, - followItem && followItem->getId() == "Invoke"_id); + followItem && ast_is(followItem)); break; } case "String"_id: @@ -1802,14 +1816,28 @@ private: transformExp(static_cast(item), temp); temp.back() = s("["sv) + temp.back() + s("]"sv); break; + case "InvokeArgs"_id: transformInvokeArgs(static_cast(item), temp); break; default: break; } } out.push_back(join(temp)); } + void transformChainValue(ChainValue_t* chainValue, str_list& out) { + transformChainList(chainValue->items.objects(), out); + } + + void transformAssignableChain(AssignableChain_t* chain, str_list& out) { + transformChainList(chain->items.objects(), out); + } + void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) { - out.push_back(s("."sv) + toString(dotChainItem->name)); + auto name = toString(dotChainItem->name); + if (State::keywords.find(name) != State::keywords.end()) { + out.push_back(s("[\""sv) + name + s("\"]"sv)); + } else { + out.push_back(s("."sv) + name); + } } void transformColonChainItem(ColonChainItem_t* colonChainItem, str_list& out) { @@ -1836,7 +1864,7 @@ private: void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) { std::string op = toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it); - str_list temp{op + (op == "not"sv ? op + " " : Empty)}; + str_list temp{op + (op == "not"sv ? s(" "sv) : Empty)}; transformExp(unary_exp->item, temp); out.push_back(join(temp)); } @@ -1994,7 +2022,7 @@ private: do { auto chainValue = value->item.as(); if (!chainValue) break; - auto chainList = getChainList(chainValue); + auto chainList = chainValue->items.objects(); auto slice = ast_cast(chainList.back()); if (!slice) break; endWithSlice = true; @@ -2003,7 +2031,7 @@ private: listVar = toString(ast_to(chainList.front())->item); } chainList.pop_back(); - auto chain = new_ptr(); + auto chain = new_ptr(); for (auto item : chainList) { chain->items.push_back(item); } @@ -2026,7 +2054,7 @@ private: temp.pop_back(); } if (newListVal) { - transformChain(chain, temp); + transformChainValue(chain, temp); _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); } std::string maxVar; @@ -2115,7 +2143,7 @@ private: default: break; } } - out.push_back(join(temp, ", "sv)); + out.push_back(s("("sv) + join(temp, ", "sv) + s(")"sv)); } void transformForHead(For_t* forNode, str_list& out) { @@ -2359,7 +2387,13 @@ private: auto key = pair->key.get(); str_list temp; switch (key->getId()) { - case "KeyName"_id: transformKeyName(static_cast(key), temp); break; + case "KeyName"_id: { + transformKeyName(static_cast(key), temp); + if (State::luaKeywords.find(temp.back()) != State::luaKeywords.end()) { + temp.back() = s("[\""sv) + temp.back() + s("\"]"); + } + break; + } case "Exp"_id: transformExp(static_cast(key), temp); temp.back() = s("["sv) + temp.back() + s("]"sv); @@ -2391,10 +2425,6 @@ private: } } - void transformLuaString(LuaString_t* luaString, str_list& out) { - out.push_back(toString(luaString)); - } - void replace(std::string& str, std::string_view from, std::string_view to) { size_t start_pos = 0; while((start_pos = str.find(from, start_pos)) != std::string::npos) { @@ -2403,6 +2433,13 @@ private: } } + void transformLuaString(LuaString_t* luaString, str_list& out) { + auto content = toString(luaString->content); + replace(content, "\r"sv, ""); + if (content[0] == '\n') content.erase(content.begin()); + out.push_back(toString(luaString->open) + content + toString(luaString->close)); + } + void transformSingleString(SingleString_t* singleString, str_list& out) { auto str = toString(singleString); replace(str, "\r"sv, ""); @@ -2430,7 +2467,7 @@ private: default: break; } } - out.push_back(join(temp, " .. "sv)); + out.push_back(temp.empty() ? s("\"\""sv) : join(temp, " .. "sv)); } void transformString(String_t* string, str_list& out) { @@ -2480,10 +2517,10 @@ private: temp.push_back(indent() + s("local "sv) + className + nll(classDecl)); } if (className.empty()) { - if (auto chain = ast_cast(assignable->item)) { - if (auto dotChain = ast_cast(chain->items.objects().back())) { + if (auto chain = ast_cast(assignable->item)) { + if (auto dotChain = ast_cast(chain->items.back())) { className = s("\""sv) + toString(dotChain->name) + s("\""sv); - } else if (auto index = ast_cast(chain->items.objects().back())) { + } else if (auto index = ast_cast(chain->items.back())) { if (auto name = index->getByPath()) { transformString(name, temp); className = temp.back(); @@ -2730,20 +2767,8 @@ private: normal_pair->value->traverse([&](ast_node* node) { if (node->getId() == "ClassDecl"_id) return traversal::Return; if (auto chainValue = ast_cast(node)) { - if (auto var = chainValue->caller->getByPath()) { - if (toString(var) == "super"sv) { - if (chainValue->arguments) { - chainValue->arguments->args.push_front(toAst("self"sv, Exp)); - _codeCache.push_back(newSuperCall); - var->m_begin.m_it = _codeCache.back().begin(); - var->m_end.m_it = _codeCache.back().end(); - } else { - _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent"); - var->m_begin.m_it = _codeCache.back().begin(); - var->m_end.m_it = _codeCache.back().end(); - } - } - } else if (auto var = chainValue->caller->getByPath()) { + if (auto callable = ast_cast(chainValue->items.front())) { + auto var = callable->item.get(); if (toString(var) == "super"sv) { auto insertSelfToArguments = [&](ast_node* item) { switch (item->getId()) { @@ -2761,13 +2786,15 @@ private: return false; } }; - auto chainList = getChainList(chainValue); + const auto& chainList = chainValue->items.objects(); if (chainList.size() >= 2) { - if (insertSelfToArguments(chainList[1])) { + auto it = chainList.begin(); + auto secondItem = *(++it); + if (insertSelfToArguments(secondItem)) { _codeCache.push_back(newSuperCall); } else { - if (auto colonChainItem = ast_cast(chainList[1])) { - if (chainList.size() > 2 && insertSelfToArguments(chainList[2])) { + if (auto colonChainItem = ast_cast(secondItem)) { + if (chainList.size() > 2 && insertSelfToArguments(*(++it))) { colonChainItem->switchToDot = true; } } @@ -2812,14 +2839,14 @@ private: void transformAssignable(Assignable_t* assignable, str_list& out) { auto item = assignable->item.get(); switch (item->getId()) { - case "Chain"_id: transformChain(static_cast(item), out); break; + case "AssignableChain"_id: transformAssignableChain(static_cast(item), out); break; case "Variable"_id: transformVariable(static_cast(item), out); break; case "SelfName"_id: transformSelfName(static_cast(item), out, false); break; default: break; } } - void transformWith(With_t* with, str_list& out) { + void transformWith(With_t* with, str_list& out, ExpList_t* assignList = nullptr) { str_list temp; std::string withVar; bool scoped = false; @@ -2869,16 +2896,19 @@ private: transformAssignment(assignment, temp); } } else { - withVar = getUnusedName("_with_"); - auto assignment = new_ptr(); - assignment->assignable.set(toAst(withVar, ExpList)); - auto assign = new_ptr(); - assign->values.dup(with->valueList->exprs); - assignment->target.set(assign); - scoped = true; - temp.push_back(indent() + s("do"sv) + nll(with)); - pushScope(); - transformAssignment(assignment, temp); + withVar = variableFrom(with->valueList); + if (withVar.empty()) { + withVar = getUnusedName("_with_"); + auto assignment = new_ptr(); + assignment->assignable.set(toAst(withVar, ExpList)); + auto assign = new_ptr(); + assign->values.dup(with->valueList->exprs); + assignment->target.set(assign); + scoped = true; + temp.push_back(indent() + s("do"sv) + nll(with)); + pushScope(); + transformAssignment(assignment, temp); + } } auto exp = with->valueList->exprs.objects().front(); if (exp->getByPath()) { @@ -2888,6 +2918,14 @@ private: _withVars.push(withVar); transformBody(with->body, temp); _withVars.pop(); + if (assignList) { + auto assignment = new_ptr(); + assignment->assignable.set(assignList); + auto assign = new_ptr(); + assign->values.push_back(toAst(withVar, Exp)); + assignment->target.set(assign); + transformAssignment(assignment, temp); + } if (scoped) { popScope(); temp.push_back(indent() + s("end"sv) + nll(with)); @@ -2928,7 +2966,7 @@ private: auto callable = new_ptr(); callable->item.set(name); auto chainValue = new_ptr(); - chainValue->caller.set(callable); + chainValue->items.push_back(callable); auto value = new_ptr(); value->item.set(chainValue); auto exp = new_ptr(); @@ -3130,11 +3168,9 @@ private: auto callable = toAst(objVar, Callable); auto dotChainItem = new_ptr(); dotChainItem->name.set(var->name); - auto chain = new_ptr(); - chain->items.push_back(callable); - chain->items.push_back(dotChainItem); auto chainValue = new_ptr(); - chainValue->caller.set(chain); + chainValue->items.push_back(callable); + chainValue->items.push_back(dotChainItem); auto value = new_ptr(); value->item.set(chainValue); auto exp = new_ptr(); @@ -3144,7 +3180,7 @@ private: auto callable = new_ptr(); callable->item.set(var); auto chainValue = new_ptr(); - chainValue->caller.set(callable); + chainValue->items.push_back(callable); auto value = new_ptr(); value->item.set(chainValue); auto exp = new_ptr(); @@ -3159,11 +3195,9 @@ private: auto callable = toAst(objVar, Callable); auto colonChain = new_ptr(); colonChain->name.set(nameNode); - auto chain = new_ptr(); - chain->items.push_back(callable); - chain->items.push_back(colonChain); auto chainValue = new_ptr(); - chainValue->caller.set(chain); + chainValue->items.push_back(callable); + chainValue->items.push_back(colonChain); auto value = new_ptr(); value->item.set(chainValue); auto exp = new_ptr(); @@ -3173,7 +3207,7 @@ private: auto callable = new_ptr(); callable->item.set(var); auto chainValue = new_ptr(); - chainValue->caller.set(callable); + chainValue->items.push_back(callable); auto value = new_ptr(); value->item.set(chainValue); auto exp = new_ptr(); @@ -3294,6 +3328,9 @@ private: for (auto exp_ : exprs) { auto exp = static_cast(exp_); transformExp(exp, tmp); + if (!singleValueFrom(exp)) { + tmp.back() = s("("sv) + tmp.back() + s(")"sv); + } temp.back().append(s(" "sv) + tmp.back() + s(" == "sv) + objVar + s(exp == exprs.back() ? ""sv : " or"sv)); } @@ -3350,138 +3387,12 @@ int main() { std::string s = R"TestCodesHere( -for x=1,10 - print "yeah" - -for x=1,#something - print "yeah" - -for y=100,60,-3 - print "count down", y - -for a=1,10 do print "okay" - -for a=1,10 - for b = 2,43 - print a,b - -for i in iter - for j in yeah - x = 343 + i + j - print i, j - -for x in *something - print x - -for k,v in pairs hello do print k,v - -for x in y, z - print x - -for x in y, z, k - print x - - -x = -> - for x in y - y - -hello = {1,2,3,4,5} - -x = for y in *hello - if y % 2 == 0 - y - -x = -> - for x in *hello - y - -t = for i=10,20 do i * 2 - -hmm = 0 -y = for j = 3,30, 8 - hmm += 1 - j * hmm - --> - for k=10,40 - "okay" - --> - return for k=10,40 - "okay" - -while true do print "name" - -while 5 + 5 - print "okay world" - working man - -while also do - i work too - "okay" - -i = 0 -x = while i < 10 - i += 1 - --- values that can'e be coerced - -x = for thing in *3 - y = "hello" - -x = for x=1,2 - y = "hello" - - --- continue - -while true - continue if false - print "yes" - break if true - print "no" - - -for x=1,10 - continue if x > 3 and x < 7 - print x - - -list = for x=1,10 - continue if x > 3 and x < 7 - x - - -for a in *{1,2,3,4,5,6} - continue if a == 1 - continue if a == 3 - print a - - - -for x=1,10 - continue if x % 2 == 0 - for y = 2,12 - continue if y % 3 == 0 - - -while true - continue if false - break - -while true - continue if false - return 22 - --- - do - xxx = {1,2,3,4} - for thing in *xxx - print thing - - + a = -> + with something + print .hello + print hi + print "world" )TestCodesHere"; MoonCompliler{}.complile(s); return 0; diff --git a/MoonParser/moon_ast.h b/MoonParser/moon_ast.h index 1e5d733..d4ade53 100644 --- a/MoonParser/moon_ast.h +++ b/MoonParser/moon_ast.h @@ -245,10 +245,8 @@ AST_END(Update) AST_LEAF(BinaryOperator, "BinaryOperator"_id) AST_END(BinaryOperator) -class Chain_t; - AST_NODE(Assignable, "Assignable"_id) - ast_ptr item; // Chain_t | Variable_t | SelfName_t + ast_ptr item; // AssignableChain_t | Variable_t | SelfName_t AST_END(Assignable) class Value_t; @@ -267,13 +265,6 @@ AST_NODE(Callable, "Callable"_id) ast_ptr item; // Variable_t | SelfName_t | VarArg_t | Parens_t AST_END(Callable) -class InvokeArgs_t; - -AST_NODE(ChainValue, "ChainValue"_id) - ast_ptr caller; // Chain_t | Callable_t - ast_ptr arguments; -AST_END(ChainValue) - AST_NODE(variable_pair, "variable_pair"_id) ast_ptr name; AST_END(variable_pair) @@ -299,7 +290,19 @@ AST_NODE(SimpleValue, "SimpleValue"_id) */ AST_END(SimpleValue) -AST_LEAF(LuaString, "LuaString"_id) +AST_LEAF(LuaStringOpen, "LuaStringOpen"_id) +AST_END(LuaStringOpen) + +AST_LEAF(LuaStringContent, "LuaStringContent"_id) +AST_END(LuaStringContent) + +AST_LEAF(LuaStringClose, "LuaStringClose"_id) +AST_END(LuaStringClose) + +AST_NODE(LuaString, "LuaString"_id) + ast_ptr open; + ast_ptr content; + ast_ptr close; AST_END(LuaString) AST_LEAF(SingleString, "SingleString"_id) @@ -345,10 +348,17 @@ AST_NODE(Invoke, "Invoke"_id) ast_sel_list args; AST_END(Invoke) -AST_NODE(Chain, "Chain"_id) +class InvokeArgs_t; + +AST_NODE(ChainValue, "ChainValue"_id) + ast_ptr sep; + ast_sel_list items; +AST_END(ChainValue) + +AST_NODE(AssignableChain, "AssignableChain"_id) ast_ptr sep; - ast_sel_list items; -AST_END(Chain) + ast_sel_list items; +AST_END(AssignableChain) AST_NODE(Value, "Value"_id) ast_ptr item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t @@ -486,6 +496,6 @@ AST_NODE(Block, "Block"_id) ast_list statements; AST_END(Block) -AST_NODE(BlockEnd, "BlockEnd"_id) +AST_NODE(File, "File"_id) ast_ptr block; -AST_END(BlockEnd) +AST_END(File) diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp index 481c885..ad86020 100644 --- a/MoonParser/moon_parser.cpp +++ b/MoonParser/moon_parser.cpp @@ -1,11 +1,21 @@ #include "moon_parser.h" +std::unordered_set State::luaKeywords = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", + "repeat", "return", "then", "true", "until", + "while" +}; + std::unordered_set State::keywords = { - "and", "while", "else", "using", "continue", - "local", "not", "then", "return", "from", - "extends", "for", "do", "or", "export", - "class", "in", "unless", "when", "elseif", - "switch", "break", "if", "with", "import", "true", "false", "nil" + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", + "repeat", "return", "then", "true", "until", + "while", // Lua keywords + "class", "continue", "export", "extends", + "import", "switch", "unless", "using", "with" // Moon keywords }; rule plain_space = *set(" \t"); @@ -44,12 +54,9 @@ rule Seperator = true_(); rule Variable = 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); - std::string name; - st->buffer >> name; - st->buffer.str(""); + for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast(*it); + auto it = st->keywords.find(st->buffer); st->buffer.clear(); - auto it = st->keywords.find(name); return it == st->keywords.end(); }); @@ -252,18 +259,18 @@ rule BinaryOperator = expr("//") | set("+-*/%^><|&"); -extern rule Chain; +extern rule AssignableChain; -rule Assignable = Chain | Space >> Variable | SelfName; +rule Assignable = AssignableChain | Space >> Variable | SelfName; extern rule Value; rule exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> Value; rule Exp = Value >> *exp_op_value; -extern rule Callable, InvokeArgs; +extern rule Chain, Callable, InvokeArgs; -rule ChainValue = (Chain | Callable) >> -InvokeArgs; +rule ChainValue = Seperator >> (Chain | Callable) >> -InvokeArgs; extern rule KeyValue, String, SimpleValue; @@ -321,10 +328,10 @@ rule chain_call = (Callable | String) >> ChainItems; rule chain_item = and_(set(".\\")) >> ChainItems; rule chain_dot_chain = DotChainItem >> -ChainItems; -rule Chain = Seperator >> ( - chain_call | - chain_item | - Space >> (chain_dot_chain | ColonChain)); +rule Chain = chain_call | chain_item | + Space >> (chain_dot_chain | ColonChain); + +rule AssignableChain = Seperator >> Chain; extern rule ChainItem; @@ -491,4 +498,6 @@ rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; rule empty_line_stop = Space >> and_(Stop); rule Line = CheckIndent >> Statement | empty_line_stop; rule Block = Seperator >> Line >> *(+Break >> Line); -rule BlockEnd = Block >> eof(); + +rule Shebang = expr("#!") >> *(not_(Stop) >> Any); +rule File = White >> -Shebang >> Block >> eof(); diff --git a/MoonParser/moon_parser.h b/MoonParser/moon_parser.h index 5327b05..0c45538 100644 --- a/MoonParser/moon_parser.h +++ b/MoonParser/moon_parser.h @@ -5,7 +5,6 @@ #include #include #include -#include #include #include "parserlib.hpp" using namespace parserlib; @@ -15,9 +14,10 @@ struct State { indents.push(0); stringOpen = -1; } - std::stringstream buffer; + std::string buffer; size_t stringOpen; std::stack indents; std::stack doStack; + static std::unordered_set luaKeywords; static std::unordered_set keywords; }; -- cgit v1.2.3-55-g6feb