1280405Srpaulo/* 2344220Skevans** $Id: lparser.c,v 2.155.1.2 2017/04/29 18:11:40 roberto Exp $ 3280405Srpaulo** Lua Parser 4280405Srpaulo** See Copyright Notice in lua.h 5280405Srpaulo*/ 6280405Srpaulo 7280405Srpaulo#define lparser_c 8280405Srpaulo#define LUA_CORE 9280405Srpaulo 10280405Srpaulo#include "lprefix.h" 11280405Srpaulo 12280405Srpaulo 13280405Srpaulo#include <string.h> 14280405Srpaulo 15280405Srpaulo#include "lua.h" 16280405Srpaulo 17280405Srpaulo#include "lcode.h" 18280405Srpaulo#include "ldebug.h" 19280405Srpaulo#include "ldo.h" 20280405Srpaulo#include "lfunc.h" 21280405Srpaulo#include "llex.h" 22280405Srpaulo#include "lmem.h" 23280405Srpaulo#include "lobject.h" 24280405Srpaulo#include "lopcodes.h" 25280405Srpaulo#include "lparser.h" 26280405Srpaulo#include "lstate.h" 27280405Srpaulo#include "lstring.h" 28280405Srpaulo#include "ltable.h" 29280405Srpaulo 30280405Srpaulo 31280405Srpaulo 32280405Srpaulo/* maximum number of local variables per function (must be smaller 33280405Srpaulo than 250, due to the bytecode format) */ 34280405Srpaulo#define MAXVARS 200 35280405Srpaulo 36280405Srpaulo 37280405Srpaulo#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) 38280405Srpaulo 39280405Srpaulo 40280405Srpaulo/* because all strings are unified by the scanner, the parser 41280405Srpaulo can use pointer equality for string equality */ 42280405Srpaulo#define eqstr(a,b) ((a) == (b)) 43280405Srpaulo 44280405Srpaulo 45280405Srpaulo/* 46280405Srpaulo** nodes for block list (list of active blocks) 47280405Srpaulo*/ 48280405Srpaulotypedef struct BlockCnt { 49280405Srpaulo struct BlockCnt *previous; /* chain */ 50280405Srpaulo int firstlabel; /* index of first label in this block */ 51280405Srpaulo int firstgoto; /* index of first pending goto in this block */ 52280405Srpaulo lu_byte nactvar; /* # active locals outside the block */ 53280405Srpaulo lu_byte upval; /* true if some variable in the block is an upvalue */ 54280405Srpaulo lu_byte isloop; /* true if 'block' is a loop */ 55280405Srpaulo} BlockCnt; 56280405Srpaulo 57280405Srpaulo 58280405Srpaulo 59280405Srpaulo/* 60280405Srpaulo** prototypes for recursive non-terminal functions 61280405Srpaulo*/ 62280405Srpaulostatic void statement (LexState *ls); 63280405Srpaulostatic void expr (LexState *ls, expdesc *v); 64280405Srpaulo 65280405Srpaulo 66280405Srpaulo/* semantic error */ 67280405Srpaulostatic l_noret semerror (LexState *ls, const char *msg) { 68280405Srpaulo ls->t.token = 0; /* remove "near <token>" from final message */ 69280405Srpaulo luaX_syntaxerror(ls, msg); 70280405Srpaulo} 71280405Srpaulo 72280405Srpaulo 73280405Srpaulostatic l_noret error_expected (LexState *ls, int token) { 74280405Srpaulo luaX_syntaxerror(ls, 75280405Srpaulo luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); 76280405Srpaulo} 77280405Srpaulo 78280405Srpaulo 79280405Srpaulostatic l_noret errorlimit (FuncState *fs, int limit, const char *what) { 80280405Srpaulo lua_State *L = fs->ls->L; 81280405Srpaulo const char *msg; 82280405Srpaulo int line = fs->f->linedefined; 83280405Srpaulo const char *where = (line == 0) 84280405Srpaulo ? "main function" 85280405Srpaulo : luaO_pushfstring(L, "function at line %d", line); 86280405Srpaulo msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", 87280405Srpaulo what, limit, where); 88280405Srpaulo luaX_syntaxerror(fs->ls, msg); 89280405Srpaulo} 90280405Srpaulo 91280405Srpaulo 92280405Srpaulostatic void checklimit (FuncState *fs, int v, int l, const char *what) { 93280405Srpaulo if (v > l) errorlimit(fs, l, what); 94280405Srpaulo} 95280405Srpaulo 96280405Srpaulo 97280405Srpaulostatic int testnext (LexState *ls, int c) { 98280405Srpaulo if (ls->t.token == c) { 99280405Srpaulo luaX_next(ls); 100280405Srpaulo return 1; 101280405Srpaulo } 102280405Srpaulo else return 0; 103280405Srpaulo} 104280405Srpaulo 105280405Srpaulo 106280405Srpaulostatic void check (LexState *ls, int c) { 107280405Srpaulo if (ls->t.token != c) 108280405Srpaulo error_expected(ls, c); 109280405Srpaulo} 110280405Srpaulo 111280405Srpaulo 112280405Srpaulostatic void checknext (LexState *ls, int c) { 113280405Srpaulo check(ls, c); 114280405Srpaulo luaX_next(ls); 115280405Srpaulo} 116280405Srpaulo 117280405Srpaulo 118280405Srpaulo#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } 119280405Srpaulo 120280405Srpaulo 121280405Srpaulo 122280405Srpaulostatic void check_match (LexState *ls, int what, int who, int where) { 123280405Srpaulo if (!testnext(ls, what)) { 124280405Srpaulo if (where == ls->linenumber) 125280405Srpaulo error_expected(ls, what); 126280405Srpaulo else { 127280405Srpaulo luaX_syntaxerror(ls, luaO_pushfstring(ls->L, 128280405Srpaulo "%s expected (to close %s at line %d)", 129280405Srpaulo luaX_token2str(ls, what), luaX_token2str(ls, who), where)); 130280405Srpaulo } 131280405Srpaulo } 132280405Srpaulo} 133280405Srpaulo 134280405Srpaulo 135280405Srpaulostatic TString *str_checkname (LexState *ls) { 136280405Srpaulo TString *ts; 137280405Srpaulo check(ls, TK_NAME); 138280405Srpaulo ts = ls->t.seminfo.ts; 139280405Srpaulo luaX_next(ls); 140280405Srpaulo return ts; 141280405Srpaulo} 142280405Srpaulo 143280405Srpaulo 144280405Srpaulostatic void init_exp (expdesc *e, expkind k, int i) { 145280405Srpaulo e->f = e->t = NO_JUMP; 146280405Srpaulo e->k = k; 147280405Srpaulo e->u.info = i; 148280405Srpaulo} 149280405Srpaulo 150280405Srpaulo 151280405Srpaulostatic void codestring (LexState *ls, expdesc *e, TString *s) { 152280405Srpaulo init_exp(e, VK, luaK_stringK(ls->fs, s)); 153280405Srpaulo} 154280405Srpaulo 155280405Srpaulo 156280405Srpaulostatic void checkname (LexState *ls, expdesc *e) { 157280405Srpaulo codestring(ls, e, str_checkname(ls)); 158280405Srpaulo} 159280405Srpaulo 160280405Srpaulo 161280405Srpaulostatic int registerlocalvar (LexState *ls, TString *varname) { 162280405Srpaulo FuncState *fs = ls->fs; 163280405Srpaulo Proto *f = fs->f; 164280405Srpaulo int oldsize = f->sizelocvars; 165280405Srpaulo luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, 166280405Srpaulo LocVar, SHRT_MAX, "local variables"); 167326344Simp while (oldsize < f->sizelocvars) 168326344Simp f->locvars[oldsize++].varname = NULL; 169280405Srpaulo f->locvars[fs->nlocvars].varname = varname; 170280405Srpaulo luaC_objbarrier(ls->L, f, varname); 171280405Srpaulo return fs->nlocvars++; 172280405Srpaulo} 173280405Srpaulo 174280405Srpaulo 175280405Srpaulostatic void new_localvar (LexState *ls, TString *name) { 176280405Srpaulo FuncState *fs = ls->fs; 177280405Srpaulo Dyndata *dyd = ls->dyd; 178280405Srpaulo int reg = registerlocalvar(ls, name); 179280405Srpaulo checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, 180280405Srpaulo MAXVARS, "local variables"); 181280405Srpaulo luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, 182280405Srpaulo dyd->actvar.size, Vardesc, MAX_INT, "local variables"); 183280405Srpaulo dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); 184280405Srpaulo} 185280405Srpaulo 186280405Srpaulo 187280405Srpaulostatic void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { 188280405Srpaulo new_localvar(ls, luaX_newstring(ls, name, sz)); 189280405Srpaulo} 190280405Srpaulo 191280405Srpaulo#define new_localvarliteral(ls,v) \ 192280405Srpaulo new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) 193280405Srpaulo 194280405Srpaulo 195280405Srpaulostatic LocVar *getlocvar (FuncState *fs, int i) { 196280405Srpaulo int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; 197280405Srpaulo lua_assert(idx < fs->nlocvars); 198280405Srpaulo return &fs->f->locvars[idx]; 199280405Srpaulo} 200280405Srpaulo 201280405Srpaulo 202280405Srpaulostatic void adjustlocalvars (LexState *ls, int nvars) { 203280405Srpaulo FuncState *fs = ls->fs; 204280405Srpaulo fs->nactvar = cast_byte(fs->nactvar + nvars); 205280405Srpaulo for (; nvars; nvars--) { 206280405Srpaulo getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; 207280405Srpaulo } 208280405Srpaulo} 209280405Srpaulo 210280405Srpaulo 211280405Srpaulostatic void removevars (FuncState *fs, int tolevel) { 212280405Srpaulo fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); 213280405Srpaulo while (fs->nactvar > tolevel) 214280405Srpaulo getlocvar(fs, --fs->nactvar)->endpc = fs->pc; 215280405Srpaulo} 216280405Srpaulo 217280405Srpaulo 218280405Srpaulostatic int searchupvalue (FuncState *fs, TString *name) { 219280405Srpaulo int i; 220280405Srpaulo Upvaldesc *up = fs->f->upvalues; 221280405Srpaulo for (i = 0; i < fs->nups; i++) { 222280405Srpaulo if (eqstr(up[i].name, name)) return i; 223280405Srpaulo } 224280405Srpaulo return -1; /* not found */ 225280405Srpaulo} 226280405Srpaulo 227280405Srpaulo 228280405Srpaulostatic int newupvalue (FuncState *fs, TString *name, expdesc *v) { 229280405Srpaulo Proto *f = fs->f; 230280405Srpaulo int oldsize = f->sizeupvalues; 231280405Srpaulo checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); 232280405Srpaulo luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, 233280405Srpaulo Upvaldesc, MAXUPVAL, "upvalues"); 234326344Simp while (oldsize < f->sizeupvalues) 235326344Simp f->upvalues[oldsize++].name = NULL; 236280405Srpaulo f->upvalues[fs->nups].instack = (v->k == VLOCAL); 237280405Srpaulo f->upvalues[fs->nups].idx = cast_byte(v->u.info); 238280405Srpaulo f->upvalues[fs->nups].name = name; 239280405Srpaulo luaC_objbarrier(fs->ls->L, f, name); 240280405Srpaulo return fs->nups++; 241280405Srpaulo} 242280405Srpaulo 243280405Srpaulo 244280405Srpaulostatic int searchvar (FuncState *fs, TString *n) { 245280405Srpaulo int i; 246280405Srpaulo for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { 247280405Srpaulo if (eqstr(n, getlocvar(fs, i)->varname)) 248280405Srpaulo return i; 249280405Srpaulo } 250280405Srpaulo return -1; /* not found */ 251280405Srpaulo} 252280405Srpaulo 253280405Srpaulo 254280405Srpaulo/* 255280405Srpaulo Mark block where variable at given level was defined 256280405Srpaulo (to emit close instructions later). 257280405Srpaulo*/ 258280405Srpaulostatic void markupval (FuncState *fs, int level) { 259280405Srpaulo BlockCnt *bl = fs->bl; 260326344Simp while (bl->nactvar > level) 261326344Simp bl = bl->previous; 262280405Srpaulo bl->upval = 1; 263280405Srpaulo} 264280405Srpaulo 265280405Srpaulo 266280405Srpaulo/* 267280405Srpaulo Find variable with given name 'n'. If it is an upvalue, add this 268280405Srpaulo upvalue into all intermediate functions. 269280405Srpaulo*/ 270326344Simpstatic void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { 271280405Srpaulo if (fs == NULL) /* no more levels? */ 272326344Simp init_exp(var, VVOID, 0); /* default is global */ 273280405Srpaulo else { 274280405Srpaulo int v = searchvar(fs, n); /* look up locals at current level */ 275280405Srpaulo if (v >= 0) { /* found? */ 276280405Srpaulo init_exp(var, VLOCAL, v); /* variable is local */ 277280405Srpaulo if (!base) 278280405Srpaulo markupval(fs, v); /* local will be used as an upval */ 279280405Srpaulo } 280280405Srpaulo else { /* not found as local at current level; try upvalues */ 281280405Srpaulo int idx = searchupvalue(fs, n); /* try existing upvalues */ 282280405Srpaulo if (idx < 0) { /* not found? */ 283326344Simp singlevaraux(fs->prev, n, var, 0); /* try upper levels */ 284326344Simp if (var->k == VVOID) /* not found? */ 285326344Simp return; /* it is a global */ 286280405Srpaulo /* else was LOCAL or UPVAL */ 287280405Srpaulo idx = newupvalue(fs, n, var); /* will be a new upvalue */ 288280405Srpaulo } 289326344Simp init_exp(var, VUPVAL, idx); /* new or old upvalue */ 290280405Srpaulo } 291280405Srpaulo } 292280405Srpaulo} 293280405Srpaulo 294280405Srpaulo 295280405Srpaulostatic void singlevar (LexState *ls, expdesc *var) { 296280405Srpaulo TString *varname = str_checkname(ls); 297280405Srpaulo FuncState *fs = ls->fs; 298326344Simp singlevaraux(fs, varname, var, 1); 299326344Simp if (var->k == VVOID) { /* global name? */ 300280405Srpaulo expdesc key; 301280405Srpaulo singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ 302326344Simp lua_assert(var->k != VVOID); /* this one must exist */ 303280405Srpaulo codestring(ls, &key, varname); /* key is variable name */ 304280405Srpaulo luaK_indexed(fs, var, &key); /* env[varname] */ 305280405Srpaulo } 306280405Srpaulo} 307280405Srpaulo 308280405Srpaulo 309280405Srpaulostatic void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { 310280405Srpaulo FuncState *fs = ls->fs; 311280405Srpaulo int extra = nvars - nexps; 312280405Srpaulo if (hasmultret(e->k)) { 313280405Srpaulo extra++; /* includes call itself */ 314280405Srpaulo if (extra < 0) extra = 0; 315280405Srpaulo luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ 316280405Srpaulo if (extra > 1) luaK_reserveregs(fs, extra-1); 317280405Srpaulo } 318280405Srpaulo else { 319280405Srpaulo if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ 320280405Srpaulo if (extra > 0) { 321280405Srpaulo int reg = fs->freereg; 322280405Srpaulo luaK_reserveregs(fs, extra); 323280405Srpaulo luaK_nil(fs, reg, extra); 324280405Srpaulo } 325280405Srpaulo } 326326344Simp if (nexps > nvars) 327326344Simp ls->fs->freereg -= nexps - nvars; /* remove extra values */ 328280405Srpaulo} 329280405Srpaulo 330280405Srpaulo 331280405Srpaulostatic void enterlevel (LexState *ls) { 332280405Srpaulo lua_State *L = ls->L; 333280405Srpaulo ++L->nCcalls; 334280405Srpaulo checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); 335280405Srpaulo} 336280405Srpaulo 337280405Srpaulo 338280405Srpaulo#define leavelevel(ls) ((ls)->L->nCcalls--) 339280405Srpaulo 340280405Srpaulo 341280405Srpaulostatic void closegoto (LexState *ls, int g, Labeldesc *label) { 342280405Srpaulo int i; 343280405Srpaulo FuncState *fs = ls->fs; 344280405Srpaulo Labellist *gl = &ls->dyd->gt; 345280405Srpaulo Labeldesc *gt = &gl->arr[g]; 346280405Srpaulo lua_assert(eqstr(gt->name, label->name)); 347280405Srpaulo if (gt->nactvar < label->nactvar) { 348280405Srpaulo TString *vname = getlocvar(fs, gt->nactvar)->varname; 349280405Srpaulo const char *msg = luaO_pushfstring(ls->L, 350280405Srpaulo "<goto %s> at line %d jumps into the scope of local '%s'", 351280405Srpaulo getstr(gt->name), gt->line, getstr(vname)); 352280405Srpaulo semerror(ls, msg); 353280405Srpaulo } 354280405Srpaulo luaK_patchlist(fs, gt->pc, label->pc); 355280405Srpaulo /* remove goto from pending list */ 356280405Srpaulo for (i = g; i < gl->n - 1; i++) 357280405Srpaulo gl->arr[i] = gl->arr[i + 1]; 358280405Srpaulo gl->n--; 359280405Srpaulo} 360280405Srpaulo 361280405Srpaulo 362280405Srpaulo/* 363280405Srpaulo** try to close a goto with existing labels; this solves backward jumps 364280405Srpaulo*/ 365280405Srpaulostatic int findlabel (LexState *ls, int g) { 366280405Srpaulo int i; 367280405Srpaulo BlockCnt *bl = ls->fs->bl; 368280405Srpaulo Dyndata *dyd = ls->dyd; 369280405Srpaulo Labeldesc *gt = &dyd->gt.arr[g]; 370280405Srpaulo /* check labels in current block for a match */ 371280405Srpaulo for (i = bl->firstlabel; i < dyd->label.n; i++) { 372280405Srpaulo Labeldesc *lb = &dyd->label.arr[i]; 373280405Srpaulo if (eqstr(lb->name, gt->name)) { /* correct label? */ 374280405Srpaulo if (gt->nactvar > lb->nactvar && 375280405Srpaulo (bl->upval || dyd->label.n > bl->firstlabel)) 376280405Srpaulo luaK_patchclose(ls->fs, gt->pc, lb->nactvar); 377280405Srpaulo closegoto(ls, g, lb); /* close it */ 378280405Srpaulo return 1; 379280405Srpaulo } 380280405Srpaulo } 381280405Srpaulo return 0; /* label not found; cannot close goto */ 382280405Srpaulo} 383280405Srpaulo 384280405Srpaulo 385280405Srpaulostatic int newlabelentry (LexState *ls, Labellist *l, TString *name, 386280405Srpaulo int line, int pc) { 387280405Srpaulo int n = l->n; 388280405Srpaulo luaM_growvector(ls->L, l->arr, n, l->size, 389280405Srpaulo Labeldesc, SHRT_MAX, "labels/gotos"); 390280405Srpaulo l->arr[n].name = name; 391280405Srpaulo l->arr[n].line = line; 392280405Srpaulo l->arr[n].nactvar = ls->fs->nactvar; 393280405Srpaulo l->arr[n].pc = pc; 394280405Srpaulo l->n = n + 1; 395280405Srpaulo return n; 396280405Srpaulo} 397280405Srpaulo 398280405Srpaulo 399280405Srpaulo/* 400280405Srpaulo** check whether new label 'lb' matches any pending gotos in current 401280405Srpaulo** block; solves forward jumps 402280405Srpaulo*/ 403280405Srpaulostatic void findgotos (LexState *ls, Labeldesc *lb) { 404280405Srpaulo Labellist *gl = &ls->dyd->gt; 405280405Srpaulo int i = ls->fs->bl->firstgoto; 406280405Srpaulo while (i < gl->n) { 407280405Srpaulo if (eqstr(gl->arr[i].name, lb->name)) 408280405Srpaulo closegoto(ls, i, lb); 409280405Srpaulo else 410280405Srpaulo i++; 411280405Srpaulo } 412280405Srpaulo} 413280405Srpaulo 414280405Srpaulo 415280405Srpaulo/* 416280405Srpaulo** export pending gotos to outer level, to check them against 417280405Srpaulo** outer labels; if the block being exited has upvalues, and 418280405Srpaulo** the goto exits the scope of any variable (which can be the 419280405Srpaulo** upvalue), close those variables being exited. 420280405Srpaulo*/ 421280405Srpaulostatic void movegotosout (FuncState *fs, BlockCnt *bl) { 422280405Srpaulo int i = bl->firstgoto; 423280405Srpaulo Labellist *gl = &fs->ls->dyd->gt; 424280405Srpaulo /* correct pending gotos to current block and try to close it 425280405Srpaulo with visible labels */ 426280405Srpaulo while (i < gl->n) { 427280405Srpaulo Labeldesc *gt = &gl->arr[i]; 428280405Srpaulo if (gt->nactvar > bl->nactvar) { 429280405Srpaulo if (bl->upval) 430280405Srpaulo luaK_patchclose(fs, gt->pc, bl->nactvar); 431280405Srpaulo gt->nactvar = bl->nactvar; 432280405Srpaulo } 433280405Srpaulo if (!findlabel(fs->ls, i)) 434280405Srpaulo i++; /* move to next one */ 435280405Srpaulo } 436280405Srpaulo} 437280405Srpaulo 438280405Srpaulo 439280405Srpaulostatic void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { 440280405Srpaulo bl->isloop = isloop; 441280405Srpaulo bl->nactvar = fs->nactvar; 442280405Srpaulo bl->firstlabel = fs->ls->dyd->label.n; 443280405Srpaulo bl->firstgoto = fs->ls->dyd->gt.n; 444280405Srpaulo bl->upval = 0; 445280405Srpaulo bl->previous = fs->bl; 446280405Srpaulo fs->bl = bl; 447280405Srpaulo lua_assert(fs->freereg == fs->nactvar); 448280405Srpaulo} 449280405Srpaulo 450280405Srpaulo 451280405Srpaulo/* 452280405Srpaulo** create a label named 'break' to resolve break statements 453280405Srpaulo*/ 454280405Srpaulostatic void breaklabel (LexState *ls) { 455280405Srpaulo TString *n = luaS_new(ls->L, "break"); 456280405Srpaulo int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); 457280405Srpaulo findgotos(ls, &ls->dyd->label.arr[l]); 458280405Srpaulo} 459280405Srpaulo 460280405Srpaulo/* 461280405Srpaulo** generates an error for an undefined 'goto'; choose appropriate 462280405Srpaulo** message when label name is a reserved word (which can only be 'break') 463280405Srpaulo*/ 464280405Srpaulostatic l_noret undefgoto (LexState *ls, Labeldesc *gt) { 465280405Srpaulo const char *msg = isreserved(gt->name) 466280405Srpaulo ? "<%s> at line %d not inside a loop" 467280405Srpaulo : "no visible label '%s' for <goto> at line %d"; 468280405Srpaulo msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); 469280405Srpaulo semerror(ls, msg); 470280405Srpaulo} 471280405Srpaulo 472280405Srpaulo 473280405Srpaulostatic void leaveblock (FuncState *fs) { 474280405Srpaulo BlockCnt *bl = fs->bl; 475280405Srpaulo LexState *ls = fs->ls; 476280405Srpaulo if (bl->previous && bl->upval) { 477280405Srpaulo /* create a 'jump to here' to close upvalues */ 478280405Srpaulo int j = luaK_jump(fs); 479280405Srpaulo luaK_patchclose(fs, j, bl->nactvar); 480280405Srpaulo luaK_patchtohere(fs, j); 481280405Srpaulo } 482280405Srpaulo if (bl->isloop) 483280405Srpaulo breaklabel(ls); /* close pending breaks */ 484280405Srpaulo fs->bl = bl->previous; 485280405Srpaulo removevars(fs, bl->nactvar); 486280405Srpaulo lua_assert(bl->nactvar == fs->nactvar); 487280405Srpaulo fs->freereg = fs->nactvar; /* free registers */ 488280405Srpaulo ls->dyd->label.n = bl->firstlabel; /* remove local labels */ 489280405Srpaulo if (bl->previous) /* inner block? */ 490280405Srpaulo movegotosout(fs, bl); /* update pending gotos to outer block */ 491280405Srpaulo else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ 492280405Srpaulo undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ 493280405Srpaulo} 494280405Srpaulo 495280405Srpaulo 496280405Srpaulo/* 497280405Srpaulo** adds a new prototype into list of prototypes 498280405Srpaulo*/ 499280405Srpaulostatic Proto *addprototype (LexState *ls) { 500280405Srpaulo Proto *clp; 501280405Srpaulo lua_State *L = ls->L; 502280405Srpaulo FuncState *fs = ls->fs; 503280405Srpaulo Proto *f = fs->f; /* prototype of current function */ 504280405Srpaulo if (fs->np >= f->sizep) { 505280405Srpaulo int oldsize = f->sizep; 506280405Srpaulo luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); 507326344Simp while (oldsize < f->sizep) 508326344Simp f->p[oldsize++] = NULL; 509280405Srpaulo } 510280405Srpaulo f->p[fs->np++] = clp = luaF_newproto(L); 511280405Srpaulo luaC_objbarrier(L, f, clp); 512280405Srpaulo return clp; 513280405Srpaulo} 514280405Srpaulo 515280405Srpaulo 516280405Srpaulo/* 517280405Srpaulo** codes instruction to create new closure in parent function. 518280405Srpaulo** The OP_CLOSURE instruction must use the last available register, 519280405Srpaulo** so that, if it invokes the GC, the GC knows which registers 520280405Srpaulo** are in use at that time. 521280405Srpaulo*/ 522280405Srpaulostatic void codeclosure (LexState *ls, expdesc *v) { 523280405Srpaulo FuncState *fs = ls->fs->prev; 524280405Srpaulo init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); 525280405Srpaulo luaK_exp2nextreg(fs, v); /* fix it at the last register */ 526280405Srpaulo} 527280405Srpaulo 528280405Srpaulo 529280405Srpaulostatic void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { 530280405Srpaulo Proto *f; 531280405Srpaulo fs->prev = ls->fs; /* linked list of funcstates */ 532280405Srpaulo fs->ls = ls; 533280405Srpaulo ls->fs = fs; 534280405Srpaulo fs->pc = 0; 535280405Srpaulo fs->lasttarget = 0; 536280405Srpaulo fs->jpc = NO_JUMP; 537280405Srpaulo fs->freereg = 0; 538280405Srpaulo fs->nk = 0; 539280405Srpaulo fs->np = 0; 540280405Srpaulo fs->nups = 0; 541280405Srpaulo fs->nlocvars = 0; 542280405Srpaulo fs->nactvar = 0; 543280405Srpaulo fs->firstlocal = ls->dyd->actvar.n; 544280405Srpaulo fs->bl = NULL; 545280405Srpaulo f = fs->f; 546280405Srpaulo f->source = ls->source; 547280405Srpaulo f->maxstacksize = 2; /* registers 0/1 are always valid */ 548280405Srpaulo enterblock(fs, bl, 0); 549280405Srpaulo} 550280405Srpaulo 551280405Srpaulo 552280405Srpaulostatic void close_func (LexState *ls) { 553280405Srpaulo lua_State *L = ls->L; 554280405Srpaulo FuncState *fs = ls->fs; 555280405Srpaulo Proto *f = fs->f; 556280405Srpaulo luaK_ret(fs, 0, 0); /* final return */ 557280405Srpaulo leaveblock(fs); 558280405Srpaulo luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); 559280405Srpaulo f->sizecode = fs->pc; 560280405Srpaulo luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); 561280405Srpaulo f->sizelineinfo = fs->pc; 562280405Srpaulo luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); 563280405Srpaulo f->sizek = fs->nk; 564280405Srpaulo luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); 565280405Srpaulo f->sizep = fs->np; 566280405Srpaulo luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); 567280405Srpaulo f->sizelocvars = fs->nlocvars; 568280405Srpaulo luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); 569280405Srpaulo f->sizeupvalues = fs->nups; 570280405Srpaulo lua_assert(fs->bl == NULL); 571280405Srpaulo ls->fs = fs->prev; 572280405Srpaulo luaC_checkGC(L); 573280405Srpaulo} 574280405Srpaulo 575280405Srpaulo 576280405Srpaulo 577280405Srpaulo/*============================================================*/ 578280405Srpaulo/* GRAMMAR RULES */ 579280405Srpaulo/*============================================================*/ 580280405Srpaulo 581280405Srpaulo 582280405Srpaulo/* 583280405Srpaulo** check whether current token is in the follow set of a block. 584280405Srpaulo** 'until' closes syntactical blocks, but do not close scope, 585280405Srpaulo** so it is handled in separate. 586280405Srpaulo*/ 587280405Srpaulostatic int block_follow (LexState *ls, int withuntil) { 588280405Srpaulo switch (ls->t.token) { 589280405Srpaulo case TK_ELSE: case TK_ELSEIF: 590280405Srpaulo case TK_END: case TK_EOS: 591280405Srpaulo return 1; 592280405Srpaulo case TK_UNTIL: return withuntil; 593280405Srpaulo default: return 0; 594280405Srpaulo } 595280405Srpaulo} 596280405Srpaulo 597280405Srpaulo 598280405Srpaulostatic void statlist (LexState *ls) { 599280405Srpaulo /* statlist -> { stat [';'] } */ 600280405Srpaulo while (!block_follow(ls, 1)) { 601280405Srpaulo if (ls->t.token == TK_RETURN) { 602280405Srpaulo statement(ls); 603280405Srpaulo return; /* 'return' must be last statement */ 604280405Srpaulo } 605280405Srpaulo statement(ls); 606280405Srpaulo } 607280405Srpaulo} 608280405Srpaulo 609280405Srpaulo 610280405Srpaulostatic void fieldsel (LexState *ls, expdesc *v) { 611280405Srpaulo /* fieldsel -> ['.' | ':'] NAME */ 612280405Srpaulo FuncState *fs = ls->fs; 613280405Srpaulo expdesc key; 614280405Srpaulo luaK_exp2anyregup(fs, v); 615280405Srpaulo luaX_next(ls); /* skip the dot or colon */ 616280405Srpaulo checkname(ls, &key); 617280405Srpaulo luaK_indexed(fs, v, &key); 618280405Srpaulo} 619280405Srpaulo 620280405Srpaulo 621280405Srpaulostatic void yindex (LexState *ls, expdesc *v) { 622280405Srpaulo /* index -> '[' expr ']' */ 623280405Srpaulo luaX_next(ls); /* skip the '[' */ 624280405Srpaulo expr(ls, v); 625280405Srpaulo luaK_exp2val(ls->fs, v); 626280405Srpaulo checknext(ls, ']'); 627280405Srpaulo} 628280405Srpaulo 629280405Srpaulo 630280405Srpaulo/* 631280405Srpaulo** {====================================================================== 632280405Srpaulo** Rules for Constructors 633280405Srpaulo** ======================================================================= 634280405Srpaulo*/ 635280405Srpaulo 636280405Srpaulo 637280405Srpaulostruct ConsControl { 638280405Srpaulo expdesc v; /* last list item read */ 639280405Srpaulo expdesc *t; /* table descriptor */ 640280405Srpaulo int nh; /* total number of 'record' elements */ 641280405Srpaulo int na; /* total number of array elements */ 642280405Srpaulo int tostore; /* number of array elements pending to be stored */ 643280405Srpaulo}; 644280405Srpaulo 645280405Srpaulo 646280405Srpaulostatic void recfield (LexState *ls, struct ConsControl *cc) { 647280405Srpaulo /* recfield -> (NAME | '['exp1']') = exp1 */ 648280405Srpaulo FuncState *fs = ls->fs; 649280405Srpaulo int reg = ls->fs->freereg; 650280405Srpaulo expdesc key, val; 651280405Srpaulo int rkkey; 652280405Srpaulo if (ls->t.token == TK_NAME) { 653280405Srpaulo checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); 654280405Srpaulo checkname(ls, &key); 655280405Srpaulo } 656280405Srpaulo else /* ls->t.token == '[' */ 657280405Srpaulo yindex(ls, &key); 658280405Srpaulo cc->nh++; 659280405Srpaulo checknext(ls, '='); 660280405Srpaulo rkkey = luaK_exp2RK(fs, &key); 661280405Srpaulo expr(ls, &val); 662280405Srpaulo luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); 663280405Srpaulo fs->freereg = reg; /* free registers */ 664280405Srpaulo} 665280405Srpaulo 666280405Srpaulo 667280405Srpaulostatic void closelistfield (FuncState *fs, struct ConsControl *cc) { 668280405Srpaulo if (cc->v.k == VVOID) return; /* there is no list item */ 669280405Srpaulo luaK_exp2nextreg(fs, &cc->v); 670280405Srpaulo cc->v.k = VVOID; 671280405Srpaulo if (cc->tostore == LFIELDS_PER_FLUSH) { 672280405Srpaulo luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ 673280405Srpaulo cc->tostore = 0; /* no more items pending */ 674280405Srpaulo } 675280405Srpaulo} 676280405Srpaulo 677280405Srpaulo 678280405Srpaulostatic void lastlistfield (FuncState *fs, struct ConsControl *cc) { 679280405Srpaulo if (cc->tostore == 0) return; 680280405Srpaulo if (hasmultret(cc->v.k)) { 681280405Srpaulo luaK_setmultret(fs, &cc->v); 682280405Srpaulo luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); 683280405Srpaulo cc->na--; /* do not count last expression (unknown number of elements) */ 684280405Srpaulo } 685280405Srpaulo else { 686280405Srpaulo if (cc->v.k != VVOID) 687280405Srpaulo luaK_exp2nextreg(fs, &cc->v); 688280405Srpaulo luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); 689280405Srpaulo } 690280405Srpaulo} 691280405Srpaulo 692280405Srpaulo 693280405Srpaulostatic void listfield (LexState *ls, struct ConsControl *cc) { 694280405Srpaulo /* listfield -> exp */ 695280405Srpaulo expr(ls, &cc->v); 696280405Srpaulo checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); 697280405Srpaulo cc->na++; 698280405Srpaulo cc->tostore++; 699280405Srpaulo} 700280405Srpaulo 701280405Srpaulo 702280405Srpaulostatic void field (LexState *ls, struct ConsControl *cc) { 703280405Srpaulo /* field -> listfield | recfield */ 704280405Srpaulo switch(ls->t.token) { 705280405Srpaulo case TK_NAME: { /* may be 'listfield' or 'recfield' */ 706280405Srpaulo if (luaX_lookahead(ls) != '=') /* expression? */ 707280405Srpaulo listfield(ls, cc); 708280405Srpaulo else 709280405Srpaulo recfield(ls, cc); 710280405Srpaulo break; 711280405Srpaulo } 712280405Srpaulo case '[': { 713280405Srpaulo recfield(ls, cc); 714280405Srpaulo break; 715280405Srpaulo } 716280405Srpaulo default: { 717280405Srpaulo listfield(ls, cc); 718280405Srpaulo break; 719280405Srpaulo } 720280405Srpaulo } 721280405Srpaulo} 722280405Srpaulo 723280405Srpaulo 724280405Srpaulostatic void constructor (LexState *ls, expdesc *t) { 725280405Srpaulo /* constructor -> '{' [ field { sep field } [sep] ] '}' 726280405Srpaulo sep -> ',' | ';' */ 727280405Srpaulo FuncState *fs = ls->fs; 728280405Srpaulo int line = ls->linenumber; 729280405Srpaulo int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); 730280405Srpaulo struct ConsControl cc; 731280405Srpaulo cc.na = cc.nh = cc.tostore = 0; 732280405Srpaulo cc.t = t; 733280405Srpaulo init_exp(t, VRELOCABLE, pc); 734280405Srpaulo init_exp(&cc.v, VVOID, 0); /* no value (yet) */ 735280405Srpaulo luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ 736280405Srpaulo checknext(ls, '{'); 737280405Srpaulo do { 738280405Srpaulo lua_assert(cc.v.k == VVOID || cc.tostore > 0); 739280405Srpaulo if (ls->t.token == '}') break; 740280405Srpaulo closelistfield(fs, &cc); 741280405Srpaulo field(ls, &cc); 742280405Srpaulo } while (testnext(ls, ',') || testnext(ls, ';')); 743280405Srpaulo check_match(ls, '}', '{', line); 744280405Srpaulo lastlistfield(fs, &cc); 745280405Srpaulo SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ 746280405Srpaulo SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ 747280405Srpaulo} 748280405Srpaulo 749280405Srpaulo/* }====================================================================== */ 750280405Srpaulo 751280405Srpaulo 752280405Srpaulo 753280405Srpaulostatic void parlist (LexState *ls) { 754280405Srpaulo /* parlist -> [ param { ',' param } ] */ 755280405Srpaulo FuncState *fs = ls->fs; 756280405Srpaulo Proto *f = fs->f; 757280405Srpaulo int nparams = 0; 758280405Srpaulo f->is_vararg = 0; 759280405Srpaulo if (ls->t.token != ')') { /* is 'parlist' not empty? */ 760280405Srpaulo do { 761280405Srpaulo switch (ls->t.token) { 762280405Srpaulo case TK_NAME: { /* param -> NAME */ 763280405Srpaulo new_localvar(ls, str_checkname(ls)); 764280405Srpaulo nparams++; 765280405Srpaulo break; 766280405Srpaulo } 767280405Srpaulo case TK_DOTS: { /* param -> '...' */ 768280405Srpaulo luaX_next(ls); 769326344Simp f->is_vararg = 1; /* declared vararg */ 770280405Srpaulo break; 771280405Srpaulo } 772280405Srpaulo default: luaX_syntaxerror(ls, "<name> or '...' expected"); 773280405Srpaulo } 774280405Srpaulo } while (!f->is_vararg && testnext(ls, ',')); 775280405Srpaulo } 776280405Srpaulo adjustlocalvars(ls, nparams); 777280405Srpaulo f->numparams = cast_byte(fs->nactvar); 778280405Srpaulo luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ 779280405Srpaulo} 780280405Srpaulo 781280405Srpaulo 782280405Srpaulostatic void body (LexState *ls, expdesc *e, int ismethod, int line) { 783280405Srpaulo /* body -> '(' parlist ')' block END */ 784280405Srpaulo FuncState new_fs; 785280405Srpaulo BlockCnt bl; 786280405Srpaulo new_fs.f = addprototype(ls); 787280405Srpaulo new_fs.f->linedefined = line; 788280405Srpaulo open_func(ls, &new_fs, &bl); 789280405Srpaulo checknext(ls, '('); 790280405Srpaulo if (ismethod) { 791280405Srpaulo new_localvarliteral(ls, "self"); /* create 'self' parameter */ 792280405Srpaulo adjustlocalvars(ls, 1); 793280405Srpaulo } 794280405Srpaulo parlist(ls); 795280405Srpaulo checknext(ls, ')'); 796280405Srpaulo statlist(ls); 797280405Srpaulo new_fs.f->lastlinedefined = ls->linenumber; 798280405Srpaulo check_match(ls, TK_END, TK_FUNCTION, line); 799280405Srpaulo codeclosure(ls, e); 800280405Srpaulo close_func(ls); 801280405Srpaulo} 802280405Srpaulo 803280405Srpaulo 804280405Srpaulostatic int explist (LexState *ls, expdesc *v) { 805280405Srpaulo /* explist -> expr { ',' expr } */ 806280405Srpaulo int n = 1; /* at least one expression */ 807280405Srpaulo expr(ls, v); 808280405Srpaulo while (testnext(ls, ',')) { 809280405Srpaulo luaK_exp2nextreg(ls->fs, v); 810280405Srpaulo expr(ls, v); 811280405Srpaulo n++; 812280405Srpaulo } 813280405Srpaulo return n; 814280405Srpaulo} 815280405Srpaulo 816280405Srpaulo 817280405Srpaulostatic void funcargs (LexState *ls, expdesc *f, int line) { 818280405Srpaulo FuncState *fs = ls->fs; 819280405Srpaulo expdesc args; 820280405Srpaulo int base, nparams; 821280405Srpaulo switch (ls->t.token) { 822280405Srpaulo case '(': { /* funcargs -> '(' [ explist ] ')' */ 823280405Srpaulo luaX_next(ls); 824280405Srpaulo if (ls->t.token == ')') /* arg list is empty? */ 825280405Srpaulo args.k = VVOID; 826280405Srpaulo else { 827280405Srpaulo explist(ls, &args); 828280405Srpaulo luaK_setmultret(fs, &args); 829280405Srpaulo } 830280405Srpaulo check_match(ls, ')', '(', line); 831280405Srpaulo break; 832280405Srpaulo } 833280405Srpaulo case '{': { /* funcargs -> constructor */ 834280405Srpaulo constructor(ls, &args); 835280405Srpaulo break; 836280405Srpaulo } 837280405Srpaulo case TK_STRING: { /* funcargs -> STRING */ 838280405Srpaulo codestring(ls, &args, ls->t.seminfo.ts); 839280405Srpaulo luaX_next(ls); /* must use 'seminfo' before 'next' */ 840280405Srpaulo break; 841280405Srpaulo } 842280405Srpaulo default: { 843280405Srpaulo luaX_syntaxerror(ls, "function arguments expected"); 844280405Srpaulo } 845280405Srpaulo } 846280405Srpaulo lua_assert(f->k == VNONRELOC); 847280405Srpaulo base = f->u.info; /* base register for call */ 848280405Srpaulo if (hasmultret(args.k)) 849280405Srpaulo nparams = LUA_MULTRET; /* open call */ 850280405Srpaulo else { 851280405Srpaulo if (args.k != VVOID) 852280405Srpaulo luaK_exp2nextreg(fs, &args); /* close last argument */ 853280405Srpaulo nparams = fs->freereg - (base+1); 854280405Srpaulo } 855280405Srpaulo init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); 856280405Srpaulo luaK_fixline(fs, line); 857280405Srpaulo fs->freereg = base+1; /* call remove function and arguments and leaves 858280405Srpaulo (unless changed) one result */ 859280405Srpaulo} 860280405Srpaulo 861280405Srpaulo 862280405Srpaulo 863280405Srpaulo 864280405Srpaulo/* 865280405Srpaulo** {====================================================================== 866280405Srpaulo** Expression parsing 867280405Srpaulo** ======================================================================= 868280405Srpaulo*/ 869280405Srpaulo 870280405Srpaulo 871280405Srpaulostatic void primaryexp (LexState *ls, expdesc *v) { 872280405Srpaulo /* primaryexp -> NAME | '(' expr ')' */ 873280405Srpaulo switch (ls->t.token) { 874280405Srpaulo case '(': { 875280405Srpaulo int line = ls->linenumber; 876280405Srpaulo luaX_next(ls); 877280405Srpaulo expr(ls, v); 878280405Srpaulo check_match(ls, ')', '(', line); 879280405Srpaulo luaK_dischargevars(ls->fs, v); 880280405Srpaulo return; 881280405Srpaulo } 882280405Srpaulo case TK_NAME: { 883280405Srpaulo singlevar(ls, v); 884280405Srpaulo return; 885280405Srpaulo } 886280405Srpaulo default: { 887280405Srpaulo luaX_syntaxerror(ls, "unexpected symbol"); 888280405Srpaulo } 889280405Srpaulo } 890280405Srpaulo} 891280405Srpaulo 892280405Srpaulo 893280405Srpaulostatic void suffixedexp (LexState *ls, expdesc *v) { 894280405Srpaulo /* suffixedexp -> 895280405Srpaulo primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ 896280405Srpaulo FuncState *fs = ls->fs; 897280405Srpaulo int line = ls->linenumber; 898280405Srpaulo primaryexp(ls, v); 899280405Srpaulo for (;;) { 900280405Srpaulo switch (ls->t.token) { 901280405Srpaulo case '.': { /* fieldsel */ 902280405Srpaulo fieldsel(ls, v); 903280405Srpaulo break; 904280405Srpaulo } 905280405Srpaulo case '[': { /* '[' exp1 ']' */ 906280405Srpaulo expdesc key; 907280405Srpaulo luaK_exp2anyregup(fs, v); 908280405Srpaulo yindex(ls, &key); 909280405Srpaulo luaK_indexed(fs, v, &key); 910280405Srpaulo break; 911280405Srpaulo } 912280405Srpaulo case ':': { /* ':' NAME funcargs */ 913280405Srpaulo expdesc key; 914280405Srpaulo luaX_next(ls); 915280405Srpaulo checkname(ls, &key); 916280405Srpaulo luaK_self(fs, v, &key); 917280405Srpaulo funcargs(ls, v, line); 918280405Srpaulo break; 919280405Srpaulo } 920280405Srpaulo case '(': case TK_STRING: case '{': { /* funcargs */ 921280405Srpaulo luaK_exp2nextreg(fs, v); 922280405Srpaulo funcargs(ls, v, line); 923280405Srpaulo break; 924280405Srpaulo } 925280405Srpaulo default: return; 926280405Srpaulo } 927280405Srpaulo } 928280405Srpaulo} 929280405Srpaulo 930280405Srpaulo 931280405Srpaulostatic void simpleexp (LexState *ls, expdesc *v) { 932280405Srpaulo /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... | 933280405Srpaulo constructor | FUNCTION body | suffixedexp */ 934280405Srpaulo switch (ls->t.token) { 935280405Srpaulo case TK_FLT: { 936280405Srpaulo init_exp(v, VKFLT, 0); 937280405Srpaulo v->u.nval = ls->t.seminfo.r; 938280405Srpaulo break; 939280405Srpaulo } 940280405Srpaulo case TK_INT: { 941280405Srpaulo init_exp(v, VKINT, 0); 942280405Srpaulo v->u.ival = ls->t.seminfo.i; 943280405Srpaulo break; 944280405Srpaulo } 945280405Srpaulo case TK_STRING: { 946280405Srpaulo codestring(ls, v, ls->t.seminfo.ts); 947280405Srpaulo break; 948280405Srpaulo } 949280405Srpaulo case TK_NIL: { 950280405Srpaulo init_exp(v, VNIL, 0); 951280405Srpaulo break; 952280405Srpaulo } 953280405Srpaulo case TK_TRUE: { 954280405Srpaulo init_exp(v, VTRUE, 0); 955280405Srpaulo break; 956280405Srpaulo } 957280405Srpaulo case TK_FALSE: { 958280405Srpaulo init_exp(v, VFALSE, 0); 959280405Srpaulo break; 960280405Srpaulo } 961280405Srpaulo case TK_DOTS: { /* vararg */ 962280405Srpaulo FuncState *fs = ls->fs; 963280405Srpaulo check_condition(ls, fs->f->is_vararg, 964280405Srpaulo "cannot use '...' outside a vararg function"); 965280405Srpaulo init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); 966280405Srpaulo break; 967280405Srpaulo } 968280405Srpaulo case '{': { /* constructor */ 969280405Srpaulo constructor(ls, v); 970280405Srpaulo return; 971280405Srpaulo } 972280405Srpaulo case TK_FUNCTION: { 973280405Srpaulo luaX_next(ls); 974280405Srpaulo body(ls, v, 0, ls->linenumber); 975280405Srpaulo return; 976280405Srpaulo } 977280405Srpaulo default: { 978280405Srpaulo suffixedexp(ls, v); 979280405Srpaulo return; 980280405Srpaulo } 981280405Srpaulo } 982280405Srpaulo luaX_next(ls); 983280405Srpaulo} 984280405Srpaulo 985280405Srpaulo 986280405Srpaulostatic UnOpr getunopr (int op) { 987280405Srpaulo switch (op) { 988280405Srpaulo case TK_NOT: return OPR_NOT; 989280405Srpaulo case '-': return OPR_MINUS; 990280405Srpaulo case '~': return OPR_BNOT; 991280405Srpaulo case '#': return OPR_LEN; 992280405Srpaulo default: return OPR_NOUNOPR; 993280405Srpaulo } 994280405Srpaulo} 995280405Srpaulo 996280405Srpaulo 997280405Srpaulostatic BinOpr getbinopr (int op) { 998280405Srpaulo switch (op) { 999280405Srpaulo case '+': return OPR_ADD; 1000280405Srpaulo case '-': return OPR_SUB; 1001280405Srpaulo case '*': return OPR_MUL; 1002280405Srpaulo case '%': return OPR_MOD; 1003280405Srpaulo case '^': return OPR_POW; 1004280405Srpaulo case '/': return OPR_DIV; 1005280405Srpaulo case TK_IDIV: return OPR_IDIV; 1006280405Srpaulo case '&': return OPR_BAND; 1007280405Srpaulo case '|': return OPR_BOR; 1008280405Srpaulo case '~': return OPR_BXOR; 1009280405Srpaulo case TK_SHL: return OPR_SHL; 1010280405Srpaulo case TK_SHR: return OPR_SHR; 1011280405Srpaulo case TK_CONCAT: return OPR_CONCAT; 1012280405Srpaulo case TK_NE: return OPR_NE; 1013280405Srpaulo case TK_EQ: return OPR_EQ; 1014280405Srpaulo case '<': return OPR_LT; 1015280405Srpaulo case TK_LE: return OPR_LE; 1016280405Srpaulo case '>': return OPR_GT; 1017280405Srpaulo case TK_GE: return OPR_GE; 1018280405Srpaulo case TK_AND: return OPR_AND; 1019280405Srpaulo case TK_OR: return OPR_OR; 1020280405Srpaulo default: return OPR_NOBINOPR; 1021280405Srpaulo } 1022280405Srpaulo} 1023280405Srpaulo 1024280405Srpaulo 1025280405Srpaulostatic const struct { 1026280405Srpaulo lu_byte left; /* left priority for each binary operator */ 1027280405Srpaulo lu_byte right; /* right priority */ 1028280405Srpaulo} priority[] = { /* ORDER OPR */ 1029280405Srpaulo {10, 10}, {10, 10}, /* '+' '-' */ 1030280405Srpaulo {11, 11}, {11, 11}, /* '*' '%' */ 1031280405Srpaulo {14, 13}, /* '^' (right associative) */ 1032280405Srpaulo {11, 11}, {11, 11}, /* '/' '//' */ 1033280405Srpaulo {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ 1034280405Srpaulo {7, 7}, {7, 7}, /* '<<' '>>' */ 1035280405Srpaulo {9, 8}, /* '..' (right associative) */ 1036280405Srpaulo {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ 1037280405Srpaulo {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ 1038280405Srpaulo {2, 2}, {1, 1} /* and, or */ 1039280405Srpaulo}; 1040280405Srpaulo 1041280405Srpaulo#define UNARY_PRIORITY 12 /* priority for unary operators */ 1042280405Srpaulo 1043280405Srpaulo 1044280405Srpaulo/* 1045280405Srpaulo** subexpr -> (simpleexp | unop subexpr) { binop subexpr } 1046280405Srpaulo** where 'binop' is any binary operator with a priority higher than 'limit' 1047280405Srpaulo*/ 1048280405Srpaulostatic BinOpr subexpr (LexState *ls, expdesc *v, int limit) { 1049280405Srpaulo BinOpr op; 1050280405Srpaulo UnOpr uop; 1051280405Srpaulo enterlevel(ls); 1052280405Srpaulo uop = getunopr(ls->t.token); 1053280405Srpaulo if (uop != OPR_NOUNOPR) { 1054280405Srpaulo int line = ls->linenumber; 1055280405Srpaulo luaX_next(ls); 1056280405Srpaulo subexpr(ls, v, UNARY_PRIORITY); 1057280405Srpaulo luaK_prefix(ls->fs, uop, v, line); 1058280405Srpaulo } 1059280405Srpaulo else simpleexp(ls, v); 1060280405Srpaulo /* expand while operators have priorities higher than 'limit' */ 1061280405Srpaulo op = getbinopr(ls->t.token); 1062280405Srpaulo while (op != OPR_NOBINOPR && priority[op].left > limit) { 1063280405Srpaulo expdesc v2; 1064280405Srpaulo BinOpr nextop; 1065280405Srpaulo int line = ls->linenumber; 1066280405Srpaulo luaX_next(ls); 1067280405Srpaulo luaK_infix(ls->fs, op, v); 1068280405Srpaulo /* read sub-expression with higher priority */ 1069280405Srpaulo nextop = subexpr(ls, &v2, priority[op].right); 1070280405Srpaulo luaK_posfix(ls->fs, op, v, &v2, line); 1071280405Srpaulo op = nextop; 1072280405Srpaulo } 1073280405Srpaulo leavelevel(ls); 1074280405Srpaulo return op; /* return first untreated operator */ 1075280405Srpaulo} 1076280405Srpaulo 1077280405Srpaulo 1078280405Srpaulostatic void expr (LexState *ls, expdesc *v) { 1079280405Srpaulo subexpr(ls, v, 0); 1080280405Srpaulo} 1081280405Srpaulo 1082280405Srpaulo/* }==================================================================== */ 1083280405Srpaulo 1084280405Srpaulo 1085280405Srpaulo 1086280405Srpaulo/* 1087280405Srpaulo** {====================================================================== 1088280405Srpaulo** Rules for Statements 1089280405Srpaulo** ======================================================================= 1090280405Srpaulo*/ 1091280405Srpaulo 1092280405Srpaulo 1093280405Srpaulostatic void block (LexState *ls) { 1094280405Srpaulo /* block -> statlist */ 1095280405Srpaulo FuncState *fs = ls->fs; 1096280405Srpaulo BlockCnt bl; 1097280405Srpaulo enterblock(fs, &bl, 0); 1098280405Srpaulo statlist(ls); 1099280405Srpaulo leaveblock(fs); 1100280405Srpaulo} 1101280405Srpaulo 1102280405Srpaulo 1103280405Srpaulo/* 1104280405Srpaulo** structure to chain all variables in the left-hand side of an 1105280405Srpaulo** assignment 1106280405Srpaulo*/ 1107280405Srpaulostruct LHS_assign { 1108280405Srpaulo struct LHS_assign *prev; 1109280405Srpaulo expdesc v; /* variable (global, local, upvalue, or indexed) */ 1110280405Srpaulo}; 1111280405Srpaulo 1112280405Srpaulo 1113280405Srpaulo/* 1114280405Srpaulo** check whether, in an assignment to an upvalue/local variable, the 1115280405Srpaulo** upvalue/local variable is begin used in a previous assignment to a 1116280405Srpaulo** table. If so, save original upvalue/local value in a safe place and 1117280405Srpaulo** use this safe copy in the previous assignment. 1118280405Srpaulo*/ 1119280405Srpaulostatic void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { 1120280405Srpaulo FuncState *fs = ls->fs; 1121280405Srpaulo int extra = fs->freereg; /* eventual position to save local variable */ 1122280405Srpaulo int conflict = 0; 1123280405Srpaulo for (; lh; lh = lh->prev) { /* check all previous assignments */ 1124280405Srpaulo if (lh->v.k == VINDEXED) { /* assigning to a table? */ 1125280405Srpaulo /* table is the upvalue/local being assigned now? */ 1126280405Srpaulo if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { 1127280405Srpaulo conflict = 1; 1128280405Srpaulo lh->v.u.ind.vt = VLOCAL; 1129280405Srpaulo lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ 1130280405Srpaulo } 1131280405Srpaulo /* index is the local being assigned? (index cannot be upvalue) */ 1132280405Srpaulo if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { 1133280405Srpaulo conflict = 1; 1134280405Srpaulo lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ 1135280405Srpaulo } 1136280405Srpaulo } 1137280405Srpaulo } 1138280405Srpaulo if (conflict) { 1139280405Srpaulo /* copy upvalue/local value to a temporary (in position 'extra') */ 1140280405Srpaulo OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; 1141280405Srpaulo luaK_codeABC(fs, op, extra, v->u.info, 0); 1142280405Srpaulo luaK_reserveregs(fs, 1); 1143280405Srpaulo } 1144280405Srpaulo} 1145280405Srpaulo 1146280405Srpaulo 1147280405Srpaulostatic void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { 1148280405Srpaulo expdesc e; 1149280405Srpaulo check_condition(ls, vkisvar(lh->v.k), "syntax error"); 1150280405Srpaulo if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ 1151280405Srpaulo struct LHS_assign nv; 1152280405Srpaulo nv.prev = lh; 1153280405Srpaulo suffixedexp(ls, &nv.v); 1154280405Srpaulo if (nv.v.k != VINDEXED) 1155280405Srpaulo check_conflict(ls, lh, &nv.v); 1156280405Srpaulo checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, 1157280405Srpaulo "C levels"); 1158280405Srpaulo assignment(ls, &nv, nvars+1); 1159280405Srpaulo } 1160280405Srpaulo else { /* assignment -> '=' explist */ 1161280405Srpaulo int nexps; 1162280405Srpaulo checknext(ls, '='); 1163280405Srpaulo nexps = explist(ls, &e); 1164326344Simp if (nexps != nvars) 1165280405Srpaulo adjust_assign(ls, nvars, nexps, &e); 1166280405Srpaulo else { 1167280405Srpaulo luaK_setoneret(ls->fs, &e); /* close last expression */ 1168280405Srpaulo luaK_storevar(ls->fs, &lh->v, &e); 1169280405Srpaulo return; /* avoid default */ 1170280405Srpaulo } 1171280405Srpaulo } 1172280405Srpaulo init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ 1173280405Srpaulo luaK_storevar(ls->fs, &lh->v, &e); 1174280405Srpaulo} 1175280405Srpaulo 1176280405Srpaulo 1177280405Srpaulostatic int cond (LexState *ls) { 1178280405Srpaulo /* cond -> exp */ 1179280405Srpaulo expdesc v; 1180280405Srpaulo expr(ls, &v); /* read condition */ 1181280405Srpaulo if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */ 1182280405Srpaulo luaK_goiftrue(ls->fs, &v); 1183280405Srpaulo return v.f; 1184280405Srpaulo} 1185280405Srpaulo 1186280405Srpaulo 1187280405Srpaulostatic void gotostat (LexState *ls, int pc) { 1188280405Srpaulo int line = ls->linenumber; 1189280405Srpaulo TString *label; 1190280405Srpaulo int g; 1191280405Srpaulo if (testnext(ls, TK_GOTO)) 1192280405Srpaulo label = str_checkname(ls); 1193280405Srpaulo else { 1194280405Srpaulo luaX_next(ls); /* skip break */ 1195280405Srpaulo label = luaS_new(ls->L, "break"); 1196280405Srpaulo } 1197280405Srpaulo g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); 1198280405Srpaulo findlabel(ls, g); /* close it if label already defined */ 1199280405Srpaulo} 1200280405Srpaulo 1201280405Srpaulo 1202280405Srpaulo/* check for repeated labels on the same block */ 1203280405Srpaulostatic void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { 1204280405Srpaulo int i; 1205280405Srpaulo for (i = fs->bl->firstlabel; i < ll->n; i++) { 1206280405Srpaulo if (eqstr(label, ll->arr[i].name)) { 1207280405Srpaulo const char *msg = luaO_pushfstring(fs->ls->L, 1208280405Srpaulo "label '%s' already defined on line %d", 1209280405Srpaulo getstr(label), ll->arr[i].line); 1210280405Srpaulo semerror(fs->ls, msg); 1211280405Srpaulo } 1212280405Srpaulo } 1213280405Srpaulo} 1214280405Srpaulo 1215280405Srpaulo 1216280405Srpaulo/* skip no-op statements */ 1217280405Srpaulostatic void skipnoopstat (LexState *ls) { 1218280405Srpaulo while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) 1219280405Srpaulo statement(ls); 1220280405Srpaulo} 1221280405Srpaulo 1222280405Srpaulo 1223280405Srpaulostatic void labelstat (LexState *ls, TString *label, int line) { 1224280405Srpaulo /* label -> '::' NAME '::' */ 1225280405Srpaulo FuncState *fs = ls->fs; 1226280405Srpaulo Labellist *ll = &ls->dyd->label; 1227280405Srpaulo int l; /* index of new label being created */ 1228280405Srpaulo checkrepeated(fs, ll, label); /* check for repeated labels */ 1229280405Srpaulo checknext(ls, TK_DBCOLON); /* skip double colon */ 1230280405Srpaulo /* create new entry for this label */ 1231326344Simp l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs)); 1232280405Srpaulo skipnoopstat(ls); /* skip other no-op statements */ 1233280405Srpaulo if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ 1234280405Srpaulo /* assume that locals are already out of scope */ 1235280405Srpaulo ll->arr[l].nactvar = fs->bl->nactvar; 1236280405Srpaulo } 1237280405Srpaulo findgotos(ls, &ll->arr[l]); 1238280405Srpaulo} 1239280405Srpaulo 1240280405Srpaulo 1241280405Srpaulostatic void whilestat (LexState *ls, int line) { 1242280405Srpaulo /* whilestat -> WHILE cond DO block END */ 1243280405Srpaulo FuncState *fs = ls->fs; 1244280405Srpaulo int whileinit; 1245280405Srpaulo int condexit; 1246280405Srpaulo BlockCnt bl; 1247280405Srpaulo luaX_next(ls); /* skip WHILE */ 1248280405Srpaulo whileinit = luaK_getlabel(fs); 1249280405Srpaulo condexit = cond(ls); 1250280405Srpaulo enterblock(fs, &bl, 1); 1251280405Srpaulo checknext(ls, TK_DO); 1252280405Srpaulo block(ls); 1253280405Srpaulo luaK_jumpto(fs, whileinit); 1254280405Srpaulo check_match(ls, TK_END, TK_WHILE, line); 1255280405Srpaulo leaveblock(fs); 1256280405Srpaulo luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ 1257280405Srpaulo} 1258280405Srpaulo 1259280405Srpaulo 1260280405Srpaulostatic void repeatstat (LexState *ls, int line) { 1261280405Srpaulo /* repeatstat -> REPEAT block UNTIL cond */ 1262280405Srpaulo int condexit; 1263280405Srpaulo FuncState *fs = ls->fs; 1264280405Srpaulo int repeat_init = luaK_getlabel(fs); 1265280405Srpaulo BlockCnt bl1, bl2; 1266280405Srpaulo enterblock(fs, &bl1, 1); /* loop block */ 1267280405Srpaulo enterblock(fs, &bl2, 0); /* scope block */ 1268280405Srpaulo luaX_next(ls); /* skip REPEAT */ 1269280405Srpaulo statlist(ls); 1270280405Srpaulo check_match(ls, TK_UNTIL, TK_REPEAT, line); 1271280405Srpaulo condexit = cond(ls); /* read condition (inside scope block) */ 1272280405Srpaulo if (bl2.upval) /* upvalues? */ 1273280405Srpaulo luaK_patchclose(fs, condexit, bl2.nactvar); 1274280405Srpaulo leaveblock(fs); /* finish scope */ 1275280405Srpaulo luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ 1276280405Srpaulo leaveblock(fs); /* finish loop */ 1277280405Srpaulo} 1278280405Srpaulo 1279280405Srpaulo 1280280405Srpaulostatic int exp1 (LexState *ls) { 1281280405Srpaulo expdesc e; 1282280405Srpaulo int reg; 1283280405Srpaulo expr(ls, &e); 1284280405Srpaulo luaK_exp2nextreg(ls->fs, &e); 1285280405Srpaulo lua_assert(e.k == VNONRELOC); 1286280405Srpaulo reg = e.u.info; 1287280405Srpaulo return reg; 1288280405Srpaulo} 1289280405Srpaulo 1290280405Srpaulo 1291280405Srpaulostatic void forbody (LexState *ls, int base, int line, int nvars, int isnum) { 1292280405Srpaulo /* forbody -> DO block */ 1293280405Srpaulo BlockCnt bl; 1294280405Srpaulo FuncState *fs = ls->fs; 1295280405Srpaulo int prep, endfor; 1296280405Srpaulo adjustlocalvars(ls, 3); /* control variables */ 1297280405Srpaulo checknext(ls, TK_DO); 1298280405Srpaulo prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); 1299280405Srpaulo enterblock(fs, &bl, 0); /* scope for declared variables */ 1300280405Srpaulo adjustlocalvars(ls, nvars); 1301280405Srpaulo luaK_reserveregs(fs, nvars); 1302280405Srpaulo block(ls); 1303280405Srpaulo leaveblock(fs); /* end of scope for declared variables */ 1304280405Srpaulo luaK_patchtohere(fs, prep); 1305280405Srpaulo if (isnum) /* numeric for? */ 1306280405Srpaulo endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); 1307280405Srpaulo else { /* generic for */ 1308280405Srpaulo luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); 1309280405Srpaulo luaK_fixline(fs, line); 1310280405Srpaulo endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); 1311280405Srpaulo } 1312280405Srpaulo luaK_patchlist(fs, endfor, prep + 1); 1313280405Srpaulo luaK_fixline(fs, line); 1314280405Srpaulo} 1315280405Srpaulo 1316280405Srpaulo 1317280405Srpaulostatic void fornum (LexState *ls, TString *varname, int line) { 1318280405Srpaulo /* fornum -> NAME = exp1,exp1[,exp1] forbody */ 1319280405Srpaulo FuncState *fs = ls->fs; 1320280405Srpaulo int base = fs->freereg; 1321280405Srpaulo new_localvarliteral(ls, "(for index)"); 1322280405Srpaulo new_localvarliteral(ls, "(for limit)"); 1323280405Srpaulo new_localvarliteral(ls, "(for step)"); 1324280405Srpaulo new_localvar(ls, varname); 1325280405Srpaulo checknext(ls, '='); 1326280405Srpaulo exp1(ls); /* initial value */ 1327280405Srpaulo checknext(ls, ','); 1328280405Srpaulo exp1(ls); /* limit */ 1329280405Srpaulo if (testnext(ls, ',')) 1330280405Srpaulo exp1(ls); /* optional step */ 1331280405Srpaulo else { /* default step = 1 */ 1332280405Srpaulo luaK_codek(fs, fs->freereg, luaK_intK(fs, 1)); 1333280405Srpaulo luaK_reserveregs(fs, 1); 1334280405Srpaulo } 1335280405Srpaulo forbody(ls, base, line, 1, 1); 1336280405Srpaulo} 1337280405Srpaulo 1338280405Srpaulo 1339280405Srpaulostatic void forlist (LexState *ls, TString *indexname) { 1340280405Srpaulo /* forlist -> NAME {,NAME} IN explist forbody */ 1341280405Srpaulo FuncState *fs = ls->fs; 1342280405Srpaulo expdesc e; 1343280405Srpaulo int nvars = 4; /* gen, state, control, plus at least one declared var */ 1344280405Srpaulo int line; 1345280405Srpaulo int base = fs->freereg; 1346280405Srpaulo /* create control variables */ 1347280405Srpaulo new_localvarliteral(ls, "(for generator)"); 1348280405Srpaulo new_localvarliteral(ls, "(for state)"); 1349280405Srpaulo new_localvarliteral(ls, "(for control)"); 1350280405Srpaulo /* create declared variables */ 1351280405Srpaulo new_localvar(ls, indexname); 1352280405Srpaulo while (testnext(ls, ',')) { 1353280405Srpaulo new_localvar(ls, str_checkname(ls)); 1354280405Srpaulo nvars++; 1355280405Srpaulo } 1356280405Srpaulo checknext(ls, TK_IN); 1357280405Srpaulo line = ls->linenumber; 1358280405Srpaulo adjust_assign(ls, 3, explist(ls, &e), &e); 1359280405Srpaulo luaK_checkstack(fs, 3); /* extra space to call generator */ 1360280405Srpaulo forbody(ls, base, line, nvars - 3, 0); 1361280405Srpaulo} 1362280405Srpaulo 1363280405Srpaulo 1364280405Srpaulostatic void forstat (LexState *ls, int line) { 1365280405Srpaulo /* forstat -> FOR (fornum | forlist) END */ 1366280405Srpaulo FuncState *fs = ls->fs; 1367280405Srpaulo TString *varname; 1368280405Srpaulo BlockCnt bl; 1369280405Srpaulo enterblock(fs, &bl, 1); /* scope for loop and control variables */ 1370280405Srpaulo luaX_next(ls); /* skip 'for' */ 1371280405Srpaulo varname = str_checkname(ls); /* first variable name */ 1372280405Srpaulo switch (ls->t.token) { 1373280405Srpaulo case '=': fornum(ls, varname, line); break; 1374280405Srpaulo case ',': case TK_IN: forlist(ls, varname); break; 1375280405Srpaulo default: luaX_syntaxerror(ls, "'=' or 'in' expected"); 1376280405Srpaulo } 1377280405Srpaulo check_match(ls, TK_END, TK_FOR, line); 1378280405Srpaulo leaveblock(fs); /* loop scope ('break' jumps to this point) */ 1379280405Srpaulo} 1380280405Srpaulo 1381280405Srpaulo 1382280405Srpaulostatic void test_then_block (LexState *ls, int *escapelist) { 1383280405Srpaulo /* test_then_block -> [IF | ELSEIF] cond THEN block */ 1384280405Srpaulo BlockCnt bl; 1385280405Srpaulo FuncState *fs = ls->fs; 1386280405Srpaulo expdesc v; 1387280405Srpaulo int jf; /* instruction to skip 'then' code (if condition is false) */ 1388280405Srpaulo luaX_next(ls); /* skip IF or ELSEIF */ 1389280405Srpaulo expr(ls, &v); /* read condition */ 1390280405Srpaulo checknext(ls, TK_THEN); 1391280405Srpaulo if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { 1392280405Srpaulo luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ 1393280405Srpaulo enterblock(fs, &bl, 0); /* must enter block before 'goto' */ 1394280405Srpaulo gotostat(ls, v.t); /* handle goto/break */ 1395344220Skevans while (testnext(ls, ';')) {} /* skip colons */ 1396280405Srpaulo if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ 1397280405Srpaulo leaveblock(fs); 1398280405Srpaulo return; /* and that is it */ 1399280405Srpaulo } 1400280405Srpaulo else /* must skip over 'then' part if condition is false */ 1401280405Srpaulo jf = luaK_jump(fs); 1402280405Srpaulo } 1403280405Srpaulo else { /* regular case (not goto/break) */ 1404280405Srpaulo luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ 1405280405Srpaulo enterblock(fs, &bl, 0); 1406280405Srpaulo jf = v.f; 1407280405Srpaulo } 1408280405Srpaulo statlist(ls); /* 'then' part */ 1409280405Srpaulo leaveblock(fs); 1410280405Srpaulo if (ls->t.token == TK_ELSE || 1411280405Srpaulo ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ 1412280405Srpaulo luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ 1413280405Srpaulo luaK_patchtohere(fs, jf); 1414280405Srpaulo} 1415280405Srpaulo 1416280405Srpaulo 1417280405Srpaulostatic void ifstat (LexState *ls, int line) { 1418280405Srpaulo /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ 1419280405Srpaulo FuncState *fs = ls->fs; 1420280405Srpaulo int escapelist = NO_JUMP; /* exit list for finished parts */ 1421280405Srpaulo test_then_block(ls, &escapelist); /* IF cond THEN block */ 1422280405Srpaulo while (ls->t.token == TK_ELSEIF) 1423280405Srpaulo test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ 1424280405Srpaulo if (testnext(ls, TK_ELSE)) 1425280405Srpaulo block(ls); /* 'else' part */ 1426280405Srpaulo check_match(ls, TK_END, TK_IF, line); 1427280405Srpaulo luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ 1428280405Srpaulo} 1429280405Srpaulo 1430280405Srpaulo 1431280405Srpaulostatic void localfunc (LexState *ls) { 1432280405Srpaulo expdesc b; 1433280405Srpaulo FuncState *fs = ls->fs; 1434280405Srpaulo new_localvar(ls, str_checkname(ls)); /* new local variable */ 1435280405Srpaulo adjustlocalvars(ls, 1); /* enter its scope */ 1436280405Srpaulo body(ls, &b, 0, ls->linenumber); /* function created in next register */ 1437280405Srpaulo /* debug information will only see the variable after this point! */ 1438280405Srpaulo getlocvar(fs, b.u.info)->startpc = fs->pc; 1439280405Srpaulo} 1440280405Srpaulo 1441280405Srpaulo 1442280405Srpaulostatic void localstat (LexState *ls) { 1443280405Srpaulo /* stat -> LOCAL NAME {',' NAME} ['=' explist] */ 1444280405Srpaulo int nvars = 0; 1445280405Srpaulo int nexps; 1446280405Srpaulo expdesc e; 1447280405Srpaulo do { 1448280405Srpaulo new_localvar(ls, str_checkname(ls)); 1449280405Srpaulo nvars++; 1450280405Srpaulo } while (testnext(ls, ',')); 1451280405Srpaulo if (testnext(ls, '=')) 1452280405Srpaulo nexps = explist(ls, &e); 1453280405Srpaulo else { 1454280405Srpaulo e.k = VVOID; 1455280405Srpaulo nexps = 0; 1456280405Srpaulo } 1457280405Srpaulo adjust_assign(ls, nvars, nexps, &e); 1458280405Srpaulo adjustlocalvars(ls, nvars); 1459280405Srpaulo} 1460280405Srpaulo 1461280405Srpaulo 1462280405Srpaulostatic int funcname (LexState *ls, expdesc *v) { 1463280405Srpaulo /* funcname -> NAME {fieldsel} [':' NAME] */ 1464280405Srpaulo int ismethod = 0; 1465280405Srpaulo singlevar(ls, v); 1466280405Srpaulo while (ls->t.token == '.') 1467280405Srpaulo fieldsel(ls, v); 1468280405Srpaulo if (ls->t.token == ':') { 1469280405Srpaulo ismethod = 1; 1470280405Srpaulo fieldsel(ls, v); 1471280405Srpaulo } 1472280405Srpaulo return ismethod; 1473280405Srpaulo} 1474280405Srpaulo 1475280405Srpaulo 1476280405Srpaulostatic void funcstat (LexState *ls, int line) { 1477280405Srpaulo /* funcstat -> FUNCTION funcname body */ 1478280405Srpaulo int ismethod; 1479280405Srpaulo expdesc v, b; 1480280405Srpaulo luaX_next(ls); /* skip FUNCTION */ 1481280405Srpaulo ismethod = funcname(ls, &v); 1482280405Srpaulo body(ls, &b, ismethod, line); 1483280405Srpaulo luaK_storevar(ls->fs, &v, &b); 1484280405Srpaulo luaK_fixline(ls->fs, line); /* definition "happens" in the first line */ 1485280405Srpaulo} 1486280405Srpaulo 1487280405Srpaulo 1488280405Srpaulostatic void exprstat (LexState *ls) { 1489280405Srpaulo /* stat -> func | assignment */ 1490280405Srpaulo FuncState *fs = ls->fs; 1491280405Srpaulo struct LHS_assign v; 1492280405Srpaulo suffixedexp(ls, &v.v); 1493280405Srpaulo if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ 1494280405Srpaulo v.prev = NULL; 1495280405Srpaulo assignment(ls, &v, 1); 1496280405Srpaulo } 1497280405Srpaulo else { /* stat -> func */ 1498280405Srpaulo check_condition(ls, v.v.k == VCALL, "syntax error"); 1499326344Simp SETARG_C(getinstruction(fs, &v.v), 1); /* call statement uses no results */ 1500280405Srpaulo } 1501280405Srpaulo} 1502280405Srpaulo 1503280405Srpaulo 1504280405Srpaulostatic void retstat (LexState *ls) { 1505280405Srpaulo /* stat -> RETURN [explist] [';'] */ 1506280405Srpaulo FuncState *fs = ls->fs; 1507280405Srpaulo expdesc e; 1508280405Srpaulo int first, nret; /* registers with returned values */ 1509280405Srpaulo if (block_follow(ls, 1) || ls->t.token == ';') 1510280405Srpaulo first = nret = 0; /* return no values */ 1511280405Srpaulo else { 1512280405Srpaulo nret = explist(ls, &e); /* optional return values */ 1513280405Srpaulo if (hasmultret(e.k)) { 1514280405Srpaulo luaK_setmultret(fs, &e); 1515280405Srpaulo if (e.k == VCALL && nret == 1) { /* tail call? */ 1516326344Simp SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); 1517326344Simp lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar); 1518280405Srpaulo } 1519280405Srpaulo first = fs->nactvar; 1520280405Srpaulo nret = LUA_MULTRET; /* return all values */ 1521280405Srpaulo } 1522280405Srpaulo else { 1523280405Srpaulo if (nret == 1) /* only one single value? */ 1524280405Srpaulo first = luaK_exp2anyreg(fs, &e); 1525280405Srpaulo else { 1526280405Srpaulo luaK_exp2nextreg(fs, &e); /* values must go to the stack */ 1527280405Srpaulo first = fs->nactvar; /* return all active values */ 1528280405Srpaulo lua_assert(nret == fs->freereg - first); 1529280405Srpaulo } 1530280405Srpaulo } 1531280405Srpaulo } 1532280405Srpaulo luaK_ret(fs, first, nret); 1533280405Srpaulo testnext(ls, ';'); /* skip optional semicolon */ 1534280405Srpaulo} 1535280405Srpaulo 1536280405Srpaulo 1537280405Srpaulostatic void statement (LexState *ls) { 1538280405Srpaulo int line = ls->linenumber; /* may be needed for error messages */ 1539280405Srpaulo enterlevel(ls); 1540280405Srpaulo switch (ls->t.token) { 1541280405Srpaulo case ';': { /* stat -> ';' (empty statement) */ 1542280405Srpaulo luaX_next(ls); /* skip ';' */ 1543280405Srpaulo break; 1544280405Srpaulo } 1545280405Srpaulo case TK_IF: { /* stat -> ifstat */ 1546280405Srpaulo ifstat(ls, line); 1547280405Srpaulo break; 1548280405Srpaulo } 1549280405Srpaulo case TK_WHILE: { /* stat -> whilestat */ 1550280405Srpaulo whilestat(ls, line); 1551280405Srpaulo break; 1552280405Srpaulo } 1553280405Srpaulo case TK_DO: { /* stat -> DO block END */ 1554280405Srpaulo luaX_next(ls); /* skip DO */ 1555280405Srpaulo block(ls); 1556280405Srpaulo check_match(ls, TK_END, TK_DO, line); 1557280405Srpaulo break; 1558280405Srpaulo } 1559280405Srpaulo case TK_FOR: { /* stat -> forstat */ 1560280405Srpaulo forstat(ls, line); 1561280405Srpaulo break; 1562280405Srpaulo } 1563280405Srpaulo case TK_REPEAT: { /* stat -> repeatstat */ 1564280405Srpaulo repeatstat(ls, line); 1565280405Srpaulo break; 1566280405Srpaulo } 1567280405Srpaulo case TK_FUNCTION: { /* stat -> funcstat */ 1568280405Srpaulo funcstat(ls, line); 1569280405Srpaulo break; 1570280405Srpaulo } 1571280405Srpaulo case TK_LOCAL: { /* stat -> localstat */ 1572280405Srpaulo luaX_next(ls); /* skip LOCAL */ 1573280405Srpaulo if (testnext(ls, TK_FUNCTION)) /* local function? */ 1574280405Srpaulo localfunc(ls); 1575280405Srpaulo else 1576280405Srpaulo localstat(ls); 1577280405Srpaulo break; 1578280405Srpaulo } 1579280405Srpaulo case TK_DBCOLON: { /* stat -> label */ 1580280405Srpaulo luaX_next(ls); /* skip double colon */ 1581280405Srpaulo labelstat(ls, str_checkname(ls), line); 1582280405Srpaulo break; 1583280405Srpaulo } 1584280405Srpaulo case TK_RETURN: { /* stat -> retstat */ 1585280405Srpaulo luaX_next(ls); /* skip RETURN */ 1586280405Srpaulo retstat(ls); 1587280405Srpaulo break; 1588280405Srpaulo } 1589280405Srpaulo case TK_BREAK: /* stat -> breakstat */ 1590280405Srpaulo case TK_GOTO: { /* stat -> 'goto' NAME */ 1591280405Srpaulo gotostat(ls, luaK_jump(ls->fs)); 1592280405Srpaulo break; 1593280405Srpaulo } 1594280405Srpaulo default: { /* stat -> func | assignment */ 1595280405Srpaulo exprstat(ls); 1596280405Srpaulo break; 1597280405Srpaulo } 1598280405Srpaulo } 1599280405Srpaulo lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && 1600280405Srpaulo ls->fs->freereg >= ls->fs->nactvar); 1601280405Srpaulo ls->fs->freereg = ls->fs->nactvar; /* free registers */ 1602280405Srpaulo leavelevel(ls); 1603280405Srpaulo} 1604280405Srpaulo 1605280405Srpaulo/* }====================================================================== */ 1606280405Srpaulo 1607280405Srpaulo 1608280405Srpaulo/* 1609280405Srpaulo** compiles the main function, which is a regular vararg function with an 1610280405Srpaulo** upvalue named LUA_ENV 1611280405Srpaulo*/ 1612280405Srpaulostatic void mainfunc (LexState *ls, FuncState *fs) { 1613280405Srpaulo BlockCnt bl; 1614280405Srpaulo expdesc v; 1615280405Srpaulo open_func(ls, fs, &bl); 1616326344Simp fs->f->is_vararg = 1; /* main function is always declared vararg */ 1617280405Srpaulo init_exp(&v, VLOCAL, 0); /* create and... */ 1618280405Srpaulo newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ 1619280405Srpaulo luaX_next(ls); /* read first token */ 1620280405Srpaulo statlist(ls); /* parse main body */ 1621280405Srpaulo check(ls, TK_EOS); 1622280405Srpaulo close_func(ls); 1623280405Srpaulo} 1624280405Srpaulo 1625280405Srpaulo 1626280405SrpauloLClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 1627280405Srpaulo Dyndata *dyd, const char *name, int firstchar) { 1628280405Srpaulo LexState lexstate; 1629280405Srpaulo FuncState funcstate; 1630280405Srpaulo LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ 1631280405Srpaulo setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */ 1632326344Simp luaD_inctop(L); 1633280405Srpaulo lexstate.h = luaH_new(L); /* create table for scanner */ 1634280405Srpaulo sethvalue(L, L->top, lexstate.h); /* anchor it */ 1635326344Simp luaD_inctop(L); 1636280405Srpaulo funcstate.f = cl->p = luaF_newproto(L); 1637280405Srpaulo funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ 1638280405Srpaulo lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ 1639280405Srpaulo lexstate.buff = buff; 1640280405Srpaulo lexstate.dyd = dyd; 1641280405Srpaulo dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; 1642280405Srpaulo luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); 1643280405Srpaulo mainfunc(&lexstate, &funcstate); 1644280405Srpaulo lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); 1645280405Srpaulo /* all scopes should be correctly finished */ 1646280405Srpaulo lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); 1647280405Srpaulo L->top--; /* remove scanner's table */ 1648280405Srpaulo return cl; /* closure is on the stack, too */ 1649280405Srpaulo} 1650280405Srpaulo 1651