commit b69e712713785394ceefa11ab3e5f9636abea733
parent f51775950737eb4d097cda0bba143973b5385947
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 21 Jun 2000 15:13:34 -0300
new way to generate SETLINEs
Diffstat:
5 files changed, 41 insertions(+), 57 deletions(-)
diff --git a/lcode.c b/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 1.36 2000/06/16 17:51:40 roberto Exp roberto $
+** $Id: lcode.c,v 1.37 2000/06/21 17:05:49 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -307,9 +307,8 @@ static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) {
static int code_label (FuncState *fs, OpCode op, int arg) {
- int j = luaK_getlabel(fs);
- luaK_code1(fs, op, arg);
- return j;
+ luaK_getlabel(fs); /* those instructions may be jump targets */
+ return luaK_code1(fs, op, arg);
}
@@ -624,9 +623,17 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
case iS: i = CREATE_S(o, arg1); break;
case iAB: i = CREATE_AB(o, arg1, arg2); break;
}
- /* put new instruction in code array */
- luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction,
+ /* check space for new instruction plus eventual SETLINE */
+ luaM_growvector(fs->L, fs->f->code, fs->pc, 2, Instruction,
"code size overflow", MAX_INT);
+ /* check the need for SETLINE */
+ if (fs->debug && fs->ls->lastline != fs->lastsetline) {
+ LexState *ls = fs->ls;
+ luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk");
+ fs->f->code[fs->pc++] = CREATE_U(OP_SETLINE, ls->lastline);
+ fs->lastsetline = ls->lastline;
+ }
+ /* put new instruction in code array */
fs->f->code[fs->pc] = i;
return fs->pc++;
}
diff --git a/llex.c b/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 1.63 2000/06/12 13:52:05 roberto Exp roberto $
+** $Id: llex.c,v 1.64 2000/06/19 18:05:14 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -138,6 +138,7 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
LS->z = z;
LS->fs = NULL;
LS->linenumber = 1;
+ LS->lastline = 1;
LS->source = source;
next(LS); /* read first char */
if (LS->current == '#') {
diff --git a/llex.h b/llex.h
@@ -1,5 +1,5 @@
/*
-** $Id: llex.h,v 1.28 2000/05/26 14:04:04 roberto Exp roberto $
+** $Id: llex.h,v 1.29 2000/06/19 18:05:14 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -51,6 +51,7 @@ typedef struct LexState {
struct lua_State *L;
struct zio *z; /* input stream */
int linenumber; /* input line counter */
+ int lastline; /* line of last token `consumed' */
TString *source; /* current source name */
} LexState;
diff --git a/lparser.c b/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 1.96 2000/06/19 18:05:14 roberto Exp roberto $
+** $Id: lparser.c,v 1.97 2000/06/19 18:26:23 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -56,6 +56,7 @@ static void exp1 (LexState *ls);
static void next (LexState *ls) {
+ ls->lastline = ls->linenumber;
if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
ls->t = ls->lookahead; /* use this one */
ls->lookahead.token = TK_EOS; /* and discharge it */
@@ -91,16 +92,6 @@ static void check_condition (LexState *ls, int c, const char *msg) {
}
-static void setline (LexState *ls) {
- FuncState *fs = ls->fs;
- if (ls->L->debug && ls->linenumber != fs->lastsetline) {
- luaX_checklimit(ls, ls->linenumber, MAXARG_U, "lines in a chunk");
- luaK_code1(fs, OP_SETLINE, ls->linenumber);
- fs->lastsetline = ls->linenumber;
- }
-}
-
-
static int optional (LexState *ls, int c) {
if (ls->t.token == c) {
next(ls);
@@ -128,18 +119,6 @@ static void check_match (LexState *ls, int what, int who, int where) {
}
-static void setline_and_next (LexState *ls) {
- setline(ls);
- next(ls);
-}
-
-
-static void check_END (LexState *ls, int who, int where) {
- setline(ls); /* setline for END */
- check_match(ls, TK_END, who, where);
-}
-
-
static int string_constant (FuncState *fs, TString *s) {
Proto *f = fs->f;
int c = s->u.s.constindex;
@@ -175,9 +154,7 @@ static int checkname (LexState *ls) {
static void luaI_registerlocalvar (LexState *ls, TString *varname, int line) {
FuncState *fs = ls->fs;
- /* start debug only when there are no active local variables,
- but keep going after starting */
- if ((ls->L->debug && fs->nlocalvar == 0) || fs->nvars != 0) {
+ if (fs->debug) {
Proto *f = fs->f;
luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT);
f->locvars[fs->nvars].varname = varname;
@@ -368,10 +345,8 @@ static void close_func (LexState *ls) {
luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
luaM_reallocvector(L, f->knum, f->nknum, Number);
luaM_reallocvector(L, f->kproto, f->nkproto, Proto *);
- if (f->locvars) { /* debug information? */
- luaI_registerlocalvar(ls, NULL, -1); /* flag end of vector */
- luaM_reallocvector(L, f->locvars, fs->nvars, LocVar);
- }
+ luaI_registerlocalvar(ls, NULL, -1); /* flag end of vector */
+ luaM_reallocvector(L, f->locvars, fs->nvars, LocVar);
ls->fs = fs->prev;
LUA_ASSERT(L, fs->bl == NULL, "wrong list end");
}
@@ -383,6 +358,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
open_func(&lexstate, &funcstate);
next(&lexstate); /* read first token */
+ funcstate.debug = L->debug; /* previous `next' may scan a pragma */
chunk(&lexstate);
check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
close_func(&lexstate);
@@ -639,7 +615,6 @@ static void constructor (LexState *ls) {
static void simpleexp (LexState *ls, expdesc *v) {
FuncState *fs = ls->fs;
- setline(ls);
switch (ls->t.token) {
case TK_NUMBER: { /* simpleexp -> NUMBER */
Number r = ls->t.seminfo.r;
@@ -819,13 +794,13 @@ static void whilestat (LexState *ls, int line) {
expdesc v;
Breaklabel bl;
enterbreak(fs, &bl);
- setline_and_next(ls); /* trace WHILE when looping */
+ next(ls);
cond(ls, &v);
check(ls, TK_DO);
block(ls);
luaK_patchlist(fs, luaK_jump(fs), while_init);
luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
- check_END(ls, TK_WHILE, line); /* trace END when loop ends */
+ check_match(ls, TK_END, TK_WHILE, line);
leavebreak(fs, &bl);
}
@@ -837,7 +812,7 @@ static void repeatstat (LexState *ls, int line) {
expdesc v;
Breaklabel bl;
enterbreak(fs, &bl);
- setline_and_next(ls); /* trace REPEAT when looping */
+ next(ls);
block(ls);
check_match(ls, TK_UNTIL, TK_REPEAT, line);
cond(ls, &v);
@@ -905,23 +880,22 @@ static void forstat (LexState *ls, int line) {
TString *varname;
Breaklabel bl;
enterbreak(fs, &bl);
- setline_and_next(ls); /* skip `for' */
+ next(ls); /* skip `for' */
varname = str_checkname(ls); /* first variable name */
switch (ls->t.token) {
case '=': fornum(ls, varname); break;
case ',': forlist(ls, varname); break;
default: luaK_error(ls, "`=' or `,' expected");
}
- check_END(ls, TK_FOR, line);
+ check_match(ls, TK_END, TK_FOR, line);
leavebreak(fs, &bl);
}
static void test_then_block (LexState *ls, expdesc *v) {
/* test_then_block -> [IF | ELSEIF] cond THEN block */
- setline_and_next(ls); /* skip IF or ELSEIF */
+ next(ls); /* skip IF or ELSEIF */
cond(ls, v);
- setline(ls); /* to trace the THEN */
check(ls, TK_THEN);
block(ls); /* `then' part */
}
@@ -941,13 +915,13 @@ static void ifstat (LexState *ls, int line) {
if (ls->t.token == TK_ELSE) {
luaK_concat(fs, &escapelist, luaK_jump(fs));
luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
- setline_and_next(ls); /* skip ELSE */
+ next(ls); /* skip ELSE */
block(ls); /* `else' part */
}
else
luaK_concat(fs, &escapelist, v.u.l.f);
luaK_patchlist(fs, escapelist, luaK_getlabel(fs));
- check_END(ls, TK_IF, line);
+ check_match(ls, TK_END, TK_IF, line);
}
@@ -956,7 +930,7 @@ static void localstat (LexState *ls) {
int nvars = 0;
int nexps;
do {
- setline_and_next(ls); /* skip LOCAL or ',' */
+ next(ls); /* skip LOCAL or ',' */
store_localvar(ls, str_checkname(ls), nvars++);
} while (ls->t.token == ',');
if (optional(ls, '='))
@@ -989,7 +963,7 @@ static void funcstat (LexState *ls, int line) {
expdesc v;
check_condition(ls, (ls->fs->prev == NULL),
"cannot nest this kind of function declaration");
- setline_and_next(ls); /* skip FUNCTION */
+ next(ls); /* skip FUNCTION */
needself = funcname(ls, &v);
body(ls, needself, line);
luaK_storevar(ls, &v);
@@ -1000,7 +974,6 @@ static void namestat (LexState *ls) {
/* stat -> func | ['%'] NAME assignment */
FuncState *fs = ls->fs;
expdesc v;
- setline(ls);
var_or_func(ls, &v);
if (v.k == VEXP) { /* stat -> func */
check_condition(ls, luaK_lastisopen(fs), "syntax error"); /* an upvalue? */
@@ -1016,7 +989,7 @@ static void namestat (LexState *ls) {
static void retstat (LexState *ls) {
/* stat -> RETURN explist */
FuncState *fs = ls->fs;
- setline_and_next(ls); /* skip RETURN */
+ next(ls); /* skip RETURN */
if (!block_follow(ls->t.token))
explist1(ls); /* optional return values */
luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar);
@@ -1031,7 +1004,7 @@ static void breakstat (LexState *ls) {
Breaklabel *bl = fs->bl;
if (!bl)
luaK_error(ls, "no loop to break");
- setline_and_next(ls); /* skip BREAK */
+ next(ls); /* skip BREAK */
luaK_adjuststack(fs, currentlevel - bl->stacklevel);
luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
fs->stacklevel = currentlevel;
@@ -1050,9 +1023,9 @@ static int stat (LexState *ls) {
return 0;
}
case TK_DO: { /* stat -> DO block END */
- setline_and_next(ls); /* skip DO */
+ next(ls); /* skip DO */
block(ls);
- check_END(ls, TK_DO, line);
+ check_match(ls, TK_END, TK_DO, line);
return 0;
}
case TK_FOR: { /* stat -> forstat */
@@ -1113,13 +1086,14 @@ static void body (LexState *ls, int needself, int line) {
FuncState new_fs;
open_func(ls, &new_fs);
new_fs.f->lineDefined = line;
+ new_fs.debug = ls->L->debug;
check(ls, '(');
if (needself)
add_localvar(ls, "self");
parlist(ls);
check(ls, ')');
chunk(ls);
- check_END(ls, TK_FUNCTION, line);
+ check_match(ls, TK_END, TK_FUNCTION, line);
close_func(ls);
pushclosure(ls, &new_fs);
}
diff --git a/lparser.h b/lparser.h
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.h,v 1.16 2000/04/06 17:36:52 roberto Exp roberto $
+** $Id: lparser.h,v 1.17 2000/05/25 18:26:42 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -49,6 +49,7 @@ typedef struct FuncState {
int nupvalues; /* number of upvalues */
int nvars; /* number of entries in f->locvars */
int lastsetline; /* line where last SETLINE was issued */
+ int debug; /* flag to generate debug information */
struct Breaklabel *bl; /* chain of breakable blocks */
expdesc upvalues[MAXUPVALUES]; /* upvalues */
TString *localvar[MAXLOCALS]; /* store local variable names */