aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lparser.c81
-rw-r--r--manual/manual.of18
-rw-r--r--testes/bwcoercion.lua2
-rw-r--r--testes/calls.lua4
-rw-r--r--testes/files.lua4
-rw-r--r--testes/goto.lua23
-rw-r--r--testes/tracegc.lua2
7 files changed, 96 insertions, 38 deletions
diff --git a/lparser.c b/lparser.c
index 201dbe8b..dde0b6d5 100644
--- a/lparser.c
+++ b/lparser.c
@@ -30,7 +30,7 @@
30 30
31 31
32 32
33/* maximum number of variable declarationss per function (must be 33/* maximum number of variable declarations per function (must be
34 smaller than 250, due to the bytecode format) */ 34 smaller than 250, due to the bytecode format) */
35#define MAXVARS 200 35#define MAXVARS 200
36 36
@@ -197,7 +197,7 @@ static int new_varkind (LexState *ls, TString *name, lu_byte kind) {
197 Dyndata *dyd = ls->dyd; 197 Dyndata *dyd = ls->dyd;
198 Vardesc *var; 198 Vardesc *var;
199 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, 199 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
200 dyd->actvar.size, Vardesc, SHRT_MAX, "variable declarationss"); 200 dyd->actvar.size, Vardesc, SHRT_MAX, "variable declarations");
201 var = &dyd->actvar.arr[dyd->actvar.n++]; 201 var = &dyd->actvar.arr[dyd->actvar.n++];
202 var->vd.kind = kind; /* default */ 202 var->vd.kind = kind; /* default */
203 var->vd.name = name; 203 var->vd.name = name;
@@ -485,6 +485,20 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
485} 485}
486 486
487 487
488static void buildglobal (LexState *ls, TString *varname, expdesc *var) {
489 FuncState *fs = ls->fs;
490 expdesc key;
491 init_exp(var, VGLOBAL, -1); /* global by default */
492 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
493 if (var->k == VGLOBAL)
494 luaK_semerror(ls, "_ENV is global when accessing variable '%s'",
495 getstr(varname));
496 luaK_exp2anyregup(fs, var); /* _ENV could be a constant */
497 codestring(&key, varname); /* key is variable name */
498 luaK_indexed(fs, var, &key); /* 'var' represents _ENV[varname] */
499}
500
501
488/* 502/*
489** Find a variable with the given name 'n', handling global variables 503** Find a variable with the given name 'n', handling global variables
490** too. 504** too.
@@ -494,18 +508,11 @@ static void buildvar (LexState *ls, TString *varname, expdesc *var) {
494 init_exp(var, VGLOBAL, -1); /* global by default */ 508 init_exp(var, VGLOBAL, -1); /* global by default */
495 singlevaraux(fs, varname, var, 1); 509 singlevaraux(fs, varname, var, 1);
496 if (var->k == VGLOBAL) { /* global name? */ 510 if (var->k == VGLOBAL) { /* global name? */
497 expdesc key;
498 int info = var->u.info; 511 int info = var->u.info;
499 /* global by default in the scope of a global declaration? */ 512 /* global by default in the scope of a global declaration? */
500 if (info == -2) 513 if (info == -2)
501 luaK_semerror(ls, "variable '%s' not declared", getstr(varname)); 514 luaK_semerror(ls, "variable '%s' not declared", getstr(varname));
502 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ 515 buildglobal(ls, varname, var);
503 if (var->k == VGLOBAL)
504 luaK_semerror(ls, "_ENV is global when accessing variable '%s'",
505 getstr(varname));
506 luaK_exp2anyregup(fs, var); /* but could be a constant */
507 codestring(&key, varname); /* key is variable name */
508 luaK_indexed(fs, var, &key); /* env[varname] */
509 if (info != -1 && ls->dyd->actvar.arr[info].vd.kind == GDKCONST) 516 if (info != -1 && ls->dyd->actvar.arr[info].vd.kind == GDKCONST)
510 var->u.ind.ro = 1; /* mark variable as read-only */ 517 var->u.ind.ro = 1; /* mark variable as read-only */
511 else /* anyway must be a global */ 518 else /* anyway must be a global */
@@ -665,7 +672,7 @@ static void createlabel (LexState *ls, TString *name, int line, int last) {
665 672
666 673
667/* 674/*
668** Traverse the pending goto's of the finishing block checking whether 675** Traverse the pending gotos of the finishing block checking whether
669** each match some label of that block. Those that do not match are 676** each match some label of that block. Those that do not match are
670** "exported" to the outer block, to be solved there. In particular, 677** "exported" to the outer block, to be solved there. In particular,
671** its 'nactvar' is updated with the level of the inner block, 678** its 'nactvar' is updated with the level of the inner block,
@@ -1435,6 +1442,15 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1435 } 1442 }
1436} 1443}
1437 1444
1445
1446/* Create code to store the "top" register in 'var' */
1447static void storevartop (FuncState *fs, expdesc *var) {
1448 expdesc e;
1449 init_exp(&e, VNONRELOC, fs->freereg - 1);
1450 luaK_storevar(fs, var, &e); /* will also free the top register */
1451}
1452
1453
1438/* 1454/*
1439** Parse and compile a multiple assignment. The first "variable" 1455** Parse and compile a multiple assignment. The first "variable"
1440** (a 'suffixedexp') was already read by the caller. 1456** (a 'suffixedexp') was already read by the caller.
@@ -1468,8 +1484,7 @@ static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) {
1468 return; /* avoid default */ 1484 return; /* avoid default */
1469 } 1485 }
1470 } 1486 }
1471 init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ 1487 storevartop(ls->fs, &lh->v); /* default assignment */
1472 luaK_storevar(ls->fs, &lh->v, &e);
1473} 1488}
1474 1489
1475 1490
@@ -1821,25 +1836,45 @@ static lu_byte getglobalattribute (LexState *ls, lu_byte df) {
1821} 1836}
1822 1837
1823 1838
1839static void globalnames (LexState *ls, lu_byte defkind) {
1840 FuncState *fs = ls->fs;
1841 int nvars = 0;
1842 int lastidx; /* index of last registered variable */
1843 do { /* for each name */
1844 TString *vname = str_checkname(ls);
1845 lu_byte kind = getglobalattribute(ls, defkind);
1846 lastidx = new_varkind(ls, vname, kind);
1847 nvars++;
1848 } while (testnext(ls, ','));
1849 if (testnext(ls, '=')) { /* initialization? */
1850 expdesc e;
1851 int i;
1852 int nexps = explist(ls, &e); /* read list of expressions */
1853 adjust_assign(ls, nvars, nexps, &e);
1854 for (i = 0; i < nvars; i++) { /* for each variable */
1855 expdesc var;
1856 TString *varname = getlocalvardesc(fs, lastidx - i)->vd.name;
1857 buildglobal(ls, varname, &var); /* create global variable in 'var' */
1858 storevartop(fs, &var);
1859 }
1860 }
1861 fs->nactvar = cast_short(fs->nactvar + nvars); /* activate declaration */
1862}
1863
1864
1824static void globalstat (LexState *ls) { 1865static void globalstat (LexState *ls) {
1825 /* globalstat -> (GLOBAL) attrib '*' 1866 /* globalstat -> (GLOBAL) attrib '*'
1826 globalstat -> (GLOBAL) attrib NAME attrib {',' NAME attrib} */ 1867 globalstat -> (GLOBAL) attrib NAME attrib {',' NAME attrib} */
1827 FuncState *fs = ls->fs; 1868 FuncState *fs = ls->fs;
1828 /* get prefixed attribute (if any); default is regular global variable */ 1869 /* get prefixed attribute (if any); default is regular global variable */
1829 lu_byte defkind = getglobalattribute(ls, GDKREG); 1870 lu_byte defkind = getglobalattribute(ls, GDKREG);
1830 if (testnext(ls, '*')) { 1871 if (!testnext(ls, '*'))
1872 globalnames(ls, defkind);
1873 else {
1831 /* use NULL as name to represent '*' entries */ 1874 /* use NULL as name to represent '*' entries */
1832 new_varkind(ls, NULL, defkind); 1875 new_varkind(ls, NULL, defkind);
1833 fs->nactvar++; /* activate declaration */ 1876 fs->nactvar++; /* activate declaration */
1834 } 1877 }
1835 else {
1836 do { /* list of names */
1837 TString *vname = str_checkname(ls);
1838 lu_byte kind = getglobalattribute(ls, defkind);
1839 new_varkind(ls, vname, kind);
1840 fs->nactvar++; /* activate declaration */
1841 } while (testnext(ls, ','));
1842 }
1843} 1878}
1844 1879
1845 1880
@@ -1850,7 +1885,7 @@ static void globalfunc (LexState *ls, int line) {
1850 TString *fname = str_checkname(ls); 1885 TString *fname = str_checkname(ls);
1851 new_varkind(ls, fname, GDKREG); /* declare global variable */ 1886 new_varkind(ls, fname, GDKREG); /* declare global variable */
1852 fs->nactvar++; /* enter its scope */ 1887 fs->nactvar++; /* enter its scope */
1853 buildvar(ls, fname, &var); 1888 buildglobal(ls, fname, &var);
1854 body(ls, &b, 0, ls->linenumber); /* compile and return closure in 'b' */ 1889 body(ls, &b, 0, ls->linenumber); /* compile and return closure in 'b' */
1855 luaK_storevar(fs, &var, &b); 1890 luaK_storevar(fs, &var, &b);
1856 luaK_fixline(fs, line); /* definition "happens" in the first line */ 1891 luaK_fixline(fs, line); /* definition "happens" in the first line */
diff --git a/manual/manual.of b/manual/manual.of
index bcc8173b..8f90f942 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -229,7 +229,7 @@ as the following example illustrates:
229@verbatim{ 229@verbatim{
230X = 1 -- Ok, global by default 230X = 1 -- Ok, global by default
231do 231do
232 global Y -- voids implicit initial declaration 232 global Y -- voids the implicit initial declaration
233 Y = 1 -- Ok, Y declared as global 233 Y = 1 -- Ok, Y declared as global
234 X = 1 -- ERROR, X not declared 234 X = 1 -- ERROR, X not declared
235end 235end
@@ -269,7 +269,7 @@ print(x) --> 10 (the global one)
269 269
270Notice that, in a declaration like @T{local x = x}, 270Notice that, in a declaration like @T{local x = x},
271the new @id{x} being declared is not in scope yet, 271the new @id{x} being declared is not in scope yet,
272and so the @id{x} in the left-hand side refers to the outside variable. 272and so the @id{x} in the right-hand side refers to the outside variable.
273 273
274Because of the @x{lexical scoping} rules, 274Because of the @x{lexical scoping} rules,
275local variables can be freely accessed by functions 275local variables can be freely accessed by functions
@@ -1651,11 +1651,12 @@ Function calls are explained in @See{functioncall}.
1651 1651
1652@sect3{localvar| @title{Variable Declarations} 1652@sect3{localvar| @title{Variable Declarations}
1653Local and global variables can be declared anywhere inside a block. 1653Local and global variables can be declared anywhere inside a block.
1654The declaration for locals can include an initialization: 1654The declaration can include an initialization:
1655@Produc{ 1655@Produc{
1656@producname{stat}@producbody{@Rw{local} 1656@producname{stat}@producbody{@Rw{local}
1657 attnamelist @bnfopt{@bnfter{=} explist}} 1657 attnamelist @bnfopt{@bnfter{=} explist}}
1658@producname{stat}@producbody{@Rw{global} attnamelist} 1658@producname{stat}@producbody{@Rw{global}
1659 attnamelist @bnfopt{@bnfter{=} explist}}
1659} 1660}
1660If present, an initial assignment has the same semantics 1661If present, an initial assignment has the same semantics
1661of a multiple assignment @see{assignment}. 1662of a multiple assignment @see{assignment}.
@@ -1712,7 +1713,8 @@ and a program that starts with any other global declaration
1712(e.g., @T{global none}) can only refer to declared variables. 1713(e.g., @T{global none}) can only refer to declared variables.
1713 1714
1714Note that, for global variables, 1715Note that, for global variables,
1715the effect of any declaration is only syntactical: 1716the effect of any declaration is only syntactical
1717(except for the optional assignment):
1716@verbatim{ 1718@verbatim{
1717global X <const>, _G 1719global X <const>, _G
1718X = 1 -- ERROR 1720X = 1 -- ERROR
@@ -3924,8 +3926,8 @@ This macro may evaluate its arguments more than once.
3924 3926
3925} 3927}
3926 3928
3927@APIEntry{unsigned (lua_numbertocstring) (lua_State *L, int idx, 3929@APIEntry{unsigned lua_numbertocstring (lua_State *L, int idx,
3928 char *buff);| 3930 char *buff);|
3929@apii{0,0,-} 3931@apii{0,0,-}
3930 3932
3931Converts the number at acceptable index @id{idx} to a string 3933Converts the number at acceptable index @id{idx} to a string
@@ -4050,7 +4052,7 @@ This function is equivalent to @Lid{lua_pushcclosure} with no upvalues.
4050 4052
4051} 4053}
4052 4054
4053@APIEntry{const char *(lua_pushexternalstring) (lua_State *L, 4055@APIEntry{const char *lua_pushexternalstring (lua_State *L,
4054 const char *s, size_t len, lua_Alloc falloc, void *ud);| 4056 const char *s, size_t len, lua_Alloc falloc, void *ud);|
4055@apii{0,1,m} 4057@apii{0,1,m}
4056 4058
diff --git a/testes/bwcoercion.lua b/testes/bwcoercion.lua
index cd735ab0..0544944d 100644
--- a/testes/bwcoercion.lua
+++ b/testes/bwcoercion.lua
@@ -4,7 +4,7 @@ local strsub = string.sub
4 4
5local print = print 5local print = print
6 6
7_ENV = nil 7global none
8 8
9-- Try to convert a value to an integer, without assuming any coercion. 9-- Try to convert a value to an integer, without assuming any coercion.
10local function toint (x) 10local function toint (x)
diff --git a/testes/calls.lua b/testes/calls.lua
index 21441701..0dacb85a 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -24,7 +24,7 @@ assert(not pcall(type))
24 24
25 25
26-- testing local-function recursion 26-- testing local-function recursion
27global fact; fact = false 27global fact = false
28do 28do
29 local res = 1 29 local res = 1
30 local function fact (n) 30 local function fact (n)
@@ -65,7 +65,7 @@ a.b.c:f2('k', 12); assert(a.b.c.k == 12)
65 65
66print('+') 66print('+')
67 67
68global t; t = nil -- 'declare' t 68global t = nil -- 'declare' t
69function f(a,b,c) local d = 'a'; t={a,b,c,d} end 69function f(a,b,c) local d = 'a'; t={a,b,c,d} end
70 70
71f( -- this line change must be valid 71f( -- this line change must be valid
diff --git a/testes/files.lua b/testes/files.lua
index d4e327b7..7146ac7c 100644
--- a/testes/files.lua
+++ b/testes/files.lua
@@ -715,7 +715,7 @@ do
715end 715end
716 716
717 717
718if T and T.nonblock then 718if T and T.nonblock and not _port then
719 print("testing failed write") 719 print("testing failed write")
720 720
721 -- unable to write anything to /dev/full 721 -- unable to write anything to /dev/full
@@ -840,7 +840,7 @@ assert(os.date("!\0\0") == "\0\0")
840local x = string.rep("a", 10000) 840local x = string.rep("a", 10000)
841assert(os.date(x) == x) 841assert(os.date(x) == x)
842local t = os.time() 842local t = os.time()
843global D; D = os.date("*t", t) 843global D = os.date("*t", t)
844assert(os.date(string.rep("%d", 1000), t) == 844assert(os.date(string.rep("%d", 1000), t) ==
845 string.rep(os.date("%d", t), 1000)) 845 string.rep(os.date("%d", t), 1000))
846assert(os.date(string.rep("%", 200)) == string.rep("%", 100)) 846assert(os.date(string.rep("%", 200)) == string.rep("%", 100))
diff --git a/testes/goto.lua b/testes/goto.lua
index 3519e75d..3310314d 100644
--- a/testes/goto.lua
+++ b/testes/goto.lua
@@ -380,7 +380,7 @@ do
380 global * 380 global *
381 Y = x + Y 381 Y = x + Y
382 assert(_ENV.Y == 20) 382 assert(_ENV.Y == 20)
383 383 Y = nil
384end 384end
385 385
386 386
@@ -411,5 +411,26 @@ do -- mixing lots of global/local declarations
411 _ENV.x200 = nil 411 _ENV.x200 = nil
412end 412end
413 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
434
414print'OK' 435print'OK'
415 436
diff --git a/testes/tracegc.lua b/testes/tracegc.lua
index 9c5c1b3f..a8c929df 100644
--- a/testes/tracegc.lua
+++ b/testes/tracegc.lua
@@ -6,7 +6,7 @@ local M = {}
6local setmetatable, stderr, collectgarbage = 6local setmetatable, stderr, collectgarbage =
7 setmetatable, io.stderr, collectgarbage 7 setmetatable, io.stderr, collectgarbage
8 8
9_ENV = nil 9global none
10 10
11local active = false 11local active = false
12 12