aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-05-18 11:43:43 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-05-18 11:43:43 -0300
commitabbae57c7844b1121e7251d56f681394f20c1821 (patch)
tree823201f4d2631fcae027117681553de80b2c96f0 /lparser.c
parentf2c1531e6cacb10926158d8def5fa5841a0f357e (diff)
downloadlua-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.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/lparser.c b/lparser.c
index 384ef690..bad3592a 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1733,7 +1733,7 @@ static void localfunc (LexState *ls) {
1733} 1733}
1734 1734
1735 1735
1736static lu_byte getvarattribute (LexState *ls) { 1736static 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
1803static lu_byte getglobalattribute (LexState *ls) { 1805static 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
1812static void globalstat (LexState *ls) { 1819static 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 }