|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
-** $Id: lparser.c,v 2.133 2013/04/26 13:07:53 roberto Exp roberto $
|
|
|
+** $Id: lparser.c,v 2.134 2013/08/16 18:55:49 roberto Exp roberto $
|
|
|
** Lua Parser
|
|
|
** See Copyright Notice in lua.h
|
|
|
*/
|
|
@@ -35,6 +35,10 @@
|
|
|
#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
|
|
|
|
|
|
|
|
|
+/* because all strings are unified by the scanner, the parser
|
|
|
+ can use pointer equality for string equality */
|
|
|
+#define eqstr(a,b) ((a) == (b))
|
|
|
+
|
|
|
|
|
|
/*
|
|
|
** nodes for block list (list of active blocks)
|
|
@@ -57,16 +61,6 @@ static void statement (LexState *ls);
|
|
|
static void expr (LexState *ls, expdesc *v);
|
|
|
|
|
|
|
|
|
-static void anchor_token (LexState *ls) {
|
|
|
- /* last token from outer function must be EOS */
|
|
|
- lua_assert(ls->fs != NULL || ls->t.token == TK_EOS);
|
|
|
- if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
|
|
|
- TString *ts = ls->t.seminfo.ts;
|
|
|
- luaX_newstring(ls, getstr(ts), ts->tsv.len);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
/* semantic error */
|
|
|
static l_noret semerror (LexState *ls, const char *msg) {
|
|
|
ls->t.token = 0; /* remove 'near to' from final message */
|
|
@@ -222,7 +216,7 @@ static int searchupvalue (FuncState *fs, TString *name) {
|
|
|
int i;
|
|
|
Upvaldesc *up = fs->f->upvalues;
|
|
|
for (i = 0; i < fs->nups; i++) {
|
|
|
- if (luaS_eqstr(up[i].name, name)) return i;
|
|
|
+ if (eqstr(up[i].name, name)) return i;
|
|
|
}
|
|
|
return -1; /* not found */
|
|
|
}
|
|
@@ -246,7 +240,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
|
|
|
static int searchvar (FuncState *fs, TString *n) {
|
|
|
int i;
|
|
|
for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
|
|
|
- if (luaS_eqstr(n, getlocvar(fs, i)->varname))
|
|
|
+ if (eqstr(n, getlocvar(fs, i)->varname))
|
|
|
return i;
|
|
|
}
|
|
|
return -1; /* not found */
|
|
@@ -342,7 +336,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) {
|
|
|
FuncState *fs = ls->fs;
|
|
|
Labellist *gl = &ls->dyd->gt;
|
|
|
Labeldesc *gt = &gl->arr[g];
|
|
|
- lua_assert(luaS_eqstr(gt->name, label->name));
|
|
|
+ lua_assert(eqstr(gt->name, label->name));
|
|
|
if (gt->nactvar < label->nactvar) {
|
|
|
TString *vname = getlocvar(fs, gt->nactvar)->varname;
|
|
|
const char *msg = luaO_pushfstring(ls->L,
|
|
@@ -369,7 +363,7 @@ static int findlabel (LexState *ls, int g) {
|
|
|
/* check labels in current block for a match */
|
|
|
for (i = bl->firstlabel; i < dyd->label.n; i++) {
|
|
|
Labeldesc *lb = &dyd->label.arr[i];
|
|
|
- if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */
|
|
|
+ if (eqstr(lb->name, gt->name)) { /* correct label? */
|
|
|
if (gt->nactvar > lb->nactvar &&
|
|
|
(bl->upval || dyd->label.n > bl->firstlabel))
|
|
|
luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
|
|
@@ -403,7 +397,7 @@ static void findgotos (LexState *ls, Labeldesc *lb) {
|
|
|
Labellist *gl = &ls->dyd->gt;
|
|
|
int i = ls->fs->bl->firstgoto;
|
|
|
while (i < gl->n) {
|
|
|
- if (luaS_eqstr(gl->arr[i].name, lb->name))
|
|
|
+ if (eqstr(gl->arr[i].name, lb->name))
|
|
|
closegoto(ls, i, lb);
|
|
|
else
|
|
|
i++;
|
|
@@ -525,7 +519,6 @@ static void codeclosure (LexState *ls, expdesc *v) {
|
|
|
|
|
|
|
|
|
static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
|
|
|
- lua_State *L = ls->L;
|
|
|
Proto *f;
|
|
|
fs->prev = ls->fs; /* linked list of funcstates */
|
|
|
fs->ls = ls;
|
|
@@ -544,10 +537,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
|
|
|
f = fs->f;
|
|
|
f->source = ls->source;
|
|
|
f->maxstacksize = 2; /* registers 0/1 are always valid */
|
|
|
- fs->h = luaH_new(L);
|
|
|
- /* anchor table of constants (to avoid being collected) */
|
|
|
- sethvalue2s(L, L->top, fs->h);
|
|
|
- incr_top(L);
|
|
|
enterblock(fs, bl, 0);
|
|
|
}
|
|
|
|
|
@@ -572,9 +561,6 @@ static void close_func (LexState *ls) {
|
|
|
f->sizeupvalues = fs->nups;
|
|
|
lua_assert(fs->bl == NULL);
|
|
|
ls->fs = fs->prev;
|
|
|
- /* last token read was anchored in defunct function; must re-anchor it */
|
|
|
- anchor_token(ls);
|
|
|
- L->top--; /* pop table of constants */
|
|
|
luaC_checkGC(L);
|
|
|
}
|
|
|
|
|
@@ -1202,7 +1188,7 @@ static void gotostat (LexState *ls, int pc) {
|
|
|
static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
|
|
|
int i;
|
|
|
for (i = fs->bl->firstlabel; i < ll->n; i++) {
|
|
|
- if (luaS_eqstr(label, ll->arr[i].name)) {
|
|
|
+ if (eqstr(label, ll->arr[i].name)) {
|
|
|
const char *msg = luaO_pushfstring(fs->ls->L,
|
|
|
"label " LUA_QS " already defined on line %d",
|
|
|
getstr(label), ll->arr[i].line);
|
|
@@ -1627,8 +1613,10 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
|
|
|
LexState lexstate;
|
|
|
FuncState funcstate;
|
|
|
Closure *cl = luaF_newLclosure(L, 1); /* create main closure */
|
|
|
- /* anchor closure (to avoid being collected) */
|
|
|
- setclLvalue(L, L->top, cl);
|
|
|
+ setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */
|
|
|
+ incr_top(L);
|
|
|
+ lexstate.h = luaH_new(L); /* create table for scanner */
|
|
|
+ sethvalue(L, L->top, lexstate.h); /* anchor it */
|
|
|
incr_top(L);
|
|
|
funcstate.f = cl->l.p = luaF_newproto(L);
|
|
|
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,
|
|
|
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
|
|
|
/* all scopes should be correctly finished */
|
|
|
lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
|
|
|
- return cl; /* it's on the stack too */
|
|
|
+ L->top--; /* remove scanner's table */
|
|
|
+ return cl; /* closure is on the stack, too */
|
|
|
}
|
|
|
|