- for 语句的解析
for i = 1, 10 do
end
for i = 1, 10, 2 do
end
for a,b in ipairs({}) do
end
for a,b in pairs({}) do
end
- forstat解析
static void forstat(LexState *ls, int line)
{
varname = str_checkname(ls); // 第一个变量名
switch (ls->t.token)
{
case '=':
fornum(ls, varname, line);
break;
case ',':
case TK_IN:
forlist(ls, varname);
break;
}
check_match(ls, TK_END, TK_FOR, line);
leaveblock(fs); /* loop scope (`break' jumps to this point) */
}
- 当值是 fornum 的时候
static void fornum(LexState *ls, TString *varname, int line)
{
FuncState *fs = ls->fs;
int base = fs->freereg;
new_localvarliteral(ls, "(for index)", 0);
new_localvarliteral(ls, "(for limit)", 1);
new_localvarliteral(ls, "(for step)", 2);
new_localvar(ls, varname, 3);
checknext(ls, '=');
exp1(ls); /* initial value */
checknext(ls, ',');
exp1(ls); /* limit */
if (testnext(ls, ','))
exp1(ls); /* optional step */
else
{ /* default step = 1 */
gafqK_codeABx(fs, OP_LOADK, fs->freereg, gafqK_numberK(fs, 1));
gafqK_reserveregs(fs, 1);
}
forbody(ls, base, line, 1, 1);
}
- 解析新的local变量
- 注册一个新的local变量,会先检查local变量的数量,然后将变量放入proto的locvars中,然后返回 当前本地变量的数量
// 解析新的local变量
static void new_localvar(LexState *ls, TString *name, int n)
{
FuncState *fs = ls->fs;
gafqY_checklimit(fs, fs->nactvar + n + 1, GAFQI_MAXVARS, "local variables");
fs->actvar[fs->nactvar + n] = cast(unsigned short, registerlocalvar(ls, name));
}
static int registerlocalvar(LexState *ls, TString *varname)
{
FuncState *fs = ls->fs;
Proto *f = fs->f;
int oldsize = f->sizelocvars;
gafqM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, LocVar, SHRT_MAX, "too many local variables");
while (oldsize < f->sizelocvars)
f->locvars[oldsize++].varname = NULL;
f->locvars[fs->nlocvars].varname = varname;
gafqC_objbarrier(ls->L, f, varname);
return fs->nlocvars++;
}
- 解析表达式exp1
static int exp1(LexState *ls)
{
expdesc e;
int k;
expr(ls, &e);
k = e.k;
gafqK_exp2nextreg(ls->fs, &e);
return k;
}
void gafqK_exp2nextreg(FuncState *fs, expdesc *e)
{
gafqK_dischargevars(fs, e);
freeexp(fs, e);
gafqK_reserveregs(fs, 1);
exp2reg(fs, e, fs->freereg - 1);
}
// 把表达式放进寄存器中
static void exp2reg(FuncState *fs, expdesc *e, int reg)
{
discharge2reg(fs, e, reg);
e->f = e->t = NO_JUMP;
e->u.s.info = reg;
e->k = VNONRELOC;
}
// reg是要被使用的寄存器的位置
static void discharge2reg(FuncState *fs, expdesc *e, int reg)
{
gafqK_dischargevars(fs, e);
switch (e->k)
{
case VKNUM:
{
gafqK_codeABx(fs, OP_LOADK, reg, gafqK_numberK(fs, e->u.nval)); // 这里生成一个操作指令, 把值存到常量k里面去
break;
}
}
e->u.s.info = reg;
e->k = VNONRELOC;
}
- 解析循环的body
// isnum 是否是数字类型的循环 for i = 1, 10 do
static void forbody(LexState *ls, int base, int line, int nvars, int isnum)
{
checknext(ls, TK_DO);
prep = isnum ? gafqK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : gafqK_jump(fs);
enterblock(fs, &bl, 0);
adjustlocalvars(ls, nvars);
gafqK_reserveregs(fs, nvars);
block(ls);
leaveblock(fs); /* end of scope for declared variables */
gafqK_patchtohere(fs, prep);
endfor = (isnum) ? gafqK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : gafqK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
gafqK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
gafqK_patchlist(fs, (isnum ? endfor : gafqK_jump(fs)), prep + 1);
}