diff options
| -rw-r--r-- | lparser.c | 55 | ||||
| -rw-r--r-- | manual/manual.of | 76 | ||||
| -rwxr-xr-x | testes/all.lua | 8 | ||||
| -rw-r--r-- | testes/calls.lua | 15 | ||||
| -rw-r--r-- | testes/closure.lua | 2 | ||||
| -rw-r--r-- | testes/code.lua | 6 | ||||
| -rw-r--r-- | testes/files.lua | 6 | ||||
| -rw-r--r-- | testes/goto.lua | 24 | ||||
| -rw-r--r-- | testes/literals.lua | 2 | ||||
| -rw-r--r-- | testes/locals.lua | 12 | ||||
| -rw-r--r-- | testes/nextvar.lua | 7 | ||||
| -rw-r--r-- | testes/pm.lua | 2 | ||||
| -rw-r--r-- | testes/strings.lua | 1 | ||||
| -rw-r--r-- | testes/utf8.lua | 2 |
14 files changed, 155 insertions, 63 deletions
| @@ -405,7 +405,12 @@ static int searchvar (FuncState *fs, TString *n, expdesc *var) { | |||
| 405 | int i; | 405 | int i; |
| 406 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { | 406 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { |
| 407 | Vardesc *vd = getlocalvardesc(fs, i); | 407 | Vardesc *vd = getlocalvardesc(fs, i); |
| 408 | if (eqstr(n, vd->vd.name)) { /* found? */ | 408 | if (vd->vd.name == NULL) { /* 'global *'? */ |
| 409 | if (var->u.info == -1) { /* no previous collective declaration? */ | ||
| 410 | var->u.info = fs->firstlocal + i; /* will use this one as default */ | ||
| 411 | } | ||
| 412 | } | ||
| 413 | else if (eqstr(n, vd->vd.name)) { /* found? */ | ||
| 409 | if (vd->vd.kind == RDKCTC) /* compile-time constant? */ | 414 | if (vd->vd.kind == RDKCTC) /* compile-time constant? */ |
| 410 | init_exp(var, VCONST, fs->firstlocal + i); | 415 | init_exp(var, VCONST, fs->firstlocal + i); |
| 411 | else if (vd->vd.kind == GDKREG || vd->vd.kind == GDKCONST) | 416 | else if (vd->vd.kind == GDKREG || vd->vd.kind == GDKCONST) |
| @@ -449,18 +454,16 @@ static void marktobeclosed (FuncState *fs) { | |||
| 449 | ** 'var' as 'void' as a flag. | 454 | ** 'var' as 'void' as a flag. |
| 450 | */ | 455 | */ |
| 451 | static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | 456 | static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { |
| 452 | int v = searchvar(fs, n, var); /* look up locals at current level */ | 457 | int v = searchvar(fs, n, var); /* look up variables at current level */ |
| 453 | if (v >= 0) { /* found? */ | 458 | if (v >= 0) { /* found? */ |
| 454 | if (v == VLOCAL && !base) | 459 | if (v == VLOCAL && !base) |
| 455 | markupval(fs, var->u.var.vidx); /* local will be used as an upval */ | 460 | markupval(fs, var->u.var.vidx); /* local will be used as an upval */ |
| 456 | } | 461 | } |
| 457 | else { /* not found as local at current level; try upvalues */ | 462 | else { /* not found at current level; try upvalues */ |
| 458 | int idx = searchupvalue(fs, n); /* try existing upvalues */ | 463 | int idx = searchupvalue(fs, n); /* try existing upvalues */ |
| 459 | if (idx < 0) { /* not found? */ | 464 | if (idx < 0) { /* not found? */ |
| 460 | if (fs->prev != NULL) /* more levels? */ | 465 | if (fs->prev != NULL) /* more levels? */ |
| 461 | singlevaraux(fs->prev, n, var, 0); /* try upper levels */ | 466 | singlevaraux(fs->prev, n, var, 0); /* try upper levels */ |
| 462 | else /* no more levels */ | ||
| 463 | init_exp(var, VGLOBAL, -1); /* global by default */ | ||
| 464 | if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ | 467 | if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ |
| 465 | idx = newupvalue(fs, n, var); /* will be a new upvalue */ | 468 | idx = newupvalue(fs, n, var); /* will be a new upvalue */ |
| 466 | else /* it is a global or a constant */ | 469 | else /* it is a global or a constant */ |
| @@ -477,6 +480,7 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | |||
| 477 | */ | 480 | */ |
| 478 | static void buildvar (LexState *ls, TString *varname, expdesc *var) { | 481 | static void buildvar (LexState *ls, TString *varname, expdesc *var) { |
| 479 | FuncState *fs = ls->fs; | 482 | FuncState *fs = ls->fs; |
| 483 | init_exp(var, VGLOBAL, -1); /* global by default */ | ||
| 480 | singlevaraux(fs, varname, var, 1); | 484 | singlevaraux(fs, varname, var, 1); |
| 481 | if (var->k == VGLOBAL) { /* global name? */ | 485 | if (var->k == VGLOBAL) { /* global name? */ |
| 482 | expdesc key; | 486 | expdesc key; |
| @@ -1796,20 +1800,33 @@ static void localstat (LexState *ls) { | |||
| 1796 | } | 1800 | } |
| 1797 | 1801 | ||
| 1798 | 1802 | ||
| 1803 | static lu_byte getglobalattribute (LexState *ls) { | ||
| 1804 | lu_byte kind = getvarattribute(ls); | ||
| 1805 | if (kind == RDKTOCLOSE) | ||
| 1806 | luaK_semerror(ls, "global variables cannot be to-be-closed"); | ||
| 1807 | /* adjust kind for global variable */ | ||
| 1808 | return (kind == VDKREG) ? GDKREG : GDKCONST; | ||
| 1809 | } | ||
| 1810 | |||
| 1811 | |||
| 1799 | static void globalstat (LexState *ls) { | 1812 | static void globalstat (LexState *ls) { |
| 1800 | /* globalstat -> (GLOBAL) NAME attrib {',' NAME attrib} */ | 1813 | /* globalstat -> (GLOBAL) '*' attrib |
| 1814 | globalstat -> (GLOBAL) NAME attrib {',' NAME attrib} */ | ||
| 1801 | FuncState *fs = ls->fs; | 1815 | FuncState *fs = ls->fs; |
| 1802 | do { | 1816 | if (testnext(ls, '*')) { |
| 1803 | TString *vname = str_checkname(ls); | 1817 | lu_byte kind = getglobalattribute(ls); |
| 1804 | lu_byte kind = getvarattribute(ls); | 1818 | /* use NULL as name to represent '*' entries */ |
| 1805 | if (kind == RDKTOCLOSE) | 1819 | new_varkind(ls, NULL, kind); |
| 1806 | luaK_semerror(ls, "global variable ('%s') cannot be to-be-closed", | ||
| 1807 | getstr(vname)); | ||
| 1808 | /* adjust kind for global variable */ | ||
| 1809 | kind = (kind == VDKREG) ? GDKREG : GDKCONST; | ||
| 1810 | new_varkind(ls, vname, kind); | ||
| 1811 | fs->nactvar++; /* activate declaration */ | 1820 | fs->nactvar++; /* activate declaration */ |
| 1812 | } while (testnext(ls, ',')); | 1821 | } |
| 1822 | else { | ||
| 1823 | do { | ||
| 1824 | TString *vname = str_checkname(ls); | ||
| 1825 | lu_byte kind = getglobalattribute(ls); | ||
| 1826 | new_varkind(ls, vname, kind); | ||
| 1827 | fs->nactvar++; /* activate declaration */ | ||
| 1828 | } while (testnext(ls, ',')); | ||
| 1829 | } | ||
| 1813 | } | 1830 | } |
| 1814 | 1831 | ||
| 1815 | 1832 | ||
| @@ -1983,10 +2000,10 @@ static void statement (LexState *ls) { | |||
| 1983 | case TK_NAME: { | 2000 | case TK_NAME: { |
| 1984 | /* compatibility code to parse global keyword when "global" | 2001 | /* compatibility code to parse global keyword when "global" |
| 1985 | is not reserved */ | 2002 | is not reserved */ |
| 1986 | if (eqstr(ls->t.seminfo.ts, luaS_newliteral(ls->L, "global"))) { | 2003 | if (strcmp(getstr(ls->t.seminfo.ts), "global") == 0) { |
| 1987 | int lk = luaX_lookahead(ls); | 2004 | int lk = luaX_lookahead(ls); |
| 1988 | if (lk == TK_NAME || lk == TK_FUNCTION) { | 2005 | if (lk == TK_NAME || lk == '*' || lk == TK_FUNCTION) { |
| 1989 | /* 'global <name>' or 'global function' */ | 2006 | /* 'global <name>' or 'global *' or 'global function' */ |
| 1990 | globalstatfunc(ls, line); | 2007 | globalstatfunc(ls, line); |
| 1991 | break; | 2008 | break; |
| 1992 | } | 2009 | } |
diff --git a/manual/manual.of b/manual/manual.of index cc71aaad..effb95da 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
| @@ -223,14 +223,15 @@ a function's formal parameter is equivalent to a local variable.) | |||
| 223 | 223 | ||
| 224 | All chunks start with an implicit declaration @T{global *}, | 224 | All chunks start with an implicit declaration @T{global *}, |
| 225 | which declares all free names as global variables; | 225 | which declares all free names as global variables; |
| 226 | this implicit declaration becomes void inside the scope of any other | 226 | this preambular declaration becomes void inside the scope of any other |
| 227 | @Rw{global} declaration, regardless of the names being declared. | 227 | @Rw{global} declaration, |
| 228 | as the following example illustrates: | ||
| 228 | @verbatim{ | 229 | @verbatim{ |
| 229 | X = 1 -- Ok, global by default | 230 | X = 1 -- Ok, global by default |
| 230 | do | 231 | do |
| 231 | global Y -- voids implicit initial declaration | 232 | global Y -- voids implicit initial declaration |
| 232 | X = 1 -- ERROR, X not declared | ||
| 233 | Y = 1 -- Ok, Y declared as global | 233 | Y = 1 -- Ok, Y declared as global |
| 234 | X = 1 -- ERROR, X not declared | ||
| 234 | end | 235 | end |
| 235 | X = 2 -- Ok, global by default again | 236 | X = 2 -- Ok, global by default again |
| 236 | } | 237 | } |
| @@ -1110,9 +1111,9 @@ and cannot be used as names: | |||
| 1110 | @index{reserved words} | 1111 | @index{reserved words} |
| 1111 | @verbatim{ | 1112 | @verbatim{ |
| 1112 | and break do else elseif end | 1113 | and break do else elseif end |
| 1113 | false for function goto if in | 1114 | false for function global goto if |
| 1114 | local nil not or repeat return | 1115 | in local nil not or repeat |
| 1115 | then true until while | 1116 | return then true until while |
| 1116 | } | 1117 | } |
| 1117 | 1118 | ||
| 1118 | Lua is a case-sensitive language: | 1119 | Lua is a case-sensitive language: |
| @@ -1653,7 +1654,8 @@ The declaration for locals can include an initialization: | |||
| 1653 | @producname{stat}@producbody{@Rw{local} attnamelist @bnfopt{@bnfter{=} explist}} | 1654 | @producname{stat}@producbody{@Rw{local} attnamelist @bnfopt{@bnfter{=} explist}} |
| 1654 | @producname{stat}@producbody{@Rw{global} attnamelist} | 1655 | @producname{stat}@producbody{@Rw{global} attnamelist} |
| 1655 | @producname{attnamelist}@producbody{ | 1656 | @producname{attnamelist}@producbody{ |
| 1656 | @bnfNter{Name} attrib @bnfrep{@bnfter{,} @bnfNter{Name} attrib}} | 1657 | @bnfNter{Name} @bnfopt{attrib} |
| 1658 | @bnfrep{@bnfter{,} @bnfNter{Name} @bnfopt{attrib}}} | ||
| 1657 | } | 1659 | } |
| 1658 | If present, an initial assignment has the same semantics | 1660 | If present, an initial assignment has the same semantics |
| 1659 | of a multiple assignment @see{assignment}. | 1661 | of a multiple assignment @see{assignment}. |
| @@ -1662,24 +1664,55 @@ Otherwise, all local variables are initialized with @nil. | |||
| 1662 | Each variable name may be postfixed by an attribute | 1664 | Each variable name may be postfixed by an attribute |
| 1663 | (a name between angle brackets): | 1665 | (a name between angle brackets): |
| 1664 | @Produc{ | 1666 | @Produc{ |
| 1665 | @producname{attrib}@producbody{@bnfopt{@bnfter{<} @bnfNter{Name} @bnfter{>}}} | 1667 | @producname{attrib}@producbody{@bnfter{<} @bnfNter{Name} @bnfter{>}} |
| 1666 | } | 1668 | } |
| 1667 | There are two possible attributes: | 1669 | There are two possible attributes: |
| 1668 | @id{const}, which declares a @emph{constant} or @emph{read-only} variable, | 1670 | @id{const}, which declares a @emph{constant} or @emph{read-only} variable, |
| 1669 | @index{constant variable} | 1671 | @index{constant variable} |
| 1670 | that is, a variable that cannot be assigned to | 1672 | that is, a variable that cannot be used as the left-hand side of an |
| 1671 | after its initialization; | 1673 | assignment, |
| 1672 | and @id{close}, which declares a to-be-closed variable @see{to-be-closed}. | 1674 | and @id{close}, which declares a to-be-closed variable @see{to-be-closed}. |
| 1673 | A list of variables can contain at most one to-be-closed variable. | 1675 | A list of variables can contain at most one to-be-closed variable. |
| 1674 | Only local variables can have the @id{close} attribute. | 1676 | Only local variables can have the @id{close} attribute. |
| 1675 | 1677 | ||
| 1678 | Lua offers also a collective declaration for global variables: | ||
| 1679 | @Produc{ | ||
| 1680 | @producname{stat}@producbody{@Rw{global} @bnfter{*} @bnfopt{attrib}} | ||
| 1681 | } | ||
| 1682 | This special form implicitly declares | ||
| 1683 | as globals all names not explicitly declared previously. | ||
| 1684 | In particular, | ||
| 1685 | @T{global * <const>} implicitly declares | ||
| 1686 | as read-only globals all names not explicitly declared previously; | ||
| 1687 | see the following example: | ||
| 1688 | @verbatim{ | ||
| 1689 | global X | ||
| 1690 | global * <const> | ||
| 1691 | print(math.pi) -- Ok, 'print' and 'math' are read-only | ||
| 1692 | X = 1 -- Ok, declared as read-write | ||
| 1693 | Y = 1 -- Error, Y is read-only | ||
| 1694 | } | ||
| 1695 | |||
| 1696 | As noted in @See{globalenv}, | ||
| 1697 | all chunks start with an implicit declaration @T{global *}, | ||
| 1698 | but this preambular declaration becomes void inside | ||
| 1699 | the scope of any other @Rw{global} declaration. | ||
| 1700 | Therefore, a program that does not use global declarations | ||
| 1701 | or start with @T{global *} | ||
| 1702 | has free read-write access to any global; | ||
| 1703 | a program that starts with @T{global * <const>} | ||
| 1704 | has free read-only access to any global; | ||
| 1705 | and a program that starts with any other global declaration | ||
| 1706 | (e.g., @T{global none}) can only refer to declared variables. | ||
| 1707 | |||
| 1676 | Note that, for global variables, | 1708 | Note that, for global variables, |
| 1677 | the @emph{read-only} atribute is only a syntactical restriction: | 1709 | the effect of any declaration is only syntactical: |
| 1678 | @verbatim{ | 1710 | @verbatim{ |
| 1679 | global X <const> | 1711 | global X <const>, _G |
| 1680 | X = 1 -- ERROR | 1712 | X = 1 -- ERROR |
| 1681 | _ENV.X = 1 -- Ok | 1713 | _ENV.X = 1 -- Ok |
| 1682 | foo() -- 'foo' can freely change the global X | 1714 | _G.print(X) -- Ok |
| 1715 | foo() -- 'foo' can freely change any global | ||
| 1683 | } | 1716 | } |
| 1684 | 1717 | ||
| 1685 | A chunk is also a block @see{chunks}, | 1718 | A chunk is also a block @see{chunks}, |
| @@ -9453,7 +9486,12 @@ change between versions. | |||
| 9453 | @itemize{ | 9486 | @itemize{ |
| 9454 | 9487 | ||
| 9455 | @item{ | 9488 | @item{ |
| 9456 | The control variable in @Rw{for} loops are read only. | 9489 | The word @Rw{global} is a reserved word. |
| 9490 | Do not use it as a regular name. | ||
| 9491 | } | ||
| 9492 | |||
| 9493 | @item{ | ||
| 9494 | The control variable in @Rw{for} loops is read only. | ||
| 9457 | If you need to change it, | 9495 | If you need to change it, |
| 9458 | declare a local variable with the same name in the loop body. | 9496 | declare a local variable with the same name in the loop body. |
| 9459 | } | 9497 | } |
| @@ -9582,12 +9620,14 @@ and @bnfNter{LiteralString}, see @See{lexical}.) | |||
| 9582 | @OrNL @Rw{global} @Rw{function} @bnfNter{Name} funcbody | 9620 | @OrNL @Rw{global} @Rw{function} @bnfNter{Name} funcbody |
| 9583 | @OrNL @Rw{local} attnamelist @bnfopt{@bnfter{=} explist} | 9621 | @OrNL @Rw{local} attnamelist @bnfopt{@bnfter{=} explist} |
| 9584 | @OrNL @Rw{global} attnamelist | 9622 | @OrNL @Rw{global} attnamelist |
| 9623 | @OrNL @Rw{global} @bnfter{*} @bnfopt{attrib} | ||
| 9585 | } | 9624 | } |
| 9586 | 9625 | ||
| 9587 | @producname{attnamelist}@producbody{ | 9626 | @producname{attnamelist}@producbody{ |
| 9588 | @bnfNter{Name} attrib @bnfrep{@bnfter{,} @bnfNter{Name} attrib}} | 9627 | @bnfNter{Name} @bnfopt{attrib} |
| 9628 | @bnfrep{@bnfter{,} @bnfNter{Name} @bnfopt{attrib}}} | ||
| 9589 | 9629 | ||
| 9590 | @producname{attrib}@producbody{@bnfopt{@bnfter{<} @bnfNter{Name} @bnfter{>}}} | 9630 | @producname{attrib}@producbody{@bnfter{<} @bnfNter{Name} @bnfter{>}} |
| 9591 | 9631 | ||
| 9592 | @producname{retstat}@producbody{@Rw{return} | 9632 | @producname{retstat}@producbody{@Rw{return} |
| 9593 | @bnfopt{explist} @bnfopt{@bnfter{;}}} | 9633 | @bnfopt{explist} @bnfopt{@bnfter{;}}} |
diff --git a/testes/all.lua b/testes/all.lua index 5c7ebfa5..499c100d 100755 --- a/testes/all.lua +++ b/testes/all.lua | |||
| @@ -2,6 +2,10 @@ | |||
| 2 | -- $Id: testes/all.lua $ | 2 | -- $Id: testes/all.lua $ |
| 3 | -- See Copyright Notice in file lua.h | 3 | -- See Copyright Notice in file lua.h |
| 4 | 4 | ||
| 5 | global * <const> | ||
| 6 | |||
| 7 | global _soft, _port, _nomsg | ||
| 8 | global T | ||
| 5 | 9 | ||
| 6 | local version = "Lua 5.5" | 10 | local version = "Lua 5.5" |
| 7 | if _VERSION ~= version then | 11 | if _VERSION ~= version then |
| @@ -34,7 +38,7 @@ if usertests then | |||
| 34 | end | 38 | end |
| 35 | 39 | ||
| 36 | -- tests should require debug when needed | 40 | -- tests should require debug when needed |
| 37 | debug = nil | 41 | global debug; debug = nil |
| 38 | 42 | ||
| 39 | 43 | ||
| 40 | if usertests then | 44 | if usertests then |
| @@ -71,7 +75,7 @@ do -- ( | |||
| 71 | 75 | ||
| 72 | -- track messages for tests not performed | 76 | -- track messages for tests not performed |
| 73 | local msgs = {} | 77 | local msgs = {} |
| 74 | function Message (m) | 78 | global function Message (m) |
| 75 | if not _nomsg then | 79 | if not _nomsg then |
| 76 | print(m) | 80 | print(m) |
| 77 | msgs[#msgs+1] = string.sub(m, 3, -3) | 81 | msgs[#msgs+1] = string.sub(m, 3, -3) |
diff --git a/testes/calls.lua b/testes/calls.lua index 942fad72..0ea1c4ab 100644 --- a/testes/calls.lua +++ b/testes/calls.lua | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | -- $Id: testes/calls.lua $ | 1 | -- $Id: testes/calls.lua $ |
| 2 | -- See Copyright Notice in file lua.h | 2 | -- See Copyright Notice in file lua.h |
| 3 | 3 | ||
| 4 | global * <const> | ||
| 5 | |||
| 4 | print("testing functions and calls") | 6 | print("testing functions and calls") |
| 5 | 7 | ||
| 6 | local debug = require "debug" | 8 | local debug = require "debug" |
| @@ -22,7 +24,7 @@ assert(not pcall(type)) | |||
| 22 | 24 | ||
| 23 | 25 | ||
| 24 | -- testing local-function recursion | 26 | -- testing local-function recursion |
| 25 | fact = false | 27 | global fact; fact = false |
| 26 | do | 28 | do |
| 27 | local res = 1 | 29 | local res = 1 |
| 28 | local function fact (n) | 30 | local function fact (n) |
| @@ -63,7 +65,7 @@ a.b.c:f2('k', 12); assert(a.b.c.k == 12) | |||
| 63 | 65 | ||
| 64 | print('+') | 66 | print('+') |
| 65 | 67 | ||
| 66 | t = nil -- 'declare' t | 68 | global t; t = nil -- 'declare' t |
| 67 | function f(a,b,c) local d = 'a'; t={a,b,c,d} end | 69 | function f(a,b,c) local d = 'a'; t={a,b,c,d} end |
| 68 | 70 | ||
| 69 | f( -- this line change must be valid | 71 | f( -- this line change must be valid |
| @@ -75,7 +77,7 @@ assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a') | |||
| 75 | 77 | ||
| 76 | t = nil -- delete 't' | 78 | t = nil -- delete 't' |
| 77 | 79 | ||
| 78 | function fat(x) | 80 | global function fat(x) |
| 79 | if x <= 1 then return 1 | 81 | if x <= 1 then return 1 |
| 80 | else return x*load("return fat(" .. x-1 .. ")", "")() | 82 | else return x*load("return fat(" .. x-1 .. ")", "")() |
| 81 | end | 83 | end |
| @@ -107,7 +109,7 @@ end | |||
| 107 | 109 | ||
| 108 | _G.deep = nil -- "declaration" (used by 'all.lua') | 110 | _G.deep = nil -- "declaration" (used by 'all.lua') |
| 109 | 111 | ||
| 110 | function deep (n) | 112 | global function deep (n) |
| 111 | if n>0 then deep(n-1) end | 113 | if n>0 then deep(n-1) end |
| 112 | end | 114 | end |
| 113 | deep(10) | 115 | deep(10) |
| @@ -352,7 +354,7 @@ assert(not load(function () return true end)) | |||
| 352 | 354 | ||
| 353 | -- small bug | 355 | -- small bug |
| 354 | local t = {nil, "return ", "3"} | 356 | local t = {nil, "return ", "3"} |
| 355 | f, msg = load(function () return table.remove(t, 1) end) | 357 | local f, msg = load(function () return table.remove(t, 1) end) |
| 356 | assert(f() == nil) -- should read the empty chunk | 358 | assert(f() == nil) -- should read the empty chunk |
| 357 | 359 | ||
| 358 | -- another small bug (in 5.2.1) | 360 | -- another small bug (in 5.2.1) |
| @@ -388,7 +390,8 @@ assert(load("return _ENV", nil, nil, 123)() == 123) | |||
| 388 | 390 | ||
| 389 | 391 | ||
| 390 | -- load when _ENV is not first upvalue | 392 | -- load when _ENV is not first upvalue |
| 391 | local x; XX = 123 | 393 | global XX; local x |
| 394 | XX = 123 | ||
| 392 | local function h () | 395 | local function h () |
| 393 | local y=x -- use 'x', so that it becomes 1st upvalue | 396 | local y=x -- use 'x', so that it becomes 1st upvalue |
| 394 | return XX -- global name | 397 | return XX -- global name |
diff --git a/testes/closure.lua b/testes/closure.lua index d3b9f621..c55d1583 100644 --- a/testes/closure.lua +++ b/testes/closure.lua | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | -- $Id: testes/closure.lua $ | 1 | -- $Id: testes/closure.lua $ |
| 2 | -- See Copyright Notice in file lua.h | 2 | -- See Copyright Notice in file lua.h |
| 3 | 3 | ||
| 4 | global * <const> | ||
| 5 | |||
| 4 | print "testing closures" | 6 | print "testing closures" |
| 5 | 7 | ||
| 6 | do -- bug in 5.4.7 | 8 | do -- bug in 5.4.7 |
diff --git a/testes/code.lua b/testes/code.lua index 111717ce..b6ceb34c 100644 --- a/testes/code.lua +++ b/testes/code.lua | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | -- $Id: testes/code.lua $ | 1 | -- $Id: testes/code.lua $ |
| 2 | -- See Copyright Notice in file lua.h | 2 | -- See Copyright Notice in file lua.h |
| 3 | 3 | ||
| 4 | global * <const> | ||
| 5 | |||
| 4 | if T==nil then | 6 | if T==nil then |
| 5 | (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n') | 7 | (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n') |
| 6 | return | 8 | return |
| @@ -405,8 +407,8 @@ do -- tests for table access in upvalues | |||
| 405 | end | 407 | end |
| 406 | 408 | ||
| 407 | -- de morgan | 409 | -- de morgan |
| 408 | checkequal(function () local a; if not (a or b) then b=a end end, | 410 | checkequal(function () local a, b; if not (a or b) then b=a end end, |
| 409 | function () local a; if (not a and not b) then b=a end end) | 411 | function () local a, b; if (not a and not b) then b=a end end) |
| 410 | 412 | ||
| 411 | checkequal(function (l) local a; return 0 <= a and a <= l end, | 413 | checkequal(function (l) local a; return 0 <= a and a <= l end, |
| 412 | function (l) local a; return not (not(a >= 0) or not(a <= l)) end) | 414 | function (l) local a; return not (not(a >= 0) or not(a <= l)) end) |
diff --git a/testes/files.lua b/testes/files.lua index a0ae661c..c2b355fb 100644 --- a/testes/files.lua +++ b/testes/files.lua | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | -- $Id: testes/files.lua $ | 1 | -- $Id: testes/files.lua $ |
| 2 | -- See Copyright Notice in file lua.h | 2 | -- See Copyright Notice in file lua.h |
| 3 | 3 | ||
| 4 | global * <const> | ||
| 5 | |||
| 4 | local debug = require "debug" | 6 | local debug = require "debug" |
| 5 | 7 | ||
| 6 | local maxint = math.maxinteger | 8 | local maxint = math.maxinteger |
| @@ -838,13 +840,13 @@ assert(os.date("!\0\0") == "\0\0") | |||
| 838 | local x = string.rep("a", 10000) | 840 | local x = string.rep("a", 10000) |
| 839 | assert(os.date(x) == x) | 841 | assert(os.date(x) == x) |
| 840 | local t = os.time() | 842 | local t = os.time() |
| 841 | D = os.date("*t", t) | 843 | global D; D = os.date("*t", t) |
| 842 | assert(os.date(string.rep("%d", 1000), t) == | 844 | assert(os.date(string.rep("%d", 1000), t) == |
| 843 | string.rep(os.date("%d", t), 1000)) | 845 | string.rep(os.date("%d", t), 1000)) |
| 844 | assert(os.date(string.rep("%", 200)) == string.rep("%", 100)) | 846 | assert(os.date(string.rep("%", 200)) == string.rep("%", 100)) |
| 845 | 847 | ||
| 846 | local function checkDateTable (t) | 848 | local function checkDateTable (t) |
| 847 | _G.D = os.date("*t", t) | 849 | D = os.date("*t", t) |
| 848 | assert(os.time(D) == t) | 850 | assert(os.time(D) == t) |
| 849 | load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and | 851 | load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and |
| 850 | D.hour==%H and D.min==%M and D.sec==%S and | 852 | D.hour==%H and D.min==%M and D.sec==%S and |
diff --git a/testes/goto.lua b/testes/goto.lua index 59713dd7..3f1f6e69 100644 --- a/testes/goto.lua +++ b/testes/goto.lua | |||
| @@ -1,6 +1,10 @@ | |||
| 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 | ||
| 4 | global require | ||
| 5 | global print, load, assert, string, setmetatable | ||
| 6 | global collectgarbage, error | ||
| 7 | |||
| 4 | print("testing goto and global declarations") | 8 | print("testing goto and global declarations") |
| 5 | 9 | ||
| 6 | collectgarbage() | 10 | collectgarbage() |
| @@ -254,6 +258,8 @@ assert(testG(5) == 10) | |||
| 254 | 258 | ||
| 255 | do -- test goto's around to-be-closed variable | 259 | do -- test goto's around to-be-closed variable |
| 256 | 260 | ||
| 261 | global * | ||
| 262 | |||
| 257 | -- set 'var' and return an object that will reset 'var' when | 263 | -- set 'var' and return an object that will reset 'var' when |
| 258 | -- it goes out of scope | 264 | -- it goes out of scope |
| 259 | local function newobj (var) | 265 | local function newobj (var) |
| @@ -265,16 +271,16 @@ do -- test goto's around to-be-closed variable | |||
| 265 | 271 | ||
| 266 | goto L1 | 272 | goto L1 |
| 267 | 273 | ||
| 268 | ::L4:: assert(not X); goto L5 -- varX dead here | 274 | ::L4:: assert(not varX); goto L5 -- varX dead here |
| 269 | 275 | ||
| 270 | ::L1:: | 276 | ::L1:: |
| 271 | local varX <close> = newobj("X") | 277 | local varX <close> = newobj("X") |
| 272 | assert(X); goto L2 -- varX alive here | 278 | assert(varX); goto L2 -- varX alive here |
| 273 | 279 | ||
| 274 | ::L3:: | 280 | ::L3:: |
| 275 | assert(X); goto L4 -- varX alive here | 281 | assert(varX); goto L4 -- varX alive here |
| 276 | 282 | ||
| 277 | ::L2:: assert(X); goto L3 -- varX alive here | 283 | ::L2:: assert(varX); goto L3 -- varX alive here |
| 278 | 284 | ||
| 279 | ::L5:: -- return | 285 | ::L5:: -- return |
| 280 | end | 286 | end |
| @@ -285,8 +291,7 @@ foo() | |||
| 285 | -------------------------------------------------------------------------- | 291 | -------------------------------------------------------------------------- |
| 286 | 292 | ||
| 287 | do | 293 | do |
| 288 | global print, load, T<const>; global assert<const> | 294 | global T<const> |
| 289 | global string | ||
| 290 | 295 | ||
| 291 | local function checkerr (code, err) | 296 | local function checkerr (code, err) |
| 292 | local st, msg = load(code) | 297 | local st, msg = load(code) |
| @@ -299,6 +304,7 @@ do | |||
| 299 | 304 | ||
| 300 | -- global variables cannot be to-be-closed | 305 | -- global variables cannot be to-be-closed |
| 301 | checkerr("global X<close>", "cannot be") | 306 | checkerr("global X<close>", "cannot be") |
| 307 | checkerr("global * <close>", "cannot be") | ||
| 302 | 308 | ||
| 303 | do | 309 | do |
| 304 | local X = 10 | 310 | local X = 10 |
| @@ -349,6 +355,12 @@ do | |||
| 349 | return | 355 | return |
| 350 | end | 356 | end |
| 351 | ]], "%:2%:") -- correct line in error message | 357 | ]], "%:2%:") -- correct line in error message |
| 358 | |||
| 359 | checkerr([[ | ||
| 360 | global * <const>; | ||
| 361 | print(X) -- Ok to use | ||
| 362 | Y = 1 -- ERROR | ||
| 363 | ]], "assign to const variable 'Y'") | ||
| 352 | 364 | ||
| 353 | end | 365 | end |
| 354 | 366 | ||
diff --git a/testes/literals.lua b/testes/literals.lua index 28995718..fecdd6d3 100644 --- a/testes/literals.lua +++ b/testes/literals.lua | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | print('testing scanner') | 4 | print('testing scanner') |
| 5 | 5 | ||
| 6 | global * <const> | ||
| 7 | |||
| 6 | local debug = require "debug" | 8 | local debug = require "debug" |
| 7 | 9 | ||
| 8 | 10 | ||
diff --git a/testes/locals.lua b/testes/locals.lua index 421595bb..99ff9edc 100644 --- a/testes/locals.lua +++ b/testes/locals.lua | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | -- $Id: testes/locals.lua $ | 1 | -- $Id: testes/locals.lua $ |
| 2 | -- See Copyright Notice in file lua.h | 2 | -- See Copyright Notice in file lua.h |
| 3 | 3 | ||
| 4 | global * <const> | ||
| 5 | |||
| 4 | print('testing local variables and environments') | 6 | print('testing local variables and environments') |
| 5 | 7 | ||
| 6 | local debug = require"debug" | 8 | local debug = require"debug" |
| @@ -39,9 +41,11 @@ f = nil | |||
| 39 | local f | 41 | local f |
| 40 | local x = 1 | 42 | local x = 1 |
| 41 | 43 | ||
| 42 | a = nil | 44 | do |
| 43 | load('local a = {}')() | 45 | global a; a = nil |
| 44 | assert(a == nil) | 46 | load('local a = {}')() |
| 47 | assert(a == nil) | ||
| 48 | end | ||
| 45 | 49 | ||
| 46 | function f (a) | 50 | function f (a) |
| 47 | local _1, _2, _3, _4, _5 | 51 | local _1, _2, _3, _4, _5 |
| @@ -154,7 +158,7 @@ local _ENV = (function (...) return ... end)(_G, dummy) -- { | |||
| 154 | do local _ENV = {assert=assert}; assert(true) end | 158 | do local _ENV = {assert=assert}; assert(true) end |
| 155 | local mt = {_G = _G} | 159 | local mt = {_G = _G} |
| 156 | local foo,x | 160 | local foo,x |
| 157 | A = false -- "declare" A | 161 | global A; A = false -- "declare" A |
| 158 | do local _ENV = mt | 162 | do local _ENV = mt |
| 159 | function foo (x) | 163 | function foo (x) |
| 160 | A = x | 164 | A = x |
diff --git a/testes/nextvar.lua b/testes/nextvar.lua index 679cb1e4..e5a97178 100644 --- a/testes/nextvar.lua +++ b/testes/nextvar.lua | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | -- $Id: testes/nextvar.lua $ | 1 | -- $Id: testes/nextvar.lua $ |
| 2 | -- See Copyright Notice in file lua.h | 2 | -- See Copyright Notice in file lua.h |
| 3 | 3 | ||
| 4 | global * <const> | ||
| 5 | |||
| 4 | print('testing tables, next, and for') | 6 | print('testing tables, next, and for') |
| 5 | 7 | ||
| 6 | local function checkerror (msg, f, ...) | 8 | local function checkerror (msg, f, ...) |
| @@ -345,9 +347,6 @@ end | |||
| 345 | 347 | ||
| 346 | local nofind = {} | 348 | local nofind = {} |
| 347 | 349 | ||
| 348 | a,b,c = 1,2,3 | ||
| 349 | a,b,c = nil | ||
| 350 | |||
| 351 | 350 | ||
| 352 | -- next uses always the same iteration function | 351 | -- next uses always the same iteration function |
| 353 | assert(next{} == next{}) | 352 | assert(next{} == next{}) |
| @@ -396,7 +395,7 @@ for i=0,10000 do | |||
| 396 | end | 395 | end |
| 397 | end | 396 | end |
| 398 | 397 | ||
| 399 | n = {n=0} | 398 | local n = {n=0} |
| 400 | for i,v in pairs(a) do | 399 | for i,v in pairs(a) do |
| 401 | n.n = n.n+1 | 400 | n.n = n.n+1 |
| 402 | assert(i and v and a[i] == v) | 401 | assert(i and v and a[i] == v) |
diff --git a/testes/pm.lua b/testes/pm.lua index ab19eb5d..1700ca2c 100644 --- a/testes/pm.lua +++ b/testes/pm.lua | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | print('testing pattern matching') | 7 | print('testing pattern matching') |
| 8 | 8 | ||
| 9 | global * <const> | ||
| 10 | |||
| 9 | local function checkerror (msg, f, ...) | 11 | local function checkerror (msg, f, ...) |
| 10 | local s, err = pcall(f, ...) | 12 | local s, err = pcall(f, ...) |
| 11 | assert(not s and string.find(err, msg)) | 13 | assert(not s and string.find(err, msg)) |
diff --git a/testes/strings.lua b/testes/strings.lua index ce28e4c5..455398c3 100644 --- a/testes/strings.lua +++ b/testes/strings.lua | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | -- ISO Latin encoding | 4 | -- ISO Latin encoding |
| 5 | 5 | ||
| 6 | global * <const> | ||
| 6 | 7 | ||
| 7 | print('testing strings and string library') | 8 | print('testing strings and string library') |
| 8 | 9 | ||
diff --git a/testes/utf8.lua b/testes/utf8.lua index d0c0184d..ec9b706f 100644 --- a/testes/utf8.lua +++ b/testes/utf8.lua | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | -- UTF-8 file | 4 | -- UTF-8 file |
| 5 | 5 | ||
| 6 | global * <const> | ||
| 7 | |||
| 6 | print "testing UTF-8 library" | 8 | print "testing UTF-8 library" |
| 7 | 9 | ||
| 8 | local utf8 = require'utf8' | 10 | local utf8 = require'utf8' |
