diff options
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | spec/inputs/assign.yue | 18 | ||||
-rw-r--r-- | spec/outputs/assign.lua | 25 | ||||
-rw-r--r-- | spec/outputs/codes_from_doc.lua | 18 | ||||
-rw-r--r-- | spec/outputs/codes_from_doc_zh.lua | 18 | ||||
-rw-r--r-- | spec/outputs/macro.lua | 24 | ||||
-rw-r--r-- | spec/outputs/plus.lua | 3 | ||||
-rw-r--r-- | spec/outputs/unicode/macro.lua | 6 | ||||
-rw-r--r-- | spec/outputs/unicode/plus.lua | 3 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 78 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 2 | ||||
-rw-r--r-- | src/yuescript/yuescript.h | 8 |
12 files changed, 123 insertions, 82 deletions
@@ -1,6 +1,6 @@ | |||
1 | MIT License | 1 | MIT License |
2 | 2 | ||
3 | Copyright (c) 2017-2025 Li Jin | 3 | Copyright (c) 2017-2025 Li Jin <dragon-fly@qq.com> |
4 | 4 | ||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy |
6 | of this software and associated documentation files (the "Software"), to deal | 6 | of this software and associated documentation files (the "Software"), to deal |
diff --git a/spec/inputs/assign.yue b/spec/inputs/assign.yue index 514aeed..ad1eda3 100644 --- a/spec/inputs/assign.yue +++ b/spec/inputs/assign.yue | |||
@@ -109,4 +109,22 @@ do | |||
109 | val = 123 | 109 | val = 123 |
110 | a = b = c = val | 110 | a = b = c = val |
111 | 111 | ||
112 | do | ||
113 | -- update | ||
114 | a ..= "abc" | ||
115 | a //= 2 | ||
116 | a or= def | ||
117 | a and= false | ||
118 | a >>= 10 | ||
119 | a <<= 10 | ||
120 | a.b.c ??= 123 | ||
121 | a.b.c += 1 | ||
122 | a.b.c -= 2 | ||
123 | a.b.c *= 3 | ||
124 | a.b.c /= 4 | ||
125 | a.b.c %= 5 | ||
126 | a &= 6 | ||
127 | a |= 7 | ||
128 | a ^= 8 | ||
129 | |||
112 | nil | 130 | nil |
diff --git a/spec/outputs/assign.lua b/spec/outputs/assign.lua index 162a563..f889865 100644 --- a/spec/outputs/assign.lua +++ b/spec/outputs/assign.lua | |||
@@ -181,5 +181,30 @@ return _(function() | |||
181 | local b = val | 181 | local b = val |
182 | local c = val | 182 | local c = val |
183 | end | 183 | end |
184 | do | ||
185 | local a = a .. "abc" | ||
186 | a = a // 2 | ||
187 | a = a or def | ||
188 | a = a and false | ||
189 | a = a >> 10 | ||
190 | a = a << 10 | ||
191 | local _obj_0 = a.b | ||
192 | if _obj_0.c == nil then | ||
193 | _obj_0.c = 123 | ||
194 | end | ||
195 | local _obj_1 = a.b | ||
196 | _obj_1.c = _obj_1.c + 1 | ||
197 | local _obj_2 = a.b | ||
198 | _obj_2.c = _obj_2.c - 2 | ||
199 | local _obj_3 = a.b | ||
200 | _obj_3.c = _obj_3.c * 3 | ||
201 | local _obj_4 = a.b | ||
202 | _obj_4.c = _obj_4.c / 4 | ||
203 | local _obj_5 = a.b | ||
204 | _obj_5.c = _obj_5.c % 5 | ||
205 | a = a & 6 | ||
206 | a = a | 7 | ||
207 | a = a ^ 8 | ||
208 | end | ||
184 | return nil | 209 | return nil |
185 | end) | 210 | end) |
diff --git a/spec/outputs/codes_from_doc.lua b/spec/outputs/codes_from_doc.lua index 74db469..a37b459 100644 --- a/spec/outputs/codes_from_doc.lua +++ b/spec/outputs/codes_from_doc.lua | |||
@@ -467,8 +467,7 @@ local x = f() | |||
467 | local y = x | 467 | local y = x |
468 | local z = x | 468 | local z = x |
469 | do | 469 | do |
470 | local a | 470 | local a = 1 |
471 | a = 1 | ||
472 | local x, y, z | 471 | local x, y, z |
473 | print("forward declare all variables as locals") | 472 | print("forward declare all variables as locals") |
474 | x = function() | 473 | x = function() |
@@ -478,8 +477,7 @@ do | |||
478 | instance = Item:new() | 477 | instance = Item:new() |
479 | end | 478 | end |
480 | do | 479 | do |
481 | local X | 480 | local X = 1 |
482 | X = 1 | ||
483 | local B | 481 | local B |
484 | print("only forward declare upper case variables") | 482 | print("only forward declare upper case variables") |
485 | local a = 1 | 483 | local a = 1 |
@@ -499,8 +497,7 @@ do | |||
499 | print("only declare upper case variables as globals") | 497 | print("only declare upper case variables as globals") |
500 | local a = 1 | 498 | local a = 1 |
501 | local B = 2 | 499 | local B = 2 |
502 | local Temp | 500 | local Temp = "a local value" |
503 | Temp = "a local value" | ||
504 | end | 501 | end |
505 | local thing = { | 502 | local thing = { |
506 | 1, | 503 | 1, |
@@ -2478,8 +2475,7 @@ local x = f() | |||
2478 | local y = x | 2475 | local y = x |
2479 | local z = x | 2476 | local z = x |
2480 | do | 2477 | do |
2481 | local a | 2478 | local a = 1 |
2482 | a = 1 | ||
2483 | local x, y, z | 2479 | local x, y, z |
2484 | print("forward declare all variables as locals") | 2480 | print("forward declare all variables as locals") |
2485 | x = function() | 2481 | x = function() |
@@ -2489,8 +2485,7 @@ do | |||
2489 | instance = Item:new() | 2485 | instance = Item:new() |
2490 | end | 2486 | end |
2491 | do | 2487 | do |
2492 | local X | 2488 | local X = 1 |
2493 | X = 1 | ||
2494 | local B | 2489 | local B |
2495 | print("only forward declare upper case variables") | 2490 | print("only forward declare upper case variables") |
2496 | local a = 1 | 2491 | local a = 1 |
@@ -2510,8 +2505,7 @@ do | |||
2510 | print("only declare upper case variables as globals") | 2505 | print("only declare upper case variables as globals") |
2511 | local a = 1 | 2506 | local a = 1 |
2512 | local B = 2 | 2507 | local B = 2 |
2513 | local Temp | 2508 | local Temp = "a local value" |
2514 | Temp = "a local value" | ||
2515 | end | 2509 | end |
2516 | local thing = { | 2510 | local thing = { |
2517 | 1, | 2511 | 1, |
diff --git a/spec/outputs/codes_from_doc_zh.lua b/spec/outputs/codes_from_doc_zh.lua index 1a10555..a23044d 100644 --- a/spec/outputs/codes_from_doc_zh.lua +++ b/spec/outputs/codes_from_doc_zh.lua | |||
@@ -467,8 +467,7 @@ local x = f() | |||
467 | local y = x | 467 | local y = x |
468 | local z = x | 468 | local z = x |
469 | do | 469 | do |
470 | local a | 470 | local a = 1 |
471 | a = 1 | ||
472 | local x, y, z | 471 | local x, y, z |
473 | print("预先声明后续所有变量为局部变量") | 472 | print("预先声明后续所有变量为局部变量") |
474 | x = function() | 473 | x = function() |
@@ -478,8 +477,7 @@ do | |||
478 | instance = Item:new() | 477 | instance = Item:new() |
479 | end | 478 | end |
480 | do | 479 | do |
481 | local X | 480 | local X = 1 |
482 | X = 1 | ||
483 | local B | 481 | local B |
484 | print("只预先声明后续大写的变量为局部变量") | 482 | print("只预先声明后续大写的变量为局部变量") |
485 | local a = 1 | 483 | local a = 1 |
@@ -499,8 +497,7 @@ do | |||
499 | print("只预先声明大写的变量为全局变量") | 497 | print("只预先声明大写的变量为全局变量") |
500 | local a = 1 | 498 | local a = 1 |
501 | local B = 2 | 499 | local B = 2 |
502 | local Temp | 500 | local Temp = "一个局部值" |
503 | Temp = "一个局部值" | ||
504 | end | 501 | end |
505 | local thing = { | 502 | local thing = { |
506 | 1, | 503 | 1, |
@@ -2472,8 +2469,7 @@ local x = f() | |||
2472 | local y = x | 2469 | local y = x |
2473 | local z = x | 2470 | local z = x |
2474 | do | 2471 | do |
2475 | local a | 2472 | local a = 1 |
2476 | a = 1 | ||
2477 | local x, y, z | 2473 | local x, y, z |
2478 | print("预先声明后续所有变量为局部变量") | 2474 | print("预先声明后续所有变量为局部变量") |
2479 | x = function() | 2475 | x = function() |
@@ -2483,8 +2479,7 @@ do | |||
2483 | instance = Item:new() | 2479 | instance = Item:new() |
2484 | end | 2480 | end |
2485 | do | 2481 | do |
2486 | local X | 2482 | local X = 1 |
2487 | X = 1 | ||
2488 | local B | 2483 | local B |
2489 | print("只预先声明后续大写的变量为局部变量") | 2484 | print("只预先声明后续大写的变量为局部变量") |
2490 | local a = 1 | 2485 | local a = 1 |
@@ -2504,8 +2499,7 @@ do | |||
2504 | print("只预先声明大写的变量为全局变量") | 2499 | print("只预先声明大写的变量为全局变量") |
2505 | local a = 1 | 2500 | local a = 1 |
2506 | local B = 2 | 2501 | local B = 2 |
2507 | local Temp | 2502 | local Temp = "一个局部值" |
2508 | Temp = "一个局部值" | ||
2509 | end | 2503 | end |
2510 | local thing = { | 2504 | local thing = { |
2511 | 1, | 2505 | 1, |
diff --git a/spec/outputs/macro.lua b/spec/outputs/macro.lua index aa74ed9..4d31574 100644 --- a/spec/outputs/macro.lua +++ b/spec/outputs/macro.lua | |||
@@ -191,13 +191,11 @@ end | |||
191 | do | 191 | do |
192 | local a = 8 | 192 | local a = 8 |
193 | a = (function() | 193 | a = (function() |
194 | local a | 194 | local a = 1 |
195 | a = 1 | ||
196 | return a + 1 | 195 | return a + 1 |
197 | end)() | 196 | end)() |
198 | a = a + (function() | 197 | a = a + (function() |
199 | local a | 198 | local a = 1 |
200 | a = 1 | ||
201 | return a + 1 | 199 | return a + 1 |
202 | end)() | 200 | end)() |
203 | print(a) | 201 | print(a) |
@@ -274,18 +272,12 @@ local result = ((((((origin.transform.root.gameObject:Parents()):Descendants()): | |||
274 | end)):Destroy() | 272 | end)):Destroy() |
275 | do | 273 | do |
276 | do | 274 | do |
277 | local _1 | 275 | local _1 = origin.transform.root.gameObject:Parents() |
278 | _1 = origin.transform.root.gameObject:Parents() | 276 | local _2 = _1:Descendants() |
279 | local _2 | 277 | local _3 = _2:SelectEnable() |
280 | _2 = _1:Descendants() | 278 | local _4 = _3:SelectVisible() |
281 | local _3 | 279 | local _5 = _4:TagEqual("fx") |
282 | _3 = _2:SelectEnable() | 280 | local _6 = _5:Where(function(x) |
283 | local _4 | ||
284 | _4 = _3:SelectVisible() | ||
285 | local _5 | ||
286 | _5 = _4:TagEqual("fx") | ||
287 | local _6 | ||
288 | _6 = _5:Where(function(x) | ||
289 | return x.name:EndsWith("(Clone)") | 281 | return x.name:EndsWith("(Clone)") |
290 | end) | 282 | end) |
291 | _6:Destroy() | 283 | _6:Destroy() |
diff --git a/spec/outputs/plus.lua b/spec/outputs/plus.lua index bd89bfe..dda0660 100644 --- a/spec/outputs/plus.lua +++ b/spec/outputs/plus.lua | |||
@@ -65,7 +65,6 @@ backpack = { | |||
65 | local start = { | 65 | local start = { |
66 | something = "cold" | 66 | something = "cold" |
67 | } | 67 | } |
68 | local bathe | 68 | local bathe = { |
69 | bathe = { | ||
70 | on = "fire" | 69 | on = "fire" |
71 | } | 70 | } |
diff --git a/spec/outputs/unicode/macro.lua b/spec/outputs/unicode/macro.lua index e2195e4..099080f 100644 --- a/spec/outputs/unicode/macro.lua +++ b/spec/outputs/unicode/macro.lua | |||
@@ -167,13 +167,11 @@ end | |||
167 | do | 167 | do |
168 | local _u53d8_u91cfa = 8 | 168 | local _u53d8_u91cfa = 8 |
169 | _u53d8_u91cfa = (function() | 169 | _u53d8_u91cfa = (function() |
170 | local _u53d8_u91cfa | 170 | local _u53d8_u91cfa = 1 |
171 | _u53d8_u91cfa = 1 | ||
172 | return _u53d8_u91cfa + 1 | 171 | return _u53d8_u91cfa + 1 |
173 | end)() | 172 | end)() |
174 | _u53d8_u91cfa = _u53d8_u91cfa + (function() | 173 | _u53d8_u91cfa = _u53d8_u91cfa + (function() |
175 | local _u53d8_u91cfa | 174 | local _u53d8_u91cfa = 1 |
176 | _u53d8_u91cfa = 1 | ||
177 | return _u53d8_u91cfa + 1 | 175 | return _u53d8_u91cfa + 1 |
178 | end)() | 176 | end)() |
179 | _u6253_u5370(_u53d8_u91cfa) | 177 | _u6253_u5370(_u53d8_u91cfa) |
diff --git a/spec/outputs/unicode/plus.lua b/spec/outputs/unicode/plus.lua index 75e4aac..adce62e 100644 --- a/spec/outputs/unicode/plus.lua +++ b/spec/outputs/unicode/plus.lua | |||
@@ -67,7 +67,6 @@ _u80cc_u5305 = { | |||
67 | local _u5f00_u59cb = { | 67 | local _u5f00_u59cb = { |
68 | ["东西"] = "冷" | 68 | ["东西"] = "冷" |
69 | } | 69 | } |
70 | local _u6d17_u6fa1 | 70 | local _u6d17_u6fa1 = { |
71 | _u6d17_u6fa1 = { | ||
72 | ["在"] = "火" | 71 | ["在"] = "火" |
73 | } | 72 | } |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index e7fe0c0..3d98fbc 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.27.0"sv; | 78 | const std::string_view version = "0.27.1"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 { |
@@ -1486,7 +1486,7 @@ private: | |||
1486 | } | 1486 | } |
1487 | } | 1487 | } |
1488 | 1488 | ||
1489 | bool isPureBackcall(Exp_t* exp) const { | 1489 | bool isPurePipeChain(Exp_t* exp) const { |
1490 | return exp->opValues.empty() && exp->pipeExprs.size() > 1; | 1490 | return exp->opValues.empty() && exp->pipeExprs.size() > 1; |
1491 | } | 1491 | } |
1492 | 1492 | ||
@@ -1869,7 +1869,7 @@ private: | |||
1869 | } | 1869 | } |
1870 | } else if (expList->exprs.size() == 1) { | 1870 | } else if (expList->exprs.size() == 1) { |
1871 | auto exp = static_cast<Exp_t*>(expList->exprs.back()); | 1871 | auto exp = static_cast<Exp_t*>(expList->exprs.back()); |
1872 | if (isPureBackcall(exp)) { | 1872 | if (isPurePipeChain(exp)) { |
1873 | transformExp(exp, out, ExpUsage::Common); | 1873 | transformExp(exp, out, ExpUsage::Common); |
1874 | break; | 1874 | break; |
1875 | } | 1875 | } |
@@ -2061,7 +2061,7 @@ private: | |||
2061 | } | 2061 | } |
2062 | } | 2062 | } |
2063 | 2063 | ||
2064 | void transformAssignment(ExpListAssign_t* assignment, str_list& out, bool optionalDestruct = false) { | 2064 | bool transformAssignment(ExpListAssign_t* assignment, str_list& out, bool optionalDestruct = false) { |
2065 | checkAssignable(assignment->expList); | 2065 | checkAssignable(assignment->expList); |
2066 | BLOCK_START | 2066 | BLOCK_START |
2067 | auto assign = ast_cast<Assign_t>(assignment->action); | 2067 | auto assign = ast_cast<Assign_t>(assignment->action); |
@@ -2176,7 +2176,7 @@ private: | |||
2176 | temp.push_back(indent() + "end"s + nll(assignment)); | 2176 | temp.push_back(indent() + "end"s + nll(assignment)); |
2177 | } | 2177 | } |
2178 | out.push_back(join(temp)); | 2178 | out.push_back(join(temp)); |
2179 | return; | 2179 | return false; |
2180 | BLOCK_END | 2180 | BLOCK_END |
2181 | } | 2181 | } |
2182 | { | 2182 | { |
@@ -2248,7 +2248,7 @@ private: | |||
2248 | transformAssignment(afterAssignment, temp); | 2248 | transformAssignment(afterAssignment, temp); |
2249 | } | 2249 | } |
2250 | out.push_back(join(temp)); | 2250 | out.push_back(join(temp)); |
2251 | return; | 2251 | return false; |
2252 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { | 2252 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { |
2253 | str_list temp; | 2253 | str_list temp; |
2254 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | 2254 | auto [beforeAssignment, afterAssignment] = splitAssignment(); |
@@ -2300,7 +2300,7 @@ private: | |||
2300 | transformAssignment(afterAssignment, temp); | 2300 | transformAssignment(afterAssignment, temp); |
2301 | } | 2301 | } |
2302 | out.push_back(join(temp)); | 2302 | out.push_back(join(temp)); |
2303 | return; | 2303 | return false; |
2304 | } else { | 2304 | } else { |
2305 | break; | 2305 | break; |
2306 | } | 2306 | } |
@@ -2322,7 +2322,7 @@ private: | |||
2322 | std::string preDefine = getPreDefineLine(assignment); | 2322 | std::string preDefine = getPreDefineLine(assignment); |
2323 | transformIf(ifNode, out, ExpUsage::Assignment, assignList); | 2323 | transformIf(ifNode, out, ExpUsage::Assignment, assignList); |
2324 | out.back().insert(0, preDefine); | 2324 | out.back().insert(0, preDefine); |
2325 | return; | 2325 | return false; |
2326 | } | 2326 | } |
2327 | case id<Switch_t>(): { | 2327 | case id<Switch_t>(): { |
2328 | auto switchNode = static_cast<Switch_t*>(value); | 2328 | auto switchNode = static_cast<Switch_t*>(value); |
@@ -2330,7 +2330,7 @@ private: | |||
2330 | std::string preDefine = getPreDefineLine(assignment); | 2330 | std::string preDefine = getPreDefineLine(assignment); |
2331 | transformSwitch(switchNode, out, ExpUsage::Assignment, assignList); | 2331 | transformSwitch(switchNode, out, ExpUsage::Assignment, assignList); |
2332 | out.back().insert(0, preDefine); | 2332 | out.back().insert(0, preDefine); |
2333 | return; | 2333 | return false; |
2334 | } | 2334 | } |
2335 | case id<With_t>(): { | 2335 | case id<With_t>(): { |
2336 | auto withNode = static_cast<With_t*>(value); | 2336 | auto withNode = static_cast<With_t*>(value); |
@@ -2338,7 +2338,7 @@ private: | |||
2338 | std::string preDefine = getPreDefineLine(assignment); | 2338 | std::string preDefine = getPreDefineLine(assignment); |
2339 | transformWith(withNode, out, expList); | 2339 | transformWith(withNode, out, expList); |
2340 | out.back().insert(0, preDefine); | 2340 | out.back().insert(0, preDefine); |
2341 | return; | 2341 | return false; |
2342 | } | 2342 | } |
2343 | case id<Do_t>(): { | 2343 | case id<Do_t>(): { |
2344 | auto expList = assignment->expList.get(); | 2344 | auto expList = assignment->expList.get(); |
@@ -2346,7 +2346,7 @@ private: | |||
2346 | std::string preDefine = getPreDefineLine(assignment); | 2346 | std::string preDefine = getPreDefineLine(assignment); |
2347 | transformDo(doNode, out, ExpUsage::Assignment, expList); | 2347 | transformDo(doNode, out, ExpUsage::Assignment, expList); |
2348 | out.back().insert(0, preDefine); | 2348 | out.back().insert(0, preDefine); |
2349 | return; | 2349 | return false; |
2350 | } | 2350 | } |
2351 | case id<Comprehension_t>(): { | 2351 | case id<Comprehension_t>(): { |
2352 | auto comp = static_cast<Comprehension_t*>(value); | 2352 | auto comp = static_cast<Comprehension_t*>(value); |
@@ -2358,42 +2358,42 @@ private: | |||
2358 | } else { | 2358 | } else { |
2359 | transformComprehension(comp, out, ExpUsage::Assignment, expList); | 2359 | transformComprehension(comp, out, ExpUsage::Assignment, expList); |
2360 | } | 2360 | } |
2361 | return; | 2361 | return false; |
2362 | } | 2362 | } |
2363 | case id<TblComprehension_t>(): { | 2363 | case id<TblComprehension_t>(): { |
2364 | auto expList = assignment->expList.get(); | 2364 | auto expList = assignment->expList.get(); |
2365 | std::string preDefine = getPreDefineLine(assignment); | 2365 | std::string preDefine = getPreDefineLine(assignment); |
2366 | transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Assignment, expList); | 2366 | transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Assignment, expList); |
2367 | out.back().insert(0, preDefine); | 2367 | out.back().insert(0, preDefine); |
2368 | return; | 2368 | return false; |
2369 | } | 2369 | } |
2370 | case id<For_t>(): { | 2370 | case id<For_t>(): { |
2371 | auto expList = assignment->expList.get(); | 2371 | auto expList = assignment->expList.get(); |
2372 | std::string preDefine = getPreDefineLine(assignment); | 2372 | std::string preDefine = getPreDefineLine(assignment); |
2373 | transformForInPlace(static_cast<For_t*>(value), out, expList); | 2373 | transformForInPlace(static_cast<For_t*>(value), out, expList); |
2374 | out.back().insert(0, preDefine); | 2374 | out.back().insert(0, preDefine); |
2375 | return; | 2375 | return false; |
2376 | } | 2376 | } |
2377 | case id<ForEach_t>(): { | 2377 | case id<ForEach_t>(): { |
2378 | auto expList = assignment->expList.get(); | 2378 | auto expList = assignment->expList.get(); |
2379 | std::string preDefine = getPreDefineLine(assignment); | 2379 | std::string preDefine = getPreDefineLine(assignment); |
2380 | transformForEachInPlace(static_cast<ForEach_t*>(value), out, expList); | 2380 | transformForEachInPlace(static_cast<ForEach_t*>(value), out, expList); |
2381 | out.back().insert(0, preDefine); | 2381 | out.back().insert(0, preDefine); |
2382 | return; | 2382 | return false; |
2383 | } | 2383 | } |
2384 | case id<ClassDecl_t>(): { | 2384 | case id<ClassDecl_t>(): { |
2385 | auto expList = assignment->expList.get(); | 2385 | auto expList = assignment->expList.get(); |
2386 | std::string preDefine = getPreDefineLine(assignment); | 2386 | std::string preDefine = getPreDefineLine(assignment); |
2387 | transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Assignment, expList); | 2387 | transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Assignment, expList); |
2388 | out.back().insert(0, preDefine); | 2388 | out.back().insert(0, preDefine); |
2389 | return; | 2389 | return false; |
2390 | } | 2390 | } |
2391 | case id<While_t>(): { | 2391 | case id<While_t>(): { |
2392 | auto expList = assignment->expList.get(); | 2392 | auto expList = assignment->expList.get(); |
2393 | std::string preDefine = getPreDefineLine(assignment); | 2393 | std::string preDefine = getPreDefineLine(assignment); |
2394 | transformWhileInPlace(static_cast<While_t*>(value), out, expList); | 2394 | transformWhileInPlace(static_cast<While_t*>(value), out, expList); |
2395 | out.back().insert(0, preDefine); | 2395 | out.back().insert(0, preDefine); |
2396 | return; | 2396 | return false; |
2397 | } | 2397 | } |
2398 | case id<TableLit_t>(): { | 2398 | case id<TableLit_t>(): { |
2399 | auto tableLit = static_cast<TableLit_t*>(value); | 2399 | auto tableLit = static_cast<TableLit_t*>(value); |
@@ -2402,7 +2402,7 @@ private: | |||
2402 | std::string preDefine = getPreDefineLine(assignment); | 2402 | std::string preDefine = getPreDefineLine(assignment); |
2403 | transformSpreadTable(tableLit->values.objects(), out, ExpUsage::Assignment, expList, false); | 2403 | transformSpreadTable(tableLit->values.objects(), out, ExpUsage::Assignment, expList, false); |
2404 | out.back().insert(0, preDefine); | 2404 | out.back().insert(0, preDefine); |
2405 | return; | 2405 | return false; |
2406 | } | 2406 | } |
2407 | break; | 2407 | break; |
2408 | } | 2408 | } |
@@ -2413,31 +2413,31 @@ private: | |||
2413 | std::string preDefine = getPreDefineLine(assignment); | 2413 | std::string preDefine = getPreDefineLine(assignment); |
2414 | transformSpreadTable(tableBlock->values.objects(), out, ExpUsage::Assignment, expList, false); | 2414 | transformSpreadTable(tableBlock->values.objects(), out, ExpUsage::Assignment, expList, false); |
2415 | out.back().insert(0, preDefine); | 2415 | out.back().insert(0, preDefine); |
2416 | return; | 2416 | return false; |
2417 | } | 2417 | } |
2418 | break; | 2418 | break; |
2419 | } | 2419 | } |
2420 | } | 2420 | } |
2421 | auto exp = ast_cast<Exp_t>(value); | 2421 | auto exp = ast_cast<Exp_t>(value); |
2422 | BREAK_IF(!exp); | 2422 | BREAK_IF(!exp); |
2423 | if (isPureBackcall(exp)) { | 2423 | if (isPurePipeChain(exp)) { |
2424 | auto expList = assignment->expList.get(); | 2424 | auto expList = assignment->expList.get(); |
2425 | transformExp(exp, out, ExpUsage::Assignment, expList); | 2425 | transformExp(exp, out, ExpUsage::Assignment, expList); |
2426 | return; | 2426 | return false; |
2427 | } else if (isPureNilCoalesed(exp)) { | 2427 | } else if (isPureNilCoalesed(exp)) { |
2428 | auto expList = assignment->expList.get(); | 2428 | auto expList = assignment->expList.get(); |
2429 | transformNilCoalesedExp(exp, out, ExpUsage::Assignment, expList); | 2429 | transformNilCoalesedExp(exp, out, ExpUsage::Assignment, expList); |
2430 | return; | 2430 | return false; |
2431 | } else if (auto unary = unaryGeneratingAnonFunc(exp)) { | 2431 | } else if (auto unary = unaryGeneratingAnonFunc(exp)) { |
2432 | std::string preDefine = getPreDefineLine(assignment); | 2432 | std::string preDefine = getPreDefineLine(assignment); |
2433 | auto expList = assignment->expList.get(); | 2433 | auto expList = assignment->expList.get(); |
2434 | transformUnaryExp(unary, out, ExpUsage::Assignment, expList); | 2434 | transformUnaryExp(unary, out, ExpUsage::Assignment, expList); |
2435 | out.back().insert(0, preDefine); | 2435 | out.back().insert(0, preDefine); |
2436 | return; | 2436 | return false; |
2437 | } else if (isConditionChaining(exp)) { | 2437 | } else if (isConditionChaining(exp)) { |
2438 | auto expList = assignment->expList.get(); | 2438 | auto expList = assignment->expList.get(); |
2439 | transformExp(exp, out, ExpUsage::Assignment, expList); | 2439 | transformExp(exp, out, ExpUsage::Assignment, expList); |
2440 | return; | 2440 | return false; |
2441 | } | 2441 | } |
2442 | auto singleVal = singleValueFrom(exp); | 2442 | auto singleVal = singleValueFrom(exp); |
2443 | BREAK_IF(!singleVal); | 2443 | BREAK_IF(!singleVal); |
@@ -2451,13 +2451,13 @@ private: | |||
2451 | std::string preDefine = getPreDefineLine(assignment); | 2451 | std::string preDefine = getPreDefineLine(assignment); |
2452 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList, false, optionalDestruct); | 2452 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList, false, optionalDestruct); |
2453 | out.back().insert(0, preDefine); | 2453 | out.back().insert(0, preDefine); |
2454 | return; | 2454 | return false; |
2455 | } | 2455 | } |
2456 | case ChainType::HasKeyword: | 2456 | case ChainType::HasKeyword: |
2457 | case ChainType::HasUnicode: | 2457 | case ChainType::HasUnicode: |
2458 | case ChainType::Macro: | 2458 | case ChainType::Macro: |
2459 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); | 2459 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); |
2460 | return; | 2460 | return false; |
2461 | case ChainType::Common: | 2461 | case ChainType::Common: |
2462 | case ChainType::EndWithEOP: | 2462 | case ChainType::EndWithEOP: |
2463 | case ChainType::Metatable: | 2463 | case ChainType::Metatable: |
@@ -2468,6 +2468,7 @@ private: | |||
2468 | auto info = extractDestructureInfo(assignment, false, optionalDestruct); | 2468 | auto info = extractDestructureInfo(assignment, false, optionalDestruct); |
2469 | if (info.destructures.empty()) { | 2469 | if (info.destructures.empty()) { |
2470 | transformAssignmentCommon(assignment, out); | 2470 | transformAssignmentCommon(assignment, out); |
2471 | return true; | ||
2471 | } else { | 2472 | } else { |
2472 | auto x = assignment; | 2473 | auto x = assignment; |
2473 | str_list temp; | 2474 | str_list temp; |
@@ -2733,6 +2734,7 @@ private: | |||
2733 | } | 2734 | } |
2734 | out.push_back(join(temp)); | 2735 | out.push_back(join(temp)); |
2735 | } | 2736 | } |
2737 | return false; | ||
2736 | } | 2738 | } |
2737 | 2739 | ||
2738 | void transformAssignItem(ast_node* value, str_list& out) { | 2740 | void transformAssignItem(ast_node* value, str_list& out) { |
@@ -5313,7 +5315,7 @@ private: | |||
5313 | if (auto valueList = returnNode->valueList.as<ExpListLow_t>()) { | 5315 | if (auto valueList = returnNode->valueList.as<ExpListLow_t>()) { |
5314 | if (valueList->exprs.size() == 1) { | 5316 | if (valueList->exprs.size() == 1) { |
5315 | auto exp = static_cast<Exp_t*>(valueList->exprs.back()); | 5317 | auto exp = static_cast<Exp_t*>(valueList->exprs.back()); |
5316 | if (isPureBackcall(exp)) { | 5318 | if (isPurePipeChain(exp)) { |
5317 | transformExp(exp, out, ExpUsage::Return); | 5319 | transformExp(exp, out, ExpUsage::Return); |
5318 | return; | 5320 | return; |
5319 | } else if (isPureNilCoalesed(exp)) { | 5321 | } else if (isPureNilCoalesed(exp)) { |
@@ -10676,6 +10678,7 @@ private: | |||
10676 | 10678 | ||
10677 | void transformLocal(Local_t* local, str_list& out) { | 10679 | void transformLocal(Local_t* local, str_list& out) { |
10678 | str_list temp; | 10680 | str_list temp; |
10681 | bool defined = local->defined; | ||
10679 | if (!local->defined) { | 10682 | if (!local->defined) { |
10680 | local->defined = true; | 10683 | local->defined = true; |
10681 | transformLocalDef(local, temp); | 10684 | transformLocalDef(local, temp); |
@@ -10704,7 +10707,26 @@ private: | |||
10704 | assign->values.push_back(tableBlock); | 10707 | assign->values.push_back(tableBlock); |
10705 | } | 10708 | } |
10706 | assignment->action.set(assign); | 10709 | assignment->action.set(assign); |
10707 | transformAssignment(assignment, temp); | 10710 | bool oneLined = transformAssignment(assignment, temp); |
10711 | for (auto val : assign->values.objects()) { | ||
10712 | if (auto value = singleValueFrom(val)) { | ||
10713 | if (auto spValue = value->item.as<SimpleValue_t>()) { | ||
10714 | if (auto funLit = spValue->value.as<FunLit_t>()) { | ||
10715 | if (!funLit->noRecursion) { | ||
10716 | oneLined = false; | ||
10717 | } | ||
10718 | break; | ||
10719 | } | ||
10720 | } | ||
10721 | } | ||
10722 | } | ||
10723 | if (!defined && oneLined && temp.size() == 2) { | ||
10724 | auto pos = temp.back().find_first_not_of(" \t"sv); | ||
10725 | if (pos != std::string::npos) { | ||
10726 | temp.back().insert(pos, "local "); | ||
10727 | temp.pop_front(); | ||
10728 | } | ||
10729 | } | ||
10708 | } | 10730 | } |
10709 | break; | 10731 | break; |
10710 | } | 10732 | } |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 5993ed5..ceb1f7c 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -519,7 +519,7 @@ YueParser::YueParser() { | |||
519 | UpdateOp = | 519 | UpdateOp = |
520 | expr("..") | "//" | "or" | "and" | | 520 | expr("..") | "//" | "or" | "and" | |
521 | ">>" | "<<" | "??" | | 521 | ">>" | "<<" | "??" | |
522 | set("+-*/%&|"); | 522 | set("+-*/%&|^"); |
523 | 523 | ||
524 | Update = UpdateOp >> '=' >> space >> Exp; | 524 | Update = UpdateOp >> '=' >> space >> Exp; |
525 | 525 | ||
diff --git a/src/yuescript/yuescript.h b/src/yuescript/yuescript.h index ebe90cb..83a4350 100644 --- a/src/yuescript/yuescript.h +++ b/src/yuescript/yuescript.h | |||
@@ -187,10 +187,10 @@ local function dump(what) | |||
187 | depth = depth or 0 | 187 | depth = depth or 0 |
188 | local t = type(what) | 188 | local t = type(what) |
189 | if "string" == t then | 189 | if "string" == t then |
190 | return "\"" .. tostring(what) .. "\"\n" | 190 | return "\"" .. tostring(what) .. "\"" |
191 | elseif "table" == t then | 191 | elseif "table" == t then |
192 | if seen[what] then | 192 | if seen[what] then |
193 | return "recursion(" .. tostring(what) .. ")...\n" | 193 | return "recursion(" .. tostring(what) .. ")..." |
194 | end | 194 | end |
195 | seen[what] = true | 195 | seen[what] = true |
196 | depth = depth + 1 | 196 | depth = depth + 1 |
@@ -199,9 +199,9 @@ local function dump(what) | |||
199 | insert(lines, ('\t'):rep(depth) .. "[" .. tostring(k) .. "] = " .. _dump(v, depth)) | 199 | insert(lines, ('\t'):rep(depth) .. "[" .. tostring(k) .. "] = " .. _dump(v, depth)) |
200 | end | 200 | end |
201 | seen[what] = false | 201 | seen[what] = false |
202 | return "{\n" .. concat(lines) .. ('\t'):rep(depth - 1) .. "}\n" | 202 | return "{\n" .. concat(lines, "\n") .. "\n" .. ('\t'):rep(depth - 1) .. "}" |
203 | else | 203 | else |
204 | return tostring(what) .. "\n" | 204 | return tostring(what) |
205 | end | 205 | end |
206 | end | 206 | end |
207 | return _dump(what) | 207 | return _dump(what) |