lua/lparser.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 18 Jun 2017 19:50:43 -0400
changeset 57 4974e5368a29
parent 0 d7ee4e2ed49d
permissions -rw-r--r--
Minor type cleanup ("unsigned char" -> "uint8_t").
icculus@0
     1
/*
icculus@0
     2
** $Id: lparser.c,v 2.130.1.1 2013/04/12 18:48:47 roberto Exp $
icculus@0
     3
** Lua Parser
icculus@0
     4
** See Copyright Notice in lua.h
icculus@0
     5
*/
icculus@0
     6
icculus@0
     7
icculus@0
     8
#include <string.h>
icculus@0
     9
icculus@0
    10
#define lparser_c
icculus@0
    11
#define LUA_CORE
icculus@0
    12
icculus@0
    13
#include "lua.h"
icculus@0
    14
icculus@0
    15
#include "lcode.h"
icculus@0
    16
#include "ldebug.h"
icculus@0
    17
#include "ldo.h"
icculus@0
    18
#include "lfunc.h"
icculus@0
    19
#include "llex.h"
icculus@0
    20
#include "lmem.h"
icculus@0
    21
#include "lobject.h"
icculus@0
    22
#include "lopcodes.h"
icculus@0
    23
#include "lparser.h"
icculus@0
    24
#include "lstate.h"
icculus@0
    25
#include "lstring.h"
icculus@0
    26
#include "ltable.h"
icculus@0
    27
icculus@0
    28
icculus@0
    29
icculus@0
    30
/* maximum number of local variables per function (must be smaller
icculus@0
    31
   than 250, due to the bytecode format) */
icculus@0
    32
#define MAXVARS		200
icculus@0
    33
icculus@0
    34
icculus@0
    35
#define hasmultret(k)		((k) == VCALL || (k) == VVARARG)
icculus@0
    36
icculus@0
    37
icculus@0
    38
icculus@0
    39
/*
icculus@0
    40
** nodes for block list (list of active blocks)
icculus@0
    41
*/
icculus@0
    42
typedef struct BlockCnt {
icculus@0
    43
  struct BlockCnt *previous;  /* chain */
icculus@0
    44
  short firstlabel;  /* index of first label in this block */
icculus@0
    45
  short firstgoto;  /* index of first pending goto in this block */
icculus@0
    46
  lu_byte nactvar;  /* # active locals outside the block */
icculus@0
    47
  lu_byte upval;  /* true if some variable in the block is an upvalue */
icculus@0
    48
  lu_byte isloop;  /* true if `block' is a loop */
icculus@0
    49
} BlockCnt;
icculus@0
    50
icculus@0
    51
icculus@0
    52
icculus@0
    53
/*
icculus@0
    54
** prototypes for recursive non-terminal functions
icculus@0
    55
*/
icculus@0
    56
static void statement (LexState *ls);
icculus@0
    57
static void expr (LexState *ls, expdesc *v);
icculus@0
    58
icculus@0
    59
icculus@0
    60
static void anchor_token (LexState *ls) {
icculus@0
    61
  /* last token from outer function must be EOS */
icculus@0
    62
  lua_assert(ls->fs != NULL || ls->t.token == TK_EOS);
icculus@0
    63
  if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
icculus@0
    64
    TString *ts = ls->t.seminfo.ts;
icculus@0
    65
    luaX_newstring(ls, getstr(ts), ts->tsv.len);
icculus@0
    66
  }
icculus@0
    67
}
icculus@0
    68
icculus@0
    69
icculus@0
    70
/* semantic error */
icculus@0
    71
static l_noret semerror (LexState *ls, const char *msg) {
icculus@0
    72
  ls->t.token = 0;  /* remove 'near to' from final message */
icculus@0
    73
  luaX_syntaxerror(ls, msg);
icculus@0
    74
}
icculus@0
    75
icculus@0
    76
icculus@0
    77
static l_noret error_expected (LexState *ls, int token) {
icculus@0
    78
  luaX_syntaxerror(ls,
icculus@0
    79
      luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
icculus@0
    80
}
icculus@0
    81
icculus@0
    82
icculus@0
    83
static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
icculus@0
    84
  lua_State *L = fs->ls->L;
icculus@0
    85
  const char *msg;
icculus@0
    86
  int line = fs->f->linedefined;
icculus@0
    87
  const char *where = (line == 0)
icculus@0
    88
                      ? "main function"
icculus@0
    89
                      : luaO_pushfstring(L, "function at line %d", line);
icculus@0
    90
  msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
icculus@0
    91
                             what, limit, where);
icculus@0
    92
  luaX_syntaxerror(fs->ls, msg);
icculus@0
    93
}
icculus@0
    94
icculus@0
    95
icculus@0
    96
static void checklimit (FuncState *fs, int v, int l, const char *what) {
icculus@0
    97
  if (v > l) errorlimit(fs, l, what);
icculus@0
    98
}
icculus@0
    99
icculus@0
   100
icculus@0
   101
static int testnext (LexState *ls, int c) {
icculus@0
   102
  if (ls->t.token == c) {
icculus@0
   103
    luaX_next(ls);
icculus@0
   104
    return 1;
icculus@0
   105
  }
icculus@0
   106
  else return 0;
icculus@0
   107
}
icculus@0
   108
icculus@0
   109
icculus@0
   110
static void check (LexState *ls, int c) {
icculus@0
   111
  if (ls->t.token != c)
icculus@0
   112
    error_expected(ls, c);
icculus@0
   113
}
icculus@0
   114
icculus@0
   115
icculus@0
   116
static void checknext (LexState *ls, int c) {
icculus@0
   117
  check(ls, c);
icculus@0
   118
  luaX_next(ls);
icculus@0
   119
}
icculus@0
   120
icculus@0
   121
icculus@0
   122
#define check_condition(ls,c,msg)	{ if (!(c)) luaX_syntaxerror(ls, msg); }
icculus@0
   123
icculus@0
   124
icculus@0
   125
icculus@0
   126
static void check_match (LexState *ls, int what, int who, int where) {
icculus@0
   127
  if (!testnext(ls, what)) {
icculus@0
   128
    if (where == ls->linenumber)
icculus@0
   129
      error_expected(ls, what);
icculus@0
   130
    else {
icculus@0
   131
      luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
icculus@0
   132
             "%s expected (to close %s at line %d)",
icculus@0
   133
              luaX_token2str(ls, what), luaX_token2str(ls, who), where));
icculus@0
   134
    }
icculus@0
   135
  }
icculus@0
   136
}
icculus@0
   137
icculus@0
   138
icculus@0
   139
static TString *str_checkname (LexState *ls) {
icculus@0
   140
  TString *ts;
icculus@0
   141
  check(ls, TK_NAME);
icculus@0
   142
  ts = ls->t.seminfo.ts;
icculus@0
   143
  luaX_next(ls);
icculus@0
   144
  return ts;
icculus@0
   145
}
icculus@0
   146
icculus@0
   147
icculus@0
   148
static void init_exp (expdesc *e, expkind k, int i) {
icculus@0
   149
  e->f = e->t = NO_JUMP;
icculus@0
   150
  e->k = k;
icculus@0
   151
  e->u.info = i;
icculus@0
   152
}
icculus@0
   153
icculus@0
   154
icculus@0
   155
static void codestring (LexState *ls, expdesc *e, TString *s) {
icculus@0
   156
  init_exp(e, VK, luaK_stringK(ls->fs, s));
icculus@0
   157
}
icculus@0
   158
icculus@0
   159
icculus@0
   160
static void checkname (LexState *ls, expdesc *e) {
icculus@0
   161
  codestring(ls, e, str_checkname(ls));
icculus@0
   162
}
icculus@0
   163
icculus@0
   164
icculus@0
   165
static int registerlocalvar (LexState *ls, TString *varname) {
icculus@0
   166
  FuncState *fs = ls->fs;
icculus@0
   167
  Proto *f = fs->f;
icculus@0
   168
  int oldsize = f->sizelocvars;
icculus@0
   169
  luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
icculus@0
   170
                  LocVar, SHRT_MAX, "local variables");
icculus@0
   171
  while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
icculus@0
   172
  f->locvars[fs->nlocvars].varname = varname;
icculus@0
   173
  luaC_objbarrier(ls->L, f, varname);
icculus@0
   174
  return fs->nlocvars++;
icculus@0
   175
}
icculus@0
   176
icculus@0
   177
icculus@0
   178
static void new_localvar (LexState *ls, TString *name) {
icculus@0
   179
  FuncState *fs = ls->fs;
icculus@0
   180
  Dyndata *dyd = ls->dyd;
icculus@0
   181
  int reg = registerlocalvar(ls, name);
icculus@0
   182
  checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
icculus@0
   183
                  MAXVARS, "local variables");
icculus@0
   184
  luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,
icculus@0
   185
                  dyd->actvar.size, Vardesc, MAX_INT, "local variables");
icculus@0
   186
  dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);
icculus@0
   187
}
icculus@0
   188
icculus@0
   189
icculus@0
   190
static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
icculus@0
   191
  new_localvar(ls, luaX_newstring(ls, name, sz));
icculus@0
   192
}
icculus@0
   193
icculus@0
   194
#define new_localvarliteral(ls,v) \
icculus@0
   195
	new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1)
icculus@0
   196
icculus@0
   197
icculus@0
   198
static LocVar *getlocvar (FuncState *fs, int i) {
icculus@0
   199
  int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
icculus@0
   200
  lua_assert(idx < fs->nlocvars);
icculus@0
   201
  return &fs->f->locvars[idx];
icculus@0
   202
}
icculus@0
   203
icculus@0
   204
icculus@0
   205
static void adjustlocalvars (LexState *ls, int nvars) {
icculus@0
   206
  FuncState *fs = ls->fs;
icculus@0
   207
  fs->nactvar = cast_byte(fs->nactvar + nvars);
icculus@0
   208
  for (; nvars; nvars--) {
icculus@0
   209
    getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
icculus@0
   210
  }
icculus@0
   211
}
icculus@0
   212
icculus@0
   213
icculus@0
   214
static void removevars (FuncState *fs, int tolevel) {
icculus@0
   215
  fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
icculus@0
   216
  while (fs->nactvar > tolevel)
icculus@0
   217
    getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
icculus@0
   218
}
icculus@0
   219
icculus@0
   220
icculus@0
   221
static int searchupvalue (FuncState *fs, TString *name) {
icculus@0
   222
  int i;
icculus@0
   223
  Upvaldesc *up = fs->f->upvalues;
icculus@0
   224
  for (i = 0; i < fs->nups; i++) {
icculus@0
   225
    if (luaS_eqstr(up[i].name, name)) return i;
icculus@0
   226
  }
icculus@0
   227
  return -1;  /* not found */
icculus@0
   228
}
icculus@0
   229
