diff options
| author | Li Jin <dragon-fly@qq.com> | 2024-09-03 23:23:25 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2024-09-03 23:23:25 +0800 |
| commit | 2f8215df7288e0aac690c8e8b1ff79865f114302 (patch) | |
| tree | 2fc316ec0d6ca82123dc1fbc2012d8eeb3bc8427 | |
| parent | 880b7eb9a427b263091f6eef5197c0285c723fd7 (diff) | |
| download | yuescript-0.25.0.tar.gz yuescript-0.25.0.tar.bz2 yuescript-0.25.0.zip | |
fix correct evaluation order for multi-value assignments.v0.25.0
| -rw-r--r-- | spec/inputs/destructure.yue | 8 | ||||
| -rw-r--r-- | spec/outputs/assign.lua | 3 | ||||
| -rw-r--r-- | spec/outputs/destructure.lua | 49 | ||||
| -rw-r--r-- | spec/outputs/metatable.lua | 13 | ||||
| -rw-r--r-- | spec/outputs/unicode/assign.lua | 3 | ||||
| -rw-r--r-- | spec/outputs/unicode/destructure.lua | 24 | ||||
| -rw-r--r-- | spec/outputs/unicode/metatable.lua | 13 | ||||
| -rw-r--r-- | src/yuescript/parser.cpp | 10 | ||||
| -rw-r--r-- | src/yuescript/parser.hpp | 11 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 247 |
10 files changed, 257 insertions, 124 deletions
diff --git a/spec/inputs/destructure.yue b/spec/inputs/destructure.yue index 5017ee1..674dfe4 100644 --- a/spec/inputs/destructure.yue +++ b/spec/inputs/destructure.yue | |||
| @@ -7,6 +7,14 @@ do | |||
| 7 | { :hello, :world } = value | 7 | { :hello, :world } = value |
| 8 | 8 | ||
| 9 | do | 9 | do |
| 10 | x, [a, b] = f! | ||
| 11 | print x, a, b | ||
| 12 | |||
| 13 | do | ||
| 14 | list = [ [1, 2], [3, 4]] | ||
| 15 | {x, y}, list = lume.first(list), lume.slice list, 2 | ||
| 16 | |||
| 17 | do | ||
| 10 | { yes: no, thing } = world | 18 | { yes: no, thing } = world |
| 11 | 19 | ||
| 12 | {:a,:b,:c,:d} = yeah | 20 | {:a,:b,:c,:d} = yeah |
diff --git a/spec/outputs/assign.lua b/spec/outputs/assign.lua index 5552f73..1978df1 100644 --- a/spec/outputs/assign.lua +++ b/spec/outputs/assign.lua | |||
| @@ -77,8 +77,7 @@ return _(function() | |||
| 77 | end | 77 | end |
| 78 | end | 78 | end |
| 79 | do | 79 | do |
| 80 | local a | 80 | local a, b |
| 81 | local b | ||
| 82 | if x then | 81 | if x then |
| 83 | local _obj_0, _obj_1 = f() | 82 | local _obj_0, _obj_1 = f() |
| 84 | a = _obj_0 | 83 | a = _obj_0 |
diff --git a/spec/outputs/destructure.lua b/spec/outputs/destructure.lua index 2d0d46f..d8517a0 100644 --- a/spec/outputs/destructure.lua +++ b/spec/outputs/destructure.lua | |||
| @@ -14,6 +14,31 @@ do | |||
| 14 | hello, world = _obj_0.hello, _obj_0.world | 14 | hello, world = _obj_0.hello, _obj_0.world |
| 15 | end | 15 | end |
| 16 | do | 16 | do |
| 17 | local x, a, b | ||
| 18 | do | ||
| 19 | local _obj_0, _obj_1 = f() | ||
| 20 | x = _obj_0 | ||
| 21 | a, b = _obj_1[1], _obj_1[2] | ||
| 22 | end | ||
| 23 | print(x, a, b) | ||
| 24 | end | ||
| 25 | do | ||
| 26 | local list = { | ||
| 27 | { | ||
| 28 | 1, | ||
| 29 | 2 | ||
| 30 | }, | ||
| 31 | { | ||
| 32 | 3, | ||
| 33 | 4 | ||
| 34 | } | ||
| 35 | } | ||
| 36 | local x, y | ||
| 37 | local _obj_0 = lume.first(list) | ||
| 38 | x, y = _obj_0[1], _obj_0[2] | ||
| 39 | list = lume.slice(list, 2) | ||
| 40 | end | ||
| 41 | do | ||
| 17 | local no, thing | 42 | local no, thing |
| 18 | do | 43 | do |
| 19 | local _obj_0 = world | 44 | local _obj_0 = world |
| @@ -24,12 +49,12 @@ do | |||
| 24 | local _obj_0 = yeah | 49 | local _obj_0 = yeah |
| 25 | a, b, c, d = _obj_0.a, _obj_0.b, _obj_0.c, _obj_0.d | 50 | a, b, c, d = _obj_0.a, _obj_0.b, _obj_0.c, _obj_0.d |
| 26 | end | 51 | end |
| 27 | b = two | ||
| 28 | a = one[1] | 52 | a = one[1] |
| 29 | c = nil | 53 | b = two |
| 30 | b = one[1] | 54 | b = one[1] |
| 31 | local e = two | 55 | c = nil |
| 32 | d = one[1] | 56 | d = one[1] |
| 57 | local e = two | ||
| 33 | local x = one | 58 | local x = one |
| 34 | local y = two[1] | 59 | local y = two[1] |
| 35 | local xx, yy = 1, 2 | 60 | local xx, yy = 1, 2 |
| @@ -46,9 +71,9 @@ do | |||
| 46 | a, b, c, d, e, f, g = _obj_0[1], _obj_0.b, _obj_0[2], _obj_0.d, _obj_0[3], _obj_0.f, _obj_0[4] | 71 | a, b, c, d, e, f, g = _obj_0[1], _obj_0.b, _obj_0[2], _obj_0.d, _obj_0[3], _obj_0.f, _obj_0[4] |
| 47 | end | 72 | end |
| 48 | do | 73 | do |
| 49 | c = nil | ||
| 50 | local _obj_0 = tbl | 74 | local _obj_0 = tbl |
| 51 | a, b = _obj_0.a, _obj_0.b | 75 | a, b = _obj_0.a, _obj_0.b |
| 76 | c = nil | ||
| 52 | end | 77 | end |
| 53 | do | 78 | do |
| 54 | a = tbl | 79 | a = tbl |
| @@ -56,8 +81,8 @@ do | |||
| 56 | b, c = _obj_0.b, _obj_0.c | 81 | b, c = _obj_0.b, _obj_0.c |
| 57 | end | 82 | end |
| 58 | do | 83 | do |
| 59 | b = _ | ||
| 60 | a = tbl.a | 84 | a = tbl.a |
| 85 | b = _ | ||
| 61 | c = _.c | 86 | c = _.c |
| 62 | end | 87 | end |
| 63 | end | 88 | end |
| @@ -211,8 +236,8 @@ do | |||
| 211 | end | 236 | end |
| 212 | one, two, three = _tbl_0.one, _tbl_0.two, _tbl_0.three | 237 | one, two, three = _tbl_0.one, _tbl_0.two, _tbl_0.three |
| 213 | end | 238 | end |
| 214 | b = 123 | ||
| 215 | a = (a["if"](a, 123) + t).a | 239 | a = (a["if"](a, 123) + t).a |
| 240 | b = 123 | ||
| 216 | end | 241 | end |
| 217 | do | 242 | do |
| 218 | local name, job | 243 | local name, job |
| @@ -399,8 +424,7 @@ do | |||
| 399 | end | 424 | end |
| 400 | end | 425 | end |
| 401 | do | 426 | do |
| 402 | local x1, x2, x3, d, e | 427 | local x1, x2, x3, d, b, e |
| 403 | local b | ||
| 404 | do | 428 | do |
| 405 | local _obj_0, _obj_1, _obj_2, _obj_3, _obj_4 = f() | 429 | local _obj_0, _obj_1, _obj_2, _obj_3, _obj_4 = f() |
| 406 | do | 430 | do |
| @@ -408,14 +432,15 @@ do | |||
| 408 | _obj_5[#_obj_5 + 1] = _obj_0 | 432 | _obj_5[#_obj_5 + 1] = _obj_0 |
| 409 | end | 433 | end |
| 410 | setmetatable(c, _obj_4) | 434 | setmetatable(c, _obj_4) |
| 411 | x1, x2, x3, d, e = 1, 2, 3, _obj_1, _obj_3 | 435 | x1, x2, x3, d = 1, 2, 3, _obj_1 |
| 412 | b = _obj_2[1] | 436 | b = _obj_2[1] |
| 437 | e = _obj_3 | ||
| 413 | end | 438 | end |
| 414 | local y1, y4 | 439 | local y1, y2, y3, y4 |
| 415 | local y2, y3 | ||
| 416 | local _obj_0, _obj_1 = f2() | 440 | local _obj_0, _obj_1 = f2() |
| 417 | y1, y4 = f1(), _obj_1 | 441 | y1 = f1() |
| 418 | y2, y3 = _obj_0.y2, _obj_0.y3 | 442 | y2, y3 = _obj_0.y2, _obj_0.y3 |
| 443 | y4 = _obj_1 | ||
| 419 | end | 444 | end |
| 420 | do | 445 | do |
| 421 | local v1, v2, v3, v4 | 446 | local v1, v2, v3, v4 |
diff --git a/spec/outputs/metatable.lua b/spec/outputs/metatable.lua index 6af10e5..0715b58 100644 --- a/spec/outputs/metatable.lua +++ b/spec/outputs/metatable.lua | |||
| @@ -48,14 +48,15 @@ do | |||
| 48 | end | 48 | end |
| 49 | do | 49 | do |
| 50 | local x, new, var, close, closeA, num, add, sub | 50 | local x, new, var, close, closeA, num, add, sub |
| 51 | local _obj_0, _obj_1 | 51 | x = 123 |
| 52 | x, _obj_0, _obj_1 = 123, a.b.c, func() | 52 | local _obj_0 = a.b.c |
| 53 | new, var = _obj_0.new, _obj_0.var | 53 | new, var = _obj_0.new, _obj_0.var |
| 54 | local _obj_2 = getmetatable(_obj_0) | 54 | local _obj_1 = getmetatable(_obj_0) |
| 55 | close, closeA = _obj_2.__close, _obj_2.__close | 55 | close, closeA = _obj_1.__close, _obj_1.__close |
| 56 | _obj_1 = func() | ||
| 56 | num = _obj_1.num | 57 | num = _obj_1.num |
| 57 | local _obj_3 = getmetatable(_obj_1) | 58 | local _obj_2 = getmetatable(_obj_1) |
| 58 | add, sub = _obj_3.__add, _obj_3.__sub | 59 | add, sub = _obj_2.__add, _obj_2.__sub |
| 59 | end | 60 | end |
| 60 | setmetatable(a.b, { }) | 61 | setmetatable(a.b, { }) |
| 61 | x.abc = 123 | 62 | x.abc = 123 |
diff --git a/spec/outputs/unicode/assign.lua b/spec/outputs/unicode/assign.lua index cb53159..e883d68 100644 --- a/spec/outputs/unicode/assign.lua +++ b/spec/outputs/unicode/assign.lua | |||
| @@ -81,8 +81,7 @@ return __u65e0_u6548_u53d8_u91cf(function() | |||
| 81 | end | 81 | end |
| 82 | end | 82 | end |
| 83 | do | 83 | do |
| 84 | local _u53d8_u91cfa | 84 | local _u53d8_u91cfa, _u5143_u7d20b |
| 85 | local _u5143_u7d20b | ||
| 86 | if x_u6761_u4ef6 then | 85 | if x_u6761_u4ef6 then |
| 87 | local _obj_0, _obj_1 = _u51fd_u6570() | 86 | local _obj_0, _obj_1 = _u51fd_u6570() |
| 88 | _u53d8_u91cfa = _obj_0 | 87 | _u53d8_u91cfa = _obj_0 |
diff --git a/spec/outputs/unicode/destructure.lua b/spec/outputs/unicode/destructure.lua index e1cd6ae..29697fa 100644 --- a/spec/outputs/unicode/destructure.lua +++ b/spec/outputs/unicode/destructure.lua | |||
| @@ -24,12 +24,12 @@ do | |||
| 24 | local _obj_0 = _u597d | 24 | local _obj_0 = _u597d |
| 25 | _u5b57_u6bb5a, _u5b57_u6bb5b, _u5b57_u6bb5c, d_u5b57_u6bb5 = _obj_0["字段a"], _obj_0["字段b"], _obj_0["字段c"], _obj_0["d字段"] | 25 | _u5b57_u6bb5a, _u5b57_u6bb5b, _u5b57_u6bb5c, d_u5b57_u6bb5 = _obj_0["字段a"], _obj_0["字段b"], _obj_0["字段c"], _obj_0["d字段"] |
| 26 | end | 26 | end |
| 27 | local _u53d8_u91cfb = _u4e8c | ||
| 28 | local a_u5143_u7d20 = _u4e00[1] | 27 | local a_u5143_u7d20 = _u4e00[1] |
| 29 | local _u53d8_u91cfc = nil | 28 | local _u53d8_u91cfb = _u4e8c |
| 30 | local b_u5143_u7d20 = _u4e00[1] | 29 | local b_u5143_u7d20 = _u4e00[1] |
| 31 | local _u53d8_u91cfe = _u4e8c | 30 | local _u53d8_u91cfc = nil |
| 32 | local d_u5143_u7d20 = _u4e00[1] | 31 | local d_u5143_u7d20 = _u4e00[1] |
| 32 | local _u53d8_u91cfe = _u4e8c | ||
| 33 | local _u53d8_u91cfx = _u4e00 | 33 | local _u53d8_u91cfx = _u4e00 |
| 34 | local _u5143_u7d20y = _u4e8c[1] | 34 | local _u5143_u7d20y = _u4e8c[1] |
| 35 | local _u53d8_u91cfxx, _u53d8_u91cfyy = 1, 2 | 35 | local _u53d8_u91cfxx, _u53d8_u91cfyy = 1, 2 |
| @@ -47,9 +47,9 @@ do | |||
| 47 | _u5143_u7d20a, _u5b57_u6bb5b, _u5143_u7d20c, _u5b57_u6bb5d, _u5143_u7d20e, _u5b57_u6bb5f, _u5143_u7d20g = _obj_0[1], _obj_0["字段b"], _obj_0[2], _obj_0["字段d"], _obj_0[3], _obj_0["字段f"], _obj_0[4] | 47 | _u5143_u7d20a, _u5b57_u6bb5b, _u5143_u7d20c, _u5b57_u6bb5d, _u5143_u7d20e, _u5b57_u6bb5f, _u5143_u7d20g = _obj_0[1], _obj_0["字段b"], _obj_0[2], _obj_0["字段d"], _obj_0[3], _obj_0["字段f"], _obj_0[4] |
| 48 | end | 48 | end |
| 49 | do | 49 | do |
| 50 | _u53d8_u91cfc = nil | ||
| 51 | local _obj_0 = _u8868 | 50 | local _obj_0 = _u8868 |
| 52 | _u5b57_u6bb5a, _u5b57_u6bb5b = _obj_0["字段a"], _obj_0["字段b"] | 51 | _u5b57_u6bb5a, _u5b57_u6bb5b = _obj_0["字段a"], _obj_0["字段b"] |
| 52 | _u53d8_u91cfc = nil | ||
| 53 | end | 53 | end |
| 54 | do | 54 | do |
| 55 | local _u53d8_u91cfa = _u8868 | 55 | local _u53d8_u91cfa = _u8868 |
| @@ -57,8 +57,8 @@ do | |||
| 57 | _u5b57_u6bb5b, _u5b57_u6bb5c = _obj_0["字段b"], _obj_0["字段c"] | 57 | _u5b57_u6bb5b, _u5b57_u6bb5c = _obj_0["字段b"], _obj_0["字段c"] |
| 58 | end | 58 | end |
| 59 | do | 59 | do |
| 60 | _u53d8_u91cfb = __u65e0_u6548_u53d8_u91cf | ||
| 61 | _u5b57_u6bb5a = _u8868["字段a"] | 60 | _u5b57_u6bb5a = _u8868["字段a"] |
| 61 | _u53d8_u91cfb = __u65e0_u6548_u53d8_u91cf | ||
| 62 | _u5b57_u6bb5c = __u65e0_u6548_u53d8_u91cf["字段c"] | 62 | _u5b57_u6bb5c = __u65e0_u6548_u53d8_u91cf["字段c"] |
| 63 | end | 63 | end |
| 64 | end | 64 | end |
| @@ -212,11 +212,11 @@ do | |||
| 212 | end | 212 | end |
| 213 | _u4e00, _u4e8c, _u4e09 = _tbl_0["一"], _tbl_0["二"], _tbl_0["三"] | 213 | _u4e00, _u4e8c, _u4e09 = _tbl_0["一"], _tbl_0["二"], _tbl_0["三"] |
| 214 | end | 214 | end |
| 215 | local _u53d8_u91cfb = 123 | ||
| 216 | _u5b57_u6bb5a = ((function() | 215 | _u5b57_u6bb5a = ((function() |
| 217 | local _call_0 = _u5bf9_u8c61a | 216 | local _call_0 = _u5bf9_u8c61a |
| 218 | return _call_0["如果"](_call_0, 123) | 217 | return _call_0["如果"](_call_0, 123) |
| 219 | end)() + _u53d8_u91cft)["字段a"] | 218 | end)() + _u53d8_u91cft)["字段a"] |
| 219 | local _u53d8_u91cfb = 123 | ||
| 220 | end | 220 | end |
| 221 | do | 221 | do |
| 222 | local _u540d_u79f0, _u5de5_u4f5c | 222 | local _u540d_u79f0, _u5de5_u4f5c |
| @@ -386,8 +386,7 @@ do | |||
| 386 | end | 386 | end |
| 387 | end | 387 | end |
| 388 | do | 388 | do |
| 389 | local _u53d8_u91cf1, _u53d8_u91cf2, _u53d8_u91cf3, _u53d8_u91cfd, _u53d8_u91cfe | 389 | local _u53d8_u91cf1, _u53d8_u91cf2, _u53d8_u91cf3, _u53d8_u91cfd, _u5143_u7d20b, _u53d8_u91cfe |
| 390 | local _u5143_u7d20b | ||
| 391 | do | 390 | do |
| 392 | local _obj_0, _obj_1, _obj_2, _obj_3, _obj_4 = _u51fd_u6570() | 391 | local _obj_0, _obj_1, _obj_2, _obj_3, _obj_4 = _u51fd_u6570() |
| 393 | do | 392 | do |
| @@ -395,14 +394,15 @@ do | |||
| 395 | _obj_5[#_obj_5 + 1] = _obj_0 | 394 | _obj_5[#_obj_5 + 1] = _obj_0 |
| 396 | end | 395 | end |
| 397 | setmetatable(_u5bf9_u8c61c, _obj_4) | 396 | setmetatable(_u5bf9_u8c61c, _obj_4) |
| 398 | _u53d8_u91cf1, _u53d8_u91cf2, _u53d8_u91cf3, _u53d8_u91cfd, _u53d8_u91cfe = 1, 2, 3, _obj_1, _obj_3 | 397 | _u53d8_u91cf1, _u53d8_u91cf2, _u53d8_u91cf3, _u53d8_u91cfd = 1, 2, 3, _obj_1 |
| 399 | _u5143_u7d20b = _obj_2[1] | 398 | _u5143_u7d20b = _obj_2[1] |
| 399 | _u53d8_u91cfe = _obj_3 | ||
| 400 | end | 400 | end |
| 401 | local _u53d8_u91cfy1, _u53d8_u91cfy4 | 401 | local _u53d8_u91cfy1, _u5b57_u6bb5y2, _u5b57_u6bb5y3, _u53d8_u91cfy4 |
| 402 | local _u5b57_u6bb5y2, _u5b57_u6bb5y3 | ||
| 403 | local _obj_0, _obj_1 = _u51fd_u65702() | 402 | local _obj_0, _obj_1 = _u51fd_u65702() |
| 404 | _u53d8_u91cfy1, _u53d8_u91cfy4 = _u51fd_u65701(), _obj_1 | 403 | _u53d8_u91cfy1 = _u51fd_u65701() |
| 405 | _u5b57_u6bb5y2, _u5b57_u6bb5y3 = _obj_0["字段y2"], _obj_0["字段y3"] | 404 | _u5b57_u6bb5y2, _u5b57_u6bb5y3 = _obj_0["字段y2"], _obj_0["字段y3"] |
| 405 | _u53d8_u91cfy4 = _obj_1 | ||
| 406 | end | 406 | end |
| 407 | do | 407 | do |
| 408 | local _u53d8_u91cfv1, _u53d8_u91cfv2, _u53d8_u91cfv3, _u53d8_u91cfv4 | 408 | local _u53d8_u91cfv1, _u53d8_u91cfv2, _u53d8_u91cfv3, _u53d8_u91cfv4 |
diff --git a/spec/outputs/unicode/metatable.lua b/spec/outputs/unicode/metatable.lua index ca48d0d..f948d21 100644 --- a/spec/outputs/unicode/metatable.lua +++ b/spec/outputs/unicode/metatable.lua | |||
| @@ -48,14 +48,15 @@ do | |||
| 48 | end | 48 | end |
| 49 | do | 49 | do |
| 50 | local _u53d8_u91cfx, _u65b0, _u53d8_u91cf, close, _u5173_u95edA, num, add, sub | 50 | local _u53d8_u91cfx, _u65b0, _u53d8_u91cf, close, _u5173_u95edA, num, add, sub |
| 51 | local _obj_0, _obj_1 | 51 | _u53d8_u91cfx = 123 |
| 52 | _u53d8_u91cfx, _obj_0, _obj_1 = 123, _u53d8_u91cfa["变量b"]["变量c"], _u51fd_u6570() | 52 | local _obj_0 = _u53d8_u91cfa["变量b"]["变量c"] |
| 53 | _u65b0, _u53d8_u91cf = _obj_0["新"], _obj_0["变量"] | 53 | _u65b0, _u53d8_u91cf = _obj_0["新"], _obj_0["变量"] |
| 54 | local _obj_2 = getmetatable(_obj_0) | 54 | local _obj_1 = getmetatable(_obj_0) |
| 55 | close, _u5173_u95edA = _obj_2.__close, _obj_2.__close | 55 | close, _u5173_u95edA = _obj_1.__close, _obj_1.__close |
| 56 | _obj_1 = _u51fd_u6570() | ||
| 56 | num = _obj_1.num | 57 | num = _obj_1.num |
| 57 | local _obj_3 = getmetatable(_obj_1) | 58 | local _obj_2 = getmetatable(_obj_1) |
| 58 | add, sub = _obj_3.__add, _obj_3.__sub | 59 | add, sub = _obj_2.__add, _obj_2.__sub |
| 59 | end | 60 | end |
| 60 | setmetatable(_u53d8_u91cfa["变量b"], { }) | 61 | setmetatable(_u53d8_u91cfa["变量b"], { }) |
| 61 | _u53d8_u91cfx.abc = 123 | 62 | _u53d8_u91cfx.abc = 123 |
diff --git a/src/yuescript/parser.cpp b/src/yuescript/parser.cpp index 5e4caa2..5d0773c 100644 --- a/src/yuescript/parser.cpp +++ b/src/yuescript/parser.cpp | |||
| @@ -15,15 +15,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
| 15 | #include <stdexcept> | 15 | #include <stdexcept> |
| 16 | #include <unordered_map> | 16 | #include <unordered_map> |
| 17 | #include <unordered_set> | 17 | #include <unordered_set> |
| 18 | #include <memory> | ||
| 19 | 18 | ||
| 20 | #include "yuescript/parser.hpp" | 19 | #include "yuescript/parser.hpp" |
| 21 | 20 | ||
| 22 | #define _DEFER(code, line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto) { \ | ||
| 23 | code; \ | ||
| 24 | }) | ||
| 25 | #define DEFER(code) _DEFER(code, __LINE__) | ||
| 26 | |||
| 27 | namespace parserlib { | 21 | namespace parserlib { |
| 28 | 22 | ||
| 29 | // internal private class that manages access to the public classes' internals. | 23 | // internal private class that manages access to the public classes' internals. |
| @@ -914,7 +908,7 @@ bool _context::parse_non_term(rule& r) { | |||
| 914 | // save the state of the rule | 908 | // save the state of the rule |
| 915 | rule::_state old_state = r.m_state; | 909 | rule::_state old_state = r.m_state; |
| 916 | // restore the rule's state | 910 | // restore the rule's state |
| 917 | DEFER(r.m_state = old_state); | 911 | rule::_state_guard quard(old_state, &r.m_state); |
| 918 | 912 | ||
| 919 | // success/failure result | 913 | // success/failure result |
| 920 | bool ok = false; | 914 | bool ok = false; |
| @@ -1008,7 +1002,7 @@ bool _context::parse_term(rule& r) { | |||
| 1008 | // save the state of the rule | 1002 | // save the state of the rule |
| 1009 | rule::_state old_state = r.m_state; | 1003 | rule::_state old_state = r.m_state; |
| 1010 | // restore the rule's state | 1004 | // restore the rule's state |
| 1011 | DEFER(r.m_state = old_state); | 1005 | rule::_state_guard quard(old_state, &r.m_state); |
| 1012 | 1006 | ||
| 1013 | // success/failure result | 1007 | // success/failure result |
| 1014 | bool ok = false; | 1008 | bool ok = false; |
diff --git a/src/yuescript/parser.hpp b/src/yuescript/parser.hpp index 71bbc1a..5ab327f 100644 --- a/src/yuescript/parser.hpp +++ b/src/yuescript/parser.hpp | |||
| @@ -294,6 +294,17 @@ private: | |||
| 294 | , m_mode(mode) { } | 294 | , m_mode(mode) { } |
| 295 | }; | 295 | }; |
| 296 | 296 | ||
| 297 | struct _state_guard { | ||
| 298 | _state m_old_state; | ||
| 299 | _state* m_current_state; | ||
| 300 | _state_guard(const _state& old, _state* new_) | ||
| 301 | : m_old_state(old) | ||
| 302 | , m_current_state(new_) { } | ||
| 303 | ~_state_guard() { | ||
| 304 | *m_current_state = m_old_state; | ||
| 305 | } | ||
| 306 | }; | ||
| 307 | |||
| 297 | // internal expression | 308 | // internal expression |
| 298 | _expr* m_expr; | 309 | _expr* m_expr; |
| 299 | 310 | ||
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 32db488..cbb5f81 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.24.1"sv; | 78 | const std::string_view version = "0.25.0"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 { |
| @@ -1943,16 +1943,26 @@ private: | |||
| 1943 | 1943 | ||
| 1944 | std::string getDestrucureDefine(ExpListAssign_t* assignment) { | 1944 | std::string getDestrucureDefine(ExpListAssign_t* assignment) { |
| 1945 | auto info = extractDestructureInfo(assignment, true, false); | 1945 | auto info = extractDestructureInfo(assignment, true, false); |
| 1946 | if (info.assignment) { | ||
| 1947 | _buf << getPreDefineLine(info.assignment); | ||
| 1948 | } | ||
| 1949 | if (!info.destructures.empty()) { | 1946 | if (!info.destructures.empty()) { |
| 1950 | str_list defs; | 1947 | str_list defs; |
| 1951 | for (const auto& destruct : info.destructures) { | 1948 | for (const auto& des : info.destructures) { |
| 1952 | for (const auto& item : destruct.items) { | 1949 | if (std::holds_alternative<Destructure>(des)) { |
| 1953 | if (!item.targetVar.empty()) { | 1950 | const auto& destruct = std::get<Destructure>(des); |
| 1954 | if (addToScope(item.targetVar)) { | 1951 | for (const auto& item : destruct.items) { |
| 1955 | defs.push_back(item.targetVar); | 1952 | if (!item.targetVar.empty()) { |
| 1953 | if (addToScope(item.targetVar)) { | ||
| 1954 | defs.push_back(item.targetVar); | ||
| 1955 | } | ||
| 1956 | } | ||
| 1957 | } | ||
| 1958 | } else { | ||
| 1959 | const auto& assignment = std::get<AssignmentPtr>(des); | ||
| 1960 | if (!assignment.extraAssignment) { | ||
| 1961 | auto names = transformAssignDefs(assignment.ptr->expList, DefOp::Get); | ||
| 1962 | for (const auto& name : names) { | ||
| 1963 | if (addToScope(name.first)) { | ||
| 1964 | defs.push_back(name.first); | ||
| 1965 | } | ||
| 1956 | } | 1966 | } |
| 1957 | } | 1967 | } |
| 1958 | } | 1968 | } |
| @@ -2007,12 +2017,15 @@ private: | |||
| 2007 | 2017 | ||
| 2008 | void markDestructureConst(ExpListAssign_t* assignment) { | 2018 | void markDestructureConst(ExpListAssign_t* assignment) { |
| 2009 | auto info = extractDestructureInfo(assignment, true, false); | 2019 | auto info = extractDestructureInfo(assignment, true, false); |
| 2010 | for (auto& destruct : info.destructures) { | 2020 | for (const auto& des : info.destructures) { |
| 2011 | for (auto& item : destruct.items) { | 2021 | if (std::holds_alternative<Destructure>(des)) { |
| 2012 | if (item.targetVar.empty()) { | 2022 | const auto& destruct = std::get<Destructure>(des); |
| 2013 | throw CompileError("can only declare variable as const"sv, item.target); | 2023 | for (const auto& item : destruct.items) { |
| 2024 | if (item.targetVar.empty()) { | ||
| 2025 | throw CompileError("can only declare variable as const"sv, item.target); | ||
| 2026 | } | ||
| 2027 | markVarConst(item.targetVar); | ||
| 2014 | } | 2028 | } |
| 2015 | markVarConst(item.targetVar); | ||
| 2016 | } | 2029 | } |
| 2017 | } | 2030 | } |
| 2018 | } | 2031 | } |
| @@ -2079,7 +2092,7 @@ private: | |||
| 2079 | BLOCK_START | 2092 | BLOCK_START |
| 2080 | auto value = singleValueFrom(*it); | 2093 | auto value = singleValueFrom(*it); |
| 2081 | BREAK_IF(!value); | 2094 | BREAK_IF(!value); |
| 2082 | if (value->item.is<SimpleTable_t>() || value->get_by_path<SimpleValue_t, TableLit_t>()) { | 2095 | if (value->item.is<SimpleTable_t>() || value->get_by_path<SimpleValue_t, TableLit_t>() || value->get_by_path<SimpleValue_t, Comprehension_t>()) { |
| 2083 | holdItem = true; | 2096 | holdItem = true; |
| 2084 | break; | 2097 | break; |
| 2085 | } | 2098 | } |
| @@ -2404,11 +2417,24 @@ private: | |||
| 2404 | bool extraScope = false; | 2417 | bool extraScope = false; |
| 2405 | if (info.extraScope) { | 2418 | if (info.extraScope) { |
| 2406 | str_list defs; | 2419 | str_list defs; |
| 2407 | for (auto& destruct : info.destructures) { | 2420 | for (const auto& des : info.destructures) { |
| 2408 | for (auto& item : destruct.items) { | 2421 | if (std::holds_alternative<Destructure>(des)) { |
| 2409 | if (!item.targetVar.empty()) { | 2422 | const auto& destruct = std::get<Destructure>(des); |
| 2410 | if (!isDefined(item.targetVar)) { | 2423 | for (auto& item : destruct.items) { |
| 2411 | defs.push_back(item.targetVar); | 2424 | if (!item.targetVar.empty()) { |
| 2425 | if (!isDefined(item.targetVar)) { | ||
| 2426 | defs.push_back(item.targetVar); | ||
| 2427 | } | ||
| 2428 | } | ||
| 2429 | } | ||
| 2430 | } else { | ||
| 2431 | const auto& assignment = std::get<AssignmentPtr>(des); | ||
| 2432 | if (!assignment.extraAssignment) { | ||
| 2433 | auto names = transformAssignDefs(assignment.ptr->expList, DefOp::Get); | ||
| 2434 | for (const auto& name : names) { | ||
| 2435 | if (addToScope(name.first)) { | ||
| 2436 | defs.push_back(name.first); | ||
| 2437 | } | ||
| 2412 | } | 2438 | } |
| 2413 | } | 2439 | } |
| 2414 | } | 2440 | } |
| @@ -2426,10 +2452,13 @@ private: | |||
| 2426 | pushScope(); | 2452 | pushScope(); |
| 2427 | } | 2453 | } |
| 2428 | } | 2454 | } |
| 2429 | if (info.assignment) { | 2455 | for (auto& des : info.destructures) { |
| 2430 | transformAssignmentCommon(info.assignment, temp); | 2456 | if (std::holds_alternative<AssignmentPtr>(des)) { |
| 2431 | } | 2457 | auto assignment = std::get<AssignmentPtr>(des).ptr.get(); |
| 2432 | for (auto& destruct : info.destructures) { | 2458 | transformAssignment(assignment, temp); |
| 2459 | continue; | ||
| 2460 | } | ||
| 2461 | auto& destruct = std::get<Destructure>(des); | ||
| 2433 | std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs; | 2462 | std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs; |
| 2434 | bool extraScope = false; | 2463 | bool extraScope = false; |
| 2435 | if (!destruct.inlineAssignment && destruct.items.size() == 1) { | 2464 | if (!destruct.inlineAssignment && destruct.items.size() == 1) { |
| @@ -2931,17 +2960,21 @@ private: | |||
| 2931 | return pairs; | 2960 | return pairs; |
| 2932 | } | 2961 | } |
| 2933 | 2962 | ||
| 2963 | struct AssignmentPtr { | ||
| 2964 | ast_ptr<false, ExpListAssign_t> ptr; | ||
| 2965 | bool extraAssignment = false; | ||
| 2966 | }; | ||
| 2967 | |||
| 2934 | struct DestructureInfo { | 2968 | struct DestructureInfo { |
| 2935 | std::list<Destructure> destructures; | 2969 | std::list<std::variant<Destructure, AssignmentPtr>> destructures; |
| 2936 | ast_ptr<false, ExpListAssign_t> assignment; | ||
| 2937 | bool extraScope = false; | 2970 | bool extraScope = false; |
| 2938 | }; | 2971 | }; |
| 2939 | 2972 | ||
| 2940 | DestructureInfo extractDestructureInfo(ExpListAssign_t* assignment, bool varDefOnly, bool optional) { | 2973 | DestructureInfo extractDestructureInfo(ExpListAssign_t* assignment, bool varDefOnly, bool optional) { |
| 2974 | if (!assignment->action.is<Assign_t>()) return {}; | ||
| 2941 | auto x = assignment; | 2975 | auto x = assignment; |
| 2942 | bool extraScope = false; | 2976 | bool extraScope = false; |
| 2943 | std::list<Destructure> destructs; | 2977 | std::list<std::variant<Destructure, AssignmentPtr>> destructs; |
| 2944 | if (!assignment->action.is<Assign_t>()) return {destructs, nullptr}; | ||
| 2945 | auto exprs = assignment->expList->exprs.objects(); | 2978 | auto exprs = assignment->expList->exprs.objects(); |
| 2946 | auto values = assignment->action.to<Assign_t>()->values.objects(); | 2979 | auto values = assignment->action.to<Assign_t>()->values.objects(); |
| 2947 | size_t size = std::max(exprs.size(), values.size()); | 2980 | size_t size = std::max(exprs.size(), values.size()); |
| @@ -2951,10 +2984,26 @@ private: | |||
| 2951 | while (values.size() < size) values.emplace_back(nil); | 2984 | while (values.size() < size) values.emplace_back(nil); |
| 2952 | } | 2985 | } |
| 2953 | using iter = node_container::iterator; | 2986 | using iter = node_container::iterator; |
| 2954 | std::vector<std::pair<iter, iter>> destructPairs; | 2987 | std::vector<std::pair<iter, iter>> assignPairs; |
| 2955 | ast_list<false, ast_node> valueItems; | 2988 | ast_list<false, ast_node> valueItems; |
| 2956 | str_list temp; | 2989 | str_list temp; |
| 2957 | pushScope(); | 2990 | pushScope(); |
| 2991 | auto checkCommonAssignment = [&]() { | ||
| 2992 | if (!assignPairs.empty()) { | ||
| 2993 | auto expList = x->new_ptr<ExpList_t>(); | ||
| 2994 | auto newAssign = x->new_ptr<ExpListAssign_t>(); | ||
| 2995 | newAssign->expList.set(expList); | ||
| 2996 | auto assign = x->new_ptr<Assign_t>(); | ||
| 2997 | newAssign->action.set(assign); | ||
| 2998 | for (const auto& pair : assignPairs) { | ||
| 2999 | expList->exprs.push_back(*pair.first); | ||
| 3000 | assign->values.push_back(*pair.second); | ||
| 3001 | } | ||
| 3002 | assignPairs.clear(); | ||
| 3003 | destructs.push_back(AssignmentPtr{newAssign, false}); | ||
| 3004 | } | ||
| 3005 | }; | ||
| 3006 | bool hasDestructuring = false; | ||
| 2958 | for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) { | 3007 | for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) { |
| 2959 | auto expr = *i; | 3008 | auto expr = *i; |
| 2960 | auto value = singleValueFrom(expr); | 3009 | auto value = singleValueFrom(expr); |
| @@ -2974,6 +3023,8 @@ private: | |||
| 2974 | } | 3023 | } |
| 2975 | } | 3024 | } |
| 2976 | if (destructNode) { | 3025 | if (destructNode) { |
| 3026 | hasDestructuring = true; | ||
| 3027 | checkCommonAssignment(); | ||
| 2977 | if (*j != nil) { | 3028 | if (*j != nil) { |
| 2978 | if (auto ssVal = simpleSingleValueFrom(*j)) { | 3029 | if (auto ssVal = simpleSingleValueFrom(*j)) { |
| 2979 | switch (ssVal->value->get_id()) { | 3030 | switch (ssVal->value->get_id()) { |
| @@ -2989,7 +3040,6 @@ private: | |||
| 2989 | } | 3040 | } |
| 2990 | } | 3041 | } |
| 2991 | } | 3042 | } |
| 2992 | destructPairs.push_back({i, j}); | ||
| 2993 | auto subDestruct = destructNode->new_ptr<TableLit_t>(); | 3043 | auto subDestruct = destructNode->new_ptr<TableLit_t>(); |
| 2994 | auto subMetaDestruct = destructNode->new_ptr<TableLit_t>(); | 3044 | auto subMetaDestruct = destructNode->new_ptr<TableLit_t>(); |
| 2995 | const node_container* dlist = nullptr; | 3045 | const node_container* dlist = nullptr; |
| @@ -3113,19 +3163,26 @@ private: | |||
| 3113 | if (!varDefOnly && !subDestruct->values.empty() && !subMetaDestruct->values.empty()) { | 3163 | if (!varDefOnly && !subDestruct->values.empty() && !subMetaDestruct->values.empty()) { |
| 3114 | auto var = singleVariableFrom(*j, AccessType::None); | 3164 | auto var = singleVariableFrom(*j, AccessType::None); |
| 3115 | if (var.empty() || !isLocal(var)) { | 3165 | if (var.empty() || !isLocal(var)) { |
| 3166 | checkCommonAssignment(); | ||
| 3116 | auto objVar = getUnusedName("_obj_"sv); | 3167 | auto objVar = getUnusedName("_obj_"sv); |
| 3117 | addToScope(objVar); | 3168 | addToScope(objVar); |
| 3118 | valueItems.pop_back(); | 3169 | valueItems.pop_back(); |
| 3119 | valueItems.push_back(toAst<Exp_t>(objVar, *j)); | 3170 | valueItems.push_back(toAst<Exp_t>(objVar, *j)); |
| 3120 | exprs.push_back(valueItems.back()); | 3171 | auto expList = x->new_ptr<ExpList_t>(); |
| 3121 | values.push_back(*j); | 3172 | auto newAssign = x->new_ptr<ExpListAssign_t>(); |
| 3173 | newAssign->expList.set(expList); | ||
| 3174 | auto assign = x->new_ptr<Assign_t>(); | ||
| 3175 | newAssign->action.set(assign); | ||
| 3176 | expList->exprs.push_back(valueItems.back()); | ||
| 3177 | assign->values.push_back(*j); | ||
| 3178 | destructs.push_back(AssignmentPtr{newAssign, true}); | ||
| 3122 | extraScope = true; | 3179 | extraScope = true; |
| 3123 | } | 3180 | } |
| 3124 | } | 3181 | } |
| 3125 | TableLit_t* tabs[] = {subDestruct.get(), subMetaDestruct.get()}; | 3182 | TableLit_t* tabs[] = {subDestruct.get(), subMetaDestruct.get()}; |
| 3126 | for (auto tab : tabs) { | 3183 | for (auto tab : tabs) { |
| 3127 | if (!tab->values.empty()) { | 3184 | if (!tab->values.empty()) { |
| 3128 | auto& destruct = destructs.emplace_back(); | 3185 | Destructure destruct; |
| 3129 | if (!varDefOnly) { | 3186 | if (!varDefOnly) { |
| 3130 | destruct.value = valueItems.back(); | 3187 | destruct.value = valueItems.back(); |
| 3131 | destruct.valueVar = singleVariableFrom(destruct.value, AccessType::None); | 3188 | destruct.valueVar = singleVariableFrom(destruct.value, AccessType::None); |
| @@ -3172,29 +3229,28 @@ private: | |||
| 3172 | destruct.valueVar.clear(); | 3229 | destruct.valueVar.clear(); |
| 3173 | } | 3230 | } |
| 3174 | } | 3231 | } |
| 3232 | destructs.push_back(destruct); | ||
| 3175 | } | 3233 | } |
| 3176 | } | 3234 | } |
| 3235 | } else { | ||
| 3236 | assignPairs.push_back({i, j}); | ||
| 3177 | } | 3237 | } |
| 3178 | } | 3238 | } |
| 3179 | for (const auto& p : destructPairs) { | 3239 | if (!hasDestructuring) { |
| 3180 | exprs.erase(p.first); | 3240 | popScope(); |
| 3181 | values.erase(p.second); | 3241 | return {}; |
| 3182 | } | ||
| 3183 | ast_ptr<false, ExpListAssign_t> newAssignment; | ||
| 3184 | if (!destructPairs.empty() && !exprs.empty()) { | ||
| 3185 | auto x = assignment; | ||
| 3186 | auto expList = x->new_ptr<ExpList_t>(); | ||
| 3187 | auto newAssign = x->new_ptr<ExpListAssign_t>(); | ||
| 3188 | newAssign->expList.set(expList); | ||
| 3189 | for (auto expr : exprs) expList->exprs.push_back(expr); | ||
| 3190 | auto assign = x->new_ptr<Assign_t>(); | ||
| 3191 | for (auto value : values) assign->values.push_back(value); | ||
| 3192 | newAssign->action.set(assign); | ||
| 3193 | newAssignment = newAssign; | ||
| 3194 | } | 3242 | } |
| 3243 | checkCommonAssignment(); | ||
| 3195 | if (!varDefOnly) { | 3244 | if (!varDefOnly) { |
| 3196 | for (auto& des : destructs) { | 3245 | for (auto& d : destructs) { |
| 3246 | if (std::holds_alternative<AssignmentPtr>(d)) { | ||
| 3247 | continue; | ||
| 3248 | } | ||
| 3249 | auto& des = std::get<Destructure>(d); | ||
| 3197 | for (const auto& item : des.items) { | 3250 | for (const auto& item : des.items) { |
| 3251 | if (!item.structure) { | ||
| 3252 | continue; | ||
| 3253 | } | ||
| 3198 | for (auto node : item.structure->items.objects()) { | 3254 | for (auto node : item.structure->items.objects()) { |
| 3199 | if (auto exp = ast_cast<Exp_t>(node)) { | 3255 | if (auto exp = ast_cast<Exp_t>(node)) { |
| 3200 | if (auto value = simpleSingleValueFrom(node)) { | 3256 | if (auto value = simpleSingleValueFrom(node)) { |
| @@ -3236,7 +3292,7 @@ private: | |||
| 3236 | } | 3292 | } |
| 3237 | } | 3293 | } |
| 3238 | popScope(); | 3294 | popScope(); |
| 3239 | return {std::move(destructs), newAssignment, extraScope}; | 3295 | return {std::move(destructs), extraScope}; |
| 3240 | } | 3296 | } |
| 3241 | 3297 | ||
| 3242 | void transformAssignmentCommon(ExpListAssign_t* assignment, str_list& out) { | 3298 | void transformAssignmentCommon(ExpListAssign_t* assignment, str_list& out) { |
| @@ -4746,23 +4802,30 @@ private: | |||
| 4746 | } | 4802 | } |
| 4747 | auto info = extractDestructureInfo(assignment, true, false); | 4803 | auto info = extractDestructureInfo(assignment, true, false); |
| 4748 | if (!info.destructures.empty()) { | 4804 | if (!info.destructures.empty()) { |
| 4749 | for (const auto& destruct : info.destructures) | 4805 | for (const auto& des : info.destructures) { |
| 4750 | for (const auto& item : destruct.items) | 4806 | if (std::holds_alternative<Destructure>(des)) { |
| 4751 | if (!item.targetVar.empty()) { | 4807 | const auto& destruct = std::get<Destructure>(des); |
| 4752 | if (std::isupper(item.targetVar[0]) && capital) { | 4808 | for (const auto& item : destruct.items) { |
| 4753 | capital->decls.push_back(item.targetVar); | 4809 | if (!item.targetVar.empty()) { |
| 4754 | } else if (any) { | 4810 | if (std::isupper(item.targetVar[0]) && capital) { |
| 4755 | any->decls.push_back(item.targetVar); | 4811 | capital->decls.push_back(item.targetVar); |
| 4812 | } else if (any) { | ||
| 4813 | any->decls.push_back(item.targetVar); | ||
| 4814 | } | ||
| 4815 | } | ||
| 4816 | } | ||
| 4817 | } else { | ||
| 4818 | const auto& assignment = std::get<AssignmentPtr>(des); | ||
| 4819 | if (!assignment.extraAssignment) { | ||
| 4820 | auto defs = transformAssignDefs(assignment.ptr->expList, DefOp::Get); | ||
| 4821 | for (const auto& def : defs) { | ||
| 4822 | if (std::isupper(def.first[0]) && capital) { | ||
| 4823 | capital->decls.push_back(def.first); | ||
| 4824 | } else if (any) { | ||
| 4825 | any->decls.push_back(def.first); | ||
| 4826 | } | ||
| 4756 | } | 4827 | } |
| 4757 | } | 4828 | } |
| 4758 | } | ||
| 4759 | if (info.assignment) { | ||
| 4760 | auto defs = transformAssignDefs(info.assignment->expList, DefOp::Get); | ||
| 4761 | for (const auto& def : defs) { | ||
| 4762 | if (std::isupper(def.first[0]) && capital) { | ||
| 4763 | capital->decls.push_back(def.first); | ||
| 4764 | } else if (any) { | ||
| 4765 | any->decls.push_back(def.first); | ||
| 4766 | } | 4829 | } |
| 4767 | } | 4830 | } |
| 4768 | } | 4831 | } |
| @@ -8551,10 +8614,17 @@ private: | |||
| 8551 | } | 8614 | } |
| 8552 | auto info = extractDestructureInfo(assignment, true, false); | 8615 | auto info = extractDestructureInfo(assignment, true, false); |
| 8553 | if (!info.destructures.empty()) { | 8616 | if (!info.destructures.empty()) { |
| 8554 | for (const auto& destruct : info.destructures) | 8617 | for (const auto& des : info.destructures) { |
| 8555 | for (const auto& item : destruct.items) | 8618 | if (std::holds_alternative<AssignmentPtr>(des)) { |
| 8556 | if (!item.targetVar.empty() && addToScope(item.targetVar)) | 8619 | continue; |
| 8620 | } | ||
| 8621 | const auto& destruct = std::get<Destructure>(des); | ||
| 8622 | for (const auto& item : destruct.items) { | ||
| 8623 | if (!item.targetVar.empty() && addToScope(item.targetVar)) { | ||
| 8557 | varDefs.push_back(item.targetVar); | 8624 | varDefs.push_back(item.targetVar); |
| 8625 | } | ||
| 8626 | } | ||
| 8627 | } | ||
| 8558 | } | 8628 | } |
| 8559 | BLOCK_START | 8629 | BLOCK_START |
| 8560 | auto assign = assignment->action.as<Assign_t>(); | 8630 | auto assign = assignment->action.as<Assign_t>(); |
| @@ -9006,10 +9076,17 @@ private: | |||
| 9006 | } | 9076 | } |
| 9007 | auto info = extractDestructureInfo(assignment, true, false); | 9077 | auto info = extractDestructureInfo(assignment, true, false); |
| 9008 | if (!info.destructures.empty()) { | 9078 | if (!info.destructures.empty()) { |
| 9009 | for (const auto& destruct : info.destructures) | 9079 | for (const auto& des : info.destructures) { |
| 9010 | for (const auto& item : destruct.items) | 9080 | if (std::holds_alternative<AssignmentPtr>(des)) { |
| 9011 | if (!item.targetVar.empty() && !isDefined(item.targetVar)) | 9081 | continue; |
| 9082 | } | ||
| 9083 | const auto& destruct = std::get<Destructure>(des); | ||
| 9084 | for (const auto& item : destruct.items) { | ||
| 9085 | if (!item.targetVar.empty() && !isDefined(item.targetVar)) { | ||
| 9012 | return traversal::Stop; | 9086 | return traversal::Stop; |
| 9087 | } | ||
| 9088 | } | ||
| 9089 | } | ||
| 9013 | } | 9090 | } |
| 9014 | BLOCK_START | 9091 | BLOCK_START |
| 9015 | auto assign = assignment->action.as<Assign_t>(); | 9092 | auto assign = assignment->action.as<Assign_t>(); |
| @@ -9248,13 +9325,19 @@ private: | |||
| 9248 | auto names = transformAssignDefs(expList, DefOp::Get); | 9325 | auto names = transformAssignDefs(expList, DefOp::Get); |
| 9249 | auto info = extractDestructureInfo(assignment, true, false); | 9326 | auto info = extractDestructureInfo(assignment, true, false); |
| 9250 | if (!info.destructures.empty()) { | 9327 | if (!info.destructures.empty()) { |
| 9251 | for (const auto& destruct : info.destructures) | 9328 | for (const auto& des : info.destructures) { |
| 9252 | for (const auto& item : destruct.items) | 9329 | if (std::holds_alternative<AssignmentPtr>(des)) { |
| 9330 | continue; | ||
| 9331 | } | ||
| 9332 | const auto& destruct = std::get<Destructure>(des); | ||
| 9333 | for (const auto& item : destruct.items) { | ||
| 9253 | if (!item.targetVar.empty()) { | 9334 | if (!item.targetVar.empty()) { |
| 9254 | auto dot = ast_cast<DotChainItem_t>(item.structure->items.back()); | 9335 | auto dot = ast_cast<DotChainItem_t>(item.structure->items.back()); |
| 9255 | auto uname = dot->name.as<UnicodeName_t>(); | 9336 | auto uname = dot->name.as<UnicodeName_t>(); |
| 9256 | names.emplace_back(item.targetVar, uname ? _parser.toString(uname) : Empty); | 9337 | names.emplace_back(item.targetVar, uname ? _parser.toString(uname) : Empty); |
| 9257 | } | 9338 | } |
| 9339 | } | ||
| 9340 | } | ||
| 9258 | } | 9341 | } |
| 9259 | if (_info.exportDefault) { | 9342 | if (_info.exportDefault) { |
| 9260 | out.back().append(indent() + _info.moduleName + " = "s + names.back().first + nlr(exportNode)); | 9343 | out.back().append(indent() + _info.moduleName + " = "s + names.back().first + nlr(exportNode)); |
| @@ -10213,7 +10296,11 @@ private: | |||
| 10213 | auto info = extractDestructureInfo(assignment, true, false); | 10296 | auto info = extractDestructureInfo(assignment, true, false); |
| 10214 | transformAssignment(assignment, temp, true); | 10297 | transformAssignment(assignment, temp, true); |
| 10215 | str_list conds; | 10298 | str_list conds; |
| 10216 | for (const auto& destruct : info.destructures) { | 10299 | for (const auto& des : info.destructures) { |
| 10300 | if (std::holds_alternative<AssignmentPtr>(des)) { | ||
| 10301 | continue; | ||
| 10302 | } | ||
| 10303 | const auto& destruct = std::get<Destructure>(des); | ||
| 10217 | for (const auto& item : destruct.items) { | 10304 | for (const auto& item : destruct.items) { |
| 10218 | if (!item.defVal) { | 10305 | if (!item.defVal) { |
| 10219 | transformExp(item.target, conds, ExpUsage::Closure); | 10306 | transformExp(item.target, conds, ExpUsage::Closure); |
| @@ -10475,7 +10562,11 @@ private: | |||
| 10475 | assignment->expList.set(leftList); | 10562 | assignment->expList.set(leftList); |
| 10476 | assignment->action.set(assign); | 10563 | assignment->action.set(assign); |
| 10477 | auto info = extractDestructureInfo(assignment, true, false); | 10564 | auto info = extractDestructureInfo(assignment, true, false); |
| 10478 | for (auto& destruct : info.destructures) { | 10565 | for (const auto& des : info.destructures) { |
| 10566 | if (std::holds_alternative<AssignmentPtr>(des)) { | ||
| 10567 | continue; | ||
| 10568 | } | ||
| 10569 | const auto& destruct = std::get<Destructure>(des); | ||
| 10479 | for (auto& item : destruct.items) { | 10570 | for (auto& item : destruct.items) { |
| 10480 | if (item.targetVar.empty()) { | 10571 | if (item.targetVar.empty()) { |
| 10481 | throw CompileError("can only declare variable as const"sv, item.target); | 10572 | throw CompileError("can only declare variable as const"sv, item.target); |
| @@ -10569,7 +10660,11 @@ private: | |||
| 10569 | assignment->action.set(assignB); | 10660 | assignment->action.set(assignB); |
| 10570 | auto info = extractDestructureInfo(assignment, true, false); | 10661 | auto info = extractDestructureInfo(assignment, true, false); |
| 10571 | str_list vars; | 10662 | str_list vars; |
| 10572 | for (auto& destruct : info.destructures) { | 10663 | for (auto& des : info.destructures) { |
| 10664 | if (std::holds_alternative<AssignmentPtr>(des)) { | ||
| 10665 | continue; | ||
| 10666 | } | ||
| 10667 | const auto& destruct = std::get<Destructure>(des); | ||
| 10573 | for (auto& item : destruct.items) { | 10668 | for (auto& item : destruct.items) { |
| 10574 | if (item.targetVar.empty()) { | 10669 | if (item.targetVar.empty()) { |
| 10575 | throw CompileError("can only declare variable as const"sv, item.target); | 10670 | throw CompileError("can only declare variable as const"sv, item.target); |
