xref: /aosp_15_r20/external/lua/src/lparser.c (revision 088332b5b69e7ab13924864b272aabfc2509d2d5)
1*088332b5SXin Li /*
2*088332b5SXin Li ** $Id: lparser.c $
3*088332b5SXin Li ** Lua Parser
4*088332b5SXin Li ** See Copyright Notice in lua.h
5*088332b5SXin Li */
6*088332b5SXin Li 
7*088332b5SXin Li #define lparser_c
8*088332b5SXin Li #define LUA_CORE
9*088332b5SXin Li 
10*088332b5SXin Li #include "lprefix.h"
11*088332b5SXin Li 
12*088332b5SXin Li 
13*088332b5SXin Li #include <limits.h>
14*088332b5SXin Li #include <string.h>
15*088332b5SXin Li 
16*088332b5SXin Li #include "lua.h"
17*088332b5SXin Li 
18*088332b5SXin Li #include "lcode.h"
19*088332b5SXin Li #include "ldebug.h"
20*088332b5SXin Li #include "ldo.h"
21*088332b5SXin Li #include "lfunc.h"
22*088332b5SXin Li #include "llex.h"
23*088332b5SXin Li #include "lmem.h"
24*088332b5SXin Li #include "lobject.h"
25*088332b5SXin Li #include "lopcodes.h"
26*088332b5SXin Li #include "lparser.h"
27*088332b5SXin Li #include "lstate.h"
28*088332b5SXin Li #include "lstring.h"
29*088332b5SXin Li #include "ltable.h"
30*088332b5SXin Li 
31*088332b5SXin Li 
32*088332b5SXin Li 
33*088332b5SXin Li /* maximum number of local variables per function (must be smaller
34*088332b5SXin Li    than 250, due to the bytecode format) */
35*088332b5SXin Li #define MAXVARS		200
36*088332b5SXin Li 
37*088332b5SXin Li 
38*088332b5SXin Li #define hasmultret(k)		((k) == VCALL || (k) == VVARARG)
39*088332b5SXin Li 
40*088332b5SXin Li 
41*088332b5SXin Li /* because all strings are unified by the scanner, the parser
42*088332b5SXin Li    can use pointer equality for string equality */
43*088332b5SXin Li #define eqstr(a,b)	((a) == (b))
44*088332b5SXin Li 
45*088332b5SXin Li 
46*088332b5SXin Li /*
47*088332b5SXin Li ** nodes for block list (list of active blocks)
48*088332b5SXin Li */
49*088332b5SXin Li typedef struct BlockCnt {
50*088332b5SXin Li   struct BlockCnt *previous;  /* chain */
51*088332b5SXin Li   int firstlabel;  /* index of first label in this block */
52*088332b5SXin Li   int firstgoto;  /* index of first pending goto in this block */
53*088332b5SXin Li   lu_byte nactvar;  /* # active locals outside the block */
54*088332b5SXin Li   lu_byte upval;  /* true if some variable in the block is an upvalue */
55*088332b5SXin Li   lu_byte isloop;  /* true if 'block' is a loop */
56*088332b5SXin Li   lu_byte insidetbc;  /* true if inside the scope of a to-be-closed var. */
57*088332b5SXin Li } BlockCnt;
58*088332b5SXin Li 
59*088332b5SXin Li 
60*088332b5SXin Li 
61*088332b5SXin Li /*
62*088332b5SXin Li ** prototypes for recursive non-terminal functions
63*088332b5SXin Li */
64*088332b5SXin Li static void statement (LexState *ls);
65*088332b5SXin Li static void expr (LexState *ls, expdesc *v);
66*088332b5SXin Li 
67*088332b5SXin Li 
error_expected(LexState * ls,int token)68*088332b5SXin Li static l_noret error_expected (LexState *ls, int token) {
69*088332b5SXin Li   luaX_syntaxerror(ls,
70*088332b5SXin Li       luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
71*088332b5SXin Li }
72*088332b5SXin Li 
73*088332b5SXin Li 
errorlimit(FuncState * fs,int limit,const char * what)74*088332b5SXin Li static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
75*088332b5SXin Li   lua_State *L = fs->ls->L;
76*088332b5SXin Li   const char *msg;
77*088332b5SXin Li   int line = fs->f->linedefined;
78*088332b5SXin Li   const char *where = (line == 0)
79*088332b5SXin Li                       ? "main function"
80*088332b5SXin Li                       : luaO_pushfstring(L, "function at line %d", line);
81*088332b5SXin Li   msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
82*088332b5SXin Li                              what, limit, where);
83*088332b5SXin Li   luaX_syntaxerror(fs->ls, msg);
84*088332b5SXin Li }
85*088332b5SXin Li 
86*088332b5SXin Li 
checklimit(FuncState * fs,int v,int l,const char * what)87*088332b5SXin Li static void checklimit (FuncState *fs, int v, int l, const char *what) {
88*088332b5SXin Li   if (v > l) errorlimit(fs, l, what);
89*088332b5SXin Li }
90*088332b5SXin Li 
91*088332b5SXin Li 
92*088332b5SXin Li /*
93*088332b5SXin Li ** Test whether next token is 'c'; if so, skip it.
94*088332b5SXin Li */
testnext(LexState * ls,int c)95*088332b5SXin Li static int testnext (LexState *ls, int c) {
96*088332b5SXin Li   if (ls->t.token == c) {
97*088332b5SXin Li     luaX_next(ls);
98*088332b5SXin Li     return 1;
99*088332b5SXin Li   }
100*088332b5SXin Li   else return 0;
101*088332b5SXin Li }
102*088332b5SXin Li 
103*088332b5SXin Li 
104*088332b5SXin Li /*
105*088332b5SXin Li ** Check that next token is 'c'.
106*088332b5SXin Li */
check(LexState * ls,int c)107*088332b5SXin Li static void check (LexState *ls, int c) {
108*088332b5SXin Li   if (ls->t.token != c)
109*088332b5SXin Li     error_expected(ls, c);
110*088332b5SXin Li }
111*088332b5SXin Li 
112*088332b5SXin Li 
113*088332b5SXin Li /*
114*088332b5SXin Li ** Check that next token is 'c' and skip it.
115*088332b5SXin Li */
checknext(LexState * ls,int c)116*088332b5SXin Li static void checknext (LexState *ls, int c) {
117*088332b5SXin Li   check(ls, c);
118*088332b5SXin Li   luaX_next(ls);
119*088332b5SXin Li }
120*088332b5SXin Li 
121*088332b5SXin Li 
122*088332b5SXin Li #define check_condition(ls,c,msg)	{ if (!(c)) luaX_syntaxerror(ls, msg); }
123*088332b5SXin Li 
124*088332b5SXin Li 
125*088332b5SXin Li /*
126*088332b5SXin Li ** Check that next token is 'what' and skip it. In case of error,
127*088332b5SXin Li ** raise an error that the expected 'what' should match a 'who'
128*088332b5SXin Li ** in line 'where' (if that is not the current line).
129*088332b5SXin Li */
check_match(LexState * ls,int what,int who,int where)130*088332b5SXin Li static void check_match (LexState *ls, int what, int who, int where) {
131*088332b5SXin Li   if (unlikely(!testnext(ls, what))) {
132*088332b5SXin Li     if (where == ls->linenumber)  /* all in the same line? */
133*088332b5SXin Li       error_expected(ls, what);  /* do not need a complex message */
134*088332b5SXin Li     else {
135*088332b5SXin Li       luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
136*088332b5SXin Li              "%s expected (to close %s at line %d)",
137*088332b5SXin Li               luaX_token2str(ls, what), luaX_token2str(ls, who), where));
138*088332b5SXin Li     }
139*088332b5SXin Li   }
140*088332b5SXin Li }
141*088332b5SXin Li 
142*088332b5SXin Li 
str_checkname(LexState * ls)143*088332b5SXin Li static TString *str_checkname (LexState *ls) {
144*088332b5SXin Li   TString *ts;
145*088332b5SXin Li   check(ls, TK_NAME);
146*088332b5SXin Li   ts = ls->t.seminfo.ts;
147*088332b5SXin Li   luaX_next(ls);
148*088332b5SXin Li   return ts;
149*088332b5SXin Li }
150*088332b5SXin Li 
151*088332b5SXin Li 
init_exp(expdesc * e,expkind k,int i)152*088332b5SXin Li static void init_exp (expdesc *e, expkind k, int i) {
153*088332b5SXin Li   e->f = e->t = NO_JUMP;
154*088332b5SXin Li   e->k = k;
155*088332b5SXin Li   e->u.info = i;
156*088332b5SXin Li }
157*088332b5SXin Li 
158*088332b5SXin Li 
codestring(expdesc * e,TString * s)159*088332b5SXin Li static void codestring (expdesc *e, TString *s) {
160*088332b5SXin Li   e->f = e->t = NO_JUMP;
161*088332b5SXin Li   e->k = VKSTR;
162*088332b5SXin Li   e->u.strval = s;
163*088332b5SXin Li }
164*088332b5SXin Li 
165*088332b5SXin Li 
codename(LexState * ls,expdesc * e)166*088332b5SXin Li static void codename (LexState *ls, expdesc *e) {
167*088332b5SXin Li   codestring(e, str_checkname(ls));
168*088332b5SXin Li }
169*088332b5SXin Li 
170*088332b5SXin Li 
171*088332b5SXin Li /*
172*088332b5SXin Li ** Register a new local variable in the active 'Proto' (for debug
173*088332b5SXin Li ** information).
174*088332b5SXin Li */
registerlocalvar(LexState * ls,FuncState * fs,TString * varname)175*088332b5SXin Li static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
176*088332b5SXin Li   Proto *f = fs->f;
177*088332b5SXin Li   int oldsize = f->sizelocvars;
178*088332b5SXin Li   luaM_growvector(ls->L, f->locvars, fs->ndebugvars, f->sizelocvars,
179*088332b5SXin Li                   LocVar, SHRT_MAX, "local variables");
180*088332b5SXin Li   while (oldsize < f->sizelocvars)
181*088332b5SXin Li     f->locvars[oldsize++].varname = NULL;
182*088332b5SXin Li   f->locvars[fs->ndebugvars].varname = varname;
183*088332b5SXin Li   f->locvars[fs->ndebugvars].startpc = fs->pc;
184*088332b5SXin Li   luaC_objbarrier(ls->L, f, varname);
185*088332b5SXin Li   return fs->ndebugvars++;
186*088332b5SXin Li }
187*088332b5SXin Li 
188*088332b5SXin Li 
189*088332b5SXin Li /*
190*088332b5SXin Li ** Create a new local variable with the given 'name'. Return its index
191*088332b5SXin Li ** in the function.
192*088332b5SXin Li */
new_localvar(LexState * ls,TString * name)193*088332b5SXin Li static int new_localvar (LexState *ls, TString *name) {
194*088332b5SXin Li   lua_State *L = ls->L;
195*088332b5SXin Li   FuncState *fs = ls->fs;
196*088332b5SXin Li   Dyndata *dyd = ls->dyd;
197*088332b5SXin Li   Vardesc *var;
198*088332b5SXin Li   checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
199*088332b5SXin Li                  MAXVARS, "local variables");
200*088332b5SXin Li   luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
201*088332b5SXin Li                   dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
202*088332b5SXin Li   var = &dyd->actvar.arr[dyd->actvar.n++];
203*088332b5SXin Li   var->vd.kind = VDKREG;  /* default */
204*088332b5SXin Li   var->vd.name = name;
205*088332b5SXin Li   return dyd->actvar.n - 1 - fs->firstlocal;
206*088332b5SXin Li }
207*088332b5SXin Li 
208*088332b5SXin Li #define new_localvarliteral(ls,v) \
209*088332b5SXin Li     new_localvar(ls,  \
210*088332b5SXin Li       luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
211*088332b5SXin Li 
212*088332b5SXin Li 
213*088332b5SXin Li 
214*088332b5SXin Li /*
215*088332b5SXin Li ** Return the "variable description" (Vardesc) of a given variable.
216*088332b5SXin Li ** (Unless noted otherwise, all variables are referred to by their
217*088332b5SXin Li ** compiler indices.)
218*088332b5SXin Li */
getlocalvardesc(FuncState * fs,int vidx)219*088332b5SXin Li static Vardesc *getlocalvardesc (FuncState *fs, int vidx) {
220*088332b5SXin Li   return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx];
221*088332b5SXin Li }
222*088332b5SXin Li 
223*088332b5SXin Li 
224*088332b5SXin Li /*
225*088332b5SXin Li ** Convert 'nvar', a compiler index level, to it corresponding
226*088332b5SXin Li ** stack index level. For that, search for the highest variable
227*088332b5SXin Li ** below that level that is in the stack and uses its stack
228*088332b5SXin Li ** index ('sidx').
229*088332b5SXin Li */
stacklevel(FuncState * fs,int nvar)230*088332b5SXin Li static int stacklevel (FuncState *fs, int nvar) {
231*088332b5SXin Li   while (nvar-- > 0) {
232*088332b5SXin Li     Vardesc *vd = getlocalvardesc(fs, nvar);  /* get variable */
233*088332b5SXin Li     if (vd->vd.kind != RDKCTC)  /* is in the stack? */
234*088332b5SXin Li       return vd->vd.sidx + 1;
235*088332b5SXin Li   }
236*088332b5SXin Li   return 0;  /* no variables in the stack */
237*088332b5SXin Li }
238*088332b5SXin Li 
239*088332b5SXin Li 
240*088332b5SXin Li /*
241*088332b5SXin Li ** Return the number of variables in the stack for function 'fs'
242*088332b5SXin Li */
luaY_nvarstack(FuncState * fs)243*088332b5SXin Li int luaY_nvarstack (FuncState *fs) {
244*088332b5SXin Li   return stacklevel(fs, fs->nactvar);
245*088332b5SXin Li }
246*088332b5SXin Li 
247*088332b5SXin Li 
248*088332b5SXin Li /*
249*088332b5SXin Li ** Get the debug-information entry for current variable 'vidx'.
250*088332b5SXin Li */
localdebuginfo(FuncState * fs,int vidx)251*088332b5SXin Li static LocVar *localdebuginfo (FuncState *fs, int vidx) {
252*088332b5SXin Li   Vardesc *vd = getlocalvardesc(fs,  vidx);
253*088332b5SXin Li   if (vd->vd.kind == RDKCTC)
254*088332b5SXin Li     return NULL;  /* no debug info. for constants */
255*088332b5SXin Li   else {
256*088332b5SXin Li     int idx = vd->vd.pidx;
257*088332b5SXin Li     lua_assert(idx < fs->ndebugvars);
258*088332b5SXin Li     return &fs->f->locvars[idx];
259*088332b5SXin Li   }
260*088332b5SXin Li }
261*088332b5SXin Li 
262*088332b5SXin Li 
263*088332b5SXin Li /*
264*088332b5SXin Li ** Create an expression representing variable 'vidx'
265*088332b5SXin Li */
init_var(FuncState * fs,expdesc * e,int vidx)266*088332b5SXin Li static void init_var (FuncState *fs, expdesc *e, int vidx) {
267*088332b5SXin Li   e->f = e->t = NO_JUMP;
268*088332b5SXin Li   e->k = VLOCAL;
269*088332b5SXin Li   e->u.var.vidx = vidx;
270*088332b5SXin Li   e->u.var.sidx = getlocalvardesc(fs, vidx)->vd.sidx;
271*088332b5SXin Li }
272*088332b5SXin Li 
273*088332b5SXin Li 
274*088332b5SXin Li /*
275*088332b5SXin Li ** Raises an error if variable described by 'e' is read only
276*088332b5SXin Li */
check_readonly(LexState * ls,expdesc * e)277*088332b5SXin Li static void check_readonly (LexState *ls, expdesc *e) {
278*088332b5SXin Li   FuncState *fs = ls->fs;
279*088332b5SXin Li   TString *varname = NULL;  /* to be set if variable is const */
280*088332b5SXin Li   switch (e->k) {
281*088332b5SXin Li     case VCONST: {
282*088332b5SXin Li       varname = ls->dyd->actvar.arr[e->u.info].vd.name;
283*088332b5SXin Li       break;
284*088332b5SXin Li     }
285*088332b5SXin Li     case VLOCAL: {
286*088332b5SXin Li       Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx);
287*088332b5SXin Li       if (vardesc->vd.kind != VDKREG)  /* not a regular variable? */
288*088332b5SXin Li         varname = vardesc->vd.name;
289*088332b5SXin Li       break;
290*088332b5SXin Li     }
291*088332b5SXin Li     case VUPVAL: {
292*088332b5SXin Li       Upvaldesc *up = &fs->f->upvalues[e->u.info];
293*088332b5SXin Li       if (up->kind != VDKREG)
294*088332b5SXin Li         varname = up->name;
295*088332b5SXin Li       break;
296*088332b5SXin Li     }
297*088332b5SXin Li     default:
298*088332b5SXin Li       return;  /* other cases cannot be read-only */
299*088332b5SXin Li   }
300*088332b5SXin Li   if (varname) {
301*088332b5SXin Li     const char *msg = luaO_pushfstring(ls->L,
302*088332b5SXin Li        "attempt to assign to const variable '%s'", getstr(varname));
303*088332b5SXin Li     luaK_semerror(ls, msg);  /* error */
304*088332b5SXin Li   }
305*088332b5SXin Li }
306*088332b5SXin Li 
307*088332b5SXin Li 
308*088332b5SXin Li /*
309*088332b5SXin Li ** Start the scope for the last 'nvars' created variables.
310*088332b5SXin Li */
adjustlocalvars(LexState * ls,int nvars)311*088332b5SXin Li static void adjustlocalvars (LexState *ls, int nvars) {
312*088332b5SXin Li   FuncState *fs = ls->fs;
313*088332b5SXin Li   int stklevel = luaY_nvarstack(fs);
314*088332b5SXin Li   int i;
315*088332b5SXin Li   for (i = 0; i < nvars; i++) {
316*088332b5SXin Li     int vidx = fs->nactvar++;
317*088332b5SXin Li     Vardesc *var = getlocalvardesc(fs, vidx);
318*088332b5SXin Li     var->vd.sidx = stklevel++;
319*088332b5SXin Li     var->vd.pidx = registerlocalvar(ls, fs, var->vd.name);
320*088332b5SXin Li   }
321*088332b5SXin Li }
322*088332b5SXin Li 
323*088332b5SXin Li 
324*088332b5SXin Li /*
325*088332b5SXin Li ** Close the scope for all variables up to level 'tolevel'.
326*088332b5SXin Li ** (debug info.)
327*088332b5SXin Li */
removevars(FuncState * fs,int tolevel)328*088332b5SXin Li static void removevars (FuncState *fs, int tolevel) {
329*088332b5SXin Li   fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
330*088332b5SXin Li   while (fs->nactvar > tolevel) {
331*088332b5SXin Li     LocVar *var = localdebuginfo(fs, --fs->nactvar);
332*088332b5SXin Li     if (var)  /* does it have debug information? */
333*088332b5SXin Li       var->endpc = fs->pc;
334*088332b5SXin Li   }
335*088332b5SXin Li }
336*088332b5SXin Li 
337*088332b5SXin Li 
338*088332b5SXin Li /*
339*088332b5SXin Li ** Search the upvalues of the function 'fs' for one
340*088332b5SXin Li ** with the given 'name'.
341*088332b5SXin Li */
searchupvalue(FuncState * fs,TString * name)342*088332b5SXin Li static int searchupvalue (FuncState *fs, TString *name) {
343*088332b5SXin Li   int i;
344*088332b5SXin Li   Upvaldesc *up = fs->f->upvalues;
345*088332b5SXin Li   for (i = 0; i < fs->nups; i++) {
346*088332b5SXin Li     if (eqstr(up[i].name, name)) return i;
347*088332b5SXin Li   }
348*088332b5SXin Li   return -1;  /* not found */
349*088332b5SXin Li }
350*088332b5SXin Li 
351*088332b5SXin Li 
allocupvalue(FuncState * fs)352*088332b5SXin Li static Upvaldesc *allocupvalue (FuncState *fs) {
353*088332b5SXin Li   Proto *f = fs->f;
354*088332b5SXin Li   int oldsize = f->sizeupvalues;
355*088332b5SXin Li   checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
356*088332b5SXin Li   luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
357*088332b5SXin Li                   Upvaldesc, MAXUPVAL, "upvalues");
358*088332b5SXin Li   while (oldsize < f->sizeupvalues)
359*088332b5SXin Li     f->upvalues[oldsize++].name = NULL;
360*088332b5SXin Li   return &f->upvalues[fs->nups++];
361*088332b5SXin Li }
362*088332b5SXin Li 
363*088332b5SXin Li 
newupvalue(FuncState * fs,TString * name,expdesc * v)364*088332b5SXin Li static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
365*088332b5SXin Li   Upvaldesc *up = allocupvalue(fs);
366*088332b5SXin Li   FuncState *prev = fs->prev;
367*088332b5SXin Li   if (v->k == VLOCAL) {
368*088332b5SXin Li     up->instack = 1;
369*088332b5SXin Li     up->idx = v->u.var.sidx;
370*088332b5SXin Li     up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind;
371*088332b5SXin Li     lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name));
372*088332b5SXin Li   }
373*088332b5SXin Li   else {
374*088332b5SXin Li     up->instack = 0;
375*088332b5SXin Li     up->idx = cast_byte(v->u.info);
376*088332b5SXin Li     up->kind = prev->f->upvalues[v->u.info].kind;
377*088332b5SXin Li     lua_assert(eqstr(name, prev->f->upvalues[v->u.info].name));
378*088332b5SXin Li   }
379*088332b5SXin Li   up->name = name;
380*088332b5SXin Li   luaC_objbarrier(fs->ls->L, fs->f, name);
381*088332b5SXin Li   return fs->nups - 1;
382*088332b5SXin Li }
383*088332b5SXin Li 
384*088332b5SXin Li 
385*088332b5SXin Li /*
386*088332b5SXin Li ** Look for an active local variable with the name 'n' in the
387*088332b5SXin Li ** function 'fs'. If found, initialize 'var' with it and return
388*088332b5SXin Li ** its expression kind; otherwise return -1.
389*088332b5SXin Li */
searchvar(FuncState * fs,TString * n,expdesc * var)390*088332b5SXin Li static int searchvar (FuncState *fs, TString *n, expdesc *var) {
391*088332b5SXin Li   int i;
392*088332b5SXin Li   for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
393*088332b5SXin Li     Vardesc *vd = getlocalvardesc(fs, i);
394*088332b5SXin Li     if (eqstr(n, vd->vd.name)) {  /* found? */
395*088332b5SXin Li       if (vd->vd.kind == RDKCTC)  /* compile-time constant? */
396*088332b5SXin Li         init_exp(var, VCONST, fs->firstlocal + i);
397*088332b5SXin Li       else  /* real variable */
398*088332b5SXin Li         init_var(fs, var, i);
399*088332b5SXin Li       return var->k;
400*088332b5SXin Li     }
401*088332b5SXin Li   }
402*088332b5SXin Li   return -1;  /* not found */
403*088332b5SXin Li }
404*088332b5SXin Li 
405*088332b5SXin Li 
406*088332b5SXin Li /*
407*088332b5SXin Li ** Mark block where variable at given level was defined
408*088332b5SXin Li ** (to emit close instructions later).
409*088332b5SXin Li */
markupval(FuncState * fs,int level)410*088332b5SXin Li static void markupval (FuncState *fs, int level) {
411*088332b5SXin Li   BlockCnt *bl = fs->bl;
412*088332b5SXin Li   while (bl->nactvar > level)
413*088332b5SXin Li     bl = bl->previous;
414*088332b5SXin Li   bl->upval = 1;
415*088332b5SXin Li   fs->needclose = 1;
416*088332b5SXin Li }
417*088332b5SXin Li 
418*088332b5SXin Li 
419*088332b5SXin Li /*
420*088332b5SXin Li ** Find a variable with the given name 'n'. If it is an upvalue, add
421*088332b5SXin Li ** this upvalue into all intermediate functions. If it is a global, set
422*088332b5SXin Li ** 'var' as 'void' as a flag.
423*088332b5SXin Li */
singlevaraux(FuncState * fs,TString * n,expdesc * var,int base)424*088332b5SXin Li static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
425*088332b5SXin Li   if (fs == NULL)  /* no more levels? */
426*088332b5SXin Li     init_exp(var, VVOID, 0);  /* default is global */
427*088332b5SXin Li   else {
428*088332b5SXin Li     int v = searchvar(fs, n, var);  /* look up locals at current level */
429*088332b5SXin Li     if (v >= 0) {  /* found? */
430*088332b5SXin Li       if (v == VLOCAL && !base)
431*088332b5SXin Li         markupval(fs, var->u.var.vidx);  /* local will be used as an upval */
432*088332b5SXin Li     }
433*088332b5SXin Li     else {  /* not found as local at current level; try upvalues */
434*088332b5SXin Li       int idx = searchupvalue(fs, n);  /* try existing upvalues */
435*088332b5SXin Li       if (idx < 0) {  /* not found? */
436*088332b5SXin Li         singlevaraux(fs->prev, n, var, 0);  /* try upper levels */
437*088332b5SXin Li         if (var->k == VLOCAL || var->k == VUPVAL)  /* local or upvalue? */
438*088332b5SXin Li           idx  = newupvalue(fs, n, var);  /* will be a new upvalue */
439*088332b5SXin Li         else  /* it is a global or a constant */
440*088332b5SXin Li           return;  /* don't need to do anything at this level */
441*088332b5SXin Li       }
442*088332b5SXin Li       init_exp(var, VUPVAL, idx);  /* new or old upvalue */
443*088332b5SXin Li     }
444*088332b5SXin Li   }
445*088332b5SXin Li }
446*088332b5SXin Li 
447*088332b5SXin Li 
448*088332b5SXin Li /*
449*088332b5SXin Li ** Find a variable with the given name 'n', handling global variables
450*088332b5SXin Li ** too.
451*088332b5SXin Li */
singlevar(LexState * ls,expdesc * var)452*088332b5SXin Li static void singlevar (LexState *ls, expdesc *var) {
453*088332b5SXin Li   TString *varname = str_checkname(ls);
454*088332b5SXin Li   FuncState *fs = ls->fs;
455*088332b5SXin Li   singlevaraux(fs, varname, var, 1);
456*088332b5SXin Li   if (var->k == VVOID) {  /* global name? */
457*088332b5SXin Li     expdesc key;
458*088332b5SXin Li     singlevaraux(fs, ls->envn, var, 1);  /* get environment variable */
459*088332b5SXin Li     lua_assert(var->k != VVOID);  /* this one must exist */
460*088332b5SXin Li     codestring(&key, varname);  /* key is variable name */
461*088332b5SXin Li     luaK_indexed(fs, var, &key);  /* env[varname] */
462*088332b5SXin Li   }
463*088332b5SXin Li }
464*088332b5SXin Li 
465*088332b5SXin Li 
466*088332b5SXin Li /*
467*088332b5SXin Li ** Adjust the number of results from an expression list 'e' with 'nexps'
468*088332b5SXin Li ** expressions to 'nvars' values.
469*088332b5SXin Li */
adjust_assign(LexState * ls,int nvars,int nexps,expdesc * e)470*088332b5SXin Li static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
471*088332b5SXin Li   FuncState *fs = ls->fs;
472*088332b5SXin Li   int needed = nvars - nexps;  /* extra values needed */
473*088332b5SXin Li   if (hasmultret(e->k)) {  /* last expression has multiple returns? */
474*088332b5SXin Li     int extra = needed + 1;  /* discount last expression itself */
475*088332b5SXin Li     if (extra < 0)
476*088332b5SXin Li       extra = 0;
477*088332b5SXin Li     luaK_setreturns(fs, e, extra);  /* last exp. provides the difference */
478*088332b5SXin Li   }
479*088332b5SXin Li   else {
480*088332b5SXin Li     if (e->k != VVOID)  /* at least one expression? */
481*088332b5SXin Li       luaK_exp2nextreg(fs, e);  /* close last expression */
482*088332b5SXin Li     if (needed > 0)  /* missing values? */
483*088332b5SXin Li       luaK_nil(fs, fs->freereg, needed);  /* complete with nils */
484*088332b5SXin Li   }
485*088332b5SXin Li   if (needed > 0)
486*088332b5SXin Li     luaK_reserveregs(fs, needed);  /* registers for extra values */
487*088332b5SXin Li   else  /* adding 'needed' is actually a subtraction */
488*088332b5SXin Li     fs->freereg += needed;  /* remove extra values */
489*088332b5SXin Li }
490*088332b5SXin Li 
491*088332b5SXin Li 
492*088332b5SXin Li /*
493*088332b5SXin Li ** Macros to limit the maximum recursion depth while parsing
494*088332b5SXin Li */
495*088332b5SXin Li #define enterlevel(ls)	luaE_enterCcall((ls)->L)
496*088332b5SXin Li 
497*088332b5SXin Li #define leavelevel(ls)	luaE_exitCcall((ls)->L)
498*088332b5SXin Li 
499*088332b5SXin Li 
500*088332b5SXin Li /*
501*088332b5SXin Li ** Generates an error that a goto jumps into the scope of some
502*088332b5SXin Li ** local variable.
503*088332b5SXin Li */
jumpscopeerror(LexState * ls,Labeldesc * gt)504*088332b5SXin Li static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
505*088332b5SXin Li   const char *varname = getstr(getlocalvardesc(ls->fs, gt->nactvar)->vd.name);
506*088332b5SXin Li   const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'";
507*088332b5SXin Li   msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname);
508*088332b5SXin Li   luaK_semerror(ls, msg);  /* raise the error */
509*088332b5SXin Li }
510*088332b5SXin Li 
511*088332b5SXin Li 
512*088332b5SXin Li /*
513*088332b5SXin Li ** Solves the goto at index 'g' to given 'label' and removes it
514*088332b5SXin Li ** from the list of pending goto's.
515*088332b5SXin Li ** If it jumps into the scope of some variable, raises an error.
516*088332b5SXin Li */
solvegoto(LexState * ls,int g,Labeldesc * label)517*088332b5SXin Li static void solvegoto (LexState *ls, int g, Labeldesc *label) {
518*088332b5SXin Li   int i;
519*088332b5SXin Li   Labellist *gl = &ls->dyd->gt;  /* list of goto's */
520*088332b5SXin Li   Labeldesc *gt = &gl->arr[g];  /* goto to be resolved */
521*088332b5SXin Li   lua_assert(eqstr(gt->name, label->name));
522*088332b5SXin Li   if (unlikely(gt->nactvar < label->nactvar))  /* enter some scope? */
523*088332b5SXin Li     jumpscopeerror(ls, gt);
524*088332b5SXin Li   luaK_patchlist(ls->fs, gt->pc, label->pc);
525*088332b5SXin Li   for (i = g; i < gl->n - 1; i++)  /* remove goto from pending list */
526*088332b5SXin Li     gl->arr[i] = gl->arr[i + 1];
527*088332b5SXin Li   gl->n--;
528*088332b5SXin Li }
529*088332b5SXin Li 
530*088332b5SXin Li 
531*088332b5SXin Li /*
532*088332b5SXin Li ** Search for an active label with the given name.
533*088332b5SXin Li */
findlabel(LexState * ls,TString * name)534*088332b5SXin Li static Labeldesc *findlabel (LexState *ls, TString *name) {
535*088332b5SXin Li   int i;
536*088332b5SXin Li   Dyndata *dyd = ls->dyd;
537*088332b5SXin Li   /* check labels in current function for a match */
538*088332b5SXin Li   for (i = ls->fs->firstlabel; i < dyd->label.n; i++) {
539*088332b5SXin Li     Labeldesc *lb = &dyd->label.arr[i];
540*088332b5SXin Li     if (eqstr(lb->name, name))  /* correct label? */
541*088332b5SXin Li       return lb;
542*088332b5SXin Li   }
543*088332b5SXin Li   return NULL;  /* label not found */
544*088332b5SXin Li }
545*088332b5SXin Li 
546*088332b5SXin Li 
547*088332b5SXin Li /*
548*088332b5SXin Li ** Adds a new label/goto in the corresponding list.
549*088332b5SXin Li */
newlabelentry(LexState * ls,Labellist * l,TString * name,int line,int pc)550*088332b5SXin Li static int newlabelentry (LexState *ls, Labellist *l, TString *name,
551*088332b5SXin Li                           int line, int pc) {
552*088332b5SXin Li   int n = l->n;
553*088332b5SXin Li   luaM_growvector(ls->L, l->arr, n, l->size,
554*088332b5SXin Li                   Labeldesc, SHRT_MAX, "labels/gotos");
555*088332b5SXin Li   l->arr[n].name = name;
556*088332b5SXin Li   l->arr[n].line = line;
557*088332b5SXin Li   l->arr[n].nactvar = ls->fs->nactvar;
558*088332b5SXin Li   l->arr[n].close = 0;
559*088332b5SXin Li   l->arr[n].pc = pc;
560*088332b5SXin Li   l->n = n + 1;
561*088332b5SXin Li   return n;
562*088332b5SXin Li }
563*088332b5SXin Li 
564*088332b5SXin Li 
newgotoentry(LexState * ls,TString * name,int line,int pc)565*088332b5SXin Li static int newgotoentry (LexState *ls, TString *name, int line, int pc) {
566*088332b5SXin Li   return newlabelentry(ls, &ls->dyd->gt, name, line, pc);
567*088332b5SXin Li }
568*088332b5SXin Li 
569*088332b5SXin Li 
570*088332b5SXin Li /*
571*088332b5SXin Li ** Solves forward jumps. Check whether new label 'lb' matches any
572*088332b5SXin Li ** pending gotos in current block and solves them. Return true
573*088332b5SXin Li ** if any of the goto's need to close upvalues.
574*088332b5SXin Li */
solvegotos(LexState * ls,Labeldesc * lb)575*088332b5SXin Li static int solvegotos (LexState *ls, Labeldesc *lb) {
576*088332b5SXin Li   Labellist *gl = &ls->dyd->gt;
577*088332b5SXin Li   int i = ls->fs->bl->firstgoto;
578*088332b5SXin Li   int needsclose = 0;
579*088332b5SXin Li   while (i < gl->n) {
580*088332b5SXin Li     if (eqstr(gl->arr[i].name, lb->name)) {
581*088332b5SXin Li       needsclose |= gl->arr[i].close;
582*088332b5SXin Li       solvegoto(ls, i, lb);  /* will remove 'i' from the list */
583*088332b5SXin Li     }
584*088332b5SXin Li     else
585*088332b5SXin Li       i++;
586*088332b5SXin Li   }
587*088332b5SXin Li   return needsclose;
588*088332b5SXin Li }
589*088332b5SXin Li 
590*088332b5SXin Li 
591*088332b5SXin Li /*
592*088332b5SXin Li ** Create a new label with the given 'name' at the given 'line'.
593*088332b5SXin Li ** 'last' tells whether label is the last non-op statement in its
594*088332b5SXin Li ** block. Solves all pending goto's to this new label and adds
595*088332b5SXin Li ** a close instruction if necessary.
596*088332b5SXin Li ** Returns true iff it added a close instruction.
597*088332b5SXin Li */
createlabel(LexState * ls,TString * name,int line,int last)598*088332b5SXin Li static int createlabel (LexState *ls, TString *name, int line,
599*088332b5SXin Li                         int last) {
600*088332b5SXin Li   FuncState *fs = ls->fs;
601*088332b5SXin Li   Labellist *ll = &ls->dyd->label;
602*088332b5SXin Li   int l = newlabelentry(ls, ll, name, line, luaK_getlabel(fs));
603*088332b5SXin Li   if (last) {  /* label is last no-op statement in the block? */
604*088332b5SXin Li     /* assume that locals are already out of scope */
605*088332b5SXin Li     ll->arr[l].nactvar = fs->bl->nactvar;
606*088332b5SXin Li   }
607*088332b5SXin Li   if (solvegotos(ls, &ll->arr[l])) {  /* need close? */
608*088332b5SXin Li     luaK_codeABC(fs, OP_CLOSE, luaY_nvarstack(fs), 0, 0);
609*088332b5SXin Li     return 1;
610*088332b5SXin Li   }
611*088332b5SXin Li   return 0;
612*088332b5SXin Li }
613*088332b5SXin Li 
614*088332b5SXin Li 
615*088332b5SXin Li /*
616*088332b5SXin Li ** Adjust pending gotos to outer level of a block.
617*088332b5SXin Li */
movegotosout(FuncState * fs,BlockCnt * bl)618*088332b5SXin Li static void movegotosout (FuncState *fs, BlockCnt *bl) {
619*088332b5SXin Li   int i;
620*088332b5SXin Li   Labellist *gl = &fs->ls->dyd->gt;
621*088332b5SXin Li   /* correct pending gotos to current block */
622*088332b5SXin Li   for (i = bl->firstgoto; i < gl->n; i++) {  /* for each pending goto */
623*088332b5SXin Li     Labeldesc *gt = &gl->arr[i];
624*088332b5SXin Li     /* leaving a variable scope? */
625*088332b5SXin Li     if (stacklevel(fs, gt->nactvar) > stacklevel(fs, bl->nactvar))
626*088332b5SXin Li       gt->close |= bl->upval;  /* jump may need a close */
627*088332b5SXin Li     gt->nactvar = bl->nactvar;  /* update goto level */
628*088332b5SXin Li   }
629*088332b5SXin Li }
630*088332b5SXin Li 
631*088332b5SXin Li 
enterblock(FuncState * fs,BlockCnt * bl,lu_byte isloop)632*088332b5SXin Li static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
633*088332b5SXin Li   bl->isloop = isloop;
634*088332b5SXin Li   bl->nactvar = fs->nactvar;
635*088332b5SXin Li   bl->firstlabel = fs->ls->dyd->label.n;
636*088332b5SXin Li   bl->firstgoto = fs->ls->dyd->gt.n;
637*088332b5SXin Li   bl->upval = 0;
638*088332b5SXin Li   bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc);
639*088332b5SXin Li   bl->previous = fs->bl;
640*088332b5SXin Li   fs->bl = bl;
641*088332b5SXin Li   lua_assert(fs->freereg == luaY_nvarstack(fs));
642*088332b5SXin Li }
643*088332b5SXin Li 
644*088332b5SXin Li 
645*088332b5SXin Li /*
646*088332b5SXin Li ** generates an error for an undefined 'goto'.
647*088332b5SXin Li */
undefgoto(LexState * ls,Labeldesc * gt)648*088332b5SXin Li static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
649*088332b5SXin Li   const char *msg;
650*088332b5SXin Li   if (eqstr(gt->name, luaS_newliteral(ls->L, "break"))) {
651*088332b5SXin Li     msg = "break outside loop at line %d";
652*088332b5SXin Li     msg = luaO_pushfstring(ls->L, msg, gt->line);
653*088332b5SXin Li   }
654*088332b5SXin Li   else {
655*088332b5SXin Li     msg = "no visible label '%s' for <goto> at line %d";
656*088332b5SXin Li     msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
657*088332b5SXin Li   }
658*088332b5SXin Li   luaK_semerror(ls, msg);
659*088332b5SXin Li }
660*088332b5SXin Li 
661*088332b5SXin Li 
leaveblock(FuncState * fs)662*088332b5SXin Li static void leaveblock (FuncState *fs) {
663*088332b5SXin Li   BlockCnt *bl = fs->bl;
664*088332b5SXin Li   LexState *ls = fs->ls;
665*088332b5SXin Li   int hasclose = 0;
666*088332b5SXin Li   int stklevel = stacklevel(fs, bl->nactvar);  /* level outside the block */
667*088332b5SXin Li   if (bl->isloop)  /* fix pending breaks? */
668*088332b5SXin Li     hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0);
669*088332b5SXin Li   if (!hasclose && bl->previous && bl->upval)
670*088332b5SXin Li     luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0);
671*088332b5SXin Li   fs->bl = bl->previous;
672*088332b5SXin Li   removevars(fs, bl->nactvar);
673*088332b5SXin Li   lua_assert(bl->nactvar == fs->nactvar);
674*088332b5SXin Li   fs->freereg = stklevel;  /* free registers */
675*088332b5SXin Li   ls->dyd->label.n = bl->firstlabel;  /* remove local labels */
676*088332b5SXin Li   if (bl->previous)  /* inner block? */
677*088332b5SXin Li     movegotosout(fs, bl);  /* update pending gotos to outer block */
678*088332b5SXin Li   else {
679*088332b5SXin Li     if (bl->firstgoto < ls->dyd->gt.n)  /* pending gotos in outer block? */
680*088332b5SXin Li       undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]);  /* error */
681*088332b5SXin Li   }
682*088332b5SXin Li }
683*088332b5SXin Li 
684*088332b5SXin Li 
685*088332b5SXin Li /*
686*088332b5SXin Li ** adds a new prototype into list of prototypes
687*088332b5SXin Li */
addprototype(LexState * ls)688*088332b5SXin Li static Proto *addprototype (LexState *ls) {
689*088332b5SXin Li   Proto *clp;
690*088332b5SXin Li   lua_State *L = ls->L;
691*088332b5SXin Li   FuncState *fs = ls->fs;
692*088332b5SXin Li   Proto *f = fs->f;  /* prototype of current function */
693*088332b5SXin Li   if (fs->np >= f->sizep) {
694*088332b5SXin Li     int oldsize = f->sizep;
695*088332b5SXin Li     luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
696*088332b5SXin Li     while (oldsize < f->sizep)
697*088332b5SXin Li       f->p[oldsize++] = NULL;
698*088332b5SXin Li   }
699*088332b5SXin Li   f->p[fs->np++] = clp = luaF_newproto(L);
700*088332b5SXin Li   luaC_objbarrier(L, f, clp);
701*088332b5SXin Li   return clp;
702*088332b5SXin Li }
703*088332b5SXin Li 
704*088332b5SXin Li 
705*088332b5SXin Li /*
706*088332b5SXin Li ** codes instruction to create new closure in parent function.
707*088332b5SXin Li ** The OP_CLOSURE instruction uses the last available register,
708*088332b5SXin Li ** so that, if it invokes the GC, the GC knows which registers
709*088332b5SXin Li ** are in use at that time.
710*088332b5SXin Li 
711*088332b5SXin Li */
codeclosure(LexState * ls,expdesc * v)712*088332b5SXin Li static void codeclosure (LexState *ls, expdesc *v) {
713*088332b5SXin Li   FuncState *fs = ls->fs->prev;
714*088332b5SXin Li   init_exp(v, VRELOC, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
715*088332b5SXin Li   luaK_exp2nextreg(fs, v);  /* fix it at the last register */
716*088332b5SXin Li }
717*088332b5SXin Li 
718*088332b5SXin Li 
open_func(LexState * ls,FuncState * fs,BlockCnt * bl)719*088332b5SXin Li static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
720*088332b5SXin Li   Proto *f = fs->f;
721*088332b5SXin Li   fs->prev = ls->fs;  /* linked list of funcstates */
722*088332b5SXin Li   fs->ls = ls;
723*088332b5SXin Li   ls->fs = fs;
724*088332b5SXin Li   fs->pc = 0;
725*088332b5SXin Li   fs->previousline = f->linedefined;
726*088332b5SXin Li   fs->iwthabs = 0;
727*088332b5SXin Li   fs->lasttarget = 0;
728*088332b5SXin Li   fs->freereg = 0;
729*088332b5SXin Li   fs->nk = 0;
730*088332b5SXin Li   fs->nabslineinfo = 0;
731*088332b5SXin Li   fs->np = 0;
732*088332b5SXin Li   fs->nups = 0;
733*088332b5SXin Li   fs->ndebugvars = 0;
734*088332b5SXin Li   fs->nactvar = 0;
735*088332b5SXin Li   fs->needclose = 0;
736*088332b5SXin Li   fs->firstlocal = ls->dyd->actvar.n;
737*088332b5SXin Li   fs->firstlabel = ls->dyd->label.n;
738*088332b5SXin Li   fs->bl = NULL;
739*088332b5SXin Li   f->source = ls->source;
740*088332b5SXin Li   luaC_objbarrier(ls->L, f, f->source);
741*088332b5SXin Li   f->maxstacksize = 2;  /* registers 0/1 are always valid */
742*088332b5SXin Li   enterblock(fs, bl, 0);
743*088332b5SXin Li }
744*088332b5SXin Li 
745*088332b5SXin Li 
close_func(LexState * ls)746*088332b5SXin Li static void close_func (LexState *ls) {
747*088332b5SXin Li   lua_State *L = ls->L;
748*088332b5SXin Li   FuncState *fs = ls->fs;
749*088332b5SXin Li   Proto *f = fs->f;
750*088332b5SXin Li   luaK_ret(fs, luaY_nvarstack(fs), 0);  /* final return */
751*088332b5SXin Li   leaveblock(fs);
752*088332b5SXin Li   lua_assert(fs->bl == NULL);
753*088332b5SXin Li   luaK_finish(fs);
754*088332b5SXin Li   luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction);
755*088332b5SXin Li   luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte);
756*088332b5SXin Li   luaM_shrinkvector(L, f->abslineinfo, f->sizeabslineinfo,
757*088332b5SXin Li                        fs->nabslineinfo, AbsLineInfo);
758*088332b5SXin Li   luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue);
759*088332b5SXin Li   luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *);
760*088332b5SXin Li   luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar);
761*088332b5SXin Li   luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
762*088332b5SXin Li   ls->fs = fs->prev;
763*088332b5SXin Li   luaC_checkGC(L);
764*088332b5SXin Li }
765*088332b5SXin Li 
766*088332b5SXin Li 
767*088332b5SXin Li 
768*088332b5SXin Li /*============================================================*/
769*088332b5SXin Li /* GRAMMAR RULES */
770*088332b5SXin Li /*============================================================*/
771*088332b5SXin Li 
772*088332b5SXin Li 
773*088332b5SXin Li /*
774*088332b5SXin Li ** check whether current token is in the follow set of a block.
775*088332b5SXin Li ** 'until' closes syntactical blocks, but do not close scope,
776*088332b5SXin Li ** so it is handled in separate.
777*088332b5SXin Li */
block_follow(LexState * ls,int withuntil)778*088332b5SXin Li static int block_follow (LexState *ls, int withuntil) {
779*088332b5SXin Li   switch (ls->t.token) {
780*088332b5SXin Li     case TK_ELSE: case TK_ELSEIF:
781*088332b5SXin Li     case TK_END: case TK_EOS:
782*088332b5SXin Li       return 1;
783*088332b5SXin Li     case TK_UNTIL: return withuntil;
784*088332b5SXin Li     default: return 0;
785*088332b5SXin Li   }
786*088332b5SXin Li }
787*088332b5SXin Li 
788*088332b5SXin Li 
statlist(LexState * ls)789*088332b5SXin Li static void statlist (LexState *ls) {
790*088332b5SXin Li   /* statlist -> { stat [';'] } */
791*088332b5SXin Li   while (!block_follow(ls, 1)) {
792*088332b5SXin Li     if (ls->t.token == TK_RETURN) {
793*088332b5SXin Li       statement(ls);
794*088332b5SXin Li       return;  /* 'return' must be last statement */
795*088332b5SXin Li     }
796*088332b5SXin Li     statement(ls);
797*088332b5SXin Li   }
798*088332b5SXin Li }
799*088332b5SXin Li 
800*088332b5SXin Li 
fieldsel(LexState * ls,expdesc * v)801*088332b5SXin Li static void fieldsel (LexState *ls, expdesc *v) {
802*088332b5SXin Li   /* fieldsel -> ['.' | ':'] NAME */
803*088332b5SXin Li   FuncState *fs = ls->fs;
804*088332b5SXin Li   expdesc key;
805*088332b5SXin Li   luaK_exp2anyregup(fs, v);
806*088332b5SXin Li   luaX_next(ls);  /* skip the dot or colon */
807*088332b5SXin Li   codename(ls, &key);
808*088332b5SXin Li   luaK_indexed(fs, v, &key);
809*088332b5SXin Li }
810*088332b5SXin Li 
811*088332b5SXin Li 
yindex(LexState * ls,expdesc * v)812*088332b5SXin Li static void yindex (LexState *ls, expdesc *v) {
813*088332b5SXin Li   /* index -> '[' expr ']' */
814*088332b5SXin Li   luaX_next(ls);  /* skip the '[' */
815*088332b5SXin Li   expr(ls, v);
816*088332b5SXin Li   luaK_exp2val(ls->fs, v);
817*088332b5SXin Li   checknext(ls, ']');
818*088332b5SXin Li }
819*088332b5SXin Li 
820*088332b5SXin Li 
821*088332b5SXin Li /*
822*088332b5SXin Li ** {======================================================================
823*088332b5SXin Li ** Rules for Constructors
824*088332b5SXin Li ** =======================================================================
825*088332b5SXin Li */
826*088332b5SXin Li 
827*088332b5SXin Li 
828*088332b5SXin Li typedef struct ConsControl {
829*088332b5SXin Li   expdesc v;  /* last list item read */
830*088332b5SXin Li   expdesc *t;  /* table descriptor */
831*088332b5SXin Li   int nh;  /* total number of 'record' elements */
832*088332b5SXin Li   int na;  /* number of array elements already stored */
833*088332b5SXin Li   int tostore;  /* number of array elements pending to be stored */
834*088332b5SXin Li } ConsControl;
835*088332b5SXin Li 
836*088332b5SXin Li 
recfield(LexState * ls,ConsControl * cc)837*088332b5SXin Li static void recfield (LexState *ls, ConsControl *cc) {
838*088332b5SXin Li   /* recfield -> (NAME | '['exp']') = exp */
839*088332b5SXin Li   FuncState *fs = ls->fs;
840*088332b5SXin Li   int reg = ls->fs->freereg;
841*088332b5SXin Li   expdesc tab, key, val;
842*088332b5SXin Li   if (ls->t.token == TK_NAME) {
843*088332b5SXin Li     checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
844*088332b5SXin Li     codename(ls, &key);
845*088332b5SXin Li   }
846*088332b5SXin Li   else  /* ls->t.token == '[' */
847*088332b5SXin Li     yindex(ls, &key);
848*088332b5SXin Li   cc->nh++;
849*088332b5SXin Li   checknext(ls, '=');
850*088332b5SXin Li   tab = *cc->t;
851*088332b5SXin Li   luaK_indexed(fs, &tab, &key);
852*088332b5SXin Li   expr(ls, &val);
853*088332b5SXin Li   luaK_storevar(fs, &tab, &val);
854*088332b5SXin Li   fs->freereg = reg;  /* free registers */
855*088332b5SXin Li }
856*088332b5SXin Li 
857*088332b5SXin Li 
closelistfield(FuncState * fs,ConsControl * cc)858*088332b5SXin Li static void closelistfield (FuncState *fs, ConsControl *cc) {
859*088332b5SXin Li   if (cc->v.k == VVOID) return;  /* there is no list item */
860*088332b5SXin Li   luaK_exp2nextreg(fs, &cc->v);
861*088332b5SXin Li   cc->v.k = VVOID;
862*088332b5SXin Li   if (cc->tostore == LFIELDS_PER_FLUSH) {
863*088332b5SXin Li     luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);  /* flush */
864*088332b5SXin Li     cc->na += cc->tostore;
865*088332b5SXin Li     cc->tostore = 0;  /* no more items pending */
866*088332b5SXin Li   }
867*088332b5SXin Li }
868*088332b5SXin Li 
869*088332b5SXin Li 
lastlistfield(FuncState * fs,ConsControl * cc)870*088332b5SXin Li static void lastlistfield (FuncState *fs, ConsControl *cc) {
871*088332b5SXin Li   if (cc->tostore == 0) return;
872*088332b5SXin Li   if (hasmultret(cc->v.k)) {
873*088332b5SXin Li     luaK_setmultret(fs, &cc->v);
874*088332b5SXin Li     luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
875*088332b5SXin Li     cc->na--;  /* do not count last expression (unknown number of elements) */
876*088332b5SXin Li   }
877*088332b5SXin Li   else {
878*088332b5SXin Li     if (cc->v.k != VVOID)
879*088332b5SXin Li       luaK_exp2nextreg(fs, &cc->v);
880*088332b5SXin Li     luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
881*088332b5SXin Li   }
882*088332b5SXin Li   cc->na += cc->tostore;
883*088332b5SXin Li }
884*088332b5SXin Li 
885*088332b5SXin Li 
listfield(LexState * ls,ConsControl * cc)886*088332b5SXin Li static void listfield (LexState *ls, ConsControl *cc) {
887*088332b5SXin Li   /* listfield -> exp */
888*088332b5SXin Li   expr(ls, &cc->v);
889*088332b5SXin Li   cc->tostore++;
890*088332b5SXin Li }
891*088332b5SXin Li 
892*088332b5SXin Li 
field(LexState * ls,ConsControl * cc)893*088332b5SXin Li static void field (LexState *ls, ConsControl *cc) {
894*088332b5SXin Li   /* field -> listfield | recfield */
895*088332b5SXin Li   switch(ls->t.token) {
896*088332b5SXin Li     case TK_NAME: {  /* may be 'listfield' or 'recfield' */
897*088332b5SXin Li       if (luaX_lookahead(ls) != '=')  /* expression? */
898*088332b5SXin Li         listfield(ls, cc);
899*088332b5SXin Li       else
900*088332b5SXin Li         recfield(ls, cc);
901*088332b5SXin Li       break;
902*088332b5SXin Li     }
903*088332b5SXin Li     case '[': {
904*088332b5SXin Li       recfield(ls, cc);
905*088332b5SXin Li       break;
906*088332b5SXin Li     }
907*088332b5SXin Li     default: {
908*088332b5SXin Li       listfield(ls, cc);
909*088332b5SXin Li       break;
910*088332b5SXin Li     }
911*088332b5SXin Li   }
912*088332b5SXin Li }
913*088332b5SXin Li 
914*088332b5SXin Li 
constructor(LexState * ls,expdesc * t)915*088332b5SXin Li static void constructor (LexState *ls, expdesc *t) {
916*088332b5SXin Li   /* constructor -> '{' [ field { sep field } [sep] ] '}'
917*088332b5SXin Li      sep -> ',' | ';' */
918*088332b5SXin Li   FuncState *fs = ls->fs;
919*088332b5SXin Li   int line = ls->linenumber;
920*088332b5SXin Li   int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
921*088332b5SXin Li   ConsControl cc;
922*088332b5SXin Li   luaK_code(fs, 0);  /* space for extra arg. */
923*088332b5SXin Li   cc.na = cc.nh = cc.tostore = 0;
924*088332b5SXin Li   cc.t = t;
925*088332b5SXin Li   init_exp(t, VNONRELOC, fs->freereg);  /* table will be at stack top */
926*088332b5SXin Li   luaK_reserveregs(fs, 1);
927*088332b5SXin Li   init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
928*088332b5SXin Li   checknext(ls, '{');
929*088332b5SXin Li   do {
930*088332b5SXin Li     lua_assert(cc.v.k == VVOID || cc.tostore > 0);
931*088332b5SXin Li     if (ls->t.token == '}') break;
932*088332b5SXin Li     closelistfield(fs, &cc);
933*088332b5SXin Li     field(ls, &cc);
934*088332b5SXin Li   } while (testnext(ls, ',') || testnext(ls, ';'));
935*088332b5SXin Li   check_match(ls, '}', '{', line);
936*088332b5SXin Li   lastlistfield(fs, &cc);
937*088332b5SXin Li   luaK_settablesize(fs, pc, t->u.info, cc.na, cc.nh);
938*088332b5SXin Li }
939*088332b5SXin Li 
940*088332b5SXin Li /* }====================================================================== */
941*088332b5SXin Li 
942*088332b5SXin Li 
setvararg(FuncState * fs,int nparams)943*088332b5SXin Li static void setvararg (FuncState *fs, int nparams) {
944*088332b5SXin Li   fs->f->is_vararg = 1;
945*088332b5SXin Li   luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0);
946*088332b5SXin Li }
947*088332b5SXin Li 
948*088332b5SXin Li 
parlist(LexState * ls)949*088332b5SXin Li static void parlist (LexState *ls) {
950*088332b5SXin Li   /* parlist -> [ param { ',' param } ] */
951*088332b5SXin Li   FuncState *fs = ls->fs;
952*088332b5SXin Li   Proto *f = fs->f;
953*088332b5SXin Li   int nparams = 0;
954*088332b5SXin Li   int isvararg = 0;
955*088332b5SXin Li   if (ls->t.token != ')') {  /* is 'parlist' not empty? */
956*088332b5SXin Li     do {
957*088332b5SXin Li       switch (ls->t.token) {
958*088332b5SXin Li         case TK_NAME: {  /* param -> NAME */
959*088332b5SXin Li           new_localvar(ls, str_checkname(ls));
960*088332b5SXin Li           nparams++;
961*088332b5SXin Li           break;
962*088332b5SXin Li         }
963*088332b5SXin Li         case TK_DOTS: {  /* param -> '...' */
964*088332b5SXin Li           luaX_next(ls);
965*088332b5SXin Li           isvararg = 1;
966*088332b5SXin Li           break;
967*088332b5SXin Li         }
968*088332b5SXin Li         default: luaX_syntaxerror(ls, "<name> or '...' expected");
969*088332b5SXin Li       }
970*088332b5SXin Li     } while (!isvararg && testnext(ls, ','));
971*088332b5SXin Li   }
972*088332b5SXin Li   adjustlocalvars(ls, nparams);
973*088332b5SXin Li   f->numparams = cast_byte(fs->nactvar);
974*088332b5SXin Li   if (isvararg)
975*088332b5SXin Li     setvararg(fs, f->numparams);  /* declared vararg */
976*088332b5SXin Li   luaK_reserveregs(fs, fs->nactvar);  /* reserve registers for parameters */
977*088332b5SXin Li }
978*088332b5SXin Li 
979*088332b5SXin Li 
body(LexState * ls,expdesc * e,int ismethod,int line)980*088332b5SXin Li static void body (LexState *ls, expdesc *e, int ismethod, int line) {
981*088332b5SXin Li   /* body ->  '(' parlist ')' block END */
982*088332b5SXin Li   FuncState new_fs;
983*088332b5SXin Li   BlockCnt bl;
984*088332b5SXin Li   new_fs.f = addprototype(ls);
985*088332b5SXin Li   new_fs.f->linedefined = line;
986*088332b5SXin Li   open_func(ls, &new_fs, &bl);
987*088332b5SXin Li   checknext(ls, '(');
988*088332b5SXin Li   if (ismethod) {
989*088332b5SXin Li     new_localvarliteral(ls, "self");  /* create 'self' parameter */
990*088332b5SXin Li     adjustlocalvars(ls, 1);
991*088332b5SXin Li   }
992*088332b5SXin Li   parlist(ls);
993*088332b5SXin Li   checknext(ls, ')');
994*088332b5SXin Li   statlist(ls);
995*088332b5SXin Li   new_fs.f->lastlinedefined = ls->linenumber;
996*088332b5SXin Li   check_match(ls, TK_END, TK_FUNCTION, line);
997*088332b5SXin Li   codeclosure(ls, e);
998*088332b5SXin Li   close_func(ls);
999*088332b5SXin Li }
1000*088332b5SXin Li 
1001*088332b5SXin Li 
explist(LexState * ls,expdesc * v)1002*088332b5SXin Li static int explist (LexState *ls, expdesc *v) {
1003*088332b5SXin Li   /* explist -> expr { ',' expr } */
1004*088332b5SXin Li   int n = 1;  /* at least one expression */
1005*088332b5SXin Li   expr(ls, v);
1006*088332b5SXin Li   while (testnext(ls, ',')) {
1007*088332b5SXin Li     luaK_exp2nextreg(ls->fs, v);
1008*088332b5SXin Li     expr(ls, v);
1009*088332b5SXin Li     n++;
1010*088332b5SXin Li   }
1011*088332b5SXin Li   return n;
1012*088332b5SXin Li }
1013*088332b5SXin Li 
1014*088332b5SXin Li 
funcargs(LexState * ls,expdesc * f,int line)1015*088332b5SXin Li static void funcargs (LexState *ls, expdesc *f, int line) {
1016*088332b5SXin Li   FuncState *fs = ls->fs;
1017*088332b5SXin Li   expdesc args;
1018*088332b5SXin Li   int base, nparams;
1019*088332b5SXin Li   switch (ls->t.token) {
1020*088332b5SXin Li     case '(': {  /* funcargs -> '(' [ explist ] ')' */
1021*088332b5SXin Li       luaX_next(ls);
1022*088332b5SXin Li       if (ls->t.token == ')')  /* arg list is empty? */
1023*088332b5SXin Li         args.k = VVOID;
1024*088332b5SXin Li       else {
1025*088332b5SXin Li         explist(ls, &args);
1026*088332b5SXin Li         if (hasmultret(args.k))
1027*088332b5SXin Li           luaK_setmultret(fs, &args);
1028*088332b5SXin Li       }
1029*088332b5SXin Li       check_match(ls, ')', '(', line);
1030*088332b5SXin Li       break;
1031*088332b5SXin Li     }
1032*088332b5SXin Li     case '{': {  /* funcargs -> constructor */
1033*088332b5SXin Li       constructor(ls, &args);
1034*088332b5SXin Li       break;
1035*088332b5SXin Li     }
1036*088332b5SXin Li     case TK_STRING: {  /* funcargs -> STRING */
1037*088332b5SXin Li       codestring(&args, ls->t.seminfo.ts);
1038*088332b5SXin Li       luaX_next(ls);  /* must use 'seminfo' before 'next' */
1039*088332b5SXin Li       break;
1040*088332b5SXin Li     }
1041*088332b5SXin Li     default: {
1042*088332b5SXin Li       luaX_syntaxerror(ls, "function arguments expected");
1043*088332b5SXin Li     }
1044*088332b5SXin Li   }
1045*088332b5SXin Li   lua_assert(f->k == VNONRELOC);
1046*088332b5SXin Li   base = f->u.info;  /* base register for call */
1047*088332b5SXin Li   if (hasmultret(args.k))
1048*088332b5SXin Li     nparams = LUA_MULTRET;  /* open call */
1049*088332b5SXin Li   else {
1050*088332b5SXin Li     if (args.k != VVOID)
1051*088332b5SXin Li       luaK_exp2nextreg(fs, &args);  /* close last argument */
1052*088332b5SXin Li     nparams = fs->freereg - (base+1);
1053*088332b5SXin Li   }
1054*088332b5SXin Li   init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
1055*088332b5SXin Li   luaK_fixline(fs, line);
1056*088332b5SXin Li   fs->freereg = base+1;  /* call remove function and arguments and leaves
1057*088332b5SXin Li                             (unless changed) one result */
1058*088332b5SXin Li }
1059*088332b5SXin Li 
1060*088332b5SXin Li 
1061*088332b5SXin Li 
1062*088332b5SXin Li 
1063*088332b5SXin Li /*
1064*088332b5SXin Li ** {======================================================================
1065*088332b5SXin Li ** Expression parsing
1066*088332b5SXin Li ** =======================================================================
1067*088332b5SXin Li */
1068*088332b5SXin Li 
1069*088332b5SXin Li 
primaryexp(LexState * ls,expdesc * v)1070*088332b5SXin Li static void primaryexp (LexState *ls, expdesc *v) {
1071*088332b5SXin Li   /* primaryexp -> NAME | '(' expr ')' */
1072*088332b5SXin Li   switch (ls->t.token) {
1073*088332b5SXin Li     case '(': {
1074*088332b5SXin Li       int line = ls->linenumber;
1075*088332b5SXin Li       luaX_next(ls);
1076*088332b5SXin Li       expr(ls, v);
1077*088332b5SXin Li       check_match(ls, ')', '(', line);
1078*088332b5SXin Li       luaK_dischargevars(ls->fs, v);
1079*088332b5SXin Li       return;
1080*088332b5SXin Li     }
1081*088332b5SXin Li     case TK_NAME: {
1082*088332b5SXin Li       singlevar(ls, v);
1083*088332b5SXin Li       return;
1084*088332b5SXin Li     }
1085*088332b5SXin Li     default: {
1086*088332b5SXin Li       luaX_syntaxerror(ls, "unexpected symbol");
1087*088332b5SXin Li     }
1088*088332b5SXin Li   }
1089*088332b5SXin Li }
1090*088332b5SXin Li 
1091*088332b5SXin Li 
suffixedexp(LexState * ls,expdesc * v)1092*088332b5SXin Li static void suffixedexp (LexState *ls, expdesc *v) {
1093*088332b5SXin Li   /* suffixedexp ->
1094*088332b5SXin Li        primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
1095*088332b5SXin Li   FuncState *fs = ls->fs;
1096*088332b5SXin Li   int line = ls->linenumber;
1097*088332b5SXin Li   primaryexp(ls, v);
1098*088332b5SXin Li   for (;;) {
1099*088332b5SXin Li     switch (ls->t.token) {
1100*088332b5SXin Li       case '.': {  /* fieldsel */
1101*088332b5SXin Li         fieldsel(ls, v);
1102*088332b5SXin Li         break;
1103*088332b5SXin Li       }
1104*088332b5SXin Li       case '[': {  /* '[' exp ']' */
1105*088332b5SXin Li         expdesc key;
1106*088332b5SXin Li         luaK_exp2anyregup(fs, v);
1107*088332b5SXin Li         yindex(ls, &key);
1108*088332b5SXin Li         luaK_indexed(fs, v, &key);
1109*088332b5SXin Li         break;
1110*088332b5SXin Li       }
1111*088332b5SXin Li       case ':': {  /* ':' NAME funcargs */
1112*088332b5SXin Li         expdesc key;
1113*088332b5SXin Li         luaX_next(ls);
1114*088332b5SXin Li         codename(ls, &key);
1115*088332b5SXin Li         luaK_self(fs, v, &key);
1116*088332b5SXin Li         funcargs(ls, v, line);
1117*088332b5SXin Li         break;
1118*088332b5SXin Li       }
1119*088332b5SXin Li       case '(': case TK_STRING: case '{': {  /* funcargs */
1120*088332b5SXin Li         luaK_exp2nextreg(fs, v);
1121*088332b5SXin Li         funcargs(ls, v, line);
1122*088332b5SXin Li         break;
1123*088332b5SXin Li       }
1124*088332b5SXin Li       default: return;
1125*088332b5SXin Li     }
1126*088332b5SXin Li   }
1127*088332b5SXin Li }
1128*088332b5SXin Li 
1129*088332b5SXin Li 
simpleexp(LexState * ls,expdesc * v)1130*088332b5SXin Li static void simpleexp (LexState *ls, expdesc *v) {
1131*088332b5SXin Li   /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... |
1132*088332b5SXin Li                   constructor | FUNCTION body | suffixedexp */
1133*088332b5SXin Li   switch (ls->t.token) {
1134*088332b5SXin Li     case TK_FLT: {
1135*088332b5SXin Li       init_exp(v, VKFLT, 0);
1136*088332b5SXin Li       v->u.nval = ls->t.seminfo.r;
1137*088332b5SXin Li       break;
1138*088332b5SXin Li     }
1139*088332b5SXin Li     case TK_INT: {
1140*088332b5SXin Li       init_exp(v, VKINT, 0);
1141*088332b5SXin Li       v->u.ival = ls->t.seminfo.i;
1142*088332b5SXin Li       break;
1143*088332b5SXin Li     }
1144*088332b5SXin Li     case TK_STRING: {
1145*088332b5SXin Li       codestring(v, ls->t.seminfo.ts);
1146*088332b5SXin Li       break;
1147*088332b5SXin Li     }
1148*088332b5SXin Li     case TK_NIL: {
1149*088332b5SXin Li       init_exp(v, VNIL, 0);
1150*088332b5SXin Li       break;
1151*088332b5SXin Li     }
1152*088332b5SXin Li     case TK_TRUE: {
1153*088332b5SXin Li       init_exp(v, VTRUE, 0);
1154*088332b5SXin Li       break;
1155*088332b5SXin Li     }
1156*088332b5SXin Li     case TK_FALSE: {
1157*088332b5SXin Li       init_exp(v, VFALSE, 0);
1158*088332b5SXin Li       break;
1159*088332b5SXin Li     }
1160*088332b5SXin Li     case TK_DOTS: {  /* vararg */
1161*088332b5SXin Li       FuncState *fs = ls->fs;
1162*088332b5SXin Li       check_condition(ls, fs->f->is_vararg,
1163*088332b5SXin Li                       "cannot use '...' outside a vararg function");
1164*088332b5SXin Li       init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1));
1165*088332b5SXin Li       break;
1166*088332b5SXin Li     }
1167*088332b5SXin Li     case '{': {  /* constructor */
1168*088332b5SXin Li       constructor(ls, v);
1169*088332b5SXin Li       return;
1170*088332b5SXin Li     }
1171*088332b5SXin Li     case TK_FUNCTION: {
1172*088332b5SXin Li       luaX_next(ls);
1173*088332b5SXin Li       body(ls, v, 0, ls->linenumber);
1174*088332b5SXin Li       return;
1175*088332b5SXin Li     }
1176*088332b5SXin Li     default: {
1177*088332b5SXin Li       suffixedexp(ls, v);
1178*088332b5SXin Li       return;
1179*088332b5SXin Li     }
1180*088332b5SXin Li   }
1181*088332b5SXin Li   luaX_next(ls);
1182*088332b5SXin Li }
1183*088332b5SXin Li 
1184*088332b5SXin Li 
getunopr(int op)1185*088332b5SXin Li static UnOpr getunopr (int op) {
1186*088332b5SXin Li   switch (op) {
1187*088332b5SXin Li     case TK_NOT: return OPR_NOT;
1188*088332b5SXin Li     case '-': return OPR_MINUS;
1189*088332b5SXin Li     case '~': return OPR_BNOT;
1190*088332b5SXin Li     case '#': return OPR_LEN;
1191*088332b5SXin Li     default: return OPR_NOUNOPR;
1192*088332b5SXin Li   }
1193*088332b5SXin Li }
1194*088332b5SXin Li 
1195*088332b5SXin Li 
getbinopr(int op)1196*088332b5SXin Li static BinOpr getbinopr (int op) {
1197*088332b5SXin Li   switch (op) {
1198*088332b5SXin Li     case '+': return OPR_ADD;
1199*088332b5SXin Li     case '-': return OPR_SUB;
1200*088332b5SXin Li     case '*': return OPR_MUL;
1201*088332b5SXin Li     case '%': return OPR_MOD;
1202*088332b5SXin Li     case '^': return OPR_POW;
1203*088332b5SXin Li     case '/': return OPR_DIV;
1204*088332b5SXin Li     case TK_IDIV: return OPR_IDIV;
1205*088332b5SXin Li     case '&': return OPR_BAND;
1206*088332b5SXin Li     case '|': return OPR_BOR;
1207*088332b5SXin Li     case '~': return OPR_BXOR;
1208*088332b5SXin Li     case TK_SHL: return OPR_SHL;
1209*088332b5SXin Li     case TK_SHR: return OPR_SHR;
1210*088332b5SXin Li     case TK_CONCAT: return OPR_CONCAT;
1211*088332b5SXin Li     case TK_NE: return OPR_NE;
1212*088332b5SXin Li     case TK_EQ: return OPR_EQ;
1213*088332b5SXin Li     case '<': return OPR_LT;
1214*088332b5SXin Li     case TK_LE: return OPR_LE;
1215*088332b5SXin Li     case '>': return OPR_GT;
1216*088332b5SXin Li     case TK_GE: return OPR_GE;
1217*088332b5SXin Li     case TK_AND: return OPR_AND;
1218*088332b5SXin Li     case TK_OR: return OPR_OR;
1219*088332b5SXin Li     default: return OPR_NOBINOPR;
1220*088332b5SXin Li   }
1221*088332b5SXin Li }
1222*088332b5SXin Li 
1223*088332b5SXin Li 
1224*088332b5SXin Li /*
1225*088332b5SXin Li ** Priority table for binary operators.
1226*088332b5SXin Li */
1227*088332b5SXin Li static const struct {
1228*088332b5SXin Li   lu_byte left;  /* left priority for each binary operator */
1229*088332b5SXin Li   lu_byte right; /* right priority */
1230*088332b5SXin Li } priority[] = {  /* ORDER OPR */
1231*088332b5SXin Li    {10, 10}, {10, 10},           /* '+' '-' */
1232*088332b5SXin Li    {11, 11}, {11, 11},           /* '*' '%' */
1233*088332b5SXin Li    {14, 13},                  /* '^' (right associative) */
1234*088332b5SXin Li    {11, 11}, {11, 11},           /* '/' '//' */
1235*088332b5SXin Li    {6, 6}, {4, 4}, {5, 5},   /* '&' '|' '~' */
1236*088332b5SXin Li    {7, 7}, {7, 7},           /* '<<' '>>' */
1237*088332b5SXin Li    {9, 8},                   /* '..' (right associative) */
1238*088332b5SXin Li    {3, 3}, {3, 3}, {3, 3},   /* ==, <, <= */
1239*088332b5SXin Li    {3, 3}, {3, 3}, {3, 3},   /* ~=, >, >= */
1240*088332b5SXin Li    {2, 2}, {1, 1}            /* and, or */
1241*088332b5SXin Li };
1242*088332b5SXin Li 
1243*088332b5SXin Li #define UNARY_PRIORITY	12  /* priority for unary operators */
1244*088332b5SXin Li 
1245*088332b5SXin Li 
1246*088332b5SXin Li /*
1247*088332b5SXin Li ** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
1248*088332b5SXin Li ** where 'binop' is any binary operator with a priority higher than 'limit'
1249*088332b5SXin Li */
subexpr(LexState * ls,expdesc * v,int limit)1250*088332b5SXin Li static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
1251*088332b5SXin Li   BinOpr op;
1252*088332b5SXin Li   UnOpr uop;
1253*088332b5SXin Li   enterlevel(ls);
1254*088332b5SXin Li   uop = getunopr(ls->t.token);
1255*088332b5SXin Li   if (uop != OPR_NOUNOPR) {  /* prefix (unary) operator? */
1256*088332b5SXin Li     int line = ls->linenumber;
1257*088332b5SXin Li     luaX_next(ls);  /* skip operator */
1258*088332b5SXin Li     subexpr(ls, v, UNARY_PRIORITY);
1259*088332b5SXin Li     luaK_prefix(ls->fs, uop, v, line);
1260*088332b5SXin Li   }
1261*088332b5SXin Li   else simpleexp(ls, v);
1262*088332b5SXin Li   /* expand while operators have priorities higher than 'limit' */
1263*088332b5SXin Li   op = getbinopr(ls->t.token);
1264*088332b5SXin Li   while (op != OPR_NOBINOPR && priority[op].left > limit) {
1265*088332b5SXin Li     expdesc v2;
1266*088332b5SXin Li     BinOpr nextop;
1267*088332b5SXin Li     int line = ls->linenumber;
1268*088332b5SXin Li     luaX_next(ls);  /* skip operator */
1269*088332b5SXin Li     luaK_infix(ls->fs, op, v);
1270*088332b5SXin Li     /* read sub-expression with higher priority */
1271*088332b5SXin Li     nextop = subexpr(ls, &v2, priority[op].right);
1272*088332b5SXin Li     luaK_posfix(ls->fs, op, v, &v2, line);
1273*088332b5SXin Li     op = nextop;
1274*088332b5SXin Li   }
1275*088332b5SXin Li   leavelevel(ls);
1276*088332b5SXin Li   return op;  /* return first untreated operator */
1277*088332b5SXin Li }
1278*088332b5SXin Li 
1279*088332b5SXin Li 
expr(LexState * ls,expdesc * v)1280*088332b5SXin Li static void expr (LexState *ls, expdesc *v) {
1281*088332b5SXin Li   subexpr(ls, v, 0);
1282*088332b5SXin Li }
1283*088332b5SXin Li 
1284*088332b5SXin Li /* }==================================================================== */
1285*088332b5SXin Li 
1286*088332b5SXin Li 
1287*088332b5SXin Li 
1288*088332b5SXin Li /*
1289*088332b5SXin Li ** {======================================================================
1290*088332b5SXin Li ** Rules for Statements
1291*088332b5SXin Li ** =======================================================================
1292*088332b5SXin Li */
1293*088332b5SXin Li 
1294*088332b5SXin Li 
block(LexState * ls)1295*088332b5SXin Li static void block (LexState *ls) {
1296*088332b5SXin Li   /* block -> statlist */
1297*088332b5SXin Li   FuncState *fs = ls->fs;
1298*088332b5SXin Li   BlockCnt bl;
1299*088332b5SXin Li   enterblock(fs, &bl, 0);
1300*088332b5SXin Li   statlist(ls);
1301*088332b5SXin Li   leaveblock(fs);
1302*088332b5SXin Li }
1303*088332b5SXin Li 
1304*088332b5SXin Li 
1305*088332b5SXin Li /*
1306*088332b5SXin Li ** structure to chain all variables in the left-hand side of an
1307*088332b5SXin Li ** assignment
1308*088332b5SXin Li */
1309*088332b5SXin Li struct LHS_assign {
1310*088332b5SXin Li   struct LHS_assign *prev;
1311*088332b5SXin Li   expdesc v;  /* variable (global, local, upvalue, or indexed) */
1312*088332b5SXin Li };
1313*088332b5SXin Li 
1314*088332b5SXin Li 
1315*088332b5SXin Li /*
1316*088332b5SXin Li ** check whether, in an assignment to an upvalue/local variable, the
1317*088332b5SXin Li ** upvalue/local variable is begin used in a previous assignment to a
1318*088332b5SXin Li ** table. If so, save original upvalue/local value in a safe place and
1319*088332b5SXin Li ** use this safe copy in the previous assignment.
1320*088332b5SXin Li */
check_conflict(LexState * ls,struct LHS_assign * lh,expdesc * v)1321*088332b5SXin Li static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1322*088332b5SXin Li   FuncState *fs = ls->fs;
1323*088332b5SXin Li   int extra = fs->freereg;  /* eventual position to save local variable */
1324*088332b5SXin Li   int conflict = 0;
1325*088332b5SXin Li   for (; lh; lh = lh->prev) {  /* check all previous assignments */
1326*088332b5SXin Li     if (vkisindexed(lh->v.k)) {  /* assignment to table field? */
1327*088332b5SXin Li       if (lh->v.k == VINDEXUP) {  /* is table an upvalue? */
1328*088332b5SXin Li         if (v->k == VUPVAL && lh->v.u.ind.t == v->u.info) {
1329*088332b5SXin Li           conflict = 1;  /* table is the upvalue being assigned now */
1330*088332b5SXin Li           lh->v.k = VINDEXSTR;
1331*088332b5SXin Li           lh->v.u.ind.t = extra;  /* assignment will use safe copy */
1332*088332b5SXin Li         }
1333*088332b5SXin Li       }
1334*088332b5SXin Li       else {  /* table is a register */
1335*088332b5SXin Li         if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.sidx) {
1336*088332b5SXin Li           conflict = 1;  /* table is the local being assigned now */
1337*088332b5SXin Li           lh->v.u.ind.t = extra;  /* assignment will use safe copy */
1338*088332b5SXin Li         }
1339*088332b5SXin Li         /* is index the local being assigned? */
1340*088332b5SXin Li         if (lh->v.k == VINDEXED && v->k == VLOCAL &&
1341*088332b5SXin Li             lh->v.u.ind.idx == v->u.var.sidx) {
1342*088332b5SXin Li           conflict = 1;
1343*088332b5SXin Li           lh->v.u.ind.idx = extra;  /* previous assignment will use safe copy */
1344*088332b5SXin Li         }
1345*088332b5SXin Li       }
1346*088332b5SXin Li     }
1347*088332b5SXin Li   }
1348*088332b5SXin Li   if (conflict) {
1349*088332b5SXin Li     /* copy upvalue/local value to a temporary (in position 'extra') */
1350*088332b5SXin Li     if (v->k == VLOCAL)
1351*088332b5SXin Li       luaK_codeABC(fs, OP_MOVE, extra, v->u.var.sidx, 0);
1352*088332b5SXin Li     else
1353*088332b5SXin Li       luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0);
1354*088332b5SXin Li     luaK_reserveregs(fs, 1);
1355*088332b5SXin Li   }
1356*088332b5SXin Li }
1357*088332b5SXin Li 
1358*088332b5SXin Li /*
1359*088332b5SXin Li ** Parse and compile a multiple assignment. The first "variable"
1360*088332b5SXin Li ** (a 'suffixedexp') was already read by the caller.
1361*088332b5SXin Li **
1362*088332b5SXin Li ** assignment -> suffixedexp restassign
1363*088332b5SXin Li ** restassign -> ',' suffixedexp restassign | '=' explist
1364*088332b5SXin Li */
restassign(LexState * ls,struct LHS_assign * lh,int nvars)1365*088332b5SXin Li static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) {
1366*088332b5SXin Li   expdesc e;
1367*088332b5SXin Li   check_condition(ls, vkisvar(lh->v.k), "syntax error");
1368*088332b5SXin Li   check_readonly(ls, &lh->v);
1369*088332b5SXin Li   if (testnext(ls, ',')) {  /* restassign -> ',' suffixedexp restassign */
1370*088332b5SXin Li     struct LHS_assign nv;
1371*088332b5SXin Li     nv.prev = lh;
1372*088332b5SXin Li     suffixedexp(ls, &nv.v);
1373*088332b5SXin Li     if (!vkisindexed(nv.v.k))
1374*088332b5SXin Li       check_conflict(ls, lh, &nv.v);
1375*088332b5SXin Li     enterlevel(ls);  /* control recursion depth */
1376*088332b5SXin Li     restassign(ls, &nv, nvars+1);
1377*088332b5SXin Li     leavelevel(ls);
1378*088332b5SXin Li   }
1379*088332b5SXin Li   else {  /* restassign -> '=' explist */
1380*088332b5SXin Li     int nexps;
1381*088332b5SXin Li     checknext(ls, '=');
1382*088332b5SXin Li     nexps = explist(ls, &e);
1383*088332b5SXin Li     if (nexps != nvars)
1384*088332b5SXin Li       adjust_assign(ls, nvars, nexps, &e);
1385*088332b5SXin Li     else {
1386*088332b5SXin Li       luaK_setoneret(ls->fs, &e);  /* close last expression */
1387*088332b5SXin Li       luaK_storevar(ls->fs, &lh->v, &e);
1388*088332b5SXin Li       return;  /* avoid default */
1389*088332b5SXin Li     }
1390*088332b5SXin Li   }
1391*088332b5SXin Li   init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
1392*088332b5SXin Li   luaK_storevar(ls->fs, &lh->v, &e);
1393*088332b5SXin Li }
1394*088332b5SXin Li 
1395*088332b5SXin Li 
cond(LexState * ls)1396*088332b5SXin Li static int cond (LexState *ls) {
1397*088332b5SXin Li   /* cond -> exp */
1398*088332b5SXin Li   expdesc v;
1399*088332b5SXin Li   expr(ls, &v);  /* read condition */
1400*088332b5SXin Li   if (v.k == VNIL) v.k = VFALSE;  /* 'falses' are all equal here */
1401*088332b5SXin Li   luaK_goiftrue(ls->fs, &v);
1402*088332b5SXin Li   return v.f;
1403*088332b5SXin Li }
1404*088332b5SXin Li 
1405*088332b5SXin Li 
gotostat(LexState * ls)1406*088332b5SXin Li static void gotostat (LexState *ls) {
1407*088332b5SXin Li   FuncState *fs = ls->fs;
1408*088332b5SXin Li   int line = ls->linenumber;
1409*088332b5SXin Li   TString *name = str_checkname(ls);  /* label's name */
1410*088332b5SXin Li   Labeldesc *lb = findlabel(ls, name);
1411*088332b5SXin Li   if (lb == NULL)  /* no label? */
1412*088332b5SXin Li     /* forward jump; will be resolved when the label is declared */
1413*088332b5SXin Li     newgotoentry(ls, name, line, luaK_jump(fs));
1414*088332b5SXin Li   else {  /* found a label */
1415*088332b5SXin Li     /* backward jump; will be resolved here */
1416*088332b5SXin Li     int lblevel = stacklevel(fs, lb->nactvar);  /* label level */
1417*088332b5SXin Li     if (luaY_nvarstack(fs) > lblevel)  /* leaving the scope of a variable? */
1418*088332b5SXin Li       luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0);
1419*088332b5SXin Li     /* create jump and link it to the label */
1420*088332b5SXin Li     luaK_patchlist(fs, luaK_jump(fs), lb->pc);
1421*088332b5SXin Li   }
1422*088332b5SXin Li }
1423*088332b5SXin Li 
1424*088332b5SXin Li 
1425*088332b5SXin Li /*
1426*088332b5SXin Li ** Break statement. Semantically equivalent to "goto break".
1427*088332b5SXin Li */
breakstat(LexState * ls)1428*088332b5SXin Li static void breakstat (LexState *ls) {
1429*088332b5SXin Li   int line = ls->linenumber;
1430*088332b5SXin Li   luaX_next(ls);  /* skip break */
1431*088332b5SXin Li   newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, luaK_jump(ls->fs));
1432*088332b5SXin Li }
1433*088332b5SXin Li 
1434*088332b5SXin Li 
1435*088332b5SXin Li /*
1436*088332b5SXin Li ** Check whether there is already a label with the given 'name'.
1437*088332b5SXin Li */
checkrepeated(LexState * ls,TString * name)1438*088332b5SXin Li static void checkrepeated (LexState *ls, TString *name) {
1439*088332b5SXin Li   Labeldesc *lb = findlabel(ls, name);
1440*088332b5SXin Li   if (unlikely(lb != NULL)) {  /* already defined? */
1441*088332b5SXin Li     const char *msg = "label '%s' already defined on line %d";
1442*088332b5SXin Li     msg = luaO_pushfstring(ls->L, msg, getstr(name), lb->line);
1443*088332b5SXin Li     luaK_semerror(ls, msg);  /* error */
1444*088332b5SXin Li   }
1445*088332b5SXin Li }
1446*088332b5SXin Li 
1447*088332b5SXin Li 
labelstat(LexState * ls,TString * name,int line)1448*088332b5SXin Li static void labelstat (LexState *ls, TString *name, int line) {
1449*088332b5SXin Li   /* label -> '::' NAME '::' */
1450*088332b5SXin Li   checknext(ls, TK_DBCOLON);  /* skip double colon */
1451*088332b5SXin Li   while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
1452*088332b5SXin Li     statement(ls);  /* skip other no-op statements */
1453*088332b5SXin Li   checkrepeated(ls, name);  /* check for repeated labels */
1454*088332b5SXin Li   createlabel(ls, name, line, block_follow(ls, 0));
1455*088332b5SXin Li }
1456*088332b5SXin Li 
1457*088332b5SXin Li 
whilestat(LexState * ls,int line)1458*088332b5SXin Li static void whilestat (LexState *ls, int line) {
1459*088332b5SXin Li   /* whilestat -> WHILE cond DO block END */
1460*088332b5SXin Li   FuncState *fs = ls->fs;
1461*088332b5SXin Li   int whileinit;
1462*088332b5SXin Li   int condexit;
1463*088332b5SXin Li   BlockCnt bl;
1464*088332b5SXin Li   luaX_next(ls);  /* skip WHILE */
1465*088332b5SXin Li   whileinit = luaK_getlabel(fs);
1466*088332b5SXin Li   condexit = cond(ls);
1467*088332b5SXin Li   enterblock(fs, &bl, 1);
1468*088332b5SXin Li   checknext(ls, TK_DO);
1469*088332b5SXin Li   block(ls);
1470*088332b5SXin Li   luaK_jumpto(fs, whileinit);
1471*088332b5SXin Li   check_match(ls, TK_END, TK_WHILE, line);
1472*088332b5SXin Li   leaveblock(fs);
1473*088332b5SXin Li   luaK_patchtohere(fs, condexit);  /* false conditions finish the loop */
1474*088332b5SXin Li }
1475*088332b5SXin Li 
1476*088332b5SXin Li 
repeatstat(LexState * ls,int line)1477*088332b5SXin Li static void repeatstat (LexState *ls, int line) {
1478*088332b5SXin Li   /* repeatstat -> REPEAT block UNTIL cond */
1479*088332b5SXin Li   int condexit;
1480*088332b5SXin Li   FuncState *fs = ls->fs;
1481*088332b5SXin Li   int repeat_init = luaK_getlabel(fs);
1482*088332b5SXin Li   BlockCnt bl1, bl2;
1483*088332b5SXin Li   enterblock(fs, &bl1, 1);  /* loop block */
1484*088332b5SXin Li   enterblock(fs, &bl2, 0);  /* scope block */
1485*088332b5SXin Li   luaX_next(ls);  /* skip REPEAT */
1486*088332b5SXin Li   statlist(ls);
1487*088332b5SXin Li   check_match(ls, TK_UNTIL, TK_REPEAT, line);
1488*088332b5SXin Li   condexit = cond(ls);  /* read condition (inside scope block) */
1489*088332b5SXin Li   leaveblock(fs);  /* finish scope */
1490*088332b5SXin Li   if (bl2.upval) {  /* upvalues? */
1491*088332b5SXin Li     int exit = luaK_jump(fs);  /* normal exit must jump over fix */
1492*088332b5SXin Li     luaK_patchtohere(fs, condexit);  /* repetition must close upvalues */
1493*088332b5SXin Li     luaK_codeABC(fs, OP_CLOSE, stacklevel(fs, bl2.nactvar), 0, 0);
1494*088332b5SXin Li     condexit = luaK_jump(fs);  /* repeat after closing upvalues */
1495*088332b5SXin Li     luaK_patchtohere(fs, exit);  /* normal exit comes to here */
1496*088332b5SXin Li   }
1497*088332b5SXin Li   luaK_patchlist(fs, condexit, repeat_init);  /* close the loop */
1498*088332b5SXin Li   leaveblock(fs);  /* finish loop */
1499*088332b5SXin Li }
1500*088332b5SXin Li 
1501*088332b5SXin Li 
1502*088332b5SXin Li /*
1503*088332b5SXin Li ** Read an expression and generate code to put its results in next
1504*088332b5SXin Li ** stack slot.
1505*088332b5SXin Li **
1506*088332b5SXin Li */
exp1(LexState * ls)1507*088332b5SXin Li static void exp1 (LexState *ls) {
1508*088332b5SXin Li   expdesc e;
1509*088332b5SXin Li   expr(ls, &e);
1510*088332b5SXin Li   luaK_exp2nextreg(ls->fs, &e);
1511*088332b5SXin Li   lua_assert(e.k == VNONRELOC);
1512*088332b5SXin Li }
1513*088332b5SXin Li 
1514*088332b5SXin Li 
1515*088332b5SXin Li /*
1516*088332b5SXin Li ** Fix for instruction at position 'pc' to jump to 'dest'.
1517*088332b5SXin Li ** (Jump addresses are relative in Lua). 'back' true means
1518*088332b5SXin Li ** a back jump.
1519*088332b5SXin Li */
fixforjump(FuncState * fs,int pc,int dest,int back)1520*088332b5SXin Li static void fixforjump (FuncState *fs, int pc, int dest, int back) {
1521*088332b5SXin Li   Instruction *jmp = &fs->f->code[pc];
1522*088332b5SXin Li   int offset = dest - (pc + 1);
1523*088332b5SXin Li   if (back)
1524*088332b5SXin Li     offset = -offset;
1525*088332b5SXin Li   if (unlikely(offset > MAXARG_Bx))
1526*088332b5SXin Li     luaX_syntaxerror(fs->ls, "control structure too long");
1527*088332b5SXin Li   SETARG_Bx(*jmp, offset);
1528*088332b5SXin Li }
1529*088332b5SXin Li 
1530*088332b5SXin Li 
1531*088332b5SXin Li /*
1532*088332b5SXin Li ** Generate code for a 'for' loop.
1533*088332b5SXin Li */
forbody(LexState * ls,int base,int line,int nvars,int isgen)1534*088332b5SXin Li static void forbody (LexState *ls, int base, int line, int nvars, int isgen) {
1535*088332b5SXin Li   /* forbody -> DO block */
1536*088332b5SXin Li   static const OpCode forprep[2] = {OP_FORPREP, OP_TFORPREP};
1537*088332b5SXin Li   static const OpCode forloop[2] = {OP_FORLOOP, OP_TFORLOOP};
1538*088332b5SXin Li   BlockCnt bl;
1539*088332b5SXin Li   FuncState *fs = ls->fs;
1540*088332b5SXin Li   int prep, endfor;
1541*088332b5SXin Li   checknext(ls, TK_DO);
1542*088332b5SXin Li   prep = luaK_codeABx(fs, forprep[isgen], base, 0);
1543*088332b5SXin Li   enterblock(fs, &bl, 0);  /* scope for declared variables */
1544*088332b5SXin Li   adjustlocalvars(ls, nvars);
1545*088332b5SXin Li   luaK_reserveregs(fs, nvars);
1546*088332b5SXin Li   block(ls);
1547*088332b5SXin Li   leaveblock(fs);  /* end of scope for declared variables */
1548*088332b5SXin Li   fixforjump(fs, prep, luaK_getlabel(fs), 0);
1549*088332b5SXin Li   if (isgen) {  /* generic for? */
1550*088332b5SXin Li     luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
1551*088332b5SXin Li     luaK_fixline(fs, line);
1552*088332b5SXin Li   }
1553*088332b5SXin Li   endfor = luaK_codeABx(fs, forloop[isgen], base, 0);
1554*088332b5SXin Li   fixforjump(fs, endfor, prep + 1, 1);
1555*088332b5SXin Li   luaK_fixline(fs, line);
1556*088332b5SXin Li }
1557*088332b5SXin Li 
1558*088332b5SXin Li 
fornum(LexState * ls,TString * varname,int line)1559*088332b5SXin Li static void fornum (LexState *ls, TString *varname, int line) {
1560*088332b5SXin Li   /* fornum -> NAME = exp,exp[,exp] forbody */
1561*088332b5SXin Li   FuncState *fs = ls->fs;
1562*088332b5SXin Li   int base = fs->freereg;
1563*088332b5SXin Li   new_localvarliteral(ls, "(for state)");
1564*088332b5SXin Li   new_localvarliteral(ls, "(for state)");
1565*088332b5SXin Li   new_localvarliteral(ls, "(for state)");
1566*088332b5SXin Li   new_localvar(ls, varname);
1567*088332b5SXin Li   checknext(ls, '=');
1568*088332b5SXin Li   exp1(ls);  /* initial value */
1569*088332b5SXin Li   checknext(ls, ',');
1570*088332b5SXin Li   exp1(ls);  /* limit */
1571*088332b5SXin Li   if (testnext(ls, ','))
1572*088332b5SXin Li     exp1(ls);  /* optional step */
1573*088332b5SXin Li   else {  /* default step = 1 */
1574*088332b5SXin Li     luaK_int(fs, fs->freereg, 1);
1575*088332b5SXin Li     luaK_reserveregs(fs, 1);
1576*088332b5SXin Li   }
1577*088332b5SXin Li   adjustlocalvars(ls, 3);  /* control variables */
1578*088332b5SXin Li   forbody(ls, base, line, 1, 0);
1579*088332b5SXin Li }
1580*088332b5SXin Li 
1581*088332b5SXin Li 
forlist(LexState * ls,TString * indexname)1582*088332b5SXin Li static void forlist (LexState *ls, TString *indexname) {
1583*088332b5SXin Li   /* forlist -> NAME {,NAME} IN explist forbody */
1584*088332b5SXin Li   FuncState *fs = ls->fs;
1585*088332b5SXin Li   expdesc e;
1586*088332b5SXin Li   int nvars = 5;  /* gen, state, control, toclose, 'indexname' */
1587*088332b5SXin Li   int line;
1588*088332b5SXin Li   int base = fs->freereg;
1589*088332b5SXin Li   /* create control variables */
1590*088332b5SXin Li   new_localvarliteral(ls, "(for state)");
1591*088332b5SXin Li   new_localvarliteral(ls, "(for state)");
1592*088332b5SXin Li   new_localvarliteral(ls, "(for state)");
1593*088332b5SXin Li   new_localvarliteral(ls, "(for state)");
1594*088332b5SXin Li   /* create declared variables */
1595*088332b5SXin Li   new_localvar(ls, indexname);
1596*088332b5SXin Li   while (testnext(ls, ',')) {
1597*088332b5SXin Li     new_localvar(ls, str_checkname(ls));
1598*088332b5SXin Li     nvars++;
1599*088332b5SXin Li   }
1600*088332b5SXin Li   checknext(ls, TK_IN);
1601*088332b5SXin Li   line = ls->linenumber;
1602*088332b5SXin Li   adjust_assign(ls, 4, explist(ls, &e), &e);
1603*088332b5SXin Li   adjustlocalvars(ls, 4);  /* control variables */
1604*088332b5SXin Li   markupval(fs, fs->nactvar);  /* last control var. must be closed */
1605*088332b5SXin Li   luaK_checkstack(fs, 3);  /* extra space to call generator */
1606*088332b5SXin Li   forbody(ls, base, line, nvars - 4, 1);
1607*088332b5SXin Li }
1608*088332b5SXin Li 
1609*088332b5SXin Li 
forstat(LexState * ls,int line)1610*088332b5SXin Li static void forstat (LexState *ls, int line) {
1611*088332b5SXin Li   /* forstat -> FOR (fornum | forlist) END */
1612*088332b5SXin Li   FuncState *fs = ls->fs;
1613*088332b5SXin Li   TString *varname;
1614*088332b5SXin Li   BlockCnt bl;
1615*088332b5SXin Li   enterblock(fs, &bl, 1);  /* scope for loop and control variables */
1616*088332b5SXin Li   luaX_next(ls);  /* skip 'for' */
1617*088332b5SXin Li   varname = str_checkname(ls);  /* first variable name */
1618*088332b5SXin Li   switch (ls->t.token) {
1619*088332b5SXin Li     case '=': fornum(ls, varname, line); break;
1620*088332b5SXin Li     case ',': case TK_IN: forlist(ls, varname); break;
1621*088332b5SXin Li     default: luaX_syntaxerror(ls, "'=' or 'in' expected");
1622*088332b5SXin Li   }
1623*088332b5SXin Li   check_match(ls, TK_END, TK_FOR, line);
1624*088332b5SXin Li   leaveblock(fs);  /* loop scope ('break' jumps to this point) */
1625*088332b5SXin Li }
1626*088332b5SXin Li 
1627*088332b5SXin Li 
1628*088332b5SXin Li /*
1629*088332b5SXin Li ** Check whether next instruction is a single jump (a 'break', a 'goto'
1630*088332b5SXin Li ** to a forward label, or a 'goto' to a backward label with no variable
1631*088332b5SXin Li ** to close). If so, set the name of the 'label' it is jumping to
1632*088332b5SXin Li ** ("break" for a 'break') or to where it is jumping to ('target') and
1633*088332b5SXin Li ** return true. If not a single jump, leave input unchanged, to be
1634*088332b5SXin Li ** handled as a regular statement.
1635*088332b5SXin Li */
issinglejump(LexState * ls,TString ** label,int * target)1636*088332b5SXin Li static int issinglejump (LexState *ls, TString **label, int *target) {
1637*088332b5SXin Li   if (testnext(ls, TK_BREAK)) {  /* a break? */
1638*088332b5SXin Li     *label = luaS_newliteral(ls->L, "break");
1639*088332b5SXin Li     return 1;
1640*088332b5SXin Li   }
1641*088332b5SXin Li   else if (ls->t.token != TK_GOTO || luaX_lookahead(ls) != TK_NAME)
1642*088332b5SXin Li     return 0;  /* not a valid goto */
1643*088332b5SXin Li   else {
1644*088332b5SXin Li     TString *lname = ls->lookahead.seminfo.ts;  /* label's id */
1645*088332b5SXin Li     Labeldesc *lb = findlabel(ls, lname);
1646*088332b5SXin Li     if (lb) {  /* a backward jump? */
1647*088332b5SXin Li       /* does it need to close variables? */
1648*088332b5SXin Li       if (luaY_nvarstack(ls->fs) > stacklevel(ls->fs, lb->nactvar))
1649*088332b5SXin Li         return 0;  /* not a single jump; cannot optimize */
1650*088332b5SXin Li       *target = lb->pc;
1651*088332b5SXin Li     }
1652*088332b5SXin Li     else  /* jump forward */
1653*088332b5SXin Li       *label = lname;
1654*088332b5SXin Li     luaX_next(ls);  /* skip goto */
1655*088332b5SXin Li     luaX_next(ls);  /* skip name */
1656*088332b5SXin Li     return 1;
1657*088332b5SXin Li   }
1658*088332b5SXin Li }
1659*088332b5SXin Li 
1660*088332b5SXin Li 
test_then_block(LexState * ls,int * escapelist)1661*088332b5SXin Li static void test_then_block (LexState *ls, int *escapelist) {
1662*088332b5SXin Li   /* test_then_block -> [IF | ELSEIF] cond THEN block */
1663*088332b5SXin Li   BlockCnt bl;
1664*088332b5SXin Li   int line;
1665*088332b5SXin Li   FuncState *fs = ls->fs;
1666*088332b5SXin Li   TString *jlb = NULL;
1667*088332b5SXin Li   int target = NO_JUMP;
1668*088332b5SXin Li   expdesc v;
1669*088332b5SXin Li   int jf;  /* instruction to skip 'then' code (if condition is false) */
1670*088332b5SXin Li   luaX_next(ls);  /* skip IF or ELSEIF */
1671*088332b5SXin Li   expr(ls, &v);  /* read condition */
1672*088332b5SXin Li   checknext(ls, TK_THEN);
1673*088332b5SXin Li   line = ls->linenumber;
1674*088332b5SXin Li   if (issinglejump(ls, &jlb, &target)) {  /* 'if x then goto' ? */
1675*088332b5SXin Li     luaK_goiffalse(ls->fs, &v);  /* will jump to label if condition is true */
1676*088332b5SXin Li     enterblock(fs, &bl, 0);  /* must enter block before 'goto' */
1677*088332b5SXin Li     if (jlb != NULL)  /* forward jump? */
1678*088332b5SXin Li       newgotoentry(ls, jlb, line, v.t);  /* will be resolved later */
1679*088332b5SXin Li     else  /* backward jump */
1680*088332b5SXin Li       luaK_patchlist(fs, v.t, target);  /* jump directly to 'target' */
1681*088332b5SXin Li     while (testnext(ls, ';')) {}  /* skip semicolons */
1682*088332b5SXin Li     if (block_follow(ls, 0)) {  /* jump is the entire block? */
1683*088332b5SXin Li       leaveblock(fs);
1684*088332b5SXin Li       return;  /* and that is it */
1685*088332b5SXin Li     }
1686*088332b5SXin Li     else  /* must skip over 'then' part if condition is false */
1687*088332b5SXin Li       jf = luaK_jump(fs);
1688*088332b5SXin Li   }
1689*088332b5SXin Li   else {  /* regular case (not a jump) */
1690*088332b5SXin Li     luaK_goiftrue(ls->fs, &v);  /* skip over block if condition is false */
1691*088332b5SXin Li     enterblock(fs, &bl, 0);
1692*088332b5SXin Li     jf = v.f;
1693*088332b5SXin Li   }
1694*088332b5SXin Li   statlist(ls);  /* 'then' part */
1695*088332b5SXin Li   leaveblock(fs);
1696*088332b5SXin Li   if (ls->t.token == TK_ELSE ||
1697*088332b5SXin Li       ls->t.token == TK_ELSEIF)  /* followed by 'else'/'elseif'? */
1698*088332b5SXin Li     luaK_concat(fs, escapelist, luaK_jump(fs));  /* must jump over it */
1699*088332b5SXin Li   luaK_patchtohere(fs, jf);
1700*088332b5SXin Li }
1701*088332b5SXin Li 
1702*088332b5SXin Li 
ifstat(LexState * ls,int line)1703*088332b5SXin Li static void ifstat (LexState *ls, int line) {
1704*088332b5SXin Li   /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1705*088332b5SXin Li   FuncState *fs = ls->fs;
1706*088332b5SXin Li   int escapelist = NO_JUMP;  /* exit list for finished parts */
1707*088332b5SXin Li   test_then_block(ls, &escapelist);  /* IF cond THEN block */
1708*088332b5SXin Li   while (ls->t.token == TK_ELSEIF)
1709*088332b5SXin Li     test_then_block(ls, &escapelist);  /* ELSEIF cond THEN block */
1710*088332b5SXin Li   if (testnext(ls, TK_ELSE))
1711*088332b5SXin Li     block(ls);  /* 'else' part */
1712*088332b5SXin Li   check_match(ls, TK_END, TK_IF, line);
1713*088332b5SXin Li   luaK_patchtohere(fs, escapelist);  /* patch escape list to 'if' end */
1714*088332b5SXin Li }
1715*088332b5SXin Li 
1716*088332b5SXin Li 
localfunc(LexState * ls)1717*088332b5SXin Li static void localfunc (LexState *ls) {
1718*088332b5SXin Li   expdesc b;
1719*088332b5SXin Li   FuncState *fs = ls->fs;
1720*088332b5SXin Li   int fvar = fs->nactvar;  /* function's variable index */
1721*088332b5SXin Li   new_localvar(ls, str_checkname(ls));  /* new local variable */
1722*088332b5SXin Li   adjustlocalvars(ls, 1);  /* enter its scope */
1723*088332b5SXin Li   body(ls, &b, 0, ls->linenumber);  /* function created in next register */
1724*088332b5SXin Li   /* debug information will only see the variable after this point! */
1725*088332b5SXin Li   localdebuginfo(fs, fvar)->startpc = fs->pc;
1726*088332b5SXin Li }
1727*088332b5SXin Li 
1728*088332b5SXin Li 
getlocalattribute(LexState * ls)1729*088332b5SXin Li static int getlocalattribute (LexState *ls) {
1730*088332b5SXin Li   /* ATTRIB -> ['<' Name '>'] */
1731*088332b5SXin Li   if (testnext(ls, '<')) {
1732*088332b5SXin Li     const char *attr = getstr(str_checkname(ls));
1733*088332b5SXin Li     checknext(ls, '>');
1734*088332b5SXin Li     if (strcmp(attr, "const") == 0)
1735*088332b5SXin Li       return RDKCONST;  /* read-only variable */
1736*088332b5SXin Li     else if (strcmp(attr, "close") == 0)
1737*088332b5SXin Li       return RDKTOCLOSE;  /* to-be-closed variable */
1738*088332b5SXin Li     else
1739*088332b5SXin Li       luaK_semerror(ls,
1740*088332b5SXin Li         luaO_pushfstring(ls->L, "unknown attribute '%s'", attr));
1741*088332b5SXin Li   }
1742*088332b5SXin Li   return VDKREG;  /* regular variable */
1743*088332b5SXin Li }
1744*088332b5SXin Li 
1745*088332b5SXin Li 
checktoclose(LexState * ls,int level)1746*088332b5SXin Li static void checktoclose (LexState *ls, int level) {
1747*088332b5SXin Li   if (level != -1) {  /* is there a to-be-closed variable? */
1748*088332b5SXin Li     FuncState *fs = ls->fs;
1749*088332b5SXin Li     markupval(fs, level + 1);
1750*088332b5SXin Li     fs->bl->insidetbc = 1;  /* in the scope of a to-be-closed variable */
1751*088332b5SXin Li     luaK_codeABC(fs, OP_TBC, stacklevel(fs, level), 0, 0);
1752*088332b5SXin Li   }
1753*088332b5SXin Li }
1754*088332b5SXin Li 
1755*088332b5SXin Li 
localstat(LexState * ls)1756*088332b5SXin Li static void localstat (LexState *ls) {
1757*088332b5SXin Li   /* stat -> LOCAL ATTRIB NAME {',' ATTRIB NAME} ['=' explist] */
1758*088332b5SXin Li   FuncState *fs = ls->fs;
1759*088332b5SXin Li   int toclose = -1;  /* index of to-be-closed variable (if any) */
1760*088332b5SXin Li   Vardesc *var;  /* last variable */
1761*088332b5SXin Li   int vidx, kind;  /* index and kind of last variable */
1762*088332b5SXin Li   int nvars = 0;
1763*088332b5SXin Li   int nexps;
1764*088332b5SXin Li   expdesc e;
1765*088332b5SXin Li   do {
1766*088332b5SXin Li     vidx = new_localvar(ls, str_checkname(ls));
1767*088332b5SXin Li     kind = getlocalattribute(ls);
1768*088332b5SXin Li     getlocalvardesc(fs, vidx)->vd.kind = kind;
1769*088332b5SXin Li     if (kind == RDKTOCLOSE) {  /* to-be-closed? */
1770*088332b5SXin Li       if (toclose != -1)  /* one already present? */
1771*088332b5SXin Li         luaK_semerror(ls, "multiple to-be-closed variables in local list");
1772*088332b5SXin Li       toclose = fs->nactvar + nvars;
1773*088332b5SXin Li     }
1774*088332b5SXin Li     nvars++;
1775*088332b5SXin Li   } while (testnext(ls, ','));
1776*088332b5SXin Li   if (testnext(ls, '='))
1777*088332b5SXin Li     nexps = explist(ls, &e);
1778*088332b5SXin Li   else {
1779*088332b5SXin Li     e.k = VVOID;
1780*088332b5SXin Li     nexps = 0;
1781*088332b5SXin Li   }
1782*088332b5SXin Li   var = getlocalvardesc(fs, vidx);  /* get last variable */
1783*088332b5SXin Li   if (nvars == nexps &&  /* no adjustments? */
1784*088332b5SXin Li       var->vd.kind == RDKCONST &&  /* last variable is const? */
1785*088332b5SXin Li       luaK_exp2const(fs, &e, &var->k)) {  /* compile-time constant? */
1786*088332b5SXin Li     var->vd.kind = RDKCTC;  /* variable is a compile-time constant */
1787*088332b5SXin Li     adjustlocalvars(ls, nvars - 1);  /* exclude last variable */
1788*088332b5SXin Li     fs->nactvar++;  /* but count it */
1789*088332b5SXin Li   }
1790*088332b5SXin Li   else {
1791*088332b5SXin Li     adjust_assign(ls, nvars, nexps, &e);
1792*088332b5SXin Li     adjustlocalvars(ls, nvars);
1793*088332b5SXin Li   }
1794*088332b5SXin Li   checktoclose(ls, toclose);
1795*088332b5SXin Li }
1796*088332b5SXin Li 
1797*088332b5SXin Li 
funcname(LexState * ls,expdesc * v)1798*088332b5SXin Li static int funcname (LexState *ls, expdesc *v) {
1799*088332b5SXin Li   /* funcname -> NAME {fieldsel} [':' NAME] */
1800*088332b5SXin Li   int ismethod = 0;
1801*088332b5SXin Li   singlevar(ls, v);
1802*088332b5SXin Li   while (ls->t.token == '.')
1803*088332b5SXin Li     fieldsel(ls, v);
1804*088332b5SXin Li   if (ls->t.token == ':') {
1805*088332b5SXin Li     ismethod = 1;
1806*088332b5SXin Li     fieldsel(ls, v);
1807*088332b5SXin Li   }
1808*088332b5SXin Li   return ismethod;
1809*088332b5SXin Li }
1810*088332b5SXin Li 
1811*088332b5SXin Li 
funcstat(LexState * ls,int line)1812*088332b5SXin Li static void funcstat (LexState *ls, int line) {
1813*088332b5SXin Li   /* funcstat -> FUNCTION funcname body */
1814*088332b5SXin Li   int ismethod;
1815*088332b5SXin Li   expdesc v, b;
1816*088332b5SXin Li   luaX_next(ls);  /* skip FUNCTION */
1817*088332b5SXin Li   ismethod = funcname(ls, &v);
1818*088332b5SXin Li   body(ls, &b, ismethod, line);
1819*088332b5SXin Li   luaK_storevar(ls->fs, &v, &b);
1820*088332b5SXin Li   luaK_fixline(ls->fs, line);  /* definition "happens" in the first line */
1821*088332b5SXin Li }
1822*088332b5SXin Li 
1823*088332b5SXin Li 
exprstat(LexState * ls)1824*088332b5SXin Li static void exprstat (LexState *ls) {
1825*088332b5SXin Li   /* stat -> func | assignment */
1826*088332b5SXin Li   FuncState *fs = ls->fs;
1827*088332b5SXin Li   struct LHS_assign v;
1828*088332b5SXin Li   suffixedexp(ls, &v.v);
1829*088332b5SXin Li   if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
1830*088332b5SXin Li     v.prev = NULL;
1831*088332b5SXin Li     restassign(ls, &v, 1);
1832*088332b5SXin Li   }
1833*088332b5SXin Li   else {  /* stat -> func */
1834*088332b5SXin Li     Instruction *inst;
1835*088332b5SXin Li     check_condition(ls, v.v.k == VCALL, "syntax error");
1836*088332b5SXin Li     inst = &getinstruction(fs, &v.v);
1837*088332b5SXin Li     SETARG_C(*inst, 1);  /* call statement uses no results */
1838*088332b5SXin Li   }
1839*088332b5SXin Li }
1840*088332b5SXin Li 
1841*088332b5SXin Li 
retstat(LexState * ls)1842*088332b5SXin Li static void retstat (LexState *ls) {
1843*088332b5SXin Li   /* stat -> RETURN [explist] [';'] */
1844*088332b5SXin Li   FuncState *fs = ls->fs;
1845*088332b5SXin Li   expdesc e;
1846*088332b5SXin Li   int nret;  /* number of values being returned */
1847*088332b5SXin Li   int first = luaY_nvarstack(fs);  /* first slot to be returned */
1848*088332b5SXin Li   if (block_follow(ls, 1) || ls->t.token == ';')
1849*088332b5SXin Li     nret = 0;  /* return no values */
1850*088332b5SXin Li   else {
1851*088332b5SXin Li     nret = explist(ls, &e);  /* optional return values */
1852*088332b5SXin Li     if (hasmultret(e.k)) {
1853*088332b5SXin Li       luaK_setmultret(fs, &e);
1854*088332b5SXin Li       if (e.k == VCALL && nret == 1 && !fs->bl->insidetbc) {  /* tail call? */
1855*088332b5SXin Li         SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL);
1856*088332b5SXin Li         lua_assert(GETARG_A(getinstruction(fs,&e)) == luaY_nvarstack(fs));
1857*088332b5SXin Li       }
1858*088332b5SXin Li       nret = LUA_MULTRET;  /* return all values */
1859*088332b5SXin Li     }
1860*088332b5SXin Li     else {
1861*088332b5SXin Li       if (nret == 1)  /* only one single value? */
1862*088332b5SXin Li         first = luaK_exp2anyreg(fs, &e);  /* can use original slot */
1863*088332b5SXin Li       else {  /* values must go to the top of the stack */
1864*088332b5SXin Li         luaK_exp2nextreg(fs, &e);
1865*088332b5SXin Li         lua_assert(nret == fs->freereg - first);
1866*088332b5SXin Li       }
1867*088332b5SXin Li     }
1868*088332b5SXin Li   }
1869*088332b5SXin Li   luaK_ret(fs, first, nret);
1870*088332b5SXin Li   testnext(ls, ';');  /* skip optional semicolon */
1871*088332b5SXin Li }
1872*088332b5SXin Li 
1873*088332b5SXin Li 
statement(LexState * ls)1874*088332b5SXin Li static void statement (LexState *ls) {
1875*088332b5SXin Li   int line = ls->linenumber;  /* may be needed for error messages */
1876*088332b5SXin Li   enterlevel(ls);
1877*088332b5SXin Li   switch (ls->t.token) {
1878*088332b5SXin Li     case ';': {  /* stat -> ';' (empty statement) */
1879*088332b5SXin Li       luaX_next(ls);  /* skip ';' */
1880*088332b5SXin Li       break;
1881*088332b5SXin Li     }
1882*088332b5SXin Li     case TK_IF: {  /* stat -> ifstat */
1883*088332b5SXin Li       ifstat(ls, line);
1884*088332b5SXin Li       break;
1885*088332b5SXin Li     }
1886*088332b5SXin Li     case TK_WHILE: {  /* stat -> whilestat */
1887*088332b5SXin Li       whilestat(ls, line);
1888*088332b5SXin Li       break;
1889*088332b5SXin Li     }
1890*088332b5SXin Li     case TK_DO: {  /* stat -> DO block END */
1891*088332b5SXin Li       luaX_next(ls);  /* skip DO */
1892*088332b5SXin Li       block(ls);
1893*088332b5SXin Li       check_match(ls, TK_END, TK_DO, line);
1894*088332b5SXin Li       break;
1895*088332b5SXin Li     }
1896*088332b5SXin Li     case TK_FOR: {  /* stat -> forstat */
1897*088332b5SXin Li       forstat(ls, line);
1898*088332b5SXin Li       break;
1899*088332b5SXin Li     }
1900*088332b5SXin Li     case TK_REPEAT: {  /* stat -> repeatstat */
1901*088332b5SXin Li       repeatstat(ls, line);
1902*088332b5SXin Li       break;
1903*088332b5SXin Li     }
1904*088332b5SXin Li     case TK_FUNCTION: {  /* stat -> funcstat */
1905*088332b5SXin Li       funcstat(ls, line);
1906*088332b5SXin Li       break;
1907*088332b5SXin Li     }
1908*088332b5SXin Li     case TK_LOCAL: {  /* stat -> localstat */
1909*088332b5SXin Li       luaX_next(ls);  /* skip LOCAL */
1910*088332b5SXin Li       if (testnext(ls, TK_FUNCTION))  /* local function? */
1911*088332b5SXin Li         localfunc(ls);
1912*088332b5SXin Li       else
1913*088332b5SXin Li         localstat(ls);
1914*088332b5SXin Li       break;
1915*088332b5SXin Li     }
1916*088332b5SXin Li     case TK_DBCOLON: {  /* stat -> label */
1917*088332b5SXin Li       luaX_next(ls);  /* skip double colon */
1918*088332b5SXin Li       labelstat(ls, str_checkname(ls), line);
1919*088332b5SXin Li       break;
1920*088332b5SXin Li     }
1921*088332b5SXin Li     case TK_RETURN: {  /* stat -> retstat */
1922*088332b5SXin Li       luaX_next(ls);  /* skip RETURN */
1923*088332b5SXin Li       retstat(ls);
1924*088332b5SXin Li       break;
1925*088332b5SXin Li     }
1926*088332b5SXin Li     case TK_BREAK: {  /* stat -> breakstat */
1927*088332b5SXin Li       breakstat(ls);
1928*088332b5SXin Li       break;
1929*088332b5SXin Li     }
1930*088332b5SXin Li     case TK_GOTO: {  /* stat -> 'goto' NAME */
1931*088332b5SXin Li       luaX_next(ls);  /* skip 'goto' */
1932*088332b5SXin Li       gotostat(ls);
1933*088332b5SXin Li       break;
1934*088332b5SXin Li     }
1935*088332b5SXin Li     default: {  /* stat -> func | assignment */
1936*088332b5SXin Li       exprstat(ls);
1937*088332b5SXin Li       break;
1938*088332b5SXin Li     }
1939*088332b5SXin Li   }
1940*088332b5SXin Li   lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
1941*088332b5SXin Li              ls->fs->freereg >= luaY_nvarstack(ls->fs));
1942*088332b5SXin Li   ls->fs->freereg = luaY_nvarstack(ls->fs);  /* free registers */
1943*088332b5SXin Li   leavelevel(ls);
1944*088332b5SXin Li }
1945*088332b5SXin Li 
1946*088332b5SXin Li /* }====================================================================== */
1947*088332b5SXin Li 
1948*088332b5SXin Li 
1949*088332b5SXin Li /*
1950*088332b5SXin Li ** compiles the main function, which is a regular vararg function with an
1951*088332b5SXin Li ** upvalue named LUA_ENV
1952*088332b5SXin Li */
mainfunc(LexState * ls,FuncState * fs)1953*088332b5SXin Li static void mainfunc (LexState *ls, FuncState *fs) {
1954*088332b5SXin Li   BlockCnt bl;
1955*088332b5SXin Li   Upvaldesc *env;
1956*088332b5SXin Li   open_func(ls, fs, &bl);
1957*088332b5SXin Li   setvararg(fs, 0);  /* main function is always declared vararg */
1958*088332b5SXin Li   env = allocupvalue(fs);  /* ...set environment upvalue */
1959*088332b5SXin Li   env->instack = 1;
1960*088332b5SXin Li   env->idx = 0;
1961*088332b5SXin Li   env->kind = VDKREG;
1962*088332b5SXin Li   env->name = ls->envn;
1963*088332b5SXin Li   luaC_objbarrier(ls->L, fs->f, env->name);
1964*088332b5SXin Li   luaX_next(ls);  /* read first token */
1965*088332b5SXin Li   statlist(ls);  /* parse main body */
1966*088332b5SXin Li   check(ls, TK_EOS);
1967*088332b5SXin Li   close_func(ls);
1968*088332b5SXin Li }
1969*088332b5SXin Li 
1970*088332b5SXin Li 
luaY_parser(lua_State * L,ZIO * z,Mbuffer * buff,Dyndata * dyd,const char * name,int firstchar)1971*088332b5SXin Li LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
1972*088332b5SXin Li                        Dyndata *dyd, const char *name, int firstchar) {
1973*088332b5SXin Li   LexState lexstate;
1974*088332b5SXin Li   FuncState funcstate;
1975*088332b5SXin Li   LClosure *cl = luaF_newLclosure(L, 1);  /* create main closure */
1976*088332b5SXin Li   setclLvalue2s(L, L->top, cl);  /* anchor it (to avoid being collected) */
1977*088332b5SXin Li   luaD_inctop(L);
1978*088332b5SXin Li   lexstate.h = luaH_new(L);  /* create table for scanner */
1979*088332b5SXin Li   sethvalue2s(L, L->top, lexstate.h);  /* anchor it */
1980*088332b5SXin Li   luaD_inctop(L);
1981*088332b5SXin Li   funcstate.f = cl->p = luaF_newproto(L);
1982*088332b5SXin Li   luaC_objbarrier(L, cl, cl->p);
1983*088332b5SXin Li   funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */
1984*088332b5SXin Li   luaC_objbarrier(L, funcstate.f, funcstate.f->source);
1985*088332b5SXin Li   lexstate.buff = buff;
1986*088332b5SXin Li   lexstate.dyd = dyd;
1987*088332b5SXin Li   dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
1988*088332b5SXin Li   luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
1989*088332b5SXin Li   mainfunc(&lexstate, &funcstate);
1990*088332b5SXin Li   lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
1991*088332b5SXin Li   /* all scopes should be correctly finished */
1992*088332b5SXin Li   lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
1993*088332b5SXin Li   L->top--;  /* remove scanner's table */
1994*088332b5SXin Li   return cl;  /* closure is on the stack, too */
1995*088332b5SXin Li }
1996*088332b5SXin Li 
1997