aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c63
1 files changed, 36 insertions, 27 deletions
diff --git a/lparser.c b/lparser.c
index 2b888c7c..2a84637a 100644
--- a/lparser.c
+++ b/lparser.c
@@ -187,10 +187,10 @@ static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
187 187
188 188
189/* 189/*
190** Create a new local variable with the given 'name'. Return its index 190** Create a new local variable with the given 'name' and given 'kind'.
191** in the function. 191** Return its index in the function.
192*/ 192*/
193static int new_localvar (LexState *ls, TString *name) { 193static int new_localvarkind (LexState *ls, TString *name, int kind) {
194 lua_State *L = ls->L; 194 lua_State *L = ls->L;
195 FuncState *fs = ls->fs; 195 FuncState *fs = ls->fs;
196 Dyndata *dyd = ls->dyd; 196 Dyndata *dyd = ls->dyd;
@@ -200,11 +200,19 @@ static int new_localvar (LexState *ls, TString *name) {
200 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, 200 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
201 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); 201 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
202 var = &dyd->actvar.arr[dyd->actvar.n++]; 202 var = &dyd->actvar.arr[dyd->actvar.n++];
203 var->vd.kind = VDKREG; /* default */ 203 var->vd.kind = kind; /* default */
204 var->vd.name = name; 204 var->vd.name = name;
205 return dyd->actvar.n - 1 - fs->firstlocal; 205 return dyd->actvar.n - 1 - fs->firstlocal;
206} 206}
207 207
208
209/*
210** Create a new local variable with the given 'name' and regular kind.
211*/
212static int new_localvar (LexState *ls, TString *name) {
213 return new_localvarkind(ls, name, VDKREG);
214}
215
208#define new_localvarliteral(ls,v) \ 216#define new_localvarliteral(ls,v) \
209 new_localvar(ls, \ 217 new_localvar(ls, \
210 luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); 218 luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
@@ -512,7 +520,8 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
512** local variable. 520** local variable.
513*/ 521*/
514static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { 522static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
515 const char *varname = getstr(getlocalvardesc(ls->fs, gt->nactvar)->vd.name); 523 TString *tsname = getlocalvardesc(ls->fs, gt->nactvar)->vd.name;
524 const char *varname = getstr(tsname);
516 const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'"; 525 const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'";
517 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); 526 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname);
518 luaK_semerror(ls, msg); /* raise the error */ 527 luaK_semerror(ls, msg); /* raise the error */
@@ -951,7 +960,7 @@ static void constructor (LexState *ls, expdesc *t) {
951 960
952 961
953static void setvararg (FuncState *fs, int nparams) { 962static void setvararg (FuncState *fs, int nparams) {
954 fs->f->is_vararg = 1; 963 fs->f->flag |= PF_ISVARARG;
955 luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0); 964 luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0);
956} 965}
957 966
@@ -1169,7 +1178,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
1169 } 1178 }
1170 case TK_DOTS: { /* vararg */ 1179 case TK_DOTS: { /* vararg */
1171 FuncState *fs = ls->fs; 1180 FuncState *fs = ls->fs;
1172 check_condition(ls, fs->f->is_vararg, 1181 check_condition(ls, fs->f->flag & PF_ISVARARG,
1173 "cannot use '...' outside a vararg function"); 1182 "cannot use '...' outside a vararg function");
1174 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1)); 1183 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1));
1175 break; 1184 break;
@@ -1550,6 +1559,7 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isgen) {
1550 int prep, endfor; 1559 int prep, endfor;
1551 checknext(ls, TK_DO); 1560 checknext(ls, TK_DO);
1552 prep = luaK_codeABx(fs, forprep[isgen], base, 0); 1561 prep = luaK_codeABx(fs, forprep[isgen], base, 0);
1562 fs->freereg--; /* both 'forprep' remove one register from the stack */
1553 enterblock(fs, &bl, 0); /* scope for declared variables */ 1563 enterblock(fs, &bl, 0); /* scope for declared variables */
1554 adjustlocalvars(ls, nvars); 1564 adjustlocalvars(ls, nvars);
1555 luaK_reserveregs(fs, nvars); 1565 luaK_reserveregs(fs, nvars);
@@ -1572,8 +1582,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
1572 int base = fs->freereg; 1582 int base = fs->freereg;
1573 new_localvarliteral(ls, "(for state)"); 1583 new_localvarliteral(ls, "(for state)");
1574 new_localvarliteral(ls, "(for state)"); 1584 new_localvarliteral(ls, "(for state)");
1575 new_localvarliteral(ls, "(for state)"); 1585 new_localvarkind(ls, varname, RDKCONST); /* control variable */
1576 new_localvar(ls, varname);
1577 checknext(ls, '='); 1586 checknext(ls, '=');
1578 exp1(ls); /* initial value */ 1587 exp1(ls); /* initial value */
1579 checknext(ls, ','); 1588 checknext(ls, ',');
@@ -1584,7 +1593,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
1584 luaK_int(fs, fs->freereg, 1); 1593 luaK_int(fs, fs->freereg, 1);
1585 luaK_reserveregs(fs, 1); 1594 luaK_reserveregs(fs, 1);
1586 } 1595 }
1587 adjustlocalvars(ls, 3); /* control variables */ 1596 adjustlocalvars(ls, 2); /* start scope for internal variables */
1588 forbody(ls, base, line, 1, 0); 1597 forbody(ls, base, line, 1, 0);
1589} 1598}
1590 1599
@@ -1593,16 +1602,15 @@ static void forlist (LexState *ls, TString *indexname) {
1593 /* forlist -> NAME {,NAME} IN explist forbody */ 1602 /* forlist -> NAME {,NAME} IN explist forbody */
1594 FuncState *fs = ls->fs; 1603 FuncState *fs = ls->fs;
1595 expdesc e; 1604 expdesc e;
1596 int nvars = 5; /* gen, state, control, toclose, 'indexname' */ 1605 int nvars = 4; /* function, state, closing, control */
1597 int line; 1606 int line;
1598 int base = fs->freereg; 1607 int base = fs->freereg;
1599 /* create control variables */ 1608 /* create internal variables */
1600 new_localvarliteral(ls, "(for state)"); 1609 new_localvarliteral(ls, "(for state)"); /* iterator function */
1601 new_localvarliteral(ls, "(for state)"); 1610 new_localvarliteral(ls, "(for state)"); /* state */
1602 new_localvarliteral(ls, "(for state)"); 1611 new_localvarliteral(ls, "(for state)"); /* closing var. (after swap) */
1603 new_localvarliteral(ls, "(for state)"); 1612 new_localvarkind(ls, indexname, RDKCONST); /* control variable */
1604 /* create declared variables */ 1613 /* other declared variables */
1605 new_localvar(ls, indexname);
1606 while (testnext(ls, ',')) { 1614 while (testnext(ls, ',')) {
1607 new_localvar(ls, str_checkname(ls)); 1615 new_localvar(ls, str_checkname(ls));
1608 nvars++; 1616 nvars++;
@@ -1610,10 +1618,10 @@ static void forlist (LexState *ls, TString *indexname) {
1610 checknext(ls, TK_IN); 1618 checknext(ls, TK_IN);
1611 line = ls->linenumber; 1619 line = ls->linenumber;
1612 adjust_assign(ls, 4, explist(ls, &e), &e); 1620 adjust_assign(ls, 4, explist(ls, &e), &e);
1613 adjustlocalvars(ls, 4); /* control variables */ 1621 adjustlocalvars(ls, 3); /* start scope for internal variables */
1614 marktobeclosed(fs); /* last control var. must be closed */ 1622 marktobeclosed(fs); /* last internal var. must be closed */
1615 luaK_checkstack(fs, 3); /* extra space to call generator */ 1623 luaK_checkstack(fs, 2); /* extra space to call iterator */
1616 forbody(ls, base, line, nvars - 4, 1); 1624 forbody(ls, base, line, nvars - 3, 1);
1617} 1625}
1618 1626
1619 1627
@@ -1701,7 +1709,8 @@ static void localfunc (LexState *ls) {
1701static int getlocalattribute (LexState *ls) { 1709static int getlocalattribute (LexState *ls) {
1702 /* ATTRIB -> ['<' Name '>'] */ 1710 /* ATTRIB -> ['<' Name '>'] */
1703 if (testnext(ls, '<')) { 1711 if (testnext(ls, '<')) {
1704 const char *attr = getstr(str_checkname(ls)); 1712 TString *ts = str_checkname(ls);
1713 const char *attr = getstr(ts);
1705 checknext(ls, '>'); 1714 checknext(ls, '>');
1706 if (strcmp(attr, "const") == 0) 1715 if (strcmp(attr, "const") == 0)
1707 return RDKCONST; /* read-only variable */ 1716 return RDKCONST; /* read-only variable */
@@ -1728,14 +1737,14 @@ static void localstat (LexState *ls) {
1728 FuncState *fs = ls->fs; 1737 FuncState *fs = ls->fs;
1729 int toclose = -1; /* index of to-be-closed variable (if any) */ 1738 int toclose = -1; /* index of to-be-closed variable (if any) */
1730 Vardesc *var; /* last variable */ 1739 Vardesc *var; /* last variable */
1731 int vidx, kind; /* index and kind of last variable */ 1740 int vidx; /* index of last variable */
1732 int nvars = 0; 1741 int nvars = 0;
1733 int nexps; 1742 int nexps;
1734 expdesc e; 1743 expdesc e;
1735 do { 1744 do {
1736 vidx = new_localvar(ls, str_checkname(ls)); 1745 TString *vname = str_checkname(ls);
1737 kind = getlocalattribute(ls); 1746 int kind = getlocalattribute(ls);
1738 getlocalvardesc(fs, vidx)->vd.kind = kind; 1747 vidx = new_localvarkind(ls, vname, kind);
1739 if (kind == RDKTOCLOSE) { /* to-be-closed? */ 1748 if (kind == RDKTOCLOSE) { /* to-be-closed? */
1740 if (toclose != -1) /* one already present? */ 1749 if (toclose != -1) /* one already present? */
1741 luaK_semerror(ls, "multiple to-be-closed variables in local list"); 1750 luaK_semerror(ls, "multiple to-be-closed variables in local list");