diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-02-07 15:14:50 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-02-07 15:14:50 -0200 |
commit | f0797492875dec5bf7a23b9172809bc92c0c04cd (patch) | |
tree | 712c44cd08fc8ee3a12c11029dc50f1988f8628f /lparser.c | |
parent | f8d677f94c3b4309be94698d33aeb0590a51eabc (diff) | |
download | lua-f0797492875dec5bf7a23b9172809bc92c0c04cd.tar.gz lua-f0797492875dec5bf7a23b9172809bc92c0c04cd.tar.bz2 lua-f0797492875dec5bf7a23b9172809bc92c0c04cd.zip |
some reorganization of dynamic data structures used by the parser
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 129 |
1 files changed, 65 insertions, 64 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.97 2011/02/04 17:34:43 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.98 2011/02/07 12:28:27 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -42,8 +42,8 @@ | |||
42 | typedef struct BlockCnt { | 42 | typedef struct BlockCnt { |
43 | struct BlockCnt *previous; /* chain */ | 43 | struct BlockCnt *previous; /* chain */ |
44 | int breaklist; /* list of jumps out of this loop */ | 44 | int breaklist; /* list of jumps out of this loop */ |
45 | int firstlabel; /* index (in Labellist) of first label in this block */ | 45 | int firstlabel; /* index of first label in this block */ |
46 | int firstgoto; /* index (in Gotolist) of first pending goto in this block */ | 46 | int firstgoto; /* index of first pending goto in this block */ |
47 | lu_byte nactvar; /* # active locals outside the block */ | 47 | lu_byte nactvar; /* # active locals outside the block */ |
48 | lu_byte upval; /* true if some variable in the block is an upvalue */ | 48 | lu_byte upval; /* true if some variable in the block is an upvalue */ |
49 | lu_byte isbreakable; /* true if `block' is a loop */ | 49 | lu_byte isbreakable; /* true if `block' is a loop */ |
@@ -169,13 +169,13 @@ static int registerlocalvar (LexState *ls, TString *varname) { | |||
169 | 169 | ||
170 | static void new_localvar (LexState *ls, TString *name) { | 170 | static void new_localvar (LexState *ls, TString *name) { |
171 | FuncState *fs = ls->fs; | 171 | FuncState *fs = ls->fs; |
172 | Varlist *vl = ls->varl; | 172 | Dyndata *dyd = ls->dyd; |
173 | int reg = registerlocalvar(ls, name); | 173 | int reg = registerlocalvar(ls, name); |
174 | checklimit(fs, vl->nactvar + 1 - fs->firstlocal, | 174 | checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, |
175 | MAXVARS, "local variables"); | 175 | MAXVARS, "local variables"); |
176 | luaM_growvector(ls->L, vl->actvar, vl->nactvar + 1, | 176 | luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, |
177 | vl->actvarsize, Vardesc, MAX_INT, "local variables"); | 177 | dyd->actvar.size, Vardesc, MAX_INT, "local variables"); |
178 | vl->actvar[vl->nactvar++].idx = cast(unsigned short, reg); | 178 | dyd->actvar.arr[dyd->actvar.n++].idx = cast(unsigned short, reg); |
179 | } | 179 | } |
180 | 180 | ||
181 | 181 | ||
@@ -188,7 +188,7 @@ static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { | |||
188 | 188 | ||
189 | 189 | ||
190 | static LocVar *getlocvar (FuncState *fs, int i) { | 190 | static LocVar *getlocvar (FuncState *fs, int i) { |
191 | int idx = fs->ls->varl->actvar[fs->firstlocal + i].idx; | 191 | int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; |
192 | lua_assert(idx < fs->nlocvars); | 192 | lua_assert(idx < fs->nlocvars); |
193 | return &fs->f->locvars[idx]; | 193 | return &fs->f->locvars[idx]; |
194 | } | 194 | } |
@@ -204,7 +204,7 @@ static void adjustlocalvars (LexState *ls, int nvars) { | |||
204 | 204 | ||
205 | 205 | ||
206 | static void removevars (FuncState *fs, int tolevel) { | 206 | static void removevars (FuncState *fs, int tolevel) { |
207 | fs->ls->varl->nactvar -= (fs->nactvar - tolevel); | 207 | fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); |
208 | while (fs->nactvar > tolevel) | 208 | while (fs->nactvar > tolevel) |
209 | getlocvar(fs, --fs->nactvar)->endpc = fs->pc; | 209 | getlocvar(fs, --fs->nactvar)->endpc = fs->pc; |
210 | } | 210 | } |
@@ -332,19 +332,20 @@ static void enterlevel (LexState *ls) { | |||
332 | static void closegoto (LexState *ls, int g, Labeldesc *label) { | 332 | static void closegoto (LexState *ls, int g, Labeldesc *label) { |
333 | int i; | 333 | int i; |
334 | FuncState *fs = ls->fs; | 334 | FuncState *fs = ls->fs; |
335 | Gotodesc *gt = &ls->gtl->gt[g]; | 335 | Dyndata *dyd = ls->dyd; |
336 | Labeldesc *gt = &dyd->gt.arr[g]; | ||
336 | lua_assert(gt->name == label->name); | 337 | lua_assert(gt->name == label->name); |
337 | if (gt->currlevel < label->nactvar) { | 338 | if (gt->nactvar < label->nactvar) { |
338 | const char *msg = luaO_pushfstring(ls->L, | 339 | const char *msg = luaO_pushfstring(ls->L, |
339 | "<goto> at line %d attemps to jump into the scope of local " LUA_QS, | 340 | "<goto> at line %d attemps to jump into the scope of local " LUA_QS, |
340 | gt->line, getstr(getlocvar(fs, gt->currlevel)->varname));; | 341 | gt->line, getstr(getlocvar(fs, gt->nactvar)->varname));; |
341 | luaX_syntaxerror(ls, msg); | 342 | luaX_syntaxerror(ls, msg); |
342 | } | 343 | } |
343 | luaK_patchlist(fs, gt->pc, label->pc); | 344 | luaK_patchlist(fs, gt->pc, label->pc); |
344 | /* remove goto from pending list */ | 345 | /* remove goto from pending list */ |
345 | for (i = g; i < ls->gtl->ngt - 1; i++) | 346 | for (i = g; i < dyd->gt.n - 1; i++) |
346 | ls->gtl->gt[i] = ls->gtl->gt[i + 1]; | 347 | dyd->gt.arr[i] = dyd->gt.arr[i + 1]; |
347 | ls->gtl->ngt--; | 348 | dyd->gt.n--; |
348 | } | 349 | } |
349 | 350 | ||
350 | 351 | ||
@@ -354,15 +355,15 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) { | |||
354 | static int findlabel (LexState *ls, int g) { | 355 | static int findlabel (LexState *ls, int g) { |
355 | int i; | 356 | int i; |
356 | BlockCnt *bl = ls->fs->bl; | 357 | BlockCnt *bl = ls->fs->bl; |
357 | Labellist *labell = ls->labell; | 358 | Dyndata *dyd = ls->dyd; |
358 | Gotodesc *gt = &ls->gtl->gt[g]; | 359 | Labeldesc *gt = &dyd->gt.arr[g]; |
359 | /* check labels in current block for a match */ | 360 | /* check labels in current block for a match */ |
360 | for (i = bl->firstlabel; i < labell->nlabel; i++) { | 361 | for (i = bl->firstlabel; i < dyd->label.n; i++) { |
361 | Labeldesc *lb = &labell->label[i]; | 362 | Labeldesc *lb = &dyd->label.arr[i]; |
362 | if (lb->name == gt->name) { | 363 | if (lb->name == gt->name) { |
363 | lua_assert(labell->label[i].pc <= gt->pc); | 364 | lua_assert(lb->pc <= gt->pc); |
364 | if (gt->currlevel > lb->nactvar && | 365 | if (gt->nactvar > lb->nactvar && |
365 | (bl->upval || ls->labell->nlabel > bl->firstlabel)) | 366 | (bl->upval || dyd->label.n > bl->firstlabel)) |
366 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); | 367 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); |
367 | closegoto(ls, g, lb); /* close it */ | 368 | closegoto(ls, g, lb); /* close it */ |
368 | return 1; | 369 | return 1; |
@@ -378,9 +379,9 @@ static int findlabel (LexState *ls, int g) { | |||
378 | */ | 379 | */ |
379 | static void findgotos (LexState *ls, Labeldesc *lb) { | 380 | static void findgotos (LexState *ls, Labeldesc *lb) { |
380 | int i; | 381 | int i; |
381 | Gotolist *gtl = ls->gtl; | 382 | Dyndata *dyd = ls->dyd; |
382 | for (i = ls->fs->bl->firstgoto; i < gtl->ngt; i++) { | 383 | for (i = ls->fs->bl->firstgoto; i < dyd->gt.n; i++) { |
383 | if (gtl->gt[i].name == lb->name) | 384 | if (dyd->gt.arr[i].name == lb->name) |
384 | closegoto(ls, i, lb); | 385 | closegoto(ls, i, lb); |
385 | } | 386 | } |
386 | } | 387 | } |
@@ -394,17 +395,17 @@ static void findgotos (LexState *ls, Labeldesc *lb) { | |||
394 | */ | 395 | */ |
395 | static void movegotosout (FuncState *fs, BlockCnt *bl) { | 396 | static void movegotosout (FuncState *fs, BlockCnt *bl) { |
396 | int i = bl->firstgoto; | 397 | int i = bl->firstgoto; |
397 | LexState *ls = fs->ls; | 398 | Dyndata *dyd = fs->ls->dyd; |
398 | /* correct pending gotos to current block and try to close it | 399 | /* correct pending gotos to current block and try to close it |
399 | with visible labels */ | 400 | with visible labels */ |
400 | while (i < ls->gtl->ngt) { | 401 | while (i < dyd->gt.n) { |
401 | Gotodesc *gt = &ls->gtl->gt[i]; | 402 | Labeldesc *gt = &dyd->gt.arr[i]; |
402 | if (gt->currlevel > bl->nactvar) { | 403 | if (gt->nactvar > bl->nactvar) { |
403 | if (bl->upval) | 404 | if (bl->upval) |
404 | luaK_patchclose(fs, gt->pc, bl->nactvar); | 405 | luaK_patchclose(fs, gt->pc, bl->nactvar); |
405 | gt->currlevel = bl->nactvar; | 406 | gt->nactvar = bl->nactvar; |
406 | } | 407 | } |
407 | if (!findlabel(ls, i)) | 408 | if (!findlabel(fs->ls, i)) |
408 | i++; /* move to next one */ | 409 | i++; /* move to next one */ |
409 | } | 410 | } |
410 | } | 411 | } |
@@ -414,8 +415,8 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { | |||
414 | bl->breaklist = NO_JUMP; | 415 | bl->breaklist = NO_JUMP; |
415 | bl->isbreakable = isbreakable; | 416 | bl->isbreakable = isbreakable; |
416 | bl->nactvar = fs->nactvar; | 417 | bl->nactvar = fs->nactvar; |
417 | bl->firstlabel = fs->ls->labell->nlabel; | 418 | bl->firstlabel = fs->ls->dyd->label.n; |
418 | bl->firstgoto = fs->ls->gtl->ngt; | 419 | bl->firstgoto = fs->ls->dyd->gt.n; |
419 | bl->upval = 0; | 420 | bl->upval = 0; |
420 | bl->previous = fs->bl; | 421 | bl->previous = fs->bl; |
421 | fs->bl = bl; | 422 | fs->bl = bl; |
@@ -427,7 +428,7 @@ static void leaveblock (FuncState *fs) { | |||
427 | BlockCnt *bl = fs->bl; | 428 | BlockCnt *bl = fs->bl; |
428 | fs->bl = bl->previous; | 429 | fs->bl = bl->previous; |
429 | removevars(fs, bl->nactvar); | 430 | removevars(fs, bl->nactvar); |
430 | fs->ls->labell->nlabel = bl->firstlabel; /* remove local labels */ | 431 | fs->ls->dyd->label.n = bl->firstlabel; /* remove local labels */ |
431 | movegotosout(fs, bl); | 432 | movegotosout(fs, bl); |
432 | if (bl->upval) { | 433 | if (bl->upval) { |
433 | /* create a 'jump to here' to close upvalues */ | 434 | /* create a 'jump to here' to close upvalues */ |
@@ -479,7 +480,7 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
479 | fs->nups = 0; | 480 | fs->nups = 0; |
480 | fs->nlocvars = 0; | 481 | fs->nlocvars = 0; |
481 | fs->nactvar = 0; | 482 | fs->nactvar = 0; |
482 | fs->firstlocal = ls->varl->nactvar; | 483 | fs->firstlocal = ls->dyd->actvar.n; |
483 | fs->bl = NULL; | 484 | fs->bl = NULL; |
484 | f = luaF_newproto(L); | 485 | f = luaF_newproto(L); |
485 | fs->f = f; | 486 | fs->f = f; |
@@ -540,8 +541,8 @@ static void mainblock (LexState *ls, FuncState *fs) { | |||
540 | BlockCnt bl; | 541 | BlockCnt bl; |
541 | enterblock(fs, &bl, 0); | 542 | enterblock(fs, &bl, 0); |
542 | statlist(ls); /* read main block */ | 543 | statlist(ls); /* read main block */ |
543 | if (bl.firstgoto < ls->gtl->ngt) { /* check pending gotos */ | 544 | if (bl.firstgoto < ls->dyd->gt.n) { /* check pending gotos */ |
544 | Gotodesc *gt = &ls->gtl->gt[bl.firstgoto]; | 545 | Labeldesc *gt = &ls->dyd->gt.arr[bl.firstgoto]; |
545 | const char *msg = luaO_pushfstring(ls->L, | 546 | const char *msg = luaO_pushfstring(ls->L, |
546 | "label " LUA_QS " (<goto> at line %d) undefined", | 547 | "label " LUA_QS " (<goto> at line %d) undefined", |
547 | getstr(gt->name), gt->line); | 548 | getstr(gt->name), gt->line); |
@@ -552,17 +553,16 @@ static void mainblock (LexState *ls, FuncState *fs) { | |||
552 | } | 553 | } |
553 | 554 | ||
554 | 555 | ||
555 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Varlist *varl, | 556 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, |
556 | Gotolist *gtl, Labellist *labell, const char *name) { | 557 | Dyndata *dyd, const char *name) { |
557 | LexState lexstate; | 558 | LexState lexstate; |
558 | FuncState funcstate; | 559 | FuncState funcstate; |
559 | TString *tname = luaS_new(L, name); | 560 | TString *tname = luaS_new(L, name); |
560 | setsvalue2s(L, L->top, tname); /* push name to protect it */ | 561 | setsvalue2s(L, L->top, tname); /* push name to protect it */ |
561 | incr_top(L); | 562 | incr_top(L); |
562 | lexstate.buff = buff; | 563 | lexstate.buff = buff; |
563 | lexstate.varl = varl; | 564 | lexstate.dyd = dyd; |
564 | lexstate.gtl = gtl; | 565 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; |
565 | lexstate.labell = labell; | ||
566 | luaX_setinput(L, &lexstate, z, tname); | 566 | luaX_setinput(L, &lexstate, z, tname); |
567 | open_mainfunc(&lexstate, &funcstate); | 567 | open_mainfunc(&lexstate, &funcstate); |
568 | luaX_next(&lexstate); /* read first token */ | 568 | luaX_next(&lexstate); /* read first token */ |
@@ -1172,22 +1172,27 @@ static void breakstat (LexState *ls) { | |||
1172 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | 1172 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); |
1173 | if (upval || | 1173 | if (upval || |
1174 | (fs->nactvar > bl->nactvar && | 1174 | (fs->nactvar > bl->nactvar && |
1175 | ls->labell->nlabel > bl->firstlabel)) | 1175 | ls->dyd->label.n > bl->firstlabel)) |
1176 | luaK_patchclose(fs, bl->breaklist, bl->nactvar); | 1176 | luaK_patchclose(fs, bl->breaklist, bl->nactvar); |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | 1179 | ||
1180 | static int newlabelentry (LexState *ls, Labellist *l, TString *name, | ||
1181 | int line, int pc) { | ||
1182 | int n = l->n; | ||
1183 | luaM_growvector(ls->L, l->arr, l->n, l->size, Labeldesc, MAX_INT, "labels"); | ||
1184 | l->arr[n].name = name; | ||
1185 | l->arr[n].line = line; | ||
1186 | l->arr[n].nactvar = ls->fs->nactvar; | ||
1187 | l->arr[n].pc = pc; | ||
1188 | l->n++; | ||
1189 | return n; | ||
1190 | } | ||
1191 | |||
1192 | |||
1180 | static void gotostat (LexState *ls, TString *label, int line) { | 1193 | static void gotostat (LexState *ls, TString *label, int line) { |
1181 | Gotolist *gtl = ls->gtl; | ||
1182 | int g = gtl->ngt; /* index of new goto being created */ | ||
1183 | /* create new entry for this goto */ | 1194 | /* create new entry for this goto */ |
1184 | luaM_growvector(ls->L, gtl->gt, gtl->ngt, gtl->gtsize, | 1195 | int g = newlabelentry(ls, &ls->dyd->gt, label, line, luaK_jump(ls->fs)); |
1185 | Gotodesc, MAX_INT, "labels"); | ||
1186 | gtl->gt[g].name = label; | ||
1187 | gtl->gt[g].line = line; | ||
1188 | gtl->gt[g].currlevel = ls->fs->nactvar; | ||
1189 | gtl->gt[g].pc = luaK_jump(ls->fs); /* create jump instruction */ | ||
1190 | gtl->ngt++; | ||
1191 | findlabel(ls, g); | 1196 | findlabel(ls, g); |
1192 | } | 1197 | } |
1193 | 1198 | ||
@@ -1195,21 +1200,17 @@ static void gotostat (LexState *ls, TString *label, int line) { | |||
1195 | static void labelstat (LexState *ls, TString *label) { | 1200 | static void labelstat (LexState *ls, TString *label) { |
1196 | /* label -> '@' NAME ':' */ | 1201 | /* label -> '@' NAME ':' */ |
1197 | FuncState *fs = ls->fs; | 1202 | FuncState *fs = ls->fs; |
1198 | Labellist *labell = ls->labell; | 1203 | int l; /* index of new label being created */ |
1199 | int l = labell->nlabel; /* index of new label being created */ | 1204 | Labeldesc *lb; |
1200 | checknext(ls, ':'); | 1205 | checknext(ls, ':'); |
1201 | /* create new entry for this label */ | 1206 | /* create new entry for this label */ |
1202 | luaM_growvector(ls->L, labell->label, labell->nlabel, labell->labelsize, | 1207 | l = newlabelentry(ls, &ls->dyd->label, label, 0, fs->pc); |
1203 | Labeldesc, MAX_INT, "labels"); | 1208 | lb = &ls->dyd->label.arr[l]; |
1204 | labell->label[l].name = label; | ||
1205 | labell->label[l].pc = fs->pc; | ||
1206 | /* if label is last statement in the block, | 1209 | /* if label is last statement in the block, |
1207 | assume that local variables are already out of scope */ | 1210 | assume that local variables are already out of scope */ |
1208 | labell->label[l].nactvar = (ls->t.token == TK_END) | 1211 | if (ls->t.token == TK_END) |
1209 | ? fs->bl->nactvar | 1212 | lb->nactvar = fs->bl->nactvar; |
1210 | : fs->nactvar; | 1213 | findgotos(ls, lb); |
1211 | labell->nlabel++; | ||
1212 | findgotos(ls, &labell->label[l]); | ||
1213 | } | 1214 | } |
1214 | 1215 | ||
1215 | 1216 | ||