Пример #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 */
}
Пример #2
0
static int statement (LexState *ls) {
  int line = ls->linenumber;  /* may be needed for error messages */
  switch (ls->t.token) {
    case TK_IF: {  /* stat -> ifstat */
      ifstat(ls, line);
      return 0;
    }
    case TK_WHILE: {  /* stat -> whilestat */
      whilestat(ls, line);
      return 0;
    }
    case TK_DO: {  /* stat -> DO block END */
      luaX_next(ls);  /* skip DO */
      block(ls);
      check_match(ls, TK_END, TK_DO, line);
      return 0;
    }
    case TK_FOR: {  /* stat -> forstat */
      forstat(ls, line);
      return 0;
    }
    case TK_REPEAT: {  /* stat -> repeatstat */
      repeatstat(ls, line);
      return 0;
    }
    case TK_FUNCTION: {
      funcstat(ls, line);  /* stat -> funcstat */
      return 0;
    }
    case TK_LOCAL: {  /* stat -> localstat */
      luaX_next(ls);  /* skip LOCAL */
      if (testnext(ls, TK_FUNCTION))  /* local function? */
        localfunc(ls);
      else
        localstat(ls);
      return 0;
    }
    case TK_RETURN: {  /* stat -> retstat */
      retstat(ls);
      return 1;  /* must be last statement */
    }
    case TK_BREAK: {  /* stat -> breakstat */
      luaX_next(ls);  /* skip BREAK */
      breakstat(ls);
      return 1;  /* must be last statement */
    }
#if LUA_EXT_CONTINUE
    case TK_CONTINUE: {  /* stat -> continuestat */
      luaX_next(ls);  /* skip CONTINUE */
      continuestat(ls);
      return 1;  /* must be last statement */
    }
#endif /* LUA_EXT_CONTINUE */
    default: {
      exprstat(ls);
      return 0;  /* to avoid warnings */
    }
  }
}
Пример #3
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 */
}
Пример #4
0
static int statement (LexState *ls) {
  int line = ls->linenumber;  /* may be needed for error messages */
  switch (ls->t.token) {
    case TK_IF: {  /* stat -> ifstat */
      ifstat(ls, line);
      return 0;
    }
    case TK_WHILE: {  /* stat -> whilestat */
      whilestat(ls, line);
      return 0;
    }
    case TK_DO: {  /* stat -> DO block END */
      luaX_next(ls);  /* skip DO */
      block(ls);
      check_match(ls, TK_END, TK_DO, line);
      return 0;
    }
    case TK_FOR: {  /* stat -> forstat */
      forstat(ls, line);
      return 0;
    }
    case TK_REPEAT: {  /* stat -> repeatstat */
      repeatstat(ls, line);
      return 0;
    }
    case TK_FUNCTION: {
      funcstat(ls, line);  /* stat -> funcstat */
      return 0;
    }
    case TK_LOCAL: {  /* stat -> localstat */
      luaX_next(ls);  /* skip LOCAL */
      if (testnext(ls, TK_FUNCTION))  /* local function? */
        localfunc(ls);
      else
        localstat(ls);
      return 0;
    }
    case TK_RETURN: {  /* stat -> retstat */
      retstat(ls);
      return 1;  /* must be last statement */
    }
    case TK_BREAK: {  /* stat -> breakstat */
      luaX_next(ls);  /* skip BREAK */
      if (testnext(ls, TK_NUMBER)) { /* multi scope 'break n' */
        breakstat(ls, ls->t.seminfo.r);
      } else breakstat(ls, 1);
      return 1;  /* must be last statement */
    }
    case TK_CONTINUE: {  /* stat -> continuestat */
      luaX_next(ls);  /* skip CONTINUE */
      continuestat(ls);
      return 1;	  /* must be last statement */
    }
    case TK_INC: {  /* added 0.5.2.*/
      luaX_next(ls);
      changevalue(ls, OP_ADD);
      return 0;
    }
    case TK_DEC: {  /* added 0.5.2.*/
      luaX_next(ls);
      changevalue(ls, OP_SUB);
      return 0;
    }
    case TK_CASE: {  /* added 0.5.2.*/
      selectstat(ls, line);
      return 0;
    }
    default: {
      exprstat(ls);
      return 0;  /* to avoid warnings */
    }
  }
}