diff options
-rw-r--r-- | llex.c | 7 | ||||
-rw-r--r-- | llex.h | 4 | ||||
-rw-r--r-- | lparser.c | 111 | ||||
-rw-r--r-- | lparser.h | 15 | ||||
-rw-r--r-- | ltests.h | 1 | ||||
-rw-r--r-- | luaconf.h | 6 | ||||
-rw-r--r-- | manual/manual.of | 184 | ||||
-rw-r--r-- | testes/db.lua | 1 | ||||
-rw-r--r-- | testes/goto.lua | 44 | ||||
-rw-r--r-- | testes/math.lua | 16 |
10 files changed, 272 insertions, 117 deletions
@@ -40,11 +40,16 @@ | |||
40 | 40 | ||
41 | #define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') | 41 | #define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') |
42 | 42 | ||
43 | #if defined(LUA_COMPAT_GLOBAL) | ||
44 | #define GLOBALLEX ".g" /* not recognizable by the scanner */ | ||
45 | #else | ||
46 | #define GLOBALLEX "global" | ||
47 | #endif | ||
43 | 48 | ||
44 | /* ORDER RESERVED */ | 49 | /* ORDER RESERVED */ |
45 | static const char *const luaX_tokens [] = { | 50 | static const char *const luaX_tokens [] = { |
46 | "and", "break", "do", "else", "elseif", | 51 | "and", "break", "do", "else", "elseif", |
47 | "end", "false", "for", "function", "goto", "if", | 52 | "end", "false", "for", "function", GLOBALLEX, "goto", "if", |
48 | "in", "local", "nil", "not", "or", "repeat", | 53 | "in", "local", "nil", "not", "or", "repeat", |
49 | "return", "then", "true", "until", "while", | 54 | "return", "then", "true", "until", "while", |
50 | "//", "..", "...", "==", ">=", "<=", "~=", | 55 | "//", "..", "...", "==", ">=", "<=", "~=", |
@@ -33,8 +33,8 @@ enum RESERVED { | |||
33 | /* terminal symbols denoted by reserved words */ | 33 | /* terminal symbols denoted by reserved words */ |
34 | TK_AND = FIRST_RESERVED, TK_BREAK, | 34 | TK_AND = FIRST_RESERVED, TK_BREAK, |
35 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, | 35 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, |
36 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, | 36 | TK_GLOBAL, TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, |
37 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, | 37 | TK_REPEAT, TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, |
38 | /* other terminal symbols */ | 38 | /* other terminal symbols */ |
39 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, | 39 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, |
40 | TK_SHL, TK_SHR, | 40 | TK_SHL, TK_SHR, |
@@ -30,8 +30,8 @@ | |||
30 | 30 | ||
31 | 31 | ||
32 | 32 | ||
33 | /* maximum number of local variables per function (must be smaller | 33 | /* maximum number of variable declarationss per function (must be |
34 | 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 | ||
37 | 37 | ||
@@ -54,6 +54,7 @@ typedef struct BlockCnt { | |||
54 | lu_byte upval; /* true if some variable in the block is an upvalue */ | 54 | lu_byte upval; /* true if some variable in the block is an upvalue */ |
55 | lu_byte isloop; /* 1 if 'block' is a loop; 2 if it has pending breaks */ | 55 | lu_byte isloop; /* 1 if 'block' is a loop; 2 if it has pending breaks */ |
56 | lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */ | 56 | lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */ |
57 | lu_byte globdec; /* true if inside the scope of any global declaration */ | ||
57 | } BlockCnt; | 58 | } BlockCnt; |
58 | 59 | ||
59 | 60 | ||
@@ -188,10 +189,10 @@ static short registerlocalvar (LexState *ls, FuncState *fs, | |||
188 | 189 | ||
189 | 190 | ||
190 | /* | 191 | /* |
191 | ** Create a new local variable with the given 'name' and given 'kind'. | 192 | ** Create a new variable with the given 'name' and given 'kind'. |
192 | ** Return its index in the function. | 193 | ** Return its index in the function. |
193 | */ | 194 | */ |
194 | static int new_localvarkind (LexState *ls, TString *name, lu_byte kind) { | 195 | static int new_varkind (LexState *ls, TString *name, lu_byte kind) { |
195 | lua_State *L = ls->L; | 196 | lua_State *L = ls->L; |
196 | FuncState *fs = ls->fs; | 197 | FuncState *fs = ls->fs; |
197 | Dyndata *dyd = ls->dyd; | 198 | Dyndata *dyd = ls->dyd; |
@@ -211,7 +212,7 @@ static int new_localvarkind (LexState *ls, TString *name, lu_byte kind) { | |||
211 | ** Create a new local variable with the given 'name' and regular kind. | 212 | ** Create a new local variable with the given 'name' and regular kind. |
212 | */ | 213 | */ |
213 | static int new_localvar (LexState *ls, TString *name) { | 214 | static int new_localvar (LexState *ls, TString *name) { |
214 | return new_localvarkind(ls, name, VDKREG); | 215 | return new_varkind(ls, name, VDKREG); |
215 | } | 216 | } |
216 | 217 | ||
217 | #define new_localvarliteral(ls,v) \ | 218 | #define new_localvarliteral(ls,v) \ |
@@ -238,7 +239,7 @@ static Vardesc *getlocalvardesc (FuncState *fs, int vidx) { | |||
238 | static lu_byte reglevel (FuncState *fs, int nvar) { | 239 | static lu_byte reglevel (FuncState *fs, int nvar) { |
239 | while (nvar-- > 0) { | 240 | while (nvar-- > 0) { |
240 | Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */ | 241 | Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */ |
241 | if (vd->vd.kind != RDKCTC) /* is in a register? */ | 242 | if (varinreg(vd)) /* is in a register? */ |
242 | return cast_byte(vd->vd.ridx + 1); | 243 | return cast_byte(vd->vd.ridx + 1); |
243 | } | 244 | } |
244 | return 0; /* no variables in registers */ | 245 | return 0; /* no variables in registers */ |
@@ -259,7 +260,7 @@ lu_byte luaY_nvarstack (FuncState *fs) { | |||
259 | */ | 260 | */ |
260 | static LocVar *localdebuginfo (FuncState *fs, int vidx) { | 261 | static LocVar *localdebuginfo (FuncState *fs, int vidx) { |
261 | Vardesc *vd = getlocalvardesc(fs, vidx); | 262 | Vardesc *vd = getlocalvardesc(fs, vidx); |
262 | if (vd->vd.kind == RDKCTC) | 263 | if (!varinreg(vd)) |
263 | return NULL; /* no debug info. for constants */ | 264 | return NULL; /* no debug info. for constants */ |
264 | else { | 265 | else { |
265 | int idx = vd->vd.pidx; | 266 | int idx = vd->vd.pidx; |
@@ -401,7 +402,9 @@ static int searchvar (FuncState *fs, TString *n, expdesc *var) { | |||
401 | if (eqstr(n, vd->vd.name)) { /* found? */ | 402 | if (eqstr(n, vd->vd.name)) { /* found? */ |
402 | if (vd->vd.kind == RDKCTC) /* compile-time constant? */ | 403 | if (vd->vd.kind == RDKCTC) /* compile-time constant? */ |
403 | init_exp(var, VCONST, fs->firstlocal + i); | 404 | init_exp(var, VCONST, fs->firstlocal + i); |
404 | else /* real variable */ | 405 | else if (vd->vd.kind == GDKREG || vd->vd.kind == GDKCONST) |
406 | init_exp(var, VGLOBAL, i); | ||
407 | else /* local variable */ | ||
405 | init_var(fs, var, i); | 408 | init_var(fs, var, i); |
406 | return cast_int(var->k); | 409 | return cast_int(var->k); |
407 | } | 410 | } |
@@ -440,25 +443,24 @@ static void marktobeclosed (FuncState *fs) { | |||
440 | ** 'var' as 'void' as a flag. | 443 | ** 'var' as 'void' as a flag. |
441 | */ | 444 | */ |
442 | static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | 445 | static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { |
443 | if (fs == NULL) /* no more levels? */ | 446 | int v = searchvar(fs, n, var); /* look up locals at current level */ |
444 | init_exp(var, VVOID, 0); /* default is global */ | 447 | if (v >= 0) { /* found? */ |
445 | else { | 448 | if (v == VLOCAL && !base) |
446 | int v = searchvar(fs, n, var); /* look up locals at current level */ | 449 | markupval(fs, var->u.var.vidx); /* local will be used as an upval */ |
447 | if (v >= 0) { /* found? */ | 450 | } |
448 | if (v == VLOCAL && !base) | 451 | else { /* not found as local at current level; try upvalues */ |
449 | markupval(fs, var->u.var.vidx); /* local will be used as an upval */ | 452 | int idx = searchupvalue(fs, n); /* try existing upvalues */ |
450 | } | 453 | if (idx < 0) { /* not found? */ |
451 | else { /* not found as local at current level; try upvalues */ | 454 | if (fs->prev != NULL) /* more levels? */ |
452 | int idx = searchupvalue(fs, n); /* try existing upvalues */ | ||
453 | if (idx < 0) { /* not found? */ | ||
454 | singlevaraux(fs->prev, n, var, 0); /* try upper levels */ | 455 | singlevaraux(fs->prev, n, var, 0); /* try upper levels */ |
455 | if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ | 456 | else /* no more levels */ |
456 | idx = newupvalue(fs, n, var); /* will be a new upvalue */ | 457 | init_exp(var, VGLOBAL, -1); /* global by default */ |
457 | else /* it is a global or a constant */ | 458 | if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ |
458 | return; /* don't need to do anything at this level */ | 459 | idx = newupvalue(fs, n, var); /* will be a new upvalue */ |
459 | } | 460 | else /* it is a global or a constant */ |
460 | init_exp(var, VUPVAL, idx); /* new or old upvalue */ | 461 | return; /* don't need to do anything at this level */ |
461 | } | 462 | } |
463 | init_exp(var, VUPVAL, idx); /* new or old upvalue */ | ||
462 | } | 464 | } |
463 | } | 465 | } |
464 | 466 | ||
@@ -471,10 +473,15 @@ static void singlevar (LexState *ls, expdesc *var) { | |||
471 | TString *varname = str_checkname(ls); | 473 | TString *varname = str_checkname(ls); |
472 | FuncState *fs = ls->fs; | 474 | FuncState *fs = ls->fs; |
473 | singlevaraux(fs, varname, var, 1); | 475 | singlevaraux(fs, varname, var, 1); |
474 | if (var->k == VVOID) { /* global name? */ | 476 | if (var->k == VGLOBAL) { /* global name? */ |
475 | expdesc key; | 477 | expdesc key; |
478 | /* global by default in the scope of a global declaration? */ | ||
479 | if (var->u.info == -1 && fs->bl->globdec) | ||
480 | luaK_semerror(ls, "variable '%s' not declared", getstr(varname)); | ||
476 | singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ | 481 | singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ |
477 | lua_assert(var->k != VVOID); /* this one must exist */ | 482 | if (var->k == VGLOBAL) |
483 | luaK_semerror(ls, "_ENV is global when accessing variable '%s'", | ||
484 | getstr(varname)); | ||
478 | luaK_exp2anyregup(fs, var); /* but could be a constant */ | 485 | luaK_exp2anyregup(fs, var); /* but could be a constant */ |
479 | codestring(&key, varname); /* key is variable name */ | 486 | codestring(&key, varname); /* key is variable name */ |
480 | luaK_indexed(fs, var, &key); /* env[varname] */ | 487 | luaK_indexed(fs, var, &key); /* env[varname] */ |
@@ -664,8 +671,13 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { | |||
664 | bl->firstlabel = fs->ls->dyd->label.n; | 671 | bl->firstlabel = fs->ls->dyd->label.n; |
665 | bl->firstgoto = fs->ls->dyd->gt.n; | 672 | bl->firstgoto = fs->ls->dyd->gt.n; |
666 | bl->upval = 0; | 673 | bl->upval = 0; |
674 | /* inherit 'insidetbc' from enclosing block */ | ||
667 | bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); | 675 | bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); |
668 | bl->previous = fs->bl; | 676 | /* inherit 'globdec' from enclosing block or enclosing function */ |
677 | bl->globdec = fs->bl != NULL ? fs->bl->globdec | ||
678 | : fs->prev != NULL ? fs->prev->bl->globdec | ||
679 | : 0; /* chunk's first block */ | ||
680 | bl->previous = fs->bl; /* link block in function's block list */ | ||
669 | fs->bl = bl; | 681 | fs->bl = bl; |
670 | lua_assert(fs->freereg == luaY_nvarstack(fs)); | 682 | lua_assert(fs->freereg == luaY_nvarstack(fs)); |
671 | } | 683 | } |
@@ -1600,7 +1612,7 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1600 | int base = fs->freereg; | 1612 | int base = fs->freereg; |
1601 | new_localvarliteral(ls, "(for state)"); | 1613 | new_localvarliteral(ls, "(for state)"); |
1602 | new_localvarliteral(ls, "(for state)"); | 1614 | new_localvarliteral(ls, "(for state)"); |
1603 | new_localvarkind(ls, varname, RDKCONST); /* control variable */ | 1615 | new_varkind(ls, varname, RDKCONST); /* control variable */ |
1604 | checknext(ls, '='); | 1616 | checknext(ls, '='); |
1605 | exp1(ls); /* initial value */ | 1617 | exp1(ls); /* initial value */ |
1606 | checknext(ls, ','); | 1618 | checknext(ls, ','); |
@@ -1627,7 +1639,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1627 | new_localvarliteral(ls, "(for state)"); /* iterator function */ | 1639 | new_localvarliteral(ls, "(for state)"); /* iterator function */ |
1628 | new_localvarliteral(ls, "(for state)"); /* state */ | 1640 | new_localvarliteral(ls, "(for state)"); /* state */ |
1629 | new_localvarliteral(ls, "(for state)"); /* closing var. (after swap) */ | 1641 | new_localvarliteral(ls, "(for state)"); /* closing var. (after swap) */ |
1630 | new_localvarkind(ls, indexname, RDKCONST); /* control variable */ | 1642 | new_varkind(ls, indexname, RDKCONST); /* control variable */ |
1631 | /* other declared variables */ | 1643 | /* other declared variables */ |
1632 | while (testnext(ls, ',')) { | 1644 | while (testnext(ls, ',')) { |
1633 | new_localvar(ls, str_checkname(ls)); | 1645 | new_localvar(ls, str_checkname(ls)); |
@@ -1702,7 +1714,7 @@ static void localfunc (LexState *ls) { | |||
1702 | } | 1714 | } |
1703 | 1715 | ||
1704 | 1716 | ||
1705 | static lu_byte getlocalattribute (LexState *ls) { | 1717 | static lu_byte getvarattribute (LexState *ls) { |
1706 | /* ATTRIB -> ['<' Name '>'] */ | 1718 | /* ATTRIB -> ['<' Name '>'] */ |
1707 | if (testnext(ls, '<')) { | 1719 | if (testnext(ls, '<')) { |
1708 | TString *ts = str_checkname(ls); | 1720 | TString *ts = str_checkname(ls); |
@@ -1738,8 +1750,8 @@ static void localstat (LexState *ls) { | |||
1738 | expdesc e; | 1750 | expdesc e; |
1739 | do { | 1751 | do { |
1740 | TString *vname = str_checkname(ls); | 1752 | TString *vname = str_checkname(ls); |
1741 | lu_byte kind = getlocalattribute(ls); | 1753 | lu_byte kind = getvarattribute(ls); |
1742 | vidx = new_localvarkind(ls, vname, kind); | 1754 | vidx = new_varkind(ls, vname, kind); |
1743 | if (kind == RDKTOCLOSE) { /* to-be-closed? */ | 1755 | if (kind == RDKTOCLOSE) { /* to-be-closed? */ |
1744 | if (toclose != -1) /* one already present? */ | 1756 | if (toclose != -1) /* one already present? */ |
1745 | luaK_semerror(ls, "multiple to-be-closed variables in local list"); | 1757 | luaK_semerror(ls, "multiple to-be-closed variables in local list"); |
@@ -1769,6 +1781,24 @@ static void localstat (LexState *ls) { | |||
1769 | } | 1781 | } |
1770 | 1782 | ||
1771 | 1783 | ||
1784 | static void globalstat (LexState *ls) { | ||
1785 | FuncState *fs = ls->fs; | ||
1786 | luaX_next(ls); /* skip 'global' */ | ||
1787 | do { | ||
1788 | TString *vname = str_checkname(ls); | ||
1789 | lu_byte kind = getvarattribute(ls); | ||
1790 | if (kind == RDKTOCLOSE) | ||
1791 | luaK_semerror(ls, "global variable ('%s') cannot be to-be-closed", | ||
1792 | getstr(vname)); | ||
1793 | /* adjust kind for global variable */ | ||
1794 | kind = (kind == VDKREG) ? GDKREG : GDKCONST; | ||
1795 | new_varkind(ls, vname, kind); | ||
1796 | fs->nactvar++; /* activate declaration */ | ||
1797 | } while (testnext(ls, ',')); | ||
1798 | fs->bl->globdec = 1; /* code is in the scope of a global declaration */ | ||
1799 | } | ||
1800 | |||
1801 | |||
1772 | static int funcname (LexState *ls, expdesc *v) { | 1802 | static int funcname (LexState *ls, expdesc *v) { |
1773 | /* funcname -> NAME {fieldsel} [':' NAME] */ | 1803 | /* funcname -> NAME {fieldsel} [':' NAME] */ |
1774 | int ismethod = 0; | 1804 | int ismethod = 0; |
@@ -1888,6 +1918,10 @@ static void statement (LexState *ls) { | |||
1888 | localstat(ls); | 1918 | localstat(ls); |
1889 | break; | 1919 | break; |
1890 | } | 1920 | } |
1921 | case TK_GLOBAL: { /* stat -> globalstat */ | ||
1922 | globalstat(ls); | ||
1923 | break; | ||
1924 | } | ||
1891 | case TK_DBCOLON: { /* stat -> label */ | 1925 | case TK_DBCOLON: { /* stat -> label */ |
1892 | luaX_next(ls); /* skip double colon */ | 1926 | luaX_next(ls); /* skip double colon */ |
1893 | labelstat(ls, str_checkname(ls), line); | 1927 | labelstat(ls, str_checkname(ls), line); |
@@ -1907,6 +1941,17 @@ static void statement (LexState *ls) { | |||
1907 | gotostat(ls, line); | 1941 | gotostat(ls, line); |
1908 | break; | 1942 | break; |
1909 | } | 1943 | } |
1944 | case TK_NAME: { | ||
1945 | /* compatibility code to parse global keyword when "global" | ||
1946 | is not reserved */ | ||
1947 | if (eqstr(ls->t.seminfo.ts, luaS_newliteral(ls->L, "global"))) { | ||
1948 | int lk = luaX_lookahead(ls); | ||
1949 | if (lk == TK_NAME) { /* 'global name'? */ | ||
1950 | globalstat(ls); | ||
1951 | break; | ||
1952 | } | ||
1953 | } /* else... */ | ||
1954 | } /* FALLTHROUGH */ | ||
1910 | default: { /* stat -> func | assignment */ | 1955 | default: { /* stat -> func | assignment */ |
1911 | exprstat(ls); | 1956 | exprstat(ls); |
1912 | break; | 1957 | break; |
@@ -37,6 +37,9 @@ typedef enum { | |||
37 | info = result register */ | 37 | info = result register */ |
38 | VLOCAL, /* local variable; var.ridx = register index; | 38 | VLOCAL, /* local variable; var.ridx = register index; |
39 | var.vidx = relative index in 'actvar.arr' */ | 39 | var.vidx = relative index in 'actvar.arr' */ |
40 | VGLOBAL, /* global variable; | ||
41 | info = relative index in 'actvar.arr' (or -1 for | ||
42 | implicit declaration) */ | ||
40 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ | 43 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ |
41 | VCONST, /* compile-time <const> variable; | 44 | VCONST, /* compile-time <const> variable; |
42 | info = absolute index in 'actvar.arr' */ | 45 | info = absolute index in 'actvar.arr' */ |
@@ -87,10 +90,16 @@ typedef struct expdesc { | |||
87 | 90 | ||
88 | 91 | ||
89 | /* kinds of variables */ | 92 | /* kinds of variables */ |
90 | #define VDKREG 0 /* regular */ | 93 | #define VDKREG 0 /* regular local */ |
91 | #define RDKCONST 1 /* constant */ | 94 | #define RDKCONST 1 /* local constant */ |
92 | #define RDKTOCLOSE 2 /* to-be-closed */ | 95 | #define RDKTOCLOSE 2 /* to-be-closed */ |
93 | #define RDKCTC 3 /* compile-time constant */ | 96 | #define RDKCTC 3 /* local compile-time constant */ |
97 | #define GDKREG 4 /* regular global */ | ||
98 | #define GDKCONST 5 /* global constant */ | ||
99 | |||
100 | /* variables that live in registers */ | ||
101 | #define varinreg(v) ((v)->vd.kind <= RDKTOCLOSE) | ||
102 | |||
94 | 103 | ||
95 | /* description of an active local variable */ | 104 | /* description of an active local variable */ |
96 | typedef union Vardesc { | 105 | typedef union Vardesc { |
@@ -14,6 +14,7 @@ | |||
14 | /* test Lua with compatibility code */ | 14 | /* test Lua with compatibility code */ |
15 | #define LUA_COMPAT_MATHLIB | 15 | #define LUA_COMPAT_MATHLIB |
16 | #define LUA_COMPAT_LT_LE | 16 | #define LUA_COMPAT_LT_LE |
17 | #undef LUA_COMPAT_GLOBAL | ||
17 | 18 | ||
18 | 19 | ||
19 | #define LUA_DEBUG | 20 | #define LUA_DEBUG |
@@ -356,6 +356,12 @@ | |||
356 | */ | 356 | */ |
357 | 357 | ||
358 | /* | 358 | /* |
359 | @@ LUA_COMPAT_GLOBAL avoids 'global' being a reserved word | ||
360 | */ | ||
361 | #define LUA_COMPAT_GLOBAL | ||
362 | |||
363 | |||
364 | /* | ||
359 | @@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3. | 365 | @@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3. |
360 | ** You can define it to get all options, or change specific options | 366 | ** You can define it to get all options, or change specific options |
361 | ** to fit your specific needs. | 367 | ** to fit your specific needs. |
diff --git a/manual/manual.of b/manual/manual.of index 7cd0d4db..ace5d375 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
@@ -213,11 +213,88 @@ of a given value @seeF{type}. | |||
213 | 213 | ||
214 | } | 214 | } |
215 | 215 | ||
216 | @sect2{globalenv| @title{Environments and the Global Environment} | 216 | @sect2{globalenv| @title{Scopes, Variables, and Environments} |
217 | @index{visibility} | ||
218 | |||
219 | A variable name refers to a global or a local variable according | ||
220 | to the declaration that is in context at that point of the code. | ||
221 | (For the purposes of this discussion, | ||
222 | a function's formal parameter is equivalent to a local variable.) | ||
223 | |||
224 | All chunks start with an implicit declaration @T{global *}, | ||
225 | which declares all free names as global variables; | ||
226 | this implicit declaration becomes void inside the scope of any other | ||
227 | @Rw{global} declaration, regardless of the names being declared. | ||
228 | @verbatim{ | ||
229 | X = 1 -- Ok, global by default | ||
230 | do | ||
231 | global Y -- voids implicit initial declaration | ||
232 | X = 1 -- ERROR, X not declared | ||
233 | Y = 1 -- Ok, Y declared as global | ||
234 | end | ||
235 | X = 2 -- Ok, global by default again | ||
236 | } | ||
237 | So, outside any global declaration, | ||
238 | Lua works as @x{global-by-default}. | ||
239 | Inside any global declaration, | ||
240 | Lua works without a default: | ||
241 | All variables must be declared. | ||
242 | |||
243 | Lua is a lexically scoped language. | ||
244 | The scope of a variable declaration begins at the first statement after | ||
245 | the declaration and lasts until the last non-void statement | ||
246 | of the innermost block that includes the declaration. | ||
247 | (@emph{Void statements} are labels and empty statements.) | ||
248 | |||
249 | A declaration shadows any declaration for the same name that | ||
250 | is in context at the point of the declaration. Inside this | ||
251 | shadow, any outer declaration for that name is void. | ||
252 | See the next example: | ||
253 | @verbatim{ | ||
254 | global print, x | ||
255 | x = 10 -- global variable | ||
256 | do -- new block | ||
257 | local x = x -- new 'x', with value 10 | ||
258 | print(x) --> 10 | ||
259 | x = x+1 | ||
260 | do -- another block | ||
261 | local x = x+1 -- another 'x' | ||
262 | print(x) --> 12 | ||
263 | end | ||
264 | print(x) --> 11 | ||
265 | end | ||
266 | print(x) --> 10 (the global one) | ||
267 | } | ||
268 | |||
269 | Notice that, in a declaration like @T{local x = x}, | ||
270 | the new @id{x} being declared is not in scope yet, | ||
271 | and so the @id{x} in the left-hand side refers to the outside variable. | ||
272 | |||
273 | Because of the @x{lexical scoping} rules, | ||
274 | local variables can be freely accessed by functions | ||
275 | defined inside their scope. | ||
276 | A local variable used by an inner function is called an @def{upvalue} | ||
277 | (or @emphx{external local variable}, or simply @emphx{external variable}) | ||
278 | inside the inner function. | ||
279 | |||
280 | Notice that each execution of a @Rw{local} statement | ||
281 | defines new local variables. | ||
282 | Consider the following example: | ||
283 | @verbatim{ | ||
284 | a = {} | ||
285 | local x = 20 | ||
286 | for i = 1, 10 do | ||
287 | local y = 0 | ||
288 | a[i] = function () y = y + 1; return x + y end | ||
289 | end | ||
290 | } | ||
291 | The loop creates ten closures | ||
292 | (that is, ten instances of the anonymous function). | ||
293 | Each of these closures uses a different @id{y} variable, | ||
294 | while all of them share the same @id{x}. | ||
217 | 295 | ||
218 | As we will discuss further in @refsec{variables} and @refsec{assignment}, | 296 | As we will discuss further in @refsec{variables} and @refsec{assignment}, |
219 | any reference to a free name | 297 | any reference to a global variable @id{var} |
220 | (that is, a name not bound to any declaration) @id{var} | ||
221 | is syntactically translated to @T{_ENV.var}. | 298 | is syntactically translated to @T{_ENV.var}. |
222 | Moreover, every chunk is compiled in the scope of | 299 | Moreover, every chunk is compiled in the scope of |
223 | an external local variable named @id{_ENV} @see{chunks}, | 300 | an external local variable named @id{_ENV} @see{chunks}, |
@@ -225,12 +302,14 @@ so @id{_ENV} itself is never a free name in a chunk. | |||
225 | 302 | ||
226 | Despite the existence of this external @id{_ENV} variable and | 303 | Despite the existence of this external @id{_ENV} variable and |
227 | the translation of free names, | 304 | the translation of free names, |
228 | @id{_ENV} is a completely regular name. | 305 | @id{_ENV} is a regular name. |
229 | In particular, | 306 | In particular, |
230 | you can define new variables and parameters with that name. | 307 | you can define new variables and parameters with that name. |
231 | Each reference to a free name uses the @id{_ENV} that is | 308 | (However, you should not define @id{_ENV} as a global variable, |
232 | visible at that point in the program, | 309 | otherwise @T{_ENV.var} would translate to |
233 | following the usual visibility rules of Lua @see{visibility}. | 310 | @T{_ENV._ENV.var} and so on, in an infinite loop.) |
311 | Each reference to a global variable name uses the @id{_ENV} that is | ||
312 | visible at that point in the program. | ||
234 | 313 | ||
235 | Any table used as the value of @id{_ENV} is called an @def{environment}. | 314 | Any table used as the value of @id{_ENV} is called an @def{environment}. |
236 | 315 | ||
@@ -244,8 +323,8 @@ When Lua loads a chunk, | |||
244 | the default value for its @id{_ENV} variable | 323 | the default value for its @id{_ENV} variable |
245 | is the global environment @seeF{load}. | 324 | is the global environment @seeF{load}. |
246 | Therefore, by default, | 325 | Therefore, by default, |
247 | free names in Lua code refer to entries in the global environment | 326 | global variables in Lua code refer to entries in the global environment |
248 | and, therefore, they are also called @def{global variables}. | 327 | and, therefore, they act as conventional global variables. |
249 | Moreover, all standard libraries are loaded in the global environment | 328 | Moreover, all standard libraries are loaded in the global environment |
250 | and some functions there operate on that environment. | 329 | and some functions there operate on that environment. |
251 | You can use @Lid{load} (or @Lid{loadfile}) | 330 | You can use @Lid{load} (or @Lid{loadfile}) |
@@ -1198,17 +1277,15 @@ global variables, local variables, and table fields. | |||
1198 | 1277 | ||
1199 | A single name can denote a global variable or a local variable | 1278 | A single name can denote a global variable or a local variable |
1200 | (or a function's formal parameter, | 1279 | (or a function's formal parameter, |
1201 | which is a particular kind of local variable): | 1280 | which is a particular kind of local variable) @see{globalenv}: |
1202 | @Produc{ | 1281 | @Produc{ |
1203 | @producname{var}@producbody{@bnfNter{Name}} | 1282 | @producname{var}@producbody{@bnfNter{Name}} |
1204 | } | 1283 | } |
1205 | @bnfNter{Name} denotes identifiers @see{lexical}. | 1284 | @bnfNter{Name} denotes identifiers @see{lexical}. |
1206 | 1285 | ||
1207 | Any variable name is assumed to be global unless explicitly declared | 1286 | Because variables are @emph{lexically scoped}, |
1208 | as a local @see{localvar}. | ||
1209 | @x{Local variables} are @emph{lexically scoped}: | ||
1210 | local variables can be freely accessed by functions | 1287 | local variables can be freely accessed by functions |
1211 | defined inside their scope @see{visibility}. | 1288 | defined inside their scope @see{globalenv}. |
1212 | 1289 | ||
1213 | Before the first assignment to a variable, its value is @nil. | 1290 | Before the first assignment to a variable, its value is @nil. |
1214 | 1291 | ||
@@ -1227,8 +1304,6 @@ The syntax @id{var.Name} is just syntactic sugar for | |||
1227 | 1304 | ||
1228 | An access to a global variable @id{x} | 1305 | An access to a global variable @id{x} |
1229 | is equivalent to @id{_ENV.x}. | 1306 | is equivalent to @id{_ENV.x}. |
1230 | Due to the way that chunks are compiled, | ||
1231 | the variable @id{_ENV} itself is never global @see{globalenv}. | ||
1232 | 1307 | ||
1233 | } | 1308 | } |
1234 | 1309 | ||
@@ -1571,17 +1646,18 @@ Function calls are explained in @See{functioncall}. | |||
1571 | 1646 | ||
1572 | } | 1647 | } |
1573 | 1648 | ||
1574 | @sect3{localvar| @title{Local Declarations} | 1649 | @sect3{localvar| @title{Variable Declarations} |
1575 | @x{Local variables} can be declared anywhere inside a block. | 1650 | Local and global variables can be declared anywhere inside a block. |
1576 | The declaration can include an initialization: | 1651 | The declaration for locals can include an initialization: |
1577 | @Produc{ | 1652 | @Produc{ |
1578 | @producname{stat}@producbody{@Rw{local} attnamelist @bnfopt{@bnfter{=} explist}} | 1653 | @producname{stat}@producbody{@Rw{local} attnamelist @bnfopt{@bnfter{=} explist}} |
1654 | @producname{stat}@producbody{@Rw{global} attnamelist} | ||
1579 | @producname{attnamelist}@producbody{ | 1655 | @producname{attnamelist}@producbody{ |
1580 | @bnfNter{Name} attrib @bnfrep{@bnfter{,} @bnfNter{Name} attrib}} | 1656 | @bnfNter{Name} attrib @bnfrep{@bnfter{,} @bnfNter{Name} attrib}} |
1581 | } | 1657 | } |
1582 | If present, an initial assignment has the same semantics | 1658 | If present, an initial assignment has the same semantics |
1583 | of a multiple assignment @see{assignment}. | 1659 | of a multiple assignment @see{assignment}. |
1584 | Otherwise, all variables are initialized with @nil. | 1660 | Otherwise, all local variables are initialized with @nil. |
1585 | 1661 | ||
1586 | Each variable name may be postfixed by an attribute | 1662 | Each variable name may be postfixed by an attribute |
1587 | (a name between angle brackets): | 1663 | (a name between angle brackets): |
@@ -1595,11 +1671,22 @@ that is, a variable that cannot be assigned to | |||
1595 | after its initialization; | 1671 | after its initialization; |
1596 | and @id{close}, which declares a to-be-closed variable @see{to-be-closed}. | 1672 | and @id{close}, which declares a to-be-closed variable @see{to-be-closed}. |
1597 | A list of variables can contain at most one to-be-closed variable. | 1673 | A list of variables can contain at most one to-be-closed variable. |
1674 | Only local variables can have the @id{close} attribute. | ||
1675 | |||
1676 | Note that, for global variables, | ||
1677 | the @emph{read-only} atribute is only a syntactical restriction: | ||
1678 | @verbatim{ | ||
1679 | global X <const> | ||
1680 | X = 1 -- ERROR | ||
1681 | _ENV.X = 1 -- Ok | ||
1682 | foo() -- 'foo' can freely change the global X | ||
1683 | } | ||
1598 | 1684 | ||
1599 | A chunk is also a block @see{chunks}, | 1685 | A chunk is also a block @see{chunks}, |
1600 | and so local variables can be declared in a chunk outside any explicit block. | 1686 | and so variables can be declared in a chunk outside any explicit block. |
1601 | 1687 | ||
1602 | The visibility rules for local variables are explained in @See{visibility}. | 1688 | The visibility rules for variable declarations |
1689 | are explained in @See{globalenv}. | ||
1603 | 1690 | ||
1604 | } | 1691 | } |
1605 | 1692 | ||
@@ -2356,58 +2443,6 @@ return x,y,f() -- returns x, y, and all results from f(). | |||
2356 | 2443 | ||
2357 | } | 2444 | } |
2358 | 2445 | ||
2359 | @sect2{visibility| @title{Visibility Rules} | ||
2360 | |||
2361 | @index{visibility} | ||
2362 | Lua is a lexically scoped language. | ||
2363 | The scope of a local variable begins at the first statement after | ||
2364 | its declaration and lasts until the last non-void statement | ||
2365 | of the innermost block that includes the declaration. | ||
2366 | (@emph{Void statements} are labels and empty statements.) | ||
2367 | Consider the following example: | ||
2368 | @verbatim{ | ||
2369 | x = 10 -- global variable | ||
2370 | do -- new block | ||
2371 | local x = x -- new 'x', with value 10 | ||
2372 | print(x) --> 10 | ||
2373 | x = x+1 | ||
2374 | do -- another block | ||
2375 | local x = x+1 -- another 'x' | ||
2376 | print(x) --> 12 | ||
2377 | end | ||
2378 | print(x) --> 11 | ||
2379 | end | ||
2380 | print(x) --> 10 (the global one) | ||
2381 | } | ||
2382 | |||
2383 | Notice that, in a declaration like @T{local x = x}, | ||
2384 | the new @id{x} being declared is not in scope yet, | ||
2385 | and so the second @id{x} refers to the outside variable. | ||
2386 | |||
2387 | Because of the @x{lexical scoping} rules, | ||
2388 | local variables can be freely accessed by functions | ||
2389 | defined inside their scope. | ||
2390 | A local variable used by an inner function is called an @def{upvalue} | ||
2391 | (or @emphx{external local variable}, or simply @emphx{external variable}) | ||
2392 | inside the inner function. | ||
2393 | |||
2394 | Notice that each execution of a @Rw{local} statement | ||
2395 | defines new local variables. | ||
2396 | Consider the following example: | ||
2397 | @verbatim{ | ||
2398 | a = {} | ||
2399 | local x = 20 | ||
2400 | for i = 1, 10 do | ||
2401 | local y = 0 | ||
2402 | a[i] = function () y = y + 1; return x + y end | ||
2403 | end | ||
2404 | } | ||
2405 | The loop creates ten closures | ||
2406 | (that is, ten instances of the anonymous function). | ||
2407 | Each of these closures uses a different @id{y} variable, | ||
2408 | while all of them share the same @id{x}. | ||
2409 | |||
2410 | } | ||
2411 | 2446 | ||
2412 | } | 2447 | } |
2413 | 2448 | ||
@@ -9535,6 +9570,7 @@ and @bnfNter{LiteralString}, see @See{lexical}.) | |||
9535 | @OrNL @Rw{function} funcname funcbody | 9570 | @OrNL @Rw{function} funcname funcbody |
9536 | @OrNL @Rw{local} @Rw{function} @bnfNter{Name} funcbody | 9571 | @OrNL @Rw{local} @Rw{function} @bnfNter{Name} funcbody |
9537 | @OrNL @Rw{local} attnamelist @bnfopt{@bnfter{=} explist} | 9572 | @OrNL @Rw{local} attnamelist @bnfopt{@bnfter{=} explist} |
9573 | @OrNL @Rw{global} attnamelist | ||
9538 | } | 9574 | } |
9539 | 9575 | ||
9540 | @producname{attnamelist}@producbody{ | 9576 | @producname{attnamelist}@producbody{ |
diff --git a/testes/db.lua b/testes/db.lua index e4982c20..ae204c41 100644 --- a/testes/db.lua +++ b/testes/db.lua | |||
@@ -349,6 +349,7 @@ end, "crl") | |||
349 | 349 | ||
350 | 350 | ||
351 | function f(a,b) | 351 | function f(a,b) |
352 | global collectgarbage, assert, g, string | ||
352 | collectgarbage() | 353 | collectgarbage() |
353 | local _, x = debug.getlocal(1, 1) | 354 | local _, x = debug.getlocal(1, 1) |
354 | local _, y = debug.getlocal(1, 2) | 355 | local _, y = debug.getlocal(1, 2) |
diff --git a/testes/goto.lua b/testes/goto.lua index eca68516..fdfddb85 100644 --- a/testes/goto.lua +++ b/testes/goto.lua | |||
@@ -1,6 +1,8 @@ | |||
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 | print("testing goto and global declarations") | ||
5 | |||
4 | collectgarbage() | 6 | collectgarbage() |
5 | 7 | ||
6 | local function errmsg (code, m) | 8 | local function errmsg (code, m) |
@@ -280,7 +282,47 @@ end | |||
280 | 282 | ||
281 | 283 | ||
282 | foo() | 284 | foo() |
283 | -------------------------------------------------------------------------------- | 285 | -------------------------------------------------------------------------- |
284 | 286 | ||
287 | do | ||
288 | global print, load, T<const>; global assert<const> | ||
289 | global string | ||
290 | |||
291 | local function checkerr (code, err) | ||
292 | local st, msg = load(code) | ||
293 | assert(not st and string.find(msg, err)) | ||
294 | end | ||
295 | |||
296 | -- globals must be declared after a global declaration | ||
297 | checkerr("global none; X = 1", "variable 'X'") | ||
298 | |||
299 | -- global variables cannot be to-be-closed | ||
300 | checkerr("global X<close>", "cannot be") | ||
301 | |||
302 | do | ||
303 | local X = 10 | ||
304 | do global X; X = 20 end | ||
305 | assert(X == 10) -- local X | ||
306 | end | ||
307 | assert(_ENV.X == 20) -- global X | ||
308 | |||
309 | -- '_ENV' cannot be global | ||
310 | checkerr("global _ENV, a; a = 10", "variable 'a'") | ||
311 | |||
312 | -- global declarations inside functions | ||
313 | checkerr([[ | ||
314 | global none | ||
315 | local function foo () XXX = 1 end --< ERROR]], "variable 'XXX'") | ||
316 | |||
317 | if not T then -- when not in "test mode", "global" isn't reserved | ||
318 | assert(load("global = 1; return global")() == 1) | ||
319 | print " ('global' is not a reserved word)" | ||
320 | else | ||
321 | -- "global" reserved, cannot be used as a variable | ||
322 | assert(not load("global = 1; return global")) | ||
323 | end | ||
324 | |||
325 | end | ||
285 | 326 | ||
286 | print'OK' | 327 | print'OK' |
328 | |||
diff --git a/testes/math.lua b/testes/math.lua index 88a57ce7..242579b1 100644 --- a/testes/math.lua +++ b/testes/math.lua | |||
@@ -3,6 +3,14 @@ | |||
3 | 3 | ||
4 | print("testing numbers and math lib") | 4 | print("testing numbers and math lib") |
5 | 5 | ||
6 | local math = require "math" | ||
7 | local string = require "string" | ||
8 | |||
9 | global none | ||
10 | |||
11 | global print, assert, pcall, type, pairs, load | ||
12 | global tonumber, tostring, select | ||
13 | |||
6 | local minint <const> = math.mininteger | 14 | local minint <const> = math.mininteger |
7 | local maxint <const> = math.maxinteger | 15 | local maxint <const> = math.maxinteger |
8 | 16 | ||
@@ -184,7 +192,7 @@ do | |||
184 | for i = -3, 3 do -- variables avoid constant folding | 192 | for i = -3, 3 do -- variables avoid constant folding |
185 | for j = -3, 3 do | 193 | for j = -3, 3 do |
186 | -- domain errors (0^(-n)) are not portable | 194 | -- domain errors (0^(-n)) are not portable |
187 | if not _port or i ~= 0 or j > 0 then | 195 | if not _ENV._port or i ~= 0 or j > 0 then |
188 | assert(eq(i^j, 1 / i^(-j))) | 196 | assert(eq(i^j, 1 / i^(-j))) |
189 | end | 197 | end |
190 | end | 198 | end |
@@ -430,7 +438,7 @@ for i = 2,36 do | |||
430 | assert(tonumber('\t10000000000\t', i) == i10) | 438 | assert(tonumber('\t10000000000\t', i) == i10) |
431 | end | 439 | end |
432 | 440 | ||
433 | if not _soft then | 441 | if not _ENV._soft then |
434 | -- tests with very long numerals | 442 | -- tests with very long numerals |
435 | assert(tonumber("0x"..string.rep("f", 13)..".0") == 2.0^(4*13) - 1) | 443 | assert(tonumber("0x"..string.rep("f", 13)..".0") == 2.0^(4*13) - 1) |
436 | assert(tonumber("0x"..string.rep("f", 150)..".0") == 2.0^(4*150) - 1) | 444 | assert(tonumber("0x"..string.rep("f", 150)..".0") == 2.0^(4*150) - 1) |
@@ -632,7 +640,7 @@ assert(maxint % -2 == -1) | |||
632 | 640 | ||
633 | -- non-portable tests because Windows C library cannot compute | 641 | -- non-portable tests because Windows C library cannot compute |
634 | -- fmod(1, huge) correctly | 642 | -- fmod(1, huge) correctly |
635 | if not _port then | 643 | if not _ENV._port then |
636 | local function anan (x) assert(isNaN(x)) end -- assert Not a Number | 644 | local function anan (x) assert(isNaN(x)) end -- assert Not a Number |
637 | anan(0.0 % 0) | 645 | anan(0.0 % 0) |
638 | anan(1.3 % 0) | 646 | anan(1.3 % 0) |
@@ -779,6 +787,7 @@ assert(a == '10' and b == '20') | |||
779 | 787 | ||
780 | do | 788 | do |
781 | print("testing -0 and NaN") | 789 | print("testing -0 and NaN") |
790 | global rawset, undef | ||
782 | local mz <const> = -0.0 | 791 | local mz <const> = -0.0 |
783 | local z <const> = 0.0 | 792 | local z <const> = 0.0 |
784 | assert(mz == z) | 793 | assert(mz == z) |
@@ -1074,6 +1083,7 @@ do | |||
1074 | -- different numbers should print differently. | 1083 | -- different numbers should print differently. |
1075 | -- check pairs of floats with minimum detectable difference | 1084 | -- check pairs of floats with minimum detectable difference |
1076 | local p = floatbits - 1 | 1085 | local p = floatbits - 1 |
1086 | global ipairs | ||
1077 | for i = 1, maxexp - 1 do | 1087 | for i = 1, maxexp - 1 do |
1078 | for _, i in ipairs{-i, i} do | 1088 | for _, i in ipairs{-i, i} do |
1079 | local x = 2^i | 1089 | local x = 2^i |