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 |