diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-17 14:46:37 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-17 14:46:37 -0200 |
commit | 063d4e4543088e7a21965bda8ee5a0f952a9029e (patch) | |
tree | 6c3f2f8e98c26f071a94a32f9f2754396a66a9de /testes/calls.lua | |
parent | e354c6355e7f48e087678ec49e340ca0696725b1 (diff) | |
download | lua-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 'testes/calls.lua')
-rw-r--r-- | testes/calls.lua | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/testes/calls.lua b/testes/calls.lua new file mode 100644 index 00000000..6d6fb7b2 --- /dev/null +++ b/testes/calls.lua | |||
@@ -0,0 +1,401 @@ | |||
1 | -- $Id: calls.lua,v 1.60 2016/11/07 13:11:28 roberto Exp $ | ||
2 | -- See Copyright Notice in file all.lua | ||
3 | |||
4 | print("testing functions and calls") | ||
5 | |||
6 | local debug = require "debug" | ||
7 | |||
8 | -- get the opportunity to test 'type' too ;) | ||
9 | |||
10 | assert(type(1<2) == 'boolean') | ||
11 | assert(type(true) == 'boolean' and type(false) == 'boolean') | ||
12 | assert(type(nil) == 'nil' | ||
13 | and type(-3) == 'number' | ||
14 | and type'x' == 'string' | ||
15 | and type{} == 'table' | ||
16 | and type(type) == 'function') | ||
17 | |||
18 | assert(type(assert) == type(print)) | ||
19 | function f (x) return a:x (x) end | ||
20 | assert(type(f) == 'function') | ||
21 | assert(not pcall(type)) | ||
22 | |||
23 | |||
24 | do -- test error in 'print' too... | ||
25 | local tostring = _ENV.tostring | ||
26 | |||
27 | _ENV.tostring = nil | ||
28 | local st, msg = pcall(print, 1) | ||
29 | assert(st == false and string.find(msg, "attempt to call a nil value")) | ||
30 | |||
31 | _ENV.tostring = function () return {} end | ||
32 | local st, msg = pcall(print, 1) | ||
33 | assert(st == false and string.find(msg, "must return a string")) | ||
34 | |||
35 | _ENV.tostring = tostring | ||
36 | end | ||
37 | |||
38 | |||
39 | -- testing local-function recursion | ||
40 | fact = false | ||
41 | do | ||
42 | local res = 1 | ||
43 | local function fact (n) | ||
44 | if n==0 then return res | ||
45 | else return n*fact(n-1) | ||
46 | end | ||
47 | end | ||
48 | assert(fact(5) == 120) | ||
49 | end | ||
50 | assert(fact == false) | ||
51 | |||
52 | -- testing declarations | ||
53 | a = {i = 10} | ||
54 | self = 20 | ||
55 | function a:x (x) return x+self.i end | ||
56 | function a.y (x) return x+self end | ||
57 | |||
58 | assert(a:x(1)+10 == a.y(1)) | ||
59 | |||
60 | a.t = {i=-100} | ||
61 | a["t"].x = function (self, a,b) return self.i+a+b end | ||
62 | |||
63 | assert(a.t:x(2,3) == -95) | ||
64 | |||
65 | do | ||
66 | local a = {x=0} | ||
67 | function a:add (x) self.x, a.y = self.x+x, 20; return self end | ||
68 | assert(a:add(10):add(20):add(30).x == 60 and a.y == 20) | ||
69 | end | ||
70 | |||
71 | local a = {b={c={}}} | ||
72 | |||
73 | function a.b.c.f1 (x) return x+1 end | ||
74 | function a.b.c:f2 (x,y) self[x] = y end | ||
75 | assert(a.b.c.f1(4) == 5) | ||
76 | a.b.c:f2('k', 12); assert(a.b.c.k == 12) | ||
77 | |||
78 | print('+') | ||
79 | |||
80 | t = nil -- 'declare' t | ||
81 | function f(a,b,c) local d = 'a'; t={a,b,c,d} end | ||
82 | |||
83 | f( -- this line change must be valid | ||
84 | 1,2) | ||
85 | assert(t[1] == 1 and t[2] == 2 and t[3] == nil and t[4] == 'a') | ||
86 | f(1,2, -- this one too | ||
87 | 3,4) | ||
88 | assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a') | ||
89 | |||
90 | function fat(x) | ||
91 | if x <= 1 then return 1 | ||
92 | else return x*load("return fat(" .. x-1 .. ")", "")() | ||
93 | end | ||
94 | end | ||
95 | |||
96 | assert(load "load 'assert(fat(6)==720)' () ")() | ||
97 | a = load('return fat(5), 3') | ||
98 | a,b = a() | ||
99 | assert(a == 120 and b == 3) | ||
100 | print('+') | ||
101 | |||
102 | function err_on_n (n) | ||
103 | if n==0 then error(); exit(1); | ||
104 | else err_on_n (n-1); exit(1); | ||
105 | end | ||
106 | end | ||
107 | |||
108 | do | ||
109 | function dummy (n) | ||
110 | if n > 0 then | ||
111 | assert(not pcall(err_on_n, n)) | ||
112 | dummy(n-1) | ||
113 | end | ||
114 | end | ||
115 | end | ||
116 | |||
117 | dummy(10) | ||
118 | |||
119 | function deep (n) | ||
120 | if n>0 then deep(n-1) end | ||
121 | end | ||
122 | deep(10) | ||
123 | deep(200) | ||
124 | |||
125 | -- testing tail call | ||
126 | function deep (n) if n>0 then return deep(n-1) else return 101 end end | ||
127 | assert(deep(30000) == 101) | ||
128 | a = {} | ||
129 | function a:deep (n) if n>0 then return self:deep(n-1) else return 101 end end | ||
130 | assert(a:deep(30000) == 101) | ||
131 | |||
132 | print('+') | ||
133 | |||
134 | |||
135 | a = nil | ||
136 | (function (x) a=x end)(23) | ||
137 | assert(a == 23 and (function (x) return x*2 end)(20) == 40) | ||
138 | |||
139 | |||
140 | -- testing closures | ||
141 | |||
142 | -- fixed-point operator | ||
143 | Z = function (le) | ||
144 | local function a (f) | ||
145 | return le(function (x) return f(f)(x) end) | ||
146 | end | ||
147 | return a(a) | ||
148 | end | ||
149 | |||
150 | |||
151 | -- non-recursive factorial | ||
152 | |||
153 | F = function (f) | ||
154 | return function (n) | ||
155 | if n == 0 then return 1 | ||
156 | else return n*f(n-1) end | ||
157 | end | ||
158 | end | ||
159 | |||
160 | fat = Z(F) | ||
161 | |||
162 | assert(fat(0) == 1 and fat(4) == 24 and Z(F)(5)==5*Z(F)(4)) | ||
163 | |||
164 | local function g (z) | ||
165 | local function f (a,b,c,d) | ||
166 | return function (x,y) return a+b+c+d+a+x+y+z end | ||
167 | end | ||
168 | return f(z,z+1,z+2,z+3) | ||
169 | end | ||
170 | |||
171 | f = g(10) | ||
172 | assert(f(9, 16) == 10+11+12+13+10+9+16+10) | ||
173 | |||
174 | Z, F, f = nil | ||
175 | print('+') | ||
176 | |||
177 | -- testing multiple returns | ||
178 | |||
179 | function unlpack (t, i) | ||
180 | i = i or 1 | ||
181 | if (i <= #t) then | ||
182 | return t[i], unlpack(t, i+1) | ||
183 | end | ||
184 | end | ||
185 | |||
186 | function equaltab (t1, t2) | ||
187 | assert(#t1 == #t2) | ||
188 | for i = 1, #t1 do | ||
189 | assert(t1[i] == t2[i]) | ||
190 | end | ||
191 | end | ||
192 | |||
193 | local pack = function (...) return (table.pack(...)) end | ||
194 | |||
195 | function f() return 1,2,30,4 end | ||
196 | function ret2 (a,b) return a,b end | ||
197 | |||
198 | local a,b,c,d = unlpack{1,2,3} | ||
199 | assert(a==1 and b==2 and c==3 and d==nil) | ||
200 | a = {1,2,3,4,false,10,'alo',false,assert} | ||
201 | equaltab(pack(unlpack(a)), a) | ||
202 | equaltab(pack(unlpack(a), -1), {1,-1}) | ||
203 | a,b,c,d = ret2(f()), ret2(f()) | ||
204 | assert(a==1 and b==1 and c==2 and d==nil) | ||
205 | a,b,c,d = unlpack(pack(ret2(f()), ret2(f()))) | ||
206 | assert(a==1 and b==1 and c==2 and d==nil) | ||
207 | a,b,c,d = unlpack(pack(ret2(f()), (ret2(f())))) | ||
208 | assert(a==1 and b==1 and c==nil and d==nil) | ||
209 | |||
210 | a = ret2{ unlpack{1,2,3}, unlpack{3,2,1}, unlpack{"a", "b"}} | ||
211 | assert(a[1] == 1 and a[2] == 3 and a[3] == "a" and a[4] == "b") | ||
212 | |||
213 | |||
214 | -- testing calls with 'incorrect' arguments | ||
215 | rawget({}, "x", 1) | ||
216 | rawset({}, "x", 1, 2) | ||
217 | assert(math.sin(1,2) == math.sin(1)) | ||
218 | table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a<b end, "extra arg") | ||
219 | |||
220 | |||
221 | -- test for generic load | ||
222 | local x = "-- a comment\0\0\0\n x = 10 + \n23; \ | ||
223 | local a = function () x = 'hi' end; \ | ||
224 | return '\0'" | ||
225 | function read1 (x) | ||
226 | local i = 0 | ||
227 | return function () | ||
228 | collectgarbage() | ||
229 | i=i+1 | ||
230 | return string.sub(x, i, i) | ||
231 | end | ||
232 | end | ||
233 | |||
234 | function cannotload (msg, a,b) | ||
235 | assert(not a and string.find(b, msg)) | ||
236 | end | ||
237 | |||
238 | a = assert(load(read1(x), "modname", "t", _G)) | ||
239 | assert(a() == "\0" and _G.x == 33) | ||
240 | assert(debug.getinfo(a).source == "modname") | ||
241 | -- cannot read text in binary mode | ||
242 | cannotload("attempt to load a text chunk", load(read1(x), "modname", "b", {})) | ||
243 | cannotload("attempt to load a text chunk", load(x, "modname", "b")) | ||
244 | |||
245 | a = assert(load(function () return nil end)) | ||
246 | a() -- empty chunk | ||
247 | |||
248 | assert(not load(function () return true end)) | ||
249 | |||
250 | |||
251 | -- small bug | ||
252 | local t = {nil, "return ", "3"} | ||
253 | f, msg = load(function () return table.remove(t, 1) end) | ||
254 | assert(f() == nil) -- should read the empty chunk | ||
255 | |||
256 | -- another small bug (in 5.2.1) | ||
257 | f = load(string.dump(function () return 1 end), nil, "b", {}) | ||
258 | assert(type(f) == "function" and f() == 1) | ||
259 | |||
260 | |||
261 | x = string.dump(load("x = 1; return x")) | ||
262 | a = assert(load(read1(x), nil, "b")) | ||
263 | assert(a() == 1 and _G.x == 1) | ||
264 | cannotload("attempt to load a binary chunk", load(read1(x), nil, "t")) | ||
265 | cannotload("attempt to load a binary chunk", load(x, nil, "t")) | ||
266 | |||
267 | assert(not pcall(string.dump, print)) -- no dump of C functions | ||
268 | |||
269 | cannotload("unexpected symbol", load(read1("*a = 123"))) | ||
270 | cannotload("unexpected symbol", load("*a = 123")) | ||
271 | cannotload("hhi", load(function () error("hhi") end)) | ||
272 | |||
273 | -- any value is valid for _ENV | ||
274 | assert(load("return _ENV", nil, nil, 123)() == 123) | ||
275 | |||
276 | |||
277 | -- load when _ENV is not first upvalue | ||
278 | local x; XX = 123 | ||
279 | local function h () | ||
280 | local y=x -- use 'x', so that it becomes 1st upvalue | ||
281 | return XX -- global name | ||
282 | end | ||
283 | local d = string.dump(h) | ||
284 | x = load(d, "", "b") | ||
285 | assert(debug.getupvalue(x, 2) == '_ENV') | ||
286 | debug.setupvalue(x, 2, _G) | ||
287 | assert(x() == 123) | ||
288 | |||
289 | assert(assert(load("return XX + ...", nil, nil, {XX = 13}))(4) == 17) | ||
290 | |||
291 | |||
292 | -- test generic load with nested functions | ||
293 | x = [[ | ||
294 | return function (x) | ||
295 | return function (y) | ||
296 | return function (z) | ||
297 | return x+y+z | ||
298 | end | ||
299 | end | ||
300 | end | ||
301 | ]] | ||
302 | |||
303 | a = assert(load(read1(x))) | ||
304 | assert(a()(2)(3)(10) == 15) | ||
305 | |||
306 | |||
307 | -- test for dump/undump with upvalues | ||
308 | local a, b = 20, 30 | ||
309 | x = load(string.dump(function (x) | ||
310 | if x == "set" then a = 10+b; b = b+1 else | ||
311 | return a | ||
312 | end | ||
313 | end), "", "b", nil) | ||
314 | assert(x() == nil) | ||
315 | assert(debug.setupvalue(x, 1, "hi") == "a") | ||
316 | assert(x() == "hi") | ||
317 | assert(debug.setupvalue(x, 2, 13) == "b") | ||
318 | assert(not debug.setupvalue(x, 3, 10)) -- only 2 upvalues | ||
319 | x("set") | ||
320 | assert(x() == 23) | ||
321 | x("set") | ||
322 | assert(x() == 24) | ||
323 | |||
324 | -- test for dump/undump with many upvalues | ||
325 | do | ||
326 | local nup = 200 -- maximum number of local variables | ||
327 | local prog = {"local a1"} | ||
328 | for i = 2, nup do prog[#prog + 1] = ", a" .. i end | ||
329 | prog[#prog + 1] = " = 1" | ||
330 | for i = 2, nup do prog[#prog + 1] = ", " .. i end | ||
331 | local sum = 1 | ||
332 | prog[#prog + 1] = "; return function () return a1" | ||
333 | for i = 2, nup do prog[#prog + 1] = " + a" .. i; sum = sum + i end | ||
334 | prog[#prog + 1] = " end" | ||
335 | prog = table.concat(prog) | ||
336 | local f = assert(load(prog))() | ||
337 | assert(f() == sum) | ||
338 | |||
339 | f = load(string.dump(f)) -- main chunk now has many upvalues | ||
340 | local a = 10 | ||
341 | local h = function () return a end | ||
342 | for i = 1, nup do | ||
343 | debug.upvaluejoin(f, i, h, 1) | ||
344 | end | ||
345 | assert(f() == 10 * nup) | ||
346 | end | ||
347 | |||
348 | -- test for long method names | ||
349 | do | ||
350 | local t = {x = 1} | ||
351 | function t:_012345678901234567890123456789012345678901234567890123456789 () | ||
352 | return self.x | ||
353 | end | ||
354 | assert(t:_012345678901234567890123456789012345678901234567890123456789() == 1) | ||
355 | end | ||
356 | |||
357 | |||
358 | -- test for bug in parameter adjustment | ||
359 | assert((function () return nil end)(4) == nil) | ||
360 | assert((function () local a; return a end)(4) == nil) | ||
361 | assert((function (a) return a end)() == nil) | ||
362 | |||
363 | |||
364 | print("testing binary chunks") | ||
365 | do | ||
366 | local header = string.pack("c4BBc6BBBBBj", | ||
367 | "\27Lua", -- signature | ||
368 | 5*16 + 3, -- version 5.3 | ||
369 | 0, -- format | ||
370 | "\x19\x93\r\n\x1a\n", -- data | ||
371 | string.packsize("i"), -- sizeof(int) | ||
372 | string.packsize("T"), -- sizeof(size_t) | ||
373 | 4, -- size of instruction | ||
374 | string.packsize("j"), -- sizeof(lua integer) | ||
375 | string.packsize("n"), -- sizeof(lua number) | ||
376 | 0x5678 -- LUAC_INT | ||
377 | -- LUAC_NUM may not have a unique binary representation (padding...) | ||
378 | ) | ||
379 | local c = string.dump(function () local a = 1; local b = 3; return a+b*3 end) | ||
380 | |||
381 | assert(string.sub(c, 1, #header) == header) | ||
382 | |||
383 | -- corrupted header | ||
384 | for i = 1, #header do | ||
385 | local s = string.sub(c, 1, i - 1) .. | ||
386 | string.char(string.byte(string.sub(c, i, i)) + 1) .. | ||
387 | string.sub(c, i + 1, -1) | ||
388 | assert(#s == #c) | ||
389 | assert(not load(s)) | ||
390 | end | ||
391 | |||
392 | -- loading truncated binary chunks | ||
393 | for i = 1, #c - 1 do | ||
394 | local st, msg = load(string.sub(c, 1, i)) | ||
395 | assert(not st and string.find(msg, "truncated")) | ||
396 | end | ||
397 | assert(assert(load(c))() == 10) | ||
398 | end | ||
399 | |||
400 | print('OK') | ||
401 | return deep | ||