diff options
author | Li Jin <dragon-fly@qq.com> | 2024-09-29 16:45:06 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2024-09-29 16:46:51 +0800 |
commit | 6af288657f5a7c43570ffbe91e1b727a4af5362d (patch) | |
tree | 72f0cb77d3fec4e6d6ab413c112278887ed44d3f | |
parent | d6d29a4288b96d42c7cabf424beb286bfbd24456 (diff) | |
download | yuescript-6af288657f5a7c43570ffbe91e1b727a4af5362d.tar.gz yuescript-6af288657f5a7c43570ffbe91e1b727a4af5362d.tar.bz2 yuescript-6af288657f5a7c43570ffbe91e1b727a4af5362d.zip |
Disallowed some semantically incorrect syntax to improve code consistency.
-rw-r--r-- | spec/inputs/upvalue_func.yue | 13 | ||||
-rw-r--r-- | spec/outputs/5.1/attrib.lua | 144 | ||||
-rw-r--r-- | src/yuescript/ast.cpp | 4 | ||||
-rw-r--r-- | src/yuescript/parser.cpp | 6 | ||||
-rw-r--r-- | src/yuescript/parser.hpp | 4 | ||||
-rw-r--r-- | src/yuescript/yue_ast.h | 2 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 58 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 2 |
8 files changed, 121 insertions, 112 deletions
diff --git a/spec/inputs/upvalue_func.yue b/spec/inputs/upvalue_func.yue index d4b3273..378bf60 100644 --- a/spec/inputs/upvalue_func.yue +++ b/spec/inputs/upvalue_func.yue | |||
@@ -208,20 +208,21 @@ GameEngine\schedule (deltaTime) -> -- closure 1 | |||
208 | -- test cases from issue | 208 | -- test cases from issue |
209 | do | 209 | do |
210 | buff_strength = (char, item) -> | 210 | buff_strength = (char, item) -> |
211 | item.buffer.strength? char.stats.strength?::ref() | 211 | item.buffer.strength? char.stats.strength?::ref! |
212 | 212 | ||
213 | local debug_env_before, debug_env_after | 213 | local debug_env_before, debug_env_after |
214 | 214 | ||
215 | exe_func = (func, env) -> | 215 | exe_func = (func, env) -> |
216 | ok, ... = try | 216 | ok, ... = try |
217 | debug_env_before(env) | 217 | debug_env_before env |
218 | func(env) | 218 | func env |
219 | debug_env_after(env) | 219 | debug_env_after env |
220 | catch ex | 220 | catch ex |
221 | -- accessing ex and error | 221 | -- accessing ex and error |
222 | error ex | 222 | error ex |
223 | return ex | 223 | -- implicit return |
224 | ex | ||
224 | if ok | 225 | if ok |
225 | return ... | 226 | return ... |
226 | else | 227 | else |
227 | os.exit(1) | 228 | os.exit 1 |
diff --git a/spec/outputs/5.1/attrib.lua b/spec/outputs/5.1/attrib.lua index c48c72c..dc1285c 100644 --- a/spec/outputs/5.1/attrib.lua +++ b/spec/outputs/5.1/attrib.lua | |||
@@ -44,18 +44,6 @@ do | |||
44 | } | 44 | } |
45 | a, b = _obj_0[1], _obj_0[2] | 45 | a, b = _obj_0[1], _obj_0[2] |
46 | end | 46 | end |
47 | local _anon_func_0 = function(_close_1, error, f, _arg_0, ...) | ||
48 | do | ||
49 | local _ok_0 = _arg_0 | ||
50 | _close_1(f) | ||
51 | if _ok_0 then | ||
52 | return ... | ||
53 | else | ||
54 | return error(...) | ||
55 | end | ||
56 | end | ||
57 | end | ||
58 | local _anon_func_1 = function() end | ||
59 | do | 47 | do |
60 | local v | 48 | local v |
61 | if flag then | 49 | if flag then |
@@ -82,28 +70,17 @@ do | |||
82 | f = _with_0 | 70 | f = _with_0 |
83 | end | 71 | end |
84 | local _close_1 = assert(getmetatable(f).__close) | 72 | local _close_1 = assert(getmetatable(f).__close) |
85 | return _anon_func_0(_close_1, error, f, pcall(_anon_func_1)) | 73 | return (function(_arg_0, ...) |
74 | local _ok_0 = _arg_0 | ||
75 | _close_1(f) | ||
76 | if _ok_0 then | ||
77 | return ... | ||
78 | else | ||
79 | return error(...) | ||
80 | end | ||
81 | end)(pcall(function() end)) | ||
86 | end)) | 82 | end)) |
87 | end | 83 | end |
88 | local _anon_func_2 = function(_close_1, d, error, _arg_0, ...) | ||
89 | do | ||
90 | local _ok_0 = _arg_0 | ||
91 | _close_1(d) | ||
92 | if _ok_0 then | ||
93 | return ... | ||
94 | else | ||
95 | return error(...) | ||
96 | end | ||
97 | end | ||
98 | end | ||
99 | local _anon_func_3 = function(a, b) | ||
100 | if a ~= nil then | ||
101 | return a | ||
102 | else | ||
103 | return b | ||
104 | end | ||
105 | end | ||
106 | local _anon_func_4 = function() end | ||
107 | do | 84 | do |
108 | local a | 85 | local a |
109 | if true then | 86 | if true then |
@@ -133,37 +110,29 @@ do | |||
133 | end | 110 | end |
134 | end | 111 | end |
135 | local d | 112 | local d |
136 | if _anon_func_3(a, b) then | 113 | if (function() |
114 | if a ~= nil then | ||
115 | return a | ||
116 | else | ||
117 | return b | ||
118 | end | ||
119 | end)() then | ||
137 | d = { | 120 | d = { |
138 | value = value | 121 | value = value |
139 | } | 122 | } |
140 | end | 123 | end |
141 | local _close_1 = assert(getmetatable(d).__close) | 124 | local _close_1 = assert(getmetatable(d).__close) |
142 | return _anon_func_2(_close_1, d, error, pcall(_anon_func_4)) | 125 | return (function(_arg_0, ...) |
126 | local _ok_0 = _arg_0 | ||
127 | _close_1(d) | ||
128 | if _ok_0 then | ||
129 | return ... | ||
130 | else | ||
131 | return error(...) | ||
132 | end | ||
133 | end)(pcall(function() end)) | ||
143 | end)) | 134 | end)) |
144 | end | 135 | end |
145 | local _anon_func_5 = function(_, _close_1, error, _arg_0, ...) | ||
146 | do | ||
147 | local _ok_0 = _arg_0 | ||
148 | _close_1(_) | ||
149 | if _ok_0 then | ||
150 | return ... | ||
151 | else | ||
152 | return error(...) | ||
153 | end | ||
154 | end | ||
155 | end | ||
156 | local _anon_func_6 = function(_, _close_2, error, _arg_0, ...) | ||
157 | do | ||
158 | local _ok_0 = _arg_0 | ||
159 | _close_2(_) | ||
160 | if _ok_0 then | ||
161 | return ... | ||
162 | else | ||
163 | return error(...) | ||
164 | end | ||
165 | end | ||
166 | end | ||
167 | do | 136 | do |
168 | local _ | 137 | local _ |
169 | do | 138 | do |
@@ -187,14 +156,30 @@ do | |||
187 | end | 156 | end |
188 | }) | 157 | }) |
189 | local _close_1 = assert(getmetatable(_).__close) | 158 | local _close_1 = assert(getmetatable(_).__close) |
190 | return _anon_func_5(_, _close_1, error, pcall(function() | 159 | return (function(_arg_0, ...) |
160 | local _ok_0 = _arg_0 | ||
161 | _close_1(_) | ||
162 | if _ok_0 then | ||
163 | return ... | ||
164 | else | ||
165 | return error(...) | ||
166 | end | ||
167 | end)(pcall(function() | ||
191 | local _ = setmetatable({ }, { | 168 | local _ = setmetatable({ }, { |
192 | __close = function() | 169 | __close = function() |
193 | return print("first") | 170 | return print("first") |
194 | end | 171 | end |
195 | }) | 172 | }) |
196 | local _close_2 = assert(getmetatable(_).__close) | 173 | local _close_2 = assert(getmetatable(_).__close) |
197 | return _anon_func_6(_, _close_2, error, pcall(function() | 174 | return (function(_arg_0, ...) |
175 | local _ok_0 = _arg_0 | ||
176 | _close_2(_) | ||
177 | if _ok_0 then | ||
178 | return ... | ||
179 | else | ||
180 | return error(...) | ||
181 | end | ||
182 | end)(pcall(function() | ||
198 | return print("third") | 183 | return print("third") |
199 | end)) | 184 | end)) |
200 | end)) | 185 | end)) |
@@ -211,29 +196,6 @@ def = function(item) | |||
211 | _defers[#_defers + 1] = item | 196 | _defers[#_defers + 1] = item |
212 | return _defers | 197 | return _defers |
213 | end | 198 | end |
214 | local _anon_func_7 = function(_, _close_1, error, _arg_0, ...) | ||
215 | do | ||
216 | local _ok_0 = _arg_0 | ||
217 | _close_1(_) | ||
218 | if _ok_0 then | ||
219 | return ... | ||
220 | else | ||
221 | return error(...) | ||
222 | end | ||
223 | end | ||
224 | end | ||
225 | local _anon_func_8 = function(_, _close_2, error, _arg_0, ...) | ||
226 | do | ||
227 | local _ok_0 = _arg_0 | ||
228 | _close_2(_) | ||
229 | if _ok_0 then | ||
230 | return ... | ||
231 | else | ||
232 | return error(...) | ||
233 | end | ||
234 | end | ||
235 | end | ||
236 | local _anon_func_9 = function() end | ||
237 | do | 199 | do |
238 | local _ = def(function() | 200 | local _ = def(function() |
239 | return print(3) | 201 | return print(3) |
@@ -252,12 +214,28 @@ do | |||
252 | return print(2) | 214 | return print(2) |
253 | end) | 215 | end) |
254 | local _close_1 = assert(getmetatable(_).__close) | 216 | local _close_1 = assert(getmetatable(_).__close) |
255 | return _anon_func_7(_, _close_1, error, pcall(function() | 217 | return (function(_arg_0, ...) |
218 | local _ok_0 = _arg_0 | ||
219 | _close_1(_) | ||
220 | if _ok_0 then | ||
221 | return ... | ||
222 | else | ||
223 | return error(...) | ||
224 | end | ||
225 | end)(pcall(function() | ||
256 | local _ = def(function() | 226 | local _ = def(function() |
257 | return print(1) | 227 | return print(1) |
258 | end) | 228 | end) |
259 | local _close_2 = assert(getmetatable(_).__close) | 229 | local _close_2 = assert(getmetatable(_).__close) |
260 | return _anon_func_8(_, _close_2, error, pcall(_anon_func_9)) | 230 | return (function(_arg_0, ...) |
231 | local _ok_0 = _arg_0 | ||
232 | _close_2(_) | ||
233 | if _ok_0 then | ||
234 | return ... | ||
235 | else | ||
236 | return error(...) | ||
237 | end | ||
238 | end)(pcall(function() end)) | ||
261 | end)) | 239 | end)) |
262 | end)) | 240 | end)) |
263 | end | 241 | end |
diff --git a/src/yuescript/ast.cpp b/src/yuescript/ast.cpp index 2bdac81..99ab8f5 100644 --- a/src/yuescript/ast.cpp +++ b/src/yuescript/ast.cpp | |||
@@ -54,8 +54,8 @@ bool ast_node::visit_child(const std::function<bool(ast_node*)>&) { | |||
54 | */ | 54 | */ |
55 | void ast_container::construct(ast_stack& st) { | 55 | void ast_container::construct(ast_stack& st) { |
56 | for (ast_member_vector::reverse_iterator it = m_members.rbegin(); | 56 | for (ast_member_vector::reverse_iterator it = m_members.rbegin(); |
57 | it != m_members.rend(); | 57 | it != m_members.rend(); |
58 | ++it) { | 58 | ++it) { |
59 | ast_member* member = *it; | 59 | ast_member* member = *it; |
60 | member->construct(st); | 60 | member->construct(st); |
61 | } | 61 | } |
diff --git a/src/yuescript/parser.cpp b/src/yuescript/parser.cpp index 5d0773c..f0ddd06 100644 --- a/src/yuescript/parser.cpp +++ b/src/yuescript/parser.cpp | |||
@@ -160,8 +160,8 @@ public: | |||
160 | // execute all the parse procs | 160 | // execute all the parse procs |
161 | void do_parse_procs(void* d) const { | 161 | void do_parse_procs(void* d) const { |
162 | for (_match_vector::const_iterator it = m_matches.begin(); | 162 | for (_match_vector::const_iterator it = m_matches.begin(); |
163 | it != m_matches.end(); | 163 | it != m_matches.end(); |
164 | ++it) { | 164 | ++it) { |
165 | const _match& m = *it; | 165 | const _match& m = *it; |
166 | parse_proc p = _private::get_parse_proc(*m.m_rule); | 166 | parse_proc p = _private::get_parse_proc(*m.m_rule); |
167 | p(m.m_begin, m.m_end, d); | 167 | p(m.m_begin, m.m_end, d); |
@@ -262,7 +262,7 @@ private: | |||
262 | bool _parse(_context& con) const { | 262 | bool _parse(_context& con) const { |
263 | for (auto it = m_string.begin(), | 263 | for (auto it = m_string.begin(), |
264 | end = m_string.end(); | 264 | end = m_string.end(); |
265 | ;) { | 265 | ;) { |
266 | if (it == end) return true; | 266 | if (it == end) return true; |
267 | if (con.end()) break; | 267 | if (con.end()) break; |
268 | if (con.symbol() != *it) break; | 268 | if (con.symbol() != *it) break; |
diff --git a/src/yuescript/parser.hpp b/src/yuescript/parser.hpp index 5ab327f..c544785 100644 --- a/src/yuescript/parser.hpp +++ b/src/yuescript/parser.hpp | |||
@@ -433,8 +433,8 @@ bool start_with(input& i, rule& g, error_list& el, void* st, void* ud); | |||
433 | template <class T> | 433 | template <class T> |
434 | T& operator<<(T& stream, const input_range& ir) { | 434 | T& operator<<(T& stream, const input_range& ir) { |
435 | for (input::const_iterator it = ir.m_begin.m_it; | 435 | for (input::const_iterator it = ir.m_begin.m_it; |
436 | it != ir.m_end.m_it; | 436 | it != ir.m_end.m_it; |
437 | ++it) { | 437 | ++it) { |
438 | stream << (typename T::char_type) * it; | 438 | stream << (typename T::char_type) * it; |
439 | } | 439 | } |
440 | return stream; | 440 | return stream; |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index cffc92d..8063517 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -277,6 +277,7 @@ AST_END(ExpList) | |||
277 | 277 | ||
278 | AST_NODE(Return) | 278 | AST_NODE(Return) |
279 | bool allowBlockMacroReturn = false; | 279 | bool allowBlockMacroReturn = false; |
280 | bool explicitReturn = true; | ||
280 | ast_sel<false, TableBlock_t, ExpListLow_t> valueList; | 281 | ast_sel<false, TableBlock_t, ExpListLow_t> valueList; |
281 | AST_MEMBER(Return, &valueList) | 282 | AST_MEMBER(Return, &valueList) |
282 | AST_END(Return) | 283 | AST_END(Return) |
@@ -766,6 +767,7 @@ AST_NODE(FunLit) | |||
766 | ast_ptr<true, FnArrow_t> arrow; | 767 | ast_ptr<true, FnArrow_t> arrow; |
767 | ast_ptr<false, Body_t> body; | 768 | ast_ptr<false, Body_t> body; |
768 | bool noRecursion = false; | 769 | bool noRecursion = false; |
770 | bool isAnon = false; | ||
769 | AST_MEMBER(FunLit, &argsDef, &defaultReturn, &arrow, &body) | 771 | AST_MEMBER(FunLit, &argsDef, &defaultReturn, &arrow, &body) |
770 | AST_END(FunLit) | 772 | AST_END(FunLit) |
771 | 773 | ||
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index b44b697..ef8e59e 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
75 | "close"s // Lua 5.4 | 75 | "close"s // Lua 5.4 |
76 | }; | 76 | }; |
77 | 77 | ||
78 | const std::string_view version = "0.25.3"sv; | 78 | const std::string_view version = "0.25.4"sv; |
79 | const std::string_view extension = "yue"sv; | 79 | const std::string_view extension = "yue"sv; |
80 | 80 | ||
81 | class CompileError : public std::logic_error { | 81 | class CompileError : public std::logic_error { |
@@ -3777,6 +3777,7 @@ private: | |||
3777 | } | 3777 | } |
3778 | case ExpUsage::Return: { | 3778 | case ExpUsage::Return: { |
3779 | auto ret = x->new_ptr<Return_t>(); | 3779 | auto ret = x->new_ptr<Return_t>(); |
3780 | ret->explicitReturn = false; | ||
3780 | auto expListLow = x->new_ptr<ExpListLow_t>(); | 3781 | auto expListLow = x->new_ptr<ExpListLow_t>(); |
3781 | expListLow->exprs.push_back(arg); | 3782 | expListLow->exprs.push_back(arg); |
3782 | ret->valueList.set(expListLow); | 3783 | ret->valueList.set(expListLow); |
@@ -4007,6 +4008,7 @@ private: | |||
4007 | auto expListLow = exp->new_ptr<ExpListLow_t>(); | 4008 | auto expListLow = exp->new_ptr<ExpListLow_t>(); |
4008 | expListLow->exprs.push_back(e); | 4009 | expListLow->exprs.push_back(e); |
4009 | auto returnNode = exp->new_ptr<Return_t>(); | 4010 | auto returnNode = exp->new_ptr<Return_t>(); |
4011 | returnNode->explicitReturn = false; | ||
4010 | returnNode->valueList.set(expListLow); | 4012 | returnNode->valueList.set(expListLow); |
4011 | transformReturn(returnNode, out); | 4013 | transformReturn(returnNode, out); |
4012 | break; | 4014 | break; |
@@ -4039,7 +4041,7 @@ private: | |||
4039 | }) != traversal::Stop; | 4041 | }) != traversal::Stop; |
4040 | } | 4042 | } |
4041 | 4043 | ||
4042 | std::optional<std::pair<std::string, str_list>> getUpValueFuncFromBlock(Block_t* block, str_list* ensureArgListInTheEnd, bool noGlobalVarPassing) { | 4044 | std::optional<std::pair<std::string, str_list>> getUpValueFuncFromBlock(Block_t* block, str_list* ensureArgListInTheEnd, bool noGlobalVarPassing, bool blockRewrite) { |
4043 | if (_funcLevel <= 1) return std::nullopt; | 4045 | if (_funcLevel <= 1) return std::nullopt; |
4044 | auto result = block->traverse([&](ast_node* node) { | 4046 | auto result = block->traverse([&](ast_node* node) { |
4045 | switch (node->get_id()) { | 4047 | switch (node->get_id()) { |
@@ -4138,6 +4140,7 @@ private: | |||
4138 | } | 4140 | } |
4139 | } | 4141 | } |
4140 | auto funLit = toAst<FunLit_t>("("s + join(args, ","sv) + ")-> nil"s, x); | 4142 | auto funLit = toAst<FunLit_t>("("s + join(args, ","sv) + ")-> nil"s, x); |
4143 | funLit->isAnon = blockRewrite ? false : true; | ||
4141 | funLit->body->content.set(newBlock); | 4144 | funLit->body->content.set(newBlock); |
4142 | funLit->noRecursion = true; | 4145 | funLit->noRecursion = true; |
4143 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 4146 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
@@ -4159,16 +4162,17 @@ private: | |||
4159 | return std::nullopt; | 4162 | return std::nullopt; |
4160 | } | 4163 | } |
4161 | 4164 | ||
4162 | std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Block_t* block, str_list* ensureArgListInTheEnd = nullptr, bool noGlobalVarPassing = false) { | 4165 | std::optional<std::pair<std::string, str_list>> upValueFuncFromBlock(Block_t* block, str_list* ensureArgListInTheEnd, bool noGlobalVarPassing, bool blockRewrite) { |
4163 | if (checkUpValueFuncAvailable(block)) { | 4166 | if (checkUpValueFuncAvailable(block)) { |
4164 | return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, noGlobalVarPassing); | 4167 | return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, noGlobalVarPassing, blockRewrite); |
4165 | } | 4168 | } |
4166 | return std::nullopt; | 4169 | return std::nullopt; |
4167 | } | 4170 | } |
4168 | 4171 | ||
4169 | std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Exp_t* exp, str_list* ensureArgListInTheEnd = nullptr) { | 4172 | std::optional<std::pair<std::string, str_list>> upValueFuncFromExp(Exp_t* exp, str_list* ensureArgListInTheEnd, bool blockRewrite) { |
4170 | if (checkUpValueFuncAvailable(exp)) { | 4173 | if (checkUpValueFuncAvailable(exp)) { |
4171 | auto returnNode = exp->new_ptr<Return_t>(); | 4174 | auto returnNode = exp->new_ptr<Return_t>(); |
4175 | returnNode->explicitReturn = false; | ||
4172 | auto returnList = exp->new_ptr<ExpListLow_t>(); | 4176 | auto returnList = exp->new_ptr<ExpListLow_t>(); |
4173 | returnList->exprs.push_back(exp); | 4177 | returnList->exprs.push_back(exp); |
4174 | returnNode->valueList.set(returnList); | 4178 | returnNode->valueList.set(returnList); |
@@ -4176,13 +4180,13 @@ private: | |||
4176 | auto stmt = exp->new_ptr<Statement_t>(); | 4180 | auto stmt = exp->new_ptr<Statement_t>(); |
4177 | stmt->content.set(returnNode); | 4181 | stmt->content.set(returnNode); |
4178 | block->statements.push_back(stmt); | 4182 | block->statements.push_back(stmt); |
4179 | return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false); | 4183 | return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite); |
4180 | } | 4184 | } |
4181 | return std::nullopt; | 4185 | return std::nullopt; |
4182 | } | 4186 | } |
4183 | 4187 | ||
4184 | bool transformAsUpValueFunc(Exp_t* exp, str_list& out) { | 4188 | bool transformAsUpValueFunc(Exp_t* exp, str_list& out) { |
4185 | auto result = upValueFuncFrom(exp); | 4189 | auto result = upValueFuncFromExp(exp, nullptr, false); |
4186 | if (result) { | 4190 | if (result) { |
4187 | auto [funcName, args] = std::move(*result); | 4191 | auto [funcName, args] = std::move(*result); |
4188 | auto newChainValue = toAst<ChainValue_t>(funcName + '(' + join(args, ","sv) + ')', exp); | 4192 | auto newChainValue = toAst<ChainValue_t>(funcName + '(' + join(args, ","sv) + ')', exp); |
@@ -4258,6 +4262,7 @@ private: | |||
4258 | _buf << indent() << "else"s << nll(x); | 4262 | _buf << indent() << "else"s << nll(x); |
4259 | temp.push_back(clearBuf()); | 4263 | temp.push_back(clearBuf()); |
4260 | auto ret = x->new_ptr<Return_t>(); | 4264 | auto ret = x->new_ptr<Return_t>(); |
4265 | ret->explicitReturn = false; | ||
4261 | auto retList = x->new_ptr<ExpListLow_t>(); | 4266 | auto retList = x->new_ptr<ExpListLow_t>(); |
4262 | retList->exprs.push_back(exp->nilCoalesed); | 4267 | retList->exprs.push_back(exp->nilCoalesed); |
4263 | ret->valueList.set(retList); | 4268 | ret->valueList.set(retList); |
@@ -4385,7 +4390,11 @@ private: | |||
4385 | } | 4390 | } |
4386 | 4391 | ||
4387 | void transformFunLit(FunLit_t* funLit, str_list& out) { | 4392 | void transformFunLit(FunLit_t* funLit, str_list& out) { |
4388 | pushUserFunctionScope(); | 4393 | if (funLit->isAnon) { |
4394 | pushAnonFunctionScope(); | ||
4395 | } else { | ||
4396 | pushUserFunctionScope(); | ||
4397 | } | ||
4389 | _varArgs.push({false, false}); | 4398 | _varArgs.push({false, false}); |
4390 | bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; | 4399 | bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; |
4391 | pushScope(); | 4400 | pushScope(); |
@@ -4419,6 +4428,7 @@ private: | |||
4419 | } | 4428 | } |
4420 | if (funLit->defaultReturn.is<ExpListLow_t>()) { | 4429 | if (funLit->defaultReturn.is<ExpListLow_t>()) { |
4421 | auto returnNode = newBlock->new_ptr<Return_t>(); | 4430 | auto returnNode = newBlock->new_ptr<Return_t>(); |
4431 | returnNode->explicitReturn = false; | ||
4422 | returnNode->valueList.set(funLit->defaultReturn); | 4432 | returnNode->valueList.set(funLit->defaultReturn); |
4423 | auto stmt = newBlock->new_ptr<Statement_t>(); | 4433 | auto stmt = newBlock->new_ptr<Statement_t>(); |
4424 | stmt->content.set(returnNode); | 4434 | stmt->content.set(returnNode); |
@@ -4594,7 +4604,7 @@ private: | |||
4594 | transformBlock(newBlock, out, usage, assignList, isRoot); | 4604 | transformBlock(newBlock, out, usage, assignList, isRoot); |
4595 | return; | 4605 | return; |
4596 | } else if (auto expListAssign = stmt->content.as<ExpListAssign_t>(); | 4606 | } else if (auto expListAssign = stmt->content.as<ExpListAssign_t>(); |
4597 | expListAssign && expListAssign->action && expListAssign->action.is<Assign_t>()) { | 4607 | expListAssign && expListAssign->action && expListAssign->action.is<Assign_t>()) { |
4598 | BLOCK_START | 4608 | BLOCK_START |
4599 | auto unary = singleUnaryExpFrom(expListAssign->expList->exprs.back()); | 4609 | auto unary = singleUnaryExpFrom(expListAssign->expList->exprs.back()); |
4600 | BREAK_IF(!unary); | 4610 | BREAK_IF(!unary); |
@@ -4693,7 +4703,7 @@ private: | |||
4693 | doNode->body.set(newBody); | 4703 | doNode->body.set(newBody); |
4694 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 4704 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
4695 | simpleValue->value.set(doNode); | 4705 | simpleValue->value.set(doNode); |
4696 | if (auto result = upValueFuncFrom(newExp(simpleValue, x), &argNames)) { | 4706 | if (auto result = upValueFuncFromExp(newExp(simpleValue, x), &argNames, true)) { |
4697 | auto [funcName, args] = std::move(*result); | 4707 | auto [funcName, args] = std::move(*result); |
4698 | str_list finalArgs; | 4708 | str_list finalArgs; |
4699 | for (const auto& arg : args) { | 4709 | for (const auto& arg : args) { |
@@ -4903,6 +4913,7 @@ private: | |||
4903 | auto expListLow = x->new_ptr<ExpListLow_t>(); | 4913 | auto expListLow = x->new_ptr<ExpListLow_t>(); |
4904 | expListLow->exprs.dup(expList->exprs); | 4914 | expListLow->exprs.dup(expList->exprs); |
4905 | auto returnNode = x->new_ptr<Return_t>(); | 4915 | auto returnNode = x->new_ptr<Return_t>(); |
4916 | returnNode->explicitReturn = false; | ||
4906 | returnNode->valueList.set(expListLow); | 4917 | returnNode->valueList.set(expListLow); |
4907 | returnNode->allowBlockMacroReturn = true; | 4918 | returnNode->allowBlockMacroReturn = true; |
4908 | last->content.set(returnNode); | 4919 | last->content.set(returnNode); |
@@ -5258,6 +5269,11 @@ private: | |||
5258 | if (!target) target = returnNode; | 5269 | if (!target) target = returnNode; |
5259 | throw CompileError("can not mix use of return and export statements in module scope"sv, target); | 5270 | throw CompileError("can not mix use of return and export statements in module scope"sv, target); |
5260 | } | 5271 | } |
5272 | if (returnNode->explicitReturn && _funcStates.top().isAnon) { | ||
5273 | ast_node* target = returnNode->valueList.get(); | ||
5274 | if (!target) target = returnNode; | ||
5275 | throw CompileError("explicit return statement is not allowed in this context"sv, target); | ||
5276 | } | ||
5261 | if (auto valueList = returnNode->valueList.as<ExpListLow_t>()) { | 5277 | if (auto valueList = returnNode->valueList.as<ExpListLow_t>()) { |
5262 | if (valueList->exprs.size() == 1) { | 5278 | if (valueList->exprs.size() == 1) { |
5263 | auto exp = static_cast<Exp_t*>(valueList->exprs.back()); | 5279 | auto exp = static_cast<Exp_t*>(valueList->exprs.back()); |
@@ -5712,6 +5728,7 @@ private: | |||
5712 | case ExpUsage::Closure: { | 5728 | case ExpUsage::Closure: { |
5713 | auto exp = newExp(partTwo, x); | 5729 | auto exp = newExp(partTwo, x); |
5714 | auto ret = x->new_ptr<Return_t>(); | 5730 | auto ret = x->new_ptr<Return_t>(); |
5731 | ret->explicitReturn = false; | ||
5715 | auto expListLow = x->new_ptr<ExpListLow_t>(); | 5732 | auto expListLow = x->new_ptr<ExpListLow_t>(); |
5716 | expListLow->exprs.push_back(exp); | 5733 | expListLow->exprs.push_back(exp); |
5717 | ret->valueList.set(expListLow); | 5734 | ret->valueList.set(expListLow); |
@@ -5810,6 +5827,7 @@ private: | |||
5810 | case ExpUsage::Closure: | 5827 | case ExpUsage::Closure: |
5811 | case ExpUsage::Return: { | 5828 | case ExpUsage::Return: { |
5812 | auto returnNode = x->new_ptr<Return_t>(); | 5829 | auto returnNode = x->new_ptr<Return_t>(); |
5830 | returnNode->explicitReturn = false; | ||
5813 | auto expListLow = x->new_ptr<ExpListLow_t>(); | 5831 | auto expListLow = x->new_ptr<ExpListLow_t>(); |
5814 | expListLow->exprs.push_back(funLit); | 5832 | expListLow->exprs.push_back(funLit); |
5815 | returnNode->valueList.set(expListLow); | 5833 | returnNode->valueList.set(expListLow); |
@@ -5944,6 +5962,7 @@ private: | |||
5944 | switch (usage) { | 5962 | switch (usage) { |
5945 | case ExpUsage::Closure: { | 5963 | case ExpUsage::Closure: { |
5946 | auto returnNode = x->new_ptr<Return_t>(); | 5964 | auto returnNode = x->new_ptr<Return_t>(); |
5965 | returnNode->explicitReturn = false; | ||
5947 | auto values = x->new_ptr<ExpListLow_t>(); | 5966 | auto values = x->new_ptr<ExpListLow_t>(); |
5948 | values->exprs.push_back(newChainExp); | 5967 | values->exprs.push_back(newChainExp); |
5949 | returnNode->valueList.set(values); | 5968 | returnNode->valueList.set(values); |
@@ -5957,6 +5976,7 @@ private: | |||
5957 | } | 5976 | } |
5958 | case ExpUsage::Return: { | 5977 | case ExpUsage::Return: { |
5959 | auto returnNode = x->new_ptr<Return_t>(); | 5978 | auto returnNode = x->new_ptr<Return_t>(); |
5979 | returnNode->explicitReturn = false; | ||
5960 | auto values = x->new_ptr<ExpListLow_t>(); | 5980 | auto values = x->new_ptr<ExpListLow_t>(); |
5961 | values->exprs.push_back(newChainExp); | 5981 | values->exprs.push_back(newChainExp); |
5962 | returnNode->valueList.set(values); | 5982 | returnNode->valueList.set(values); |
@@ -6629,6 +6649,7 @@ private: | |||
6629 | auto expListLow = x->new_ptr<ExpListLow_t>(); | 6649 | auto expListLow = x->new_ptr<ExpListLow_t>(); |
6630 | expListLow->exprs.push_back(node); | 6650 | expListLow->exprs.push_back(node); |
6631 | auto returnNode = x->new_ptr<Return_t>(); | 6651 | auto returnNode = x->new_ptr<Return_t>(); |
6652 | returnNode->explicitReturn = false; | ||
6632 | returnNode->valueList.set(expListLow); | 6653 | returnNode->valueList.set(expListLow); |
6633 | transformReturn(returnNode, out); | 6654 | transformReturn(returnNode, out); |
6634 | break; | 6655 | break; |
@@ -7612,6 +7633,7 @@ private: | |||
7612 | simpleValue->value.set(tableLit); | 7633 | simpleValue->value.set(tableLit); |
7613 | auto exp = newExp(simpleValue, x); | 7634 | auto exp = newExp(simpleValue, x); |
7614 | auto returnNode = x->new_ptr<Return_t>(); | 7635 | auto returnNode = x->new_ptr<Return_t>(); |
7636 | returnNode->explicitReturn = false; | ||
7615 | auto expList = x->new_ptr<ExpListLow_t>(); | 7637 | auto expList = x->new_ptr<ExpListLow_t>(); |
7616 | expList->exprs.push_back(exp); | 7638 | expList->exprs.push_back(exp); |
7617 | returnNode->valueList.set(expList); | 7639 | returnNode->valueList.set(expList); |
@@ -8296,6 +8318,7 @@ private: | |||
8296 | } else { | 8318 | } else { |
8297 | auto accum = transformForInner(forNode, temp); | 8319 | auto accum = transformForInner(forNode, temp); |
8298 | auto returnNode = x->new_ptr<Return_t>(); | 8320 | auto returnNode = x->new_ptr<Return_t>(); |
8321 | returnNode->explicitReturn = false; | ||
8299 | auto expListLow = toAst<ExpListLow_t>(accum, x); | 8322 | auto expListLow = toAst<ExpListLow_t>(accum, x); |
8300 | returnNode->valueList.set(expListLow); | 8323 | returnNode->valueList.set(expListLow); |
8301 | transformReturn(returnNode, temp); | 8324 | transformReturn(returnNode, temp); |
@@ -8395,6 +8418,7 @@ private: | |||
8395 | } else { | 8418 | } else { |
8396 | auto accum = transformForEachInner(forEach, temp); | 8419 | auto accum = transformForEachInner(forEach, temp); |
8397 | auto returnNode = x->new_ptr<Return_t>(); | 8420 | auto returnNode = x->new_ptr<Return_t>(); |
8421 | returnNode->explicitReturn = false; | ||
8398 | auto expListLow = toAst<ExpListLow_t>(accum, x); | 8422 | auto expListLow = toAst<ExpListLow_t>(accum, x); |
8399 | returnNode->valueList.set(expListLow); | 8423 | returnNode->valueList.set(expListLow); |
8400 | transformReturn(returnNode, temp); | 8424 | transformReturn(returnNode, temp); |
@@ -9618,11 +9642,13 @@ private: | |||
9618 | auto x = tryNode; | 9642 | auto x = tryNode; |
9619 | ast_ptr<true, Exp_t> errHandler; | 9643 | ast_ptr<true, Exp_t> errHandler; |
9620 | if (tryNode->catchBlock) { | 9644 | if (tryNode->catchBlock) { |
9621 | auto errHandleStr = "("s + variableToString(tryNode->catchBlock->err) + ")->"s; | 9645 | auto catchBlock = tryNode->catchBlock.get(); |
9622 | errHandler.set(toAst<Exp_t>(errHandleStr, x->func)); | 9646 | auto errHandleStr = "("s + variableToString(catchBlock->err) + ")->"s; |
9647 | errHandler.set(toAst<Exp_t>(errHandleStr, catchBlock)); | ||
9623 | auto funLit = simpleSingleValueFrom(errHandler)->value.to<FunLit_t>(); | 9648 | auto funLit = simpleSingleValueFrom(errHandler)->value.to<FunLit_t>(); |
9624 | auto body = x->new_ptr<Body_t>(); | 9649 | funLit->isAnon = true; |
9625 | body->content.set(tryNode->catchBlock->block); | 9650 | auto body = catchBlock->block->new_ptr<Body_t>(); |
9651 | body->content.set(catchBlock->block); | ||
9626 | funLit->body.set(body); | 9652 | funLit->body.set(body); |
9627 | } | 9653 | } |
9628 | ast_sel<false, Block_t, Exp_t> tryFunc; | 9654 | ast_sel<false, Block_t, Exp_t> tryFunc; |
@@ -9700,7 +9726,7 @@ private: | |||
9700 | } | 9726 | } |
9701 | if (auto tryBlock = tryFunc.as<Block_t>()) { | 9727 | if (auto tryBlock = tryFunc.as<Block_t>()) { |
9702 | if (getLuaTarget(tryBlock) >= 502 || !errHandler) { | 9728 | if (getLuaTarget(tryBlock) >= 502 || !errHandler) { |
9703 | if (auto result = upValueFuncFrom(tryBlock, nullptr, true)) { | 9729 | if (auto result = upValueFuncFromBlock(tryBlock, nullptr, true, false)) { |
9704 | auto [funcName, args] = std::move(*result); | 9730 | auto [funcName, args] = std::move(*result); |
9705 | if (errHandler) { | 9731 | if (errHandler) { |
9706 | auto xpcall = toAst<ChainValue_t>("xpcall()", x); | 9732 | auto xpcall = toAst<ChainValue_t>("xpcall()", x); |
@@ -9729,6 +9755,7 @@ private: | |||
9729 | } | 9755 | } |
9730 | auto tryExp = toAst<Exp_t>("->"sv, x); | 9756 | auto tryExp = toAst<Exp_t>("->"sv, x); |
9731 | auto funLit = simpleSingleValueFrom(tryExp)->value.to<FunLit_t>(); | 9757 | auto funLit = simpleSingleValueFrom(tryExp)->value.to<FunLit_t>(); |
9758 | funLit->isAnon = true; | ||
9732 | auto body = x->new_ptr<Body_t>(); | 9759 | auto body = x->new_ptr<Body_t>(); |
9733 | body->content.set(tryBlock); | 9760 | body->content.set(tryBlock); |
9734 | funLit->body.set(body); | 9761 | funLit->body.set(body); |
@@ -9762,6 +9789,7 @@ private: | |||
9762 | if (errHandler && getLuaTarget(x) < 502) { | 9789 | if (errHandler && getLuaTarget(x) < 502) { |
9763 | auto tryExp = toAst<Exp_t>("->"sv, x); | 9790 | auto tryExp = toAst<Exp_t>("->"sv, x); |
9764 | auto funLit = simpleSingleValueFrom(tryExp)->value.to<FunLit_t>(); | 9791 | auto funLit = simpleSingleValueFrom(tryExp)->value.to<FunLit_t>(); |
9792 | funLit->isAnon = true; | ||
9765 | auto expList = x->new_ptr<ExpList_t>(); | 9793 | auto expList = x->new_ptr<ExpList_t>(); |
9766 | expList->exprs.push_back(tryFunc); | 9794 | expList->exprs.push_back(tryFunc); |
9767 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 9795 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 93787cd..d7af780 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -1167,7 +1167,7 @@ std::string ParseInfo::errorMessage(std::string_view msg, int errLine, int errCo | |||
1167 | } | 1167 | } |
1168 | auto line = Converter{}.to_bytes(std::wstring(begin, end)); | 1168 | auto line = Converter{}.to_bytes(std::wstring(begin, end)); |
1169 | while (col < static_cast<int>(line.size()) | 1169 | while (col < static_cast<int>(line.size()) |
1170 | && (line[col] == ' ' || line[col] == '\t')) { | 1170 | && (line[col] == ' ' || line[col] == '\t')) { |
1171 | col++; | 1171 | col++; |
1172 | } | 1172 | } |
1173 | Utils::replace(line, "\t"sv, " "sv); | 1173 | Utils::replace(line, "\t"sv, " "sv); |