diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-05-18 11:43:43 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-05-18 11:43:43 -0300 |
| commit | abbae57c7844b1121e7251d56f681394f20c1821 (patch) | |
| tree | 823201f4d2631fcae027117681553de80b2c96f0 /lparser.c | |
| parent | f2c1531e6cacb10926158d8def5fa5841a0f357e (diff) | |
| download | lua-abbae57c7844b1121e7251d56f681394f20c1821.tar.gz lua-abbae57c7844b1121e7251d56f681394f20c1821.tar.bz2 lua-abbae57c7844b1121e7251d56f681394f20c1821.zip | |
Variable attributes can prefix name list
In this format, the attribute applies to all names in the list;
e.g. "global<const> print, require, math".
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 53 |
1 files changed, 31 insertions, 22 deletions
| @@ -1733,7 +1733,7 @@ static void localfunc (LexState *ls) { | |||
| 1733 | } | 1733 | } |
| 1734 | 1734 | ||
| 1735 | 1735 | ||
| 1736 | static lu_byte getvarattribute (LexState *ls) { | 1736 | static lu_byte getvarattribute (LexState *ls, lu_byte df) { |
| 1737 | /* attrib -> ['<' NAME '>'] */ | 1737 | /* attrib -> ['<' NAME '>'] */ |
| 1738 | if (testnext(ls, '<')) { | 1738 | if (testnext(ls, '<')) { |
| 1739 | TString *ts = str_checkname(ls); | 1739 | TString *ts = str_checkname(ls); |
| @@ -1746,7 +1746,7 @@ static lu_byte getvarattribute (LexState *ls) { | |||
| 1746 | else | 1746 | else |
| 1747 | luaK_semerror(ls, "unknown attribute '%s'", attr); | 1747 | luaK_semerror(ls, "unknown attribute '%s'", attr); |
| 1748 | } | 1748 | } |
| 1749 | return VDKREG; /* regular variable */ | 1749 | return df; /* return default value */ |
| 1750 | } | 1750 | } |
| 1751 | 1751 | ||
| 1752 | 1752 | ||
| @@ -1767,10 +1767,12 @@ static void localstat (LexState *ls) { | |||
| 1767 | int nvars = 0; | 1767 | int nvars = 0; |
| 1768 | int nexps; | 1768 | int nexps; |
| 1769 | expdesc e; | 1769 | expdesc e; |
| 1770 | do { | 1770 | /* get prefixed attribute (if any); default is regular local variable */ |
| 1771 | TString *vname = str_checkname(ls); | 1771 | lu_byte defkind = getvarattribute(ls, VDKREG); |
| 1772 | lu_byte kind = getvarattribute(ls); | 1772 | do { /* for each variable */ |
| 1773 | vidx = new_varkind(ls, vname, kind); | 1773 | TString *vname = str_checkname(ls); /* get its name */ |
| 1774 | lu_byte kind = getvarattribute(ls, defkind); /* postfixed attribute */ | ||
| 1775 | vidx = new_varkind(ls, vname, kind); /* predeclare it */ | ||
| 1774 | if (kind == RDKTOCLOSE) { /* to-be-closed? */ | 1776 | if (kind == RDKTOCLOSE) { /* to-be-closed? */ |
| 1775 | if (toclose != -1) /* one already present? */ | 1777 | if (toclose != -1) /* one already present? */ |
| 1776 | luaK_semerror(ls, "multiple to-be-closed variables in local list"); | 1778 | luaK_semerror(ls, "multiple to-be-closed variables in local list"); |
| @@ -1778,13 +1780,13 @@ static void localstat (LexState *ls) { | |||
| 1778 | } | 1780 | } |
| 1779 | nvars++; | 1781 | nvars++; |
| 1780 | } while (testnext(ls, ',')); | 1782 | } while (testnext(ls, ',')); |
| 1781 | if (testnext(ls, '=')) | 1783 | if (testnext(ls, '=')) /* initialization? */ |
| 1782 | nexps = explist(ls, &e); | 1784 | nexps = explist(ls, &e); |
| 1783 | else { | 1785 | else { |
| 1784 | e.k = VVOID; | 1786 | e.k = VVOID; |
| 1785 | nexps = 0; | 1787 | nexps = 0; |
| 1786 | } | 1788 | } |
| 1787 | var = getlocalvardesc(fs, vidx); /* get last variable */ | 1789 | var = getlocalvardesc(fs, vidx); /* retrieve last variable */ |
| 1788 | if (nvars == nexps && /* no adjustments? */ | 1790 | if (nvars == nexps && /* no adjustments? */ |
| 1789 | var->vd.kind == RDKCONST && /* last variable is const? */ | 1791 | var->vd.kind == RDKCONST && /* last variable is const? */ |
| 1790 | luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ | 1792 | luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ |
| @@ -1800,29 +1802,35 @@ static void localstat (LexState *ls) { | |||
| 1800 | } | 1802 | } |
| 1801 | 1803 | ||
| 1802 | 1804 | ||
| 1803 | static lu_byte getglobalattribute (LexState *ls) { | 1805 | static lu_byte getglobalattribute (LexState *ls, lu_byte df) { |
| 1804 | lu_byte kind = getvarattribute(ls); | 1806 | lu_byte kind = getvarattribute(ls, df); |
| 1805 | if (kind == RDKTOCLOSE) | 1807 | switch (kind) { |
| 1806 | luaK_semerror(ls, "global variables cannot be to-be-closed"); | 1808 | case RDKTOCLOSE: |
| 1807 | /* adjust kind for global variable */ | 1809 | luaK_semerror(ls, "global variables cannot be to-be-closed"); |
| 1808 | return (kind == VDKREG) ? GDKREG : GDKCONST; | 1810 | break; /* to avoid warnings */ |
| 1811 | case RDKCONST: | ||
| 1812 | return GDKCONST; /* adjust kind for global variable */ | ||
| 1813 | default: | ||
| 1814 | return kind; | ||
| 1815 | } | ||
| 1809 | } | 1816 | } |
| 1810 | 1817 | ||
| 1811 | 1818 | ||
| 1812 | static void globalstat (LexState *ls) { | 1819 | static void globalstat (LexState *ls) { |
| 1813 | /* globalstat -> (GLOBAL) '*' attrib | 1820 | /* globalstat -> (GLOBAL) attrib '*' |
| 1814 | globalstat -> (GLOBAL) NAME attrib {',' NAME attrib} */ | 1821 | globalstat -> (GLOBAL) attrib NAME attrib {',' NAME attrib} */ |
| 1815 | FuncState *fs = ls->fs; | 1822 | FuncState *fs = ls->fs; |
| 1823 | /* get prefixed attribute (if any); default is regular global variable */ | ||
| 1824 | lu_byte defkind = getglobalattribute(ls, GDKREG); | ||
| 1816 | if (testnext(ls, '*')) { | 1825 | if (testnext(ls, '*')) { |
| 1817 | lu_byte kind = getglobalattribute(ls); | ||
| 1818 | /* use NULL as name to represent '*' entries */ | 1826 | /* use NULL as name to represent '*' entries */ |
| 1819 | new_varkind(ls, NULL, kind); | 1827 | new_varkind(ls, NULL, defkind); |
| 1820 | fs->nactvar++; /* activate declaration */ | 1828 | fs->nactvar++; /* activate declaration */ |
| 1821 | } | 1829 | } |
| 1822 | else { | 1830 | else { |
| 1823 | do { | 1831 | do { /* list of names */ |
| 1824 | TString *vname = str_checkname(ls); | 1832 | TString *vname = str_checkname(ls); |
| 1825 | lu_byte kind = getglobalattribute(ls); | 1833 | lu_byte kind = getglobalattribute(ls, defkind); |
| 1826 | new_varkind(ls, vname, kind); | 1834 | new_varkind(ls, vname, kind); |
| 1827 | fs->nactvar++; /* activate declaration */ | 1835 | fs->nactvar++; /* activate declaration */ |
| 1828 | } while (testnext(ls, ',')); | 1836 | } while (testnext(ls, ',')); |
| @@ -2003,8 +2011,9 @@ static void statement (LexState *ls) { | |||
| 2003 | is not reserved */ | 2011 | is not reserved */ |
| 2004 | if (ls->t.seminfo.ts == ls->glbn) { /* current = "global"? */ | 2012 | if (ls->t.seminfo.ts == ls->glbn) { /* current = "global"? */ |
| 2005 | int lk = luaX_lookahead(ls); | 2013 | int lk = luaX_lookahead(ls); |
| 2006 | if (lk == TK_NAME || lk == '*' || lk == TK_FUNCTION) { | 2014 | if (lk == '<' || lk == TK_NAME || lk == '*' || lk == TK_FUNCTION) { |
| 2007 | /* 'global name' or 'global *' or 'global function' */ | 2015 | /* 'global <attrib>' or 'global name' or 'global *' or |
| 2016 | 'global function' */ | ||
| 2008 | globalstatfunc(ls, line); | 2017 | globalstatfunc(ls, line); |
| 2009 | break; | 2018 | break; |
| 2010 | } | 2019 | } |
