aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-03-14 15:01:52 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-03-14 15:01:52 -0300
commit7ff21273d66541ac19ad817f90e8bcea5790f355 (patch)
tree9798243bbc84da7f0ea3aa7316ba42b06b947e63
parent207dad86065acf4b6168bea1f13e88b7306a7440 (diff)
downloadlua-7ff21273d66541ac19ad817f90e8bcea5790f355.tar.gz
lua-7ff21273d66541ac19ad817f90e8bcea5790f355.tar.bz2
lua-7ff21273d66541ac19ad817f90e8bcea5790f355.zip
implementation of `global' statement
-rw-r--r--llimits.h8
-rw-r--r--lparser.c269
-rw-r--r--lparser.h36
-rw-r--r--ltests.c4
4 files changed, 211 insertions, 106 deletions
diff --git a/llimits.h b/llimits.h
index 22cfe305..9f6d6520 100644
--- a/llimits.h
+++ b/llimits.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llimits.h,v 1.38 2002/03/05 16:22:54 roberto Exp roberto $ 2** $Id: llimits.h,v 1.39 2002/03/07 18:11:51 roberto Exp roberto $
3** Limits, basic types, and some other `installation-dependent' definitions 3** Limits, basic types, and some other `installation-dependent' definitions
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -96,9 +96,9 @@ typedef unsigned long Instruction;
96#define MAXSTACK 250 96#define MAXSTACK 250
97 97
98 98
99/* maximum number of local variables */ 99/* maximum number of variables declared in a function */
100#ifndef MAXLOCALS 100#ifndef MAXVARS
101#define MAXLOCALS 200 /* arbitrary limit (<MAXSTACK) */ 101#define MAXVARS 200 /* arbitrary limit (<MAXSTACK) */
102#endif 102#endif
103 103
104 104
diff --git a/lparser.c b/lparser.c
index 507bddfe..13177507 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.167 2002/02/14 21:46:58 roberto Exp $ 2** $Id: lparser.c,v 1.168 2002/03/08 19:10:32 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -24,14 +24,17 @@
24 24
25 25
26/* 26/*
27** nodes for break list (list of active breakable loops) 27** nodes for block list (list of active blocks)
28*/ 28*/
29typedef struct Breaklabel { 29typedef struct BlockCnt {
30 struct Breaklabel *previous; /* chain */ 30 struct BlockCnt *previous; /* chain */
31 int breaklist; /* list of jumps out of this loop */ 31 int breaklist; /* list of jumps out of this loop */
32 int nactloc; /* # of active local variables outside the breakable structure */ 32 int nactloc; /* # active local variables outside the breakable structure */
33} Breaklabel; 33 int nactvar;
34 34 int defaultglob;
35 int upval; /* true if some variable in the block is an upvalue */
36 int isbreakable; /* true if `block' is a loop */
37} BlockCnt;
35 38
36 39
37 40
@@ -77,9 +80,7 @@ static void check (LexState *ls, int c) {
77} 80}
78 81
79 82
80static void check_condition (LexState *ls, int c, const char *msg) { 83#define check_condition(ls,c,msg) { if (!(c)) luaK_error(ls, msg); }
81 if (!c) luaK_error(ls, msg);
82}
83 84
84 85
85static int optional (LexState *ls, int c) { 86static int optional (LexState *ls, int c) {
@@ -143,41 +144,51 @@ static int luaI_registerlocalvar (LexState *ls, TString *varname) {
143} 144}
144 145
145 146
146static void new_localvar (LexState *ls, TString *name, int n) { 147static vardesc *new_var (LexState *ls, int n) {
147 FuncState *fs = ls->fs; 148 FuncState *fs = ls->fs;
148 luaX_checklimit(ls, fs->nactloc+n+1, MAXLOCALS, "local variables"); 149 luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "variables");
149 fs->actloc[fs->nactloc+n] = luaI_registerlocalvar(ls, name); 150 return &fs->actvar[fs->nactvar+n];
151}
152
153
154static void new_localvar (LexState *ls, TString *name, int n) {
155 vardesc *v = new_var(ls, n);
156 v->k = VLOCAL;
157 v->i = luaI_registerlocalvar(ls, name);
158 v->level = ls->fs->nactloc + n;
150} 159}
151 160
152 161
153static void adjustlocalvars (LexState *ls, int nvars) { 162static void adjustlocalvars (LexState *ls, int nvars) {
154 FuncState *fs = ls->fs; 163 FuncState *fs = ls->fs;
155 while (nvars--) { 164 while (nvars--) {
156 fs->f->locvars[fs->actloc[fs->nactloc]].startpc = fs->pc; 165 lua_assert(fs->actvar[fs->nactvar].k == VLOCAL);
157 resetbit(fs->wasup, fs->nactloc); 166 fs->f->locvars[fs->actvar[fs->nactvar].i].startpc = fs->pc;
167 fs->nactvar++;
158 fs->nactloc++; 168 fs->nactloc++;
159 } 169 }
160} 170}
161 171
162 172
163static void closelevel (LexState *ls, int level) { 173static void adjustglobalvars (LexState *ls, int nvars, int level) {
164 FuncState *fs = ls->fs; 174 FuncState *fs = ls->fs;
165 int i; 175 while (nvars--) {
166 for (i=level; i<fs->nactloc; i++) 176 fs->actvar[fs->nactvar].k = VGLOBAL;
167 if (testbit(fs->wasup, i)) { 177 fs->actvar[fs->nactvar].level = level;
168 luaK_codeABC(fs, OP_CLOSE, level, 0, 0); 178 fs->nactvar++;
169 return; 179 }
170 }
171 return; /* nothing to close */
172} 180}
173 181
174 182
175static void removelocalvars (LexState *ls, int nvars, int toclose) { 183static void removevars (LexState *ls, int tolevel) {
176 FuncState *fs = ls->fs; 184 FuncState *fs = ls->fs;
177 if (toclose) 185 while (fs->nactvar > tolevel) {
178 closelevel(ls, fs->nactloc - nvars); 186 fs->nactvar--;
179 while (nvars--) 187 if (fs->actvar[fs->nactvar].k == VLOCAL) {
180 fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc; 188 fs->nactloc--;
189 fs->f->locvars[fs->actvar[fs->nactvar].i].endpc = fs->pc;
190 }
191 }
181} 192}
182 193
183 194
@@ -186,6 +197,12 @@ static void new_localvarstr (LexState *ls, const char *name, int n) {
186} 197}
187 198
188 199
200static void create_local (LexState *ls, const char *name) {
201 new_localvarstr(ls, name, 0);
202 adjustlocalvars(ls, 1);
203}
204
205
189static int indexupvalue (FuncState *fs, expdesc *v) { 206static int indexupvalue (FuncState *fs, expdesc *v) {
190 int i; 207 int i;
191 for (i=0; i<fs->f->nupvalues; i++) { 208 for (i=0; i<fs->f->nupvalues; i++) {
@@ -199,28 +216,72 @@ static int indexupvalue (FuncState *fs, expdesc *v) {
199} 216}
200 217
201 218
202static void singlevar (FuncState *fs, TString *n, expdesc *var, int baselevel) { 219static vardesc *searchvar (FuncState *fs, TString *n) {
203 if (fs == NULL) 220 int i;
204 init_exp(var, VGLOBAL, 0); /* not local in any level; global variable */ 221 for (i=fs->nactvar-1; i >= 0; i--) {
205 else { /* look up at current level */ 222 vardesc *v = &fs->actvar[i];
206 int i; 223 if (v->k == VLOCAL ? n == fs->f->locvars[v->i].varname
207 for (i=fs->nactloc-1; i >= 0; i--) { 224 : n == tsvalue(&fs->f->k[v->i]))
208 if (n == fs->f->locvars[fs->actloc[i]].varname) { 225 return v;
209 if (!baselevel) 226 }
210 setbit(fs->wasup, i); /* will be upvalue in some other level */ 227 return NULL; /* not found */
211 init_exp(var, VLOCAL, i); 228}
212 return; 229
230
231static void markupval (FuncState *fs, int level) {
232 BlockCnt *bl = fs->bl;
233 while (bl && bl->nactloc > level) bl = bl->previous;
234 if (bl) bl->upval = 1;
235}
236
237
238static int singlevar_aux (FuncState *fs, TString *n, expdesc *var, int nd) {
239 if (fs == NULL) { /* no more levels? */
240 init_exp(var, VGLOBAL, NO_REG); /* default is free global */
241 return VNIL; /* not found */
242 }
243 else {
244 vardesc *v = searchvar(fs, n); /* look up at current level */
245 if (v) {
246 if (v->level == NO_REG) { /* free global? */
247 lua_assert(v->k == VGLOBAL);
248 init_exp(var, VGLOBAL, NO_REG);
213 } 249 }
250 else
251 init_exp(var, VLOCAL, v->level);
252 return v->k;
214 } 253 }
215 /* not found at current level; try upper one */ 254 else { /* not found at current level; try upper one */
216 singlevar(fs->prev, n, var, 0); 255 int k = singlevar_aux(fs->prev, n, var, nd && fs->defaultglob == NO_REG);
217 if (var->k == VGLOBAL) { 256 if (var->k == VGLOBAL) {
218 if (baselevel) 257 if (k == VNIL && nd && fs->defaultglob != NO_REG) {
219 var->info = luaK_stringK(fs, n); /* info points to global name */ 258 init_exp(var, VLOCAL, fs->defaultglob);
259 k = VGLOBAL; /* now there is a declaration */
260 }
261 }
262 else { /* LOCAL or UPVAL */
263 if (var->k == VLOCAL)
264 markupval(fs->prev, var->info); /* local will be used as an upval */
265 var->info = indexupvalue(fs, var);
266 var->k = VUPVAL; /* upvalue in this level */
267 }
268 return k;
220 } 269 }
221 else { /* local variable in some upper level? */ 270 }
222 var->info = indexupvalue(fs, var); 271}
223 var->k = VUPVAL; /* upvalue in this level */ 272
273
274static void singlevar (FuncState *fs, TString *n, expdesc *var) {
275 int k = singlevar_aux(fs, n, var, 1);
276 if (k == VNIL || k == VGLOBAL) { /* global? */
277 if (var->k == VGLOBAL) /* free global? */
278 var->info = luaK_stringK(fs, n);
279 else { /* `indexed' global */
280 expdesc e;
281 codestring(fs->ls, &e, n);
282 luaK_exp2anyreg(fs, var);
283 var->aux = luaK_exp2RK(fs, &e);
284 var->k = VINDEXED;
224 } 285 }
225 } 286 }
226} 287}
@@ -250,29 +311,38 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
250static void code_params (LexState *ls, int nparams, int dots) { 311static void code_params (LexState *ls, int nparams, int dots) {
251 FuncState *fs = ls->fs; 312 FuncState *fs = ls->fs;
252 adjustlocalvars(ls, nparams); 313 adjustlocalvars(ls, nparams);
253 luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters"); 314 luaX_checklimit(ls, fs->nactvar, MAXPARAMS, "parameters");
254 fs->f->numparams = cast(lu_byte, fs->nactloc); 315 fs->f->numparams = cast(lu_byte, fs->nactloc);
255 fs->f->is_vararg = cast(lu_byte, dots); 316 fs->f->is_vararg = cast(lu_byte, dots);
256 if (dots) { 317 if (dots)
257 new_localvarstr(ls, "arg", 0); 318 create_local(ls, "arg");
258 adjustlocalvars(ls, 1);
259 }
260 luaK_reserveregs(fs, fs->nactloc); /* reserve register for parameters */ 319 luaK_reserveregs(fs, fs->nactloc); /* reserve register for parameters */
261} 320}
262 321
263 322
264static void enterbreak (FuncState *fs, Breaklabel *bl) { 323static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) {
265 bl->breaklist = NO_JUMP; 324 bl->breaklist = NO_JUMP;
325 bl->isbreakable = isbreakable;
266 bl->nactloc = fs->nactloc; 326 bl->nactloc = fs->nactloc;
327 bl->nactvar = fs->nactvar;
328 bl->defaultglob = fs->defaultglob;
329 bl->upval = 0;
267 bl->previous = fs->bl; 330 bl->previous = fs->bl;
268 fs->bl = bl; 331 fs->bl = bl;
269} 332}
270 333
271 334
272static void leavebreak (FuncState *fs, Breaklabel *bl) { 335static void leaveblock (FuncState *fs) {
336 BlockCnt *bl = fs->bl;
273 fs->bl = bl->previous; 337 fs->bl = bl->previous;
274 luaK_patchtohere(fs, bl->breaklist); 338 removevars(fs->ls, bl->nactvar);
339 if (bl->upval)
340 luaK_codeABC(fs, OP_CLOSE, bl->nactloc, 0, 0);
275 lua_assert(bl->nactloc == fs->nactloc); 341 lua_assert(bl->nactloc == fs->nactloc);
342 lua_assert(bl->nactvar == fs->nactvar);
343 fs->defaultglob = bl->defaultglob;
344 fs->freereg = bl->nactloc; /* free registers used by locals */
345 luaK_patchtohere(fs, bl->breaklist);
276} 346}
277 347
278 348
@@ -308,7 +378,9 @@ static void open_func (LexState *ls, FuncState *fs) {
308 fs->nlineinfo = 0; 378 fs->nlineinfo = 0;
309 fs->nlocvars = 0; 379 fs->nlocvars = 0;
310 fs->nactloc = 0; 380 fs->nactloc = 0;
381 fs->nactvar = 0;
311 fs->lastline = 0; 382 fs->lastline = 0;
383 fs->defaultglob = NO_REG; /* default is free globals */
312 fs->bl = NULL; 384 fs->bl = NULL;
313 f->code = NULL; 385 f->code = NULL;
314 f->source = ls->source; 386 f->source = ls->source;
@@ -322,7 +394,7 @@ static void close_func (LexState *ls) {
322 lua_State *L = ls->L; 394 lua_State *L = ls->L;
323 FuncState *fs = ls->fs; 395 FuncState *fs = ls->fs;
324 Proto *f = fs->f; 396 Proto *f = fs->f;
325 removelocalvars(ls, fs->nactloc, 0); 397 removevars(ls, 0);
326 luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */ 398 luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */
327 luaK_getlabel(fs); /* close eventual list of pending jumps */ 399 luaK_getlabel(fs); /* close eventual list of pending jumps */
328 lua_assert(G(L)->roottable == fs->h); 400 lua_assert(G(L)->roottable == fs->h);
@@ -352,8 +424,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
352 open_func(&lexstate, &funcstate); 424 open_func(&lexstate, &funcstate);
353 next(&lexstate); /* read first token */ 425 next(&lexstate); /* read first token */
354 chunk(&lexstate); 426 chunk(&lexstate);
355 check_condition(&lexstate, (lexstate.t.token == TK_EOS), 427 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
356 "<eof> expected");
357 close_func(&lexstate); 428 close_func(&lexstate);
358 lua_assert(funcstate.prev == NULL); 429 lua_assert(funcstate.prev == NULL);
359 lua_assert(funcstate.f->nupvalues == 0); 430 lua_assert(funcstate.f->nupvalues == 0);
@@ -593,13 +664,13 @@ static void prefixexp (LexState *ls, expdesc *v) {
593 return; 664 return;
594 } 665 }
595 case TK_NAME: { 666 case TK_NAME: {
596 singlevar(ls->fs, str_checkname(ls), v, 1); 667 singlevar(ls->fs, str_checkname(ls), v);
597 next(ls); 668 next(ls);
598 return; 669 return;
599 } 670 }
600 case '%': { /* for compatibility only */ 671 case '%': { /* for compatibility only */
601 next(ls); /* skip `%' */ 672 next(ls); /* skip `%' */
602 singlevar(ls->fs, str_checkname(ls), v, 1); 673 singlevar(ls->fs, str_checkname(ls), v);
603 check_condition(ls, v->k == VUPVAL, "global upvalues are obsolete"); 674 check_condition(ls, v->k == VUPVAL, "global upvalues are obsolete");
604 next(ls); 675 next(ls);
605 return; 676 return;
@@ -797,10 +868,11 @@ static int block_follow (int token) {
797static void block (LexState *ls) { 868static void block (LexState *ls) {
798 /* block -> chunk */ 869 /* block -> chunk */
799 FuncState *fs = ls->fs; 870 FuncState *fs = ls->fs;
800 int nactloc = fs->nactloc; 871 BlockCnt bl;
872 enterblock(fs, &bl, 0);
801 chunk(ls); 873 chunk(ls);
802 removelocalvars(ls, fs->nactloc - nactloc, 1); 874 lua_assert(bl.breaklist == NO_JUMP);
803 fs->freereg = nactloc; /* free registers used by locals */ 875 leaveblock(fs);
804} 876}
805 877
806 878
@@ -887,8 +959,8 @@ static void whilestat (LexState *ls, int line) {
887 FuncState *fs = ls->fs; 959 FuncState *fs = ls->fs;
888 int while_init = luaK_getlabel(fs); 960 int while_init = luaK_getlabel(fs);
889 expdesc v; 961 expdesc v;
890 Breaklabel bl; 962 BlockCnt bl;
891 enterbreak(fs, &bl); 963 enterblock(fs, &bl, 1);
892 next(ls); 964 next(ls);
893 cond(ls, &v); 965 cond(ls, &v);
894 check(ls, TK_DO); 966 check(ls, TK_DO);
@@ -896,7 +968,7 @@ static void whilestat (LexState *ls, int line) {
896 luaK_patchlist(fs, luaK_jump(fs), while_init); 968 luaK_patchlist(fs, luaK_jump(fs), while_init);
897 luaK_patchtohere(fs, v.f); 969 luaK_patchtohere(fs, v.f);
898 check_match(ls, TK_END, TK_WHILE, line); 970 check_match(ls, TK_END, TK_WHILE, line);
899 leavebreak(fs, &bl); 971 leaveblock(fs);
900} 972}
901 973
902 974
@@ -905,14 +977,14 @@ static void repeatstat (LexState *ls, int line) {
905 FuncState *fs = ls->fs; 977 FuncState *fs = ls->fs;
906 int repeat_init = luaK_getlabel(fs); 978 int repeat_init = luaK_getlabel(fs);
907 expdesc v; 979 expdesc v;
908 Breaklabel bl; 980 BlockCnt bl;
909 enterbreak(fs, &bl); 981 enterblock(fs, &bl, 1);
910 next(ls); 982 next(ls);
911 block(ls); 983 block(ls);
912 check_match(ls, TK_UNTIL, TK_REPEAT, line); 984 check_match(ls, TK_UNTIL, TK_REPEAT, line);
913 cond(ls, &v); 985 cond(ls, &v);
914 luaK_patchlist(fs, v.f, repeat_init); 986 luaK_patchlist(fs, v.f, repeat_init);
915 leavebreak(fs, &bl); 987 leaveblock(fs);
916} 988}
917 989
918 990
@@ -949,7 +1021,6 @@ static void fornum (LexState *ls, TString *varname) {
949 block(ls); 1021 block(ls);
950 luaK_patchtohere(fs, prep-1); 1022 luaK_patchtohere(fs, prep-1);
951 luaK_patchlist(fs, luaK_codeAsBc(fs, OP_FORLOOP, base, NO_JUMP), prep); 1023 luaK_patchlist(fs, luaK_codeAsBc(fs, OP_FORLOOP, base, NO_JUMP), prep);
952 removelocalvars(ls, 3, 1);
953} 1024}
954 1025
955 1026
@@ -977,7 +1048,6 @@ static void forlist (LexState *ls, TString *indexname) {
977 block(ls); 1048 block(ls);
978 luaK_patchlist(fs, luaK_jump(fs), prep-1); 1049 luaK_patchlist(fs, luaK_jump(fs), prep-1);
979 luaK_patchtohere(fs, prep); 1050 luaK_patchtohere(fs, prep);
980 removelocalvars(ls, nvars+1, 1);
981} 1051}
982 1052
983 1053
@@ -985,8 +1055,8 @@ static void forstat (LexState *ls, int line) {
985 /* forstat -> fornum | forlist */ 1055 /* forstat -> fornum | forlist */
986 FuncState *fs = ls->fs; 1056 FuncState *fs = ls->fs;
987 TString *varname; 1057 TString *varname;
988 Breaklabel bl; 1058 BlockCnt bl;
989 enterbreak(fs, &bl); 1059 enterblock(fs, &bl, 1);
990 next(ls); /* skip `for' */ 1060 next(ls); /* skip `for' */
991 varname = str_checkname(ls); /* first variable name */ 1061 varname = str_checkname(ls); /* first variable name */
992 next(ls); /* skip var name */ 1062 next(ls); /* skip var name */
@@ -996,7 +1066,7 @@ static void forstat (LexState *ls, int line) {
996 default: luaK_error(ls, "`=' or `in' expected"); 1066 default: luaK_error(ls, "`=' or `in' expected");
997 } 1067 }
998 check_match(ls, TK_END, TK_FOR, line); 1068 check_match(ls, TK_END, TK_FOR, line);
999 leavebreak(fs, &bl); 1069 leaveblock(fs);
1000} 1070}
1001 1071
1002 1072
@@ -1054,10 +1124,37 @@ static void localstat (LexState *ls) {
1054} 1124}
1055 1125
1056 1126
1127static void globalstat (LexState *ls) {
1128 /* stat -> GLOBAL NAME {`,' NAME} [IN exp] | GLOBAL IN exp */
1129 FuncState *fs = ls->fs;
1130 next(ls); /* skip GLOBAL */
1131 if (optional(ls, TK_IN)) { /* default declaration? */
1132 exp1(ls);
1133 fs->defaultglob = fs->freereg - 1;
1134 create_local(ls, "(global table)");
1135 }
1136 else {
1137 int nvars = 0;
1138 do {
1139 vardesc *v = new_var(ls, nvars++);
1140 v->i = luaK_stringK(ls->fs, str_checkname(ls));
1141 next(ls); /* skip name */
1142 } while (optional(ls, ','));
1143 if (!optional(ls, TK_IN))
1144 adjustglobalvars(ls, nvars, NO_REG); /* free globals */
1145 else {
1146 exp1(ls);
1147 adjustglobalvars(ls, nvars, ls->fs->freereg - 1);
1148 create_local(ls, "(global table)");
1149 }
1150 }
1151}
1152
1153
1057static int funcname (LexState *ls, expdesc *v) { 1154static int funcname (LexState *ls, expdesc *v) {
1058 /* funcname -> NAME {field} [`:' NAME] */ 1155 /* funcname -> NAME {field} [`:' NAME] */
1059 int needself = 0; 1156 int needself = 0;
1060 singlevar(ls->fs, str_checkname(ls), v, 1); 1157 singlevar(ls->fs, str_checkname(ls), v);
1061 next(ls); /* skip var name */ 1158 next(ls); /* skip var name */
1062 while (ls->t.token == '.') { 1159 while (ls->t.token == '.') {
1063 luaY_field(ls, v); 1160 luaY_field(ls, v);
@@ -1125,11 +1222,17 @@ static void retstat (LexState *ls) {
1125static void breakstat (LexState *ls) { 1222static void breakstat (LexState *ls) {
1126 /* stat -> BREAK [NAME] */ 1223 /* stat -> BREAK [NAME] */
1127 FuncState *fs = ls->fs; 1224 FuncState *fs = ls->fs;
1128 Breaklabel *bl = fs->bl; 1225 BlockCnt *bl = fs->bl;
1226 int upval = 0;
1227 next(ls); /* skip BREAK */
1228 while (bl && !bl->isbreakable) {
1229 upval |= bl->upval;
1230 bl = bl->previous;
1231 }
1129 if (!bl) 1232 if (!bl)
1130 luaK_error(ls, "no loop to break"); 1233 luaK_error(ls, "no loop to break");
1131 next(ls); /* skip BREAK */ 1234 if (upval)
1132 closelevel(ls, bl->nactloc); 1235 luaK_codeABC(fs, OP_CLOSE, bl->nactloc, 0, 0);
1133 luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); 1236 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
1134} 1237}
1135 1238
@@ -1167,6 +1270,10 @@ static int statement (LexState *ls) {
1167 localstat(ls); 1270 localstat(ls);
1168 return 0; 1271 return 0;
1169 } 1272 }
1273 case TK_GLOBAL: { /* stat -> globalstat */
1274 globalstat(ls);
1275 return 0;
1276 }
1170 case TK_RETURN: { /* stat -> retstat */ 1277 case TK_RETURN: { /* stat -> retstat */
1171 retstat(ls); 1278 retstat(ls);
1172 return 1; /* must be last statement */ 1279 return 1; /* must be last statement */
@@ -1207,10 +1314,8 @@ static void body (LexState *ls, expdesc *e, int needself, int line) {
1207 open_func(ls, &new_fs); 1314 open_func(ls, &new_fs);
1208 new_fs.f->lineDefined = line; 1315 new_fs.f->lineDefined = line;
1209 check(ls, '('); 1316 check(ls, '(');
1210 if (needself) { 1317 if (needself)
1211 new_localvarstr(ls, "self", 0); 1318 create_local(ls, "self");
1212 adjustlocalvars(ls, 1);
1213 }
1214 parlist(ls); 1319 parlist(ls);
1215 check(ls, ')'); 1320 check(ls, ')');
1216 chunk(ls); 1321 chunk(ls);
diff --git a/lparser.h b/lparser.h
index 5df59891..44f1759e 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ 2** $Id: lparser.h,v 1.39 2002/02/08 22:42:41 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,18 +13,6 @@
13#include "lzio.h" 13#include "lzio.h"
14 14
15 15
16
17/* small implementation of bit arrays */
18
19#define BPW (CHAR_BIT*sizeof(unsigned int)) /* bits per word */
20
21#define words2bits(b) (((b)-1)/BPW + 1)
22
23#define setbit(a, b) ((a)[(b)/BPW] |= (1 << (b)%BPW))
24#define resetbit(a, b) ((a)[(b)/BPW] &= ~((1 << (b)%BPW)))
25#define testbit(a, b) ((a)[(b)/BPW] & (1 << (b)%BPW))
26
27
28/* 16/*
29** Expression descriptor 17** Expression descriptor
30*/ 18*/
@@ -37,7 +25,7 @@ typedef enum {
37 VK, /* info = index of constant in `k' */ 25 VK, /* info = index of constant in `k' */
38 VLOCAL, /* info = local register */ 26 VLOCAL, /* info = local register */
39 VUPVAL, /* info = index of upvalue in `upvalues' */ 27 VUPVAL, /* info = index of upvalue in `upvalues' */
40 VGLOBAL, /* info = index of global name in `k' */ 28 VGLOBAL, /* info = index of table; aux = index of global name in `k' */
41 VINDEXED, /* info = table register; aux = index register (or `k') */ 29 VINDEXED, /* info = table register; aux = index register (or `k') */
42 VRELOCABLE, /* info = instruction pc */ 30 VRELOCABLE, /* info = instruction pc */
43 VNONRELOC, /* info = result register */ 31 VNONRELOC, /* info = result register */
@@ -53,6 +41,18 @@ typedef struct expdesc {
53} expdesc; 41} expdesc;
54 42
55 43
44/* describe declared variables */
45typedef struct vardesc {
46 int i; /* if local, its index in `locvars';
47 if global, its name index in `k' */
48 lu_byte k;
49 lu_byte level; /* if local, stack level;
50 if global, corresponding local (NO_REG for free globals) */
51} vardesc;
52
53
54struct BlockCnt; /* defined in lparser.c */
55
56/* state needed to generate code for a given function */ 56/* state needed to generate code for a given function */
57typedef struct FuncState { 57typedef struct FuncState {
58 Proto *f; /* current function header */ 58 Proto *f; /* current function header */
@@ -60,21 +60,21 @@ typedef struct FuncState {
60 struct FuncState *prev; /* enclosing function */ 60 struct FuncState *prev; /* enclosing function */
61 struct LexState *ls; /* lexical state */ 61 struct LexState *ls; /* lexical state */
62 struct lua_State *L; /* copy of the Lua state */ 62 struct lua_State *L; /* copy of the Lua state */
63 struct Breaklabel *bl; /* chain of breakable blocks */ 63 struct BlockCnt *bl; /* chain of current blocks */
64 int pc; /* next position to code (equivalent to `ncode') */ 64 int pc; /* next position to code (equivalent to `ncode') */
65 int lasttarget; /* `pc' of last `jump target' */ 65 int lasttarget; /* `pc' of last `jump target' */
66 int jlt; /* list of jumps to `lasttarget' */ 66 int jlt; /* list of jumps to `lasttarget' */
67 int freereg; /* first free register */ 67 int freereg; /* first free register */
68 int defaultglob; /* where to look for non-declared globals */
68 int nk; /* number of elements in `k' */ 69 int nk; /* number of elements in `k' */
69 int np; /* number of elements in `p' */ 70 int np; /* number of elements in `p' */
70 int nlineinfo; /* number of elements in `lineinfo' */ 71 int nlineinfo; /* number of elements in `lineinfo' */
71 int nlocvars; /* number of elements in `locvars' */ 72 int nlocvars; /* number of elements in `locvars' */
72 int nactloc; /* number of active local variables */ 73 int nactloc; /* number of active local variables */
74 int nactvar; /* number of elements in array `actvar' */
73 int lastline; /* line where last `lineinfo' was generated */ 75 int lastline; /* line where last `lineinfo' was generated */
74 expdesc upvalues[MAXUPVALUES]; /* upvalues */ 76 expdesc upvalues[MAXUPVALUES]; /* upvalues */
75 int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */ 77 vardesc actvar[MAXVARS]; /* declared-variable stack */
76 unsigned int wasup[words2bits(MAXLOCALS)]; /* bit array to mark whether a
77 local variable was used as upvalue at some level */
78} FuncState; 78} FuncState;
79 79
80 80
diff --git a/ltests.c b/ltests.c
index 50836dfc..6dbc2bb1 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 1.110 2002/03/04 15:26:56 roberto Exp roberto $ 2** $Id: ltests.c,v 1.111 2002/03/04 21:29:41 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -219,7 +219,7 @@ static int get_limits (lua_State *L) {
219 lua_newtable(L); 219 lua_newtable(L);
220 setnameval(L, "BITS_INT", BITS_INT); 220 setnameval(L, "BITS_INT", BITS_INT);
221 setnameval(L, "LFPF", LFIELDS_PER_FLUSH); 221 setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
222 setnameval(L, "MAXLOCALS", MAXLOCALS); 222 setnameval(L, "MAXVARS", MAXVARS);
223 setnameval(L, "MAXPARAMS", MAXPARAMS); 223 setnameval(L, "MAXPARAMS", MAXPARAMS);
224 setnameval(L, "MAXSTACK", MAXSTACK); 224 setnameval(L, "MAXSTACK", MAXSTACK);
225 setnameval(L, "MAXUPVALUES", MAXUPVALUES); 225 setnameval(L, "MAXUPVALUES", MAXUPVALUES);