@@ -174,25 +174,25 @@ assert(x==20)
do -- constants
local < const> a , b, < const> c = 10 , 20 , 30
local a < const> , b, c < const> = 10 , 20 , 30
b = a + c + b -- 'b' is not constant
assert (a == 10 and b == 60 and c == 30 )
local function checkro (name , code )
local st, msg = load (code)
local gab = string.format (" attempt to assign to const variable '%s'" , name)
assert (not st and string.find (msg, gab))
end
checkro (" y" , " local x, <const> y , z = 10, 20, 30; x = 11; y = 12" )
checkro (" x" , " local <const> x , y, <const> z = 10, 20, 30; x = 11" )
checkro (" z" , " local <const> x , y, <const> z = 10, 20, 30; y = 10; z = 11" )
checkro (" y" , " local x, y <const>, z = 10, 20, 30; x = 11; y = 12" )
checkro (" x" , " local x <const>, y, z <const> = 10, 20, 30; x = 11" )
checkro (" z" , " local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11" )
checkro (" z" , [[
local a, <const> z , b = 10;
local a, z <const>, b = 10;
function foo() a = 20; z = 32; end
]] )
checkro (" var1" , [[
local a, <const> var1 = 10;
local a, var1 <const> = 10;
function foo() a = 20; z = function () var1 = 12; end end
]] )
end
@@ -215,9 +215,9 @@ end
do
local a = {}
do
local < toclose > x = setmetatable ({" x" }, {__close = function (self )
local x < close > = setmetatable ({" x" }, {__close = function (self )
a[# a + 1 ] = self [1 ] end })
local w, < toclose > y , z = func2close (function (self , err )
local w, y < close > , z = func2close (function (self , err )
assert (err == nil ); a[# a + 1 ] = " y"
end , 10 , 20 )
a[# a + 1 ] = " in"
@@ -235,7 +235,7 @@ do
-- closing functions do not corrupt returning values
local function foo (x )
local < toclose > _ = closescope
local _ < close > = closescope
return x, X, 23
end
@@ -244,7 +244,7 @@ do
X = false
foo = function (x )
local < toclose > _ = closescope
local _ < close > = closescope
local y = 15
return y
end
@@ -253,7 +253,7 @@ do
X = false
foo = function ()
local < toclose > x = closescope
local x < close > = closescope
return x
end
@@ -266,13 +266,13 @@ do
-- calls cannot be tail in the scope of to-be-closed variables
local X, Y
local function foo ()
local < toclose > _ = func2close (function () Y = 10 end )
local _ < close > = func2close (function () Y = 10 end )
assert (X == true and Y == nil ) -- 'X' not closed yet
return 1 ,2 ,3
end
local function bar ()
local < toclose > _ = func2close (function () X = false end )
local _ < close > = func2close (function () X = false end )
X = true
do
return foo () -- not a tail call!
@@ -287,14 +287,14 @@ end
do -- errors in __close
local log = {}
local function foo (err )
local < toclose > x =
local x < close > =
func2close (function (self , msg ) log[# log + 1 ] = msg; error (1 ) end )
local < toclose > x1 =
local x1 < close > =
func2close (function (self , msg ) log[# log + 1 ] = msg; end )
local < toclose > gc = func2close (function () collectgarbage () end )
local < toclose > y =
local gc < close > = func2close (function () collectgarbage () end )
local y < close > =
func2close (function (self , msg ) log[# log + 1 ] = msg; error (2 ) end )
local < toclose > z =
local z < close > =
func2close (function (self , msg )
log[# log + 1 ] = (msg or 10 ) + 1 ;
error (3 )
@@ -316,7 +316,7 @@ do -- errors in __close
-- error in toclose in vararg function
function foo (...)
local < toclose > x123 = 10
local x123 < close > = 10
end
local st, msg = pcall (foo)
@@ -329,16 +329,16 @@ do
-- errors due to non-closable values
local function foo ()
local < toclose > x = {}
local x < close > = {}
end
local stat, msg = pcall (foo)
assert (not stat and string.find (msg, " variable 'x'" ))
-- with other errors, non-closable values are ignored
local function foo ()
local < toclose > x = 34
local < toclose > y = func2close (function () error (32 ) end )
local x < close > = 34
local y < close > = func2close (function () error (32 ) end )
end
local stat, msg = pcall (foo)
assert (not stat and msg == 32 )
@@ -350,8 +350,8 @@ if rawget(_G, "T") then
-- memory error inside closing function
local function foo ()
local < toclose > y = func2close (function () T.alloccount () end )
local < toclose > x = setmetatable ({}, {__close = function ()
local y < close > = func2close (function () T.alloccount () end )
local x < close > = setmetatable ({}, {__close = function ()
T.alloccount (0 ); local x = {} -- force a memory error
end })
error (1000 ) -- common error inside the function's body
@@ -377,7 +377,7 @@ if rawget(_G, "T") then
end
local function test ()
local < toclose > x = enter (0 ) -- set a memory limit
local x < close > = enter (0 ) -- set a memory limit
-- creation of previous upvalue will raise a memory error
assert (false ) -- should not run
end
@@ -392,14 +392,14 @@ if rawget(_G, "T") then
-- repeat test with extra closing upvalues
local function test ()
local < toclose > xxx = func2close (function (self , msg )
local xxx < close > = func2close (function (self , msg )
assert (msg == " not enough memory" );
error (1000 ) -- raise another error
end )
local < toclose > xx = func2close (function (self , msg )
local xx < close > = func2close (function (self , msg )
assert (msg == " not enough memory" );
end )
local < toclose > x = enter (0 ) -- set a memory limit
local x < close > = enter (0 ) -- set a memory limit
-- creation of previous upvalue will raise a memory error
os.exit (false ) -- should not run
end
@@ -469,9 +469,9 @@ do
local x = false
local y = false
local co = coroutine.wrap (function ()
local < toclose > xv = func2close (function () x = true end )
local xv < close > = func2close (function () x = true end )
do
local < toclose > yv = func2close (function () y = true end )
local yv < close > = func2close (function () y = true end )
coroutine.yield (100 ) -- yield doesn't close variable
end
coroutine.yield (200 ) -- yield doesn't close variable
@@ -491,8 +491,8 @@ do
-- error in a wrapped coroutine raising errors when closing a variable
local x = 0
local co = coroutine.wrap (function ()
local < toclose > xx = func2close (function () x = x + 1 ; error (" YYY" ) end )
local < toclose > xv = func2close (function () x = x + 1 ; error (" XXX" ) end )
local xx < close > = func2close (function () x = x + 1 ; error (" YYY" ) end )
local xv < close > = func2close (function () x = x + 1 ; error (" XXX" ) end )
coroutine.yield (100 )
error (200 )
end )
@@ -503,8 +503,8 @@ do
local x = 0
local y = 0
co = coroutine.wrap (function ()
local < toclose > xx = func2close (function () y = y + 1 ; error (" YYY" ) end )
local < toclose > xv = func2close (function () x = x + 1 ; error (" XXX" ) end )
local xx < close > = func2close (function () y = y + 1 ; error (" YYY" ) end )
local xv < close > = func2close (function () x = x + 1 ; error (" XXX" ) end )
coroutine.yield (100 )
return 200
end )
@@ -519,7 +519,7 @@ end
-- a suspended coroutine should not close its variables when collected
local co
co = coroutine.wrap (function ()
local < toclose > x = function () os.exit (false ) end -- should not run
local x < close > = function () os.exit (false ) end -- should not run
co = nil
coroutine.yield ()
end )