icculus@0
   230
icculus@0
   231
static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
icculus@0
   232
  Proto *f = fs->f;
icculus@0
   233
  int oldsize = f->sizeupvalues;
icculus@0
   234
  checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
icculus@0
   235
  luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
icculus@0
   236
                  Upvaldesc, MAXUPVAL, "upvalues");
icculus@0
   237
  while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
icculus@0
   238
  f->upvalues[fs->nups].instack = (v->k == VLOCAL);
icculus@0
   239
  f->upvalues[fs->nups].idx = cast_byte(v->u.info);
icculus@0
   240
  f->upvalues[fs->nups].name = name;
icculus@0
   241
  luaC_objbarrier(fs->ls->L, f, name);
icculus@0
   242
  return fs->nups++;
icculus@0
   243
}
icculus@0
   244
icculus@0
   245
icculus@0
   246
static int searchvar (FuncState *fs, TString *n) {
icculus@0
   247
  int i;
icculus@0
   248
  for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
icculus@0
   249
    if (luaS_eqstr(n, getlocvar(fs, i)->varname))
icculus@0
   250
      return i;
icculus@0
   251
  }
icculus@0
   252
  return -1;  /* not found */
icculus@0
   253
}
icculus@0
   254
icculus@0
   255
icculus@0
   256
/*
icculus@0
   257
  Mark block where variable at given level was defined
icculus@0
   258
  (to emit close instructions later).
icculus@0
   259
*/
icculus@0
   260
static void markupval (FuncState *fs, int level) {
icculus@0
   261
  BlockCnt *bl = fs->bl;
icculus@0
   262
  while (bl->nactvar > level) bl = bl->previous;
icculus@0
   263
  bl->upval = 1;
icculus@0
   264
}
icculus@0
   265
icculus@0
   266
icculus@0
   267
/*
icculus@0
   268
  Find variable with given name 'n'. If it is an upvalue, add this
icculus@0
   269
  upvalue into all intermediate functions.
icculus@0
   270
*/
icculus@0
   271
static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
icculus@0
   272
  if (fs == NULL)  /* no more levels? */
icculus@0
   273
    return VVOID;  /* default is global */
icculus@0
   274
  else {
icculus@0
   275
    int v = searchvar(fs, n);  /* look up locals at current level */
icculus@0
   276
    if (v >= 0) {  /* found? */
icculus@0
   277
      init_exp(var, VLOCAL, v);  /* variable is local */
icculus@0
   278
      if (!base)
icculus@0
   279
        markupval(fs, v);  /* local will be used as an upval */
icculus@0
   280
      return VLOCAL;
icculus@0
   281
    }
icculus@0
   282
    else {  /* not found as local at current level; try upvalues */
icculus@0
   283
      int idx = searchupvalue(fs, n);  /* try existing upvalues */
icculus@0
   284
      if (idx < 0) {  /* not found? */
icculus@0
   285
        if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
icculus@0
   286
          return VVOID;  /* not found; is a global */
icculus@0
   287
        /* else was LOCAL or UPVAL */
icculus@0
   288
        idx  = newupvalue(fs, n, var);  /* will be a new upvalue */
icculus@0
   289
      }
icculus@0
   290
      init_exp(var, VUPVAL, idx);
icculus@0
   291
      return VUPVAL;
icculus@0
   292
    }
icculus@0
   293
  }
icculus@0
   294
}
icculus@0
   295
icculus@0
   296
icculus@0
   297
static void singlevar (LexState *ls, expdesc *var) {
icculus@0
   298
  TString *varname = str_checkname(ls);
icculus@0
   299
  FuncState *fs = ls->fs;
icculus@0
   300
  if (singlevaraux(fs, varname, var, 1) == VVOID) {  /* global name? */
icculus@0
   301
    expdesc key;
icculus@0
   302
    singlevaraux(fs, ls->envn, var, 1);  /* get environment variable */
icculus@0
   303
    lua_assert(var->k == VLOCAL || var->k == VUPVAL);
icculus@0
   304
    codestring(ls, &key, varname);  /* key is variable name */
icculus@0
   305
    luaK_indexed(fs, var, &key);  /* env[varname] */
icculus@0
   306
  }
icculus@0
   307
}
icculus@0
   308
icculus@0
   309
icculus@0
   310
static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
icculus@0
   311
  FuncState *fs = ls->fs;
icculus@0
   312
  int extra = nvars - nexps;
icculus@0
   313
  if (hasmultret(e->k)) {
icculus@0
   314
    extra++;  /* includes call itself */
icculus@0
   315
    if (extra < 0) extra = 0;
icculus@0
   316
    luaK_setreturns(fs, e, extra);  /* last exp. provides the difference */
icculus@0
   317
    if (extra > 1) luaK_reserveregs(fs, extra-1);
icculus@0
   318
  }
icculus@0
   319
  else {
icculus@0
   320
    if (e->k != VVOID) luaK_exp2nextreg(fs, e);  /* close last expression */
icculus@0
   321
    if (extra > 0) {
icculus@0
   322
      int reg = fs->freereg;
icculus@0
   323
      luaK_reserveregs(fs, extra);
icculus@0
   324
      luaK_nil(fs, reg, extra);
icculus@0
   325
    }
icculus@0
   326
  }
icculus@0
   327
}
icculus@0
   328
icculus@0
   329
icculus@0
   330
static void enterlevel (LexState *ls) {
icculus@0
   331
  lua_State *L = ls->L;
icculus@0
   332
  ++L->nCcalls;
icculus@0
   333
  checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
icculus@0
   334
}
icculus@0
   335
icculus@0
   336
icculus@0
   337
#define leavelevel(ls)	((ls)->L->nCcalls--)
icculus@0
   338
icculus@0
   339
icculus@0
   340
static void closegoto (LexState *ls, int g, Labeldesc *label) {
icculus@0
   341
  int i;
icculus@0
   342
  FuncState *fs = ls->fs;
icculus@0
   343
  Labellist *gl = &ls->dyd->gt;
icculus@0
   344
  Labeldesc *gt = &gl->arr[g];
icculus@0
   345
  lua_assert(luaS_eqstr(gt->name, label->name));
icculus@0
   346
  if (gt->nactvar < label->nactvar) {
icculus@0
   347
    TString *vname = getlocvar(fs, gt->nactvar)->varname;
icculus@0
   348
    const char *msg = luaO_pushfstring(ls->L,
icculus@0
   349
      "<goto %s> at line %d jumps into the scope of local " LUA_QS,
icculus@0
   350
      getstr(gt->name), gt->line, getstr(vname));
icculus@0
   351
    semerror(ls, msg);
icculus@0
   352
  }
icculus@0
   353
  luaK_patchlist(fs, gt->pc, label->pc);
icculus@0
   354
  /* remove goto from pending list */
icculus@0
   355
  for (i = g; i < gl->n - 1; i++)
icculus@0
   356
    gl->arr[i] = gl->arr[i + 1];
icculus@0
   357
  gl->n--;
icculus@0
   358
}
icculus@0
   359
icculus@0
   360
icculus@0
   361
/*
icculus@0
   362
** try to close a goto with existing labels; this solves backward jumps
icculus@0
   363
*/
icculus@0
   364
static int findlabel (LexState *ls, int g) {
icculus@0
   365
  int i;
icculus@0
   366
  BlockCnt *bl = ls->fs->bl;
icculus@0
   367
  Dyndata *dyd = ls->dyd;
icculus@0
   368
  Labeldesc *gt = &dyd->gt.arr[g];
icculus@0
   369
  /* check labels in current block for a match */
icculus@0
   370
  for (i = bl->firstlabel; i < dyd->label.n; i++) {
icculus@0
   371
    Labeldesc *lb = &dyd->label.arr[i];
icculus@0
   372
    if (luaS_eqstr(lb->name, gt->name)) {  /* correct label? */
icculus@0
   373
      if (gt->nactvar > lb->nactvar &&
icculus@0
   374
          (bl->upval || dyd->label.n > bl->firstlabel))
icculus@0
   375
        luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
icculus@0
   376
      closegoto(ls, g, lb);  /* close it */
icculus@0
   377
      return 1;
icculus@0
   378
    }
icculus@0
   379
  }
icculus@0
   380
  return 0;  /* label not found; cannot close goto */
icculus@0
   381
}
icculus@0
   382
icculus@0
   383
icculus@0
   384
static int newlabelentry (LexState *ls, Labellist *l, TString *name,
icculus@0
   385
                          int line, int pc) {
icculus@0
   386
  int n = l->n;
icculus@0
   387
  luaM_growvector(ls->L, l->arr, n, l->size,
icculus@0
   388
                  Labeldesc, SHRT_MAX, "labels/gotos");
icculus@0
   389
  l->arr[n].name = name;
icculus@0
   390
  l->arr[n].line = line;
icculus@0
   391
  l->arr[n].nactvar = ls->fs->nactvar;
icculus@0
   392
  l->arr[n].pc = pc;
icculus@0
   393
  l->n++;
icculus@0
   394
  return n;
icculus@0
   395
}
icculus@0
   396
icculus@0
   397
icculus@0
   398
/*
icculus@0
   399
** check whether new label 'lb' matches any pending gotos in current
icculus@0
   400
** block; solves forward jumps
icculus@0
   401
*/
icculus@0
   402
static void findgotos (LexState *ls, Labeldesc *lb) {
icculus@0
   403
  Labellist *gl = &ls->dyd->gt;
icculus@0
   404
  int i = ls->fs->bl->firstgoto;
icculus@0
   405
  while (i < gl->n) {
icculus@0
   406
    if (luaS_eqstr(gl->arr[i].name, lb->name))
icculus@0
   407
      closegoto(ls, i, lb);
icculus@0
   408
    else
icculus@0
   409
      i++;
icculus@0
   410
  }
icculus@0
   411
}
icculus@0
   412
icculus@0
   413
icculus@0
   414
/*
icculus@0
   415
** "export" pending gotos to outer level, to check them against
icculus@0
   416
** outer labels; if the block being exited has upvalues, and
icculus@0
   417
** the goto exits the scope of any variable (which can be the
icculus@0
   418
** upvalue), close those variables being exited.
icculus@0
   419
*/
icculus@0
   420
static void movegotosout (FuncState *fs, BlockCnt *bl) {
icculus@0
   421
  int i = bl->firstgoto;
icculus@0
   422
  Labellist *gl = &fs->ls->dyd->gt;
icculus@0
   423
  /* correct pending gotos to current block and try to close it
icculus@0
   424
     with visible labels */
icculus@0
   425
  while (i < gl->n) {
icculus@0
   426
    Labeldesc *gt = &gl->arr[i];
icculus@0
   427
    if (gt->nactvar > bl->nactvar) {
icculus@0
   428
      if (bl->upval)
icculus@0
   429
        luaK_patchclose(fs, gt->pc, bl->nactvar);
icculus@0
   430
      gt->nactvar = bl->nactvar;
icculus@0
   431
    }
icculus@0
   432
    if (!findlabel(fs->ls, i))
icculus@0
   433
      i++;  /* move to next one */
icculus@0
   434
  }
icculus@0
   435
}
icculus@0
   436
icculus@0
   437
icculus@0
   438
static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
icculus@0
   439
  bl->isloop = isloop;
icculus@0
   440
  bl->nactvar = fs->nactvar;
icculus@0
   441
  bl->firstlabel = fs->ls->dyd->label.n;
icculus@0
   442
  bl->firstgoto = fs->ls->dyd->gt.n;
icculus@0
   443
  bl->upval = 0;
icculus@0
   444
  bl->previous = fs->bl;
icculus@0
   445
  fs->bl = bl;
icculus@0
   446
  lua_assert(fs->freereg == fs->nactvar);
icculus@0
   447
}
icculus@0
   448
icculus@0
   449
icculus@0
   450
/*
icculus@0
   451
** create a label named "break" to resolve break statements
icculus@0
   452
*/
icculus@0
   453
static void breaklabel (LexState *ls) {
icculus@0
   454
  TString *n = luaS_new(ls->L, "break");
icculus@0
   455
  int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc);
icculus@0
   456
  findgotos(ls, &ls->dyd->label.arr[l]);
icculus@0
   457
}
icculus@0
   458
icculus@0
   459
/*
icculus@0
   460
** generates an error for an undefined 'goto'; choose appropriate
icculus@0
   461
** message when label name is a reserved word (which can only be 'break')
icculus@0
   462
*/
icculus@0
   463
static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
icculus@0
   464
  const char *msg = isreserved(gt->name)
icculus@0
   465
                    ? "<%s> at line %d not inside a loop"
icculus@0
   466
                    : "no visible label " LUA_QS " for <goto> at line %d";
icculus@0
   467
  msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
icculus@0
   468
  semerror(ls, msg);
icculus@0
   469
}
icculus@0
   470
icculus@0
   471
icculus@0
   472
static void leaveblock (FuncState *fs) {
icculus@0
   473
  BlockCnt *bl = fs->bl;
icculus@0
   474
  LexState *ls = fs->ls;
icculus@0
   475
  if (bl->previous && bl->upval) {
icculus@0
   476
    /* create a 'jump to here' to close upvalues */
icculus@0
   477
    int j = luaK_jump(fs);
icculus@0
   478
    luaK_patchclose(fs, j, bl->nactvar);
icculus@0
   479
    luaK_patchtohere(fs, j);
icculus@0
   480
  }
icculus@0
   481
  if (bl->isloop)
icculus@0
   482
    breaklabel(ls);  /* close pending breaks */
icculus@0
   483
  fs->bl = bl->previous;
icculus@0
   484
  removevars(fs, bl->nactvar);
icculus@0
   485
  lua_assert(bl->nactvar == fs->nactvar);
icculus@0
   486
  fs->freereg = fs->nactvar;  /* free registers */
icculus@0
   487
  ls->dyd->label.n = bl->firstlabel;  /* remove local labels */
icculus@0
   488
  if (bl->previous)  /* inner block? */
icculus@0
   489
    movegotosout(fs, bl);  /* update pending gotos to outer block */
icculus@0
   490
  else if (bl->firstgoto < ls->dyd->gt.n)  /* pending gotos in outer block? */
icculus@0
   491
    undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]);  /* error */
icculus@0
   492
}
icculus@0
   493
icculus@0
   494
icculus@0
   495
/*
icculus@0
   496
** adds a new prototype into list of prototypes
icculus@0
   497
*/
icculus@0
   498
static Proto *addprototype (LexState *ls) {
icculus@0
   499
  Proto *clp;
icculus@0
   500
  lua_State *L = ls->L;
icculus@0
   501
  FuncState *fs = ls->fs;
icculus@0
   502
  Proto *f = fs->f;  /* prototype of current function */
icculus@0
   503
  if (fs->np >= f->sizep) {
icculus@0
   504
    int oldsize = f->sizep;
icculus@0
   505
    luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
icculus@0
   506
    while (oldsize < f->sizep) f->p[oldsize++] = NULL;
icculus@0
   507
  }
icculus@0
   508
  f->p[fs->np++] = clp = luaF_newproto(L);
icculus@0
   509
  luaC_objbarrier(L, f, clp);
icculus@0
   510
  return clp;
icculus@0
   511
}
icculus@0
   512
icculus@0
   513
icculus@0
   514
/*
icculus@0
   515
** codes instruction to create new closure in parent function.
icculus@0
   516
** The OP_CLOSURE instruction must use the last available register,
icculus@0
   517
** so that, if it invokes the GC, the GC knows which registers
icculus@0
   518
** are in use at that time.
icculus@0
   519
*/
icculus@0
   520
static void codeclosure (LexState *ls, expdesc *v) {
icculus@0
   521
  FuncState *fs = ls->fs->prev;
icculus@0
   522
  init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
icculus@0
   523
  luaK_exp2nextreg(fs, v);  /* fix it at the last register */
icculus@0
   524
}
icculus@0
   525
icculus@0
   526
icculus@0
   527
static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
icculus@0
   528
  lua_State *L = ls->L;
icculus@0
   529
  Proto *f;
icculus@0
   530
  fs->prev = ls->fs;  /* linked list of funcstates */
icculus@0
   531
  fs->ls = ls;
icculus@0
   532
  ls->fs = fs;
icculus@0
   533
  fs->pc = 0;
icculus@0
   534
  fs->lasttarget = 0;
icculus@0
   535
  fs->jpc = NO_JUMP;
icculus@0
   536
  fs->freereg = 0;
icculus@0
   537
  fs->nk = 0;
icculus@0
   538
  fs->np = 0;
icculus@0
   539
  fs->nups = 0;
icculus@0
   540
  fs->nlocvars = 0;
icculus@0
   541
  fs->nactvar = 0;
icculus@0
   542
  fs->firstlocal = ls->dyd->actvar.n;
icculus@0
   543
  fs->bl = NULL;
icculus@0
   544
  f = fs->f;
icculus@0
   545
  f->source = ls->source;
icculus@0
   546
  f->maxstacksize = 2;  /* registers 0/1 are always valid */
icculus@0
   547
  fs->h = luaH_new(L);
icculus@0
   548
  /* anchor table of constants (to avoid being collected) */
icculus@0
   549
  sethvalue2s(L, L->top, fs->h);
icculus@0
   550
  incr_top(L);
icculus@0
   551
  enterblock(fs, bl, 0);
icculus@0
   552
}
icculus@0
   553
icculus@0
   554
icculus@0
   555
static void close_func (LexState *ls) {
icculus@0
   556
  lua_State *L = ls->L;
icculus@0
   557
  FuncState *fs = ls->fs;
icculus@0
   558
  Proto *f = fs->f;
icculus@0
   559
  luaK_ret(fs, 0, 0);  /* final return */
icculus@0
   560
  leaveblock(fs);
icculus@0
   561
  luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
icculus@0
   562
  f->sizecode = fs->pc;
icculus@0
   563
  luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
icculus@0
   564
  f->sizelineinfo = fs->pc;
icculus@0
   565
  luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
icculus@0
   566
  f->sizek = fs->nk;
icculus@0
   567
  luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
icculus@0
   568
  f->sizep = fs->np;
icculus@0
   569
  luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
icculus@0
   570
  f->sizelocvars = fs->nlocvars;
icculus@0
   571
  luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
icculus@0
   572
  f->sizeupvalues = fs->nups;
icculus@0
   573
  lua_assert(fs->bl == NULL);
icculus@0
   574
  ls->fs = fs->prev;
icculus@0
   575
  /* last token read was anchored in defunct function; must re-anchor it */
icculus@0
   576
  anchor_token(ls);
icculus@0
   577
  L->top--;  /* pop table of constants */
icculus@0
   578
  luaC_checkGC(L);
icculus@0
   579
}
icculus@0
   580
icculus@0
   581
icculus@0
   582
icculus@0
   583
/*============================================================*/
icculus@0
   584
/* GRAMMAR RULES */
icculus@0
   585
/*============================================================*/
icculus@0
   586
icculus@0
   587
icculus@0
   588
/*
icculus@0
   589
** check whether current token is in the follow set of a block.
icculus@0
   590
** 'until' closes syntactical blocks, but do not close scope,
icculus@0
   591
** so it handled in separate.
icculus@0
   592
*/
icculus@0
   593
static int block_follow (LexState *ls, int withuntil) {
icculus@0
   594
  switch (ls->t.token) {
icculus@0
   595
    case TK_ELSE: case TK_ELSEIF:
icculus@0
   596
    case TK_END: case TK_EOS:
icculus@0
   597
      return 1;
icculus@0
   598
    case TK_UNTIL: return withuntil;
icculus@0
   599
    default: return 0;
icculus@0
   600
  }
icculus@0
   601
}
icculus@0
   602
icculus@0
   603
icculus@0
   604
static void statlist (LexState *ls) {
icculus@0
   605
  /* statlist -> { stat [`;'] } */
icculus@0
   606
  while (!block_follow(ls, 1)) {
icculus@0
   607
    if (ls->t.token == TK_RETURN) {
icculus@0
   608
      statement(ls);
icculus@0
   609
      return;  /* 'return' must be last statement */
icculus@0
   610
    }
icculus@0
   611
    statement(ls);
icculus@0
   612
  }
icculus@0
   613
}
icculus@0
   614
icculus@0
   615
icculus@0
   616
static void fieldsel (LexState *ls, expdesc *v) {
icculus@0
   617
  /* fieldsel -> ['.' | ':'] NAME */
icculus@0
   618
  FuncState *fs = ls->fs;
icculus@0
   619
  expdesc key;
icculus@0
   620
  luaK_exp2anyregup(fs, v);
icculus@0
   621
  luaX_next(ls);  /* skip the dot or colon */
icculus@0
   622
  checkname(ls, &key);
icculus@0
   623
  luaK_indexed(fs, v, &key);
icculus@0
   624
}
icculus@0
   625
icculus@0
   626
icculus@0
   627
static void yindex (LexState *ls, expdesc *v) {
icculus@0
   628
  /* index -> '[' expr ']' */
icculus@0
   629
  luaX_next(ls);  /* skip the '[' */
icculus@0
   630
  expr(ls, v);
icculus@0
   631
  luaK_exp2val(ls->fs, v);
icculus@0
   632
  checknext(ls, ']');
icculus@0
   633
}
icculus@0
   634
icculus@0
   635
icculus@0
   636
/*
icculus@0
   637
** {======================================================================
icculus@0
   638
** Rules for Constructors
icculus@0
   639
** =======================================================================
icculus@0
   640
*/
icculus@0
   641
icculus@0
   642
icculus@0
   643
struct ConsControl {
icculus@0
   644
  expdesc v;  /* last list item read */
icculus@0
   645
  expdesc *t;  /* table descriptor */
icculus@0
   646
  int nh;  /* total number of `record' elements */
icculus@0
   647
  int na;  /* total number of array elements */
icculus@0
   648
  int tostore;  /* number of array elements pending to be stored */
icculus@0
   649
};
icculus@0
   650
icculus@0
   651
icculus@0
   652
static void recfield (LexState *ls, struct ConsControl *cc) {
icculus@0
   653
  /* recfield -> (NAME | `['exp1`]') = exp1 */
icculus@0
   654
  FuncState *fs = ls->fs;
icculus@0
   655
  int reg = ls->fs->freereg;
icculus@0
   656
  expdesc key, val;
icculus@0
   657
  int rkkey;
icculus@0
   658
  if (ls->t.token == TK_NAME) {
icculus@0
   659
    checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
icculus@0
   660
    checkname(ls, &key);
icculus@0
   661
  }
icculus@0
   662
  else  /* ls->t.token == '[' */
icculus@0
   663
    yindex(ls, &key);
icculus@0
   664
  cc->nh++;
icculus@0
   665
  checknext(ls, '=');
icculus@0
   666
  rkkey = luaK_exp2RK(fs, &key);
icculus@0
   667
  expr(ls, &val);
icculus@0
   668
  luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));
icculus@0
   669
  fs->freereg = reg;  /* free registers */
icculus@0
   670
}
icculus@0
   671
icculus@0
   672
icculus@0
   673
static void closelistfield (FuncState *fs, struct ConsControl *cc) {
icculus@0
   674
  if (cc->v.k == VVOID) return;  /* there is no list item */
icculus@0
   675
  luaK_exp2nextreg(fs, &cc->v);
icculus@0
   676
  cc->v.k = VVOID;
icculus@0
   677
  if (cc->tostore == LFIELDS_PER_FLUSH) {
icculus@0
   678
    luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);  /* flush */
icculus@0
   679
    cc->tostore = 0;  /* no more items pending */
icculus@0
   680
  }
icculus@0
   681
}
icculus@0
   682
icculus@0
   683
icculus@0
   684
static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
icculus@0
   685
  if (cc->tostore == 0) return;
icculus@0
   686
  if (hasmultret(cc->v.k)) {
icculus@0
   687
    luaK_setmultret(fs, &cc->v);
icculus@0
   688
    luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
icculus@0
   689
    cc->na--;  /* do not count last expression (unknown number of elements) */
icculus@0
   690
  }
icculus@0
   691
  else {
icculus@0
   692
    if (cc->v.k != VVOID)
icculus@0
   693
      luaK_exp2nextreg(fs, &cc->v);
icculus@0
   694
    luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
icculus@0
   695
  }
icculus@0
   696
}
icculus@0
   697
icculus@0
   698
icculus@0
   699
static void listfield (LexState *ls, struct ConsControl *cc) {
icculus@0
   700
  /* listfield -> exp */
icculus@0
   701
  expr(ls, &cc->v);
icculus@0
   702
  checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
icculus@0
   703
  cc->na++;
icculus@0
   704
  cc->tostore++;
icculus@0
   705
}
icculus@0
   706
icculus@0
   707
icculus@0
   708
static void field (LexState *ls, struct ConsControl *cc) {
icculus@0
   709
  /* field -> listfield | recfield */
icculus@0
   710
  switch(ls->t.token) {
icculus@0
   711
    case TK_NAME: {  /* may be 'listfield' or 'recfield' */
icculus@0
   712
      if (luaX_lookahead(ls) != '=')  /* expression? */
icculus@0
   713
        listfield(ls, cc);
icculus@0
   714
      else
icculus@0
   715
        recfield(ls, cc);
icculus@0
   716
      break;
icculus@0
   717
    }
icculus@0
   718
    case '[': {
icculus@0
   719
      recfield(ls, cc);
icculus@0
   720
      break;
icculus@0
   721
    }
icculus@0
   722
    default: {
icculus@0
   723
      listfield(ls, cc);
icculus@0
   724
      break;
icculus@0
   725
    }
icculus@0
   726
  }
icculus@0
   727
}
icculus@0
   728
icculus@0
   729
icculus@0
   730
static void constructor (LexState *ls, expdesc *t) {
icculus@0
   731
  /* constructor -> '{' [ field { sep field } [sep] ] '}'
icculus@0
   732
     sep -> ',' | ';' */
icculus@0
   733
  FuncState *fs = ls->fs;
icculus@0
   734
  int line = ls->linenumber;
icculus@0
   735
  int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
icculus@0
   736
  struct ConsControl cc;
icculus@0
   737
  cc.na = cc.nh = cc.tostore = 0;
icculus@0
   738
  cc.t = t;
icculus@0
   739
  init_exp(t, VRELOCABLE, pc);
icculus@0
   740
  init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
icculus@0
   741
  luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top */
icculus@0
   742
  checknext(ls, '{');
icculus@0
   743
  do {
icculus@0
   744
    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
icculus@0
   745
    if (ls->t.token == '}') break;
icculus@0
   746
    closelistfield(fs, &cc);
icculus@0
   747
    field(ls, &cc);
icculus@0
   748
  } while (testnext(ls, ',') || testnext(ls, ';'));
icculus@0
   749
  check_match(ls, '}', '{', line);
icculus@0
   750
  lastlistfield(fs, &cc);
icculus@0
   751
  SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
icculus@0
   752
  SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh));  /* set initial table size */
icculus@0
   753
}
icculus@0
   754
icculus@0
   755
/* }====================================================================== */
icculus@0
   756
icculus@0
   757
icculus@0
   758
icculus@0
   759
static void parlist (LexState *ls) {
icculus@0
   760
  /* parlist -> [ param { `,' param } ] */
icculus@0
   761
  FuncState *fs = ls->fs;
icculus@0
   762
  Proto *f = fs->f;
icculus@0
   763
  int nparams = 0;
icculus@0
   764
  f->is_vararg = 0;
icculus@0
   765
  if (ls->t.token != ')') {  /* is `parlist' not empty? */
icculus@0
   766
    do {
icculus@0
   767
      switch (ls->t.token) {
icculus@0
   768
        case TK_NAME: {  /* param -> NAME */
icculus@0
   769
          new_localvar(ls, str_checkname(ls));
icculus@0
   770
          nparams++;
icculus@0
   771
          break;
icculus@0
   772
        }
icculus@0
   773
        case TK_DOTS: {  /* param -> `...' */
icculus@0
   774
          luaX_next(ls);
icculus@0
   775
          f->is_vararg = 1;
icculus@0
   776
          break;
icculus@0
   777
        }
icculus@0
   778
        default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
icculus@0
   779
      }
icculus@0
   780
    } while (!f->is_vararg && testnext(ls, ','));
icculus@0
   781
  }
icculus@0
   782
  adjustlocalvars(ls, nparams);
icculus@0
   783
  f->numparams = cast_byte(fs->nactvar);
icculus@0
   784
  luaK_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
icculus@0
   785
}
icculus@0
   786
icculus@0
   787
icculus@0
   788
static void body (LexState *ls, expdesc *e, int ismethod, int line) {
icculus@0
   789
  /* body ->  `(' parlist `)' block END */
icculus@0
   790
  FuncState new_fs;
icculus@0
   791
  BlockCnt bl;
icculus@0
   792
  new_fs.f = addprototype(ls);
icculus@0
   793
  new_fs.f->linedefined = line;
icculus@0
   794
  open_func(ls, &new_fs, &bl);
icculus@0
   795
  checknext(ls, '(');
icculus@0
   796
  if (ismethod) {
icculus@0
   797
    new_localvarliteral(ls, "self");  /* create 'self' parameter */
icculus@0
   798
    adjustlocalvars(ls, 1);
icculus@0
   799
  }
icculus@0
   800
  parlist(ls);
icculus@0
   801
  checknext(ls, ')');
icculus@0
   802
  statlist(ls);
icculus@0
   803
  new_fs.f->lastlinedefined = ls->linenumber;
icculus@0
   804
  check_match(ls, TK_END, TK_FUNCTION, line);
icculus@0
   805
  codeclosure(ls, e);
icculus@0
   806
  close_func(ls);
icculus@0
   807
}
icculus@0
   808
icculus@0
   809
icculus@0
   810
static int explist (LexState *ls, expdesc *v) {
icculus@0
   811
  /* explist -> expr { `,' expr } */
icculus@0
   812
  int n = 1;  /* at least one expression */
icculus@0
   813
  expr(ls, v);
icculus@0
   814
  while (testnext(ls, ',')) {
icculus@0
   815
    luaK_exp2nextreg(ls->fs, v);
icculus@0
   816
    expr(ls, v);
icculus@0
   817
    n++;
icculus@0
   818
  }
icculus@0
   819
  return n;
icculus@0
   820
}
icculus@0
   821
icculus@0
   822
icculus@0
   823
static void funcargs (LexState *ls, expdesc *f, int line) {
icculus@0
   824
  FuncState *fs = ls->fs;
icculus@0
   825
  expdesc args;
icculus@0
   826
  int base, nparams;
icculus@0
   827
  switch (ls->t.token) {
icculus@0
   828
    case '(': {  /* funcargs -> `(' [ explist ] `)' */
icculus@0
   829
      luaX_next(ls);
icculus@0
   830
      if (ls->t.token == ')')  /* arg list is empty? */
icculus@0
   831
        args.k = VVOID;
icculus@0
   832
      else {
icculus@0
   833
        explist(ls, &args);
icculus@0
   834
        luaK_setmultret(fs, &args);
icculus@0
   835
      }
icculus@0
   836
      check_match(ls, ')', '(', line);
icculus@0
   837
      break;
icculus@0
   838
    }
icculus@0
   839
    case '{': {  /* funcargs -> constructor */
icculus@0
   840
      constructor(ls, &args);
icculus@0
   841
      break;
icculus@0
   842
    }
icculus@0
   843
    case TK_STRING: {  /* funcargs -> STRING */
icculus@0
   844
      codestring(ls, &args, ls->t.seminfo.ts);
icculus@0
   845
      luaX_next(ls);  /* must use `seminfo' before `next' */
icculus@0
   846
      break;
icculus@0
   847
    }
icculus@0
   848
    default: {
icculus@0
   849
      luaX_syntaxerror(ls, "function arguments expected");
icculus@0
   850
    }
icculus@0
   851
  }
icculus@0
   852
  lua_assert(f->k == VNONRELOC);
icculus@0
   853
  base = f->u.info;  /* base register for call */
icculus@0
   854
  if (hasmultret(args.k))
icculus@0
   855
    nparams = LUA_MULTRET;  /* open call */
icculus@0
   856
  else {
icculus@0
   857
    if (args.k != VVOID)
icculus@0
   858
      luaK_exp2nextreg(fs, &args);  /* close last argument */
icculus@0
   859
    nparams = fs->freereg - (base+1);
icculus@0
   860
  }
icculus@0
   861
  init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
icculus@0
   862
  luaK_fixline(fs, line);
icculus@0
   863
  fs->freereg = base+1;  /* call remove function and arguments and leaves
icculus@0
   864
                            (unless changed) one result */
icculus@0
   865
}
icculus@0
   866
