From b2cdbc975526b710d23c41af18978afbac516240 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Thu, 12 Mar 2020 10:27:53 +0800 Subject: fix macro type mismatch issue. --- .gitignore | 3 ++- spec/inputs/macro.moon | 40 ++++++++++++++++++++++++++++++++++++++-- src/MoonP/moon_compiler.cpp | 30 +++++++++++++++++++++++------- 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 77a4b57..a1e491d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ moonplus-*.rock* !moonplus-dev-1.rockspec .vs bin -.o +src/lua-5.3/*.o +src/lua-5.3/*.a diff --git a/spec/inputs/macro.moon b/spec/inputs/macro.moon index db03a10..07ac7b3 100644 --- a/spec/inputs/macro.moon +++ b/spec/inputs/macro.moon @@ -43,7 +43,7 @@ macro block foreach = (items,action)-> #{action}" macro expr pipe = (...)-> - switch select "#",... + switch select "#", ... when 0 then return "" when 1 then return ... ops = {...} @@ -53,7 +53,7 @@ macro expr pipe = (...)-> last = "_#{i}" stmt res = "do -#{table.concat stmts,"\n"} +#{table.concat stmts, "\n"} #{last}" $showMacro "pipe", res @@ -68,3 +68,39 @@ val = $pipe( $reduce(0, _1 + _2) ) +macro expr plus = (a, b)-> "#{a} + #{b}" + +$plus(1,2)\call 123 + +macro expr curry = (...)-> + args = {...} + len = #args + body = args[len] + def = table.concat ["(#{args[i]})->" for i = 1, len - 1] + "#{def}\n#{body\gsub "^do\n",""}" + +f = $curry x,y,z,do + print x,y,z + +macro expr get_inner = (var)-> "do + a = 1 + a + 1" + +macro expr get_inner_hygienic = (var)-> "(-> + local a = 1 + a + 1)!" + +do + a = 8 + a = $get_inner! + a += $get_inner! + print a + +do + a = 8 + a = $get_inner_hygienic! + a += $get_inner_hygienic! + print a + +nil + diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 046bf28..3a326b1 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp @@ -3017,7 +3017,7 @@ private: const auto& chainList = chainValue->items.objects(); std::string type, codes; std::tie(type, codes) = expandMacroStr(chainValue); - std::string targetType(usage == ExpUsage::Common ? "block"sv : "expr"sv); + std::string targetType(usage != ExpUsage::Common || chainList.size() > 2 ? "expr"sv : "block"sv); if (type != targetType) { throw std::logic_error(_info.errorMessage(s("macro type mismatch, "sv) + targetType + s(" expected, got "sv) + type + '.', x)); } @@ -3026,7 +3026,11 @@ private: if (codes.empty()) { return {x->new_ptr().get(),std::move(info.codes)}; } - info = _parser.parse(codes); + if (type == "expr"sv) { + info = _parser.parse(codes); + } else { + info = _parser.parse(codes); + } } else { info = _parser.parse(codes); } @@ -3042,9 +3046,7 @@ private: node->m_end.m_col = col; return traversal::Continue; }); - if (usage == ExpUsage::Common) { - return {info.node,std::move(info.codes)}; - } else { + if (type == "expr"sv) { ast_ptr exp; exp.set(info.node); if (!exp->opValues.empty() || chainList.size() > 2) { @@ -3064,15 +3066,28 @@ private: exp = x->new_ptr(); exp->value.set(value); } - return {exp.get(),std::move(info.codes)}; + if (usage == ExpUsage::Common) { + auto expList = x->new_ptr(); + expList->exprs.push_back(exp); + auto exps = x->new_ptr(); + exps->expList.set(expList); + auto stmt = x->new_ptr(); + stmt->content.set(exps); + auto block = x->new_ptr(); + block->statements.push_back(stmt); + info.node.set(block); + } else { + info.node.set(exp); + } } + return {info.node,std::move(info.codes)}; } void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { if (isMacroChain(chainValue)) { ast_ptr node; std::unique_ptr codes; - std::tie(node,codes) = expandMacro(chainValue, usage); + std::tie(node, codes) = expandMacro(chainValue, usage); if (usage == ExpUsage::Common) { transformBlock(node.to(), out, usage, assignList); } else { @@ -4983,3 +4998,4 @@ std::tuple MoonCompiler::compile(std::string } } // namespace MoonP + -- cgit v1.2.3-55-g6feb