Browse Source

no more `global' declarations

v5-2
Roberto Ierusalimschy 23 years ago
parent
commit
1c328a191a
  1. 6
      lcode.c
  2. 7
      ldebug.c
  3. 180
      lparser.c
  4. 21
      lparser.h

6
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;
}

7
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;

180
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 */
}
}

21
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;

Loading…
Cancel
Save