aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2024-05-17 16:38:44 +0800
committerLi Jin <dragon-fly@qq.com>2024-05-17 16:38:44 +0800
commit06bf167924d04aaefe80d6e4ead40989a447ea34 (patch)
treeccd2c3b62797d378ee7cc1872440483d328980ca
parentfe317e2bdd9cb60b3c7cd347e21ce65cf90396e7 (diff)
downloadyuescript-06bf167924d04aaefe80d6e4ead40989a447ea34.tar.gz
yuescript-06bf167924d04aaefe80d6e4ead40989a447ea34.tar.bz2
yuescript-06bf167924d04aaefe80d6e4ead40989a447ea34.zip
fix more cases in try-catch syntax.v0.23.6
-rw-r--r--spec/inputs/try_catch.yue7
-rw-r--r--spec/inputs/upvalue_func.yue2
-rw-r--r--spec/outputs/5.1/attrib.lua4
-rw-r--r--spec/outputs/5.1/try_catch.lua47
-rw-r--r--spec/outputs/codes_from_doc.lua56
-rw-r--r--spec/outputs/codes_from_doc_zh.lua56
-rw-r--r--spec/outputs/try_catch.lua89
-rw-r--r--spec/outputs/unicode/try_catch.lua58
-rw-r--r--spec/outputs/upvalue_func.lua48
-rw-r--r--src/yuescript/yue_compiler.cpp326
10 files changed, 556 insertions, 137 deletions
diff --git a/spec/inputs/try_catch.yue b/spec/inputs/try_catch.yue
index 419eef4..4e05bc6 100644
--- a/spec/inputs/try_catch.yue
+++ b/spec/inputs/try_catch.yue
@@ -20,6 +20,8 @@ f = ->
20 20
21 success, result = try func 1, 2, 3 21 success, result = try func 1, 2, 3
22 22
23 tb = {}
24
23 try tb.func 25 try tb.func
24 try tb.func! 26 try tb.func!
25 try tb.func() 27 try tb.func()
@@ -57,4 +59,9 @@ f = ->
57 59
58 try func 1, 2, 3 60 try func 1, 2, 3
59 61
62 do
63 <- x
64 local tb, a, b, c
65 f = -> try tb.f a, b, c
66
60 nil 67 nil
diff --git a/spec/inputs/upvalue_func.yue b/spec/inputs/upvalue_func.yue
index 159be76..d4b3273 100644
--- a/spec/inputs/upvalue_func.yue
+++ b/spec/inputs/upvalue_func.yue
@@ -210,6 +210,8 @@ do
210 buff_strength = (char, item) -> 210 buff_strength = (char, item) ->
211 item.buffer.strength? char.stats.strength?::ref() 211 item.buffer.strength? char.stats.strength?::ref()
212 212
213 local debug_env_before, debug_env_after
214
213 exe_func = (func, env) -> 215 exe_func = (func, env) ->
214 ok, ... = try 216 ok, ... = try
215 debug_env_before(env) 217 debug_env_before(env)
diff --git a/spec/outputs/5.1/attrib.lua b/spec/outputs/5.1/attrib.lua
index 9cacd97..8361b24 100644
--- a/spec/outputs/5.1/attrib.lua
+++ b/spec/outputs/5.1/attrib.lua
@@ -199,7 +199,9 @@ do
199 end 199 end
200 }) 200 })
201 local _close_2 = assert(getmetatable(_).__close) 201 local _close_2 = assert(getmetatable(_).__close)
202 return _anon_func_9(_, _close_2, error, pcall(print, "third")) 202 return _anon_func_9(_, _close_2, error, pcall(function()
203 return print("third")
204 end))
203 end)) 205 end))
204 end)) 206 end))
205end 207end
diff --git a/spec/outputs/5.1/try_catch.lua b/spec/outputs/5.1/try_catch.lua
index f63cd91..d4c80c1 100644
--- a/spec/outputs/5.1/try_catch.lua
+++ b/spec/outputs/5.1/try_catch.lua
@@ -1,9 +1,8 @@
1local _anon_func_0 = function(func, print) 1local _anon_func_0 = function(tb)
2 print("trying") 2 return tb.func
3 return func(1, 2, 3)
4end 3end
5local _anon_func_1 = function(tb) 4local _anon_func_1 = function(tb)
6 return tb.func 5 return tb.func()
7end 6end
8local _anon_func_2 = function(tb) 7local _anon_func_2 = function(tb)
9 return tb.func() 8 return tb.func()
@@ -12,16 +11,16 @@ local _anon_func_3 = function(tb)
12 return tb.func() 11 return tb.func()
13end 12end
14local _anon_func_4 = function(tb) 13local _anon_func_4 = function(tb)
15 return tb.func() 14 return tb:func(1, 2, 3)
16end 15end
17local _anon_func_5 = function(tb) 16local _anon_func_5 = function(tb)
18 return tb:func(1, 2, 3) 17 return tb.func(1)
19end 18end
20local _anon_func_6 = function(tb) 19local _anon_func_6 = function(tb)
21 return tb.func(1) 20 return tb.func(1)
22end 21end
23local _anon_func_7 = function(tb) 22local _anon_func_7 = function(a, b, c, tb)
24 return tb.func(1) 23 return tb.f(a, b, c)
25end 24end
26local f 25local f
27f = function() 26f = function()
@@ -35,22 +34,28 @@ f = function()
35 end, function(err) 34 end, function(err)
36 return print(err) 35 return print(err)
37 end) 36 end)
38 pcall(_anon_func_0, func, print) 37 pcall(function()
38 print("trying")
39 return func(1, 2, 3)
40 end)
39 do 41 do
40 local success, result = xpcall(function() 42 local success, result = xpcall(function()
41 return func(1, 2, 3) 43 return func(1, 2, 3)
42 end, function(err) 44 end, function(err)
43 return print(err) 45 return print(err)
44 end) 46 end)
45 success, result = pcall(func, 1, 2, 3) 47 success, result = pcall(function()
48 return func(1, 2, 3)
49 end)
46 end 50 end
51 local tb = { }
52 pcall(_anon_func_0, tb)
47 pcall(_anon_func_1, tb) 53 pcall(_anon_func_1, tb)
48 pcall(_anon_func_2, tb) 54 pcall(_anon_func_2, tb)
49 pcall(_anon_func_3, tb) 55 pcall(_anon_func_3, tb)
50 pcall(_anon_func_4, tb) 56 pcall(_anon_func_4, tb)
51 pcall(_anon_func_5, tb) 57 pcall(_anon_func_5, tb)
52 pcall(_anon_func_6, tb) 58 pcall(_anon_func_6, tb)
53 pcall(_anon_func_7, tb)
54 if (xpcall(function() 59 if (xpcall(function()
55 return func(1) 60 return func(1)
56 end, function(err) 61 end, function(err)
@@ -67,7 +72,9 @@ f = function()
67 end 72 end
68 do 73 do
69 do 74 do
70 local success, result = pcall(func, "abc", 123) 75 local success, result = pcall(function()
76 return func("abc", 123)
77 end)
71 if success then 78 if success then
72 print(result) 79 print(result)
73 end 80 end
@@ -87,8 +94,20 @@ f = function()
87 end 94 end
88 end 95 end
89 do 96 do
90 pcall(func, 1, 2, 3) 97 pcall(function()
91 pcall(func, 1, 2, 3) 98 return func(1, 2, 3)
99 end)
100 pcall(function()
101 return func(1, 2, 3)
102 end)
103 end
104 do
105 x(function()
106 local tb, a, b, c
107 f = function()
108 return pcall(_anon_func_7, a, b, c, tb)
109 end
110 end)
92 end 111 end
93 return nil 112 return nil
94end 113end
diff --git a/spec/outputs/codes_from_doc.lua b/spec/outputs/codes_from_doc.lua
index b2ba836..6f61569 100644
--- a/spec/outputs/codes_from_doc.lua
+++ b/spec/outputs/codes_from_doc.lua
@@ -608,23 +608,33 @@ end):concat(Rx.Observable.of('who do we appreciate')):map(function(value)
608end):subscribe(print) 608end):subscribe(print)
609local str = strA .. strB .. strC 609local str = strA .. strB .. strC
610func(3000, "192.168.1.1") 610func(3000, "192.168.1.1")
611xpcall(func, function(err) 611xpcall(function()
612 return func(1, 2, 3)
613end, function(err)
612 return print(yue.traceback(err)) 614 return print(yue.traceback(err))
613end, 1, 2, 3) 615end)
614local success, result = xpcall(func, function(err) 616local success, result = xpcall(function()
617 return func(1, 2, 3)
618end, function(err)
615 return yue.traceback(err) 619 return yue.traceback(err)
616end, 1, 2, 3) 620end)
617xpcall(func, function(err) 621xpcall(function()
622 return func(1, 2, 3)
623end, function(err)
618 return print(yue.traceback(err)) 624 return print(yue.traceback(err))
619end, 1, 2, 3) 625end)
620success, result = pcall(func, 1, 2, 3) 626success, result = pcall(function()
627 return func(1, 2, 3)
628end)
621pcall(function() 629pcall(function()
622 print("trying") 630 print("trying")
623 return func(1, 2, 3) 631 return func(1, 2, 3)
624end) 632end)
625success, result = xpcall(func, function(err) 633success, result = xpcall(function()
634 return func(1, 2, 3)
635end, function(err)
626 return print(yue.traceback(err)) 636 return print(yue.traceback(err))
627end, 1, 2, 3) 637end)
628if success then 638if success then
629 print(result) 639 print(result)
630end 640end
@@ -2595,23 +2605,33 @@ end):concat(Rx.Observable.of('who do we appreciate')):map(function(value)
2595end):subscribe(print) 2605end):subscribe(print)
2596local str = strA .. strB .. strC 2606local str = strA .. strB .. strC
2597func(3000, "192.168.1.1") 2607func(3000, "192.168.1.1")
2598xpcall(func, function(err) 2608xpcall(function()
2609 return func(1, 2, 3)
2610end, function(err)
2599 return print(yue.traceback(err)) 2611 return print(yue.traceback(err))
2600end, 1, 2, 3) 2612end)
2601local success, result = xpcall(func, function(err) 2613local success, result = xpcall(function()
2614 return func(1, 2, 3)
2615end, function(err)
2602 return yue.traceback(err) 2616 return yue.traceback(err)
2603end, 1, 2, 3) 2617end)
2604xpcall(func, function(err) 2618xpcall(function()
2619 return func(1, 2, 3)
2620end, function(err)
2605 return print(yue.traceback(err)) 2621 return print(yue.traceback(err))
2606end, 1, 2, 3) 2622end)
2607success, result = pcall(func, 1, 2, 3) 2623success, result = pcall(function()
2624 return func(1, 2, 3)
2625end)
2608pcall(function() 2626pcall(function()
2609 print("trying") 2627 print("trying")
2610 return func(1, 2, 3) 2628 return func(1, 2, 3)
2611end) 2629end)
2612success, result = xpcall(func, function(err) 2630success, result = xpcall(function()
2631 return func(1, 2, 3)
2632end, function(err)
2613 return print(yue.traceback(err)) 2633 return print(yue.traceback(err))
2614end, 1, 2, 3) 2634end)
2615if success then 2635if success then
2616 print(result) 2636 print(result)
2617end 2637end
diff --git a/spec/outputs/codes_from_doc_zh.lua b/spec/outputs/codes_from_doc_zh.lua
index 3f9615f..aa53926 100644
--- a/spec/outputs/codes_from_doc_zh.lua
+++ b/spec/outputs/codes_from_doc_zh.lua
@@ -608,23 +608,33 @@ end):concat(Rx.Observable.of('who do we appreciate')):map(function(value)
608end):subscribe(print) 608end):subscribe(print)
609local str = strA .. strB .. strC 609local str = strA .. strB .. strC
610func(3000, "192.168.1.1") 610func(3000, "192.168.1.1")
611xpcall(func, function(err) 611xpcall(function()
612 return func(1, 2, 3)
613end, function(err)
612 return print(yue.traceback(err)) 614 return print(yue.traceback(err))
613end, 1, 2, 3) 615end)
614local success, result = xpcall(func, function(err) 616local success, result = xpcall(function()
617 return func(1, 2, 3)
618end, function(err)
615 return yue.traceback(err) 619 return yue.traceback(err)
616end, 1, 2, 3) 620end)
617xpcall(func, function(err) 621xpcall(function()
622 return func(1, 2, 3)
623end, function(err)
618 return print(yue.traceback(err)) 624 return print(yue.traceback(err))
619end, 1, 2, 3) 625end)
620success, result = pcall(func, 1, 2, 3) 626success, result = pcall(function()
627 return func(1, 2, 3)
628end)
621pcall(function() 629pcall(function()
622 print("尝试中") 630 print("尝试中")
623 return func(1, 2, 3) 631 return func(1, 2, 3)
624end) 632end)
625success, result = xpcall(func, function(err) 633success, result = xpcall(function()
634 return func(1, 2, 3)
635end, function(err)
626 return print(yue.traceback(err)) 636 return print(yue.traceback(err))
627end, 1, 2, 3) 637end)
628if success then 638if success then
629 print(result) 639 print(result)
630end 640end
@@ -2589,23 +2599,33 @@ end):concat(Rx.Observable.of('who do we appreciate')):map(function(value)
2589end):subscribe(print) 2599end):subscribe(print)
2590local str = strA .. strB .. strC 2600local str = strA .. strB .. strC
2591func(3000, "192.168.1.1") 2601func(3000, "192.168.1.1")
2592xpcall(func, function(err) 2602xpcall(function()
2603 return func(1, 2, 3)
2604end, function(err)
2593 return print(yue.traceback(err)) 2605 return print(yue.traceback(err))
2594end, 1, 2, 3) 2606end)
2595local success, result = xpcall(func, function(err) 2607local success, result = xpcall(function()
2608 return func(1, 2, 3)
2609end, function(err)
2596 return yue.traceback(err) 2610 return yue.traceback(err)
2597end, 1, 2, 3) 2611end)
2598xpcall(func, function(err) 2612xpcall(function()
2613 return func(1, 2, 3)
2614end, function(err)
2599 return print(yue.traceback(err)) 2615 return print(yue.traceback(err))
2600end, 1, 2, 3) 2616end)
2601success, result = pcall(func, 1, 2, 3) 2617success, result = pcall(function()
2618 return func(1, 2, 3)
2619end)
2602pcall(function() 2620pcall(function()
2603 print("尝试中") 2621 print("尝试中")
2604 return func(1, 2, 3) 2622 return func(1, 2, 3)
2605end) 2623end)
2606success, result = xpcall(func, function(err) 2624success, result = xpcall(function()
2625 return func(1, 2, 3)
2626end, function(err)
2607 return print(yue.traceback(err)) 2627 return print(yue.traceback(err))
2608end, 1, 2, 3) 2628end)
2609if success then 2629if success then
2610 print(result) 2630 print(result)
2611end 2631end
diff --git a/spec/outputs/try_catch.lua b/spec/outputs/try_catch.lua
index 3c3dd3c..d4c80c1 100644
--- a/spec/outputs/try_catch.lua
+++ b/spec/outputs/try_catch.lua
@@ -1,9 +1,8 @@
1local _anon_func_0 = function(func, print) 1local _anon_func_0 = function(tb)
2 print("trying") 2 return tb.func
3 return func(1, 2, 3)
4end 3end
5local _anon_func_1 = function(tb) 4local _anon_func_1 = function(tb)
6 return tb.func 5 return tb.func()
7end 6end
8local _anon_func_2 = function(tb) 7local _anon_func_2 = function(tb)
9 return tb.func() 8 return tb.func()
@@ -12,69 +11,103 @@ local _anon_func_3 = function(tb)
12 return tb.func() 11 return tb.func()
13end 12end
14local _anon_func_4 = function(tb) 13local _anon_func_4 = function(tb)
15 return tb.func() 14 return tb:func(1, 2, 3)
16end 15end
17local _anon_func_5 = function(tb) 16local _anon_func_5 = function(tb)
18 return tb:func(1, 2, 3) 17 return tb.func(1)
19end 18end
20local _anon_func_6 = function(tb) 19local _anon_func_6 = function(tb)
21 return tb.func(1) 20 return tb.func(1)
22end 21end
23local _anon_func_7 = function(tb) 22local _anon_func_7 = function(a, b, c, tb)
24 return tb.func(1) 23 return tb.f(a, b, c)
25end 24end
26local f 25local f
27f = function() 26f = function()
28 xpcall(func, function(err) 27 xpcall(function()
28 return func(1, 2, 3)
29 end, function(err)
29 return print(err) 30 return print(err)
30 end, 1, 2, 3) 31 end)
31 xpcall(func, function(err) 32 xpcall(function()
33 return func(1, 2, 3)
34 end, function(err)
32 return print(err) 35 return print(err)
33 end, 1, 2, 3) 36 end)
34 pcall(_anon_func_0, func, print) 37 pcall(function()
38 print("trying")
39 return func(1, 2, 3)
40 end)
35 do 41 do
36 local success, result = xpcall(func, function(err) 42 local success, result = xpcall(function()
43 return func(1, 2, 3)
44 end, function(err)
37 return print(err) 45 return print(err)
38 end, 1, 2, 3) 46 end)
39 success, result = pcall(func, 1, 2, 3) 47 success, result = pcall(function()
48 return func(1, 2, 3)
49 end)
40 end 50 end
51 local tb = { }
52 pcall(_anon_func_0, tb)
41 pcall(_anon_func_1, tb) 53 pcall(_anon_func_1, tb)
42 pcall(_anon_func_2, tb) 54 pcall(_anon_func_2, tb)
43 pcall(_anon_func_3, tb) 55 pcall(_anon_func_3, tb)
44 pcall(_anon_func_4, tb) 56 pcall(_anon_func_4, tb)
45 pcall(_anon_func_5, tb) 57 pcall(_anon_func_5, tb)
46 pcall(_anon_func_6, tb) 58 pcall(_anon_func_6, tb)
47 pcall(_anon_func_7, tb) 59 if (xpcall(function()
48 if (xpcall(func, function(err) 60 return func(1)
61 end, function(err)
49 return print(err) 62 return print(err)
50 end, 1)) then 63 end)) then
51 print("OK") 64 print("OK")
52 end 65 end
53 if xpcall((func), function(err) 66 if xpcall(function()
67 return func(1)
68 end, function(err)
54 return print(err) 69 return print(err)
55 end, 1) then 70 end) then
56 print("OK") 71 print("OK")
57 end 72 end
58 do 73 do
59 do 74 do
60 local success, result = pcall(func, "abc", 123) 75 local success, result = pcall(function()
76 return func("abc", 123)
77 end)
61 if success then 78 if success then
62 print(result) 79 print(result)
63 end 80 end
64 end 81 end
65 local success, result = xpcall(func, function(err) 82 local success, result = xpcall(function()
83 return func("abc", 123)
84 end, function(err)
66 return print(err) 85 return print(err)
67 end, "abc", 123) 86 end)
68 success, result = xpcall(func, function(err) 87 success, result = xpcall(function()
88 return func("abc", 123)
89 end, function(err)
69 return print(err) 90 return print(err)
70 end, "abc", 123) 91 end)
71 if success then 92 if success then
72 print(result) 93 print(result)
73 end 94 end
74 end 95 end
75 do 96 do
76 pcall(func, 1, 2, 3) 97 pcall(function()
77 pcall(func, 1, 2, 3) 98 return func(1, 2, 3)
99 end)
100 pcall(function()
101 return func(1, 2, 3)
102 end)
103 end
104 do
105 x(function()
106 local tb, a, b, c
107 f = function()
108 return pcall(_anon_func_7, a, b, c, tb)
109 end
110 end)
78 end 111 end
79 return nil 112 return nil
80end 113end
diff --git a/spec/outputs/unicode/try_catch.lua b/spec/outputs/unicode/try_catch.lua
index 7d95f9b..22f29f9 100644
--- a/spec/outputs/unicode/try_catch.lua
+++ b/spec/outputs/unicode/try_catch.lua
@@ -1,18 +1,26 @@
1xpcall(_u51fd_u6570, function(_u9519_u8bef) 1xpcall(function()
2 return _u51fd_u6570(1, 2, 3)
3end, function(_u9519_u8bef)
2 return _u6253_u5370(_u9519_u8bef) 4 return _u6253_u5370(_u9519_u8bef)
3end, 1, 2, 3) 5end)
4xpcall(_u51fd_u6570, function(_u9519_u8bef) 6xpcall(function()
7 return _u51fd_u6570(1, 2, 3)
8end, function(_u9519_u8bef)
5 return _u6253_u5370(_u9519_u8bef) 9 return _u6253_u5370(_u9519_u8bef)
6end, 1, 2, 3) 10end)
7pcall(function() 11pcall(function()
8 _u6253_u5370("正在try") 12 _u6253_u5370("正在try")
9 return _u51fd_u6570(1, 2, 3) 13 return _u51fd_u6570(1, 2, 3)
10end) 14end)
11do 15do
12 local _u6210_u529f, _u7ed3_u679c = xpcall(_u51fd_u6570, function(_u9519_u8bef) 16 local _u6210_u529f, _u7ed3_u679c = xpcall(function()
17 return _u51fd_u6570(1, 2, 3)
18 end, function(_u9519_u8bef)
13 return _u6253_u5370(_u9519_u8bef) 19 return _u6253_u5370(_u9519_u8bef)
14 end, 1, 2, 3) 20 end)
15 _u6210_u529f, _u7ed3_u679c = pcall(_u51fd_u6570, 1, 2, 3) 21 _u6210_u529f, _u7ed3_u679c = pcall(function()
22 return _u51fd_u6570(1, 2, 3)
23 end)
16end 24end
17pcall(function() 25pcall(function()
18 return _u8868["函数"] 26 return _u8868["函数"]
@@ -36,35 +44,49 @@ end)
36pcall(function() 44pcall(function()
37 return _u8868["函数"](1) 45 return _u8868["函数"](1)
38end) 46end)
39if (xpcall(_u51fd_u6570, function(_u9519_u8bef) 47if (xpcall(function()
48 return _u51fd_u6570(1)
49end, function(_u9519_u8bef)
40 return _u6253_u5370(_u9519_u8bef) 50 return _u6253_u5370(_u9519_u8bef)
41end, 1)) then 51end)) then
42 _u6253_u5370("好的") 52 _u6253_u5370("好的")
43end 53end
44if xpcall((_u51fd_u6570), function(_u9519_u8bef) 54if xpcall(function()
55 return _u51fd_u6570(1)
56end, function(_u9519_u8bef)
45 return _u6253_u5370(_u9519_u8bef) 57 return _u6253_u5370(_u9519_u8bef)
46end, 1) then 58end) then
47 _u6253_u5370("好的") 59 _u6253_u5370("好的")
48end 60end
49do 61do
50 do 62 do
51 local _u6210_u529f, _u7ed3_u679c = pcall(_u51fd_u6570, "abc", 123) 63 local _u6210_u529f, _u7ed3_u679c = pcall(function()
64 return _u51fd_u6570("abc", 123)
65 end)
52 if _u6210_u529f then 66 if _u6210_u529f then
53 _u6253_u5370(_u7ed3_u679c) 67 _u6253_u5370(_u7ed3_u679c)
54 end 68 end
55 end 69 end
56 local _u6210_u529f, _u7ed3_u679c = xpcall(_u51fd_u6570, function(_u9519_u8bef) 70 local _u6210_u529f, _u7ed3_u679c = xpcall(function()
71 return _u51fd_u6570("abc", 123)
72 end, function(_u9519_u8bef)
57 return _u6253_u5370(_u9519_u8bef) 73 return _u6253_u5370(_u9519_u8bef)
58 end, "abc", 123) 74 end)
59 _u6210_u529f, _u7ed3_u679c = xpcall(_u51fd_u6570, function(_u9519_u8bef) 75 _u6210_u529f, _u7ed3_u679c = xpcall(function()
76 return _u51fd_u6570("abc", 123)
77 end, function(_u9519_u8bef)
60 return _u6253_u5370(_u9519_u8bef) 78 return _u6253_u5370(_u9519_u8bef)
61 end, "abc", 123) 79 end)
62 if _u6210_u529f then 80 if _u6210_u529f then
63 _u6253_u5370(_u7ed3_u679c) 81 _u6253_u5370(_u7ed3_u679c)
64 end 82 end
65end 83end
66do 84do
67 pcall(_u51fd_u6570, 1, 2, 3) 85 pcall(function()
68 pcall(_u51fd_u6570, 1, 2, 3) 86 return _u51fd_u6570(1, 2, 3)
87 end)
88 pcall(function()
89 return _u51fd_u6570(1, 2, 3)
90 end)
69end 91end
70return nil 92return nil
diff --git a/spec/outputs/upvalue_func.lua b/spec/outputs/upvalue_func.lua
index 5113692..e66eefa 100644
--- a/spec/outputs/upvalue_func.lua
+++ b/spec/outputs/upvalue_func.lua
@@ -367,12 +367,7 @@ local _anon_func_18 = function(print, select, _arg_0, ...)
367 end 367 end
368 end 368 end
369end 369end
370local _anon_func_19 = function(print) 370local _anon_func_19 = function(cond, i)
371 local a = 1
372 print(a + nil)
373 return 1, 2, 3
374end
375local _anon_func_20 = function(cond, i)
376 local _accum_0 = { } 371 local _accum_0 = { }
377 local _len_0 = 1 372 local _len_0 = 1
378 while cond do 373 while cond do
@@ -382,7 +377,7 @@ local _anon_func_20 = function(cond, i)
382 end 377 end
383 return _accum_0 378 return _accum_0
384end 379end
385local _anon_func_21 = function(value) 380local _anon_func_20 = function(value)
386 if 1 == value then 381 if 1 == value then
387 return 'a' 382 return 'a'
388 elseif 2 == value then 383 elseif 2 == value then
@@ -417,27 +412,31 @@ GameEngine:onUpdate(function(deltaTime)
417 func(_anon_func_16(pairs, tb, tostring)) 412 func(_anon_func_16(pairs, tb, tostring))
418 func(_anon_func_17(print)) 413 func(_anon_func_17(print))
419 do 414 do
420 _anon_func_18(print, select, pcall(_anon_func_19, print)) 415 _anon_func_18(print, select, pcall(function()
416 local a = 1
417 print(a + nil)
418 return 1, 2, 3
419 end))
421 end 420 end
422 i = 1 421 i = 1
423 func(_anon_func_20(cond, i)) 422 func(_anon_func_19(cond, i))
424 return func(_anon_func_21(value)) 423 return func(_anon_func_20(value))
425end) 424end)
426local _anon_func_22 = function(cond) 425local _anon_func_21 = function(cond)
427 if cond then 426 if cond then
428 return 998 427 return 998
429 else 428 else
430 return "abc" 429 return "abc"
431 end 430 end
432end 431end
433local _anon_func_23 = function(valueB) 432local _anon_func_22 = function(valueB)
434 if valueB ~= nil then 433 if valueB ~= nil then
435 return valueB 434 return valueB
436 else 435 else
437 return 123 436 return 123
438 end 437 end
439end 438end
440local _anon_func_24 = function(tb) 439local _anon_func_23 = function(tb)
441 if tb ~= nil then 440 if tb ~= nil then
442 local _obj_0 = tb.abc 441 local _obj_0 = tb.abc
443 if _obj_0 ~= nil then 442 if _obj_0 ~= nil then
@@ -451,7 +450,7 @@ local _anon_func_24 = function(tb)
451 end 450 end
452 return nil 451 return nil
453end 452end
454local _anon_func_26 = function(itemA, listA) 453local _anon_func_25 = function(itemA, listA)
455 for _index_0 = 1, #listA do 454 for _index_0 = 1, #listA do
456 if listA[_index_0] == itemA then 455 if listA[_index_0] == itemA then
457 return true 456 return true
@@ -459,17 +458,17 @@ local _anon_func_26 = function(itemA, listA)
459 end 458 end
460 return false 459 return false
461end 460end
462local _anon_func_25 = function(itemA, listA, tb) 461local _anon_func_24 = function(itemA, listA, tb)
463 do 462 do
464 local _call_0 = tb 463 local _call_0 = tb
465 local _call_1 = _call_0["end"](_call_0) 464 local _call_1 = _call_0["end"](_call_0)
466 return _call_1["🤣"](_call_1, 123 and (#listA > 0 and _anon_func_26(itemA, listA))) 465 return _call_1["🤣"](_call_1, 123 and (#listA > 0 and _anon_func_25(itemA, listA)))
467 end 466 end
468end 467end
469GameEngine:onEvent("SomeEvent", function() 468GameEngine:onEvent("SomeEvent", function()
470 return func(value + (_anon_func_22(cond)) + (_anon_func_23(valueB)) > _anon_func_24(tb) + _anon_func_25(itemA, listA, tb)) 469 return func(value + (_anon_func_21(cond)) + (_anon_func_22(valueB)) > _anon_func_23(tb) + _anon_func_24(itemA, listA, tb))
471end) 470end)
472local _anon_func_27 = function(UpdateScoreText, tostring, value) 471local _anon_func_26 = function(UpdateScoreText, tostring, value)
473 if value > 200 then 472 if value > 200 then
474 UpdateScoreText("Win: " .. tostring(value)) 473 UpdateScoreText("Win: " .. tostring(value))
475 return "done" 474 return "done"
@@ -480,7 +479,7 @@ local _anon_func_27 = function(UpdateScoreText, tostring, value)
480end 479end
481GameEngine:schedule(function(deltaTime) 480GameEngine:schedule(function(deltaTime)
482 local value = 123 481 local value = 123
483 return func(_anon_func_27(UpdateScoreText, tostring, value)) 482 return func(_anon_func_26(UpdateScoreText, tostring, value))
484end) 483end)
485GameEngine:schedule(function(deltaTime) 484GameEngine:schedule(function(deltaTime)
486 local value = 123 485 local value = 123
@@ -496,14 +495,14 @@ GameEngine:schedule(function(deltaTime)
496 end 495 end
497 end)()) 496 end)())
498end) 497end)
499local _anon_func_28 = function(char) 498local _anon_func_27 = function(char)
500 local _obj_0 = char.stats.strength 499 local _obj_0 = char.stats.strength
501 if _obj_0 ~= nil then 500 if _obj_0 ~= nil then
502 return _obj_0:ref() 501 return _obj_0:ref()
503 end 502 end
504 return nil 503 return nil
505end 504end
506local _anon_func_29 = function(os, _arg_0, ...) 505local _anon_func_28 = function(os, _arg_0, ...)
507 do 506 do
508 local ok = _arg_0 507 local ok = _arg_0
509 if ok then 508 if ok then
@@ -513,7 +512,7 @@ local _anon_func_29 = function(os, _arg_0, ...)
513 end 512 end
514 end 513 end
515end 514end
516local _anon_func_30 = function(debug_env_after, debug_env_before, env, func) 515local _anon_func_29 = function(debug_env_after, debug_env_before, env, func)
517 debug_env_before(env) 516 debug_env_before(env)
518 func(env) 517 func(env)
519 return debug_env_after(env) 518 return debug_env_after(env)
@@ -523,13 +522,14 @@ do
523 buff_strength = function(char, item) 522 buff_strength = function(char, item)
524 local _obj_0 = item.buffer.strength 523 local _obj_0 = item.buffer.strength
525 if _obj_0 ~= nil then 524 if _obj_0 ~= nil then
526 return _obj_0(_anon_func_28(char)) 525 return _obj_0(_anon_func_27(char))
527 end 526 end
528 return nil 527 return nil
529 end 528 end
529 local debug_env_before, debug_env_after
530 local exe_func 530 local exe_func
531 exe_func = function(func, env) 531 exe_func = function(func, env)
532 return _anon_func_29(os, xpcall(_anon_func_30, function(ex) 532 return _anon_func_28(os, xpcall(_anon_func_29, function(ex)
533 error(ex) 533 error(ex)
534 return ex 534 return ex
535 end, debug_env_after, debug_env_before, env, func)) 535 end, debug_env_after, debug_env_before, env, func))
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index c205031..7f6a042 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
78const std::string_view version = "0.23.4"sv; 78const std::string_view version = "0.23.6"sv;
79const std::string_view extension = "yue"sv; 79const std::string_view extension = "yue"sv;
80 80
81class CompileError : public std::logic_error { 81class CompileError : public std::logic_error {
@@ -577,6 +577,273 @@ private:
577 } 577 }
578 } 578 }
579 579
580 bool isConstTableItem(ast_node* item) {
581 switch (item->get_id()) {
582 case id<VariablePairDef_t>(): {
583 auto pair = static_cast<VariablePairDef_t*>(item);
584 if (pair->defVal) return false;
585 return isConstTableItem(pair->pair);
586 }
587 case id<NormalPairDef_t>(): {
588 auto pair = static_cast<NormalPairDef_t*>(item);
589 if (pair->defVal) return false;
590 return isConstTableItem(pair->pair);
591 }
592 case id<MetaVariablePairDef_t>(): {
593 auto pair = static_cast<MetaVariablePairDef_t*>(item);
594 if (pair->defVal) return false;
595 return isConstTableItem(pair->pair);
596 }
597 case id<MetaNormalPairDef_t>(): {
598 auto pair = static_cast<MetaNormalPairDef_t*>(item);
599 if (pair->defVal) return false;
600 return isConstTableItem(pair->pair);
601 }
602 case id<NormalDef_t>(): {
603 auto pair = static_cast<NormalDef_t*>(item);
604 if (pair->defVal) return false;
605 return isConstTableItem(pair->item);
606 }
607 case id<Exp_t>(): {
608 auto pair = static_cast<Exp_t*>(item);
609 return isConstExp(pair);
610 }
611 case id<VariablePair_t>(): {
612 auto pair = static_cast<VariablePair_t*>(item);
613 return isLocal(variableToString(pair->name));
614 }
615 case id<NormalPair_t>(): {
616 auto pair = static_cast<NormalPair_t*>(item);
617 if (auto exp = pair->key.as<Exp_t>()) {
618 if (!isConstExp(exp)) {
619 return false;
620 }
621 }
622 if (auto exp = pair->value.as<Exp_t>()) {
623 if (!isConstExp(exp)) {
624 return false;
625 }
626 } else if (auto tbBlock = pair->value.as<TableBlock_t>()) {
627 if (!isConstTable(tbBlock)) {
628 return false;
629 }
630 } else {
631 return false;
632 }
633 return true;
634 }
635 case id<TableBlockIndent_t>(): {
636 auto pair = static_cast<TableBlockIndent_t*>(item);
637 return isConstTable(pair);
638 }
639 case id<TableBlock_t>(): {
640 auto pair = static_cast<TableBlock_t*>(item);
641 return isConstTable(pair);
642 break;
643 }
644 case id<MetaVariablePair_t>(): {
645 auto pair = static_cast<MetaVariablePair_t*>(item);
646 return isLocal(variableToString(pair->name));
647 }
648 case id<MetaNormalPair_t>(): {
649 auto pair = static_cast<MetaNormalPair_t*>(item);
650 if (auto str = pair->key.as<String_t>()) {
651 if (!ast_is<SingleString_t, LuaString_t>(str)) {
652 return false;
653 }
654 } else if (auto exp = pair->key.as<Exp_t>()) {
655 if (!isConstExp(exp)) {
656 return false;
657 }
658 } else if (pair->key.is<Name_t>()) {
659 return true;
660 } else {
661 return false;
662 }
663 if (auto exp = pair->value.as<Exp_t>()) {
664 if (!isConstExp(exp)) {
665 return false;
666 }
667 } else if (auto tbBlock = pair->value.as<TableBlock_t>()) {
668 if (!isConstTable(tbBlock)) {
669 return false;
670 }
671 } else {
672 return false;
673 }
674 return true;
675 }
676 }
677 return false;
678 }
679
680 bool isConstTable(TableLit_t* tableLit) {
681 for (auto value : tableLit->values.objects()) {
682 if (!isConstTableItem(value)) {
683 return false;
684 }
685 }
686 return true;
687 }
688
689 bool isConstTable(TableBlock_t* tableBlock) {
690 for (auto value : tableBlock->values.objects()) {
691 if (!isConstTableItem(value)) {
692 return false;
693 }
694 }
695 return true;
696 }
697
698 bool isConstTable(SimpleTable_t* stable) {
699 for (auto value : stable->pairs.objects()) {
700 if (!isConstTableItem(value)) {
701 return false;
702 }
703 }
704 return true;
705 }
706
707 bool isConstTable(TableBlockIndent_t* table) {
708 for (auto value : table->values.objects()) {
709 if (!isConstTableItem(value)) {
710 return false;
711 }
712 }
713 return true;
714 }
715
716 bool isConstChainValue(ChainValue_t* value) {
717 auto var = singleVariableFrom(value, AccessType::None);
718 return isLocal(var);
719 }
720
721 bool isConstUnaryValue(UnaryValue_t* value) {
722 if (value->ops.size() > 1) {
723 return false;
724 }
725 auto unaryStr = _parser.toString(value->ops.front());
726 if (unaryStr == "-"sv) {
727 return value->value->item->get_by_path<SimpleValue_t, Num_t>();
728 } else if (unaryStr == "#"sv) {
729 return false;
730 } else if (unaryStr == "not"sv) {
731 return isConstValue(value->value);
732 }
733 return false;
734 }
735
736 bool isConstNum(Value_t* value) {
737 return value->get_by_path<SimpleValue_t, Num_t>();
738 }
739
740 bool isConstUnaryExp(UnaryExp_t* value) {
741 if (value->inExp) return false;
742 if (value->ops.size() == 0) {
743 if (value->expos.size() == 1) {
744 return isConstValue(static_cast<Value_t*>(value->expos.front()));
745 }
746 for (auto expo : value->expos.objects()) {
747 if (!isConstNum(static_cast<Value_t*>(expo))) {
748 return false;
749 }
750 }
751 return true;
752 }
753 if (value->ops.size() > 1) {
754 return false;
755 }
756 auto unaryStr = _parser.toString(value->ops.front());
757 if (unaryStr == "-"sv) {
758 for (auto expo : value->expos.objects()) {
759 if (!isConstNum(static_cast<Value_t*>(expo))) {
760 return false;
761 }
762 }
763 return true;
764 } else if (unaryStr == "#"sv) {
765 return false;
766 } else if (unaryStr == "not"sv) {
767 if (value->expos.size() == 1) {
768 return isConstValue(static_cast<Value_t*>(value->expos.front()));
769 }
770 for (auto expo : value->expos.objects()) {
771 if (!isConstNum(static_cast<Value_t*>(expo))) {
772 return false;
773 }
774 }
775 return true;
776 }
777 return false;
778 }
779
780 bool isConstValue(Value_t* value) {
781 if (auto strNode = value->item.as<String_t>()) {
782 switch (strNode->str->get_id()) {
783 case id<SingleString_t>():
784 case id<LuaString_t>():
785 return true;
786 case id<DoubleString_t>():
787 return false;
788 default:
789 YUEE("AST node mismatch", strNode->str);
790 return false;
791 }
792 } else if (auto chainValue = value->item.as<ChainValue_t>()) {
793 return isConstChainValue(chainValue);
794 } else if (auto simpleValue = value->item.as<SimpleValue_t>()) {
795 if (ast_is<ConstValue_t, Num_t, VarArg_t, FunLit_t>(simpleValue->value.get())) {
796 return true;
797 } else if (auto uValue = simpleValue->value.as<UnaryValue_t>()) {
798 return isConstUnaryValue(uValue);
799 } else if (auto comp = simpleValue->value.as<Comprehension_t>()) {
800 for (auto item : comp->items.objects()) {
801 if (auto ndef = ast_cast<NormalDef_t>(item)) {
802 if (ndef->defVal) {
803 return false;
804 }
805 if (!isConstExp(ndef->item)) {
806 return false;
807 }
808 } else {
809 return false;
810 }
811 }
812 return true;
813 } else if (auto tableLit = simpleValue->value.as<TableLit_t>()) {
814 return isConstTable(tableLit);
815 } else {
816 return false;
817 }
818 } else if (auto simpleTable = value->item.as<SimpleTable_t>()) {
819 return isConstTable(simpleTable);
820 }
821 return false;
822 }
823
824 bool isConstUnaryExps(const ast_list<true, UnaryExp_t>& list) {
825 if (list.size() > 1) {
826 return false;
827 }
828 if (!isConstUnaryExp(static_cast<UnaryExp_t*>(list.front()))) {
829 return false;
830 }
831 return true;
832 }
833
834 bool isConstExp(Exp_t* exp) {
835 if (exp->nilCoalesed) {
836 return false;
837 }
838 if (!isConstUnaryExps(exp->pipeExprs)) {
839 return false;
840 }
841 if (exp->opValues.empty()) {
842 return true;
843 }
844 return false;
845 }
846
580 void markVarConst(const std::string& name) { 847 void markVarConst(const std::string& name) {
581 auto& scope = _scopes.back(); 848 auto& scope = _scopes.back();
582 scope.vars->insert_or_assign(name, VarType::Const); 849 scope.vars->insert_or_assign(name, VarType::Const);
@@ -3691,7 +3958,7 @@ private:
3691 }) != traversal::Stop; 3958 }) != traversal::Stop;
3692 } 3959 }
3693 3960
3694 std::optional<std::pair<std::string, str_list>> getUpValueFuncFromBlock(Block_t* block, str_list* ensureArgListInTheEnd) { 3961 std::optional<std::pair<std::string, str_list>> getUpValueFuncFromBlock(Block_t* block, str_list* ensureArgListInTheEnd, bool noGlobalVarPassing) {
3695 if (_funcLevel <= 1) return std::nullopt; 3962 if (_funcLevel <= 1) return std::nullopt;
3696 auto result = block->traverse([&](ast_node* node) { 3963 auto result = block->traverse([&](ast_node* node) {
3697 switch (node->get_id()) { 3964 switch (node->get_id()) {
@@ -3754,6 +4021,9 @@ private:
3754 } else if (std::find(args.begin(), args.end(), global.name) == args.end()) { 4021 } else if (std::find(args.begin(), args.end(), global.name) == args.end()) {
3755 args.push_back(global.name); 4022 args.push_back(global.name);
3756 } 4023 }
4024 if (noGlobalVarPassing && !isLocal(global.name)) {
4025 return std::nullopt;
4026 }
3757 } 4027 }
3758 } 4028 }
3759 } 4029 }
@@ -3809,9 +4079,9 @@ private:
3809 } 4079 }
3810 4080
3811 4081
3812 std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Block_t* block, str_list* ensureArgListInTheEnd = nullptr) { 4082 std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Block_t* block, str_list* ensureArgListInTheEnd = nullptr, bool noGlobalVarPassing = false) {
3813 if (checkUpValueFuncAvailable(block)) { 4083 if (checkUpValueFuncAvailable(block)) {
3814 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd); 4084 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, noGlobalVarPassing);
3815 } 4085 }
3816 return std::nullopt; 4086 return std::nullopt;
3817 } 4087 }
@@ -3826,7 +4096,7 @@ private:
3826 auto stmt = exp->new_ptr<Statement_t>(); 4096 auto stmt = exp->new_ptr<Statement_t>();
3827 stmt->content.set(returnNode); 4097 stmt->content.set(returnNode);
3828 block->statements.push_back(stmt); 4098 block->statements.push_back(stmt);
3829 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd); 4099 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false);
3830 } 4100 }
3831 return std::nullopt; 4101 return std::nullopt;
3832 } 4102 }
@@ -9135,23 +9405,47 @@ private:
9135 BREAK_IF(var.empty()); 9405 BREAK_IF(var.empty());
9136 tryFunc.set(expListAssign->expList->exprs.front()); 9406 tryFunc.set(expListAssign->expList->exprs.front());
9137 BLOCK_END 9407 BLOCK_END
9138 } else { 9408 }
9139 auto tryExp = tryFunc.as<Exp_t>(); 9409 if (auto tryExp = tryFunc.as<Exp_t>()) {
9140 bool needWrap = singleVariableFrom(tryExp, AccessType::None).empty(); 9410 bool wrapped = true;
9141 BLOCK_START 9411 BLOCK_START
9142 auto value = singleValueFrom(tryExp); 9412 auto value = singleValueFrom(tryExp);
9143 BREAK_IF(!value); 9413 BREAK_IF(!value);
9144 auto chainValue = value->item.as<ChainValue_t>(); 9414 auto chainValue = value->item.as<ChainValue_t>();
9145 BREAK_IF(!chainValue); 9415 BREAK_IF(!chainValue);
9146 BREAK_IF(!isChainValueCall(chainValue)); 9416 BREAK_IF(!isChainValueCall(chainValue));
9147 auto tmpChain = chainValue->new_ptr<ChainValue_t>(); 9417 auto chainCaller = chainValue->new_ptr<ChainValue_t>();
9148 tmpChain->items.dup(chainValue->items); 9418 chainCaller->items.dup(chainValue->items);
9149 tmpChain->items.pop_back(); 9419 chainCaller->items.pop_back();
9150 auto var = singleVariableFrom(tmpChain, AccessType::None); 9420 BREAK_IF(!isConstChainValue(chainCaller));
9151 BREAK_IF(var.empty()); 9421 _ast_list* args = nullptr;
9152 needWrap = false; 9422 if (auto invoke = ast_cast<InvokeArgs_t>(chainValue->items.back())) {
9423 args = &invoke->args;
9424 } else {
9425 args = &(ast_to<Invoke_t>(chainValue->items.back())->args);
9426 }
9427 wrapped = false;
9428 for (auto arg : args->objects()) {
9429 switch (arg->get_id()) {
9430 case id<Exp_t>():
9431 if (isConstExp(static_cast<Exp_t*>(arg))) continue;
9432 break;
9433 case id<SingleString_t>():
9434 case id<LuaString_t>():
9435 continue;
9436 case id<DoubleString_t>():
9437 break;
9438 case id<TableLit_t>():
9439 if (isConstTable(static_cast<TableLit_t*>(arg))) continue;
9440 break;
9441 case id<TableBlock_t>():
9442 if (isConstTable(static_cast<TableBlock_t*>(arg))) continue;
9443 break;
9444 }
9445 wrapped = true;
9446 }
9153 BLOCK_END 9447 BLOCK_END
9154 if (needWrap) { 9448 if (wrapped) {
9155 auto expList = x->new_ptr<ExpList_t>(); 9449 auto expList = x->new_ptr<ExpList_t>();
9156 expList->exprs.push_back(tryFunc); 9450 expList->exprs.push_back(tryFunc);
9157 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 9451 auto expListAssign = x->new_ptr<ExpListAssign_t>();
@@ -9165,7 +9459,7 @@ private:
9165 } 9459 }
9166 if (auto tryBlock = tryFunc.as<Block_t>()) { 9460 if (auto tryBlock = tryFunc.as<Block_t>()) {
9167 if (getLuaTarget(tryBlock) >= 502 || !errHandler) { 9461 if (getLuaTarget(tryBlock) >= 502 || !errHandler) {
9168 if (auto result = upValueFuncFrom(tryBlock)) { 9462 if (auto result = upValueFuncFrom(tryBlock, nullptr, true)) {
9169 auto [funcName, args] = std::move(*result); 9463 auto [funcName, args] = std::move(*result);
9170 if (errHandler) { 9464 if (errHandler) {
9171 auto xpcall = toAst<ChainValue_t>("xpcall()", x); 9465 auto xpcall = toAst<ChainValue_t>("xpcall()", x);