diff options
| -rw-r--r-- | lcode.c | 27 | ||||
| -rw-r--r-- | lcode.h | 5 | ||||
| -rw-r--r-- | lparser.c | 47 |
3 files changed, 64 insertions, 15 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.99 2002/05/07 17:36:56 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.100 2002/05/09 14:14:34 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -39,6 +39,13 @@ void luaK_nil (FuncState *fs, int from, int n) { | |||
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | void luaK_moveexp (expdesc *e, int offset) { | ||
| 43 | if (e->t != NO_JUMP) e->t += offset; | ||
| 44 | if (e->f != NO_JUMP) e->f += offset; | ||
| 45 | if (e->k == VRELOCABLE || e->k == VJMP) e->info += offset; | ||
| 46 | } | ||
| 47 | |||
| 48 | |||
| 42 | int luaK_jump (FuncState *fs) { | 49 | int luaK_jump (FuncState *fs) { |
| 43 | int j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); | 50 | int j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); |
| 44 | if (j == fs->lasttarget) { /* possible jumps to this jump? */ | 51 | if (j == fs->lasttarget) { /* possible jumps to this jump? */ |
| @@ -515,12 +522,10 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { | |||
| 515 | } | 522 | } |
| 516 | } | 523 | } |
| 517 | luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ | 524 | luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ |
| 518 | luaK_patchtohere(fs, e->t); | ||
| 519 | e->t = NO_JUMP; | ||
| 520 | } | 525 | } |
| 521 | 526 | ||
| 522 | 527 | ||
| 523 | static void luaK_goiffalse (FuncState *fs, expdesc *e) { | 528 | void luaK_goiffalse (FuncState *fs, expdesc *e) { |
| 524 | int pc; /* pc of last jump */ | 529 | int pc; /* pc of last jump */ |
| 525 | luaK_dischargevars(fs, e); | 530 | luaK_dischargevars(fs, e); |
| 526 | switch (e->k) { | 531 | switch (e->k) { |
| @@ -542,8 +547,6 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) { | |||
| 542 | } | 547 | } |
| 543 | } | 548 | } |
| 544 | luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ | 549 | luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ |
| 545 | luaK_patchtohere(fs, e->f); | ||
| 546 | e->f = NO_JUMP; | ||
| 547 | } | 550 | } |
| 548 | 551 | ||
| 549 | 552 | ||
| @@ -607,10 +610,14 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
| 607 | switch (op) { | 610 | switch (op) { |
| 608 | case OPR_AND: { | 611 | case OPR_AND: { |
| 609 | luaK_goiftrue(fs, v); | 612 | luaK_goiftrue(fs, v); |
| 613 | luaK_patchtohere(fs, v->t); | ||
| 614 | v->t = NO_JUMP; | ||
| 610 | break; | 615 | break; |
| 611 | } | 616 | } |
| 612 | case OPR_OR: { | 617 | case OPR_OR: { |
| 613 | luaK_goiffalse(fs, v); | 618 | luaK_goiffalse(fs, v); |
| 619 | luaK_patchtohere(fs, v->f); | ||
| 620 | v->f = NO_JUMP; | ||
| 614 | break; | 621 | break; |
| 615 | } | 622 | } |
| 616 | case OPR_CONCAT: { | 623 | case OPR_CONCAT: { |
| @@ -727,7 +734,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { | |||
| 727 | } | 734 | } |
| 728 | 735 | ||
| 729 | 736 | ||
| 730 | static int luaK_code (FuncState *fs, Instruction i) { | 737 | int luaK_code (FuncState *fs, Instruction i, int line) { |
| 731 | Proto *f = fs->f; | 738 | Proto *f = fs->f; |
| 732 | int oldsize = f->sizecode; | 739 | int oldsize = f->sizecode; |
| 733 | /* put new instruction in code array */ | 740 | /* put new instruction in code array */ |
| @@ -736,19 +743,19 @@ static int luaK_code (FuncState *fs, Instruction i) { | |||
| 736 | f->code[fs->pc] = i; | 743 | f->code[fs->pc] = i; |
| 737 | if (f->sizecode != oldsize) | 744 | if (f->sizecode != oldsize) |
| 738 | luaM_reallocvector(fs->L, f->lineinfo, oldsize, f->sizecode, int); | 745 | luaM_reallocvector(fs->L, f->lineinfo, oldsize, f->sizecode, int); |
| 739 | f->lineinfo[fs->pc] = fs->ls->lastline; | 746 | f->lineinfo[fs->pc] = line; |
| 740 | return fs->pc++; | 747 | return fs->pc++; |
| 741 | } | 748 | } |
| 742 | 749 | ||
| 743 | 750 | ||
| 744 | int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { | 751 | int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { |
| 745 | lua_assert(getOpMode(o) == iABC); | 752 | lua_assert(getOpMode(o) == iABC); |
| 746 | return luaK_code(fs, CREATE_ABC(o, a, b, c)); | 753 | return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); |
| 747 | } | 754 | } |
| 748 | 755 | ||
| 749 | 756 | ||
| 750 | int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { | 757 | int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { |
| 751 | lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); | 758 | lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); |
| 752 | return luaK_code(fs, CREATE_ABx(o, a, bc)); | 759 | return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); |
| 753 | } | 760 | } |
| 754 | 761 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.h,v 1.32 2002/04/24 20:07:46 roberto Exp roberto $ | 2 | ** $Id: lcode.h,v 1.33 2002/05/07 17:36:56 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -41,6 +41,7 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr; | |||
| 41 | 41 | ||
| 42 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) | 42 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) |
| 43 | 43 | ||
| 44 | int luaK_code (FuncState *fs, Instruction i, int line); | ||
| 44 | int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); | 45 | int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); |
| 45 | int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); | 46 | int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); |
| 46 | void luaK_nil (FuncState *fs, int from, int n); | 47 | void luaK_nil (FuncState *fs, int from, int n); |
| @@ -54,7 +55,9 @@ void luaK_exp2val (FuncState *fs, expdesc *e); | |||
| 54 | int luaK_exp2RK (FuncState *fs, expdesc *e); | 55 | int luaK_exp2RK (FuncState *fs, expdesc *e); |
| 55 | void luaK_self (FuncState *fs, expdesc *e, expdesc *key); | 56 | void luaK_self (FuncState *fs, expdesc *e, expdesc *key); |
| 56 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); | 57 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); |
| 58 | void luaK_moveexp (expdesc *e, int offset); | ||
| 57 | void luaK_goiftrue (FuncState *fs, expdesc *e); | 59 | void luaK_goiftrue (FuncState *fs, expdesc *e); |
| 60 | void luaK_goiffalse (FuncState *fs, expdesc *e); | ||
| 58 | void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); | 61 | void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); |
| 59 | void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults); | 62 | void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults); |
| 60 | int luaK_jump (FuncState *fs); | 63 | int luaK_jump (FuncState *fs); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.178 2002/04/24 20:07:46 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.179 2002/05/07 17:36:56 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 | */ |
| @@ -946,22 +946,61 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | |||
| 946 | static void cond (LexState *ls, expdesc *v) { | 946 | static void cond (LexState *ls, expdesc *v) { |
| 947 | /* cond -> exp */ | 947 | /* cond -> exp */ |
| 948 | expr(ls, v); /* read condition */ | 948 | expr(ls, v); /* read condition */ |
| 949 | if (v->k == VNIL) v->k = VFALSE; /* `falses' are all equal here */ | ||
| 949 | luaK_goiftrue(ls->fs, v); | 950 | luaK_goiftrue(ls->fs, v); |
| 951 | luaK_patchtohere(ls->fs, v->t); | ||
| 950 | } | 952 | } |
| 951 | 953 | ||
| 952 | 954 | ||
| 955 | /* | ||
| 956 | ** The while statement optimizes its code by coding the condition | ||
| 957 | ** after its body (and thus avoiding one jump in the loop). | ||
| 958 | */ | ||
| 959 | |||
| 960 | /* | ||
| 961 | ** maximum size of expressions for optimizing `while' code | ||
| 962 | */ | ||
| 963 | #ifndef MAXEXPWHILE | ||
| 964 | #define MAXEXPWHILE 100 | ||
| 965 | #endif | ||
| 966 | |||
| 967 | /* | ||
| 968 | ** the call `luaK_goiffalse' may grow the size of an expression by | ||
| 969 | ** at most this: | ||
| 970 | */ | ||
| 971 | #define EXTRAEXP 5 | ||
| 972 | |||
| 953 | static void whilestat (LexState *ls, int line) { | 973 | static void whilestat (LexState *ls, int line) { |
| 954 | /* whilestat -> WHILE cond DO block END */ | 974 | /* whilestat -> WHILE cond DO block END */ |
| 975 | Instruction codeexp[MAXEXPWHILE + EXTRAEXP]; | ||
| 976 | int lineexp = 0; | ||
| 977 | int i; | ||
| 978 | int sizeexp; | ||
| 955 | FuncState *fs = ls->fs; | 979 | FuncState *fs = ls->fs; |
| 956 | int while_init = luaK_getlabel(fs); | 980 | int while_init = luaK_getlabel(fs); |
| 957 | expdesc v; | 981 | expdesc v; |
| 958 | BlockCnt bl; | 982 | BlockCnt bl; |
| 959 | enterblock(fs, &bl, 1); | ||
| 960 | next(ls); | 983 | next(ls); |
| 961 | cond(ls, &v); | 984 | expr(ls, &v); |
| 985 | if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ | ||
| 986 | lineexp = ls->linenumber; | ||
| 987 | luaK_goiffalse(fs, &v); | ||
| 988 | sizeexp = fs->pc - while_init; | ||
| 989 | if (sizeexp > MAXEXPWHILE) | ||
| 990 | luaX_syntaxerror(ls, "while condition too complex"); | ||
| 991 | fs->pc = while_init; /* remove `exp' code */ | ||
| 992 | luaK_getlabel(fs); | ||
| 993 | for (i = 0; i < sizeexp; i++) /* save `exp' code */ | ||
| 994 | codeexp[i] = fs->f->code[while_init + i]; | ||
| 995 | luaK_jump(fs); | ||
| 996 | enterblock(fs, &bl, 1); | ||
| 962 | check(ls, TK_DO); | 997 | check(ls, TK_DO); |
| 963 | block(ls); | 998 | block(ls); |
| 964 | luaK_patchlist(fs, luaK_jump(fs), while_init); | 999 | luaK_patchtohere(fs, while_init); /* initial jump jumps to here */ |
| 1000 | luaK_moveexp(&v, fs->pc - while_init); /* correct pointers */ | ||
| 1001 | for (i=0; i<sizeexp; i++) | ||
| 1002 | luaK_code(fs, codeexp[i], lineexp); | ||
| 1003 | luaK_patchlist(fs, v.t, while_init+1); | ||
| 965 | luaK_patchtohere(fs, v.f); | 1004 | luaK_patchtohere(fs, v.f); |
| 966 | check_match(ls, TK_END, TK_WHILE, line); | 1005 | check_match(ls, TK_END, TK_WHILE, line); |
| 967 | leaveblock(fs); | 1006 | leaveblock(fs); |
