aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c97
1 files changed, 52 insertions, 45 deletions
diff --git a/lparser.c b/lparser.c
index ed1b3081..84bc5f25 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.125 2012/01/23 23:05:18 roberto Exp roberto $ 2** $Id: lparser.c,v 2.126 2012/04/20 19:20:05 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*/
@@ -493,21 +493,30 @@ static void leaveblock (FuncState *fs) {
493 493
494 494
495/* 495/*
496** adds prototype being created into its parent list of prototypes 496** adds a new prototype into list of prototypes
497** and codes instruction to create new closure
498*/ 497*/
499static void codeclosure (LexState *ls, Proto *clp, expdesc *v) { 498static Proto *addprototype (LexState *ls) {
500 FuncState *fs = ls->fs->prev; 499 Proto *clp;
501 Proto *f = fs->f; /* prototype of function creating new closure */ 500 lua_State *L = ls->L;
501 FuncState *fs = ls->fs;
502 Proto *f = fs->f; /* prototype of current function */
502 if (fs->np >= f->sizep) { 503 if (fs->np >= f->sizep) {
503 int oldsize = f->sizep; 504 int oldsize = f->sizep;
504 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, 505 luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
505 MAXARG_Bx, "functions");
506 while (oldsize < f->sizep) f->p[oldsize++] = NULL; 506 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
507 } 507 }
508 f->p[fs->np++] = clp; 508 f->p[fs->np++] = clp = luaF_newproto(L);
509 luaC_objbarrier(ls->L, f, clp); 509 luaC_objbarrier(L, f, clp);
510 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); 510 return clp;
511}
512
513
514/*
515** codes instruction to create new closure in parent function
516*/
517static void codeclosure (LexState *ls, expdesc *v) {
518 FuncState *fs = ls->fs->prev;
519 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
511 luaK_exp2nextreg(fs, v); /* fix it at stack top (for GC) */ 520 luaK_exp2nextreg(fs, v); /* fix it at stack top (for GC) */
512} 521}
513 522
@@ -529,13 +538,9 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
529 fs->nactvar = 0; 538 fs->nactvar = 0;
530 fs->firstlocal = ls->dyd->actvar.n; 539 fs->firstlocal = ls->dyd->actvar.n;
531 fs->bl = NULL; 540 fs->bl = NULL;
532 f = luaF_newproto(L); 541 f = fs->f;
533 fs->f = f;
534 f->source = ls->source; 542 f->source = ls->source;
535 f->maxstacksize = 2; /* registers 0/1 are always valid */ 543 f->maxstacksize = 2; /* registers 0/1 are always valid */
536 /* anchor prototype (to avoid being collected) */
537 setptvalue2s(L, L->top, f);
538 incr_top(L);
539 fs->h = luaH_new(L); 544 fs->h = luaH_new(L);
540 /* anchor table of constants (to avoid being collected) */ 545 /* anchor table of constants (to avoid being collected) */
541 sethvalue2s(L, L->top, fs->h); 546 sethvalue2s(L, L->top, fs->h);
@@ -568,20 +573,6 @@ static void close_func (LexState *ls) {
568 anchor_token(ls); 573 anchor_token(ls);
569 L->top--; /* pop table of constants */ 574 L->top--; /* pop table of constants */
570 luaC_checkGC(L); 575 luaC_checkGC(L);
571 L->top--; /* pop prototype (after possible collection) */
572}
573
574
575/*
576** opens the main function, which is a regular vararg function with an
577** upvalue named LUA_ENV
578*/
579static void open_mainfunc (LexState *ls, FuncState *fs, BlockCnt *bl) {
580 expdesc v;
581 open_func(ls, fs, bl);
582 fs->f->is_vararg = 1; /* main function is always vararg */
583 init_exp(&v, VLOCAL, 0);
584 newupvalue(fs, ls->envn, &v); /* create environment upvalue */
585} 576}
586 577
587 578
@@ -795,8 +786,9 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) {
795 /* body -> `(' parlist `)' block END */ 786 /* body -> `(' parlist `)' block END */
796 FuncState new_fs; 787 FuncState new_fs;
797 BlockCnt bl; 788 BlockCnt bl;
798 open_func(ls, &new_fs, &bl); 789 new_fs.f = addprototype(ls);
799 new_fs.f->linedefined = line; 790 new_fs.f->linedefined = line;
791 open_func(ls, &new_fs, &bl);
800 checknext(ls, '('); 792 checknext(ls, '(');
801 if (ismethod) { 793 if (ismethod) {
802 new_localvarliteral(ls, "self"); /* create 'self' parameter */ 794 new_localvarliteral(ls, "self"); /* create 'self' parameter */
@@ -807,7 +799,7 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) {
807 statlist(ls); 799 statlist(ls);
808 new_fs.f->lastlinedefined = ls->linenumber; 800 new_fs.f->lastlinedefined = ls->linenumber;
809 check_match(ls, TK_END, TK_FUNCTION, line); 801 check_match(ls, TK_END, TK_FUNCTION, line);
810 codeclosure(ls, new_fs.f, e); 802 codeclosure(ls, e);
811 close_func(ls); 803 close_func(ls);
812} 804}
813 805
@@ -1596,27 +1588,42 @@ static void statement (LexState *ls) {
1596/* }====================================================================== */ 1588/* }====================================================================== */
1597 1589
1598 1590
1599Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 1591/*
1600 Dyndata *dyd, const char *name, int firstchar) { 1592** compiles the main function, which is a regular vararg function with an
1593** upvalue named LUA_ENV
1594*/
1595static void mainfunc (LexState *ls, FuncState *fs) {
1596 BlockCnt bl;
1597 expdesc v;
1598 open_func(ls, fs, &bl);
1599 fs->f->is_vararg = 1; /* main function is always vararg */
1600 init_exp(&v, VLOCAL, 0); /* create and... */
1601 newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
1602 luaX_next(ls); /* read first token */
1603 statlist(ls); /* parse main body */
1604 check(ls, TK_EOS);
1605 close_func(ls);
1606}
1607
1608
1609Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
1610 Dyndata *dyd, const char *name, int firstchar) {
1601 LexState lexstate; 1611 LexState lexstate;
1602 FuncState funcstate; 1612 FuncState funcstate;
1603 BlockCnt bl; 1613 Closure *cl = luaF_newLclosure(L, 1); /* create main closure */
1604 TString *tname = luaS_new(L, name); 1614 /* anchor closure (to avoid being collected) */
1605 setsvalue2s(L, L->top, tname); /* push name to protect it */ 1615 setclLvalue(L, L->top, cl);
1606 incr_top(L); 1616 incr_top(L);
1617 funcstate.f = cl->l.p = luaF_newproto(L);
1618 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
1607 lexstate.buff = buff; 1619 lexstate.buff = buff;
1608 lexstate.dyd = dyd; 1620 lexstate.dyd = dyd;
1609 dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; 1621 dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
1610 luaX_setinput(L, &lexstate, z, tname, firstchar); 1622 luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
1611 open_mainfunc(&lexstate, &funcstate, &bl); 1623 mainfunc(&lexstate, &funcstate);
1612 luaX_next(&lexstate); /* read first token */
1613 statlist(&lexstate); /* main body */
1614 check(&lexstate, TK_EOS);
1615 close_func(&lexstate);
1616 L->top--; /* pop name */
1617 lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); 1624 lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
1618 /* all scopes should be correctly finished */ 1625 /* all scopes should be correctly finished */
1619 lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); 1626 lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
1620 return funcstate.f; 1627 return cl; /* it's on the stack too */
1621} 1628}
1622 1629