Jelajahi Sumber

Flag for to-be-closed variables changed to '<toclose>'

The flag for to-be-closed variables was changed from '*toclose'
to '<toclose>'. Several people found confusing the old syntax and
the new one has a clear terminator, making it more flexible for
future changes.
Roberto Ierusalimschy 6 tahun lalu
induk
melakukan
d881325c2f
8 mengubah file dengan 40 tambahan dan 38 penghapusan
  1. 2 1
      lparser.c
  2. 2 2
      manual/manual.of
  3. 2 1
      testes/api.lua
  4. 3 3
      testes/coroutine.lua
  5. 3 3
      testes/files.lua
  6. 1 1
      testes/goto.lua
  7. 25 25
      testes/locals.lua
  8. 2 2
      testes/main.lua

+ 2 - 1
lparser.c

@@ -1621,6 +1621,7 @@ static void tocloselocalstat (LexState *ls) {
   if (strcmp(getstr(attr), "toclose") != 0)
     luaK_semerror(ls,
       luaO_pushfstring(ls->L, "unknown attribute '%s'", getstr(attr)));
+  testnext(ls, '>');
   new_localvar(ls, str_checkname(ls));
   checknext(ls, '=');
   exp1(ls);
@@ -1634,7 +1635,7 @@ static void tocloselocalstat (LexState *ls) {
 static void localstat (LexState *ls) {
   /* stat -> LOCAL NAME {',' NAME} ['=' explist]
            | LOCAL *toclose NAME '=' exp */
-  if (testnext(ls, '*'))
+  if (testnext(ls, '<'))
     tocloselocalstat(ls);
   else
     commonlocalstat(ls);

+ 2 - 2
manual/manual.of

@@ -1509,7 +1509,7 @@ A local variable can be declared as a @def{to-be-closed} variable,
 with the following syntax:
 @Produc{
 @producname{stat}@producbody{
-  @Rw{local} @bnfter{*} @bnfter{toclose} Name @bnfter{=} exp
+  @Rw{local} @bnfter{<} @bnfter{toclose} @bnfter{>} Name @bnfter{=} exp
 }}
 A to-be-closed variable behaves like a normal local variable,
 except that its value is @emph{closed} whenever the variable
@@ -8949,7 +8949,7 @@ and @bnfNter{LiteralString}, see @See{lexical}.)
 @OrNL	@Rw{function} funcname funcbody
 @OrNL	@Rw{local} @Rw{function} @bnfNter{Name} funcbody
 @OrNL	@Rw{local} namelist @bnfopt{@bnfter{=} explist}
-@OrNL	@Rw{local} @bnfter{*} @bnfter{toclose} Name @bnfter{=} exp
+@OrNL	@Rw{local} @bnfter{<} @bnfter{toclose} @bnfter{>} Name @bnfter{=} exp
 }
 
 @producname{retstat}@producbody{@Rw{return}

+ 2 - 1
testes/api.lua

@@ -1137,7 +1137,8 @@ end)
 testamem("to-be-closed variables", function()
   local flag
   do
-    local *toclose x = setmetatable({}, {__close = function () flag = true end})
+    local <toclose> x =
+              setmetatable({}, {__close = function () flag = true end})
     flag = false
     local x = {}
   end

+ 3 - 3
testes/coroutine.lua

@@ -151,7 +151,7 @@ do
   end
 
   co = coroutine.create(function ()
-    local *toclose x = func2close(function (self, err)
+    local <toclose> x = func2close(function (self, err)
       assert(err == nil); X = false
     end)
     X = true
@@ -164,7 +164,7 @@ do
 
   -- error killing a coroutine
   co = coroutine.create(function()
-    local *toclose x = func2close(function (self, err)
+    local <toclose> x = func2close(function (self, err)
       assert(err == nil); error(111)
     end)
     coroutine.yield()
@@ -348,7 +348,7 @@ do
 
   local X = false
   A = coroutine.wrap(function()
-    local *toclose _ = setmetatable({}, {__close = function () X = true end})
+    local <toclose> _ = setmetatable({}, {__close = function () X = true end})
     return pcall(A, 1)
   end)
   st, res = A()

+ 3 - 3
testes/files.lua

@@ -125,7 +125,7 @@ do
   -- closing file by scope
   local F = nil
   do
-    local *toclose f = assert(io.open(file, "w"))
+    local <toclose> f = assert(io.open(file, "w"))
     F = f
   end
   assert(tostring(F) == "file (closed)")
@@ -135,7 +135,7 @@ assert(os.remove(file))
 
 do
   -- test writing/reading numbers
-  local *toclose f = assert(io.open(file, "w"))
+  local <toclose> f = assert(io.open(file, "w"))
   f:write(maxint, '\n')
   f:write(string.format("0X%x\n", maxint))
   f:write("0xABCp-3", '\n')
@@ -158,7 +158,7 @@ assert(os.remove(file))
 
 -- testing multiple arguments to io.read
 do
-  local *toclose f = assert(io.open(file, "w"))
+  local <toclose> f = assert(io.open(file, "w"))
   f:write[[
 a line
 another line

+ 1 - 1
testes/goto.lua

@@ -258,7 +258,7 @@ do
   ::L2:: goto L3
 
   ::L1:: do
-    local *toclose a = setmetatable({}, {__close = function () X = true end})
+    local <toclose> a = setmetatable({}, {__close = function () X = true end})
     assert(X == nil)
     if a then goto L2 end   -- jumping back out of scope of 'a'
   end

+ 25 - 25
testes/locals.lua

@@ -185,9 +185,9 @@ end
 do
   local a = {}
   do
-    local *toclose x = setmetatable({"x"}, {__close = function (self)
+    local <toclose> x = setmetatable({"x"}, {__close = function (self)
                                                    a[#a + 1] = self[1] end})
-    local *toclose y = func2close(function (self, err)
+    local <toclose> y = func2close(function (self, err)
                          assert(err == nil); a[#a + 1] = "y"
                        end)
     a[#a + 1] = "in"
@@ -203,7 +203,7 @@ do
 
   -- closing functions do not corrupt returning values
   local function foo (x)
-    local *toclose _ = closescope
+    local <toclose> _ = closescope
     return x, X, 23
   end
 
@@ -212,7 +212,7 @@ do
 
   X = false
   foo = function (x)
-    local *toclose _ = closescope
+    local <toclose> _ = closescope
     local y = 15
     return y
   end
@@ -221,7 +221,7 @@ do
 
   X = false
   foo = function ()
-    local *toclose x = closescope
+    local <toclose> x = closescope
     return x
   end
 
@@ -234,13 +234,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 <toclose> _ = 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 <toclose> _ = func2close(function () X = false end)
     X = true
     do
       return foo()    -- not a tail call!
@@ -255,14 +255,14 @@ end
 do   -- errors in __close
   local log = {}
   local function foo (err)
-    local *toclose x =
+    local <toclose> x =
        func2close(function (self, msg) log[#log + 1] = msg; error(1) end)
-    local *toclose x1 =
+    local <toclose> x1 =
        func2close(function (self, msg) log[#log + 1] = msg; end)
-    local *toclose gc = func2close(function () collectgarbage() end)
-    local *toclose y =
+    local <toclose> gc = func2close(function () collectgarbage() end)
+    local <toclose> y =
       func2close(function (self, msg) log[#log + 1] = msg; error(2) end)
-    local *toclose z =
+    local <toclose> z =
       func2close(function (self, msg) log[#log + 1] = msg or 10; error(3) end)
     if err then error(4) end
   end
@@ -283,7 +283,7 @@ do
 
   -- errors due to non-closable values
   local function foo ()
-    local *toclose x = 34
+    local <toclose> x = 34
   end
   local stat, msg = pcall(foo)
   assert(not stat and string.find(msg, "variable 'x'"))
@@ -291,8 +291,8 @@ do
 
   -- with other errors, non-closable values are ignored
   local function foo ()
-    local *toclose x = 34
-    local *toclose y = func2close(function () error(32) end)
+    local <toclose> x = 34
+    local <toclose> y = func2close(function () error(32) end)
   end
   local stat, msg = pcall(foo)
   assert(not stat and msg == 32)
@@ -304,8 +304,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 <toclose> y = func2close(function () T.alloccount() end)
+    local <toclose> x = setmetatable({}, {__close = function ()
       T.alloccount(0); local x = {}   -- force a memory error
     end})
     error("a")   -- common error inside the function's body
@@ -331,7 +331,7 @@ if rawget(_G, "T") then
   end
 
   local function test ()
-    local *toclose x = enter(0)   -- set a memory limit
+    local <toclose> x = enter(0)   -- set a memory limit
     -- creation of previous upvalue will raise a memory error
     assert(false)    -- should not run
   end
@@ -346,14 +346,14 @@ if rawget(_G, "T") then
 
   -- repeat test with extra closing upvalues
   local function test ()
-    local *toclose xxx = func2close(function (self, msg)
+    local <toclose> xxx = func2close(function (self, msg)
       assert(msg == "not enough memory");
       error(1000)   -- raise another error
     end)
-    local *toclose xx = func2close(function (self, msg)
+    local <toclose> xx = func2close(function (self, msg)
       assert(msg == "not enough memory");
     end)
-    local *toclose x = enter(0)   -- set a memory limit
+    local <toclose> x = enter(0)   -- set a memory limit
     -- creation of previous upvalue will raise a memory error
     os.exit(false)    -- should not run
   end
@@ -424,9 +424,9 @@ do
   local x = false
   local y = false
   local co = coroutine.wrap(function ()
-    local *toclose xv = func2close(function () x = true end)
+    local <toclose> xv = func2close(function () x = true end)
     do
-      local *toclose yv = func2close(function () y = true end)
+      local <toclose> yv = func2close(function () y = true end)
       coroutine.yield(100)   -- yield doesn't close variable
     end
     coroutine.yield(200)   -- yield doesn't close variable
@@ -446,7 +446,7 @@ do
   -- error in a wrapped coroutine raising errors when closing a variable
   local x = false
   local co = coroutine.wrap(function ()
-    local *toclose xv = func2close(function () error("XXX") end)
+    local <toclose> xv = func2close(function () error("XXX") end)
       coroutine.yield(100)
       error(200)
   end)
@@ -461,7 +461,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 <toclose> x = function () os.exit(false) end    -- should not run
   co = nil
   coroutine.yield()
 end)

+ 2 - 2
testes/main.lua

@@ -320,11 +320,11 @@ NoRun("", "lua %s", prog)   -- no message
 
 -- to-be-closed variables in main chunk
 prepfile[[
-  local *toclose x = function (err)
+  local <toclose> x = function (err)
     assert(err == 120)
     print("Ok")
   end
-  local *toclose e1 = function () error(120) end
+  local <toclose> e1 = function () error(120) end
   os.exit(true, true)
 ]]
 RUN('lua %s > %s', prog, out)