diff options
| -rw-r--r-- | lopcodes.h | 4 | ||||
| -rw-r--r-- | lparser.c | 45 | ||||
| -rw-r--r-- | lvm.c | 33 |
3 files changed, 47 insertions, 35 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.21 1999/02/04 16:36:16 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.22 1999/02/08 17:07:59 roberto Exp roberto $ |
| 3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -22,6 +22,7 @@ RETCODE,/* b - - */ | |||
| 22 | 22 | ||
| 23 | PUSHNIL,/* b - nil_0...nil_b */ | 23 | PUSHNIL,/* b - nil_0...nil_b */ |
| 24 | POP,/* b - - TOP-=(b+1) */ | 24 | POP,/* b - - TOP-=(b+1) */ |
| 25 | POPDUP,/* b v v TOP-=(b+1) */ | ||
| 25 | 26 | ||
| 26 | PUSHNUMBERW,/* w - (float)(w-NUMOFFSET) */ | 27 | PUSHNUMBERW,/* w - (float)(w-NUMOFFSET) */ |
| 27 | PUSHNUMBER,/* b - (float)(b-NUMOFFSET) */ | 28 | PUSHNUMBER,/* b - (float)(b-NUMOFFSET) */ |
| @@ -59,6 +60,7 @@ SETTABLEPOP,/* - v i t - t[i]=v */ | |||
| 59 | SETTABPPDUP,/* - v i t v t[i]=v */ | 60 | SETTABPPDUP,/* - v i t v t[i]=v */ |
| 60 | 61 | ||
| 61 | SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ | 62 | SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ |
| 63 | SETTABLEDUP,/* b v a_b...a_1 i t v a_b...a_1 i t t[i]=v */ | ||
| 62 | 64 | ||
| 63 | SETLISTW,/* w c v_c...v_1 t - t[i+w*FPF]=v_i */ | 65 | SETLISTW,/* w c v_c...v_1 t - t[i+w*FPF]=v_i */ |
| 64 | SETLIST,/* b c v_c...v_1 t - t[i+b*FPF]=v_i */ | 66 | SETLIST,/* b c v_c...v_1 t - t[i+b*FPF]=v_i */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.16 1999/02/04 17:47:59 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.17 1999/02/08 17:07:59 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -102,7 +102,7 @@ typedef struct FuncState { | |||
| 102 | /* | 102 | /* |
| 103 | ** prototypes for non-terminal functions | 103 | ** prototypes for non-terminal functions |
| 104 | */ | 104 | */ |
| 105 | static int assignment (LexState *ls, vardesc *v, int nvars); | 105 | static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes); |
| 106 | static int cond (LexState *ls); | 106 | static int cond (LexState *ls); |
| 107 | static int funcname (LexState *ls, vardesc *v); | 107 | static int funcname (LexState *ls, vardesc *v); |
| 108 | static int funcparams (LexState *ls, int slf); | 108 | static int funcparams (LexState *ls, int slf); |
| @@ -387,7 +387,7 @@ static void check_debugline (LexState *ls) { | |||
| 387 | 387 | ||
| 388 | static void adjuststack (LexState *ls, int n) { | 388 | static void adjuststack (LexState *ls, int n) { |
| 389 | if (n > 0) | 389 | if (n > 0) |
| 390 | code_oparg(ls, POP, n-1, -n); | 390 | code_oparg(ls, POP, n, -n); |
| 391 | else if (n < 0) | 391 | else if (n < 0) |
| 392 | code_oparg(ls, PUSHNIL, (-n)-1, -n); | 392 | code_oparg(ls, PUSHNIL, (-n)-1, -n); |
| 393 | } | 393 | } |
| @@ -472,7 +472,13 @@ static void lua_pushvar (LexState *ls, vardesc *var) { | |||
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | 474 | ||
| 475 | static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) { | 475 | /* to be used by "storevar" and assignment */ |
| 476 | static OpCode set_pop[] = {SETLOCAL, SETGLOBAL, SETTABLEPOP, SETTABLE}; | ||
| 477 | static OpCode set_dup[] = {SETLOCALDUP, SETGLOBALDUP, SETTABPPDUP, | ||
| 478 | SETTABLEDUP}; | ||
| 479 | |||
| 480 | |||
| 481 | static void storevar (LexState *ls, vardesc *var, OpCode *codes) { | ||
| 476 | switch (var->k) { | 482 | switch (var->k) { |
| 477 | case VLOCAL: | 483 | case VLOCAL: |
| 478 | code_oparg(ls, codes[0], var->info, -1); | 484 | code_oparg(ls, codes[0], var->info, -1); |
| @@ -489,12 +495,6 @@ static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) { | |||
| 489 | } | 495 | } |
| 490 | 496 | ||
| 491 | 497 | ||
| 492 | static void storevar (LexState *ls, vardesc *var) { | ||
| 493 | static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLEPOP}; | ||
| 494 | genstorevar(ls, var, codes); | ||
| 495 | } | ||
| 496 | |||
| 497 | |||
| 498 | static int fix_jump (LexState *ls, int pc, OpCode op, int n) { | 498 | static int fix_jump (LexState *ls, int pc, OpCode op, int n) { |
| 499 | /* jump is relative to position following jump instruction */ | 499 | /* jump is relative to position following jump instruction */ |
| 500 | return fix_opcode(ls, pc, op, n-(pc+JMPSIZE)); | 500 | return fix_opcode(ls, pc, op, n-(pc+JMPSIZE)); |
| @@ -748,7 +748,7 @@ static int stat (LexState *ls) { | |||
| 748 | next(ls); | 748 | next(ls); |
| 749 | needself = funcname(ls, &v); | 749 | needself = funcname(ls, &v); |
| 750 | body(ls, needself, line); | 750 | body(ls, needself, line); |
| 751 | storevar(ls, &v); | 751 | storevar(ls, &v, set_pop); |
| 752 | return 1; | 752 | return 1; |
| 753 | } | 753 | } |
| 754 | 754 | ||
| @@ -773,8 +773,8 @@ static int stat (LexState *ls) { | |||
| 773 | luaX_error(ls, "syntax error"); | 773 | luaX_error(ls, "syntax error"); |
| 774 | close_exp(ls, v.info, 0); | 774 | close_exp(ls, v.info, 0); |
| 775 | } | 775 | } |
| 776 | else { | 776 | else { /* stat -> ['%'] NAME assignment */ |
| 777 | int left = assignment(ls, &v, 1); /* stat -> ['%'] NAME assignment */ | 777 | int left = assignment(ls, &v, 1, set_pop); |
| 778 | adjuststack(ls, left); /* remove eventual 'garbage' left on stack */ | 778 | adjuststack(ls, left); /* remove eventual 'garbage' left on stack */ |
| 779 | } | 779 | } |
| 780 | return 1; | 780 | return 1; |
| @@ -953,14 +953,13 @@ static void exp0 (LexState *ls, vardesc *v) { | |||
| 953 | 953 | ||
| 954 | 954 | ||
| 955 | static void Gexp (LexState *ls, vardesc *v) { | 955 | static void Gexp (LexState *ls, vardesc *v) { |
| 956 | /* Gexp -> exp0 | var '=' exp1 */ | 956 | /* Gexp -> exp0 | assignment */ |
| 957 | static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABPPDUP}; | ||
| 958 | exp0(ls, v); | 957 | exp0(ls, v); |
| 959 | if (v->k != VEXP && optional(ls, '=')) { /* assignment expression? */ | 958 | if (v->k != VEXP && (ls->token == '=' || ls->token == ',')) { |
| 960 | unloaddot(ls, v); | 959 | int left = assignment(ls, v, 1, set_dup); |
| 961 | exp1(ls); | ||
| 962 | genstorevar(ls, v, codes); | ||
| 963 | deltastack(ls, 1); /* DUP operations push an extra value */ | 960 | deltastack(ls, 1); /* DUP operations push an extra value */ |
| 961 | if (left > 0) | ||
| 962 | code_oparg(ls, POPDUP, left, -left); | ||
| 964 | v->k = VEXP; v->info = 0; /* this expression is closed now */ | 963 | v->k = VEXP; v->info = 0; /* this expression is closed now */ |
| 965 | } | 964 | } |
| 966 | } | 965 | } |
| @@ -1244,7 +1243,7 @@ static void decinit (LexState *ls, listdesc *d) { | |||
| 1244 | } | 1243 | } |
| 1245 | 1244 | ||
| 1246 | 1245 | ||
| 1247 | static int assignment (LexState *ls, vardesc *v, int nvars) { | 1246 | static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes) { |
| 1248 | int left = 0; | 1247 | int left = 0; |
| 1249 | unloaddot(ls, v); | 1248 | unloaddot(ls, v); |
| 1250 | if (ls->token == ',') { /* assignment -> ',' NAME assignment */ | 1249 | if (ls->token == ',') { /* assignment -> ',' NAME assignment */ |
| @@ -1253,7 +1252,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) { | |||
| 1253 | var_or_func(ls, &nv); | 1252 | var_or_func(ls, &nv); |
| 1254 | if (nv.k == VEXP) | 1253 | if (nv.k == VEXP) |
| 1255 | luaX_error(ls, "syntax error"); | 1254 | luaX_error(ls, "syntax error"); |
| 1256 | left = assignment(ls, &nv, nvars+1); | 1255 | left = assignment(ls, &nv, nvars+1, set_pop); |
| 1257 | } | 1256 | } |
| 1258 | else { /* assignment -> '=' explist1 */ | 1257 | else { /* assignment -> '=' explist1 */ |
| 1259 | listdesc d; | 1258 | listdesc d; |
| @@ -1263,10 +1262,10 @@ static int assignment (LexState *ls, vardesc *v, int nvars) { | |||
| 1263 | } | 1262 | } |
| 1264 | if (v->k != VINDEXED || left+(nvars-1) == 0) { | 1263 | if (v->k != VINDEXED || left+(nvars-1) == 0) { |
| 1265 | /* global/local var or indexed var without values in between */ | 1264 | /* global/local var or indexed var without values in between */ |
| 1266 | storevar(ls, v); | 1265 | storevar(ls, v, codes); |
| 1267 | } | 1266 | } |
| 1268 | else { /* indexed var with values in between*/ | 1267 | else { /* indexed var with values in between*/ |
| 1269 | code_oparg(ls, SETTABLE, left+(nvars-1), -1); | 1268 | code_oparg(ls, codes[3], left+(nvars-1), -1); |
| 1270 | left += 2; /* table/index are not popped, because they aren't on top */ | 1269 | left += 2; /* table/index are not popped, because they aren't on top */ |
| 1271 | } | 1270 | } |
| 1272 | return left; | 1271 | return left; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.45 1999/02/04 17:47:59 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.46 1999/02/08 17:07:59 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -344,7 +344,12 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) { | |||
| 344 | break; | 344 | break; |
| 345 | 345 | ||
| 346 | case POP: aux = *pc++; | 346 | case POP: aux = *pc++; |
| 347 | S->top -= (aux+1); | 347 | S->top -= aux; |
| 348 | break; | ||
| 349 | |||
| 350 | case POPDUP: aux = *pc++; | ||
| 351 | *(S->top-aux-1) = *(S->top-1); | ||
| 352 | S->top -= aux; | ||
| 348 | break; | 353 | break; |
| 349 | 354 | ||
| 350 | case PUSHNUMBERW: aux += highbyte(*pc++); | 355 | case PUSHNUMBERW: aux += highbyte(*pc++); |
| @@ -420,22 +425,28 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) { | |||
| 420 | break; | 425 | break; |
| 421 | 426 | ||
| 422 | case SETTABLEPOP: | 427 | case SETTABLEPOP: |
| 423 | luaV_settable(S->top-3); | 428 | luaV_settable(S->top-3); |
| 424 | S->top -= 2; /* pop table and index */ | 429 | S->top -= 2; /* pop table and index */ |
| 425 | break; | 430 | break; |
| 426 | 431 | ||
| 427 | case SETTABPPDUP: { | 432 | case SETTABPPDUP: { |
| 428 | TObject temp = *(S->top-1); | 433 | TObject temp = *(S->top-1); |
| 429 | luaV_settable(S->top-3); | 434 | luaV_settable(S->top-3); |
| 430 | S->top--; /* pop index (temp goes into "table" position) */ | 435 | S->top--; /* pop index (temp goes into "table" position) */ |
| 431 | *(S->top-1) = temp; | 436 | *(S->top-1) = temp; |
| 432 | break; | 437 | break; |
| 433 | } | 438 | } |
| 434 | 439 | ||
| 435 | case SETTABLE: | 440 | case SETTABLE: |
| 436 | luaV_settable(S->top-3-(*pc++)); | 441 | luaV_settable(S->top-3-(*pc++)); |
| 437 | break; | 442 | break; |
| 438 | 443 | ||
| 444 | case SETTABLEDUP: | ||
| 445 | *S->top = *(S->top-1); | ||
| 446 | S->top++; | ||
| 447 | luaV_settable(S->top-(3+1)-(*pc++)); | ||
| 448 | break; | ||
| 449 | |||
| 439 | case SETLISTW: aux += highbyte(*pc++); | 450 | case SETLISTW: aux += highbyte(*pc++); |
| 440 | case SETLIST: aux += *pc++; { | 451 | case SETLIST: aux += *pc++; { |
| 441 | int n = *(pc++); | 452 | int n = *(pc++); |
