aboutsummaryrefslogtreecommitdiff
path: root/testes/closure.lua
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testes/closure.lua271
1 files changed, 271 insertions, 0 deletions
diff --git a/testes/closure.lua b/testes/closure.lua
new file mode 100644
index 00000000..79da3cc0
--- /dev/null
+++ b/testes/closure.lua
@@ -0,0 +1,271 @@
1-- $Id: closure.lua,v 1.62 2018/03/12 14:19:36 roberto Exp $
2-- See Copyright Notice in file all.lua
3
4print "testing closures"
5
6local A,B = 0,{g=10}
7function f(x)
8 local a = {}
9 for i=1,1000 do
10 local y = 0
11 do
12 a[i] = function () B.g = B.g+1; y = y+x; return y+A end
13 end
14 end
15 local dummy = function () return a[A] end
16 collectgarbage()
17 A = 1; assert(dummy() == a[1]); A = 0;
18 assert(a[1]() == x)
19 assert(a[3]() == x)
20 collectgarbage()
21 assert(B.g == 12)
22 return a
23end
24
25local a = f(10)
26-- force a GC in this level
27local x = {[1] = {}} -- to detect a GC
28setmetatable(x, {__mode = 'kv'})
29while x[1] do -- repeat until GC
30 local a = A..A..A..A -- create garbage
31 A = A+1
32end
33assert(a[1]() == 20+A)
34assert(a[1]() == 30+A)
35assert(a[2]() == 10+A)
36collectgarbage()
37assert(a[2]() == 20+A)
38assert(a[2]() == 30+A)
39assert(a[3]() == 20+A)
40assert(a[8]() == 10+A)
41assert(getmetatable(x).__mode == 'kv')
42assert(B.g == 19)
43
44
45-- testing equality
46a = {}
47collectgarbage"stop"
48for i = 1, 5 do a[i] = function (x) return x + a + _ENV end end
49collectgarbage"restart"
50assert(a[3] == a[4] and a[4] == a[5])
51
52for i = 1, 5 do a[i] = function (x) return i + a + _ENV end end
53assert(a[3] ~= a[4] and a[4] ~= a[5])
54
55local function f()
56 return function (x) return math.sin(_ENV[x]) end
57end
58assert(f() == f())
59
60
61-- testing closures with 'for' control variable
62a = {}
63for i=1,10 do
64 a[i] = {set = function(x) i=x end, get = function () return i end}
65 if i == 3 then break end
66end
67assert(a[4] == undef)
68a[1].set(10)
69assert(a[2].get() == 2)
70a[2].set('a')
71assert(a[3].get() == 3)
72assert(a[2].get() == 'a')
73
74a = {}
75local t = {"a", "b"}
76for i = 1, #t do
77 local k = t[i]
78 a[i] = {set = function(x, y) i=x; k=y end,
79 get = function () return i, k end}
80 if i == 2 then break end
81end
82a[1].set(10, 20)
83local r,s = a[2].get()
84assert(r == 2 and s == 'b')
85r,s = a[1].get()
86assert(r == 10 and s == 20)
87a[2].set('a', 'b')
88r,s = a[2].get()
89assert(r == "a" and s == "b")
90
91
92-- testing closures with 'for' control variable x break
93for i=1,3 do
94 f = function () return i end
95 break
96end
97assert(f() == 1)
98
99for k = 1, #t do
100 local v = t[k]
101 f = function () return k, v end
102 break
103end
104assert(({f()})[1] == 1)
105assert(({f()})[2] == "a")
106
107
108-- testing closure x break x return x errors
109
110local b
111function f(x)
112 local first = 1
113 while 1 do
114 if x == 3 and not first then return end
115 local a = 'xuxu'
116 b = function (op, y)
117 if op == 'set' then
118 a = x+y
119 else
120 return a
121 end
122 end
123 if x == 1 then do break end
124 elseif x == 2 then return
125 else if x ~= 3 then error() end
126 end
127 first = nil
128 end
129end
130
131for i=1,3 do
132 f(i)
133 assert(b('get') == 'xuxu')
134 b('set', 10); assert(b('get') == 10+i)
135 b = nil
136end
137
138pcall(f, 4);
139assert(b('get') == 'xuxu')
140b('set', 10); assert(b('get') == 14)
141
142
143local w
144-- testing multi-level closure
145function f(x)
146 return function (y)
147 return function (z) return w+x+y+z end
148 end
149end
150
151y = f(10)
152w = 1.345
153assert(y(20)(30) == 60+w)
154
155
156-- testing closures x break
157do
158 local X, Y
159 local a = math.sin(0)
160
161 while a do
162 local b = 10
163 X = function () return b end -- closure with upvalue
164 if a then break end
165 end
166
167 do
168 local b = 20
169 Y = function () return b end -- closure with upvalue
170 end
171
172 -- upvalues must be different
173 assert(X() == 10 and Y() == 20)
174end
175
176
177-- testing closures x repeat-until
178
179local a = {}
180local i = 1
181repeat
182 local x = i
183 a[i] = function () i = x+1; return x end
184until i > 10 or a[i]() ~= x
185assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4)
186
187
188-- testing closures created in 'then' and 'else' parts of 'if's
189a = {}
190for i = 1, 10 do
191 if i % 3 == 0 then
192 local y = 0
193 a[i] = function (x) local t = y; y = x; return t end
194 elseif i % 3 == 1 then
195 goto L1
196 error'not here'
197 ::L1::
198 local y = 1
199 a[i] = function (x) local t = y; y = x; return t end
200 elseif i % 3 == 2 then
201 local t
202 goto l4
203 ::l4a:: a[i] = t; goto l4b
204 error("should never be here!")
205 ::l4::
206 local y = 2
207 t = function (x) local t = y; y = x; return t end
208 goto l4a
209 error("should never be here!")
210 ::l4b::
211 end
212end
213
214for i = 1, 10 do
215 assert(a[i](i * 10) == i % 3 and a[i]() == i * 10)
216end
217
218print'+'
219
220
221-- test for correctly closing upvalues in tail calls of vararg functions
222local function t ()
223 local function c(a,b) assert(a=="test" and b=="OK") end
224 local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end
225 local x = 1
226 return v(function() return x end)
227end
228t()
229
230
231-- test for debug manipulation of upvalues
232local debug = require'debug'
233
234do
235 local a , b, c = 3, 5, 7
236 foo1 = function () return a+b end;
237 foo2 = function () return b+a end;
238 do
239 local a = 10
240 foo3 = function () return a+b end;
241 end
242end
243
244assert(debug.upvalueid(foo1, 1))
245assert(debug.upvalueid(foo1, 2))
246assert(not pcall(debug.upvalueid, foo1, 3))
247assert(debug.upvalueid(foo1, 1) == debug.upvalueid(foo2, 2))
248assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo2, 1))
249assert(debug.upvalueid(foo3, 1))
250assert(debug.upvalueid(foo1, 1) ~= debug.upvalueid(foo3, 1))
251assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo3, 2))
252
253assert(debug.upvalueid(string.gmatch("x", "x"), 1) ~= nil)
254
255assert(foo1() == 3 + 5 and foo2() == 5 + 3)
256debug.upvaluejoin(foo1, 2, foo2, 2)
257assert(foo1() == 3 + 3 and foo2() == 5 + 3)
258assert(foo3() == 10 + 5)
259debug.upvaluejoin(foo3, 2, foo2, 1)
260assert(foo3() == 10 + 5)
261debug.upvaluejoin(foo3, 2, foo2, 2)
262assert(foo3() == 10 + 3)
263
264assert(not pcall(debug.upvaluejoin, foo1, 3, foo2, 1))
265assert(not pcall(debug.upvaluejoin, foo1, 1, foo2, 3))
266assert(not pcall(debug.upvaluejoin, foo1, 0, foo2, 1))
267assert(not pcall(debug.upvaluejoin, print, 1, foo2, 1))
268assert(not pcall(debug.upvaluejoin, {}, 1, foo2, 1))
269assert(not pcall(debug.upvaluejoin, foo1, 1, print, 1))
270
271print'OK'