diff options
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 205 |
1 files changed, 102 insertions, 103 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.63 2000/03/03 18:53:17 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.64 2000/03/03 20:29:25 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,10 +23,11 @@ | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| 26 | ** check whether arbitrary limits fit in respective opcode types | 26 | ** check whether arbitrary limits fit into respective opcode types |
| 27 | */ | 27 | */ |
| 28 | #if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \ | 28 | #if MAXLOCALS > MAXARG_U || MAXUPVALUES > MAXARG_B || MAXVARSLH > MAXARG_B || \ |
| 29 | MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B | 29 | MAXPARAMS > MAXLOCALS || MAXSTACK > MAXARG_A || \ |
| 30 | LFIELDS_PER_FLUSH > MAXARG_B || MULT_RET > MAXARG_B | ||
| 30 | #error invalid limits | 31 | #error invalid limits |
| 31 | #endif | 32 | #endif |
| 32 | 33 | ||
| @@ -53,7 +54,7 @@ static void body (LexState *ls, int needself, int line); | |||
| 53 | static void chunk (LexState *ls); | 54 | static void chunk (LexState *ls); |
| 54 | static void constructor (LexState *ls); | 55 | static void constructor (LexState *ls); |
| 55 | static void expr (LexState *ls, expdesc *v); | 56 | static void expr (LexState *ls, expdesc *v); |
| 56 | static int exp1 (LexState *ls); | 57 | static void exp1 (LexState *ls); |
| 57 | 58 | ||
| 58 | 59 | ||
| 59 | static void next (LexState *ls) { | 60 | static void next (LexState *ls) { |
| @@ -256,9 +257,9 @@ static void pushupvalue (LexState *ls, TaggedString *n) { | |||
| 256 | } | 257 | } |
| 257 | 258 | ||
| 258 | 259 | ||
| 259 | static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { | 260 | static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { |
| 260 | int diff = d->n - nvars; | 261 | int diff = nexps - nvars; |
| 261 | if (d->n == 0 || !luaK_iscall(ls, d->info)) { /* list is empty or closed */ | 262 | if (nexps == 0 || !luaK_lastisopen(ls)) { /* list is empty or closed */ |
| 262 | /* push or pop eventual difference between list lengths */ | 263 | /* push or pop eventual difference between list lengths */ |
| 263 | luaK_adjuststack(ls, diff); | 264 | luaK_adjuststack(ls, diff); |
| 264 | } | 265 | } |
| @@ -266,10 +267,10 @@ static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { | |||
| 266 | diff--; /* do not count function call itself */ | 267 | diff--; /* do not count function call itself */ |
| 267 | if (diff <= 0) { /* more variables than values? */ | 268 | if (diff <= 0) { /* more variables than values? */ |
| 268 | /* function call must provide extra values */ | 269 | /* function call must provide extra values */ |
| 269 | luaK_setcallreturns(ls, d->info, -diff); | 270 | luaK_setcallreturns(ls, -diff); |
| 270 | } | 271 | } |
| 271 | else { /* more values than variables */ | 272 | else { /* more values than variables */ |
| 272 | luaK_setcallreturns(ls, d->info, 0); /* call should provide no value */ | 273 | luaK_setcallreturns(ls, 0); /* call should provide no value */ |
| 273 | luaK_adjuststack(ls, diff); /* pop eventual extra values */ | 274 | luaK_adjuststack(ls, diff); /* pop eventual extra values */ |
| 274 | } | 275 | } |
| 275 | } | 276 | } |
| @@ -310,7 +311,7 @@ static void func_onstack (LexState *ls, FuncState *func) { | |||
| 310 | TProtoFunc *f = ls->fs->f; | 311 | TProtoFunc *f = ls->fs->f; |
| 311 | int i; | 312 | int i; |
| 312 | for (i=0; i<func->nupvalues; i++) | 313 | for (i=0; i<func->nupvalues; i++) |
| 313 | luaK_2stack(ls, &func->upvalues[i]); | 314 | luaK_1tostack(ls, &func->upvalues[i]); |
| 314 | luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *, | 315 | luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *, |
| 315 | constantEM, MAXARG_A); | 316 | constantEM, MAXARG_A); |
| 316 | f->kproto[f->nkproto++] = func->f; | 317 | f->kproto[f->nkproto++] = func->f; |
| @@ -331,6 +332,7 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { | |||
| 331 | fs->f = f; | 332 | fs->f = f; |
| 332 | f->source = source; | 333 | f->source = source; |
| 333 | fs->pc = 0; | 334 | fs->pc = 0; |
| 335 | fs->lasttarget = 0; | ||
| 334 | f->code = NULL; | 336 | f->code = NULL; |
| 335 | f->maxstacksize = 0; | 337 | f->maxstacksize = 0; |
| 336 | f->numparams = 0; /* default for main chunk */ | 338 | f->numparams = 0; /* default for main chunk */ |
| @@ -380,57 +382,57 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) { | |||
| 380 | /*============================================================*/ | 382 | /*============================================================*/ |
| 381 | 383 | ||
| 382 | 384 | ||
| 383 | static void explist1 (LexState *ls, listdesc *d) { | 385 | static int explist1 (LexState *ls) { |
| 386 | /* explist1 -> expr { ',' expr } */ | ||
| 387 | int n = 1; /* at least one expression */ | ||
| 384 | expdesc v; | 388 | expdesc v; |
| 385 | expr(ls, &v); | 389 | expr(ls, &v); |
| 386 | d->n = 1; | ||
| 387 | while (ls->token == ',') { | 390 | while (ls->token == ',') { |
| 388 | d->n++; | 391 | luaK_1tostack(ls, &v); /* gets only 1 value from previous expression */ |
| 389 | luaK_2stack(ls, &v); | 392 | next(ls); /* skip comma */ |
| 390 | next(ls); | ||
| 391 | expr(ls, &v); | 393 | expr(ls, &v); |
| 394 | n++; | ||
| 392 | } | 395 | } |
| 393 | luaK_2stack(ls, &v); | 396 | luaK_tostack(ls, &v); |
| 394 | luaK_setcallreturns(ls, v.info, MULT_RET); /* default for explists */ | 397 | return n; |
| 395 | d->info = v.info; | ||
| 396 | } | 398 | } |
| 397 | 399 | ||
| 398 | 400 | ||
| 399 | static void explist (LexState *ls, listdesc *d) { | 401 | static int explist (LexState *ls) { |
| 402 | /* explist -> [ explist1 ] */ | ||
| 400 | switch (ls->token) { | 403 | switch (ls->token) { |
| 401 | case ELSE: case ELSEIF: case END: case UNTIL: | 404 | case ELSE: case ELSEIF: case END: case UNTIL: |
| 402 | case EOS: case ';': case ')': | 405 | case EOS: case ';': case ')': |
| 403 | d->n = 0; | 406 | return 0; /* empty list */ |
| 404 | break; | ||
| 405 | 407 | ||
| 406 | default: | 408 | default: |
| 407 | explist1(ls, d); | 409 | return explist1(ls); |
| 408 | } | 410 | } |
| 409 | } | 411 | } |
| 410 | 412 | ||
| 411 | 413 | ||
| 412 | static void funcparams (LexState *ls, int slf) { | 414 | static void funcargs (LexState *ls, int slf) { |
| 413 | FuncState *fs = ls->fs; | 415 | FuncState *fs = ls->fs; |
| 414 | int slevel = fs->stacksize - slf - 1; /* where is func in the stack */ | 416 | int slevel = fs->stacksize - slf - 1; /* where is func in the stack */ |
| 415 | switch (ls->token) { | 417 | switch (ls->token) { |
| 416 | case '(': { /* funcparams -> '(' explist ')' */ | 418 | case '(': { /* funcargs -> '(' explist ')' */ |
| 417 | int line = ls->linenumber; | 419 | int line = ls->linenumber; |
| 418 | listdesc e; | 420 | int nargs; |
| 419 | next(ls); | 421 | next(ls); |
| 420 | explist(ls, &e); | 422 | nargs = explist(ls); |
| 421 | check_match(ls, ')', '(', line); | 423 | check_match(ls, ')', '(', line); |
| 422 | #ifdef LUA_COMPAT_ARGRET | 424 | #ifdef LUA_COMPAT_ARGRET |
| 423 | if (e.n > 0) /* arg list is not empty? */ | 425 | if (nargs > 0) /* arg list is not empty? */ |
| 424 | luaK_setcallreturns(ls, e.pc, 1); /* last call returns only 1 value */ | 426 | luaK_setcallreturns(ls, 1); /* last call returns only 1 value */ |
| 425 | #endif | 427 | #endif |
| 426 | break; | 428 | break; |
| 427 | } | 429 | } |
| 428 | 430 | ||
| 429 | case '{': /* funcparams -> constructor */ | 431 | case '{': /* funcargs -> constructor */ |
| 430 | constructor(ls); | 432 | constructor(ls); |
| 431 | break; | 433 | break; |
| 432 | 434 | ||
| 433 | case STRING: /* funcparams -> STRING */ | 435 | case STRING: /* funcargs -> STRING */ |
| 434 | code_string(ls, ls->seminfo.ts); /* must use `seminfo' before `next' */ | 436 | code_string(ls, ls->seminfo.ts); /* must use `seminfo' before `next' */ |
| 435 | next(ls); | 437 | next(ls); |
| 436 | break; | 438 | break; |
| @@ -439,8 +441,8 @@ static void funcparams (LexState *ls, int slf) { | |||
| 439 | luaK_error(ls, "function arguments expected"); | 441 | luaK_error(ls, "function arguments expected"); |
| 440 | break; | 442 | break; |
| 441 | } | 443 | } |
| 442 | fs->stacksize = slevel; /* call will remove func and params */ | 444 | fs->stacksize = slevel; /* call will remove function and arguments */ |
| 443 | luaK_AB(ls, CALL, slevel, 0, 0); | 445 | luaK_AB(ls, CALL, slevel, MULT_RET, 0); |
| 444 | } | 446 | } |
| 445 | 447 | ||
| 446 | 448 | ||
| @@ -449,37 +451,34 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { | |||
| 449 | switch (ls->token) { | 451 | switch (ls->token) { |
| 450 | case '.': /* var_or_func_tail -> '.' NAME */ | 452 | case '.': /* var_or_func_tail -> '.' NAME */ |
| 451 | next(ls); | 453 | next(ls); |
| 452 | luaK_2stack(ls, v); /* `v' must be on stack */ | 454 | luaK_1tostack(ls, v); /* `v' must be on stack */ |
| 453 | luaK_kstr(ls, checkname(ls)); | 455 | luaK_kstr(ls, checkname(ls)); |
| 454 | v->k = VINDEXED; | 456 | v->k = VINDEXED; |
| 455 | v->info = NOJUMPS; | ||
| 456 | break; | 457 | break; |
| 457 | 458 | ||
| 458 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ | 459 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ |
| 459 | next(ls); | 460 | next(ls); |
| 460 | luaK_2stack(ls, v); /* `v' must be on stack */ | 461 | luaK_1tostack(ls, v); /* `v' must be on stack */ |
| 461 | v->k = VINDEXED; | 462 | v->k = VINDEXED; |
| 462 | v->info = exp1(ls); | 463 | exp1(ls); |
| 463 | check(ls, ']'); | 464 | check(ls, ']'); |
| 464 | break; | 465 | break; |
| 465 | 466 | ||
| 466 | case ':': { /* var_or_func_tail -> ':' NAME funcparams */ | 467 | case ':': { /* var_or_func_tail -> ':' NAME funcargs */ |
| 467 | int name; | 468 | int name; |
| 468 | next(ls); | 469 | next(ls); |
| 469 | name = checkname(ls); | 470 | name = checkname(ls); |
| 470 | luaK_2stack(ls, v); /* `v' must be on stack */ | 471 | luaK_1tostack(ls, v); /* `v' must be on stack */ |
| 471 | luaK_U(ls, PUSHSELF, name, 1); | 472 | luaK_U(ls, PUSHSELF, name, 1); |
| 472 | funcparams(ls, 1); | 473 | funcargs(ls, 1); |
| 473 | v->k = VEXP; | 474 | v->k = VEXP; |
| 474 | v->info = NOJUMPS; | ||
| 475 | break; | 475 | break; |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ | 478 | case '(': case STRING: case '{': /* var_or_func_tail -> funcargs */ |
| 479 | luaK_2stack(ls, v); /* `v' must be on stack */ | 479 | luaK_1tostack(ls, v); /* `v' must be on stack */ |
| 480 | funcparams(ls, 0); | 480 | funcargs(ls, 0); |
| 481 | v->k = VEXP; | 481 | v->k = VEXP; |
| 482 | v->info = NOJUMPS; | ||
| 483 | break; | 482 | break; |
| 484 | 483 | ||
| 485 | default: return; /* should be follow... */ | 484 | default: return; /* should be follow... */ |
| @@ -493,7 +492,6 @@ static void var_or_func (LexState *ls, expdesc *v) { | |||
| 493 | if (optional(ls, '%')) { /* upvalue? */ | 492 | if (optional(ls, '%')) { /* upvalue? */ |
| 494 | pushupvalue(ls, str_checkname(ls)); | 493 | pushupvalue(ls, str_checkname(ls)); |
| 495 | v->k = VEXP; | 494 | v->k = VEXP; |
| 496 | v->info = NOJUMPS; | ||
| 497 | } | 495 | } |
| 498 | else /* variable name */ | 496 | else /* variable name */ |
| 499 | singlevar(ls, str_checkname(ls), v, 0); | 497 | singlevar(ls, str_checkname(ls), v, 0); |
| @@ -593,7 +591,7 @@ static void constructor_part (LexState *ls, constdesc *cd) { | |||
| 593 | cd->k = 1; /* record */ | 591 | cd->k = 1; /* record */ |
| 594 | } | 592 | } |
| 595 | else { | 593 | else { |
| 596 | luaK_2stack(ls, &v); | 594 | luaK_tostack(ls, &v); |
| 597 | cd->n = listfields(ls); | 595 | cd->n = listfields(ls); |
| 598 | cd->k = 0; /* list */ | 596 | cd->k = 0; /* list */ |
| 599 | } | 597 | } |
| @@ -693,15 +691,13 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
| 693 | return; | 691 | return; |
| 694 | } | 692 | } |
| 695 | v->k = VEXP; | 693 | v->k = VEXP; |
| 696 | v->info = NOJUMPS; | ||
| 697 | } | 694 | } |
| 698 | 695 | ||
| 699 | 696 | ||
| 700 | static int exp1 (LexState *ls) { | 697 | static void exp1 (LexState *ls) { |
| 701 | expdesc v; | 698 | expdesc v; |
| 702 | expr(ls, &v); | 699 | expr(ls, &v); |
| 703 | luaK_2stack(ls, &v); | 700 | luaK_1tostack(ls, &v); |
| 704 | return v.info; | ||
| 705 | } | 701 | } |
| 706 | 702 | ||
| 707 | 703 | ||
| @@ -711,53 +707,54 @@ static int exp1 (LexState *ls) { | |||
| 711 | */ | 707 | */ |
| 712 | static int get_priority (int op, int *rp) { | 708 | static int get_priority (int op, int *rp) { |
| 713 | switch (op) { | 709 | switch (op) { |
| 714 | case AND: case OR: | 710 | |
| 715 | *rp = 1; return 1; | 711 | case '^': *rp = 8; return 9; /* right associative */ |
| 716 | case EQ: case NE: | 712 | |
| 717 | case '>': case '<': case LE: case GE: | ||
| 718 | *rp = 2; return 2; | ||
| 719 | case CONC: | ||
| 720 | *rp = 4; return 4; /* left associative (?) */ | ||
| 721 | case '+': case '-': | ||
| 722 | *rp = 5; return 5; | ||
| 723 | case '*': case '/': | ||
| 724 | *rp = 6; return 6; | ||
| 725 | #define UNARY_PRIORITY 7 | 713 | #define UNARY_PRIORITY 7 |
| 726 | case '^': | 714 | |
| 727 | *rp = 8; return 9; /* right associative */ | 715 | case '*': case '/': *rp = 6; return 6; |
| 728 | default: | 716 | |
| 729 | *rp = -1; return -1; | 717 | case '+': case '-': *rp = 5; return 5; |
| 718 | |||
| 719 | case CONC: *rp = 4; return 4; /* left associative (?) */ | ||
| 720 | |||
| 721 | case EQ: case NE: case '>': case '<': case LE: case GE: | ||
| 722 | *rp = 2; return 2; | ||
| 723 | |||
| 724 | case AND: case OR: *rp = 1; return 1; | ||
| 725 | |||
| 726 | default: *rp = -1; return -1; | ||
| 730 | } | 727 | } |
| 731 | } | 728 | } |
| 732 | 729 | ||
| 733 | 730 | ||
| 734 | /* | 731 | /* |
| 735 | ** expr -> simplexep | (NOT | '-') expr | expr binop expr | 732 | ** subexpr -> (simplexep | (NOT | '-') subexpr) { binop subexpr } |
| 736 | ** where `binop' is any binary operator with a priority higher than `limit' | 733 | ** where `binop' is any binary operator with a priority higher than `limit' |
| 737 | */ | 734 | */ |
| 738 | static void operator_expr (LexState *ls, expdesc *v, int limit) { | 735 | static void subexpr (LexState *ls, expdesc *v, int limit) { |
| 739 | int rp; | 736 | int rp; |
| 740 | if (ls->token == '-' || ls->token == NOT) { | 737 | if (ls->token == '-' || ls->token == NOT) { |
| 741 | int op = ls->token; /* operator */ | 738 | int op = ls->token; /* operator */ |
| 742 | next(ls); | 739 | next(ls); |
| 743 | operator_expr(ls, v, UNARY_PRIORITY); | 740 | subexpr(ls, v, UNARY_PRIORITY); |
| 744 | luaK_prefix(ls, op, v); | 741 | luaK_prefix(ls, op, v); |
| 745 | } | 742 | } |
| 746 | else simpleexp(ls, v); | 743 | else simpleexp(ls, v); |
| 747 | /* expand while following operators have a priority higher than `limit' */ | 744 | /* expand while operators have priorities higher than `limit' */ |
| 748 | while (get_priority(ls->token, &rp) > limit) { | 745 | while (get_priority(ls->token, &rp) > limit) { |
| 749 | int op = ls->token; /* operator */ | ||
| 750 | expdesc v2; | 746 | expdesc v2; |
| 751 | luaK_infix(ls, v); | 747 | int op = ls->token; /* current operator (with priority == `rp') */ |
| 752 | next(ls); | 748 | next(ls); |
| 753 | operator_expr(ls, &v2, rp); | 749 | luaK_infix(ls, op, v); |
| 750 | subexpr(ls, &v2, rp); /* read sub-expression with priority > `rp' */ | ||
| 754 | luaK_posfix(ls, op, v, &v2); | 751 | luaK_posfix(ls, op, v, &v2); |
| 755 | } | 752 | } |
| 756 | } | 753 | } |
| 757 | 754 | ||
| 758 | 755 | ||
| 759 | static void expr (LexState *ls, expdesc *v) { | 756 | static void expr (LexState *ls, expdesc *v) { |
| 760 | operator_expr(ls, v, -1); | 757 | subexpr(ls, v, -1); |
| 761 | } | 758 | } |
| 762 | 759 | ||
| 763 | /* }==================================================================== */ | 760 | /* }==================================================================== */ |
| @@ -775,7 +772,7 @@ static void block (LexState *ls) { | |||
| 775 | FuncState *fs = ls->fs; | 772 | FuncState *fs = ls->fs; |
| 776 | int nlocalvar = fs->nlocalvar; | 773 | int nlocalvar = fs->nlocalvar; |
| 777 | chunk(ls); | 774 | chunk(ls); |
| 778 | luaK_adjuststack(ls, fs->nlocalvar - nlocalvar); | 775 | luaK_adjuststack(ls, fs->nlocalvar - nlocalvar); /* remove local variables */ |
| 779 | for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--) | 776 | for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--) |
| 780 | luaI_unregisterlocalvar(ls, fs->lastsetline); | 777 | luaI_unregisterlocalvar(ls, fs->lastsetline); |
| 781 | } | 778 | } |
| @@ -793,12 +790,12 @@ static int assignment (LexState *ls, expdesc *v, int nvars) { | |||
| 793 | left = assignment(ls, &nv, nvars+1); | 790 | left = assignment(ls, &nv, nvars+1); |
| 794 | } | 791 | } |
| 795 | else { /* assignment -> '=' explist1 */ | 792 | else { /* assignment -> '=' explist1 */ |
| 796 | listdesc d; | 793 | int nexps;; |
| 797 | if (ls->token != '=') | 794 | if (ls->token != '=') |
| 798 | error_unexpected(ls); | 795 | error_unexpected(ls); |
| 799 | next(ls); | 796 | next(ls); |
| 800 | explist1(ls, &d); | 797 | nexps = explist1(ls); |
| 801 | adjust_mult_assign(ls, nvars, &d); | 798 | adjust_mult_assign(ls, nvars, nexps); |
| 802 | } | 799 | } |
| 803 | if (v->k != VINDEXED || left+(nvars-1) == 0) { | 800 | if (v->k != VINDEXED || left+(nvars-1) == 0) { |
| 804 | /* global/local var or indexed var without values in between */ | 801 | /* global/local var or indexed var without values in between */ |
| @@ -821,7 +818,8 @@ static void whilestat (LexState *ls, int line) { | |||
| 821 | /* whilestat -> WHILE exp1 DO block END */ | 818 | /* whilestat -> WHILE exp1 DO block END */ |
| 822 | Instruction buffer[MAX_WHILE_EXP]; | 819 | Instruction buffer[MAX_WHILE_EXP]; |
| 823 | FuncState *fs = ls->fs; | 820 | FuncState *fs = ls->fs; |
| 824 | int while_init = fs->pc; | 821 | int while_init = luaK_getlabel(ls); |
| 822 | int loopentry; /* point to jump to repeat the loop */ | ||
| 825 | int cond_size; | 823 | int cond_size; |
| 826 | int i; | 824 | int i; |
| 827 | next(ls); /* skip WHILE */ | 825 | next(ls); /* skip WHILE */ |
| @@ -836,20 +834,20 @@ static void whilestat (LexState *ls, int line) { | |||
| 836 | luaK_deltastack(ls, -1); | 834 | luaK_deltastack(ls, -1); |
| 837 | luaK_S(ls, JMP, 0, 0); /* initial jump to condition */ | 835 | luaK_S(ls, JMP, 0, 0); /* initial jump to condition */ |
| 838 | check(ls, DO); | 836 | check(ls, DO); |
| 837 | loopentry = luaK_getlabel(ls); | ||
| 839 | block(ls); | 838 | block(ls); |
| 840 | check_match(ls, END, WHILE, line); | 839 | check_match(ls, END, WHILE, line); |
| 841 | luaK_fixjump(ls, while_init, fs->pc); | 840 | luaK_fixjump(ls, while_init, luaK_getlabel(ls)); |
| 842 | /* copy condition to new position, and correct stack */ | 841 | /* copy condition to new position, and correct stack */ |
| 843 | for (i=0; i<cond_size; i++) luaK_primitivecode(ls, buffer[i]); | 842 | for (i=0; i<cond_size; i++) luaK_primitivecode(ls, buffer[i]); |
| 844 | luaK_deltastack(ls, 1); | 843 | luaK_deltastack(ls, 1); |
| 845 | luaK_fixjump(ls, luaK_S(ls, IFTJMP, 0, -1), while_init+1); | 844 | luaK_fixjump(ls, luaK_S(ls, IFTJMP, 0, -1), loopentry); |
| 846 | } | 845 | } |
| 847 | 846 | ||
| 848 | 847 | ||
| 849 | static void repeatstat (LexState *ls, int line) { | 848 | static void repeatstat (LexState *ls, int line) { |
| 850 | /* repeatstat -> REPEAT block UNTIL exp1 */ | 849 | /* repeatstat -> REPEAT block UNTIL exp1 */ |
| 851 | FuncState *fs = ls->fs; | 850 | int repeat_init = luaK_getlabel(ls); |
| 852 | int repeat_init = fs->pc; | ||
| 853 | next(ls); | 851 | next(ls); |
| 854 | block(ls); | 852 | block(ls); |
| 855 | check_match(ls, UNTIL, REPEAT, line); | 853 | check_match(ls, UNTIL, REPEAT, line); |
| @@ -870,28 +868,28 @@ static int localnamelist (LexState *ls) { | |||
| 870 | } | 868 | } |
| 871 | 869 | ||
| 872 | 870 | ||
| 873 | static void decinit (LexState *ls, listdesc *d) { | 871 | static int decinit (LexState *ls) { |
| 874 | /* decinit -> ['=' explist1] */ | 872 | /* decinit -> ['=' explist1] */ |
| 875 | if (ls->token == '=') { | 873 | if (ls->token == '=') { |
| 876 | next(ls); | 874 | next(ls); |
| 877 | explist1(ls, d); | 875 | return explist1(ls); |
| 878 | } | 876 | } |
| 879 | else | 877 | else |
| 880 | d->n = 0; | 878 | return 0; /* no initializations */ |
| 881 | } | 879 | } |
| 882 | 880 | ||
| 883 | 881 | ||
| 884 | static void localstat (LexState *ls) { | 882 | static void localstat (LexState *ls) { |
| 885 | /* stat -> LOCAL localnamelist decinit */ | 883 | /* stat -> LOCAL localnamelist decinit */ |
| 886 | FuncState *fs = ls->fs; | 884 | FuncState *fs = ls->fs; |
| 887 | listdesc d; | ||
| 888 | int nvars; | 885 | int nvars; |
| 886 | int nexps; | ||
| 889 | check_debugline(ls); | 887 | check_debugline(ls); |
| 890 | next(ls); | 888 | next(ls); |
| 891 | nvars = localnamelist(ls); | 889 | nvars = localnamelist(ls); |
| 892 | decinit(ls, &d); | 890 | nexps = decinit(ls); |
| 893 | adjustlocalvars(ls, nvars, fs->lastsetline); | 891 | adjustlocalvars(ls, nvars, fs->lastsetline); |
| 894 | adjust_mult_assign(ls, nvars, &d); | 892 | adjust_mult_assign(ls, nvars, nexps); |
| 895 | } | 893 | } |
| 896 | 894 | ||
| 897 | 895 | ||
| @@ -902,7 +900,7 @@ static int funcname (LexState *ls, expdesc *v) { | |||
| 902 | if (ls->token == ':' || ls->token == '.') { | 900 | if (ls->token == ':' || ls->token == '.') { |
| 903 | needself = (ls->token == ':'); | 901 | needself = (ls->token == ':'); |
| 904 | next(ls); | 902 | next(ls); |
| 905 | luaK_2stack(ls, v); | 903 | luaK_1tostack(ls, v); |
| 906 | luaK_kstr(ls, checkname(ls)); | 904 | luaK_kstr(ls, checkname(ls)); |
| 907 | v->k = VINDEXED; | 905 | v->k = VINDEXED; |
| 908 | } | 906 | } |
| @@ -931,9 +929,9 @@ static void namestat (LexState *ls) { | |||
| 931 | check_debugline(ls); | 929 | check_debugline(ls); |
| 932 | var_or_func(ls, &v); | 930 | var_or_func(ls, &v); |
| 933 | if (v.k == VEXP) { /* stat -> func */ | 931 | if (v.k == VEXP) { /* stat -> func */ |
| 934 | if (!luaK_iscall(ls, v.info)) /* is just an upvalue? */ | 932 | if (!luaK_lastisopen(ls)) /* is just an upvalue? */ |
| 935 | luaK_error(ls, "syntax error"); | 933 | luaK_error(ls, "syntax error"); |
| 936 | luaK_setcallreturns(ls, v.info, 0); /* call statement uses no results */ | 934 | luaK_setcallreturns(ls, 0); /* call statement uses no results */ |
| 937 | } | 935 | } |
| 938 | else { /* stat -> ['%'] NAME assignment */ | 936 | else { /* stat -> ['%'] NAME assignment */ |
| 939 | int left = assignment(ls, &v, 1); | 937 | int left = assignment(ls, &v, 1); |
| @@ -950,11 +948,11 @@ static void ifpart (LexState *ls, int line) { | |||
| 950 | int elseinit; | 948 | int elseinit; |
| 951 | next(ls); /* skip IF or ELSEIF */ | 949 | next(ls); /* skip IF or ELSEIF */ |
| 952 | exp1(ls); /* cond */ | 950 | exp1(ls); /* cond */ |
| 953 | c = luaK_S(ls, IFFJMP, 0, -1); /* jump `then' if `cond' is false */ | 951 | c = luaK_S(ls, IFFJMP, 0, -1); /* jump over `then' part if `cond' is false */ |
| 954 | check(ls, THEN); | 952 | check(ls, THEN); |
| 955 | block(ls); /* `then' part */ | 953 | block(ls); /* `then' part */ |
| 956 | je = luaK_S(ls, JMP, 0, 0); /* jump `else' part after `then' */ | 954 | je = luaK_S(ls, JMP, 0, 0); /* jump over `else' part after `then' */ |
| 957 | elseinit = fs->pc; | 955 | elseinit = luaK_getlabel(ls); |
| 958 | if (ls->token == ELSEIF) | 956 | if (ls->token == ELSEIF) |
| 959 | ifpart(ls, line); | 957 | ifpart(ls, line); |
| 960 | else { | 958 | else { |
| @@ -962,14 +960,15 @@ static void ifpart (LexState *ls, int line) { | |||
| 962 | block(ls); /* `else' part */ | 960 | block(ls); /* `else' part */ |
| 963 | check_match(ls, END, IF, line); | 961 | check_match(ls, END, IF, line); |
| 964 | } | 962 | } |
| 965 | if (fs->pc > elseinit) /* is there an `else' part? */ | 963 | if (fs->pc > elseinit) { /* is there an `else' part? */ |
| 966 | luaK_fixjump(ls, je, fs->pc); /* last jump jumps over it */ | 964 | luaK_fixjump(ls, je, luaK_getlabel(ls)); /* last jump jumps over it */ |
| 967 | else { | 965 | luaK_fixjump(ls, c, elseinit); /* fix first jump to `else' part */ |
| 966 | } | ||
| 967 | else { /* no else part */ | ||
| 968 | fs->pc--; /* remove last jump */ | 968 | fs->pc--; /* remove last jump */ |
| 969 | elseinit--; /* first jump will be smaller */ | ||
| 970 | LUA_ASSERT(L, fs->pc == je, "jump out of place"); | 969 | LUA_ASSERT(L, fs->pc == je, "jump out of place"); |
| 970 | luaK_fixjump(ls, c, luaK_getlabel(ls)); /* fix first jump to `if' end */ | ||
| 971 | } | 971 | } |
| 972 | luaK_fixjump(ls, c, elseinit); /* fix first jump to `else' part */ | ||
| 973 | } | 972 | } |
| 974 | 973 | ||
| 975 | 974 | ||
| @@ -1073,11 +1072,11 @@ static void body (LexState *ls, int needself, int line) { | |||
| 1073 | static void ret (LexState *ls) { | 1072 | static void ret (LexState *ls) { |
| 1074 | /* ret -> [RETURN explist sc] */ | 1073 | /* ret -> [RETURN explist sc] */ |
| 1075 | if (ls->token == RETURN) { | 1074 | if (ls->token == RETURN) { |
| 1076 | listdesc e; | 1075 | int nexps; /* number of expressions returned */ |
| 1077 | check_debugline(ls); | 1076 | check_debugline(ls); |
| 1078 | next(ls); | 1077 | next(ls); |
| 1079 | explist(ls, &e); | 1078 | nexps = explist(ls); |
| 1080 | luaK_retcode(ls, ls->fs->nlocalvar, &e); | 1079 | luaK_retcode(ls, ls->fs->nlocalvar, nexps); |
| 1081 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ | 1080 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ |
| 1082 | optional(ls, ';'); | 1081 | optional(ls, ';'); |
| 1083 | } | 1082 | } |
