Browse Source

new "local function"

v5-2
Roberto Ierusalimschy 23 years ago
parent
commit
65d66ba275
  1. 58
      lparser.c

58
lparser.c

@ -1,5 +1,5 @@
/* /*
** $Id: lparser.c,v 1.186 2002/06/06 13:16:02 roberto Exp roberto $ ** $Id: lparser.c,v 1.187 2002/06/06 13:52:37 roberto Exp roberto $
** Lua Parser ** Lua Parser
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -73,16 +73,6 @@ static void error_expected (LexState *ls, int token) {
} }
static void check (LexState *ls, int c) {
if (ls->t.token != c)
error_expected(ls, c);
next(ls);
}
#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
static int testnext (LexState *ls, int c) { static int testnext (LexState *ls, int c) {
if (ls->t.token == c) { if (ls->t.token == c) {
next(ls); next(ls);
@ -92,8 +82,18 @@ static int testnext (LexState *ls, int c) {
} }
static void check (LexState *ls, int c) {
if (!testnext(ls, c))
error_expected(ls, c);
}
#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
static void check_match (LexState *ls, int what, int who, int where) { static void check_match (LexState *ls, int what, int who, int where) {
if (ls->t.token != what) { if (!testnext(ls, what)) {
if (where == ls->linenumber) if (where == ls->linenumber)
error_expected(ls, what); error_expected(ls, what);
else { else {
@ -102,7 +102,6 @@ static void check_match (LexState *ls, int what, int who, int where) {
luaX_token2str(ls, what), luaX_token2str(ls, who), where)); luaX_token2str(ls, what), luaX_token2str(ls, who), where));
} }
} }
next(ls);
} }
@ -400,8 +399,7 @@ static int explist1 (LexState *ls, expdesc *v) {
/* explist1 -> expr { `,' expr } */ /* explist1 -> expr { `,' expr } */
int n = 1; /* at least one expression */ int n = 1; /* at least one expression */
expr(ls, v); expr(ls, v);
while (ls->t.token == ',') { while (testnext(ls, ',')) {
next(ls); /* skip comma */
luaK_exp2nextreg(ls->fs, v); luaK_exp2nextreg(ls->fs, v);
expr(ls, v); expr(ls, v);
n++; n++;
@ -544,7 +542,7 @@ static void constructor (LexState *ls, expdesc *t) {
init_exp(&cc.v, VVOID, 0); /* no value (yet) */ init_exp(&cc.v, VVOID, 0); /* no value (yet) */
luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
check(ls, '{'); check(ls, '{');
for (;;) { do {
lua_assert(cc.v.k == VVOID || cc.tostore > 0); lua_assert(cc.v.k == VVOID || cc.tostore > 0);
testnext(ls, ';'); /* compatibility only */ testnext(ls, ';'); /* compatibility only */
if (ls->t.token == '}') break; if (ls->t.token == '}') break;
@ -567,11 +565,7 @@ static void constructor (LexState *ls, expdesc *t) {
break; break;
} }
} }
if (ls->t.token == ',' || ls->t.token == ';') } while (testnext(ls, ',') || testnext(ls, ';'));
next(ls);
else
break;
}
check_match(ls, '}', '{', line); check_match(ls, '}', '{', line);
lastlistfield(fs, &cc); lastlistfield(fs, &cc);
if (cc.na > 0) if (cc.na > 0)
@ -857,10 +851,9 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
expdesc e; expdesc e;
check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
"syntax error"); "syntax error");
if (ls->t.token == ',') { /* assignment -> `,' primaryexp assignment */ if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
struct LHS_assign nv; struct LHS_assign nv;
nv.prev = lh; nv.prev = lh;
next(ls);
primaryexp(ls, &nv.v); primaryexp(ls, &nv.v);
if (nv.v.k == VLOCAL) if (nv.v.k == VLOCAL)
check_conflict(ls, lh, &nv.v); check_conflict(ls, lh, &nv.v);
@ -1083,7 +1076,7 @@ static void ifstat (LexState *ls, int line) {
if (ls->t.token == TK_ELSE) { if (ls->t.token == TK_ELSE) {
luaK_concat(fs, &escapelist, luaK_jump(fs)); luaK_concat(fs, &escapelist, luaK_jump(fs));
luaK_patchtohere(fs, v.f); luaK_patchtohere(fs, v.f);
next(ls); /* skip ELSE */ next(ls); /* skip ELSE (after patch, for correct line info) */
block(ls); /* `else' part */ block(ls); /* `else' part */
} }
else else
@ -1093,12 +1086,21 @@ static void ifstat (LexState *ls, int line) {
} }
static void localfunc (LexState *ls) {
expdesc v, b;
new_localvar(ls, str_checkname(ls), 0);
init_exp(&v, VLOCAL, ls->fs->freereg++);
adjustlocalvars(ls, 1);
body(ls, &b, 0, ls->linenumber);
luaK_storevar(ls->fs, &v, &b);
}
static void localstat (LexState *ls) { static void localstat (LexState *ls) {
/* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
int nvars = 0; int nvars = 0;
int nexps; int nexps;
expdesc e; expdesc e;
next(ls); /* skip LOCAL */
do { do {
new_localvar(ls, str_checkname(ls), nvars++); new_localvar(ls, str_checkname(ls), nvars++);
} while (testnext(ls, ',')); } while (testnext(ls, ','));
@ -1234,7 +1236,11 @@ static int statement (LexState *ls) {
return 0; return 0;
} }
case TK_LOCAL: { /* stat -> localstat */ case TK_LOCAL: { /* stat -> localstat */
localstat(ls); next(ls); /* skip LOCAL */
if (testnext(ls, TK_FUNCTION)) /* local function? */
localfunc(ls);
else
localstat(ls);
return 0; return 0;
} }
case TK_RETURN: { /* stat -> retstat */ case TK_RETURN: { /* stat -> retstat */

Loading…
Cancel
Save