diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-05-27 10:08:34 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-05-27 10:08:34 -0300 |
| commit | 7e59a8901d063dbea4eb0693c9c2d85bda1fc5f6 (patch) | |
| tree | 1834168cd16e821a017e3d8408978f89e6c2ddaf /lparser.c | |
| parent | abc6eac404da8181ad945ac6950f61a65ba7dfa5 (diff) | |
| download | lua-7e59a8901d063dbea4eb0693c9c2d85bda1fc5f6.tar.gz lua-7e59a8901d063dbea4eb0693c9c2d85bda1fc5f6.tar.bz2 lua-7e59a8901d063dbea4eb0693c9c2d85bda1fc5f6.zip | |
NEW LL(1) PARSER
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 1332 |
1 files changed, 1332 insertions, 0 deletions
diff --git a/lparser.c b/lparser.c new file mode 100644 index 00000000..0eefb204 --- /dev/null +++ b/lparser.c | |||
| @@ -0,0 +1,1332 @@ | |||
| 1 | /* | ||
| 2 | ** $Id: $ | ||
| 3 | ** LL(1) Parser and code generator for Lua | ||
| 4 | ** See Copyright Notice in lua.h | ||
| 5 | */ | ||
| 6 | |||
| 7 | |||
| 8 | #include <stdio.h> | ||
| 9 | |||
| 10 | #include "lauxlib.h" | ||
| 11 | #include "ldo.h" | ||
| 12 | #include "lfunc.h" | ||
| 13 | #include "llex.h" | ||
| 14 | #include "lmem.h" | ||
| 15 | #include "lopcodes.h" | ||
| 16 | #include "lparser.h" | ||
| 17 | #include "lstate.h" | ||
| 18 | #include "lstring.h" | ||
| 19 | #include "lua.h" | ||
| 20 | #include "luadebug.h" | ||
| 21 | #include "lzio.h" | ||
| 22 | |||
| 23 | |||
| 24 | /* for limit numbers in error messages */ | ||
| 25 | #define MES_LIM(x) "(limit=" x ")" | ||
| 26 | |||
| 27 | |||
| 28 | /* size of a "normal" jump instruction: OpCode + 1 byte */ | ||
| 29 | #define JMPSIZE 2 | ||
| 30 | |||
| 31 | /* maximum number of local variables */ | ||
| 32 | #define MAXLOCALS 32 | ||
| 33 | #define SMAXLOCALS "32" | ||
| 34 | |||
| 35 | |||
| 36 | /* maximum number of upvalues */ | ||
| 37 | #define MAXUPVALUES 16 | ||
| 38 | #define SMAXUPVALUES "16" | ||
| 39 | |||
| 40 | |||
| 41 | /* | ||
| 42 | ** Variable descriptor: | ||
| 43 | ** must include a "exp" option because LL(1) cannot distinguish | ||
| 44 | ** between variables, upvalues and function calls on first sight. | ||
| 45 | ** VGLOBAL: info is constant index of global name | ||
| 46 | ** VLOCAL: info is stack index | ||
| 47 | ** VDOT: info is constant index of index name | ||
| 48 | ** VEXP: info is pc index of "nparam" of function call (or 0 if exp is closed) | ||
| 49 | */ | ||
| 50 | typedef enum {VGLOBAL, VLOCAL, VDOT, VINDEXED, VEXP} varkind; | ||
| 51 | |||
| 52 | typedef struct { | ||
| 53 | varkind k; | ||
| 54 | int info; | ||
| 55 | } vardesc; | ||
| 56 | |||
| 57 | |||
| 58 | /* | ||
| 59 | ** Expression List descriptor: | ||
| 60 | ** tells number of expressions in the list, | ||
| 61 | ** and, if last expression is open (a function call), | ||
| 62 | ** where is its pc index of "nparam" | ||
| 63 | */ | ||
| 64 | typedef struct { | ||
| 65 | int n; | ||
| 66 | int pc; /* 0 if last expression is closed */ | ||
| 67 | } listdesc; | ||
| 68 | |||
| 69 | |||
| 70 | /* | ||
| 71 | ** Constructors descriptor: | ||
| 72 | ** "n" indicates number of elements, and "k" signals whether | ||
| 73 | ** it is a list constructor (k = 0) or a record constructor (k = 1) | ||
| 74 | ** or empty (k = ';' or '}') | ||
| 75 | */ | ||
| 76 | typedef struct { | ||
| 77 | int n; | ||
| 78 | int k; | ||
| 79 | } constdesc; | ||
| 80 | |||
| 81 | |||
| 82 | /* state needed to generate code for a given function */ | ||
| 83 | typedef struct FuncState { | ||
| 84 | TProtoFunc *f; /* current function header */ | ||
| 85 | struct FuncState *prev; /* enclosuring function */ | ||
| 86 | int pc; /* next position to code */ | ||
| 87 | int stacksize; /* number of values on activation register */ | ||
| 88 | int maxstacksize; /* maximum number of values on activation register */ | ||
| 89 | int nlocalvar; /* number of active local variables */ | ||
| 90 | int nupvalues; /* number of upvalues */ | ||
| 91 | int nvars; /* number of entries in f->locvars */ | ||
| 92 | int maxcode; /* size of f->code */ | ||
| 93 | int maxvars; /* size of f->locvars (-1 if no debug information) */ | ||
| 94 | int maxconsts; /* size of f->consts */ | ||
| 95 | int lastsetline; /* line where last SETLINE was issued */ | ||
| 96 | vardesc upvalues[MAXUPVALUES]; /* upvalues */ | ||
| 97 | TaggedString *localvar[MAXLOCALS]; /* store local variable names */ | ||
| 98 | } FuncState; | ||
| 99 | |||
| 100 | |||
| 101 | static int assignment (LexState *ls, vardesc *v, int nvars); | ||
| 102 | static int cond (LexState *ls); | ||
| 103 | static int funcname (LexState *ls, vardesc *v); | ||
| 104 | static int funcparams (LexState *ls, int slf); | ||
| 105 | static int listfields (LexState *ls); | ||
| 106 | static int localnamelist (LexState *ls); | ||
| 107 | static int optional (LexState *ls, int c); | ||
| 108 | static int recfields (LexState *ls); | ||
| 109 | static int stat (LexState *ls); | ||
| 110 | static void block (LexState *ls); | ||
| 111 | static void body (LexState *ls, int needself, int line); | ||
| 112 | static void chunk (LexState *ls); | ||
| 113 | static void constructor (LexState *ls); | ||
| 114 | static void decinit (LexState *ls, listdesc *d); | ||
| 115 | static void exp (LexState *ls, vardesc *v); | ||
| 116 | static void exp1 (LexState *ls); | ||
| 117 | static void exp2 (LexState *ls, vardesc *v); | ||
| 118 | static void explist (LexState *ls, listdesc *e); | ||
| 119 | static void explist1 (LexState *ls, listdesc *e); | ||
| 120 | static void ifpart (LexState *ls); | ||
| 121 | static void parlist (LexState *ls); | ||
| 122 | static void part (LexState *ls, constdesc *cd); | ||
| 123 | static void recfield (LexState *ls); | ||
| 124 | static void ret (LexState *ls); | ||
| 125 | static void simpleexp (LexState *ls, vardesc *v); | ||
| 126 | static void statlist (LexState *ls); | ||
| 127 | static void var_or_func (LexState *ls, vardesc *v); | ||
| 128 | static void var_or_func_tail (LexState *ls, vardesc *v); | ||
| 129 | |||
| 130 | |||
| 131 | |||
| 132 | static void check_pc (FuncState *fs, int n) { | ||
| 133 | if (fs->pc+n > fs->maxcode) | ||
| 134 | fs->maxcode = luaM_growvector(&fs->f->code, fs->maxcode, | ||
| 135 | Byte, codeEM, MAX_INT); | ||
| 136 | } | ||
| 137 | |||
| 138 | |||
| 139 | static void code_byte (FuncState *fs, Byte c) { | ||
| 140 | check_pc(fs, 1); | ||
| 141 | fs->f->code[fs->pc++] = c; | ||
| 142 | } | ||
| 143 | |||
| 144 | |||
| 145 | static void deltastack (LexState *ls, int delta) { | ||
| 146 | FuncState *fs = ls->fs; | ||
| 147 | fs->stacksize += delta; | ||
| 148 | if (fs->stacksize > fs->maxstacksize) { | ||
| 149 | if (fs->stacksize > 255) | ||
| 150 | luaX_error(ls, "function/expression too complex"); | ||
| 151 | fs->maxstacksize = fs->stacksize; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | |||
| 156 | static int code_oparg_at (LexState *ls, int pc, OpCode op, int builtin, | ||
| 157 | int arg, int delta) { | ||
| 158 | Byte *code = ls->fs->f->code; | ||
| 159 | deltastack(ls, delta); | ||
| 160 | if (arg < builtin) { | ||
| 161 | code[pc] = op+1+arg; | ||
| 162 | return 1; | ||
| 163 | } | ||
| 164 | else if (arg <= 255) { | ||
| 165 | code[pc] = op; | ||
| 166 | code[pc+1] = arg; | ||
| 167 | return 2; | ||
| 168 | } | ||
| 169 | else if (arg <= MAX_WORD) { | ||
| 170 | code[pc] = op+1+builtin; | ||
| 171 | code[pc+1] = arg>>8; | ||
| 172 | code[pc+2] = arg&0xFF; | ||
| 173 | return 3; | ||
| 174 | } | ||
| 175 | else luaX_error(ls, "code too long " MES_LIM("64K")); | ||
| 176 | return 0; /* to avoid warnings */ | ||
| 177 | } | ||
| 178 | |||
| 179 | |||
| 180 | static int fix_opcode (LexState *ls, int pc, OpCode op, int builtin, int arg) { | ||
| 181 | FuncState *fs = ls->fs; | ||
| 182 | TProtoFunc *f = fs->f; | ||
| 183 | if (arg < builtin) { /* close space */ | ||
| 184 | luaO_memdown(f->code+pc+1, f->code+pc+2, fs->pc-(pc+2)); | ||
| 185 | fs->pc--; | ||
| 186 | } | ||
| 187 | else if (arg > 255) { /* open space */ | ||
| 188 | check_pc(fs, 1); | ||
| 189 | luaO_memup(f->code+pc+1, f->code+pc, fs->pc-pc); | ||
| 190 | fs->pc++; | ||
| 191 | } | ||
| 192 | return code_oparg_at(ls, pc, op, builtin, arg, 0) - 2; | ||
| 193 | } | ||
| 194 | |||
| 195 | static void code_oparg (LexState *ls, OpCode op, int builtin, int arg, | ||
| 196 | int delta) { | ||
| 197 | check_pc(ls->fs, 3); /* maximum code size */ | ||
| 198 | ls->fs->pc += code_oparg_at(ls, ls->fs->pc, op, builtin, arg, delta); | ||
| 199 | } | ||
| 200 | |||
| 201 | |||
| 202 | static void code_opcode (LexState *ls, OpCode op, int delta) { | ||
| 203 | deltastack(ls, delta); | ||
| 204 | code_byte(ls->fs, op); | ||
| 205 | } | ||
| 206 | |||
| 207 | |||
| 208 | static void code_constant (LexState *ls, int c) { | ||
| 209 | code_oparg(ls, PUSHCONSTANT, 8, c, 1); | ||
| 210 | } | ||
| 211 | |||
| 212 | |||
| 213 | static int next_constant (FuncState *fs) { | ||
| 214 | TProtoFunc *f = fs->f; | ||
| 215 | if (f->nconsts >= fs->maxconsts) { | ||
| 216 | fs->maxconsts = luaM_growvector(&f->consts, fs->maxconsts, TObject, | ||
| 217 | constantEM, MAX_WORD); | ||
| 218 | } | ||
| 219 | return f->nconsts++; | ||
| 220 | } | ||
| 221 | |||
| 222 | |||
| 223 | static int string_constant (FuncState *fs, TaggedString *s) { | ||
| 224 | TProtoFunc *f = fs->f; | ||
| 225 | int c = s->constindex; | ||
| 226 | if (!(c < f->nconsts && | ||
| 227 | ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) { | ||
| 228 | c = next_constant(fs); | ||
| 229 | ttype(&f->consts[c]) = LUA_T_STRING; | ||
| 230 | tsvalue(&f->consts[c]) = s; | ||
| 231 | s->constindex = c; /* hint for next time */ | ||
| 232 | } | ||
| 233 | return c; | ||
| 234 | } | ||
| 235 | |||
| 236 | |||
| 237 | static void code_string (LexState *ls, TaggedString *s) { | ||
| 238 | code_constant(ls, string_constant(ls->fs, s)); | ||
| 239 | } | ||
| 240 | |||
| 241 | |||
| 242 | #define LIM 20 | ||
| 243 | static int real_constant (FuncState *fs, real r) { | ||
| 244 | /* check whether 'r' has appeared within the last LIM entries */ | ||
| 245 | TObject *cnt = fs->f->consts; | ||
| 246 | int c = fs->f->nconsts; | ||
| 247 | int lim = c < LIM ? 0 : c-LIM; | ||
| 248 | while (--c >= lim) { | ||
| 249 | if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r) | ||
| 250 | return c; | ||
| 251 | } | ||
| 252 | /* not found; create a luaM_new entry */ | ||
| 253 | c = next_constant(fs); | ||
| 254 | cnt = fs->f->consts; /* 'next_constant' may reallocate this vector */ | ||
| 255 | ttype(&cnt[c]) = LUA_T_NUMBER; | ||
| 256 | nvalue(&cnt[c]) = r; | ||
| 257 | return c; | ||
| 258 | } | ||
| 259 | |||
| 260 | |||
| 261 | static void code_number (LexState *ls, real f) { | ||
| 262 | int i; | ||
| 263 | if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(int)f) == f) | ||
| 264 | code_oparg(ls, PUSHNUMBER, 3, i, 1); /* f has a short integer value */ | ||
| 265 | else | ||
| 266 | code_constant(ls, real_constant(ls->fs, f)); | ||
| 267 | } | ||
| 268 | |||
| 269 | |||
| 270 | static void flush_record (LexState *ls, int n) { | ||
| 271 | if (n > 0) | ||
| 272 | code_oparg(ls, SETMAP, 1, n-1, -2*n); | ||
| 273 | } | ||
| 274 | |||
| 275 | |||
| 276 | static void flush_list (LexState *ls, int m, int n) { | ||
| 277 | if (n == 0) return; | ||
| 278 | code_oparg(ls, SETLIST, 1, m, -n); | ||
| 279 | code_byte(ls->fs, n); | ||
| 280 | } | ||
| 281 | |||
| 282 | |||
| 283 | static void luaI_registerlocalvar (FuncState *fs, TaggedString *varname, | ||
| 284 | int line) { | ||
| 285 | if (fs->maxvars != -1) { /* debug information? */ | ||
| 286 | TProtoFunc *f = fs->f; | ||
| 287 | if (fs->nvars >= fs->maxvars) | ||
| 288 | fs->maxvars = luaM_growvector(&f->locvars, fs->maxvars, | ||
| 289 | LocVar, "", MAX_WORD); | ||
| 290 | f->locvars[fs->nvars].varname = varname; | ||
| 291 | f->locvars[fs->nvars].line = line; | ||
| 292 | fs->nvars++; | ||
| 293 | } | ||
| 294 | } | ||
| 295 | |||
| 296 | |||
| 297 | static void luaI_unregisterlocalvar (FuncState *fs, int line) { | ||
| 298 | luaI_registerlocalvar(fs, NULL, line); | ||
| 299 | } | ||
| 300 | |||
| 301 | |||
| 302 | static void store_localvar (LexState *ls, TaggedString *name, int n) { | ||
| 303 | FuncState *fs = ls->fs; | ||
| 304 | if (fs->nlocalvar+n < MAXLOCALS) | ||
| 305 | fs->localvar[fs->nlocalvar+n] = name; | ||
| 306 | else | ||
| 307 | luaX_error(ls, "too many local variables " MES_LIM(SMAXLOCALS)); | ||
| 308 | luaI_registerlocalvar(fs, name, ls->linenumber); | ||
| 309 | } | ||
| 310 | |||
| 311 | |||
| 312 | static void add_localvar (LexState *ls, TaggedString *name) { | ||
| 313 | store_localvar(ls, name, 0); | ||
| 314 | ls->fs->nlocalvar++; | ||
| 315 | } | ||
| 316 | |||
| 317 | |||
| 318 | static int aux_localname (FuncState *fs, TaggedString *n) { | ||
| 319 | int i; | ||
| 320 | for (i=fs->nlocalvar-1; i >= 0; i--) | ||
| 321 | if (n == fs->localvar[i]) return i; /* local var index */ | ||
| 322 | return -1; /* not found */ | ||
| 323 | } | ||
| 324 | |||
| 325 | |||
| 326 | static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int prev) { | ||
| 327 | FuncState *fs = prev ? ls->fs->prev : ls->fs; | ||
| 328 | int i = aux_localname(fs, n); | ||
| 329 | if (i >= 0) { /* local value */ | ||
| 330 | var->k = VLOCAL; | ||
| 331 | var->info = i; | ||
| 332 | } | ||
| 333 | else { /* check shadowing */ | ||
| 334 | FuncState *level = fs; | ||
| 335 | while ((level = level->prev) != NULL) | ||
| 336 | if (aux_localname(level, n) >= 0) | ||
| 337 | luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); | ||
| 338 | var->k = VGLOBAL; | ||
| 339 | var->info = string_constant(fs, n); | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | |||
| 344 | static int indexupvalue (LexState *ls, TaggedString *n) { | ||
| 345 | FuncState *fs = ls->fs; | ||
| 346 | vardesc v; | ||
| 347 | int i; | ||
| 348 | singlevar(ls, n, &v, 1); | ||
| 349 | for (i=0; i<fs->nupvalues; i++) { | ||
| 350 | if (fs->upvalues[i].k == v.k && fs->upvalues[i].info == v.info) | ||
| 351 | return i; | ||
| 352 | } | ||
| 353 | /* new one */ | ||
| 354 | if (++(fs->nupvalues) > MAXUPVALUES) | ||
| 355 | luaX_error(ls, "too many upvalues in a single function " | ||
| 356 | MES_LIM(SMAXUPVALUES)); | ||
| 357 | fs->upvalues[i] = v; /* i = fs->nupvalues - 1 */ | ||
| 358 | return i; | ||
| 359 | } | ||
| 360 | |||
| 361 | |||
| 362 | static void pushupvalue (LexState *ls, TaggedString *n) { | ||
| 363 | int i; | ||
| 364 | if (ls->fs->prev == NULL) | ||
| 365 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | ||
| 366 | if (aux_localname(ls->fs, n) >= 0) | ||
| 367 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); | ||
| 368 | i = indexupvalue(ls, n); | ||
| 369 | code_oparg(ls, PUSHUPVALUE, 2, i, 1); | ||
| 370 | } | ||
| 371 | |||
| 372 | |||
| 373 | |||
| 374 | static void check_debugline (LexState *ls) { | ||
| 375 | if (lua_debug && ls->linenumber != ls->fs->lastsetline) { | ||
| 376 | code_oparg(ls, SETLINE, 0, ls->linenumber, 0); | ||
| 377 | ls->fs->lastsetline = ls->linenumber; | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | |||
| 382 | static void adjuststack (LexState *ls, int n) { | ||
| 383 | if (n > 0) | ||
| 384 | code_oparg(ls, POP, 2, n-1, -n); | ||
| 385 | else if (n < 0) | ||
| 386 | code_oparg(ls, PUSHNIL, 1, (-n)-1, -n); | ||
| 387 | } | ||
| 388 | |||
| 389 | |||
| 390 | static void close_exp (LexState *ls, int pc, int nresults) { | ||
| 391 | if (pc > 0) { /* expression is an open function call */ | ||
| 392 | Byte *code = ls->fs->f->code; | ||
| 393 | int nparams = code[pc]; /* save nparams */ | ||
| 394 | pc += fix_opcode(ls, pc-2, CALLFUNC, 2, nresults); | ||
| 395 | code[pc] = nparams; /* restore nparams */ | ||
| 396 | if (nresults != MULT_RET) | ||
| 397 | deltastack(ls, nresults); /* "push" results */ | ||
| 398 | deltastack(ls, -(nparams+1)); /* "pop" params and function */ | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | |||
| 403 | static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { | ||
| 404 | int diff = d->n - nvars; | ||
| 405 | if (d->pc == 0) { /* list is closed */ | ||
| 406 | /* push or pop eventual difference between list lengths */ | ||
| 407 | adjuststack(ls, diff); | ||
| 408 | } | ||
| 409 | else { /* must correct function call */ | ||
| 410 | diff--; /* do not count function call itself */ | ||
| 411 | if (diff < 0) { /* more variables than values */ | ||
| 412 | /* function call must provide extra values */ | ||
| 413 | close_exp(ls, d->pc, -diff); | ||
| 414 | } | ||
| 415 | else { /* more values than variables */ | ||
| 416 | close_exp(ls, d->pc, 0); /* call should provide no value */ | ||
| 417 | adjuststack(ls, diff); /* pop eventual extra values */ | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | |||
| 423 | static void code_args (LexState *ls, int nparams, int dots) { | ||
| 424 | FuncState *fs = ls->fs; | ||
| 425 | fs->nlocalvar += nparams; /* "self" may already be there */ | ||
| 426 | nparams = fs->nlocalvar; | ||
| 427 | if (!dots) { | ||
| 428 | fs->f->code[1] = nparams; /* fill-in arg information */ | ||
| 429 | deltastack(ls, nparams); | ||
| 430 | } | ||
| 431 | else { | ||
| 432 | fs->f->code[1] = nparams+ZEROVARARG; | ||
| 433 | deltastack(ls, nparams+1); | ||
| 434 | add_localvar(ls, luaS_new("arg")); | ||
| 435 | } | ||
| 436 | } | ||
| 437 | |||
| 438 | |||
| 439 | static void lua_pushvar (LexState *ls, vardesc *var) { | ||
| 440 | switch (var->k) { | ||
| 441 | case VLOCAL: | ||
| 442 | code_oparg(ls, PUSHLOCAL, 8, var->info, 1); | ||
| 443 | break; | ||
| 444 | case VGLOBAL: | ||
| 445 | code_oparg(ls, GETGLOBAL, 8, var->info, 1); | ||
| 446 | break; | ||
| 447 | case VDOT: | ||
| 448 | code_oparg(ls, GETDOTTED, 8, var->info, 0); | ||
| 449 | break; | ||
| 450 | case VINDEXED: | ||
| 451 | code_opcode(ls, GETTABLE, -1); | ||
| 452 | break; | ||
| 453 | case VEXP: | ||
| 454 | close_exp(ls, var->info, 1); /* function must return 1 value */ | ||
| 455 | break; | ||
| 456 | } | ||
| 457 | var->k = VEXP; | ||
| 458 | var->info = 0; /* now this is a closed expression */ | ||
| 459 | } | ||
| 460 | |||
| 461 | |||
| 462 | static void storevar (LexState *ls, vardesc *var) { | ||
| 463 | switch (var->k) { | ||
| 464 | case VLOCAL: | ||
| 465 | code_oparg(ls, SETLOCAL, 8, var->info, -1); | ||
| 466 | break; | ||
| 467 | case VGLOBAL: | ||
| 468 | code_oparg(ls, SETGLOBAL, 8, var->info, -1); | ||
| 469 | break; | ||
| 470 | case VINDEXED: | ||
| 471 | code_opcode(ls, SETTABLE0, -3); | ||
| 472 | break; | ||
| 473 | default: | ||
| 474 | LUA_INTERNALERROR("invalid var kind to store"); | ||
| 475 | } | ||
| 476 | } | ||
| 477 | |||
| 478 | |||
| 479 | static int fix_jump (LexState *ls, int pc, OpCode op, int n) { | ||
| 480 | /* jump is relative to position following jump instruction */ | ||
| 481 | return fix_opcode(ls, pc, op, 0, n-(pc+JMPSIZE)); | ||
| 482 | } | ||
| 483 | |||
| 484 | |||
| 485 | static void fix_upjmp (LexState *ls, OpCode op, int pos) { | ||
| 486 | int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */ | ||
| 487 | if (delta > 255) delta++; | ||
| 488 | code_oparg(ls, op, 0, delta, 0); | ||
| 489 | } | ||
| 490 | |||
| 491 | |||
| 492 | static void codeIf (LexState *ls, int thenAdd, int elseAdd) { | ||
| 493 | FuncState *fs = ls->fs; | ||
| 494 | int elseinit = elseAdd+JMPSIZE; | ||
| 495 | if (fs->pc == elseinit) { /* no else part */ | ||
| 496 | fs->pc -= JMPSIZE; | ||
| 497 | elseinit = fs->pc; | ||
| 498 | } | ||
| 499 | else | ||
| 500 | elseinit += fix_jump(ls, elseAdd, JMP, fs->pc); | ||
| 501 | fix_jump(ls, thenAdd, IFFJMP, elseinit); | ||
| 502 | } | ||
| 503 | |||
| 504 | |||
| 505 | static void func_onstack (LexState *ls, FuncState *func) { | ||
| 506 | FuncState *fs = ls->fs; | ||
| 507 | int i; | ||
| 508 | int c = next_constant(fs); | ||
| 509 | ttype(&fs->f->consts[c]) = LUA_T_PROTO; | ||
| 510 | fs->f->consts[c].value.tf = func->f; | ||
| 511 | if (func->nupvalues == 0) | ||
| 512 | code_constant(ls, c); | ||
| 513 | else { | ||
| 514 | for (i=0; i<func->nupvalues; i++) | ||
| 515 | lua_pushvar(ls, &func->upvalues[i]); | ||
| 516 | code_oparg(ls, CLOSURE, 0, c, -func->nupvalues+1); | ||
| 517 | code_byte(fs, func->nupvalues); | ||
| 518 | } | ||
| 519 | } | ||
| 520 | |||
| 521 | |||
| 522 | static void init_state (LexState *ls, FuncState *fs, TaggedString *filename) { | ||
| 523 | TProtoFunc *f = luaF_newproto(); | ||
| 524 | fs->prev = ls->fs; /* linked list of funcstates */ | ||
| 525 | ls->fs = fs; | ||
| 526 | fs->stacksize = 0; | ||
| 527 | fs->maxstacksize = 0; | ||
| 528 | fs->nlocalvar = 0; | ||
| 529 | fs->nupvalues = 0; | ||
| 530 | fs->lastsetline = 0; | ||
| 531 | fs->f = f; | ||
| 532 | f->fileName = filename; | ||
| 533 | fs->pc = 0; | ||
| 534 | fs->maxcode = 0; | ||
| 535 | f->code = NULL; | ||
| 536 | fs->maxconsts = 0; | ||
| 537 | if (lua_debug) | ||
| 538 | fs->nvars = fs->maxvars = 0; | ||
| 539 | else | ||
| 540 | fs->maxvars = -1; /* flag no debug information */ | ||
| 541 | code_byte(fs, 0); /* to be filled with stacksize */ | ||
| 542 | code_byte(fs, 0); /* to be filled with arg information */ | ||
| 543 | } | ||
| 544 | |||
| 545 | |||
| 546 | static void close_func (LexState *ls) { | ||
| 547 | FuncState *fs = ls->fs; | ||
| 548 | TProtoFunc *f = fs->f; | ||
| 549 | code_opcode(ls, ENDCODE, 0); | ||
| 550 | f->code[0] = fs->maxstacksize; | ||
| 551 | f->code = luaM_reallocvector(f->code, fs->pc, Byte); | ||
| 552 | f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject); | ||
| 553 | if (fs->maxvars != -1) { /* debug information? */ | ||
| 554 | luaI_registerlocalvar(fs, NULL, -1); /* flag end of vector */ | ||
| 555 | f->locvars = luaM_reallocvector(f->locvars, fs->nvars, LocVar); | ||
| 556 | } | ||
| 557 | ls->fs = fs->prev; | ||
| 558 | } | ||
| 559 | |||
| 560 | |||
| 561 | |||
| 562 | static int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, DO, NAME, | ||
| 563 | LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';', EOS, ',', 0}; | ||
| 564 | |||
| 565 | static int is_in (int tok, int *toks) { | ||
| 566 | int *t = toks; | ||
| 567 | while (*t) { | ||
| 568 | if (*t == tok) | ||
| 569 | return t-toks; | ||
| 570 | t++; | ||
| 571 | } | ||
| 572 | return -1; | ||
| 573 | } | ||
| 574 | |||
| 575 | |||
| 576 | static void next (LexState *ls) { | ||
| 577 | ls->token = luaX_lex(ls); | ||
| 578 | } | ||
| 579 | |||
| 580 | |||
| 581 | static void error_expected (LexState *ls, int token) { | ||
| 582 | char buff[100], t[TOKEN_LEN]; | ||
| 583 | luaX_token2str(ls, token, t); | ||
| 584 | sprintf(buff, "`%s' expected", t); | ||
| 585 | luaX_error(ls, buff); | ||
| 586 | } | ||
| 587 | |||
| 588 | static void error_unmatched (LexState *ls, int what, int who, int where) { | ||
| 589 | if (where == ls->linenumber) | ||
| 590 | error_expected(ls, what); | ||
| 591 | else { | ||
| 592 | char buff[100]; | ||
| 593 | char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; | ||
| 594 | luaX_token2str(ls, what, t_what); | ||
| 595 | luaX_token2str(ls, who, t_who); | ||
| 596 | sprintf(buff, "`%s' expected (to close `%s' at line %d)", | ||
| 597 | t_what, t_who, where); | ||
| 598 | luaX_error(ls, buff); | ||
| 599 | } | ||
| 600 | } | ||
| 601 | |||
| 602 | static void check (LexState *ls, int c) { | ||
| 603 | if (ls->token != c) | ||
| 604 | error_expected(ls, c); | ||
| 605 | next(ls); | ||
| 606 | } | ||
| 607 | |||
| 608 | static void check_match (LexState *ls, int what, int who, int where) { | ||
| 609 | if (ls->token != what) | ||
| 610 | error_unmatched(ls, what, who, where); | ||
| 611 | check_debugline(ls); /* to 'mark' the 'what' */ | ||
| 612 | next(ls); | ||
| 613 | } | ||
| 614 | |||
| 615 | static TaggedString *checkname (LexState *ls) { | ||
| 616 | TaggedString *ts; | ||
| 617 | if (ls->token != NAME) | ||
| 618 | luaX_error(ls, "`NAME' expected"); | ||
| 619 | ts = ls->seminfo.ts; | ||
| 620 | next(ls); | ||
| 621 | return ts; | ||
| 622 | } | ||
| 623 | |||
| 624 | |||
| 625 | static int optional (LexState *ls, int c) { | ||
| 626 | if (ls->token == c) { | ||
| 627 | next(ls); | ||
| 628 | return 1; | ||
| 629 | } | ||
| 630 | else return 0; | ||
| 631 | } | ||
| 632 | |||
| 633 | |||
| 634 | TProtoFunc *luaY_parser (ZIO *z) { | ||
| 635 | struct LexState lexstate; | ||
| 636 | struct FuncState funcstate; | ||
| 637 | luaX_setinput(&lexstate, z); | ||
| 638 | init_state(&lexstate, &funcstate, luaS_new(zname(z))); | ||
| 639 | next(&lexstate); /* read first token */ | ||
| 640 | chunk(&lexstate); | ||
| 641 | if (lexstate.token != EOS) | ||
| 642 | luaX_error(&lexstate, "<eof> expected"); | ||
| 643 | close_func(&lexstate); | ||
| 644 | return funcstate.f; | ||
| 645 | } | ||
| 646 | |||
| 647 | |||
| 648 | |||
| 649 | /*============================================================*/ | ||
| 650 | /* GRAMAR RULES */ | ||
| 651 | /*============================================================*/ | ||
| 652 | |||
| 653 | static void chunk (LexState *ls) { | ||
| 654 | /* chunk -> statlist ret */ | ||
| 655 | statlist(ls); | ||
| 656 | ret(ls); | ||
| 657 | } | ||
| 658 | |||
| 659 | static void statlist (LexState *ls) { | ||
| 660 | /* statlist -> { stat [;] } */ | ||
| 661 | while (stat(ls)) { | ||
| 662 | LUA_ASSERT(ls->fs->stacksize == ls->fs->nlocalvar, | ||
| 663 | "stack size != # local vars"); | ||
| 664 | optional(ls, ';'); | ||
| 665 | } | ||
| 666 | } | ||
| 667 | |||
| 668 | static int stat (LexState *ls) { | ||
| 669 | int line = ls->linenumber; /* may be needed for error messages */ | ||
| 670 | FuncState *fs = ls->fs; | ||
| 671 | switch (ls->token) { | ||
| 672 | case IF: { /* stat -> IF ifpart END */ | ||
| 673 | next(ls); | ||
| 674 | ifpart(ls); | ||
| 675 | check_match(ls, END, IF, line); | ||
| 676 | return 1; | ||
| 677 | } | ||
| 678 | |||
| 679 | case WHILE: { /* stat -> WHILE cond DO block END */ | ||
| 680 | TProtoFunc *f = fs->f; | ||
| 681 | int while_init = fs->pc; | ||
| 682 | int cond_end, cond_size; | ||
| 683 | next(ls); | ||
| 684 | cond_end = cond(ls); | ||
| 685 | check(ls, DO); | ||
| 686 | block(ls); | ||
| 687 | check_match(ls, END, WHILE, line); | ||
| 688 | cond_size = cond_end-while_init; | ||
| 689 | check_pc(fs, cond_size); | ||
| 690 | memcpy(f->code+fs->pc, f->code+while_init, cond_size); | ||
| 691 | luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init); | ||
| 692 | while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size); | ||
| 693 | fix_upjmp(ls, IFTUPJMP, while_init); | ||
| 694 | return 1; | ||
| 695 | } | ||
| 696 | |||
| 697 | case DO: { /* stat -> DO block END */ | ||
| 698 | next(ls); | ||
| 699 | block(ls); | ||
| 700 | check_match(ls, END, DO, line); | ||
| 701 | return 1; | ||
| 702 | } | ||
| 703 | |||
| 704 | case REPEAT: { /* stat -> REPEAT block UNTIL exp1 */ | ||
| 705 | int repeat_init = fs->pc; | ||
| 706 | next(ls); | ||
| 707 | block(ls); | ||
| 708 | check_match(ls, UNTIL, REPEAT, line); | ||
| 709 | exp1(ls); | ||
| 710 | fix_upjmp(ls, IFFUPJMP, repeat_init); | ||
| 711 | deltastack(ls, -1); /* pops condition */ | ||
| 712 | return 1; | ||
| 713 | } | ||
| 714 | |||
| 715 | case FUNCTION: { /* stat -> FUNCTION funcname body */ | ||
| 716 | int needself; | ||
| 717 | vardesc v; | ||
| 718 | if (ls->fs->prev) /* inside other function? */ | ||
| 719 | return 0; | ||
| 720 | check_debugline(ls); | ||
| 721 | next(ls); | ||
| 722 | needself = funcname(ls, &v); | ||
| 723 | body(ls, needself, line); | ||
| 724 | storevar(ls, &v); | ||
| 725 | return 1; | ||
| 726 | } | ||
| 727 | |||
| 728 | case LOCAL: { /* stat -> LOCAL localnamelist decinit */ | ||
| 729 | listdesc d; | ||
| 730 | int nvars; | ||
| 731 | check_debugline(ls); | ||
| 732 | next(ls); | ||
| 733 | nvars = localnamelist(ls); | ||
| 734 | decinit(ls, &d); | ||
| 735 | ls->fs->nlocalvar += nvars; | ||
| 736 | adjust_mult_assign(ls, nvars, &d); | ||
| 737 | return 1; | ||
| 738 | } | ||
| 739 | |||
| 740 | case NAME: case '%': { /* stat -> func | ['%'] NAME assignment */ | ||
| 741 | vardesc v; | ||
| 742 | check_debugline(ls); | ||
| 743 | var_or_func(ls, &v); | ||
| 744 | if (v.k == VEXP) { /* stat -> func */ | ||
| 745 | if (v.info == 0) /* is just an upper value? */ | ||
| 746 | luaX_error(ls, "syntax error"); | ||
| 747 | close_exp(ls, v.info, 0); | ||
| 748 | } | ||
| 749 | else { | ||
| 750 | int left = assignment(ls, &v, 1); /* stat -> ['%'] NAME assignment */ | ||
| 751 | adjuststack(ls, left); /* remove eventual 'garbage' left on stack */ | ||
| 752 | } | ||
| 753 | return 1; | ||
| 754 | } | ||
| 755 | |||
| 756 | case RETURN: case ';': case ELSE: case ELSEIF: | ||
| 757 | case END: case UNTIL: case EOS: /* 'stat' follow */ | ||
| 758 | return 0; | ||
| 759 | |||
| 760 | default: | ||
| 761 | luaX_error(ls, "<statement> expected"); | ||
| 762 | return 0; /* to avoid warnings */ | ||
| 763 | } | ||
| 764 | } | ||
| 765 | |||
| 766 | static int SaveWord (LexState *ls) { | ||
| 767 | int res = ls->fs->pc; | ||
| 768 | check_pc(ls->fs, JMPSIZE); | ||
| 769 | ls->fs->pc += JMPSIZE; /* open space */ | ||
| 770 | return res; | ||
| 771 | } | ||
| 772 | |||
| 773 | static int SaveWordPop (LexState *ls) { | ||
| 774 | deltastack(ls, -1); /* pop condition */ | ||
| 775 | return SaveWord(ls); | ||
| 776 | } | ||
| 777 | |||
| 778 | static int cond (LexState *ls) { | ||
| 779 | /* cond -> exp1 */ | ||
| 780 | exp1(ls); | ||
| 781 | return SaveWordPop(ls); | ||
| 782 | } | ||
| 783 | |||
| 784 | static void block (LexState *ls) { | ||
| 785 | /* block -> chunk */ | ||
| 786 | FuncState *fs = ls->fs; | ||
| 787 | int nlocalvar = fs->nlocalvar; | ||
| 788 | chunk(ls); | ||
| 789 | adjuststack(ls, fs->nlocalvar - nlocalvar); | ||
| 790 | for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--) | ||
| 791 | luaI_unregisterlocalvar(fs, ls->linenumber); | ||
| 792 | } | ||
| 793 | |||
| 794 | static int funcname (LexState *ls, vardesc *v) { | ||
| 795 | /* funcname -> NAME [':' NAME | '.' NAME] */ | ||
| 796 | int needself = 0; | ||
| 797 | singlevar(ls, checkname(ls), v, 0); | ||
| 798 | if (ls->token == ':' || ls->token == '.') { | ||
| 799 | needself = (ls->token == ':'); | ||
| 800 | next(ls); | ||
| 801 | lua_pushvar(ls, v); | ||
| 802 | code_string(ls, checkname(ls)); | ||
| 803 | v->k = VINDEXED; | ||
| 804 | } | ||
| 805 | return needself; | ||
| 806 | } | ||
| 807 | |||
| 808 | static void body (LexState *ls, int needself, int line) { | ||
| 809 | /* body -> '(' parlist ')' chunk END */ | ||
| 810 | FuncState newfs; | ||
| 811 | init_state(ls, &newfs, ls->fs->f->fileName); | ||
| 812 | newfs.f->lineDefined = line; | ||
| 813 | check(ls, '('); | ||
| 814 | if (needself) | ||
| 815 | add_localvar(ls, luaS_new("self")); | ||
| 816 | parlist(ls); | ||
| 817 | check(ls, ')'); | ||
| 818 | chunk(ls); | ||
| 819 | check_match(ls, END, FUNCTION, line); | ||
| 820 | close_func(ls); | ||
| 821 | func_onstack(ls, &newfs); | ||
| 822 | } | ||
| 823 | |||
| 824 | static void ifpart (LexState *ls) { | ||
| 825 | /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ | ||
| 826 | int c = cond(ls); | ||
| 827 | int e; | ||
| 828 | check(ls, THEN); | ||
| 829 | block(ls); | ||
| 830 | e = SaveWord(ls); | ||
| 831 | switch (ls->token) { | ||
| 832 | case ELSE: | ||
| 833 | next(ls); | ||
| 834 | block(ls); | ||
| 835 | break; | ||
| 836 | |||
| 837 | case ELSEIF: | ||
| 838 | next(ls); | ||
| 839 | ifpart(ls); | ||
| 840 | break; | ||
| 841 | } | ||
| 842 | codeIf(ls, c, e); | ||
| 843 | } | ||
| 844 | |||
| 845 | static void ret (LexState *ls) { | ||
| 846 | /* ret -> [RETURN explist sc] */ | ||
| 847 | if (ls->token == RETURN) { | ||
| 848 | listdesc e; | ||
| 849 | check_debugline(ls); | ||
| 850 | next(ls); | ||
| 851 | explist(ls, &e); | ||
| 852 | close_exp(ls, e.pc, MULT_RET); | ||
| 853 | code_oparg(ls, RETCODE, 0, ls->fs->nlocalvar, 0); | ||
| 854 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ | ||
| 855 | optional(ls, ';'); | ||
| 856 | } | ||
| 857 | } | ||
| 858 | |||
| 859 | |||
| 860 | /* | ||
| 861 | ** For parsing expressions, we use a classic stack with priorities. | ||
| 862 | ** Each binary operator is represented by its index in "binop" + FIRSTBIN | ||
| 863 | ** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1. | ||
| 864 | */ | ||
| 865 | |||
| 866 | /* code of first binary operator */ | ||
| 867 | #define FIRSTBIN 2 | ||
| 868 | |||
| 869 | /* code for power operator (last operator) | ||
| 870 | ** '^' needs special treatment because it is right associative | ||
| 871 | */ | ||
| 872 | #define POW 13 | ||
| 873 | |||
| 874 | static int binop [] = {EQ, NE, '>', '<', LE, GE, CONC, | ||
| 875 | '+', '-', '*', '/', '^', 0}; | ||
| 876 | |||
| 877 | static int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6}; | ||
| 878 | |||
| 879 | static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP, | ||
| 880 | LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP}; | ||
| 881 | |||
| 882 | #define MAXOPS 20 | ||
| 883 | |||
| 884 | typedef struct { | ||
| 885 | int ops[MAXOPS]; | ||
| 886 | int top; | ||
| 887 | } stack_op; | ||
| 888 | |||
| 889 | |||
| 890 | static void exp1 (LexState *ls) { | ||
| 891 | vardesc v; | ||
| 892 | exp(ls, &v); | ||
| 893 | lua_pushvar(ls, &v); | ||
| 894 | if (is_in(ls->token, expfollow) < 0) | ||
| 895 | luaX_error(ls, "ill formed expression"); | ||
| 896 | } | ||
| 897 | |||
| 898 | |||
| 899 | static void exp (LexState *ls, vardesc *v) { | ||
| 900 | exp2(ls, v); | ||
| 901 | while (ls->token == AND || ls->token == OR) { | ||
| 902 | int is_and = (ls->token == AND); | ||
| 903 | int pc; | ||
| 904 | lua_pushvar(ls, v); | ||
| 905 | next(ls); | ||
| 906 | pc = SaveWordPop(ls); | ||
| 907 | exp2(ls, v); | ||
| 908 | lua_pushvar(ls, v); | ||
| 909 | fix_jump(ls, pc, (is_and?ONFJMP:ONTJMP), ls->fs->pc); | ||
| 910 | } | ||
| 911 | } | ||
| 912 | |||
| 913 | |||
| 914 | static void push (LexState *ls, stack_op *s, int op) { | ||
| 915 | if (s->top == MAXOPS) | ||
| 916 | luaX_error(ls, "expression too complex"); | ||
| 917 | s->ops[s->top++] = op; | ||
| 918 | } | ||
| 919 | |||
| 920 | |||
| 921 | static void prefix (LexState *ls, stack_op *s) { | ||
| 922 | while (ls->token == NOT || ls->token == '-') { | ||
| 923 | push(ls, s, ls->token==NOT?0:1); | ||
| 924 | next(ls); | ||
| 925 | } | ||
| 926 | } | ||
| 927 | |||
| 928 | static void pop_to (LexState *ls, stack_op *s, int prio) { | ||
| 929 | int op; | ||
| 930 | while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) { | ||
| 931 | code_opcode(ls, opcodes[op], op<FIRSTBIN?0:-1); | ||
| 932 | s->top--; | ||
| 933 | } | ||
| 934 | } | ||
| 935 | |||
| 936 | static void exp2 (LexState *ls, vardesc *v) { | ||
| 937 | stack_op s; | ||
| 938 | int op; | ||
| 939 | s.top = 0; | ||
| 940 | prefix(ls, &s); | ||
| 941 | simpleexp(ls, v); | ||
| 942 | while ((op = is_in(ls->token, binop)) >= 0) { | ||
| 943 | op += FIRSTBIN; | ||
| 944 | lua_pushvar(ls, v); | ||
| 945 | /* '^' is right associative, so must 'simulate' a higher priority */ | ||
| 946 | pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); | ||
| 947 | push(ls, &s, op); | ||
| 948 | next(ls); | ||
| 949 | prefix(ls, &s); | ||
| 950 | simpleexp(ls, v); | ||
| 951 | lua_pushvar(ls, v); | ||
| 952 | } | ||
| 953 | if (s.top > 0) { | ||
| 954 | lua_pushvar(ls, v); | ||
| 955 | pop_to(ls, &s, 0); | ||
| 956 | } | ||
| 957 | } | ||
| 958 | |||
| 959 | |||
| 960 | static void simpleexp (LexState *ls, vardesc *v) { | ||
| 961 | check_debugline(ls); | ||
| 962 | switch (ls->token) { | ||
| 963 | case '(': /* simpleexp -> '(' exp ')' */ | ||
| 964 | next(ls); | ||
| 965 | exp(ls, v); | ||
| 966 | check(ls, ')'); | ||
| 967 | break; | ||
| 968 | |||
| 969 | case NUMBER: /* simpleexp -> NUMBER */ | ||
| 970 | code_number(ls, ls->seminfo.r); | ||
| 971 | next(ls); | ||
| 972 | v->k = VEXP; v->info = 0; | ||
| 973 | break; | ||
| 974 | |||
| 975 | case STRING: /* simpleexp -> STRING */ | ||
| 976 | code_string(ls, ls->seminfo.ts); | ||
| 977 | next(ls); | ||
| 978 | v->k = VEXP; v->info = 0; | ||
| 979 | break; | ||
| 980 | |||
| 981 | case NIL: /* simpleexp -> NIL */ | ||
| 982 | adjuststack(ls, -1); | ||
| 983 | next(ls); | ||
| 984 | v->k = VEXP; v->info = 0; | ||
| 985 | break; | ||
| 986 | |||
| 987 | case '{': /* simpleexp -> constructor */ | ||
| 988 | constructor(ls); | ||
| 989 | v->k = VEXP; v->info = 0; | ||
| 990 | break; | ||
| 991 | |||
| 992 | case FUNCTION: { /* simpleexp -> FUNCTION body */ | ||
| 993 | int line = ls->linenumber; | ||
| 994 | next(ls); | ||
| 995 | body(ls, 0, line); | ||
| 996 | v->k = VEXP; v->info = 0; | ||
| 997 | break; | ||
| 998 | } | ||
| 999 | |||
| 1000 | case NAME: case '%': | ||
| 1001 | var_or_func(ls, v); | ||
| 1002 | break; | ||
| 1003 | |||
| 1004 | default: | ||
| 1005 | luaX_error(ls, "<expression> expected"); | ||
| 1006 | break; | ||
| 1007 | } | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | static void var_or_func (LexState *ls, vardesc *v) { | ||
| 1011 | /* var_or_func -> ['%'] NAME var_or_func_tail */ | ||
| 1012 | if (optional(ls, '%')) { /* upvalue? */ | ||
| 1013 | pushupvalue(ls, checkname(ls)); | ||
| 1014 | v->k = VEXP; | ||
| 1015 | v->info = 0; /* closed expression */ | ||
| 1016 | } | ||
| 1017 | else /* variable name */ | ||
| 1018 | singlevar(ls, checkname(ls), v, 0); | ||
| 1019 | var_or_func_tail(ls, v); | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | static void var_or_func_tail (LexState *ls, vardesc *v) { | ||
| 1023 | for (;;) { | ||
| 1024 | switch (ls->token) { | ||
| 1025 | case '.': /* var_or_func_tail -> '.' NAME */ | ||
| 1026 | next(ls); | ||
| 1027 | lua_pushvar(ls, v); /* 'v' must be on stack */ | ||
| 1028 | v->k = VDOT; | ||
| 1029 | v->info = string_constant(ls->fs, checkname(ls)); | ||
| 1030 | break; | ||
| 1031 | |||
| 1032 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ | ||
| 1033 | next(ls); | ||
| 1034 | lua_pushvar(ls, v); /* 'v' must be on stack */ | ||
| 1035 | exp1(ls); | ||
| 1036 | check(ls, ']'); | ||
| 1037 | v->k = VINDEXED; | ||
| 1038 | break; | ||
| 1039 | |||
| 1040 | case ':': /* var_or_func_tail -> ':' NAME funcparams */ | ||
| 1041 | next(ls); | ||
| 1042 | lua_pushvar(ls, v); /* 'v' must be on stack */ | ||
| 1043 | code_oparg(ls, PUSHSELF, 8, string_constant(ls->fs, checkname(ls)), 1); | ||
| 1044 | v->k = VEXP; | ||
| 1045 | v->info = funcparams(ls, 1); | ||
| 1046 | break; | ||
| 1047 | |||
| 1048 | case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ | ||
| 1049 | lua_pushvar(ls, v); /* 'v' must be on stack */ | ||
| 1050 | v->k = VEXP; | ||
| 1051 | v->info = funcparams(ls, 0); | ||
| 1052 | break; | ||
| 1053 | |||
| 1054 | default: return; /* should be follow... */ | ||
| 1055 | } | ||
| 1056 | } | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | static int funcparams (LexState *ls, int slf) { | ||
| 1060 | FuncState *fs = ls->fs; | ||
| 1061 | int nparams = 1; /* default value */ | ||
| 1062 | switch (ls->token) { | ||
| 1063 | case '(': { /* funcparams -> '(' explist ')' */ | ||
| 1064 | listdesc e; | ||
| 1065 | next(ls); | ||
| 1066 | explist(ls, &e); | ||
| 1067 | check(ls, ')'); | ||
| 1068 | close_exp(ls, e.pc, 1); | ||
| 1069 | nparams = e.n; | ||
| 1070 | break; | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | case '{': /* funcparams -> constructor */ | ||
| 1074 | constructor(ls); | ||
| 1075 | break; | ||
| 1076 | |||
| 1077 | case STRING: /* funcparams -> STRING */ | ||
| 1078 | next(ls); | ||
| 1079 | break; | ||
| 1080 | |||
| 1081 | default: | ||
| 1082 | luaX_error(ls, "function arguments expected"); | ||
| 1083 | break; | ||
| 1084 | } | ||
| 1085 | code_byte(fs, 0); /* save space for opcode */ | ||
| 1086 | code_byte(fs, 0); /* and nresult */ | ||
| 1087 | code_byte(fs, nparams+slf); | ||
| 1088 | return fs->pc-1; | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | static void explist (LexState *ls, listdesc *d) { | ||
| 1092 | switch (ls->token) { | ||
| 1093 | case ELSE: case ELSEIF: case END: case UNTIL: | ||
| 1094 | case EOS: case ';': case ')': | ||
| 1095 | d->pc = 0; | ||
| 1096 | d->n = 0; | ||
| 1097 | break; | ||
| 1098 | |||
| 1099 | default: | ||
| 1100 | explist1(ls, d); | ||
| 1101 | } | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | static void explist1 (LexState *ls, listdesc *d) { | ||
| 1105 | vardesc v; | ||
| 1106 | exp(ls, &v); | ||
| 1107 | d->n = 1; | ||
| 1108 | while (ls->token == ',') { | ||
| 1109 | d->n++; | ||
| 1110 | lua_pushvar(ls, &v); | ||
| 1111 | next(ls); | ||
| 1112 | exp(ls, &v); | ||
| 1113 | } | ||
| 1114 | if (v.k == VEXP) | ||
| 1115 | d->pc = v.info; | ||
| 1116 | else { | ||
| 1117 | lua_pushvar(ls, &v); | ||
| 1118 | d->pc = 0; | ||
| 1119 | } | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | static void parlist (LexState *ls) { | ||
| 1123 | int nparams = 0; | ||
| 1124 | int dots = 0; | ||
| 1125 | switch (ls->token) { | ||
| 1126 | case DOTS: /* parlist -> DOTS */ | ||
| 1127 | next(ls); | ||
| 1128 | dots = 1; | ||
| 1129 | break; | ||
| 1130 | |||
| 1131 | case NAME: /* parlist, tailparlist -> NAME [',' tailparlist] */ | ||
| 1132 | init: | ||
| 1133 | store_localvar(ls, checkname(ls), nparams++); | ||
| 1134 | if (ls->token == ',') { | ||
| 1135 | next(ls); | ||
| 1136 | switch (ls->token) { | ||
| 1137 | case DOTS: /* tailparlist -> DOTS */ | ||
| 1138 | next(ls); | ||
| 1139 | dots = 1; | ||
| 1140 | break; | ||
| 1141 | |||
| 1142 | case NAME: /* tailparlist -> NAME [',' tailparlist] */ | ||
| 1143 | goto init; | ||
| 1144 | |||
| 1145 | default: luaX_error(ls, "NAME or `...' expected"); | ||
| 1146 | } | ||
| 1147 | } | ||
| 1148 | break; | ||
| 1149 | |||
| 1150 | case ')': break; /* parlist -> empty */ | ||
| 1151 | |||
| 1152 | default: luaX_error(ls, "NAME or `...' expected"); | ||
| 1153 | } | ||
| 1154 | code_args(ls, nparams, dots); | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | static int localnamelist (LexState *ls) { | ||
| 1158 | /* localnamelist -> NAME {',' NAME} */ | ||
| 1159 | int i = 1; | ||
| 1160 | store_localvar(ls, checkname(ls), 0); | ||
| 1161 | while (ls->token == ',') { | ||
| 1162 | next(ls); | ||
| 1163 | store_localvar(ls, checkname(ls), i++); | ||
| 1164 | } | ||
| 1165 | return i; | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | static void decinit (LexState *ls, listdesc *d) { | ||
| 1169 | /* decinit -> ['=' explist1] */ | ||
| 1170 | if (ls->token == '=') { | ||
| 1171 | next(ls); | ||
| 1172 | explist1(ls, d); | ||
| 1173 | } | ||
| 1174 | else { | ||
| 1175 | d->n = 0; | ||
| 1176 | d->pc = 0; | ||
| 1177 | } | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | static int assignment (LexState *ls, vardesc *v, int nvars) { | ||
| 1181 | int left = 0; | ||
| 1182 | /* dotted variables <a.x> must be stored like regular indexed vars <a["x"]> */ | ||
| 1183 | if (v->k == VDOT) { | ||
| 1184 | code_constant(ls, v->info); | ||
| 1185 | v->k = VINDEXED; | ||
| 1186 | } | ||
| 1187 | if (ls->token == ',') { /* assignment -> ',' NAME assignment */ | ||
| 1188 | vardesc nv; | ||
| 1189 | next(ls); | ||
| 1190 | var_or_func(ls, &nv); | ||
| 1191 | if (nv.k == VEXP) | ||
| 1192 | luaX_error(ls, "syntax error"); | ||
| 1193 | left = assignment(ls, &nv, nvars+1); | ||
| 1194 | } | ||
| 1195 | else { /* assignment -> '=' explist1 */ | ||
| 1196 | listdesc d; | ||
| 1197 | check(ls, '='); | ||
| 1198 | explist1(ls, &d); | ||
| 1199 | adjust_mult_assign(ls, nvars, &d); | ||
| 1200 | } | ||
| 1201 | if (v->k != VINDEXED || left+(nvars-1) == 0) { | ||
| 1202 | /* global/local var or indexed var without values in between */ | ||
| 1203 | storevar(ls, v); | ||
| 1204 | } | ||
| 1205 | else { /* indexed var with values in between*/ | ||
| 1206 | code_oparg(ls, SETTABLE, 0, left+(nvars-1), -1); | ||
| 1207 | left += 2; /* table/index are not popped, because they aren't on top */ | ||
| 1208 | } | ||
| 1209 | return left; | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | static void constructor (LexState *ls) { | ||
| 1213 | /* constructor -> '{' part [';' part] '}' */ | ||
| 1214 | int line = ls->linenumber; | ||
| 1215 | int pc = SaveWord(ls); | ||
| 1216 | int nelems; | ||
| 1217 | constdesc cd; | ||
| 1218 | deltastack(ls, 1); | ||
| 1219 | check(ls, '{'); | ||
| 1220 | part(ls, &cd); | ||
| 1221 | nelems = cd.n; | ||
| 1222 | if (ls->token == ';') { | ||
| 1223 | constdesc other_cd; | ||
| 1224 | next(ls); | ||
| 1225 | part(ls, &other_cd); | ||
| 1226 | if (cd.k == other_cd.k) /* repeated parts? */ | ||
| 1227 | luaX_error(ls, "invalid constructor syntax"); | ||
| 1228 | nelems += other_cd.n; | ||
| 1229 | } | ||
| 1230 | check_match(ls, '}', '{', line); | ||
| 1231 | fix_opcode(ls, pc, CREATEARRAY, 2, nelems); | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | static void part (LexState *ls, constdesc *cd) { | ||
| 1235 | switch (ls->token) { | ||
| 1236 | case ';': case '}': /* part -> empty */ | ||
| 1237 | cd->n = 0; | ||
| 1238 | cd->k = ls->token; | ||
| 1239 | return; | ||
| 1240 | |||
| 1241 | case NAME: { | ||
| 1242 | vardesc v; | ||
| 1243 | exp(ls, &v); | ||
| 1244 | if (ls->token == '=') { | ||
| 1245 | switch (v.k) { | ||
| 1246 | case VGLOBAL: | ||
| 1247 | code_constant(ls, v.info); | ||
| 1248 | break; | ||
| 1249 | case VLOCAL: | ||
| 1250 | code_string(ls, ls->fs->localvar[v.info]); | ||
| 1251 | break; | ||
| 1252 | default: | ||
| 1253 | luaX_error(ls, "`=' unexpected"); | ||
| 1254 | } | ||
| 1255 | next(ls); | ||
| 1256 | exp1(ls); | ||
| 1257 | cd->n = recfields(ls); | ||
| 1258 | cd->k = 1; /* record */ | ||
| 1259 | } | ||
| 1260 | else { | ||
| 1261 | lua_pushvar(ls, &v); | ||
| 1262 | cd->n = listfields(ls); | ||
| 1263 | cd->k = 0; /* list */ | ||
| 1264 | } | ||
| 1265 | break; | ||
| 1266 | } | ||
| 1267 | |||
| 1268 | case '[': /* part -> recfield recfields */ | ||
| 1269 | recfield(ls); | ||
| 1270 | cd->n = recfields(ls); | ||
| 1271 | cd->k = 1; /* record */ | ||
| 1272 | break; | ||
| 1273 | |||
| 1274 | default: /* part -> exp1 listfields */ | ||
| 1275 | exp1(ls); | ||
| 1276 | cd->n = listfields(ls); | ||
| 1277 | cd->k = 0; /* list */ | ||
| 1278 | break; | ||
| 1279 | } | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | static int recfields (LexState *ls) { | ||
| 1283 | /* recfields -> { ',' recfield } [','] */ | ||
| 1284 | int n = 1; /* one has been read before */ | ||
| 1285 | while (ls->token == ',') { | ||
| 1286 | next(ls); | ||
| 1287 | if (ls->token == ';' || ls->token == '}') | ||
| 1288 | break; | ||
| 1289 | recfield(ls); | ||
| 1290 | n++; | ||
| 1291 | if (n%RFIELDS_PER_FLUSH == 0) | ||
| 1292 | flush_record(ls, RFIELDS_PER_FLUSH); | ||
| 1293 | } | ||
| 1294 | flush_record(ls, n%RFIELDS_PER_FLUSH); | ||
| 1295 | return n; | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | static int listfields (LexState *ls) { | ||
| 1299 | /* listfields -> { ',' exp1 } [','] */ | ||
| 1300 | int n = 1; /* one has been read before */ | ||
| 1301 | while (ls->token == ',') { | ||
| 1302 | next(ls); | ||
| 1303 | if (ls->token == ';' || ls->token == '}') | ||
| 1304 | break; | ||
| 1305 | exp1(ls); | ||
| 1306 | n++; | ||
| 1307 | if (n%LFIELDS_PER_FLUSH == 0) | ||
| 1308 | flush_list(ls, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); | ||
| 1309 | } | ||
| 1310 | flush_list(ls, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); | ||
| 1311 | return n; | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | static void recfield (LexState *ls) { | ||
| 1315 | /* recfield -> (NAME | '['exp1']') = exp1 */ | ||
| 1316 | switch (ls->token) { | ||
| 1317 | case NAME: | ||
| 1318 | code_string(ls, checkname(ls)); | ||
| 1319 | break; | ||
| 1320 | |||
| 1321 | case '[': | ||
| 1322 | next(ls); | ||
| 1323 | exp1(ls); | ||
| 1324 | check(ls, ']'); | ||
| 1325 | break; | ||
| 1326 | |||
| 1327 | default: luaX_error(ls, "NAME or `[' expected"); | ||
| 1328 | } | ||
| 1329 | check(ls, '='); | ||
| 1330 | exp1(ls); | ||
| 1331 | } | ||
| 1332 | |||
