Example #1
0
static void funcargs (LexState *ls, expdesc *f) {
  FuncState *fs = ls->fs;
  expdesc args;
  int base, nparams;
  int line = ls->linenumber;
  switch (ls->t.token) {
    case '(': {  /* funcargs -> `(' [ explist1 ] `)' */
      if (line != ls->lastline)
        luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
      luaX_next(ls);
      if (ls->t.token == ')')  /* arg list is empty? */
        args.k = VVOID;
      else {
        explist1(ls, &args);
        luaK_setmultret(fs, &args);
      }
      check_match(ls, ')', '(', line);
      break;
    }
    case '{': {  /* funcargs -> constructor */
      constructor(ls, &args);
      break;
    }
    case TK_STRING: {  /* funcargs -> STRING */
      codestring(ls, &args, ls->t.seminfo.ts);
      luaX_next(ls);  /* must use `seminfo' before `next' */
      break;
    }
    default: {
      luaX_syntaxerror(ls, "function arguments expected");
      return;
    }
  }
  lua_assert(f->k == VNONRELOC);
  base = f->u.s.info;  /* base register for call */
  if (hasmultret(args.k))
    nparams = LUA_MULTRET;  /* open call */
  else {
    if (args.k != VVOID)
      luaK_exp2nextreg(fs, &args);  /* close last argument */
    nparams = fs->freereg - (base+1);
  }
  init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
  luaK_fixline(fs, line);
  fs->freereg = base+1;  /* call remove function and arguments and leaves
                            (unless changed) one result */
}
Example #2
0
static TString* str_checkname(LexState* ls)
{
	TString* ts;
	check(ls, TK_NAME);
	ts = ls->t.seminfo.ts;
	luaX_next(ls);
	return ts;
}
Example #3
0
static void yindex(LexState* ls, expdesc* v)
{
	/* index -> '[' expr ']' */
	luaX_next(ls);	/* skip the '[' */
	expr(ls, v);
	luaK_exp2val(ls->fs, v);
	checknext(ls, ']');
}
Example #4
0
static int testnext(LexState* ls, int c)
{
	if (ls->t.token == c)
	{
		luaX_next(ls);
		return 1;
	}
	else return 0;
}
Example #5
0
static void field (LexState *ls, expdesc *v) {
  /* field -> ['.' | ':'] NAME */
  FuncState *fs = ls->fs;
  expdesc key;
  luaK_exp2anyreg(fs, v);
  luaX_next(ls);  /* skip the dot or colon */
  checkname(ls, &key);
  luaK_indexed(fs, v, &key);
}
Example #6
0
static int test_then_block (LexState *ls) {
  /* test_then_block -> [IF | ELSEIF] cond THEN block */
  int condexit;
  luaX_next(ls);  /* skip IF or ELSEIF */
  condexit = cond(ls);
  checknext(ls, TK_THEN);
  block(ls);  /* `then' part */
  return condexit;
}
Example #7
0
static void funcstat (LexState *ls, int line) {
  /* funcstat -> FUNCTION funcname body */
  int needself;
  expdesc v, b;
  luaX_next(ls);  /* skip FUNCTION */
  needself = funcname(ls, &v);
  body(ls, &b, needself, line);
  luaK_storevar(ls->fs, &v, &b);
  luaK_fixline(ls->fs, line);  /* definition `happens' in the first line */
}
Example #8
0
static void retstat (LexState *ls)
{
    /* stat -> RETURN explist */
    FuncState *fs = GetCurrentFuncState( ls );
    expdesc e;
    int first, nret;  /* registers with returned values */

    luaX_next(ls);  /* skip RETURN */

    if (block_follow(ls->t.token) || ls->t.token == ';')
    {
        first = nret = 0;  /* return no values */
    }
    else
    {
        nret = explist1(ls, &e);  /* optional return values */

        if (hasmultret(e.k))
        {
            luaK_setmultret(fs, &e);

            if (e.k == VCALL && nret == 1)
            {  /* tail call? */
                SET_OPCODE(getcode(fs,&e), OP_TAILCALL);

                lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
            }

            first = fs->nactvar;

            nret = LUA_MULTRET;  /* return all values */
        }
        else
        {
            if (nret == 1)  /* only one single value? */
            {
                first = luaK_exp2anyreg(fs, &e);
            }
            else
            {
                luaK_exp2nextreg(fs, &e);  /* values must go to the `stack' */
                first = fs->nactvar;  /* return all `active' values */

                lua_assert(nret == fs->freereg - first);
            }
        }
    }

    luaK_ret(fs, first, nret);
}
Example #9
0
Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name)
{
    struct LexState lexstate;
    struct FuncState funcstate;
    lexstate.buff = buff;

    TString *inputNameString = luaS_new(L, name);

    try
    {
        luaX_setinput(L, &lexstate, z, inputNameString );

        open_func(&lexstate, &funcstate);
        try
        {
            funcstate.f->is_vararg = VARARG_ISVARARG;  /* main func. is always vararg */

            luaX_next(&lexstate);  /* read first token */

            chunk(&lexstate);
            check(&lexstate, TK_EOS);
        }
        catch( ... )
        {
            close_func(&lexstate);

            // We do not need the proto anymore.
            funcstate.f->DereferenceGC( L );
            throw;
        }
        close_func(&lexstate);

        // The result is funcstate.f, which is a referenced proto.
    }
    catch( ... )
    {
        // When done parsing, we should clear up the string.
        inputNameString->DereferenceGC( L );
        throw;
    }

    inputNameString->DereferenceGC( L );

    lua_assert(funcstate.next == NULL);
    lua_assert(funcstate.f->nups == 0);
    lua_assert(lexstate.fsList.IsEmpty() == true);
    return funcstate.f;
}
Example #10
0
static void retstat (LexState *ls) {
  /* stat -> RETURN explist */
  FuncState *fs = ls->fs;
  BlockCnt *bl = fs->bl;
  expdesc e;
  int first, nret;  /* registers with returned values */
  int ret_in_try = 0;
  luaX_next(ls);  /* skip RETURN */
  if (block_follow(ls->t.token) || ls->t.token == ';')
    first = nret = 0;  /* return no values */
  else {
    nret = explist1(ls, &e);  /* optional return values */
    if (hasmultret(e.k)) {
      luaK_setmultret(fs, &e);
      if (e.k == VCALL && nret == 1) {  /* tail call? */
        SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
        lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
      }
      first = fs->nactvar;
      nret = LUA_MULTRET;  /* return all values */
    }
    else {
      if (nret == 1)  /* only one single value? */
        first = luaK_exp2anyreg(fs, &e);
      else {
        luaK_exp2nextreg(fs, &e);  /* values must go to the `stack' */
        first = fs->nactvar;  /* return all `active' values */
        lua_assert(nret == fs->freereg - first);
      }
    }
  }

  /* before return, we should exit all try-catch blocks */
  while (bl) {
    if (bl->isbreakable == 2) {
      if (ret_in_try)
        luaK_codeABC(fs, OP_EXITTRY, 0, 0, 0);
      else {
        ret_in_try = 1;
        luaK_codeABC(fs, OP_EXITTRY, first, nret+1, 1); /* here we will save all return values */
      }
    } else if (bl->isbreakable == 3)
      luaX_syntaxerror(ls, "can't return in _finally_ clause");
    bl = bl->previous;
  }

  luaK_codeABC(fs, OP_RETURN, first, nret+1, ret_in_try);
}
Example #11
0
Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
  struct LexState lexstate;
  struct FuncState funcstate;
  lexstate.buff = buff;
  luaX_setinput(L, &lexstate, z, luaS_new(L, name));
  open_func(&lexstate, &funcstate);
  funcstate.f->is_vararg = VARARG_ISVARARG;  /* main func. is always vararg */
  luaX_next(&lexstate);  /* read first token */
  chunk(&lexstate);
  check(&lexstate, TK_EOS);
  close_func(&lexstate);
  lua_assert(funcstate.prev == NULL);
  lua_assert(funcstate.f->nups == 0);
  lua_assert(lexstate.fs == NULL);
  return funcstate.f;
}
Example #12
0
static void forstat (LexState *ls, int line) {
  /* forstat -> FOR (fornum | forlist) END */
  FuncState *fs = ls->fs;
  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");
  }
  check_match(ls, TK_END, TK_FOR, line);
  leaveblock(fs);  /* loop scope (`break' jumps to this point) */
}
Example #13
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 #14
0
static void dostrip(LexState *X)
{
 int ln=1;
 int lt=0;
 for (;;)
 {
  int t;
  luaX_next(X);
  t=X->t.token;
  if (preserve)
  {
   if (X->linenumber!=ln)
   {
    if (preserve>1)
     while (X->linenumber!=ln++) printf("\n");
    else if (lt!=0)
     printf("\n");
    ln=X->linenumber;
    lt=0;
   }
  }
  if (space(lt,t)) printf(" ");
  switch (t)
  {
   case TK_EOS:
    return;
   case TK_STRING:
    quote(X->t.seminfo.ts);
    break;
   case TK_NAME:
    printf("%s",getstr(X->t.seminfo.ts));
    break;
   case TK_NUMBER:
    printf("%s",X->buff->buffer);
    break;
   default:
    if (t<FIRST_RESERVED)
     printf("%c",t);
    else
     printf("%s",luaX_tokens[t-FIRST_RESERVED]);
    break;
  }
  lt=t;
  if (preserve>2) printf("\n");
 }
}
Example #15
0
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars, BinOpr *opr) {
  expdesc e;
  check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
                      "syntax error");
  if (testnext(ls, ',')) {  /* assignment -> `,' primaryexp assignment */
    struct LHS_assign nv;
    nv.prev = lh;
    primaryexp(ls, &nv.v);
    if (nv.v.k == VLOCAL)
      check_conflict(ls, lh, &nv.v);
    assignment(ls, &nv, nvars+1, opr);
  }
  else {  /* assignment -> `=' explist1 */
    int nexps;

	*opr = OPR_NOBINOPR;
	switch(ls->t.token)
	{
	case '=': break;
	case TK_CONCATASSIGN: *opr = OPR_CONCAT; break;
	case TK_ADDASSIGN: *opr = OPR_ADD; break;
	case TK_SUBASSIGN: *opr = OPR_SUB; break;
	case TK_MULASSIGN: *opr = OPR_MUL; break;
	case TK_DIVASSIGN: *opr = OPR_DIV; break;
	case TK_POWASSIGN: *opr = OPR_POW; break;
	case TK_MODASSIGN: *opr = OPR_MOD; break;
	default:
		luaX_syntaxerror(ls, "unexpected symbol");
		break;
	};
	luaX_next(ls);
    nexps = explist1(ls, &e);
    if (nexps != nvars) {
      adjust_assign(ls, nvars, nexps, &e);
      if (nexps > nvars)
        ls->fs->freereg -= nexps - nvars;  /* remove extra values */
    }
    else {
      luaK_setoneret(ls->fs, &e);  /* close last expression */
      luaK_storevar(ls->fs, &lh->v, &e, *opr);
      return;  /* avoid default */
    }
  }
  init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
  luaK_storevar(ls->fs, &lh->v, &e, *opr);
}
Example #16
0
static void compound (LexState *ls, struct LHS_assign *lh) {
  expdesc rh;
  int nexps;
  BinOpr op;

  check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
                      "syntax error");
  /* parse Compound operation. */
  op = getcompopr(ls->t.token);
  luaX_next(ls);

  /* parse right-hand expression */
  nexps = explist1(ls, &rh);
  check_condition(ls, nexps == 1, "syntax error");

  luaK_posfix(ls->fs, op, &(lh->v), &rh);
}
Example #17
0
static void primaryexp(LexState* ls, expdesc* v)
{
	/* primaryexp ->
	prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
	FuncState* fs = ls->fs;
	prefixexp(ls, v);
	for (;;)
	{
		switch (ls->t.token)
		{
			case '.':    /* field */
			{
				field(ls, v);
				break;
			}
			case '[':    /* `[' exp1 `]' */
			{
				expdesc key;
				luaK_exp2anyreg(fs, v);
				yindex(ls, &key);
				luaK_indexed(fs, v, &key);
				break;
			}
			case ':':    /* `:' NAME funcargs */
			{
				expdesc key;
				luaX_next(ls);
				checkname(ls, &key);
				luaK_self(fs, v, &key);
				funcargs(ls, v);
				break;
			}
			case '(':
			case TK_STRING:
			case '{':    /* funcargs */
			{
				luaK_exp2nextreg(fs, v);
				funcargs(ls, v);
				break;
			}
			default:
				return;
		}
	}
}
Example #18
0
Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
  struct LexState lexstate;
  struct FuncState *pfuncstate = (struct FuncState*)malloc(sizeof(struct FuncState));
  Proto *res;
  lexstate.buff = buff;
  luaX_setinput(L, &lexstate, z, luaS_new(L, name));
  open_func(&lexstate, pfuncstate);
  pfuncstate->f->is_vararg = VARARG_ISVARARG;  /* main func. is always vararg */
  luaX_next(&lexstate);  /* read first token */
  chunk(&lexstate);
  check(&lexstate, TK_EOS);
  close_func(&lexstate);
  lua_assert(pfuncstate->prev == NULL);
  lua_assert(pfuncstate->f->nups == 0);
  lua_assert(lexstate.fs == NULL);
  res = pfuncstate->f;
  free(pfuncstate);
  return res;
}
Example #19
0
Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
  struct LexState lexstate;
  struct FuncState funcstate;
  TString *tname = luaS_new(L, name);
  setsvalue2s(L, L->top, tname);  /* protect name */
  incr_top(L);
  lexstate.buff = buff;
  luaX_setinput(L, &lexstate, z, tname);
  open_func(&lexstate, &funcstate);
  funcstate.f->is_vararg = VARARG_ISVARARG;  /* main func. is always vararg */
  luaX_next(&lexstate);  /* read first token */
  chunk(&lexstate);
  check(&lexstate, TK_EOS);
  close_func(&lexstate);
  L->top--; /* remove 'name' from stack */
  lua_assert(funcstate.prev == NULL);
  lua_assert(funcstate.f->nups == 0);
  lua_assert(lexstate.fs == NULL);
  return funcstate.f;
}
Example #20
0
static void inc_assignment(LexState *ls, struct LHS_assign *lh) {
    BinOpr op = getbinopr(ls->t.token);
    FuncState * fs=ls->fs;
    expdesc e, v2;
    /* reserve all registers needed by the lvalue */
    luaK_reserveregs(fs,fs->freereg-fs->nactvar);
    luaX_next(ls);
    checknext(ls, '=');
    enterlevel(ls);
    e = lh->v;
    luaK_infix(fs,op,&e);
    /* we only match one expr(), not a full explist(),
     so "a+=2,2" will be a parse error. */
    expr(ls,&v2);
    luaK_posfix(fs, op, &e, &v2);
    leavelevel(ls);
    luaK_exp2nextreg(fs,&e);
    luaK_setoneret(ls->fs, &e);
    luaK_storevar(ls->fs, &lh->v, &e);
}
Example #21
0
static void parlist (LexState *ls)
{
    /* parlist -> [ param { `,' param } ] */
    FuncState *fs = GetCurrentFuncState( ls );
    Proto *f = fs->f;
    int nparams = 0;

    f->is_vararg = 0;

    if (ls->t.token != ')')
    {  /* is `parlist' not empty? */
        do
        {
            switch (ls->t.token)
            {
            case TK_NAME:
            {  /* param -> NAME */
                new_localvar(ls, str_checkname(ls), nparams++);
                break;
            }
            case TK_DOTS:
            {  /* param -> `...' */
                luaX_next(ls);
                f->is_vararg |= VARARG_ISVARARG;
                break;
            }
            default:
            {
                luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
                break;
            }
            }
        }
        while (!f->is_vararg && testnext(ls, ','));
    }
    adjustlocalvars(ls, nparams);

    f->numparams = cast_byte( fs->nactvar - (f->is_vararg & VARARG_HASARG) );

    luaK_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
}
Example #22
0
static void prefixexp (LexState *ls, expdesc *v) {
  /* prefixexp -> NAME | '(' expr ')' */
  switch (ls->t.token) {
    case '(': {
      int line = ls->linenumber;
      luaX_next(ls);
      expr(ls, v);
      check_match(ls, ')', '(', line);
      luaK_dischargevars(ls->fs, v);
      return;
    }
    case TK_NAME: {
      singlevar(ls, v);
      return;
    }
    default: {
      luaX_syntaxerror(ls, "unexpected symbol");
      return;
    }
  }
}
Example #23
0
static void parlist(LexState* ls)
{
	/* parlist -> [ param { `,' param } ] */
	FuncState* fs = ls->fs;
	Proto* f = fs->f;
	int nparams = 0;
	f->is_vararg = 0;
	if (ls->t.token != ')')	   /* is `parlist' not empty? */
	{
		do
		{
			switch (ls->t.token)
			{
				case TK_NAME:	 /* param -> NAME */
				{
					new_localvar(ls, str_checkname(ls), nparams++);
					break;
				}
				case TK_DOTS:	 /* param -> `...' */
				{
					luaX_next(ls);
#if defined(LUA_COMPAT_VARARG)
					/* use `arg' as default name */
					new_localvarliteral(ls, "arg", nparams++);
					f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
#endif
					f->is_vararg |= VARARG_ISVARARG;
					break;
				}
				default:
					luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
			}
		}
		while (!f->is_vararg && testnext(ls, ','));
	}
	adjustlocalvars(ls, nparams);
	f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
	luaK_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
}
Example #24
0
static void ifstat (LexState *ls, int line) {
  /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
  FuncState *fs = ls->fs;
  int flist;
  int escapelist = NO_JUMP;
  flist = test_then_block(ls);  /* IF cond THEN block */
  while (ls->t.token == TK_ELSEIF) {
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    luaK_patchtohere(fs, flist);
    flist = test_then_block(ls);  /* ELSEIF cond THEN block */
  }
  if (ls->t.token == TK_ELSE) {
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    luaK_patchtohere(fs, flist);
    luaX_next(ls);  /* skip ELSE (after patch, for correct line info) */
    block(ls);  /* `else' part */
  }
  else
    luaK_concat(fs, &escapelist, flist);
  luaK_patchtohere(fs, escapelist);
  check_match(ls, TK_END, TK_IF, line);
}
Example #25
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 #26
0
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
  expdesc e;
  check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
                      "syntax error");
  if (testnext(ls, ',')) {  /* assignment -> `,' primaryexp assignment */
    struct LHS_assign nv;
    nv.prev = lh;
    primaryexp(ls, &nv.v);
    if (nv.v.k == VLOCAL)
      check_conflict(ls, lh, &nv.v);
    luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
                    "variables in assignment");
    assignment(ls, &nv, nvars+1);
  }
  else {  /* assignment -> `=' explist1 */
    int nexps;
#if LUA_MUTATION_OPERATORS
    luaX_next(ls); /* consume `=' token. */
#else
    checknext(ls, '=');
#endif /* LUA_MUTATION_OPERATORS */
    nexps = explist1(ls, &e);
    if (nexps != nvars) {
      adjust_assign(ls, nvars, nexps, &e);
      if (nexps > nvars)
        ls->fs->freereg -= nexps - nvars;  /* remove extra values */
    }
    else {
      luaK_setoneret(ls->fs, &e);  /* close last expression */
      luaK_storevar(ls->fs, &lh->v, &e);
      return;  /* avoid default */
    }
  }
  init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
  luaK_storevar(ls->fs, &lh->v, &e);
}
Example #27
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);
  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 #28
