diff options
| author | Li Jin <dragon-fly@qq.com> | 2024-03-19 02:22:56 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2024-03-19 02:22:56 +0800 |
| commit | afc86619d710a578dc3f2bfc2ee1d62913f9abe8 (patch) | |
| tree | 726ffe4d33bbaf8be411f73add51a1ffe734bc6f | |
| parent | 4f399a181dc773bcc1a86737522915c2c776fb2b (diff) | |
| download | yuescript-afc86619d710a578dc3f2bfc2ee1d62913f9abe8.tar.gz yuescript-afc86619d710a578dc3f2bfc2ee1d62913f9abe8.tar.bz2 yuescript-afc86619d710a578dc3f2bfc2ee1d62913f9abe8.zip | |
try fixing issue #162.
| -rw-r--r-- | spec/inputs/attrib.yue | 2 | ||||
| -rw-r--r-- | spec/inputs/unicode/multiline_chain.yue | 6 | ||||
| -rw-r--r-- | spec/outputs/5.1/attrib.lua | 183 | ||||
| -rw-r--r-- | spec/outputs/assign.lua | 9 | ||||
| -rw-r--r-- | spec/outputs/attrib.lua | 1 | ||||
| -rw-r--r-- | spec/outputs/unicode/assign.lua | 9 | ||||
| -rw-r--r-- | spec/outputs/unicode/macro.lua | 26 | ||||
| -rw-r--r-- | spec/outputs/unicode/multiline_chain.lua | 35 | ||||
| -rw-r--r-- | spec/outputs/unicode/syntax.lua | 13 | ||||
| -rw-r--r-- | spec/outputs/unicode/vararg.lua | 488 | ||||
| -rw-r--r-- | spec/outputs/vararg.lua | 488 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.cpp | 266 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.h | 5 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 604 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.h | 12 |
15 files changed, 1328 insertions, 819 deletions
diff --git a/spec/inputs/attrib.yue b/spec/inputs/attrib.yue index 36aca99..f66f0db 100644 --- a/spec/inputs/attrib.yue +++ b/spec/inputs/attrib.yue | |||
| @@ -41,6 +41,8 @@ do | |||
| 41 | 41 | ||
| 42 | close _ = <close>: -> print "first" | 42 | close _ = <close>: -> print "first" |
| 43 | 43 | ||
| 44 | print "third" | ||
| 45 | |||
| 44 | _defers = setmetatable {}, __close: => | 46 | _defers = setmetatable {}, __close: => |
| 45 | @[#@]! | 47 | @[#@]! |
| 46 | @[#@] = nil | 48 | @[#@] = nil |
diff --git a/spec/inputs/unicode/multiline_chain.yue b/spec/inputs/unicode/multiline_chain.yue index 403f93b..6e8551c 100644 --- a/spec/inputs/unicode/multiline_chain.yue +++ b/spec/inputs/unicode/multiline_chain.yue | |||
| @@ -21,8 +21,10 @@ | |||
| 21 | 21 | ||
| 22 | 表bb = | 22 | 表bb = |
| 23 | 键1: 变量a | 23 | 键1: 变量a |
| 24 | \变量b 123 | 24 | \变量b 123, |
| 25 | .变量c! | 25 | :字段A |
| 26 | .变量c 1, 2, 3 | ||
| 27 | :字段B | ||
| 26 | 键2: | 28 | 键2: |
| 27 | 键w1: 变量a! | 29 | 键w1: 变量a! |
| 28 | .变量b | 30 | .变量b |
diff --git a/spec/outputs/5.1/attrib.lua b/spec/outputs/5.1/attrib.lua index 70e7e24..e28dca4 100644 --- a/spec/outputs/5.1/attrib.lua +++ b/spec/outputs/5.1/attrib.lua | |||
| @@ -50,6 +50,22 @@ do | |||
| 50 | a, b = _obj_0[1], _obj_0[2] | 50 | a, b = _obj_0[1], _obj_0[2] |
| 51 | end | 51 | end |
| 52 | end | 52 | end |
| 53 | local _anon_func_0 = function(f, error, _close_1, _arg_0, ...) | ||
| 54 | do | ||
| 55 | local _ok_0 = _arg_0 | ||
| 56 | _close_1(f) | ||
| 57 | if _ok_0 then | ||
| 58 | return ... | ||
| 59 | else | ||
| 60 | return error(...) | ||
| 61 | end | ||
| 62 | end | ||
| 63 | end | ||
| 64 | local _anon_func_1 = function(io) | ||
| 65 | local _with_0 = io.open("file.txt") | ||
| 66 | _with_0:write("Hello") | ||
| 67 | return _with_0 | ||
| 68 | end | ||
| 53 | do | 69 | do |
| 54 | local v = (function() | 70 | local v = (function() |
| 55 | if flag then | 71 | if flag then |
| @@ -70,23 +86,43 @@ do | |||
| 70 | return error(...) | 86 | return error(...) |
| 71 | end | 87 | end |
| 72 | end)(pcall(function(...) | 88 | end)(pcall(function(...) |
| 73 | local f = (function() | 89 | local f = _anon_func_1(io) |
| 74 | local _with_0 = io.open("file.txt") | ||
| 75 | _with_0:write("Hello") | ||
| 76 | return _with_0 | ||
| 77 | end)() | ||
| 78 | local _close_1 = assert(getmetatable(f).__close) | 90 | local _close_1 = assert(getmetatable(f).__close) |
| 79 | return (function(_arg_0, ...) | 91 | return _anon_func_0(f, error, _close_1, pcall(function(...) end, ...)) |
| 80 | local _ok_0 = _arg_0 | ||
| 81 | _close_1(f) | ||
| 82 | if _ok_0 then | ||
| 83 | return ... | ||
| 84 | else | ||
| 85 | return error(...) | ||
| 86 | end | ||
| 87 | end)(pcall(function(...) end, ...)) | ||
| 88 | end, ...)) | 92 | end, ...)) |
| 89 | end | 93 | end |
| 94 | local _anon_func_2 = function(d, error, _close_1, _arg_0, ...) | ||
| 95 | do | ||
| 96 | local _ok_0 = _arg_0 | ||
| 97 | _close_1(d) | ||
| 98 | if _ok_0 then | ||
| 99 | return ... | ||
| 100 | else | ||
| 101 | return error(...) | ||
| 102 | end | ||
| 103 | end | ||
| 104 | end | ||
| 105 | local _anon_func_3 = function(x) | ||
| 106 | if true then | ||
| 107 | if "abc" == x then | ||
| 108 | return 998 | ||
| 109 | end | ||
| 110 | end | ||
| 111 | end | ||
| 112 | local _anon_func_5 = function(a, b) | ||
| 113 | if a ~= nil then | ||
| 114 | return a | ||
| 115 | else | ||
| 116 | return b | ||
| 117 | end | ||
| 118 | end | ||
| 119 | local _anon_func_4 = function(a, b) | ||
| 120 | if _anon_func_5(a, b) then | ||
| 121 | return { | ||
| 122 | value = value | ||
| 123 | } | ||
| 124 | end | ||
| 125 | end | ||
| 90 | do | 126 | do |
| 91 | local a = (function() | 127 | local a = (function() |
| 92 | if true then | 128 | if true then |
| @@ -110,39 +146,34 @@ do | |||
| 110 | return error(...) | 146 | return error(...) |
| 111 | end | 147 | end |
| 112 | end)(pcall(function(...) | 148 | end)(pcall(function(...) |
| 113 | local c = (function() | 149 | local c = _anon_func_3(x) |
| 114 | if true then | 150 | local d = _anon_func_4(a, b) |
| 115 | local _exp_0 = x | ||
| 116 | if "abc" == _exp_0 then | ||
| 117 | return 998 | ||
| 118 | end | ||
| 119 | end | ||
| 120 | end)() | ||
| 121 | local d = (function() | ||
| 122 | if (function() | ||
| 123 | if a ~= nil then | ||
| 124 | return a | ||
| 125 | else | ||
| 126 | return b | ||
| 127 | end | ||
| 128 | end)() then | ||
| 129 | return { | ||
| 130 | value = value | ||
| 131 | } | ||
| 132 | end | ||
| 133 | end)() | ||
| 134 | local _close_1 = assert(getmetatable(d).__close) | 151 | local _close_1 = assert(getmetatable(d).__close) |
| 135 | return (function(_arg_0, ...) | 152 | return _anon_func_2(d, error, _close_1, pcall(function(...) end, ...)) |
| 136 | local _ok_0 = _arg_0 | ||
| 137 | _close_1(d) | ||
| 138 | if _ok_0 then | ||
| 139 | return ... | ||
| 140 | else | ||
| 141 | return error(...) | ||
| 142 | end | ||
| 143 | end)(pcall(function(...) end, ...)) | ||
| 144 | end, ...)) | 153 | end, ...)) |
| 145 | end | 154 | end |
| 155 | local _anon_func_6 = function(_, error, _close_1, _arg_0, ...) | ||
| 156 | do | ||
| 157 | local _ok_0 = _arg_0 | ||
| 158 | _close_1(_) | ||
| 159 | if _ok_0 then | ||
| 160 | return ... | ||
| 161 | else | ||
| 162 | return error(...) | ||
| 163 | end | ||
| 164 | end | ||
| 165 | end | ||
| 166 | local _anon_func_7 = function(_, _close_2, error, _arg_0, ...) | ||
| 167 | do | ||
| 168 | local _ok_0 = _arg_0 | ||
| 169 | _close_2(_) | ||
| 170 | if _ok_0 then | ||
| 171 | return ... | ||
| 172 | else | ||
| 173 | return error(...) | ||
| 174 | end | ||
| 175 | end | ||
| 176 | end | ||
| 146 | do | 177 | do |
| 147 | local _ = (function() | 178 | local _ = (function() |
| 148 | local _with_0 = io.open("file.txt") | 179 | local _with_0 = io.open("file.txt") |
| @@ -165,30 +196,16 @@ do | |||
| 165 | end | 196 | end |
| 166 | }) | 197 | }) |
| 167 | local _close_1 = assert(getmetatable(_).__close) | 198 | local _close_1 = assert(getmetatable(_).__close) |
| 168 | return (function(_arg_0, ...) | 199 | return _anon_func_6(_, error, _close_1, pcall(function(...) |
| 169 | local _ok_0 = _arg_0 | ||
| 170 | _close_1(_) | ||
| 171 | if _ok_0 then | ||
| 172 | return ... | ||
| 173 | else | ||
| 174 | return error(...) | ||
| 175 | end | ||
| 176 | end)(pcall(function(...) | ||
| 177 | local _ = setmetatable({ }, { | 200 | local _ = setmetatable({ }, { |
| 178 | __close = function() | 201 | __close = function() |
| 179 | return print("first") | 202 | return print("first") |
| 180 | end | 203 | end |
| 181 | }) | 204 | }) |
| 182 | local _close_2 = assert(getmetatable(_).__close) | 205 | local _close_2 = assert(getmetatable(_).__close) |
| 183 | return (function(_arg_0, ...) | 206 | return _anon_func_7(_, _close_2, error, pcall(function(...) |
| 184 | local _ok_0 = _arg_0 | 207 | return print("third") |
| 185 | _close_2(_) | 208 | end, ...)) |
| 186 | if _ok_0 then | ||
| 187 | return ... | ||
| 188 | else | ||
| 189 | return error(...) | ||
| 190 | end | ||
| 191 | end)(pcall(function(...) end, ...)) | ||
| 192 | end, ...)) | 209 | end, ...)) |
| 193 | end, ...)) | 210 | end, ...)) |
| 194 | end | 211 | end |
| @@ -203,6 +220,28 @@ def = function(item) | |||
| 203 | _defers[#_defers + 1] = item | 220 | _defers[#_defers + 1] = item |
| 204 | return _defers | 221 | return _defers |
| 205 | end | 222 | end |
| 223 | local _anon_func_8 = function(_, error, _close_1, _arg_0, ...) | ||
| 224 | do | ||
| 225 | local _ok_0 = _arg_0 | ||
| 226 | _close_1(_) | ||
| 227 | if _ok_0 then | ||
| 228 | return ... | ||
| 229 | else | ||
| 230 | return error(...) | ||
| 231 | end | ||
| 232 | end | ||
| 233 | end | ||
| 234 | local _anon_func_9 = function(_, _close_2, error, _arg_0, ...) | ||
| 235 | do | ||
| 236 | local _ok_0 = _arg_0 | ||
| 237 | _close_2(_) | ||
| 238 | if _ok_0 then | ||
| 239 | return ... | ||
| 240 | else | ||
| 241 | return error(...) | ||
| 242 | end | ||
| 243 | end | ||
| 244 | end | ||
| 206 | do | 245 | do |
| 207 | local _ = def(function() | 246 | local _ = def(function() |
| 208 | return print(3) | 247 | return print(3) |
| @@ -221,28 +260,12 @@ do | |||
| 221 | return print(2) | 260 | return print(2) |
| 222 | end) | 261 | end) |
| 223 | local _close_1 = assert(getmetatable(_).__close) | 262 | local _close_1 = assert(getmetatable(_).__close) |
| 224 | return (function(_arg_0, ...) | 263 | return _anon_func_8(_, error, _close_1, pcall(function(...) |
| 225 | local _ok_0 = _arg_0 | ||
| 226 | _close_1(_) | ||
| 227 | if _ok_0 then | ||
| 228 | return ... | ||
| 229 | else | ||
| 230 | return error(...) | ||
| 231 | end | ||
| 232 | end)(pcall(function(...) | ||
| 233 | local _ = def(function() | 264 | local _ = def(function() |
| 234 | return print(1) | 265 | return print(1) |
| 235 | end) | 266 | end) |
| 236 | local _close_2 = assert(getmetatable(_).__close) | 267 | local _close_2 = assert(getmetatable(_).__close) |
| 237 | return (function(_arg_0, ...) | 268 | return _anon_func_9(_, _close_2, error, pcall(function(...) end, ...)) |
| 238 | local _ok_0 = _arg_0 | ||
| 239 | _close_2(_) | ||
| 240 | if _ok_0 then | ||
| 241 | return ... | ||
| 242 | else | ||
| 243 | return error(...) | ||
| 244 | end | ||
| 245 | end)(pcall(function(...) end, ...)) | ||
| 246 | end, ...)) | 269 | end, ...)) |
| 247 | end, ...)) | 270 | end, ...)) |
| 248 | end | 271 | end |
diff --git a/spec/outputs/assign.lua b/spec/outputs/assign.lua index 228e859..8bf7b35 100644 --- a/spec/outputs/assign.lua +++ b/spec/outputs/assign.lua | |||
| @@ -42,11 +42,14 @@ do | |||
| 42 | end | 42 | end |
| 43 | end | 43 | end |
| 44 | end | 44 | end |
| 45 | return _(function() | 45 | local _anon_func_0 = function(print) |
| 46 | setmetatable(a, (function() | 46 | do |
| 47 | print(123) | 47 | print(123) |
| 48 | return { } | 48 | return { } |
| 49 | end)()) | 49 | end |
| 50 | end | ||
| 51 | return _(function() | ||
| 52 | setmetatable(a, _anon_func_0(print)) | ||
| 50 | do | 53 | do |
| 51 | local a, b | 54 | local a, b |
| 52 | if "a" == c then | 55 | if "a" == c then |
diff --git a/spec/outputs/attrib.lua b/spec/outputs/attrib.lua index 181555f..07fc165 100644 --- a/spec/outputs/attrib.lua +++ b/spec/outputs/attrib.lua | |||
| @@ -106,6 +106,7 @@ do | |||
| 106 | return print("first") | 106 | return print("first") |
| 107 | end | 107 | end |
| 108 | }) | 108 | }) |
| 109 | print("third") | ||
| 109 | end | 110 | end |
| 110 | local _defers = setmetatable({ }, { | 111 | local _defers = setmetatable({ }, { |
| 111 | __close = function(self) | 112 | __close = function(self) |
diff --git a/spec/outputs/unicode/assign.lua b/spec/outputs/unicode/assign.lua index b530093..290b248 100644 --- a/spec/outputs/unicode/assign.lua +++ b/spec/outputs/unicode/assign.lua | |||
| @@ -42,11 +42,14 @@ do | |||
| 42 | end | 42 | end |
| 43 | end | 43 | end |
| 44 | end | 44 | end |
| 45 | return __u65e0_u6548_u53d8_u91cf(function() | 45 | local _anon_func_0 = function(_u6253_u5370) |
| 46 | setmetatable(a_u53d8_u91cf, (function() | 46 | do |
| 47 | _u6253_u5370(123) | 47 | _u6253_u5370(123) |
| 48 | return { } | 48 | return { } |
| 49 | end)()) | 49 | end |
| 50 | end | ||
| 51 | return __u65e0_u6548_u53d8_u91cf(function() | ||
| 52 | setmetatable(a_u53d8_u91cf, _anon_func_0(_u6253_u5370)) | ||
| 50 | do | 53 | do |
| 51 | local _u5143_u7d20a, _u5143_u7d20b | 54 | local _u5143_u7d20a, _u5143_u7d20b |
| 52 | do | 55 | do |
diff --git a/spec/outputs/unicode/macro.lua b/spec/outputs/unicode/macro.lua index 2ae5dce..88f6de7 100644 --- a/spec/outputs/unicode/macro.lua +++ b/spec/outputs/unicode/macro.lua | |||
| @@ -211,11 +211,11 @@ local _call_1 = (_({ | |||
| 211 | -2, | 211 | -2, |
| 212 | 3 | 212 | 3 |
| 213 | })) | 213 | })) |
| 214 | _call_1 = _call_1["链"](_call_1, _call_1, _call_1, _call_1, _call_1, _call_1, _call_1, _call_1) | 214 | _call_1 = _call_1["链"](_call_1) |
| 215 | _call_1 = _call_1["映射"](_call_1, _call_1, _call_1, _call_1, function(self) | 215 | _call_1 = _call_1["映射"](_call_1, function(self) |
| 216 | return self * 2 | 216 | return self * 2 |
| 217 | end) | 217 | end) |
| 218 | _call_1 = _call_1["过滤"](_call_1, _call_1, function(self) | 218 | _call_1 = _call_1["过滤"](_call_1, function(self) |
| 219 | return self > 3 | 219 | return self > 3 |
| 220 | end) | 220 | end) |
| 221 | local _u7ed3_u679ca = _call_1["取值"](_call_1) | 221 | local _u7ed3_u679ca = _call_1["取值"](_call_1) |
| @@ -227,25 +227,25 @@ local _call_2 = (_({ | |||
| 227 | -2, | 227 | -2, |
| 228 | 3 | 228 | 3 |
| 229 | })) | 229 | })) |
| 230 | _call_2 = _call_2["链"](_call_2, _call_2, _call_2, _call_2, _call_2, _call_2, _call_2, _call_2) | 230 | _call_2 = _call_2["链"](_call_2) |
| 231 | _call_2 = _call_2["映射"](_call_2, _call_2, _call_2, _call_2, function(self) | 231 | _call_2 = _call_2["映射"](_call_2, function(self) |
| 232 | return self * 2 | 232 | return self * 2 |
| 233 | end) | 233 | end) |
| 234 | _call_2 = _call_2["过滤"](_call_2, _call_2, function(self) | 234 | _call_2 = _call_2["过滤"](_call_2, function(self) |
| 235 | return self > 3 | 235 | return self > 3 |
| 236 | end) | 236 | end) |
| 237 | _call_2["每一个"](_call_2, function(self) | 237 | _call_2["每一个"](_call_2, function(self) |
| 238 | return _u6253_u5370(self) | 238 | return _u6253_u5370(self) |
| 239 | end) | 239 | end) |
| 240 | local _call_3 = _u539f_u70b9["变换"]["根节点"]["游戏对象"] | 240 | local _call_3 = _u539f_u70b9["变换"]["根节点"]["游戏对象"] |
| 241 | _call_3 = _call_3["父节点"](_call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3) | 241 | _call_3 = _call_3["父节点"](_call_3) |
| 242 | _call_3 = _call_3["后代"](_call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3) | 242 | _call_3 = _call_3["后代"](_call_3) |
| 243 | _call_3 = _call_3["选择启用"](_call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3) | 243 | _call_3 = _call_3["选择启用"](_call_3) |
| 244 | _call_3 = _call_3["选择可见"](_call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3, _call_3) | 244 | _call_3 = _call_3["选择可见"](_call_3) |
| 245 | _call_3 = _call_3["标签等于"](_call_3, _call_3, _call_3, _call_3, "fx") | 245 | _call_3 = _call_3["标签等于"](_call_3, "fx") |
| 246 | _call_3 = _call_3["其中"](_call_3, _call_3, function(x) | 246 | _call_3 = _call_3["其中"](_call_3, function(x) |
| 247 | local _call_4 = x["名称"] | 247 | local _call_4 = x["名称"] |
| 248 | return _call_4["结尾为"](_call_4, _call_4, "(克隆)") | 248 | return _call_4["结尾为"](_call_4, "(克隆)") |
| 249 | end) | 249 | end) |
| 250 | _u7ed3_u679c = _call_3["摧毁"](_call_3) | 250 | _u7ed3_u679c = _call_3["摧毁"](_call_3) |
| 251 | do | 251 | do |
diff --git a/spec/outputs/unicode/multiline_chain.lua b/spec/outputs/unicode/multiline_chain.lua index 90fdf0b..f45e71f 100644 --- a/spec/outputs/unicode/multiline_chain.lua +++ b/spec/outputs/unicode/multiline_chain.lua | |||
| @@ -24,7 +24,11 @@ end)(), { | |||
| 24 | local _u8868bb = { | 24 | local _u8868bb = { |
| 25 | ["键1"] = (function() | 25 | ["键1"] = (function() |
| 26 | local _call_1 = _u53d8_u91cfa | 26 | local _call_1 = _u53d8_u91cfa |
| 27 | return _call_1["变量b"](_call_1, 123)["变量c"]() | 27 | return (_call_1["变量b"](_call_1, 123, { |
| 28 | ["字段A"] = _u5b57_u6bb5A | ||
| 29 | }))["变量c"](1, 2, 3, { | ||
| 30 | ["字段B"] = _u5b57_u6bb5B | ||
| 31 | }) | ||
| 28 | end)(), | 32 | end)(), |
| 29 | ["键2"] = { | 33 | ["键2"] = { |
| 30 | ["键w1"] = (function() | 34 | ["键w1"] = (function() |
| @@ -54,37 +58,40 @@ _u51fd_u6570 = function() | |||
| 54 | end | 58 | end |
| 55 | return _accum_0 | 59 | return _accum_0 |
| 56 | end | 60 | end |
| 61 | local _anon_func_0 = function(_u53d8_u91cfa) | ||
| 62 | do | ||
| 63 | local _call_1 = _u53d8_u91cfa | ||
| 64 | return (_call_1["变量b"](_call_1, 123))["变量c"]("abc") | ||
| 65 | end | ||
| 66 | end | ||
| 57 | local _u51fd_u65701 | 67 | local _u51fd_u65701 |
| 58 | _u51fd_u65701 = function() | 68 | _u51fd_u65701 = function() |
| 59 | return _u53d8_u91cfx, (function() | 69 | return _u53d8_u91cfx, _anon_func_0(_u53d8_u91cfa) |
| 60 | local _call_1 = _u53d8_u91cfa | ||
| 61 | return _call_1["变量b"](_call_1, 123)["变量c"]("abc") | ||
| 62 | end)() | ||
| 63 | end | 70 | end |
| 64 | local _call_1 = _u539f_u59cb["转换"].root.gameObject | 71 | local _call_1 = _u539f_u59cb["转换"].root.gameObject |
| 65 | local _call_2 = _call_1["父节点"](_call_1) | 72 | local _call_2 = _call_1["父节点"](_call_1) |
| 66 | local _call_3 = _call_2["后代节点"](_call_2) | 73 | local _call_3 = _call_2["后代节点"](_call_2) |
| 67 | local _call_4 = _call_3["选择启用"](_call_3) | 74 | local _call_4 = _call_3["选择启用"](_call_3) |
| 68 | local _call_5 = _call_4["选择可见"](_call_4) | 75 | local _call_5 = _call_4["选择可见"](_call_4) |
| 69 | local _call_6 = _call_5["标签相等"](_call_5, "fx") | 76 | local _call_6 = (_call_5["标签相等"](_call_5, "fx")) |
| 70 | local _call_7 = _call_6["筛选"](_call_6, function(_u5143_u7d20) | 77 | local _call_7 = (_call_6["筛选"](_call_6, function(_u5143_u7d20) |
| 71 | if _u5143_u7d20["是否目标"](_u5143_u7d20, _u5143_u7d20) then | 78 | if _u5143_u7d20["是否目标"](_u5143_u7d20) then |
| 72 | return false | 79 | return false |
| 73 | end | 80 | end |
| 74 | local _call_7 = _u5143_u7d20["名称"] | 81 | local _call_7 = _u5143_u7d20["名称"] |
| 75 | return _call_7["结束于"](_call_7, _call_7, "(Clone)") | 82 | return _call_7["结束于"](_call_7, "(Clone)") |
| 76 | end) | 83 | end)) |
| 77 | local _u7ed3_u679c = _call_7["销毁"](_call_7) | 84 | local _u7ed3_u679c = _call_7["销毁"](_call_7) |
| 78 | local _call_8 = _u539f_u70b9["变换"]["根节点"]["游戏对象"] | 85 | local _call_8 = _u539f_u70b9["变换"]["根节点"]["游戏对象"] |
| 79 | local _call_9 = _call_8["父节点"](_call_8) | 86 | local _call_9 = _call_8["父节点"](_call_8) |
| 80 | local _call_10 = _call_9["后代节点"](_call_9) | 87 | local _call_10 = _call_9["后代节点"](_call_9) |
| 81 | local _call_11 = _call_10["选择启用"](_call_10) | 88 | local _call_11 = _call_10["选择启用"](_call_10) |
| 82 | local _call_12 = _call_11["选择可见"](_call_11) | 89 | local _call_12 = _call_11["选择可见"](_call_11) |
| 83 | local _call_13 = _call_12["标签相等"](_call_12, "fx") | 90 | local _call_13 = (_call_12["标签相等"](_call_12, "fx")) |
| 84 | local _call_14 = _call_13["筛选"](_call_13, function(_u5143_u7d20) | 91 | local _call_14 = (_call_13["筛选"](_call_13, function(_u5143_u7d20) |
| 85 | local _call_14 = _u5143_u7d20["名称"] | 92 | local _call_14 = _u5143_u7d20["名称"] |
| 86 | return _call_14["结束于"](_call_14, _call_14, "(Clone)") | 93 | return _call_14["结束于"](_call_14, "(Clone)") |
| 87 | end) | 94 | end)) |
| 88 | _call_14["销毁"](_call_14) | 95 | _call_14["销毁"](_call_14) |
| 89 | do | 96 | do |
| 90 | local _with_0 = _u9879_u76ee | 97 | local _with_0 = _u9879_u76ee |
diff --git a/spec/outputs/unicode/syntax.lua b/spec/outputs/unicode/syntax.lua index 664fa46..f086db6 100644 --- a/spec/outputs/unicode/syntax.lua +++ b/spec/outputs/unicode/syntax.lua | |||
| @@ -282,13 +282,16 @@ _ = 5 + _u4ec0_u4e48(_u65e0_u804a) | |||
| 282 | _u4ec0_u4e48(_u65e0_u804a + 5) | 282 | _u4ec0_u4e48(_u65e0_u804a + 5) |
| 283 | _ = 5 - _u4ec0_u4e48(_u65e0_u804a) | 283 | _ = 5 - _u4ec0_u4e48(_u65e0_u804a) |
| 284 | _u4ec0_u4e48(_u65e0_u804a - 5) | 284 | _u4ec0_u4e48(_u65e0_u804a - 5) |
| 285 | _u53d8_u91cfx = _u4f60_u597d - _u4e16_u754c - _u67d0_u7269; | 285 | _u53d8_u91cfx = _u4f60_u597d - _u4e16_u754c - _u67d0_u7269 |
| 286 | local _anon_func_0 = function(_u4ec0_u4e48) | ||
| 287 | do | ||
| 288 | local _call_8 = _u4ec0_u4e48 | ||
| 289 | return _call_8["酷"](_call_8, 100) | ||
| 290 | end | ||
| 291 | end | ||
| 286 | (function(_u67d0_u7269) | 292 | (function(_u67d0_u7269) |
| 287 | if _u67d0_u7269 == nil then | 293 | if _u67d0_u7269 == nil then |
| 288 | _u67d0_u7269 = _u4e0e((function() | 294 | _u67d0_u7269 = _u4e0e(_anon_func_0(_u4ec0_u4e48)) |
| 289 | local _call_8 = _u4ec0_u4e48 | ||
| 290 | return _call_8["酷"](_call_8, 100) | ||
| 291 | end)()) | ||
| 292 | end | 295 | end |
| 293 | return _u6253_u5370(_u67d0_u7269) | 296 | return _u6253_u5370(_u67d0_u7269) |
| 294 | end)() | 297 | end)() |
diff --git a/spec/outputs/unicode/vararg.lua b/spec/outputs/unicode/vararg.lua index 41d1bfd..39fbf0c 100644 --- a/spec/outputs/unicode/vararg.lua +++ b/spec/outputs/unicode/vararg.lua | |||
| @@ -1,211 +1,264 @@ | |||
| 1 | local _u8fde_u63a5 | 1 | local _anon_func_0 = function(_u53d8_u91cfa) |
| 2 | _u8fde_u63a5 = function(...) | 2 | _u53d8_u91cfa["函数"](_u53d8_u91cfa) |
| 3 | _u5e26_u6709((function() | 3 | return _u53d8_u91cfa |
| 4 | local _with_0 = _u53d8_u91cfa | 4 | end |
| 5 | _with_0["函数"](_with_0) | 5 | local _anon_func_1 = function(_u53d8_u91cfa, ...) |
| 6 | return _with_0 | 6 | _u53d8_u91cfa["函数"](_u53d8_u91cfa, ...) |
| 7 | end)()) | 7 | return _u53d8_u91cfa |
| 8 | _u5e26_u6709((function(...) | 8 | end |
| 9 | local _with_0 = _u53d8_u91cfa | 9 | local _anon_func_2 = function(_u9879_u76ee) |
| 10 | _with_0["函数"](_with_0, ...) | 10 | local _accum_0 = { } |
| 11 | return _with_0 | 11 | local _len_0 = 1 |
| 12 | end)(...)) | 12 | for i = 1, 10 do |
| 13 | _u5217_u8868_u751f_u6210((function() | 13 | _accum_0[_len_0] = _u9879_u76ee[i] |
| 14 | local _accum_0 = { } | 14 | _len_0 = _len_0 + 1 |
| 15 | local _len_0 = 1 | 15 | end |
| 16 | for i = 1, 10 do | 16 | return _accum_0 |
| 17 | _accum_0[_len_0] = _u9879_u76ee[i] | 17 | end |
| 18 | _len_0 = _len_0 + 1 | 18 | local _anon_func_3 = function(_u9879_u76ee, ...) |
| 19 | end | 19 | local _accum_0 = { } |
| 20 | return _accum_0 | 20 | local _len_0 = 1 |
| 21 | end)()) | 21 | for i = 1, 10 do |
| 22 | _u5217_u8868_u751f_u6210((function(...) | 22 | _accum_0[_len_0] = _u9879_u76ee[i](...) |
| 23 | local _accum_0 = { } | 23 | _len_0 = _len_0 + 1 |
| 24 | local _len_0 = 1 | 24 | end |
| 25 | for i = 1, 10 do | 25 | return _accum_0 |
| 26 | _accum_0[_len_0] = _u9879_u76ee[i](...) | 26 | end |
| 27 | _len_0 = _len_0 + 1 | 27 | local _anon_func_4 = function(_u9879_u76ee) |
| 28 | end | 28 | local _accum_0 = { } |
| 29 | return _accum_0 | 29 | local _len_0 = 1 |
| 30 | end)(...)) | 30 | for _index_0 = 1, #_u9879_u76ee do |
| 31 | _u5217_u8868_u751f_u6210((function() | 31 | local _u7269_u54c1 = _u9879_u76ee[_index_0] |
| 32 | local _accum_0 = { } | 32 | _accum_0[_len_0] = _u7269_u54c1 |
| 33 | local _len_0 = 1 | 33 | _len_0 = _len_0 + 1 |
| 34 | local _list_0 = _u9879_u76ee | 34 | end |
| 35 | for _index_0 = 1, #_list_0 do | 35 | return _accum_0 |
| 36 | local _u7269_u54c1 = _list_0[_index_0] | 36 | end |
| 37 | _accum_0[_len_0] = _u7269_u54c1 | 37 | local _anon_func_5 = function(_u9879_u76ee, ...) |
| 38 | _len_0 = _len_0 + 1 | 38 | local _accum_0 = { } |
| 39 | end | 39 | local _len_0 = 1 |
| 40 | return _accum_0 | 40 | for _index_0 = 1, #_u9879_u76ee do |
| 41 | end)()) | 41 | local _u7269_u54c1 = _u9879_u76ee[_index_0] |
| 42 | _u5217_u8868_u751f_u6210((function(...) | 42 | _accum_0[_len_0] = _u7269_u54c1(...) |
| 43 | local _accum_0 = { } | 43 | _len_0 = _len_0 + 1 |
| 44 | local _len_0 = 1 | 44 | end |
| 45 | local _list_0 = _u9879_u76ee | 45 | return _accum_0 |
| 46 | for _index_0 = 1, #_list_0 do | 46 | end |
| 47 | local _u7269_u54c1 = _list_0[_index_0] | 47 | local _anon_func_6 = function(setmetatable, _u51fd_u6570) |
| 48 | _accum_0[_len_0] = _u7269_u54c1(...) | 48 | local _u53d8_u91cfA |
| 49 | _len_0 = _len_0 + 1 | 49 | do |
| 50 | local _class_0 | ||
| 51 | local _base_0 = { } | ||
| 52 | if _base_0.__index == nil then | ||
| 53 | _base_0.__index = _base_0 | ||
| 50 | end | 54 | end |
| 51 | return _accum_0 | 55 | _class_0 = setmetatable({ |
| 52 | end)(...)) | 56 | __init = function() end, |
| 53 | _u7c7b_u751f_u6210((function() | 57 | __base = _base_0, |
| 54 | local _u53d8_u91cfA | 58 | __name = "变量A" |
| 55 | do | 59 | }, { |
| 56 | local _class_0 | 60 | __index = _base_0, |
| 57 | local _base_0 = { } | 61 | __call = function(cls, ...) |
| 58 | if _base_0.__index == nil then | 62 | local _self_0 = setmetatable({ }, _base_0) |
| 59 | _base_0.__index = _base_0 | 63 | cls.__init(_self_0, ...) |
| 64 | return _self_0 | ||
| 60 | end | 65 | end |
| 61 | _class_0 = setmetatable({ | 66 | }) |
| 62 | __init = function() end, | 67 | _base_0.__class = _class_0 |
| 63 | __base = _base_0, | 68 | local self = _class_0; |
| 64 | __name = "变量A" | 69 | _u51fd_u6570() |
| 65 | }, { | 70 | _u53d8_u91cfA = _class_0 |
| 66 | __index = _base_0, | 71 | return _class_0 |
| 67 | __call = function(cls, ...) | 72 | end |
| 68 | local _self_0 = setmetatable({ }, _base_0) | 73 | end |
| 69 | cls.__init(_self_0, ...) | 74 | local _anon_func_7 = function(setmetatable, _u51fd_u6570, ...) |
| 70 | return _self_0 | 75 | local _u53d8_u91cfA |
| 71 | end | 76 | do |
| 72 | }) | 77 | local _class_0 |
| 73 | _base_0.__class = _class_0 | 78 | local _base_0 = { } |
| 74 | local self = _class_0; | 79 | if _base_0.__index == nil then |
| 75 | _u51fd_u6570() | 80 | _base_0.__index = _base_0 |
| 76 | _u53d8_u91cfA = _class_0 | ||
| 77 | return _class_0 | ||
| 78 | end | 81 | end |
| 79 | end)()) | 82 | _class_0 = setmetatable({ |
| 80 | _u7c7b_u751f_u6210((function(...) | 83 | __init = function() end, |
| 81 | local _u53d8_u91cfA | 84 | __base = _base_0, |
| 82 | do | 85 | __name = "变量A" |
| 83 | local _class_0 | 86 | }, { |
| 84 | local _base_0 = { } | 87 | __index = _base_0, |
| 85 | if _base_0.__index == nil then | 88 | __call = function(cls, ...) |
| 86 | _base_0.__index = _base_0 | 89 | local _self_0 = setmetatable({ }, _base_0) |
| 90 | cls.__init(_self_0, ...) | ||
| 91 | return _self_0 | ||
| 87 | end | 92 | end |
| 88 | _class_0 = setmetatable({ | 93 | }) |
| 89 | __init = function() end, | 94 | _base_0.__class = _class_0 |
| 90 | __base = _base_0, | 95 | local self = _class_0; |
| 91 | __name = "变量A" | 96 | _u51fd_u6570(...) |
| 92 | }, { | 97 | _u53d8_u91cfA = _class_0 |
| 93 | __index = _base_0, | 98 | return _class_0 |
| 94 | __call = function(cls, ...) | 99 | end |
| 95 | local _self_0 = setmetatable({ }, _base_0) | 100 | end |
| 96 | cls.__init(_self_0, ...) | 101 | local _anon_func_8 = function(pairs, _u8868) |
| 97 | return _self_0 | 102 | local _tbl_0 = { } |
| 98 | end | 103 | for _u952e, _u503c in pairs(_u8868) do |
| 99 | }) | 104 | _tbl_0[_u952e] = _u503c |
| 100 | _base_0.__class = _class_0 | 105 | end |
| 101 | local self = _class_0; | 106 | return _tbl_0 |
| 102 | _u51fd_u6570(...) | 107 | end |
| 103 | _u53d8_u91cfA = _class_0 | 108 | local _anon_func_9 = function(pairs, _u8868, ...) |
| 104 | return _class_0 | 109 | local _tbl_0 = { } |
| 105 | end | 110 | for _u952e, _u503c in pairs(_u8868) do |
| 106 | end)(...)) | 111 | _tbl_0[_u952e] = _u503c(...) |
| 107 | _u8868_u751f_u6210((function() | 112 | end |
| 108 | local _tbl_0 = { } | 113 | return _tbl_0 |
| 109 | for _u952e, _u503c in pairs(_u8868) do | 114 | end |
| 110 | _tbl_0[_u952e] = _u503c | 115 | local _anon_func_10 = function(_u9879_u76ee) |
| 111 | end | 116 | local _tbl_0 = { } |
| 112 | return _tbl_0 | 117 | for _index_0 = 1, #_u9879_u76ee do |
| 113 | end)()) | 118 | local _u7269_u54c1 = _u9879_u76ee[_index_0] |
| 114 | _u8868_u751f_u6210((function(...) | 119 | _tbl_0[_u7269_u54c1] = true |
| 115 | local _tbl_0 = { } | 120 | end |
| 116 | for _u952e, _u503c in pairs(_u8868) do | 121 | return _tbl_0 |
| 117 | _tbl_0[_u952e] = _u503c(...) | 122 | end |
| 118 | end | 123 | local _anon_func_11 = function(_u9879_u76ee, ...) |
| 119 | return _tbl_0 | 124 | local _tbl_0 = { } |
| 120 | end)(...)) | 125 | for _index_0 = 1, #_u9879_u76ee do |
| 121 | _u8868_u751f_u6210((function() | 126 | local _u7269_u54c1 = _u9879_u76ee[_index_0] |
| 122 | local _tbl_0 = { } | 127 | _tbl_0[_u7269_u54c1(...)] = true |
| 123 | local _list_0 = _u9879_u76ee | 128 | end |
| 124 | for _index_0 = 1, #_list_0 do | 129 | return _tbl_0 |
| 125 | local _u7269_u54c1 = _list_0[_index_0] | 130 | end |
| 126 | _tbl_0[_u7269_u54c1] = true | 131 | local _anon_func_12 = function(_u51fd_u6570) |
| 127 | end | 132 | do |
| 128 | return _tbl_0 | ||
| 129 | end)()) | ||
| 130 | _u8868_u751f_u6210((function(...) | ||
| 131 | local _tbl_0 = { } | ||
| 132 | local _list_0 = _u9879_u76ee | ||
| 133 | for _index_0 = 1, #_list_0 do | ||
| 134 | local _u7269_u54c1 = _list_0[_index_0] | ||
| 135 | _tbl_0[_u7269_u54c1(...)] = true | ||
| 136 | end | ||
| 137 | return _tbl_0 | ||
| 138 | end)(...)) | ||
| 139 | _u505a_u64cd_u4f5c((function() | ||
| 140 | return _u51fd_u6570() | 133 | return _u51fd_u6570() |
| 141 | end)()) | 134 | end |
| 142 | _u505a_u64cd_u4f5c((function(...) | 135 | end |
| 136 | local _anon_func_13 = function(_u51fd_u6570, ...) | ||
| 137 | do | ||
| 143 | return _u51fd_u6570(...) | 138 | return _u51fd_u6570(...) |
| 144 | end)(...)) | 139 | end |
| 145 | _u5f53_u64cd_u4f5c((function() | 140 | end |
| 146 | local _accum_0 = { } | 141 | local _anon_func_14 = function(_u51fd_u6570) |
| 147 | local _len_0 = 1 | 142 | local _accum_0 = { } |
| 148 | while false do | 143 | local _len_0 = 1 |
| 149 | _accum_0[_len_0] = _u51fd_u6570() | 144 | while false do |
| 150 | _len_0 = _len_0 + 1 | 145 | _accum_0[_len_0] = _u51fd_u6570() |
| 151 | end | 146 | _len_0 = _len_0 + 1 |
| 152 | return _accum_0 | 147 | end |
| 153 | end)()) | 148 | return _accum_0 |
| 154 | _u5f53_u64cd_u4f5c((function(...) | 149 | end |
| 155 | local _accum_0 = { } | 150 | local _anon_func_15 = function(_u51fd_u6570, ...) |
| 156 | local _len_0 = 1 | 151 | local _accum_0 = { } |
| 157 | while false do | 152 | local _len_0 = 1 |
| 158 | _accum_0[_len_0] = _u51fd_u6570(...) | 153 | while false do |
| 159 | _len_0 = _len_0 + 1 | 154 | _accum_0[_len_0] = _u51fd_u6570(...) |
| 160 | end | 155 | _len_0 = _len_0 + 1 |
| 161 | return _accum_0 | 156 | end |
| 162 | end)(...)) | 157 | return _accum_0 |
| 163 | _u5982_u679c_u64cd_u4f5c((function() | 158 | end |
| 164 | if false then | 159 | local _anon_func_16 = function(_u51fd_u6570) |
| 165 | return _u51fd_u6570() | 160 | if false then |
| 166 | end | 161 | return _u51fd_u6570() |
| 167 | end)()) | 162 | end |
| 168 | _u5982_u679c_u64cd_u4f5c((function(...) | 163 | end |
| 169 | if false then | 164 | local _anon_func_17 = function(_u51fd_u6570, ...) |
| 170 | return _u51fd_u6570(...) | 165 | if false then |
| 171 | end | 166 | return _u51fd_u6570(...) |
| 172 | end)(...)) | 167 | end |
| 173 | _u9664_u975e_u64cd_u4f5c((function() | 168 | end |
| 174 | if not true then | 169 | local _anon_func_18 = function(_u51fd_u6570) |
| 175 | return _u51fd_u6570() | 170 | if not true then |
| 176 | end | 171 | return _u51fd_u6570() |
| 177 | end)()) | 172 | end |
| 178 | _u9664_u975e_u64cd_u4f5c((function(...) | 173 | end |
| 179 | if not true then | 174 | local _anon_func_19 = function(_u51fd_u6570, ...) |
| 180 | return _u51fd_u6570(...) | 175 | if not true then |
| 181 | end | 176 | return _u51fd_u6570(...) |
| 182 | end)(...)) | 177 | end |
| 183 | _u5207_u6362_u64cd_u4f5c((function() | 178 | end |
| 184 | local _exp_0 = _u53d8_u91cfx | 179 | local _anon_func_20 = function(_u53d8_u91cfx, _u51fd_u6570) |
| 185 | if "abc" == _exp_0 then | 180 | if "abc" == _u53d8_u91cfx then |
| 186 | return _u51fd_u6570() | 181 | return _u51fd_u6570() |
| 187 | end | 182 | end |
| 188 | end)()) | 183 | end |
| 189 | _u5207_u6362_u64cd_u4f5c((function(...) | 184 | local _anon_func_21 = function(_u53d8_u91cfx, _u51fd_u6570, ...) |
| 190 | local _exp_0 = _u53d8_u91cfx | 185 | if "abc" == _u53d8_u91cfx then |
| 191 | if "abc" == _exp_0 then | 186 | return _u51fd_u6570(...) |
| 192 | return _u51fd_u6570(...) | 187 | end |
| 193 | end | 188 | end |
| 194 | end)(...)) | 189 | local _anon_func_22 = function(_u51fd_u6570) |
| 195 | _u8868_u8fbe_u5f0f_u64cd_u4f5c((function() | 190 | if _u51fd_u6570 ~= nil then |
| 196 | local _obj_0 = _u51fd_u6570 | 191 | return _u51fd_u6570() |
| 197 | if _obj_0 ~= nil then | 192 | end |
| 198 | return _obj_0() | 193 | return nil |
| 199 | end | 194 | end |
| 200 | return nil | 195 | local _anon_func_23 = function(_u51fd_u6570, ...) |
| 201 | end)()) | 196 | if _u51fd_u6570 ~= nil then |
| 202 | _u8868_u8fbe_u5f0f_u64cd_u4f5c((function(...) | 197 | return _u51fd_u6570(...) |
| 203 | local _obj_0 = _u51fd_u6570 | 198 | end |
| 204 | if _obj_0 ~= nil then | 199 | return nil |
| 205 | return _obj_0(...) | 200 | end |
| 206 | end | 201 | local _anon_func_24 = function(select, _u6253_u5370, ...) |
| 207 | return nil | 202 | do |
| 208 | end)(...)) | 203 | _u6253_u5370(select("#", ...)) |
| 204 | return _u6253_u5370(...) | ||
| 205 | end | ||
| 206 | end | ||
| 207 | local _anon_func_25 = function(_u6253_u5370, ...) | ||
| 208 | do | ||
| 209 | return _u6253_u5370(...) | ||
| 210 | end | ||
| 211 | end | ||
| 212 | local _anon_func_26 = function(_u53d8_u91cfx, _u8868, _u88682) | ||
| 213 | if 1 == _u53d8_u91cfx then | ||
| 214 | _u8868["变量x"] = 123 | ||
| 215 | return _u8868 | ||
| 216 | else | ||
| 217 | return _u88682 | ||
| 218 | end | ||
| 219 | end | ||
| 220 | local _anon_func_27 = function(_u6253_u5370, ...) | ||
| 221 | do | ||
| 222 | return _u6253_u5370(...) | ||
| 223 | end | ||
| 224 | end | ||
| 225 | local _anon_func_28 = function(_u6761_u4ef6) | ||
| 226 | if _u6761_u4ef6 then | ||
| 227 | return 3, 4, 5 | ||
| 228 | end | ||
| 229 | end | ||
| 230 | local _anon_func_29 = function(_u6253_u5370, _arg_0, ...) | ||
| 231 | do | ||
| 232 | local _u8868 = _arg_0 | ||
| 233 | return _u6253_u5370(...) | ||
| 234 | end | ||
| 235 | end | ||
| 236 | local _u8fde_u63a5 | ||
| 237 | _u8fde_u63a5 = function(...) | ||
| 238 | _u5e26_u6709(_anon_func_0(_u53d8_u91cfa)) | ||
| 239 | _u5e26_u6709(_anon_func_1(_u53d8_u91cfa, ...)) | ||
| 240 | _u5217_u8868_u751f_u6210(_anon_func_2(_u9879_u76ee)) | ||
| 241 | _u5217_u8868_u751f_u6210(_anon_func_3(_u9879_u76ee, ...)) | ||
| 242 | _u5217_u8868_u751f_u6210(_anon_func_4(_u9879_u76ee)) | ||
| 243 | _u5217_u8868_u751f_u6210(_anon_func_5(_u9879_u76ee, ...)) | ||
| 244 | _u7c7b_u751f_u6210(_anon_func_6(setmetatable, _u51fd_u6570)) | ||
| 245 | _u7c7b_u751f_u6210(_anon_func_7(setmetatable, _u51fd_u6570, ...)) | ||
| 246 | _u8868_u751f_u6210(_anon_func_8(pairs, _u8868)) | ||
| 247 | _u8868_u751f_u6210(_anon_func_9(pairs, _u8868, ...)) | ||
| 248 | _u8868_u751f_u6210(_anon_func_10(_u9879_u76ee)) | ||
| 249 | _u8868_u751f_u6210(_anon_func_11(_u9879_u76ee, ...)) | ||
| 250 | _u505a_u64cd_u4f5c(_anon_func_12(_u51fd_u6570)) | ||
| 251 | _u505a_u64cd_u4f5c(_anon_func_13(_u51fd_u6570, ...)) | ||
| 252 | _u5f53_u64cd_u4f5c(_anon_func_14(_u51fd_u6570)) | ||
| 253 | _u5f53_u64cd_u4f5c(_anon_func_15(_u51fd_u6570, ...)) | ||
| 254 | _u5982_u679c_u64cd_u4f5c(_anon_func_16(_u51fd_u6570)) | ||
| 255 | _u5982_u679c_u64cd_u4f5c(_anon_func_17(_u51fd_u6570, ...)) | ||
| 256 | _u9664_u975e_u64cd_u4f5c(_anon_func_18(_u51fd_u6570)) | ||
| 257 | _u9664_u975e_u64cd_u4f5c(_anon_func_19(_u51fd_u6570, ...)) | ||
| 258 | _u5207_u6362_u64cd_u4f5c(_anon_func_20(_u53d8_u91cfx, _u51fd_u6570)) | ||
| 259 | _u5207_u6362_u64cd_u4f5c(_anon_func_21(_u53d8_u91cfx, _u51fd_u6570, ...)) | ||
| 260 | _u8868_u8fbe_u5f0f_u64cd_u4f5c(_anon_func_22(_u51fd_u6570)) | ||
| 261 | _u8868_u8fbe_u5f0f_u64cd_u4f5c(_anon_func_23(_u51fd_u6570, ...)) | ||
| 209 | _u5192_u53f7((function() | 262 | _u5192_u53f7((function() |
| 210 | local _base_0 = f() | 263 | local _base_0 = f() |
| 211 | local _fn_0 = _base_0["函数"] | 264 | local _fn_0 = _base_0["函数"] |
| @@ -240,40 +293,17 @@ _u8fde_u63a5 = function(...) | |||
| 240 | _u591a_u53c2_u6570_u51fd_u6570 = function() | 293 | _u591a_u53c2_u6570_u51fd_u6570 = function() |
| 241 | return 10, nil, 20, nil, 30 | 294 | return 10, nil, 20, nil, 30 |
| 242 | end | 295 | end |
| 243 | return (function(...) | 296 | return _anon_func_24(select, _u6253_u5370, _u591a_u53c2_u6570_u51fd_u6570()) |
| 244 | _u6253_u5370(select("#", ...)) | ||
| 245 | return _u6253_u5370(...) | ||
| 246 | end)(_u591a_u53c2_u6570_u51fd_u6570()) | ||
| 247 | end)(_u51fd_u6570_u540d(true)) | 297 | end)(_u51fd_u6570_u540d(true)) |
| 248 | end | 298 | end |
| 249 | do | 299 | do |
| 250 | (function(...) | 300 | _anon_func_25(_u6253_u5370, _anon_func_26(_u53d8_u91cfx, _u8868, _u88682)) |
| 251 | return _u6253_u5370(...) | ||
| 252 | end)((function() | ||
| 253 | local _exp_0 = _u53d8_u91cfx | ||
| 254 | if 1 == _exp_0 then | ||
| 255 | local _with_0 = _u8868 | ||
| 256 | _with_0["变量x"] = 123 | ||
| 257 | return _with_0 | ||
| 258 | else | ||
| 259 | return _u88682 | ||
| 260 | end | ||
| 261 | end)()) | ||
| 262 | end | 301 | end |
| 263 | do | 302 | do |
| 264 | (function(...) | 303 | _anon_func_27(_u6253_u5370, 1, 2, _anon_func_28(_u6761_u4ef6)) |
| 265 | return _u6253_u5370(...) | ||
| 266 | end)(1, 2, (function() | ||
| 267 | if _u6761_u4ef6 then | ||
| 268 | return 3, 4, 5 | ||
| 269 | end | ||
| 270 | end)()) | ||
| 271 | end | 304 | end |
| 272 | do | 305 | do |
| 273 | (function(_arg_0, ...) | 306 | _anon_func_29(_u6253_u5370, { |
| 274 | local _u8868 = _arg_0 | ||
| 275 | return _u6253_u5370(...) | ||
| 276 | end)({ | ||
| 277 | ["名字"] = "abc", | 307 | ["名字"] = "abc", |
| 278 | ["值"] = 123 | 308 | ["值"] = 123 |
| 279 | }) | 309 | }) |
diff --git a/spec/outputs/vararg.lua b/spec/outputs/vararg.lua index ea40da1..39becd4 100644 --- a/spec/outputs/vararg.lua +++ b/spec/outputs/vararg.lua | |||
| @@ -1,211 +1,264 @@ | |||
| 1 | local join | 1 | local _anon_func_0 = function(a) |
| 2 | join = function(...) | 2 | a:func() |
| 3 | f_with((function() | 3 | return a |
| 4 | local _with_0 = a | 4 | end |
| 5 | _with_0:func() | 5 | local _anon_func_1 = function(a, ...) |
| 6 | return _with_0 | 6 | a:func(...) |
| 7 | end)()) | 7 | return a |
| 8 | f_with((function(...) | 8 | end |
| 9 | local _with_0 = a | 9 | local _anon_func_2 = function(items) |
| 10 | _with_0:func(...) | 10 | local _accum_0 = { } |
| 11 | return _with_0 | 11 | local _len_0 = 1 |
| 12 | end)(...)) | 12 | for i = 1, 10 do |
| 13 | f_listcomp((function() | 13 | _accum_0[_len_0] = items[i] |
| 14 | local _accum_0 = { } | 14 | _len_0 = _len_0 + 1 |
| 15 | local _len_0 = 1 | 15 | end |
| 16 | for i = 1, 10 do | 16 | return _accum_0 |
| 17 | _accum_0[_len_0] = items[i] | 17 | end |
| 18 | _len_0 = _len_0 + 1 | 18 | local _anon_func_3 = function(items, ...) |
| 19 | end | 19 | local _accum_0 = { } |
| 20 | return _accum_0 | 20 | local _len_0 = 1 |
| 21 | end)()) | 21 | for i = 1, 10 do |
| 22 | f_listcomp((function(...) | 22 | _accum_0[_len_0] = items[i](...) |
| 23 | local _accum_0 = { } | 23 | _len_0 = _len_0 + 1 |
| 24 | local _len_0 = 1 | 24 | end |
| 25 | for i = 1, 10 do | 25 | return _accum_0 |
| 26 | _accum_0[_len_0] = items[i](...) | 26 | end |
| 27 | _len_0 = _len_0 + 1 | 27 | local _anon_func_4 = function(items) |
| 28 | end | 28 | local _accum_0 = { } |
| 29 | return _accum_0 | 29 | local _len_0 = 1 |
| 30 | end)(...)) | 30 | for _index_0 = 1, #items do |
| 31 | f_listcomp((function() | 31 | local item = items[_index_0] |
| 32 | local _accum_0 = { } | 32 | _accum_0[_len_0] = item |
| 33 | local _len_0 = 1 | 33 | _len_0 = _len_0 + 1 |
| 34 | local _list_0 = items | 34 | end |
| 35 | for _index_0 = 1, #_list_0 do | 35 | return _accum_0 |
| 36 | local item = _list_0[_index_0] | 36 | end |
| 37 | _accum_0[_len_0] = item | 37 | local _anon_func_5 = function(items, ...) |
| 38 | _len_0 = _len_0 + 1 | 38 | local _accum_0 = { } |
| 39 | end | 39 | local _len_0 = 1 |
| 40 | return _accum_0 | 40 | for _index_0 = 1, #items do |
| 41 | end)()) | 41 | local item = items[_index_0] |
| 42 | f_listcomp((function(...) | 42 | _accum_0[_len_0] = item(...) |
| 43 | local _accum_0 = { } | 43 | _len_0 = _len_0 + 1 |
| 44 | local _len_0 = 1 | 44 | end |
| 45 | local _list_0 = items | 45 | return _accum_0 |
| 46 | for _index_0 = 1, #_list_0 do | 46 | end |
| 47 | local item = _list_0[_index_0] | 47 | local _anon_func_6 = function(setmetatable, func) |
| 48 | _accum_0[_len_0] = item(...) | 48 | local A |
| 49 | _len_0 = _len_0 + 1 | 49 | do |
| 50 | local _class_0 | ||
| 51 | local _base_0 = { } | ||
| 52 | if _base_0.__index == nil then | ||
| 53 | _base_0.__index = _base_0 | ||
| 50 | end | 54 | end |
| 51 | return _accum_0 | 55 | _class_0 = setmetatable({ |
| 52 | end)(...)) | 56 | __init = function() end, |
| 53 | f_class((function() | 57 | __base = _base_0, |
| 54 | local A | 58 | __name = "A" |
| 55 | do | 59 | }, { |
| 56 | local _class_0 | 60 | __index = _base_0, |
| 57 | local _base_0 = { } | 61 | __call = function(cls, ...) |
| 58 | if _base_0.__index == nil then | 62 | local _self_0 = setmetatable({ }, _base_0) |
| 59 | _base_0.__index = _base_0 | 63 | cls.__init(_self_0, ...) |
| 64 | return _self_0 | ||
| 60 | end | 65 | end |
| 61 | _class_0 = setmetatable({ | 66 | }) |
| 62 | __init = function() end, | 67 | _base_0.__class = _class_0 |
| 63 | __base = _base_0, | 68 | local self = _class_0; |
| 64 | __name = "A" | 69 | func() |
| 65 | }, { | 70 | A = _class_0 |
| 66 | __index = _base_0, | 71 | return _class_0 |
| 67 | __call = function(cls, ...) | 72 | end |
| 68 | local _self_0 = setmetatable({ }, _base_0) | 73 | end |
| 69 | cls.__init(_self_0, ...) | 74 | local _anon_func_7 = function(setmetatable, func, ...) |
| 70 | return _self_0 | 75 | local A |
| 71 | end | 76 | do |
| 72 | }) | 77 | local _class_0 |
| 73 | _base_0.__class = _class_0 | 78 | local _base_0 = { } |
| 74 | local self = _class_0; | 79 | if _base_0.__index == nil then |
| 75 | func() | 80 | _base_0.__index = _base_0 |
| 76 | A = _class_0 | ||
| 77 | return _class_0 | ||
| 78 | end | 81 | end |
| 79 | end)()) | 82 | _class_0 = setmetatable({ |
| 80 | f_class((function(...) | 83 | __init = function() end, |
| 81 | local A | 84 | __base = _base_0, |
| 82 | do | 85 | __name = "A" |
| 83 | local _class_0 | 86 | }, { |
| 84 | local _base_0 = { } | 87 | __index = _base_0, |
| 85 | if _base_0.__index == nil then | 88 | __call = function(cls, ...) |
| 86 | _base_0.__index = _base_0 | 89 | local _self_0 = setmetatable({ }, _base_0) |
| 90 | cls.__init(_self_0, ...) | ||
| 91 | return _self_0 | ||
| 87 | end | 92 | end |
| 88 | _class_0 = setmetatable({ | 93 | }) |
| 89 | __init = function() end, | 94 | _base_0.__class = _class_0 |
| 90 | __base = _base_0, | 95 | local self = _class_0; |
| 91 | __name = "A" | 96 | func(...) |
| 92 | }, { | 97 | A = _class_0 |
| 93 | __index = _base_0, | 98 | return _class_0 |
| 94 | __call = function(cls, ...) | 99 | end |
| 95 | local _self_0 = setmetatable({ }, _base_0) | 100 | end |
| 96 | cls.__init(_self_0, ...) | 101 | local _anon_func_8 = function(pairs, tb) |
| 97 | return _self_0 | 102 | local _tbl_0 = { } |
| 98 | end | 103 | for k, v in pairs(tb) do |
| 99 | }) | 104 | _tbl_0[k] = v |
| 100 | _base_0.__class = _class_0 | 105 | end |
| 101 | local self = _class_0; | 106 | return _tbl_0 |
| 102 | func(...) | 107 | end |
| 103 | A = _class_0 | 108 | local _anon_func_9 = function(pairs, tb, ...) |
| 104 | return _class_0 | 109 | local _tbl_0 = { } |
| 105 | end | 110 | for k, v in pairs(tb) do |
| 106 | end)(...)) | 111 | _tbl_0[k] = v(...) |
| 107 | f_tblcomp((function() | 112 | end |
| 108 | local _tbl_0 = { } | 113 | return _tbl_0 |
| 109 | for k, v in pairs(tb) do | 114 | end |
| 110 | _tbl_0[k] = v | 115 | local _anon_func_10 = function(items) |
| 111 | end | 116 | local _tbl_0 = { } |
| 112 | return _tbl_0 | 117 | for _index_0 = 1, #items do |
| 113 | end)()) | 118 | local item = items[_index_0] |
| 114 | f_tblcomp((function(...) | 119 | _tbl_0[item] = true |
| 115 | local _tbl_0 = { } | 120 | end |
| 116 | for k, v in pairs(tb) do | 121 | return _tbl_0 |
| 117 | _tbl_0[k] = v(...) | 122 | end |
| 118 | end | 123 | local _anon_func_11 = function(items, ...) |
| 119 | return _tbl_0 | 124 | local _tbl_0 = { } |
| 120 | end)(...)) | 125 | for _index_0 = 1, #items do |
| 121 | f_tblcomp((function() | 126 | local item = items[_index_0] |
| 122 | local _tbl_0 = { } | 127 | _tbl_0[item(...)] = true |
| 123 | local _list_0 = items | 128 | end |
| 124 | for _index_0 = 1, #_list_0 do | 129 | return _tbl_0 |
| 125 | local item = _list_0[_index_0] | 130 | end |
| 126 | _tbl_0[item] = true | 131 | local _anon_func_12 = function(func) |
| 127 | end | 132 | do |
| 128 | return _tbl_0 | ||
| 129 | end)()) | ||
| 130 | f_tblcomp((function(...) | ||
| 131 | local _tbl_0 = { } | ||
| 132 | local _list_0 = items | ||
| 133 | for _index_0 = 1, #_list_0 do | ||
| 134 | local item = _list_0[_index_0] | ||
| 135 | _tbl_0[item(...)] = true | ||
| 136 | end | ||
| 137 | return _tbl_0 | ||
| 138 | end)(...)) | ||
| 139 | f_do((function() | ||
| 140 | return func() | 133 | return func() |
| 141 | end)()) | 134 | end |
| 142 | f_do((function(...) | 135 | end |
| 136 | local _anon_func_13 = function(func, ...) | ||
| 137 | do | ||
| 143 | return func(...) | 138 | return func(...) |
| 144 | end)(...)) | 139 | end |
| 145 | f_while((function() | 140 | end |
| 146 | local _accum_0 = { } | 141 | local _anon_func_14 = function(func) |
| 147 | local _len_0 = 1 | 142 | local _accum_0 = { } |
| 148 | while false do | 143 | local _len_0 = 1 |
| 149 | _accum_0[_len_0] = func() | 144 | while false do |
| 150 | _len_0 = _len_0 + 1 | 145 | _accum_0[_len_0] = func() |
| 151 | end | 146 | _len_0 = _len_0 + 1 |
| 152 | return _accum_0 | 147 | end |
| 153 | end)()) | 148 | return _accum_0 |
| 154 | f_while((function(...) | 149 | end |
| 155 | local _accum_0 = { } | 150 | local _anon_func_15 = function(func, ...) |
| 156 | local _len_0 = 1 | 151 | local _accum_0 = { } |
| 157 | while false do | 152 | local _len_0 = 1 |
| 158 | _accum_0[_len_0] = func(...) | 153 | while false do |
| 159 | _len_0 = _len_0 + 1 | 154 | _accum_0[_len_0] = func(...) |
| 160 | end | 155 | _len_0 = _len_0 + 1 |
| 161 | return _accum_0 | 156 | end |
| 162 | end)(...)) | 157 | return _accum_0 |
| 163 | f_if((function() | 158 | end |
| 164 | if false then | 159 | local _anon_func_16 = function(func) |
| 165 | return func() | 160 | if false then |
| 166 | end | 161 | return func() |
| 167 | end)()) | 162 | end |
| 168 | f_if((function(...) | 163 | end |
| 169 | if false then | 164 | local _anon_func_17 = function(func, ...) |
| 170 | return func(...) | 165 | if false then |
| 171 | end | 166 | return func(...) |
| 172 | end)(...)) | 167 | end |
| 173 | f_unless((function() | 168 | end |
| 174 | if not true then | 169 | local _anon_func_18 = function(func) |
| 175 | return func() | 170 | if not true then |
| 176 | end | 171 | return func() |
| 177 | end)()) | 172 | end |
| 178 | f_unless((function(...) | 173 | end |
| 179 | if not true then | 174 | local _anon_func_19 = function(func, ...) |
| 180 | return func(...) | 175 | if not true then |
| 181 | end | 176 | return func(...) |
| 182 | end)(...)) | 177 | end |
| 183 | f_switch((function() | 178 | end |
| 184 | local _exp_0 = x | 179 | local _anon_func_20 = function(x, func) |
| 185 | if "abc" == _exp_0 then | 180 | if "abc" == x then |
| 186 | return func() | 181 | return func() |
| 187 | end | 182 | end |
| 188 | end)()) | 183 | end |
| 189 | f_switch((function(...) | 184 | local _anon_func_21 = function(x, func, ...) |
| 190 | local _exp_0 = x | 185 | if "abc" == x then |
| 191 | if "abc" == _exp_0 then | 186 | return func(...) |
| 192 | return func(...) | 187 | end |
| 193 | end | 188 | end |
| 194 | end)(...)) | 189 | local _anon_func_22 = function(func) |
| 195 | f_eop((function() | 190 | if func ~= nil then |
| 196 | local _obj_0 = func | 191 | return func() |
| 197 | if _obj_0 ~= nil then | 192 | end |
| 198 | return _obj_0() | 193 | return nil |
| 199 | end | 194 | end |
| 200 | return nil | 195 | local _anon_func_23 = function(func, ...) |
| 201 | end)()) | 196 | if func ~= nil then |
| 202 | f_eop((function(...) | 197 | return func(...) |
| 203 | local _obj_0 = func | 198 | end |
| 204 | if _obj_0 ~= nil then | 199 | return nil |
| 205 | return _obj_0(...) | 200 | end |
| 206 | end | 201 | local _anon_func_24 = function(select, print, ...) |
| 207 | return nil | 202 | do |
| 208 | end)(...)) | 203 | print(select("#", ...)) |
| 204 | return print(...) | ||
| 205 | end | ||
| 206 | end | ||
| 207 | local _anon_func_25 = function(print, ...) | ||
| 208 | do | ||
| 209 | return print(...) | ||
| 210 | end | ||
| 211 | end | ||
| 212 | local _anon_func_26 = function(x, tb, tb2) | ||
| 213 | if 1 == x then | ||
| 214 | tb.x = 123 | ||
| 215 | return tb | ||
| 216 | else | ||
| 217 | return tb2 | ||
| 218 | end | ||
| 219 | end | ||
| 220 | local _anon_func_27 = function(print, ...) | ||
| 221 | do | ||
| 222 | return print(...) | ||
| 223 | end | ||
| 224 | end | ||
| 225 | local _anon_func_28 = function(cond) | ||
| 226 | if cond then | ||
| 227 | return 3, 4, 5 | ||
| 228 | end | ||
| 229 | end | ||
| 230 | local _anon_func_29 = function(print, _arg_0, ...) | ||
| 231 | do | ||
| 232 | local tb = _arg_0 | ||
| 233 | return print(...) | ||
| 234 | end | ||
| 235 | end | ||
| 236 | local join | ||
| 237 | join = function(...) | ||
| 238 | f_with(_anon_func_0(a)) | ||
| 239 | f_with(_anon_func_1(a, ...)) | ||
| 240 | f_listcomp(_anon_func_2(items)) | ||
| 241 | f_listcomp(_anon_func_3(items, ...)) | ||
| 242 | f_listcomp(_anon_func_4(items)) | ||
| 243 | f_listcomp(_anon_func_5(items, ...)) | ||
| 244 | f_class(_anon_func_6(setmetatable, func)) | ||
| 245 | f_class(_anon_func_7(setmetatable, func, ...)) | ||
| 246 | f_tblcomp(_anon_func_8(pairs, tb)) | ||
| 247 | f_tblcomp(_anon_func_9(pairs, tb, ...)) | ||
| 248 | f_tblcomp(_anon_func_10(items)) | ||
| 249 | f_tblcomp(_anon_func_11(items, ...)) | ||
| 250 | f_do(_anon_func_12(func)) | ||
| 251 | f_do(_anon_func_13(func, ...)) | ||
| 252 | f_while(_anon_func_14(func)) | ||
| 253 | f_while(_anon_func_15(func, ...)) | ||
| 254 | f_if(_anon_func_16(func)) | ||
| 255 | f_if(_anon_func_17(func, ...)) | ||
| 256 | f_unless(_anon_func_18(func)) | ||
| 257 | f_unless(_anon_func_19(func, ...)) | ||
| 258 | f_switch(_anon_func_20(x, func)) | ||
| 259 | f_switch(_anon_func_21(x, func, ...)) | ||
| 260 | f_eop(_anon_func_22(func)) | ||
| 261 | f_eop(_anon_func_23(func, ...)) | ||
| 209 | f_colon((function() | 262 | f_colon((function() |
| 210 | local _base_0 = f() | 263 | local _base_0 = f() |
| 211 | local _fn_0 = _base_0.func | 264 | local _fn_0 = _base_0.func |
| @@ -240,40 +293,17 @@ join = function(...) | |||
| 240 | fn_many_args = function() | 293 | fn_many_args = function() |
| 241 | return 10, nil, 20, nil, 30 | 294 | return 10, nil, 20, nil, 30 |
| 242 | end | 295 | end |
| 243 | return (function(...) | 296 | return _anon_func_24(select, print, fn_many_args()) |
| 244 | print(select("#", ...)) | ||
| 245 | return print(...) | ||
| 246 | end)(fn_many_args()) | ||
| 247 | end)(fn(true)) | 297 | end)(fn(true)) |
| 248 | end | 298 | end |
| 249 | do | 299 | do |
| 250 | (function(...) | 300 | _anon_func_25(print, _anon_func_26(x, tb, tb2)) |
| 251 | return print(...) | ||
| 252 | end)((function() | ||
| 253 | local _exp_0 = x | ||
| 254 | if 1 == _exp_0 then | ||
| 255 | local _with_0 = tb | ||
| 256 | _with_0.x = 123 | ||
| 257 | return _with_0 | ||
| 258 | else | ||
| 259 | return tb2 | ||
| 260 | end | ||
| 261 | end)()) | ||
| 262 | end | 301 | end |
| 263 | do | 302 | do |
| 264 | (function(...) | 303 | _anon_func_27(print, 1, 2, _anon_func_28(cond)) |
| 265 | return print(...) | ||
| 266 | end)(1, 2, (function() | ||
| 267 | if cond then | ||
| 268 | return 3, 4, 5 | ||
| 269 | end | ||
| 270 | end)()) | ||
| 271 | end | 304 | end |
| 272 | do | 305 | do |
| 273 | (function(_arg_0, ...) | 306 | _anon_func_29(print, { |
| 274 | local tb = _arg_0 | ||
| 275 | return print(...) | ||
| 276 | end)({ | ||
| 277 | name = "abc", | 307 | name = "abc", |
| 278 | value = 123 | 308 | value = 123 |
| 279 | }) | 309 | }) |
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index fbf7a63..3a22345 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
| @@ -195,7 +195,7 @@ std::string YueLineComment_t::to_string(void* ud) const { | |||
| 195 | } | 195 | } |
| 196 | std::string MultilineCommentInner_t::to_string(void* ud) const { | 196 | std::string MultilineCommentInner_t::to_string(void* ud) const { |
| 197 | auto info = reinterpret_cast<YueFormat*>(ud); | 197 | auto info = reinterpret_cast<YueFormat*>(ud); |
| 198 | return "--[["s + info->convert(this) + "]]"s; | 198 | return info->convert(this); |
| 199 | } | 199 | } |
| 200 | std::string Variable_t::to_string(void* ud) const { | 200 | std::string Variable_t::to_string(void* ud) const { |
| 201 | return name->to_string(ud); | 201 | return name->to_string(ud); |
| @@ -583,12 +583,12 @@ std::string CatchBlock_t::to_string(void* ud) const { | |||
| 583 | auto info = reinterpret_cast<YueFormat*>(ud); | 583 | auto info = reinterpret_cast<YueFormat*>(ud); |
| 584 | auto line = "catch "s + err->to_string(ud); | 584 | auto line = "catch "s + err->to_string(ud); |
| 585 | info->pushScope(); | 585 | info->pushScope(); |
| 586 | auto block = body->to_string(ud); | 586 | auto blockStr = block->to_string(ud); |
| 587 | if (block.empty()) { | 587 | if (blockStr.empty()) { |
| 588 | block = info->ind() + "--"s; | 588 | blockStr = info->ind() + "--"s; |
| 589 | } | 589 | } |
| 590 | info->popScope(); | 590 | info->popScope(); |
| 591 | return line + '\n' + block; | 591 | return line + '\n' + blockStr; |
| 592 | } | 592 | } |
| 593 | std::string Try_t::to_string(void* ud) const { | 593 | std::string Try_t::to_string(void* ud) const { |
| 594 | auto info = reinterpret_cast<YueFormat*>(ud); | 594 | auto info = reinterpret_cast<YueFormat*>(ud); |
| @@ -609,21 +609,158 @@ std::string Try_t::to_string(void* ud) const { | |||
| 609 | } | 609 | } |
| 610 | return join(temp, "\n"sv); | 610 | return join(temp, "\n"sv); |
| 611 | } | 611 | } |
| 612 | std::string Comprehension_t::to_string(void* ud) const { | 612 | static bool isInBlockExp(ast_node* node, bool last = false) { |
| 613 | str_list temp; | 613 | if (auto exp = ast_cast<Exp_t>(node)) { |
| 614 | for (const auto& item : items.objects()) { | 614 | UnaryExp_t* unaryExp = nullptr; |
| 615 | temp.push_back(item->to_string(ud)); | 615 | if (exp->opValues.empty()) { |
| 616 | } | 616 | unaryExp = static_cast<UnaryExp_t*>(exp->pipeExprs.back()); |
| 617 | if (temp.size() > 0) { | 617 | } else { |
| 618 | temp.front().insert(0, temp.front()[0] == '[' ? " "s : ""s); | 618 | unaryExp = static_cast<UnaryExp_t*>(static_cast<ExpOpValue_t*>(exp->opValues.back())->pipeExprs.back()); |
| 619 | } | ||
| 620 | auto value = static_cast<Value_t*>(unaryExp->expos.back()); | ||
| 621 | if (auto simpleValue = value->item.as<SimpleValue_t>()) { | ||
| 622 | switch (simpleValue->value->get_id()) { | ||
| 623 | case id<TableLit_t>(): | ||
| 624 | case id<ConstValue_t>(): | ||
| 625 | case id<Num_t>(): | ||
| 626 | case id<VarArg_t>(): | ||
| 627 | case id<TblComprehension_t>(): | ||
| 628 | case id<Comprehension_t>(): | ||
| 629 | return false; | ||
| 630 | case id<FunLit_t>(): | ||
| 631 | if (!last) { | ||
| 632 | return true; | ||
| 633 | } | ||
| 634 | return false; | ||
| 635 | default: | ||
| 636 | return true; | ||
| 637 | } | ||
| 638 | } else if (auto chainValue = value->item.as<ChainValue_t>()) { | ||
| 639 | if (ast_is<InvokeArgs_t>(chainValue->items.back())) { | ||
| 640 | return true; | ||
| 641 | } | ||
| 642 | } else if (!last && value->item.is<SimpleTable_t>()) { | ||
| 643 | return true; | ||
| 644 | } | ||
| 645 | } else if (ast_is<TableBlock_t>(node)) { | ||
| 646 | return true; | ||
| 647 | } else { | ||
| 648 | switch (node->get_id()) { | ||
| 649 | case id<VariablePairDef_t>(): { | ||
| 650 | auto pair = static_cast<VariablePairDef_t*>(node); | ||
| 651 | if (pair->defVal) { | ||
| 652 | return true; | ||
| 653 | } | ||
| 654 | return false; | ||
| 655 | } | ||
| 656 | case id<NormalPairDef_t>(): { | ||
| 657 | auto pair = static_cast<NormalPairDef_t*>(node); | ||
| 658 | if (pair->defVal) { | ||
| 659 | return true; | ||
| 660 | } | ||
| 661 | return isInBlockExp(pair->pair->value); | ||
| 662 | } | ||
| 663 | case id<SpreadExp_t>(): { | ||
| 664 | auto pair = static_cast<SpreadExp_t*>(node); | ||
| 665 | return isInBlockExp(pair->exp); | ||
| 666 | } | ||
| 667 | case id<NormalDef_t>(): { | ||
| 668 | auto pair = static_cast<NormalDef_t*>(node); | ||
| 669 | if (pair->defVal) { | ||
| 670 | return true; | ||
| 671 | } | ||
| 672 | return isInBlockExp(pair->item); | ||
| 673 | } | ||
| 674 | case id<MetaVariablePairDef_t>(): { | ||
| 675 | auto pair = static_cast<MetaVariablePairDef_t*>(node); | ||
| 676 | if (pair->defVal) { | ||
| 677 | return true; | ||
| 678 | } | ||
| 679 | return false; | ||
| 680 | } | ||
| 681 | case id<MetaNormalPairDef_t>(): { | ||
| 682 | auto pair = static_cast<MetaNormalPairDef_t*>(node); | ||
| 683 | if (pair->defVal) { | ||
| 684 | return true; | ||
| 685 | } | ||
| 686 | return isInBlockExp(pair->pair->value); | ||
| 687 | } | ||
| 688 | case id<VariablePair_t>(): { | ||
| 689 | return false; | ||
| 690 | } | ||
| 691 | case id<NormalPair_t>(): { | ||
| 692 | auto pair = static_cast<NormalPair_t*>(node); | ||
| 693 | return isInBlockExp(pair->value); | ||
| 694 | } | ||
| 695 | case id<MetaVariablePair_t>(): { | ||
| 696 | return false; | ||
| 697 | } | ||
| 698 | case id<MetaNormalPair_t>(): { | ||
| 699 | auto pair = static_cast<MetaNormalPair_t*>(node); | ||
| 700 | return isInBlockExp(pair->value); | ||
| 701 | } | ||
| 702 | case id<TableBlockIndent_t>(): { | ||
| 703 | return true; | ||
| 704 | } | ||
| 705 | case id<SpreadListExp_t>(): { | ||
| 706 | auto pair = static_cast<SpreadListExp_t*>(node); | ||
| 707 | return isInBlockExp(pair->exp); | ||
| 708 | } | ||
| 709 | default: | ||
| 710 | return false; | ||
| 711 | } | ||
| 619 | } | 712 | } |
| 713 | return false; | ||
| 714 | } | ||
| 715 | std::string Comprehension_t::to_string(void* ud) const { | ||
| 620 | if (items.size() != 2 || !ast_is<CompInner_t>(items.back())) { | 716 | if (items.size() != 2 || !ast_is<CompInner_t>(items.back())) { |
| 621 | if (items.size() == 1) { | 717 | if (items.size() == 1) { |
| 718 | str_list temp; | ||
| 719 | for (const auto& item : items.objects()) { | ||
| 720 | temp.push_back(item->to_string(ud)); | ||
| 721 | } | ||
| 722 | if (temp.size() > 0) { | ||
| 723 | temp.front().insert(0, temp.front()[0] == '[' ? " "s : ""s); | ||
| 724 | } | ||
| 622 | return '[' + join(temp, ", "sv) + ",]"s; | 725 | return '[' + join(temp, ", "sv) + ",]"s; |
| 623 | } else { | 726 | } else { |
| 624 | return '[' + join(temp, ", "sv) + ']'; | 727 | bool hasInBlockExp = false; |
| 728 | for (auto value : items.objects()) { | ||
| 729 | if (isInBlockExp(value, value == items.back())) { | ||
| 730 | hasInBlockExp = true; | ||
| 731 | break; | ||
| 732 | } | ||
| 733 | } | ||
| 734 | if (hasInBlockExp) { | ||
| 735 | auto info = reinterpret_cast<YueFormat*>(ud); | ||
| 736 | str_list temp; | ||
| 737 | temp.emplace_back("["s); | ||
| 738 | info->pushScope(); | ||
| 739 | for (auto value : items.objects()) { | ||
| 740 | temp.emplace_back(info->ind() + value->to_string(ud)); | ||
| 741 | } | ||
| 742 | info->popScope(); | ||
| 743 | temp.emplace_back(info->ind() + ']'); | ||
| 744 | return join(temp, "\n"sv); | ||
| 745 | } else { | ||
| 746 | str_list temp; | ||
| 747 | for (const auto& item : items.objects()) { | ||
| 748 | temp.push_back(item->to_string(ud)); | ||
| 749 | } | ||
| 750 | if (temp.size() > 0) { | ||
| 751 | temp.front().insert(0, temp.front()[0] == '[' ? " "s : ""s); | ||
| 752 | } | ||
| 753 | return '[' + join(temp, ", "sv) + ']'; | ||
| 754 | } | ||
| 625 | } | 755 | } |
| 626 | } else { | 756 | } else { |
| 757 | str_list temp; | ||
| 758 | for (const auto& item : items.objects()) { | ||
| 759 | temp.push_back(item->to_string(ud)); | ||
| 760 | } | ||
| 761 | if (temp.size() > 0) { | ||
| 762 | temp.front().insert(0, temp.front()[0] == '[' ? " "s : ""s); | ||
| 763 | } | ||
| 627 | return '[' + join(temp, " "sv) + ']'; | 764 | return '[' + join(temp, " "sv) + ']'; |
| 628 | } | 765 | } |
| 629 | } | 766 | } |
| @@ -834,109 +971,6 @@ std::string Slice_t::to_string(void* ud) const { | |||
| 834 | auto valueStr = join(temp); | 971 | auto valueStr = join(temp); |
| 835 | return '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']'; | 972 | return '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']'; |
| 836 | } | 973 | } |
| 837 | static bool isInBlockExp(ast_node* node, bool last = false) { | ||
| 838 | if (auto exp = ast_cast<Exp_t>(node)) { | ||
| 839 | UnaryExp_t* unaryExp = nullptr; | ||
| 840 | if (exp->opValues.empty()) { | ||
| 841 | unaryExp = static_cast<UnaryExp_t*>(exp->pipeExprs.back()); | ||
| 842 | } else { | ||
| 843 | unaryExp = static_cast<UnaryExp_t*>(static_cast<ExpOpValue_t*>(exp->opValues.back())->pipeExprs.back()); | ||
| 844 | } | ||
| 845 | auto value = static_cast<Value_t*>(unaryExp->expos.back()); | ||
| 846 | if (auto simpleValue = value->item.as<SimpleValue_t>()) { | ||
| 847 | switch (simpleValue->value->get_id()) { | ||
| 848 | case id<TableLit_t>(): | ||
| 849 | case id<ConstValue_t>(): | ||
| 850 | case id<Num_t>(): | ||
| 851 | case id<VarArg_t>(): | ||
| 852 | case id<TblComprehension_t>(): | ||
| 853 | case id<Comprehension_t>(): | ||
| 854 | return false; | ||
| 855 | case id<FunLit_t>(): | ||
| 856 | if (!last) { | ||
| 857 | return true; | ||
| 858 | } | ||
| 859 | return false; | ||
| 860 | default: | ||
| 861 | return true; | ||
| 862 | } | ||
| 863 | } else if (auto chainValue = value->item.as<ChainValue_t>()) { | ||
| 864 | if (ast_is<InvokeArgs_t>(chainValue->items.back())) { | ||
| 865 | return true; | ||
| 866 | } | ||
| 867 | } else if (!last && value->item.is<SimpleTable_t>()) { | ||
| 868 | return true; | ||
| 869 | } | ||
| 870 | } else if (ast_is<TableBlock_t>(node)) { | ||
| 871 | return true; | ||
| 872 | } else { | ||
| 873 | switch (node->get_id()) { | ||
| 874 | case id<VariablePairDef_t>(): { | ||
| 875 | auto pair = static_cast<VariablePairDef_t*>(node); | ||
| 876 | if (pair->defVal) { | ||
| 877 | return true; | ||
| 878 | } | ||
| 879 | return false; | ||
| 880 | } | ||
| 881 | case id<NormalPairDef_t>(): { | ||
| 882 | auto pair = static_cast<NormalPairDef_t*>(node); | ||
| 883 | if (pair->defVal) { | ||
| 884 | return true; | ||
| 885 | } | ||
| 886 | return isInBlockExp(pair->pair->value); | ||
| 887 | } | ||
| 888 | case id<SpreadExp_t>(): { | ||
| 889 | auto pair = static_cast<SpreadExp_t*>(node); | ||
| 890 | return isInBlockExp(pair->exp); | ||
| 891 | } | ||
| 892 | case id<NormalDef_t>(): { | ||
| 893 | auto pair = static_cast<NormalDef_t*>(node); | ||
| 894 | if (pair->defVal) { | ||
| 895 | return true; | ||
| 896 | } | ||
| 897 | return isInBlockExp(pair->item); | ||
| 898 | } | ||
| 899 | case id<MetaVariablePairDef_t>(): { | ||
| 900 | auto pair = static_cast<MetaVariablePairDef_t*>(node); | ||
| 901 | if (pair->defVal) { | ||
| 902 | return true; | ||
| 903 | } | ||
| 904 | return false; | ||
| 905 | } | ||
| 906 | case id<MetaNormalPairDef_t>(): { | ||
| 907 | auto pair = static_cast<MetaNormalPairDef_t*>(node); | ||
| 908 | if (pair->defVal) { | ||
| 909 | return true; | ||
| 910 | } | ||
| 911 | return isInBlockExp(pair->pair->value); | ||
| 912 | } | ||
| 913 | case id<VariablePair_t>(): { | ||
| 914 | return false; | ||
| 915 | } | ||
| 916 | case id<NormalPair_t>(): { | ||
| 917 | auto pair = static_cast<NormalPair_t*>(node); | ||
| 918 | return isInBlockExp(pair->value); | ||
| 919 | } | ||
| 920 | case id<MetaVariablePair_t>(): { | ||
| 921 | return false; | ||
| 922 | } | ||
| 923 | case id<MetaNormalPair_t>(): { | ||
| 924 | auto pair = static_cast<MetaNormalPair_t*>(node); | ||
| 925 | return isInBlockExp(pair->value); | ||
| 926 | } | ||
| 927 | case id<TableBlockIndent_t>(): { | ||
| 928 | return true; | ||
| 929 | } | ||
| 930 | case id<SpreadListExp_t>(): { | ||
| 931 | auto pair = static_cast<SpreadListExp_t*>(node); | ||
| 932 | return isInBlockExp(pair->exp); | ||
| 933 | } | ||
| 934 | default: | ||
| 935 | return false; | ||
| 936 | } | ||
| 937 | } | ||
| 938 | return false; | ||
| 939 | } | ||
| 940 | std::string Invoke_t::to_string(void* ud) const { | 974 | std::string Invoke_t::to_string(void* ud) const { |
| 941 | if (args.empty()) { | 975 | if (args.empty()) { |
| 942 | return "!"s; | 976 | return "!"s; |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 73ffc9a..2ea0a85 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -368,8 +368,8 @@ AST_END(Do, "do"sv) | |||
| 368 | 368 | ||
| 369 | AST_NODE(CatchBlock) | 369 | AST_NODE(CatchBlock) |
| 370 | ast_ptr<true, Variable_t> err; | 370 | ast_ptr<true, Variable_t> err; |
| 371 | ast_ptr<true, Block_t> body; | 371 | ast_ptr<true, Block_t> block; |
| 372 | AST_MEMBER(CatchBlock, &err, &body) | 372 | AST_MEMBER(CatchBlock, &err, &block) |
| 373 | AST_END(CatchBlock, "catch_block"sv) | 373 | AST_END(CatchBlock, "catch_block"sv) |
| 374 | 374 | ||
| 375 | AST_NODE(Try) | 375 | AST_NODE(Try) |
| @@ -759,6 +759,7 @@ AST_NODE(FunLit) | |||
| 759 | ast_sel<false, ExpListLow_t, DefaultValue_t> defaultReturn; | 759 | ast_sel<false, ExpListLow_t, DefaultValue_t> defaultReturn; |
| 760 | ast_ptr<true, FnArrow_t> arrow; | 760 | ast_ptr<true, FnArrow_t> arrow; |
| 761 | ast_ptr<false, Body_t> body; | 761 | ast_ptr<false, Body_t> body; |
| 762 | bool noRecursion = false; | ||
| 762 | AST_MEMBER(FunLit, &argsDef, &defaultReturn, &arrow, &body) | 763 | AST_MEMBER(FunLit, &argsDef, &defaultReturn, &arrow, &body) |
| 763 | AST_END(FunLit, "fun_lit"sv) | 764 | AST_END(FunLit, "fun_lit"sv) |
| 764 | 765 | ||
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index c991733..d416dbd 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.22.3"sv; | 78 | const std::string_view version = "0.23.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 { |
| @@ -95,13 +95,15 @@ CompileInfo::CompileInfo( | |||
| 95 | std::unique_ptr<GlobalVars>&& globals, | 95 | std::unique_ptr<GlobalVars>&& globals, |
| 96 | std::unique_ptr<Options>&& options, | 96 | std::unique_ptr<Options>&& options, |
| 97 | double parseTime, | 97 | double parseTime, |
| 98 | double compileTime) | 98 | double compileTime, |
| 99 | bool usedVar) | ||
| 99 | : codes(std::move(codes)) | 100 | : codes(std::move(codes)) |
| 100 | , error(std::move(error)) | 101 | , error(std::move(error)) |
| 101 | , globals(std::move(globals)) | 102 | , globals(std::move(globals)) |
| 102 | , options(std::move(options)) | 103 | , options(std::move(options)) |
| 103 | , parseTime(parseTime) | 104 | , parseTime(parseTime) |
| 104 | , compileTime(compileTime) { } | 105 | , compileTime(compileTime) |
| 106 | , usedVar(usedVar) { } | ||
| 105 | 107 | ||
| 106 | CompileInfo::CompileInfo(CompileInfo&& other) | 108 | CompileInfo::CompileInfo(CompileInfo&& other) |
| 107 | : codes(std::move(other.codes)) | 109 | : codes(std::move(other.codes)) |
| @@ -214,7 +216,8 @@ public: | |||
| 214 | } | 216 | } |
| 215 | str_list out; | 217 | str_list out; |
| 216 | pushScope(); | 218 | pushScope(); |
| 217 | _enableReturn.push(_info.moduleName.empty()); | 219 | _funcStates.push({false, _info.moduleName.empty()}); |
| 220 | _funcLevel = 1; | ||
| 218 | _gotoScopes.push(0); | 221 | _gotoScopes.push(0); |
| 219 | _gotoScope = 1; | 222 | _gotoScope = 1; |
| 220 | _varArgs.push({true, false}); | 223 | _varArgs.push({true, false}); |
| @@ -252,9 +255,8 @@ public: | |||
| 252 | if (config.lintGlobalVariable) { | 255 | if (config.lintGlobalVariable) { |
| 253 | globals = std::make_unique<GlobalVars>(); | 256 | globals = std::make_unique<GlobalVars>(); |
| 254 | for (const auto& var : _globals) { | 257 | for (const auto& var : _globals) { |
| 255 | int line, col; | 258 | auto [name, line, col, accessType] = var.second; |
| 256 | std::tie(line, col) = var.second; | 259 | globals->push_back({name, line + _config.lineOffset, col, accessType}); |
| 257 | globals->push_back({var.first, line + _config.lineOffset, col}); | ||
| 258 | } | 260 | } |
| 259 | std::sort(globals->begin(), globals->end(), [](const GlobalVar& varA, const GlobalVar& varB) { | 261 | std::sort(globals->begin(), globals->end(), [](const GlobalVar& varA, const GlobalVar& varB) { |
| 260 | if (varA.line < varB.line) { | 262 | if (varA.line < varB.line) { |
| @@ -286,7 +288,8 @@ public: | |||
| 286 | } | 288 | } |
| 287 | } | 289 | } |
| 288 | #endif // YUE_NO_MACRO | 290 | #endif // YUE_NO_MACRO |
| 289 | return {std::move(out.back()), std::nullopt, std::move(globals), std::move(options), parseTime, compileTime}; | 291 | bool usedVar = _varArgs.top().usedVar; |
| 292 | return {std::move(out.back()), std::nullopt, std::move(globals), std::move(options), parseTime, compileTime, usedVar}; | ||
| 290 | } catch (const CompileError& error) { | 293 | } catch (const CompileError& error) { |
| 291 | auto displayMessage = _info.errorMessage(error.what(), error.line, error.col, _config.lineOffset); | 294 | auto displayMessage = _info.errorMessage(error.what(), error.line, error.col, _config.lineOffset); |
| 292 | return { | 295 | return { |
| @@ -298,7 +301,7 @@ public: | |||
| 298 | displayMessage}, | 301 | displayMessage}, |
| 299 | std::move(globals), | 302 | std::move(globals), |
| 300 | std::move(options), | 303 | std::move(options), |
| 301 | parseTime, compileTime}; | 304 | parseTime, compileTime, false}; |
| 302 | } | 305 | } |
| 303 | } else { | 306 | } else { |
| 304 | const auto& error = _info.error.value(); | 307 | const auto& error = _info.error.value(); |
| @@ -312,7 +315,7 @@ public: | |||
| 312 | ""}, | 315 | ""}, |
| 313 | std::move(globals), | 316 | std::move(globals), |
| 314 | std::move(options), | 317 | std::move(options), |
| 315 | parseTime, compileTime}; | 318 | parseTime, compileTime, false}; |
| 316 | } | 319 | } |
| 317 | auto displayMessage = _info.errorMessage(error.msg, error.line, error.col, _config.lineOffset); | 320 | auto displayMessage = _info.errorMessage(error.msg, error.line, error.col, _config.lineOffset); |
| 318 | return { | 321 | return { |
| @@ -324,7 +327,7 @@ public: | |||
| 324 | displayMessage}, | 327 | displayMessage}, |
| 325 | std::move(globals), | 328 | std::move(globals), |
| 326 | std::move(options), | 329 | std::move(options), |
| 327 | parseTime, compileTime}; | 330 | parseTime, compileTime, false}; |
| 328 | } | 331 | } |
| 329 | } | 332 | } |
| 330 | 333 | ||
| @@ -341,7 +344,7 @@ public: | |||
| 341 | _varArgs = {}; | 344 | _varArgs = {}; |
| 342 | _withVars = {}; | 345 | _withVars = {}; |
| 343 | _continueVars = {}; | 346 | _continueVars = {}; |
| 344 | _enableReturn = {}; | 347 | _funcStates = {}; |
| 345 | #ifndef YUE_NO_MACRO | 348 | #ifndef YUE_NO_MACRO |
| 346 | if (_useModule) { | 349 | if (_useModule) { |
| 347 | _useModule = false; | 350 | _useModule = false; |
| @@ -375,16 +378,22 @@ private: | |||
| 375 | bool usedVar; | 378 | bool usedVar; |
| 376 | }; | 379 | }; |
| 377 | std::stack<VarArgState> _varArgs; | 380 | std::stack<VarArgState> _varArgs; |
| 378 | std::stack<bool> _enableReturn; | 381 | struct FuncState { |
| 382 | bool isAnon; | ||
| 383 | bool enableReturn; | ||
| 384 | }; | ||
| 385 | int _funcLevel = 0; | ||
| 386 | std::stack<FuncState> _funcStates; | ||
| 379 | std::stack<bool> _enableBreakLoop; | 387 | std::stack<bool> _enableBreakLoop; |
| 380 | std::stack<std::string> _withVars; | 388 | std::stack<std::string> _withVars; |
| 389 | str_list _rootDefs; | ||
| 381 | struct ContinueVar { | 390 | struct ContinueVar { |
| 382 | std::string var; | 391 | std::string var; |
| 383 | ast_ptr<false, ExpListAssign_t> condAssign; | 392 | ast_ptr<false, ExpListAssign_t> condAssign; |
| 384 | }; | 393 | }; |
| 385 | std::stack<ContinueVar> _continueVars; | 394 | std::stack<ContinueVar> _continueVars; |
| 386 | std::list<std::unique_ptr<input>> _codeCache; | 395 | std::list<std::unique_ptr<input>> _codeCache; |
| 387 | std::unordered_map<std::string, std::pair<int, int>> _globals; | 396 | std::unordered_map<std::string, std::tuple<std::string, int, int, AccessType>> _globals; |
| 388 | std::ostringstream _buf; | 397 | std::ostringstream _buf; |
| 389 | std::ostringstream _joinBuf; | 398 | std::ostringstream _joinBuf; |
| 390 | const std::string _newLine = "\n"; | 399 | const std::string _newLine = "\n"; |
| @@ -526,7 +535,7 @@ private: | |||
| 526 | return local; | 535 | return local; |
| 527 | } | 536 | } |
| 528 | 537 | ||
| 529 | bool isGlobal(const std::string& name) const { | 538 | bool isDeclaredAsGlobal(const std::string& name) const { |
| 530 | bool global = false; | 539 | bool global = false; |
| 531 | for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { | 540 | for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { |
| 532 | auto vars = it->vars.get(); | 541 | auto vars = it->vars.get(); |
| @@ -1020,7 +1029,7 @@ private: | |||
| 1020 | return type; | 1029 | return type; |
| 1021 | } | 1030 | } |
| 1022 | 1031 | ||
| 1023 | std::string singleVariableFrom(ChainValue_t* chainValue) { | 1032 | std::string singleVariableFrom(ChainValue_t* chainValue, AccessType accessType) { |
| 1024 | BLOCK_START | 1033 | BLOCK_START |
| 1025 | BREAK_IF(!chainValue); | 1034 | BREAK_IF(!chainValue); |
| 1026 | BREAK_IF(chainValue->items.size() != 1); | 1035 | BREAK_IF(chainValue->items.size() != 1); |
| @@ -1034,7 +1043,7 @@ private: | |||
| 1034 | } | 1043 | } |
| 1035 | BREAK_IF(!var); | 1044 | BREAK_IF(!var); |
| 1036 | str_list tmp; | 1045 | str_list tmp; |
| 1037 | transformCallable(callable, tmp); | 1046 | transformCallable(callable, tmp, accessType); |
| 1038 | return tmp.back(); | 1047 | return tmp.back(); |
| 1039 | BLOCK_END | 1048 | BLOCK_END |
| 1040 | return Empty; | 1049 | return Empty; |
| @@ -1064,7 +1073,7 @@ private: | |||
| 1064 | } | 1073 | } |
| 1065 | } | 1074 | } |
| 1066 | 1075 | ||
| 1067 | std::string singleVariableFrom(ast_node* expList, bool accessing) { | 1076 | std::string singleVariableFrom(ast_node* expList, AccessType accessType) { |
| 1068 | if (!ast_is<Exp_t, ExpList_t, Value_t>(expList)) return Empty; | 1077 | if (!ast_is<Exp_t, ExpList_t, Value_t>(expList)) return Empty; |
| 1069 | BLOCK_START | 1078 | BLOCK_START |
| 1070 | auto value = ast_cast<Value_t>(expList); | 1079 | auto value = ast_cast<Value_t>(expList); |
| @@ -1078,14 +1087,7 @@ private: | |||
| 1078 | auto callable = ast_cast<Callable_t>(chainValue->items.front()); | 1087 | auto callable = ast_cast<Callable_t>(chainValue->items.front()); |
| 1079 | BREAK_IF(!callable || !(callable->item.is<Variable_t>() || callable->get_by_path<SelfItem_t, Self_t>())); | 1088 | BREAK_IF(!callable || !(callable->item.is<Variable_t>() || callable->get_by_path<SelfItem_t, Self_t>())); |
| 1080 | str_list tmp; | 1089 | str_list tmp; |
| 1081 | if (accessing) { | 1090 | transformCallable(callable, tmp, accessType); |
| 1082 | transformCallable(callable, tmp); | ||
| 1083 | } else { | ||
| 1084 | bool lintGlobal = _config.lintGlobalVariable; | ||
| 1085 | _config.lintGlobalVariable = false; | ||
| 1086 | transformCallable(callable, tmp); | ||
| 1087 | _config.lintGlobalVariable = lintGlobal; | ||
| 1088 | } | ||
| 1089 | return tmp.back(); | 1091 | return tmp.back(); |
| 1090 | BLOCK_END | 1092 | BLOCK_END |
| 1091 | return Empty; | 1093 | return Empty; |
| @@ -1235,7 +1237,7 @@ private: | |||
| 1235 | return unary; | 1237 | return unary; |
| 1236 | } | 1238 | } |
| 1237 | auto value = static_cast<Value_t*>(unary->expos.back()); | 1239 | auto value = static_cast<Value_t*>(unary->expos.back()); |
| 1238 | auto varName = singleVariableFrom(value, false); | 1240 | auto varName = singleVariableFrom(value, AccessType::None); |
| 1239 | if (varName.empty() || !isLocal(varName)) { | 1241 | if (varName.empty() || !isLocal(varName)) { |
| 1240 | return unary; | 1242 | return unary; |
| 1241 | } | 1243 | } |
| @@ -1243,15 +1245,26 @@ private: | |||
| 1243 | return nullptr; | 1245 | return nullptr; |
| 1244 | } | 1246 | } |
| 1245 | 1247 | ||
| 1246 | void pushFunctionScope() { | 1248 | void pushFunctionScope(bool anonFunc) { |
| 1247 | _enableReturn.push(true); | 1249 | _funcLevel += anonFunc ? 0 : 1; |
| 1250 | _funcStates.push({anonFunc, true}); | ||
| 1248 | _enableBreakLoop.push(false); | 1251 | _enableBreakLoop.push(false); |
| 1249 | _gotoScopes.push(_gotoScope); | 1252 | _gotoScopes.push(_gotoScope); |
| 1250 | _gotoScope++; | 1253 | _gotoScope++; |
| 1251 | } | 1254 | } |
| 1252 | 1255 | ||
| 1256 | |||
| 1257 | void pushUserFunctionScope() { | ||
| 1258 | pushFunctionScope(false); | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | void pushAnonFunctionScope() { | ||
| 1262 | pushFunctionScope(true); | ||
| 1263 | } | ||
| 1264 | |||
| 1253 | void popFunctionScope() { | 1265 | void popFunctionScope() { |
| 1254 | _enableReturn.pop(); | 1266 | _funcLevel -= _funcStates.top().isAnon ? 0 : 1; |
| 1267 | _funcStates.pop(); | ||
| 1255 | _enableBreakLoop.pop(); | 1268 | _enableBreakLoop.pop(); |
| 1256 | _gotoScopes.pop(); | 1269 | _gotoScopes.pop(); |
| 1257 | } | 1270 | } |
| @@ -1276,12 +1289,16 @@ private: | |||
| 1276 | return !_varArgs.empty() && _varArgs.top().usedVar ? "end)(...)"s : "end)()"s; | 1289 | return !_varArgs.empty() && _varArgs.top().usedVar ? "end)(...)"s : "end)()"s; |
| 1277 | } | 1290 | } |
| 1278 | 1291 | ||
| 1279 | std::string globalVar(std::string_view var, ast_node* x) { | 1292 | std::string globalVar(std::string_view var, ast_node* x, AccessType accessType) { |
| 1280 | std::string str(var); | 1293 | std::string str(var); |
| 1281 | if (_config.lintGlobalVariable) { | 1294 | if (_config.lintGlobalVariable) { |
| 1282 | if (!isDefined(str)) { | 1295 | if (!isLocal(str)) { |
| 1283 | if (_globals.find(str) == _globals.end()) { | 1296 | auto key = str + ':' + std::to_string(x->m_begin.m_line) + ':' + std::to_string(x->m_begin.m_col); |
| 1284 | _globals[str] = {x->m_begin.m_line, x->m_begin.m_col}; | 1297 | if (_globals.find(key) == _globals.end()) { |
| 1298 | if (accessType == AccessType::Read && _funcLevel > 1) { | ||
| 1299 | accessType = AccessType::Capture; | ||
| 1300 | } | ||
| 1301 | _globals[key] = {str, x->m_begin.m_line, x->m_begin.m_col, accessType}; | ||
| 1285 | } | 1302 | } |
| 1286 | } | 1303 | } |
| 1287 | } | 1304 | } |
| @@ -1532,7 +1549,15 @@ private: | |||
| 1532 | case id<While_t>(): transformWhile(static_cast<While_t*>(value), out); break; | 1549 | case id<While_t>(): transformWhile(static_cast<While_t*>(value), out); break; |
| 1533 | case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Common); break; | 1550 | case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Common); break; |
| 1534 | case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Common); break; | 1551 | case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Common); break; |
| 1535 | case id<Comprehension_t>(): transformCompCommon(static_cast<Comprehension_t*>(value), out); break; | 1552 | case id<Comprehension_t>(): { |
| 1553 | auto comp = static_cast<Comprehension_t*>(value); | ||
| 1554 | if (comp->items.size() == 2 && ast_is<CompInner_t>(comp->items.back())) { | ||
| 1555 | transformCompCommon(comp, out); | ||
| 1556 | } else { | ||
| 1557 | specialSingleValue = false; | ||
| 1558 | } | ||
| 1559 | break; | ||
| 1560 | } | ||
| 1536 | default: specialSingleValue = false; break; | 1561 | default: specialSingleValue = false; break; |
| 1537 | } | 1562 | } |
| 1538 | if (specialSingleValue) { | 1563 | if (specialSingleValue) { |
| @@ -1567,7 +1592,7 @@ private: | |||
| 1567 | _config.lintGlobalVariable = false; | 1592 | _config.lintGlobalVariable = false; |
| 1568 | if (!assignment->action.is<Assign_t>()) return vars; | 1593 | if (!assignment->action.is<Assign_t>()) return vars; |
| 1569 | for (auto exp : assignment->expList->exprs.objects()) { | 1594 | for (auto exp : assignment->expList->exprs.objects()) { |
| 1570 | auto var = singleVariableFrom(exp, true); | 1595 | auto var = singleVariableFrom(exp, AccessType::Write); |
| 1571 | vars.push_back(var.empty() ? Empty : var); | 1596 | vars.push_back(var.empty() ? Empty : var); |
| 1572 | } | 1597 | } |
| 1573 | _config.lintGlobalVariable = lintGlobal; | 1598 | _config.lintGlobalVariable = lintGlobal; |
| @@ -1579,7 +1604,7 @@ private: | |||
| 1579 | bool lintGlobal = _config.lintGlobalVariable; | 1604 | bool lintGlobal = _config.lintGlobalVariable; |
| 1580 | _config.lintGlobalVariable = false; | 1605 | _config.lintGlobalVariable = false; |
| 1581 | for (auto exp : with->valueList->exprs.objects()) { | 1606 | for (auto exp : with->valueList->exprs.objects()) { |
| 1582 | auto var = singleVariableFrom(exp, true); | 1607 | auto var = singleVariableFrom(exp, AccessType::Write); |
| 1583 | vars.push_back(var.empty() ? Empty : var); | 1608 | vars.push_back(var.empty() ? Empty : var); |
| 1584 | } | 1609 | } |
| 1585 | _config.lintGlobalVariable = lintGlobal; | 1610 | _config.lintGlobalVariable = lintGlobal; |
| @@ -1867,7 +1892,7 @@ private: | |||
| 1867 | throw CompileError("right value missing"sv, values.front()); | 1892 | throw CompileError("right value missing"sv, values.front()); |
| 1868 | } | 1893 | } |
| 1869 | transformAssignItem(*vit, args); | 1894 | transformAssignItem(*vit, args); |
| 1870 | _buf << indent() << globalVar("setmetatable"sv, x) << '(' << join(args, ", "sv) << ')' << nll(x); | 1895 | _buf << indent() << globalVar("setmetatable"sv, x, AccessType::Read) << '(' << join(args, ", "sv) << ')' << nll(x); |
| 1871 | temp.push_back(clearBuf()); | 1896 | temp.push_back(clearBuf()); |
| 1872 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { | 1897 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { |
| 1873 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); | 1898 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); |
| @@ -1880,7 +1905,7 @@ private: | |||
| 1880 | tmpChain->items.push_back(toAst<Callable_t>(_withVars.top(), chainValue)); | 1905 | tmpChain->items.push_back(toAst<Callable_t>(_withVars.top(), chainValue)); |
| 1881 | } | 1906 | } |
| 1882 | } | 1907 | } |
| 1883 | auto varName = singleVariableFrom(tmpChain); | 1908 | auto varName = singleVariableFrom(tmpChain, AccessType::Write); |
| 1884 | bool isScoped = false; | 1909 | bool isScoped = false; |
| 1885 | if (varName.empty() || !isLocal(varName)) { | 1910 | if (varName.empty() || !isLocal(varName)) { |
| 1886 | isScoped = true; | 1911 | isScoped = true; |
| @@ -2433,7 +2458,7 @@ private: | |||
| 2433 | } | 2458 | } |
| 2434 | } else { | 2459 | } else { |
| 2435 | auto exp = static_cast<Exp_t*>(pair); | 2460 | auto exp = static_cast<Exp_t*>(pair); |
| 2436 | auto varName = singleVariableFrom(exp, false); | 2461 | auto varName = singleVariableFrom(exp, AccessType::None); |
| 2437 | if (varName == "_"sv) break; | 2462 | if (varName == "_"sv) break; |
| 2438 | auto chain = exp->new_ptr<ChainValue_t>(); | 2463 | auto chain = exp->new_ptr<ChainValue_t>(); |
| 2439 | auto indexItem = toAst<Exp_t>(std::to_string(index), exp); | 2464 | auto indexItem = toAst<Exp_t>(std::to_string(index), exp); |
| @@ -2514,7 +2539,7 @@ private: | |||
| 2514 | } else { | 2539 | } else { |
| 2515 | auto chain = exp->new_ptr<ChainValue_t>(); | 2540 | auto chain = exp->new_ptr<ChainValue_t>(); |
| 2516 | if (keyIndex) chain->items.push_back(keyIndex); | 2541 | if (keyIndex) chain->items.push_back(keyIndex); |
| 2517 | auto varName = singleVariableFrom(exp, false); | 2542 | auto varName = singleVariableFrom(exp, AccessType::None); |
| 2518 | pairs.push_back({exp, | 2543 | pairs.push_back({exp, |
| 2519 | varName, | 2544 | varName, |
| 2520 | chain, | 2545 | chain, |
| @@ -2801,7 +2826,7 @@ private: | |||
| 2801 | } | 2826 | } |
| 2802 | valueItems.push_back(*j); | 2827 | valueItems.push_back(*j); |
| 2803 | if (!varDefOnly && !subDestruct->values.empty() && !subMetaDestruct->values.empty()) { | 2828 | if (!varDefOnly && !subDestruct->values.empty() && !subMetaDestruct->values.empty()) { |
| 2804 | auto var = singleVariableFrom(*j, false); | 2829 | auto var = singleVariableFrom(*j, AccessType::None); |
| 2805 | if (var.empty() || !isLocal(var)) { | 2830 | if (var.empty() || !isLocal(var)) { |
| 2806 | auto objVar = getUnusedName("_obj_"sv); | 2831 | auto objVar = getUnusedName("_obj_"sv); |
| 2807 | addToScope(objVar); | 2832 | addToScope(objVar); |
| @@ -2818,7 +2843,7 @@ private: | |||
| 2818 | auto& destruct = destructs.emplace_back(); | 2843 | auto& destruct = destructs.emplace_back(); |
| 2819 | if (!varDefOnly) { | 2844 | if (!varDefOnly) { |
| 2820 | destruct.value = valueItems.back(); | 2845 | destruct.value = valueItems.back(); |
| 2821 | destruct.valueVar = singleVariableFrom(destruct.value, false); | 2846 | destruct.valueVar = singleVariableFrom(destruct.value, AccessType::None); |
| 2822 | } | 2847 | } |
| 2823 | auto simpleValue = tab->new_ptr<SimpleValue_t>(); | 2848 | auto simpleValue = tab->new_ptr<SimpleValue_t>(); |
| 2824 | simpleValue->value.set(tab); | 2849 | simpleValue->value.set(tab); |
| @@ -2893,7 +2918,7 @@ private: | |||
| 2893 | } | 2918 | } |
| 2894 | } | 2919 | } |
| 2895 | if (auto value = singleValueFrom(exp); !value || !value->item.is<String_t>()) { | 2920 | if (auto value = singleValueFrom(exp); !value || !value->item.is<String_t>()) { |
| 2896 | auto var = singleVariableFrom(exp, false); | 2921 | auto var = singleVariableFrom(exp, AccessType::None); |
| 2897 | if (var.empty()) { | 2922 | if (var.empty()) { |
| 2898 | if (!des.inlineAssignment) { | 2923 | if (!des.inlineAssignment) { |
| 2899 | des.inlineAssignment = x->new_ptr<ExpListAssign_t>(); | 2924 | des.inlineAssignment = x->new_ptr<ExpListAssign_t>(); |
| @@ -2986,7 +3011,7 @@ private: | |||
| 2986 | BLOCK_START | 3011 | BLOCK_START |
| 2987 | auto exp = ast_cast<Exp_t>(item); | 3012 | auto exp = ast_cast<Exp_t>(item); |
| 2988 | BREAK_IF(!exp); | 3013 | BREAK_IF(!exp); |
| 2989 | auto var = singleVariableFrom(exp, true); | 3014 | auto var = singleVariableFrom(exp, AccessType::Write); |
| 2990 | BREAK_IF(!var.empty()); | 3015 | BREAK_IF(!var.empty()); |
| 2991 | auto upVar = getUnusedName("_update_"sv); | 3016 | auto upVar = getUnusedName("_update_"sv); |
| 2992 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 3017 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
| @@ -3038,23 +3063,40 @@ private: | |||
| 3038 | auto assign = static_cast<Assign_t*>(action); | 3063 | auto assign = static_cast<Assign_t*>(action); |
| 3039 | auto defs = transformAssignDefs(expList, DefOp::Check); | 3064 | auto defs = transformAssignDefs(expList, DefOp::Check); |
| 3040 | bool oneLined = defs.size() == expList->exprs.objects().size(); | 3065 | bool oneLined = defs.size() == expList->exprs.objects().size(); |
| 3066 | bool nonRecursionFunLit = false; | ||
| 3041 | for (auto val : assign->values.objects()) { | 3067 | for (auto val : assign->values.objects()) { |
| 3042 | if (auto value = singleValueFrom(val)) { | 3068 | if (auto value = singleValueFrom(val)) { |
| 3043 | if (auto spValue = value->item.as<SimpleValue_t>()) { | 3069 | if (auto spValue = value->item.as<SimpleValue_t>()) { |
| 3044 | if (spValue->value.is<FunLit_t>()) { | 3070 | if (auto funLit = spValue->value.as<FunLit_t>()) { |
| 3045 | oneLined = false; | 3071 | if (funLit->noRecursion) { |
| 3072 | nonRecursionFunLit = true; | ||
| 3073 | } else { | ||
| 3074 | oneLined = false; | ||
| 3075 | } | ||
| 3046 | break; | 3076 | break; |
| 3047 | } | 3077 | } |
| 3048 | } | 3078 | } |
| 3049 | } | 3079 | } |
| 3050 | } | 3080 | } |
| 3051 | if (oneLined) { | 3081 | if (oneLined) { |
| 3052 | for (auto value : assign->values.objects()) { | ||
| 3053 | transformAssignItem(value, temp); | ||
| 3054 | } | ||
| 3055 | std::string preDefine = toLocalDecl(defs); | 3082 | std::string preDefine = toLocalDecl(defs); |
| 3056 | for (const auto& def : defs) { | 3083 | if (nonRecursionFunLit) { |
| 3057 | addToScope(def.first); | 3084 | for (const auto& def : defs) { |
| 3085 | addToScope(def.first); | ||
| 3086 | } | ||
| 3087 | for (auto value : assign->values.objects()) { | ||
| 3088 | transformAssignItem(value, temp); | ||
| 3089 | } | ||
| 3090 | } else { | ||
| 3091 | for (auto value : assign->values.objects()) { | ||
| 3092 | transformAssignItem(value, temp); | ||
| 3093 | } | ||
| 3094 | for (const auto& def : defs) { | ||
| 3095 | addToScope(def.first); | ||
| 3096 | } | ||
| 3097 | } | ||
| 3098 | for (ast_node* exp : expList->exprs.objects()) { | ||
| 3099 | singleVariableFrom(exp, AccessType::Write); | ||
| 3058 | } | 3100 | } |
| 3059 | if (preDefine.empty()) { | 3101 | if (preDefine.empty()) { |
| 3060 | transformExpList(expList, temp); | 3102 | transformExpList(expList, temp); |
| @@ -3069,6 +3111,9 @@ private: | |||
| 3069 | for (const auto& def : defs) { | 3111 | for (const auto& def : defs) { |
| 3070 | addToScope(def.first); | 3112 | addToScope(def.first); |
| 3071 | } | 3113 | } |
| 3114 | for (ast_node* exp : expList->exprs.objects()) { | ||
| 3115 | singleVariableFrom(exp, AccessType::Write); | ||
| 3116 | } | ||
| 3072 | transformExpList(expList, temp); | 3117 | transformExpList(expList, temp); |
| 3073 | std::string left = std::move(temp.back()); | 3118 | std::string left = std::move(temp.back()); |
| 3074 | temp.pop_back(); | 3119 | temp.pop_back(); |
| @@ -3122,7 +3167,18 @@ private: | |||
| 3122 | str_list temp; | 3167 | str_list temp; |
| 3123 | std::string* funcStart = nullptr; | 3168 | std::string* funcStart = nullptr; |
| 3124 | if (usage == ExpUsage::Closure) { | 3169 | if (usage == ExpUsage::Closure) { |
| 3125 | pushFunctionScope(); | 3170 | auto x = nodes.front(); |
| 3171 | auto newIf = x->new_ptr<If_t>(); | ||
| 3172 | newIf->type.set(toAst<IfType_t>(unless ? "unless"sv : "if"sv, x)); | ||
| 3173 | for (ast_node* node : nodes) { | ||
| 3174 | newIf->nodes.push_back(node); | ||
| 3175 | } | ||
| 3176 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
| 3177 | simpleValue->value.set(newIf); | ||
| 3178 | if (transformAsUpValueFunc(newExp(simpleValue, x), out)) { | ||
| 3179 | return; | ||
| 3180 | } | ||
| 3181 | pushAnonFunctionScope(); | ||
| 3126 | pushAnonVarArg(); | 3182 | pushAnonVarArg(); |
| 3127 | funcStart = &temp.emplace_back(); | 3183 | funcStart = &temp.emplace_back(); |
| 3128 | pushScope(); | 3184 | pushScope(); |
| @@ -3149,12 +3205,12 @@ private: | |||
| 3149 | if (asmt) { | 3205 | if (asmt) { |
| 3150 | auto exp = firstIfCond->condition.get(); | 3206 | auto exp = firstIfCond->condition.get(); |
| 3151 | auto x = exp; | 3207 | auto x = exp; |
| 3152 | auto var = singleVariableFrom(exp, false); | 3208 | auto var = singleVariableFrom(exp, AccessType::None); |
| 3153 | if (var.empty() || isGlobal(var)) { | 3209 | if (var.empty() || isDeclaredAsGlobal(var)) { |
| 3154 | storingValue = true; | 3210 | storingValue = true; |
| 3155 | auto desVar = getUnusedName("_des_"sv); | 3211 | auto desVar = getUnusedName("_des_"sv); |
| 3156 | if (asmt->assign->values.objects().size() == 1) { | 3212 | if (asmt->assign->values.objects().size() == 1) { |
| 3157 | auto var = singleVariableFrom(asmt->assign->values.objects().front(), true); | 3213 | auto var = singleVariableFrom(asmt->assign->values.objects().front(), AccessType::Read); |
| 3158 | if (!var.empty() && isLocal(var)) { | 3214 | if (!var.empty() && isLocal(var)) { |
| 3159 | desVar = var; | 3215 | desVar = var; |
| 3160 | storingValue = false; | 3216 | storingValue = false; |
| @@ -3300,7 +3356,7 @@ private: | |||
| 3300 | } | 3356 | } |
| 3301 | bool findPlaceHolder = false; | 3357 | bool findPlaceHolder = false; |
| 3302 | for (auto a : args->objects()) { | 3358 | for (auto a : args->objects()) { |
| 3303 | auto name = singleVariableFrom(a, false); | 3359 | auto name = singleVariableFrom(a, AccessType::None); |
| 3304 | if (name == "_"sv) { | 3360 | if (name == "_"sv) { |
| 3305 | if (!findPlaceHolder) { | 3361 | if (!findPlaceHolder) { |
| 3306 | args->swap(a, arg); | 3362 | args->swap(a, arg); |
| @@ -3396,7 +3452,7 @@ private: | |||
| 3396 | if (item.second->size() == 1) { | 3452 | if (item.second->size() == 1) { |
| 3397 | if (auto unary = singleUnaryExpFrom(node)) { | 3453 | if (auto unary = singleUnaryExpFrom(node)) { |
| 3398 | if (auto value = singleValueFrom(unary)) { | 3454 | if (auto value = singleValueFrom(unary)) { |
| 3399 | varName = singleVariableFrom(value, true); | 3455 | varName = singleVariableFrom(value, AccessType::Read); |
| 3400 | } | 3456 | } |
| 3401 | if (varName.empty()) { | 3457 | if (varName.empty()) { |
| 3402 | if (auto sval = static_cast<Value_t*>(unary->expos.front())->item.as<SimpleValue_t>()) { | 3458 | if (auto sval = static_cast<Value_t*>(unary->expos.front())->item.as<SimpleValue_t>()) { |
| @@ -3597,7 +3653,137 @@ private: | |||
| 3597 | } | 3653 | } |
| 3598 | } | 3654 | } |
| 3599 | 3655 | ||
| 3656 | std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Exp_t* exp, str_list* ensureArgList = nullptr) { | ||
| 3657 | if (_funcLevel <= 1) return std::nullopt; | ||
| 3658 | auto result = exp->traverse([&](ast_node* node) { | ||
| 3659 | switch (node->get_id()) { | ||
| 3660 | case id<MacroName_t>(): | ||
| 3661 | return traversal::Stop; | ||
| 3662 | } | ||
| 3663 | return traversal::Continue; | ||
| 3664 | }); | ||
| 3665 | if (result != traversal::Stop) { | ||
| 3666 | str_list args; | ||
| 3667 | bool upVarsAssignedOrCaptured = false; | ||
| 3668 | bool usedVar = false; | ||
| 3669 | ast_ptr<false, Statement_t> stmt; | ||
| 3670 | { | ||
| 3671 | str_list globals; | ||
| 3672 | for (const auto& scope : _scopes) { | ||
| 3673 | if (scope.vars) { | ||
| 3674 | for (const auto& var : *scope.vars) { | ||
| 3675 | globals.push_back(var.first); | ||
| 3676 | } | ||
| 3677 | } | ||
| 3678 | } | ||
| 3679 | auto returnNode = exp->new_ptr<Return_t>(); | ||
| 3680 | auto returnList = exp->new_ptr<ExpListLow_t>(); | ||
| 3681 | returnList->exprs.push_back(exp); | ||
| 3682 | returnNode->valueList.set(returnList); | ||
| 3683 | std::string codes; | ||
| 3684 | if (_withVars.empty()) { | ||
| 3685 | codes = YueFormat{}.toString(returnNode); | ||
| 3686 | stmt = exp->new_ptr<Statement_t>(); | ||
| 3687 | stmt->content.set(returnNode); | ||
| 3688 | } else { | ||
| 3689 | auto withNode = exp->new_ptr<With_t>(); | ||
| 3690 | withNode->valueList.set(toAst<ExpList_t>(_withVars.top(), exp)); | ||
| 3691 | auto returnStmt = exp->new_ptr<Statement_t>(); | ||
| 3692 | returnStmt->content.set(returnNode); | ||
| 3693 | withNode->body.set(returnStmt); | ||
| 3694 | codes = YueFormat{}.toString(withNode); | ||
| 3695 | stmt = exp->new_ptr<Statement_t>(); | ||
| 3696 | auto simpleValue = exp->new_ptr<SimpleValue_t>(); | ||
| 3697 | simpleValue->value.set(withNode); | ||
| 3698 | auto newExpr = newExp(simpleValue, exp); | ||
| 3699 | auto explist = exp->new_ptr<ExpList_t>(); | ||
| 3700 | explist->exprs.push_back(newExpr); | ||
| 3701 | auto expListAssign = exp->new_ptr<ExpListAssign_t>(); | ||
| 3702 | expListAssign->expList.set(explist); | ||
| 3703 | stmt->content.set(expListAssign); | ||
| 3704 | } | ||
| 3705 | if (!globals.empty()) { | ||
| 3706 | codes.insert(0, "global "s + join(globals, ","sv) + '\n'); | ||
| 3707 | } | ||
| 3708 | YueConfig config; | ||
| 3709 | config.lintGlobalVariable = true; | ||
| 3710 | auto result = YueCompiler{L, _luaOpen, true}.compile(codes, config); | ||
| 3711 | if (result.error) { | ||
| 3712 | YUEE("failed to compile dues to Yue formatter", exp); | ||
| 3713 | } | ||
| 3714 | usedVar = result.usedVar; | ||
| 3715 | if (result.globals) { | ||
| 3716 | for (const auto& global : *result.globals) { | ||
| 3717 | if (global.accessType != AccessType::Read) { | ||
| 3718 | upVarsAssignedOrCaptured = true; | ||
| 3719 | break; | ||
| 3720 | } else if (std::find(args.begin(), args.end(), global.name) == args.end()) { | ||
| 3721 | args.push_back(global.name); | ||
| 3722 | } | ||
| 3723 | } | ||
| 3724 | } | ||
| 3725 | } | ||
| 3726 | if (!upVarsAssignedOrCaptured) { | ||
| 3727 | auto x = exp; | ||
| 3728 | if (usedVar) { | ||
| 3729 | args.push_back("..."s); | ||
| 3730 | } | ||
| 3731 | if (ensureArgList) { | ||
| 3732 | std::unordered_set<std::string> vars; | ||
| 3733 | for (const auto& arg : args) { | ||
| 3734 | vars.insert(arg); | ||
| 3735 | } | ||
| 3736 | for (const auto& arg : *ensureArgList) { | ||
| 3737 | vars.erase(arg); | ||
| 3738 | } | ||
| 3739 | str_list finalArgs; | ||
| 3740 | for (const auto& arg : vars) { | ||
| 3741 | finalArgs.push_back(arg); | ||
| 3742 | } | ||
| 3743 | for (const auto& arg : *ensureArgList) { | ||
| 3744 | finalArgs.push_back(arg); | ||
| 3745 | } | ||
| 3746 | args = std::move(finalArgs); | ||
| 3747 | } | ||
| 3748 | auto funLit = toAst<FunLit_t>("("s + join(args, ","sv) + ")-> nil"s, x); | ||
| 3749 | funLit->body->content.set(stmt.get()); | ||
| 3750 | funLit->noRecursion = true; | ||
| 3751 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
| 3752 | simpleValue->value.set(funLit); | ||
| 3753 | auto funcName = getUnusedName("_anon_func_"sv); | ||
| 3754 | auto assignment = assignmentFrom(toAst<Exp_t>(funcName, x), newExp(simpleValue, x), x); | ||
| 3755 | auto scopes = std::move(_scopes); | ||
| 3756 | _scopes.push_back(std::move(scopes.front())); | ||
| 3757 | scopes.pop_front(); | ||
| 3758 | int offset = _indentOffset; | ||
| 3759 | _indentOffset = 0; | ||
| 3760 | transformAssignment(assignment, _rootDefs); | ||
| 3761 | scopes.push_front(std::move(_scopes.front())); | ||
| 3762 | _scopes = std::move(scopes); | ||
| 3763 | _indentOffset = offset; | ||
| 3764 | return std::make_pair(funcName, args); | ||
| 3765 | } | ||
| 3766 | } | ||
| 3767 | return std::nullopt; | ||
| 3768 | } | ||
| 3769 | |||
| 3770 | bool transformAsUpValueFunc(Exp_t* exp, str_list& out) { | ||
| 3771 | auto result = upValueFuncFrom(exp); | ||
| 3772 | if (result) { | ||
| 3773 | auto [funcName, args] = std::move(*result); | ||
| 3774 | auto newChainValue = toAst<ChainValue_t>(funcName + '(' + join(args, ","sv) + ')', exp); | ||
| 3775 | transformChainValue(newChainValue, out, ExpUsage::Closure); | ||
| 3776 | return true; | ||
| 3777 | } | ||
| 3778 | return false; | ||
| 3779 | } | ||
| 3780 | |||
| 3600 | void transformNilCoalesedExp(Exp_t* exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr, bool nilBranchOnly = false) { | 3781 | void transformNilCoalesedExp(Exp_t* exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr, bool nilBranchOnly = false) { |
| 3782 | if (usage == ExpUsage::Closure) { | ||
| 3783 | if (transformAsUpValueFunc(exp, out)) { | ||
| 3784 | return; | ||
| 3785 | } | ||
| 3786 | } | ||
| 3601 | auto x = exp; | 3787 | auto x = exp; |
| 3602 | str_list temp; | 3788 | str_list temp; |
| 3603 | auto left = exp->new_ptr<Exp_t>(); | 3789 | auto left = exp->new_ptr<Exp_t>(); |
| @@ -3620,12 +3806,12 @@ private: | |||
| 3620 | } | 3806 | } |
| 3621 | std::string* funcStart = nullptr; | 3807 | std::string* funcStart = nullptr; |
| 3622 | if (usage == ExpUsage::Closure) { | 3808 | if (usage == ExpUsage::Closure) { |
| 3623 | pushFunctionScope(); | 3809 | pushAnonFunctionScope(); |
| 3624 | pushAnonVarArg(); | 3810 | pushAnonVarArg(); |
| 3625 | funcStart = &temp.emplace_back(); | 3811 | funcStart = &temp.emplace_back(); |
| 3626 | pushScope(); | 3812 | pushScope(); |
| 3627 | } | 3813 | } |
| 3628 | auto objVar = singleVariableFrom(left, true); | 3814 | auto objVar = singleVariableFrom(left, AccessType::Read); |
| 3629 | auto prepareValue = [&](bool forAssignment = false) { | 3815 | auto prepareValue = [&](bool forAssignment = false) { |
| 3630 | if (objVar.empty() || !isLocal(objVar)) { | 3816 | if (objVar.empty() || !isLocal(objVar)) { |
| 3631 | if (forAssignment) { | 3817 | if (forAssignment) { |
| @@ -3724,21 +3910,25 @@ private: | |||
| 3724 | } | 3910 | } |
| 3725 | } | 3911 | } |
| 3726 | 3912 | ||
| 3727 | void transformCallable(Callable_t* callable, str_list& out, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) { | 3913 | void transformCallable(Callable_t* callable, str_list& out, AccessType accessType, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) { |
| 3728 | auto item = callable->item.get(); | 3914 | auto item = callable->item.get(); |
| 3729 | switch (item->get_id()) { | 3915 | switch (item->get_id()) { |
| 3730 | case id<Variable_t>(): { | 3916 | case id<Variable_t>(): { |
| 3731 | transformVariable(static_cast<Variable_t*>(item), out); | 3917 | transformVariable(static_cast<Variable_t*>(item), out); |
| 3732 | if (_config.lintGlobalVariable && !isLocal(out.back())) { | 3918 | if (_config.lintGlobalVariable && accessType != AccessType::None && !isLocal(out.back())) { |
| 3733 | if (_globals.find(out.back()) == _globals.end()) { | 3919 | auto key = out.back() + ':' + std::to_string(item->m_begin.m_line) + ':' + std::to_string(item->m_begin.m_col); |
| 3734 | _globals[out.back()] = {item->m_begin.m_line, item->m_begin.m_col}; | 3920 | if (_globals.find(key) == _globals.end()) { |
| 3921 | if (accessType == AccessType::Read && _funcLevel > 1) { | ||
| 3922 | accessType = AccessType::Capture; | ||
| 3923 | } | ||
| 3924 | _globals[key] = {out.back(), item->m_begin.m_line, item->m_begin.m_col, accessType}; | ||
| 3735 | } | 3925 | } |
| 3736 | } | 3926 | } |
| 3737 | break; | 3927 | break; |
| 3738 | } | 3928 | } |
| 3739 | case id<SelfItem_t>(): { | 3929 | case id<SelfItem_t>(): { |
| 3740 | transformSelfName(static_cast<SelfItem_t*>(item), out, invoke); | 3930 | transformSelfName(static_cast<SelfItem_t*>(item), out, invoke); |
| 3741 | globalVar("self"sv, item); | 3931 | globalVar("self"sv, item, accessType); |
| 3742 | break; | 3932 | break; |
| 3743 | } | 3933 | } |
| 3744 | case id<Parens_t>(): transformParens(static_cast<Parens_t*>(item), out); break; | 3934 | case id<Parens_t>(): transformParens(static_cast<Parens_t*>(item), out); break; |
| @@ -3777,7 +3967,7 @@ private: | |||
| 3777 | } | 3967 | } |
| 3778 | 3968 | ||
| 3779 | void transformFunLit(FunLit_t* funLit, str_list& out) { | 3969 | void transformFunLit(FunLit_t* funLit, str_list& out) { |
| 3780 | pushFunctionScope(); | 3970 | pushUserFunctionScope(); |
| 3781 | _varArgs.push({false, false}); | 3971 | _varArgs.push({false, false}); |
| 3782 | bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; | 3972 | bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; |
| 3783 | pushScope(); | 3973 | pushScope(); |
| @@ -3951,7 +4141,7 @@ private: | |||
| 3951 | } | 4141 | } |
| 3952 | bool findPlaceHolder = false; | 4142 | bool findPlaceHolder = false; |
| 3953 | for (auto a : args->objects()) { | 4143 | for (auto a : args->objects()) { |
| 3954 | auto name = singleVariableFrom(a, false); | 4144 | auto name = singleVariableFrom(a, AccessType::None); |
| 3955 | if (name == "_"sv) { | 4145 | if (name == "_"sv) { |
| 3956 | if (!findPlaceHolder) { | 4146 | if (!findPlaceHolder) { |
| 3957 | args->swap(a, arg); | 4147 | args->swap(a, arg); |
| @@ -4078,6 +4268,26 @@ private: | |||
| 4078 | argNames.push_back("..."s); | 4268 | argNames.push_back("..."s); |
| 4079 | auto newBody = x->new_ptr<Body_t>(); | 4269 | auto newBody = x->new_ptr<Body_t>(); |
| 4080 | newBody->content.set(followingBlock); | 4270 | newBody->content.set(followingBlock); |
| 4271 | { | ||
| 4272 | auto doNode = x->new_ptr<Do_t>(); | ||
| 4273 | doNode->body.set(newBody); | ||
| 4274 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
| 4275 | simpleValue->value.set(doNode); | ||
| 4276 | if (auto result = upValueFuncFrom(newExp(simpleValue, x), &argNames)) { | ||
| 4277 | auto [funcName, args] = std::move(*result); | ||
| 4278 | str_list finalArgs; | ||
| 4279 | for (const auto& arg : args) { | ||
| 4280 | if (std::find(argNames.begin(), argNames.end(), arg) == argNames.end()) { | ||
| 4281 | finalArgs.push_back(arg); | ||
| 4282 | } | ||
| 4283 | } | ||
| 4284 | newBlock->statements.push_back(toAst<Statement_t>(funcName + ' ' + join(finalArgs, ","sv), x)); | ||
| 4285 | auto sVal = singleValueFrom(static_cast<Statement_t*>(newBlock->statements.back())->content.to<ExpListAssign_t>()->expList); | ||
| 4286 | ast_to<InvokeArgs_t>(sVal->item.to<ChainValue_t>()->items.back())->args.dup(newInvoke->args); | ||
| 4287 | transformBlock(newBlock, out, usage, assignList, isRoot); | ||
| 4288 | return; | ||
| 4289 | } | ||
| 4290 | } | ||
| 4081 | auto funLit = toAst<FunLit_t>('(' + join(argNames, ","sv) + ")->"s, x); | 4291 | auto funLit = toAst<FunLit_t>('(' + join(argNames, ","sv) + ")->"s, x); |
| 4082 | funLit->body.set(newBody); | 4292 | funLit->body.set(newBody); |
| 4083 | auto newSimpleValue = x->new_ptr<SimpleValue_t>(); | 4293 | auto newSimpleValue = x->new_ptr<SimpleValue_t>(); |
| @@ -4323,6 +4533,13 @@ private: | |||
| 4323 | str_list temp; | 4533 | str_list temp; |
| 4324 | for (auto node : nodes) { | 4534 | for (auto node : nodes) { |
| 4325 | transformStatement(static_cast<Statement_t*>(node), temp); | 4535 | transformStatement(static_cast<Statement_t*>(node), temp); |
| 4536 | if (isRoot && !_rootDefs.empty()) { | ||
| 4537 | auto last = std::move(temp.back()); | ||
| 4538 | temp.pop_back(); | ||
| 4539 | temp.insert(temp.end(), _rootDefs.begin(), _rootDefs.end()); | ||
| 4540 | _rootDefs.clear(); | ||
| 4541 | temp.push_back(std::move(last)); | ||
| 4542 | } | ||
| 4326 | if (!temp.empty() && _parser.startWith<StatementSep_t>(temp.back())) { | 4543 | if (!temp.empty() && _parser.startWith<StatementSep_t>(temp.back())) { |
| 4327 | auto rit = ++temp.rbegin(); | 4544 | auto rit = ++temp.rbegin(); |
| 4328 | if (rit != temp.rend() && !rit->empty()) { | 4545 | if (rit != temp.rend() && !rit->empty()) { |
| @@ -4590,7 +4807,7 @@ private: | |||
| 4590 | #endif // YUE_NO_MACRO | 4807 | #endif // YUE_NO_MACRO |
| 4591 | 4808 | ||
| 4592 | void transformReturn(Return_t* returnNode, str_list& out) { | 4809 | void transformReturn(Return_t* returnNode, str_list& out) { |
| 4593 | if (!_enableReturn.top()) { | 4810 | if (!_funcStates.top().enableReturn) { |
| 4594 | ast_node* target = returnNode->valueList.get(); | 4811 | ast_node* target = returnNode->valueList.get(); |
| 4595 | if (!target) target = returnNode; | 4812 | if (!target) target = returnNode; |
| 4596 | throw CompileError("can not mix use of return and export statements in module scope"sv, target); | 4813 | throw CompileError("can not mix use of return and export statements in module scope"sv, target); |
| @@ -4909,7 +5126,14 @@ private: | |||
| 4909 | str_list temp; | 5126 | str_list temp; |
| 4910 | std::string* funcStart = nullptr; | 5127 | std::string* funcStart = nullptr; |
| 4911 | if (usage == ExpUsage::Closure) { | 5128 | if (usage == ExpUsage::Closure) { |
| 4912 | pushFunctionScope(); | 5129 | auto chainValue = x->new_ptr<ChainValue_t>(); |
| 5130 | for (ast_node* node : chainList) { | ||
| 5131 | chainValue->items.push_back(node); | ||
| 5132 | } | ||
| 5133 | if (transformAsUpValueFunc(newExp(chainValue, x), out)) { | ||
| 5134 | return true; | ||
| 5135 | } | ||
| 5136 | pushAnonFunctionScope(); | ||
| 4913 | pushAnonVarArg(); | 5137 | pushAnonVarArg(); |
| 4914 | funcStart = &temp.emplace_back(); | 5138 | funcStart = &temp.emplace_back(); |
| 4915 | pushScope(); | 5139 | pushScope(); |
| @@ -4940,7 +5164,7 @@ private: | |||
| 4940 | break; | 5164 | break; |
| 4941 | } | 5165 | } |
| 4942 | BLOCK_END | 5166 | BLOCK_END |
| 4943 | auto objVar = singleVariableFrom(partOne); | 5167 | auto objVar = singleVariableFrom(partOne, AccessType::Read); |
| 4944 | bool isScoped = false; | 5168 | bool isScoped = false; |
| 4945 | if (objVar.empty() || !isLocal(objVar)) { | 5169 | if (objVar.empty() || !isLocal(objVar)) { |
| 4946 | switch (usage) { | 5170 | switch (usage) { |
| @@ -4965,7 +5189,7 @@ private: | |||
| 4965 | } | 5189 | } |
| 4966 | chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x)); | 5190 | chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x)); |
| 4967 | } | 5191 | } |
| 4968 | auto newObj = singleVariableFrom(chainValue); | 5192 | auto newObj = singleVariableFrom(chainValue, AccessType::Read); |
| 4969 | if (!newObj.empty()) { | 5193 | if (!newObj.empty()) { |
| 4970 | objVar = newObj; | 5194 | objVar = newObj; |
| 4971 | } else { | 5195 | } else { |
| @@ -5085,7 +5309,7 @@ private: | |||
| 5085 | pushScope(); | 5309 | pushScope(); |
| 5086 | break; | 5310 | break; |
| 5087 | case ExpUsage::Closure: | 5311 | case ExpUsage::Closure: |
| 5088 | pushFunctionScope(); | 5312 | pushAnonFunctionScope(); |
| 5089 | pushAnonVarArg(); | 5313 | pushAnonVarArg(); |
| 5090 | funcStart = &temp.emplace_back(); | 5314 | funcStart = &temp.emplace_back(); |
| 5091 | pushScope(); | 5315 | pushScope(); |
| @@ -5222,7 +5446,14 @@ private: | |||
| 5222 | str_list temp; | 5446 | str_list temp; |
| 5223 | std::string* funcStart = nullptr; | 5447 | std::string* funcStart = nullptr; |
| 5224 | if (usage == ExpUsage::Closure) { | 5448 | if (usage == ExpUsage::Closure) { |
| 5225 | pushFunctionScope(); | 5449 | auto chainValue = x->new_ptr<ChainValue_t>(); |
| 5450 | for (ast_node* node : chainList) { | ||
| 5451 | chainValue->items.push_back(node); | ||
| 5452 | } | ||
| 5453 | if (transformAsUpValueFunc(newExp(chainValue, x), out)) { | ||
| 5454 | return true; | ||
| 5455 | } | ||
| 5456 | pushAnonFunctionScope(); | ||
| 5226 | pushAnonVarArg(); | 5457 | pushAnonVarArg(); |
| 5227 | funcStart = &temp.emplace_back(); | 5458 | funcStart = &temp.emplace_back(); |
| 5228 | pushScope(); | 5459 | pushScope(); |
| @@ -5349,12 +5580,6 @@ private: | |||
| 5349 | for (auto it = chainList.begin(); it != chainList.end(); ++it) { | 5580 | for (auto it = chainList.begin(); it != chainList.end(); ++it) { |
| 5350 | auto item = *it; | 5581 | auto item = *it; |
| 5351 | switch (item->get_id()) { | 5582 | switch (item->get_id()) { |
| 5352 | case id<Invoke_t>(): | ||
| 5353 | transformInvoke(static_cast<Invoke_t*>(item), temp); | ||
| 5354 | break; | ||
| 5355 | case id<DotChainItem_t>(): | ||
| 5356 | transformDotChainItem(static_cast<DotChainItem_t*>(item), temp); | ||
| 5357 | break; | ||
| 5358 | case id<ColonChainItem_t>(): { | 5583 | case id<ColonChainItem_t>(): { |
| 5359 | auto colonItem = static_cast<ColonChainItem_t*>(item); | 5584 | auto colonItem = static_cast<ColonChainItem_t*>(item); |
| 5360 | auto current = it; | 5585 | auto current = it; |
| @@ -5390,7 +5615,7 @@ private: | |||
| 5390 | chainValue->items.push_back(*i); | 5615 | chainValue->items.push_back(*i); |
| 5391 | } | 5616 | } |
| 5392 | auto exp = newExp(chainValue, x); | 5617 | auto exp = newExp(chainValue, x); |
| 5393 | callVar = singleVariableFrom(exp, true); | 5618 | callVar = singleVariableFrom(exp, AccessType::Read); |
| 5394 | if (callVar.empty() || !isLocal(callVar)) { | 5619 | if (callVar.empty() || !isLocal(callVar)) { |
| 5395 | callVar = getUnusedName("_call_"s); | 5620 | callVar = getUnusedName("_call_"s); |
| 5396 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 5621 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| @@ -5413,10 +5638,27 @@ private: | |||
| 5413 | } | 5638 | } |
| 5414 | chainValue->items.push_back(toAst<Exp_t>('\"' + name + '\"', x)); | 5639 | chainValue->items.push_back(toAst<Exp_t>('\"' + name + '\"', x)); |
| 5415 | if (auto invoke = ast_cast<Invoke_t>(followItem)) { | 5640 | if (auto invoke = ast_cast<Invoke_t>(followItem)) { |
| 5416 | invoke->args.push_front(toAst<Exp_t>(callVar, x)); | 5641 | auto newInvoke = x->new_ptr<Invoke_t>(); |
| 5642 | newInvoke->args.push_back(toAst<Exp_t>(callVar, x)); | ||
| 5643 | newInvoke->args.dup(invoke->args); | ||
| 5644 | chainValue->items.push_back(newInvoke); | ||
| 5645 | ++next; | ||
| 5417 | } else { | 5646 | } else { |
| 5418 | auto invokeArgs = static_cast<InvokeArgs_t*>(followItem); | 5647 | auto invokeArgs = static_cast<InvokeArgs_t*>(followItem); |
| 5419 | invokeArgs->args.push_front(toAst<Exp_t>(callVar, x)); | 5648 | auto newInvokeArgs = x->new_ptr<InvokeArgs_t>(); |
| 5649 | newInvokeArgs->args.push_back(toAst<Exp_t>(callVar, x)); | ||
| 5650 | newInvokeArgs->args.dup(invokeArgs->args); | ||
| 5651 | chainValue->items.push_back(newInvokeArgs); | ||
| 5652 | ++next; | ||
| 5653 | if (next != chainList.end()) { | ||
| 5654 | auto paren = x->new_ptr<Parens_t>(); | ||
| 5655 | paren->expr.set(newExp(chainValue, x)); | ||
| 5656 | auto ncallable = x->new_ptr<Callable_t>(); | ||
| 5657 | ncallable->item.set(paren); | ||
| 5658 | auto nchainValue = x->new_ptr<ChainValue_t>(); | ||
| 5659 | nchainValue->items.push_back(ncallable); | ||
| 5660 | chainValue.set(nchainValue); | ||
| 5661 | } | ||
| 5420 | } | 5662 | } |
| 5421 | for (auto i = next; i != chainList.end(); ++i) { | 5663 | for (auto i = next; i != chainList.end(); ++i) { |
| 5422 | chainValue->items.push_back(*i); | 5664 | chainValue->items.push_back(*i); |
| @@ -5447,6 +5689,15 @@ private: | |||
| 5447 | } else { | 5689 | } else { |
| 5448 | auto body = x->new_ptr<Body_t>(); | 5690 | auto body = x->new_ptr<Body_t>(); |
| 5449 | body->content.set(block); | 5691 | body->content.set(block); |
| 5692 | { | ||
| 5693 | auto doNode = x->new_ptr<Do_t>(); | ||
| 5694 | doNode->body.set(body); | ||
| 5695 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
| 5696 | simpleValue->value.set(doNode); | ||
| 5697 | if (transformAsUpValueFunc(newExp(simpleValue, x), out)) { | ||
| 5698 | return; | ||
| 5699 | } | ||
| 5700 | } | ||
| 5450 | auto funLit = toAst<FunLit_t>("->"sv, x); | 5701 | auto funLit = toAst<FunLit_t>("->"sv, x); |
| 5451 | funLit->body.set(body); | 5702 | funLit->body.set(body); |
| 5452 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 5703 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
| @@ -5464,9 +5715,21 @@ private: | |||
| 5464 | } | 5715 | } |
| 5465 | return; | 5716 | return; |
| 5466 | } | 5717 | } |
| 5467 | transformColonChainItem(colonItem, temp); | ||
| 5468 | break; | ||
| 5469 | } | 5718 | } |
| 5719 | } | ||
| 5720 | } | ||
| 5721 | for (auto it = chainList.begin(); it != chainList.end(); ++it) { | ||
| 5722 | auto item = *it; | ||
| 5723 | switch (item->get_id()) { | ||
| 5724 | case id<Invoke_t>(): | ||
| 5725 | transformInvoke(static_cast<Invoke_t*>(item), temp); | ||
| 5726 | break; | ||
| 5727 | case id<DotChainItem_t>(): | ||
| 5728 | transformDotChainItem(static_cast<DotChainItem_t*>(item), temp); | ||
| 5729 | break; | ||
| 5730 | case id<ColonChainItem_t>(): | ||
| 5731 | transformColonChainItem(static_cast<ColonChainItem_t*>(item), temp); | ||
| 5732 | break; | ||
| 5470 | case id<Slice_t>(): | 5733 | case id<Slice_t>(): |
| 5471 | transformSlice(static_cast<Slice_t*>(item), temp); | 5734 | transformSlice(static_cast<Slice_t*>(item), temp); |
| 5472 | break; | 5735 | break; |
| @@ -5478,7 +5741,7 @@ private: | |||
| 5478 | if (ast_is<Invoke_t, InvokeArgs_t>(followItem)) { | 5741 | if (ast_is<Invoke_t, InvokeArgs_t>(followItem)) { |
| 5479 | invoke.set(followItem); | 5742 | invoke.set(followItem); |
| 5480 | } | 5743 | } |
| 5481 | transformCallable(static_cast<Callable_t*>(item), temp, invoke); | 5744 | transformCallable(static_cast<Callable_t*>(item), temp, AccessType::Read, invoke); |
| 5482 | break; | 5745 | break; |
| 5483 | } | 5746 | } |
| 5484 | case id<String_t>(): | 5747 | case id<String_t>(): |
| @@ -5969,7 +6232,7 @@ private: | |||
| 5969 | std::string varName; | 6232 | std::string varName; |
| 5970 | if (unary_exp->ops.empty() && unary_exp->expos.size() == 1) { | 6233 | if (unary_exp->ops.empty() && unary_exp->expos.size() == 1) { |
| 5971 | auto value = static_cast<Value_t*>(unary_exp->expos.back()); | 6234 | auto value = static_cast<Value_t*>(unary_exp->expos.back()); |
| 5972 | varName = singleVariableFrom(value, false); | 6235 | varName = singleVariableFrom(value, AccessType::None); |
| 5973 | if (!isLocal(varName)) { | 6236 | if (!isLocal(varName)) { |
| 5974 | varName.clear(); | 6237 | varName.clear(); |
| 5975 | } | 6238 | } |
| @@ -6018,7 +6281,7 @@ private: | |||
| 6018 | BLOCK_START | 6281 | BLOCK_START |
| 6019 | BREAK_IF(discrete); | 6282 | BREAK_IF(discrete); |
| 6020 | str_list temp; | 6283 | str_list temp; |
| 6021 | auto checkVar = singleVariableFrom(inExp, false); | 6284 | auto checkVar = singleVariableFrom(inExp, AccessType::None); |
| 6022 | if (usage == ExpUsage::Assignment) { | 6285 | if (usage == ExpUsage::Assignment) { |
| 6023 | auto block = x->new_ptr<Block_t>(); | 6286 | auto block = x->new_ptr<Block_t>(); |
| 6024 | if (checkVar.empty() || !isLocal(checkVar)) { | 6287 | if (checkVar.empty() || !isLocal(checkVar)) { |
| @@ -6091,7 +6354,11 @@ private: | |||
| 6091 | if (usage == ExpUsage::Return) { | 6354 | if (usage == ExpUsage::Return) { |
| 6092 | arrayCheck(!unary_exp->inExp->not_); | 6355 | arrayCheck(!unary_exp->inExp->not_); |
| 6093 | } else { | 6356 | } else { |
| 6094 | pushFunctionScope(); | 6357 | if (transformAsUpValueFunc(newExp(unary_exp, unary_exp), out)) { |
| 6358 | out.back() = "(#"s + checkVar + " > 0 and "s + out.back() + ')'; | ||
| 6359 | return; | ||
| 6360 | } | ||
| 6361 | pushAnonFunctionScope(); | ||
| 6095 | pushAnonVarArg(); | 6362 | pushAnonVarArg(); |
| 6096 | pushScope(); | 6363 | pushScope(); |
| 6097 | arrayCheck(true); | 6364 | arrayCheck(true); |
| @@ -6106,7 +6373,10 @@ private: | |||
| 6106 | } | 6373 | } |
| 6107 | } else { | 6374 | } else { |
| 6108 | if (usage == ExpUsage::Closure) { | 6375 | if (usage == ExpUsage::Closure) { |
| 6109 | pushFunctionScope(); | 6376 | if (transformAsUpValueFunc(newExp(unary_exp, unary_exp), out)) { |
| 6377 | return; | ||
| 6378 | } | ||
| 6379 | pushAnonFunctionScope(); | ||
| 6110 | pushAnonVarArg(); | 6380 | pushAnonVarArg(); |
| 6111 | pushScope(); | 6381 | pushScope(); |
| 6112 | } | 6382 | } |
| @@ -6160,7 +6430,10 @@ private: | |||
| 6160 | if (varName.empty()) { | 6430 | if (varName.empty()) { |
| 6161 | str_list temp; | 6431 | str_list temp; |
| 6162 | if (usage == ExpUsage::Closure) { | 6432 | if (usage == ExpUsage::Closure) { |
| 6163 | pushFunctionScope(); | 6433 | if (transformAsUpValueFunc(newExp(unary_exp, unary_exp), out)) { |
| 6434 | return; | ||
| 6435 | } | ||
| 6436 | pushAnonFunctionScope(); | ||
| 6164 | pushAnonVarArg(); | 6437 | pushAnonVarArg(); |
| 6165 | pushScope(); | 6438 | pushScope(); |
| 6166 | } else if (usage == ExpUsage::Assignment) { | 6439 | } else if (usage == ExpUsage::Assignment) { |
| @@ -6302,11 +6575,21 @@ private: | |||
| 6302 | void transformSpreadTable(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 6575 | void transformSpreadTable(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| 6303 | auto x = values.front(); | 6576 | auto x = values.front(); |
| 6304 | switch (usage) { | 6577 | switch (usage) { |
| 6305 | case ExpUsage::Closure: | 6578 | case ExpUsage::Closure: { |
| 6306 | pushFunctionScope(); | 6579 | auto tableLit = x->new_ptr<TableLit_t>(); |
| 6580 | for (ast_node* value : values) { | ||
| 6581 | tableLit->values.push_back(value); | ||
| 6582 | } | ||
| 6583 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
| 6584 | simpleValue->value.set(tableLit); | ||
| 6585 | if (transformAsUpValueFunc(newExp(simpleValue, x), out)) { | ||
| 6586 | return; | ||
| 6587 | } | ||
| 6588 | pushAnonFunctionScope(); | ||
| 6307 | pushAnonVarArg(); | 6589 | pushAnonVarArg(); |
| 6308 | pushScope(); | 6590 | pushScope(); |
| 6309 | break; | 6591 | break; |
| 6592 | } | ||
| 6310 | case ExpUsage::Assignment: | 6593 | case ExpUsage::Assignment: |
| 6311 | pushScope(); | 6594 | pushScope(); |
| 6312 | break; | 6595 | break; |
| @@ -6336,7 +6619,7 @@ private: | |||
| 6336 | std::string indexVar = getUnusedName("_idx_"sv); | 6619 | std::string indexVar = getUnusedName("_idx_"sv); |
| 6337 | std::string keyVar = getUnusedName("_key_"sv); | 6620 | std::string keyVar = getUnusedName("_key_"sv); |
| 6338 | std::string valueVar = getUnusedName("_value_"sv); | 6621 | std::string valueVar = getUnusedName("_value_"sv); |
| 6339 | auto objVar = singleVariableFrom(spread->exp, true); | 6622 | auto objVar = singleVariableFrom(spread->exp, AccessType::Read); |
| 6340 | if (objVar.empty()) { | 6623 | if (objVar.empty()) { |
| 6341 | objVar = getUnusedName("_obj_"); | 6624 | objVar = getUnusedName("_obj_"); |
| 6342 | auto assignment = toAst<ExpListAssign_t>(objVar + "=nil"s, item); | 6625 | auto assignment = toAst<ExpListAssign_t>(objVar + "=nil"s, item); |
| @@ -6360,7 +6643,7 @@ private: | |||
| 6360 | auto spread = static_cast<SpreadListExp_t*>(item); | 6643 | auto spread = static_cast<SpreadListExp_t*>(item); |
| 6361 | std::string indexVar = getUnusedName("_idx_"sv); | 6644 | std::string indexVar = getUnusedName("_idx_"sv); |
| 6362 | std::string valueVar = getUnusedName("_value_"sv); | 6645 | std::string valueVar = getUnusedName("_value_"sv); |
| 6363 | auto objVar = singleVariableFrom(spread->exp, true); | 6646 | auto objVar = singleVariableFrom(spread->exp, AccessType::Read); |
| 6364 | if (objVar.empty()) { | 6647 | if (objVar.empty()) { |
| 6365 | objVar = getUnusedName("_obj_"); | 6648 | objVar = getUnusedName("_obj_"); |
| 6366 | auto assignment = toAst<ExpListAssign_t>(objVar + "=nil"s, item); | 6649 | auto assignment = toAst<ExpListAssign_t>(objVar + "=nil"s, item); |
| @@ -6704,7 +6987,7 @@ private: | |||
| 6704 | decIndentOffset(); | 6987 | decIndentOffset(); |
| 6705 | out.back() += (indent() + '}'); | 6988 | out.back() += (indent() + '}'); |
| 6706 | } else { | 6989 | } else { |
| 6707 | auto tabStr = globalVar("setmetatable"sv, x); | 6990 | auto tabStr = globalVar("setmetatable"sv, x, AccessType::Read); |
| 6708 | tabStr += '('; | 6991 | tabStr += '('; |
| 6709 | if (temp.empty()) { | 6992 | if (temp.empty()) { |
| 6710 | decIndentOffset(); | 6993 | decIndentOffset(); |
| @@ -6825,20 +7108,26 @@ private: | |||
| 6825 | if (!def || def->defVal) { | 7108 | if (!def || def->defVal) { |
| 6826 | throw CompileError("invalid comprehension expression", comp->items.front()); | 7109 | throw CompileError("invalid comprehension expression", comp->items.front()); |
| 6827 | } | 7110 | } |
| 6828 | auto value = def->item.get(); | ||
| 6829 | auto compInner = static_cast<CompInner_t*>(comp->items.back()); | ||
| 6830 | switch (usage) { | 7111 | switch (usage) { |
| 6831 | case ExpUsage::Closure: | 7112 | case ExpUsage::Closure: { |
| 6832 | pushFunctionScope(); | 7113 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
| 7114 | simpleValue->value.set(comp); | ||
| 7115 | if (transformAsUpValueFunc(newExp(simpleValue, x), out)) { | ||
| 7116 | return; | ||
| 7117 | } | ||
| 7118 | pushAnonFunctionScope(); | ||
| 6833 | pushAnonVarArg(); | 7119 | pushAnonVarArg(); |
| 6834 | pushScope(); | 7120 | pushScope(); |
| 6835 | break; | 7121 | break; |
| 7122 | } | ||
| 6836 | case ExpUsage::Assignment: | 7123 | case ExpUsage::Assignment: |
| 6837 | pushScope(); | 7124 | pushScope(); |
| 6838 | break; | 7125 | break; |
| 6839 | default: | 7126 | default: |
| 6840 | break; | 7127 | break; |
| 6841 | } | 7128 | } |
| 7129 | auto value = def->item.get(); | ||
| 7130 | auto compInner = static_cast<CompInner_t*>(comp->items.back()); | ||
| 6842 | str_list temp; | 7131 | str_list temp; |
| 6843 | std::string accumVar = getUnusedName("_accum_"sv); | 7132 | std::string accumVar = getUnusedName("_accum_"sv); |
| 6844 | std::string lenVar = getUnusedName("_len_"sv); | 7133 | std::string lenVar = getUnusedName("_len_"sv); |
| @@ -6954,7 +7243,7 @@ private: | |||
| 6954 | switch (loopTarget->get_id()) { | 7243 | switch (loopTarget->get_id()) { |
| 6955 | case id<StarExp_t>(): { | 7244 | case id<StarExp_t>(): { |
| 6956 | auto star_exp = static_cast<StarExp_t*>(loopTarget); | 7245 | auto star_exp = static_cast<StarExp_t*>(loopTarget); |
| 6957 | auto listVar = singleVariableFrom(star_exp->value, true); | 7246 | auto listVar = singleVariableFrom(star_exp->value, AccessType::Read); |
| 6958 | if (!isLocal(listVar)) listVar.clear(); | 7247 | if (!isLocal(listVar)) listVar.clear(); |
| 6959 | auto indexVar = getUnusedName("_index_"sv); | 7248 | auto indexVar = getUnusedName("_index_"sv); |
| 6960 | varAfter.push_back(indexVar); | 7249 | varAfter.push_back(indexVar); |
| @@ -7430,8 +7719,13 @@ private: | |||
| 7430 | } | 7719 | } |
| 7431 | 7720 | ||
| 7432 | void transformForClosure(For_t* forNode, str_list& out) { | 7721 | void transformForClosure(For_t* forNode, str_list& out) { |
| 7722 | auto simpleValue = forNode->new_ptr<SimpleValue_t>(); | ||
| 7723 | simpleValue->value.set(forNode); | ||
| 7724 | if (transformAsUpValueFunc(newExp(simpleValue, forNode), out)) { | ||
| 7725 | return; | ||
| 7726 | } | ||
| 7433 | str_list temp; | 7727 | str_list temp; |
| 7434 | pushFunctionScope(); | 7728 | pushAnonFunctionScope(); |
| 7435 | pushAnonVarArg(); | 7729 | pushAnonVarArg(); |
| 7436 | std::string& funcStart = temp.emplace_back(); | 7730 | std::string& funcStart = temp.emplace_back(); |
| 7437 | pushScope(); | 7731 | pushScope(); |
| @@ -7519,8 +7813,13 @@ private: | |||
| 7519 | } | 7813 | } |
| 7520 | 7814 | ||
| 7521 | void transformForEachClosure(ForEach_t* forEach, str_list& out) { | 7815 | void transformForEachClosure(ForEach_t* forEach, str_list& out) { |
| 7816 | auto simpleValue = forEach->new_ptr<SimpleValue_t>(); | ||
| 7817 | simpleValue->value.set(forEach); | ||
| 7818 | if (transformAsUpValueFunc(newExp(simpleValue, forEach), out)) { | ||
| 7819 | return; | ||
| 7820 | } | ||
| 7522 | str_list temp; | 7821 | str_list temp; |
| 7523 | pushFunctionScope(); | 7822 | pushAnonFunctionScope(); |
| 7524 | pushAnonVarArg(); | 7823 | pushAnonVarArg(); |
| 7525 | std::string& funcStart = temp.emplace_back(); | 7824 | std::string& funcStart = temp.emplace_back(); |
| 7526 | pushScope(); | 7825 | pushScope(); |
| @@ -7569,8 +7868,9 @@ private: | |||
| 7569 | out.push_back(name + " = "s + name); | 7868 | out.push_back(name + " = "s + name); |
| 7570 | } | 7869 | } |
| 7571 | if (_config.lintGlobalVariable && !isLocal(name)) { | 7870 | if (_config.lintGlobalVariable && !isLocal(name)) { |
| 7572 | if (_globals.find(name) == _globals.end()) { | 7871 | auto key = name + ':' + std::to_string(pair->name->m_begin.m_line) + ':' + std::to_string(pair->name->m_begin.m_col); |
| 7573 | _globals[name] = {pair->name->m_begin.m_line, pair->name->m_begin.m_col}; | 7872 | if (_globals.find(key) != _globals.end()) { |
| 7873 | _globals[key] = {name, pair->name->m_begin.m_line, pair->name->m_begin.m_col, _funcLevel > 1 ? AccessType::Capture : AccessType::Read}; | ||
| 7574 | } | 7874 | } |
| 7575 | } | 7875 | } |
| 7576 | } | 7876 | } |
| @@ -7675,7 +7975,7 @@ private: | |||
| 7675 | } | 7975 | } |
| 7676 | case id<Exp_t>(): { | 7976 | case id<Exp_t>(): { |
| 7677 | transformExp(static_cast<Exp_t*>(content), temp, ExpUsage::Closure); | 7977 | transformExp(static_cast<Exp_t*>(content), temp, ExpUsage::Closure); |
| 7678 | temp.back() = globalVar("tostring"sv, content) + '(' + temp.back() + ')'; | 7978 | temp.back() = globalVar("tostring"sv, content, AccessType::Read) + '(' + temp.back() + ')'; |
| 7679 | break; | 7979 | break; |
| 7680 | } | 7980 | } |
| 7681 | default: YUEE("AST node mismatch", content); break; | 7981 | default: YUEE("AST node mismatch", content); break; |
| @@ -7708,8 +8008,13 @@ private: | |||
| 7708 | } | 8008 | } |
| 7709 | 8009 | ||
| 7710 | void transformClassDeclClosure(ClassDecl_t* classDecl, str_list& out) { | 8010 | void transformClassDeclClosure(ClassDecl_t* classDecl, str_list& out) { |
| 8011 | auto simpleValue = classDecl->new_ptr<SimpleValue_t>(); | ||
| 8012 | simpleValue->value.set(classDecl); | ||
| 8013 | if (transformAsUpValueFunc(newExp(simpleValue, classDecl), out)) { | ||
| 8014 | return; | ||
| 8015 | } | ||
| 7711 | str_list temp; | 8016 | str_list temp; |
| 7712 | pushFunctionScope(); | 8017 | pushAnonFunctionScope(); |
| 7713 | pushAnonVarArg(); | 8018 | pushAnonVarArg(); |
| 7714 | std::string& funcStart = temp.emplace_back(); | 8019 | std::string& funcStart = temp.emplace_back(); |
| 7715 | pushScope(); | 8020 | pushScope(); |
| @@ -7918,7 +8223,7 @@ private: | |||
| 7918 | if (extend) { | 8223 | if (extend) { |
| 7919 | _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl); | 8224 | _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl); |
| 7920 | } | 8225 | } |
| 7921 | _buf << indent() << classVar << " = "sv << globalVar("setmetatable"sv, classDecl) << "({"sv << nll(classDecl); | 8226 | _buf << indent() << classVar << " = "sv << globalVar("setmetatable"sv, classDecl, AccessType::Read) << "({"sv << nll(classDecl); |
| 7922 | if (!builtins.empty()) { | 8227 | if (!builtins.empty()) { |
| 7923 | _buf << join(builtins) << ',' << nll(classDecl); | 8228 | _buf << join(builtins) << ',' << nll(classDecl); |
| 7924 | } else { | 8229 | } else { |
| @@ -8142,8 +8447,13 @@ private: | |||
| 8142 | } | 8447 | } |
| 8143 | 8448 | ||
| 8144 | void transformWithClosure(With_t* with, str_list& out) { | 8449 | void transformWithClosure(With_t* with, str_list& out) { |
| 8450 | auto simpleValue = with->new_ptr<SimpleValue_t>(); | ||
| 8451 | simpleValue->value.set(with); | ||
| 8452 | if (transformAsUpValueFunc(newExp(simpleValue, with), out)) { | ||
| 8453 | return; | ||
| 8454 | } | ||
| 8145 | str_list temp; | 8455 | str_list temp; |
| 8146 | pushFunctionScope(); | 8456 | pushAnonFunctionScope(); |
| 8147 | pushAnonVarArg(); | 8457 | pushAnonVarArg(); |
| 8148 | std::string& funcStart = temp.emplace_back(); | 8458 | std::string& funcStart = temp.emplace_back(); |
| 8149 | pushScope(); | 8459 | pushScope(); |
| @@ -8163,9 +8473,9 @@ private: | |||
| 8163 | bool scoped = false; | 8473 | bool scoped = false; |
| 8164 | if (with->assigns) { | 8474 | if (with->assigns) { |
| 8165 | auto vars = getAssignVars(with); | 8475 | auto vars = getAssignVars(with); |
| 8166 | if (vars.front().empty() || isGlobal(vars.front())) { | 8476 | if (vars.front().empty() || isDeclaredAsGlobal(vars.front())) { |
| 8167 | if (with->assigns->values.objects().size() == 1) { | 8477 | if (with->assigns->values.objects().size() == 1) { |
| 8168 | auto var = singleVariableFrom(with->assigns->values.objects().front(), true); | 8478 | auto var = singleVariableFrom(with->assigns->values.objects().front(), AccessType::Read); |
| 8169 | if (!var.empty() && isLocal(var)) { | 8479 | if (!var.empty() && isLocal(var)) { |
| 8170 | withVar = var; | 8480 | withVar = var; |
| 8171 | } | 8481 | } |
| @@ -8211,7 +8521,7 @@ private: | |||
| 8211 | transformAssignment(assignment, temp); | 8521 | transformAssignment(assignment, temp); |
| 8212 | } | 8522 | } |
| 8213 | } else { | 8523 | } else { |
| 8214 | withVar = singleVariableFrom(with->valueList, true); | 8524 | withVar = singleVariableFrom(with->valueList, AccessType::Read); |
| 8215 | if (withVar.empty() || !isLocal(withVar)) { | 8525 | if (withVar.empty() || !isLocal(withVar)) { |
| 8216 | withVar = getUnusedName("_with_"sv); | 8526 | withVar = getUnusedName("_with_"sv); |
| 8217 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 8527 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| @@ -8555,11 +8865,17 @@ private: | |||
| 8555 | 8865 | ||
| 8556 | void transformTblComprehension(TblComprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 8866 | void transformTblComprehension(TblComprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| 8557 | switch (usage) { | 8867 | switch (usage) { |
| 8558 | case ExpUsage::Closure: | 8868 | case ExpUsage::Closure: { |
| 8559 | pushFunctionScope(); | 8869 | auto simpleValue = comp->new_ptr<SimpleValue_t>(); |
| 8870 | simpleValue->value.set(comp); | ||
| 8871 | if (transformAsUpValueFunc(newExp(simpleValue, comp), out)) { | ||
| 8872 | return; | ||
| 8873 | } | ||
| 8874 | pushAnonFunctionScope(); | ||
| 8560 | pushAnonVarArg(); | 8875 | pushAnonVarArg(); |
| 8561 | pushScope(); | 8876 | pushScope(); |
| 8562 | break; | 8877 | break; |
| 8878 | } | ||
| 8563 | case ExpUsage::Assignment: | 8879 | case ExpUsage::Assignment: |
| 8564 | pushScope(); | 8880 | pushScope(); |
| 8565 | break; | 8881 | break; |
| @@ -8663,7 +8979,12 @@ private: | |||
| 8663 | str_list temp; | 8979 | str_list temp; |
| 8664 | std::string* funcStart = nullptr; | 8980 | std::string* funcStart = nullptr; |
| 8665 | if (usage == ExpUsage::Closure) { | 8981 | if (usage == ExpUsage::Closure) { |
| 8666 | pushFunctionScope(); | 8982 | auto simpleValue = doNode->new_ptr<SimpleValue_t>(); |
| 8983 | simpleValue->value.set(doNode); | ||
| 8984 | if (transformAsUpValueFunc(newExp(simpleValue, doNode), out)) { | ||
| 8985 | return; | ||
| 8986 | } | ||
| 8987 | pushAnonFunctionScope(); | ||
| 8667 | pushAnonVarArg(); | 8988 | pushAnonVarArg(); |
| 8668 | funcStart = &temp.emplace_back(); | 8989 | funcStart = &temp.emplace_back(); |
| 8669 | } else { | 8990 | } else { |
| @@ -8691,7 +9012,7 @@ private: | |||
| 8691 | errHandler.set(toAst<Exp_t>(errHandleStr, x->func)); | 9012 | errHandler.set(toAst<Exp_t>(errHandleStr, x->func)); |
| 8692 | auto funLit = simpleSingleValueFrom(errHandler)->value.to<FunLit_t>(); | 9013 | auto funLit = simpleSingleValueFrom(errHandler)->value.to<FunLit_t>(); |
| 8693 | auto body = x->new_ptr<Body_t>(); | 9014 | auto body = x->new_ptr<Body_t>(); |
| 8694 | body->content.set(tryNode->catchBlock->body); | 9015 | body->content.set(tryNode->catchBlock->block); |
| 8695 | funLit->body.set(body); | 9016 | funLit->body.set(body); |
| 8696 | } | 9017 | } |
| 8697 | if (auto tryBlock = tryNode->func.as<Block_t>()) { | 9018 | if (auto tryBlock = tryNode->func.as<Block_t>()) { |
| @@ -8709,6 +9030,35 @@ private: | |||
| 8709 | BLOCK_END | 9030 | BLOCK_END |
| 8710 | } | 9031 | } |
| 8711 | if (auto tryBlock = tryNode->func.as<Block_t>()) { | 9032 | if (auto tryBlock = tryNode->func.as<Block_t>()) { |
| 9033 | { | ||
| 9034 | auto body = tryBlock->new_ptr<Body_t>(); | ||
| 9035 | body->content.set(tryBlock); | ||
| 9036 | auto doNode = tryBlock->new_ptr<Do_t>(); | ||
| 9037 | doNode->body.set(body); | ||
| 9038 | auto simpleValue = tryBlock->new_ptr<SimpleValue_t>(); | ||
| 9039 | simpleValue->value.set(doNode); | ||
| 9040 | if (auto result = upValueFuncFrom(newExp(simpleValue, tryBlock))) { | ||
| 9041 | auto [funcName, args] = std::move(*result); | ||
| 9042 | if (errHandler) { | ||
| 9043 | auto xpcall = toAst<ChainValue_t>("xpcall()", x); | ||
| 9044 | auto invoke = ast_to<Invoke_t>(xpcall->items.back()); | ||
| 9045 | invoke->args.push_back(toAst<Exp_t>(funcName, x)); | ||
| 9046 | invoke->args.push_back(errHandler); | ||
| 9047 | invoke->args.dup(toAst<ExpList_t>(join(args, ","sv), x)->exprs); | ||
| 9048 | transformChainValue(xpcall, out, ExpUsage::Closure); | ||
| 9049 | } else { | ||
| 9050 | auto pcall = toAst<ChainValue_t>("pcall()", x); | ||
| 9051 | auto invoke = ast_to<Invoke_t>(pcall->items.back()); | ||
| 9052 | invoke->args.push_back(toAst<Exp_t>(funcName, x)); | ||
| 9053 | invoke->args.dup(toAst<ExpList_t>(join(args, ","sv), x)->exprs); | ||
| 9054 | transformChainValue(pcall, out, ExpUsage::Closure); | ||
| 9055 | } | ||
| 9056 | if (usage == ExpUsage::Common) { | ||
| 9057 | out.back().append(nlr(x)); | ||
| 9058 | } | ||
| 9059 | return; | ||
| 9060 | } | ||
| 9061 | } | ||
| 8712 | auto tryExp = toAst<Exp_t>("->"sv, x); | 9062 | auto tryExp = toAst<Exp_t>("->"sv, x); |
| 8713 | auto funLit = simpleSingleValueFrom(tryExp)->value.to<FunLit_t>(); | 9063 | auto funLit = simpleSingleValueFrom(tryExp)->value.to<FunLit_t>(); |
| 8714 | auto body = x->new_ptr<Body_t>(); | 9064 | auto body = x->new_ptr<Body_t>(); |
| @@ -8806,7 +9156,7 @@ private: | |||
| 8806 | void transformImportFrom(ImportFrom_t* importNode, str_list& out) { | 9156 | void transformImportFrom(ImportFrom_t* importNode, str_list& out) { |
| 8807 | str_list temp; | 9157 | str_list temp; |
| 8808 | auto x = importNode; | 9158 | auto x = importNode; |
| 8809 | auto objVar = singleVariableFrom(importNode->item, true); | 9159 | auto objVar = singleVariableFrom(importNode->item, AccessType::Read); |
| 8810 | ast_ptr<false, ExpListAssign_t> objAssign; | 9160 | ast_ptr<false, ExpListAssign_t> objAssign; |
| 8811 | if (objVar.empty()) { | 9161 | if (objVar.empty()) { |
| 8812 | objVar = getUnusedName("_obj_"sv); | 9162 | objVar = getUnusedName("_obj_"sv); |
| @@ -9169,8 +9519,13 @@ private: | |||
| 9169 | 9519 | ||
| 9170 | void transformWhileClosure(While_t* whileNode, str_list& out) { | 9520 | void transformWhileClosure(While_t* whileNode, str_list& out) { |
| 9171 | auto x = whileNode; | 9521 | auto x = whileNode; |
| 9522 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
| 9523 | simpleValue->value.set(whileNode); | ||
| 9524 | if (transformAsUpValueFunc(newExp(simpleValue, x), out)) { | ||
| 9525 | return; | ||
| 9526 | } | ||
| 9172 | str_list temp; | 9527 | str_list temp; |
| 9173 | pushFunctionScope(); | 9528 | pushAnonFunctionScope(); |
| 9174 | pushAnonVarArg(); | 9529 | pushAnonVarArg(); |
| 9175 | std::string& funcStart = temp.emplace_back(); | 9530 | std::string& funcStart = temp.emplace_back(); |
| 9176 | pushScope(); | 9531 | pushScope(); |
| @@ -9232,13 +9587,18 @@ private: | |||
| 9232 | str_list temp; | 9587 | str_list temp; |
| 9233 | std::string* funcStart = nullptr; | 9588 | std::string* funcStart = nullptr; |
| 9234 | if (usage == ExpUsage::Closure) { | 9589 | if (usage == ExpUsage::Closure) { |
| 9235 | pushFunctionScope(); | 9590 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
| 9591 | simpleValue->value.set(switchNode); | ||
| 9592 | if (transformAsUpValueFunc(newExp(simpleValue, x), out)) { | ||
| 9593 | return; | ||
| 9594 | } | ||
| 9595 | pushAnonFunctionScope(); | ||
| 9236 | pushAnonVarArg(); | 9596 | pushAnonVarArg(); |
| 9237 | funcStart = &temp.emplace_back(); | 9597 | funcStart = &temp.emplace_back(); |
| 9238 | pushScope(); | 9598 | pushScope(); |
| 9239 | } | 9599 | } |
| 9240 | bool extraScope = false; | 9600 | bool extraScope = false; |
| 9241 | auto objVar = singleVariableFrom(switchNode->target, true); | 9601 | auto objVar = singleVariableFrom(switchNode->target, AccessType::Read); |
| 9242 | if (objVar.empty() || !isLocal(objVar)) { | 9602 | if (objVar.empty() || !isLocal(objVar)) { |
| 9243 | if (usage == ExpUsage::Common || usage == ExpUsage::Assignment) { | 9603 | if (usage == ExpUsage::Common || usage == ExpUsage::Assignment) { |
| 9244 | extraScope = true; | 9604 | extraScope = true; |
| @@ -9285,7 +9645,7 @@ private: | |||
| 9285 | forceAddToScope(typeVar); | 9645 | forceAddToScope(typeVar); |
| 9286 | tabCheckVar = getUnusedName("_tab_"sv); | 9646 | tabCheckVar = getUnusedName("_tab_"sv); |
| 9287 | forceAddToScope(tabCheckVar); | 9647 | forceAddToScope(tabCheckVar); |
| 9288 | temp.push_back(indent() + "local "s + typeVar + " = "s + globalVar("type"sv, branch) + '(' + objVar + ')' + nll(branch)); | 9648 | temp.push_back(indent() + "local "s + typeVar + " = "s + globalVar("type"sv, branch, AccessType::Read) + '(' + objVar + ')' + nll(branch)); |
| 9289 | temp.push_back(indent() + "local "s + tabCheckVar + " = \"table\" == "s + typeVar + " or \"userdata\" == "s + typeVar + nll(branch)); | 9649 | temp.push_back(indent() + "local "s + tabCheckVar + " = \"table\" == "s + typeVar + " or \"userdata\" == "s + typeVar + nll(branch)); |
| 9290 | } | 9650 | } |
| 9291 | std::string matchVar; | 9651 | std::string matchVar; |
| @@ -9730,12 +10090,12 @@ private: | |||
| 9730 | constVal = ast_is<ConstValue_t, Num_t>(simpleVal->value); | 10090 | constVal = ast_is<ConstValue_t, Num_t>(simpleVal->value); |
| 9731 | } | 10091 | } |
| 9732 | bool localVal = false; | 10092 | bool localVal = false; |
| 9733 | if (auto var = singleVariableFrom(value, false); isLocal(var)) { | 10093 | if (auto var = singleVariableFrom(value, AccessType::None); isLocal(var)) { |
| 9734 | localVal = true; | 10094 | localVal = true; |
| 9735 | } | 10095 | } |
| 9736 | if (!constVal && !localVal) { | 10096 | if (!constVal && !localVal) { |
| 9737 | for (auto exp : chainAssign->exprs.objects()) { | 10097 | for (auto exp : chainAssign->exprs.objects()) { |
| 9738 | std::string var = singleVariableFrom(exp, false); | 10098 | std::string var = singleVariableFrom(exp, AccessType::None); |
| 9739 | if (!var.empty()) { | 10099 | if (!var.empty()) { |
| 9740 | str_list temp; | 10100 | str_list temp; |
| 9741 | transformAssignment(assignmentFrom(static_cast<Exp_t*>(exp), value, exp), temp); | 10101 | transformAssignment(assignmentFrom(static_cast<Exp_t*>(exp), value, exp), temp); |
diff --git a/src/yuescript/yue_compiler.h b/src/yuescript/yue_compiler.h index a781b58..8c8ea61 100644 --- a/src/yuescript/yue_compiler.h +++ b/src/yuescript/yue_compiler.h | |||
| @@ -39,10 +39,18 @@ struct YueConfig { | |||
| 39 | Options options; | 39 | Options options; |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | enum class AccessType { | ||
| 43 | None, | ||
| 44 | Read, | ||
| 45 | Capture, | ||
| 46 | Write | ||
| 47 | }; | ||
| 48 | |||
| 42 | struct GlobalVar { | 49 | struct GlobalVar { |
| 43 | std::string name; | 50 | std::string name; |
| 44 | int line; | 51 | int line; |
| 45 | int col; | 52 | int col; |
| 53 | AccessType accessType; | ||
| 46 | }; | 54 | }; |
| 47 | 55 | ||
| 48 | using GlobalVars = std::vector<GlobalVar>; | 56 | using GlobalVars = std::vector<GlobalVar>; |
| @@ -60,6 +68,7 @@ struct CompileInfo { | |||
| 60 | std::unique_ptr<Options> options; | 68 | std::unique_ptr<Options> options; |
| 61 | double parseTime; | 69 | double parseTime; |
| 62 | double compileTime; | 70 | double compileTime; |
| 71 | bool usedVar; | ||
| 63 | 72 | ||
| 64 | CompileInfo() { } | 73 | CompileInfo() { } |
| 65 | CompileInfo( | 74 | CompileInfo( |
| @@ -68,7 +77,8 @@ struct CompileInfo { | |||
| 68 | std::unique_ptr<GlobalVars>&& globals, | 77 | std::unique_ptr<GlobalVars>&& globals, |
| 69 | std::unique_ptr<Options>&& options, | 78 | std::unique_ptr<Options>&& options, |
| 70 | double parseTime, | 79 | double parseTime, |
| 71 | double compileTime); | 80 | double compileTime, |
| 81 | bool usedVar); | ||
| 72 | CompileInfo(CompileInfo&& other); | 82 | CompileInfo(CompileInfo&& other); |
| 73 | void operator=(CompileInfo&& other); | 83 | void operator=(CompileInfo&& other); |
| 74 | }; | 84 | }; |
