commit 1c328a191a8b86b7ad601cb9a935f1da5373fdf7
parent 58bf77bc7f37d697c5bfc33be169c6b841dd8a1d
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 14 May 2002 14:52:00 -0300
no more `global' declarations
Diffstat:
M | lcode.c | | | 6 | +++--- |
M | ldebug.c | | | 7 | +------ |
M | lparser.c | | | 180 | ++++++++++++++++++++----------------------------------------------------------- |
M | lparser.h | | | 21 | +++++---------------- |
4 files changed, 53 insertions(+), 161 deletions(-)
diff --git a/lcode.c b/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 1.102 2002/05/10 19:22:11 roberto Exp roberto $
+** $Id: lcode.c,v 1.103 2002/05/13 13:07:48 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -191,7 +191,7 @@ void luaK_reserveregs (FuncState *fs, int n) {
static void freereg (FuncState *fs, int reg) {
- if (reg >= fs->nactloc && reg < MAXSTACK) {
+ if (reg >= fs->nactvar && reg < MAXSTACK) {
fs->freereg--;
lua_assert(reg == fs->freereg);
}
@@ -375,7 +375,7 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
if (e->k == VNONRELOC) {
if (!hasjumps(e)) return e->info; /* exp is already in a register */
- if (e->info >= fs->nactloc) { /* reg. is not a local? */
+ if (e->info >= fs->nactvar) { /* reg. is not a local? */
luaK_exp2reg(fs, e, e->info); /* put value on it */
return e->info;
}
diff --git a/ldebug.c b/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 1.113 2002/05/09 14:14:34 roberto Exp roberto $
+** $Id: ldebug.c,v 1.114 2002/05/13 13:09:00 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -432,11 +432,6 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
break;
}
case OP_GETTABLE: {
- *name = luaF_getlocalname(p, GETARG_B(i)+1, pc);
- if (*name && *name[0] == '*') {
- *name = kname(p, GETARG_C(i));
- return "global";
- }
*name = kname(p, GETARG_C(i));
return "field";
break;
diff --git a/lparser.c b/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 1.181 2002/05/10 19:22:11 roberto Exp roberto $
+** $Id: lparser.c,v 1.182 2002/05/13 13:09:00 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -23,15 +23,18 @@
+
+#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
+
+
+
/*
** nodes for block list (list of active blocks)
*/
typedef struct BlockCnt {
struct BlockCnt *previous; /* chain */
int breaklist; /* list of jumps out of this loop */
- int nactloc; /* # active local variables outside the breakable structure */
- int nactvar;
- int defaultglob;
+ int nactvar; /* # active local variables outside the breakable structure */
int upval; /* true if some variable in the block is an upvalue */
int isbreakable; /* true if `block' is a loop */
} BlockCnt;
@@ -138,51 +141,26 @@ static int luaI_registerlocalvar (LexState *ls, TString *varname) {
}
-static vardesc *new_var (LexState *ls, int n) {
- FuncState *fs = ls->fs;
- luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "variables");
- return &fs->actvar[fs->nactvar+n];
-}
-
-
static void new_localvar (LexState *ls, TString *name, int n) {
- vardesc *v = new_var(ls, n);
- v->k = VLOCAL;
- v->i = luaI_registerlocalvar(ls, name);
- v->level = ls->fs->nactloc + n;
-}
-
-
-static void adjustlocalvars (LexState *ls, int nvars) {
FuncState *fs = ls->fs;
- while (nvars--) {
- lua_assert(fs->actvar[fs->nactvar].k == VLOCAL);
- fs->f->locvars[fs->actvar[fs->nactvar].i].startpc = fs->pc;
- fs->nactvar++;
- fs->nactloc++;
- }
+ luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "local variables");
+ fs->actvar[fs->nactvar+n] = luaI_registerlocalvar(ls, name);
}
-static void adjustglobalvars (LexState *ls, int nvars, int level) {
+static void adjustlocalvars (LexState *ls, int nvars) {
FuncState *fs = ls->fs;
- while (nvars--) {
- fs->actvar[fs->nactvar].k = VGLOBAL;
- fs->actvar[fs->nactvar].level = level;
- fs->nactvar++;
+ fs->nactvar += nvars;
+ for (; nvars; nvars--) {
+ getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
}
}
static void removevars (LexState *ls, int tolevel) {
FuncState *fs = ls->fs;
- while (fs->nactvar > tolevel) {
- fs->nactvar--;
- if (fs->actvar[fs->nactvar].k == VLOCAL) {
- fs->nactloc--;
- fs->f->locvars[fs->actvar[fs->nactvar].i].endpc = fs->pc;
- }
- }
+ while (fs->nactvar > tolevel)
+ getlocvar(fs, --fs->nactvar).endpc = fs->pc;
}
@@ -210,80 +188,48 @@ static int indexupvalue (FuncState *fs, expdesc *v) {
}
-static vardesc *searchvar (FuncState *fs, TString *n) {
+static int searchvar (FuncState *fs, TString *n) {
int i;
for (i=fs->nactvar-1; i >= 0; i--) {
- vardesc *v = &fs->actvar[i];
- if (v->k == VLOCAL ? n == fs->f->locvars[v->i].varname
- : n == tsvalue(&fs->f->k[v->i]))
- return v;
+ if (n == getlocvar(fs, i).varname)
+ return i;
}
- return NULL; /* not found */
+ return -1; /* not found */
}
static void markupval (FuncState *fs, int level) {
BlockCnt *bl = fs->bl;
- while (bl && bl->nactloc > level) bl = bl->previous;
+ while (bl && bl->nactvar > level) bl = bl->previous;
if (bl) bl->upval = 1;
}
-static int singlevar_aux (FuncState *fs, TString *n, expdesc *var, int nd) {
- if (fs == NULL) { /* no more levels? */
- init_exp(var, VGLOBAL, NO_REG); /* default is free global */
- return VNIL; /* not found */
- }
+static void singlevar (FuncState *fs, TString *n, expdesc *var, int base) {
+ if (fs == NULL) /* no more levels? */
+ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
else {
- vardesc *v = searchvar(fs, n); /* look up at current level */
- if (v) {
- if (v->level == NO_REG) { /* free global? */
- lua_assert(v->k == VGLOBAL);
- init_exp(var, VGLOBAL, NO_REG);
- }
- else
- init_exp(var, VLOCAL, v->level);
- return v->k;
+ int v = searchvar(fs, n); /* look up at current level */
+ if (v >= 0) {
+ init_exp(var, VLOCAL, v);
+ if (!base)
+ markupval(fs, v); /* local will be used as an upval */
}
else { /* not found at current level; try upper one */
- int k = singlevar_aux(fs->prev, n, var, nd && fs->defaultglob == NO_REG);
+ singlevar(fs->prev, n, var, 0);
if (var->k == VGLOBAL) {
- if (k == VNIL && nd && fs->defaultglob != NO_REG) {
- if (fs->defaultglob == NO_REG1)
- luaX_syntaxerror(fs->ls, "undeclared global");
- init_exp(var, VLOCAL, fs->defaultglob);
- k = VGLOBAL; /* now there is a declaration */
- }
+ if (base)
+ var->info = luaK_stringK(fs, n); /* info points to global name */
}
else { /* LOCAL or UPVAL */
- if (var->k == VLOCAL)
- markupval(fs->prev, var->info); /* local will be used as an upval */
var->info = indexupvalue(fs, var);
var->k = VUPVAL; /* upvalue in this level */
}
- return k;
}
}
}
-static void singlevar (FuncState *fs, TString *n, expdesc *var) {
- int k = singlevar_aux(fs, n, var, 1);
- if (k == VNIL || k == VGLOBAL) { /* global? */
- if (var->k == VGLOBAL) /* free global? */
- var->info = luaK_stringK(fs, n);
- else { /* `indexed' global */
- expdesc e;
- codestring(fs->ls, &e, n);
- luaK_exp2anyreg(fs, var);
- var->aux = luaK_exp2RK(fs, &e);
- var->k = VINDEXED;
- }
- }
-}
-
-
-
static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
FuncState *fs = ls->fs;
int extra = nvars - nexps;
@@ -308,24 +254,22 @@ static void code_params (LexState *ls, int nparams, int dots) {
FuncState *fs = ls->fs;
adjustlocalvars(ls, nparams);
luaX_checklimit(ls, fs->nactvar, MAXPARAMS, "parameters");
- fs->f->numparams = cast(lu_byte, fs->nactloc);
+ fs->f->numparams = cast(lu_byte, fs->nactvar);
fs->f->is_vararg = cast(lu_byte, dots);
if (dots)
create_local(ls, "arg");
- luaK_reserveregs(fs, fs->nactloc); /* reserve register for parameters */
+ luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
}
static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) {
bl->breaklist = NO_JUMP;
bl->isbreakable = isbreakable;
- bl->nactloc = fs->nactloc;
bl->nactvar = fs->nactvar;
- bl->defaultglob = fs->defaultglob;
bl->upval = 0;
bl->previous = fs->bl;
fs->bl = bl;
- lua_assert(fs->freereg == fs->nactloc);
+ lua_assert(fs->freereg == fs->nactvar);
}
@@ -334,11 +278,9 @@ static void leaveblock (FuncState *fs) {
fs->bl = bl->previous;
removevars(fs->ls, bl->nactvar);
if (bl->upval)
- luaK_codeABC(fs, OP_CLOSE, bl->nactloc, 0, 0);
- lua_assert(bl->nactloc == fs->nactloc);
+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
lua_assert(bl->nactvar == fs->nactvar);
- fs->freereg = fs->nactloc; /* free registers */
- fs->defaultglob = bl->defaultglob;
+ fs->freereg = fs->nactvar; /* free registers */
luaK_patchtohere(fs, bl->breaklist);
}
@@ -373,9 +315,7 @@ static void open_func (LexState *ls, FuncState *fs) {
fs->h = luaH_new(ls->L, 0, 0);
fs->np = 0;
fs->nlocvars = 0;
- fs->nactloc = 0;
fs->nactvar = 0;
- fs->defaultglob = NO_REG; /* default is free globals */
fs->bl = NULL;
f->code = NULL;
f->source = ls->source;
@@ -658,13 +598,13 @@ static void prefixexp (LexState *ls, expdesc *v) {
return;
}
case TK_NAME: {
- singlevar(ls->fs, str_checkname(ls), v);
+ singlevar(ls->fs, str_checkname(ls), v, 1);
next(ls);
return;
}
case '%': { /* for compatibility only */
next(ls); /* skip `%' */
- singlevar(ls->fs, str_checkname(ls), v);
+ singlevar(ls->fs, str_checkname(ls), v, 1);
check_condition(ls, v->k == VUPVAL, "global upvalues are obsolete");
next(ls);
return;
@@ -1173,38 +1113,10 @@ static void localstat (LexState *ls) {
}
-static void globalstat (LexState *ls) {
- /* stat -> GLOBAL NAME {`,' NAME} [IN exp] | GLOBAL IN exp */
- FuncState *fs = ls->fs;
- int nvars = 0;
- next(ls); /* skip GLOBAL */
- if (ls->t.token == TK_NAME) {
- do {
- vardesc *v = new_var(ls, nvars++);
- v->i = luaK_stringK(ls->fs, str_checkname(ls));
- next(ls); /* skip name */
- } while (optional(ls, ','));
- }
- if (!optional(ls, TK_IN)) { /* free globals? */
- if (nvars == 0) /* default - free is invalid */
- error_expected(ls, TK_IN);
- adjustglobalvars(ls, nvars, NO_REG); /* mark globals as free */
- }
- else {
- int baselocal = fs->freereg;
- int k = exp1(ls);
- if (nvars == 0)
- fs->defaultglob = (k == VNIL) ? NO_REG1 : baselocal;
- adjustglobalvars(ls, nvars, baselocal);
- create_local(ls, "*");
- }
-}
-
-
static int funcname (LexState *ls, expdesc *v) {
/* funcname -> NAME {field} [`:' NAME] */
int needself = 0;
- singlevar(ls->fs, str_checkname(ls), v);
+ singlevar(ls->fs, str_checkname(ls), v, 1);
next(ls); /* skip var name */
while (ls->t.token == '.') {
luaY_field(ls, v);
@@ -1259,7 +1171,7 @@ static void retstat (LexState *ls) {
return;
}
luaK_setcallreturns(fs, &e, LUA_MULTRET);
- first = fs->nactloc;
+ first = fs->nactvar;
nret = LUA_MULTRET; /* return all values */
}
else {
@@ -1267,7 +1179,7 @@ static void retstat (LexState *ls) {
first = luaK_exp2anyreg(fs, &e);
else {
luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
- first = fs->nactloc; /* return all `active' values */
+ first = fs->nactvar; /* return all `active' values */
lua_assert(nret == fs->freereg - first);
}
}
@@ -1289,7 +1201,7 @@ static void breakstat (LexState *ls) {
if (!bl)
luaX_syntaxerror(ls, "no loop to break");
if (upval)
- luaK_codeABC(fs, OP_CLOSE, bl->nactloc, 0, 0);
+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
}
@@ -1327,10 +1239,6 @@ static int statement (LexState *ls) {
localstat(ls);
return 0;
}
- case TK_GLOBAL: { /* stat -> globalstat */
- globalstat(ls);
- return 0;
- }
case TK_RETURN: { /* stat -> retstat */
retstat(ls);
return 1; /* must be last statement */
@@ -1391,8 +1299,8 @@ static void chunk (LexState *ls) {
while (!islast && !block_follow(ls->t.token)) {
islast = statement(ls);
optional(ls, ';');
- lua_assert(ls->fs->freereg >= ls->fs->nactloc);
- ls->fs->freereg = ls->fs->nactloc; /* free registers */
+ lua_assert(ls->fs->freereg >= ls->fs->nactvar);
+ ls->fs->freereg = ls->fs->nactvar; /* free registers */
}
}
diff --git a/lparser.h b/lparser.h
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.h,v 1.42 2002/05/09 18:00:38 roberto Exp roberto $
+** $Id: lparser.h,v 1.43 2002/05/10 19:22:11 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -41,18 +41,9 @@ typedef struct expdesc {
} expdesc;
-/* describe declared variables */
-typedef struct vardesc {
- int i; /* if local, its index in `locvars';
- if global, its name index in `k' */
- lu_byte k;
- lu_byte level; /* if local, stack level;
- if global, corresponding local (NO_REG for free globals) */
-} vardesc;
-
-
struct BlockCnt; /* defined in lparser.c */
+
/* state needed to generate code for a given function */
typedef struct FuncState {
Proto *f; /* current function header */
@@ -63,16 +54,14 @@ typedef struct FuncState {
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to `ncode') */
int lasttarget; /* `pc' of last `jump target' */
- int jpc; /* list of jumps to `pc' */
+ int jpc; /* list of pending jumps to `pc' */
int freereg; /* first free register */
- int defaultglob; /* where to look for non-declared globals */
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
int nlocvars; /* number of elements in `locvars' */
- int nactloc; /* number of active local variables */
- int nactvar; /* number of elements in array `actvar' */
+ int nactvar; /* number of active local variables */
expdesc upvalues[MAXUPVALUES]; /* upvalues */
- vardesc actvar[MAXVARS]; /* declared-variable stack */
+ int actvar[MAXVARS]; /* declared-variable stack */
} FuncState;