summaryrefslogtreecommitdiff
path: root/testes/closure.lua
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-12-17 14:46:37 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-12-17 14:46:37 -0200
commit063d4e4543088e7a21965bda8ee5a0f952a9029e (patch)
tree6c3f2f8e98c26f071a94a32f9f2754396a66a9de /testes/closure.lua
parente354c6355e7f48e087678ec49e340ca0696725b1 (diff)
downloadlua-5.3.5.tar.gz
lua-5.3.5.tar.bz2
lua-5.3.5.zip
Lua 5.3.5 ported to gitv5.3.5
This is the first commit for the branch Lua 5.3. All source files were copied from the official distribution of 5.3.5 in the Lua site. The test files are the same of 5.3.4. The manual came from the previous RCS repository, revision 1.167.1.2.
Diffstat (limited to '')
-rw-r--r--testes/closure.lua247
1 files changed, 247 insertions, 0 deletions
diff --git a/testes/closure.lua b/testes/closure.lua
new file mode 100644
index 00000000..15897ae6
--- /dev/null
+++ b/testes/closure.lua
@@ -0,0 +1,247 @@
1-- $Id: closure.lua,v 1.59 2016/11/07 13:11:28 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 = {}
47for i = 1, 5 do a[i] = function (x) return x + a + _ENV end end
48assert(a[3] == a[4] and a[4] == a[5])
49
50for i = 1, 5 do a[i] = function (x) return i + a + _ENV end end
51assert(a[3] ~= a[4] and a[4] ~= a[5])
52
53local function f()
54 return function (x) return math.sin(_ENV[x]) end
55end
56assert(f() == f())
57
58
59-- testing closures with 'for' control variable
60a = {}
61for i=1,10 do
62 a[i] = {set = function(x) i=x end, get = function () return i end}
63 if i == 3 then break end
64end
65assert(a[4] == nil)
66a[1].set(10)
67assert(a[2].get() == 2)
68a[2].set('a')
69assert(a[3].get() == 3)
70assert(a[2].get() == 'a')
71
72a = {}
73local t = {"a", "b"}
74for i = 1, #t do
75 local k = t[i]
76 a[i] = {set = function(x, y) i=x; k=y end,
77 get = function () return i, k end}
78 if i == 2 then break end
79end
80a[1].set(10, 20)
81local r,s = a[2].get()
82assert(r == 2 and s == 'b')
83r,s = a[1].get()
84assert(r == 10 and s == 20)
85a[2].set('a', 'b')
86r,s = a[2].get()
87assert(r == "a" and s == "b")
88
89
90-- testing closures with 'for' control variable x break
91for i=1,3 do
92 f = function () return i end
93 break
94end
95assert(f() == 1)
96
97for k = 1, #t do
98 local v = t[k]
99 f = function () return k, v end
100 break
101end
102assert(({f()})[1] == 1)
103assert(({f()})[2] == "a")
104
105
106-- testing closure x break x return x errors
107
108local b
109function f(x)
110 local first = 1
111 while 1 do
112 if x == 3 and not first then return end
113 local a = 'xuxu'
114 b = function (op, y)
115 if op == 'set' then
116 a = x+y
117 else
118 return a
119 end
120 end
121 if x == 1 then do break end
122 elseif x == 2 then return
123 else if x ~= 3 then error() end
124 end
125 first = nil
126 end
127end
128
129for i=1,3 do
130 f(i)
131 assert(b('get') == 'xuxu')
132 b('set', 10); assert(b('get') == 10+i)
133 b = nil
134end
135
136pcall(f, 4);
137assert(b('get') == 'xuxu')
138b('set', 10); assert(b('get') == 14)
139
140
141local w
142-- testing multi-level closure
143function f(x)
144 return function (y)
145 return function (z) return w+x+y+z end
146 end
147end
148
149y = f(10)
150w = 1.345
151assert(y(20)(30) == 60+w)
152
153-- testing closures x repeat-until
154
155local a = {}
156local i = 1
157repeat
158 local x = i
159 a[i] = function () i = x+1; return x end
160until i > 10 or a[i]() ~= x
161assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4)
162
163
164-- testing closures created in 'then' and 'else' parts of 'if's
165a = {}
166for i = 1, 10 do
167 if i % 3 == 0 then
168 local y = 0
169 a[i] = function (x) local t = y; y = x; return t end
170 elseif i % 3 == 1 then
171 goto L1
172 error'not here'
173 ::L1::
174 local y = 1
175 a[i] = function (x) local t = y; y = x; return t end
176 elseif i % 3 == 2 then
177 local t
178 goto l4
179 ::l4a:: a[i] = t; goto l4b
180 error("should never be here!")
181 ::l4::
182 local y = 2
183 t = function (x) local t = y; y = x; return t end
184 goto l4a
185 error("should never be here!")
186 ::l4b::
187 end
188end
189
190for i = 1, 10 do
191 assert(a[i](i * 10) == i % 3 and a[i]() == i * 10)
192end
193
194print'+'
195
196
197-- test for correctly closing upvalues in tail calls of vararg functions
198local function t ()
199 local function c(a,b) assert(a=="test" and b=="OK") end
200 local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end
201 local x = 1
202 return v(function() return x end)
203end
204t()
205
206
207-- test for debug manipulation of upvalues
208local debug = require'debug'
209
210do
211 local a , b, c = 3, 5, 7
212 foo1 = function () return a+b end;
213 foo2 = function () return b+a end;
214 do
215 local a = 10
216 foo3 = function () return a+b end;
217 end
218end
219
220assert(debug.upvalueid(foo1, 1))
221assert(debug.upvalueid(foo1, 2))
222assert(not pcall(debug.upvalueid, foo1, 3))
223assert(debug.upvalueid(foo1, 1) == debug.upvalueid(foo2, 2))
224assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo2, 1))
225assert(debug.upvalueid(foo3, 1))
226assert(debug.upvalueid(foo1, 1) ~= debug.upvalueid(foo3, 1))
227assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo3, 2))
228
229assert(debug.upvalueid(string.gmatch("x", "x"), 1) ~= nil)
230
231assert(foo1() == 3 + 5 and foo2() == 5 + 3)
232debug.upvaluejoin(foo1, 2, foo2, 2)
233assert(foo1() == 3 + 3 and foo2() == 5 + 3)
234assert(foo3() == 10 + 5)
235debug.upvaluejoin(foo3, 2, foo2, 1)
236assert(foo3() == 10 + 5)
237debug.upvaluejoin(foo3, 2, foo2, 2)
238assert(foo3() == 10 + 3)
239
240assert(not pcall(debug.upvaluejoin, foo1, 3, foo2, 1))
241assert(not pcall(debug.upvaluejoin, foo1, 1, foo2, 3))
242assert(not pcall(debug.upvaluejoin, foo1, 0, foo2, 1))
243assert(not pcall(debug.upvaluejoin, print, 1, foo2, 1))
244assert(not pcall(debug.upvaluejoin, {}, 1, foo2, 1))
245assert(not pcall(debug.upvaluejoin, foo1, 1, print, 1))
246
247print'OK'