aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-09 10:57:37 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-09 10:57:37 -0300
commite3cf93ddb677fe9482563a5687d3bf3e05ca0407 (patch)
treec692a19e5597c785c198d558a07dd0571f3fa98c /lparser.c
parent88b306f495fa7034c708c6b75a355a6deee51c58 (diff)
downloadlua-e3cf93ddb677fe9482563a5687d3bf3e05ca0407.tar.gz
lua-e3cf93ddb677fe9482563a5687d3bf3e05ca0407.tar.bz2
lua-e3cf93ddb677fe9482563a5687d3bf3e05ca0407.zip
first implementation of "threaded code" for boolean operations
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/lparser.c b/lparser.c
index 7fb5a0d7..a8198190 100644
--- a/lparser.c
+++ b/lparser.c
@@ -218,7 +218,7 @@ static void singlevar (LexState *ls, TaggedString *n, expdesc *var, int prev) {
218 int i = aux_localname(fs, n); 218 int i = aux_localname(fs, n);
219 if (i >= 0) { /* local value? */ 219 if (i >= 0) { /* local value? */
220 var->k = VLOCAL; 220 var->k = VLOCAL;
221 var->info = i; 221 var->u.index = i;
222 } 222 }
223 else { 223 else {
224 FuncState *level = fs; 224 FuncState *level = fs;
@@ -226,7 +226,7 @@ static void singlevar (LexState *ls, TaggedString *n, expdesc *var, int prev) {
226 if (aux_localname(level, n) >= 0) 226 if (aux_localname(level, n) >= 0)
227 luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); 227 luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str);
228 var->k = VGLOBAL; 228 var->k = VGLOBAL;
229 var->info = string_constant(ls, fs, n); 229 var->u.index = string_constant(ls, fs, n);
230 } 230 }
231} 231}
232 232
@@ -237,7 +237,7 @@ static int indexupvalue (LexState *ls, TaggedString *n) {
237 int i; 237 int i;
238 singlevar(ls, n, &v, 1); 238 singlevar(ls, n, &v, 1);
239 for (i=0; i<fs->nupvalues; i++) { 239 for (i=0; i<fs->nupvalues; i++) {
240 if (fs->upvalues[i].k == v.k && fs->upvalues[i].info == v.info) 240 if (fs->upvalues[i].k == v.k && fs->upvalues[i].u.index == v.u.index)
241 return i; 241 return i;
242 } 242 }
243 /* new one */ 243 /* new one */
@@ -296,9 +296,9 @@ static void code_args (LexState *ls, int nparams, int dots) {
296static int getvarname (LexState *ls, expdesc *var) { 296static int getvarname (LexState *ls, expdesc *var) {
297 switch (var->k) { 297 switch (var->k) {
298 case VGLOBAL: 298 case VGLOBAL:
299 return var->info; 299 return var->u.index;
300 case VLOCAL: 300 case VLOCAL:
301 return string_constant(ls, ls->fs, ls->fs->localvar[var->info]); 301 return string_constant(ls, ls->fs, ls->fs->localvar[var->u.index]);
302 break; 302 break;
303 default: 303 default:
304 error_unexpected(ls); /* there is no `var name' */ 304 error_unexpected(ls); /* there is no `var name' */
@@ -311,7 +311,7 @@ static void func_onstack (LexState *ls, FuncState *func) {
311 TProtoFunc *f = ls->fs->f; 311 TProtoFunc *f = ls->fs->f;
312 int i; 312 int i;
313 for (i=0; i<func->nupvalues; i++) 313 for (i=0; i<func->nupvalues; i++)
314 luaK_1tostack(ls, &func->upvalues[i]); 314 luaK_tostack(ls, &func->upvalues[i], 1);
315 luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *, 315 luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *,
316 constantEM, MAXARG_A); 316 constantEM, MAXARG_A);
317 f->kproto[f->nkproto++] = func->f; 317 f->kproto[f->nkproto++] = func->f;
@@ -388,12 +388,12 @@ static int explist1 (LexState *ls) {
388 expdesc v; 388 expdesc v;
389 expr(ls, &v); 389 expr(ls, &v);
390 while (ls->token == ',') { 390 while (ls->token == ',') {
391 luaK_1tostack(ls, &v); /* gets only 1 value from previous expression */ 391 luaK_tostack(ls, &v, 1); /* gets only 1 value from previous expression */
392 next(ls); /* skip comma */ 392 next(ls); /* skip comma */
393 expr(ls, &v); 393 expr(ls, &v);
394 n++; 394 n++;
395 } 395 }
396 luaK_tostack(ls, &v); 396 luaK_tostack(ls, &v, 0);
397 return n; 397 return n;
398} 398}
399 399
@@ -451,14 +451,14 @@ static void var_or_func_tail (LexState *ls, expdesc *v) {
451 switch (ls->token) { 451 switch (ls->token) {
452 case '.': /* var_or_func_tail -> '.' NAME */ 452 case '.': /* var_or_func_tail -> '.' NAME */
453 next(ls); 453 next(ls);
454 luaK_1tostack(ls, v); /* `v' must be on stack */ 454 luaK_tostack(ls, v, 1); /* `v' must be on stack */
455 luaK_kstr(ls, checkname(ls)); 455 luaK_kstr(ls, checkname(ls));
456 v->k = VINDEXED; 456 v->k = VINDEXED;
457 break; 457 break;
458 458
459 case '[': /* var_or_func_tail -> '[' exp1 ']' */ 459 case '[': /* var_or_func_tail -> '[' exp1 ']' */
460 next(ls); 460 next(ls);
461 luaK_1tostack(ls, v); /* `v' must be on stack */ 461 luaK_tostack(ls, v, 1); /* `v' must be on stack */
462 v->k = VINDEXED; 462 v->k = VINDEXED;
463 exp1(ls); 463 exp1(ls);
464 check(ls, ']'); 464 check(ls, ']');
@@ -468,17 +468,19 @@ static void var_or_func_tail (LexState *ls, expdesc *v) {
468 int name; 468 int name;
469 next(ls); 469 next(ls);
470 name = checkname(ls); 470 name = checkname(ls);
471 luaK_1tostack(ls, v); /* `v' must be on stack */ 471 luaK_tostack(ls, v, 1); /* `v' must be on stack */
472 luaK_U(ls, PUSHSELF, name, 1); 472 luaK_U(ls, PUSHSELF, name, 1);
473 funcargs(ls, 1); 473 funcargs(ls, 1);
474 v->k = VEXP; 474 v->k = VEXP;
475 v->u.l.t = v->u.l.f = 0;
475 break; 476 break;
476 } 477 }
477 478
478 case '(': case STRING: case '{': /* var_or_func_tail -> funcargs */ 479 case '(': case STRING: case '{': /* var_or_func_tail -> funcargs */
479 luaK_1tostack(ls, v); /* `v' must be on stack */ 480 luaK_tostack(ls, v, 1); /* `v' must be on stack */
480 funcargs(ls, 0); 481 funcargs(ls, 0);
481 v->k = VEXP; 482 v->k = VEXP;
483 v->u.l.t = v->u.l.f = 0;
482 break; 484 break;
483 485
484 default: return; /* should be follow... */ 486 default: return; /* should be follow... */
@@ -492,6 +494,7 @@ static void var_or_func (LexState *ls, expdesc *v) {
492 if (optional(ls, '%')) { /* upvalue? */ 494 if (optional(ls, '%')) { /* upvalue? */
493 pushupvalue(ls, str_checkname(ls)); 495 pushupvalue(ls, str_checkname(ls));
494 v->k = VEXP; 496 v->k = VEXP;
497 v->u.l.t = v->u.l.f = 0;
495 } 498 }
496 else /* variable name */ 499 else /* variable name */
497 singlevar(ls, str_checkname(ls), v, 0); 500 singlevar(ls, str_checkname(ls), v, 0);
@@ -591,7 +594,7 @@ static void constructor_part (LexState *ls, constdesc *cd) {
591 cd->k = 1; /* record */ 594 cd->k = 1; /* record */
592 } 595 }
593 else { 596 else {
594 luaK_tostack(ls, &v); 597 luaK_tostack(ls, &v, 0);
595 cd->n = listfields(ls); 598 cd->n = listfields(ls);
596 cd->k = 0; /* list */ 599 cd->k = 0; /* list */
597 } 600 }
@@ -632,7 +635,7 @@ static void constructor (LexState *ls) {
632 } 635 }
633 check_match(ls, '}', '{', line); 636 check_match(ls, '}', '{', line);
634 /* set initial table size */ 637 /* set initial table size */
635 ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); 638 SETARG_U(ls->fs->f->code[pc], nelems);
636} 639}
637 640
638/* }====================================================================== */ 641/* }====================================================================== */
@@ -691,13 +694,14 @@ static void simpleexp (LexState *ls, expdesc *v) {
691 return; 694 return;
692 } 695 }
693 v->k = VEXP; 696 v->k = VEXP;
697 v->u.l.t = v->u.l.f = 0;
694} 698}
695 699
696 700
697static void exp1 (LexState *ls) { 701static void exp1 (LexState *ls) {
698 expdesc v; 702 expdesc v;
699 expr(ls, &v); 703 expr(ls, &v);
700 luaK_1tostack(ls, &v); 704 luaK_tostack(ls, &v, 1);
701} 705}
702 706
703 707
@@ -820,10 +824,13 @@ static void whilestat (LexState *ls, int line) {
820 FuncState *fs = ls->fs; 824 FuncState *fs = ls->fs;
821 int while_init = luaK_getlabel(ls); 825 int while_init = luaK_getlabel(ls);
822 int loopentry; /* point to jump to repeat the loop */ 826 int loopentry; /* point to jump to repeat the loop */
827 int cond_init; /* init of condition, after the move */
823 int cond_size; 828 int cond_size;
829 expdesc v;
824 int i; 830 int i;
825 next(ls); /* skip WHILE */ 831 next(ls); /* skip WHILE */
826 exp1(ls); /* read condition */ 832 expr(ls, &v); /* read condition */
833 luaK_goiffalse(ls, &v, 0);
827 cond_size = fs->pc - while_init; 834 cond_size = fs->pc - while_init;
828 /* save condition (to move it to after body) */ 835 /* save condition (to move it to after body) */
829 if (cond_size > MAX_WHILE_EXP) 836 if (cond_size > MAX_WHILE_EXP)
@@ -831,28 +838,31 @@ static void whilestat (LexState *ls, int line) {
831 for (i=0; i<cond_size; i++) buffer[i] = fs->f->code[while_init+i]; 838 for (i=0; i<cond_size; i++) buffer[i] = fs->f->code[while_init+i];
832 /* go back to state prior condition */ 839 /* go back to state prior condition */
833 fs->pc = while_init; 840 fs->pc = while_init;
834 luaK_deltastack(ls, -1);
835 luaK_S(ls, JMP, 0, 0); /* initial jump to condition */ 841 luaK_S(ls, JMP, 0, 0); /* initial jump to condition */
836 check(ls, DO); 842 check(ls, DO);
837 loopentry = luaK_getlabel(ls); 843 loopentry = luaK_getlabel(ls);
838 block(ls); 844 block(ls);
839 check_match(ls, END, WHILE, line); 845 check_match(ls, END, WHILE, line);
840 luaK_fixjump(ls, while_init, luaK_getlabel(ls)); 846 cond_init = luaK_getlabel(ls);
841 /* copy condition to new position, and correct stack */ 847 luaK_fixjump(ls, while_init, cond_init);
848 /* correct `v' and copy condition to new position */
849 if (v.u.l.t != 0) v.u.l.t += cond_init-while_init;
842 for (i=0; i<cond_size; i++) luaK_primitivecode(ls, buffer[i]); 850 for (i=0; i<cond_size; i++) luaK_primitivecode(ls, buffer[i]);
843 luaK_deltastack(ls, 1); 851 luaK_patchlist(ls, v.u.l.t, loopentry);
844 luaK_fixjump(ls, luaK_S(ls, IFTJMP, 0, -1), loopentry); 852 luaK_getlabel(ls); /* mark possible jump to this point */
845} 853}
846 854
847 855
848static void repeatstat (LexState *ls, int line) { 856static void repeatstat (LexState *ls, int line) {
849 /* repeatstat -> REPEAT block UNTIL exp1 */ 857 /* repeatstat -> REPEAT block UNTIL exp1 */
850 int repeat_init = luaK_getlabel(ls); 858 int repeat_init = luaK_getlabel(ls);
859 expdesc v;
851 next(ls); 860 next(ls);
852 block(ls); 861 block(ls);
853 check_match(ls, UNTIL, REPEAT, line); 862 check_match(ls, UNTIL, REPEAT, line);
854 exp1(ls); 863 expr(ls, &v);
855 luaK_fixjump(ls, luaK_S(ls, IFFJMP, 0, -1), repeat_init); 864 luaK_goiftrue(ls, &v, 0);
865 luaK_patchlist(ls, v.u.l.f, repeat_init);
856} 866}
857 867
858 868
@@ -900,7 +910,7 @@ static int funcname (LexState *ls, expdesc *v) {
900 if (ls->token == ':' || ls->token == '.') { 910 if (ls->token == ':' || ls->token == '.') {
901 needself = (ls->token == ':'); 911 needself = (ls->token == ':');
902 next(ls); 912 next(ls);
903 luaK_1tostack(ls, v); 913 luaK_tostack(ls, v, 1);
904 luaK_kstr(ls, checkname(ls)); 914 luaK_kstr(ls, checkname(ls));
905 v->k = VINDEXED; 915 v->k = VINDEXED;
906 } 916 }
@@ -943,11 +953,11 @@ static void namestat (LexState *ls) {
943static void ifpart (LexState *ls, int line) { 953static void ifpart (LexState *ls, int line) {
944 /* ifpart -> cond THEN block (ELSEIF ifpart | [ELSE block] END) */ 954 /* ifpart -> cond THEN block (ELSEIF ifpart | [ELSE block] END) */
945 FuncState *fs = ls->fs; 955 FuncState *fs = ls->fs;
946 int c; /* address of the conditional jump */ 956 expdesc v;
947 int elseinit; 957 int elseinit;
948 next(ls); /* skip IF or ELSEIF */ 958 next(ls); /* skip IF or ELSEIF */
949 exp1(ls); /* cond */ 959 expr(ls, &v); /* cond */
950 c = luaK_S(ls, IFFJMP, 0, -1); /* 1st jump: over `then' part */ 960 luaK_goiftrue(ls, &v, 0);
951 check(ls, THEN); 961 check(ls, THEN);
952 block(ls); /* `then' part */ 962 block(ls); /* `then' part */
953 luaK_S(ls, JMP, 0, 0); /* 2nd jump: over `else' part */ 963 luaK_S(ls, JMP, 0, 0); /* 2nd jump: over `else' part */
@@ -960,13 +970,13 @@ static void ifpart (LexState *ls, int line) {
960 check_match(ls, END, IF, line); 970 check_match(ls, END, IF, line);
961 } 971 }
962 if (fs->pc > elseinit) { /* is there an `else' part? */ 972 if (fs->pc > elseinit) { /* is there an `else' part? */
963 luaK_fixjump(ls, c, elseinit); /* fix 1st jump to `else' part */
964 luaK_fixjump(ls, elseinit-1, luaK_getlabel(ls)); /* fix 2nd jump */ 973 luaK_fixjump(ls, elseinit-1, luaK_getlabel(ls)); /* fix 2nd jump */
965 } 974 }
966 else { /* no else part */ 975 else { /* no else part */
967 fs->pc--; /* remove 2nd jump */ 976 fs->pc--; /* remove 2nd jump */
968 luaK_fixjump(ls, c, luaK_getlabel(ls)); /* fix 1st jump to `if' end */ 977 elseinit = luaK_getlabel(ls); /* `elseinit' points to end */
969 } 978 }
979 luaK_patchlist(ls, v.u.l.f, elseinit); /* fix 1st jump to `else' part */
970} 980}
971 981
972 982