diff options
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 63 |
1 files changed, 36 insertions, 27 deletions
@@ -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 | */ |
193 | static int new_localvar (LexState *ls, TString *name) { | 193 | static 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 | */ | ||
212 | static 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 | */ |
514 | static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { | 522 | static 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 | ||
953 | static void setvararg (FuncState *fs, int nparams) { | 962 | static 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) { | |||
1701 | static int getlocalattribute (LexState *ls) { | 1709 | static 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"); |