aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/lparser.c b/lparser.c
index 27daa926..37102b72 100644
--- a/lparser.c
+++ b/lparser.c
@@ -212,27 +212,28 @@ static int new_localvar (LexState *ls, TString *name) {
212 212
213 213
214/* 214/*
215** Return the "variable description" (Vardesc) of a given 215** Return the "variable description" (Vardesc) of a given variable.
216** variable 216** (Unless noted otherwise, all variables are referred to by their
217** compiler indices.)
217*/ 218*/
218static Vardesc *getlocalvardesc (FuncState *fs, int i) { 219static Vardesc *getlocalvardesc (FuncState *fs, int vidx) {
219 return &fs->ls->dyd->actvar.arr[fs->firstlocal + i]; 220 return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx];
220} 221}
221 222
222 223
223/* 224/*
224** Convert 'nvar' (number of active variables at some point) to 225** Convert 'nvar', a compiler index level, to it corresponding
225** number of variables in the stack at that point. 226** stack index level. For that, search for the highest variable
227** below that level that is in the stack and uses its stack
228** index ('sidx').
226*/ 229*/
227static int stacklevel (FuncState *fs, int nvar) { 230static int stacklevel (FuncState *fs, int nvar) {
228 while (nvar > 0) { 231 while (nvar-- > 0) {
229 Vardesc *vd = getlocalvardesc(fs, nvar - 1); 232 Vardesc *vd = getlocalvardesc(fs, nvar); /* get variable */
230 if (vd->vd.kind != RDKCTC) /* is in the stack? */ 233 if (vd->vd.kind != RDKCTC) /* is in the stack? */
231 return vd->vd.sidx + 1; 234 return vd->vd.sidx + 1;
232 else
233 nvar--; /* try previous variable */
234 } 235 }
235 return 0; /* no variables */ 236 return 0; /* no variables in the stack */
236} 237}
237 238
238 239
@@ -245,10 +246,10 @@ int luaY_nvarstack (FuncState *fs) {
245 246
246 247
247/* 248/*
248** Get the debug-information entry for current variable 'i'. 249** Get the debug-information entry for current variable 'vidx'.
249*/ 250*/
250static LocVar *localdebuginfo (FuncState *fs, int i) { 251static LocVar *localdebuginfo (FuncState *fs, int vidx) {
251 Vardesc *vd = getlocalvardesc(fs, i); 252 Vardesc *vd = getlocalvardesc(fs, vidx);
252 if (vd->vd.kind == RDKCTC) 253 if (vd->vd.kind == RDKCTC)
253 return NULL; /* no debug info. for constants */ 254 return NULL; /* no debug info. for constants */
254 else { 255 else {
@@ -259,14 +260,20 @@ static LocVar *localdebuginfo (FuncState *fs, int i) {
259} 260}
260 261
261 262
262static void init_var (FuncState *fs, expdesc *e, int i) { 263/*
264** Create an expression representing variable 'vidx'
265*/
266static void init_var (FuncState *fs, expdesc *e, int vidx) {
263 e->f = e->t = NO_JUMP; 267 e->f = e->t = NO_JUMP;
264 e->k = VLOCAL; 268 e->k = VLOCAL;
265 e->u.var.vidx = i; 269 e->u.var.vidx = vidx;
266 e->u.var.sidx = getlocalvardesc(fs, i)->vd.sidx; 270 e->u.var.sidx = getlocalvardesc(fs, vidx)->vd.sidx;
267} 271}
268 272
269 273
274/*
275** Raises an error if variable described by 'e' is read only
276*/
270static void check_readonly (LexState *ls, expdesc *e) { 277static void check_readonly (LexState *ls, expdesc *e) {
271 FuncState *fs = ls->fs; 278 FuncState *fs = ls->fs;
272 TString *varname = NULL; /* to be set if variable is const */ 279 TString *varname = NULL; /* to be set if variable is const */
@@ -306,8 +313,8 @@ static void adjustlocalvars (LexState *ls, int nvars) {
306 int stklevel = luaY_nvarstack(fs); 313 int stklevel = luaY_nvarstack(fs);
307 int i; 314 int i;
308 for (i = 0; i < nvars; i++) { 315 for (i = 0; i < nvars; i++) {
309 int varidx = fs->nactvar++; 316 int vidx = fs->nactvar++;
310 Vardesc *var = getlocalvardesc(fs, varidx); 317 Vardesc *var = getlocalvardesc(fs, vidx);
311 var->vd.sidx = stklevel++; 318 var->vd.sidx = stklevel++;
312 var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); 319 var->vd.pidx = registerlocalvar(ls, fs, var->vd.name);
313 } 320 }
@@ -377,7 +384,8 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
377 384
378/* 385/*
379** Look for an active local variable with the name 'n' in the 386** Look for an active local variable with the name 'n' in the
380** function 'fs'. 387** function 'fs'. If found, initialize 'var' with it and return
388** its expression kind; otherwise return -1.
381*/ 389*/
382static int searchvar (FuncState *fs, TString *n, expdesc *var) { 390static int searchvar (FuncState *fs, TString *n, expdesc *var) {
383 int i; 391 int i;
@@ -1592,7 +1600,7 @@ static void forlist (LexState *ls, TString *indexname) {
1592 line = ls->linenumber; 1600 line = ls->linenumber;
1593 adjust_assign(ls, 4, explist(ls, &e), &e); 1601 adjust_assign(ls, 4, explist(ls, &e), &e);
1594 adjustlocalvars(ls, 4); /* control variables */ 1602 adjustlocalvars(ls, 4); /* control variables */
1595 markupval(fs, luaY_nvarstack(fs)); /* state may create an upvalue */ 1603 markupval(fs, fs->nactvar); /* last control var. must be closed */
1596 luaK_checkstack(fs, 3); /* extra space to call generator */ 1604 luaK_checkstack(fs, 3); /* extra space to call generator */
1597 forbody(ls, base, line, nvars - 4, 1); 1605 forbody(ls, base, line, nvars - 4, 1);
1598} 1606}
@@ -1730,7 +1738,7 @@ static int getlocalattribute (LexState *ls) {
1730 luaK_semerror(ls, 1738 luaK_semerror(ls,
1731 luaO_pushfstring(ls->L, "unknown attribute '%s'", attr)); 1739 luaO_pushfstring(ls->L, "unknown attribute '%s'", attr));
1732 } 1740 }
1733 return VDKREG; 1741 return VDKREG; /* regular variable */
1734} 1742}
1735 1743
1736 1744
@@ -1739,7 +1747,7 @@ static void checktoclose (LexState *ls, int level) {
1739 FuncState *fs = ls->fs; 1747 FuncState *fs = ls->fs;
1740 markupval(fs, level + 1); 1748 markupval(fs, level + 1);
1741 fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ 1749 fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */
1742 luaK_codeABC(fs, OP_TBC, level, 0, 0); 1750 luaK_codeABC(fs, OP_TBC, stacklevel(fs, level), 0, 0);
1743 } 1751 }
1744} 1752}
1745 1753
@@ -1749,18 +1757,18 @@ static void localstat (LexState *ls) {
1749 FuncState *fs = ls->fs; 1757 FuncState *fs = ls->fs;
1750 int toclose = -1; /* index of to-be-closed variable (if any) */ 1758 int toclose = -1; /* index of to-be-closed variable (if any) */
1751 Vardesc *var; /* last variable */ 1759 Vardesc *var; /* last variable */
1752 int ivar, kind; /* index and kind of last variable */ 1760 int vidx, kind; /* index and kind of last variable */
1753 int nvars = 0; 1761 int nvars = 0;
1754 int nexps; 1762 int nexps;
1755 expdesc e; 1763 expdesc e;
1756 do { 1764 do {
1757 ivar = new_localvar(ls, str_checkname(ls)); 1765 vidx = new_localvar(ls, str_checkname(ls));
1758 kind = getlocalattribute(ls); 1766 kind = getlocalattribute(ls);
1759 getlocalvardesc(fs, ivar)->vd.kind = kind; 1767 getlocalvardesc(fs, vidx)->vd.kind = kind;
1760 if (kind == RDKTOCLOSE) { /* to-be-closed? */ 1768 if (kind == RDKTOCLOSE) { /* to-be-closed? */
1761 if (toclose != -1) /* one already present? */ 1769 if (toclose != -1) /* one already present? */
1762 luaK_semerror(ls, "multiple to-be-closed variables in local list"); 1770 luaK_semerror(ls, "multiple to-be-closed variables in local list");
1763 toclose = luaY_nvarstack(fs) + nvars; 1771 toclose = fs->nactvar + nvars;
1764 } 1772 }
1765 nvars++; 1773 nvars++;
1766 } while (testnext(ls, ',')); 1774 } while (testnext(ls, ','));
@@ -1770,7 +1778,7 @@ static void localstat (LexState *ls) {
1770 e.k = VVOID; 1778 e.k = VVOID;
1771 nexps = 0; 1779 nexps = 0;
1772 } 1780 }
1773 var = getlocalvardesc(fs, ivar); /* get last variable */ 1781 var = getlocalvardesc(fs, vidx); /* get last variable */
1774 if (nvars == nexps && /* no adjustments? */ 1782 if (nvars == nexps && /* no adjustments? */
1775 var->vd.kind == RDKCONST && /* last variable is const? */ 1783 var->vd.kind == RDKCONST && /* last variable is const? */
1776 luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ 1784 luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */