misc/liblua/lparser.c
author nemo
Sun, 11 Sep 2011 10:46:53 -0400
changeset 5856 ed97138dc414
parent 2812 0a24853de796
child 10017 de822cd3df3a
permissions -rw-r--r--
Should prevent a crasher when drowning while firing
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2812
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     1
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     2
** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     3
** Lua Parser
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     4
** See Copyright Notice in lua.h
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     5
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     6
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     7
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     8
#include <string.h>
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     9
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    10
#define lparser_c
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    11
#define LUA_CORE
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    12
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    13
#include "lua.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    14
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    15
#include "lcode.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    16
#include "ldebug.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    17
#include "ldo.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    18
#include "lfunc.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    19
#include "llex.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    20
#include "lmem.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    21
#include "lobject.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    22
#include "lopcodes.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    23
#include "lparser.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    24
#include "lstate.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    25
#include "lstring.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    26
#include "ltable.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    27
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    28
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    29
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    30
#define hasmultret(k)		((k) == VCALL || (k) == VVARARG)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    31
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    32
#define getlocvar(fs, i)	((fs)->f->locvars[(fs)->actvar[i]])
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    33
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    34
#define luaY_checklimit(fs,v,l,m)	if ((v)>(l)) errorlimit(fs,l,m)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    35
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    36
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    37
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    38
** nodes for block list (list of active blocks)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    39
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    40
typedef struct BlockCnt {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    41
  struct BlockCnt *previous;  /* chain */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    42
  int breaklist;  /* list of jumps out of this loop */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    43
  lu_byte nactvar;  /* # active locals outside the breakable structure */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    44
  lu_byte upval;  /* true if some variable in the block is an upvalue */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    45
  lu_byte isbreakable;  /* true if `block' is a loop */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    46
} BlockCnt;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    47
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    48
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    49
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    50
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    51
** prototypes for recursive non-terminal functions
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    52
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    53
static void chunk (LexState *ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    54
static void expr (LexState *ls, expdesc *v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    55
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    56
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    57
static void anchor_token (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    58
  if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    59
    TString *ts = ls->t.seminfo.ts;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    60
    luaX_newstring(ls, getstr(ts), ts->tsv.len);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    61
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    62
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    63
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    64
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    65
static void error_expected (LexState *ls, int token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    66
  luaX_syntaxerror(ls,
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    67
      luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    68
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    69
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    70
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    71
static void errorlimit (FuncState *fs, int limit, const char *what) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    72
  const char *msg = (fs->f->linedefined == 0) ?
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    73
    luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    74
    luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    75
                            fs->f->linedefined, limit, what);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    76
  luaX_lexerror(fs->ls, msg, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    77
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    78
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    79
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    80
static int testnext (LexState *ls, int c) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    81
  if (ls->t.token == c) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    82
    luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    83
    return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    84
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    85
  else return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    86
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    87
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    88
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    89
static void check (LexState *ls, int c) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    90
  if (ls->t.token != c)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    91
    error_expected(ls, c);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    92
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    93
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    94
static void checknext (LexState *ls, int c) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    95
  check(ls, c);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    96
  luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    97
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    98
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    99
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   100
#define check_condition(ls,c,msg)	{ if (!(c)) luaX_syntaxerror(ls, msg); }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   101
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   102
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   103
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   104
static void check_match (LexState *ls, int what, int who, int where) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   105
  if (!testnext(ls, what)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   106
    if (where == ls->linenumber)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   107
      error_expected(ls, what);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   108
    else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   109
      luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   110
             LUA_QS " expected (to close " LUA_QS " at line %d)",
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   111
              luaX_token2str(ls, what), luaX_token2str(ls, who), where));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   112
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   113
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   114
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   115
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   116
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   117
static TString *str_checkname (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   118
  TString *ts;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   119
  check(ls, TK_NAME);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   120
  ts = ls->t.seminfo.ts;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   121
  luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   122
  return ts;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   123
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   124
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   125
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   126
static void init_exp (expdesc *e, expkind k, int i) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   127
  e->f = e->t = NO_JUMP;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   128
  e->k = k;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   129
  e->u.s.info = i;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   130
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   131
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   132
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   133
static void codestring (LexState *ls, expdesc *e, TString *s) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   134
  init_exp(e, VK, luaK_stringK(ls->fs, s));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   135
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   136
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   137
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   138
static void checkname(LexState *ls, expdesc *e) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   139
  codestring(ls, e, str_checkname(ls));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   140
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   141
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   142
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   143
static int registerlocalvar (LexState *ls, TString *varname) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   144
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   145
  Proto *f = fs->f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   146
  int oldsize = f->sizelocvars;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   147
  luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   148
                  LocVar, SHRT_MAX, "too many local variables");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   149
  while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   150
  f->locvars[fs->nlocvars].varname = varname;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   151
  luaC_objbarrier(ls->L, f, varname);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   152
  return fs->nlocvars++;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   153
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   154
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   155
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   156
#define new_localvarliteral(ls,v,n) \
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   157
  new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   158
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   159
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   160
static void new_localvar (LexState *ls, TString *name, int n) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   161
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   162
  luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   163
  fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   164
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   165
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   166
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   167
static void adjustlocalvars (LexState *ls, int nvars) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   168
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   169
  fs->nactvar = cast_byte(fs->nactvar + nvars);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   170
  for (; nvars; nvars--) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   171
    getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   172
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   173
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   174
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   175
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   176
static void removevars (LexState *ls, int tolevel) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   177
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   178
  while (fs->nactvar > tolevel)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   179
    getlocvar(fs, --fs->nactvar).endpc = fs->pc;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   180
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   181
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   182
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   183
static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   184
  int i;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   185
  Proto *f = fs->f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   186
  int oldsize = f->sizeupvalues;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   187
  for (i=0; i<f->nups; i++) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   188
    if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   189
      lua_assert(f->upvalues[i] == name);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   190
      return i;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   191
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   192
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   193
  /* new one */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   194
  luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   195
  luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   196
                  TString *, MAX_INT, "");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   197
  while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   198
  f->upvalues[f->nups] = name;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   199
  luaC_objbarrier(fs->L, f, name);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   200
  lua_assert(v->k == VLOCAL || v->k == VUPVAL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   201
  fs->upvalues[f->nups].k = cast_byte(v->k);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   202
  fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   203
  return f->nups++;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   204
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   205
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   206
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   207
static int searchvar (FuncState *fs, TString *n) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   208
  int i;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   209
  for (i=fs->nactvar-1; i >= 0; i--) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   210
    if (n == getlocvar(fs, i).varname)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   211
      return i;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   212
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   213
  return -1;  /* not found */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   214
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   215
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   216
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   217
static void markupval (FuncState *fs, int level) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   218
  BlockCnt *bl = fs->bl;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   219
  while (bl && bl->nactvar > level) bl = bl->previous;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   220
  if (bl) bl->upval = 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   221
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   222
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   223
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   224
static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   225
  if (fs == NULL) {  /* no more levels? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   226
    init_exp(var, VGLOBAL, NO_REG);  /* default is global variable */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   227
    return VGLOBAL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   228
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   229
  else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   230
    int v = searchvar(fs, n);  /* look up at current level */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   231
    if (v >= 0) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   232
      init_exp(var, VLOCAL, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   233
      if (!base)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   234
        markupval(fs, v);  /* local will be used as an upval */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   235
      return VLOCAL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   236
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   237
    else {  /* not found at current level; try upper one */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   238
      if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   239
        return VGLOBAL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   240
      var->u.s.info = indexupvalue(fs, n, var);  /* else was LOCAL or UPVAL */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   241
      var->k = VUPVAL;  /* upvalue in this level */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   242
      return VUPVAL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   243
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   244
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   245
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   246
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   247
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   248
static void singlevar (LexState *ls, expdesc *var) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   249
  TString *varname = str_checkname(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   250
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   251
  if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   252
    var->u.s.info = luaK_stringK(fs, varname);  /* info points to global name */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   253
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   254
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   255
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   256
static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   257
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   258
  int extra = nvars - nexps;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   259
  if (hasmultret(e->k)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   260
    extra++;  /* includes call itself */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   261
    if (extra < 0) extra = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   262
    luaK_setreturns(fs, e, extra);  /* last exp. provides the difference */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   263
    if (extra > 1) luaK_reserveregs(fs, extra-1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   264
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   265
  else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   266
    if (e->k != VVOID) luaK_exp2nextreg(fs, e);  /* close last expression */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   267
    if (extra > 0) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   268
      int reg = fs->freereg;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   269
      luaK_reserveregs(fs, extra);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   270
      luaK_nil(fs, reg, extra);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   271
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   272
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   273
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   274
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   275
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   276
static void enterlevel (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   277
  if (++ls->L->nCcalls > LUAI_MAXCCALLS)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   278
	luaX_lexerror(ls, "chunk has too many syntax levels", 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   279
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   280
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   281
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   282
#define leavelevel(ls)	((ls)->L->nCcalls--)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   283
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   284
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   285
static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   286
  bl->breaklist = NO_JUMP;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   287
  bl->isbreakable = isbreakable;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   288
  bl->nactvar = fs->nactvar;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   289
  bl->upval = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   290
  bl->previous = fs->bl;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   291
  fs->bl = bl;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   292
  lua_assert(fs->freereg == fs->nactvar);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   293
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   294
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   295
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   296
static void leaveblock (FuncState *fs) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   297
  BlockCnt *bl = fs->bl;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   298
  fs->bl = bl->previous;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   299
  removevars(fs->ls, bl->nactvar);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   300
  if (bl->upval)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   301
    luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   302
  /* a block either controls scope or breaks (never both) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   303
  lua_assert(!bl->isbreakable || !bl->upval);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   304
  lua_assert(bl->nactvar == fs->nactvar);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   305
  fs->freereg = fs->nactvar;  /* free registers */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   306
  luaK_patchtohere(fs, bl->breaklist);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   307
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   308
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   309
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   310
static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   311
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   312
  Proto *f = fs->f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   313
  int oldsize = f->sizep;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   314
  int i;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   315
  luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   316
                  MAXARG_Bx, "constant table overflow");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   317
  while (oldsize < f->sizep) f->p[oldsize++] = NULL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   318
  f->p[fs->np++] = func->f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   319
  luaC_objbarrier(ls->L, f, func->f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   320
  init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   321
  for (i=0; i<func->f->nups; i++) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   322
    OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   323
    luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   324
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   325
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   326
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   327
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   328
static void open_func (LexState *ls, FuncState *fs) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   329
  lua_State *L = ls->L;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   330
  Proto *f = luaF_newproto(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   331
  fs->f = f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   332
  fs->prev = ls->fs;  /* linked list of funcstates */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   333
  fs->ls = ls;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   334
  fs->L = L;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   335
  ls->fs = fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   336
  fs->pc = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   337
  fs->lasttarget = -1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   338
  fs->jpc = NO_JUMP;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   339
  fs->freereg = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   340
  fs->nk = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   341
  fs->np = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   342
  fs->nlocvars = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   343
  fs->nactvar = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   344
  fs->bl = NULL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   345
  f->source = ls->source;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   346
  f->maxstacksize = 2;  /* registers 0/1 are always valid */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   347
  fs->h = luaH_new(L, 0, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   348
  /* anchor table of constants and prototype (to avoid being collected) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   349
  sethvalue2s(L, L->top, fs->h);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   350
  incr_top(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   351
  setptvalue2s(L, L->top, f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   352
  incr_top(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   353
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   354
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   355
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   356
static void close_func (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   357
  lua_State *L = ls->L;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   358
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   359
  Proto *f = fs->f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   360
  removevars(ls, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   361
  luaK_ret(fs, 0, 0);  /* final return */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   362
  luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   363
  f->sizecode = fs->pc;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   364
  luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   365
  f->sizelineinfo = fs->pc;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   366
  luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   367
  f->sizek = fs->nk;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   368
  luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   369
  f->sizep = fs->np;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   370
  luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   371
  f->sizelocvars = fs->nlocvars;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   372
  luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   373
  f->sizeupvalues = f->nups;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   374
  lua_assert(luaG_checkcode(f));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   375
  lua_assert(fs->bl == NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   376
  ls->fs = fs->prev;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   377
  L->top -= 2;  /* remove table and prototype from the stack */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   378
  /* last token read was anchored in defunct function; must reanchor it */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   379
  if (fs) anchor_token(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   380
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   381
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   382
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   383
Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   384
  struct LexState lexstate;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   385
  struct FuncState funcstate;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   386
  lexstate.buff = buff;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   387
  luaX_setinput(L, &lexstate, z, luaS_new(L, name));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   388
  open_func(&lexstate, &funcstate);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   389
  funcstate.f->is_vararg = VARARG_ISVARARG;  /* main func. is always vararg */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   390
  luaX_next(&lexstate);  /* read first token */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   391
  chunk(&lexstate);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   392
  check(&lexstate, TK_EOS);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   393
  close_func(&lexstate);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   394
  lua_assert(funcstate.prev == NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   395
  lua_assert(funcstate.f->nups == 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   396
  lua_assert(lexstate.fs == NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   397
  return funcstate.f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   398
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   399
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   400
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   401
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   402
/*============================================================*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   403
/* GRAMMAR RULES */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   404
/*============================================================*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   405
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   406
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   407
static void field (LexState *ls, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   408
  /* field -> ['.' | ':'] NAME */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   409
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   410
  expdesc key;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   411
  luaK_exp2anyreg(fs, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   412
  luaX_next(ls);  /* skip the dot or colon */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   413
  checkname(ls, &key);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   414
  luaK_indexed(fs, v, &key);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   415
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   416
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   417
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   418
static void yindex (LexState *ls, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   419
  /* index -> '[' expr ']' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   420
  luaX_next(ls);  /* skip the '[' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   421
  expr(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   422
  luaK_exp2val(ls->fs, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   423
  checknext(ls, ']');
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   424
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   425
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   426
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   427
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   428
** {======================================================================
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   429
** Rules for Constructors
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   430
** =======================================================================
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   431
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   432
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   433
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   434
struct ConsControl {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   435
  expdesc v;  /* last list item read */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   436
  expdesc *t;  /* table descriptor */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   437
  int nh;  /* total number of `record' elements */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   438
  int na;  /* total number of array elements */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   439
  int tostore;  /* number of array elements pending to be stored */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   440
};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   441
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   442
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   443
static void recfield (LexState *ls, struct ConsControl *cc) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   444
  /* recfield -> (NAME | `['exp1`]') = exp1 */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   445
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   446
  int reg = ls->fs->freereg;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   447
  expdesc key, val;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   448
  int rkkey;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   449
  if (ls->t.token == TK_NAME) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   450
    luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   451
    checkname(ls, &key);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   452
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   453
  else  /* ls->t.token == '[' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   454
    yindex(ls, &key);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   455
  cc->nh++;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   456
  checknext(ls, '=');
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   457
  rkkey = luaK_exp2RK(fs, &key);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   458
  expr(ls, &val);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   459
  luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   460
  fs->freereg = reg;  /* free registers */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   461
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   462
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   463
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   464
static void closelistfield (FuncState *fs, struct ConsControl *cc) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   465
  if (cc->v.k == VVOID) return;  /* there is no list item */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   466
  luaK_exp2nextreg(fs, &cc->v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   467
  cc->v.k = VVOID;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   468
  if (cc->tostore == LFIELDS_PER_FLUSH) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   469
    luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);  /* flush */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   470
    cc->tostore = 0;  /* no more items pending */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   471
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   472
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   473
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   474
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   475
static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   476
  if (cc->tostore == 0) return;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   477
  if (hasmultret(cc->v.k)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   478
    luaK_setmultret(fs, &cc->v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   479
    luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   480
    cc->na--;  /* do not count last expression (unknown number of elements) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   481
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   482
  else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   483
    if (cc->v.k != VVOID)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   484
      luaK_exp2nextreg(fs, &cc->v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   485
    luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   486
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   487
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   488
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   489
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   490
static void listfield (LexState *ls, struct ConsControl *cc) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   491
  expr(ls, &cc->v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   492
  luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   493
  cc->na++;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   494
  cc->tostore++;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   495
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   496
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   497
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   498
static void constructor (LexState *ls, expdesc *t) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   499
  /* constructor -> ?? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   500
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   501
  int line = ls->linenumber;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   502
  int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   503
  struct ConsControl cc;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   504
  cc.na = cc.nh = cc.tostore = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   505
  cc.t = t;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   506
  init_exp(t, VRELOCABLE, pc);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   507
  init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   508
  luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top (for gc) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   509
  checknext(ls, '{');
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   510
  do {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   511
    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   512
    if (ls->t.token == '}') break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   513
    closelistfield(fs, &cc);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   514
    switch(ls->t.token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   515
      case TK_NAME: {  /* may be listfields or recfields */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   516
        luaX_lookahead(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   517
        if (ls->lookahead.token != '=')  /* expression? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   518
          listfield(ls, &cc);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   519
        else
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   520
          recfield(ls, &cc);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   521
        break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   522
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   523
      case '[': {  /* constructor_item -> recfield */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   524
        recfield(ls, &cc);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   525
        break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   526
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   527
      default: {  /* constructor_part -> listfield */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   528
        listfield(ls, &cc);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   529
        break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   530
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   531
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   532
  } while (testnext(ls, ',') || testnext(ls, ';'));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   533
  check_match(ls, '}', '{', line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   534
  lastlistfield(fs, &cc);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   535
  SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   536
  SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh));  /* set initial table size */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   537
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   538
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   539
/* }====================================================================== */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   540
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   541
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   542
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   543
static void parlist (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   544
  /* parlist -> [ param { `,' param } ] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   545
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   546
  Proto *f = fs->f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   547
  int nparams = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   548
  f->is_vararg = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   549
  if (ls->t.token != ')') {  /* is `parlist' not empty? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   550
    do {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   551
      switch (ls->t.token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   552
        case TK_NAME: {  /* param -> NAME */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   553
          new_localvar(ls, str_checkname(ls), nparams++);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   554
          break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   555
        }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   556
        case TK_DOTS: {  /* param -> `...' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   557
          luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   558
#if defined(LUA_COMPAT_VARARG)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   559
          /* use `arg' as default name */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   560
          new_localvarliteral(ls, "arg", nparams++);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   561
          f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   562
#endif
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   563
          f->is_vararg |= VARARG_ISVARARG;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   564
          break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   565
        }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   566
        default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   567
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   568
    } while (!f->is_vararg && testnext(ls, ','));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   569
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   570
  adjustlocalvars(ls, nparams);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   571
  f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   572
  luaK_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   573
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   574
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   575
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   576
static void body (LexState *ls, expdesc *e, int needself, int line) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   577
  /* body ->  `(' parlist `)' chunk END */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   578
  FuncState new_fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   579
  open_func(ls, &new_fs);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   580
  new_fs.f->linedefined = line;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   581
  checknext(ls, '(');
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   582
  if (needself) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   583
    new_localvarliteral(ls, "self", 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   584
    adjustlocalvars(ls, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   585
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   586
  parlist(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   587
  checknext(ls, ')');
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   588
  chunk(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   589
  new_fs.f->lastlinedefined = ls->linenumber;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   590
  check_match(ls, TK_END, TK_FUNCTION, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   591
  close_func(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   592
  pushclosure(ls, &new_fs, e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   593
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   594
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   595
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   596
static int explist1 (LexState *ls, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   597
  /* explist1 -> expr { `,' expr } */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   598
  int n = 1;  /* at least one expression */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   599
  expr(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   600
  while (testnext(ls, ',')) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   601
    luaK_exp2nextreg(ls->fs, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   602
    expr(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   603
    n++;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   604
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   605
  return n;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   606
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   607
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   608
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   609
static void funcargs (LexState *ls, expdesc *f) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   610
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   611
  expdesc args;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   612
  int base, nparams;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   613
  int line = ls->linenumber;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   614
  switch (ls->t.token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   615
    case '(': {  /* funcargs -> `(' [ explist1 ] `)' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   616
      if (line != ls->lastline)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   617
        luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   618
      luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   619
      if (ls->t.token == ')')  /* arg list is empty? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   620
        args.k = VVOID;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   621
      else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   622
        explist1(ls, &args);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   623
        luaK_setmultret(fs, &args);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   624
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   625
      check_match(ls, ')', '(', line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   626
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   627
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   628
    case '{': {  /* funcargs -> constructor */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   629
      constructor(ls, &args);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   630
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   631
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   632
    case TK_STRING: {  /* funcargs -> STRING */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   633
      codestring(ls, &args, ls->t.seminfo.ts);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   634
      luaX_next(ls);  /* must use `seminfo' before `next' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   635
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   636
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   637
    default: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   638
      luaX_syntaxerror(ls, "function arguments expected");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   639
      return;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   640
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   641
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   642
  lua_assert(f->k == VNONRELOC);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   643
  base = f->u.s.info;  /* base register for call */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   644
  if (hasmultret(args.k))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   645
    nparams = LUA_MULTRET;  /* open call */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   646
  else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   647
    if (args.k != VVOID)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   648
      luaK_exp2nextreg(fs, &args);  /* close last argument */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   649
    nparams = fs->freereg - (base+1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   650
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   651
  init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   652
  luaK_fixline(fs, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   653
  fs->freereg = base+1;  /* call remove function and arguments and leaves
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   654
                            (unless changed) one result */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   655
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   656
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   657
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   658
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   659
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   660
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   661
** {======================================================================
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   662
** Expression parsing
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   663
** =======================================================================
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   664
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   665
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   666
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   667
static void prefixexp (LexState *ls, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   668
  /* prefixexp -> NAME | '(' expr ')' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   669
  switch (ls->t.token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   670
    case '(': {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   671
      int line = ls->linenumber;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   672
      luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   673
      expr(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   674
      check_match(ls, ')', '(', line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   675
      luaK_dischargevars(ls->fs, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   676
      return;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   677
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   678
    case TK_NAME: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   679
      singlevar(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   680
      return;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   681
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   682
    default: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   683
      luaX_syntaxerror(ls, "unexpected symbol");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   684
      return;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   685
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   686
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   687
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   688
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   689
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   690
static void primaryexp (LexState *ls, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   691
  /* primaryexp ->
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   692
        prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   693
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   694
  prefixexp(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   695
  for (;;) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   696
    switch (ls->t.token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   697
      case '.': {  /* field */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   698
        field(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   699
        break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   700
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   701
      case '[': {  /* `[' exp1 `]' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   702
        expdesc key;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   703
        luaK_exp2anyreg(fs, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   704
        yindex(ls, &key);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   705
        luaK_indexed(fs, v, &key);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   706
        break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   707
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   708
      case ':': {  /* `:' NAME funcargs */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   709
        expdesc key;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   710
        luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   711
        checkname(ls, &key);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   712
        luaK_self(fs, v, &key);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   713
        funcargs(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   714
        break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   715
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   716
      case '(': case TK_STRING: case '{': {  /* funcargs */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   717
        luaK_exp2nextreg(fs, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   718
        funcargs(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   719
        break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   720
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   721
      default: return;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   722
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   723
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   724
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   725
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   726
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   727
static void simpleexp (LexState *ls, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   728
  /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   729
                  constructor | FUNCTION body | primaryexp */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   730
  switch (ls->t.token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   731
    case TK_NUMBER: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   732
      init_exp(v, VKNUM, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   733
      v->u.nval = ls->t.seminfo.r;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   734
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   735
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   736
    case TK_STRING: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   737
      codestring(ls, v, ls->t.seminfo.ts);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   738
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   739
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   740
    case TK_NIL: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   741
      init_exp(v, VNIL, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   742
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   743
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   744
    case TK_TRUE: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   745
      init_exp(v, VTRUE, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   746
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   747
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   748
    case TK_FALSE: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   749
      init_exp(v, VFALSE, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   750
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   751
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   752
    case TK_DOTS: {  /* vararg */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   753
      FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   754
      check_condition(ls, fs->f->is_vararg,
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   755
                      "cannot use " LUA_QL("...") " outside a vararg function");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   756
      fs->f->is_vararg &= ~VARARG_NEEDSARG;  /* don't need 'arg' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   757
      init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   758
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   759
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   760
    case '{': {  /* constructor */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   761
      constructor(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   762
      return;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   763
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   764
    case TK_FUNCTION: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   765
      luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   766
      body(ls, v, 0, ls->linenumber);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   767
      return;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   768
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   769
    default: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   770
      primaryexp(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   771
      return;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   772
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   773
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   774
  luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   775
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   776
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   777
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   778
static UnOpr getunopr (int op) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   779
  switch (op) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   780
    case TK_NOT: return OPR_NOT;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   781
    case '-': return OPR_MINUS;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   782
    case '#': return OPR_LEN;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   783
    default: return OPR_NOUNOPR;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   784
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   785
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   786
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   787
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   788
static BinOpr getbinopr (int op) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   789
  switch (op) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   790
    case '+': return OPR_ADD;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   791
    case '-': return OPR_SUB;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   792
    case '*': return OPR_MUL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   793
    case '/': return OPR_DIV;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   794
    case '%': return OPR_MOD;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   795
    case '^': return OPR_POW;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   796
    case TK_CONCAT: return OPR_CONCAT;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   797
    case TK_NE: return OPR_NE;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   798
    case TK_EQ: return OPR_EQ;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   799
    case '<': return OPR_LT;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   800
    case TK_LE: return OPR_LE;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   801
    case '>': return OPR_GT;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   802
    case TK_GE: return OPR_GE;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   803
    case TK_AND: return OPR_AND;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   804
    case TK_OR: return OPR_OR;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   805
    default: return OPR_NOBINOPR;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   806
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   807
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   808
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   809
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   810
static const struct {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   811
  lu_byte left;  /* left priority for each binary operator */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   812
  lu_byte right; /* right priority */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   813
} priority[] = {  /* ORDER OPR */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   814
   {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7},  /* `+' `-' `/' `%' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   815
   {10, 9}, {5, 4},                 /* power and concat (right associative) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   816
   {3, 3}, {3, 3},                  /* equality and inequality */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   817
   {3, 3}, {3, 3}, {3, 3}, {3, 3},  /* order */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   818
   {2, 2}, {1, 1}                   /* logical (and/or) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   819
};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   820
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   821
#define UNARY_PRIORITY	8  /* priority for unary operators */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   822
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   823
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   824
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   825
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   826
** where `binop' is any binary operator with a priority higher than `limit'
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   827
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   828
static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   829
  BinOpr op;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   830
  UnOpr uop;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   831
  enterlevel(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   832
  uop = getunopr(ls->t.token);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   833
  if (uop != OPR_NOUNOPR) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   834
    luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   835
    subexpr(ls, v, UNARY_PRIORITY);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   836
    luaK_prefix(ls->fs, uop, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   837
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   838
  else simpleexp(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   839
  /* expand while operators have priorities higher than `limit' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   840
  op = getbinopr(ls->t.token);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   841
  while (op != OPR_NOBINOPR && priority[op].left > limit) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   842
    expdesc v2;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   843
    BinOpr nextop;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   844
    luaX_next(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   845
    luaK_infix(ls->fs, op, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   846
    /* read sub-expression with higher priority */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   847
    nextop = subexpr(ls, &v2, priority[op].right);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   848
    luaK_posfix(ls->fs, op, v, &v2);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   849
    op = nextop;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   850
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   851
  leavelevel(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   852
  return op;  /* return first untreated operator */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   853
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   854
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   855
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   856
static void expr (LexState *ls, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   857
  subexpr(ls, v, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   858
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   859
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   860
/* }==================================================================== */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   861
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   862
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   863
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   864
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   865
** {======================================================================
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   866
** Rules for Statements
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   867
** =======================================================================
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   868
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   869
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   870
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   871
static int block_follow (int token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   872
  switch (token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   873
    case TK_ELSE: case TK_ELSEIF: case TK_END:
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   874
    case TK_UNTIL: case TK_EOS:
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   875
      return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   876
    default: return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   877
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   878
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   879
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   880
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   881
static void block (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   882
  /* block -> chunk */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   883
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   884
  BlockCnt bl;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   885
  enterblock(fs, &bl, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   886
  chunk(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   887
  lua_assert(bl.breaklist == NO_JUMP);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   888
  leaveblock(fs);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   889
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   890
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   891
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   892
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   893
** structure to chain all variables in the left-hand side of an
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   894
** assignment
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   895
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   896
struct LHS_assign {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   897
  struct LHS_assign *prev;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   898
  expdesc v;  /* variable (global, local, upvalue, or indexed) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   899
};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   900
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   901
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   902
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   903
** check whether, in an assignment to a local variable, the local variable
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   904
** is needed in a previous assignment (to a table). If so, save original
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   905
** local value in a safe place and use this safe copy in the previous
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   906
** assignment.
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   907
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   908
static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   909
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   910
  int extra = fs->freereg;  /* eventual position to save local variable */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   911
  int conflict = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   912
  for (; lh; lh = lh->prev) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   913
    if (lh->v.k == VINDEXED) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   914
      if (lh->v.u.s.info == v->u.s.info) {  /* conflict? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   915
        conflict = 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   916
        lh->v.u.s.info = extra;  /* previous assignment will use safe copy */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   917
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   918
      if (lh->v.u.s.aux == v->u.s.info) {  /* conflict? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   919
        conflict = 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   920
        lh->v.u.s.aux = extra;  /* previous assignment will use safe copy */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   921
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   922
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   923
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   924
  if (conflict) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   925
    luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0);  /* make copy */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   926
    luaK_reserveregs(fs, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   927
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   928
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   929
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   930
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   931
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   932
  expdesc e;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   933
  check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   934
                      "syntax error");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   935
  if (testnext(ls, ',')) {  /* assignment -> `,' primaryexp assignment */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   936
    struct LHS_assign nv;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   937
    nv.prev = lh;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   938
    primaryexp(ls, &nv.v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   939
    if (nv.v.k == VLOCAL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   940
      check_conflict(ls, lh, &nv.v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   941
    luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   942
                    "variables in assignment");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   943
    assignment(ls, &nv, nvars+1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   944
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   945
  else {  /* assignment -> `=' explist1 */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   946
    int nexps;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   947
    checknext(ls, '=');
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   948
    nexps = explist1(ls, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   949
    if (nexps != nvars) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   950
      adjust_assign(ls, nvars, nexps, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   951
      if (nexps > nvars)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   952
        ls->fs->freereg -= nexps - nvars;  /* remove extra values */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   953
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   954
    else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   955
      luaK_setoneret(ls->fs, &e);  /* close last expression */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   956
      luaK_storevar(ls->fs, &lh->v, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   957
      return;  /* avoid default */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   958
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   959
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   960
  init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   961
  luaK_storevar(ls->fs, &lh->v, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   962
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   963
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   964
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   965
static int cond (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   966
  /* cond -> exp */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   967
  expdesc v;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   968
  expr(ls, &v);  /* read condition */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   969
  if (v.k == VNIL) v.k = VFALSE;  /* `falses' are all equal here */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   970
  luaK_goiftrue(ls->fs, &v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   971
  return v.f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   972
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   973
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   974
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   975
static void breakstat (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   976
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   977
  BlockCnt *bl = fs->bl;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   978
  int upval = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   979
  while (bl && !bl->isbreakable) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   980
    upval |= bl->upval;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   981
    bl = bl->previous;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   982
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   983
  if (!bl)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   984
    luaX_syntaxerror(ls, "no loop to break");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   985
  if (upval)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   986
    luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   987
  luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   988
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   989
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   990
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   991
static void whilestat (LexState *ls, int line) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   992
  /* whilestat -> WHILE cond DO block END */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   993
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   994
  int whileinit;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   995
  int condexit;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   996
  BlockCnt bl;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   997
  luaX_next(ls);  /* skip WHILE */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   998
  whileinit = luaK_getlabel(fs);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   999
  condexit = cond(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1000
  enterblock(fs, &bl, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1001
  checknext(ls, TK_DO);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1002
  block(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1003
  luaK_patchlist(fs, luaK_jump(fs), whileinit);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1004
  check_match(ls, TK_END, TK_WHILE, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1005
  leaveblock(fs);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1006
  luaK_patchtohere(fs, condexit);  /* false conditions finish the loop */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1007
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1008
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1009
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1010
static void repeatstat (LexState *ls, int line) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1011
  /* repeatstat -> REPEAT block UNTIL cond */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1012
  int condexit;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1013
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1014
  int repeat_init = luaK_getlabel(fs);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1015
  BlockCnt bl1, bl2;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1016
  enterblock(fs, &bl1, 1);  /* loop block */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1017
  enterblock(fs, &bl2, 0);  /* scope block */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1018
  luaX_next(ls);  /* skip REPEAT */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1019
  chunk(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1020
  check_match(ls, TK_UNTIL, TK_REPEAT, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1021
  condexit = cond(ls);  /* read condition (inside scope block) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1022
  if (!bl2.upval) {  /* no upvalues? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1023
    leaveblock(fs);  /* finish scope */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1024
    luaK_patchlist(ls->fs, condexit, repeat_init);  /* close the loop */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1025
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1026
  else {  /* complete semantics when there are upvalues */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1027
    breakstat(ls);  /* if condition then break */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1028
    luaK_patchtohere(ls->fs, condexit);  /* else... */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1029
    leaveblock(fs);  /* finish scope... */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1030
    luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init);  /* and repeat */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1031
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1032
  leaveblock(fs);  /* finish loop */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1033
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1034
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1035
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1036
static int exp1 (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1037
  expdesc e;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1038
  int k;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1039
  expr(ls, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1040
  k = e.k;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1041
  luaK_exp2nextreg(ls->fs, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1042
  return k;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1043
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1044
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1045
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1046
static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1047
  /* forbody -> DO block */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1048
  BlockCnt bl;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1049
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1050
  int prep, endfor;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1051
  adjustlocalvars(ls, 3);  /* control variables */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1052
  checknext(ls, TK_DO);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1053
  prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1054
  enterblock(fs, &bl, 0);  /* scope for declared variables */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1055
  adjustlocalvars(ls, nvars);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1056
  luaK_reserveregs(fs, nvars);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1057
  block(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1058
  leaveblock(fs);  /* end of scope for declared variables */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1059
  luaK_patchtohere(fs, prep);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1060
  endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1061
                     luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1062
  luaK_fixline(fs, line);  /* pretend that `OP_FOR' starts the loop */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1063
  luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1064
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1065
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1066
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1067
static void fornum (LexState *ls, TString *varname, int line) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1068
  /* fornum -> NAME = exp1,exp1[,exp1] forbody */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1069
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1070
  int base = fs->freereg;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1071
  new_localvarliteral(ls, "(for index)", 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1072
  new_localvarliteral(ls, "(for limit)", 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1073
  new_localvarliteral(ls, "(for step)", 2);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1074
  new_localvar(ls, varname, 3);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1075
  checknext(ls, '=');
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1076
  exp1(ls);  /* initial value */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1077
  checknext(ls, ',');
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1078
  exp1(ls);  /* limit */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1079
  if (testnext(ls, ','))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1080
    exp1(ls);  /* optional step */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1081
  else {  /* default step = 1 */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1082
    luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1083
    luaK_reserveregs(fs, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1084
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1085
  forbody(ls, base, line, 1, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1086
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1087
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1088
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1089
static void forlist (LexState *ls, TString *indexname) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1090
  /* forlist -> NAME {,NAME} IN explist1 forbody */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1091
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1092
  expdesc e;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1093
  int nvars = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1094
  int line;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1095
  int base = fs->freereg;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1096
  /* create control variables */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1097
  new_localvarliteral(ls, "(for generator)", nvars++);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1098
  new_localvarliteral(ls, "(for state)", nvars++);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1099
  new_localvarliteral(ls, "(for control)", nvars++);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1100
  /* create declared variables */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1101
  new_localvar(ls, indexname, nvars++);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1102
  while (testnext(ls, ','))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1103
    new_localvar(ls, str_checkname(ls), nvars++);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1104
  checknext(ls, TK_IN);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1105
  line = ls->linenumber;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1106
  adjust_assign(ls, 3, explist1(ls, &e), &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1107
  luaK_checkstack(fs, 3);  /* extra space to call generator */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1108
  forbody(ls, base, line, nvars - 3, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1109
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1110
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1111
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1112
static void forstat (LexState *ls, int line) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1113
  /* forstat -> FOR (fornum | forlist) END */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1114
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1115
  TString *varname;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1116
  BlockCnt bl;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1117
  enterblock(fs, &bl, 1);  /* scope for loop and control variables */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1118
  luaX_next(ls);  /* skip `for' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1119
  varname = str_checkname(ls);  /* first variable name */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1120
  switch (ls->t.token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1121
    case '=': fornum(ls, varname, line); break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1122
    case ',': case TK_IN: forlist(ls, varname); break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1123
    default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1124
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1125
  check_match(ls, TK_END, TK_FOR, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1126
  leaveblock(fs);  /* loop scope (`break' jumps to this point) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1127
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1128
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1129
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1130
static int test_then_block (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1131
  /* test_then_block -> [IF | ELSEIF] cond THEN block */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1132
  int condexit;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1133
  luaX_next(ls);  /* skip IF or ELSEIF */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1134
  condexit = cond(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1135
  checknext(ls, TK_THEN);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1136
  block(ls);  /* `then' part */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1137
  return condexit;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1138
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1139
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1140
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1141
static void ifstat (LexState *ls, int line) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1142
  /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1143
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1144
  int flist;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1145
  int escapelist = NO_JUMP;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1146
  flist = test_then_block(ls);  /* IF cond THEN block */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1147
  while (ls->t.token == TK_ELSEIF) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1148
    luaK_concat(fs, &escapelist, luaK_jump(fs));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1149
    luaK_patchtohere(fs, flist);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1150
    flist = test_then_block(ls);  /* ELSEIF cond THEN block */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1151
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1152
  if (ls->t.token == TK_ELSE) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1153
    luaK_concat(fs, &escapelist, luaK_jump(fs));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1154
    luaK_patchtohere(fs, flist);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1155
    luaX_next(ls);  /* skip ELSE (after patch, for correct line info) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1156
    block(ls);  /* `else' part */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1157
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1158
  else
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1159
    luaK_concat(fs, &escapelist, flist);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1160
  luaK_patchtohere(fs, escapelist);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1161
  check_match(ls, TK_END, TK_IF, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1162
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1163
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1164
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1165
static void localfunc (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1166
  expdesc v, b;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1167
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1168
  new_localvar(ls, str_checkname(ls), 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1169
  init_exp(&v, VLOCAL, fs->freereg);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1170
  luaK_reserveregs(fs, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1171
  adjustlocalvars(ls, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1172
  body(ls, &b, 0, ls->linenumber);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1173
  luaK_storevar(fs, &v, &b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1174
  /* debug information will only see the variable after this point! */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1175
  getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1176
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1177
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1178
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1179
static void localstat (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1180
  /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1181
  int nvars = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1182
  int nexps;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1183
  expdesc e;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1184
  do {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1185
    new_localvar(ls, str_checkname(ls), nvars++);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1186
  } while (testnext(ls, ','));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1187
  if (testnext(ls, '='))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1188
    nexps = explist1(ls, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1189
  else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1190
    e.k = VVOID;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1191
    nexps = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1192
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1193
  adjust_assign(ls, nvars, nexps, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1194
  adjustlocalvars(ls, nvars);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1195
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1196
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1197
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1198
static int funcname (LexState *ls, expdesc *v) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1199
  /* funcname -> NAME {field} [`:' NAME] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1200
  int needself = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1201
  singlevar(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1202
  while (ls->t.token == '.')
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1203
    field(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1204
  if (ls->t.token == ':') {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1205
    needself = 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1206
    field(ls, v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1207
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1208
  return needself;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1209
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1210
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1211
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1212
static void funcstat (LexState *ls, int line) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1213
  /* funcstat -> FUNCTION funcname body */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1214
  int needself;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1215
  expdesc v, b;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1216
  luaX_next(ls);  /* skip FUNCTION */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1217
  needself = funcname(ls, &v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1218
  body(ls, &b, needself, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1219
  luaK_storevar(ls->fs, &v, &b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1220
  luaK_fixline(ls->fs, line);  /* definition `happens' in the first line */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1221
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1222
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1223
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1224
static void exprstat (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1225
  /* stat -> func | assignment */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1226
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1227
  struct LHS_assign v;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1228
  primaryexp(ls, &v.v);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1229
  if (v.v.k == VCALL)  /* stat -> func */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1230
    SETARG_C(getcode(fs, &v.v), 1);  /* call statement uses no results */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1231
  else {  /* stat -> assignment */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1232
    v.prev = NULL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1233
    assignment(ls, &v, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1234
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1235
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1236
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1237
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1238
static void retstat (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1239
  /* stat -> RETURN explist */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1240
  FuncState *fs = ls->fs;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1241
  expdesc e;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1242
  int first, nret;  /* registers with returned values */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1243
  luaX_next(ls);  /* skip RETURN */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1244
  if (block_follow(ls->t.token) || ls->t.token == ';')
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1245
    first = nret = 0;  /* return no values */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1246
  else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1247
    nret = explist1(ls, &e);  /* optional return values */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1248
    if (hasmultret(e.k)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1249
      luaK_setmultret(fs, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1250
      if (e.k == VCALL && nret == 1) {  /* tail call? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1251
        SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1252
        lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1253
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1254
      first = fs->nactvar;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1255
      nret = LUA_MULTRET;  /* return all values */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1256
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1257
    else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1258
      if (nret == 1)  /* only one single value? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1259
        first = luaK_exp2anyreg(fs, &e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1260
      else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1261
        luaK_exp2nextreg(fs, &e);  /* values must go to the `stack' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1262
        first = fs->nactvar;  /* return all `active' values */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1263
        lua_assert(nret == fs->freereg - first);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1264
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1265
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1266
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1267
  luaK_ret(fs, first, nret);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1268
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1269
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1270
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1271
static int statement (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1272
  int line = ls->linenumber;  /* may be needed for error messages */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1273
  switch (ls->t.token) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1274
    case TK_IF: {  /* stat -> ifstat */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1275
      ifstat(ls, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1276
      return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1277
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1278
    case TK_WHILE: {  /* stat -> whilestat */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1279
      whilestat(ls, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1280
      return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1281
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1282
    case TK_DO: {  /* stat -> DO block END */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1283
      luaX_next(ls);  /* skip DO */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1284
      block(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1285
      check_match(ls, TK_END, TK_DO, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1286
      return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1287
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1288
    case TK_FOR: {  /* stat -> forstat */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1289
      forstat(ls, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1290
      return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1291
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1292
    case TK_REPEAT: {  /* stat -> repeatstat */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1293
      repeatstat(ls, line);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1294
      return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1295
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1296
    case TK_FUNCTION: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1297
      funcstat(ls, line);  /* stat -> funcstat */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1298
      return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1299
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1300
    case TK_LOCAL: {  /* stat -> localstat */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1301
      luaX_next(ls);  /* skip LOCAL */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1302
      if (testnext(ls, TK_FUNCTION))  /* local function? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1303
        localfunc(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1304
      else
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1305
        localstat(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1306
      return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1307
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1308
    case TK_RETURN: {  /* stat -> retstat */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1309
      retstat(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1310
      return 1;  /* must be last statement */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1311
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1312
    case TK_BREAK: {  /* stat -> breakstat */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1313
      luaX_next(ls);  /* skip BREAK */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1314
      breakstat(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1315
      return 1;  /* must be last statement */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1316
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1317
    default: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1318
      exprstat(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1319
      return 0;  /* to avoid warnings */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1320
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1321
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1322
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1323
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1324
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1325
static void chunk (LexState *ls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1326
  /* chunk -> { stat [`;'] } */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1327
  int islast = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1328
  enterlevel(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1329
  while (!islast && !block_follow(ls->t.token)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1330
    islast = statement(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1331
    testnext(ls, ';');
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1332
    lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1333
               ls->fs->freereg >= ls->fs->nactvar);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1334
    ls->fs->freereg = ls->fs->nactvar;  /* free registers */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1335
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1336
  leavelevel(ls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1337
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1338
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
  1339
/* }====================================================================== */