diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-05-08 11:08:03 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-05-08 11:08:03 -0300 |
commit | 3f0ea90aa8b8493485637f6e8d2a070a1ac0d5cb (patch) | |
tree | c8f2808286713805ab138a7c4fc1ccf149d94cd7 /lparser.c | |
parent | 4365a45d681b4e71e3c39148489bb8eae538ccf7 (diff) | |
download | lua-3f0ea90aa8b8493485637f6e8d2a070a1ac0d5cb.tar.gz lua-3f0ea90aa8b8493485637f6e8d2a070a1ac0d5cb.tar.bz2 lua-3f0ea90aa8b8493485637f6e8d2a070a1ac0d5cb.zip |
New syntax 'global function'
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 49 |
1 files changed, 39 insertions, 10 deletions
@@ -477,8 +477,7 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | |||
477 | ** Find a variable with the given name 'n', handling global variables | 477 | ** Find a variable with the given name 'n', handling global variables |
478 | ** too. | 478 | ** too. |
479 | */ | 479 | */ |
480 | static void singlevar (LexState *ls, expdesc *var) { | 480 | static void buildvar (LexState *ls, TString *varname, expdesc *var) { |
481 | TString *varname = str_checkname(ls); | ||
482 | FuncState *fs = ls->fs; | 481 | FuncState *fs = ls->fs; |
483 | singlevaraux(fs, varname, var, 1); | 482 | singlevaraux(fs, varname, var, 1); |
484 | if (var->k == VGLOBAL) { /* global name? */ | 483 | if (var->k == VGLOBAL) { /* global name? */ |
@@ -501,6 +500,11 @@ static void singlevar (LexState *ls, expdesc *var) { | |||
501 | } | 500 | } |
502 | 501 | ||
503 | 502 | ||
503 | static void singlevar (LexState *ls, expdesc *var) { | ||
504 | buildvar(ls, str_checkname(ls), var); | ||
505 | } | ||
506 | |||
507 | |||
504 | /* | 508 | /* |
505 | ** Adjust the number of results from an expression list 'e' with 'nexps' | 509 | ** Adjust the number of results from an expression list 'e' with 'nexps' |
506 | ** expressions to 'nvars' values. | 510 | ** expressions to 'nvars' values. |
@@ -1727,7 +1731,7 @@ static void localfunc (LexState *ls) { | |||
1727 | 1731 | ||
1728 | 1732 | ||
1729 | static lu_byte getvarattribute (LexState *ls) { | 1733 | static lu_byte getvarattribute (LexState *ls) { |
1730 | /* ATTRIB -> ['<' Name '>'] */ | 1734 | /* attrib -> ['<' NAME '>'] */ |
1731 | if (testnext(ls, '<')) { | 1735 | if (testnext(ls, '<')) { |
1732 | TString *ts = str_checkname(ls); | 1736 | TString *ts = str_checkname(ls); |
1733 | const char *attr = getstr(ts); | 1737 | const char *attr = getstr(ts); |
@@ -1752,7 +1756,7 @@ static void checktoclose (FuncState *fs, int level) { | |||
1752 | 1756 | ||
1753 | 1757 | ||
1754 | static void localstat (LexState *ls) { | 1758 | static void localstat (LexState *ls) { |
1755 | /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */ | 1759 | /* stat -> LOCAL NAME attrib { ',' NAME attrib } ['=' explist] */ |
1756 | FuncState *fs = ls->fs; | 1760 | FuncState *fs = ls->fs; |
1757 | int toclose = -1; /* index of to-be-closed variable (if any) */ | 1761 | int toclose = -1; /* index of to-be-closed variable (if any) */ |
1758 | Vardesc *var; /* last variable */ | 1762 | Vardesc *var; /* last variable */ |
@@ -1794,8 +1798,8 @@ static void localstat (LexState *ls) { | |||
1794 | 1798 | ||
1795 | 1799 | ||
1796 | static void globalstat (LexState *ls) { | 1800 | static void globalstat (LexState *ls) { |
1801 | /* globalstat -> (GLOBAL) NAME attrib {',' NAME attrib} */ | ||
1797 | FuncState *fs = ls->fs; | 1802 | FuncState *fs = ls->fs; |
1798 | luaX_next(ls); /* skip 'global' */ | ||
1799 | do { | 1803 | do { |
1800 | TString *vname = str_checkname(ls); | 1804 | TString *vname = str_checkname(ls); |
1801 | lu_byte kind = getvarattribute(ls); | 1805 | lu_byte kind = getvarattribute(ls); |
@@ -1807,7 +1811,31 @@ static void globalstat (LexState *ls) { | |||
1807 | new_varkind(ls, vname, kind); | 1811 | new_varkind(ls, vname, kind); |
1808 | fs->nactvar++; /* activate declaration */ | 1812 | fs->nactvar++; /* activate declaration */ |
1809 | } while (testnext(ls, ',')); | 1813 | } while (testnext(ls, ',')); |
1810 | fs->bl->globdec = 1; /* code is in the scope of a global declaration */ | 1814 | } |
1815 | |||
1816 | |||
1817 | static void globalfunc (LexState *ls, int line) { | ||
1818 | /* globalfunc -> (GLOBAL FUNCTION) NAME body */ | ||
1819 | expdesc var, b; | ||
1820 | FuncState *fs = ls->fs; | ||
1821 | TString *fname = str_checkname(ls); | ||
1822 | new_varkind(ls, fname, GDKREG); /* declare global variable */ | ||
1823 | fs->nactvar++; /* enter its scope */ | ||
1824 | buildvar(ls, fname, &var); | ||
1825 | body(ls, &b, 0, ls->linenumber); /* compile and return closure in 'b' */ | ||
1826 | luaK_storevar(fs, &var, &b); | ||
1827 | luaK_fixline(fs, line); /* definition "happens" in the first line */ | ||
1828 | } | ||
1829 | |||
1830 | |||
1831 | static void globalstatfunc (LexState *ls, int line) { | ||
1832 | /* stat -> GLOBAL globalfunc | GLOBAL globalstat */ | ||
1833 | luaX_next(ls); /* skip 'global' */ | ||
1834 | ls->fs->bl->globdec = 1; /* in the scope of a global declaration */ | ||
1835 | if (testnext(ls, TK_FUNCTION)) | ||
1836 | globalfunc(ls, line); | ||
1837 | else | ||
1838 | globalstat(ls); | ||
1811 | } | 1839 | } |
1812 | 1840 | ||
1813 | 1841 | ||
@@ -1930,8 +1958,8 @@ static void statement (LexState *ls) { | |||
1930 | localstat(ls); | 1958 | localstat(ls); |
1931 | break; | 1959 | break; |
1932 | } | 1960 | } |
1933 | case TK_GLOBAL: { /* stat -> globalstat */ | 1961 | case TK_GLOBAL: { /* stat -> globalstatfunc */ |
1934 | globalstat(ls); | 1962 | globalstatfunc(ls, line); |
1935 | break; | 1963 | break; |
1936 | } | 1964 | } |
1937 | case TK_DBCOLON: { /* stat -> label */ | 1965 | case TK_DBCOLON: { /* stat -> label */ |
@@ -1958,8 +1986,9 @@ static void statement (LexState *ls) { | |||
1958 | is not reserved */ | 1986 | is not reserved */ |
1959 | if (eqstr(ls->t.seminfo.ts, luaS_newliteral(ls->L, "global"))) { | 1987 | if (eqstr(ls->t.seminfo.ts, luaS_newliteral(ls->L, "global"))) { |
1960 | int lk = luaX_lookahead(ls); | 1988 | int lk = luaX_lookahead(ls); |
1961 | if (lk == TK_NAME) { /* 'global name'? */ | 1989 | if (lk == TK_NAME || lk == TK_FUNCTION) { |
1962 | globalstat(ls); | 1990 | /* 'global <name>' or 'global function' */ |
1991 | globalstatfunc(ls, line); | ||
1963 | break; | 1992 | break; |
1964 | } | 1993 | } |
1965 | } /* else... */ | 1994 | } /* else... */ |