aboutsummaryrefslogtreecommitdiff
path: root/testes/goto.lua
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testes/goto.lua170
1 files changed, 160 insertions, 10 deletions
diff --git a/testes/goto.lua b/testes/goto.lua
index eca68516..3310314d 100644
--- a/testes/goto.lua
+++ b/testes/goto.lua
@@ -1,6 +1,12 @@
1-- $Id: testes/goto.lua $ 1-- $Id: testes/goto.lua $
2-- See Copyright Notice in file lua.h 2-- See Copyright Notice in file lua.h
3 3
4global<const> require
5global<const> print, load, assert, string, setmetatable
6global<const> collectgarbage, error
7
8print("testing goto and global declarations")
9
4collectgarbage() 10collectgarbage()
5 11
6local function errmsg (code, m) 12local function errmsg (code, m)
@@ -17,15 +23,18 @@ errmsg([[ ::l1:: ::l1:: ]], "label 'l1'")
17errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'") 23errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'")
18 24
19 25
20-- undefined label
21errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'")
22 26
23-- jumping over variable definition 27-- jumping over variable declaration
28errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "scope of 'aa'")
29
30errmsg([[ goto l2; global *; ::l1:: ::l2:: print(3) ]], "scope of '*'")
31
24errmsg([[ 32errmsg([[
25do local bb, cc; goto l1; end 33do local bb, cc; goto l1; end
26local aa 34local aa
27::l1:: print(3) 35::l1:: print(3)
28]], "local 'aa'") 36]], "scope of 'aa'")
37
29 38
30-- jumping into a block 39-- jumping into a block
31errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'") 40errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'")
@@ -38,7 +47,7 @@ errmsg([[
38 local xuxu = 10 47 local xuxu = 10
39 ::cont:: 48 ::cont::
40 until xuxu < x 49 until xuxu < x
41]], "local 'xuxu'") 50]], "scope of 'xuxu'")
42 51
43-- simple gotos 52-- simple gotos
44local x 53local x
@@ -252,6 +261,8 @@ assert(testG(5) == 10)
252 261
253do -- test goto's around to-be-closed variable 262do -- test goto's around to-be-closed variable
254 263
264 global *
265
255 -- set 'var' and return an object that will reset 'var' when 266 -- set 'var' and return an object that will reset 'var' when
256 -- it goes out of scope 267 -- it goes out of scope
257 local function newobj (var) 268 local function newobj (var)
@@ -263,16 +274,16 @@ do -- test goto's around to-be-closed variable
263 274
264 goto L1 275 goto L1
265 276
266 ::L4:: assert(not X); goto L5 -- varX dead here 277 ::L4:: assert(not varX); goto L5 -- varX dead here
267 278
268 ::L1:: 279 ::L1::
269 local varX <close> = newobj("X") 280 local varX <close> = newobj("X")
270 assert(X); goto L2 -- varX alive here 281 assert(varX); goto L2 -- varX alive here
271 282
272 ::L3:: 283 ::L3::
273 assert(X); goto L4 -- varX alive here 284 assert(varX); goto L4 -- varX alive here
274 285
275 ::L2:: assert(X); goto L3 -- varX alive here 286 ::L2:: assert(varX); goto L3 -- varX alive here
276 287
277 ::L5:: -- return 288 ::L5:: -- return
278end 289end
@@ -280,7 +291,146 @@ end
280 291
281 292
282foo() 293foo()
283-------------------------------------------------------------------------------- 294--------------------------------------------------------------------------
295
296local function checkerr (code, err)
297 local st, msg = load(code)
298 assert(not st and string.find(msg, err))
299end
300
301do
302 global T<const>
303
304 -- globals must be declared, after a global declaration
305 checkerr("global none; X = 1", "variable 'X'")
306 checkerr("global none; function XX() end", "variable 'XX'")
284 307
308 -- global variables cannot be to-be-closed
309 checkerr("global X<close>", "cannot be")
310 checkerr("global <close> *", "cannot be")
311
312 do
313 local X = 10
314 do global X; X = 20 end
315 assert(X == 10) -- local X
316 end
317 assert(_ENV.X == 20) -- global X
318
319 -- '_ENV' cannot be global
320 checkerr("global _ENV, a; a = 10", "variable 'a'")
321
322 -- global declarations inside functions
323 checkerr([[
324 global none
325 local function foo () XXX = 1 end --< ERROR]], "variable 'XXX'")
326
327 if not T then -- when not in "test mode", "global" isn't reserved
328 assert(load("global = 1; return global")() == 1)
329 print " ('global' is not a reserved word)"
330 else
331 -- "global" reserved, cannot be used as a variable
332 assert(not load("global = 1; return global"))
333 end
334
335 local foo = 20
336 do
337 global function foo (x)
338 if x == 0 then return 1 else return 2 * foo(x - 1) end
339 end
340 assert(foo == _ENV.foo and foo(4) == 16)
341 end
342 assert(_ENV.foo(4) == 16)
343 assert(foo == 20) -- local one is in context here
344
345 do
346 global foo;
347 function foo (x) return end -- Ok after declaration
348 end
349
350 checkerr([[
351 global<const> foo;
352 function foo (x) return end -- ERROR: foo is read-only
353 ]], "assign to const variable 'foo'")
354
355 checkerr([[
356 global foo <const>;
357 function foo (x) -- ERROR: foo is read-only
358 return
359 end
360 ]], "%:2%:") -- correct line in error message
361
362 checkerr([[
363 global<const> *;
364 print(X) -- Ok to use
365 Y = 1 -- ERROR
366 ]], "assign to const variable 'Y'")
367
368 checkerr([[
369 global *;
370 Y = X -- Ok to use
371 global<const> *;
372 Y = 1 -- ERROR
373 ]], "assign to const variable 'Y'")
374
375 global *
376 Y = 10
377 assert(_ENV.Y == 10)
378 global<const> *
379 local x = Y
380 global *
381 Y = x + Y
382 assert(_ENV.Y == 20)
383 Y = nil
384end
385
386
387do -- Ok to declare hundreds of globals
388 global table
389 local code = {}
390 for i = 1, 1000 do
391 code[#code + 1] = ";global x" .. i
392 end
393 code[#code + 1] = "; return x990"
394 code = table.concat(code)
395 _ENV.x990 = 11
396 assert(load(code)() == 11)
397 _ENV.x990 = nil
398end
399
400do -- mixing lots of global/local declarations
401 global table
402 local code = {}
403 for i = 1, 200 do
404 code[#code + 1] = ";global x" .. i
405 code[#code + 1] = ";local y" .. i .. "=" .. (2*i)
406 end
407 code[#code + 1] = "; return x200 + y200"
408 code = table.concat(code)
409 _ENV.x200 = 11
410 assert(assert(load(code))() == 2*200 + 11)
411 _ENV.x200 = nil
412end
413
414do print "testing initialization in global declarations"
415 global<const> a, b, c = 10, 20, 30
416 assert(_ENV.a == 10 and b == 20 and c == 30)
417
418 global<const> a, b, c = 10
419 assert(_ENV.a == 10 and b == nil and c == nil)
420
421 global table
422 global a, b, c, d = table.unpack{1, 2, 3, 6, 5}
423 assert(_ENV.a == 1 and b == 2 and c == 3 and d == 6)
424
425 local a, b = 100, 200
426 do
427 global a, b = a, b
428 end
429 assert(_ENV.a == 100 and _ENV.b == 200)
430
431
432 _ENV.a, _ENV.b, _ENV.c, _ENV.d = nil -- erase these globals
433end
285 434
286print'OK' 435print'OK'
436