Path: blob/main/sys/contrib/openzfs/module/lua/lparser.c
48383 views
// SPDX-License-Identifier: MIT1/*2** $Id: lparser.c,v 2.130.1.1 2013/04/12 18:48:47 roberto Exp $3** Lua Parser4** See Copyright Notice in lua.h5*/67#define lparser_c8#define LUA_CORE910#include <sys/lua/lua.h>1112#include "lcode.h"13#include "ldebug.h"14#include "ldo.h"15#include "lfunc.h"16#include "llex.h"17#include "lmem.h"18#include "lobject.h"19#include "lopcodes.h"20#include "lparser.h"21#include "lstate.h"22#include "lstring.h"23#include "ltable.h"24252627/* maximum number of local variables per function (must be smaller28than 250, due to the bytecode format) */29#define MAXVARS 200303132#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)33343536/*37** nodes for block list (list of active blocks)38*/39typedef struct BlockCnt {40struct BlockCnt *previous; /* chain */41short firstlabel; /* index of first label in this block */42short firstgoto; /* index of first pending goto in this block */43lu_byte nactvar; /* # active locals outside the block */44lu_byte upval; /* true if some variable in the block is an upvalue */45lu_byte isloop; /* true if `block' is a loop */46} BlockCnt;47484950/*51** prototypes for recursive non-terminal functions52*/53static void statement (LexState *ls);54static void expr (LexState *ls, expdesc *v);555657static void anchor_token (LexState *ls) {58/* last token from outer function must be EOS */59lua_assert(ls->fs != NULL || ls->t.token == TK_EOS);60if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {61TString *ts = ls->t.seminfo.ts;62luaX_newstring(ls, getstr(ts), ts->tsv.len);63}64}656667/* semantic error */68static l_noret semerror (LexState *ls, const char *msg) {69ls->t.token = 0; /* remove 'near to' from final message */70luaX_syntaxerror(ls, msg);71}727374static l_noret error_expected (LexState *ls, int token) {75luaX_syntaxerror(ls,76luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));77}787980static l_noret errorlimit (FuncState *fs, int limit, const char *what) {81lua_State *L = fs->ls->L;82const char *msg;83int line = fs->f->linedefined;84const char *where = (line == 0)85? "main function"86: luaO_pushfstring(L, "function at line %d", line);87msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",88what, limit, where);89luaX_syntaxerror(fs->ls, msg);90}919293static void checklimit (FuncState *fs, int v, int l, const char *what) {94if (v > l) errorlimit(fs, l, what);95}969798static int testnext (LexState *ls, int c) {99if (ls->t.token == c) {100luaX_next(ls);101return 1;102}103else return 0;104}105106107static void check (LexState *ls, int c) {108if (ls->t.token != c)109error_expected(ls, c);110}111112113static void checknext (LexState *ls, int c) {114check(ls, c);115luaX_next(ls);116}117118119#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }120121122123static void check_match (LexState *ls, int what, int who, int where) {124if (!testnext(ls, what)) {125if (where == ls->linenumber)126error_expected(ls, what);127else {128luaX_syntaxerror(ls, luaO_pushfstring(ls->L,129"%s expected (to close %s at line %d)",130luaX_token2str(ls, what), luaX_token2str(ls, who), where));131}132}133}134135136static TString *str_checkname (LexState *ls) {137TString *ts;138check(ls, TK_NAME);139ts = ls->t.seminfo.ts;140luaX_next(ls);141return ts;142}143144145static void init_exp (expdesc *e, expkind k, int i) {146e->f = e->t = NO_JUMP;147e->k = k;148e->u.info = i;149}150151152static void codestring (LexState *ls, expdesc *e, TString *s) {153init_exp(e, VK, luaK_stringK(ls->fs, s));154}155156157static void checkname (LexState *ls, expdesc *e) {158codestring(ls, e, str_checkname(ls));159}160161162static int registerlocalvar (LexState *ls, TString *varname) {163FuncState *fs = ls->fs;164Proto *f = fs->f;165int oldsize = f->sizelocvars;166luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,167LocVar, SHRT_MAX, "local variables");168while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;169f->locvars[fs->nlocvars].varname = varname;170luaC_objbarrier(ls->L, f, varname);171return fs->nlocvars++;172}173174175static void new_localvar (LexState *ls, TString *name) {176FuncState *fs = ls->fs;177Dyndata *dyd = ls->dyd;178int reg = registerlocalvar(ls, name);179checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,180MAXVARS, "local variables");181luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,182dyd->actvar.size, Vardesc, MAX_INT, "local variables");183dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);184}185186187static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {188new_localvar(ls, luaX_newstring(ls, name, sz));189}190191#define new_localvarliteral(ls,v) \192new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1)193194195static LocVar *getlocvar (FuncState *fs, int i) {196int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;197lua_assert(idx < fs->nlocvars);198return &fs->f->locvars[idx];199}200201202static void adjustlocalvars (LexState *ls, int nvars) {203FuncState *fs = ls->fs;204fs->nactvar = cast_byte(fs->nactvar + nvars);205for (; nvars; nvars--) {206getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;207}208}209210211static void removevars (FuncState *fs, int tolevel) {212fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);213while (fs->nactvar > tolevel)214getlocvar(fs, --fs->nactvar)->endpc = fs->pc;215}216217218static int searchupvalue (FuncState *fs, TString *name) {219int i;220Upvaldesc *up = fs->f->upvalues;221for (i = 0; i < fs->nups; i++) {222if (luaS_eqstr(up[i].name, name)) return i;223}224return -1; /* not found */225}226227228static int newupvalue (FuncState *fs, TString *name, expdesc *v) {229Proto *f = fs->f;230int oldsize = f->sizeupvalues;231checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");232luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,233Upvaldesc, MAXUPVAL, "upvalues");234while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;235f->upvalues[fs->nups].instack = (v->k == VLOCAL);236f->upvalues[fs->nups].idx = cast_byte(v->u.info);237f->upvalues[fs->nups].name = name;238luaC_objbarrier(fs->ls->L, f, name);239return fs->nups++;240}241242243static int searchvar (FuncState *fs, TString *n) {244int i;245for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {246if (luaS_eqstr(n, getlocvar(fs, i)->varname))247return i;248}249return -1; /* not found */250}251252253/*254Mark block where variable at given level was defined255(to emit close instructions later).256*/257static void markupval (FuncState *fs, int level) {258BlockCnt *bl = fs->bl;259while (bl->nactvar > level) bl = bl->previous;260bl->upval = 1;261}262263264/*265Find variable with given name 'n'. If it is an upvalue, add this266upvalue into all intermediate functions.267*/268static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {269if (fs == NULL) /* no more levels? */270return VVOID; /* default is global */271else {272int v = searchvar(fs, n); /* look up locals at current level */273if (v >= 0) { /* found? */274init_exp(var, VLOCAL, v); /* variable is local */275if (!base)276markupval(fs, v); /* local will be used as an upval */277return VLOCAL;278}279else { /* not found as local at current level; try upvalues */280int idx = searchupvalue(fs, n); /* try existing upvalues */281if (idx < 0) { /* not found? */282if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */283return VVOID; /* not found; is a global */284/* else was LOCAL or UPVAL */285idx = newupvalue(fs, n, var); /* will be a new upvalue */286}287init_exp(var, VUPVAL, idx);288return VUPVAL;289}290}291}292293294static void singlevar (LexState *ls, expdesc *var) {295TString *varname = str_checkname(ls);296FuncState *fs = ls->fs;297if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */298expdesc key;299singlevaraux(fs, ls->envn, var, 1); /* get environment variable */300lua_assert(var->k == VLOCAL || var->k == VUPVAL);301codestring(ls, &key, varname); /* key is variable name */302luaK_indexed(fs, var, &key); /* env[varname] */303}304}305306307static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {308FuncState *fs = ls->fs;309int extra = nvars - nexps;310if (hasmultret(e->k)) {311extra++; /* includes call itself */312if (extra < 0) extra = 0;313luaK_setreturns(fs, e, extra); /* last exp. provides the difference */314if (extra > 1) luaK_reserveregs(fs, extra-1);315}316else {317if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */318if (extra > 0) {319int reg = fs->freereg;320luaK_reserveregs(fs, extra);321luaK_nil(fs, reg, extra);322}323}324}325326327static void enterlevel (LexState *ls) {328lua_State *L = ls->L;329++L->nCcalls;330checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");331}332333334#define leavelevel(ls) ((ls)->L->nCcalls--)335336337static void closegoto (LexState *ls, int g, Labeldesc *label) {338int i;339FuncState *fs = ls->fs;340Labellist *gl = &ls->dyd->gt;341Labeldesc *gt = &gl->arr[g];342lua_assert(luaS_eqstr(gt->name, label->name));343if (gt->nactvar < label->nactvar) {344TString *vname = getlocvar(fs, gt->nactvar)->varname;345const char *msg = luaO_pushfstring(ls->L,346"<goto %s> at line %d jumps into the scope of local " LUA_QS,347getstr(gt->name), gt->line, getstr(vname));348semerror(ls, msg);349}350luaK_patchlist(fs, gt->pc, label->pc);351/* remove goto from pending list */352for (i = g; i < gl->n - 1; i++)353gl->arr[i] = gl->arr[i + 1];354gl->n--;355}356357358/*359** try to close a goto with existing labels; this solves backward jumps360*/361static int findlabel (LexState *ls, int g) {362int i;363BlockCnt *bl = ls->fs->bl;364Dyndata *dyd = ls->dyd;365Labeldesc *gt = &dyd->gt.arr[g];366/* check labels in current block for a match */367for (i = bl->firstlabel; i < dyd->label.n; i++) {368Labeldesc *lb = &dyd->label.arr[i];369if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */370if (gt->nactvar > lb->nactvar &&371(bl->upval || dyd->label.n > bl->firstlabel))372luaK_patchclose(ls->fs, gt->pc, lb->nactvar);373closegoto(ls, g, lb); /* close it */374return 1;375}376}377return 0; /* label not found; cannot close goto */378}379380381static int newlabelentry (LexState *ls, Labellist *l, TString *name,382int line, int pc) {383int n = l->n;384luaM_growvector(ls->L, l->arr, n, l->size,385Labeldesc, SHRT_MAX, "labels/gotos");386l->arr[n].name = name;387l->arr[n].line = line;388l->arr[n].nactvar = ls->fs->nactvar;389l->arr[n].pc = pc;390l->n++;391return n;392}393394395/*396** check whether new label 'lb' matches any pending gotos in current397** block; solves forward jumps398*/399static void findgotos (LexState *ls, Labeldesc *lb) {400Labellist *gl = &ls->dyd->gt;401int i = ls->fs->bl->firstgoto;402while (i < gl->n) {403if (luaS_eqstr(gl->arr[i].name, lb->name))404closegoto(ls, i, lb);405else406i++;407}408}409410411/*412** "export" pending gotos to outer level, to check them against413** outer labels; if the block being exited has upvalues, and414** the goto exits the scope of any variable (which can be the415** upvalue), close those variables being exited.416*/417static void movegotosout (FuncState *fs, BlockCnt *bl) {418int i = bl->firstgoto;419Labellist *gl = &fs->ls->dyd->gt;420/* correct pending gotos to current block and try to close it421with visible labels */422while (i < gl->n) {423Labeldesc *gt = &gl->arr[i];424if (gt->nactvar > bl->nactvar) {425if (bl->upval)426luaK_patchclose(fs, gt->pc, bl->nactvar);427gt->nactvar = bl->nactvar;428}429if (!findlabel(fs->ls, i))430i++; /* move to next one */431}432}433434435static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {436bl->isloop = isloop;437bl->nactvar = fs->nactvar;438bl->firstlabel = fs->ls->dyd->label.n;439bl->firstgoto = fs->ls->dyd->gt.n;440bl->upval = 0;441bl->previous = fs->bl;442fs->bl = bl;443lua_assert(fs->freereg == fs->nactvar);444}445446447/*448** create a label named "break" to resolve break statements449*/450static void breaklabel (LexState *ls) {451TString *n = luaS_new(ls->L, "break");452int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc);453findgotos(ls, &ls->dyd->label.arr[l]);454}455456/*457** generates an error for an undefined 'goto'; choose appropriate458** message when label name is a reserved word (which can only be 'break')459*/460static l_noret undefgoto (LexState *ls, Labeldesc *gt) {461const char *msg = isreserved(gt->name)462? "<%s> at line %d not inside a loop"463: "no visible label " LUA_QS " for <goto> at line %d";464msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);465semerror(ls, msg);466}467468469static void leaveblock (FuncState *fs) {470BlockCnt *bl = fs->bl;471LexState *ls = fs->ls;472if (bl->previous && bl->upval) {473/* create a 'jump to here' to close upvalues */474int j = luaK_jump(fs);475luaK_patchclose(fs, j, bl->nactvar);476luaK_patchtohere(fs, j);477}478if (bl->isloop)479breaklabel(ls); /* close pending breaks */480fs->bl = bl->previous;481removevars(fs, bl->nactvar);482lua_assert(bl->nactvar == fs->nactvar);483fs->freereg = fs->nactvar; /* free registers */484ls->dyd->label.n = bl->firstlabel; /* remove local labels */485if (bl->previous) /* inner block? */486movegotosout(fs, bl); /* update pending gotos to outer block */487else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */488undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */489}490491492/*493** adds a new prototype into list of prototypes494*/495static Proto *addprototype (LexState *ls) {496Proto *clp;497lua_State *L = ls->L;498FuncState *fs = ls->fs;499Proto *f = fs->f; /* prototype of current function */500if (fs->np >= f->sizep) {501int oldsize = f->sizep;502luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");503while (oldsize < f->sizep) f->p[oldsize++] = NULL;504}505f->p[fs->np++] = clp = luaF_newproto(L);506luaC_objbarrier(L, f, clp);507return clp;508}509510511/*512** codes instruction to create new closure in parent function.513** The OP_CLOSURE instruction must use the last available register,514** so that, if it invokes the GC, the GC knows which registers515** are in use at that time.516*/517static void codeclosure (LexState *ls, expdesc *v) {518FuncState *fs = ls->fs->prev;519init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));520luaK_exp2nextreg(fs, v); /* fix it at the last register */521}522523524static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {525lua_State *L = ls->L;526Proto *f;527fs->prev = ls->fs; /* linked list of funcstates */528fs->ls = ls;529ls->fs = fs;530fs->pc = 0;531fs->lasttarget = 0;532fs->jpc = NO_JUMP;533fs->freereg = 0;534fs->nk = 0;535fs->np = 0;536fs->nups = 0;537fs->nlocvars = 0;538fs->nactvar = 0;539fs->firstlocal = ls->dyd->actvar.n;540fs->bl = NULL;541f = fs->f;542f->source = ls->source;543f->maxstacksize = 2; /* registers 0/1 are always valid */544fs->h = luaH_new(L);545/* anchor table of constants (to avoid being collected) */546sethvalue2s(L, L->top, fs->h);547incr_top(L);548enterblock(fs, bl, 0);549}550551552static void close_func (LexState *ls) {553lua_State *L = ls->L;554FuncState *fs = ls->fs;555Proto *f = fs->f;556luaK_ret(fs, 0, 0); /* final return */557leaveblock(fs);558luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);559f->sizecode = fs->pc;560luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);561f->sizelineinfo = fs->pc;562luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);563f->sizek = fs->nk;564luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);565f->sizep = fs->np;566luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);567f->sizelocvars = fs->nlocvars;568luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);569f->sizeupvalues = fs->nups;570lua_assert(fs->bl == NULL);571ls->fs = fs->prev;572/* last token read was anchored in defunct function; must re-anchor it */573anchor_token(ls);574L->top--; /* pop table of constants */575luaC_checkGC(L);576}577578579580/*============================================================*/581/* GRAMMAR RULES */582/*============================================================*/583584585/*586** check whether current token is in the follow set of a block.587** 'until' closes syntactical blocks, but do not close scope,588** so it handled in separate.589*/590static int block_follow (LexState *ls, int withuntil) {591switch (ls->t.token) {592case TK_ELSE: case TK_ELSEIF:593case TK_END: case TK_EOS:594return 1;595case TK_UNTIL: return withuntil;596default: return 0;597}598}599600601/*602* by inlining statlist() and test_then_block() we cut back the603* native stack usage per nested C call from 272 bytes to 152604* which allows us to stay within budget for 8K kernel stacks605*/606__attribute__((always_inline)) inline607static void statlist (LexState *ls) {608/* statlist -> { stat [`;'] } */609while (!block_follow(ls, 1)) {610if (ls->t.token == TK_RETURN) {611statement(ls);612return; /* 'return' must be last statement */613}614statement(ls);615}616}617618619static void fieldsel (LexState *ls, expdesc *v) {620/* fieldsel -> ['.' | ':'] NAME */621FuncState *fs = ls->fs;622expdesc key;623luaK_exp2anyregup(fs, v);624luaX_next(ls); /* skip the dot or colon */625checkname(ls, &key);626luaK_indexed(fs, v, &key);627}628629630static void yindex (LexState *ls, expdesc *v) {631/* index -> '[' expr ']' */632luaX_next(ls); /* skip the '[' */633expr(ls, v);634luaK_exp2val(ls->fs, v);635checknext(ls, ']');636}637638639/*640** {======================================================================641** Rules for Constructors642** =======================================================================643*/644645646struct ConsControl {647expdesc v; /* last list item read */648expdesc *t; /* table descriptor */649int nh; /* total number of `record' elements */650int na; /* total number of array elements */651int tostore; /* number of array elements pending to be stored */652};653654655static void recfield (LexState *ls, struct ConsControl *cc) {656/* recfield -> (NAME | `['exp1`]') = exp1 */657FuncState *fs = ls->fs;658int reg = ls->fs->freereg;659expdesc key, val;660int rkkey;661if (ls->t.token == TK_NAME) {662checklimit(fs, cc->nh, MAX_INT, "items in a constructor");663checkname(ls, &key);664}665else /* ls->t.token == '[' */666yindex(ls, &key);667cc->nh++;668checknext(ls, '=');669rkkey = luaK_exp2RK(fs, &key);670expr(ls, &val);671luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));672fs->freereg = reg; /* free registers */673}674675676static void closelistfield (FuncState *fs, struct ConsControl *cc) {677if (cc->v.k == VVOID) return; /* there is no list item */678luaK_exp2nextreg(fs, &cc->v);679cc->v.k = VVOID;680if (cc->tostore == LFIELDS_PER_FLUSH) {681luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */682cc->tostore = 0; /* no more items pending */683}684}685686687static void lastlistfield (FuncState *fs, struct ConsControl *cc) {688if (cc->tostore == 0) return;689if (hasmultret(cc->v.k)) {690luaK_setmultret(fs, &cc->v);691luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);692cc->na--; /* do not count last expression (unknown number of elements) */693}694else {695if (cc->v.k != VVOID)696luaK_exp2nextreg(fs, &cc->v);697luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);698}699}700701702static void listfield (LexState *ls, struct ConsControl *cc) {703/* listfield -> exp */704expr(ls, &cc->v);705checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");706cc->na++;707cc->tostore++;708}709710711static void field (LexState *ls, struct ConsControl *cc) {712/* field -> listfield | recfield */713switch(ls->t.token) {714case TK_NAME: { /* may be 'listfield' or 'recfield' */715if (luaX_lookahead(ls) != '=') /* expression? */716listfield(ls, cc);717else718recfield(ls, cc);719break;720}721case '[': {722recfield(ls, cc);723break;724}725default: {726listfield(ls, cc);727break;728}729}730}731732733static void constructor (LexState *ls, expdesc *t) {734/* constructor -> '{' [ field { sep field } [sep] ] '}'735sep -> ',' | ';' */736FuncState *fs = ls->fs;737int line = ls->linenumber;738int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);739struct ConsControl cc;740cc.na = cc.nh = cc.tostore = 0;741cc.t = t;742init_exp(t, VRELOCABLE, pc);743init_exp(&cc.v, VVOID, 0); /* no value (yet) */744luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */745checknext(ls, '{');746do {747lua_assert(cc.v.k == VVOID || cc.tostore > 0);748if (ls->t.token == '}') break;749closelistfield(fs, &cc);750field(ls, &cc);751} while (testnext(ls, ',') || testnext(ls, ';'));752check_match(ls, '}', '{', line);753lastlistfield(fs, &cc);754SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */755SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */756}757758/* }====================================================================== */759760761762static void parlist (LexState *ls) {763/* parlist -> [ param { `,' param } ] */764FuncState *fs = ls->fs;765Proto *f = fs->f;766int nparams = 0;767f->is_vararg = 0;768if (ls->t.token != ')') { /* is `parlist' not empty? */769do {770switch (ls->t.token) {771case TK_NAME: { /* param -> NAME */772new_localvar(ls, str_checkname(ls));773nparams++;774break;775}776case TK_DOTS: { /* param -> `...' */777luaX_next(ls);778f->is_vararg = 1;779break;780}781default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");782}783} while (!f->is_vararg && testnext(ls, ','));784}785adjustlocalvars(ls, nparams);786f->numparams = cast_byte(fs->nactvar);787luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */788}789790791static void body (LexState *ls, expdesc *e, int ismethod, int line) {792/* body -> `(' parlist `)' block END */793FuncState new_fs;794BlockCnt bl;795new_fs.f = addprototype(ls);796new_fs.f->linedefined = line;797open_func(ls, &new_fs, &bl);798checknext(ls, '(');799if (ismethod) {800new_localvarliteral(ls, "self"); /* create 'self' parameter */801adjustlocalvars(ls, 1);802}803parlist(ls);804checknext(ls, ')');805statlist(ls);806new_fs.f->lastlinedefined = ls->linenumber;807check_match(ls, TK_END, TK_FUNCTION, line);808codeclosure(ls, e);809close_func(ls);810}811812813static int explist (LexState *ls, expdesc *v) {814/* explist -> expr { `,' expr } */815int n = 1; /* at least one expression */816expr(ls, v);817while (testnext(ls, ',')) {818luaK_exp2nextreg(ls->fs, v);819expr(ls, v);820n++;821}822return n;823}824825826static void funcargs (LexState *ls, expdesc *f, int line) {827FuncState *fs = ls->fs;828expdesc args;829int base, nparams;830switch (ls->t.token) {831case '(': { /* funcargs -> `(' [ explist ] `)' */832luaX_next(ls);833if (ls->t.token == ')') /* arg list is empty? */834args.k = VVOID;835else {836explist(ls, &args);837luaK_setmultret(fs, &args);838}839check_match(ls, ')', '(', line);840break;841}842case '{': { /* funcargs -> constructor */843constructor(ls, &args);844break;845}846case TK_STRING: { /* funcargs -> STRING */847codestring(ls, &args, ls->t.seminfo.ts);848luaX_next(ls); /* must use `seminfo' before `next' */849break;850}851default: {852luaX_syntaxerror(ls, "function arguments expected");853}854}855lua_assert(f->k == VNONRELOC);856base = f->u.info; /* base register for call */857if (hasmultret(args.k))858nparams = LUA_MULTRET; /* open call */859else {860if (args.k != VVOID)861luaK_exp2nextreg(fs, &args); /* close last argument */862nparams = fs->freereg - (base+1);863}864init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));865luaK_fixline(fs, line);866fs->freereg = base+1; /* call remove function and arguments and leaves867(unless changed) one result */868}869870871872873/*874** {======================================================================875** Expression parsing876** =======================================================================877*/878879880static void primaryexp (LexState *ls, expdesc *v) {881/* primaryexp -> NAME | '(' expr ')' */882switch (ls->t.token) {883case '(': {884int line = ls->linenumber;885luaX_next(ls);886expr(ls, v);887check_match(ls, ')', '(', line);888luaK_dischargevars(ls->fs, v);889return;890}891case TK_NAME: {892singlevar(ls, v);893return;894}895default: {896luaX_syntaxerror(ls, "unexpected symbol");897}898}899}900901902static void suffixedexp (LexState *ls, expdesc *v) {903/* suffixedexp ->904primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */905FuncState *fs = ls->fs;906int line = ls->linenumber;907primaryexp(ls, v);908for (;;) {909switch (ls->t.token) {910case '.': { /* fieldsel */911fieldsel(ls, v);912break;913}914case '[': { /* `[' exp1 `]' */915expdesc key;916luaK_exp2anyregup(fs, v);917yindex(ls, &key);918luaK_indexed(fs, v, &key);919break;920}921case ':': { /* `:' NAME funcargs */922expdesc key;923luaX_next(ls);924checkname(ls, &key);925luaK_self(fs, v, &key);926funcargs(ls, v, line);927break;928}929case '(': case TK_STRING: case '{': { /* funcargs */930luaK_exp2nextreg(fs, v);931funcargs(ls, v, line);932break;933}934default: return;935}936}937}938939940static void simpleexp (LexState *ls, expdesc *v) {941/* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |942constructor | FUNCTION body | suffixedexp */943switch (ls->t.token) {944case TK_NUMBER: {945init_exp(v, VKNUM, 0);946v->u.nval = ls->t.seminfo.r;947break;948}949case TK_STRING: {950codestring(ls, v, ls->t.seminfo.ts);951break;952}953case TK_NIL: {954init_exp(v, VNIL, 0);955break;956}957case TK_TRUE: {958init_exp(v, VTRUE, 0);959break;960}961case TK_FALSE: {962init_exp(v, VFALSE, 0);963break;964}965case TK_DOTS: { /* vararg */966FuncState *fs = ls->fs;967check_condition(ls, fs->f->is_vararg,968"cannot use " LUA_QL("...") " outside a vararg function");969init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));970break;971}972case '{': { /* constructor */973constructor(ls, v);974return;975}976case TK_FUNCTION: {977luaX_next(ls);978body(ls, v, 0, ls->linenumber);979return;980}981default: {982suffixedexp(ls, v);983return;984}985}986luaX_next(ls);987}988989990static UnOpr getunopr (int op) {991switch (op) {992case TK_NOT: return OPR_NOT;993case '-': return OPR_MINUS;994case '#': return OPR_LEN;995default: return OPR_NOUNOPR;996}997}9989991000static BinOpr getbinopr (int op) {1001switch (op) {1002case '+': return OPR_ADD;1003case '-': return OPR_SUB;1004case '*': return OPR_MUL;1005case '/': return OPR_DIV;1006case '%': return OPR_MOD;1007case '^': return OPR_POW;1008case TK_CONCAT: return OPR_CONCAT;1009case TK_NE: return OPR_NE;1010case TK_EQ: return OPR_EQ;1011case '<': return OPR_LT;1012case TK_LE: return OPR_LE;1013case '>': return OPR_GT;1014case TK_GE: return OPR_GE;1015case TK_AND: return OPR_AND;1016case TK_OR: return OPR_OR;1017default: return OPR_NOBINOPR;1018}1019}102010211022static const struct {1023lu_byte left; /* left priority for each binary operator */1024lu_byte right; /* right priority */1025} priority[] = { /* ORDER OPR */1026{6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */1027{10, 9}, {5, 4}, /* ^, .. (right associative) */1028{3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */1029{3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */1030{2, 2}, {1, 1} /* and, or */1031};10321033#define UNARY_PRIORITY 8 /* priority for unary operators */103410351036/*1037** subexpr -> (simpleexp | unop subexpr) { binop subexpr }1038** where `binop' is any binary operator with a priority higher than `limit'1039*/1040static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {1041BinOpr op;1042UnOpr uop;1043enterlevel(ls);1044uop = getunopr(ls->t.token);1045if (uop != OPR_NOUNOPR) {1046int line = ls->linenumber;1047luaX_next(ls);1048subexpr(ls, v, UNARY_PRIORITY);1049luaK_prefix(ls->fs, uop, v, line);1050}1051else simpleexp(ls, v);1052/* expand while operators have priorities higher than `limit' */1053op = getbinopr(ls->t.token);1054while (op != OPR_NOBINOPR && priority[op].left > limit) {1055expdesc v2;1056BinOpr nextop;1057int line = ls->linenumber;1058luaX_next(ls);1059luaK_infix(ls->fs, op, v);1060/* read sub-expression with higher priority */1061nextop = subexpr(ls, &v2, priority[op].right);1062luaK_posfix(ls->fs, op, v, &v2, line);1063op = nextop;1064}1065leavelevel(ls);1066return op; /* return first untreated operator */1067}106810691070static void expr (LexState *ls, expdesc *v) {1071subexpr(ls, v, 0);1072}10731074/* }==================================================================== */1075107610771078/*1079** {======================================================================1080** Rules for Statements1081** =======================================================================1082*/108310841085static void block (LexState *ls) {1086/* block -> statlist */1087FuncState *fs = ls->fs;1088BlockCnt bl;1089enterblock(fs, &bl, 0);1090statlist(ls);1091leaveblock(fs);1092}109310941095/*1096** structure to chain all variables in the left-hand side of an1097** assignment1098*/1099struct LHS_assign {1100struct LHS_assign *prev;1101expdesc v; /* variable (global, local, upvalue, or indexed) */1102};110311041105/*1106** check whether, in an assignment to an upvalue/local variable, the1107** upvalue/local variable is begin used in a previous assignment to a1108** table. If so, save original upvalue/local value in a safe place and1109** use this safe copy in the previous assignment.1110*/1111static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {1112FuncState *fs = ls->fs;1113int extra = fs->freereg; /* eventual position to save local variable */1114int conflict = 0;1115for (; lh; lh = lh->prev) { /* check all previous assignments */1116if (lh->v.k == VINDEXED) { /* assigning to a table? */1117/* table is the upvalue/local being assigned now? */1118if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {1119conflict = 1;1120lh->v.u.ind.vt = VLOCAL;1121lh->v.u.ind.t = extra; /* previous assignment will use safe copy */1122}1123/* index is the local being assigned? (index cannot be upvalue) */1124if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {1125conflict = 1;1126lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */1127}1128}1129}1130if (conflict) {1131/* copy upvalue/local value to a temporary (in position 'extra') */1132OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;1133luaK_codeABC(fs, op, extra, v->u.info, 0);1134luaK_reserveregs(fs, 1);1135}1136}113711381139static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {1140expdesc e;1141check_condition(ls, vkisvar(lh->v.k), "syntax error");1142if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */1143struct LHS_assign nv;1144nv.prev = lh;1145suffixedexp(ls, &nv.v);1146if (nv.v.k != VINDEXED)1147check_conflict(ls, lh, &nv.v);1148checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,1149"C levels");1150assignment(ls, &nv, nvars+1);1151}1152else { /* assignment -> `=' explist */1153int nexps;1154checknext(ls, '=');1155nexps = explist(ls, &e);1156if (nexps != nvars) {1157adjust_assign(ls, nvars, nexps, &e);1158if (nexps > nvars)1159ls->fs->freereg -= nexps - nvars; /* remove extra values */1160}1161else {1162luaK_setoneret(ls->fs, &e); /* close last expression */1163luaK_storevar(ls->fs, &lh->v, &e);1164return; /* avoid default */1165}1166}1167init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */1168luaK_storevar(ls->fs, &lh->v, &e);1169}117011711172static int cond (LexState *ls) {1173/* cond -> exp */1174expdesc v;1175expr(ls, &v); /* read condition */1176if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */1177luaK_goiftrue(ls->fs, &v);1178return v.f;1179}118011811182static void gotostat (LexState *ls, int pc) {1183int line = ls->linenumber;1184TString *label;1185int g;1186if (testnext(ls, TK_GOTO))1187label = str_checkname(ls);1188else {1189luaX_next(ls); /* skip break */1190label = luaS_new(ls->L, "break");1191}1192g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);1193findlabel(ls, g); /* close it if label already defined */1194}119511961197/* check for repeated labels on the same block */1198static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {1199int i;1200for (i = fs->bl->firstlabel; i < ll->n; i++) {1201if (luaS_eqstr(label, ll->arr[i].name)) {1202const char *msg = luaO_pushfstring(fs->ls->L,1203"label " LUA_QS " already defined on line %d",1204getstr(label), ll->arr[i].line);1205semerror(fs->ls, msg);1206}1207}1208}120912101211/* skip no-op statements */1212static void skipnoopstat (LexState *ls) {1213while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)1214statement(ls);1215}121612171218static void labelstat (LexState *ls, TString *label, int line) {1219/* label -> '::' NAME '::' */1220FuncState *fs = ls->fs;1221Labellist *ll = &ls->dyd->label;1222int l; /* index of new label being created */1223checkrepeated(fs, ll, label); /* check for repeated labels */1224checknext(ls, TK_DBCOLON); /* skip double colon */1225/* create new entry for this label */1226l = newlabelentry(ls, ll, label, line, fs->pc);1227skipnoopstat(ls); /* skip other no-op statements */1228if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */1229/* assume that locals are already out of scope */1230ll->arr[l].nactvar = fs->bl->nactvar;1231}1232findgotos(ls, &ll->arr[l]);1233}123412351236static void whilestat (LexState *ls, int line) {1237/* whilestat -> WHILE cond DO block END */1238FuncState *fs = ls->fs;1239int whileinit;1240int condexit;1241BlockCnt bl;1242luaX_next(ls); /* skip WHILE */1243whileinit = luaK_getlabel(fs);1244condexit = cond(ls);1245enterblock(fs, &bl, 1);1246checknext(ls, TK_DO);1247block(ls);1248luaK_jumpto(fs, whileinit);1249check_match(ls, TK_END, TK_WHILE, line);1250leaveblock(fs);1251luaK_patchtohere(fs, condexit); /* false conditions finish the loop */1252}125312541255static void repeatstat (LexState *ls, int line) {1256/* repeatstat -> REPEAT block UNTIL cond */1257int condexit;1258FuncState *fs = ls->fs;1259int repeat_init = luaK_getlabel(fs);1260BlockCnt bl1, bl2;1261enterblock(fs, &bl1, 1); /* loop block */1262enterblock(fs, &bl2, 0); /* scope block */1263luaX_next(ls); /* skip REPEAT */1264statlist(ls);1265check_match(ls, TK_UNTIL, TK_REPEAT, line);1266condexit = cond(ls); /* read condition (inside scope block) */1267if (bl2.upval) /* upvalues? */1268luaK_patchclose(fs, condexit, bl2.nactvar);1269leaveblock(fs); /* finish scope */1270luaK_patchlist(fs, condexit, repeat_init); /* close the loop */1271leaveblock(fs); /* finish loop */1272}127312741275static int exp1 (LexState *ls) {1276expdesc e;1277int reg;1278expr(ls, &e);1279luaK_exp2nextreg(ls->fs, &e);1280lua_assert(e.k == VNONRELOC);1281reg = e.u.info;1282return reg;1283}128412851286static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {1287/* forbody -> DO block */1288BlockCnt bl;1289FuncState *fs = ls->fs;1290int prep, endfor;1291adjustlocalvars(ls, 3); /* control variables */1292checknext(ls, TK_DO);1293prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);1294enterblock(fs, &bl, 0); /* scope for declared variables */1295adjustlocalvars(ls, nvars);1296luaK_reserveregs(fs, nvars);1297block(ls);1298leaveblock(fs); /* end of scope for declared variables */1299luaK_patchtohere(fs, prep);1300if (isnum) /* numeric for? */1301endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);1302else { /* generic for */1303luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);1304luaK_fixline(fs, line);1305endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);1306}1307luaK_patchlist(fs, endfor, prep + 1);1308luaK_fixline(fs, line);1309}131013111312static void fornum (LexState *ls, TString *varname, int line) {1313/* fornum -> NAME = exp1,exp1[,exp1] forbody */1314FuncState *fs = ls->fs;1315int base = fs->freereg;1316new_localvarliteral(ls, "(for index)");1317new_localvarliteral(ls, "(for limit)");1318new_localvarliteral(ls, "(for step)");1319new_localvar(ls, varname);1320checknext(ls, '=');1321exp1(ls); /* initial value */1322checknext(ls, ',');1323exp1(ls); /* limit */1324if (testnext(ls, ','))1325exp1(ls); /* optional step */1326else { /* default step = 1 */1327luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1));1328luaK_reserveregs(fs, 1);1329}1330forbody(ls, base, line, 1, 1);1331}133213331334static void forlist (LexState *ls, TString *indexname) {1335/* forlist -> NAME {,NAME} IN explist forbody */1336FuncState *fs = ls->fs;1337expdesc e;1338int nvars = 4; /* gen, state, control, plus at least one declared var */1339int line;1340int base = fs->freereg;1341/* create control variables */1342new_localvarliteral(ls, "(for generator)");1343new_localvarliteral(ls, "(for state)");1344new_localvarliteral(ls, "(for control)");1345/* create declared variables */1346new_localvar(ls, indexname);1347while (testnext(ls, ',')) {1348new_localvar(ls, str_checkname(ls));1349nvars++;1350}1351checknext(ls, TK_IN);1352line = ls->linenumber;1353adjust_assign(ls, 3, explist(ls, &e), &e);1354luaK_checkstack(fs, 3); /* extra space to call generator */1355forbody(ls, base, line, nvars - 3, 0);1356}135713581359static void forstat (LexState *ls, int line) {1360/* forstat -> FOR (fornum | forlist) END */1361FuncState *fs = ls->fs;1362TString *varname;1363BlockCnt bl;1364enterblock(fs, &bl, 1); /* scope for loop and control variables */1365luaX_next(ls); /* skip `for' */1366varname = str_checkname(ls); /* first variable name */1367switch (ls->t.token) {1368case '=': fornum(ls, varname, line); break;1369case ',': case TK_IN: forlist(ls, varname); break;1370default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");1371}1372check_match(ls, TK_END, TK_FOR, line);1373leaveblock(fs); /* loop scope (`break' jumps to this point) */1374}137513761377__attribute__((always_inline)) inline1378static void test_then_block (LexState *ls, int *escapelist) {1379/* test_then_block -> [IF | ELSEIF] cond THEN block */1380BlockCnt bl;1381FuncState *fs = ls->fs;1382expdesc v;1383int jf; /* instruction to skip 'then' code (if condition is false) */1384luaX_next(ls); /* skip IF or ELSEIF */1385expr(ls, &v); /* read condition */1386checknext(ls, TK_THEN);1387if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {1388luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */1389enterblock(fs, &bl, 0); /* must enter block before 'goto' */1390gotostat(ls, v.t); /* handle goto/break */1391skipnoopstat(ls); /* skip other no-op statements */1392if (block_follow(ls, 0)) { /* 'goto' is the entire block? */1393leaveblock(fs);1394return; /* and that is it */1395}1396else /* must skip over 'then' part if condition is false */1397jf = luaK_jump(fs);1398}1399else { /* regular case (not goto/break) */1400luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */1401enterblock(fs, &bl, 0);1402jf = v.f;1403}1404statlist(ls); /* `then' part */1405leaveblock(fs);1406if (ls->t.token == TK_ELSE ||1407ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */1408luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */1409luaK_patchtohere(fs, jf);1410}141114121413static void ifstat (LexState *ls, int line) {1414/* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */1415FuncState *fs = ls->fs;1416int escapelist = NO_JUMP; /* exit list for finished parts */1417test_then_block(ls, &escapelist); /* IF cond THEN block */1418while (ls->t.token == TK_ELSEIF)1419test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */1420if (testnext(ls, TK_ELSE))1421block(ls); /* `else' part */1422check_match(ls, TK_END, TK_IF, line);1423luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */1424}142514261427static void localfunc (LexState *ls) {1428expdesc b;1429FuncState *fs = ls->fs;1430new_localvar(ls, str_checkname(ls)); /* new local variable */1431adjustlocalvars(ls, 1); /* enter its scope */1432body(ls, &b, 0, ls->linenumber); /* function created in next register */1433/* debug information will only see the variable after this point! */1434getlocvar(fs, b.u.info)->startpc = fs->pc;1435}143614371438static void localstat (LexState *ls) {1439/* stat -> LOCAL NAME {`,' NAME} [`=' explist] */1440int nvars = 0;1441int nexps;1442expdesc e;1443do {1444new_localvar(ls, str_checkname(ls));1445nvars++;1446} while (testnext(ls, ','));1447if (testnext(ls, '='))1448nexps = explist(ls, &e);1449else {1450e.k = VVOID;1451nexps = 0;1452}1453adjust_assign(ls, nvars, nexps, &e);1454adjustlocalvars(ls, nvars);1455}145614571458static int funcname (LexState *ls, expdesc *v) {1459/* funcname -> NAME {fieldsel} [`:' NAME] */1460int ismethod = 0;1461singlevar(ls, v);1462while (ls->t.token == '.')1463fieldsel(ls, v);1464if (ls->t.token == ':') {1465ismethod = 1;1466fieldsel(ls, v);1467}1468return ismethod;1469}147014711472static void funcstat (LexState *ls, int line) {1473/* funcstat -> FUNCTION funcname body */1474int ismethod;1475expdesc v, b;1476luaX_next(ls); /* skip FUNCTION */1477ismethod = funcname(ls, &v);1478body(ls, &b, ismethod, line);1479luaK_storevar(ls->fs, &v, &b);1480luaK_fixline(ls->fs, line); /* definition `happens' in the first line */1481}148214831484static void exprstat (LexState *ls) {1485/* stat -> func | assignment */1486FuncState *fs = ls->fs;1487struct LHS_assign v;1488suffixedexp(ls, &v.v);1489if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */1490v.prev = NULL;1491assignment(ls, &v, 1);1492}1493else { /* stat -> func */1494check_condition(ls, v.v.k == VCALL, "syntax error");1495SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */1496}1497}149814991500static void retstat (LexState *ls) {1501/* stat -> RETURN [explist] [';'] */1502FuncState *fs = ls->fs;1503expdesc e;1504int first, nret; /* registers with returned values */1505if (block_follow(ls, 1) || ls->t.token == ';')1506first = nret = 0; /* return no values */1507else {1508nret = explist(ls, &e); /* optional return values */1509if (hasmultret(e.k)) {1510luaK_setmultret(fs, &e);1511if (e.k == VCALL && nret == 1) { /* tail call? */1512SET_OPCODE(getcode(fs,&e), OP_TAILCALL);1513lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);1514}1515first = fs->nactvar;1516nret = LUA_MULTRET; /* return all values */1517}1518else {1519if (nret == 1) /* only one single value? */1520first = luaK_exp2anyreg(fs, &e);1521else {1522luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */1523first = fs->nactvar; /* return all `active' values */1524lua_assert(nret == fs->freereg - first);1525}1526}1527}1528luaK_ret(fs, first, nret);1529(void) testnext(ls, ';'); /* skip optional semicolon */1530}153115321533static void statement (LexState *ls) {1534int line = ls->linenumber; /* may be needed for error messages */1535enterlevel(ls);1536switch (ls->t.token) {1537case ';': { /* stat -> ';' (empty statement) */1538luaX_next(ls); /* skip ';' */1539break;1540}1541case TK_IF: { /* stat -> ifstat */1542ifstat(ls, line);1543break;1544}1545case TK_WHILE: { /* stat -> whilestat */1546whilestat(ls, line);1547break;1548}1549case TK_DO: { /* stat -> DO block END */1550luaX_next(ls); /* skip DO */1551block(ls);1552check_match(ls, TK_END, TK_DO, line);1553break;1554}1555case TK_FOR: { /* stat -> forstat */1556forstat(ls, line);1557break;1558}1559case TK_REPEAT: { /* stat -> repeatstat */1560repeatstat(ls, line);1561break;1562}1563case TK_FUNCTION: { /* stat -> funcstat */1564funcstat(ls, line);1565break;1566}1567case TK_LOCAL: { /* stat -> localstat */1568luaX_next(ls); /* skip LOCAL */1569if (testnext(ls, TK_FUNCTION)) /* local function? */1570localfunc(ls);1571else1572localstat(ls);1573break;1574}1575case TK_DBCOLON: { /* stat -> label */1576luaX_next(ls); /* skip double colon */1577labelstat(ls, str_checkname(ls), line);1578break;1579}1580case TK_RETURN: { /* stat -> retstat */1581luaX_next(ls); /* skip RETURN */1582retstat(ls);1583break;1584}1585case TK_BREAK: /* stat -> breakstat */1586case TK_GOTO: { /* stat -> 'goto' NAME */1587gotostat(ls, luaK_jump(ls->fs));1588break;1589}1590default: { /* stat -> func | assignment */1591exprstat(ls);1592break;1593}1594}1595lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&1596ls->fs->freereg >= ls->fs->nactvar);1597ls->fs->freereg = ls->fs->nactvar; /* free registers */1598leavelevel(ls);1599}16001601/* }====================================================================== */160216031604/*1605** compiles the main function, which is a regular vararg function with an1606** upvalue named LUA_ENV1607*/1608static void mainfunc (LexState *ls, FuncState *fs) {1609BlockCnt bl;1610expdesc v;1611open_func(ls, fs, &bl);1612fs->f->is_vararg = 1; /* main function is always vararg */1613init_exp(&v, VLOCAL, 0); /* create and... */1614newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */1615luaX_next(ls); /* read first token */1616statlist(ls); /* parse main body */1617check(ls, TK_EOS);1618close_func(ls);1619}162016211622Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,1623Dyndata *dyd, const char *name, int firstchar) {1624LexState lexstate;1625FuncState funcstate;1626Closure *cl = luaF_newLclosure(L, 1); /* create main closure */1627/* anchor closure (to avoid being collected) */1628setclLvalue(L, L->top, cl);1629incr_top(L);1630funcstate.f = cl->l.p = luaF_newproto(L);1631funcstate.f->source = luaS_new(L, name); /* create and anchor TString */1632lexstate.buff = buff;1633lexstate.dyd = dyd;1634dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;1635luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);1636mainfunc(&lexstate, &funcstate);1637lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);1638/* all scopes should be correctly finished */1639lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);1640return cl; /* it's on the stack too */1641}164216431644