aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-04 17:18:15 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-04 17:18:15 -0300
commit563de491be90601f23a735aede89ea9a3ef86ee9 (patch)
treec92677f388289ead55c8a8778493b0af7e41f159 /lparser.c
parent29e01934253adf5fbf43faff81d87d7470cef8ce (diff)
downloadlua-563de491be90601f23a735aede89ea9a3ef86ee9.tar.gz
lua-563de491be90601f23a735aede89ea9a3ef86ee9.tar.bz2
lua-563de491be90601f23a735aede89ea9a3ef86ee9.zip
a better way to control optimizations.
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c205
1 files changed, 102 insertions, 103 deletions
diff --git a/lparser.c b/lparser.c
index e39f77b0..4c1eeb80 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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);
53static void chunk (LexState *ls); 54static void chunk (LexState *ls);
54static void constructor (LexState *ls); 55static void constructor (LexState *ls);
55static void expr (LexState *ls, expdesc *v); 56static void expr (LexState *ls, expdesc *v);
56static int exp1 (LexState *ls); 57static void exp1 (LexState *ls);
57 58
58 59
59static void next (LexState *ls) { 60static void next (LexState *ls) {
@@ -256,9 +257,9 @@ static void pushupvalue (LexState *ls, TaggedString *n) {
256} 257}
257 258
258 259
259static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { 260static 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
383static void explist1 (LexState *ls, listdesc *d) { 385static 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
399static void explist (LexState *ls, listdesc *d) { 401static 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
412static void funcparams (LexState *ls, int slf) { 414static 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
700static int exp1 (LexState *ls) { 697static 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*/
712static int get_priority (int op, int *rp) { 708static 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*/
738static void operator_expr (LexState *ls, expdesc *v, int limit) { 735static 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
759static void expr (LexState *ls, expdesc *v) { 756static 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
849static void repeatstat (LexState *ls, int line) { 848static 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
873static void decinit (LexState *ls, listdesc *d) { 871static 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
884static void localstat (LexState *ls) { 882static 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) {
1073static void ret (LexState *ls) { 1072static 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 }