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 | |
| 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
| -rw-r--r-- | ldo.c | 23 | ||||
| -rw-r--r-- | llex.h | 10 | ||||
| -rw-r--r-- | lparser.c | 129 | ||||
| -rw-r--r-- | lparser.h | 60 |
4 files changed, 104 insertions, 118 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.90 2010/10/25 19:01:37 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.91 2011/02/04 17:34:43 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -615,10 +615,8 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
| 615 | */ | 615 | */ |
| 616 | struct SParser { /* data to `f_parser' */ | 616 | struct SParser { /* data to `f_parser' */ |
| 617 | ZIO *z; | 617 | ZIO *z; |
| 618 | Mbuffer buff; /* buffer to be used by the scanner */ | 618 | Mbuffer buff; /* dynamic structure used by the scanner */ |
| 619 | Varlist varl; /* list of local variables (to be used by the parser) */ | 619 | Dyndata dyd; /* dynamic structures used by the parser */ |
| 620 | Gotolist gtl; /* list of pending gotos (") */ | ||
| 621 | Labellist labell; /* list of active labels (") */ | ||
| 622 | const char *name; | 620 | const char *name; |
| 623 | }; | 621 | }; |
| 624 | 622 | ||
| @@ -630,8 +628,7 @@ static void f_parser (lua_State *L, void *ud) { | |||
| 630 | int c = luaZ_lookahead(p->z); | 628 | int c = luaZ_lookahead(p->z); |
| 631 | tf = (c == LUA_SIGNATURE[0]) | 629 | tf = (c == LUA_SIGNATURE[0]) |
| 632 | ? luaU_undump(L, p->z, &p->buff, p->name) | 630 | ? luaU_undump(L, p->z, &p->buff, p->name) |
| 633 | : luaY_parser(L, p->z, &p->buff, &p->varl, | 631 | : luaY_parser(L, p->z, &p->buff, &p->dyd, p->name); |
| 634 | &p->gtl, &p->labell, p->name); | ||
| 635 | setptvalue2s(L, L->top, tf); | 632 | setptvalue2s(L, L->top, tf); |
| 636 | incr_top(L); | 633 | incr_top(L); |
| 637 | cl = luaF_newLclosure(L, tf); | 634 | cl = luaF_newLclosure(L, tf); |
| @@ -646,15 +643,15 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { | |||
| 646 | int status; | 643 | int status; |
| 647 | L->nny++; /* cannot yield during parsing */ | 644 | L->nny++; /* cannot yield during parsing */ |
| 648 | p.z = z; p.name = name; | 645 | p.z = z; p.name = name; |
| 649 | p.varl.actvar = NULL; p.varl.nactvar = p.varl.actvarsize = 0; | 646 | p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; |
| 650 | p.gtl.gt = NULL; p.gtl.ngt = p.gtl.gtsize = 0; | 647 | p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; |
| 651 | p.labell.label = NULL; p.labell.nlabel = p.labell.labelsize = 0; | 648 | p.dyd.label.arr = NULL; p.dyd.label.size = 0; |
| 652 | luaZ_initbuffer(L, &p.buff); | 649 | luaZ_initbuffer(L, &p.buff); |
| 653 | status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); | 650 | status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); |
| 654 | luaZ_freebuffer(L, &p.buff); | 651 | luaZ_freebuffer(L, &p.buff); |
| 655 | luaM_freearray(L, p.varl.actvar, p.varl.actvarsize); | 652 | luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); |
| 656 | luaM_freearray(L, p.gtl.gt, p.gtl.gtsize); | 653 | luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); |
| 657 | luaM_freearray(L, p.labell.label, p.labell.labelsize); | 654 | luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); |
| 658 | L->nny--; | 655 | L->nny--; |
| 659 | return status; | 656 | return status; |
| 660 | } | 657 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.h,v 1.66 2011/02/02 14:55:17 roberto Exp roberto $ | 2 | ** $Id: llex.h,v 1.67 2011/02/04 17:34:43 roberto Exp roberto $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -48,19 +48,19 @@ typedef struct Token { | |||
| 48 | } Token; | 48 | } Token; |
| 49 | 49 | ||
| 50 | 50 | ||
| 51 | /* state of the lexer plus state of the parser when shared by all | ||
| 52 | functions */ | ||
| 51 | typedef struct LexState { | 53 | typedef struct LexState { |
| 52 | int current; /* current character (charint) */ | 54 | int current; /* current character (charint) */ |
| 53 | int linenumber; /* input line counter */ | 55 | int linenumber; /* input line counter */ |
| 54 | int lastline; /* line of last token `consumed' */ | 56 | int lastline; /* line of last token `consumed' */ |
| 55 | Token t; /* current token */ | 57 | Token t; /* current token */ |
| 56 | Token lookahead; /* look ahead token */ | 58 | Token lookahead; /* look ahead token */ |
| 57 | struct FuncState *fs; /* `FuncState' is private to the parser */ | 59 | struct FuncState *fs; /* current function (parser) */ |
| 58 | struct lua_State *L; | 60 | struct lua_State *L; |
| 59 | ZIO *z; /* input stream */ | 61 | ZIO *z; /* input stream */ |
| 60 | Mbuffer *buff; /* buffer for tokens */ | 62 | Mbuffer *buff; /* buffer for tokens */ |
| 61 | struct Varlist *varl; /* list of all active local variables */ | 63 | struct Dyndata *dyd; /* dynamic structures used by the parser */ |
| 62 | struct Gotolist *gtl; /* list of pending gotos */ | ||
| 63 | struct Labellist *labell; /* list of active labels */ | ||
| 64 | TString *source; /* current source name */ | 64 | TString *source; /* current source name */ |
| 65 | TString *envn; /* environment variable name */ | 65 | TString *envn; /* environment variable name */ |
| 66 | char decpoint; /* locale decimal point */ | 66 | char decpoint; /* locale decimal point */ |
| @@ -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 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.h,v 1.65 2010/07/07 16:27:29 roberto Exp roberto $ | 2 | ** $Id: lparser.h,v 1.66 2011/02/04 17:34:43 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 | */ |
| @@ -59,47 +59,36 @@ typedef struct Vardesc { | |||
| 59 | } Vardesc; | 59 | } Vardesc; |
| 60 | 60 | ||
| 61 | 61 | ||
| 62 | /* list of all active local variables */ | 62 | /* description of pending goto statements and label statements */ |
| 63 | typedef struct Varlist { | ||
| 64 | Vardesc *actvar; | ||
| 65 | int nactvar; | ||
| 66 | int actvarsize; | ||
| 67 | } Varlist; | ||
| 68 | |||
| 69 | |||
| 70 | /* description of pending goto statement */ | ||
| 71 | typedef struct Gotodesc { | ||
| 72 | TString *name; | ||
| 73 | int pc; /* where it is coded */ | ||
| 74 | int line; /* line where it appeared */ | ||
| 75 | lu_byte currlevel; /* variable level where it appears in current block */ | ||
| 76 | } Gotodesc; | ||
| 77 | |||
| 78 | |||
| 79 | /* list of pending gotos */ | ||
| 80 | typedef struct Gotolist { | ||
| 81 | Gotodesc *gt; | ||
| 82 | int ngt; | ||
| 83 | int gtsize; | ||
| 84 | } Gotolist; | ||
| 85 | |||
| 86 | |||
| 87 | /* description of active labels */ | ||
| 88 | typedef struct Labeldesc { | 63 | typedef struct Labeldesc { |
| 89 | TString *name; | 64 | TString *name; /* label identifier */ |
| 90 | int pc; /* label position */ | 65 | int pc; /* position in code */ |
| 91 | lu_byte nactvar; /* variable level where it appears in current block */ | 66 | int line; /* line where it appeared */ |
| 67 | lu_byte nactvar; /* local level where it appears in current block */ | ||
| 92 | } Labeldesc; | 68 | } Labeldesc; |
| 93 | 69 | ||
| 94 | 70 | ||
| 95 | /* list of active labels */ | 71 | /* list of labels or gotos */ |
| 96 | typedef struct Labellist { | 72 | typedef struct Labellist { |
| 97 | Labeldesc *label; | 73 | Labeldesc *arr; /* array */ |
| 98 | int nlabel; | 74 | int n; /* number of entries in use */ |
| 99 | int labelsize; | 75 | int size; /* array size */ |
| 100 | } Labellist; | 76 | } Labellist; |
| 101 | 77 | ||
| 102 | 78 | ||
| 79 | /* dynamic structures used by the parser */ | ||
| 80 | typedef struct Dyndata { | ||
| 81 | struct { /* list of active local variables */ | ||
| 82 | Vardesc *arr; | ||
| 83 | int n; | ||
| 84 | int size; | ||
| 85 | } actvar; | ||
| 86 | Labellist gt; /* list of pending gotos */ | ||
| 87 | Labellist label; /* list of active labels */ | ||
| 88 | } Dyndata; | ||
| 89 | |||
| 90 | |||
| 91 | /* control of blocks */ | ||
| 103 | struct BlockCnt; /* defined in lparser.c */ | 92 | struct BlockCnt; /* defined in lparser.c */ |
| 104 | 93 | ||
| 105 | 94 | ||
| @@ -125,8 +114,7 @@ typedef struct FuncState { | |||
| 125 | 114 | ||
| 126 | 115 | ||
| 127 | LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | 116 | LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, |
| 128 | Varlist *varl, Gotolist *gtl, | 117 | Dyndata *dyd, const char *name); |
| 129 | Labellist *labell, const char *name); | ||
| 130 | 118 | ||
| 131 | 119 | ||
| 132 | #endif | 120 | #endif |
