diff options
Diffstat (limited to '')
| -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... */ |
