diff options
| -rw-r--r-- | lcode.c | 38 | ||||
| -rw-r--r-- | lgc.c | 11 | ||||
| -rw-r--r-- | lopcodes.h | 4 | ||||
| -rw-r--r-- | lparser.c | 416 | ||||
| -rw-r--r-- | lvm.c | 25 |
5 files changed, 223 insertions, 271 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.32 2000/05/24 13:54:49 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.33 2000/05/24 18:04:17 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -69,16 +69,16 @@ static int luaK_getjump (FuncState *fs, int pc) { | |||
| 69 | 69 | ||
| 70 | 70 | ||
| 71 | /* | 71 | /* |
| 72 | ** discharge list of jumps to last target. | ||
| 73 | ** returns current `pc' and marks it as a jump target (to avoid wrong | 72 | ** returns current `pc' and marks it as a jump target (to avoid wrong |
| 74 | ** optimizations with consecutive instructions not in the same basic block). | 73 | ** optimizations with consecutive instructions not in the same basic block). |
| 74 | ** discharge list of jumps to last target. | ||
| 75 | */ | 75 | */ |
| 76 | int luaK_getlabel (FuncState *fs) { | 76 | int luaK_getlabel (FuncState *fs) { |
| 77 | if (fs->pc != fs->lasttarget) { | 77 | if (fs->pc != fs->lasttarget) { |
| 78 | int lasttarget = fs->lasttarget; | 78 | int lasttarget = fs->lasttarget; |
| 79 | fs->lasttarget = fs->pc; | 79 | fs->lasttarget = fs->pc; |
| 80 | luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */ | 80 | luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */ |
| 81 | fs->jlt = NO_JUMP; /* nobody jumps to this new label (till now) */ | 81 | fs->jlt = NO_JUMP; /* nobody jumps to this new label (yet) */ |
| 82 | } | 82 | } |
| 83 | return fs->pc; | 83 | return fs->pc; |
| 84 | } | 84 | } |
| @@ -86,7 +86,7 @@ int luaK_getlabel (FuncState *fs) { | |||
| 86 | 86 | ||
| 87 | void luaK_deltastack (FuncState *fs, int delta) { | 87 | void luaK_deltastack (FuncState *fs, int delta) { |
| 88 | fs->stacklevel += delta; | 88 | fs->stacklevel += delta; |
| 89 | if (delta > 0 && fs->stacklevel > fs->f->maxstacksize) { | 89 | if (fs->stacklevel > fs->f->maxstacksize) { |
| 90 | if (fs->stacklevel > MAXSTACK) | 90 | if (fs->stacklevel > MAXSTACK) |
| 91 | luaK_error(fs->ls, "function or expression too complex"); | 91 | luaK_error(fs->ls, "function or expression too complex"); |
| 92 | fs->f->maxstacksize = fs->stacklevel; | 92 | fs->f->maxstacksize = fs->stacklevel; |
| @@ -99,7 +99,7 @@ void luaK_kstr (LexState *ls, int c) { | |||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | 101 | ||
| 102 | static int real_constant (FuncState *fs, Number r) { | 102 | static int number_constant (FuncState *fs, Number r) { |
| 103 | /* check whether `r' has appeared within the last LOOKBACKNUMS entries */ | 103 | /* check whether `r' has appeared within the last LOOKBACKNUMS entries */ |
| 104 | Proto *f = fs->f; | 104 | Proto *f = fs->f; |
| 105 | int c = f->nknum; | 105 | int c = f->nknum; |
| @@ -116,17 +116,17 @@ static int real_constant (FuncState *fs, Number r) { | |||
| 116 | 116 | ||
| 117 | 117 | ||
| 118 | void luaK_number (FuncState *fs, Number f) { | 118 | void luaK_number (FuncState *fs, Number f) { |
| 119 | if (f <= (Number)MAXARG_S && (int)f == f) | 119 | if (f <= (Number)MAXARG_S && (Number)(int)f == f) |
| 120 | luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */ | 120 | luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */ |
| 121 | else | 121 | else |
| 122 | luaK_code1(fs, OP_PUSHNUM, real_constant(fs, f)); | 122 | luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f)); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | 125 | ||
| 126 | void luaK_adjuststack (FuncState *fs, int n) { | 126 | void luaK_adjuststack (FuncState *fs, int n) { |
| 127 | if (n > 0) | 127 | if (n > 0) |
| 128 | luaK_code1(fs, OP_POP, n); | 128 | luaK_code1(fs, OP_POP, n); |
| 129 | else if (n < 0) | 129 | else |
| 130 | luaK_code1(fs, OP_PUSHNIL, -n); | 130 | luaK_code1(fs, OP_PUSHNIL, -n); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| @@ -170,7 +170,7 @@ static int discharge (FuncState *fs, expdesc *var) { | |||
| 170 | 170 | ||
| 171 | static void discharge1 (FuncState *fs, expdesc *var) { | 171 | static void discharge1 (FuncState *fs, expdesc *var) { |
| 172 | discharge(fs, var); | 172 | discharge(fs, var); |
| 173 | /* if it has jumps it is already discharged */ | 173 | /* if it has jumps then it is already discharged */ |
| 174 | if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP) | 174 | if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP) |
| 175 | luaK_setcallreturns(fs, 1); /* call must return 1 value */ | 175 | luaK_setcallreturns(fs, 1); /* call must return 1 value */ |
| 176 | } | 176 | } |
| @@ -275,12 +275,10 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) { | |||
| 275 | discharge1(fs, v); | 275 | discharge1(fs, v); |
| 276 | previous = &fs->f->code[fs->pc-1]; | 276 | previous = &fs->f->code[fs->pc-1]; |
| 277 | LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "bad place to set line"); | 277 | LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "bad place to set line"); |
| 278 | if (ISJUMP(GET_OPCODE(*previous))) { | 278 | if (!ISJUMP(GET_OPCODE(*previous))) |
| 279 | if (invert) | ||
| 280 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); | ||
| 281 | } | ||
| 282 | else | ||
| 283 | luaK_code1(fs, jump, NO_JUMP); | 279 | luaK_code1(fs, jump, NO_JUMP); |
| 280 | else if (invert) | ||
| 281 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); | ||
| 284 | luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ | 282 | luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ |
| 285 | luaK_patchlist(fs, *golist, luaK_getlabel(fs)); | 283 | luaK_patchlist(fs, *golist, luaK_getlabel(fs)); |
| 286 | *golist = NO_JUMP; | 284 | *golist = NO_JUMP; |
| @@ -431,12 +429,17 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 431 | break; | 429 | break; |
| 432 | 430 | ||
| 433 | case OP_SETTABLE: | 431 | case OP_SETTABLE: |
| 432 | delta = -arg2; | ||
| 433 | break; | ||
| 434 | |||
| 434 | case OP_SETLIST: | 435 | case OP_SETLIST: |
| 436 | if (arg2 == 0) return NO_JUMP; /* nothing to do */ | ||
| 435 | delta = -arg2; | 437 | delta = -arg2; |
| 436 | break; | 438 | break; |
| 437 | 439 | ||
| 438 | case OP_SETMAP: | 440 | case OP_SETMAP: |
| 439 | delta = -2*(arg1+1); | 441 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ |
| 442 | delta = -2*arg1; | ||
| 440 | break; | 443 | break; |
| 441 | 444 | ||
| 442 | case OP_RETURN: | 445 | case OP_RETURN: |
| @@ -448,6 +451,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 448 | break; | 451 | break; |
| 449 | 452 | ||
| 450 | case OP_PUSHNIL: | 453 | case OP_PUSHNIL: |
| 454 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ | ||
| 451 | delta = arg1; | 455 | delta = arg1; |
| 452 | switch(GET_OPCODE(i)) { | 456 | switch(GET_OPCODE(i)) { |
| 453 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; | 457 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; |
| @@ -456,6 +460,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 456 | break; | 460 | break; |
| 457 | 461 | ||
| 458 | case OP_POP: | 462 | case OP_POP: |
| 463 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ | ||
| 459 | delta = -arg1; | 464 | delta = -arg1; |
| 460 | switch(GET_OPCODE(i)) { | 465 | switch(GET_OPCODE(i)) { |
| 461 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; | 466 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; |
| @@ -561,13 +566,14 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 561 | fs->f->code[fs->pc-1] = i; /* change previous instruction */ | 566 | fs->f->code[fs->pc-1] = i; /* change previous instruction */ |
| 562 | return fs->pc-1; /* do not generate new instruction */ | 567 | return fs->pc-1; /* do not generate new instruction */ |
| 563 | } | 568 | } |
| 569 | /* build new instruction */ | ||
| 564 | switch ((enum Mode)luaK_opproperties[o].mode) { | 570 | switch ((enum Mode)luaK_opproperties[o].mode) { |
| 565 | case iO: i = CREATE_0(o); break; | 571 | case iO: i = CREATE_0(o); break; |
| 566 | case iU: i = CREATE_U(o, arg1); break; | 572 | case iU: i = CREATE_U(o, arg1); break; |
| 567 | case iS: i = CREATE_S(o, arg1); break; | 573 | case iS: i = CREATE_S(o, arg1); break; |
| 568 | case iAB: i = CREATE_AB(o, arg1, arg2); break; | 574 | case iAB: i = CREATE_AB(o, arg1, arg2); break; |
| 569 | } | 575 | } |
| 570 | /* actually create the new instruction */ | 576 | /* put new instruction in code array */ |
| 571 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, | 577 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, |
| 572 | "code size overflow", MAX_INT); | 578 | "code size overflow", MAX_INT); |
| 573 | fs->f->code[fs->pc] = i; | 579 | fs->f->code[fs->pc] = i; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.52 2000/05/30 18:54:49 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.53 2000/05/30 19:00:31 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -34,10 +34,15 @@ static void protomark (lua_State *L, Proto *f) { | |||
| 34 | int i; | 34 | int i; |
| 35 | f->marked = 1; | 35 | f->marked = 1; |
| 36 | strmark(L, f->source); | 36 | strmark(L, f->source); |
| 37 | for (i=f->nkstr-1; i>=0; i--) | 37 | for (i=0; i<f->nkstr; i++) |
| 38 | strmark(L, f->kstr[i]); | 38 | strmark(L, f->kstr[i]); |
| 39 | for (i=f->nkproto-1; i>=0; i--) | 39 | for (i=0; i<f->nkproto; i++) |
| 40 | protomark(L, f->kproto[i]); | 40 | protomark(L, f->kproto[i]); |
| 41 | if (f->locvars) { /* is there debug information? */ | ||
| 42 | LocVar *lv; | ||
| 43 | for (lv=f->locvars; lv->line != -1; lv++) /* mark local-variable names */ | ||
| 44 | if (lv->varname) strmark(L, lv->varname); | ||
| 45 | } | ||
| 41 | } | 46 | } |
| 42 | } | 47 | } |
| 43 | 48 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.61 2000/05/15 19:48:04 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.62 2000/05/22 18:44:46 roberto Exp roberto $ |
| 3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -113,7 +113,7 @@ OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */ | |||
| 113 | OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ | 113 | OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ |
| 114 | 114 | ||
| 115 | OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */ | 115 | OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */ |
| 116 | OP_SETMAP,/* U v_u k_u - v_0 k_0 t t t[k_i]=v_i */ | 116 | OP_SETMAP,/* U v_u k_u - v_1 k_1 t t t[k_i]=v_i */ |
| 117 | 117 | ||
| 118 | OP_ADD,/* - y x x+y */ | 118 | OP_ADD,/* - y x x+y */ |
| 119 | OP_ADDI,/* S x x+s */ | 119 | OP_ADDI,/* S x x+s */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.92 2000/05/25 18:59:59 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.93 2000/05/30 19:00:31 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 | */ |
| @@ -11,7 +11,6 @@ | |||
| 11 | #define LUA_REENTRANT | 11 | #define LUA_REENTRANT |
| 12 | 12 | ||
| 13 | #include "lcode.h" | 13 | #include "lcode.h" |
| 14 | #include "ldo.h" | ||
| 15 | #include "lfunc.h" | 14 | #include "lfunc.h" |
| 16 | #include "llex.h" | 15 | #include "llex.h" |
| 17 | #include "lmem.h" | 16 | #include "lmem.h" |
| @@ -79,11 +78,6 @@ static void error_expected (LexState *ls, int token) { | |||
| 79 | } | 78 | } |
| 80 | 79 | ||
| 81 | 80 | ||
| 82 | static void error_unexpected (LexState *ls) { | ||
| 83 | luaK_error(ls, "unexpected token"); | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 87 | static void check (LexState *ls, int c) { | 81 | static void check (LexState *ls, int c) { |
| 88 | if (ls->t.token != c) | 82 | if (ls->t.token != c) |
| 89 | error_expected(ls, c); | 83 | error_expected(ls, c); |
| @@ -91,6 +85,11 @@ static void check (LexState *ls, int c) { | |||
| 91 | } | 85 | } |
| 92 | 86 | ||
| 93 | 87 | ||
| 88 | static void check_condition (LexState *ls, int c, const char *msg) { | ||
| 89 | if (!c) luaK_error(ls, msg); | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
| 94 | static void setline (LexState *ls) { | 93 | static void setline (LexState *ls) { |
| 95 | FuncState *fs = ls->fs; | 94 | FuncState *fs = ls->fs; |
| 96 | if (ls->L->debug && ls->linenumber != fs->lastsetline) { | 95 | if (ls->L->debug && ls->linenumber != fs->lastsetline) { |
| @@ -159,27 +158,17 @@ static void code_string (LexState *ls, TString *s) { | |||
| 159 | } | 158 | } |
| 160 | 159 | ||
| 161 | 160 | ||
| 162 | static int checkname (LexState *ls) { | ||
| 163 | int sc; | ||
| 164 | if (ls->t.token != TK_NAME) | ||
| 165 | luaK_error(ls, "<name> expected"); | ||
| 166 | sc = string_constant(ls->fs, ls->t.seminfo.ts); | ||
| 167 | next(ls); | ||
| 168 | return sc; | ||
| 169 | } | ||
| 170 | |||
| 171 | |||
| 172 | static TString *str_checkname (LexState *ls) { | 161 | static TString *str_checkname (LexState *ls) { |
| 173 | int i = checkname(ls); /* this call may realloc `f->kstr' */ | 162 | TString *ts; |
| 174 | return ls->fs->f->kstr[i]; | 163 | check_condition(ls, (ls->t.token == TK_NAME), "<name> expected"); |
| 164 | ts = ls->t.seminfo.ts; | ||
| 165 | next(ls); | ||
| 166 | return ts; | ||
| 175 | } | 167 | } |
| 176 | 168 | ||
| 177 | 169 | ||
| 178 | static TString *optionalname (LexState *ls) { | 170 | static int checkname (LexState *ls) { |
| 179 | if (ls->t.token == TK_NAME) | 171 | return string_constant(ls->fs, str_checkname(ls)); |
| 180 | return str_checkname(ls); | ||
| 181 | else | ||
| 182 | return NULL; | ||
| 183 | } | 172 | } |
| 184 | 173 | ||
| 185 | 174 | ||
| @@ -229,94 +218,90 @@ static void add_localvar (LexState *ls, const char *name) { | |||
| 229 | } | 218 | } |
| 230 | 219 | ||
| 231 | 220 | ||
| 232 | static int aux_localname (FuncState *fs, TString *n) { | 221 | static int search_local (LexState *ls, TString *n, expdesc *var) { |
| 233 | int i; | 222 | FuncState *fs; |
| 234 | for (i=fs->nlocalvar-1; i >= 0; i--) | 223 | int level = 0; |
| 235 | if (n == fs->localvar[i]) return i; /* local var index */ | 224 | for (fs=ls->fs; fs; fs=fs->prev) { |
| 236 | return -1; /* not found */ | 225 | int i; |
| 226 | for (i=fs->nlocalvar-1; i >= 0; i--) { | ||
| 227 | if (n == fs->localvar[i]) { | ||
| 228 | var->k = VLOCAL; | ||
| 229 | var->u.index = i; | ||
| 230 | return level; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | level++; /* `var' not found; check outer level */ | ||
| 234 | } | ||
| 235 | var->k = VGLOBAL; /* not found in any level; must be global */ | ||
| 236 | return -1; | ||
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | 239 | ||
| 240 | static void singlevar (LexState *ls, TString *n, expdesc *var, int prev) { | 240 | static void singlevar (LexState *ls, TString *n, expdesc *var) { |
| 241 | FuncState *fs = prev ? ls->fs->prev : ls->fs; | 241 | int level = search_local(ls, n, var); |
| 242 | int i = aux_localname(fs, n); | 242 | if (level >= 1) /* neither local (0) nor global (-1)? */ |
| 243 | if (i >= 0) { /* local value? */ | 243 | luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); |
| 244 | var->k = VLOCAL; | 244 | else if (level == -1) /* global? */ |
| 245 | var->u.index = i; | 245 | var->u.index = string_constant(ls->fs, n); |
| 246 | } | ||
| 247 | else { | ||
| 248 | FuncState *level = fs; | ||
| 249 | while ((level = level->prev) != NULL) /* check shadowing */ | ||
| 250 | if (aux_localname(level, n) >= 0) | ||
| 251 | luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); | ||
| 252 | var->k = VGLOBAL; | ||
| 253 | var->u.index = string_constant(fs, n); | ||
| 254 | } | ||
| 255 | } | 246 | } |
| 256 | 247 | ||
| 257 | 248 | ||
| 258 | static int indexupvalue (LexState *ls, TString *n) { | 249 | static int indexupvalue (LexState *ls, expdesc *v) { |
| 259 | FuncState *fs = ls->fs; | 250 | FuncState *fs = ls->fs; |
| 260 | expdesc v; | ||
| 261 | int i; | 251 | int i; |
| 262 | singlevar(ls, n, &v, 1); | ||
| 263 | for (i=0; i<fs->nupvalues; i++) { | 252 | for (i=0; i<fs->nupvalues; i++) { |
| 264 | if (fs->upvalues[i].k == v.k && fs->upvalues[i].u.index == v.u.index) | 253 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.index == v->u.index) |
| 265 | return i; | 254 | return i; |
| 266 | } | 255 | } |
| 267 | /* new one */ | 256 | /* new one */ |
| 268 | ++(fs->nupvalues); | 257 | luaX_checklimit(ls, fs->nupvalues+1, MAXUPVALUES, "upvalues"); |
| 269 | luaX_checklimit(ls, fs->nupvalues, MAXUPVALUES, "upvalues"); | 258 | fs->upvalues[fs->nupvalues] = *v; |
| 270 | fs->upvalues[i] = v; /* i = fs->nupvalues - 1 */ | 259 | return fs->nupvalues++; |
| 271 | return i; | ||
| 272 | } | 260 | } |
| 273 | 261 | ||
| 274 | 262 | ||
| 275 | static void pushupvalue (LexState *ls, TString *n) { | 263 | static void pushupvalue (LexState *ls, TString *n) { |
| 276 | FuncState *fs = ls->fs; | 264 | FuncState *fs = ls->fs; |
| 277 | if (fs->prev == NULL) | 265 | expdesc v; |
| 278 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | 266 | int level = search_local(ls, n, &v); |
| 279 | if (aux_localname(ls->fs, n) >= 0) | 267 | if (level == -1) { /* global? */ |
| 280 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); | 268 | if (fs->prev == NULL) |
| 281 | luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, n)); | 269 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); |
| 270 | v.u.index = string_constant(fs->prev, n); | ||
| 271 | } | ||
| 272 | else if (level != 1) | ||
| 273 | luaX_syntaxerror(ls, | ||
| 274 | "upvalue must be global or local to immediately outer scope", n->str); | ||
| 275 | luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, &v)); | ||
| 282 | } | 276 | } |
| 283 | 277 | ||
| 284 | 278 | ||
| 285 | static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { | 279 | static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { |
| 286 | FuncState *fs = ls->fs; | 280 | FuncState *fs = ls->fs; |
| 287 | int diff = nexps - nvars; | 281 | int diff = nexps - nvars; |
| 288 | if (nexps == 0 || !luaK_lastisopen(fs)) { /* list is empty or closed */ | 282 | if (nexps > 0 && luaK_lastisopen(fs)) { /* list ends in a function call */ |
| 289 | /* push or pop eventual difference between list lengths */ | ||
| 290 | luaK_adjuststack(fs, diff); | ||
| 291 | } | ||
| 292 | else { /* list ends in a function call; must correct it */ | ||
| 293 | diff--; /* do not count function call itself */ | 283 | diff--; /* do not count function call itself */ |
| 294 | if (diff <= 0) { /* more variables than values? */ | 284 | if (diff <= 0) { /* more variables than values? */ |
| 295 | /* function call must provide extra values */ | 285 | luaK_setcallreturns(fs, -diff); /* function call provide extra values */ |
| 296 | luaK_setcallreturns(fs, -diff); | 286 | diff = 0; /* no more difference */ |
| 297 | } | 287 | } |
| 298 | else { /* more values than variables */ | 288 | else /* more values than variables */ |
| 299 | luaK_setcallreturns(fs, 0); /* call should provide no value */ | 289 | luaK_setcallreturns(fs, 0); /* call should provide no value */ |
| 300 | luaK_adjuststack(fs, diff); /* pop eventual extra values */ | ||
| 301 | } | ||
| 302 | } | 290 | } |
| 291 | /* push or pop eventual difference between list lengths */ | ||
| 292 | luaK_adjuststack(fs, diff); | ||
| 303 | } | 293 | } |
| 304 | 294 | ||
| 305 | 295 | ||
| 306 | static void code_args (LexState *ls, int nparams, int dots) { | 296 | static void code_params (LexState *ls, int nparams, int dots) { |
| 307 | FuncState *fs = ls->fs; | 297 | FuncState *fs = ls->fs; |
| 308 | nparams -= dots; /* do not count `...' as a parameter */ | ||
| 309 | adjustlocalvars(ls, nparams); | 298 | adjustlocalvars(ls, nparams); |
| 310 | luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); | 299 | luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); |
| 311 | nparams = fs->nlocalvar; /* `self' could be there already */ | 300 | fs->f->numparams = fs->nlocalvar; /* `self' could be there already */ |
| 312 | fs->f->numparams = nparams; | ||
| 313 | fs->f->is_vararg = dots; | 301 | fs->f->is_vararg = dots; |
| 314 | if (!dots) | 302 | if (dots) |
| 315 | luaK_deltastack(fs, nparams); | ||
| 316 | else { | ||
| 317 | luaK_deltastack(fs, nparams+1); | ||
| 318 | add_localvar(ls, "arg"); | 303 | add_localvar(ls, "arg"); |
| 319 | } | 304 | luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */ |
| 320 | } | 305 | } |
| 321 | 306 | ||
| 322 | 307 | ||
| @@ -336,21 +321,23 @@ static void leavebreak (FuncState *fs, Breaklabel *bl) { | |||
| 336 | } | 321 | } |
| 337 | 322 | ||
| 338 | 323 | ||
| 339 | static Breaklabel *findlabel (FuncState *fs, TString *name) { | 324 | static Breaklabel *findlabel (LexState *ls) { |
| 325 | FuncState *fs = ls->fs; | ||
| 340 | Breaklabel *bl; | 326 | Breaklabel *bl; |
| 327 | TString *label = (ls->t.token == TK_NAME) ? ls->t.seminfo.ts : NULL; | ||
| 341 | for (bl=fs->bl; bl; bl=bl->previous) { | 328 | for (bl=fs->bl; bl; bl=bl->previous) { |
| 342 | if (bl->label == name) | 329 | if (bl->label == label) { |
| 330 | if (label) next(ls); /* no errors; can skip optional label */ | ||
| 343 | return bl; | 331 | return bl; |
| 332 | } | ||
| 344 | } | 333 | } |
| 345 | if (name) /* label not found: choose appropriate error message */ | 334 | /* label not found */ |
| 346 | luaX_syntaxerror(fs->ls, "break not inside given label", name->str); | 335 | luaK_error(fs->ls, "invalid break"); |
| 347 | else | ||
| 348 | luaK_error(fs->ls, "break not inside while or repeat loop"); | ||
| 349 | return NULL; /* to avoid warnings */ | 336 | return NULL; /* to avoid warnings */ |
| 350 | } | 337 | } |
| 351 | 338 | ||
| 352 | 339 | ||
| 353 | static void func_onstack (LexState *ls, FuncState *func) { | 340 | static void pushclosure (LexState *ls, FuncState *func) { |
| 354 | FuncState *fs = ls->fs; | 341 | FuncState *fs = ls->fs; |
| 355 | Proto *f = fs->f; | 342 | Proto *f = fs->f; |
| 356 | int i; | 343 | int i; |
| @@ -363,7 +350,7 @@ static void func_onstack (LexState *ls, FuncState *func) { | |||
| 363 | } | 350 | } |
| 364 | 351 | ||
| 365 | 352 | ||
| 366 | static void init_state (LexState *ls, FuncState *fs, TString *source) { | 353 | static void open_func (LexState *ls, FuncState *fs, TString *source) { |
| 367 | Proto *f = luaF_newproto(ls->L); | 354 | Proto *f = luaF_newproto(ls->L); |
| 368 | fs->prev = ls->fs; /* linked list of funcstates */ | 355 | fs->prev = ls->fs; /* linked list of funcstates */ |
| 369 | fs->ls = ls; | 356 | fs->ls = ls; |
| @@ -410,13 +397,13 @@ Proto *luaY_parser (lua_State *L, ZIO *z) { | |||
| 410 | struct LexState lexstate; | 397 | struct LexState lexstate; |
| 411 | struct FuncState funcstate; | 398 | struct FuncState funcstate; |
| 412 | luaX_setinput(L, &lexstate, z); | 399 | luaX_setinput(L, &lexstate, z); |
| 413 | init_state(&lexstate, &funcstate, luaS_new(L, zname(z))); | 400 | open_func(&lexstate, &funcstate, luaS_new(L, zname(z))); |
| 414 | next(&lexstate); /* read first token */ | 401 | next(&lexstate); /* read first token */ |
| 415 | chunk(&lexstate); | 402 | chunk(&lexstate); |
| 416 | if (lexstate.t.token != TK_EOS) | 403 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); |
| 417 | luaK_error(&lexstate, "<eof> expected"); | ||
| 418 | close_func(&lexstate); | 404 | close_func(&lexstate); |
| 419 | LUA_ASSERT(L, funcstate.prev == NULL, "wrong list end"); | 405 | LUA_ASSERT(L, funcstate.prev == NULL, "wrong list end"); |
| 406 | LUA_ASSERT(L, funcstate.nupvalues == 0, "no upvalues in main"); | ||
| 420 | return funcstate.f; | 407 | return funcstate.f; |
| 421 | } | 408 | } |
| 422 | 409 | ||
| @@ -443,28 +430,16 @@ static int explist1 (LexState *ls) { | |||
| 443 | } | 430 | } |
| 444 | 431 | ||
| 445 | 432 | ||
| 446 | static int explist (LexState *ls) { | ||
| 447 | /* explist -> [ explist1 ] */ | ||
| 448 | switch (ls->t.token) { | ||
| 449 | case TK_NUMBER: case TK_STRING: case TK_NIL: case '{': | ||
| 450 | case TK_FUNCTION: case '(': case TK_NAME: case '%': | ||
| 451 | case TK_NOT: case '-': /* first `expr' */ | ||
| 452 | return explist1(ls); | ||
| 453 | default: | ||
| 454 | return 0; /* empty list */ | ||
| 455 | } | ||
| 456 | } | ||
| 457 | |||
| 458 | |||
| 459 | static void funcargs (LexState *ls, int slf) { | 433 | static void funcargs (LexState *ls, int slf) { |
| 460 | FuncState *fs = ls->fs; | 434 | FuncState *fs = ls->fs; |
| 461 | int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ | 435 | int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ |
| 462 | switch (ls->t.token) { | 436 | switch (ls->t.token) { |
| 463 | case '(': { /* funcargs -> '(' explist ')' */ | 437 | case '(': { /* funcargs -> '(' [ explist1 ] ')' */ |
| 464 | int line = ls->linenumber; | 438 | int line = ls->linenumber; |
| 465 | int nargs; | 439 | int nargs = 0; |
| 466 | next(ls); | 440 | next(ls); |
| 467 | nargs = explist(ls); | 441 | if (ls->t.token != ')') /* arg list not empty? */ |
| 442 | nargs = explist1(ls); | ||
| 468 | check_match(ls, ')', '(', line); | 443 | check_match(ls, ')', '(', line); |
| 469 | #ifdef LUA_COMPAT_ARGRET | 444 | #ifdef LUA_COMPAT_ARGRET |
| 470 | if (nargs > 0) /* arg list is not empty? */ | 445 | if (nargs > 0) /* arg list is not empty? */ |
| @@ -543,7 +518,7 @@ static void var_or_func (LexState *ls, expdesc *v) { | |||
| 543 | v->u.l.t = v->u.l.f = NO_JUMP; | 518 | v->u.l.t = v->u.l.f = NO_JUMP; |
| 544 | } | 519 | } |
| 545 | else /* variable name */ | 520 | else /* variable name */ |
| 546 | singlevar(ls, str_checkname(ls), v, 0); | 521 | singlevar(ls, str_checkname(ls), v); |
| 547 | var_or_func_tail(ls, v); | 522 | var_or_func_tail(ls, v); |
| 548 | } | 523 | } |
| 549 | 524 | ||
| @@ -580,7 +555,6 @@ static int recfields (LexState *ls) { | |||
| 580 | /* recfields -> recfield { ',' recfield } [','] */ | 555 | /* recfields -> recfield { ',' recfield } [','] */ |
| 581 | FuncState *fs = ls->fs; | 556 | FuncState *fs = ls->fs; |
| 582 | int n = 1; /* at least one element */ | 557 | int n = 1; /* at least one element */ |
| 583 | int mod_n = 1; /* mod_n == n%RFIELDS_PER_FLUSH */ | ||
| 584 | recfield(ls); | 558 | recfield(ls); |
| 585 | while (ls->t.token == ',') { | 559 | while (ls->t.token == ',') { |
| 586 | next(ls); | 560 | next(ls); |
| @@ -588,13 +562,10 @@ static int recfields (LexState *ls) { | |||
| 588 | break; | 562 | break; |
| 589 | recfield(ls); | 563 | recfield(ls); |
| 590 | n++; | 564 | n++; |
| 591 | if (++mod_n == RFIELDS_PER_FLUSH) { | 565 | if (n%RFIELDS_PER_FLUSH == 0) |
| 592 | luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH-1); | 566 | luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH); |
| 593 | mod_n = 0; | ||
| 594 | } | ||
| 595 | } | 567 | } |
| 596 | if (mod_n) | 568 | luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH); |
| 597 | luaK_code1(fs, OP_SETMAP, mod_n-1); | ||
| 598 | return n; | 569 | return n; |
| 599 | } | 570 | } |
| 600 | 571 | ||
| @@ -603,7 +574,6 @@ static int listfields (LexState *ls) { | |||
| 603 | /* listfields -> exp1 { ',' exp1 } [','] */ | 574 | /* listfields -> exp1 { ',' exp1 } [','] */ |
| 604 | FuncState *fs = ls->fs; | 575 | FuncState *fs = ls->fs; |
| 605 | int n = 1; /* at least one element */ | 576 | int n = 1; /* at least one element */ |
| 606 | int mod_n = 1; /* mod_n == n%LFIELDS_PER_FLUSH */ | ||
| 607 | exp1(ls); | 577 | exp1(ls); |
| 608 | while (ls->t.token == ',') { | 578 | while (ls->t.token == ',') { |
| 609 | next(ls); | 579 | next(ls); |
| @@ -613,13 +583,10 @@ static int listfields (LexState *ls) { | |||
| 613 | n++; | 583 | n++; |
| 614 | luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, | 584 | luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, |
| 615 | "`item groups' in a list initializer"); | 585 | "`item groups' in a list initializer"); |
| 616 | if (++mod_n == LFIELDS_PER_FLUSH) { | 586 | if (n%LFIELDS_PER_FLUSH == 0) |
| 617 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); | 587 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); |
| 618 | mod_n = 0; | ||
| 619 | } | ||
| 620 | } | 588 | } |
| 621 | if (mod_n > 0) | 589 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); |
| 622 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n); | ||
| 623 | return n; | 590 | return n; |
| 624 | } | 591 | } |
| 625 | 592 | ||
| @@ -663,18 +630,15 @@ static void constructor (LexState *ls) { | |||
| 663 | check(ls, '{'); | 630 | check(ls, '{'); |
| 664 | constructor_part(ls, &cd); | 631 | constructor_part(ls, &cd); |
| 665 | nelems = cd.n; | 632 | nelems = cd.n; |
| 666 | if (ls->t.token == ';') { | 633 | if (optional(ls, ';')) { |
| 667 | Constdesc other_cd; | 634 | Constdesc other_cd; |
| 668 | next(ls); | ||
| 669 | constructor_part(ls, &other_cd); | 635 | constructor_part(ls, &other_cd); |
| 670 | if (cd.k == other_cd.k) /* repeated parts? */ | 636 | check_condition(ls, (cd.k != other_cd.k), "invalid constructor syntax"); |
| 671 | luaK_error(ls, "invalid constructor syntax"); | ||
| 672 | nelems += other_cd.n; | 637 | nelems += other_cd.n; |
| 673 | } | 638 | } |
| 674 | check_match(ls, '}', '{', line); | 639 | check_match(ls, '}', '{', line); |
| 675 | /* set initial table size */ | ||
| 676 | luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor"); | 640 | luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor"); |
| 677 | SETARG_U(fs->f->code[pc], nelems); | 641 | SETARG_U(fs->f->code[pc], nelems); /* set initial table size */ |
| 678 | } | 642 | } |
| 679 | 643 | ||
| 680 | /* }====================================================================== */ | 644 | /* }====================================================================== */ |
| @@ -811,6 +775,16 @@ static void expr (LexState *ls, expdesc *v) { | |||
| 811 | */ | 775 | */ |
| 812 | 776 | ||
| 813 | 777 | ||
| 778 | static int block_follow (int token) { | ||
| 779 | switch (token) { | ||
| 780 | case TK_ELSE: case TK_ELSEIF: case TK_END: | ||
| 781 | case TK_UNTIL: case TK_EOS: | ||
| 782 | return 1; | ||
| 783 | default: return 0; | ||
| 784 | } | ||
| 785 | } | ||
| 786 | |||
| 787 | |||
| 814 | static void block (LexState *ls) { | 788 | static void block (LexState *ls) { |
| 815 | /* block -> chunk */ | 789 | /* block -> chunk */ |
| 816 | FuncState *fs = ls->fs; | 790 | FuncState *fs = ls->fs; |
| @@ -822,21 +796,18 @@ static void block (LexState *ls) { | |||
| 822 | 796 | ||
| 823 | 797 | ||
| 824 | static int assignment (LexState *ls, expdesc *v, int nvars) { | 798 | static int assignment (LexState *ls, expdesc *v, int nvars) { |
| 825 | int left = 0; | 799 | int left = 0; /* number of values left in the stack after assignment */ |
| 826 | luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); | 800 | luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); |
| 827 | if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ | 801 | if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ |
| 828 | expdesc nv; | 802 | expdesc nv; |
| 829 | next(ls); | 803 | next(ls); |
| 830 | var_or_func(ls, &nv); | 804 | var_or_func(ls, &nv); |
| 831 | if (nv.k == VEXP) | 805 | check_condition(ls, (nv.k != VEXP), "syntax error"); |
| 832 | luaK_error(ls, "syntax error"); | ||
| 833 | left = assignment(ls, &nv, nvars+1); | 806 | left = assignment(ls, &nv, nvars+1); |
| 834 | } | 807 | } |
| 835 | else { /* assignment -> '=' explist1 */ | 808 | else { /* assignment -> '=' explist1 */ |
| 836 | int nexps;; | 809 | int nexps; |
| 837 | if (ls->t.token != '=') | 810 | check(ls, '='); |
| 838 | error_unexpected(ls); | ||
| 839 | next(ls); | ||
| 840 | nexps = explist1(ls); | 811 | nexps = explist1(ls); |
| 841 | adjust_mult_assign(ls, nvars, nexps); | 812 | adjust_mult_assign(ls, nvars, nexps); |
| 842 | } | 813 | } |
| @@ -850,16 +821,22 @@ static int assignment (LexState *ls, expdesc *v, int nvars) { | |||
| 850 | } | 821 | } |
| 851 | 822 | ||
| 852 | 823 | ||
| 824 | static void cond (LexState *ls, expdesc *v) { | ||
| 825 | /* cond -> exp */ | ||
| 826 | expr(ls, v); /* read condition */ | ||
| 827 | luaK_goiftrue(ls->fs, v, 0); | ||
| 828 | } | ||
| 829 | |||
| 830 | |||
| 853 | static void whilestat (LexState *ls, int line) { | 831 | static void whilestat (LexState *ls, int line) { |
| 854 | /* whilestat -> WHILE exp1 DO block END */ | 832 | /* whilestat -> WHILE cond DO block END */ |
| 855 | FuncState *fs = ls->fs; | 833 | FuncState *fs = ls->fs; |
| 856 | int while_init = luaK_getlabel(fs); | 834 | int while_init = luaK_getlabel(fs); |
| 857 | expdesc v; | 835 | expdesc v; |
| 858 | Breaklabel bl; | 836 | Breaklabel bl; |
| 859 | enterbreak(fs, &bl); | 837 | enterbreak(fs, &bl); |
| 860 | setline_and_next(ls); /* trace WHILE when looping */ | 838 | setline_and_next(ls); /* trace WHILE when looping */ |
| 861 | expr(ls, &v); /* read condition */ | 839 | cond(ls, &v); |
| 862 | luaK_goiftrue(fs, &v, 0); | ||
| 863 | check(ls, TK_DO); | 840 | check(ls, TK_DO); |
| 864 | block(ls); | 841 | block(ls); |
| 865 | luaK_patchlist(fs, luaK_jump(fs), while_init); | 842 | luaK_patchlist(fs, luaK_jump(fs), while_init); |
| @@ -870,7 +847,7 @@ static void whilestat (LexState *ls, int line) { | |||
| 870 | 847 | ||
| 871 | 848 | ||
| 872 | static void repeatstat (LexState *ls, int line) { | 849 | static void repeatstat (LexState *ls, int line) { |
| 873 | /* repeatstat -> REPEAT block UNTIL exp1 */ | 850 | /* repeatstat -> REPEAT block UNTIL cond */ |
| 874 | FuncState *fs = ls->fs; | 851 | FuncState *fs = ls->fs; |
| 875 | int repeat_init = luaK_getlabel(fs); | 852 | int repeat_init = luaK_getlabel(fs); |
| 876 | expdesc v; | 853 | expdesc v; |
| @@ -879,14 +856,14 @@ static void repeatstat (LexState *ls, int line) { | |||
| 879 | setline_and_next(ls); /* trace REPEAT when looping */ | 856 | setline_and_next(ls); /* trace REPEAT when looping */ |
| 880 | block(ls); | 857 | block(ls); |
| 881 | check_match(ls, TK_UNTIL, TK_REPEAT, line); | 858 | check_match(ls, TK_UNTIL, TK_REPEAT, line); |
| 882 | expr(ls, &v); | 859 | cond(ls, &v); |
| 883 | luaK_goiftrue(fs, &v, 0); | ||
| 884 | luaK_patchlist(fs, v.u.l.f, repeat_init); | 860 | luaK_patchlist(fs, v.u.l.f, repeat_init); |
| 885 | leavebreak(fs, &bl); | 861 | leavebreak(fs, &bl); |
| 886 | } | 862 | } |
| 887 | 863 | ||
| 888 | 864 | ||
| 889 | static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { | 865 | static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { |
| 866 | /* forbody -> DO block END */ | ||
| 890 | FuncState *fs = ls->fs; | 867 | FuncState *fs = ls->fs; |
| 891 | int prep = luaK_code1(fs, prepfor, NO_JUMP); | 868 | int prep = luaK_code1(fs, prepfor, NO_JUMP); |
| 892 | int blockinit = luaK_getlabel(fs); | 869 | int blockinit = luaK_getlabel(fs); |
| @@ -898,6 +875,7 @@ static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { | |||
| 898 | 875 | ||
| 899 | 876 | ||
| 900 | static void fornum (LexState *ls, TString *varname) { | 877 | static void fornum (LexState *ls, TString *varname) { |
| 878 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ | ||
| 901 | FuncState *fs = ls->fs; | 879 | FuncState *fs = ls->fs; |
| 902 | store_localvar(ls, varname, 0); | 880 | store_localvar(ls, varname, 0); |
| 903 | check(ls, '='); | 881 | check(ls, '='); |
| @@ -910,19 +888,21 @@ static void fornum (LexState *ls, TString *varname) { | |||
| 910 | luaK_code1(fs, OP_PUSHINT, 1); /* default step */ | 888 | luaK_code1(fs, OP_PUSHINT, 1); /* default step */ |
| 911 | adjustlocalvars(ls, 1); /* scope for control variables */ | 889 | adjustlocalvars(ls, 1); /* scope for control variables */ |
| 912 | add_localvar(ls, "*limit*"); | 890 | add_localvar(ls, "*limit*"); |
| 913 | add_localvar(ls, "*step*"); | 891 | add_localvar(ls, "*count*"); |
| 914 | forbody(ls, OP_FORPREP, OP_FORLOOP); | 892 | forbody(ls, OP_FORPREP, OP_FORLOOP); |
| 915 | removelocalvars(ls, 3); | 893 | removelocalvars(ls, 3); |
| 916 | } | 894 | } |
| 917 | 895 | ||
| 918 | 896 | ||
| 919 | static void forlist (LexState *ls, TString *indexname) { | 897 | static void forlist (LexState *ls, TString *indexname) { |
| 898 | /* forlist -> NAME,NAME IN exp1 forbody */ | ||
| 920 | TString *valname; | 899 | TString *valname; |
| 921 | check(ls, ','); | 900 | check(ls, ','); |
| 922 | valname = str_checkname(ls); | 901 | valname = str_checkname(ls); |
| 923 | /* next test is dirty, but avoids `in' being a reserved word */ | 902 | /* next test is dirty, but avoids `in' being a reserved word */ |
| 924 | if (ls->t.token != TK_NAME || ls->t.seminfo.ts != luaS_new(ls->L, "in")) | 903 | check_condition(ls, |
| 925 | luaK_error(ls, "`in' expected"); | 904 | (ls->t.token == TK_NAME && ls->t.seminfo.ts == luaS_new(ls->L, "in")), |
| 905 | "`in' expected"); | ||
| 926 | next(ls); /* skip `in' */ | 906 | next(ls); /* skip `in' */ |
| 927 | exp1(ls); /* table */ | 907 | exp1(ls); /* table */ |
| 928 | add_localvar(ls, "*table*"); | 908 | add_localvar(ls, "*table*"); |
| @@ -936,8 +916,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
| 936 | 916 | ||
| 937 | 917 | ||
| 938 | static void forstat (LexState *ls, int line) { | 918 | static void forstat (LexState *ls, int line) { |
| 939 | /* forstat -> FOR NAME '=' expr1 ',' expr1 [',' expr1] DO block END */ | 919 | /* forstat -> fornum | forlist */ |
| 940 | /* forstat -> FOR NAME1, NAME2 IN expr1 DO block END */ | ||
| 941 | FuncState *fs = ls->fs; | 920 | FuncState *fs = ls->fs; |
| 942 | TString *varname; | 921 | TString *varname; |
| 943 | Breaklabel bl; | 922 | Breaklabel bl; |
| @@ -954,11 +933,10 @@ static void forstat (LexState *ls, int line) { | |||
| 954 | } | 933 | } |
| 955 | 934 | ||
| 956 | 935 | ||
| 957 | static void test_and_block (LexState *ls, expdesc *v) { | 936 | static void test_then_block (LexState *ls, expdesc *v) { |
| 958 | /* test_and_block -> [IF | ELSEIF] cond THEN block */ | 937 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ |
| 959 | setline_and_next(ls); /* skip IF or ELSEIF */ | 938 | setline_and_next(ls); /* skip IF or ELSEIF */ |
| 960 | expr(ls, v); /* cond */ | 939 | cond(ls, v); |
| 961 | luaK_goiftrue(ls->fs, v, 0); | ||
| 962 | setline(ls); /* to trace the THEN */ | 940 | setline(ls); /* to trace the THEN */ |
| 963 | check(ls, TK_THEN); | 941 | check(ls, TK_THEN); |
| 964 | block(ls); /* `then' part */ | 942 | block(ls); /* `then' part */ |
| @@ -970,11 +948,11 @@ static void ifstat (LexState *ls, int line) { | |||
| 970 | FuncState *fs = ls->fs; | 948 | FuncState *fs = ls->fs; |
| 971 | expdesc v; | 949 | expdesc v; |
| 972 | int escapelist = NO_JUMP; | 950 | int escapelist = NO_JUMP; |
| 973 | test_and_block(ls, &v); /* IF cond THEN block */ | 951 | test_then_block(ls, &v); /* IF cond THEN block */ |
| 974 | while (ls->t.token == TK_ELSEIF) { | 952 | while (ls->t.token == TK_ELSEIF) { |
| 975 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 953 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
| 976 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 954 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); |
| 977 | test_and_block(ls, &v); /* ELSEIF cond THEN block */ | 955 | test_then_block(ls, &v); /* ELSEIF cond THEN block */ |
| 978 | } | 956 | } |
| 979 | if (ls->t.token == TK_ELSE) { | 957 | if (ls->t.token == TK_ELSE) { |
| 980 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 958 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
| @@ -989,36 +967,18 @@ static void ifstat (LexState *ls, int line) { | |||
| 989 | } | 967 | } |
| 990 | 968 | ||
| 991 | 969 | ||
| 992 | static int localnamelist (LexState *ls) { | ||
| 993 | /* localnamelist -> NAME {',' NAME} */ | ||
| 994 | int i = 1; | ||
| 995 | store_localvar(ls, str_checkname(ls), 0); | ||
| 996 | while (ls->t.token == ',') { | ||
| 997 | next(ls); | ||
| 998 | store_localvar(ls, str_checkname(ls), i++); | ||
| 999 | } | ||
| 1000 | return i; | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | |||
| 1004 | static int decinit (LexState *ls) { | ||
| 1005 | /* decinit -> ['=' explist1] */ | ||
| 1006 | if (ls->t.token == '=') { | ||
| 1007 | next(ls); | ||
| 1008 | return explist1(ls); | ||
| 1009 | } | ||
| 1010 | else | ||
| 1011 | return 0; /* no initializations */ | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | |||
| 1015 | static void localstat (LexState *ls) { | 970 | static void localstat (LexState *ls) { |
| 1016 | /* stat -> LOCAL localnamelist decinit */ | 971 | /* stat -> LOCAL NAME {',' NAME} ['=' explist1] */ |
| 1017 | int nvars; | 972 | int nvars = 0; |
| 1018 | int nexps; | 973 | int nexps; |
| 1019 | setline_and_next(ls); /* skip LOCAL */ | 974 | do { |
| 1020 | nvars = localnamelist(ls); | 975 | setline_and_next(ls); /* skip LOCAL or ',' */ |
| 1021 | nexps = decinit(ls); | 976 | store_localvar(ls, str_checkname(ls), nvars++); |
| 977 | } while (ls->t.token == ','); | ||
| 978 | if (optional(ls, '=')) | ||
| 979 | nexps = explist1(ls); | ||
| 980 | else | ||
| 981 | nexps = 0; | ||
| 1022 | adjustlocalvars(ls, nvars); | 982 | adjustlocalvars(ls, nvars); |
| 1023 | adjust_mult_assign(ls, nvars, nexps); | 983 | adjust_mult_assign(ls, nvars, nexps); |
| 1024 | } | 984 | } |
| @@ -1027,7 +987,7 @@ static void localstat (LexState *ls) { | |||
| 1027 | static int funcname (LexState *ls, expdesc *v) { | 987 | static int funcname (LexState *ls, expdesc *v) { |
| 1028 | /* funcname -> NAME [':' NAME | '.' NAME] */ | 988 | /* funcname -> NAME [':' NAME | '.' NAME] */ |
| 1029 | int needself = 0; | 989 | int needself = 0; |
| 1030 | singlevar(ls, str_checkname(ls), v, 0); | 990 | singlevar(ls, str_checkname(ls), v); |
| 1031 | if (ls->t.token == ':' || ls->t.token == '.') { | 991 | if (ls->t.token == ':' || ls->t.token == '.') { |
| 1032 | needself = (ls->t.token == ':'); | 992 | needself = (ls->t.token == ':'); |
| 1033 | next(ls); | 993 | next(ls); |
| @@ -1043,8 +1003,8 @@ static void funcstat (LexState *ls, int line) { | |||
| 1043 | /* funcstat -> FUNCTION funcname body */ | 1003 | /* funcstat -> FUNCTION funcname body */ |
| 1044 | int needself; | 1004 | int needself; |
| 1045 | expdesc v; | 1005 | expdesc v; |
| 1046 | if (ls->fs->prev) /* inside other function? */ | 1006 | check_condition(ls, (ls->fs->prev == NULL), |
| 1047 | luaK_error(ls, "cannot nest this kind of function declaration"); | 1007 | "cannot nest this kind of function declaration"); |
| 1048 | setline_and_next(ls); /* skip FUNCTION */ | 1008 | setline_and_next(ls); /* skip FUNCTION */ |
| 1049 | needself = funcname(ls, &v); | 1009 | needself = funcname(ls, &v); |
| 1050 | body(ls, needself, line); | 1010 | body(ls, needself, line); |
| @@ -1059,8 +1019,7 @@ static void namestat (LexState *ls) { | |||
| 1059 | setline(ls); | 1019 | setline(ls); |
| 1060 | var_or_func(ls, &v); | 1020 | var_or_func(ls, &v); |
| 1061 | if (v.k == VEXP) { /* stat -> func */ | 1021 | if (v.k == VEXP) { /* stat -> func */ |
| 1062 | if (!luaK_lastisopen(fs)) /* is just an upvalue? */ | 1022 | check_condition(ls, luaK_lastisopen(fs), "syntax error"); /* an upvalue? */ |
| 1063 | luaK_error(ls, "syntax error"); | ||
| 1064 | luaK_setcallreturns(fs, 0); /* call statement uses no results */ | 1023 | luaK_setcallreturns(fs, 0); /* call statement uses no results */ |
| 1065 | } | 1024 | } |
| 1066 | else { /* stat -> ['%'] NAME assignment */ | 1025 | else { /* stat -> ['%'] NAME assignment */ |
| @@ -1074,7 +1033,8 @@ static void retstat (LexState *ls) { | |||
| 1074 | /* stat -> RETURN explist */ | 1033 | /* stat -> RETURN explist */ |
| 1075 | FuncState *fs = ls->fs; | 1034 | FuncState *fs = ls->fs; |
| 1076 | setline_and_next(ls); /* skip RETURN */ | 1035 | setline_and_next(ls); /* skip RETURN */ |
| 1077 | explist(ls); | 1036 | if (!block_follow(ls->t.token)) |
| 1037 | explist1(ls); /* optional return values */ | ||
| 1078 | luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar); | 1038 | luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar); |
| 1079 | fs->stacklevel = fs->nlocalvar; /* removes all temp values */ | 1039 | fs->stacklevel = fs->nlocalvar; /* removes all temp values */ |
| 1080 | } | 1040 | } |
| @@ -1086,7 +1046,7 @@ static void breakstat (LexState *ls) { | |||
| 1086 | Breaklabel *bl; | 1046 | Breaklabel *bl; |
| 1087 | int currentlevel = fs->stacklevel; | 1047 | int currentlevel = fs->stacklevel; |
| 1088 | setline_and_next(ls); /* skip BREAK */ | 1048 | setline_and_next(ls); /* skip BREAK */ |
| 1089 | bl = findlabel(fs, optionalname(ls)); | 1049 | bl = findlabel(ls); |
| 1090 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); | 1050 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); |
| 1091 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | 1051 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); |
| 1092 | fs->stacklevel = currentlevel; | 1052 | fs->stacklevel = currentlevel; |
| @@ -1098,66 +1058,48 @@ static int stat (LexState *ls) { | |||
| 1098 | switch (ls->t.token) { | 1058 | switch (ls->t.token) { |
| 1099 | case TK_IF: { /* stat -> ifstat */ | 1059 | case TK_IF: { /* stat -> ifstat */ |
| 1100 | ifstat(ls, line); | 1060 | ifstat(ls, line); |
| 1101 | return 1; | 1061 | return 0; |
| 1102 | } | 1062 | } |
| 1103 | case TK_WHILE: { /* stat -> whilestat */ | 1063 | case TK_WHILE: { /* stat -> whilestat */ |
| 1104 | whilestat(ls, line); | 1064 | whilestat(ls, line); |
| 1105 | return 1; | 1065 | return 0; |
| 1106 | } | 1066 | } |
| 1107 | case TK_DO: { /* stat -> DO block END */ | 1067 | case TK_DO: { /* stat -> DO block END */ |
| 1108 | setline_and_next(ls); /* skip DO */ | 1068 | setline_and_next(ls); /* skip DO */ |
| 1109 | block(ls); | 1069 | block(ls); |
| 1110 | check_END(ls, TK_DO, line); | 1070 | check_END(ls, TK_DO, line); |
| 1111 | return 1; | 1071 | return 0; |
| 1112 | } | 1072 | } |
| 1113 | case TK_FOR: { /* stat -> forstat */ | 1073 | case TK_FOR: { /* stat -> forstat */ |
| 1114 | forstat(ls, line); | 1074 | forstat(ls, line); |
| 1115 | return 1; | 1075 | return 0; |
| 1116 | } | 1076 | } |
| 1117 | case TK_REPEAT: { /* stat -> repeatstat */ | 1077 | case TK_REPEAT: { /* stat -> repeatstat */ |
| 1118 | repeatstat(ls, line); | 1078 | repeatstat(ls, line); |
| 1119 | return 1; | 1079 | return 0; |
| 1120 | } | 1080 | } |
| 1121 | case TK_FUNCTION: { /* stat -> funcstat */ | 1081 | case TK_FUNCTION: { /* stat -> funcstat */ |
| 1122 | funcstat(ls, line); | 1082 | funcstat(ls, line); |
| 1123 | return 1; | 1083 | return 0; |
| 1124 | } | 1084 | } |
| 1125 | case TK_LOCAL: { /* stat -> localstat */ | 1085 | case TK_LOCAL: { /* stat -> localstat */ |
| 1126 | localstat(ls); | 1086 | localstat(ls); |
| 1127 | return 1; | 1087 | return 0; |
| 1128 | } | 1088 | } |
| 1129 | case TK_NAME: case '%': { /* stat -> namestat */ | 1089 | case TK_NAME: case '%': { /* stat -> namestat */ |
| 1130 | namestat(ls); | 1090 | namestat(ls); |
| 1131 | return 1; | 1091 | return 0; |
| 1132 | } | 1092 | } |
| 1133 | case TK_RETURN: { /* stat -> retstat */ | 1093 | case TK_RETURN: { /* stat -> retstat */ |
| 1134 | retstat(ls); | 1094 | retstat(ls); |
| 1135 | return 2; /* must be last statement */ | 1095 | return 1; /* must be last statement */ |
| 1136 | } | 1096 | } |
| 1137 | case TK_BREAK: { /* stat -> breakstat */ | 1097 | case TK_BREAK: { /* stat -> breakstat */ |
| 1138 | breakstat(ls); | 1098 | breakstat(ls); |
| 1139 | return 2; /* must be last statement */ | 1099 | return 1; /* must be last statement */ |
| 1140 | } | 1100 | } |
| 1141 | default: { | 1101 | default: { |
| 1142 | return 0; /* no statement */ | 1102 | luaK_error(ls, "<statement> expected"); |
| 1143 | } | ||
| 1144 | } | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | |||
| 1148 | static int param (LexState *ls, int n) { | ||
| 1149 | /* param -> NAME | DOTS */ | ||
| 1150 | switch (ls->t.token) { | ||
| 1151 | case TK_DOTS: { | ||
| 1152 | next(ls); | ||
| 1153 | return 1; | ||
| 1154 | } | ||
| 1155 | case TK_NAME: { | ||
| 1156 | store_localvar(ls, str_checkname(ls), n); | ||
| 1157 | return 0; | ||
| 1158 | } | ||
| 1159 | default: { | ||
| 1160 | luaK_error(ls, "<name> or `...' expected"); | ||
| 1161 | return 0; /* to avoid warnings */ | 1103 | return 0; /* to avoid warnings */ |
| 1162 | } | 1104 | } |
| 1163 | } | 1105 | } |
| @@ -1169,22 +1111,22 @@ static void parlist (LexState *ls) { | |||
| 1169 | int nparams = 0; | 1111 | int nparams = 0; |
| 1170 | int dots = 0; | 1112 | int dots = 0; |
| 1171 | if (ls->t.token != ')') { /* is `parlist' not empty? */ | 1113 | if (ls->t.token != ')') { /* is `parlist' not empty? */ |
| 1172 | dots = param(ls, nparams); | 1114 | do { |
| 1173 | nparams++; | 1115 | switch (ls->t.token) { |
| 1174 | while (ls->t.token == ',' && !dots) { | 1116 | case TK_DOTS: next(ls); dots = 1; break; |
| 1175 | next(ls); | 1117 | case TK_NAME: store_localvar(ls, str_checkname(ls), nparams++); break; |
| 1176 | dots = param(ls, nparams); | 1118 | default: luaK_error(ls, "<name> or `...' expected"); |
| 1177 | nparams++; | 1119 | } |
| 1178 | } | 1120 | } while (!dots && optional(ls, ',')); |
| 1179 | } | 1121 | } |
| 1180 | code_args(ls, nparams, dots); | 1122 | code_params(ls, nparams, dots); |
| 1181 | } | 1123 | } |
| 1182 | 1124 | ||
| 1183 | 1125 | ||
| 1184 | static void body (LexState *ls, int needself, int line) { | 1126 | static void body (LexState *ls, int needself, int line) { |
| 1185 | /* body -> '(' parlist ')' chunk END */ | 1127 | /* body -> '(' parlist ')' chunk END */ |
| 1186 | FuncState new_fs; | 1128 | FuncState new_fs; |
| 1187 | init_state(ls, &new_fs, ls->fs->f->source); | 1129 | open_func(ls, &new_fs, ls->fs->f->source); |
| 1188 | new_fs.f->lineDefined = line; | 1130 | new_fs.f->lineDefined = line; |
| 1189 | check(ls, '('); | 1131 | check(ls, '('); |
| 1190 | if (needself) | 1132 | if (needself) |
| @@ -1194,40 +1136,40 @@ static void body (LexState *ls, int needself, int line) { | |||
| 1194 | chunk(ls); | 1136 | chunk(ls); |
| 1195 | check_END(ls, TK_FUNCTION, line); | 1137 | check_END(ls, TK_FUNCTION, line); |
| 1196 | close_func(ls); | 1138 | close_func(ls); |
| 1197 | func_onstack(ls, &new_fs); | 1139 | pushclosure(ls, &new_fs); |
| 1198 | } | 1140 | } |
| 1199 | 1141 | ||
| 1200 | 1142 | ||
| 1201 | /* }====================================================================== */ | 1143 | /* }====================================================================== */ |
| 1202 | 1144 | ||
| 1203 | 1145 | ||
| 1204 | static void label (LexState *ls, Breaklabel *bl) { | 1146 | static TString *optional_label (LexState *ls) { |
| 1205 | /* label -> [ '|' NAME '|' ] */ | 1147 | /* label -> [ '|' NAME '|' ] */ |
| 1206 | if (optional(ls, '|')) { | 1148 | if (optional(ls, '|')) { |
| 1207 | enterbreak(ls->fs, bl); | 1149 | TString *l = str_checkname(ls); |
| 1208 | bl->label = str_checkname(ls); | ||
| 1209 | check(ls, '|'); | 1150 | check(ls, '|'); |
| 1151 | return l; | ||
| 1210 | } | 1152 | } |
| 1211 | else | 1153 | else |
| 1212 | bl->label = NULL; /* there is no label */ | 1154 | return NULL; /* there is no label */ |
| 1213 | } | 1155 | } |
| 1214 | 1156 | ||
| 1215 | 1157 | ||
| 1216 | static void chunk (LexState *ls) { | 1158 | static void chunk (LexState *ls) { |
| 1217 | /* chunk -> { [label] stat [';'] } */ | 1159 | /* chunk -> { [label] stat [';'] } */ |
| 1218 | Breaklabel bl; | 1160 | int islast = 0; |
| 1219 | int a; | 1161 | while (!islast && !block_follow(ls->t.token)) { |
| 1220 | do { | 1162 | Breaklabel bl; |
| 1221 | label(ls, &bl); | 1163 | TString *l = optional_label(ls); |
| 1222 | a = stat(ls); | 1164 | if (l) { |
| 1223 | if (a != 0) | 1165 | enterbreak(ls->fs, &bl); |
| 1224 | optional(ls, ';'); | 1166 | bl.label = l; |
| 1225 | else if (bl.label) | 1167 | } |
| 1226 | luaK_error(ls, "label without a statement"); | 1168 | islast = stat(ls); |
| 1169 | optional(ls, ';'); | ||
| 1227 | LUA_ASSERT(ls->L, ls->fs->stacklevel == ls->fs->nlocalvar, | 1170 | LUA_ASSERT(ls->L, ls->fs->stacklevel == ls->fs->nlocalvar, |
| 1228 | "stack size != # local vars"); | 1171 | "stack size != # local vars"); |
| 1229 | if (bl.label) | 1172 | if (l) leavebreak(ls->fs, &bl); |
| 1230 | leavebreak(ls->fs, &bl); | 1173 | } |
| 1231 | } while (a == 1); | ||
| 1232 | } | 1174 | } |
| 1233 | 1175 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.109 2000/05/25 19:02:21 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.110 2000/05/30 19:00:31 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 | */ |
| @@ -483,13 +483,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 483 | 483 | ||
| 484 | case OP_SETMAP: { | 484 | case OP_SETMAP: { |
| 485 | int n = GETARG_U(i); | 485 | int n = GETARG_U(i); |
| 486 | StkId finaltop = top-2*(n+1); | 486 | StkId finaltop = top-2*n; |
| 487 | Hash *arr = avalue(finaltop-1); | 487 | Hash *arr = avalue(finaltop-1); |
| 488 | L->top = finaltop; /* final value of `top' (in case of errors) */ | 488 | L->top = finaltop; /* final value of `top' (in case of errors) */ |
| 489 | do { | 489 | for (; n; n--) { |
| 490 | luaH_set(L, arr, top-2, top-1); | 490 | luaH_set(L, arr, top-2, top-1); |
| 491 | top-=2; | 491 | top-=2; |
| 492 | } while (n--); | 492 | } |
| 493 | break; | 493 | break; |
| 494 | } | 494 | } |
| 495 | 495 | ||
| @@ -625,23 +625,22 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 625 | lua_error(L, "`for' limit must be a number"); | 625 | lua_error(L, "`for' limit must be a number"); |
| 626 | if (tonumber(top-3)) | 626 | if (tonumber(top-3)) |
| 627 | lua_error(L, "`for' initial value must be a number"); | 627 | lua_error(L, "`for' initial value must be a number"); |
| 628 | /* number of steps */ | ||
| 629 | nvalue(top-2) = (nvalue(top-2)-nvalue(top-3))/nvalue(top-1); | ||
| 628 | nvalue(top-3) -= nvalue(top-1); /* to be undone by first FORLOOP */ | 630 | nvalue(top-3) -= nvalue(top-1); /* to be undone by first FORLOOP */ |
| 629 | pc += GETARG_S(i); | 631 | pc += GETARG_S(i); |
| 630 | break; | 632 | break; |
| 631 | 633 | ||
| 632 | case OP_FORLOOP: { | 634 | case OP_FORLOOP: { |
| 633 | Number step = nvalue(top-1); | ||
| 634 | Number limit = nvalue(top-2); | ||
| 635 | Number index; | ||
| 636 | LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step"); | 635 | LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step"); |
| 637 | LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid limit"); | 636 | LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid count"); |
| 638 | if (ttype(top-3) != TAG_NUMBER) | 637 | if (nvalue(top-2) < 0) |
| 639 | lua_error(L, "`for' index must be a number"); | ||
| 640 | index = nvalue(top-3)+step; | ||
| 641 | if ((step>0) ? index>limit : index<limit) | ||
| 642 | top -= 3; /* end loop: remove control variables */ | 638 | top -= 3; /* end loop: remove control variables */ |
| 643 | else { | 639 | else { |
| 644 | nvalue(top-3) = index; | 640 | nvalue(top-2)--; /* decrement count */ |
| 641 | if (ttype(top-3) != TAG_NUMBER) | ||
| 642 | lua_error(L, "`for' index must be a number"); | ||
| 643 | nvalue(top-3) += nvalue(top-1); /* increment index */ | ||
| 645 | pc += GETARG_S(i); | 644 | pc += GETARG_S(i); |
| 646 | } | 645 | } |
| 647 | break; | 646 | break; |