0
static void checknext (LexState *ls, int c) {
  check(ls, c);
  luaX_next(ls);
}
Example #29
0
static void primaryexp (LexState *ls, expdesc *v) {
  /* primaryexp ->
        prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
  FuncState *fs = ls->fs;
  prefixexp(ls, v);
  for (;;) {
    switch (ls->t.token) {
      case '.': {  /* field */
        field(ls, v);
        break;
      }
      case '[': {  /* `[' exp1 `]' */
        expdesc key;
        luaK_exp2anyreg(fs, v);
        yindex(ls, &key);
        luaK_indexed(fs, v, &key);
        break;
      }
      case ':': {  /* `:' NAME funcargs */
        expdesc key;
        luaX_next(ls);
        checkname(ls, &key);
        luaK_self(fs, v, &key);
        funcargs(ls, v);
        break;
      }
#if LUA_WIDESTRING
      case '(': case TK_STRING: case TK_WSTRING: case '{': {  /* funcargs */
#else
      case '(': case TK_STRING: case '{': {  /* funcargs */
#endif /* LUA_WIDESTRING */
        luaK_exp2nextreg(fs, v);
        funcargs(ls, v);
        break;
      }
      default: return;
    }
  }
}


static void simpleexp (LexState *ls, expdesc *v) {
#if LUA_WIDESTRING
  /* simpleexp -> NUMBER | STRING | WSTRING | NIL | true | false | ... |
                  constructor | FUNCTION body | primaryexp */
#else
  /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
                  constructor | FUNCTION body | primaryexp */
#endif /* LUA_WIDESTRING */
  switch (ls->t.token) {
    case TK_NUMBER: {
      init_exp(v, VKNUM, 0);
      v->u.nval = ls->t.seminfo.r;
      break;
    }
    case TK_STRING: {
      codestring(ls, v, ls->t.seminfo.ts);
      break;
    }
#if LUA_WIDESTRING
    case TK_WSTRING: {
      codewstring(ls, v, ls->t.seminfo.ts);
      break;
    }
#endif /* LUA_WIDESTRING */
    case TK_NIL: {
      init_exp(v, VNIL, 0);
      break;
    }
    case TK_TRUE: {
      init_exp(v, VTRUE, 0);
      break;
    }
    case TK_FALSE: {
      init_exp(v, VFALSE, 0);
      break;
    }
    case TK_DOTS: {  /* vararg */
      FuncState *fs = ls->fs;
      check_condition(ls, fs->f->is_vararg,
                      "cannot use " LUA_QL("...") " outside a vararg function");
      fs->f->is_vararg &= ~VARARG_NEEDSARG;  /* don't need 'arg' */
      init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
      break;
    }
    case '{': {  /* constructor */
      constructor(ls, v);
      return;
    }
    case TK_FUNCTION: {
      luaX_next(ls);
      body(ls, v, 0, ls->linenumber);
      return;
    }
    default: {
      primaryexp(ls, v);
      return;
    }
  }
  luaX_next(ls);
}


