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