aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-05-08 11:08:03 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-05-08 11:08:03 -0300
commit3f0ea90aa8b8493485637f6e8d2a070a1ac0d5cb (patch)
treec8f2808286713805ab138a7c4fc1ccf149d94cd7 /lparser.c
parent4365a45d681b4e71e3c39148489bb8eae538ccf7 (diff)
downloadlua-3f0ea90aa8b8493485637f6e8d2a070a1ac0d5cb.tar.gz
lua-3f0ea90aa8b8493485637f6e8d2a070a1ac0d5cb.tar.bz2
lua-3f0ea90aa8b8493485637f6e8d2a070a1ac0d5cb.zip
New syntax 'global function'
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/lparser.c b/lparser.c
index 61ce0908..a11f1dd3 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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*/
480static void singlevar (LexState *ls, expdesc *var) { 480static 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
503static 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
1729static lu_byte getvarattribute (LexState *ls) { 1733static 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
1754static void localstat (LexState *ls) { 1758static 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
1796static void globalstat (LexState *ls) { 1800static 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
1817static 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
1831static 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... */