From 88c1052e700f38cf3d8ad82d469da4c487760b7e Mon Sep 17 00:00:00 2001 From: Li Jin Date: Fri, 29 May 2020 02:00:20 +0800 Subject: change operator precedence to [1].^ [2].unary operators (not, #, -, ~) [3].|> [4].*, /, //, %, ... fix destructure with one table variable to operator-value expression. fix simple chain value with Lua keyword colon chain item. --- src/MoonP/moon_ast.h | 33 ++-- src/MoonP/moon_compiler.cpp | 464 ++++++++++++++++++++++---------------------- src/MoonP/moon_parser.cpp | 37 ++-- src/MoonP/moon_parser.h | 13 +- 4 files changed, 280 insertions(+), 267 deletions(-) (limited to 'src') diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index 4918a0a..42522dd 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h @@ -341,8 +341,8 @@ AST_END(Update) AST_LEAF(BinaryOperator) AST_END(BinaryOperator) -AST_LEAF(BackcallOperator) -AST_END(BackcallOperator) +AST_LEAF(unary_operator) +AST_END(unary_operator) class AssignableChain_t; @@ -351,18 +351,19 @@ AST_NODE(Assignable) AST_MEMBER(Assignable, &item) AST_END(Assignable) -class Value_t; +class unary_exp_t; AST_NODE(exp_op_value) - ast_sel op; - ast_ptr value; - AST_MEMBER(exp_op_value, &op, &value) + ast_ptr op; + ast_list backcalls; + AST_MEMBER(exp_op_value, &op, &backcalls) AST_END(exp_op_value) AST_NODE(Exp) - ast_ptr value; + ast_ptr sep; + ast_list backcalls; ast_list opValues; - AST_MEMBER(Exp, &value, &opValues) + AST_MEMBER(Exp, &sep, &backcalls, &opValues) AST_END(Exp) class Parens_t; @@ -396,14 +397,15 @@ AST_END(simple_table) class String_t; class const_value_t; class ClassDecl_t; -class unary_exp_t; +class unary_value_t; class TableLit_t; class FunLit_t; AST_NODE(SimpleValue) ast_sel value; AST_MEMBER(SimpleValue, &value) @@ -641,9 +643,16 @@ AST_END(InvokeArgs) AST_LEAF(const_value) AST_END(const_value) +AST_NODE(unary_value) + ast_list ops; + ast_ptr value; + AST_MEMBER(unary_value, &ops, &value) +AST_END(unary_value) + AST_NODE(unary_exp) - ast_ptr item; - AST_MEMBER(unary_exp, &item) + ast_list ops; + ast_list expos; + AST_MEMBER(unary_exp, &ops, &expos) AST_END(unary_exp) AST_NODE(ExpListAssign) diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 189a428..f7462dc 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp @@ -43,7 +43,7 @@ inline std::string s(std::string_view sv) { } const std::string_view version() { - return "0.3.14"sv; + return "0.4.0"sv; } // name of table stored in lua registry @@ -407,14 +407,57 @@ private: } break; } + case id(): { + auto unary = static_cast(item); + if (unary->ops.empty() && unary->expos.size() == 1) { + return static_cast(unary->expos.back()); + } + return nullptr; + } + default: break; } if (!exp) return nullptr; - if (exp->opValues.empty()) { - return exp->value.get(); - } + BLOCK_START + BREAK_IF(!exp->opValues.empty()); + BREAK_IF(exp->backcalls.size() != 1); + auto unary = static_cast(exp->backcalls.back()); + BREAK_IF(!unary->ops.empty()); + BREAK_IF(unary->expos.size() != 1); + return static_cast(unary->expos.back()); + BLOCK_END return nullptr; } + ast_ptr newExp(Value_t* value, ast_node* x) { + auto unary = x->new_ptr(); + unary->expos.push_back(value); + auto exp = x->new_ptr(); + exp->backcalls.push_back(unary); + return exp; + } + + ast_ptr newExp(Value_t* left, BinaryOperator_t* op, Value_t* right, ast_node* x) { + auto lunary = x->new_ptr(); + lunary->expos.push_back(left); + auto opValue = x->new_ptr(); + { + auto runary = x->new_ptr(); + runary->expos.push_back(right); + opValue->op.set(op); + opValue->backcalls.push_back(runary); + } + auto exp = x->new_ptr(); + exp->backcalls.push_back(lunary); + exp->opValues.push_back(opValue); + return exp; + } + + ast_ptr newExp(unary_exp_t* unary, ast_node* x) { + auto exp = x->new_ptr(); + exp->backcalls.push_back(unary); + return exp; + } + SimpleValue_t* simpleSingleValueFrom(ast_node* expList) const { auto value = singleValueFrom(expList); if (value && value->item.is()) { @@ -423,18 +466,6 @@ private: return nullptr; } - Value_t* firstValueFrom(ast_node* item) const { - Exp_t* exp = nullptr; - if (auto expList = ast_cast(item)) { - if (!expList->exprs.empty()) { - exp = static_cast(expList->exprs.front()); - } - } else { - exp = ast_cast(item); - } - return exp->value.get(); - } - Statement_t* lastStatementFrom(Body_t* body) const { if (auto stmt = body->content.as()) { return stmt; @@ -526,7 +557,7 @@ private: BLOCK_START auto value = singleValueFrom(expList); BREAK_IF(!value); - auto chainValue = value->getByPath(); + auto chainValue = value->item.as(); BREAK_IF(!chainValue); BREAK_IF(chainValue->items.size() != 1); auto callable = ast_cast(chainValue->items.front()); @@ -542,7 +573,7 @@ private: BLOCK_START auto value = singleValueFrom(exp); BREAK_IF(!value); - auto chainValue = value->getByPath(); + auto chainValue = value->item.as(); BREAK_IF(!chainValue); BREAK_IF(chainValue->items.size() != 1); auto callable = ast_cast(chainValue->items.front()); @@ -614,18 +645,7 @@ private: } bool isPureBackcall(Exp_t* exp) const { - if (exp->opValues.empty()) { - return false; - } - bool backcall = true; - for (auto _opValue : exp->opValues.objects()) { - auto opValue = static_cast(_opValue); - if (!opValue->op.is()) { - backcall = false; - break; - } - } - return backcall; + return exp->opValues.empty() && exp->backcalls.size() > 1; } bool isMacroChain(ChainValue_t* chainValue) const { @@ -672,8 +692,7 @@ private: simpleValue->value.set(ifNode); auto value = x->new_ptr(); value->item.set(simpleValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto expList = x->new_ptr(); expList->exprs.push_back(exp); auto expListAssign = x->new_ptr(); @@ -700,8 +719,7 @@ private: simpleValue->value.set(unless); auto value = x->new_ptr(); value->item.set(simpleValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto exprList = x->new_ptr(); exprList->exprs.push_back(exp); auto expListAssign = x->new_ptr(); @@ -720,8 +738,7 @@ private: simpleValue->value.set(comp); auto value = x->new_ptr(); value->item.set(simpleValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto expList = x->new_ptr(); expList->exprs.push_back(exp); auto expListAssign = x->new_ptr(); @@ -951,8 +968,9 @@ private: checkAssignable(assignment->expList); BLOCK_START auto assign = ast_cast(assignment->action); - BREAK_IF(!assign || assign->values.objects().size() != 1); - auto value = assign->values.objects().front(); + BREAK_IF(!assign); + BREAK_IF(assign->values.objects().size() != 1); + auto value = assign->values.objects().back(); if (ast_is(value)) { if (auto val = simpleSingleValueFrom(value)) { value = val->value.get(); @@ -1046,8 +1064,9 @@ private: transformExp(exp, out, ExpUsage::Assignment, expList); return; } - BREAK_IF(!exp->opValues.empty()); - if (auto chainValue = exp->value->item.as()) { + auto singleVal = singleValueFrom(exp); + BREAK_IF(!singleVal); + if (auto chainValue = singleVal->item.as()) { auto type = specialChainValue(chainValue); auto expList = assignment->expList.get(); switch (type) { @@ -1115,7 +1134,7 @@ private: if (!defs.empty()) _buf << indent() << "local "sv << join(defs,", "sv) << nll(assignment); _buf << indent() << "do"sv << nll(assignment); pushScope(); - auto objVar = getUnusedName("_obj_"); + auto objVar = getUnusedName("_obj_"sv); for (auto& v : values) v.insert(0, objVar); _buf << indent() << "local "sv << objVar << " = "sv << destruct.value << nll(assignment); _buf << indent() << join(names, ", "sv) << " = "sv << join(values, ", "sv) << nll(assignment); @@ -1291,8 +1310,9 @@ private: str_list temp; for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) { auto expr = *i; - ast_node* destructNode = expr->getByPath(); - if (destructNode || (destructNode = expr->getByPath())) { + auto value = singleValueFrom(expr); + ast_node* destructNode = value->getByPath(); + if (destructNode || (destructNode = value->item.as())) { destructPairs.push_back({i,j}); auto& destruct = destructs.emplace_back(); if (!varDefOnly) { @@ -1304,6 +1324,10 @@ private: } auto pairs = destructFromExp(expr); destruct.items = std::move(pairs); + if (destruct.items.size() == 1 && !singleValueFrom(*j)) { + destruct.value.insert(0, "("sv); + destruct.value.append(")"sv); + } } } for (const auto& p : destructPairs) { @@ -1337,7 +1361,7 @@ private: auto leftExp = static_cast(expList->exprs.objects().front()); auto leftValue = singleValueFrom(leftExp); if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp)); - if (auto chain = leftValue->getByPath()) { + if (auto chain = leftValue->item.as()) { auto tmpChain = x->new_ptr(); for (auto item : chain->items.objects()) { bool itemAdded = false; @@ -1440,8 +1464,7 @@ private: simpleValue->value.set(newIf); auto value = x->new_ptr(); value->item.set(simpleValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto expList = x->new_ptr(); expList->exprs.push_back(exp); auto expListAssign = x->new_ptr(); @@ -1612,14 +1635,18 @@ private: out.push_back(join(temp, ", "sv)); } - ast_ptr transformBackcall(Value_t* first, node_container::const_iterator begin, node_container::const_iterator end) { - auto arg = first->new_ptr(); - arg->value.set(first); - for (auto it = begin; it != end; ++it) { - auto opValue = static_cast(*it); - if (auto chainValue = opValue->value->item.as()) { - auto newArg = first->new_ptr(); - { + void transform_backcall_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { + if (values.size() == 1 && usage == ExpUsage::Closure) { + transform_unary_exp(static_cast(values.front()), out); + } else { + auto x = values.front(); + auto arg = newExp(static_cast(x), x); + auto begin = values.begin(); begin++; + for (auto it = begin; it != values.end(); ++it) { + auto unary = static_cast(*it); + auto value = singleValueFrom(unary); + if (!value) throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, *it)); + if (auto chainValue = value->item.as()) { if (isChainValueCall(chainValue)) { auto last = chainValue->items.back(); _ast_list* args = nullptr; @@ -1647,98 +1674,65 @@ private: args->push_front(arg); } } else { - auto invoke = first->new_ptr(); + auto invoke = x->new_ptr(); invoke->args.push_front(arg); chainValue->items.push_back(invoke); } - auto value = first->new_ptr(); - value->item.set(chainValue); - newArg->value.set(value); - arg.set(newArg); + arg.set(newExp(unary, x)); + } else { + throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, value)); } - } else { - throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, opValue->value)); } - } - return arg; - } - - void transformExp(Exp_t* exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { - const auto& opValues = exp->opValues.objects(); - for (auto it = opValues.begin(); it != opValues.end(); ++it) { - auto opValue = static_cast(*it); - if (opValue->op.is()) { - auto end = std::find_if_not(it, opValues.end(), [](ast_node* node) { - return static_cast(node)->op.is(); - }); - ast_ptr backcall; - if (it == opValues.begin()) { - auto first = exp->value.get(); - backcall = transformBackcall(first, it, end); - for (auto i = end; i != opValues.end(); ++i) { - backcall->opValues.push_back(*i); - } - } else { - auto prev = it; --prev; - auto first = static_cast(*prev)->value.get(); - backcall = transformBackcall(first, it, end); - for (auto i = opValues.begin(); i != it; ++i) { - backcall->opValues.push_back(*i); - } - static_cast(backcall->opValues.back())->value.set(backcall->value); - backcall->value.set(exp->value); - for (auto i = end; i != opValues.end(); ++i) { - backcall->opValues.push_back(*i); - } + switch (usage) { + case ExpUsage::Assignment: { + auto assignment = x->new_ptr(); + auto assign = x->new_ptr(); + assign->values.push_back(arg); + assignment->action.set(assign); + assignment->expList.set(assignList); + transformAssignment(assignment, out); + return; } - auto x = exp; - switch (usage) { - case ExpUsage::Assignment: { - auto assignment = x->new_ptr(); - auto assign = x->new_ptr(); - assign->values.push_back(backcall); - assignment->action.set(assign); - assignment->expList.set(assignList); - transformAssignment(assignment, out); - return; - } - case ExpUsage::Common: { - if (backcall->opValues.empty() && backcall->value->item.is()) { - transformChainValue(backcall->value->item.to(), out, ExpUsage::Common); - } else { - transformExp(backcall, out, ExpUsage::Closure); - out.back().insert(0, indent()); - out.back().append(nlr(x)); - } - return; - } - case ExpUsage::Return: { - auto ret = x->new_ptr(); - auto expListLow = x->new_ptr(); - expListLow->exprs.push_back(backcall); - ret->valueList.set(expListLow); - transformReturn(ret, out); - return; - } - case ExpUsage::Closure: { - transformExp(backcall, out, ExpUsage::Closure); - return; + case ExpUsage::Common: { + auto value = singleValueFrom(arg); + if (value && value->item.is()) { + transformChainValue(value->item.to(), out, ExpUsage::Common); + } else { + transformExp(arg, out, ExpUsage::Closure); + out.back().insert(0, indent()); + out.back().append(nlr(x)); } - default: assert(false); return; + return; } + case ExpUsage::Return: { + auto ret = x->new_ptr(); + auto expListLow = x->new_ptr(); + expListLow->exprs.push_back(arg); + ret->valueList.set(expListLow); + transformReturn(ret, out); + return; + } + case ExpUsage::Closure: { + transformExp(arg, out, ExpUsage::Closure); + return; + } + default: assert(false); return; } } + } + + void transformExp(Exp_t* exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { + if (exp->opValues.empty()) { + transform_backcall_exp(exp->backcalls.objects(), out, usage, assignList); + return; + } assert(usage == ExpUsage::Closure); str_list temp; - transformValue(exp->value, temp); + transform_backcall_exp(exp->backcalls.objects(), temp, ExpUsage::Closure); for (auto _opValue : exp->opValues.objects()) { auto opValue = static_cast(_opValue); - if (auto op = opValue->op.as()) { - transformBinaryOperator(op, temp); - } else { - temp.push_back(s("|>"sv)); - } - transformValue(opValue->value, temp); + transformBinaryOperator(opValue->op, temp); + transform_backcall_exp(opValue->backcalls.objects(), temp, ExpUsage::Closure); } out.push_back(join(temp, " "sv)); } @@ -1748,11 +1742,7 @@ private: switch (item->getId()) { case id(): transformSimpleValue(static_cast(item), out); break; case id(): transform_simple_table(static_cast(item), out); break; - case id(): { - auto chainValue = static_cast(item); - transformChainValue(chainValue, out, ExpUsage::Closure); - break; - } + case id(): transformChainValue(static_cast(item), out, ExpUsage::Closure); break; case id(): transformString(static_cast(item), out); break; default: assert(false); break; } @@ -1812,7 +1802,7 @@ private: case id(): transformForClosure(static_cast(value), out); break; case id(): transformWhileClosure(static_cast(value), out); break; case id(): transformDo(static_cast(value), out, ExpUsage::Closure); break; - case id(): transform_unary_exp(static_cast(value), out); break; + case id(): transform_unary_value(static_cast(value), out); break; case id(): transformTblComprehension(static_cast(value), out, ExpUsage::Closure); break; case id(): transformTableLit(static_cast(value), out); break; case id(): transformComprehension(static_cast(value), out, ExpUsage::Closure); break; @@ -1904,7 +1894,7 @@ private: } } x = backcall; - auto arg = x->new_ptr(); + ast_ptr arg; { auto block = x->new_ptr(); auto next = it; ++next; @@ -1924,7 +1914,7 @@ private: simpleValue->value.set(funLit); auto value = x->new_ptr(); value->item.set(simpleValue); - arg->value.set(value); + arg = newExp(value, x); } if (isChainValueCall(backcall->value)) { auto last = backcall->value->items.back(); @@ -1962,8 +1952,7 @@ private: auto chainValue = backcall->value.get(); auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto expList = x->new_ptr(); expList->exprs.push_back(exp); auto expListAssign = x->new_ptr(); @@ -2103,8 +2092,7 @@ private: simpleValue->value.set(last->content); auto value = x->new_ptr(); value->item.set(simpleValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); assign->values.push_back(exp); } newAssignment->action.set(assign); @@ -2539,12 +2527,7 @@ private: chainValue->items.pop_back(); auto value = x->new_ptr(); value->item.set(chainValue); - auto opValue = x->new_ptr(); - opValue->op.set(toAst("!="sv, x)); - opValue->value.set(toAst("nil"sv, x)); - auto exp = x->new_ptr(); - exp->value.set(value); - exp->opValues.push_back(opValue); + auto exp = newExp(value, toAst("!="sv, x), toAst("nil"sv, x), x); parens->expr.set(exp); } switch (usage) { @@ -2555,8 +2538,7 @@ private: chainValue->items.push_back(callable); auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto assignment = x->new_ptr(); assignment->expList.set(assignList); auto assign = x->new_ptr(); @@ -2633,8 +2615,7 @@ private: } else { auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto assign = x->new_ptr(); assign->values.push_back(exp); auto expListAssign = x->new_ptr(); @@ -2665,8 +2646,7 @@ private: } auto value = x->new_ptr(); value->item.set(partOne); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto assign = x->new_ptr(); assign->values.push_back(exp); auto expListAssign = x->new_ptr(); @@ -2689,8 +2669,7 @@ private: case ExpUsage::Assignment: { auto value = x->new_ptr(); value->item.set(partTwo); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto assign = x->new_ptr(); assign->values.push_back(exp); auto assignment = x->new_ptr(); @@ -2703,8 +2682,7 @@ private: case ExpUsage::Closure: { auto value = x->new_ptr(); value->item.set(partTwo); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto ret = x->new_ptr(); auto expListLow = x->new_ptr(); expListLow->exprs.push_back(exp); @@ -2771,8 +2749,7 @@ private: { auto value = x->new_ptr(); value->item.set(baseChain); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto assign = x->new_ptr(); assign->values.push_back(exp); auto assignment = x->new_ptr(); @@ -2886,8 +2863,7 @@ private: } auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); callVar = singleVariableFrom(exp); if (callVar.empty()) { callVar = getUnusedName(s("_call_"sv)); @@ -2901,6 +2877,7 @@ private: block->statements.push_back(stmt); } } + ast_ptr nexp; { auto name = _parser.toString(colonItem->name); auto chainValue = x->new_ptr(); @@ -2920,10 +2897,9 @@ private: } auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + nexp = newExp(value, x); auto expList = x->new_ptr(); - expList->exprs.push_back(exp); + expList->exprs.push_back(nexp); auto expListAssign = x->new_ptr(); expListAssign->expList.set(expList); auto stmt = x->new_ptr(); @@ -2942,25 +2918,28 @@ private: default: break; } - auto body = x->new_ptr(); - body->content.set(block); - auto funLit = toAst("->"sv, x); - funLit->body.set(body); - auto simpleValue = x->new_ptr(); - simpleValue->value.set(funLit); - auto value = x->new_ptr(); - value->item.set(simpleValue); - auto exp = x->new_ptr(); - exp->value.set(value); - auto paren = x->new_ptr(); - paren->expr.set(exp); - auto callable = x->new_ptr(); - callable->item.set(paren); - auto chainValue = x->new_ptr(); - chainValue->items.push_back(callable); - auto invoke = x->new_ptr(); - chainValue->items.push_back(invoke); - transformChainValue(chainValue, out, ExpUsage::Closure); + if (block->statements.size() == 1) { + transformExp(nexp, out, usage, assignList); + } else { + auto body = x->new_ptr(); + body->content.set(block); + auto funLit = toAst("->"sv, x); + funLit->body.set(body); + auto simpleValue = x->new_ptr(); + simpleValue->value.set(funLit); + auto value = x->new_ptr(); + value->item.set(simpleValue); + auto exp = newExp(value, x); + auto paren = x->new_ptr(); + paren->expr.set(exp); + auto callable = x->new_ptr(); + callable->item.set(paren); + auto chainValue = x->new_ptr(); + chainValue->items.push_back(callable); + auto invoke = x->new_ptr(); + chainValue->items.push_back(invoke); + transformChainValue(chainValue, out, ExpUsage::Closure); + } return; } transformColonChainItem(colonItem, temp); @@ -3032,13 +3011,13 @@ private: } for (auto arg : *args) { std::string str; - if (auto exp = ast_cast(arg)) { - // patch for backcall operator support + // check whether arg is reassembled + // do some workaround for backcall expression + if (ast_is(arg) && arg->m_begin.m_it == arg->m_end.m_it) { + auto exp = static_cast(arg); BLOCK_START - BREAK_IF(arg->m_begin.m_line != arg->m_end.m_line || - arg->m_begin.m_col != arg->m_end.m_col); BREAK_IF(!exp->opValues.empty()); - auto chainValue = exp->getByPath(); + auto chainValue = exp->getByPath(); BREAK_IF(!chainValue); BREAK_IF(!isMacroChain(chainValue)); BREAK_IF(chainValue->items.size() != 2); @@ -3047,26 +3026,27 @@ private: str = codes; BLOCK_END if (str.empty()) { - bool multiLineStr = false; - BLOCK_START - auto value = singleValueFrom(exp); - BREAK_IF(!value); - auto lstr = value->getByPath(); - BREAK_IF(!lstr); - str = _parser.toString(lstr->content); - multiLineStr = true; - BLOCK_END - if (!multiLineStr) { - // convert sub nodes to strings in case exp is assembled - // in transform stage, the toString() function won't be able - // to convert its whole content - str = _parser.toString(exp->value); - for (auto opVal : exp->opValues.objects()) { - str += _parser.toString(opVal); - } - } + // exp is reassembled due to backcall expressions + // in transform stage, toString(exp) won't be able + // to convert its whole text content + str = _parser.toString(exp->backcalls.front()); + } + } else { + bool multiLineStr = false; + BLOCK_START + auto exp = ast_cast(arg); + BREAK_IF(!exp); + auto value = singleValueFrom(exp); + BREAK_IF(!value); + auto lstr = value->getByPath(); + BREAK_IF(!lstr); + str = _parser.toString(lstr->content); + multiLineStr = true; + BLOCK_END + if (!multiLineStr) { + str = _parser.toString(arg); } - } else str = _parser.toString(arg); + } Utils::trim(str); Utils::replace(str, "\r\n"sv, "\n"sv); lua_pushlstring(L, str.c_str(), str.size()); @@ -3160,8 +3140,7 @@ private: } auto value = x->new_ptr(); value->item.set(newChain); - exp = x->new_ptr(); - exp->value.set(value); + exp = newExp(value, x); } if (usage == ExpUsage::Common) { auto expList = x->new_ptr(); @@ -3276,13 +3255,34 @@ private: out.push_back(s("("sv) + join(temp, ", "sv) + s(")"sv)); } - void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) { - std::string op = _parser.toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it); - str_list temp{op + (op == "not"sv ? s(" "sv) : Empty)}; - transformExp(unary_exp->item, temp, ExpUsage::Closure); + void transform_unary_value(unary_value_t* unary_value, str_list& out) { + str_list temp; + for (auto _op : unary_value->ops.objects()) { + std::string op = _parser.toString(_op); + temp.push_back(op + (op == "not"sv ? s(" "sv) : Empty)); + } + transformValue(unary_value->value, temp); out.push_back(join(temp)); } + void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) { + if (unary_exp->ops.empty() && unary_exp->expos.size() == 1) { + transformValue(static_cast(unary_exp->expos.back()), out); + return; + } + std::string unary_op; + for (auto _op : unary_exp->ops.objects()) { + std::string op = _parser.toString(_op); + unary_op.append(op + (op == "not"sv ? s(" "sv) : Empty)); + } + str_list temp; + for (auto _value : unary_exp->expos.objects()) { + auto value = static_cast(_value); + transformValue(value, temp); + } + out.push_back(unary_op + join(temp, " ^ "sv)); + } + void transformVariable(Variable_t* name, str_list& out) { out.push_back(_parser.toString(name)); } @@ -3555,8 +3555,7 @@ private: sValue->value.set(pair.first); auto value = x->new_ptr(); value->item.set(sValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto expList = x->new_ptr(); expList->exprs.push_back(exp); auto assign = x->new_ptr(); @@ -3916,7 +3915,7 @@ private: if (auto dotChain = ast_cast(chain->items.back())) { className = s("\""sv) + _parser.toString(dotChain->name) + s("\""sv); } else if (auto index = ast_cast(chain->items.back())) { - if (auto name = index->getByPath()) { + if (auto name = index->getByPath()) { transformString(name, temp); className = temp.back(); temp.pop_back(); @@ -4441,8 +4440,7 @@ private: chainValue->items.push_back(callable); auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); expList->exprs.push_back(exp); } auto assignment = x->new_ptr(); @@ -4480,8 +4478,8 @@ private: for (auto _exp : expList->exprs.objects()) { auto exp = static_cast(_exp); if (!variableFrom(exp) && - !exp->getByPath() && - !exp->getByPath()) { + !exp->getByPath() && + !exp->getByPath()) { throw std::logic_error(_info.errorMessage("left hand expressions must be variables in export statement"sv, x)); } } @@ -4525,7 +4523,7 @@ private: auto assignList = toAst(_info.moduleName + s("[#"sv) + _info.moduleName + s("+1]"sv), x); assignment->expList.set(assignList); for (auto exp : expList->exprs.objects()) { - if (auto classDecl = exp->getByPath()) { + if (auto classDecl = exp->getByPath()) { if (classDecl->name && classDecl->name->item->getId() == id()) { transformClassDecl(classDecl, temp, ExpUsage::Common); auto name = _parser.toString(classDecl->name->item); @@ -4728,8 +4726,7 @@ private: chainValue->items.push_back(dotChainItem); auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); assign->values.push_back(exp); } auto callable = x->new_ptr(); @@ -4738,8 +4735,7 @@ private: chainValue->items.push_back(callable); auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); expList->exprs.push_back(exp); break; } @@ -4755,8 +4751,7 @@ private: chainValue->items.push_back(colonChain); auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); assign->values.push_back(exp); } auto callable = x->new_ptr(); @@ -4765,8 +4760,7 @@ private: chainValue->items.push_back(callable); auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); expList->exprs.push_back(exp); break; } @@ -4898,8 +4892,7 @@ private: simpleValue->value.set(tableLit); value->item.set(simpleValue); } - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); auto assignList = x->new_ptr(); assignList->exprs.push_back(exp); auto assign = x->new_ptr(); @@ -5087,8 +5080,7 @@ private: chainValue->items.push_back(callable); auto value = x->new_ptr(); value->item.set(chainValue); - auto exp = x->new_ptr(); - exp->value.set(value); + auto exp = newExp(value, x); expList->exprs.push_back(exp); } auto assignment = x->new_ptr(); diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 2d71567..25e67b3 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp @@ -292,6 +292,25 @@ MoonParser::MoonParser() { Update = Space >> update_op >> expr("=") >> Exp; + Assignable = AssignableChain | Space >> Variable | Space >> SelfName; + + unary_value = unary_operator >> *(Space >> unary_operator) >> Value; + + ExponentialOperator = expr('^'); + expo_value = Space >> ExponentialOperator >> *SpaceBreak >> Value; + expo_exp = Value >> *expo_value; + + unary_operator = + expr('-') >> not_(expr('>') | space_one) | + expr('#') | + expr('~') >> not_(space_one) | + expr("not") >> not_(AlphaNum); + unary_exp = *(Space >> unary_operator) >> expo_exp; + + BackcallOperator = expr("|>"); + backcall_value = Space >> BackcallOperator >> *SpaceBreak >> unary_exp; + backcall_exp = unary_exp >> *backcall_value; + BinaryOperator = (expr("or") >> not_(AlphaNum)) | (expr("and") >> not_(AlphaNum)) | @@ -304,14 +323,9 @@ MoonParser::MoonParser() { expr("<<") | expr(">>") | expr("//") | - set("+-*/%^><|&~"); - - BackcallOperator = expr("|>"); - - Assignable = AssignableChain | Space >> Variable | Space >> SelfName; - - exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; - Exp = Value >> *exp_op_value; + set("+-*/%><|&~"); + exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> backcall_exp; + Exp = Seperator >> backcall_exp >> *exp_op_value; ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> -InvokeArgs; @@ -520,16 +534,11 @@ MoonParser::MoonParser() { ); const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); - minus_exp = expr('-') >> not_(space_one) >> Exp; - sharp_exp = expr('#') >> Exp; - tilde_exp = expr('~') >> not_(space_one) >> Exp; - not_exp = expr("not") >> not_(AlphaNum) >> Exp; - unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp; SimpleValue = (Space >> const_value) | If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | - (Space >> unary_exp) | + (Space >> unary_value) | TblComprehension | TableLit | Comprehension | FunLit | (Space >> Num); diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h index 069fdf1..5787438 100644 --- a/src/MoonP/moon_parser.h +++ b/src/MoonP/moon_parser.h @@ -172,10 +172,12 @@ private: rule ArgLine; rule ArgBlock; rule invoke_args_with_table; - rule minus_exp; - rule sharp_exp; - rule tilde_exp; - rule not_exp; + rule BackcallOperator; + rule ExponentialOperator; + rule backcall_value; + rule backcall_exp; + rule expo_value; + rule expo_exp; rule empty_line_stop; rule Line; rule Shebang; @@ -233,7 +235,7 @@ private: AST_RULE(update_op) AST_RULE(Update) AST_RULE(BinaryOperator) - AST_RULE(BackcallOperator) + AST_RULE(unary_operator) AST_RULE(Assignable) AST_RULE(AssignableChain) AST_RULE(exp_op_value) @@ -286,6 +288,7 @@ private: AST_RULE(AssignableNameList) AST_RULE(InvokeArgs) AST_RULE(const_value) + AST_RULE(unary_value) AST_RULE(unary_exp) AST_RULE(ExpListAssign) AST_RULE(if_line) -- cgit v1.2.3-55-g6feb