aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-09-07 14:39:10 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-09-07 14:39:10 -0300
commitabdbe883a86bbc7fbf1d1bfc50756e1b42fc45b5 (patch)
tree051a7571c8acaf5451b5c9b7d67f1796a345c565 /lparser.c
parent4d0935ec0ffed827aade5594216fae15bed7c6b5 (diff)
downloadlua-abdbe883a86bbc7fbf1d1bfc50756e1b42fc45b5.tar.gz
lua-abdbe883a86bbc7fbf1d1bfc50756e1b42fc45b5.tar.bz2
lua-abdbe883a86bbc7fbf1d1bfc50756e1b42fc45b5.zip
first implementation of unrestricted static scoping
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c147
1 files changed, 69 insertions, 78 deletions
diff --git a/lparser.c b/lparser.c
index aa79a86a..725c2749 100644
--- a/lparser.c
+++ b/lparser.c
@@ -41,6 +41,7 @@ typedef struct Constdesc {
41typedef struct Breaklabel { 41typedef struct Breaklabel {
42 struct Breaklabel *previous; /* chain */ 42 struct Breaklabel *previous; /* chain */
43 int breaklist; /* list of jumps out of this loop */ 43 int breaklist; /* list of jumps out of this loop */
44 int nactloc; /* # of active local variables outside the breakable structure */
44} Breaklabel; 45} Breaklabel;
45 46
46 47
@@ -163,13 +164,29 @@ static void new_localvar (LexState *ls, TString *name, int n) {
163 164
164static void adjustlocalvars (LexState *ls, int nvars) { 165static void adjustlocalvars (LexState *ls, int nvars) {
165 FuncState *fs = ls->fs; 166 FuncState *fs = ls->fs;
166 while (nvars--) 167 while (nvars--) {
167 fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc; 168 fs->f->locvars[fs->actloc[fs->nactloc]].startpc = fs->pc;
169 resetbit(fs->wasup, fs->nactloc);
170 fs->nactloc++;
171 }
172}
173
174
175static void closelevel (LexState *ls, int level) {
176 FuncState *fs = ls->fs;
177 int i;
178 for (i=level; i<fs->nactloc; i++)
179 if (testbit(fs->wasup, i)) {
180 luaK_codeABC(fs, OP_CLOSE, level, 0, 0);
181 return;
182 }
183 return; /* nothing to close */
168} 184}
169 185
170 186
171static void removelocalvars (LexState *ls, int nvars) { 187static void removelocalvars (LexState *ls, int nvars) {
172 FuncState *fs = ls->fs; 188 FuncState *fs = ls->fs;
189 closelevel(ls, fs->nactloc - nvars);
173 while (nvars--) 190 while (nvars--)
174 fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc; 191 fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc;
175} 192}
@@ -180,68 +197,47 @@ static void new_localvarstr (LexState *ls, const l_char *name, int n) {
180} 197}
181 198
182 199
183static int search_local (LexState *ls, TString *n, expdesc *var) { 200static int indexupvalue (FuncState *fs, expdesc *v) {
184 FuncState *fs;
185 int level = 0;
186 for (fs=ls->fs; fs; fs=fs->prev) {
187 int i;
188 for (i=fs->nactloc-1; i >= 0; i--) {
189 if (n == fs->f->locvars[fs->actloc[i]].varname) {
190 init_exp(var, VLOCAL, i);
191 return level;
192 }
193 }
194 level++; /* `var' not found; check outer level */
195 }
196 init_exp(var, VGLOBAL, 0); /* not found in any level; must be global */
197 return -1;
198}
199
200
201static void singlevar (LexState *ls, TString *n, expdesc *var) {
202 int level = search_local(ls, n, var);
203 if (level >= 1) /* neither local (0) nor global (-1)? */
204 luaX_syntaxerror(ls, l_s("cannot access a variable in outer function"),
205 getstr(n));
206 else if (level == -1) /* global? */
207 var->u.i.info = luaK_stringk(ls->fs, n);
208}
209
210
211static int indexupvalue (LexState *ls, expdesc *v) {
212 FuncState *fs = ls->fs;
213 int i; 201 int i;
214 for (i=0; i<fs->f->nupvalues; i++) { 202 for (i=0; i<fs->f->nupvalues; i++) {
215 if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.i.info == v->u.i.info) 203 if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.i.info == v->u.i.info)
216 return i; 204 return i;
217 } 205 }
218 /* new one */ 206 /* new one */
219 luaX_checklimit(ls, fs->f->nupvalues+1, MAXUPVALUES, l_s("upvalues")); 207 luaX_checklimit(fs->ls, fs->f->nupvalues+1, MAXUPVALUES, l_s("upvalues"));
220 fs->upvalues[fs->f->nupvalues] = *v; 208 fs->upvalues[fs->f->nupvalues] = *v;
221 return fs->f->nupvalues++; 209 return fs->f->nupvalues++;
222} 210}
223 211
224 212
225static void codeupvalue (LexState *ls, expdesc *v, TString *n) { 213static void singlevar (FuncState *fs, TString *n, expdesc *var, int baselevel) {
226 FuncState *fs = ls->fs; 214 if (fs == NULL)
227 int level; 215 init_exp(var, VGLOBAL, 0); /* not local in any level; global variable */
228 level = search_local(ls, n, v); 216 else { /* look up at current level */
229 if (level == -1) { /* global? */ 217 int i;
230 if (fs->prev == NULL) 218 for (i=fs->nactloc-1; i >= 0; i--) {
231 luaX_syntaxerror(ls, l_s("cannot access an upvalue at top level"), 219 if (n == fs->f->locvars[fs->actloc[i]].varname) {
232 getstr(n)); 220 if (!baselevel)
233 v->u.i.info = luaK_stringk(fs->prev, n); 221 setbit(fs->wasup, i); /* will be upvalue in some other level */
234 } 222 init_exp(var, VLOCAL, i);
235 else if (level != 1) { 223 return;
236 luaX_syntaxerror(ls, 224 }
237 l_s("upvalue must be global or local to immediately outer function"), 225 }
238 getstr(n)); 226 /* not found at current level; try upper one */
227 singlevar(fs->prev, n, var, 0);
228 if (var->k == VGLOBAL) {
229 if (baselevel)
230 var->u.i.info = luaK_stringk(fs, n); /* info points to global name */
231 }
232 else { /* local variable in some upper level? */
233 var->u.i.info = indexupvalue(fs, var);
234 var->k = VUPVAL; /* upvalue in this level */
235 }
239 } 236 }
240 init_exp(v, VRELOCABLE,
241 luaK_codeABc(fs, OP_LOADUPVAL, 0, indexupvalue(ls, v)));
242} 237}
243 238
244 239
240
245static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { 241static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
246 FuncState *fs = ls->fs; 242 FuncState *fs = ls->fs;
247 int extra = nvars - nexps; 243 int extra = nvars - nexps;
@@ -278,6 +274,7 @@ static void code_params (LexState *ls, int nparams, short dots) {
278 274
279static void enterbreak (FuncState *fs, Breaklabel *bl) { 275static void enterbreak (FuncState *fs, Breaklabel *bl) {
280 bl->breaklist = NO_JUMP; 276 bl->breaklist = NO_JUMP;
277 bl->nactloc = fs->nactloc;
281 bl->previous = fs->bl; 278 bl->previous = fs->bl;
282 fs->bl = bl; 279 fs->bl = bl;
283} 280}
@@ -286,6 +283,7 @@ static void enterbreak (FuncState *fs, Breaklabel *bl) {
286static void leavebreak (FuncState *fs, Breaklabel *bl) { 283static void leavebreak (FuncState *fs, Breaklabel *bl) {
287 fs->bl = bl->previous; 284 fs->bl = bl->previous;
288 luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs)); 285 luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs));
286 lua_assert(bl->nactloc == fs->nactloc);
289} 287}
290 288
291 289
@@ -293,16 +291,14 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
293 FuncState *fs = ls->fs; 291 FuncState *fs = ls->fs;
294 Proto *f = fs->f; 292 Proto *f = fs->f;
295 int i; 293 int i;
296 int reg = fs->freereg;
297 for (i=0; i<func->f->nupvalues; i++)
298 luaK_exp2nextreg(fs, &func->upvalues[i]);
299 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, 294 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
300 MAXARG_Bc, l_s("constant table overflow")); 295 MAXARG_Bc, l_s("constant table overflow"));
301 f->p[fs->np++] = func->f; 296 f->p[fs->np++] = func->f;
302 fs->freereg = reg; /* CLOSURE will consume those values */ 297 init_exp(v, VRELOCABLE, luaK_codeABc(fs, OP_CLOSURE, 0, fs->np-1));
303 init_exp(v, VNONRELOC, reg); 298 for (i=0; i<func->f->nupvalues; i++) {
304 luaK_reserveregs(fs, 1); 299 luaK_exp2nextreg(fs, &func->upvalues[i]);
305 luaK_codeABc(fs, OP_CLOSURE, v->u.i.info, fs->np-1); 300 fs->freereg--; /* CLOSURE will use these values */
301 }
306} 302}
307 303
308 304
@@ -337,9 +333,9 @@ static void close_func (LexState *ls) {
337 lua_State *L = ls->L; 333 lua_State *L = ls->L;
338 FuncState *fs = ls->fs; 334 FuncState *fs = ls->fs;
339 Proto *f = fs->f; 335 Proto *f = fs->f;
336 removelocalvars(ls, fs->nactloc);
340 luaK_codeABC(fs, OP_RETURN, 0, 0, 0); /* final return */ 337 luaK_codeABC(fs, OP_RETURN, 0, 0, 0); /* final return */
341 luaK_getlabel(fs); /* close eventual list of pending jumps */ 338 luaK_getlabel(fs); /* close eventual list of pending jumps */
342 removelocalvars(ls, fs->nactloc);
343 lua_assert(G(L)->roottable == fs->h); 339 lua_assert(G(L)->roottable == fs->h);
344 G(L)->roottable = fs->h->next; 340 G(L)->roottable = fs->h->next;
345 luaH_free(L, fs->h); 341 luaH_free(L, fs->h);
@@ -644,16 +640,18 @@ static void primaryexp (LexState *ls, expdesc *v) {
644 return; 640 return;
645 } 641 }
646 case TK_NAME: { 642 case TK_NAME: {
647 singlevar(ls, str_checkname(ls), v); 643 singlevar(ls->fs, str_checkname(ls), v, 1);
648 next(ls); 644 next(ls);
649 return; 645 return;
650 } 646 }
651 case l_c('%'): { 647 case l_c('%'): { /* for compatibility only */
652 next(ls); /* skip `%' */ 648 next(ls); /* skip `%' */
653 codeupvalue(ls, v, str_checkname(ls)); 649 singlevar(ls->fs, str_checkname(ls), v, 1);
650 check_condition(ls, v->k == VUPVAL, l_s("global upvalues are deprecated"));
654 next(ls); 651 next(ls);
655 break; 652 return;
656 } 653 }
654
657 default: { 655 default: {
658 luaK_error(ls, l_s("unexpected symbol")); 656 luaK_error(ls, l_s("unexpected symbol"));
659 return; 657 return;
@@ -812,7 +810,7 @@ static void block (LexState *ls) {
812*/ 810*/
813struct LHS_assign { 811struct LHS_assign {
814 struct LHS_assign *prev; 812 struct LHS_assign *prev;
815 expdesc v; /* variable (global, local, or indexed) */ 813 expdesc v; /* variable (global, local, upvalue, or indexed) */
816}; 814};
817 815
818 816
@@ -847,9 +845,8 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
847 845
848static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { 846static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
849 expdesc e; 847 expdesc e;
850 check_condition(ls, lh->v.k == VLOCAL || lh->v.k == VGLOBAL || 848 check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
851 lh->v.k == VINDEXED, 849 l_s("syntax error!!"));
852 l_s("syntax error"));
853 if (ls->t.token == l_c(',')) { /* assignment -> `,' simpleexp assignment */ 850 if (ls->t.token == l_c(',')) { /* assignment -> `,' simpleexp assignment */
854 struct LHS_assign nv; 851 struct LHS_assign nv;
855 nv.prev = lh; 852 nv.prev = lh;
@@ -1054,7 +1051,7 @@ static void localstat (LexState *ls) {
1054static int funcname (LexState *ls, expdesc *v) { 1051static int funcname (LexState *ls, expdesc *v) {
1055 /* funcname -> NAME {field} [`:' NAME] */ 1052 /* funcname -> NAME {field} [`:' NAME] */
1056 int needself = 0; 1053 int needself = 0;
1057 singlevar(ls, str_checkname(ls), v); 1054 singlevar(ls->fs, str_checkname(ls), v, 1);
1058 next(ls); /* skip var name */ 1055 next(ls); /* skip var name */
1059 while (ls->t.token == l_c('.')) { 1056 while (ls->t.token == l_c('.')) {
1060 luaY_field(ls, v); 1057 luaY_field(ls, v);
@@ -1102,25 +1099,19 @@ static void retstat (LexState *ls) {
1102 if (block_follow(ls->t.token) || ls->t.token == l_c(';')) 1099 if (block_follow(ls->t.token) || ls->t.token == l_c(';'))
1103 first = nret = 0; /* return no values */ 1100 first = nret = 0; /* return no values */
1104 else { 1101 else {
1105 int n = explist1(ls, &e); /* optional return values */ 1102 explist1(ls, &e); /* optional return values */
1106 if (e.k == VCALL) { 1103 if (e.k == VCALL) {
1107 luaK_setcallreturns(fs, &e, LUA_MULTRET); 1104 luaK_setcallreturns(fs, &e, LUA_MULTRET);
1108 first = fs->nactloc; 1105 first = fs->nactloc;
1109 nret = NO_REG; /* return all values */ 1106 nret = NO_REG; /* return all values */
1110 } 1107 }
1111 else { 1108 else {
1112 if (n == 1) { /* only one value? */ 1109 luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
1113 luaK_exp2anyreg(fs, &e); 1110 first = fs->nactloc;
1114 first = e.u.i.info; 1111 nret = fs->freereg - first; /* return all `active' values */
1115 nret = 1; /* return only this value */
1116 }
1117 else {
1118 luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
1119 first = fs->nactloc;
1120 nret = fs->freereg - first; /* return all `active' values */
1121 }
1122 } 1112 }
1123 } 1113 }
1114 closelevel(ls, 0);
1124 luaK_codeABC(fs, OP_RETURN, first, nret, 0); 1115 luaK_codeABC(fs, OP_RETURN, first, nret, 0);
1125 fs->freereg = fs->nactloc; /* removes all temp values */ 1116 fs->freereg = fs->nactloc; /* removes all temp values */
1126} 1117}
@@ -1133,8 +1124,8 @@ static void breakstat (LexState *ls) {
1133 if (!bl) 1124 if (!bl)
1134 luaK_error(ls, l_s("no loop to break")); 1125 luaK_error(ls, l_s("no loop to break"));
1135 next(ls); /* skip BREAK */ 1126 next(ls); /* skip BREAK */
1127 closelevel(ls, bl->nactloc);
1136 luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); 1128 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
1137 /* correct stack for compiler and symbolic execution */
1138} 1129}
1139 1130
1140 1131