aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lparser.c233
1 files changed, 100 insertions, 133 deletions
diff --git a/lparser.c b/lparser.c
index 4ddca7a8..67aa21ab 100644
--- a/lparser.c
+++ b/lparser.c
@@ -22,18 +22,6 @@
22#include "lstring.h" 22#include "lstring.h"
23 23
24 24
25/*
26** Constructors descriptor:
27** `n' indicates number of elements, and `k' signals whether
28** it is a list constructor (k = 0) or a record constructor (k = 1)
29** or empty (k = `;' or `}')
30*/
31typedef struct Constdesc {
32 int narray;
33 int nhash;
34 int k;
35} Constdesc;
36
37 25
38/* 26/*
39** nodes for break list (list of active breakable loops) 27** nodes for break list (list of active breakable loops)
@@ -251,7 +239,7 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
251 else { 239 else {
252 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ 240 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
253 if (extra > 0) { 241 if (extra > 0) {
254 int reg = fs->freereg; 242 int reg = fs->freereg;
255 luaK_reserveregs(fs, extra); 243 luaK_reserveregs(fs, extra);
256 luaK_nil(fs, reg, extra); 244 luaK_nil(fs, reg, extra);
257 } 245 }
@@ -469,139 +457,118 @@ static void funcargs (LexState *ls, expdesc *f) {
469*/ 457*/
470 458
471 459
472static void recfield (LexState *ls, expdesc *t) { 460struct ConsControl {
461 expdesc v; /* last list item read */
462 expdesc *t; /* table descriptor */
463 int nh; /* total number of `record' elements */
464 int na; /* total number of array elements */
465 int tostore; /* number of array elements pending to be stored */
466};
467
468
469static void recfield (LexState *ls, struct ConsControl *cc) {
473 /* recfield -> (NAME | `['exp1`]') = exp1 */ 470 /* recfield -> (NAME | `['exp1`]') = exp1 */
474 FuncState *fs = ls->fs; 471 FuncState *fs = ls->fs;
475 int reg = ls->fs->freereg; 472 int reg = ls->fs->freereg;
476 expdesc key, val; 473 expdesc key, val;
477 switch (ls->t.token) { 474 if (ls->t.token == TK_NAME)
478 case TK_NAME: { 475 checkname(ls, &key);
479 checkname(ls, &key); 476 else /* ls->t.token == '[' */
480 break; 477 luaY_index(ls, &key);
481 }
482 case '[': {
483 luaY_index(ls, &key);
484 break;
485 }
486 default: luaK_error(ls, "<name> or `[' expected");
487 }
488 check(ls, '='); 478 check(ls, '=');
489 luaK_exp2RK(fs, &key); 479 luaK_exp2RK(fs, &key);
490 expr(ls, &val); 480 expr(ls, &val);
491 luaK_exp2anyreg(fs, &val); 481 luaK_exp2anyreg(fs, &val);
492 luaK_codeABC(fs, OP_SETTABLE, val.info, t->info, 482 luaK_codeABC(fs, OP_SETTABLE, val.info, cc->t->info, luaK_exp2RK(fs, &key));
493 luaK_exp2RK(fs, &key));
494 fs->freereg = reg; /* free registers */ 483 fs->freereg = reg; /* free registers */
484 luaX_checklimit(ls, cc->nh, MAX_INT, "items in a constructor");
485 cc->nh++;
495} 486}
496 487
497 488
498static int anotherfield (LexState *ls) { 489static void closelistfield (FuncState *fs, struct ConsControl *cc) {
499 if (ls->t.token != ',') return 0; 490 if (cc->v.k == VVOID) return; /* there is no list item */
500 next(ls); /* skip the comma */ 491 luaK_exp2nextreg(fs, &cc->v);
501 return (ls->t.token != ';' && ls->t.token != '}'); 492 cc->v.k = VVOID;
502} 493 if (cc->tostore == LFIELDS_PER_FLUSH) {
503 494 luaK_codeABc(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */
504 495 cc->tostore = 0; /* no more items pending */
505static int recfields (LexState *ls, expdesc *t) { 496 fs->freereg = cc->t->info + 1; /* free registers */
506 /* recfields -> recfield { `,' recfield } [`,'] */ 497 }
507 int n = 0;
508 do { /* at least one element */
509 recfield(ls, t);
510 luaX_checklimit(ls, n, MAX_INT, "items in a constructor");
511 n++;
512 } while (anotherfield(ls));
513 return n;
514} 498}
515 499
516 500
517static int listfields (LexState *ls, expdesc *t) { 501static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
518 /* listfields -> exp1 { `,' exp1 } [`,'] */ 502 if (cc->tostore == 0) return;
519 expdesc v; 503 if (cc->v.k == VCALL) {
520 FuncState *fs = ls->fs; 504 luaK_setcallreturns(fs, &cc->v, LUA_MULTRET);
521 int n = 1; /* at least one element */ 505 luaK_codeABc(fs, OP_SETLISTO, cc->t->info, cc->na-1);
522 int reg;
523 reg = fs->freereg;
524 expr(ls, &v);
525 while (anotherfield(ls)) {
526 luaK_exp2nextreg(fs, &v);
527 luaX_checklimit(ls, n, MAXARG_Bc, "items in a constructor");
528 if (n%LFIELDS_PER_FLUSH == 0) {
529 luaK_codeABc(fs, OP_SETLIST, t->info, n-1); /* flush */
530 fs->freereg = reg; /* free registers */
531 }
532 expr(ls, &v);
533 n++;
534 }
535 if (v.k == VCALL) {
536 luaK_setcallreturns(fs, &v, LUA_MULTRET);
537 luaK_codeABc(fs, OP_SETLISTO, t->info, n-1);
538 } 506 }
539 else { 507 else {
540 luaK_exp2nextreg(fs, &v); 508 if (cc->v.k != VVOID)
541 luaK_codeABc(fs, OP_SETLIST, t->info, n-1); 509 luaK_exp2nextreg(fs, &cc->v);
510 luaK_codeABc(fs, OP_SETLIST, cc->t->info, cc->na-1);
542 } 511 }
543 fs->freereg = reg; /* free registers */ 512 fs->freereg = cc->t->info + 1; /* free registers */
544 return n;
545} 513}
546 514
547 515
548static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { 516static void listfield (LexState *ls, struct ConsControl *cc) {
549 switch (ls->t.token) { 517 expr(ls, &cc->v);
550 case ';': case '}': { /* constructor_part -> empty */ 518 luaX_checklimit(ls, cc->na, MAXARG_Bc, "items in a constructor");
551 cd->narray = cd->nhash = 0; 519 cc->na++;
552 cd->k = ls->t.token; 520 cc->tostore++;
553 break;
554 }
555 case TK_NAME: { /* may be listfields or recfields */
556 lookahead(ls);
557 if (ls->lookahead.token != '=') /* expression? */
558 goto case_default;
559 /* else go through to recfields */
560 }
561 case '[': { /* constructor_part -> recfields */
562 cd->nhash = recfields(ls, t);
563 cd->narray = 0;
564 cd->k = 1; /* record */
565 break;
566 }
567 default: { /* constructor_part -> listfields */
568 case_default:
569 cd->narray = listfields(ls, t);
570 cd->nhash = 0;
571 cd->k = 0; /* list */
572 break;
573 }
574 }
575} 521}
576 522
577 523
578static void constructor (LexState *ls, expdesc *t) { 524static void constructor (LexState *ls, expdesc *t) {
579 /* constructor -> `{' constructor_part [`;' constructor_part] `}' */ 525 /* constructor -> ?? */
580 FuncState *fs = ls->fs; 526 FuncState *fs = ls->fs;
581 int line = ls->linenumber; 527 int line = ls->linenumber;
582 int na, nh; 528 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
583 int pc; 529 struct ConsControl cc;
584 Constdesc cd; 530 cc.na = cc.nh = cc.tostore = 0;
585 pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); 531 cc.t = t;
586 init_exp(t, VRELOCABLE, pc); 532 init_exp(t, VRELOCABLE, pc);
533 init_exp(&cc.v, VVOID, 0); /* no value (yet) */
587 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ 534 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
588 check(ls, '{'); 535 check(ls, '{');
589 constructor_part(ls, t, &cd); 536 for (;;) {
590 na = cd.narray; 537 lua_assert(cc.v.k == VVOID || cc.tostore > 0);
591 nh = cd.nhash; 538 optional(ls, ';'); /* compatibility only */
592 if (optional(ls, ';')) { 539 if (ls->t.token == '}') break;
593 Constdesc other_cd; 540 closelistfield(fs, &cc);
594 constructor_part(ls, t, &other_cd); 541 switch(ls->t.token) {
595 check_condition(ls,(cd.k != other_cd.k), "invalid constructor syntax"); 542 case TK_NAME: { /* may be listfields or recfields */
596 na += other_cd.narray; 543 lookahead(ls);
597 nh += other_cd.nhash; 544 if (ls->lookahead.token != '=') /* expression? */
545 listfield(ls, &cc);
546 else
547 recfield(ls, &cc);
548 break;
549 }
550 case '[': { /* constructor_item -> recfield */
551 recfield(ls, &cc);
552 break;
553 }
554 default: { /* constructor_part -> listfield */
555 listfield(ls, &cc);
556 break;
557 }
558 }
559 if (ls->t.token == ',' || ls->t.token == ';')
560 next(ls);
561 else
562 break;
598 } 563 }
599 check_match(ls, '}', '{', line); 564 check_match(ls, '}', '{', line);
600 if (na > 0) 565 lastlistfield(fs, &cc);
601 SETARG_B(fs->f->code[pc], luaO_log2(na-1)+2); /* set initial table size */ 566 if (cc.na > 0)
602 SETARG_C(fs->f->code[pc], luaO_log2(nh)+1); /* set initial table size */ 567 SETARG_B(fs->f->code[pc], luaO_log2(cc.na-1)+2); /* set initial table size */
568 SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */
603} 569}
604 570
571
605/* }====================================================================== */ 572/* }====================================================================== */
606 573
607 574
@@ -955,24 +922,27 @@ static void exp1 (LexState *ls) {
955} 922}
956 923
957 924
958static void forbody (LexState *ls, int nvar, OpCode loopfor) { 925static void forbody (LexState *ls, OpCode loopfor) {
959 /* forbody -> DO block END */ 926 /* forbody -> DO block END */
960 FuncState *fs = ls->fs; 927 FuncState *fs = ls->fs;
961 int basereg = fs->freereg - nvar; 928 int basereg = fs->freereg - 3;
962 int prep = luaK_jump(fs); 929 int prep = luaK_jump(fs);
963 int blockinit = luaK_getlabel(fs); 930 int blockinit = luaK_getlabel(fs);
964 check(ls, TK_DO); 931 check(ls, TK_DO);
965 adjustlocalvars(ls, nvar); /* scope for control variables */ 932 adjustlocalvars(ls, 3); /* scope for control variables */
966 block(ls); 933 block(ls);
967 luaK_patchlist(fs, prep, luaK_getlabel(fs)); 934 luaK_patchlist(fs, prep, luaK_getlabel(fs));
968 luaK_patchlist(fs, luaK_codeAsBc(fs, loopfor, basereg, NO_JUMP), blockinit); 935 luaK_patchlist(fs, luaK_codeAsBc(fs, loopfor, basereg, NO_JUMP), blockinit);
969 removelocalvars(ls, nvar, 1); 936 removelocalvars(ls, 3, 1);
970} 937}
971 938
972 939
973static void fornum (LexState *ls, TString *varname) { 940static void fornum (LexState *ls, TString *varname) {
974 /* fornum -> NAME = exp1,exp1[,exp1] forbody */ 941 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
975 FuncState *fs = ls->fs; 942 FuncState *fs = ls->fs;
943 new_localvar(ls, varname, 0);
944 new_localvarstr(ls, "(limit)", 1);
945 new_localvarstr(ls, "(step)", 2);
976 check(ls, '='); 946 check(ls, '=');
977 exp1(ls); /* initial value */ 947 exp1(ls); /* initial value */
978 check(ls, ','); 948 check(ls, ',');
@@ -983,30 +953,27 @@ static void fornum (LexState *ls, TString *varname) {
983 luaK_codeABc(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); 953 luaK_codeABc(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
984 luaK_reserveregs(fs, 1); 954 luaK_reserveregs(fs, 1);
985 } 955 }
986 new_localvar(ls, varname, 0);
987 new_localvarstr(ls, "(limit)", 1);
988 new_localvarstr(ls, "(step)", 2);
989 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1); 956 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1);
990 forbody(ls, 3, OP_FORLOOP); 957 forbody(ls, OP_FORLOOP);
991} 958}
992 959
993 960
994static void forlist (LexState *ls, TString *indexname) { 961static void forlist (LexState *ls, TString *indexname) {
995 /* forlist -> NAME,NAME IN exp1 forbody */ 962 /* forlist -> NAME,NAME IN exp1 forbody */
996 TString *valname;
997 FuncState *fs = ls->fs; 963 FuncState *fs = ls->fs;
998 check(ls, ','); 964 new_localvarstr(ls, "(table)", 0);
999 valname = str_checkname(ls); 965 new_localvar(ls, indexname, 1);
1000 next(ls); /* skip var name */ 966 if (optional(ls, ',')) {
967 new_localvar(ls, str_checkname(ls), 2);
968 next(ls); /* skip var name */
969 }
970 else
971 new_localvarstr(ls, "(val)", 2);
1001 check(ls, TK_IN); 972 check(ls, TK_IN);
1002 exp1(ls); /* table */ 973 exp1(ls); /* table */
1003 new_localvarstr(ls, "(table)", 0); 974 luaK_reserveregs(fs, 2); /* registers for index and val */
1004 new_localvarstr(ls, "(index)", 1); 975 luaK_codeABC(fs, OP_LOADNIL, fs->freereg - 2, fs->freereg - 1, 0);
1005 new_localvar(ls, indexname, 2); 976 forbody(ls, OP_TFORLOOP);
1006 new_localvar(ls, valname, 3);
1007 luaK_reserveregs(fs, 3); /* registers for control, index and val */
1008 luaK_codeABc(fs, OP_LOADK, fs->freereg - 3, luaK_numberK(fs, -1));
1009 forbody(ls, 4, OP_TFORLOOP);
1010} 977}
1011 978
1012 979
@@ -1021,8 +988,8 @@ static void forstat (LexState *ls, int line) {
1021 next(ls); /* skip var name */ 988 next(ls); /* skip var name */
1022 switch (ls->t.token) { 989 switch (ls->t.token) {
1023 case '=': fornum(ls, varname); break; 990 case '=': fornum(ls, varname); break;
1024 case ',': forlist(ls, varname); break; 991 case ',': case TK_IN: forlist(ls, varname); break;
1025 default: luaK_error(ls, "`=' or `,' expected"); 992 default: luaK_error(ls, "`=' or `in' expected");
1026 } 993 }
1027 check_match(ls, TK_END, TK_FOR, line); 994 check_match(ls, TK_END, TK_FOR, line);
1028 leavebreak(fs, &bl); 995 leavebreak(fs, &bl);