diff options
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 45 |
1 files changed, 17 insertions, 28 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.133 2013/04/26 13:07:53 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.134 2013/08/16 18:55:49 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 | */ |
@@ -35,6 +35,10 @@ | |||
35 | #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) | 35 | #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) |
36 | 36 | ||
37 | 37 | ||
38 | /* because all strings are unified by the scanner, the parser | ||
39 | can use pointer equality for string equality */ | ||
40 | #define eqstr(a,b) ((a) == (b)) | ||
41 | |||
38 | 42 | ||
39 | /* | 43 | /* |
40 | ** nodes for block list (list of active blocks) | 44 | ** nodes for block list (list of active blocks) |
@@ -57,16 +61,6 @@ static void statement (LexState *ls); | |||
57 | static void expr (LexState *ls, expdesc *v); | 61 | static void expr (LexState *ls, expdesc *v); |
58 | 62 | ||
59 | 63 | ||
60 | static void anchor_token (LexState *ls) { | ||
61 | /* last token from outer function must be EOS */ | ||
62 | lua_assert(ls->fs != NULL || ls->t.token == TK_EOS); | ||
63 | if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { | ||
64 | TString *ts = ls->t.seminfo.ts; | ||
65 | luaX_newstring(ls, getstr(ts), ts->tsv.len); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | |||
70 | /* semantic error */ | 64 | /* semantic error */ |
71 | static l_noret semerror (LexState *ls, const char *msg) { | 65 | static l_noret semerror (LexState *ls, const char *msg) { |
72 | ls->t.token = 0; /* remove 'near to' from final message */ | 66 | ls->t.token = 0; /* remove 'near to' from final message */ |
@@ -222,7 +216,7 @@ static int searchupvalue (FuncState *fs, TString *name) { | |||
222 | int i; | 216 | int i; |
223 | Upvaldesc *up = fs->f->upvalues; | 217 | Upvaldesc *up = fs->f->upvalues; |
224 | for (i = 0; i < fs->nups; i++) { | 218 | for (i = 0; i < fs->nups; i++) { |
225 | if (luaS_eqstr(up[i].name, name)) return i; | 219 | if (eqstr(up[i].name, name)) return i; |
226 | } | 220 | } |
227 | return -1; /* not found */ | 221 | return -1; /* not found */ |
228 | } | 222 | } |
@@ -246,7 +240,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) { | |||
246 | static int searchvar (FuncState *fs, TString *n) { | 240 | static int searchvar (FuncState *fs, TString *n) { |
247 | int i; | 241 | int i; |
248 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { | 242 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { |
249 | if (luaS_eqstr(n, getlocvar(fs, i)->varname)) | 243 | if (eqstr(n, getlocvar(fs, i)->varname)) |
250 | return i; | 244 | return i; |
251 | } | 245 | } |
252 | return -1; /* not found */ | 246 | return -1; /* not found */ |
@@ -342,7 +336,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) { | |||
342 | FuncState *fs = ls->fs; | 336 | FuncState *fs = ls->fs; |
343 | Labellist *gl = &ls->dyd->gt; | 337 | Labellist *gl = &ls->dyd->gt; |
344 | Labeldesc *gt = &gl->arr[g]; | 338 | Labeldesc *gt = &gl->arr[g]; |
345 | lua_assert(luaS_eqstr(gt->name, label->name)); | 339 | lua_assert(eqstr(gt->name, label->name)); |
346 | if (gt->nactvar < label->nactvar) { | 340 | if (gt->nactvar < label->nactvar) { |
347 | TString *vname = getlocvar(fs, gt->nactvar)->varname; | 341 | TString *vname = getlocvar(fs, gt->nactvar)->varname; |
348 | const char *msg = luaO_pushfstring(ls->L, | 342 | const char *msg = luaO_pushfstring(ls->L, |
@@ -369,7 +363,7 @@ static int findlabel (LexState *ls, int g) { | |||
369 | /* check labels in current block for a match */ | 363 | /* check labels in current block for a match */ |
370 | for (i = bl->firstlabel; i < dyd->label.n; i++) { | 364 | for (i = bl->firstlabel; i < dyd->label.n; i++) { |
371 | Labeldesc *lb = &dyd->label.arr[i]; | 365 | Labeldesc *lb = &dyd->label.arr[i]; |
372 | if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */ | 366 | if (eqstr(lb->name, gt->name)) { /* correct label? */ |
373 | if (gt->nactvar > lb->nactvar && | 367 | if (gt->nactvar > lb->nactvar && |
374 | (bl->upval || dyd->label.n > bl->firstlabel)) | 368 | (bl->upval || dyd->label.n > bl->firstlabel)) |
375 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); | 369 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); |
@@ -403,7 +397,7 @@ static void findgotos (LexState *ls, Labeldesc *lb) { | |||
403 | Labellist *gl = &ls->dyd->gt; | 397 | Labellist *gl = &ls->dyd->gt; |
404 | int i = ls->fs->bl->firstgoto; | 398 | int i = ls->fs->bl->firstgoto; |
405 | while (i < gl->n) { | 399 | while (i < gl->n) { |
406 | if (luaS_eqstr(gl->arr[i].name, lb->name)) | 400 | if (eqstr(gl->arr[i].name, lb->name)) |
407 | closegoto(ls, i, lb); | 401 | closegoto(ls, i, lb); |
408 | else | 402 | else |
409 | i++; | 403 | i++; |
@@ -525,7 +519,6 @@ static void codeclosure (LexState *ls, expdesc *v) { | |||
525 | 519 | ||
526 | 520 | ||
527 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | 521 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { |
528 | lua_State *L = ls->L; | ||
529 | Proto *f; | 522 | Proto *f; |
530 | fs->prev = ls->fs; /* linked list of funcstates */ | 523 | fs->prev = ls->fs; /* linked list of funcstates */ |
531 | fs->ls = ls; | 524 | fs->ls = ls; |
@@ -544,10 +537,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | |||
544 | f = fs->f; | 537 | f = fs->f; |
545 | f->source = ls->source; | 538 | f->source = ls->source; |
546 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | 539 | f->maxstacksize = 2; /* registers 0/1 are always valid */ |
547 | fs->h = luaH_new(L); | ||
548 | /* anchor table of constants (to avoid being collected) */ | ||
549 | sethvalue2s(L, L->top, fs->h); | ||
550 | incr_top(L); | ||
551 | enterblock(fs, bl, 0); | 540 | enterblock(fs, bl, 0); |
552 | } | 541 | } |
553 | 542 | ||
@@ -572,9 +561,6 @@ static void close_func (LexState *ls) { | |||
572 | f->sizeupvalues = fs->nups; | 561 | f->sizeupvalues = fs->nups; |
573 | lua_assert(fs->bl == NULL); | 562 | lua_assert(fs->bl == NULL); |
574 | ls->fs = fs->prev; | 563 | ls->fs = fs->prev; |
575 | /* last token read was anchored in defunct function; must re-anchor it */ | ||
576 | anchor_token(ls); | ||
577 | L->top--; /* pop table of constants */ | ||
578 | luaC_checkGC(L); | 564 | luaC_checkGC(L); |
579 | } | 565 | } |
580 | 566 | ||
@@ -1202,7 +1188,7 @@ static void gotostat (LexState *ls, int pc) { | |||
1202 | static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { | 1188 | static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { |
1203 | int i; | 1189 | int i; |
1204 | for (i = fs->bl->firstlabel; i < ll->n; i++) { | 1190 | for (i = fs->bl->firstlabel; i < ll->n; i++) { |
1205 | if (luaS_eqstr(label, ll->arr[i].name)) { | 1191 | if (eqstr(label, ll->arr[i].name)) { |
1206 | const char *msg = luaO_pushfstring(fs->ls->L, | 1192 | const char *msg = luaO_pushfstring(fs->ls->L, |
1207 | "label " LUA_QS " already defined on line %d", | 1193 | "label " LUA_QS " already defined on line %d", |
1208 | getstr(label), ll->arr[i].line); | 1194 | getstr(label), ll->arr[i].line); |
@@ -1627,8 +1613,10 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |||
1627 | LexState lexstate; | 1613 | LexState lexstate; |
1628 | FuncState funcstate; | 1614 | FuncState funcstate; |
1629 | Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ | 1615 | Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ |
1630 | /* anchor closure (to avoid being collected) */ | 1616 | setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */ |
1631 | setclLvalue(L, L->top, cl); | 1617 | incr_top(L); |
1618 | lexstate.h = luaH_new(L); /* create table for scanner */ | ||
1619 | sethvalue(L, L->top, lexstate.h); /* anchor it */ | ||
1632 | incr_top(L); | 1620 | incr_top(L); |
1633 | funcstate.f = cl->l.p = luaF_newproto(L); | 1621 | funcstate.f = cl->l.p = luaF_newproto(L); |
1634 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ | 1622 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ |
@@ -1641,6 +1629,7 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |||
1641 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); | 1629 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); |
1642 | /* all scopes should be correctly finished */ | 1630 | /* all scopes should be correctly finished */ |
1643 | lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); | 1631 | lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); |
1644 | return cl; /* it's on the stack too */ | 1632 | L->top--; /* remove scanner's table */ |
1633 | return cl; /* closure is on the stack, too */ | ||
1645 | } | 1634 | } |
1646 | 1635 | ||