aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-03-12 10:27:53 +0800
committerLi Jin <dragon-fly@qq.com>2020-03-12 10:27:53 +0800
commitb2cdbc975526b710d23c41af18978afbac516240 (patch)
tree40092d049e9e424476a548f1b3de08575fd1ac99
parentbd5550aa0aff81eafd077cd44e6fa3e88015f6e7 (diff)
downloadyuescript-b2cdbc975526b710d23c41af18978afbac516240.tar.gz
yuescript-b2cdbc975526b710d23c41af18978afbac516240.tar.bz2
yuescript-b2cdbc975526b710d23c41af18978afbac516240.zip
fix macro type mismatch issue.
-rw-r--r--.gitignore3
-rw-r--r--spec/inputs/macro.moon40
-rw-r--r--src/MoonP/moon_compiler.cpp30
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*
7!moonplus-dev-1.rockspec 7!moonplus-dev-1.rockspec
8.vs 8.vs
9bin 9bin
10.o 10src/lua-5.3/*.o
11src/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
45macro expr pipe = (...)-> 45macro 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
71macro expr plus = (a, b)-> "#{a} + #{b}"
72
73$plus(1,2)\call 123
74
75macro 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
82f = $curry x,y,z,do
83 print x,y,z
84
85macro expr get_inner = (var)-> "do
86 a = 1
87 a + 1"
88
89macro expr get_inner_hygienic = (var)-> "(->
90 local a = 1
91 a + 1)!"
92
93do
94 a = 8
95 a = $get_inner!
96 a += $get_inner!
97 print a
98
99do
100 a = 8
101 a = $get_inner_hygienic!
102 a += $get_inner_hygienic!
103 print a
104
105nil
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