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 | } |