icculus@0
   867
icculus@0
   868
icculus@0
   869
icculus@0
   870
/*
icculus@0
   871
** {======================================================================
icculus@0
   872
** Expression parsing
icculus@0
   873
** =======================================================================
icculus@0
   874
*/
icculus@0
   875
icculus@0
   876
icculus@0
   877
static void primaryexp (LexState *ls, expdesc *v) {
icculus@0
   878
  /* primaryexp -> NAME | '(' expr ')' */
icculus@0
   879
  switch (ls->t.token) {
icculus@0
   880
    case '(': {
icculus@0
   881
      int line = ls->linenumber;
icculus@0
   882
      luaX_next(ls);
icculus@0
   883
      expr(ls, v);
icculus@0
   884
      check_match(ls, ')', '(', line);
icculus@0
   885
      luaK_dischargevars(ls->fs, v);
icculus@0
   886
      return;
icculus@0
   887
    }
icculus@0
   888
    case TK_NAME: {
icculus@0
   889
      singlevar(ls, v);
icculus@0
   890
      return;
icculus@0
   891
    }
icculus@0
   892
    default: {
icculus@0
   893
      luaX_syntaxerror(ls, "unexpected symbol");
icculus@0
   894
    }
icculus@0
   895
  }
icculus@0
   896
}
icculus@0
   897
icculus@0
   898
icculus@0
   899
static void suffixedexp (LexState *ls, expdesc *v) {
icculus@0
   900
  /* suffixedexp ->
icculus@0
   901
       primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
icculus@0
   902
  FuncState *fs = ls->fs;
icculus@0
   903
  int line = ls->linenumber;
icculus@0
   904
  primaryexp(ls, v);
icculus@0
   905
  for (;;) {
icculus@0
   906
    switch (ls->t.token) {
icculus@0
   907
      case '.': {  /* fieldsel */
icculus@0
   908
        fieldsel(ls, v);
icculus@0
   909
        break;
icculus@0
   910
      }
icculus@0
   911
      case '[': {  /* `[' exp1 `]' */
icculus@0
   912
        expdesc key;
icculus@0
   913
        luaK_exp2anyregup(fs, v);
icculus@0
   914
        yindex(ls, &key);
icculus@0
   915
        luaK_indexed(fs, v, &key);
icculus@0
   916
        break;
icculus@0
   917
      }
icculus@0
   918
      case ':': {  /* `:' NAME funcargs */
icculus@0
   919
        expdesc key;
icculus@0
   920
        luaX_next(ls);
icculus@0
   921
        checkname(ls, &key);
icculus@0
   922
        luaK_self(fs, v, &key);
icculus@0
   923
        funcargs(ls, v, line);
icculus@0
   924
        break;
icculus@0
   925
      }
icculus@0
   926
      case '(': case TK_STRING: case '{': {  /* funcargs */
icculus@0
   927
        luaK_exp2nextreg(fs, v);
icculus@0
   928
        funcargs(ls, v, line);
icculus@0
   929
        break;
icculus@0
   930
      }
icculus@0
   931
      default: return;
icculus@0
   932
    }
icculus@0
   933
  }
icculus@0
   934
}
icculus@0
   935
icculus@0
   936
icculus@0
   937
static void simpleexp (LexState *ls, expdesc *v) {
icculus@0
   938
  /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
icculus@0
   939
                  constructor | FUNCTION body | suffixedexp */
icculus@0
   940
  switch (ls->t.token) {
icculus@0
   941
    case TK_NUMBER: {
icculus@0
   942
      init_exp(v, VKNUM, 0);
icculus@0
   943
      v->u.nval = ls->t.seminfo.r;
icculus@0
   944
      break;
icculus@0
   945
    }
icculus@0
   946
    case TK_STRING: {
icculus@0
   947
      codestring(ls, v, ls->t.seminfo.ts);
icculus@0
   948
      break;
icculus@0
   949
    }
icculus@0
   950
    case TK_NIL: {
icculus@0
   951
      init_exp(v, VNIL, 0);
icculus@0
   952
      break;
icculus@0
   953
    }
icculus@0
   954
    case TK_TRUE: {
icculus@0
   955
      init_exp(v, VTRUE, 0);
icculus@0
   956
      break;
icculus@0
   957
    }
icculus@0
   958
    case TK_FALSE: {
icculus@0
   959
      init_exp(v, VFALSE, 0);
icculus@0
   960
      break;
icculus@0
   961
    }
icculus@0
   962
    case TK_DOTS: {  /* vararg */
icculus@0
   963
      FuncState *fs = ls->fs;
icculus@0
   964
      check_condition(ls, fs->f->is_vararg,
icculus@0
   965
                      "cannot use " LUA_QL("...") " outside a vararg function");
icculus@0
   966
      init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
icculus@0
   967
      break;
icculus@0
   968
    }
icculus@0
   969
    case '{': {  /* constructor */
icculus@0
   970
      constructor(ls, v);
icculus@0
   971
      return;
icculus@0
   972
    }
icculus@0
   973
    case TK_FUNCTION: {
icculus@0
   974
      luaX_next(ls);
icculus@0
   975
      body(ls, v, 0, ls->linenumber);
icculus@0
   976
      return;
icculus@0
   977
    }
icculus@0
   978
    default: {
icculus@0
   979
      suffixedexp(ls, v);
icculus@0
   980
      return;
icculus@0
   981
    }
icculus@0
   982
  }
icculus@0
   983
  luaX_next(ls);
icculus@0
   984
}
icculus@0
   985
icculus@0
   986
icculus@0
   987
static UnOpr getunopr (int op) {
icculus@0
   988
  switch (op) {
icculus@0
   989
    case TK_NOT: return OPR_NOT;
icculus@0
   990
    case '-': return OPR_MINUS;
icculus@0
   991
    case '#': return OPR_LEN;
icculus@0
   992
    default: return OPR_NOUNOPR;
icculus@0
   993
  }
icculus@0
   994
}
icculus@0
   995
icculus@0
   996
icculus@0
   997
static BinOpr getbinopr (int op) {
icculus@0
   998
  switch (op) {
icculus@0
   999
    case '+': return OPR_ADD;
icculus@0
  1000
    case '-': return OPR_SUB;
icculus@0
  1001
    case '*': return OPR_MUL;
icculus@0
  1002
    case '/': return OPR_DIV;
icculus@0
  1003
    case '%': return OPR_MOD;
icculus@0
  1004
    case '^': return OPR_POW;
icculus@0
  1005
    case TK_CONCAT: return OPR_CONCAT;
icculus@0
  1006
    case TK_NE: return OPR_NE;
icculus@0
  1007
    case TK_EQ: return OPR_EQ;
icculus@0
  1008
    case '<': return OPR_LT;
icculus@0
  1009
    case TK_LE: return OPR_LE;
icculus@0
  1010
    case '>': return OPR_GT;
icculus@0
  1011
    case TK_GE: return OPR_GE;
icculus@0
  1012
    case TK_AND: return OPR_AND;
icculus@0
  1013
    case TK_OR: return OPR_OR;
icculus@0
  1014
    default: return OPR_NOBINOPR;
icculus@0
  1015
  }
icculus@0
  1016
}
icculus@0
  1017
icculus@0
  1018
icculus@0
  1019
static const struct {
icculus@0
  1020
  lu_byte left;  /* left priority for each binary operator */
icculus@0
  1021
  lu_byte right; /* right priority */
icculus@0
  1022
} priority[] = {  /* ORDER OPR */
icculus@0
  1023
   {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7},  /* `+' `-' `*' `/' `%' */
icculus@0
  1024
   {10, 9}, {5, 4},                 /* ^, .. (right associative) */
icculus@0
  1025
   {3, 3}, {3, 3}, {3, 3},          /* ==, <, <= */
icculus@0
  1026
   {3, 3}, {3, 3}, {3, 3},          /* ~=, >, >= */
icculus@0
  1027
   {2, 2}, {1, 1}                   /* and, or */
icculus@0
  1028
};
icculus@0
  1029
icculus@0
  1030
#define UNARY_PRIORITY	8  /* priority for unary operators */
icculus@0
  1031
icculus@0
  1032
icculus@0
  1033
/*
icculus@0
  1034
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
icculus@0
  1035
** where `binop' is any binary operator with a priority higher than `limit'
icculus@0
  1036
*/
icculus@0
  1037
static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
icculus@0
  1038
  BinOpr op;
icculus@0
  1039
  UnOpr uop;
icculus@0
  1040
  enterlevel(ls);
icculus@0
  1041
  uop = getunopr(ls->t.token);
icculus@0
  1042
  if (uop != OPR_NOUNOPR) {
icculus@0
  1043
    int line = ls->linenumber;
icculus@0
  1044
    luaX_next(ls);
icculus@0
  1045
    subexpr(ls, v, UNARY_PRIORITY);
icculus@0
  1046
    luaK_prefix(ls->fs, uop, v, line);
icculus@0
  1047
  }
icculus@0
  1048
  else simpleexp(ls, v);
icculus@0
  1049
  /* expand while operators have priorities higher than `limit' */
icculus@0
  1050
  op = getbinopr(ls->t.token);
icculus@0
  1051
  while (op != OPR_NOBINOPR && priority[op].left > limit) {
icculus@0
  1052
    expdesc v2;
icculus@0
  1053
    BinOpr nextop;
icculus@0
  1054
    int line = ls->linenumber;
icculus@0
  1055
    luaX_next(ls);
icculus@0
  1056
    luaK_infix(ls->fs, op, v);
icculus@0
  1057
    /* read sub-expression with higher priority */
icculus@0
  1058
    nextop = subexpr(ls, &v2, priority[op].right);
icculus@0
  1059
    luaK_posfix(ls->fs, op, v, &v2, line);
icculus@0
  1060
    op = nextop;
icculus@0
  1061
  }
icculus@0
  1062
  leavelevel(ls);
icculus@0
  1063
  return op;  /* return first untreated operator */
icculus@0
  1064
}
icculus@0
  1065
icculus@0
  1066
icculus@0
  1067
