diff options
Diffstat (limited to 'lcode.c')
| -rw-r--r-- | lcode.c | 48 |
1 files changed, 23 insertions, 25 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.15 2000/03/17 14:46:04 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.16 2000/03/20 19:15:37 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 | */ |
| @@ -408,49 +408,47 @@ static void concatlists (FuncState *fs, int *l1, int l2) { | |||
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | 410 | ||
| 411 | void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) { | 411 | static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) { |
| 412 | Instruction *previous; | 412 | Instruction *previous; |
| 413 | int *golist = &v->u.l.f; | ||
| 414 | int *exitlist = &v->u.l.t; | ||
| 415 | if (invert) { /* interchange `golist' and `exitlist' */ | ||
| 416 | int *temp = golist; golist = exitlist; exitlist = temp; | ||
| 417 | } | ||
| 413 | discharge1(fs, v); | 418 | discharge1(fs, v); |
| 414 | previous = &fs->f->code[fs->pc-1]; | 419 | previous = &fs->f->code[fs->pc-1]; |
| 415 | LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "bad place to set line"); | 420 | LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "bad place to set line"); |
| 416 | if (ISJUMP(GET_OPCODE(*previous))) | 421 | if (ISJUMP(GET_OPCODE(*previous))) { |
| 417 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); | 422 | if (invert) |
| 418 | else { | 423 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); |
| 419 | OpCode jump = keepvalue ? OP_ONFJMP : OP_IFFJMP; | ||
| 420 | luaK_jump(fs, jump); | ||
| 421 | } | 424 | } |
| 422 | insert_last(fs, &v->u.l.f); | 425 | else |
| 423 | luaK_patchlist(fs, v->u.l.t, luaK_getlabel(fs)); | 426 | luaK_jump(fs, jump); |
| 424 | v->u.l.t = NO_JUMP; | 427 | insert_last(fs, exitlist); |
| 428 | luaK_patchlist(fs, *golist, luaK_getlabel(fs)); | ||
| 429 | *golist = NO_JUMP; | ||
| 430 | } | ||
| 431 | |||
| 432 | |||
| 433 | void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) { | ||
| 434 | luaK_testgo(fs, v, 1, keepvalue ? OP_ONFJMP : OP_IFFJMP); | ||
| 425 | } | 435 | } |
| 426 | 436 | ||
| 427 | 437 | ||
| 428 | void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) { | 438 | void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) { |
| 429 | Instruction previous; | 439 | luaK_testgo(fs, v, 0, keepvalue ? OP_ONTJMP : OP_IFTJMP); |
| 430 | discharge1(fs, v); | ||
| 431 | previous = fs->f->code[fs->pc-1]; | ||
| 432 | LUA_ASSERT(L, GET_OPCODE(previous) != OP_SETLINE, "bad place to set line"); | ||
| 433 | if (!ISJUMP(GET_OPCODE(previous))) { | ||
| 434 | OpCode jump = keepvalue ? OP_ONTJMP : OP_IFTJMP; | ||
| 435 | luaK_jump(fs, jump); | ||
| 436 | } | ||
| 437 | insert_last(fs, &v->u.l.t); | ||
| 438 | luaK_patchlist(fs, v->u.l.f, luaK_getlabel(fs)); | ||
| 439 | v->u.l.f = NO_JUMP; | ||
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | 442 | ||
| 443 | void luaK_tostack (LexState *ls, expdesc *v, int onlyone) { | 443 | void luaK_tostack (LexState *ls, expdesc *v, int onlyone) { |
| 444 | FuncState *fs = ls->fs; | 444 | FuncState *fs = ls->fs; |
| 445 | if (discharge(fs, v)) return; | 445 | if (!discharge(fs, v)) { /* `v' is an expression? */ |
| 446 | else { /* is an expression */ | ||
| 447 | OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]); | 446 | OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]); |
| 448 | LUA_ASSERT(L, previous != OP_SETLINE, "bad place to set line"); | 447 | LUA_ASSERT(L, previous != OP_SETLINE, "bad place to set line"); |
| 449 | if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) { | 448 | if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) { |
| 450 | /* it is an expression without jumps */ | 449 | /* it is an expression without jumps */ |
| 451 | if (onlyone && v->k == VEXP) | 450 | if (onlyone) |
| 452 | luaK_setcallreturns(fs, 1); /* call must return 1 value */ | 451 | luaK_setcallreturns(fs, 1); /* call must return 1 value */ |
| 453 | return; | ||
| 454 | } | 452 | } |
| 455 | else { /* expression has jumps... */ | 453 | else { /* expression has jumps... */ |
| 456 | int p_nil = 0; /* position of an eventual PUSHNIL */ | 454 | int p_nil = 0; /* position of an eventual PUSHNIL */ |
