diff options
| author | Li Jin <dragon-fly@qq.com> | 2024-09-04 12:16:10 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2024-09-04 12:16:25 +0800 |
| commit | 461bf7c32408553125d71b23e04e21fed690c4f5 (patch) | |
| tree | 4442efd0fc2524e82be63e12e3e046a0532b26dd | |
| parent | 2f8215df7288e0aac690c8e8b1ff79865f114302 (diff) | |
| download | yuescript-0.25.1.tar.gz yuescript-0.25.1.tar.bz2 yuescript-0.25.1.zip | |
fix more cases for evaluation order of multi-value assignments.v0.25.1
| -rw-r--r-- | spec/inputs/assign.yue | 20 | ||||
| -rw-r--r-- | spec/outputs/assign.lua | 97 | ||||
| -rw-r--r-- | spec/outputs/destructure.lua | 5 | ||||
| -rw-r--r-- | spec/outputs/metatable.lua | 5 | ||||
| -rw-r--r-- | spec/outputs/unicode/assign.lua | 37 | ||||
| -rw-r--r-- | spec/outputs/unicode/destructure.lua | 5 | ||||
| -rw-r--r-- | spec/outputs/unicode/metatable.lua | 5 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 121 |
8 files changed, 194 insertions, 101 deletions
diff --git a/spec/inputs/assign.yue b/spec/inputs/assign.yue index 2c89a99..514aeed 100644 --- a/spec/inputs/assign.yue +++ b/spec/inputs/assign.yue | |||
| @@ -63,6 +63,20 @@ do | |||
| 63 | 123, tb | 63 | 123, tb |
| 64 | 64 | ||
| 65 | do | 65 | do |
| 66 | a, b[] = if x | ||
| 67 | switch y | ||
| 68 | when 1 | ||
| 69 | f! | ||
| 70 | print a, b | ||
| 71 | |||
| 72 | do | ||
| 73 | a, {b} = if x | ||
| 74 | f! | ||
| 75 | else | ||
| 76 | 123, tb | ||
| 77 | print a, b | ||
| 78 | |||
| 79 | do | ||
| 66 | a, b[], c, d.<add> = if x | 80 | a, b[], c, d.<add> = if x |
| 67 | switch y | 81 | switch y |
| 68 | when 1 | 82 | when 1 |
| @@ -75,6 +89,12 @@ do | |||
| 75 | do | 89 | do |
| 76 | print 123 | 90 | print 123 |
| 77 | 1, f2! | 91 | 1, f2! |
| 92 | print a, b, c, d | ||
| 93 | |||
| 94 | do | ||
| 95 | x, [a, b], tb.<>, c[] = 1, if cond | ||
| 96 | f! | ||
| 97 | print x, a, b | ||
| 78 | 98 | ||
| 79 | do | 99 | do |
| 80 | a = b = c = d = 0 | 100 | a = b = c = d = 0 |
diff --git a/spec/outputs/assign.lua b/spec/outputs/assign.lua index 1978df1..162a563 100644 --- a/spec/outputs/assign.lua +++ b/spec/outputs/assign.lua | |||
| @@ -67,50 +67,95 @@ return _(function() | |||
| 67 | end | 67 | end |
| 68 | do | 68 | do |
| 69 | local a | 69 | local a |
| 70 | local _obj_0, _obj_1 | ||
| 70 | if x then | 71 | if x then |
| 71 | local _exp_0 = y | 72 | local _exp_0 = y |
| 72 | if 1 == _exp_0 then | 73 | if 1 == _exp_0 then |
| 73 | local _obj_0, _obj_1 = f() | 74 | _obj_0, _obj_1 = f() |
| 74 | b[#b + 1] = _obj_1 | ||
| 75 | a = _obj_0 | ||
| 76 | end | 75 | end |
| 77 | end | 76 | end |
| 77 | a = _obj_0 | ||
| 78 | b[#b + 1] = _obj_1 | ||
| 78 | end | 79 | end |
| 79 | do | 80 | do |
| 80 | local a, b | 81 | local a, b |
| 82 | local _obj_0, _obj_1 | ||
| 81 | if x then | 83 | if x then |
| 82 | local _obj_0, _obj_1 = f() | 84 | _obj_0, _obj_1 = f() |
| 85 | else | ||
| 86 | _obj_0, _obj_1 = 123, tb | ||
| 87 | end | ||
| 88 | a = _obj_0 | ||
| 89 | b = _obj_1[1] | ||
| 90 | end | ||
| 91 | do | ||
| 92 | local a | ||
| 93 | do | ||
| 94 | local _obj_0, _obj_1 | ||
| 95 | if x then | ||
| 96 | local _exp_0 = y | ||
| 97 | if 1 == _exp_0 then | ||
| 98 | _obj_0, _obj_1 = f() | ||
| 99 | end | ||
| 100 | end | ||
| 101 | a = _obj_0 | ||
| 102 | b[#b + 1] = _obj_1 | ||
| 103 | end | ||
| 104 | print(a, b) | ||
| 105 | end | ||
| 106 | do | ||
| 107 | local a, b | ||
| 108 | do | ||
| 109 | local _obj_0, _obj_1 | ||
| 110 | if x then | ||
| 111 | _obj_0, _obj_1 = f() | ||
| 112 | else | ||
| 113 | _obj_0, _obj_1 = 123, tb | ||
| 114 | end | ||
| 83 | a = _obj_0 | 115 | a = _obj_0 |
| 84 | b = _obj_1[1] | 116 | b = _obj_1[1] |
| 85 | else | ||
| 86 | a = 123 | ||
| 87 | b = tb[1] | ||
| 88 | end | 117 | end |
| 118 | print(a, b) | ||
| 89 | end | 119 | end |
| 90 | do | 120 | do |
| 91 | local a, c | 121 | local a, c |
| 92 | if x then | 122 | do |
| 93 | local _exp_0 = y | 123 | local _obj_0, _obj_1, _obj_2, _obj_3 |
| 94 | if 1 == _exp_0 then | 124 | if x then |
| 95 | local _obj_0, _obj_1, _obj_2, _obj_3 = f() | 125 | local _exp_0 = y |
| 96 | b[#b + 1] = _obj_1 | 126 | if 1 == _exp_0 then |
| 97 | a, c, getmetatable(d).__add = _obj_0, _obj_2, _obj_3 | 127 | _obj_0, _obj_1, _obj_2, _obj_3 = f() |
| 98 | end | 128 | end |
| 99 | elseif x2 then | 129 | elseif x2 then |
| 100 | if y2 then | 130 | if y2 then |
| 101 | local _obj_0, _obj_1, _obj_2, _obj_3 = f1() | 131 | _obj_0, _obj_1, _obj_2, _obj_3 = f1() |
| 102 | b[#b + 1] = _obj_1 | 132 | end |
| 103 | a, c, getmetatable(d).__add = _obj_0, _obj_2, _obj_3 | 133 | else |
| 134 | print("hello") | ||
| 135 | do | ||
| 136 | print(123) | ||
| 137 | _obj_0, _obj_1, _obj_2, _obj_3 = 1, f2() | ||
| 138 | end | ||
| 104 | end | 139 | end |
| 105 | else | 140 | a = _obj_0 |
| 106 | print("hello") | 141 | b[#b + 1] = _obj_1 |
| 107 | do | 142 | c, getmetatable(d).__add = _obj_2, _obj_3 |
| 108 | print(123) | 143 | end |
| 109 | local _obj_0, _obj_1, _obj_2 = f2() | 144 | print(a, b, c, d) |
| 110 | b[#b + 1] = _obj_0 | 145 | end |
| 111 | a, c, getmetatable(d).__add = 1, _obj_1, _obj_2 | 146 | do |
| 147 | local x, a, b | ||
| 148 | do | ||
| 149 | local _obj_0, _obj_1, _obj_2 | ||
| 150 | if cond then | ||
| 151 | _obj_0, _obj_1, _obj_2 = f() | ||
| 112 | end | 152 | end |
| 153 | x = 1 | ||
| 154 | a, b = _obj_0[1], _obj_0[2] | ||
| 155 | setmetatable(tb, _obj_1) | ||
| 156 | c[#c + 1] = _obj_2 | ||
| 113 | end | 157 | end |
| 158 | print(x, a, b) | ||
| 114 | end | 159 | end |
| 115 | do | 160 | do |
| 116 | local a = 0 | 161 | local a = 0 |
diff --git a/spec/outputs/destructure.lua b/spec/outputs/destructure.lua index d8517a0..44da58b 100644 --- a/spec/outputs/destructure.lua +++ b/spec/outputs/destructure.lua | |||
| @@ -427,14 +427,15 @@ do | |||
| 427 | local x1, x2, x3, d, b, e | 427 | local x1, x2, x3, d, b, e |
| 428 | do | 428 | do |
| 429 | 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() |
| 430 | x1, x2, x3 = 1, 2, 3 | ||
| 430 | do | 431 | do |
| 431 | local _obj_5 = a | 432 | local _obj_5 = a |
| 432 | _obj_5[#_obj_5 + 1] = _obj_0 | 433 | _obj_5[#_obj_5 + 1] = _obj_0 |
| 433 | end | 434 | end |
| 434 | setmetatable(c, _obj_4) | 435 | d = _obj_1 |
| 435 | x1, x2, x3, d = 1, 2, 3, _obj_1 | ||
| 436 | b = _obj_2[1] | 436 | b = _obj_2[1] |
| 437 | e = _obj_3 | 437 | e = _obj_3 |
| 438 | setmetatable(c, _obj_4) | ||
| 438 | end | 439 | end |
| 439 | local y1, y2, y3, y4 | 440 | local y1, y2, y3, y4 |
| 440 | local _obj_0, _obj_1 = f2() | 441 | local _obj_0, _obj_1 = f2() |
diff --git a/spec/outputs/metatable.lua b/spec/outputs/metatable.lua index 0715b58..974a6e4 100644 --- a/spec/outputs/metatable.lua +++ b/spec/outputs/metatable.lua | |||
| @@ -58,11 +58,12 @@ do | |||
| 58 | local _obj_2 = getmetatable(_obj_1) | 58 | local _obj_2 = getmetatable(_obj_1) |
| 59 | add, sub = _obj_2.__add, _obj_2.__sub | 59 | add, sub = _obj_2.__add, _obj_2.__sub |
| 60 | end | 60 | end |
| 61 | setmetatable(a.b, { }) | ||
| 62 | x.abc = 123 | 61 | x.abc = 123 |
| 62 | setmetatable(a.b, { }) | ||
| 63 | setmetatable(func(), mt) | 63 | setmetatable(func(), mt) |
| 64 | a = 1 | ||
| 64 | setmetatable(b.c, mt) | 65 | setmetatable(b.c, mt) |
| 65 | a, d, e = 1, "abc", nil | 66 | d, e = "abc", nil |
| 66 | local is_same = getmetatable(a).__index == getmetatable(a).__index | 67 | local is_same = getmetatable(a).__index == getmetatable(a).__index |
| 67 | setmetatable(a, { | 68 | setmetatable(a, { |
| 68 | __index = tb | 69 | __index = tb |
diff --git a/spec/outputs/unicode/assign.lua b/spec/outputs/unicode/assign.lua index e883d68..bf43953 100644 --- a/spec/outputs/unicode/assign.lua +++ b/spec/outputs/unicode/assign.lua | |||
| @@ -71,53 +71,50 @@ return __u65e0_u6548_u53d8_u91cf(function() | |||
| 71 | end | 71 | end |
| 72 | do | 72 | do |
| 73 | local _u53d8_u91cfa | 73 | local _u53d8_u91cfa |
| 74 | local _obj_0, _obj_1 | ||
| 74 | if x_u6761_u4ef6 then | 75 | if x_u6761_u4ef6 then |
| 75 | local _exp_0 = _u5bf9_u8c61y | 76 | local _exp_0 = _u5bf9_u8c61y |
| 76 | if 1 == _exp_0 then | 77 | if 1 == _exp_0 then |
| 77 | local _obj_0, _obj_1 = _u51fd_u6570() | 78 | _obj_0, _obj_1 = _u51fd_u6570() |
| 78 | _u53d8_u91cfb[#_u53d8_u91cfb + 1] = _obj_1 | ||
| 79 | _u53d8_u91cfa = _obj_0 | ||
| 80 | end | 79 | end |
| 81 | end | 80 | end |
| 81 | _u53d8_u91cfa = _obj_0 | ||
| 82 | _u53d8_u91cfb[#_u53d8_u91cfb + 1] = _obj_1 | ||
| 82 | end | 83 | end |
| 83 | do | 84 | do |
| 84 | local _u53d8_u91cfa, _u5143_u7d20b | 85 | local _u53d8_u91cfa, _u5143_u7d20b |
| 86 | local _obj_0, _obj_1 | ||
| 85 | if x_u6761_u4ef6 then | 87 | if x_u6761_u4ef6 then |
| 86 | local _obj_0, _obj_1 = _u51fd_u6570() | 88 | _obj_0, _obj_1 = _u51fd_u6570() |
| 87 | _u53d8_u91cfa = _obj_0 | ||
| 88 | _u5143_u7d20b = _obj_1[1] | ||
| 89 | else | 89 | else |
| 90 | _u53d8_u91cfa = 123 | 90 | _obj_0, _obj_1 = 123, _u8868 |
| 91 | _u5143_u7d20b = _u8868[1] | ||
| 92 | end | 91 | end |
| 92 | _u53d8_u91cfa = _obj_0 | ||
| 93 | _u5143_u7d20b = _obj_1[1] | ||
| 93 | end | 94 | end |
| 94 | do | 95 | do |
| 95 | local _u53d8_u91cfa, _u5bf9_u8c61c | 96 | local _u53d8_u91cfa, _u5bf9_u8c61c |
| 97 | local _obj_0, _obj_1, _obj_2, _obj_3 | ||
| 96 | if _u6761_u4ef6x then | 98 | if _u6761_u4ef6x then |
| 97 | local _exp_0 = _u5bf9_u8c61y | 99 | local _exp_0 = _u5bf9_u8c61y |
| 98 | if 1 == _exp_0 then | 100 | if 1 == _exp_0 then |
| 99 | local _obj_0, _obj_1, _obj_2, _obj_3 = _u51fd_u6570() | 101 | _obj_0, _obj_1, _obj_2, _obj_3 = _u51fd_u6570() |
| 100 | local _obj_4 = _u6570_u7ec4b | ||
| 101 | _obj_4[#_obj_4 + 1] = _obj_1 | ||
| 102 | _u53d8_u91cfa, _u5bf9_u8c61c, getmetatable(_u5bf9_u8c61d).__add = _obj_0, _obj_2, _obj_3 | ||
| 103 | end | 102 | end |
| 104 | elseif _u6761_u4ef6x2 then | 103 | elseif _u6761_u4ef6x2 then |
| 105 | if _u6761_u4ef6y2 then | 104 | if _u6761_u4ef6y2 then |
| 106 | local _obj_0, _obj_1, _obj_2, _obj_3 = _u51fd_u65701() | 105 | _obj_0, _obj_1, _obj_2, _obj_3 = _u51fd_u65701() |
| 107 | local _obj_4 = _u6570_u7ec4b | ||
| 108 | _obj_4[#_obj_4 + 1] = _obj_1 | ||
| 109 | _u53d8_u91cfa, _u5bf9_u8c61c, getmetatable(_u5bf9_u8c61d).__add = _obj_0, _obj_2, _obj_3 | ||
| 110 | end | 106 | end |
| 111 | else | 107 | else |
| 112 | _u6253_u5370("hello") | 108 | _u6253_u5370("hello") |
| 113 | do | 109 | do |
| 114 | _u6253_u5370(123) | 110 | _u6253_u5370(123) |
| 115 | local _obj_0, _obj_1, _obj_2 = _u51fd_u65702() | 111 | _obj_0, _obj_1, _obj_2, _obj_3 = 1, _u51fd_u65702() |
| 116 | local _obj_3 = _u6570_u7ec4b | ||
| 117 | _obj_3[#_obj_3 + 1] = _obj_0 | ||
| 118 | _u53d8_u91cfa, _u5bf9_u8c61c, getmetatable(_u5bf9_u8c61d).__add = 1, _obj_1, _obj_2 | ||
| 119 | end | 112 | end |
| 120 | end | 113 | end |
| 114 | _u53d8_u91cfa = _obj_0 | ||
| 115 | local _obj_4 = _u6570_u7ec4b | ||
| 116 | _obj_4[#_obj_4 + 1] = _obj_1 | ||
| 117 | _u5bf9_u8c61c, getmetatable(_u5bf9_u8c61d).__add = _obj_2, _obj_3 | ||
| 121 | end | 118 | end |
| 122 | do | 119 | do |
| 123 | local _u53d8_u91cfa = 0 | 120 | local _u53d8_u91cfa = 0 |
diff --git a/spec/outputs/unicode/destructure.lua b/spec/outputs/unicode/destructure.lua index 29697fa..27c4d47 100644 --- a/spec/outputs/unicode/destructure.lua +++ b/spec/outputs/unicode/destructure.lua | |||
| @@ -389,14 +389,15 @@ do | |||
| 389 | local _u53d8_u91cf1, _u53d8_u91cf2, _u53d8_u91cf3, _u53d8_u91cfd, _u5143_u7d20b, _u53d8_u91cfe | 389 | local _u53d8_u91cf1, _u53d8_u91cf2, _u53d8_u91cf3, _u53d8_u91cfd, _u5143_u7d20b, _u53d8_u91cfe |
| 390 | do | 390 | do |
| 391 | 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() |
| 392 | _u53d8_u91cf1, _u53d8_u91cf2, _u53d8_u91cf3 = 1, 2, 3 | ||
| 392 | do | 393 | do |
| 393 | local _obj_5 = _u6570_u7ec4a | 394 | local _obj_5 = _u6570_u7ec4a |
| 394 | _obj_5[#_obj_5 + 1] = _obj_0 | 395 | _obj_5[#_obj_5 + 1] = _obj_0 |
| 395 | end | 396 | end |
| 396 | setmetatable(_u5bf9_u8c61c, _obj_4) | 397 | _u53d8_u91cfd = _obj_1 |
| 397 | _u53d8_u91cf1, _u53d8_u91cf2, _u53d8_u91cf3, _u53d8_u91cfd = 1, 2, 3, _obj_1 | ||
| 398 | _u5143_u7d20b = _obj_2[1] | 398 | _u5143_u7d20b = _obj_2[1] |
| 399 | _u53d8_u91cfe = _obj_3 | 399 | _u53d8_u91cfe = _obj_3 |
| 400 | setmetatable(_u5bf9_u8c61c, _obj_4) | ||
| 400 | end | 401 | end |
| 401 | local _u53d8_u91cfy1, _u5b57_u6bb5y2, _u5b57_u6bb5y3, _u53d8_u91cfy4 | 402 | local _u53d8_u91cfy1, _u5b57_u6bb5y2, _u5b57_u6bb5y3, _u53d8_u91cfy4 |
| 402 | local _obj_0, _obj_1 = _u51fd_u65702() | 403 | local _obj_0, _obj_1 = _u51fd_u65702() |
diff --git a/spec/outputs/unicode/metatable.lua b/spec/outputs/unicode/metatable.lua index f948d21..970e52c 100644 --- a/spec/outputs/unicode/metatable.lua +++ b/spec/outputs/unicode/metatable.lua | |||
| @@ -58,11 +58,12 @@ do | |||
| 58 | local _obj_2 = getmetatable(_obj_1) | 58 | local _obj_2 = getmetatable(_obj_1) |
| 59 | add, sub = _obj_2.__add, _obj_2.__sub | 59 | add, sub = _obj_2.__add, _obj_2.__sub |
| 60 | end | 60 | end |
| 61 | setmetatable(_u53d8_u91cfa["变量b"], { }) | ||
| 62 | _u53d8_u91cfx.abc = 123 | 61 | _u53d8_u91cfx.abc = 123 |
| 62 | setmetatable(_u53d8_u91cfa["变量b"], { }) | ||
| 63 | setmetatable(_u51fd_u6570(), mt) | 63 | setmetatable(_u51fd_u6570(), mt) |
| 64 | _u53d8_u91cfa = 1 | ||
| 64 | setmetatable(_u53d8_u91cfb["变量c"], mt) | 65 | setmetatable(_u53d8_u91cfb["变量c"], mt) |
| 65 | _u53d8_u91cfa, _u53d8_u91cfd, _u53d8_u91cfe = 1, "abc", nil | 66 | _u53d8_u91cfd, _u53d8_u91cfe = "abc", nil |
| 66 | local _u76f8_u540c = getmetatable(_u53d8_u91cfa).__index == getmetatable(_u53d8_u91cfa).__index | 67 | local _u76f8_u540c = getmetatable(_u53d8_u91cfa).__index == getmetatable(_u53d8_u91cfa).__index |
| 67 | setmetatable(_u53d8_u91cfa, { | 68 | setmetatable(_u53d8_u91cfa, { |
| 68 | __index = _u8868 | 69 | __index = _u8868 |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index cbb5f81..5d031db 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.0"sv; | 78 | const std::string_view version = "0.25.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 { |
| @@ -2047,34 +2047,34 @@ private: | |||
| 2047 | } | 2047 | } |
| 2048 | throw CompileError(clearBuf(), values.front()); | 2048 | throw CompileError(clearBuf(), values.front()); |
| 2049 | } | 2049 | } |
| 2050 | bool checkValuesLater = false; | ||
| 2051 | if (exprs.size() > values.size()) { | 2050 | if (exprs.size() > values.size()) { |
| 2052 | BLOCK_START | 2051 | BLOCK_START |
| 2052 | bool needHoldValues = false; | ||
| 2053 | switch (values.back()->get_id()) { | 2053 | switch (values.back()->get_id()) { |
| 2054 | case id<If_t>(): | 2054 | case id<If_t>(): |
| 2055 | case id<Switch_t>(): | 2055 | case id<Switch_t>(): |
| 2056 | checkValuesLater = true; | 2056 | needHoldValues = true; |
| 2057 | break; | 2057 | break; |
| 2058 | } | 2058 | } |
| 2059 | BREAK_IF(checkValuesLater); | 2059 | if (!needHoldValues) { |
| 2060 | auto value = singleValueFrom(values.back()); | 2060 | if (auto value = singleValueFrom(values.back())) { |
| 2061 | if (!value) { | 2061 | if (auto val = value->item.as<SimpleValue_t>()) { |
| 2062 | _buf << exprs.size() << " right values expected, got "sv << values.size(); | 2062 | switch (val->value->get_id()) { |
| 2063 | throw CompileError(clearBuf(), values.front()); | 2063 | case id<If_t>(): |
| 2064 | } | 2064 | case id<Switch_t>(): |
| 2065 | if (auto val = value->item.as<SimpleValue_t>()) { | 2065 | case id<Do_t>(): |
| 2066 | switch (val->value->get_id()) { | 2066 | case id<Try_t>(): |
| 2067 | case id<If_t>(): | 2067 | needHoldValues = true; |
| 2068 | case id<Switch_t>(): | 2068 | break; |
| 2069 | case id<Do_t>(): | 2069 | } |
| 2070 | case id<Try_t>(): | 2070 | } else if (auto chainValue = value->item.as<ChainValue_t>()) { |
| 2071 | checkValuesLater = true; | 2071 | if (chainValue && ast_is<Invoke_t, InvokeArgs_t>(chainValue->items.back())) { |
| 2072 | break; | 2072 | needHoldValues = true; |
| 2073 | } | ||
| 2074 | } | ||
| 2073 | } | 2075 | } |
| 2074 | BREAK_IF(checkValuesLater); | ||
| 2075 | } | 2076 | } |
| 2076 | auto chainValue = value->item.as<ChainValue_t>(); | 2077 | if (!needHoldValues) { |
| 2077 | if (!chainValue || !ast_is<Invoke_t, InvokeArgs_t>(chainValue->items.back())) { | ||
| 2078 | _buf << exprs.size() << " right values expected, got "sv << values.size(); | 2078 | _buf << exprs.size() << " right values expected, got "sv << values.size(); |
| 2079 | throw CompileError(clearBuf(), values.front()); | 2079 | throw CompileError(clearBuf(), values.front()); |
| 2080 | } | 2080 | } |
| @@ -2138,7 +2138,7 @@ private: | |||
| 2138 | temp.push_back(indent() + "do"s + nll(assignment)); | 2138 | temp.push_back(indent() + "do"s + nll(assignment)); |
| 2139 | pushScope(); | 2139 | pushScope(); |
| 2140 | } | 2140 | } |
| 2141 | transformAssignmentCommon(preAssignment, temp); | 2141 | transformAssignment(preAssignment, temp); |
| 2142 | transformAssignment(assignment, temp); | 2142 | transformAssignment(assignment, temp); |
| 2143 | if (needScope) { | 2143 | if (needScope) { |
| 2144 | popScope(); | 2144 | popScope(); |
| @@ -2148,17 +2148,52 @@ private: | |||
| 2148 | return; | 2148 | return; |
| 2149 | BLOCK_END | 2149 | BLOCK_END |
| 2150 | } | 2150 | } |
| 2151 | if (!checkValuesLater) { | 2151 | { |
| 2152 | auto vit = values.begin(); | 2152 | auto vit = values.begin(); |
| 2153 | for (auto it = exprs.begin(); it != exprs.end(); ++it) { | 2153 | for (auto it = exprs.begin(); it != exprs.end(); ++it) { |
| 2154 | auto splitAssignment = [&]() { | ||
| 2155 | auto beforeAssignment = x->new_ptr<ExpListAssign_t>(); | ||
| 2156 | auto afterAssignment = x->new_ptr<ExpListAssign_t>(); | ||
| 2157 | { | ||
| 2158 | auto beforeExpList = x->new_ptr<ExpList_t>(); | ||
| 2159 | auto beforeAssign = x->new_ptr<Assign_t>(); | ||
| 2160 | beforeAssignment->expList.set(beforeExpList); | ||
| 2161 | beforeAssignment->action.set(beforeAssign); | ||
| 2162 | auto afterExpList = x->new_ptr<ExpList_t>(); | ||
| 2163 | auto afterAssign = x->new_ptr<Assign_t>(); | ||
| 2164 | afterAssignment->expList.set(afterExpList); | ||
| 2165 | afterAssignment->action.set(afterAssign); | ||
| 2166 | ExpList_t* currentExpList = beforeExpList.get(); | ||
| 2167 | for (auto exp : exprs) { | ||
| 2168 | if (exp != *it) { | ||
| 2169 | currentExpList->exprs.push_back(exp); | ||
| 2170 | } else { | ||
| 2171 | currentExpList = afterExpList.get(); | ||
| 2172 | } | ||
| 2173 | } | ||
| 2174 | Assign_t* currentAssign = beforeAssign.get(); | ||
| 2175 | for (auto value : values) { | ||
| 2176 | if (value != *vit) { | ||
| 2177 | currentAssign->values.push_back(value); | ||
| 2178 | } else { | ||
| 2179 | currentAssign = afterAssign.get(); | ||
| 2180 | } | ||
| 2181 | } | ||
| 2182 | } | ||
| 2183 | return std::make_pair(beforeAssignment, afterAssignment); | ||
| 2184 | }; | ||
| 2154 | BLOCK_START | 2185 | BLOCK_START |
| 2155 | auto value = singleValueFrom(*it); | 2186 | auto value = singleValueFrom(*it); |
| 2156 | BREAK_IF(!value); | 2187 | BREAK_IF(!value); |
| 2157 | auto chainValue = value->item.as<ChainValue_t>(); | 2188 | auto chainValue = value->item.as<ChainValue_t>(); |
| 2158 | BREAK_IF(!chainValue); | 2189 | BREAK_IF(!chainValue); |
| 2159 | str_list temp; | ||
| 2160 | if (auto dot = ast_cast<DotChainItem_t>(chainValue->items.back())) { | 2190 | if (auto dot = ast_cast<DotChainItem_t>(chainValue->items.back())) { |
| 2161 | BREAK_IF(!dot->name.is<Metatable_t>()); | 2191 | BREAK_IF(!dot->name.is<Metatable_t>()); |
| 2192 | str_list temp; | ||
| 2193 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | ||
| 2194 | if (!beforeAssignment->expList->exprs.empty()) { | ||
| 2195 | transformAssignment(beforeAssignment, temp); | ||
| 2196 | } | ||
| 2162 | str_list args; | 2197 | str_list args; |
| 2163 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); | 2198 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); |
| 2164 | tmpChain->items.dup(chainValue->items); | 2199 | tmpChain->items.dup(chainValue->items); |
| @@ -2178,7 +2213,17 @@ private: | |||
| 2178 | transformAssignItem(*vit, args); | 2213 | transformAssignItem(*vit, args); |
| 2179 | _buf << indent() << globalVar("setmetatable"sv, x, AccessType::Read) << '(' << join(args, ", "sv) << ')' << nll(x); | 2214 | _buf << indent() << globalVar("setmetatable"sv, x, AccessType::Read) << '(' << join(args, ", "sv) << ')' << nll(x); |
| 2180 | temp.push_back(clearBuf()); | 2215 | temp.push_back(clearBuf()); |
| 2216 | if (!afterAssignment->expList->exprs.empty()) { | ||
| 2217 | transformAssignment(afterAssignment, temp); | ||
| 2218 | } | ||
| 2219 | out.push_back(join(temp)); | ||
| 2220 | return; | ||
| 2181 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { | 2221 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { |
| 2222 | str_list temp; | ||
| 2223 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | ||
| 2224 | if (!beforeAssignment->expList->exprs.empty()) { | ||
| 2225 | transformAssignment(beforeAssignment, temp); | ||
| 2226 | } | ||
| 2182 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); | 2227 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); |
| 2183 | tmpChain->items.dup(chainValue->items); | 2228 | tmpChain->items.dup(chainValue->items); |
| 2184 | tmpChain->items.pop_back(); | 2229 | tmpChain->items.pop_back(); |
| @@ -2220,32 +2265,14 @@ private: | |||
| 2220 | popScope(); | 2265 | popScope(); |
| 2221 | temp.push_back(indent() + "end"s + nlr(x)); | 2266 | temp.push_back(indent() + "end"s + nlr(x)); |
| 2222 | } | 2267 | } |
| 2223 | } else | 2268 | if (!afterAssignment->expList->exprs.empty()) { |
| 2224 | break; | 2269 | transformAssignment(afterAssignment, temp); |
| 2225 | auto newExpList = x->new_ptr<ExpList_t>(); | 2270 | } |
| 2226 | auto newAssign = x->new_ptr<Assign_t>(); | ||
| 2227 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | ||
| 2228 | newAssignment->expList.set(newExpList); | ||
| 2229 | newAssignment->action.set(newAssign); | ||
| 2230 | for (auto exp : exprs) { | ||
| 2231 | if (exp != *it) newExpList->exprs.push_back(exp); | ||
| 2232 | } | ||
| 2233 | for (auto value : values) { | ||
| 2234 | if (value != *vit) newAssign->values.push_back(value); | ||
| 2235 | } | ||
| 2236 | if (newExpList->exprs.empty() && newAssign->values.empty()) { | ||
| 2237 | out.push_back(join(temp)); | 2271 | out.push_back(join(temp)); |
| 2238 | return; | 2272 | return; |
| 2273 | } else { | ||
| 2274 | break; | ||
| 2239 | } | 2275 | } |
| 2240 | if (newExpList->exprs.size() < newAssign->values.size()) { | ||
| 2241 | auto exp = toAst<Exp_t>("_"sv, x); | ||
| 2242 | while (newExpList->exprs.size() < newAssign->values.size()) { | ||
| 2243 | newExpList->exprs.push_back(exp); | ||
| 2244 | } | ||
| 2245 | } | ||
| 2246 | transformAssignment(newAssignment, temp); | ||
| 2247 | out.push_back(join(temp)); | ||
| 2248 | return; | ||
| 2249 | BLOCK_END | 2276 | BLOCK_END |
| 2250 | if (vit != values.end()) ++vit; | 2277 | if (vit != values.end()) ++vit; |
| 2251 | } | 2278 | } |
| @@ -2432,7 +2459,7 @@ private: | |||
| 2432 | if (!assignment.extraAssignment) { | 2459 | if (!assignment.extraAssignment) { |
| 2433 | auto names = transformAssignDefs(assignment.ptr->expList, DefOp::Get); | 2460 | auto names = transformAssignDefs(assignment.ptr->expList, DefOp::Get); |
| 2434 | for (const auto& name : names) { | 2461 | for (const auto& name : names) { |
| 2435 | if (addToScope(name.first)) { | 2462 | if (!isDefined(name.first)) { |
| 2436 | defs.push_back(name.first); | 2463 | defs.push_back(name.first); |
| 2437 | } | 2464 | } |
| 2438 | } | 2465 | } |
