diff options
| author | Li Jin <dragon-fly@qq.com> | 2020-03-12 10:27:53 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2020-03-12 10:27:53 +0800 |
| commit | b2cdbc975526b710d23c41af18978afbac516240 (patch) | |
| tree | 40092d049e9e424476a548f1b3de08575fd1ac99 | |
| parent | bd5550aa0aff81eafd077cd44e6fa3e88015f6e7 (diff) | |
| download | yuescript-b2cdbc975526b710d23c41af18978afbac516240.tar.gz yuescript-b2cdbc975526b710d23c41af18978afbac516240.tar.bz2 yuescript-b2cdbc975526b710d23c41af18978afbac516240.zip | |
fix macro type mismatch issue.
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | spec/inputs/macro.moon | 40 | ||||
| -rw-r--r-- | src/MoonP/moon_compiler.cpp | 30 |
3 files changed, 63 insertions, 10 deletions
| @@ -7,4 +7,5 @@ moonplus-*.rock* | |||
| 7 | !moonplus-dev-1.rockspec | 7 | !moonplus-dev-1.rockspec |
| 8 | .vs | 8 | .vs |
| 9 | bin | 9 | bin |
| 10 | .o | 10 | src/lua-5.3/*.o |
| 11 | 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)-> | |||
| 43 | #{action}" | 43 | #{action}" |
| 44 | 44 | ||
| 45 | macro expr pipe = (...)-> | 45 | macro expr pipe = (...)-> |
| 46 | switch select "#",... | 46 | switch select "#", ... |
| 47 | when 0 then return "" | 47 | when 0 then return "" |
| 48 | when 1 then return ... | 48 | when 1 then return ... |
| 49 | ops = {...} | 49 | ops = {...} |
| @@ -53,7 +53,7 @@ macro expr pipe = (...)-> | |||
| 53 | last = "_#{i}" | 53 | last = "_#{i}" |
| 54 | stmt | 54 | stmt |
| 55 | res = "do | 55 | res = "do |
| 56 | #{table.concat stmts,"\n"} | 56 | #{table.concat stmts, "\n"} |
| 57 | #{last}" | 57 | #{last}" |
| 58 | $showMacro "pipe", res | 58 | $showMacro "pipe", res |
| 59 | 59 | ||
| @@ -68,3 +68,39 @@ val = $pipe( | |||
| 68 | $reduce(0, _1 + _2) | 68 | $reduce(0, _1 + _2) |
| 69 | ) | 69 | ) |
| 70 | 70 | ||
| 71 | macro expr plus = (a, b)-> "#{a} + #{b}" | ||
| 72 | |||
| 73 | $plus(1,2)\call 123 | ||
| 74 | |||
| 75 | macro expr curry = (...)-> | ||
| 76 | args = {...} | ||
| 77 | len = #args | ||
| 78 | body = args[len] | ||
| 79 | def = table.concat ["(#{args[i]})->" for i = 1, len - 1] | ||
| 80 | "#{def}\n#{body\gsub "^do\n",""}" | ||
| 81 | |||
| 82 | f = $curry x,y,z,do | ||
| 83 | print x,y,z | ||
| 84 | |||
| 85 | macro expr get_inner = (var)-> "do | ||
| 86 | a = 1 | ||
| 87 | a + 1" | ||
| 88 | |||
| 89 | macro expr get_inner_hygienic = (var)-> "(-> | ||
| 90 | local a = 1 | ||
| 91 | a + 1)!" | ||
| 92 | |||
| 93 | do | ||
| 94 | a = 8 | ||
| 95 | a = $get_inner! | ||
| 96 | a += $get_inner! | ||
| 97 | print a | ||
| 98 | |||
| 99 | do | ||
| 100 | a = 8 | ||
| 101 | a = $get_inner_hygienic! | ||
| 102 | a += $get_inner_hygienic! | ||
| 103 | print a | ||
| 104 | |||
| 105 | nil | ||
| 106 | |||
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: | |||
| 3017 | const auto& chainList = chainValue->items.objects(); | 3017 | const auto& chainList = chainValue->items.objects(); |
| 3018 | std::string type, codes; | 3018 | std::string type, codes; |
| 3019 | std::tie(type, codes) = expandMacroStr(chainValue); | 3019 | std::tie(type, codes) = expandMacroStr(chainValue); |
| 3020 | std::string targetType(usage == ExpUsage::Common ? "block"sv : "expr"sv); | 3020 | std::string targetType(usage != ExpUsage::Common || chainList.size() > 2 ? "expr"sv : "block"sv); |
| 3021 | if (type != targetType) { | 3021 | if (type != targetType) { |
| 3022 | throw std::logic_error(_info.errorMessage(s("macro type mismatch, "sv) + targetType + s(" expected, got "sv) + type + '.', x)); | 3022 | throw std::logic_error(_info.errorMessage(s("macro type mismatch, "sv) + targetType + s(" expected, got "sv) + type + '.', x)); |
| 3023 | } | 3023 | } |
| @@ -3026,7 +3026,11 @@ private: | |||
| 3026 | if (codes.empty()) { | 3026 | if (codes.empty()) { |
| 3027 | return {x->new_ptr<Block_t>().get(),std::move(info.codes)}; | 3027 | return {x->new_ptr<Block_t>().get(),std::move(info.codes)}; |
| 3028 | } | 3028 | } |
| 3029 | info = _parser.parse<Block_t>(codes); | 3029 | if (type == "expr"sv) { |
| 3030 | info = _parser.parse<Exp_t>(codes); | ||
| 3031 | } else { | ||
| 3032 | info = _parser.parse<Block_t>(codes); | ||
| 3033 | } | ||
| 3030 | } else { | 3034 | } else { |
| 3031 | info = _parser.parse<Exp_t>(codes); | 3035 | info = _parser.parse<Exp_t>(codes); |
| 3032 | } | 3036 | } |
| @@ -3042,9 +3046,7 @@ private: | |||
| 3042 | node->m_end.m_col = col; | 3046 | node->m_end.m_col = col; |
| 3043 | return traversal::Continue; | 3047 | return traversal::Continue; |
| 3044 | }); | 3048 | }); |
| 3045 | if (usage == ExpUsage::Common) { | 3049 | if (type == "expr"sv) { |
| 3046 | return {info.node,std::move(info.codes)}; | ||
| 3047 | } else { | ||
| 3048 | ast_ptr<false, Exp_t> exp; | 3050 | ast_ptr<false, Exp_t> exp; |
| 3049 | exp.set(info.node); | 3051 | exp.set(info.node); |
| 3050 | if (!exp->opValues.empty() || chainList.size() > 2) { | 3052 | if (!exp->opValues.empty() || chainList.size() > 2) { |
| @@ -3064,15 +3066,28 @@ private: | |||
| 3064 | exp = x->new_ptr<Exp_t>(); | 3066 | exp = x->new_ptr<Exp_t>(); |
| 3065 | exp->value.set(value); | 3067 | exp->value.set(value); |
| 3066 | } | 3068 | } |
| 3067 | return {exp.get(),std::move(info.codes)}; | 3069 | if (usage == ExpUsage::Common) { |
| 3070 | auto expList = x->new_ptr<ExpList_t>(); | ||
| 3071 | expList->exprs.push_back(exp); | ||
| 3072 | auto exps = x->new_ptr<ExpListAssign_t>(); | ||
| 3073 | exps->expList.set(expList); | ||
| 3074 | auto stmt = x->new_ptr<Statement_t>(); | ||
| 3075 | stmt->content.set(exps); | ||
| 3076 | auto block = x->new_ptr<Block_t>(); | ||
| 3077 | block->statements.push_back(stmt); | ||
| 3078 | info.node.set(block); | ||
| 3079 | } else { | ||
| 3080 | info.node.set(exp); | ||
| 3081 | } | ||
| 3068 | } | 3082 | } |
| 3083 | return {info.node,std::move(info.codes)}; | ||
| 3069 | } | 3084 | } |
| 3070 | 3085 | ||
| 3071 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 3086 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| 3072 | if (isMacroChain(chainValue)) { | 3087 | if (isMacroChain(chainValue)) { |
| 3073 | ast_ptr<false,ast_node> node; | 3088 | ast_ptr<false,ast_node> node; |
| 3074 | std::unique_ptr<input> codes; | 3089 | std::unique_ptr<input> codes; |
| 3075 | std::tie(node,codes) = expandMacro(chainValue, usage); | 3090 | std::tie(node, codes) = expandMacro(chainValue, usage); |
| 3076 | if (usage == ExpUsage::Common) { | 3091 | if (usage == ExpUsage::Common) { |
| 3077 | transformBlock(node.to<Block_t>(), out, usage, assignList); | 3092 | transformBlock(node.to<Block_t>(), out, usage, assignList); |
| 3078 | } else { | 3093 | } else { |
| @@ -4983,3 +4998,4 @@ std::tuple<std::string,std::string,GlobalVars> MoonCompiler::compile(std::string | |||
| 4983 | } | 4998 | } |
| 4984 | 4999 | ||
| 4985 | } // namespace MoonP | 5000 | } // namespace MoonP |
| 5001 | |||
