From 74c4f6eab47f76b093e17f515204525e00a3b352 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Tue, 17 Sep 2019 00:41:21 +0800 Subject: completing spec/class.moon --- MoonParser/ast.hpp | 9 +- MoonParser/moon_ast.cpp | 557 ++++++++++++++++++++++++++++++++++++++------- MoonParser/moon_ast.h | 43 ++-- MoonParser/moon_parser.cpp | 94 ++++---- MoonParser/moon_parser.h | 6 +- 5 files changed, 548 insertions(+), 161 deletions(-) diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp index d239eac..e7ae74f 100644 --- a/MoonParser/ast.hpp +++ b/MoonParser/ast.hpp @@ -367,13 +367,20 @@ public: clear(); } - void add(ast_node* node) { + void push_back(ast_node* node) { if (accept(node)) { m_objects.push_back(node); node->retain(); } } + void push_front(ast_node* node) { + if (accept(node)) { + m_objects.push_front(node); + node->retain(); + } + } + const container& objects() const { return m_objects; } diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index fa95097..af34395 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp @@ -23,8 +23,8 @@ const input& AstLeaf::getValue() { ast __##type##_t(type); AST_IMPL(Num) -AST_IMPL(_Name) AST_IMPL(Name) +AST_IMPL(Variable) AST_IMPL(self) AST_IMPL(self_name) AST_IMPL(self_class) @@ -235,7 +235,7 @@ private: return !defined; } - std::string getValidName(std::string_view name) { + std::string getUnusedName(std::string_view name) { int index = 0; std::string newName; do { @@ -344,6 +344,71 @@ private: return parse(_codeCache.back(), r, el, &st); } + Invoke_t* startWithInvoke(ast_node* chain) { + ast_node* invoke = nullptr; + chain->traverse([&](ast_node* node) { + switch (node->getId()) { + case "Invoke"_id: + invoke = node; + return traversal::Stop; + case "DotChainItem"_id: + case "ColonChainItem"_id: + case "Slice"_id: + case "Index"_id: + case "Callable"_id: + case "String"_id: + return traversal::Stop; + default: + return traversal::Continue; + } + }); + return static_cast(invoke); + } + + Invoke_t* endWithInvoke(Chain_t* chain) { + ast_node* last = nullptr; + chain->traverse([&](ast_node* node) { + switch (node->getId()) { + case "Invoke"_id: + case "DotChainItem"_id: + case "ColonChainItem"_id: + case "Slice"_id: + case "Index"_id: + case "Callable"_id: + case "String"_id: + last = node; + return traversal::Return; + default: + return traversal::Continue; + } + }); + if (last && last->getId() == "Invoke"_id) { + return static_cast(last); + } else { + return nullptr; + } + } + + std::vector getChainList(ast_node* chain) { + std::vector list; + chain->traverse([&](ast_node* node) { + switch (node->getId()) { + case "Invoke"_id: + case "DotChainItem"_id: + case "ColonChainItem"_id: + case "Slice"_id: + case "Index"_id: + case "Callable"_id: + case "String"_id: + list.push_back(node); + return traversal::Return; + default: + return traversal::Continue; + } + }); + return list; + } + void transformStatement(Statement_t* statement, std::vector& out) { if (statement->appendix) { auto appendix = statement->appendix; @@ -354,7 +419,7 @@ private: ifCond->condition = if_else_line->condition; auto exprList = new_ptr(); - exprList->exprs.add(if_else_line->elseExpr); + exprList->exprs.push_back(if_else_line->elseExpr); auto stmt = new_ptr(); stmt->content.set(exprList); auto body = new_ptr(); @@ -369,7 +434,7 @@ private: auto ifNode = new_ptr(); ifNode->firstCondition.set(ifCond); ifNode->firstBody.set(body); - ifNode->branches.add(ifElseIf); + ifNode->branches.push_back(ifElseIf); statement->appendix.set(nullptr); auto simpleValue = new_ptr(); @@ -379,7 +444,7 @@ private: auto exp = new_ptr(); exp->value.set(value); exprList = new_ptr(); - exprList->exprs.add(exp); + exprList->exprs.push_back(exp); statement->content.set(exprList); break; } @@ -416,14 +481,38 @@ private: break; } if (auto singleValue = singleValueFrom(expList)) { - if (auto ifNode = static_cast(singleValue->getByPath({"SimpleValue"_id, "If"_id}))) { - transformIf(ifNode, out); - break; + if (auto simpleValue = static_cast(singleValue->getByPath({"SimpleValue"_id}))) { + auto value = simpleValue->getFirstChild(); + bool specialSingleValue = true; + switch (value->getId()) { + case "If"_id: transformIf(static_cast(value), out); break; + case "ClassDecl"_id: transformClassDecl(static_cast(value), out); break; + case "Unless"_id: transformUnless(static_cast(value), out); break; + case "Switch"_id: transformSwitch(static_cast(value), out); break; + case "With"_id: transformWith(static_cast(value), out); break; + case "ForEach"_id: transformForEach(static_cast(value), out); break; + case "For"_id: transformFor(static_cast(value), out); break; + case "While"_id: transformWhile(static_cast(value), out); break; + case "Do"_id: transformDo(static_cast(value), out); break; + default: specialSingleValue = false; break; + } + if (specialSingleValue) { + break; + } } - if (singleValue->getByPath({"ChainValue"_id, "InvokeArgs"_id})) { - transformValue(singleValue, out); - out.back() = indent() + out.back() + nlr(singleValue); - break; + if (auto chainValue = static_cast(singleValue->getByPath({"ChainValue"_id}))) { + if (chainValue->arguments) { + transformValue(singleValue, out); + out.back() = indent() + out.back() + nlr(singleValue); + break; + } else { + auto chain = static_cast(chainValue->getByPath({"Chain"_id})); + if (chain && endWithInvoke(chain)) { + transformValue(singleValue, out); + out.back() = indent() + out.back() + nlr(singleValue); + break; + } + } } } std::string preDefine; @@ -445,7 +534,7 @@ private: std::vector values; expList->traverse([&](ast_node* child) { if (child->getId() == "Value"_id) { - auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Name"_id}); + auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Variable"_id}); if (target) { auto name = toString(target); if (addToScope(name)) { @@ -557,6 +646,14 @@ private: out.push_back(preDefine + nll(statement) + temp.front()); return; } + case "ClassDecl"_id: { + std::vector temp; + auto expList = assignment->assignable.get(); + std::string preDefine = transformAssignDefs(expList); + transformClassDecl(static_cast(valueItem), temp, ClassDeclUsage::Assignment, expList); + out.push_back(preDefine + nll(statement) + temp.front()); + return; + } } } } @@ -575,7 +672,7 @@ private: if (auto body = node->getByPath({"Body"_id})) { if (traversal::Stop == body->traverse([&](ast_node* n) { if (n->getId() == "Callable"_id) { - if (auto name = n->getByPath({"Name"_id})) { + if (auto name = n->getByPath({"Variable"_id})) { if (temp.front() ==toString(name)) { return traversal::Stop; } @@ -721,7 +818,7 @@ private: void transformCallable(Callable_t* callable, std::vector& out, bool invoke) { auto item = callable->item.get(); switch (item->getId()) { - case "Name"_id: transformName(static_cast(item), out); break; + case "Variable"_id: transformVariable(static_cast(item), out); break; case "SelfName"_id: transformSelfName(static_cast(item), out, invoke); break; case "VarArg"_id: out.push_back(s("..."sv)); break; case "Parens"_id: transformParens(static_cast(item), out); break; @@ -742,7 +839,7 @@ private: case "If"_id: transformIfClosure(static_cast(value), out); break; case "Switch"_id: transformSwitch(value, out); break; case "With"_id: transformWith(value, out); break; - case "ClassDecl"_id: transformClassDecl(static_cast(value), out); break; + case "ClassDecl"_id: transformClassDeclClosure(static_cast(value), out); break; case "ForEach"_id: transformForEachClosure(static_cast(value), out); break; case "For"_id: transformForClosure(static_cast(value), out); break; case "While"_id: transformWhile(value, out); break; @@ -829,6 +926,8 @@ private: if (auto singleValue = singleValueFrom(valueList)) { if (auto comp = singleValue->getByPath({"SimpleValue"_id, "Comprehension"_id})) { transformCompReturn(static_cast(comp), out); + } else if (auto classDecl = singleValue->getByPath({"SimpleValue"_id, "ClassDecl"_id})) { + transformClassDecl(static_cast(classDecl), out, ClassDeclUsage::Return); } else { transformValue(singleValue, out); out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); @@ -877,7 +976,7 @@ private: auto def = static_cast(_def); auto& arg = argItems.emplace_back(); switch (def->name->getId()) { - case "Name"_id: arg.name = toString(def->name); break; + case "Variable"_id: arg.name = toString(def->name); break; case "SelfName"_id: { assignSelf = true; auto selfName = static_cast(def->name.get()); @@ -971,7 +1070,10 @@ private: std::vector temp; auto caller = chain_call->caller.get(); switch (caller->getId()) { - case "Callable"_id: transformCallable(static_cast(caller), temp, true); break; + case "Callable"_id: { + transformCallable(static_cast(caller), temp, startWithInvoke(chain_call->chain)); + break; + } case "String"_id: transformString(static_cast(caller), temp); break; default: break; } @@ -1030,7 +1132,9 @@ private: void transformColonChain(ColonChain_t* colonChain, std::vector& out) { std::vector temp; - temp.push_back(s(":"sv) + toString(colonChain->colonChain->name)); + temp.push_back( + s(colonChain->colonChain->switchToDot ? "."sv : ":"sv) + + toString(colonChain->colonChain->name)); if (colonChain->invokeChain) { transform_invoke_chain(colonChain->invokeChain, temp); } @@ -1053,7 +1157,7 @@ private: out.push_back(join(temp)); } - void transformName(Name_t* name, std::vector& out) { + void transformVariable(Variable_t* name, std::vector& out) { out.push_back(toString(name)); } @@ -1086,8 +1190,8 @@ private: void transformComprehension(Comprehension_t* comp, std::vector& out) { std::vector temp; - std::string accum = getValidName("_accum_"); - std::string len = getValidName("_len_"); + std::string accum = getUnusedName("_accum_"); + std::string len = getUnusedName("_len_"); addToScope(accum); addToScope(len); transformExp(comp->value, temp); @@ -1177,8 +1281,8 @@ private: switch (loopTarget->getId()) { case "star_exp"_id: { auto star_exp = static_cast(loopTarget); - auto listName = getValidName("_list_"); - auto indexName = getValidName("_index_"); + auto listName = getUnusedName("_list_"); + auto indexName = getUnusedName("_index_"); addToScope(listName); addToScope(indexName); transformExp(star_exp->value, temp); @@ -1211,8 +1315,8 @@ private: for (auto _item : nameList->items.objects()) { auto item = static_cast(_item)->item.get(); switch (item->getId()) { - case "Name"_id: - transformName(static_cast(item), temp); + case "Variable"_id: + transformVariable(static_cast(item), temp); break; case "TableLit"_id: transformTableLit(static_cast(item), temp); @@ -1262,8 +1366,8 @@ private: void transformForClosure(For_t* forNode, std::vector& out) { std::vector temp; - std::string accum = getValidName("_accum_"); - std::string len = getValidName("_len_"); + std::string accum = getUnusedName("_accum_"); + std::string len = getUnusedName("_len_"); addToScope(accum); addToScope(len); _buf << "(function()"sv << nll(forNode); @@ -1299,8 +1403,8 @@ private: void transformForInPlace(For_t* forNode, std::vector& out, ExpList_t* assignExpList) { std::vector temp; - std::string accum = getValidName("_accum_"); - std::string len = getValidName("_len_"); + std::string accum = getUnusedName("_accum_"); + std::string len = getUnusedName("_len_"); _buf << indent() << "do"sv << nll(forNode); pushScope(); addToScope(accum); @@ -1351,8 +1455,8 @@ private: void transformForEachClosure(ForEach_t* forEach, std::vector& out) { std::vector temp; - std::string accum = getValidName("_accum_"); - std::string len = getValidName("_len_"); + std::string accum = getUnusedName("_accum_"); + std::string len = getUnusedName("_len_"); addToScope(accum); addToScope(len); _buf << "(function()"sv << nll(forEach); @@ -1388,8 +1492,8 @@ private: void transformForEachInPlace(ForEach_t* forEach, std::vector& out, ExpList_t* assignExpList) { std::vector temp; - std::string accum = getValidName("_accum_"); - std::string len = getValidName("_len_"); + std::string accum = getUnusedName("_accum_"); + std::string len = getUnusedName("_len_"); _buf << indent() << "do"sv << nll(forEach); pushScope(); addToScope(accum); @@ -1462,7 +1566,7 @@ private: auto name = keyName->name.get(); switch (name->getId()) { case "SelfName"_id: transformSelfName(static_cast(name), out, false); break; - case "_Name"_id: out.push_back(toString(name)); break; + case "Name"_id: out.push_back(toString(name)); break; default: break; } } @@ -1504,47 +1608,309 @@ private: } } - void transformClassDecl(ClassDecl_t* classDecl, std::vector& out) { - std::vector temp; - if (classDecl->name) { - transformAssignable(classDecl->name, temp); - } - if (classDecl->extend) { - transformExp(classDecl->extend, temp); - } - if (classDecl->body) { - transformClassBlock(classDecl->body, temp); + std::pair defineClassVariable(Assignable_t* assignable) { + if (assignable->item->getId() == "Variable"_id) { + auto variable = static_cast(assignable->item.get()); + auto name = toString(variable); + if (addToScope(name)) { + return {name, true}; + } else { + return {name, false}; + } } - out.push_back(join(temp, "\n"sv)); + return {Empty, false}; } - void transformClassBlock(ClassBlock_t* classBlock, std::vector& out) { + enum class ClassDeclUsage { + Return, + Assignment, + Common + }; + + void transformClassDeclClosure(ClassDecl_t* classDecl, std::vector& out) { std::vector temp; - for (auto _line : classBlock->lines.objects()) { - auto line = static_cast(_line); - transformClassLine(line, temp); - } - out.push_back(join(temp,"\n"sv)); + temp.push_back(s("(function()"sv) + nll(classDecl)); + pushScope(); + transformClassDecl(classDecl, temp, ClassDeclUsage::Return); + popScope(); + temp.push_back(s("end)()"sv)); + out.push_back(join(temp)); } - void transformClassLine(ClassLine_t* classLine, std::vector& out) { - auto content = classLine->content.get(); - switch (content->getId()) { - case "class_member_list"_id: - transform_class_member_list(static_cast(content), out); - break; - case "Statement"_id: - transformStatement(static_cast(content), out); + struct ClassMember { + std::string key; + bool isBuiltin; + ast_node* node; + }; + + void transformClassDecl(ClassDecl_t* classDecl, std::vector& out, ClassDeclUsage usage = ClassDeclUsage::Common, ExpList_t* expList = nullptr) { + std::vector temp; + auto body = classDecl->body.get(); + auto assignable = classDecl->name.get(); + auto extend = classDecl->extend.get(); + std::string className; + if (assignable) { + bool newDefined = false; + std::tie(className, newDefined) = defineClassVariable(assignable); + if (newDefined) { + temp.push_back(indent() + s("local "sv) + className + nll(classDecl)); + } + } + temp.push_back(indent() + s("do"sv) + nll(classDecl)); + pushScope(); + auto classVar = getUnusedName("_class_"sv); + addToScope(classVar); + temp.push_back(indent() + s("local "sv) + classVar + nll(classDecl)); + if (body) { + body->traverse([&](ast_node* node) { + if (node->getId() == "Statement"_id) { + if (auto assignment = static_cast(node->getByPath({"Assignment"_id}))) { + std::string preDefine = transformAssignDefs(assignment->assignable.get()); + if (!preDefine.empty()) temp.push_back(preDefine + nll(assignment)); + } + return traversal::Return; + } + return traversal::Continue; + }); + } + std::string parent, parentVar; + if (extend) { + parentVar = getUnusedName("_parent_"sv); + addToScope(parentVar); + transformExp(extend, temp); + parent = temp.back(); + temp.pop_back(); + temp.push_back(indent() + s("local "sv) + parentVar + s(" = "sv) + parent + nll(classDecl)); + } + auto baseVar = getUnusedName("_base_"sv); + auto selfVar = getUnusedName("_self_"sv); + addToScope(baseVar); + addToScope(selfVar); + temp.push_back(indent() + s("local "sv) + baseVar + s(" = "sv)); + std::vector builtins; + std::vector customs; + std::vector statements; + if (body) { + std::list members; + for (auto _classLine : classDecl->body->lines.objects()) { + auto classLine = static_cast(_classLine); + auto content = classLine->content.get(); + switch (content->getId()) { + case "class_member_list"_id: + pushScope(); + transform_class_member_list(static_cast(content), members, classVar); + popScope(); + members.back().key = indent(1) + members.back().key; + break; + case "Statement"_id: + transformStatement(static_cast(content), statements); + break; + default: break; + } + } + for (auto& member : members) { + if (member.isBuiltin) { + builtins.push_back((builtins.empty() ? Empty : s(","sv) + nll(member.node)) + member.key); + } else { + customs.push_back((customs.empty() ? Empty : s(","sv) + nll(member.node)) + member.key); + } + } + if (!customs.empty()) { + temp.back() += s("{"sv) + nll(body); + temp.push_back(join(customs) + nll(body)); + temp.push_back(indent() + s("}"sv) + nll(body)); + } else { + temp.back() += s("{ }"sv) + nll(body); + } + temp.push_back(indent() + baseVar + s(".__index = "sv) + baseVar + nll(classDecl)); + } else { + temp.back() += s("{ }"sv) + nll(classDecl); + } + if (extend) { + _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl); + } + _buf << indent() << classVar << " = setmetatable({" << nll(classDecl); + if (!builtins.empty()) { + _buf << join(builtins) << ","sv << nll(classDecl); + } else { + if (extend) { + _buf << indent(1) << "__init = function(self, ...)"sv << nll(classDecl); + _buf << indent(2) << "return _class_0.__parent.__init(self, ...)"sv << nll(classDecl); + _buf << indent(1) << "end,"sv << nll(classDecl); + } else { + _buf << indent(1) << "__init = function() end,"sv << nll(classDecl); + } + } + _buf << indent(1) << "__base = "sv << baseVar; + if (!className.empty()) { + _buf << ","sv << nll(classDecl) << indent(1) << "__name = \""sv << className << "\""sv << (extend ? s(","sv) : Empty) << nll(classDecl); + } else { + _buf << nll(classDecl); + } + if (extend) { + _buf << indent(1) << "__parent = "sv << parentVar << nll(classDecl); + } + _buf << indent() << "}, {"sv << nll(classDecl); + if (extend) { + _buf << indent(1) << "__index = function(cls, name)"sv << nll(classDecl); + _buf << indent(2) << "local val = rawget("sv << baseVar << ", name)"sv << nll(classDecl); + _buf << indent(2) << "if val == nil then"sv << nll(classDecl); + _buf << indent(3) << "local parent = rawget(cls, \"__parent\")"sv << nll(classDecl); + _buf << indent(3) << "if parent then"sv << nll(classDecl); + _buf << indent(4) << "return parent[name]"sv << nll(classDecl); + _buf << indent(3) << "end"sv << nll(classDecl); + _buf << indent(2) << "else"sv << nll(classDecl); + _buf << indent(3) << "return val"sv << nll(classDecl); + _buf << indent(2) << "end"sv << nll(classDecl); + _buf << indent(1) << "end,"sv << nll(classDecl); + } else { + _buf << indent(1) << "__index = "sv << baseVar << ","sv << nll(classDecl); + } + _buf << indent(1) << "__call = function(cls, ...)"sv << nll(classDecl); + _buf << indent(2) << "local " << selfVar << " = setmetatable({}, "sv << baseVar << ")"sv << nll(classDecl); + _buf << indent(2) << "cls.__init("sv << selfVar << ", ...)"sv << nll(classDecl); + _buf << indent(2) << "return "sv << selfVar << nll(classDecl); + _buf << indent(1) << "end"sv << nll(classDecl); + _buf << indent() << "})"sv << nll(classDecl); + _buf << indent() << baseVar << ".__class = "sv << classVar << nll(classDecl); + if (extend) { + _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nll(classDecl); + _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nll(classDecl); + _buf << indent() << "end"sv << nll(classDecl); + } + if (!statements.empty()) _buf << indent() << "local self = "sv << classVar << nll(classDecl); + _buf << join(statements); + if (!className.empty()) _buf << indent() << className << " = "sv << classVar << nll(classDecl); + switch (usage) { + case ClassDeclUsage::Return: { + _buf << indent() << "return "sv << classVar << nlr(classDecl); break; - case "Exp"_id: - transformExp(static_cast(content), out); + } + case ClassDeclUsage::Assignment: { + std::vector tmp; + transformExpList(expList, tmp); + _buf << indent() << tmp.back() << " = "sv << classVar << nlr(classDecl); break; + } + default: break; } + temp.push_back(clearBuf()); + popScope(); + temp.push_back(indent() + s("end"sv) + nlr(classDecl)); + out.push_back(join(temp)); } - void transform_class_member_list(class_member_list_t* class_member_list, std::vector& out) {noop(class_member_list, out);} + void transform_class_member_list(class_member_list_t* class_member_list, std::list& out, const std::string& classVar) { + std::vector temp; + for (auto _keyValue : class_member_list->values.objects()) { + auto keyValue = static_cast(_keyValue); + bool isBuiltin = false; + do { + auto keyName = static_cast( + keyValue->getByPath({"normal_pair"_id, "KeyName"_id}) + ); + if (!keyName) break; + auto normal_pair = static_cast(keyValue->getFirstChild()); + auto nameNode = keyName->getByPath({"Name"_id}); + if (!nameNode) break; + auto name = toString(nameNode); + input newSuperCall; + isBuiltin = name == "new"sv; + if (isBuiltin) { + keyName->name.set(toAst("__init"sv, Name)); + newSuperCall = _converter.from_bytes(classVar) + L".__parent.__init"; + } else { + newSuperCall = _converter.from_bytes(classVar) + L".__parent.__base." + _converter.from_bytes(name); + } + 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({"Variable"_id})) { + if (toString(var) == "super"sv) { + if (chainValue->arguments && chainValue->arguments->argsList) { + chainValue->arguments->argsList->exprs.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({"chain_call"_id, "Callable"_id, "Variable"_id})) { + if (toString(var) == "super"sv) { + auto chainList = getChainList(chainValue->caller); + if (auto args = chainValue->getByPath({"InvokeArgs"_id, "ExpList"_id})) { + chainList.push_back(args); + } + auto insertSelfToArguments = [&](ast_node* item) { + switch (item->getId()) { + case "ExpList"_id: + static_cast(item)->exprs.push_front(toAst("self"sv, Exp)); + break; + case "Invoke"_id: { + auto invoke = static_cast(item); + if (auto fnArgs = invoke->argument.as()) { + fnArgs->args.push_front(toAst("self"sv, Exp)); + } else { + auto string = new_ptr(); + string->str.set(invoke->argument); + auto value = new_ptr(); + value->item.set(string); + auto exp = new_ptr(); + exp->value.set(value); + auto newFnArgs = new_ptr(); + fnArgs->args.push_back(toAst("self"sv, Exp)); + newFnArgs->args.push_back(exp); + invoke->argument.set(newFnArgs); + } + break; + } + default: break; + } + }; + if (chainList.size() == 2) { + _codeCache.push_back(newSuperCall); + var->m_begin.m_it = _codeCache.back().begin(); + var->m_end.m_it = _codeCache.back().end(); + auto item = chainList.back(); + insertSelfToArguments(item); + } else if (chainList.size() > 2) { + _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(); + if (auto colonChainItem = ast_cast(chainList[1])) { + colonChainItem->switchToDot = true; + auto item = chainList[2]; + insertSelfToArguments(item); + } + } 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(); + } + } + } + } + return traversal::Continue; + }); + } while (false); + transformKeyValue(keyValue, temp); + out.push_back({temp.back(), isBuiltin, keyValue}); + temp.clear(); + } + } - void transformAssignable(ast_node* node, std::vector& out) {noop(node, out);} + void transformAssignable(Assignable_t* assignable, std::vector& out) { + auto item = assignable->item.get(); + switch (item->getId()) { + case "Chain"_id: transformChain(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 transformUpdate(ast_node* node, std::vector& out) {noop(node, out);} void transformImport(ast_node* node, std::vector& out) {noopnl(node, out);} @@ -1565,40 +1931,69 @@ private: void transformCompFor(ast_node* node, std::vector& out) {noop(node, out);} void transformCompClause(ast_node* node, std::vector& out) {noop(node, out);} void transform_invoke_args_with_table(ast_node* node, std::vector& out) {noop(node, out);} + void transformUnless(Unless_t* node, std::vector& out) {noop(node, out);} }; const std::string MoonCompliler::Empty; int main() { - std::string s = R"TestCodesHere( --- vararg bubbling -f = (...) -> #{...} + std::string s = R"TestCodesHere(class Hello + new: (@test, @world) => + print "creating object.." + hello: => + print @test, @world + __tostring: => "hello world" + +x = Hello 1,2 +x\hello() + +print x + +class Simple + cool: => print "cool" + +class Yikes extends Simple + new: => print "created hello" + +x = Yikes() +x\cool() + + +class Hi + new: (arg) => + print "init arg", arg -dont_bubble = -> - [x for x in ((...)-> print ...)("hello")] + cool: (num) => + print "num", num -k = [x for x in ((...)-> print ...)("hello")] -j = for i=1,10 - (...) -> print ... +class Simple extends Hi + new: => super "man" + cool: => super 120302 --- bubble me +x = Simple() +x\cool() -m = (...) -> - [x for x in *{...} when f(...) > 4] +print x.__class == Simple -x = for i in *{...} do i -y = [x for x in *{...}] -z = [x for x in hallo when f(...) > 4] +class Okay + -- what is going on + something: 20323 + -- yeaha -a = for i=1,10 do ... -b = for i=1,10 - -> print ... +class Biggie extends Okay + something: => + super 1,2,3,4 + super.something another_self, 1,2,3,4 + assert super == Okay +class Yeah + okay: => + super\something 1,2,3,4 )TestCodesHere"; MoonCompliler{}.complile(s); diff --git a/MoonParser/moon_ast.h b/MoonParser/moon_ast.h index 9eab2f9..9733bf9 100644 --- a/MoonParser/moon_ast.h +++ b/MoonParser/moon_ast.h @@ -48,25 +48,25 @@ public: \ AST_LEAF(Num, "Num"_id) AST_END(Num) -AST_LEAF(_Name, "_Name"_id) -AST_END(_Name) - -AST_NODE(Name, "Name"_id) - ast_ptr<_Name_t> name; +AST_LEAF(Name, "Name"_id) AST_END(Name) +AST_NODE(Variable, "Variable"_id) + ast_ptr name; +AST_END(Variable) + AST_LEAF(self, "self"_id) AST_END(self) AST_NODE(self_name, "self_name"_id) - ast_ptr<_Name_t> name; + ast_ptr name; AST_END(self_name) AST_LEAF(self_class, "self_class"_id) AST_END(self_class) AST_NODE(self_class_name, "self_class_name"_id) - ast_ptr<_Name_t> name; + ast_ptr name; AST_END(self_class_name) AST_NODE(SelfName, "SelfName"_id) @@ -74,7 +74,7 @@ AST_NODE(SelfName, "SelfName"_id) AST_END(SelfName) AST_NODE(KeyName, "KeyName"_id) - ast_ptr name; // SelfName_t | _Name_t + ast_ptr name; // SelfName_t | Name_t AST_END(KeyName) AST_LEAF(VarArg, "VarArg"_id) @@ -88,7 +88,7 @@ AST_END(Seperator) AST_NODE(NameList, "NameList"_id) ast_ptr sep; - ast_list names; + ast_list names; AST_END(NameList) AST_NODE(Local, "Local"_id) @@ -96,13 +96,13 @@ AST_NODE(Local, "Local"_id) AST_END(Local) AST_NODE(colon_import_name, "colon_import_name"_id) - ast_ptr name; + ast_ptr name; AST_END(colon_import_name) class Exp_t; AST_NODE(ImportName, "ImportName"_id) - ast_ptr name; // colon_import_name_t | Name_t + ast_ptr name; // colon_import_name_t | Variable_t AST_END(ImportName) AST_NODE(Import, "Import"_id) @@ -182,7 +182,7 @@ AST_NODE(for_step_value, "for_step_value"_id) AST_END(for_step_value) AST_NODE(For, "For"_id) - ast_ptr varName; + ast_ptr varName; ast_ptr startValue; ast_ptr stopValue; ast_ptr stepValue; @@ -228,7 +228,7 @@ AST_NODE(CompForEach, "CompForEach"_id) AST_END(CompForEach) AST_NODE(CompFor, "CompFor"_id) - ast_ptr varName; + ast_ptr varName; ast_ptr startValue; ast_ptr stopValue; ast_ptr stepValue; @@ -264,7 +264,7 @@ AST_END(BinaryOperator) class Chain_t; AST_NODE(Assignable, "Assignable"_id) - ast_ptr item; // Chain_t | Name_t | SelfName_t + ast_ptr item; // Chain_t | Variable_t | SelfName_t AST_END(Assignable) class Value_t; @@ -280,7 +280,7 @@ AST_NODE(Exp, "Exp"_id) AST_END(Exp) AST_NODE(Callable, "Callable"_id) - ast_ptr item; // Name_t | SelfName_t | VarArg_t | Parens_t + ast_ptr item; // Variable_t | SelfName_t | VarArg_t | Parens_t AST_END(Callable) class InvokeArgs_t; @@ -359,11 +359,12 @@ AST_NODE(chain_item, "chain_item"_id) AST_END(chain_item) AST_NODE(DotChainItem, "DotChainItem"_id) - ast_ptr<_Name_t> name; + ast_ptr name; AST_END(DotChainItem) AST_NODE(ColonChainItem, "ColonChainItem"_id) - ast_ptr<_Name_t> name; + ast_ptr name; + bool switchToDot = false; AST_END(ColonChainItem) AST_NODE(chain_dot_chain, "chain_dot_chain"_id) @@ -430,7 +431,7 @@ AST_NODE(class_member_list, "class_member_list"_id) AST_END(class_member_list) AST_NODE(ClassLine, "ClassLine"_id) - ast_ptr content; // class_member_list_t | Statement_t | Exp_t + ast_ptr content; // class_member_list_t | Statement_t AST_END(ClassLine) AST_NODE(ClassBlock, "ClassBlock"_id) @@ -457,7 +458,7 @@ AST_NODE(Export, "Export"_id) AST_END(Export) AST_NODE(variable_pair, "variable_pair"_id) - ast_ptr name; + ast_ptr name; AST_END(variable_pair) AST_NODE(normal_pair, "normal_pair"_id) @@ -470,7 +471,7 @@ AST_NODE(KeyValue, "KeyValue"_id) AST_END(KeyValue) AST_NODE(FnArgDef, "FnArgDef"_id) - ast_ptr name; // Name_t | SelfName_t + ast_ptr name; // Variable_t | SelfName_t ast_ptr defaultValue; AST_END(FnArgDef) @@ -499,7 +500,7 @@ AST_NODE(FunLit, "FunLit"_id) AST_END(FunLit) AST_NODE(NameOrDestructure, "NameOrDestructure"_id) - ast_ptr item; // Name_t | TableLit_t + ast_ptr item; // Variable_t | TableLit_t AST_END(NameOrDestructure) AST_NODE(AssignableNameList, "AssignableNameList"_id) diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp index 3009ee5..ec8df38 100644 --- a/MoonParser/moon_parser.cpp +++ b/MoonParser/moon_parser.cpp @@ -20,9 +20,8 @@ rule SomeSpace = +set(" \t") >> -Comment; rule SpaceBreak = Space >> Break; rule EmptyLine = SpaceBreak; rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; -rule _Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum; -rule SpaceName = Space >> _Name; -rule _Num = +rule Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum; +rule Num = ( "0x" >> +(range('0', '9') | range('a', 'f') | range('A', 'F')) >> @@ -35,7 +34,6 @@ rule _Num = ('.' >> +range('0', '9')) ) >> -(set("eE") >> -expr('-') >> +range('0', '9')) ); -rule Num = Space >> _Num; rule Cut = false_(); rule Seperator = true_(); @@ -44,8 +42,7 @@ rule Seperator = true_(); #define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut))) #define key(str) (Space >> str >> not_(AlphaNum)) -rule Name = user(_Name, [](const item_t& item) -{ +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; @@ -57,21 +54,18 @@ rule Name = user(_Name, [](const item_t& item) }); rule self = expr('@'); -rule self_name = '@' >> _Name; +rule self_name = '@' >> Name; rule self_class = expr("@@"); -rule self_class_name = "@@" >> _Name; +rule self_class_name = "@@" >> Name; rule SelfName = Space >> (self_class_name | self_class | self_name | self); -rule KeyName = SelfName | Space >> _Name; +rule KeyName = SelfName | Space >> Name; rule VarArg = Space >> "..."; -rule check_indent = user(Indent, [](const item_t& item) -{ +rule check_indent = user(Indent, [](const item_t& item) { int indent = 0; - for (input_it i = item.begin; i != item.end; ++i) - { - switch (*i) - { + for (input_it i = item.begin; i != item.end; ++i) { + switch (*i) { case ' ': indent++; break; case '\t': indent += 4; break; } @@ -81,21 +75,17 @@ rule check_indent = user(Indent, [](const item_t& item) }); rule CheckIndent = and_(check_indent); -rule advance = user(Indent, [](const item_t& item) -{ +rule advance = user(Indent, [](const item_t& item) { int indent = 0; - for (input_it i = item.begin; i != item.end; ++i) - { - switch (*i) - { + for (input_it i = item.begin; i != item.end; ++i) { + switch (*i) { case ' ': indent++; break; case '\t': indent += 4; break; } } State* st = reinterpret_cast(item.user_data); int top = st->indents.top(); - if (top != -1 && indent > top) - { + if (top != -1 && indent > top) { st->indents.push(indent); return true; } @@ -103,13 +93,10 @@ rule advance = user(Indent, [](const item_t& item) }); rule Advance = and_(advance); -rule push_indent = user(Indent, [](const item_t& item) -{ +rule push_indent = user(Indent, [](const item_t& item) { int indent = 0; - for (input_it i = item.begin; i != item.end; ++i) - { - switch (*i) - { + for (input_it i = item.begin; i != item.end; ++i) { + switch (*i) { case ' ': indent++; break; case '\t': indent += 4; break; } @@ -120,15 +107,13 @@ rule push_indent = user(Indent, [](const item_t& item) }); rule PushIndent = and_(push_indent); -rule PreventIndent = user(true_(), [](const item_t& item) -{ +rule PreventIndent = user(true_(), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); st->indents.push(-1); return true; }); -rule PopIndent = user(true_(), [](const item_t& item) -{ +rule PopIndent = user(true_(), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); st->indents.pop(); return true; @@ -143,8 +128,8 @@ extern rule NameList; rule local_flag = expr('*') | expr('^'); rule Local = key("local") >> ((Space >> local_flag) | NameList); -rule colon_import_name = sym('\\') >> Space >> Name; -rule ImportName = colon_import_name | Space >> Name; +rule colon_import_name = sym('\\') >> Space >> Variable; +rule ImportName = colon_import_name | Space >> Variable; rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); extern rule Exp; @@ -183,7 +168,7 @@ rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *I rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; rule for_step_value = sym(',') >> Exp; -rule for_args = Space >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; +rule for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; rule For = key("for") >> DisableDo >> ensure(for_args, PopDo) >> @@ -230,7 +215,7 @@ extern rule CompForEach, CompFor, CompClause; rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause; rule star_exp = sym('*') >> Exp; rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp); -rule CompFor = key("for") >> Space >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; +rule CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; rule CompClause = CompFor | CompForEach | key("when") >> Exp; extern rule TableBlock; @@ -269,7 +254,7 @@ rule BinaryOperator = extern rule Chain; -rule Assignable = Chain | Space >> Name | SelfName; +rule Assignable = Chain | Space >> Variable | SelfName; extern rule Value; @@ -324,7 +309,7 @@ rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringCl }); rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); -rule Callable = Space >> Name | SelfName | VarArg | Parens; +rule Callable = Space >> Variable | SelfName | VarArg | Parens; rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); rule FnArgs = Seperator >> @@ -356,8 +341,8 @@ extern rule Invoke, Slice; rule Index = symx('[') >> Exp >> sym(']'); rule ChainItem = Invoke | DotChainItem | Slice | Index; -rule DotChainItem = symx('.') >> _Name; -rule ColonChainItem = symx('\\') >> _Name; +rule DotChainItem = symx('.') >> Name; +rule ColonChainItem = symx('\\') >> Name; rule invoke_chain = Invoke >> -ChainItems; rule ColonChain = ColonChainItem >> -invoke_chain; @@ -406,7 +391,7 @@ rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent) extern rule Statement; rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue); -rule ClassLine = CheckIndent >> (class_member_list | Statement | Exp) >> -sym(','); +rule ClassLine = CheckIndent >> (class_member_list | Statement) >> -sym(','); rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent; rule ClassDecl = @@ -419,7 +404,7 @@ rule export_values = NameList >> -(sym('=') >> ExpListLow); rule export_op = expr('*') | expr('^'); rule Export = key("export") >> (ClassDecl | (Space >> export_op) | export_values); -rule variable_pair = sym(':') >> not_(SomeSpace) >> Space >> Name; +rule variable_pair = sym(':') >> not_(SomeSpace) >> Space >> Variable; rule normal_pair = ( @@ -436,7 +421,7 @@ rule KeyValue = variable_pair | normal_pair; rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue); rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); -rule FnArgDef = (Space >> Name | SelfName) >> -(sym('=') >> Exp); +rule FnArgDef = (Space >> Variable | SelfName) >> -(sym('=') >> Exp); rule FnArgDefList = Seperator >> ( @@ -455,8 +440,8 @@ rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> Whit rule fn_arrow = expr("->") | expr("=>"); rule FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; -rule NameList = Seperator >> Space >> Name >> *(sym(',') >> Space >> Name); -rule NameOrDestructure = Space >> Name | TableLit; +rule NameList = Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variable); +rule NameOrDestructure = Space >> Variable | TableLit; rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure); rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp); @@ -479,18 +464,19 @@ rule InvokeArgs = TableBlock ); -rule const_value = key("nil") | key("true") | key("false"); -rule minus_exp = sym('-') >> not_(SomeSpace) >> Exp; -rule sharp_exp = sym('#') >> Exp; -rule tilde_exp = sym('~') >> Exp; -rule not_exp = key("not") >> Exp; +rule const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); +rule minus_exp = expr('-') >> not_(SomeSpace) >> Exp; +rule sharp_exp = expr('#') >> Exp; +rule tilde_exp = expr('~') >> Exp; +rule not_exp = expr("not") >> not_(AlphaNum) >> Exp; rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp; rule SimpleValue = - const_value | + (Space >> const_value) | If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | - unary_exp | - TblComprehension | TableLit | Comprehension | FunLit | Num; + (Space >> unary_exp) | + TblComprehension | TableLit | Comprehension | FunLit | + (Space >> Num); rule Assignment = ExpList >> (Update | Assign); diff --git a/MoonParser/moon_parser.h b/MoonParser/moon_parser.h index 6f9ef8f..5327b05 100644 --- a/MoonParser/moon_parser.h +++ b/MoonParser/moon_parser.h @@ -10,10 +10,8 @@ #include "parserlib.hpp" using namespace parserlib; -struct State -{ - State() - { +struct State { + State() { indents.push(0); stringOpen = -1; } -- cgit v1.2.3-55-g6feb