aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-08-27 18:01:44 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-08-27 18:01:44 -0300
commit8332d5c8a5059b85da1adaa3f0197d0f57afae81 (patch)
tree8a2f59ff0803da3afbc7e8a409911c920d624e94 /lparser.c
parent885961be1d8e3f703b54d1d19e6c63617cd2ed24 (diff)
downloadlua-8332d5c8a5059b85da1adaa3f0197d0f57afae81.tar.gz
lua-8332d5c8a5059b85da1adaa3f0197d0f57afae81.tar.bz2
lua-8332d5c8a5059b85da1adaa3f0197d0f57afae81.zip
parser fully reentrant(!)
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/lparser.c b/lparser.c
index 1eb56401..633a5693 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.215 2003/07/29 18:51:00 roberto Exp roberto $ 2** $Id: lparser.c,v 1.216 2003/08/25 19:51:54 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,6 +13,7 @@
13 13
14#include "lcode.h" 14#include "lcode.h"
15#include "ldebug.h" 15#include "ldebug.h"
16#include "ldo.h"
16#include "lfunc.h" 17#include "lfunc.h"
17#include "llex.h" 18#include "llex.h"
18#include "lmem.h" 19#include "lmem.h"
@@ -71,6 +72,14 @@ static void lookahead (LexState *ls) {
71} 72}
72 73
73 74
75static void anchor_token (LexState *ls) {
76 if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
77 TString *ts = ls->t.seminfo.ts;
78 luaX_newstring(ls, getstr(ts), ts->tsv.len);
79 }
80}
81
82
74static void error_expected (LexState *ls, int token) { 83static void error_expected (LexState *ls, int token) {
75 luaX_syntaxerror(ls, 84 luaX_syntaxerror(ls,
76 luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token))); 85 luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token)));
@@ -138,9 +147,11 @@ static void checkname(LexState *ls, expdesc *e) {
138static int luaI_registerlocalvar (LexState *ls, TString *varname) { 147static int luaI_registerlocalvar (LexState *ls, TString *varname) {
139 FuncState *fs = ls->fs; 148 FuncState *fs = ls->fs;
140 Proto *f = fs->f; 149 Proto *f = fs->f;
150 int oldsize = f->sizelocvars;
141 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, 151 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
142 LocVar, USHRT_MAX, "too many local variables"); 152 LocVar, USHRT_MAX, "too many local variables");
143 f->locvars[fs->nlocvars].varname = varname; 153 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
154 f->locvars[fs->nlocvars].varname = varname; /* write barrier */
144 return fs->nlocvars++; 155 return fs->nlocvars++;
145} 156}
146 157
@@ -170,24 +181,27 @@ static void removevars (LexState *ls, int tolevel) {
170 181
171 182
172static void new_localvarstr (LexState *ls, const char *name, int n) { 183static void new_localvarstr (LexState *ls, const char *name, int n) {
173 new_localvar(ls, luaS_new(ls->L, name), n); 184 TString *ts = luaX_newstring(ls, name, strlen(name));
185 new_localvar(ls, ts, n);
174} 186}
175 187
176 188
177static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { 189static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
178 int i; 190 int i;
179 Proto *f = fs->f; 191 Proto *f = fs->f;
192 int oldsize = f->sizeupvalues;
180 for (i=0; i<f->nups; i++) { 193 for (i=0; i<f->nups; i++) {
181 if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) { 194 if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) {
182 lua_assert(fs->f->upvalues[i] == name); 195 lua_assert(f->upvalues[i] == name);
183 return i; 196 return i;
184 } 197 }
185 } 198 }
186 /* new one */ 199 /* new one */
187 luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues"); 200 luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues");
188 luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues, 201 luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
189 TString *, MAX_INT, ""); 202 TString *, MAX_INT, "");
190 fs->f->upvalues[f->nups] = name; 203 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
204 f->upvalues[f->nups] = name; /* write barrier */
191 lua_assert(v->k == VLOCAL || v->k == VUPVAL); 205 lua_assert(v->k == VLOCAL || v->k == VUPVAL);
192 fs->upvalues[f->nups].k = cast(lu_byte, v->k); 206 fs->upvalues[f->nups].k = cast(lu_byte, v->k);
193 fs->upvalues[f->nups].info = cast(lu_byte, v->info); 207 fs->upvalues[f->nups].info = cast(lu_byte, v->info);
@@ -290,10 +304,12 @@ static void leaveblock (FuncState *fs) {
290static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { 304static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
291 FuncState *fs = ls->fs; 305 FuncState *fs = ls->fs;
292 Proto *f = fs->f; 306 Proto *f = fs->f;
307 int oldsize = f->sizep;
293 int i; 308 int i;
294 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, 309 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
295 MAXARG_Bx, "constant table overflow"); 310 MAXARG_Bx, "constant table overflow");
296 f->p[fs->np++] = func->f; 311 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
312 f->p[fs->np++] = func->f; /* write barrier */
297 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); 313 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
298 for (i=0; i<func->f->nups; i++) { 314 for (i=0; i<func->f->nups; i++) {
299 OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; 315 OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
@@ -303,24 +319,30 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
303 319
304 320
305static void open_func (LexState *ls, FuncState *fs) { 321static void open_func (LexState *ls, FuncState *fs) {
322 lua_State *L = ls->L;
306 Proto *f = luaF_newproto(ls->L); 323 Proto *f = luaF_newproto(ls->L);
307 fs->f = f; 324 fs->f = f;
308 fs->prev = ls->fs; /* linked list of funcstates */ 325 fs->prev = ls->fs; /* linked list of funcstates */
309 fs->ls = ls; 326 fs->ls = ls;
310 fs->L = ls->L; 327 fs->L = L;
311 ls->fs = fs; 328 ls->fs = fs;
312 fs->pc = 0; 329 fs->pc = 0;
313 fs->lasttarget = 0; 330 fs->lasttarget = 0;
314 fs->jpc = NO_JUMP; 331 fs->jpc = NO_JUMP;
315 fs->freereg = 0; 332 fs->freereg = 0;
316 fs->nk = 0; 333 fs->nk = 0;
317 fs->h = luaH_new(ls->L, 0, 0);
318 fs->np = 0; 334 fs->np = 0;
319 fs->nlocvars = 0; 335 fs->nlocvars = 0;
320 fs->nactvar = 0; 336 fs->nactvar = 0;
321 fs->bl = NULL; 337 fs->bl = NULL;
322 f->source = ls->source; 338 f->source = ls->source;
323 f->maxstacksize = 2; /* registers 0/1 are always valid */ 339 f->maxstacksize = 2; /* registers 0/1 are always valid */
340 fs->h = luaH_new(L, 0, 0);
341 /* anchor table of constants and prototype (to avoid being collected) */
342 sethvalue2s(L->top, fs->h);
343 incr_top(L);
344 setptvalue2s(L->top, f);
345 incr_top(L);
324} 346}
325 347
326 348
@@ -345,6 +367,9 @@ static void close_func (LexState *ls) {
345 lua_assert(luaG_checkcode(f)); 367 lua_assert(luaG_checkcode(f));
346 lua_assert(fs->bl == NULL); 368 lua_assert(fs->bl == NULL);
347 ls->fs = fs->prev; 369 ls->fs = fs->prev;
370 L->top -= 2; /* remove table and prototype from the stack */
371 /* last token read was anchored in defunct function; must reanchor it */
372 if (fs) anchor_token(ls);
348} 373}
349 374
350 375
@@ -362,6 +387,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
362 lua_assert(funcstate.prev == NULL); 387 lua_assert(funcstate.prev == NULL);
363 lua_assert(funcstate.f->nups == 0); 388 lua_assert(funcstate.f->nups == 0);
364 lua_assert(lexstate.nestlevel == 0); 389 lua_assert(lexstate.nestlevel == 0);
390 lua_assert(lexstate.fs == NULL);
365 return funcstate.f; 391 return funcstate.f;
366} 392}
367 393
@@ -530,7 +556,7 @@ static void parlist (LexState *ls) {
530 case TK_DOTS: { /* param -> `...' */ 556 case TK_DOTS: { /* param -> `...' */
531 next(ls); 557 next(ls);
532 /* use `arg' as default name */ 558 /* use `arg' as default name */
533 new_localvar(ls, luaS_new(ls->L, "arg"), nparams++); 559 new_localvarstr(ls, "arg", nparams++);
534 f->is_vararg = 1; 560 f->is_vararg = 1;
535 break; 561 break;
536 } 562 }