diff options
Diffstat (limited to '')
| -rw-r--r-- | lparser.c | 36 |
1 files changed, 21 insertions, 15 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.157 2001/09/25 17:06:48 roberto Exp $ | 2 | ** $Id: lparser.c,v 1.159 2001/10/02 16:41:36 roberto Exp $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -30,7 +30,8 @@ | |||
| 30 | ** or empty (k = `;' or `}') | 30 | ** or empty (k = `;' or `}') |
| 31 | */ | 31 | */ |
| 32 | typedef struct Constdesc { | 32 | typedef struct Constdesc { |
| 33 | int n; | 33 | int narray; |
| 34 | int nhash; | ||
| 34 | int k; | 35 | int k; |
| 35 | } Constdesc; | 36 | } Constdesc; |
| 36 | 37 | ||
| @@ -315,7 +316,7 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
| 315 | fs->jlt = NO_JUMP; | 316 | fs->jlt = NO_JUMP; |
| 316 | fs->freereg = 0; | 317 | fs->freereg = 0; |
| 317 | fs->nk = 0; | 318 | fs->nk = 0; |
| 318 | fs->h = luaH_new(ls->L, 0); | 319 | fs->h = luaH_new(ls->L, 0, 0); |
| 319 | fs->np = 0; | 320 | fs->np = 0; |
| 320 | fs->nlineinfo = 0; | 321 | fs->nlineinfo = 0; |
| 321 | fs->nlocvars = 0; | 322 | fs->nlocvars = 0; |
| @@ -507,6 +508,7 @@ static int recfields (LexState *ls, expdesc *t) { | |||
| 507 | int n = 0; | 508 | int n = 0; |
| 508 | do { /* at least one element */ | 509 | do { /* at least one element */ |
| 509 | recfield(ls, t); | 510 | recfield(ls, t); |
| 511 | luaX_checklimit(ls, n, MAX_INT, l_s("items in a constructor")); | ||
| 510 | n++; | 512 | n++; |
| 511 | } while (anotherfield(ls)); | 513 | } while (anotherfield(ls)); |
| 512 | return n; | 514 | return n; |
| @@ -523,8 +525,7 @@ static int listfields (LexState *ls, expdesc *t) { | |||
| 523 | expr(ls, &v); | 525 | expr(ls, &v); |
| 524 | while (anotherfield(ls)) { | 526 | while (anotherfield(ls)) { |
| 525 | luaK_exp2nextreg(fs, &v); | 527 | luaK_exp2nextreg(fs, &v); |
| 526 | luaX_checklimit(ls, n, MAXARG_Bc, | 528 | luaX_checklimit(ls, n, MAXARG_Bc, l_s("items in a constructor")); |
| 527 | l_s("`item groups' in a list initializer")); | ||
| 528 | if (n%LFIELDS_PER_FLUSH == 0) { | 529 | if (n%LFIELDS_PER_FLUSH == 0) { |
| 529 | luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); /* flush */ | 530 | luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); /* flush */ |
| 530 | fs->freereg = reg; /* free registers */ | 531 | fs->freereg = reg; /* free registers */ |
| @@ -548,7 +549,7 @@ static int listfields (LexState *ls, expdesc *t) { | |||
| 548 | static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { | 549 | static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { |
| 549 | switch (ls->t.token) { | 550 | switch (ls->t.token) { |
| 550 | case l_c(';'): case l_c('}'): { /* constructor_part -> empty */ | 551 | case l_c(';'): case l_c('}'): { /* constructor_part -> empty */ |
| 551 | cd->n = 0; | 552 | cd->narray = cd->nhash = 0; |
| 552 | cd->k = ls->t.token; | 553 | cd->k = ls->t.token; |
| 553 | break; | 554 | break; |
| 554 | } | 555 | } |
| @@ -559,13 +560,15 @@ static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { | |||
| 559 | /* else go through to recfields */ | 560 | /* else go through to recfields */ |
| 560 | } | 561 | } |
| 561 | case l_c('['): { /* constructor_part -> recfields */ | 562 | case l_c('['): { /* constructor_part -> recfields */ |
| 562 | cd->n = recfields(ls, t); | 563 | cd->nhash = recfields(ls, t); |
| 564 | cd->narray = 0; | ||
| 563 | cd->k = 1; /* record */ | 565 | cd->k = 1; /* record */ |
| 564 | break; | 566 | break; |
| 565 | } | 567 | } |
| 566 | default: { /* constructor_part -> listfields */ | 568 | default: { /* constructor_part -> listfields */ |
| 567 | case_default: | 569 | case_default: |
| 568 | cd->n = listfields(ls, t); | 570 | cd->narray = listfields(ls, t); |
| 571 | cd->nhash = 0; | ||
| 569 | cd->k = 0; /* list */ | 572 | cd->k = 0; /* list */ |
| 570 | break; | 573 | break; |
| 571 | } | 574 | } |
| @@ -577,24 +580,27 @@ static void constructor (LexState *ls, expdesc *t) { | |||
| 577 | /* constructor -> `{' constructor_part [`;' constructor_part] `}' */ | 580 | /* constructor -> `{' constructor_part [`;' constructor_part] `}' */ |
| 578 | FuncState *fs = ls->fs; | 581 | FuncState *fs = ls->fs; |
| 579 | int line = ls->linenumber; | 582 | int line = ls->linenumber; |
| 580 | int n; | 583 | int na, nh; |
| 581 | int pc; | 584 | int pc; |
| 582 | Constdesc cd; | 585 | Constdesc cd; |
| 583 | pc = luaK_codeABc(fs, OP_NEWTABLE, 0, 0); | 586 | pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); |
| 584 | init_exp(t, VRELOCABLE, pc); | 587 | init_exp(t, VRELOCABLE, pc); |
| 585 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ | 588 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ |
| 586 | check(ls, l_c('{')); | 589 | check(ls, l_c('{')); |
| 587 | constructor_part(ls, t, &cd); | 590 | constructor_part(ls, t, &cd); |
| 588 | n = cd.n; | 591 | na = cd.narray; |
| 592 | nh = cd.nhash; | ||
| 589 | if (optional(ls, l_c(';'))) { | 593 | if (optional(ls, l_c(';'))) { |
| 590 | Constdesc other_cd; | 594 | Constdesc other_cd; |
| 591 | constructor_part(ls, t, &other_cd); | 595 | constructor_part(ls, t, &other_cd); |
| 592 | check_condition(ls, (cd.k != other_cd.k), l_s("invalid constructor syntax")); | 596 | check_condition(ls,(cd.k != other_cd.k), l_s("invalid constructor syntax")); |
| 593 | n += other_cd.n; | 597 | na += other_cd.narray; |
| 598 | nh += other_cd.nhash; | ||
| 594 | } | 599 | } |
| 595 | check_match(ls, l_c('}'), l_c('{'), line); | 600 | check_match(ls, l_c('}'), l_c('{'), line); |
| 596 | luaX_checklimit(ls, n, MAXARG_Bc, l_s("elements in a table constructor")); | 601 | if (na > 0) |
| 597 | SETARG_Bc(fs->f->code[pc], n); /* set initial table size */ | 602 | SETARG_B(fs->f->code[pc], luaO_log2(na-1)+2); /* set initial table size */ |
| 603 | SETARG_C(fs->f->code[pc], luaO_log2(nh)+1); /* set initial table size */ | ||
| 598 | } | 604 | } |
| 599 | 605 | ||
| 600 | /* }====================================================================== */ | 606 | /* }====================================================================== */ |
