예제 #1
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);
}
예제 #2
0
파일: lparser.c 프로젝트: xiaofeng/Arcemu
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 */
}
예제 #3
0
static void body (LexState *ls, expdesc *e, int needself, int line)
{
    /* body ->  `(' parlist `)' chunk END */
    FuncState new_fs;
    open_func(ls, &new_fs);
    try
    {
        new_fs.f->linedefined = line;
        checknext(ls, '(');
        if (needself)
        {
            new_localvarliteral(ls, "self", 0);
            adjustlocalvars(ls, 1);
        }
        parlist(ls);
        checknext(ls, ')');
        chunk(ls);
        new_fs.f->lastlinedefined = ls->linenumber;
        check_match(ls, TK_END, TK_FUNCTION, line);
    }
    catch( ... )
    {
        close_func(ls);

        // We do not need the proto anymore.
        new_fs.f->DereferenceGC( ls->L );
        throw;
    }
    close_func(ls);
    pushclosure(ls, &new_fs, e);

    // Terminate the FuncState again.
    new_fs.f->DereferenceGC( ls->L );
}
예제 #4
0
static void localstat (LexState *ls)
{
    /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
    int nvars = 0;
    int nexps;
    expdesc e;

    do
    {
        new_localvar(ls, str_checkname(ls), nvars++);
    }
    while (testnext(ls, ','));

    if (testnext(ls, '='))
    {
        nexps = explist1(ls, &e);
    }
    else
    {
        e.k = VVOID;
        nexps = 0;
    }

    adjust_assign(ls, nvars, nexps, &e);

    adjustlocalvars(ls, nvars);
}
예제 #5
0
파일: lparser.c 프로젝트: 0xmono/miranda-ng
static void localfunc (LexState *ls) {
  expdesc v, b;
  new_localvar(ls, str_checkname(ls), 0);
  init_exp(&v, VLOCAL, ls->fs->freereg++);
  adjustlocalvars(ls, 1);
  body(ls, &b, 0, ls->linenumber);
  luaK_storevar(ls->fs, &v, &b);
}
예제 #6
0
static void localstat (LexState *ls) {
  /* stat -> LOCAL NAME {`,' NAME} [ IN primaryexp | `=' explist1] */
  int nvars = 0;
  int nexps;
  expdesc e;
  do {
    new_localvar(ls, str_checkname(ls), nvars++);
  } while (testnext(ls, ','));
  
  if (testnext(ls, TK_IN)) {
    lu_byte from_var;
    int regs = ls->fs->freereg;
    int vars = ls->fs->nactvar;

    luaK_reserveregs(ls->fs, nvars);
    adjustlocalvars(ls, nvars);

    new_localvarliteral(ls, "(from)", 0);
    primaryexp(ls, &e);
    luaK_exp2nextreg(ls->fs, &e);
    from_var = ls->fs->nactvar;
    adjustlocalvars(ls, 1);
    luaK_setoneret(ls->fs, &e);  /* close last expression */

    for (nexps=0; nexps<nvars; nexps++) {
      expdesc v, key;
      init_exp(&e, VNONRELOC, ls->fs->freereg-1);
      codestring(ls, &key, getlocvar(ls->fs, vars+nexps).varname);
      luaK_indexed(ls->fs, &e, &key);
      init_exp(&v, VLOCAL, regs+nexps);
      luaK_storevar(ls->fs, &v, &e);
    }
    removevars(ls, from_var);
    return;
  }
  
  if (testnext(ls, '='))
    nexps = explist1(ls, &e);
  else {
    e.k = VVOID;
    nexps = 0;
  }
  adjust_assign(ls, nvars, nexps, &e);
  adjustlocalvars(ls, nvars);
}
예제 #7
0
파일: lparser.c 프로젝트: BitMax/openitg
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->nactvar);
  fs->f->is_vararg = cast(lu_byte, dots);
  if (dots)
    create_local(ls, "arg");
  luaK_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
}
예제 #8
0
파일: lparser.c 프로젝트: xiaofeng/Arcemu
static void localfunc (LexState *ls) {
  expdesc v, b;
  FuncState *fs = ls->fs;
  new_localvar(ls, str_checkname(ls), 0);
  init_exp(&v, VLOCAL, fs->freereg);
  luaK_reserveregs(fs, 1);
  adjustlocalvars(ls, 1);
  body(ls, &b, 0, ls->linenumber);
  luaK_storevar(fs, &v, &b);
  /* debug information will only see the variable after this point! */
  getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
}
예제 #9
0
static int assignment (LexState *ls, struct LHS_assign *lh, int nvars,
                       lu_byte *from_var)
{
  expdesc e;
  int from = 0;
  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");
    from = assignment(ls, &nv, nvars+1, from_var);
  }
  else {  /* assignment -> IN primaryexp | `=' explist1 */
    int nexps;
    if (testnext(ls, TK_IN)) {
      new_localvarliteral(ls, "(from)", 0);
      primaryexp(ls, &e);
      luaK_exp2nextreg(ls->fs, &e);
      *from_var = ls->fs->nactvar;
      adjustlocalvars(ls, 1);

      luaK_setoneret(ls->fs, &e);  /* close last expression */
      getfrom(ls, &e, &lh->v);
      luaK_storevar(ls->fs, &lh->v, &e);
      return 1;  /* avoid default */
    }
    else {
      checknext(ls, '=');
      nexps = explist1(ls, &e);
    }

    if (nexps == nvars) {
      luaK_setoneret(ls->fs, &e);  /* close last expression */
      luaK_storevar(ls->fs, &lh->v, &e);
      return 0;  /* avoid default */
    }
    else {
      adjust_assign(ls, nvars, nexps, &e);
      if (nexps > nvars)
        ls->fs->freereg -= nexps - nvars;  /* remove extra values */
    }
  }
  init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
  if (from) getfrom(ls, &e, &lh->v);
   luaK_storevar(ls->fs, &lh->v, &e);
  return from;
}
예제 #10
0
파일: lparser.c 프로젝트: BitMax/openitg
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);
}
예제 #11
0
파일: lparser.c 프로젝트: arsaccol/SLED
static void body (LexState *ls, expdesc *e, int needself, int line) {
  /* body ->  `(' parlist `)' chunk END */  

#ifdef LUA_UTILITIES_NET
  char szFuncName1[256];
  char szFuncName2[256];
#endif

  FuncState new_fs;
  open_func(ls, &new_fs);
  new_fs.f->linedefined = line;

#ifdef LUA_UTILITIES_NET
  szFuncName1[0] = 0;
  szFuncName2[0] = 0;
  TryGetFunctionName(ls->t.seminfo.ts, szFuncName1, 256);
#endif

  checknext(ls, '(');
  if (needself) {
    new_localvarliteral(ls, "self", 0);
    adjustlocalvars(ls, 1);
  }
  parlist(ls);
  checknext(ls, ')');
  chunk(ls);    
  
#ifdef LUA_UTILITIES_NET
  if (szFuncName1[0] == 0)
	TryGetFunctionName(ls->t.seminfo.ts, szFuncName2, 256);
#endif
  
  new_fs.f->lastlinedefined = ls->linenumber;
  check_match(ls, TK_END, TK_FUNCTION, line);
  close_func(ls);

#ifdef LUA_UTILITIES_NET
  // Use the correct function name based on values obtained
  if (szFuncName1[0] == 0)
	  GetFunction(szFuncName2, ls, new_fs.f);
  else
	  GetFunction(szFuncName1, ls, new_fs.f);
#endif

  pushclosure(ls, &new_fs, e);
}
예제 #12
0
파일: lparser.c 프로젝트: xiaofeng/Arcemu
static void body (LexState *ls, expdesc *e, int needself, int line) {
  /* body ->  `(' parlist `)' chunk END */
  FuncState new_fs;
  open_func(ls, &new_fs);
  new_fs.f->linedefined = line;
  checknext(ls, '(');
  if (needself) {
    new_localvarliteral(ls, "self", 0);
    adjustlocalvars(ls, 1);
  }
  parlist(ls);
  checknext(ls, ')');
  chunk(ls);
  new_fs.f->lastlinedefined = ls->linenumber;
  check_match(ls, TK_END, TK_FUNCTION, line);
  close_func(ls);
  pushclosure(ls, &new_fs, e);
}
예제 #13
0
파일: lparser.c 프로젝트: BitMax/openitg
static void create_local (LexState *ls, const char *name) {
  new_localvarstr(ls, name, 0);
  adjustlocalvars(ls, 1);
}
예제 #14
0
static void constructor (LexState *ls, expdesc *t) {
  /* constructor -> ?? */
  FuncState *fs = ls->fs;
  int line = ls->linenumber;
  int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
  struct ConsControl cc;
  cc.na = cc.nh = cc.tostore = 0;
  cc.t = t;
  init_exp(t, VRELOCABLE, pc);
  init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
  luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top (for gc) */
  checknext(ls, '{');
#if LUA_OPTIONAL_COMMA
  for (;;) {
#else
  do {
#endif /* LUA_OPTIONAL_COMMA */
    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
    if (ls->t.token == '}') break;
    closelistfield(fs, &cc);
    switch(ls->t.token) {
      case TK_NAME: {  /* may be listfields or recfields */
        luaX_lookahead(ls);
        if (ls->lookahead.token != '=')  /* expression? */
          listfield(ls, &cc);
        else
          recfield(ls, &cc);
        break;
      }
      case '[': {  /* constructor_item -> recfield */
        recfield(ls, &cc);
        break;
      }
      default: {  /* constructor_part -> listfield */
        listfield(ls, &cc);
        break;
      }
    }
#if LUA_OPTIONAL_COMMA
	if (ls->t.token == ',' || ls->t.token == ';')
		next(ls);
	else if (ls->t.token == '}')
		break;
  }
#else
  } while (testnext(ls, ',') || testnext(ls, ';'));
#endif /* LUA_OPTIONAL_COMMA */
  check_match(ls, '}', '{', line);
  lastlistfield(fs, &cc);
  SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
  SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh));  /* set initial table size */
}

/* }====================================================================== */



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 */
}
예제 #15
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);
}