static void expr (LexState *ls, expdesc *v) {
icculus@0
  1068
  subexpr(ls, v, 0);
icculus@0
  1069
}
icculus@0
  1070
icculus@0
  1071
/* }==================================================================== */
icculus@0
  1072
icculus@0
  1073
icculus@0
  1074
icculus@0
  1075
/*
icculus@0
  1076
** {======================================================================
icculus@0
  1077
** Rules for Statements
icculus@0
  1078
** =======================================================================
icculus@0
  1079
*/
icculus@0
  1080
icculus@0
  1081
icculus@0
  1082
static void block (LexState *ls) {
icculus@0
  1083
  /* block -> statlist */
icculus@0
  1084
  FuncState *fs = ls->fs;
icculus@0
  1085
  BlockCnt bl;
icculus@0
  1086
  enterblock(fs, &bl, 0);
icculus@0
  1087
  statlist(ls);
icculus@0
  1088
  leaveblock(fs);
icculus@0
  1089
}
icculus@0
  1090
icculus@0
  1091
icculus@0
  1092
/*
icculus@0
  1093
** structure to chain all variables in the left-hand side of an
icculus@0
  1094
** assignment
icculus@0
  1095
*/
icculus@0
  1096
struct LHS_assign {
icculus@0
  1097
  struct LHS_assign *prev;
icculus@0
  1098
  expdesc v;  /* variable (global, local, upvalue, or indexed) */
icculus@0
  1099
};
icculus@0
  1100
icculus@0
  1101
icculus@0
  1102
/*
icculus@0
  1103
** check whether, in an assignment to an upvalue/local variable, the
icculus@0
  1104
** upvalue/local variable is begin used in a previous assignment to a
icculus@0
  1105
** table. If so, save original upvalue/local value in a safe place and
icculus@0
  1106
** use this safe copy in the previous assignment.
icculus@0
  1107
*/
icculus@0
  1108
static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
icculus@0
  1109
  FuncState *fs = ls->fs;
icculus@0
  1110
  int extra = fs->freereg;  /* eventual position to save local variable */
icculus@0
  1111
  int conflict = 0;
icculus@0
  1112
  for (; lh; lh = lh->prev) {  /* check all previous assignments */
icculus@0
  1113
    if (lh->v.k == VINDEXED) {  /* assigning to a table? */
icculus@0
  1114
      /* table is the upvalue/local being assigned now? */
icculus@0
  1115
      if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
icculus@0
  1116
        conflict = 1;
icculus@0
  1117
        lh->v.u.ind.vt = VLOCAL;
icculus@0
  1118
        lh->v.u.ind.t = extra;  /* previous assignment will use safe copy */
icculus@0
  1119
      }
icculus@0
  1120
      /* index is the local being assigned? (index cannot be upvalue) */
icculus@0
  1121
      if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
icculus@0
  1122
        conflict = 1;
icculus@0
  1123
        lh->v.u.ind.idx = extra;  /* previous assignment will use safe copy */
icculus@0
  1124
      }
icculus@0
  1125
    }
icculus@0
  1126
  }
icculus@0
  1127
  if (conflict) {
icculus@0
  1128
    /* copy upvalue/local value to a temporary (in position 'extra') */
icculus@0
  1129
    OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
icculus@0
  1130
    luaK_codeABC(fs, op, extra, v->u.info, 0);
icculus@0
  1131
    luaK_reserveregs(fs, 1);
icculus@0
  1132
  }
icculus@0
  1133
}
icculus@0
  1134
icculus@0
  1135
icculus@0
  1136
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
icculus@0
  1137
  expdesc e;
icculus@0
  1138
  check_condition(ls, vkisvar(lh->v.k), "syntax error");
icculus@0
  1139
  if (testnext(ls, ',')) {  /* assignment -> ',' suffixedexp assignment */
icculus@0
  1140
    struct LHS_assign nv;
icculus@0
  1141
    nv.prev = lh;
icculus@0
  1142
    suffixedexp(ls, &nv.v);
icculus@0
  1143
    if (nv.v.k != VINDEXED)
icculus@0
  1144
      check_conflict(ls, lh, &nv.v);
icculus@0
  1145
    checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
icculus@0
  1146
                    "C levels");
icculus@0
  1147
    assignment(ls, &nv, nvars+1);
icculus@0
  1148
  }
icculus@0
  1149
  else {  /* assignment -> `=' explist */
icculus@0
  1150
    int nexps;
icculus@0
  1151
    checknext(ls, '=');
icculus@0
  1152
    nexps = explist(ls, &e);
icculus@0
  1153
    if (nexps != nvars) {
icculus@0
  1154
      adjust_assign(ls, nvars, nexps, &e);
icculus@0
  1155
      if (nexps > nvars)
icculus@0
  1156
        ls->fs->freereg -= nexps - nvars;  /* remove extra values */
icculus@0
  1157
    }
icculus@0
  1158
    else {
icculus@0
  1159
      luaK_setoneret(ls->fs, &e);  /* close last expression */
icculus@0
  1160
      luaK_storevar(ls->fs, &lh->v, &e);
icculus@0
  1161
      return;  /* avoid default */
icculus@0
  1162
    }
icculus@0
  1163
  }
icculus@0
  1164
  init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
icculus@0
  1165
  luaK_storevar(ls->fs, &lh->v, &e);
icculus@0
  1166
}
icculus@0
  1167
icculus@0
  1168
icculus@0
  1169
static int cond (LexState *ls) {
icculus@0
  1170
  /* cond -> exp */
icculus@0
  1171
  expdesc v;
icculus@0
  1172
  expr(ls, &v);  /* read condition */
icculus@0
  1173
  if (v.k == VNIL) v.k = VFALSE;  /* `falses' are all equal here */
icculus@0
  1174
  luaK_goiftrue(ls->fs, &v);
icculus@0
  1175
  return v.f;
icculus@0
  1176
}
icculus@0
  1177
icculus@0
  1178
icculus@0
  1179
static void gotostat (LexState *ls, int pc) {
icculus@0
  1180
  int line = ls->linenumber;
icculus@0
  1181
  TString *label;
icculus@0
  1182
  int g;
icculus@0
  1183
  if (testnext(ls, TK_GOTO))
icculus@0
  1184
    label = str_checkname(ls);
icculus@0
  1185
  else {
icculus@0
  1186
    luaX_next(ls);  /* skip break */
icculus@0
  1187
    label = luaS_new(ls->L, "break");
icculus@0
  1188
  }
icculus@0
  1189
  g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
icculus@0
  1190
  findlabel(ls, g);  /* close it if label already defined */
icculus@0
  1191
}
icculus@0
  1192
icculus@0
  1193
icculus@0
  1194
/* check for repeated labels on the same block */
icculus@0
  1195
static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
icculus@0
  1196
  int i;
icculus@0
  1197
  for (i = fs->bl->firstlabel; i < ll->n; i++) {
icculus@0
  1198
    if (luaS_eqstr(label, ll->arr[i].name)) {
icculus@0
  1199
      const char *msg = luaO_pushfstring(fs->ls->L,
icculus@0
  1200
                          "label " LUA_QS " already defined on line %d",
icculus@0
  1201
                          getstr(label), ll->arr[i].line);
icculus@0
  1202
      semerror(fs->ls, msg);
icculus@0
  1203
    }
icculus@0
  1204
  }
icculus@0
  1205
}
icculus@0
  1206
icculus@0
  1207
icculus@0
  1208
/* skip no-op statements */
icculus@0
  1209
static void skipnoopstat (LexState *ls) {
icculus@0
  1210
  while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
icculus@0
  1211
    statement(ls);
icculus@0
  1212
}
icculus@0
  1213
icculus@0
  1214
icculus@0
  1215
static void labelstat (LexState *ls, TString *label, int line) {
icculus@0
  1216
  /* label -> '::' NAME '::' */
icculus@0
  1217
  FuncState *fs = ls->fs;
icculus@0
  1218
  Labellist *ll = &ls->dyd->label;
icculus@0
  1219
  int l;  /* index of new label being created */
icculus@0
  1220
  checkrepeated(fs, ll, label);  /* check for repeated labels */
icculus@0
  1221
  checknext(ls, TK_DBCOLON);  /* skip double colon */
icculus@0
  1222
  /* create new entry for this label */
icculus@0
  1223
  l = newlabelentry(ls, ll, label, line, fs->pc);
icculus@0
  1224
  skipnoopstat(ls);  /* skip other no-op statements */
icculus@0
  1225
  if (block_follow(ls, 0)) {  /* label is last no-op statement in the block? */
icculus@0
  1226
    /* assume that locals are already out of scope */
icculus@0
  1227
    ll->arr[l].nactvar = fs->bl->nactvar;
icculus@0
  1228
  }
icculus@0
  1229
  findgotos(ls, &ll->arr[l]);
icculus@0
  1230
}
icculus@0
  1231
icculus@0
  1232
icculus@0
  1233
static void whilestat (LexState *ls, int line) {
icculus@0
  1234
  /* whilestat -> WHILE cond DO block END */
icculus@0
  1235
  FuncState *fs = ls->fs;
icculus@0
  1236
  int whileinit;
icculus@0
  1237
  int condexit;
icculus@0
  1238
  BlockCnt bl;
icculus@0
  1239
  luaX_next(ls);  /* skip WHILE */
icculus@0
  1240
  whileinit = luaK_getlabel(fs);
icculus@0
  1241
  condexit = cond(ls);
icculus@0
  1242
  enterblock(fs, &bl, 1);
icculus@0
  1243
  checknext(ls, TK_DO);
icculus@0
  1244
  block(ls);
icculus@0
  1245
  luaK_jumpto(fs, whileinit);
icculus@0
  1246
  check_match(ls, TK_END, TK_WHILE, line);
icculus@0
  1247
  leaveblock(fs);
icculus@0
  1248
  luaK_patchtohere(fs, condexit);  /* false conditions finish the loop */
icculus@0
  1249
}
icculus@0
  1250
icculus@0
  1251
icculus@0
  1252
static void repeatstat (LexState *ls, int line) {
icculus@0
  1253
  /* repeatstat -> REPEAT block UNTIL cond */
icculus@0
  1254
  int condexit;
icculus@0
  1255
  FuncState *fs = ls->fs;
icculus@0
  1256
  int repeat_init = luaK_getlabel(fs);
icculus@0
  1257
  BlockCnt bl1, bl2;
icculus@0
  1258
  enterblock(fs, &bl1, 1);  /* loop block */
icculus@0
  1259
  enterblock(fs, &bl2, 0);  /* scope block */
icculus@0
  1260
  luaX_next(ls);  /* skip REPEAT */
icculus@0
  1261
  statlist(ls);
icculus@0
  1262
  check_match(ls, TK_UNTIL, TK_REPEAT, line);
icculus@0
  1263
  condexit = cond(ls);  /* read condition (inside scope block) */
icculus@0
  1264
  if (bl2.upval)  /* upvalues? */
icculus@0
  1265
    luaK_patchclose(fs, condexit, bl2.nactvar);
icculus@0
  1266
  leaveblock(fs);  /* finish scope */
icculus@0
  1267
  luaK_patchlist(fs, condexit, repeat_init);  /* close the loop */
icculus@0
  1268
  leaveblock(fs);  /* finish loop */
icculus@0
  1269
}
icculus@0
  1270