static UnOpr getunopr (int op) {
  switch (op) {
    case TK_NOT: return OPR_NOT;
    case '-': return OPR_MINUS;
    case '#': return OPR_LEN;
    default: return OPR_NOUNOPR;
  }
}


static BinOpr getbinopr (int op) {
  switch (op) {
    case '+': return OPR_ADD;
    case '-': return OPR_SUB;
    case '*': return OPR_MUL;
    case '/': return OPR_DIV;
    case '%': return OPR_MOD;
#if LUA_BITFIELD_OPS
    case '&': return OPR_BAND;
    case '|': return OPR_BOR;
    case TK_XOR: return OPR_BXOR;
    case TK_SHL: return OPR_BSHL;
    case TK_SHR: return OPR_BSHR;
#endif /* LUA_BITFIELD_OPS */
    case '^': return OPR_POW;
    case TK_CONCAT: return OPR_CONCAT;
    case TK_NE: return OPR_NE;
    case TK_EQ: return OPR_EQ;
    case '<': return OPR_LT;
    case TK_LE: return OPR_LE;
    case '>': return OPR_GT;
    case TK_GE: return OPR_GE;
    case TK_AND: return OPR_AND;
    case TK_OR: return OPR_OR;
    default: return OPR_NOBINOPR;
  }
}


