diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-05-13 17:15:59 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-05-13 17:15:59 -0300 |
| commit | 6d268b0b00ae63e5d06aedc4fb3cec105123a565 (patch) | |
| tree | 26fac79b53bfd79a9351291427358eb2e89c7360 /lvm.c | |
| parent | c7677471918fa55095f4993484eb5805091364fd (diff) | |
| download | lua-6d268b0b00ae63e5d06aedc4fb3cec105123a565.tar.gz lua-6d268b0b00ae63e5d06aedc4fb3cec105123a565.tar.bz2 lua-6d268b0b00ae63e5d06aedc4fb3cec105123a565.zip | |
new semantics for "for" local variables
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 52 |
1 files changed, 27 insertions, 25 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.284 2003/04/03 13:35:34 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.285 2003/05/05 18:39:57 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -639,43 +639,45 @@ StkId luaV_execute (lua_State *L) { | |||
| 639 | } | 639 | } |
| 640 | } | 640 | } |
| 641 | case OP_FORLOOP: { | 641 | case OP_FORLOOP: { |
| 642 | lua_Number step, idx, limit; | 642 | lua_Number step = nvalue(ra+2); |
| 643 | lua_Number idx = nvalue(ra) + step; /* increment index */ | ||
| 644 | lua_Number limit = nvalue(ra+1); | ||
| 645 | if (step > 0 ? idx <= limit : idx >= limit) { | ||
| 646 | dojump(pc, GETARG_sBx(i)); /* jump back */ | ||
| 647 | setnvalue(ra, idx); /* update internal index... */ | ||
| 648 | setnvalue(ra+3, idx); /* ...and external index */ | ||
| 649 | } | ||
| 650 | break; | ||
| 651 | } | ||
| 652 | case OP_FORPREP: { | ||
| 653 | const TObject *init = ra; | ||
| 643 | const TObject *plimit = ra+1; | 654 | const TObject *plimit = ra+1; |
| 644 | const TObject *pstep = ra+2; | 655 | const TObject *pstep = ra+2; |
| 645 | if (!ttisnumber(ra)) | 656 | if (!tonumber(init, ra)) |
| 646 | luaG_runerror(L, "`for' initial value must be a number"); | 657 | luaG_runerror(L, "`for' initial value must be a number"); |
| 647 | if (!tonumber(plimit, ra+1)) | 658 | else if (!tonumber(plimit, ra+1)) |
| 648 | luaG_runerror(L, "`for' limit must be a number"); | 659 | luaG_runerror(L, "`for' limit must be a number"); |
| 649 | if (!tonumber(pstep, ra+2)) | 660 | else if (!tonumber(pstep, ra+2)) |
| 650 | luaG_runerror(L, "`for' step must be a number"); | 661 | luaG_runerror(L, "`for' step must be a number"); |
| 651 | step = nvalue(pstep); | 662 | setnvalue(ra, nvalue(ra) - nvalue(pstep)); |
| 652 | idx = nvalue(ra) + step; /* increment index */ | 663 | dojump(pc, GETARG_sBx(i)); |
| 653 | limit = nvalue(plimit); | ||
| 654 | if (step > 0 ? idx <= limit : idx >= limit) { | ||
| 655 | dojump(pc, GETARG_sBx(i)); /* jump back */ | ||
| 656 | chgnvalue(ra, idx); /* update index */ | ||
| 657 | } | ||
| 658 | break; | 664 | break; |
| 659 | } | 665 | } |
| 660 | case OP_TFORLOOP: { | 666 | case OP_TFORLOOP: { |
| 661 | int nvar = GETARG_C(i) + 1; | 667 | StkId cb = ra + 3; /* call base */ |
| 662 | StkId cb = ra + nvar + 2; /* call base */ | ||
| 663 | setobjs2s(cb, ra); | ||
| 664 | setobjs2s(cb+1, ra+1); | ||
| 665 | setobjs2s(cb+2, ra+2); | 668 | setobjs2s(cb+2, ra+2); |
| 669 | setobjs2s(cb+1, ra+1); | ||
| 670 | setobjs2s(cb, ra); | ||
| 666 | L->top = cb+3; /* func. + 2 args (state and index) */ | 671 | L->top = cb+3; /* func. + 2 args (state and index) */ |
| 667 | luaD_call(L, cb, nvar); | 672 | luaD_call(L, cb, GETARG_C(i)); |
| 668 | L->top = L->ci->top; | 673 | L->top = L->ci->top; |
| 669 | ra = XRA(i) + 2; /* final position of first result */ | 674 | cb = XRA(i) + 3; /* previous call may change the stack */ |
| 670 | cb = ra + nvar; | 675 | if (ttisnil(cb)) /* break loop? */ |
| 671 | do { /* move results to proper positions */ | ||
| 672 | nvar--; | ||
| 673 | setobjs2s(ra+nvar, cb+nvar); | ||
| 674 | } while (nvar > 0); | ||
| 675 | if (ttisnil(ra)) /* break loop? */ | ||
| 676 | pc++; /* skip jump (break loop) */ | 676 | pc++; /* skip jump (break loop) */ |
| 677 | else | 677 | else { |
| 678 | setobjs2s(cb-1, cb); /* save control variable */ | ||
| 678 | dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */ | 679 | dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */ |
| 680 | } | ||
| 679 | break; | 681 | break; |
| 680 | } | 682 | } |
| 681 | case OP_TFORPREP: { /* for compatibility only */ | 683 | case OP_TFORPREP: { /* for compatibility only */ |
