diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-02 18:30:53 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-02 18:30:53 -0200 |
| commit | fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022 (patch) | |
| tree | 030c6dd803fff11ae0c368e90b78a9fef2b8b731 | |
| parent | ae77864844d6b933eb8be68694cbb8498af165dc (diff) | |
| download | lua-fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022.tar.gz lua-fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022.tar.bz2 lua-fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022.zip | |
new way to call functions, plus several small changes. This is
a temporary version!
| -rw-r--r-- | lua.h | 29 | ||||
| -rw-r--r-- | lua.stx | 190 | ||||
| -rw-r--r-- | opcode.c | 1298 | ||||
| -rw-r--r-- | opcode.h | 41 |
4 files changed, 777 insertions, 781 deletions
| @@ -2,13 +2,29 @@ | |||
| 2 | ** LUA - Linguagem para Usuarios de Aplicacao | 2 | ** LUA - Linguagem para Usuarios de Aplicacao |
| 3 | ** Grupo de Tecnologia em Computacao Grafica | 3 | ** Grupo de Tecnologia em Computacao Grafica |
| 4 | ** TeCGraf - PUC-Rio | 4 | ** TeCGraf - PUC-Rio |
| 5 | ** $Id: lua.h,v 1.4 1994/08/24 15:29:02 celes Exp roberto $ | 5 | ** $Id: lua.h,v 1.5 1994/11/01 17:54:31 roberto Exp $ |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | 8 | ||
| 9 | #ifndef lua_h | 9 | #ifndef lua_h |
| 10 | #define lua_h | 10 | #define lua_h |
| 11 | 11 | ||
| 12 | /* Private Part */ | ||
| 13 | |||
| 14 | typedef enum | ||
| 15 | { | ||
| 16 | LUA_T_MARK, | ||
| 17 | LUA_T_NIL, | ||
| 18 | LUA_T_NUMBER, | ||
| 19 | LUA_T_STRING, | ||
| 20 | LUA_T_ARRAY, | ||
| 21 | LUA_T_FUNCTION, | ||
| 22 | LUA_T_CFUNCTION, | ||
| 23 | LUA_T_USERDATA | ||
| 24 | } Type; | ||
| 25 | |||
| 26 | |||
| 27 | /* Public Part */ | ||
| 12 | 28 | ||
| 13 | typedef void (*lua_CFunction) (void); | 29 | typedef void (*lua_CFunction) (void); |
| 14 | typedef struct Object *lua_Object; | 30 | typedef struct Object *lua_Object; |
| @@ -19,8 +35,7 @@ void lua_errorfunction (void (*fn) (char *s)); | |||
| 19 | void lua_error (char *s); | 35 | void lua_error (char *s); |
| 20 | int lua_dofile (char *filename); | 36 | int lua_dofile (char *filename); |
| 21 | int lua_dostring (char *string); | 37 | int lua_dostring (char *string); |
| 22 | int lua_call (char *functionname, int nparam); | 38 | int lua_callfunction (lua_Object function); |
| 23 | int lua_callfunction (lua_Object function, int nparam); | ||
| 24 | 39 | ||
| 25 | lua_Object lua_getparam (int number); | 40 | lua_Object lua_getparam (int number); |
| 26 | float lua_getnumber (lua_Object object); | 41 | float lua_getnumber (lua_Object object); |
| @@ -33,8 +48,6 @@ lua_Object lua_getfield (lua_Object object, char *field); | |||
| 33 | lua_Object lua_getindexed (lua_Object object, float index); | 48 | lua_Object lua_getindexed (lua_Object object, float index); |
| 34 | lua_Object lua_getglobal (char *name); | 49 | lua_Object lua_getglobal (char *name); |
| 35 | 50 | ||
| 36 | lua_Object lua_pop (void); | ||
| 37 | |||
| 38 | int lua_pushnil (void); | 51 | int lua_pushnil (void); |
| 39 | int lua_pushnumber (float n); | 52 | int lua_pushnumber (float n); |
| 40 | int lua_pushstring (char *s); | 53 | int lua_pushstring (char *s); |
| @@ -57,4 +70,10 @@ int lua_isfunction (lua_Object object); | |||
| 57 | int lua_iscfunction (lua_Object object); | 70 | int lua_iscfunction (lua_Object object); |
| 58 | int lua_isuserdata (lua_Object object); | 71 | int lua_isuserdata (lua_Object object); |
| 59 | 72 | ||
| 73 | |||
| 74 | /* for lua 1.1 */ | ||
| 75 | |||
| 76 | #define lua_call(f) lua_callfunction(lua_getglobal(f)) | ||
| 77 | |||
| 78 | |||
| 60 | #endif | 79 | #endif |
| @@ -1,6 +1,6 @@ | |||
| 1 | %{ | 1 | %{ |
| 2 | 2 | ||
| 3 | char *rcs_luastx = "$Id: lua.stx,v 2.11 1994/10/21 19:00:12 roberto Exp roberto $"; | 3 | char *rcs_luastx = "$Id: lua.stx,v 2.12 1994/11/01 18:25:20 roberto Exp roberto $"; |
| 4 | 4 | ||
| 5 | #include <stdio.h> | 5 | #include <stdio.h> |
| 6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| @@ -37,7 +37,6 @@ static int nlocalvar=0; /* number of local variables */ | |||
| 37 | #define MAXFIELDS FIELDS_PER_FLUSH*2 | 37 | #define MAXFIELDS FIELDS_PER_FLUSH*2 |
| 38 | static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ | 38 | static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ |
| 39 | static int nfields=0; | 39 | static int nfields=0; |
| 40 | static int ntemp; /* number of temporary var into stack */ | ||
| 41 | static int err; /* flag to indicate error */ | 40 | static int err; /* flag to indicate error */ |
| 42 | 41 | ||
| 43 | /* Internal functions */ | 42 | /* Internal functions */ |
| @@ -112,7 +111,6 @@ static void flush_record (int n) | |||
| 112 | code_byte(n); | 111 | code_byte(n); |
| 113 | for (i=0; i<n; i++) | 112 | for (i=0; i<n; i++) |
| 114 | code_word(fields[--nfields]); | 113 | code_word(fields[--nfields]); |
| 115 | ntemp -= n; | ||
| 116 | } | 114 | } |
| 117 | 115 | ||
| 118 | static void flush_list (int m, int n) | 116 | static void flush_list (int m, int n) |
| @@ -132,27 +130,15 @@ static void flush_list (int m, int n) | |||
| 132 | err = 1; | 130 | err = 1; |
| 133 | } | 131 | } |
| 134 | code_byte(n); | 132 | code_byte(n); |
| 135 | ntemp-=n; | ||
| 136 | } | ||
| 137 | |||
| 138 | static void incr_ntemp (void) | ||
| 139 | { | ||
| 140 | if (ntemp+nlocalvar+MAXVAR+1 < STACKGAP) | ||
| 141 | ntemp++; | ||
| 142 | else | ||
| 143 | { | ||
| 144 | lua_error ("stack overflow"); | ||
| 145 | err = 1; | ||
| 146 | } | ||
| 147 | } | 133 | } |
| 148 | 134 | ||
| 149 | static void add_nlocalvar (int n) | 135 | static void add_nlocalvar (int n) |
| 150 | { | 136 | { |
| 151 | if (ntemp+nlocalvar+MAXVAR+n < STACKGAP) | 137 | if (MAX_TEMPS+nlocalvar+MAXVAR+n < STACKGAP) |
| 152 | nlocalvar += n; | 138 | nlocalvar += n; |
| 153 | else | 139 | else |
| 154 | { | 140 | { |
| 155 | lua_error ("too many local variables or expression too complicate"); | 141 | lua_error ("too many local variables"); |
| 156 | err = 1; | 142 | err = 1; |
| 157 | } | 143 | } |
| 158 | } | 144 | } |
| @@ -190,7 +176,6 @@ static void code_number (float f) | |||
| 190 | code_byte(PUSHFLOAT); | 176 | code_byte(PUSHFLOAT); |
| 191 | code_float(f); | 177 | code_float(f); |
| 192 | } | 178 | } |
| 193 | incr_ntemp(); | ||
| 194 | } | 179 | } |
| 195 | 180 | ||
| 196 | static void init_function (void) | 181 | static void init_function (void) |
| @@ -235,8 +220,8 @@ static void init_function (void) | |||
| 235 | %token <vInt> DEBUG | 220 | %token <vInt> DEBUG |
| 236 | 221 | ||
| 237 | %type <vLong> PrepJump | 222 | %type <vLong> PrepJump |
| 238 | %type <vInt> expr, exprlist, exprlist1, varlist1, funcvalue | 223 | %type <vInt> expr, exprlist, exprlist1, varlist1, funcParams, funcvalue |
| 239 | %type <vInt> fieldlist, localdeclist | 224 | %type <vInt> fieldlist, localdeclist, decinit |
| 240 | %type <vInt> ffieldlist1 | 225 | %type <vInt> ffieldlist1 |
| 241 | %type <vInt> lfieldlist1 | 226 | %type <vInt> lfieldlist1 |
| 242 | %type <vLong> var, singlevar | 227 | %type <vLong> var, singlevar |
| @@ -290,8 +275,8 @@ function : FUNCTION NAME | |||
| 290 | END | 275 | END |
| 291 | { | 276 | { |
| 292 | if (lua_debug) code_byte(RESET); | 277 | if (lua_debug) code_byte(RESET); |
| 293 | code_byte(RETCODE); code_byte(nlocalvar); | 278 | codereturn(); |
| 294 | s_tag($<vWord>3) = T_FUNCTION; | 279 | s_tag($<vWord>3) = LUA_T_FUNCTION; |
| 295 | s_bvalue($<vWord>3) = calloc (pc, sizeof(Byte)); | 280 | s_bvalue($<vWord>3) = calloc (pc, sizeof(Byte)); |
| 296 | if (s_bvalue($<vWord>3) == NULL) | 281 | if (s_bvalue($<vWord>3) == NULL) |
| 297 | { | 282 | { |
| @@ -330,7 +315,7 @@ method : FUNCTION NAME { $<vWord>$ = lua_findsymbol($2); } ':' NAME | |||
| 330 | { | 315 | { |
| 331 | Byte *b; | 316 | Byte *b; |
| 332 | if (lua_debug) code_byte(RESET); | 317 | if (lua_debug) code_byte(RESET); |
| 333 | code_byte(RETCODE); code_byte(nlocalvar); | 318 | codereturn(); |
| 334 | b = calloc (pc, sizeof(Byte)); | 319 | b = calloc (pc, sizeof(Byte)); |
| 335 | if (b == NULL) | 320 | if (b == NULL) |
| 336 | { | 321 | { |
| @@ -362,7 +347,6 @@ statlist : /* empty */ | |||
| 362 | ; | 347 | ; |
| 363 | 348 | ||
| 364 | stat : { | 349 | stat : { |
| 365 | ntemp = 0; | ||
| 366 | if (lua_debug) | 350 | if (lua_debug) |
| 367 | { | 351 | { |
| 368 | code_byte(SETLINE); code_word(lua_linenumber); | 352 | code_byte(SETLINE); code_word(lua_linenumber); |
| @@ -414,16 +398,18 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END | |||
| 414 | { | 398 | { |
| 415 | { | 399 | { |
| 416 | int i; | 400 | int i; |
| 417 | if ($3 == 0 || nvarbuffer != ntemp - $1 * 2) | 401 | adjust_mult_assign(nvarbuffer, $3, $1 * 2 + nvarbuffer); |
| 418 | lua_codeadjust ($1 * 2 + nvarbuffer); | ||
| 419 | for (i=nvarbuffer-1; i>=0; i--) | 402 | for (i=nvarbuffer-1; i>=0; i--) |
| 420 | lua_codestore (i); | 403 | lua_codestore (i); |
| 421 | if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0)) | 404 | if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0)) |
| 422 | lua_codeadjust (0); | 405 | lua_codeadjust (0); |
| 423 | } | 406 | } |
| 424 | } | 407 | } |
| 425 | | functioncall { lua_codeadjust (0); } | 408 | | functioncall { code_byte(0); } |
| 426 | | LOCAL localdeclist decinit { add_nlocalvar($2); lua_codeadjust (0); } | 409 | | LOCAL localdeclist decinit |
| 410 | { add_nlocalvar($2); | ||
| 411 | adjust_mult_assign($2, $3, 0); | ||
| 412 | } | ||
| 427 | ; | 413 | ; |
| 428 | 414 | ||
| 429 | elsepart : /* empty */ | 415 | elsepart : /* empty */ |
| @@ -448,7 +434,7 @@ elsepart : /* empty */ | |||
| 448 | } | 434 | } |
| 449 | ; | 435 | ; |
| 450 | 436 | ||
| 451 | block : {$<vInt>$ = nlocalvar;} statlist {ntemp = 0;} ret | 437 | block : {$<vInt>$ = nlocalvar;} statlist ret |
| 452 | { | 438 | { |
| 453 | if (nlocalvar != $<vInt>1) | 439 | if (nlocalvar != $<vInt>1) |
| 454 | { | 440 | { |
| @@ -462,8 +448,9 @@ ret : /* empty */ | |||
| 462 | | { if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}} | 448 | | { if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}} |
| 463 | RETURN exprlist sc | 449 | RETURN exprlist sc |
| 464 | { | 450 | { |
| 451 | if ($3 < 0) code_byte(MULT_RET); | ||
| 465 | if (lua_debug) code_byte(RESET); | 452 | if (lua_debug) code_byte(RESET); |
| 466 | code_byte(RETCODE); code_byte(nlocalvar); | 453 | codereturn(); |
| 467 | } | 454 | } |
| 468 | ; | 455 | ; |
| 469 | 456 | ||
| @@ -474,22 +461,22 @@ PrepJump : /* empty */ | |||
| 474 | code_word (0); | 461 | code_word (0); |
| 475 | } | 462 | } |
| 476 | 463 | ||
| 477 | expr1 : expr { if ($1 == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}} | 464 | expr1 : expr { if ($1 == 0) code_byte(1); } |
| 478 | ; | 465 | ; |
| 479 | 466 | ||
| 480 | expr : '(' expr ')' { $$ = $2; } | 467 | expr : '(' expr ')' { $$ = $2; } |
| 481 | | expr1 EQ expr1 { code_byte(EQOP); $$ = 1; ntemp--;} | 468 | | expr1 EQ expr1 { code_byte(EQOP); $$ = 1; } |
| 482 | | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; ntemp--;} | 469 | | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; } |
| 483 | | expr1 '>' expr1 { code_byte(LEOP); code_byte(NOTOP); $$ = 1; ntemp--;} | 470 | | expr1 '>' expr1 { code_byte(LEOP); code_byte(NOTOP); $$ = 1; } |
| 484 | | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; ntemp--;} | 471 | | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; } |
| 485 | | expr1 LE expr1 { code_byte(LEOP); $$ = 1; ntemp--;} | 472 | | expr1 LE expr1 { code_byte(LEOP); $$ = 1; } |
| 486 | | expr1 GE expr1 { code_byte(LTOP); code_byte(NOTOP); $$ = 1; ntemp--;} | 473 | | expr1 GE expr1 { code_byte(LTOP); code_byte(NOTOP); $$ = 1; } |
| 487 | | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; ntemp--;} | 474 | | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; } |
| 488 | | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; ntemp--;} | 475 | | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; } |
| 489 | | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; ntemp--;} | 476 | | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; } |
| 490 | | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; ntemp--;} | 477 | | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; } |
| 491 | | expr1 '^' expr1 { code_byte(POWOP); $$ = 1; ntemp--;} | 478 | | expr1 '^' expr1 { code_byte(POWOP); $$ = 1; } |
| 492 | | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; ntemp--;} | 479 | | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; } |
| 493 | | '+' expr1 %prec UNARY { $$ = 1; } | 480 | | '+' expr1 %prec UNARY { $$ = 1; } |
| 494 | | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;} | 481 | | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;} |
| 495 | | table { $$ = 1; } | 482 | | table { $$ = 1; } |
| @@ -500,9 +487,8 @@ expr : '(' expr ')' { $$ = $2; } | |||
| 500 | code_byte(PUSHSTRING); | 487 | code_byte(PUSHSTRING); |
| 501 | code_word(lua_findconstant($1)); | 488 | code_word(lua_findconstant($1)); |
| 502 | $$ = 1; | 489 | $$ = 1; |
| 503 | incr_ntemp(); | ||
| 504 | } | 490 | } |
| 505 | | NIL {code_byte(PUSHNIL); $$ = 1; incr_ntemp();} | 491 | | NIL {code_byte(PUSHNIL); $$ = 1; } |
| 506 | | functioncall | 492 | | functioncall |
| 507 | { | 493 | { |
| 508 | $$ = 0; | 494 | $$ = 0; |
| @@ -512,13 +498,13 @@ expr : '(' expr ')' { $$ = $2; } | |||
| 512 | } | 498 | } |
| 513 | } | 499 | } |
| 514 | | NOT expr1 { code_byte(NOTOP); $$ = 1;} | 500 | | NOT expr1 { code_byte(NOTOP); $$ = 1;} |
| 515 | | expr1 AND PrepJump {code_byte(POP); ntemp--;} expr1 | 501 | | expr1 AND PrepJump {code_byte(POP); } expr1 |
| 516 | { | 502 | { |
| 517 | basepc[$3] = ONFJMP; | 503 | basepc[$3] = ONFJMP; |
| 518 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); | 504 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); |
| 519 | $$ = 1; | 505 | $$ = 1; |
| 520 | } | 506 | } |
| 521 | | expr1 OR PrepJump {code_byte(POP); ntemp--;} expr1 | 507 | | expr1 OR PrepJump {code_byte(POP); } expr1 |
| 522 | { | 508 | { |
| 523 | basepc[$3] = ONTJMP; | 509 | basepc[$3] = ONTJMP; |
| 524 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); | 510 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); |
| @@ -537,33 +523,35 @@ table : | |||
| 537 | } | 523 | } |
| 538 | ; | 524 | ; |
| 539 | 525 | ||
| 540 | functioncall : funcvalue funcParams { code_byte(CALLFUNC); ntemp = $1-1; } | 526 | functioncall : funcvalue funcParams |
| 527 | { code_byte(CALLFUNC); code_byte($1+$2); } | ||
| 541 | ; | 528 | ; |
| 542 | funcvalue : varexp | 529 | |
| 543 | { | 530 | funcvalue : varexp { $$ = 0; } |
| 544 | $$ = ntemp; code_byte(PUSHMARK); incr_ntemp(); | ||
| 545 | } | ||
| 546 | | varexp ':' NAME | 531 | | varexp ':' NAME |
| 547 | { | 532 | { |
| 548 | code_byte(PUSHSTRING); | 533 | code_byte(PUSHSTRING); |
| 549 | code_word(lua_findconstant($3)); | 534 | code_word(lua_findconstant($3)); |
| 550 | incr_ntemp(); | 535 | code_byte(PUSHSELF); |
| 551 | $$ = ntemp-1; | 536 | $$ = 1; |
| 552 | code_byte(PUSHMARKMET); | ||
| 553 | incr_ntemp(); | ||
| 554 | } | 537 | } |
| 555 | ; | 538 | ; |
| 539 | |||
| 556 | funcParams : '(' exprlist ')' | 540 | funcParams : '(' exprlist ')' |
| 557 | | table | 541 | { if ($2<0) { code_byte(1); $$ = -$2; } else $$ = $2; } |
| 542 | | table { $$ = 1; } | ||
| 558 | ; | 543 | ; |
| 559 | 544 | ||
| 560 | exprlist : /* empty */ { $$ = 1; } | 545 | exprlist : /* empty */ { $$ = 0; } |
| 561 | | exprlist1 { $$ = $1; } | 546 | | exprlist1 { $$ = $1; } |
| 562 | ; | 547 | ; |
| 563 | 548 | ||
| 564 | exprlist1 : expr { $$ = $1; } | 549 | exprlist1 : expr { if ($1 == 0) $$ = -1; else $$ = 1; } |
| 565 | | exprlist1 ',' {if (!$1){lua_codeadjust (ntemp+1); incr_ntemp();}} | 550 | | exprlist1 ',' { if ($1 < 0) code_byte(1); } expr |
| 566 | expr {$$ = $4;} | 551 | { |
| 552 | int r = $1 < 0 ? -$1 : $1; | ||
| 553 | $$ = ($4 == 0) ? -(r+1) : r+1; | ||
| 554 | } | ||
| 567 | ; | 555 | ; |
| 568 | 556 | ||
| 569 | parlist : /* empty */ | 557 | parlist : /* empty */ |
| @@ -641,7 +629,7 @@ var : singlevar { $$ = $1; } | |||
| 641 | | varexp '.' NAME | 629 | | varexp '.' NAME |
| 642 | { | 630 | { |
| 643 | code_byte(PUSHSTRING); | 631 | code_byte(PUSHSTRING); |
| 644 | code_word(lua_findconstant($3)); incr_ntemp(); | 632 | code_word(lua_findconstant($3)); |
| 645 | $$ = 0; /* indexed variable */ | 633 | $$ = 0; /* indexed variable */ |
| 646 | } | 634 | } |
| 647 | ; | 635 | ; |
| @@ -668,8 +656,8 @@ localdeclist : NAME {localvar[nlocalvar]=lua_findsymbol($1); $$ = 1;} | |||
| 668 | } | 656 | } |
| 669 | ; | 657 | ; |
| 670 | 658 | ||
| 671 | decinit : /* empty */ | 659 | decinit : /* empty */ { $$ = 0; } |
| 672 | | '=' exprlist1 | 660 | | '=' exprlist1 { $$ = $2; } |
| 673 | ; | 661 | ; |
| 674 | 662 | ||
| 675 | setdebug : DEBUG {lua_debug = $1;} | 663 | setdebug : DEBUG {lua_debug = $1;} |
| @@ -698,7 +686,6 @@ static void lua_pushvar (long number) | |||
| 698 | { | 686 | { |
| 699 | code_byte(PUSHGLOBAL); | 687 | code_byte(PUSHGLOBAL); |
| 700 | code_word(number-1); | 688 | code_word(number-1); |
| 701 | incr_ntemp(); | ||
| 702 | } | 689 | } |
| 703 | else if (number < 0) /* local var */ | 690 | else if (number < 0) /* local var */ |
| 704 | { | 691 | { |
| @@ -709,19 +696,50 @@ static void lua_pushvar (long number) | |||
| 709 | code_byte(PUSHLOCAL); | 696 | code_byte(PUSHLOCAL); |
| 710 | code_byte(number); | 697 | code_byte(number); |
| 711 | } | 698 | } |
| 712 | incr_ntemp(); | ||
| 713 | } | 699 | } |
| 714 | else | 700 | else |
| 715 | { | 701 | { |
| 716 | code_byte(PUSHINDEXED); | 702 | code_byte(PUSHINDEXED); |
| 717 | ntemp--; | ||
| 718 | } | 703 | } |
| 719 | } | 704 | } |
| 720 | 705 | ||
| 721 | static void lua_codeadjust (int n) | 706 | static void lua_codeadjust (int n) |
| 722 | { | 707 | { |
| 723 | code_byte(ADJUST); | 708 | if (n+nlocalvar == 0) |
| 724 | code_byte(n + nlocalvar); | 709 | code_byte(ADJUST0); |
| 710 | else | ||
| 711 | { | ||
| 712 | code_byte(ADJUST); | ||
| 713 | code_byte(n+nlocalvar); | ||
| 714 | } | ||
| 715 | } | ||
| 716 | |||
| 717 | static void codereturn (void) | ||
| 718 | { | ||
| 719 | if (nlocalvar == 0) | ||
| 720 | code_byte(RETCODE0); | ||
| 721 | else | ||
| 722 | { | ||
| 723 | code_byte(RETCODE); | ||
| 724 | code_byte(nlocalvar); | ||
| 725 | } | ||
| 726 | } | ||
| 727 | |||
| 728 | static void adjust_mult_assign (int vars, int exps, int temps) | ||
| 729 | { | ||
| 730 | if (exps < 0) | ||
| 731 | { | ||
| 732 | int r = vars - (-exps-1); | ||
| 733 | if (r >= 0) | ||
| 734 | code_byte(r); | ||
| 735 | else | ||
| 736 | { | ||
| 737 | code_byte(0); | ||
| 738 | lua_codeadjust(temps); | ||
| 739 | } | ||
| 740 | } | ||
| 741 | else if (vars != exps) | ||
| 742 | lua_codeadjust(temps); | ||
| 725 | } | 743 | } |
| 726 | 744 | ||
| 727 | static void lua_codestore (int i) | 745 | static void lua_codestore (int i) |
| @@ -775,10 +793,9 @@ int yywrap (void) | |||
| 775 | 793 | ||
| 776 | 794 | ||
| 777 | /* | 795 | /* |
| 778 | ** Parse LUA code and execute global statement. | 796 | ** Parse LUA code and returns global statements. |
| 779 | ** Return 0 on success or 1 on error. | ||
| 780 | */ | 797 | */ |
| 781 | int lua_parse (void) | 798 | Byte *lua_parse (void) |
| 782 | { | 799 | { |
| 783 | Byte *init = initcode = (Byte *) calloc(CODE_BLOCK, sizeof(Byte)); | 800 | Byte *init = initcode = (Byte *) calloc(CODE_BLOCK, sizeof(Byte)); |
| 784 | maincode = 0; | 801 | maincode = 0; |
| @@ -786,18 +803,17 @@ int lua_parse (void) | |||
| 786 | if (init == NULL) | 803 | if (init == NULL) |
| 787 | { | 804 | { |
| 788 | lua_error("not enough memory"); | 805 | lua_error("not enough memory"); |
| 789 | return 1; | 806 | return NULL; |
| 790 | } | 807 | } |
| 791 | err = 0; | 808 | err = 0; |
| 792 | if (yyparse () || (err==1)) return 1; | 809 | if (yyparse () || (err==1)) return NULL; |
| 793 | initcode[maincode++] = HALT; | 810 | initcode[maincode++] = RETCODE0; |
| 794 | init = initcode; | 811 | init = initcode; |
| 795 | #if LISTING | 812 | #if LISTING |
| 796 | PrintCode(init,init+maincode); | 813 | { static void PrintCode (Byte *code, Byte *end); |
| 814 | PrintCode(init,init+maincode); } | ||
| 797 | #endif | 815 | #endif |
| 798 | if (lua_execute (init)) return 1; | 816 | return init; |
| 799 | free(init); | ||
| 800 | return 0; | ||
| 801 | } | 817 | } |
| 802 | 818 | ||
| 803 | 819 | ||
| @@ -876,7 +892,6 @@ static void PrintCode (Byte *code, Byte *end) | |||
| 876 | } | 892 | } |
| 877 | break; | 893 | break; |
| 878 | case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; | 894 | case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; |
| 879 | case PUSHMARK: printf ("%d PUSHMARK\n", (p++)-code); break; | ||
| 880 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: | 895 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: |
| 881 | case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: | 896 | case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: |
| 882 | case STORELOCAL8: case STORELOCAL9: | 897 | case STORELOCAL8: case STORELOCAL9: |
| @@ -896,6 +911,7 @@ static void PrintCode (Byte *code, Byte *end) | |||
| 896 | printf ("%d STOREGLOBAL %d\n", n, c.w); | 911 | printf ("%d STOREGLOBAL %d\n", n, c.w); |
| 897 | } | 912 | } |
| 898 | break; | 913 | break; |
| 914 | case PUSHSELF: printf ("%d PUSHSELF\n", (p++)-code); break; | ||
| 899 | case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break; | 915 | case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break; |
| 900 | case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p)); | 916 | case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p)); |
| 901 | p++; | 917 | p++; |
| @@ -912,6 +928,7 @@ static void PrintCode (Byte *code, Byte *end) | |||
| 912 | printf("%d STORERECORD %d\n", p-code, *(++p)); | 928 | printf("%d STORERECORD %d\n", p-code, *(++p)); |
| 913 | p += *p*sizeof(Word) + 1; | 929 | p += *p*sizeof(Word) + 1; |
| 914 | break; | 930 | break; |
| 931 | case ADJUST0: printf ("%d ADJUST0\n", (p++)-code); break; | ||
| 915 | case ADJUST: | 932 | case ADJUST: |
| 916 | printf ("%d ADJUST %d\n", p-code, *(++p)); | 933 | printf ("%d ADJUST %d\n", p-code, *(++p)); |
| 917 | p++; | 934 | p++; |
| @@ -922,7 +939,7 @@ static void PrintCode (Byte *code, Byte *end) | |||
| 922 | int n = p-code; | 939 | int n = p-code; |
| 923 | p++; | 940 | p++; |
| 924 | get_word(c,p); | 941 | get_word(c,p); |
| 925 | printf ("%d CREATEARRAY\n", n, c.w); | 942 | printf ("%d CREATEARRAY %d\n", n, c.w); |
| 926 | break; | 943 | break; |
| 927 | } | 944 | } |
| 928 | case EQOP: printf ("%d EQOP\n", (p++)-code); break; | 945 | case EQOP: printf ("%d EQOP\n", (p++)-code); break; |
| @@ -990,16 +1007,19 @@ static void PrintCode (Byte *code, Byte *end) | |||
| 990 | } | 1007 | } |
| 991 | break; | 1008 | break; |
| 992 | case POP: printf ("%d POP\n", (p++)-code); break; | 1009 | case POP: printf ("%d POP\n", (p++)-code); break; |
| 993 | case CALLFUNC: printf ("%d CALLFUNC\n", (p++)-code); break; | 1010 | case CALLFUNC: |
| 1011 | printf ("%d CALLFUNC %d %d\n", p-code, *(p+1), *(p+2)); | ||
| 1012 | p+=3; | ||
| 1013 | break; | ||
| 1014 | case RETCODE0: printf ("%d RETCODE0\n", (p++)-code); break; | ||
| 994 | case RETCODE: | 1015 | case RETCODE: |
| 995 | printf ("%d RETCODE %d\n", p-code, *(++p)); | 1016 | printf ("%d RETCODE %d\n", p-code, *(++p)); |
| 996 | p++; | 1017 | p++; |
| 997 | break; | 1018 | break; |
| 998 | case HALT: printf ("%d HALT\n", (p++)-code); break; | ||
| 999 | case SETFUNCTION: | 1019 | case SETFUNCTION: |
| 1000 | { | 1020 | { |
| 1001 | CodeCode c1; | 1021 | CodeCode c1; |
| 1002 | CodeWord c1; | 1022 | CodeWord c2; |
| 1003 | int n = p-code; | 1023 | int n = p-code; |
| 1004 | p++; | 1024 | p++; |
| 1005 | get_code(c1,p); | 1025 | get_code(c1,p); |
| @@ -3,11 +3,12 @@ | |||
| 3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | char *rcs_opcode="$Id: opcode.c,v 2.11 1994/11/01 17:54:31 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 2.12 1994/11/01 18:25:20 roberto Exp roberto $"; |
| 7 | 7 | ||
| 8 | #include <stdio.h> | 8 | #include <stdio.h> |
| 9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
| 10 | #include <string.h> | 10 | #include <string.h> |
| 11 | #include <setjmp.h> | ||
| 11 | #include <math.h> | 12 | #include <math.h> |
| 12 | #ifdef __GNUC__ | 13 | #ifdef __GNUC__ |
| 13 | #include <floatingpoint.h> | 14 | #include <floatingpoint.h> |
| @@ -19,57 +20,69 @@ char *rcs_opcode="$Id: opcode.c,v 2.11 1994/11/01 17:54:31 roberto Exp roberto $ | |||
| 19 | #include "table.h" | 20 | #include "table.h" |
| 20 | #include "lua.h" | 21 | #include "lua.h" |
| 21 | 22 | ||
| 22 | #define tonumber(o) ((tag(o) != T_NUMBER) && (lua_tonumber(o) != 0)) | 23 | #define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0)) |
| 23 | #define tostring(o) ((tag(o) != T_STRING) && (lua_tostring(o) != 0)) | 24 | #define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) |
| 24 | 25 | ||
| 25 | 26 | ||
| 26 | #define STACK_BUFFER (STACKGAP+128) | 27 | #define STACK_BUFFER (STACKGAP+128) |
| 27 | 28 | ||
| 28 | static Long maxstack; | 29 | static Long maxstack; |
| 29 | static Object *stack=NULL; | 30 | static Object *stack=NULL; |
| 30 | static Object *top, *base; | 31 | static Object *top; |
| 32 | |||
| 33 | static int CBase; /* when Lua calls C or C calls Lua, points to the */ | ||
| 34 | /* first slot after the last parameter. */ | ||
| 35 | static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ | ||
| 36 | /* when C calls Lua, has the number of results. */ | ||
| 37 | |||
| 38 | static jmp_buf *errorJmp; | ||
| 39 | |||
| 40 | static int lua_execute (Byte *pc, int base); | ||
| 41 | |||
| 42 | |||
| 43 | |||
| 44 | /* | ||
| 45 | ** Reports an error, and jumps up to the available recover label | ||
| 46 | */ | ||
| 47 | void lua_error (char *s) | ||
| 48 | { | ||
| 49 | fprintf (stderr, "lua: %s\n", s); | ||
| 50 | if (errorJmp) | ||
| 51 | longjmp(*errorJmp, 1); | ||
| 52 | else | ||
| 53 | exit(1); | ||
| 54 | } | ||
| 31 | 55 | ||
| 32 | 56 | ||
| 33 | /* | 57 | /* |
| 34 | ** Init stack | 58 | ** Init stack |
| 35 | */ | 59 | */ |
| 36 | static int lua_initstack (void) | 60 | static void lua_initstack (void) |
| 37 | { | 61 | { |
| 38 | maxstack = STACK_BUFFER; | 62 | maxstack = STACK_BUFFER; |
| 39 | stack = (Object *)calloc(maxstack, sizeof(Object)); | 63 | stack = (Object *)calloc(maxstack, sizeof(Object)); |
| 40 | if (stack == NULL) | 64 | if (stack == NULL) |
| 41 | { | 65 | lua_error("stack - not enough memory"); |
| 42 | lua_error("stack - not enough memory"); | 66 | top = stack; |
| 43 | return 1; | ||
| 44 | } | ||
| 45 | tag(stack) = T_MARK; | ||
| 46 | top = base = stack+1; | ||
| 47 | return 0; | ||
| 48 | } | 67 | } |
| 49 | 68 | ||
| 50 | 69 | ||
| 51 | /* | 70 | /* |
| 52 | ** Check stack overflow and, if necessary, realloc vector | 71 | ** Check stack overflow and, if necessary, realloc vector |
| 53 | */ | 72 | */ |
| 54 | static int lua_checkstack (Word n) | 73 | static void lua_checkstack (Word n) |
| 55 | { | 74 | { |
| 56 | if (stack == NULL) | 75 | if (stack == NULL) |
| 57 | return lua_initstack(); | 76 | return lua_initstack(); |
| 58 | if (n > maxstack) | 77 | if (n > maxstack) |
| 59 | { | 78 | { |
| 60 | Word t = top-stack; | 79 | int t = top-stack; |
| 61 | Word b = base-stack; | ||
| 62 | maxstack *= 2; | 80 | maxstack *= 2; |
| 63 | stack = (Object *)realloc(stack, maxstack*sizeof(Object)); | 81 | stack = (Object *)realloc(stack, maxstack*sizeof(Object)); |
| 64 | if (stack == NULL) | 82 | if (stack == NULL) |
| 65 | { | 83 | lua_error("stack - not enough memory"); |
| 66 | lua_error("stack - not enough memory"); | ||
| 67 | return 1; | ||
| 68 | } | ||
| 69 | top = stack + t; | 84 | top = stack + t; |
| 70 | base = stack + b; | ||
| 71 | } | 85 | } |
| 72 | return 0; | ||
| 73 | } | 86 | } |
| 74 | 87 | ||
| 75 | 88 | ||
| @@ -82,10 +95,7 @@ static char *lua_strconc (char *l, char *r) | |||
| 82 | static char buffer[1024]; | 95 | static char buffer[1024]; |
| 83 | int n = strlen(l)+strlen(r)+1; | 96 | int n = strlen(l)+strlen(r)+1; |
| 84 | if (n > 1024) | 97 | if (n > 1024) |
| 85 | { | 98 | lua_error ("string too large"); |
| 86 | lua_error ("string too large"); | ||
| 87 | return NULL; | ||
| 88 | } | ||
| 89 | return strcat(strcpy(buffer,l),r); | 99 | return strcat(strcpy(buffer,l),r); |
| 90 | } | 100 | } |
| 91 | 101 | ||
| @@ -99,59 +109,46 @@ static int ToReal (char* s, float* f) | |||
| 99 | /* | 109 | /* |
| 100 | ** Convert, if possible, to a number object. | 110 | ** Convert, if possible, to a number object. |
| 101 | ** Return 0 if success, not 0 if error. | 111 | ** Return 0 if success, not 0 if error. |
| 102 | */ | 112 | */ |
| 103 | static int lua_tonumber (Object *obj) | 113 | static int lua_tonumber (Object *obj) |
| 104 | { | 114 | { |
| 105 | if (tag(obj) != T_STRING) | 115 | if (tag(obj) != LUA_T_STRING) |
| 106 | { | 116 | return 1;; |
| 107 | lua_reportbug ("unexpected type at conversion to number"); | ||
| 108 | return 1; | ||
| 109 | } | ||
| 110 | if (!ToReal(svalue(obj), &nvalue(obj))) | 117 | if (!ToReal(svalue(obj), &nvalue(obj))) |
| 111 | { | 118 | return 2; |
| 112 | lua_reportbug ("string to number convertion failed"); | 119 | tag(obj) = LUA_T_NUMBER; |
| 113 | return 2; | ||
| 114 | } | ||
| 115 | tag(obj) = T_NUMBER; | ||
| 116 | return 0; | 120 | return 0; |
| 117 | } | 121 | } |
| 118 | 122 | ||
| 119 | /* | 123 | /* |
| 120 | ** Test if it is possible to convert an object to a number object. | 124 | ** Test if it is possible to convert an object to a number object. |
| 121 | ** If possible, return the converted object, otherwise return nil object. | 125 | ** If possible, return the converted object, otherwise return nil object. |
| 122 | */ | 126 | */ |
| 123 | static Object *lua_convtonumber (Object *obj) | 127 | static Object *lua_convtonumber (Object *obj) |
| 124 | { | 128 | { |
| 125 | static Object cvt; | 129 | static Object cvt; |
| 126 | 130 | if (tag(obj) == LUA_T_NUMBER) | |
| 127 | if (tag(obj) == T_NUMBER) | ||
| 128 | { | 131 | { |
| 129 | cvt = *obj; | 132 | cvt = *obj; |
| 130 | return &cvt; | 133 | return &cvt; |
| 131 | } | 134 | } |
| 132 | 135 | if (tag(obj) == LUA_T_STRING && ToReal(svalue(obj), &nvalue(&cvt))) | |
| 133 | if (tag(obj) == T_STRING && ToReal(svalue(obj), &nvalue(&cvt))) | 136 | tag(&cvt) = LUA_T_NUMBER; |
| 134 | tag(&cvt) = T_NUMBER; | 137 | else |
| 135 | else | 138 | tag(&cvt) = LUA_T_NIL; |
| 136 | tag(&cvt) = T_NIL; | ||
| 137 | |||
| 138 | return &cvt; | 139 | return &cvt; |
| 139 | } | 140 | } |
| 140 | 141 | ||
| 141 | 142 | ||
| 142 | |||
| 143 | /* | 143 | /* |
| 144 | ** Convert, if possible, to a string tag | 144 | ** Convert, if possible, to a string tag |
| 145 | ** Return 0 in success or not 0 on error. | 145 | ** Return 0 in success or not 0 on error. |
| 146 | */ | 146 | */ |
| 147 | static int lua_tostring (Object *obj) | 147 | static int lua_tostring (Object *obj) |
| 148 | { | 148 | { |
| 149 | static char s[256]; | 149 | static char s[256]; |
| 150 | if (tag(obj) != T_NUMBER) | 150 | if (tag(obj) != LUA_T_NUMBER) |
| 151 | { | 151 | lua_reportbug ("unexpected type at conversion to string"); |
| 152 | lua_reportbug ("unexpected type at conversion to string"); | ||
| 153 | return 1; | ||
| 154 | } | ||
| 155 | if ((int) nvalue(obj) == nvalue(obj)) | 152 | if ((int) nvalue(obj) == nvalue(obj)) |
| 156 | sprintf (s, "%d", (int) nvalue(obj)); | 153 | sprintf (s, "%d", (int) nvalue(obj)); |
| 157 | else | 154 | else |
| @@ -159,487 +156,67 @@ static int lua_tostring (Object *obj) | |||
| 159 | svalue(obj) = lua_createstring(s); | 156 | svalue(obj) = lua_createstring(s); |
| 160 | if (svalue(obj) == NULL) | 157 | if (svalue(obj) == NULL) |
| 161 | return 1; | 158 | return 1; |
| 162 | tag(obj) = T_STRING; | 159 | tag(obj) = LUA_T_STRING; |
| 163 | return 0; | 160 | return 0; |
| 164 | } | 161 | } |
| 165 | 162 | ||
| 166 | 163 | ||
| 167 | /* | 164 | /* |
| 168 | ** Execute the given opcode. Return 0 in success or 1 on error. | 165 | ** Adjust stack. Set top to the given value, pushing NILs if needed. |
| 169 | */ | 166 | */ |
| 170 | int lua_execute (Byte *pc) | 167 | static void adjust_top (Object *newtop) |
| 171 | { | 168 | { |
| 172 | Word oldbase; | 169 | while (top < newtop) tag(top++) = LUA_T_NIL; |
| 173 | 170 | top = newtop; /* top could be bigger than newtop */ | |
| 174 | if (stack == NULL) | 171 | } |
| 175 | lua_initstack(); | ||
| 176 | |||
| 177 | oldbase = base-stack; | ||
| 178 | base = top; | ||
| 179 | while (1) | ||
| 180 | { | ||
| 181 | OpCode opcode; | ||
| 182 | switch (opcode = (OpCode)*pc++) | ||
| 183 | { | ||
| 184 | case PUSHNIL: tag(top++) = T_NIL; break; | ||
| 185 | |||
| 186 | case PUSH0: tag(top) = T_NUMBER; nvalue(top++) = 0; break; | ||
| 187 | case PUSH1: tag(top) = T_NUMBER; nvalue(top++) = 1; break; | ||
| 188 | case PUSH2: tag(top) = T_NUMBER; nvalue(top++) = 2; break; | ||
| 189 | |||
| 190 | case PUSHBYTE: tag(top) = T_NUMBER; nvalue(top++) = *pc++; break; | ||
| 191 | |||
| 192 | case PUSHWORD: | ||
| 193 | { | ||
| 194 | CodeWord code; | ||
| 195 | get_word(code,pc); | ||
| 196 | tag(top) = T_NUMBER; nvalue(top++) = code.w; | ||
| 197 | } | ||
| 198 | break; | ||
| 199 | |||
| 200 | case PUSHFLOAT: | ||
| 201 | { | ||
| 202 | CodeFloat code; | ||
| 203 | get_float(code,pc); | ||
| 204 | tag(top) = T_NUMBER; nvalue(top++) = code.f; | ||
| 205 | } | ||
| 206 | break; | ||
| 207 | 172 | ||
| 208 | case PUSHSTRING: | ||
| 209 | { | ||
| 210 | CodeWord code; | ||
| 211 | get_word(code,pc); | ||
| 212 | tag(top) = T_STRING; svalue(top++) = lua_constant[code.w]; | ||
| 213 | } | ||
| 214 | break; | ||
| 215 | 173 | ||
| 216 | case PUSHFUNCTION: | 174 | /* |
| 217 | { | 175 | ** Call a C function. CBase will point to the top of the stack, |
| 218 | CodeCode code; | 176 | ** and CnResults is the number of parameters. Returns an index |
| 219 | get_code(code,pc); | 177 | ** to the first result from C. |
| 220 | tag(top) = T_FUNCTION; bvalue(top++) = code.b; | 178 | */ |
| 221 | } | 179 | static int callC (lua_CFunction func, int base) |
| 222 | break; | 180 | { |
| 223 | 181 | int oldBase = CBase; | |
| 224 | case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: | 182 | int oldCnResults = CnResults; |
| 225 | case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: | 183 | int firstResult; |
| 226 | case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: | 184 | CnResults = (top-stack) - base; |
| 227 | case PUSHLOCAL9: *top++ = *(base + (int)(opcode-PUSHLOCAL0)); break; | 185 | CBase = base+CnResults; /* incorporate parameters on the stack */ |
| 228 | 186 | (*func)(); | |
| 229 | case PUSHLOCAL: *top++ = *(base + (*pc++)); break; | 187 | firstResult = CBase; |
| 230 | 188 | CBase = oldBase; | |
| 231 | case PUSHGLOBAL: | 189 | CnResults = oldCnResults; |
| 232 | { | 190 | return firstResult; |
| 233 | CodeWord code; | 191 | } |
| 234 | get_word(code,pc); | ||
| 235 | *top++ = s_object(code.w); | ||
| 236 | } | ||
| 237 | break; | ||
| 238 | |||
| 239 | case PUSHINDEXED: | ||
| 240 | { | ||
| 241 | int s = lua_pushsubscript(); | ||
| 242 | if (s == 1) return 1; | ||
| 243 | } | ||
| 244 | break; | ||
| 245 | |||
| 246 | case PUSHMARK: tag(top++) = T_MARK; break; | ||
| 247 | case PUSHMARKMET: | ||
| 248 | { | ||
| 249 | Object receiver = *(top-2); | ||
| 250 | if (lua_pushsubscript() == 1) return 1; | ||
| 251 | tag(top++) = T_MARK; | ||
| 252 | *(top++) = receiver; | ||
| 253 | break; | ||
| 254 | } | ||
| 255 | |||
| 256 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: | ||
| 257 | case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: | ||
| 258 | case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: | ||
| 259 | case STORELOCAL9: *(base + (int)(opcode-STORELOCAL0)) = *(--top); break; | ||
| 260 | |||
| 261 | case STORELOCAL: *(base + (*pc++)) = *(--top); break; | ||
| 262 | |||
| 263 | case STOREGLOBAL: | ||
| 264 | { | ||
| 265 | CodeWord code; | ||
| 266 | get_word(code,pc); | ||
| 267 | s_object(code.w) = *(--top); | ||
| 268 | } | ||
| 269 | break; | ||
| 270 | |||
| 271 | case STOREINDEXED0: | ||
| 272 | { | ||
| 273 | int s = lua_storesubscript(); | ||
| 274 | if (s == 1) return 1; | ||
| 275 | } | ||
| 276 | break; | ||
| 277 | |||
| 278 | case STOREINDEXED: | ||
| 279 | { | ||
| 280 | int n = *pc++; | ||
| 281 | if (tag(top-3-n) != T_ARRAY) | ||
| 282 | { | ||
| 283 | lua_reportbug ("indexed expression not a table"); | ||
| 284 | return 1; | ||
| 285 | } | ||
| 286 | { | ||
| 287 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | ||
| 288 | if (h == NULL) return 1; | ||
| 289 | *h = *(top-1); | ||
| 290 | } | ||
| 291 | top--; | ||
| 292 | } | ||
| 293 | break; | ||
| 294 | |||
| 295 | case STORELIST0: | ||
| 296 | case STORELIST: | ||
| 297 | { | ||
| 298 | int m, n; | ||
| 299 | Object *arr; | ||
| 300 | if (opcode == STORELIST0) m = 0; | ||
| 301 | else m = *(pc++) * FIELDS_PER_FLUSH; | ||
| 302 | n = *(pc++); | ||
| 303 | arr = top-n-1; | ||
| 304 | if (tag(arr) != T_ARRAY) | ||
| 305 | { | ||
| 306 | lua_reportbug ("internal error - table expected"); | ||
| 307 | return 1; | ||
| 308 | } | ||
| 309 | while (n) | ||
| 310 | { | ||
| 311 | tag(top) = T_NUMBER; nvalue(top) = n+m; | ||
| 312 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
| 313 | top--; | ||
| 314 | n--; | ||
| 315 | } | ||
| 316 | } | ||
| 317 | break; | ||
| 318 | |||
| 319 | case STORERECORD: | ||
| 320 | { | ||
| 321 | int n = *(pc++); | ||
| 322 | Object *arr = top-n-1; | ||
| 323 | if (tag(arr) != T_ARRAY) | ||
| 324 | { | ||
| 325 | lua_reportbug ("internal error - table expected"); | ||
| 326 | return 1; | ||
| 327 | } | ||
| 328 | while (n) | ||
| 329 | { | ||
| 330 | CodeWord code; | ||
| 331 | get_word(code,pc); | ||
| 332 | tag(top) = T_STRING; svalue(top) = lua_constant[code.w]; | ||
| 333 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
| 334 | top--; | ||
| 335 | n--; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | break; | ||
| 339 | |||
| 340 | case ADJUST: | ||
| 341 | { | ||
| 342 | Object *newtop = base + *(pc++); | ||
| 343 | while (top < newtop) tag(top++) = T_NIL; | ||
| 344 | top = newtop; /* top could be bigger than newtop */ | ||
| 345 | } | ||
| 346 | break; | ||
| 347 | |||
| 348 | case CREATEARRAY: | ||
| 349 | { | ||
| 350 | CodeWord size; | ||
| 351 | get_word(size,pc); | ||
| 352 | top++; | ||
| 353 | avalue(top-1) = lua_createarray(size.w); | ||
| 354 | if (avalue(top-1) == NULL) | ||
| 355 | return 1; | ||
| 356 | tag(top-1) = T_ARRAY; | ||
| 357 | } | ||
| 358 | break; | ||
| 359 | |||
| 360 | case EQOP: | ||
| 361 | { | ||
| 362 | Object *l = top-2; | ||
| 363 | Object *r = top-1; | ||
| 364 | --top; | ||
| 365 | if (tag(l) != tag(r)) | ||
| 366 | tag(top-1) = T_NIL; | ||
| 367 | else | ||
| 368 | { | ||
| 369 | switch (tag(l)) | ||
| 370 | { | ||
| 371 | case T_NIL: tag(top-1) = T_NUMBER; break; | ||
| 372 | case T_NUMBER: tag(top-1) = (nvalue(l) == nvalue(r)) ? T_NUMBER : T_NIL; break; | ||
| 373 | case T_ARRAY: tag(top-1) = (avalue(l) == avalue(r)) ? T_NUMBER : T_NIL; break; | ||
| 374 | case T_FUNCTION: tag(top-1) = (bvalue(l) == bvalue(r)) ? T_NUMBER : T_NIL; break; | ||
| 375 | case T_CFUNCTION: tag(top-1) = (fvalue(l) == fvalue(r)) ? T_NUMBER : T_NIL; break; | ||
| 376 | case T_USERDATA: tag(top-1) = (uvalue(l) == uvalue(r)) ? T_NUMBER : T_NIL; break; | ||
| 377 | case T_STRING: tag(top-1) = (strcmp (svalue(l), svalue(r)) == 0) ? T_NUMBER : T_NIL; break; | ||
| 378 | case T_MARK: return 1; | ||
| 379 | } | ||
| 380 | } | ||
| 381 | nvalue(top-1) = 1; | ||
| 382 | } | ||
| 383 | break; | ||
| 384 | |||
| 385 | case LTOP: | ||
| 386 | { | ||
| 387 | Object *l = top-2; | ||
| 388 | Object *r = top-1; | ||
| 389 | --top; | ||
| 390 | if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) | ||
| 391 | tag(top-1) = (nvalue(l) < nvalue(r)) ? T_NUMBER : T_NIL; | ||
| 392 | else | ||
| 393 | { | ||
| 394 | if (tostring(l) || tostring(r)) | ||
| 395 | return 1; | ||
| 396 | tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? T_NUMBER : T_NIL; | ||
| 397 | } | ||
| 398 | nvalue(top-1) = 1; | ||
| 399 | } | ||
| 400 | break; | ||
| 401 | |||
| 402 | case LEOP: | ||
| 403 | { | ||
| 404 | Object *l = top-2; | ||
| 405 | Object *r = top-1; | ||
| 406 | --top; | ||
| 407 | if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) | ||
| 408 | tag(top-1) = (nvalue(l) <= nvalue(r)) ? T_NUMBER : T_NIL; | ||
| 409 | else | ||
| 410 | { | ||
| 411 | if (tostring(l) || tostring(r)) | ||
| 412 | return 1; | ||
| 413 | tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? T_NUMBER : T_NIL; | ||
| 414 | } | ||
| 415 | nvalue(top-1) = 1; | ||
| 416 | } | ||
| 417 | break; | ||
| 418 | |||
| 419 | case ADDOP: | ||
| 420 | { | ||
| 421 | Object *l = top-2; | ||
| 422 | Object *r = top-1; | ||
| 423 | if (tonumber(r) || tonumber(l)) | ||
| 424 | return 1; | ||
| 425 | nvalue(l) += nvalue(r); | ||
| 426 | --top; | ||
| 427 | } | ||
| 428 | break; | ||
| 429 | |||
| 430 | case SUBOP: | ||
| 431 | { | ||
| 432 | Object *l = top-2; | ||
| 433 | Object *r = top-1; | ||
| 434 | if (tonumber(r) || tonumber(l)) | ||
| 435 | return 1; | ||
| 436 | nvalue(l) -= nvalue(r); | ||
| 437 | --top; | ||
| 438 | } | ||
| 439 | break; | ||
| 440 | |||
| 441 | case MULTOP: | ||
| 442 | { | ||
| 443 | Object *l = top-2; | ||
| 444 | Object *r = top-1; | ||
| 445 | if (tonumber(r) || tonumber(l)) | ||
| 446 | return 1; | ||
| 447 | nvalue(l) *= nvalue(r); | ||
| 448 | --top; | ||
| 449 | } | ||
| 450 | break; | ||
| 451 | |||
| 452 | case DIVOP: | ||
| 453 | { | ||
| 454 | Object *l = top-2; | ||
| 455 | Object *r = top-1; | ||
| 456 | if (tonumber(r) || tonumber(l)) | ||
| 457 | return 1; | ||
| 458 | nvalue(l) /= nvalue(r); | ||
| 459 | --top; | ||
| 460 | } | ||
| 461 | break; | ||
| 462 | |||
| 463 | case POWOP: | ||
| 464 | { | ||
| 465 | Object *l = top-2; | ||
| 466 | Object *r = top-1; | ||
| 467 | if (tonumber(r) || tonumber(l)) | ||
| 468 | return 1; | ||
| 469 | nvalue(l) = pow(nvalue(l), nvalue(r)); | ||
| 470 | --top; | ||
| 471 | } | ||
| 472 | break; | ||
| 473 | |||
| 474 | case CONCOP: | ||
| 475 | { | ||
| 476 | Object *l = top-2; | ||
| 477 | Object *r = top-1; | ||
| 478 | if (tostring(r) || tostring(l)) | ||
| 479 | return 1; | ||
| 480 | svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | ||
| 481 | if (svalue(l) == NULL) | ||
| 482 | return 1; | ||
| 483 | --top; | ||
| 484 | } | ||
| 485 | break; | ||
| 486 | |||
| 487 | case MINUSOP: | ||
| 488 | if (tonumber(top-1)) | ||
| 489 | return 1; | ||
| 490 | nvalue(top-1) = - nvalue(top-1); | ||
| 491 | break; | ||
| 492 | |||
| 493 | case NOTOP: | ||
| 494 | tag(top-1) = tag(top-1) == T_NIL ? T_NUMBER : T_NIL; | ||
| 495 | break; | ||
| 496 | |||
| 497 | case ONTJMP: | ||
| 498 | { | ||
| 499 | CodeWord code; | ||
| 500 | get_word(code,pc); | ||
| 501 | if (tag(top-1) != T_NIL) pc += code.w; | ||
| 502 | } | ||
| 503 | break; | ||
| 504 | |||
| 505 | case ONFJMP: | ||
| 506 | { | ||
| 507 | CodeWord code; | ||
| 508 | get_word(code,pc); | ||
| 509 | if (tag(top-1) == T_NIL) pc += code.w; | ||
| 510 | } | ||
| 511 | break; | ||
| 512 | |||
| 513 | case JMP: | ||
| 514 | { | ||
| 515 | CodeWord code; | ||
| 516 | get_word(code,pc); | ||
| 517 | pc += code.w; | ||
| 518 | } | ||
| 519 | break; | ||
| 520 | |||
| 521 | case UPJMP: | ||
| 522 | { | ||
| 523 | CodeWord code; | ||
| 524 | get_word(code,pc); | ||
| 525 | pc -= code.w; | ||
| 526 | } | ||
| 527 | break; | ||
| 528 | |||
| 529 | case IFFJMP: | ||
| 530 | { | ||
| 531 | CodeWord code; | ||
| 532 | get_word(code,pc); | ||
| 533 | top--; | ||
| 534 | if (tag(top) == T_NIL) pc += code.w; | ||
| 535 | } | ||
| 536 | break; | ||
| 537 | 192 | ||
| 538 | case IFFUPJMP: | ||
| 539 | { | ||
| 540 | CodeWord code; | ||
| 541 | get_word(code,pc); | ||
| 542 | top--; | ||
| 543 | if (tag(top) == T_NIL) pc -= code.w; | ||
| 544 | } | ||
| 545 | break; | ||
| 546 | 193 | ||
| 547 | case POP: --top; break; | 194 | /* |
| 548 | 195 | ** Call a function (C or Lua). The parameters must be on the stack, | |
| 549 | case CALLFUNC: | 196 | ** between [stack+base,top). When returns, the results are on the stack, |
| 550 | { | 197 | ** between [stack+whereRes,top). The number of results is nResults, unless |
| 551 | Byte *newpc; | 198 | ** nResults=MULT_RET. |
| 552 | Object *b = top-1; | 199 | */ |
| 553 | while (tag(b) != T_MARK) b--; | 200 | static void do_call (Object *func, int base, int nResults, int whereRes) |
| 554 | if (tag(b-1) == T_FUNCTION) | 201 | { |
| 555 | { | 202 | int firstResult; |
| 556 | lua_debugline = 0; /* always reset debug flag */ | 203 | if (tag(func) == LUA_T_CFUNCTION) |
| 557 | newpc = bvalue(b-1); | 204 | firstResult = callC(fvalue(func), base); |
| 558 | bvalue(b-1) = pc; /* store return code */ | 205 | else if (tag(func) == LUA_T_FUNCTION) |
| 559 | nvalue(b) = (base-stack); /* store base value */ | 206 | firstResult = lua_execute(bvalue(func), base); |
| 560 | base = b+1; | 207 | else |
| 561 | pc = newpc; | 208 | lua_reportbug ("call expression not a function"); |
| 562 | if (lua_checkstack(STACKGAP+(base-stack))) | 209 | /* adjust the number of results */ |
| 563 | return 1; | 210 | if (nResults != MULT_RET && top - (stack+firstResult) != nResults) |
| 564 | } | 211 | adjust_top(stack+firstResult+nResults); |
| 565 | else if (tag(b-1) == T_CFUNCTION) | 212 | /* move results to the given position */ |
| 566 | { | 213 | if (firstResult != whereRes) |
| 567 | int nparam; | 214 | { |
| 568 | lua_debugline = 0; /* always reset debug flag */ | 215 | int i = top - (stack+firstResult); /* number of results */ |
| 569 | nvalue(b) = (base-stack); /* store base value */ | 216 | top -= firstResult-whereRes; |
| 570 | base = b+1; | 217 | while (i--) |
| 571 | nparam = top-base; /* number of parameters */ | 218 | *(stack+whereRes+i) = *(stack+firstResult+i); |
| 572 | (fvalue(b-1))(); /* call C function */ | ||
| 573 | |||
| 574 | /* shift returned values */ | ||
| 575 | { | ||
| 576 | int i; | ||
| 577 | int nretval = top - base - nparam; | ||
| 578 | top = base - 2; | ||
| 579 | base = stack + (int) nvalue(base-1); | ||
| 580 | for (i=0; i<nretval; i++) | ||
| 581 | { | ||
| 582 | *top = *(top+nparam+2); | ||
| 583 | ++top; | ||
| 584 | } | ||
| 585 | } | ||
| 586 | } | ||
| 587 | else | ||
| 588 | { | ||
| 589 | lua_reportbug ("call expression not a function"); | ||
| 590 | return 1; | ||
| 591 | } | ||
| 592 | } | ||
| 593 | break; | ||
| 594 | |||
| 595 | case RETCODE: | ||
| 596 | { | ||
| 597 | int i; | ||
| 598 | int shift = *pc++; | ||
| 599 | int nretval = top - base - shift; | ||
| 600 | top = base - 2; | ||
| 601 | pc = bvalue(base-2); | ||
| 602 | base = stack + (int) nvalue(base-1); | ||
| 603 | for (i=0; i<nretval; i++) | ||
| 604 | { | ||
| 605 | *top = *(top+shift+2); | ||
| 606 | ++top; | ||
| 607 | } | ||
| 608 | } | ||
| 609 | break; | ||
| 610 | |||
| 611 | case HALT: | ||
| 612 | base = stack+oldbase; | ||
| 613 | return 0; /* success */ | ||
| 614 | |||
| 615 | case SETFUNCTION: | ||
| 616 | { | ||
| 617 | CodeCode file; | ||
| 618 | CodeWord func; | ||
| 619 | get_code(file,pc); | ||
| 620 | get_word(func,pc); | ||
| 621 | if (lua_pushfunction ((char *)file.b, func.w)) | ||
| 622 | return 1; | ||
| 623 | } | ||
| 624 | break; | ||
| 625 | |||
| 626 | case SETLINE: | ||
| 627 | { | ||
| 628 | CodeWord code; | ||
| 629 | get_word(code,pc); | ||
| 630 | lua_debugline = code.w; | ||
| 631 | } | ||
| 632 | break; | ||
| 633 | |||
| 634 | case RESET: | ||
| 635 | lua_popfunction (); | ||
| 636 | break; | ||
| 637 | |||
| 638 | default: | ||
| 639 | lua_error ("internal error - opcode didn't match"); | ||
| 640 | return 1; | ||
| 641 | } | 219 | } |
| 642 | } | ||
| 643 | } | 220 | } |
| 644 | 221 | ||
| 645 | 222 | ||
| @@ -649,7 +226,7 @@ int lua_execute (Byte *pc) | |||
| 649 | int lua_pushsubscript (void) | 226 | int lua_pushsubscript (void) |
| 650 | { | 227 | { |
| 651 | --top; | 228 | --top; |
| 652 | if (tag(top-1) != T_ARRAY) | 229 | if (tag(top-1) != LUA_T_ARRAY) |
| 653 | { | 230 | { |
| 654 | lua_reportbug ("indexed expression not a table"); | 231 | lua_reportbug ("indexed expression not a table"); |
| 655 | return 1; | 232 | return 1; |
| @@ -668,7 +245,7 @@ int lua_pushsubscript (void) | |||
| 668 | */ | 245 | */ |
| 669 | int lua_storesubscript (void) | 246 | int lua_storesubscript (void) |
| 670 | { | 247 | { |
| 671 | if (tag(top-3) != T_ARRAY) | 248 | if (tag(top-3) != LUA_T_ARRAY) |
| 672 | { | 249 | { |
| 673 | lua_reportbug ("indexed expression not a table"); | 250 | lua_reportbug ("indexed expression not a table"); |
| 674 | return 1; | 251 | return 1; |
| @@ -693,61 +270,89 @@ void lua_travstack (void (*fn)(Object *)) | |||
| 693 | fn (o); | 270 | fn (o); |
| 694 | } | 271 | } |
| 695 | 272 | ||
| 273 | |||
| 696 | /* | 274 | /* |
| 697 | ** Open file, generate opcode and execute global statement. Return 0 on | 275 | ** Executes a main procedure. Uses as Base the top of the stack, as it |
| 698 | ** success or 1 on error. | 276 | ** uses no parameters and left no results. |
| 699 | */ | 277 | */ |
| 700 | int lua_dofile (char *filename) | 278 | static void do_main (Byte *main) |
| 701 | { | 279 | { |
| 702 | if (lua_openfile (filename)) return 1; | 280 | if (main) |
| 703 | if (lua_parse ()) { lua_closefile (); return 1; } | 281 | { |
| 704 | lua_closefile (); | 282 | Object f; |
| 705 | return 0; | 283 | tag(&f) = LUA_T_FUNCTION; bvalue(&f) = main; |
| 284 | do_call(&f, top-stack, 0, top-stack); | ||
| 285 | free(main); | ||
| 286 | } | ||
| 706 | } | 287 | } |
| 707 | 288 | ||
| 289 | |||
| 708 | /* | 290 | /* |
| 709 | ** Generate opcode stored on string and execute global statement. Return 0 on | 291 | ** Open file, generate opcode and execute global statement. Return 0 on |
| 710 | ** success or 1 on error. | 292 | ** success or 1 on error. |
| 711 | */ | 293 | */ |
| 712 | int lua_dostring (char *string) | 294 | int lua_dofile (char *filename) |
| 713 | { | 295 | { |
| 714 | if (lua_openstring (string)) return 1; | 296 | jmp_buf myErrorJmp; |
| 715 | if (lua_parse ()) return 1; | 297 | int status; |
| 716 | lua_closestring(); | 298 | jmp_buf *oldErr = errorJmp; |
| 717 | return 0; | 299 | errorJmp = &myErrorJmp; |
| 300 | if (setjmp(myErrorJmp) == 0) | ||
| 301 | { | ||
| 302 | lua_openfile (filename); | ||
| 303 | do_main(lua_parse()); | ||
| 304 | status = 0; | ||
| 305 | } | ||
| 306 | else | ||
| 307 | status = 1; | ||
| 308 | lua_closefile(); | ||
| 309 | errorJmp = oldErr; | ||
| 310 | return status; | ||
| 718 | } | 311 | } |
| 719 | 312 | ||
| 720 | /* | 313 | /* |
| 721 | ** Execute the given function. Return 0 on success or 1 on error. | 314 | ** Generate opcode stored on string and execute global statement. Return 0 on |
| 315 | ** success or 1 on error. | ||
| 722 | */ | 316 | */ |
| 723 | int lua_call (char *functionname, int nparam) | 317 | int lua_dostring (char *string) |
| 724 | { | 318 | { |
| 725 | static Byte startcode[] = {CALLFUNC, HALT}; | 319 | jmp_buf myErrorJmp; |
| 726 | int i; | 320 | int status; |
| 727 | Object func = s_object(lua_findsymbol(functionname)); | 321 | jmp_buf *oldErr = errorJmp; |
| 728 | if (tag(&func) != T_FUNCTION) return 1; | 322 | errorJmp = &myErrorJmp; |
| 729 | for (i=1; i<=nparam; i++) | 323 | if (setjmp(myErrorJmp) == 0) |
| 730 | *(top-i+2) = *(top-i); | 324 | { |
| 731 | top += 2; | 325 | lua_openstring(string); |
| 732 | tag(top-nparam-1) = T_MARK; | 326 | do_main(lua_parse()); |
| 733 | *(top-nparam-2) = func; | 327 | status = 0; |
| 734 | return (lua_execute (startcode)); | 328 | } |
| 329 | else | ||
| 330 | status = 1; | ||
| 331 | lua_closestring(); | ||
| 332 | errorJmp = oldErr; | ||
| 333 | return status; | ||
| 735 | } | 334 | } |
| 736 | 335 | ||
| 737 | /* | 336 | /* |
| 738 | ** Execute the given lua function. Return 0 on success or 1 on error. | 337 | ** Execute the given lua function. Return 0 on success or 1 on error. |
| 739 | */ | 338 | */ |
| 740 | int lua_callfunction (Object *function, int nparam) | 339 | int lua_callfunction (Object *function) |
| 741 | { | 340 | { |
| 742 | static Byte startcode[] = {CALLFUNC, HALT}; | 341 | jmp_buf myErrorJmp; |
| 743 | int i; | 342 | int status; |
| 744 | if (tag(function) != T_FUNCTION) return 1; | 343 | jmp_buf *oldErr = errorJmp; |
| 745 | for (i=1; i<=nparam; i++) | 344 | errorJmp = &myErrorJmp; |
| 746 | *(top-i+2) = *(top-i); | 345 | if (setjmp(myErrorJmp) == 0) |
| 747 | top += 2; | 346 | { |
| 748 | tag(top-nparam-1) = T_MARK; | 347 | do_call(function, CBase, MULT_RET, CBase); |
| 749 | *(top-nparam-2) = *function; | 348 | CnResults = (top-stack) - CBase; /* number of results */ |
| 750 | return (lua_execute (startcode)); | 349 | CBase += CnResults; /* incorporate results on the stack */ |
| 350 | status = 0; | ||
| 351 | } | ||
| 352 | else | ||
| 353 | status = 1; | ||
| 354 | errorJmp = oldErr; | ||
| 355 | return status; | ||
| 751 | } | 356 | } |
| 752 | 357 | ||
| 753 | /* | 358 | /* |
| @@ -756,8 +361,8 @@ int lua_callfunction (Object *function, int nparam) | |||
| 756 | */ | 361 | */ |
| 757 | Object *lua_getparam (int number) | 362 | Object *lua_getparam (int number) |
| 758 | { | 363 | { |
| 759 | if (number <= 0 || number > top-base) return NULL; | 364 | if (number <= 0 || number > CnResults) return NULL; |
| 760 | return (base+number-1); | 365 | return (stack+(CBase-CnResults+number-1)); |
| 761 | } | 366 | } |
| 762 | 367 | ||
| 763 | /* | 368 | /* |
| @@ -765,7 +370,7 @@ Object *lua_getparam (int number) | |||
| 765 | */ | 370 | */ |
| 766 | real lua_getnumber (Object *object) | 371 | real lua_getnumber (Object *object) |
| 767 | { | 372 | { |
| 768 | if (object == NULL || tag(object) == T_NIL) return 0.0; | 373 | if (object == NULL || tag(object) == LUA_T_NIL) return 0.0; |
| 769 | if (tonumber (object)) return 0.0; | 374 | if (tonumber (object)) return 0.0; |
| 770 | else return (nvalue(object)); | 375 | else return (nvalue(object)); |
| 771 | } | 376 | } |
| @@ -775,7 +380,7 @@ real lua_getnumber (Object *object) | |||
| 775 | */ | 380 | */ |
| 776 | char *lua_getstring (Object *object) | 381 | char *lua_getstring (Object *object) |
| 777 | { | 382 | { |
| 778 | if (object == NULL || tag(object) == T_NIL) return NULL; | 383 | if (object == NULL || tag(object) == LUA_T_NIL) return NULL; |
| 779 | if (tostring (object)) return NULL; | 384 | if (tostring (object)) return NULL; |
| 780 | else return (svalue(object)); | 385 | else return (svalue(object)); |
| 781 | } | 386 | } |
| @@ -785,7 +390,7 @@ char *lua_getstring (Object *object) | |||
| 785 | */ | 390 | */ |
| 786 | char *lua_copystring (Object *object) | 391 | char *lua_copystring (Object *object) |
| 787 | { | 392 | { |
| 788 | if (object == NULL || tag(object) == T_NIL) return NULL; | 393 | if (object == NULL || tag(object) == LUA_T_NIL) return NULL; |
| 789 | if (tostring (object)) return NULL; | 394 | if (tostring (object)) return NULL; |
| 790 | else return (strdup(svalue(object))); | 395 | else return (strdup(svalue(object))); |
| 791 | } | 396 | } |
| @@ -796,7 +401,7 @@ char *lua_copystring (Object *object) | |||
| 796 | lua_CFunction lua_getcfunction (Object *object) | 401 | lua_CFunction lua_getcfunction (Object *object) |
| 797 | { | 402 | { |
| 798 | if (object == NULL) return NULL; | 403 | if (object == NULL) return NULL; |
| 799 | if (tag(object) != T_CFUNCTION) return NULL; | 404 | if (tag(object) != LUA_T_CFUNCTION) return NULL; |
| 800 | else return (fvalue(object)); | 405 | else return (fvalue(object)); |
| 801 | } | 406 | } |
| 802 | 407 | ||
| @@ -806,7 +411,7 @@ lua_CFunction lua_getcfunction (Object *object) | |||
| 806 | void *lua_getuserdata (Object *object) | 411 | void *lua_getuserdata (Object *object) |
| 807 | { | 412 | { |
| 808 | if (object == NULL) return NULL; | 413 | if (object == NULL) return NULL; |
| 809 | if (tag(object) != T_USERDATA) return NULL; | 414 | if (tag(object) != LUA_T_USERDATA) return NULL; |
| 810 | else return (uvalue(object)); | 415 | else return (uvalue(object)); |
| 811 | } | 416 | } |
| 812 | 417 | ||
| @@ -816,7 +421,7 @@ void *lua_getuserdata (Object *object) | |||
| 816 | void *lua_gettable (Object *object) | 421 | void *lua_gettable (Object *object) |
| 817 | { | 422 | { |
| 818 | if (object == NULL) return NULL; | 423 | if (object == NULL) return NULL; |
| 819 | if (tag(object) != T_ARRAY) return NULL; | 424 | if (tag(object) != LUA_T_ARRAY) return NULL; |
| 820 | else return (avalue(object)); | 425 | else return (avalue(object)); |
| 821 | } | 426 | } |
| 822 | 427 | ||
| @@ -827,12 +432,12 @@ void *lua_gettable (Object *object) | |||
| 827 | Object *lua_getfield (Object *object, char *field) | 432 | Object *lua_getfield (Object *object, char *field) |
| 828 | { | 433 | { |
| 829 | if (object == NULL) return NULL; | 434 | if (object == NULL) return NULL; |
| 830 | if (tag(object) != T_ARRAY) | 435 | if (tag(object) != LUA_T_ARRAY) |
| 831 | return NULL; | 436 | return NULL; |
| 832 | else | 437 | else |
| 833 | { | 438 | { |
| 834 | Object ref; | 439 | Object ref; |
| 835 | tag(&ref) = T_STRING; | 440 | tag(&ref) = LUA_T_STRING; |
| 836 | svalue(&ref) = lua_constant[lua_findconstant(field)]; | 441 | svalue(&ref) = lua_constant[lua_findconstant(field)]; |
| 837 | return (lua_hashget(avalue(object), &ref)); | 442 | return (lua_hashget(avalue(object), &ref)); |
| 838 | } | 443 | } |
| @@ -845,12 +450,12 @@ Object *lua_getfield (Object *object, char *field) | |||
| 845 | Object *lua_getindexed (Object *object, float index) | 450 | Object *lua_getindexed (Object *object, float index) |
| 846 | { | 451 | { |
| 847 | if (object == NULL) return NULL; | 452 | if (object == NULL) return NULL; |
| 848 | if (tag(object) != T_ARRAY) | 453 | if (tag(object) != LUA_T_ARRAY) |
| 849 | return NULL; | 454 | return NULL; |
| 850 | else | 455 | else |
| 851 | { | 456 | { |
| 852 | Object ref; | 457 | Object ref; |
| 853 | tag(&ref) = T_NUMBER; | 458 | tag(&ref) = LUA_T_NUMBER; |
| 854 | nvalue(&ref) = index; | 459 | nvalue(&ref) = index; |
| 855 | return (lua_hashget(avalue(object), &ref)); | 460 | return (lua_hashget(avalue(object), &ref)); |
| 856 | } | 461 | } |
| @@ -867,23 +472,12 @@ Object *lua_getglobal (char *name) | |||
| 867 | } | 472 | } |
| 868 | 473 | ||
| 869 | /* | 474 | /* |
| 870 | ** Pop and return an object | ||
| 871 | */ | ||
| 872 | Object *lua_pop (void) | ||
| 873 | { | ||
| 874 | if (top <= base) return NULL; | ||
| 875 | top--; | ||
| 876 | return top; | ||
| 877 | } | ||
| 878 | |||
| 879 | /* | ||
| 880 | ** Push a nil object | 475 | ** Push a nil object |
| 881 | */ | 476 | */ |
| 882 | int lua_pushnil (void) | 477 | int lua_pushnil (void) |
| 883 | { | 478 | { |
| 884 | if (lua_checkstack(top-stack+1) == 1) | 479 | lua_checkstack(top-stack+1); |
| 885 | return 1; | 480 | tag(top++) = LUA_T_NIL; |
| 886 | tag(top++) = T_NIL; | ||
| 887 | return 0; | 481 | return 0; |
| 888 | } | 482 | } |
| 889 | 483 | ||
| @@ -892,9 +486,8 @@ int lua_pushnil (void) | |||
| 892 | */ | 486 | */ |
| 893 | int lua_pushnumber (real n) | 487 | int lua_pushnumber (real n) |
| 894 | { | 488 | { |
| 895 | if (lua_checkstack(top-stack+1) == 1) | 489 | lua_checkstack(top-stack+1); |
| 896 | return 1; | 490 | tag(top) = LUA_T_NUMBER; nvalue(top++) = n; |
| 897 | tag(top) = T_NUMBER; nvalue(top++) = n; | ||
| 898 | return 0; | 491 | return 0; |
| 899 | } | 492 | } |
| 900 | 493 | ||
| @@ -903,9 +496,8 @@ int lua_pushnumber (real n) | |||
| 903 | */ | 496 | */ |
| 904 | int lua_pushstring (char *s) | 497 | int lua_pushstring (char *s) |
| 905 | { | 498 | { |
| 906 | if (lua_checkstack(top-stack+1) == 1) | 499 | lua_checkstack(top-stack+1); |
| 907 | return 1; | 500 | tag(top) = LUA_T_STRING; |
| 908 | tag(top) = T_STRING; | ||
| 909 | svalue(top++) = lua_createstring(s); | 501 | svalue(top++) = lua_createstring(s); |
| 910 | return 0; | 502 | return 0; |
| 911 | } | 503 | } |
| @@ -915,9 +507,8 @@ int lua_pushstring (char *s) | |||
| 915 | */ | 507 | */ |
| 916 | int lua_pushcfunction (lua_CFunction fn) | 508 | int lua_pushcfunction (lua_CFunction fn) |
| 917 | { | 509 | { |
| 918 | if (lua_checkstack(top-stack+1) == 1) | 510 | lua_checkstack(top-stack+1); |
| 919 | return 1; | 511 | tag(top) = LUA_T_CFUNCTION; fvalue(top++) = fn; |
| 920 | tag(top) = T_CFUNCTION; fvalue(top++) = fn; | ||
| 921 | return 0; | 512 | return 0; |
| 922 | } | 513 | } |
| 923 | 514 | ||
| @@ -926,9 +517,8 @@ int lua_pushcfunction (lua_CFunction fn) | |||
| 926 | */ | 517 | */ |
| 927 | int lua_pushuserdata (void *u) | 518 | int lua_pushuserdata (void *u) |
| 928 | { | 519 | { |
| 929 | if (lua_checkstack(top-stack+1) == 1) | 520 | lua_checkstack(top-stack+1); |
| 930 | return 1; | 521 | tag(top) = LUA_T_USERDATA; uvalue(top++) = u; |
| 931 | tag(top) = T_USERDATA; uvalue(top++) = u; | ||
| 932 | return 0; | 522 | return 0; |
| 933 | } | 523 | } |
| 934 | 524 | ||
| @@ -937,9 +527,8 @@ int lua_pushuserdata (void *u) | |||
| 937 | */ | 527 | */ |
| 938 | int lua_pushtable (void *t) | 528 | int lua_pushtable (void *t) |
| 939 | { | 529 | { |
| 940 | if (lua_checkstack(top-stack+1) == 1) | 530 | lua_checkstack(top-stack+1); |
| 941 | return 1; | 531 | tag(top) = LUA_T_ARRAY; avalue(top++) = t; |
| 942 | tag(top) = T_ARRAY; avalue(top++) = t; | ||
| 943 | return 0; | 532 | return 0; |
| 944 | } | 533 | } |
| 945 | 534 | ||
| @@ -948,21 +537,20 @@ int lua_pushtable (void *t) | |||
| 948 | */ | 537 | */ |
| 949 | int lua_pushobject (Object *o) | 538 | int lua_pushobject (Object *o) |
| 950 | { | 539 | { |
| 951 | if (lua_checkstack(top-stack+1) == 1) | 540 | lua_checkstack(top-stack+1); |
| 952 | return 1; | ||
| 953 | *top++ = *o; | 541 | *top++ = *o; |
| 954 | return 0; | 542 | return 0; |
| 955 | } | 543 | } |
| 956 | 544 | ||
| 957 | /* | 545 | /* |
| 958 | ** Store top of the stack at a global variable array field. | 546 | ** Store top of the stack at a global variable array field. |
| 959 | ** Return 1 on error, 0 on success. | 547 | ** Return 1 on error, 0 on success. |
| 960 | */ | 548 | */ |
| 961 | int lua_storeglobal (char *name) | 549 | int lua_storeglobal (char *name) |
| 962 | { | 550 | { |
| 963 | int n = lua_findsymbol (name); | 551 | int n = lua_findsymbol (name); |
| 964 | if (n < 0) return 1; | 552 | if (n < 0) return 1; |
| 965 | if (tag(top-1) == T_MARK) return 1; | 553 | if (tag(top-1) == LUA_T_MARK) return 1; |
| 966 | s_object(n) = *(--top); | 554 | s_object(n) = *(--top); |
| 967 | return 0; | 555 | return 0; |
| 968 | } | 556 | } |
| @@ -973,16 +561,16 @@ int lua_storeglobal (char *name) | |||
| 973 | */ | 561 | */ |
| 974 | int lua_storefield (lua_Object object, char *field) | 562 | int lua_storefield (lua_Object object, char *field) |
| 975 | { | 563 | { |
| 976 | if (tag(object) != T_ARRAY) | 564 | if (tag(object) != LUA_T_ARRAY) |
| 977 | return 1; | 565 | return 1; |
| 978 | else | 566 | else |
| 979 | { | 567 | { |
| 980 | Object ref, *h; | 568 | Object ref, *h; |
| 981 | tag(&ref) = T_STRING; | 569 | tag(&ref) = LUA_T_STRING; |
| 982 | svalue(&ref) = lua_createstring(field); | 570 | svalue(&ref) = lua_createstring(field); |
| 983 | h = lua_hashdefine(avalue(object), &ref); | 571 | h = lua_hashdefine(avalue(object), &ref); |
| 984 | if (h == NULL) return 1; | 572 | if (h == NULL) return 1; |
| 985 | if (tag(top-1) == T_MARK) return 1; | 573 | if (tag(top-1) == LUA_T_MARK) return 1; |
| 986 | *h = *(--top); | 574 | *h = *(--top); |
| 987 | } | 575 | } |
| 988 | return 0; | 576 | return 0; |
| @@ -994,16 +582,16 @@ int lua_storefield (lua_Object object, char *field) | |||
| 994 | */ | 582 | */ |
| 995 | int lua_storeindexed (lua_Object object, float index) | 583 | int lua_storeindexed (lua_Object object, float index) |
| 996 | { | 584 | { |
| 997 | if (tag(object) != T_ARRAY) | 585 | if (tag(object) != LUA_T_ARRAY) |
| 998 | return 1; | 586 | return 1; |
| 999 | else | 587 | else |
| 1000 | { | 588 | { |
| 1001 | Object ref, *h; | 589 | Object ref, *h; |
| 1002 | tag(&ref) = T_NUMBER; | 590 | tag(&ref) = LUA_T_NUMBER; |
| 1003 | nvalue(&ref) = index; | 591 | nvalue(&ref) = index; |
| 1004 | h = lua_hashdefine(avalue(object), &ref); | 592 | h = lua_hashdefine(avalue(object), &ref); |
| 1005 | if (h == NULL) return 1; | 593 | if (h == NULL) return 1; |
| 1006 | if (tag(top-1) == T_MARK) return 1; | 594 | if (tag(top-1) == LUA_T_MARK) return 1; |
| 1007 | *h = *(--top); | 595 | *h = *(--top); |
| 1008 | } | 596 | } |
| 1009 | return 0; | 597 | return 0; |
| @@ -1015,7 +603,7 @@ int lua_storeindexed (lua_Object object, float index) | |||
| 1015 | */ | 603 | */ |
| 1016 | int lua_isnil (Object *object) | 604 | int lua_isnil (Object *object) |
| 1017 | { | 605 | { |
| 1018 | return (object != NULL && tag(object) == T_NIL); | 606 | return (object != NULL && tag(object) == LUA_T_NIL); |
| 1019 | } | 607 | } |
| 1020 | 608 | ||
| 1021 | /* | 609 | /* |
| @@ -1023,7 +611,7 @@ int lua_isnil (Object *object) | |||
| 1023 | */ | 611 | */ |
| 1024 | int lua_isnumber (Object *object) | 612 | int lua_isnumber (Object *object) |
| 1025 | { | 613 | { |
| 1026 | return (object != NULL && tag(object) == T_NUMBER); | 614 | return (object != NULL && tag(object) == LUA_T_NUMBER); |
| 1027 | } | 615 | } |
| 1028 | 616 | ||
| 1029 | /* | 617 | /* |
| @@ -1031,7 +619,7 @@ int lua_isnumber (Object *object) | |||
| 1031 | */ | 619 | */ |
| 1032 | int lua_isstring (Object *object) | 620 | int lua_isstring (Object *object) |
| 1033 | { | 621 | { |
| 1034 | return (object != NULL && tag(object) == T_STRING); | 622 | return (object != NULL && tag(object) == LUA_T_STRING); |
| 1035 | } | 623 | } |
| 1036 | 624 | ||
| 1037 | /* | 625 | /* |
| @@ -1039,7 +627,7 @@ int lua_isstring (Object *object) | |||
| 1039 | */ | 627 | */ |
| 1040 | int lua_istable (Object *object) | 628 | int lua_istable (Object *object) |
| 1041 | { | 629 | { |
| 1042 | return (object != NULL && tag(object) == T_ARRAY); | 630 | return (object != NULL && tag(object) == LUA_T_ARRAY); |
| 1043 | } | 631 | } |
| 1044 | 632 | ||
| 1045 | /* | 633 | /* |
| @@ -1047,15 +635,15 @@ int lua_istable (Object *object) | |||
| 1047 | */ | 635 | */ |
| 1048 | int lua_isfunction (Object *object) | 636 | int lua_isfunction (Object *object) |
| 1049 | { | 637 | { |
| 1050 | return (object != NULL && tag(object) == T_FUNCTION); | 638 | return (object != NULL && tag(object) == LUA_T_FUNCTION); |
| 1051 | } | 639 | } |
| 1052 | 640 | ||
| 1053 | /* | 641 | /* |
| 1054 | ** Given an object handle, return if it is a cfunction one. | 642 | ** Given an object handle, return if it is a cfunction one. |
| 1055 | */ | 643 | */ |
| 1056 | int lua_iscfunction (Object *object) | 644 | int lua_iscfunction (Object *object) |
| 1057 | { | 645 | { |
| 1058 | return (object != NULL && tag(object) == T_CFUNCTION); | 646 | return (object != NULL && tag(object) == LUA_T_CFUNCTION); |
| 1059 | } | 647 | } |
| 1060 | 648 | ||
| 1061 | /* | 649 | /* |
| @@ -1063,21 +651,10 @@ int lua_iscfunction (Object *object) | |||
| 1063 | */ | 651 | */ |
| 1064 | int lua_isuserdata (Object *object) | 652 | int lua_isuserdata (Object *object) |
| 1065 | { | 653 | { |
| 1066 | return (object != NULL && tag(object) == T_USERDATA); | 654 | return (object != NULL && tag(object) == LUA_T_USERDATA); |
| 1067 | } | ||
| 1068 | |||
| 1069 | /* | ||
| 1070 | ** Internal function: return an object type. | ||
| 1071 | */ | ||
| 1072 | void lua_type (void) | ||
| 1073 | { | ||
| 1074 | Object *o = lua_getparam(1); | ||
| 1075 | |||
| 1076 | if (lua_constant == NULL) | ||
| 1077 | lua_initconstant(); | ||
| 1078 | lua_pushstring (lua_constant[tag(o)]); | ||
| 1079 | } | 655 | } |
| 1080 | 656 | ||
| 657 | |||
| 1081 | /* | 658 | /* |
| 1082 | ** Internal function: convert an object to a number | 659 | ** Internal function: convert an object to a number |
| 1083 | */ | 660 | */ |
| @@ -1087,48 +664,439 @@ void lua_obj2number (void) | |||
| 1087 | lua_pushobject (lua_convtonumber(o)); | 664 | lua_pushobject (lua_convtonumber(o)); |
| 1088 | } | 665 | } |
| 1089 | 666 | ||
| 667 | |||
| 668 | |||
| 1090 | /* | 669 | /* |
| 1091 | ** Internal function: print object values | 670 | ** Execute the given opcode, until a RET. Parameters are between |
| 671 | ** [stack+base,top). Returns n such that the the results are between | ||
| 672 | ** [stack+n,top). | ||
| 1092 | */ | 673 | */ |
| 1093 | void lua_print (void) | 674 | static int lua_execute (Byte *pc, int base) |
| 1094 | { | 675 | { |
| 1095 | int i=1; | 676 | lua_debugline = 0; /* reset debug flag */ |
| 1096 | Object *obj; | 677 | if (stack == NULL) |
| 1097 | while ((obj=lua_getparam (i++)) != NULL) | 678 | lua_initstack(); |
| 679 | while (1) | ||
| 1098 | { | 680 | { |
| 1099 | if (lua_isnumber(obj)) printf("%g\n",lua_getnumber (obj)); | 681 | OpCode opcode; |
| 1100 | else if (lua_isstring(obj)) printf("%s\n",lua_getstring (obj)); | 682 | switch (opcode = (OpCode)*pc++) |
| 1101 | else if (lua_isfunction(obj)) printf("function: %p\n",bvalue(obj)); | 683 | { |
| 1102 | else if (lua_iscfunction(obj)) printf("cfunction: %p\n",lua_getcfunction (obj)); | 684 | case PUSHNIL: tag(top++) = LUA_T_NIL; break; |
| 1103 | else if (lua_isuserdata(obj)) printf("userdata: %p\n",lua_getuserdata (obj)); | ||
| 1104 | else if (lua_istable(obj)) printf("table: %p\n",obj); | ||
| 1105 | else if (lua_isnil(obj)) printf("nil\n"); | ||
| 1106 | else printf("invalid value to print\n"); | ||
| 1107 | } | ||
| 1108 | } | ||
| 1109 | 685 | ||
| 1110 | /* | 686 | case PUSH0: tag(top) = LUA_T_NUMBER; nvalue(top++) = 0; break; |
| 1111 | ** Internal function: do a file | 687 | case PUSH1: tag(top) = LUA_T_NUMBER; nvalue(top++) = 1; break; |
| 1112 | */ | 688 | case PUSH2: tag(top) = LUA_T_NUMBER; nvalue(top++) = 2; break; |
| 1113 | void lua_internaldofile (void) | ||
| 1114 | { | ||
| 1115 | lua_Object obj = lua_getparam (1); | ||
| 1116 | if (lua_isstring(obj) && !lua_dofile(lua_getstring(obj))) | ||
| 1117 | lua_pushnumber(1); | ||
| 1118 | else | ||
| 1119 | lua_pushnil(); | ||
| 1120 | } | ||
| 1121 | 689 | ||
| 1122 | /* | 690 | case PUSHBYTE: tag(top) = LUA_T_NUMBER; nvalue(top++) = *pc++; break; |
| 1123 | ** Internal function: do a string | 691 | |
| 1124 | */ | 692 | case PUSHWORD: |
| 1125 | void lua_internaldostring (void) | 693 | { |
| 1126 | { | 694 | CodeWord code; |
| 1127 | lua_Object obj = lua_getparam (1); | 695 | get_word(code,pc); |
| 1128 | if (lua_isstring(obj) && !lua_dostring(lua_getstring(obj))) | 696 | tag(top) = LUA_T_NUMBER; nvalue(top++) = code.w; |
| 1129 | lua_pushnumber(1); | 697 | } |
| 1130 | else | 698 | break; |
| 1131 | lua_pushnil(); | 699 | |
| 1132 | } | 700 | case PUSHFLOAT: |
| 701 | { | ||
| 702 | CodeFloat code; | ||
| 703 | get_float(code,pc); | ||
| 704 | tag(top) = LUA_T_NUMBER; nvalue(top++) = code.f; | ||
| 705 | } | ||
| 706 | break; | ||
| 707 | |||
| 708 | case PUSHSTRING: | ||
| 709 | { | ||
| 710 | CodeWord code; | ||
| 711 | get_word(code,pc); | ||
| 712 | tag(top) = LUA_T_STRING; svalue(top++) = lua_constant[code.w]; | ||
| 713 | } | ||
| 714 | break; | ||
| 715 | |||
| 716 | case PUSHFUNCTION: | ||
| 717 | { | ||
| 718 | CodeCode code; | ||
| 719 | get_code(code,pc); | ||
| 720 | tag(top) = LUA_T_FUNCTION; bvalue(top++) = code.b; | ||
| 721 | } | ||
| 722 | break; | ||
| 723 | |||
| 724 | case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: | ||
| 725 | case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: | ||
| 726 | case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: | ||
| 727 | case PUSHLOCAL9: *top++ = *((stack+base) + (int)(opcode-PUSHLOCAL0)); break; | ||
| 728 | |||
| 729 | case PUSHLOCAL: *top++ = *((stack+base) + (*pc++)); break; | ||
| 730 | |||
| 731 | case PUSHGLOBAL: | ||
| 732 | { | ||
| 733 | CodeWord code; | ||
| 734 | get_word(code,pc); | ||
| 735 | *top++ = s_object(code.w); | ||
| 736 | } | ||
| 737 | break; | ||
| 738 | |||
| 739 | case PUSHINDEXED: | ||
| 740 | { | ||
| 741 | int s = lua_pushsubscript(); | ||
| 742 | if (s == 1) return 1; | ||
| 743 | } | ||
| 744 | break; | ||
| 745 | |||
| 746 | case PUSHSELF: | ||
| 747 | { | ||
| 748 | Object receiver = *(top-2); | ||
| 749 | if (lua_pushsubscript() == 1) return 1; | ||
| 750 | *(top++) = receiver; | ||
| 751 | break; | ||
| 752 | } | ||
| 753 | |||
| 754 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: | ||
| 755 | case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: | ||
| 756 | case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: | ||
| 757 | case STORELOCAL9: | ||
| 758 | *((stack+base) + (int)(opcode-STORELOCAL0)) = *(--top); | ||
| 759 | break; | ||
| 760 | |||
| 761 | case STORELOCAL: *((stack+base) + (*pc++)) = *(--top); break; | ||
| 762 | |||
| 763 | case STOREGLOBAL: | ||
| 764 | { | ||
| 765 | CodeWord code; | ||
| 766 | get_word(code,pc); | ||
| 767 | s_object(code.w) = *(--top); | ||
| 768 | } | ||
| 769 | break; | ||
| 770 | |||
| 771 | case STOREINDEXED0: | ||
| 772 | { | ||
| 773 | int s = lua_storesubscript(); | ||
| 774 | if (s == 1) return 1; | ||
| 775 | } | ||
| 776 | break; | ||
| 777 | |||
| 778 | case STOREINDEXED: | ||
| 779 | { | ||
| 780 | int n = *pc++; | ||
| 781 | if (tag(top-3-n) != LUA_T_ARRAY) | ||
| 782 | { | ||
| 783 | lua_reportbug ("indexed expression not a table"); | ||
| 784 | return 1; | ||
| 785 | } | ||
| 786 | { | ||
| 787 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | ||
| 788 | if (h == NULL) return 1; | ||
| 789 | *h = *(top-1); | ||
| 790 | } | ||
| 791 | top--; | ||
| 792 | } | ||
| 793 | break; | ||
| 794 | |||
| 795 | case STORELIST0: | ||
| 796 | case STORELIST: | ||
| 797 | { | ||
| 798 | int m, n; | ||
| 799 | Object *arr; | ||
| 800 | if (opcode == STORELIST0) m = 0; | ||
| 801 | else m = *(pc++) * FIELDS_PER_FLUSH; | ||
| 802 | n = *(pc++); | ||
| 803 | arr = top-n-1; | ||
| 804 | if (tag(arr) != LUA_T_ARRAY) | ||
| 805 | { | ||
| 806 | lua_reportbug ("internal error - table expected"); | ||
| 807 | return 1; | ||
| 808 | } | ||
| 809 | while (n) | ||
| 810 | { | ||
| 811 | tag(top) = LUA_T_NUMBER; nvalue(top) = n+m; | ||
| 812 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
| 813 | top--; | ||
| 814 | n--; | ||
| 815 | } | ||
| 816 | } | ||
| 817 | break; | ||
| 818 | |||
| 819 | case STORERECORD: | ||
| 820 | { | ||
| 821 | int n = *(pc++); | ||
| 822 | Object *arr = top-n-1; | ||
| 823 | if (tag(arr) != LUA_T_ARRAY) | ||
| 824 | { | ||
| 825 | lua_reportbug ("internal error - table expected"); | ||
| 826 | return 1; | ||
| 827 | } | ||
| 828 | while (n) | ||
| 829 | { | ||
| 830 | CodeWord code; | ||
| 831 | get_word(code,pc); | ||
| 832 | tag(top) = LUA_T_STRING; svalue(top) = lua_constant[code.w]; | ||
| 833 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
| 834 | top--; | ||
| 835 | n--; | ||
| 836 | } | ||
| 837 | } | ||
| 838 | break; | ||
| 839 | |||
| 840 | case ADJUST0: | ||
| 841 | adjust_top((stack+base)); | ||
| 842 | break; | ||
| 843 | |||
| 844 | case ADJUST: | ||
| 845 | adjust_top((stack+base) + *(pc++)); | ||
| 846 | break; | ||
| 847 | |||
| 848 | case CREATEARRAY: | ||
| 849 | { | ||
| 850 | CodeWord size; | ||
| 851 | get_word(size,pc); | ||
| 852 | top++; | ||
| 853 | avalue(top-1) = lua_createarray(size.w); | ||
| 854 | if (avalue(top-1) == NULL) | ||
| 855 | return 1; | ||
| 856 | tag(top-1) = LUA_T_ARRAY; | ||
| 857 | } | ||
| 858 | break; | ||
| 859 | |||
| 860 | case EQOP: | ||
| 861 | { | ||
| 862 | int res; | ||
| 863 | Object *l = top-2; | ||
| 864 | Object *r = top-1; | ||
| 865 | --top; | ||
| 866 | if (tag(l) != tag(r)) | ||
| 867 | res = 0; | ||
| 868 | else | ||
| 869 | { | ||
| 870 | switch (tag(l)) | ||
| 871 | { | ||
| 872 | case LUA_T_NIL: | ||
| 873 | res = 0; break; | ||
| 874 | case LUA_T_NUMBER: | ||
| 875 | res = (nvalue(l) == nvalue(r)); break; | ||
| 876 | case LUA_T_ARRAY: | ||
| 877 | res = (avalue(l) == avalue(r)); break; | ||
| 878 | case LUA_T_FUNCTION: | ||
| 879 | res = (bvalue(l) == bvalue(r)); break; | ||
| 880 | case LUA_T_CFUNCTION: | ||
| 881 | res = (fvalue(l) == fvalue(r)); break; | ||
| 882 | case LUA_T_STRING: | ||
| 883 | res = (strcmp (svalue(l), svalue(r)) == 0); break; | ||
| 884 | default: | ||
| 885 | res = (uvalue(l) == uvalue(r)); break; | ||
| 886 | } | ||
| 887 | } | ||
| 888 | tag(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; | ||
| 889 | nvalue(top-1) = 1; | ||
| 890 | } | ||
| 891 | break; | ||
| 892 | |||
| 893 | case LTOP: | ||
| 894 | { | ||
| 895 | Object *l = top-2; | ||
| 896 | Object *r = top-1; | ||
| 897 | --top; | ||
| 898 | if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) | ||
| 899 | tag(top-1) = (nvalue(l) < nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL; | ||
| 900 | else | ||
| 901 | { | ||
| 902 | if (tostring(l) || tostring(r)) | ||
| 903 | return 1; | ||
| 904 | tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? LUA_T_NUMBER : LUA_T_NIL; | ||
| 905 | } | ||
| 906 | nvalue(top-1) = 1; | ||
| 907 | } | ||
| 908 | break; | ||
| 909 | |||
| 910 | case LEOP: | ||
| 911 | { | ||
| 912 | Object *l = top-2; | ||
| 913 | Object *r = top-1; | ||
| 914 | --top; | ||
| 915 | if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) | ||
| 916 | tag(top-1) = (nvalue(l) <= nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL; | ||
| 917 | else | ||
| 918 | { | ||
| 919 | if (tostring(l) || tostring(r)) | ||
| 920 | return 1; | ||
| 921 | tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? LUA_T_NUMBER : LUA_T_NIL; | ||
| 922 | } | ||
| 923 | nvalue(top-1) = 1; | ||
| 924 | } | ||
| 925 | break; | ||
| 926 | |||
| 927 | case ADDOP: | ||
| 928 | { | ||
| 929 | Object *l = top-2; | ||
| 930 | Object *r = top-1; | ||
| 931 | if (tonumber(r) || tonumber(l)) | ||
| 932 | return 1; | ||
| 933 | nvalue(l) += nvalue(r); | ||
| 934 | --top; | ||
| 935 | } | ||
| 936 | break; | ||
| 937 | |||
| 938 | case SUBOP: | ||
| 939 | { | ||
| 940 | Object *l = top-2; | ||
| 941 | Object *r = top-1; | ||
| 942 | if (tonumber(r) || tonumber(l)) | ||
| 943 | return 1; | ||
| 944 | nvalue(l) -= nvalue(r); | ||
| 945 | --top; | ||
| 946 | } | ||
| 947 | break; | ||
| 1133 | 948 | ||
| 949 | case MULTOP: | ||
| 950 | { | ||
| 951 | Object *l = top-2; | ||
| 952 | Object *r = top-1; | ||
| 953 | if (tonumber(r) || tonumber(l)) | ||
| 954 | return 1; | ||
| 955 | nvalue(l) *= nvalue(r); | ||
| 956 | --top; | ||
| 957 | } | ||
| 958 | break; | ||
| 959 | |||
| 960 | case DIVOP: | ||
| 961 | { | ||
| 962 | Object *l = top-2; | ||
| 963 | Object *r = top-1; | ||
| 964 | if (tonumber(r) || tonumber(l)) | ||
| 965 | return 1; | ||
| 966 | nvalue(l) /= nvalue(r); | ||
| 967 | --top; | ||
| 968 | } | ||
| 969 | break; | ||
| 970 | |||
| 971 | case POWOP: | ||
| 972 | { | ||
| 973 | Object *l = top-2; | ||
| 974 | Object *r = top-1; | ||
| 975 | if (tonumber(r) || tonumber(l)) | ||
| 976 | return 1; | ||
| 977 | nvalue(l) = pow(nvalue(l), nvalue(r)); | ||
| 978 | --top; | ||
| 979 | } | ||
| 980 | break; | ||
| 981 | |||
| 982 | case CONCOP: | ||
| 983 | { | ||
| 984 | Object *l = top-2; | ||
| 985 | Object *r = top-1; | ||
| 986 | if (tostring(r) || tostring(l)) | ||
| 987 | return 1; | ||
| 988 | svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | ||
| 989 | if (svalue(l) == NULL) | ||
| 990 | return 1; | ||
| 991 | --top; | ||
| 992 | } | ||
| 993 | break; | ||
| 994 | |||
| 995 | case MINUSOP: | ||
| 996 | if (tonumber(top-1)) | ||
| 997 | return 1; | ||
| 998 | nvalue(top-1) = - nvalue(top-1); | ||
| 999 | break; | ||
| 1000 | |||
| 1001 | case NOTOP: | ||
| 1002 | tag(top-1) = tag(top-1) == LUA_T_NIL ? LUA_T_NUMBER : LUA_T_NIL; | ||
| 1003 | break; | ||
| 1004 | |||
| 1005 | case ONTJMP: | ||
| 1006 | { | ||
| 1007 | CodeWord code; | ||
| 1008 | get_word(code,pc); | ||
| 1009 | if (tag(top-1) != LUA_T_NIL) pc += code.w; | ||
| 1010 | } | ||
| 1011 | break; | ||
| 1012 | |||
| 1013 | case ONFJMP: | ||
| 1014 | { | ||
| 1015 | CodeWord code; | ||
| 1016 | get_word(code,pc); | ||
| 1017 | if (tag(top-1) == LUA_T_NIL) pc += code.w; | ||
| 1018 | } | ||
| 1019 | break; | ||
| 1020 | |||
| 1021 | case JMP: | ||
| 1022 | { | ||
| 1023 | CodeWord code; | ||
| 1024 | get_word(code,pc); | ||
| 1025 | pc += code.w; | ||
| 1026 | } | ||
| 1027 | break; | ||
| 1028 | |||
| 1029 | case UPJMP: | ||
| 1030 | { | ||
| 1031 | CodeWord code; | ||
| 1032 | get_word(code,pc); | ||
| 1033 | pc -= code.w; | ||
| 1034 | } | ||
| 1035 | break; | ||
| 1036 | |||
| 1037 | case IFFJMP: | ||
| 1038 | { | ||
| 1039 | CodeWord code; | ||
| 1040 | get_word(code,pc); | ||
| 1041 | top--; | ||
| 1042 | if (tag(top) == LUA_T_NIL) pc += code.w; | ||
| 1043 | } | ||
| 1044 | break; | ||
| 1045 | |||
| 1046 | case IFFUPJMP: | ||
| 1047 | { | ||
| 1048 | CodeWord code; | ||
| 1049 | get_word(code,pc); | ||
| 1050 | top--; | ||
| 1051 | if (tag(top) == LUA_T_NIL) pc -= code.w; | ||
| 1052 | } | ||
| 1053 | break; | ||
| 1054 | |||
| 1055 | case POP: --top; break; | ||
| 1056 | |||
| 1057 | case CALLFUNC: | ||
| 1058 | { | ||
| 1059 | int nParams = *(pc++); | ||
| 1060 | int nResults = *(pc++); | ||
| 1061 | Object *func = top-1-nParams; /* function is below parameters */ | ||
| 1062 | int newBase = (top-stack)-nParams; | ||
| 1063 | do_call(func, newBase, nResults, newBase-1); | ||
| 1064 | } | ||
| 1065 | break; | ||
| 1066 | |||
| 1067 | case RETCODE0: | ||
| 1068 | return base; | ||
| 1069 | |||
| 1070 | case RETCODE: | ||
| 1071 | return base+*pc; | ||
| 1072 | |||
| 1073 | case SETFUNCTION: | ||
| 1074 | { | ||
| 1075 | CodeCode file; | ||
| 1076 | CodeWord func; | ||
| 1077 | get_code(file,pc); | ||
| 1078 | get_word(func,pc); | ||
| 1079 | if (lua_pushfunction ((char *)file.b, func.w)) | ||
| 1080 | return 1; | ||
| 1081 | } | ||
| 1082 | break; | ||
| 1083 | |||
| 1084 | case SETLINE: | ||
| 1085 | { | ||
| 1086 | CodeWord code; | ||
| 1087 | get_word(code,pc); | ||
| 1088 | lua_debugline = code.w; | ||
| 1089 | } | ||
| 1090 | break; | ||
| 1091 | |||
| 1092 | case RESET: | ||
| 1093 | lua_popfunction (); | ||
| 1094 | break; | ||
| 1095 | |||
| 1096 | default: | ||
| 1097 | lua_error ("internal error - opcode doesn't match"); | ||
| 1098 | return 1; | ||
| 1099 | } | ||
| 1100 | } | ||
| 1101 | } | ||
| 1134 | 1102 | ||
| @@ -1,11 +1,13 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** TeCGraf - PUC-Rio | 2 | ** TeCGraf - PUC-Rio |
| 3 | ** $Id: opcode.h,v 2.3 1994/08/05 19:31:09 celes Exp celes $ | 3 | ** $Id: opcode.h,v 2.4 1994/10/17 19:00:40 celes Exp roberto $ |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #ifndef opcode_h | 6 | #ifndef opcode_h |
| 7 | #define opcode_h | 7 | #define opcode_h |
| 8 | 8 | ||
| 9 | #include "lua.h" | ||
| 10 | |||
| 9 | #ifndef STACKGAP | 11 | #ifndef STACKGAP |
| 10 | #define STACKGAP 128 | 12 | #define STACKGAP 128 |
| 11 | #endif | 13 | #endif |
| @@ -16,6 +18,8 @@ | |||
| 16 | 18 | ||
| 17 | #define FIELDS_PER_FLUSH 40 | 19 | #define FIELDS_PER_FLUSH 40 |
| 18 | 20 | ||
| 21 | #define MAX_TEMPS 20 | ||
| 22 | |||
| 19 | typedef unsigned char Byte; | 23 | typedef unsigned char Byte; |
| 20 | 24 | ||
| 21 | typedef unsigned short Word; | 25 | typedef unsigned short Word; |
| @@ -54,8 +58,7 @@ typedef enum | |||
| 54 | PUSHLOCAL, | 58 | PUSHLOCAL, |
| 55 | PUSHGLOBAL, | 59 | PUSHGLOBAL, |
| 56 | PUSHINDEXED, | 60 | PUSHINDEXED, |
| 57 | PUSHMARK, | 61 | PUSHSELF, |
| 58 | PUSHMARKMET, | ||
| 59 | STORELOCAL0, STORELOCAL1, STORELOCAL2, STORELOCAL3, STORELOCAL4, | 62 | STORELOCAL0, STORELOCAL1, STORELOCAL2, STORELOCAL3, STORELOCAL4, |
| 60 | STORELOCAL5, STORELOCAL6, STORELOCAL7, STORELOCAL8, STORELOCAL9, | 63 | STORELOCAL5, STORELOCAL6, STORELOCAL7, STORELOCAL8, STORELOCAL9, |
| 61 | STORELOCAL, | 64 | STORELOCAL, |
| @@ -65,6 +68,7 @@ typedef enum | |||
| 65 | STORELIST0, | 68 | STORELIST0, |
| 66 | STORELIST, | 69 | STORELIST, |
| 67 | STORERECORD, | 70 | STORERECORD, |
| 71 | ADJUST0, | ||
| 68 | ADJUST, | 72 | ADJUST, |
| 69 | CREATEARRAY, | 73 | CREATEARRAY, |
| 70 | EQOP, | 74 | EQOP, |
| @@ -86,34 +90,25 @@ typedef enum | |||
| 86 | IFFUPJMP, | 90 | IFFUPJMP, |
| 87 | POP, | 91 | POP, |
| 88 | CALLFUNC, | 92 | CALLFUNC, |
| 93 | RETCODE0, | ||
| 89 | RETCODE, | 94 | RETCODE, |
| 90 | HALT, | ||
| 91 | SETFUNCTION, | 95 | SETFUNCTION, |
| 92 | SETLINE, | 96 | SETLINE, |
| 93 | RESET | 97 | RESET |
| 94 | } OpCode; | 98 | } OpCode; |
| 95 | 99 | ||
| 96 | typedef enum | 100 | #define MULT_RET 255 |
| 97 | { | 101 | |
| 98 | T_MARK, | ||
| 99 | T_NIL, | ||
| 100 | T_NUMBER, | ||
| 101 | T_STRING, | ||
| 102 | T_ARRAY, | ||
| 103 | T_FUNCTION, | ||
| 104 | T_CFUNCTION, | ||
| 105 | T_USERDATA | ||
| 106 | } Type; | ||
| 107 | 102 | ||
| 108 | typedef void (*Cfunction) (void); | 103 | typedef void (*Cfunction) (void); |
| 109 | typedef int (*Input) (void); | 104 | typedef int (*Input) (void); |
| 110 | 105 | ||
| 111 | typedef union | 106 | typedef union |
| 112 | { | 107 | { |
| 113 | Cfunction f; | 108 | Cfunction f; |
| 114 | real n; | 109 | real n; |
| 115 | char *s; | 110 | char *s; |
| 116 | Byte *b; | 111 | Byte *b; |
| 117 | struct Hash *a; | 112 | struct Hash *a; |
| 118 | void *u; | 113 | void *u; |
| 119 | } Value; | 114 | } Value; |
| @@ -157,18 +152,12 @@ typedef struct | |||
| 157 | 152 | ||
| 158 | 153 | ||
| 159 | /* Exported functions */ | 154 | /* Exported functions */ |
| 160 | int lua_execute (Byte *pc); | ||
| 161 | void lua_markstack (void); | ||
| 162 | char *lua_strdup (char *l); | 155 | char *lua_strdup (char *l); |
| 163 | 156 | ||
| 164 | void lua_setinput (Input fn); /* from "lex.c" module */ | 157 | void lua_setinput (Input fn); /* from "lex.c" module */ |
| 165 | char *lua_lasttext (void); /* from "lex.c" module */ | 158 | char *lua_lasttext (void); /* from "lex.c" module */ |
| 166 | int lua_parse (void); /* from "lua.stx" module */ | 159 | Byte *lua_parse (void); /* from "lua.stx" module */ |
| 167 | void lua_type (void); | ||
| 168 | void lua_obj2number (void); | 160 | void lua_obj2number (void); |
| 169 | void lua_print (void); | ||
| 170 | void lua_internaldofile (void); | ||
| 171 | void lua_internaldostring (void); | ||
| 172 | void lua_travstack (void (*fn)(Object *)); | 161 | void lua_travstack (void (*fn)(Object *)); |
| 173 | 162 | ||
| 174 | #endif | 163 | #endif |
