Example #1
0
static void repeatstat(LexState* ls, int line)
{
	/* repeatstat -> REPEAT block UNTIL cond */
	int condexit;
	FuncState* fs = ls->fs;
	int repeat_init = luaK_getlabel(fs);
	BlockCnt bl1, bl2;
	enterblock(fs, &bl1, 1);  /* loop block */
	enterblock(fs, &bl2, 0);  /* scope block */
	luaX_next(ls);	/* skip REPEAT */
	chunk(ls);
	luaK_patchtohere(fs, bl1.continuelist);
	check_match(ls, TK_UNTIL, TK_REPEAT, line);
	condexit = cond(ls);	/* read condition (inside scope block) */
	if (!bl2.upval)	   /* no upvalues? */
	{
		leaveblock(fs);	 /* finish scope */
		luaK_patchlist(ls->fs, condexit, repeat_init);	/* close the loop */
	}
	else	/* complete semantics when there are upvalues */
	{
		breakstat(ls);	/* if condition then break */
		luaK_patchtohere(ls->fs, condexit);	 /* else... */
		leaveblock(fs);	 /* finish scope... */
		luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init);	 /* and repeat */
	}
	leaveblock(fs);	 /* finish loop */
}
Example #2
0
static void selectstat (LexState *ls, int line) {
  /* selectstat -> CASE val1 OF val2 THEN block [OF valx THEN block [ELSE THEN block]] ESAC */
  FuncState *fs = ls->fs;
  BlockCnt bl;
  int escapelist = NO_JUMP;
  expdesc v;
  luaX_next(ls);  /* skip `case' */
  enterblock(fs, &bl, 0);  /* block to control variable scope */
  expr(ls, &v);
  checknext(ls, TK_OF);
  casestat(ls, &v);
  while (ls->t.token == TK_OF) {
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    luaK_patchtohere(fs, v.f);
    luaX_next(ls);  /* skip OF */
    casestat(ls, &v);  /* OF val THEN block */
  }
  if (ls->t.token == TK_ELSE) {
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    luaK_patchtohere(fs, v.f);
    luaX_next(ls);  /* skip ELSE */
    block(ls);  /* default part */
  } else {
    luaK_concat(fs, &escapelist, v.f);
  }
  luaK_patchtohere(fs, escapelist);
  check_match(ls, TK_ESAC, TK_CASE, line);
  leaveblock(fs);
}
Example #3
0
static void forstat (LexState *ls, int line)
{
    /* forstat -> FOR (fornum | forlist) END */
    FuncState *fs = GetCurrentFuncState( ls );
    TString *varname;
    BlockCnt bl;

    enterblock(fs, &bl, 1);  /* scope for loop and control variables */

    luaX_next(ls);  /* skip `for' */

    varname = str_checkname(ls);  /* first variable name */

    switch (ls->t.token)
    {
    case '=':
        fornum(ls, varname, line);
        break;
    case ',': case TK_IN:
        forlist(ls, varname);
        break;
    default:
        luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
        break;
    }

    check_match(ls, TK_END, TK_FOR, line);

    leaveblock(fs);  /* loop scope (`break' jumps to this point) */
}
Example #4
0
static void forbody (LexState *ls, int base, int line, int nvars, int isnum)
{
    /* forbody -> DO block */
    BlockCnt bl;
    FuncState *fs = GetCurrentFuncState( ls );

    adjustlocalvars(ls, 3);  /* control variables */

    checknext(ls, TK_DO);

    int prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);

    enterblock(fs, &bl, 0);  /* scope for declared variables */

    adjustlocalvars(ls, nvars);
    luaK_reserveregs(fs, nvars);
    block(ls);

    leaveblock(fs);  /* end of scope for declared variables */

    luaK_patchtohere(fs, prep);

    int endfor = (isnum) ?
        luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);

    luaK_fixline(fs, line);  /* pretend that `OP_FOR' starts the loop */

    luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
}
Example #5
0
static void block (LexState *ls) {
  /* block -> chunk */
  FuncState *fs = ls->fs;
  BlockCnt bl;
  enterblock(fs, &bl, 0);
  chunk(ls);
  lua_assert(bl.breaklist == NO_JUMP);
  leaveblock(fs);
}
Example #6
0
static void block (LexState *ls) {
  /* block -> chunk */
  FuncState *fs = ls->fs;
  BlockCnt *pbl = (BlockCnt*)luaM_malloc(ls->L,sizeof(BlockCnt));
  enterblock(fs, pbl, 0);
  chunk(ls);
  lua_assert(pbl->breaklist == NO_JUMP);
  leaveblock(fs);
  luaM_free(ls->L,pbl);
}
Example #7
0
static void repeatstat (LexState *ls, int line) {
  /* repeatstat -> REPEAT block UNTIL cond */
  int condexit;
  FuncState *fs = ls->fs;
  int repeat_init = luaK_getlabel(fs);
  BlockCnt bl1, bl2;
  enterblock(fs, &bl1, 1);  /* loop block */
  enterblock(fs, &bl2, 0);  /* scope block */
  luaX_next(ls);  /* skip REPEAT */
  chunk(ls);
  check_match(ls, TK_UNTIL, TK_REPEAT, line);
#if LUA_EXT_CONTINUE
  if (bl2.continuelist != NO_JUMP) {
    int oldprohibition = fs->prohibitedloc;
    luaK_patchtohere(fs, bl2.continuelist);
    fs->prohibitedloc = bl2.continuepos;
    condexit = cond(ls);  /* read condition (inside scope block) */
    fs->prohibitedloc = oldprohibition;
    bl2.continuelist = NO_JUMP;
  }
  else {
    condexit = cond(ls);  /* read condition (inside scope block) */
  }
#else
  condexit = cond(ls);  /* read condition (inside scope block) */
#endif /* LUA_EXT_CONTINUE */
  if (!bl2.upval) {  /* no upvalues? */
    leaveblock(fs);  /* finish scope */
    luaK_patchlist(ls->fs, condexit, repeat_init);  /* close the loop */
  }
  else {  /* complete semantics when there are upvalues */
    breakstat(ls);  /* if condition then break */
    luaK_patchtohere(ls->fs, condexit);  /* else... */
    leaveblock(fs);  /* finish scope... */
    luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init);  /* and repeat */
  }
  leaveblock(fs);  /* finish loop */
}
Example #8
0
static void repeatstat (LexState *ls, int line) {
  /* repeatstat -> REPEAT block UNTIL cond */
  FuncState *fs = ls->fs;
  int repeat_init = luaK_getlabel(fs);
  expdesc v;
  BlockCnt bl;
  enterblock(fs, &bl, 1);
  next(ls);
  block(ls);
  check_match(ls, TK_UNTIL, TK_REPEAT, line);
  cond(ls, &v);
  luaK_patchlist(fs, v.f, repeat_init);
  leaveblock(fs);
}
Example #9
0
static void forstat (LexState *ls, int line) {
  /* forstat -> fornum | forlist */
  FuncState *fs = ls->fs;
  TString *varname;
  BlockCnt bl;
  enterblock(fs, &bl, 0);  /* block to control variable scope */
  next(ls);  /* skip `for' */
  varname = str_checkname(ls);  /* first variable name */
  switch (ls->t.token) {
    case '=': fornum(ls, varname, line); break;
    case ',': case TK_IN: forlist(ls, varname); break;
    default: luaX_syntaxerror(ls, "`=' or `in' expected");
  }
  check_match(ls, TK_END, TK_FOR, line);
  leaveblock(fs);
}
Example #10
0
static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
  BlockCnt bl;
  FuncState *fs = ls->fs;
  int prep, endfor;
  adjustlocalvars(ls, nvars);  /* scope for all variables */
  check(ls, TK_DO);
  enterblock(fs, &bl, 1);  /* loop block */
  prep = luaK_getlabel(fs);
  block(ls);
  luaK_patchtohere(fs, prep-1);
  endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
                     luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3);
  luaK_fixline(fs, line);  /* pretend that `OP_FOR' starts the loop */
  luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep);
  leaveblock(fs);
}
Example #11
0
static void whilestat (LexState *ls, int line) {
  /* whilestat -> WHILE cond DO block END */
  FuncState *fs = ls->fs;
  int whileinit;
  int condexit;
  BlockCnt bl;
  luaX_next(ls);  /* skip WHILE */
  whileinit = luaK_getlabel(fs);
  condexit = cond(ls);
  enterblock(fs, &bl, 1);
  checknext(ls, TK_DO);
  block(ls);
  luaK_patchlist(fs, luaK_jump(fs), whileinit);
  check_match(ls, TK_END, TK_WHILE, line);
  leaveblock(fs);
  luaK_patchtohere(fs, condexit);  /* false conditions finish the loop */
}
Example #12
0
static void whilestat (LexState *ls, int line) {
  /* whilestat -> WHILE cond DO block END */
  Instruction codeexp[MAXEXPWHILE + EXTRAEXP];
  int lineexp;
  int i;
  int sizeexp;
  FuncState *fs = ls->fs;
  int whileinit, blockinit, expinit;
  expdesc v;
  BlockCnt bl;
  next(ls);  /* skip WHILE */
  whileinit = luaK_jump(fs);  /* jump to condition (which will be moved) */
  expinit = luaK_getlabel(fs);
  expr(ls, &v);  /* parse condition */
  if (v.k == VK) v.k = VTRUE;  /* `trues' are all equal here */
  lineexp = ls->linenumber;
  luaK_goiffalse(fs, &v);
  luaK_concat(fs, &v.f, fs->jpc);
  fs->jpc = NO_JUMP;
  sizeexp = fs->pc - expinit;  /* size of expression code */
  if (sizeexp > MAXEXPWHILE) 
    luaX_syntaxerror(ls, "`while' condition too complex");
  for (i = 0; i < sizeexp; i++)  /* save `exp' code */
    codeexp[i] = fs->f->code[expinit + i];
  fs->pc = expinit;  /* remove `exp' code */
  enterblock(fs, &bl, 1);
  check(ls, TK_DO);
  blockinit = luaK_getlabel(fs);
  block(ls);
  luaK_patchtohere(fs, whileinit);  /* initial jump jumps to here */
  luaK_patchtohere(fs, bl.continuelist);
  /* move `exp' back to code */
  if (v.t != NO_JUMP) v.t += fs->pc - expinit;
  if (v.f != NO_JUMP) v.f += fs->pc - expinit;
  for (i=0; i<sizeexp; i++)
    luaK_code(fs, codeexp[i], lineexp);
  check_match(ls, TK_END, TK_WHILE, line);
  leaveblock(fs);
  luaK_patchlist(fs, v.t, blockinit);  /* true conditions go back to loop */
  luaK_patchtohere(fs, v.f);  /* false conditions finish the loop */
}
Example #13
0
static void trystat (LexState *ls, int line) {
  /* trystat -> TRY block CATCH err DO block END */
  FuncState *fs = ls->fs;
  BlockCnt bl;
  int base, pc, escapelist = NO_JUMP;

  luaX_next(ls);

  enterblock(fs, &bl, 2);   /* try block */
  base = fs->freereg;
  new_localvarliteral(ls, "(error obj)", 0);
  adjustlocalvars(ls, 1);  /* error object */
  luaK_reserveregs(fs, 1);

  pc = luaK_codeAsBx(fs, OP_TRY, base, NO_JUMP);
  chunk(ls);

  if (ls->t.token == TK_CATCH) {
    TString *varname;
    int errobj;

    luaK_codeABC(fs, OP_EXITTRY, 0, 0, 0);
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    SET_OPCODE(fs->f->code[pc], OP_TRYCATCH);   /* change it to TRYCATCH */
    luaK_patchtohere(fs, pc);
    bl.isbreakable = 0;

    // local err
    luaX_next(ls);  /* skip `catch' */
    varname = str_checkname(ls);  /* first variable name */

    // do
    checknext(ls, TK_DO);
    errobj = fs->freereg;
    new_localvar(ls, varname, 0);
    adjustlocalvars(ls, 1);
    luaK_reserveregs(fs, 1);
    luaK_codeABC(fs, OP_MOVE, errobj, base, 0);

    block(ls);

  } else if (ls->t.token == TK_FINALLY) {
    luaK_codeABC(fs, OP_EXITTRY, 0, 0, 0);
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    SET_OPCODE(fs->f->code[pc], OP_TRYFIN);   /* change it to TRYFIN */
    luaK_patchtohere(fs, pc);
    bl.isbreakable = 3;

    luaX_next(ls);  /* skip 'finally' */

    block(ls);

    luaK_codeABC(fs, OP_RETFIN, base, 0, 0);  /* OP_ENDFIN jump to the return point */

  } else {
    luaK_codeABC(fs, OP_EXITTRY, 0, 0, 0);
    luaK_concat(fs, &escapelist, pc);
  }

  leaveblock(fs);

  luaK_patchtohere(fs, escapelist);
  check_match(ls, TK_END, TK_TRY, line);
}