static const struct {
  lu_byte left;  /* left priority for each binary operator */
  lu_byte right; /* right priority */
} priority[] = {  /* ORDER OPR */
#if LUA_BITFIELD_OPS
   {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8},  /* bitwise operators */
#endif /* LUA_BITFIELD_OPS */
   {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7},  /* `+' `-' `/' `%' */
   {10, 9}, {5, 4},                 /* power and concat (right associative) */
   {3, 3}, {3, 3},                  /* equality and inequality */
   {3, 3}, {3, 3}, {3, 3}, {3, 3},  /* order */
   {2, 2}, {1, 1}                   /* logical (and/or) */
};

#define UNARY_PRIORITY	8  /* priority for unary operators */


/*
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
** where `binop' is any binary operator with a priority higher than `limit'
*/
static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
  BinOpr op;
  UnOpr uop;
  enterlevel(ls);
  uop = getunopr(ls->t.token);
  if (uop != OPR_NOUNOPR) {
    luaX_next(ls);
    subexpr(ls, v, UNARY_PRIORITY);
    luaK_prefix(ls->fs, uop, v);
  }
  else simpleexp(ls, v);
  /* expand while operators have priorities higher than `limit' */
  op = getbinopr(ls->t.token);
  while (op != OPR_NOBINOPR && priority[op].left > limit) {
    expdesc v2;
    BinOpr nextop;
    luaX_next(ls);
    luaK_infix(ls->fs, op, v);
    /* read sub-expression with higher priority */
    nextop = subexpr(ls, &v2, priority[op].right);
    luaK_posfix(ls->fs, op, v, &v2);
    op = nextop;
  }
  leavelevel(ls);
  return op;  /* return first untreated operator */
}
Example #30
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 */
		}
		case TK_CONTINUE:  /* stat -> continuestat */
		{
			luaX_next(ls);	/* skip CONTINUE */
			continuestat(ls);
			return 1;	   /* must be last statement */
		}
		default:
		{
			exprstat(ls);
			return 0;	 /* to avoid warnings */
		}
	}
}