diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-09 10:57:37 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-09 10:57:37 -0300 |
| commit | e3cf93ddb677fe9482563a5687d3bf3e05ca0407 (patch) | |
| tree | c692a19e5597c785c198d558a07dd0571f3fa98c /lparser.c | |
| parent | 88b306f495fa7034c708c6b75a355a6deee51c58 (diff) | |
| download | lua-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.c | 68 |
1 files changed, 39 insertions, 29 deletions
| @@ -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) { | |||
| 296 | static int getvarname (LexState *ls, expdesc *var) { | 296 | static 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 | ||
| 697 | static void exp1 (LexState *ls) { | 701 | static 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 | ||
| 848 | static void repeatstat (LexState *ls, int line) { | 856 | static 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) { | |||
| 943 | static void ifpart (LexState *ls, int line) { | 953 | static 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 | ||