icculus@0
  1271
icculus@0
  1272
static int exp1 (LexState *ls) {
icculus@0
  1273
  expdesc e;
icculus@0
  1274
  int reg;
icculus@0
  1275
  expr(ls, &e);
icculus@0
  1276
  luaK_exp2nextreg(ls->fs, &e);
icculus@0
  1277
  lua_assert(e.k == VNONRELOC);
icculus@0
  1278
  reg = e.u.info;
icculus@0
  1279
  return reg;
icculus@0
  1280
}
icculus@0
  1281
icculus@0
  1282
icculus@0
  1283
static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
icculus@0
  1284
  /* forbody -> DO block */
icculus@0
  1285
  BlockCnt bl;
icculus@0
  1286
  FuncState *fs = ls->fs;
icculus@0
  1287
  int prep, endfor;
icculus@0
  1288
  adjustlocalvars(ls, 3);  /* control variables */
icculus@0
  1289
  checknext(ls, TK_DO);
icculus@0
  1290
  prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
icculus@0
  1291
  enterblock(fs, &bl, 0);  /* scope for declared variables */
icculus@0
  1292
  adjustlocalvars(ls, nvars);
icculus@0
  1293
  luaK_reserveregs(fs, nvars);
icculus@0
  1294
  block(ls);
icculus@0
  1295
  leaveblock(fs);  /* end of scope for declared variables */
icculus@0
  1296
  luaK_patchtohere(fs, prep);
icculus@0
  1297
  if (isnum)  /* numeric for? */
icculus@0
  1298
    endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);
icculus@0
  1299
  else {  /* generic for */
icculus@0
  1300
    luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
icculus@0
  1301
    luaK_fixline(fs, line);
icculus@0
  1302
    endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);
icculus@0
  1303
  }
icculus@0
  1304
  luaK_patchlist(fs, endfor, prep + 1);
icculus@0
  1305
  luaK_fixline(fs, line);
icculus@0
  1306
}
icculus@0
  1307
icculus@0
  1308
icculus@0
  1309
static void fornum (LexState *ls, TString *varname, int line) {
icculus@0
  1310
  /* fornum -> NAME = exp1,exp1[,exp1] forbody */
icculus@0
  1311
  FuncState *fs = ls->fs;
icculus@0
  1312
  int base = fs->freereg;
icculus@0
  1313
  new_localvarliteral(ls, "(for index)");
icculus@0
  1314
  new_localvarliteral(ls, "(for limit)");
icculus@0
  1315
  new_localvarliteral(ls, "(for step)");
icculus@0
  1316
  new_localvar(ls, varname);
icculus@0
  1317
  checknext(ls, '=');
icculus@0
  1318
  exp1(ls);  /* initial value */
icculus@0
  1319
  checknext(ls, ',');
icculus@0
  1320
  exp1(ls);  /* limit */
icculus@0
  1321
  if (testnext(ls, ','))
icculus@0
  1322
    exp1(ls);  /* optional step */
icculus@0
  1323
  else {  /* default step = 1 */
icculus@0
  1324
    luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1));
icculus@0
  1325
    luaK_reserveregs(fs, 1);
icculus@0
  1326
  }
icculus@0
  1327
  forbody(ls, base, line, 1, 1);
icculus@0
  1328
}
icculus@0
  1329
icculus@0
  1330
icculus@0
  1331
static void forlist (LexState *ls, TString *indexname) {
icculus@0
  1332
  /* forlist -> NAME {,NAME} IN explist forbody */
icculus@0
  1333
  FuncState *fs = ls->fs;
icculus@0
  1334
  expdesc e;
icculus@0
  1335
  int nvars = 4;  /* gen, state, control, plus at least one declared var */
icculus@0
  1336
  int line;
icculus@0
  1337
  int base = fs->freereg;
icculus@0
  1338
  /* create control variables */
icculus@0
  1339
  new_localvarliteral(ls, "(for generator)");
icculus@0
  1340
  new_localvarliteral(ls, "(for state)");
icculus@0
  1341
  new_localvarliteral(ls, "(for control)");
icculus@0
  1342
  /* create declared variables */
icculus@0
  1343
  new_localvar(ls, indexname);
icculus@0
  1344
  while (testnext(ls, ',')) {
icculus@0
  1345
    new_localvar(ls, str_checkname(ls));
icculus@0
  1346
    nvars++;
icculus@0
  1347
  }
icculus@0
  1348
  checknext(ls, TK_IN);
icculus@0
  1349
  line = ls->linenumber;
icculus@0
  1350
  adjust_assign(ls, 3, explist(ls, &e), &e);
icculus@0
  1351
  luaK_checkstack(fs, 3);  /* extra space to call generator */
icculus@0
  1352
  forbody(ls, base, line, nvars - 3, 0);
icculus@0
  1353
}
icculus@0
  1354
icculus@0
  1355
icculus@0
  1356
static void forstat (LexState *ls, int line) {
icculus@0
  1357
  /* forstat -> FOR (fornum | forlist) END */
icculus@0
  1358
  FuncState *fs = ls->fs;
icculus@0
  1359
  TString *varname;
icculus@0
  1360
  BlockCnt bl;
icculus@0
  1361
  enterblock(fs, &bl, 1);  /* scope for loop and control variables */
icculus@0
  1362
  luaX_next(ls);  /* skip `for' */
icculus@0
  1363
  varname = str_checkname(ls);  /* first variable name */
icculus@0
  1364
  switch (ls->t.token) {
icculus@0
  1365
    case '=': fornum(ls, varname, line); break;
icculus@0
  1366
    case ',': case TK_IN: forlist(ls, varname); break;
icculus@0
  1367
    default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
icculus@0
  1368
  }
icculus@0
  1369
  check_match(ls, TK_END, TK_FOR, line);
icculus@0
  1370
  leaveblock(fs);  /* loop scope (`break' jumps to this point) */
icculus@0
  1371
}
icculus@0
  1372
icculus@0
  1373
icculus@0
  1374
static void test_then_block (LexState *ls, int *escapelist) {
icculus@0
  1375
  /* test_then_block -> [IF | ELSEIF] cond THEN block */
icculus@0
  1376
  BlockCnt bl;
icculus@0
  1377
  FuncState *fs = ls->fs;
icculus@0
  1378
  expdesc v;
icculus@0
  1379
  int jf;  /* instruction to skip 'then' code (if condition is false) */
icculus@0
  1380
  luaX_next(ls);  /* skip IF or ELSEIF */
icculus@0
  1381
  expr(ls, &v);  /* read condition */
icculus@0
  1382
  checknext(ls, TK_THEN);
icculus@0
  1383
  if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
icculus@0
  1384
    luaK_goiffalse(ls->fs, &v);  /* will jump to label if condition is true */
icculus@0
  1385
    enterblock(fs, &bl, 0);  /* must enter block before 'goto' */
icculus@0
  1386
    gotostat(ls, v.t);  /* handle goto/break */
icculus@0
  1387
    skipnoopstat(ls);  /* skip other no-op statements */
icculus@0
  1388
    if (block_follow(ls, 0)) {  /* 'goto' is the entire block? */
icculus@0
  1389
      leaveblock(fs);
icculus@0
  1390
      return;  /* and that is it */
icculus@0
  1391
    }
icculus@0
  1392
    else  /* must skip over 'then' part if condition is false */
icculus@0
  1393
      jf = luaK_jump(fs);
icculus@0
  1394
  }
icculus@0
  1395
  else {  /* regular case (not goto/break) */
icculus@0
  1396
    luaK_goiftrue(ls->fs, &v);  /* skip over block if condition is false */
icculus@0
  1397
    enterblock(fs, &bl, 0);
icculus@0
  1398
    jf = v.f;
icculus@0
  1399
  }
icculus@0
  1400
  statlist(ls);  /* `then' part */
icculus@0
  1401
  leaveblock(fs);
icculus@0
  1402
  if (ls->t.token == TK_ELSE ||
icculus@0
  1403
      ls->t.token == TK_ELSEIF)  /* followed by 'else'/'elseif'? */
icculus@0
  1404
    luaK_concat(fs, escapelist, luaK_jump(fs));  /* must jump over it */
icculus@0
  1405
  luaK_patchtohere(fs, jf);
icculus@0
  1406
}
icculus@0
  1407
icculus@0
  1408
icculus@0
  1409
static void ifstat (LexState *ls, int line) {
icculus@0
  1410
  /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
icculus@0
  1411
  FuncState *fs = ls->fs;
icculus@0
  1412
  int escapelist = NO_JUMP;  /* exit list for finished parts */
icculus@0
  1413
  test_then_block(ls, &escapelist);  /* IF cond THEN block */
icculus@0
  1414
  while (ls->t.token == TK_ELSEIF)
icculus@0
  1415
    test_then_block(ls, &escapelist);  /* ELSEIF cond THEN block */
icculus@0
  1416
  if (testnext(ls, TK_ELSE))
icculus@0
  1417
    block(ls);  /* `else' part */
icculus@0
  1418
  check_match(ls, TK_END, TK_IF, line);
icculus@0
  1419
  luaK_patchtohere(fs, escapelist);  /* patch escape list to 'if' end */
icculus@0
  1420
}
icculus@0
  1421
icculus@0
  1422
icculus@0
  1423
static void localfunc (LexState *ls) {
icculus@0
  1424
  expdesc b;
icculus@0
  1425
  FuncState *fs = ls->fs;
icculus@0
  1426
  new_localvar(ls, str_checkname(ls));  /* new local variable */
icculus@0
  1427
  adjustlocalvars(ls, 1);  /* enter its scope */
icculus@0
  1428
  body(ls, &b, 0, ls->linenumber);  /* function created in next register */
icculus@0
  1429
  /* debug information will only see the variable after this point! */
icculus@0
  1430
  getlocvar(fs, b.u.info)->startpc = fs->pc;
icculus@0
  1431
}
icculus@0
  1432
icculus@0
  1433
icculus@0
  1434
static void localstat (LexState *ls) {
icculus@0
  1435
  /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */
icculus@0
  1436
  int nvars = 0;
icculus@0
  1437
  int nexps;
icculus@0
  1438
  expdesc e;
icculus@0
  1439
  do {
icculus@0
  1440
    new_localvar(ls, str_checkname(ls));
icculus@0
  1441
    nvars++;
icculus@0
  1442
  } while (testnext(ls, ','));
icculus@0
  1443
  if (testnext(ls, '='))
icculus@0
  1444
    nexps = explist(ls, &e);
icculus@0
  1445
  else {
icculus@0
  1446
    e.k = VVOID;
icculus@0
  1447
    nexps = 0;
icculus@0
  1448
  }
icculus@0
  1449
  adjust_assign(ls, nvars, nexps, &e);
icculus@0
  1450
  adjustlocalvars(ls, nvars);
icculus@0
  1451
}
icculus@0
  1452
icculus@0
  1453
icculus@0
  1454
static int funcname (LexState *ls, expdesc *v) {
icculus@0
  1455
  /* funcname -> NAME {fieldsel} [`:' NAME] */
icculus@0
  1456
  int ismethod = 0;
icculus@0
  1457
  singlevar(ls, v);
icculus@0
  1458
  while (ls->t.token == '.')
icculus@0
  1459
    fieldsel(ls, v);
icculus@0
  1460
  if (ls->t.token == ':') {
icculus@0
  1461
    ismethod = 1;
icculus@0
  1462
    fieldsel(ls, v);
icculus@0
  1463
  }
icculus@0
  1464
  return ismethod;
icculus@0
  1465
}
icculus@0
  1466
icculus@0
  1467
icculus@0
  1468
static void funcstat (LexState *ls, int line) {
icculus@0
  1469
  /* funcstat -> FUNCTION funcname body */
icculus@0
  1470
  int ismethod;
icculus@0
  1471
  expdesc v, b;
icculus@0
  1472
  luaX_next(ls);  /* skip FUNCTION */
icculus@0
  1473
  ismethod = funcname(ls, &v);
icculus@0
  1474
  body(ls, &b, ismethod, line);
icculus@0
  1475
  luaK_storevar(ls->fs, &v, &b);
icculus@0
  1476
  luaK_fixline(ls->fs, line);  /* definition `happens' in the first line */
icculus@0
  1477
}
icculus@0
  1478
icculus@0
  1479
icculus@0
  1480
static void exprstat (LexState *ls) {
icculus@0
  1481
  /* stat -> func | assignment */
icculus@0
  1482
  FuncState *fs = ls->fs;
icculus@0
  1483
  struct LHS_assign v;
icculus@0
  1484
  suffixedexp(ls, &v.v);
icculus@0
  1485
  if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
icculus@0
  1486
    v.prev = NULL;
icculus@0
  1487
    assignment(ls, &v, 1);
icculus@0
  1488
  }
icculus@0
  1489
  else {  /* stat -> func */
icculus@0
  1490
    check_condition(ls, v.v.k == VCALL, "syntax error");
icculus@0
  1491
    SETARG_C(getcode(fs, &v.v), 1);  /* call statement uses no results */
icculus@0
  1492
  }
icculus@0
  1493
}
icculus@0
  1494
icculus@0
  1495
icculus@0
  1496
static void retstat (LexState *ls) {
icculus@0
  1497
  /* stat -> RETURN [explist] [';'] */
icculus@0
  1498
  FuncState *fs = ls->fs;
icculus@0
  1499
  expdesc e;
icculus@0
  1500
  int first, nret;  /* registers with returned values */
icculus@0
  1501
  if (block_follow(ls, 1) || ls->t.token == ';')
icculus@0
  1502
    first = nret = 0;  /* return no values */
icculus@0
  1503
  else {
icculus@0
  1504
    nret = explist(ls, &e);  /* optional return values */
icculus@0
  1505
    if (hasmultret(e.k)) {
icculus@0
  1506
      luaK_setmultret(fs, &e);
icculus@0
  1507
      if (e.k == VCALL && nret == 1) {  /* tail call? */
icculus@0
  1508
        SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
icculus@0
  1509
        lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
icculus@0
  1510
      }
icculus@0
  1511
      first = fs->nactvar;
icculus@0
  1512
      nret = LUA_MULTRET;  /* return all values */
icculus@0
  1513
    }
icculus@0
  1514
    else {
icculus@0
  1515
      if (nret == 1)  /* only one single value? */
icculus@0
  1516
        first = luaK_exp2anyreg(fs, &e);
icculus@0
  1517
      else {
icculus@0
  1518
        luaK_exp2nextreg(fs, &e);  /* values must go to the `stack' */
icculus@0
  1519
        first = fs->nactvar;  /* return all `active' values */
icculus@0
  1520
        lua_assert(nret == fs->freereg - first);
icculus@0
  1521
      }
icculus@0
  1522
    }
icculus@0
  1523
  }
icculus@0
  1524
  luaK_ret(fs, first, nret);
icculus@0
  1525
  testnext(ls, ';');  /* skip optional semicolon */
icculus@0
  1526
}
icculus@0
  1527
icculus@0
  1528
icculus@0
  1529
static void statement (LexState *ls) {
icculus@0
  1530
  int line = ls->linenumber;  /* may be needed for error messages */
icculus@0
  1531
  enterlevel(ls);
icculus@0
  1532
  switch (ls->t.token) {
icculus@0
  1533
    case ';': {  /* stat -> ';' (empty statement) */
icculus@0
  1534
      luaX_next(ls);  /* skip ';' */
icculus@0
  1535
      break;
icculus@0
  1536
    }
icculus@0
  1537
    case TK_IF: {  /* stat -> ifstat */
icculus@0
  1538
      ifstat(ls, line);
icculus@0
  1539
      break;
icculus@0
  1540
    }
icculus@0
  1541
    case TK_WHILE: {  /* stat -> whilestat */
icculus@0
  1542
      whilestat(ls, line);
icculus@0
  1543
      break;
icculus@0
  1544
    }
icculus@0
  1545
    case TK_DO: {  /* stat -> DO block END */
icculus@0
  1546
      luaX_next(ls);  /* skip DO */
icculus@0
  1547
      block(ls);
icculus@0
  1548
      check_match(ls, TK_END, TK_DO, line);
icculus@0
  1549
      break;
icculus@0
  1550
    }
icculus@0
  1551
    case TK_FOR: {  /* stat -> forstat */
icculus@0
  1552
      forstat(ls, line);
icculus@0
  1553
      break;
icculus@0
  1554
    }
icculus@0
  1555
    case TK_REPEAT: {  /* stat -> repeatstat */
icculus@0
  1556
      repeatstat(ls, line);
icculus@0
  1557
      break;
icculus@0
  1558
    }
icculus@0
  1559
    case TK_FUNCTION: {  /* stat -> funcstat */
icculus@0
  1560
      funcstat(ls, line);
icculus@0
  1561
      break;
icculus@0
  1562
    }
icculus@0
  1563
    case TK_LOCAL: {  /* stat -> localstat */
icculus@0
  1564
      luaX_next(ls);  /* skip LOCAL */
icculus@0
  1565
      if (testnext(ls, TK_FUNCTION))  /* local function? */
icculus@0
  1566
        localfunc(ls);
icculus@0
  1567
      else
icculus@0
  1568
        localstat(ls);
icculus@0
  1569
      break;
icculus@0
  1570
    }
icculus@0
  1571
    case TK_DBCOLON: {  /* stat -> label */
icculus@0
  1572
      luaX_next(ls);  /* skip double colon */
icculus@0
  1573
      labelstat(ls, str_checkname(ls), line);
icculus@0
  1574
      break;
icculus@0
  1575
    }
icculus@0
  1576
    case TK_RETURN: {  /* stat -> retstat */
icculus@0
  1577
      luaX_next(ls);  /* skip RETURN */
icculus@0
  1578
      retstat(ls);
icculus@0
  1579
      break;
icculus@0
  1580
    }
icculus@0
  1581
    case TK_BREAK:   /* stat -> breakstat */
icculus@0
  1582
    case TK_GOTO: {  /* stat -> 'goto' NAME */
icculus@0
  1583
      gotostat(ls, luaK_jump(ls->fs));
icculus@0
  1584
      break;
icculus@0
  1585
    }
icculus@0
  1586
    default: {  /* stat -> func | assignment */
icculus@0
  1587
      exprstat(ls);
icculus@0
  1588
      break;
icculus@0
  1589
    }
icculus@0
  1590
  }
icculus@0
  1591
  lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
icculus@0
  1592
             ls->fs->freereg >= ls->fs->nactvar);
icculus@0
  1593
  ls->fs->freereg = ls->fs->nactvar;  /* free registers */
icculus@0
  1594
  leavelevel(ls);
icculus@0
  1595
}
icculus@0
  1596
icculus@0
  1597
/* }====================================================================== */
icculus@0
  1598
icculus@0
  1599
icculus@0
  1600
/*
icculus@0
  1601
** compiles the main function, which is a regular vararg function with an
icculus@0
  1602
** upvalue named LUA_ENV
icculus@0
  1603
*/
icculus@0
  1604
static void mainfunc (LexState *ls, FuncState *fs) {
icculus@0
  1605
  BlockCnt bl;
icculus@0
  1606
  expdesc v;
icculus@0
  1607
  open_func(ls, fs, &bl);
icculus@0
  1608
  fs->f->is_vararg = 1;  /* main function is always vararg */
icculus@0
  1609
  init_exp(&v, VLOCAL, 0);  /* create and... */
icculus@0
  1610
  newupvalue(fs, ls->envn, &v);  /* ...set environment upvalue */
icculus@0
  1611
  luaX_next(ls);  /* read first token */
icculus@0
  1612
  statlist(ls);  /* parse main body */
icculus@0
  1613
  check(ls, TK_EOS);
icculus@0
  1614
  close_func(ls);
icculus@0
  1615
}
icculus@0
  1616
icculus@0
  1617
icculus@0
  1618
Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
icculus@0
  1619
                      Dyndata *dyd, const char *name, int firstchar) {
icculus@0
  1620
  LexState lexstate;
icculus@0
  1621
  FuncState funcstate;
icculus@0
  1622
  Closure *cl = luaF_newLclosure(L, 1);  /* create main closure */
icculus@0
  1623
  /* anchor closure (to avoid being collected) */
icculus@0
  1624
  setclLvalue(L, L->top, cl);
icculus@0
  1625
  incr_top(L);
icculus@0
  1626
  funcstate.f = cl->l.p = luaF_newproto(L);
icculus@0
  1627
  funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */
icculus@0
  1628
  lexstate.buff = buff;
icculus@0
  1629
  lexstate.dyd = dyd;
icculus@0
  1630
  dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
icculus@0
  1631
  luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
icculus@0
  1632
  mainfunc(&lexstate, &funcstate);
icculus@0
  1633
  lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
icculus@0
  1634
  /* all scopes should be correctly finished */
icculus@0
  1635
  lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
icculus@0
  1636
  return cl;  /* it's on the stack too */
icculus@0
  1637
}
icculus@0
  1638